diff --git a/bin/cat/Makefile b/bin/cat/Makefile new file mode 100644 index 0000000..e92c8fd --- /dev/null +++ b/bin/cat/Makefile @@ -0,0 +1,48 @@ +# $Id: Makefile 115 2016-01-14 02:55:19Z reddawg $ +# Application Makefile (C) 2002-2004 The UbixOS Project + +# Include Global 'Source' Options +include ../../Makefile.incl +include ../Makefile.incl + +#Linker +LD = ld + +#Binary File Name +BINARY = cat + +#Delete Program +REMOVE = rm -f + +#Objects +OBJS = cat.o + +LIBRARIES = ../../build/lib/libc_old.so + +# Link The Binary +$(BINARY) : $(OBJS) + $(CC) $(CFLAGS) -o ../../build/bin/$@ $(STARTUP) $(LIBRARIES) $(OBJS) + #strip $(BINARY) + +# Compile the source files +.cpp.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.o: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -c -o $@ $< + +.c.s: + $(CC) -Wall -O $(CFLAGS) $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) -Wall $(CLFAGS) $(INCLUDES) -c -o $@ $< + +# Clean Up The junk +clean: + $(REMOVE) $(OBJS) ../../build/bin/$(BINARY) diff --git a/bin/cat/cat.c b/bin/cat/cat.c new file mode 100644 index 0000000..209c234 --- /dev/null +++ b/bin/cat/cat.c @@ -0,0 +1,387 @@ +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Kevin Fall. + * + * 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. + * 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. + */ + +#if 0 +#ifndef lint +static char const copyright[] = +"@(#) Copyright (c) 1989, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ +#endif + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)cat.c 8.2 (Berkeley) 4/27/95"; +#endif +#endif /* not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/bin/cat/cat.c 306201 2016-09-22 16:49:53Z ache $"); + +#include +#include +#ifndef NO_UDOM_SUPPORT +#include +#include +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int bflag, eflag, lflag, nflag, sflag, tflag, vflag; +static int rval; +static const char *filename; + +static void usage(void) __dead2; +static void scanfiles(char *argv[], int cooked); +static void cook_cat(FILE *); +static void raw_cat(int); + +#ifndef NO_UDOM_SUPPORT +static int udom_open(const char *path, int flags); +#endif + +/* + * Memory strategy threshold, in pages: if physmem is larger than this, + * use a large buffer. + */ +#define PHYSPAGES_THRESHOLD (32 * 1024) + +/* Maximum buffer size in bytes - do not allow it to grow larger than this. */ +#define BUFSIZE_MAX (2 * 1024 * 1024) + +/* + * Small (default) buffer size in bytes. It's inefficient for this to be + * smaller than MAXPHYS. + */ +#define BUFSIZE_SMALL (MAXPHYS) + +int +main(int argc, char *argv[]) +{ + int ch; + struct flock stdout_lock; + + setlocale(LC_CTYPE, ""); + + while ((ch = getopt(argc, argv, "belnstuv")) != -1) + switch (ch) { + case 'b': + bflag = nflag = 1; /* -b implies -n */ + break; + case 'e': + eflag = vflag = 1; /* -e implies -v */ + break; + case 'l': + lflag = 1; + break; + case 'n': + nflag = 1; + break; + case 's': + sflag = 1; + break; + case 't': + tflag = vflag = 1; /* -t implies -v */ + break; + case 'u': + setbuf(stdout, NULL); + break; + case 'v': + vflag = 1; + break; + default: + usage(); + } + argv += optind; + + if (lflag) { + stdout_lock.l_len = 0; + stdout_lock.l_start = 0; + stdout_lock.l_type = F_WRLCK; + stdout_lock.l_whence = SEEK_SET; + if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1) + err(EXIT_FAILURE, "stdout"); + } + + if (bflag || eflag || nflag || sflag || tflag || vflag) + scanfiles(argv, 1); + else + scanfiles(argv, 0); + if (fclose(stdout)) + err(1, "stdout"); + exit(rval); + /* NOTREACHED */ +} + +static void +usage(void) +{ + + fprintf(stderr, "usage: cat [-belnstuv] [file ...]\n"); + exit(1); + /* NOTREACHED */ +} + +static void +scanfiles(char *argv[], int cooked) +{ + int fd, i; + char *path; + FILE *fp; + + i = 0; + fd = -1; + while ((path = argv[i]) != NULL || i == 0) { + if (path == NULL || strcmp(path, "-") == 0) { + filename = "stdin"; + fd = STDIN_FILENO; + } else { + filename = path; + fd = open(path, O_RDONLY); +#ifndef NO_UDOM_SUPPORT + if (fd < 0 && errno == EOPNOTSUPP) + fd = udom_open(path, O_RDONLY); +#endif + } + if (fd < 0) { + warn("%s", path); + rval = 1; + } else if (cooked) { + if (fd == STDIN_FILENO) + cook_cat(stdin); + else { + fp = fdopen(fd, "r"); + cook_cat(fp); + fclose(fp); + } + } else { + raw_cat(fd); + if (fd != STDIN_FILENO) + close(fd); + } + if (path == NULL) + break; + ++i; + } +} + +static void +cook_cat(FILE *fp) +{ + int ch, gobble, line, prev; + wint_t wch; + + /* Reset EOF condition on stdin. */ + if (fp == stdin && feof(stdin)) + clearerr(stdin); + + line = gobble = 0; + for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) { + if (prev == '\n') { + if (sflag) { + if (ch == '\n') { + if (gobble) + continue; + gobble = 1; + } else + gobble = 0; + } + if (nflag && (!bflag || ch != '\n')) { + (void)fprintf(stdout, "%6d\t", ++line); + if (ferror(stdout)) + break; + } + } + if (ch == '\n') { + if (eflag && putchar('$') == EOF) + break; + } else if (ch == '\t') { + if (tflag) { + if (putchar('^') == EOF || putchar('I') == EOF) + break; + continue; + } + } else if (vflag) { + (void)ungetc(ch, fp); + /* + * Our getwc(3) doesn't change file position + * on error. + */ + if ((wch = getwc(fp)) == WEOF) { + if (ferror(fp) && errno == EILSEQ) { + clearerr(fp); + /* Resync attempt. */ + memset(&fp->_mbstate, 0, sizeof(mbstate_t)); + if ((ch = getc(fp)) == EOF) + break; + wch = ch; + goto ilseq; + } else + break; + } + if (!iswascii(wch) && !iswprint(wch)) { +ilseq: + if (putchar('M') == EOF || putchar('-') == EOF) + break; + wch = toascii(wch); + } + if (iswcntrl(wch)) { + ch = toascii(wch); + ch = (ch == '\177') ? '?' : (ch | 0100); + if (putchar('^') == EOF || putchar(ch) == EOF) + break; + continue; + } + if (putwchar(wch) == WEOF) + break; + ch = -1; + continue; + } + if (putchar(ch) == EOF) + break; + } + if (ferror(fp)) { + warn("%s", filename); + rval = 1; + clearerr(fp); + } + if (ferror(stdout)) + err(1, "stdout"); +} + +static void +raw_cat(int rfd) +{ + int off, wfd; + ssize_t nr, nw; + static size_t bsize; + static char *buf = NULL; + struct stat sbuf; + + wfd = fileno(stdout); + if (buf == NULL) { + if (fstat(wfd, &sbuf)) + err(1, "stdout"); + if (S_ISREG(sbuf.st_mode)) { + /* If there's plenty of RAM, use a large copy buffer */ + if (sysconf(_SC_PHYS_PAGES) > PHYSPAGES_THRESHOLD) + bsize = MIN(BUFSIZE_MAX, MAXPHYS * 8); + else + bsize = BUFSIZE_SMALL; + } else + bsize = MAX(sbuf.st_blksize, + (blksize_t)sysconf(_SC_PAGESIZE)); + if ((buf = malloc(bsize)) == NULL) + err(1, "malloc() failure of IO buffer"); + } + while ((nr = read(rfd, buf, bsize)) > 0) + for (off = 0; nr; nr -= nw, off += nw) + if ((nw = write(wfd, buf + off, (size_t)nr)) < 0) + err(1, "stdout"); + if (nr < 0) { + warn("%s", filename); + rval = 1; + } +} + +#ifndef NO_UDOM_SUPPORT + +static int +udom_open(const char *path, int flags) +{ + struct addrinfo hints, *res, *res0; + char rpath[PATH_MAX]; + int fd = -1; + int error; + + /* + * Construct the unix domain socket address and attempt to connect. + */ + bzero(&hints, sizeof(hints)); + hints.ai_family = AF_LOCAL; + if (realpath(path, rpath) == NULL) + return (-1); + error = getaddrinfo(rpath, NULL, &hints, &res0); + if (error) { + warn("%s", gai_strerror(error)); + errno = EINVAL; + return (-1); + } + for (res = res0; res != NULL; res = res->ai_next) { + fd = socket(res->ai_family, res->ai_socktype, + res->ai_protocol); + if (fd < 0) { + freeaddrinfo(res0); + return (-1); + } + error = connect(fd, res->ai_addr, res->ai_addrlen); + if (error == 0) + break; + else { + close(fd); + fd = -1; + } + } + freeaddrinfo(res0); + + /* + * handle the open flags by shutting down appropriate directions + */ + if (fd >= 0) { + switch(flags & O_ACCMODE) { + case O_RDONLY: + if (shutdown(fd, SHUT_WR) == -1) + warn(NULL); + break; + case O_WRONLY: + if (shutdown(fd, SHUT_RD) == -1) + warn(NULL); + break; + default: + break; + } + } + return (fd); +} + +#endif diff --git a/contrib/jemalloc/COPYING b/contrib/jemalloc/COPYING new file mode 100644 index 0000000..104b1f8 --- /dev/null +++ b/contrib/jemalloc/COPYING @@ -0,0 +1,27 @@ +Unless otherwise specified, files in the jemalloc source distribution are +subject to the following license: +-------------------------------------------------------------------------------- +Copyright (C) 2002-2016 Jason Evans . +All rights reserved. +Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved. +Copyright (C) 2009-2016 Facebook, Inc. 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(s), + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice(s), + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. +-------------------------------------------------------------------------------- diff --git a/contrib/jemalloc/ChangeLog b/contrib/jemalloc/ChangeLog new file mode 100644 index 0000000..532255d --- /dev/null +++ b/contrib/jemalloc/ChangeLog @@ -0,0 +1,928 @@ +Following are change highlights associated with official releases. Important +bug fixes are all mentioned, but some internal enhancements are omitted here for +brevity. Much more detail can be found in the git revision history: + + https://github.com/jemalloc/jemalloc + +* 4.2.1 (June 8, 2016) + + Bug fixes: + - Fix bootstrapping issues for configurations that require allocation during + tsd initialization (e.g. --disable-tls). (@cferris1000, @jasone) + - Fix gettimeofday() version of nstime_update(). (@ronawho) + - Fix Valgrind regressions in calloc() and chunk_alloc_wrapper(). (@ronawho) + - Fix potential VM map fragmentation regression. (@jasone) + - Fix opt_zero-triggered in-place huge reallocation zeroing. (@jasone) + - Fix heap profiling context leaks in reallocation edge cases. (@jasone) + +* 4.2.0 (May 12, 2016) + + New features: + - Add the arena..reset mallctl, which makes it possible to discard all of + an arena's allocations in a single operation. (@jasone) + - Add the stats.retained and stats.arenas..retained statistics. (@jasone) + - Add the --with-version configure option. (@jasone) + - Support --with-lg-page values larger than actual page size. (@jasone) + + Optimizations: + - Use pairing heaps rather than red-black trees for various hot data + structures. (@djwatson, @jasone) + - Streamline fast paths of rtree operations. (@jasone) + - Optimize the fast paths of calloc() and [m,d,sd]allocx(). (@jasone) + - Decommit unused virtual memory if the OS does not overcommit. (@jasone) + - Specify MAP_NORESERVE on Linux if [heuristic] overcommit is active, in order + to avoid unfortunate interactions during fork(2). (@jasone) + + Bug fixes: + - Fix chunk accounting related to triggering gdump profiles. (@jasone) + - Link against librt for clock_gettime(2) if glibc < 2.17. (@jasone) + - Scale leak report summary according to sampling probability. (@jasone) + +* 4.1.1 (May 3, 2016) + + This bugfix release resolves a variety of mostly minor issues, though the + bitmap fix is critical for 64-bit Windows. + + Bug fixes: + - Fix the linear scan version of bitmap_sfu() to shift by the proper amount + even when sizeof(long) is not the same as sizeof(void *), as on 64-bit + Windows. (@jasone) + - Fix hashing functions to avoid unaligned memory accesses (and resulting + crashes). This is relevant at least to some ARM-based platforms. + (@rkmisra) + - Fix fork()-related lock rank ordering reversals. These reversals were + unlikely to cause deadlocks in practice except when heap profiling was + enabled and active. (@jasone) + - Fix various chunk leaks in OOM code paths. (@jasone) + - Fix malloc_stats_print() to print opt.narenas correctly. (@jasone) + - Fix MSVC-specific build/test issues. (@rustyx, @yuslepukhin) + - Fix a variety of test failures that were due to test fragility rather than + core bugs. (@jasone) + +* 4.1.0 (February 28, 2016) + + This release is primarily about optimizations, but it also incorporates a lot + of portability-motivated refactoring and enhancements. Many people worked on + this release, to an extent that even with the omission here of minor changes + (see git revision history), and of the people who reported and diagnosed + issues, so much of the work was contributed that starting with this release, + changes are annotated with author credits to help reflect the collaborative + effort involved. + + New features: + - Implement decay-based unused dirty page purging, a major optimization with + mallctl API impact. This is an alternative to the existing ratio-based + unused dirty page purging, and is intended to eventually become the sole + purging mechanism. New mallctls: + + opt.purge + + opt.decay_time + + arena..decay + + arena..decay_time + + arenas.decay_time + + stats.arenas..decay_time + (@jasone, @cevans87) + - Add --with-malloc-conf, which makes it possible to embed a default + options string during configuration. This was motivated by the desire to + specify --with-malloc-conf=purge:decay , since the default must remain + purge:ratio until the 5.0.0 release. (@jasone) + - Add MS Visual Studio 2015 support. (@rustyx, @yuslepukhin) + - Make *allocx() size class overflow behavior defined. The maximum + size class is now less than PTRDIFF_MAX to protect applications against + numerical overflow, and all allocation functions are guaranteed to indicate + errors rather than potentially crashing if the request size exceeds the + maximum size class. (@jasone) + - jeprof: + + Add raw heap profile support. (@jasone) + + Add --retain and --exclude for backtrace symbol filtering. (@jasone) + + Optimizations: + - Optimize the fast path to combine various bootstrapping and configuration + checks and execute more streamlined code in the common case. (@interwq) + - Use linear scan for small bitmaps (used for small object tracking). In + addition to speeding up bitmap operations on 64-bit systems, this reduces + allocator metadata overhead by approximately 0.2%. (@djwatson) + - Separate arena_avail trees, which substantially speeds up run tree + operations. (@djwatson) + - Use memoization (boot-time-computed table) for run quantization. Separate + arena_avail trees reduced the importance of this optimization. (@jasone) + - Attempt mmap-based in-place huge reallocation. This can dramatically speed + up incremental huge reallocation. (@jasone) + + Incompatible changes: + - Make opt.narenas unsigned rather than size_t. (@jasone) + + Bug fixes: + - Fix stats.cactive accounting regression. (@rustyx, @jasone) + - Handle unaligned keys in hash(). This caused problems for some ARM systems. + (@jasone, @cferris1000) + - Refactor arenas array. In addition to fixing a fork-related deadlock, this + makes arena lookups faster and simpler. (@jasone) + - Move retained memory allocation out of the default chunk allocation + function, to a location that gets executed even if the application installs + a custom chunk allocation function. This resolves a virtual memory leak. + (@buchgr) + - Fix a potential tsd cleanup leak. (@cferris1000, @jasone) + - Fix run quantization. In practice this bug had no impact unless + applications requested memory with alignment exceeding one page. + (@jasone, @djwatson) + - Fix LinuxThreads-specific bootstrapping deadlock. (Cosmin Paraschiv) + - jeprof: + + Don't discard curl options if timeout is not defined. (@djwatson) + + Detect failed profile fetches. (@djwatson) + - Fix stats.arenas..{dss,lg_dirty_mult,decay_time,pactive,pdirty} for + --disable-stats case. (@jasone) + +* 4.0.4 (October 24, 2015) + + This bugfix release fixes another xallocx() regression. No other regressions + have come to light in over a month, so this is likely a good starting point + for people who prefer to wait for "dot one" releases with all the major issues + shaken out. + + Bug fixes: + - Fix xallocx(..., MALLOCX_ZERO to zero the last full trailing page of large + allocations that have been randomly assigned an offset of 0 when + --enable-cache-oblivious configure option is enabled. + +* 4.0.3 (September 24, 2015) + + This bugfix release continues the trend of xallocx() and heap profiling fixes. + + Bug fixes: + - Fix xallocx(..., MALLOCX_ZERO) to zero all trailing bytes of large + allocations when --enable-cache-oblivious configure option is enabled. + - Fix xallocx(..., MALLOCX_ZERO) to zero trailing bytes of huge allocations + when resizing from/to a size class that is not a multiple of the chunk size. + - Fix prof_tctx_dump_iter() to filter out nodes that were created after heap + profile dumping started. + - Work around a potentially bad thread-specific data initialization + interaction with NPTL (glibc's pthreads implementation). + +* 4.0.2 (September 21, 2015) + + This bugfix release addresses a few bugs specific to heap profiling. + + Bug fixes: + - Fix ixallocx_prof_sample() to never modify nor create sampled small + allocations. xallocx() is in general incapable of moving small allocations, + so this fix removes buggy code without loss of generality. + - Fix irallocx_prof_sample() to always allocate large regions, even when + alignment is non-zero. + - Fix prof_alloc_rollback() to read tdata from thread-specific data rather + than dereferencing a potentially invalid tctx. + +* 4.0.1 (September 15, 2015) + + This is a bugfix release that is somewhat high risk due to the amount of + refactoring required to address deep xallocx() problems. As a side effect of + these fixes, xallocx() now tries harder to partially fulfill requests for + optional extra space. Note that a couple of minor heap profiling + optimizations are included, but these are better thought of as performance + fixes that were integral to disovering most of the other bugs. + + Optimizations: + - Avoid a chunk metadata read in arena_prof_tctx_set(), since it is in the + fast path when heap profiling is enabled. Additionally, split a special + case out into arena_prof_tctx_reset(), which also avoids chunk metadata + reads. + - Optimize irallocx_prof() to optimistically update the sampler state. The + prior implementation appears to have been a holdover from when + rallocx()/xallocx() functionality was combined as rallocm(). + + Bug fixes: + - Fix TLS configuration such that it is enabled by default for platforms on + which it works correctly. + - Fix arenas_cache_cleanup() and arena_get_hard() to handle + allocation/deallocation within the application's thread-specific data + cleanup functions even after arenas_cache is torn down. + - Fix xallocx() bugs related to size+extra exceeding HUGE_MAXCLASS. + - Fix chunk purge hook calls for in-place huge shrinking reallocation to + specify the old chunk size rather than the new chunk size. This bug caused + no correctness issues for the default chunk purge function, but was + visible to custom functions set via the "arena..chunk_hooks" mallctl. + - Fix heap profiling bugs: + + Fix heap profiling to distinguish among otherwise identical sample sites + with interposed resets (triggered via the "prof.reset" mallctl). This bug + could cause data structure corruption that would most likely result in a + segfault. + + Fix irealloc_prof() to prof_alloc_rollback() on OOM. + + Make one call to prof_active_get_unlocked() per allocation event, and use + the result throughout the relevant functions that handle an allocation + event. Also add a missing check in prof_realloc(). These fixes protect + allocation events against concurrent prof_active changes. + + Fix ixallocx_prof() to pass usize_max and zero to ixallocx_prof_sample() + in the correct order. + + Fix prof_realloc() to call prof_free_sampled_object() after calling + prof_malloc_sample_object(). Prior to this fix, if tctx and old_tctx were + the same, the tctx could have been prematurely destroyed. + - Fix portability bugs: + + Don't bitshift by negative amounts when encoding/decoding run sizes in + chunk header maps. This affected systems with page sizes greater than 8 + KiB. + + Rename index_t to szind_t to avoid an existing type on Solaris. + + Add JEMALLOC_CXX_THROW to the memalign() function prototype, in order to + match glibc and avoid compilation errors when including both + jemalloc/jemalloc.h and malloc.h in C++ code. + + Don't assume that /bin/sh is appropriate when running size_classes.sh + during configuration. + + Consider __sparcv9 a synonym for __sparc64__ when defining LG_QUANTUM. + + Link tests to librt if it contains clock_gettime(2). + +* 4.0.0 (August 17, 2015) + + This version contains many speed and space optimizations, both minor and + major. The major themes are generalization, unification, and simplification. + Although many of these optimizations cause no visible behavior change, their + cumulative effect is substantial. + + New features: + - Normalize size class spacing to be consistent across the complete size + range. By default there are four size classes per size doubling, but this + is now configurable via the --with-lg-size-class-group option. Also add the + --with-lg-page, --with-lg-page-sizes, --with-lg-quantum, and + --with-lg-tiny-min options, which can be used to tweak page and size class + settings. Impacts: + + Worst case performance for incrementally growing/shrinking reallocation + is improved because there are far fewer size classes, and therefore + copying happens less often. + + Internal fragmentation is limited to 20% for all but the smallest size + classes (those less than four times the quantum). (1B + 4 KiB) + and (1B + 4 MiB) previously suffered nearly 50% internal fragmentation. + + Chunk fragmentation tends to be lower because there are fewer distinct run + sizes to pack. + - Add support for explicit tcaches. The "tcache.create", "tcache.flush", and + "tcache.destroy" mallctls control tcache lifetime and flushing, and the + MALLOCX_TCACHE(tc) and MALLOCX_TCACHE_NONE flags to the *allocx() API + control which tcache is used for each operation. + - Implement per thread heap profiling, as well as the ability to + enable/disable heap profiling on a per thread basis. Add the "prof.reset", + "prof.lg_sample", "thread.prof.name", "thread.prof.active", + "opt.prof_thread_active_init", "prof.thread_active_init", and + "thread.prof.active" mallctls. + - Add support for per arena application-specified chunk allocators, configured + via the "arena..chunk_hooks" mallctl. + - Refactor huge allocation to be managed by arenas, so that arenas now + function as general purpose independent allocators. This is important in + the context of user-specified chunk allocators, aside from the scalability + benefits. Related new statistics: + + The "stats.arenas..huge.allocated", "stats.arenas..huge.nmalloc", + "stats.arenas..huge.ndalloc", and "stats.arenas..huge.nrequests" + mallctls provide high level per arena huge allocation statistics. + + The "arenas.nhchunks", "arenas.hchunk..size", + "stats.arenas..hchunks..nmalloc", + "stats.arenas..hchunks..ndalloc", + "stats.arenas..hchunks..nrequests", and + "stats.arenas..hchunks..curhchunks" mallctls provide per size class + statistics. + - Add the 'util' column to malloc_stats_print() output, which reports the + proportion of available regions that are currently in use for each small + size class. + - Add "alloc" and "free" modes for for junk filling (see the "opt.junk" + mallctl), so that it is possible to separately enable junk filling for + allocation versus deallocation. + - Add the jemalloc-config script, which provides information about how + jemalloc was configured, and how to integrate it into application builds. + - Add metadata statistics, which are accessible via the "stats.metadata", + "stats.arenas..metadata.mapped", and + "stats.arenas..metadata.allocated" mallctls. + - Add the "stats.resident" mallctl, which reports the upper limit of + physically resident memory mapped by the allocator. + - Add per arena control over unused dirty page purging, via the + "arenas.lg_dirty_mult", "arena..lg_dirty_mult", and + "stats.arenas..lg_dirty_mult" mallctls. + - Add the "prof.gdump" mallctl, which makes it possible to toggle the gdump + feature on/off during program execution. + - Add sdallocx(), which implements sized deallocation. The primary + optimization over dallocx() is the removal of a metadata read, which often + suffers an L1 cache miss. + - Add missing header includes in jemalloc/jemalloc.h, so that applications + only have to #include . + - Add support for additional platforms: + + Bitrig + + Cygwin + + DragonFlyBSD + + iOS + + OpenBSD + + OpenRISC/or1k + + Optimizations: + - Maintain dirty runs in per arena LRUs rather than in per arena trees of + dirty-run-containing chunks. In practice this change significantly reduces + dirty page purging volume. + - Integrate whole chunks into the unused dirty page purging machinery. This + reduces the cost of repeated huge allocation/deallocation, because it + effectively introduces a cache of chunks. + - Split the arena chunk map into two separate arrays, in order to increase + cache locality for the frequently accessed bits. + - Move small run metadata out of runs, into arena chunk headers. This reduces + run fragmentation, smaller runs reduce external fragmentation for small size + classes, and packed (less uniformly aligned) metadata layout improves CPU + cache set distribution. + - Randomly distribute large allocation base pointer alignment relative to page + boundaries in order to more uniformly utilize CPU cache sets. This can be + disabled via the --disable-cache-oblivious configure option, and queried via + the "config.cache_oblivious" mallctl. + - Micro-optimize the fast paths for the public API functions. + - Refactor thread-specific data to reside in a single structure. This assures + that only a single TLS read is necessary per call into the public API. + - Implement in-place huge allocation growing and shrinking. + - Refactor rtree (radix tree for chunk lookups) to be lock-free, and make + additional optimizations that reduce maximum lookup depth to one or two + levels. This resolves what was a concurrency bottleneck for per arena huge + allocation, because a global data structure is critical for determining + which arenas own which huge allocations. + + Incompatible changes: + - Replace --enable-cc-silence with --disable-cc-silence to suppress spurious + warnings by default. + - Assure that the constness of malloc_usable_size()'s return type matches that + of the system implementation. + - Change the heap profile dump format to support per thread heap profiling, + rename pprof to jeprof, and enhance it with the --thread= option. As a + result, the bundled jeprof must now be used rather than the upstream + (gperftools) pprof. + - Disable "opt.prof_final" by default, in order to avoid atexit(3), which can + internally deadlock on some platforms. + - Change the "arenas.nlruns" mallctl type from size_t to unsigned. + - Replace the "stats.arenas..bins..allocated" mallctl with + "stats.arenas..bins..curregs". + - Ignore MALLOC_CONF in set{uid,gid,cap} binaries. + - Ignore MALLOCX_ARENA(a) in dallocx(), in favor of using the + MALLOCX_TCACHE(tc) and MALLOCX_TCACHE_NONE flags to control tcache usage. + + Removed features: + - Remove the *allocm() API, which is superseded by the *allocx() API. + - Remove the --enable-dss options, and make dss non-optional on all platforms + which support sbrk(2). + - Remove the "arenas.purge" mallctl, which was obsoleted by the + "arena..purge" mallctl in 3.1.0. + - Remove the unnecessary "opt.valgrind" mallctl; jemalloc automatically + detects whether it is running inside Valgrind. + - Remove the "stats.huge.allocated", "stats.huge.nmalloc", and + "stats.huge.ndalloc" mallctls. + - Remove the --enable-mremap option. + - Remove the "stats.chunks.current", "stats.chunks.total", and + "stats.chunks.high" mallctls. + + Bug fixes: + - Fix the cactive statistic to decrease (rather than increase) when active + memory decreases. This regression was first released in 3.5.0. + - Fix OOM handling in memalign() and valloc(). A variant of this bug existed + in all releases since 2.0.0, which introduced these functions. + - Fix an OOM-related regression in arena_tcache_fill_small(), which could + cause cache corruption on OOM. This regression was present in all releases + from 2.2.0 through 3.6.0. + - Fix size class overflow handling for malloc(), posix_memalign(), memalign(), + calloc(), and realloc() when profiling is enabled. + - Fix the "arena..dss" mallctl to return an error if "primary" or + "secondary" precedence is specified, but sbrk(2) is not supported. + - Fix fallback lg_floor() implementations to handle extremely large inputs. + - Ensure the default purgeable zone is after the default zone on OS X. + - Fix latent bugs in atomic_*(). + - Fix the "arena..dss" mallctl to handle read-only calls. + - Fix tls_model configuration to enable the initial-exec model when possible. + - Mark malloc_conf as a weak symbol so that the application can override it. + - Correctly detect glibc's adaptive pthread mutexes. + - Fix the --without-export configure option. + +* 3.6.0 (March 31, 2014) + + This version contains a critical bug fix for a regression present in 3.5.0 and + 3.5.1. + + Bug fixes: + - Fix a regression in arena_chunk_alloc() that caused crashes during + small/large allocation if chunk allocation failed. In the absence of this + bug, chunk allocation failure would result in allocation failure, e.g. NULL + return from malloc(). This regression was introduced in 3.5.0. + - Fix backtracing for gcc intrinsics-based backtracing by specifying + -fno-omit-frame-pointer to gcc. Note that the application (and all the + libraries it links to) must also be compiled with this option for + backtracing to be reliable. + - Use dss allocation precedence for huge allocations as well as small/large + allocations. + - Fix test assertion failure message formatting. This bug did not manifest on + x86_64 systems because of implementation subtleties in va_list. + - Fix inconsequential test failures for hash and SFMT code. + + New features: + - Support heap profiling on FreeBSD. This feature depends on the proc + filesystem being mounted during heap profile dumping. + +* 3.5.1 (February 25, 2014) + + This version primarily addresses minor bugs in test code. + + Bug fixes: + - Configure Solaris/Illumos to use MADV_FREE. + - Fix junk filling for mremap(2)-based huge reallocation. This is only + relevant if configuring with the --enable-mremap option specified. + - Avoid compilation failure if 'restrict' C99 keyword is not supported by the + compiler. + - Add a configure test for SSE2 rather than assuming it is usable on i686 + systems. This fixes test compilation errors, especially on 32-bit Linux + systems. + - Fix mallctl argument size mismatches (size_t vs. uint64_t) in the stats unit + test. + - Fix/remove flawed alignment-related overflow tests. + - Prevent compiler optimizations that could change backtraces in the + prof_accum unit test. + +* 3.5.0 (January 22, 2014) + + This version focuses on refactoring and automated testing, though it also + includes some non-trivial heap profiling optimizations not mentioned below. + + New features: + - Add the *allocx() API, which is a successor to the experimental *allocm() + API. The *allocx() functions are slightly simpler to use because they have + fewer parameters, they directly return the results of primary interest, and + mallocx()/rallocx() avoid the strict aliasing pitfall that + allocm()/rallocm() share with posix_memalign(). Note that *allocm() is + slated for removal in the next non-bugfix release. + - Add support for LinuxThreads. + + Bug fixes: + - Unless heap profiling is enabled, disable floating point code and don't link + with libm. This, in combination with e.g. EXTRA_CFLAGS=-mno-sse on x64 + systems, makes it possible to completely disable floating point register + use. Some versions of glibc neglect to save/restore caller-saved floating + point registers during dynamic lazy symbol loading, and the symbol loading + code uses whatever malloc the application happens to have linked/loaded + with, the result being potential floating point register corruption. + - Report ENOMEM rather than EINVAL if an OOM occurs during heap profiling + backtrace creation in imemalign(). This bug impacted posix_memalign() and + aligned_alloc(). + - Fix a file descriptor leak in a prof_dump_maps() error path. + - Fix prof_dump() to close the dump file descriptor for all relevant error + paths. + - Fix rallocm() to use the arena specified by the ALLOCM_ARENA(s) flag for + allocation, not just deallocation. + - Fix a data race for large allocation stats counters. + - Fix a potential infinite loop during thread exit. This bug occurred on + Solaris, and could affect other platforms with similar pthreads TSD + implementations. + - Don't junk-fill reallocations unless usable size changes. This fixes a + violation of the *allocx()/*allocm() semantics. + - Fix growing large reallocation to junk fill new space. + - Fix huge deallocation to junk fill when munmap is disabled. + - Change the default private namespace prefix from empty to je_, and change + --with-private-namespace-prefix so that it prepends an additional prefix + rather than replacing je_. This reduces the likelihood of applications + which statically link jemalloc experiencing symbol name collisions. + - Add missing private namespace mangling (relevant when + --with-private-namespace is specified). + - Add and use JEMALLOC_INLINE_C so that static inline functions are marked as + static even for debug builds. + - Add a missing mutex unlock in a malloc_init_hard() error path. In practice + this error path is never executed. + - Fix numerous bugs in malloc_strotumax() error handling/reporting. These + bugs had no impact except for malformed inputs. + - Fix numerous bugs in malloc_snprintf(). These bugs were not exercised by + existing calls, so they had no impact. + +* 3.4.1 (October 20, 2013) + + Bug fixes: + - Fix a race in the "arenas.extend" mallctl that could cause memory corruption + of internal data structures and subsequent crashes. + - Fix Valgrind integration flaws that caused Valgrind warnings about reads of + uninitialized memory in: + + arena chunk headers + + internal zero-initialized data structures (relevant to tcache and prof + code) + - Preserve errno during the first allocation. A readlink(2) call during + initialization fails unless /etc/malloc.conf exists, so errno was typically + set during the first allocation prior to this fix. + - Fix compilation warnings reported by gcc 4.8.1. + +* 3.4.0 (June 2, 2013) + + This version is essentially a small bugfix release, but the addition of + aarch64 support requires that the minor version be incremented. + + Bug fixes: + - Fix race-triggered deadlocks in chunk_record(). These deadlocks were + typically triggered by multiple threads concurrently deallocating huge + objects. + + New features: + - Add support for the aarch64 architecture. + +* 3.3.1 (March 6, 2013) + + This version fixes bugs that are typically encountered only when utilizing + custom run-time options. + + Bug fixes: + - Fix a locking order bug that could cause deadlock during fork if heap + profiling were enabled. + - Fix a chunk recycling bug that could cause the allocator to lose track of + whether a chunk was zeroed. On FreeBSD, NetBSD, and OS X, it could cause + corruption if allocating via sbrk(2) (unlikely unless running with the + "dss:primary" option specified). This was completely harmless on Linux + unless using mlockall(2) (and unlikely even then, unless the + --disable-munmap configure option or the "dss:primary" option was + specified). This regression was introduced in 3.1.0 by the + mlockall(2)/madvise(2) interaction fix. + - Fix TLS-related memory corruption that could occur during thread exit if the + thread never allocated memory. Only the quarantine and prof facilities were + susceptible. + - Fix two quarantine bugs: + + Internal reallocation of the quarantined object array leaked the old + array. + + Reallocation failure for internal reallocation of the quarantined object + array (very unlikely) resulted in memory corruption. + - Fix Valgrind integration to annotate all internally allocated memory in a + way that keeps Valgrind happy about internal data structure access. + - Fix building for s390 systems. + +* 3.3.0 (January 23, 2013) + + This version includes a few minor performance improvements in addition to the + listed new features and bug fixes. + + New features: + - Add clipping support to lg_chunk option processing. + - Add the --enable-ivsalloc option. + - Add the --without-export option. + - Add the --disable-zone-allocator option. + + Bug fixes: + - Fix "arenas.extend" mallctl to output the number of arenas. + - Fix chunk_recycle() to unconditionally inform Valgrind that returned memory + is undefined. + - Fix build break on FreeBSD related to alloca.h. + +* 3.2.0 (November 9, 2012) + + In addition to a couple of bug fixes, this version modifies page run + allocation and dirty page purging algorithms in order to better control + page-level virtual memory fragmentation. + + Incompatible changes: + - Change the "opt.lg_dirty_mult" default from 5 to 3 (32:1 to 8:1). + + Bug fixes: + - Fix dss/mmap allocation precedence code to use recyclable mmap memory only + after primary dss allocation fails. + - Fix deadlock in the "arenas.purge" mallctl. This regression was introduced + in 3.1.0 by the addition of the "arena..purge" mallctl. + +* 3.1.0 (October 16, 2012) + + New features: + - Auto-detect whether running inside Valgrind, thus removing the need to + manually specify MALLOC_CONF=valgrind:true. + - Add the "arenas.extend" mallctl, which allows applications to create + manually managed arenas. + - Add the ALLOCM_ARENA() flag for {,r,d}allocm(). + - Add the "opt.dss", "arena..dss", and "stats.arenas..dss" mallctls, + which provide control over dss/mmap precedence. + - Add the "arena..purge" mallctl, which obsoletes "arenas.purge". + - Define LG_QUANTUM for hppa. + + Incompatible changes: + - Disable tcache by default if running inside Valgrind, in order to avoid + making unallocated objects appear reachable to Valgrind. + - Drop const from malloc_usable_size() argument on Linux. + + Bug fixes: + - Fix heap profiling crash if sampled object is freed via realloc(p, 0). + - Remove const from __*_hook variable declarations, so that glibc can modify + them during process forking. + - Fix mlockall(2)/madvise(2) interaction. + - Fix fork(2)-related deadlocks. + - Fix error return value for "thread.tcache.enabled" mallctl. + +* 3.0.0 (May 11, 2012) + + Although this version adds some major new features, the primary focus is on + internal code cleanup that facilitates maintainability and portability, most + of which is not reflected in the ChangeLog. This is the first release to + incorporate substantial contributions from numerous other developers, and the + result is a more broadly useful allocator (see the git revision history for + contribution details). Note that the license has been unified, thanks to + Facebook granting a license under the same terms as the other copyright + holders (see COPYING). + + New features: + - Implement Valgrind support, redzones, and quarantine. + - Add support for additional platforms: + + FreeBSD + + Mac OS X Lion + + MinGW + + Windows (no support yet for replacing the system malloc) + - Add support for additional architectures: + + MIPS + + SH4 + + Tilera + - Add support for cross compiling. + - Add nallocm(), which rounds a request size up to the nearest size class + without actually allocating. + - Implement aligned_alloc() (blame C11). + - Add the "thread.tcache.enabled" mallctl. + - Add the "opt.prof_final" mallctl. + - Update pprof (from gperftools 2.0). + - Add the --with-mangling option. + - Add the --disable-experimental option. + - Add the --disable-munmap option, and make it the default on Linux. + - Add the --enable-mremap option, which disables use of mremap(2) by default. + + Incompatible changes: + - Enable stats by default. + - Enable fill by default. + - Disable lazy locking by default. + - Rename the "tcache.flush" mallctl to "thread.tcache.flush". + - Rename the "arenas.pagesize" mallctl to "arenas.page". + - Change the "opt.lg_prof_sample" default from 0 to 19 (1 B to 512 KiB). + - Change the "opt.prof_accum" default from true to false. + + Removed features: + - Remove the swap feature, including the "config.swap", "swap.avail", + "swap.prezeroed", "swap.nfds", and "swap.fds" mallctls. + - Remove highruns statistics, including the + "stats.arenas..bins..highruns" and + "stats.arenas..lruns..highruns" mallctls. + - As part of small size class refactoring, remove the "opt.lg_[qc]space_max", + "arenas.cacheline", "arenas.subpage", "arenas.[tqcs]space_{min,max}", and + "arenas.[tqcs]bins" mallctls. + - Remove the "arenas.chunksize" mallctl. + - Remove the "opt.lg_prof_tcmax" option. + - Remove the "opt.lg_prof_bt_max" option. + - Remove the "opt.lg_tcache_gc_sweep" option. + - Remove the --disable-tiny option, including the "config.tiny" mallctl. + - Remove the --enable-dynamic-page-shift configure option. + - Remove the --enable-sysv configure option. + + Bug fixes: + - Fix a statistics-related bug in the "thread.arena" mallctl that could cause + invalid statistics and crashes. + - Work around TLS deallocation via free() on Linux. This bug could cause + write-after-free memory corruption. + - Fix a potential deadlock that could occur during interval- and + growth-triggered heap profile dumps. + - Fix large calloc() zeroing bugs due to dropping chunk map unzeroed flags. + - Fix chunk_alloc_dss() to stop claiming memory is zeroed. This bug could + cause memory corruption and crashes with --enable-dss specified. + - Fix fork-related bugs that could cause deadlock in children between fork + and exec. + - Fix malloc_stats_print() to honor 'b' and 'l' in the opts parameter. + - Fix realloc(p, 0) to act like free(p). + - Do not enforce minimum alignment in memalign(). + - Check for NULL pointer in malloc_usable_size(). + - Fix an off-by-one heap profile statistics bug that could be observed in + interval- and growth-triggered heap profiles. + - Fix the "epoch" mallctl to update cached stats even if the passed in epoch + is 0. + - Fix bin->runcur management to fix a layout policy bug. This bug did not + affect correctness. + - Fix a bug in choose_arena_hard() that potentially caused more arenas to be + initialized than necessary. + - Add missing "opt.lg_tcache_max" mallctl implementation. + - Use glibc allocator hooks to make mixed allocator usage less likely. + - Fix build issues for --disable-tcache. + - Don't mangle pthread_create() when --with-private-namespace is specified. + +* 2.2.5 (November 14, 2011) + + Bug fixes: + - Fix huge_ralloc() race when using mremap(2). This is a serious bug that + could cause memory corruption and/or crashes. + - Fix huge_ralloc() to maintain chunk statistics. + - Fix malloc_stats_print(..., "a") output. + +* 2.2.4 (November 5, 2011) + + Bug fixes: + - Initialize arenas_tsd before using it. This bug existed for 2.2.[0-3], as + well as for --disable-tls builds in earlier releases. + - Do not assume a 4 KiB page size in test/rallocm.c. + +* 2.2.3 (August 31, 2011) + + This version fixes numerous bugs related to heap profiling. + + Bug fixes: + - Fix a prof-related race condition. This bug could cause memory corruption, + but only occurred in non-default configurations (prof_accum:false). + - Fix off-by-one backtracing issues (make sure that prof_alloc_prep() is + excluded from backtraces). + - Fix a prof-related bug in realloc() (only triggered by OOM errors). + - Fix prof-related bugs in allocm() and rallocm(). + - Fix prof_tdata_cleanup() for --disable-tls builds. + - Fix a relative include path, to fix objdir builds. + +* 2.2.2 (July 30, 2011) + + Bug fixes: + - Fix a build error for --disable-tcache. + - Fix assertions in arena_purge() (for real this time). + - Add the --with-private-namespace option. This is a workaround for symbol + conflicts that can inadvertently arise when using static libraries. + +* 2.2.1 (March 30, 2011) + + Bug fixes: + - Implement atomic operations for x86/x64. This fixes compilation failures + for versions of gcc that are still in wide use. + - Fix an assertion in arena_purge(). + +* 2.2.0 (March 22, 2011) + + This version incorporates several improvements to algorithms and data + structures that tend to reduce fragmentation and increase speed. + + New features: + - Add the "stats.cactive" mallctl. + - Update pprof (from google-perftools 1.7). + - Improve backtracing-related configuration logic, and add the + --disable-prof-libgcc option. + + Bug fixes: + - Change default symbol visibility from "internal", to "hidden", which + decreases the overhead of library-internal function calls. + - Fix symbol visibility so that it is also set on OS X. + - Fix a build dependency regression caused by the introduction of the .pic.o + suffix for PIC object files. + - Add missing checks for mutex initialization failures. + - Don't use libgcc-based backtracing except on x64, where it is known to work. + - Fix deadlocks on OS X that were due to memory allocation in + pthread_mutex_lock(). + - Heap profiling-specific fixes: + + Fix memory corruption due to integer overflow in small region index + computation, when using a small enough sample interval that profiling + context pointers are stored in small run headers. + + Fix a bootstrap ordering bug that only occurred with TLS disabled. + + Fix a rallocm() rsize bug. + + Fix error detection bugs for aligned memory allocation. + +* 2.1.3 (March 14, 2011) + + Bug fixes: + - Fix a cpp logic regression (due to the "thread.{de,}allocatedp" mallctl fix + for OS X in 2.1.2). + - Fix a "thread.arena" mallctl bug. + - Fix a thread cache stats merging bug. + +* 2.1.2 (March 2, 2011) + + Bug fixes: + - Fix "thread.{de,}allocatedp" mallctl for OS X. + - Add missing jemalloc.a to build system. + +* 2.1.1 (January 31, 2011) + + Bug fixes: + - Fix aligned huge reallocation (affected allocm()). + - Fix the ALLOCM_LG_ALIGN macro definition. + - Fix a heap dumping deadlock. + - Fix a "thread.arena" mallctl bug. + +* 2.1.0 (December 3, 2010) + + This version incorporates some optimizations that can't quite be considered + bug fixes. + + New features: + - Use Linux's mremap(2) for huge object reallocation when possible. + - Avoid locking in mallctl*() when possible. + - Add the "thread.[de]allocatedp" mallctl's. + - Convert the manual page source from roff to DocBook, and generate both roff + and HTML manuals. + + Bug fixes: + - Fix a crash due to incorrect bootstrap ordering. This only impacted + --enable-debug --enable-dss configurations. + - Fix a minor statistics bug for mallctl("swap.avail", ...). + +* 2.0.1 (October 29, 2010) + + Bug fixes: + - Fix a race condition in heap profiling that could cause undefined behavior + if "opt.prof_accum" were disabled. + - Add missing mutex unlocks for some OOM error paths in the heap profiling + code. + - Fix a compilation error for non-C99 builds. + +* 2.0.0 (October 24, 2010) + + This version focuses on the experimental *allocm() API, and on improved + run-time configuration/introspection. Nonetheless, numerous performance + improvements are also included. + + New features: + - Implement the experimental {,r,s,d}allocm() API, which provides a superset + of the functionality available via malloc(), calloc(), posix_memalign(), + realloc(), malloc_usable_size(), and free(). These functions can be used to + allocate/reallocate aligned zeroed memory, ask for optional extra memory + during reallocation, prevent object movement during reallocation, etc. + - Replace JEMALLOC_OPTIONS/JEMALLOC_PROF_PREFIX with MALLOC_CONF, which is + more human-readable, and more flexible. For example: + JEMALLOC_OPTIONS=AJP + is now: + MALLOC_CONF=abort:true,fill:true,stats_print:true + - Port to Apple OS X. Sponsored by Mozilla. + - Make it possible for the application to control thread-->arena mappings via + the "thread.arena" mallctl. + - Add compile-time support for all TLS-related functionality via pthreads TSD. + This is mainly of interest for OS X, which does not support TLS, but has a + TSD implementation with similar performance. + - Override memalign() and valloc() if they are provided by the system. + - Add the "arenas.purge" mallctl, which can be used to synchronously purge all + dirty unused pages. + - Make cumulative heap profiling data optional, so that it is possible to + limit the amount of memory consumed by heap profiling data structures. + - Add per thread allocation counters that can be accessed via the + "thread.allocated" and "thread.deallocated" mallctls. + + Incompatible changes: + - Remove JEMALLOC_OPTIONS and malloc_options (see MALLOC_CONF above). + - Increase default backtrace depth from 4 to 128 for heap profiling. + - Disable interval-based profile dumps by default. + + Bug fixes: + - Remove bad assertions in fork handler functions. These assertions could + cause aborts for some combinations of configure settings. + - Fix strerror_r() usage to deal with non-standard semantics in GNU libc. + - Fix leak context reporting. This bug tended to cause the number of contexts + to be underreported (though the reported number of objects and bytes were + correct). + - Fix a realloc() bug for large in-place growing reallocation. This bug could + cause memory corruption, but it was hard to trigger. + - Fix an allocation bug for small allocations that could be triggered if + multiple threads raced to create a new run of backing pages. + - Enhance the heap profiler to trigger samples based on usable size, rather + than request size. + - Fix a heap profiling bug due to sometimes losing track of requested object + size for sampled objects. + +* 1.0.3 (August 12, 2010) + + Bug fixes: + - Fix the libunwind-based implementation of stack backtracing (used for heap + profiling). This bug could cause zero-length backtraces to be reported. + - Add a missing mutex unlock in library initialization code. If multiple + threads raced to initialize malloc, some of them could end up permanently + blocked. + +* 1.0.2 (May 11, 2010) + + Bug fixes: + - Fix junk filling of large objects, which could cause memory corruption. + - Add MAP_NORESERVE support for chunk mapping, because otherwise virtual + memory limits could cause swap file configuration to fail. Contributed by + Jordan DeLong. + +* 1.0.1 (April 14, 2010) + + Bug fixes: + - Fix compilation when --enable-fill is specified. + - Fix threads-related profiling bugs that affected accuracy and caused memory + to be leaked during thread exit. + - Fix dirty page purging race conditions that could cause crashes. + - Fix crash in tcache flushing code during thread destruction. + +* 1.0.0 (April 11, 2010) + + This release focuses on speed and run-time introspection. Numerous + algorithmic improvements make this release substantially faster than its + predecessors. + + New features: + - Implement autoconf-based configuration system. + - Add mallctl*(), for the purposes of introspection and run-time + configuration. + - Make it possible for the application to manually flush a thread's cache, via + the "tcache.flush" mallctl. + - Base maximum dirty page count on proportion of active memory. + - Compute various additional run-time statistics, including per size class + statistics for large objects. + - Expose malloc_stats_print(), which can be called repeatedly by the + application. + - Simplify the malloc_message() signature to only take one string argument, + and incorporate an opaque data pointer argument for use by the application + in combination with malloc_stats_print(). + - Add support for allocation backed by one or more swap files, and allow the + application to disable over-commit if swap files are in use. + - Implement allocation profiling and leak checking. + + Removed features: + - Remove the dynamic arena rebalancing code, since thread-specific caching + reduces its utility. + + Bug fixes: + - Modify chunk allocation to work when address space layout randomization + (ASLR) is in use. + - Fix thread cleanup bugs related to TLS destruction. + - Handle 0-size allocation requests in posix_memalign(). + - Fix a chunk leak. The leaked chunks were never touched, so this impacted + virtual memory usage, but not physical memory usage. + +* linux_2008082[78]a (August 27/28, 2008) + + These snapshot releases are the simple result of incorporating Linux-specific + support into the FreeBSD malloc sources. + +-------------------------------------------------------------------------------- +vim:filetype=text:textwidth=80 diff --git a/contrib/jemalloc/FREEBSD-Xlist b/contrib/jemalloc/FREEBSD-Xlist new file mode 100644 index 0000000..dff8d26 --- /dev/null +++ b/contrib/jemalloc/FREEBSD-Xlist @@ -0,0 +1,52 @@ +$FreeBSD$ +.autom4te.cfg +.git* +FREEBSD-* +INSTALL +Makefile* +README +autogen.sh +autom4te.cache/ +bin/ +build-aux/ +config.* +configure* +coverage.sh +doc/*.in +doc/*.xml +doc/*.xsl +doc/*.html +include/jemalloc/internal/jemalloc_internal.h.in +include/jemalloc/internal/jemalloc_internal_defs.h.in +include/jemalloc/internal/private_namespace.sh +include/jemalloc/internal/private_symbols.txt +include/jemalloc/internal/private_unnamespace.h +include/jemalloc/internal/private_unnamespace.sh +include/jemalloc/internal/public_namespace.sh +include/jemalloc/internal/public_symbols.txt +include/jemalloc/internal/public_unnamespace.h +include/jemalloc/internal/public_unnamespace.sh +include/jemalloc/internal/size_classes.sh +include/jemalloc/internal/smoothstep.sh +include/jemalloc/jemalloc.h.in +include/jemalloc/jemalloc.sh +include/jemalloc/jemalloc_defs.h +include/jemalloc/jemalloc_defs.h.in +include/jemalloc/jemalloc_macros.h +include/jemalloc/jemalloc_macros.h.in +include/jemalloc/jemalloc_mangle_jet.h +include/jemalloc/jemalloc_mangle.sh +include/jemalloc/jemalloc_mangle.h +include/jemalloc/jemalloc_protos_jet.h +include/jemalloc/jemalloc_protos.h +include/jemalloc/jemalloc_protos.h.in +include/jemalloc/jemalloc_rename.h +include/jemalloc/jemalloc_rename.sh +include/jemalloc/jemalloc_typedefs.h.in +include/msvc_compat/ +install-sh +jemalloc.pc* +msvc/ +src/valgrind.c +src/zone.c +test/ diff --git a/contrib/jemalloc/FREEBSD-diffs b/contrib/jemalloc/FREEBSD-diffs new file mode 100644 index 0000000..df0a538 --- /dev/null +++ b/contrib/jemalloc/FREEBSD-diffs @@ -0,0 +1,544 @@ +diff --git a/doc/jemalloc.xml.in b/doc/jemalloc.xml.in +index c4a44e3..4626e9b 100644 +--- a/doc/jemalloc.xml.in ++++ b/doc/jemalloc.xml.in +@@ -53,11 +53,23 @@ + This manual describes jemalloc @jemalloc_version@. More information + can be found at the jemalloc website. ++ ++ The following configuration options are enabled in libc's built-in ++ jemalloc: , ++ , , ++ , , ++ , , and ++ . Additionally, ++ is enabled in development versions of ++ FreeBSD (controlled by the MALLOC_PRODUCTION make ++ variable). ++ + + + SYNOPSIS + +- #include <jemalloc/jemalloc.h> ++ #include <stdlib.h> ++#include <malloc_np.h> + + Standard API + +@@ -2961,4 +2973,18 @@ malloc_conf = "lg_chunk:24";]]> + The posix_memalign function conforms + to IEEE Std 1003.1-2001 (“POSIX.1”). + ++ ++ HISTORY ++ The malloc_usable_size and ++ posix_memalign functions first appeared in ++ FreeBSD 7.0. ++ ++ The aligned_alloc, ++ malloc_stats_print, and ++ mallctl* functions first appeared in ++ FreeBSD 10.0. ++ ++ The *allocx functions first appeared ++ in FreeBSD 11.0. ++ + +diff --git a/include/jemalloc/internal/arena.h b/include/jemalloc/internal/arena.h +index b1de2b6..da6b6d2 100644 +--- a/include/jemalloc/internal/arena.h ++++ b/include/jemalloc/internal/arena.h +@@ -718,8 +718,13 @@ arena_miscelm_get_mutable(arena_chunk_t *chunk, size_t pageind) + JEMALLOC_ALWAYS_INLINE const arena_chunk_map_misc_t * + arena_miscelm_get_const(const arena_chunk_t *chunk, size_t pageind) + { ++#if 1 /* Work around gcc bug. */ ++ arena_chunk_t *mchunk = (arena_chunk_t *)chunk; + ++ return (arena_miscelm_get_mutable(mchunk, pageind)); ++#else + return (arena_miscelm_get_mutable((arena_chunk_t *)chunk, pageind)); ++#endif + } + + JEMALLOC_ALWAYS_INLINE size_t +@@ -778,8 +783,13 @@ arena_mapbitsp_get_mutable(arena_chunk_t *chunk, size_t pageind) + JEMALLOC_ALWAYS_INLINE const size_t * + arena_mapbitsp_get_const(const arena_chunk_t *chunk, size_t pageind) + { ++#if 1 /* Work around gcc bug. */ ++ arena_chunk_t *mchunk = (arena_chunk_t *)chunk; + ++ return (arena_mapbitsp_get_mutable(mchunk, pageind)); ++#else + return (arena_mapbitsp_get_mutable((arena_chunk_t *)chunk, pageind)); ++#endif + } + + JEMALLOC_ALWAYS_INLINE size_t +diff --git a/include/jemalloc/internal/jemalloc_internal.h.in b/include/jemalloc/internal/jemalloc_internal.h.in +index 8f82edd..78e2df2 100644 +--- a/include/jemalloc/internal/jemalloc_internal.h.in ++++ b/include/jemalloc/internal/jemalloc_internal.h.in +@@ -8,6 +8,9 @@ + #include + #endif + ++#include "un-namespace.h" ++#include "libc_private.h" ++ + #define JEMALLOC_NO_DEMANGLE + #ifdef JEMALLOC_JET + # define JEMALLOC_N(n) jet_##n +@@ -42,13 +45,7 @@ static const bool config_fill = + false + #endif + ; +-static const bool config_lazy_lock = +-#ifdef JEMALLOC_LAZY_LOCK +- true +-#else +- false +-#endif +- ; ++static const bool config_lazy_lock = true; + static const char * const config_malloc_conf = JEMALLOC_CONFIG_MALLOC_CONF; + static const bool config_prof = + #ifdef JEMALLOC_PROF +diff --git a/include/jemalloc/internal/jemalloc_internal_decls.h b/include/jemalloc/internal/jemalloc_internal_decls.h +index 2b8ca5d..42d97f2 100644 +--- a/include/jemalloc/internal/jemalloc_internal_decls.h ++++ b/include/jemalloc/internal/jemalloc_internal_decls.h +@@ -1,6 +1,9 @@ + #ifndef JEMALLOC_INTERNAL_DECLS_H + #define JEMALLOC_INTERNAL_DECLS_H + ++#include "libc_private.h" ++#include "namespace.h" ++ + #include + #ifdef _WIN32 + # include +diff --git a/include/jemalloc/internal/mutex.h b/include/jemalloc/internal/mutex.h +index 5221799..60ab041 100644 +--- a/include/jemalloc/internal/mutex.h ++++ b/include/jemalloc/internal/mutex.h +@@ -52,9 +52,6 @@ struct malloc_mutex_s { + + #ifdef JEMALLOC_LAZY_LOCK + extern bool isthreaded; +-#else +-# undef isthreaded /* Undo private_namespace.h definition. */ +-# define isthreaded true + #endif + + bool malloc_mutex_init(malloc_mutex_t *mutex, const char *name, +@@ -62,6 +59,7 @@ bool malloc_mutex_init(malloc_mutex_t *mutex, const char *name, + void malloc_mutex_prefork(tsdn_t *tsdn, malloc_mutex_t *mutex); + void malloc_mutex_postfork_parent(tsdn_t *tsdn, malloc_mutex_t *mutex); + void malloc_mutex_postfork_child(tsdn_t *tsdn, malloc_mutex_t *mutex); ++bool malloc_mutex_first_thread(void); + bool malloc_mutex_boot(void); + + #endif /* JEMALLOC_H_EXTERNS */ +diff --git a/include/jemalloc/internal/private_symbols.txt b/include/jemalloc/internal/private_symbols.txt +index f2b6a55..69369c9 100644 +--- a/include/jemalloc/internal/private_symbols.txt ++++ b/include/jemalloc/internal/private_symbols.txt +@@ -311,7 +311,6 @@ iralloct_realign + isalloc + isdalloct + isqalloc +-isthreaded + ivsalloc + ixalloc + jemalloc_postfork_child +diff --git a/include/jemalloc/jemalloc_FreeBSD.h b/include/jemalloc/jemalloc_FreeBSD.h +new file mode 100644 +index 0000000..c58a8f3 +--- /dev/null ++++ b/include/jemalloc/jemalloc_FreeBSD.h +@@ -0,0 +1,162 @@ ++/* ++ * Override settings that were generated in jemalloc_defs.h as necessary. ++ */ ++ ++#undef JEMALLOC_OVERRIDE_VALLOC ++ ++#ifndef MALLOC_PRODUCTION ++#define JEMALLOC_DEBUG ++#endif ++ ++#undef JEMALLOC_DSS ++ ++/* ++ * The following are architecture-dependent, so conditionally define them for ++ * each supported architecture. ++ */ ++#undef JEMALLOC_TLS_MODEL ++#undef STATIC_PAGE_SHIFT ++#undef LG_SIZEOF_PTR ++#undef LG_SIZEOF_INT ++#undef LG_SIZEOF_LONG ++#undef LG_SIZEOF_INTMAX_T ++ ++#ifdef __i386__ ++# define LG_SIZEOF_PTR 2 ++# define JEMALLOC_TLS_MODEL __attribute__((tls_model("initial-exec"))) ++#endif ++#ifdef __ia64__ ++# define LG_SIZEOF_PTR 3 ++#endif ++#ifdef __sparc64__ ++# define LG_SIZEOF_PTR 3 ++# define JEMALLOC_TLS_MODEL __attribute__((tls_model("initial-exec"))) ++#endif ++#ifdef __amd64__ ++# define LG_SIZEOF_PTR 3 ++# define JEMALLOC_TLS_MODEL __attribute__((tls_model("initial-exec"))) ++#endif ++#ifdef __arm__ ++# define LG_SIZEOF_PTR 2 ++#endif ++#ifdef __aarch64__ ++# define LG_SIZEOF_PTR 3 ++#endif ++#ifdef __mips__ ++#ifdef __mips_n64 ++# define LG_SIZEOF_PTR 3 ++#else ++# define LG_SIZEOF_PTR 2 ++#endif ++#endif ++#ifdef __powerpc64__ ++# define LG_SIZEOF_PTR 3 ++#elif defined(__powerpc__) ++# define LG_SIZEOF_PTR 2 ++#endif ++#ifdef __riscv__ ++# define LG_SIZEOF_PTR 3 ++#endif ++ ++#ifndef JEMALLOC_TLS_MODEL ++# define JEMALLOC_TLS_MODEL /* Default. */ ++#endif ++ ++#define STATIC_PAGE_SHIFT PAGE_SHIFT ++#define LG_SIZEOF_INT 2 ++#define LG_SIZEOF_LONG LG_SIZEOF_PTR ++#define LG_SIZEOF_INTMAX_T 3 ++ ++#undef CPU_SPINWAIT ++#include ++#include ++#define CPU_SPINWAIT cpu_spinwait() ++ ++/* Disable lazy-lock machinery, mangle isthreaded, and adjust its type. */ ++#undef JEMALLOC_LAZY_LOCK ++extern int __isthreaded; ++#define isthreaded ((bool)__isthreaded) ++ ++/* Mangle. */ ++#undef je_malloc ++#undef je_calloc ++#undef je_posix_memalign ++#undef je_aligned_alloc ++#undef je_realloc ++#undef je_free ++#undef je_malloc_usable_size ++#undef je_mallocx ++#undef je_rallocx ++#undef je_xallocx ++#undef je_sallocx ++#undef je_dallocx ++#undef je_sdallocx ++#undef je_nallocx ++#undef je_mallctl ++#undef je_mallctlnametomib ++#undef je_mallctlbymib ++#undef je_malloc_stats_print ++#undef je_allocm ++#undef je_rallocm ++#undef je_sallocm ++#undef je_dallocm ++#undef je_nallocm ++#define je_malloc __malloc ++#define je_calloc __calloc ++#define je_posix_memalign __posix_memalign ++#define je_aligned_alloc __aligned_alloc ++#define je_realloc __realloc ++#define je_free __free ++#define je_malloc_usable_size __malloc_usable_size ++#define je_mallocx __mallocx ++#define je_rallocx __rallocx ++#define je_xallocx __xallocx ++#define je_sallocx __sallocx ++#define je_dallocx __dallocx ++#define je_sdallocx __sdallocx ++#define je_nallocx __nallocx ++#define je_mallctl __mallctl ++#define je_mallctlnametomib __mallctlnametomib ++#define je_mallctlbymib __mallctlbymib ++#define je_malloc_stats_print __malloc_stats_print ++#define je_allocm __allocm ++#define je_rallocm __rallocm ++#define je_sallocm __sallocm ++#define je_dallocm __dallocm ++#define je_nallocm __nallocm ++#define open _open ++#define read _read ++#define write _write ++#define close _close ++#define pthread_mutex_lock _pthread_mutex_lock ++#define pthread_mutex_unlock _pthread_mutex_unlock ++ ++#ifdef JEMALLOC_C_ ++/* ++ * Define 'weak' symbols so that an application can have its own versions ++ * of malloc, calloc, realloc, free, et al. ++ */ ++__weak_reference(__malloc, malloc); ++__weak_reference(__calloc, calloc); ++__weak_reference(__posix_memalign, posix_memalign); ++__weak_reference(__aligned_alloc, aligned_alloc); ++__weak_reference(__realloc, realloc); ++__weak_reference(__free, free); ++__weak_reference(__malloc_usable_size, malloc_usable_size); ++__weak_reference(__mallocx, mallocx); ++__weak_reference(__rallocx, rallocx); ++__weak_reference(__xallocx, xallocx); ++__weak_reference(__sallocx, sallocx); ++__weak_reference(__dallocx, dallocx); ++__weak_reference(__sdallocx, sdallocx); ++__weak_reference(__nallocx, nallocx); ++__weak_reference(__mallctl, mallctl); ++__weak_reference(__mallctlnametomib, mallctlnametomib); ++__weak_reference(__mallctlbymib, mallctlbymib); ++__weak_reference(__malloc_stats_print, malloc_stats_print); ++__weak_reference(__allocm, allocm); ++__weak_reference(__rallocm, rallocm); ++__weak_reference(__sallocm, sallocm); ++__weak_reference(__dallocm, dallocm); ++__weak_reference(__nallocm, nallocm); ++#endif +diff --git a/include/jemalloc/jemalloc_rename.sh b/include/jemalloc/jemalloc_rename.sh +index f943891..47d032c 100755 +--- a/include/jemalloc/jemalloc_rename.sh ++++ b/include/jemalloc/jemalloc_rename.sh +@@ -19,4 +19,6 @@ done + + cat <: */ ++const char *__malloc_options_1_0 = NULL; ++__sym_compat(_malloc_options, __malloc_options_1_0, FBSD_1.0); ++ + /* Runtime configuration options. */ + const char *je_malloc_conf JEMALLOC_ATTR(weak); + bool opt_abort = +@@ -2673,6 +2677,107 @@ je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr) + */ + /******************************************************************************/ + /* ++ * Begin compatibility functions. ++ */ ++ ++#define ALLOCM_LG_ALIGN(la) (la) ++#define ALLOCM_ALIGN(a) (ffsl(a)-1) ++#define ALLOCM_ZERO ((int)0x40) ++#define ALLOCM_NO_MOVE ((int)0x80) ++ ++#define ALLOCM_SUCCESS 0 ++#define ALLOCM_ERR_OOM 1 ++#define ALLOCM_ERR_NOT_MOVED 2 ++ ++int ++je_allocm(void **ptr, size_t *rsize, size_t size, int flags) ++{ ++ void *p; ++ ++ assert(ptr != NULL); ++ ++ p = je_mallocx(size, flags); ++ if (p == NULL) ++ return (ALLOCM_ERR_OOM); ++ if (rsize != NULL) ++ *rsize = isalloc(tsdn_fetch(), p, config_prof); ++ *ptr = p; ++ return (ALLOCM_SUCCESS); ++} ++ ++int ++je_rallocm(void **ptr, size_t *rsize, size_t size, size_t extra, int flags) ++{ ++ int ret; ++ bool no_move = flags & ALLOCM_NO_MOVE; ++ ++ assert(ptr != NULL); ++ assert(*ptr != NULL); ++ assert(size != 0); ++ assert(SIZE_T_MAX - size >= extra); ++ ++ if (no_move) { ++ size_t usize = je_xallocx(*ptr, size, extra, flags); ++ ret = (usize >= size) ? ALLOCM_SUCCESS : ALLOCM_ERR_NOT_MOVED; ++ if (rsize != NULL) ++ *rsize = usize; ++ } else { ++ void *p = je_rallocx(*ptr, size+extra, flags); ++ if (p != NULL) { ++ *ptr = p; ++ ret = ALLOCM_SUCCESS; ++ } else ++ ret = ALLOCM_ERR_OOM; ++ if (rsize != NULL) ++ *rsize = isalloc(tsdn_fetch(), *ptr, config_prof); ++ } ++ return (ret); ++} ++ ++int ++je_sallocm(const void *ptr, size_t *rsize, int flags) ++{ ++ ++ assert(rsize != NULL); ++ *rsize = je_sallocx(ptr, flags); ++ return (ALLOCM_SUCCESS); ++} ++ ++int ++je_dallocm(void *ptr, int flags) ++{ ++ ++ je_dallocx(ptr, flags); ++ return (ALLOCM_SUCCESS); ++} ++ ++int ++je_nallocm(size_t *rsize, size_t size, int flags) ++{ ++ size_t usize; ++ ++ usize = je_nallocx(size, flags); ++ if (usize == 0) ++ return (ALLOCM_ERR_OOM); ++ if (rsize != NULL) ++ *rsize = usize; ++ return (ALLOCM_SUCCESS); ++} ++ ++#undef ALLOCM_LG_ALIGN ++#undef ALLOCM_ALIGN ++#undef ALLOCM_ZERO ++#undef ALLOCM_NO_MOVE ++ ++#undef ALLOCM_SUCCESS ++#undef ALLOCM_ERR_OOM ++#undef ALLOCM_ERR_NOT_MOVED ++ ++/* ++ * End compatibility functions. ++ */ ++/******************************************************************************/ ++/* + * The following functions are used by threading libraries for protection of + * malloc during fork(). + */ +@@ -2814,4 +2919,11 @@ jemalloc_postfork_child(void) + ctl_postfork_child(tsd_tsdn(tsd)); + } + ++void ++_malloc_first_thread(void) ++{ ++ ++ (void)malloc_mutex_first_thread(); ++} ++ + /******************************************************************************/ +diff --git a/src/mutex.c b/src/mutex.c +index a1fac34..a24e420 100644 +--- a/src/mutex.c ++++ b/src/mutex.c +@@ -66,6 +66,17 @@ pthread_create(pthread_t *__restrict thread, + #ifdef JEMALLOC_MUTEX_INIT_CB + JEMALLOC_EXPORT int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, + void *(calloc_cb)(size_t, size_t)); ++ ++#pragma weak _pthread_mutex_init_calloc_cb ++int ++_pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, ++ void *(calloc_cb)(size_t, size_t)) ++{ ++ ++ return (((int (*)(pthread_mutex_t *, void *(*)(size_t, size_t))) ++ __libc_interposing[INTERPOS__pthread_mutex_init_calloc_cb])(mutex, ++ calloc_cb)); ++} + #endif + + bool +@@ -140,7 +151,7 @@ malloc_mutex_postfork_child(tsdn_t *tsdn, malloc_mutex_t *mutex) + } + + bool +-malloc_mutex_boot(void) ++malloc_mutex_first_thread(void) + { + + #ifdef JEMALLOC_MUTEX_INIT_CB +@@ -154,3 +165,14 @@ malloc_mutex_boot(void) + #endif + return (false); + } ++ ++bool ++malloc_mutex_boot(void) ++{ ++ ++#ifndef JEMALLOC_MUTEX_INIT_CB ++ return (malloc_mutex_first_thread()); ++#else ++ return (false); ++#endif ++} +diff --git a/src/util.c b/src/util.c +index a1c4a2a..04f9153 100644 +--- a/src/util.c ++++ b/src/util.c +@@ -67,6 +67,22 @@ wrtmessage(void *cbopaque, const char *s) + + JEMALLOC_EXPORT void (*je_malloc_message)(void *, const char *s); + ++JEMALLOC_ATTR(visibility("hidden")) ++void ++wrtmessage_1_0(const char *s1, const char *s2, const char *s3, ++ const char *s4) ++{ ++ ++ wrtmessage(NULL, s1); ++ wrtmessage(NULL, s2); ++ wrtmessage(NULL, s3); ++ wrtmessage(NULL, s4); ++} ++ ++void (*__malloc_message_1_0)(const char *s1, const char *s2, const char *s3, ++ const char *s4) = wrtmessage_1_0; ++__sym_compat(_malloc_message, __malloc_message_1_0, FBSD_1.0); ++ + /* + * Wrapper around malloc_message() that avoids the need for + * je_malloc_message(...) throughout the code. diff --git a/contrib/jemalloc/FREEBSD-upgrade b/contrib/jemalloc/FREEBSD-upgrade new file mode 100755 index 0000000..6ee6cc9 --- /dev/null +++ b/contrib/jemalloc/FREEBSD-upgrade @@ -0,0 +1,130 @@ +#!/bin/sh +# $FreeBSD$ +# +# Usage: cd /usr/src/contrib/jemalloc +# ./FREEBSD-upgrade [args] +# +# At least the following ports are required when importing jemalloc: +# - devel/autoconf +# - devel/git +# - devel/gmake +# - textproc/docbook-xsl +# - textproc/libxslt +# +# The normal workflow for importing a new release is: +# +# cd /usr/src/contrib/jemalloc +# +# Merge local changes that were made since the previous import: +# +# ./FREEBSD-upgrade merge-changes +# ./FREEBSD-upgrade rediff +# +# Extract latest jemalloc release. +# +# ./FREEBSD-upgrade extract +# +# Fix patch conflicts as necessary, then regenerate diffs to update line +# offsets: +# +# ./FREEBSD-upgrade rediff +# ./FREEBSD-upgrade extract +# +# Do multiple buildworld/installworld rounds. If problems arise and patches +# are needed, edit the code in ${work} as necessary, then: +# +# ./FREEBSD-upgrade rediff +# ./FREEBSD-upgrade extract +# +# The rediff/extract order is important because rediff saves the local +# changes, then extract blows away the work tree and re-creates it with the +# diffs applied. +# +# Finally, to clean up: +# +# ./FREEBSD-upgrade clean + +set -e + +if [ ! -x "FREEBSD-upgrade" ] ; then + echo "Run from within src/contrib/jemalloc/" >&2 + exit 1 +fi + +src=`pwd` +workname="jemalloc.git" +work="${src}/../${workname}" # merge-changes expects ${workname} in "..". +changes="${src}/FREEBSD-changes" + +do_extract() { + local rev=$1 + # Clone. + rm -rf ${work} + git clone https://github.com/jemalloc/jemalloc.git ${work} + ( + cd ${work} + if [ "x${rev}" != "x" ] ; then + # Use optional rev argument to check out a revision other than HEAD on + # master. + git checkout ${rev} + fi + # Apply diffs before generating files. + patch -p1 < "${src}/FREEBSD-diffs" + find . -name '*.orig' -delete + # Generate various files. + ./autogen.sh --enable-cc-silence --enable-xmalloc --enable-utrace \ + --with-xslroot=/usr/local/share/xsl/docbook --with-private-namespace=__ \ + --with-lg-page-sizes=12,13,14,16 + gmake dist + ) +} + +do_diff() { + ( + cd ${work} + find . -name '*.orig' -delete + find . -name '*.rej' -delete + git add -A + git diff --cached + ) > FREEBSD-diffs +} + +command=$1 +shift +case "${command}" in + merge-changes) # Merge local changes that were made since the previous import. + rev=`cat VERSION |tr 'g' ' ' |awk '{print $2}'` + # Extract code corresponding to most recent import. + do_extract ${rev} + # Compute local differences to the upstream+patches and apply them. + ( + cd .. + diff -ru -X ${src}/FREEBSD-Xlist ${workname} jemalloc > ${changes} || true + ) + ( + cd ${work} + patch -p1 < ${changes} + find . -name '*.orig' -delete + ) + # Update diff. + do_diff + ;; + extract) # Extract upstream sources, apply patches, copy to contrib/jemalloc. + rev=$1 + do_extract ${rev} + # Delete existing files so that cruft doesn't silently remain. + rm -rf ChangeLog COPYING VERSION doc include src + # Copy files over. + tar cf - -C ${work} -X FREEBSD-Xlist . |tar xvf - + ;; + rediff) # Regenerate diffs based on working tree. + do_diff + ;; + clean) # Remove working tree and temporary files. + rm -rf ${work} ${changes} + ;; + *) + echo "Unsupported command: \"${command}\"" >&2 + exit 1 + ;; +esac diff --git a/contrib/jemalloc/VERSION b/contrib/jemalloc/VERSION new file mode 100644 index 0000000..b17fa1d --- /dev/null +++ b/contrib/jemalloc/VERSION @@ -0,0 +1 @@ +4.2.1-0-g3de035335255d553bdb344c32ffdb603816195d8 diff --git a/contrib/jemalloc/doc/jemalloc.3 b/contrib/jemalloc/doc/jemalloc.3 new file mode 100644 index 0000000..26fb02a --- /dev/null +++ b/contrib/jemalloc/doc/jemalloc.3 @@ -0,0 +1,2154 @@ +'\" t +.\" Title: JEMALLOC +.\" Author: Jason Evans +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 06/08/2016 +.\" Manual: User Manual +.\" Source: jemalloc 4.2.1-0-g3de035335255d553bdb344c32ffdb603816195d8 +.\" Language: English +.\" +.TH "JEMALLOC" "3" "06/08/2016" "jemalloc 4.2.1-0-g3de035335255" "User Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +jemalloc \- general purpose memory allocation functions +.SH "LIBRARY" +.PP +This manual describes jemalloc 4\&.2\&.1\-0\-g3de035335255d553bdb344c32ffdb603816195d8\&. More information can be found at the +\m[blue]\fBjemalloc website\fR\m[]\&\s-2\u[1]\d\s+2\&. +.PP +The following configuration options are enabled in libc\*(Aqs built\-in jemalloc: +\fB\-\-enable\-fill\fR, +\fB\-\-enable\-lazy\-lock\fR, +\fB\-\-enable\-munmap\fR, +\fB\-\-enable\-stats\fR, +\fB\-\-enable\-tcache\fR, +\fB\-\-enable\-tls\fR, +\fB\-\-enable\-utrace\fR, and +\fB\-\-enable\-xmalloc\fR\&. Additionally, +\fB\-\-enable\-debug\fR +is enabled in development versions of FreeBSD (controlled by the +\fBMALLOC_PRODUCTION\fR +make variable)\&. +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +#include +.fi +.ft +.SS "Standard API" +.HP \w'void\ *malloc('u +.BI "void *malloc(size_t\ " "size" ");" +.HP \w'void\ *calloc('u +.BI "void *calloc(size_t\ " "number" ", size_t\ " "size" ");" +.HP \w'int\ posix_memalign('u +.BI "int posix_memalign(void\ **" "ptr" ", size_t\ " "alignment" ", size_t\ " "size" ");" +.HP \w'void\ *aligned_alloc('u +.BI "void *aligned_alloc(size_t\ " "alignment" ", size_t\ " "size" ");" +.HP \w'void\ *realloc('u +.BI "void *realloc(void\ *" "ptr" ", size_t\ " "size" ");" +.HP \w'void\ free('u +.BI "void free(void\ *" "ptr" ");" +.SS "Non\-standard API" +.HP \w'void\ *mallocx('u +.BI "void *mallocx(size_t\ " "size" ", int\ " "flags" ");" +.HP \w'void\ *rallocx('u +.BI "void *rallocx(void\ *" "ptr" ", size_t\ " "size" ", int\ " "flags" ");" +.HP \w'size_t\ xallocx('u +.BI "size_t xallocx(void\ *" "ptr" ", size_t\ " "size" ", size_t\ " "extra" ", int\ " "flags" ");" +.HP \w'size_t\ sallocx('u +.BI "size_t sallocx(void\ *" "ptr" ", int\ " "flags" ");" +.HP \w'void\ dallocx('u +.BI "void dallocx(void\ *" "ptr" ", int\ " "flags" ");" +.HP \w'void\ sdallocx('u +.BI "void sdallocx(void\ *" "ptr" ", size_t\ " "size" ", int\ " "flags" ");" +.HP \w'size_t\ nallocx('u +.BI "size_t nallocx(size_t\ " "size" ", int\ " "flags" ");" +.HP \w'int\ mallctl('u +.BI "int mallctl(const\ char\ *" "name" ", void\ *" "oldp" ", size_t\ *" "oldlenp" ", void\ *" "newp" ", size_t\ " "newlen" ");" +.HP \w'int\ mallctlnametomib('u +.BI "int mallctlnametomib(const\ char\ *" "name" ", size_t\ *" "mibp" ", size_t\ *" "miblenp" ");" +.HP \w'int\ mallctlbymib('u +.BI "int mallctlbymib(const\ size_t\ *" "mib" ", size_t\ " "miblen" ", void\ *" "oldp" ", size_t\ *" "oldlenp" ", void\ *" "newp" ", size_t\ " "newlen" ");" +.HP \w'void\ malloc_stats_print('u +.BI "void malloc_stats_print(void\ " "(*write_cb)" "\ (void\ *,\ const\ char\ *), void\ *" "cbopaque" ", const\ char\ *" "opts" ");" +.HP \w'size_t\ malloc_usable_size('u +.BI "size_t malloc_usable_size(const\ void\ *" "ptr" ");" +.HP \w'void\ (*malloc_message)('u +.BI "void (*malloc_message)(void\ *" "cbopaque" ", const\ char\ *" "s" ");" +.PP +const char *\fImalloc_conf\fR; +.SH "DESCRIPTION" +.SS "Standard API" +.PP +The +\fBmalloc\fR\fB\fR +function allocates +\fIsize\fR +bytes of uninitialized memory\&. The allocated space is suitably aligned (after possible pointer coercion) for storage of any type of object\&. +.PP +The +\fBcalloc\fR\fB\fR +function allocates space for +\fInumber\fR +objects, each +\fIsize\fR +bytes in length\&. The result is identical to calling +\fBmalloc\fR\fB\fR +with an argument of +\fInumber\fR +* +\fIsize\fR, with the exception that the allocated memory is explicitly initialized to zero bytes\&. +.PP +The +\fBposix_memalign\fR\fB\fR +function allocates +\fIsize\fR +bytes of memory such that the allocation\*(Aqs base address is a multiple of +\fIalignment\fR, and returns the allocation in the value pointed to by +\fIptr\fR\&. The requested +\fIalignment\fR +must be a power of 2 at least as large as +sizeof(\fBvoid *\fR)\&. +.PP +The +\fBaligned_alloc\fR\fB\fR +function allocates +\fIsize\fR +bytes of memory such that the allocation\*(Aqs base address is a multiple of +\fIalignment\fR\&. The requested +\fIalignment\fR +must be a power of 2\&. Behavior is undefined if +\fIsize\fR +is not an integral multiple of +\fIalignment\fR\&. +.PP +The +\fBrealloc\fR\fB\fR +function changes the size of the previously allocated memory referenced by +\fIptr\fR +to +\fIsize\fR +bytes\&. The contents of the memory are unchanged up to the lesser of the new and old sizes\&. If the new size is larger, the contents of the newly allocated portion of the memory are undefined\&. Upon success, the memory referenced by +\fIptr\fR +is freed and a pointer to the newly allocated memory is returned\&. Note that +\fBrealloc\fR\fB\fR +may move the memory allocation, resulting in a different return value than +\fIptr\fR\&. If +\fIptr\fR +is +\fBNULL\fR, the +\fBrealloc\fR\fB\fR +function behaves identically to +\fBmalloc\fR\fB\fR +for the specified size\&. +.PP +The +\fBfree\fR\fB\fR +function causes the allocated memory referenced by +\fIptr\fR +to be made available for future allocations\&. If +\fIptr\fR +is +\fBNULL\fR, no action occurs\&. +.SS "Non\-standard API" +.PP +The +\fBmallocx\fR\fB\fR, +\fBrallocx\fR\fB\fR, +\fBxallocx\fR\fB\fR, +\fBsallocx\fR\fB\fR, +\fBdallocx\fR\fB\fR, +\fBsdallocx\fR\fB\fR, and +\fBnallocx\fR\fB\fR +functions all have a +\fIflags\fR +argument that can be used to specify options\&. The functions only check the options that are contextually relevant\&. Use bitwise or (|) operations to specify one or more of the following: +.PP +\fBMALLOCX_LG_ALIGN(\fR\fB\fIla\fR\fR\fB) \fR +.RS 4 +Align the memory allocation to start at an address that is a multiple of +(1 << \fIla\fR)\&. This macro does not validate that +\fIla\fR +is within the valid range\&. +.RE +.PP +\fBMALLOCX_ALIGN(\fR\fB\fIa\fR\fR\fB) \fR +.RS 4 +Align the memory allocation to start at an address that is a multiple of +\fIa\fR, where +\fIa\fR +is a power of two\&. This macro does not validate that +\fIa\fR +is a power of 2\&. +.RE +.PP +\fBMALLOCX_ZERO\fR +.RS 4 +Initialize newly allocated memory to contain zero bytes\&. In the growing reallocation case, the real size prior to reallocation defines the boundary between untouched bytes and those that are initialized to contain zero bytes\&. If this macro is absent, newly allocated memory is uninitialized\&. +.RE +.PP +\fBMALLOCX_TCACHE(\fR\fB\fItc\fR\fR\fB) \fR +.RS 4 +Use the thread\-specific cache (tcache) specified by the identifier +\fItc\fR, which must have been acquired via the +"tcache\&.create" +mallctl\&. This macro does not validate that +\fItc\fR +specifies a valid identifier\&. +.RE +.PP +\fBMALLOCX_TCACHE_NONE\fR +.RS 4 +Do not use a thread\-specific cache (tcache)\&. Unless +\fBMALLOCX_TCACHE(\fR\fB\fItc\fR\fR\fB)\fR +or +\fBMALLOCX_TCACHE_NONE\fR +is specified, an automatically managed tcache will be used under many circumstances\&. This macro cannot be used in the same +\fIflags\fR +argument as +\fBMALLOCX_TCACHE(\fR\fB\fItc\fR\fR\fB)\fR\&. +.RE +.PP +\fBMALLOCX_ARENA(\fR\fB\fIa\fR\fR\fB) \fR +.RS 4 +Use the arena specified by the index +\fIa\fR\&. This macro has no effect for regions that were allocated via an arena other than the one specified\&. This macro does not validate that +\fIa\fR +specifies an arena index in the valid range\&. +.RE +.PP +The +\fBmallocx\fR\fB\fR +function allocates at least +\fIsize\fR +bytes of memory, and returns a pointer to the base address of the allocation\&. Behavior is undefined if +\fIsize\fR +is +\fB0\fR\&. +.PP +The +\fBrallocx\fR\fB\fR +function resizes the allocation at +\fIptr\fR +to be at least +\fIsize\fR +bytes, and returns a pointer to the base address of the resulting allocation, which may or may not have moved from its original location\&. Behavior is undefined if +\fIsize\fR +is +\fB0\fR\&. +.PP +The +\fBxallocx\fR\fB\fR +function resizes the allocation at +\fIptr\fR +in place to be at least +\fIsize\fR +bytes, and returns the real size of the allocation\&. If +\fIextra\fR +is non\-zero, an attempt is made to resize the allocation to be at least +(\fIsize\fR + \fIextra\fR) +bytes, though inability to allocate the extra byte(s) will not by itself result in failure to resize\&. Behavior is undefined if +\fIsize\fR +is +\fB0\fR, or if +(\fIsize\fR + \fIextra\fR > \fBSIZE_T_MAX\fR)\&. +.PP +The +\fBsallocx\fR\fB\fR +function returns the real size of the allocation at +\fIptr\fR\&. +.PP +The +\fBdallocx\fR\fB\fR +function causes the memory referenced by +\fIptr\fR +to be made available for future allocations\&. +.PP +The +\fBsdallocx\fR\fB\fR +function is an extension of +\fBdallocx\fR\fB\fR +with a +\fIsize\fR +parameter to allow the caller to pass in the allocation size as an optimization\&. The minimum valid input size is the original requested size of the allocation, and the maximum valid input size is the corresponding value returned by +\fBnallocx\fR\fB\fR +or +\fBsallocx\fR\fB\fR\&. +.PP +The +\fBnallocx\fR\fB\fR +function allocates no memory, but it performs the same size computation as the +\fBmallocx\fR\fB\fR +function, and returns the real size of the allocation that would result from the equivalent +\fBmallocx\fR\fB\fR +function call, or +\fB0\fR +if the inputs exceed the maximum supported size class and/or alignment\&. Behavior is undefined if +\fIsize\fR +is +\fB0\fR\&. +.PP +The +\fBmallctl\fR\fB\fR +function provides a general interface for introspecting the memory allocator, as well as setting modifiable parameters and triggering actions\&. The period\-separated +\fIname\fR +argument specifies a location in a tree\-structured namespace; see the +MALLCTL NAMESPACE +section for documentation on the tree contents\&. To read a value, pass a pointer via +\fIoldp\fR +to adequate space to contain the value, and a pointer to its length via +\fIoldlenp\fR; otherwise pass +\fBNULL\fR +and +\fBNULL\fR\&. Similarly, to write a value, pass a pointer to the value via +\fInewp\fR, and its length via +\fInewlen\fR; otherwise pass +\fBNULL\fR +and +\fB0\fR\&. +.PP +The +\fBmallctlnametomib\fR\fB\fR +function provides a way to avoid repeated name lookups for applications that repeatedly query the same portion of the namespace, by translating a name to a \(lqManagement Information Base\(rq (MIB) that can be passed repeatedly to +\fBmallctlbymib\fR\fB\fR\&. Upon successful return from +\fBmallctlnametomib\fR\fB\fR, +\fImibp\fR +contains an array of +\fI*miblenp\fR +integers, where +\fI*miblenp\fR +is the lesser of the number of components in +\fIname\fR +and the input value of +\fI*miblenp\fR\&. Thus it is possible to pass a +\fI*miblenp\fR +that is smaller than the number of period\-separated name components, which results in a partial MIB that can be used as the basis for constructing a complete MIB\&. For name components that are integers (e\&.g\&. the 2 in +"arenas\&.bin\&.2\&.size"), the corresponding MIB component will always be that integer\&. Therefore, it is legitimate to construct code like the following: +.sp +.if n \{\ +.RS 4 +.\} +.nf +unsigned nbins, i; +size_t mib[4]; +size_t len, miblen; + +len = sizeof(nbins); +mallctl("arenas\&.nbins", &nbins, &len, NULL, 0); + +miblen = 4; +mallctlnametomib("arenas\&.bin\&.0\&.size", mib, &miblen); +for (i = 0; i < nbins; i++) { + size_t bin_size; + + mib[2] = i; + len = sizeof(bin_size); + mallctlbymib(mib, miblen, &bin_size, &len, NULL, 0); + /* Do something with bin_size\&.\&.\&. */ +} +.fi +.if n \{\ +.RE +.\} +.PP +The +\fBmalloc_stats_print\fR\fB\fR +function writes human\-readable summary statistics via the +\fIwrite_cb\fR +callback function pointer and +\fIcbopaque\fR +data passed to +\fIwrite_cb\fR, or +\fBmalloc_message\fR\fB\fR +if +\fIwrite_cb\fR +is +\fBNULL\fR\&. This function can be called repeatedly\&. General information that never changes during execution can be omitted by specifying "g" as a character within the +\fIopts\fR +string\&. Note that +\fBmalloc_message\fR\fB\fR +uses the +\fBmallctl*\fR\fB\fR +functions internally, so inconsistent statistics can be reported if multiple threads use these functions simultaneously\&. If +\fB\-\-enable\-stats\fR +is specified during configuration, \(lqm\(rq and \(lqa\(rq can be specified to omit merged arena and per arena statistics, respectively; \(lqb\(rq, \(lql\(rq, and \(lqh\(rq can be specified to omit per size class statistics for bins, large objects, and huge objects, respectively\&. Unrecognized characters are silently ignored\&. Note that thread caching may prevent some statistics from being completely up to date, since extra locking would be required to merge counters that track thread cache operations\&. +.PP +The +\fBmalloc_usable_size\fR\fB\fR +function returns the usable size of the allocation pointed to by +\fIptr\fR\&. The return value may be larger than the size that was requested during allocation\&. The +\fBmalloc_usable_size\fR\fB\fR +function is not a mechanism for in\-place +\fBrealloc\fR\fB\fR; rather it is provided solely as a tool for introspection purposes\&. Any discrepancy between the requested allocation size and the size reported by +\fBmalloc_usable_size\fR\fB\fR +should not be depended on, since such behavior is entirely implementation\-dependent\&. +.SH "TUNING" +.PP +Once, when the first call is made to one of the memory allocation routines, the allocator initializes its internals based in part on various options that can be specified at compile\- or run\-time\&. +.PP +The string specified via +\fB\-\-with\-malloc\-conf\fR, the string pointed to by the global variable +\fImalloc_conf\fR, the \(lqname\(rq of the file referenced by the symbolic link named +/etc/malloc\&.conf, and the value of the environment variable +\fBMALLOC_CONF\fR, will be interpreted, in that order, from left to right as options\&. Note that +\fImalloc_conf\fR +may be read before +\fBmain\fR\fB\fR +is entered, so the declaration of +\fImalloc_conf\fR +should specify an initializer that contains the final value to be read by jemalloc\&. +\fB\-\-with\-malloc\-conf\fR +and +\fImalloc_conf\fR +are compile\-time mechanisms, whereas +/etc/malloc\&.conf +and +\fBMALLOC_CONF\fR +can be safely set any time prior to program invocation\&. +.PP +An options string is a comma\-separated list of option:value pairs\&. There is one key corresponding to each +"opt\&.*" +mallctl (see the +MALLCTL NAMESPACE +section for options documentation)\&. For example, +abort:true,narenas:1 +sets the +"opt\&.abort" +and +"opt\&.narenas" +options\&. Some options have boolean values (true/false), others have integer values (base 8, 10, or 16, depending on prefix), and yet others have raw string values\&. +.SH "IMPLEMENTATION NOTES" +.PP +Traditionally, allocators have used +\fBsbrk\fR(2) +to obtain memory, which is suboptimal for several reasons, including race conditions, increased fragmentation, and artificial limitations on maximum usable memory\&. If +\fBsbrk\fR(2) +is supported by the operating system, this allocator uses both +\fBmmap\fR(2) +and +\fBsbrk\fR(2), in that order of preference; otherwise only +\fBmmap\fR(2) +is used\&. +.PP +This allocator uses multiple arenas in order to reduce lock contention for threaded programs on multi\-processor systems\&. This works well with regard to threading scalability, but incurs some costs\&. There is a small fixed per\-arena overhead, and additionally, arenas manage memory completely independently of each other, which means a small fixed increase in overall memory fragmentation\&. These overheads are not generally an issue, given the number of arenas normally used\&. Note that using substantially more arenas than the default is not likely to improve performance, mainly due to reduced cache performance\&. However, it may make sense to reduce the number of arenas if an application does not make much use of the allocation functions\&. +.PP +In addition to multiple arenas, unless +\fB\-\-disable\-tcache\fR +is specified during configuration, this allocator supports thread\-specific caching for small and large objects, in order to make it possible to completely avoid synchronization for most allocation requests\&. Such caching allows very fast allocation in the common case, but it increases memory usage and fragmentation, since a bounded number of objects can remain allocated in each thread cache\&. +.PP +Memory is conceptually broken into equal\-sized chunks, where the chunk size is a power of two that is greater than the page size\&. Chunks are always aligned to multiples of the chunk size\&. This alignment makes it possible to find metadata for user objects very quickly\&. User objects are broken into three categories according to size: small, large, and huge\&. Multiple small and large objects can reside within a single chunk, whereas huge objects each have one or more chunks backing them\&. Each chunk that contains small and/or large objects tracks its contents as runs of contiguous pages (unused, backing a set of small objects, or backing one large object)\&. The combination of chunk alignment and chunk page maps makes it possible to determine all metadata regarding small and large allocations in constant time\&. +.PP +Small objects are managed in groups by page runs\&. Each run maintains a bitmap to track which regions are in use\&. Allocation requests that are no more than half the quantum (8 or 16, depending on architecture) are rounded up to the nearest power of two that is at least +sizeof(\fBdouble\fR)\&. All other object size classes are multiples of the quantum, spaced such that there are four size classes for each doubling in size, which limits internal fragmentation to approximately 20% for all but the smallest size classes\&. Small size classes are smaller than four times the page size, large size classes are smaller than the chunk size (see the +"opt\&.lg_chunk" +option), and huge size classes extend from the chunk size up to the largest size class that does not exceed +\fBPTRDIFF_MAX\fR\&. +.PP +Allocations are packed tightly together, which can be an issue for multi\-threaded applications\&. If you need to assure that allocations do not suffer from cacheline sharing, round your allocation requests up to the nearest multiple of the cacheline size, or specify cacheline alignment when allocating\&. +.PP +The +\fBrealloc\fR\fB\fR, +\fBrallocx\fR\fB\fR, and +\fBxallocx\fR\fB\fR +functions may resize allocations without moving them under limited circumstances\&. Unlike the +\fB*allocx\fR\fB\fR +API, the standard API does not officially round up the usable size of an allocation to the nearest size class, so technically it is necessary to call +\fBrealloc\fR\fB\fR +to grow e\&.g\&. a 9\-byte allocation to 16 bytes, or shrink a 16\-byte allocation to 9 bytes\&. Growth and shrinkage trivially succeeds in place as long as the pre\-size and post\-size both round up to the same size class\&. No other API guarantees are made regarding in\-place resizing, but the current implementation also tries to resize large and huge allocations in place, as long as the pre\-size and post\-size are both large or both huge\&. In such cases shrinkage always succeeds for large size classes, but for huge size classes the chunk allocator must support splitting (see +"arena\&.\&.chunk_hooks")\&. Growth only succeeds if the trailing memory is currently available, and additionally for huge size classes the chunk allocator must support merging\&. +.PP +Assuming 2 MiB chunks, 4 KiB pages, and a 16\-byte quantum on a 64\-bit system, the size classes in each category are as shown in +Table 1\&. +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&1.\ \&Size classes +.TS +allbox tab(:); +lB rB lB. +T{ +Category +T}:T{ +Spacing +T}:T{ +Size +T} +.T& +l r l +^ r l +^ r l +^ r l +^ r l +^ r l +^ r l +^ r l +^ r l +l r l +^ r l +^ r l +^ r l +^ r l +^ r l +^ r l +^ r l +l r l +^ r l +^ r l +^ r l +^ r l +^ r l +^ r l +^ r l +^ r l. +T{ +Small +T}:T{ +lg +T}:T{ +[8] +T} +:T{ +16 +T}:T{ +[16, 32, 48, 64, 80, 96, 112, 128] +T} +:T{ +32 +T}:T{ +[160, 192, 224, 256] +T} +:T{ +64 +T}:T{ +[320, 384, 448, 512] +T} +:T{ +128 +T}:T{ +[640, 768, 896, 1024] +T} +:T{ +256 +T}:T{ +[1280, 1536, 1792, 2048] +T} +:T{ +512 +T}:T{ +[2560, 3072, 3584, 4096] +T} +:T{ +1 KiB +T}:T{ +[5 KiB, 6 KiB, 7 KiB, 8 KiB] +T} +:T{ +2 KiB +T}:T{ +[10 KiB, 12 KiB, 14 KiB] +T} +T{ +Large +T}:T{ +2 KiB +T}:T{ +[16 KiB] +T} +:T{ +4 KiB +T}:T{ +[20 KiB, 24 KiB, 28 KiB, 32 KiB] +T} +:T{ +8 KiB +T}:T{ +[40 KiB, 48 KiB, 54 KiB, 64 KiB] +T} +:T{ +16 KiB +T}:T{ +[80 KiB, 96 KiB, 112 KiB, 128 KiB] +T} +:T{ +32 KiB +T}:T{ +[160 KiB, 192 KiB, 224 KiB, 256 KiB] +T} +:T{ +64 KiB +T}:T{ +[320 KiB, 384 KiB, 448 KiB, 512 KiB] +T} +:T{ +128 KiB +T}:T{ +[640 KiB, 768 KiB, 896 KiB, 1 MiB] +T} +:T{ +256 KiB +T}:T{ +[1280 KiB, 1536 KiB, 1792 KiB] +T} +T{ +Huge +T}:T{ +256 KiB +T}:T{ +[2 MiB] +T} +:T{ +512 KiB +T}:T{ +[2560 KiB, 3 MiB, 3584 KiB, 4 MiB] +T} +:T{ +1 MiB +T}:T{ +[5 MiB, 6 MiB, 7 MiB, 8 MiB] +T} +:T{ +2 MiB +T}:T{ +[10 MiB, 12 MiB, 14 MiB, 16 MiB] +T} +:T{ +4 MiB +T}:T{ +[20 MiB, 24 MiB, 28 MiB, 32 MiB] +T} +:T{ +8 MiB +T}:T{ +[40 MiB, 48 MiB, 56 MiB, 64 MiB] +T} +:T{ +\&.\&.\&. +T}:T{ +\&.\&.\&. +T} +:T{ +512 PiB +T}:T{ +[2560 PiB, 3 EiB, 3584 PiB, 4 EiB] +T} +:T{ +1 EiB +T}:T{ +[5 EiB, 6 EiB, 7 EiB] +T} +.TE +.sp 1 +.SH "MALLCTL NAMESPACE" +.PP +The following names are defined in the namespace accessible via the +\fBmallctl*\fR\fB\fR +functions\&. Value types are specified in parentheses, their readable/writable statuses are encoded as +rw, +r\-, +\-w, or +\-\-, and required build configuration flags follow, if any\&. A name element encoded as + +or + +indicates an integer component, where the integer varies from 0 to some upper value that must be determined via introspection\&. In the case of +"stats\&.arenas\&.\&.*", + +equal to +"arenas\&.narenas" +can be used to access the summation of statistics from all arenas\&. Take special note of the +"epoch" +mallctl, which controls refreshing of cached dynamic statistics\&. +.PP +"version" (\fBconst char *\fR) r\- +.RS 4 +Return the jemalloc version string\&. +.RE +.PP +"epoch" (\fBuint64_t\fR) rw +.RS 4 +If a value is passed in, refresh the data from which the +\fBmallctl*\fR\fB\fR +functions report values, and increment the epoch\&. Return the current epoch\&. This is useful for detecting whether another thread caused a refresh\&. +.RE +.PP +"config\&.cache_oblivious" (\fBbool\fR) r\- +.RS 4 +\fB\-\-enable\-cache\-oblivious\fR +was specified during build configuration\&. +.RE +.PP +"config\&.debug" (\fBbool\fR) r\- +.RS 4 +\fB\-\-enable\-debug\fR +was specified during build configuration\&. +.RE +.PP +"config\&.fill" (\fBbool\fR) r\- +.RS 4 +\fB\-\-enable\-fill\fR +was specified during build configuration\&. +.RE +.PP +"config\&.lazy_lock" (\fBbool\fR) r\- +.RS 4 +\fB\-\-enable\-lazy\-lock\fR +was specified during build configuration\&. +.RE +.PP +"config\&.malloc_conf" (\fBconst char *\fR) r\- +.RS 4 +Embedded configure\-time\-specified run\-time options string, empty unless +\fB\-\-with\-malloc\-conf\fR +was specified during build configuration\&. +.RE +.PP +"config\&.munmap" (\fBbool\fR) r\- +.RS 4 +\fB\-\-enable\-munmap\fR +was specified during build configuration\&. +.RE +.PP +"config\&.prof" (\fBbool\fR) r\- +.RS 4 +\fB\-\-enable\-prof\fR +was specified during build configuration\&. +.RE +.PP +"config\&.prof_libgcc" (\fBbool\fR) r\- +.RS 4 +\fB\-\-disable\-prof\-libgcc\fR +was not specified during build configuration\&. +.RE +.PP +"config\&.prof_libunwind" (\fBbool\fR) r\- +.RS 4 +\fB\-\-enable\-prof\-libunwind\fR +was specified during build configuration\&. +.RE +.PP +"config\&.stats" (\fBbool\fR) r\- +.RS 4 +\fB\-\-enable\-stats\fR +was specified during build configuration\&. +.RE +.PP +"config\&.tcache" (\fBbool\fR) r\- +.RS 4 +\fB\-\-disable\-tcache\fR +was not specified during build configuration\&. +.RE +.PP +"config\&.tls" (\fBbool\fR) r\- +.RS 4 +\fB\-\-disable\-tls\fR +was not specified during build configuration\&. +.RE +.PP +"config\&.utrace" (\fBbool\fR) r\- +.RS 4 +\fB\-\-enable\-utrace\fR +was specified during build configuration\&. +.RE +.PP +"config\&.valgrind" (\fBbool\fR) r\- +.RS 4 +\fB\-\-enable\-valgrind\fR +was specified during build configuration\&. +.RE +.PP +"config\&.xmalloc" (\fBbool\fR) r\- +.RS 4 +\fB\-\-enable\-xmalloc\fR +was specified during build configuration\&. +.RE +.PP +"opt\&.abort" (\fBbool\fR) r\- +.RS 4 +Abort\-on\-warning enabled/disabled\&. If true, most warnings are fatal\&. The process will call +\fBabort\fR(3) +in these cases\&. This option is disabled by default unless +\fB\-\-enable\-debug\fR +is specified during configuration, in which case it is enabled by default\&. +.RE +.PP +"opt\&.dss" (\fBconst char *\fR) r\- +.RS 4 +dss (\fBsbrk\fR(2)) allocation precedence as related to +\fBmmap\fR(2) +allocation\&. The following settings are supported if +\fBsbrk\fR(2) +is supported by the operating system: \(lqdisabled\(rq, \(lqprimary\(rq, and \(lqsecondary\(rq; otherwise only \(lqdisabled\(rq is supported\&. The default is \(lqsecondary\(rq if +\fBsbrk\fR(2) +is supported by the operating system; \(lqdisabled\(rq otherwise\&. +.RE +.PP +"opt\&.lg_chunk" (\fBsize_t\fR) r\- +.RS 4 +Virtual memory chunk size (log base 2)\&. If a chunk size outside the supported size range is specified, the size is silently clipped to the minimum/maximum supported size\&. The default chunk size is 2 MiB (2^21)\&. +.RE +.PP +"opt\&.narenas" (\fBunsigned\fR) r\- +.RS 4 +Maximum number of arenas to use for automatic multiplexing of threads and arenas\&. The default is four times the number of CPUs, or one if there is a single CPU\&. +.RE +.PP +"opt\&.purge" (\fBconst char *\fR) r\- +.RS 4 +Purge mode is \(lqratio\(rq (default) or \(lqdecay\(rq\&. See +"opt\&.lg_dirty_mult" +for details of the ratio mode\&. See +"opt\&.decay_time" +for details of the decay mode\&. +.RE +.PP +"opt\&.lg_dirty_mult" (\fBssize_t\fR) r\- +.RS 4 +Per\-arena minimum ratio (log base 2) of active to dirty pages\&. Some dirty unused pages may be allowed to accumulate, within the limit set by the ratio (or one chunk worth of dirty pages, whichever is greater), before informing the kernel about some of those pages via +\fBmadvise\fR(2) +or a similar system call\&. This provides the kernel with sufficient information to recycle dirty pages if physical memory becomes scarce and the pages remain unused\&. The default minimum ratio is 8:1 (2^3:1); an option value of \-1 will disable dirty page purging\&. See +"arenas\&.lg_dirty_mult" +and +"arena\&.\&.lg_dirty_mult" +for related dynamic control options\&. +.RE +.PP +"opt\&.decay_time" (\fBssize_t\fR) r\- +.RS 4 +Approximate time in seconds from the creation of a set of unused dirty pages until an equivalent set of unused dirty pages is purged and/or reused\&. The pages are incrementally purged according to a sigmoidal decay curve that starts and ends with zero purge rate\&. A decay time of 0 causes all unused dirty pages to be purged immediately upon creation\&. A decay time of \-1 disables purging\&. The default decay time is 10 seconds\&. See +"arenas\&.decay_time" +and +"arena\&.\&.decay_time" +for related dynamic control options\&. +.RE +.PP +"opt\&.stats_print" (\fBbool\fR) r\- +.RS 4 +Enable/disable statistics printing at exit\&. If enabled, the +\fBmalloc_stats_print\fR\fB\fR +function is called at program exit via an +\fBatexit\fR(3) +function\&. If +\fB\-\-enable\-stats\fR +is specified during configuration, this has the potential to cause deadlock for a multi\-threaded process that exits while one or more threads are executing in the memory allocation functions\&. Furthermore, +\fBatexit\fR\fB\fR +may allocate memory during application initialization and then deadlock internally when jemalloc in turn calls +\fBatexit\fR\fB\fR, so this option is not universally usable (though the application can register its own +\fBatexit\fR\fB\fR +function with equivalent functionality)\&. Therefore, this option should only be used with care; it is primarily intended as a performance tuning aid during application development\&. This option is disabled by default\&. +.RE +.PP +"opt\&.junk" (\fBconst char *\fR) r\- [\fB\-\-enable\-fill\fR] +.RS 4 +Junk filling\&. If set to "alloc", each byte of uninitialized allocated memory will be initialized to +0xa5\&. If set to "free", all deallocated memory will be initialized to +0x5a\&. If set to "true", both allocated and deallocated memory will be initialized, and if set to "false", junk filling be disabled entirely\&. This is intended for debugging and will impact performance negatively\&. This option is "false" by default unless +\fB\-\-enable\-debug\fR +is specified during configuration, in which case it is "true" by default unless running inside +\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2\&. +.RE +.PP +"opt\&.quarantine" (\fBsize_t\fR) r\- [\fB\-\-enable\-fill\fR] +.RS 4 +Per thread quarantine size in bytes\&. If non\-zero, each thread maintains a FIFO object quarantine that stores up to the specified number of bytes of memory\&. The quarantined memory is not freed until it is released from quarantine, though it is immediately junk\-filled if the +"opt\&.junk" +option is enabled\&. This feature is of particular use in combination with +\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2, which can detect attempts to access quarantined objects\&. This is intended for debugging and will impact performance negatively\&. The default quarantine size is 0 unless running inside Valgrind, in which case the default is 16 MiB\&. +.RE +.PP +"opt\&.redzone" (\fBbool\fR) r\- [\fB\-\-enable\-fill\fR] +.RS 4 +Redzones enabled/disabled\&. If enabled, small allocations have redzones before and after them\&. Furthermore, if the +"opt\&.junk" +option is enabled, the redzones are checked for corruption during deallocation\&. However, the primary intended purpose of this feature is to be used in combination with +\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2, which needs redzones in order to do effective buffer overflow/underflow detection\&. This option is intended for debugging and will impact performance negatively\&. This option is disabled by default unless running inside Valgrind\&. +.RE +.PP +"opt\&.zero" (\fBbool\fR) r\- [\fB\-\-enable\-fill\fR] +.RS 4 +Zero filling enabled/disabled\&. If enabled, each byte of uninitialized allocated memory will be initialized to 0\&. Note that this initialization only happens once for each byte, so +\fBrealloc\fR\fB\fR +and +\fBrallocx\fR\fB\fR +calls do not zero memory that was previously allocated\&. This is intended for debugging and will impact performance negatively\&. This option is disabled by default\&. +.RE +.PP +"opt\&.utrace" (\fBbool\fR) r\- [\fB\-\-enable\-utrace\fR] +.RS 4 +Allocation tracing based on +\fButrace\fR(2) +enabled/disabled\&. This option is disabled by default\&. +.RE +.PP +"opt\&.xmalloc" (\fBbool\fR) r\- [\fB\-\-enable\-xmalloc\fR] +.RS 4 +Abort\-on\-out\-of\-memory enabled/disabled\&. If enabled, rather than returning failure for any allocation function, display a diagnostic message on +\fBSTDERR_FILENO\fR +and cause the program to drop core (using +\fBabort\fR(3))\&. If an application is designed to depend on this behavior, set the option at compile time by including the following in the source code: +.sp +.if n \{\ +.RS 4 +.\} +.nf +malloc_conf = "xmalloc:true"; +.fi +.if n \{\ +.RE +.\} +.sp +This option is disabled by default\&. +.RE +.PP +"opt\&.tcache" (\fBbool\fR) r\- [\fB\-\-enable\-tcache\fR] +.RS 4 +Thread\-specific caching (tcache) enabled/disabled\&. When there are multiple threads, each thread uses a tcache for objects up to a certain size\&. Thread\-specific caching allows many allocations to be satisfied without performing any thread synchronization, at the cost of increased memory use\&. See the +"opt\&.lg_tcache_max" +option for related tuning information\&. This option is enabled by default unless running inside +\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2, in which case it is forcefully disabled\&. +.RE +.PP +"opt\&.lg_tcache_max" (\fBsize_t\fR) r\- [\fB\-\-enable\-tcache\fR] +.RS 4 +Maximum size class (log base 2) to cache in the thread\-specific cache (tcache)\&. At a minimum, all small size classes are cached, and at a maximum all large size classes are cached\&. The default maximum is 32 KiB (2^15)\&. +.RE +.PP +"opt\&.prof" (\fBbool\fR) r\- [\fB\-\-enable\-prof\fR] +.RS 4 +Memory profiling enabled/disabled\&. If enabled, profile memory allocation activity\&. See the +"opt\&.prof_active" +option for on\-the\-fly activation/deactivation\&. See the +"opt\&.lg_prof_sample" +option for probabilistic sampling control\&. See the +"opt\&.prof_accum" +option for control of cumulative sample reporting\&. See the +"opt\&.lg_prof_interval" +option for information on interval\-triggered profile dumping, the +"opt\&.prof_gdump" +option for information on high\-water\-triggered profile dumping, and the +"opt\&.prof_final" +option for final profile dumping\&. Profile output is compatible with the +\fBjeprof\fR +command, which is based on the +\fBpprof\fR +that is developed as part of the +\m[blue]\fBgperftools package\fR\m[]\&\s-2\u[3]\d\s+2\&. See +HEAP PROFILE FORMAT +for heap profile format documentation\&. +.RE +.PP +"opt\&.prof_prefix" (\fBconst char *\fR) r\- [\fB\-\-enable\-prof\fR] +.RS 4 +Filename prefix for profile dumps\&. If the prefix is set to the empty string, no automatic dumps will occur; this is primarily useful for disabling the automatic final heap dump (which also disables leak reporting, if enabled)\&. The default prefix is +jeprof\&. +.RE +.PP +"opt\&.prof_active" (\fBbool\fR) r\- [\fB\-\-enable\-prof\fR] +.RS 4 +Profiling activated/deactivated\&. This is a secondary control mechanism that makes it possible to start the application with profiling enabled (see the +"opt\&.prof" +option) but inactive, then toggle profiling at any time during program execution with the +"prof\&.active" +mallctl\&. This option is enabled by default\&. +.RE +.PP +"opt\&.prof_thread_active_init" (\fBbool\fR) r\- [\fB\-\-enable\-prof\fR] +.RS 4 +Initial setting for +"thread\&.prof\&.active" +in newly created threads\&. The initial setting for newly created threads can also be changed during execution via the +"prof\&.thread_active_init" +mallctl\&. This option is enabled by default\&. +.RE +.PP +"opt\&.lg_prof_sample" (\fBsize_t\fR) r\- [\fB\-\-enable\-prof\fR] +.RS 4 +Average interval (log base 2) between allocation samples, as measured in bytes of allocation activity\&. Increasing the sampling interval decreases profile fidelity, but also decreases the computational overhead\&. The default sample interval is 512 KiB (2^19 B)\&. +.RE +.PP +"opt\&.prof_accum" (\fBbool\fR) r\- [\fB\-\-enable\-prof\fR] +.RS 4 +Reporting of cumulative object/byte counts in profile dumps enabled/disabled\&. If this option is enabled, every unique backtrace must be stored for the duration of execution\&. Depending on the application, this can impose a large memory overhead, and the cumulative counts are not always of interest\&. This option is disabled by default\&. +.RE +.PP +"opt\&.lg_prof_interval" (\fBssize_t\fR) r\- [\fB\-\-enable\-prof\fR] +.RS 4 +Average interval (log base 2) between memory profile dumps, as measured in bytes of allocation activity\&. The actual interval between dumps may be sporadic because decentralized allocation counters are used to avoid synchronization bottlenecks\&. Profiles are dumped to files named according to the pattern +\&.\&.\&.i\&.heap, where + +is controlled by the +"opt\&.prof_prefix" +option\&. By default, interval\-triggered profile dumping is disabled (encoded as \-1)\&. +.RE +.PP +"opt\&.prof_gdump" (\fBbool\fR) r\- [\fB\-\-enable\-prof\fR] +.RS 4 +Set the initial state of +"prof\&.gdump", which when enabled triggers a memory profile dump every time the total virtual memory exceeds the previous maximum\&. This option is disabled by default\&. +.RE +.PP +"opt\&.prof_final" (\fBbool\fR) r\- [\fB\-\-enable\-prof\fR] +.RS 4 +Use an +\fBatexit\fR(3) +function to dump final memory usage to a file named according to the pattern +\&.\&.\&.f\&.heap, where + +is controlled by the +"opt\&.prof_prefix" +option\&. Note that +\fBatexit\fR\fB\fR +may allocate memory during application initialization and then deadlock internally when jemalloc in turn calls +\fBatexit\fR\fB\fR, so this option is not universally usable (though the application can register its own +\fBatexit\fR\fB\fR +function with equivalent functionality)\&. This option is disabled by default\&. +.RE +.PP +"opt\&.prof_leak" (\fBbool\fR) r\- [\fB\-\-enable\-prof\fR] +.RS 4 +Leak reporting enabled/disabled\&. If enabled, use an +\fBatexit\fR(3) +function to report memory leaks detected by allocation sampling\&. See the +"opt\&.prof" +option for information on analyzing heap profile output\&. This option is disabled by default\&. +.RE +.PP +"thread\&.arena" (\fBunsigned\fR) rw +.RS 4 +Get or set the arena associated with the calling thread\&. If the specified arena was not initialized beforehand (see the +"arenas\&.initialized" +mallctl), it will be automatically initialized as a side effect of calling this interface\&. +.RE +.PP +"thread\&.allocated" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Get the total number of bytes ever allocated by the calling thread\&. This counter has the potential to wrap around; it is up to the application to appropriately interpret the counter in such cases\&. +.RE +.PP +"thread\&.allocatedp" (\fBuint64_t *\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Get a pointer to the the value that is returned by the +"thread\&.allocated" +mallctl\&. This is useful for avoiding the overhead of repeated +\fBmallctl*\fR\fB\fR +calls\&. +.RE +.PP +"thread\&.deallocated" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Get the total number of bytes ever deallocated by the calling thread\&. This counter has the potential to wrap around; it is up to the application to appropriately interpret the counter in such cases\&. +.RE +.PP +"thread\&.deallocatedp" (\fBuint64_t *\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Get a pointer to the the value that is returned by the +"thread\&.deallocated" +mallctl\&. This is useful for avoiding the overhead of repeated +\fBmallctl*\fR\fB\fR +calls\&. +.RE +.PP +"thread\&.tcache\&.enabled" (\fBbool\fR) rw [\fB\-\-enable\-tcache\fR] +.RS 4 +Enable/disable calling thread\*(Aqs tcache\&. The tcache is implicitly flushed as a side effect of becoming disabled (see +"thread\&.tcache\&.flush")\&. +.RE +.PP +"thread\&.tcache\&.flush" (\fBvoid\fR) \-\- [\fB\-\-enable\-tcache\fR] +.RS 4 +Flush calling thread\*(Aqs thread\-specific cache (tcache)\&. This interface releases all cached objects and internal data structures associated with the calling thread\*(Aqs tcache\&. Ordinarily, this interface need not be called, since automatic periodic incremental garbage collection occurs, and the thread cache is automatically discarded when a thread exits\&. However, garbage collection is triggered by allocation activity, so it is possible for a thread that stops allocating/deallocating to retain its cache indefinitely, in which case the developer may find manual flushing useful\&. +.RE +.PP +"thread\&.prof\&.name" (\fBconst char *\fR) r\- or \-w [\fB\-\-enable\-prof\fR] +.RS 4 +Get/set the descriptive name associated with the calling thread in memory profile dumps\&. An internal copy of the name string is created, so the input string need not be maintained after this interface completes execution\&. The output string of this interface should be copied for non\-ephemeral uses, because multiple implementation details can cause asynchronous string deallocation\&. Furthermore, each invocation of this interface can only read or write; simultaneous read/write is not supported due to string lifetime limitations\&. The name string must be nil\-terminated and comprised only of characters in the sets recognized by +\fBisgraph\fR(3) +and +\fBisblank\fR(3)\&. +.RE +.PP +"thread\&.prof\&.active" (\fBbool\fR) rw [\fB\-\-enable\-prof\fR] +.RS 4 +Control whether sampling is currently active for the calling thread\&. This is an activation mechanism in addition to +"prof\&.active"; both must be active for the calling thread to sample\&. This flag is enabled by default\&. +.RE +.PP +"tcache\&.create" (\fBunsigned\fR) r\- [\fB\-\-enable\-tcache\fR] +.RS 4 +Create an explicit thread\-specific cache (tcache) and return an identifier that can be passed to the +\fBMALLOCX_TCACHE(\fR\fB\fItc\fR\fR\fB)\fR +macro to explicitly use the specified cache rather than the automatically managed one that is used by default\&. Each explicit cache can be used by only one thread at a time; the application must assure that this constraint holds\&. +.RE +.PP +"tcache\&.flush" (\fBunsigned\fR) \-w [\fB\-\-enable\-tcache\fR] +.RS 4 +Flush the specified thread\-specific cache (tcache)\&. The same considerations apply to this interface as to +"thread\&.tcache\&.flush", except that the tcache will never be automatically discarded\&. +.RE +.PP +"tcache\&.destroy" (\fBunsigned\fR) \-w [\fB\-\-enable\-tcache\fR] +.RS 4 +Flush the specified thread\-specific cache (tcache) and make the identifier available for use during a future tcache creation\&. +.RE +.PP +"arena\&.\&.purge" (\fBvoid\fR) \-\- +.RS 4 +Purge all unused dirty pages for arena , or for all arenas if equals +"arenas\&.narenas"\&. +.RE +.PP +"arena\&.\&.decay" (\fBvoid\fR) \-\- +.RS 4 +Trigger decay\-based purging of unused dirty pages for arena , or for all arenas if equals +"arenas\&.narenas"\&. The proportion of unused dirty pages to be purged depends on the current time; see +"opt\&.decay_time" +for details\&. +.RE +.PP +"arena\&.\&.reset" (\fBvoid\fR) \-\- +.RS 4 +Discard all of the arena\*(Aqs extant allocations\&. This interface can only be used with arenas created via +"arenas\&.extend"\&. None of the arena\*(Aqs discarded/cached allocations may accessed afterward\&. As part of this requirement, all thread caches which were used to allocate/deallocate in conjunction with the arena must be flushed beforehand\&. This interface cannot be used if running inside Valgrind, nor if the +quarantine +size is non\-zero\&. +.RE +.PP +"arena\&.\&.dss" (\fBconst char *\fR) rw +.RS 4 +Set the precedence of dss allocation as related to mmap allocation for arena , or for all arenas if equals +"arenas\&.narenas"\&. See +"opt\&.dss" +for supported settings\&. +.RE +.PP +"arena\&.\&.lg_dirty_mult" (\fBssize_t\fR) rw +.RS 4 +Current per\-arena minimum ratio (log base 2) of active to dirty pages for arena \&. Each time this interface is set and the ratio is increased, pages are synchronously purged as necessary to impose the new ratio\&. See +"opt\&.lg_dirty_mult" +for additional information\&. +.RE +.PP +"arena\&.\&.decay_time" (\fBssize_t\fR) rw +.RS 4 +Current per\-arena approximate time in seconds from the creation of a set of unused dirty pages until an equivalent set of unused dirty pages is purged and/or reused\&. Each time this interface is set, all currently unused dirty pages are considered to have fully decayed, which causes immediate purging of all unused dirty pages unless the decay time is set to \-1 (i\&.e\&. purging disabled)\&. See +"opt\&.decay_time" +for additional information\&. +.RE +.PP +"arena\&.\&.chunk_hooks" (\fBchunk_hooks_t\fR) rw +.RS 4 +Get or set the chunk management hook functions for arena \&. The functions must be capable of operating on all extant chunks associated with arena , usually by passing unknown chunks to the replaced functions\&. In practice, it is feasible to control allocation for arenas created via +"arenas\&.extend" +such that all chunks originate from an application\-supplied chunk allocator (by setting custom chunk hook functions just after arena creation), but the automatically created arenas may have already created chunks prior to the application having an opportunity to take over chunk allocation\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +typedef struct { + chunk_alloc_t *alloc; + chunk_dalloc_t *dalloc; + chunk_commit_t *commit; + chunk_decommit_t *decommit; + chunk_purge_t *purge; + chunk_split_t *split; + chunk_merge_t *merge; +} chunk_hooks_t; +.fi +.if n \{\ +.RE +.\} +.sp +The +\fBchunk_hooks_t\fR +structure comprises function pointers which are described individually below\&. jemalloc uses these functions to manage chunk lifetime, which starts off with allocation of mapped committed memory, in the simplest case followed by deallocation\&. However, there are performance and platform reasons to retain chunks for later reuse\&. Cleanup attempts cascade from deallocation to decommit to purging, which gives the chunk management functions opportunities to reject the most permanent cleanup operations in favor of less permanent (and often less costly) operations\&. The chunk splitting and merging operations can also be opted out of, but this is mainly intended to support platforms on which virtual memory mappings provided by the operating system kernel do not automatically coalesce and split, e\&.g\&. Windows\&. +.HP \w'typedef\ void\ *(chunk_alloc_t)('u +.BI "typedef void *(chunk_alloc_t)(void\ *" "chunk" ", size_t\ " "size" ", size_t\ " "alignment" ", bool\ *" "zero" ", bool\ *" "commit" ", unsigned\ " "arena_ind" ");" +.sp +.if n \{\ +.RS 4 +.\} +.nf +.fi +.if n \{\ +.RE +.\} +.sp +A chunk allocation function conforms to the +\fBchunk_alloc_t\fR +type and upon success returns a pointer to +\fIsize\fR +bytes of mapped memory on behalf of arena +\fIarena_ind\fR +such that the chunk\*(Aqs base address is a multiple of +\fIalignment\fR, as well as setting +\fI*zero\fR +to indicate whether the chunk is zeroed and +\fI*commit\fR +to indicate whether the chunk is committed\&. Upon error the function returns +\fBNULL\fR +and leaves +\fI*zero\fR +and +\fI*commit\fR +unmodified\&. The +\fIsize\fR +parameter is always a multiple of the chunk size\&. The +\fIalignment\fR +parameter is always a power of two at least as large as the chunk size\&. Zeroing is mandatory if +\fI*zero\fR +is true upon function entry\&. Committing is mandatory if +\fI*commit\fR +is true upon function entry\&. If +\fIchunk\fR +is not +\fBNULL\fR, the returned pointer must be +\fIchunk\fR +on success or +\fBNULL\fR +on error\&. Committed memory may be committed in absolute terms as on a system that does not overcommit, or in implicit terms as on a system that overcommits and satisfies physical memory needs on demand via soft page faults\&. Note that replacing the default chunk allocation function makes the arena\*(Aqs +"arena\&.\&.dss" +setting irrelevant\&. +.HP \w'typedef\ bool\ (chunk_dalloc_t)('u +.BI "typedef bool (chunk_dalloc_t)(void\ *" "chunk" ", size_t\ " "size" ", bool\ " "committed" ", unsigned\ " "arena_ind" ");" +.sp +.if n \{\ +.RS 4 +.\} +.nf +.fi +.if n \{\ +.RE +.\} +.sp +A chunk deallocation function conforms to the +\fBchunk_dalloc_t\fR +type and deallocates a +\fIchunk\fR +of given +\fIsize\fR +with +\fIcommitted\fR/decommited memory as indicated, on behalf of arena +\fIarena_ind\fR, returning false upon success\&. If the function returns true, this indicates opt\-out from deallocation; the virtual memory mapping associated with the chunk remains mapped, in the same commit state, and available for future use, in which case it will be automatically retained for later reuse\&. +.HP \w'typedef\ bool\ (chunk_commit_t)('u +.BI "typedef bool (chunk_commit_t)(void\ *" "chunk" ", size_t\ " "size" ", size_t\ " "offset" ", size_t\ " "length" ", unsigned\ " "arena_ind" ");" +.sp +.if n \{\ +.RS 4 +.\} +.nf +.fi +.if n \{\ +.RE +.\} +.sp +A chunk commit function conforms to the +\fBchunk_commit_t\fR +type and commits zeroed physical memory to back pages within a +\fIchunk\fR +of given +\fIsize\fR +at +\fIoffset\fR +bytes, extending for +\fIlength\fR +on behalf of arena +\fIarena_ind\fR, returning false upon success\&. Committed memory may be committed in absolute terms as on a system that does not overcommit, or in implicit terms as on a system that overcommits and satisfies physical memory needs on demand via soft page faults\&. If the function returns true, this indicates insufficient physical memory to satisfy the request\&. +.HP \w'typedef\ bool\ (chunk_decommit_t)('u +.BI "typedef bool (chunk_decommit_t)(void\ *" "chunk" ", size_t\ " "size" ", size_t\ " "offset" ", size_t\ " "length" ", unsigned\ " "arena_ind" ");" +.sp +.if n \{\ +.RS 4 +.\} +.nf +.fi +.if n \{\ +.RE +.\} +.sp +A chunk decommit function conforms to the +\fBchunk_decommit_t\fR +type and decommits any physical memory that is backing pages within a +\fIchunk\fR +of given +\fIsize\fR +at +\fIoffset\fR +bytes, extending for +\fIlength\fR +on behalf of arena +\fIarena_ind\fR, returning false upon success, in which case the pages will be committed via the chunk commit function before being reused\&. If the function returns true, this indicates opt\-out from decommit; the memory remains committed and available for future use, in which case it will be automatically retained for later reuse\&. +.HP \w'typedef\ bool\ (chunk_purge_t)('u +.BI "typedef bool (chunk_purge_t)(void\ *" "chunk" ", size_t" "size" ", size_t\ " "offset" ", size_t\ " "length" ", unsigned\ " "arena_ind" ");" +.sp +.if n \{\ +.RS 4 +.\} +.nf +.fi +.if n \{\ +.RE +.\} +.sp +A chunk purge function conforms to the +\fBchunk_purge_t\fR +type and optionally discards physical pages within the virtual memory mapping associated with +\fIchunk\fR +of given +\fIsize\fR +at +\fIoffset\fR +bytes, extending for +\fIlength\fR +on behalf of arena +\fIarena_ind\fR, returning false if pages within the purged virtual memory range will be zero\-filled the next time they are accessed\&. +.HP \w'typedef\ bool\ (chunk_split_t)('u +.BI "typedef bool (chunk_split_t)(void\ *" "chunk" ", size_t\ " "size" ", size_t\ " "size_a" ", size_t\ " "size_b" ", bool\ " "committed" ", unsigned\ " "arena_ind" ");" +.sp +.if n \{\ +.RS 4 +.\} +.nf +.fi +.if n \{\ +.RE +.\} +.sp +A chunk split function conforms to the +\fBchunk_split_t\fR +type and optionally splits +\fIchunk\fR +of given +\fIsize\fR +into two adjacent chunks, the first of +\fIsize_a\fR +bytes, and the second of +\fIsize_b\fR +bytes, operating on +\fIcommitted\fR/decommitted memory as indicated, on behalf of arena +\fIarena_ind\fR, returning false upon success\&. If the function returns true, this indicates that the chunk remains unsplit and therefore should continue to be operated on as a whole\&. +.HP \w'typedef\ bool\ (chunk_merge_t)('u +.BI "typedef bool (chunk_merge_t)(void\ *" "chunk_a" ", size_t\ " "size_a" ", void\ *" "chunk_b" ", size_t\ " "size_b" ", bool\ " "committed" ", unsigned\ " "arena_ind" ");" +.sp +.if n \{\ +.RS 4 +.\} +.nf +.fi +.if n \{\ +.RE +.\} +.sp +A chunk merge function conforms to the +\fBchunk_merge_t\fR +type and optionally merges adjacent chunks, +\fIchunk_a\fR +of given +\fIsize_a\fR +and +\fIchunk_b\fR +of given +\fIsize_b\fR +into one contiguous chunk, operating on +\fIcommitted\fR/decommitted memory as indicated, on behalf of arena +\fIarena_ind\fR, returning false upon success\&. If the function returns true, this indicates that the chunks remain distinct mappings and therefore should continue to be operated on independently\&. +.RE +.PP +"arenas\&.narenas" (\fBunsigned\fR) r\- +.RS 4 +Current limit on number of arenas\&. +.RE +.PP +"arenas\&.initialized" (\fBbool *\fR) r\- +.RS 4 +An array of +"arenas\&.narenas" +booleans\&. Each boolean indicates whether the corresponding arena is initialized\&. +.RE +.PP +"arenas\&.lg_dirty_mult" (\fBssize_t\fR) rw +.RS 4 +Current default per\-arena minimum ratio (log base 2) of active to dirty pages, used to initialize +"arena\&.\&.lg_dirty_mult" +during arena creation\&. See +"opt\&.lg_dirty_mult" +for additional information\&. +.RE +.PP +"arenas\&.decay_time" (\fBssize_t\fR) rw +.RS 4 +Current default per\-arena approximate time in seconds from the creation of a set of unused dirty pages until an equivalent set of unused dirty pages is purged and/or reused, used to initialize +"arena\&.\&.decay_time" +during arena creation\&. See +"opt\&.decay_time" +for additional information\&. +.RE +.PP +"arenas\&.quantum" (\fBsize_t\fR) r\- +.RS 4 +Quantum size\&. +.RE +.PP +"arenas\&.page" (\fBsize_t\fR) r\- +.RS 4 +Page size\&. +.RE +.PP +"arenas\&.tcache_max" (\fBsize_t\fR) r\- [\fB\-\-enable\-tcache\fR] +.RS 4 +Maximum thread\-cached size class\&. +.RE +.PP +"arenas\&.nbins" (\fBunsigned\fR) r\- +.RS 4 +Number of bin size classes\&. +.RE +.PP +"arenas\&.nhbins" (\fBunsigned\fR) r\- [\fB\-\-enable\-tcache\fR] +.RS 4 +Total number of thread cache bin size classes\&. +.RE +.PP +"arenas\&.bin\&.\&.size" (\fBsize_t\fR) r\- +.RS 4 +Maximum size supported by size class\&. +.RE +.PP +"arenas\&.bin\&.\&.nregs" (\fBuint32_t\fR) r\- +.RS 4 +Number of regions per page run\&. +.RE +.PP +"arenas\&.bin\&.\&.run_size" (\fBsize_t\fR) r\- +.RS 4 +Number of bytes per page run\&. +.RE +.PP +"arenas\&.nlruns" (\fBunsigned\fR) r\- +.RS 4 +Total number of large size classes\&. +.RE +.PP +"arenas\&.lrun\&.\&.size" (\fBsize_t\fR) r\- +.RS 4 +Maximum size supported by this large size class\&. +.RE +.PP +"arenas\&.nhchunks" (\fBunsigned\fR) r\- +.RS 4 +Total number of huge size classes\&. +.RE +.PP +"arenas\&.hchunk\&.\&.size" (\fBsize_t\fR) r\- +.RS 4 +Maximum size supported by this huge size class\&. +.RE +.PP +"arenas\&.extend" (\fBunsigned\fR) r\- +.RS 4 +Extend the array of arenas by appending a new arena, and returning the new arena index\&. +.RE +.PP +"prof\&.thread_active_init" (\fBbool\fR) rw [\fB\-\-enable\-prof\fR] +.RS 4 +Control the initial setting for +"thread\&.prof\&.active" +in newly created threads\&. See the +"opt\&.prof_thread_active_init" +option for additional information\&. +.RE +.PP +"prof\&.active" (\fBbool\fR) rw [\fB\-\-enable\-prof\fR] +.RS 4 +Control whether sampling is currently active\&. See the +"opt\&.prof_active" +option for additional information, as well as the interrelated +"thread\&.prof\&.active" +mallctl\&. +.RE +.PP +"prof\&.dump" (\fBconst char *\fR) \-w [\fB\-\-enable\-prof\fR] +.RS 4 +Dump a memory profile to the specified file, or if NULL is specified, to a file according to the pattern +\&.\&.\&.m\&.heap, where + +is controlled by the +"opt\&.prof_prefix" +option\&. +.RE +.PP +"prof\&.gdump" (\fBbool\fR) rw [\fB\-\-enable\-prof\fR] +.RS 4 +When enabled, trigger a memory profile dump every time the total virtual memory exceeds the previous maximum\&. Profiles are dumped to files named according to the pattern +\&.\&.\&.u\&.heap, where + +is controlled by the +"opt\&.prof_prefix" +option\&. +.RE +.PP +"prof\&.reset" (\fBsize_t\fR) \-w [\fB\-\-enable\-prof\fR] +.RS 4 +Reset all memory profile statistics, and optionally update the sample rate (see +"opt\&.lg_prof_sample" +and +"prof\&.lg_sample")\&. +.RE +.PP +"prof\&.lg_sample" (\fBsize_t\fR) r\- [\fB\-\-enable\-prof\fR] +.RS 4 +Get the current sample rate (see +"opt\&.lg_prof_sample")\&. +.RE +.PP +"prof\&.interval" (\fBuint64_t\fR) r\- [\fB\-\-enable\-prof\fR] +.RS 4 +Average number of bytes allocated between interval\-based profile dumps\&. See the +"opt\&.lg_prof_interval" +option for additional information\&. +.RE +.PP +"stats\&.cactive" (\fBsize_t *\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Pointer to a counter that contains an approximate count of the current number of bytes in active pages\&. The estimate may be high, but never low, because each arena rounds up when computing its contribution to the counter\&. Note that the +"epoch" +mallctl has no bearing on this counter\&. Furthermore, counter consistency is maintained via atomic operations, so it is necessary to use an atomic operation in order to guarantee a consistent read when dereferencing the pointer\&. +.RE +.PP +"stats\&.allocated" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Total number of bytes allocated by the application\&. +.RE +.PP +"stats\&.active" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Total number of bytes in active pages allocated by the application\&. This is a multiple of the page size, and greater than or equal to +"stats\&.allocated"\&. This does not include +"stats\&.arenas\&.\&.pdirty", nor pages entirely devoted to allocator metadata\&. +.RE +.PP +"stats\&.metadata" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Total number of bytes dedicated to metadata, which comprise base allocations used for bootstrap\-sensitive internal allocator data structures, arena chunk headers (see +"stats\&.arenas\&.\&.metadata\&.mapped"), and internal allocations (see +"stats\&.arenas\&.\&.metadata\&.allocated")\&. +.RE +.PP +"stats\&.resident" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Maximum number of bytes in physically resident data pages mapped by the allocator, comprising all pages dedicated to allocator metadata, pages backing active allocations, and unused dirty pages\&. This is a maximum rather than precise because pages may not actually be physically resident if they correspond to demand\-zeroed virtual memory that has not yet been touched\&. This is a multiple of the page size, and is larger than +"stats\&.active"\&. +.RE +.PP +"stats\&.mapped" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Total number of bytes in active chunks mapped by the allocator\&. This is a multiple of the chunk size, and is larger than +"stats\&.active"\&. This does not include inactive chunks, even those that contain unused dirty pages, which means that there is no strict ordering between this and +"stats\&.resident"\&. +.RE +.PP +"stats\&.retained" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Total number of bytes in virtual memory mappings that were retained rather than being returned to the operating system via e\&.g\&. +\fBmunmap\fR(2)\&. Retained virtual memory is typically untouched, decommitted, or purged, so it has no strongly associated physical memory (see +chunk hooks +for details)\&. Retained memory is excluded from mapped memory statistics, e\&.g\&. +"stats\&.mapped"\&. +.RE +.PP +"stats\&.arenas\&.\&.dss" (\fBconst char *\fR) r\- +.RS 4 +dss (\fBsbrk\fR(2)) allocation precedence as related to +\fBmmap\fR(2) +allocation\&. See +"opt\&.dss" +for details\&. +.RE +.PP +"stats\&.arenas\&.\&.lg_dirty_mult" (\fBssize_t\fR) r\- +.RS 4 +Minimum ratio (log base 2) of active to dirty pages\&. See +"opt\&.lg_dirty_mult" +for details\&. +.RE +.PP +"stats\&.arenas\&.\&.decay_time" (\fBssize_t\fR) r\- +.RS 4 +Approximate time in seconds from the creation of a set of unused dirty pages until an equivalent set of unused dirty pages is purged and/or reused\&. See +"opt\&.decay_time" +for details\&. +.RE +.PP +"stats\&.arenas\&.\&.nthreads" (\fBunsigned\fR) r\- +.RS 4 +Number of threads currently assigned to arena\&. +.RE +.PP +"stats\&.arenas\&.\&.pactive" (\fBsize_t\fR) r\- +.RS 4 +Number of pages in active runs\&. +.RE +.PP +"stats\&.arenas\&.\&.pdirty" (\fBsize_t\fR) r\- +.RS 4 +Number of pages within unused runs that are potentially dirty, and for which +\fBmadvise\fR\fB\fI\&.\&.\&.\fR\fR\fB \fR\fB\fI\fBMADV_DONTNEED\fR\fR\fR +or similar has not been called\&. +.RE +.PP +"stats\&.arenas\&.\&.mapped" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Number of mapped bytes\&. +.RE +.PP +"stats\&.arenas\&.\&.retained" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Number of retained bytes\&. See +"stats\&.retained" +for details\&. +.RE +.PP +"stats\&.arenas\&.\&.metadata\&.mapped" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Number of mapped bytes in arena chunk headers, which track the states of the non\-metadata pages\&. +.RE +.PP +"stats\&.arenas\&.\&.metadata\&.allocated" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Number of bytes dedicated to internal allocations\&. Internal allocations differ from application\-originated allocations in that they are for internal use, and that they are omitted from heap profiles\&. This statistic is reported separately from +"stats\&.metadata" +and +"stats\&.arenas\&.\&.metadata\&.mapped" +because it overlaps with e\&.g\&. the +"stats\&.allocated" +and +"stats\&.active" +statistics, whereas the other metadata statistics do not\&. +.RE +.PP +"stats\&.arenas\&.\&.npurge" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Number of dirty page purge sweeps performed\&. +.RE +.PP +"stats\&.arenas\&.\&.nmadvise" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Number of +\fBmadvise\fR\fB\fI\&.\&.\&.\fR\fR\fB \fR\fB\fI\fBMADV_DONTNEED\fR\fR\fR +or similar calls made to purge dirty pages\&. +.RE +.PP +"stats\&.arenas\&.\&.purged" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Number of pages purged\&. +.RE +.PP +"stats\&.arenas\&.\&.small\&.allocated" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Number of bytes currently allocated by small objects\&. +.RE +.PP +"stats\&.arenas\&.\&.small\&.nmalloc" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of allocation requests served by small bins\&. +.RE +.PP +"stats\&.arenas\&.\&.small\&.ndalloc" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of small objects returned to bins\&. +.RE +.PP +"stats\&.arenas\&.\&.small\&.nrequests" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of small allocation requests\&. +.RE +.PP +"stats\&.arenas\&.\&.large\&.allocated" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Number of bytes currently allocated by large objects\&. +.RE +.PP +"stats\&.arenas\&.\&.large\&.nmalloc" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of large allocation requests served directly by the arena\&. +.RE +.PP +"stats\&.arenas\&.\&.large\&.ndalloc" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of large deallocation requests served directly by the arena\&. +.RE +.PP +"stats\&.arenas\&.\&.large\&.nrequests" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of large allocation requests\&. +.RE +.PP +"stats\&.arenas\&.\&.huge\&.allocated" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Number of bytes currently allocated by huge objects\&. +.RE +.PP +"stats\&.arenas\&.\&.huge\&.nmalloc" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of huge allocation requests served directly by the arena\&. +.RE +.PP +"stats\&.arenas\&.\&.huge\&.ndalloc" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of huge deallocation requests served directly by the arena\&. +.RE +.PP +"stats\&.arenas\&.\&.huge\&.nrequests" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of huge allocation requests\&. +.RE +.PP +"stats\&.arenas\&.\&.bins\&.\&.nmalloc" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of allocations served by bin\&. +.RE +.PP +"stats\&.arenas\&.\&.bins\&.\&.ndalloc" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of allocations returned to bin\&. +.RE +.PP +"stats\&.arenas\&.\&.bins\&.\&.nrequests" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of allocation requests\&. +.RE +.PP +"stats\&.arenas\&.\&.bins\&.\&.curregs" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Current number of regions for this size class\&. +.RE +.PP +"stats\&.arenas\&.\&.bins\&.\&.nfills" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR \fB\-\-enable\-tcache\fR] +.RS 4 +Cumulative number of tcache fills\&. +.RE +.PP +"stats\&.arenas\&.\&.bins\&.\&.nflushes" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR \fB\-\-enable\-tcache\fR] +.RS 4 +Cumulative number of tcache flushes\&. +.RE +.PP +"stats\&.arenas\&.\&.bins\&.\&.nruns" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of runs created\&. +.RE +.PP +"stats\&.arenas\&.\&.bins\&.\&.nreruns" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of times the current run from which to allocate changed\&. +.RE +.PP +"stats\&.arenas\&.\&.bins\&.\&.curruns" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Current number of runs\&. +.RE +.PP +"stats\&.arenas\&.\&.lruns\&.\&.nmalloc" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of allocation requests for this size class served directly by the arena\&. +.RE +.PP +"stats\&.arenas\&.\&.lruns\&.\&.ndalloc" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of deallocation requests for this size class served directly by the arena\&. +.RE +.PP +"stats\&.arenas\&.\&.lruns\&.\&.nrequests" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of allocation requests for this size class\&. +.RE +.PP +"stats\&.arenas\&.\&.lruns\&.\&.curruns" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Current number of runs for this size class\&. +.RE +.PP +"stats\&.arenas\&.\&.hchunks\&.\&.nmalloc" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of allocation requests for this size class served directly by the arena\&. +.RE +.PP +"stats\&.arenas\&.\&.hchunks\&.\&.ndalloc" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of deallocation requests for this size class served directly by the arena\&. +.RE +.PP +"stats\&.arenas\&.\&.hchunks\&.\&.nrequests" (\fBuint64_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Cumulative number of allocation requests for this size class\&. +.RE +.PP +"stats\&.arenas\&.\&.hchunks\&.\&.curhchunks" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR] +.RS 4 +Current number of huge allocations for this size class\&. +.RE +.SH "HEAP PROFILE FORMAT" +.PP +Although the heap profiling functionality was originally designed to be compatible with the +\fBpprof\fR +command that is developed as part of the +\m[blue]\fBgperftools package\fR\m[]\&\s-2\u[3]\d\s+2, the addition of per thread heap profiling functionality required a different heap profile format\&. The +\fBjeprof\fR +command is derived from +\fBpprof\fR, with enhancements to support the heap profile format described here\&. +.PP +In the following hypothetical heap profile, +\fB[\&.\&.\&.]\fR +indicates elision for the sake of compactness\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +heap_v2/524288 + t*: 28106: 56637512 [0: 0] + [\&.\&.\&.] + t3: 352: 16777344 [0: 0] + [\&.\&.\&.] + t99: 17754: 29341640 [0: 0] + [\&.\&.\&.] +@ 0x5f86da8 0x5f5a1dc [\&.\&.\&.] 0x29e4d4e 0xa200316 0xabb2988 [\&.\&.\&.] + t*: 13: 6688 [0: 0] + t3: 12: 6496 [0: ] + t99: 1: 192 [0: 0] +[\&.\&.\&.] + +MAPPED_LIBRARIES: +[\&.\&.\&.] +.fi +.if n \{\ +.RE +.\} +.sp +The following matches the above heap profile, but most tokens are replaced with +\fB\fR +to indicate descriptions of the corresponding fields\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +/ + : : [: ] + [\&.\&.\&.] + : : [: ] + [\&.\&.\&.] + : : [: ] + [\&.\&.\&.] +@ [\&.\&.\&.] [\&.\&.\&.] + : : [: ] + : : [: ] + : : [: ] +[\&.\&.\&.] + +MAPPED_LIBRARIES: +/maps> +.fi +.if n \{\ +.RE +.\} +.SH "DEBUGGING MALLOC PROBLEMS" +.PP +When debugging, it is a good idea to configure/build jemalloc with the +\fB\-\-enable\-debug\fR +and +\fB\-\-enable\-fill\fR +options, and recompile the program with suitable options and symbols for debugger support\&. When so configured, jemalloc incorporates a wide variety of run\-time assertions that catch application errors such as double\-free, write\-after\-free, etc\&. +.PP +Programs often accidentally depend on \(lquninitialized\(rq memory actually being filled with zero bytes\&. Junk filling (see the +"opt\&.junk" +option) tends to expose such bugs in the form of obviously incorrect results and/or coredumps\&. Conversely, zero filling (see the +"opt\&.zero" +option) eliminates the symptoms of such bugs\&. Between these two options, it is usually possible to quickly detect, diagnose, and eliminate such bugs\&. +.PP +This implementation does not provide much detail about the problems it detects, because the performance impact for storing such information would be prohibitive\&. However, jemalloc does integrate with the most excellent +\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2 +tool if the +\fB\-\-enable\-valgrind\fR +configuration option is enabled\&. +.SH "DIAGNOSTIC MESSAGES" +.PP +If any of the memory allocation/deallocation functions detect an error or warning condition, a message will be printed to file descriptor +\fBSTDERR_FILENO\fR\&. Errors will result in the process dumping core\&. If the +"opt\&.abort" +option is set, most warnings are treated as errors\&. +.PP +The +\fImalloc_message\fR +variable allows the programmer to override the function which emits the text strings forming the errors and warnings if for some reason the +\fBSTDERR_FILENO\fR +file descriptor is not suitable for this\&. +\fBmalloc_message\fR\fB\fR +takes the +\fIcbopaque\fR +pointer argument that is +\fBNULL\fR +unless overridden by the arguments in a call to +\fBmalloc_stats_print\fR\fB\fR, followed by a string pointer\&. Please note that doing anything which tries to allocate memory in this function is likely to result in a crash or deadlock\&. +.PP +All messages are prefixed by \(lq:\(rq\&. +.SH "RETURN VALUES" +.SS "Standard API" +.PP +The +\fBmalloc\fR\fB\fR +and +\fBcalloc\fR\fB\fR +functions return a pointer to the allocated memory if successful; otherwise a +\fBNULL\fR +pointer is returned and +\fIerrno\fR +is set to +ENOMEM\&. +.PP +The +\fBposix_memalign\fR\fB\fR +function returns the value 0 if successful; otherwise it returns an error value\&. The +\fBposix_memalign\fR\fB\fR +function will fail if: +.PP +EINVAL +.RS 4 +The +\fIalignment\fR +parameter is not a power of 2 at least as large as +sizeof(\fBvoid *\fR)\&. +.RE +.PP +ENOMEM +.RS 4 +Memory allocation error\&. +.RE +.PP +The +\fBaligned_alloc\fR\fB\fR +function returns a pointer to the allocated memory if successful; otherwise a +\fBNULL\fR +pointer is returned and +\fIerrno\fR +is set\&. The +\fBaligned_alloc\fR\fB\fR +function will fail if: +.PP +EINVAL +.RS 4 +The +\fIalignment\fR +parameter is not a power of 2\&. +.RE +.PP +ENOMEM +.RS 4 +Memory allocation error\&. +.RE +.PP +The +\fBrealloc\fR\fB\fR +function returns a pointer, possibly identical to +\fIptr\fR, to the allocated memory if successful; otherwise a +\fBNULL\fR +pointer is returned, and +\fIerrno\fR +is set to +ENOMEM +if the error was the result of an allocation failure\&. The +\fBrealloc\fR\fB\fR +function always leaves the original buffer intact when an error occurs\&. +.PP +The +\fBfree\fR\fB\fR +function returns no value\&. +.SS "Non\-standard API" +.PP +The +\fBmallocx\fR\fB\fR +and +\fBrallocx\fR\fB\fR +functions return a pointer to the allocated memory if successful; otherwise a +\fBNULL\fR +pointer is returned to indicate insufficient contiguous memory was available to service the allocation request\&. +.PP +The +\fBxallocx\fR\fB\fR +function returns the real size of the resulting resized allocation pointed to by +\fIptr\fR, which is a value less than +\fIsize\fR +if the allocation could not be adequately grown in place\&. +.PP +The +\fBsallocx\fR\fB\fR +function returns the real size of the allocation pointed to by +\fIptr\fR\&. +.PP +The +\fBnallocx\fR\fB\fR +returns the real size that would result from a successful equivalent +\fBmallocx\fR\fB\fR +function call, or zero if insufficient memory is available to perform the size computation\&. +.PP +The +\fBmallctl\fR\fB\fR, +\fBmallctlnametomib\fR\fB\fR, and +\fBmallctlbymib\fR\fB\fR +functions return 0 on success; otherwise they return an error value\&. The functions will fail if: +.PP +EINVAL +.RS 4 +\fInewp\fR +is not +\fBNULL\fR, and +\fInewlen\fR +is too large or too small\&. Alternatively, +\fI*oldlenp\fR +is too large or too small; in this case as much data as possible are read despite the error\&. +.RE +.PP +ENOENT +.RS 4 +\fIname\fR +or +\fImib\fR +specifies an unknown/invalid value\&. +.RE +.PP +EPERM +.RS 4 +Attempt to read or write void value, or attempt to write read\-only value\&. +.RE +.PP +EAGAIN +.RS 4 +A memory allocation failure occurred\&. +.RE +.PP +EFAULT +.RS 4 +An interface with side effects failed in some way not directly related to +\fBmallctl*\fR\fB\fR +read/write processing\&. +.RE +.PP +The +\fBmalloc_usable_size\fR\fB\fR +function returns the usable size of the allocation pointed to by +\fIptr\fR\&. +.SH "ENVIRONMENT" +.PP +The following environment variable affects the execution of the allocation functions: +.PP +\fBMALLOC_CONF\fR +.RS 4 +If the environment variable +\fBMALLOC_CONF\fR +is set, the characters it contains will be interpreted as options\&. +.RE +.SH "EXAMPLES" +.PP +To dump core whenever a problem occurs: +.sp +.if n \{\ +.RS 4 +.\} +.nf +ln \-s \*(Aqabort:true\*(Aq /etc/malloc\&.conf +.fi +.if n \{\ +.RE +.\} +.PP +To specify in the source a chunk size that is 16 MiB: +.sp +.if n \{\ +.RS 4 +.\} +.nf +malloc_conf = "lg_chunk:24"; +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP +\fBmadvise\fR(2), +\fBmmap\fR(2), +\fBsbrk\fR(2), +\fButrace\fR(2), +\fBalloca\fR(3), +\fBatexit\fR(3), +\fBgetpagesize\fR(3) +.SH "STANDARDS" +.PP +The +\fBmalloc\fR\fB\fR, +\fBcalloc\fR\fB\fR, +\fBrealloc\fR\fB\fR, and +\fBfree\fR\fB\fR +functions conform to ISO/IEC 9899:1990 (\(lqISO C90\(rq)\&. +.PP +The +\fBposix_memalign\fR\fB\fR +function conforms to IEEE Std 1003\&.1\-2001 (\(lqPOSIX\&.1\(rq)\&. +.SH "HISTORY" +.PP +The +\fBmalloc_usable_size\fR\fB\fR +and +\fBposix_memalign\fR\fB\fR +functions first appeared in FreeBSD 7\&.0\&. +.PP +The +\fBaligned_alloc\fR\fB\fR, +\fBmalloc_stats_print\fR\fB\fR, and +\fBmallctl*\fR\fB\fR +functions first appeared in FreeBSD 10\&.0\&. +.PP +The +\fB*allocx\fR\fB\fR +functions first appeared in FreeBSD 11\&.0\&. +.SH "AUTHOR" +.PP +\fBJason Evans\fR +.RS 4 +.RE +.SH "NOTES" +.IP " 1." 4 +jemalloc website +.RS 4 +\%http://www.canonware.com/jemalloc/ +.RE +.IP " 2." 4 +Valgrind +.RS 4 +\%http://valgrind.org/ +.RE +.IP " 3." 4 +gperftools package +.RS 4 +\%http://code.google.com/p/gperftools/ +.RE diff --git a/contrib/jemalloc/include/jemalloc/internal/arena.h b/contrib/jemalloc/include/jemalloc/internal/arena.h new file mode 100644 index 0000000..da6b6d2 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/arena.h @@ -0,0 +1,1525 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#define LARGE_MINCLASS (ZU(1) << LG_LARGE_MINCLASS) + +/* Maximum number of regions in one run. */ +#define LG_RUN_MAXREGS (LG_PAGE - LG_TINY_MIN) +#define RUN_MAXREGS (1U << LG_RUN_MAXREGS) + +/* + * Minimum redzone size. Redzones may be larger than this if necessary to + * preserve region alignment. + */ +#define REDZONE_MINSIZE 16 + +/* + * The minimum ratio of active:dirty pages per arena is computed as: + * + * (nactive >> lg_dirty_mult) >= ndirty + * + * So, supposing that lg_dirty_mult is 3, there can be no less than 8 times as + * many active pages as dirty pages. + */ +#define LG_DIRTY_MULT_DEFAULT 3 + +typedef enum { + purge_mode_ratio = 0, + purge_mode_decay = 1, + + purge_mode_limit = 2 +} purge_mode_t; +#define PURGE_DEFAULT purge_mode_ratio +/* Default decay time in seconds. */ +#define DECAY_TIME_DEFAULT 10 +/* Number of event ticks between time checks. */ +#define DECAY_NTICKS_PER_UPDATE 1000 + +typedef struct arena_runs_dirty_link_s arena_runs_dirty_link_t; +typedef struct arena_avail_links_s arena_avail_links_t; +typedef struct arena_run_s arena_run_t; +typedef struct arena_chunk_map_bits_s arena_chunk_map_bits_t; +typedef struct arena_chunk_map_misc_s arena_chunk_map_misc_t; +typedef struct arena_chunk_s arena_chunk_t; +typedef struct arena_bin_info_s arena_bin_info_t; +typedef struct arena_bin_s arena_bin_t; +typedef struct arena_s arena_t; +typedef struct arena_tdata_s arena_tdata_t; + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#ifdef JEMALLOC_ARENA_STRUCTS_A +struct arena_run_s { + /* Index of bin this run is associated with. */ + szind_t binind; + + /* Number of free regions in run. */ + unsigned nfree; + + /* Per region allocated/deallocated bitmap. */ + bitmap_t bitmap[BITMAP_GROUPS_MAX]; +}; + +/* Each element of the chunk map corresponds to one page within the chunk. */ +struct arena_chunk_map_bits_s { + /* + * Run address (or size) and various flags are stored together. The bit + * layout looks like (assuming 32-bit system): + * + * ???????? ???????? ???nnnnn nnndumla + * + * ? : Unallocated: Run address for first/last pages, unset for internal + * pages. + * Small: Run page offset. + * Large: Run page count for first page, unset for trailing pages. + * n : binind for small size class, BININD_INVALID for large size class. + * d : dirty? + * u : unzeroed? + * m : decommitted? + * l : large? + * a : allocated? + * + * Following are example bit patterns for the three types of runs. + * + * p : run page offset + * s : run size + * n : binind for size class; large objects set these to BININD_INVALID + * x : don't care + * - : 0 + * + : 1 + * [DUMLA] : bit set + * [dumla] : bit unset + * + * Unallocated (clean): + * ssssssss ssssssss sss+++++ +++dum-a + * xxxxxxxx xxxxxxxx xxxxxxxx xxx-Uxxx + * ssssssss ssssssss sss+++++ +++dUm-a + * + * Unallocated (dirty): + * ssssssss ssssssss sss+++++ +++D-m-a + * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx + * ssssssss ssssssss sss+++++ +++D-m-a + * + * Small: + * pppppppp pppppppp pppnnnnn nnnd---A + * pppppppp pppppppp pppnnnnn nnn----A + * pppppppp pppppppp pppnnnnn nnnd---A + * + * Large: + * ssssssss ssssssss sss+++++ +++D--LA + * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx + * -------- -------- ---+++++ +++D--LA + * + * Large (sampled, size <= LARGE_MINCLASS): + * ssssssss ssssssss sssnnnnn nnnD--LA + * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx + * -------- -------- ---+++++ +++D--LA + * + * Large (not sampled, size == LARGE_MINCLASS): + * ssssssss ssssssss sss+++++ +++D--LA + * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx + * -------- -------- ---+++++ +++D--LA + */ + size_t bits; +#define CHUNK_MAP_ALLOCATED ((size_t)0x01U) +#define CHUNK_MAP_LARGE ((size_t)0x02U) +#define CHUNK_MAP_STATE_MASK ((size_t)0x3U) + +#define CHUNK_MAP_DECOMMITTED ((size_t)0x04U) +#define CHUNK_MAP_UNZEROED ((size_t)0x08U) +#define CHUNK_MAP_DIRTY ((size_t)0x10U) +#define CHUNK_MAP_FLAGS_MASK ((size_t)0x1cU) + +#define CHUNK_MAP_BININD_SHIFT 5 +#define BININD_INVALID ((size_t)0xffU) +#define CHUNK_MAP_BININD_MASK (BININD_INVALID << CHUNK_MAP_BININD_SHIFT) +#define CHUNK_MAP_BININD_INVALID CHUNK_MAP_BININD_MASK + +#define CHUNK_MAP_RUNIND_SHIFT (CHUNK_MAP_BININD_SHIFT + 8) +#define CHUNK_MAP_SIZE_SHIFT (CHUNK_MAP_RUNIND_SHIFT - LG_PAGE) +#define CHUNK_MAP_SIZE_MASK \ + (~(CHUNK_MAP_BININD_MASK | CHUNK_MAP_FLAGS_MASK | CHUNK_MAP_STATE_MASK)) +}; + +struct arena_runs_dirty_link_s { + qr(arena_runs_dirty_link_t) rd_link; +}; + +/* + * Each arena_chunk_map_misc_t corresponds to one page within the chunk, just + * like arena_chunk_map_bits_t. Two separate arrays are stored within each + * chunk header in order to improve cache locality. + */ +struct arena_chunk_map_misc_s { + /* + * Linkage for run heaps. There are two disjoint uses: + * + * 1) arena_t's runs_avail heaps. + * 2) arena_run_t conceptually uses this linkage for in-use non-full + * runs, rather than directly embedding linkage. + */ + phn(arena_chunk_map_misc_t) ph_link; + + union { + /* Linkage for list of dirty runs. */ + arena_runs_dirty_link_t rd; + + /* Profile counters, used for large object runs. */ + union { + void *prof_tctx_pun; + prof_tctx_t *prof_tctx; + }; + + /* Small region run metadata. */ + arena_run_t run; + }; +}; +typedef ph(arena_chunk_map_misc_t) arena_run_heap_t; +#endif /* JEMALLOC_ARENA_STRUCTS_A */ + +#ifdef JEMALLOC_ARENA_STRUCTS_B +/* Arena chunk header. */ +struct arena_chunk_s { + /* + * A pointer to the arena that owns the chunk is stored within the node. + * This field as a whole is used by chunks_rtree to support both + * ivsalloc() and core-based debugging. + */ + extent_node_t node; + + /* + * Map of pages within chunk that keeps track of free/large/small. The + * first map_bias entries are omitted, since the chunk header does not + * need to be tracked in the map. This omission saves a header page + * for common chunk sizes (e.g. 4 MiB). + */ + arena_chunk_map_bits_t map_bits[1]; /* Dynamically sized. */ +}; + +/* + * Read-only information associated with each element of arena_t's bins array + * is stored separately, partly to reduce memory usage (only one copy, rather + * than one per arena), but mainly to avoid false cacheline sharing. + * + * Each run has the following layout: + * + * /--------------------\ + * | pad? | + * |--------------------| + * | redzone | + * reg0_offset | region 0 | + * | redzone | + * |--------------------| \ + * | redzone | | + * | region 1 | > reg_interval + * | redzone | / + * |--------------------| + * | ... | + * | ... | + * | ... | + * |--------------------| + * | redzone | + * | region nregs-1 | + * | redzone | + * |--------------------| + * | alignment pad? | + * \--------------------/ + * + * reg_interval has at least the same minimum alignment as reg_size; this + * preserves the alignment constraint that sa2u() depends on. Alignment pad is + * either 0 or redzone_size; it is present only if needed to align reg0_offset. + */ +struct arena_bin_info_s { + /* Size of regions in a run for this bin's size class. */ + size_t reg_size; + + /* Redzone size. */ + size_t redzone_size; + + /* Interval between regions (reg_size + (redzone_size << 1)). */ + size_t reg_interval; + + /* Total size of a run for this bin's size class. */ + size_t run_size; + + /* Total number of regions in a run for this bin's size class. */ + uint32_t nregs; + + /* + * Metadata used to manipulate bitmaps for runs associated with this + * bin. + */ + bitmap_info_t bitmap_info; + + /* Offset of first region in a run for this bin's size class. */ + uint32_t reg0_offset; +}; + +struct arena_bin_s { + /* + * All operations on runcur, runs, and stats require that lock be + * locked. Run allocation/deallocation are protected by the arena lock, + * which may be acquired while holding one or more bin locks, but not + * vise versa. + */ + malloc_mutex_t lock; + + /* + * Current run being used to service allocations of this bin's size + * class. + */ + arena_run_t *runcur; + + /* + * Heap of non-full runs. This heap is used when looking for an + * existing run when runcur is no longer usable. We choose the + * non-full run that is lowest in memory; this policy tends to keep + * objects packed well, and it can also help reduce the number of + * almost-empty chunks. + */ + arena_run_heap_t runs; + + /* Bin statistics. */ + malloc_bin_stats_t stats; +}; + +struct arena_s { + /* This arena's index within the arenas array. */ + unsigned ind; + + /* + * Number of threads currently assigned to this arena, synchronized via + * atomic operations. Each thread has two distinct assignments, one for + * application-serving allocation, and the other for internal metadata + * allocation. Internal metadata must not be allocated from arenas + * created via the arenas.extend mallctl, because the arena..reset + * mallctl indiscriminately discards all allocations for the affected + * arena. + * + * 0: Application allocation. + * 1: Internal metadata allocation. + */ + unsigned nthreads[2]; + + /* + * There are three classes of arena operations from a locking + * perspective: + * 1) Thread assignment (modifies nthreads) is synchronized via atomics. + * 2) Bin-related operations are protected by bin locks. + * 3) Chunk- and run-related operations are protected by this mutex. + */ + malloc_mutex_t lock; + + arena_stats_t stats; + /* + * List of tcaches for extant threads associated with this arena. + * Stats from these are merged incrementally, and at exit if + * opt_stats_print is enabled. + */ + ql_head(tcache_t) tcache_ql; + + uint64_t prof_accumbytes; + + /* + * PRNG state for cache index randomization of large allocation base + * pointers. + */ + uint64_t offset_state; + + dss_prec_t dss_prec; + + + /* Extant arena chunks. */ + ql_head(extent_node_t) achunks; + + /* + * In order to avoid rapid chunk allocation/deallocation when an arena + * oscillates right on the cusp of needing a new chunk, cache the most + * recently freed chunk. The spare is left in the arena's chunk trees + * until it is deleted. + * + * There is one spare chunk per arena, rather than one spare total, in + * order to avoid interactions between multiple threads that could make + * a single spare inadequate. + */ + arena_chunk_t *spare; + + /* Minimum ratio (log base 2) of nactive:ndirty. */ + ssize_t lg_dirty_mult; + + /* True if a thread is currently executing arena_purge_to_limit(). */ + bool purging; + + /* Number of pages in active runs and huge regions. */ + size_t nactive; + + /* + * Current count of pages within unused runs that are potentially + * dirty, and for which madvise(... MADV_DONTNEED) has not been called. + * By tracking this, we can institute a limit on how much dirty unused + * memory is mapped for each arena. + */ + size_t ndirty; + + /* + * Unused dirty memory this arena manages. Dirty memory is conceptually + * tracked as an arbitrarily interleaved LRU of dirty runs and cached + * chunks, but the list linkage is actually semi-duplicated in order to + * avoid extra arena_chunk_map_misc_t space overhead. + * + * LRU-----------------------------------------------------------MRU + * + * /-- arena ---\ + * | | + * | | + * |------------| /- chunk -\ + * ...->|chunks_cache|<--------------------------->| /----\ |<--... + * |------------| | |node| | + * | | | | | | + * | | /- run -\ /- run -\ | | | | + * | | | | | | | | | | + * | | | | | | | | | | + * |------------| |-------| |-------| | |----| | + * ...->|runs_dirty |<-->|rd |<-->|rd |<---->|rd |<----... + * |------------| |-------| |-------| | |----| | + * | | | | | | | | | | + * | | | | | | | \----/ | + * | | \-------/ \-------/ | | + * | | | | + * | | | | + * \------------/ \---------/ + */ + arena_runs_dirty_link_t runs_dirty; + extent_node_t chunks_cache; + + /* + * Approximate time in seconds from the creation of a set of unused + * dirty pages until an equivalent set of unused dirty pages is purged + * and/or reused. + */ + ssize_t decay_time; + /* decay_time / SMOOTHSTEP_NSTEPS. */ + nstime_t decay_interval; + /* + * Time at which the current decay interval logically started. We do + * not actually advance to a new epoch until sometime after it starts + * because of scheduling and computation delays, and it is even possible + * to completely skip epochs. In all cases, during epoch advancement we + * merge all relevant activity into the most recently recorded epoch. + */ + nstime_t decay_epoch; + /* decay_deadline randomness generator. */ + uint64_t decay_jitter_state; + /* + * Deadline for current epoch. This is the sum of decay_interval and + * per epoch jitter which is a uniform random variable in + * [0..decay_interval). Epochs always advance by precise multiples of + * decay_interval, but we randomize the deadline to reduce the + * likelihood of arenas purging in lockstep. + */ + nstime_t decay_deadline; + /* + * Number of dirty pages at beginning of current epoch. During epoch + * advancement we use the delta between decay_ndirty and ndirty to + * determine how many dirty pages, if any, were generated, and record + * the result in decay_backlog. + */ + size_t decay_ndirty; + /* + * Memoized result of arena_decay_backlog_npages_limit() corresponding + * to the current contents of decay_backlog, i.e. the limit on how many + * pages are allowed to exist for the decay epochs. + */ + size_t decay_backlog_npages_limit; + /* + * Trailing log of how many unused dirty pages were generated during + * each of the past SMOOTHSTEP_NSTEPS decay epochs, where the last + * element is the most recent epoch. Corresponding epoch times are + * relative to decay_epoch. + */ + size_t decay_backlog[SMOOTHSTEP_NSTEPS]; + + /* Extant huge allocations. */ + ql_head(extent_node_t) huge; + /* Synchronizes all huge allocation/update/deallocation. */ + malloc_mutex_t huge_mtx; + + /* + * Trees of chunks that were previously allocated (trees differ only in + * node ordering). These are used when allocating chunks, in an attempt + * to re-use address space. Depending on function, different tree + * orderings are needed, which is why there are two trees with the same + * contents. + */ + extent_tree_t chunks_szad_cached; + extent_tree_t chunks_ad_cached; + extent_tree_t chunks_szad_retained; + extent_tree_t chunks_ad_retained; + + malloc_mutex_t chunks_mtx; + /* Cache of nodes that were allocated via base_alloc(). */ + ql_head(extent_node_t) node_cache; + malloc_mutex_t node_cache_mtx; + + /* User-configurable chunk hook functions. */ + chunk_hooks_t chunk_hooks; + + /* bins is used to store trees of free regions. */ + arena_bin_t bins[NBINS]; + + /* + * Quantized address-ordered heaps of this arena's available runs. The + * heaps are used for first-best-fit run allocation. + */ + arena_run_heap_t runs_avail[1]; /* Dynamically sized. */ +}; + +/* Used in conjunction with tsd for fast arena-related context lookup. */ +struct arena_tdata_s { + ticker_t decay_ticker; +}; +#endif /* JEMALLOC_ARENA_STRUCTS_B */ + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +static const size_t large_pad = +#ifdef JEMALLOC_CACHE_OBLIVIOUS + PAGE +#else + 0 +#endif + ; + +extern purge_mode_t opt_purge; +extern const char *purge_mode_names[]; +extern ssize_t opt_lg_dirty_mult; +extern ssize_t opt_decay_time; + +extern arena_bin_info_t arena_bin_info[NBINS]; + +extern size_t map_bias; /* Number of arena chunk header pages. */ +extern size_t map_misc_offset; +extern size_t arena_maxrun; /* Max run size for arenas. */ +extern size_t large_maxclass; /* Max large size class. */ +extern size_t run_quantize_max; /* Max run_quantize_*() input. */ +extern unsigned nlclasses; /* Number of large size classes. */ +extern unsigned nhclasses; /* Number of huge size classes. */ + +#ifdef JEMALLOC_JET +typedef size_t (run_quantize_t)(size_t); +extern run_quantize_t *run_quantize_floor; +extern run_quantize_t *run_quantize_ceil; +#endif +void arena_chunk_cache_maybe_insert(arena_t *arena, extent_node_t *node, + bool cache); +void arena_chunk_cache_maybe_remove(arena_t *arena, extent_node_t *node, + bool cache); +extent_node_t *arena_node_alloc(tsdn_t *tsdn, arena_t *arena); +void arena_node_dalloc(tsdn_t *tsdn, arena_t *arena, extent_node_t *node); +void *arena_chunk_alloc_huge(tsdn_t *tsdn, arena_t *arena, size_t usize, + size_t alignment, bool *zero); +void arena_chunk_dalloc_huge(tsdn_t *tsdn, arena_t *arena, void *chunk, + size_t usize); +void arena_chunk_ralloc_huge_similar(tsdn_t *tsdn, arena_t *arena, + void *chunk, size_t oldsize, size_t usize); +void arena_chunk_ralloc_huge_shrink(tsdn_t *tsdn, arena_t *arena, + void *chunk, size_t oldsize, size_t usize); +bool arena_chunk_ralloc_huge_expand(tsdn_t *tsdn, arena_t *arena, + void *chunk, size_t oldsize, size_t usize, bool *zero); +ssize_t arena_lg_dirty_mult_get(tsdn_t *tsdn, arena_t *arena); +bool arena_lg_dirty_mult_set(tsdn_t *tsdn, arena_t *arena, + ssize_t lg_dirty_mult); +ssize_t arena_decay_time_get(tsdn_t *tsdn, arena_t *arena); +bool arena_decay_time_set(tsdn_t *tsdn, arena_t *arena, ssize_t decay_time); +void arena_purge(tsdn_t *tsdn, arena_t *arena, bool all); +void arena_maybe_purge(tsdn_t *tsdn, arena_t *arena); +void arena_reset(tsd_t *tsd, arena_t *arena); +void arena_tcache_fill_small(tsdn_t *tsdn, arena_t *arena, + tcache_bin_t *tbin, szind_t binind, uint64_t prof_accumbytes); +void arena_alloc_junk_small(void *ptr, arena_bin_info_t *bin_info, + bool zero); +#ifdef JEMALLOC_JET +typedef void (arena_redzone_corruption_t)(void *, size_t, bool, size_t, + uint8_t); +extern arena_redzone_corruption_t *arena_redzone_corruption; +typedef void (arena_dalloc_junk_small_t)(void *, arena_bin_info_t *); +extern arena_dalloc_junk_small_t *arena_dalloc_junk_small; +#else +void arena_dalloc_junk_small(void *ptr, arena_bin_info_t *bin_info); +#endif +void arena_quarantine_junk_small(void *ptr, size_t usize); +void *arena_malloc_large(tsdn_t *tsdn, arena_t *arena, szind_t ind, + bool zero); +void *arena_malloc_hard(tsdn_t *tsdn, arena_t *arena, size_t size, + szind_t ind, bool zero); +void *arena_palloc(tsdn_t *tsdn, arena_t *arena, size_t usize, + size_t alignment, bool zero, tcache_t *tcache); +void arena_prof_promoted(tsdn_t *tsdn, const void *ptr, size_t size); +void arena_dalloc_bin_junked_locked(tsdn_t *tsdn, arena_t *arena, + arena_chunk_t *chunk, void *ptr, arena_chunk_map_bits_t *bitselm); +void arena_dalloc_bin(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, + void *ptr, size_t pageind, arena_chunk_map_bits_t *bitselm); +void arena_dalloc_small(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, + void *ptr, size_t pageind); +#ifdef JEMALLOC_JET +typedef void (arena_dalloc_junk_large_t)(void *, size_t); +extern arena_dalloc_junk_large_t *arena_dalloc_junk_large; +#else +void arena_dalloc_junk_large(void *ptr, size_t usize); +#endif +void arena_dalloc_large_junked_locked(tsdn_t *tsdn, arena_t *arena, + arena_chunk_t *chunk, void *ptr); +void arena_dalloc_large(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, + void *ptr); +#ifdef JEMALLOC_JET +typedef void (arena_ralloc_junk_large_t)(void *, size_t, size_t); +extern arena_ralloc_junk_large_t *arena_ralloc_junk_large; +#endif +bool arena_ralloc_no_move(tsdn_t *tsdn, void *ptr, size_t oldsize, + size_t size, size_t extra, bool zero); +void *arena_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, + size_t size, size_t alignment, bool zero, tcache_t *tcache); +dss_prec_t arena_dss_prec_get(tsdn_t *tsdn, arena_t *arena); +bool arena_dss_prec_set(tsdn_t *tsdn, arena_t *arena, dss_prec_t dss_prec); +ssize_t arena_lg_dirty_mult_default_get(void); +bool arena_lg_dirty_mult_default_set(ssize_t lg_dirty_mult); +ssize_t arena_decay_time_default_get(void); +bool arena_decay_time_default_set(ssize_t decay_time); +void arena_basic_stats_merge(tsdn_t *tsdn, arena_t *arena, + unsigned *nthreads, const char **dss, ssize_t *lg_dirty_mult, + ssize_t *decay_time, size_t *nactive, size_t *ndirty); +void arena_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads, + const char **dss, ssize_t *lg_dirty_mult, ssize_t *decay_time, + size_t *nactive, size_t *ndirty, arena_stats_t *astats, + malloc_bin_stats_t *bstats, malloc_large_stats_t *lstats, + malloc_huge_stats_t *hstats); +unsigned arena_nthreads_get(arena_t *arena, bool internal); +void arena_nthreads_inc(arena_t *arena, bool internal); +void arena_nthreads_dec(arena_t *arena, bool internal); +arena_t *arena_new(tsdn_t *tsdn, unsigned ind); +bool arena_boot(void); +void arena_prefork0(tsdn_t *tsdn, arena_t *arena); +void arena_prefork1(tsdn_t *tsdn, arena_t *arena); +void arena_prefork2(tsdn_t *tsdn, arena_t *arena); +void arena_prefork3(tsdn_t *tsdn, arena_t *arena); +void arena_postfork_parent(tsdn_t *tsdn, arena_t *arena); +void arena_postfork_child(tsdn_t *tsdn, arena_t *arena); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +arena_chunk_map_bits_t *arena_bitselm_get_mutable(arena_chunk_t *chunk, + size_t pageind); +const arena_chunk_map_bits_t *arena_bitselm_get_const( + const arena_chunk_t *chunk, size_t pageind); +arena_chunk_map_misc_t *arena_miscelm_get_mutable(arena_chunk_t *chunk, + size_t pageind); +const arena_chunk_map_misc_t *arena_miscelm_get_const( + const arena_chunk_t *chunk, size_t pageind); +size_t arena_miscelm_to_pageind(const arena_chunk_map_misc_t *miscelm); +void *arena_miscelm_to_rpages(const arena_chunk_map_misc_t *miscelm); +arena_chunk_map_misc_t *arena_rd_to_miscelm(arena_runs_dirty_link_t *rd); +arena_chunk_map_misc_t *arena_run_to_miscelm(arena_run_t *run); +size_t *arena_mapbitsp_get_mutable(arena_chunk_t *chunk, size_t pageind); +const size_t *arena_mapbitsp_get_const(const arena_chunk_t *chunk, + size_t pageind); +size_t arena_mapbitsp_read(const size_t *mapbitsp); +size_t arena_mapbits_get(const arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbits_size_decode(size_t mapbits); +size_t arena_mapbits_unallocated_size_get(const arena_chunk_t *chunk, + size_t pageind); +size_t arena_mapbits_large_size_get(const arena_chunk_t *chunk, + size_t pageind); +size_t arena_mapbits_small_runind_get(const arena_chunk_t *chunk, + size_t pageind); +szind_t arena_mapbits_binind_get(const arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbits_dirty_get(const arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbits_unzeroed_get(const arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbits_decommitted_get(const arena_chunk_t *chunk, + size_t pageind); +size_t arena_mapbits_large_get(const arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbits_allocated_get(const arena_chunk_t *chunk, size_t pageind); +void arena_mapbitsp_write(size_t *mapbitsp, size_t mapbits); +size_t arena_mapbits_size_encode(size_t size); +void arena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind, + size_t size, size_t flags); +void arena_mapbits_unallocated_size_set(arena_chunk_t *chunk, size_t pageind, + size_t size); +void arena_mapbits_internal_set(arena_chunk_t *chunk, size_t pageind, + size_t flags); +void arena_mapbits_large_set(arena_chunk_t *chunk, size_t pageind, + size_t size, size_t flags); +void arena_mapbits_large_binind_set(arena_chunk_t *chunk, size_t pageind, + szind_t binind); +void arena_mapbits_small_set(arena_chunk_t *chunk, size_t pageind, + size_t runind, szind_t binind, size_t flags); +void arena_metadata_allocated_add(arena_t *arena, size_t size); +void arena_metadata_allocated_sub(arena_t *arena, size_t size); +size_t arena_metadata_allocated_get(arena_t *arena); +bool arena_prof_accum_impl(arena_t *arena, uint64_t accumbytes); +bool arena_prof_accum_locked(arena_t *arena, uint64_t accumbytes); +bool arena_prof_accum(tsdn_t *tsdn, arena_t *arena, uint64_t accumbytes); +szind_t arena_ptr_small_binind_get(const void *ptr, size_t mapbits); +szind_t arena_bin_index(arena_t *arena, arena_bin_t *bin); +size_t arena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info, + const void *ptr); +prof_tctx_t *arena_prof_tctx_get(tsdn_t *tsdn, const void *ptr); +void arena_prof_tctx_set(tsdn_t *tsdn, const void *ptr, size_t usize, + prof_tctx_t *tctx); +void arena_prof_tctx_reset(tsdn_t *tsdn, const void *ptr, size_t usize, + const void *old_ptr, prof_tctx_t *old_tctx); +void arena_decay_ticks(tsdn_t *tsdn, arena_t *arena, unsigned nticks); +void arena_decay_tick(tsdn_t *tsdn, arena_t *arena); +void *arena_malloc(tsdn_t *tsdn, arena_t *arena, size_t size, szind_t ind, + bool zero, tcache_t *tcache, bool slow_path); +arena_t *arena_aalloc(const void *ptr); +size_t arena_salloc(tsdn_t *tsdn, const void *ptr, bool demote); +void arena_dalloc(tsdn_t *tsdn, void *ptr, tcache_t *tcache, bool slow_path); +void arena_sdalloc(tsdn_t *tsdn, void *ptr, size_t size, tcache_t *tcache, + bool slow_path); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_ARENA_C_)) +# ifdef JEMALLOC_ARENA_INLINE_A +JEMALLOC_ALWAYS_INLINE arena_chunk_map_bits_t * +arena_bitselm_get_mutable(arena_chunk_t *chunk, size_t pageind) +{ + + assert(pageind >= map_bias); + assert(pageind < chunk_npages); + + return (&chunk->map_bits[pageind-map_bias]); +} + +JEMALLOC_ALWAYS_INLINE const arena_chunk_map_bits_t * +arena_bitselm_get_const(const arena_chunk_t *chunk, size_t pageind) +{ + + return (arena_bitselm_get_mutable((arena_chunk_t *)chunk, pageind)); +} + +JEMALLOC_ALWAYS_INLINE arena_chunk_map_misc_t * +arena_miscelm_get_mutable(arena_chunk_t *chunk, size_t pageind) +{ + + assert(pageind >= map_bias); + assert(pageind < chunk_npages); + + return ((arena_chunk_map_misc_t *)((uintptr_t)chunk + + (uintptr_t)map_misc_offset) + pageind-map_bias); +} + +JEMALLOC_ALWAYS_INLINE const arena_chunk_map_misc_t * +arena_miscelm_get_const(const arena_chunk_t *chunk, size_t pageind) +{ +#if 1 /* Work around gcc bug. */ + arena_chunk_t *mchunk = (arena_chunk_t *)chunk; + + return (arena_miscelm_get_mutable(mchunk, pageind)); +#else + return (arena_miscelm_get_mutable((arena_chunk_t *)chunk, pageind)); +#endif +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_miscelm_to_pageind(const arena_chunk_map_misc_t *miscelm) +{ + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(miscelm); + size_t pageind = ((uintptr_t)miscelm - ((uintptr_t)chunk + + map_misc_offset)) / sizeof(arena_chunk_map_misc_t) + map_bias; + + assert(pageind >= map_bias); + assert(pageind < chunk_npages); + + return (pageind); +} + +JEMALLOC_ALWAYS_INLINE void * +arena_miscelm_to_rpages(const arena_chunk_map_misc_t *miscelm) +{ + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(miscelm); + size_t pageind = arena_miscelm_to_pageind(miscelm); + + return ((void *)((uintptr_t)chunk + (pageind << LG_PAGE))); +} + +JEMALLOC_ALWAYS_INLINE arena_chunk_map_misc_t * +arena_rd_to_miscelm(arena_runs_dirty_link_t *rd) +{ + arena_chunk_map_misc_t *miscelm = (arena_chunk_map_misc_t + *)((uintptr_t)rd - offsetof(arena_chunk_map_misc_t, rd)); + + assert(arena_miscelm_to_pageind(miscelm) >= map_bias); + assert(arena_miscelm_to_pageind(miscelm) < chunk_npages); + + return (miscelm); +} + +JEMALLOC_ALWAYS_INLINE arena_chunk_map_misc_t * +arena_run_to_miscelm(arena_run_t *run) +{ + arena_chunk_map_misc_t *miscelm = (arena_chunk_map_misc_t + *)((uintptr_t)run - offsetof(arena_chunk_map_misc_t, run)); + + assert(arena_miscelm_to_pageind(miscelm) >= map_bias); + assert(arena_miscelm_to_pageind(miscelm) < chunk_npages); + + return (miscelm); +} + +JEMALLOC_ALWAYS_INLINE size_t * +arena_mapbitsp_get_mutable(arena_chunk_t *chunk, size_t pageind) +{ + + return (&arena_bitselm_get_mutable(chunk, pageind)->bits); +} + +JEMALLOC_ALWAYS_INLINE const size_t * +arena_mapbitsp_get_const(const arena_chunk_t *chunk, size_t pageind) +{ +#if 1 /* Work around gcc bug. */ + arena_chunk_t *mchunk = (arena_chunk_t *)chunk; + + return (arena_mapbitsp_get_mutable(mchunk, pageind)); +#else + return (arena_mapbitsp_get_mutable((arena_chunk_t *)chunk, pageind)); +#endif +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbitsp_read(const size_t *mapbitsp) +{ + + return (*mapbitsp); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_get(const arena_chunk_t *chunk, size_t pageind) +{ + + return (arena_mapbitsp_read(arena_mapbitsp_get_const(chunk, pageind))); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_size_decode(size_t mapbits) +{ + size_t size; + +#if CHUNK_MAP_SIZE_SHIFT > 0 + size = (mapbits & CHUNK_MAP_SIZE_MASK) >> CHUNK_MAP_SIZE_SHIFT; +#elif CHUNK_MAP_SIZE_SHIFT == 0 + size = mapbits & CHUNK_MAP_SIZE_MASK; +#else + size = (mapbits & CHUNK_MAP_SIZE_MASK) << -CHUNK_MAP_SIZE_SHIFT; +#endif + + return (size); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_unallocated_size_get(const arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == 0); + return (arena_mapbits_size_decode(mapbits)); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_large_size_get(const arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == + (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)); + return (arena_mapbits_size_decode(mapbits)); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_small_runind_get(const arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == + CHUNK_MAP_ALLOCATED); + return (mapbits >> CHUNK_MAP_RUNIND_SHIFT); +} + +JEMALLOC_ALWAYS_INLINE szind_t +arena_mapbits_binind_get(const arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + szind_t binind; + + mapbits = arena_mapbits_get(chunk, pageind); + binind = (mapbits & CHUNK_MAP_BININD_MASK) >> CHUNK_MAP_BININD_SHIFT; + assert(binind < NBINS || binind == BININD_INVALID); + return (binind); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_dirty_get(const arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & CHUNK_MAP_DECOMMITTED) == 0 || (mapbits & + (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0); + return (mapbits & CHUNK_MAP_DIRTY); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_unzeroed_get(const arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & CHUNK_MAP_DECOMMITTED) == 0 || (mapbits & + (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0); + return (mapbits & CHUNK_MAP_UNZEROED); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_decommitted_get(const arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & CHUNK_MAP_DECOMMITTED) == 0 || (mapbits & + (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0); + return (mapbits & CHUNK_MAP_DECOMMITTED); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_large_get(const arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + return (mapbits & CHUNK_MAP_LARGE); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_allocated_get(const arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + return (mapbits & CHUNK_MAP_ALLOCATED); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbitsp_write(size_t *mapbitsp, size_t mapbits) +{ + + *mapbitsp = mapbits; +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_size_encode(size_t size) +{ + size_t mapbits; + +#if CHUNK_MAP_SIZE_SHIFT > 0 + mapbits = size << CHUNK_MAP_SIZE_SHIFT; +#elif CHUNK_MAP_SIZE_SHIFT == 0 + mapbits = size; +#else + mapbits = size >> -CHUNK_MAP_SIZE_SHIFT; +#endif + + assert((mapbits & ~CHUNK_MAP_SIZE_MASK) == 0); + return (mapbits); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind, size_t size, + size_t flags) +{ + size_t *mapbitsp = arena_mapbitsp_get_mutable(chunk, pageind); + + assert((size & PAGE_MASK) == 0); + assert((flags & CHUNK_MAP_FLAGS_MASK) == flags); + assert((flags & CHUNK_MAP_DECOMMITTED) == 0 || (flags & + (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0); + arena_mapbitsp_write(mapbitsp, arena_mapbits_size_encode(size) | + CHUNK_MAP_BININD_INVALID | flags); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbits_unallocated_size_set(arena_chunk_t *chunk, size_t pageind, + size_t size) +{ + size_t *mapbitsp = arena_mapbitsp_get_mutable(chunk, pageind); + size_t mapbits = arena_mapbitsp_read(mapbitsp); + + assert((size & PAGE_MASK) == 0); + assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == 0); + arena_mapbitsp_write(mapbitsp, arena_mapbits_size_encode(size) | + (mapbits & ~CHUNK_MAP_SIZE_MASK)); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbits_internal_set(arena_chunk_t *chunk, size_t pageind, size_t flags) +{ + size_t *mapbitsp = arena_mapbitsp_get_mutable(chunk, pageind); + + assert((flags & CHUNK_MAP_UNZEROED) == flags); + arena_mapbitsp_write(mapbitsp, flags); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbits_large_set(arena_chunk_t *chunk, size_t pageind, size_t size, + size_t flags) +{ + size_t *mapbitsp = arena_mapbitsp_get_mutable(chunk, pageind); + + assert((size & PAGE_MASK) == 0); + assert((flags & CHUNK_MAP_FLAGS_MASK) == flags); + assert((flags & CHUNK_MAP_DECOMMITTED) == 0 || (flags & + (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0); + arena_mapbitsp_write(mapbitsp, arena_mapbits_size_encode(size) | + CHUNK_MAP_BININD_INVALID | flags | CHUNK_MAP_LARGE | + CHUNK_MAP_ALLOCATED); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbits_large_binind_set(arena_chunk_t *chunk, size_t pageind, + szind_t binind) +{ + size_t *mapbitsp = arena_mapbitsp_get_mutable(chunk, pageind); + size_t mapbits = arena_mapbitsp_read(mapbitsp); + + assert(binind <= BININD_INVALID); + assert(arena_mapbits_large_size_get(chunk, pageind) == LARGE_MINCLASS + + large_pad); + arena_mapbitsp_write(mapbitsp, (mapbits & ~CHUNK_MAP_BININD_MASK) | + (binind << CHUNK_MAP_BININD_SHIFT)); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbits_small_set(arena_chunk_t *chunk, size_t pageind, size_t runind, + szind_t binind, size_t flags) +{ + size_t *mapbitsp = arena_mapbitsp_get_mutable(chunk, pageind); + + assert(binind < BININD_INVALID); + assert(pageind - runind >= map_bias); + assert((flags & CHUNK_MAP_UNZEROED) == flags); + arena_mapbitsp_write(mapbitsp, (runind << CHUNK_MAP_RUNIND_SHIFT) | + (binind << CHUNK_MAP_BININD_SHIFT) | flags | CHUNK_MAP_ALLOCATED); +} + +JEMALLOC_INLINE void +arena_metadata_allocated_add(arena_t *arena, size_t size) +{ + + atomic_add_z(&arena->stats.metadata_allocated, size); +} + +JEMALLOC_INLINE void +arena_metadata_allocated_sub(arena_t *arena, size_t size) +{ + + atomic_sub_z(&arena->stats.metadata_allocated, size); +} + +JEMALLOC_INLINE size_t +arena_metadata_allocated_get(arena_t *arena) +{ + + return (atomic_read_z(&arena->stats.metadata_allocated)); +} + +JEMALLOC_INLINE bool +arena_prof_accum_impl(arena_t *arena, uint64_t accumbytes) +{ + + cassert(config_prof); + assert(prof_interval != 0); + + arena->prof_accumbytes += accumbytes; + if (arena->prof_accumbytes >= prof_interval) { + arena->prof_accumbytes -= prof_interval; + return (true); + } + return (false); +} + +JEMALLOC_INLINE bool +arena_prof_accum_locked(arena_t *arena, uint64_t accumbytes) +{ + + cassert(config_prof); + + if (likely(prof_interval == 0)) + return (false); + return (arena_prof_accum_impl(arena, accumbytes)); +} + +JEMALLOC_INLINE bool +arena_prof_accum(tsdn_t *tsdn, arena_t *arena, uint64_t accumbytes) +{ + + cassert(config_prof); + + if (likely(prof_interval == 0)) + return (false); + + { + bool ret; + + malloc_mutex_lock(tsdn, &arena->lock); + ret = arena_prof_accum_impl(arena, accumbytes); + malloc_mutex_unlock(tsdn, &arena->lock); + return (ret); + } +} + +JEMALLOC_ALWAYS_INLINE szind_t +arena_ptr_small_binind_get(const void *ptr, size_t mapbits) +{ + szind_t binind; + + binind = (mapbits & CHUNK_MAP_BININD_MASK) >> CHUNK_MAP_BININD_SHIFT; + + if (config_debug) { + arena_chunk_t *chunk; + arena_t *arena; + size_t pageind; + size_t actual_mapbits; + size_t rpages_ind; + const arena_run_t *run; + arena_bin_t *bin; + szind_t run_binind, actual_binind; + arena_bin_info_t *bin_info; + const arena_chunk_map_misc_t *miscelm; + const void *rpages; + + assert(binind != BININD_INVALID); + assert(binind < NBINS); + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + arena = extent_node_arena_get(&chunk->node); + pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + actual_mapbits = arena_mapbits_get(chunk, pageind); + assert(mapbits == actual_mapbits); + assert(arena_mapbits_large_get(chunk, pageind) == 0); + assert(arena_mapbits_allocated_get(chunk, pageind) != 0); + rpages_ind = pageind - arena_mapbits_small_runind_get(chunk, + pageind); + miscelm = arena_miscelm_get_const(chunk, rpages_ind); + run = &miscelm->run; + run_binind = run->binind; + bin = &arena->bins[run_binind]; + actual_binind = (szind_t)(bin - arena->bins); + assert(run_binind == actual_binind); + bin_info = &arena_bin_info[actual_binind]; + rpages = arena_miscelm_to_rpages(miscelm); + assert(((uintptr_t)ptr - ((uintptr_t)rpages + + (uintptr_t)bin_info->reg0_offset)) % bin_info->reg_interval + == 0); + } + + return (binind); +} +# endif /* JEMALLOC_ARENA_INLINE_A */ + +# ifdef JEMALLOC_ARENA_INLINE_B +JEMALLOC_INLINE szind_t +arena_bin_index(arena_t *arena, arena_bin_t *bin) +{ + szind_t binind = (szind_t)(bin - arena->bins); + assert(binind < NBINS); + return (binind); +} + +JEMALLOC_INLINE size_t +arena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info, const void *ptr) +{ + size_t diff, interval, shift, regind; + arena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run); + void *rpages = arena_miscelm_to_rpages(miscelm); + + /* + * Freeing a pointer lower than region zero can cause assertion + * failure. + */ + assert((uintptr_t)ptr >= (uintptr_t)rpages + + (uintptr_t)bin_info->reg0_offset); + + /* + * Avoid doing division with a variable divisor if possible. Using + * actual division here can reduce allocator throughput by over 20%! + */ + diff = (size_t)((uintptr_t)ptr - (uintptr_t)rpages - + bin_info->reg0_offset); + + /* Rescale (factor powers of 2 out of the numerator and denominator). */ + interval = bin_info->reg_interval; + shift = ffs_zu(interval) - 1; + diff >>= shift; + interval >>= shift; + + if (interval == 1) { + /* The divisor was a power of 2. */ + regind = diff; + } else { + /* + * To divide by a number D that is not a power of two we + * multiply by (2^21 / D) and then right shift by 21 positions. + * + * X / D + * + * becomes + * + * (X * interval_invs[D - 3]) >> SIZE_INV_SHIFT + * + * We can omit the first three elements, because we never + * divide by 0, and 1 and 2 are both powers of two, which are + * handled above. + */ +#define SIZE_INV_SHIFT ((sizeof(size_t) << 3) - LG_RUN_MAXREGS) +#define SIZE_INV(s) (((ZU(1) << SIZE_INV_SHIFT) / (s)) + 1) + static const size_t interval_invs[] = { + SIZE_INV(3), + SIZE_INV(4), SIZE_INV(5), SIZE_INV(6), SIZE_INV(7), + SIZE_INV(8), SIZE_INV(9), SIZE_INV(10), SIZE_INV(11), + SIZE_INV(12), SIZE_INV(13), SIZE_INV(14), SIZE_INV(15), + SIZE_INV(16), SIZE_INV(17), SIZE_INV(18), SIZE_INV(19), + SIZE_INV(20), SIZE_INV(21), SIZE_INV(22), SIZE_INV(23), + SIZE_INV(24), SIZE_INV(25), SIZE_INV(26), SIZE_INV(27), + SIZE_INV(28), SIZE_INV(29), SIZE_INV(30), SIZE_INV(31) + }; + + if (likely(interval <= ((sizeof(interval_invs) / sizeof(size_t)) + + 2))) { + regind = (diff * interval_invs[interval - 3]) >> + SIZE_INV_SHIFT; + } else + regind = diff / interval; +#undef SIZE_INV +#undef SIZE_INV_SHIFT + } + assert(diff == regind * interval); + assert(regind < bin_info->nregs); + + return (regind); +} + +JEMALLOC_INLINE prof_tctx_t * +arena_prof_tctx_get(tsdn_t *tsdn, const void *ptr) +{ + prof_tctx_t *ret; + arena_chunk_t *chunk; + + cassert(config_prof); + assert(ptr != NULL); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + size_t mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & CHUNK_MAP_ALLOCATED) != 0); + if (likely((mapbits & CHUNK_MAP_LARGE) == 0)) + ret = (prof_tctx_t *)(uintptr_t)1U; + else { + arena_chunk_map_misc_t *elm = + arena_miscelm_get_mutable(chunk, pageind); + ret = atomic_read_p(&elm->prof_tctx_pun); + } + } else + ret = huge_prof_tctx_get(tsdn, ptr); + + return (ret); +} + +JEMALLOC_INLINE void +arena_prof_tctx_set(tsdn_t *tsdn, const void *ptr, size_t usize, + prof_tctx_t *tctx) +{ + arena_chunk_t *chunk; + + cassert(config_prof); + assert(ptr != NULL); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + + assert(arena_mapbits_allocated_get(chunk, pageind) != 0); + + if (unlikely(usize > SMALL_MAXCLASS || (uintptr_t)tctx > + (uintptr_t)1U)) { + arena_chunk_map_misc_t *elm; + + assert(arena_mapbits_large_get(chunk, pageind) != 0); + + elm = arena_miscelm_get_mutable(chunk, pageind); + atomic_write_p(&elm->prof_tctx_pun, tctx); + } else { + /* + * tctx must always be initialized for large runs. + * Assert that the surrounding conditional logic is + * equivalent to checking whether ptr refers to a large + * run. + */ + assert(arena_mapbits_large_get(chunk, pageind) == 0); + } + } else + huge_prof_tctx_set(tsdn, ptr, tctx); +} + +JEMALLOC_INLINE void +arena_prof_tctx_reset(tsdn_t *tsdn, const void *ptr, size_t usize, + const void *old_ptr, prof_tctx_t *old_tctx) +{ + + cassert(config_prof); + assert(ptr != NULL); + + if (unlikely(usize > SMALL_MAXCLASS || (ptr == old_ptr && + (uintptr_t)old_tctx > (uintptr_t)1U))) { + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { + size_t pageind; + arena_chunk_map_misc_t *elm; + + pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> + LG_PAGE; + assert(arena_mapbits_allocated_get(chunk, pageind) != + 0); + assert(arena_mapbits_large_get(chunk, pageind) != 0); + + elm = arena_miscelm_get_mutable(chunk, pageind); + atomic_write_p(&elm->prof_tctx_pun, + (prof_tctx_t *)(uintptr_t)1U); + } else + huge_prof_tctx_reset(tsdn, ptr); + } +} + +JEMALLOC_ALWAYS_INLINE void +arena_decay_ticks(tsdn_t *tsdn, arena_t *arena, unsigned nticks) +{ + tsd_t *tsd; + ticker_t *decay_ticker; + + if (unlikely(tsdn_null(tsdn))) + return; + tsd = tsdn_tsd(tsdn); + decay_ticker = decay_ticker_get(tsd, arena->ind); + if (unlikely(decay_ticker == NULL)) + return; + if (unlikely(ticker_ticks(decay_ticker, nticks))) + arena_purge(tsdn, arena, false); +} + +JEMALLOC_ALWAYS_INLINE void +arena_decay_tick(tsdn_t *tsdn, arena_t *arena) +{ + + arena_decay_ticks(tsdn, arena, 1); +} + +JEMALLOC_ALWAYS_INLINE void * +arena_malloc(tsdn_t *tsdn, arena_t *arena, size_t size, szind_t ind, bool zero, + tcache_t *tcache, bool slow_path) +{ + + assert(!tsdn_null(tsdn) || tcache == NULL); + assert(size != 0); + + if (likely(tcache != NULL)) { + if (likely(size <= SMALL_MAXCLASS)) { + return (tcache_alloc_small(tsdn_tsd(tsdn), arena, + tcache, size, ind, zero, slow_path)); + } + if (likely(size <= tcache_maxclass)) { + return (tcache_alloc_large(tsdn_tsd(tsdn), arena, + tcache, size, ind, zero, slow_path)); + } + /* (size > tcache_maxclass) case falls through. */ + assert(size > tcache_maxclass); + } + + return (arena_malloc_hard(tsdn, arena, size, ind, zero)); +} + +JEMALLOC_ALWAYS_INLINE arena_t * +arena_aalloc(const void *ptr) +{ + arena_chunk_t *chunk; + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) + return (extent_node_arena_get(&chunk->node)); + else + return (huge_aalloc(ptr)); +} + +/* Return the size of the allocation pointed to by ptr. */ +JEMALLOC_ALWAYS_INLINE size_t +arena_salloc(tsdn_t *tsdn, const void *ptr, bool demote) +{ + size_t ret; + arena_chunk_t *chunk; + size_t pageind; + szind_t binind; + + assert(ptr != NULL); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { + pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + assert(arena_mapbits_allocated_get(chunk, pageind) != 0); + binind = arena_mapbits_binind_get(chunk, pageind); + if (unlikely(binind == BININD_INVALID || (config_prof && !demote + && arena_mapbits_large_get(chunk, pageind) != 0))) { + /* + * Large allocation. In the common case (demote), and + * as this is an inline function, most callers will only + * end up looking at binind to determine that ptr is a + * small allocation. + */ + assert(config_cache_oblivious || ((uintptr_t)ptr & + PAGE_MASK) == 0); + ret = arena_mapbits_large_size_get(chunk, pageind) - + large_pad; + assert(ret != 0); + assert(pageind + ((ret+large_pad)>>LG_PAGE) <= + chunk_npages); + assert(arena_mapbits_dirty_get(chunk, pageind) == + arena_mapbits_dirty_get(chunk, + pageind+((ret+large_pad)>>LG_PAGE)-1)); + } else { + /* + * Small allocation (possibly promoted to a large + * object). + */ + assert(arena_mapbits_large_get(chunk, pageind) != 0 || + arena_ptr_small_binind_get(ptr, + arena_mapbits_get(chunk, pageind)) == binind); + ret = index2size(binind); + } + } else + ret = huge_salloc(tsdn, ptr); + + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void +arena_dalloc(tsdn_t *tsdn, void *ptr, tcache_t *tcache, bool slow_path) +{ + arena_chunk_t *chunk; + size_t pageind, mapbits; + + assert(!tsdn_null(tsdn) || tcache == NULL); + assert(ptr != NULL); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { + pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + mapbits = arena_mapbits_get(chunk, pageind); + assert(arena_mapbits_allocated_get(chunk, pageind) != 0); + if (likely((mapbits & CHUNK_MAP_LARGE) == 0)) { + /* Small allocation. */ + if (likely(tcache != NULL)) { + szind_t binind = arena_ptr_small_binind_get(ptr, + mapbits); + tcache_dalloc_small(tsdn_tsd(tsdn), tcache, ptr, + binind, slow_path); + } else { + arena_dalloc_small(tsdn, + extent_node_arena_get(&chunk->node), chunk, + ptr, pageind); + } + } else { + size_t size = arena_mapbits_large_size_get(chunk, + pageind); + + assert(config_cache_oblivious || ((uintptr_t)ptr & + PAGE_MASK) == 0); + + if (likely(tcache != NULL) && size - large_pad <= + tcache_maxclass) { + tcache_dalloc_large(tsdn_tsd(tsdn), tcache, ptr, + size - large_pad, slow_path); + } else { + arena_dalloc_large(tsdn, + extent_node_arena_get(&chunk->node), chunk, + ptr); + } + } + } else + huge_dalloc(tsdn, ptr); +} + +JEMALLOC_ALWAYS_INLINE void +arena_sdalloc(tsdn_t *tsdn, void *ptr, size_t size, tcache_t *tcache, + bool slow_path) +{ + arena_chunk_t *chunk; + + assert(!tsdn_null(tsdn) || tcache == NULL); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { + if (config_prof && opt_prof) { + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> + LG_PAGE; + assert(arena_mapbits_allocated_get(chunk, pageind) != + 0); + if (arena_mapbits_large_get(chunk, pageind) != 0) { + /* + * Make sure to use promoted size, not request + * size. + */ + size = arena_mapbits_large_size_get(chunk, + pageind) - large_pad; + } + } + assert(s2u(size) == s2u(arena_salloc(tsdn, ptr, false))); + + if (likely(size <= SMALL_MAXCLASS)) { + /* Small allocation. */ + if (likely(tcache != NULL)) { + szind_t binind = size2index(size); + tcache_dalloc_small(tsdn_tsd(tsdn), tcache, ptr, + binind, slow_path); + } else { + size_t pageind = ((uintptr_t)ptr - + (uintptr_t)chunk) >> LG_PAGE; + arena_dalloc_small(tsdn, + extent_node_arena_get(&chunk->node), chunk, + ptr, pageind); + } + } else { + assert(config_cache_oblivious || ((uintptr_t)ptr & + PAGE_MASK) == 0); + + if (likely(tcache != NULL) && size <= tcache_maxclass) { + tcache_dalloc_large(tsdn_tsd(tsdn), tcache, ptr, + size, slow_path); + } else { + arena_dalloc_large(tsdn, + extent_node_arena_get(&chunk->node), chunk, + ptr); + } + } + } else + huge_dalloc(tsdn, ptr); +} +# endif /* JEMALLOC_ARENA_INLINE_B */ +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/assert.h b/contrib/jemalloc/include/jemalloc/internal/assert.h new file mode 100644 index 0000000..6f8f7eb --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/assert.h @@ -0,0 +1,45 @@ +/* + * Define a custom assert() in order to reduce the chances of deadlock during + * assertion failure. + */ +#ifndef assert +#define assert(e) do { \ + if (unlikely(config_debug && !(e))) { \ + malloc_printf( \ + ": %s:%d: Failed assertion: \"%s\"\n", \ + __FILE__, __LINE__, #e); \ + abort(); \ + } \ +} while (0) +#endif + +#ifndef not_reached +#define not_reached() do { \ + if (config_debug) { \ + malloc_printf( \ + ": %s:%d: Unreachable code reached\n", \ + __FILE__, __LINE__); \ + abort(); \ + } \ + unreachable(); \ +} while (0) +#endif + +#ifndef not_implemented +#define not_implemented() do { \ + if (config_debug) { \ + malloc_printf(": %s:%d: Not implemented\n", \ + __FILE__, __LINE__); \ + abort(); \ + } \ +} while (0) +#endif + +#ifndef assert_not_implemented +#define assert_not_implemented(e) do { \ + if (unlikely(config_debug && !(e))) \ + not_implemented(); \ +} while (0) +#endif + + diff --git a/contrib/jemalloc/include/jemalloc/internal/atomic.h b/contrib/jemalloc/include/jemalloc/internal/atomic.h new file mode 100644 index 0000000..3f15ea1 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/atomic.h @@ -0,0 +1,651 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#define atomic_read_uint64(p) atomic_add_uint64(p, 0) +#define atomic_read_uint32(p) atomic_add_uint32(p, 0) +#define atomic_read_p(p) atomic_add_p(p, NULL) +#define atomic_read_z(p) atomic_add_z(p, 0) +#define atomic_read_u(p) atomic_add_u(p, 0) + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +/* + * All arithmetic functions return the arithmetic result of the atomic + * operation. Some atomic operation APIs return the value prior to mutation, in + * which case the following functions must redundantly compute the result so + * that it can be returned. These functions are normally inlined, so the extra + * operations can be optimized away if the return values aren't used by the + * callers. + * + * atomic_read_( *p) { return (*p); } + * atomic_add_( *p, x) { return (*p += x); } + * atomic_sub_( *p, x) { return (*p -= x); } + * bool atomic_cas_( *p, c, s) + * { + * if (*p != c) + * return (true); + * *p = s; + * return (false); + * } + * void atomic_write_( *p, x) { *p = x; } + */ + +#ifndef JEMALLOC_ENABLE_INLINE +uint64_t atomic_add_uint64(uint64_t *p, uint64_t x); +uint64_t atomic_sub_uint64(uint64_t *p, uint64_t x); +bool atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s); +void atomic_write_uint64(uint64_t *p, uint64_t x); +uint32_t atomic_add_uint32(uint32_t *p, uint32_t x); +uint32_t atomic_sub_uint32(uint32_t *p, uint32_t x); +bool atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s); +void atomic_write_uint32(uint32_t *p, uint32_t x); +void *atomic_add_p(void **p, void *x); +void *atomic_sub_p(void **p, void *x); +bool atomic_cas_p(void **p, void *c, void *s); +void atomic_write_p(void **p, const void *x); +size_t atomic_add_z(size_t *p, size_t x); +size_t atomic_sub_z(size_t *p, size_t x); +bool atomic_cas_z(size_t *p, size_t c, size_t s); +void atomic_write_z(size_t *p, size_t x); +unsigned atomic_add_u(unsigned *p, unsigned x); +unsigned atomic_sub_u(unsigned *p, unsigned x); +bool atomic_cas_u(unsigned *p, unsigned c, unsigned s); +void atomic_write_u(unsigned *p, unsigned x); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_ATOMIC_C_)) +/******************************************************************************/ +/* 64-bit operations. */ +#if (LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3) +# if (defined(__amd64__) || defined(__x86_64__)) +JEMALLOC_INLINE uint64_t +atomic_add_uint64(uint64_t *p, uint64_t x) +{ + uint64_t t = x; + + asm volatile ( + "lock; xaddq %0, %1;" + : "+r" (t), "=m" (*p) /* Outputs. */ + : "m" (*p) /* Inputs. */ + ); + + return (t + x); +} + +JEMALLOC_INLINE uint64_t +atomic_sub_uint64(uint64_t *p, uint64_t x) +{ + uint64_t t; + + x = (uint64_t)(-(int64_t)x); + t = x; + asm volatile ( + "lock; xaddq %0, %1;" + : "+r" (t), "=m" (*p) /* Outputs. */ + : "m" (*p) /* Inputs. */ + ); + + return (t + x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s) +{ + uint8_t success; + + asm volatile ( + "lock; cmpxchgq %4, %0;" + "sete %1;" + : "=m" (*p), "=a" (success) /* Outputs. */ + : "m" (*p), "a" (c), "r" (s) /* Inputs. */ + : "memory" /* Clobbers. */ + ); + + return (!(bool)success); +} + +JEMALLOC_INLINE void +atomic_write_uint64(uint64_t *p, uint64_t x) +{ + + asm volatile ( + "xchgq %1, %0;" /* Lock is implied by xchgq. */ + : "=m" (*p), "+r" (x) /* Outputs. */ + : "m" (*p) /* Inputs. */ + : "memory" /* Clobbers. */ + ); +} +# elif (defined(JEMALLOC_C11ATOMICS)) +JEMALLOC_INLINE uint64_t +atomic_add_uint64(uint64_t *p, uint64_t x) +{ + volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p; + return (atomic_fetch_add(a, x) + x); +} + +JEMALLOC_INLINE uint64_t +atomic_sub_uint64(uint64_t *p, uint64_t x) +{ + volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p; + return (atomic_fetch_sub(a, x) - x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s) +{ + volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p; + return (!atomic_compare_exchange_strong(a, &c, s)); +} + +JEMALLOC_INLINE void +atomic_write_uint64(uint64_t *p, uint64_t x) +{ + volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p; + atomic_store(a, x); +} +# elif (defined(JEMALLOC_ATOMIC9)) +JEMALLOC_INLINE uint64_t +atomic_add_uint64(uint64_t *p, uint64_t x) +{ + + /* + * atomic_fetchadd_64() doesn't exist, but we only ever use this + * function on LP64 systems, so atomic_fetchadd_long() will do. + */ + assert(sizeof(uint64_t) == sizeof(unsigned long)); + + return (atomic_fetchadd_long(p, (unsigned long)x) + x); +} + +JEMALLOC_INLINE uint64_t +atomic_sub_uint64(uint64_t *p, uint64_t x) +{ + + assert(sizeof(uint64_t) == sizeof(unsigned long)); + + return (atomic_fetchadd_long(p, (unsigned long)(-(long)x)) - x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s) +{ + + assert(sizeof(uint64_t) == sizeof(unsigned long)); + + return (!atomic_cmpset_long(p, (unsigned long)c, (unsigned long)s)); +} + +JEMALLOC_INLINE void +atomic_write_uint64(uint64_t *p, uint64_t x) +{ + + assert(sizeof(uint64_t) == sizeof(unsigned long)); + + atomic_store_rel_long(p, x); +} +# elif (defined(JEMALLOC_OSATOMIC)) +JEMALLOC_INLINE uint64_t +atomic_add_uint64(uint64_t *p, uint64_t x) +{ + + return (OSAtomicAdd64((int64_t)x, (int64_t *)p)); +} + +JEMALLOC_INLINE uint64_t +atomic_sub_uint64(uint64_t *p, uint64_t x) +{ + + return (OSAtomicAdd64(-((int64_t)x), (int64_t *)p)); +} + +JEMALLOC_INLINE bool +atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s) +{ + + return (!OSAtomicCompareAndSwap64(c, s, (int64_t *)p)); +} + +JEMALLOC_INLINE void +atomic_write_uint64(uint64_t *p, uint64_t x) +{ + uint64_t o; + + /*The documented OSAtomic*() API does not expose an atomic exchange. */ + do { + o = atomic_read_uint64(p); + } while (atomic_cas_uint64(p, o, x)); +} +# elif (defined(_MSC_VER)) +JEMALLOC_INLINE uint64_t +atomic_add_uint64(uint64_t *p, uint64_t x) +{ + + return (InterlockedExchangeAdd64(p, x) + x); +} + +JEMALLOC_INLINE uint64_t +atomic_sub_uint64(uint64_t *p, uint64_t x) +{ + + return (InterlockedExchangeAdd64(p, -((int64_t)x)) - x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s) +{ + uint64_t o; + + o = InterlockedCompareExchange64(p, s, c); + return (o != c); +} + +JEMALLOC_INLINE void +atomic_write_uint64(uint64_t *p, uint64_t x) +{ + + InterlockedExchange64(p, x); +} +# elif (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) || \ + defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_8)) +JEMALLOC_INLINE uint64_t +atomic_add_uint64(uint64_t *p, uint64_t x) +{ + + return (__sync_add_and_fetch(p, x)); +} + +JEMALLOC_INLINE uint64_t +atomic_sub_uint64(uint64_t *p, uint64_t x) +{ + + return (__sync_sub_and_fetch(p, x)); +} + +JEMALLOC_INLINE bool +atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s) +{ + + return (!__sync_bool_compare_and_swap(p, c, s)); +} + +JEMALLOC_INLINE void +atomic_write_uint64(uint64_t *p, uint64_t x) +{ + + __sync_lock_test_and_set(p, x); +} +# else +# error "Missing implementation for 64-bit atomic operations" +# endif +#endif + +/******************************************************************************/ +/* 32-bit operations. */ +#if (defined(__i386__) || defined(__amd64__) || defined(__x86_64__)) +JEMALLOC_INLINE uint32_t +atomic_add_uint32(uint32_t *p, uint32_t x) +{ + uint32_t t = x; + + asm volatile ( + "lock; xaddl %0, %1;" + : "+r" (t), "=m" (*p) /* Outputs. */ + : "m" (*p) /* Inputs. */ + ); + + return (t + x); +} + +JEMALLOC_INLINE uint32_t +atomic_sub_uint32(uint32_t *p, uint32_t x) +{ + uint32_t t; + + x = (uint32_t)(-(int32_t)x); + t = x; + asm volatile ( + "lock; xaddl %0, %1;" + : "+r" (t), "=m" (*p) /* Outputs. */ + : "m" (*p) /* Inputs. */ + ); + + return (t + x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s) +{ + uint8_t success; + + asm volatile ( + "lock; cmpxchgl %4, %0;" + "sete %1;" + : "=m" (*p), "=a" (success) /* Outputs. */ + : "m" (*p), "a" (c), "r" (s) /* Inputs. */ + : "memory" + ); + + return (!(bool)success); +} + +JEMALLOC_INLINE void +atomic_write_uint32(uint32_t *p, uint32_t x) +{ + + asm volatile ( + "xchgl %1, %0;" /* Lock is implied by xchgl. */ + : "=m" (*p), "+r" (x) /* Outputs. */ + : "m" (*p) /* Inputs. */ + : "memory" /* Clobbers. */ + ); +} +# elif (defined(JEMALLOC_C11ATOMICS)) +JEMALLOC_INLINE uint32_t +atomic_add_uint32(uint32_t *p, uint32_t x) +{ + volatile atomic_uint_least32_t *a = (volatile atomic_uint_least32_t *)p; + return (atomic_fetch_add(a, x) + x); +} + +JEMALLOC_INLINE uint32_t +atomic_sub_uint32(uint32_t *p, uint32_t x) +{ + volatile atomic_uint_least32_t *a = (volatile atomic_uint_least32_t *)p; + return (atomic_fetch_sub(a, x) - x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s) +{ + volatile atomic_uint_least32_t *a = (volatile atomic_uint_least32_t *)p; + return (!atomic_compare_exchange_strong(a, &c, s)); +} + +JEMALLOC_INLINE void +atomic_write_uint32(uint32_t *p, uint32_t x) +{ + volatile atomic_uint_least32_t *a = (volatile atomic_uint_least32_t *)p; + atomic_store(a, x); +} +#elif (defined(JEMALLOC_ATOMIC9)) +JEMALLOC_INLINE uint32_t +atomic_add_uint32(uint32_t *p, uint32_t x) +{ + + return (atomic_fetchadd_32(p, x) + x); +} + +JEMALLOC_INLINE uint32_t +atomic_sub_uint32(uint32_t *p, uint32_t x) +{ + + return (atomic_fetchadd_32(p, (uint32_t)(-(int32_t)x)) - x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s) +{ + + return (!atomic_cmpset_32(p, c, s)); +} + +JEMALLOC_INLINE void +atomic_write_uint32(uint32_t *p, uint32_t x) +{ + + atomic_store_rel_32(p, x); +} +#elif (defined(JEMALLOC_OSATOMIC)) +JEMALLOC_INLINE uint32_t +atomic_add_uint32(uint32_t *p, uint32_t x) +{ + + return (OSAtomicAdd32((int32_t)x, (int32_t *)p)); +} + +JEMALLOC_INLINE uint32_t +atomic_sub_uint32(uint32_t *p, uint32_t x) +{ + + return (OSAtomicAdd32(-((int32_t)x), (int32_t *)p)); +} + +JEMALLOC_INLINE bool +atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s) +{ + + return (!OSAtomicCompareAndSwap32(c, s, (int32_t *)p)); +} + +JEMALLOC_INLINE void +atomic_write_uint32(uint32_t *p, uint32_t x) +{ + uint32_t o; + + /*The documented OSAtomic*() API does not expose an atomic exchange. */ + do { + o = atomic_read_uint32(p); + } while (atomic_cas_uint32(p, o, x)); +} +#elif (defined(_MSC_VER)) +JEMALLOC_INLINE uint32_t +atomic_add_uint32(uint32_t *p, uint32_t x) +{ + + return (InterlockedExchangeAdd(p, x) + x); +} + +JEMALLOC_INLINE uint32_t +atomic_sub_uint32(uint32_t *p, uint32_t x) +{ + + return (InterlockedExchangeAdd(p, -((int32_t)x)) - x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s) +{ + uint32_t o; + + o = InterlockedCompareExchange(p, s, c); + return (o != c); +} + +JEMALLOC_INLINE void +atomic_write_uint32(uint32_t *p, uint32_t x) +{ + + InterlockedExchange(p, x); +} +#elif (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || \ + defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4)) +JEMALLOC_INLINE uint32_t +atomic_add_uint32(uint32_t *p, uint32_t x) +{ + + return (__sync_add_and_fetch(p, x)); +} + +JEMALLOC_INLINE uint32_t +atomic_sub_uint32(uint32_t *p, uint32_t x) +{ + + return (__sync_sub_and_fetch(p, x)); +} + +JEMALLOC_INLINE bool +atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s) +{ + + return (!__sync_bool_compare_and_swap(p, c, s)); +} + +JEMALLOC_INLINE void +atomic_write_uint32(uint32_t *p, uint32_t x) +{ + + __sync_lock_test_and_set(p, x); +} +#else +# error "Missing implementation for 32-bit atomic operations" +#endif + +/******************************************************************************/ +/* Pointer operations. */ +JEMALLOC_INLINE void * +atomic_add_p(void **p, void *x) +{ + +#if (LG_SIZEOF_PTR == 3) + return ((void *)atomic_add_uint64((uint64_t *)p, (uint64_t)x)); +#elif (LG_SIZEOF_PTR == 2) + return ((void *)atomic_add_uint32((uint32_t *)p, (uint32_t)x)); +#endif +} + +JEMALLOC_INLINE void * +atomic_sub_p(void **p, void *x) +{ + +#if (LG_SIZEOF_PTR == 3) + return ((void *)atomic_add_uint64((uint64_t *)p, + (uint64_t)-((int64_t)x))); +#elif (LG_SIZEOF_PTR == 2) + return ((void *)atomic_add_uint32((uint32_t *)p, + (uint32_t)-((int32_t)x))); +#endif +} + +JEMALLOC_INLINE bool +atomic_cas_p(void **p, void *c, void *s) +{ + +#if (LG_SIZEOF_PTR == 3) + return (atomic_cas_uint64((uint64_t *)p, (uint64_t)c, (uint64_t)s)); +#elif (LG_SIZEOF_PTR == 2) + return (atomic_cas_uint32((uint32_t *)p, (uint32_t)c, (uint32_t)s)); +#endif +} + +JEMALLOC_INLINE void +atomic_write_p(void **p, const void *x) +{ + +#if (LG_SIZEOF_PTR == 3) + atomic_write_uint64((uint64_t *)p, (uint64_t)x); +#elif (LG_SIZEOF_PTR == 2) + atomic_write_uint32((uint32_t *)p, (uint32_t)x); +#endif +} + +/******************************************************************************/ +/* size_t operations. */ +JEMALLOC_INLINE size_t +atomic_add_z(size_t *p, size_t x) +{ + +#if (LG_SIZEOF_PTR == 3) + return ((size_t)atomic_add_uint64((uint64_t *)p, (uint64_t)x)); +#elif (LG_SIZEOF_PTR == 2) + return ((size_t)atomic_add_uint32((uint32_t *)p, (uint32_t)x)); +#endif +} + +JEMALLOC_INLINE size_t +atomic_sub_z(size_t *p, size_t x) +{ + +#if (LG_SIZEOF_PTR == 3) + return ((size_t)atomic_add_uint64((uint64_t *)p, + (uint64_t)-((int64_t)x))); +#elif (LG_SIZEOF_PTR == 2) + return ((size_t)atomic_add_uint32((uint32_t *)p, + (uint32_t)-((int32_t)x))); +#endif +} + +JEMALLOC_INLINE bool +atomic_cas_z(size_t *p, size_t c, size_t s) +{ + +#if (LG_SIZEOF_PTR == 3) + return (atomic_cas_uint64((uint64_t *)p, (uint64_t)c, (uint64_t)s)); +#elif (LG_SIZEOF_PTR == 2) + return (atomic_cas_uint32((uint32_t *)p, (uint32_t)c, (uint32_t)s)); +#endif +} + +JEMALLOC_INLINE void +atomic_write_z(size_t *p, size_t x) +{ + +#if (LG_SIZEOF_PTR == 3) + atomic_write_uint64((uint64_t *)p, (uint64_t)x); +#elif (LG_SIZEOF_PTR == 2) + atomic_write_uint32((uint32_t *)p, (uint32_t)x); +#endif +} + +/******************************************************************************/ +/* unsigned operations. */ +JEMALLOC_INLINE unsigned +atomic_add_u(unsigned *p, unsigned x) +{ + +#if (LG_SIZEOF_INT == 3) + return ((unsigned)atomic_add_uint64((uint64_t *)p, (uint64_t)x)); +#elif (LG_SIZEOF_INT == 2) + return ((unsigned)atomic_add_uint32((uint32_t *)p, (uint32_t)x)); +#endif +} + +JEMALLOC_INLINE unsigned +atomic_sub_u(unsigned *p, unsigned x) +{ + +#if (LG_SIZEOF_INT == 3) + return ((unsigned)atomic_add_uint64((uint64_t *)p, + (uint64_t)-((int64_t)x))); +#elif (LG_SIZEOF_INT == 2) + return ((unsigned)atomic_add_uint32((uint32_t *)p, + (uint32_t)-((int32_t)x))); +#endif +} + +JEMALLOC_INLINE bool +atomic_cas_u(unsigned *p, unsigned c, unsigned s) +{ + +#if (LG_SIZEOF_INT == 3) + return (atomic_cas_uint64((uint64_t *)p, (uint64_t)c, (uint64_t)s)); +#elif (LG_SIZEOF_INT == 2) + return (atomic_cas_uint32((uint32_t *)p, (uint32_t)c, (uint32_t)s)); +#endif +} + +JEMALLOC_INLINE void +atomic_write_u(unsigned *p, unsigned x) +{ + +#if (LG_SIZEOF_INT == 3) + atomic_write_uint64((uint64_t *)p, (uint64_t)x); +#elif (LG_SIZEOF_INT == 2) + atomic_write_uint32((uint32_t *)p, (uint32_t)x); +#endif +} + +/******************************************************************************/ +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/base.h b/contrib/jemalloc/include/jemalloc/internal/base.h new file mode 100644 index 0000000..d6b81e1 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/base.h @@ -0,0 +1,25 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void *base_alloc(tsdn_t *tsdn, size_t size); +void base_stats_get(tsdn_t *tsdn, size_t *allocated, size_t *resident, + size_t *mapped); +bool base_boot(void); +void base_prefork(tsdn_t *tsdn); +void base_postfork_parent(tsdn_t *tsdn); +void base_postfork_child(tsdn_t *tsdn); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/bitmap.h b/contrib/jemalloc/include/jemalloc/internal/bitmap.h new file mode 100644 index 0000000..36f38b5 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/bitmap.h @@ -0,0 +1,274 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +/* Maximum bitmap bit count is 2^LG_BITMAP_MAXBITS. */ +#define LG_BITMAP_MAXBITS LG_RUN_MAXREGS +#define BITMAP_MAXBITS (ZU(1) << LG_BITMAP_MAXBITS) + +typedef struct bitmap_level_s bitmap_level_t; +typedef struct bitmap_info_s bitmap_info_t; +typedef unsigned long bitmap_t; +#define LG_SIZEOF_BITMAP LG_SIZEOF_LONG + +/* Number of bits per group. */ +#define LG_BITMAP_GROUP_NBITS (LG_SIZEOF_BITMAP + 3) +#define BITMAP_GROUP_NBITS (ZU(1) << LG_BITMAP_GROUP_NBITS) +#define BITMAP_GROUP_NBITS_MASK (BITMAP_GROUP_NBITS-1) + +/* + * Do some analysis on how big the bitmap is before we use a tree. For a brute + * force linear search, if we would have to call ffs_lu() more than 2^3 times, + * use a tree instead. + */ +#if LG_BITMAP_MAXBITS - LG_BITMAP_GROUP_NBITS > 3 +# define USE_TREE +#endif + +/* Number of groups required to store a given number of bits. */ +#define BITMAP_BITS2GROUPS(nbits) \ + ((nbits + BITMAP_GROUP_NBITS_MASK) >> LG_BITMAP_GROUP_NBITS) + +/* + * Number of groups required at a particular level for a given number of bits. + */ +#define BITMAP_GROUPS_L0(nbits) \ + BITMAP_BITS2GROUPS(nbits) +#define BITMAP_GROUPS_L1(nbits) \ + BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(nbits)) +#define BITMAP_GROUPS_L2(nbits) \ + BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS((nbits)))) +#define BITMAP_GROUPS_L3(nbits) \ + BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS( \ + BITMAP_BITS2GROUPS((nbits))))) + +/* + * Assuming the number of levels, number of groups required for a given number + * of bits. + */ +#define BITMAP_GROUPS_1_LEVEL(nbits) \ + BITMAP_GROUPS_L0(nbits) +#define BITMAP_GROUPS_2_LEVEL(nbits) \ + (BITMAP_GROUPS_1_LEVEL(nbits) + BITMAP_GROUPS_L1(nbits)) +#define BITMAP_GROUPS_3_LEVEL(nbits) \ + (BITMAP_GROUPS_2_LEVEL(nbits) + BITMAP_GROUPS_L2(nbits)) +#define BITMAP_GROUPS_4_LEVEL(nbits) \ + (BITMAP_GROUPS_3_LEVEL(nbits) + BITMAP_GROUPS_L3(nbits)) + +/* + * Maximum number of groups required to support LG_BITMAP_MAXBITS. + */ +#ifdef USE_TREE + +#if LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS +# define BITMAP_GROUPS_MAX BITMAP_GROUPS_1_LEVEL(BITMAP_MAXBITS) +#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 2 +# define BITMAP_GROUPS_MAX BITMAP_GROUPS_2_LEVEL(BITMAP_MAXBITS) +#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 3 +# define BITMAP_GROUPS_MAX BITMAP_GROUPS_3_LEVEL(BITMAP_MAXBITS) +#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 4 +# define BITMAP_GROUPS_MAX BITMAP_GROUPS_4_LEVEL(BITMAP_MAXBITS) +#else +# error "Unsupported bitmap size" +#endif + +/* Maximum number of levels possible. */ +#define BITMAP_MAX_LEVELS \ + (LG_BITMAP_MAXBITS / LG_SIZEOF_BITMAP) \ + + !!(LG_BITMAP_MAXBITS % LG_SIZEOF_BITMAP) + +#else /* USE_TREE */ + +#define BITMAP_GROUPS_MAX BITMAP_BITS2GROUPS(BITMAP_MAXBITS) + +#endif /* USE_TREE */ + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct bitmap_level_s { + /* Offset of this level's groups within the array of groups. */ + size_t group_offset; +}; + +struct bitmap_info_s { + /* Logical number of bits in bitmap (stored at bottom level). */ + size_t nbits; + +#ifdef USE_TREE + /* Number of levels necessary for nbits. */ + unsigned nlevels; + + /* + * Only the first (nlevels+1) elements are used, and levels are ordered + * bottom to top (e.g. the bottom level is stored in levels[0]). + */ + bitmap_level_t levels[BITMAP_MAX_LEVELS+1]; +#else /* USE_TREE */ + /* Number of groups necessary for nbits. */ + size_t ngroups; +#endif /* USE_TREE */ +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void bitmap_info_init(bitmap_info_t *binfo, size_t nbits); +void bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo); +size_t bitmap_size(const bitmap_info_t *binfo); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +bool bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo); +bool bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit); +void bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit); +size_t bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo); +void bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_BITMAP_C_)) +JEMALLOC_INLINE bool +bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo) +{ +#ifdef USE_TREE + size_t rgoff = binfo->levels[binfo->nlevels].group_offset - 1; + bitmap_t rg = bitmap[rgoff]; + /* The bitmap is full iff the root group is 0. */ + return (rg == 0); +#else + size_t i; + + for (i = 0; i < binfo->ngroups; i++) { + if (bitmap[i] != 0) + return (false); + } + return (true); +#endif +} + +JEMALLOC_INLINE bool +bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) +{ + size_t goff; + bitmap_t g; + + assert(bit < binfo->nbits); + goff = bit >> LG_BITMAP_GROUP_NBITS; + g = bitmap[goff]; + return (!(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)))); +} + +JEMALLOC_INLINE void +bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) +{ + size_t goff; + bitmap_t *gp; + bitmap_t g; + + assert(bit < binfo->nbits); + assert(!bitmap_get(bitmap, binfo, bit)); + goff = bit >> LG_BITMAP_GROUP_NBITS; + gp = &bitmap[goff]; + g = *gp; + assert(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK))); + g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK); + *gp = g; + assert(bitmap_get(bitmap, binfo, bit)); +#ifdef USE_TREE + /* Propagate group state transitions up the tree. */ + if (g == 0) { + unsigned i; + for (i = 1; i < binfo->nlevels; i++) { + bit = goff; + goff = bit >> LG_BITMAP_GROUP_NBITS; + gp = &bitmap[binfo->levels[i].group_offset + goff]; + g = *gp; + assert(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK))); + g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK); + *gp = g; + if (g != 0) + break; + } + } +#endif +} + +/* sfu: set first unset. */ +JEMALLOC_INLINE size_t +bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo) +{ + size_t bit; + bitmap_t g; + unsigned i; + + assert(!bitmap_full(bitmap, binfo)); + +#ifdef USE_TREE + i = binfo->nlevels - 1; + g = bitmap[binfo->levels[i].group_offset]; + bit = ffs_lu(g) - 1; + while (i > 0) { + i--; + g = bitmap[binfo->levels[i].group_offset + bit]; + bit = (bit << LG_BITMAP_GROUP_NBITS) + (ffs_lu(g) - 1); + } +#else + i = 0; + g = bitmap[0]; + while ((bit = ffs_lu(g)) == 0) { + i++; + g = bitmap[i]; + } + bit = (i << LG_BITMAP_GROUP_NBITS) + (bit - 1); +#endif + bitmap_set(bitmap, binfo, bit); + return (bit); +} + +JEMALLOC_INLINE void +bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) +{ + size_t goff; + bitmap_t *gp; + bitmap_t g; + UNUSED bool propagate; + + assert(bit < binfo->nbits); + assert(bitmap_get(bitmap, binfo, bit)); + goff = bit >> LG_BITMAP_GROUP_NBITS; + gp = &bitmap[goff]; + g = *gp; + propagate = (g == 0); + assert((g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK))) == 0); + g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK); + *gp = g; + assert(!bitmap_get(bitmap, binfo, bit)); +#ifdef USE_TREE + /* Propagate group state transitions up the tree. */ + if (propagate) { + unsigned i; + for (i = 1; i < binfo->nlevels; i++) { + bit = goff; + goff = bit >> LG_BITMAP_GROUP_NBITS; + gp = &bitmap[binfo->levels[i].group_offset + goff]; + g = *gp; + propagate = (g == 0); + assert((g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK))) + == 0); + g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK); + *gp = g; + if (!propagate) + break; + } + } +#endif /* USE_TREE */ +} + +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/chunk.h b/contrib/jemalloc/include/jemalloc/internal/chunk.h new file mode 100644 index 0000000..c9fd4ec --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/chunk.h @@ -0,0 +1,99 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +/* + * Size and alignment of memory chunks that are allocated by the OS's virtual + * memory system. + */ +#define LG_CHUNK_DEFAULT 21 + +/* Return the chunk address for allocation address a. */ +#define CHUNK_ADDR2BASE(a) \ + ((void *)((uintptr_t)(a) & ~chunksize_mask)) + +/* Return the chunk offset of address a. */ +#define CHUNK_ADDR2OFFSET(a) \ + ((size_t)((uintptr_t)(a) & chunksize_mask)) + +/* Return the smallest chunk multiple that is >= s. */ +#define CHUNK_CEILING(s) \ + (((s) + chunksize_mask) & ~chunksize_mask) + +#define CHUNK_HOOKS_INITIALIZER { \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL \ +} + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +extern size_t opt_lg_chunk; +extern const char *opt_dss; + +extern rtree_t chunks_rtree; + +extern size_t chunksize; +extern size_t chunksize_mask; /* (chunksize - 1). */ +extern size_t chunk_npages; + +extern const chunk_hooks_t chunk_hooks_default; + +chunk_hooks_t chunk_hooks_get(tsdn_t *tsdn, arena_t *arena); +chunk_hooks_t chunk_hooks_set(tsdn_t *tsdn, arena_t *arena, + const chunk_hooks_t *chunk_hooks); + +bool chunk_register(tsdn_t *tsdn, const void *chunk, + const extent_node_t *node); +void chunk_deregister(const void *chunk, const extent_node_t *node); +void *chunk_alloc_base(size_t size); +void *chunk_alloc_cache(tsdn_t *tsdn, arena_t *arena, + chunk_hooks_t *chunk_hooks, void *new_addr, size_t size, size_t alignment, + bool *zero, bool dalloc_node); +void *chunk_alloc_wrapper(tsdn_t *tsdn, arena_t *arena, + chunk_hooks_t *chunk_hooks, void *new_addr, size_t size, size_t alignment, + bool *zero, bool *commit); +void chunk_dalloc_cache(tsdn_t *tsdn, arena_t *arena, + chunk_hooks_t *chunk_hooks, void *chunk, size_t size, bool committed); +void chunk_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, + chunk_hooks_t *chunk_hooks, void *chunk, size_t size, bool zeroed, + bool committed); +bool chunk_purge_wrapper(tsdn_t *tsdn, arena_t *arena, + chunk_hooks_t *chunk_hooks, void *chunk, size_t size, size_t offset, + size_t length); +bool chunk_boot(void); +void chunk_prefork(tsdn_t *tsdn); +void chunk_postfork_parent(tsdn_t *tsdn); +void chunk_postfork_child(tsdn_t *tsdn); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +extent_node_t *chunk_lookup(const void *chunk, bool dependent); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_CHUNK_C_)) +JEMALLOC_INLINE extent_node_t * +chunk_lookup(const void *ptr, bool dependent) +{ + + return (rtree_get(&chunks_rtree, (uintptr_t)ptr, dependent)); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ + +#include "jemalloc/internal/chunk_dss.h" +#include "jemalloc/internal/chunk_mmap.h" diff --git a/contrib/jemalloc/include/jemalloc/internal/chunk_dss.h b/contrib/jemalloc/include/jemalloc/internal/chunk_dss.h new file mode 100644 index 0000000..724fa57 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/chunk_dss.h @@ -0,0 +1,39 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef enum { + dss_prec_disabled = 0, + dss_prec_primary = 1, + dss_prec_secondary = 2, + + dss_prec_limit = 3 +} dss_prec_t; +#define DSS_PREC_DEFAULT dss_prec_secondary +#define DSS_DEFAULT "secondary" + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +extern const char *dss_prec_names[]; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +dss_prec_t chunk_dss_prec_get(tsdn_t *tsdn); +bool chunk_dss_prec_set(tsdn_t *tsdn, dss_prec_t dss_prec); +void *chunk_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, + size_t size, size_t alignment, bool *zero, bool *commit); +bool chunk_in_dss(tsdn_t *tsdn, void *chunk); +bool chunk_dss_boot(void); +void chunk_dss_prefork(tsdn_t *tsdn); +void chunk_dss_postfork_parent(tsdn_t *tsdn); +void chunk_dss_postfork_child(tsdn_t *tsdn); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/chunk_mmap.h b/contrib/jemalloc/include/jemalloc/internal/chunk_mmap.h new file mode 100644 index 0000000..6f2d0ac --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/chunk_mmap.h @@ -0,0 +1,21 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void *chunk_alloc_mmap(void *new_addr, size_t size, size_t alignment, + bool *zero, bool *commit); +bool chunk_dalloc_mmap(void *chunk, size_t size); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/ckh.h b/contrib/jemalloc/include/jemalloc/internal/ckh.h new file mode 100644 index 0000000..46e151c --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/ckh.h @@ -0,0 +1,86 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct ckh_s ckh_t; +typedef struct ckhc_s ckhc_t; + +/* Typedefs to allow easy function pointer passing. */ +typedef void ckh_hash_t (const void *, size_t[2]); +typedef bool ckh_keycomp_t (const void *, const void *); + +/* Maintain counters used to get an idea of performance. */ +/* #define CKH_COUNT */ +/* Print counter values in ckh_delete() (requires CKH_COUNT). */ +/* #define CKH_VERBOSE */ + +/* + * There are 2^LG_CKH_BUCKET_CELLS cells in each hash table bucket. Try to fit + * one bucket per L1 cache line. + */ +#define LG_CKH_BUCKET_CELLS (LG_CACHELINE - LG_SIZEOF_PTR - 1) + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +/* Hash table cell. */ +struct ckhc_s { + const void *key; + const void *data; +}; + +struct ckh_s { +#ifdef CKH_COUNT + /* Counters used to get an idea of performance. */ + uint64_t ngrows; + uint64_t nshrinks; + uint64_t nshrinkfails; + uint64_t ninserts; + uint64_t nrelocs; +#endif + + /* Used for pseudo-random number generation. */ + uint64_t prng_state; + + /* Total number of items. */ + size_t count; + + /* + * Minimum and current number of hash table buckets. There are + * 2^LG_CKH_BUCKET_CELLS cells per bucket. + */ + unsigned lg_minbuckets; + unsigned lg_curbuckets; + + /* Hash and comparison functions. */ + ckh_hash_t *hash; + ckh_keycomp_t *keycomp; + + /* Hash table with 2^lg_curbuckets buckets. */ + ckhc_t *tab; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +bool ckh_new(tsdn_t *tsdn, ckh_t *ckh, size_t minitems, ckh_hash_t *hash, + ckh_keycomp_t *keycomp); +void ckh_delete(tsdn_t *tsdn, ckh_t *ckh); +size_t ckh_count(ckh_t *ckh); +bool ckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data); +bool ckh_insert(tsdn_t *tsdn, ckh_t *ckh, const void *key, const void *data); +bool ckh_remove(tsdn_t *tsdn, ckh_t *ckh, const void *searchkey, void **key, + void **data); +bool ckh_search(ckh_t *ckh, const void *searchkey, void **key, void **data); +void ckh_string_hash(const void *key, size_t r_hash[2]); +bool ckh_string_keycomp(const void *k1, const void *k2); +void ckh_pointer_hash(const void *key, size_t r_hash[2]); +bool ckh_pointer_keycomp(const void *k1, const void *k2); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/ctl.h b/contrib/jemalloc/include/jemalloc/internal/ctl.h new file mode 100644 index 0000000..af0f6d7 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/ctl.h @@ -0,0 +1,118 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct ctl_node_s ctl_node_t; +typedef struct ctl_named_node_s ctl_named_node_t; +typedef struct ctl_indexed_node_s ctl_indexed_node_t; +typedef struct ctl_arena_stats_s ctl_arena_stats_t; +typedef struct ctl_stats_s ctl_stats_t; + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct ctl_node_s { + bool named; +}; + +struct ctl_named_node_s { + struct ctl_node_s node; + const char *name; + /* If (nchildren == 0), this is a terminal node. */ + unsigned nchildren; + const ctl_node_t *children; + int (*ctl)(tsd_t *, const size_t *, size_t, void *, + size_t *, void *, size_t); +}; + +struct ctl_indexed_node_s { + struct ctl_node_s node; + const ctl_named_node_t *(*index)(tsdn_t *, const size_t *, size_t, + size_t); +}; + +struct ctl_arena_stats_s { + bool initialized; + unsigned nthreads; + const char *dss; + ssize_t lg_dirty_mult; + ssize_t decay_time; + size_t pactive; + size_t pdirty; + + /* The remainder are only populated if config_stats is true. */ + + arena_stats_t astats; + + /* Aggregate stats for small size classes, based on bin stats. */ + size_t allocated_small; + uint64_t nmalloc_small; + uint64_t ndalloc_small; + uint64_t nrequests_small; + + malloc_bin_stats_t bstats[NBINS]; + malloc_large_stats_t *lstats; /* nlclasses elements. */ + malloc_huge_stats_t *hstats; /* nhclasses elements. */ +}; + +struct ctl_stats_s { + size_t allocated; + size_t active; + size_t metadata; + size_t resident; + size_t mapped; + size_t retained; + unsigned narenas; + ctl_arena_stats_t *arenas; /* (narenas + 1) elements. */ +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +int ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp, + void *newp, size_t newlen); +int ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, + size_t *miblenp); + +int ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen); +bool ctl_boot(void); +void ctl_prefork(tsdn_t *tsdn); +void ctl_postfork_parent(tsdn_t *tsdn); +void ctl_postfork_child(tsdn_t *tsdn); + +#define xmallctl(name, oldp, oldlenp, newp, newlen) do { \ + if (je_mallctl(name, oldp, oldlenp, newp, newlen) \ + != 0) { \ + malloc_printf( \ + ": Failure in xmallctl(\"%s\", ...)\n", \ + name); \ + abort(); \ + } \ +} while (0) + +#define xmallctlnametomib(name, mibp, miblenp) do { \ + if (je_mallctlnametomib(name, mibp, miblenp) != 0) { \ + malloc_printf(": Failure in " \ + "xmallctlnametomib(\"%s\", ...)\n", name); \ + abort(); \ + } \ +} while (0) + +#define xmallctlbymib(mib, miblen, oldp, oldlenp, newp, newlen) do { \ + if (je_mallctlbymib(mib, miblen, oldp, oldlenp, newp, \ + newlen) != 0) { \ + malloc_write( \ + ": Failure in xmallctlbymib()\n"); \ + abort(); \ + } \ +} while (0) + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ + diff --git a/contrib/jemalloc/include/jemalloc/internal/extent.h b/contrib/jemalloc/include/jemalloc/internal/extent.h new file mode 100644 index 0000000..49d76a5 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/extent.h @@ -0,0 +1,239 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct extent_node_s extent_node_t; + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +/* Tree of extents. Use accessor functions for en_* fields. */ +struct extent_node_s { + /* Arena from which this extent came, if any. */ + arena_t *en_arena; + + /* Pointer to the extent that this tree node is responsible for. */ + void *en_addr; + + /* Total region size. */ + size_t en_size; + + /* + * The zeroed flag is used by chunk recycling code to track whether + * memory is zero-filled. + */ + bool en_zeroed; + + /* + * True if physical memory is committed to the extent, whether + * explicitly or implicitly as on a system that overcommits and + * satisfies physical memory needs on demand via soft page faults. + */ + bool en_committed; + + /* + * The achunk flag is used to validate that huge allocation lookups + * don't return arena chunks. + */ + bool en_achunk; + + /* Profile counters, used for huge objects. */ + prof_tctx_t *en_prof_tctx; + + /* Linkage for arena's runs_dirty and chunks_cache rings. */ + arena_runs_dirty_link_t rd; + qr(extent_node_t) cc_link; + + union { + /* Linkage for the size/address-ordered tree. */ + rb_node(extent_node_t) szad_link; + + /* Linkage for arena's achunks, huge, and node_cache lists. */ + ql_elm(extent_node_t) ql_link; + }; + + /* Linkage for the address-ordered tree. */ + rb_node(extent_node_t) ad_link; +}; +typedef rb_tree(extent_node_t) extent_tree_t; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +rb_proto(, extent_tree_szad_, extent_tree_t, extent_node_t) + +rb_proto(, extent_tree_ad_, extent_tree_t, extent_node_t) + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +arena_t *extent_node_arena_get(const extent_node_t *node); +void *extent_node_addr_get(const extent_node_t *node); +size_t extent_node_size_get(const extent_node_t *node); +bool extent_node_zeroed_get(const extent_node_t *node); +bool extent_node_committed_get(const extent_node_t *node); +bool extent_node_achunk_get(const extent_node_t *node); +prof_tctx_t *extent_node_prof_tctx_get(const extent_node_t *node); +void extent_node_arena_set(extent_node_t *node, arena_t *arena); +void extent_node_addr_set(extent_node_t *node, void *addr); +void extent_node_size_set(extent_node_t *node, size_t size); +void extent_node_zeroed_set(extent_node_t *node, bool zeroed); +void extent_node_committed_set(extent_node_t *node, bool committed); +void extent_node_achunk_set(extent_node_t *node, bool achunk); +void extent_node_prof_tctx_set(extent_node_t *node, prof_tctx_t *tctx); +void extent_node_init(extent_node_t *node, arena_t *arena, void *addr, + size_t size, bool zeroed, bool committed); +void extent_node_dirty_linkage_init(extent_node_t *node); +void extent_node_dirty_insert(extent_node_t *node, + arena_runs_dirty_link_t *runs_dirty, extent_node_t *chunks_dirty); +void extent_node_dirty_remove(extent_node_t *node); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_EXTENT_C_)) +JEMALLOC_INLINE arena_t * +extent_node_arena_get(const extent_node_t *node) +{ + + return (node->en_arena); +} + +JEMALLOC_INLINE void * +extent_node_addr_get(const extent_node_t *node) +{ + + return (node->en_addr); +} + +JEMALLOC_INLINE size_t +extent_node_size_get(const extent_node_t *node) +{ + + return (node->en_size); +} + +JEMALLOC_INLINE bool +extent_node_zeroed_get(const extent_node_t *node) +{ + + return (node->en_zeroed); +} + +JEMALLOC_INLINE bool +extent_node_committed_get(const extent_node_t *node) +{ + + assert(!node->en_achunk); + return (node->en_committed); +} + +JEMALLOC_INLINE bool +extent_node_achunk_get(const extent_node_t *node) +{ + + return (node->en_achunk); +} + +JEMALLOC_INLINE prof_tctx_t * +extent_node_prof_tctx_get(const extent_node_t *node) +{ + + return (node->en_prof_tctx); +} + +JEMALLOC_INLINE void +extent_node_arena_set(extent_node_t *node, arena_t *arena) +{ + + node->en_arena = arena; +} + +JEMALLOC_INLINE void +extent_node_addr_set(extent_node_t *node, void *addr) +{ + + node->en_addr = addr; +} + +JEMALLOC_INLINE void +extent_node_size_set(extent_node_t *node, size_t size) +{ + + node->en_size = size; +} + +JEMALLOC_INLINE void +extent_node_zeroed_set(extent_node_t *node, bool zeroed) +{ + + node->en_zeroed = zeroed; +} + +JEMALLOC_INLINE void +extent_node_committed_set(extent_node_t *node, bool committed) +{ + + node->en_committed = committed; +} + +JEMALLOC_INLINE void +extent_node_achunk_set(extent_node_t *node, bool achunk) +{ + + node->en_achunk = achunk; +} + +JEMALLOC_INLINE void +extent_node_prof_tctx_set(extent_node_t *node, prof_tctx_t *tctx) +{ + + node->en_prof_tctx = tctx; +} + +JEMALLOC_INLINE void +extent_node_init(extent_node_t *node, arena_t *arena, void *addr, size_t size, + bool zeroed, bool committed) +{ + + extent_node_arena_set(node, arena); + extent_node_addr_set(node, addr); + extent_node_size_set(node, size); + extent_node_zeroed_set(node, zeroed); + extent_node_committed_set(node, committed); + extent_node_achunk_set(node, false); + if (config_prof) + extent_node_prof_tctx_set(node, NULL); +} + +JEMALLOC_INLINE void +extent_node_dirty_linkage_init(extent_node_t *node) +{ + + qr_new(&node->rd, rd_link); + qr_new(node, cc_link); +} + +JEMALLOC_INLINE void +extent_node_dirty_insert(extent_node_t *node, + arena_runs_dirty_link_t *runs_dirty, extent_node_t *chunks_dirty) +{ + + qr_meld(runs_dirty, &node->rd, rd_link); + qr_meld(chunks_dirty, node, cc_link); +} + +JEMALLOC_INLINE void +extent_node_dirty_remove(extent_node_t *node) +{ + + qr_remove(&node->rd, rd_link); + qr_remove(node, cc_link); +} + +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ + diff --git a/contrib/jemalloc/include/jemalloc/internal/hash.h b/contrib/jemalloc/include/jemalloc/internal/hash.h new file mode 100644 index 0000000..1ff2d9a --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/hash.h @@ -0,0 +1,357 @@ +/* + * The following hash function is based on MurmurHash3, placed into the public + * domain by Austin Appleby. See https://github.com/aappleby/smhasher for + * details. + */ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +uint32_t hash_x86_32(const void *key, int len, uint32_t seed); +void hash_x86_128(const void *key, const int len, uint32_t seed, + uint64_t r_out[2]); +void hash_x64_128(const void *key, const int len, const uint32_t seed, + uint64_t r_out[2]); +void hash(const void *key, size_t len, const uint32_t seed, + size_t r_hash[2]); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_HASH_C_)) +/******************************************************************************/ +/* Internal implementation. */ +JEMALLOC_INLINE uint32_t +hash_rotl_32(uint32_t x, int8_t r) +{ + + return ((x << r) | (x >> (32 - r))); +} + +JEMALLOC_INLINE uint64_t +hash_rotl_64(uint64_t x, int8_t r) +{ + + return ((x << r) | (x >> (64 - r))); +} + +JEMALLOC_INLINE uint32_t +hash_get_block_32(const uint32_t *p, int i) +{ + + /* Handle unaligned read. */ + if (unlikely((uintptr_t)p & (sizeof(uint32_t)-1)) != 0) { + uint32_t ret; + + memcpy(&ret, (uint8_t *)(p + i), sizeof(uint32_t)); + return (ret); + } + + return (p[i]); +} + +JEMALLOC_INLINE uint64_t +hash_get_block_64(const uint64_t *p, int i) +{ + + /* Handle unaligned read. */ + if (unlikely((uintptr_t)p & (sizeof(uint64_t)-1)) != 0) { + uint64_t ret; + + memcpy(&ret, (uint8_t *)(p + i), sizeof(uint64_t)); + return (ret); + } + + return (p[i]); +} + +JEMALLOC_INLINE uint32_t +hash_fmix_32(uint32_t h) +{ + + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return (h); +} + +JEMALLOC_INLINE uint64_t +hash_fmix_64(uint64_t k) +{ + + k ^= k >> 33; + k *= KQU(0xff51afd7ed558ccd); + k ^= k >> 33; + k *= KQU(0xc4ceb9fe1a85ec53); + k ^= k >> 33; + + return (k); +} + +JEMALLOC_INLINE uint32_t +hash_x86_32(const void *key, int len, uint32_t seed) +{ + const uint8_t *data = (const uint8_t *) key; + const int nblocks = len / 4; + + uint32_t h1 = seed; + + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + + /* body */ + { + const uint32_t *blocks = (const uint32_t *) (data + nblocks*4); + int i; + + for (i = -nblocks; i; i++) { + uint32_t k1 = hash_get_block_32(blocks, i); + + k1 *= c1; + k1 = hash_rotl_32(k1, 15); + k1 *= c2; + + h1 ^= k1; + h1 = hash_rotl_32(h1, 13); + h1 = h1*5 + 0xe6546b64; + } + } + + /* tail */ + { + const uint8_t *tail = (const uint8_t *) (data + nblocks*4); + + uint32_t k1 = 0; + + switch (len & 3) { + case 3: k1 ^= tail[2] << 16; + case 2: k1 ^= tail[1] << 8; + case 1: k1 ^= tail[0]; k1 *= c1; k1 = hash_rotl_32(k1, 15); + k1 *= c2; h1 ^= k1; + } + } + + /* finalization */ + h1 ^= len; + + h1 = hash_fmix_32(h1); + + return (h1); +} + +UNUSED JEMALLOC_INLINE void +hash_x86_128(const void *key, const int len, uint32_t seed, + uint64_t r_out[2]) +{ + const uint8_t * data = (const uint8_t *) key; + const int nblocks = len / 16; + + uint32_t h1 = seed; + uint32_t h2 = seed; + uint32_t h3 = seed; + uint32_t h4 = seed; + + const uint32_t c1 = 0x239b961b; + const uint32_t c2 = 0xab0e9789; + const uint32_t c3 = 0x38b34ae5; + const uint32_t c4 = 0xa1e38b93; + + /* body */ + { + const uint32_t *blocks = (const uint32_t *) (data + nblocks*16); + int i; + + for (i = -nblocks; i; i++) { + uint32_t k1 = hash_get_block_32(blocks, i*4 + 0); + uint32_t k2 = hash_get_block_32(blocks, i*4 + 1); + uint32_t k3 = hash_get_block_32(blocks, i*4 + 2); + uint32_t k4 = hash_get_block_32(blocks, i*4 + 3); + + k1 *= c1; k1 = hash_rotl_32(k1, 15); k1 *= c2; h1 ^= k1; + + h1 = hash_rotl_32(h1, 19); h1 += h2; + h1 = h1*5 + 0x561ccd1b; + + k2 *= c2; k2 = hash_rotl_32(k2, 16); k2 *= c3; h2 ^= k2; + + h2 = hash_rotl_32(h2, 17); h2 += h3; + h2 = h2*5 + 0x0bcaa747; + + k3 *= c3; k3 = hash_rotl_32(k3, 17); k3 *= c4; h3 ^= k3; + + h3 = hash_rotl_32(h3, 15); h3 += h4; + h3 = h3*5 + 0x96cd1c35; + + k4 *= c4; k4 = hash_rotl_32(k4, 18); k4 *= c1; h4 ^= k4; + + h4 = hash_rotl_32(h4, 13); h4 += h1; + h4 = h4*5 + 0x32ac3b17; + } + } + + /* tail */ + { + const uint8_t *tail = (const uint8_t *) (data + nblocks*16); + uint32_t k1 = 0; + uint32_t k2 = 0; + uint32_t k3 = 0; + uint32_t k4 = 0; + + switch (len & 15) { + case 15: k4 ^= tail[14] << 16; + case 14: k4 ^= tail[13] << 8; + case 13: k4 ^= tail[12] << 0; + k4 *= c4; k4 = hash_rotl_32(k4, 18); k4 *= c1; h4 ^= k4; + + case 12: k3 ^= tail[11] << 24; + case 11: k3 ^= tail[10] << 16; + case 10: k3 ^= tail[ 9] << 8; + case 9: k3 ^= tail[ 8] << 0; + k3 *= c3; k3 = hash_rotl_32(k3, 17); k3 *= c4; h3 ^= k3; + + case 8: k2 ^= tail[ 7] << 24; + case 7: k2 ^= tail[ 6] << 16; + case 6: k2 ^= tail[ 5] << 8; + case 5: k2 ^= tail[ 4] << 0; + k2 *= c2; k2 = hash_rotl_32(k2, 16); k2 *= c3; h2 ^= k2; + + case 4: k1 ^= tail[ 3] << 24; + case 3: k1 ^= tail[ 2] << 16; + case 2: k1 ^= tail[ 1] << 8; + case 1: k1 ^= tail[ 0] << 0; + k1 *= c1; k1 = hash_rotl_32(k1, 15); k1 *= c2; h1 ^= k1; + } + } + + /* finalization */ + h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len; + + h1 += h2; h1 += h3; h1 += h4; + h2 += h1; h3 += h1; h4 += h1; + + h1 = hash_fmix_32(h1); + h2 = hash_fmix_32(h2); + h3 = hash_fmix_32(h3); + h4 = hash_fmix_32(h4); + + h1 += h2; h1 += h3; h1 += h4; + h2 += h1; h3 += h1; h4 += h1; + + r_out[0] = (((uint64_t) h2) << 32) | h1; + r_out[1] = (((uint64_t) h4) << 32) | h3; +} + +UNUSED JEMALLOC_INLINE void +hash_x64_128(const void *key, const int len, const uint32_t seed, + uint64_t r_out[2]) +{ + const uint8_t *data = (const uint8_t *) key; + const int nblocks = len / 16; + + uint64_t h1 = seed; + uint64_t h2 = seed; + + const uint64_t c1 = KQU(0x87c37b91114253d5); + const uint64_t c2 = KQU(0x4cf5ad432745937f); + + /* body */ + { + const uint64_t *blocks = (const uint64_t *) (data); + int i; + + for (i = 0; i < nblocks; i++) { + uint64_t k1 = hash_get_block_64(blocks, i*2 + 0); + uint64_t k2 = hash_get_block_64(blocks, i*2 + 1); + + k1 *= c1; k1 = hash_rotl_64(k1, 31); k1 *= c2; h1 ^= k1; + + h1 = hash_rotl_64(h1, 27); h1 += h2; + h1 = h1*5 + 0x52dce729; + + k2 *= c2; k2 = hash_rotl_64(k2, 33); k2 *= c1; h2 ^= k2; + + h2 = hash_rotl_64(h2, 31); h2 += h1; + h2 = h2*5 + 0x38495ab5; + } + } + + /* tail */ + { + const uint8_t *tail = (const uint8_t*)(data + nblocks*16); + uint64_t k1 = 0; + uint64_t k2 = 0; + + switch (len & 15) { + case 15: k2 ^= ((uint64_t)(tail[14])) << 48; + case 14: k2 ^= ((uint64_t)(tail[13])) << 40; + case 13: k2 ^= ((uint64_t)(tail[12])) << 32; + case 12: k2 ^= ((uint64_t)(tail[11])) << 24; + case 11: k2 ^= ((uint64_t)(tail[10])) << 16; + case 10: k2 ^= ((uint64_t)(tail[ 9])) << 8; + case 9: k2 ^= ((uint64_t)(tail[ 8])) << 0; + k2 *= c2; k2 = hash_rotl_64(k2, 33); k2 *= c1; h2 ^= k2; + + case 8: k1 ^= ((uint64_t)(tail[ 7])) << 56; + case 7: k1 ^= ((uint64_t)(tail[ 6])) << 48; + case 6: k1 ^= ((uint64_t)(tail[ 5])) << 40; + case 5: k1 ^= ((uint64_t)(tail[ 4])) << 32; + case 4: k1 ^= ((uint64_t)(tail[ 3])) << 24; + case 3: k1 ^= ((uint64_t)(tail[ 2])) << 16; + case 2: k1 ^= ((uint64_t)(tail[ 1])) << 8; + case 1: k1 ^= ((uint64_t)(tail[ 0])) << 0; + k1 *= c1; k1 = hash_rotl_64(k1, 31); k1 *= c2; h1 ^= k1; + } + } + + /* finalization */ + h1 ^= len; h2 ^= len; + + h1 += h2; + h2 += h1; + + h1 = hash_fmix_64(h1); + h2 = hash_fmix_64(h2); + + h1 += h2; + h2 += h1; + + r_out[0] = h1; + r_out[1] = h2; +} + +/******************************************************************************/ +/* API. */ +JEMALLOC_INLINE void +hash(const void *key, size_t len, const uint32_t seed, size_t r_hash[2]) +{ + + assert(len <= INT_MAX); /* Unfortunate implementation limitation. */ + +#if (LG_SIZEOF_PTR == 3 && !defined(JEMALLOC_BIG_ENDIAN)) + hash_x64_128(key, (int)len, seed, (uint64_t *)r_hash); +#else + { + uint64_t hashes[2]; + hash_x86_128(key, (int)len, seed, hashes); + r_hash[0] = (size_t)hashes[0]; + r_hash[1] = (size_t)hashes[1]; + } +#endif +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/huge.h b/contrib/jemalloc/include/jemalloc/internal/huge.h new file mode 100644 index 0000000..b5fa9e6 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/huge.h @@ -0,0 +1,35 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void *huge_malloc(tsdn_t *tsdn, arena_t *arena, size_t usize, bool zero); +void *huge_palloc(tsdn_t *tsdn, arena_t *arena, size_t usize, + size_t alignment, bool zero); +bool huge_ralloc_no_move(tsdn_t *tsdn, void *ptr, size_t oldsize, + size_t usize_min, size_t usize_max, bool zero); +void *huge_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, + size_t usize, size_t alignment, bool zero, tcache_t *tcache); +#ifdef JEMALLOC_JET +typedef void (huge_dalloc_junk_t)(tsdn_t *, void *, size_t); +extern huge_dalloc_junk_t *huge_dalloc_junk; +#endif +void huge_dalloc(tsdn_t *tsdn, void *ptr); +arena_t *huge_aalloc(const void *ptr); +size_t huge_salloc(tsdn_t *tsdn, const void *ptr); +prof_tctx_t *huge_prof_tctx_get(tsdn_t *tsdn, const void *ptr); +void huge_prof_tctx_set(tsdn_t *tsdn, const void *ptr, prof_tctx_t *tctx); +void huge_prof_tctx_reset(tsdn_t *tsdn, const void *ptr); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal.h b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal.h new file mode 100644 index 0000000..49f14a5 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal.h @@ -0,0 +1,1191 @@ +#ifndef JEMALLOC_INTERNAL_H +#define JEMALLOC_INTERNAL_H + +#include "jemalloc_internal_defs.h" +#include "jemalloc/internal/jemalloc_internal_decls.h" + +#ifdef JEMALLOC_UTRACE +#include +#endif + +#include "un-namespace.h" +#include "libc_private.h" + +#define JEMALLOC_NO_DEMANGLE +#ifdef JEMALLOC_JET +# define JEMALLOC_N(n) jet_##n +# include "jemalloc/internal/public_namespace.h" +# define JEMALLOC_NO_RENAME +# include "../jemalloc.h" +# undef JEMALLOC_NO_RENAME +#else +# define JEMALLOC_N(n) __je_##n +# include "../jemalloc.h" +#endif +#include "jemalloc/internal/private_namespace.h" + +static const bool config_debug = +#ifdef JEMALLOC_DEBUG + true +#else + false +#endif + ; +static const bool have_dss = +#ifdef JEMALLOC_DSS + true +#else + false +#endif + ; +static const bool config_fill = +#ifdef JEMALLOC_FILL + true +#else + false +#endif + ; +static const bool config_lazy_lock = true; +static const char * const config_malloc_conf = JEMALLOC_CONFIG_MALLOC_CONF; +static const bool config_prof = +#ifdef JEMALLOC_PROF + true +#else + false +#endif + ; +static const bool config_prof_libgcc = +#ifdef JEMALLOC_PROF_LIBGCC + true +#else + false +#endif + ; +static const bool config_prof_libunwind = +#ifdef JEMALLOC_PROF_LIBUNWIND + true +#else + false +#endif + ; +static const bool maps_coalesce = +#ifdef JEMALLOC_MAPS_COALESCE + true +#else + false +#endif + ; +static const bool config_munmap = +#ifdef JEMALLOC_MUNMAP + true +#else + false +#endif + ; +static const bool config_stats = +#ifdef JEMALLOC_STATS + true +#else + false +#endif + ; +static const bool config_tcache = +#ifdef JEMALLOC_TCACHE + true +#else + false +#endif + ; +static const bool config_tls = +#ifdef JEMALLOC_TLS + true +#else + false +#endif + ; +static const bool config_utrace = +#ifdef JEMALLOC_UTRACE + true +#else + false +#endif + ; +static const bool config_valgrind = +#ifdef JEMALLOC_VALGRIND + true +#else + false +#endif + ; +static const bool config_xmalloc = +#ifdef JEMALLOC_XMALLOC + true +#else + false +#endif + ; +static const bool config_ivsalloc = +#ifdef JEMALLOC_IVSALLOC + true +#else + false +#endif + ; +static const bool config_cache_oblivious = +#ifdef JEMALLOC_CACHE_OBLIVIOUS + true +#else + false +#endif + ; + +#ifdef JEMALLOC_C11ATOMICS +#include +#endif + +#ifdef JEMALLOC_ATOMIC9 +#include +#endif + +#if (defined(JEMALLOC_OSATOMIC) || defined(JEMALLOC_OSSPIN)) +#include +#endif + +#ifdef JEMALLOC_ZONE +#include +#include +#include +#include +#endif + +#include "jemalloc/internal/ph.h" +#define RB_COMPACT +#include "jemalloc/internal/rb.h" +#include "jemalloc/internal/qr.h" +#include "jemalloc/internal/ql.h" + +/* + * jemalloc can conceptually be broken into components (arena, tcache, etc.), + * but there are circular dependencies that cannot be broken without + * substantial performance degradation. In order to reduce the effect on + * visual code flow, read the header files in multiple passes, with one of the + * following cpp variables defined during each pass: + * + * JEMALLOC_H_TYPES : Preprocessor-defined constants and psuedo-opaque data + * types. + * JEMALLOC_H_STRUCTS : Data structures. + * JEMALLOC_H_EXTERNS : Extern data declarations and function prototypes. + * JEMALLOC_H_INLINES : Inline functions. + */ +/******************************************************************************/ +#define JEMALLOC_H_TYPES + +#include "jemalloc/internal/jemalloc_internal_macros.h" + +/* Size class index type. */ +typedef unsigned szind_t; + +/* + * Flags bits: + * + * a: arena + * t: tcache + * 0: unused + * z: zero + * n: alignment + * + * aaaaaaaa aaaatttt tttttttt 0znnnnnn + */ +#define MALLOCX_ARENA_MASK ((int)~0xfffff) +#define MALLOCX_ARENA_MAX 0xffe +#define MALLOCX_TCACHE_MASK ((int)~0xfff000ffU) +#define MALLOCX_TCACHE_MAX 0xffd +#define MALLOCX_LG_ALIGN_MASK ((int)0x3f) +/* Use MALLOCX_ALIGN_GET() if alignment may not be specified in flags. */ +#define MALLOCX_ALIGN_GET_SPECIFIED(flags) \ + (ZU(1) << (flags & MALLOCX_LG_ALIGN_MASK)) +#define MALLOCX_ALIGN_GET(flags) \ + (MALLOCX_ALIGN_GET_SPECIFIED(flags) & (SIZE_T_MAX-1)) +#define MALLOCX_ZERO_GET(flags) \ + ((bool)(flags & MALLOCX_ZERO)) + +#define MALLOCX_TCACHE_GET(flags) \ + (((unsigned)((flags & MALLOCX_TCACHE_MASK) >> 8)) - 2) +#define MALLOCX_ARENA_GET(flags) \ + (((unsigned)(((unsigned)flags) >> 20)) - 1) + +/* Smallest size class to support. */ +#define TINY_MIN (1U << LG_TINY_MIN) + +/* + * Minimum allocation alignment is 2^LG_QUANTUM bytes (ignoring tiny size + * classes). + */ +#ifndef LG_QUANTUM +# if (defined(__i386__) || defined(_M_IX86)) +# define LG_QUANTUM 4 +# endif +# ifdef __ia64__ +# define LG_QUANTUM 4 +# endif +# ifdef __alpha__ +# define LG_QUANTUM 4 +# endif +# if (defined(__sparc64__) || defined(__sparcv9)) +# define LG_QUANTUM 4 +# endif +# if (defined(__amd64__) || defined(__x86_64__) || defined(_M_X64)) +# define LG_QUANTUM 4 +# endif +# ifdef __arm__ +# define LG_QUANTUM 3 +# endif +# ifdef __aarch64__ +# define LG_QUANTUM 4 +# endif +# ifdef __hppa__ +# define LG_QUANTUM 4 +# endif +# ifdef __mips__ +# define LG_QUANTUM 3 +# endif +# ifdef __or1k__ +# define LG_QUANTUM 3 +# endif +# ifdef __powerpc__ +# define LG_QUANTUM 4 +# endif +# ifdef __riscv__ +# define LG_QUANTUM 4 +# endif +# ifdef __s390__ +# define LG_QUANTUM 4 +# endif +# ifdef __SH4__ +# define LG_QUANTUM 4 +# endif +# ifdef __tile__ +# define LG_QUANTUM 4 +# endif +# ifdef __le32__ +# define LG_QUANTUM 4 +# endif +# ifndef LG_QUANTUM +# error "Unknown minimum alignment for architecture; specify via " + "--with-lg-quantum" +# endif +#endif + +#define QUANTUM ((size_t)(1U << LG_QUANTUM)) +#define QUANTUM_MASK (QUANTUM - 1) + +/* Return the smallest quantum multiple that is >= a. */ +#define QUANTUM_CEILING(a) \ + (((a) + QUANTUM_MASK) & ~QUANTUM_MASK) + +#define LONG ((size_t)(1U << LG_SIZEOF_LONG)) +#define LONG_MASK (LONG - 1) + +/* Return the smallest long multiple that is >= a. */ +#define LONG_CEILING(a) \ + (((a) + LONG_MASK) & ~LONG_MASK) + +#define SIZEOF_PTR (1U << LG_SIZEOF_PTR) +#define PTR_MASK (SIZEOF_PTR - 1) + +/* Return the smallest (void *) multiple that is >= a. */ +#define PTR_CEILING(a) \ + (((a) + PTR_MASK) & ~PTR_MASK) + +/* + * Maximum size of L1 cache line. This is used to avoid cache line aliasing. + * In addition, this controls the spacing of cacheline-spaced size classes. + * + * CACHELINE cannot be based on LG_CACHELINE because __declspec(align()) can + * only handle raw constants. + */ +#define LG_CACHELINE 6 +#define CACHELINE 64 +#define CACHELINE_MASK (CACHELINE - 1) + +/* Return the smallest cacheline multiple that is >= s. */ +#define CACHELINE_CEILING(s) \ + (((s) + CACHELINE_MASK) & ~CACHELINE_MASK) + +/* Page size. LG_PAGE is determined by the configure script. */ +#ifdef PAGE_MASK +# undef PAGE_MASK +#endif +#define PAGE ((size_t)(1U << LG_PAGE)) +#define PAGE_MASK ((size_t)(PAGE - 1)) + +/* Return the page base address for the page containing address a. */ +#define PAGE_ADDR2BASE(a) \ + ((void *)((uintptr_t)(a) & ~PAGE_MASK)) + +/* Return the smallest pagesize multiple that is >= s. */ +#define PAGE_CEILING(s) \ + (((s) + PAGE_MASK) & ~PAGE_MASK) + +/* Return the nearest aligned address at or below a. */ +#define ALIGNMENT_ADDR2BASE(a, alignment) \ + ((void *)((uintptr_t)(a) & (-(alignment)))) + +/* Return the offset between a and the nearest aligned address at or below a. */ +#define ALIGNMENT_ADDR2OFFSET(a, alignment) \ + ((size_t)((uintptr_t)(a) & (alignment - 1))) + +/* Return the smallest alignment multiple that is >= s. */ +#define ALIGNMENT_CEILING(s, alignment) \ + (((s) + (alignment - 1)) & (-(alignment))) + +/* Declare a variable-length array. */ +#if __STDC_VERSION__ < 199901L +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# ifdef JEMALLOC_HAS_ALLOCA_H +# include +# else +# include +# endif +# endif +# define VARIABLE_ARRAY(type, name, count) \ + type *name = alloca(sizeof(type) * (count)) +#else +# define VARIABLE_ARRAY(type, name, count) type name[(count)] +#endif + +#include "jemalloc/internal/nstime.h" +#include "jemalloc/internal/valgrind.h" +#include "jemalloc/internal/util.h" +#include "jemalloc/internal/atomic.h" +#include "jemalloc/internal/prng.h" +#include "jemalloc/internal/ticker.h" +#include "jemalloc/internal/ckh.h" +#include "jemalloc/internal/size_classes.h" +#include "jemalloc/internal/smoothstep.h" +#include "jemalloc/internal/stats.h" +#include "jemalloc/internal/ctl.h" +#include "jemalloc/internal/witness.h" +#include "jemalloc/internal/mutex.h" +#include "jemalloc/internal/tsd.h" +#include "jemalloc/internal/mb.h" +#include "jemalloc/internal/extent.h" +#include "jemalloc/internal/arena.h" +#include "jemalloc/internal/bitmap.h" +#include "jemalloc/internal/base.h" +#include "jemalloc/internal/rtree.h" +#include "jemalloc/internal/pages.h" +#include "jemalloc/internal/chunk.h" +#include "jemalloc/internal/huge.h" +#include "jemalloc/internal/tcache.h" +#include "jemalloc/internal/hash.h" +#include "jemalloc/internal/quarantine.h" +#include "jemalloc/internal/prof.h" + +#undef JEMALLOC_H_TYPES +/******************************************************************************/ +#define JEMALLOC_H_STRUCTS + +#include "jemalloc/internal/nstime.h" +#include "jemalloc/internal/valgrind.h" +#include "jemalloc/internal/util.h" +#include "jemalloc/internal/atomic.h" +#include "jemalloc/internal/prng.h" +#include "jemalloc/internal/ticker.h" +#include "jemalloc/internal/ckh.h" +#include "jemalloc/internal/size_classes.h" +#include "jemalloc/internal/smoothstep.h" +#include "jemalloc/internal/stats.h" +#include "jemalloc/internal/ctl.h" +#include "jemalloc/internal/witness.h" +#include "jemalloc/internal/mutex.h" +#include "jemalloc/internal/mb.h" +#include "jemalloc/internal/bitmap.h" +#define JEMALLOC_ARENA_STRUCTS_A +#include "jemalloc/internal/arena.h" +#undef JEMALLOC_ARENA_STRUCTS_A +#include "jemalloc/internal/extent.h" +#define JEMALLOC_ARENA_STRUCTS_B +#include "jemalloc/internal/arena.h" +#undef JEMALLOC_ARENA_STRUCTS_B +#include "jemalloc/internal/base.h" +#include "jemalloc/internal/rtree.h" +#include "jemalloc/internal/pages.h" +#include "jemalloc/internal/chunk.h" +#include "jemalloc/internal/huge.h" +#include "jemalloc/internal/tcache.h" +#include "jemalloc/internal/hash.h" +#include "jemalloc/internal/quarantine.h" +#include "jemalloc/internal/prof.h" + +#include "jemalloc/internal/tsd.h" + +#undef JEMALLOC_H_STRUCTS +/******************************************************************************/ +#define JEMALLOC_H_EXTERNS + +extern bool opt_abort; +extern const char *opt_junk; +extern bool opt_junk_alloc; +extern bool opt_junk_free; +extern size_t opt_quarantine; +extern bool opt_redzone; +extern bool opt_utrace; +extern bool opt_xmalloc; +extern bool opt_zero; +extern unsigned opt_narenas; + +extern bool in_valgrind; + +/* Number of CPUs. */ +extern unsigned ncpus; + +/* Number of arenas used for automatic multiplexing of threads and arenas. */ +extern unsigned narenas_auto; + +/* + * Arenas that are used to service external requests. Not all elements of the + * arenas array are necessarily used; arenas are created lazily as needed. + */ +extern arena_t **arenas; + +/* + * index2size_tab encodes the same information as could be computed (at + * unacceptable cost in some code paths) by index2size_compute(). + */ +extern size_t const index2size_tab[NSIZES+1]; +/* + * size2index_tab is a compact lookup table that rounds request sizes up to + * size classes. In order to reduce cache footprint, the table is compressed, + * and all accesses are via size2index(). + */ +extern uint8_t const size2index_tab[]; + +void *a0malloc(size_t size); +void a0dalloc(void *ptr); +void *bootstrap_malloc(size_t size); +void *bootstrap_calloc(size_t num, size_t size); +void bootstrap_free(void *ptr); +unsigned narenas_total_get(void); +arena_t *arena_init(tsdn_t *tsdn, unsigned ind); +arena_tdata_t *arena_tdata_get_hard(tsd_t *tsd, unsigned ind); +arena_t *arena_choose_hard(tsd_t *tsd, bool internal); +void arena_migrate(tsd_t *tsd, unsigned oldind, unsigned newind); +void thread_allocated_cleanup(tsd_t *tsd); +void thread_deallocated_cleanup(tsd_t *tsd); +void iarena_cleanup(tsd_t *tsd); +void arena_cleanup(tsd_t *tsd); +void arenas_tdata_cleanup(tsd_t *tsd); +void narenas_tdata_cleanup(tsd_t *tsd); +void arenas_tdata_bypass_cleanup(tsd_t *tsd); +void jemalloc_prefork(void); +void jemalloc_postfork_parent(void); +void jemalloc_postfork_child(void); + +#include "jemalloc/internal/nstime.h" +#include "jemalloc/internal/valgrind.h" +#include "jemalloc/internal/util.h" +#include "jemalloc/internal/atomic.h" +#include "jemalloc/internal/prng.h" +#include "jemalloc/internal/ticker.h" +#include "jemalloc/internal/ckh.h" +#include "jemalloc/internal/size_classes.h" +#include "jemalloc/internal/smoothstep.h" +#include "jemalloc/internal/stats.h" +#include "jemalloc/internal/ctl.h" +#include "jemalloc/internal/witness.h" +#include "jemalloc/internal/mutex.h" +#include "jemalloc/internal/mb.h" +#include "jemalloc/internal/bitmap.h" +#include "jemalloc/internal/extent.h" +#include "jemalloc/internal/arena.h" +#include "jemalloc/internal/base.h" +#include "jemalloc/internal/rtree.h" +#include "jemalloc/internal/pages.h" +#include "jemalloc/internal/chunk.h" +#include "jemalloc/internal/huge.h" +#include "jemalloc/internal/tcache.h" +#include "jemalloc/internal/hash.h" +#include "jemalloc/internal/quarantine.h" +#include "jemalloc/internal/prof.h" +#include "jemalloc/internal/tsd.h" + +#undef JEMALLOC_H_EXTERNS +/******************************************************************************/ +#define JEMALLOC_H_INLINES + +#include "jemalloc/internal/nstime.h" +#include "jemalloc/internal/valgrind.h" +#include "jemalloc/internal/util.h" +#include "jemalloc/internal/atomic.h" +#include "jemalloc/internal/prng.h" +#include "jemalloc/internal/ticker.h" +#include "jemalloc/internal/ckh.h" +#include "jemalloc/internal/size_classes.h" +#include "jemalloc/internal/smoothstep.h" +#include "jemalloc/internal/stats.h" +#include "jemalloc/internal/ctl.h" +#include "jemalloc/internal/tsd.h" +#include "jemalloc/internal/witness.h" +#include "jemalloc/internal/mutex.h" +#include "jemalloc/internal/mb.h" +#include "jemalloc/internal/extent.h" +#include "jemalloc/internal/base.h" +#include "jemalloc/internal/rtree.h" +#include "jemalloc/internal/pages.h" +#include "jemalloc/internal/chunk.h" +#include "jemalloc/internal/huge.h" + +#ifndef JEMALLOC_ENABLE_INLINE +szind_t size2index_compute(size_t size); +szind_t size2index_lookup(size_t size); +szind_t size2index(size_t size); +size_t index2size_compute(szind_t index); +size_t index2size_lookup(szind_t index); +size_t index2size(szind_t index); +size_t s2u_compute(size_t size); +size_t s2u_lookup(size_t size); +size_t s2u(size_t size); +size_t sa2u(size_t size, size_t alignment); +arena_t *arena_choose_impl(tsd_t *tsd, arena_t *arena, bool internal); +arena_t *arena_choose(tsd_t *tsd, arena_t *arena); +arena_t *arena_ichoose(tsdn_t *tsdn, arena_t *arena); +arena_tdata_t *arena_tdata_get(tsd_t *tsd, unsigned ind, + bool refresh_if_missing); +arena_t *arena_get(tsdn_t *tsdn, unsigned ind, bool init_if_missing); +ticker_t *decay_ticker_get(tsd_t *tsd, unsigned ind); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_C_)) +JEMALLOC_INLINE szind_t +size2index_compute(size_t size) +{ + +#if (NTBINS != 0) + if (size <= (ZU(1) << LG_TINY_MAXCLASS)) { + szind_t lg_tmin = LG_TINY_MAXCLASS - NTBINS + 1; + szind_t lg_ceil = lg_floor(pow2_ceil_zu(size)); + return (lg_ceil < lg_tmin ? 0 : lg_ceil - lg_tmin); + } +#endif + { + szind_t x = unlikely(ZI(size) < 0) ? ((size<<1) ? + (ZU(1)<<(LG_SIZEOF_PTR+3)) : ((ZU(1)<<(LG_SIZEOF_PTR+3))-1)) + : lg_floor((size<<1)-1); + szind_t shift = (x < LG_SIZE_CLASS_GROUP + LG_QUANTUM) ? 0 : + x - (LG_SIZE_CLASS_GROUP + LG_QUANTUM); + szind_t grp = shift << LG_SIZE_CLASS_GROUP; + + szind_t lg_delta = (x < LG_SIZE_CLASS_GROUP + LG_QUANTUM + 1) + ? LG_QUANTUM : x - LG_SIZE_CLASS_GROUP - 1; + + size_t delta_inverse_mask = ZI(-1) << lg_delta; + szind_t mod = ((((size-1) & delta_inverse_mask) >> lg_delta)) & + ((ZU(1) << LG_SIZE_CLASS_GROUP) - 1); + + szind_t index = NTBINS + grp + mod; + return (index); + } +} + +JEMALLOC_ALWAYS_INLINE szind_t +size2index_lookup(size_t size) +{ + + assert(size <= LOOKUP_MAXCLASS); + { + szind_t ret = (size2index_tab[(size-1) >> LG_TINY_MIN]); + assert(ret == size2index_compute(size)); + return (ret); + } +} + +JEMALLOC_ALWAYS_INLINE szind_t +size2index(size_t size) +{ + + assert(size > 0); + if (likely(size <= LOOKUP_MAXCLASS)) + return (size2index_lookup(size)); + return (size2index_compute(size)); +} + +JEMALLOC_INLINE size_t +index2size_compute(szind_t index) +{ + +#if (NTBINS > 0) + if (index < NTBINS) + return (ZU(1) << (LG_TINY_MAXCLASS - NTBINS + 1 + index)); +#endif + { + size_t reduced_index = index - NTBINS; + size_t grp = reduced_index >> LG_SIZE_CLASS_GROUP; + size_t mod = reduced_index & ((ZU(1) << LG_SIZE_CLASS_GROUP) - + 1); + + size_t grp_size_mask = ~((!!grp)-1); + size_t grp_size = ((ZU(1) << (LG_QUANTUM + + (LG_SIZE_CLASS_GROUP-1))) << grp) & grp_size_mask; + + size_t shift = (grp == 0) ? 1 : grp; + size_t lg_delta = shift + (LG_QUANTUM-1); + size_t mod_size = (mod+1) << lg_delta; + + size_t usize = grp_size + mod_size; + return (usize); + } +} + +JEMALLOC_ALWAYS_INLINE size_t +index2size_lookup(szind_t index) +{ + size_t ret = (size_t)index2size_tab[index]; + assert(ret == index2size_compute(index)); + return (ret); +} + +JEMALLOC_ALWAYS_INLINE size_t +index2size(szind_t index) +{ + + assert(index < NSIZES); + return (index2size_lookup(index)); +} + +JEMALLOC_ALWAYS_INLINE size_t +s2u_compute(size_t size) +{ + +#if (NTBINS > 0) + if (size <= (ZU(1) << LG_TINY_MAXCLASS)) { + size_t lg_tmin = LG_TINY_MAXCLASS - NTBINS + 1; + size_t lg_ceil = lg_floor(pow2_ceil_zu(size)); + return (lg_ceil < lg_tmin ? (ZU(1) << lg_tmin) : + (ZU(1) << lg_ceil)); + } +#endif + { + size_t x = unlikely(ZI(size) < 0) ? ((size<<1) ? + (ZU(1)<<(LG_SIZEOF_PTR+3)) : ((ZU(1)<<(LG_SIZEOF_PTR+3))-1)) + : lg_floor((size<<1)-1); + size_t lg_delta = (x < LG_SIZE_CLASS_GROUP + LG_QUANTUM + 1) + ? LG_QUANTUM : x - LG_SIZE_CLASS_GROUP - 1; + size_t delta = ZU(1) << lg_delta; + size_t delta_mask = delta - 1; + size_t usize = (size + delta_mask) & ~delta_mask; + return (usize); + } +} + +JEMALLOC_ALWAYS_INLINE size_t +s2u_lookup(size_t size) +{ + size_t ret = index2size_lookup(size2index_lookup(size)); + + assert(ret == s2u_compute(size)); + return (ret); +} + +/* + * Compute usable size that would result from allocating an object with the + * specified size. + */ +JEMALLOC_ALWAYS_INLINE size_t +s2u(size_t size) +{ + + assert(size > 0); + if (likely(size <= LOOKUP_MAXCLASS)) + return (s2u_lookup(size)); + return (s2u_compute(size)); +} + +/* + * Compute usable size that would result from allocating an object with the + * specified size and alignment. + */ +JEMALLOC_ALWAYS_INLINE size_t +sa2u(size_t size, size_t alignment) +{ + size_t usize; + + assert(alignment != 0 && ((alignment - 1) & alignment) == 0); + + /* Try for a small size class. */ + if (size <= SMALL_MAXCLASS && alignment < PAGE) { + /* + * Round size up to the nearest multiple of alignment. + * + * This done, we can take advantage of the fact that for each + * small size class, every object is aligned at the smallest + * power of two that is non-zero in the base two representation + * of the size. For example: + * + * Size | Base 2 | Minimum alignment + * -----+----------+------------------ + * 96 | 1100000 | 32 + * 144 | 10100000 | 32 + * 192 | 11000000 | 64 + */ + usize = s2u(ALIGNMENT_CEILING(size, alignment)); + if (usize < LARGE_MINCLASS) + return (usize); + } + + /* Try for a large size class. */ + if (likely(size <= large_maxclass) && likely(alignment < chunksize)) { + /* + * We can't achieve subpage alignment, so round up alignment + * to the minimum that can actually be supported. + */ + alignment = PAGE_CEILING(alignment); + + /* Make sure result is a large size class. */ + usize = (size <= LARGE_MINCLASS) ? LARGE_MINCLASS : s2u(size); + + /* + * Calculate the size of the over-size run that arena_palloc() + * would need to allocate in order to guarantee the alignment. + */ + if (usize + large_pad + alignment - PAGE <= arena_maxrun) + return (usize); + } + + /* Huge size class. Beware of overflow. */ + + if (unlikely(alignment > HUGE_MAXCLASS)) + return (0); + + /* + * We can't achieve subchunk alignment, so round up alignment to the + * minimum that can actually be supported. + */ + alignment = CHUNK_CEILING(alignment); + + /* Make sure result is a huge size class. */ + if (size <= chunksize) + usize = chunksize; + else { + usize = s2u(size); + if (usize < size) { + /* size_t overflow. */ + return (0); + } + } + + /* + * Calculate the multi-chunk mapping that huge_palloc() would need in + * order to guarantee the alignment. + */ + if (usize + alignment - PAGE < usize) { + /* size_t overflow. */ + return (0); + } + return (usize); +} + +/* Choose an arena based on a per-thread value. */ +JEMALLOC_INLINE arena_t * +arena_choose_impl(tsd_t *tsd, arena_t *arena, bool internal) +{ + arena_t *ret; + + if (arena != NULL) + return (arena); + + ret = internal ? tsd_iarena_get(tsd) : tsd_arena_get(tsd); + if (unlikely(ret == NULL)) + ret = arena_choose_hard(tsd, internal); + + return (ret); +} + +JEMALLOC_INLINE arena_t * +arena_choose(tsd_t *tsd, arena_t *arena) +{ + + return (arena_choose_impl(tsd, arena, false)); +} + +JEMALLOC_INLINE arena_t * +arena_ichoose(tsdn_t *tsdn, arena_t *arena) +{ + + assert(!tsdn_null(tsdn) || arena != NULL); + + if (!tsdn_null(tsdn)) + return (arena_choose_impl(tsdn_tsd(tsdn), NULL, true)); + return (arena); +} + +JEMALLOC_INLINE arena_tdata_t * +arena_tdata_get(tsd_t *tsd, unsigned ind, bool refresh_if_missing) +{ + arena_tdata_t *tdata; + arena_tdata_t *arenas_tdata = tsd_arenas_tdata_get(tsd); + + if (unlikely(arenas_tdata == NULL)) { + /* arenas_tdata hasn't been initialized yet. */ + return (arena_tdata_get_hard(tsd, ind)); + } + if (unlikely(ind >= tsd_narenas_tdata_get(tsd))) { + /* + * ind is invalid, cache is old (too small), or tdata to be + * initialized. + */ + return (refresh_if_missing ? arena_tdata_get_hard(tsd, ind) : + NULL); + } + + tdata = &arenas_tdata[ind]; + if (likely(tdata != NULL) || !refresh_if_missing) + return (tdata); + return (arena_tdata_get_hard(tsd, ind)); +} + +JEMALLOC_INLINE arena_t * +arena_get(tsdn_t *tsdn, unsigned ind, bool init_if_missing) +{ + arena_t *ret; + + assert(ind <= MALLOCX_ARENA_MAX); + + ret = arenas[ind]; + if (unlikely(ret == NULL)) { + ret = atomic_read_p((void *)&arenas[ind]); + if (init_if_missing && unlikely(ret == NULL)) + ret = arena_init(tsdn, ind); + } + return (ret); +} + +JEMALLOC_INLINE ticker_t * +decay_ticker_get(tsd_t *tsd, unsigned ind) +{ + arena_tdata_t *tdata; + + tdata = arena_tdata_get(tsd, ind, true); + if (unlikely(tdata == NULL)) + return (NULL); + return (&tdata->decay_ticker); +} +#endif + +#include "jemalloc/internal/bitmap.h" +/* + * Include portions of arena.h interleaved with tcache.h in order to resolve + * circular dependencies. + */ +#define JEMALLOC_ARENA_INLINE_A +#include "jemalloc/internal/arena.h" +#undef JEMALLOC_ARENA_INLINE_A +#include "jemalloc/internal/tcache.h" +#define JEMALLOC_ARENA_INLINE_B +#include "jemalloc/internal/arena.h" +#undef JEMALLOC_ARENA_INLINE_B +#include "jemalloc/internal/hash.h" +#include "jemalloc/internal/quarantine.h" + +#ifndef JEMALLOC_ENABLE_INLINE +arena_t *iaalloc(const void *ptr); +size_t isalloc(tsdn_t *tsdn, const void *ptr, bool demote); +void *iallocztm(tsdn_t *tsdn, size_t size, szind_t ind, bool zero, + tcache_t *tcache, bool is_metadata, arena_t *arena, bool slow_path); +void *ialloc(tsd_t *tsd, size_t size, szind_t ind, bool zero, + bool slow_path); +void *ipallocztm(tsdn_t *tsdn, size_t usize, size_t alignment, bool zero, + tcache_t *tcache, bool is_metadata, arena_t *arena); +void *ipalloct(tsdn_t *tsdn, size_t usize, size_t alignment, bool zero, + tcache_t *tcache, arena_t *arena); +void *ipalloc(tsd_t *tsd, size_t usize, size_t alignment, bool zero); +size_t ivsalloc(tsdn_t *tsdn, const void *ptr, bool demote); +size_t u2rz(size_t usize); +size_t p2rz(tsdn_t *tsdn, const void *ptr); +void idalloctm(tsdn_t *tsdn, void *ptr, tcache_t *tcache, bool is_metadata, + bool slow_path); +void idalloc(tsd_t *tsd, void *ptr); +void iqalloc(tsd_t *tsd, void *ptr, tcache_t *tcache, bool slow_path); +void isdalloct(tsdn_t *tsdn, void *ptr, size_t size, tcache_t *tcache, + bool slow_path); +void isqalloc(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache, + bool slow_path); +void *iralloct_realign(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, + size_t extra, size_t alignment, bool zero, tcache_t *tcache, + arena_t *arena); +void *iralloct(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, + size_t alignment, bool zero, tcache_t *tcache, arena_t *arena); +void *iralloc(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, + size_t alignment, bool zero); +bool ixalloc(tsdn_t *tsdn, void *ptr, size_t oldsize, size_t size, + size_t extra, size_t alignment, bool zero); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_C_)) +JEMALLOC_ALWAYS_INLINE arena_t * +iaalloc(const void *ptr) +{ + + assert(ptr != NULL); + + return (arena_aalloc(ptr)); +} + +/* + * Typical usage: + * tsdn_t *tsdn = [...] + * void *ptr = [...] + * size_t sz = isalloc(tsdn, ptr, config_prof); + */ +JEMALLOC_ALWAYS_INLINE size_t +isalloc(tsdn_t *tsdn, const void *ptr, bool demote) +{ + + assert(ptr != NULL); + /* Demotion only makes sense if config_prof is true. */ + assert(config_prof || !demote); + + return (arena_salloc(tsdn, ptr, demote)); +} + +JEMALLOC_ALWAYS_INLINE void * +iallocztm(tsdn_t *tsdn, size_t size, szind_t ind, bool zero, tcache_t *tcache, + bool is_metadata, arena_t *arena, bool slow_path) +{ + void *ret; + + assert(size != 0); + assert(!is_metadata || tcache == NULL); + assert(!is_metadata || arena == NULL || arena->ind < narenas_auto); + + ret = arena_malloc(tsdn, arena, size, ind, zero, tcache, slow_path); + if (config_stats && is_metadata && likely(ret != NULL)) { + arena_metadata_allocated_add(iaalloc(ret), + isalloc(tsdn, ret, config_prof)); + } + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void * +ialloc(tsd_t *tsd, size_t size, szind_t ind, bool zero, bool slow_path) +{ + + return (iallocztm(tsd_tsdn(tsd), size, ind, zero, tcache_get(tsd, true), + false, NULL, slow_path)); +} + +JEMALLOC_ALWAYS_INLINE void * +ipallocztm(tsdn_t *tsdn, size_t usize, size_t alignment, bool zero, + tcache_t *tcache, bool is_metadata, arena_t *arena) +{ + void *ret; + + assert(usize != 0); + assert(usize == sa2u(usize, alignment)); + assert(!is_metadata || tcache == NULL); + assert(!is_metadata || arena == NULL || arena->ind < narenas_auto); + + ret = arena_palloc(tsdn, arena, usize, alignment, zero, tcache); + assert(ALIGNMENT_ADDR2BASE(ret, alignment) == ret); + if (config_stats && is_metadata && likely(ret != NULL)) { + arena_metadata_allocated_add(iaalloc(ret), isalloc(tsdn, ret, + config_prof)); + } + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void * +ipalloct(tsdn_t *tsdn, size_t usize, size_t alignment, bool zero, + tcache_t *tcache, arena_t *arena) +{ + + return (ipallocztm(tsdn, usize, alignment, zero, tcache, false, arena)); +} + +JEMALLOC_ALWAYS_INLINE void * +ipalloc(tsd_t *tsd, size_t usize, size_t alignment, bool zero) +{ + + return (ipallocztm(tsd_tsdn(tsd), usize, alignment, zero, + tcache_get(tsd, true), false, NULL)); +} + +JEMALLOC_ALWAYS_INLINE size_t +ivsalloc(tsdn_t *tsdn, const void *ptr, bool demote) +{ + extent_node_t *node; + + /* Return 0 if ptr is not within a chunk managed by jemalloc. */ + node = chunk_lookup(ptr, false); + if (node == NULL) + return (0); + /* Only arena chunks should be looked up via interior pointers. */ + assert(extent_node_addr_get(node) == ptr || + extent_node_achunk_get(node)); + + return (isalloc(tsdn, ptr, demote)); +} + +JEMALLOC_INLINE size_t +u2rz(size_t usize) +{ + size_t ret; + + if (usize <= SMALL_MAXCLASS) { + szind_t binind = size2index(usize); + ret = arena_bin_info[binind].redzone_size; + } else + ret = 0; + + return (ret); +} + +JEMALLOC_INLINE size_t +p2rz(tsdn_t *tsdn, const void *ptr) +{ + size_t usize = isalloc(tsdn, ptr, false); + + return (u2rz(usize)); +} + +JEMALLOC_ALWAYS_INLINE void +idalloctm(tsdn_t *tsdn, void *ptr, tcache_t *tcache, bool is_metadata, + bool slow_path) +{ + + assert(ptr != NULL); + assert(!is_metadata || tcache == NULL); + assert(!is_metadata || iaalloc(ptr)->ind < narenas_auto); + if (config_stats && is_metadata) { + arena_metadata_allocated_sub(iaalloc(ptr), isalloc(tsdn, ptr, + config_prof)); + } + + arena_dalloc(tsdn, ptr, tcache, slow_path); +} + +JEMALLOC_ALWAYS_INLINE void +idalloc(tsd_t *tsd, void *ptr) +{ + + idalloctm(tsd_tsdn(tsd), ptr, tcache_get(tsd, false), false, true); +} + +JEMALLOC_ALWAYS_INLINE void +iqalloc(tsd_t *tsd, void *ptr, tcache_t *tcache, bool slow_path) +{ + + if (slow_path && config_fill && unlikely(opt_quarantine)) + quarantine(tsd, ptr); + else + idalloctm(tsd_tsdn(tsd), ptr, tcache, false, slow_path); +} + +JEMALLOC_ALWAYS_INLINE void +isdalloct(tsdn_t *tsdn, void *ptr, size_t size, tcache_t *tcache, + bool slow_path) +{ + + arena_sdalloc(tsdn, ptr, size, tcache, slow_path); +} + +JEMALLOC_ALWAYS_INLINE void +isqalloc(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache, bool slow_path) +{ + + if (slow_path && config_fill && unlikely(opt_quarantine)) + quarantine(tsd, ptr); + else + isdalloct(tsd_tsdn(tsd), ptr, size, tcache, slow_path); +} + +JEMALLOC_ALWAYS_INLINE void * +iralloct_realign(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, + size_t extra, size_t alignment, bool zero, tcache_t *tcache, arena_t *arena) +{ + void *p; + size_t usize, copysize; + + usize = sa2u(size + extra, alignment); + if (unlikely(usize == 0 || usize > HUGE_MAXCLASS)) + return (NULL); + p = ipalloct(tsd_tsdn(tsd), usize, alignment, zero, tcache, arena); + if (p == NULL) { + if (extra == 0) + return (NULL); + /* Try again, without extra this time. */ + usize = sa2u(size, alignment); + if (unlikely(usize == 0 || usize > HUGE_MAXCLASS)) + return (NULL); + p = ipalloct(tsd_tsdn(tsd), usize, alignment, zero, tcache, + arena); + if (p == NULL) + return (NULL); + } + /* + * Copy at most size bytes (not size+extra), since the caller has no + * expectation that the extra bytes will be reliably preserved. + */ + copysize = (size < oldsize) ? size : oldsize; + memcpy(p, ptr, copysize); + isqalloc(tsd, ptr, oldsize, tcache, true); + return (p); +} + +JEMALLOC_ALWAYS_INLINE void * +iralloct(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, size_t alignment, + bool zero, tcache_t *tcache, arena_t *arena) +{ + + assert(ptr != NULL); + assert(size != 0); + + if (alignment != 0 && ((uintptr_t)ptr & ((uintptr_t)alignment-1)) + != 0) { + /* + * Existing object alignment is inadequate; allocate new space + * and copy. + */ + return (iralloct_realign(tsd, ptr, oldsize, size, 0, alignment, + zero, tcache, arena)); + } + + return (arena_ralloc(tsd, arena, ptr, oldsize, size, alignment, zero, + tcache)); +} + +JEMALLOC_ALWAYS_INLINE void * +iralloc(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, size_t alignment, + bool zero) +{ + + return (iralloct(tsd, ptr, oldsize, size, alignment, zero, + tcache_get(tsd, true), NULL)); +} + +JEMALLOC_ALWAYS_INLINE bool +ixalloc(tsdn_t *tsdn, void *ptr, size_t oldsize, size_t size, size_t extra, + size_t alignment, bool zero) +{ + + assert(ptr != NULL); + assert(size != 0); + + if (alignment != 0 && ((uintptr_t)ptr & ((uintptr_t)alignment-1)) + != 0) { + /* Existing object alignment is inadequate. */ + return (true); + } + + return (arena_ralloc_no_move(tsdn, ptr, oldsize, size, extra, zero)); +} +#endif + +#include "jemalloc/internal/prof.h" + +#undef JEMALLOC_H_INLINES +/******************************************************************************/ +#endif /* JEMALLOC_INTERNAL_H */ diff --git a/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h new file mode 100644 index 0000000..42d97f2 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h @@ -0,0 +1,68 @@ +#ifndef JEMALLOC_INTERNAL_DECLS_H +#define JEMALLOC_INTERNAL_DECLS_H + +#include "libc_private.h" +#include "namespace.h" + +#include +#ifdef _WIN32 +# include +# include "msvc_compat/windows_extra.h" + +#else +# include +# include +# if !defined(__pnacl__) && !defined(__native_client__) +# include +# if !defined(SYS_write) && defined(__NR_write) +# define SYS_write __NR_write +# endif +# include +# endif +# include +# include +# include +#endif +#include + +#include +#ifndef SIZE_T_MAX +# define SIZE_T_MAX SIZE_MAX +#endif +#include +#include +#include +#include +#include +#include +#ifndef offsetof +# define offsetof(type, member) ((size_t)&(((type *)NULL)->member)) +#endif +#include +#include +#include +#ifdef _MSC_VER +# include +typedef intptr_t ssize_t; +# define PATH_MAX 1024 +# define STDERR_FILENO 2 +# define __func__ __FUNCTION__ +# ifdef JEMALLOC_HAS_RESTRICT +# define restrict __restrict +# endif +/* Disable warnings about deprecated system functions. */ +# pragma warning(disable: 4996) +#if _MSC_VER < 1800 +static int +isblank(int c) +{ + + return (c == '\t' || c == ' '); +} +#endif +#else +# include +#endif +#include + +#endif /* JEMALLOC_INTERNAL_H */ diff --git a/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h new file mode 100644 index 0000000..32f6f15 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h @@ -0,0 +1,279 @@ +/* include/jemalloc/internal/jemalloc_internal_defs.h. Generated from jemalloc_internal_defs.h.in by configure. */ +#ifndef JEMALLOC_INTERNAL_DEFS_H_ +#define JEMALLOC_INTERNAL_DEFS_H_ +/* + * If JEMALLOC_PREFIX is defined via --with-jemalloc-prefix, it will cause all + * public APIs to be prefixed. This makes it possible, with some care, to use + * multiple allocators simultaneously. + */ +/* #undef JEMALLOC_PREFIX */ +/* #undef JEMALLOC_CPREFIX */ + +/* + * JEMALLOC_PRIVATE_NAMESPACE is used as a prefix for all library-private APIs. + * For shared libraries, symbol visibility mechanisms prevent these symbols + * from being exported, but for static libraries, naming collisions are a real + * possibility. + */ +#define JEMALLOC_PRIVATE_NAMESPACE __je_ + +/* + * Hyper-threaded CPUs may need a special instruction inside spin loops in + * order to yield to another virtual CPU. + */ +#define CPU_SPINWAIT __asm__ volatile("pause") + +/* Defined if C11 atomics are available. */ +/* #undef JEMALLOC_C11ATOMICS */ + +/* Defined if the equivalent of FreeBSD's atomic(9) functions are available. */ +#define JEMALLOC_ATOMIC9 1 + +/* + * Defined if OSAtomic*() functions are available, as provided by Darwin, and + * documented in the atomic(3) manual page. + */ +/* #undef JEMALLOC_OSATOMIC */ + +/* + * Defined if __sync_add_and_fetch(uint32_t *, uint32_t) and + * __sync_sub_and_fetch(uint32_t *, uint32_t) are available, despite + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 not being defined (which means the + * functions are defined in libgcc instead of being inlines). + */ +/* #undef JE_FORCE_SYNC_COMPARE_AND_SWAP_4 */ + +/* + * Defined if __sync_add_and_fetch(uint64_t *, uint64_t) and + * __sync_sub_and_fetch(uint64_t *, uint64_t) are available, despite + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 not being defined (which means the + * functions are defined in libgcc instead of being inlines). + */ +/* #undef JE_FORCE_SYNC_COMPARE_AND_SWAP_8 */ + +/* + * Defined if __builtin_clz() and __builtin_clzl() are available. + */ +#define JEMALLOC_HAVE_BUILTIN_CLZ + +/* + * Defined if madvise(2) is available. + */ +#define JEMALLOC_HAVE_MADVISE + +/* + * Defined if OSSpin*() functions are available, as provided by Darwin, and + * documented in the spinlock(3) manual page. + */ +/* #undef JEMALLOC_OSSPIN */ + +/* + * Defined if secure_getenv(3) is available. + */ +/* #undef JEMALLOC_HAVE_SECURE_GETENV */ + +/* + * Defined if issetugid(2) is available. + */ +#define JEMALLOC_HAVE_ISSETUGID + +/* + * Defined if _malloc_thread_cleanup() exists. At least in the case of + * FreeBSD, pthread_key_create() allocates, which if used during malloc + * bootstrapping will cause recursion into the pthreads library. Therefore, if + * _malloc_thread_cleanup() exists, use it as the basis for thread cleanup in + * malloc_tsd. + */ +#define JEMALLOC_MALLOC_THREAD_CLEANUP + +/* + * Defined if threaded initialization is known to be safe on this platform. + * Among other things, it must be possible to initialize a mutex without + * triggering allocation in order for threaded allocation to be safe. + */ +/* #undef JEMALLOC_THREADED_INIT */ + +/* + * Defined if the pthreads implementation defines + * _pthread_mutex_init_calloc_cb(), in which case the function is used in order + * to avoid recursive allocation during mutex initialization. + */ +#define JEMALLOC_MUTEX_INIT_CB 1 + +/* Non-empty if the tls_model attribute is supported. */ +#define JEMALLOC_TLS_MODEL __attribute__((tls_model("initial-exec"))) + +/* JEMALLOC_CC_SILENCE enables code that silences unuseful compiler warnings. */ +#define JEMALLOC_CC_SILENCE + +/* JEMALLOC_CODE_COVERAGE enables test code coverage analysis. */ +/* #undef JEMALLOC_CODE_COVERAGE */ + +/* + * JEMALLOC_DEBUG enables assertions and other sanity checks, and disables + * inline functions. + */ +/* #undef JEMALLOC_DEBUG */ + +/* JEMALLOC_STATS enables statistics calculation. */ +#define JEMALLOC_STATS + +/* JEMALLOC_PROF enables allocation profiling. */ +/* #undef JEMALLOC_PROF */ + +/* Use libunwind for profile backtracing if defined. */ +/* #undef JEMALLOC_PROF_LIBUNWIND */ + +/* Use libgcc for profile backtracing if defined. */ +/* #undef JEMALLOC_PROF_LIBGCC */ + +/* Use gcc intrinsics for profile backtracing if defined. */ +/* #undef JEMALLOC_PROF_GCC */ + +/* + * JEMALLOC_TCACHE enables a thread-specific caching layer for small objects. + * This makes it possible to allocate/deallocate objects without any locking + * when the cache is in the steady state. + */ +#define JEMALLOC_TCACHE + +/* + * JEMALLOC_DSS enables use of sbrk(2) to allocate chunks from the data storage + * segment (DSS). + */ +#define JEMALLOC_DSS + +/* Support memory filling (junk/zero/quarantine/redzone). */ +#define JEMALLOC_FILL + +/* Support utrace(2)-based tracing. */ +#define JEMALLOC_UTRACE + +/* Support Valgrind. */ +/* #undef JEMALLOC_VALGRIND */ + +/* Support optional abort() on OOM. */ +#define JEMALLOC_XMALLOC + +/* Support lazy locking (avoid locking unless a second thread is launched). */ +#define JEMALLOC_LAZY_LOCK + +/* Minimum size class to support is 2^LG_TINY_MIN bytes. */ +#define LG_TINY_MIN 3 + +/* + * Minimum allocation alignment is 2^LG_QUANTUM bytes (ignoring tiny size + * classes). + */ +/* #undef LG_QUANTUM */ + +/* One page is 2^LG_PAGE bytes. */ +#define LG_PAGE 12 + +/* + * If defined, adjacent virtual memory mappings with identical attributes + * automatically coalesce, and they fragment when changes are made to subranges. + * This is the normal order of things for mmap()/munmap(), but on Windows + * VirtualAlloc()/VirtualFree() operations must be precisely matched, i.e. + * mappings do *not* coalesce/fragment. + */ +#define JEMALLOC_MAPS_COALESCE + +/* + * If defined, use munmap() to unmap freed chunks, rather than storing them for + * later reuse. This is disabled by default on Linux because common sequences + * of mmap()/munmap() calls will cause virtual memory map holes. + */ +#define JEMALLOC_MUNMAP + +/* TLS is used to map arenas and magazine caches to threads. */ +#define JEMALLOC_TLS + +/* + * ffs*() functions to use for bitmapping. Don't use these directly; instead, + * use ffs_*() from util.h. + */ +#define JEMALLOC_INTERNAL_FFSLL __builtin_ffsll +#define JEMALLOC_INTERNAL_FFSL __builtin_ffsl +#define JEMALLOC_INTERNAL_FFS __builtin_ffs + +/* + * JEMALLOC_IVSALLOC enables ivsalloc(), which verifies that pointers reside + * within jemalloc-owned chunks before dereferencing them. + */ +/* #undef JEMALLOC_IVSALLOC */ + +/* + * If defined, explicitly attempt to more uniformly distribute large allocation + * pointer alignments across all cache indices. + */ +#define JEMALLOC_CACHE_OBLIVIOUS + +/* + * Darwin (OS X) uses zones to work around Mach-O symbol override shortcomings. + */ +/* #undef JEMALLOC_ZONE */ +/* #undef JEMALLOC_ZONE_VERSION */ + +/* + * Methods for determining whether the OS overcommits. + * JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY: Linux's + * /proc/sys/vm.overcommit_memory file. + * JEMALLOC_SYSCTL_VM_OVERCOMMIT: FreeBSD's vm.overcommit sysctl. + */ +#define JEMALLOC_SYSCTL_VM_OVERCOMMIT +/* #undef JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY */ + +/* + * Methods for purging unused pages differ between operating systems. + * + * madvise(..., MADV_DONTNEED) : On Linux, this immediately discards pages, + * such that new pages will be demand-zeroed if + * the address region is later touched. + * madvise(..., MADV_FREE) : On FreeBSD and Darwin, this marks pages as being + * unused, such that they will be discarded rather + * than swapped out. + */ +/* #undef JEMALLOC_PURGE_MADVISE_DONTNEED */ +#define JEMALLOC_PURGE_MADVISE_FREE + +/* Define if operating system has alloca.h header. */ +/* #undef JEMALLOC_HAS_ALLOCA_H */ + +/* C99 restrict keyword supported. */ +#define JEMALLOC_HAS_RESTRICT 1 + +/* For use by hash code. */ +/* #undef JEMALLOC_BIG_ENDIAN */ + +/* sizeof(int) == 2^LG_SIZEOF_INT. */ +#define LG_SIZEOF_INT 2 + +/* sizeof(long) == 2^LG_SIZEOF_LONG. */ +#define LG_SIZEOF_LONG 3 + +/* sizeof(long long) == 2^LG_SIZEOF_LONG_LONG. */ +#define LG_SIZEOF_LONG_LONG 3 + +/* sizeof(intmax_t) == 2^LG_SIZEOF_INTMAX_T. */ +#define LG_SIZEOF_INTMAX_T 3 + +/* glibc malloc hooks (__malloc_hook, __realloc_hook, __free_hook). */ +/* #undef JEMALLOC_GLIBC_MALLOC_HOOK */ + +/* glibc memalign hook. */ +/* #undef JEMALLOC_GLIBC_MEMALIGN_HOOK */ + +/* Adaptive mutex support in pthreads. */ +#define JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP + +/* + * If defined, jemalloc symbols are not exported (doesn't work when + * JEMALLOC_PREFIX is not defined). + */ +/* #undef JEMALLOC_EXPORT */ + +/* config.malloc_conf options string. */ +#define JEMALLOC_CONFIG_MALLOC_CONF "" + +#endif /* JEMALLOC_INTERNAL_DEFS_H_ */ diff --git a/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_macros.h b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_macros.h new file mode 100644 index 0000000..a08ba77 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/jemalloc_internal_macros.h @@ -0,0 +1,57 @@ +/* + * JEMALLOC_ALWAYS_INLINE and JEMALLOC_INLINE are used within header files for + * functions that are static inline functions if inlining is enabled, and + * single-definition library-private functions if inlining is disabled. + * + * JEMALLOC_ALWAYS_INLINE_C and JEMALLOC_INLINE_C are for use in .c files, in + * which case the denoted functions are always static, regardless of whether + * inlining is enabled. + */ +#if defined(JEMALLOC_DEBUG) || defined(JEMALLOC_CODE_COVERAGE) + /* Disable inlining to make debugging/profiling easier. */ +# define JEMALLOC_ALWAYS_INLINE +# define JEMALLOC_ALWAYS_INLINE_C static +# define JEMALLOC_INLINE +# define JEMALLOC_INLINE_C static +# define inline +#else +# define JEMALLOC_ENABLE_INLINE +# ifdef JEMALLOC_HAVE_ATTR +# define JEMALLOC_ALWAYS_INLINE \ + static inline JEMALLOC_ATTR(unused) JEMALLOC_ATTR(always_inline) +# define JEMALLOC_ALWAYS_INLINE_C \ + static inline JEMALLOC_ATTR(always_inline) +# else +# define JEMALLOC_ALWAYS_INLINE static inline +# define JEMALLOC_ALWAYS_INLINE_C static inline +# endif +# define JEMALLOC_INLINE static inline +# define JEMALLOC_INLINE_C static inline +# ifdef _MSC_VER +# define inline _inline +# endif +#endif + +#ifdef JEMALLOC_CC_SILENCE +# define UNUSED JEMALLOC_ATTR(unused) +#else +# define UNUSED +#endif + +#define ZU(z) ((size_t)z) +#define ZI(z) ((ssize_t)z) +#define QU(q) ((uint64_t)q) +#define QI(q) ((int64_t)q) + +#define KZU(z) ZU(z##ULL) +#define KZI(z) ZI(z##LL) +#define KQU(q) QU(q##ULL) +#define KQI(q) QI(q##LL) + +#ifndef __DECONST +# define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) +#endif + +#ifndef JEMALLOC_HAS_RESTRICT +# define restrict +#endif diff --git a/contrib/jemalloc/include/jemalloc/internal/mb.h b/contrib/jemalloc/include/jemalloc/internal/mb.h new file mode 100644 index 0000000..437c86f --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/mb.h @@ -0,0 +1,115 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +void mb_write(void); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MB_C_)) +#ifdef __i386__ +/* + * According to the Intel Architecture Software Developer's Manual, current + * processors execute instructions in order from the perspective of other + * processors in a multiprocessor system, but 1) Intel reserves the right to + * change that, and 2) the compiler's optimizer could re-order instructions if + * there weren't some form of barrier. Therefore, even if running on an + * architecture that does not need memory barriers (everything through at least + * i686), an "optimizer barrier" is necessary. + */ +JEMALLOC_INLINE void +mb_write(void) +{ + +# if 0 + /* This is a true memory barrier. */ + asm volatile ("pusha;" + "xor %%eax,%%eax;" + "cpuid;" + "popa;" + : /* Outputs. */ + : /* Inputs. */ + : "memory" /* Clobbers. */ + ); +# else + /* + * This is hopefully enough to keep the compiler from reordering + * instructions around this one. + */ + asm volatile ("nop;" + : /* Outputs. */ + : /* Inputs. */ + : "memory" /* Clobbers. */ + ); +# endif +} +#elif (defined(__amd64__) || defined(__x86_64__)) +JEMALLOC_INLINE void +mb_write(void) +{ + + asm volatile ("sfence" + : /* Outputs. */ + : /* Inputs. */ + : "memory" /* Clobbers. */ + ); +} +#elif defined(__powerpc__) +JEMALLOC_INLINE void +mb_write(void) +{ + + asm volatile ("eieio" + : /* Outputs. */ + : /* Inputs. */ + : "memory" /* Clobbers. */ + ); +} +#elif defined(__sparc64__) +JEMALLOC_INLINE void +mb_write(void) +{ + + asm volatile ("membar #StoreStore" + : /* Outputs. */ + : /* Inputs. */ + : "memory" /* Clobbers. */ + ); +} +#elif defined(__tile__) +JEMALLOC_INLINE void +mb_write(void) +{ + + __sync_synchronize(); +} +#else +/* + * This is much slower than a simple memory barrier, but the semantics of mutex + * unlock make this work. + */ +JEMALLOC_INLINE void +mb_write(void) +{ + malloc_mutex_t mtx; + + malloc_mutex_init(&mtx, "mb", WITNESS_RANK_OMIT); + malloc_mutex_lock(NULL, &mtx); + malloc_mutex_unlock(NULL, &mtx); +} +#endif +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/mutex.h b/contrib/jemalloc/include/jemalloc/internal/mutex.h new file mode 100644 index 0000000..60ab041 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/mutex.h @@ -0,0 +1,136 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct malloc_mutex_s malloc_mutex_t; + +#ifdef _WIN32 +# define MALLOC_MUTEX_INITIALIZER +#elif (defined(JEMALLOC_OSSPIN)) +# define MALLOC_MUTEX_INITIALIZER {0, WITNESS_INITIALIZER(WITNESS_RANK_OMIT)} +#elif (defined(JEMALLOC_MUTEX_INIT_CB)) +# define MALLOC_MUTEX_INITIALIZER \ + {PTHREAD_MUTEX_INITIALIZER, NULL, WITNESS_INITIALIZER(WITNESS_RANK_OMIT)} +#else +# if (defined(JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP) && \ + defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP)) +# define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_ADAPTIVE_NP +# define MALLOC_MUTEX_INITIALIZER \ + {PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP, \ + WITNESS_INITIALIZER(WITNESS_RANK_OMIT)} +# else +# define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT +# define MALLOC_MUTEX_INITIALIZER \ + {PTHREAD_MUTEX_INITIALIZER, WITNESS_INITIALIZER(WITNESS_RANK_OMIT)} +# endif +#endif + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct malloc_mutex_s { +#ifdef _WIN32 +# if _WIN32_WINNT >= 0x0600 + SRWLOCK lock; +# else + CRITICAL_SECTION lock; +# endif +#elif (defined(JEMALLOC_OSSPIN)) + OSSpinLock lock; +#elif (defined(JEMALLOC_MUTEX_INIT_CB)) + pthread_mutex_t lock; + malloc_mutex_t *postponed_next; +#else + pthread_mutex_t lock; +#endif + witness_t witness; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#ifdef JEMALLOC_LAZY_LOCK +extern bool isthreaded; +#endif + +bool malloc_mutex_init(malloc_mutex_t *mutex, const char *name, + witness_rank_t rank); +void malloc_mutex_prefork(tsdn_t *tsdn, malloc_mutex_t *mutex); +void malloc_mutex_postfork_parent(tsdn_t *tsdn, malloc_mutex_t *mutex); +void malloc_mutex_postfork_child(tsdn_t *tsdn, malloc_mutex_t *mutex); +bool malloc_mutex_first_thread(void); +bool malloc_mutex_boot(void); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +void malloc_mutex_lock(tsdn_t *tsdn, malloc_mutex_t *mutex); +void malloc_mutex_unlock(tsdn_t *tsdn, malloc_mutex_t *mutex); +void malloc_mutex_assert_owner(tsdn_t *tsdn, malloc_mutex_t *mutex); +void malloc_mutex_assert_not_owner(tsdn_t *tsdn, malloc_mutex_t *mutex); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MUTEX_C_)) +JEMALLOC_INLINE void +malloc_mutex_lock(tsdn_t *tsdn, malloc_mutex_t *mutex) +{ + + if (isthreaded) { + witness_assert_not_owner(tsdn, &mutex->witness); +#ifdef _WIN32 +# if _WIN32_WINNT >= 0x0600 + AcquireSRWLockExclusive(&mutex->lock); +# else + EnterCriticalSection(&mutex->lock); +# endif +#elif (defined(JEMALLOC_OSSPIN)) + OSSpinLockLock(&mutex->lock); +#else + pthread_mutex_lock(&mutex->lock); +#endif + witness_lock(tsdn, &mutex->witness); + } +} + +JEMALLOC_INLINE void +malloc_mutex_unlock(tsdn_t *tsdn, malloc_mutex_t *mutex) +{ + + if (isthreaded) { + witness_unlock(tsdn, &mutex->witness); +#ifdef _WIN32 +# if _WIN32_WINNT >= 0x0600 + ReleaseSRWLockExclusive(&mutex->lock); +# else + LeaveCriticalSection(&mutex->lock); +# endif +#elif (defined(JEMALLOC_OSSPIN)) + OSSpinLockUnlock(&mutex->lock); +#else + pthread_mutex_unlock(&mutex->lock); +#endif + } +} + +JEMALLOC_INLINE void +malloc_mutex_assert_owner(tsdn_t *tsdn, malloc_mutex_t *mutex) +{ + + if (isthreaded) + witness_assert_owner(tsdn, &mutex->witness); +} + +JEMALLOC_INLINE void +malloc_mutex_assert_not_owner(tsdn_t *tsdn, malloc_mutex_t *mutex) +{ + + if (isthreaded) + witness_assert_not_owner(tsdn, &mutex->witness); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/nstime.h b/contrib/jemalloc/include/jemalloc/internal/nstime.h new file mode 100644 index 0000000..4d8ef7b --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/nstime.h @@ -0,0 +1,51 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#if defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 +#define JEMALLOC_CLOCK_GETTIME 1 +#else +#define JEMALLOC_CLOCK_GETTIME 0 +#endif + +typedef struct nstime_s nstime_t; + +/* Maximum supported number of seconds (~584 years). */ +#define NSTIME_SEC_MAX KQU(18446744072) + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct nstime_s { + uint64_t ns; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void nstime_init(nstime_t *time, uint64_t ns); +void nstime_init2(nstime_t *time, uint64_t sec, uint64_t nsec); +uint64_t nstime_ns(const nstime_t *time); +uint64_t nstime_sec(const nstime_t *time); +uint64_t nstime_nsec(const nstime_t *time); +void nstime_copy(nstime_t *time, const nstime_t *source); +int nstime_compare(const nstime_t *a, const nstime_t *b); +void nstime_add(nstime_t *time, const nstime_t *addend); +void nstime_subtract(nstime_t *time, const nstime_t *subtrahend); +void nstime_imultiply(nstime_t *time, uint64_t multiplier); +void nstime_idivide(nstime_t *time, uint64_t divisor); +uint64_t nstime_divide(const nstime_t *time, const nstime_t *divisor); +#ifdef JEMALLOC_JET +typedef bool (nstime_update_t)(nstime_t *); +extern nstime_update_t *nstime_update; +#else +bool nstime_update(nstime_t *time); +#endif + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/pages.h b/contrib/jemalloc/include/jemalloc/internal/pages.h new file mode 100644 index 0000000..e21effd --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/pages.h @@ -0,0 +1,27 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void *pages_map(void *addr, size_t size, bool *commit); +void pages_unmap(void *addr, size_t size); +void *pages_trim(void *addr, size_t alloc_size, size_t leadsize, + size_t size, bool *commit); +bool pages_commit(void *addr, size_t size); +bool pages_decommit(void *addr, size_t size); +bool pages_purge(void *addr, size_t size); +void pages_boot(void); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ + diff --git a/contrib/jemalloc/include/jemalloc/internal/ph.h b/contrib/jemalloc/include/jemalloc/internal/ph.h new file mode 100644 index 0000000..4f91c33 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/ph.h @@ -0,0 +1,345 @@ +/* + * A Pairing Heap implementation. + * + * "The Pairing Heap: A New Form of Self-Adjusting Heap" + * https://www.cs.cmu.edu/~sleator/papers/pairing-heaps.pdf + * + * With auxiliary twopass list, described in a follow on paper. + * + * "Pairing Heaps: Experiments and Analysis" + * http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.106.2988&rep=rep1&type=pdf + * + ******************************************************************************* + */ + +#ifndef PH_H_ +#define PH_H_ + +/* Node structure. */ +#define phn(a_type) \ +struct { \ + a_type *phn_prev; \ + a_type *phn_next; \ + a_type *phn_lchild; \ +} + +/* Root structure. */ +#define ph(a_type) \ +struct { \ + a_type *ph_root; \ +} + +/* Internal utility macros. */ +#define phn_lchild_get(a_type, a_field, a_phn) \ + (a_phn->a_field.phn_lchild) +#define phn_lchild_set(a_type, a_field, a_phn, a_lchild) do { \ + a_phn->a_field.phn_lchild = a_lchild; \ +} while (0) + +#define phn_next_get(a_type, a_field, a_phn) \ + (a_phn->a_field.phn_next) +#define phn_prev_set(a_type, a_field, a_phn, a_prev) do { \ + a_phn->a_field.phn_prev = a_prev; \ +} while (0) + +#define phn_prev_get(a_type, a_field, a_phn) \ + (a_phn->a_field.phn_prev) +#define phn_next_set(a_type, a_field, a_phn, a_next) do { \ + a_phn->a_field.phn_next = a_next; \ +} while (0) + +#define phn_merge_ordered(a_type, a_field, a_phn0, a_phn1, a_cmp) do { \ + a_type *phn0child; \ + \ + assert(a_phn0 != NULL); \ + assert(a_phn1 != NULL); \ + assert(a_cmp(a_phn0, a_phn1) <= 0); \ + \ + phn_prev_set(a_type, a_field, a_phn1, a_phn0); \ + phn0child = phn_lchild_get(a_type, a_field, a_phn0); \ + phn_next_set(a_type, a_field, a_phn1, phn0child); \ + if (phn0child != NULL) \ + phn_prev_set(a_type, a_field, phn0child, a_phn1); \ + phn_lchild_set(a_type, a_field, a_phn0, a_phn1); \ +} while (0) + +#define phn_merge(a_type, a_field, a_phn0, a_phn1, a_cmp, r_phn) do { \ + if (a_phn0 == NULL) \ + r_phn = a_phn1; \ + else if (a_phn1 == NULL) \ + r_phn = a_phn0; \ + else if (a_cmp(a_phn0, a_phn1) < 0) { \ + phn_merge_ordered(a_type, a_field, a_phn0, a_phn1, \ + a_cmp); \ + r_phn = a_phn0; \ + } else { \ + phn_merge_ordered(a_type, a_field, a_phn1, a_phn0, \ + a_cmp); \ + r_phn = a_phn1; \ + } \ +} while (0) + +#define ph_merge_siblings(a_type, a_field, a_phn, a_cmp, r_phn) do { \ + a_type *head = NULL; \ + a_type *tail = NULL; \ + a_type *phn0 = a_phn; \ + a_type *phn1 = phn_next_get(a_type, a_field, phn0); \ + \ + /* \ + * Multipass merge, wherein the first two elements of a FIFO \ + * are repeatedly merged, and each result is appended to the \ + * singly linked FIFO, until the FIFO contains only a single \ + * element. We start with a sibling list but no reference to \ + * its tail, so we do a single pass over the sibling list to \ + * populate the FIFO. \ + */ \ + if (phn1 != NULL) { \ + a_type *phnrest = phn_next_get(a_type, a_field, phn1); \ + if (phnrest != NULL) \ + phn_prev_set(a_type, a_field, phnrest, NULL); \ + phn_prev_set(a_type, a_field, phn0, NULL); \ + phn_next_set(a_type, a_field, phn0, NULL); \ + phn_prev_set(a_type, a_field, phn1, NULL); \ + phn_next_set(a_type, a_field, phn1, NULL); \ + phn_merge(a_type, a_field, phn0, phn1, a_cmp, phn0); \ + head = tail = phn0; \ + phn0 = phnrest; \ + while (phn0 != NULL) { \ + phn1 = phn_next_get(a_type, a_field, phn0); \ + if (phn1 != NULL) { \ + phnrest = phn_next_get(a_type, a_field, \ + phn1); \ + if (phnrest != NULL) { \ + phn_prev_set(a_type, a_field, \ + phnrest, NULL); \ + } \ + phn_prev_set(a_type, a_field, phn0, \ + NULL); \ + phn_next_set(a_type, a_field, phn0, \ + NULL); \ + phn_prev_set(a_type, a_field, phn1, \ + NULL); \ + phn_next_set(a_type, a_field, phn1, \ + NULL); \ + phn_merge(a_type, a_field, phn0, phn1, \ + a_cmp, phn0); \ + phn_next_set(a_type, a_field, tail, \ + phn0); \ + tail = phn0; \ + phn0 = phnrest; \ + } else { \ + phn_next_set(a_type, a_field, tail, \ + phn0); \ + tail = phn0; \ + phn0 = NULL; \ + } \ + } \ + phn0 = head; \ + phn1 = phn_next_get(a_type, a_field, phn0); \ + if (phn1 != NULL) { \ + while (true) { \ + head = phn_next_get(a_type, a_field, \ + phn1); \ + assert(phn_prev_get(a_type, a_field, \ + phn0) == NULL); \ + phn_next_set(a_type, a_field, phn0, \ + NULL); \ + assert(phn_prev_get(a_type, a_field, \ + phn1) == NULL); \ + phn_next_set(a_type, a_field, phn1, \ + NULL); \ + phn_merge(a_type, a_field, phn0, phn1, \ + a_cmp, phn0); \ + if (head == NULL) \ + break; \ + phn_next_set(a_type, a_field, tail, \ + phn0); \ + tail = phn0; \ + phn0 = head; \ + phn1 = phn_next_get(a_type, a_field, \ + phn0); \ + } \ + } \ + } \ + r_phn = phn0; \ +} while (0) + +#define ph_merge_aux(a_type, a_field, a_ph, a_cmp) do { \ + a_type *phn = phn_next_get(a_type, a_field, a_ph->ph_root); \ + if (phn != NULL) { \ + phn_prev_set(a_type, a_field, a_ph->ph_root, NULL); \ + phn_next_set(a_type, a_field, a_ph->ph_root, NULL); \ + phn_prev_set(a_type, a_field, phn, NULL); \ + ph_merge_siblings(a_type, a_field, phn, a_cmp, phn); \ + assert(phn_next_get(a_type, a_field, phn) == NULL); \ + phn_merge(a_type, a_field, a_ph->ph_root, phn, a_cmp, \ + a_ph->ph_root); \ + } \ +} while (0) + +#define ph_merge_children(a_type, a_field, a_phn, a_cmp, r_phn) do { \ + a_type *lchild = phn_lchild_get(a_type, a_field, a_phn); \ + if (lchild == NULL) \ + r_phn = NULL; \ + else { \ + ph_merge_siblings(a_type, a_field, lchild, a_cmp, \ + r_phn); \ + } \ +} while (0) + +/* + * The ph_proto() macro generates function prototypes that correspond to the + * functions generated by an equivalently parameterized call to ph_gen(). + */ +#define ph_proto(a_attr, a_prefix, a_ph_type, a_type) \ +a_attr void a_prefix##new(a_ph_type *ph); \ +a_attr bool a_prefix##empty(a_ph_type *ph); \ +a_attr a_type *a_prefix##first(a_ph_type *ph); \ +a_attr void a_prefix##insert(a_ph_type *ph, a_type *phn); \ +a_attr a_type *a_prefix##remove_first(a_ph_type *ph); \ +a_attr void a_prefix##remove(a_ph_type *ph, a_type *phn); + +/* + * The ph_gen() macro generates a type-specific pairing heap implementation, + * based on the above cpp macros. + */ +#define ph_gen(a_attr, a_prefix, a_ph_type, a_type, a_field, a_cmp) \ +a_attr void \ +a_prefix##new(a_ph_type *ph) \ +{ \ + \ + memset(ph, 0, sizeof(ph(a_type))); \ +} \ +a_attr bool \ +a_prefix##empty(a_ph_type *ph) \ +{ \ + \ + return (ph->ph_root == NULL); \ +} \ +a_attr a_type * \ +a_prefix##first(a_ph_type *ph) \ +{ \ + \ + if (ph->ph_root == NULL) \ + return (NULL); \ + ph_merge_aux(a_type, a_field, ph, a_cmp); \ + return (ph->ph_root); \ +} \ +a_attr void \ +a_prefix##insert(a_ph_type *ph, a_type *phn) \ +{ \ + \ + memset(&phn->a_field, 0, sizeof(phn(a_type))); \ + \ + /* \ + * Treat the root as an aux list during insertion, and lazily \ + * merge during a_prefix##remove_first(). For elements that \ + * are inserted, then removed via a_prefix##remove() before the \ + * aux list is ever processed, this makes insert/remove \ + * constant-time, whereas eager merging would make insert \ + * O(log n). \ + */ \ + if (ph->ph_root == NULL) \ + ph->ph_root = phn; \ + else { \ + phn_next_set(a_type, a_field, phn, phn_next_get(a_type, \ + a_field, ph->ph_root)); \ + if (phn_next_get(a_type, a_field, ph->ph_root) != \ + NULL) { \ + phn_prev_set(a_type, a_field, \ + phn_next_get(a_type, a_field, ph->ph_root), \ + phn); \ + } \ + phn_prev_set(a_type, a_field, phn, ph->ph_root); \ + phn_next_set(a_type, a_field, ph->ph_root, phn); \ + } \ +} \ +a_attr a_type * \ +a_prefix##remove_first(a_ph_type *ph) \ +{ \ + a_type *ret; \ + \ + if (ph->ph_root == NULL) \ + return (NULL); \ + ph_merge_aux(a_type, a_field, ph, a_cmp); \ + \ + ret = ph->ph_root; \ + \ + ph_merge_children(a_type, a_field, ph->ph_root, a_cmp, \ + ph->ph_root); \ + \ + return (ret); \ +} \ +a_attr void \ +a_prefix##remove(a_ph_type *ph, a_type *phn) \ +{ \ + a_type *replace, *parent; \ + \ + /* \ + * We can delete from aux list without merging it, but we need \ + * to merge if we are dealing with the root node. \ + */ \ + if (ph->ph_root == phn) { \ + ph_merge_aux(a_type, a_field, ph, a_cmp); \ + if (ph->ph_root == phn) { \ + ph_merge_children(a_type, a_field, ph->ph_root, \ + a_cmp, ph->ph_root); \ + return; \ + } \ + } \ + \ + /* Get parent (if phn is leftmost child) before mutating. */ \ + if ((parent = phn_prev_get(a_type, a_field, phn)) != NULL) { \ + if (phn_lchild_get(a_type, a_field, parent) != phn) \ + parent = NULL; \ + } \ + /* Find a possible replacement node, and link to parent. */ \ + ph_merge_children(a_type, a_field, phn, a_cmp, replace); \ + /* Set next/prev for sibling linked list. */ \ + if (replace != NULL) { \ + if (parent != NULL) { \ + phn_prev_set(a_type, a_field, replace, parent); \ + phn_lchild_set(a_type, a_field, parent, \ + replace); \ + } else { \ + phn_prev_set(a_type, a_field, replace, \ + phn_prev_get(a_type, a_field, phn)); \ + if (phn_prev_get(a_type, a_field, phn) != \ + NULL) { \ + phn_next_set(a_type, a_field, \ + phn_prev_get(a_type, a_field, phn), \ + replace); \ + } \ + } \ + phn_next_set(a_type, a_field, replace, \ + phn_next_get(a_type, a_field, phn)); \ + if (phn_next_get(a_type, a_field, phn) != NULL) { \ + phn_prev_set(a_type, a_field, \ + phn_next_get(a_type, a_field, phn), \ + replace); \ + } \ + } else { \ + if (parent != NULL) { \ + a_type *next = phn_next_get(a_type, a_field, \ + phn); \ + phn_lchild_set(a_type, a_field, parent, next); \ + if (next != NULL) { \ + phn_prev_set(a_type, a_field, next, \ + parent); \ + } \ + } else { \ + assert(phn_prev_get(a_type, a_field, phn) != \ + NULL); \ + phn_next_set(a_type, a_field, \ + phn_prev_get(a_type, a_field, phn), \ + phn_next_get(a_type, a_field, phn)); \ + } \ + if (phn_next_get(a_type, a_field, phn) != NULL) { \ + phn_prev_set(a_type, a_field, \ + phn_next_get(a_type, a_field, phn), \ + phn_prev_get(a_type, a_field, phn)); \ + } \ + } \ +} + +#endif /* PH_H_ */ diff --git a/contrib/jemalloc/include/jemalloc/internal/private_namespace.h b/contrib/jemalloc/include/jemalloc/internal/private_namespace.h new file mode 100644 index 0000000..00bedba --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/private_namespace.h @@ -0,0 +1,611 @@ +#define a0dalloc JEMALLOC_N(a0dalloc) +#define a0malloc JEMALLOC_N(a0malloc) +#define arena_aalloc JEMALLOC_N(arena_aalloc) +#define arena_alloc_junk_small JEMALLOC_N(arena_alloc_junk_small) +#define arena_basic_stats_merge JEMALLOC_N(arena_basic_stats_merge) +#define arena_bin_index JEMALLOC_N(arena_bin_index) +#define arena_bin_info JEMALLOC_N(arena_bin_info) +#define arena_bitselm_get_const JEMALLOC_N(arena_bitselm_get_const) +#define arena_bitselm_get_mutable JEMALLOC_N(arena_bitselm_get_mutable) +#define arena_boot JEMALLOC_N(arena_boot) +#define arena_choose JEMALLOC_N(arena_choose) +#define arena_choose_hard JEMALLOC_N(arena_choose_hard) +#define arena_choose_impl JEMALLOC_N(arena_choose_impl) +#define arena_chunk_alloc_huge JEMALLOC_N(arena_chunk_alloc_huge) +#define arena_chunk_cache_maybe_insert JEMALLOC_N(arena_chunk_cache_maybe_insert) +#define arena_chunk_cache_maybe_remove JEMALLOC_N(arena_chunk_cache_maybe_remove) +#define arena_chunk_dalloc_huge JEMALLOC_N(arena_chunk_dalloc_huge) +#define arena_chunk_ralloc_huge_expand JEMALLOC_N(arena_chunk_ralloc_huge_expand) +#define arena_chunk_ralloc_huge_shrink JEMALLOC_N(arena_chunk_ralloc_huge_shrink) +#define arena_chunk_ralloc_huge_similar JEMALLOC_N(arena_chunk_ralloc_huge_similar) +#define arena_cleanup JEMALLOC_N(arena_cleanup) +#define arena_dalloc JEMALLOC_N(arena_dalloc) +#define arena_dalloc_bin JEMALLOC_N(arena_dalloc_bin) +#define arena_dalloc_bin_junked_locked JEMALLOC_N(arena_dalloc_bin_junked_locked) +#define arena_dalloc_junk_large JEMALLOC_N(arena_dalloc_junk_large) +#define arena_dalloc_junk_small JEMALLOC_N(arena_dalloc_junk_small) +#define arena_dalloc_large JEMALLOC_N(arena_dalloc_large) +#define arena_dalloc_large_junked_locked JEMALLOC_N(arena_dalloc_large_junked_locked) +#define arena_dalloc_small JEMALLOC_N(arena_dalloc_small) +#define arena_decay_tick JEMALLOC_N(arena_decay_tick) +#define arena_decay_ticks JEMALLOC_N(arena_decay_ticks) +#define arena_decay_time_default_get JEMALLOC_N(arena_decay_time_default_get) +#define arena_decay_time_default_set JEMALLOC_N(arena_decay_time_default_set) +#define arena_decay_time_get JEMALLOC_N(arena_decay_time_get) +#define arena_decay_time_set JEMALLOC_N(arena_decay_time_set) +#define arena_dss_prec_get JEMALLOC_N(arena_dss_prec_get) +#define arena_dss_prec_set JEMALLOC_N(arena_dss_prec_set) +#define arena_get JEMALLOC_N(arena_get) +#define arena_ichoose JEMALLOC_N(arena_ichoose) +#define arena_init JEMALLOC_N(arena_init) +#define arena_lg_dirty_mult_default_get JEMALLOC_N(arena_lg_dirty_mult_default_get) +#define arena_lg_dirty_mult_default_set JEMALLOC_N(arena_lg_dirty_mult_default_set) +#define arena_lg_dirty_mult_get JEMALLOC_N(arena_lg_dirty_mult_get) +#define arena_lg_dirty_mult_set JEMALLOC_N(arena_lg_dirty_mult_set) +#define arena_malloc JEMALLOC_N(arena_malloc) +#define arena_malloc_hard JEMALLOC_N(arena_malloc_hard) +#define arena_malloc_large JEMALLOC_N(arena_malloc_large) +#define arena_mapbits_allocated_get JEMALLOC_N(arena_mapbits_allocated_get) +#define arena_mapbits_binind_get JEMALLOC_N(arena_mapbits_binind_get) +#define arena_mapbits_decommitted_get JEMALLOC_N(arena_mapbits_decommitted_get) +#define arena_mapbits_dirty_get JEMALLOC_N(arena_mapbits_dirty_get) +#define arena_mapbits_get JEMALLOC_N(arena_mapbits_get) +#define arena_mapbits_internal_set JEMALLOC_N(arena_mapbits_internal_set) +#define arena_mapbits_large_binind_set JEMALLOC_N(arena_mapbits_large_binind_set) +#define arena_mapbits_large_get JEMALLOC_N(arena_mapbits_large_get) +#define arena_mapbits_large_set JEMALLOC_N(arena_mapbits_large_set) +#define arena_mapbits_large_size_get JEMALLOC_N(arena_mapbits_large_size_get) +#define arena_mapbits_size_decode JEMALLOC_N(arena_mapbits_size_decode) +#define arena_mapbits_size_encode JEMALLOC_N(arena_mapbits_size_encode) +#define arena_mapbits_small_runind_get JEMALLOC_N(arena_mapbits_small_runind_get) +#define arena_mapbits_small_set JEMALLOC_N(arena_mapbits_small_set) +#define arena_mapbits_unallocated_set JEMALLOC_N(arena_mapbits_unallocated_set) +#define arena_mapbits_unallocated_size_get JEMALLOC_N(arena_mapbits_unallocated_size_get) +#define arena_mapbits_unallocated_size_set JEMALLOC_N(arena_mapbits_unallocated_size_set) +#define arena_mapbits_unzeroed_get JEMALLOC_N(arena_mapbits_unzeroed_get) +#define arena_mapbitsp_get_const JEMALLOC_N(arena_mapbitsp_get_const) +#define arena_mapbitsp_get_mutable JEMALLOC_N(arena_mapbitsp_get_mutable) +#define arena_mapbitsp_read JEMALLOC_N(arena_mapbitsp_read) +#define arena_mapbitsp_write JEMALLOC_N(arena_mapbitsp_write) +#define arena_maxrun JEMALLOC_N(arena_maxrun) +#define arena_maybe_purge JEMALLOC_N(arena_maybe_purge) +#define arena_metadata_allocated_add JEMALLOC_N(arena_metadata_allocated_add) +#define arena_metadata_allocated_get JEMALLOC_N(arena_metadata_allocated_get) +#define arena_metadata_allocated_sub JEMALLOC_N(arena_metadata_allocated_sub) +#define arena_migrate JEMALLOC_N(arena_migrate) +#define arena_miscelm_get_const JEMALLOC_N(arena_miscelm_get_const) +#define arena_miscelm_get_mutable JEMALLOC_N(arena_miscelm_get_mutable) +#define arena_miscelm_to_pageind JEMALLOC_N(arena_miscelm_to_pageind) +#define arena_miscelm_to_rpages JEMALLOC_N(arena_miscelm_to_rpages) +#define arena_new JEMALLOC_N(arena_new) +#define arena_node_alloc JEMALLOC_N(arena_node_alloc) +#define arena_node_dalloc JEMALLOC_N(arena_node_dalloc) +#define arena_nthreads_dec JEMALLOC_N(arena_nthreads_dec) +#define arena_nthreads_get JEMALLOC_N(arena_nthreads_get) +#define arena_nthreads_inc JEMALLOC_N(arena_nthreads_inc) +#define arena_palloc JEMALLOC_N(arena_palloc) +#define arena_postfork_child JEMALLOC_N(arena_postfork_child) +#define arena_postfork_parent JEMALLOC_N(arena_postfork_parent) +#define arena_prefork0 JEMALLOC_N(arena_prefork0) +#define arena_prefork1 JEMALLOC_N(arena_prefork1) +#define arena_prefork2 JEMALLOC_N(arena_prefork2) +#define arena_prefork3 JEMALLOC_N(arena_prefork3) +#define arena_prof_accum JEMALLOC_N(arena_prof_accum) +#define arena_prof_accum_impl JEMALLOC_N(arena_prof_accum_impl) +#define arena_prof_accum_locked JEMALLOC_N(arena_prof_accum_locked) +#define arena_prof_promoted JEMALLOC_N(arena_prof_promoted) +#define arena_prof_tctx_get JEMALLOC_N(arena_prof_tctx_get) +#define arena_prof_tctx_reset JEMALLOC_N(arena_prof_tctx_reset) +#define arena_prof_tctx_set JEMALLOC_N(arena_prof_tctx_set) +#define arena_ptr_small_binind_get JEMALLOC_N(arena_ptr_small_binind_get) +#define arena_purge JEMALLOC_N(arena_purge) +#define arena_quarantine_junk_small JEMALLOC_N(arena_quarantine_junk_small) +#define arena_ralloc JEMALLOC_N(arena_ralloc) +#define arena_ralloc_junk_large JEMALLOC_N(arena_ralloc_junk_large) +#define arena_ralloc_no_move JEMALLOC_N(arena_ralloc_no_move) +#define arena_rd_to_miscelm JEMALLOC_N(arena_rd_to_miscelm) +#define arena_redzone_corruption JEMALLOC_N(arena_redzone_corruption) +#define arena_reset JEMALLOC_N(arena_reset) +#define arena_run_regind JEMALLOC_N(arena_run_regind) +#define arena_run_to_miscelm JEMALLOC_N(arena_run_to_miscelm) +#define arena_salloc JEMALLOC_N(arena_salloc) +#define arena_sdalloc JEMALLOC_N(arena_sdalloc) +#define arena_stats_merge JEMALLOC_N(arena_stats_merge) +#define arena_tcache_fill_small JEMALLOC_N(arena_tcache_fill_small) +#define arena_tdata_get JEMALLOC_N(arena_tdata_get) +#define arena_tdata_get_hard JEMALLOC_N(arena_tdata_get_hard) +#define arenas JEMALLOC_N(arenas) +#define arenas_tdata_bypass_cleanup JEMALLOC_N(arenas_tdata_bypass_cleanup) +#define arenas_tdata_cleanup JEMALLOC_N(arenas_tdata_cleanup) +#define atomic_add_p JEMALLOC_N(atomic_add_p) +#define atomic_add_u JEMALLOC_N(atomic_add_u) +#define atomic_add_uint32 JEMALLOC_N(atomic_add_uint32) +#define atomic_add_uint64 JEMALLOC_N(atomic_add_uint64) +#define atomic_add_z JEMALLOC_N(atomic_add_z) +#define atomic_cas_p JEMALLOC_N(atomic_cas_p) +#define atomic_cas_u JEMALLOC_N(atomic_cas_u) +#define atomic_cas_uint32 JEMALLOC_N(atomic_cas_uint32) +#define atomic_cas_uint64 JEMALLOC_N(atomic_cas_uint64) +#define atomic_cas_z JEMALLOC_N(atomic_cas_z) +#define atomic_sub_p JEMALLOC_N(atomic_sub_p) +#define atomic_sub_u JEMALLOC_N(atomic_sub_u) +#define atomic_sub_uint32 JEMALLOC_N(atomic_sub_uint32) +#define atomic_sub_uint64 JEMALLOC_N(atomic_sub_uint64) +#define atomic_sub_z JEMALLOC_N(atomic_sub_z) +#define atomic_write_p JEMALLOC_N(atomic_write_p) +#define atomic_write_u JEMALLOC_N(atomic_write_u) +#define atomic_write_uint32 JEMALLOC_N(atomic_write_uint32) +#define atomic_write_uint64 JEMALLOC_N(atomic_write_uint64) +#define atomic_write_z JEMALLOC_N(atomic_write_z) +#define base_alloc JEMALLOC_N(base_alloc) +#define base_boot JEMALLOC_N(base_boot) +#define base_postfork_child JEMALLOC_N(base_postfork_child) +#define base_postfork_parent JEMALLOC_N(base_postfork_parent) +#define base_prefork JEMALLOC_N(base_prefork) +#define base_stats_get JEMALLOC_N(base_stats_get) +#define bitmap_full JEMALLOC_N(bitmap_full) +#define bitmap_get JEMALLOC_N(bitmap_get) +#define bitmap_info_init JEMALLOC_N(bitmap_info_init) +#define bitmap_init JEMALLOC_N(bitmap_init) +#define bitmap_set JEMALLOC_N(bitmap_set) +#define bitmap_sfu JEMALLOC_N(bitmap_sfu) +#define bitmap_size JEMALLOC_N(bitmap_size) +#define bitmap_unset JEMALLOC_N(bitmap_unset) +#define bootstrap_calloc JEMALLOC_N(bootstrap_calloc) +#define bootstrap_free JEMALLOC_N(bootstrap_free) +#define bootstrap_malloc JEMALLOC_N(bootstrap_malloc) +#define bt_init JEMALLOC_N(bt_init) +#define buferror JEMALLOC_N(buferror) +#define chunk_alloc_base JEMALLOC_N(chunk_alloc_base) +#define chunk_alloc_cache JEMALLOC_N(chunk_alloc_cache) +#define chunk_alloc_dss JEMALLOC_N(chunk_alloc_dss) +#define chunk_alloc_mmap JEMALLOC_N(chunk_alloc_mmap) +#define chunk_alloc_wrapper JEMALLOC_N(chunk_alloc_wrapper) +#define chunk_boot JEMALLOC_N(chunk_boot) +#define chunk_dalloc_cache JEMALLOC_N(chunk_dalloc_cache) +#define chunk_dalloc_mmap JEMALLOC_N(chunk_dalloc_mmap) +#define chunk_dalloc_wrapper JEMALLOC_N(chunk_dalloc_wrapper) +#define chunk_deregister JEMALLOC_N(chunk_deregister) +#define chunk_dss_boot JEMALLOC_N(chunk_dss_boot) +#define chunk_dss_postfork_child JEMALLOC_N(chunk_dss_postfork_child) +#define chunk_dss_postfork_parent JEMALLOC_N(chunk_dss_postfork_parent) +#define chunk_dss_prec_get JEMALLOC_N(chunk_dss_prec_get) +#define chunk_dss_prec_set JEMALLOC_N(chunk_dss_prec_set) +#define chunk_dss_prefork JEMALLOC_N(chunk_dss_prefork) +#define chunk_hooks_default JEMALLOC_N(chunk_hooks_default) +#define chunk_hooks_get JEMALLOC_N(chunk_hooks_get) +#define chunk_hooks_set JEMALLOC_N(chunk_hooks_set) +#define chunk_in_dss JEMALLOC_N(chunk_in_dss) +#define chunk_lookup JEMALLOC_N(chunk_lookup) +#define chunk_npages JEMALLOC_N(chunk_npages) +#define chunk_postfork_child JEMALLOC_N(chunk_postfork_child) +#define chunk_postfork_parent JEMALLOC_N(chunk_postfork_parent) +#define chunk_prefork JEMALLOC_N(chunk_prefork) +#define chunk_purge_wrapper JEMALLOC_N(chunk_purge_wrapper) +#define chunk_register JEMALLOC_N(chunk_register) +#define chunks_rtree JEMALLOC_N(chunks_rtree) +#define chunksize JEMALLOC_N(chunksize) +#define chunksize_mask JEMALLOC_N(chunksize_mask) +#define ckh_count JEMALLOC_N(ckh_count) +#define ckh_delete JEMALLOC_N(ckh_delete) +#define ckh_insert JEMALLOC_N(ckh_insert) +#define ckh_iter JEMALLOC_N(ckh_iter) +#define ckh_new JEMALLOC_N(ckh_new) +#define ckh_pointer_hash JEMALLOC_N(ckh_pointer_hash) +#define ckh_pointer_keycomp JEMALLOC_N(ckh_pointer_keycomp) +#define ckh_remove JEMALLOC_N(ckh_remove) +#define ckh_search JEMALLOC_N(ckh_search) +#define ckh_string_hash JEMALLOC_N(ckh_string_hash) +#define ckh_string_keycomp JEMALLOC_N(ckh_string_keycomp) +#define ctl_boot JEMALLOC_N(ctl_boot) +#define ctl_bymib JEMALLOC_N(ctl_bymib) +#define ctl_byname JEMALLOC_N(ctl_byname) +#define ctl_nametomib JEMALLOC_N(ctl_nametomib) +#define ctl_postfork_child JEMALLOC_N(ctl_postfork_child) +#define ctl_postfork_parent JEMALLOC_N(ctl_postfork_parent) +#define ctl_prefork JEMALLOC_N(ctl_prefork) +#define decay_ticker_get JEMALLOC_N(decay_ticker_get) +#define dss_prec_names JEMALLOC_N(dss_prec_names) +#define extent_node_achunk_get JEMALLOC_N(extent_node_achunk_get) +#define extent_node_achunk_set JEMALLOC_N(extent_node_achunk_set) +#define extent_node_addr_get JEMALLOC_N(extent_node_addr_get) +#define extent_node_addr_set JEMALLOC_N(extent_node_addr_set) +#define extent_node_arena_get JEMALLOC_N(extent_node_arena_get) +#define extent_node_arena_set JEMALLOC_N(extent_node_arena_set) +#define extent_node_committed_get JEMALLOC_N(extent_node_committed_get) +#define extent_node_committed_set JEMALLOC_N(extent_node_committed_set) +#define extent_node_dirty_insert JEMALLOC_N(extent_node_dirty_insert) +#define extent_node_dirty_linkage_init JEMALLOC_N(extent_node_dirty_linkage_init) +#define extent_node_dirty_remove JEMALLOC_N(extent_node_dirty_remove) +#define extent_node_init JEMALLOC_N(extent_node_init) +#define extent_node_prof_tctx_get JEMALLOC_N(extent_node_prof_tctx_get) +#define extent_node_prof_tctx_set JEMALLOC_N(extent_node_prof_tctx_set) +#define extent_node_size_get JEMALLOC_N(extent_node_size_get) +#define extent_node_size_set JEMALLOC_N(extent_node_size_set) +#define extent_node_zeroed_get JEMALLOC_N(extent_node_zeroed_get) +#define extent_node_zeroed_set JEMALLOC_N(extent_node_zeroed_set) +#define extent_tree_ad_destroy JEMALLOC_N(extent_tree_ad_destroy) +#define extent_tree_ad_destroy_recurse JEMALLOC_N(extent_tree_ad_destroy_recurse) +#define extent_tree_ad_empty JEMALLOC_N(extent_tree_ad_empty) +#define extent_tree_ad_first JEMALLOC_N(extent_tree_ad_first) +#define extent_tree_ad_insert JEMALLOC_N(extent_tree_ad_insert) +#define extent_tree_ad_iter JEMALLOC_N(extent_tree_ad_iter) +#define extent_tree_ad_iter_recurse JEMALLOC_N(extent_tree_ad_iter_recurse) +#define extent_tree_ad_iter_start JEMALLOC_N(extent_tree_ad_iter_start) +#define extent_tree_ad_last JEMALLOC_N(extent_tree_ad_last) +#define extent_tree_ad_new JEMALLOC_N(extent_tree_ad_new) +#define extent_tree_ad_next JEMALLOC_N(extent_tree_ad_next) +#define extent_tree_ad_nsearch JEMALLOC_N(extent_tree_ad_nsearch) +#define extent_tree_ad_prev JEMALLOC_N(extent_tree_ad_prev) +#define extent_tree_ad_psearch JEMALLOC_N(extent_tree_ad_psearch) +#define extent_tree_ad_remove JEMALLOC_N(extent_tree_ad_remove) +#define extent_tree_ad_reverse_iter JEMALLOC_N(extent_tree_ad_reverse_iter) +#define extent_tree_ad_reverse_iter_recurse JEMALLOC_N(extent_tree_ad_reverse_iter_recurse) +#define extent_tree_ad_reverse_iter_start JEMALLOC_N(extent_tree_ad_reverse_iter_start) +#define extent_tree_ad_search JEMALLOC_N(extent_tree_ad_search) +#define extent_tree_szad_destroy JEMALLOC_N(extent_tree_szad_destroy) +#define extent_tree_szad_destroy_recurse JEMALLOC_N(extent_tree_szad_destroy_recurse) +#define extent_tree_szad_empty JEMALLOC_N(extent_tree_szad_empty) +#define extent_tree_szad_first JEMALLOC_N(extent_tree_szad_first) +#define extent_tree_szad_insert JEMALLOC_N(extent_tree_szad_insert) +#define extent_tree_szad_iter JEMALLOC_N(extent_tree_szad_iter) +#define extent_tree_szad_iter_recurse JEMALLOC_N(extent_tree_szad_iter_recurse) +#define extent_tree_szad_iter_start JEMALLOC_N(extent_tree_szad_iter_start) +#define extent_tree_szad_last JEMALLOC_N(extent_tree_szad_last) +#define extent_tree_szad_new JEMALLOC_N(extent_tree_szad_new) +#define extent_tree_szad_next JEMALLOC_N(extent_tree_szad_next) +#define extent_tree_szad_nsearch JEMALLOC_N(extent_tree_szad_nsearch) +#define extent_tree_szad_prev JEMALLOC_N(extent_tree_szad_prev) +#define extent_tree_szad_psearch JEMALLOC_N(extent_tree_szad_psearch) +#define extent_tree_szad_remove JEMALLOC_N(extent_tree_szad_remove) +#define extent_tree_szad_reverse_iter JEMALLOC_N(extent_tree_szad_reverse_iter) +#define extent_tree_szad_reverse_iter_recurse JEMALLOC_N(extent_tree_szad_reverse_iter_recurse) +#define extent_tree_szad_reverse_iter_start JEMALLOC_N(extent_tree_szad_reverse_iter_start) +#define extent_tree_szad_search JEMALLOC_N(extent_tree_szad_search) +#define ffs_llu JEMALLOC_N(ffs_llu) +#define ffs_lu JEMALLOC_N(ffs_lu) +#define ffs_u JEMALLOC_N(ffs_u) +#define ffs_u32 JEMALLOC_N(ffs_u32) +#define ffs_u64 JEMALLOC_N(ffs_u64) +#define ffs_zu JEMALLOC_N(ffs_zu) +#define get_errno JEMALLOC_N(get_errno) +#define hash JEMALLOC_N(hash) +#define hash_fmix_32 JEMALLOC_N(hash_fmix_32) +#define hash_fmix_64 JEMALLOC_N(hash_fmix_64) +#define hash_get_block_32 JEMALLOC_N(hash_get_block_32) +#define hash_get_block_64 JEMALLOC_N(hash_get_block_64) +#define hash_rotl_32 JEMALLOC_N(hash_rotl_32) +#define hash_rotl_64 JEMALLOC_N(hash_rotl_64) +#define hash_x64_128 JEMALLOC_N(hash_x64_128) +#define hash_x86_128 JEMALLOC_N(hash_x86_128) +#define hash_x86_32 JEMALLOC_N(hash_x86_32) +#define huge_aalloc JEMALLOC_N(huge_aalloc) +#define huge_dalloc JEMALLOC_N(huge_dalloc) +#define huge_dalloc_junk JEMALLOC_N(huge_dalloc_junk) +#define huge_malloc JEMALLOC_N(huge_malloc) +#define huge_palloc JEMALLOC_N(huge_palloc) +#define huge_prof_tctx_get JEMALLOC_N(huge_prof_tctx_get) +#define huge_prof_tctx_reset JEMALLOC_N(huge_prof_tctx_reset) +#define huge_prof_tctx_set JEMALLOC_N(huge_prof_tctx_set) +#define huge_ralloc JEMALLOC_N(huge_ralloc) +#define huge_ralloc_no_move JEMALLOC_N(huge_ralloc_no_move) +#define huge_salloc JEMALLOC_N(huge_salloc) +#define iaalloc JEMALLOC_N(iaalloc) +#define ialloc JEMALLOC_N(ialloc) +#define iallocztm JEMALLOC_N(iallocztm) +#define iarena_cleanup JEMALLOC_N(iarena_cleanup) +#define idalloc JEMALLOC_N(idalloc) +#define idalloctm JEMALLOC_N(idalloctm) +#define in_valgrind JEMALLOC_N(in_valgrind) +#define index2size JEMALLOC_N(index2size) +#define index2size_compute JEMALLOC_N(index2size_compute) +#define index2size_lookup JEMALLOC_N(index2size_lookup) +#define index2size_tab JEMALLOC_N(index2size_tab) +#define ipalloc JEMALLOC_N(ipalloc) +#define ipalloct JEMALLOC_N(ipalloct) +#define ipallocztm JEMALLOC_N(ipallocztm) +#define iqalloc JEMALLOC_N(iqalloc) +#define iralloc JEMALLOC_N(iralloc) +#define iralloct JEMALLOC_N(iralloct) +#define iralloct_realign JEMALLOC_N(iralloct_realign) +#define isalloc JEMALLOC_N(isalloc) +#define isdalloct JEMALLOC_N(isdalloct) +#define isqalloc JEMALLOC_N(isqalloc) +#define ivsalloc JEMALLOC_N(ivsalloc) +#define ixalloc JEMALLOC_N(ixalloc) +#define jemalloc_postfork_child JEMALLOC_N(jemalloc_postfork_child) +#define jemalloc_postfork_parent JEMALLOC_N(jemalloc_postfork_parent) +#define jemalloc_prefork JEMALLOC_N(jemalloc_prefork) +#define large_maxclass JEMALLOC_N(large_maxclass) +#define lg_floor JEMALLOC_N(lg_floor) +#define lg_prof_sample JEMALLOC_N(lg_prof_sample) +#define malloc_cprintf JEMALLOC_N(malloc_cprintf) +#define malloc_mutex_assert_not_owner JEMALLOC_N(malloc_mutex_assert_not_owner) +#define malloc_mutex_assert_owner JEMALLOC_N(malloc_mutex_assert_owner) +#define malloc_mutex_boot JEMALLOC_N(malloc_mutex_boot) +#define malloc_mutex_init JEMALLOC_N(malloc_mutex_init) +#define malloc_mutex_lock JEMALLOC_N(malloc_mutex_lock) +#define malloc_mutex_postfork_child JEMALLOC_N(malloc_mutex_postfork_child) +#define malloc_mutex_postfork_parent JEMALLOC_N(malloc_mutex_postfork_parent) +#define malloc_mutex_prefork JEMALLOC_N(malloc_mutex_prefork) +#define malloc_mutex_unlock JEMALLOC_N(malloc_mutex_unlock) +#define malloc_printf JEMALLOC_N(malloc_printf) +#define malloc_snprintf JEMALLOC_N(malloc_snprintf) +#define malloc_strtoumax JEMALLOC_N(malloc_strtoumax) +#define malloc_tsd_boot0 JEMALLOC_N(malloc_tsd_boot0) +#define malloc_tsd_boot1 JEMALLOC_N(malloc_tsd_boot1) +#define malloc_tsd_cleanup_register JEMALLOC_N(malloc_tsd_cleanup_register) +#define malloc_tsd_dalloc JEMALLOC_N(malloc_tsd_dalloc) +#define malloc_tsd_malloc JEMALLOC_N(malloc_tsd_malloc) +#define malloc_tsd_no_cleanup JEMALLOC_N(malloc_tsd_no_cleanup) +#define malloc_vcprintf JEMALLOC_N(malloc_vcprintf) +#define malloc_vsnprintf JEMALLOC_N(malloc_vsnprintf) +#define malloc_write JEMALLOC_N(malloc_write) +#define map_bias JEMALLOC_N(map_bias) +#define map_misc_offset JEMALLOC_N(map_misc_offset) +#define mb_write JEMALLOC_N(mb_write) +#define narenas_auto JEMALLOC_N(narenas_auto) +#define narenas_tdata_cleanup JEMALLOC_N(narenas_tdata_cleanup) +#define narenas_total_get JEMALLOC_N(narenas_total_get) +#define ncpus JEMALLOC_N(ncpus) +#define nhbins JEMALLOC_N(nhbins) +#define nhclasses JEMALLOC_N(nhclasses) +#define nlclasses JEMALLOC_N(nlclasses) +#define nstime_add JEMALLOC_N(nstime_add) +#define nstime_compare JEMALLOC_N(nstime_compare) +#define nstime_copy JEMALLOC_N(nstime_copy) +#define nstime_divide JEMALLOC_N(nstime_divide) +#define nstime_idivide JEMALLOC_N(nstime_idivide) +#define nstime_imultiply JEMALLOC_N(nstime_imultiply) +#define nstime_init JEMALLOC_N(nstime_init) +#define nstime_init2 JEMALLOC_N(nstime_init2) +#define nstime_ns JEMALLOC_N(nstime_ns) +#define nstime_nsec JEMALLOC_N(nstime_nsec) +#define nstime_sec JEMALLOC_N(nstime_sec) +#define nstime_subtract JEMALLOC_N(nstime_subtract) +#define nstime_update JEMALLOC_N(nstime_update) +#define opt_abort JEMALLOC_N(opt_abort) +#define opt_decay_time JEMALLOC_N(opt_decay_time) +#define opt_dss JEMALLOC_N(opt_dss) +#define opt_junk JEMALLOC_N(opt_junk) +#define opt_junk_alloc JEMALLOC_N(opt_junk_alloc) +#define opt_junk_free JEMALLOC_N(opt_junk_free) +#define opt_lg_chunk JEMALLOC_N(opt_lg_chunk) +#define opt_lg_dirty_mult JEMALLOC_N(opt_lg_dirty_mult) +#define opt_lg_prof_interval JEMALLOC_N(opt_lg_prof_interval) +#define opt_lg_prof_sample JEMALLOC_N(opt_lg_prof_sample) +#define opt_lg_tcache_max JEMALLOC_N(opt_lg_tcache_max) +#define opt_narenas JEMALLOC_N(opt_narenas) +#define opt_prof JEMALLOC_N(opt_prof) +#define opt_prof_accum JEMALLOC_N(opt_prof_accum) +#define opt_prof_active JEMALLOC_N(opt_prof_active) +#define opt_prof_final JEMALLOC_N(opt_prof_final) +#define opt_prof_gdump JEMALLOC_N(opt_prof_gdump) +#define opt_prof_leak JEMALLOC_N(opt_prof_leak) +#define opt_prof_prefix JEMALLOC_N(opt_prof_prefix) +#define opt_prof_thread_active_init JEMALLOC_N(opt_prof_thread_active_init) +#define opt_purge JEMALLOC_N(opt_purge) +#define opt_quarantine JEMALLOC_N(opt_quarantine) +#define opt_redzone JEMALLOC_N(opt_redzone) +#define opt_stats_print JEMALLOC_N(opt_stats_print) +#define opt_tcache JEMALLOC_N(opt_tcache) +#define opt_utrace JEMALLOC_N(opt_utrace) +#define opt_xmalloc JEMALLOC_N(opt_xmalloc) +#define opt_zero JEMALLOC_N(opt_zero) +#define p2rz JEMALLOC_N(p2rz) +#define pages_boot JEMALLOC_N(pages_boot) +#define pages_commit JEMALLOC_N(pages_commit) +#define pages_decommit JEMALLOC_N(pages_decommit) +#define pages_map JEMALLOC_N(pages_map) +#define pages_purge JEMALLOC_N(pages_purge) +#define pages_trim JEMALLOC_N(pages_trim) +#define pages_unmap JEMALLOC_N(pages_unmap) +#define pow2_ceil_u32 JEMALLOC_N(pow2_ceil_u32) +#define pow2_ceil_u64 JEMALLOC_N(pow2_ceil_u64) +#define pow2_ceil_zu JEMALLOC_N(pow2_ceil_zu) +#define prng_lg_range JEMALLOC_N(prng_lg_range) +#define prng_range JEMALLOC_N(prng_range) +#define prof_active JEMALLOC_N(prof_active) +#define prof_active_get JEMALLOC_N(prof_active_get) +#define prof_active_get_unlocked JEMALLOC_N(prof_active_get_unlocked) +#define prof_active_set JEMALLOC_N(prof_active_set) +#define prof_alloc_prep JEMALLOC_N(prof_alloc_prep) +#define prof_alloc_rollback JEMALLOC_N(prof_alloc_rollback) +#define prof_backtrace JEMALLOC_N(prof_backtrace) +#define prof_boot0 JEMALLOC_N(prof_boot0) +#define prof_boot1 JEMALLOC_N(prof_boot1) +#define prof_boot2 JEMALLOC_N(prof_boot2) +#define prof_bt_count JEMALLOC_N(prof_bt_count) +#define prof_dump_header JEMALLOC_N(prof_dump_header) +#define prof_dump_open JEMALLOC_N(prof_dump_open) +#define prof_free JEMALLOC_N(prof_free) +#define prof_free_sampled_object JEMALLOC_N(prof_free_sampled_object) +#define prof_gdump JEMALLOC_N(prof_gdump) +#define prof_gdump_get JEMALLOC_N(prof_gdump_get) +#define prof_gdump_get_unlocked JEMALLOC_N(prof_gdump_get_unlocked) +#define prof_gdump_set JEMALLOC_N(prof_gdump_set) +#define prof_gdump_val JEMALLOC_N(prof_gdump_val) +#define prof_idump JEMALLOC_N(prof_idump) +#define prof_interval JEMALLOC_N(prof_interval) +#define prof_lookup JEMALLOC_N(prof_lookup) +#define prof_malloc JEMALLOC_N(prof_malloc) +#define prof_malloc_sample_object JEMALLOC_N(prof_malloc_sample_object) +#define prof_mdump JEMALLOC_N(prof_mdump) +#define prof_postfork_child JEMALLOC_N(prof_postfork_child) +#define prof_postfork_parent JEMALLOC_N(prof_postfork_parent) +#define prof_prefork0 JEMALLOC_N(prof_prefork0) +#define prof_prefork1 JEMALLOC_N(prof_prefork1) +#define prof_realloc JEMALLOC_N(prof_realloc) +#define prof_reset JEMALLOC_N(prof_reset) +#define prof_sample_accum_update JEMALLOC_N(prof_sample_accum_update) +#define prof_sample_threshold_update JEMALLOC_N(prof_sample_threshold_update) +#define prof_tctx_get JEMALLOC_N(prof_tctx_get) +#define prof_tctx_reset JEMALLOC_N(prof_tctx_reset) +#define prof_tctx_set JEMALLOC_N(prof_tctx_set) +#define prof_tdata_cleanup JEMALLOC_N(prof_tdata_cleanup) +#define prof_tdata_count JEMALLOC_N(prof_tdata_count) +#define prof_tdata_get JEMALLOC_N(prof_tdata_get) +#define prof_tdata_init JEMALLOC_N(prof_tdata_init) +#define prof_tdata_reinit JEMALLOC_N(prof_tdata_reinit) +#define prof_thread_active_get JEMALLOC_N(prof_thread_active_get) +#define prof_thread_active_init_get JEMALLOC_N(prof_thread_active_init_get) +#define prof_thread_active_init_set JEMALLOC_N(prof_thread_active_init_set) +#define prof_thread_active_set JEMALLOC_N(prof_thread_active_set) +#define prof_thread_name_get JEMALLOC_N(prof_thread_name_get) +#define prof_thread_name_set JEMALLOC_N(prof_thread_name_set) +#define purge_mode_names JEMALLOC_N(purge_mode_names) +#define quarantine JEMALLOC_N(quarantine) +#define quarantine_alloc_hook JEMALLOC_N(quarantine_alloc_hook) +#define quarantine_alloc_hook_work JEMALLOC_N(quarantine_alloc_hook_work) +#define quarantine_cleanup JEMALLOC_N(quarantine_cleanup) +#define register_zone JEMALLOC_N(register_zone) +#define rtree_child_read JEMALLOC_N(rtree_child_read) +#define rtree_child_read_hard JEMALLOC_N(rtree_child_read_hard) +#define rtree_child_tryread JEMALLOC_N(rtree_child_tryread) +#define rtree_delete JEMALLOC_N(rtree_delete) +#define rtree_get JEMALLOC_N(rtree_get) +#define rtree_new JEMALLOC_N(rtree_new) +#define rtree_node_valid JEMALLOC_N(rtree_node_valid) +#define rtree_set JEMALLOC_N(rtree_set) +#define rtree_start_level JEMALLOC_N(rtree_start_level) +#define rtree_subkey JEMALLOC_N(rtree_subkey) +#define rtree_subtree_read JEMALLOC_N(rtree_subtree_read) +#define rtree_subtree_read_hard JEMALLOC_N(rtree_subtree_read_hard) +#define rtree_subtree_tryread JEMALLOC_N(rtree_subtree_tryread) +#define rtree_val_read JEMALLOC_N(rtree_val_read) +#define rtree_val_write JEMALLOC_N(rtree_val_write) +#define run_quantize_ceil JEMALLOC_N(run_quantize_ceil) +#define run_quantize_floor JEMALLOC_N(run_quantize_floor) +#define run_quantize_max JEMALLOC_N(run_quantize_max) +#define s2u JEMALLOC_N(s2u) +#define s2u_compute JEMALLOC_N(s2u_compute) +#define s2u_lookup JEMALLOC_N(s2u_lookup) +#define sa2u JEMALLOC_N(sa2u) +#define set_errno JEMALLOC_N(set_errno) +#define size2index JEMALLOC_N(size2index) +#define size2index_compute JEMALLOC_N(size2index_compute) +#define size2index_lookup JEMALLOC_N(size2index_lookup) +#define size2index_tab JEMALLOC_N(size2index_tab) +#define stats_cactive JEMALLOC_N(stats_cactive) +#define stats_cactive_add JEMALLOC_N(stats_cactive_add) +#define stats_cactive_get JEMALLOC_N(stats_cactive_get) +#define stats_cactive_sub JEMALLOC_N(stats_cactive_sub) +#define stats_print JEMALLOC_N(stats_print) +#define tcache_alloc_easy JEMALLOC_N(tcache_alloc_easy) +#define tcache_alloc_large JEMALLOC_N(tcache_alloc_large) +#define tcache_alloc_small JEMALLOC_N(tcache_alloc_small) +#define tcache_alloc_small_hard JEMALLOC_N(tcache_alloc_small_hard) +#define tcache_arena_reassociate JEMALLOC_N(tcache_arena_reassociate) +#define tcache_bin_flush_large JEMALLOC_N(tcache_bin_flush_large) +#define tcache_bin_flush_small JEMALLOC_N(tcache_bin_flush_small) +#define tcache_bin_info JEMALLOC_N(tcache_bin_info) +#define tcache_boot JEMALLOC_N(tcache_boot) +#define tcache_cleanup JEMALLOC_N(tcache_cleanup) +#define tcache_create JEMALLOC_N(tcache_create) +#define tcache_dalloc_large JEMALLOC_N(tcache_dalloc_large) +#define tcache_dalloc_small JEMALLOC_N(tcache_dalloc_small) +#define tcache_enabled_cleanup JEMALLOC_N(tcache_enabled_cleanup) +#define tcache_enabled_get JEMALLOC_N(tcache_enabled_get) +#define tcache_enabled_set JEMALLOC_N(tcache_enabled_set) +#define tcache_event JEMALLOC_N(tcache_event) +#define tcache_event_hard JEMALLOC_N(tcache_event_hard) +#define tcache_flush JEMALLOC_N(tcache_flush) +#define tcache_get JEMALLOC_N(tcache_get) +#define tcache_get_hard JEMALLOC_N(tcache_get_hard) +#define tcache_maxclass JEMALLOC_N(tcache_maxclass) +#define tcache_salloc JEMALLOC_N(tcache_salloc) +#define tcache_stats_merge JEMALLOC_N(tcache_stats_merge) +#define tcaches JEMALLOC_N(tcaches) +#define tcaches_create JEMALLOC_N(tcaches_create) +#define tcaches_destroy JEMALLOC_N(tcaches_destroy) +#define tcaches_flush JEMALLOC_N(tcaches_flush) +#define tcaches_get JEMALLOC_N(tcaches_get) +#define thread_allocated_cleanup JEMALLOC_N(thread_allocated_cleanup) +#define thread_deallocated_cleanup JEMALLOC_N(thread_deallocated_cleanup) +#define ticker_copy JEMALLOC_N(ticker_copy) +#define ticker_init JEMALLOC_N(ticker_init) +#define ticker_read JEMALLOC_N(ticker_read) +#define ticker_tick JEMALLOC_N(ticker_tick) +#define ticker_ticks JEMALLOC_N(ticker_ticks) +#define tsd_arena_get JEMALLOC_N(tsd_arena_get) +#define tsd_arena_set JEMALLOC_N(tsd_arena_set) +#define tsd_arenap_get JEMALLOC_N(tsd_arenap_get) +#define tsd_arenas_tdata_bypass_get JEMALLOC_N(tsd_arenas_tdata_bypass_get) +#define tsd_arenas_tdata_bypass_set JEMALLOC_N(tsd_arenas_tdata_bypass_set) +#define tsd_arenas_tdata_bypassp_get JEMALLOC_N(tsd_arenas_tdata_bypassp_get) +#define tsd_arenas_tdata_get JEMALLOC_N(tsd_arenas_tdata_get) +#define tsd_arenas_tdata_set JEMALLOC_N(tsd_arenas_tdata_set) +#define tsd_arenas_tdatap_get JEMALLOC_N(tsd_arenas_tdatap_get) +#define tsd_boot JEMALLOC_N(tsd_boot) +#define tsd_boot0 JEMALLOC_N(tsd_boot0) +#define tsd_boot1 JEMALLOC_N(tsd_boot1) +#define tsd_booted JEMALLOC_N(tsd_booted) +#define tsd_booted_get JEMALLOC_N(tsd_booted_get) +#define tsd_cleanup JEMALLOC_N(tsd_cleanup) +#define tsd_cleanup_wrapper JEMALLOC_N(tsd_cleanup_wrapper) +#define tsd_fetch JEMALLOC_N(tsd_fetch) +#define tsd_get JEMALLOC_N(tsd_get) +#define tsd_iarena_get JEMALLOC_N(tsd_iarena_get) +#define tsd_iarena_set JEMALLOC_N(tsd_iarena_set) +#define tsd_iarenap_get JEMALLOC_N(tsd_iarenap_get) +#define tsd_initialized JEMALLOC_N(tsd_initialized) +#define tsd_init_check_recursion JEMALLOC_N(tsd_init_check_recursion) +#define tsd_init_finish JEMALLOC_N(tsd_init_finish) +#define tsd_init_head JEMALLOC_N(tsd_init_head) +#define tsd_narenas_tdata_get JEMALLOC_N(tsd_narenas_tdata_get) +#define tsd_narenas_tdata_set JEMALLOC_N(tsd_narenas_tdata_set) +#define tsd_narenas_tdatap_get JEMALLOC_N(tsd_narenas_tdatap_get) +#define tsd_wrapper_get JEMALLOC_N(tsd_wrapper_get) +#define tsd_wrapper_set JEMALLOC_N(tsd_wrapper_set) +#define tsd_nominal JEMALLOC_N(tsd_nominal) +#define tsd_prof_tdata_get JEMALLOC_N(tsd_prof_tdata_get) +#define tsd_prof_tdata_set JEMALLOC_N(tsd_prof_tdata_set) +#define tsd_prof_tdatap_get JEMALLOC_N(tsd_prof_tdatap_get) +#define tsd_quarantine_get JEMALLOC_N(tsd_quarantine_get) +#define tsd_quarantine_set JEMALLOC_N(tsd_quarantine_set) +#define tsd_quarantinep_get JEMALLOC_N(tsd_quarantinep_get) +#define tsd_set JEMALLOC_N(tsd_set) +#define tsd_tcache_enabled_get JEMALLOC_N(tsd_tcache_enabled_get) +#define tsd_tcache_enabled_set JEMALLOC_N(tsd_tcache_enabled_set) +#define tsd_tcache_enabledp_get JEMALLOC_N(tsd_tcache_enabledp_get) +#define tsd_tcache_get JEMALLOC_N(tsd_tcache_get) +#define tsd_tcache_set JEMALLOC_N(tsd_tcache_set) +#define tsd_tcachep_get JEMALLOC_N(tsd_tcachep_get) +#define tsd_thread_allocated_get JEMALLOC_N(tsd_thread_allocated_get) +#define tsd_thread_allocated_set JEMALLOC_N(tsd_thread_allocated_set) +#define tsd_thread_allocatedp_get JEMALLOC_N(tsd_thread_allocatedp_get) +#define tsd_thread_deallocated_get JEMALLOC_N(tsd_thread_deallocated_get) +#define tsd_thread_deallocated_set JEMALLOC_N(tsd_thread_deallocated_set) +#define tsd_thread_deallocatedp_get JEMALLOC_N(tsd_thread_deallocatedp_get) +#define tsd_tls JEMALLOC_N(tsd_tls) +#define tsd_tsd JEMALLOC_N(tsd_tsd) +#define tsd_tsdn JEMALLOC_N(tsd_tsdn) +#define tsd_witness_fork_get JEMALLOC_N(tsd_witness_fork_get) +#define tsd_witness_fork_set JEMALLOC_N(tsd_witness_fork_set) +#define tsd_witness_forkp_get JEMALLOC_N(tsd_witness_forkp_get) +#define tsd_witnesses_get JEMALLOC_N(tsd_witnesses_get) +#define tsd_witnesses_set JEMALLOC_N(tsd_witnesses_set) +#define tsd_witnessesp_get JEMALLOC_N(tsd_witnessesp_get) +#define tsdn_fetch JEMALLOC_N(tsdn_fetch) +#define tsdn_null JEMALLOC_N(tsdn_null) +#define tsdn_tsd JEMALLOC_N(tsdn_tsd) +#define u2rz JEMALLOC_N(u2rz) +#define valgrind_freelike_block JEMALLOC_N(valgrind_freelike_block) +#define valgrind_make_mem_defined JEMALLOC_N(valgrind_make_mem_defined) +#define valgrind_make_mem_noaccess JEMALLOC_N(valgrind_make_mem_noaccess) +#define valgrind_make_mem_undefined JEMALLOC_N(valgrind_make_mem_undefined) +#define witness_assert_lockless JEMALLOC_N(witness_assert_lockless) +#define witness_assert_not_owner JEMALLOC_N(witness_assert_not_owner) +#define witness_assert_owner JEMALLOC_N(witness_assert_owner) +#define witness_fork_cleanup JEMALLOC_N(witness_fork_cleanup) +#define witness_init JEMALLOC_N(witness_init) +#define witness_lock JEMALLOC_N(witness_lock) +#define witness_lock_error JEMALLOC_N(witness_lock_error) +#define witness_lockless_error JEMALLOC_N(witness_lockless_error) +#define witness_not_owner_error JEMALLOC_N(witness_not_owner_error) +#define witness_owner_error JEMALLOC_N(witness_owner_error) +#define witness_postfork_child JEMALLOC_N(witness_postfork_child) +#define witness_postfork_parent JEMALLOC_N(witness_postfork_parent) +#define witness_prefork JEMALLOC_N(witness_prefork) +#define witness_unlock JEMALLOC_N(witness_unlock) +#define witnesses_cleanup JEMALLOC_N(witnesses_cleanup) diff --git a/contrib/jemalloc/include/jemalloc/internal/prng.h b/contrib/jemalloc/include/jemalloc/internal/prng.h new file mode 100644 index 0000000..5830f8b --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/prng.h @@ -0,0 +1,79 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +/* + * Simple linear congruential pseudo-random number generator: + * + * prng(y) = (a*x + c) % m + * + * where the following constants ensure maximal period: + * + * a == Odd number (relatively prime to 2^n), and (a-1) is a multiple of 4. + * c == Odd number (relatively prime to 2^n). + * m == 2^32 + * + * See Knuth's TAOCP 3rd Ed., Vol. 2, pg. 17 for details on these constraints. + * + * This choice of m has the disadvantage that the quality of the bits is + * proportional to bit position. For example, the lowest bit has a cycle of 2, + * the next has a cycle of 4, etc. For this reason, we prefer to use the upper + * bits. + */ +#define PRNG_A UINT64_C(6364136223846793005) +#define PRNG_C UINT64_C(1442695040888963407) + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +uint64_t prng_lg_range(uint64_t *state, unsigned lg_range); +uint64_t prng_range(uint64_t *state, uint64_t range); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_PRNG_C_)) +JEMALLOC_ALWAYS_INLINE uint64_t +prng_lg_range(uint64_t *state, unsigned lg_range) +{ + uint64_t ret; + + assert(lg_range > 0); + assert(lg_range <= 64); + + ret = (*state * PRNG_A) + PRNG_C; + *state = ret; + ret >>= (64 - lg_range); + + return (ret); +} + +JEMALLOC_ALWAYS_INLINE uint64_t +prng_range(uint64_t *state, uint64_t range) +{ + uint64_t ret; + unsigned lg_range; + + assert(range > 1); + + /* Compute the ceiling of lg(range). */ + lg_range = ffs_u64(pow2_ceil_u64(range)) - 1; + + /* Generate a result in [0..range) via repeated trial. */ + do { + ret = prng_lg_range(state, lg_range); + } while (ret >= range); + + return (ret); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/prof.h b/contrib/jemalloc/include/jemalloc/internal/prof.h new file mode 100644 index 0000000..21dff5f --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/prof.h @@ -0,0 +1,547 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct prof_bt_s prof_bt_t; +typedef struct prof_cnt_s prof_cnt_t; +typedef struct prof_tctx_s prof_tctx_t; +typedef struct prof_gctx_s prof_gctx_t; +typedef struct prof_tdata_s prof_tdata_t; + +/* Option defaults. */ +#ifdef JEMALLOC_PROF +# define PROF_PREFIX_DEFAULT "jeprof" +#else +# define PROF_PREFIX_DEFAULT "" +#endif +#define LG_PROF_SAMPLE_DEFAULT 19 +#define LG_PROF_INTERVAL_DEFAULT -1 + +/* + * Hard limit on stack backtrace depth. The version of prof_backtrace() that + * is based on __builtin_return_address() necessarily has a hard-coded number + * of backtrace frame handlers, and should be kept in sync with this setting. + */ +#define PROF_BT_MAX 128 + +/* Initial hash table size. */ +#define PROF_CKH_MINITEMS 64 + +/* Size of memory buffer to use when writing dump files. */ +#define PROF_DUMP_BUFSIZE 65536 + +/* Size of stack-allocated buffer used by prof_printf(). */ +#define PROF_PRINTF_BUFSIZE 128 + +/* + * Number of mutexes shared among all gctx's. No space is allocated for these + * unless profiling is enabled, so it's okay to over-provision. + */ +#define PROF_NCTX_LOCKS 1024 + +/* + * Number of mutexes shared among all tdata's. No space is allocated for these + * unless profiling is enabled, so it's okay to over-provision. + */ +#define PROF_NTDATA_LOCKS 256 + +/* + * prof_tdata pointers close to NULL are used to encode state information that + * is used for cleaning up during thread shutdown. + */ +#define PROF_TDATA_STATE_REINCARNATED ((prof_tdata_t *)(uintptr_t)1) +#define PROF_TDATA_STATE_PURGATORY ((prof_tdata_t *)(uintptr_t)2) +#define PROF_TDATA_STATE_MAX PROF_TDATA_STATE_PURGATORY + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct prof_bt_s { + /* Backtrace, stored as len program counters. */ + void **vec; + unsigned len; +}; + +#ifdef JEMALLOC_PROF_LIBGCC +/* Data structure passed to libgcc _Unwind_Backtrace() callback functions. */ +typedef struct { + prof_bt_t *bt; + unsigned max; +} prof_unwind_data_t; +#endif + +struct prof_cnt_s { + /* Profiling counters. */ + uint64_t curobjs; + uint64_t curbytes; + uint64_t accumobjs; + uint64_t accumbytes; +}; + +typedef enum { + prof_tctx_state_initializing, + prof_tctx_state_nominal, + prof_tctx_state_dumping, + prof_tctx_state_purgatory /* Dumper must finish destroying. */ +} prof_tctx_state_t; + +struct prof_tctx_s { + /* Thread data for thread that performed the allocation. */ + prof_tdata_t *tdata; + + /* + * Copy of tdata->thr_{uid,discrim}, necessary because tdata may be + * defunct during teardown. + */ + uint64_t thr_uid; + uint64_t thr_discrim; + + /* Profiling counters, protected by tdata->lock. */ + prof_cnt_t cnts; + + /* Associated global context. */ + prof_gctx_t *gctx; + + /* + * UID that distinguishes multiple tctx's created by the same thread, + * but coexisting in gctx->tctxs. There are two ways that such + * coexistence can occur: + * - A dumper thread can cause a tctx to be retained in the purgatory + * state. + * - Although a single "producer" thread must create all tctx's which + * share the same thr_uid, multiple "consumers" can each concurrently + * execute portions of prof_tctx_destroy(). prof_tctx_destroy() only + * gets called once each time cnts.cur{objs,bytes} drop to 0, but this + * threshold can be hit again before the first consumer finishes + * executing prof_tctx_destroy(). + */ + uint64_t tctx_uid; + + /* Linkage into gctx's tctxs. */ + rb_node(prof_tctx_t) tctx_link; + + /* + * True during prof_alloc_prep()..prof_malloc_sample_object(), prevents + * sample vs destroy race. + */ + bool prepared; + + /* Current dump-related state, protected by gctx->lock. */ + prof_tctx_state_t state; + + /* + * Copy of cnts snapshotted during early dump phase, protected by + * dump_mtx. + */ + prof_cnt_t dump_cnts; +}; +typedef rb_tree(prof_tctx_t) prof_tctx_tree_t; + +struct prof_gctx_s { + /* Protects nlimbo, cnt_summed, and tctxs. */ + malloc_mutex_t *lock; + + /* + * Number of threads that currently cause this gctx to be in a state of + * limbo due to one of: + * - Initializing this gctx. + * - Initializing per thread counters associated with this gctx. + * - Preparing to destroy this gctx. + * - Dumping a heap profile that includes this gctx. + * nlimbo must be 1 (single destroyer) in order to safely destroy the + * gctx. + */ + unsigned nlimbo; + + /* + * Tree of profile counters, one for each thread that has allocated in + * this context. + */ + prof_tctx_tree_t tctxs; + + /* Linkage for tree of contexts to be dumped. */ + rb_node(prof_gctx_t) dump_link; + + /* Temporary storage for summation during dump. */ + prof_cnt_t cnt_summed; + + /* Associated backtrace. */ + prof_bt_t bt; + + /* Backtrace vector, variable size, referred to by bt. */ + void *vec[1]; +}; +typedef rb_tree(prof_gctx_t) prof_gctx_tree_t; + +struct prof_tdata_s { + malloc_mutex_t *lock; + + /* Monotonically increasing unique thread identifier. */ + uint64_t thr_uid; + + /* + * Monotonically increasing discriminator among tdata structures + * associated with the same thr_uid. + */ + uint64_t thr_discrim; + + /* Included in heap profile dumps if non-NULL. */ + char *thread_name; + + bool attached; + bool expired; + + rb_node(prof_tdata_t) tdata_link; + + /* + * Counter used to initialize prof_tctx_t's tctx_uid. No locking is + * necessary when incrementing this field, because only one thread ever + * does so. + */ + uint64_t tctx_uid_next; + + /* + * Hash of (prof_bt_t *)-->(prof_tctx_t *). Each thread tracks + * backtraces for which it has non-zero allocation/deallocation counters + * associated with thread-specific prof_tctx_t objects. Other threads + * may write to prof_tctx_t contents when freeing associated objects. + */ + ckh_t bt2tctx; + + /* Sampling state. */ + uint64_t prng_state; + uint64_t bytes_until_sample; + + /* State used to avoid dumping while operating on prof internals. */ + bool enq; + bool enq_idump; + bool enq_gdump; + + /* + * Set to true during an early dump phase for tdata's which are + * currently being dumped. New threads' tdata's have this initialized + * to false so that they aren't accidentally included in later dump + * phases. + */ + bool dumping; + + /* + * True if profiling is active for this tdata's thread + * (thread.prof.active mallctl). + */ + bool active; + + /* Temporary storage for summation during dump. */ + prof_cnt_t cnt_summed; + + /* Backtrace vector, used for calls to prof_backtrace(). */ + void *vec[PROF_BT_MAX]; +}; +typedef rb_tree(prof_tdata_t) prof_tdata_tree_t; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +extern bool opt_prof; +extern bool opt_prof_active; +extern bool opt_prof_thread_active_init; +extern size_t opt_lg_prof_sample; /* Mean bytes between samples. */ +extern ssize_t opt_lg_prof_interval; /* lg(prof_interval). */ +extern bool opt_prof_gdump; /* High-water memory dumping. */ +extern bool opt_prof_final; /* Final profile dumping. */ +extern bool opt_prof_leak; /* Dump leak summary at exit. */ +extern bool opt_prof_accum; /* Report cumulative bytes. */ +extern char opt_prof_prefix[ + /* Minimize memory bloat for non-prof builds. */ +#ifdef JEMALLOC_PROF + PATH_MAX + +#endif + 1]; + +/* Accessed via prof_active_[gs]et{_unlocked,}(). */ +extern bool prof_active; + +/* Accessed via prof_gdump_[gs]et{_unlocked,}(). */ +extern bool prof_gdump_val; + +/* + * Profile dump interval, measured in bytes allocated. Each arena triggers a + * profile dump when it reaches this threshold. The effect is that the + * interval between profile dumps averages prof_interval, though the actual + * interval between dumps will tend to be sporadic, and the interval will be a + * maximum of approximately (prof_interval * narenas). + */ +extern uint64_t prof_interval; + +/* + * Initialized as opt_lg_prof_sample, and potentially modified during profiling + * resets. + */ +extern size_t lg_prof_sample; + +void prof_alloc_rollback(tsd_t *tsd, prof_tctx_t *tctx, bool updated); +void prof_malloc_sample_object(tsdn_t *tsdn, const void *ptr, size_t usize, + prof_tctx_t *tctx); +void prof_free_sampled_object(tsd_t *tsd, size_t usize, prof_tctx_t *tctx); +void bt_init(prof_bt_t *bt, void **vec); +void prof_backtrace(prof_bt_t *bt); +prof_tctx_t *prof_lookup(tsd_t *tsd, prof_bt_t *bt); +#ifdef JEMALLOC_JET +size_t prof_tdata_count(void); +size_t prof_bt_count(void); +const prof_cnt_t *prof_cnt_all(void); +typedef int (prof_dump_open_t)(bool, const char *); +extern prof_dump_open_t *prof_dump_open; +typedef bool (prof_dump_header_t)(tsdn_t *, bool, const prof_cnt_t *); +extern prof_dump_header_t *prof_dump_header; +#endif +void prof_idump(tsdn_t *tsdn); +bool prof_mdump(tsd_t *tsd, const char *filename); +void prof_gdump(tsdn_t *tsdn); +prof_tdata_t *prof_tdata_init(tsdn_t *tsdn); +prof_tdata_t *prof_tdata_reinit(tsd_t *tsd, prof_tdata_t *tdata); +void prof_reset(tsdn_t *tsdn, size_t lg_sample); +void prof_tdata_cleanup(tsd_t *tsd); +bool prof_active_get(tsdn_t *tsdn); +bool prof_active_set(tsdn_t *tsdn, bool active); +const char *prof_thread_name_get(tsd_t *tsd); +int prof_thread_name_set(tsd_t *tsd, const char *thread_name); +bool prof_thread_active_get(tsd_t *tsd); +bool prof_thread_active_set(tsd_t *tsd, bool active); +bool prof_thread_active_init_get(tsdn_t *tsdn); +bool prof_thread_active_init_set(tsdn_t *tsdn, bool active_init); +bool prof_gdump_get(tsdn_t *tsdn); +bool prof_gdump_set(tsdn_t *tsdn, bool active); +void prof_boot0(void); +void prof_boot1(void); +bool prof_boot2(tsdn_t *tsdn); +void prof_prefork0(tsdn_t *tsdn); +void prof_prefork1(tsdn_t *tsdn); +void prof_postfork_parent(tsdn_t *tsdn); +void prof_postfork_child(tsdn_t *tsdn); +void prof_sample_threshold_update(prof_tdata_t *tdata); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +bool prof_active_get_unlocked(void); +bool prof_gdump_get_unlocked(void); +prof_tdata_t *prof_tdata_get(tsd_t *tsd, bool create); +prof_tctx_t *prof_tctx_get(tsdn_t *tsdn, const void *ptr); +void prof_tctx_set(tsdn_t *tsdn, const void *ptr, size_t usize, + prof_tctx_t *tctx); +void prof_tctx_reset(tsdn_t *tsdn, const void *ptr, size_t usize, + const void *old_ptr, prof_tctx_t *tctx); +bool prof_sample_accum_update(tsd_t *tsd, size_t usize, bool commit, + prof_tdata_t **tdata_out); +prof_tctx_t *prof_alloc_prep(tsd_t *tsd, size_t usize, bool prof_active, + bool update); +void prof_malloc(tsdn_t *tsdn, const void *ptr, size_t usize, + prof_tctx_t *tctx); +void prof_realloc(tsd_t *tsd, const void *ptr, size_t usize, + prof_tctx_t *tctx, bool prof_active, bool updated, const void *old_ptr, + size_t old_usize, prof_tctx_t *old_tctx); +void prof_free(tsd_t *tsd, const void *ptr, size_t usize); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_PROF_C_)) +JEMALLOC_ALWAYS_INLINE bool +prof_active_get_unlocked(void) +{ + + /* + * Even if opt_prof is true, sampling can be temporarily disabled by + * setting prof_active to false. No locking is used when reading + * prof_active in the fast path, so there are no guarantees regarding + * how long it will take for all threads to notice state changes. + */ + return (prof_active); +} + +JEMALLOC_ALWAYS_INLINE bool +prof_gdump_get_unlocked(void) +{ + + /* + * No locking is used when reading prof_gdump_val in the fast path, so + * there are no guarantees regarding how long it will take for all + * threads to notice state changes. + */ + return (prof_gdump_val); +} + +JEMALLOC_ALWAYS_INLINE prof_tdata_t * +prof_tdata_get(tsd_t *tsd, bool create) +{ + prof_tdata_t *tdata; + + cassert(config_prof); + + tdata = tsd_prof_tdata_get(tsd); + if (create) { + if (unlikely(tdata == NULL)) { + if (tsd_nominal(tsd)) { + tdata = prof_tdata_init(tsd_tsdn(tsd)); + tsd_prof_tdata_set(tsd, tdata); + } + } else if (unlikely(tdata->expired)) { + tdata = prof_tdata_reinit(tsd, tdata); + tsd_prof_tdata_set(tsd, tdata); + } + assert(tdata == NULL || tdata->attached); + } + + return (tdata); +} + +JEMALLOC_ALWAYS_INLINE prof_tctx_t * +prof_tctx_get(tsdn_t *tsdn, const void *ptr) +{ + + cassert(config_prof); + assert(ptr != NULL); + + return (arena_prof_tctx_get(tsdn, ptr)); +} + +JEMALLOC_ALWAYS_INLINE void +prof_tctx_set(tsdn_t *tsdn, const void *ptr, size_t usize, prof_tctx_t *tctx) +{ + + cassert(config_prof); + assert(ptr != NULL); + + arena_prof_tctx_set(tsdn, ptr, usize, tctx); +} + +JEMALLOC_ALWAYS_INLINE void +prof_tctx_reset(tsdn_t *tsdn, const void *ptr, size_t usize, const void *old_ptr, + prof_tctx_t *old_tctx) +{ + + cassert(config_prof); + assert(ptr != NULL); + + arena_prof_tctx_reset(tsdn, ptr, usize, old_ptr, old_tctx); +} + +JEMALLOC_ALWAYS_INLINE bool +prof_sample_accum_update(tsd_t *tsd, size_t usize, bool update, + prof_tdata_t **tdata_out) +{ + prof_tdata_t *tdata; + + cassert(config_prof); + + tdata = prof_tdata_get(tsd, true); + if (unlikely((uintptr_t)tdata <= (uintptr_t)PROF_TDATA_STATE_MAX)) + tdata = NULL; + + if (tdata_out != NULL) + *tdata_out = tdata; + + if (unlikely(tdata == NULL)) + return (true); + + if (likely(tdata->bytes_until_sample >= usize)) { + if (update) + tdata->bytes_until_sample -= usize; + return (true); + } else { + /* Compute new sample threshold. */ + if (update) + prof_sample_threshold_update(tdata); + return (!tdata->active); + } +} + +JEMALLOC_ALWAYS_INLINE prof_tctx_t * +prof_alloc_prep(tsd_t *tsd, size_t usize, bool prof_active, bool update) +{ + prof_tctx_t *ret; + prof_tdata_t *tdata; + prof_bt_t bt; + + assert(usize == s2u(usize)); + + if (!prof_active || likely(prof_sample_accum_update(tsd, usize, update, + &tdata))) + ret = (prof_tctx_t *)(uintptr_t)1U; + else { + bt_init(&bt, tdata->vec); + prof_backtrace(&bt); + ret = prof_lookup(tsd, &bt); + } + + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void +prof_malloc(tsdn_t *tsdn, const void *ptr, size_t usize, prof_tctx_t *tctx) +{ + + cassert(config_prof); + assert(ptr != NULL); + assert(usize == isalloc(tsdn, ptr, true)); + + if (unlikely((uintptr_t)tctx > (uintptr_t)1U)) + prof_malloc_sample_object(tsdn, ptr, usize, tctx); + else + prof_tctx_set(tsdn, ptr, usize, (prof_tctx_t *)(uintptr_t)1U); +} + +JEMALLOC_ALWAYS_INLINE void +prof_realloc(tsd_t *tsd, const void *ptr, size_t usize, prof_tctx_t *tctx, + bool prof_active, bool updated, const void *old_ptr, size_t old_usize, + prof_tctx_t *old_tctx) +{ + bool sampled, old_sampled; + + cassert(config_prof); + assert(ptr != NULL || (uintptr_t)tctx <= (uintptr_t)1U); + + if (prof_active && !updated && ptr != NULL) { + assert(usize == isalloc(tsd_tsdn(tsd), ptr, true)); + if (prof_sample_accum_update(tsd, usize, true, NULL)) { + /* + * Don't sample. The usize passed to prof_alloc_prep() + * was larger than what actually got allocated, so a + * backtrace was captured for this allocation, even + * though its actual usize was insufficient to cross the + * sample threshold. + */ + prof_alloc_rollback(tsd, tctx, true); + tctx = (prof_tctx_t *)(uintptr_t)1U; + } + } + + sampled = ((uintptr_t)tctx > (uintptr_t)1U); + old_sampled = ((uintptr_t)old_tctx > (uintptr_t)1U); + + if (unlikely(sampled)) + prof_malloc_sample_object(tsd_tsdn(tsd), ptr, usize, tctx); + else + prof_tctx_reset(tsd_tsdn(tsd), ptr, usize, old_ptr, old_tctx); + + if (unlikely(old_sampled)) + prof_free_sampled_object(tsd, old_usize, old_tctx); +} + +JEMALLOC_ALWAYS_INLINE void +prof_free(tsd_t *tsd, const void *ptr, size_t usize) +{ + prof_tctx_t *tctx = prof_tctx_get(tsd_tsdn(tsd), ptr); + + cassert(config_prof); + assert(usize == isalloc(tsd_tsdn(tsd), ptr, true)); + + if (unlikely((uintptr_t)tctx > (uintptr_t)1U)) + prof_free_sampled_object(tsd, usize, tctx); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/public_namespace.h b/contrib/jemalloc/include/jemalloc/internal/public_namespace.h new file mode 100644 index 0000000..d5a4de8 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/public_namespace.h @@ -0,0 +1,21 @@ +#define je_malloc_conf JEMALLOC_N(malloc_conf) +#define je_malloc_message JEMALLOC_N(malloc_message) +#define je_malloc JEMALLOC_N(malloc) +#define je_calloc JEMALLOC_N(calloc) +#define je_posix_memalign JEMALLOC_N(posix_memalign) +#define je_aligned_alloc JEMALLOC_N(aligned_alloc) +#define je_realloc JEMALLOC_N(realloc) +#define je_free JEMALLOC_N(free) +#define je_mallocx JEMALLOC_N(mallocx) +#define je_rallocx JEMALLOC_N(rallocx) +#define je_xallocx JEMALLOC_N(xallocx) +#define je_sallocx JEMALLOC_N(sallocx) +#define je_dallocx JEMALLOC_N(dallocx) +#define je_sdallocx JEMALLOC_N(sdallocx) +#define je_nallocx JEMALLOC_N(nallocx) +#define je_mallctl JEMALLOC_N(mallctl) +#define je_mallctlnametomib JEMALLOC_N(mallctlnametomib) +#define je_mallctlbymib JEMALLOC_N(mallctlbymib) +#define je_malloc_stats_print JEMALLOC_N(malloc_stats_print) +#define je_malloc_usable_size JEMALLOC_N(malloc_usable_size) +#define je_valloc JEMALLOC_N(valloc) diff --git a/contrib/jemalloc/include/jemalloc/internal/ql.h b/contrib/jemalloc/include/jemalloc/internal/ql.h new file mode 100644 index 0000000..1834bb8 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/ql.h @@ -0,0 +1,81 @@ +/* List definitions. */ +#define ql_head(a_type) \ +struct { \ + a_type *qlh_first; \ +} + +#define ql_head_initializer(a_head) {NULL} + +#define ql_elm(a_type) qr(a_type) + +/* List functions. */ +#define ql_new(a_head) do { \ + (a_head)->qlh_first = NULL; \ +} while (0) + +#define ql_elm_new(a_elm, a_field) qr_new((a_elm), a_field) + +#define ql_first(a_head) ((a_head)->qlh_first) + +#define ql_last(a_head, a_field) \ + ((ql_first(a_head) != NULL) \ + ? qr_prev(ql_first(a_head), a_field) : NULL) + +#define ql_next(a_head, a_elm, a_field) \ + ((ql_last(a_head, a_field) != (a_elm)) \ + ? qr_next((a_elm), a_field) : NULL) + +#define ql_prev(a_head, a_elm, a_field) \ + ((ql_first(a_head) != (a_elm)) ? qr_prev((a_elm), a_field) \ + : NULL) + +#define ql_before_insert(a_head, a_qlelm, a_elm, a_field) do { \ + qr_before_insert((a_qlelm), (a_elm), a_field); \ + if (ql_first(a_head) == (a_qlelm)) { \ + ql_first(a_head) = (a_elm); \ + } \ +} while (0) + +#define ql_after_insert(a_qlelm, a_elm, a_field) \ + qr_after_insert((a_qlelm), (a_elm), a_field) + +#define ql_head_insert(a_head, a_elm, a_field) do { \ + if (ql_first(a_head) != NULL) { \ + qr_before_insert(ql_first(a_head), (a_elm), a_field); \ + } \ + ql_first(a_head) = (a_elm); \ +} while (0) + +#define ql_tail_insert(a_head, a_elm, a_field) do { \ + if (ql_first(a_head) != NULL) { \ + qr_before_insert(ql_first(a_head), (a_elm), a_field); \ + } \ + ql_first(a_head) = qr_next((a_elm), a_field); \ +} while (0) + +#define ql_remove(a_head, a_elm, a_field) do { \ + if (ql_first(a_head) == (a_elm)) { \ + ql_first(a_head) = qr_next(ql_first(a_head), a_field); \ + } \ + if (ql_first(a_head) != (a_elm)) { \ + qr_remove((a_elm), a_field); \ + } else { \ + ql_first(a_head) = NULL; \ + } \ +} while (0) + +#define ql_head_remove(a_head, a_type, a_field) do { \ + a_type *t = ql_first(a_head); \ + ql_remove((a_head), t, a_field); \ +} while (0) + +#define ql_tail_remove(a_head, a_type, a_field) do { \ + a_type *t = ql_last(a_head, a_field); \ + ql_remove((a_head), t, a_field); \ +} while (0) + +#define ql_foreach(a_var, a_head, a_field) \ + qr_foreach((a_var), ql_first(a_head), a_field) + +#define ql_reverse_foreach(a_var, a_head, a_field) \ + qr_reverse_foreach((a_var), ql_first(a_head), a_field) diff --git a/contrib/jemalloc/include/jemalloc/internal/qr.h b/contrib/jemalloc/include/jemalloc/internal/qr.h new file mode 100644 index 0000000..0fbaec2 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/qr.h @@ -0,0 +1,69 @@ +/* Ring definitions. */ +#define qr(a_type) \ +struct { \ + a_type *qre_next; \ + a_type *qre_prev; \ +} + +/* Ring functions. */ +#define qr_new(a_qr, a_field) do { \ + (a_qr)->a_field.qre_next = (a_qr); \ + (a_qr)->a_field.qre_prev = (a_qr); \ +} while (0) + +#define qr_next(a_qr, a_field) ((a_qr)->a_field.qre_next) + +#define qr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev) + +#define qr_before_insert(a_qrelm, a_qr, a_field) do { \ + (a_qr)->a_field.qre_prev = (a_qrelm)->a_field.qre_prev; \ + (a_qr)->a_field.qre_next = (a_qrelm); \ + (a_qr)->a_field.qre_prev->a_field.qre_next = (a_qr); \ + (a_qrelm)->a_field.qre_prev = (a_qr); \ +} while (0) + +#define qr_after_insert(a_qrelm, a_qr, a_field) \ + do \ + { \ + (a_qr)->a_field.qre_next = (a_qrelm)->a_field.qre_next; \ + (a_qr)->a_field.qre_prev = (a_qrelm); \ + (a_qr)->a_field.qre_next->a_field.qre_prev = (a_qr); \ + (a_qrelm)->a_field.qre_next = (a_qr); \ + } while (0) + +#define qr_meld(a_qr_a, a_qr_b, a_field) do { \ + void *t; \ + (a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b); \ + (a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a); \ + t = (a_qr_a)->a_field.qre_prev; \ + (a_qr_a)->a_field.qre_prev = (a_qr_b)->a_field.qre_prev; \ + (a_qr_b)->a_field.qre_prev = t; \ +} while (0) + +/* + * qr_meld() and qr_split() are functionally equivalent, so there's no need to + * have two copies of the code. + */ +#define qr_split(a_qr_a, a_qr_b, a_field) \ + qr_meld((a_qr_a), (a_qr_b), a_field) + +#define qr_remove(a_qr, a_field) do { \ + (a_qr)->a_field.qre_prev->a_field.qre_next \ + = (a_qr)->a_field.qre_next; \ + (a_qr)->a_field.qre_next->a_field.qre_prev \ + = (a_qr)->a_field.qre_prev; \ + (a_qr)->a_field.qre_next = (a_qr); \ + (a_qr)->a_field.qre_prev = (a_qr); \ +} while (0) + +#define qr_foreach(var, a_qr, a_field) \ + for ((var) = (a_qr); \ + (var) != NULL; \ + (var) = (((var)->a_field.qre_next != (a_qr)) \ + ? (var)->a_field.qre_next : NULL)) + +#define qr_reverse_foreach(var, a_qr, a_field) \ + for ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL; \ + (var) != NULL; \ + (var) = (((var) != (a_qr)) \ + ? (var)->a_field.qre_prev : NULL)) diff --git a/contrib/jemalloc/include/jemalloc/internal/quarantine.h b/contrib/jemalloc/include/jemalloc/internal/quarantine.h new file mode 100644 index 0000000..ae60739 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/quarantine.h @@ -0,0 +1,60 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct quarantine_obj_s quarantine_obj_t; +typedef struct quarantine_s quarantine_t; + +/* Default per thread quarantine size if valgrind is enabled. */ +#define JEMALLOC_VALGRIND_QUARANTINE_DEFAULT (ZU(1) << 24) + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct quarantine_obj_s { + void *ptr; + size_t usize; +}; + +struct quarantine_s { + size_t curbytes; + size_t curobjs; + size_t first; +#define LG_MAXOBJS_INIT 10 + size_t lg_maxobjs; + quarantine_obj_t objs[1]; /* Dynamically sized ring buffer. */ +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void quarantine_alloc_hook_work(tsd_t *tsd); +void quarantine(tsd_t *tsd, void *ptr); +void quarantine_cleanup(tsd_t *tsd); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +void quarantine_alloc_hook(void); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_QUARANTINE_C_)) +JEMALLOC_ALWAYS_INLINE void +quarantine_alloc_hook(void) +{ + tsd_t *tsd; + + assert(config_fill && opt_quarantine); + + tsd = tsd_fetch(); + if (tsd_quarantine_get(tsd) == NULL) + quarantine_alloc_hook_work(tsd); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ + diff --git a/contrib/jemalloc/include/jemalloc/internal/rb.h b/contrib/jemalloc/include/jemalloc/internal/rb.h new file mode 100644 index 0000000..3770342 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/rb.h @@ -0,0 +1,1003 @@ +/*- + ******************************************************************************* + * + * cpp macro implementation of left-leaning 2-3 red-black trees. Parent + * pointers are not used, and color bits are stored in the least significant + * bit of right-child pointers (if RB_COMPACT is defined), thus making node + * linkage as compact as is possible for red-black trees. + * + * Usage: + * + * #include + * #include + * #define NDEBUG // (Optional, see assert(3).) + * #include + * #define RB_COMPACT // (Optional, embed color bits in right-child pointers.) + * #include + * ... + * + ******************************************************************************* + */ + +#ifndef RB_H_ +#define RB_H_ + +#ifdef RB_COMPACT +/* Node structure. */ +#define rb_node(a_type) \ +struct { \ + a_type *rbn_left; \ + a_type *rbn_right_red; \ +} +#else +#define rb_node(a_type) \ +struct { \ + a_type *rbn_left; \ + a_type *rbn_right; \ + bool rbn_red; \ +} +#endif + +/* Root structure. */ +#define rb_tree(a_type) \ +struct { \ + a_type *rbt_root; \ +} + +/* Left accessors. */ +#define rbtn_left_get(a_type, a_field, a_node) \ + ((a_node)->a_field.rbn_left) +#define rbtn_left_set(a_type, a_field, a_node, a_left) do { \ + (a_node)->a_field.rbn_left = a_left; \ +} while (0) + +#ifdef RB_COMPACT +/* Right accessors. */ +#define rbtn_right_get(a_type, a_field, a_node) \ + ((a_type *) (((intptr_t) (a_node)->a_field.rbn_right_red) \ + & ((ssize_t)-2))) +#define rbtn_right_set(a_type, a_field, a_node, a_right) do { \ + (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) a_right) \ + | (((uintptr_t) (a_node)->a_field.rbn_right_red) & ((size_t)1))); \ +} while (0) + +/* Color accessors. */ +#define rbtn_red_get(a_type, a_field, a_node) \ + ((bool) (((uintptr_t) (a_node)->a_field.rbn_right_red) \ + & ((size_t)1))) +#define rbtn_color_set(a_type, a_field, a_node, a_red) do { \ + (a_node)->a_field.rbn_right_red = (a_type *) ((((intptr_t) \ + (a_node)->a_field.rbn_right_red) & ((ssize_t)-2)) \ + | ((ssize_t)a_red)); \ +} while (0) +#define rbtn_red_set(a_type, a_field, a_node) do { \ + (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) \ + (a_node)->a_field.rbn_right_red) | ((size_t)1)); \ +} while (0) +#define rbtn_black_set(a_type, a_field, a_node) do { \ + (a_node)->a_field.rbn_right_red = (a_type *) (((intptr_t) \ + (a_node)->a_field.rbn_right_red) & ((ssize_t)-2)); \ +} while (0) + +/* Node initializer. */ +#define rbt_node_new(a_type, a_field, a_rbt, a_node) do { \ + /* Bookkeeping bit cannot be used by node pointer. */ \ + assert(((uintptr_t)(a_node) & 0x1) == 0); \ + rbtn_left_set(a_type, a_field, (a_node), NULL); \ + rbtn_right_set(a_type, a_field, (a_node), NULL); \ + rbtn_red_set(a_type, a_field, (a_node)); \ +} while (0) +#else +/* Right accessors. */ +#define rbtn_right_get(a_type, a_field, a_node) \ + ((a_node)->a_field.rbn_right) +#define rbtn_right_set(a_type, a_field, a_node, a_right) do { \ + (a_node)->a_field.rbn_right = a_right; \ +} while (0) + +/* Color accessors. */ +#define rbtn_red_get(a_type, a_field, a_node) \ + ((a_node)->a_field.rbn_red) +#define rbtn_color_set(a_type, a_field, a_node, a_red) do { \ + (a_node)->a_field.rbn_red = (a_red); \ +} while (0) +#define rbtn_red_set(a_type, a_field, a_node) do { \ + (a_node)->a_field.rbn_red = true; \ +} while (0) +#define rbtn_black_set(a_type, a_field, a_node) do { \ + (a_node)->a_field.rbn_red = false; \ +} while (0) + +/* Node initializer. */ +#define rbt_node_new(a_type, a_field, a_rbt, a_node) do { \ + rbtn_left_set(a_type, a_field, (a_node), NULL); \ + rbtn_right_set(a_type, a_field, (a_node), NULL); \ + rbtn_red_set(a_type, a_field, (a_node)); \ +} while (0) +#endif + +/* Tree initializer. */ +#define rb_new(a_type, a_field, a_rbt) do { \ + (a_rbt)->rbt_root = NULL; \ +} while (0) + +/* Internal utility macros. */ +#define rbtn_first(a_type, a_field, a_rbt, a_root, r_node) do { \ + (r_node) = (a_root); \ + if ((r_node) != NULL) { \ + for (; \ + rbtn_left_get(a_type, a_field, (r_node)) != NULL; \ + (r_node) = rbtn_left_get(a_type, a_field, (r_node))) { \ + } \ + } \ +} while (0) + +#define rbtn_last(a_type, a_field, a_rbt, a_root, r_node) do { \ + (r_node) = (a_root); \ + if ((r_node) != NULL) { \ + for (; rbtn_right_get(a_type, a_field, (r_node)) != NULL; \ + (r_node) = rbtn_right_get(a_type, a_field, (r_node))) { \ + } \ + } \ +} while (0) + +#define rbtn_rotate_left(a_type, a_field, a_node, r_node) do { \ + (r_node) = rbtn_right_get(a_type, a_field, (a_node)); \ + rbtn_right_set(a_type, a_field, (a_node), \ + rbtn_left_get(a_type, a_field, (r_node))); \ + rbtn_left_set(a_type, a_field, (r_node), (a_node)); \ +} while (0) + +#define rbtn_rotate_right(a_type, a_field, a_node, r_node) do { \ + (r_node) = rbtn_left_get(a_type, a_field, (a_node)); \ + rbtn_left_set(a_type, a_field, (a_node), \ + rbtn_right_get(a_type, a_field, (r_node))); \ + rbtn_right_set(a_type, a_field, (r_node), (a_node)); \ +} while (0) + +/* + * The rb_proto() macro generates function prototypes that correspond to the + * functions generated by an equivalently parameterized call to rb_gen(). + */ + +#define rb_proto(a_attr, a_prefix, a_rbt_type, a_type) \ +a_attr void \ +a_prefix##new(a_rbt_type *rbtree); \ +a_attr bool \ +a_prefix##empty(a_rbt_type *rbtree); \ +a_attr a_type * \ +a_prefix##first(a_rbt_type *rbtree); \ +a_attr a_type * \ +a_prefix##last(a_rbt_type *rbtree); \ +a_attr a_type * \ +a_prefix##next(a_rbt_type *rbtree, a_type *node); \ +a_attr a_type * \ +a_prefix##prev(a_rbt_type *rbtree, a_type *node); \ +a_attr a_type * \ +a_prefix##search(a_rbt_type *rbtree, const a_type *key); \ +a_attr a_type * \ +a_prefix##nsearch(a_rbt_type *rbtree, const a_type *key); \ +a_attr a_type * \ +a_prefix##psearch(a_rbt_type *rbtree, const a_type *key); \ +a_attr void \ +a_prefix##insert(a_rbt_type *rbtree, a_type *node); \ +a_attr void \ +a_prefix##remove(a_rbt_type *rbtree, a_type *node); \ +a_attr a_type * \ +a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)( \ + a_rbt_type *, a_type *, void *), void *arg); \ +a_attr a_type * \ +a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start, \ + a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg); \ +a_attr void \ +a_prefix##destroy(a_rbt_type *rbtree, void (*cb)(a_type *, void *), \ + void *arg); + +/* + * The rb_gen() macro generates a type-specific red-black tree implementation, + * based on the above cpp macros. + * + * Arguments: + * + * a_attr : Function attribute for generated functions (ex: static). + * a_prefix : Prefix for generated functions (ex: ex_). + * a_rb_type : Type for red-black tree data structure (ex: ex_t). + * a_type : Type for red-black tree node data structure (ex: ex_node_t). + * a_field : Name of red-black tree node linkage (ex: ex_link). + * a_cmp : Node comparison function name, with the following prototype: + * int (a_cmp *)(a_type *a_node, a_type *a_other); + * ^^^^^^ + * or a_key + * Interpretation of comparison function return values: + * -1 : a_node < a_other + * 0 : a_node == a_other + * 1 : a_node > a_other + * In all cases, the a_node or a_key macro argument is the first + * argument to the comparison function, which makes it possible + * to write comparison functions that treat the first argument + * specially. + * + * Assuming the following setup: + * + * typedef struct ex_node_s ex_node_t; + * struct ex_node_s { + * rb_node(ex_node_t) ex_link; + * }; + * typedef rb_tree(ex_node_t) ex_t; + * rb_gen(static, ex_, ex_t, ex_node_t, ex_link, ex_cmp) + * + * The following API is generated: + * + * static void + * ex_new(ex_t *tree); + * Description: Initialize a red-black tree structure. + * Args: + * tree: Pointer to an uninitialized red-black tree object. + * + * static bool + * ex_empty(ex_t *tree); + * Description: Determine whether tree is empty. + * Args: + * tree: Pointer to an initialized red-black tree object. + * Ret: True if tree is empty, false otherwise. + * + * static ex_node_t * + * ex_first(ex_t *tree); + * static ex_node_t * + * ex_last(ex_t *tree); + * Description: Get the first/last node in tree. + * Args: + * tree: Pointer to an initialized red-black tree object. + * Ret: First/last node in tree, or NULL if tree is empty. + * + * static ex_node_t * + * ex_next(ex_t *tree, ex_node_t *node); + * static ex_node_t * + * ex_prev(ex_t *tree, ex_node_t *node); + * Description: Get node's successor/predecessor. + * Args: + * tree: Pointer to an initialized red-black tree object. + * node: A node in tree. + * Ret: node's successor/predecessor in tree, or NULL if node is + * last/first. + * + * static ex_node_t * + * ex_search(ex_t *tree, const ex_node_t *key); + * Description: Search for node that matches key. + * Args: + * tree: Pointer to an initialized red-black tree object. + * key : Search key. + * Ret: Node in tree that matches key, or NULL if no match. + * + * static ex_node_t * + * ex_nsearch(ex_t *tree, const ex_node_t *key); + * static ex_node_t * + * ex_psearch(ex_t *tree, const ex_node_t *key); + * Description: Search for node that matches key. If no match is found, + * return what would be key's successor/predecessor, were + * key in tree. + * Args: + * tree: Pointer to an initialized red-black tree object. + * key : Search key. + * Ret: Node in tree that matches key, or if no match, hypothetical node's + * successor/predecessor (NULL if no successor/predecessor). + * + * static void + * ex_insert(ex_t *tree, ex_node_t *node); + * Description: Insert node into tree. + * Args: + * tree: Pointer to an initialized red-black tree object. + * node: Node to be inserted into tree. + * + * static void + * ex_remove(ex_t *tree, ex_node_t *node); + * Description: Remove node from tree. + * Args: + * tree: Pointer to an initialized red-black tree object. + * node: Node in tree to be removed. + * + * static ex_node_t * + * ex_iter(ex_t *tree, ex_node_t *start, ex_node_t *(*cb)(ex_t *, + * ex_node_t *, void *), void *arg); + * static ex_node_t * + * ex_reverse_iter(ex_t *tree, ex_node_t *start, ex_node *(*cb)(ex_t *, + * ex_node_t *, void *), void *arg); + * Description: Iterate forward/backward over tree, starting at node. If + * tree is modified, iteration must be immediately + * terminated by the callback function that causes the + * modification. + * Args: + * tree : Pointer to an initialized red-black tree object. + * start: Node at which to start iteration, or NULL to start at + * first/last node. + * cb : Callback function, which is called for each node during + * iteration. Under normal circumstances the callback function + * should return NULL, which causes iteration to continue. If a + * callback function returns non-NULL, iteration is immediately + * terminated and the non-NULL return value is returned by the + * iterator. This is useful for re-starting iteration after + * modifying tree. + * arg : Opaque pointer passed to cb(). + * Ret: NULL if iteration completed, or the non-NULL callback return value + * that caused termination of the iteration. + * + * static void + * ex_destroy(ex_t *tree, void (*cb)(ex_node_t *, void *), void *arg); + * Description: Iterate over the tree with post-order traversal, remove + * each node, and run the callback if non-null. This is + * used for destroying a tree without paying the cost to + * rebalance it. The tree must not be otherwise altered + * during traversal. + * Args: + * tree: Pointer to an initialized red-black tree object. + * cb : Callback function, which, if non-null, is called for each node + * during iteration. There is no way to stop iteration once it + * has begun. + * arg : Opaque pointer passed to cb(). + */ +#define rb_gen(a_attr, a_prefix, a_rbt_type, a_type, a_field, a_cmp) \ +a_attr void \ +a_prefix##new(a_rbt_type *rbtree) { \ + rb_new(a_type, a_field, rbtree); \ +} \ +a_attr bool \ +a_prefix##empty(a_rbt_type *rbtree) { \ + return (rbtree->rbt_root == NULL); \ +} \ +a_attr a_type * \ +a_prefix##first(a_rbt_type *rbtree) { \ + a_type *ret; \ + rbtn_first(a_type, a_field, rbtree, rbtree->rbt_root, ret); \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##last(a_rbt_type *rbtree) { \ + a_type *ret; \ + rbtn_last(a_type, a_field, rbtree, rbtree->rbt_root, ret); \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##next(a_rbt_type *rbtree, a_type *node) { \ + a_type *ret; \ + if (rbtn_right_get(a_type, a_field, node) != NULL) { \ + rbtn_first(a_type, a_field, rbtree, rbtn_right_get(a_type, \ + a_field, node), ret); \ + } else { \ + a_type *tnode = rbtree->rbt_root; \ + assert(tnode != NULL); \ + ret = NULL; \ + while (true) { \ + int cmp = (a_cmp)(node, tnode); \ + if (cmp < 0) { \ + ret = tnode; \ + tnode = rbtn_left_get(a_type, a_field, tnode); \ + } else if (cmp > 0) { \ + tnode = rbtn_right_get(a_type, a_field, tnode); \ + } else { \ + break; \ + } \ + assert(tnode != NULL); \ + } \ + } \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##prev(a_rbt_type *rbtree, a_type *node) { \ + a_type *ret; \ + if (rbtn_left_get(a_type, a_field, node) != NULL) { \ + rbtn_last(a_type, a_field, rbtree, rbtn_left_get(a_type, \ + a_field, node), ret); \ + } else { \ + a_type *tnode = rbtree->rbt_root; \ + assert(tnode != NULL); \ + ret = NULL; \ + while (true) { \ + int cmp = (a_cmp)(node, tnode); \ + if (cmp < 0) { \ + tnode = rbtn_left_get(a_type, a_field, tnode); \ + } else if (cmp > 0) { \ + ret = tnode; \ + tnode = rbtn_right_get(a_type, a_field, tnode); \ + } else { \ + break; \ + } \ + assert(tnode != NULL); \ + } \ + } \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##search(a_rbt_type *rbtree, const a_type *key) { \ + a_type *ret; \ + int cmp; \ + ret = rbtree->rbt_root; \ + while (ret != NULL \ + && (cmp = (a_cmp)(key, ret)) != 0) { \ + if (cmp < 0) { \ + ret = rbtn_left_get(a_type, a_field, ret); \ + } else { \ + ret = rbtn_right_get(a_type, a_field, ret); \ + } \ + } \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##nsearch(a_rbt_type *rbtree, const a_type *key) { \ + a_type *ret; \ + a_type *tnode = rbtree->rbt_root; \ + ret = NULL; \ + while (tnode != NULL) { \ + int cmp = (a_cmp)(key, tnode); \ + if (cmp < 0) { \ + ret = tnode; \ + tnode = rbtn_left_get(a_type, a_field, tnode); \ + } else if (cmp > 0) { \ + tnode = rbtn_right_get(a_type, a_field, tnode); \ + } else { \ + ret = tnode; \ + break; \ + } \ + } \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##psearch(a_rbt_type *rbtree, const a_type *key) { \ + a_type *ret; \ + a_type *tnode = rbtree->rbt_root; \ + ret = NULL; \ + while (tnode != NULL) { \ + int cmp = (a_cmp)(key, tnode); \ + if (cmp < 0) { \ + tnode = rbtn_left_get(a_type, a_field, tnode); \ + } else if (cmp > 0) { \ + ret = tnode; \ + tnode = rbtn_right_get(a_type, a_field, tnode); \ + } else { \ + ret = tnode; \ + break; \ + } \ + } \ + return (ret); \ +} \ +a_attr void \ +a_prefix##insert(a_rbt_type *rbtree, a_type *node) { \ + struct { \ + a_type *node; \ + int cmp; \ + } path[sizeof(void *) << 4], *pathp; \ + rbt_node_new(a_type, a_field, rbtree, node); \ + /* Wind. */ \ + path->node = rbtree->rbt_root; \ + for (pathp = path; pathp->node != NULL; pathp++) { \ + int cmp = pathp->cmp = a_cmp(node, pathp->node); \ + assert(cmp != 0); \ + if (cmp < 0) { \ + pathp[1].node = rbtn_left_get(a_type, a_field, \ + pathp->node); \ + } else { \ + pathp[1].node = rbtn_right_get(a_type, a_field, \ + pathp->node); \ + } \ + } \ + pathp->node = node; \ + /* Unwind. */ \ + for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) { \ + a_type *cnode = pathp->node; \ + if (pathp->cmp < 0) { \ + a_type *left = pathp[1].node; \ + rbtn_left_set(a_type, a_field, cnode, left); \ + if (rbtn_red_get(a_type, a_field, left)) { \ + a_type *leftleft = rbtn_left_get(a_type, a_field, left);\ + if (leftleft != NULL && rbtn_red_get(a_type, a_field, \ + leftleft)) { \ + /* Fix up 4-node. */ \ + a_type *tnode; \ + rbtn_black_set(a_type, a_field, leftleft); \ + rbtn_rotate_right(a_type, a_field, cnode, tnode); \ + cnode = tnode; \ + } \ + } else { \ + return; \ + } \ + } else { \ + a_type *right = pathp[1].node; \ + rbtn_right_set(a_type, a_field, cnode, right); \ + if (rbtn_red_get(a_type, a_field, right)) { \ + a_type *left = rbtn_left_get(a_type, a_field, cnode); \ + if (left != NULL && rbtn_red_get(a_type, a_field, \ + left)) { \ + /* Split 4-node. */ \ + rbtn_black_set(a_type, a_field, left); \ + rbtn_black_set(a_type, a_field, right); \ + rbtn_red_set(a_type, a_field, cnode); \ + } else { \ + /* Lean left. */ \ + a_type *tnode; \ + bool tred = rbtn_red_get(a_type, a_field, cnode); \ + rbtn_rotate_left(a_type, a_field, cnode, tnode); \ + rbtn_color_set(a_type, a_field, tnode, tred); \ + rbtn_red_set(a_type, a_field, cnode); \ + cnode = tnode; \ + } \ + } else { \ + return; \ + } \ + } \ + pathp->node = cnode; \ + } \ + /* Set root, and make it black. */ \ + rbtree->rbt_root = path->node; \ + rbtn_black_set(a_type, a_field, rbtree->rbt_root); \ +} \ +a_attr void \ +a_prefix##remove(a_rbt_type *rbtree, a_type *node) { \ + struct { \ + a_type *node; \ + int cmp; \ + } *pathp, *nodep, path[sizeof(void *) << 4]; \ + /* Wind. */ \ + nodep = NULL; /* Silence compiler warning. */ \ + path->node = rbtree->rbt_root; \ + for (pathp = path; pathp->node != NULL; pathp++) { \ + int cmp = pathp->cmp = a_cmp(node, pathp->node); \ + if (cmp < 0) { \ + pathp[1].node = rbtn_left_get(a_type, a_field, \ + pathp->node); \ + } else { \ + pathp[1].node = rbtn_right_get(a_type, a_field, \ + pathp->node); \ + if (cmp == 0) { \ + /* Find node's successor, in preparation for swap. */ \ + pathp->cmp = 1; \ + nodep = pathp; \ + for (pathp++; pathp->node != NULL; \ + pathp++) { \ + pathp->cmp = -1; \ + pathp[1].node = rbtn_left_get(a_type, a_field, \ + pathp->node); \ + } \ + break; \ + } \ + } \ + } \ + assert(nodep->node == node); \ + pathp--; \ + if (pathp->node != node) { \ + /* Swap node with its successor. */ \ + bool tred = rbtn_red_get(a_type, a_field, pathp->node); \ + rbtn_color_set(a_type, a_field, pathp->node, \ + rbtn_red_get(a_type, a_field, node)); \ + rbtn_left_set(a_type, a_field, pathp->node, \ + rbtn_left_get(a_type, a_field, node)); \ + /* If node's successor is its right child, the following code */\ + /* will do the wrong thing for the right child pointer. */\ + /* However, it doesn't matter, because the pointer will be */\ + /* properly set when the successor is pruned. */\ + rbtn_right_set(a_type, a_field, pathp->node, \ + rbtn_right_get(a_type, a_field, node)); \ + rbtn_color_set(a_type, a_field, node, tred); \ + /* The pruned leaf node's child pointers are never accessed */\ + /* again, so don't bother setting them to nil. */\ + nodep->node = pathp->node; \ + pathp->node = node; \ + if (nodep == path) { \ + rbtree->rbt_root = nodep->node; \ + } else { \ + if (nodep[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, nodep[-1].node, \ + nodep->node); \ + } else { \ + rbtn_right_set(a_type, a_field, nodep[-1].node, \ + nodep->node); \ + } \ + } \ + } else { \ + a_type *left = rbtn_left_get(a_type, a_field, node); \ + if (left != NULL) { \ + /* node has no successor, but it has a left child. */\ + /* Splice node out, without losing the left child. */\ + assert(!rbtn_red_get(a_type, a_field, node)); \ + assert(rbtn_red_get(a_type, a_field, left)); \ + rbtn_black_set(a_type, a_field, left); \ + if (pathp == path) { \ + rbtree->rbt_root = left; \ + } else { \ + if (pathp[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, pathp[-1].node, \ + left); \ + } else { \ + rbtn_right_set(a_type, a_field, pathp[-1].node, \ + left); \ + } \ + } \ + return; \ + } else if (pathp == path) { \ + /* The tree only contained one node. */ \ + rbtree->rbt_root = NULL; \ + return; \ + } \ + } \ + if (rbtn_red_get(a_type, a_field, pathp->node)) { \ + /* Prune red node, which requires no fixup. */ \ + assert(pathp[-1].cmp < 0); \ + rbtn_left_set(a_type, a_field, pathp[-1].node, NULL); \ + return; \ + } \ + /* The node to be pruned is black, so unwind until balance is */\ + /* restored. */\ + pathp->node = NULL; \ + for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) { \ + assert(pathp->cmp != 0); \ + if (pathp->cmp < 0) { \ + rbtn_left_set(a_type, a_field, pathp->node, \ + pathp[1].node); \ + if (rbtn_red_get(a_type, a_field, pathp->node)) { \ + a_type *right = rbtn_right_get(a_type, a_field, \ + pathp->node); \ + a_type *rightleft = rbtn_left_get(a_type, a_field, \ + right); \ + a_type *tnode; \ + if (rightleft != NULL && rbtn_red_get(a_type, a_field, \ + rightleft)) { \ + /* In the following diagrams, ||, //, and \\ */\ + /* indicate the path to the removed node. */\ + /* */\ + /* || */\ + /* pathp(r) */\ + /* // \ */\ + /* (b) (b) */\ + /* / */\ + /* (r) */\ + /* */\ + rbtn_black_set(a_type, a_field, pathp->node); \ + rbtn_rotate_right(a_type, a_field, right, tnode); \ + rbtn_right_set(a_type, a_field, pathp->node, tnode);\ + rbtn_rotate_left(a_type, a_field, pathp->node, \ + tnode); \ + } else { \ + /* || */\ + /* pathp(r) */\ + /* // \ */\ + /* (b) (b) */\ + /* / */\ + /* (b) */\ + /* */\ + rbtn_rotate_left(a_type, a_field, pathp->node, \ + tnode); \ + } \ + /* Balance restored, but rotation modified subtree */\ + /* root. */\ + assert((uintptr_t)pathp > (uintptr_t)path); \ + if (pathp[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, pathp[-1].node, \ + tnode); \ + } else { \ + rbtn_right_set(a_type, a_field, pathp[-1].node, \ + tnode); \ + } \ + return; \ + } else { \ + a_type *right = rbtn_right_get(a_type, a_field, \ + pathp->node); \ + a_type *rightleft = rbtn_left_get(a_type, a_field, \ + right); \ + if (rightleft != NULL && rbtn_red_get(a_type, a_field, \ + rightleft)) { \ + /* || */\ + /* pathp(b) */\ + /* // \ */\ + /* (b) (b) */\ + /* / */\ + /* (r) */\ + a_type *tnode; \ + rbtn_black_set(a_type, a_field, rightleft); \ + rbtn_rotate_right(a_type, a_field, right, tnode); \ + rbtn_right_set(a_type, a_field, pathp->node, tnode);\ + rbtn_rotate_left(a_type, a_field, pathp->node, \ + tnode); \ + /* Balance restored, but rotation modified */\ + /* subtree root, which may actually be the tree */\ + /* root. */\ + if (pathp == path) { \ + /* Set root. */ \ + rbtree->rbt_root = tnode; \ + } else { \ + if (pathp[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, \ + pathp[-1].node, tnode); \ + } else { \ + rbtn_right_set(a_type, a_field, \ + pathp[-1].node, tnode); \ + } \ + } \ + return; \ + } else { \ + /* || */\ + /* pathp(b) */\ + /* // \ */\ + /* (b) (b) */\ + /* / */\ + /* (b) */\ + a_type *tnode; \ + rbtn_red_set(a_type, a_field, pathp->node); \ + rbtn_rotate_left(a_type, a_field, pathp->node, \ + tnode); \ + pathp->node = tnode; \ + } \ + } \ + } else { \ + a_type *left; \ + rbtn_right_set(a_type, a_field, pathp->node, \ + pathp[1].node); \ + left = rbtn_left_get(a_type, a_field, pathp->node); \ + if (rbtn_red_get(a_type, a_field, left)) { \ + a_type *tnode; \ + a_type *leftright = rbtn_right_get(a_type, a_field, \ + left); \ + a_type *leftrightleft = rbtn_left_get(a_type, a_field, \ + leftright); \ + if (leftrightleft != NULL && rbtn_red_get(a_type, \ + a_field, leftrightleft)) { \ + /* || */\ + /* pathp(b) */\ + /* / \\ */\ + /* (r) (b) */\ + /* \ */\ + /* (b) */\ + /* / */\ + /* (r) */\ + a_type *unode; \ + rbtn_black_set(a_type, a_field, leftrightleft); \ + rbtn_rotate_right(a_type, a_field, pathp->node, \ + unode); \ + rbtn_rotate_right(a_type, a_field, pathp->node, \ + tnode); \ + rbtn_right_set(a_type, a_field, unode, tnode); \ + rbtn_rotate_left(a_type, a_field, unode, tnode); \ + } else { \ + /* || */\ + /* pathp(b) */\ + /* / \\ */\ + /* (r) (b) */\ + /* \ */\ + /* (b) */\ + /* / */\ + /* (b) */\ + assert(leftright != NULL); \ + rbtn_red_set(a_type, a_field, leftright); \ + rbtn_rotate_right(a_type, a_field, pathp->node, \ + tnode); \ + rbtn_black_set(a_type, a_field, tnode); \ + } \ + /* Balance restored, but rotation modified subtree */\ + /* root, which may actually be the tree root. */\ + if (pathp == path) { \ + /* Set root. */ \ + rbtree->rbt_root = tnode; \ + } else { \ + if (pathp[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, pathp[-1].node, \ + tnode); \ + } else { \ + rbtn_right_set(a_type, a_field, pathp[-1].node, \ + tnode); \ + } \ + } \ + return; \ + } else if (rbtn_red_get(a_type, a_field, pathp->node)) { \ + a_type *leftleft = rbtn_left_get(a_type, a_field, left);\ + if (leftleft != NULL && rbtn_red_get(a_type, a_field, \ + leftleft)) { \ + /* || */\ + /* pathp(r) */\ + /* / \\ */\ + /* (b) (b) */\ + /* / */\ + /* (r) */\ + a_type *tnode; \ + rbtn_black_set(a_type, a_field, pathp->node); \ + rbtn_red_set(a_type, a_field, left); \ + rbtn_black_set(a_type, a_field, leftleft); \ + rbtn_rotate_right(a_type, a_field, pathp->node, \ + tnode); \ + /* Balance restored, but rotation modified */\ + /* subtree root. */\ + assert((uintptr_t)pathp > (uintptr_t)path); \ + if (pathp[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, pathp[-1].node, \ + tnode); \ + } else { \ + rbtn_right_set(a_type, a_field, pathp[-1].node, \ + tnode); \ + } \ + return; \ + } else { \ + /* || */\ + /* pathp(r) */\ + /* / \\ */\ + /* (b) (b) */\ + /* / */\ + /* (b) */\ + rbtn_red_set(a_type, a_field, left); \ + rbtn_black_set(a_type, a_field, pathp->node); \ + /* Balance restored. */ \ + return; \ + } \ + } else { \ + a_type *leftleft = rbtn_left_get(a_type, a_field, left);\ + if (leftleft != NULL && rbtn_red_get(a_type, a_field, \ + leftleft)) { \ + /* || */\ + /* pathp(b) */\ + /* / \\ */\ + /* (b) (b) */\ + /* / */\ + /* (r) */\ + a_type *tnode; \ + rbtn_black_set(a_type, a_field, leftleft); \ + rbtn_rotate_right(a_type, a_field, pathp->node, \ + tnode); \ + /* Balance restored, but rotation modified */\ + /* subtree root, which may actually be the tree */\ + /* root. */\ + if (pathp == path) { \ + /* Set root. */ \ + rbtree->rbt_root = tnode; \ + } else { \ + if (pathp[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, \ + pathp[-1].node, tnode); \ + } else { \ + rbtn_right_set(a_type, a_field, \ + pathp[-1].node, tnode); \ + } \ + } \ + return; \ + } else { \ + /* || */\ + /* pathp(b) */\ + /* / \\ */\ + /* (b) (b) */\ + /* / */\ + /* (b) */\ + rbtn_red_set(a_type, a_field, left); \ + } \ + } \ + } \ + } \ + /* Set root. */ \ + rbtree->rbt_root = path->node; \ + assert(!rbtn_red_get(a_type, a_field, rbtree->rbt_root)); \ +} \ +a_attr a_type * \ +a_prefix##iter_recurse(a_rbt_type *rbtree, a_type *node, \ + a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ + if (node == NULL) { \ + return (NULL); \ + } else { \ + a_type *ret; \ + if ((ret = a_prefix##iter_recurse(rbtree, rbtn_left_get(a_type, \ + a_field, node), cb, arg)) != NULL || (ret = cb(rbtree, node, \ + arg)) != NULL) { \ + return (ret); \ + } \ + return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \ + a_field, node), cb, arg)); \ + } \ +} \ +a_attr a_type * \ +a_prefix##iter_start(a_rbt_type *rbtree, a_type *start, a_type *node, \ + a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ + int cmp = a_cmp(start, node); \ + if (cmp < 0) { \ + a_type *ret; \ + if ((ret = a_prefix##iter_start(rbtree, start, \ + rbtn_left_get(a_type, a_field, node), cb, arg)) != NULL || \ + (ret = cb(rbtree, node, arg)) != NULL) { \ + return (ret); \ + } \ + return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \ + a_field, node), cb, arg)); \ + } else if (cmp > 0) { \ + return (a_prefix##iter_start(rbtree, start, \ + rbtn_right_get(a_type, a_field, node), cb, arg)); \ + } else { \ + a_type *ret; \ + if ((ret = cb(rbtree, node, arg)) != NULL) { \ + return (ret); \ + } \ + return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \ + a_field, node), cb, arg)); \ + } \ +} \ +a_attr a_type * \ +a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)( \ + a_rbt_type *, a_type *, void *), void *arg) { \ + a_type *ret; \ + if (start != NULL) { \ + ret = a_prefix##iter_start(rbtree, start, rbtree->rbt_root, \ + cb, arg); \ + } else { \ + ret = a_prefix##iter_recurse(rbtree, rbtree->rbt_root, cb, arg);\ + } \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##reverse_iter_recurse(a_rbt_type *rbtree, a_type *node, \ + a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ + if (node == NULL) { \ + return (NULL); \ + } else { \ + a_type *ret; \ + if ((ret = a_prefix##reverse_iter_recurse(rbtree, \ + rbtn_right_get(a_type, a_field, node), cb, arg)) != NULL || \ + (ret = cb(rbtree, node, arg)) != NULL) { \ + return (ret); \ + } \ + return (a_prefix##reverse_iter_recurse(rbtree, \ + rbtn_left_get(a_type, a_field, node), cb, arg)); \ + } \ +} \ +a_attr a_type * \ +a_prefix##reverse_iter_start(a_rbt_type *rbtree, a_type *start, \ + a_type *node, a_type *(*cb)(a_rbt_type *, a_type *, void *), \ + void *arg) { \ + int cmp = a_cmp(start, node); \ + if (cmp > 0) { \ + a_type *ret; \ + if ((ret = a_prefix##reverse_iter_start(rbtree, start, \ + rbtn_right_get(a_type, a_field, node), cb, arg)) != NULL || \ + (ret = cb(rbtree, node, arg)) != NULL) { \ + return (ret); \ + } \ + return (a_prefix##reverse_iter_recurse(rbtree, \ + rbtn_left_get(a_type, a_field, node), cb, arg)); \ + } else if (cmp < 0) { \ + return (a_prefix##reverse_iter_start(rbtree, start, \ + rbtn_left_get(a_type, a_field, node), cb, arg)); \ + } else { \ + a_type *ret; \ + if ((ret = cb(rbtree, node, arg)) != NULL) { \ + return (ret); \ + } \ + return (a_prefix##reverse_iter_recurse(rbtree, \ + rbtn_left_get(a_type, a_field, node), cb, arg)); \ + } \ +} \ +a_attr a_type * \ +a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start, \ + a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ + a_type *ret; \ + if (start != NULL) { \ + ret = a_prefix##reverse_iter_start(rbtree, start, \ + rbtree->rbt_root, cb, arg); \ + } else { \ + ret = a_prefix##reverse_iter_recurse(rbtree, rbtree->rbt_root, \ + cb, arg); \ + } \ + return (ret); \ +} \ +a_attr void \ +a_prefix##destroy_recurse(a_rbt_type *rbtree, a_type *node, void (*cb)( \ + a_type *, void *), void *arg) { \ + if (node == NULL) { \ + return; \ + } \ + a_prefix##destroy_recurse(rbtree, rbtn_left_get(a_type, a_field, \ + node), cb, arg); \ + rbtn_left_set(a_type, a_field, (node), NULL); \ + a_prefix##destroy_recurse(rbtree, rbtn_right_get(a_type, a_field, \ + node), cb, arg); \ + rbtn_right_set(a_type, a_field, (node), NULL); \ + if (cb) { \ + cb(node, arg); \ + } \ +} \ +a_attr void \ +a_prefix##destroy(a_rbt_type *rbtree, void (*cb)(a_type *, void *), \ + void *arg) { \ + a_prefix##destroy_recurse(rbtree, rbtree->rbt_root, cb, arg); \ + rbtree->rbt_root = NULL; \ +} + +#endif /* RB_H_ */ diff --git a/contrib/jemalloc/include/jemalloc/internal/rtree.h b/contrib/jemalloc/include/jemalloc/internal/rtree.h new file mode 100644 index 0000000..8d0c584 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/rtree.h @@ -0,0 +1,366 @@ +/* + * This radix tree implementation is tailored to the singular purpose of + * associating metadata with chunks that are currently owned by jemalloc. + * + ******************************************************************************* + */ +#ifdef JEMALLOC_H_TYPES + +typedef struct rtree_node_elm_s rtree_node_elm_t; +typedef struct rtree_level_s rtree_level_t; +typedef struct rtree_s rtree_t; + +/* + * RTREE_BITS_PER_LEVEL must be a power of two that is no larger than the + * machine address width. + */ +#define LG_RTREE_BITS_PER_LEVEL 4 +#define RTREE_BITS_PER_LEVEL (1U << LG_RTREE_BITS_PER_LEVEL) +/* Maximum rtree height. */ +#define RTREE_HEIGHT_MAX \ + ((1U << (LG_SIZEOF_PTR+3)) / RTREE_BITS_PER_LEVEL) + +/* Used for two-stage lock-free node initialization. */ +#define RTREE_NODE_INITIALIZING ((rtree_node_elm_t *)0x1) + +/* + * The node allocation callback function's argument is the number of contiguous + * rtree_node_elm_t structures to allocate, and the resulting memory must be + * zeroed. + */ +typedef rtree_node_elm_t *(rtree_node_alloc_t)(size_t); +typedef void (rtree_node_dalloc_t)(rtree_node_elm_t *); + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct rtree_node_elm_s { + union { + void *pun; + rtree_node_elm_t *child; + extent_node_t *val; + }; +}; + +struct rtree_level_s { + /* + * A non-NULL subtree points to a subtree rooted along the hypothetical + * path to the leaf node corresponding to key 0. Depending on what keys + * have been used to store to the tree, an arbitrary combination of + * subtree pointers may remain NULL. + * + * Suppose keys comprise 48 bits, and LG_RTREE_BITS_PER_LEVEL is 4. + * This results in a 3-level tree, and the leftmost leaf can be directly + * accessed via subtrees[2], the subtree prefixed by 0x0000 (excluding + * 0x00000000) can be accessed via subtrees[1], and the remainder of the + * tree can be accessed via subtrees[0]. + * + * levels[0] : [ | 0x0001******** | 0x0002******** | ...] + * + * levels[1] : [ | 0x00000001**** | 0x00000002**** | ... ] + * + * levels[2] : [val(0x000000000000) | val(0x000000000001) | ...] + * + * This has practical implications on x64, which currently uses only the + * lower 47 bits of virtual address space in userland, thus leaving + * subtrees[0] unused and avoiding a level of tree traversal. + */ + union { + void *subtree_pun; + rtree_node_elm_t *subtree; + }; + /* Number of key bits distinguished by this level. */ + unsigned bits; + /* + * Cumulative number of key bits distinguished by traversing to + * corresponding tree level. + */ + unsigned cumbits; +}; + +struct rtree_s { + rtree_node_alloc_t *alloc; + rtree_node_dalloc_t *dalloc; + unsigned height; + /* + * Precomputed table used to convert from the number of leading 0 key + * bits to which subtree level to start at. + */ + unsigned start_level[RTREE_HEIGHT_MAX]; + rtree_level_t levels[RTREE_HEIGHT_MAX]; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +bool rtree_new(rtree_t *rtree, unsigned bits, rtree_node_alloc_t *alloc, + rtree_node_dalloc_t *dalloc); +void rtree_delete(rtree_t *rtree); +rtree_node_elm_t *rtree_subtree_read_hard(rtree_t *rtree, + unsigned level); +rtree_node_elm_t *rtree_child_read_hard(rtree_t *rtree, + rtree_node_elm_t *elm, unsigned level); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +unsigned rtree_start_level(rtree_t *rtree, uintptr_t key); +uintptr_t rtree_subkey(rtree_t *rtree, uintptr_t key, unsigned level); + +bool rtree_node_valid(rtree_node_elm_t *node); +rtree_node_elm_t *rtree_child_tryread(rtree_node_elm_t *elm, + bool dependent); +rtree_node_elm_t *rtree_child_read(rtree_t *rtree, rtree_node_elm_t *elm, + unsigned level, bool dependent); +extent_node_t *rtree_val_read(rtree_t *rtree, rtree_node_elm_t *elm, + bool dependent); +void rtree_val_write(rtree_t *rtree, rtree_node_elm_t *elm, + const extent_node_t *val); +rtree_node_elm_t *rtree_subtree_tryread(rtree_t *rtree, unsigned level, + bool dependent); +rtree_node_elm_t *rtree_subtree_read(rtree_t *rtree, unsigned level, + bool dependent); + +extent_node_t *rtree_get(rtree_t *rtree, uintptr_t key, bool dependent); +bool rtree_set(rtree_t *rtree, uintptr_t key, const extent_node_t *val); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_RTREE_C_)) +JEMALLOC_ALWAYS_INLINE unsigned +rtree_start_level(rtree_t *rtree, uintptr_t key) +{ + unsigned start_level; + + if (unlikely(key == 0)) + return (rtree->height - 1); + + start_level = rtree->start_level[lg_floor(key) >> + LG_RTREE_BITS_PER_LEVEL]; + assert(start_level < rtree->height); + return (start_level); +} + +JEMALLOC_ALWAYS_INLINE uintptr_t +rtree_subkey(rtree_t *rtree, uintptr_t key, unsigned level) +{ + + return ((key >> ((ZU(1) << (LG_SIZEOF_PTR+3)) - + rtree->levels[level].cumbits)) & ((ZU(1) << + rtree->levels[level].bits) - 1)); +} + +JEMALLOC_ALWAYS_INLINE bool +rtree_node_valid(rtree_node_elm_t *node) +{ + + return ((uintptr_t)node > (uintptr_t)RTREE_NODE_INITIALIZING); +} + +JEMALLOC_ALWAYS_INLINE rtree_node_elm_t * +rtree_child_tryread(rtree_node_elm_t *elm, bool dependent) +{ + rtree_node_elm_t *child; + + /* Double-checked read (first read may be stale. */ + child = elm->child; + if (!dependent && !rtree_node_valid(child)) + child = atomic_read_p(&elm->pun); + assert(!dependent || child != NULL); + return (child); +} + +JEMALLOC_ALWAYS_INLINE rtree_node_elm_t * +rtree_child_read(rtree_t *rtree, rtree_node_elm_t *elm, unsigned level, + bool dependent) +{ + rtree_node_elm_t *child; + + child = rtree_child_tryread(elm, dependent); + if (!dependent && unlikely(!rtree_node_valid(child))) + child = rtree_child_read_hard(rtree, elm, level); + assert(!dependent || child != NULL); + return (child); +} + +JEMALLOC_ALWAYS_INLINE extent_node_t * +rtree_val_read(rtree_t *rtree, rtree_node_elm_t *elm, bool dependent) +{ + + if (dependent) { + /* + * Reading a val on behalf of a pointer to a valid allocation is + * guaranteed to be a clean read even without synchronization, + * because the rtree update became visible in memory before the + * pointer came into existence. + */ + return (elm->val); + } else { + /* + * An arbitrary read, e.g. on behalf of ivsalloc(), may not be + * dependent on a previous rtree write, which means a stale read + * could result if synchronization were omitted here. + */ + return (atomic_read_p(&elm->pun)); + } +} + +JEMALLOC_INLINE void +rtree_val_write(rtree_t *rtree, rtree_node_elm_t *elm, const extent_node_t *val) +{ + + atomic_write_p(&elm->pun, val); +} + +JEMALLOC_ALWAYS_INLINE rtree_node_elm_t * +rtree_subtree_tryread(rtree_t *rtree, unsigned level, bool dependent) +{ + rtree_node_elm_t *subtree; + + /* Double-checked read (first read may be stale. */ + subtree = rtree->levels[level].subtree; + if (!dependent && unlikely(!rtree_node_valid(subtree))) + subtree = atomic_read_p(&rtree->levels[level].subtree_pun); + assert(!dependent || subtree != NULL); + return (subtree); +} + +JEMALLOC_ALWAYS_INLINE rtree_node_elm_t * +rtree_subtree_read(rtree_t *rtree, unsigned level, bool dependent) +{ + rtree_node_elm_t *subtree; + + subtree = rtree_subtree_tryread(rtree, level, dependent); + if (!dependent && unlikely(!rtree_node_valid(subtree))) + subtree = rtree_subtree_read_hard(rtree, level); + assert(!dependent || subtree != NULL); + return (subtree); +} + +JEMALLOC_ALWAYS_INLINE extent_node_t * +rtree_get(rtree_t *rtree, uintptr_t key, bool dependent) +{ + uintptr_t subkey; + unsigned start_level; + rtree_node_elm_t *node; + + start_level = rtree_start_level(rtree, key); + + node = rtree_subtree_tryread(rtree, start_level, dependent); +#define RTREE_GET_BIAS (RTREE_HEIGHT_MAX - rtree->height) + switch (start_level + RTREE_GET_BIAS) { +#define RTREE_GET_SUBTREE(level) \ + case level: \ + assert(level < (RTREE_HEIGHT_MAX-1)); \ + if (!dependent && unlikely(!rtree_node_valid(node))) \ + return (NULL); \ + subkey = rtree_subkey(rtree, key, level - \ + RTREE_GET_BIAS); \ + node = rtree_child_tryread(&node[subkey], dependent); \ + /* Fall through. */ +#define RTREE_GET_LEAF(level) \ + case level: \ + assert(level == (RTREE_HEIGHT_MAX-1)); \ + if (!dependent && unlikely(!rtree_node_valid(node))) \ + return (NULL); \ + subkey = rtree_subkey(rtree, key, level - \ + RTREE_GET_BIAS); \ + /* \ + * node is a leaf, so it contains values rather than \ + * child pointers. \ + */ \ + return (rtree_val_read(rtree, &node[subkey], \ + dependent)); +#if RTREE_HEIGHT_MAX > 1 + RTREE_GET_SUBTREE(0) +#endif +#if RTREE_HEIGHT_MAX > 2 + RTREE_GET_SUBTREE(1) +#endif +#if RTREE_HEIGHT_MAX > 3 + RTREE_GET_SUBTREE(2) +#endif +#if RTREE_HEIGHT_MAX > 4 + RTREE_GET_SUBTREE(3) +#endif +#if RTREE_HEIGHT_MAX > 5 + RTREE_GET_SUBTREE(4) +#endif +#if RTREE_HEIGHT_MAX > 6 + RTREE_GET_SUBTREE(5) +#endif +#if RTREE_HEIGHT_MAX > 7 + RTREE_GET_SUBTREE(6) +#endif +#if RTREE_HEIGHT_MAX > 8 + RTREE_GET_SUBTREE(7) +#endif +#if RTREE_HEIGHT_MAX > 9 + RTREE_GET_SUBTREE(8) +#endif +#if RTREE_HEIGHT_MAX > 10 + RTREE_GET_SUBTREE(9) +#endif +#if RTREE_HEIGHT_MAX > 11 + RTREE_GET_SUBTREE(10) +#endif +#if RTREE_HEIGHT_MAX > 12 + RTREE_GET_SUBTREE(11) +#endif +#if RTREE_HEIGHT_MAX > 13 + RTREE_GET_SUBTREE(12) +#endif +#if RTREE_HEIGHT_MAX > 14 + RTREE_GET_SUBTREE(13) +#endif +#if RTREE_HEIGHT_MAX > 15 + RTREE_GET_SUBTREE(14) +#endif +#if RTREE_HEIGHT_MAX > 16 +# error Unsupported RTREE_HEIGHT_MAX +#endif + RTREE_GET_LEAF(RTREE_HEIGHT_MAX-1) +#undef RTREE_GET_SUBTREE +#undef RTREE_GET_LEAF + default: not_reached(); + } +#undef RTREE_GET_BIAS + not_reached(); +} + +JEMALLOC_INLINE bool +rtree_set(rtree_t *rtree, uintptr_t key, const extent_node_t *val) +{ + uintptr_t subkey; + unsigned i, start_level; + rtree_node_elm_t *node, *child; + + start_level = rtree_start_level(rtree, key); + + node = rtree_subtree_read(rtree, start_level, false); + if (node == NULL) + return (true); + for (i = start_level; /**/; i++, node = child) { + subkey = rtree_subkey(rtree, key, i); + if (i == rtree->height - 1) { + /* + * node is a leaf, so it contains values rather than + * child pointers. + */ + rtree_val_write(rtree, &node[subkey], val); + return (false); + } + assert(i + 1 < rtree->height); + child = rtree_child_read(rtree, &node[subkey], i, false); + if (child == NULL) + return (true); + } + not_reached(); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/size_classes.h b/contrib/jemalloc/include/jemalloc/internal/size_classes.h new file mode 100644 index 0000000..615586d --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/size_classes.h @@ -0,0 +1,5495 @@ +/* This file was automatically generated by size_classes.sh. */ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +/* + * This header requires LG_SIZEOF_PTR, LG_TINY_MIN, LG_QUANTUM, and LG_PAGE to + * be defined prior to inclusion, and it in turn defines: + * + * LG_SIZE_CLASS_GROUP: Lg of size class count for each size doubling. + * SIZE_CLASSES: Complete table of + * SC(index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup) + * tuples. + * index: Size class index. + * lg_grp: Lg group base size (no deltas added). + * lg_delta: Lg delta to previous size class. + * ndelta: Delta multiplier. size == 1< 255) +# error "Too many small size classes" +#endif + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/smoothstep.h b/contrib/jemalloc/include/jemalloc/internal/smoothstep.h new file mode 100644 index 0000000..c5333cc --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/smoothstep.h @@ -0,0 +1,246 @@ +/* + * This file was generated by the following command: + * sh smoothstep.sh smoother 200 24 3 15 + */ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +/* + * This header defines a precomputed table based on the smoothstep family of + * sigmoidal curves (https://en.wikipedia.org/wiki/Smoothstep) that grow from 0 + * to 1 in 0 <= x <= 1. The table is stored as integer fixed point values so + * that floating point math can be avoided. + * + * 3 2 + * smoothstep(x) = -2x + 3x + * + * 5 4 3 + * smootherstep(x) = 6x - 15x + 10x + * + * 7 6 5 4 + * smootheststep(x) = -20x + 70x - 84x + 35x + */ + +#define SMOOTHSTEP_VARIANT "smoother" +#define SMOOTHSTEP_NSTEPS 200 +#define SMOOTHSTEP_BFP 24 +#define SMOOTHSTEP \ + /* STEP(step, h, x, y) */ \ + STEP( 1, UINT64_C(0x0000000000000014), 0.005, 0.000001240643750) \ + STEP( 2, UINT64_C(0x00000000000000a5), 0.010, 0.000009850600000) \ + STEP( 3, UINT64_C(0x0000000000000229), 0.015, 0.000032995181250) \ + STEP( 4, UINT64_C(0x0000000000000516), 0.020, 0.000077619200000) \ + STEP( 5, UINT64_C(0x00000000000009dc), 0.025, 0.000150449218750) \ + STEP( 6, UINT64_C(0x00000000000010e8), 0.030, 0.000257995800000) \ + STEP( 7, UINT64_C(0x0000000000001aa4), 0.035, 0.000406555756250) \ + STEP( 8, UINT64_C(0x0000000000002777), 0.040, 0.000602214400000) \ + STEP( 9, UINT64_C(0x00000000000037c2), 0.045, 0.000850847793750) \ + STEP( 10, UINT64_C(0x0000000000004be6), 0.050, 0.001158125000000) \ + STEP( 11, UINT64_C(0x000000000000643c), 0.055, 0.001529510331250) \ + STEP( 12, UINT64_C(0x000000000000811f), 0.060, 0.001970265600000) \ + STEP( 13, UINT64_C(0x000000000000a2e2), 0.065, 0.002485452368750) \ + STEP( 14, UINT64_C(0x000000000000c9d8), 0.070, 0.003079934200000) \ + STEP( 15, UINT64_C(0x000000000000f64f), 0.075, 0.003758378906250) \ + STEP( 16, UINT64_C(0x0000000000012891), 0.080, 0.004525260800000) \ + STEP( 17, UINT64_C(0x00000000000160e7), 0.085, 0.005384862943750) \ + STEP( 18, UINT64_C(0x0000000000019f95), 0.090, 0.006341279400000) \ + STEP( 19, UINT64_C(0x000000000001e4dc), 0.095, 0.007398417481250) \ + STEP( 20, UINT64_C(0x00000000000230fc), 0.100, 0.008560000000000) \ + STEP( 21, UINT64_C(0x0000000000028430), 0.105, 0.009829567518750) \ + STEP( 22, UINT64_C(0x000000000002deb0), 0.110, 0.011210480600000) \ + STEP( 23, UINT64_C(0x00000000000340b1), 0.115, 0.012705922056250) \ + STEP( 24, UINT64_C(0x000000000003aa67), 0.120, 0.014318899200000) \ + STEP( 25, UINT64_C(0x0000000000041c00), 0.125, 0.016052246093750) \ + STEP( 26, UINT64_C(0x00000000000495a8), 0.130, 0.017908625800000) \ + STEP( 27, UINT64_C(0x000000000005178b), 0.135, 0.019890532631250) \ + STEP( 28, UINT64_C(0x000000000005a1cf), 0.140, 0.022000294400000) \ + STEP( 29, UINT64_C(0x0000000000063498), 0.145, 0.024240074668750) \ + STEP( 30, UINT64_C(0x000000000006d009), 0.150, 0.026611875000000) \ + STEP( 31, UINT64_C(0x000000000007743f), 0.155, 0.029117537206250) \ + STEP( 32, UINT64_C(0x0000000000082157), 0.160, 0.031758745600000) \ + STEP( 33, UINT64_C(0x000000000008d76b), 0.165, 0.034537029243750) \ + STEP( 34, UINT64_C(0x0000000000099691), 0.170, 0.037453764200000) \ + STEP( 35, UINT64_C(0x00000000000a5edf), 0.175, 0.040510175781250) \ + STEP( 36, UINT64_C(0x00000000000b3067), 0.180, 0.043707340800000) \ + STEP( 37, UINT64_C(0x00000000000c0b38), 0.185, 0.047046189818750) \ + STEP( 38, UINT64_C(0x00000000000cef5e), 0.190, 0.050527509400000) \ + STEP( 39, UINT64_C(0x00000000000ddce6), 0.195, 0.054151944356250) \ + STEP( 40, UINT64_C(0x00000000000ed3d8), 0.200, 0.057920000000000) \ + STEP( 41, UINT64_C(0x00000000000fd439), 0.205, 0.061832044393750) \ + STEP( 42, UINT64_C(0x000000000010de0e), 0.210, 0.065888310600000) \ + STEP( 43, UINT64_C(0x000000000011f158), 0.215, 0.070088898931250) \ + STEP( 44, UINT64_C(0x0000000000130e17), 0.220, 0.074433779200000) \ + STEP( 45, UINT64_C(0x0000000000143448), 0.225, 0.078922792968750) \ + STEP( 46, UINT64_C(0x00000000001563e7), 0.230, 0.083555655800000) \ + STEP( 47, UINT64_C(0x0000000000169cec), 0.235, 0.088331959506250) \ + STEP( 48, UINT64_C(0x000000000017df4f), 0.240, 0.093251174400000) \ + STEP( 49, UINT64_C(0x0000000000192b04), 0.245, 0.098312651543750) \ + STEP( 50, UINT64_C(0x00000000001a8000), 0.250, 0.103515625000000) \ + STEP( 51, UINT64_C(0x00000000001bde32), 0.255, 0.108859214081250) \ + STEP( 52, UINT64_C(0x00000000001d458b), 0.260, 0.114342425600000) \ + STEP( 53, UINT64_C(0x00000000001eb5f8), 0.265, 0.119964156118750) \ + STEP( 54, UINT64_C(0x0000000000202f65), 0.270, 0.125723194200000) \ + STEP( 55, UINT64_C(0x000000000021b1bb), 0.275, 0.131618222656250) \ + STEP( 56, UINT64_C(0x0000000000233ce3), 0.280, 0.137647820800000) \ + STEP( 57, UINT64_C(0x000000000024d0c3), 0.285, 0.143810466693750) \ + STEP( 58, UINT64_C(0x0000000000266d40), 0.290, 0.150104539400000) \ + STEP( 59, UINT64_C(0x000000000028123d), 0.295, 0.156528321231250) \ + STEP( 60, UINT64_C(0x000000000029bf9c), 0.300, 0.163080000000000) \ + STEP( 61, UINT64_C(0x00000000002b753d), 0.305, 0.169757671268750) \ + STEP( 62, UINT64_C(0x00000000002d32fe), 0.310, 0.176559340600000) \ + STEP( 63, UINT64_C(0x00000000002ef8bc), 0.315, 0.183482925806250) \ + STEP( 64, UINT64_C(0x000000000030c654), 0.320, 0.190526259200000) \ + STEP( 65, UINT64_C(0x0000000000329b9f), 0.325, 0.197687089843750) \ + STEP( 66, UINT64_C(0x0000000000347875), 0.330, 0.204963085800000) \ + STEP( 67, UINT64_C(0x0000000000365cb0), 0.335, 0.212351836381250) \ + STEP( 68, UINT64_C(0x0000000000384825), 0.340, 0.219850854400000) \ + STEP( 69, UINT64_C(0x00000000003a3aa8), 0.345, 0.227457578418750) \ + STEP( 70, UINT64_C(0x00000000003c340f), 0.350, 0.235169375000000) \ + STEP( 71, UINT64_C(0x00000000003e342b), 0.355, 0.242983540956250) \ + STEP( 72, UINT64_C(0x0000000000403ace), 0.360, 0.250897305600000) \ + STEP( 73, UINT64_C(0x00000000004247c8), 0.365, 0.258907832993750) \ + STEP( 74, UINT64_C(0x0000000000445ae9), 0.370, 0.267012224200000) \ + STEP( 75, UINT64_C(0x0000000000467400), 0.375, 0.275207519531250) \ + STEP( 76, UINT64_C(0x00000000004892d8), 0.380, 0.283490700800000) \ + STEP( 77, UINT64_C(0x00000000004ab740), 0.385, 0.291858693568750) \ + STEP( 78, UINT64_C(0x00000000004ce102), 0.390, 0.300308369400000) \ + STEP( 79, UINT64_C(0x00000000004f0fe9), 0.395, 0.308836548106250) \ + STEP( 80, UINT64_C(0x00000000005143bf), 0.400, 0.317440000000000) \ + STEP( 81, UINT64_C(0x0000000000537c4d), 0.405, 0.326115448143750) \ + STEP( 82, UINT64_C(0x000000000055b95b), 0.410, 0.334859570600000) \ + STEP( 83, UINT64_C(0x000000000057fab1), 0.415, 0.343669002681250) \ + STEP( 84, UINT64_C(0x00000000005a4015), 0.420, 0.352540339200000) \ + STEP( 85, UINT64_C(0x00000000005c894e), 0.425, 0.361470136718750) \ + STEP( 86, UINT64_C(0x00000000005ed622), 0.430, 0.370454915800000) \ + STEP( 87, UINT64_C(0x0000000000612655), 0.435, 0.379491163256250) \ + STEP( 88, UINT64_C(0x00000000006379ac), 0.440, 0.388575334400000) \ + STEP( 89, UINT64_C(0x000000000065cfeb), 0.445, 0.397703855293750) \ + STEP( 90, UINT64_C(0x00000000006828d6), 0.450, 0.406873125000000) \ + STEP( 91, UINT64_C(0x00000000006a842f), 0.455, 0.416079517831250) \ + STEP( 92, UINT64_C(0x00000000006ce1bb), 0.460, 0.425319385600000) \ + STEP( 93, UINT64_C(0x00000000006f413a), 0.465, 0.434589059868750) \ + STEP( 94, UINT64_C(0x000000000071a270), 0.470, 0.443884854200000) \ + STEP( 95, UINT64_C(0x000000000074051d), 0.475, 0.453203066406250) \ + STEP( 96, UINT64_C(0x0000000000766905), 0.480, 0.462539980800000) \ + STEP( 97, UINT64_C(0x000000000078cde7), 0.485, 0.471891870443750) \ + STEP( 98, UINT64_C(0x00000000007b3387), 0.490, 0.481254999400000) \ + STEP( 99, UINT64_C(0x00000000007d99a4), 0.495, 0.490625624981250) \ + STEP( 100, UINT64_C(0x0000000000800000), 0.500, 0.500000000000000) \ + STEP( 101, UINT64_C(0x000000000082665b), 0.505, 0.509374375018750) \ + STEP( 102, UINT64_C(0x000000000084cc78), 0.510, 0.518745000600000) \ + STEP( 103, UINT64_C(0x0000000000873218), 0.515, 0.528108129556250) \ + STEP( 104, UINT64_C(0x00000000008996fa), 0.520, 0.537460019200000) \ + STEP( 105, UINT64_C(0x00000000008bfae2), 0.525, 0.546796933593750) \ + STEP( 106, UINT64_C(0x00000000008e5d8f), 0.530, 0.556115145800000) \ + STEP( 107, UINT64_C(0x000000000090bec5), 0.535, 0.565410940131250) \ + STEP( 108, UINT64_C(0x0000000000931e44), 0.540, 0.574680614400000) \ + STEP( 109, UINT64_C(0x0000000000957bd0), 0.545, 0.583920482168750) \ + STEP( 110, UINT64_C(0x000000000097d729), 0.550, 0.593126875000000) \ + STEP( 111, UINT64_C(0x00000000009a3014), 0.555, 0.602296144706250) \ + STEP( 112, UINT64_C(0x00000000009c8653), 0.560, 0.611424665600000) \ + STEP( 113, UINT64_C(0x00000000009ed9aa), 0.565, 0.620508836743750) \ + STEP( 114, UINT64_C(0x0000000000a129dd), 0.570, 0.629545084200000) \ + STEP( 115, UINT64_C(0x0000000000a376b1), 0.575, 0.638529863281250) \ + STEP( 116, UINT64_C(0x0000000000a5bfea), 0.580, 0.647459660800000) \ + STEP( 117, UINT64_C(0x0000000000a8054e), 0.585, 0.656330997318750) \ + STEP( 118, UINT64_C(0x0000000000aa46a4), 0.590, 0.665140429400000) \ + STEP( 119, UINT64_C(0x0000000000ac83b2), 0.595, 0.673884551856250) \ + STEP( 120, UINT64_C(0x0000000000aebc40), 0.600, 0.682560000000000) \ + STEP( 121, UINT64_C(0x0000000000b0f016), 0.605, 0.691163451893750) \ + STEP( 122, UINT64_C(0x0000000000b31efd), 0.610, 0.699691630600000) \ + STEP( 123, UINT64_C(0x0000000000b548bf), 0.615, 0.708141306431250) \ + STEP( 124, UINT64_C(0x0000000000b76d27), 0.620, 0.716509299200000) \ + STEP( 125, UINT64_C(0x0000000000b98c00), 0.625, 0.724792480468750) \ + STEP( 126, UINT64_C(0x0000000000bba516), 0.630, 0.732987775800000) \ + STEP( 127, UINT64_C(0x0000000000bdb837), 0.635, 0.741092167006250) \ + STEP( 128, UINT64_C(0x0000000000bfc531), 0.640, 0.749102694400000) \ + STEP( 129, UINT64_C(0x0000000000c1cbd4), 0.645, 0.757016459043750) \ + STEP( 130, UINT64_C(0x0000000000c3cbf0), 0.650, 0.764830625000000) \ + STEP( 131, UINT64_C(0x0000000000c5c557), 0.655, 0.772542421581250) \ + STEP( 132, UINT64_C(0x0000000000c7b7da), 0.660, 0.780149145600000) \ + STEP( 133, UINT64_C(0x0000000000c9a34f), 0.665, 0.787648163618750) \ + STEP( 134, UINT64_C(0x0000000000cb878a), 0.670, 0.795036914200000) \ + STEP( 135, UINT64_C(0x0000000000cd6460), 0.675, 0.802312910156250) \ + STEP( 136, UINT64_C(0x0000000000cf39ab), 0.680, 0.809473740800000) \ + STEP( 137, UINT64_C(0x0000000000d10743), 0.685, 0.816517074193750) \ + STEP( 138, UINT64_C(0x0000000000d2cd01), 0.690, 0.823440659400000) \ + STEP( 139, UINT64_C(0x0000000000d48ac2), 0.695, 0.830242328731250) \ + STEP( 140, UINT64_C(0x0000000000d64063), 0.700, 0.836920000000000) \ + STEP( 141, UINT64_C(0x0000000000d7edc2), 0.705, 0.843471678768750) \ + STEP( 142, UINT64_C(0x0000000000d992bf), 0.710, 0.849895460600000) \ + STEP( 143, UINT64_C(0x0000000000db2f3c), 0.715, 0.856189533306250) \ + STEP( 144, UINT64_C(0x0000000000dcc31c), 0.720, 0.862352179200000) \ + STEP( 145, UINT64_C(0x0000000000de4e44), 0.725, 0.868381777343750) \ + STEP( 146, UINT64_C(0x0000000000dfd09a), 0.730, 0.874276805800000) \ + STEP( 147, UINT64_C(0x0000000000e14a07), 0.735, 0.880035843881250) \ + STEP( 148, UINT64_C(0x0000000000e2ba74), 0.740, 0.885657574400000) \ + STEP( 149, UINT64_C(0x0000000000e421cd), 0.745, 0.891140785918750) \ + STEP( 150, UINT64_C(0x0000000000e58000), 0.750, 0.896484375000000) \ + STEP( 151, UINT64_C(0x0000000000e6d4fb), 0.755, 0.901687348456250) \ + STEP( 152, UINT64_C(0x0000000000e820b0), 0.760, 0.906748825600000) \ + STEP( 153, UINT64_C(0x0000000000e96313), 0.765, 0.911668040493750) \ + STEP( 154, UINT64_C(0x0000000000ea9c18), 0.770, 0.916444344200000) \ + STEP( 155, UINT64_C(0x0000000000ebcbb7), 0.775, 0.921077207031250) \ + STEP( 156, UINT64_C(0x0000000000ecf1e8), 0.780, 0.925566220800000) \ + STEP( 157, UINT64_C(0x0000000000ee0ea7), 0.785, 0.929911101068750) \ + STEP( 158, UINT64_C(0x0000000000ef21f1), 0.790, 0.934111689400000) \ + STEP( 159, UINT64_C(0x0000000000f02bc6), 0.795, 0.938167955606250) \ + STEP( 160, UINT64_C(0x0000000000f12c27), 0.800, 0.942080000000000) \ + STEP( 161, UINT64_C(0x0000000000f22319), 0.805, 0.945848055643750) \ + STEP( 162, UINT64_C(0x0000000000f310a1), 0.810, 0.949472490600000) \ + STEP( 163, UINT64_C(0x0000000000f3f4c7), 0.815, 0.952953810181250) \ + STEP( 164, UINT64_C(0x0000000000f4cf98), 0.820, 0.956292659200000) \ + STEP( 165, UINT64_C(0x0000000000f5a120), 0.825, 0.959489824218750) \ + STEP( 166, UINT64_C(0x0000000000f6696e), 0.830, 0.962546235800000) \ + STEP( 167, UINT64_C(0x0000000000f72894), 0.835, 0.965462970756250) \ + STEP( 168, UINT64_C(0x0000000000f7dea8), 0.840, 0.968241254400000) \ + STEP( 169, UINT64_C(0x0000000000f88bc0), 0.845, 0.970882462793750) \ + STEP( 170, UINT64_C(0x0000000000f92ff6), 0.850, 0.973388125000000) \ + STEP( 171, UINT64_C(0x0000000000f9cb67), 0.855, 0.975759925331250) \ + STEP( 172, UINT64_C(0x0000000000fa5e30), 0.860, 0.977999705600000) \ + STEP( 173, UINT64_C(0x0000000000fae874), 0.865, 0.980109467368750) \ + STEP( 174, UINT64_C(0x0000000000fb6a57), 0.870, 0.982091374200000) \ + STEP( 175, UINT64_C(0x0000000000fbe400), 0.875, 0.983947753906250) \ + STEP( 176, UINT64_C(0x0000000000fc5598), 0.880, 0.985681100800000) \ + STEP( 177, UINT64_C(0x0000000000fcbf4e), 0.885, 0.987294077943750) \ + STEP( 178, UINT64_C(0x0000000000fd214f), 0.890, 0.988789519400000) \ + STEP( 179, UINT64_C(0x0000000000fd7bcf), 0.895, 0.990170432481250) \ + STEP( 180, UINT64_C(0x0000000000fdcf03), 0.900, 0.991440000000000) \ + STEP( 181, UINT64_C(0x0000000000fe1b23), 0.905, 0.992601582518750) \ + STEP( 182, UINT64_C(0x0000000000fe606a), 0.910, 0.993658720600000) \ + STEP( 183, UINT64_C(0x0000000000fe9f18), 0.915, 0.994615137056250) \ + STEP( 184, UINT64_C(0x0000000000fed76e), 0.920, 0.995474739200000) \ + STEP( 185, UINT64_C(0x0000000000ff09b0), 0.925, 0.996241621093750) \ + STEP( 186, UINT64_C(0x0000000000ff3627), 0.930, 0.996920065800000) \ + STEP( 187, UINT64_C(0x0000000000ff5d1d), 0.935, 0.997514547631250) \ + STEP( 188, UINT64_C(0x0000000000ff7ee0), 0.940, 0.998029734400000) \ + STEP( 189, UINT64_C(0x0000000000ff9bc3), 0.945, 0.998470489668750) \ + STEP( 190, UINT64_C(0x0000000000ffb419), 0.950, 0.998841875000000) \ + STEP( 191, UINT64_C(0x0000000000ffc83d), 0.955, 0.999149152206250) \ + STEP( 192, UINT64_C(0x0000000000ffd888), 0.960, 0.999397785600000) \ + STEP( 193, UINT64_C(0x0000000000ffe55b), 0.965, 0.999593444243750) \ + STEP( 194, UINT64_C(0x0000000000ffef17), 0.970, 0.999742004200000) \ + STEP( 195, UINT64_C(0x0000000000fff623), 0.975, 0.999849550781250) \ + STEP( 196, UINT64_C(0x0000000000fffae9), 0.980, 0.999922380800000) \ + STEP( 197, UINT64_C(0x0000000000fffdd6), 0.985, 0.999967004818750) \ + STEP( 198, UINT64_C(0x0000000000ffff5a), 0.990, 0.999990149400000) \ + STEP( 199, UINT64_C(0x0000000000ffffeb), 0.995, 0.999998759356250) \ + STEP( 200, UINT64_C(0x0000000001000000), 1.000, 1.000000000000000) \ + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/stats.h b/contrib/jemalloc/include/jemalloc/internal/stats.h new file mode 100644 index 0000000..b621817 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/stats.h @@ -0,0 +1,201 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct tcache_bin_stats_s tcache_bin_stats_t; +typedef struct malloc_bin_stats_s malloc_bin_stats_t; +typedef struct malloc_large_stats_s malloc_large_stats_t; +typedef struct malloc_huge_stats_s malloc_huge_stats_t; +typedef struct arena_stats_s arena_stats_t; +typedef struct chunk_stats_s chunk_stats_t; + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct tcache_bin_stats_s { + /* + * Number of allocation requests that corresponded to the size of this + * bin. + */ + uint64_t nrequests; +}; + +struct malloc_bin_stats_s { + /* + * Total number of allocation/deallocation requests served directly by + * the bin. Note that tcache may allocate an object, then recycle it + * many times, resulting many increments to nrequests, but only one + * each to nmalloc and ndalloc. + */ + uint64_t nmalloc; + uint64_t ndalloc; + + /* + * Number of allocation requests that correspond to the size of this + * bin. This includes requests served by tcache, though tcache only + * periodically merges into this counter. + */ + uint64_t nrequests; + + /* + * Current number of regions of this size class, including regions + * currently cached by tcache. + */ + size_t curregs; + + /* Number of tcache fills from this bin. */ + uint64_t nfills; + + /* Number of tcache flushes to this bin. */ + uint64_t nflushes; + + /* Total number of runs created for this bin's size class. */ + uint64_t nruns; + + /* + * Total number of runs reused by extracting them from the runs tree for + * this bin's size class. + */ + uint64_t reruns; + + /* Current number of runs in this bin. */ + size_t curruns; +}; + +struct malloc_large_stats_s { + /* + * Total number of allocation/deallocation requests served directly by + * the arena. Note that tcache may allocate an object, then recycle it + * many times, resulting many increments to nrequests, but only one + * each to nmalloc and ndalloc. + */ + uint64_t nmalloc; + uint64_t ndalloc; + + /* + * Number of allocation requests that correspond to this size class. + * This includes requests served by tcache, though tcache only + * periodically merges into this counter. + */ + uint64_t nrequests; + + /* + * Current number of runs of this size class, including runs currently + * cached by tcache. + */ + size_t curruns; +}; + +struct malloc_huge_stats_s { + /* + * Total number of allocation/deallocation requests served directly by + * the arena. + */ + uint64_t nmalloc; + uint64_t ndalloc; + + /* Current number of (multi-)chunk allocations of this size class. */ + size_t curhchunks; +}; + +struct arena_stats_s { + /* Number of bytes currently mapped. */ + size_t mapped; + + /* + * Number of bytes currently retained as a side effect of munmap() being + * disabled/bypassed. Retained bytes are technically mapped (though + * always decommitted or purged), but they are excluded from the mapped + * statistic (above). + */ + size_t retained; + + /* + * Total number of purge sweeps, total number of madvise calls made, + * and total pages purged in order to keep dirty unused memory under + * control. + */ + uint64_t npurge; + uint64_t nmadvise; + uint64_t purged; + + /* + * Number of bytes currently mapped purely for metadata purposes, and + * number of bytes currently allocated for internal metadata. + */ + size_t metadata_mapped; + size_t metadata_allocated; /* Protected via atomic_*_z(). */ + + /* Per-size-category statistics. */ + size_t allocated_large; + uint64_t nmalloc_large; + uint64_t ndalloc_large; + uint64_t nrequests_large; + + size_t allocated_huge; + uint64_t nmalloc_huge; + uint64_t ndalloc_huge; + + /* One element for each large size class. */ + malloc_large_stats_t *lstats; + + /* One element for each huge size class. */ + malloc_huge_stats_t *hstats; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +extern bool opt_stats_print; + +extern size_t stats_cactive; + +void stats_print(void (*write)(void *, const char *), void *cbopaque, + const char *opts); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +size_t stats_cactive_get(void); +void stats_cactive_add(size_t size); +void stats_cactive_sub(size_t size); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_STATS_C_)) +JEMALLOC_INLINE size_t +stats_cactive_get(void) +{ + + return (atomic_read_z(&stats_cactive)); +} + +JEMALLOC_INLINE void +stats_cactive_add(size_t size) +{ + UNUSED size_t cactive; + + assert(size > 0); + assert((size & chunksize_mask) == 0); + + cactive = atomic_add_z(&stats_cactive, size); + assert(cactive - size < cactive); +} + +JEMALLOC_INLINE void +stats_cactive_sub(size_t size) +{ + UNUSED size_t cactive; + + assert(size > 0); + assert((size & chunksize_mask) == 0); + + cactive = atomic_sub_z(&stats_cactive, size); + assert(cactive + size > cactive); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/tcache.h b/contrib/jemalloc/include/jemalloc/internal/tcache.h new file mode 100644 index 0000000..70883b1 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/tcache.h @@ -0,0 +1,469 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct tcache_bin_info_s tcache_bin_info_t; +typedef struct tcache_bin_s tcache_bin_t; +typedef struct tcache_s tcache_t; +typedef struct tcaches_s tcaches_t; + +/* + * tcache pointers close to NULL are used to encode state information that is + * used for two purposes: preventing thread caching on a per thread basis and + * cleaning up during thread shutdown. + */ +#define TCACHE_STATE_DISABLED ((tcache_t *)(uintptr_t)1) +#define TCACHE_STATE_REINCARNATED ((tcache_t *)(uintptr_t)2) +#define TCACHE_STATE_PURGATORY ((tcache_t *)(uintptr_t)3) +#define TCACHE_STATE_MAX TCACHE_STATE_PURGATORY + +/* + * Absolute minimum number of cache slots for each small bin. + */ +#define TCACHE_NSLOTS_SMALL_MIN 20 + +/* + * Absolute maximum number of cache slots for each small bin in the thread + * cache. This is an additional constraint beyond that imposed as: twice the + * number of regions per run for this size class. + * + * This constant must be an even number. + */ +#define TCACHE_NSLOTS_SMALL_MAX 200 + +/* Number of cache slots for large size classes. */ +#define TCACHE_NSLOTS_LARGE 20 + +/* (1U << opt_lg_tcache_max) is used to compute tcache_maxclass. */ +#define LG_TCACHE_MAXCLASS_DEFAULT 15 + +/* + * TCACHE_GC_SWEEP is the approximate number of allocation events between + * full GC sweeps. Integer rounding may cause the actual number to be + * slightly higher, since GC is performed incrementally. + */ +#define TCACHE_GC_SWEEP 8192 + +/* Number of tcache allocation/deallocation events between incremental GCs. */ +#define TCACHE_GC_INCR \ + ((TCACHE_GC_SWEEP / NBINS) + ((TCACHE_GC_SWEEP / NBINS == 0) ? 0 : 1)) + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +typedef enum { + tcache_enabled_false = 0, /* Enable cast to/from bool. */ + tcache_enabled_true = 1, + tcache_enabled_default = 2 +} tcache_enabled_t; + +/* + * Read-only information associated with each element of tcache_t's tbins array + * is stored separately, mainly to reduce memory usage. + */ +struct tcache_bin_info_s { + unsigned ncached_max; /* Upper limit on ncached. */ +}; + +struct tcache_bin_s { + tcache_bin_stats_t tstats; + int low_water; /* Min # cached since last GC. */ + unsigned lg_fill_div; /* Fill (ncached_max >> lg_fill_div). */ + unsigned ncached; /* # of cached objects. */ + /* + * To make use of adjacent cacheline prefetch, the items in the avail + * stack goes to higher address for newer allocations. avail points + * just above the available space, which means that + * avail[-ncached, ... -1] are available items and the lowest item will + * be allocated first. + */ + void **avail; /* Stack of available objects. */ +}; + +struct tcache_s { + ql_elm(tcache_t) link; /* Used for aggregating stats. */ + uint64_t prof_accumbytes;/* Cleared after arena_prof_accum(). */ + ticker_t gc_ticker; /* Drives incremental GC. */ + szind_t next_gc_bin; /* Next bin to GC. */ + tcache_bin_t tbins[1]; /* Dynamically sized. */ + /* + * The pointer stacks associated with tbins follow as a contiguous + * array. During tcache initialization, the avail pointer in each + * element of tbins is initialized to point to the proper offset within + * this array. + */ +}; + +/* Linkage for list of available (previously used) explicit tcache IDs. */ +struct tcaches_s { + union { + tcache_t *tcache; + tcaches_t *next; + }; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +extern bool opt_tcache; +extern ssize_t opt_lg_tcache_max; + +extern tcache_bin_info_t *tcache_bin_info; + +/* + * Number of tcache bins. There are NBINS small-object bins, plus 0 or more + * large-object bins. + */ +extern unsigned nhbins; + +/* Maximum cached size class. */ +extern size_t tcache_maxclass; + +/* + * Explicit tcaches, managed via the tcache.{create,flush,destroy} mallctls and + * usable via the MALLOCX_TCACHE() flag. The automatic per thread tcaches are + * completely disjoint from this data structure. tcaches starts off as a sparse + * array, so it has no physical memory footprint until individual pages are + * touched. This allows the entire array to be allocated the first time an + * explicit tcache is created without a disproportionate impact on memory usage. + */ +extern tcaches_t *tcaches; + +size_t tcache_salloc(tsdn_t *tsdn, const void *ptr); +void tcache_event_hard(tsd_t *tsd, tcache_t *tcache); +void *tcache_alloc_small_hard(tsdn_t *tsdn, arena_t *arena, tcache_t *tcache, + tcache_bin_t *tbin, szind_t binind, bool *tcache_success); +void tcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, tcache_bin_t *tbin, + szind_t binind, unsigned rem); +void tcache_bin_flush_large(tsd_t *tsd, tcache_bin_t *tbin, szind_t binind, + unsigned rem, tcache_t *tcache); +void tcache_arena_reassociate(tsdn_t *tsdn, tcache_t *tcache, + arena_t *oldarena, arena_t *newarena); +tcache_t *tcache_get_hard(tsd_t *tsd); +tcache_t *tcache_create(tsdn_t *tsdn, arena_t *arena); +void tcache_cleanup(tsd_t *tsd); +void tcache_enabled_cleanup(tsd_t *tsd); +void tcache_stats_merge(tsdn_t *tsdn, tcache_t *tcache, arena_t *arena); +bool tcaches_create(tsdn_t *tsdn, unsigned *r_ind); +void tcaches_flush(tsd_t *tsd, unsigned ind); +void tcaches_destroy(tsd_t *tsd, unsigned ind); +bool tcache_boot(tsdn_t *tsdn); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +void tcache_event(tsd_t *tsd, tcache_t *tcache); +void tcache_flush(void); +bool tcache_enabled_get(void); +tcache_t *tcache_get(tsd_t *tsd, bool create); +void tcache_enabled_set(bool enabled); +void *tcache_alloc_easy(tcache_bin_t *tbin, bool *tcache_success); +void *tcache_alloc_small(tsd_t *tsd, arena_t *arena, tcache_t *tcache, + size_t size, szind_t ind, bool zero, bool slow_path); +void *tcache_alloc_large(tsd_t *tsd, arena_t *arena, tcache_t *tcache, + size_t size, szind_t ind, bool zero, bool slow_path); +void tcache_dalloc_small(tsd_t *tsd, tcache_t *tcache, void *ptr, + szind_t binind, bool slow_path); +void tcache_dalloc_large(tsd_t *tsd, tcache_t *tcache, void *ptr, + size_t size, bool slow_path); +tcache_t *tcaches_get(tsd_t *tsd, unsigned ind); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TCACHE_C_)) +JEMALLOC_INLINE void +tcache_flush(void) +{ + tsd_t *tsd; + + cassert(config_tcache); + + tsd = tsd_fetch(); + tcache_cleanup(tsd); +} + +JEMALLOC_INLINE bool +tcache_enabled_get(void) +{ + tsd_t *tsd; + tcache_enabled_t tcache_enabled; + + cassert(config_tcache); + + tsd = tsd_fetch(); + tcache_enabled = tsd_tcache_enabled_get(tsd); + if (tcache_enabled == tcache_enabled_default) { + tcache_enabled = (tcache_enabled_t)opt_tcache; + tsd_tcache_enabled_set(tsd, tcache_enabled); + } + + return ((bool)tcache_enabled); +} + +JEMALLOC_INLINE void +tcache_enabled_set(bool enabled) +{ + tsd_t *tsd; + tcache_enabled_t tcache_enabled; + + cassert(config_tcache); + + tsd = tsd_fetch(); + + tcache_enabled = (tcache_enabled_t)enabled; + tsd_tcache_enabled_set(tsd, tcache_enabled); + + if (!enabled) + tcache_cleanup(tsd); +} + +JEMALLOC_ALWAYS_INLINE tcache_t * +tcache_get(tsd_t *tsd, bool create) +{ + tcache_t *tcache; + + if (!config_tcache) + return (NULL); + + tcache = tsd_tcache_get(tsd); + if (!create) + return (tcache); + if (unlikely(tcache == NULL) && tsd_nominal(tsd)) { + tcache = tcache_get_hard(tsd); + tsd_tcache_set(tsd, tcache); + } + + return (tcache); +} + +JEMALLOC_ALWAYS_INLINE void +tcache_event(tsd_t *tsd, tcache_t *tcache) +{ + + if (TCACHE_GC_INCR == 0) + return; + + if (unlikely(ticker_tick(&tcache->gc_ticker))) + tcache_event_hard(tsd, tcache); +} + +JEMALLOC_ALWAYS_INLINE void * +tcache_alloc_easy(tcache_bin_t *tbin, bool *tcache_success) +{ + void *ret; + + if (unlikely(tbin->ncached == 0)) { + tbin->low_water = -1; + *tcache_success = false; + return (NULL); + } + /* + * tcache_success (instead of ret) should be checked upon the return of + * this function. We avoid checking (ret == NULL) because there is + * never a null stored on the avail stack (which is unknown to the + * compiler), and eagerly checking ret would cause pipeline stall + * (waiting for the cacheline). + */ + *tcache_success = true; + ret = *(tbin->avail - tbin->ncached); + tbin->ncached--; + + if (unlikely((int)tbin->ncached < tbin->low_water)) + tbin->low_water = tbin->ncached; + + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void * +tcache_alloc_small(tsd_t *tsd, arena_t *arena, tcache_t *tcache, size_t size, + szind_t binind, bool zero, bool slow_path) +{ + void *ret; + tcache_bin_t *tbin; + bool tcache_success; + size_t usize JEMALLOC_CC_SILENCE_INIT(0); + + assert(binind < NBINS); + tbin = &tcache->tbins[binind]; + ret = tcache_alloc_easy(tbin, &tcache_success); + assert(tcache_success == (ret != NULL)); + if (unlikely(!tcache_success)) { + bool tcache_hard_success; + arena = arena_choose(tsd, arena); + if (unlikely(arena == NULL)) + return (NULL); + + ret = tcache_alloc_small_hard(tsd_tsdn(tsd), arena, tcache, + tbin, binind, &tcache_hard_success); + if (tcache_hard_success == false) + return (NULL); + } + + assert(ret); + /* + * Only compute usize if required. The checks in the following if + * statement are all static. + */ + if (config_prof || (slow_path && config_fill) || unlikely(zero)) { + usize = index2size(binind); + assert(tcache_salloc(tsd_tsdn(tsd), ret) == usize); + } + + if (likely(!zero)) { + if (slow_path && config_fill) { + if (unlikely(opt_junk_alloc)) { + arena_alloc_junk_small(ret, + &arena_bin_info[binind], false); + } else if (unlikely(opt_zero)) + memset(ret, 0, usize); + } + } else { + if (slow_path && config_fill && unlikely(opt_junk_alloc)) { + arena_alloc_junk_small(ret, &arena_bin_info[binind], + true); + } + memset(ret, 0, usize); + } + + if (config_stats) + tbin->tstats.nrequests++; + if (config_prof) + tcache->prof_accumbytes += usize; + tcache_event(tsd, tcache); + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void * +tcache_alloc_large(tsd_t *tsd, arena_t *arena, tcache_t *tcache, size_t size, + szind_t binind, bool zero, bool slow_path) +{ + void *ret; + tcache_bin_t *tbin; + bool tcache_success; + + assert(binind < nhbins); + tbin = &tcache->tbins[binind]; + ret = tcache_alloc_easy(tbin, &tcache_success); + assert(tcache_success == (ret != NULL)); + if (unlikely(!tcache_success)) { + /* + * Only allocate one large object at a time, because it's quite + * expensive to create one and not use it. + */ + arena = arena_choose(tsd, arena); + if (unlikely(arena == NULL)) + return (NULL); + + ret = arena_malloc_large(tsd_tsdn(tsd), arena, binind, zero); + if (ret == NULL) + return (NULL); + } else { + size_t usize JEMALLOC_CC_SILENCE_INIT(0); + + /* Only compute usize on demand */ + if (config_prof || (slow_path && config_fill) || + unlikely(zero)) { + usize = index2size(binind); + assert(usize <= tcache_maxclass); + } + + if (config_prof && usize == LARGE_MINCLASS) { + arena_chunk_t *chunk = + (arena_chunk_t *)CHUNK_ADDR2BASE(ret); + size_t pageind = (((uintptr_t)ret - (uintptr_t)chunk) >> + LG_PAGE); + arena_mapbits_large_binind_set(chunk, pageind, + BININD_INVALID); + } + if (likely(!zero)) { + if (slow_path && config_fill) { + if (unlikely(opt_junk_alloc)) { + memset(ret, JEMALLOC_ALLOC_JUNK, + usize); + } else if (unlikely(opt_zero)) + memset(ret, 0, usize); + } + } else + memset(ret, 0, usize); + + if (config_stats) + tbin->tstats.nrequests++; + if (config_prof) + tcache->prof_accumbytes += usize; + } + + tcache_event(tsd, tcache); + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void +tcache_dalloc_small(tsd_t *tsd, tcache_t *tcache, void *ptr, szind_t binind, + bool slow_path) +{ + tcache_bin_t *tbin; + tcache_bin_info_t *tbin_info; + + assert(tcache_salloc(tsd_tsdn(tsd), ptr) <= SMALL_MAXCLASS); + + if (slow_path && config_fill && unlikely(opt_junk_free)) + arena_dalloc_junk_small(ptr, &arena_bin_info[binind]); + + tbin = &tcache->tbins[binind]; + tbin_info = &tcache_bin_info[binind]; + if (unlikely(tbin->ncached == tbin_info->ncached_max)) { + tcache_bin_flush_small(tsd, tcache, tbin, binind, + (tbin_info->ncached_max >> 1)); + } + assert(tbin->ncached < tbin_info->ncached_max); + tbin->ncached++; + *(tbin->avail - tbin->ncached) = ptr; + + tcache_event(tsd, tcache); +} + +JEMALLOC_ALWAYS_INLINE void +tcache_dalloc_large(tsd_t *tsd, tcache_t *tcache, void *ptr, size_t size, + bool slow_path) +{ + szind_t binind; + tcache_bin_t *tbin; + tcache_bin_info_t *tbin_info; + + assert((size & PAGE_MASK) == 0); + assert(tcache_salloc(tsd_tsdn(tsd), ptr) > SMALL_MAXCLASS); + assert(tcache_salloc(tsd_tsdn(tsd), ptr) <= tcache_maxclass); + + binind = size2index(size); + + if (slow_path && config_fill && unlikely(opt_junk_free)) + arena_dalloc_junk_large(ptr, size); + + tbin = &tcache->tbins[binind]; + tbin_info = &tcache_bin_info[binind]; + if (unlikely(tbin->ncached == tbin_info->ncached_max)) { + tcache_bin_flush_large(tsd, tbin, binind, + (tbin_info->ncached_max >> 1), tcache); + } + assert(tbin->ncached < tbin_info->ncached_max); + tbin->ncached++; + *(tbin->avail - tbin->ncached) = ptr; + + tcache_event(tsd, tcache); +} + +JEMALLOC_ALWAYS_INLINE tcache_t * +tcaches_get(tsd_t *tsd, unsigned ind) +{ + tcaches_t *elm = &tcaches[ind]; + if (unlikely(elm->tcache == NULL)) { + elm->tcache = tcache_create(tsd_tsdn(tsd), arena_choose(tsd, + NULL)); + } + return (elm->tcache); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/ticker.h b/contrib/jemalloc/include/jemalloc/internal/ticker.h new file mode 100644 index 0000000..4696e56 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/ticker.h @@ -0,0 +1,75 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct ticker_s ticker_t; + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct ticker_s { + int32_t tick; + int32_t nticks; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +void ticker_init(ticker_t *ticker, int32_t nticks); +void ticker_copy(ticker_t *ticker, const ticker_t *other); +int32_t ticker_read(const ticker_t *ticker); +bool ticker_ticks(ticker_t *ticker, int32_t nticks); +bool ticker_tick(ticker_t *ticker); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TICKER_C_)) +JEMALLOC_INLINE void +ticker_init(ticker_t *ticker, int32_t nticks) +{ + + ticker->tick = nticks; + ticker->nticks = nticks; +} + +JEMALLOC_INLINE void +ticker_copy(ticker_t *ticker, const ticker_t *other) +{ + + *ticker = *other; +} + +JEMALLOC_INLINE int32_t +ticker_read(const ticker_t *ticker) +{ + + return (ticker->tick); +} + +JEMALLOC_INLINE bool +ticker_ticks(ticker_t *ticker, int32_t nticks) +{ + + if (unlikely(ticker->tick < nticks)) { + ticker->tick = ticker->nticks; + return (true); + } + ticker->tick -= nticks; + return(false); +} + +JEMALLOC_INLINE bool +ticker_tick(ticker_t *ticker) +{ + + return (ticker_ticks(ticker, 1)); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/tsd.h b/contrib/jemalloc/include/jemalloc/internal/tsd.h new file mode 100644 index 0000000..bf11341 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/tsd.h @@ -0,0 +1,747 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +/* Maximum number of malloc_tsd users with cleanup functions. */ +#define MALLOC_TSD_CLEANUPS_MAX 2 + +typedef bool (*malloc_tsd_cleanup_t)(void); + +#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \ + !defined(_WIN32)) +typedef struct tsd_init_block_s tsd_init_block_t; +typedef struct tsd_init_head_s tsd_init_head_t; +#endif + +typedef struct tsd_s tsd_t; +typedef struct tsdn_s tsdn_t; + +#define TSDN_NULL ((tsdn_t *)0) + +typedef enum { + tsd_state_uninitialized, + tsd_state_nominal, + tsd_state_purgatory, + tsd_state_reincarnated +} tsd_state_t; + +/* + * TLS/TSD-agnostic macro-based implementation of thread-specific data. There + * are five macros that support (at least) three use cases: file-private, + * library-private, and library-private inlined. Following is an example + * library-private tsd variable: + * + * In example.h: + * typedef struct { + * int x; + * int y; + * } example_t; + * #define EX_INITIALIZER JEMALLOC_CONCAT({0, 0}) + * malloc_tsd_types(example_, example_t) + * malloc_tsd_protos(, example_, example_t) + * malloc_tsd_externs(example_, example_t) + * In example.c: + * malloc_tsd_data(, example_, example_t, EX_INITIALIZER) + * malloc_tsd_funcs(, example_, example_t, EX_INITIALIZER, + * example_tsd_cleanup) + * + * The result is a set of generated functions, e.g.: + * + * bool example_tsd_boot(void) {...} + * bool example_tsd_booted_get(void) {...} + * example_t *example_tsd_get() {...} + * void example_tsd_set(example_t *val) {...} + * + * Note that all of the functions deal in terms of (a_type *) rather than + * (a_type) so that it is possible to support non-pointer types (unlike + * pthreads TSD). example_tsd_cleanup() is passed an (a_type *) pointer that is + * cast to (void *). This means that the cleanup function needs to cast the + * function argument to (a_type *), then dereference the resulting pointer to + * access fields, e.g. + * + * void + * example_tsd_cleanup(void *arg) + * { + * example_t *example = (example_t *)arg; + * + * example->x = 42; + * [...] + * if ([want the cleanup function to be called again]) + * example_tsd_set(example); + * } + * + * If example_tsd_set() is called within example_tsd_cleanup(), it will be + * called again. This is similar to how pthreads TSD destruction works, except + * that pthreads only calls the cleanup function again if the value was set to + * non-NULL. + */ + +/* malloc_tsd_types(). */ +#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP +#define malloc_tsd_types(a_name, a_type) +#elif (defined(JEMALLOC_TLS)) +#define malloc_tsd_types(a_name, a_type) +#elif (defined(_WIN32)) +#define malloc_tsd_types(a_name, a_type) \ +typedef struct { \ + bool initialized; \ + a_type val; \ +} a_name##tsd_wrapper_t; +#else +#define malloc_tsd_types(a_name, a_type) \ +typedef struct { \ + bool initialized; \ + a_type val; \ +} a_name##tsd_wrapper_t; +#endif + +/* malloc_tsd_protos(). */ +#define malloc_tsd_protos(a_attr, a_name, a_type) \ +a_attr bool \ +a_name##tsd_boot0(void); \ +a_attr void \ +a_name##tsd_boot1(void); \ +a_attr bool \ +a_name##tsd_boot(void); \ +a_attr bool \ +a_name##tsd_booted_get(void); \ +a_attr a_type * \ +a_name##tsd_get(void); \ +a_attr void \ +a_name##tsd_set(a_type *val); + +/* malloc_tsd_externs(). */ +#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP +#define malloc_tsd_externs(a_name, a_type) \ +extern __thread a_type a_name##tsd_tls; \ +extern __thread bool a_name##tsd_initialized; \ +extern bool a_name##tsd_booted; +#elif (defined(JEMALLOC_TLS)) +#define malloc_tsd_externs(a_name, a_type) \ +extern __thread a_type a_name##tsd_tls; \ +extern pthread_key_t a_name##tsd_tsd; \ +extern bool a_name##tsd_booted; +#elif (defined(_WIN32)) +#define malloc_tsd_externs(a_name, a_type) \ +extern DWORD a_name##tsd_tsd; \ +extern a_name##tsd_wrapper_t a_name##tsd_boot_wrapper; \ +extern bool a_name##tsd_booted; +#else +#define malloc_tsd_externs(a_name, a_type) \ +extern pthread_key_t a_name##tsd_tsd; \ +extern tsd_init_head_t a_name##tsd_init_head; \ +extern a_name##tsd_wrapper_t a_name##tsd_boot_wrapper; \ +extern bool a_name##tsd_booted; +#endif + +/* malloc_tsd_data(). */ +#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP +#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \ +a_attr __thread a_type JEMALLOC_TLS_MODEL \ + a_name##tsd_tls = a_initializer; \ +a_attr __thread bool JEMALLOC_TLS_MODEL \ + a_name##tsd_initialized = false; \ +a_attr bool a_name##tsd_booted = false; +#elif (defined(JEMALLOC_TLS)) +#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \ +a_attr __thread a_type JEMALLOC_TLS_MODEL \ + a_name##tsd_tls = a_initializer; \ +a_attr pthread_key_t a_name##tsd_tsd; \ +a_attr bool a_name##tsd_booted = false; +#elif (defined(_WIN32)) +#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \ +a_attr DWORD a_name##tsd_tsd; \ +a_attr a_name##tsd_wrapper_t a_name##tsd_boot_wrapper = { \ + false, \ + a_initializer \ +}; \ +a_attr bool a_name##tsd_booted = false; +#else +#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \ +a_attr pthread_key_t a_name##tsd_tsd; \ +a_attr tsd_init_head_t a_name##tsd_init_head = { \ + ql_head_initializer(blocks), \ + MALLOC_MUTEX_INITIALIZER \ +}; \ +a_attr a_name##tsd_wrapper_t a_name##tsd_boot_wrapper = { \ + false, \ + a_initializer \ +}; \ +a_attr bool a_name##tsd_booted = false; +#endif + +/* malloc_tsd_funcs(). */ +#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP +#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \ + a_cleanup) \ +/* Initialization/cleanup. */ \ +a_attr bool \ +a_name##tsd_cleanup_wrapper(void) \ +{ \ + \ + if (a_name##tsd_initialized) { \ + a_name##tsd_initialized = false; \ + a_cleanup(&a_name##tsd_tls); \ + } \ + return (a_name##tsd_initialized); \ +} \ +a_attr bool \ +a_name##tsd_boot0(void) \ +{ \ + \ + if (a_cleanup != malloc_tsd_no_cleanup) { \ + malloc_tsd_cleanup_register( \ + &a_name##tsd_cleanup_wrapper); \ + } \ + a_name##tsd_booted = true; \ + return (false); \ +} \ +a_attr void \ +a_name##tsd_boot1(void) \ +{ \ + \ + /* Do nothing. */ \ +} \ +a_attr bool \ +a_name##tsd_boot(void) \ +{ \ + \ + return (a_name##tsd_boot0()); \ +} \ +a_attr bool \ +a_name##tsd_booted_get(void) \ +{ \ + \ + return (a_name##tsd_booted); \ +} \ +/* Get/set. */ \ +a_attr a_type * \ +a_name##tsd_get(void) \ +{ \ + \ + assert(a_name##tsd_booted); \ + return (&a_name##tsd_tls); \ +} \ +a_attr void \ +a_name##tsd_set(a_type *val) \ +{ \ + \ + assert(a_name##tsd_booted); \ + a_name##tsd_tls = (*val); \ + if (a_cleanup != malloc_tsd_no_cleanup) \ + a_name##tsd_initialized = true; \ +} +#elif (defined(JEMALLOC_TLS)) +#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \ + a_cleanup) \ +/* Initialization/cleanup. */ \ +a_attr bool \ +a_name##tsd_boot0(void) \ +{ \ + \ + if (a_cleanup != malloc_tsd_no_cleanup) { \ + if (pthread_key_create(&a_name##tsd_tsd, a_cleanup) != \ + 0) \ + return (true); \ + } \ + a_name##tsd_booted = true; \ + return (false); \ +} \ +a_attr void \ +a_name##tsd_boot1(void) \ +{ \ + \ + /* Do nothing. */ \ +} \ +a_attr bool \ +a_name##tsd_boot(void) \ +{ \ + \ + return (a_name##tsd_boot0()); \ +} \ +a_attr bool \ +a_name##tsd_booted_get(void) \ +{ \ + \ + return (a_name##tsd_booted); \ +} \ +/* Get/set. */ \ +a_attr a_type * \ +a_name##tsd_get(void) \ +{ \ + \ + assert(a_name##tsd_booted); \ + return (&a_name##tsd_tls); \ +} \ +a_attr void \ +a_name##tsd_set(a_type *val) \ +{ \ + \ + assert(a_name##tsd_booted); \ + a_name##tsd_tls = (*val); \ + if (a_cleanup != malloc_tsd_no_cleanup) { \ + if (pthread_setspecific(a_name##tsd_tsd, \ + (void *)(&a_name##tsd_tls))) { \ + malloc_write(": Error" \ + " setting TSD for "#a_name"\n"); \ + if (opt_abort) \ + abort(); \ + } \ + } \ +} +#elif (defined(_WIN32)) +#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \ + a_cleanup) \ +/* Initialization/cleanup. */ \ +a_attr bool \ +a_name##tsd_cleanup_wrapper(void) \ +{ \ + DWORD error = GetLastError(); \ + a_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *) \ + TlsGetValue(a_name##tsd_tsd); \ + SetLastError(error); \ + \ + if (wrapper == NULL) \ + return (false); \ + if (a_cleanup != malloc_tsd_no_cleanup && \ + wrapper->initialized) { \ + wrapper->initialized = false; \ + a_cleanup(&wrapper->val); \ + if (wrapper->initialized) { \ + /* Trigger another cleanup round. */ \ + return (true); \ + } \ + } \ + malloc_tsd_dalloc(wrapper); \ + return (false); \ +} \ +a_attr void \ +a_name##tsd_wrapper_set(a_name##tsd_wrapper_t *wrapper) \ +{ \ + \ + if (!TlsSetValue(a_name##tsd_tsd, (void *)wrapper)) { \ + malloc_write(": Error setting" \ + " TSD for "#a_name"\n"); \ + abort(); \ + } \ +} \ +a_attr a_name##tsd_wrapper_t * \ +a_name##tsd_wrapper_get(void) \ +{ \ + DWORD error = GetLastError(); \ + a_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *) \ + TlsGetValue(a_name##tsd_tsd); \ + SetLastError(error); \ + \ + if (unlikely(wrapper == NULL)) { \ + wrapper = (a_name##tsd_wrapper_t *) \ + malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t)); \ + if (wrapper == NULL) { \ + malloc_write(": Error allocating" \ + " TSD for "#a_name"\n"); \ + abort(); \ + } else { \ + wrapper->initialized = false; \ + wrapper->val = a_initializer; \ + } \ + a_name##tsd_wrapper_set(wrapper); \ + } \ + return (wrapper); \ +} \ +a_attr bool \ +a_name##tsd_boot0(void) \ +{ \ + \ + a_name##tsd_tsd = TlsAlloc(); \ + if (a_name##tsd_tsd == TLS_OUT_OF_INDEXES) \ + return (true); \ + if (a_cleanup != malloc_tsd_no_cleanup) { \ + malloc_tsd_cleanup_register( \ + &a_name##tsd_cleanup_wrapper); \ + } \ + a_name##tsd_wrapper_set(&a_name##tsd_boot_wrapper); \ + a_name##tsd_booted = true; \ + return (false); \ +} \ +a_attr void \ +a_name##tsd_boot1(void) \ +{ \ + a_name##tsd_wrapper_t *wrapper; \ + wrapper = (a_name##tsd_wrapper_t *) \ + malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t)); \ + if (wrapper == NULL) { \ + malloc_write(": Error allocating" \ + " TSD for "#a_name"\n"); \ + abort(); \ + } \ + memcpy(wrapper, &a_name##tsd_boot_wrapper, \ + sizeof(a_name##tsd_wrapper_t)); \ + a_name##tsd_wrapper_set(wrapper); \ +} \ +a_attr bool \ +a_name##tsd_boot(void) \ +{ \ + \ + if (a_name##tsd_boot0()) \ + return (true); \ + a_name##tsd_boot1(); \ + return (false); \ +} \ +a_attr bool \ +a_name##tsd_booted_get(void) \ +{ \ + \ + return (a_name##tsd_booted); \ +} \ +/* Get/set. */ \ +a_attr a_type * \ +a_name##tsd_get(void) \ +{ \ + a_name##tsd_wrapper_t *wrapper; \ + \ + assert(a_name##tsd_booted); \ + wrapper = a_name##tsd_wrapper_get(); \ + return (&wrapper->val); \ +} \ +a_attr void \ +a_name##tsd_set(a_type *val) \ +{ \ + a_name##tsd_wrapper_t *wrapper; \ + \ + assert(a_name##tsd_booted); \ + wrapper = a_name##tsd_wrapper_get(); \ + wrapper->val = *(val); \ + if (a_cleanup != malloc_tsd_no_cleanup) \ + wrapper->initialized = true; \ +} +#else +#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \ + a_cleanup) \ +/* Initialization/cleanup. */ \ +a_attr void \ +a_name##tsd_cleanup_wrapper(void *arg) \ +{ \ + a_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *)arg; \ + \ + if (a_cleanup != malloc_tsd_no_cleanup && \ + wrapper->initialized) { \ + wrapper->initialized = false; \ + a_cleanup(&wrapper->val); \ + if (wrapper->initialized) { \ + /* Trigger another cleanup round. */ \ + if (pthread_setspecific(a_name##tsd_tsd, \ + (void *)wrapper)) { \ + malloc_write(": Error" \ + " setting TSD for "#a_name"\n"); \ + if (opt_abort) \ + abort(); \ + } \ + return; \ + } \ + } \ + malloc_tsd_dalloc(wrapper); \ +} \ +a_attr void \ +a_name##tsd_wrapper_set(a_name##tsd_wrapper_t *wrapper) \ +{ \ + \ + if (pthread_setspecific(a_name##tsd_tsd, \ + (void *)wrapper)) { \ + malloc_write(": Error setting" \ + " TSD for "#a_name"\n"); \ + abort(); \ + } \ +} \ +a_attr a_name##tsd_wrapper_t * \ +a_name##tsd_wrapper_get(void) \ +{ \ + a_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *) \ + pthread_getspecific(a_name##tsd_tsd); \ + \ + if (unlikely(wrapper == NULL)) { \ + tsd_init_block_t block; \ + wrapper = tsd_init_check_recursion( \ + &a_name##tsd_init_head, &block); \ + if (wrapper) \ + return (wrapper); \ + wrapper = (a_name##tsd_wrapper_t *) \ + malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t)); \ + block.data = wrapper; \ + if (wrapper == NULL) { \ + malloc_write(": Error allocating" \ + " TSD for "#a_name"\n"); \ + abort(); \ + } else { \ + wrapper->initialized = false; \ + wrapper->val = a_initializer; \ + } \ + a_name##tsd_wrapper_set(wrapper); \ + tsd_init_finish(&a_name##tsd_init_head, &block); \ + } \ + return (wrapper); \ +} \ +a_attr bool \ +a_name##tsd_boot0(void) \ +{ \ + \ + if (pthread_key_create(&a_name##tsd_tsd, \ + a_name##tsd_cleanup_wrapper) != 0) \ + return (true); \ + a_name##tsd_wrapper_set(&a_name##tsd_boot_wrapper); \ + a_name##tsd_booted = true; \ + return (false); \ +} \ +a_attr void \ +a_name##tsd_boot1(void) \ +{ \ + a_name##tsd_wrapper_t *wrapper; \ + wrapper = (a_name##tsd_wrapper_t *) \ + malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t)); \ + if (wrapper == NULL) { \ + malloc_write(": Error allocating" \ + " TSD for "#a_name"\n"); \ + abort(); \ + } \ + memcpy(wrapper, &a_name##tsd_boot_wrapper, \ + sizeof(a_name##tsd_wrapper_t)); \ + a_name##tsd_wrapper_set(wrapper); \ +} \ +a_attr bool \ +a_name##tsd_boot(void) \ +{ \ + \ + if (a_name##tsd_boot0()) \ + return (true); \ + a_name##tsd_boot1(); \ + return (false); \ +} \ +a_attr bool \ +a_name##tsd_booted_get(void) \ +{ \ + \ + return (a_name##tsd_booted); \ +} \ +/* Get/set. */ \ +a_attr a_type * \ +a_name##tsd_get(void) \ +{ \ + a_name##tsd_wrapper_t *wrapper; \ + \ + assert(a_name##tsd_booted); \ + wrapper = a_name##tsd_wrapper_get(); \ + return (&wrapper->val); \ +} \ +a_attr void \ +a_name##tsd_set(a_type *val) \ +{ \ + a_name##tsd_wrapper_t *wrapper; \ + \ + assert(a_name##tsd_booted); \ + wrapper = a_name##tsd_wrapper_get(); \ + wrapper->val = *(val); \ + if (a_cleanup != malloc_tsd_no_cleanup) \ + wrapper->initialized = true; \ +} +#endif + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \ + !defined(_WIN32)) +struct tsd_init_block_s { + ql_elm(tsd_init_block_t) link; + pthread_t thread; + void *data; +}; +struct tsd_init_head_s { + ql_head(tsd_init_block_t) blocks; + malloc_mutex_t lock; +}; +#endif + +#define MALLOC_TSD \ +/* O(name, type) */ \ + O(tcache, tcache_t *) \ + O(thread_allocated, uint64_t) \ + O(thread_deallocated, uint64_t) \ + O(prof_tdata, prof_tdata_t *) \ + O(iarena, arena_t *) \ + O(arena, arena_t *) \ + O(arenas_tdata, arena_tdata_t *) \ + O(narenas_tdata, unsigned) \ + O(arenas_tdata_bypass, bool) \ + O(tcache_enabled, tcache_enabled_t) \ + O(quarantine, quarantine_t *) \ + O(witnesses, witness_list_t) \ + O(witness_fork, bool) \ + +#define TSD_INITIALIZER { \ + tsd_state_uninitialized, \ + NULL, \ + 0, \ + 0, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + 0, \ + false, \ + tcache_enabled_default, \ + NULL, \ + ql_head_initializer(witnesses), \ + false \ +} + +struct tsd_s { + tsd_state_t state; +#define O(n, t) \ + t n; +MALLOC_TSD +#undef O +}; + +/* + * Wrapper around tsd_t that makes it possible to avoid implicit conversion + * between tsd_t and tsdn_t, where tsdn_t is "nullable" and has to be + * explicitly converted to tsd_t, which is non-nullable. + */ +struct tsdn_s { + tsd_t tsd; +}; + +static const tsd_t tsd_initializer = TSD_INITIALIZER; + +malloc_tsd_types(, tsd_t) + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void *malloc_tsd_malloc(size_t size); +void malloc_tsd_dalloc(void *wrapper); +void malloc_tsd_no_cleanup(void *arg); +void malloc_tsd_cleanup_register(bool (*f)(void)); +tsd_t *malloc_tsd_boot0(void); +void malloc_tsd_boot1(void); +#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \ + !defined(_WIN32)) +void *tsd_init_check_recursion(tsd_init_head_t *head, + tsd_init_block_t *block); +void tsd_init_finish(tsd_init_head_t *head, tsd_init_block_t *block); +#endif +void tsd_cleanup(void *arg); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +malloc_tsd_protos(JEMALLOC_ATTR(unused), , tsd_t) + +tsd_t *tsd_fetch(void); +tsdn_t *tsd_tsdn(tsd_t *tsd); +bool tsd_nominal(tsd_t *tsd); +#define O(n, t) \ +t *tsd_##n##p_get(tsd_t *tsd); \ +t tsd_##n##_get(tsd_t *tsd); \ +void tsd_##n##_set(tsd_t *tsd, t n); +MALLOC_TSD +#undef O +tsdn_t *tsdn_fetch(void); +bool tsdn_null(const tsdn_t *tsdn); +tsd_t *tsdn_tsd(tsdn_t *tsdn); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TSD_C_)) +malloc_tsd_externs(, tsd_t) +malloc_tsd_funcs(JEMALLOC_ALWAYS_INLINE, , tsd_t, tsd_initializer, tsd_cleanup) + +JEMALLOC_ALWAYS_INLINE tsd_t * +tsd_fetch(void) +{ + tsd_t *tsd = tsd_get(); + + if (unlikely(tsd->state != tsd_state_nominal)) { + if (tsd->state == tsd_state_uninitialized) { + tsd->state = tsd_state_nominal; + /* Trigger cleanup handler registration. */ + tsd_set(tsd); + } else if (tsd->state == tsd_state_purgatory) { + tsd->state = tsd_state_reincarnated; + tsd_set(tsd); + } else + assert(tsd->state == tsd_state_reincarnated); + } + + return (tsd); +} + +JEMALLOC_ALWAYS_INLINE tsdn_t * +tsd_tsdn(tsd_t *tsd) +{ + + return ((tsdn_t *)tsd); +} + +JEMALLOC_INLINE bool +tsd_nominal(tsd_t *tsd) +{ + + return (tsd->state == tsd_state_nominal); +} + +#define O(n, t) \ +JEMALLOC_ALWAYS_INLINE t * \ +tsd_##n##p_get(tsd_t *tsd) \ +{ \ + \ + return (&tsd->n); \ +} \ + \ +JEMALLOC_ALWAYS_INLINE t \ +tsd_##n##_get(tsd_t *tsd) \ +{ \ + \ + return (*tsd_##n##p_get(tsd)); \ +} \ + \ +JEMALLOC_ALWAYS_INLINE void \ +tsd_##n##_set(tsd_t *tsd, t n) \ +{ \ + \ + assert(tsd->state == tsd_state_nominal); \ + tsd->n = n; \ +} +MALLOC_TSD +#undef O + +JEMALLOC_ALWAYS_INLINE tsdn_t * +tsdn_fetch(void) +{ + + if (!tsd_booted_get()) + return (NULL); + + return (tsd_tsdn(tsd_fetch())); +} + +JEMALLOC_ALWAYS_INLINE bool +tsdn_null(const tsdn_t *tsdn) +{ + + return (tsdn == NULL); +} + +JEMALLOC_ALWAYS_INLINE tsd_t * +tsdn_tsd(tsdn_t *tsdn) +{ + + assert(!tsdn_null(tsdn)); + + return (&tsdn->tsd); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/util.h b/contrib/jemalloc/include/jemalloc/internal/util.h new file mode 100644 index 0000000..a0c2203 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/util.h @@ -0,0 +1,348 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#ifdef _WIN32 +# ifdef _WIN64 +# define FMT64_PREFIX "ll" +# define FMTPTR_PREFIX "ll" +# else +# define FMT64_PREFIX "ll" +# define FMTPTR_PREFIX "" +# endif +# define FMTd32 "d" +# define FMTu32 "u" +# define FMTx32 "x" +# define FMTd64 FMT64_PREFIX "d" +# define FMTu64 FMT64_PREFIX "u" +# define FMTx64 FMT64_PREFIX "x" +# define FMTdPTR FMTPTR_PREFIX "d" +# define FMTuPTR FMTPTR_PREFIX "u" +# define FMTxPTR FMTPTR_PREFIX "x" +#else +# include +# define FMTd32 PRId32 +# define FMTu32 PRIu32 +# define FMTx32 PRIx32 +# define FMTd64 PRId64 +# define FMTu64 PRIu64 +# define FMTx64 PRIx64 +# define FMTdPTR PRIdPTR +# define FMTuPTR PRIuPTR +# define FMTxPTR PRIxPTR +#endif + +/* Size of stack-allocated buffer passed to buferror(). */ +#define BUFERROR_BUF 64 + +/* + * Size of stack-allocated buffer used by malloc_{,v,vc}printf(). This must be + * large enough for all possible uses within jemalloc. + */ +#define MALLOC_PRINTF_BUFSIZE 4096 + +/* Junk fill patterns. */ +#define JEMALLOC_ALLOC_JUNK ((uint8_t)0xa5) +#define JEMALLOC_FREE_JUNK ((uint8_t)0x5a) + +/* + * Wrap a cpp argument that contains commas such that it isn't broken up into + * multiple arguments. + */ +#define JEMALLOC_ARG_CONCAT(...) __VA_ARGS__ + +/* + * Silence compiler warnings due to uninitialized values. This is used + * wherever the compiler fails to recognize that the variable is never used + * uninitialized. + */ +#ifdef JEMALLOC_CC_SILENCE +# define JEMALLOC_CC_SILENCE_INIT(v) = v +#else +# define JEMALLOC_CC_SILENCE_INIT(v) +#endif + +#define JEMALLOC_GNUC_PREREQ(major, minor) \ + (!defined(__clang__) && \ + (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))) +#ifndef __has_builtin +# define __has_builtin(builtin) (0) +#endif +#define JEMALLOC_CLANG_HAS_BUILTIN(builtin) \ + (defined(__clang__) && __has_builtin(builtin)) + +#ifdef __GNUC__ +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +# if JEMALLOC_GNUC_PREREQ(4, 6) || \ + JEMALLOC_CLANG_HAS_BUILTIN(__builtin_unreachable) +# define unreachable() __builtin_unreachable() +# else +# define unreachable() abort() +# endif +#else +# define likely(x) !!(x) +# define unlikely(x) !!(x) +# define unreachable() abort() +#endif + +#include "jemalloc/internal/assert.h" + +/* Use to assert a particular configuration, e.g., cassert(config_debug). */ +#define cassert(c) do { \ + if (unlikely(!(c))) \ + not_reached(); \ +} while (0) + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +int buferror(int err, char *buf, size_t buflen); +uintmax_t malloc_strtoumax(const char *restrict nptr, + char **restrict endptr, int base); +void malloc_write(const char *s); + +/* + * malloc_vsnprintf() supports a subset of snprintf(3) that avoids floating + * point math. + */ +size_t malloc_vsnprintf(char *str, size_t size, const char *format, + va_list ap); +size_t malloc_snprintf(char *str, size_t size, const char *format, ...) + JEMALLOC_FORMAT_PRINTF(3, 4); +void malloc_vcprintf(void (*write_cb)(void *, const char *), void *cbopaque, + const char *format, va_list ap); +void malloc_cprintf(void (*write)(void *, const char *), void *cbopaque, + const char *format, ...) JEMALLOC_FORMAT_PRINTF(3, 4); +void malloc_printf(const char *format, ...) JEMALLOC_FORMAT_PRINTF(1, 2); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +unsigned ffs_llu(unsigned long long bitmap); +unsigned ffs_lu(unsigned long bitmap); +unsigned ffs_u(unsigned bitmap); +unsigned ffs_zu(size_t bitmap); +unsigned ffs_u64(uint64_t bitmap); +unsigned ffs_u32(uint32_t bitmap); +uint64_t pow2_ceil_u64(uint64_t x); +uint32_t pow2_ceil_u32(uint32_t x); +size_t pow2_ceil_zu(size_t x); +unsigned lg_floor(size_t x); +void set_errno(int errnum); +int get_errno(void); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_UTIL_C_)) + +/* Sanity check. */ +#if !defined(JEMALLOC_INTERNAL_FFSLL) || !defined(JEMALLOC_INTERNAL_FFSL) \ + || !defined(JEMALLOC_INTERNAL_FFS) +# error JEMALLOC_INTERNAL_FFS{,L,LL} should have been defined by configure +#endif + +JEMALLOC_ALWAYS_INLINE unsigned +ffs_llu(unsigned long long bitmap) +{ + + return (JEMALLOC_INTERNAL_FFSLL(bitmap)); +} + +JEMALLOC_ALWAYS_INLINE unsigned +ffs_lu(unsigned long bitmap) +{ + + return (JEMALLOC_INTERNAL_FFSL(bitmap)); +} + +JEMALLOC_ALWAYS_INLINE unsigned +ffs_u(unsigned bitmap) +{ + + return (JEMALLOC_INTERNAL_FFS(bitmap)); +} + +JEMALLOC_ALWAYS_INLINE unsigned +ffs_zu(size_t bitmap) +{ + +#if LG_SIZEOF_PTR == LG_SIZEOF_INT + return (ffs_u(bitmap)); +#elif LG_SIZEOF_PTR == LG_SIZEOF_LONG + return (ffs_lu(bitmap)); +#elif LG_SIZEOF_PTR == LG_SIZEOF_LONG_LONG + return (ffs_llu(bitmap)); +#else +#error No implementation for size_t ffs() +#endif +} + +JEMALLOC_ALWAYS_INLINE unsigned +ffs_u64(uint64_t bitmap) +{ + +#if LG_SIZEOF_LONG == 3 + return (ffs_lu(bitmap)); +#elif LG_SIZEOF_LONG_LONG == 3 + return (ffs_llu(bitmap)); +#else +#error No implementation for 64-bit ffs() +#endif +} + +JEMALLOC_ALWAYS_INLINE unsigned +ffs_u32(uint32_t bitmap) +{ + +#if LG_SIZEOF_INT == 2 + return (ffs_u(bitmap)); +#else +#error No implementation for 32-bit ffs() +#endif + return (ffs_u(bitmap)); +} + +JEMALLOC_INLINE uint64_t +pow2_ceil_u64(uint64_t x) +{ + + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + x++; + return (x); +} + +JEMALLOC_INLINE uint32_t +pow2_ceil_u32(uint32_t x) +{ + + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x++; + return (x); +} + +/* Compute the smallest power of 2 that is >= x. */ +JEMALLOC_INLINE size_t +pow2_ceil_zu(size_t x) +{ + +#if (LG_SIZEOF_PTR == 3) + return (pow2_ceil_u64(x)); +#else + return (pow2_ceil_u32(x)); +#endif +} + +#if (defined(__i386__) || defined(__amd64__) || defined(__x86_64__)) +JEMALLOC_INLINE unsigned +lg_floor(size_t x) +{ + size_t ret; + + assert(x != 0); + + asm ("bsr %1, %0" + : "=r"(ret) // Outputs. + : "r"(x) // Inputs. + ); + assert(ret < UINT_MAX); + return ((unsigned)ret); +} +#elif (defined(_MSC_VER)) +JEMALLOC_INLINE unsigned +lg_floor(size_t x) +{ + unsigned long ret; + + assert(x != 0); + +#if (LG_SIZEOF_PTR == 3) + _BitScanReverse64(&ret, x); +#elif (LG_SIZEOF_PTR == 2) + _BitScanReverse(&ret, x); +#else +# error "Unsupported type size for lg_floor()" +#endif + assert(ret < UINT_MAX); + return ((unsigned)ret); +} +#elif (defined(JEMALLOC_HAVE_BUILTIN_CLZ)) +JEMALLOC_INLINE unsigned +lg_floor(size_t x) +{ + + assert(x != 0); + +#if (LG_SIZEOF_PTR == LG_SIZEOF_INT) + return (((8 << LG_SIZEOF_PTR) - 1) - __builtin_clz(x)); +#elif (LG_SIZEOF_PTR == LG_SIZEOF_LONG) + return (((8 << LG_SIZEOF_PTR) - 1) - __builtin_clzl(x)); +#else +# error "Unsupported type size for lg_floor()" +#endif +} +#else +JEMALLOC_INLINE unsigned +lg_floor(size_t x) +{ + + assert(x != 0); + + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); +#if (LG_SIZEOF_PTR == 3) + x |= (x >> 32); +#endif + if (x == SIZE_T_MAX) + return ((8 << LG_SIZEOF_PTR) - 1); + x++; + return (ffs_zu(x) - 2); +} +#endif + +/* Set error code. */ +JEMALLOC_INLINE void +set_errno(int errnum) +{ + +#ifdef _WIN32 + SetLastError(errnum); +#else + errno = errnum; +#endif +} + +/* Get last error code. */ +JEMALLOC_INLINE int +get_errno(void) +{ + +#ifdef _WIN32 + return (GetLastError()); +#else + return (errno); +#endif +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/internal/valgrind.h b/contrib/jemalloc/include/jemalloc/internal/valgrind.h new file mode 100644 index 0000000..1a86808 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/valgrind.h @@ -0,0 +1,114 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#ifdef JEMALLOC_VALGRIND +#include + +/* + * The size that is reported to Valgrind must be consistent through a chain of + * malloc..realloc..realloc calls. Request size isn't recorded anywhere in + * jemalloc, so it is critical that all callers of these macros provide usize + * rather than request size. As a result, buffer overflow detection is + * technically weakened for the standard API, though it is generally accepted + * practice to consider any extra bytes reported by malloc_usable_size() as + * usable space. + */ +#define JEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(ptr, usize) do { \ + if (unlikely(in_valgrind)) \ + valgrind_make_mem_noaccess(ptr, usize); \ +} while (0) +#define JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize) do { \ + if (unlikely(in_valgrind)) \ + valgrind_make_mem_undefined(ptr, usize); \ +} while (0) +#define JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ptr, usize) do { \ + if (unlikely(in_valgrind)) \ + valgrind_make_mem_defined(ptr, usize); \ +} while (0) +/* + * The VALGRIND_MALLOCLIKE_BLOCK() and VALGRIND_RESIZEINPLACE_BLOCK() macro + * calls must be embedded in macros rather than in functions so that when + * Valgrind reports errors, there are no extra stack frames in the backtraces. + */ +#define JEMALLOC_VALGRIND_MALLOC(cond, tsdn, ptr, usize, zero) do { \ + if (unlikely(in_valgrind && cond)) { \ + VALGRIND_MALLOCLIKE_BLOCK(ptr, usize, p2rz(tsdn, ptr), \ + zero); \ + } \ +} while (0) +#define JEMALLOC_VALGRIND_REALLOC(maybe_moved, tsdn, ptr, usize, \ + ptr_maybe_null, old_ptr, old_usize, old_rzsize, old_ptr_maybe_null, \ + zero) do { \ + if (unlikely(in_valgrind)) { \ + size_t rzsize = p2rz(tsdn, ptr); \ + \ + if (!maybe_moved || ptr == old_ptr) { \ + VALGRIND_RESIZEINPLACE_BLOCK(ptr, old_usize, \ + usize, rzsize); \ + if (zero && old_usize < usize) { \ + valgrind_make_mem_defined( \ + (void *)((uintptr_t)ptr + \ + old_usize), usize - old_usize); \ + } \ + } else { \ + if (!old_ptr_maybe_null || old_ptr != NULL) { \ + valgrind_freelike_block(old_ptr, \ + old_rzsize); \ + } \ + if (!ptr_maybe_null || ptr != NULL) { \ + size_t copy_size = (old_usize < usize) \ + ? old_usize : usize; \ + size_t tail_size = usize - copy_size; \ + VALGRIND_MALLOCLIKE_BLOCK(ptr, usize, \ + rzsize, false); \ + if (copy_size > 0) { \ + valgrind_make_mem_defined(ptr, \ + copy_size); \ + } \ + if (zero && tail_size > 0) { \ + valgrind_make_mem_defined( \ + (void *)((uintptr_t)ptr + \ + copy_size), tail_size); \ + } \ + } \ + } \ + } \ +} while (0) +#define JEMALLOC_VALGRIND_FREE(ptr, rzsize) do { \ + if (unlikely(in_valgrind)) \ + valgrind_freelike_block(ptr, rzsize); \ +} while (0) +#else +#define RUNNING_ON_VALGRIND ((unsigned)0) +#define JEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(ptr, usize) do {} while (0) +#define JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize) do {} while (0) +#define JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ptr, usize) do {} while (0) +#define JEMALLOC_VALGRIND_MALLOC(cond, tsdn, ptr, usize, zero) do {} while (0) +#define JEMALLOC_VALGRIND_REALLOC(maybe_moved, tsdn, ptr, usize, \ + ptr_maybe_null, old_ptr, old_usize, old_rzsize, old_ptr_maybe_null, \ + zero) do {} while (0) +#define JEMALLOC_VALGRIND_FREE(ptr, rzsize) do {} while (0) +#endif + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#ifdef JEMALLOC_VALGRIND +void valgrind_make_mem_noaccess(void *ptr, size_t usize); +void valgrind_make_mem_undefined(void *ptr, size_t usize); +void valgrind_make_mem_defined(void *ptr, size_t usize); +void valgrind_freelike_block(void *ptr, size_t usize); +#endif + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ + diff --git a/contrib/jemalloc/include/jemalloc/internal/witness.h b/contrib/jemalloc/include/jemalloc/internal/witness.h new file mode 100644 index 0000000..d78dca2 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/internal/witness.h @@ -0,0 +1,249 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct witness_s witness_t; +typedef unsigned witness_rank_t; +typedef ql_head(witness_t) witness_list_t; +typedef int witness_comp_t (const witness_t *, const witness_t *); + +/* + * Lock ranks. Witnesses with rank WITNESS_RANK_OMIT are completely ignored by + * the witness machinery. + */ +#define WITNESS_RANK_OMIT 0U + +#define WITNESS_RANK_INIT 1U +#define WITNESS_RANK_CTL 1U +#define WITNESS_RANK_ARENAS 2U + +#define WITNESS_RANK_PROF_DUMP 3U +#define WITNESS_RANK_PROF_BT2GCTX 4U +#define WITNESS_RANK_PROF_TDATAS 5U +#define WITNESS_RANK_PROF_TDATA 6U +#define WITNESS_RANK_PROF_GCTX 7U + +#define WITNESS_RANK_ARENA 8U +#define WITNESS_RANK_ARENA_CHUNKS 9U +#define WITNESS_RANK_ARENA_NODE_CACHE 10 + +#define WITNESS_RANK_BASE 11U + +#define WITNESS_RANK_LEAF 0xffffffffU +#define WITNESS_RANK_ARENA_BIN WITNESS_RANK_LEAF +#define WITNESS_RANK_ARENA_HUGE WITNESS_RANK_LEAF +#define WITNESS_RANK_DSS WITNESS_RANK_LEAF +#define WITNESS_RANK_PROF_ACTIVE WITNESS_RANK_LEAF +#define WITNESS_RANK_PROF_DUMP_SEQ WITNESS_RANK_LEAF +#define WITNESS_RANK_PROF_GDUMP WITNESS_RANK_LEAF +#define WITNESS_RANK_PROF_NEXT_THR_UID WITNESS_RANK_LEAF +#define WITNESS_RANK_PROF_THREAD_ACTIVE_INIT WITNESS_RANK_LEAF + +#define WITNESS_INITIALIZER(rank) {"initializer", rank, NULL, {NULL, NULL}} + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct witness_s { + /* Name, used for printing lock order reversal messages. */ + const char *name; + + /* + * Witness rank, where 0 is lowest and UINT_MAX is highest. Witnesses + * must be acquired in order of increasing rank. + */ + witness_rank_t rank; + + /* + * If two witnesses are of equal rank and they have the samp comp + * function pointer, it is called as a last attempt to differentiate + * between witnesses of equal rank. + */ + witness_comp_t *comp; + + /* Linkage for thread's currently owned locks. */ + ql_elm(witness_t) link; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void witness_init(witness_t *witness, const char *name, witness_rank_t rank, + witness_comp_t *comp); +#ifdef JEMALLOC_JET +typedef void (witness_lock_error_t)(const witness_list_t *, const witness_t *); +extern witness_lock_error_t *witness_lock_error; +#else +void witness_lock_error(const witness_list_t *witnesses, + const witness_t *witness); +#endif +#ifdef JEMALLOC_JET +typedef void (witness_owner_error_t)(const witness_t *); +extern witness_owner_error_t *witness_owner_error; +#else +void witness_owner_error(const witness_t *witness); +#endif +#ifdef JEMALLOC_JET +typedef void (witness_not_owner_error_t)(const witness_t *); +extern witness_not_owner_error_t *witness_not_owner_error; +#else +void witness_not_owner_error(const witness_t *witness); +#endif +#ifdef JEMALLOC_JET +typedef void (witness_lockless_error_t)(const witness_list_t *); +extern witness_lockless_error_t *witness_lockless_error; +#else +void witness_lockless_error(const witness_list_t *witnesses); +#endif + +void witnesses_cleanup(tsd_t *tsd); +void witness_fork_cleanup(tsd_t *tsd); +void witness_prefork(tsd_t *tsd); +void witness_postfork_parent(tsd_t *tsd); +void witness_postfork_child(tsd_t *tsd); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +void witness_assert_owner(tsdn_t *tsdn, const witness_t *witness); +void witness_assert_not_owner(tsdn_t *tsdn, const witness_t *witness); +void witness_assert_lockless(tsdn_t *tsdn); +void witness_lock(tsdn_t *tsdn, witness_t *witness); +void witness_unlock(tsdn_t *tsdn, witness_t *witness); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MUTEX_C_)) +JEMALLOC_INLINE void +witness_assert_owner(tsdn_t *tsdn, const witness_t *witness) +{ + tsd_t *tsd; + witness_list_t *witnesses; + witness_t *w; + + if (!config_debug) + return; + + if (tsdn_null(tsdn)) + return; + tsd = tsdn_tsd(tsdn); + if (witness->rank == WITNESS_RANK_OMIT) + return; + + witnesses = tsd_witnessesp_get(tsd); + ql_foreach(w, witnesses, link) { + if (w == witness) + return; + } + witness_owner_error(witness); +} + +JEMALLOC_INLINE void +witness_assert_not_owner(tsdn_t *tsdn, const witness_t *witness) +{ + tsd_t *tsd; + witness_list_t *witnesses; + witness_t *w; + + if (!config_debug) + return; + + if (tsdn_null(tsdn)) + return; + tsd = tsdn_tsd(tsdn); + if (witness->rank == WITNESS_RANK_OMIT) + return; + + witnesses = tsd_witnessesp_get(tsd); + ql_foreach(w, witnesses, link) { + if (w == witness) + witness_not_owner_error(witness); + } +} + +JEMALLOC_INLINE void +witness_assert_lockless(tsdn_t *tsdn) +{ + tsd_t *tsd; + witness_list_t *witnesses; + witness_t *w; + + if (!config_debug) + return; + + if (tsdn_null(tsdn)) + return; + tsd = tsdn_tsd(tsdn); + + witnesses = tsd_witnessesp_get(tsd); + w = ql_last(witnesses, link); + if (w != NULL) + witness_lockless_error(witnesses); +} + +JEMALLOC_INLINE void +witness_lock(tsdn_t *tsdn, witness_t *witness) +{ + tsd_t *tsd; + witness_list_t *witnesses; + witness_t *w; + + if (!config_debug) + return; + + if (tsdn_null(tsdn)) + return; + tsd = tsdn_tsd(tsdn); + if (witness->rank == WITNESS_RANK_OMIT) + return; + + witness_assert_not_owner(tsdn, witness); + + witnesses = tsd_witnessesp_get(tsd); + w = ql_last(witnesses, link); + if (w == NULL) { + /* No other locks; do nothing. */ + } else if (tsd_witness_fork_get(tsd) && w->rank <= witness->rank) { + /* Forking, and relaxed ranking satisfied. */ + } else if (w->rank > witness->rank) { + /* Not forking, rank order reversal. */ + witness_lock_error(witnesses, witness); + } else if (w->rank == witness->rank && (w->comp == NULL || w->comp != + witness->comp || w->comp(w, witness) > 0)) { + /* + * Missing/incompatible comparison function, or comparison + * function indicates rank order reversal. + */ + witness_lock_error(witnesses, witness); + } + + ql_elm_new(witness, link); + ql_tail_insert(witnesses, witness, link); +} + +JEMALLOC_INLINE void +witness_unlock(tsdn_t *tsdn, witness_t *witness) +{ + tsd_t *tsd; + witness_list_t *witnesses; + + if (!config_debug) + return; + + if (tsdn_null(tsdn)) + return; + tsd = tsdn_tsd(tsdn); + if (witness->rank == WITNESS_RANK_OMIT) + return; + + witness_assert_owner(tsdn, witness); + + witnesses = tsd_witnessesp_get(tsd); + ql_remove(witnesses, witness, link); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/contrib/jemalloc/include/jemalloc/jemalloc.h b/contrib/jemalloc/include/jemalloc/jemalloc.h new file mode 100644 index 0000000..d2c876e --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/jemalloc.h @@ -0,0 +1,381 @@ +#ifndef JEMALLOC_H_ +#define JEMALLOC_H_ +#ifdef __cplusplus +extern "C" { +#endif + +/* Defined if __attribute__((...)) syntax is supported. */ +#define JEMALLOC_HAVE_ATTR + +/* Defined if alloc_size attribute is supported. */ +/* #undef JEMALLOC_HAVE_ATTR_ALLOC_SIZE */ + +/* Defined if format(gnu_printf, ...) attribute is supported. */ +/* #undef JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF */ + +/* Defined if format(printf, ...) attribute is supported. */ +#define JEMALLOC_HAVE_ATTR_FORMAT_PRINTF + +/* + * Define overrides for non-standard allocator-related functions if they are + * present on the system. + */ +/* #undef JEMALLOC_OVERRIDE_MEMALIGN */ +#define JEMALLOC_OVERRIDE_VALLOC + +/* + * At least Linux omits the "const" in: + * + * size_t malloc_usable_size(const void *ptr); + * + * Match the operating system's prototype. + */ +#define JEMALLOC_USABLE_SIZE_CONST const + +/* + * If defined, specify throw() for the public function prototypes when compiling + * with C++. The only justification for this is to match the prototypes that + * glibc defines. + */ +/* #undef JEMALLOC_USE_CXX_THROW */ + +#ifdef _MSC_VER +# ifdef _WIN64 +# define LG_SIZEOF_PTR_WIN 3 +# else +# define LG_SIZEOF_PTR_WIN 2 +# endif +#endif + +/* sizeof(void *) == 2^LG_SIZEOF_PTR. */ +#define LG_SIZEOF_PTR 3 + +/* + * Name mangling for public symbols is controlled by --with-mangling and + * --with-jemalloc-prefix. With default settings the je_ prefix is stripped by + * these macro definitions. + */ +#ifndef JEMALLOC_NO_RENAME +# define je_malloc_conf malloc_conf +# define je_malloc_message malloc_message +# define je_malloc malloc +# define je_calloc calloc +# define je_posix_memalign posix_memalign +# define je_aligned_alloc aligned_alloc +# define je_realloc realloc +# define je_free free +# define je_mallocx mallocx +# define je_rallocx rallocx +# define je_xallocx xallocx +# define je_sallocx sallocx +# define je_dallocx dallocx +# define je_sdallocx sdallocx +# define je_nallocx nallocx +# define je_mallctl mallctl +# define je_mallctlnametomib mallctlnametomib +# define je_mallctlbymib mallctlbymib +# define je_malloc_stats_print malloc_stats_print +# define je_malloc_usable_size malloc_usable_size +# define je_valloc valloc +#endif + +#include "jemalloc_FreeBSD.h" + +#include +#include +#include +#include +#include + +#define JEMALLOC_VERSION "4.2.1-0-g3de035335255d553bdb344c32ffdb603816195d8" +#define JEMALLOC_VERSION_MAJOR 4 +#define JEMALLOC_VERSION_MINOR 2 +#define JEMALLOC_VERSION_BUGFIX 1 +#define JEMALLOC_VERSION_NREV 0 +#define JEMALLOC_VERSION_GID "3de035335255d553bdb344c32ffdb603816195d8" + +# define MALLOCX_LG_ALIGN(la) ((int)(la)) +# if LG_SIZEOF_PTR == 2 +# define MALLOCX_ALIGN(a) ((int)(ffs((int)(a))-1)) +# else +# define MALLOCX_ALIGN(a) \ + ((int)(((size_t)(a) < (size_t)INT_MAX) ? ffs((int)(a))-1 : \ + ffs((int)(((size_t)(a))>>32))+31)) +# endif +# define MALLOCX_ZERO ((int)0x40) +/* + * Bias tcache index bits so that 0 encodes "automatic tcache management", and 1 + * encodes MALLOCX_TCACHE_NONE. + */ +# define MALLOCX_TCACHE(tc) ((int)(((tc)+2) << 8)) +# define MALLOCX_TCACHE_NONE MALLOCX_TCACHE(-1) +/* + * Bias arena index bits so that 0 encodes "use an automatically chosen arena". + */ +# define MALLOCX_ARENA(a) ((((int)(a))+1) << 20) + +#if defined(__cplusplus) && defined(JEMALLOC_USE_CXX_THROW) +# define JEMALLOC_CXX_THROW throw() +#else +# define JEMALLOC_CXX_THROW +#endif + +#if _MSC_VER +# define JEMALLOC_ATTR(s) +# define JEMALLOC_ALIGNED(s) __declspec(align(s)) +# define JEMALLOC_ALLOC_SIZE(s) +# define JEMALLOC_ALLOC_SIZE2(s1, s2) +# ifndef JEMALLOC_EXPORT +# ifdef DLLEXPORT +# define JEMALLOC_EXPORT __declspec(dllexport) +# else +# define JEMALLOC_EXPORT __declspec(dllimport) +# endif +# endif +# define JEMALLOC_FORMAT_PRINTF(s, i) +# define JEMALLOC_NOINLINE __declspec(noinline) +# ifdef __cplusplus +# define JEMALLOC_NOTHROW __declspec(nothrow) +# else +# define JEMALLOC_NOTHROW +# endif +# define JEMALLOC_SECTION(s) __declspec(allocate(s)) +# define JEMALLOC_RESTRICT_RETURN __declspec(restrict) +# if _MSC_VER >= 1900 && !defined(__EDG__) +# define JEMALLOC_ALLOCATOR __declspec(allocator) +# else +# define JEMALLOC_ALLOCATOR +# endif +#elif defined(JEMALLOC_HAVE_ATTR) +# define JEMALLOC_ATTR(s) __attribute__((s)) +# define JEMALLOC_ALIGNED(s) JEMALLOC_ATTR(aligned(s)) +# ifdef JEMALLOC_HAVE_ATTR_ALLOC_SIZE +# define JEMALLOC_ALLOC_SIZE(s) JEMALLOC_ATTR(alloc_size(s)) +# define JEMALLOC_ALLOC_SIZE2(s1, s2) JEMALLOC_ATTR(alloc_size(s1, s2)) +# else +# define JEMALLOC_ALLOC_SIZE(s) +# define JEMALLOC_ALLOC_SIZE2(s1, s2) +# endif +# ifndef JEMALLOC_EXPORT +# define JEMALLOC_EXPORT JEMALLOC_ATTR(visibility("default")) +# endif +# ifdef JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF +# define JEMALLOC_FORMAT_PRINTF(s, i) JEMALLOC_ATTR(format(gnu_printf, s, i)) +# elif defined(JEMALLOC_HAVE_ATTR_FORMAT_PRINTF) +# define JEMALLOC_FORMAT_PRINTF(s, i) JEMALLOC_ATTR(format(printf, s, i)) +# else +# define JEMALLOC_FORMAT_PRINTF(s, i) +# endif +# define JEMALLOC_NOINLINE JEMALLOC_ATTR(noinline) +# define JEMALLOC_NOTHROW JEMALLOC_ATTR(nothrow) +# define JEMALLOC_SECTION(s) JEMALLOC_ATTR(section(s)) +# define JEMALLOC_RESTRICT_RETURN +# define JEMALLOC_ALLOCATOR +#else +# define JEMALLOC_ATTR(s) +# define JEMALLOC_ALIGNED(s) +# define JEMALLOC_ALLOC_SIZE(s) +# define JEMALLOC_ALLOC_SIZE2(s1, s2) +# define JEMALLOC_EXPORT +# define JEMALLOC_FORMAT_PRINTF(s, i) +# define JEMALLOC_NOINLINE +# define JEMALLOC_NOTHROW +# define JEMALLOC_SECTION(s) +# define JEMALLOC_RESTRICT_RETURN +# define JEMALLOC_ALLOCATOR +#endif + +/* + * The je_ prefix on the following public symbol declarations is an artifact + * of namespace management, and should be omitted in application code unless + * JEMALLOC_NO_DEMANGLE is defined (see jemalloc_mangle.h). + */ +extern JEMALLOC_EXPORT const char *je_malloc_conf; +extern JEMALLOC_EXPORT void (*je_malloc_message)(void *cbopaque, + const char *s); + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN + void JEMALLOC_NOTHROW *je_malloc(size_t size) + JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN + void JEMALLOC_NOTHROW *je_calloc(size_t num, size_t size) + JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2); +JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_posix_memalign(void **memptr, + size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1)); +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN + void JEMALLOC_NOTHROW *je_aligned_alloc(size_t alignment, + size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) + JEMALLOC_ALLOC_SIZE(2); +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN + void JEMALLOC_NOTHROW *je_realloc(void *ptr, size_t size) + JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2); +JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_free(void *ptr) + JEMALLOC_CXX_THROW; + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN + void JEMALLOC_NOTHROW *je_mallocx(size_t size, int flags) + JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN + void JEMALLOC_NOTHROW *je_rallocx(void *ptr, size_t size, + int flags) JEMALLOC_ALLOC_SIZE(2); +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_xallocx(void *ptr, size_t size, + size_t extra, int flags); +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_sallocx(const void *ptr, + int flags) JEMALLOC_ATTR(pure); +JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_dallocx(void *ptr, int flags); +JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_sdallocx(void *ptr, size_t size, + int flags); +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_nallocx(size_t size, int flags) + JEMALLOC_ATTR(pure); + +JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctl(const char *name, + void *oldp, size_t *oldlenp, void *newp, size_t newlen); +JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctlnametomib(const char *name, + size_t *mibp, size_t *miblenp); +JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctlbymib(const size_t *mib, + size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); +JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_malloc_stats_print( + void (*write_cb)(void *, const char *), void *je_cbopaque, + const char *opts); +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_malloc_usable_size( + JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW; + +#ifdef JEMALLOC_OVERRIDE_MEMALIGN +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN + void JEMALLOC_NOTHROW *je_memalign(size_t alignment, size_t size) + JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc); +#endif + +#ifdef JEMALLOC_OVERRIDE_VALLOC +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN + void JEMALLOC_NOTHROW *je_valloc(size_t size) JEMALLOC_CXX_THROW + JEMALLOC_ATTR(malloc); +#endif + +/* + * void * + * chunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero, + * bool *commit, unsigned arena_ind); + */ +typedef void *(chunk_alloc_t)(void *, size_t, size_t, bool *, bool *, unsigned); + +/* + * bool + * chunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind); + */ +typedef bool (chunk_dalloc_t)(void *, size_t, bool, unsigned); + +/* + * bool + * chunk_commit(void *chunk, size_t size, size_t offset, size_t length, + * unsigned arena_ind); + */ +typedef bool (chunk_commit_t)(void *, size_t, size_t, size_t, unsigned); + +/* + * bool + * chunk_decommit(void *chunk, size_t size, size_t offset, size_t length, + * unsigned arena_ind); + */ +typedef bool (chunk_decommit_t)(void *, size_t, size_t, size_t, unsigned); + +/* + * bool + * chunk_purge(void *chunk, size_t size, size_t offset, size_t length, + * unsigned arena_ind); + */ +typedef bool (chunk_purge_t)(void *, size_t, size_t, size_t, unsigned); + +/* + * bool + * chunk_split(void *chunk, size_t size, size_t size_a, size_t size_b, + * bool committed, unsigned arena_ind); + */ +typedef bool (chunk_split_t)(void *, size_t, size_t, size_t, bool, unsigned); + +/* + * bool + * chunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, + * bool committed, unsigned arena_ind); + */ +typedef bool (chunk_merge_t)(void *, size_t, void *, size_t, bool, unsigned); + +typedef struct { + chunk_alloc_t *alloc; + chunk_dalloc_t *dalloc; + chunk_commit_t *commit; + chunk_decommit_t *decommit; + chunk_purge_t *purge; + chunk_split_t *split; + chunk_merge_t *merge; +} chunk_hooks_t; + +/* + * By default application code must explicitly refer to mangled symbol names, + * so that it is possible to use jemalloc in conjunction with another allocator + * in the same application. Define JEMALLOC_MANGLE in order to cause automatic + * name mangling that matches the API prefixing that happened as a result of + * --with-mangling and/or --with-jemalloc-prefix configuration settings. + */ +#ifdef JEMALLOC_MANGLE +# ifndef JEMALLOC_NO_DEMANGLE +# define JEMALLOC_NO_DEMANGLE +# endif +# define malloc_conf je_malloc_conf +# define malloc_message je_malloc_message +# define malloc je_malloc +# define calloc je_calloc +# define posix_memalign je_posix_memalign +# define aligned_alloc je_aligned_alloc +# define realloc je_realloc +# define free je_free +# define mallocx je_mallocx +# define rallocx je_rallocx +# define xallocx je_xallocx +# define sallocx je_sallocx +# define dallocx je_dallocx +# define sdallocx je_sdallocx +# define nallocx je_nallocx +# define mallctl je_mallctl +# define mallctlnametomib je_mallctlnametomib +# define mallctlbymib je_mallctlbymib +# define malloc_stats_print je_malloc_stats_print +# define malloc_usable_size je_malloc_usable_size +# define valloc je_valloc +#endif + +/* + * The je_* macros can be used as stable alternative names for the + * public jemalloc API if JEMALLOC_NO_DEMANGLE is defined. This is primarily + * meant for use in jemalloc itself, but it can be used by application code to + * provide isolation from the name mangling specified via --with-mangling + * and/or --with-jemalloc-prefix. + */ +#ifndef JEMALLOC_NO_DEMANGLE +# undef je_malloc_conf +# undef je_malloc_message +# undef je_malloc +# undef je_calloc +# undef je_posix_memalign +# undef je_aligned_alloc +# undef je_realloc +# undef je_free +# undef je_mallocx +# undef je_rallocx +# undef je_xallocx +# undef je_sallocx +# undef je_dallocx +# undef je_sdallocx +# undef je_nallocx +# undef je_mallctl +# undef je_mallctlnametomib +# undef je_mallctlbymib +# undef je_malloc_stats_print +# undef je_malloc_usable_size +# undef je_valloc +#endif + +#ifdef __cplusplus +} +#endif +#endif /* JEMALLOC_H_ */ diff --git a/contrib/jemalloc/include/jemalloc/jemalloc_FreeBSD.h b/contrib/jemalloc/include/jemalloc/jemalloc_FreeBSD.h new file mode 100644 index 0000000..e2ddfd8 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/jemalloc_FreeBSD.h @@ -0,0 +1,165 @@ +/* + * Override settings that were generated in jemalloc_defs.h as necessary. + */ + +#undef JEMALLOC_OVERRIDE_VALLOC + +#ifndef MALLOC_PRODUCTION +#define MALLOC_PRODUCTION +#endif +#ifndef MALLOC_PRODUCTION +#define JEMALLOC_DEBUG +#endif + +#undef JEMALLOC_DSS + +/* + * The following are architecture-dependent, so conditionally define them for + * each supported architecture. + */ +#undef JEMALLOC_TLS_MODEL +#undef STATIC_PAGE_SHIFT +#undef LG_SIZEOF_PTR +#undef LG_SIZEOF_INT +#undef LG_SIZEOF_LONG +#undef LG_SIZEOF_INTMAX_T + +#ifdef __i386__ +# define LG_SIZEOF_PTR 2 +# define JEMALLOC_TLS_MODEL __attribute__((tls_model("initial-exec"))) +#endif +#ifdef __ia64__ +# define LG_SIZEOF_PTR 3 +#endif +#ifdef __sparc64__ +# define LG_SIZEOF_PTR 3 +# define JEMALLOC_TLS_MODEL __attribute__((tls_model("initial-exec"))) +#endif +#ifdef __amd64__ +# define LG_SIZEOF_PTR 3 +# define JEMALLOC_TLS_MODEL __attribute__((tls_model("initial-exec"))) +#endif +#ifdef __arm__ +# define LG_SIZEOF_PTR 2 +#endif +#ifdef __aarch64__ +# define LG_SIZEOF_PTR 3 +#endif +#ifdef __mips__ +#ifdef __mips_n64 +# define LG_SIZEOF_PTR 3 +#else +# define LG_SIZEOF_PTR 2 +#endif +#endif +#ifdef __powerpc64__ +# define LG_SIZEOF_PTR 3 +#elif defined(__powerpc__) +# define LG_SIZEOF_PTR 2 +#endif +#ifdef __riscv__ +# define LG_SIZEOF_PTR 3 +#endif + +#ifndef JEMALLOC_TLS_MODEL +# define JEMALLOC_TLS_MODEL /* Default. */ +#endif + +#define STATIC_PAGE_SHIFT PAGE_SHIFT +#define LG_SIZEOF_INT 2 +#define LG_SIZEOF_LONG LG_SIZEOF_PTR +#define LG_SIZEOF_INTMAX_T 3 + +#undef CPU_SPINWAIT +#include +#include +#define CPU_SPINWAIT cpu_spinwait() + +/* Disable lazy-lock machinery, mangle isthreaded, and adjust its type. */ +#undef JEMALLOC_LAZY_LOCK +extern int __isthreaded; +#define isthreaded ((bool)__isthreaded) + +/* Mangle. */ +#undef je_malloc +#undef je_calloc +#undef je_posix_memalign +#undef je_aligned_alloc +#undef je_realloc +#undef je_free +#undef je_malloc_usable_size +#undef je_mallocx +#undef je_rallocx +#undef je_xallocx +#undef je_sallocx +#undef je_dallocx +#undef je_sdallocx +#undef je_nallocx +#undef je_mallctl +#undef je_mallctlnametomib +#undef je_mallctlbymib +#undef je_malloc_stats_print +#undef je_allocm +#undef je_rallocm +#undef je_sallocm +#undef je_dallocm +#undef je_nallocm +#define je_malloc __malloc +#define je_calloc __calloc +#define je_posix_memalign __posix_memalign +#define je_aligned_alloc __aligned_alloc +#define je_realloc __realloc +#define je_free __free +#define je_malloc_usable_size __malloc_usable_size +#define je_mallocx __mallocx +#define je_rallocx __rallocx +#define je_xallocx __xallocx +#define je_sallocx __sallocx +#define je_dallocx __dallocx +#define je_sdallocx __sdallocx +#define je_nallocx __nallocx +#define je_mallctl __mallctl +#define je_mallctlnametomib __mallctlnametomib +#define je_mallctlbymib __mallctlbymib +#define je_malloc_stats_print __malloc_stats_print +#define je_allocm __allocm +#define je_rallocm __rallocm +#define je_sallocm __sallocm +#define je_dallocm __dallocm +#define je_nallocm __nallocm +#define open _open +#define read _read +#define write _write +#define close _close +#define pthread_mutex_lock _pthread_mutex_lock +#define pthread_mutex_unlock _pthread_mutex_unlock + +#ifdef JEMALLOC_C_ +/* + * Define 'weak' symbols so that an application can have its own versions + * of malloc, calloc, realloc, free, et al. + */ +__weak_reference(__malloc, malloc); +__weak_reference(__calloc, calloc); +__weak_reference(__posix_memalign, posix_memalign); +__weak_reference(__aligned_alloc, aligned_alloc); +__weak_reference(__realloc, realloc); +__weak_reference(__free, free); +__weak_reference(__malloc_usable_size, malloc_usable_size); +__weak_reference(__mallocx, mallocx); +__weak_reference(__rallocx, rallocx); +__weak_reference(__xallocx, xallocx); +__weak_reference(__sallocx, sallocx); +__weak_reference(__dallocx, dallocx); +__weak_reference(__sdallocx, sdallocx); +__weak_reference(__nallocx, nallocx); +__weak_reference(__mallctl, mallctl); +__weak_reference(__mallctlnametomib, mallctlnametomib); +__weak_reference(__mallctlbymib, mallctlbymib); +__weak_reference(__malloc_stats_print, malloc_stats_print); +__weak_reference(__allocm, allocm); +__weak_reference(__rallocm, rallocm); +__weak_reference(__sallocm, sallocm); +__weak_reference(__dallocm, dallocm); +__weak_reference(__nallocm, nallocm); +#endif diff --git a/contrib/jemalloc/include/jemalloc/jemalloc_typedefs.h b/contrib/jemalloc/include/jemalloc/jemalloc_typedefs.h new file mode 100644 index 0000000..fa7b350 --- /dev/null +++ b/contrib/jemalloc/include/jemalloc/jemalloc_typedefs.h @@ -0,0 +1,57 @@ +/* + * void * + * chunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero, + * bool *commit, unsigned arena_ind); + */ +typedef void *(chunk_alloc_t)(void *, size_t, size_t, bool *, bool *, unsigned); + +/* + * bool + * chunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind); + */ +typedef bool (chunk_dalloc_t)(void *, size_t, bool, unsigned); + +/* + * bool + * chunk_commit(void *chunk, size_t size, size_t offset, size_t length, + * unsigned arena_ind); + */ +typedef bool (chunk_commit_t)(void *, size_t, size_t, size_t, unsigned); + +/* + * bool + * chunk_decommit(void *chunk, size_t size, size_t offset, size_t length, + * unsigned arena_ind); + */ +typedef bool (chunk_decommit_t)(void *, size_t, size_t, size_t, unsigned); + +/* + * bool + * chunk_purge(void *chunk, size_t size, size_t offset, size_t length, + * unsigned arena_ind); + */ +typedef bool (chunk_purge_t)(void *, size_t, size_t, size_t, unsigned); + +/* + * bool + * chunk_split(void *chunk, size_t size, size_t size_a, size_t size_b, + * bool committed, unsigned arena_ind); + */ +typedef bool (chunk_split_t)(void *, size_t, size_t, size_t, bool, unsigned); + +/* + * bool + * chunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, + * bool committed, unsigned arena_ind); + */ +typedef bool (chunk_merge_t)(void *, size_t, void *, size_t, bool, unsigned); + +typedef struct { + chunk_alloc_t *alloc; + chunk_dalloc_t *dalloc; + chunk_commit_t *commit; + chunk_decommit_t *decommit; + chunk_purge_t *purge; + chunk_split_t *split; + chunk_merge_t *merge; +} chunk_hooks_t; diff --git a/contrib/jemalloc/src/arena.c b/contrib/jemalloc/src/arena.c new file mode 100644 index 0000000..ce62590 --- /dev/null +++ b/contrib/jemalloc/src/arena.c @@ -0,0 +1,3891 @@ +#define JEMALLOC_ARENA_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +purge_mode_t opt_purge = PURGE_DEFAULT; +const char *purge_mode_names[] = { + "ratio", + "decay", + "N/A" +}; +ssize_t opt_lg_dirty_mult = LG_DIRTY_MULT_DEFAULT; +static ssize_t lg_dirty_mult_default; +ssize_t opt_decay_time = DECAY_TIME_DEFAULT; +static ssize_t decay_time_default; + +arena_bin_info_t arena_bin_info[NBINS]; + +size_t map_bias; +size_t map_misc_offset; +size_t arena_maxrun; /* Max run size for arenas. */ +size_t large_maxclass; /* Max large size class. */ +size_t run_quantize_max; /* Max run_quantize_*() input. */ +static size_t small_maxrun; /* Max run size for small size classes. */ +static bool *small_run_tab; /* Valid small run page multiples. */ +static size_t *run_quantize_floor_tab; /* run_quantize_floor() memoization. */ +static size_t *run_quantize_ceil_tab; /* run_quantize_ceil() memoization. */ +unsigned nlclasses; /* Number of large size classes. */ +unsigned nhclasses; /* Number of huge size classes. */ +static szind_t runs_avail_bias; /* Size index for first runs_avail tree. */ +static szind_t runs_avail_nclasses; /* Number of runs_avail trees. */ + +/******************************************************************************/ +/* + * Function prototypes for static functions that are referenced prior to + * definition. + */ + +static void arena_purge_to_limit(tsdn_t *tsdn, arena_t *arena, + size_t ndirty_limit); +static void arena_run_dalloc(tsdn_t *tsdn, arena_t *arena, arena_run_t *run, + bool dirty, bool cleaned, bool decommitted); +static void arena_dalloc_bin_run(tsdn_t *tsdn, arena_t *arena, + arena_chunk_t *chunk, arena_run_t *run, arena_bin_t *bin); +static void arena_bin_lower_run(arena_t *arena, arena_chunk_t *chunk, + arena_run_t *run, arena_bin_t *bin); + +/******************************************************************************/ + +JEMALLOC_INLINE_C size_t +arena_miscelm_size_get(const arena_chunk_map_misc_t *miscelm) +{ + arena_chunk_t *chunk; + size_t pageind, mapbits; + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(miscelm); + pageind = arena_miscelm_to_pageind(miscelm); + mapbits = arena_mapbits_get(chunk, pageind); + return (arena_mapbits_size_decode(mapbits)); +} + +JEMALLOC_INLINE_C int +arena_run_addr_comp(const arena_chunk_map_misc_t *a, + const arena_chunk_map_misc_t *b) +{ + uintptr_t a_miscelm = (uintptr_t)a; + uintptr_t b_miscelm = (uintptr_t)b; + + assert(a != NULL); + assert(b != NULL); + + return ((a_miscelm > b_miscelm) - (a_miscelm < b_miscelm)); +} + +/* Generate pairing heap functions. */ +ph_gen(static UNUSED, arena_run_heap_, arena_run_heap_t, arena_chunk_map_misc_t, + ph_link, arena_run_addr_comp) + +static size_t +run_quantize_floor_compute(size_t size) +{ + size_t qsize; + + assert(size != 0); + assert(size == PAGE_CEILING(size)); + + /* Don't change sizes that are valid small run sizes. */ + if (size <= small_maxrun && small_run_tab[size >> LG_PAGE]) + return (size); + + /* + * Round down to the nearest run size that can actually be requested + * during normal large allocation. Add large_pad so that cache index + * randomization can offset the allocation from the page boundary. + */ + qsize = index2size(size2index(size - large_pad + 1) - 1) + large_pad; + if (qsize <= SMALL_MAXCLASS + large_pad) + return (run_quantize_floor_compute(size - large_pad)); + assert(qsize <= size); + return (qsize); +} + +static size_t +run_quantize_ceil_compute_hard(size_t size) +{ + size_t large_run_size_next; + + assert(size != 0); + assert(size == PAGE_CEILING(size)); + + /* + * Return the next quantized size greater than the input size. + * Quantized sizes comprise the union of run sizes that back small + * region runs, and run sizes that back large regions with no explicit + * alignment constraints. + */ + + if (size > SMALL_MAXCLASS) { + large_run_size_next = PAGE_CEILING(index2size(size2index(size - + large_pad) + 1) + large_pad); + } else + large_run_size_next = SIZE_T_MAX; + if (size >= small_maxrun) + return (large_run_size_next); + + while (true) { + size += PAGE; + assert(size <= small_maxrun); + if (small_run_tab[size >> LG_PAGE]) { + if (large_run_size_next < size) + return (large_run_size_next); + return (size); + } + } +} + +static size_t +run_quantize_ceil_compute(size_t size) +{ + size_t qsize = run_quantize_floor_compute(size); + + if (qsize < size) { + /* + * Skip a quantization that may have an adequately large run, + * because under-sized runs may be mixed in. This only happens + * when an unusual size is requested, i.e. for aligned + * allocation, and is just one of several places where linear + * search would potentially find sufficiently aligned available + * memory somewhere lower. + */ + qsize = run_quantize_ceil_compute_hard(qsize); + } + return (qsize); +} + +#ifdef JEMALLOC_JET +#undef run_quantize_floor +#define run_quantize_floor JEMALLOC_N(n_run_quantize_floor) +#endif +static size_t +run_quantize_floor(size_t size) +{ + size_t ret; + + assert(size > 0); + assert(size <= run_quantize_max); + assert((size & PAGE_MASK) == 0); + + ret = run_quantize_floor_tab[(size >> LG_PAGE) - 1]; + assert(ret == run_quantize_floor_compute(size)); + return (ret); +} +#ifdef JEMALLOC_JET +#undef run_quantize_floor +#define run_quantize_floor JEMALLOC_N(run_quantize_floor) +run_quantize_t *run_quantize_floor = JEMALLOC_N(n_run_quantize_floor); +#endif + +#ifdef JEMALLOC_JET +#undef run_quantize_ceil +#define run_quantize_ceil JEMALLOC_N(n_run_quantize_ceil) +#endif +static size_t +run_quantize_ceil(size_t size) +{ + size_t ret; + + assert(size > 0); + assert(size <= run_quantize_max); + assert((size & PAGE_MASK) == 0); + + ret = run_quantize_ceil_tab[(size >> LG_PAGE) - 1]; + assert(ret == run_quantize_ceil_compute(size)); + return (ret); +} +#ifdef JEMALLOC_JET +#undef run_quantize_ceil +#define run_quantize_ceil JEMALLOC_N(run_quantize_ceil) +run_quantize_t *run_quantize_ceil = JEMALLOC_N(n_run_quantize_ceil); +#endif + +static arena_run_heap_t * +arena_runs_avail_get(arena_t *arena, szind_t ind) +{ + + assert(ind >= runs_avail_bias); + assert(ind - runs_avail_bias < runs_avail_nclasses); + + return (&arena->runs_avail[ind - runs_avail_bias]); +} + +static void +arena_avail_insert(arena_t *arena, arena_chunk_t *chunk, size_t pageind, + size_t npages) +{ + szind_t ind = size2index(run_quantize_floor(arena_miscelm_size_get( + arena_miscelm_get_const(chunk, pageind)))); + assert(npages == (arena_mapbits_unallocated_size_get(chunk, pageind) >> + LG_PAGE)); + arena_run_heap_insert(arena_runs_avail_get(arena, ind), + arena_miscelm_get_mutable(chunk, pageind)); +} + +static void +arena_avail_remove(arena_t *arena, arena_chunk_t *chunk, size_t pageind, + size_t npages) +{ + szind_t ind = size2index(run_quantize_floor(arena_miscelm_size_get( + arena_miscelm_get_const(chunk, pageind)))); + assert(npages == (arena_mapbits_unallocated_size_get(chunk, pageind) >> + LG_PAGE)); + arena_run_heap_remove(arena_runs_avail_get(arena, ind), + arena_miscelm_get_mutable(chunk, pageind)); +} + +static void +arena_run_dirty_insert(arena_t *arena, arena_chunk_t *chunk, size_t pageind, + size_t npages) +{ + arena_chunk_map_misc_t *miscelm = arena_miscelm_get_mutable(chunk, + pageind); + + assert(npages == (arena_mapbits_unallocated_size_get(chunk, pageind) >> + LG_PAGE)); + assert(arena_mapbits_dirty_get(chunk, pageind) == CHUNK_MAP_DIRTY); + assert(arena_mapbits_dirty_get(chunk, pageind+npages-1) == + CHUNK_MAP_DIRTY); + + qr_new(&miscelm->rd, rd_link); + qr_meld(&arena->runs_dirty, &miscelm->rd, rd_link); + arena->ndirty += npages; +} + +static void +arena_run_dirty_remove(arena_t *arena, arena_chunk_t *chunk, size_t pageind, + size_t npages) +{ + arena_chunk_map_misc_t *miscelm = arena_miscelm_get_mutable(chunk, + pageind); + + assert(npages == (arena_mapbits_unallocated_size_get(chunk, pageind) >> + LG_PAGE)); + assert(arena_mapbits_dirty_get(chunk, pageind) == CHUNK_MAP_DIRTY); + assert(arena_mapbits_dirty_get(chunk, pageind+npages-1) == + CHUNK_MAP_DIRTY); + + qr_remove(&miscelm->rd, rd_link); + assert(arena->ndirty >= npages); + arena->ndirty -= npages; +} + +static size_t +arena_chunk_dirty_npages(const extent_node_t *node) +{ + + return (extent_node_size_get(node) >> LG_PAGE); +} + +void +arena_chunk_cache_maybe_insert(arena_t *arena, extent_node_t *node, bool cache) +{ + + if (cache) { + extent_node_dirty_linkage_init(node); + extent_node_dirty_insert(node, &arena->runs_dirty, + &arena->chunks_cache); + arena->ndirty += arena_chunk_dirty_npages(node); + } +} + +void +arena_chunk_cache_maybe_remove(arena_t *arena, extent_node_t *node, bool dirty) +{ + + if (dirty) { + extent_node_dirty_remove(node); + assert(arena->ndirty >= arena_chunk_dirty_npages(node)); + arena->ndirty -= arena_chunk_dirty_npages(node); + } +} + +JEMALLOC_INLINE_C void * +arena_run_reg_alloc(arena_run_t *run, arena_bin_info_t *bin_info) +{ + void *ret; + size_t regind; + arena_chunk_map_misc_t *miscelm; + void *rpages; + + assert(run->nfree > 0); + assert(!bitmap_full(run->bitmap, &bin_info->bitmap_info)); + + regind = (unsigned)bitmap_sfu(run->bitmap, &bin_info->bitmap_info); + miscelm = arena_run_to_miscelm(run); + rpages = arena_miscelm_to_rpages(miscelm); + ret = (void *)((uintptr_t)rpages + (uintptr_t)bin_info->reg0_offset + + (uintptr_t)(bin_info->reg_interval * regind)); + run->nfree--; + return (ret); +} + +JEMALLOC_INLINE_C void +arena_run_reg_dalloc(arena_run_t *run, void *ptr) +{ + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + size_t mapbits = arena_mapbits_get(chunk, pageind); + szind_t binind = arena_ptr_small_binind_get(ptr, mapbits); + arena_bin_info_t *bin_info = &arena_bin_info[binind]; + size_t regind = arena_run_regind(run, bin_info, ptr); + + assert(run->nfree < bin_info->nregs); + /* Freeing an interior pointer can cause assertion failure. */ + assert(((uintptr_t)ptr - + ((uintptr_t)arena_miscelm_to_rpages(arena_run_to_miscelm(run)) + + (uintptr_t)bin_info->reg0_offset)) % + (uintptr_t)bin_info->reg_interval == 0); + assert((uintptr_t)ptr >= + (uintptr_t)arena_miscelm_to_rpages(arena_run_to_miscelm(run)) + + (uintptr_t)bin_info->reg0_offset); + /* Freeing an unallocated pointer can cause assertion failure. */ + assert(bitmap_get(run->bitmap, &bin_info->bitmap_info, regind)); + + bitmap_unset(run->bitmap, &bin_info->bitmap_info, regind); + run->nfree++; +} + +JEMALLOC_INLINE_C void +arena_run_zero(arena_chunk_t *chunk, size_t run_ind, size_t npages) +{ + + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED((void *)((uintptr_t)chunk + + (run_ind << LG_PAGE)), (npages << LG_PAGE)); + memset((void *)((uintptr_t)chunk + (run_ind << LG_PAGE)), 0, + (npages << LG_PAGE)); +} + +JEMALLOC_INLINE_C void +arena_run_page_mark_zeroed(arena_chunk_t *chunk, size_t run_ind) +{ + + JEMALLOC_VALGRIND_MAKE_MEM_DEFINED((void *)((uintptr_t)chunk + (run_ind + << LG_PAGE)), PAGE); +} + +JEMALLOC_INLINE_C void +arena_run_page_validate_zeroed(arena_chunk_t *chunk, size_t run_ind) +{ + size_t i; + UNUSED size_t *p = (size_t *)((uintptr_t)chunk + (run_ind << LG_PAGE)); + + arena_run_page_mark_zeroed(chunk, run_ind); + for (i = 0; i < PAGE / sizeof(size_t); i++) + assert(p[i] == 0); +} + +static void +arena_nactive_add(arena_t *arena, size_t add_pages) +{ + + if (config_stats) { + size_t cactive_add = CHUNK_CEILING((arena->nactive + + add_pages) << LG_PAGE) - CHUNK_CEILING(arena->nactive << + LG_PAGE); + if (cactive_add != 0) + stats_cactive_add(cactive_add); + } + arena->nactive += add_pages; +} + +static void +arena_nactive_sub(arena_t *arena, size_t sub_pages) +{ + + if (config_stats) { + size_t cactive_sub = CHUNK_CEILING(arena->nactive << LG_PAGE) - + CHUNK_CEILING((arena->nactive - sub_pages) << LG_PAGE); + if (cactive_sub != 0) + stats_cactive_sub(cactive_sub); + } + arena->nactive -= sub_pages; +} + +static void +arena_run_split_remove(arena_t *arena, arena_chunk_t *chunk, size_t run_ind, + size_t flag_dirty, size_t flag_decommitted, size_t need_pages) +{ + size_t total_pages, rem_pages; + + assert(flag_dirty == 0 || flag_decommitted == 0); + + total_pages = arena_mapbits_unallocated_size_get(chunk, run_ind) >> + LG_PAGE; + assert(arena_mapbits_dirty_get(chunk, run_ind+total_pages-1) == + flag_dirty); + assert(need_pages <= total_pages); + rem_pages = total_pages - need_pages; + + arena_avail_remove(arena, chunk, run_ind, total_pages); + if (flag_dirty != 0) + arena_run_dirty_remove(arena, chunk, run_ind, total_pages); + arena_nactive_add(arena, need_pages); + + /* Keep track of trailing unused pages for later use. */ + if (rem_pages > 0) { + size_t flags = flag_dirty | flag_decommitted; + size_t flag_unzeroed_mask = (flags == 0) ? CHUNK_MAP_UNZEROED : + 0; + + arena_mapbits_unallocated_set(chunk, run_ind+need_pages, + (rem_pages << LG_PAGE), flags | + (arena_mapbits_unzeroed_get(chunk, run_ind+need_pages) & + flag_unzeroed_mask)); + arena_mapbits_unallocated_set(chunk, run_ind+total_pages-1, + (rem_pages << LG_PAGE), flags | + (arena_mapbits_unzeroed_get(chunk, run_ind+total_pages-1) & + flag_unzeroed_mask)); + if (flag_dirty != 0) { + arena_run_dirty_insert(arena, chunk, run_ind+need_pages, + rem_pages); + } + arena_avail_insert(arena, chunk, run_ind+need_pages, rem_pages); + } +} + +static bool +arena_run_split_large_helper(arena_t *arena, arena_run_t *run, size_t size, + bool remove, bool zero) +{ + arena_chunk_t *chunk; + arena_chunk_map_misc_t *miscelm; + size_t flag_dirty, flag_decommitted, run_ind, need_pages; + size_t flag_unzeroed_mask; + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); + miscelm = arena_run_to_miscelm(run); + run_ind = arena_miscelm_to_pageind(miscelm); + flag_dirty = arena_mapbits_dirty_get(chunk, run_ind); + flag_decommitted = arena_mapbits_decommitted_get(chunk, run_ind); + need_pages = (size >> LG_PAGE); + assert(need_pages > 0); + + if (flag_decommitted != 0 && arena->chunk_hooks.commit(chunk, chunksize, + run_ind << LG_PAGE, size, arena->ind)) + return (true); + + if (remove) { + arena_run_split_remove(arena, chunk, run_ind, flag_dirty, + flag_decommitted, need_pages); + } + + if (zero) { + if (flag_decommitted != 0) { + /* The run is untouched, and therefore zeroed. */ + JEMALLOC_VALGRIND_MAKE_MEM_DEFINED((void + *)((uintptr_t)chunk + (run_ind << LG_PAGE)), + (need_pages << LG_PAGE)); + } else if (flag_dirty != 0) { + /* The run is dirty, so all pages must be zeroed. */ + arena_run_zero(chunk, run_ind, need_pages); + } else { + /* + * The run is clean, so some pages may be zeroed (i.e. + * never before touched). + */ + size_t i; + for (i = 0; i < need_pages; i++) { + if (arena_mapbits_unzeroed_get(chunk, run_ind+i) + != 0) + arena_run_zero(chunk, run_ind+i, 1); + else if (config_debug) { + arena_run_page_validate_zeroed(chunk, + run_ind+i); + } else { + arena_run_page_mark_zeroed(chunk, + run_ind+i); + } + } + } + } else { + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED((void *)((uintptr_t)chunk + + (run_ind << LG_PAGE)), (need_pages << LG_PAGE)); + } + + /* + * Set the last element first, in case the run only contains one page + * (i.e. both statements set the same element). + */ + flag_unzeroed_mask = (flag_dirty | flag_decommitted) == 0 ? + CHUNK_MAP_UNZEROED : 0; + arena_mapbits_large_set(chunk, run_ind+need_pages-1, 0, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, + run_ind+need_pages-1))); + arena_mapbits_large_set(chunk, run_ind, size, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, run_ind))); + return (false); +} + +static bool +arena_run_split_large(arena_t *arena, arena_run_t *run, size_t size, bool zero) +{ + + return (arena_run_split_large_helper(arena, run, size, true, zero)); +} + +static bool +arena_run_init_large(arena_t *arena, arena_run_t *run, size_t size, bool zero) +{ + + return (arena_run_split_large_helper(arena, run, size, false, zero)); +} + +static bool +arena_run_split_small(arena_t *arena, arena_run_t *run, size_t size, + szind_t binind) +{ + arena_chunk_t *chunk; + arena_chunk_map_misc_t *miscelm; + size_t flag_dirty, flag_decommitted, run_ind, need_pages, i; + + assert(binind != BININD_INVALID); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); + miscelm = arena_run_to_miscelm(run); + run_ind = arena_miscelm_to_pageind(miscelm); + flag_dirty = arena_mapbits_dirty_get(chunk, run_ind); + flag_decommitted = arena_mapbits_decommitted_get(chunk, run_ind); + need_pages = (size >> LG_PAGE); + assert(need_pages > 0); + + if (flag_decommitted != 0 && arena->chunk_hooks.commit(chunk, chunksize, + run_ind << LG_PAGE, size, arena->ind)) + return (true); + + arena_run_split_remove(arena, chunk, run_ind, flag_dirty, + flag_decommitted, need_pages); + + for (i = 0; i < need_pages; i++) { + size_t flag_unzeroed = arena_mapbits_unzeroed_get(chunk, + run_ind+i); + arena_mapbits_small_set(chunk, run_ind+i, i, binind, + flag_unzeroed); + if (config_debug && flag_dirty == 0 && flag_unzeroed == 0) + arena_run_page_validate_zeroed(chunk, run_ind+i); + } + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED((void *)((uintptr_t)chunk + + (run_ind << LG_PAGE)), (need_pages << LG_PAGE)); + return (false); +} + +static arena_chunk_t * +arena_chunk_init_spare(arena_t *arena) +{ + arena_chunk_t *chunk; + + assert(arena->spare != NULL); + + chunk = arena->spare; + arena->spare = NULL; + + assert(arena_mapbits_allocated_get(chunk, map_bias) == 0); + assert(arena_mapbits_allocated_get(chunk, chunk_npages-1) == 0); + assert(arena_mapbits_unallocated_size_get(chunk, map_bias) == + arena_maxrun); + assert(arena_mapbits_unallocated_size_get(chunk, chunk_npages-1) == + arena_maxrun); + assert(arena_mapbits_dirty_get(chunk, map_bias) == + arena_mapbits_dirty_get(chunk, chunk_npages-1)); + + return (chunk); +} + +static bool +arena_chunk_register(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, + bool zero) +{ + + /* + * The extent node notion of "committed" doesn't directly apply to + * arena chunks. Arbitrarily mark them as committed. The commit state + * of runs is tracked individually, and upon chunk deallocation the + * entire chunk is in a consistent commit state. + */ + extent_node_init(&chunk->node, arena, chunk, chunksize, zero, true); + extent_node_achunk_set(&chunk->node, true); + return (chunk_register(tsdn, chunk, &chunk->node)); +} + +static arena_chunk_t * +arena_chunk_alloc_internal_hard(tsdn_t *tsdn, arena_t *arena, + chunk_hooks_t *chunk_hooks, bool *zero, bool *commit) +{ + arena_chunk_t *chunk; + + malloc_mutex_unlock(tsdn, &arena->lock); + + chunk = (arena_chunk_t *)chunk_alloc_wrapper(tsdn, arena, chunk_hooks, + NULL, chunksize, chunksize, zero, commit); + if (chunk != NULL && !*commit) { + /* Commit header. */ + if (chunk_hooks->commit(chunk, chunksize, 0, map_bias << + LG_PAGE, arena->ind)) { + chunk_dalloc_wrapper(tsdn, arena, chunk_hooks, + (void *)chunk, chunksize, *zero, *commit); + chunk = NULL; + } + } + if (chunk != NULL && arena_chunk_register(tsdn, arena, chunk, *zero)) { + if (!*commit) { + /* Undo commit of header. */ + chunk_hooks->decommit(chunk, chunksize, 0, map_bias << + LG_PAGE, arena->ind); + } + chunk_dalloc_wrapper(tsdn, arena, chunk_hooks, (void *)chunk, + chunksize, *zero, *commit); + chunk = NULL; + } + + malloc_mutex_lock(tsdn, &arena->lock); + return (chunk); +} + +static arena_chunk_t * +arena_chunk_alloc_internal(tsdn_t *tsdn, arena_t *arena, bool *zero, + bool *commit) +{ + arena_chunk_t *chunk; + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + + chunk = chunk_alloc_cache(tsdn, arena, &chunk_hooks, NULL, chunksize, + chunksize, zero, true); + if (chunk != NULL) { + if (arena_chunk_register(tsdn, arena, chunk, *zero)) { + chunk_dalloc_cache(tsdn, arena, &chunk_hooks, chunk, + chunksize, true); + return (NULL); + } + *commit = true; + } + if (chunk == NULL) { + chunk = arena_chunk_alloc_internal_hard(tsdn, arena, + &chunk_hooks, zero, commit); + } + + if (config_stats && chunk != NULL) { + arena->stats.mapped += chunksize; + arena->stats.metadata_mapped += (map_bias << LG_PAGE); + } + + return (chunk); +} + +static arena_chunk_t * +arena_chunk_init_hard(tsdn_t *tsdn, arena_t *arena) +{ + arena_chunk_t *chunk; + bool zero, commit; + size_t flag_unzeroed, flag_decommitted, i; + + assert(arena->spare == NULL); + + zero = false; + commit = false; + chunk = arena_chunk_alloc_internal(tsdn, arena, &zero, &commit); + if (chunk == NULL) + return (NULL); + + /* + * Initialize the map to contain one maximal free untouched run. Mark + * the pages as zeroed if arena_chunk_alloc_internal() returned a zeroed + * or decommitted chunk. + */ + flag_unzeroed = (zero || !commit) ? 0 : CHUNK_MAP_UNZEROED; + flag_decommitted = commit ? 0 : CHUNK_MAP_DECOMMITTED; + arena_mapbits_unallocated_set(chunk, map_bias, arena_maxrun, + flag_unzeroed | flag_decommitted); + /* + * There is no need to initialize the internal page map entries unless + * the chunk is not zeroed. + */ + if (!zero) { + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED( + (void *)arena_bitselm_get_const(chunk, map_bias+1), + (size_t)((uintptr_t)arena_bitselm_get_const(chunk, + chunk_npages-1) - + (uintptr_t)arena_bitselm_get_const(chunk, map_bias+1))); + for (i = map_bias+1; i < chunk_npages-1; i++) + arena_mapbits_internal_set(chunk, i, flag_unzeroed); + } else { + JEMALLOC_VALGRIND_MAKE_MEM_DEFINED((void + *)arena_bitselm_get_const(chunk, map_bias+1), + (size_t)((uintptr_t)arena_bitselm_get_const(chunk, + chunk_npages-1) - + (uintptr_t)arena_bitselm_get_const(chunk, map_bias+1))); + if (config_debug) { + for (i = map_bias+1; i < chunk_npages-1; i++) { + assert(arena_mapbits_unzeroed_get(chunk, i) == + flag_unzeroed); + } + } + } + arena_mapbits_unallocated_set(chunk, chunk_npages-1, arena_maxrun, + flag_unzeroed); + + return (chunk); +} + +static arena_chunk_t * +arena_chunk_alloc(tsdn_t *tsdn, arena_t *arena) +{ + arena_chunk_t *chunk; + + if (arena->spare != NULL) + chunk = arena_chunk_init_spare(arena); + else { + chunk = arena_chunk_init_hard(tsdn, arena); + if (chunk == NULL) + return (NULL); + } + + ql_elm_new(&chunk->node, ql_link); + ql_tail_insert(&arena->achunks, &chunk->node, ql_link); + arena_avail_insert(arena, chunk, map_bias, chunk_npages-map_bias); + + return (chunk); +} + +static void +arena_chunk_discard(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk) +{ + bool committed; + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + + chunk_deregister(chunk, &chunk->node); + + committed = (arena_mapbits_decommitted_get(chunk, map_bias) == 0); + if (!committed) { + /* + * Decommit the header. Mark the chunk as decommitted even if + * header decommit fails, since treating a partially committed + * chunk as committed has a high potential for causing later + * access of decommitted memory. + */ + chunk_hooks = chunk_hooks_get(tsdn, arena); + chunk_hooks.decommit(chunk, chunksize, 0, map_bias << LG_PAGE, + arena->ind); + } + + chunk_dalloc_cache(tsdn, arena, &chunk_hooks, (void *)chunk, chunksize, + committed); + + if (config_stats) { + arena->stats.mapped -= chunksize; + arena->stats.metadata_mapped -= (map_bias << LG_PAGE); + } +} + +static void +arena_spare_discard(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *spare) +{ + + assert(arena->spare != spare); + + if (arena_mapbits_dirty_get(spare, map_bias) != 0) { + arena_run_dirty_remove(arena, spare, map_bias, + chunk_npages-map_bias); + } + + arena_chunk_discard(tsdn, arena, spare); +} + +static void +arena_chunk_dalloc(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk) +{ + arena_chunk_t *spare; + + assert(arena_mapbits_allocated_get(chunk, map_bias) == 0); + assert(arena_mapbits_allocated_get(chunk, chunk_npages-1) == 0); + assert(arena_mapbits_unallocated_size_get(chunk, map_bias) == + arena_maxrun); + assert(arena_mapbits_unallocated_size_get(chunk, chunk_npages-1) == + arena_maxrun); + assert(arena_mapbits_dirty_get(chunk, map_bias) == + arena_mapbits_dirty_get(chunk, chunk_npages-1)); + assert(arena_mapbits_decommitted_get(chunk, map_bias) == + arena_mapbits_decommitted_get(chunk, chunk_npages-1)); + + /* Remove run from runs_avail, so that the arena does not use it. */ + arena_avail_remove(arena, chunk, map_bias, chunk_npages-map_bias); + + ql_remove(&arena->achunks, &chunk->node, ql_link); + spare = arena->spare; + arena->spare = chunk; + if (spare != NULL) + arena_spare_discard(tsdn, arena, spare); +} + +static void +arena_huge_malloc_stats_update(arena_t *arena, size_t usize) +{ + szind_t index = size2index(usize) - nlclasses - NBINS; + + cassert(config_stats); + + arena->stats.nmalloc_huge++; + arena->stats.allocated_huge += usize; + arena->stats.hstats[index].nmalloc++; + arena->stats.hstats[index].curhchunks++; +} + +static void +arena_huge_malloc_stats_update_undo(arena_t *arena, size_t usize) +{ + szind_t index = size2index(usize) - nlclasses - NBINS; + + cassert(config_stats); + + arena->stats.nmalloc_huge--; + arena->stats.allocated_huge -= usize; + arena->stats.hstats[index].nmalloc--; + arena->stats.hstats[index].curhchunks--; +} + +static void +arena_huge_dalloc_stats_update(arena_t *arena, size_t usize) +{ + szind_t index = size2index(usize) - nlclasses - NBINS; + + cassert(config_stats); + + arena->stats.ndalloc_huge++; + arena->stats.allocated_huge -= usize; + arena->stats.hstats[index].ndalloc++; + arena->stats.hstats[index].curhchunks--; +} + +static void +arena_huge_reset_stats_cancel(arena_t *arena, size_t usize) +{ + szind_t index = size2index(usize) - nlclasses - NBINS; + + cassert(config_stats); + + arena->stats.ndalloc_huge++; + arena->stats.hstats[index].ndalloc--; +} + +static void +arena_huge_dalloc_stats_update_undo(arena_t *arena, size_t usize) +{ + szind_t index = size2index(usize) - nlclasses - NBINS; + + cassert(config_stats); + + arena->stats.ndalloc_huge--; + arena->stats.allocated_huge += usize; + arena->stats.hstats[index].ndalloc--; + arena->stats.hstats[index].curhchunks++; +} + +static void +arena_huge_ralloc_stats_update(arena_t *arena, size_t oldsize, size_t usize) +{ + + arena_huge_dalloc_stats_update(arena, oldsize); + arena_huge_malloc_stats_update(arena, usize); +} + +static void +arena_huge_ralloc_stats_update_undo(arena_t *arena, size_t oldsize, + size_t usize) +{ + + arena_huge_dalloc_stats_update_undo(arena, oldsize); + arena_huge_malloc_stats_update_undo(arena, usize); +} + +extent_node_t * +arena_node_alloc(tsdn_t *tsdn, arena_t *arena) +{ + extent_node_t *node; + + malloc_mutex_lock(tsdn, &arena->node_cache_mtx); + node = ql_last(&arena->node_cache, ql_link); + if (node == NULL) { + malloc_mutex_unlock(tsdn, &arena->node_cache_mtx); + return (base_alloc(tsdn, sizeof(extent_node_t))); + } + ql_tail_remove(&arena->node_cache, extent_node_t, ql_link); + malloc_mutex_unlock(tsdn, &arena->node_cache_mtx); + return (node); +} + +void +arena_node_dalloc(tsdn_t *tsdn, arena_t *arena, extent_node_t *node) +{ + + malloc_mutex_lock(tsdn, &arena->node_cache_mtx); + ql_elm_new(node, ql_link); + ql_tail_insert(&arena->node_cache, node, ql_link); + malloc_mutex_unlock(tsdn, &arena->node_cache_mtx); +} + +static void * +arena_chunk_alloc_huge_hard(tsdn_t *tsdn, arena_t *arena, + chunk_hooks_t *chunk_hooks, size_t usize, size_t alignment, bool *zero, + size_t csize) +{ + void *ret; + bool commit = true; + + ret = chunk_alloc_wrapper(tsdn, arena, chunk_hooks, NULL, csize, + alignment, zero, &commit); + if (ret == NULL) { + /* Revert optimistic stats updates. */ + malloc_mutex_lock(tsdn, &arena->lock); + if (config_stats) { + arena_huge_malloc_stats_update_undo(arena, usize); + arena->stats.mapped -= usize; + } + arena_nactive_sub(arena, usize >> LG_PAGE); + malloc_mutex_unlock(tsdn, &arena->lock); + } + + return (ret); +} + +void * +arena_chunk_alloc_huge(tsdn_t *tsdn, arena_t *arena, size_t usize, + size_t alignment, bool *zero) +{ + void *ret; + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + size_t csize = CHUNK_CEILING(usize); + + malloc_mutex_lock(tsdn, &arena->lock); + + /* Optimistically update stats. */ + if (config_stats) { + arena_huge_malloc_stats_update(arena, usize); + arena->stats.mapped += usize; + } + arena_nactive_add(arena, usize >> LG_PAGE); + + ret = chunk_alloc_cache(tsdn, arena, &chunk_hooks, NULL, csize, + alignment, zero, true); + malloc_mutex_unlock(tsdn, &arena->lock); + if (ret == NULL) { + ret = arena_chunk_alloc_huge_hard(tsdn, arena, &chunk_hooks, + usize, alignment, zero, csize); + } + + return (ret); +} + +void +arena_chunk_dalloc_huge(tsdn_t *tsdn, arena_t *arena, void *chunk, size_t usize) +{ + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + size_t csize; + + csize = CHUNK_CEILING(usize); + malloc_mutex_lock(tsdn, &arena->lock); + if (config_stats) { + arena_huge_dalloc_stats_update(arena, usize); + arena->stats.mapped -= usize; + } + arena_nactive_sub(arena, usize >> LG_PAGE); + + chunk_dalloc_cache(tsdn, arena, &chunk_hooks, chunk, csize, true); + malloc_mutex_unlock(tsdn, &arena->lock); +} + +void +arena_chunk_ralloc_huge_similar(tsdn_t *tsdn, arena_t *arena, void *chunk, + size_t oldsize, size_t usize) +{ + + assert(CHUNK_CEILING(oldsize) == CHUNK_CEILING(usize)); + assert(oldsize != usize); + + malloc_mutex_lock(tsdn, &arena->lock); + if (config_stats) + arena_huge_ralloc_stats_update(arena, oldsize, usize); + if (oldsize < usize) + arena_nactive_add(arena, (usize - oldsize) >> LG_PAGE); + else + arena_nactive_sub(arena, (oldsize - usize) >> LG_PAGE); + malloc_mutex_unlock(tsdn, &arena->lock); +} + +void +arena_chunk_ralloc_huge_shrink(tsdn_t *tsdn, arena_t *arena, void *chunk, + size_t oldsize, size_t usize) +{ + size_t udiff = oldsize - usize; + size_t cdiff = CHUNK_CEILING(oldsize) - CHUNK_CEILING(usize); + + malloc_mutex_lock(tsdn, &arena->lock); + if (config_stats) { + arena_huge_ralloc_stats_update(arena, oldsize, usize); + if (cdiff != 0) + arena->stats.mapped -= cdiff; + } + arena_nactive_sub(arena, udiff >> LG_PAGE); + + if (cdiff != 0) { + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + void *nchunk = (void *)((uintptr_t)chunk + + CHUNK_CEILING(usize)); + + chunk_dalloc_cache(tsdn, arena, &chunk_hooks, nchunk, cdiff, + true); + } + malloc_mutex_unlock(tsdn, &arena->lock); +} + +static bool +arena_chunk_ralloc_huge_expand_hard(tsdn_t *tsdn, arena_t *arena, + chunk_hooks_t *chunk_hooks, void *chunk, size_t oldsize, size_t usize, + bool *zero, void *nchunk, size_t udiff, size_t cdiff) +{ + bool err; + bool commit = true; + + err = (chunk_alloc_wrapper(tsdn, arena, chunk_hooks, nchunk, cdiff, + chunksize, zero, &commit) == NULL); + if (err) { + /* Revert optimistic stats updates. */ + malloc_mutex_lock(tsdn, &arena->lock); + if (config_stats) { + arena_huge_ralloc_stats_update_undo(arena, oldsize, + usize); + arena->stats.mapped -= cdiff; + } + arena_nactive_sub(arena, udiff >> LG_PAGE); + malloc_mutex_unlock(tsdn, &arena->lock); + } else if (chunk_hooks->merge(chunk, CHUNK_CEILING(oldsize), nchunk, + cdiff, true, arena->ind)) { + chunk_dalloc_wrapper(tsdn, arena, chunk_hooks, nchunk, cdiff, + *zero, true); + err = true; + } + return (err); +} + +bool +arena_chunk_ralloc_huge_expand(tsdn_t *tsdn, arena_t *arena, void *chunk, + size_t oldsize, size_t usize, bool *zero) +{ + bool err; + chunk_hooks_t chunk_hooks = chunk_hooks_get(tsdn, arena); + void *nchunk = (void *)((uintptr_t)chunk + CHUNK_CEILING(oldsize)); + size_t udiff = usize - oldsize; + size_t cdiff = CHUNK_CEILING(usize) - CHUNK_CEILING(oldsize); + + malloc_mutex_lock(tsdn, &arena->lock); + + /* Optimistically update stats. */ + if (config_stats) { + arena_huge_ralloc_stats_update(arena, oldsize, usize); + arena->stats.mapped += cdiff; + } + arena_nactive_add(arena, udiff >> LG_PAGE); + + err = (chunk_alloc_cache(tsdn, arena, &chunk_hooks, nchunk, cdiff, + chunksize, zero, true) == NULL); + malloc_mutex_unlock(tsdn, &arena->lock); + if (err) { + err = arena_chunk_ralloc_huge_expand_hard(tsdn, arena, + &chunk_hooks, chunk, oldsize, usize, zero, nchunk, udiff, + cdiff); + } else if (chunk_hooks.merge(chunk, CHUNK_CEILING(oldsize), nchunk, + cdiff, true, arena->ind)) { + chunk_dalloc_wrapper(tsdn, arena, &chunk_hooks, nchunk, cdiff, + *zero, true); + err = true; + } + + return (err); +} + +/* + * Do first-best-fit run selection, i.e. select the lowest run that best fits. + * Run sizes are indexed, so not all candidate runs are necessarily exactly the + * same size. + */ +static arena_run_t * +arena_run_first_best_fit(arena_t *arena, size_t size) +{ + szind_t ind, i; + + ind = size2index(run_quantize_ceil(size)); + for (i = ind; i < runs_avail_nclasses + runs_avail_bias; i++) { + arena_chunk_map_misc_t *miscelm = arena_run_heap_first( + arena_runs_avail_get(arena, i)); + if (miscelm != NULL) + return (&miscelm->run); + } + + return (NULL); +} + +static arena_run_t * +arena_run_alloc_large_helper(arena_t *arena, size_t size, bool zero) +{ + arena_run_t *run = arena_run_first_best_fit(arena, s2u(size)); + if (run != NULL) { + if (arena_run_split_large(arena, run, size, zero)) + run = NULL; + } + return (run); +} + +static arena_run_t * +arena_run_alloc_large(tsdn_t *tsdn, arena_t *arena, size_t size, bool zero) +{ + arena_chunk_t *chunk; + arena_run_t *run; + + assert(size <= arena_maxrun); + assert(size == PAGE_CEILING(size)); + + /* Search the arena's chunks for the lowest best fit. */ + run = arena_run_alloc_large_helper(arena, size, zero); + if (run != NULL) + return (run); + + /* + * No usable runs. Create a new chunk from which to allocate the run. + */ + chunk = arena_chunk_alloc(tsdn, arena); + if (chunk != NULL) { + run = &arena_miscelm_get_mutable(chunk, map_bias)->run; + if (arena_run_split_large(arena, run, size, zero)) + run = NULL; + return (run); + } + + /* + * arena_chunk_alloc() failed, but another thread may have made + * sufficient memory available while this one dropped arena->lock in + * arena_chunk_alloc(), so search one more time. + */ + return (arena_run_alloc_large_helper(arena, size, zero)); +} + +static arena_run_t * +arena_run_alloc_small_helper(arena_t *arena, size_t size, szind_t binind) +{ + arena_run_t *run = arena_run_first_best_fit(arena, size); + if (run != NULL) { + if (arena_run_split_small(arena, run, size, binind)) + run = NULL; + } + return (run); +} + +static arena_run_t * +arena_run_alloc_small(tsdn_t *tsdn, arena_t *arena, size_t size, szind_t binind) +{ + arena_chunk_t *chunk; + arena_run_t *run; + + assert(size <= arena_maxrun); + assert(size == PAGE_CEILING(size)); + assert(binind != BININD_INVALID); + + /* Search the arena's chunks for the lowest best fit. */ + run = arena_run_alloc_small_helper(arena, size, binind); + if (run != NULL) + return (run); + + /* + * No usable runs. Create a new chunk from which to allocate the run. + */ + chunk = arena_chunk_alloc(tsdn, arena); + if (chunk != NULL) { + run = &arena_miscelm_get_mutable(chunk, map_bias)->run; + if (arena_run_split_small(arena, run, size, binind)) + run = NULL; + return (run); + } + + /* + * arena_chunk_alloc() failed, but another thread may have made + * sufficient memory available while this one dropped arena->lock in + * arena_chunk_alloc(), so search one more time. + */ + return (arena_run_alloc_small_helper(arena, size, binind)); +} + +static bool +arena_lg_dirty_mult_valid(ssize_t lg_dirty_mult) +{ + + return (lg_dirty_mult >= -1 && lg_dirty_mult < (ssize_t)(sizeof(size_t) + << 3)); +} + +ssize_t +arena_lg_dirty_mult_get(tsdn_t *tsdn, arena_t *arena) +{ + ssize_t lg_dirty_mult; + + malloc_mutex_lock(tsdn, &arena->lock); + lg_dirty_mult = arena->lg_dirty_mult; + malloc_mutex_unlock(tsdn, &arena->lock); + + return (lg_dirty_mult); +} + +bool +arena_lg_dirty_mult_set(tsdn_t *tsdn, arena_t *arena, ssize_t lg_dirty_mult) +{ + + if (!arena_lg_dirty_mult_valid(lg_dirty_mult)) + return (true); + + malloc_mutex_lock(tsdn, &arena->lock); + arena->lg_dirty_mult = lg_dirty_mult; + arena_maybe_purge(tsdn, arena); + malloc_mutex_unlock(tsdn, &arena->lock); + + return (false); +} + +static void +arena_decay_deadline_init(arena_t *arena) +{ + + assert(opt_purge == purge_mode_decay); + + /* + * Generate a new deadline that is uniformly random within the next + * epoch after the current one. + */ + nstime_copy(&arena->decay_deadline, &arena->decay_epoch); + nstime_add(&arena->decay_deadline, &arena->decay_interval); + if (arena->decay_time > 0) { + nstime_t jitter; + + nstime_init(&jitter, prng_range(&arena->decay_jitter_state, + nstime_ns(&arena->decay_interval))); + nstime_add(&arena->decay_deadline, &jitter); + } +} + +static bool +arena_decay_deadline_reached(const arena_t *arena, const nstime_t *time) +{ + + assert(opt_purge == purge_mode_decay); + + return (nstime_compare(&arena->decay_deadline, time) <= 0); +} + +static size_t +arena_decay_backlog_npages_limit(const arena_t *arena) +{ + static const uint64_t h_steps[] = { +#define STEP(step, h, x, y) \ + h, + SMOOTHSTEP +#undef STEP + }; + uint64_t sum; + size_t npages_limit_backlog; + unsigned i; + + assert(opt_purge == purge_mode_decay); + + /* + * For each element of decay_backlog, multiply by the corresponding + * fixed-point smoothstep decay factor. Sum the products, then divide + * to round down to the nearest whole number of pages. + */ + sum = 0; + for (i = 0; i < SMOOTHSTEP_NSTEPS; i++) + sum += arena->decay_backlog[i] * h_steps[i]; + npages_limit_backlog = (size_t)(sum >> SMOOTHSTEP_BFP); + + return (npages_limit_backlog); +} + +static void +arena_decay_epoch_advance(arena_t *arena, const nstime_t *time) +{ + uint64_t nadvance_u64; + nstime_t delta; + size_t ndirty_delta; + + assert(opt_purge == purge_mode_decay); + assert(arena_decay_deadline_reached(arena, time)); + + nstime_copy(&delta, time); + nstime_subtract(&delta, &arena->decay_epoch); + nadvance_u64 = nstime_divide(&delta, &arena->decay_interval); + assert(nadvance_u64 > 0); + + /* Add nadvance_u64 decay intervals to epoch. */ + nstime_copy(&delta, &arena->decay_interval); + nstime_imultiply(&delta, nadvance_u64); + nstime_add(&arena->decay_epoch, &delta); + + /* Set a new deadline. */ + arena_decay_deadline_init(arena); + + /* Update the backlog. */ + if (nadvance_u64 >= SMOOTHSTEP_NSTEPS) { + memset(arena->decay_backlog, 0, (SMOOTHSTEP_NSTEPS-1) * + sizeof(size_t)); + } else { + size_t nadvance_z = (size_t)nadvance_u64; + + assert((uint64_t)nadvance_z == nadvance_u64); + + memmove(arena->decay_backlog, &arena->decay_backlog[nadvance_z], + (SMOOTHSTEP_NSTEPS - nadvance_z) * sizeof(size_t)); + if (nadvance_z > 1) { + memset(&arena->decay_backlog[SMOOTHSTEP_NSTEPS - + nadvance_z], 0, (nadvance_z-1) * sizeof(size_t)); + } + } + ndirty_delta = (arena->ndirty > arena->decay_ndirty) ? arena->ndirty - + arena->decay_ndirty : 0; + arena->decay_ndirty = arena->ndirty; + arena->decay_backlog[SMOOTHSTEP_NSTEPS-1] = ndirty_delta; + arena->decay_backlog_npages_limit = + arena_decay_backlog_npages_limit(arena); +} + +static size_t +arena_decay_npages_limit(arena_t *arena) +{ + size_t npages_limit; + + assert(opt_purge == purge_mode_decay); + + npages_limit = arena->decay_backlog_npages_limit; + + /* Add in any dirty pages created during the current epoch. */ + if (arena->ndirty > arena->decay_ndirty) + npages_limit += arena->ndirty - arena->decay_ndirty; + + return (npages_limit); +} + +static void +arena_decay_init(arena_t *arena, ssize_t decay_time) +{ + + arena->decay_time = decay_time; + if (decay_time > 0) { + nstime_init2(&arena->decay_interval, decay_time, 0); + nstime_idivide(&arena->decay_interval, SMOOTHSTEP_NSTEPS); + } + + nstime_init(&arena->decay_epoch, 0); + nstime_update(&arena->decay_epoch); + arena->decay_jitter_state = (uint64_t)(uintptr_t)arena; + arena_decay_deadline_init(arena); + arena->decay_ndirty = arena->ndirty; + arena->decay_backlog_npages_limit = 0; + memset(arena->decay_backlog, 0, SMOOTHSTEP_NSTEPS * sizeof(size_t)); +} + +static bool +arena_decay_time_valid(ssize_t decay_time) +{ + + if (decay_time < -1) + return (false); + if (decay_time == -1 || (uint64_t)decay_time <= NSTIME_SEC_MAX) + return (true); + return (false); +} + +ssize_t +arena_decay_time_get(tsdn_t *tsdn, arena_t *arena) +{ + ssize_t decay_time; + + malloc_mutex_lock(tsdn, &arena->lock); + decay_time = arena->decay_time; + malloc_mutex_unlock(tsdn, &arena->lock); + + return (decay_time); +} + +bool +arena_decay_time_set(tsdn_t *tsdn, arena_t *arena, ssize_t decay_time) +{ + + if (!arena_decay_time_valid(decay_time)) + return (true); + + malloc_mutex_lock(tsdn, &arena->lock); + /* + * Restart decay backlog from scratch, which may cause many dirty pages + * to be immediately purged. It would conceptually be possible to map + * the old backlog onto the new backlog, but there is no justification + * for such complexity since decay_time changes are intended to be + * infrequent, either between the {-1, 0, >0} states, or a one-time + * arbitrary change during initial arena configuration. + */ + arena_decay_init(arena, decay_time); + arena_maybe_purge(tsdn, arena); + malloc_mutex_unlock(tsdn, &arena->lock); + + return (false); +} + +static void +arena_maybe_purge_ratio(tsdn_t *tsdn, arena_t *arena) +{ + + assert(opt_purge == purge_mode_ratio); + + /* Don't purge if the option is disabled. */ + if (arena->lg_dirty_mult < 0) + return; + + /* + * Iterate, since preventing recursive purging could otherwise leave too + * many dirty pages. + */ + while (true) { + size_t threshold = (arena->nactive >> arena->lg_dirty_mult); + if (threshold < chunk_npages) + threshold = chunk_npages; + /* + * Don't purge unless the number of purgeable pages exceeds the + * threshold. + */ + if (arena->ndirty <= threshold) + return; + arena_purge_to_limit(tsdn, arena, threshold); + } +} + +static void +arena_maybe_purge_decay(tsdn_t *tsdn, arena_t *arena) +{ + nstime_t time; + size_t ndirty_limit; + + assert(opt_purge == purge_mode_decay); + + /* Purge all or nothing if the option is disabled. */ + if (arena->decay_time <= 0) { + if (arena->decay_time == 0) + arena_purge_to_limit(tsdn, arena, 0); + return; + } + + nstime_copy(&time, &arena->decay_epoch); + if (unlikely(nstime_update(&time))) { + /* Time went backwards. Force an epoch advance. */ + nstime_copy(&time, &arena->decay_deadline); + } + + if (arena_decay_deadline_reached(arena, &time)) + arena_decay_epoch_advance(arena, &time); + + ndirty_limit = arena_decay_npages_limit(arena); + + /* + * Don't try to purge unless the number of purgeable pages exceeds the + * current limit. + */ + if (arena->ndirty <= ndirty_limit) + return; + arena_purge_to_limit(tsdn, arena, ndirty_limit); +} + +void +arena_maybe_purge(tsdn_t *tsdn, arena_t *arena) +{ + + /* Don't recursively purge. */ + if (arena->purging) + return; + + if (opt_purge == purge_mode_ratio) + arena_maybe_purge_ratio(tsdn, arena); + else + arena_maybe_purge_decay(tsdn, arena); +} + +static size_t +arena_dirty_count(arena_t *arena) +{ + size_t ndirty = 0; + arena_runs_dirty_link_t *rdelm; + extent_node_t *chunkselm; + + for (rdelm = qr_next(&arena->runs_dirty, rd_link), + chunkselm = qr_next(&arena->chunks_cache, cc_link); + rdelm != &arena->runs_dirty; rdelm = qr_next(rdelm, rd_link)) { + size_t npages; + + if (rdelm == &chunkselm->rd) { + npages = extent_node_size_get(chunkselm) >> LG_PAGE; + chunkselm = qr_next(chunkselm, cc_link); + } else { + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE( + rdelm); + arena_chunk_map_misc_t *miscelm = + arena_rd_to_miscelm(rdelm); + size_t pageind = arena_miscelm_to_pageind(miscelm); + assert(arena_mapbits_allocated_get(chunk, pageind) == + 0); + assert(arena_mapbits_large_get(chunk, pageind) == 0); + assert(arena_mapbits_dirty_get(chunk, pageind) != 0); + npages = arena_mapbits_unallocated_size_get(chunk, + pageind) >> LG_PAGE; + } + ndirty += npages; + } + + return (ndirty); +} + +static size_t +arena_stash_dirty(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, + size_t ndirty_limit, arena_runs_dirty_link_t *purge_runs_sentinel, + extent_node_t *purge_chunks_sentinel) +{ + arena_runs_dirty_link_t *rdelm, *rdelm_next; + extent_node_t *chunkselm; + size_t nstashed = 0; + + /* Stash runs/chunks according to ndirty_limit. */ + for (rdelm = qr_next(&arena->runs_dirty, rd_link), + chunkselm = qr_next(&arena->chunks_cache, cc_link); + rdelm != &arena->runs_dirty; rdelm = rdelm_next) { + size_t npages; + rdelm_next = qr_next(rdelm, rd_link); + + if (rdelm == &chunkselm->rd) { + extent_node_t *chunkselm_next; + bool zero; + UNUSED void *chunk; + + npages = extent_node_size_get(chunkselm) >> LG_PAGE; + if (opt_purge == purge_mode_decay && arena->ndirty - + (nstashed + npages) < ndirty_limit) + break; + + chunkselm_next = qr_next(chunkselm, cc_link); + /* + * Allocate. chunkselm remains valid due to the + * dalloc_node=false argument to chunk_alloc_cache(). + */ + zero = false; + chunk = chunk_alloc_cache(tsdn, arena, chunk_hooks, + extent_node_addr_get(chunkselm), + extent_node_size_get(chunkselm), chunksize, &zero, + false); + assert(chunk == extent_node_addr_get(chunkselm)); + assert(zero == extent_node_zeroed_get(chunkselm)); + extent_node_dirty_insert(chunkselm, purge_runs_sentinel, + purge_chunks_sentinel); + assert(npages == (extent_node_size_get(chunkselm) >> + LG_PAGE)); + chunkselm = chunkselm_next; + } else { + arena_chunk_t *chunk = + (arena_chunk_t *)CHUNK_ADDR2BASE(rdelm); + arena_chunk_map_misc_t *miscelm = + arena_rd_to_miscelm(rdelm); + size_t pageind = arena_miscelm_to_pageind(miscelm); + arena_run_t *run = &miscelm->run; + size_t run_size = + arena_mapbits_unallocated_size_get(chunk, pageind); + + npages = run_size >> LG_PAGE; + if (opt_purge == purge_mode_decay && arena->ndirty - + (nstashed + npages) < ndirty_limit) + break; + + assert(pageind + npages <= chunk_npages); + assert(arena_mapbits_dirty_get(chunk, pageind) == + arena_mapbits_dirty_get(chunk, pageind+npages-1)); + + /* + * If purging the spare chunk's run, make it available + * prior to allocation. + */ + if (chunk == arena->spare) + arena_chunk_alloc(tsdn, arena); + + /* Temporarily allocate the free dirty run. */ + arena_run_split_large(arena, run, run_size, false); + /* Stash. */ + if (false) + qr_new(rdelm, rd_link); /* Redundant. */ + else { + assert(qr_next(rdelm, rd_link) == rdelm); + assert(qr_prev(rdelm, rd_link) == rdelm); + } + qr_meld(purge_runs_sentinel, rdelm, rd_link); + } + + nstashed += npages; + if (opt_purge == purge_mode_ratio && arena->ndirty - nstashed <= + ndirty_limit) + break; + } + + return (nstashed); +} + +static size_t +arena_purge_stashed(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, + arena_runs_dirty_link_t *purge_runs_sentinel, + extent_node_t *purge_chunks_sentinel) +{ + size_t npurged, nmadvise; + arena_runs_dirty_link_t *rdelm; + extent_node_t *chunkselm; + + if (config_stats) + nmadvise = 0; + npurged = 0; + + malloc_mutex_unlock(tsdn, &arena->lock); + for (rdelm = qr_next(purge_runs_sentinel, rd_link), + chunkselm = qr_next(purge_chunks_sentinel, cc_link); + rdelm != purge_runs_sentinel; rdelm = qr_next(rdelm, rd_link)) { + size_t npages; + + if (rdelm == &chunkselm->rd) { + /* + * Don't actually purge the chunk here because 1) + * chunkselm is embedded in the chunk and must remain + * valid, and 2) we deallocate the chunk in + * arena_unstash_purged(), where it is destroyed, + * decommitted, or purged, depending on chunk + * deallocation policy. + */ + size_t size = extent_node_size_get(chunkselm); + npages = size >> LG_PAGE; + chunkselm = qr_next(chunkselm, cc_link); + } else { + size_t pageind, run_size, flag_unzeroed, flags, i; + bool decommitted; + arena_chunk_t *chunk = + (arena_chunk_t *)CHUNK_ADDR2BASE(rdelm); + arena_chunk_map_misc_t *miscelm = + arena_rd_to_miscelm(rdelm); + pageind = arena_miscelm_to_pageind(miscelm); + run_size = arena_mapbits_large_size_get(chunk, pageind); + npages = run_size >> LG_PAGE; + + assert(pageind + npages <= chunk_npages); + assert(!arena_mapbits_decommitted_get(chunk, pageind)); + assert(!arena_mapbits_decommitted_get(chunk, + pageind+npages-1)); + decommitted = !chunk_hooks->decommit(chunk, chunksize, + pageind << LG_PAGE, npages << LG_PAGE, arena->ind); + if (decommitted) { + flag_unzeroed = 0; + flags = CHUNK_MAP_DECOMMITTED; + } else { + flag_unzeroed = chunk_purge_wrapper(tsdn, arena, + chunk_hooks, chunk, chunksize, pageind << + LG_PAGE, run_size) ? CHUNK_MAP_UNZEROED : 0; + flags = flag_unzeroed; + } + arena_mapbits_large_set(chunk, pageind+npages-1, 0, + flags); + arena_mapbits_large_set(chunk, pageind, run_size, + flags); + + /* + * Set the unzeroed flag for internal pages, now that + * chunk_purge_wrapper() has returned whether the pages + * were zeroed as a side effect of purging. This chunk + * map modification is safe even though the arena mutex + * isn't currently owned by this thread, because the run + * is marked as allocated, thus protecting it from being + * modified by any other thread. As long as these + * writes don't perturb the first and last elements' + * CHUNK_MAP_ALLOCATED bits, behavior is well defined. + */ + for (i = 1; i < npages-1; i++) { + arena_mapbits_internal_set(chunk, pageind+i, + flag_unzeroed); + } + } + + npurged += npages; + if (config_stats) + nmadvise++; + } + malloc_mutex_lock(tsdn, &arena->lock); + + if (config_stats) { + arena->stats.nmadvise += nmadvise; + arena->stats.purged += npurged; + } + + return (npurged); +} + +static void +arena_unstash_purged(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, + arena_runs_dirty_link_t *purge_runs_sentinel, + extent_node_t *purge_chunks_sentinel) +{ + arena_runs_dirty_link_t *rdelm, *rdelm_next; + extent_node_t *chunkselm; + + /* Deallocate chunks/runs. */ + for (rdelm = qr_next(purge_runs_sentinel, rd_link), + chunkselm = qr_next(purge_chunks_sentinel, cc_link); + rdelm != purge_runs_sentinel; rdelm = rdelm_next) { + rdelm_next = qr_next(rdelm, rd_link); + if (rdelm == &chunkselm->rd) { + extent_node_t *chunkselm_next = qr_next(chunkselm, + cc_link); + void *addr = extent_node_addr_get(chunkselm); + size_t size = extent_node_size_get(chunkselm); + bool zeroed = extent_node_zeroed_get(chunkselm); + bool committed = extent_node_committed_get(chunkselm); + extent_node_dirty_remove(chunkselm); + arena_node_dalloc(tsdn, arena, chunkselm); + chunkselm = chunkselm_next; + chunk_dalloc_wrapper(tsdn, arena, chunk_hooks, addr, + size, zeroed, committed); + } else { + arena_chunk_t *chunk = + (arena_chunk_t *)CHUNK_ADDR2BASE(rdelm); + arena_chunk_map_misc_t *miscelm = + arena_rd_to_miscelm(rdelm); + size_t pageind = arena_miscelm_to_pageind(miscelm); + bool decommitted = (arena_mapbits_decommitted_get(chunk, + pageind) != 0); + arena_run_t *run = &miscelm->run; + qr_remove(rdelm, rd_link); + arena_run_dalloc(tsdn, arena, run, false, true, + decommitted); + } + } +} + +/* + * NB: ndirty_limit is interpreted differently depending on opt_purge: + * - purge_mode_ratio: Purge as few dirty run/chunks as possible to reach the + * desired state: + * (arena->ndirty <= ndirty_limit) + * - purge_mode_decay: Purge as many dirty runs/chunks as possible without + * violating the invariant: + * (arena->ndirty >= ndirty_limit) + */ +static void +arena_purge_to_limit(tsdn_t *tsdn, arena_t *arena, size_t ndirty_limit) +{ + chunk_hooks_t chunk_hooks = chunk_hooks_get(tsdn, arena); + size_t npurge, npurged; + arena_runs_dirty_link_t purge_runs_sentinel; + extent_node_t purge_chunks_sentinel; + + arena->purging = true; + + /* + * Calls to arena_dirty_count() are disabled even for debug builds + * because overhead grows nonlinearly as memory usage increases. + */ + if (false && config_debug) { + size_t ndirty = arena_dirty_count(arena); + assert(ndirty == arena->ndirty); + } + assert(opt_purge != purge_mode_ratio || (arena->nactive >> + arena->lg_dirty_mult) < arena->ndirty || ndirty_limit == 0); + + qr_new(&purge_runs_sentinel, rd_link); + extent_node_dirty_linkage_init(&purge_chunks_sentinel); + + npurge = arena_stash_dirty(tsdn, arena, &chunk_hooks, ndirty_limit, + &purge_runs_sentinel, &purge_chunks_sentinel); + if (npurge == 0) + goto label_return; + npurged = arena_purge_stashed(tsdn, arena, &chunk_hooks, + &purge_runs_sentinel, &purge_chunks_sentinel); + assert(npurged == npurge); + arena_unstash_purged(tsdn, arena, &chunk_hooks, &purge_runs_sentinel, + &purge_chunks_sentinel); + + if (config_stats) + arena->stats.npurge++; + +label_return: + arena->purging = false; +} + +void +arena_purge(tsdn_t *tsdn, arena_t *arena, bool all) +{ + + malloc_mutex_lock(tsdn, &arena->lock); + if (all) + arena_purge_to_limit(tsdn, arena, 0); + else + arena_maybe_purge(tsdn, arena); + malloc_mutex_unlock(tsdn, &arena->lock); +} + +static void +arena_achunk_prof_reset(tsd_t *tsd, arena_t *arena, arena_chunk_t *chunk) +{ + size_t pageind, npages; + + cassert(config_prof); + assert(opt_prof); + + /* + * Iterate over the allocated runs and remove profiled allocations from + * the sample set. + */ + for (pageind = map_bias; pageind < chunk_npages; pageind += npages) { + if (arena_mapbits_allocated_get(chunk, pageind) != 0) { + if (arena_mapbits_large_get(chunk, pageind) != 0) { + void *ptr = (void *)((uintptr_t)chunk + (pageind + << LG_PAGE)); + size_t usize = isalloc(tsd_tsdn(tsd), ptr, + config_prof); + + prof_free(tsd, ptr, usize); + npages = arena_mapbits_large_size_get(chunk, + pageind) >> LG_PAGE; + } else { + /* Skip small run. */ + size_t binind = arena_mapbits_binind_get(chunk, + pageind); + arena_bin_info_t *bin_info = + &arena_bin_info[binind]; + npages = bin_info->run_size >> LG_PAGE; + } + } else { + /* Skip unallocated run. */ + npages = arena_mapbits_unallocated_size_get(chunk, + pageind) >> LG_PAGE; + } + assert(pageind + npages <= chunk_npages); + } +} + +void +arena_reset(tsd_t *tsd, arena_t *arena) +{ + unsigned i; + extent_node_t *node; + + /* + * Locking in this function is unintuitive. The caller guarantees that + * no concurrent operations are happening in this arena, but there are + * still reasons that some locking is necessary: + * + * - Some of the functions in the transitive closure of calls assume + * appropriate locks are held, and in some cases these locks are + * temporarily dropped to avoid lock order reversal or deadlock due to + * reentry. + * - mallctl("epoch", ...) may concurrently refresh stats. While + * strictly speaking this is a "concurrent operation", disallowing + * stats refreshes would impose an inconvenient burden. + */ + + /* Remove large allocations from prof sample set. */ + if (config_prof && opt_prof) { + ql_foreach(node, &arena->achunks, ql_link) { + arena_achunk_prof_reset(tsd, arena, + extent_node_addr_get(node)); + } + } + + /* Reset curruns for large size classes. */ + if (config_stats) { + for (i = 0; i < nlclasses; i++) + arena->stats.lstats[i].curruns = 0; + } + + /* Huge allocations. */ + malloc_mutex_lock(tsd_tsdn(tsd), &arena->huge_mtx); + for (node = ql_last(&arena->huge, ql_link); node != NULL; node = + ql_last(&arena->huge, ql_link)) { + void *ptr = extent_node_addr_get(node); + size_t usize; + + malloc_mutex_unlock(tsd_tsdn(tsd), &arena->huge_mtx); + if (config_stats || (config_prof && opt_prof)) + usize = isalloc(tsd_tsdn(tsd), ptr, config_prof); + /* Remove huge allocation from prof sample set. */ + if (config_prof && opt_prof) + prof_free(tsd, ptr, usize); + huge_dalloc(tsd_tsdn(tsd), ptr); + malloc_mutex_lock(tsd_tsdn(tsd), &arena->huge_mtx); + /* Cancel out unwanted effects on stats. */ + if (config_stats) + arena_huge_reset_stats_cancel(arena, usize); + } + malloc_mutex_unlock(tsd_tsdn(tsd), &arena->huge_mtx); + + malloc_mutex_lock(tsd_tsdn(tsd), &arena->lock); + + /* Bins. */ + for (i = 0; i < NBINS; i++) { + arena_bin_t *bin = &arena->bins[i]; + malloc_mutex_lock(tsd_tsdn(tsd), &bin->lock); + bin->runcur = NULL; + arena_run_heap_new(&bin->runs); + if (config_stats) { + bin->stats.curregs = 0; + bin->stats.curruns = 0; + } + malloc_mutex_unlock(tsd_tsdn(tsd), &bin->lock); + } + + /* + * Re-initialize runs_dirty such that the chunks_cache and runs_dirty + * chains directly correspond. + */ + qr_new(&arena->runs_dirty, rd_link); + for (node = qr_next(&arena->chunks_cache, cc_link); + node != &arena->chunks_cache; node = qr_next(node, cc_link)) { + qr_new(&node->rd, rd_link); + qr_meld(&arena->runs_dirty, &node->rd, rd_link); + } + + /* Arena chunks. */ + for (node = ql_last(&arena->achunks, ql_link); node != NULL; node = + ql_last(&arena->achunks, ql_link)) { + ql_remove(&arena->achunks, node, ql_link); + arena_chunk_discard(tsd_tsdn(tsd), arena, + extent_node_addr_get(node)); + } + + /* Spare. */ + if (arena->spare != NULL) { + arena_chunk_discard(tsd_tsdn(tsd), arena, arena->spare); + arena->spare = NULL; + } + + assert(!arena->purging); + arena->nactive = 0; + + for(i = 0; i < runs_avail_nclasses; i++) + arena_run_heap_new(&arena->runs_avail[i]); + + malloc_mutex_unlock(tsd_tsdn(tsd), &arena->lock); +} + +static void +arena_run_coalesce(arena_t *arena, arena_chunk_t *chunk, size_t *p_size, + size_t *p_run_ind, size_t *p_run_pages, size_t flag_dirty, + size_t flag_decommitted) +{ + size_t size = *p_size; + size_t run_ind = *p_run_ind; + size_t run_pages = *p_run_pages; + + /* Try to coalesce forward. */ + if (run_ind + run_pages < chunk_npages && + arena_mapbits_allocated_get(chunk, run_ind+run_pages) == 0 && + arena_mapbits_dirty_get(chunk, run_ind+run_pages) == flag_dirty && + arena_mapbits_decommitted_get(chunk, run_ind+run_pages) == + flag_decommitted) { + size_t nrun_size = arena_mapbits_unallocated_size_get(chunk, + run_ind+run_pages); + size_t nrun_pages = nrun_size >> LG_PAGE; + + /* + * Remove successor from runs_avail; the coalesced run is + * inserted later. + */ + assert(arena_mapbits_unallocated_size_get(chunk, + run_ind+run_pages+nrun_pages-1) == nrun_size); + assert(arena_mapbits_dirty_get(chunk, + run_ind+run_pages+nrun_pages-1) == flag_dirty); + assert(arena_mapbits_decommitted_get(chunk, + run_ind+run_pages+nrun_pages-1) == flag_decommitted); + arena_avail_remove(arena, chunk, run_ind+run_pages, nrun_pages); + + /* + * If the successor is dirty, remove it from the set of dirty + * pages. + */ + if (flag_dirty != 0) { + arena_run_dirty_remove(arena, chunk, run_ind+run_pages, + nrun_pages); + } + + size += nrun_size; + run_pages += nrun_pages; + + arena_mapbits_unallocated_size_set(chunk, run_ind, size); + arena_mapbits_unallocated_size_set(chunk, run_ind+run_pages-1, + size); + } + + /* Try to coalesce backward. */ + if (run_ind > map_bias && arena_mapbits_allocated_get(chunk, + run_ind-1) == 0 && arena_mapbits_dirty_get(chunk, run_ind-1) == + flag_dirty && arena_mapbits_decommitted_get(chunk, run_ind-1) == + flag_decommitted) { + size_t prun_size = arena_mapbits_unallocated_size_get(chunk, + run_ind-1); + size_t prun_pages = prun_size >> LG_PAGE; + + run_ind -= prun_pages; + + /* + * Remove predecessor from runs_avail; the coalesced run is + * inserted later. + */ + assert(arena_mapbits_unallocated_size_get(chunk, run_ind) == + prun_size); + assert(arena_mapbits_dirty_get(chunk, run_ind) == flag_dirty); + assert(arena_mapbits_decommitted_get(chunk, run_ind) == + flag_decommitted); + arena_avail_remove(arena, chunk, run_ind, prun_pages); + + /* + * If the predecessor is dirty, remove it from the set of dirty + * pages. + */ + if (flag_dirty != 0) { + arena_run_dirty_remove(arena, chunk, run_ind, + prun_pages); + } + + size += prun_size; + run_pages += prun_pages; + + arena_mapbits_unallocated_size_set(chunk, run_ind, size); + arena_mapbits_unallocated_size_set(chunk, run_ind+run_pages-1, + size); + } + + *p_size = size; + *p_run_ind = run_ind; + *p_run_pages = run_pages; +} + +static size_t +arena_run_size_get(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run, + size_t run_ind) +{ + size_t size; + + assert(run_ind >= map_bias); + assert(run_ind < chunk_npages); + + if (arena_mapbits_large_get(chunk, run_ind) != 0) { + size = arena_mapbits_large_size_get(chunk, run_ind); + assert(size == PAGE || arena_mapbits_large_size_get(chunk, + run_ind+(size>>LG_PAGE)-1) == 0); + } else { + arena_bin_info_t *bin_info = &arena_bin_info[run->binind]; + size = bin_info->run_size; + } + + return (size); +} + +static void +arena_run_dalloc(tsdn_t *tsdn, arena_t *arena, arena_run_t *run, bool dirty, + bool cleaned, bool decommitted) +{ + arena_chunk_t *chunk; + arena_chunk_map_misc_t *miscelm; + size_t size, run_ind, run_pages, flag_dirty, flag_decommitted; + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); + miscelm = arena_run_to_miscelm(run); + run_ind = arena_miscelm_to_pageind(miscelm); + assert(run_ind >= map_bias); + assert(run_ind < chunk_npages); + size = arena_run_size_get(arena, chunk, run, run_ind); + run_pages = (size >> LG_PAGE); + arena_nactive_sub(arena, run_pages); + + /* + * The run is dirty if the caller claims to have dirtied it, as well as + * if it was already dirty before being allocated and the caller + * doesn't claim to have cleaned it. + */ + assert(arena_mapbits_dirty_get(chunk, run_ind) == + arena_mapbits_dirty_get(chunk, run_ind+run_pages-1)); + if (!cleaned && !decommitted && arena_mapbits_dirty_get(chunk, run_ind) + != 0) + dirty = true; + flag_dirty = dirty ? CHUNK_MAP_DIRTY : 0; + flag_decommitted = decommitted ? CHUNK_MAP_DECOMMITTED : 0; + + /* Mark pages as unallocated in the chunk map. */ + if (dirty || decommitted) { + size_t flags = flag_dirty | flag_decommitted; + arena_mapbits_unallocated_set(chunk, run_ind, size, flags); + arena_mapbits_unallocated_set(chunk, run_ind+run_pages-1, size, + flags); + } else { + arena_mapbits_unallocated_set(chunk, run_ind, size, + arena_mapbits_unzeroed_get(chunk, run_ind)); + arena_mapbits_unallocated_set(chunk, run_ind+run_pages-1, size, + arena_mapbits_unzeroed_get(chunk, run_ind+run_pages-1)); + } + + arena_run_coalesce(arena, chunk, &size, &run_ind, &run_pages, + flag_dirty, flag_decommitted); + + /* Insert into runs_avail, now that coalescing is complete. */ + assert(arena_mapbits_unallocated_size_get(chunk, run_ind) == + arena_mapbits_unallocated_size_get(chunk, run_ind+run_pages-1)); + assert(arena_mapbits_dirty_get(chunk, run_ind) == + arena_mapbits_dirty_get(chunk, run_ind+run_pages-1)); + assert(arena_mapbits_decommitted_get(chunk, run_ind) == + arena_mapbits_decommitted_get(chunk, run_ind+run_pages-1)); + arena_avail_insert(arena, chunk, run_ind, run_pages); + + if (dirty) + arena_run_dirty_insert(arena, chunk, run_ind, run_pages); + + /* Deallocate chunk if it is now completely unused. */ + if (size == arena_maxrun) { + assert(run_ind == map_bias); + assert(run_pages == (arena_maxrun >> LG_PAGE)); + arena_chunk_dalloc(tsdn, arena, chunk); + } + + /* + * It is okay to do dirty page processing here even if the chunk was + * deallocated above, since in that case it is the spare. Waiting + * until after possible chunk deallocation to do dirty processing + * allows for an old spare to be fully deallocated, thus decreasing the + * chances of spuriously crossing the dirty page purging threshold. + */ + if (dirty) + arena_maybe_purge(tsdn, arena); +} + +static void +arena_run_trim_head(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, + arena_run_t *run, size_t oldsize, size_t newsize) +{ + arena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run); + size_t pageind = arena_miscelm_to_pageind(miscelm); + size_t head_npages = (oldsize - newsize) >> LG_PAGE; + size_t flag_dirty = arena_mapbits_dirty_get(chunk, pageind); + size_t flag_decommitted = arena_mapbits_decommitted_get(chunk, pageind); + size_t flag_unzeroed_mask = (flag_dirty | flag_decommitted) == 0 ? + CHUNK_MAP_UNZEROED : 0; + + assert(oldsize > newsize); + + /* + * Update the chunk map so that arena_run_dalloc() can treat the + * leading run as separately allocated. Set the last element of each + * run first, in case of single-page runs. + */ + assert(arena_mapbits_large_size_get(chunk, pageind) == oldsize); + arena_mapbits_large_set(chunk, pageind+head_npages-1, 0, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, + pageind+head_npages-1))); + arena_mapbits_large_set(chunk, pageind, oldsize-newsize, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, pageind))); + + if (config_debug) { + UNUSED size_t tail_npages = newsize >> LG_PAGE; + assert(arena_mapbits_large_size_get(chunk, + pageind+head_npages+tail_npages-1) == 0); + assert(arena_mapbits_dirty_get(chunk, + pageind+head_npages+tail_npages-1) == flag_dirty); + } + arena_mapbits_large_set(chunk, pageind+head_npages, newsize, + flag_dirty | (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, + pageind+head_npages))); + + arena_run_dalloc(tsdn, arena, run, false, false, (flag_decommitted != + 0)); +} + +static void +arena_run_trim_tail(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, + arena_run_t *run, size_t oldsize, size_t newsize, bool dirty) +{ + arena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run); + size_t pageind = arena_miscelm_to_pageind(miscelm); + size_t head_npages = newsize >> LG_PAGE; + size_t flag_dirty = arena_mapbits_dirty_get(chunk, pageind); + size_t flag_decommitted = arena_mapbits_decommitted_get(chunk, pageind); + size_t flag_unzeroed_mask = (flag_dirty | flag_decommitted) == 0 ? + CHUNK_MAP_UNZEROED : 0; + arena_chunk_map_misc_t *tail_miscelm; + arena_run_t *tail_run; + + assert(oldsize > newsize); + + /* + * Update the chunk map so that arena_run_dalloc() can treat the + * trailing run as separately allocated. Set the last element of each + * run first, in case of single-page runs. + */ + assert(arena_mapbits_large_size_get(chunk, pageind) == oldsize); + arena_mapbits_large_set(chunk, pageind+head_npages-1, 0, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, + pageind+head_npages-1))); + arena_mapbits_large_set(chunk, pageind, newsize, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, pageind))); + + if (config_debug) { + UNUSED size_t tail_npages = (oldsize - newsize) >> LG_PAGE; + assert(arena_mapbits_large_size_get(chunk, + pageind+head_npages+tail_npages-1) == 0); + assert(arena_mapbits_dirty_get(chunk, + pageind+head_npages+tail_npages-1) == flag_dirty); + } + arena_mapbits_large_set(chunk, pageind+head_npages, oldsize-newsize, + flag_dirty | (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, + pageind+head_npages))); + + tail_miscelm = arena_miscelm_get_mutable(chunk, pageind + head_npages); + tail_run = &tail_miscelm->run; + arena_run_dalloc(tsdn, arena, tail_run, dirty, false, (flag_decommitted + != 0)); +} + +static void +arena_bin_runs_insert(arena_bin_t *bin, arena_run_t *run) +{ + arena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run); + + arena_run_heap_insert(&bin->runs, miscelm); +} + +static arena_run_t * +arena_bin_nonfull_run_tryget(arena_bin_t *bin) +{ + arena_chunk_map_misc_t *miscelm; + + miscelm = arena_run_heap_remove_first(&bin->runs); + if (miscelm == NULL) + return (NULL); + if (config_stats) + bin->stats.reruns++; + + return (&miscelm->run); +} + +static arena_run_t * +arena_bin_nonfull_run_get(tsdn_t *tsdn, arena_t *arena, arena_bin_t *bin) +{ + arena_run_t *run; + szind_t binind; + arena_bin_info_t *bin_info; + + /* Look for a usable run. */ + run = arena_bin_nonfull_run_tryget(bin); + if (run != NULL) + return (run); + /* No existing runs have any space available. */ + + binind = arena_bin_index(arena, bin); + bin_info = &arena_bin_info[binind]; + + /* Allocate a new run. */ + malloc_mutex_unlock(tsdn, &bin->lock); + /******************************/ + malloc_mutex_lock(tsdn, &arena->lock); + run = arena_run_alloc_small(tsdn, arena, bin_info->run_size, binind); + if (run != NULL) { + /* Initialize run internals. */ + run->binind = binind; + run->nfree = bin_info->nregs; + bitmap_init(run->bitmap, &bin_info->bitmap_info); + } + malloc_mutex_unlock(tsdn, &arena->lock); + /********************************/ + malloc_mutex_lock(tsdn, &bin->lock); + if (run != NULL) { + if (config_stats) { + bin->stats.nruns++; + bin->stats.curruns++; + } + return (run); + } + + /* + * arena_run_alloc_small() failed, but another thread may have made + * sufficient memory available while this one dropped bin->lock above, + * so search one more time. + */ + run = arena_bin_nonfull_run_tryget(bin); + if (run != NULL) + return (run); + + return (NULL); +} + +/* Re-fill bin->runcur, then call arena_run_reg_alloc(). */ +static void * +arena_bin_malloc_hard(tsdn_t *tsdn, arena_t *arena, arena_bin_t *bin) +{ + szind_t binind; + arena_bin_info_t *bin_info; + arena_run_t *run; + + binind = arena_bin_index(arena, bin); + bin_info = &arena_bin_info[binind]; + bin->runcur = NULL; + run = arena_bin_nonfull_run_get(tsdn, arena, bin); + if (bin->runcur != NULL && bin->runcur->nfree > 0) { + /* + * Another thread updated runcur while this one ran without the + * bin lock in arena_bin_nonfull_run_get(). + */ + void *ret; + assert(bin->runcur->nfree > 0); + ret = arena_run_reg_alloc(bin->runcur, bin_info); + if (run != NULL) { + arena_chunk_t *chunk; + + /* + * arena_run_alloc_small() may have allocated run, or + * it may have pulled run from the bin's run tree. + * Therefore it is unsafe to make any assumptions about + * how run has previously been used, and + * arena_bin_lower_run() must be called, as if a region + * were just deallocated from the run. + */ + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); + if (run->nfree == bin_info->nregs) { + arena_dalloc_bin_run(tsdn, arena, chunk, run, + bin); + } else + arena_bin_lower_run(arena, chunk, run, bin); + } + return (ret); + } + + if (run == NULL) + return (NULL); + + bin->runcur = run; + + assert(bin->runcur->nfree > 0); + + return (arena_run_reg_alloc(bin->runcur, bin_info)); +} + +void +arena_tcache_fill_small(tsdn_t *tsdn, arena_t *arena, tcache_bin_t *tbin, + szind_t binind, uint64_t prof_accumbytes) +{ + unsigned i, nfill; + arena_bin_t *bin; + + assert(tbin->ncached == 0); + + if (config_prof && arena_prof_accum(tsdn, arena, prof_accumbytes)) + prof_idump(tsdn); + bin = &arena->bins[binind]; + malloc_mutex_lock(tsdn, &bin->lock); + for (i = 0, nfill = (tcache_bin_info[binind].ncached_max >> + tbin->lg_fill_div); i < nfill; i++) { + arena_run_t *run; + void *ptr; + if ((run = bin->runcur) != NULL && run->nfree > 0) + ptr = arena_run_reg_alloc(run, &arena_bin_info[binind]); + else + ptr = arena_bin_malloc_hard(tsdn, arena, bin); + if (ptr == NULL) { + /* + * OOM. tbin->avail isn't yet filled down to its first + * element, so the successful allocations (if any) must + * be moved just before tbin->avail before bailing out. + */ + if (i > 0) { + memmove(tbin->avail - i, tbin->avail - nfill, + i * sizeof(void *)); + } + break; + } + if (config_fill && unlikely(opt_junk_alloc)) { + arena_alloc_junk_small(ptr, &arena_bin_info[binind], + true); + } + /* Insert such that low regions get used first. */ + *(tbin->avail - nfill + i) = ptr; + } + if (config_stats) { + bin->stats.nmalloc += i; + bin->stats.nrequests += tbin->tstats.nrequests; + bin->stats.curregs += i; + bin->stats.nfills++; + tbin->tstats.nrequests = 0; + } + malloc_mutex_unlock(tsdn, &bin->lock); + tbin->ncached = i; + arena_decay_tick(tsdn, arena); +} + +void +arena_alloc_junk_small(void *ptr, arena_bin_info_t *bin_info, bool zero) +{ + + size_t redzone_size = bin_info->redzone_size; + + if (zero) { + memset((void *)((uintptr_t)ptr - redzone_size), + JEMALLOC_ALLOC_JUNK, redzone_size); + memset((void *)((uintptr_t)ptr + bin_info->reg_size), + JEMALLOC_ALLOC_JUNK, redzone_size); + } else { + memset((void *)((uintptr_t)ptr - redzone_size), + JEMALLOC_ALLOC_JUNK, bin_info->reg_interval); + } +} + +#ifdef JEMALLOC_JET +#undef arena_redzone_corruption +#define arena_redzone_corruption JEMALLOC_N(n_arena_redzone_corruption) +#endif +static void +arena_redzone_corruption(void *ptr, size_t usize, bool after, + size_t offset, uint8_t byte) +{ + + malloc_printf(": Corrupt redzone %zu byte%s %s %p " + "(size %zu), byte=%#x\n", offset, (offset == 1) ? "" : "s", + after ? "after" : "before", ptr, usize, byte); +} +#ifdef JEMALLOC_JET +#undef arena_redzone_corruption +#define arena_redzone_corruption JEMALLOC_N(arena_redzone_corruption) +arena_redzone_corruption_t *arena_redzone_corruption = + JEMALLOC_N(n_arena_redzone_corruption); +#endif + +static void +arena_redzones_validate(void *ptr, arena_bin_info_t *bin_info, bool reset) +{ + bool error = false; + + if (opt_junk_alloc) { + size_t size = bin_info->reg_size; + size_t redzone_size = bin_info->redzone_size; + size_t i; + + for (i = 1; i <= redzone_size; i++) { + uint8_t *byte = (uint8_t *)((uintptr_t)ptr - i); + if (*byte != JEMALLOC_ALLOC_JUNK) { + error = true; + arena_redzone_corruption(ptr, size, false, i, + *byte); + if (reset) + *byte = JEMALLOC_ALLOC_JUNK; + } + } + for (i = 0; i < redzone_size; i++) { + uint8_t *byte = (uint8_t *)((uintptr_t)ptr + size + i); + if (*byte != JEMALLOC_ALLOC_JUNK) { + error = true; + arena_redzone_corruption(ptr, size, true, i, + *byte); + if (reset) + *byte = JEMALLOC_ALLOC_JUNK; + } + } + } + + if (opt_abort && error) + abort(); +} + +#ifdef JEMALLOC_JET +#undef arena_dalloc_junk_small +#define arena_dalloc_junk_small JEMALLOC_N(n_arena_dalloc_junk_small) +#endif +void +arena_dalloc_junk_small(void *ptr, arena_bin_info_t *bin_info) +{ + size_t redzone_size = bin_info->redzone_size; + + arena_redzones_validate(ptr, bin_info, false); + memset((void *)((uintptr_t)ptr - redzone_size), JEMALLOC_FREE_JUNK, + bin_info->reg_interval); +} +#ifdef JEMALLOC_JET +#undef arena_dalloc_junk_small +#define arena_dalloc_junk_small JEMALLOC_N(arena_dalloc_junk_small) +arena_dalloc_junk_small_t *arena_dalloc_junk_small = + JEMALLOC_N(n_arena_dalloc_junk_small); +#endif + +void +arena_quarantine_junk_small(void *ptr, size_t usize) +{ + szind_t binind; + arena_bin_info_t *bin_info; + cassert(config_fill); + assert(opt_junk_free); + assert(opt_quarantine); + assert(usize <= SMALL_MAXCLASS); + + binind = size2index(usize); + bin_info = &arena_bin_info[binind]; + arena_redzones_validate(ptr, bin_info, true); +} + +static void * +arena_malloc_small(tsdn_t *tsdn, arena_t *arena, szind_t binind, bool zero) +{ + void *ret; + arena_bin_t *bin; + size_t usize; + arena_run_t *run; + + assert(binind < NBINS); + bin = &arena->bins[binind]; + usize = index2size(binind); + + malloc_mutex_lock(tsdn, &bin->lock); + if ((run = bin->runcur) != NULL && run->nfree > 0) + ret = arena_run_reg_alloc(run, &arena_bin_info[binind]); + else + ret = arena_bin_malloc_hard(tsdn, arena, bin); + + if (ret == NULL) { + malloc_mutex_unlock(tsdn, &bin->lock); + return (NULL); + } + + if (config_stats) { + bin->stats.nmalloc++; + bin->stats.nrequests++; + bin->stats.curregs++; + } + malloc_mutex_unlock(tsdn, &bin->lock); + if (config_prof && !isthreaded && arena_prof_accum(tsdn, arena, usize)) + prof_idump(tsdn); + + if (!zero) { + if (config_fill) { + if (unlikely(opt_junk_alloc)) { + arena_alloc_junk_small(ret, + &arena_bin_info[binind], false); + } else if (unlikely(opt_zero)) + memset(ret, 0, usize); + } + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, usize); + } else { + if (config_fill && unlikely(opt_junk_alloc)) { + arena_alloc_junk_small(ret, &arena_bin_info[binind], + true); + } + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, usize); + memset(ret, 0, usize); + } + + arena_decay_tick(tsdn, arena); + return (ret); +} + +void * +arena_malloc_large(tsdn_t *tsdn, arena_t *arena, szind_t binind, bool zero) +{ + void *ret; + size_t usize; + uintptr_t random_offset; + arena_run_t *run; + arena_chunk_map_misc_t *miscelm; + UNUSED bool idump JEMALLOC_CC_SILENCE_INIT(false); + + /* Large allocation. */ + usize = index2size(binind); + malloc_mutex_lock(tsdn, &arena->lock); + if (config_cache_oblivious) { + uint64_t r; + + /* + * Compute a uniformly distributed offset within the first page + * that is a multiple of the cacheline size, e.g. [0 .. 63) * 64 + * for 4 KiB pages and 64-byte cachelines. + */ + r = prng_lg_range(&arena->offset_state, LG_PAGE - LG_CACHELINE); + random_offset = ((uintptr_t)r) << LG_CACHELINE; + } else + random_offset = 0; + run = arena_run_alloc_large(tsdn, arena, usize + large_pad, zero); + if (run == NULL) { + malloc_mutex_unlock(tsdn, &arena->lock); + return (NULL); + } + miscelm = arena_run_to_miscelm(run); + ret = (void *)((uintptr_t)arena_miscelm_to_rpages(miscelm) + + random_offset); + if (config_stats) { + szind_t index = binind - NBINS; + + arena->stats.nmalloc_large++; + arena->stats.nrequests_large++; + arena->stats.allocated_large += usize; + arena->stats.lstats[index].nmalloc++; + arena->stats.lstats[index].nrequests++; + arena->stats.lstats[index].curruns++; + } + if (config_prof) + idump = arena_prof_accum_locked(arena, usize); + malloc_mutex_unlock(tsdn, &arena->lock); + if (config_prof && idump) + prof_idump(tsdn); + + if (!zero) { + if (config_fill) { + if (unlikely(opt_junk_alloc)) + memset(ret, JEMALLOC_ALLOC_JUNK, usize); + else if (unlikely(opt_zero)) + memset(ret, 0, usize); + } + } + + arena_decay_tick(tsdn, arena); + return (ret); +} + +void * +arena_malloc_hard(tsdn_t *tsdn, arena_t *arena, size_t size, szind_t ind, + bool zero) +{ + + assert(!tsdn_null(tsdn) || arena != NULL); + + if (likely(!tsdn_null(tsdn))) + arena = arena_choose(tsdn_tsd(tsdn), arena); + if (unlikely(arena == NULL)) + return (NULL); + + if (likely(size <= SMALL_MAXCLASS)) + return (arena_malloc_small(tsdn, arena, ind, zero)); + if (likely(size <= large_maxclass)) + return (arena_malloc_large(tsdn, arena, ind, zero)); + return (huge_malloc(tsdn, arena, index2size(ind), zero)); +} + +/* Only handles large allocations that require more than page alignment. */ +static void * +arena_palloc_large(tsdn_t *tsdn, arena_t *arena, size_t usize, size_t alignment, + bool zero) +{ + void *ret; + size_t alloc_size, leadsize, trailsize; + arena_run_t *run; + arena_chunk_t *chunk; + arena_chunk_map_misc_t *miscelm; + void *rpages; + + assert(!tsdn_null(tsdn) || arena != NULL); + assert(usize == PAGE_CEILING(usize)); + + if (likely(!tsdn_null(tsdn))) + arena = arena_choose(tsdn_tsd(tsdn), arena); + if (unlikely(arena == NULL)) + return (NULL); + + alignment = PAGE_CEILING(alignment); + alloc_size = usize + large_pad + alignment - PAGE; + + malloc_mutex_lock(tsdn, &arena->lock); + run = arena_run_alloc_large(tsdn, arena, alloc_size, false); + if (run == NULL) { + malloc_mutex_unlock(tsdn, &arena->lock); + return (NULL); + } + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); + miscelm = arena_run_to_miscelm(run); + rpages = arena_miscelm_to_rpages(miscelm); + + leadsize = ALIGNMENT_CEILING((uintptr_t)rpages, alignment) - + (uintptr_t)rpages; + assert(alloc_size >= leadsize + usize); + trailsize = alloc_size - leadsize - usize - large_pad; + if (leadsize != 0) { + arena_chunk_map_misc_t *head_miscelm = miscelm; + arena_run_t *head_run = run; + + miscelm = arena_miscelm_get_mutable(chunk, + arena_miscelm_to_pageind(head_miscelm) + (leadsize >> + LG_PAGE)); + run = &miscelm->run; + + arena_run_trim_head(tsdn, arena, chunk, head_run, alloc_size, + alloc_size - leadsize); + } + if (trailsize != 0) { + arena_run_trim_tail(tsdn, arena, chunk, run, usize + large_pad + + trailsize, usize + large_pad, false); + } + if (arena_run_init_large(arena, run, usize + large_pad, zero)) { + size_t run_ind = + arena_miscelm_to_pageind(arena_run_to_miscelm(run)); + bool dirty = (arena_mapbits_dirty_get(chunk, run_ind) != 0); + bool decommitted = (arena_mapbits_decommitted_get(chunk, + run_ind) != 0); + + assert(decommitted); /* Cause of OOM. */ + arena_run_dalloc(tsdn, arena, run, dirty, false, decommitted); + malloc_mutex_unlock(tsdn, &arena->lock); + return (NULL); + } + ret = arena_miscelm_to_rpages(miscelm); + + if (config_stats) { + szind_t index = size2index(usize) - NBINS; + + arena->stats.nmalloc_large++; + arena->stats.nrequests_large++; + arena->stats.allocated_large += usize; + arena->stats.lstats[index].nmalloc++; + arena->stats.lstats[index].nrequests++; + arena->stats.lstats[index].curruns++; + } + malloc_mutex_unlock(tsdn, &arena->lock); + + if (config_fill && !zero) { + if (unlikely(opt_junk_alloc)) + memset(ret, JEMALLOC_ALLOC_JUNK, usize); + else if (unlikely(opt_zero)) + memset(ret, 0, usize); + } + arena_decay_tick(tsdn, arena); + return (ret); +} + +void * +arena_palloc(tsdn_t *tsdn, arena_t *arena, size_t usize, size_t alignment, + bool zero, tcache_t *tcache) +{ + void *ret; + + if (usize <= SMALL_MAXCLASS && (alignment < PAGE || (alignment == PAGE + && (usize & PAGE_MASK) == 0))) { + /* Small; alignment doesn't require special run placement. */ + ret = arena_malloc(tsdn, arena, usize, size2index(usize), zero, + tcache, true); + } else if (usize <= large_maxclass && alignment <= PAGE) { + /* + * Large; alignment doesn't require special run placement. + * However, the cached pointer may be at a random offset from + * the base of the run, so do some bit manipulation to retrieve + * the base. + */ + ret = arena_malloc(tsdn, arena, usize, size2index(usize), zero, + tcache, true); + if (config_cache_oblivious) + ret = (void *)((uintptr_t)ret & ~PAGE_MASK); + } else { + if (likely(usize <= large_maxclass)) { + ret = arena_palloc_large(tsdn, arena, usize, alignment, + zero); + } else if (likely(alignment <= chunksize)) + ret = huge_malloc(tsdn, arena, usize, zero); + else { + ret = huge_palloc(tsdn, arena, usize, alignment, zero); + } + } + return (ret); +} + +void +arena_prof_promoted(tsdn_t *tsdn, const void *ptr, size_t size) +{ + arena_chunk_t *chunk; + size_t pageind; + szind_t binind; + + cassert(config_prof); + assert(ptr != NULL); + assert(CHUNK_ADDR2BASE(ptr) != ptr); + assert(isalloc(tsdn, ptr, false) == LARGE_MINCLASS); + assert(isalloc(tsdn, ptr, true) == LARGE_MINCLASS); + assert(size <= SMALL_MAXCLASS); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + binind = size2index(size); + assert(binind < NBINS); + arena_mapbits_large_binind_set(chunk, pageind, binind); + + assert(isalloc(tsdn, ptr, false) == LARGE_MINCLASS); + assert(isalloc(tsdn, ptr, true) == size); +} + +static void +arena_dissociate_bin_run(arena_chunk_t *chunk, arena_run_t *run, + arena_bin_t *bin) +{ + + /* Dissociate run from bin. */ + if (run == bin->runcur) + bin->runcur = NULL; + else { + szind_t binind = arena_bin_index(extent_node_arena_get( + &chunk->node), bin); + arena_bin_info_t *bin_info = &arena_bin_info[binind]; + + /* + * The following block's conditional is necessary because if the + * run only contains one region, then it never gets inserted + * into the non-full runs tree. + */ + if (bin_info->nregs != 1) { + arena_chunk_map_misc_t *miscelm = + arena_run_to_miscelm(run); + + arena_run_heap_remove(&bin->runs, miscelm); + } + } +} + +static void +arena_dalloc_bin_run(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, + arena_run_t *run, arena_bin_t *bin) +{ + + assert(run != bin->runcur); + + malloc_mutex_unlock(tsdn, &bin->lock); + /******************************/ + malloc_mutex_lock(tsdn, &arena->lock); + arena_run_dalloc(tsdn, arena, run, true, false, false); + malloc_mutex_unlock(tsdn, &arena->lock); + /****************************/ + malloc_mutex_lock(tsdn, &bin->lock); + if (config_stats) + bin->stats.curruns--; +} + +static void +arena_bin_lower_run(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run, + arena_bin_t *bin) +{ + + /* + * Make sure that if bin->runcur is non-NULL, it refers to the lowest + * non-full run. It is okay to NULL runcur out rather than proactively + * keeping it pointing at the lowest non-full run. + */ + if ((uintptr_t)run < (uintptr_t)bin->runcur) { + /* Switch runcur. */ + if (bin->runcur->nfree > 0) + arena_bin_runs_insert(bin, bin->runcur); + bin->runcur = run; + if (config_stats) + bin->stats.reruns++; + } else + arena_bin_runs_insert(bin, run); +} + +static void +arena_dalloc_bin_locked_impl(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, + void *ptr, arena_chunk_map_bits_t *bitselm, bool junked) +{ + size_t pageind, rpages_ind; + arena_run_t *run; + arena_bin_t *bin; + arena_bin_info_t *bin_info; + szind_t binind; + + pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + rpages_ind = pageind - arena_mapbits_small_runind_get(chunk, pageind); + run = &arena_miscelm_get_mutable(chunk, rpages_ind)->run; + binind = run->binind; + bin = &arena->bins[binind]; + bin_info = &arena_bin_info[binind]; + + if (!junked && config_fill && unlikely(opt_junk_free)) + arena_dalloc_junk_small(ptr, bin_info); + + arena_run_reg_dalloc(run, ptr); + if (run->nfree == bin_info->nregs) { + arena_dissociate_bin_run(chunk, run, bin); + arena_dalloc_bin_run(tsdn, arena, chunk, run, bin); + } else if (run->nfree == 1 && run != bin->runcur) + arena_bin_lower_run(arena, chunk, run, bin); + + if (config_stats) { + bin->stats.ndalloc++; + bin->stats.curregs--; + } +} + +void +arena_dalloc_bin_junked_locked(tsdn_t *tsdn, arena_t *arena, + arena_chunk_t *chunk, void *ptr, arena_chunk_map_bits_t *bitselm) +{ + + arena_dalloc_bin_locked_impl(tsdn, arena, chunk, ptr, bitselm, true); +} + +void +arena_dalloc_bin(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, void *ptr, + size_t pageind, arena_chunk_map_bits_t *bitselm) +{ + arena_run_t *run; + arena_bin_t *bin; + size_t rpages_ind; + + rpages_ind = pageind - arena_mapbits_small_runind_get(chunk, pageind); + run = &arena_miscelm_get_mutable(chunk, rpages_ind)->run; + bin = &arena->bins[run->binind]; + malloc_mutex_lock(tsdn, &bin->lock); + arena_dalloc_bin_locked_impl(tsdn, arena, chunk, ptr, bitselm, false); + malloc_mutex_unlock(tsdn, &bin->lock); +} + +void +arena_dalloc_small(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, + void *ptr, size_t pageind) +{ + arena_chunk_map_bits_t *bitselm; + + if (config_debug) { + /* arena_ptr_small_binind_get() does extra sanity checking. */ + assert(arena_ptr_small_binind_get(ptr, arena_mapbits_get(chunk, + pageind)) != BININD_INVALID); + } + bitselm = arena_bitselm_get_mutable(chunk, pageind); + arena_dalloc_bin(tsdn, arena, chunk, ptr, pageind, bitselm); + arena_decay_tick(tsdn, arena); +} + +#ifdef JEMALLOC_JET +#undef arena_dalloc_junk_large +#define arena_dalloc_junk_large JEMALLOC_N(n_arena_dalloc_junk_large) +#endif +void +arena_dalloc_junk_large(void *ptr, size_t usize) +{ + + if (config_fill && unlikely(opt_junk_free)) + memset(ptr, JEMALLOC_FREE_JUNK, usize); +} +#ifdef JEMALLOC_JET +#undef arena_dalloc_junk_large +#define arena_dalloc_junk_large JEMALLOC_N(arena_dalloc_junk_large) +arena_dalloc_junk_large_t *arena_dalloc_junk_large = + JEMALLOC_N(n_arena_dalloc_junk_large); +#endif + +static void +arena_dalloc_large_locked_impl(tsdn_t *tsdn, arena_t *arena, + arena_chunk_t *chunk, void *ptr, bool junked) +{ + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + arena_chunk_map_misc_t *miscelm = arena_miscelm_get_mutable(chunk, + pageind); + arena_run_t *run = &miscelm->run; + + if (config_fill || config_stats) { + size_t usize = arena_mapbits_large_size_get(chunk, pageind) - + large_pad; + + if (!junked) + arena_dalloc_junk_large(ptr, usize); + if (config_stats) { + szind_t index = size2index(usize) - NBINS; + + arena->stats.ndalloc_large++; + arena->stats.allocated_large -= usize; + arena->stats.lstats[index].ndalloc++; + arena->stats.lstats[index].curruns--; + } + } + + arena_run_dalloc(tsdn, arena, run, true, false, false); +} + +void +arena_dalloc_large_junked_locked(tsdn_t *tsdn, arena_t *arena, + arena_chunk_t *chunk, void *ptr) +{ + + arena_dalloc_large_locked_impl(tsdn, arena, chunk, ptr, true); +} + +void +arena_dalloc_large(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, + void *ptr) +{ + + malloc_mutex_lock(tsdn, &arena->lock); + arena_dalloc_large_locked_impl(tsdn, arena, chunk, ptr, false); + malloc_mutex_unlock(tsdn, &arena->lock); + arena_decay_tick(tsdn, arena); +} + +static void +arena_ralloc_large_shrink(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, + void *ptr, size_t oldsize, size_t size) +{ + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + arena_chunk_map_misc_t *miscelm = arena_miscelm_get_mutable(chunk, + pageind); + arena_run_t *run = &miscelm->run; + + assert(size < oldsize); + + /* + * Shrink the run, and make trailing pages available for other + * allocations. + */ + malloc_mutex_lock(tsdn, &arena->lock); + arena_run_trim_tail(tsdn, arena, chunk, run, oldsize + large_pad, size + + large_pad, true); + if (config_stats) { + szind_t oldindex = size2index(oldsize) - NBINS; + szind_t index = size2index(size) - NBINS; + + arena->stats.ndalloc_large++; + arena->stats.allocated_large -= oldsize; + arena->stats.lstats[oldindex].ndalloc++; + arena->stats.lstats[oldindex].curruns--; + + arena->stats.nmalloc_large++; + arena->stats.nrequests_large++; + arena->stats.allocated_large += size; + arena->stats.lstats[index].nmalloc++; + arena->stats.lstats[index].nrequests++; + arena->stats.lstats[index].curruns++; + } + malloc_mutex_unlock(tsdn, &arena->lock); +} + +static bool +arena_ralloc_large_grow(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk, + void *ptr, size_t oldsize, size_t usize_min, size_t usize_max, bool zero) +{ + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + size_t npages = (oldsize + large_pad) >> LG_PAGE; + size_t followsize; + + assert(oldsize == arena_mapbits_large_size_get(chunk, pageind) - + large_pad); + + /* Try to extend the run. */ + malloc_mutex_lock(tsdn, &arena->lock); + if (pageind+npages >= chunk_npages || arena_mapbits_allocated_get(chunk, + pageind+npages) != 0) + goto label_fail; + followsize = arena_mapbits_unallocated_size_get(chunk, pageind+npages); + if (oldsize + followsize >= usize_min) { + /* + * The next run is available and sufficiently large. Split the + * following run, then merge the first part with the existing + * allocation. + */ + arena_run_t *run; + size_t usize, splitsize, size, flag_dirty, flag_unzeroed_mask; + + usize = usize_max; + while (oldsize + followsize < usize) + usize = index2size(size2index(usize)-1); + assert(usize >= usize_min); + assert(usize >= oldsize); + splitsize = usize - oldsize; + if (splitsize == 0) + goto label_fail; + + run = &arena_miscelm_get_mutable(chunk, pageind+npages)->run; + if (arena_run_split_large(arena, run, splitsize, zero)) + goto label_fail; + + if (config_cache_oblivious && zero) { + /* + * Zero the trailing bytes of the original allocation's + * last page, since they are in an indeterminate state. + * There will always be trailing bytes, because ptr's + * offset from the beginning of the run is a multiple of + * CACHELINE in [0 .. PAGE). + */ + void *zbase = (void *)((uintptr_t)ptr + oldsize); + void *zpast = PAGE_ADDR2BASE((void *)((uintptr_t)zbase + + PAGE)); + size_t nzero = (uintptr_t)zpast - (uintptr_t)zbase; + assert(nzero > 0); + memset(zbase, 0, nzero); + } + + size = oldsize + splitsize; + npages = (size + large_pad) >> LG_PAGE; + + /* + * Mark the extended run as dirty if either portion of the run + * was dirty before allocation. This is rather pedantic, + * because there's not actually any sequence of events that + * could cause the resulting run to be passed to + * arena_run_dalloc() with the dirty argument set to false + * (which is when dirty flag consistency would really matter). + */ + flag_dirty = arena_mapbits_dirty_get(chunk, pageind) | + arena_mapbits_dirty_get(chunk, pageind+npages-1); + flag_unzeroed_mask = flag_dirty == 0 ? CHUNK_MAP_UNZEROED : 0; + arena_mapbits_large_set(chunk, pageind, size + large_pad, + flag_dirty | (flag_unzeroed_mask & + arena_mapbits_unzeroed_get(chunk, pageind))); + arena_mapbits_large_set(chunk, pageind+npages-1, 0, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, + pageind+npages-1))); + + if (config_stats) { + szind_t oldindex = size2index(oldsize) - NBINS; + szind_t index = size2index(size) - NBINS; + + arena->stats.ndalloc_large++; + arena->stats.allocated_large -= oldsize; + arena->stats.lstats[oldindex].ndalloc++; + arena->stats.lstats[oldindex].curruns--; + + arena->stats.nmalloc_large++; + arena->stats.nrequests_large++; + arena->stats.allocated_large += size; + arena->stats.lstats[index].nmalloc++; + arena->stats.lstats[index].nrequests++; + arena->stats.lstats[index].curruns++; + } + malloc_mutex_unlock(tsdn, &arena->lock); + return (false); + } +label_fail: + malloc_mutex_unlock(tsdn, &arena->lock); + return (true); +} + +#ifdef JEMALLOC_JET +#undef arena_ralloc_junk_large +#define arena_ralloc_junk_large JEMALLOC_N(n_arena_ralloc_junk_large) +#endif +static void +arena_ralloc_junk_large(void *ptr, size_t old_usize, size_t usize) +{ + + if (config_fill && unlikely(opt_junk_free)) { + memset((void *)((uintptr_t)ptr + usize), JEMALLOC_FREE_JUNK, + old_usize - usize); + } +} +#ifdef JEMALLOC_JET +#undef arena_ralloc_junk_large +#define arena_ralloc_junk_large JEMALLOC_N(arena_ralloc_junk_large) +arena_ralloc_junk_large_t *arena_ralloc_junk_large = + JEMALLOC_N(n_arena_ralloc_junk_large); +#endif + +/* + * Try to resize a large allocation, in order to avoid copying. This will + * always fail if growing an object, and the following run is already in use. + */ +static bool +arena_ralloc_large(tsdn_t *tsdn, void *ptr, size_t oldsize, size_t usize_min, + size_t usize_max, bool zero) +{ + arena_chunk_t *chunk; + arena_t *arena; + + if (oldsize == usize_max) { + /* Current size class is compatible and maximal. */ + return (false); + } + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + arena = extent_node_arena_get(&chunk->node); + + if (oldsize < usize_max) { + bool ret = arena_ralloc_large_grow(tsdn, arena, chunk, ptr, + oldsize, usize_min, usize_max, zero); + if (config_fill && !ret && !zero) { + if (unlikely(opt_junk_alloc)) { + memset((void *)((uintptr_t)ptr + oldsize), + JEMALLOC_ALLOC_JUNK, + isalloc(tsdn, ptr, config_prof) - oldsize); + } else if (unlikely(opt_zero)) { + memset((void *)((uintptr_t)ptr + oldsize), 0, + isalloc(tsdn, ptr, config_prof) - oldsize); + } + } + return (ret); + } + + assert(oldsize > usize_max); + /* Fill before shrinking in order avoid a race. */ + arena_ralloc_junk_large(ptr, oldsize, usize_max); + arena_ralloc_large_shrink(tsdn, arena, chunk, ptr, oldsize, usize_max); + return (false); +} + +bool +arena_ralloc_no_move(tsdn_t *tsdn, void *ptr, size_t oldsize, size_t size, + size_t extra, bool zero) +{ + size_t usize_min, usize_max; + + /* Calls with non-zero extra had to clamp extra. */ + assert(extra == 0 || size + extra <= HUGE_MAXCLASS); + + if (unlikely(size > HUGE_MAXCLASS)) + return (true); + + usize_min = s2u(size); + usize_max = s2u(size + extra); + if (likely(oldsize <= large_maxclass && usize_min <= large_maxclass)) { + arena_chunk_t *chunk; + + /* + * Avoid moving the allocation if the size class can be left the + * same. + */ + if (oldsize <= SMALL_MAXCLASS) { + assert(arena_bin_info[size2index(oldsize)].reg_size == + oldsize); + if ((usize_max > SMALL_MAXCLASS || + size2index(usize_max) != size2index(oldsize)) && + (size > oldsize || usize_max < oldsize)) + return (true); + } else { + if (usize_max <= SMALL_MAXCLASS) + return (true); + if (arena_ralloc_large(tsdn, ptr, oldsize, usize_min, + usize_max, zero)) + return (true); + } + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + arena_decay_tick(tsdn, extent_node_arena_get(&chunk->node)); + return (false); + } else { + return (huge_ralloc_no_move(tsdn, ptr, oldsize, usize_min, + usize_max, zero)); + } +} + +static void * +arena_ralloc_move_helper(tsdn_t *tsdn, arena_t *arena, size_t usize, + size_t alignment, bool zero, tcache_t *tcache) +{ + + if (alignment == 0) + return (arena_malloc(tsdn, arena, usize, size2index(usize), + zero, tcache, true)); + usize = sa2u(usize, alignment); + if (unlikely(usize == 0 || usize > HUGE_MAXCLASS)) + return (NULL); + return (ipalloct(tsdn, usize, alignment, zero, tcache, arena)); +} + +void * +arena_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, size_t size, + size_t alignment, bool zero, tcache_t *tcache) +{ + void *ret; + size_t usize; + + usize = s2u(size); + if (unlikely(usize == 0 || size > HUGE_MAXCLASS)) + return (NULL); + + if (likely(usize <= large_maxclass)) { + size_t copysize; + + /* Try to avoid moving the allocation. */ + if (!arena_ralloc_no_move(tsd_tsdn(tsd), ptr, oldsize, usize, 0, + zero)) + return (ptr); + + /* + * size and oldsize are different enough that we need to move + * the object. In that case, fall back to allocating new space + * and copying. + */ + ret = arena_ralloc_move_helper(tsd_tsdn(tsd), arena, usize, + alignment, zero, tcache); + if (ret == NULL) + return (NULL); + + /* + * Junk/zero-filling were already done by + * ipalloc()/arena_malloc(). + */ + + copysize = (usize < oldsize) ? usize : oldsize; + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, copysize); + memcpy(ret, ptr, copysize); + isqalloc(tsd, ptr, oldsize, tcache, true); + } else { + ret = huge_ralloc(tsd, arena, ptr, oldsize, usize, alignment, + zero, tcache); + } + return (ret); +} + +dss_prec_t +arena_dss_prec_get(tsdn_t *tsdn, arena_t *arena) +{ + dss_prec_t ret; + + malloc_mutex_lock(tsdn, &arena->lock); + ret = arena->dss_prec; + malloc_mutex_unlock(tsdn, &arena->lock); + return (ret); +} + +bool +arena_dss_prec_set(tsdn_t *tsdn, arena_t *arena, dss_prec_t dss_prec) +{ + + if (!have_dss) + return (dss_prec != dss_prec_disabled); + malloc_mutex_lock(tsdn, &arena->lock); + arena->dss_prec = dss_prec; + malloc_mutex_unlock(tsdn, &arena->lock); + return (false); +} + +ssize_t +arena_lg_dirty_mult_default_get(void) +{ + + return ((ssize_t)atomic_read_z((size_t *)&lg_dirty_mult_default)); +} + +bool +arena_lg_dirty_mult_default_set(ssize_t lg_dirty_mult) +{ + + if (opt_purge != purge_mode_ratio) + return (true); + if (!arena_lg_dirty_mult_valid(lg_dirty_mult)) + return (true); + atomic_write_z((size_t *)&lg_dirty_mult_default, (size_t)lg_dirty_mult); + return (false); +} + +ssize_t +arena_decay_time_default_get(void) +{ + + return ((ssize_t)atomic_read_z((size_t *)&decay_time_default)); +} + +bool +arena_decay_time_default_set(ssize_t decay_time) +{ + + if (opt_purge != purge_mode_decay) + return (true); + if (!arena_decay_time_valid(decay_time)) + return (true); + atomic_write_z((size_t *)&decay_time_default, (size_t)decay_time); + return (false); +} + +static void +arena_basic_stats_merge_locked(arena_t *arena, unsigned *nthreads, + const char **dss, ssize_t *lg_dirty_mult, ssize_t *decay_time, + size_t *nactive, size_t *ndirty) +{ + + *nthreads += arena_nthreads_get(arena, false); + *dss = dss_prec_names[arena->dss_prec]; + *lg_dirty_mult = arena->lg_dirty_mult; + *decay_time = arena->decay_time; + *nactive += arena->nactive; + *ndirty += arena->ndirty; +} + +void +arena_basic_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads, + const char **dss, ssize_t *lg_dirty_mult, ssize_t *decay_time, + size_t *nactive, size_t *ndirty) +{ + + malloc_mutex_lock(tsdn, &arena->lock); + arena_basic_stats_merge_locked(arena, nthreads, dss, lg_dirty_mult, + decay_time, nactive, ndirty); + malloc_mutex_unlock(tsdn, &arena->lock); +} + +void +arena_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads, + const char **dss, ssize_t *lg_dirty_mult, ssize_t *decay_time, + size_t *nactive, size_t *ndirty, arena_stats_t *astats, + malloc_bin_stats_t *bstats, malloc_large_stats_t *lstats, + malloc_huge_stats_t *hstats) +{ + unsigned i; + + cassert(config_stats); + + malloc_mutex_lock(tsdn, &arena->lock); + arena_basic_stats_merge_locked(arena, nthreads, dss, lg_dirty_mult, + decay_time, nactive, ndirty); + + astats->mapped += arena->stats.mapped; + astats->retained += arena->stats.retained; + astats->npurge += arena->stats.npurge; + astats->nmadvise += arena->stats.nmadvise; + astats->purged += arena->stats.purged; + astats->metadata_mapped += arena->stats.metadata_mapped; + astats->metadata_allocated += arena_metadata_allocated_get(arena); + astats->allocated_large += arena->stats.allocated_large; + astats->nmalloc_large += arena->stats.nmalloc_large; + astats->ndalloc_large += arena->stats.ndalloc_large; + astats->nrequests_large += arena->stats.nrequests_large; + astats->allocated_huge += arena->stats.allocated_huge; + astats->nmalloc_huge += arena->stats.nmalloc_huge; + astats->ndalloc_huge += arena->stats.ndalloc_huge; + + for (i = 0; i < nlclasses; i++) { + lstats[i].nmalloc += arena->stats.lstats[i].nmalloc; + lstats[i].ndalloc += arena->stats.lstats[i].ndalloc; + lstats[i].nrequests += arena->stats.lstats[i].nrequests; + lstats[i].curruns += arena->stats.lstats[i].curruns; + } + + for (i = 0; i < nhclasses; i++) { + hstats[i].nmalloc += arena->stats.hstats[i].nmalloc; + hstats[i].ndalloc += arena->stats.hstats[i].ndalloc; + hstats[i].curhchunks += arena->stats.hstats[i].curhchunks; + } + malloc_mutex_unlock(tsdn, &arena->lock); + + for (i = 0; i < NBINS; i++) { + arena_bin_t *bin = &arena->bins[i]; + + malloc_mutex_lock(tsdn, &bin->lock); + bstats[i].nmalloc += bin->stats.nmalloc; + bstats[i].ndalloc += bin->stats.ndalloc; + bstats[i].nrequests += bin->stats.nrequests; + bstats[i].curregs += bin->stats.curregs; + if (config_tcache) { + bstats[i].nfills += bin->stats.nfills; + bstats[i].nflushes += bin->stats.nflushes; + } + bstats[i].nruns += bin->stats.nruns; + bstats[i].reruns += bin->stats.reruns; + bstats[i].curruns += bin->stats.curruns; + malloc_mutex_unlock(tsdn, &bin->lock); + } +} + +unsigned +arena_nthreads_get(arena_t *arena, bool internal) +{ + + return (atomic_read_u(&arena->nthreads[internal])); +} + +void +arena_nthreads_inc(arena_t *arena, bool internal) +{ + + atomic_add_u(&arena->nthreads[internal], 1); +} + +void +arena_nthreads_dec(arena_t *arena, bool internal) +{ + + atomic_sub_u(&arena->nthreads[internal], 1); +} + +arena_t * +arena_new(tsdn_t *tsdn, unsigned ind) +{ + arena_t *arena; + size_t arena_size; + unsigned i; + + /* Compute arena size to incorporate sufficient runs_avail elements. */ + arena_size = offsetof(arena_t, runs_avail) + (sizeof(arena_run_heap_t) * + runs_avail_nclasses); + /* + * Allocate arena, arena->lstats, and arena->hstats contiguously, mainly + * because there is no way to clean up if base_alloc() OOMs. + */ + if (config_stats) { + arena = (arena_t *)base_alloc(tsdn, + CACHELINE_CEILING(arena_size) + QUANTUM_CEILING(nlclasses * + sizeof(malloc_large_stats_t) + nhclasses) * + sizeof(malloc_huge_stats_t)); + } else + arena = (arena_t *)base_alloc(tsdn, arena_size); + if (arena == NULL) + return (NULL); + + arena->ind = ind; + arena->nthreads[0] = arena->nthreads[1] = 0; + if (malloc_mutex_init(&arena->lock, "arena", WITNESS_RANK_ARENA)) + return (NULL); + + if (config_stats) { + memset(&arena->stats, 0, sizeof(arena_stats_t)); + arena->stats.lstats = (malloc_large_stats_t *)((uintptr_t)arena + + CACHELINE_CEILING(arena_size)); + memset(arena->stats.lstats, 0, nlclasses * + sizeof(malloc_large_stats_t)); + arena->stats.hstats = (malloc_huge_stats_t *)((uintptr_t)arena + + CACHELINE_CEILING(arena_size) + + QUANTUM_CEILING(nlclasses * sizeof(malloc_large_stats_t))); + memset(arena->stats.hstats, 0, nhclasses * + sizeof(malloc_huge_stats_t)); + if (config_tcache) + ql_new(&arena->tcache_ql); + } + + if (config_prof) + arena->prof_accumbytes = 0; + + if (config_cache_oblivious) { + /* + * A nondeterministic seed based on the address of arena reduces + * the likelihood of lockstep non-uniform cache index + * utilization among identical concurrent processes, but at the + * cost of test repeatability. For debug builds, instead use a + * deterministic seed. + */ + arena->offset_state = config_debug ? ind : + (uint64_t)(uintptr_t)arena; + } + + arena->dss_prec = chunk_dss_prec_get(tsdn); + + ql_new(&arena->achunks); + + arena->spare = NULL; + + arena->lg_dirty_mult = arena_lg_dirty_mult_default_get(); + arena->purging = false; + arena->nactive = 0; + arena->ndirty = 0; + + for(i = 0; i < runs_avail_nclasses; i++) + arena_run_heap_new(&arena->runs_avail[i]); + qr_new(&arena->runs_dirty, rd_link); + qr_new(&arena->chunks_cache, cc_link); + + if (opt_purge == purge_mode_decay) + arena_decay_init(arena, arena_decay_time_default_get()); + + ql_new(&arena->huge); + if (malloc_mutex_init(&arena->huge_mtx, "arena_huge", + WITNESS_RANK_ARENA_HUGE)) + return (NULL); + + extent_tree_szad_new(&arena->chunks_szad_cached); + extent_tree_ad_new(&arena->chunks_ad_cached); + extent_tree_szad_new(&arena->chunks_szad_retained); + extent_tree_ad_new(&arena->chunks_ad_retained); + if (malloc_mutex_init(&arena->chunks_mtx, "arena_chunks", + WITNESS_RANK_ARENA_CHUNKS)) + return (NULL); + ql_new(&arena->node_cache); + if (malloc_mutex_init(&arena->node_cache_mtx, "arena_node_cache", + WITNESS_RANK_ARENA_NODE_CACHE)) + return (NULL); + + arena->chunk_hooks = chunk_hooks_default; + + /* Initialize bins. */ + for (i = 0; i < NBINS; i++) { + arena_bin_t *bin = &arena->bins[i]; + if (malloc_mutex_init(&bin->lock, "arena_bin", + WITNESS_RANK_ARENA_BIN)) + return (NULL); + bin->runcur = NULL; + arena_run_heap_new(&bin->runs); + if (config_stats) + memset(&bin->stats, 0, sizeof(malloc_bin_stats_t)); + } + + return (arena); +} + +/* + * Calculate bin_info->run_size such that it meets the following constraints: + * + * *) bin_info->run_size <= arena_maxrun + * *) bin_info->nregs <= RUN_MAXREGS + * + * bin_info->nregs and bin_info->reg0_offset are also calculated here, since + * these settings are all interdependent. + */ +static void +bin_info_run_size_calc(arena_bin_info_t *bin_info) +{ + size_t pad_size; + size_t try_run_size, perfect_run_size, actual_run_size; + uint32_t try_nregs, perfect_nregs, actual_nregs; + + /* + * Determine redzone size based on minimum alignment and minimum + * redzone size. Add padding to the end of the run if it is needed to + * align the regions. The padding allows each redzone to be half the + * minimum alignment; without the padding, each redzone would have to + * be twice as large in order to maintain alignment. + */ + if (config_fill && unlikely(opt_redzone)) { + size_t align_min = ZU(1) << (ffs_zu(bin_info->reg_size) - 1); + if (align_min <= REDZONE_MINSIZE) { + bin_info->redzone_size = REDZONE_MINSIZE; + pad_size = 0; + } else { + bin_info->redzone_size = align_min >> 1; + pad_size = bin_info->redzone_size; + } + } else { + bin_info->redzone_size = 0; + pad_size = 0; + } + bin_info->reg_interval = bin_info->reg_size + + (bin_info->redzone_size << 1); + + /* + * Compute run size under ideal conditions (no redzones, no limit on run + * size). + */ + try_run_size = PAGE; + try_nregs = (uint32_t)(try_run_size / bin_info->reg_size); + do { + perfect_run_size = try_run_size; + perfect_nregs = try_nregs; + + try_run_size += PAGE; + try_nregs = (uint32_t)(try_run_size / bin_info->reg_size); + } while (perfect_run_size != perfect_nregs * bin_info->reg_size); + assert(perfect_nregs <= RUN_MAXREGS); + + actual_run_size = perfect_run_size; + actual_nregs = (uint32_t)((actual_run_size - pad_size) / + bin_info->reg_interval); + + /* + * Redzones can require enough padding that not even a single region can + * fit within the number of pages that would normally be dedicated to a + * run for this size class. Increase the run size until at least one + * region fits. + */ + while (actual_nregs == 0) { + assert(config_fill && unlikely(opt_redzone)); + + actual_run_size += PAGE; + actual_nregs = (uint32_t)((actual_run_size - pad_size) / + bin_info->reg_interval); + } + + /* + * Make sure that the run will fit within an arena chunk. + */ + while (actual_run_size > arena_maxrun) { + actual_run_size -= PAGE; + actual_nregs = (uint32_t)((actual_run_size - pad_size) / + bin_info->reg_interval); + } + assert(actual_nregs > 0); + assert(actual_run_size == s2u(actual_run_size)); + + /* Copy final settings. */ + bin_info->run_size = actual_run_size; + bin_info->nregs = actual_nregs; + bin_info->reg0_offset = (uint32_t)(actual_run_size - (actual_nregs * + bin_info->reg_interval) - pad_size + bin_info->redzone_size); + + if (actual_run_size > small_maxrun) + small_maxrun = actual_run_size; + + assert(bin_info->reg0_offset - bin_info->redzone_size + (bin_info->nregs + * bin_info->reg_interval) + pad_size == bin_info->run_size); +} + +static void +bin_info_init(void) +{ + arena_bin_info_t *bin_info; + +#define BIN_INFO_INIT_bin_yes(index, size) \ + bin_info = &arena_bin_info[index]; \ + bin_info->reg_size = size; \ + bin_info_run_size_calc(bin_info); \ + bitmap_info_init(&bin_info->bitmap_info, bin_info->nregs); +#define BIN_INFO_INIT_bin_no(index, size) +#define SC(index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup) \ + BIN_INFO_INIT_bin_##bin(index, (ZU(1)<> + LG_PAGE)); + if (small_run_tab == NULL) + return (true); + +#define TAB_INIT_bin_yes(index, size) { \ + arena_bin_info_t *bin_info = &arena_bin_info[index]; \ + small_run_tab[bin_info->run_size >> LG_PAGE] = true; \ + } +#define TAB_INIT_bin_no(index, size) +#define SC(index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup) \ + TAB_INIT_bin_##bin(index, (ZU(1)<> LG_PAGE)); + if (run_quantize_floor_tab == NULL) + return (true); + + run_quantize_ceil_tab = (size_t *)base_alloc(NULL, sizeof(size_t) * + (run_quantize_max >> LG_PAGE)); + if (run_quantize_ceil_tab == NULL) + return (true); + + for (i = 1; i <= run_quantize_max >> LG_PAGE; i++) { + size_t run_size = i << LG_PAGE; + + run_quantize_floor_tab[i-1] = + run_quantize_floor_compute(run_size); + run_quantize_ceil_tab[i-1] = + run_quantize_ceil_compute(run_size); + } + + return (false); +} + +bool +arena_boot(void) +{ + unsigned i; + + arena_lg_dirty_mult_default_set(opt_lg_dirty_mult); + arena_decay_time_default_set(opt_decay_time); + + /* + * Compute the header size such that it is large enough to contain the + * page map. The page map is biased to omit entries for the header + * itself, so some iteration is necessary to compute the map bias. + * + * 1) Compute safe header_size and map_bias values that include enough + * space for an unbiased page map. + * 2) Refine map_bias based on (1) to omit the header pages in the page + * map. The resulting map_bias may be one too small. + * 3) Refine map_bias based on (2). The result will be >= the result + * from (2), and will always be correct. + */ + map_bias = 0; + for (i = 0; i < 3; i++) { + size_t header_size = offsetof(arena_chunk_t, map_bits) + + ((sizeof(arena_chunk_map_bits_t) + + sizeof(arena_chunk_map_misc_t)) * (chunk_npages-map_bias)); + map_bias = (header_size + PAGE_MASK) >> LG_PAGE; + } + assert(map_bias > 0); + + map_misc_offset = offsetof(arena_chunk_t, map_bits) + + sizeof(arena_chunk_map_bits_t) * (chunk_npages-map_bias); + + arena_maxrun = chunksize - (map_bias << LG_PAGE); + assert(arena_maxrun > 0); + large_maxclass = index2size(size2index(chunksize)-1); + if (large_maxclass > arena_maxrun) { + /* + * For small chunk sizes it's possible for there to be fewer + * non-header pages available than are necessary to serve the + * size classes just below chunksize. + */ + large_maxclass = arena_maxrun; + } + assert(large_maxclass > 0); + nlclasses = size2index(large_maxclass) - size2index(SMALL_MAXCLASS); + nhclasses = NSIZES - nlclasses - NBINS; + + bin_info_init(); + if (small_run_size_init()) + return (true); + if (run_quantize_init()) + return (true); + + runs_avail_bias = size2index(PAGE); + runs_avail_nclasses = size2index(run_quantize_max)+1 - runs_avail_bias; + + return (false); +} + +void +arena_prefork0(tsdn_t *tsdn, arena_t *arena) +{ + + malloc_mutex_prefork(tsdn, &arena->lock); +} + +void +arena_prefork1(tsdn_t *tsdn, arena_t *arena) +{ + + malloc_mutex_prefork(tsdn, &arena->chunks_mtx); +} + +void +arena_prefork2(tsdn_t *tsdn, arena_t *arena) +{ + + malloc_mutex_prefork(tsdn, &arena->node_cache_mtx); +} + +void +arena_prefork3(tsdn_t *tsdn, arena_t *arena) +{ + unsigned i; + + for (i = 0; i < NBINS; i++) + malloc_mutex_prefork(tsdn, &arena->bins[i].lock); + malloc_mutex_prefork(tsdn, &arena->huge_mtx); +} + +void +arena_postfork_parent(tsdn_t *tsdn, arena_t *arena) +{ + unsigned i; + + malloc_mutex_postfork_parent(tsdn, &arena->huge_mtx); + for (i = 0; i < NBINS; i++) + malloc_mutex_postfork_parent(tsdn, &arena->bins[i].lock); + malloc_mutex_postfork_parent(tsdn, &arena->node_cache_mtx); + malloc_mutex_postfork_parent(tsdn, &arena->chunks_mtx); + malloc_mutex_postfork_parent(tsdn, &arena->lock); +} + +void +arena_postfork_child(tsdn_t *tsdn, arena_t *arena) +{ + unsigned i; + + malloc_mutex_postfork_child(tsdn, &arena->huge_mtx); + for (i = 0; i < NBINS; i++) + malloc_mutex_postfork_child(tsdn, &arena->bins[i].lock); + malloc_mutex_postfork_child(tsdn, &arena->node_cache_mtx); + malloc_mutex_postfork_child(tsdn, &arena->chunks_mtx); + malloc_mutex_postfork_child(tsdn, &arena->lock); +} diff --git a/contrib/jemalloc/src/atomic.c b/contrib/jemalloc/src/atomic.c new file mode 100644 index 0000000..77ee313 --- /dev/null +++ b/contrib/jemalloc/src/atomic.c @@ -0,0 +1,2 @@ +#define JEMALLOC_ATOMIC_C_ +#include "jemalloc/internal/jemalloc_internal.h" diff --git a/contrib/jemalloc/src/base.c b/contrib/jemalloc/src/base.c new file mode 100644 index 0000000..81b0801 --- /dev/null +++ b/contrib/jemalloc/src/base.c @@ -0,0 +1,177 @@ +#define JEMALLOC_BASE_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +static malloc_mutex_t base_mtx; +static extent_tree_t base_avail_szad; +static extent_node_t *base_nodes; +static size_t base_allocated; +static size_t base_resident; +static size_t base_mapped; + +/******************************************************************************/ + +static extent_node_t * +base_node_try_alloc(tsdn_t *tsdn) +{ + extent_node_t *node; + + malloc_mutex_assert_owner(tsdn, &base_mtx); + + if (base_nodes == NULL) + return (NULL); + node = base_nodes; + base_nodes = *(extent_node_t **)node; + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(node, sizeof(extent_node_t)); + return (node); +} + +static void +base_node_dalloc(tsdn_t *tsdn, extent_node_t *node) +{ + + malloc_mutex_assert_owner(tsdn, &base_mtx); + + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(node, sizeof(extent_node_t)); + *(extent_node_t **)node = base_nodes; + base_nodes = node; +} + +static extent_node_t * +base_chunk_alloc(tsdn_t *tsdn, size_t minsize) +{ + extent_node_t *node; + size_t csize, nsize; + void *addr; + + malloc_mutex_assert_owner(tsdn, &base_mtx); + assert(minsize != 0); + node = base_node_try_alloc(tsdn); + /* Allocate enough space to also carve a node out if necessary. */ + nsize = (node == NULL) ? CACHELINE_CEILING(sizeof(extent_node_t)) : 0; + csize = CHUNK_CEILING(minsize + nsize); + addr = chunk_alloc_base(csize); + if (addr == NULL) { + if (node != NULL) + base_node_dalloc(tsdn, node); + return (NULL); + } + base_mapped += csize; + if (node == NULL) { + node = (extent_node_t *)addr; + addr = (void *)((uintptr_t)addr + nsize); + csize -= nsize; + if (config_stats) { + base_allocated += nsize; + base_resident += PAGE_CEILING(nsize); + } + } + extent_node_init(node, NULL, addr, csize, true, true); + return (node); +} + +/* + * base_alloc() guarantees demand-zeroed memory, in order to make multi-page + * sparse data structures such as radix tree nodes efficient with respect to + * physical memory usage. + */ +void * +base_alloc(tsdn_t *tsdn, size_t size) +{ + void *ret; + size_t csize, usize; + extent_node_t *node; + extent_node_t key; + + /* + * Round size up to nearest multiple of the cacheline size, so that + * there is no chance of false cache line sharing. + */ + csize = CACHELINE_CEILING(size); + + usize = s2u(csize); + extent_node_init(&key, NULL, NULL, usize, false, false); + malloc_mutex_lock(tsdn, &base_mtx); + node = extent_tree_szad_nsearch(&base_avail_szad, &key); + if (node != NULL) { + /* Use existing space. */ + extent_tree_szad_remove(&base_avail_szad, node); + } else { + /* Try to allocate more space. */ + node = base_chunk_alloc(tsdn, csize); + } + if (node == NULL) { + ret = NULL; + goto label_return; + } + + ret = extent_node_addr_get(node); + if (extent_node_size_get(node) > csize) { + extent_node_addr_set(node, (void *)((uintptr_t)ret + csize)); + extent_node_size_set(node, extent_node_size_get(node) - csize); + extent_tree_szad_insert(&base_avail_szad, node); + } else + base_node_dalloc(tsdn, node); + if (config_stats) { + base_allocated += csize; + /* + * Add one PAGE to base_resident for every page boundary that is + * crossed by the new allocation. + */ + base_resident += PAGE_CEILING((uintptr_t)ret + csize) - + PAGE_CEILING((uintptr_t)ret); + } + JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ret, csize); +label_return: + malloc_mutex_unlock(tsdn, &base_mtx); + return (ret); +} + +void +base_stats_get(tsdn_t *tsdn, size_t *allocated, size_t *resident, + size_t *mapped) +{ + + malloc_mutex_lock(tsdn, &base_mtx); + assert(base_allocated <= base_resident); + assert(base_resident <= base_mapped); + *allocated = base_allocated; + *resident = base_resident; + *mapped = base_mapped; + malloc_mutex_unlock(tsdn, &base_mtx); +} + +bool +base_boot(void) +{ + + if (malloc_mutex_init(&base_mtx, "base", WITNESS_RANK_BASE)) + return (true); + extent_tree_szad_new(&base_avail_szad); + base_nodes = NULL; + + return (false); +} + +void +base_prefork(tsdn_t *tsdn) +{ + + malloc_mutex_prefork(tsdn, &base_mtx); +} + +void +base_postfork_parent(tsdn_t *tsdn) +{ + + malloc_mutex_postfork_parent(tsdn, &base_mtx); +} + +void +base_postfork_child(tsdn_t *tsdn) +{ + + malloc_mutex_postfork_child(tsdn, &base_mtx); +} diff --git a/contrib/jemalloc/src/bitmap.c b/contrib/jemalloc/src/bitmap.c new file mode 100644 index 0000000..ac0f3b3 --- /dev/null +++ b/contrib/jemalloc/src/bitmap.c @@ -0,0 +1,111 @@ +#define JEMALLOC_BITMAP_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ + +#ifdef USE_TREE + +void +bitmap_info_init(bitmap_info_t *binfo, size_t nbits) +{ + unsigned i; + size_t group_count; + + assert(nbits > 0); + assert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS)); + + /* + * Compute the number of groups necessary to store nbits bits, and + * progressively work upward through the levels until reaching a level + * that requires only one group. + */ + binfo->levels[0].group_offset = 0; + group_count = BITMAP_BITS2GROUPS(nbits); + for (i = 1; group_count > 1; i++) { + assert(i < BITMAP_MAX_LEVELS); + binfo->levels[i].group_offset = binfo->levels[i-1].group_offset + + group_count; + group_count = BITMAP_BITS2GROUPS(group_count); + } + binfo->levels[i].group_offset = binfo->levels[i-1].group_offset + + group_count; + assert(binfo->levels[i].group_offset <= BITMAP_GROUPS_MAX); + binfo->nlevels = i; + binfo->nbits = nbits; +} + +static size_t +bitmap_info_ngroups(const bitmap_info_t *binfo) +{ + + return (binfo->levels[binfo->nlevels].group_offset); +} + +void +bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo) +{ + size_t extra; + unsigned i; + + /* + * Bits are actually inverted with regard to the external bitmap + * interface, so the bitmap starts out with all 1 bits, except for + * trailing unused bits (if any). Note that each group uses bit 0 to + * correspond to the first logical bit in the group, so extra bits + * are the most significant bits of the last group. + */ + memset(bitmap, 0xffU, bitmap_size(binfo)); + extra = (BITMAP_GROUP_NBITS - (binfo->nbits & BITMAP_GROUP_NBITS_MASK)) + & BITMAP_GROUP_NBITS_MASK; + if (extra != 0) + bitmap[binfo->levels[1].group_offset - 1] >>= extra; + for (i = 1; i < binfo->nlevels; i++) { + size_t group_count = binfo->levels[i].group_offset - + binfo->levels[i-1].group_offset; + extra = (BITMAP_GROUP_NBITS - (group_count & + BITMAP_GROUP_NBITS_MASK)) & BITMAP_GROUP_NBITS_MASK; + if (extra != 0) + bitmap[binfo->levels[i+1].group_offset - 1] >>= extra; + } +} + +#else /* USE_TREE */ + +void +bitmap_info_init(bitmap_info_t *binfo, size_t nbits) +{ + + assert(nbits > 0); + assert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS)); + + binfo->ngroups = BITMAP_BITS2GROUPS(nbits); + binfo->nbits = nbits; +} + +static size_t +bitmap_info_ngroups(const bitmap_info_t *binfo) +{ + + return (binfo->ngroups); +} + +void +bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo) +{ + size_t extra; + + memset(bitmap, 0xffU, bitmap_size(binfo)); + extra = (BITMAP_GROUP_NBITS - (binfo->nbits & BITMAP_GROUP_NBITS_MASK)) + & BITMAP_GROUP_NBITS_MASK; + if (extra != 0) + bitmap[binfo->ngroups - 1] >>= extra; +} + +#endif /* USE_TREE */ + +size_t +bitmap_size(const bitmap_info_t *binfo) +{ + + return (bitmap_info_ngroups(binfo) << LG_SIZEOF_BITMAP); +} diff --git a/contrib/jemalloc/src/chunk.c b/contrib/jemalloc/src/chunk.c new file mode 100644 index 0000000..f292c98 --- /dev/null +++ b/contrib/jemalloc/src/chunk.c @@ -0,0 +1,812 @@ +#define JEMALLOC_CHUNK_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +const char *opt_dss = DSS_DEFAULT; +size_t opt_lg_chunk = 0; + +/* Used exclusively for gdump triggering. */ +static size_t curchunks; +static size_t highchunks; + +rtree_t chunks_rtree; + +/* Various chunk-related settings. */ +size_t chunksize; +size_t chunksize_mask; /* (chunksize - 1). */ +size_t chunk_npages; + +static void *chunk_alloc_default(void *new_addr, size_t size, + size_t alignment, bool *zero, bool *commit, unsigned arena_ind); +static bool chunk_dalloc_default(void *chunk, size_t size, bool committed, + unsigned arena_ind); +static bool chunk_commit_default(void *chunk, size_t size, size_t offset, + size_t length, unsigned arena_ind); +static bool chunk_decommit_default(void *chunk, size_t size, size_t offset, + size_t length, unsigned arena_ind); +static bool chunk_purge_default(void *chunk, size_t size, size_t offset, + size_t length, unsigned arena_ind); +static bool chunk_split_default(void *chunk, size_t size, size_t size_a, + size_t size_b, bool committed, unsigned arena_ind); +static bool chunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, + size_t size_b, bool committed, unsigned arena_ind); + +const chunk_hooks_t chunk_hooks_default = { + chunk_alloc_default, + chunk_dalloc_default, + chunk_commit_default, + chunk_decommit_default, + chunk_purge_default, + chunk_split_default, + chunk_merge_default +}; + +/******************************************************************************/ +/* + * Function prototypes for static functions that are referenced prior to + * definition. + */ + +static void chunk_record(tsdn_t *tsdn, arena_t *arena, + chunk_hooks_t *chunk_hooks, extent_tree_t *chunks_szad, + extent_tree_t *chunks_ad, bool cache, void *chunk, size_t size, bool zeroed, + bool committed); + +/******************************************************************************/ + +static chunk_hooks_t +chunk_hooks_get_locked(arena_t *arena) +{ + + return (arena->chunk_hooks); +} + +chunk_hooks_t +chunk_hooks_get(tsdn_t *tsdn, arena_t *arena) +{ + chunk_hooks_t chunk_hooks; + + malloc_mutex_lock(tsdn, &arena->chunks_mtx); + chunk_hooks = chunk_hooks_get_locked(arena); + malloc_mutex_unlock(tsdn, &arena->chunks_mtx); + + return (chunk_hooks); +} + +chunk_hooks_t +chunk_hooks_set(tsdn_t *tsdn, arena_t *arena, const chunk_hooks_t *chunk_hooks) +{ + chunk_hooks_t old_chunk_hooks; + + malloc_mutex_lock(tsdn, &arena->chunks_mtx); + old_chunk_hooks = arena->chunk_hooks; + /* + * Copy each field atomically so that it is impossible for readers to + * see partially updated pointers. There are places where readers only + * need one hook function pointer (therefore no need to copy the + * entirety of arena->chunk_hooks), and stale reads do not affect + * correctness, so they perform unlocked reads. + */ +#define ATOMIC_COPY_HOOK(n) do { \ + union { \ + chunk_##n##_t **n; \ + void **v; \ + } u; \ + u.n = &arena->chunk_hooks.n; \ + atomic_write_p(u.v, chunk_hooks->n); \ +} while (0) + ATOMIC_COPY_HOOK(alloc); + ATOMIC_COPY_HOOK(dalloc); + ATOMIC_COPY_HOOK(commit); + ATOMIC_COPY_HOOK(decommit); + ATOMIC_COPY_HOOK(purge); + ATOMIC_COPY_HOOK(split); + ATOMIC_COPY_HOOK(merge); +#undef ATOMIC_COPY_HOOK + malloc_mutex_unlock(tsdn, &arena->chunks_mtx); + + return (old_chunk_hooks); +} + +static void +chunk_hooks_assure_initialized_impl(tsdn_t *tsdn, arena_t *arena, + chunk_hooks_t *chunk_hooks, bool locked) +{ + static const chunk_hooks_t uninitialized_hooks = + CHUNK_HOOKS_INITIALIZER; + + if (memcmp(chunk_hooks, &uninitialized_hooks, sizeof(chunk_hooks_t)) == + 0) { + *chunk_hooks = locked ? chunk_hooks_get_locked(arena) : + chunk_hooks_get(tsdn, arena); + } +} + +static void +chunk_hooks_assure_initialized_locked(tsdn_t *tsdn, arena_t *arena, + chunk_hooks_t *chunk_hooks) +{ + + chunk_hooks_assure_initialized_impl(tsdn, arena, chunk_hooks, true); +} + +static void +chunk_hooks_assure_initialized(tsdn_t *tsdn, arena_t *arena, + chunk_hooks_t *chunk_hooks) +{ + + chunk_hooks_assure_initialized_impl(tsdn, arena, chunk_hooks, false); +} + +bool +chunk_register(tsdn_t *tsdn, const void *chunk, const extent_node_t *node) +{ + + assert(extent_node_addr_get(node) == chunk); + + if (rtree_set(&chunks_rtree, (uintptr_t)chunk, node)) + return (true); + if (config_prof && opt_prof) { + size_t size = extent_node_size_get(node); + size_t nadd = (size == 0) ? 1 : size / chunksize; + size_t cur = atomic_add_z(&curchunks, nadd); + size_t high = atomic_read_z(&highchunks); + while (cur > high && atomic_cas_z(&highchunks, high, cur)) { + /* + * Don't refresh cur, because it may have decreased + * since this thread lost the highchunks update race. + */ + high = atomic_read_z(&highchunks); + } + if (cur > high && prof_gdump_get_unlocked()) + prof_gdump(tsdn); + } + + return (false); +} + +void +chunk_deregister(const void *chunk, const extent_node_t *node) +{ + bool err; + + err = rtree_set(&chunks_rtree, (uintptr_t)chunk, NULL); + assert(!err); + if (config_prof && opt_prof) { + size_t size = extent_node_size_get(node); + size_t nsub = (size == 0) ? 1 : size / chunksize; + assert(atomic_read_z(&curchunks) >= nsub); + atomic_sub_z(&curchunks, nsub); + } +} + +/* + * Do first-best-fit chunk selection, i.e. select the lowest chunk that best + * fits. + */ +static extent_node_t * +chunk_first_best_fit(arena_t *arena, extent_tree_t *chunks_szad, + extent_tree_t *chunks_ad, size_t size) +{ + extent_node_t key; + + assert(size == CHUNK_CEILING(size)); + + extent_node_init(&key, arena, NULL, size, false, false); + return (extent_tree_szad_nsearch(chunks_szad, &key)); +} + +static void * +chunk_recycle(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, + extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, bool cache, + void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit, + bool dalloc_node) +{ + void *ret; + extent_node_t *node; + size_t alloc_size, leadsize, trailsize; + bool zeroed, committed; + + assert(new_addr == NULL || alignment == chunksize); + /* + * Cached chunks use the node linkage embedded in their headers, in + * which case dalloc_node is true, and new_addr is non-NULL because + * we're operating on a specific chunk. + */ + assert(dalloc_node || new_addr != NULL); + + alloc_size = CHUNK_CEILING(s2u(size + alignment - chunksize)); + /* Beware size_t wrap-around. */ + if (alloc_size < size) + return (NULL); + malloc_mutex_lock(tsdn, &arena->chunks_mtx); + chunk_hooks_assure_initialized_locked(tsdn, arena, chunk_hooks); + if (new_addr != NULL) { + extent_node_t key; + extent_node_init(&key, arena, new_addr, alloc_size, false, + false); + node = extent_tree_ad_search(chunks_ad, &key); + } else { + node = chunk_first_best_fit(arena, chunks_szad, chunks_ad, + alloc_size); + } + if (node == NULL || (new_addr != NULL && extent_node_size_get(node) < + size)) { + malloc_mutex_unlock(tsdn, &arena->chunks_mtx); + return (NULL); + } + leadsize = ALIGNMENT_CEILING((uintptr_t)extent_node_addr_get(node), + alignment) - (uintptr_t)extent_node_addr_get(node); + assert(new_addr == NULL || leadsize == 0); + assert(extent_node_size_get(node) >= leadsize + size); + trailsize = extent_node_size_get(node) - leadsize - size; + ret = (void *)((uintptr_t)extent_node_addr_get(node) + leadsize); + zeroed = extent_node_zeroed_get(node); + if (zeroed) + *zero = true; + committed = extent_node_committed_get(node); + if (committed) + *commit = true; + /* Split the lead. */ + if (leadsize != 0 && + chunk_hooks->split(extent_node_addr_get(node), + extent_node_size_get(node), leadsize, size, false, arena->ind)) { + malloc_mutex_unlock(tsdn, &arena->chunks_mtx); + return (NULL); + } + /* Remove node from the tree. */ + extent_tree_szad_remove(chunks_szad, node); + extent_tree_ad_remove(chunks_ad, node); + arena_chunk_cache_maybe_remove(arena, node, cache); + if (leadsize != 0) { + /* Insert the leading space as a smaller chunk. */ + extent_node_size_set(node, leadsize); + extent_tree_szad_insert(chunks_szad, node); + extent_tree_ad_insert(chunks_ad, node); + arena_chunk_cache_maybe_insert(arena, node, cache); + node = NULL; + } + if (trailsize != 0) { + /* Split the trail. */ + if (chunk_hooks->split(ret, size + trailsize, size, + trailsize, false, arena->ind)) { + if (dalloc_node && node != NULL) + arena_node_dalloc(tsdn, arena, node); + malloc_mutex_unlock(tsdn, &arena->chunks_mtx); + chunk_record(tsdn, arena, chunk_hooks, chunks_szad, + chunks_ad, cache, ret, size + trailsize, zeroed, + committed); + return (NULL); + } + /* Insert the trailing space as a smaller chunk. */ + if (node == NULL) { + node = arena_node_alloc(tsdn, arena); + if (node == NULL) { + malloc_mutex_unlock(tsdn, &arena->chunks_mtx); + chunk_record(tsdn, arena, chunk_hooks, + chunks_szad, chunks_ad, cache, ret, size + + trailsize, zeroed, committed); + return (NULL); + } + } + extent_node_init(node, arena, (void *)((uintptr_t)(ret) + size), + trailsize, zeroed, committed); + extent_tree_szad_insert(chunks_szad, node); + extent_tree_ad_insert(chunks_ad, node); + arena_chunk_cache_maybe_insert(arena, node, cache); + node = NULL; + } + if (!committed && chunk_hooks->commit(ret, size, 0, size, arena->ind)) { + malloc_mutex_unlock(tsdn, &arena->chunks_mtx); + chunk_record(tsdn, arena, chunk_hooks, chunks_szad, chunks_ad, + cache, ret, size, zeroed, committed); + return (NULL); + } + malloc_mutex_unlock(tsdn, &arena->chunks_mtx); + + assert(dalloc_node || node != NULL); + if (dalloc_node && node != NULL) + arena_node_dalloc(tsdn, arena, node); + if (*zero) { + if (!zeroed) + memset(ret, 0, size); + else if (config_debug) { + size_t i; + size_t *p = (size_t *)(uintptr_t)ret; + + JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ret, size); + for (i = 0; i < size / sizeof(size_t); i++) + assert(p[i] == 0); + } + } + return (ret); +} + +/* + * If the caller specifies (!*zero), it is still possible to receive zeroed + * memory, in which case *zero is toggled to true. arena_chunk_alloc() takes + * advantage of this to avoid demanding zeroed chunks, but taking advantage of + * them if they are returned. + */ +static void * +chunk_alloc_core(tsdn_t *tsdn, arena_t *arena, void *new_addr, size_t size, + size_t alignment, bool *zero, bool *commit, dss_prec_t dss_prec) +{ + void *ret; + + assert(size != 0); + assert((size & chunksize_mask) == 0); + assert(alignment != 0); + assert((alignment & chunksize_mask) == 0); + + /* "primary" dss. */ + if (have_dss && dss_prec == dss_prec_primary && (ret = + chunk_alloc_dss(tsdn, arena, new_addr, size, alignment, zero, + commit)) != NULL) + return (ret); + /* mmap. */ + if ((ret = chunk_alloc_mmap(new_addr, size, alignment, zero, commit)) != + NULL) + return (ret); + /* "secondary" dss. */ + if (have_dss && dss_prec == dss_prec_secondary && (ret = + chunk_alloc_dss(tsdn, arena, new_addr, size, alignment, zero, + commit)) != NULL) + return (ret); + + /* All strategies for allocation failed. */ + return (NULL); +} + +void * +chunk_alloc_base(size_t size) +{ + void *ret; + bool zero, commit; + + /* + * Directly call chunk_alloc_mmap() rather than chunk_alloc_core() + * because it's critical that chunk_alloc_base() return untouched + * demand-zeroed virtual memory. + */ + zero = true; + commit = true; + ret = chunk_alloc_mmap(NULL, size, chunksize, &zero, &commit); + if (ret == NULL) + return (NULL); + if (config_valgrind) + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size); + + return (ret); +} + +void * +chunk_alloc_cache(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, + void *new_addr, size_t size, size_t alignment, bool *zero, bool dalloc_node) +{ + void *ret; + bool commit; + + assert(size != 0); + assert((size & chunksize_mask) == 0); + assert(alignment != 0); + assert((alignment & chunksize_mask) == 0); + + commit = true; + ret = chunk_recycle(tsdn, arena, chunk_hooks, + &arena->chunks_szad_cached, &arena->chunks_ad_cached, true, + new_addr, size, alignment, zero, &commit, dalloc_node); + if (ret == NULL) + return (NULL); + assert(commit); + if (config_valgrind) + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size); + return (ret); +} + +static arena_t * +chunk_arena_get(tsdn_t *tsdn, unsigned arena_ind) +{ + arena_t *arena; + + arena = arena_get(tsdn, arena_ind, false); + /* + * The arena we're allocating on behalf of must have been initialized + * already. + */ + assert(arena != NULL); + return (arena); +} + +static void * +chunk_alloc_default_impl(tsdn_t *tsdn, arena_t *arena, void *new_addr, + size_t size, size_t alignment, bool *zero, bool *commit) +{ + void *ret; + + ret = chunk_alloc_core(tsdn, arena, new_addr, size, alignment, zero, + commit, arena->dss_prec); + if (ret == NULL) + return (NULL); + if (config_valgrind) + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size); + + return (ret); +} + +static void * +chunk_alloc_default(void *new_addr, size_t size, size_t alignment, bool *zero, + bool *commit, unsigned arena_ind) +{ + tsdn_t *tsdn; + arena_t *arena; + + tsdn = tsdn_fetch(); + arena = chunk_arena_get(tsdn, arena_ind); + + return (chunk_alloc_default_impl(tsdn, arena, new_addr, size, alignment, + zero, commit)); +} + +static void * +chunk_alloc_retained(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, + void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit) +{ + void *ret; + + assert(size != 0); + assert((size & chunksize_mask) == 0); + assert(alignment != 0); + assert((alignment & chunksize_mask) == 0); + + ret = chunk_recycle(tsdn, arena, chunk_hooks, + &arena->chunks_szad_retained, &arena->chunks_ad_retained, false, + new_addr, size, alignment, zero, commit, true); + + if (config_stats && ret != NULL) + arena->stats.retained -= size; + + return (ret); +} + +void * +chunk_alloc_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, + void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit) +{ + void *ret; + + chunk_hooks_assure_initialized(tsdn, arena, chunk_hooks); + + ret = chunk_alloc_retained(tsdn, arena, chunk_hooks, new_addr, size, + alignment, zero, commit); + if (ret == NULL) { + if (chunk_hooks->alloc == chunk_alloc_default) { + /* Call directly to propagate tsdn. */ + ret = chunk_alloc_default_impl(tsdn, arena, new_addr, + size, alignment, zero, commit); + } else { + ret = chunk_hooks->alloc(new_addr, size, alignment, + zero, commit, arena->ind); + } + + if (ret == NULL) + return (NULL); + + if (config_valgrind && chunk_hooks->alloc != + chunk_alloc_default) + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, chunksize); + } + + return (ret); +} + +static void +chunk_record(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, + extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, bool cache, + void *chunk, size_t size, bool zeroed, bool committed) +{ + bool unzeroed; + extent_node_t *node, *prev; + extent_node_t key; + + assert(!cache || !zeroed); + unzeroed = cache || !zeroed; + JEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(chunk, size); + + malloc_mutex_lock(tsdn, &arena->chunks_mtx); + chunk_hooks_assure_initialized_locked(tsdn, arena, chunk_hooks); + extent_node_init(&key, arena, (void *)((uintptr_t)chunk + size), 0, + false, false); + node = extent_tree_ad_nsearch(chunks_ad, &key); + /* Try to coalesce forward. */ + if (node != NULL && extent_node_addr_get(node) == + extent_node_addr_get(&key) && extent_node_committed_get(node) == + committed && !chunk_hooks->merge(chunk, size, + extent_node_addr_get(node), extent_node_size_get(node), false, + arena->ind)) { + /* + * Coalesce chunk with the following address range. This does + * not change the position within chunks_ad, so only + * remove/insert from/into chunks_szad. + */ + extent_tree_szad_remove(chunks_szad, node); + arena_chunk_cache_maybe_remove(arena, node, cache); + extent_node_addr_set(node, chunk); + extent_node_size_set(node, size + extent_node_size_get(node)); + extent_node_zeroed_set(node, extent_node_zeroed_get(node) && + !unzeroed); + extent_tree_szad_insert(chunks_szad, node); + arena_chunk_cache_maybe_insert(arena, node, cache); + } else { + /* Coalescing forward failed, so insert a new node. */ + node = arena_node_alloc(tsdn, arena); + if (node == NULL) { + /* + * Node allocation failed, which is an exceedingly + * unlikely failure. Leak chunk after making sure its + * pages have already been purged, so that this is only + * a virtual memory leak. + */ + if (cache) { + chunk_purge_wrapper(tsdn, arena, chunk_hooks, + chunk, size, 0, size); + } + goto label_return; + } + extent_node_init(node, arena, chunk, size, !unzeroed, + committed); + extent_tree_ad_insert(chunks_ad, node); + extent_tree_szad_insert(chunks_szad, node); + arena_chunk_cache_maybe_insert(arena, node, cache); + } + + /* Try to coalesce backward. */ + prev = extent_tree_ad_prev(chunks_ad, node); + if (prev != NULL && (void *)((uintptr_t)extent_node_addr_get(prev) + + extent_node_size_get(prev)) == chunk && + extent_node_committed_get(prev) == committed && + !chunk_hooks->merge(extent_node_addr_get(prev), + extent_node_size_get(prev), chunk, size, false, arena->ind)) { + /* + * Coalesce chunk with the previous address range. This does + * not change the position within chunks_ad, so only + * remove/insert node from/into chunks_szad. + */ + extent_tree_szad_remove(chunks_szad, prev); + extent_tree_ad_remove(chunks_ad, prev); + arena_chunk_cache_maybe_remove(arena, prev, cache); + extent_tree_szad_remove(chunks_szad, node); + arena_chunk_cache_maybe_remove(arena, node, cache); + extent_node_addr_set(node, extent_node_addr_get(prev)); + extent_node_size_set(node, extent_node_size_get(prev) + + extent_node_size_get(node)); + extent_node_zeroed_set(node, extent_node_zeroed_get(prev) && + extent_node_zeroed_get(node)); + extent_tree_szad_insert(chunks_szad, node); + arena_chunk_cache_maybe_insert(arena, node, cache); + + arena_node_dalloc(tsdn, arena, prev); + } + +label_return: + malloc_mutex_unlock(tsdn, &arena->chunks_mtx); +} + +void +chunk_dalloc_cache(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, + void *chunk, size_t size, bool committed) +{ + + assert(chunk != NULL); + assert(CHUNK_ADDR2BASE(chunk) == chunk); + assert(size != 0); + assert((size & chunksize_mask) == 0); + + chunk_record(tsdn, arena, chunk_hooks, &arena->chunks_szad_cached, + &arena->chunks_ad_cached, true, chunk, size, false, committed); + arena_maybe_purge(tsdn, arena); +} + +static bool +chunk_dalloc_default_impl(tsdn_t *tsdn, void *chunk, size_t size) +{ + + if (!have_dss || !chunk_in_dss(tsdn, chunk)) + return (chunk_dalloc_mmap(chunk, size)); + return (true); +} + +static bool +chunk_dalloc_default(void *chunk, size_t size, bool committed, + unsigned arena_ind) +{ + tsdn_t *tsdn; + + tsdn = tsdn_fetch(); + + return (chunk_dalloc_default_impl(tsdn, chunk, size)); +} + +void +chunk_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, + void *chunk, size_t size, bool zeroed, bool committed) +{ + bool err; + + assert(chunk != NULL); + assert(CHUNK_ADDR2BASE(chunk) == chunk); + assert(size != 0); + assert((size & chunksize_mask) == 0); + + chunk_hooks_assure_initialized(tsdn, arena, chunk_hooks); + /* Try to deallocate. */ + if (chunk_hooks->dalloc == chunk_dalloc_default) { + /* Call directly to propagate tsdn. */ + err = chunk_dalloc_default_impl(tsdn, chunk, size); + } else + err = chunk_hooks->dalloc(chunk, size, committed, arena->ind); + + if (!err) + return; + /* Try to decommit; purge if that fails. */ + if (committed) { + committed = chunk_hooks->decommit(chunk, size, 0, size, + arena->ind); + } + zeroed = !committed || !chunk_hooks->purge(chunk, size, 0, size, + arena->ind); + chunk_record(tsdn, arena, chunk_hooks, &arena->chunks_szad_retained, + &arena->chunks_ad_retained, false, chunk, size, zeroed, committed); + + if (config_stats) + arena->stats.retained += size; +} + +static bool +chunk_commit_default(void *chunk, size_t size, size_t offset, size_t length, + unsigned arena_ind) +{ + + return (pages_commit((void *)((uintptr_t)chunk + (uintptr_t)offset), + length)); +} + +static bool +chunk_decommit_default(void *chunk, size_t size, size_t offset, size_t length, + unsigned arena_ind) +{ + + return (pages_decommit((void *)((uintptr_t)chunk + (uintptr_t)offset), + length)); +} + +static bool +chunk_purge_default(void *chunk, size_t size, size_t offset, size_t length, + unsigned arena_ind) +{ + + assert(chunk != NULL); + assert(CHUNK_ADDR2BASE(chunk) == chunk); + assert((offset & PAGE_MASK) == 0); + assert(length != 0); + assert((length & PAGE_MASK) == 0); + + return (pages_purge((void *)((uintptr_t)chunk + (uintptr_t)offset), + length)); +} + +bool +chunk_purge_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, + void *chunk, size_t size, size_t offset, size_t length) +{ + + chunk_hooks_assure_initialized(tsdn, arena, chunk_hooks); + return (chunk_hooks->purge(chunk, size, offset, length, arena->ind)); +} + +static bool +chunk_split_default(void *chunk, size_t size, size_t size_a, size_t size_b, + bool committed, unsigned arena_ind) +{ + + if (!maps_coalesce) + return (true); + return (false); +} + +static bool +chunk_merge_default_impl(tsdn_t *tsdn, void *chunk_a, void *chunk_b) +{ + + if (!maps_coalesce) + return (true); + if (have_dss && chunk_in_dss(tsdn, chunk_a) != chunk_in_dss(tsdn, + chunk_b)) + return (true); + + return (false); +} + +static bool +chunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, + bool committed, unsigned arena_ind) +{ + tsdn_t *tsdn; + + tsdn = tsdn_fetch(); + + return (chunk_merge_default_impl(tsdn, chunk_a, chunk_b)); +} + +static rtree_node_elm_t * +chunks_rtree_node_alloc(size_t nelms) +{ + + return ((rtree_node_elm_t *)base_alloc(TSDN_NULL, nelms * + sizeof(rtree_node_elm_t))); +} + +bool +chunk_boot(void) +{ +#ifdef _WIN32 + SYSTEM_INFO info; + GetSystemInfo(&info); + + /* + * Verify actual page size is equal to or an integral multiple of + * configured page size. + */ + if (info.dwPageSize & ((1U << LG_PAGE) - 1)) + return (true); + + /* + * Configure chunksize (if not set) to match granularity (usually 64K), + * so pages_map will always take fast path. + */ + if (!opt_lg_chunk) { + opt_lg_chunk = ffs_u((unsigned)info.dwAllocationGranularity) + - 1; + } +#else + if (!opt_lg_chunk) + opt_lg_chunk = LG_CHUNK_DEFAULT; +#endif + + /* Set variables according to the value of opt_lg_chunk. */ + chunksize = (ZU(1) << opt_lg_chunk); + assert(chunksize >= PAGE); + chunksize_mask = chunksize - 1; + chunk_npages = (chunksize >> LG_PAGE); + + if (have_dss && chunk_dss_boot()) + return (true); + if (rtree_new(&chunks_rtree, (unsigned)((ZU(1) << (LG_SIZEOF_PTR+3)) - + opt_lg_chunk), chunks_rtree_node_alloc, NULL)) + return (true); + + return (false); +} + +void +chunk_prefork(tsdn_t *tsdn) +{ + + chunk_dss_prefork(tsdn); +} + +void +chunk_postfork_parent(tsdn_t *tsdn) +{ + + chunk_dss_postfork_parent(tsdn); +} + +void +chunk_postfork_child(tsdn_t *tsdn) +{ + + chunk_dss_postfork_child(tsdn); +} diff --git a/contrib/jemalloc/src/chunk_dss.c b/contrib/jemalloc/src/chunk_dss.c new file mode 100644 index 0000000..0b1f82b --- /dev/null +++ b/contrib/jemalloc/src/chunk_dss.c @@ -0,0 +1,214 @@ +#define JEMALLOC_CHUNK_DSS_C_ +#include "jemalloc/internal/jemalloc_internal.h" +/******************************************************************************/ +/* Data. */ + +const char *dss_prec_names[] = { + "disabled", + "primary", + "secondary", + "N/A" +}; + +/* Current dss precedence default, used when creating new arenas. */ +static dss_prec_t dss_prec_default = DSS_PREC_DEFAULT; + +/* + * Protects sbrk() calls. This avoids malloc races among threads, though it + * does not protect against races with threads that call sbrk() directly. + */ +static malloc_mutex_t dss_mtx; + +/* Base address of the DSS. */ +static void *dss_base; +/* Current end of the DSS, or ((void *)-1) if the DSS is exhausted. */ +static void *dss_prev; +/* Current upper limit on DSS addresses. */ +static void *dss_max; + +/******************************************************************************/ + +static void * +chunk_dss_sbrk(intptr_t increment) +{ + +#ifdef JEMALLOC_DSS + return (sbrk(increment)); +#else + not_implemented(); + return (NULL); +#endif +} + +dss_prec_t +chunk_dss_prec_get(tsdn_t *tsdn) +{ + dss_prec_t ret; + + if (!have_dss) + return (dss_prec_disabled); + malloc_mutex_lock(tsdn, &dss_mtx); + ret = dss_prec_default; + malloc_mutex_unlock(tsdn, &dss_mtx); + return (ret); +} + +bool +chunk_dss_prec_set(tsdn_t *tsdn, dss_prec_t dss_prec) +{ + + if (!have_dss) + return (dss_prec != dss_prec_disabled); + malloc_mutex_lock(tsdn, &dss_mtx); + dss_prec_default = dss_prec; + malloc_mutex_unlock(tsdn, &dss_mtx); + return (false); +} + +void * +chunk_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, size_t size, + size_t alignment, bool *zero, bool *commit) +{ + cassert(have_dss); + assert(size > 0 && (size & chunksize_mask) == 0); + assert(alignment > 0 && (alignment & chunksize_mask) == 0); + + /* + * sbrk() uses a signed increment argument, so take care not to + * interpret a huge allocation request as a negative increment. + */ + if ((intptr_t)size < 0) + return (NULL); + + malloc_mutex_lock(tsdn, &dss_mtx); + if (dss_prev != (void *)-1) { + + /* + * The loop is necessary to recover from races with other + * threads that are using the DSS for something other than + * malloc. + */ + do { + void *ret, *cpad, *dss_next; + size_t gap_size, cpad_size; + intptr_t incr; + /* Avoid an unnecessary system call. */ + if (new_addr != NULL && dss_max != new_addr) + break; + + /* Get the current end of the DSS. */ + dss_max = chunk_dss_sbrk(0); + + /* Make sure the earlier condition still holds. */ + if (new_addr != NULL && dss_max != new_addr) + break; + + /* + * Calculate how much padding is necessary to + * chunk-align the end of the DSS. + */ + gap_size = (chunksize - CHUNK_ADDR2OFFSET(dss_max)) & + chunksize_mask; + /* + * Compute how much chunk-aligned pad space (if any) is + * necessary to satisfy alignment. This space can be + * recycled for later use. + */ + cpad = (void *)((uintptr_t)dss_max + gap_size); + ret = (void *)ALIGNMENT_CEILING((uintptr_t)dss_max, + alignment); + cpad_size = (uintptr_t)ret - (uintptr_t)cpad; + dss_next = (void *)((uintptr_t)ret + size); + if ((uintptr_t)ret < (uintptr_t)dss_max || + (uintptr_t)dss_next < (uintptr_t)dss_max) { + /* Wrap-around. */ + malloc_mutex_unlock(tsdn, &dss_mtx); + return (NULL); + } + incr = gap_size + cpad_size + size; + dss_prev = chunk_dss_sbrk(incr); + if (dss_prev == dss_max) { + /* Success. */ + dss_max = dss_next; + malloc_mutex_unlock(tsdn, &dss_mtx); + if (cpad_size != 0) { + chunk_hooks_t chunk_hooks = + CHUNK_HOOKS_INITIALIZER; + chunk_dalloc_wrapper(tsdn, arena, + &chunk_hooks, cpad, cpad_size, + false, true); + } + if (*zero) { + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED( + ret, size); + memset(ret, 0, size); + } + if (!*commit) + *commit = pages_decommit(ret, size); + return (ret); + } + } while (dss_prev != (void *)-1); + } + malloc_mutex_unlock(tsdn, &dss_mtx); + + return (NULL); +} + +bool +chunk_in_dss(tsdn_t *tsdn, void *chunk) +{ + bool ret; + + cassert(have_dss); + + malloc_mutex_lock(tsdn, &dss_mtx); + if ((uintptr_t)chunk >= (uintptr_t)dss_base + && (uintptr_t)chunk < (uintptr_t)dss_max) + ret = true; + else + ret = false; + malloc_mutex_unlock(tsdn, &dss_mtx); + + return (ret); +} + +bool +chunk_dss_boot(void) +{ + + cassert(have_dss); + + if (malloc_mutex_init(&dss_mtx, "dss", WITNESS_RANK_DSS)) + return (true); + dss_base = chunk_dss_sbrk(0); + dss_prev = dss_base; + dss_max = dss_base; + + return (false); +} + +void +chunk_dss_prefork(tsdn_t *tsdn) +{ + + if (have_dss) + malloc_mutex_prefork(tsdn, &dss_mtx); +} + +void +chunk_dss_postfork_parent(tsdn_t *tsdn) +{ + + if (have_dss) + malloc_mutex_postfork_parent(tsdn, &dss_mtx); +} + +void +chunk_dss_postfork_child(tsdn_t *tsdn) +{ + + if (have_dss) + malloc_mutex_postfork_child(tsdn, &dss_mtx); +} + +/******************************************************************************/ diff --git a/contrib/jemalloc/src/chunk_mmap.c b/contrib/jemalloc/src/chunk_mmap.c new file mode 100644 index 0000000..73fc497 --- /dev/null +++ b/contrib/jemalloc/src/chunk_mmap.c @@ -0,0 +1,78 @@ +#define JEMALLOC_CHUNK_MMAP_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ + +static void * +chunk_alloc_mmap_slow(size_t size, size_t alignment, bool *zero, bool *commit) +{ + void *ret; + size_t alloc_size; + + alloc_size = size + alignment - PAGE; + /* Beware size_t wrap-around. */ + if (alloc_size < size) + return (NULL); + do { + void *pages; + size_t leadsize; + pages = pages_map(NULL, alloc_size, commit); + if (pages == NULL) + return (NULL); + leadsize = ALIGNMENT_CEILING((uintptr_t)pages, alignment) - + (uintptr_t)pages; + ret = pages_trim(pages, alloc_size, leadsize, size, commit); + } while (ret == NULL); + + assert(ret != NULL); + *zero = true; + return (ret); +} + +void * +chunk_alloc_mmap(void *new_addr, size_t size, size_t alignment, bool *zero, + bool *commit) +{ + void *ret; + size_t offset; + + /* + * Ideally, there would be a way to specify alignment to mmap() (like + * NetBSD has), but in the absence of such a feature, we have to work + * hard to efficiently create aligned mappings. The reliable, but + * slow method is to create a mapping that is over-sized, then trim the + * excess. However, that always results in one or two calls to + * pages_unmap(). + * + * Optimistically try mapping precisely the right amount before falling + * back to the slow method, with the expectation that the optimistic + * approach works most of the time. + */ + + assert(alignment != 0); + assert((alignment & chunksize_mask) == 0); + + ret = pages_map(new_addr, size, commit); + if (ret == NULL || ret == new_addr) + return (ret); + assert(new_addr == NULL); + offset = ALIGNMENT_ADDR2OFFSET(ret, alignment); + if (offset != 0) { + pages_unmap(ret, size); + return (chunk_alloc_mmap_slow(size, alignment, zero, commit)); + } + + assert(ret != NULL); + *zero = true; + return (ret); +} + +bool +chunk_dalloc_mmap(void *chunk, size_t size) +{ + + if (config_munmap) + pages_unmap(chunk, size); + + return (!config_munmap); +} diff --git a/contrib/jemalloc/src/ckh.c b/contrib/jemalloc/src/ckh.c new file mode 100644 index 0000000..747c1c8 --- /dev/null +++ b/contrib/jemalloc/src/ckh.c @@ -0,0 +1,568 @@ +/* + ******************************************************************************* + * Implementation of (2^1+,2) cuckoo hashing, where 2^1+ indicates that each + * hash bucket contains 2^n cells, for n >= 1, and 2 indicates that two hash + * functions are employed. The original cuckoo hashing algorithm was described + * in: + * + * Pagh, R., F.F. Rodler (2004) Cuckoo Hashing. Journal of Algorithms + * 51(2):122-144. + * + * Generalization of cuckoo hashing was discussed in: + * + * Erlingsson, U., M. Manasse, F. McSherry (2006) A cool and practical + * alternative to traditional hash tables. In Proceedings of the 7th + * Workshop on Distributed Data and Structures (WDAS'06), Santa Clara, CA, + * January 2006. + * + * This implementation uses precisely two hash functions because that is the + * fewest that can work, and supporting multiple hashes is an implementation + * burden. Here is a reproduction of Figure 1 from Erlingsson et al. (2006) + * that shows approximate expected maximum load factors for various + * configurations: + * + * | #cells/bucket | + * #hashes | 1 | 2 | 4 | 8 | + * --------+-------+-------+-------+-------+ + * 1 | 0.006 | 0.006 | 0.03 | 0.12 | + * 2 | 0.49 | 0.86 |>0.93< |>0.96< | + * 3 | 0.91 | 0.97 | 0.98 | 0.999 | + * 4 | 0.97 | 0.99 | 0.999 | | + * + * The number of cells per bucket is chosen such that a bucket fits in one cache + * line. So, on 32- and 64-bit systems, we use (8,2) and (4,2) cuckoo hashing, + * respectively. + * + ******************************************************************************/ +#define JEMALLOC_CKH_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Function prototypes for non-inline static functions. */ + +static bool ckh_grow(tsdn_t *tsdn, ckh_t *ckh); +static void ckh_shrink(tsdn_t *tsdn, ckh_t *ckh); + +/******************************************************************************/ + +/* + * Search bucket for key and return the cell number if found; SIZE_T_MAX + * otherwise. + */ +JEMALLOC_INLINE_C size_t +ckh_bucket_search(ckh_t *ckh, size_t bucket, const void *key) +{ + ckhc_t *cell; + unsigned i; + + for (i = 0; i < (ZU(1) << LG_CKH_BUCKET_CELLS); i++) { + cell = &ckh->tab[(bucket << LG_CKH_BUCKET_CELLS) + i]; + if (cell->key != NULL && ckh->keycomp(key, cell->key)) + return ((bucket << LG_CKH_BUCKET_CELLS) + i); + } + + return (SIZE_T_MAX); +} + +/* + * Search table for key and return cell number if found; SIZE_T_MAX otherwise. + */ +JEMALLOC_INLINE_C size_t +ckh_isearch(ckh_t *ckh, const void *key) +{ + size_t hashes[2], bucket, cell; + + assert(ckh != NULL); + + ckh->hash(key, hashes); + + /* Search primary bucket. */ + bucket = hashes[0] & ((ZU(1) << ckh->lg_curbuckets) - 1); + cell = ckh_bucket_search(ckh, bucket, key); + if (cell != SIZE_T_MAX) + return (cell); + + /* Search secondary bucket. */ + bucket = hashes[1] & ((ZU(1) << ckh->lg_curbuckets) - 1); + cell = ckh_bucket_search(ckh, bucket, key); + return (cell); +} + +JEMALLOC_INLINE_C bool +ckh_try_bucket_insert(ckh_t *ckh, size_t bucket, const void *key, + const void *data) +{ + ckhc_t *cell; + unsigned offset, i; + + /* + * Cycle through the cells in the bucket, starting at a random position. + * The randomness avoids worst-case search overhead as buckets fill up. + */ + offset = (unsigned)prng_lg_range(&ckh->prng_state, LG_CKH_BUCKET_CELLS); + for (i = 0; i < (ZU(1) << LG_CKH_BUCKET_CELLS); i++) { + cell = &ckh->tab[(bucket << LG_CKH_BUCKET_CELLS) + + ((i + offset) & ((ZU(1) << LG_CKH_BUCKET_CELLS) - 1))]; + if (cell->key == NULL) { + cell->key = key; + cell->data = data; + ckh->count++; + return (false); + } + } + + return (true); +} + +/* + * No space is available in bucket. Randomly evict an item, then try to find an + * alternate location for that item. Iteratively repeat this + * eviction/relocation procedure until either success or detection of an + * eviction/relocation bucket cycle. + */ +JEMALLOC_INLINE_C bool +ckh_evict_reloc_insert(ckh_t *ckh, size_t argbucket, void const **argkey, + void const **argdata) +{ + const void *key, *data, *tkey, *tdata; + ckhc_t *cell; + size_t hashes[2], bucket, tbucket; + unsigned i; + + bucket = argbucket; + key = *argkey; + data = *argdata; + while (true) { + /* + * Choose a random item within the bucket to evict. This is + * critical to correct function, because without (eventually) + * evicting all items within a bucket during iteration, it + * would be possible to get stuck in an infinite loop if there + * were an item for which both hashes indicated the same + * bucket. + */ + i = (unsigned)prng_lg_range(&ckh->prng_state, + LG_CKH_BUCKET_CELLS); + cell = &ckh->tab[(bucket << LG_CKH_BUCKET_CELLS) + i]; + assert(cell->key != NULL); + + /* Swap cell->{key,data} and {key,data} (evict). */ + tkey = cell->key; tdata = cell->data; + cell->key = key; cell->data = data; + key = tkey; data = tdata; + +#ifdef CKH_COUNT + ckh->nrelocs++; +#endif + + /* Find the alternate bucket for the evicted item. */ + ckh->hash(key, hashes); + tbucket = hashes[1] & ((ZU(1) << ckh->lg_curbuckets) - 1); + if (tbucket == bucket) { + tbucket = hashes[0] & ((ZU(1) << ckh->lg_curbuckets) + - 1); + /* + * It may be that (tbucket == bucket) still, if the + * item's hashes both indicate this bucket. However, + * we are guaranteed to eventually escape this bucket + * during iteration, assuming pseudo-random item + * selection (true randomness would make infinite + * looping a remote possibility). The reason we can + * never get trapped forever is that there are two + * cases: + * + * 1) This bucket == argbucket, so we will quickly + * detect an eviction cycle and terminate. + * 2) An item was evicted to this bucket from another, + * which means that at least one item in this bucket + * has hashes that indicate distinct buckets. + */ + } + /* Check for a cycle. */ + if (tbucket == argbucket) { + *argkey = key; + *argdata = data; + return (true); + } + + bucket = tbucket; + if (!ckh_try_bucket_insert(ckh, bucket, key, data)) + return (false); + } +} + +JEMALLOC_INLINE_C bool +ckh_try_insert(ckh_t *ckh, void const**argkey, void const**argdata) +{ + size_t hashes[2], bucket; + const void *key = *argkey; + const void *data = *argdata; + + ckh->hash(key, hashes); + + /* Try to insert in primary bucket. */ + bucket = hashes[0] & ((ZU(1) << ckh->lg_curbuckets) - 1); + if (!ckh_try_bucket_insert(ckh, bucket, key, data)) + return (false); + + /* Try to insert in secondary bucket. */ + bucket = hashes[1] & ((ZU(1) << ckh->lg_curbuckets) - 1); + if (!ckh_try_bucket_insert(ckh, bucket, key, data)) + return (false); + + /* + * Try to find a place for this item via iterative eviction/relocation. + */ + return (ckh_evict_reloc_insert(ckh, bucket, argkey, argdata)); +} + +/* + * Try to rebuild the hash table from scratch by inserting all items from the + * old table into the new. + */ +JEMALLOC_INLINE_C bool +ckh_rebuild(ckh_t *ckh, ckhc_t *aTab) +{ + size_t count, i, nins; + const void *key, *data; + + count = ckh->count; + ckh->count = 0; + for (i = nins = 0; nins < count; i++) { + if (aTab[i].key != NULL) { + key = aTab[i].key; + data = aTab[i].data; + if (ckh_try_insert(ckh, &key, &data)) { + ckh->count = count; + return (true); + } + nins++; + } + } + + return (false); +} + +static bool +ckh_grow(tsdn_t *tsdn, ckh_t *ckh) +{ + bool ret; + ckhc_t *tab, *ttab; + unsigned lg_prevbuckets, lg_curcells; + +#ifdef CKH_COUNT + ckh->ngrows++; +#endif + + /* + * It is possible (though unlikely, given well behaved hashes) that the + * table will have to be doubled more than once in order to create a + * usable table. + */ + lg_prevbuckets = ckh->lg_curbuckets; + lg_curcells = ckh->lg_curbuckets + LG_CKH_BUCKET_CELLS; + while (true) { + size_t usize; + + lg_curcells++; + usize = sa2u(sizeof(ckhc_t) << lg_curcells, CACHELINE); + if (unlikely(usize == 0 || usize > HUGE_MAXCLASS)) { + ret = true; + goto label_return; + } + tab = (ckhc_t *)ipallocztm(tsdn, usize, CACHELINE, true, NULL, + true, arena_ichoose(tsdn, NULL)); + if (tab == NULL) { + ret = true; + goto label_return; + } + /* Swap in new table. */ + ttab = ckh->tab; + ckh->tab = tab; + tab = ttab; + ckh->lg_curbuckets = lg_curcells - LG_CKH_BUCKET_CELLS; + + if (!ckh_rebuild(ckh, tab)) { + idalloctm(tsdn, tab, NULL, true, true); + break; + } + + /* Rebuilding failed, so back out partially rebuilt table. */ + idalloctm(tsdn, ckh->tab, NULL, true, true); + ckh->tab = tab; + ckh->lg_curbuckets = lg_prevbuckets; + } + + ret = false; +label_return: + return (ret); +} + +static void +ckh_shrink(tsdn_t *tsdn, ckh_t *ckh) +{ + ckhc_t *tab, *ttab; + size_t usize; + unsigned lg_prevbuckets, lg_curcells; + + /* + * It is possible (though unlikely, given well behaved hashes) that the + * table rebuild will fail. + */ + lg_prevbuckets = ckh->lg_curbuckets; + lg_curcells = ckh->lg_curbuckets + LG_CKH_BUCKET_CELLS - 1; + usize = sa2u(sizeof(ckhc_t) << lg_curcells, CACHELINE); + if (unlikely(usize == 0 || usize > HUGE_MAXCLASS)) + return; + tab = (ckhc_t *)ipallocztm(tsdn, usize, CACHELINE, true, NULL, true, + arena_ichoose(tsdn, NULL)); + if (tab == NULL) { + /* + * An OOM error isn't worth propagating, since it doesn't + * prevent this or future operations from proceeding. + */ + return; + } + /* Swap in new table. */ + ttab = ckh->tab; + ckh->tab = tab; + tab = ttab; + ckh->lg_curbuckets = lg_curcells - LG_CKH_BUCKET_CELLS; + + if (!ckh_rebuild(ckh, tab)) { + idalloctm(tsdn, tab, NULL, true, true); +#ifdef CKH_COUNT + ckh->nshrinks++; +#endif + return; + } + + /* Rebuilding failed, so back out partially rebuilt table. */ + idalloctm(tsdn, ckh->tab, NULL, true, true); + ckh->tab = tab; + ckh->lg_curbuckets = lg_prevbuckets; +#ifdef CKH_COUNT + ckh->nshrinkfails++; +#endif +} + +bool +ckh_new(tsdn_t *tsdn, ckh_t *ckh, size_t minitems, ckh_hash_t *hash, + ckh_keycomp_t *keycomp) +{ + bool ret; + size_t mincells, usize; + unsigned lg_mincells; + + assert(minitems > 0); + assert(hash != NULL); + assert(keycomp != NULL); + +#ifdef CKH_COUNT + ckh->ngrows = 0; + ckh->nshrinks = 0; + ckh->nshrinkfails = 0; + ckh->ninserts = 0; + ckh->nrelocs = 0; +#endif + ckh->prng_state = 42; /* Value doesn't really matter. */ + ckh->count = 0; + + /* + * Find the minimum power of 2 that is large enough to fit minitems + * entries. We are using (2+,2) cuckoo hashing, which has an expected + * maximum load factor of at least ~0.86, so 0.75 is a conservative load + * factor that will typically allow mincells items to fit without ever + * growing the table. + */ + assert(LG_CKH_BUCKET_CELLS > 0); + mincells = ((minitems + (3 - (minitems % 3))) / 3) << 2; + for (lg_mincells = LG_CKH_BUCKET_CELLS; + (ZU(1) << lg_mincells) < mincells; + lg_mincells++) + ; /* Do nothing. */ + ckh->lg_minbuckets = lg_mincells - LG_CKH_BUCKET_CELLS; + ckh->lg_curbuckets = lg_mincells - LG_CKH_BUCKET_CELLS; + ckh->hash = hash; + ckh->keycomp = keycomp; + + usize = sa2u(sizeof(ckhc_t) << lg_mincells, CACHELINE); + if (unlikely(usize == 0 || usize > HUGE_MAXCLASS)) { + ret = true; + goto label_return; + } + ckh->tab = (ckhc_t *)ipallocztm(tsdn, usize, CACHELINE, true, NULL, + true, arena_ichoose(tsdn, NULL)); + if (ckh->tab == NULL) { + ret = true; + goto label_return; + } + + ret = false; +label_return: + return (ret); +} + +void +ckh_delete(tsdn_t *tsdn, ckh_t *ckh) +{ + + assert(ckh != NULL); + +#ifdef CKH_VERBOSE + malloc_printf( + "%s(%p): ngrows: %"FMTu64", nshrinks: %"FMTu64"," + " nshrinkfails: %"FMTu64", ninserts: %"FMTu64"," + " nrelocs: %"FMTu64"\n", __func__, ckh, + (unsigned long long)ckh->ngrows, + (unsigned long long)ckh->nshrinks, + (unsigned long long)ckh->nshrinkfails, + (unsigned long long)ckh->ninserts, + (unsigned long long)ckh->nrelocs); +#endif + + idalloctm(tsdn, ckh->tab, NULL, true, true); + if (config_debug) + memset(ckh, JEMALLOC_FREE_JUNK, sizeof(ckh_t)); +} + +size_t +ckh_count(ckh_t *ckh) +{ + + assert(ckh != NULL); + + return (ckh->count); +} + +bool +ckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data) +{ + size_t i, ncells; + + for (i = *tabind, ncells = (ZU(1) << (ckh->lg_curbuckets + + LG_CKH_BUCKET_CELLS)); i < ncells; i++) { + if (ckh->tab[i].key != NULL) { + if (key != NULL) + *key = (void *)ckh->tab[i].key; + if (data != NULL) + *data = (void *)ckh->tab[i].data; + *tabind = i + 1; + return (false); + } + } + + return (true); +} + +bool +ckh_insert(tsdn_t *tsdn, ckh_t *ckh, const void *key, const void *data) +{ + bool ret; + + assert(ckh != NULL); + assert(ckh_search(ckh, key, NULL, NULL)); + +#ifdef CKH_COUNT + ckh->ninserts++; +#endif + + while (ckh_try_insert(ckh, &key, &data)) { + if (ckh_grow(tsdn, ckh)) { + ret = true; + goto label_return; + } + } + + ret = false; +label_return: + return (ret); +} + +bool +ckh_remove(tsdn_t *tsdn, ckh_t *ckh, const void *searchkey, void **key, + void **data) +{ + size_t cell; + + assert(ckh != NULL); + + cell = ckh_isearch(ckh, searchkey); + if (cell != SIZE_T_MAX) { + if (key != NULL) + *key = (void *)ckh->tab[cell].key; + if (data != NULL) + *data = (void *)ckh->tab[cell].data; + ckh->tab[cell].key = NULL; + ckh->tab[cell].data = NULL; /* Not necessary. */ + + ckh->count--; + /* Try to halve the table if it is less than 1/4 full. */ + if (ckh->count < (ZU(1) << (ckh->lg_curbuckets + + LG_CKH_BUCKET_CELLS - 2)) && ckh->lg_curbuckets + > ckh->lg_minbuckets) { + /* Ignore error due to OOM. */ + ckh_shrink(tsdn, ckh); + } + + return (false); + } + + return (true); +} + +bool +ckh_search(ckh_t *ckh, const void *searchkey, void **key, void **data) +{ + size_t cell; + + assert(ckh != NULL); + + cell = ckh_isearch(ckh, searchkey); + if (cell != SIZE_T_MAX) { + if (key != NULL) + *key = (void *)ckh->tab[cell].key; + if (data != NULL) + *data = (void *)ckh->tab[cell].data; + return (false); + } + + return (true); +} + +void +ckh_string_hash(const void *key, size_t r_hash[2]) +{ + + hash(key, strlen((const char *)key), 0x94122f33U, r_hash); +} + +bool +ckh_string_keycomp(const void *k1, const void *k2) +{ + + assert(k1 != NULL); + assert(k2 != NULL); + + return (strcmp((char *)k1, (char *)k2) ? false : true); +} + +void +ckh_pointer_hash(const void *key, size_t r_hash[2]) +{ + union { + const void *v; + size_t i; + } u; + + assert(sizeof(u.v) == sizeof(u.i)); + u.v = key; + hash(&u.i, sizeof(u.i), 0xd983396eU, r_hash); +} + +bool +ckh_pointer_keycomp(const void *k1, const void *k2) +{ + + return ((k1 == k2) ? true : false); +} diff --git a/contrib/jemalloc/src/ctl.c b/contrib/jemalloc/src/ctl.c new file mode 100644 index 0000000..dad8008 --- /dev/null +++ b/contrib/jemalloc/src/ctl.c @@ -0,0 +1,2254 @@ +#define JEMALLOC_CTL_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +/* + * ctl_mtx protects the following: + * - ctl_stats.* + */ +static malloc_mutex_t ctl_mtx; +static bool ctl_initialized; +static uint64_t ctl_epoch; +static ctl_stats_t ctl_stats; + +/******************************************************************************/ +/* Helpers for named and indexed nodes. */ + +JEMALLOC_INLINE_C const ctl_named_node_t * +ctl_named_node(const ctl_node_t *node) +{ + + return ((node->named) ? (const ctl_named_node_t *)node : NULL); +} + +JEMALLOC_INLINE_C const ctl_named_node_t * +ctl_named_children(const ctl_named_node_t *node, size_t index) +{ + const ctl_named_node_t *children = ctl_named_node(node->children); + + return (children ? &children[index] : NULL); +} + +JEMALLOC_INLINE_C const ctl_indexed_node_t * +ctl_indexed_node(const ctl_node_t *node) +{ + + return (!node->named ? (const ctl_indexed_node_t *)node : NULL); +} + +/******************************************************************************/ +/* Function prototypes for non-inline static functions. */ + +#define CTL_PROTO(n) \ +static int n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, \ + void *oldp, size_t *oldlenp, void *newp, size_t newlen); + +#define INDEX_PROTO(n) \ +static const ctl_named_node_t *n##_index(tsdn_t *tsdn, \ + const size_t *mib, size_t miblen, size_t i); + +static bool ctl_arena_init(ctl_arena_stats_t *astats); +static void ctl_arena_clear(ctl_arena_stats_t *astats); +static void ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats, + arena_t *arena); +static void ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, + ctl_arena_stats_t *astats); +static void ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i); +static bool ctl_grow(tsdn_t *tsdn); +static void ctl_refresh(tsdn_t *tsdn); +static bool ctl_init(tsdn_t *tsdn); +static int ctl_lookup(tsdn_t *tsdn, const char *name, + ctl_node_t const **nodesp, size_t *mibp, size_t *depthp); + +CTL_PROTO(version) +CTL_PROTO(epoch) +CTL_PROTO(thread_tcache_enabled) +CTL_PROTO(thread_tcache_flush) +CTL_PROTO(thread_prof_name) +CTL_PROTO(thread_prof_active) +CTL_PROTO(thread_arena) +CTL_PROTO(thread_allocated) +CTL_PROTO(thread_allocatedp) +CTL_PROTO(thread_deallocated) +CTL_PROTO(thread_deallocatedp) +CTL_PROTO(config_cache_oblivious) +CTL_PROTO(config_debug) +CTL_PROTO(config_fill) +CTL_PROTO(config_lazy_lock) +CTL_PROTO(config_malloc_conf) +CTL_PROTO(config_munmap) +CTL_PROTO(config_prof) +CTL_PROTO(config_prof_libgcc) +CTL_PROTO(config_prof_libunwind) +CTL_PROTO(config_stats) +CTL_PROTO(config_tcache) +CTL_PROTO(config_tls) +CTL_PROTO(config_utrace) +CTL_PROTO(config_valgrind) +CTL_PROTO(config_xmalloc) +CTL_PROTO(opt_abort) +CTL_PROTO(opt_dss) +CTL_PROTO(opt_lg_chunk) +CTL_PROTO(opt_narenas) +CTL_PROTO(opt_purge) +CTL_PROTO(opt_lg_dirty_mult) +CTL_PROTO(opt_decay_time) +CTL_PROTO(opt_stats_print) +CTL_PROTO(opt_junk) +CTL_PROTO(opt_zero) +CTL_PROTO(opt_quarantine) +CTL_PROTO(opt_redzone) +CTL_PROTO(opt_utrace) +CTL_PROTO(opt_xmalloc) +CTL_PROTO(opt_tcache) +CTL_PROTO(opt_lg_tcache_max) +CTL_PROTO(opt_prof) +CTL_PROTO(opt_prof_prefix) +CTL_PROTO(opt_prof_active) +CTL_PROTO(opt_prof_thread_active_init) +CTL_PROTO(opt_lg_prof_sample) +CTL_PROTO(opt_lg_prof_interval) +CTL_PROTO(opt_prof_gdump) +CTL_PROTO(opt_prof_final) +CTL_PROTO(opt_prof_leak) +CTL_PROTO(opt_prof_accum) +CTL_PROTO(tcache_create) +CTL_PROTO(tcache_flush) +CTL_PROTO(tcache_destroy) +static void arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all); +CTL_PROTO(arena_i_purge) +CTL_PROTO(arena_i_decay) +CTL_PROTO(arena_i_reset) +CTL_PROTO(arena_i_dss) +CTL_PROTO(arena_i_lg_dirty_mult) +CTL_PROTO(arena_i_decay_time) +CTL_PROTO(arena_i_chunk_hooks) +INDEX_PROTO(arena_i) +CTL_PROTO(arenas_bin_i_size) +CTL_PROTO(arenas_bin_i_nregs) +CTL_PROTO(arenas_bin_i_run_size) +INDEX_PROTO(arenas_bin_i) +CTL_PROTO(arenas_lrun_i_size) +INDEX_PROTO(arenas_lrun_i) +CTL_PROTO(arenas_hchunk_i_size) +INDEX_PROTO(arenas_hchunk_i) +CTL_PROTO(arenas_narenas) +CTL_PROTO(arenas_initialized) +CTL_PROTO(arenas_lg_dirty_mult) +CTL_PROTO(arenas_decay_time) +CTL_PROTO(arenas_quantum) +CTL_PROTO(arenas_page) +CTL_PROTO(arenas_tcache_max) +CTL_PROTO(arenas_nbins) +CTL_PROTO(arenas_nhbins) +CTL_PROTO(arenas_nlruns) +CTL_PROTO(arenas_nhchunks) +CTL_PROTO(arenas_extend) +CTL_PROTO(prof_thread_active_init) +CTL_PROTO(prof_active) +CTL_PROTO(prof_dump) +CTL_PROTO(prof_gdump) +CTL_PROTO(prof_reset) +CTL_PROTO(prof_interval) +CTL_PROTO(lg_prof_sample) +CTL_PROTO(stats_arenas_i_small_allocated) +CTL_PROTO(stats_arenas_i_small_nmalloc) +CTL_PROTO(stats_arenas_i_small_ndalloc) +CTL_PROTO(stats_arenas_i_small_nrequests) +CTL_PROTO(stats_arenas_i_large_allocated) +CTL_PROTO(stats_arenas_i_large_nmalloc) +CTL_PROTO(stats_arenas_i_large_ndalloc) +CTL_PROTO(stats_arenas_i_large_nrequests) +CTL_PROTO(stats_arenas_i_huge_allocated) +CTL_PROTO(stats_arenas_i_huge_nmalloc) +CTL_PROTO(stats_arenas_i_huge_ndalloc) +CTL_PROTO(stats_arenas_i_huge_nrequests) +CTL_PROTO(stats_arenas_i_bins_j_nmalloc) +CTL_PROTO(stats_arenas_i_bins_j_ndalloc) +CTL_PROTO(stats_arenas_i_bins_j_nrequests) +CTL_PROTO(stats_arenas_i_bins_j_curregs) +CTL_PROTO(stats_arenas_i_bins_j_nfills) +CTL_PROTO(stats_arenas_i_bins_j_nflushes) +CTL_PROTO(stats_arenas_i_bins_j_nruns) +CTL_PROTO(stats_arenas_i_bins_j_nreruns) +CTL_PROTO(stats_arenas_i_bins_j_curruns) +INDEX_PROTO(stats_arenas_i_bins_j) +CTL_PROTO(stats_arenas_i_lruns_j_nmalloc) +CTL_PROTO(stats_arenas_i_lruns_j_ndalloc) +CTL_PROTO(stats_arenas_i_lruns_j_nrequests) +CTL_PROTO(stats_arenas_i_lruns_j_curruns) +INDEX_PROTO(stats_arenas_i_lruns_j) +CTL_PROTO(stats_arenas_i_hchunks_j_nmalloc) +CTL_PROTO(stats_arenas_i_hchunks_j_ndalloc) +CTL_PROTO(stats_arenas_i_hchunks_j_nrequests) +CTL_PROTO(stats_arenas_i_hchunks_j_curhchunks) +INDEX_PROTO(stats_arenas_i_hchunks_j) +CTL_PROTO(stats_arenas_i_nthreads) +CTL_PROTO(stats_arenas_i_dss) +CTL_PROTO(stats_arenas_i_lg_dirty_mult) +CTL_PROTO(stats_arenas_i_decay_time) +CTL_PROTO(stats_arenas_i_pactive) +CTL_PROTO(stats_arenas_i_pdirty) +CTL_PROTO(stats_arenas_i_mapped) +CTL_PROTO(stats_arenas_i_retained) +CTL_PROTO(stats_arenas_i_npurge) +CTL_PROTO(stats_arenas_i_nmadvise) +CTL_PROTO(stats_arenas_i_purged) +CTL_PROTO(stats_arenas_i_metadata_mapped) +CTL_PROTO(stats_arenas_i_metadata_allocated) +INDEX_PROTO(stats_arenas_i) +CTL_PROTO(stats_cactive) +CTL_PROTO(stats_allocated) +CTL_PROTO(stats_active) +CTL_PROTO(stats_metadata) +CTL_PROTO(stats_resident) +CTL_PROTO(stats_mapped) +CTL_PROTO(stats_retained) + +/******************************************************************************/ +/* mallctl tree. */ + +/* Maximum tree depth. */ +#define CTL_MAX_DEPTH 6 + +#define NAME(n) {true}, n +#define CHILD(t, c) \ + sizeof(c##_node) / sizeof(ctl_##t##_node_t), \ + (ctl_node_t *)c##_node, \ + NULL +#define CTL(c) 0, NULL, c##_ctl + +/* + * Only handles internal indexed nodes, since there are currently no external + * ones. + */ +#define INDEX(i) {false}, i##_index + +static const ctl_named_node_t thread_tcache_node[] = { + {NAME("enabled"), CTL(thread_tcache_enabled)}, + {NAME("flush"), CTL(thread_tcache_flush)} +}; + +static const ctl_named_node_t thread_prof_node[] = { + {NAME("name"), CTL(thread_prof_name)}, + {NAME("active"), CTL(thread_prof_active)} +}; + +static const ctl_named_node_t thread_node[] = { + {NAME("arena"), CTL(thread_arena)}, + {NAME("allocated"), CTL(thread_allocated)}, + {NAME("allocatedp"), CTL(thread_allocatedp)}, + {NAME("deallocated"), CTL(thread_deallocated)}, + {NAME("deallocatedp"), CTL(thread_deallocatedp)}, + {NAME("tcache"), CHILD(named, thread_tcache)}, + {NAME("prof"), CHILD(named, thread_prof)} +}; + +static const ctl_named_node_t config_node[] = { + {NAME("cache_oblivious"), CTL(config_cache_oblivious)}, + {NAME("debug"), CTL(config_debug)}, + {NAME("fill"), CTL(config_fill)}, + {NAME("lazy_lock"), CTL(config_lazy_lock)}, + {NAME("malloc_conf"), CTL(config_malloc_conf)}, + {NAME("munmap"), CTL(config_munmap)}, + {NAME("prof"), CTL(config_prof)}, + {NAME("prof_libgcc"), CTL(config_prof_libgcc)}, + {NAME("prof_libunwind"), CTL(config_prof_libunwind)}, + {NAME("stats"), CTL(config_stats)}, + {NAME("tcache"), CTL(config_tcache)}, + {NAME("tls"), CTL(config_tls)}, + {NAME("utrace"), CTL(config_utrace)}, + {NAME("valgrind"), CTL(config_valgrind)}, + {NAME("xmalloc"), CTL(config_xmalloc)} +}; + +static const ctl_named_node_t opt_node[] = { + {NAME("abort"), CTL(opt_abort)}, + {NAME("dss"), CTL(opt_dss)}, + {NAME("lg_chunk"), CTL(opt_lg_chunk)}, + {NAME("narenas"), CTL(opt_narenas)}, + {NAME("purge"), CTL(opt_purge)}, + {NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)}, + {NAME("decay_time"), CTL(opt_decay_time)}, + {NAME("stats_print"), CTL(opt_stats_print)}, + {NAME("junk"), CTL(opt_junk)}, + {NAME("zero"), CTL(opt_zero)}, + {NAME("quarantine"), CTL(opt_quarantine)}, + {NAME("redzone"), CTL(opt_redzone)}, + {NAME("utrace"), CTL(opt_utrace)}, + {NAME("xmalloc"), CTL(opt_xmalloc)}, + {NAME("tcache"), CTL(opt_tcache)}, + {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)}, + {NAME("prof"), CTL(opt_prof)}, + {NAME("prof_prefix"), CTL(opt_prof_prefix)}, + {NAME("prof_active"), CTL(opt_prof_active)}, + {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)}, + {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)}, + {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)}, + {NAME("prof_gdump"), CTL(opt_prof_gdump)}, + {NAME("prof_final"), CTL(opt_prof_final)}, + {NAME("prof_leak"), CTL(opt_prof_leak)}, + {NAME("prof_accum"), CTL(opt_prof_accum)} +}; + +static const ctl_named_node_t tcache_node[] = { + {NAME("create"), CTL(tcache_create)}, + {NAME("flush"), CTL(tcache_flush)}, + {NAME("destroy"), CTL(tcache_destroy)} +}; + +static const ctl_named_node_t arena_i_node[] = { + {NAME("purge"), CTL(arena_i_purge)}, + {NAME("decay"), CTL(arena_i_decay)}, + {NAME("reset"), CTL(arena_i_reset)}, + {NAME("dss"), CTL(arena_i_dss)}, + {NAME("lg_dirty_mult"), CTL(arena_i_lg_dirty_mult)}, + {NAME("decay_time"), CTL(arena_i_decay_time)}, + {NAME("chunk_hooks"), CTL(arena_i_chunk_hooks)} +}; +static const ctl_named_node_t super_arena_i_node[] = { + {NAME(""), CHILD(named, arena_i)} +}; + +static const ctl_indexed_node_t arena_node[] = { + {INDEX(arena_i)} +}; + +static const ctl_named_node_t arenas_bin_i_node[] = { + {NAME("size"), CTL(arenas_bin_i_size)}, + {NAME("nregs"), CTL(arenas_bin_i_nregs)}, + {NAME("run_size"), CTL(arenas_bin_i_run_size)} +}; +static const ctl_named_node_t super_arenas_bin_i_node[] = { + {NAME(""), CHILD(named, arenas_bin_i)} +}; + +static const ctl_indexed_node_t arenas_bin_node[] = { + {INDEX(arenas_bin_i)} +}; + +static const ctl_named_node_t arenas_lrun_i_node[] = { + {NAME("size"), CTL(arenas_lrun_i_size)} +}; +static const ctl_named_node_t super_arenas_lrun_i_node[] = { + {NAME(""), CHILD(named, arenas_lrun_i)} +}; + +static const ctl_indexed_node_t arenas_lrun_node[] = { + {INDEX(arenas_lrun_i)} +}; + +static const ctl_named_node_t arenas_hchunk_i_node[] = { + {NAME("size"), CTL(arenas_hchunk_i_size)} +}; +static const ctl_named_node_t super_arenas_hchunk_i_node[] = { + {NAME(""), CHILD(named, arenas_hchunk_i)} +}; + +static const ctl_indexed_node_t arenas_hchunk_node[] = { + {INDEX(arenas_hchunk_i)} +}; + +static const ctl_named_node_t arenas_node[] = { + {NAME("narenas"), CTL(arenas_narenas)}, + {NAME("initialized"), CTL(arenas_initialized)}, + {NAME("lg_dirty_mult"), CTL(arenas_lg_dirty_mult)}, + {NAME("decay_time"), CTL(arenas_decay_time)}, + {NAME("quantum"), CTL(arenas_quantum)}, + {NAME("page"), CTL(arenas_page)}, + {NAME("tcache_max"), CTL(arenas_tcache_max)}, + {NAME("nbins"), CTL(arenas_nbins)}, + {NAME("nhbins"), CTL(arenas_nhbins)}, + {NAME("bin"), CHILD(indexed, arenas_bin)}, + {NAME("nlruns"), CTL(arenas_nlruns)}, + {NAME("lrun"), CHILD(indexed, arenas_lrun)}, + {NAME("nhchunks"), CTL(arenas_nhchunks)}, + {NAME("hchunk"), CHILD(indexed, arenas_hchunk)}, + {NAME("extend"), CTL(arenas_extend)} +}; + +static const ctl_named_node_t prof_node[] = { + {NAME("thread_active_init"), CTL(prof_thread_active_init)}, + {NAME("active"), CTL(prof_active)}, + {NAME("dump"), CTL(prof_dump)}, + {NAME("gdump"), CTL(prof_gdump)}, + {NAME("reset"), CTL(prof_reset)}, + {NAME("interval"), CTL(prof_interval)}, + {NAME("lg_sample"), CTL(lg_prof_sample)} +}; + +static const ctl_named_node_t stats_arenas_i_metadata_node[] = { + {NAME("mapped"), CTL(stats_arenas_i_metadata_mapped)}, + {NAME("allocated"), CTL(stats_arenas_i_metadata_allocated)} +}; + +static const ctl_named_node_t stats_arenas_i_small_node[] = { + {NAME("allocated"), CTL(stats_arenas_i_small_allocated)}, + {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)}, + {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)}, + {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)} +}; + +static const ctl_named_node_t stats_arenas_i_large_node[] = { + {NAME("allocated"), CTL(stats_arenas_i_large_allocated)}, + {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)}, + {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)}, + {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)} +}; + +static const ctl_named_node_t stats_arenas_i_huge_node[] = { + {NAME("allocated"), CTL(stats_arenas_i_huge_allocated)}, + {NAME("nmalloc"), CTL(stats_arenas_i_huge_nmalloc)}, + {NAME("ndalloc"), CTL(stats_arenas_i_huge_ndalloc)}, + {NAME("nrequests"), CTL(stats_arenas_i_huge_nrequests)} +}; + +static const ctl_named_node_t stats_arenas_i_bins_j_node[] = { + {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)}, + {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)}, + {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)}, + {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)}, + {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)}, + {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)}, + {NAME("nruns"), CTL(stats_arenas_i_bins_j_nruns)}, + {NAME("nreruns"), CTL(stats_arenas_i_bins_j_nreruns)}, + {NAME("curruns"), CTL(stats_arenas_i_bins_j_curruns)} +}; +static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = { + {NAME(""), CHILD(named, stats_arenas_i_bins_j)} +}; + +static const ctl_indexed_node_t stats_arenas_i_bins_node[] = { + {INDEX(stats_arenas_i_bins_j)} +}; + +static const ctl_named_node_t stats_arenas_i_lruns_j_node[] = { + {NAME("nmalloc"), CTL(stats_arenas_i_lruns_j_nmalloc)}, + {NAME("ndalloc"), CTL(stats_arenas_i_lruns_j_ndalloc)}, + {NAME("nrequests"), CTL(stats_arenas_i_lruns_j_nrequests)}, + {NAME("curruns"), CTL(stats_arenas_i_lruns_j_curruns)} +}; +static const ctl_named_node_t super_stats_arenas_i_lruns_j_node[] = { + {NAME(""), CHILD(named, stats_arenas_i_lruns_j)} +}; + +static const ctl_indexed_node_t stats_arenas_i_lruns_node[] = { + {INDEX(stats_arenas_i_lruns_j)} +}; + +static const ctl_named_node_t stats_arenas_i_hchunks_j_node[] = { + {NAME("nmalloc"), CTL(stats_arenas_i_hchunks_j_nmalloc)}, + {NAME("ndalloc"), CTL(stats_arenas_i_hchunks_j_ndalloc)}, + {NAME("nrequests"), CTL(stats_arenas_i_hchunks_j_nrequests)}, + {NAME("curhchunks"), CTL(stats_arenas_i_hchunks_j_curhchunks)} +}; +static const ctl_named_node_t super_stats_arenas_i_hchunks_j_node[] = { + {NAME(""), CHILD(named, stats_arenas_i_hchunks_j)} +}; + +static const ctl_indexed_node_t stats_arenas_i_hchunks_node[] = { + {INDEX(stats_arenas_i_hchunks_j)} +}; + +static const ctl_named_node_t stats_arenas_i_node[] = { + {NAME("nthreads"), CTL(stats_arenas_i_nthreads)}, + {NAME("dss"), CTL(stats_arenas_i_dss)}, + {NAME("lg_dirty_mult"), CTL(stats_arenas_i_lg_dirty_mult)}, + {NAME("decay_time"), CTL(stats_arenas_i_decay_time)}, + {NAME("pactive"), CTL(stats_arenas_i_pactive)}, + {NAME("pdirty"), CTL(stats_arenas_i_pdirty)}, + {NAME("mapped"), CTL(stats_arenas_i_mapped)}, + {NAME("retained"), CTL(stats_arenas_i_retained)}, + {NAME("npurge"), CTL(stats_arenas_i_npurge)}, + {NAME("nmadvise"), CTL(stats_arenas_i_nmadvise)}, + {NAME("purged"), CTL(stats_arenas_i_purged)}, + {NAME("metadata"), CHILD(named, stats_arenas_i_metadata)}, + {NAME("small"), CHILD(named, stats_arenas_i_small)}, + {NAME("large"), CHILD(named, stats_arenas_i_large)}, + {NAME("huge"), CHILD(named, stats_arenas_i_huge)}, + {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)}, + {NAME("lruns"), CHILD(indexed, stats_arenas_i_lruns)}, + {NAME("hchunks"), CHILD(indexed, stats_arenas_i_hchunks)} +}; +static const ctl_named_node_t super_stats_arenas_i_node[] = { + {NAME(""), CHILD(named, stats_arenas_i)} +}; + +static const ctl_indexed_node_t stats_arenas_node[] = { + {INDEX(stats_arenas_i)} +}; + +static const ctl_named_node_t stats_node[] = { + {NAME("cactive"), CTL(stats_cactive)}, + {NAME("allocated"), CTL(stats_allocated)}, + {NAME("active"), CTL(stats_active)}, + {NAME("metadata"), CTL(stats_metadata)}, + {NAME("resident"), CTL(stats_resident)}, + {NAME("mapped"), CTL(stats_mapped)}, + {NAME("retained"), CTL(stats_retained)}, + {NAME("arenas"), CHILD(indexed, stats_arenas)} +}; + +static const ctl_named_node_t root_node[] = { + {NAME("version"), CTL(version)}, + {NAME("epoch"), CTL(epoch)}, + {NAME("thread"), CHILD(named, thread)}, + {NAME("config"), CHILD(named, config)}, + {NAME("opt"), CHILD(named, opt)}, + {NAME("tcache"), CHILD(named, tcache)}, + {NAME("arena"), CHILD(indexed, arena)}, + {NAME("arenas"), CHILD(named, arenas)}, + {NAME("prof"), CHILD(named, prof)}, + {NAME("stats"), CHILD(named, stats)} +}; +static const ctl_named_node_t super_root_node[] = { + {NAME(""), CHILD(named, root)} +}; + +#undef NAME +#undef CHILD +#undef CTL +#undef INDEX + +/******************************************************************************/ + +static bool +ctl_arena_init(ctl_arena_stats_t *astats) +{ + + if (astats->lstats == NULL) { + astats->lstats = (malloc_large_stats_t *)a0malloc(nlclasses * + sizeof(malloc_large_stats_t)); + if (astats->lstats == NULL) + return (true); + } + + if (astats->hstats == NULL) { + astats->hstats = (malloc_huge_stats_t *)a0malloc(nhclasses * + sizeof(malloc_huge_stats_t)); + if (astats->hstats == NULL) + return (true); + } + + return (false); +} + +static void +ctl_arena_clear(ctl_arena_stats_t *astats) +{ + + astats->nthreads = 0; + astats->dss = dss_prec_names[dss_prec_limit]; + astats->lg_dirty_mult = -1; + astats->decay_time = -1; + astats->pactive = 0; + astats->pdirty = 0; + if (config_stats) { + memset(&astats->astats, 0, sizeof(arena_stats_t)); + astats->allocated_small = 0; + astats->nmalloc_small = 0; + astats->ndalloc_small = 0; + astats->nrequests_small = 0; + memset(astats->bstats, 0, NBINS * sizeof(malloc_bin_stats_t)); + memset(astats->lstats, 0, nlclasses * + sizeof(malloc_large_stats_t)); + memset(astats->hstats, 0, nhclasses * + sizeof(malloc_huge_stats_t)); + } +} + +static void +ctl_arena_stats_amerge(tsdn_t *tsdn, ctl_arena_stats_t *cstats, arena_t *arena) +{ + unsigned i; + + if (config_stats) { + arena_stats_merge(tsdn, arena, &cstats->nthreads, &cstats->dss, + &cstats->lg_dirty_mult, &cstats->decay_time, + &cstats->pactive, &cstats->pdirty, &cstats->astats, + cstats->bstats, cstats->lstats, cstats->hstats); + + for (i = 0; i < NBINS; i++) { + cstats->allocated_small += cstats->bstats[i].curregs * + index2size(i); + cstats->nmalloc_small += cstats->bstats[i].nmalloc; + cstats->ndalloc_small += cstats->bstats[i].ndalloc; + cstats->nrequests_small += cstats->bstats[i].nrequests; + } + } else { + arena_basic_stats_merge(tsdn, arena, &cstats->nthreads, + &cstats->dss, &cstats->lg_dirty_mult, &cstats->decay_time, + &cstats->pactive, &cstats->pdirty); + } +} + +static void +ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, ctl_arena_stats_t *astats) +{ + unsigned i; + + sstats->nthreads += astats->nthreads; + sstats->pactive += astats->pactive; + sstats->pdirty += astats->pdirty; + + if (config_stats) { + sstats->astats.mapped += astats->astats.mapped; + sstats->astats.retained += astats->astats.retained; + sstats->astats.npurge += astats->astats.npurge; + sstats->astats.nmadvise += astats->astats.nmadvise; + sstats->astats.purged += astats->astats.purged; + + sstats->astats.metadata_mapped += + astats->astats.metadata_mapped; + sstats->astats.metadata_allocated += + astats->astats.metadata_allocated; + + sstats->allocated_small += astats->allocated_small; + sstats->nmalloc_small += astats->nmalloc_small; + sstats->ndalloc_small += astats->ndalloc_small; + sstats->nrequests_small += astats->nrequests_small; + + sstats->astats.allocated_large += + astats->astats.allocated_large; + sstats->astats.nmalloc_large += astats->astats.nmalloc_large; + sstats->astats.ndalloc_large += astats->astats.ndalloc_large; + sstats->astats.nrequests_large += + astats->astats.nrequests_large; + + sstats->astats.allocated_huge += astats->astats.allocated_huge; + sstats->astats.nmalloc_huge += astats->astats.nmalloc_huge; + sstats->astats.ndalloc_huge += astats->astats.ndalloc_huge; + + for (i = 0; i < NBINS; i++) { + sstats->bstats[i].nmalloc += astats->bstats[i].nmalloc; + sstats->bstats[i].ndalloc += astats->bstats[i].ndalloc; + sstats->bstats[i].nrequests += + astats->bstats[i].nrequests; + sstats->bstats[i].curregs += astats->bstats[i].curregs; + if (config_tcache) { + sstats->bstats[i].nfills += + astats->bstats[i].nfills; + sstats->bstats[i].nflushes += + astats->bstats[i].nflushes; + } + sstats->bstats[i].nruns += astats->bstats[i].nruns; + sstats->bstats[i].reruns += astats->bstats[i].reruns; + sstats->bstats[i].curruns += astats->bstats[i].curruns; + } + + for (i = 0; i < nlclasses; i++) { + sstats->lstats[i].nmalloc += astats->lstats[i].nmalloc; + sstats->lstats[i].ndalloc += astats->lstats[i].ndalloc; + sstats->lstats[i].nrequests += + astats->lstats[i].nrequests; + sstats->lstats[i].curruns += astats->lstats[i].curruns; + } + + for (i = 0; i < nhclasses; i++) { + sstats->hstats[i].nmalloc += astats->hstats[i].nmalloc; + sstats->hstats[i].ndalloc += astats->hstats[i].ndalloc; + sstats->hstats[i].curhchunks += + astats->hstats[i].curhchunks; + } + } +} + +static void +ctl_arena_refresh(tsdn_t *tsdn, arena_t *arena, unsigned i) +{ + ctl_arena_stats_t *astats = &ctl_stats.arenas[i]; + ctl_arena_stats_t *sstats = &ctl_stats.arenas[ctl_stats.narenas]; + + ctl_arena_clear(astats); + ctl_arena_stats_amerge(tsdn, astats, arena); + /* Merge into sum stats as well. */ + ctl_arena_stats_smerge(sstats, astats); +} + +static bool +ctl_grow(tsdn_t *tsdn) +{ + ctl_arena_stats_t *astats; + + /* Initialize new arena. */ + if (arena_init(tsdn, ctl_stats.narenas) == NULL) + return (true); + + /* Allocate extended arena stats. */ + astats = (ctl_arena_stats_t *)a0malloc((ctl_stats.narenas + 2) * + sizeof(ctl_arena_stats_t)); + if (astats == NULL) + return (true); + + /* Initialize the new astats element. */ + memcpy(astats, ctl_stats.arenas, (ctl_stats.narenas + 1) * + sizeof(ctl_arena_stats_t)); + memset(&astats[ctl_stats.narenas + 1], 0, sizeof(ctl_arena_stats_t)); + if (ctl_arena_init(&astats[ctl_stats.narenas + 1])) { + a0dalloc(astats); + return (true); + } + /* Swap merged stats to their new location. */ + { + ctl_arena_stats_t tstats; + memcpy(&tstats, &astats[ctl_stats.narenas], + sizeof(ctl_arena_stats_t)); + memcpy(&astats[ctl_stats.narenas], + &astats[ctl_stats.narenas + 1], sizeof(ctl_arena_stats_t)); + memcpy(&astats[ctl_stats.narenas + 1], &tstats, + sizeof(ctl_arena_stats_t)); + } + a0dalloc(ctl_stats.arenas); + ctl_stats.arenas = astats; + ctl_stats.narenas++; + + return (false); +} + +static void +ctl_refresh(tsdn_t *tsdn) +{ + unsigned i; + VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas); + + /* + * Clear sum stats, since they will be merged into by + * ctl_arena_refresh(). + */ + ctl_arena_clear(&ctl_stats.arenas[ctl_stats.narenas]); + + for (i = 0; i < ctl_stats.narenas; i++) + tarenas[i] = arena_get(tsdn, i, false); + + for (i = 0; i < ctl_stats.narenas; i++) { + bool initialized = (tarenas[i] != NULL); + + ctl_stats.arenas[i].initialized = initialized; + if (initialized) + ctl_arena_refresh(tsdn, tarenas[i], i); + } + + if (config_stats) { + size_t base_allocated, base_resident, base_mapped; + base_stats_get(tsdn, &base_allocated, &base_resident, + &base_mapped); + ctl_stats.allocated = + ctl_stats.arenas[ctl_stats.narenas].allocated_small + + ctl_stats.arenas[ctl_stats.narenas].astats.allocated_large + + ctl_stats.arenas[ctl_stats.narenas].astats.allocated_huge; + ctl_stats.active = + (ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE); + ctl_stats.metadata = base_allocated + + ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped + + ctl_stats.arenas[ctl_stats.narenas].astats + .metadata_allocated; + ctl_stats.resident = base_resident + + ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped + + ((ctl_stats.arenas[ctl_stats.narenas].pactive + + ctl_stats.arenas[ctl_stats.narenas].pdirty) << LG_PAGE); + ctl_stats.mapped = base_mapped + + ctl_stats.arenas[ctl_stats.narenas].astats.mapped; + ctl_stats.retained = + ctl_stats.arenas[ctl_stats.narenas].astats.retained; + } + + ctl_epoch++; +} + +static bool +ctl_init(tsdn_t *tsdn) +{ + bool ret; + + malloc_mutex_lock(tsdn, &ctl_mtx); + if (!ctl_initialized) { + /* + * Allocate space for one extra arena stats element, which + * contains summed stats across all arenas. + */ + ctl_stats.narenas = narenas_total_get(); + ctl_stats.arenas = (ctl_arena_stats_t *)a0malloc( + (ctl_stats.narenas + 1) * sizeof(ctl_arena_stats_t)); + if (ctl_stats.arenas == NULL) { + ret = true; + goto label_return; + } + memset(ctl_stats.arenas, 0, (ctl_stats.narenas + 1) * + sizeof(ctl_arena_stats_t)); + + /* + * Initialize all stats structures, regardless of whether they + * ever get used. Lazy initialization would allow errors to + * cause inconsistent state to be viewable by the application. + */ + if (config_stats) { + unsigned i; + for (i = 0; i <= ctl_stats.narenas; i++) { + if (ctl_arena_init(&ctl_stats.arenas[i])) { + unsigned j; + for (j = 0; j < i; j++) { + a0dalloc( + ctl_stats.arenas[j].lstats); + a0dalloc( + ctl_stats.arenas[j].hstats); + } + a0dalloc(ctl_stats.arenas); + ctl_stats.arenas = NULL; + ret = true; + goto label_return; + } + } + } + ctl_stats.arenas[ctl_stats.narenas].initialized = true; + + ctl_epoch = 0; + ctl_refresh(tsdn); + ctl_initialized = true; + } + + ret = false; +label_return: + malloc_mutex_unlock(tsdn, &ctl_mtx); + return (ret); +} + +static int +ctl_lookup(tsdn_t *tsdn, const char *name, ctl_node_t const **nodesp, + size_t *mibp, size_t *depthp) +{ + int ret; + const char *elm, *tdot, *dot; + size_t elen, i, j; + const ctl_named_node_t *node; + + elm = name; + /* Equivalent to strchrnul(). */ + dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0'); + elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); + if (elen == 0) { + ret = ENOENT; + goto label_return; + } + node = super_root_node; + for (i = 0; i < *depthp; i++) { + assert(node); + assert(node->nchildren > 0); + if (ctl_named_node(node->children) != NULL) { + const ctl_named_node_t *pnode = node; + + /* Children are named. */ + for (j = 0; j < node->nchildren; j++) { + const ctl_named_node_t *child = + ctl_named_children(node, j); + if (strlen(child->name) == elen && + strncmp(elm, child->name, elen) == 0) { + node = child; + if (nodesp != NULL) + nodesp[i] = + (const ctl_node_t *)node; + mibp[i] = j; + break; + } + } + if (node == pnode) { + ret = ENOENT; + goto label_return; + } + } else { + uintmax_t index; + const ctl_indexed_node_t *inode; + + /* Children are indexed. */ + index = malloc_strtoumax(elm, NULL, 10); + if (index == UINTMAX_MAX || index > SIZE_T_MAX) { + ret = ENOENT; + goto label_return; + } + + inode = ctl_indexed_node(node->children); + node = inode->index(tsdn, mibp, *depthp, (size_t)index); + if (node == NULL) { + ret = ENOENT; + goto label_return; + } + + if (nodesp != NULL) + nodesp[i] = (const ctl_node_t *)node; + mibp[i] = (size_t)index; + } + + if (node->ctl != NULL) { + /* Terminal node. */ + if (*dot != '\0') { + /* + * The name contains more elements than are + * in this path through the tree. + */ + ret = ENOENT; + goto label_return; + } + /* Complete lookup successful. */ + *depthp = i + 1; + break; + } + + /* Update elm. */ + if (*dot == '\0') { + /* No more elements. */ + ret = ENOENT; + goto label_return; + } + elm = &dot[1]; + dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : + strchr(elm, '\0'); + elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); + } + + ret = 0; +label_return: + return (ret); +} + +int +ctl_byname(tsd_t *tsd, const char *name, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + size_t depth; + ctl_node_t const *nodes[CTL_MAX_DEPTH]; + size_t mib[CTL_MAX_DEPTH]; + const ctl_named_node_t *node; + + if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) { + ret = EAGAIN; + goto label_return; + } + + depth = CTL_MAX_DEPTH; + ret = ctl_lookup(tsd_tsdn(tsd), name, nodes, mib, &depth); + if (ret != 0) + goto label_return; + + node = ctl_named_node(nodes[depth-1]); + if (node != NULL && node->ctl) + ret = node->ctl(tsd, mib, depth, oldp, oldlenp, newp, newlen); + else { + /* The name refers to a partial path through the ctl tree. */ + ret = ENOENT; + } + +label_return: + return(ret); +} + +int +ctl_nametomib(tsdn_t *tsdn, const char *name, size_t *mibp, size_t *miblenp) +{ + int ret; + + if (!ctl_initialized && ctl_init(tsdn)) { + ret = EAGAIN; + goto label_return; + } + + ret = ctl_lookup(tsdn, name, NULL, mibp, miblenp); +label_return: + return(ret); +} + +int +ctl_bymib(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + const ctl_named_node_t *node; + size_t i; + + if (!ctl_initialized && ctl_init(tsd_tsdn(tsd))) { + ret = EAGAIN; + goto label_return; + } + + /* Iterate down the tree. */ + node = super_root_node; + for (i = 0; i < miblen; i++) { + assert(node); + assert(node->nchildren > 0); + if (ctl_named_node(node->children) != NULL) { + /* Children are named. */ + if (node->nchildren <= (unsigned)mib[i]) { + ret = ENOENT; + goto label_return; + } + node = ctl_named_children(node, mib[i]); + } else { + const ctl_indexed_node_t *inode; + + /* Indexed element. */ + inode = ctl_indexed_node(node->children); + node = inode->index(tsd_tsdn(tsd), mib, miblen, mib[i]); + if (node == NULL) { + ret = ENOENT; + goto label_return; + } + } + } + + /* Call the ctl function. */ + if (node && node->ctl) + ret = node->ctl(tsd, mib, miblen, oldp, oldlenp, newp, newlen); + else { + /* Partial MIB. */ + ret = ENOENT; + } + +label_return: + return(ret); +} + +bool +ctl_boot(void) +{ + + if (malloc_mutex_init(&ctl_mtx, "ctl", WITNESS_RANK_CTL)) + return (true); + + ctl_initialized = false; + + return (false); +} + +void +ctl_prefork(tsdn_t *tsdn) +{ + + malloc_mutex_prefork(tsdn, &ctl_mtx); +} + +void +ctl_postfork_parent(tsdn_t *tsdn) +{ + + malloc_mutex_postfork_parent(tsdn, &ctl_mtx); +} + +void +ctl_postfork_child(tsdn_t *tsdn) +{ + + malloc_mutex_postfork_child(tsdn, &ctl_mtx); +} + +/******************************************************************************/ +/* *_ctl() functions. */ + +#define READONLY() do { \ + if (newp != NULL || newlen != 0) { \ + ret = EPERM; \ + goto label_return; \ + } \ +} while (0) + +#define WRITEONLY() do { \ + if (oldp != NULL || oldlenp != NULL) { \ + ret = EPERM; \ + goto label_return; \ + } \ +} while (0) + +#define READ_XOR_WRITE() do { \ + if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \ + newlen != 0)) { \ + ret = EPERM; \ + goto label_return; \ + } \ +} while (0) + +#define READ(v, t) do { \ + if (oldp != NULL && oldlenp != NULL) { \ + if (*oldlenp != sizeof(t)) { \ + size_t copylen = (sizeof(t) <= *oldlenp) \ + ? sizeof(t) : *oldlenp; \ + memcpy(oldp, (void *)&(v), copylen); \ + ret = EINVAL; \ + goto label_return; \ + } \ + *(t *)oldp = (v); \ + } \ +} while (0) + +#define WRITE(v, t) do { \ + if (newp != NULL) { \ + if (newlen != sizeof(t)) { \ + ret = EINVAL; \ + goto label_return; \ + } \ + (v) = *(t *)newp; \ + } \ +} while (0) + +/* + * There's a lot of code duplication in the following macros due to limitations + * in how nested cpp macros are expanded. + */ +#define CTL_RO_CLGEN(c, l, n, v, t) \ +static int \ +n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ + size_t *oldlenp, void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + if (!(c)) \ + return (ENOENT); \ + if (l) \ + malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \ + READONLY(); \ + oldval = (v); \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + if (l) \ + malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \ + return (ret); \ +} + +#define CTL_RO_CGEN(c, n, v, t) \ +static int \ +n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ + size_t *oldlenp, void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + if (!(c)) \ + return (ENOENT); \ + malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \ + READONLY(); \ + oldval = (v); \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \ + return (ret); \ +} + +#define CTL_RO_GEN(n, v, t) \ +static int \ +n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ + size_t *oldlenp, void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); \ + READONLY(); \ + oldval = (v); \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); \ + return (ret); \ +} + +/* + * ctl_mtx is not acquired, under the assumption that no pertinent data will + * mutate during the call. + */ +#define CTL_RO_NL_CGEN(c, n, v, t) \ +static int \ +n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ + size_t *oldlenp, void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + if (!(c)) \ + return (ENOENT); \ + READONLY(); \ + oldval = (v); \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + return (ret); \ +} + +#define CTL_RO_NL_GEN(n, v, t) \ +static int \ +n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ + size_t *oldlenp, void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + READONLY(); \ + oldval = (v); \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + return (ret); \ +} + +#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \ +static int \ +n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ + size_t *oldlenp, void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + if (!(c)) \ + return (ENOENT); \ + READONLY(); \ + oldval = (m(tsd)); \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + return (ret); \ +} + +#define CTL_RO_CONFIG_GEN(n, t) \ +static int \ +n##_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, \ + size_t *oldlenp, void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + READONLY(); \ + oldval = n; \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + return (ret); \ +} + +/******************************************************************************/ + +CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *) + +static int +epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + UNUSED uint64_t newval; + + malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); + WRITE(newval, uint64_t); + if (newp != NULL) + ctl_refresh(tsd_tsdn(tsd)); + READ(ctl_epoch, uint64_t); + + ret = 0; +label_return: + malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); + return (ret); +} + +/******************************************************************************/ + +CTL_RO_CONFIG_GEN(config_cache_oblivious, bool) +CTL_RO_CONFIG_GEN(config_debug, bool) +CTL_RO_CONFIG_GEN(config_fill, bool) +CTL_RO_CONFIG_GEN(config_lazy_lock, bool) +CTL_RO_CONFIG_GEN(config_malloc_conf, const char *) +CTL_RO_CONFIG_GEN(config_munmap, bool) +CTL_RO_CONFIG_GEN(config_prof, bool) +CTL_RO_CONFIG_GEN(config_prof_libgcc, bool) +CTL_RO_CONFIG_GEN(config_prof_libunwind, bool) +CTL_RO_CONFIG_GEN(config_stats, bool) +CTL_RO_CONFIG_GEN(config_tcache, bool) +CTL_RO_CONFIG_GEN(config_tls, bool) +CTL_RO_CONFIG_GEN(config_utrace, bool) +CTL_RO_CONFIG_GEN(config_valgrind, bool) +CTL_RO_CONFIG_GEN(config_xmalloc, bool) + +/******************************************************************************/ + +CTL_RO_NL_GEN(opt_abort, opt_abort, bool) +CTL_RO_NL_GEN(opt_dss, opt_dss, const char *) +CTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t) +CTL_RO_NL_GEN(opt_narenas, opt_narenas, unsigned) +CTL_RO_NL_GEN(opt_purge, purge_mode_names[opt_purge], const char *) +CTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t) +CTL_RO_NL_GEN(opt_decay_time, opt_decay_time, ssize_t) +CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool) +CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *) +CTL_RO_NL_CGEN(config_fill, opt_quarantine, opt_quarantine, size_t) +CTL_RO_NL_CGEN(config_fill, opt_redzone, opt_redzone, bool) +CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool) +CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool) +CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool) +CTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool) +CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t) +CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool) +CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *) +CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool) +CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init, + opt_prof_thread_active_init, bool) +CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t) +CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool) +CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t) +CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool) +CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool) +CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool) + +/******************************************************************************/ + +static int +thread_arena_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + arena_t *oldarena; + unsigned newind, oldind; + + oldarena = arena_choose(tsd, NULL); + if (oldarena == NULL) + return (EAGAIN); + + malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); + newind = oldind = oldarena->ind; + WRITE(newind, unsigned); + READ(oldind, unsigned); + if (newind != oldind) { + arena_t *newarena; + + if (newind >= ctl_stats.narenas) { + /* New arena index is out of range. */ + ret = EFAULT; + goto label_return; + } + + /* Initialize arena if necessary. */ + newarena = arena_get(tsd_tsdn(tsd), newind, true); + if (newarena == NULL) { + ret = EAGAIN; + goto label_return; + } + /* Set new arena/tcache associations. */ + arena_migrate(tsd, oldind, newind); + if (config_tcache) { + tcache_t *tcache = tsd_tcache_get(tsd); + if (tcache != NULL) { + tcache_arena_reassociate(tsd_tsdn(tsd), tcache, + oldarena, newarena); + } + } + } + + ret = 0; +label_return: + malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); + return (ret); +} + +CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get, + uint64_t) +CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get, + uint64_t *) +CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get, + uint64_t) +CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp, + tsd_thread_deallocatedp_get, uint64_t *) + +static int +thread_tcache_enabled_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, + void *oldp, size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + bool oldval; + + if (!config_tcache) + return (ENOENT); + + oldval = tcache_enabled_get(); + if (newp != NULL) { + if (newlen != sizeof(bool)) { + ret = EINVAL; + goto label_return; + } + tcache_enabled_set(*(bool *)newp); + } + READ(oldval, bool); + + ret = 0; +label_return: + return (ret); +} + +static int +thread_tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, + void *oldp, size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + + if (!config_tcache) + return (ENOENT); + + READONLY(); + WRITEONLY(); + + tcache_flush(); + + ret = 0; +label_return: + return (ret); +} + +static int +thread_prof_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + + if (!config_prof) + return (ENOENT); + + READ_XOR_WRITE(); + + if (newp != NULL) { + if (newlen != sizeof(const char *)) { + ret = EINVAL; + goto label_return; + } + + if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) != + 0) + goto label_return; + } else { + const char *oldname = prof_thread_name_get(tsd); + READ(oldname, const char *); + } + + ret = 0; +label_return: + return (ret); +} + +static int +thread_prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + bool oldval; + + if (!config_prof) + return (ENOENT); + + oldval = prof_thread_active_get(tsd); + if (newp != NULL) { + if (newlen != sizeof(bool)) { + ret = EINVAL; + goto label_return; + } + if (prof_thread_active_set(tsd, *(bool *)newp)) { + ret = EAGAIN; + goto label_return; + } + } + READ(oldval, bool); + + ret = 0; +label_return: + return (ret); +} + +/******************************************************************************/ + +static int +tcache_create_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned tcache_ind; + + if (!config_tcache) + return (ENOENT); + + malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); + READONLY(); + if (tcaches_create(tsd_tsdn(tsd), &tcache_ind)) { + ret = EFAULT; + goto label_return; + } + READ(tcache_ind, unsigned); + + ret = 0; +label_return: + malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); + return (ret); +} + +static int +tcache_flush_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned tcache_ind; + + if (!config_tcache) + return (ENOENT); + + WRITEONLY(); + tcache_ind = UINT_MAX; + WRITE(tcache_ind, unsigned); + if (tcache_ind == UINT_MAX) { + ret = EFAULT; + goto label_return; + } + tcaches_flush(tsd, tcache_ind); + + ret = 0; +label_return: + return (ret); +} + +static int +tcache_destroy_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned tcache_ind; + + if (!config_tcache) + return (ENOENT); + + WRITEONLY(); + tcache_ind = UINT_MAX; + WRITE(tcache_ind, unsigned); + if (tcache_ind == UINT_MAX) { + ret = EFAULT; + goto label_return; + } + tcaches_destroy(tsd, tcache_ind); + + ret = 0; +label_return: + return (ret); +} + +/******************************************************************************/ + +static void +arena_i_purge(tsdn_t *tsdn, unsigned arena_ind, bool all) +{ + + malloc_mutex_lock(tsdn, &ctl_mtx); + { + unsigned narenas = ctl_stats.narenas; + + if (arena_ind == narenas) { + unsigned i; + VARIABLE_ARRAY(arena_t *, tarenas, narenas); + + for (i = 0; i < narenas; i++) + tarenas[i] = arena_get(tsdn, i, false); + + /* + * No further need to hold ctl_mtx, since narenas and + * tarenas contain everything needed below. + */ + malloc_mutex_unlock(tsdn, &ctl_mtx); + + for (i = 0; i < narenas; i++) { + if (tarenas[i] != NULL) + arena_purge(tsdn, tarenas[i], all); + } + } else { + arena_t *tarena; + + assert(arena_ind < narenas); + + tarena = arena_get(tsdn, arena_ind, false); + + /* No further need to hold ctl_mtx. */ + malloc_mutex_unlock(tsdn, &ctl_mtx); + + if (tarena != NULL) + arena_purge(tsdn, tarena, all); + } + } +} + +static int +arena_i_purge_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + + READONLY(); + WRITEONLY(); + arena_i_purge(tsd_tsdn(tsd), (unsigned)mib[1], true); + + ret = 0; +label_return: + return (ret); +} + +static int +arena_i_decay_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + + READONLY(); + WRITEONLY(); + arena_i_purge(tsd_tsdn(tsd), (unsigned)mib[1], false); + + ret = 0; +label_return: + return (ret); +} + +static int +arena_i_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned arena_ind; + arena_t *arena; + + READONLY(); + WRITEONLY(); + + if ((config_valgrind && unlikely(in_valgrind)) || (config_fill && + unlikely(opt_quarantine))) { + ret = EFAULT; + goto label_return; + } + + arena_ind = (unsigned)mib[1]; + if (config_debug) { + malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); + assert(arena_ind < ctl_stats.narenas); + malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); + } + assert(arena_ind >= opt_narenas); + + arena = arena_get(tsd_tsdn(tsd), arena_ind, false); + + arena_reset(tsd, arena); + + ret = 0; +label_return: + return (ret); +} + +static int +arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + const char *dss = NULL; + unsigned arena_ind = (unsigned)mib[1]; + dss_prec_t dss_prec_old = dss_prec_limit; + dss_prec_t dss_prec = dss_prec_limit; + + malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); + WRITE(dss, const char *); + if (dss != NULL) { + int i; + bool match = false; + + for (i = 0; i < dss_prec_limit; i++) { + if (strcmp(dss_prec_names[i], dss) == 0) { + dss_prec = i; + match = true; + break; + } + } + + if (!match) { + ret = EINVAL; + goto label_return; + } + } + + if (arena_ind < ctl_stats.narenas) { + arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false); + if (arena == NULL || (dss_prec != dss_prec_limit && + arena_dss_prec_set(tsd_tsdn(tsd), arena, dss_prec))) { + ret = EFAULT; + goto label_return; + } + dss_prec_old = arena_dss_prec_get(tsd_tsdn(tsd), arena); + } else { + if (dss_prec != dss_prec_limit && + chunk_dss_prec_set(tsd_tsdn(tsd), dss_prec)) { + ret = EFAULT; + goto label_return; + } + dss_prec_old = chunk_dss_prec_get(tsd_tsdn(tsd)); + } + + dss = dss_prec_names[dss_prec_old]; + READ(dss, const char *); + + ret = 0; +label_return: + malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); + return (ret); +} + +static int +arena_i_lg_dirty_mult_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, + void *oldp, size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned arena_ind = (unsigned)mib[1]; + arena_t *arena; + + arena = arena_get(tsd_tsdn(tsd), arena_ind, false); + if (arena == NULL) { + ret = EFAULT; + goto label_return; + } + + if (oldp != NULL && oldlenp != NULL) { + size_t oldval = arena_lg_dirty_mult_get(tsd_tsdn(tsd), arena); + READ(oldval, ssize_t); + } + if (newp != NULL) { + if (newlen != sizeof(ssize_t)) { + ret = EINVAL; + goto label_return; + } + if (arena_lg_dirty_mult_set(tsd_tsdn(tsd), arena, + *(ssize_t *)newp)) { + ret = EFAULT; + goto label_return; + } + } + + ret = 0; +label_return: + return (ret); +} + +static int +arena_i_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned arena_ind = (unsigned)mib[1]; + arena_t *arena; + + arena = arena_get(tsd_tsdn(tsd), arena_ind, false); + if (arena == NULL) { + ret = EFAULT; + goto label_return; + } + + if (oldp != NULL && oldlenp != NULL) { + size_t oldval = arena_decay_time_get(tsd_tsdn(tsd), arena); + READ(oldval, ssize_t); + } + if (newp != NULL) { + if (newlen != sizeof(ssize_t)) { + ret = EINVAL; + goto label_return; + } + if (arena_decay_time_set(tsd_tsdn(tsd), arena, + *(ssize_t *)newp)) { + ret = EFAULT; + goto label_return; + } + } + + ret = 0; +label_return: + return (ret); +} + +static int +arena_i_chunk_hooks_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, + void *oldp, size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned arena_ind = (unsigned)mib[1]; + arena_t *arena; + + malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); + if (arena_ind < narenas_total_get() && (arena = + arena_get(tsd_tsdn(tsd), arena_ind, false)) != NULL) { + if (newp != NULL) { + chunk_hooks_t old_chunk_hooks, new_chunk_hooks; + WRITE(new_chunk_hooks, chunk_hooks_t); + old_chunk_hooks = chunk_hooks_set(tsd_tsdn(tsd), arena, + &new_chunk_hooks); + READ(old_chunk_hooks, chunk_hooks_t); + } else { + chunk_hooks_t old_chunk_hooks = + chunk_hooks_get(tsd_tsdn(tsd), arena); + READ(old_chunk_hooks, chunk_hooks_t); + } + } else { + ret = EFAULT; + goto label_return; + } + ret = 0; +label_return: + malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); + return (ret); +} + +static const ctl_named_node_t * +arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) +{ + const ctl_named_node_t *ret; + + malloc_mutex_lock(tsdn, &ctl_mtx); + if (i > ctl_stats.narenas) { + ret = NULL; + goto label_return; + } + + ret = super_arena_i_node; +label_return: + malloc_mutex_unlock(tsdn, &ctl_mtx); + return (ret); +} + +/******************************************************************************/ + +static int +arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned narenas; + + malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); + READONLY(); + if (*oldlenp != sizeof(unsigned)) { + ret = EINVAL; + goto label_return; + } + narenas = ctl_stats.narenas; + READ(narenas, unsigned); + + ret = 0; +label_return: + malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); + return (ret); +} + +static int +arenas_initialized_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned nread, i; + + malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); + READONLY(); + if (*oldlenp != ctl_stats.narenas * sizeof(bool)) { + ret = EINVAL; + nread = (*oldlenp < ctl_stats.narenas * sizeof(bool)) + ? (unsigned)(*oldlenp / sizeof(bool)) : ctl_stats.narenas; + } else { + ret = 0; + nread = ctl_stats.narenas; + } + + for (i = 0; i < nread; i++) + ((bool *)oldp)[i] = ctl_stats.arenas[i].initialized; + +label_return: + malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); + return (ret); +} + +static int +arenas_lg_dirty_mult_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, + void *oldp, size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + + if (oldp != NULL && oldlenp != NULL) { + size_t oldval = arena_lg_dirty_mult_default_get(); + READ(oldval, ssize_t); + } + if (newp != NULL) { + if (newlen != sizeof(ssize_t)) { + ret = EINVAL; + goto label_return; + } + if (arena_lg_dirty_mult_default_set(*(ssize_t *)newp)) { + ret = EFAULT; + goto label_return; + } + } + + ret = 0; +label_return: + return (ret); +} + +static int +arenas_decay_time_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + + if (oldp != NULL && oldlenp != NULL) { + size_t oldval = arena_decay_time_default_get(); + READ(oldval, ssize_t); + } + if (newp != NULL) { + if (newlen != sizeof(ssize_t)) { + ret = EINVAL; + goto label_return; + } + if (arena_decay_time_default_set(*(ssize_t *)newp)) { + ret = EFAULT; + goto label_return; + } + } + + ret = 0; +label_return: + return (ret); +} + +CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t) +CTL_RO_NL_GEN(arenas_page, PAGE, size_t) +CTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t) +CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned) +CTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned) +CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t) +CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t) +CTL_RO_NL_GEN(arenas_bin_i_run_size, arena_bin_info[mib[2]].run_size, size_t) +static const ctl_named_node_t * +arenas_bin_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) +{ + + if (i > NBINS) + return (NULL); + return (super_arenas_bin_i_node); +} + +CTL_RO_NL_GEN(arenas_nlruns, nlclasses, unsigned) +CTL_RO_NL_GEN(arenas_lrun_i_size, index2size(NBINS+(szind_t)mib[2]), size_t) +static const ctl_named_node_t * +arenas_lrun_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) +{ + + if (i > nlclasses) + return (NULL); + return (super_arenas_lrun_i_node); +} + +CTL_RO_NL_GEN(arenas_nhchunks, nhclasses, unsigned) +CTL_RO_NL_GEN(arenas_hchunk_i_size, index2size(NBINS+nlclasses+(szind_t)mib[2]), + size_t) +static const ctl_named_node_t * +arenas_hchunk_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) +{ + + if (i > nhclasses) + return (NULL); + return (super_arenas_hchunk_i_node); +} + +static int +arenas_extend_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned narenas; + + malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx); + READONLY(); + if (ctl_grow(tsd_tsdn(tsd))) { + ret = EAGAIN; + goto label_return; + } + narenas = ctl_stats.narenas - 1; + READ(narenas, unsigned); + + ret = 0; +label_return: + malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx); + return (ret); +} + +/******************************************************************************/ + +static int +prof_thread_active_init_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, + void *oldp, size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + bool oldval; + + if (!config_prof) + return (ENOENT); + + if (newp != NULL) { + if (newlen != sizeof(bool)) { + ret = EINVAL; + goto label_return; + } + oldval = prof_thread_active_init_set(tsd_tsdn(tsd), + *(bool *)newp); + } else + oldval = prof_thread_active_init_get(tsd_tsdn(tsd)); + READ(oldval, bool); + + ret = 0; +label_return: + return (ret); +} + +static int +prof_active_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + bool oldval; + + if (!config_prof) + return (ENOENT); + + if (newp != NULL) { + if (newlen != sizeof(bool)) { + ret = EINVAL; + goto label_return; + } + oldval = prof_active_set(tsd_tsdn(tsd), *(bool *)newp); + } else + oldval = prof_active_get(tsd_tsdn(tsd)); + READ(oldval, bool); + + ret = 0; +label_return: + return (ret); +} + +static int +prof_dump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + const char *filename = NULL; + + if (!config_prof) + return (ENOENT); + + WRITEONLY(); + WRITE(filename, const char *); + + if (prof_mdump(tsd, filename)) { + ret = EFAULT; + goto label_return; + } + + ret = 0; +label_return: + return (ret); +} + +static int +prof_gdump_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + bool oldval; + + if (!config_prof) + return (ENOENT); + + if (newp != NULL) { + if (newlen != sizeof(bool)) { + ret = EINVAL; + goto label_return; + } + oldval = prof_gdump_set(tsd_tsdn(tsd), *(bool *)newp); + } else + oldval = prof_gdump_get(tsd_tsdn(tsd)); + READ(oldval, bool); + + ret = 0; +label_return: + return (ret); +} + +static int +prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + size_t lg_sample = lg_prof_sample; + + if (!config_prof) + return (ENOENT); + + WRITEONLY(); + WRITE(lg_sample, size_t); + if (lg_sample >= (sizeof(uint64_t) << 3)) + lg_sample = (sizeof(uint64_t) << 3) - 1; + + prof_reset(tsd_tsdn(tsd), lg_sample); + + ret = 0; +label_return: + return (ret); +} + +CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t) +CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t) + +/******************************************************************************/ + +CTL_RO_CGEN(config_stats, stats_cactive, &stats_cactive, size_t *) +CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t) +CTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t) +CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats.metadata, size_t) +CTL_RO_CGEN(config_stats, stats_resident, ctl_stats.resident, size_t) +CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t) +CTL_RO_CGEN(config_stats, stats_retained, ctl_stats.retained, size_t) + +CTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *) +CTL_RO_GEN(stats_arenas_i_lg_dirty_mult, ctl_stats.arenas[mib[2]].lg_dirty_mult, + ssize_t) +CTL_RO_GEN(stats_arenas_i_decay_time, ctl_stats.arenas[mib[2]].decay_time, + ssize_t) +CTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned) +CTL_RO_GEN(stats_arenas_i_pactive, ctl_stats.arenas[mib[2]].pactive, size_t) +CTL_RO_GEN(stats_arenas_i_pdirty, ctl_stats.arenas[mib[2]].pdirty, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_mapped, + ctl_stats.arenas[mib[2]].astats.mapped, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_retained, + ctl_stats.arenas[mib[2]].astats.retained, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_npurge, + ctl_stats.arenas[mib[2]].astats.npurge, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise, + ctl_stats.arenas[mib[2]].astats.nmadvise, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_purged, + ctl_stats.arenas[mib[2]].astats.purged, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_mapped, + ctl_stats.arenas[mib[2]].astats.metadata_mapped, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_allocated, + ctl_stats.arenas[mib[2]].astats.metadata_allocated, size_t) + +CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated, + ctl_stats.arenas[mib[2]].allocated_small, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc, + ctl_stats.arenas[mib[2]].nmalloc_small, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc, + ctl_stats.arenas[mib[2]].ndalloc_small, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests, + ctl_stats.arenas[mib[2]].nrequests_small, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated, + ctl_stats.arenas[mib[2]].astats.allocated_large, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc, + ctl_stats.arenas[mib[2]].astats.nmalloc_large, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc, + ctl_stats.arenas[mib[2]].astats.ndalloc_large, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests, + ctl_stats.arenas[mib[2]].astats.nrequests_large, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_huge_allocated, + ctl_stats.arenas[mib[2]].astats.allocated_huge, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_huge_nmalloc, + ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_huge_ndalloc, + ctl_stats.arenas[mib[2]].astats.ndalloc_huge, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_huge_nrequests, + ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) /* Intentional. */ + +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc, + ctl_stats.arenas[mib[2]].bstats[mib[4]].nmalloc, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc, + ctl_stats.arenas[mib[2]].bstats[mib[4]].ndalloc, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests, + ctl_stats.arenas[mib[2]].bstats[mib[4]].nrequests, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs, + ctl_stats.arenas[mib[2]].bstats[mib[4]].curregs, size_t) +CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills, + ctl_stats.arenas[mib[2]].bstats[mib[4]].nfills, uint64_t) +CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes, + ctl_stats.arenas[mib[2]].bstats[mib[4]].nflushes, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nruns, + ctl_stats.arenas[mib[2]].bstats[mib[4]].nruns, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreruns, + ctl_stats.arenas[mib[2]].bstats[mib[4]].reruns, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curruns, + ctl_stats.arenas[mib[2]].bstats[mib[4]].curruns, size_t) + +static const ctl_named_node_t * +stats_arenas_i_bins_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, + size_t j) +{ + + if (j > NBINS) + return (NULL); + return (super_stats_arenas_i_bins_j_node); +} + +CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nmalloc, + ctl_stats.arenas[mib[2]].lstats[mib[4]].nmalloc, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_ndalloc, + ctl_stats.arenas[mib[2]].lstats[mib[4]].ndalloc, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nrequests, + ctl_stats.arenas[mib[2]].lstats[mib[4]].nrequests, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_curruns, + ctl_stats.arenas[mib[2]].lstats[mib[4]].curruns, size_t) + +static const ctl_named_node_t * +stats_arenas_i_lruns_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, + size_t j) +{ + + if (j > nlclasses) + return (NULL); + return (super_stats_arenas_i_lruns_j_node); +} + +CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nmalloc, + ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_ndalloc, + ctl_stats.arenas[mib[2]].hstats[mib[4]].ndalloc, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nrequests, + ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, /* Intentional. */ + uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_curhchunks, + ctl_stats.arenas[mib[2]].hstats[mib[4]].curhchunks, size_t) + +static const ctl_named_node_t * +stats_arenas_i_hchunks_j_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, + size_t j) +{ + + if (j > nhclasses) + return (NULL); + return (super_stats_arenas_i_hchunks_j_node); +} + +static const ctl_named_node_t * +stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) +{ + const ctl_named_node_t * ret; + + malloc_mutex_lock(tsdn, &ctl_mtx); + if (i > ctl_stats.narenas || !ctl_stats.arenas[i].initialized) { + ret = NULL; + goto label_return; + } + + ret = super_stats_arenas_i_node; +label_return: + malloc_mutex_unlock(tsdn, &ctl_mtx); + return (ret); +} diff --git a/contrib/jemalloc/src/extent.c b/contrib/jemalloc/src/extent.c new file mode 100644 index 0000000..9f5146e --- /dev/null +++ b/contrib/jemalloc/src/extent.c @@ -0,0 +1,53 @@ +#define JEMALLOC_EXTENT_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ + +JEMALLOC_INLINE_C size_t +extent_quantize(size_t size) +{ + + /* + * Round down to the nearest chunk size that can actually be requested + * during normal huge allocation. + */ + return (index2size(size2index(size + 1) - 1)); +} + +JEMALLOC_INLINE_C int +extent_szad_comp(const extent_node_t *a, const extent_node_t *b) +{ + int ret; + size_t a_qsize = extent_quantize(extent_node_size_get(a)); + size_t b_qsize = extent_quantize(extent_node_size_get(b)); + + /* + * Compare based on quantized size rather than size, in order to sort + * equally useful extents only by address. + */ + ret = (a_qsize > b_qsize) - (a_qsize < b_qsize); + if (ret == 0) { + uintptr_t a_addr = (uintptr_t)extent_node_addr_get(a); + uintptr_t b_addr = (uintptr_t)extent_node_addr_get(b); + + ret = (a_addr > b_addr) - (a_addr < b_addr); + } + + return (ret); +} + +/* Generate red-black tree functions. */ +rb_gen(, extent_tree_szad_, extent_tree_t, extent_node_t, szad_link, + extent_szad_comp) + +JEMALLOC_INLINE_C int +extent_ad_comp(const extent_node_t *a, const extent_node_t *b) +{ + uintptr_t a_addr = (uintptr_t)extent_node_addr_get(a); + uintptr_t b_addr = (uintptr_t)extent_node_addr_get(b); + + return ((a_addr > b_addr) - (a_addr < b_addr)); +} + +/* Generate red-black tree functions. */ +rb_gen(, extent_tree_ad_, extent_tree_t, extent_node_t, ad_link, extent_ad_comp) diff --git a/contrib/jemalloc/src/hash.c b/contrib/jemalloc/src/hash.c new file mode 100644 index 0000000..cfa4da0 --- /dev/null +++ b/contrib/jemalloc/src/hash.c @@ -0,0 +1,2 @@ +#define JEMALLOC_HASH_C_ +#include "jemalloc/internal/jemalloc_internal.h" diff --git a/contrib/jemalloc/src/huge.c b/contrib/jemalloc/src/huge.c new file mode 100644 index 0000000..3a2877c --- /dev/null +++ b/contrib/jemalloc/src/huge.c @@ -0,0 +1,471 @@ +#define JEMALLOC_HUGE_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ + +static extent_node_t * +huge_node_get(const void *ptr) +{ + extent_node_t *node; + + node = chunk_lookup(ptr, true); + assert(!extent_node_achunk_get(node)); + + return (node); +} + +static bool +huge_node_set(tsdn_t *tsdn, const void *ptr, extent_node_t *node) +{ + + assert(extent_node_addr_get(node) == ptr); + assert(!extent_node_achunk_get(node)); + return (chunk_register(tsdn, ptr, node)); +} + +static void +huge_node_reset(tsdn_t *tsdn, const void *ptr, extent_node_t *node) +{ + bool err; + + err = huge_node_set(tsdn, ptr, node); + assert(!err); +} + +static void +huge_node_unset(const void *ptr, const extent_node_t *node) +{ + + chunk_deregister(ptr, node); +} + +void * +huge_malloc(tsdn_t *tsdn, arena_t *arena, size_t usize, bool zero) +{ + + assert(usize == s2u(usize)); + + return (huge_palloc(tsdn, arena, usize, chunksize, zero)); +} + +void * +huge_palloc(tsdn_t *tsdn, arena_t *arena, size_t usize, size_t alignment, + bool zero) +{ + void *ret; + size_t ausize; + extent_node_t *node; + bool is_zeroed; + + /* Allocate one or more contiguous chunks for this request. */ + + assert(!tsdn_null(tsdn) || arena != NULL); + + ausize = sa2u(usize, alignment); + if (unlikely(ausize == 0 || ausize > HUGE_MAXCLASS)) + return (NULL); + assert(ausize >= chunksize); + + /* Allocate an extent node with which to track the chunk. */ + node = ipallocztm(tsdn, CACHELINE_CEILING(sizeof(extent_node_t)), + CACHELINE, false, NULL, true, arena_ichoose(tsdn, arena)); + if (node == NULL) + return (NULL); + + /* + * Copy zero into is_zeroed and pass the copy to chunk_alloc(), so that + * it is possible to make correct junk/zero fill decisions below. + */ + is_zeroed = zero; + if (likely(!tsdn_null(tsdn))) + arena = arena_choose(tsdn_tsd(tsdn), arena); + if (unlikely(arena == NULL) || (ret = arena_chunk_alloc_huge(tsdn, + arena, usize, alignment, &is_zeroed)) == NULL) { + idalloctm(tsdn, node, NULL, true, true); + return (NULL); + } + + extent_node_init(node, arena, ret, usize, is_zeroed, true); + + if (huge_node_set(tsdn, ret, node)) { + arena_chunk_dalloc_huge(tsdn, arena, ret, usize); + idalloctm(tsdn, node, NULL, true, true); + return (NULL); + } + + /* Insert node into huge. */ + malloc_mutex_lock(tsdn, &arena->huge_mtx); + ql_elm_new(node, ql_link); + ql_tail_insert(&arena->huge, node, ql_link); + malloc_mutex_unlock(tsdn, &arena->huge_mtx); + + if (zero || (config_fill && unlikely(opt_zero))) { + if (!is_zeroed) + memset(ret, 0, usize); + } else if (config_fill && unlikely(opt_junk_alloc)) + memset(ret, JEMALLOC_ALLOC_JUNK, usize); + + arena_decay_tick(tsdn, arena); + return (ret); +} + +#ifdef JEMALLOC_JET +#undef huge_dalloc_junk +#define huge_dalloc_junk JEMALLOC_N(huge_dalloc_junk_impl) +#endif +static void +huge_dalloc_junk(tsdn_t *tsdn, void *ptr, size_t usize) +{ + + if (config_fill && have_dss && unlikely(opt_junk_free)) { + /* + * Only bother junk filling if the chunk isn't about to be + * unmapped. + */ + if (!config_munmap || (have_dss && chunk_in_dss(tsdn, ptr))) + memset(ptr, JEMALLOC_FREE_JUNK, usize); + } +} +#ifdef JEMALLOC_JET +#undef huge_dalloc_junk +#define huge_dalloc_junk JEMALLOC_N(huge_dalloc_junk) +huge_dalloc_junk_t *huge_dalloc_junk = JEMALLOC_N(huge_dalloc_junk_impl); +#endif + +static void +huge_ralloc_no_move_similar(tsdn_t *tsdn, void *ptr, size_t oldsize, + size_t usize_min, size_t usize_max, bool zero) +{ + size_t usize, usize_next; + extent_node_t *node; + arena_t *arena; + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + bool pre_zeroed, post_zeroed; + + /* Increase usize to incorporate extra. */ + for (usize = usize_min; usize < usize_max && (usize_next = s2u(usize+1)) + <= oldsize; usize = usize_next) + ; /* Do nothing. */ + + if (oldsize == usize) + return; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + pre_zeroed = extent_node_zeroed_get(node); + + /* Fill if necessary (shrinking). */ + if (oldsize > usize) { + size_t sdiff = oldsize - usize; + if (config_fill && unlikely(opt_junk_free)) { + memset((void *)((uintptr_t)ptr + usize), + JEMALLOC_FREE_JUNK, sdiff); + post_zeroed = false; + } else { + post_zeroed = !chunk_purge_wrapper(tsdn, arena, + &chunk_hooks, ptr, CHUNK_CEILING(oldsize), usize, + sdiff); + } + } else + post_zeroed = pre_zeroed; + + malloc_mutex_lock(tsdn, &arena->huge_mtx); + /* Update the size of the huge allocation. */ + huge_node_unset(ptr, node); + assert(extent_node_size_get(node) != usize); + extent_node_size_set(node, usize); + huge_node_reset(tsdn, ptr, node); + /* Update zeroed. */ + extent_node_zeroed_set(node, post_zeroed); + malloc_mutex_unlock(tsdn, &arena->huge_mtx); + + arena_chunk_ralloc_huge_similar(tsdn, arena, ptr, oldsize, usize); + + /* Fill if necessary (growing). */ + if (oldsize < usize) { + if (zero || (config_fill && unlikely(opt_zero))) { + if (!pre_zeroed) { + memset((void *)((uintptr_t)ptr + oldsize), 0, + usize - oldsize); + } + } else if (config_fill && unlikely(opt_junk_alloc)) { + memset((void *)((uintptr_t)ptr + oldsize), + JEMALLOC_ALLOC_JUNK, usize - oldsize); + } + } +} + +static bool +huge_ralloc_no_move_shrink(tsdn_t *tsdn, void *ptr, size_t oldsize, + size_t usize) +{ + extent_node_t *node; + arena_t *arena; + chunk_hooks_t chunk_hooks; + size_t cdiff; + bool pre_zeroed, post_zeroed; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + pre_zeroed = extent_node_zeroed_get(node); + chunk_hooks = chunk_hooks_get(tsdn, arena); + + assert(oldsize > usize); + + /* Split excess chunks. */ + cdiff = CHUNK_CEILING(oldsize) - CHUNK_CEILING(usize); + if (cdiff != 0 && chunk_hooks.split(ptr, CHUNK_CEILING(oldsize), + CHUNK_CEILING(usize), cdiff, true, arena->ind)) + return (true); + + if (oldsize > usize) { + size_t sdiff = oldsize - usize; + if (config_fill && unlikely(opt_junk_free)) { + huge_dalloc_junk(tsdn, (void *)((uintptr_t)ptr + usize), + sdiff); + post_zeroed = false; + } else { + post_zeroed = !chunk_purge_wrapper(tsdn, arena, + &chunk_hooks, CHUNK_ADDR2BASE((uintptr_t)ptr + + usize), CHUNK_CEILING(oldsize), + CHUNK_ADDR2OFFSET((uintptr_t)ptr + usize), sdiff); + } + } else + post_zeroed = pre_zeroed; + + malloc_mutex_lock(tsdn, &arena->huge_mtx); + /* Update the size of the huge allocation. */ + huge_node_unset(ptr, node); + extent_node_size_set(node, usize); + huge_node_reset(tsdn, ptr, node); + /* Update zeroed. */ + extent_node_zeroed_set(node, post_zeroed); + malloc_mutex_unlock(tsdn, &arena->huge_mtx); + + /* Zap the excess chunks. */ + arena_chunk_ralloc_huge_shrink(tsdn, arena, ptr, oldsize, usize); + + return (false); +} + +static bool +huge_ralloc_no_move_expand(tsdn_t *tsdn, void *ptr, size_t oldsize, + size_t usize, bool zero) { + extent_node_t *node; + arena_t *arena; + bool is_zeroed_subchunk, is_zeroed_chunk; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + malloc_mutex_lock(tsdn, &arena->huge_mtx); + is_zeroed_subchunk = extent_node_zeroed_get(node); + malloc_mutex_unlock(tsdn, &arena->huge_mtx); + + /* + * Use is_zeroed_chunk to detect whether the trailing memory is zeroed, + * update extent's zeroed field, and zero as necessary. + */ + is_zeroed_chunk = false; + if (arena_chunk_ralloc_huge_expand(tsdn, arena, ptr, oldsize, usize, + &is_zeroed_chunk)) + return (true); + + malloc_mutex_lock(tsdn, &arena->huge_mtx); + huge_node_unset(ptr, node); + extent_node_size_set(node, usize); + extent_node_zeroed_set(node, extent_node_zeroed_get(node) && + is_zeroed_chunk); + huge_node_reset(tsdn, ptr, node); + malloc_mutex_unlock(tsdn, &arena->huge_mtx); + + if (zero || (config_fill && unlikely(opt_zero))) { + if (!is_zeroed_subchunk) { + memset((void *)((uintptr_t)ptr + oldsize), 0, + CHUNK_CEILING(oldsize) - oldsize); + } + if (!is_zeroed_chunk) { + memset((void *)((uintptr_t)ptr + + CHUNK_CEILING(oldsize)), 0, usize - + CHUNK_CEILING(oldsize)); + } + } else if (config_fill && unlikely(opt_junk_alloc)) { + memset((void *)((uintptr_t)ptr + oldsize), JEMALLOC_ALLOC_JUNK, + usize - oldsize); + } + + return (false); +} + +bool +huge_ralloc_no_move(tsdn_t *tsdn, void *ptr, size_t oldsize, size_t usize_min, + size_t usize_max, bool zero) +{ + + assert(s2u(oldsize) == oldsize); + /* The following should have been caught by callers. */ + assert(usize_min > 0 && usize_max <= HUGE_MAXCLASS); + + /* Both allocations must be huge to avoid a move. */ + if (oldsize < chunksize || usize_max < chunksize) + return (true); + + if (CHUNK_CEILING(usize_max) > CHUNK_CEILING(oldsize)) { + /* Attempt to expand the allocation in-place. */ + if (!huge_ralloc_no_move_expand(tsdn, ptr, oldsize, usize_max, + zero)) { + arena_decay_tick(tsdn, huge_aalloc(ptr)); + return (false); + } + /* Try again, this time with usize_min. */ + if (usize_min < usize_max && CHUNK_CEILING(usize_min) > + CHUNK_CEILING(oldsize) && huge_ralloc_no_move_expand(tsdn, + ptr, oldsize, usize_min, zero)) { + arena_decay_tick(tsdn, huge_aalloc(ptr)); + return (false); + } + } + + /* + * Avoid moving the allocation if the existing chunk size accommodates + * the new size. + */ + if (CHUNK_CEILING(oldsize) >= CHUNK_CEILING(usize_min) + && CHUNK_CEILING(oldsize) <= CHUNK_CEILING(usize_max)) { + huge_ralloc_no_move_similar(tsdn, ptr, oldsize, usize_min, + usize_max, zero); + arena_decay_tick(tsdn, huge_aalloc(ptr)); + return (false); + } + + /* Attempt to shrink the allocation in-place. */ + if (CHUNK_CEILING(oldsize) > CHUNK_CEILING(usize_max)) { + if (!huge_ralloc_no_move_shrink(tsdn, ptr, oldsize, + usize_max)) { + arena_decay_tick(tsdn, huge_aalloc(ptr)); + return (false); + } + } + return (true); +} + +static void * +huge_ralloc_move_helper(tsdn_t *tsdn, arena_t *arena, size_t usize, + size_t alignment, bool zero) +{ + + if (alignment <= chunksize) + return (huge_malloc(tsdn, arena, usize, zero)); + return (huge_palloc(tsdn, arena, usize, alignment, zero)); +} + +void * +huge_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, + size_t usize, size_t alignment, bool zero, tcache_t *tcache) +{ + void *ret; + size_t copysize; + + /* The following should have been caught by callers. */ + assert(usize > 0 && usize <= HUGE_MAXCLASS); + + /* Try to avoid moving the allocation. */ + if (!huge_ralloc_no_move(tsd_tsdn(tsd), ptr, oldsize, usize, usize, + zero)) + return (ptr); + + /* + * usize and oldsize are different enough that we need to use a + * different size class. In that case, fall back to allocating new + * space and copying. + */ + ret = huge_ralloc_move_helper(tsd_tsdn(tsd), arena, usize, alignment, + zero); + if (ret == NULL) + return (NULL); + + copysize = (usize < oldsize) ? usize : oldsize; + memcpy(ret, ptr, copysize); + isqalloc(tsd, ptr, oldsize, tcache, true); + return (ret); +} + +void +huge_dalloc(tsdn_t *tsdn, void *ptr) +{ + extent_node_t *node; + arena_t *arena; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + huge_node_unset(ptr, node); + malloc_mutex_lock(tsdn, &arena->huge_mtx); + ql_remove(&arena->huge, node, ql_link); + malloc_mutex_unlock(tsdn, &arena->huge_mtx); + + huge_dalloc_junk(tsdn, extent_node_addr_get(node), + extent_node_size_get(node)); + arena_chunk_dalloc_huge(tsdn, extent_node_arena_get(node), + extent_node_addr_get(node), extent_node_size_get(node)); + idalloctm(tsdn, node, NULL, true, true); + + arena_decay_tick(tsdn, arena); +} + +arena_t * +huge_aalloc(const void *ptr) +{ + + return (extent_node_arena_get(huge_node_get(ptr))); +} + +size_t +huge_salloc(tsdn_t *tsdn, const void *ptr) +{ + size_t size; + extent_node_t *node; + arena_t *arena; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + malloc_mutex_lock(tsdn, &arena->huge_mtx); + size = extent_node_size_get(node); + malloc_mutex_unlock(tsdn, &arena->huge_mtx); + + return (size); +} + +prof_tctx_t * +huge_prof_tctx_get(tsdn_t *tsdn, const void *ptr) +{ + prof_tctx_t *tctx; + extent_node_t *node; + arena_t *arena; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + malloc_mutex_lock(tsdn, &arena->huge_mtx); + tctx = extent_node_prof_tctx_get(node); + malloc_mutex_unlock(tsdn, &arena->huge_mtx); + + return (tctx); +} + +void +huge_prof_tctx_set(tsdn_t *tsdn, const void *ptr, prof_tctx_t *tctx) +{ + extent_node_t *node; + arena_t *arena; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + malloc_mutex_lock(tsdn, &arena->huge_mtx); + extent_node_prof_tctx_set(node, tctx); + malloc_mutex_unlock(tsdn, &arena->huge_mtx); +} + +void +huge_prof_tctx_reset(tsdn_t *tsdn, const void *ptr) +{ + + huge_prof_tctx_set(tsdn, ptr, (prof_tctx_t *)(uintptr_t)1U); +} diff --git a/contrib/jemalloc/src/jemalloc.c b/contrib/jemalloc/src/jemalloc.c new file mode 100644 index 0000000..46dd1d1 --- /dev/null +++ b/contrib/jemalloc/src/jemalloc.c @@ -0,0 +1,2929 @@ +#define JEMALLOC_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +/* Work around : */ +const char *__malloc_options_1_0 = NULL; +__sym_compat(_malloc_options, __malloc_options_1_0, FBSD_1.0); + +/* Runtime configuration options. */ +const char *je_malloc_conf JEMALLOC_ATTR(weak); +bool opt_abort = +#ifdef JEMALLOC_DEBUG + true +#else + false +#endif + ; +const char *opt_junk = +#if (defined(JEMALLOC_DEBUG) && defined(JEMALLOC_FILL)) + "true" +#else + "false" +#endif + ; +bool opt_junk_alloc = +#if (defined(JEMALLOC_DEBUG) && defined(JEMALLOC_FILL)) + true +#else + false +#endif + ; +bool opt_junk_free = +#if (defined(JEMALLOC_DEBUG) && defined(JEMALLOC_FILL)) + true +#else + false +#endif + ; + +size_t opt_quarantine = ZU(0); +bool opt_redzone = false; +bool opt_utrace = false; +bool opt_xmalloc = false; +bool opt_zero = false; +unsigned opt_narenas = 0; + +/* Initialized to true if the process is running inside Valgrind. */ +bool in_valgrind; + +unsigned ncpus; + +/* Protects arenas initialization. */ +static malloc_mutex_t arenas_lock; +/* + * Arenas that are used to service external requests. Not all elements of the + * arenas array are necessarily used; arenas are created lazily as needed. + * + * arenas[0..narenas_auto) are used for automatic multiplexing of threads and + * arenas. arenas[narenas_auto..narenas_total) are only used if the application + * takes some action to create them and allocate from them. + */ +arena_t **arenas; +static unsigned narenas_total; /* Use narenas_total_*(). */ +static arena_t *a0; /* arenas[0]; read-only after initialization. */ +unsigned narenas_auto; /* Read-only after initialization. */ + +typedef enum { + malloc_init_uninitialized = 3, + malloc_init_a0_initialized = 2, + malloc_init_recursible = 1, + malloc_init_initialized = 0 /* Common case --> jnz. */ +} malloc_init_t; +static malloc_init_t malloc_init_state = malloc_init_uninitialized; + +/* False should be the common case. Set to true to trigger initialization. */ +static bool malloc_slow = true; + +/* When malloc_slow is true, set the corresponding bits for sanity check. */ +enum { + flag_opt_junk_alloc = (1U), + flag_opt_junk_free = (1U << 1), + flag_opt_quarantine = (1U << 2), + flag_opt_zero = (1U << 3), + flag_opt_utrace = (1U << 4), + flag_in_valgrind = (1U << 5), + flag_opt_xmalloc = (1U << 6) +}; +static uint8_t malloc_slow_flags; + +/* Last entry for overflow detection only. */ +JEMALLOC_ALIGNED(CACHELINE) +const size_t index2size_tab[NSIZES+1] = { +#define SC(index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup) \ + ((ZU(1)<= 0x0600 +static malloc_mutex_t init_lock = SRWLOCK_INIT; +#else +static malloc_mutex_t init_lock; +static bool init_lock_initialized = false; + +JEMALLOC_ATTR(constructor) +static void WINAPI +_init_init_lock(void) +{ + + /* If another constructor in the same binary is using mallctl to + * e.g. setup chunk hooks, it may end up running before this one, + * and malloc_init_hard will crash trying to lock the uninitialized + * lock. So we force an initialization of the lock in + * malloc_init_hard as well. We don't try to care about atomicity + * of the accessed to the init_lock_initialized boolean, since it + * really only matters early in the process creation, before any + * separate thread normally starts doing anything. */ + if (!init_lock_initialized) + malloc_mutex_init(&init_lock, "init", WITNESS_RANK_INIT); + init_lock_initialized = true; +} + +#ifdef _MSC_VER +# pragma section(".CRT$XCU", read) +JEMALLOC_SECTION(".CRT$XCU") JEMALLOC_ATTR(used) +static const void (WINAPI *init_init_lock)(void) = _init_init_lock; +#endif +#endif +#else +static malloc_mutex_t init_lock = MALLOC_MUTEX_INITIALIZER; +#endif + +typedef struct { + void *p; /* Input pointer (as in realloc(p, s)). */ + size_t s; /* Request size. */ + void *r; /* Result pointer. */ +} malloc_utrace_t; + +#ifdef JEMALLOC_UTRACE +# define UTRACE(a, b, c) do { \ + if (unlikely(opt_utrace)) { \ + int utrace_serrno = errno; \ + malloc_utrace_t ut; \ + ut.p = (a); \ + ut.s = (b); \ + ut.r = (c); \ + utrace(&ut, sizeof(ut)); \ + errno = utrace_serrno; \ + } \ +} while (0) +#else +# define UTRACE(a, b, c) +#endif + +/******************************************************************************/ +/* + * Function prototypes for static functions that are referenced prior to + * definition. + */ + +static bool malloc_init_hard_a0(void); +static bool malloc_init_hard(void); + +/******************************************************************************/ +/* + * Begin miscellaneous support functions. + */ + +JEMALLOC_ALWAYS_INLINE_C bool +malloc_initialized(void) +{ + + return (malloc_init_state == malloc_init_initialized); +} + +JEMALLOC_ALWAYS_INLINE_C void +malloc_thread_init(void) +{ + + /* + * TSD initialization can't be safely done as a side effect of + * deallocation, because it is possible for a thread to do nothing but + * deallocate its TLS data via free(), in which case writing to TLS + * would cause write-after-free memory corruption. The quarantine + * facility *only* gets used as a side effect of deallocation, so make + * a best effort attempt at initializing its TSD by hooking all + * allocation events. + */ + if (config_fill && unlikely(opt_quarantine)) + quarantine_alloc_hook(); +} + +JEMALLOC_ALWAYS_INLINE_C bool +malloc_init_a0(void) +{ + + if (unlikely(malloc_init_state == malloc_init_uninitialized)) + return (malloc_init_hard_a0()); + return (false); +} + +JEMALLOC_ALWAYS_INLINE_C bool +malloc_init(void) +{ + + if (unlikely(!malloc_initialized()) && malloc_init_hard()) + return (true); + malloc_thread_init(); + + return (false); +} + +/* + * The a0*() functions are used instead of i{d,}alloc() in situations that + * cannot tolerate TLS variable access. + */ + +static void * +a0ialloc(size_t size, bool zero, bool is_metadata) +{ + + if (unlikely(malloc_init_a0())) + return (NULL); + + return (iallocztm(TSDN_NULL, size, size2index(size), zero, NULL, + is_metadata, arena_get(TSDN_NULL, 0, true), true)); +} + +static void +a0idalloc(void *ptr, bool is_metadata) +{ + + idalloctm(TSDN_NULL, ptr, false, is_metadata, true); +} + +void * +a0malloc(size_t size) +{ + + return (a0ialloc(size, false, true)); +} + +void +a0dalloc(void *ptr) +{ + + a0idalloc(ptr, true); +} + +/* + * FreeBSD's libc uses the bootstrap_*() functions in bootstrap-senstive + * situations that cannot tolerate TLS variable access (TLS allocation and very + * early internal data structure initialization). + */ + +void * +bootstrap_malloc(size_t size) +{ + + if (unlikely(size == 0)) + size = 1; + + return (a0ialloc(size, false, false)); +} + +void * +bootstrap_calloc(size_t num, size_t size) +{ + size_t num_size; + + num_size = num * size; + if (unlikely(num_size == 0)) { + assert(num == 0 || size == 0); + num_size = 1; + } + + return (a0ialloc(num_size, true, false)); +} + +void +bootstrap_free(void *ptr) +{ + + if (unlikely(ptr == NULL)) + return; + + a0idalloc(ptr, false); +} + +static void +arena_set(unsigned ind, arena_t *arena) +{ + + atomic_write_p((void **)&arenas[ind], arena); +} + +static void +narenas_total_set(unsigned narenas) +{ + + atomic_write_u(&narenas_total, narenas); +} + +static void +narenas_total_inc(void) +{ + + atomic_add_u(&narenas_total, 1); +} + +unsigned +narenas_total_get(void) +{ + + return (atomic_read_u(&narenas_total)); +} + +/* Create a new arena and insert it into the arenas array at index ind. */ +static arena_t * +arena_init_locked(tsdn_t *tsdn, unsigned ind) +{ + arena_t *arena; + + assert(ind <= narenas_total_get()); + if (ind > MALLOCX_ARENA_MAX) + return (NULL); + if (ind == narenas_total_get()) + narenas_total_inc(); + + /* + * Another thread may have already initialized arenas[ind] if it's an + * auto arena. + */ + arena = arena_get(tsdn, ind, false); + if (arena != NULL) { + assert(ind < narenas_auto); + return (arena); + } + + /* Actually initialize the arena. */ + arena = arena_new(tsdn, ind); + arena_set(ind, arena); + return (arena); +} + +arena_t * +arena_init(tsdn_t *tsdn, unsigned ind) +{ + arena_t *arena; + + malloc_mutex_lock(tsdn, &arenas_lock); + arena = arena_init_locked(tsdn, ind); + malloc_mutex_unlock(tsdn, &arenas_lock); + return (arena); +} + +static void +arena_bind(tsd_t *tsd, unsigned ind, bool internal) +{ + arena_t *arena; + + arena = arena_get(tsd_tsdn(tsd), ind, false); + arena_nthreads_inc(arena, internal); + + if (tsd_nominal(tsd)) { + if (internal) + tsd_iarena_set(tsd, arena); + else + tsd_arena_set(tsd, arena); + } +} + +void +arena_migrate(tsd_t *tsd, unsigned oldind, unsigned newind) +{ + arena_t *oldarena, *newarena; + + oldarena = arena_get(tsd_tsdn(tsd), oldind, false); + newarena = arena_get(tsd_tsdn(tsd), newind, false); + arena_nthreads_dec(oldarena, false); + arena_nthreads_inc(newarena, false); + tsd_arena_set(tsd, newarena); +} + +static void +arena_unbind(tsd_t *tsd, unsigned ind, bool internal) +{ + arena_t *arena; + + arena = arena_get(tsd_tsdn(tsd), ind, false); + arena_nthreads_dec(arena, internal); + if (internal) + tsd_iarena_set(tsd, NULL); + else + tsd_arena_set(tsd, NULL); +} + +arena_tdata_t * +arena_tdata_get_hard(tsd_t *tsd, unsigned ind) +{ + arena_tdata_t *tdata, *arenas_tdata_old; + arena_tdata_t *arenas_tdata = tsd_arenas_tdata_get(tsd); + unsigned narenas_tdata_old, i; + unsigned narenas_tdata = tsd_narenas_tdata_get(tsd); + unsigned narenas_actual = narenas_total_get(); + + /* + * Dissociate old tdata array (and set up for deallocation upon return) + * if it's too small. + */ + if (arenas_tdata != NULL && narenas_tdata < narenas_actual) { + arenas_tdata_old = arenas_tdata; + narenas_tdata_old = narenas_tdata; + arenas_tdata = NULL; + narenas_tdata = 0; + tsd_arenas_tdata_set(tsd, arenas_tdata); + tsd_narenas_tdata_set(tsd, narenas_tdata); + } else { + arenas_tdata_old = NULL; + narenas_tdata_old = 0; + } + + /* Allocate tdata array if it's missing. */ + if (arenas_tdata == NULL) { + bool *arenas_tdata_bypassp = tsd_arenas_tdata_bypassp_get(tsd); + narenas_tdata = (ind < narenas_actual) ? narenas_actual : ind+1; + + if (tsd_nominal(tsd) && !*arenas_tdata_bypassp) { + *arenas_tdata_bypassp = true; + arenas_tdata = (arena_tdata_t *)a0malloc( + sizeof(arena_tdata_t) * narenas_tdata); + *arenas_tdata_bypassp = false; + } + if (arenas_tdata == NULL) { + tdata = NULL; + goto label_return; + } + assert(tsd_nominal(tsd) && !*arenas_tdata_bypassp); + tsd_arenas_tdata_set(tsd, arenas_tdata); + tsd_narenas_tdata_set(tsd, narenas_tdata); + } + + /* + * Copy to tdata array. It's possible that the actual number of arenas + * has increased since narenas_total_get() was called above, but that + * causes no correctness issues unless two threads concurrently execute + * the arenas.extend mallctl, which we trust mallctl synchronization to + * prevent. + */ + + /* Copy/initialize tickers. */ + for (i = 0; i < narenas_actual; i++) { + if (i < narenas_tdata_old) { + ticker_copy(&arenas_tdata[i].decay_ticker, + &arenas_tdata_old[i].decay_ticker); + } else { + ticker_init(&arenas_tdata[i].decay_ticker, + DECAY_NTICKS_PER_UPDATE); + } + } + if (narenas_tdata > narenas_actual) { + memset(&arenas_tdata[narenas_actual], 0, sizeof(arena_tdata_t) + * (narenas_tdata - narenas_actual)); + } + + /* Read the refreshed tdata array. */ + tdata = &arenas_tdata[ind]; +label_return: + if (arenas_tdata_old != NULL) + a0dalloc(arenas_tdata_old); + return (tdata); +} + +/* Slow path, called only by arena_choose(). */ +arena_t * +arena_choose_hard(tsd_t *tsd, bool internal) +{ + arena_t *ret JEMALLOC_CC_SILENCE_INIT(NULL); + + if (narenas_auto > 1) { + unsigned i, j, choose[2], first_null; + + /* + * Determine binding for both non-internal and internal + * allocation. + * + * choose[0]: For application allocation. + * choose[1]: For internal metadata allocation. + */ + + for (j = 0; j < 2; j++) + choose[j] = 0; + + first_null = narenas_auto; + malloc_mutex_lock(tsd_tsdn(tsd), &arenas_lock); + assert(arena_get(tsd_tsdn(tsd), 0, false) != NULL); + for (i = 1; i < narenas_auto; i++) { + if (arena_get(tsd_tsdn(tsd), i, false) != NULL) { + /* + * Choose the first arena that has the lowest + * number of threads assigned to it. + */ + for (j = 0; j < 2; j++) { + if (arena_nthreads_get(arena_get( + tsd_tsdn(tsd), i, false), !!j) < + arena_nthreads_get(arena_get( + tsd_tsdn(tsd), choose[j], false), + !!j)) + choose[j] = i; + } + } else if (first_null == narenas_auto) { + /* + * Record the index of the first uninitialized + * arena, in case all extant arenas are in use. + * + * NB: It is possible for there to be + * discontinuities in terms of initialized + * versus uninitialized arenas, due to the + * "thread.arena" mallctl. + */ + first_null = i; + } + } + + for (j = 0; j < 2; j++) { + if (arena_nthreads_get(arena_get(tsd_tsdn(tsd), + choose[j], false), !!j) == 0 || first_null == + narenas_auto) { + /* + * Use an unloaded arena, or the least loaded + * arena if all arenas are already initialized. + */ + if (!!j == internal) { + ret = arena_get(tsd_tsdn(tsd), + choose[j], false); + } + } else { + arena_t *arena; + + /* Initialize a new arena. */ + choose[j] = first_null; + arena = arena_init_locked(tsd_tsdn(tsd), + choose[j]); + if (arena == NULL) { + malloc_mutex_unlock(tsd_tsdn(tsd), + &arenas_lock); + return (NULL); + } + if (!!j == internal) + ret = arena; + } + arena_bind(tsd, choose[j], !!j); + } + malloc_mutex_unlock(tsd_tsdn(tsd), &arenas_lock); + } else { + ret = arena_get(tsd_tsdn(tsd), 0, false); + arena_bind(tsd, 0, false); + arena_bind(tsd, 0, true); + } + + return (ret); +} + +void +thread_allocated_cleanup(tsd_t *tsd) +{ + + /* Do nothing. */ +} + +void +thread_deallocated_cleanup(tsd_t *tsd) +{ + + /* Do nothing. */ +} + +void +iarena_cleanup(tsd_t *tsd) +{ + arena_t *iarena; + + iarena = tsd_iarena_get(tsd); + if (iarena != NULL) + arena_unbind(tsd, iarena->ind, true); +} + +void +arena_cleanup(tsd_t *tsd) +{ + arena_t *arena; + + arena = tsd_arena_get(tsd); + if (arena != NULL) + arena_unbind(tsd, arena->ind, false); +} + +void +arenas_tdata_cleanup(tsd_t *tsd) +{ + arena_tdata_t *arenas_tdata; + + /* Prevent tsd->arenas_tdata from being (re)created. */ + *tsd_arenas_tdata_bypassp_get(tsd) = true; + + arenas_tdata = tsd_arenas_tdata_get(tsd); + if (arenas_tdata != NULL) { + tsd_arenas_tdata_set(tsd, NULL); + a0dalloc(arenas_tdata); + } +} + +void +narenas_tdata_cleanup(tsd_t *tsd) +{ + + /* Do nothing. */ +} + +void +arenas_tdata_bypass_cleanup(tsd_t *tsd) +{ + + /* Do nothing. */ +} + +static void +stats_print_atexit(void) +{ + + if (config_tcache && config_stats) { + tsdn_t *tsdn; + unsigned narenas, i; + + tsdn = tsdn_fetch(); + + /* + * Merge stats from extant threads. This is racy, since + * individual threads do not lock when recording tcache stats + * events. As a consequence, the final stats may be slightly + * out of date by the time they are reported, if other threads + * continue to allocate. + */ + for (i = 0, narenas = narenas_total_get(); i < narenas; i++) { + arena_t *arena = arena_get(tsdn, i, false); + if (arena != NULL) { + tcache_t *tcache; + + /* + * tcache_stats_merge() locks bins, so if any + * code is introduced that acquires both arena + * and bin locks in the opposite order, + * deadlocks may result. + */ + malloc_mutex_lock(tsdn, &arena->lock); + ql_foreach(tcache, &arena->tcache_ql, link) { + tcache_stats_merge(tsdn, tcache, arena); + } + malloc_mutex_unlock(tsdn, &arena->lock); + } + } + } + je_malloc_stats_print(NULL, NULL, NULL); +} + +/* + * End miscellaneous support functions. + */ +/******************************************************************************/ +/* + * Begin initialization functions. + */ + +#ifndef JEMALLOC_HAVE_SECURE_GETENV +static char * +secure_getenv(const char *name) +{ + +# ifdef JEMALLOC_HAVE_ISSETUGID + if (issetugid() != 0) + return (NULL); +# endif + return (getenv(name)); +} +#endif + +static unsigned +malloc_ncpus(void) +{ + long result; + +#ifdef _WIN32 + SYSTEM_INFO si; + GetSystemInfo(&si); + result = si.dwNumberOfProcessors; +#else + result = sysconf(_SC_NPROCESSORS_ONLN); +#endif + return ((result == -1) ? 1 : (unsigned)result); +} + +static bool +malloc_conf_next(char const **opts_p, char const **k_p, size_t *klen_p, + char const **v_p, size_t *vlen_p) +{ + bool accept; + const char *opts = *opts_p; + + *k_p = opts; + + for (accept = false; !accept;) { + switch (*opts) { + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case '_': + opts++; + break; + case ':': + opts++; + *klen_p = (uintptr_t)opts - 1 - (uintptr_t)*k_p; + *v_p = opts; + accept = true; + break; + case '\0': + if (opts != *opts_p) { + malloc_write(": Conf string ends " + "with key\n"); + } + return (true); + default: + malloc_write(": Malformed conf string\n"); + return (true); + } + } + + for (accept = false; !accept;) { + switch (*opts) { + case ',': + opts++; + /* + * Look ahead one character here, because the next time + * this function is called, it will assume that end of + * input has been cleanly reached if no input remains, + * but we have optimistically already consumed the + * comma if one exists. + */ + if (*opts == '\0') { + malloc_write(": Conf string ends " + "with comma\n"); + } + *vlen_p = (uintptr_t)opts - 1 - (uintptr_t)*v_p; + accept = true; + break; + case '\0': + *vlen_p = (uintptr_t)opts - (uintptr_t)*v_p; + accept = true; + break; + default: + opts++; + break; + } + } + + *opts_p = opts; + return (false); +} + +static void +malloc_conf_error(const char *msg, const char *k, size_t klen, const char *v, + size_t vlen) +{ + + malloc_printf(": %s: %.*s:%.*s\n", msg, (int)klen, k, + (int)vlen, v); +} + +static void +malloc_slow_flag_init(void) +{ + /* + * Combine the runtime options into malloc_slow for fast path. Called + * after processing all the options. + */ + malloc_slow_flags |= (opt_junk_alloc ? flag_opt_junk_alloc : 0) + | (opt_junk_free ? flag_opt_junk_free : 0) + | (opt_quarantine ? flag_opt_quarantine : 0) + | (opt_zero ? flag_opt_zero : 0) + | (opt_utrace ? flag_opt_utrace : 0) + | (opt_xmalloc ? flag_opt_xmalloc : 0); + + if (config_valgrind) + malloc_slow_flags |= (in_valgrind ? flag_in_valgrind : 0); + + malloc_slow = (malloc_slow_flags != 0); +} + +static void +malloc_conf_init(void) +{ + unsigned i; + char buf[PATH_MAX + 1]; + const char *opts, *k, *v; + size_t klen, vlen; + + /* + * Automatically configure valgrind before processing options. The + * valgrind option remains in jemalloc 3.x for compatibility reasons. + */ + if (config_valgrind) { + in_valgrind = (RUNNING_ON_VALGRIND != 0) ? true : false; + if (config_fill && unlikely(in_valgrind)) { + opt_junk = "false"; + opt_junk_alloc = false; + opt_junk_free = false; + assert(!opt_zero); + opt_quarantine = JEMALLOC_VALGRIND_QUARANTINE_DEFAULT; + opt_redzone = true; + } + if (config_tcache && unlikely(in_valgrind)) + opt_tcache = false; + } + + for (i = 0; i < 4; i++) { + /* Get runtime configuration. */ + switch (i) { + case 0: + opts = config_malloc_conf; + break; + case 1: + if (je_malloc_conf != NULL) { + /* + * Use options that were compiled into the + * program. + */ + opts = je_malloc_conf; + } else { + /* No configuration specified. */ + buf[0] = '\0'; + opts = buf; + } + break; + case 2: { + ssize_t linklen = 0; +#ifndef _WIN32 + int saved_errno = errno; + const char *linkname = +# ifdef JEMALLOC_PREFIX + "/etc/"JEMALLOC_PREFIX"malloc.conf" +# else + "/etc/malloc.conf" +# endif + ; + + /* + * Try to use the contents of the "/etc/malloc.conf" + * symbolic link's name. + */ + linklen = readlink(linkname, buf, sizeof(buf) - 1); + if (linklen == -1) { + /* No configuration specified. */ + linklen = 0; + /* Restore errno. */ + set_errno(saved_errno); + } +#endif + buf[linklen] = '\0'; + opts = buf; + break; + } case 3: { + const char *envname = +#ifdef JEMALLOC_PREFIX + JEMALLOC_CPREFIX"MALLOC_CONF" +#else + "MALLOC_CONF" +#endif + ; + + if ((opts = secure_getenv(envname)) != NULL) { + /* + * Do nothing; opts is already initialized to + * the value of the MALLOC_CONF environment + * variable. + */ + } else { + /* No configuration specified. */ + buf[0] = '\0'; + opts = buf; + } + break; + } default: + not_reached(); + buf[0] = '\0'; + opts = buf; + } + + while (*opts != '\0' && !malloc_conf_next(&opts, &k, &klen, &v, + &vlen)) { +#define CONF_MATCH(n) \ + (sizeof(n)-1 == klen && strncmp(n, k, klen) == 0) +#define CONF_MATCH_VALUE(n) \ + (sizeof(n)-1 == vlen && strncmp(n, v, vlen) == 0) +#define CONF_HANDLE_BOOL(o, n, cont) \ + if (CONF_MATCH(n)) { \ + if (CONF_MATCH_VALUE("true")) \ + o = true; \ + else if (CONF_MATCH_VALUE("false")) \ + o = false; \ + else { \ + malloc_conf_error( \ + "Invalid conf value", \ + k, klen, v, vlen); \ + } \ + if (cont) \ + continue; \ + } +#define CONF_HANDLE_T_U(t, o, n, min, max, clip) \ + if (CONF_MATCH(n)) { \ + uintmax_t um; \ + char *end; \ + \ + set_errno(0); \ + um = malloc_strtoumax(v, &end, 0); \ + if (get_errno() != 0 || (uintptr_t)end -\ + (uintptr_t)v != vlen) { \ + malloc_conf_error( \ + "Invalid conf value", \ + k, klen, v, vlen); \ + } else if (clip) { \ + if ((min) != 0 && um < (min)) \ + o = (t)(min); \ + else if (um > (max)) \ + o = (t)(max); \ + else \ + o = (t)um; \ + } else { \ + if (((min) != 0 && um < (min)) \ + || um > (max)) { \ + malloc_conf_error( \ + "Out-of-range " \ + "conf value", \ + k, klen, v, vlen); \ + } else \ + o = (t)um; \ + } \ + continue; \ + } +#define CONF_HANDLE_UNSIGNED(o, n, min, max, clip) \ + CONF_HANDLE_T_U(unsigned, o, n, min, max, clip) +#define CONF_HANDLE_SIZE_T(o, n, min, max, clip) \ + CONF_HANDLE_T_U(size_t, o, n, min, max, clip) +#define CONF_HANDLE_SSIZE_T(o, n, min, max) \ + if (CONF_MATCH(n)) { \ + long l; \ + char *end; \ + \ + set_errno(0); \ + l = strtol(v, &end, 0); \ + if (get_errno() != 0 || (uintptr_t)end -\ + (uintptr_t)v != vlen) { \ + malloc_conf_error( \ + "Invalid conf value", \ + k, klen, v, vlen); \ + } else if (l < (ssize_t)(min) || l > \ + (ssize_t)(max)) { \ + malloc_conf_error( \ + "Out-of-range conf value", \ + k, klen, v, vlen); \ + } else \ + o = l; \ + continue; \ + } +#define CONF_HANDLE_CHAR_P(o, n, d) \ + if (CONF_MATCH(n)) { \ + size_t cpylen = (vlen <= \ + sizeof(o)-1) ? vlen : \ + sizeof(o)-1; \ + strncpy(o, v, cpylen); \ + o[cpylen] = '\0'; \ + continue; \ + } + + CONF_HANDLE_BOOL(opt_abort, "abort", true) + /* + * Chunks always require at least one header page, + * as many as 2^(LG_SIZE_CLASS_GROUP+1) data pages, and + * possibly an additional page in the presence of + * redzones. In order to simplify options processing, + * use a conservative bound that accommodates all these + * constraints. + */ + CONF_HANDLE_SIZE_T(opt_lg_chunk, "lg_chunk", LG_PAGE + + LG_SIZE_CLASS_GROUP + (config_fill ? 2 : 1), + (sizeof(size_t) << 3) - 1, true) + if (strncmp("dss", k, klen) == 0) { + int i; + bool match = false; + for (i = 0; i < dss_prec_limit; i++) { + if (strncmp(dss_prec_names[i], v, vlen) + == 0) { + if (chunk_dss_prec_set(NULL, + i)) { + malloc_conf_error( + "Error setting dss", + k, klen, v, vlen); + } else { + opt_dss = + dss_prec_names[i]; + match = true; + break; + } + } + } + if (!match) { + malloc_conf_error("Invalid conf value", + k, klen, v, vlen); + } + continue; + } + CONF_HANDLE_UNSIGNED(opt_narenas, "narenas", 1, + UINT_MAX, false) + if (strncmp("purge", k, klen) == 0) { + int i; + bool match = false; + for (i = 0; i < purge_mode_limit; i++) { + if (strncmp(purge_mode_names[i], v, + vlen) == 0) { + opt_purge = (purge_mode_t)i; + match = true; + break; + } + } + if (!match) { + malloc_conf_error("Invalid conf value", + k, klen, v, vlen); + } + continue; + } + CONF_HANDLE_SSIZE_T(opt_lg_dirty_mult, "lg_dirty_mult", + -1, (sizeof(size_t) << 3) - 1) + CONF_HANDLE_SSIZE_T(opt_decay_time, "decay_time", -1, + NSTIME_SEC_MAX); + CONF_HANDLE_BOOL(opt_stats_print, "stats_print", true) + if (config_fill) { + if (CONF_MATCH("junk")) { + if (CONF_MATCH_VALUE("true")) { + opt_junk = "true"; + opt_junk_alloc = opt_junk_free = + true; + } else if (CONF_MATCH_VALUE("false")) { + opt_junk = "false"; + opt_junk_alloc = opt_junk_free = + false; + } else if (CONF_MATCH_VALUE("alloc")) { + opt_junk = "alloc"; + opt_junk_alloc = true; + opt_junk_free = false; + } else if (CONF_MATCH_VALUE("free")) { + opt_junk = "free"; + opt_junk_alloc = false; + opt_junk_free = true; + } else { + malloc_conf_error( + "Invalid conf value", k, + klen, v, vlen); + } + continue; + } + CONF_HANDLE_SIZE_T(opt_quarantine, "quarantine", + 0, SIZE_T_MAX, false) + CONF_HANDLE_BOOL(opt_redzone, "redzone", true) + CONF_HANDLE_BOOL(opt_zero, "zero", true) + } + if (config_utrace) { + CONF_HANDLE_BOOL(opt_utrace, "utrace", true) + } + if (config_xmalloc) { + CONF_HANDLE_BOOL(opt_xmalloc, "xmalloc", true) + } + if (config_tcache) { + CONF_HANDLE_BOOL(opt_tcache, "tcache", + !config_valgrind || !in_valgrind) + if (CONF_MATCH("tcache")) { + assert(config_valgrind && in_valgrind); + if (opt_tcache) { + opt_tcache = false; + malloc_conf_error( + "tcache cannot be enabled " + "while running inside Valgrind", + k, klen, v, vlen); + } + continue; + } + CONF_HANDLE_SSIZE_T(opt_lg_tcache_max, + "lg_tcache_max", -1, + (sizeof(size_t) << 3) - 1) + } + if (config_prof) { + CONF_HANDLE_BOOL(opt_prof, "prof", true) + CONF_HANDLE_CHAR_P(opt_prof_prefix, + "prof_prefix", "jeprof") + CONF_HANDLE_BOOL(opt_prof_active, "prof_active", + true) + CONF_HANDLE_BOOL(opt_prof_thread_active_init, + "prof_thread_active_init", true) + CONF_HANDLE_SIZE_T(opt_lg_prof_sample, + "lg_prof_sample", 0, + (sizeof(uint64_t) << 3) - 1, true) + CONF_HANDLE_BOOL(opt_prof_accum, "prof_accum", + true) + CONF_HANDLE_SSIZE_T(opt_lg_prof_interval, + "lg_prof_interval", -1, + (sizeof(uint64_t) << 3) - 1) + CONF_HANDLE_BOOL(opt_prof_gdump, "prof_gdump", + true) + CONF_HANDLE_BOOL(opt_prof_final, "prof_final", + true) + CONF_HANDLE_BOOL(opt_prof_leak, "prof_leak", + true) + } + malloc_conf_error("Invalid conf pair", k, klen, v, + vlen); +#undef CONF_MATCH +#undef CONF_HANDLE_BOOL +#undef CONF_HANDLE_SIZE_T +#undef CONF_HANDLE_SSIZE_T +#undef CONF_HANDLE_CHAR_P + } + } +} + +static bool +malloc_init_hard_needed(void) +{ + + if (malloc_initialized() || (IS_INITIALIZER && malloc_init_state == + malloc_init_recursible)) { + /* + * Another thread initialized the allocator before this one + * acquired init_lock, or this thread is the initializing + * thread, and it is recursively allocating. + */ + return (false); + } +#ifdef JEMALLOC_THREADED_INIT + if (malloc_initializer != NO_INITIALIZER && !IS_INITIALIZER) { + /* Busy-wait until the initializing thread completes. */ + do { + malloc_mutex_unlock(NULL, &init_lock); + CPU_SPINWAIT; + malloc_mutex_lock(NULL, &init_lock); + } while (!malloc_initialized()); + return (false); + } +#endif + return (true); +} + +static bool +malloc_init_hard_a0_locked() +{ + + malloc_initializer = INITIALIZER; + + if (config_prof) + prof_boot0(); + malloc_conf_init(); + if (opt_stats_print) { + /* Print statistics at exit. */ + if (atexit(stats_print_atexit) != 0) { + malloc_write(": Error in atexit()\n"); + if (opt_abort) + abort(); + } + } + pages_boot(); + if (base_boot()) + return (true); + if (chunk_boot()) + return (true); + if (ctl_boot()) + return (true); + if (config_prof) + prof_boot1(); + if (arena_boot()) + return (true); + if (config_tcache && tcache_boot(TSDN_NULL)) + return (true); + if (malloc_mutex_init(&arenas_lock, "arenas", WITNESS_RANK_ARENAS)) + return (true); + /* + * Create enough scaffolding to allow recursive allocation in + * malloc_ncpus(). + */ + narenas_auto = 1; + narenas_total_set(narenas_auto); + arenas = &a0; + memset(arenas, 0, sizeof(arena_t *) * narenas_auto); + /* + * Initialize one arena here. The rest are lazily created in + * arena_choose_hard(). + */ + if (arena_init(TSDN_NULL, 0) == NULL) + return (true); + + malloc_init_state = malloc_init_a0_initialized; + + return (false); +} + +static bool +malloc_init_hard_a0(void) +{ + bool ret; + + malloc_mutex_lock(TSDN_NULL, &init_lock); + ret = malloc_init_hard_a0_locked(); + malloc_mutex_unlock(TSDN_NULL, &init_lock); + return (ret); +} + +/* Initialize data structures which may trigger recursive allocation. */ +static bool +malloc_init_hard_recursible(void) +{ + + malloc_init_state = malloc_init_recursible; + + ncpus = malloc_ncpus(); + +#if (!defined(JEMALLOC_MUTEX_INIT_CB) && !defined(JEMALLOC_ZONE) \ + && !defined(_WIN32) && !defined(__native_client__)) + /* LinuxThreads' pthread_atfork() allocates. */ + if (pthread_atfork(jemalloc_prefork, jemalloc_postfork_parent, + jemalloc_postfork_child) != 0) { + malloc_write(": Error in pthread_atfork()\n"); + if (opt_abort) + abort(); + return (true); + } +#endif + + return (false); +} + +static bool +malloc_init_hard_finish(tsdn_t *tsdn) +{ + + if (malloc_mutex_boot()) + return (true); + + if (opt_narenas == 0) { + /* + * For SMP systems, create more than one arena per CPU by + * default. + */ + if (ncpus > 1) + opt_narenas = ncpus << 2; + else + opt_narenas = 1; + } + narenas_auto = opt_narenas; + /* + * Limit the number of arenas to the indexing range of MALLOCX_ARENA(). + */ + if (narenas_auto > MALLOCX_ARENA_MAX) { + narenas_auto = MALLOCX_ARENA_MAX; + malloc_printf(": Reducing narenas to limit (%d)\n", + narenas_auto); + } + narenas_total_set(narenas_auto); + + /* Allocate and initialize arenas. */ + arenas = (arena_t **)base_alloc(tsdn, sizeof(arena_t *) * + (MALLOCX_ARENA_MAX+1)); + if (arenas == NULL) + return (true); + /* Copy the pointer to the one arena that was already initialized. */ + arena_set(0, a0); + + malloc_init_state = malloc_init_initialized; + malloc_slow_flag_init(); + + return (false); +} + +static bool +malloc_init_hard(void) +{ + tsd_t *tsd; + +#if defined(_WIN32) && _WIN32_WINNT < 0x0600 + _init_init_lock(); +#endif + malloc_mutex_lock(TSDN_NULL, &init_lock); + if (!malloc_init_hard_needed()) { + malloc_mutex_unlock(TSDN_NULL, &init_lock); + return (false); + } + + if (malloc_init_state != malloc_init_a0_initialized && + malloc_init_hard_a0_locked()) { + malloc_mutex_unlock(TSDN_NULL, &init_lock); + return (true); + } + + malloc_mutex_unlock(TSDN_NULL, &init_lock); + /* Recursive allocation relies on functional tsd. */ + tsd = malloc_tsd_boot0(); + if (tsd == NULL) + return (true); + if (malloc_init_hard_recursible()) + return (true); + malloc_mutex_lock(tsd_tsdn(tsd), &init_lock); + + if (config_prof && prof_boot2(tsd_tsdn(tsd))) { + malloc_mutex_unlock(tsd_tsdn(tsd), &init_lock); + return (true); + } + + if (malloc_init_hard_finish(tsd_tsdn(tsd))) { + malloc_mutex_unlock(tsd_tsdn(tsd), &init_lock); + return (true); + } + + malloc_mutex_unlock(tsd_tsdn(tsd), &init_lock); + malloc_tsd_boot1(); + return (false); +} + +/* + * End initialization functions. + */ +/******************************************************************************/ +/* + * Begin malloc(3)-compatible functions. + */ + +static void * +ialloc_prof_sample(tsd_t *tsd, size_t usize, szind_t ind, bool zero, + prof_tctx_t *tctx, bool slow_path) +{ + void *p; + + if (tctx == NULL) + return (NULL); + if (usize <= SMALL_MAXCLASS) { + szind_t ind_large = size2index(LARGE_MINCLASS); + p = ialloc(tsd, LARGE_MINCLASS, ind_large, zero, slow_path); + if (p == NULL) + return (NULL); + arena_prof_promoted(tsd_tsdn(tsd), p, usize); + } else + p = ialloc(tsd, usize, ind, zero, slow_path); + + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +ialloc_prof(tsd_t *tsd, size_t usize, szind_t ind, bool zero, bool slow_path) +{ + void *p; + prof_tctx_t *tctx; + + tctx = prof_alloc_prep(tsd, usize, prof_active_get_unlocked(), true); + if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) + p = ialloc_prof_sample(tsd, usize, ind, zero, tctx, slow_path); + else + p = ialloc(tsd, usize, ind, zero, slow_path); + if (unlikely(p == NULL)) { + prof_alloc_rollback(tsd, tctx, true); + return (NULL); + } + prof_malloc(tsd_tsdn(tsd), p, usize, tctx); + + return (p); +} + +/* + * ialloc_body() is inlined so that fast and slow paths are generated separately + * with statically known slow_path. + * + * This function guarantees that *tsdn is non-NULL on success. + */ +JEMALLOC_ALWAYS_INLINE_C void * +ialloc_body(size_t size, bool zero, tsdn_t **tsdn, size_t *usize, + bool slow_path) +{ + tsd_t *tsd; + szind_t ind; + + if (slow_path && unlikely(malloc_init())) { + *tsdn = NULL; + return (NULL); + } + + tsd = tsd_fetch(); + *tsdn = tsd_tsdn(tsd); + witness_assert_lockless(tsd_tsdn(tsd)); + + ind = size2index(size); + if (unlikely(ind >= NSIZES)) + return (NULL); + + if (config_stats || (config_prof && opt_prof) || (slow_path && + config_valgrind && unlikely(in_valgrind))) { + *usize = index2size(ind); + assert(*usize > 0 && *usize <= HUGE_MAXCLASS); + } + + if (config_prof && opt_prof) + return (ialloc_prof(tsd, *usize, ind, zero, slow_path)); + + return (ialloc(tsd, size, ind, zero, slow_path)); +} + +JEMALLOC_ALWAYS_INLINE_C void +ialloc_post_check(void *ret, tsdn_t *tsdn, size_t usize, const char *func, + bool update_errno, bool slow_path) +{ + + assert(!tsdn_null(tsdn) || ret == NULL); + + if (unlikely(ret == NULL)) { + if (slow_path && config_xmalloc && unlikely(opt_xmalloc)) { + malloc_printf(": Error in %s(): out of " + "memory\n", func); + abort(); + } + if (update_errno) + set_errno(ENOMEM); + } + if (config_stats && likely(ret != NULL)) { + assert(usize == isalloc(tsdn, ret, config_prof)); + *tsd_thread_allocatedp_get(tsdn_tsd(tsdn)) += usize; + } + witness_assert_lockless(tsdn); +} + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1) +je_malloc(size_t size) +{ + void *ret; + tsdn_t *tsdn; + size_t usize JEMALLOC_CC_SILENCE_INIT(0); + + if (size == 0) + size = 1; + + if (likely(!malloc_slow)) { + ret = ialloc_body(size, false, &tsdn, &usize, false); + ialloc_post_check(ret, tsdn, usize, "malloc", true, false); + } else { + ret = ialloc_body(size, false, &tsdn, &usize, true); + ialloc_post_check(ret, tsdn, usize, "malloc", true, true); + UTRACE(0, size, ret); + JEMALLOC_VALGRIND_MALLOC(ret != NULL, tsdn, ret, usize, false); + } + + return (ret); +} + +static void * +imemalign_prof_sample(tsd_t *tsd, size_t alignment, size_t usize, + prof_tctx_t *tctx) +{ + void *p; + + if (tctx == NULL) + return (NULL); + if (usize <= SMALL_MAXCLASS) { + assert(sa2u(LARGE_MINCLASS, alignment) == LARGE_MINCLASS); + p = ipalloc(tsd, LARGE_MINCLASS, alignment, false); + if (p == NULL) + return (NULL); + arena_prof_promoted(tsd_tsdn(tsd), p, usize); + } else + p = ipalloc(tsd, usize, alignment, false); + + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +imemalign_prof(tsd_t *tsd, size_t alignment, size_t usize) +{ + void *p; + prof_tctx_t *tctx; + + tctx = prof_alloc_prep(tsd, usize, prof_active_get_unlocked(), true); + if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) + p = imemalign_prof_sample(tsd, alignment, usize, tctx); + else + p = ipalloc(tsd, usize, alignment, false); + if (unlikely(p == NULL)) { + prof_alloc_rollback(tsd, tctx, true); + return (NULL); + } + prof_malloc(tsd_tsdn(tsd), p, usize, tctx); + + return (p); +} + +JEMALLOC_ATTR(nonnull(1)) +static int +imemalign(void **memptr, size_t alignment, size_t size, size_t min_alignment) +{ + int ret; + tsd_t *tsd; + size_t usize; + void *result; + + assert(min_alignment != 0); + + if (unlikely(malloc_init())) { + tsd = NULL; + result = NULL; + goto label_oom; + } + tsd = tsd_fetch(); + witness_assert_lockless(tsd_tsdn(tsd)); + if (size == 0) + size = 1; + + /* Make sure that alignment is a large enough power of 2. */ + if (unlikely(((alignment - 1) & alignment) != 0 + || (alignment < min_alignment))) { + if (config_xmalloc && unlikely(opt_xmalloc)) { + malloc_write(": Error allocating " + "aligned memory: invalid alignment\n"); + abort(); + } + result = NULL; + ret = EINVAL; + goto label_return; + } + + usize = sa2u(size, alignment); + if (unlikely(usize == 0 || usize > HUGE_MAXCLASS)) { + result = NULL; + goto label_oom; + } + + if (config_prof && opt_prof) + result = imemalign_prof(tsd, alignment, usize); + else + result = ipalloc(tsd, usize, alignment, false); + if (unlikely(result == NULL)) + goto label_oom; + assert(((uintptr_t)result & (alignment - 1)) == ZU(0)); + + *memptr = result; + ret = 0; +label_return: + if (config_stats && likely(result != NULL)) { + assert(usize == isalloc(tsd_tsdn(tsd), result, config_prof)); + *tsd_thread_allocatedp_get(tsd) += usize; + } + UTRACE(0, size, result); + JEMALLOC_VALGRIND_MALLOC(result != NULL, tsd_tsdn(tsd), result, usize, + false); + witness_assert_lockless(tsd_tsdn(tsd)); + return (ret); +label_oom: + assert(result == NULL); + if (config_xmalloc && unlikely(opt_xmalloc)) { + malloc_write(": Error allocating aligned memory: " + "out of memory\n"); + abort(); + } + ret = ENOMEM; + witness_assert_lockless(tsd_tsdn(tsd)); + goto label_return; +} + +JEMALLOC_EXPORT int JEMALLOC_NOTHROW +JEMALLOC_ATTR(nonnull(1)) +je_posix_memalign(void **memptr, size_t alignment, size_t size) +{ + int ret; + + ret = imemalign(memptr, alignment, size, sizeof(void *)); + + return (ret); +} + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(2) +je_aligned_alloc(size_t alignment, size_t size) +{ + void *ret; + int err; + + if (unlikely((err = imemalign(&ret, alignment, size, 1)) != 0)) { + ret = NULL; + set_errno(err); + } + + return (ret); +} + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2) +je_calloc(size_t num, size_t size) +{ + void *ret; + tsdn_t *tsdn; + size_t num_size; + size_t usize JEMALLOC_CC_SILENCE_INIT(0); + + num_size = num * size; + if (unlikely(num_size == 0)) { + if (num == 0 || size == 0) + num_size = 1; + else + num_size = HUGE_MAXCLASS + 1; /* Trigger OOM. */ + /* + * Try to avoid division here. We know that it isn't possible to + * overflow during multiplication if neither operand uses any of the + * most significant half of the bits in a size_t. + */ + } else if (unlikely(((num | size) & (SIZE_T_MAX << (sizeof(size_t) << + 2))) && (num_size / size != num))) + num_size = HUGE_MAXCLASS + 1; /* size_t overflow. */ + + if (likely(!malloc_slow)) { + ret = ialloc_body(num_size, true, &tsdn, &usize, false); + ialloc_post_check(ret, tsdn, usize, "calloc", true, false); + } else { + ret = ialloc_body(num_size, true, &tsdn, &usize, true); + ialloc_post_check(ret, tsdn, usize, "calloc", true, true); + UTRACE(0, num_size, ret); + JEMALLOC_VALGRIND_MALLOC(ret != NULL, tsdn, ret, usize, true); + } + + return (ret); +} + +static void * +irealloc_prof_sample(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t usize, + prof_tctx_t *tctx) +{ + void *p; + + if (tctx == NULL) + return (NULL); + if (usize <= SMALL_MAXCLASS) { + p = iralloc(tsd, old_ptr, old_usize, LARGE_MINCLASS, 0, false); + if (p == NULL) + return (NULL); + arena_prof_promoted(tsd_tsdn(tsd), p, usize); + } else + p = iralloc(tsd, old_ptr, old_usize, usize, 0, false); + + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +irealloc_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t usize) +{ + void *p; + bool prof_active; + prof_tctx_t *old_tctx, *tctx; + + prof_active = prof_active_get_unlocked(); + old_tctx = prof_tctx_get(tsd_tsdn(tsd), old_ptr); + tctx = prof_alloc_prep(tsd, usize, prof_active, true); + if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) + p = irealloc_prof_sample(tsd, old_ptr, old_usize, usize, tctx); + else + p = iralloc(tsd, old_ptr, old_usize, usize, 0, false); + if (unlikely(p == NULL)) { + prof_alloc_rollback(tsd, tctx, true); + return (NULL); + } + prof_realloc(tsd, p, usize, tctx, prof_active, true, old_ptr, old_usize, + old_tctx); + + return (p); +} + +JEMALLOC_INLINE_C void +ifree(tsd_t *tsd, void *ptr, tcache_t *tcache, bool slow_path) +{ + size_t usize; + UNUSED size_t rzsize JEMALLOC_CC_SILENCE_INIT(0); + + witness_assert_lockless(tsd_tsdn(tsd)); + + assert(ptr != NULL); + assert(malloc_initialized() || IS_INITIALIZER); + + if (config_prof && opt_prof) { + usize = isalloc(tsd_tsdn(tsd), ptr, config_prof); + prof_free(tsd, ptr, usize); + } else if (config_stats || config_valgrind) + usize = isalloc(tsd_tsdn(tsd), ptr, config_prof); + if (config_stats) + *tsd_thread_deallocatedp_get(tsd) += usize; + + if (likely(!slow_path)) + iqalloc(tsd, ptr, tcache, false); + else { + if (config_valgrind && unlikely(in_valgrind)) + rzsize = p2rz(tsd_tsdn(tsd), ptr); + iqalloc(tsd, ptr, tcache, true); + JEMALLOC_VALGRIND_FREE(ptr, rzsize); + } +} + +JEMALLOC_INLINE_C void +isfree(tsd_t *tsd, void *ptr, size_t usize, tcache_t *tcache, bool slow_path) +{ + UNUSED size_t rzsize JEMALLOC_CC_SILENCE_INIT(0); + + witness_assert_lockless(tsd_tsdn(tsd)); + + assert(ptr != NULL); + assert(malloc_initialized() || IS_INITIALIZER); + + if (config_prof && opt_prof) + prof_free(tsd, ptr, usize); + if (config_stats) + *tsd_thread_deallocatedp_get(tsd) += usize; + if (config_valgrind && unlikely(in_valgrind)) + rzsize = p2rz(tsd_tsdn(tsd), ptr); + isqalloc(tsd, ptr, usize, tcache, slow_path); + JEMALLOC_VALGRIND_FREE(ptr, rzsize); +} + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ALLOC_SIZE(2) +je_realloc(void *ptr, size_t size) +{ + void *ret; + tsdn_t *tsdn JEMALLOC_CC_SILENCE_INIT(NULL); + size_t usize JEMALLOC_CC_SILENCE_INIT(0); + size_t old_usize = 0; + UNUSED size_t old_rzsize JEMALLOC_CC_SILENCE_INIT(0); + + if (unlikely(size == 0)) { + if (ptr != NULL) { + tsd_t *tsd; + + /* realloc(ptr, 0) is equivalent to free(ptr). */ + UTRACE(ptr, 0, 0); + tsd = tsd_fetch(); + ifree(tsd, ptr, tcache_get(tsd, false), true); + return (NULL); + } + size = 1; + } + + if (likely(ptr != NULL)) { + tsd_t *tsd; + + assert(malloc_initialized() || IS_INITIALIZER); + malloc_thread_init(); + tsd = tsd_fetch(); + + witness_assert_lockless(tsd_tsdn(tsd)); + + old_usize = isalloc(tsd_tsdn(tsd), ptr, config_prof); + if (config_valgrind && unlikely(in_valgrind)) { + old_rzsize = config_prof ? p2rz(tsd_tsdn(tsd), ptr) : + u2rz(old_usize); + } + + if (config_prof && opt_prof) { + usize = s2u(size); + ret = unlikely(usize == 0 || usize > HUGE_MAXCLASS) ? + NULL : irealloc_prof(tsd, ptr, old_usize, usize); + } else { + if (config_stats || (config_valgrind && + unlikely(in_valgrind))) + usize = s2u(size); + ret = iralloc(tsd, ptr, old_usize, size, 0, false); + } + tsdn = tsd_tsdn(tsd); + } else { + /* realloc(NULL, size) is equivalent to malloc(size). */ + if (likely(!malloc_slow)) + ret = ialloc_body(size, false, &tsdn, &usize, false); + else + ret = ialloc_body(size, false, &tsdn, &usize, true); + assert(!tsdn_null(tsdn) || ret == NULL); + } + + if (unlikely(ret == NULL)) { + if (config_xmalloc && unlikely(opt_xmalloc)) { + malloc_write(": Error in realloc(): " + "out of memory\n"); + abort(); + } + set_errno(ENOMEM); + } + if (config_stats && likely(ret != NULL)) { + tsd_t *tsd; + + assert(usize == isalloc(tsdn, ret, config_prof)); + tsd = tsdn_tsd(tsdn); + *tsd_thread_allocatedp_get(tsd) += usize; + *tsd_thread_deallocatedp_get(tsd) += old_usize; + } + UTRACE(ptr, size, ret); + JEMALLOC_VALGRIND_REALLOC(true, tsdn, ret, usize, true, ptr, old_usize, + old_rzsize, true, false); + witness_assert_lockless(tsdn); + return (ret); +} + +JEMALLOC_EXPORT void JEMALLOC_NOTHROW +je_free(void *ptr) +{ + + UTRACE(ptr, 0, 0); + if (likely(ptr != NULL)) { + tsd_t *tsd = tsd_fetch(); + witness_assert_lockless(tsd_tsdn(tsd)); + if (likely(!malloc_slow)) + ifree(tsd, ptr, tcache_get(tsd, false), false); + else + ifree(tsd, ptr, tcache_get(tsd, false), true); + witness_assert_lockless(tsd_tsdn(tsd)); + } +} + +/* + * End malloc(3)-compatible functions. + */ +/******************************************************************************/ +/* + * Begin non-standard override functions. + */ + +#ifdef JEMALLOC_OVERRIDE_MEMALIGN +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ATTR(malloc) +je_memalign(size_t alignment, size_t size) +{ + void *ret JEMALLOC_CC_SILENCE_INIT(NULL); + if (unlikely(imemalign(&ret, alignment, size, 1) != 0)) + ret = NULL; + return (ret); +} +#endif + +#ifdef JEMALLOC_OVERRIDE_VALLOC +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ATTR(malloc) +je_valloc(size_t size) +{ + void *ret JEMALLOC_CC_SILENCE_INIT(NULL); + if (unlikely(imemalign(&ret, PAGE, size, 1) != 0)) + ret = NULL; + return (ret); +} +#endif + +/* + * is_malloc(je_malloc) is some macro magic to detect if jemalloc_defs.h has + * #define je_malloc malloc + */ +#define malloc_is_malloc 1 +#define is_malloc_(a) malloc_is_ ## a +#define is_malloc(a) is_malloc_(a) + +#if ((is_malloc(je_malloc) == 1) && defined(JEMALLOC_GLIBC_MALLOC_HOOK)) +/* + * glibc provides the RTLD_DEEPBIND flag for dlopen which can make it possible + * to inconsistently reference libc's malloc(3)-compatible functions + * (https://bugzilla.mozilla.org/show_bug.cgi?id=493541). + * + * These definitions interpose hooks in glibc. The functions are actually + * passed an extra argument for the caller return address, which will be + * ignored. + */ +JEMALLOC_EXPORT void (*__free_hook)(void *ptr) = je_free; +JEMALLOC_EXPORT void *(*__malloc_hook)(size_t size) = je_malloc; +JEMALLOC_EXPORT void *(*__realloc_hook)(void *ptr, size_t size) = je_realloc; +# ifdef JEMALLOC_GLIBC_MEMALIGN_HOOK +JEMALLOC_EXPORT void *(*__memalign_hook)(size_t alignment, size_t size) = + je_memalign; +# endif +#endif + +/* + * End non-standard override functions. + */ +/******************************************************************************/ +/* + * Begin non-standard functions. + */ + +JEMALLOC_ALWAYS_INLINE_C bool +imallocx_flags_decode(tsd_t *tsd, size_t size, int flags, size_t *usize, + size_t *alignment, bool *zero, tcache_t **tcache, arena_t **arena) +{ + + if ((flags & MALLOCX_LG_ALIGN_MASK) == 0) { + *alignment = 0; + *usize = s2u(size); + } else { + *alignment = MALLOCX_ALIGN_GET_SPECIFIED(flags); + *usize = sa2u(size, *alignment); + } + if (unlikely(*usize == 0 || *usize > HUGE_MAXCLASS)) + return (true); + *zero = MALLOCX_ZERO_GET(flags); + if ((flags & MALLOCX_TCACHE_MASK) != 0) { + if ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE) + *tcache = NULL; + else + *tcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags)); + } else + *tcache = tcache_get(tsd, true); + if ((flags & MALLOCX_ARENA_MASK) != 0) { + unsigned arena_ind = MALLOCX_ARENA_GET(flags); + *arena = arena_get(tsd_tsdn(tsd), arena_ind, true); + if (unlikely(*arena == NULL)) + return (true); + } else + *arena = NULL; + return (false); +} + +JEMALLOC_ALWAYS_INLINE_C void * +imallocx_flags(tsdn_t *tsdn, size_t usize, size_t alignment, bool zero, + tcache_t *tcache, arena_t *arena, bool slow_path) +{ + szind_t ind; + + if (unlikely(alignment != 0)) + return (ipalloct(tsdn, usize, alignment, zero, tcache, arena)); + ind = size2index(usize); + assert(ind < NSIZES); + return (iallocztm(tsdn, usize, ind, zero, tcache, false, arena, + slow_path)); +} + +static void * +imallocx_prof_sample(tsdn_t *tsdn, size_t usize, size_t alignment, bool zero, + tcache_t *tcache, arena_t *arena, bool slow_path) +{ + void *p; + + if (usize <= SMALL_MAXCLASS) { + assert(((alignment == 0) ? s2u(LARGE_MINCLASS) : + sa2u(LARGE_MINCLASS, alignment)) == LARGE_MINCLASS); + p = imallocx_flags(tsdn, LARGE_MINCLASS, alignment, zero, + tcache, arena, slow_path); + if (p == NULL) + return (NULL); + arena_prof_promoted(tsdn, p, usize); + } else { + p = imallocx_flags(tsdn, usize, alignment, zero, tcache, arena, + slow_path); + } + + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +imallocx_prof(tsd_t *tsd, size_t size, int flags, size_t *usize, bool slow_path) +{ + void *p; + size_t alignment; + bool zero; + tcache_t *tcache; + arena_t *arena; + prof_tctx_t *tctx; + + if (unlikely(imallocx_flags_decode(tsd, size, flags, usize, &alignment, + &zero, &tcache, &arena))) + return (NULL); + tctx = prof_alloc_prep(tsd, *usize, prof_active_get_unlocked(), true); + if (likely((uintptr_t)tctx == (uintptr_t)1U)) { + p = imallocx_flags(tsd_tsdn(tsd), *usize, alignment, zero, + tcache, arena, slow_path); + } else if ((uintptr_t)tctx > (uintptr_t)1U) { + p = imallocx_prof_sample(tsd_tsdn(tsd), *usize, alignment, zero, + tcache, arena, slow_path); + } else + p = NULL; + if (unlikely(p == NULL)) { + prof_alloc_rollback(tsd, tctx, true); + return (NULL); + } + prof_malloc(tsd_tsdn(tsd), p, *usize, tctx); + + assert(alignment == 0 || ((uintptr_t)p & (alignment - 1)) == ZU(0)); + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +imallocx_no_prof(tsd_t *tsd, size_t size, int flags, size_t *usize, + bool slow_path) +{ + void *p; + size_t alignment; + bool zero; + tcache_t *tcache; + arena_t *arena; + + if (unlikely(imallocx_flags_decode(tsd, size, flags, usize, &alignment, + &zero, &tcache, &arena))) + return (NULL); + p = imallocx_flags(tsd_tsdn(tsd), *usize, alignment, zero, tcache, + arena, slow_path); + assert(alignment == 0 || ((uintptr_t)p & (alignment - 1)) == ZU(0)); + return (p); +} + +/* This function guarantees that *tsdn is non-NULL on success. */ +JEMALLOC_ALWAYS_INLINE_C void * +imallocx_body(size_t size, int flags, tsdn_t **tsdn, size_t *usize, + bool slow_path) +{ + tsd_t *tsd; + + if (slow_path && unlikely(malloc_init())) { + *tsdn = NULL; + return (NULL); + } + + tsd = tsd_fetch(); + *tsdn = tsd_tsdn(tsd); + witness_assert_lockless(tsd_tsdn(tsd)); + + if (likely(flags == 0)) { + szind_t ind = size2index(size); + if (unlikely(ind >= NSIZES)) + return (NULL); + if (config_stats || (config_prof && opt_prof) || (slow_path && + config_valgrind && unlikely(in_valgrind))) { + *usize = index2size(ind); + assert(*usize > 0 && *usize <= HUGE_MAXCLASS); + } + + if (config_prof && opt_prof) { + return (ialloc_prof(tsd, *usize, ind, false, + slow_path)); + } + + return (ialloc(tsd, size, ind, false, slow_path)); + } + + if (config_prof && opt_prof) + return (imallocx_prof(tsd, size, flags, usize, slow_path)); + + return (imallocx_no_prof(tsd, size, flags, usize, slow_path)); +} + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1) +je_mallocx(size_t size, int flags) +{ + tsdn_t *tsdn; + void *p; + size_t usize; + + assert(size != 0); + + if (likely(!malloc_slow)) { + p = imallocx_body(size, flags, &tsdn, &usize, false); + ialloc_post_check(p, tsdn, usize, "mallocx", false, false); + } else { + p = imallocx_body(size, flags, &tsdn, &usize, true); + ialloc_post_check(p, tsdn, usize, "mallocx", false, true); + UTRACE(0, size, p); + JEMALLOC_VALGRIND_MALLOC(p != NULL, tsdn, p, usize, + MALLOCX_ZERO_GET(flags)); + } + + return (p); +} + +static void * +irallocx_prof_sample(tsd_t *tsd, void *old_ptr, size_t old_usize, + size_t usize, size_t alignment, bool zero, tcache_t *tcache, arena_t *arena, + prof_tctx_t *tctx) +{ + void *p; + + if (tctx == NULL) + return (NULL); + if (usize <= SMALL_MAXCLASS) { + p = iralloct(tsd, old_ptr, old_usize, LARGE_MINCLASS, alignment, + zero, tcache, arena); + if (p == NULL) + return (NULL); + arena_prof_promoted(tsd_tsdn(tsd), p, usize); + } else { + p = iralloct(tsd, old_ptr, old_usize, usize, alignment, zero, + tcache, arena); + } + + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +irallocx_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t size, + size_t alignment, size_t *usize, bool zero, tcache_t *tcache, + arena_t *arena) +{ + void *p; + bool prof_active; + prof_tctx_t *old_tctx, *tctx; + + prof_active = prof_active_get_unlocked(); + old_tctx = prof_tctx_get(tsd_tsdn(tsd), old_ptr); + tctx = prof_alloc_prep(tsd, *usize, prof_active, false); + if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) { + p = irallocx_prof_sample(tsd, old_ptr, old_usize, *usize, + alignment, zero, tcache, arena, tctx); + } else { + p = iralloct(tsd, old_ptr, old_usize, size, alignment, zero, + tcache, arena); + } + if (unlikely(p == NULL)) { + prof_alloc_rollback(tsd, tctx, false); + return (NULL); + } + + if (p == old_ptr && alignment != 0) { + /* + * The allocation did not move, so it is possible that the size + * class is smaller than would guarantee the requested + * alignment, and that the alignment constraint was + * serendipitously satisfied. Additionally, old_usize may not + * be the same as the current usize because of in-place large + * reallocation. Therefore, query the actual value of usize. + */ + *usize = isalloc(tsd_tsdn(tsd), p, config_prof); + } + prof_realloc(tsd, p, *usize, tctx, prof_active, false, old_ptr, + old_usize, old_tctx); + + return (p); +} + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ALLOC_SIZE(2) +je_rallocx(void *ptr, size_t size, int flags) +{ + void *p; + tsd_t *tsd; + size_t usize; + size_t old_usize; + UNUSED size_t old_rzsize JEMALLOC_CC_SILENCE_INIT(0); + size_t alignment = MALLOCX_ALIGN_GET(flags); + bool zero = flags & MALLOCX_ZERO; + arena_t *arena; + tcache_t *tcache; + + assert(ptr != NULL); + assert(size != 0); + assert(malloc_initialized() || IS_INITIALIZER); + malloc_thread_init(); + tsd = tsd_fetch(); + witness_assert_lockless(tsd_tsdn(tsd)); + + if (unlikely((flags & MALLOCX_ARENA_MASK) != 0)) { + unsigned arena_ind = MALLOCX_ARENA_GET(flags); + arena = arena_get(tsd_tsdn(tsd), arena_ind, true); + if (unlikely(arena == NULL)) + goto label_oom; + } else + arena = NULL; + + if (unlikely((flags & MALLOCX_TCACHE_MASK) != 0)) { + if ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE) + tcache = NULL; + else + tcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags)); + } else + tcache = tcache_get(tsd, true); + + old_usize = isalloc(tsd_tsdn(tsd), ptr, config_prof); + if (config_valgrind && unlikely(in_valgrind)) + old_rzsize = u2rz(old_usize); + + if (config_prof && opt_prof) { + usize = (alignment == 0) ? s2u(size) : sa2u(size, alignment); + if (unlikely(usize == 0 || usize > HUGE_MAXCLASS)) + goto label_oom; + p = irallocx_prof(tsd, ptr, old_usize, size, alignment, &usize, + zero, tcache, arena); + if (unlikely(p == NULL)) + goto label_oom; + } else { + p = iralloct(tsd, ptr, old_usize, size, alignment, zero, + tcache, arena); + if (unlikely(p == NULL)) + goto label_oom; + if (config_stats || (config_valgrind && unlikely(in_valgrind))) + usize = isalloc(tsd_tsdn(tsd), p, config_prof); + } + assert(alignment == 0 || ((uintptr_t)p & (alignment - 1)) == ZU(0)); + + if (config_stats) { + *tsd_thread_allocatedp_get(tsd) += usize; + *tsd_thread_deallocatedp_get(tsd) += old_usize; + } + UTRACE(ptr, size, p); + JEMALLOC_VALGRIND_REALLOC(true, tsd_tsdn(tsd), p, usize, false, ptr, + old_usize, old_rzsize, false, zero); + witness_assert_lockless(tsd_tsdn(tsd)); + return (p); +label_oom: + if (config_xmalloc && unlikely(opt_xmalloc)) { + malloc_write(": Error in rallocx(): out of memory\n"); + abort(); + } + UTRACE(ptr, size, 0); + witness_assert_lockless(tsd_tsdn(tsd)); + return (NULL); +} + +JEMALLOC_ALWAYS_INLINE_C size_t +ixallocx_helper(tsdn_t *tsdn, void *ptr, size_t old_usize, size_t size, + size_t extra, size_t alignment, bool zero) +{ + size_t usize; + + if (ixalloc(tsdn, ptr, old_usize, size, extra, alignment, zero)) + return (old_usize); + usize = isalloc(tsdn, ptr, config_prof); + + return (usize); +} + +static size_t +ixallocx_prof_sample(tsdn_t *tsdn, void *ptr, size_t old_usize, size_t size, + size_t extra, size_t alignment, bool zero, prof_tctx_t *tctx) +{ + size_t usize; + + if (tctx == NULL) + return (old_usize); + usize = ixallocx_helper(tsdn, ptr, old_usize, size, extra, alignment, + zero); + + return (usize); +} + +JEMALLOC_ALWAYS_INLINE_C size_t +ixallocx_prof(tsd_t *tsd, void *ptr, size_t old_usize, size_t size, + size_t extra, size_t alignment, bool zero) +{ + size_t usize_max, usize; + bool prof_active; + prof_tctx_t *old_tctx, *tctx; + + prof_active = prof_active_get_unlocked(); + old_tctx = prof_tctx_get(tsd_tsdn(tsd), ptr); + /* + * usize isn't knowable before ixalloc() returns when extra is non-zero. + * Therefore, compute its maximum possible value and use that in + * prof_alloc_prep() to decide whether to capture a backtrace. + * prof_realloc() will use the actual usize to decide whether to sample. + */ + if (alignment == 0) { + usize_max = s2u(size+extra); + assert(usize_max > 0 && usize_max <= HUGE_MAXCLASS); + } else { + usize_max = sa2u(size+extra, alignment); + if (unlikely(usize_max == 0 || usize_max > HUGE_MAXCLASS)) { + /* + * usize_max is out of range, and chances are that + * allocation will fail, but use the maximum possible + * value and carry on with prof_alloc_prep(), just in + * case allocation succeeds. + */ + usize_max = HUGE_MAXCLASS; + } + } + tctx = prof_alloc_prep(tsd, usize_max, prof_active, false); + + if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) { + usize = ixallocx_prof_sample(tsd_tsdn(tsd), ptr, old_usize, + size, extra, alignment, zero, tctx); + } else { + usize = ixallocx_helper(tsd_tsdn(tsd), ptr, old_usize, size, + extra, alignment, zero); + } + if (usize == old_usize) { + prof_alloc_rollback(tsd, tctx, false); + return (usize); + } + prof_realloc(tsd, ptr, usize, tctx, prof_active, false, ptr, old_usize, + old_tctx); + + return (usize); +} + +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW +je_xallocx(void *ptr, size_t size, size_t extra, int flags) +{ + tsd_t *tsd; + size_t usize, old_usize; + UNUSED size_t old_rzsize JEMALLOC_CC_SILENCE_INIT(0); + size_t alignment = MALLOCX_ALIGN_GET(flags); + bool zero = flags & MALLOCX_ZERO; + + assert(ptr != NULL); + assert(size != 0); + assert(SIZE_T_MAX - size >= extra); + assert(malloc_initialized() || IS_INITIALIZER); + malloc_thread_init(); + tsd = tsd_fetch(); + witness_assert_lockless(tsd_tsdn(tsd)); + + old_usize = isalloc(tsd_tsdn(tsd), ptr, config_prof); + + /* + * The API explicitly absolves itself of protecting against (size + + * extra) numerical overflow, but we may need to clamp extra to avoid + * exceeding HUGE_MAXCLASS. + * + * Ordinarily, size limit checking is handled deeper down, but here we + * have to check as part of (size + extra) clamping, since we need the + * clamped value in the above helper functions. + */ + if (unlikely(size > HUGE_MAXCLASS)) { + usize = old_usize; + goto label_not_resized; + } + if (unlikely(HUGE_MAXCLASS - size < extra)) + extra = HUGE_MAXCLASS - size; + + if (config_valgrind && unlikely(in_valgrind)) + old_rzsize = u2rz(old_usize); + + if (config_prof && opt_prof) { + usize = ixallocx_prof(tsd, ptr, old_usize, size, extra, + alignment, zero); + } else { + usize = ixallocx_helper(tsd_tsdn(tsd), ptr, old_usize, size, + extra, alignment, zero); + } + if (unlikely(usize == old_usize)) + goto label_not_resized; + + if (config_stats) { + *tsd_thread_allocatedp_get(tsd) += usize; + *tsd_thread_deallocatedp_get(tsd) += old_usize; + } + JEMALLOC_VALGRIND_REALLOC(false, tsd_tsdn(tsd), ptr, usize, false, ptr, + old_usize, old_rzsize, false, zero); +label_not_resized: + UTRACE(ptr, size, ptr); + witness_assert_lockless(tsd_tsdn(tsd)); + return (usize); +} + +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW +JEMALLOC_ATTR(pure) +je_sallocx(const void *ptr, int flags) +{ + size_t usize; + tsdn_t *tsdn; + + assert(malloc_initialized() || IS_INITIALIZER); + malloc_thread_init(); + + tsdn = tsdn_fetch(); + witness_assert_lockless(tsdn); + + if (config_ivsalloc) + usize = ivsalloc(tsdn, ptr, config_prof); + else + usize = isalloc(tsdn, ptr, config_prof); + + witness_assert_lockless(tsdn); + return (usize); +} + +JEMALLOC_EXPORT void JEMALLOC_NOTHROW +je_dallocx(void *ptr, int flags) +{ + tsd_t *tsd; + tcache_t *tcache; + + assert(ptr != NULL); + assert(malloc_initialized() || IS_INITIALIZER); + + tsd = tsd_fetch(); + witness_assert_lockless(tsd_tsdn(tsd)); + if (unlikely((flags & MALLOCX_TCACHE_MASK) != 0)) { + if ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE) + tcache = NULL; + else + tcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags)); + } else + tcache = tcache_get(tsd, false); + + UTRACE(ptr, 0, 0); + if (likely(!malloc_slow)) + ifree(tsd, ptr, tcache, false); + else + ifree(tsd, ptr, tcache, true); + witness_assert_lockless(tsd_tsdn(tsd)); +} + +JEMALLOC_ALWAYS_INLINE_C size_t +inallocx(tsdn_t *tsdn, size_t size, int flags) +{ + size_t usize; + + witness_assert_lockless(tsdn); + + if (likely((flags & MALLOCX_LG_ALIGN_MASK) == 0)) + usize = s2u(size); + else + usize = sa2u(size, MALLOCX_ALIGN_GET_SPECIFIED(flags)); + witness_assert_lockless(tsdn); + return (usize); +} + +JEMALLOC_EXPORT void JEMALLOC_NOTHROW +je_sdallocx(void *ptr, size_t size, int flags) +{ + tsd_t *tsd; + tcache_t *tcache; + size_t usize; + + assert(ptr != NULL); + assert(malloc_initialized() || IS_INITIALIZER); + tsd = tsd_fetch(); + usize = inallocx(tsd_tsdn(tsd), size, flags); + assert(usize == isalloc(tsd_tsdn(tsd), ptr, config_prof)); + + witness_assert_lockless(tsd_tsdn(tsd)); + if (unlikely((flags & MALLOCX_TCACHE_MASK) != 0)) { + if ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE) + tcache = NULL; + else + tcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags)); + } else + tcache = tcache_get(tsd, false); + + UTRACE(ptr, 0, 0); + if (likely(!malloc_slow)) + isfree(tsd, ptr, usize, tcache, false); + else + isfree(tsd, ptr, usize, tcache, true); + witness_assert_lockless(tsd_tsdn(tsd)); +} + +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW +JEMALLOC_ATTR(pure) +je_nallocx(size_t size, int flags) +{ + size_t usize; + tsdn_t *tsdn; + + assert(size != 0); + + if (unlikely(malloc_init())) + return (0); + + tsdn = tsdn_fetch(); + witness_assert_lockless(tsdn); + + usize = inallocx(tsdn, size, flags); + if (unlikely(usize > HUGE_MAXCLASS)) + return (0); + + witness_assert_lockless(tsdn); + return (usize); +} + +JEMALLOC_EXPORT int JEMALLOC_NOTHROW +je_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, + size_t newlen) +{ + int ret; + tsd_t *tsd; + + if (unlikely(malloc_init())) + return (EAGAIN); + + tsd = tsd_fetch(); + witness_assert_lockless(tsd_tsdn(tsd)); + ret = ctl_byname(tsd, name, oldp, oldlenp, newp, newlen); + witness_assert_lockless(tsd_tsdn(tsd)); + return (ret); +} + +JEMALLOC_EXPORT int JEMALLOC_NOTHROW +je_mallctlnametomib(const char *name, size_t *mibp, size_t *miblenp) +{ + int ret; + tsdn_t *tsdn; + + if (unlikely(malloc_init())) + return (EAGAIN); + + tsdn = tsdn_fetch(); + witness_assert_lockless(tsdn); + ret = ctl_nametomib(tsdn, name, mibp, miblenp); + witness_assert_lockless(tsdn); + return (ret); +} + +JEMALLOC_EXPORT int JEMALLOC_NOTHROW +je_mallctlbymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + tsd_t *tsd; + + if (unlikely(malloc_init())) + return (EAGAIN); + + tsd = tsd_fetch(); + witness_assert_lockless(tsd_tsdn(tsd)); + ret = ctl_bymib(tsd, mib, miblen, oldp, oldlenp, newp, newlen); + witness_assert_lockless(tsd_tsdn(tsd)); + return (ret); +} + +JEMALLOC_EXPORT void JEMALLOC_NOTHROW +je_malloc_stats_print(void (*write_cb)(void *, const char *), void *cbopaque, + const char *opts) +{ + tsdn_t *tsdn; + + tsdn = tsdn_fetch(); + witness_assert_lockless(tsdn); + stats_print(write_cb, cbopaque, opts); + witness_assert_lockless(tsdn); +} + +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW +je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr) +{ + size_t ret; + tsdn_t *tsdn; + + assert(malloc_initialized() || IS_INITIALIZER); + malloc_thread_init(); + + tsdn = tsdn_fetch(); + witness_assert_lockless(tsdn); + + if (config_ivsalloc) + ret = ivsalloc(tsdn, ptr, config_prof); + else + ret = (ptr == NULL) ? 0 : isalloc(tsdn, ptr, config_prof); + + witness_assert_lockless(tsdn); + return (ret); +} + +/* + * End non-standard functions. + */ +/******************************************************************************/ +/* + * Begin compatibility functions. + */ + +#define ALLOCM_LG_ALIGN(la) (la) +#define ALLOCM_ALIGN(a) (ffsl(a)-1) +#define ALLOCM_ZERO ((int)0x40) +#define ALLOCM_NO_MOVE ((int)0x80) + +#define ALLOCM_SUCCESS 0 +#define ALLOCM_ERR_OOM 1 +#define ALLOCM_ERR_NOT_MOVED 2 + +int +je_allocm(void **ptr, size_t *rsize, size_t size, int flags) +{ + void *p; + + assert(ptr != NULL); + + p = je_mallocx(size, flags); + if (p == NULL) + return (ALLOCM_ERR_OOM); + if (rsize != NULL) + *rsize = isalloc(tsdn_fetch(), p, config_prof); + *ptr = p; + return (ALLOCM_SUCCESS); +} + +int +je_rallocm(void **ptr, size_t *rsize, size_t size, size_t extra, int flags) +{ + int ret; + bool no_move = flags & ALLOCM_NO_MOVE; + + assert(ptr != NULL); + assert(*ptr != NULL); + assert(size != 0); + assert(SIZE_T_MAX - size >= extra); + + if (no_move) { + size_t usize = je_xallocx(*ptr, size, extra, flags); + ret = (usize >= size) ? ALLOCM_SUCCESS : ALLOCM_ERR_NOT_MOVED; + if (rsize != NULL) + *rsize = usize; + } else { + void *p = je_rallocx(*ptr, size+extra, flags); + if (p != NULL) { + *ptr = p; + ret = ALLOCM_SUCCESS; + } else + ret = ALLOCM_ERR_OOM; + if (rsize != NULL) + *rsize = isalloc(tsdn_fetch(), *ptr, config_prof); + } + return (ret); +} + +int +je_sallocm(const void *ptr, size_t *rsize, int flags) +{ + + assert(rsize != NULL); + *rsize = je_sallocx(ptr, flags); + return (ALLOCM_SUCCESS); +} + +int +je_dallocm(void *ptr, int flags) +{ + + je_dallocx(ptr, flags); + return (ALLOCM_SUCCESS); +} + +int +je_nallocm(size_t *rsize, size_t size, int flags) +{ + size_t usize; + + usize = je_nallocx(size, flags); + if (usize == 0) + return (ALLOCM_ERR_OOM); + if (rsize != NULL) + *rsize = usize; + return (ALLOCM_SUCCESS); +} + +#undef ALLOCM_LG_ALIGN +#undef ALLOCM_ALIGN +#undef ALLOCM_ZERO +#undef ALLOCM_NO_MOVE + +#undef ALLOCM_SUCCESS +#undef ALLOCM_ERR_OOM +#undef ALLOCM_ERR_NOT_MOVED + +/* + * End compatibility functions. + */ +/******************************************************************************/ +/* + * The following functions are used by threading libraries for protection of + * malloc during fork(). + */ + +/* + * If an application creates a thread before doing any allocation in the main + * thread, then calls fork(2) in the main thread followed by memory allocation + * in the child process, a race can occur that results in deadlock within the + * child: the main thread may have forked while the created thread had + * partially initialized the allocator. Ordinarily jemalloc prevents + * fork/malloc races via the following functions it registers during + * initialization using pthread_atfork(), but of course that does no good if + * the allocator isn't fully initialized at fork time. The following library + * constructor is a partial solution to this problem. It may still be possible + * to trigger the deadlock described above, but doing so would involve forking + * via a library constructor that runs before jemalloc's runs. + */ +#ifndef JEMALLOC_JET +JEMALLOC_ATTR(constructor) +static void +jemalloc_constructor(void) +{ + + malloc_init(); +} +#endif + +#ifndef JEMALLOC_MUTEX_INIT_CB +void +jemalloc_prefork(void) +#else +JEMALLOC_EXPORT void +_malloc_prefork(void) +#endif +{ + tsd_t *tsd; + unsigned i, j, narenas; + arena_t *arena; + +#ifdef JEMALLOC_MUTEX_INIT_CB + if (!malloc_initialized()) + return; +#endif + assert(malloc_initialized()); + + tsd = tsd_fetch(); + + narenas = narenas_total_get(); + + witness_prefork(tsd); + /* Acquire all mutexes in a safe order. */ + ctl_prefork(tsd_tsdn(tsd)); + malloc_mutex_prefork(tsd_tsdn(tsd), &arenas_lock); + prof_prefork0(tsd_tsdn(tsd)); + for (i = 0; i < 3; i++) { + for (j = 0; j < narenas; j++) { + if ((arena = arena_get(tsd_tsdn(tsd), j, false)) != + NULL) { + switch (i) { + case 0: + arena_prefork0(tsd_tsdn(tsd), arena); + break; + case 1: + arena_prefork1(tsd_tsdn(tsd), arena); + break; + case 2: + arena_prefork2(tsd_tsdn(tsd), arena); + break; + default: not_reached(); + } + } + } + } + base_prefork(tsd_tsdn(tsd)); + chunk_prefork(tsd_tsdn(tsd)); + for (i = 0; i < narenas; i++) { + if ((arena = arena_get(tsd_tsdn(tsd), i, false)) != NULL) + arena_prefork3(tsd_tsdn(tsd), arena); + } + prof_prefork1(tsd_tsdn(tsd)); +} + +#ifndef JEMALLOC_MUTEX_INIT_CB +void +jemalloc_postfork_parent(void) +#else +JEMALLOC_EXPORT void +_malloc_postfork(void) +#endif +{ + tsd_t *tsd; + unsigned i, narenas; + +#ifdef JEMALLOC_MUTEX_INIT_CB + if (!malloc_initialized()) + return; +#endif + assert(malloc_initialized()); + + tsd = tsd_fetch(); + + witness_postfork_parent(tsd); + /* Release all mutexes, now that fork() has completed. */ + chunk_postfork_parent(tsd_tsdn(tsd)); + base_postfork_parent(tsd_tsdn(tsd)); + for (i = 0, narenas = narenas_total_get(); i < narenas; i++) { + arena_t *arena; + + if ((arena = arena_get(tsd_tsdn(tsd), i, false)) != NULL) + arena_postfork_parent(tsd_tsdn(tsd), arena); + } + prof_postfork_parent(tsd_tsdn(tsd)); + malloc_mutex_postfork_parent(tsd_tsdn(tsd), &arenas_lock); + ctl_postfork_parent(tsd_tsdn(tsd)); +} + +void +jemalloc_postfork_child(void) +{ + tsd_t *tsd; + unsigned i, narenas; + + assert(malloc_initialized()); + + tsd = tsd_fetch(); + + witness_postfork_child(tsd); + /* Release all mutexes, now that fork() has completed. */ + chunk_postfork_child(tsd_tsdn(tsd)); + base_postfork_child(tsd_tsdn(tsd)); + for (i = 0, narenas = narenas_total_get(); i < narenas; i++) { + arena_t *arena; + + if ((arena = arena_get(tsd_tsdn(tsd), i, false)) != NULL) + arena_postfork_child(tsd_tsdn(tsd), arena); + } + prof_postfork_child(tsd_tsdn(tsd)); + malloc_mutex_postfork_child(tsd_tsdn(tsd), &arenas_lock); + ctl_postfork_child(tsd_tsdn(tsd)); +} + +void +_malloc_first_thread(void) +{ + + (void)malloc_mutex_first_thread(); +} + +/******************************************************************************/ diff --git a/contrib/jemalloc/src/mb.c b/contrib/jemalloc/src/mb.c new file mode 100644 index 0000000..dc2c0a2 --- /dev/null +++ b/contrib/jemalloc/src/mb.c @@ -0,0 +1,2 @@ +#define JEMALLOC_MB_C_ +#include "jemalloc/internal/jemalloc_internal.h" diff --git a/contrib/jemalloc/src/mutex.c b/contrib/jemalloc/src/mutex.c new file mode 100644 index 0000000..a24e420 --- /dev/null +++ b/contrib/jemalloc/src/mutex.c @@ -0,0 +1,178 @@ +#define JEMALLOC_MUTEX_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +#if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) +#include +#endif + +#ifndef _CRT_SPINCOUNT +#define _CRT_SPINCOUNT 4000 +#endif + +/******************************************************************************/ +/* Data. */ + +#ifdef JEMALLOC_LAZY_LOCK +bool isthreaded = false; +#endif +#ifdef JEMALLOC_MUTEX_INIT_CB +static bool postpone_init = true; +static malloc_mutex_t *postponed_mutexes = NULL; +#endif + +#if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) +static void pthread_create_once(void); +#endif + +/******************************************************************************/ +/* + * We intercept pthread_create() calls in order to toggle isthreaded if the + * process goes multi-threaded. + */ + +#if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) +static int (*pthread_create_fptr)(pthread_t *__restrict, const pthread_attr_t *, + void *(*)(void *), void *__restrict); + +static void +pthread_create_once(void) +{ + + pthread_create_fptr = dlsym(RTLD_NEXT, "pthread_create"); + if (pthread_create_fptr == NULL) { + malloc_write(": Error in dlsym(RTLD_NEXT, " + "\"pthread_create\")\n"); + abort(); + } + + isthreaded = true; +} + +JEMALLOC_EXPORT int +pthread_create(pthread_t *__restrict thread, + const pthread_attr_t *__restrict attr, void *(*start_routine)(void *), + void *__restrict arg) +{ + static pthread_once_t once_control = PTHREAD_ONCE_INIT; + + pthread_once(&once_control, pthread_create_once); + + return (pthread_create_fptr(thread, attr, start_routine, arg)); +} +#endif + +/******************************************************************************/ + +#ifdef JEMALLOC_MUTEX_INIT_CB +JEMALLOC_EXPORT int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, + void *(calloc_cb)(size_t, size_t)); + +#pragma weak _pthread_mutex_init_calloc_cb +int +_pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, + void *(calloc_cb)(size_t, size_t)) +{ + + return (((int (*)(pthread_mutex_t *, void *(*)(size_t, size_t))) + __libc_interposing[INTERPOS__pthread_mutex_init_calloc_cb])(mutex, + calloc_cb)); +} +#endif + +bool +malloc_mutex_init(malloc_mutex_t *mutex, const char *name, witness_rank_t rank) +{ + +#ifdef _WIN32 +# if _WIN32_WINNT >= 0x0600 + InitializeSRWLock(&mutex->lock); +# else + if (!InitializeCriticalSectionAndSpinCount(&mutex->lock, + _CRT_SPINCOUNT)) + return (true); +# endif +#elif (defined(JEMALLOC_OSSPIN)) + mutex->lock = 0; +#elif (defined(JEMALLOC_MUTEX_INIT_CB)) + if (postpone_init) { + mutex->postponed_next = postponed_mutexes; + postponed_mutexes = mutex; + } else { + if (_pthread_mutex_init_calloc_cb(&mutex->lock, + bootstrap_calloc) != 0) + return (true); + } +#else + pthread_mutexattr_t attr; + + if (pthread_mutexattr_init(&attr) != 0) + return (true); + pthread_mutexattr_settype(&attr, MALLOC_MUTEX_TYPE); + if (pthread_mutex_init(&mutex->lock, &attr) != 0) { + pthread_mutexattr_destroy(&attr); + return (true); + } + pthread_mutexattr_destroy(&attr); +#endif + if (config_debug) + witness_init(&mutex->witness, name, rank, NULL); + return (false); +} + +void +malloc_mutex_prefork(tsdn_t *tsdn, malloc_mutex_t *mutex) +{ + + malloc_mutex_lock(tsdn, mutex); +} + +void +malloc_mutex_postfork_parent(tsdn_t *tsdn, malloc_mutex_t *mutex) +{ + + malloc_mutex_unlock(tsdn, mutex); +} + +void +malloc_mutex_postfork_child(tsdn_t *tsdn, malloc_mutex_t *mutex) +{ + +#ifdef JEMALLOC_MUTEX_INIT_CB + malloc_mutex_unlock(tsdn, mutex); +#else + if (malloc_mutex_init(mutex, mutex->witness.name, + mutex->witness.rank)) { + malloc_printf(": Error re-initializing mutex in " + "child\n"); + if (opt_abort) + abort(); + } +#endif +} + +bool +malloc_mutex_first_thread(void) +{ + +#ifdef JEMALLOC_MUTEX_INIT_CB + postpone_init = false; + while (postponed_mutexes != NULL) { + if (_pthread_mutex_init_calloc_cb(&postponed_mutexes->lock, + bootstrap_calloc) != 0) + return (true); + postponed_mutexes = postponed_mutexes->postponed_next; + } +#endif + return (false); +} + +bool +malloc_mutex_boot(void) +{ + +#ifndef JEMALLOC_MUTEX_INIT_CB + return (malloc_mutex_first_thread()); +#else + return (false); +#endif +} diff --git a/contrib/jemalloc/src/nstime.c b/contrib/jemalloc/src/nstime.c new file mode 100644 index 0000000..aad2c26 --- /dev/null +++ b/contrib/jemalloc/src/nstime.c @@ -0,0 +1,150 @@ +#include "jemalloc/internal/jemalloc_internal.h" + +#define BILLION UINT64_C(1000000000) + +void +nstime_init(nstime_t *time, uint64_t ns) +{ + + time->ns = ns; +} + +void +nstime_init2(nstime_t *time, uint64_t sec, uint64_t nsec) +{ + + time->ns = sec * BILLION + nsec; +} + +uint64_t +nstime_ns(const nstime_t *time) +{ + + return (time->ns); +} + +uint64_t +nstime_sec(const nstime_t *time) +{ + + return (time->ns / BILLION); +} + +uint64_t +nstime_nsec(const nstime_t *time) +{ + + return (time->ns % BILLION); +} + +void +nstime_copy(nstime_t *time, const nstime_t *source) +{ + + *time = *source; +} + +int +nstime_compare(const nstime_t *a, const nstime_t *b) +{ + + return ((a->ns > b->ns) - (a->ns < b->ns)); +} + +void +nstime_add(nstime_t *time, const nstime_t *addend) +{ + + assert(UINT64_MAX - time->ns >= addend->ns); + + time->ns += addend->ns; +} + +void +nstime_subtract(nstime_t *time, const nstime_t *subtrahend) +{ + + assert(nstime_compare(time, subtrahend) >= 0); + + time->ns -= subtrahend->ns; +} + +void +nstime_imultiply(nstime_t *time, uint64_t multiplier) +{ + + assert((((time->ns | multiplier) & (UINT64_MAX << (sizeof(uint64_t) << + 2))) == 0) || ((time->ns * multiplier) / multiplier == time->ns)); + + time->ns *= multiplier; +} + +void +nstime_idivide(nstime_t *time, uint64_t divisor) +{ + + assert(divisor != 0); + + time->ns /= divisor; +} + +uint64_t +nstime_divide(const nstime_t *time, const nstime_t *divisor) +{ + + assert(divisor->ns != 0); + + return (time->ns / divisor->ns); +} + +#ifdef JEMALLOC_JET +#undef nstime_update +#define nstime_update JEMALLOC_N(n_nstime_update) +#endif +bool +nstime_update(nstime_t *time) +{ + nstime_t old_time; + + nstime_copy(&old_time, time); + +#ifdef _WIN32 + { + FILETIME ft; + uint64_t ticks; + GetSystemTimeAsFileTime(&ft); + ticks = (((uint64_t)ft.dwHighDateTime) << 32) | + ft.dwLowDateTime; + time->ns = ticks * 100; + } +#elif JEMALLOC_CLOCK_GETTIME + { + struct timespec ts; + + if (sysconf(_SC_MONOTONIC_CLOCK) > 0) + clock_gettime(CLOCK_MONOTONIC, &ts); + else + clock_gettime(CLOCK_REALTIME, &ts); + time->ns = ts.tv_sec * BILLION + ts.tv_nsec; + } +#else + { + struct timeval tv; + gettimeofday(&tv, NULL); + time->ns = tv.tv_sec * BILLION + tv.tv_usec * 1000; + } +#endif + + /* Handle non-monotonic clocks. */ + if (unlikely(nstime_compare(&old_time, time) > 0)) { + nstime_copy(time, &old_time); + return (true); + } + + return (false); +} +#ifdef JEMALLOC_JET +#undef nstime_update +#define nstime_update JEMALLOC_N(nstime_update) +nstime_update_t *nstime_update = JEMALLOC_N(n_nstime_update); +#endif diff --git a/contrib/jemalloc/src/pages.c b/contrib/jemalloc/src/pages.c new file mode 100644 index 0000000..2a9b7e3 --- /dev/null +++ b/contrib/jemalloc/src/pages.c @@ -0,0 +1,253 @@ +#define JEMALLOC_PAGES_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +#ifdef JEMALLOC_SYSCTL_VM_OVERCOMMIT +#include +#endif + +/******************************************************************************/ +/* Data. */ + +#ifndef _WIN32 +# define PAGES_PROT_COMMIT (PROT_READ | PROT_WRITE) +# define PAGES_PROT_DECOMMIT (PROT_NONE) +static int mmap_flags; +#endif +static bool os_overcommits; + +/******************************************************************************/ + +void * +pages_map(void *addr, size_t size, bool *commit) +{ + void *ret; + + assert(size != 0); + + if (os_overcommits) + *commit = true; + +#ifdef _WIN32 + /* + * If VirtualAlloc can't allocate at the given address when one is + * given, it fails and returns NULL. + */ + ret = VirtualAlloc(addr, size, MEM_RESERVE | (*commit ? MEM_COMMIT : 0), + PAGE_READWRITE); +#else + /* + * We don't use MAP_FIXED here, because it can cause the *replacement* + * of existing mappings, and we only want to create new mappings. + */ + { + int prot = *commit ? PAGES_PROT_COMMIT : PAGES_PROT_DECOMMIT; + + ret = mmap(addr, size, prot, mmap_flags, -1, 0); + } + assert(ret != NULL); + + if (ret == MAP_FAILED) + ret = NULL; + else if (addr != NULL && ret != addr) { + /* + * We succeeded in mapping memory, but not in the right place. + */ + pages_unmap(ret, size); + ret = NULL; + } +#endif + assert(ret == NULL || (addr == NULL && ret != addr) + || (addr != NULL && ret == addr)); + return (ret); +} + +void +pages_unmap(void *addr, size_t size) +{ + +#ifdef _WIN32 + if (VirtualFree(addr, 0, MEM_RELEASE) == 0) +#else + if (munmap(addr, size) == -1) +#endif + { + char buf[BUFERROR_BUF]; + + buferror(get_errno(), buf, sizeof(buf)); + malloc_printf(": Error in " +#ifdef _WIN32 + "VirtualFree" +#else + "munmap" +#endif + "(): %s\n", buf); + if (opt_abort) + abort(); + } +} + +void * +pages_trim(void *addr, size_t alloc_size, size_t leadsize, size_t size, + bool *commit) +{ + void *ret = (void *)((uintptr_t)addr + leadsize); + + assert(alloc_size >= leadsize + size); +#ifdef _WIN32 + { + void *new_addr; + + pages_unmap(addr, alloc_size); + new_addr = pages_map(ret, size, commit); + if (new_addr == ret) + return (ret); + if (new_addr) + pages_unmap(new_addr, size); + return (NULL); + } +#else + { + size_t trailsize = alloc_size - leadsize - size; + + if (leadsize != 0) + pages_unmap(addr, leadsize); + if (trailsize != 0) + pages_unmap((void *)((uintptr_t)ret + size), trailsize); + return (ret); + } +#endif +} + +static bool +pages_commit_impl(void *addr, size_t size, bool commit) +{ + + if (os_overcommits) + return (true); + +#ifdef _WIN32 + return (commit ? (addr != VirtualAlloc(addr, size, MEM_COMMIT, + PAGE_READWRITE)) : (!VirtualFree(addr, size, MEM_DECOMMIT))); +#else + { + int prot = commit ? PAGES_PROT_COMMIT : PAGES_PROT_DECOMMIT; + void *result = mmap(addr, size, prot, mmap_flags | MAP_FIXED, + -1, 0); + if (result == MAP_FAILED) + return (true); + if (result != addr) { + /* + * We succeeded in mapping memory, but not in the right + * place. + */ + pages_unmap(result, size); + return (true); + } + return (false); + } +#endif +} + +bool +pages_commit(void *addr, size_t size) +{ + + return (pages_commit_impl(addr, size, true)); +} + +bool +pages_decommit(void *addr, size_t size) +{ + + return (pages_commit_impl(addr, size, false)); +} + +bool +pages_purge(void *addr, size_t size) +{ + bool unzeroed; + +#ifdef _WIN32 + VirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE); + unzeroed = true; +#elif defined(JEMALLOC_HAVE_MADVISE) +# ifdef JEMALLOC_PURGE_MADVISE_DONTNEED +# define JEMALLOC_MADV_PURGE MADV_DONTNEED +# define JEMALLOC_MADV_ZEROS true +# elif defined(JEMALLOC_PURGE_MADVISE_FREE) +# define JEMALLOC_MADV_PURGE MADV_FREE +# define JEMALLOC_MADV_ZEROS false +# else +# error "No madvise(2) flag defined for purging unused dirty pages." +# endif + int err = madvise(addr, size, JEMALLOC_MADV_PURGE); + unzeroed = (!JEMALLOC_MADV_ZEROS || err != 0); +# undef JEMALLOC_MADV_PURGE +# undef JEMALLOC_MADV_ZEROS +#else + /* Last resort no-op. */ + unzeroed = true; +#endif + return (unzeroed); +} + +#ifdef JEMALLOC_SYSCTL_VM_OVERCOMMIT +static bool +os_overcommits_sysctl(void) +{ + int vm_overcommit; + size_t sz; + + sz = sizeof(vm_overcommit); + if (sysctlbyname("vm.overcommit", &vm_overcommit, &sz, NULL, 0) != 0) + return (false); /* Error. */ + + return ((vm_overcommit & 0x3) == 0); +} +#endif + +#ifdef JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY +static bool +os_overcommits_proc(void) +{ + int fd; + char buf[1]; + ssize_t nread; + + fd = open("/proc/sys/vm/overcommit_memory", O_RDONLY); + if (fd == -1) + return (false); /* Error. */ + + nread = read(fd, &buf, sizeof(buf)); + if (nread < 1) + return (false); /* Error. */ + /* + * /proc/sys/vm/overcommit_memory meanings: + * 0: Heuristic overcommit. + * 1: Always overcommit. + * 2: Never overcommit. + */ + return (buf[0] == '0' || buf[0] == '1'); +} +#endif + +void +pages_boot(void) +{ + +#ifndef _WIN32 + mmap_flags = MAP_PRIVATE | MAP_ANON; +#endif + +#ifdef JEMALLOC_SYSCTL_VM_OVERCOMMIT + os_overcommits = os_overcommits_sysctl(); +#elif defined(JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY) + os_overcommits = os_overcommits_proc(); +# ifdef MAP_NORESERVE + if (os_overcommits) + mmap_flags |= MAP_NORESERVE; +# endif +#else + os_overcommits = false; +#endif +} diff --git a/contrib/jemalloc/src/prng.c b/contrib/jemalloc/src/prng.c new file mode 100644 index 0000000..76646a2 --- /dev/null +++ b/contrib/jemalloc/src/prng.c @@ -0,0 +1,2 @@ +#define JEMALLOC_PRNG_C_ +#include "jemalloc/internal/jemalloc_internal.h" diff --git a/contrib/jemalloc/src/prof.c b/contrib/jemalloc/src/prof.c new file mode 100644 index 0000000..c1f58d4 --- /dev/null +++ b/contrib/jemalloc/src/prof.c @@ -0,0 +1,2358 @@ +#define JEMALLOC_PROF_C_ +#include "jemalloc/internal/jemalloc_internal.h" +/******************************************************************************/ + +#ifdef JEMALLOC_PROF_LIBUNWIND +#define UNW_LOCAL_ONLY +#include +#endif + +#ifdef JEMALLOC_PROF_LIBGCC +#include +#endif + +/******************************************************************************/ +/* Data. */ + +bool opt_prof = false; +bool opt_prof_active = true; +bool opt_prof_thread_active_init = true; +size_t opt_lg_prof_sample = LG_PROF_SAMPLE_DEFAULT; +ssize_t opt_lg_prof_interval = LG_PROF_INTERVAL_DEFAULT; +bool opt_prof_gdump = false; +bool opt_prof_final = false; +bool opt_prof_leak = false; +bool opt_prof_accum = false; +char opt_prof_prefix[ + /* Minimize memory bloat for non-prof builds. */ +#ifdef JEMALLOC_PROF + PATH_MAX + +#endif + 1]; + +/* + * Initialized as opt_prof_active, and accessed via + * prof_active_[gs]et{_unlocked,}(). + */ +bool prof_active; +static malloc_mutex_t prof_active_mtx; + +/* + * Initialized as opt_prof_thread_active_init, and accessed via + * prof_thread_active_init_[gs]et(). + */ +static bool prof_thread_active_init; +static malloc_mutex_t prof_thread_active_init_mtx; + +/* + * Initialized as opt_prof_gdump, and accessed via + * prof_gdump_[gs]et{_unlocked,}(). + */ +bool prof_gdump_val; +static malloc_mutex_t prof_gdump_mtx; + +uint64_t prof_interval = 0; + +size_t lg_prof_sample; + +/* + * Table of mutexes that are shared among gctx's. These are leaf locks, so + * there is no problem with using them for more than one gctx at the same time. + * The primary motivation for this sharing though is that gctx's are ephemeral, + * and destroying mutexes causes complications for systems that allocate when + * creating/destroying mutexes. + */ +static malloc_mutex_t *gctx_locks; +static unsigned cum_gctxs; /* Atomic counter. */ + +/* + * Table of mutexes that are shared among tdata's. No operations require + * holding multiple tdata locks, so there is no problem with using them for more + * than one tdata at the same time, even though a gctx lock may be acquired + * while holding a tdata lock. + */ +static malloc_mutex_t *tdata_locks; + +/* + * Global hash of (prof_bt_t *)-->(prof_gctx_t *). This is the master data + * structure that knows about all backtraces currently captured. + */ +static ckh_t bt2gctx; +static malloc_mutex_t bt2gctx_mtx; + +/* + * Tree of all extant prof_tdata_t structures, regardless of state, + * {attached,detached,expired}. + */ +static prof_tdata_tree_t tdatas; +static malloc_mutex_t tdatas_mtx; + +static uint64_t next_thr_uid; +static malloc_mutex_t next_thr_uid_mtx; + +static malloc_mutex_t prof_dump_seq_mtx; +static uint64_t prof_dump_seq; +static uint64_t prof_dump_iseq; +static uint64_t prof_dump_mseq; +static uint64_t prof_dump_useq; + +/* + * This buffer is rather large for stack allocation, so use a single buffer for + * all profile dumps. + */ +static malloc_mutex_t prof_dump_mtx; +static char prof_dump_buf[ + /* Minimize memory bloat for non-prof builds. */ +#ifdef JEMALLOC_PROF + PROF_DUMP_BUFSIZE +#else + 1 +#endif +]; +static size_t prof_dump_buf_end; +static int prof_dump_fd; + +/* Do not dump any profiles until bootstrapping is complete. */ +static bool prof_booted = false; + +/******************************************************************************/ +/* + * Function prototypes for static functions that are referenced prior to + * definition. + */ + +static bool prof_tctx_should_destroy(tsdn_t *tsdn, prof_tctx_t *tctx); +static void prof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx); +static bool prof_tdata_should_destroy(tsdn_t *tsdn, prof_tdata_t *tdata, + bool even_if_attached); +static void prof_tdata_destroy(tsdn_t *tsdn, prof_tdata_t *tdata, + bool even_if_attached); +static char *prof_thread_name_alloc(tsdn_t *tsdn, const char *thread_name); + +/******************************************************************************/ +/* Red-black trees. */ + +JEMALLOC_INLINE_C int +prof_tctx_comp(const prof_tctx_t *a, const prof_tctx_t *b) +{ + uint64_t a_thr_uid = a->thr_uid; + uint64_t b_thr_uid = b->thr_uid; + int ret = (a_thr_uid > b_thr_uid) - (a_thr_uid < b_thr_uid); + if (ret == 0) { + uint64_t a_thr_discrim = a->thr_discrim; + uint64_t b_thr_discrim = b->thr_discrim; + ret = (a_thr_discrim > b_thr_discrim) - (a_thr_discrim < + b_thr_discrim); + if (ret == 0) { + uint64_t a_tctx_uid = a->tctx_uid; + uint64_t b_tctx_uid = b->tctx_uid; + ret = (a_tctx_uid > b_tctx_uid) - (a_tctx_uid < + b_tctx_uid); + } + } + return (ret); +} + +rb_gen(static UNUSED, tctx_tree_, prof_tctx_tree_t, prof_tctx_t, + tctx_link, prof_tctx_comp) + +JEMALLOC_INLINE_C int +prof_gctx_comp(const prof_gctx_t *a, const prof_gctx_t *b) +{ + unsigned a_len = a->bt.len; + unsigned b_len = b->bt.len; + unsigned comp_len = (a_len < b_len) ? a_len : b_len; + int ret = memcmp(a->bt.vec, b->bt.vec, comp_len * sizeof(void *)); + if (ret == 0) + ret = (a_len > b_len) - (a_len < b_len); + return (ret); +} + +rb_gen(static UNUSED, gctx_tree_, prof_gctx_tree_t, prof_gctx_t, dump_link, + prof_gctx_comp) + +JEMALLOC_INLINE_C int +prof_tdata_comp(const prof_tdata_t *a, const prof_tdata_t *b) +{ + int ret; + uint64_t a_uid = a->thr_uid; + uint64_t b_uid = b->thr_uid; + + ret = ((a_uid > b_uid) - (a_uid < b_uid)); + if (ret == 0) { + uint64_t a_discrim = a->thr_discrim; + uint64_t b_discrim = b->thr_discrim; + + ret = ((a_discrim > b_discrim) - (a_discrim < b_discrim)); + } + return (ret); +} + +rb_gen(static UNUSED, tdata_tree_, prof_tdata_tree_t, prof_tdata_t, tdata_link, + prof_tdata_comp) + +/******************************************************************************/ + +void +prof_alloc_rollback(tsd_t *tsd, prof_tctx_t *tctx, bool updated) +{ + prof_tdata_t *tdata; + + cassert(config_prof); + + if (updated) { + /* + * Compute a new sample threshold. This isn't very important in + * practice, because this function is rarely executed, so the + * potential for sample bias is minimal except in contrived + * programs. + */ + tdata = prof_tdata_get(tsd, true); + if (tdata != NULL) + prof_sample_threshold_update(tdata); + } + + if ((uintptr_t)tctx > (uintptr_t)1U) { + malloc_mutex_lock(tsd_tsdn(tsd), tctx->tdata->lock); + tctx->prepared = false; + if (prof_tctx_should_destroy(tsd_tsdn(tsd), tctx)) + prof_tctx_destroy(tsd, tctx); + else + malloc_mutex_unlock(tsd_tsdn(tsd), tctx->tdata->lock); + } +} + +void +prof_malloc_sample_object(tsdn_t *tsdn, const void *ptr, size_t usize, + prof_tctx_t *tctx) +{ + + prof_tctx_set(tsdn, ptr, usize, tctx); + + malloc_mutex_lock(tsdn, tctx->tdata->lock); + tctx->cnts.curobjs++; + tctx->cnts.curbytes += usize; + if (opt_prof_accum) { + tctx->cnts.accumobjs++; + tctx->cnts.accumbytes += usize; + } + tctx->prepared = false; + malloc_mutex_unlock(tsdn, tctx->tdata->lock); +} + +void +prof_free_sampled_object(tsd_t *tsd, size_t usize, prof_tctx_t *tctx) +{ + + malloc_mutex_lock(tsd_tsdn(tsd), tctx->tdata->lock); + assert(tctx->cnts.curobjs > 0); + assert(tctx->cnts.curbytes >= usize); + tctx->cnts.curobjs--; + tctx->cnts.curbytes -= usize; + + if (prof_tctx_should_destroy(tsd_tsdn(tsd), tctx)) + prof_tctx_destroy(tsd, tctx); + else + malloc_mutex_unlock(tsd_tsdn(tsd), tctx->tdata->lock); +} + +void +bt_init(prof_bt_t *bt, void **vec) +{ + + cassert(config_prof); + + bt->vec = vec; + bt->len = 0; +} + +JEMALLOC_INLINE_C void +prof_enter(tsd_t *tsd, prof_tdata_t *tdata) +{ + + cassert(config_prof); + assert(tdata == prof_tdata_get(tsd, false)); + + if (tdata != NULL) { + assert(!tdata->enq); + tdata->enq = true; + } + + malloc_mutex_lock(tsd_tsdn(tsd), &bt2gctx_mtx); +} + +JEMALLOC_INLINE_C void +prof_leave(tsd_t *tsd, prof_tdata_t *tdata) +{ + + cassert(config_prof); + assert(tdata == prof_tdata_get(tsd, false)); + + malloc_mutex_unlock(tsd_tsdn(tsd), &bt2gctx_mtx); + + if (tdata != NULL) { + bool idump, gdump; + + assert(tdata->enq); + tdata->enq = false; + idump = tdata->enq_idump; + tdata->enq_idump = false; + gdump = tdata->enq_gdump; + tdata->enq_gdump = false; + + if (idump) + prof_idump(tsd_tsdn(tsd)); + if (gdump) + prof_gdump(tsd_tsdn(tsd)); + } +} + +#ifdef JEMALLOC_PROF_LIBUNWIND +void +prof_backtrace(prof_bt_t *bt) +{ + int nframes; + + cassert(config_prof); + assert(bt->len == 0); + assert(bt->vec != NULL); + + nframes = unw_backtrace(bt->vec, PROF_BT_MAX); + if (nframes <= 0) + return; + bt->len = nframes; +} +#elif (defined(JEMALLOC_PROF_LIBGCC)) +static _Unwind_Reason_Code +prof_unwind_init_callback(struct _Unwind_Context *context, void *arg) +{ + + cassert(config_prof); + + return (_URC_NO_REASON); +} + +static _Unwind_Reason_Code +prof_unwind_callback(struct _Unwind_Context *context, void *arg) +{ + prof_unwind_data_t *data = (prof_unwind_data_t *)arg; + void *ip; + + cassert(config_prof); + + ip = (void *)_Unwind_GetIP(context); + if (ip == NULL) + return (_URC_END_OF_STACK); + data->bt->vec[data->bt->len] = ip; + data->bt->len++; + if (data->bt->len == data->max) + return (_URC_END_OF_STACK); + + return (_URC_NO_REASON); +} + +void +prof_backtrace(prof_bt_t *bt) +{ + prof_unwind_data_t data = {bt, PROF_BT_MAX}; + + cassert(config_prof); + + _Unwind_Backtrace(prof_unwind_callback, &data); +} +#elif (defined(JEMALLOC_PROF_GCC)) +void +prof_backtrace(prof_bt_t *bt) +{ +#define BT_FRAME(i) \ + if ((i) < PROF_BT_MAX) { \ + void *p; \ + if (__builtin_frame_address(i) == 0) \ + return; \ + p = __builtin_return_address(i); \ + if (p == NULL) \ + return; \ + bt->vec[(i)] = p; \ + bt->len = (i) + 1; \ + } else \ + return; + + cassert(config_prof); + + BT_FRAME(0) + BT_FRAME(1) + BT_FRAME(2) + BT_FRAME(3) + BT_FRAME(4) + BT_FRAME(5) + BT_FRAME(6) + BT_FRAME(7) + BT_FRAME(8) + BT_FRAME(9) + + BT_FRAME(10) + BT_FRAME(11) + BT_FRAME(12) + BT_FRAME(13) + BT_FRAME(14) + BT_FRAME(15) + BT_FRAME(16) + BT_FRAME(17) + BT_FRAME(18) + BT_FRAME(19) + + BT_FRAME(20) + BT_FRAME(21) + BT_FRAME(22) + BT_FRAME(23) + BT_FRAME(24) + BT_FRAME(25) + BT_FRAME(26) + BT_FRAME(27) + BT_FRAME(28) + BT_FRAME(29) + + BT_FRAME(30) + BT_FRAME(31) + BT_FRAME(32) + BT_FRAME(33) + BT_FRAME(34) + BT_FRAME(35) + BT_FRAME(36) + BT_FRAME(37) + BT_FRAME(38) + BT_FRAME(39) + + BT_FRAME(40) + BT_FRAME(41) + BT_FRAME(42) + BT_FRAME(43) + BT_FRAME(44) + BT_FRAME(45) + BT_FRAME(46) + BT_FRAME(47) + BT_FRAME(48) + BT_FRAME(49) + + BT_FRAME(50) + BT_FRAME(51) + BT_FRAME(52) + BT_FRAME(53) + BT_FRAME(54) + BT_FRAME(55) + BT_FRAME(56) + BT_FRAME(57) + BT_FRAME(58) + BT_FRAME(59) + + BT_FRAME(60) + BT_FRAME(61) + BT_FRAME(62) + BT_FRAME(63) + BT_FRAME(64) + BT_FRAME(65) + BT_FRAME(66) + BT_FRAME(67) + BT_FRAME(68) + BT_FRAME(69) + + BT_FRAME(70) + BT_FRAME(71) + BT_FRAME(72) + BT_FRAME(73) + BT_FRAME(74) + BT_FRAME(75) + BT_FRAME(76) + BT_FRAME(77) + BT_FRAME(78) + BT_FRAME(79) + + BT_FRAME(80) + BT_FRAME(81) + BT_FRAME(82) + BT_FRAME(83) + BT_FRAME(84) + BT_FRAME(85) + BT_FRAME(86) + BT_FRAME(87) + BT_FRAME(88) + BT_FRAME(89) + + BT_FRAME(90) + BT_FRAME(91) + BT_FRAME(92) + BT_FRAME(93) + BT_FRAME(94) + BT_FRAME(95) + BT_FRAME(96) + BT_FRAME(97) + BT_FRAME(98) + BT_FRAME(99) + + BT_FRAME(100) + BT_FRAME(101) + BT_FRAME(102) + BT_FRAME(103) + BT_FRAME(104) + BT_FRAME(105) + BT_FRAME(106) + BT_FRAME(107) + BT_FRAME(108) + BT_FRAME(109) + + BT_FRAME(110) + BT_FRAME(111) + BT_FRAME(112) + BT_FRAME(113) + BT_FRAME(114) + BT_FRAME(115) + BT_FRAME(116) + BT_FRAME(117) + BT_FRAME(118) + BT_FRAME(119) + + BT_FRAME(120) + BT_FRAME(121) + BT_FRAME(122) + BT_FRAME(123) + BT_FRAME(124) + BT_FRAME(125) + BT_FRAME(126) + BT_FRAME(127) +#undef BT_FRAME +} +#else +void +prof_backtrace(prof_bt_t *bt) +{ + + cassert(config_prof); + not_reached(); +} +#endif + +static malloc_mutex_t * +prof_gctx_mutex_choose(void) +{ + unsigned ngctxs = atomic_add_u(&cum_gctxs, 1); + + return (&gctx_locks[(ngctxs - 1) % PROF_NCTX_LOCKS]); +} + +static malloc_mutex_t * +prof_tdata_mutex_choose(uint64_t thr_uid) +{ + + return (&tdata_locks[thr_uid % PROF_NTDATA_LOCKS]); +} + +static prof_gctx_t * +prof_gctx_create(tsdn_t *tsdn, prof_bt_t *bt) +{ + /* + * Create a single allocation that has space for vec of length bt->len. + */ + size_t size = offsetof(prof_gctx_t, vec) + (bt->len * sizeof(void *)); + prof_gctx_t *gctx = (prof_gctx_t *)iallocztm(tsdn, size, + size2index(size), false, NULL, true, arena_get(TSDN_NULL, 0, true), + true); + if (gctx == NULL) + return (NULL); + gctx->lock = prof_gctx_mutex_choose(); + /* + * Set nlimbo to 1, in order to avoid a race condition with + * prof_tctx_destroy()/prof_gctx_try_destroy(). + */ + gctx->nlimbo = 1; + tctx_tree_new(&gctx->tctxs); + /* Duplicate bt. */ + memcpy(gctx->vec, bt->vec, bt->len * sizeof(void *)); + gctx->bt.vec = gctx->vec; + gctx->bt.len = bt->len; + return (gctx); +} + +static void +prof_gctx_try_destroy(tsd_t *tsd, prof_tdata_t *tdata_self, prof_gctx_t *gctx, + prof_tdata_t *tdata) +{ + + cassert(config_prof); + + /* + * Check that gctx is still unused by any thread cache before destroying + * it. prof_lookup() increments gctx->nlimbo in order to avoid a race + * condition with this function, as does prof_tctx_destroy() in order to + * avoid a race between the main body of prof_tctx_destroy() and entry + * into this function. + */ + prof_enter(tsd, tdata_self); + malloc_mutex_lock(tsd_tsdn(tsd), gctx->lock); + assert(gctx->nlimbo != 0); + if (tctx_tree_empty(&gctx->tctxs) && gctx->nlimbo == 1) { + /* Remove gctx from bt2gctx. */ + if (ckh_remove(tsd_tsdn(tsd), &bt2gctx, &gctx->bt, NULL, NULL)) + not_reached(); + prof_leave(tsd, tdata_self); + /* Destroy gctx. */ + malloc_mutex_unlock(tsd_tsdn(tsd), gctx->lock); + idalloctm(tsd_tsdn(tsd), gctx, NULL, true, true); + } else { + /* + * Compensate for increment in prof_tctx_destroy() or + * prof_lookup(). + */ + gctx->nlimbo--; + malloc_mutex_unlock(tsd_tsdn(tsd), gctx->lock); + prof_leave(tsd, tdata_self); + } +} + +static bool +prof_tctx_should_destroy(tsdn_t *tsdn, prof_tctx_t *tctx) +{ + + malloc_mutex_assert_owner(tsdn, tctx->tdata->lock); + + if (opt_prof_accum) + return (false); + if (tctx->cnts.curobjs != 0) + return (false); + if (tctx->prepared) + return (false); + return (true); +} + +static bool +prof_gctx_should_destroy(prof_gctx_t *gctx) +{ + + if (opt_prof_accum) + return (false); + if (!tctx_tree_empty(&gctx->tctxs)) + return (false); + if (gctx->nlimbo != 0) + return (false); + return (true); +} + +static void +prof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx) +{ + prof_tdata_t *tdata = tctx->tdata; + prof_gctx_t *gctx = tctx->gctx; + bool destroy_tdata, destroy_tctx, destroy_gctx; + + malloc_mutex_assert_owner(tsd_tsdn(tsd), tctx->tdata->lock); + + assert(tctx->cnts.curobjs == 0); + assert(tctx->cnts.curbytes == 0); + assert(!opt_prof_accum); + assert(tctx->cnts.accumobjs == 0); + assert(tctx->cnts.accumbytes == 0); + + ckh_remove(tsd_tsdn(tsd), &tdata->bt2tctx, &gctx->bt, NULL, NULL); + destroy_tdata = prof_tdata_should_destroy(tsd_tsdn(tsd), tdata, false); + malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock); + + malloc_mutex_lock(tsd_tsdn(tsd), gctx->lock); + switch (tctx->state) { + case prof_tctx_state_nominal: + tctx_tree_remove(&gctx->tctxs, tctx); + destroy_tctx = true; + if (prof_gctx_should_destroy(gctx)) { + /* + * Increment gctx->nlimbo in order to keep another + * thread from winning the race to destroy gctx while + * this one has gctx->lock dropped. Without this, it + * would be possible for another thread to: + * + * 1) Sample an allocation associated with gctx. + * 2) Deallocate the sampled object. + * 3) Successfully prof_gctx_try_destroy(gctx). + * + * The result would be that gctx no longer exists by the + * time this thread accesses it in + * prof_gctx_try_destroy(). + */ + gctx->nlimbo++; + destroy_gctx = true; + } else + destroy_gctx = false; + break; + case prof_tctx_state_dumping: + /* + * A dumping thread needs tctx to remain valid until dumping + * has finished. Change state such that the dumping thread will + * complete destruction during a late dump iteration phase. + */ + tctx->state = prof_tctx_state_purgatory; + destroy_tctx = false; + destroy_gctx = false; + break; + default: + not_reached(); + destroy_tctx = false; + destroy_gctx = false; + } + malloc_mutex_unlock(tsd_tsdn(tsd), gctx->lock); + if (destroy_gctx) { + prof_gctx_try_destroy(tsd, prof_tdata_get(tsd, false), gctx, + tdata); + } + + malloc_mutex_assert_not_owner(tsd_tsdn(tsd), tctx->tdata->lock); + + if (destroy_tdata) + prof_tdata_destroy(tsd_tsdn(tsd), tdata, false); + + if (destroy_tctx) + idalloctm(tsd_tsdn(tsd), tctx, NULL, true, true); +} + +static bool +prof_lookup_global(tsd_t *tsd, prof_bt_t *bt, prof_tdata_t *tdata, + void **p_btkey, prof_gctx_t **p_gctx, bool *p_new_gctx) +{ + union { + prof_gctx_t *p; + void *v; + } gctx; + union { + prof_bt_t *p; + void *v; + } btkey; + bool new_gctx; + + prof_enter(tsd, tdata); + if (ckh_search(&bt2gctx, bt, &btkey.v, &gctx.v)) { + /* bt has never been seen before. Insert it. */ + gctx.p = prof_gctx_create(tsd_tsdn(tsd), bt); + if (gctx.v == NULL) { + prof_leave(tsd, tdata); + return (true); + } + btkey.p = &gctx.p->bt; + if (ckh_insert(tsd_tsdn(tsd), &bt2gctx, btkey.v, gctx.v)) { + /* OOM. */ + prof_leave(tsd, tdata); + idalloctm(tsd_tsdn(tsd), gctx.v, NULL, true, true); + return (true); + } + new_gctx = true; + } else { + /* + * Increment nlimbo, in order to avoid a race condition with + * prof_tctx_destroy()/prof_gctx_try_destroy(). + */ + malloc_mutex_lock(tsd_tsdn(tsd), gctx.p->lock); + gctx.p->nlimbo++; + malloc_mutex_unlock(tsd_tsdn(tsd), gctx.p->lock); + new_gctx = false; + } + prof_leave(tsd, tdata); + + *p_btkey = btkey.v; + *p_gctx = gctx.p; + *p_new_gctx = new_gctx; + return (false); +} + +prof_tctx_t * +prof_lookup(tsd_t *tsd, prof_bt_t *bt) +{ + union { + prof_tctx_t *p; + void *v; + } ret; + prof_tdata_t *tdata; + bool not_found; + + cassert(config_prof); + + tdata = prof_tdata_get(tsd, false); + if (tdata == NULL) + return (NULL); + + malloc_mutex_lock(tsd_tsdn(tsd), tdata->lock); + not_found = ckh_search(&tdata->bt2tctx, bt, NULL, &ret.v); + if (!not_found) /* Note double negative! */ + ret.p->prepared = true; + malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock); + if (not_found) { + void *btkey; + prof_gctx_t *gctx; + bool new_gctx, error; + + /* + * This thread's cache lacks bt. Look for it in the global + * cache. + */ + if (prof_lookup_global(tsd, bt, tdata, &btkey, &gctx, + &new_gctx)) + return (NULL); + + /* Link a prof_tctx_t into gctx for this thread. */ + ret.v = iallocztm(tsd_tsdn(tsd), sizeof(prof_tctx_t), + size2index(sizeof(prof_tctx_t)), false, NULL, true, + arena_ichoose(tsd_tsdn(tsd), NULL), true); + if (ret.p == NULL) { + if (new_gctx) + prof_gctx_try_destroy(tsd, tdata, gctx, tdata); + return (NULL); + } + ret.p->tdata = tdata; + ret.p->thr_uid = tdata->thr_uid; + ret.p->thr_discrim = tdata->thr_discrim; + memset(&ret.p->cnts, 0, sizeof(prof_cnt_t)); + ret.p->gctx = gctx; + ret.p->tctx_uid = tdata->tctx_uid_next++; + ret.p->prepared = true; + ret.p->state = prof_tctx_state_initializing; + malloc_mutex_lock(tsd_tsdn(tsd), tdata->lock); + error = ckh_insert(tsd_tsdn(tsd), &tdata->bt2tctx, btkey, + ret.v); + malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock); + if (error) { + if (new_gctx) + prof_gctx_try_destroy(tsd, tdata, gctx, tdata); + idalloctm(tsd_tsdn(tsd), ret.v, NULL, true, true); + return (NULL); + } + malloc_mutex_lock(tsd_tsdn(tsd), gctx->lock); + ret.p->state = prof_tctx_state_nominal; + tctx_tree_insert(&gctx->tctxs, ret.p); + gctx->nlimbo--; + malloc_mutex_unlock(tsd_tsdn(tsd), gctx->lock); + } + + return (ret.p); +} + +/* + * The bodies of this function and prof_leakcheck() are compiled out unless heap + * profiling is enabled, so that it is possible to compile jemalloc with + * floating point support completely disabled. Avoiding floating point code is + * important on memory-constrained systems, but it also enables a workaround for + * versions of glibc that don't properly save/restore floating point registers + * during dynamic lazy symbol loading (which internally calls into whatever + * malloc implementation happens to be integrated into the application). Note + * that some compilers (e.g. gcc 4.8) may use floating point registers for fast + * memory moves, so jemalloc must be compiled with such optimizations disabled + * (e.g. + * -mno-sse) in order for the workaround to be complete. + */ +void +prof_sample_threshold_update(prof_tdata_t *tdata) +{ +#ifdef JEMALLOC_PROF + uint64_t r; + double u; + + if (!config_prof) + return; + + if (lg_prof_sample == 0) { + tdata->bytes_until_sample = 0; + return; + } + + /* + * Compute sample interval as a geometrically distributed random + * variable with mean (2^lg_prof_sample). + * + * __ __ + * | log(u) | 1 + * tdata->bytes_until_sample = | -------- |, where p = --------------- + * | log(1-p) | lg_prof_sample + * 2 + * + * For more information on the math, see: + * + * Non-Uniform Random Variate Generation + * Luc Devroye + * Springer-Verlag, New York, 1986 + * pp 500 + * (http://luc.devroye.org/rnbookindex.html) + */ + r = prng_lg_range(&tdata->prng_state, 53); + u = (double)r * (1.0/9007199254740992.0L); + tdata->bytes_until_sample = (uint64_t)(log(u) / + log(1.0 - (1.0 / (double)((uint64_t)1U << lg_prof_sample)))) + + (uint64_t)1U; +#endif +} + +#ifdef JEMALLOC_JET +static prof_tdata_t * +prof_tdata_count_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg) +{ + size_t *tdata_count = (size_t *)arg; + + (*tdata_count)++; + + return (NULL); +} + +size_t +prof_tdata_count(void) +{ + size_t tdata_count = 0; + tsdn_t *tsdn; + + tsdn = tsdn_fetch(); + malloc_mutex_lock(tsdn, &tdatas_mtx); + tdata_tree_iter(&tdatas, NULL, prof_tdata_count_iter, + (void *)&tdata_count); + malloc_mutex_unlock(tsdn, &tdatas_mtx); + + return (tdata_count); +} +#endif + +#ifdef JEMALLOC_JET +size_t +prof_bt_count(void) +{ + size_t bt_count; + tsd_t *tsd; + prof_tdata_t *tdata; + + tsd = tsd_fetch(); + tdata = prof_tdata_get(tsd, false); + if (tdata == NULL) + return (0); + + malloc_mutex_lock(tsd_tsdn(tsd), &bt2gctx_mtx); + bt_count = ckh_count(&bt2gctx); + malloc_mutex_unlock(tsd_tsdn(tsd), &bt2gctx_mtx); + + return (bt_count); +} +#endif + +#ifdef JEMALLOC_JET +#undef prof_dump_open +#define prof_dump_open JEMALLOC_N(prof_dump_open_impl) +#endif +static int +prof_dump_open(bool propagate_err, const char *filename) +{ + int fd; + + fd = creat(filename, 0644); + if (fd == -1 && !propagate_err) { + malloc_printf(": creat(\"%s\"), 0644) failed\n", + filename); + if (opt_abort) + abort(); + } + + return (fd); +} +#ifdef JEMALLOC_JET +#undef prof_dump_open +#define prof_dump_open JEMALLOC_N(prof_dump_open) +prof_dump_open_t *prof_dump_open = JEMALLOC_N(prof_dump_open_impl); +#endif + +static bool +prof_dump_flush(bool propagate_err) +{ + bool ret = false; + ssize_t err; + + cassert(config_prof); + + err = write(prof_dump_fd, prof_dump_buf, prof_dump_buf_end); + if (err == -1) { + if (!propagate_err) { + malloc_write(": write() failed during heap " + "profile flush\n"); + if (opt_abort) + abort(); + } + ret = true; + } + prof_dump_buf_end = 0; + + return (ret); +} + +static bool +prof_dump_close(bool propagate_err) +{ + bool ret; + + assert(prof_dump_fd != -1); + ret = prof_dump_flush(propagate_err); + close(prof_dump_fd); + prof_dump_fd = -1; + + return (ret); +} + +static bool +prof_dump_write(bool propagate_err, const char *s) +{ + size_t i, slen, n; + + cassert(config_prof); + + i = 0; + slen = strlen(s); + while (i < slen) { + /* Flush the buffer if it is full. */ + if (prof_dump_buf_end == PROF_DUMP_BUFSIZE) + if (prof_dump_flush(propagate_err) && propagate_err) + return (true); + + if (prof_dump_buf_end + slen <= PROF_DUMP_BUFSIZE) { + /* Finish writing. */ + n = slen - i; + } else { + /* Write as much of s as will fit. */ + n = PROF_DUMP_BUFSIZE - prof_dump_buf_end; + } + memcpy(&prof_dump_buf[prof_dump_buf_end], &s[i], n); + prof_dump_buf_end += n; + i += n; + } + + return (false); +} + +JEMALLOC_FORMAT_PRINTF(2, 3) +static bool +prof_dump_printf(bool propagate_err, const char *format, ...) +{ + bool ret; + va_list ap; + char buf[PROF_PRINTF_BUFSIZE]; + + va_start(ap, format); + malloc_vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + ret = prof_dump_write(propagate_err, buf); + + return (ret); +} + +static void +prof_tctx_merge_tdata(tsdn_t *tsdn, prof_tctx_t *tctx, prof_tdata_t *tdata) +{ + + malloc_mutex_assert_owner(tsdn, tctx->tdata->lock); + + malloc_mutex_lock(tsdn, tctx->gctx->lock); + + switch (tctx->state) { + case prof_tctx_state_initializing: + malloc_mutex_unlock(tsdn, tctx->gctx->lock); + return; + case prof_tctx_state_nominal: + tctx->state = prof_tctx_state_dumping; + malloc_mutex_unlock(tsdn, tctx->gctx->lock); + + memcpy(&tctx->dump_cnts, &tctx->cnts, sizeof(prof_cnt_t)); + + tdata->cnt_summed.curobjs += tctx->dump_cnts.curobjs; + tdata->cnt_summed.curbytes += tctx->dump_cnts.curbytes; + if (opt_prof_accum) { + tdata->cnt_summed.accumobjs += + tctx->dump_cnts.accumobjs; + tdata->cnt_summed.accumbytes += + tctx->dump_cnts.accumbytes; + } + break; + case prof_tctx_state_dumping: + case prof_tctx_state_purgatory: + not_reached(); + } +} + +static void +prof_tctx_merge_gctx(tsdn_t *tsdn, prof_tctx_t *tctx, prof_gctx_t *gctx) +{ + + malloc_mutex_assert_owner(tsdn, gctx->lock); + + gctx->cnt_summed.curobjs += tctx->dump_cnts.curobjs; + gctx->cnt_summed.curbytes += tctx->dump_cnts.curbytes; + if (opt_prof_accum) { + gctx->cnt_summed.accumobjs += tctx->dump_cnts.accumobjs; + gctx->cnt_summed.accumbytes += tctx->dump_cnts.accumbytes; + } +} + +static prof_tctx_t * +prof_tctx_merge_iter(prof_tctx_tree_t *tctxs, prof_tctx_t *tctx, void *arg) +{ + tsdn_t *tsdn = (tsdn_t *)arg; + + malloc_mutex_assert_owner(tsdn, tctx->gctx->lock); + + switch (tctx->state) { + case prof_tctx_state_nominal: + /* New since dumping started; ignore. */ + break; + case prof_tctx_state_dumping: + case prof_tctx_state_purgatory: + prof_tctx_merge_gctx(tsdn, tctx, tctx->gctx); + break; + default: + not_reached(); + } + + return (NULL); +} + +struct prof_tctx_dump_iter_arg_s { + tsdn_t *tsdn; + bool propagate_err; +}; + +static prof_tctx_t * +prof_tctx_dump_iter(prof_tctx_tree_t *tctxs, prof_tctx_t *tctx, void *opaque) +{ + struct prof_tctx_dump_iter_arg_s *arg = + (struct prof_tctx_dump_iter_arg_s *)opaque; + + malloc_mutex_assert_owner(arg->tsdn, tctx->gctx->lock); + + switch (tctx->state) { + case prof_tctx_state_initializing: + case prof_tctx_state_nominal: + /* Not captured by this dump. */ + break; + case prof_tctx_state_dumping: + case prof_tctx_state_purgatory: + if (prof_dump_printf(arg->propagate_err, + " t%"FMTu64": %"FMTu64": %"FMTu64" [%"FMTu64": " + "%"FMTu64"]\n", tctx->thr_uid, tctx->dump_cnts.curobjs, + tctx->dump_cnts.curbytes, tctx->dump_cnts.accumobjs, + tctx->dump_cnts.accumbytes)) + return (tctx); + break; + default: + not_reached(); + } + return (NULL); +} + +static prof_tctx_t * +prof_tctx_finish_iter(prof_tctx_tree_t *tctxs, prof_tctx_t *tctx, void *arg) +{ + tsdn_t *tsdn = (tsdn_t *)arg; + prof_tctx_t *ret; + + malloc_mutex_assert_owner(tsdn, tctx->gctx->lock); + + switch (tctx->state) { + case prof_tctx_state_nominal: + /* New since dumping started; ignore. */ + break; + case prof_tctx_state_dumping: + tctx->state = prof_tctx_state_nominal; + break; + case prof_tctx_state_purgatory: + ret = tctx; + goto label_return; + default: + not_reached(); + } + + ret = NULL; +label_return: + return (ret); +} + +static void +prof_dump_gctx_prep(tsdn_t *tsdn, prof_gctx_t *gctx, prof_gctx_tree_t *gctxs) +{ + + cassert(config_prof); + + malloc_mutex_lock(tsdn, gctx->lock); + + /* + * Increment nlimbo so that gctx won't go away before dump. + * Additionally, link gctx into the dump list so that it is included in + * prof_dump()'s second pass. + */ + gctx->nlimbo++; + gctx_tree_insert(gctxs, gctx); + + memset(&gctx->cnt_summed, 0, sizeof(prof_cnt_t)); + + malloc_mutex_unlock(tsdn, gctx->lock); +} + +struct prof_gctx_merge_iter_arg_s { + tsdn_t *tsdn; + size_t leak_ngctx; +}; + +static prof_gctx_t * +prof_gctx_merge_iter(prof_gctx_tree_t *gctxs, prof_gctx_t *gctx, void *opaque) +{ + struct prof_gctx_merge_iter_arg_s *arg = + (struct prof_gctx_merge_iter_arg_s *)opaque; + + malloc_mutex_lock(arg->tsdn, gctx->lock); + tctx_tree_iter(&gctx->tctxs, NULL, prof_tctx_merge_iter, + (void *)arg->tsdn); + if (gctx->cnt_summed.curobjs != 0) + arg->leak_ngctx++; + malloc_mutex_unlock(arg->tsdn, gctx->lock); + + return (NULL); +} + +static void +prof_gctx_finish(tsd_t *tsd, prof_gctx_tree_t *gctxs) +{ + prof_tdata_t *tdata = prof_tdata_get(tsd, false); + prof_gctx_t *gctx; + + /* + * Standard tree iteration won't work here, because as soon as we + * decrement gctx->nlimbo and unlock gctx, another thread can + * concurrently destroy it, which will corrupt the tree. Therefore, + * tear down the tree one node at a time during iteration. + */ + while ((gctx = gctx_tree_first(gctxs)) != NULL) { + gctx_tree_remove(gctxs, gctx); + malloc_mutex_lock(tsd_tsdn(tsd), gctx->lock); + { + prof_tctx_t *next; + + next = NULL; + do { + prof_tctx_t *to_destroy = + tctx_tree_iter(&gctx->tctxs, next, + prof_tctx_finish_iter, + (void *)tsd_tsdn(tsd)); + if (to_destroy != NULL) { + next = tctx_tree_next(&gctx->tctxs, + to_destroy); + tctx_tree_remove(&gctx->tctxs, + to_destroy); + idalloctm(tsd_tsdn(tsd), to_destroy, + NULL, true, true); + } else + next = NULL; + } while (next != NULL); + } + gctx->nlimbo--; + if (prof_gctx_should_destroy(gctx)) { + gctx->nlimbo++; + malloc_mutex_unlock(tsd_tsdn(tsd), gctx->lock); + prof_gctx_try_destroy(tsd, tdata, gctx, tdata); + } else + malloc_mutex_unlock(tsd_tsdn(tsd), gctx->lock); + } +} + +struct prof_tdata_merge_iter_arg_s { + tsdn_t *tsdn; + prof_cnt_t cnt_all; +}; + +static prof_tdata_t * +prof_tdata_merge_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, + void *opaque) +{ + struct prof_tdata_merge_iter_arg_s *arg = + (struct prof_tdata_merge_iter_arg_s *)opaque; + + malloc_mutex_lock(arg->tsdn, tdata->lock); + if (!tdata->expired) { + size_t tabind; + union { + prof_tctx_t *p; + void *v; + } tctx; + + tdata->dumping = true; + memset(&tdata->cnt_summed, 0, sizeof(prof_cnt_t)); + for (tabind = 0; !ckh_iter(&tdata->bt2tctx, &tabind, NULL, + &tctx.v);) + prof_tctx_merge_tdata(arg->tsdn, tctx.p, tdata); + + arg->cnt_all.curobjs += tdata->cnt_summed.curobjs; + arg->cnt_all.curbytes += tdata->cnt_summed.curbytes; + if (opt_prof_accum) { + arg->cnt_all.accumobjs += tdata->cnt_summed.accumobjs; + arg->cnt_all.accumbytes += tdata->cnt_summed.accumbytes; + } + } else + tdata->dumping = false; + malloc_mutex_unlock(arg->tsdn, tdata->lock); + + return (NULL); +} + +static prof_tdata_t * +prof_tdata_dump_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg) +{ + bool propagate_err = *(bool *)arg; + + if (!tdata->dumping) + return (NULL); + + if (prof_dump_printf(propagate_err, + " t%"FMTu64": %"FMTu64": %"FMTu64" [%"FMTu64": %"FMTu64"]%s%s\n", + tdata->thr_uid, tdata->cnt_summed.curobjs, + tdata->cnt_summed.curbytes, tdata->cnt_summed.accumobjs, + tdata->cnt_summed.accumbytes, + (tdata->thread_name != NULL) ? " " : "", + (tdata->thread_name != NULL) ? tdata->thread_name : "")) + return (tdata); + return (NULL); +} + +#ifdef JEMALLOC_JET +#undef prof_dump_header +#define prof_dump_header JEMALLOC_N(prof_dump_header_impl) +#endif +static bool +prof_dump_header(tsdn_t *tsdn, bool propagate_err, const prof_cnt_t *cnt_all) +{ + bool ret; + + if (prof_dump_printf(propagate_err, + "heap_v2/%"FMTu64"\n" + " t*: %"FMTu64": %"FMTu64" [%"FMTu64": %"FMTu64"]\n", + ((uint64_t)1U << lg_prof_sample), cnt_all->curobjs, + cnt_all->curbytes, cnt_all->accumobjs, cnt_all->accumbytes)) + return (true); + + malloc_mutex_lock(tsdn, &tdatas_mtx); + ret = (tdata_tree_iter(&tdatas, NULL, prof_tdata_dump_iter, + (void *)&propagate_err) != NULL); + malloc_mutex_unlock(tsdn, &tdatas_mtx); + return (ret); +} +#ifdef JEMALLOC_JET +#undef prof_dump_header +#define prof_dump_header JEMALLOC_N(prof_dump_header) +prof_dump_header_t *prof_dump_header = JEMALLOC_N(prof_dump_header_impl); +#endif + +static bool +prof_dump_gctx(tsdn_t *tsdn, bool propagate_err, prof_gctx_t *gctx, + const prof_bt_t *bt, prof_gctx_tree_t *gctxs) +{ + bool ret; + unsigned i; + struct prof_tctx_dump_iter_arg_s prof_tctx_dump_iter_arg; + + cassert(config_prof); + malloc_mutex_assert_owner(tsdn, gctx->lock); + + /* Avoid dumping such gctx's that have no useful data. */ + if ((!opt_prof_accum && gctx->cnt_summed.curobjs == 0) || + (opt_prof_accum && gctx->cnt_summed.accumobjs == 0)) { + assert(gctx->cnt_summed.curobjs == 0); + assert(gctx->cnt_summed.curbytes == 0); + assert(gctx->cnt_summed.accumobjs == 0); + assert(gctx->cnt_summed.accumbytes == 0); + ret = false; + goto label_return; + } + + if (prof_dump_printf(propagate_err, "@")) { + ret = true; + goto label_return; + } + for (i = 0; i < bt->len; i++) { + if (prof_dump_printf(propagate_err, " %#"FMTxPTR, + (uintptr_t)bt->vec[i])) { + ret = true; + goto label_return; + } + } + + if (prof_dump_printf(propagate_err, + "\n" + " t*: %"FMTu64": %"FMTu64" [%"FMTu64": %"FMTu64"]\n", + gctx->cnt_summed.curobjs, gctx->cnt_summed.curbytes, + gctx->cnt_summed.accumobjs, gctx->cnt_summed.accumbytes)) { + ret = true; + goto label_return; + } + + prof_tctx_dump_iter_arg.tsdn = tsdn; + prof_tctx_dump_iter_arg.propagate_err = propagate_err; + if (tctx_tree_iter(&gctx->tctxs, NULL, prof_tctx_dump_iter, + (void *)&prof_tctx_dump_iter_arg) != NULL) { + ret = true; + goto label_return; + } + + ret = false; +label_return: + return (ret); +} + +#ifndef _WIN32 +JEMALLOC_FORMAT_PRINTF(1, 2) +static int +prof_open_maps(const char *format, ...) +{ + int mfd; + va_list ap; + char filename[PATH_MAX + 1]; + + va_start(ap, format); + malloc_vsnprintf(filename, sizeof(filename), format, ap); + va_end(ap); + mfd = open(filename, O_RDONLY); + + return (mfd); +} +#endif + +static int +prof_getpid(void) +{ + +#ifdef _WIN32 + return (GetCurrentProcessId()); +#else + return (getpid()); +#endif +} + +static bool +prof_dump_maps(bool propagate_err) +{ + bool ret; + int mfd; + + cassert(config_prof); +#ifdef __FreeBSD__ + mfd = prof_open_maps("/proc/curproc/map"); +#elif defined(_WIN32) + mfd = -1; // Not implemented +#else + { + int pid = prof_getpid(); + + mfd = prof_open_maps("/proc/%d/task/%d/maps", pid, pid); + if (mfd == -1) + mfd = prof_open_maps("/proc/%d/maps", pid); + } +#endif + if (mfd != -1) { + ssize_t nread; + + if (prof_dump_write(propagate_err, "\nMAPPED_LIBRARIES:\n") && + propagate_err) { + ret = true; + goto label_return; + } + nread = 0; + do { + prof_dump_buf_end += nread; + if (prof_dump_buf_end == PROF_DUMP_BUFSIZE) { + /* Make space in prof_dump_buf before read(). */ + if (prof_dump_flush(propagate_err) && + propagate_err) { + ret = true; + goto label_return; + } + } + nread = read(mfd, &prof_dump_buf[prof_dump_buf_end], + PROF_DUMP_BUFSIZE - prof_dump_buf_end); + } while (nread > 0); + } else { + ret = true; + goto label_return; + } + + ret = false; +label_return: + if (mfd != -1) + close(mfd); + return (ret); +} + +/* + * See prof_sample_threshold_update() comment for why the body of this function + * is conditionally compiled. + */ +static void +prof_leakcheck(const prof_cnt_t *cnt_all, size_t leak_ngctx, + const char *filename) +{ + +#ifdef JEMALLOC_PROF + /* + * Scaling is equivalent AdjustSamples() in jeprof, but the result may + * differ slightly from what jeprof reports, because here we scale the + * summary values, whereas jeprof scales each context individually and + * reports the sums of the scaled values. + */ + if (cnt_all->curbytes != 0) { + double sample_period = (double)((uint64_t)1 << lg_prof_sample); + double ratio = (((double)cnt_all->curbytes) / + (double)cnt_all->curobjs) / sample_period; + double scale_factor = 1.0 / (1.0 - exp(-ratio)); + uint64_t curbytes = (uint64_t)round(((double)cnt_all->curbytes) + * scale_factor); + uint64_t curobjs = (uint64_t)round(((double)cnt_all->curobjs) * + scale_factor); + + malloc_printf(": Leak approximation summary: ~%"FMTu64 + " byte%s, ~%"FMTu64" object%s, >= %zu context%s\n", + curbytes, (curbytes != 1) ? "s" : "", curobjs, (curobjs != + 1) ? "s" : "", leak_ngctx, (leak_ngctx != 1) ? "s" : ""); + malloc_printf( + ": Run jeprof on \"%s\" for leak detail\n", + filename); + } +#endif +} + +struct prof_gctx_dump_iter_arg_s { + tsdn_t *tsdn; + bool propagate_err; +}; + +static prof_gctx_t * +prof_gctx_dump_iter(prof_gctx_tree_t *gctxs, prof_gctx_t *gctx, void *opaque) +{ + prof_gctx_t *ret; + struct prof_gctx_dump_iter_arg_s *arg = + (struct prof_gctx_dump_iter_arg_s *)opaque; + + malloc_mutex_lock(arg->tsdn, gctx->lock); + + if (prof_dump_gctx(arg->tsdn, arg->propagate_err, gctx, &gctx->bt, + gctxs)) { + ret = gctx; + goto label_return; + } + + ret = NULL; +label_return: + malloc_mutex_unlock(arg->tsdn, gctx->lock); + return (ret); +} + +static bool +prof_dump(tsd_t *tsd, bool propagate_err, const char *filename, bool leakcheck) +{ + prof_tdata_t *tdata; + struct prof_tdata_merge_iter_arg_s prof_tdata_merge_iter_arg; + size_t tabind; + union { + prof_gctx_t *p; + void *v; + } gctx; + struct prof_gctx_merge_iter_arg_s prof_gctx_merge_iter_arg; + struct prof_gctx_dump_iter_arg_s prof_gctx_dump_iter_arg; + prof_gctx_tree_t gctxs; + + cassert(config_prof); + + tdata = prof_tdata_get(tsd, true); + if (tdata == NULL) + return (true); + + malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_mtx); + prof_enter(tsd, tdata); + + /* + * Put gctx's in limbo and clear their counters in preparation for + * summing. + */ + gctx_tree_new(&gctxs); + for (tabind = 0; !ckh_iter(&bt2gctx, &tabind, NULL, &gctx.v);) + prof_dump_gctx_prep(tsd_tsdn(tsd), gctx.p, &gctxs); + + /* + * Iterate over tdatas, and for the non-expired ones snapshot their tctx + * stats and merge them into the associated gctx's. + */ + prof_tdata_merge_iter_arg.tsdn = tsd_tsdn(tsd); + memset(&prof_tdata_merge_iter_arg.cnt_all, 0, sizeof(prof_cnt_t)); + malloc_mutex_lock(tsd_tsdn(tsd), &tdatas_mtx); + tdata_tree_iter(&tdatas, NULL, prof_tdata_merge_iter, + (void *)&prof_tdata_merge_iter_arg); + malloc_mutex_unlock(tsd_tsdn(tsd), &tdatas_mtx); + + /* Merge tctx stats into gctx's. */ + prof_gctx_merge_iter_arg.tsdn = tsd_tsdn(tsd); + prof_gctx_merge_iter_arg.leak_ngctx = 0; + gctx_tree_iter(&gctxs, NULL, prof_gctx_merge_iter, + (void *)&prof_gctx_merge_iter_arg); + + prof_leave(tsd, tdata); + + /* Create dump file. */ + if ((prof_dump_fd = prof_dump_open(propagate_err, filename)) == -1) + goto label_open_close_error; + + /* Dump profile header. */ + if (prof_dump_header(tsd_tsdn(tsd), propagate_err, + &prof_tdata_merge_iter_arg.cnt_all)) + goto label_write_error; + + /* Dump per gctx profile stats. */ + prof_gctx_dump_iter_arg.tsdn = tsd_tsdn(tsd); + prof_gctx_dump_iter_arg.propagate_err = propagate_err; + if (gctx_tree_iter(&gctxs, NULL, prof_gctx_dump_iter, + (void *)&prof_gctx_dump_iter_arg) != NULL) + goto label_write_error; + + /* Dump /proc//maps if possible. */ + if (prof_dump_maps(propagate_err)) + goto label_write_error; + + if (prof_dump_close(propagate_err)) + goto label_open_close_error; + + prof_gctx_finish(tsd, &gctxs); + malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_mtx); + + if (leakcheck) { + prof_leakcheck(&prof_tdata_merge_iter_arg.cnt_all, + prof_gctx_merge_iter_arg.leak_ngctx, filename); + } + return (false); +label_write_error: + prof_dump_close(propagate_err); +label_open_close_error: + prof_gctx_finish(tsd, &gctxs); + malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_mtx); + return (true); +} + +#define DUMP_FILENAME_BUFSIZE (PATH_MAX + 1) +#define VSEQ_INVALID UINT64_C(0xffffffffffffffff) +static void +prof_dump_filename(char *filename, char v, uint64_t vseq) +{ + + cassert(config_prof); + + if (vseq != VSEQ_INVALID) { + /* "...v.heap" */ + malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE, + "%s.%d.%"FMTu64".%c%"FMTu64".heap", + opt_prof_prefix, prof_getpid(), prof_dump_seq, v, vseq); + } else { + /* "....heap" */ + malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE, + "%s.%d.%"FMTu64".%c.heap", + opt_prof_prefix, prof_getpid(), prof_dump_seq, v); + } + prof_dump_seq++; +} + +static void +prof_fdump(void) +{ + tsd_t *tsd; + char filename[DUMP_FILENAME_BUFSIZE]; + + cassert(config_prof); + assert(opt_prof_final); + assert(opt_prof_prefix[0] != '\0'); + + if (!prof_booted) + return; + tsd = tsd_fetch(); + + malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_seq_mtx); + prof_dump_filename(filename, 'f', VSEQ_INVALID); + malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_seq_mtx); + prof_dump(tsd, false, filename, opt_prof_leak); +} + +void +prof_idump(tsdn_t *tsdn) +{ + tsd_t *tsd; + prof_tdata_t *tdata; + + cassert(config_prof); + + if (!prof_booted || tsdn_null(tsdn)) + return; + tsd = tsdn_tsd(tsdn); + tdata = prof_tdata_get(tsd, false); + if (tdata == NULL) + return; + if (tdata->enq) { + tdata->enq_idump = true; + return; + } + + if (opt_prof_prefix[0] != '\0') { + char filename[PATH_MAX + 1]; + malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_seq_mtx); + prof_dump_filename(filename, 'i', prof_dump_iseq); + prof_dump_iseq++; + malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_seq_mtx); + prof_dump(tsd, false, filename, false); + } +} + +bool +prof_mdump(tsd_t *tsd, const char *filename) +{ + char filename_buf[DUMP_FILENAME_BUFSIZE]; + + cassert(config_prof); + + if (!opt_prof || !prof_booted) + return (true); + + if (filename == NULL) { + /* No filename specified, so automatically generate one. */ + if (opt_prof_prefix[0] == '\0') + return (true); + malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_seq_mtx); + prof_dump_filename(filename_buf, 'm', prof_dump_mseq); + prof_dump_mseq++; + malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_seq_mtx); + filename = filename_buf; + } + return (prof_dump(tsd, true, filename, false)); +} + +void +prof_gdump(tsdn_t *tsdn) +{ + tsd_t *tsd; + prof_tdata_t *tdata; + + cassert(config_prof); + + if (!prof_booted || tsdn_null(tsdn)) + return; + tsd = tsdn_tsd(tsdn); + tdata = prof_tdata_get(tsd, false); + if (tdata == NULL) + return; + if (tdata->enq) { + tdata->enq_gdump = true; + return; + } + + if (opt_prof_prefix[0] != '\0') { + char filename[DUMP_FILENAME_BUFSIZE]; + malloc_mutex_lock(tsdn, &prof_dump_seq_mtx); + prof_dump_filename(filename, 'u', prof_dump_useq); + prof_dump_useq++; + malloc_mutex_unlock(tsdn, &prof_dump_seq_mtx); + prof_dump(tsd, false, filename, false); + } +} + +static void +prof_bt_hash(const void *key, size_t r_hash[2]) +{ + prof_bt_t *bt = (prof_bt_t *)key; + + cassert(config_prof); + + hash(bt->vec, bt->len * sizeof(void *), 0x94122f33U, r_hash); +} + +static bool +prof_bt_keycomp(const void *k1, const void *k2) +{ + const prof_bt_t *bt1 = (prof_bt_t *)k1; + const prof_bt_t *bt2 = (prof_bt_t *)k2; + + cassert(config_prof); + + if (bt1->len != bt2->len) + return (false); + return (memcmp(bt1->vec, bt2->vec, bt1->len * sizeof(void *)) == 0); +} + +JEMALLOC_INLINE_C uint64_t +prof_thr_uid_alloc(tsdn_t *tsdn) +{ + uint64_t thr_uid; + + malloc_mutex_lock(tsdn, &next_thr_uid_mtx); + thr_uid = next_thr_uid; + next_thr_uid++; + malloc_mutex_unlock(tsdn, &next_thr_uid_mtx); + + return (thr_uid); +} + +static prof_tdata_t * +prof_tdata_init_impl(tsdn_t *tsdn, uint64_t thr_uid, uint64_t thr_discrim, + char *thread_name, bool active) +{ + prof_tdata_t *tdata; + + cassert(config_prof); + + /* Initialize an empty cache for this thread. */ + tdata = (prof_tdata_t *)iallocztm(tsdn, sizeof(prof_tdata_t), + size2index(sizeof(prof_tdata_t)), false, NULL, true, + arena_get(TSDN_NULL, 0, true), true); + if (tdata == NULL) + return (NULL); + + tdata->lock = prof_tdata_mutex_choose(thr_uid); + tdata->thr_uid = thr_uid; + tdata->thr_discrim = thr_discrim; + tdata->thread_name = thread_name; + tdata->attached = true; + tdata->expired = false; + tdata->tctx_uid_next = 0; + + if (ckh_new(tsdn, &tdata->bt2tctx, PROF_CKH_MINITEMS, + prof_bt_hash, prof_bt_keycomp)) { + idalloctm(tsdn, tdata, NULL, true, true); + return (NULL); + } + + tdata->prng_state = (uint64_t)(uintptr_t)tdata; + prof_sample_threshold_update(tdata); + + tdata->enq = false; + tdata->enq_idump = false; + tdata->enq_gdump = false; + + tdata->dumping = false; + tdata->active = active; + + malloc_mutex_lock(tsdn, &tdatas_mtx); + tdata_tree_insert(&tdatas, tdata); + malloc_mutex_unlock(tsdn, &tdatas_mtx); + + return (tdata); +} + +prof_tdata_t * +prof_tdata_init(tsdn_t *tsdn) +{ + + return (prof_tdata_init_impl(tsdn, prof_thr_uid_alloc(tsdn), 0, NULL, + prof_thread_active_init_get(tsdn))); +} + +static bool +prof_tdata_should_destroy_unlocked(prof_tdata_t *tdata, bool even_if_attached) +{ + + if (tdata->attached && !even_if_attached) + return (false); + if (ckh_count(&tdata->bt2tctx) != 0) + return (false); + return (true); +} + +static bool +prof_tdata_should_destroy(tsdn_t *tsdn, prof_tdata_t *tdata, + bool even_if_attached) +{ + + malloc_mutex_assert_owner(tsdn, tdata->lock); + + return (prof_tdata_should_destroy_unlocked(tdata, even_if_attached)); +} + +static void +prof_tdata_destroy_locked(tsdn_t *tsdn, prof_tdata_t *tdata, + bool even_if_attached) +{ + + malloc_mutex_assert_owner(tsdn, &tdatas_mtx); + + assert(tsdn_null(tsdn) || tsd_prof_tdata_get(tsdn_tsd(tsdn)) != tdata); + + tdata_tree_remove(&tdatas, tdata); + + assert(prof_tdata_should_destroy_unlocked(tdata, even_if_attached)); + + if (tdata->thread_name != NULL) + idalloctm(tsdn, tdata->thread_name, NULL, true, true); + ckh_delete(tsdn, &tdata->bt2tctx); + idalloctm(tsdn, tdata, NULL, true, true); +} + +static void +prof_tdata_destroy(tsdn_t *tsdn, prof_tdata_t *tdata, bool even_if_attached) +{ + + malloc_mutex_lock(tsdn, &tdatas_mtx); + prof_tdata_destroy_locked(tsdn, tdata, even_if_attached); + malloc_mutex_unlock(tsdn, &tdatas_mtx); +} + +static void +prof_tdata_detach(tsd_t *tsd, prof_tdata_t *tdata) +{ + bool destroy_tdata; + + malloc_mutex_lock(tsd_tsdn(tsd), tdata->lock); + if (tdata->attached) { + destroy_tdata = prof_tdata_should_destroy(tsd_tsdn(tsd), tdata, + true); + /* + * Only detach if !destroy_tdata, because detaching would allow + * another thread to win the race to destroy tdata. + */ + if (!destroy_tdata) + tdata->attached = false; + tsd_prof_tdata_set(tsd, NULL); + } else + destroy_tdata = false; + malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock); + if (destroy_tdata) + prof_tdata_destroy(tsd_tsdn(tsd), tdata, true); +} + +prof_tdata_t * +prof_tdata_reinit(tsd_t *tsd, prof_tdata_t *tdata) +{ + uint64_t thr_uid = tdata->thr_uid; + uint64_t thr_discrim = tdata->thr_discrim + 1; + char *thread_name = (tdata->thread_name != NULL) ? + prof_thread_name_alloc(tsd_tsdn(tsd), tdata->thread_name) : NULL; + bool active = tdata->active; + + prof_tdata_detach(tsd, tdata); + return (prof_tdata_init_impl(tsd_tsdn(tsd), thr_uid, thr_discrim, + thread_name, active)); +} + +static bool +prof_tdata_expire(tsdn_t *tsdn, prof_tdata_t *tdata) +{ + bool destroy_tdata; + + malloc_mutex_lock(tsdn, tdata->lock); + if (!tdata->expired) { + tdata->expired = true; + destroy_tdata = tdata->attached ? false : + prof_tdata_should_destroy(tsdn, tdata, false); + } else + destroy_tdata = false; + malloc_mutex_unlock(tsdn, tdata->lock); + + return (destroy_tdata); +} + +static prof_tdata_t * +prof_tdata_reset_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg) +{ + tsdn_t *tsdn = (tsdn_t *)arg; + + return (prof_tdata_expire(tsdn, tdata) ? tdata : NULL); +} + +void +prof_reset(tsdn_t *tsdn, size_t lg_sample) +{ + prof_tdata_t *next; + + assert(lg_sample < (sizeof(uint64_t) << 3)); + + malloc_mutex_lock(tsdn, &prof_dump_mtx); + malloc_mutex_lock(tsdn, &tdatas_mtx); + + lg_prof_sample = lg_sample; + + next = NULL; + do { + prof_tdata_t *to_destroy = tdata_tree_iter(&tdatas, next, + prof_tdata_reset_iter, (void *)tsdn); + if (to_destroy != NULL) { + next = tdata_tree_next(&tdatas, to_destroy); + prof_tdata_destroy_locked(tsdn, to_destroy, false); + } else + next = NULL; + } while (next != NULL); + + malloc_mutex_unlock(tsdn, &tdatas_mtx); + malloc_mutex_unlock(tsdn, &prof_dump_mtx); +} + +void +prof_tdata_cleanup(tsd_t *tsd) +{ + prof_tdata_t *tdata; + + if (!config_prof) + return; + + tdata = tsd_prof_tdata_get(tsd); + if (tdata != NULL) + prof_tdata_detach(tsd, tdata); +} + +bool +prof_active_get(tsdn_t *tsdn) +{ + bool prof_active_current; + + malloc_mutex_lock(tsdn, &prof_active_mtx); + prof_active_current = prof_active; + malloc_mutex_unlock(tsdn, &prof_active_mtx); + return (prof_active_current); +} + +bool +prof_active_set(tsdn_t *tsdn, bool active) +{ + bool prof_active_old; + + malloc_mutex_lock(tsdn, &prof_active_mtx); + prof_active_old = prof_active; + prof_active = active; + malloc_mutex_unlock(tsdn, &prof_active_mtx); + return (prof_active_old); +} + +const char * +prof_thread_name_get(tsd_t *tsd) +{ + prof_tdata_t *tdata; + + tdata = prof_tdata_get(tsd, true); + if (tdata == NULL) + return (""); + return (tdata->thread_name != NULL ? tdata->thread_name : ""); +} + +static char * +prof_thread_name_alloc(tsdn_t *tsdn, const char *thread_name) +{ + char *ret; + size_t size; + + if (thread_name == NULL) + return (NULL); + + size = strlen(thread_name) + 1; + if (size == 1) + return (""); + + ret = iallocztm(tsdn, size, size2index(size), false, NULL, true, + arena_get(TSDN_NULL, 0, true), true); + if (ret == NULL) + return (NULL); + memcpy(ret, thread_name, size); + return (ret); +} + +int +prof_thread_name_set(tsd_t *tsd, const char *thread_name) +{ + prof_tdata_t *tdata; + unsigned i; + char *s; + + tdata = prof_tdata_get(tsd, true); + if (tdata == NULL) + return (EAGAIN); + + /* Validate input. */ + if (thread_name == NULL) + return (EFAULT); + for (i = 0; thread_name[i] != '\0'; i++) { + char c = thread_name[i]; + if (!isgraph(c) && !isblank(c)) + return (EFAULT); + } + + s = prof_thread_name_alloc(tsd_tsdn(tsd), thread_name); + if (s == NULL) + return (EAGAIN); + + if (tdata->thread_name != NULL) { + idalloctm(tsd_tsdn(tsd), tdata->thread_name, NULL, true, true); + tdata->thread_name = NULL; + } + if (strlen(s) > 0) + tdata->thread_name = s; + return (0); +} + +bool +prof_thread_active_get(tsd_t *tsd) +{ + prof_tdata_t *tdata; + + tdata = prof_tdata_get(tsd, true); + if (tdata == NULL) + return (false); + return (tdata->active); +} + +bool +prof_thread_active_set(tsd_t *tsd, bool active) +{ + prof_tdata_t *tdata; + + tdata = prof_tdata_get(tsd, true); + if (tdata == NULL) + return (true); + tdata->active = active; + return (false); +} + +bool +prof_thread_active_init_get(tsdn_t *tsdn) +{ + bool active_init; + + malloc_mutex_lock(tsdn, &prof_thread_active_init_mtx); + active_init = prof_thread_active_init; + malloc_mutex_unlock(tsdn, &prof_thread_active_init_mtx); + return (active_init); +} + +bool +prof_thread_active_init_set(tsdn_t *tsdn, bool active_init) +{ + bool active_init_old; + + malloc_mutex_lock(tsdn, &prof_thread_active_init_mtx); + active_init_old = prof_thread_active_init; + prof_thread_active_init = active_init; + malloc_mutex_unlock(tsdn, &prof_thread_active_init_mtx); + return (active_init_old); +} + +bool +prof_gdump_get(tsdn_t *tsdn) +{ + bool prof_gdump_current; + + malloc_mutex_lock(tsdn, &prof_gdump_mtx); + prof_gdump_current = prof_gdump_val; + malloc_mutex_unlock(tsdn, &prof_gdump_mtx); + return (prof_gdump_current); +} + +bool +prof_gdump_set(tsdn_t *tsdn, bool gdump) +{ + bool prof_gdump_old; + + malloc_mutex_lock(tsdn, &prof_gdump_mtx); + prof_gdump_old = prof_gdump_val; + prof_gdump_val = gdump; + malloc_mutex_unlock(tsdn, &prof_gdump_mtx); + return (prof_gdump_old); +} + +void +prof_boot0(void) +{ + + cassert(config_prof); + + memcpy(opt_prof_prefix, PROF_PREFIX_DEFAULT, + sizeof(PROF_PREFIX_DEFAULT)); +} + +void +prof_boot1(void) +{ + + cassert(config_prof); + + /* + * opt_prof must be in its final state before any arenas are + * initialized, so this function must be executed early. + */ + + if (opt_prof_leak && !opt_prof) { + /* + * Enable opt_prof, but in such a way that profiles are never + * automatically dumped. + */ + opt_prof = true; + opt_prof_gdump = false; + } else if (opt_prof) { + if (opt_lg_prof_interval >= 0) { + prof_interval = (((uint64_t)1U) << + opt_lg_prof_interval); + } + } +} + +bool +prof_boot2(tsdn_t *tsdn) +{ + + cassert(config_prof); + + if (opt_prof) { + unsigned i; + + lg_prof_sample = opt_lg_prof_sample; + + prof_active = opt_prof_active; + if (malloc_mutex_init(&prof_active_mtx, "prof_active", + WITNESS_RANK_PROF_ACTIVE)) + return (true); + + prof_gdump_val = opt_prof_gdump; + if (malloc_mutex_init(&prof_gdump_mtx, "prof_gdump", + WITNESS_RANK_PROF_GDUMP)) + return (true); + + prof_thread_active_init = opt_prof_thread_active_init; + if (malloc_mutex_init(&prof_thread_active_init_mtx, + "prof_thread_active_init", + WITNESS_RANK_PROF_THREAD_ACTIVE_INIT)) + return (true); + + if (ckh_new(tsdn, &bt2gctx, PROF_CKH_MINITEMS, prof_bt_hash, + prof_bt_keycomp)) + return (true); + if (malloc_mutex_init(&bt2gctx_mtx, "prof_bt2gctx", + WITNESS_RANK_PROF_BT2GCTX)) + return (true); + + tdata_tree_new(&tdatas); + if (malloc_mutex_init(&tdatas_mtx, "prof_tdatas", + WITNESS_RANK_PROF_TDATAS)) + return (true); + + next_thr_uid = 0; + if (malloc_mutex_init(&next_thr_uid_mtx, "prof_next_thr_uid", + WITNESS_RANK_PROF_NEXT_THR_UID)) + return (true); + + if (malloc_mutex_init(&prof_dump_seq_mtx, "prof_dump_seq", + WITNESS_RANK_PROF_DUMP_SEQ)) + return (true); + if (malloc_mutex_init(&prof_dump_mtx, "prof_dump", + WITNESS_RANK_PROF_DUMP)) + return (true); + + if (opt_prof_final && opt_prof_prefix[0] != '\0' && + atexit(prof_fdump) != 0) { + malloc_write(": Error in atexit()\n"); + if (opt_abort) + abort(); + } + + gctx_locks = (malloc_mutex_t *)base_alloc(tsdn, PROF_NCTX_LOCKS + * sizeof(malloc_mutex_t)); + if (gctx_locks == NULL) + return (true); + for (i = 0; i < PROF_NCTX_LOCKS; i++) { + if (malloc_mutex_init(&gctx_locks[i], "prof_gctx", + WITNESS_RANK_PROF_GCTX)) + return (true); + } + + tdata_locks = (malloc_mutex_t *)base_alloc(tsdn, + PROF_NTDATA_LOCKS * sizeof(malloc_mutex_t)); + if (tdata_locks == NULL) + return (true); + for (i = 0; i < PROF_NTDATA_LOCKS; i++) { + if (malloc_mutex_init(&tdata_locks[i], "prof_tdata", + WITNESS_RANK_PROF_TDATA)) + return (true); + } + } + +#ifdef JEMALLOC_PROF_LIBGCC + /* + * Cause the backtracing machinery to allocate its internal state + * before enabling profiling. + */ + _Unwind_Backtrace(prof_unwind_init_callback, NULL); +#endif + + prof_booted = true; + + return (false); +} + +void +prof_prefork0(tsdn_t *tsdn) +{ + + if (opt_prof) { + unsigned i; + + malloc_mutex_prefork(tsdn, &prof_dump_mtx); + malloc_mutex_prefork(tsdn, &bt2gctx_mtx); + malloc_mutex_prefork(tsdn, &tdatas_mtx); + for (i = 0; i < PROF_NTDATA_LOCKS; i++) + malloc_mutex_prefork(tsdn, &tdata_locks[i]); + for (i = 0; i < PROF_NCTX_LOCKS; i++) + malloc_mutex_prefork(tsdn, &gctx_locks[i]); + } +} + +void +prof_prefork1(tsdn_t *tsdn) +{ + + if (opt_prof) { + malloc_mutex_prefork(tsdn, &prof_active_mtx); + malloc_mutex_prefork(tsdn, &prof_dump_seq_mtx); + malloc_mutex_prefork(tsdn, &prof_gdump_mtx); + malloc_mutex_prefork(tsdn, &next_thr_uid_mtx); + malloc_mutex_prefork(tsdn, &prof_thread_active_init_mtx); + } +} + +void +prof_postfork_parent(tsdn_t *tsdn) +{ + + if (opt_prof) { + unsigned i; + + malloc_mutex_postfork_parent(tsdn, + &prof_thread_active_init_mtx); + malloc_mutex_postfork_parent(tsdn, &next_thr_uid_mtx); + malloc_mutex_postfork_parent(tsdn, &prof_gdump_mtx); + malloc_mutex_postfork_parent(tsdn, &prof_dump_seq_mtx); + malloc_mutex_postfork_parent(tsdn, &prof_active_mtx); + for (i = 0; i < PROF_NCTX_LOCKS; i++) + malloc_mutex_postfork_parent(tsdn, &gctx_locks[i]); + for (i = 0; i < PROF_NTDATA_LOCKS; i++) + malloc_mutex_postfork_parent(tsdn, &tdata_locks[i]); + malloc_mutex_postfork_parent(tsdn, &tdatas_mtx); + malloc_mutex_postfork_parent(tsdn, &bt2gctx_mtx); + malloc_mutex_postfork_parent(tsdn, &prof_dump_mtx); + } +} + +void +prof_postfork_child(tsdn_t *tsdn) +{ + + if (opt_prof) { + unsigned i; + + malloc_mutex_postfork_child(tsdn, &prof_thread_active_init_mtx); + malloc_mutex_postfork_child(tsdn, &next_thr_uid_mtx); + malloc_mutex_postfork_child(tsdn, &prof_gdump_mtx); + malloc_mutex_postfork_child(tsdn, &prof_dump_seq_mtx); + malloc_mutex_postfork_child(tsdn, &prof_active_mtx); + for (i = 0; i < PROF_NCTX_LOCKS; i++) + malloc_mutex_postfork_child(tsdn, &gctx_locks[i]); + for (i = 0; i < PROF_NTDATA_LOCKS; i++) + malloc_mutex_postfork_child(tsdn, &tdata_locks[i]); + malloc_mutex_postfork_child(tsdn, &tdatas_mtx); + malloc_mutex_postfork_child(tsdn, &bt2gctx_mtx); + malloc_mutex_postfork_child(tsdn, &prof_dump_mtx); + } +} + +/******************************************************************************/ diff --git a/contrib/jemalloc/src/quarantine.c b/contrib/jemalloc/src/quarantine.c new file mode 100644 index 0000000..18903fb --- /dev/null +++ b/contrib/jemalloc/src/quarantine.c @@ -0,0 +1,183 @@ +#define JEMALLOC_QUARANTINE_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/* + * Quarantine pointers close to NULL are used to encode state information that + * is used for cleaning up during thread shutdown. + */ +#define QUARANTINE_STATE_REINCARNATED ((quarantine_t *)(uintptr_t)1) +#define QUARANTINE_STATE_PURGATORY ((quarantine_t *)(uintptr_t)2) +#define QUARANTINE_STATE_MAX QUARANTINE_STATE_PURGATORY + +/******************************************************************************/ +/* Function prototypes for non-inline static functions. */ + +static quarantine_t *quarantine_grow(tsd_t *tsd, quarantine_t *quarantine); +static void quarantine_drain_one(tsdn_t *tsdn, quarantine_t *quarantine); +static void quarantine_drain(tsdn_t *tsdn, quarantine_t *quarantine, + size_t upper_bound); + +/******************************************************************************/ + +static quarantine_t * +quarantine_init(tsdn_t *tsdn, size_t lg_maxobjs) +{ + quarantine_t *quarantine; + size_t size; + + size = offsetof(quarantine_t, objs) + ((ZU(1) << lg_maxobjs) * + sizeof(quarantine_obj_t)); + quarantine = (quarantine_t *)iallocztm(tsdn, size, size2index(size), + false, NULL, true, arena_get(TSDN_NULL, 0, true), true); + if (quarantine == NULL) + return (NULL); + quarantine->curbytes = 0; + quarantine->curobjs = 0; + quarantine->first = 0; + quarantine->lg_maxobjs = lg_maxobjs; + + return (quarantine); +} + +void +quarantine_alloc_hook_work(tsd_t *tsd) +{ + quarantine_t *quarantine; + + if (!tsd_nominal(tsd)) + return; + + quarantine = quarantine_init(tsd_tsdn(tsd), LG_MAXOBJS_INIT); + /* + * Check again whether quarantine has been initialized, because + * quarantine_init() may have triggered recursive initialization. + */ + if (tsd_quarantine_get(tsd) == NULL) + tsd_quarantine_set(tsd, quarantine); + else + idalloctm(tsd_tsdn(tsd), quarantine, NULL, true, true); +} + +static quarantine_t * +quarantine_grow(tsd_t *tsd, quarantine_t *quarantine) +{ + quarantine_t *ret; + + ret = quarantine_init(tsd_tsdn(tsd), quarantine->lg_maxobjs + 1); + if (ret == NULL) { + quarantine_drain_one(tsd_tsdn(tsd), quarantine); + return (quarantine); + } + + ret->curbytes = quarantine->curbytes; + ret->curobjs = quarantine->curobjs; + if (quarantine->first + quarantine->curobjs <= (ZU(1) << + quarantine->lg_maxobjs)) { + /* objs ring buffer data are contiguous. */ + memcpy(ret->objs, &quarantine->objs[quarantine->first], + quarantine->curobjs * sizeof(quarantine_obj_t)); + } else { + /* objs ring buffer data wrap around. */ + size_t ncopy_a = (ZU(1) << quarantine->lg_maxobjs) - + quarantine->first; + size_t ncopy_b = quarantine->curobjs - ncopy_a; + + memcpy(ret->objs, &quarantine->objs[quarantine->first], ncopy_a + * sizeof(quarantine_obj_t)); + memcpy(&ret->objs[ncopy_a], quarantine->objs, ncopy_b * + sizeof(quarantine_obj_t)); + } + idalloctm(tsd_tsdn(tsd), quarantine, NULL, true, true); + + tsd_quarantine_set(tsd, ret); + return (ret); +} + +static void +quarantine_drain_one(tsdn_t *tsdn, quarantine_t *quarantine) +{ + quarantine_obj_t *obj = &quarantine->objs[quarantine->first]; + assert(obj->usize == isalloc(tsdn, obj->ptr, config_prof)); + idalloctm(tsdn, obj->ptr, NULL, false, true); + quarantine->curbytes -= obj->usize; + quarantine->curobjs--; + quarantine->first = (quarantine->first + 1) & ((ZU(1) << + quarantine->lg_maxobjs) - 1); +} + +static void +quarantine_drain(tsdn_t *tsdn, quarantine_t *quarantine, size_t upper_bound) +{ + + while (quarantine->curbytes > upper_bound && quarantine->curobjs > 0) + quarantine_drain_one(tsdn, quarantine); +} + +void +quarantine(tsd_t *tsd, void *ptr) +{ + quarantine_t *quarantine; + size_t usize = isalloc(tsd_tsdn(tsd), ptr, config_prof); + + cassert(config_fill); + assert(opt_quarantine); + + if ((quarantine = tsd_quarantine_get(tsd)) == NULL) { + idalloctm(tsd_tsdn(tsd), ptr, NULL, false, true); + return; + } + /* + * Drain one or more objects if the quarantine size limit would be + * exceeded by appending ptr. + */ + if (quarantine->curbytes + usize > opt_quarantine) { + size_t upper_bound = (opt_quarantine >= usize) ? opt_quarantine + - usize : 0; + quarantine_drain(tsd_tsdn(tsd), quarantine, upper_bound); + } + /* Grow the quarantine ring buffer if it's full. */ + if (quarantine->curobjs == (ZU(1) << quarantine->lg_maxobjs)) + quarantine = quarantine_grow(tsd, quarantine); + /* quarantine_grow() must free a slot if it fails to grow. */ + assert(quarantine->curobjs < (ZU(1) << quarantine->lg_maxobjs)); + /* Append ptr if its size doesn't exceed the quarantine size. */ + if (quarantine->curbytes + usize <= opt_quarantine) { + size_t offset = (quarantine->first + quarantine->curobjs) & + ((ZU(1) << quarantine->lg_maxobjs) - 1); + quarantine_obj_t *obj = &quarantine->objs[offset]; + obj->ptr = ptr; + obj->usize = usize; + quarantine->curbytes += usize; + quarantine->curobjs++; + if (config_fill && unlikely(opt_junk_free)) { + /* + * Only do redzone validation if Valgrind isn't in + * operation. + */ + if ((!config_valgrind || likely(!in_valgrind)) + && usize <= SMALL_MAXCLASS) + arena_quarantine_junk_small(ptr, usize); + else + memset(ptr, JEMALLOC_FREE_JUNK, usize); + } + } else { + assert(quarantine->curbytes == 0); + idalloctm(tsd_tsdn(tsd), ptr, NULL, false, true); + } +} + +void +quarantine_cleanup(tsd_t *tsd) +{ + quarantine_t *quarantine; + + if (!config_fill) + return; + + quarantine = tsd_quarantine_get(tsd); + if (quarantine != NULL) { + quarantine_drain(tsd_tsdn(tsd), quarantine, 0); + idalloctm(tsd_tsdn(tsd), quarantine, NULL, true, true); + tsd_quarantine_set(tsd, NULL); + } +} diff --git a/contrib/jemalloc/src/rtree.c b/contrib/jemalloc/src/rtree.c new file mode 100644 index 0000000..3166b45 --- /dev/null +++ b/contrib/jemalloc/src/rtree.c @@ -0,0 +1,129 @@ +#define JEMALLOC_RTREE_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +static unsigned +hmin(unsigned ha, unsigned hb) +{ + + return (ha < hb ? ha : hb); +} + +/* Only the most significant bits of keys passed to rtree_[gs]et() are used. */ +bool +rtree_new(rtree_t *rtree, unsigned bits, rtree_node_alloc_t *alloc, + rtree_node_dalloc_t *dalloc) +{ + unsigned bits_in_leaf, height, i; + + assert(RTREE_HEIGHT_MAX == ((ZU(1) << (LG_SIZEOF_PTR+3)) / + RTREE_BITS_PER_LEVEL)); + assert(bits > 0 && bits <= (sizeof(uintptr_t) << 3)); + + bits_in_leaf = (bits % RTREE_BITS_PER_LEVEL) == 0 ? RTREE_BITS_PER_LEVEL + : (bits % RTREE_BITS_PER_LEVEL); + if (bits > bits_in_leaf) { + height = 1 + (bits - bits_in_leaf) / RTREE_BITS_PER_LEVEL; + if ((height-1) * RTREE_BITS_PER_LEVEL + bits_in_leaf != bits) + height++; + } else + height = 1; + assert((height-1) * RTREE_BITS_PER_LEVEL + bits_in_leaf == bits); + + rtree->alloc = alloc; + rtree->dalloc = dalloc; + rtree->height = height; + + /* Root level. */ + rtree->levels[0].subtree = NULL; + rtree->levels[0].bits = (height > 1) ? RTREE_BITS_PER_LEVEL : + bits_in_leaf; + rtree->levels[0].cumbits = rtree->levels[0].bits; + /* Interior levels. */ + for (i = 1; i < height-1; i++) { + rtree->levels[i].subtree = NULL; + rtree->levels[i].bits = RTREE_BITS_PER_LEVEL; + rtree->levels[i].cumbits = rtree->levels[i-1].cumbits + + RTREE_BITS_PER_LEVEL; + } + /* Leaf level. */ + if (height > 1) { + rtree->levels[height-1].subtree = NULL; + rtree->levels[height-1].bits = bits_in_leaf; + rtree->levels[height-1].cumbits = bits; + } + + /* Compute lookup table to be used by rtree_start_level(). */ + for (i = 0; i < RTREE_HEIGHT_MAX; i++) { + rtree->start_level[i] = hmin(RTREE_HEIGHT_MAX - 1 - i, height - + 1); + } + + return (false); +} + +static void +rtree_delete_subtree(rtree_t *rtree, rtree_node_elm_t *node, unsigned level) +{ + + if (level + 1 < rtree->height) { + size_t nchildren, i; + + nchildren = ZU(1) << rtree->levels[level].bits; + for (i = 0; i < nchildren; i++) { + rtree_node_elm_t *child = node[i].child; + if (child != NULL) + rtree_delete_subtree(rtree, child, level + 1); + } + } + rtree->dalloc(node); +} + +void +rtree_delete(rtree_t *rtree) +{ + unsigned i; + + for (i = 0; i < rtree->height; i++) { + rtree_node_elm_t *subtree = rtree->levels[i].subtree; + if (subtree != NULL) + rtree_delete_subtree(rtree, subtree, i); + } +} + +static rtree_node_elm_t * +rtree_node_init(rtree_t *rtree, unsigned level, rtree_node_elm_t **elmp) +{ + rtree_node_elm_t *node; + + if (atomic_cas_p((void **)elmp, NULL, RTREE_NODE_INITIALIZING)) { + /* + * Another thread is already in the process of initializing. + * Spin-wait until initialization is complete. + */ + do { + CPU_SPINWAIT; + node = atomic_read_p((void **)elmp); + } while (node == RTREE_NODE_INITIALIZING); + } else { + node = rtree->alloc(ZU(1) << rtree->levels[level].bits); + if (node == NULL) + return (NULL); + atomic_write_p((void **)elmp, node); + } + + return (node); +} + +rtree_node_elm_t * +rtree_subtree_read_hard(rtree_t *rtree, unsigned level) +{ + + return (rtree_node_init(rtree, level, &rtree->levels[level].subtree)); +} + +rtree_node_elm_t * +rtree_child_read_hard(rtree_t *rtree, rtree_node_elm_t *elm, unsigned level) +{ + + return (rtree_node_init(rtree, level, &elm->child)); +} diff --git a/contrib/jemalloc/src/stats.c b/contrib/jemalloc/src/stats.c new file mode 100644 index 0000000..073be4f --- /dev/null +++ b/contrib/jemalloc/src/stats.c @@ -0,0 +1,676 @@ +#define JEMALLOC_STATS_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +#define CTL_GET(n, v, t) do { \ + size_t sz = sizeof(t); \ + xmallctl(n, v, &sz, NULL, 0); \ +} while (0) + +#define CTL_M2_GET(n, i, v, t) do { \ + size_t mib[6]; \ + size_t miblen = sizeof(mib) / sizeof(size_t); \ + size_t sz = sizeof(t); \ + xmallctlnametomib(n, mib, &miblen); \ + mib[2] = (i); \ + xmallctlbymib(mib, miblen, v, &sz, NULL, 0); \ +} while (0) + +#define CTL_M2_M4_GET(n, i, j, v, t) do { \ + size_t mib[6]; \ + size_t miblen = sizeof(mib) / sizeof(size_t); \ + size_t sz = sizeof(t); \ + xmallctlnametomib(n, mib, &miblen); \ + mib[2] = (i); \ + mib[4] = (j); \ + xmallctlbymib(mib, miblen, v, &sz, NULL, 0); \ +} while (0) + +/******************************************************************************/ +/* Data. */ + +bool opt_stats_print = false; + +size_t stats_cactive = 0; + +/******************************************************************************/ +/* Function prototypes for non-inline static functions. */ + +static void stats_arena_bins_print(void (*write_cb)(void *, const char *), + void *cbopaque, unsigned i); +static void stats_arena_lruns_print(void (*write_cb)(void *, const char *), + void *cbopaque, unsigned i); +static void stats_arena_hchunks_print( + void (*write_cb)(void *, const char *), void *cbopaque, unsigned i); +static void stats_arena_print(void (*write_cb)(void *, const char *), + void *cbopaque, unsigned i, bool bins, bool large, bool huge); + +/******************************************************************************/ + +static void +stats_arena_bins_print(void (*write_cb)(void *, const char *), void *cbopaque, + unsigned i) +{ + size_t page; + bool config_tcache, in_gap; + unsigned nbins, j; + + CTL_GET("arenas.page", &page, size_t); + + CTL_GET("config.tcache", &config_tcache, bool); + if (config_tcache) { + malloc_cprintf(write_cb, cbopaque, + "bins: size ind allocated nmalloc" + " ndalloc nrequests curregs curruns regs" + " pgs util nfills nflushes newruns" + " reruns\n"); + } else { + malloc_cprintf(write_cb, cbopaque, + "bins: size ind allocated nmalloc" + " ndalloc nrequests curregs curruns regs" + " pgs util newruns reruns\n"); + } + CTL_GET("arenas.nbins", &nbins, unsigned); + for (j = 0, in_gap = false; j < nbins; j++) { + uint64_t nruns; + + CTL_M2_M4_GET("stats.arenas.0.bins.0.nruns", i, j, &nruns, + uint64_t); + if (nruns == 0) + in_gap = true; + else { + size_t reg_size, run_size, curregs, availregs, milli; + size_t curruns; + uint32_t nregs; + uint64_t nmalloc, ndalloc, nrequests, nfills, nflushes; + uint64_t reruns; + char util[6]; /* "x.yyy". */ + + if (in_gap) { + malloc_cprintf(write_cb, cbopaque, + " ---\n"); + in_gap = false; + } + CTL_M2_GET("arenas.bin.0.size", j, ®_size, size_t); + CTL_M2_GET("arenas.bin.0.nregs", j, &nregs, uint32_t); + CTL_M2_GET("arenas.bin.0.run_size", j, &run_size, + size_t); + CTL_M2_M4_GET("stats.arenas.0.bins.0.nmalloc", i, j, + &nmalloc, uint64_t); + CTL_M2_M4_GET("stats.arenas.0.bins.0.ndalloc", i, j, + &ndalloc, uint64_t); + CTL_M2_M4_GET("stats.arenas.0.bins.0.curregs", i, j, + &curregs, size_t); + CTL_M2_M4_GET("stats.arenas.0.bins.0.nrequests", i, j, + &nrequests, uint64_t); + if (config_tcache) { + CTL_M2_M4_GET("stats.arenas.0.bins.0.nfills", i, + j, &nfills, uint64_t); + CTL_M2_M4_GET("stats.arenas.0.bins.0.nflushes", + i, j, &nflushes, uint64_t); + } + CTL_M2_M4_GET("stats.arenas.0.bins.0.nreruns", i, j, + &reruns, uint64_t); + CTL_M2_M4_GET("stats.arenas.0.bins.0.curruns", i, j, + &curruns, size_t); + + availregs = nregs * curruns; + milli = (availregs != 0) ? (1000 * curregs) / availregs + : 1000; + assert(milli <= 1000); + if (milli < 10) { + malloc_snprintf(util, sizeof(util), + "0.00%zu", milli); + } else if (milli < 100) { + malloc_snprintf(util, sizeof(util), "0.0%zu", + milli); + } else if (milli < 1000) { + malloc_snprintf(util, sizeof(util), "0.%zu", + milli); + } else + malloc_snprintf(util, sizeof(util), "1"); + + if (config_tcache) { + malloc_cprintf(write_cb, cbopaque, + "%20zu %3u %12zu %12"FMTu64 + " %12"FMTu64" %12"FMTu64" %12zu" + " %12zu %4u %3zu %-5s %12"FMTu64 + " %12"FMTu64" %12"FMTu64" %12"FMTu64"\n", + reg_size, j, curregs * reg_size, nmalloc, + ndalloc, nrequests, curregs, curruns, nregs, + run_size / page, util, nfills, nflushes, + nruns, reruns); + } else { + malloc_cprintf(write_cb, cbopaque, + "%20zu %3u %12zu %12"FMTu64 + " %12"FMTu64" %12"FMTu64" %12zu" + " %12zu %4u %3zu %-5s %12"FMTu64 + " %12"FMTu64"\n", + reg_size, j, curregs * reg_size, nmalloc, + ndalloc, nrequests, curregs, curruns, nregs, + run_size / page, util, nruns, reruns); + } + } + } + if (in_gap) { + malloc_cprintf(write_cb, cbopaque, + " ---\n"); + } +} + +static void +stats_arena_lruns_print(void (*write_cb)(void *, const char *), void *cbopaque, + unsigned i) +{ + unsigned nbins, nlruns, j; + bool in_gap; + + malloc_cprintf(write_cb, cbopaque, + "large: size ind allocated nmalloc ndalloc" + " nrequests curruns\n"); + CTL_GET("arenas.nbins", &nbins, unsigned); + CTL_GET("arenas.nlruns", &nlruns, unsigned); + for (j = 0, in_gap = false; j < nlruns; j++) { + uint64_t nmalloc, ndalloc, nrequests; + size_t run_size, curruns; + + CTL_M2_M4_GET("stats.arenas.0.lruns.0.nmalloc", i, j, &nmalloc, + uint64_t); + CTL_M2_M4_GET("stats.arenas.0.lruns.0.ndalloc", i, j, &ndalloc, + uint64_t); + CTL_M2_M4_GET("stats.arenas.0.lruns.0.nrequests", i, j, + &nrequests, uint64_t); + if (nrequests == 0) + in_gap = true; + else { + CTL_M2_GET("arenas.lrun.0.size", j, &run_size, size_t); + CTL_M2_M4_GET("stats.arenas.0.lruns.0.curruns", i, j, + &curruns, size_t); + if (in_gap) { + malloc_cprintf(write_cb, cbopaque, + " ---\n"); + in_gap = false; + } + malloc_cprintf(write_cb, cbopaque, + "%20zu %3u %12zu %12"FMTu64" %12"FMTu64 + " %12"FMTu64" %12zu\n", + run_size, nbins + j, curruns * run_size, nmalloc, + ndalloc, nrequests, curruns); + } + } + if (in_gap) { + malloc_cprintf(write_cb, cbopaque, + " ---\n"); + } +} + +static void +stats_arena_hchunks_print(void (*write_cb)(void *, const char *), + void *cbopaque, unsigned i) +{ + unsigned nbins, nlruns, nhchunks, j; + bool in_gap; + + malloc_cprintf(write_cb, cbopaque, + "huge: size ind allocated nmalloc ndalloc" + " nrequests curhchunks\n"); + CTL_GET("arenas.nbins", &nbins, unsigned); + CTL_GET("arenas.nlruns", &nlruns, unsigned); + CTL_GET("arenas.nhchunks", &nhchunks, unsigned); + for (j = 0, in_gap = false; j < nhchunks; j++) { + uint64_t nmalloc, ndalloc, nrequests; + size_t hchunk_size, curhchunks; + + CTL_M2_M4_GET("stats.arenas.0.hchunks.0.nmalloc", i, j, + &nmalloc, uint64_t); + CTL_M2_M4_GET("stats.arenas.0.hchunks.0.ndalloc", i, j, + &ndalloc, uint64_t); + CTL_M2_M4_GET("stats.arenas.0.hchunks.0.nrequests", i, j, + &nrequests, uint64_t); + if (nrequests == 0) + in_gap = true; + else { + CTL_M2_GET("arenas.hchunk.0.size", j, &hchunk_size, + size_t); + CTL_M2_M4_GET("stats.arenas.0.hchunks.0.curhchunks", i, + j, &curhchunks, size_t); + if (in_gap) { + malloc_cprintf(write_cb, cbopaque, + " ---\n"); + in_gap = false; + } + malloc_cprintf(write_cb, cbopaque, + "%20zu %3u %12zu %12"FMTu64" %12"FMTu64 + " %12"FMTu64" %12zu\n", + hchunk_size, nbins + nlruns + j, + curhchunks * hchunk_size, nmalloc, ndalloc, + nrequests, curhchunks); + } + } + if (in_gap) { + malloc_cprintf(write_cb, cbopaque, + " ---\n"); + } +} + +static void +stats_arena_print(void (*write_cb)(void *, const char *), void *cbopaque, + unsigned i, bool bins, bool large, bool huge) +{ + unsigned nthreads; + const char *dss; + ssize_t lg_dirty_mult, decay_time; + size_t page, pactive, pdirty, mapped, retained; + size_t metadata_mapped, metadata_allocated; + uint64_t npurge, nmadvise, purged; + size_t small_allocated; + uint64_t small_nmalloc, small_ndalloc, small_nrequests; + size_t large_allocated; + uint64_t large_nmalloc, large_ndalloc, large_nrequests; + size_t huge_allocated; + uint64_t huge_nmalloc, huge_ndalloc, huge_nrequests; + + CTL_GET("arenas.page", &page, size_t); + + CTL_M2_GET("stats.arenas.0.nthreads", i, &nthreads, unsigned); + malloc_cprintf(write_cb, cbopaque, + "assigned threads: %u\n", nthreads); + CTL_M2_GET("stats.arenas.0.dss", i, &dss, const char *); + malloc_cprintf(write_cb, cbopaque, "dss allocation precedence: %s\n", + dss); + CTL_M2_GET("stats.arenas.0.lg_dirty_mult", i, &lg_dirty_mult, ssize_t); + if (opt_purge == purge_mode_ratio) { + if (lg_dirty_mult >= 0) { + malloc_cprintf(write_cb, cbopaque, + "min active:dirty page ratio: %u:1\n", + (1U << lg_dirty_mult)); + } else { + malloc_cprintf(write_cb, cbopaque, + "min active:dirty page ratio: N/A\n"); + } + } + CTL_M2_GET("stats.arenas.0.decay_time", i, &decay_time, ssize_t); + if (opt_purge == purge_mode_decay) { + if (decay_time >= 0) { + malloc_cprintf(write_cb, cbopaque, "decay time: %zd\n", + decay_time); + } else + malloc_cprintf(write_cb, cbopaque, "decay time: N/A\n"); + } + CTL_M2_GET("stats.arenas.0.pactive", i, &pactive, size_t); + CTL_M2_GET("stats.arenas.0.pdirty", i, &pdirty, size_t); + CTL_M2_GET("stats.arenas.0.npurge", i, &npurge, uint64_t); + CTL_M2_GET("stats.arenas.0.nmadvise", i, &nmadvise, uint64_t); + CTL_M2_GET("stats.arenas.0.purged", i, &purged, uint64_t); + malloc_cprintf(write_cb, cbopaque, + "purging: dirty: %zu, sweeps: %"FMTu64", madvises: %"FMTu64", " + "purged: %"FMTu64"\n", pdirty, npurge, nmadvise, purged); + + malloc_cprintf(write_cb, cbopaque, + " allocated nmalloc ndalloc" + " nrequests\n"); + CTL_M2_GET("stats.arenas.0.small.allocated", i, &small_allocated, + size_t); + CTL_M2_GET("stats.arenas.0.small.nmalloc", i, &small_nmalloc, uint64_t); + CTL_M2_GET("stats.arenas.0.small.ndalloc", i, &small_ndalloc, uint64_t); + CTL_M2_GET("stats.arenas.0.small.nrequests", i, &small_nrequests, + uint64_t); + malloc_cprintf(write_cb, cbopaque, + "small: %12zu %12"FMTu64" %12"FMTu64 + " %12"FMTu64"\n", + small_allocated, small_nmalloc, small_ndalloc, small_nrequests); + CTL_M2_GET("stats.arenas.0.large.allocated", i, &large_allocated, + size_t); + CTL_M2_GET("stats.arenas.0.large.nmalloc", i, &large_nmalloc, uint64_t); + CTL_M2_GET("stats.arenas.0.large.ndalloc", i, &large_ndalloc, uint64_t); + CTL_M2_GET("stats.arenas.0.large.nrequests", i, &large_nrequests, + uint64_t); + malloc_cprintf(write_cb, cbopaque, + "large: %12zu %12"FMTu64" %12"FMTu64 + " %12"FMTu64"\n", + large_allocated, large_nmalloc, large_ndalloc, large_nrequests); + CTL_M2_GET("stats.arenas.0.huge.allocated", i, &huge_allocated, size_t); + CTL_M2_GET("stats.arenas.0.huge.nmalloc", i, &huge_nmalloc, uint64_t); + CTL_M2_GET("stats.arenas.0.huge.ndalloc", i, &huge_ndalloc, uint64_t); + CTL_M2_GET("stats.arenas.0.huge.nrequests", i, &huge_nrequests, + uint64_t); + malloc_cprintf(write_cb, cbopaque, + "huge: %12zu %12"FMTu64" %12"FMTu64 + " %12"FMTu64"\n", + huge_allocated, huge_nmalloc, huge_ndalloc, huge_nrequests); + malloc_cprintf(write_cb, cbopaque, + "total: %12zu %12"FMTu64" %12"FMTu64 + " %12"FMTu64"\n", + small_allocated + large_allocated + huge_allocated, + small_nmalloc + large_nmalloc + huge_nmalloc, + small_ndalloc + large_ndalloc + huge_ndalloc, + small_nrequests + large_nrequests + huge_nrequests); + malloc_cprintf(write_cb, cbopaque, + "active: %12zu\n", pactive * page); + CTL_M2_GET("stats.arenas.0.mapped", i, &mapped, size_t); + malloc_cprintf(write_cb, cbopaque, + "mapped: %12zu\n", mapped); + CTL_M2_GET("stats.arenas.0.retained", i, &retained, size_t); + malloc_cprintf(write_cb, cbopaque, + "retained: %12zu\n", retained); + CTL_M2_GET("stats.arenas.0.metadata.mapped", i, &metadata_mapped, + size_t); + CTL_M2_GET("stats.arenas.0.metadata.allocated", i, &metadata_allocated, + size_t); + malloc_cprintf(write_cb, cbopaque, + "metadata: mapped: %zu, allocated: %zu\n", + metadata_mapped, metadata_allocated); + + if (bins) + stats_arena_bins_print(write_cb, cbopaque, i); + if (large) + stats_arena_lruns_print(write_cb, cbopaque, i); + if (huge) + stats_arena_hchunks_print(write_cb, cbopaque, i); +} + +void +stats_print(void (*write_cb)(void *, const char *), void *cbopaque, + const char *opts) +{ + int err; + uint64_t epoch; + size_t u64sz; + bool general = true; + bool merged = true; + bool unmerged = true; + bool bins = true; + bool large = true; + bool huge = true; + + /* + * Refresh stats, in case mallctl() was called by the application. + * + * Check for OOM here, since refreshing the ctl cache can trigger + * allocation. In practice, none of the subsequent mallctl()-related + * calls in this function will cause OOM if this one succeeds. + * */ + epoch = 1; + u64sz = sizeof(uint64_t); + err = je_mallctl("epoch", &epoch, &u64sz, &epoch, sizeof(uint64_t)); + if (err != 0) { + if (err == EAGAIN) { + malloc_write(": Memory allocation failure in " + "mallctl(\"epoch\", ...)\n"); + return; + } + malloc_write(": Failure in mallctl(\"epoch\", " + "...)\n"); + abort(); + } + + if (opts != NULL) { + unsigned i; + + for (i = 0; opts[i] != '\0'; i++) { + switch (opts[i]) { + case 'g': + general = false; + break; + case 'm': + merged = false; + break; + case 'a': + unmerged = false; + break; + case 'b': + bins = false; + break; + case 'l': + large = false; + break; + case 'h': + huge = false; + break; + default:; + } + } + } + + malloc_cprintf(write_cb, cbopaque, + "___ Begin jemalloc statistics ___\n"); + if (general) { + const char *cpv; + bool bv; + unsigned uv; + ssize_t ssv; + size_t sv, bsz, usz, ssz, sssz, cpsz; + + bsz = sizeof(bool); + usz = sizeof(unsigned); + ssz = sizeof(size_t); + sssz = sizeof(ssize_t); + cpsz = sizeof(const char *); + + CTL_GET("version", &cpv, const char *); + malloc_cprintf(write_cb, cbopaque, "Version: %s\n", cpv); + CTL_GET("config.debug", &bv, bool); + malloc_cprintf(write_cb, cbopaque, "Assertions %s\n", + bv ? "enabled" : "disabled"); + malloc_cprintf(write_cb, cbopaque, + "config.malloc_conf: \"%s\"\n", config_malloc_conf); + +#define OPT_WRITE_BOOL(n) \ + if (je_mallctl("opt."#n, &bv, &bsz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": %s\n", bv ? "true" : "false"); \ + } +#define OPT_WRITE_BOOL_MUTABLE(n, m) { \ + bool bv2; \ + if (je_mallctl("opt."#n, &bv, &bsz, NULL, 0) == 0 && \ + je_mallctl(#m, &bv2, &bsz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": %s ("#m": %s)\n", bv ? "true" \ + : "false", bv2 ? "true" : "false"); \ + } \ +} +#define OPT_WRITE_UNSIGNED(n) \ + if (je_mallctl("opt."#n, &uv, &usz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": %u\n", uv); \ + } +#define OPT_WRITE_SIZE_T(n) \ + if (je_mallctl("opt."#n, &sv, &ssz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": %zu\n", sv); \ + } +#define OPT_WRITE_SSIZE_T(n) \ + if (je_mallctl("opt."#n, &ssv, &sssz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": %zd\n", ssv); \ + } +#define OPT_WRITE_SSIZE_T_MUTABLE(n, m) { \ + ssize_t ssv2; \ + if (je_mallctl("opt."#n, &ssv, &sssz, NULL, 0) == 0 && \ + je_mallctl(#m, &ssv2, &sssz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": %zd ("#m": %zd)\n", \ + ssv, ssv2); \ + } \ +} +#define OPT_WRITE_CHAR_P(n) \ + if (je_mallctl("opt."#n, &cpv, &cpsz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": \"%s\"\n", cpv); \ + } + + malloc_cprintf(write_cb, cbopaque, + "Run-time option settings:\n"); + OPT_WRITE_BOOL(abort) + OPT_WRITE_SIZE_T(lg_chunk) + OPT_WRITE_CHAR_P(dss) + OPT_WRITE_UNSIGNED(narenas) + OPT_WRITE_CHAR_P(purge) + if (opt_purge == purge_mode_ratio) { + OPT_WRITE_SSIZE_T_MUTABLE(lg_dirty_mult, + arenas.lg_dirty_mult) + } + if (opt_purge == purge_mode_decay) + OPT_WRITE_SSIZE_T_MUTABLE(decay_time, arenas.decay_time) + OPT_WRITE_BOOL(stats_print) + OPT_WRITE_CHAR_P(junk) + OPT_WRITE_SIZE_T(quarantine) + OPT_WRITE_BOOL(redzone) + OPT_WRITE_BOOL(zero) + OPT_WRITE_BOOL(utrace) + OPT_WRITE_BOOL(valgrind) + OPT_WRITE_BOOL(xmalloc) + OPT_WRITE_BOOL(tcache) + OPT_WRITE_SSIZE_T(lg_tcache_max) + OPT_WRITE_BOOL(prof) + OPT_WRITE_CHAR_P(prof_prefix) + OPT_WRITE_BOOL_MUTABLE(prof_active, prof.active) + OPT_WRITE_BOOL_MUTABLE(prof_thread_active_init, + prof.thread_active_init) + OPT_WRITE_SSIZE_T(lg_prof_sample) + OPT_WRITE_BOOL(prof_accum) + OPT_WRITE_SSIZE_T(lg_prof_interval) + OPT_WRITE_BOOL(prof_gdump) + OPT_WRITE_BOOL(prof_final) + OPT_WRITE_BOOL(prof_leak) + +#undef OPT_WRITE_BOOL +#undef OPT_WRITE_BOOL_MUTABLE +#undef OPT_WRITE_SIZE_T +#undef OPT_WRITE_SSIZE_T +#undef OPT_WRITE_CHAR_P + + malloc_cprintf(write_cb, cbopaque, "CPUs: %u\n", ncpus); + + CTL_GET("arenas.narenas", &uv, unsigned); + malloc_cprintf(write_cb, cbopaque, "Arenas: %u\n", uv); + + malloc_cprintf(write_cb, cbopaque, "Pointer size: %zu\n", + sizeof(void *)); + + CTL_GET("arenas.quantum", &sv, size_t); + malloc_cprintf(write_cb, cbopaque, "Quantum size: %zu\n", + sv); + + CTL_GET("arenas.page", &sv, size_t); + malloc_cprintf(write_cb, cbopaque, "Page size: %zu\n", sv); + + CTL_GET("arenas.lg_dirty_mult", &ssv, ssize_t); + if (opt_purge == purge_mode_ratio) { + if (ssv >= 0) { + malloc_cprintf(write_cb, cbopaque, + "Min active:dirty page ratio per arena: " + "%u:1\n", (1U << ssv)); + } else { + malloc_cprintf(write_cb, cbopaque, + "Min active:dirty page ratio per arena: " + "N/A\n"); + } + } + CTL_GET("arenas.decay_time", &ssv, ssize_t); + if (opt_purge == purge_mode_decay) { + malloc_cprintf(write_cb, cbopaque, + "Unused dirty page decay time: %zd%s\n", + ssv, (ssv < 0) ? " (no decay)" : ""); + } + if (je_mallctl("arenas.tcache_max", &sv, &ssz, NULL, 0) == 0) { + malloc_cprintf(write_cb, cbopaque, + "Maximum thread-cached size class: %zu\n", sv); + } + if (je_mallctl("opt.prof", &bv, &bsz, NULL, 0) == 0 && bv) { + CTL_GET("prof.lg_sample", &sv, size_t); + malloc_cprintf(write_cb, cbopaque, + "Average profile sample interval: %"FMTu64 + " (2^%zu)\n", (((uint64_t)1U) << sv), sv); + + CTL_GET("opt.lg_prof_interval", &ssv, ssize_t); + if (ssv >= 0) { + malloc_cprintf(write_cb, cbopaque, + "Average profile dump interval: %"FMTu64 + " (2^%zd)\n", + (((uint64_t)1U) << ssv), ssv); + } else { + malloc_cprintf(write_cb, cbopaque, + "Average profile dump interval: N/A\n"); + } + } + CTL_GET("opt.lg_chunk", &sv, size_t); + malloc_cprintf(write_cb, cbopaque, + "Chunk size: %zu (2^%zu)\n", (ZU(1) << sv), sv); + } + + if (config_stats) { + size_t *cactive; + size_t allocated, active, metadata, resident, mapped, retained; + + CTL_GET("stats.cactive", &cactive, size_t *); + CTL_GET("stats.allocated", &allocated, size_t); + CTL_GET("stats.active", &active, size_t); + CTL_GET("stats.metadata", &metadata, size_t); + CTL_GET("stats.resident", &resident, size_t); + CTL_GET("stats.mapped", &mapped, size_t); + CTL_GET("stats.retained", &retained, size_t); + malloc_cprintf(write_cb, cbopaque, + "Allocated: %zu, active: %zu, metadata: %zu," + " resident: %zu, mapped: %zu, retained: %zu\n", + allocated, active, metadata, resident, mapped, retained); + malloc_cprintf(write_cb, cbopaque, + "Current active ceiling: %zu\n", + atomic_read_z(cactive)); + + if (merged) { + unsigned narenas; + + CTL_GET("arenas.narenas", &narenas, unsigned); + { + VARIABLE_ARRAY(bool, initialized, narenas); + size_t isz; + unsigned i, ninitialized; + + isz = sizeof(bool) * narenas; + xmallctl("arenas.initialized", initialized, + &isz, NULL, 0); + for (i = ninitialized = 0; i < narenas; i++) { + if (initialized[i]) + ninitialized++; + } + + if (ninitialized > 1 || !unmerged) { + /* Print merged arena stats. */ + malloc_cprintf(write_cb, cbopaque, + "\nMerged arenas stats:\n"); + stats_arena_print(write_cb, cbopaque, + narenas, bins, large, huge); + } + } + } + + if (unmerged) { + unsigned narenas; + + /* Print stats for each arena. */ + + CTL_GET("arenas.narenas", &narenas, unsigned); + { + VARIABLE_ARRAY(bool, initialized, narenas); + size_t isz; + unsigned i; + + isz = sizeof(bool) * narenas; + xmallctl("arenas.initialized", initialized, + &isz, NULL, 0); + + for (i = 0; i < narenas; i++) { + if (initialized[i]) { + malloc_cprintf(write_cb, + cbopaque, + "\narenas[%u]:\n", i); + stats_arena_print(write_cb, + cbopaque, i, bins, large, + huge); + } + } + } + } + } + malloc_cprintf(write_cb, cbopaque, "--- End jemalloc statistics ---\n"); +} diff --git a/contrib/jemalloc/src/tcache.c b/contrib/jemalloc/src/tcache.c new file mode 100644 index 0000000..175759c --- /dev/null +++ b/contrib/jemalloc/src/tcache.c @@ -0,0 +1,555 @@ +#define JEMALLOC_TCACHE_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +bool opt_tcache = true; +ssize_t opt_lg_tcache_max = LG_TCACHE_MAXCLASS_DEFAULT; + +tcache_bin_info_t *tcache_bin_info; +static unsigned stack_nelms; /* Total stack elms per tcache. */ + +unsigned nhbins; +size_t tcache_maxclass; + +tcaches_t *tcaches; + +/* Index of first element within tcaches that has never been used. */ +static unsigned tcaches_past; + +/* Head of singly linked list tracking available tcaches elements. */ +static tcaches_t *tcaches_avail; + +/******************************************************************************/ + +size_t +tcache_salloc(tsdn_t *tsdn, const void *ptr) +{ + + return (arena_salloc(tsdn, ptr, false)); +} + +void +tcache_event_hard(tsd_t *tsd, tcache_t *tcache) +{ + szind_t binind = tcache->next_gc_bin; + tcache_bin_t *tbin = &tcache->tbins[binind]; + tcache_bin_info_t *tbin_info = &tcache_bin_info[binind]; + + if (tbin->low_water > 0) { + /* + * Flush (ceiling) 3/4 of the objects below the low water mark. + */ + if (binind < NBINS) { + tcache_bin_flush_small(tsd, tcache, tbin, binind, + tbin->ncached - tbin->low_water + (tbin->low_water + >> 2)); + } else { + tcache_bin_flush_large(tsd, tbin, binind, tbin->ncached + - tbin->low_water + (tbin->low_water >> 2), tcache); + } + /* + * Reduce fill count by 2X. Limit lg_fill_div such that the + * fill count is always at least 1. + */ + if ((tbin_info->ncached_max >> (tbin->lg_fill_div+1)) >= 1) + tbin->lg_fill_div++; + } else if (tbin->low_water < 0) { + /* + * Increase fill count by 2X. Make sure lg_fill_div stays + * greater than 0. + */ + if (tbin->lg_fill_div > 1) + tbin->lg_fill_div--; + } + tbin->low_water = tbin->ncached; + + tcache->next_gc_bin++; + if (tcache->next_gc_bin == nhbins) + tcache->next_gc_bin = 0; +} + +void * +tcache_alloc_small_hard(tsdn_t *tsdn, arena_t *arena, tcache_t *tcache, + tcache_bin_t *tbin, szind_t binind, bool *tcache_success) +{ + void *ret; + + arena_tcache_fill_small(tsdn, arena, tbin, binind, config_prof ? + tcache->prof_accumbytes : 0); + if (config_prof) + tcache->prof_accumbytes = 0; + ret = tcache_alloc_easy(tbin, tcache_success); + + return (ret); +} + +void +tcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, tcache_bin_t *tbin, + szind_t binind, unsigned rem) +{ + arena_t *arena; + void *ptr; + unsigned i, nflush, ndeferred; + bool merged_stats = false; + + assert(binind < NBINS); + assert(rem <= tbin->ncached); + + arena = arena_choose(tsd, NULL); + assert(arena != NULL); + for (nflush = tbin->ncached - rem; nflush > 0; nflush = ndeferred) { + /* Lock the arena bin associated with the first object. */ + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE( + *(tbin->avail - 1)); + arena_t *bin_arena = extent_node_arena_get(&chunk->node); + arena_bin_t *bin = &bin_arena->bins[binind]; + + if (config_prof && bin_arena == arena) { + if (arena_prof_accum(tsd_tsdn(tsd), arena, + tcache->prof_accumbytes)) + prof_idump(tsd_tsdn(tsd)); + tcache->prof_accumbytes = 0; + } + + malloc_mutex_lock(tsd_tsdn(tsd), &bin->lock); + if (config_stats && bin_arena == arena) { + assert(!merged_stats); + merged_stats = true; + bin->stats.nflushes++; + bin->stats.nrequests += tbin->tstats.nrequests; + tbin->tstats.nrequests = 0; + } + ndeferred = 0; + for (i = 0; i < nflush; i++) { + ptr = *(tbin->avail - 1 - i); + assert(ptr != NULL); + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (extent_node_arena_get(&chunk->node) == bin_arena) { + size_t pageind = ((uintptr_t)ptr - + (uintptr_t)chunk) >> LG_PAGE; + arena_chunk_map_bits_t *bitselm = + arena_bitselm_get_mutable(chunk, pageind); + arena_dalloc_bin_junked_locked(tsd_tsdn(tsd), + bin_arena, chunk, ptr, bitselm); + } else { + /* + * This object was allocated via a different + * arena bin than the one that is currently + * locked. Stash the object, so that it can be + * handled in a future pass. + */ + *(tbin->avail - 1 - ndeferred) = ptr; + ndeferred++; + } + } + malloc_mutex_unlock(tsd_tsdn(tsd), &bin->lock); + arena_decay_ticks(tsd_tsdn(tsd), bin_arena, nflush - ndeferred); + } + if (config_stats && !merged_stats) { + /* + * The flush loop didn't happen to flush to this thread's + * arena, so the stats didn't get merged. Manually do so now. + */ + arena_bin_t *bin = &arena->bins[binind]; + malloc_mutex_lock(tsd_tsdn(tsd), &bin->lock); + bin->stats.nflushes++; + bin->stats.nrequests += tbin->tstats.nrequests; + tbin->tstats.nrequests = 0; + malloc_mutex_unlock(tsd_tsdn(tsd), &bin->lock); + } + + memmove(tbin->avail - rem, tbin->avail - tbin->ncached, rem * + sizeof(void *)); + tbin->ncached = rem; + if ((int)tbin->ncached < tbin->low_water) + tbin->low_water = tbin->ncached; +} + +void +tcache_bin_flush_large(tsd_t *tsd, tcache_bin_t *tbin, szind_t binind, + unsigned rem, tcache_t *tcache) +{ + arena_t *arena; + void *ptr; + unsigned i, nflush, ndeferred; + bool merged_stats = false; + + assert(binind < nhbins); + assert(rem <= tbin->ncached); + + arena = arena_choose(tsd, NULL); + assert(arena != NULL); + for (nflush = tbin->ncached - rem; nflush > 0; nflush = ndeferred) { + /* Lock the arena associated with the first object. */ + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE( + *(tbin->avail - 1)); + arena_t *locked_arena = extent_node_arena_get(&chunk->node); + UNUSED bool idump; + + if (config_prof) + idump = false; + malloc_mutex_lock(tsd_tsdn(tsd), &locked_arena->lock); + if ((config_prof || config_stats) && locked_arena == arena) { + if (config_prof) { + idump = arena_prof_accum_locked(arena, + tcache->prof_accumbytes); + tcache->prof_accumbytes = 0; + } + if (config_stats) { + merged_stats = true; + arena->stats.nrequests_large += + tbin->tstats.nrequests; + arena->stats.lstats[binind - NBINS].nrequests += + tbin->tstats.nrequests; + tbin->tstats.nrequests = 0; + } + } + ndeferred = 0; + for (i = 0; i < nflush; i++) { + ptr = *(tbin->avail - 1 - i); + assert(ptr != NULL); + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (extent_node_arena_get(&chunk->node) == + locked_arena) { + arena_dalloc_large_junked_locked(tsd_tsdn(tsd), + locked_arena, chunk, ptr); + } else { + /* + * This object was allocated via a different + * arena than the one that is currently locked. + * Stash the object, so that it can be handled + * in a future pass. + */ + *(tbin->avail - 1 - ndeferred) = ptr; + ndeferred++; + } + } + malloc_mutex_unlock(tsd_tsdn(tsd), &locked_arena->lock); + if (config_prof && idump) + prof_idump(tsd_tsdn(tsd)); + arena_decay_ticks(tsd_tsdn(tsd), locked_arena, nflush - + ndeferred); + } + if (config_stats && !merged_stats) { + /* + * The flush loop didn't happen to flush to this thread's + * arena, so the stats didn't get merged. Manually do so now. + */ + malloc_mutex_lock(tsd_tsdn(tsd), &arena->lock); + arena->stats.nrequests_large += tbin->tstats.nrequests; + arena->stats.lstats[binind - NBINS].nrequests += + tbin->tstats.nrequests; + tbin->tstats.nrequests = 0; + malloc_mutex_unlock(tsd_tsdn(tsd), &arena->lock); + } + + memmove(tbin->avail - rem, tbin->avail - tbin->ncached, rem * + sizeof(void *)); + tbin->ncached = rem; + if ((int)tbin->ncached < tbin->low_water) + tbin->low_water = tbin->ncached; +} + +static void +tcache_arena_associate(tsdn_t *tsdn, tcache_t *tcache, arena_t *arena) +{ + + if (config_stats) { + /* Link into list of extant tcaches. */ + malloc_mutex_lock(tsdn, &arena->lock); + ql_elm_new(tcache, link); + ql_tail_insert(&arena->tcache_ql, tcache, link); + malloc_mutex_unlock(tsdn, &arena->lock); + } +} + +static void +tcache_arena_dissociate(tsdn_t *tsdn, tcache_t *tcache, arena_t *arena) +{ + + if (config_stats) { + /* Unlink from list of extant tcaches. */ + malloc_mutex_lock(tsdn, &arena->lock); + if (config_debug) { + bool in_ql = false; + tcache_t *iter; + ql_foreach(iter, &arena->tcache_ql, link) { + if (iter == tcache) { + in_ql = true; + break; + } + } + assert(in_ql); + } + ql_remove(&arena->tcache_ql, tcache, link); + tcache_stats_merge(tsdn, tcache, arena); + malloc_mutex_unlock(tsdn, &arena->lock); + } +} + +void +tcache_arena_reassociate(tsdn_t *tsdn, tcache_t *tcache, arena_t *oldarena, + arena_t *newarena) +{ + + tcache_arena_dissociate(tsdn, tcache, oldarena); + tcache_arena_associate(tsdn, tcache, newarena); +} + +tcache_t * +tcache_get_hard(tsd_t *tsd) +{ + arena_t *arena; + + if (!tcache_enabled_get()) { + if (tsd_nominal(tsd)) + tcache_enabled_set(false); /* Memoize. */ + return (NULL); + } + arena = arena_choose(tsd, NULL); + if (unlikely(arena == NULL)) + return (NULL); + return (tcache_create(tsd_tsdn(tsd), arena)); +} + +tcache_t * +tcache_create(tsdn_t *tsdn, arena_t *arena) +{ + tcache_t *tcache; + size_t size, stack_offset; + unsigned i; + + size = offsetof(tcache_t, tbins) + (sizeof(tcache_bin_t) * nhbins); + /* Naturally align the pointer stacks. */ + size = PTR_CEILING(size); + stack_offset = size; + size += stack_nelms * sizeof(void *); + /* Avoid false cacheline sharing. */ + size = sa2u(size, CACHELINE); + + tcache = ipallocztm(tsdn, size, CACHELINE, true, NULL, true, + arena_get(TSDN_NULL, 0, true)); + if (tcache == NULL) + return (NULL); + + tcache_arena_associate(tsdn, tcache, arena); + + ticker_init(&tcache->gc_ticker, TCACHE_GC_INCR); + + assert((TCACHE_NSLOTS_SMALL_MAX & 1U) == 0); + for (i = 0; i < nhbins; i++) { + tcache->tbins[i].lg_fill_div = 1; + stack_offset += tcache_bin_info[i].ncached_max * sizeof(void *); + /* + * avail points past the available space. Allocations will + * access the slots toward higher addresses (for the benefit of + * prefetch). + */ + tcache->tbins[i].avail = (void **)((uintptr_t)tcache + + (uintptr_t)stack_offset); + } + + return (tcache); +} + +static void +tcache_destroy(tsd_t *tsd, tcache_t *tcache) +{ + arena_t *arena; + unsigned i; + + arena = arena_choose(tsd, NULL); + tcache_arena_dissociate(tsd_tsdn(tsd), tcache, arena); + + for (i = 0; i < NBINS; i++) { + tcache_bin_t *tbin = &tcache->tbins[i]; + tcache_bin_flush_small(tsd, tcache, tbin, i, 0); + + if (config_stats && tbin->tstats.nrequests != 0) { + arena_bin_t *bin = &arena->bins[i]; + malloc_mutex_lock(tsd_tsdn(tsd), &bin->lock); + bin->stats.nrequests += tbin->tstats.nrequests; + malloc_mutex_unlock(tsd_tsdn(tsd), &bin->lock); + } + } + + for (; i < nhbins; i++) { + tcache_bin_t *tbin = &tcache->tbins[i]; + tcache_bin_flush_large(tsd, tbin, i, 0, tcache); + + if (config_stats && tbin->tstats.nrequests != 0) { + malloc_mutex_lock(tsd_tsdn(tsd), &arena->lock); + arena->stats.nrequests_large += tbin->tstats.nrequests; + arena->stats.lstats[i - NBINS].nrequests += + tbin->tstats.nrequests; + malloc_mutex_unlock(tsd_tsdn(tsd), &arena->lock); + } + } + + if (config_prof && tcache->prof_accumbytes > 0 && + arena_prof_accum(tsd_tsdn(tsd), arena, tcache->prof_accumbytes)) + prof_idump(tsd_tsdn(tsd)); + + idalloctm(tsd_tsdn(tsd), tcache, NULL, true, true); +} + +void +tcache_cleanup(tsd_t *tsd) +{ + tcache_t *tcache; + + if (!config_tcache) + return; + + if ((tcache = tsd_tcache_get(tsd)) != NULL) { + tcache_destroy(tsd, tcache); + tsd_tcache_set(tsd, NULL); + } +} + +void +tcache_enabled_cleanup(tsd_t *tsd) +{ + + /* Do nothing. */ +} + +void +tcache_stats_merge(tsdn_t *tsdn, tcache_t *tcache, arena_t *arena) +{ + unsigned i; + + cassert(config_stats); + + malloc_mutex_assert_owner(tsdn, &arena->lock); + + /* Merge and reset tcache stats. */ + for (i = 0; i < NBINS; i++) { + arena_bin_t *bin = &arena->bins[i]; + tcache_bin_t *tbin = &tcache->tbins[i]; + malloc_mutex_lock(tsdn, &bin->lock); + bin->stats.nrequests += tbin->tstats.nrequests; + malloc_mutex_unlock(tsdn, &bin->lock); + tbin->tstats.nrequests = 0; + } + + for (; i < nhbins; i++) { + malloc_large_stats_t *lstats = &arena->stats.lstats[i - NBINS]; + tcache_bin_t *tbin = &tcache->tbins[i]; + arena->stats.nrequests_large += tbin->tstats.nrequests; + lstats->nrequests += tbin->tstats.nrequests; + tbin->tstats.nrequests = 0; + } +} + +bool +tcaches_create(tsdn_t *tsdn, unsigned *r_ind) +{ + arena_t *arena; + tcache_t *tcache; + tcaches_t *elm; + + if (tcaches == NULL) { + tcaches = base_alloc(tsdn, sizeof(tcache_t *) * + (MALLOCX_TCACHE_MAX+1)); + if (tcaches == NULL) + return (true); + } + + if (tcaches_avail == NULL && tcaches_past > MALLOCX_TCACHE_MAX) + return (true); + arena = arena_ichoose(tsdn, NULL); + if (unlikely(arena == NULL)) + return (true); + tcache = tcache_create(tsdn, arena); + if (tcache == NULL) + return (true); + + if (tcaches_avail != NULL) { + elm = tcaches_avail; + tcaches_avail = tcaches_avail->next; + elm->tcache = tcache; + *r_ind = (unsigned)(elm - tcaches); + } else { + elm = &tcaches[tcaches_past]; + elm->tcache = tcache; + *r_ind = tcaches_past; + tcaches_past++; + } + + return (false); +} + +static void +tcaches_elm_flush(tsd_t *tsd, tcaches_t *elm) +{ + + if (elm->tcache == NULL) + return; + tcache_destroy(tsd, elm->tcache); + elm->tcache = NULL; +} + +void +tcaches_flush(tsd_t *tsd, unsigned ind) +{ + + tcaches_elm_flush(tsd, &tcaches[ind]); +} + +void +tcaches_destroy(tsd_t *tsd, unsigned ind) +{ + tcaches_t *elm = &tcaches[ind]; + tcaches_elm_flush(tsd, elm); + elm->next = tcaches_avail; + tcaches_avail = elm; +} + +bool +tcache_boot(tsdn_t *tsdn) +{ + unsigned i; + + /* + * If necessary, clamp opt_lg_tcache_max, now that large_maxclass is + * known. + */ + if (opt_lg_tcache_max < 0 || (1U << opt_lg_tcache_max) < SMALL_MAXCLASS) + tcache_maxclass = SMALL_MAXCLASS; + else if ((1U << opt_lg_tcache_max) > large_maxclass) + tcache_maxclass = large_maxclass; + else + tcache_maxclass = (1U << opt_lg_tcache_max); + + nhbins = size2index(tcache_maxclass) + 1; + + /* Initialize tcache_bin_info. */ + tcache_bin_info = (tcache_bin_info_t *)base_alloc(tsdn, nhbins * + sizeof(tcache_bin_info_t)); + if (tcache_bin_info == NULL) + return (true); + stack_nelms = 0; + for (i = 0; i < NBINS; i++) { + if ((arena_bin_info[i].nregs << 1) <= TCACHE_NSLOTS_SMALL_MIN) { + tcache_bin_info[i].ncached_max = + TCACHE_NSLOTS_SMALL_MIN; + } else if ((arena_bin_info[i].nregs << 1) <= + TCACHE_NSLOTS_SMALL_MAX) { + tcache_bin_info[i].ncached_max = + (arena_bin_info[i].nregs << 1); + } else { + tcache_bin_info[i].ncached_max = + TCACHE_NSLOTS_SMALL_MAX; + } + stack_nelms += tcache_bin_info[i].ncached_max; + } + for (; i < nhbins; i++) { + tcache_bin_info[i].ncached_max = TCACHE_NSLOTS_LARGE; + stack_nelms += tcache_bin_info[i].ncached_max; + } + + return (false); +} diff --git a/contrib/jemalloc/src/ticker.c b/contrib/jemalloc/src/ticker.c new file mode 100644 index 0000000..db09024 --- /dev/null +++ b/contrib/jemalloc/src/ticker.c @@ -0,0 +1,2 @@ +#define JEMALLOC_TICKER_C_ +#include "jemalloc/internal/jemalloc_internal.h" diff --git a/contrib/jemalloc/src/tsd.c b/contrib/jemalloc/src/tsd.c new file mode 100644 index 0000000..aeaa5e1 --- /dev/null +++ b/contrib/jemalloc/src/tsd.c @@ -0,0 +1,197 @@ +#define JEMALLOC_TSD_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +static unsigned ncleanups; +static malloc_tsd_cleanup_t cleanups[MALLOC_TSD_CLEANUPS_MAX]; + +malloc_tsd_data(, , tsd_t, TSD_INITIALIZER) + +/******************************************************************************/ + +void * +malloc_tsd_malloc(size_t size) +{ + + return (a0malloc(CACHELINE_CEILING(size))); +} + +void +malloc_tsd_dalloc(void *wrapper) +{ + + a0dalloc(wrapper); +} + +void +malloc_tsd_no_cleanup(void *arg) +{ + + not_reached(); +} + +#if defined(JEMALLOC_MALLOC_THREAD_CLEANUP) || defined(_WIN32) +#ifndef _WIN32 +JEMALLOC_EXPORT +#endif +void +_malloc_thread_cleanup(void) +{ + bool pending[MALLOC_TSD_CLEANUPS_MAX], again; + unsigned i; + + for (i = 0; i < ncleanups; i++) + pending[i] = true; + + do { + again = false; + for (i = 0; i < ncleanups; i++) { + if (pending[i]) { + pending[i] = cleanups[i](); + if (pending[i]) + again = true; + } + } + } while (again); +} +#endif + +void +malloc_tsd_cleanup_register(bool (*f)(void)) +{ + + assert(ncleanups < MALLOC_TSD_CLEANUPS_MAX); + cleanups[ncleanups] = f; + ncleanups++; +} + +void +tsd_cleanup(void *arg) +{ + tsd_t *tsd = (tsd_t *)arg; + + switch (tsd->state) { + case tsd_state_uninitialized: + /* Do nothing. */ + break; + case tsd_state_nominal: +#define O(n, t) \ + n##_cleanup(tsd); +MALLOC_TSD +#undef O + tsd->state = tsd_state_purgatory; + tsd_set(tsd); + break; + case tsd_state_purgatory: + /* + * The previous time this destructor was called, we set the + * state to tsd_state_purgatory so that other destructors + * wouldn't cause re-creation of the tsd. This time, do + * nothing, and do not request another callback. + */ + break; + case tsd_state_reincarnated: + /* + * Another destructor deallocated memory after this destructor + * was called. Reset state to tsd_state_purgatory and request + * another callback. + */ + tsd->state = tsd_state_purgatory; + tsd_set(tsd); + break; + default: + not_reached(); + } +} + +tsd_t * +malloc_tsd_boot0(void) +{ + tsd_t *tsd; + + ncleanups = 0; + if (tsd_boot0()) + return (NULL); + tsd = tsd_fetch(); + *tsd_arenas_tdata_bypassp_get(tsd) = true; + return (tsd); +} + +void +malloc_tsd_boot1(void) +{ + + tsd_boot1(); + *tsd_arenas_tdata_bypassp_get(tsd_fetch()) = false; +} + +#ifdef _WIN32 +static BOOL WINAPI +_tls_callback(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + + switch (fdwReason) { +#ifdef JEMALLOC_LAZY_LOCK + case DLL_THREAD_ATTACH: + isthreaded = true; + break; +#endif + case DLL_THREAD_DETACH: + _malloc_thread_cleanup(); + break; + default: + break; + } + return (true); +} + +#ifdef _MSC_VER +# ifdef _M_IX86 +# pragma comment(linker, "/INCLUDE:__tls_used") +# pragma comment(linker, "/INCLUDE:_tls_callback") +# else +# pragma comment(linker, "/INCLUDE:_tls_used") +# pragma comment(linker, "/INCLUDE:tls_callback") +# endif +# pragma section(".CRT$XLY",long,read) +#endif +JEMALLOC_SECTION(".CRT$XLY") JEMALLOC_ATTR(used) +BOOL (WINAPI *const tls_callback)(HINSTANCE hinstDLL, + DWORD fdwReason, LPVOID lpvReserved) = _tls_callback; +#endif + +#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \ + !defined(_WIN32)) +void * +tsd_init_check_recursion(tsd_init_head_t *head, tsd_init_block_t *block) +{ + pthread_t self = pthread_self(); + tsd_init_block_t *iter; + + /* Check whether this thread has already inserted into the list. */ + malloc_mutex_lock(NULL, &head->lock); + ql_foreach(iter, &head->blocks, link) { + if (iter->thread == self) { + malloc_mutex_unlock(NULL, &head->lock); + return (iter->data); + } + } + /* Insert block into list. */ + ql_elm_new(block, link); + block->thread = self; + ql_tail_insert(&head->blocks, block, link); + malloc_mutex_unlock(NULL, &head->lock); + return (NULL); +} + +void +tsd_init_finish(tsd_init_head_t *head, tsd_init_block_t *block) +{ + + malloc_mutex_lock(NULL, &head->lock); + ql_remove(&head->blocks, block, link); + malloc_mutex_unlock(NULL, &head->lock); +} +#endif diff --git a/contrib/jemalloc/src/util.c b/contrib/jemalloc/src/util.c new file mode 100644 index 0000000..04f9153 --- /dev/null +++ b/contrib/jemalloc/src/util.c @@ -0,0 +1,682 @@ +/* + * Define simple versions of assertion macros that won't recurse in case + * of assertion failures in malloc_*printf(). + */ +#define assert(e) do { \ + if (config_debug && !(e)) { \ + malloc_write(": Failed assertion\n"); \ + abort(); \ + } \ +} while (0) + +#define not_reached() do { \ + if (config_debug) { \ + malloc_write(": Unreachable code reached\n"); \ + abort(); \ + } \ + unreachable(); \ +} while (0) + +#define not_implemented() do { \ + if (config_debug) { \ + malloc_write(": Not implemented\n"); \ + abort(); \ + } \ +} while (0) + +#define JEMALLOC_UTIL_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Function prototypes for non-inline static functions. */ + +static void wrtmessage(void *cbopaque, const char *s); +#define U2S_BUFSIZE ((1U << (LG_SIZEOF_INTMAX_T + 3)) + 1) +static char *u2s(uintmax_t x, unsigned base, bool uppercase, char *s, + size_t *slen_p); +#define D2S_BUFSIZE (1 + U2S_BUFSIZE) +static char *d2s(intmax_t x, char sign, char *s, size_t *slen_p); +#define O2S_BUFSIZE (1 + U2S_BUFSIZE) +static char *o2s(uintmax_t x, bool alt_form, char *s, size_t *slen_p); +#define X2S_BUFSIZE (2 + U2S_BUFSIZE) +static char *x2s(uintmax_t x, bool alt_form, bool uppercase, char *s, + size_t *slen_p); + +/******************************************************************************/ + +/* malloc_message() setup. */ +static void +wrtmessage(void *cbopaque, const char *s) +{ + +#ifdef SYS_write + /* + * Use syscall(2) rather than write(2) when possible in order to avoid + * the possibility of memory allocation within libc. This is necessary + * on FreeBSD; most operating systems do not have this problem though. + * + * syscall() returns long or int, depending on platform, so capture the + * unused result in the widest plausible type to avoid compiler + * warnings. + */ + UNUSED long result = syscall(SYS_write, STDERR_FILENO, s, strlen(s)); +#else + UNUSED ssize_t result = write(STDERR_FILENO, s, strlen(s)); +#endif +} + +JEMALLOC_EXPORT void (*je_malloc_message)(void *, const char *s); + +JEMALLOC_ATTR(visibility("hidden")) +void +wrtmessage_1_0(const char *s1, const char *s2, const char *s3, + const char *s4) +{ + + wrtmessage(NULL, s1); + wrtmessage(NULL, s2); + wrtmessage(NULL, s3); + wrtmessage(NULL, s4); +} + +void (*__malloc_message_1_0)(const char *s1, const char *s2, const char *s3, + const char *s4) = wrtmessage_1_0; +__sym_compat(_malloc_message, __malloc_message_1_0, FBSD_1.0); + +/* + * Wrapper around malloc_message() that avoids the need for + * je_malloc_message(...) throughout the code. + */ +void +malloc_write(const char *s) +{ + + if (je_malloc_message != NULL) + je_malloc_message(NULL, s); + else + wrtmessage(NULL, s); +} + +/* + * glibc provides a non-standard strerror_r() when _GNU_SOURCE is defined, so + * provide a wrapper. + */ +int +buferror(int err, char *buf, size_t buflen) +{ + +#ifdef _WIN32 + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, + (LPSTR)buf, (DWORD)buflen, NULL); + return (0); +#elif defined(__GLIBC__) && defined(_GNU_SOURCE) + char *b = strerror_r(err, buf, buflen); + if (b != buf) { + strncpy(buf, b, buflen); + buf[buflen-1] = '\0'; + } + return (0); +#else + return (strerror_r(err, buf, buflen)); +#endif +} + +uintmax_t +malloc_strtoumax(const char *restrict nptr, char **restrict endptr, int base) +{ + uintmax_t ret, digit; + unsigned b; + bool neg; + const char *p, *ns; + + p = nptr; + if (base < 0 || base == 1 || base > 36) { + ns = p; + set_errno(EINVAL); + ret = UINTMAX_MAX; + goto label_return; + } + b = base; + + /* Swallow leading whitespace and get sign, if any. */ + neg = false; + while (true) { + switch (*p) { + case '\t': case '\n': case '\v': case '\f': case '\r': case ' ': + p++; + break; + case '-': + neg = true; + /* Fall through. */ + case '+': + p++; + /* Fall through. */ + default: + goto label_prefix; + } + } + + /* Get prefix, if any. */ + label_prefix: + /* + * Note where the first non-whitespace/sign character is so that it is + * possible to tell whether any digits are consumed (e.g., " 0" vs. + * " -x"). + */ + ns = p; + if (*p == '0') { + switch (p[1]) { + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': + if (b == 0) + b = 8; + if (b == 8) + p++; + break; + case 'X': case 'x': + switch (p[2]) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': + if (b == 0) + b = 16; + if (b == 16) + p += 2; + break; + default: + break; + } + break; + default: + p++; + ret = 0; + goto label_return; + } + } + if (b == 0) + b = 10; + + /* Convert. */ + ret = 0; + while ((*p >= '0' && *p <= '9' && (digit = *p - '0') < b) + || (*p >= 'A' && *p <= 'Z' && (digit = 10 + *p - 'A') < b) + || (*p >= 'a' && *p <= 'z' && (digit = 10 + *p - 'a') < b)) { + uintmax_t pret = ret; + ret *= b; + ret += digit; + if (ret < pret) { + /* Overflow. */ + set_errno(ERANGE); + ret = UINTMAX_MAX; + goto label_return; + } + p++; + } + if (neg) + ret = -ret; + + if (p == ns) { + /* No conversion performed. */ + set_errno(EINVAL); + ret = UINTMAX_MAX; + goto label_return; + } + +label_return: + if (endptr != NULL) { + if (p == ns) { + /* No characters were converted. */ + *endptr = (char *)nptr; + } else + *endptr = (char *)p; + } + return (ret); +} + +static char * +u2s(uintmax_t x, unsigned base, bool uppercase, char *s, size_t *slen_p) +{ + unsigned i; + + i = U2S_BUFSIZE - 1; + s[i] = '\0'; + switch (base) { + case 10: + do { + i--; + s[i] = "0123456789"[x % (uint64_t)10]; + x /= (uint64_t)10; + } while (x > 0); + break; + case 16: { + const char *digits = (uppercase) + ? "0123456789ABCDEF" + : "0123456789abcdef"; + + do { + i--; + s[i] = digits[x & 0xf]; + x >>= 4; + } while (x > 0); + break; + } default: { + const char *digits = (uppercase) + ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + : "0123456789abcdefghijklmnopqrstuvwxyz"; + + assert(base >= 2 && base <= 36); + do { + i--; + s[i] = digits[x % (uint64_t)base]; + x /= (uint64_t)base; + } while (x > 0); + }} + + *slen_p = U2S_BUFSIZE - 1 - i; + return (&s[i]); +} + +static char * +d2s(intmax_t x, char sign, char *s, size_t *slen_p) +{ + bool neg; + + if ((neg = (x < 0))) + x = -x; + s = u2s(x, 10, false, s, slen_p); + if (neg) + sign = '-'; + switch (sign) { + case '-': + if (!neg) + break; + /* Fall through. */ + case ' ': + case '+': + s--; + (*slen_p)++; + *s = sign; + break; + default: not_reached(); + } + return (s); +} + +static char * +o2s(uintmax_t x, bool alt_form, char *s, size_t *slen_p) +{ + + s = u2s(x, 8, false, s, slen_p); + if (alt_form && *s != '0') { + s--; + (*slen_p)++; + *s = '0'; + } + return (s); +} + +static char * +x2s(uintmax_t x, bool alt_form, bool uppercase, char *s, size_t *slen_p) +{ + + s = u2s(x, 16, uppercase, s, slen_p); + if (alt_form) { + s -= 2; + (*slen_p) += 2; + memcpy(s, uppercase ? "0X" : "0x", 2); + } + return (s); +} + +size_t +malloc_vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + size_t i; + const char *f; + +#define APPEND_C(c) do { \ + if (i < size) \ + str[i] = (c); \ + i++; \ +} while (0) +#define APPEND_S(s, slen) do { \ + if (i < size) { \ + size_t cpylen = (slen <= size - i) ? slen : size - i; \ + memcpy(&str[i], s, cpylen); \ + } \ + i += slen; \ +} while (0) +#define APPEND_PADDED_S(s, slen, width, left_justify) do { \ + /* Left padding. */ \ + size_t pad_len = (width == -1) ? 0 : ((slen < (size_t)width) ? \ + (size_t)width - slen : 0); \ + if (!left_justify && pad_len != 0) { \ + size_t j; \ + for (j = 0; j < pad_len; j++) \ + APPEND_C(' '); \ + } \ + /* Value. */ \ + APPEND_S(s, slen); \ + /* Right padding. */ \ + if (left_justify && pad_len != 0) { \ + size_t j; \ + for (j = 0; j < pad_len; j++) \ + APPEND_C(' '); \ + } \ +} while (0) +#define GET_ARG_NUMERIC(val, len) do { \ + switch (len) { \ + case '?': \ + val = va_arg(ap, int); \ + break; \ + case '?' | 0x80: \ + val = va_arg(ap, unsigned int); \ + break; \ + case 'l': \ + val = va_arg(ap, long); \ + break; \ + case 'l' | 0x80: \ + val = va_arg(ap, unsigned long); \ + break; \ + case 'q': \ + val = va_arg(ap, long long); \ + break; \ + case 'q' | 0x80: \ + val = va_arg(ap, unsigned long long); \ + break; \ + case 'j': \ + val = va_arg(ap, intmax_t); \ + break; \ + case 'j' | 0x80: \ + val = va_arg(ap, uintmax_t); \ + break; \ + case 't': \ + val = va_arg(ap, ptrdiff_t); \ + break; \ + case 'z': \ + val = va_arg(ap, ssize_t); \ + break; \ + case 'z' | 0x80: \ + val = va_arg(ap, size_t); \ + break; \ + case 'p': /* Synthetic; used for %p. */ \ + val = va_arg(ap, uintptr_t); \ + break; \ + default: \ + not_reached(); \ + val = 0; \ + } \ +} while (0) + + i = 0; + f = format; + while (true) { + switch (*f) { + case '\0': goto label_out; + case '%': { + bool alt_form = false; + bool left_justify = false; + bool plus_space = false; + bool plus_plus = false; + int prec = -1; + int width = -1; + unsigned char len = '?'; + char *s; + size_t slen; + + f++; + /* Flags. */ + while (true) { + switch (*f) { + case '#': + assert(!alt_form); + alt_form = true; + break; + case '-': + assert(!left_justify); + left_justify = true; + break; + case ' ': + assert(!plus_space); + plus_space = true; + break; + case '+': + assert(!plus_plus); + plus_plus = true; + break; + default: goto label_width; + } + f++; + } + /* Width. */ + label_width: + switch (*f) { + case '*': + width = va_arg(ap, int); + f++; + if (width < 0) { + left_justify = true; + width = -width; + } + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + uintmax_t uwidth; + set_errno(0); + uwidth = malloc_strtoumax(f, (char **)&f, 10); + assert(uwidth != UINTMAX_MAX || get_errno() != + ERANGE); + width = (int)uwidth; + break; + } default: + break; + } + /* Width/precision separator. */ + if (*f == '.') + f++; + else + goto label_length; + /* Precision. */ + switch (*f) { + case '*': + prec = va_arg(ap, int); + f++; + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + uintmax_t uprec; + set_errno(0); + uprec = malloc_strtoumax(f, (char **)&f, 10); + assert(uprec != UINTMAX_MAX || get_errno() != + ERANGE); + prec = (int)uprec; + break; + } + default: break; + } + /* Length. */ + label_length: + switch (*f) { + case 'l': + f++; + if (*f == 'l') { + len = 'q'; + f++; + } else + len = 'l'; + break; + case 'q': case 'j': case 't': case 'z': + len = *f; + f++; + break; + default: break; + } + /* Conversion specifier. */ + switch (*f) { + case '%': + /* %% */ + APPEND_C(*f); + f++; + break; + case 'd': case 'i': { + intmax_t val JEMALLOC_CC_SILENCE_INIT(0); + char buf[D2S_BUFSIZE]; + + GET_ARG_NUMERIC(val, len); + s = d2s(val, (plus_plus ? '+' : (plus_space ? + ' ' : '-')), buf, &slen); + APPEND_PADDED_S(s, slen, width, left_justify); + f++; + break; + } case 'o': { + uintmax_t val JEMALLOC_CC_SILENCE_INIT(0); + char buf[O2S_BUFSIZE]; + + GET_ARG_NUMERIC(val, len | 0x80); + s = o2s(val, alt_form, buf, &slen); + APPEND_PADDED_S(s, slen, width, left_justify); + f++; + break; + } case 'u': { + uintmax_t val JEMALLOC_CC_SILENCE_INIT(0); + char buf[U2S_BUFSIZE]; + + GET_ARG_NUMERIC(val, len | 0x80); + s = u2s(val, 10, false, buf, &slen); + APPEND_PADDED_S(s, slen, width, left_justify); + f++; + break; + } case 'x': case 'X': { + uintmax_t val JEMALLOC_CC_SILENCE_INIT(0); + char buf[X2S_BUFSIZE]; + + GET_ARG_NUMERIC(val, len | 0x80); + s = x2s(val, alt_form, *f == 'X', buf, &slen); + APPEND_PADDED_S(s, slen, width, left_justify); + f++; + break; + } case 'c': { + unsigned char val; + char buf[2]; + + assert(len == '?' || len == 'l'); + assert_not_implemented(len != 'l'); + val = va_arg(ap, int); + buf[0] = val; + buf[1] = '\0'; + APPEND_PADDED_S(buf, 1, width, left_justify); + f++; + break; + } case 's': + assert(len == '?' || len == 'l'); + assert_not_implemented(len != 'l'); + s = va_arg(ap, char *); + slen = (prec < 0) ? strlen(s) : (size_t)prec; + APPEND_PADDED_S(s, slen, width, left_justify); + f++; + break; + case 'p': { + uintmax_t val; + char buf[X2S_BUFSIZE]; + + GET_ARG_NUMERIC(val, 'p'); + s = x2s(val, true, false, buf, &slen); + APPEND_PADDED_S(s, slen, width, left_justify); + f++; + break; + } default: not_reached(); + } + break; + } default: { + APPEND_C(*f); + f++; + break; + }} + } + label_out: + if (i < size) + str[i] = '\0'; + else + str[size - 1] = '\0'; + +#undef APPEND_C +#undef APPEND_S +#undef APPEND_PADDED_S +#undef GET_ARG_NUMERIC + return (i); +} + +JEMALLOC_FORMAT_PRINTF(3, 4) +size_t +malloc_snprintf(char *str, size_t size, const char *format, ...) +{ + size_t ret; + va_list ap; + + va_start(ap, format); + ret = malloc_vsnprintf(str, size, format, ap); + va_end(ap); + + return (ret); +} + +void +malloc_vcprintf(void (*write_cb)(void *, const char *), void *cbopaque, + const char *format, va_list ap) +{ + char buf[MALLOC_PRINTF_BUFSIZE]; + + if (write_cb == NULL) { + /* + * The caller did not provide an alternate write_cb callback + * function, so use the default one. malloc_write() is an + * inline function, so use malloc_message() directly here. + */ + write_cb = (je_malloc_message != NULL) ? je_malloc_message : + wrtmessage; + cbopaque = NULL; + } + + malloc_vsnprintf(buf, sizeof(buf), format, ap); + write_cb(cbopaque, buf); +} + +/* + * Print to a callback function in such a way as to (hopefully) avoid memory + * allocation. + */ +JEMALLOC_FORMAT_PRINTF(3, 4) +void +malloc_cprintf(void (*write_cb)(void *, const char *), void *cbopaque, + const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + malloc_vcprintf(write_cb, cbopaque, format, ap); + va_end(ap); +} + +/* Print to stderr in such a way as to avoid memory allocation. */ +JEMALLOC_FORMAT_PRINTF(1, 2) +void +malloc_printf(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + malloc_vcprintf(NULL, NULL, format, ap); + va_end(ap); +} + +/* + * Restore normal assertion macros, in order to make it possible to compile all + * C files as a single concatenation. + */ +#undef assert +#undef not_reached +#undef not_implemented +#include "jemalloc/internal/assert.h" diff --git a/contrib/jemalloc/src/witness.c b/contrib/jemalloc/src/witness.c new file mode 100644 index 0000000..23753f2 --- /dev/null +++ b/contrib/jemalloc/src/witness.c @@ -0,0 +1,136 @@ +#define JEMALLOC_WITNESS_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +void +witness_init(witness_t *witness, const char *name, witness_rank_t rank, + witness_comp_t *comp) +{ + + witness->name = name; + witness->rank = rank; + witness->comp = comp; +} + +#ifdef JEMALLOC_JET +#undef witness_lock_error +#define witness_lock_error JEMALLOC_N(n_witness_lock_error) +#endif +void +witness_lock_error(const witness_list_t *witnesses, const witness_t *witness) +{ + witness_t *w; + + malloc_printf(": Lock rank order reversal:"); + ql_foreach(w, witnesses, link) { + malloc_printf(" %s(%u)", w->name, w->rank); + } + malloc_printf(" %s(%u)\n", witness->name, witness->rank); + abort(); +} +#ifdef JEMALLOC_JET +#undef witness_lock_error +#define witness_lock_error JEMALLOC_N(witness_lock_error) +witness_lock_error_t *witness_lock_error = JEMALLOC_N(n_witness_lock_error); +#endif + +#ifdef JEMALLOC_JET +#undef witness_owner_error +#define witness_owner_error JEMALLOC_N(n_witness_owner_error) +#endif +void +witness_owner_error(const witness_t *witness) +{ + + malloc_printf(": Should own %s(%u)\n", witness->name, + witness->rank); + abort(); +} +#ifdef JEMALLOC_JET +#undef witness_owner_error +#define witness_owner_error JEMALLOC_N(witness_owner_error) +witness_owner_error_t *witness_owner_error = JEMALLOC_N(n_witness_owner_error); +#endif + +#ifdef JEMALLOC_JET +#undef witness_not_owner_error +#define witness_not_owner_error JEMALLOC_N(n_witness_not_owner_error) +#endif +void +witness_not_owner_error(const witness_t *witness) +{ + + malloc_printf(": Should not own %s(%u)\n", witness->name, + witness->rank); + abort(); +} +#ifdef JEMALLOC_JET +#undef witness_not_owner_error +#define witness_not_owner_error JEMALLOC_N(witness_not_owner_error) +witness_not_owner_error_t *witness_not_owner_error = + JEMALLOC_N(n_witness_not_owner_error); +#endif + +#ifdef JEMALLOC_JET +#undef witness_lockless_error +#define witness_lockless_error JEMALLOC_N(n_witness_lockless_error) +#endif +void +witness_lockless_error(const witness_list_t *witnesses) +{ + witness_t *w; + + malloc_printf(": Should not own any locks:"); + ql_foreach(w, witnesses, link) { + malloc_printf(" %s(%u)", w->name, w->rank); + } + malloc_printf("\n"); + abort(); +} +#ifdef JEMALLOC_JET +#undef witness_lockless_error +#define witness_lockless_error JEMALLOC_N(witness_lockless_error) +witness_lockless_error_t *witness_lockless_error = + JEMALLOC_N(n_witness_lockless_error); +#endif + +void +witnesses_cleanup(tsd_t *tsd) +{ + + witness_assert_lockless(tsd_tsdn(tsd)); + + /* Do nothing. */ +} + +void +witness_fork_cleanup(tsd_t *tsd) +{ + + /* Do nothing. */ +} + +void +witness_prefork(tsd_t *tsd) +{ + + tsd_witness_fork_set(tsd, true); +} + +void +witness_postfork_parent(tsd_t *tsd) +{ + + tsd_witness_fork_set(tsd, false); +} + +void +witness_postfork_child(tsd_t *tsd) +{ +#ifndef JEMALLOC_MUTEX_INIT_CB + witness_list_t *witnesses; + + witnesses = tsd_witnessesp_get(tsd); + ql_new(witnesses); +#endif + tsd_witness_fork_set(tsd, false); +} diff --git a/contrib/libc-pwcache/pwcache.c b/contrib/libc-pwcache/pwcache.c new file mode 100644 index 0000000..ac7fcb0 --- /dev/null +++ b/contrib/libc-pwcache/pwcache.c @@ -0,0 +1,646 @@ +/* $NetBSD: pwcache.c,v 1.31 2010/03/23 20:28:59 drochner Exp $ */ + +/*- + * Copyright (c) 1992 Keith Muller. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Keith Muller of the University of California, San Diego. + * + * 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. + */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +/* + * XXX Undefine the renames of these functions so that we don't + * XXX rename the versions found in the host's by mistake! + */ +#undef group_from_gid +#undef user_from_uid +#endif + +#include +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)cache.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: pwcache.c,v 1.31 2010/03/23 20:28:59 drochner Exp $"); +#endif +#endif /* LIBC_SCCS and not lint */ +__FBSDID("$FreeBSD: releng/11.1/contrib/libc-pwcache/pwcache.c 241731 2012-10-19 12:44:22Z brooks $"); + +#include "namespace.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define _DIAGASSERT(x) assert((x)) + +#if HAVE_NBTOOL_CONFIG_H +/* XXX Now, re-apply the renaming that we undid above. */ +#define group_from_gid __nbcompat_group_from_gid +#define user_from_uid __nbcompat_user_from_uid +#endif + +#ifdef __weak_alias +__weak_alias(user_from_uid,_user_from_uid) +__weak_alias(group_from_gid,_group_from_gid) +__weak_alias(pwcache_groupdb,_pwcache_groupdb) +#endif + +#if !HAVE_PWCACHE_USERDB || HAVE_NBTOOL_CONFIG_H +#include "pwcache.h" + +/* + * routines that control user, group, uid and gid caches (for the archive + * member print routine). + * IMPORTANT: + * these routines cache BOTH hits and misses, a major performance improvement + */ + +/* + * function pointers to various name lookup routines. + * these may be changed as necessary. + */ +static int (*_pwcache_setgroupent)(int) = setgroupent; +static void (*_pwcache_endgrent)(void) = endgrent; +static struct group * (*_pwcache_getgrnam)(const char *) = getgrnam; +static struct group * (*_pwcache_getgrgid)(gid_t) = getgrgid; +static int (*_pwcache_setpassent)(int) = setpassent; +static void (*_pwcache_endpwent)(void) = endpwent; +static struct passwd * (*_pwcache_getpwnam)(const char *) = getpwnam; +static struct passwd * (*_pwcache_getpwuid)(uid_t) = getpwuid; + +/* + * internal state + */ +static int pwopn; /* is password file open */ +static int gropn; /* is group file open */ +static UIDC **uidtb; /* uid to name cache */ +static GIDC **gidtb; /* gid to name cache */ +static UIDC **usrtb; /* user name to uid cache */ +static GIDC **grptb; /* group name to gid cache */ + +static int uidtb_fail; /* uidtb_start() failed ? */ +static int gidtb_fail; /* gidtb_start() failed ? */ +static int usrtb_fail; /* usrtb_start() failed ? */ +static int grptb_fail; /* grptb_start() failed ? */ + + +static u_int st_hash(const char *, size_t, int); +static int uidtb_start(void); +static int gidtb_start(void); +static int usrtb_start(void); +static int grptb_start(void); + + +static u_int +st_hash(const char *name, size_t len, int tabsz) +{ + u_int key = 0; + + _DIAGASSERT(name != NULL); + + while (len--) { + key += *name++; + key = (key << 8) | (key >> 24); + } + + return (key % tabsz); +} + +/* + * uidtb_start + * creates an an empty uidtb + * Return: + * 0 if ok, -1 otherwise + */ +static int +uidtb_start(void) +{ + + if (uidtb != NULL) + return (0); + if (uidtb_fail) + return (-1); + if ((uidtb = (UIDC **)calloc(UID_SZ, sizeof(UIDC *))) == NULL) { + ++uidtb_fail; + return (-1); + } + return (0); +} + +/* + * gidtb_start + * creates an an empty gidtb + * Return: + * 0 if ok, -1 otherwise + */ +static int +gidtb_start(void) +{ + + if (gidtb != NULL) + return (0); + if (gidtb_fail) + return (-1); + if ((gidtb = (GIDC **)calloc(GID_SZ, sizeof(GIDC *))) == NULL) { + ++gidtb_fail; + return (-1); + } + return (0); +} + +/* + * usrtb_start + * creates an an empty usrtb + * Return: + * 0 if ok, -1 otherwise + */ +static int +usrtb_start(void) +{ + + if (usrtb != NULL) + return (0); + if (usrtb_fail) + return (-1); + if ((usrtb = (UIDC **)calloc(UNM_SZ, sizeof(UIDC *))) == NULL) { + ++usrtb_fail; + return (-1); + } + return (0); +} + +/* + * grptb_start + * creates an an empty grptb + * Return: + * 0 if ok, -1 otherwise + */ +static int +grptb_start(void) +{ + + if (grptb != NULL) + return (0); + if (grptb_fail) + return (-1); + if ((grptb = (GIDC **)calloc(GNM_SZ, sizeof(GIDC *))) == NULL) { + ++grptb_fail; + return (-1); + } + return (0); +} + +/* + * user_from_uid() + * caches the name (if any) for the uid. If noname clear, we always + * return the stored name (if valid or invalid match). + * We use a simple hash table. + * Return + * Pointer to stored name (or a empty string) + */ +const char * +user_from_uid(uid_t uid, int noname) +{ + struct passwd *pw; + UIDC *ptr, **pptr; + + if ((uidtb == NULL) && (uidtb_start() < 0)) + return (NULL); + + /* + * see if we have this uid cached + */ + pptr = uidtb + (uid % UID_SZ); + ptr = *pptr; + + if ((ptr != NULL) && (ptr->valid > 0) && (ptr->uid == uid)) { + /* + * have an entry for this uid + */ + if (!noname || (ptr->valid == VALID)) + return (ptr->name); + return (NULL); + } + + /* + * No entry for this uid, we will add it + */ + if (!pwopn) { + if (_pwcache_setpassent != NULL) + (*_pwcache_setpassent)(1); + ++pwopn; + } + + if (ptr == NULL) + *pptr = ptr = (UIDC *)malloc(sizeof(UIDC)); + + if ((pw = (*_pwcache_getpwuid)(uid)) == NULL) { + /* + * no match for this uid in the local password file + * a string that is the uid in numeric format + */ + if (ptr == NULL) + return (NULL); + ptr->uid = uid; + (void)snprintf(ptr->name, UNMLEN, "%lu", (long) uid); + ptr->valid = INVALID; + if (noname) + return (NULL); + } else { + /* + * there is an entry for this uid in the password file + */ + if (ptr == NULL) + return (pw->pw_name); + ptr->uid = uid; + (void)strlcpy(ptr->name, pw->pw_name, UNMLEN); + ptr->valid = VALID; + } + return (ptr->name); +} + +/* + * group_from_gid() + * caches the name (if any) for the gid. If noname clear, we always + * return the stored name (if valid or invalid match). + * We use a simple hash table. + * Return + * Pointer to stored name (or a empty string) + */ +const char * +group_from_gid(gid_t gid, int noname) +{ + struct group *gr; + GIDC *ptr, **pptr; + + if ((gidtb == NULL) && (gidtb_start() < 0)) + return (NULL); + + /* + * see if we have this gid cached + */ + pptr = gidtb + (gid % GID_SZ); + ptr = *pptr; + + if ((ptr != NULL) && (ptr->valid > 0) && (ptr->gid == gid)) { + /* + * have an entry for this gid + */ + if (!noname || (ptr->valid == VALID)) + return (ptr->name); + return (NULL); + } + + /* + * No entry for this gid, we will add it + */ + if (!gropn) { + if (_pwcache_setgroupent != NULL) + (*_pwcache_setgroupent)(1); + ++gropn; + } + + if (ptr == NULL) + *pptr = ptr = (GIDC *)malloc(sizeof(GIDC)); + + if ((gr = (*_pwcache_getgrgid)(gid)) == NULL) { + /* + * no match for this gid in the local group file, put in + * a string that is the gid in numberic format + */ + if (ptr == NULL) + return (NULL); + ptr->gid = gid; + (void)snprintf(ptr->name, GNMLEN, "%lu", (long) gid); + ptr->valid = INVALID; + if (noname) + return (NULL); + } else { + /* + * there is an entry for this group in the group file + */ + if (ptr == NULL) + return (gr->gr_name); + ptr->gid = gid; + (void)strlcpy(ptr->name, gr->gr_name, GNMLEN); + ptr->valid = VALID; + } + return (ptr->name); +} + +/* + * uid_from_user() + * caches the uid for a given user name. We use a simple hash table. + * Return + * the uid (if any) for a user name, or a -1 if no match can be found + */ +int +uid_from_user(const char *name, uid_t *uid) +{ + struct passwd *pw; + UIDC *ptr, **pptr; + size_t namelen; + + /* + * return -1 for mangled names + */ + if (name == NULL || ((namelen = strlen(name)) == 0)) + return (-1); + if ((usrtb == NULL) && (usrtb_start() < 0)) + return (-1); + + /* + * look up in hash table, if found and valid return the uid, + * if found and invalid, return a -1 + */ + pptr = usrtb + st_hash(name, namelen, UNM_SZ); + ptr = *pptr; + + if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) { + if (ptr->valid == INVALID) + return (-1); + *uid = ptr->uid; + return (0); + } + + if (!pwopn) { + if (_pwcache_setpassent != NULL) + (*_pwcache_setpassent)(1); + ++pwopn; + } + + if (ptr == NULL) + *pptr = ptr = (UIDC *)malloc(sizeof(UIDC)); + + /* + * no match, look it up, if no match store it as an invalid entry, + * or store the matching uid + */ + if (ptr == NULL) { + if ((pw = (*_pwcache_getpwnam)(name)) == NULL) + return (-1); + *uid = pw->pw_uid; + return (0); + } + (void)strlcpy(ptr->name, name, UNMLEN); + if ((pw = (*_pwcache_getpwnam)(name)) == NULL) { + ptr->valid = INVALID; + return (-1); + } + ptr->valid = VALID; + *uid = ptr->uid = pw->pw_uid; + return (0); +} + +/* + * gid_from_group() + * caches the gid for a given group name. We use a simple hash table. + * Return + * the gid (if any) for a group name, or a -1 if no match can be found + */ +int +gid_from_group(const char *name, gid_t *gid) +{ + struct group *gr; + GIDC *ptr, **pptr; + size_t namelen; + + /* + * return -1 for mangled names + */ + if (name == NULL || ((namelen = strlen(name)) == 0)) + return (-1); + if ((grptb == NULL) && (grptb_start() < 0)) + return (-1); + + /* + * look up in hash table, if found and valid return the uid, + * if found and invalid, return a -1 + */ + pptr = grptb + st_hash(name, namelen, GID_SZ); + ptr = *pptr; + + if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) { + if (ptr->valid == INVALID) + return (-1); + *gid = ptr->gid; + return (0); + } + + if (!gropn) { + if (_pwcache_setgroupent != NULL) + (*_pwcache_setgroupent)(1); + ++gropn; + } + + if (ptr == NULL) + *pptr = ptr = (GIDC *)malloc(sizeof(GIDC)); + + /* + * no match, look it up, if no match store it as an invalid entry, + * or store the matching gid + */ + if (ptr == NULL) { + if ((gr = (*_pwcache_getgrnam)(name)) == NULL) + return (-1); + *gid = gr->gr_gid; + return (0); + } + + (void)strlcpy(ptr->name, name, GNMLEN); + if ((gr = (*_pwcache_getgrnam)(name)) == NULL) { + ptr->valid = INVALID; + return (-1); + } + ptr->valid = VALID; + *gid = ptr->gid = gr->gr_gid; + return (0); +} + +#define FLUSHTB(arr, len, fail) \ + do { \ + if (arr != NULL) { \ + for (i = 0; i < len; i++) \ + if (arr[i] != NULL) \ + free(arr[i]); \ + arr = NULL; \ + } \ + fail = 0; \ + } while (/* CONSTCOND */0); + +int +pwcache_userdb( + int (*a_setpassent)(int), + void (*a_endpwent)(void), + struct passwd * (*a_getpwnam)(const char *), + struct passwd * (*a_getpwuid)(uid_t)) +{ + int i; + + /* a_setpassent and a_endpwent may be NULL */ + if (a_getpwnam == NULL || a_getpwuid == NULL) + return (-1); + + if (_pwcache_endpwent != NULL) + (*_pwcache_endpwent)(); + FLUSHTB(uidtb, UID_SZ, uidtb_fail); + FLUSHTB(usrtb, UNM_SZ, usrtb_fail); + pwopn = 0; + _pwcache_setpassent = a_setpassent; + _pwcache_endpwent = a_endpwent; + _pwcache_getpwnam = a_getpwnam; + _pwcache_getpwuid = a_getpwuid; + + return (0); +} + +int +pwcache_groupdb( + int (*a_setgroupent)(int), + void (*a_endgrent)(void), + struct group * (*a_getgrnam)(const char *), + struct group * (*a_getgrgid)(gid_t)) +{ + int i; + + /* a_setgroupent and a_endgrent may be NULL */ + if (a_getgrnam == NULL || a_getgrgid == NULL) + return (-1); + + if (_pwcache_endgrent != NULL) + (*_pwcache_endgrent)(); + FLUSHTB(gidtb, GID_SZ, gidtb_fail); + FLUSHTB(grptb, GNM_SZ, grptb_fail); + gropn = 0; + _pwcache_setgroupent = a_setgroupent; + _pwcache_endgrent = a_endgrent; + _pwcache_getgrnam = a_getgrnam; + _pwcache_getgrgid = a_getgrgid; + + return (0); +} + + +#ifdef TEST_PWCACHE + +struct passwd * +test_getpwnam(const char *name) +{ + static struct passwd foo; + + memset(&foo, 0, sizeof(foo)); + if (strcmp(name, "toor") == 0) { + foo.pw_uid = 666; + return &foo; + } + return (getpwnam(name)); +} + +int +main(int argc, char *argv[]) +{ + uid_t u; + int r, i; + + printf("pass 1 (default userdb)\n"); + for (i = 1; i < argc; i++) { + printf("i: %d, pwopn %d usrtb_fail %d usrtb %p\n", + i, pwopn, usrtb_fail, usrtb); + r = uid_from_user(argv[i], &u); + if (r == -1) + printf(" uid_from_user %s: failed\n", argv[i]); + else + printf(" uid_from_user %s: %d\n", argv[i], u); + } + printf("pass 1 finish: pwopn %d usrtb_fail %d usrtb %p\n", + pwopn, usrtb_fail, usrtb); + + puts(""); + printf("pass 2 (replacement userdb)\n"); + printf("pwcache_userdb returned %d\n", + pwcache_userdb(setpassent, test_getpwnam, getpwuid)); + printf("pwopn %d usrtb_fail %d usrtb %p\n", pwopn, usrtb_fail, usrtb); + + for (i = 1; i < argc; i++) { + printf("i: %d, pwopn %d usrtb_fail %d usrtb %p\n", + i, pwopn, usrtb_fail, usrtb); + u = -1; + r = uid_from_user(argv[i], &u); + if (r == -1) + printf(" uid_from_user %s: failed\n", argv[i]); + else + printf(" uid_from_user %s: %d\n", argv[i], u); + } + printf("pass 2 finish: pwopn %d usrtb_fail %d usrtb %p\n", + pwopn, usrtb_fail, usrtb); + + puts(""); + printf("pass 3 (null pointers)\n"); + printf("pwcache_userdb returned %d\n", + pwcache_userdb(NULL, NULL, NULL)); + + return (0); +} +#endif /* TEST_PWCACHE */ +#endif /* !HAVE_PWCACHE_USERDB */ diff --git a/contrib/libc-pwcache/pwcache.h b/contrib/libc-pwcache/pwcache.h new file mode 100644 index 0000000..a77ea95 --- /dev/null +++ b/contrib/libc-pwcache/pwcache.h @@ -0,0 +1,73 @@ +/* $NetBSD: pwcache.h,v 1.5 2003/11/10 08:51:51 wiz Exp $ */ +/* $FreeBSD: releng/11.1/contrib/libc-pwcache/pwcache.h 241731 2012-10-19 12:44:22Z brooks $ */ + +/*- + * Copyright (c) 1992 Keith Muller. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Keith Muller of the University of California, San Diego. + * + * 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. + * + * @(#)cache.h 8.1 (Berkeley) 5/31/93 + */ + +/* + * Constants and data structures used to implement group and password file + * caches. Traditional passwd/group cache routines perform quite poorly with + * archives. The chances of hitting a valid lookup with an archive is quite a + * bit worse than with files already resident on the file system. These misses + * create a MAJOR performance cost. To address this problem, these routines + * cache both hits and misses. + * + * NOTE: name lengths must be as large as those stored in ANY PROTOCOL and + * as stored in the passwd and group files. CACHE SIZES MUST BE PRIME + */ +#define UNMLEN 32 /* >= user name found in any protocol */ +#define GNMLEN 32 /* >= group name found in any protocol */ +#define UID_SZ 317 /* size of uid to user_name cache */ +#define UNM_SZ 317 /* size of user_name to uid cache */ +#define GID_SZ 251 /* size of gid to group_name cache */ +#define GNM_SZ 251 /* size of group_name to gid cache */ +#define VALID 1 /* entry and name are valid */ +#define INVALID 2 /* entry valid, name NOT valid */ + +/* + * Node structures used in the user, group, uid, and gid caches. + */ + +typedef struct uidc { + int valid; /* is this a valid or a miss entry */ + char name[UNMLEN]; /* uid name */ + uid_t uid; /* cached uid */ +} UIDC; + +typedef struct gidc { + int valid; /* is this a valid or a miss entry */ + char name[GNMLEN]; /* gid name */ + gid_t gid; /* cached gid */ +} GIDC; diff --git a/contrib/libc-vis/unvis.3 b/contrib/libc-vis/unvis.3 new file mode 100644 index 0000000..2280724 --- /dev/null +++ b/contrib/libc-vis/unvis.3 @@ -0,0 +1,262 @@ +.\" $NetBSD: unvis.3,v 1.27 2012/12/15 07:34:36 wiz Exp $ +.\" $FreeBSD: releng/11.1/contrib/libc-vis/unvis.3 248302 2013-03-14 23:51:47Z brooks $ +.\" +.\" Copyright (c) 1989, 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. +.\" +.\" @(#)unvis.3 8.2 (Berkeley) 12/11/93 +.\" +.Dd March 12, 2011 +.Dt UNVIS 3 +.Os +.Sh NAME +.Nm unvis , +.Nm strunvis +.Nd decode a visual representation of characters +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In vis.h +.Ft int +.Fn unvis "char *cp" "int c" "int *astate" "int flag" +.Ft int +.Fn strunvis "char *dst" "const char *src" +.Ft int +.Fn strnunvis "char *dst" "size_t dlen" "const char *src" +.Ft int +.Fn strunvisx "char *dst" "const char *src" "int flag" +.Ft int +.Fn strnunvisx "char *dst" "size_t dlen" "const char *src" "int flag" +.Sh DESCRIPTION +The +.Fn unvis , +.Fn strunvis +and +.Fn strunvisx +functions +are used to decode a visual representation of characters, as produced +by the +.Xr vis 3 +function, back into +the original form. +.Pp +The +.Fn unvis +function is called with successive characters in +.Ar c +until a valid sequence is recognized, at which time the decoded +character is available at the character pointed to by +.Ar cp . +.Pp +The +.Fn strunvis +function decodes the characters pointed to by +.Ar src +into the buffer pointed to by +.Ar dst . +The +.Fn strunvis +function simply copies +.Ar src +to +.Ar dst , +decoding any escape sequences along the way, +and returns the number of characters placed into +.Ar dst , +or \-1 if an +invalid escape sequence was detected. +The size of +.Ar dst +should be equal to the size of +.Ar src +(that is, no expansion takes place during decoding). +.Pp +The +.Fn strunvisx +function does the same as the +.Fn strunvis +function, +but it allows you to add a flag that specifies the style the string +.Ar src +is encoded with. +Currently, the supported flags are: +.Dv VIS_HTTPSTYLE +and +.Dv VIS_MIMESTYLE . +.Pp +The +.Fn unvis +function implements a state machine that can be used to decode an +arbitrary stream of bytes. +All state associated with the bytes being decoded is stored outside the +.Fn unvis +function (that is, a pointer to the state is passed in), so +calls decoding different streams can be freely intermixed. +To start decoding a stream of bytes, first initialize an integer to zero. +Call +.Fn unvis +with each successive byte, along with a pointer +to this integer, and a pointer to a destination character. +The +.Fn unvis +function has several return codes that must be handled properly. +They are: +.Bl -tag -width UNVIS_VALIDPUSH +.It Li \&0 No (zero) +Another character is necessary; nothing has been recognized yet. +.It Dv UNVIS_VALID +A valid character has been recognized and is available at the location +pointed to by +.Fa cp . +.It Dv UNVIS_VALIDPUSH +A valid character has been recognized and is available at the location +pointed to by +.Fa cp ; +however, the character currently passed in should be passed in again. +.It Dv UNVIS_NOCHAR +A valid sequence was detected, but no character was produced. +This return code is necessary to indicate a logical break between characters. +.It Dv UNVIS_SYNBAD +An invalid escape sequence was detected, or the decoder is in an unknown state. +The decoder is placed into the starting state. +.El +.Pp +When all bytes in the stream have been processed, call +.Fn unvis +one more time with flag set to +.Dv UNVIS_END +to extract any remaining character (the character passed in is ignored). +.Pp +The +.Fa flag +argument is also used to specify the encoding style of the source. +If set to +.Dv VIS_HTTPSTYLE +or +.Dv VIS_HTTP1808 , +.Fn unvis +will decode URI strings as specified in RFC 1808. +If set to +.Dv VIS_HTTP1866 , +.Fn unvis +will decode entity references and numeric character references +as specified in RFC 1866. +If set to +.Dv VIS_MIMESTYLE , +.Fn unvis +will decode MIME Quoted-Printable strings as specified in RFC 2045. +If set to +.Dv VIS_NOESCAPE , +.Fn unvis +will not decode +.Ql \e +quoted characters. +.Pp +The following code fragment illustrates a proper use of +.Fn unvis . +.Bd -literal -offset indent +int state = 0; +char out; + +while ((ch = getchar()) != EOF) { +again: + switch(unvis(\*[Am]out, ch, \*[Am]state, 0)) { + case 0: + case UNVIS_NOCHAR: + break; + case UNVIS_VALID: + (void)putchar(out); + break; + case UNVIS_VALIDPUSH: + (void)putchar(out); + goto again; + case UNVIS_SYNBAD: + errx(EXIT_FAILURE, "Bad character sequence!"); + } +} +if (unvis(\*[Am]out, '\e0', \*[Am]state, UNVIS_END) == UNVIS_VALID) + (void)putchar(out); +.Ed +.Sh ERRORS +The functions +.Fn strunvis , +.Fn strnunvis , +.Fn strunvisx , +and +.Fn strnunvisx +will return \-1 on error and set +.Va errno +to: +.Bl -tag -width Er +.It Bq Er EINVAL +An invalid escape sequence was detected, or the decoder is in an unknown state. +.El +.Pp +In addition the functions +.Fn strnunvis +and +.Fn strnunvisx +will can also set +.Va errno +on error to: +.Bl -tag -width Er +.It Bq Er ENOSPC +Not enough space to perform the conversion. +.El +.Sh SEE ALSO +.Xr unvis 1 , +.Xr vis 1 , +.Xr vis 3 +.Rs +.%A R. Fielding +.%T Relative Uniform Resource Locators +.%O RFC1808 +.Re +.Sh HISTORY +The +.Fn unvis +function +first appeared in +.Bx 4.4 . +The +.Fn strnunvis +and +.Fn strnunvisx +functions appeared in +.Nx 6.0 +and +.Fx 9.2 . +.Sh BUGS +The names +.Dv VIS_HTTP1808 +and +.Dv VIS_HTTP1866 +are wrong. +Percent-encoding was defined in RFC 1738, the original RFC for URL. +RFC 1866 defines HTML 2.0, an application of SGML, from which it +inherits concepts of numeric character references and entity +references. diff --git a/contrib/libc-vis/unvis.c b/contrib/libc-vis/unvis.c new file mode 100644 index 0000000..5a0c3d3 --- /dev/null +++ b/contrib/libc-vis/unvis.c @@ -0,0 +1,568 @@ +/* $NetBSD: unvis.c,v 1.44 2014/09/26 15:43:36 roy 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 +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: unvis.c,v 1.44 2014/09/26 15:43:36 roy Exp $"); +#endif +#endif /* LIBC_SCCS and not lint */ +__FBSDID("$FreeBSD: releng/11.1/contrib/libc-vis/unvis.c 301679 2016-06-08 18:21:27Z brooks $"); + +#include "namespace.h" +#include + +#include +#include +#include +#include +#include +#include + +#define _DIAGASSERT(x) assert(x) + +/* + * Return the number of elements in a statically-allocated array, + * __x. + */ +#define __arraycount(__x) (sizeof(__x) / sizeof(__x[0])) + +#ifdef __weak_alias +__weak_alias(strnunvisx,_strnunvisx) +#endif + +#if !HAVE_VIS +/* + * 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 S_HEX 7 /* mandatory hex digit */ +#define S_HEX1 8 /* http hex digit */ +#define S_HEX2 9 /* http hex digit 2 */ +#define S_MIME1 10 /* mime hex digit 1 */ +#define S_MIME2 11 /* mime hex digit 2 */ +#define S_EATCRNL 12 /* mime eating CRNL */ +#define S_AMP 13 /* seen & */ +#define S_NUMBER 14 /* collecting number */ +#define S_STRING 15 /* collecting string */ + +#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') +#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) +#define XTOD(c) (isdigit(c) ? (c - '0') : ((c - 'A') + 10)) + +/* + * RFC 1866 + */ +static const struct nv { + char name[7]; + uint8_t value; +} nv[] = { + { "AElig", 198 }, /* capital AE diphthong (ligature) */ + { "Aacute", 193 }, /* capital A, acute accent */ + { "Acirc", 194 }, /* capital A, circumflex accent */ + { "Agrave", 192 }, /* capital A, grave accent */ + { "Aring", 197 }, /* capital A, ring */ + { "Atilde", 195 }, /* capital A, tilde */ + { "Auml", 196 }, /* capital A, dieresis or umlaut mark */ + { "Ccedil", 199 }, /* capital C, cedilla */ + { "ETH", 208 }, /* capital Eth, Icelandic */ + { "Eacute", 201 }, /* capital E, acute accent */ + { "Ecirc", 202 }, /* capital E, circumflex accent */ + { "Egrave", 200 }, /* capital E, grave accent */ + { "Euml", 203 }, /* capital E, dieresis or umlaut mark */ + { "Iacute", 205 }, /* capital I, acute accent */ + { "Icirc", 206 }, /* capital I, circumflex accent */ + { "Igrave", 204 }, /* capital I, grave accent */ + { "Iuml", 207 }, /* capital I, dieresis or umlaut mark */ + { "Ntilde", 209 }, /* capital N, tilde */ + { "Oacute", 211 }, /* capital O, acute accent */ + { "Ocirc", 212 }, /* capital O, circumflex accent */ + { "Ograve", 210 }, /* capital O, grave accent */ + { "Oslash", 216 }, /* capital O, slash */ + { "Otilde", 213 }, /* capital O, tilde */ + { "Ouml", 214 }, /* capital O, dieresis or umlaut mark */ + { "THORN", 222 }, /* capital THORN, Icelandic */ + { "Uacute", 218 }, /* capital U, acute accent */ + { "Ucirc", 219 }, /* capital U, circumflex accent */ + { "Ugrave", 217 }, /* capital U, grave accent */ + { "Uuml", 220 }, /* capital U, dieresis or umlaut mark */ + { "Yacute", 221 }, /* capital Y, acute accent */ + { "aacute", 225 }, /* small a, acute accent */ + { "acirc", 226 }, /* small a, circumflex accent */ + { "acute", 180 }, /* acute accent */ + { "aelig", 230 }, /* small ae diphthong (ligature) */ + { "agrave", 224 }, /* small a, grave accent */ + { "amp", 38 }, /* ampersand */ + { "aring", 229 }, /* small a, ring */ + { "atilde", 227 }, /* small a, tilde */ + { "auml", 228 }, /* small a, dieresis or umlaut mark */ + { "brvbar", 166 }, /* broken (vertical) bar */ + { "ccedil", 231 }, /* small c, cedilla */ + { "cedil", 184 }, /* cedilla */ + { "cent", 162 }, /* cent sign */ + { "copy", 169 }, /* copyright sign */ + { "curren", 164 }, /* general currency sign */ + { "deg", 176 }, /* degree sign */ + { "divide", 247 }, /* divide sign */ + { "eacute", 233 }, /* small e, acute accent */ + { "ecirc", 234 }, /* small e, circumflex accent */ + { "egrave", 232 }, /* small e, grave accent */ + { "eth", 240 }, /* small eth, Icelandic */ + { "euml", 235 }, /* small e, dieresis or umlaut mark */ + { "frac12", 189 }, /* fraction one-half */ + { "frac14", 188 }, /* fraction one-quarter */ + { "frac34", 190 }, /* fraction three-quarters */ + { "gt", 62 }, /* greater than */ + { "iacute", 237 }, /* small i, acute accent */ + { "icirc", 238 }, /* small i, circumflex accent */ + { "iexcl", 161 }, /* inverted exclamation mark */ + { "igrave", 236 }, /* small i, grave accent */ + { "iquest", 191 }, /* inverted question mark */ + { "iuml", 239 }, /* small i, dieresis or umlaut mark */ + { "laquo", 171 }, /* angle quotation mark, left */ + { "lt", 60 }, /* less than */ + { "macr", 175 }, /* macron */ + { "micro", 181 }, /* micro sign */ + { "middot", 183 }, /* middle dot */ + { "nbsp", 160 }, /* no-break space */ + { "not", 172 }, /* not sign */ + { "ntilde", 241 }, /* small n, tilde */ + { "oacute", 243 }, /* small o, acute accent */ + { "ocirc", 244 }, /* small o, circumflex accent */ + { "ograve", 242 }, /* small o, grave accent */ + { "ordf", 170 }, /* ordinal indicator, feminine */ + { "ordm", 186 }, /* ordinal indicator, masculine */ + { "oslash", 248 }, /* small o, slash */ + { "otilde", 245 }, /* small o, tilde */ + { "ouml", 246 }, /* small o, dieresis or umlaut mark */ + { "para", 182 }, /* pilcrow (paragraph sign) */ + { "plusmn", 177 }, /* plus-or-minus sign */ + { "pound", 163 }, /* pound sterling sign */ + { "quot", 34 }, /* double quote */ + { "raquo", 187 }, /* angle quotation mark, right */ + { "reg", 174 }, /* registered sign */ + { "sect", 167 }, /* section sign */ + { "shy", 173 }, /* soft hyphen */ + { "sup1", 185 }, /* superscript one */ + { "sup2", 178 }, /* superscript two */ + { "sup3", 179 }, /* superscript three */ + { "szlig", 223 }, /* small sharp s, German (sz ligature) */ + { "thorn", 254 }, /* small thorn, Icelandic */ + { "times", 215 }, /* multiply sign */ + { "uacute", 250 }, /* small u, acute accent */ + { "ucirc", 251 }, /* small u, circumflex accent */ + { "ugrave", 249 }, /* small u, grave accent */ + { "uml", 168 }, /* umlaut (dieresis) */ + { "uuml", 252 }, /* small u, dieresis or umlaut mark */ + { "yacute", 253 }, /* small y, acute accent */ + { "yen", 165 }, /* yen sign */ + { "yuml", 255 }, /* small y, dieresis or umlaut mark */ +}; + +/* + * unvis - decode characters previously encoded by vis + */ +int +unvis(char *cp, int c, int *astate, int flag) +{ + unsigned char uc = (unsigned char)c; + unsigned char st, ia, is, lc; + +/* + * Bottom 8 bits of astate hold the state machine state. + * Top 8 bits hold the current character in the http 1866 nv string decoding + */ +#define GS(a) ((a) & 0xff) +#define SS(a, b) (((uint32_t)(a) << 24) | (b)) +#define GI(a) ((uint32_t)(a) >> 24) + + _DIAGASSERT(cp != NULL); + _DIAGASSERT(astate != NULL); + st = GS(*astate); + + if (flag & UNVIS_END) { + switch (st) { + case S_OCTAL2: + case S_OCTAL3: + case S_HEX2: + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case S_GROUND: + return UNVIS_NOCHAR; + default: + return UNVIS_SYNBAD; + } + } + + switch (st) { + + case S_GROUND: + *cp = 0; + if ((flag & VIS_NOESCAPE) == 0 && c == '\\') { + *astate = SS(0, S_START); + return UNVIS_NOCHAR; + } + if ((flag & VIS_HTTP1808) && c == '%') { + *astate = SS(0, S_HEX1); + return UNVIS_NOCHAR; + } + if ((flag & VIS_HTTP1866) && c == '&') { + *astate = SS(0, S_AMP); + return UNVIS_NOCHAR; + } + if ((flag & VIS_MIMESTYLE) && c == '=') { + *astate = SS(0, S_MIME1); + return UNVIS_NOCHAR; + } + *cp = c; + return UNVIS_VALID; + + case S_START: + switch(c) { + case '\\': + *cp = c; + *astate = SS(0, 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 = SS(0, S_OCTAL2); + return UNVIS_NOCHAR; + case 'M': + *cp = (char)0200; + *astate = SS(0, S_META); + return UNVIS_NOCHAR; + case '^': + *astate = SS(0, S_CTRL); + return UNVIS_NOCHAR; + case 'n': + *cp = '\n'; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case 'r': + *cp = '\r'; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case 'b': + *cp = '\b'; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case 'a': + *cp = '\007'; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case 'v': + *cp = '\v'; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case 't': + *cp = '\t'; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case 'f': + *cp = '\f'; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case 's': + *cp = ' '; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case 'E': + *cp = '\033'; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case 'x': + *astate = SS(0, S_HEX); + return UNVIS_NOCHAR; + case '\n': + /* + * hidden newline + */ + *astate = SS(0, S_GROUND); + return UNVIS_NOCHAR; + case '$': + /* + * hidden marker + */ + *astate = SS(0, S_GROUND); + return UNVIS_NOCHAR; + default: + if (isgraph(c)) { + *cp = c; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + } + } + goto bad; + + case S_META: + if (c == '-') + *astate = SS(0, S_META1); + else if (c == '^') + *astate = SS(0, S_CTRL); + else + goto bad; + return UNVIS_NOCHAR; + + case S_META1: + *astate = SS(0, S_GROUND); + *cp |= c; + return UNVIS_VALID; + + case S_CTRL: + if (c == '?') + *cp |= 0177; + else + *cp |= c & 037; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + + case S_OCTAL2: /* second possible octal digit */ + if (isoctal(uc)) { + /* + * yes - and maybe a third + */ + *cp = (*cp << 3) + (c - '0'); + *astate = SS(0, S_OCTAL3); + return UNVIS_NOCHAR; + } + /* + * no - done with current sequence, push back passed char + */ + *astate = SS(0, S_GROUND); + return UNVIS_VALIDPUSH; + + case S_OCTAL3: /* third possible octal digit */ + *astate = SS(0, S_GROUND); + if (isoctal(uc)) { + *cp = (*cp << 3) + (c - '0'); + return UNVIS_VALID; + } + /* + * we were done, push back passed char + */ + return UNVIS_VALIDPUSH; + + case S_HEX: + if (!isxdigit(uc)) + goto bad; + /*FALLTHROUGH*/ + case S_HEX1: + if (isxdigit(uc)) { + *cp = xtod(uc); + *astate = SS(0, S_HEX2); + return UNVIS_NOCHAR; + } + /* + * no - done with current sequence, push back passed char + */ + *astate = SS(0, S_GROUND); + return UNVIS_VALIDPUSH; + + case S_HEX2: + *astate = S_GROUND; + if (isxdigit(uc)) { + *cp = xtod(uc) | (*cp << 4); + return UNVIS_VALID; + } + return UNVIS_VALIDPUSH; + + case S_MIME1: + if (uc == '\n' || uc == '\r') { + *astate = SS(0, S_EATCRNL); + return UNVIS_NOCHAR; + } + if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) { + *cp = XTOD(uc); + *astate = SS(0, S_MIME2); + return UNVIS_NOCHAR; + } + goto bad; + + case S_MIME2: + if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) { + *astate = SS(0, S_GROUND); + *cp = XTOD(uc) | (*cp << 4); + return UNVIS_VALID; + } + goto bad; + + case S_EATCRNL: + switch (uc) { + case '\r': + case '\n': + return UNVIS_NOCHAR; + case '=': + *astate = SS(0, S_MIME1); + return UNVIS_NOCHAR; + default: + *cp = uc; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + } + + case S_AMP: + *cp = 0; + if (uc == '#') { + *astate = SS(0, S_NUMBER); + return UNVIS_NOCHAR; + } + *astate = SS(0, S_STRING); + /*FALLTHROUGH*/ + + case S_STRING: + ia = *cp; /* index in the array */ + is = GI(*astate); /* index in the string */ + lc = is == 0 ? 0 : nv[ia].name[is - 1]; /* last character */ + + if (uc == ';') + uc = '\0'; + + for (; ia < __arraycount(nv); ia++) { + if (is != 0 && nv[ia].name[is - 1] != lc) + goto bad; + if (nv[ia].name[is] == uc) + break; + } + + if (ia == __arraycount(nv)) + goto bad; + + if (uc != 0) { + *cp = ia; + *astate = SS(is + 1, S_STRING); + return UNVIS_NOCHAR; + } + + *cp = nv[ia].value; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + + case S_NUMBER: + if (uc == ';') + return UNVIS_VALID; + if (!isdigit(uc)) + goto bad; + *cp += (*cp * 10) + uc - '0'; + return UNVIS_NOCHAR; + + default: + bad: + /* + * decoder in unknown state - (probably uninitialized) + */ + *astate = SS(0, S_GROUND); + return UNVIS_SYNBAD; + } +} + +/* + * strnunvisx - decode src into dst + * + * Number of chars decoded into dst is returned, -1 on error. + * Dst is null terminated. + */ + +int +strnunvisx(char *dst, size_t dlen, const char *src, int flag) +{ + char c; + char t = '\0', *start = dst; + int state = 0; + + _DIAGASSERT(src != NULL); + _DIAGASSERT(dst != NULL); +#define CHECKSPACE() \ + do { \ + if (dlen-- == 0) { \ + errno = ENOSPC; \ + return -1; \ + } \ + } while (/*CONSTCOND*/0) + + while ((c = *src++) != '\0') { + again: + switch (unvis(&t, c, &state, flag)) { + case UNVIS_VALID: + CHECKSPACE(); + *dst++ = t; + break; + case UNVIS_VALIDPUSH: + CHECKSPACE(); + *dst++ = t; + goto again; + case 0: + case UNVIS_NOCHAR: + break; + case UNVIS_SYNBAD: + errno = EINVAL; + return -1; + default: + _DIAGASSERT(/*CONSTCOND*/0); + errno = EINVAL; + return -1; + } + } + if (unvis(&t, c, &state, UNVIS_END) == UNVIS_VALID) { + CHECKSPACE(); + *dst++ = t; + } + CHECKSPACE(); + *dst = '\0'; + return (int)(dst - start); +} + +int +strunvisx(char *dst, const char *src, int flag) +{ + return strnunvisx(dst, (size_t)~0, src, flag); +} + +int +strunvis(char *dst, const char *src) +{ + return strnunvisx(dst, (size_t)~0, src, 0); +} + +int +strnunvis(char *dst, size_t dlen, const char *src) +{ + return strnunvisx(dst, dlen, src, 0); +} +#endif diff --git a/contrib/libc-vis/vis.3 b/contrib/libc-vis/vis.3 new file mode 100644 index 0000000..372bc1a --- /dev/null +++ b/contrib/libc-vis/vis.3 @@ -0,0 +1,550 @@ +.\" $NetBSD: vis.3,v 1.45 2016/06/08 15:00:04 wiz Exp $ +.\" $FreeBSD: releng/11.1/contrib/libc-vis/vis.3 301679 2016-06-08 18:21:27Z brooks $ +.\" +.\" Copyright (c) 1989, 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. +.\" +.\" @(#)vis.3 8.1 (Berkeley) 6/9/93 +.\" +.Dd January 14, 2015 +.Dt VIS 3 +.Os +.Sh NAME +.Nm vis , +.Nm nvis , +.Nm strvis , +.Nm stravis , +.Nm strnvis , +.Nm strvisx , +.Nm strnvisx , +.Nm strenvisx , +.Nm svis , +.Nm snvis , +.Nm strsvis , +.Nm strsnvis , +.Nm strsvisx , +.Nm strsnvisx , +.Nm strsenvisx +.Nd visually encode characters +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In vis.h +.Ft char * +.Fn vis "char *dst" "int c" "int flag" "int nextc" +.Ft char * +.Fn nvis "char *dst" "size_t dlen" "int c" "int flag" "int nextc" +.Ft int +.Fn strvis "char *dst" "const char *src" "int flag" +.Ft int +.Fn stravis "char **dst" "const char *src" "int flag" +.Ft int +.Fn strnvis "char *dst" "size_t dlen" "const char *src" "int flag" +.Ft int +.Fn strvisx "char *dst" "const char *src" "size_t len" "int flag" +.Ft int +.Fn strnvisx "char *dst" "size_t dlen" "const char *src" "size_t len" "int flag" +.Ft int +.Fn strenvisx "char *dst" "size_t dlen" "const char *src" "size_t len" "int flag" "int *cerr_ptr" +.Ft char * +.Fn svis "char *dst" "int c" "int flag" "int nextc" "const char *extra" +.Ft char * +.Fn snvis "char *dst" "size_t dlen" "int c" "int flag" "int nextc" "const char *extra" +.Ft int +.Fn strsvis "char *dst" "const char *src" "int flag" "const char *extra" +.Ft int +.Fn strsnvis "char *dst" "size_t dlen" "const char *src" "int flag" "const char *extra" +.Ft int +.Fn strsvisx "char *dst" "const char *src" "size_t len" "int flag" "const char *extra" +.Ft int +.Fn strsnvisx "char *dst" "size_t dlen" "const char *src" "size_t len" "int flag" "const char *extra" +.Ft int +.Fn strsenvisx "char *dst" "size_t dlen" "const char *src" "size_t len" "int flag" "const char *extra" "int *cerr_ptr" +.Sh DESCRIPTION +The +.Fn vis +function +copies into +.Fa dst +a string which represents the character +.Fa c . +If +.Fa c +needs no encoding, it is copied in unaltered. +The string is null terminated, and a pointer to the end of the string is +returned. +The maximum length of any encoding is four +bytes (not including the trailing +.Dv NUL ) ; +thus, when +encoding a set of characters into a buffer, the size of the buffer should +be four times the number of bytes encoded, plus one for the trailing +.Dv NUL . +The flag parameter is used for altering the default range of +characters considered for encoding and for altering the visual +representation. +The additional character, +.Fa nextc , +is only used when selecting the +.Dv VIS_CSTYLE +encoding format (explained below). +.Pp +The +.Fn strvis , +.Fn stravis , +.Fn strnvis , +.Fn strvisx , +and +.Fn strnvisx +functions copy into +.Fa dst +a visual representation of +the string +.Fa src . +The +.Fn strvis +and +.Fn strnvis +functions encode characters from +.Fa src +up to the +first +.Dv NUL . +The +.Fn strvisx +and +.Fn strnvisx +functions encode exactly +.Fa len +characters from +.Fa src +(this +is useful for encoding a block of data that may contain +.Dv NUL Ns 's ) . +Both forms +.Dv NUL +terminate +.Fa dst . +The size of +.Fa dst +must be four times the number +of bytes encoded from +.Fa src +(plus one for the +.Dv NUL ) . +Both +forms return the number of characters in +.Fa dst +(not including the trailing +.Dv NUL ) . +The +.Fn stravis +function allocates space dynamically to hold the string. +The +.Dq Nm n +versions of the functions also take an additional argument +.Fa dlen +that indicates the length of the +.Fa dst +buffer. +If +.Fa dlen +is not large enough to fit the converted string then the +.Fn strnvis +and +.Fn strnvisx +functions return \-1 and set +.Va errno +to +.Dv ENOSPC . +The +.Fn strenvisx +function takes an additional argument, +.Fa cerr_ptr , +that is used to pass in and out a multibyte conversion error flag. +This is useful when processing single characters at a time when +it is possible that the locale may be set to something other +than the locale of the characters in the input data. +.Pp +The functions +.Fn svis , +.Fn snvis , +.Fn strsvis , +.Fn strsnvis , +.Fn strsvisx , +.Fn strsnvisx , +and +.Fn strsenvisx +correspond to +.Fn vis , +.Fn nvis , +.Fn strvis , +.Fn strnvis , +.Fn strvisx , +.Fn strnvisx , +and +.Fn strenvisx +but have an additional argument +.Fa extra , +pointing to a +.Dv NUL +terminated list of characters. +These characters will be copied encoded or backslash-escaped into +.Fa dst . +These functions are useful e.g. to remove the special meaning +of certain characters to shells. +.Pp +The encoding is a unique, invertible representation composed entirely of +graphic characters; it can be decoded back into the original form using +the +.Xr unvis 3 , +.Xr strunvis 3 +or +.Xr strnunvis 3 +functions. +.Pp +There are two parameters that can be controlled: the range of +characters that are encoded (applies only to +.Fn vis , +.Fn nvis , +.Fn strvis , +.Fn strnvis , +.Fn strvisx , +and +.Fn strnvisx ) , +and the type of representation used. +By default, all non-graphic characters, +except space, tab, and newline are encoded (see +.Xr isgraph 3 ) . +The following flags +alter this: +.Bl -tag -width VIS_WHITEX +.It Dv VIS_GLOB +Also encode the magic characters +.Ql ( * , +.Ql \&? , +.Ql \&[ , +and +.Ql # ) +recognized by +.Xr glob 3 . +.It Dv VIS_SHELL +Also encode the meta characters used by shells (in addition to the glob +characters): +.Ql ( ' , +.Ql ` , +.Ql \&" , +.Ql \&; , +.Ql & , +.Ql < , +.Ql > , +.Ql \&( , +.Ql \&) , +.Ql \&| , +.Ql \&] , +.Ql \e , +.Ql $ , +.Ql \&! , +.Ql \&^ , +and +.Ql ~ ) . +.It Dv VIS_SP +Also encode space. +.It Dv VIS_TAB +Also encode tab. +.It Dv VIS_NL +Also encode newline. +.It Dv VIS_WHITE +Synonym for +.Dv VIS_SP | VIS_TAB | VIS_NL . +.It Dv VIS_META +Synonym for +.Dv VIS_WHITE | VIS_GLOB | VIS_SHELL . +.It Dv VIS_SAFE +Only encode +.Dq unsafe +characters. +Unsafe means control characters which may cause common terminals to perform +unexpected functions. +Currently this form allows space, tab, newline, backspace, bell, and +return \(em in addition to all graphic characters \(em unencoded. +.El +.Pp +(The above flags have no effect for +.Fn svis , +.Fn snvis , +.Fn strsvis , +.Fn strsnvis , +.Fn strsvisx , +and +.Fn strsnvisx . +When using these functions, place all graphic characters to be +encoded in an array pointed to by +.Fa extra . +In general, the backslash character should be included in this array, see the +warning on the use of the +.Dv VIS_NOSLASH +flag below). +.Pp +There are four forms of encoding. +All forms use the backslash character +.Ql \e +to introduce a special +sequence; two backslashes are used to represent a real backslash, +except +.Dv VIS_HTTPSTYLE +that uses +.Ql % , +or +.Dv VIS_MIMESTYLE +that uses +.Ql = . +These are the visual formats: +.Bl -tag -width VIS_CSTYLE +.It (default) +Use an +.Ql M +to represent meta characters (characters with the 8th +bit set), and use caret +.Ql ^ +to represent control characters (see +.Xr iscntrl 3 ) . +The following formats are used: +.Bl -tag -width xxxxx +.It Dv \e^C +Represents the control character +.Ql C . +Spans characters +.Ql \e000 +through +.Ql \e037 , +and +.Ql \e177 +(as +.Ql \e^? ) . +.It Dv \eM-C +Represents character +.Ql C +with the 8th bit set. +Spans characters +.Ql \e241 +through +.Ql \e376 . +.It Dv \eM^C +Represents control character +.Ql C +with the 8th bit set. +Spans characters +.Ql \e200 +through +.Ql \e237 , +and +.Ql \e377 +(as +.Ql \eM^? ) . +.It Dv \e040 +Represents +.Tn ASCII +space. +.It Dv \e240 +Represents Meta-space. +.El +.Pp +.It Dv VIS_CSTYLE +Use C-style backslash sequences to represent standard non-printable +characters. +The following sequences are used to represent the indicated characters: +.Bd -unfilled -offset indent +.Li \ea Tn \(em BEL No (007) +.Li \eb Tn \(em BS No (010) +.Li \ef Tn \(em NP No (014) +.Li \en Tn \(em NL No (012) +.Li \er Tn \(em CR No (015) +.Li \es Tn \(em SP No (040) +.Li \et Tn \(em HT No (011) +.Li \ev Tn \(em VT No (013) +.Li \e0 Tn \(em NUL No (000) +.Ed +.Pp +When using this format, the +.Fa nextc +parameter is looked at to determine if a +.Dv NUL +character can be encoded as +.Ql \e0 +instead of +.Ql \e000 . +If +.Fa nextc +is an octal digit, the latter representation is used to +avoid ambiguity. +.It Dv VIS_OCTAL +Use a three digit octal sequence. +The form is +.Ql \eddd +where +.Em d +represents an octal digit. +.It Dv VIS_HTTPSTYLE +Use URI encoding as described in RFC 1738. +The form is +.Ql %xx +where +.Em x +represents a lower case hexadecimal digit. +.It Dv VIS_MIMESTYLE +Use MIME Quoted-Printable encoding as described in RFC 2045, only don't +break lines and don't handle CRLF. +The form is +.Ql =XX +where +.Em X +represents an upper case hexadecimal digit. +.El +.Pp +There is one additional flag, +.Dv VIS_NOSLASH , +which inhibits the +doubling of backslashes and the backslash before the default +format (that is, control characters are represented by +.Ql ^C +and +meta characters as +.Ql M-C ) . +With this flag set, the encoding is +ambiguous and non-invertible. +.Sh MULTIBYTE CHARACTER SUPPORT +These functions support multibyte character input. +The encoding conversion is influenced by the setting of the +.Ev LC_CTYPE +environment variable which defines the set of characters +that can be copied without encoding. +.Pp +If +.Dv VIS_NOLOCALE +is set, processing is done assuming the C locale and overriding +any other environment settings. +.Pp +When 8-bit data is present in the input, +.Ev LC_CTYPE +must be set to the correct locale or to the C locale. +If the locales of the data and the conversion are mismatched, +multibyte character recognition may fail and encoding will be performed +byte-by-byte instead. +.Pp +As noted above, +.Fa dst +must be four times the number of bytes processed from +.Fa src . +But note that each multibyte character can be up to +.Dv MB_LEN_MAX +bytes +.\" (see +.\" .Xr multibyte 3 ) +so in terms of multibyte characters, +.Fa dst +must be four times +.Dv MB_LEN_MAX +times the number of characters processed from +.Fa src . +.Sh ENVIRONMENT +.Bl -tag -width ".Ev LC_CTYPE" +.It Ev LC_CTYPE +Specify the locale of the input data. +Set to C if the input data locale is unknown. +.El +.Sh ERRORS +The functions +.Fn nvis +and +.Fn snvis +will return +.Dv NULL +and the functions +.Fn strnvis , +.Fn strnvisx , +.Fn strsnvis , +and +.Fn strsnvisx , +will return \-1 when the +.Fa dlen +destination buffer size is not enough to perform the conversion while +setting +.Va errno +to: +.Bl -tag -width ".Bq Er ENOSPC" +.It Bq Er ENOSPC +The destination buffer size is not large enough to perform the conversion. +.El +.Sh SEE ALSO +.Xr unvis 1 , +.Xr vis 1 , +.Xr glob 3 , +.\" .Xr multibyte 3 , +.Xr unvis 3 +.Rs +.%A T. Berners-Lee +.%T Uniform Resource Locators (URL) +.%O "RFC 1738" +.Re +.Rs +.%T "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies" +.%O "RFC 2045" +.Re +.Sh HISTORY +The +.Fn vis , +.Fn strvis , +and +.Fn strvisx +functions first appeared in +.Bx 4.4 . +The +.Fn svis , +.Fn strsvis , +and +.Fn strsvisx +functions appeared in +.Nx 1.5 +and +.Fx 9.2 . +The buffer size limited versions of the functions +.Po Fn nvis , +.Fn strnvis , +.Fn strnvisx , +.Fn snvis , +.Fn strsnvis , +and +.Fn strsnvisx Pc +appeared in +.Nx 6.0 +and +.Fx 9.2 . +Multibyte character support was added in +.Nx 7.0 +and +.Fx 9.2 . diff --git a/contrib/libc-vis/vis.c b/contrib/libc-vis/vis.c new file mode 100644 index 0000000..a6b8b6d --- /dev/null +++ b/contrib/libc-vis/vis.c @@ -0,0 +1,766 @@ +/* $NetBSD: vis.c,v 1.71 2016/01/14 20:41:23 christos 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. + */ + +/*- + * Copyright (c) 1999, 2005 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: vis.c,v 1.71 2016/01/14 20:41:23 christos Exp $"); +#endif /* LIBC_SCCS and not lint */ +#ifdef __FBSDID +__FBSDID("$FreeBSD: releng/11.1/contrib/libc-vis/vis.c 314634 2017-03-03 21:43:03Z bdrewery $"); +#define _DIAGASSERT(x) assert(x) +#endif + +#include "namespace.h" +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef __weak_alias +__weak_alias(strvisx,_strvisx) +#endif + +#if !HAVE_VIS || !HAVE_SVIS +#include +#include +#include +#include + +/* + * The reason for going through the trouble to deal with character encodings + * in vis(3), is that we use this to safe encode output of commands. This + * safe encoding varies depending on the character set. For example if we + * display ps output in French, we don't want to display French characters + * as M-foo. + */ + +static wchar_t *do_svis(wchar_t *, wint_t, int, wint_t, const wchar_t *); + +#undef BELL +#define BELL L'\a' + +#if defined(LC_C_LOCALE) +#define iscgraph(c) isgraph_l(c, LC_C_LOCALE) +#else +/* Keep it simple for now, no locale stuff */ +#define iscgraph(c) isgraph(c) +#ifdef notyet +#include +static int +iscgraph(int c) { + int rv; + char *ol; + + ol = setlocale(LC_CTYPE, "C"); + rv = isgraph(c); + if (ol) + setlocale(LC_CTYPE, ol); + return rv; +} +#endif +#endif + +#define ISGRAPH(flags, c) \ + (((flags) & VIS_NOLOCALE) ? iscgraph(c) : iswgraph(c)) + +#define iswoctal(c) (((u_char)(c)) >= L'0' && ((u_char)(c)) <= L'7') +#define iswwhite(c) (c == L' ' || c == L'\t' || c == L'\n') +#define iswsafe(c) (c == L'\b' || c == BELL || c == L'\r') +#define xtoa(c) L"0123456789abcdef"[c] +#define XTOA(c) L"0123456789ABCDEF"[c] + +#define MAXEXTRAS 30 + +static const wchar_t char_shell[] = L"'`\";&<>()|{}]\\$!^~"; +static const wchar_t char_glob[] = L"*?[#"; + +#if !HAVE_NBTOOL_CONFIG_H +#ifndef __NetBSD__ +/* + * On NetBSD MB_LEN_MAX is currently 32 which does not fit on any integer + * integral type and it is probably wrong, since currently the maximum + * number of bytes and character needs is 6. Until this is fixed, the + * loops below are using sizeof(uint64_t) - 1 instead of MB_LEN_MAX, and + * the assertion is commented out. + */ +#ifdef __FreeBSD__ +/* + * On FreeBSD including for CTASSERT only works in kernel + * mode. + */ +#ifndef CTASSERT +#define CTASSERT(x) _CTASSERT(x, __LINE__) +#define _CTASSERT(x, y) __CTASSERT(x, y) +#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] +#endif +#endif /* __FreeBSD__ */ +CTASSERT(MB_LEN_MAX <= sizeof(uint64_t)); +#endif /* !__NetBSD__ */ +#endif + +/* + * This is do_hvis, for HTTP style (RFC 1808) + */ +static wchar_t * +do_hvis(wchar_t *dst, wint_t c, int flags, wint_t nextc, const wchar_t *extra) +{ + if (iswalnum(c) + /* safe */ + || c == L'$' || c == L'-' || c == L'_' || c == L'.' || c == L'+' + /* extra */ + || c == L'!' || c == L'*' || c == L'\'' || c == L'(' || c == L')' + || c == L',') + dst = do_svis(dst, c, flags, nextc, extra); + else { + *dst++ = L'%'; + *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); + *dst++ = xtoa((unsigned int)c & 0xf); + } + + return dst; +} + +/* + * This is do_mvis, for Quoted-Printable MIME (RFC 2045) + * NB: No handling of long lines or CRLF. + */ +static wchar_t * +do_mvis(wchar_t *dst, wint_t c, int flags, wint_t nextc, const wchar_t *extra) +{ + if ((c != L'\n') && + /* Space at the end of the line */ + ((iswspace(c) && (nextc == L'\r' || nextc == L'\n')) || + /* Out of range */ + (!iswspace(c) && (c < 33 || (c > 60 && c < 62) || c > 126)) || + /* Specific char to be escaped */ + wcschr(L"#$@[\\]^`{|}~", c) != NULL)) { + *dst++ = L'='; + *dst++ = XTOA(((unsigned int)c >> 4) & 0xf); + *dst++ = XTOA((unsigned int)c & 0xf); + } else + dst = do_svis(dst, c, flags, nextc, extra); + return dst; +} + +/* + * Output single byte of multibyte character. + */ +static wchar_t * +do_mbyte(wchar_t *dst, wint_t c, int flags, wint_t nextc, int iswextra) +{ + if (flags & VIS_CSTYLE) { + switch (c) { + case L'\n': + *dst++ = L'\\'; *dst++ = L'n'; + return dst; + case L'\r': + *dst++ = L'\\'; *dst++ = L'r'; + return dst; + case L'\b': + *dst++ = L'\\'; *dst++ = L'b'; + return dst; + case BELL: + *dst++ = L'\\'; *dst++ = L'a'; + return dst; + case L'\v': + *dst++ = L'\\'; *dst++ = L'v'; + return dst; + case L'\t': + *dst++ = L'\\'; *dst++ = L't'; + return dst; + case L'\f': + *dst++ = L'\\'; *dst++ = L'f'; + return dst; + case L' ': + *dst++ = L'\\'; *dst++ = L's'; + return dst; + case L'\0': + *dst++ = L'\\'; *dst++ = L'0'; + if (iswoctal(nextc)) { + *dst++ = L'0'; + *dst++ = L'0'; + } + return dst; + /* We cannot encode these characters in VIS_CSTYLE + * because they special meaning */ + case L'n': + case L'r': + case L'b': + case L'a': + case L'v': + case L't': + case L'f': + case L's': + case L'0': + case L'M': + case L'^': + case L'$': /* vis(1) -l */ + break; + default: + if (ISGRAPH(flags, c) && !iswoctal(c)) { + *dst++ = L'\\'; + *dst++ = c; + return dst; + } + } + } + if (iswextra || ((c & 0177) == L' ') || (flags & VIS_OCTAL)) { + *dst++ = L'\\'; + *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + L'0'; + *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + L'0'; + *dst++ = (c & 07) + L'0'; + } else { + if ((flags & VIS_NOSLASH) == 0) + *dst++ = L'\\'; + + if (c & 0200) { + c &= 0177; + *dst++ = L'M'; + } + + if (iswcntrl(c)) { + *dst++ = L'^'; + if (c == 0177) + *dst++ = L'?'; + else + *dst++ = c + L'@'; + } else { + *dst++ = L'-'; + *dst++ = c; + } + } + + return dst; +} + +/* + * This is do_vis, the central code of vis. + * dst: Pointer to the destination buffer + * c: Character to encode + * flags: Flags word + * nextc: The character following 'c' + * extra: Pointer to the list of extra characters to be + * backslash-protected. + */ +static wchar_t * +do_svis(wchar_t *dst, wint_t c, int flags, wint_t nextc, const wchar_t *extra) +{ + int iswextra, i, shft; + uint64_t bmsk, wmsk; + + iswextra = wcschr(extra, c) != NULL; + if (!iswextra && (ISGRAPH(flags, c) || iswwhite(c) || + ((flags & VIS_SAFE) && iswsafe(c)))) { + *dst++ = c; + return dst; + } + + /* See comment in istrsenvisx() output loop, below. */ + wmsk = 0; + for (i = sizeof(wmsk) - 1; i >= 0; i--) { + shft = i * NBBY; + bmsk = (uint64_t)0xffLL << shft; + wmsk |= bmsk; + if ((c & wmsk) || i == 0) + dst = do_mbyte(dst, (wint_t)( + (uint64_t)(c & bmsk) >> shft), + flags, nextc, iswextra); + } + + return dst; +} + +typedef wchar_t *(*visfun_t)(wchar_t *, wint_t, int, wint_t, const wchar_t *); + +/* + * Return the appropriate encoding function depending on the flags given. + */ +static visfun_t +getvisfun(int flags) +{ + if (flags & VIS_HTTPSTYLE) + return do_hvis; + if (flags & VIS_MIMESTYLE) + return do_mvis; + return do_svis; +} + +/* + * Expand list of extra characters to not visually encode. + */ +static wchar_t * +makeextralist(int flags, const char *src) +{ + wchar_t *dst, *d; + size_t len; + const wchar_t *s; + mbstate_t mbstate; + + bzero(&mbstate, sizeof(mbstate)); + len = strlen(src); + if ((dst = calloc(len + MAXEXTRAS, sizeof(*dst))) == NULL) + return NULL; + + if ((flags & VIS_NOLOCALE) || mbsrtowcs(dst, &src, len, &mbstate) == (size_t)-1) { + size_t i; + for (i = 0; i < len; i++) + dst[i] = (wchar_t)(u_char)src[i]; + d = dst + len; + } else + d = dst + wcslen(dst); + + if (flags & VIS_GLOB) + for (s = char_glob; *s; *d++ = *s++) + continue; + + if (flags & VIS_SHELL) + for (s = char_shell; *s; *d++ = *s++) + continue; + + if (flags & VIS_SP) *d++ = L' '; + if (flags & VIS_TAB) *d++ = L'\t'; + if (flags & VIS_NL) *d++ = L'\n'; + if ((flags & VIS_NOSLASH) == 0) *d++ = L'\\'; + *d = L'\0'; + + return dst; +} + +/* + * istrsenvisx() + * The main internal function. + * All user-visible functions call this one. + */ +static int +istrsenvisx(char **mbdstp, size_t *dlen, const char *mbsrc, size_t mblength, + int flags, const char *mbextra, int *cerr_ptr) +{ + wchar_t *dst, *src, *pdst, *psrc, *start, *extra; + size_t len, olen; + uint64_t bmsk, wmsk; + wint_t c; + visfun_t f; + int clen = 0, cerr, error = -1, i, shft; + char *mbdst, *mdst; + ssize_t mbslength, maxolen; + mbstate_t mbstate; + + _DIAGASSERT(mbdstp != NULL); + _DIAGASSERT(mbsrc != NULL || mblength == 0); + _DIAGASSERT(mbextra != NULL); + + /* + * Input (mbsrc) is a char string considered to be multibyte + * characters. The input loop will read this string pulling + * one character, possibly multiple bytes, from mbsrc and + * converting each to wchar_t in src. + * + * The vis conversion will be done using the wide char + * wchar_t string. + * + * This will then be converted back to a multibyte string to + * return to the caller. + */ + + /* Allocate space for the wide char strings */ + psrc = pdst = extra = NULL; + mdst = NULL; + if ((psrc = calloc(mblength + 1, sizeof(*psrc))) == NULL) + return -1; + if ((pdst = calloc((4 * mblength) + 1, sizeof(*pdst))) == NULL) + goto out; + if (*mbdstp == NULL) { + if ((mdst = calloc((4 * mblength) + 1, sizeof(*mdst))) == NULL) + goto out; + *mbdstp = mdst; + } + + mbdst = *mbdstp; + dst = pdst; + src = psrc; + + if (flags & VIS_NOLOCALE) { + /* Do one byte at a time conversion */ + cerr = 1; + } else { + /* Use caller's multibyte conversion error flag. */ + cerr = cerr_ptr ? *cerr_ptr : 0; + } + + /* + * Input loop. + * Handle up to mblength characters (not bytes). We do not + * stop at NULs because we may be processing a block of data + * that includes NULs. + */ + mbslength = (ssize_t)mblength; + /* + * When inputing a single character, must also read in the + * next character for nextc, the look-ahead character. + */ + if (mbslength == 1) + mbslength++; + bzero(&mbstate, sizeof(mbstate)); + while (mbslength > 0) { + /* Convert one multibyte character to wchar_t. */ + if (!cerr) + clen = mbrtowc(src, mbsrc, MB_LEN_MAX, &mbstate); + if (cerr || clen < 0) { + /* Conversion error, process as a byte instead. */ + *src = (wint_t)(u_char)*mbsrc; + clen = 1; + cerr = 1; + } + if (clen == 0) + /* + * NUL in input gives 0 return value. process + * as single NUL byte and keep going. + */ + clen = 1; + /* Advance buffer character pointer. */ + src++; + /* Advance input pointer by number of bytes read. */ + mbsrc += clen; + /* Decrement input byte count. */ + mbslength -= clen; + } + len = src - psrc; + src = psrc; + /* + * In the single character input case, we will have actually + * processed two characters, c and nextc. Reset len back to + * just a single character. + */ + if (mblength < len) + len = mblength; + + /* Convert extra argument to list of characters for this mode. */ + extra = makeextralist(flags, mbextra); + if (!extra) { + if (dlen && *dlen == 0) { + errno = ENOSPC; + goto out; + } + *mbdst = '\0'; /* can't create extra, return "" */ + error = 0; + goto out; + } + + /* Look up which processing function to call. */ + f = getvisfun(flags); + + /* + * Main processing loop. + * Call do_Xvis processing function one character at a time + * with next character available for look-ahead. + */ + for (start = dst; len > 0; len--) { + c = *src++; + dst = (*f)(dst, c, flags, len >= 1 ? *src : L'\0', extra); + if (dst == NULL) { + errno = ENOSPC; + goto out; + } + } + + /* Terminate the string in the buffer. */ + *dst = L'\0'; + + /* + * Output loop. + * Convert wchar_t string back to multibyte output string. + * If we have hit a multi-byte conversion error on input, + * output byte-by-byte here. Else use wctomb(). + */ + len = wcslen(start); + maxolen = dlen ? *dlen : (wcslen(start) * MB_LEN_MAX + 1); + olen = 0; + bzero(&mbstate, sizeof(mbstate)); + for (dst = start; len > 0; len--) { + if (!cerr) + clen = wcrtomb(mbdst, *dst, &mbstate); + if (cerr || clen < 0) { + /* + * Conversion error, process as a byte(s) instead. + * Examine each byte and higher-order bytes for + * data. E.g., + * 0x000000000000a264 -> a2 64 + * 0x000000001f00a264 -> 1f 00 a2 64 + */ + clen = 0; + wmsk = 0; + for (i = sizeof(wmsk) - 1; i >= 0; i--) { + shft = i * NBBY; + bmsk = (uint64_t)0xffLL << shft; + wmsk |= bmsk; + if ((*dst & wmsk) || i == 0) + mbdst[clen++] = (char)( + (uint64_t)(*dst & bmsk) >> + shft); + } + cerr = 1; + } + /* If this character would exceed our output limit, stop. */ + if (olen + clen > (size_t)maxolen) + break; + /* Advance output pointer by number of bytes written. */ + mbdst += clen; + /* Advance buffer character pointer. */ + dst++; + /* Incrment output character count. */ + olen += clen; + } + + /* Terminate the output string. */ + *mbdst = '\0'; + + if (flags & VIS_NOLOCALE) { + /* Pass conversion error flag out. */ + if (cerr_ptr) + *cerr_ptr = cerr; + } + + free(extra); + free(pdst); + free(psrc); + + return (int)olen; +out: + free(extra); + free(pdst); + free(psrc); + free(mdst); + return error; +} + +static int +istrsenvisxl(char **mbdstp, size_t *dlen, const char *mbsrc, + int flags, const char *mbextra, int *cerr_ptr) +{ + return istrsenvisx(mbdstp, dlen, mbsrc, + mbsrc != NULL ? strlen(mbsrc) : 0, flags, mbextra, cerr_ptr); +} + +#endif + +#if !HAVE_SVIS +/* + * The "svis" variants all take an "extra" arg that is a pointer + * to a NUL-terminated list of characters to be encoded, too. + * These functions are useful e. g. to encode strings in such a + * way so that they are not interpreted by a shell. + */ + +char * +svis(char *mbdst, int c, int flags, int nextc, const char *mbextra) +{ + char cc[2]; + int ret; + + cc[0] = c; + cc[1] = nextc; + + ret = istrsenvisx(&mbdst, NULL, cc, 1, flags, mbextra, NULL); + if (ret < 0) + return NULL; + return mbdst + ret; +} + +char * +snvis(char *mbdst, size_t dlen, int c, int flags, int nextc, const char *mbextra) +{ + char cc[2]; + int ret; + + cc[0] = c; + cc[1] = nextc; + + ret = istrsenvisx(&mbdst, &dlen, cc, 1, flags, mbextra, NULL); + if (ret < 0) + return NULL; + return mbdst + ret; +} + +int +strsvis(char *mbdst, const char *mbsrc, int flags, const char *mbextra) +{ + return istrsenvisxl(&mbdst, NULL, mbsrc, flags, mbextra, NULL); +} + +int +strsnvis(char *mbdst, size_t dlen, const char *mbsrc, int flags, const char *mbextra) +{ + return istrsenvisxl(&mbdst, &dlen, mbsrc, flags, mbextra, NULL); +} + +int +strsvisx(char *mbdst, const char *mbsrc, size_t len, int flags, const char *mbextra) +{ + return istrsenvisx(&mbdst, NULL, mbsrc, len, flags, mbextra, NULL); +} + +int +strsnvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags, + const char *mbextra) +{ + return istrsenvisx(&mbdst, &dlen, mbsrc, len, flags, mbextra, NULL); +} + +int +strsenvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags, + const char *mbextra, int *cerr_ptr) +{ + return istrsenvisx(&mbdst, &dlen, mbsrc, len, flags, mbextra, cerr_ptr); +} +#endif + +#if !HAVE_VIS +/* + * vis - visually encode characters + */ +char * +vis(char *mbdst, int c, int flags, int nextc) +{ + char cc[2]; + int ret; + + cc[0] = c; + cc[1] = nextc; + + ret = istrsenvisx(&mbdst, NULL, cc, 1, flags, "", NULL); + if (ret < 0) + return NULL; + return mbdst + ret; +} + +char * +nvis(char *mbdst, size_t dlen, int c, int flags, int nextc) +{ + char cc[2]; + int ret; + + cc[0] = c; + cc[1] = nextc; + + ret = istrsenvisx(&mbdst, &dlen, cc, 1, flags, "", NULL); + if (ret < 0) + return NULL; + return mbdst + ret; +} + +/* + * strvis - 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. + */ + +int +strvis(char *mbdst, const char *mbsrc, int flags) +{ + return istrsenvisxl(&mbdst, NULL, mbsrc, flags, "", NULL); +} + +int +strnvis(char *mbdst, size_t dlen, const char *mbsrc, int flags) +{ + return istrsenvisxl(&mbdst, &dlen, mbsrc, flags, "", NULL); +} + +int +stravis(char **mbdstp, const char *mbsrc, int flags) +{ + *mbdstp = NULL; + return istrsenvisxl(mbdstp, NULL, mbsrc, flags, "", NULL); +} + +/* + * 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. + * + * Strvisx encodes exactly len characters from src into dst. + * This is useful for encoding a block of data. + */ + +int +strvisx(char *mbdst, const char *mbsrc, size_t len, int flags) +{ + return istrsenvisx(&mbdst, NULL, mbsrc, len, flags, "", NULL); +} + +int +strnvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags) +{ + return istrsenvisx(&mbdst, &dlen, mbsrc, len, flags, "", NULL); +} + +int +strenvisx(char *mbdst, size_t dlen, const char *mbsrc, size_t len, int flags, + int *cerr_ptr) +{ + return istrsenvisx(&mbdst, &dlen, mbsrc, len, flags, "", cerr_ptr); +} +#endif diff --git a/contrib/libc-vis/vis.h b/contrib/libc-vis/vis.h new file mode 100644 index 0000000..da697cb --- /dev/null +++ b/contrib/libc-vis/vis.h @@ -0,0 +1,121 @@ +/* $NetBSD: vis.h,v 1.24 2016/01/14 20:42:14 christos Exp $ */ +/* $FreeBSD: releng/11.1/contrib/libc-vis/vis.h 301679 2016-06-08 18:21:27Z brooks $ */ + +/*- + * Copyright (c) 1990, 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. + * + * @(#)vis.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _VIS_H_ +#define _VIS_H_ + +#include + +/* + * to select alternate encoding format + */ +#define VIS_OCTAL 0x0001 /* use octal \ddd format */ +#define VIS_CSTYLE 0x0002 /* use \[nrft0..] where appropiate */ + +/* + * to alter set of characters encoded (default is to encode all + * non-graphic except space, tab, and newline). + */ +#define VIS_SP 0x0004 /* also encode space */ +#define VIS_TAB 0x0008 /* also encode tab */ +#define VIS_NL 0x0010 /* also encode newline */ +#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) +#define VIS_SAFE 0x0020 /* only encode "unsafe" characters */ + +/* + * other + */ +#define VIS_NOSLASH 0x0040 /* inhibit printing '\' */ +#define VIS_HTTP1808 0x0080 /* http-style escape % hex hex */ +#define VIS_HTTPSTYLE 0x0080 /* http-style escape % hex hex */ +#define VIS_GLOB 0x0100 /* encode glob(3) magic characters */ +#define VIS_MIMESTYLE 0x0200 /* mime-style escape = HEX HEX */ +#define VIS_HTTP1866 0x0400 /* http-style &#num; or &string; */ +#define VIS_NOESCAPE 0x0800 /* don't decode `\' */ +#define _VIS_END 0x1000 /* for unvis */ +#define VIS_SHELL 0x2000 /* encode shell special characters [not glob] */ +#define VIS_META (VIS_WHITE | VIS_GLOB | VIS_SHELL) +#define VIS_NOLOCALE 0x4000 /* encode using the C locale */ + +/* + * 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 _VIS_END /* no more characters */ + +#include + +__BEGIN_DECLS +char *vis(char *, int, int, int); +char *nvis(char *, size_t, int, int, int); + +char *svis(char *, int, int, int, const char *); +char *snvis(char *, size_t, int, int, int, const char *); + +int strvis(char *, const char *, int); +int stravis(char **, const char *, int); +int strnvis(char *, size_t, const char *, int); + +int strsvis(char *, const char *, int, const char *); +int strsnvis(char *, size_t, const char *, int, const char *); + +int strvisx(char *, const char *, size_t, int); +int strnvisx(char *, size_t, const char *, size_t, int); +int strenvisx(char *, size_t, const char *, size_t, int, int *); + +int strsvisx(char *, const char *, size_t, int, const char *); +int strsnvisx(char *, size_t, const char *, size_t, int, const char *); +int strsenvisx(char *, size_t, const char *, size_t , int, const char *, + int *); + +int strunvis(char *, const char *); +int strnunvis(char *, size_t, const char *); + +int strunvisx(char *, const char *, int); +int strnunvisx(char *, size_t, const char *, int); + +#ifndef __LIBC12_SOURCE__ +int unvis(char *, int, int *, int); +#endif +__END_DECLS + +#endif /* !_VIS_H_ */ diff --git a/contrib/netbsd-tests/FREEBSD-upgrade b/contrib/netbsd-tests/FREEBSD-upgrade new file mode 100644 index 0000000..edeba70 --- /dev/null +++ b/contrib/netbsd-tests/FREEBSD-upgrade @@ -0,0 +1,38 @@ +$FreeBSD$ + +This document contains a collection of notes specific to the import +of the NetBSD test suite into head. These notes are built on the instructions +in the FreeBSD Subversion Primer that detail how to deal with vendor +branches and you are supposed to follow those: + + http://www.freebsd.org/doc/en/articles/committers-guide/subversion-primer.html + +The NetBSD test source code was originally obtained via NetBSD anoncvs as +described in the NetBSD handbook: + + http://www.netbsd.org/docs/guide/en/chap-fetch.html#chap-fetch-cvs + +and is imported into the NetBSD/tests vendor branch (see +base/vendor/NetBSD/tests/). + +The process used to bootstrap the vendor tree was similar to the following: + + /bin/sh + export CVSROOT="anoncvs@anoncvs.NetBSD.org:/cvsroot" + cvs -z9 co -D "09/30/2014 20:45" -P src/tests + mv src/tests/* tests/dist/. + +Please adjust the checkout date spec (the argument passed via -D) to match +the desired checkout time. + +To merge the vendor branch into head do something like this: + + cd .../base/head/contrib/netbsd-tests + svn merge --accept=postpone \ + svn+ssh://svn.freebsd.org/base/vendor/NetBSD/tests/dist . + find . -name Makefile\* | xargs svn rm --force + +and resolve any conflicts that may arise at this point. + +Lastly, with the list of old and new files in this import, make sure +to update the reachover Makefiles accordingly. diff --git a/contrib/netbsd-tests/bin/cat/d_align.in b/contrib/netbsd-tests/bin/cat/d_align.in new file mode 100644 index 0000000..37d30c7 --- /dev/null +++ b/contrib/netbsd-tests/bin/cat/d_align.in @@ -0,0 +1,5 @@ +a b c + +1 2 3 + +x y z diff --git a/contrib/netbsd-tests/bin/cat/d_align.out b/contrib/netbsd-tests/bin/cat/d_align.out new file mode 100644 index 0000000..4f44c00 --- /dev/null +++ b/contrib/netbsd-tests/bin/cat/d_align.out @@ -0,0 +1,5 @@ + 1 a b c$ + $ + 2 1 2 3$ + $ + 3 x y z$ diff --git a/contrib/netbsd-tests/bin/cat/d_se_output.in b/contrib/netbsd-tests/bin/cat/d_se_output.in new file mode 100644 index 0000000..0d3c8c1 --- /dev/null +++ b/contrib/netbsd-tests/bin/cat/d_se_output.in @@ -0,0 +1,3 @@ + +Of course it runs NetBSD + diff --git a/contrib/netbsd-tests/bin/cat/d_se_output.out b/contrib/netbsd-tests/bin/cat/d_se_output.out new file mode 100644 index 0000000..c4767c3 --- /dev/null +++ b/contrib/netbsd-tests/bin/cat/d_se_output.out @@ -0,0 +1,3 @@ +$ +Of course it runs NetBSD$ +$ diff --git a/contrib/netbsd-tests/bin/cat/t_cat.sh b/contrib/netbsd-tests/bin/cat/t_cat.sh new file mode 100755 index 0000000..799a748 --- /dev/null +++ b/contrib/netbsd-tests/bin/cat/t_cat.sh @@ -0,0 +1,71 @@ +# $NetBSD: t_cat.sh,v 1.3 2016/06/16 01:04:58 sevan Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case align +align_head() { + atf_set "descr" "Test that cat(1) aligns the output " \ + "right with options '-be' (PR bin/4841)" +} + +align_body() { + + atf_check -s ignore -o file:$(atf_get_srcdir)/d_align.out \ + -x "cat -be $(atf_get_srcdir)/d_align.in" +} + +atf_test_case nonexistent +nonexistent_head() { + atf_set "descr" "Test that cat(1) doesn't return zero exit " \ + "status for a nonexistent file (PR bin/3538)" +} + +nonexistent_body() { + + atf_check -s not-exit:0 -o empty -e not-empty \ + -x "cat /some/name/that/does/not/exist" +} + +atf_test_case se_output +se_output_head() { + atf_set "descr" "Test that cat(1) prints a $ sign " \ + "on blank lines with options '-se' (PR bin/51250)" +} + +se_output_body() { + atf_check -s ignore -o file:$(atf_get_srcdir)/d_se_output.out \ + -x "cat -se $(atf_get_srcdir)/d_se_output.in" +} + +atf_init_test_cases() +{ + atf_add_test_case align + atf_add_test_case nonexistent + atf_add_test_case se_output +} diff --git a/contrib/netbsd-tests/bin/cp/t_cp.sh b/contrib/netbsd-tests/bin/cp/t_cp.sh new file mode 100755 index 0000000..be55c7c --- /dev/null +++ b/contrib/netbsd-tests/bin/cp/t_cp.sh @@ -0,0 +1,294 @@ +# $NetBSD: t_cp.sh,v 1.1 2012/03/17 16:33:10 jruoho Exp $ +# +# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +FILES="file file2 file3 link dir dir2 dirlink target" + +cleanup() { + rm -fr ${FILES} +} + +cp_compare() { + echo "Ensuring that $2 and $3 are identical" + cmp -s $2 $3 || atf_fail "$2 and $3 are different" +} + +reset() { + cleanup + echo "I'm a file" > file + echo "I'm a file, 2" > file2 + echo "I'm a file, 3" > file3 + ln -s file link + mkdir dir + ln -s dir dirlink +} + +atf_test_case file_to_file +file_to_file_head() { + atf_set "descr" "Checks the copy of a file to a file" +} +file_to_file_body() { + reset + + file_to_file_simple + file_to_file_preserve + file_to_file_noflags +} + +file_to_file_simple() { + rm -f file2 + umask 022 + chmod 777 file + atf_check -s eq:0 -o empty -e empty cp file file2 + cp_compare file_to_file_simple file file2 + if [ `stat -f "%Lp" file2` != "755" ]; then + atf_fail "new file not created with umask" + fi + + chmod 644 file + chmod 777 file2 + cp_compare file_to_file_simple file file2 + if [ `stat -f "%Lp" file2` != "777" ]; then + atf_fail "existing files permissions not retained" + fi +} + +file_to_file_preserve() { + rm file3 + chmod 644 file + chflags nodump file + atf_check -s eq:0 -o empty -e empty cp -p file file3 + finfo=`stat -f "%p%u%g%m%z%f" file` + f3info=`stat -f "%p%u%g%m%z%f" file3` + if [ $finfo != $f3info ]; then + atf_fail "attributes not preserved" + fi +} + +file_to_file_noflags() { + rm file3 + chmod 644 file + chflags nodump file + atf_check -s eq:0 -o empty -e empty cp -p -N file file3 + finfo=`stat -f "%f" file` + f3info=`stat -f "%f" file3` + if [ $finfo = $f3info ]; then + atf_fail "-p -N preserved file flags" + fi +} + +atf_test_case file_to_link +file_to_link_head() { + atf_set "descr" "Checks the copy of a file to a symbolic link" +} +file_to_link_body() { + reset + atf_check -s eq:0 -o empty -e empty cp file2 link + cp_compare file_to_link file file2 +} + +atf_test_case link_to_file +link_to_file_head() { + atf_set "descr" "Checks the copy of a symbolic link to a file" +} +link_to_file_body() { + reset + # file and link are identical (not copied). + atf_check -s eq:1 -o empty -e ignore cp link file + atf_check -s eq:0 -o empty -e empty cp link file2 + cp_compare link_to_file file file2 +} + +atf_test_case file_over_link +file_over_link_head() { + atf_set "descr" "Checks the copy of a file to a symbolic link" \ + "without following it" +} +file_over_link_body() { + reset + atf_check -s eq:0 -o empty -e empty cp -P file link + cp_compare file_over_link file link +} + +atf_test_case link_over_file +link_over_file_head() { + atf_set "descr" "Checks the copy of a symbolic link to a file" \ + "without following the former" +} +link_over_file_body() { + reset + atf_check -s eq:0 -o empty -e empty cp -P link file + if [ `readlink link` != `readlink file` ]; then + atf_fail "readlink link != readlink file" + fi +} + +atf_test_case files_to_dir +files_to_dir_head() { + atf_set "descr" "Checks the copy of multiple files into a directory" +} +files_to_dir_body() { + reset + # can't copy multiple files to a file + atf_check -s eq:1 -o empty -e ignore cp file file2 file3 + atf_check -s eq:0 -o empty -e empty cp file file2 link dir + cp_compare files_to_dir file "dir/file" +} + +atf_test_case dir_to_file +dir_to_file_head() { + atf_set "descr" "Checks the copy of a directory onto a file, which" \ + "should not work" +} +dir_to_file_body() { + reset + # can't copy a dir onto a file + atf_check -s eq:1 -o empty -e ignore cp dir file + atf_check -s eq:1 -o empty -e ignore cp -R dir file +} + +atf_test_case file_to_linkdir +file_to_linkdir_head() { + atf_set "descr" "Checks the copy of a file to a symbolic link that" \ + "points to a directory" +} +file_to_linkdir_body() { + reset + atf_check -s eq:0 -o empty -e empty cp file dirlink + cp_compare file_to_linkdir file "dir/file" + + # overwrite the link + atf_check -s eq:0 -o empty -e empty cp -P file dirlink + atf_check -s eq:1 -o empty -e empty readlink dirlink + cp_compare file_to_linkdir file dirlink +} + +atf_test_case linkdir_to_file +linkdir_to_file_head() { + atf_set "descr" "Checks the copy of a symbolic link that points to" \ + "a directory onto a file" +} +linkdir_to_file_body() { + reset + # cannot copy a dir onto a file + atf_check -s eq:1 -o empty -e ignore cp dirlink file + + # overwrite the link + atf_check -s eq:0 -o empty -e empty cp -P dirlink file + if [ `readlink file` != `readlink dirlink` ]; then + atf_fail "readlink link != readlink file" + fi +} + +dir_to_dne_no_R() { + atf_check -s eq:1 -o empty -e ignore cp dir dir2 +} + +dir_to_dne() { + atf_check -s eq:0 -o empty -e empty cp -R dir dir2 + cp_compare dir_to_dne "dir/file" "dir2/file" + readlink dir2/link >/dev/null + if [ $? -gt 0 ]; then + atf_fail "-R didn't copy a link as a link" + fi +} + +dir_to_dir_H() { + dir_to_dir_setup + atf_check -s eq:0 -o empty -e empty cp -R dir dir2 + + chmod 777 dir + + # copy a dir into a dir, only command-line links are followed + atf_check -s eq:0 -o empty -e empty cp -R -H dirlink dir2 + cp_compare dir_to_dir_H "dir/file" "dir2/dirlink/file" + readlink dir2/dirlink/link >/dev/null + if [ $? -gt 0 ]; then + atf_fail "didn't copy a link as a link" + fi + + # Created directories have the same mode as the corresponding + # source directory, unmodified by the process's umask. + if [ `stat -f "%Lp" dir2/dirlink` != "777" ]; then + atf_fail "-R modified dir perms with umask" + fi +} + +dir_to_dir_L() { + dir_to_dir_setup + atf_check -s eq:0 -o empty -e empty cp -R dir dir2 + atf_check -s eq:0 -o empty -e empty cp -R -H dirlink dir2 + + # copy a dir into a dir, following all links + atf_check -s eq:0 -o empty -e empty cp -R -H -L dirlink dir2/dirlink + cp_compare dir_to_dir_L "dir/file" "dir2/dirlink/dirlink/file" + # fail if -R -L copied a link as a link + atf_check -s eq:1 -o ignore -e empty readlink dir2/dirlink/dirlink/link +} + +dir_to_dir_subdir_exists() { + # recursively copy a dir into another dir, with some subdirs already + # existing + cleanup + + mkdir -p dir/1 dir/2 dir/3 target/2 + echo "file" > dir/2/file + atf_check -s eq:0 -o empty -e empty cp -R dir/* target + cp_compare dir_to_dir_subdir_exists "dir/2/file" "target/2/file" +} + +dir_to_dir_setup() { + reset + umask 077 + cp -P file file2 file3 link dir +} + +atf_test_case dir_to_dir +dir_to_dir_head() { + atf_set "descr" "Checks the copy of a directory onto another directory" +} +dir_to_dir_body() { + dir_to_dir_setup + dir_to_dne_no_R + dir_to_dne + dir_to_dir_H + dir_to_dir_L + dir_to_dir_subdir_exists +} + +atf_init_test_cases() +{ + atf_add_test_case file_to_file + atf_add_test_case file_to_link + atf_add_test_case link_to_file + atf_add_test_case file_over_link + atf_add_test_case link_over_file + atf_add_test_case files_to_dir + atf_add_test_case file_to_linkdir + atf_add_test_case linkdir_to_file + atf_add_test_case dir_to_file + atf_add_test_case dir_to_dir +} diff --git a/contrib/netbsd-tests/bin/dd/t_dd.sh b/contrib/netbsd-tests/bin/dd/t_dd.sh new file mode 100755 index 0000000..62379c2 --- /dev/null +++ b/contrib/netbsd-tests/bin/dd/t_dd.sh @@ -0,0 +1,136 @@ +# $NetBSD: t_dd.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $ +# +# Copyright (c) 2007 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +test_dd_length() { + result=$1 + cmd=$2 + set -- x `eval $cmd | wc -c` + res=$2 + if [ x"$res" != x"$result" ]; then + atf_fail "Expected $result bytes of output, got $res: $cmd" + fi +} + +atf_test_case length +length_head() { + # XXX The PR should be stored in a tag. + atf_set "descr" "Test for result messages accidentally pumped into" \ + "the output file if the standard IO descriptors are" \ + "closed. The last of the three following tests is" \ + "the one expected to fail. (NetBSD PR bin/8521)" +} +length_body() { + # Begin FreeBSD + if ! df /dev/fd | grep -q '^fdescfs'; then + atf_skip "fdescfs is not mounted on /dev/fd" + fi + # End FreeBSD + + test_dd_length 512 \ + "dd if=/dev/zero of=/dev/fd/5 count=1 5>&1 >/dev/null 2>/dev/null" + test_dd_length 512 \ + "dd if=/dev/zero of=/dev/fd/5 count=1 5>&1 >&- 2>/dev/null" + test_dd_length 512 \ + "dd if=/dev/zero of=/dev/fd/5 count=1 5>&1 >&- 2>&-" +} + +test_dd_io() { + res="`echo -n "$2" | eval $1`" + if [ x"$res" != x"$3" ]; then + atf_fail "Expected \"$3\", got \"$res\": $1" + fi +} + +allbits1="\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377" + +ebcdicbits1="\000\001\002\003\067\055\056\057\026\005\045\013\014\015\016\017\020\021\022\023\074\075\062\046\030\031\077\047\034\035\036\037\100\132\177\173\133\154\120\175\115\135\134\116\153\140\113\141\360\361\362\363\364\365\366\367\370\371\172\136\114\176\156\157\174\301\302\303\304\305\306\307\310\311\321\322\323\324\325\326\327\330\331\342\343\344\345\346\347\350\351\255\340\275\232\155\171\201\202\203\204\205\206\207\210\211\221\222\223\224\225\226\227\230\231\242\243\244\245\246\247\250\251\300\117\320\137\007\040\041\042\043\044\025\006\027\050\051\052\053\054\011\012\033\060\061\032\063\064\065\066\010\070\071\072\073\004\024\076\341\101\102\103\104\105\106\107\110\111\121\122\123\124\125\126\127\130\131\142\143\144\145\146\147\150\151\160\161\162\163\164\165\166\167\170\200\212\213\214\215\216\217\220\152\233\234\235\236\237\240\252\253\254\112\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\241\276\277\312\313\314\315\316\317\332\333\334\335\336\337\352\353\354\355\356\357\372\373\374\375\376\377" + +allvisbits=`echo -n "$allbits1" | unvis | vis` +ebcdicvisbits=`echo -n "$ebcdicbits1" | unvis | vis` + +atf_test_case io +io_head() { + atf_set "descr" "This checks the combination of bs= with" \ + "conv=ebcdic. Prior to revision 1.24 of dd's" \ + "args.c, the conv option would be ignored." +} +io_body() { + test_dd_io "unvis | dd 2>/dev/null | vis" \ + "$allvisbits" "$allvisbits" + test_dd_io "unvis | dd ibs=1 2>/dev/null | vis" \ + "$allvisbits" "$allvisbits" + test_dd_io "unvis | dd obs=1 2>/dev/null | vis" \ + "$allvisbits" "$allvisbits" + test_dd_io "unvis | dd bs=1 2>/dev/null | vis" \ + "$allvisbits" "$allvisbits" + + test_dd_io "unvis | dd conv=ebcdic 2>/dev/null | vis" \ + "$allvisbits" "$ebcdicvisbits" + test_dd_io "unvis | dd conv=ebcdic ibs=512 2>/dev/null | vis" \ + "$allvisbits" "$ebcdicvisbits" + test_dd_io "unvis | dd conv=ebcdic obs=512 2>/dev/null | vis" \ + "$allvisbits" "$ebcdicvisbits" + test_dd_io "unvis | dd conv=ebcdic bs=512 2>/dev/null | vis" \ + "$allvisbits" "$ebcdicvisbits" + + test_dd_io "unvis | dd conv=ebcdic 2>/dev/null | vis" \ + "$allvisbits" "$ebcdicvisbits" + test_dd_io "unvis | dd conv=ebcdic ibs=1 2>/dev/null | vis" \ + "$allvisbits" "$ebcdicvisbits" + test_dd_io "unvis | dd conv=ebcdic obs=1 2>/dev/null | vis" \ + "$allvisbits" "$ebcdicvisbits" + test_dd_io "unvis | dd conv=ebcdic bs=1 2>/dev/null | vis" \ + "$allvisbits" "$ebcdicvisbits" +} + +atf_test_case seek +seek_head() { + atf_set "descr" "Tests output file seeking" +} + +seek_body() { + echo TEST1234 > testfile + atf_check -s exit:0 -e ignore \ + dd if=/dev/zero of=testfile seek=1 bs=8k count=1 + atf_check -s exit:0 -e ignore -o match:'^TEST1234$' dd if=testfile + eval $(stat -s testfile) + atf_check_equal $st_size $((2*8192)) + + echo -n TEST1234 > tf2 + atf_check -s exit:0 -e ignore -x \ + 'dd bs=4 if=/dev/zero count=1 | tr \\0 \\n | dd of=tf2 bs=4 seek=1' + atf_check -s exit:0 -e ignore -o match:'^TEST$' dd if=tf2 + eval $(stat -s tf2) + atf_check_equal $st_size 8 +} + +atf_init_test_cases() +{ + atf_add_test_case length + atf_add_test_case io + atf_add_test_case seek +} diff --git a/contrib/netbsd-tests/bin/df/getmntinfo.c b/contrib/netbsd-tests/bin/df/getmntinfo.c new file mode 100644 index 0000000..4ad1f40 --- /dev/null +++ b/contrib/netbsd-tests/bin/df/getmntinfo.c @@ -0,0 +1,218 @@ +/* $NetBSD: getmntinfo.c,v 1.1 2012/03/17 16:33:11 jruoho Exp $ */ +/* + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include +#include +#include + +#define KB * 1024 +#define MB * 1024 KB +#define GB * 1024 MB + +static struct statvfs *getnewstatvfs(void); +static void other_variants(const struct statvfs *, const int *, int, + const int *, int); +static void setup_filer(void); +static void setup_ld0g(void); +static void setup_strpct(void); + +static struct statvfs *allstatvfs; +static int sftotal, sfused; + +struct statvfs * +getnewstatvfs(void) +{ + + if (sftotal == sfused) { + sftotal = sftotal ? sftotal * 2 : 1; + allstatvfs = realloc(allstatvfs, + sftotal * sizeof(struct statvfs)); + if (allstatvfs == NULL) + err(EXIT_FAILURE, "realloc"); + } + + return (&allstatvfs[sfused++]); +} + +void +other_variants(const struct statvfs *tmpl, const int *minfree, int minfreecnt, + const int *consumed, int consumedcnt) +{ + int64_t total, used; + struct statvfs *sf; + int i, j; + + for (i = 0; i < minfreecnt; i++) + for (j = 0; j < consumedcnt; j++) { + sf = getnewstatvfs(); + *sf = *tmpl; + total = (int64_t)(u_long)sf->f_blocks * sf->f_bsize; + used = total * consumed[j] / 100; + sf->f_bfree = (total - used) / sf->f_bsize; + sf->f_bavail = (total * (100 - minfree[i]) / 100 - + used) / (int)sf->f_bsize; + sf->f_bresvd = sf->f_bfree - sf->f_bavail; + } +} + +/* + * Parameter taken from: + * http://mail-index.NetBSD.org/tech-userlevel/2004/03/24/0001.html + */ +void +setup_filer(void) +{ + static const struct statvfs tmpl = { +#define BSIZE 512 +#define TOTAL 1147ULL GB +#define USED 132ULL MB + .f_bsize = BSIZE, + .f_frsize = BSIZE, + .f_blocks = TOTAL / BSIZE, + .f_bfree = (TOTAL - USED) / BSIZE, + .f_bavail = (TOTAL - USED) / BSIZE, + .f_bresvd = 0, + .f_mntfromname = "filer:/", + .f_mntonname = "/filer", +#undef USED +#undef TOTAL +#undef BSIZE + }; + static const int minfree[] = { 0, 5, 10, 15, }; + static const int consumed[] = { 0, 20, 60, 95, 100 }; + + *getnewstatvfs() = tmpl; + other_variants(&tmpl, minfree, sizeof(minfree) / sizeof(minfree[0]), + consumed, sizeof(consumed) / sizeof(consumed[0])); +} + +/* + * Parameter taken from: + * http://mail-index.NetBSD.org/current-users/2004/03/01/0038.html + */ +void +setup_ld0g(void) +{ + static const struct statvfs tmpl = { +#define BSIZE 4096 /* Guess */ +#define TOTAL 1308726116ULL KB +#define USED 17901268ULL KB +#define AVAIL 1225388540ULL KB + .f_bsize = BSIZE, + .f_frsize = BSIZE, + .f_blocks = TOTAL / BSIZE, + .f_bfree = (TOTAL - USED) / BSIZE, + .f_bavail = AVAIL / BSIZE, + .f_bresvd = (TOTAL - USED) / BSIZE - AVAIL / BSIZE, + .f_mntfromname = "/dev/ld0g", + .f_mntonname = "/anon-root", +#undef AVAIL +#undef USED +#undef TOTAL +#undef BSIZE + }; + static const int minfree[] = { 0, 5, 10, 15, }; + static const int consumed[] = { 0, 20, 60, 95, 100 }; + + *getnewstatvfs() = tmpl; + other_variants(&tmpl, minfree, sizeof(minfree) / sizeof(minfree[0]), + consumed, sizeof(consumed) / sizeof(consumed[0])); +} + +/* + * Test of strpct() with huge number. + */ +void +setup_strpct(void) +{ + static const struct statvfs tmpl = { +#define BSIZE 4096 /* Guess */ +#define TOTAL 0x4ffffffffULL KB +#define USED (TOTAL / 2) +#define AVAIL (TOTAL / 2) + .f_bsize = BSIZE, + .f_frsize = BSIZE, + .f_blocks = TOTAL / BSIZE, + .f_bfree = (TOTAL - USED) / BSIZE, + .f_bavail = AVAIL / BSIZE, + .f_bresvd = (TOTAL - USED) / BSIZE - AVAIL / BSIZE, + .f_mntfromname = "/dev/strpct", + .f_mntonname = "/strpct", +#undef AVAIL +#undef USED +#undef TOTAL +#undef BSIZE + }; + + *getnewstatvfs() = tmpl; +} + +/* + * Parameter taken from: + * http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=23600 + */ +static void +setup_pr23600(void) +{ + static const struct statvfs tmpl = { +#define BSIZE 512 +#define TOTAL 20971376ULL +#define USED 5719864ULL +#define AVAIL 15251512ULL + .f_bsize = BSIZE, + .f_frsize = BSIZE, + .f_blocks = TOTAL, + .f_bfree = TOTAL - USED, + .f_bavail = AVAIL, + .f_bresvd = TOTAL - USED - AVAIL, + .f_mntfromname = "/dev/wd0e", + .f_mntonname = "/mount/windows/C", +#undef AVAIL +#undef USED +#undef TOTAL +#undef BSIZE + }; + + *getnewstatvfs() = tmpl; +} + +int +getmntinfo(struct statvfs **mntbuf, int flags) +{ + + setup_filer(); + setup_ld0g(); + setup_strpct(); + setup_pr23600(); + + *mntbuf = allstatvfs; + return (sfused); +} diff --git a/contrib/netbsd-tests/bin/df/t_df.sh b/contrib/netbsd-tests/bin/df/t_df.sh new file mode 100755 index 0000000..ffb5aad --- /dev/null +++ b/contrib/netbsd-tests/bin/df/t_df.sh @@ -0,0 +1,148 @@ +# $NetBSD: t_df.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $ +# +# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case normal +normal_head() { + atf_set "descr" "Checks that the output of df without flags is" \ + "correct according to some already-known, sane" \ + "output" +} +normal_body() { + cat >expout <expout <&1` + if [ "$res" != "$2" ]; then + atf_fail "Expected $2, got $res from expression: " \ + "`eval echo $1`" + fi +} + +atf_test_case lang +lang_ops_head() { + atf_set "descr" "Test that expr(1) works with non-C LANG (PR bin/2486)" +} +lang_body() { + + export LANG=nonexistent + atf_check -s exit:0 -o inline:"21\n" -e empty -x "expr 10 + 11" + + export LANG=ru_RU.KOI8-R + atf_check -s exit:0 -o inline:"21\n" -e empty -x "expr 10 + 11" +} + +atf_test_case overflow +overflow_head() { + atf_set "descr" "Test overflow cases" +} +overflow_body() { + test_expr '4611686018427387904 + 4611686018427387903' \ + '9223372036854775807' + test_expr '4611686018427387904 + 4611686018427387904' \ + "expr: integer overflow or underflow occurred for operation '4611686018427387904 + 4611686018427387904'" + test_expr '4611686018427387904 - -4611686018427387904' \ + "expr: integer overflow or underflow occurred for operation '4611686018427387904 - -4611686018427387904'" + test_expr '-4611686018427387904 - 4611686018427387903' \ + '-9223372036854775807' + test_expr '-4611686018427387904 - 4611686018427387905' \ + "expr: integer overflow or underflow occurred for operation '-4611686018427387904 - 4611686018427387905'" + test_expr '-4611686018427387904 \* 1' '-4611686018427387904' + test_expr '-4611686018427387904 \* -1' '4611686018427387904' + test_expr '-4611686018427387904 \* 2' '-9223372036854775808' + test_expr '-4611686018427387904 \* 3' \ + "expr: integer overflow or underflow occurred for operation '-4611686018427387904 * 3'" + test_expr '-4611686018427387904 \* -2' \ + "expr: integer overflow or underflow occurred for operation '-4611686018427387904 * -2'" + test_expr '4611686018427387904 \* 1' '4611686018427387904' + test_expr '4611686018427387904 \* 2' \ + "expr: integer overflow or underflow occurred for operation '4611686018427387904 * 2'" + test_expr '4611686018427387904 \* 3' \ + "expr: integer overflow or underflow occurred for operation '4611686018427387904 * 3'" +} + +atf_test_case gtkmm +gtkmm_head() { + atf_set "descr" "Test from gtk-- configure that cause problems on old expr" +} +gtkmm_body() { + test_expr '3 \> 3 \| 3 = 3 \& 4 \> 4 \| 3 = 3 \& 4 = 4 \& 5 \>= 5' '1' + test_expr '3 \> 3 \| 3 = 3 \& 4 \> 4 \| 3 = 3 \& 4 = 4 \& 5 \>= 6' '0' + test_expr '3 \> 3 \| 3 = 3 \& 4 \> 4 \| 3 = 3 \& 4 = 3 \& 5 \>= 5' '0' + test_expr '3 \> 3 \| 3 = 3 \& 4 \> 4 \| 3 = 2 \& 4 = 4 \& 5 \>= 5' '0' + test_expr '3 \> 2 \| 3 = 3 \& 4 \> 4 \| 3 = 3 \& 4 = 4 \& 5 \>= 6' '1' + test_expr '3 \> 3 \| 3 = 3 \& 4 \> 3 \| 3 = 3 \& 4 = 4 \& 5 \>= 5' '1' +} + +atf_test_case colon_vs_math +colon_vs_math_head() { + atf_set "descr" "Basic precendence test with the : operator vs. math" +} +colon_vs_math_body() { + test_expr '2 : 4 / 2' '0' + test_expr '4 : 4 % 3' '1' +} + +atf_test_case arithmetic_ops +arithmetic_ops_head() { + atf_set "descr" "Dangling arithemtic operator" +} +arithmetic_ops_body() { + # Begin FreeBSD + atf_expect_fail "the following testcases fail with syntax errors on FreeBSD" + # End FreeBSD + test_expr '.java_wrapper : /' '0' + test_expr '4 : \*' '0' + test_expr '4 : +' '0' + test_expr '4 : -' '0' + test_expr '4 : /' '0' + test_expr '4 : %' '0' +} + +atf_test_case basic_math +basic_math_head() { + atf_set "descr" "Basic math test" +} +basic_math_body() { + test_expr '2 + 4 \* 5' '22' +} + +atf_test_case basic_functional +basic_functional_head() { + atf_set "descr" "Basic functional tests" +} +basic_functional_body() { + test_expr '2' '2' + test_expr '-4' '-4' + test_expr 'hello' 'hello' +} + +atf_test_case compare_ops_precedence +compare_ops_precedence_head() { + atf_set "descr" "Compare operator precendence test" +} +compare_ops_precedence_body() { + test_expr '2 \> 1 \* 17' '0' +} + +atf_test_case compare_ops +compare_ops_head() { + atf_set "descr" "Compare operator tests" +} +compare_ops_body() { + test_expr '2 \!= 5' '1' + test_expr '2 \!= 2' '0' + test_expr '2 \<= 3' '1' + test_expr '2 \<= 2' '1' + test_expr '2 \<= 1' '0' + test_expr '2 \< 3' '1' + test_expr '2 \< 2' '0' + test_expr '2 = 2' '1' + test_expr '2 = 4' '0' + test_expr '2 \>= 1' '1' + test_expr '2 \>= 2' '1' + test_expr '2 \>= 3' '0' + test_expr '2 \> 1' '1' + test_expr '2 \> 2' '0' +} + +atf_test_case multiply +multiply_head() { + atf_set "descr" "Test the multiply operator (PR bin/12838)" +} +multiply_body() { + test_expr '1 \* -1' '-1' + test_expr '2 \> 1 \* 17' '0' +} + +atf_test_case negative +negative_head() { + atf_set "descr" "Test the additive inverse" +} +negative_body() { + test_expr '-1 + 5' '4' + test_expr '- 1 + 5' 'expr: syntax error' + + test_expr '5 + -1' '4' + test_expr '5 + - 1' 'expr: syntax error' + + test_expr '1 - -5' '6' +} + +atf_test_case math_precedence +math_precedence_head() { + atf_set "descr" "More complex math test for precedence" +} +math_precedence_body() { + test_expr '-3 + -1 \* 4 + 3 / -6' '-7' +} + +atf_test_case precedence +precedence_head() { + atf_set "descr" "Test precedence" +} +precedence_body() { + # This is messy but the shell escapes cause that + test_expr 'X1/2/3 : X\\\(.\*[^/]\\\)//\*[^/][^/]\*/\*$ \| . : \\\(.\\\)' '1/2' +} + +atf_test_case regex +regex_head() { + atf_set "descr" "Test proper () returning \1 from a regex" +} +regex_body() { + # This is messy but the shell escapes cause that + test_expr '1/2 : .\*/\\\(.\*\\\)' '2' +} + +atf_init_test_cases() +{ + atf_add_test_case lang + atf_add_test_case overflow + atf_add_test_case gtkmm + atf_add_test_case colon_vs_math + atf_add_test_case arithmetic_ops + atf_add_test_case basic_math + atf_add_test_case basic_functional + atf_add_test_case compare_ops_precedence + atf_add_test_case compare_ops + atf_add_test_case multiply + atf_add_test_case negative + atf_add_test_case math_precedence + atf_add_test_case precedence + atf_add_test_case regex +} diff --git a/contrib/netbsd-tests/bin/pax/t_pax.sh b/contrib/netbsd-tests/bin/pax/t_pax.sh new file mode 100755 index 0000000..63ae7f8 --- /dev/null +++ b/contrib/netbsd-tests/bin/pax/t_pax.sh @@ -0,0 +1,54 @@ +# $NetBSD: t_pax.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $ +# +# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case append +append_head() { + atf_set "descr" "Ensure that appending a file to an archive" \ + "produces the same results as if the file" \ + "had been there during the archive's creation" +} +append_body() { + touch foo bar + + # store both foo and bar into file1.tar + atf_check -s eq:0 -o empty -e empty \ + pax -w -b 512 -x ustar -f file1.tar foo bar + + # store foo into file2.tar, then append bar to file2.tar + atf_check -s eq:0 -o empty -e empty \ + pax -w -b 512 -x ustar -f file2.tar foo + atf_check -s eq:0 -o empty -e empty \ + pax -w -b 512 -x ustar -f file2.tar -a bar + + # ensure that file1.tar and file2.tar are equal + atf_check -s eq:0 -o empty -e empty cmp file1.tar file2.tar +} + +atf_init_test_cases() +{ + atf_add_test_case append +} diff --git a/contrib/netbsd-tests/bin/ps/keywords b/contrib/netbsd-tests/bin/ps/keywords new file mode 100644 index 0000000..3f05f54 --- /dev/null +++ b/contrib/netbsd-tests/bin/ps/keywords @@ -0,0 +1,123 @@ +# $NetBSD: keywords,v 1.2 2014/01/16 04:16:32 mlelstv Exp $ +# +# Table of keywords for use with ps "-o" option. +# +# The first column (keyword) is the name of a keyword. +# +# The second column (header) is the default column header associated +# with the keyword, except if the keyword is an alias, in which case the +# second column is the name of another keyword. +# +# The third column (flag) may be blank, "LJUST", or "ALIAS". "ALIAS" +# means that the keyword is an alias. "LJUST" means that the keyword +# should be displayed in a left-justified column. The default is that +# the keyword should be displayed in a right-justified column. +# +# keyword header flag +# +ktracep KTRACEP +nwchan WCHAN +p_ru P_RU +paddr PADDR +rlink RLINK +%cpu %CPU +%mem %MEM +acflag ACFLG +acflg acflag ALIAS +args command ALIAS +blocked sigmask ALIAS +caught sigcatch ALIAS +comm COMMAND LJUST +command COMMAND LJUST +cpu CPU +cputime time ALIAS +ctime CTIME +egid EGID +egroup EGROUP LJUST +etime ELAPSED +euid EUID +euser EUSER LJUST +f F +flags f ALIAS +gid GID +group GROUP LJUST +groupnames GROUPNAMES LJUST +groups GROUPS LJUST +holdcnt HOLDCNT +ignored sigignore ALIAS +inblk INBLK +inblock inblk ALIAS +jobc JOBC +ktrace KTRACE +laddr LADDR +lid LID +lim LIM +login LOGIN LJUST +logname login ALIAS +lstart STARTED LJUST +lstate STAT LJUST +ltime LTIME +majflt MAJFLT +minflt MINFLT +msgrcv MSGRCV +msgsnd MSGSND +ni nice ALIAS +nice NI +nivcsw NIVCSW +nlwp NLWP +nsignals nsigs ALIAS +nsigs NSIGS +nswap NSWAP +nvcsw NVCSW +oublk OUBLK +oublock oublk ALIAS +pagein PAGEIN +pcpu %cpu ALIAS +pending sig ALIAS +pgid PGID +pid PID +pmem %mem ALIAS +ppid PPID +pri PRI +re RE +rgid RGID +rgroup RGROUP LJUST +rlwp RLWP +rss RSS +rssize rsz ALIAS +rsz RSZ +ruid RUID +ruser RUSER LJUST +sess SESS +sid SID +sig PENDING +sigcatch CAUGHT +sigignore IGNORED +sigmask BLOCKED +sl SL +start STARTED +stat state ALIAS +state STAT LJUST +stime STIME +svgid SVGID +svgroup SVGROUP LJUST +svuid SVUID +svuser SVUSER LJUST +tdev TDEV +time TIME +tpgid TPGID +tsess TSESS +tsiz TSIZ +tt TTY LJUST +tty TTY LJUST +uaddr UADDR +ucomm UCOMM LJUST +uid UID +upr UPR +user USER LJUST +usrpri upr ALIAS +utime UTIME +vsize vsz ALIAS +vsz VSZ +wchan WCHAN LJUST +xstat XSTAT diff --git a/contrib/netbsd-tests/bin/ps/t_ps.sh b/contrib/netbsd-tests/bin/ps/t_ps.sh new file mode 100755 index 0000000..8f8829b --- /dev/null +++ b/contrib/netbsd-tests/bin/ps/t_ps.sh @@ -0,0 +1,404 @@ +# $NetBSD: t_ps.sh,v 1.2 2014/01/16 04:16:32 mlelstv Exp $ +# +# Copyright (c) 2007 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# the implementation of "ps" to test +: ${TEST_PS:="ps"} +# tab and newline characters +tab="$(printf '\t')" +# nl="$(printf '\n')" doesn't work +nl=' +' + +# +# Parse the "keywords" file into a load of shell variables +# +setup_keywords() +{ + # Set variables representing the header text + # for all normal keywords (except aliases), and + # for regular expressions to match the text in left- or + # right-justified columns. + # For example, head_text_p_cpu="%CPU" head_regexp_p_cpu=" *%CPU". + while read keyword heading flag + do + case "$keyword" in + ''|\#*) continue + ;; + esac + [ x"$flag" = x"ALIAS" ] && continue + kvar="${keyword}" + case "${keyword}" in + %*) kvar="p_${keyword#%}" + ;; + esac + eval head_text_${kvar}=\'"${heading}"\' + case "${flag}" in + '') # right justified + eval head_regexp_${kvar}=\'" *${heading}"\' + ;; + LJUST) # left justified + eval head_regexp_${kvar}=\'"${heading} *"\' + ;; + *) atf_fail "unknown flag in keywords" + ;; + esac + done <"$(atf_get_srcdir)/keywords" + + # Now do the aliases. + while read keyword heading flag + do + case "$keyword" in + ''|\#*) continue + ;; + esac + [ x"$flag" != x"ALIAS" ] && continue + kvar="${keyword}" + avar="${heading}" + case "${keyword}" in + %*) kvar="p_${keyword#%}" + ;; + esac + case "${heading}" in + %*) avar="p_${heading#%}" + ;; + esac + eval head_text_${kvar}=\"\$head_text_${avar}\" + eval head_regexp_${kvar}=\"\$head_regexp_${avar}\" + done <"$(atf_get_srcdir)/keywords" + + # default sets of keywords + default_keywords='pid tty stat time command' + j_keywords='user pid ppid pgid sess jobc state tt time command' + l_keywords='uid pid ppid cpu pri nice vsz rss wchan state tt time command' + s_keywords='uid pid ppid cpu lid nlwp pri nice vsz rss wchan lstate tt ltime command' + u_keywords='user pid %cpu %mem vsz rss tt state start time command' + v_keywords='pid state time sl re pagein vsz rss lim tsiz %cpu %mem command' +} + +# Convert a list of keywords like "pid comm" to a regexp +# like " *PID COMMAND *" +heading_keywords_to_regexp() +{ + local keywords="$1" + local regexp + regexp="$(echo "$keywords" | \ + sed -E -e 's/\%/p_/g' -e 's/(^| )/\1\$head_regexp_/g')" + eval regexp=\""${regexp}"\" + regexp="^${regexp}\$" + echo "$regexp" +} + +# +# Check that a string matches a regexp; use the specified id +# in error or success messages. +# +check_regexp() { + local id="$1" string="$2" regexp="$3" + if ! expr "$string" : "$regexp" >/dev/null + then + atf_fail "${id}: expected [${regexp}], got [${string}]" + false + fi +} + +# +# Run "ps $args -p $$"; check that only one line is printed, +# without a preceding header line. +# +check_no_heading_line() +{ + local args="$1" + local output="$(eval "${TEST_PS} $args -p $$")" + case "$output" in + *"$nl"*) + local firstline="${output%%${nl}*}" + atf_fail "check_no_heading_line [$args] got [$firstline]" + ;; + *) + ;; + esac +} + +# +# Run "ps $args"; check that the heading matches the expected regexp. +# +check_heading_regexp() +{ + args="$1" + regexp="$2" + actual="$( eval "${TEST_PS} $args" | sed -e 1q )" + check_regexp "heading [$args]" "${actual}" "${regexp}" +} + +# +# Run "ps $args"; check that the heading matches a regexp constructed +# from the specified keywords. +# +check_heading_keywords() +{ + args="$1" + keywords="$2" + check_heading_regexp "$args" "$(heading_keywords_to_regexp "$keywords")" +} + +# +# Try several variations on "ps $flag", "ps -$flag", etc., +# and check that the heading always has the correct keywords. +# +check_heading_variations() +{ + flag="$1" + keywords="$2" + for args in "$flag" "-$flag" "-$flag$flag -$flag"; do + check_heading_keywords "$args" "$keywords" + done +} + +atf_test_case default_columns +default_columns_head() +{ + atf_set "descr" "Checks that the default set of columns is correct" \ + "and also check that the columns printed by the -j," \ + "-l, -s, -u and -v flags alone are correct" +} +default_columns_body() +{ + setup_keywords + check_heading_keywords '' "$default_keywords" + check_heading_variations 'j' "$j_keywords" + check_heading_variations 'l' "$l_keywords" + check_heading_variations 's' "$s_keywords" + check_heading_variations 'u' "$u_keywords" + check_heading_variations 'v' "$v_keywords" +} + +atf_test_case minus_O +minus_O_head() +{ + atf_set "descr" "Checks that 'ps -O foo' inserts columns just after" \ + "the pid column" +} +minus_O_body() +{ + setup_keywords + check_heading_keywords '-O %cpu,%mem' \ + "$(echo "${default_keywords}" | sed -e 's/pid/pid %cpu %mem/')" + check_heading_keywords '-O %cpu -O %mem' \ + "$(echo "${default_keywords}" | sed -e 's/pid/pid %cpu %mem/')" + check_heading_keywords '-O%cpu -O%mem' \ + "$(echo "${default_keywords}" | sed -e 's/pid/pid %cpu %mem/')" +} + +atf_test_case minus_o +minus_o_head() +{ + atf_set "descr" "Checks simple cases of 'ps -o foo' to control which" \ + "columns are printed; this does not test header" \ + "overriding via 'ps -o foo=BAR'" +} +minus_o_body() +{ + setup_keywords + # Keywords for "-o name" override the default display + check_heading_keywords '-o pid,%cpu,%mem' \ + "pid %cpu %mem" + check_heading_keywords '-o pid -o %cpu,%mem' \ + "pid %cpu %mem" + check_heading_keywords '-opid -o %cpu,%mem' \ + "pid %cpu %mem" + # Space works like comma + check_heading_keywords '-opid -o "%cpu %mem"' \ + "pid %cpu %mem" + # Check missing pid + check_heading_keywords '-o comm' \ + "comm" + # Check pid present but not first + check_heading_keywords '-o comm,pid' \ + "comm pid" +} + +atf_test_case override_heading_simple +override_heading_simple_head() +{ + atf_set "descr" "Tests simple uses of header overriding via" \ + "'ps -o foo=BAR'. This does not test columns " \ + "with null headings, or headings with embedded" \ + "space, ',' or '='." +} +override_heading_simple_body() +{ + setup_keywords + check_heading_regexp '-o pid=PPP -o comm' \ + '^ *PPP '"${head_text_comm}"'$' # no trailing space + check_heading_regexp '-o pid=PPP -o comm=CCC' \ + '^ *PPP CCC$' + check_heading_regexp '-o pid,comm=CCC' \ + '^'"${head_regexp_pid}"' CCC$' + check_heading_regexp '-o pid -o comm=CCC' \ + '^'"${head_regexp_pid}"' CCC$' + # Check missing pid + check_heading_regexp '-o comm=CCC' \ + '^CCC$' + # Check pid present but not first + check_heading_regexp '-o comm=CCC -o pid=PPP' \ + '^CCC *PPP$' + check_heading_regexp '-o comm,pid=PPP' \ + '^'"${head_regexp_comm}"' *PPP$' +} + +atf_test_case override_heading_embedded_specials +override_heading_embedded_specials_head() +{ + atf_set "descr" "Tests header overriding with embedded space," \ + "',' or '='. Everything after the first '='" \ + "is part of the heading." +} +override_heading_embedded_specials_body() +{ + setup_keywords + # Check embedded "," or "=" in override header. + check_heading_regexp '-o comm,pid==' \ + '^'"${head_regexp_comm}"' *=$' + check_heading_regexp '-o comm,pid=,' \ + '^'"${head_regexp_comm}"' *,$' + check_heading_regexp '-o pid=PPP,comm' \ + '^ *PPP,comm$' # not like '-o pid=PPP -o comm' + check_heading_regexp '-o pid=PPP,comm=CCC' \ + '^ *PPP,comm=CCC$' # not like '-o pid=PPP -o comm=CCC' + check_heading_regexp '-o comm,pid=PPP,QQQ' \ + '^'"${head_regexp_comm}"' *PPP,QQQ$' + check_heading_regexp '-o comm,pid=ppid,tty=state' \ + '^'"${head_regexp_comm}"' *ppid,tty=state$' + # Check embedded space or tab in override header. + check_heading_regexp '-o comm,pid="PPP QQQ"' \ + '^'"${head_regexp_comm}"' *PPP QQQ$' + check_heading_regexp '-o comm,pid="PPP${tab}QQQ"' \ + '^'"${head_regexp_comm}"' *PPP'"${tab}"'QQQ$' +} + +atf_test_case override_heading_some_null +override_heading_some_null_head() +{ + atf_set "descr" "Tests simple uses of null column headings" \ + "overriding via 'ps -o foo=BAR -o baz='. This" \ + "does not test the case where all columns have" \ + "null headings." +} +override_heading_some_null_body() +{ + setup_keywords + check_heading_regexp '-o pid=PPP -o comm=' \ + '^ *PPP *$' + check_heading_regexp '-o pid= -o comm=CCC' \ + '^ * CCC$' + check_heading_regexp '-o pid -o comm=' \ + '^'"${head_regexp_pid}"' *$' + # Check missing pid + check_heading_regexp '-o ppid= -o comm=CCC' \ + '^ * CCC$' + check_heading_regexp '-o ppid=PPP -o comm=' \ + '^ *PPP *$' + # Check pid present but not first + check_heading_regexp '-o comm= -o pid=PPP' \ + '^ * PPP$' + check_heading_regexp '-o comm,pid=' \ + '^'"${head_regexp_comm}"' *$' + # A field with a null custom heading retains a minimum width + # derived from the default heading. This does not apply + # to a field with a very short (non-null) custom heading. + # + # We choose "holdcnt" as a column whose width is likely to be + # determined entirely by the header width, because the values + # are likely to be very small. + check_heading_regexp '-o holdcnt -o holdcnt -o holdcnt' \ + '^HOLDCNT HOLDCNT HOLDCNT$' + check_heading_regexp '-o holdcnt -o holdcnt= -o holdcnt' \ + '^HOLDCNT HOLDCNT$' + check_heading_regexp '-o holdcnt -o holdcnt=HH -o holdcnt' \ + '^HOLDCNT HH HOLDCNT$' +} + +atf_test_case override_heading_all_null +override_heading_all_null_head() +{ + atf_set "descr" "Tests the use of 'ps -o foo= -o bar=' (with a" \ + "null heading for every column). The heading" \ + "should not be printed at all in this case." +} +override_heading_all_null_body() +{ + setup_keywords + # A heading with a space is not a null heading, + # so should not be suppressed + check_heading_regexp '-o comm=" "' \ + '^ *$' + # Null headings should be suppressed + check_no_heading_line '-o pid= -o comm=' + check_no_heading_line '-o pid= -o comm=' + # Check missing pid + check_no_heading_line '-o ppid=' + check_no_heading_line '-o comm=' + check_no_heading_line '-o command=' + check_no_heading_line '-o ppid= -o comm=' + check_no_heading_line '-o comm= -o ppid=' + # Check pid present but not first + check_no_heading_line '-o comm= -o pid=' + check_no_heading_line '-o ppid= -o pid= -o command=' +} + +atf_test_case duplicate_column +duplicate_column_head() +{ + atf_set "descr" "Tests the use of -o options to display the" \ + "same column more than once" +} +duplicate_column_body() +{ + setup_keywords + # two custom headers + check_heading_regexp '-o pid=PPP -o pid=QQQ' \ + '^ *PPP *QQQ$' + # one custom header, before and after default header + check_heading_regexp '-o pid=PPP -o pid' \ + '^ *PPP '"${head_regexp_pid}"'$' + check_heading_regexp '-o pid -o pid=QQQ' \ + '^'"${head_regexp_pid}"' *QQQ$' + # custom headers both before and after default header + check_heading_regexp '-o pid=PPP -o pid -o pid=QQQ' \ + '^ *PPP '"${head_regexp_pid}"' *QQQ$' +} + +atf_init_test_cases() { + atf_add_test_case default_columns + atf_add_test_case minus_O + atf_add_test_case minus_o + atf_add_test_case override_heading_simple + atf_add_test_case override_heading_embedded_specials + atf_add_test_case override_heading_some_null + atf_add_test_case override_heading_all_null + atf_add_test_case duplicate_column +} diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_case.out new file mode 100644 index 0000000..4c42055 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_case.out @@ -0,0 +1,8 @@ +before case +before dotcmd +before case +before break +after break, return value: 0 +after case +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_compound.out new file mode 100644 index 0000000..01113ca --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_compound.out @@ -0,0 +1,8 @@ +before case +before dotcmd +compound start +before break +after break, return value: 0 +compound end +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_file.out new file mode 100644 index 0000000..5264020 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_file.out @@ -0,0 +1,6 @@ +before case +before dotcmd +before break +after break, return value: 0 +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_for.out new file mode 100644 index 0000000..e116ee2 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_for.out @@ -0,0 +1,7 @@ +before case +before dotcmd +before for +before break +after for +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_func.out new file mode 100644 index 0000000..906a804 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_func.out @@ -0,0 +1,8 @@ +before case +before dotcmd +before function +before break +after break +after function +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_subshell.out new file mode 100644 index 0000000..073caff --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_subshell.out @@ -0,0 +1,8 @@ +before case +before dotcmd +subshell start +before break +after break, return value: 0 +subshell end +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_until.out new file mode 100644 index 0000000..f47bd43 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_until.out @@ -0,0 +1,7 @@ +before case +before dotcmd +before until +before break +after until +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_while.out new file mode 100644 index 0000000..e9a73f8 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_break_while.out @@ -0,0 +1,7 @@ +before case +before dotcmd +before while +before break +after while +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_case.out new file mode 100644 index 0000000..7919427 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_case.out @@ -0,0 +1,8 @@ +before case +before dotcmd +before case +before continue +after continue, return value: 0 +after case +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_compound.out new file mode 100644 index 0000000..9195e08 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_compound.out @@ -0,0 +1,8 @@ +before case +before dotcmd +compound start +before continue +after continue, return value: 0 +compound end +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_file.out new file mode 100644 index 0000000..100a590 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_file.out @@ -0,0 +1,6 @@ +before case +before dotcmd +before continue +after continue, return value: 0 +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_for.out new file mode 100644 index 0000000..9a078d0 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_for.out @@ -0,0 +1,8 @@ +before case +before dotcmd +before for +before continue +before continue +after for +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_func.out new file mode 100644 index 0000000..6282c89 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_func.out @@ -0,0 +1,8 @@ +before case +before dotcmd +before function +before continue +after continue +after function +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_subshell.out new file mode 100644 index 0000000..b066ab6 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_subshell.out @@ -0,0 +1,8 @@ +before case +before dotcmd +subshell start +before continue +after continue, return value: 0 +subshell end +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_until.out new file mode 100644 index 0000000..afc85b6 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_until.out @@ -0,0 +1,8 @@ +before case +before dotcmd +before until +before continue +before continue +after until +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_while.out new file mode 100644 index 0000000..cb4137d --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_continue_while.out @@ -0,0 +1,8 @@ +before case +before dotcmd +before while +before continue +before continue +after while +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_case.out new file mode 100644 index 0000000..734369d --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_case.out @@ -0,0 +1,6 @@ +before case +before dotcmd +before case +before return +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_compound.out new file mode 100644 index 0000000..2fae84e --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_compound.out @@ -0,0 +1,6 @@ +before case +before dotcmd +compound start +before return +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_file.out new file mode 100644 index 0000000..f97ecc6 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_file.out @@ -0,0 +1,5 @@ +before case +before dotcmd +before return +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_for.out new file mode 100644 index 0000000..d863537 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_for.out @@ -0,0 +1,6 @@ +before case +before dotcmd +before for +before return +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_func.out new file mode 100644 index 0000000..aed8fa4 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_func.out @@ -0,0 +1,7 @@ +before case +before dotcmd +before function +before return +after function +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_subshell.out new file mode 100644 index 0000000..364d245 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_subshell.out @@ -0,0 +1,6 @@ +before case +before dotcmd +subshell start +before return +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_until.out new file mode 100644 index 0000000..daf3811 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_until.out @@ -0,0 +1,6 @@ +before case +before dotcmd +before until +before return +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_while.out new file mode 100644 index 0000000..ef6a676 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/case_return_while.out @@ -0,0 +1,6 @@ +before case +before dotcmd +before while +before return +after dotcmd, return value: 0 +after case diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_case.out new file mode 100644 index 0000000..144bcd6 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_case.out @@ -0,0 +1,8 @@ +compound start +before dotcmd +before case +before break +after break, return value: 0 +after case +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_compound.out new file mode 100644 index 0000000..3fd7b2f --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_compound.out @@ -0,0 +1,8 @@ +compound start +before dotcmd +compound start +before break +after break, return value: 0 +compound end +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_file.out new file mode 100644 index 0000000..5ad5ed3 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_file.out @@ -0,0 +1,6 @@ +compound start +before dotcmd +before break +after break, return value: 0 +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_for.out new file mode 100644 index 0000000..7f03e49 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_for.out @@ -0,0 +1,7 @@ +compound start +before dotcmd +before for +before break +after for +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_func.out new file mode 100644 index 0000000..82e86b3 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_func.out @@ -0,0 +1,8 @@ +compound start +before dotcmd +before function +before break +after break +after function +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_subshell.out new file mode 100644 index 0000000..e26e980 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_subshell.out @@ -0,0 +1,8 @@ +compound start +before dotcmd +subshell start +before break +after break, return value: 0 +subshell end +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_until.out new file mode 100644 index 0000000..34dd25a --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_until.out @@ -0,0 +1,7 @@ +compound start +before dotcmd +before until +before break +after until +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_while.out new file mode 100644 index 0000000..7019045 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_break_while.out @@ -0,0 +1,7 @@ +compound start +before dotcmd +before while +before break +after while +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_case.out new file mode 100644 index 0000000..206548c --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_case.out @@ -0,0 +1,8 @@ +compound start +before dotcmd +before case +before continue +after continue, return value: 0 +after case +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_compound.out new file mode 100644 index 0000000..a8c7efc --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_compound.out @@ -0,0 +1,8 @@ +compound start +before dotcmd +compound start +before continue +after continue, return value: 0 +compound end +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_file.out new file mode 100644 index 0000000..c619ad5 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_file.out @@ -0,0 +1,6 @@ +compound start +before dotcmd +before continue +after continue, return value: 0 +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_for.out new file mode 100644 index 0000000..35b092a --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_for.out @@ -0,0 +1,8 @@ +compound start +before dotcmd +before for +before continue +before continue +after for +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_func.out new file mode 100644 index 0000000..198dbd6 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_func.out @@ -0,0 +1,8 @@ +compound start +before dotcmd +before function +before continue +after continue +after function +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_subshell.out new file mode 100644 index 0000000..1ecaa96 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_subshell.out @@ -0,0 +1,8 @@ +compound start +before dotcmd +subshell start +before continue +after continue, return value: 0 +subshell end +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_until.out new file mode 100644 index 0000000..4a74a8e --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_until.out @@ -0,0 +1,8 @@ +compound start +before dotcmd +before until +before continue +before continue +after until +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_while.out new file mode 100644 index 0000000..b2d939e --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_continue_while.out @@ -0,0 +1,8 @@ +compound start +before dotcmd +before while +before continue +before continue +after while +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_case.out new file mode 100644 index 0000000..995d5b5 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_case.out @@ -0,0 +1,6 @@ +compound start +before dotcmd +before case +before return +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_compound.out new file mode 100644 index 0000000..f6e4858 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_compound.out @@ -0,0 +1,6 @@ +compound start +before dotcmd +compound start +before return +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_file.out new file mode 100644 index 0000000..84347b2 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_file.out @@ -0,0 +1,5 @@ +compound start +before dotcmd +before return +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_for.out new file mode 100644 index 0000000..ec23447 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_for.out @@ -0,0 +1,6 @@ +compound start +before dotcmd +before for +before return +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_func.out new file mode 100644 index 0000000..12798d0 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_func.out @@ -0,0 +1,7 @@ +compound start +before dotcmd +before function +before return +after function +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_subshell.out new file mode 100644 index 0000000..af0ab78 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_subshell.out @@ -0,0 +1,6 @@ +compound start +before dotcmd +subshell start +before return +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_until.out new file mode 100644 index 0000000..a108f50 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_until.out @@ -0,0 +1,6 @@ +compound start +before dotcmd +before until +before return +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_while.out new file mode 100644 index 0000000..ef34c03 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/compound_return_while.out @@ -0,0 +1,6 @@ +compound start +before dotcmd +before while +before return +after dotcmd, return value: 0 +compound end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_case.out new file mode 100644 index 0000000..2f34f10 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_case.out @@ -0,0 +1,6 @@ +before dotcmd +before case +before break +after break, return value: 0 +after case +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_compound.out new file mode 100644 index 0000000..0c7300d --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_compound.out @@ -0,0 +1,6 @@ +before dotcmd +compound start +before break +after break, return value: 0 +compound end +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_file.out new file mode 100644 index 0000000..fb4db19 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_file.out @@ -0,0 +1,4 @@ +before dotcmd +before break +after break, return value: 0 +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_for.out new file mode 100644 index 0000000..66f4452 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_for.out @@ -0,0 +1,5 @@ +before dotcmd +before for +before break +after for +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_func.out new file mode 100644 index 0000000..c5488ab --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_func.out @@ -0,0 +1,6 @@ +before dotcmd +before function +before break +after break +after function +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_subshell.out new file mode 100644 index 0000000..47e2394 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_subshell.out @@ -0,0 +1,6 @@ +before dotcmd +subshell start +before break +after break, return value: 0 +subshell end +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_until.out new file mode 100644 index 0000000..b51ff19 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_until.out @@ -0,0 +1,5 @@ +before dotcmd +before until +before break +after until +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_while.out new file mode 100644 index 0000000..0fd3a83 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_break_while.out @@ -0,0 +1,5 @@ +before dotcmd +before while +before break +after while +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_case.out new file mode 100644 index 0000000..2cf3be6 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_case.out @@ -0,0 +1,6 @@ +before dotcmd +before case +before continue +after continue, return value: 0 +after case +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_compound.out new file mode 100644 index 0000000..7bec420 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_compound.out @@ -0,0 +1,6 @@ +before dotcmd +compound start +before continue +after continue, return value: 0 +compound end +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_file.out new file mode 100644 index 0000000..2f8806c --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_file.out @@ -0,0 +1,4 @@ +before dotcmd +before continue +after continue, return value: 0 +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_for.out new file mode 100644 index 0000000..e8da239 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_for.out @@ -0,0 +1,6 @@ +before dotcmd +before for +before continue +before continue +after for +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_func.out new file mode 100644 index 0000000..da683c0 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_func.out @@ -0,0 +1,6 @@ +before dotcmd +before function +before continue +after continue +after function +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_subshell.out new file mode 100644 index 0000000..388558b --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_subshell.out @@ -0,0 +1,6 @@ +before dotcmd +subshell start +before continue +after continue, return value: 0 +subshell end +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_until.out new file mode 100644 index 0000000..bb0f281 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_until.out @@ -0,0 +1,6 @@ +before dotcmd +before until +before continue +before continue +after until +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_while.out new file mode 100644 index 0000000..6333823 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_continue_while.out @@ -0,0 +1,6 @@ +before dotcmd +before while +before continue +before continue +after while +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_case.out new file mode 100644 index 0000000..4866852 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_case.out @@ -0,0 +1,4 @@ +before dotcmd +before case +before return +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_compound.out new file mode 100644 index 0000000..6b83145 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_compound.out @@ -0,0 +1,4 @@ +before dotcmd +compound start +before return +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_file.out new file mode 100644 index 0000000..2d67423 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_file.out @@ -0,0 +1,3 @@ +before dotcmd +before return +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_for.out new file mode 100644 index 0000000..83f8e00 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_for.out @@ -0,0 +1,4 @@ +before dotcmd +before for +before return +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_func.out new file mode 100644 index 0000000..a0db2c9 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_func.out @@ -0,0 +1,5 @@ +before dotcmd +before function +before return +after function +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_subshell.out new file mode 100644 index 0000000..83cd0e4 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_subshell.out @@ -0,0 +1,4 @@ +before dotcmd +subshell start +before return +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_until.out new file mode 100644 index 0000000..fdf2449 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_until.out @@ -0,0 +1,4 @@ +before dotcmd +before until +before return +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_while.out new file mode 100644 index 0000000..a733aa3 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/file_return_while.out @@ -0,0 +1,4 @@ +before dotcmd +before while +before return +after dotcmd, return value: 0 diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_case.out new file mode 100644 index 0000000..262db24 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_case.out @@ -0,0 +1,5 @@ +before for +before dotcmd +before case +before break +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_compound.out new file mode 100644 index 0000000..418a4de --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_compound.out @@ -0,0 +1,5 @@ +before for +before dotcmd +compound start +before break +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_file.out new file mode 100644 index 0000000..752c95c --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_file.out @@ -0,0 +1,4 @@ +before for +before dotcmd +before break +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_for.out new file mode 100644 index 0000000..20af622 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_for.out @@ -0,0 +1,12 @@ +before for +before dotcmd +before for +before break +after for +after dotcmd, return value: 0 +before dotcmd +before for +before break +after for +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_func.out new file mode 100644 index 0000000..fe0cab4 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_func.out @@ -0,0 +1,5 @@ +before for +before dotcmd +before function +before break +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_subshell.out new file mode 100644 index 0000000..985aab6 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_subshell.out @@ -0,0 +1,10 @@ +before for +before dotcmd +subshell start +before break +after dotcmd, return value: 0 +before dotcmd +subshell start +before break +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_until.out new file mode 100644 index 0000000..b47c901 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_until.out @@ -0,0 +1,12 @@ +before for +before dotcmd +before until +before break +after until +after dotcmd, return value: 0 +before dotcmd +before until +before break +after until +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_while.out new file mode 100644 index 0000000..deb4ceb --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_break_while.out @@ -0,0 +1,12 @@ +before for +before dotcmd +before while +before break +after while +after dotcmd, return value: 0 +before dotcmd +before while +before break +after while +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_case.out new file mode 100644 index 0000000..e989063 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_case.out @@ -0,0 +1,8 @@ +before for +before dotcmd +before case +before continue +before dotcmd +before case +before continue +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_compound.out new file mode 100644 index 0000000..0fd23b6 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_compound.out @@ -0,0 +1,8 @@ +before for +before dotcmd +compound start +before continue +before dotcmd +compound start +before continue +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_file.out new file mode 100644 index 0000000..286bb88 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_file.out @@ -0,0 +1,6 @@ +before for +before dotcmd +before continue +before dotcmd +before continue +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_for.out new file mode 100644 index 0000000..044d5a3 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_for.out @@ -0,0 +1,14 @@ +before for +before dotcmd +before for +before continue +before continue +after for +after dotcmd, return value: 0 +before dotcmd +before for +before continue +before continue +after for +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_func.out new file mode 100644 index 0000000..a0cc6cc --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_func.out @@ -0,0 +1,8 @@ +before for +before dotcmd +before function +before continue +before dotcmd +before function +before continue +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_subshell.out new file mode 100644 index 0000000..f1ae7aa --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_subshell.out @@ -0,0 +1,10 @@ +before for +before dotcmd +subshell start +before continue +after dotcmd, return value: 0 +before dotcmd +subshell start +before continue +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_until.out new file mode 100644 index 0000000..b1c4147 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_until.out @@ -0,0 +1,14 @@ +before for +before dotcmd +before until +before continue +before continue +after until +after dotcmd, return value: 0 +before dotcmd +before until +before continue +before continue +after until +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_while.out new file mode 100644 index 0000000..f8e5c5d --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_continue_while.out @@ -0,0 +1,14 @@ +before for +before dotcmd +before while +before continue +before continue +after while +after dotcmd, return value: 0 +before dotcmd +before while +before continue +before continue +after while +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_case.out new file mode 100644 index 0000000..24b7145 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_case.out @@ -0,0 +1,10 @@ +before for +before dotcmd +before case +before return +after dotcmd, return value: 0 +before dotcmd +before case +before return +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_compound.out new file mode 100644 index 0000000..30b4dac --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_compound.out @@ -0,0 +1,10 @@ +before for +before dotcmd +compound start +before return +after dotcmd, return value: 0 +before dotcmd +compound start +before return +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_file.out new file mode 100644 index 0000000..8855562 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_file.out @@ -0,0 +1,8 @@ +before for +before dotcmd +before return +after dotcmd, return value: 0 +before dotcmd +before return +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_for.out new file mode 100644 index 0000000..52a72a9 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_for.out @@ -0,0 +1,10 @@ +before for +before dotcmd +before for +before return +after dotcmd, return value: 0 +before dotcmd +before for +before return +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_func.out new file mode 100644 index 0000000..4f0fee2 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_func.out @@ -0,0 +1,12 @@ +before for +before dotcmd +before function +before return +after function +after dotcmd, return value: 0 +before dotcmd +before function +before return +after function +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_subshell.out new file mode 100644 index 0000000..4b8f36c --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_subshell.out @@ -0,0 +1,10 @@ +before for +before dotcmd +subshell start +before return +after dotcmd, return value: 0 +before dotcmd +subshell start +before return +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_until.out new file mode 100644 index 0000000..3eaf9df --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_until.out @@ -0,0 +1,10 @@ +before for +before dotcmd +before until +before return +after dotcmd, return value: 0 +before dotcmd +before until +before return +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_while.out new file mode 100644 index 0000000..8cbad95 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/for_return_while.out @@ -0,0 +1,10 @@ +before for +before dotcmd +before while +before return +after dotcmd, return value: 0 +before dotcmd +before while +before return +after dotcmd, return value: 0 +after for diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_case.out new file mode 100644 index 0000000..7373371 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_case.out @@ -0,0 +1,8 @@ +before function +before dotcmd +before case +before break +after break, return value: 0 +after case +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_compound.out new file mode 100644 index 0000000..e87b4a2 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_compound.out @@ -0,0 +1,8 @@ +before function +before dotcmd +compound start +before break +after break, return value: 0 +compound end +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_file.out new file mode 100644 index 0000000..cf14422 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_file.out @@ -0,0 +1,6 @@ +before function +before dotcmd +before break +after break, return value: 0 +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_for.out new file mode 100644 index 0000000..c385348 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_for.out @@ -0,0 +1,7 @@ +before function +before dotcmd +before for +before break +after for +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_func.out new file mode 100644 index 0000000..5c1c4c8 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_func.out @@ -0,0 +1,8 @@ +before function +before dotcmd +before function +before break +after break +after function +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_subshell.out new file mode 100644 index 0000000..affe3e4 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_subshell.out @@ -0,0 +1,8 @@ +before function +before dotcmd +subshell start +before break +after break, return value: 0 +subshell end +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_until.out new file mode 100644 index 0000000..b0f942a --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_until.out @@ -0,0 +1,7 @@ +before function +before dotcmd +before until +before break +after until +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_while.out new file mode 100644 index 0000000..d687aa7 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_break_while.out @@ -0,0 +1,7 @@ +before function +before dotcmd +before while +before break +after while +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_case.out new file mode 100644 index 0000000..b1ad4be --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_case.out @@ -0,0 +1,8 @@ +before function +before dotcmd +before case +before continue +after continue, return value: 0 +after case +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_compound.out new file mode 100644 index 0000000..d6a5edd --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_compound.out @@ -0,0 +1,8 @@ +before function +before dotcmd +compound start +before continue +after continue, return value: 0 +compound end +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_file.out new file mode 100644 index 0000000..f300d6a --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_file.out @@ -0,0 +1,6 @@ +before function +before dotcmd +before continue +after continue, return value: 0 +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_for.out new file mode 100644 index 0000000..d46095d --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_for.out @@ -0,0 +1,8 @@ +before function +before dotcmd +before for +before continue +before continue +after for +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_func.out new file mode 100644 index 0000000..3ff73a2 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_func.out @@ -0,0 +1,8 @@ +before function +before dotcmd +before function +before continue +after continue +after function +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_subshell.out new file mode 100644 index 0000000..fd295aa --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_subshell.out @@ -0,0 +1,8 @@ +before function +before dotcmd +subshell start +before continue +after continue, return value: 0 +subshell end +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_until.out new file mode 100644 index 0000000..7a65083 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_until.out @@ -0,0 +1,8 @@ +before function +before dotcmd +before until +before continue +before continue +after until +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_while.out new file mode 100644 index 0000000..6ecbe82 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_continue_while.out @@ -0,0 +1,8 @@ +before function +before dotcmd +before while +before continue +before continue +after while +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_case.out new file mode 100644 index 0000000..8f0c094 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_case.out @@ -0,0 +1,6 @@ +before function +before dotcmd +before case +before return +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_compound.out new file mode 100644 index 0000000..e3d8670 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_compound.out @@ -0,0 +1,6 @@ +before function +before dotcmd +compound start +before return +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_file.out new file mode 100644 index 0000000..95e3415 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_file.out @@ -0,0 +1,5 @@ +before function +before dotcmd +before return +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_for.out new file mode 100644 index 0000000..511cc39 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_for.out @@ -0,0 +1,6 @@ +before function +before dotcmd +before for +before return +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_func.out new file mode 100644 index 0000000..a87d3a7 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_func.out @@ -0,0 +1,7 @@ +before function +before dotcmd +before function +before return +after function +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_subshell.out new file mode 100644 index 0000000..fdb37b2 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_subshell.out @@ -0,0 +1,6 @@ +before function +before dotcmd +subshell start +before return +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_until.out new file mode 100644 index 0000000..08b45be --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_until.out @@ -0,0 +1,6 @@ +before function +before dotcmd +before until +before return +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_while.out new file mode 100644 index 0000000..27fbcaf --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/func_return_while.out @@ -0,0 +1,6 @@ +before function +before dotcmd +before while +before return +after dotcmd +after function diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_case.out new file mode 100644 index 0000000..155daea --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_case.out @@ -0,0 +1,8 @@ +subshell start +before dotcmd +before case +before break +after break, return value: 0 +after case +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_compound.out new file mode 100644 index 0000000..a643ac0 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_compound.out @@ -0,0 +1,8 @@ +subshell start +before dotcmd +compound start +before break +after break, return value: 0 +compound end +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_file.out new file mode 100644 index 0000000..2556d89 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_file.out @@ -0,0 +1,6 @@ +subshell start +before dotcmd +before break +after break, return value: 0 +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_for.out new file mode 100644 index 0000000..27040a9 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_for.out @@ -0,0 +1,7 @@ +subshell start +before dotcmd +before for +before break +after for +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_func.out new file mode 100644 index 0000000..83ec062 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_func.out @@ -0,0 +1,8 @@ +subshell start +before dotcmd +before function +before break +after break +after function +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_subshell.out new file mode 100644 index 0000000..8a53ac5 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_subshell.out @@ -0,0 +1,8 @@ +subshell start +before dotcmd +subshell start +before break +after break, return value: 0 +subshell end +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_until.out new file mode 100644 index 0000000..a31fa5b --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_until.out @@ -0,0 +1,7 @@ +subshell start +before dotcmd +before until +before break +after until +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_while.out new file mode 100644 index 0000000..42eb970 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_break_while.out @@ -0,0 +1,7 @@ +subshell start +before dotcmd +before while +before break +after while +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_case.out new file mode 100644 index 0000000..4d74b7b --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_case.out @@ -0,0 +1,8 @@ +subshell start +before dotcmd +before case +before continue +after continue, return value: 0 +after case +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_compound.out new file mode 100644 index 0000000..4328df3 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_compound.out @@ -0,0 +1,8 @@ +subshell start +before dotcmd +compound start +before continue +after continue, return value: 0 +compound end +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_file.out new file mode 100644 index 0000000..a4a6e4a --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_file.out @@ -0,0 +1,6 @@ +subshell start +before dotcmd +before continue +after continue, return value: 0 +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_for.out new file mode 100644 index 0000000..e829889 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_for.out @@ -0,0 +1,8 @@ +subshell start +before dotcmd +before for +before continue +before continue +after for +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_func.out new file mode 100644 index 0000000..e0ead4c --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_func.out @@ -0,0 +1,8 @@ +subshell start +before dotcmd +before function +before continue +after continue +after function +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_subshell.out new file mode 100644 index 0000000..dfcdfb4 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_subshell.out @@ -0,0 +1,8 @@ +subshell start +before dotcmd +subshell start +before continue +after continue, return value: 0 +subshell end +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_until.out new file mode 100644 index 0000000..66e8f9f --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_until.out @@ -0,0 +1,8 @@ +subshell start +before dotcmd +before until +before continue +before continue +after until +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_while.out new file mode 100644 index 0000000..f1c83f4 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_continue_while.out @@ -0,0 +1,8 @@ +subshell start +before dotcmd +before while +before continue +before continue +after while +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_case.out new file mode 100644 index 0000000..008d939 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_case.out @@ -0,0 +1,6 @@ +subshell start +before dotcmd +before case +before return +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_compound.out new file mode 100644 index 0000000..bdab231 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_compound.out @@ -0,0 +1,6 @@ +subshell start +before dotcmd +compound start +before return +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_file.out new file mode 100644 index 0000000..43d011d --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_file.out @@ -0,0 +1,5 @@ +subshell start +before dotcmd +before return +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_for.out new file mode 100644 index 0000000..7cfed89 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_for.out @@ -0,0 +1,6 @@ +subshell start +before dotcmd +before for +before return +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_func.out new file mode 100644 index 0000000..b695c53 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_func.out @@ -0,0 +1,7 @@ +subshell start +before dotcmd +before function +before return +after function +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_subshell.out new file mode 100644 index 0000000..c5ccf59 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_subshell.out @@ -0,0 +1,6 @@ +subshell start +before dotcmd +subshell start +before return +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_until.out new file mode 100644 index 0000000..64737ad --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_until.out @@ -0,0 +1,6 @@ +subshell start +before dotcmd +before until +before return +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_while.out new file mode 100644 index 0000000..de520c4 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/subshell_return_while.out @@ -0,0 +1,6 @@ +subshell start +before dotcmd +before while +before return +after dotcmd, return value: 0 +subshell end diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_case.out new file mode 100644 index 0000000..f0483b4 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_case.out @@ -0,0 +1,5 @@ +before until +before dotcmd +before case +before break +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_compound.out new file mode 100644 index 0000000..a5e37ba --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_compound.out @@ -0,0 +1,5 @@ +before until +before dotcmd +compound start +before break +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_file.out new file mode 100644 index 0000000..a2fde4d --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_file.out @@ -0,0 +1,4 @@ +before until +before dotcmd +before break +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_for.out new file mode 100644 index 0000000..8b3faf5 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_for.out @@ -0,0 +1,12 @@ +before until +before dotcmd +before for +before break +after for +after dotcmd, return value: 0 +before dotcmd +before for +before break +after for +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_func.out new file mode 100644 index 0000000..a83ce2b --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_func.out @@ -0,0 +1,5 @@ +before until +before dotcmd +before function +before break +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_subshell.out new file mode 100644 index 0000000..008d30d --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_subshell.out @@ -0,0 +1,10 @@ +before until +before dotcmd +subshell start +before break +after dotcmd, return value: 0 +before dotcmd +subshell start +before break +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_until.out new file mode 100644 index 0000000..05fb94a --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_until.out @@ -0,0 +1,12 @@ +before until +before dotcmd +before until +before break +after until +after dotcmd, return value: 0 +before dotcmd +before until +before break +after until +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_while.out new file mode 100644 index 0000000..6ae1f9c --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_break_while.out @@ -0,0 +1,12 @@ +before until +before dotcmd +before while +before break +after while +after dotcmd, return value: 0 +before dotcmd +before while +before break +after while +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_case.out new file mode 100644 index 0000000..40028fb --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_case.out @@ -0,0 +1,8 @@ +before until +before dotcmd +before case +before continue +before dotcmd +before case +before continue +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_compound.out new file mode 100644 index 0000000..3641e1e --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_compound.out @@ -0,0 +1,8 @@ +before until +before dotcmd +compound start +before continue +before dotcmd +compound start +before continue +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_file.out new file mode 100644 index 0000000..c9f5193 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_file.out @@ -0,0 +1,6 @@ +before until +before dotcmd +before continue +before dotcmd +before continue +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_for.out new file mode 100644 index 0000000..fd58240 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_for.out @@ -0,0 +1,14 @@ +before until +before dotcmd +before for +before continue +before continue +after for +after dotcmd, return value: 0 +before dotcmd +before for +before continue +before continue +after for +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_func.out new file mode 100644 index 0000000..6beb163 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_func.out @@ -0,0 +1,8 @@ +before until +before dotcmd +before function +before continue +before dotcmd +before function +before continue +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_subshell.out new file mode 100644 index 0000000..534509e --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_subshell.out @@ -0,0 +1,10 @@ +before until +before dotcmd +subshell start +before continue +after dotcmd, return value: 0 +before dotcmd +subshell start +before continue +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_until.out new file mode 100644 index 0000000..ddfeb27 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_until.out @@ -0,0 +1,14 @@ +before until +before dotcmd +before until +before continue +before continue +after until +after dotcmd, return value: 0 +before dotcmd +before until +before continue +before continue +after until +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_while.out new file mode 100644 index 0000000..5707821 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_continue_while.out @@ -0,0 +1,14 @@ +before until +before dotcmd +before while +before continue +before continue +after while +after dotcmd, return value: 0 +before dotcmd +before while +before continue +before continue +after while +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_case.out new file mode 100644 index 0000000..70dd420 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_case.out @@ -0,0 +1,10 @@ +before until +before dotcmd +before case +before return +after dotcmd, return value: 0 +before dotcmd +before case +before return +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_compound.out new file mode 100644 index 0000000..145d2c5 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_compound.out @@ -0,0 +1,10 @@ +before until +before dotcmd +compound start +before return +after dotcmd, return value: 0 +before dotcmd +compound start +before return +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_file.out new file mode 100644 index 0000000..5b0adb1 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_file.out @@ -0,0 +1,8 @@ +before until +before dotcmd +before return +after dotcmd, return value: 0 +before dotcmd +before return +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_for.out new file mode 100644 index 0000000..b113e8c --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_for.out @@ -0,0 +1,10 @@ +before until +before dotcmd +before for +before return +after dotcmd, return value: 0 +before dotcmd +before for +before return +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_func.out new file mode 100644 index 0000000..1ab16ab --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_func.out @@ -0,0 +1,12 @@ +before until +before dotcmd +before function +before return +after function +after dotcmd, return value: 0 +before dotcmd +before function +before return +after function +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_subshell.out new file mode 100644 index 0000000..d444631 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_subshell.out @@ -0,0 +1,10 @@ +before until +before dotcmd +subshell start +before return +after dotcmd, return value: 0 +before dotcmd +subshell start +before return +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_until.out new file mode 100644 index 0000000..3998017 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_until.out @@ -0,0 +1,10 @@ +before until +before dotcmd +before until +before return +after dotcmd, return value: 0 +before dotcmd +before until +before return +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_while.out new file mode 100644 index 0000000..9b140cf --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/until_return_while.out @@ -0,0 +1,10 @@ +before until +before dotcmd +before while +before return +after dotcmd, return value: 0 +before dotcmd +before while +before return +after dotcmd, return value: 0 +after until diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_case.out new file mode 100644 index 0000000..1b0731f --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_case.out @@ -0,0 +1,5 @@ +before while +before dotcmd +before case +before break +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_compound.out new file mode 100644 index 0000000..05c23eb --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_compound.out @@ -0,0 +1,5 @@ +before while +before dotcmd +compound start +before break +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_file.out new file mode 100644 index 0000000..cb70ae1 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_file.out @@ -0,0 +1,4 @@ +before while +before dotcmd +before break +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_for.out new file mode 100644 index 0000000..b94eac1 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_for.out @@ -0,0 +1,12 @@ +before while +before dotcmd +before for +before break +after for +after dotcmd, return value: 0 +before dotcmd +before for +before break +after for +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_func.out new file mode 100644 index 0000000..7d54c15 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_func.out @@ -0,0 +1,5 @@ +before while +before dotcmd +before function +before break +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_subshell.out new file mode 100644 index 0000000..234cd66 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_subshell.out @@ -0,0 +1,10 @@ +before while +before dotcmd +subshell start +before break +after dotcmd, return value: 0 +before dotcmd +subshell start +before break +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_until.out new file mode 100644 index 0000000..f360230 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_until.out @@ -0,0 +1,12 @@ +before while +before dotcmd +before until +before break +after until +after dotcmd, return value: 0 +before dotcmd +before until +before break +after until +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_while.out new file mode 100644 index 0000000..451b0a2 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_break_while.out @@ -0,0 +1,12 @@ +before while +before dotcmd +before while +before break +after while +after dotcmd, return value: 0 +before dotcmd +before while +before break +after while +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_case.out new file mode 100644 index 0000000..d7f412c --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_case.out @@ -0,0 +1,8 @@ +before while +before dotcmd +before case +before continue +before dotcmd +before case +before continue +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_compound.out new file mode 100644 index 0000000..0019047 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_compound.out @@ -0,0 +1,8 @@ +before while +before dotcmd +compound start +before continue +before dotcmd +compound start +before continue +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_file.out new file mode 100644 index 0000000..9070dea --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_file.out @@ -0,0 +1,6 @@ +before while +before dotcmd +before continue +before dotcmd +before continue +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_for.out new file mode 100644 index 0000000..98696ee --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_for.out @@ -0,0 +1,14 @@ +before while +before dotcmd +before for +before continue +before continue +after for +after dotcmd, return value: 0 +before dotcmd +before for +before continue +before continue +after for +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_func.out new file mode 100644 index 0000000..77efc2c --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_func.out @@ -0,0 +1,8 @@ +before while +before dotcmd +before function +before continue +before dotcmd +before function +before continue +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_subshell.out new file mode 100644 index 0000000..b4106a1 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_subshell.out @@ -0,0 +1,10 @@ +before while +before dotcmd +subshell start +before continue +after dotcmd, return value: 0 +before dotcmd +subshell start +before continue +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_until.out new file mode 100644 index 0000000..7f893a0 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_until.out @@ -0,0 +1,14 @@ +before while +before dotcmd +before until +before continue +before continue +after until +after dotcmd, return value: 0 +before dotcmd +before until +before continue +before continue +after until +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_while.out new file mode 100644 index 0000000..317be17 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_continue_while.out @@ -0,0 +1,14 @@ +before while +before dotcmd +before while +before continue +before continue +after while +after dotcmd, return value: 0 +before dotcmd +before while +before continue +before continue +after while +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_case.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_case.out new file mode 100644 index 0000000..abb6a4a --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_case.out @@ -0,0 +1,10 @@ +before while +before dotcmd +before case +before return +after dotcmd, return value: 0 +before dotcmd +before case +before return +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_compound.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_compound.out new file mode 100644 index 0000000..b37418b --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_compound.out @@ -0,0 +1,10 @@ +before while +before dotcmd +compound start +before return +after dotcmd, return value: 0 +before dotcmd +compound start +before return +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_file.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_file.out new file mode 100644 index 0000000..1c4791e --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_file.out @@ -0,0 +1,8 @@ +before while +before dotcmd +before return +after dotcmd, return value: 0 +before dotcmd +before return +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_for.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_for.out new file mode 100644 index 0000000..0569d6f --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_for.out @@ -0,0 +1,10 @@ +before while +before dotcmd +before for +before return +after dotcmd, return value: 0 +before dotcmd +before for +before return +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_func.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_func.out new file mode 100644 index 0000000..cb5a308 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_func.out @@ -0,0 +1,12 @@ +before while +before dotcmd +before function +before return +after function +after dotcmd, return value: 0 +before dotcmd +before function +before return +after function +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_subshell.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_subshell.out new file mode 100644 index 0000000..161a227 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_subshell.out @@ -0,0 +1,10 @@ +before while +before dotcmd +subshell start +before return +after dotcmd, return value: 0 +before dotcmd +subshell start +before return +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_until.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_until.out new file mode 100644 index 0000000..d84a5f7 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_until.out @@ -0,0 +1,10 @@ +before while +before dotcmd +before until +before return +after dotcmd, return value: 0 +before dotcmd +before until +before return +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_while.out b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_while.out new file mode 100644 index 0000000..4eeaaa9 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/out/while_return_while.out @@ -0,0 +1,10 @@ +before while +before dotcmd +before while +before return +after dotcmd, return value: 0 +before dotcmd +before while +before return +after dotcmd, return value: 0 +after while diff --git a/contrib/netbsd-tests/bin/sh/dotcmd/scoped_command b/contrib/netbsd-tests/bin/sh/dotcmd/scoped_command new file mode 100755 index 0000000..36e712b --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/dotcmd/scoped_command @@ -0,0 +1,150 @@ +#!/bin/sh +# +# $NetBSD: scoped_command,v 1.2 2016/03/27 14:57:50 christos Exp $ +# +# Copyright (c) 2014 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jarmo Jaakkola. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +: ${TEST_SH:=/bin/sh} + +sane_sh() +{ + set -- ${TEST_SH} + case "$#" in + (0) set /bin/sh;; + (1|2) ;; + (*) set "$1";; # Just ignore options if we cannot make them work + esac + + case "$1" in + /*) TEST_SH="$1${2+ }$2";; + ./*) TEST_SH="${PWD}${1#.}${2+ }$2";; + */*) TEST_SH="${PWD}/$1${2+ }$2";; + *) TEST_SH="$( command -v "$1" )${2+ }$2";; + esac +} + +sane_sh + +set -e + +# USAGE: +# scoped_command scope cmd msg var_suffix +# +# Write to stdout a piece of Bourne Shell script with _cmd_ in specific +# _scope_. The execution of _cmd_ is bracketed by prints of "before _msg_" +# and "after _msg_, return value ${?}". If the generated script uses +# variables, __var_suffix_ is appended to their names to allow nesting of +# scripts generated this way. +# +# _scope_ should be one of: case, compound, file, for, func, subshell, +# until, while. +# _cmd_ is the command line to execute. Remember proper quoting! +# _msg_ is text that will be used inside single quotes. +# _var_suffix_ is a syntactically valid identifier name. + +# don't rely on command lists (';') +cmd="echo 'before ${3}' +${2} +echo 'after ${3}, return value:' ${?}" + +echo "#!${TEST_SH}" + +[ 'func' = "${1}" ] && cat </dev/null + then + # 16 bits or less, or hex unsupported, just give up... + return + fi + test $( ${TEST_SH} -c 'echo $(( 0x1FFFF ))' ) = 131071 || return + + # when attempting to exceed the number of available bits + # the shell may react in any of 3 (rational) ways + # 1. syntax error (maybe even core dump...) and fail + # 2. represent a positive number input as negative value + # 3. keep the number positive, but not the value expected + # (perhaps pegged at the max possible value) + # any of those may be accompanied by a message to stderr + + # Must check all 3 possibilities for each plausible size + # Tests do not use 0x8000... because that value can have weird + # other side effects that are not relevant to discover here. + # But we do want to try and force the sign bit set. + + if ! ${TEST_SH} -c ': $(( 0xC0000000 ))' 2>/dev/null + then + # proobably shell detected overflow and complained + ARITH_BITS=32 + return + fi + if ${TEST_SH} 2>/dev/null \ + -c 'case $(( 0xC0000000 )); in (-*) exit 0;; esac; exit 1' + then + ARITH_BITS=32 + return + fi + if ${TEST_SH} -c '[ $(( 0xC0000000 )) != 3221225472 ]' 2>/dev/null + then + ARITH_BITS=32 + return + fi + + if ! ${TEST_SH} -c ': $(( 0xC000000000000000 ))' 2>/dev/null + then + ARITH_BITS=64 + return + fi + if ${TEST_SH} 2>/dev/null \ + -c 'case $(( 0xC000000000000000 )); in (-*) exit 0;; esac; exit 1' + then + ARITH_BITS=64 + return + fi + if ${TEST_SH} 2>/dev/null \ + -c '[ $((0xC000000000000000)) != 13835058055282163712 ]' + then + ARITH_BITS=64 + return + fi + + if ${TEST_SH} 2>/dev/null -c \ + '[ $((0x123456781234567812345678)) = 5634002657842756053938493048 ]' + then + # just assume... (for now anyway, revisit when it happens...) + ARITH_BITS=96 + return + fi +} + +atf_test_case constants +constants_head() +{ + atf_set "descr" "Tests that arithmetic expansion can handle constants" +} +constants_body() +{ + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $((0x0))' + + # atf_expect_fail "PR bin/50959" + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $((0X0))' + # atf_expect_pass + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $((000))' + + atf_check -s exit:0 -o inline:'1\n' -e empty \ + ${TEST_SH} -c 'echo $(( 000000001 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty \ + ${TEST_SH} -c 'echo $(( 0x000000 ))' + + atf_check -s exit:0 -o inline:'99999\n' -e empty \ + ${TEST_SH} -c 'echo $((99999))' + + [ ${ARITH_BITS} -gt 44 ] && + atf_check -s exit:0 -o inline:'9191919191919\n' -e empty \ + ${TEST_SH} -c 'echo $((9191919191919))' + + atf_check -s exit:0 -o inline:'13\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xD ))' + atf_check -s exit:0 -o inline:'11\n' -e empty ${TEST_SH} -c \ + 'echo $(( 013 ))' + atf_check -s exit:0 -o inline:'7\n' -e empty ${TEST_SH} -c \ + 'x=7;echo $(($x))' + atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \ + 'x=9;echo $((x))' + + atf_check -s exit:0 -o inline:'11\n' -e empty \ + ${TEST_SH} -c 'x=0xB; echo $(( $x ))' + atf_check -s exit:0 -o inline:'27\n' -e empty \ + ${TEST_SH} -c 'x=0X1B; echo $(( x ))' + atf_check -s exit:0 -o inline:'27\n' -e empty \ + ${TEST_SH} -c 'X=033; echo $(( $X ))' + atf_check -s exit:0 -o inline:'219\n' -e empty \ + ${TEST_SH} -c 'X=0333; echo $(( X ))' + atf_check -s exit:0 -o inline:'0\n' -e empty \ + ${TEST_SH} -c 'NULL=; echo $(( NULL ))' + + # Not clear if this is 0, nothing, or an error, so omit for now + # atf_check -s exit:0 -o inline:'0\n' -e empty \ + # ${TEST_SH} -c 'echo $(( ))' + + # not clear whether this should return 0 or an error, so omit for now + # atf_check -s exit:0 -o inline:'0\n' -e empty \ + # ${TEST_SH} -c 'echo $(( UNDEFINED_VAR ))' +} + + +atf_test_case do_unary_plus +do_unary_plus_head() +{ + atf_set "descr" "Tests that unary plus works as expected" +} +do_unary_plus_body() +{ + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( +0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( +1 ))' + atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \ + 'echo $(( + 6 ))' + atf_check -s exit:0 -o inline:'4321\n' -e empty ${TEST_SH} -c \ + 'echo $(( + 4321 ))' + atf_check -s exit:0 -o inline:'17185\n' -e empty ${TEST_SH} -c \ + 'echo $(( + 0x4321 ))' +} + +atf_test_case do_unary_minus +do_unary_minus_head() +{ + atf_set "descr" "Tests that unary minus works as expected" +} +do_unary_minus_body() +{ + atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \ + 'echo $(( -1 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( - 0 ))' + atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \ + 'echo $(( - 1 ))' + atf_check -s exit:0 -o inline:'-6\n' -e empty ${TEST_SH} -c \ + 'echo $(( - 6 ))' + atf_check -s exit:0 -o inline:'-4321\n' -e empty ${TEST_SH} -c \ + 'echo $(( - 4321 ))' + atf_check -s exit:0 -o inline:'-2257\n' -e empty ${TEST_SH} -c \ + 'echo $(( - 04321 ))' + atf_check -s exit:0 -o inline:'-7\n' -e empty ${TEST_SH} -c \ + 'echo $((-7))' +} + +atf_test_case do_unary_not +do_unary_not_head() +{ + atf_set "descr" "Tests that unary not (boolean) works as expected" +} +do_unary_not_body() +{ + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( ! 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( ! 0 ))' + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( !1234 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( !0xFFFF ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( ! 000000 ))' +} + +atf_test_case do_unary_tilde +do_unary_tilde_head() +{ + atf_set "descr" "Tests that unary not (bitwise) works as expected" +} +do_unary_tilde_body() +{ + # definitely 2's complement arithmetic here... + + atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \ + 'echo $(( ~ 0 ))' + atf_check -s exit:0 -o inline:'-2\n' -e empty ${TEST_SH} -c \ + 'echo $(( ~ 1 ))' + + atf_check -s exit:0 -o inline:'-1235\n' -e empty ${TEST_SH} -c \ + 'echo $(( ~1234 ))' + atf_check -s exit:0 -o inline:'-256\n' -e empty ${TEST_SH} -c \ + 'echo $(( ~0xFF ))' +} + +atf_test_case elementary_add +elementary_add_head() +{ + atf_set "descr" "Tests that simple addition works as expected" +} +elementary_add_body() +{ + # some of these tests actually test unary ops & op precedence... + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 + 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 + 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 + 1 ))' + atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 + 1 ))' + atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \ + 'echo $(( 4 + 6 ))' + atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \ + 'echo $(( 6 + 4 ))' + atf_check -s exit:0 -o inline:'5555\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1234 + 4321 ))' + atf_check -s exit:0 -o inline:'3333\n' -e empty ${TEST_SH} -c \ + 'echo $((1111+2222))' + atf_check -s exit:0 -o inline:'5555\n' -e empty ${TEST_SH} -c \ + 'echo $((+3333+2222))' + atf_check -s exit:0 -o inline:'7777\n' -e empty ${TEST_SH} -c \ + 'echo $((+3333 + +4444))' + atf_check -s exit:0 -o inline:'-7777\n' -e empty ${TEST_SH} -c \ + 'echo -$((+4125+ +3652))' +} + +atf_test_case elementary_sub +elementary_sub_head() +{ + atf_set "descr" "Tests that simple subtraction works as expected" +} +elementary_sub_body() +{ + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 - 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 - 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 - 1 ))' + atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 - 1 ))' + atf_check -s exit:0 -o inline:'488\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1066 - 578 ))' + atf_check -s exit:0 -o inline:'-3662\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2016-5678 ))' + atf_check -s exit:0 -o inline:'-3662\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2016+-5678 ))' + atf_check -s exit:0 -o inline:'-3662\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2016-+5678 ))' + atf_check -s exit:0 -o inline:'-7694\n' -e empty ${TEST_SH} -c \ + 'echo $(( -2016-5678 ))' + atf_check -s exit:0 -o inline:'--1\n' -e empty ${TEST_SH} -c \ + 'echo -$(( -1018 - -1017 ))' +} + +atf_test_case elementary_mul +elementary_mul_head() +{ + atf_set "descr" "Tests that simple multiplication works as expected" +} +elementary_mul_body() +{ + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 * 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 * 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 * 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 * 1 ))' + atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \ + 'echo $(( -1 * 1 ))' + atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 * -1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( -1 * -1 ))' + atf_check -s exit:0 -o inline:'391\n' -e empty ${TEST_SH} -c \ + 'echo $(( 17 * 23 ))' + atf_check -s exit:0 -o inline:'169\n' -e empty ${TEST_SH} -c \ + 'echo $(( 13*13 ))' + atf_check -s exit:0 -o inline:'-11264\n' -e empty ${TEST_SH} -c \ + 'echo $(( -11 *1024 ))' + atf_check -s exit:0 -o inline:'-16983\n' -e empty ${TEST_SH} -c \ + 'echo $(( 17* -999 ))' + atf_check -s exit:0 -o inline:'9309\n' -e empty ${TEST_SH} -c \ + 'echo $(( -29*-321 ))' +} + +atf_test_case elementary_div +elementary_div_head() +{ + atf_set "descr" "Tests that simple division works as expected" +} +elementary_div_body() +{ + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 / 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 / 1 ))' + test ${ARITH_BITS} -ge 38 && + atf_check -s exit:0 -o inline:'99999999999\n' -e empty \ + ${TEST_SH} -c 'echo $(( 99999999999 / 1 ))' + atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2 / 1 ))' + + atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 / 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 / 2 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 / 3 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 / 4 ))' + + atf_check -s exit:0 -o inline:'173\n' -e empty ${TEST_SH} -c \ + 'echo $(( 123456 / 713 ))' + atf_check -s exit:0 -o inline:'13\n' -e empty ${TEST_SH} -c \ + 'echo $(( 169 / 13 ))' +} + +atf_test_case elementary_rem +elementary_rem_head() +{ + atf_set "descr" "Tests that simple modulus works as expected" +} +elementary_rem_body() +{ + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 % 1 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 % 1 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2 % 1 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9999 % 1 ))' + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 % 2 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 % 2 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2 % 2 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xFFFF % 2 ))' + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 % 3 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 % 3 ))' + atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2 % 3 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 % 3 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3123 % 3 ))' + + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9999 % 2 ))' + + atf_check -s exit:0 -o inline:'107\n' -e empty ${TEST_SH} -c \ + 'echo $(( 123456%173 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $((169%13))' +} + +atf_test_case elementary_shl +elementary_shl_head() +{ + atf_set "descr" "Tests that simple shift left works as expected" +} +elementary_shl_body() +{ + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 << 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 << 1 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 << 17 ))' + + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 << 0 ))' + atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 << 1 ))' + atf_check -s exit:0 -o inline:'131072\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 << 17 ))' + + atf_check -s exit:0 -o inline:'2021161080\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x3C3C3C3C << 1 ))' + + test "${ARITH_BITS}" -ge 40 && + atf_check -s exit:0 -o inline:'129354309120\n' -e empty \ + ${TEST_SH} -c 'echo $(( 0x3C3C3C3C << 7 ))' + test "${ARITH_BITS}" -ge 72 && + atf_check -s exit:0 -o inline:'1111145054534149079040\n' \ + -e empty ${TEST_SH} -c 'echo $(( 0x3C3C3C3C << 40 ))' + + return 0 +} + +atf_test_case elementary_shr +elementary_shr_head() +{ + atf_set "descr" "Tests that simple shift right works as expected" +} +elementary_shr_body() +{ + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 >> 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 >> 1 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 >> 17 ))' + + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 >> 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 >> 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2 >> 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 >> 1 ))' + + atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x10 >> 2 ))' + atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \ + 'echo $(( 022 >> 2 ))' + + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 131072 >> 17 ))' + + test ${ARITH_BITS} -ge 40 && + atf_check -s exit:0 -o inline:'8\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x4000000000 >> 35 ))' + test ${ARITH_BITS} -ge 80 && + atf_check -s exit:0 -o inline:'4464\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x93400FACE005C871000 >> 64 ))' + + return 0 +} + +atf_test_case elementary_eq +elementary_eq_head() +{ + atf_set "descr" "Tests that simple equality test works as expected" +} +elementary_eq_body() +{ + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 == 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 == 0000 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 == 0x00 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 == 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'X=30; Y=0x1E; echo $(( X == Y ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x1234 == 4660 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x1234 == 011064 ))' + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 == 1 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 == 0000000000000001 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 == 0x10000000000000 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 == 2 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'X=3; Y=7; echo $(( X == Y ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1234 == 0x4660 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 01234 == 0x11064 ))' +} +atf_test_case elementary_ne +elementary_ne_head() +{ + atf_set "descr" "Tests that simple inequality test works as expected" +} +elementary_ne_body() +{ + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 != 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x71 != 17 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1234 != 01234 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x1234 != 01234 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'X=3; echo $(( X != 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'X=3; Y=0x11; echo $(( X != Y ))' + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 != 3 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 != 0x0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xA != 012 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'X=1; echo $(( X != 1 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'X=0xC; Y=014; echo $(( X != Y ))' +} +atf_test_case elementary_lt +elementary_lt_head() +{ + atf_set "descr" "Tests that simple less than test works as expected" +} +elementary_lt_body() +{ + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 < 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( -1 < 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 < 10 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 100 < 101 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xA1 < 200 ))' + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 < 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 < 0 ))' + + test ${ARITH_BITS} -ge 40 && + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x1BEEFF00D < 0x1FACECAFE ))' + + return 0 +} +atf_test_case elementary_le +elementary_le_head() +{ + atf_set "descr" "Tests that simple less or equal test works as expected" +} +elementary_le_body() +{ + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 <= 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( -1 <= 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 <= 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 <= 10 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 100 <= 101 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xA1 <= 161 ))' + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 <= 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( -100 <= -200 ))' + + test ${ARITH_BITS} -ge 40 && + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'cost=; AUD=; echo $(( $cost 0x2FEEDBABE <= $AUD 12866927294 ))' + + return 0 +} +atf_test_case elementary_gt +elementary_gt_head() +{ + atf_set "descr" "Tests that simple greater than works as expected" +} +elementary_gt_body() +{ + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 > 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 > -1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 11 > 012 ))' + + # atf_expect_fail "PR bin/50959" + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2147483647 > 0X7FFFFF0 ))' + # atf_expect_pass + + test ${ARITH_BITS} -gt 32 && + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x80000000 > 0x7FFFFFFF ))' + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 > 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 > 1 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( -1 > 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 > 10 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2015 > 2016 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xA1 > 200 ))' + + test ${ARITH_BITS} -ge 44 && + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x7F07F07F0 > 34099628014 ))' + + return 0 +} +atf_test_case elementary_ge +elementary_ge_head() +{ + atf_set "descr" "Tests that simple greater or equal works as expected" +} +elementary_ge_body() +{ + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 >= 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 >= 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( -100 >= -101 ))' + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( -1 >= 0 ))' +} + +atf_test_case fiddle_bits_and +fiddle_bits_and_head() +{ + atf_set "descr" "Test bitwise and operations in arithmetic expressions" +} +fiddle_bits_and_body() +{ + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 & 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 & 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 & 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 & 1 ))' + + atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xFF & 0xFF ))' + atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xFFFF & 0377 ))' + + test "${ARITH_BITS}" -ge 48 && + atf_check -s exit:0 -o inline:'70377641607203\n' -e empty \ + ${TEST_SH} -c 'echo $(( 0x5432FEDC0123 & 0x42871357BAB3 ))' + + return 0 +} +atf_test_case fiddle_bits_or +fiddle_bits_or_head() +{ + atf_set "descr" "Test bitwise or operations in arithmetic expressions" +} +fiddle_bits_or_body() +{ + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 | 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 | 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 | 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 | 1 ))' + + atf_check -s exit:0 -o inline:'4369\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x1111 | 0x1111 ))' + atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xAA | 0125 ))' + + test "${ARITH_BITS}" -ge 48 && + atf_check -s exit:0 -o inline:'95348271856563\n' -e empty \ + ${TEST_SH} -c 'echo $(( 0x5432FEDC0123 | 0x42871357BAB3 ))' + + return 0 +} +atf_test_case fiddle_bits_xor +fiddle_bits_xor_head() +{ + atf_set "descr" "Test bitwise xor operations in arithmetic expressions" +} +fiddle_bits_xor_body() +{ + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 ^ 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 ^ 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 ^ 1 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 ^ 1 ))' + + atf_check -s exit:0 -o inline:'255\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xF0 ^ 0x0F ))' + atf_check -s exit:0 -o inline:'15\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xF0 ^ 0xFF ))' + + test "${ARITH_BITS}" -ge 48 && + atf_check -s exit:0 -o inline:'24970630249360\n' -e empty \ + ${TEST_SH} -c 'echo $(( 0x5432FEDC0123 ^ 0x42871357BAB3 ))' + + return 0 +} + +atf_test_case logical_and +logical_and_head() +{ + atf_set "descr" "Test logical and operations in arithmetic expressions" +} +logical_and_body() +{ + # cannot test short-circuit eval until sh implements side effects... + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 && 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 && 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 && 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 && 1 ))' + + # atf_expect_fail "PR bin/50960" + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x1111 && 01234 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xFFFF && 0xF0F0 ))' +} +atf_test_case logical_or +logical_or_head() +{ + atf_set "descr" "Test logical or operations in arithmetic expressions" +} +logical_or_body() +{ + # cannot test short-circuit eval until sh implements side effects... + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 || 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 || 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 || 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 || 1 ))' + + # atf_expect_fail "PR bin/50960" + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x1111 || 01234 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x33 || 0xF0F0 ))' +} + +atf_test_case make_selection +make_selection_head() +{ + atf_set "descr" "Test ?: operator in arithmetic expressions" +} +make_selection_body() +{ + # atf_expect_fail "PR bin/50958" + + atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0 ? 2 : 3 ))' + atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 ? 2 : 3 ))' + + atf_check -s exit:0 -o inline:'111\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0x1234 ? 111 : 222 ))' + + atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 < 2 ? -1 : 1 > 2 ? 1 : 0 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 < 1 ? -1 : 1 > 1 ? 1 : 0 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2 < 1 ? -1 : 2 > 1 ? 1 : 0 ))' +} + +atf_test_case operator_precedence +operator_precedence_head() +{ + atf_set "descr" "Test operator precedence without parentheses" +} +operator_precedence_body() +{ + # NB: apart from $(( )) ** NO ** parentheses in the expressions. + + atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 + 2 + 3 ))' + atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 - 2 + 3 ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 - 2 - 1 ))' + atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 - 2 + 1 ))' + + atf_check -s exit:0 -o inline:'-1\n' -e empty ${TEST_SH} -c \ + 'echo $(( - 2 + 1 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2 + -1 ))' + + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( ! 2 + 1 ))' + atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2 + !1 ))' + + atf_check -s exit:0 -o inline:'8\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 * 2 + 2 ))' + atf_check -s exit:0 -o inline:'7\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 + 2 * 2 ))' + atf_check -s exit:0 -o inline:'12\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 * 2 * 2 ))' + + atf_check -s exit:0 -o inline:'5\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 / 3 + 2 ))' + atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 + 3 / 2 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 / 3 / 2 ))' + + atf_check -s exit:0 -o inline:'72\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 << 1 + 2 ))' + atf_check -s exit:0 -o inline:'48\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 + 3 << 2 ))' + atf_check -s exit:0 -o inline:'288\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 << 3 << 2 ))' + + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 >> 1 + 2 ))' + atf_check -s exit:0 -o inline:'3\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 + 3 >> 2 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 19 >> 3 >> 1 ))' + + atf_check -s exit:0 -o inline:'4\n' -e empty ${TEST_SH} -c \ + 'echo $(( 19 >> 3 << 1 ))' + atf_check -s exit:0 -o inline:'76\n' -e empty ${TEST_SH} -c \ + 'echo $(( 19 << 3 >> 1 ))' + + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2 + 3 < 3 * 2 ))' + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2 << 3 >= 3 << 2 ))' + + # sh inherits C's crazy operator precedence... + + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 0xfD & 0xF == 0xF ))' +} + +parentheses_head() +{ + atf_set "descr" "Test use of () to group sub-expressions" +} +parentheses_body() +{ + atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \ + 'echo $(( (1 + 2) + 3 ))' + atf_check -s exit:0 -o inline:'-4\n' -e empty ${TEST_SH} -c \ + 'echo $(( 1 - (2 + 3) ))' + atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 - (2 - 1) ))' + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 - ( 2 + 1 ) ))' + + atf_check -s exit:0 -o inline:'-3\n' -e empty ${TEST_SH} -c \ + 'echo $(( - (2 + 1) ))' + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( ! (2 + 1) ))' + + atf_check -s exit:0 -o inline:'12\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 * (2 + 2) ))' + atf_check -s exit:0 -o inline:'10\n' -e empty ${TEST_SH} -c \ + 'echo $(( (3 + 2) * 2 ))' + atf_check -s exit:0 -o inline:'12\n' -e empty ${TEST_SH} -c \ + 'echo $(( 3 * (2 * 2) ))' + + atf_check -s exit:0 -o inline:'1\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 / (3 + 2) ))' + atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \ + 'echo $(( ( 9 + 3 ) / 2 ))' + atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 / ( 3 / 2 ) ))' + + atf_check -s exit:0 -o inline:'20\n' -e empty ${TEST_SH} -c \ + 'echo $(( ( 9 << 1 ) + 2 ))' + atf_check -s exit:0 -o inline:'21\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 + (3 << 2) ))' + atf_check -s exit:0 -o inline:'36864\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 << (3 << 2) ))' + + atf_check -s exit:0 -o inline:'6\n' -e empty ${TEST_SH} -c \ + 'echo $(( (9 >> 1) + 2 ))' + atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \ + 'echo $(( 9 + (3 >> 2) ))' + atf_check -s exit:0 -o inline:'9\n' -e empty ${TEST_SH} -c \ + 'echo $(( 19 >> (3 >> 1) ))' + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( 19 >> (3 << 1) ))' + atf_check -s exit:0 -o inline:'38\n' -e empty ${TEST_SH} -c \ + 'echo $(( 19 << (3 >> 1) ))' + + atf_check -s exit:0 -o inline:'2\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2 + (3 < 3) * 2 ))' + atf_check -s exit:0 -o inline:'32\n' -e empty ${TEST_SH} -c \ + 'echo $(( 2 << ((3 >= 3) << 2) ))' + + # sh inherits C's crazy operator precedence... + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'echo $(( (0xfD & 0xF) == 0xF ))' +} + +atf_test_case arithmetic_fails +arithmetic_fails_head() +{ + atf_set "descr" "Dummy test to force failure" +} +arithmetic_fails_body() +{ + atf_fail "Cannot estimate number of bits supported by $(( ))" +} + +atf_init_test_cases() { + + discover_range + + test "${ARITH_BITS}" = '?' && { + atf_add_test_case arithmetic_fails + return 0 + } + + # odd names are to get atf's sort order semi-rational + + atf_add_test_case constants + atf_add_test_case do_unary_plus + atf_add_test_case do_unary_minus + atf_add_test_case do_unary_not + atf_add_test_case do_unary_tilde + atf_add_test_case elementary_add + atf_add_test_case elementary_sub + atf_add_test_case elementary_mul + atf_add_test_case elementary_div + atf_add_test_case elementary_rem + atf_add_test_case elementary_shl + atf_add_test_case elementary_shr + atf_add_test_case elementary_eq + atf_add_test_case elementary_ne + atf_add_test_case elementary_lt + atf_add_test_case elementary_le + atf_add_test_case elementary_gt + atf_add_test_case elementary_ge + atf_add_test_case fiddle_bits_and + atf_add_test_case fiddle_bits_or + atf_add_test_case fiddle_bits_xor + atf_add_test_case logical_and + atf_add_test_case logical_or + atf_add_test_case make_selection + atf_add_test_case operator_precedence + atf_add_test_case parentheses + # atf_add_test_case progressive # build up big expr + # atf_add_test_case test_errors # erroneous input + # atf_add_test_case torture # hard stuff (if there is any) + # atf_add_test_case var_assign # assignment ops + # atf_add_test_case vulgarity # truly evil inputs (syntax in vars...) +} diff --git a/contrib/netbsd-tests/bin/sh/t_cmdsub.sh b/contrib/netbsd-tests/bin/sh/t_cmdsub.sh new file mode 100755 index 0000000..f3ee210 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_cmdsub.sh @@ -0,0 +1,783 @@ +# $NetBSD: t_cmdsub.sh,v 1.4 2016/04/04 12:40:13 christos Exp $ +# +# Copyright (c) 2016 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + +# +# This file tests command substitutions ( `...` and $( ... ) ) +# +# CAUTION: +# Be careful attempting running these tests outside the ATF environment +# Some of the tests run "rm *" in the current directory to clean up +# An ATF test directory should be empty already, outside ATF, anything + +atf_test_case a_basic_cmdsub +a_basic_cmdsub_head() { + atf_set "descr" 'Test operation of simple $( ) substitutions' +} +a_basic_cmdsub_body() { + atf_check -s exit:0 -o match:'Result is true today' -e empty \ + ${TEST_SH} -c \ + 'echo Result is $( true && echo true || echo false ) today' + + atf_check -s exit:0 -o match:'Result is false today' -e empty \ + ${TEST_SH} -c \ + 'echo Result is $( false && echo true || echo false ) today' + + atf_check -s exit:0 -o match:'aaabbbccc' -e empty \ + ${TEST_SH} -c 'echo aaa$( echo bbb )ccc' + atf_check -s exit:0 -o match:'aaabbb cccddd' -e empty \ + ${TEST_SH} -c 'echo aaa$( echo bbb ccc )ddd' + atf_check -s exit:0 -o inline:'aaabbb cccddd\n' -e empty \ + ${TEST_SH} -c 'echo aaa$( echo bbb; echo ccc )ddd' + atf_check -s exit:0 -o inline:'aaabbb\ncccddd\n' -e empty \ + ${TEST_SH} -c 'echo "aaa$( echo bbb; echo ccc )ddd"' + + atf_check -s exit:0 -o inline:'some string\n' -e empty \ + ${TEST_SH} -c 'X=$( echo some string ); echo "$X"' + atf_check -s exit:0 -o inline:'weird; string *\n' -e empty \ + ${TEST_SH} -c 'X=$( echo "weird; string *" ); echo "$X"' + + rm -f * 2>/dev/null || : + for f in file-1 file-2 + do + cp /dev/null "$f" + done + + atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ + ${TEST_SH} -c 'echo Found $( echo * )' + atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ + ${TEST_SH} -c 'echo Found "$( echo * )"' + atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ + ${TEST_SH} -c 'echo Found $('" echo '*' )" + atf_check -s exit:0 -o match:'Found \*' -e empty \ + ${TEST_SH} -c 'echo Found "$('" echo '*' "')"' + atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ + ${TEST_SH} -c 'echo Found $('" echo \\* )" + atf_check -s exit:0 -o match:'Found \*' -e empty \ + ${TEST_SH} -c 'echo Found "$('" echo \\* )"\" +} + +atf_test_case b_basic_backticks +b_basic_backticks_head() { + atf_set "descr" 'Test operation of old style ` ` substitutions' +} +b_basic_backticks_body() { + atf_check -s exit:0 -o match:'Result is true today' -e empty \ + ${TEST_SH} -c \ + 'echo Result is `true && echo true || echo false` today' + + atf_check -s exit:0 -o match:'Result is false today' -e empty \ + ${TEST_SH} -c \ + 'echo Result is `false && echo true || echo false` today' + + atf_check -s exit:0 -o match:'aaabbbccc' -e empty \ + ${TEST_SH} -c 'echo aaa` echo bbb `ccc' + atf_check -s exit:0 -o match:'aaabbb cccddd' -e empty \ + ${TEST_SH} -c 'echo aaa` echo bbb ccc `ddd' + atf_check -s exit:0 -o inline:'aaabbb cccddd\n' -e empty \ + ${TEST_SH} -c 'echo aaa` echo bbb; echo ccc `ddd' + atf_check -s exit:0 -o inline:'aaabbb\ncccddd\n' -e empty \ + ${TEST_SH} -c 'echo "aaa` echo bbb; echo ccc `ddd"' + + atf_check -s exit:0 -o inline:'some string\n' -e empty \ + ${TEST_SH} -c 'X=` echo some string `; echo "$X"' + atf_check -s exit:0 -o inline:'weird; string *\n' -e empty \ + ${TEST_SH} -c 'X=` echo "weird; string *" `; echo "$X"' + + rm -f * 2>/dev/null || : + for f in file-1 file-2 + do + cp /dev/null "$f" + done + + atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ + ${TEST_SH} -c 'echo Found ` echo * `' + atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ + ${TEST_SH} -c 'echo Found "` echo * `"' + atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ + ${TEST_SH} -c 'echo Found `'" echo '*' "'`' + atf_check -s exit:0 -o match:'Found \*' -e empty \ + ${TEST_SH} -c 'echo Found "`'" echo '*' "'`"' + atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \ + ${TEST_SH} -c 'echo Found `'" echo \\* "'`' + atf_check -s exit:0 -o match:'Found \*' -e empty \ + ${TEST_SH} -c 'echo Found "`'" echo \\* "'`"' +} + +atf_test_case c_nested_cmdsub +c_nested_cmdsub_head() { + atf_set "descr" "Test that cmd substitutions can be nested" +} +c_nested_cmdsub_body() { + atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \ + ${TEST_SH} -c 'echo __$( echo foo$(echo bar)bletch )__' + atf_check -s exit:0 -o match:'_abcde_' -e empty \ + ${TEST_SH} -c 'echo _$(echo a$(echo $(echo b)c$(echo d))e )_' + atf_check -s exit:0 -o match:'123454321' -e empty \ + ${TEST_SH} -c 'echo 1$(echo 2$(echo 3$(echo 4$(echo 5)4)3)2)1' +} + +atf_test_case d_nested_backticks +d_nested_backticks_head() { + atf_set "descr" "Tests that old style backtick cmd subs can be nested" +} +d_nested_backticks_body() { + atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \ + ${TEST_SH} -c 'echo __` echo foo\`echo bar\`bletch `__' + atf_check -s exit:0 -o match:'_abcde_' -e empty \ + ${TEST_SH} -c \ + 'echo _`echo a\`echo \\\`echo b\\\`c\\\`echo d\\\`\`e `_' + atf_check -s exit:0 -o match:'123454321' -e empty \ + ${TEST_SH} -c \ + 'echo 1`echo 2\`echo 3\\\`echo 4\\\\\\\`echo 5\\\\\\\`4\\\`3\`2`1' +} + +atf_test_case e_perverse_mixing +e_perverse_mixing_head() { + atf_set "descr" \ + "Checks various mixed new and old style cmd substitutions" +} +e_perverse_mixing_body() { + atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \ + ${TEST_SH} -c 'echo __$( echo foo`echo bar`bletch )__' + atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \ + ${TEST_SH} -c 'echo __` echo foo$(echo bar)bletch `__' + atf_check -s exit:0 -o match:'_abcde_' -e empty \ + ${TEST_SH} -c 'echo _$(echo a`echo $(echo b)c$(echo d)`e )_' + atf_check -s exit:0 -o match:'_abcde_' -e empty \ + ${TEST_SH} -c 'echo _`echo a$(echo \`echo b\`c\`echo d\`)e `_' + atf_check -s exit:0 -o match:'12345654321' -e empty \ + ${TEST_SH} -c \ + 'echo 1`echo 2$(echo 3\`echo 4\\\`echo 5$(echo 6)5\\\`4\`3)2`1' +} + +atf_test_case f_redirect_in_cmdsub +f_redirect_in_cmdsub_head() { + atf_set "descr" "Checks that redirects work in command substitutions" +} +f_redirect_in_cmdsub_body() { + atf_require_prog cat + atf_require_prog rm + + rm -f file 2>/dev/null || : + atf_check -s exit:0 -o match:'_aa_' -e empty \ + ${TEST_SH} -c 'echo _$( echo a$( echo b > file )a)_' + atf_check -s exit:0 -o match:b -e empty ${TEST_SH} -c 'cat file' + atf_check -s exit:0 -o match:'_aba_' -e empty \ + ${TEST_SH} -c 'echo _$( echo a$( cat < file )a)_' + atf_check -s exit:0 -o match:'_aa_' -e empty \ + ${TEST_SH} -c 'echo _$( echo a$( echo d >> file )a)_' + atf_check -s exit:0 -o inline:'b\nd\n' -e empty ${TEST_SH} -c 'cat file' + atf_check -s exit:0 -o match:'_aa_' -e match:'not error' \ + ${TEST_SH} -c 'echo _$( echo a$( echo not error >&2 )a)_' +} + +atf_test_case g_redirect_in_backticks +g_redirect_in_backticks_head() { + atf_set "descr" "Checks that redirects work in old style cmd sub" +} +g_redirect_in_backticks_body() { + atf_require_prog cat + atf_require_prog rm + + rm -f file 2>/dev/null || : + atf_check -s exit:0 -o match:'_aa_' -e empty \ + ${TEST_SH} -c 'echo _` echo a\` echo b > file \`a`_' + atf_check -s exit:0 -o match:b -e empty ${TEST_SH} -c 'cat file' + atf_check -s exit:0 -o match:'_aba_' -e empty \ + ${TEST_SH} -c 'echo _` echo a\` cat < file \`a`_' + atf_check -s exit:0 -o match:'_aa_' -e empty \ + ${TEST_SH} -c 'echo _` echo a\` echo d >> file \`a`_' + atf_check -s exit:0 -o inline:'b\nd\n' -e empty ${TEST_SH} -c 'cat file' + atf_check -s exit:0 -o match:'_aa_' -e match:'not error' \ + ${TEST_SH} -c 'echo _` echo a\` echo not error >&2 \`a`_' +} + +atf_test_case h_vars_in_cmdsub +h_vars_in_cmdsub_head() { + atf_set "descr" "Check that variables work in command substitutions" +} +h_vars_in_cmdsub_body() { + atf_check -s exit:0 -o match:'__abc__' -e empty \ + ${TEST_SH} -c 'X=abc; echo __$( echo ${X} )__' + atf_check -s exit:0 -o match:'__abc__' -e empty \ + ${TEST_SH} -c 'X=abc; echo __$( echo "${X}" )__' + atf_check -s exit:0 -o match:'__abc__' -e empty \ + ${TEST_SH} -c 'X=abc; echo "__$( echo ${X} )__"' + atf_check -s exit:0 -o match:'__abc__' -e empty \ + ${TEST_SH} -c 'X=abc; echo "__$( echo "${X}" )__"' + + atf_check -s exit:0 -o inline:'a\n\nb\n\nc\n' -e empty \ + ${TEST_SH} -c "for X in a '' b '' c"'; do echo $( echo "$X" ); done' + + atf_check -s exit:0 -o match:'__acd__' -e empty \ + ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X-b}${Y-c}d)__"' + atf_check -s exit:0 -o match:'__abcd__' -e empty \ + ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X:-b}${Y:-c}d)__"' + atf_check -s exit:0 -o match:'__XYX__' -e empty \ + ${TEST_SH} -c 'X=X; echo "__${X}$( X=Y; echo ${X} )${X}__"' + atf_check -s exit:0 -o match:'__def__' -e empty \ + ${TEST_SH} -c 'X=abc; echo "__$(X=def; echo "${X}" )__"' + atf_check -s exit:0 -o inline:'abcdef\nabc\n' -e empty \ + ${TEST_SH} -c 'X=abc; echo "$X$(X=def; echo ${X} )"; echo $X' +} + +atf_test_case i_vars_in_backticks +i_vars_in_backticks_head() { + atf_set "descr" "Checks that variables work in old style cmd sub" +} +i_vars_in_backticks_body() { + atf_check -s exit:0 -o match:'__abc__' -e empty \ + ${TEST_SH} -c 'X=abc; echo __` echo ${X} `__' + atf_check -s exit:0 -o match:'__abc__' -e empty \ + ${TEST_SH} -c 'X=abc; echo __` echo "${X}" `__' + atf_check -s exit:0 -o match:'__abc__' -e empty \ + ${TEST_SH} -c 'X=abc; echo "__` echo ${X} `__"' + atf_check -s exit:0 -o match:'__abc__' -e empty \ + ${TEST_SH} -c 'X=abc; echo "__` echo \"${X}\" `__"' + + atf_check -s exit:0 -o inline:'a\n\nb\n\nc\n' -e empty \ + ${TEST_SH} -c "for X in a '' b '' c"'; do echo $( echo "$X" ); done' + + atf_check -s exit:0 -o match:'__acd__' -e empty \ + ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X-b}${Y-c}d)__"' + atf_check -s exit:0 -o match:'__abcd__' -e empty \ + ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X:-b}${Y:-c}d)__"' + atf_check -s exit:0 -o match:'__XYX__' -e empty \ + ${TEST_SH} -c 'X=X; echo "__${X}$( X=Y; echo ${X} )${X}__"' + atf_check -s exit:0 -o inline:'abcdef\nabc\n' -e empty \ + ${TEST_SH} -c 'X=abc; echo "$X`X=def; echo \"${X}\" `";echo $X' + + # The following is nonsense, so is not included ... + # atf_check -s exit:0 -o match:'__abc__' -e empty \ + # oV cV oV cV + # ${TEST_SH} -c 'X=abc; echo "__`X=def echo "${X}" `__"' + # `start in " ^ " ends, ` not yet +} + +atf_test_case j_cmdsub_in_varexpand +j_cmdsub_in_varexpand_head() { + atf_set "descr" "Checks that command sub can be used in var expansion" +} +j_cmdsub_in_varexpand_body() { + atf_check -s exit:0 -o match:'foo' -e empty \ + ${TEST_SH} -c 'X=set; echo ${X+$(echo foo)}' + atf_check -s exit:0 -o match:'set' -e empty \ + ${TEST_SH} -c 'X=set; echo ${X-$(echo foo)}' + rm -f bar 2>/dev/null || : + atf_check -s exit:0 -o match:'set' -e empty \ + ${TEST_SH} -c 'X=set; echo ${X-$(echo foo > bar)}' + test -f bar && atf_fail "bar should not exist, but does" + atf_check -s exit:0 -o inline:'\n' -e empty \ + ${TEST_SH} -c 'X=set; echo ${X+$(echo foo > bar)}' + test -f bar || atf_fail "bar should exist, but does not" +} + +atf_test_case k_backticks_in_varexpand +k_backticks_in_varexpand_head() { + atf_set "descr" "Checks that old style cmd sub works in var expansion" +} +k_backticks_in_varexpand_body() { + atf_check -s exit:0 -o match:'foo' -e empty \ + ${TEST_SH} -c 'X=set; echo ${X+`echo foo`}' + atf_check -s exit:0 -o match:'set' -e empty \ + ${TEST_SH} -c 'X=set; echo ${X-`echo foo`}' + rm -f bar 2>/dev/null || : + atf_check -s exit:0 -o match:'set' -e empty \ + ${TEST_SH} -c 'X=set; echo ${X-`echo foo > bar`}' + test -f bar && atf_fail "bar should not exist, but does" + atf_check -s exit:0 -o inline:'\n' -e empty \ + ${TEST_SH} -c 'X=set; echo ${X+`echo foo > bar`}' + test -f bar || atf_fail "bar should exist, but does not" +} + +atf_test_case l_arithmetic_in_cmdsub +l_arithmetic_in_cmdsub_head() { + atf_set "descr" "Checks that arithmetic works in cmd substitutions" +} +l_arithmetic_in_cmdsub_body() { + atf_check -s exit:0 -o inline:'1 + 1 = 2\n' -e empty \ + ${TEST_SH} -c 'echo 1 + 1 = $( echo $(( 1 + 1 )) )' + atf_check -s exit:0 -o inline:'X * Y = 6\n' -e empty \ + ${TEST_SH} -c 'X=2; Y=3; echo X \* Y = $( echo $(( X * Y )) )' + atf_check -s exit:0 -o inline:'Y % X = 1\n' -e empty \ + ${TEST_SH} -c 'X=2; Y=3; echo Y % X = $( echo $(( $Y % $X )) )' +} + +atf_test_case m_arithmetic_in_backticks +m_arithmetic_in_backticks_head() { + atf_set "descr" "Checks that arithmetic works in old style cmd sub" +} +m_arithmetic_in_backticks_body() { + atf_check -s exit:0 -o inline:'2 + 3 = 5\n' -e empty \ + ${TEST_SH} -c 'echo 2 + 3 = ` echo $(( 2 + 3 )) `' + atf_check -s exit:0 -o inline:'X * Y = 6\n' -e empty \ + ${TEST_SH} -c 'X=2; Y=3; echo X \* Y = ` echo $(( X * Y )) `' + atf_check -s exit:0 -o inline:'Y % X = 1\n' -e empty \ + ${TEST_SH} -c 'X=2; Y=3; echo Y % X = ` echo $(( $Y % $X )) `' +} + +atf_test_case n_cmdsub_in_arithmetic +n_cmdsub_in_arithmetic_head() { + atf_set "descr" "Tests uses of command substitutions in arithmetic" +} +n_cmdsub_in_arithmetic_body() { + atf_check -s exit:0 -o inline:'7\n' -e empty \ + ${TEST_SH} -c 'echo $(( $( echo 3 ) $( echo + ) $( echo 4 ) ))' + atf_check -s exit:0 -o inline:'11\n7\n18\n4\n1\n' -e empty \ + ${TEST_SH} -c \ + 'for op in + - \* / % + do + echo $(( $( echo 9 ) $( echo "${op}" ) $( echo 2 ) )) + done' +} + +atf_test_case o_backticks_in_arithmetic +o_backticks_in_arithmetic_head() { + atf_set "descr" "Tests old style cmd sub used in arithmetic" +} +o_backticks_in_arithmetic_body() { + atf_check -s exit:0 -o inline:'33\n' -e empty \ + ${TEST_SH} -c 'echo $(( `echo 77` `echo -` `echo 44`))' + atf_check -s exit:0 -o inline:'14\n8\n33\n3\n2\n' -e empty \ + ${TEST_SH} -c \ + 'for op in + - \* / % + do + echo $((`echo 11``echo "${op}"``echo 3`)) + done' +} + +atf_test_case p_cmdsub_in_heredoc +p_cmdsub_in_heredoc_head() { + atf_set "descr" "Checks that cmdsubs work inside a here document" +} +p_cmdsub_in_heredoc_body() { + atf_require_prog cat + + atf_check -s exit:0 -o inline:'line 1+1\nline 2\nline 3\n' -e empty \ + ${TEST_SH} -c \ + 'cat <<- EOF + $( echo line 1 )$( echo +1 ) + $( echo line 2;echo line 3 ) + EOF' +} + +atf_test_case q_backticks_in_heredoc +q_backticks_in_heredoc_head() { + atf_set "descr" "Checks that old style cmdsubs work in here docs" +} +q_backticks_in_heredoc_body() { + atf_require_prog cat + + atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \ + ${TEST_SH} -c \ + 'cat <<- EOF + `echo Mary ` `echo had a ` + ` echo little; echo lamb ` + EOF' +} + +atf_test_case r_heredoc_in_cmdsub +r_heredoc_in_cmdsub_head() { + atf_set "descr" "Checks that here docs work inside cmd subs" +} +r_heredoc_in_cmdsub_body() { + atf_require_prog cat + + atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \ + ${TEST_SH} -c 'echo "$( cat <<- \EOF + Mary had a + little + lamb + EOF + )"' + + atf_check -s exit:0 -e empty \ + -o inline:'Mary had 1\nlittle\nlamb\nMary had 4\nlittle\nlambs\n' \ + ${TEST_SH} -c 'for N in 1 4; do echo "$( cat <<- EOF + Mary had ${N} + little + lamb$( [ $N -gt 1 ] && echo s ) + EOF + )"; done' + + + atf_check -s exit:0 -o inline:'A Calculation:\n2 * 7 = 14\n' -e empty \ + ${TEST_SH} -c 'echo "$( cat <<- EOF + A Calculation: + 2 * 7 = $(( 2 * 7 )) + EOF + )"' +} + +atf_test_case s_heredoc_in_backticks +s_heredoc_in_backticks_head() { + atf_set "descr" "Checks that here docs work inside old style cmd subs" +} +s_heredoc_in_backticks_body() { + atf_require_prog cat + + atf_check -s exit:0 -o inline:'Mary had a little lamb\n' -e empty \ + ${TEST_SH} -c 'echo ` cat <<- \EOF + Mary had a + little + lamb + EOF + `' + + atf_check -s exit:0 -o inline:'A Calculation:\n17 / 3 = 5\n' -e empty \ + ${TEST_SH} -c 'echo "` cat <<- EOF + A Calculation: + 17 / 3 = $(( 17 / 3 )) + EOF + `"' +} + +atf_test_case t_nested_cmdsubs_in_heredoc +t_nested_cmdsubs_in_heredoc_head() { + atf_set "descr" "Checks nested command substitutions in here docs" +} +t_nested_cmdsubs_in_heredoc_body() { + atf_require_prog cat + atf_require_prog rm + + rm -f * 2>/dev/null || : + echo "Hello" > File + + atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \ + ${TEST_SH} -c 'cat <<- EOF + $(cat File) U + $( V=$(cat File); echo "${V%lo}p" ) me! + EOF' + + rm -f * 2>/dev/null || : + echo V>V ; echo A>A; echo R>R + echo Value>VAR + + atf_check -s exit:0 -o inline:'$2.50\n' -e empty \ + ${TEST_SH} -c 'cat <<- EOF + $(Value='\''$2.50'\'';eval echo $(eval $(cat V)$(cat A)$(cat R)=\'\''\$$(cat $(cat V)$(cat A)$(cat R))\'\''; eval echo \$$(set -- *;echo ${3}${1}${2}))) + EOF' +} + +atf_test_case u_nested_backticks_in_heredoc +u_nested_backticks_in_heredoc_head() { + atf_set "descr" "Checks nested old style cmd subs in here docs" +} +u_nested_backticks_in_heredoc_body() { + atf_require_prog cat + atf_require_prog rm + + rm -f * 2>/dev/null || : + echo "Hello" > File + + atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \ + ${TEST_SH} -c 'cat <<- EOF + `cat File` U + `V=\`cat File\`; echo "${V%lo}p" ` me! + EOF' + + rm -f * 2>/dev/null || : + echo V>V ; echo A>A; echo R>R + echo Value>VAR + + atf_check -s exit:0 -o inline:'$5.20\n' -e empty \ + ${TEST_SH} -c 'cat <<- EOF + `Value='\''$5.20'\'';eval echo \`eval \\\`cat V\\\`\\\`cat A\\\`\\\`cat R\\\`=\\\'\''\\\$\\\`cat \\\\\\\`cat V\\\\\\\`\\\\\\\`cat A\\\\\\\`\\\\\\\`cat R\\\\\\\`\\\`\\\'\''; eval echo \\\$\\\`set -- *;echo \\\\\${3}\\\\\${1}\\\\\${2}\\\`\`` + EOF' +} + +atf_test_case v_cmdsub_paren_tests +v_cmdsub__paren_tests_head() { + atf_set "descr" "tests with cmdsubs containing embedded ')'" +} +v_cmdsub_paren_tests_body() { + + # Tests from: + # http://www.in-ulm.de/~mascheck/various/cmd-subst/ + # (slightly modified.) + + atf_check -s exit:0 -o inline:'A.1\n' -e empty ${TEST_SH} -c \ + 'echo $( + case x in x) echo A.1;; esac + )' + + atf_check -s exit:0 -o inline:'A.2\n' -e empty ${TEST_SH} -c \ + 'echo $( + case x in x) echo A.2;; esac # comment + )' + + atf_check -s exit:0 -o inline:'A.3\n' -e empty ${TEST_SH} -c \ + 'echo $( + case x in (x) echo A.3;; esac + )' + + atf_check -s exit:0 -o inline:'A.4\n' -e empty ${TEST_SH} -c \ + 'echo $( + case x in (x) echo A.4;; esac # comment + )' + + atf_check -s exit:0 -o inline:'A.5\n' -e empty ${TEST_SH} -c \ + 'echo $( + case x in (x) echo A.5 + esac + )' + + atf_check -s exit:0 -o inline:'B: quoted )\n' -e empty ${TEST_SH} -c \ + 'echo $( + echo '\''B: quoted )'\'' + )' + + atf_check -s exit:0 -o inline:'C: comment then closing paren\n' \ + -e empty ${TEST_SH} -c \ + 'echo $( + echo C: comment then closing paren # ) + )' + + atf_check -s exit:0 -o inline:'D.1: here-doc with )\n' \ + -e empty ${TEST_SH} -c \ + 'echo $( + cat <<-\eof + D.1: here-doc with ) + eof + )' + + # D.2 is a bogus test. + + atf_check -s exit:0 -o inline:'D.3: here-doc with \()\n' \ + -e empty ${TEST_SH} -c \ + 'echo $( + cat <<-\eof + D.3: here-doc with \() + eof + )' + + atf_check -s exit:0 -e empty \ + -o inline:'E: here-doc terminated with a parenthesis ("academic")\n' \ + ${TEST_SH} -c \ + 'echo $( + cat <<-\) + E: here-doc terminated with a parenthesis ("academic") + ) + )' + + atf_check -s exit:0 -e empty \ +-o inline:'F.1: here-doc embed with unbal single, back- or doublequote '\''\n' \ + ${TEST_SH} -c \ + 'echo $( + cat <<-"eof" + F.1: here-doc embed with unbal single, back- or doublequote '\'' + eof + )' + atf_check -s exit:0 -e empty \ + -o inline:'F.2: here-doc embed with unbal single, back- or doublequote "\n' \ + ${TEST_SH} -c \ + 'echo $( + cat <<-"eof" + F.2: here-doc embed with unbal single, back- or doublequote " + eof + )' + atf_check -s exit:0 -e empty \ + -o inline:'F.3: here-doc embed with unbal single, back- or doublequote `\n' \ + ${TEST_SH} -c \ + 'echo $( + cat <<-"eof" + F.3: here-doc embed with unbal single, back- or doublequote ` + eof + )' + + atf_check -s exit:0 -e empty -o inline:'G: backslash at end of line\n' \ + ${TEST_SH} -c \ + 'echo $( + echo G: backslash at end of line # \ + )' + + atf_check -s exit:0 -e empty \ + -o inline:'H: empty command-substitution\n' \ + ${TEST_SH} -c 'echo H: empty command-substitution $( )' +} + +atf_test_case w_heredoc_outside_cmdsub +w_heredoc_outside_cmdsub_head() { + atf_set "descr" "Checks that here docs work inside cmd subs" +} +w_heredoc_outside_cmdsub_body() { + atf_require_prog cat + + atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \ + ${TEST_SH} -c 'echo "$( cat <<- \EOF )" + Mary had a + little + lamb + EOF + ' + + atf_check -s exit:0 -e empty \ + -o inline:'Mary had 1\nlittle\nlamb\nMary had 4\nlittle\nlambs\n' \ + ${TEST_SH} -c 'for N in 1 4; do echo "$( cat <<- EOF )" + Mary had ${N} + little + lamb$( [ $N -gt 1 ] && echo s ) + EOF + done' + + + atf_check -s exit:0 -o inline:'A Calculation:\n2 * 7 = 14\n' -e empty \ + ${TEST_SH} -c 'echo "$( cat <<- EOF)" + A Calculation: + 2 * 7 = $(( 2 * 7 )) + EOF + ' +} + +atf_test_case x_heredoc_outside_backticks +x_heredoc_outside_backticks_head() { + atf_set "descr" "Checks that here docs work inside old style cmd subs" +} +x_heredoc_outside_backticks_body() { + atf_require_prog cat + + atf_check -s exit:0 -o inline:'Mary had a little lamb\n' -e empty \ + ${TEST_SH} -c 'echo ` cat <<- \EOF ` + Mary had a + little + lamb + EOF + ' + + atf_check -s exit:0 -o inline:'A Calculation:\n17 / 3 = 5\n' -e empty \ + ${TEST_SH} -c 'echo "` cat <<- EOF `" + A Calculation: + 17 / 3 = $(( 17 / 3 )) + EOF + ' +} + +atf_test_case t_nested_cmdsubs_in_heredoc +t_nested_cmdsubs_in_heredoc_head() { + atf_set "descr" "Checks nested command substitutions in here docs" +} +t_nested_cmdsubs_in_heredoc_body() { + atf_require_prog cat + atf_require_prog rm + + rm -f * 2>/dev/null || : + echo "Hello" > File + + atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \ + ${TEST_SH} -c 'cat <<- EOF + $(cat File) U + $( V=$(cat File); echo "${V%lo}p" ) me! + EOF' + + rm -f * 2>/dev/null || : + echo V>V ; echo A>A; echo R>R + echo Value>VAR + + atf_check -s exit:0 -o inline:'$2.50\n' -e empty \ + ${TEST_SH} -c 'cat <<- EOF + $(Value='\''$2.50'\'';eval echo $(eval $(cat V)$(cat A)$(cat R)=\'\''\$$(cat $(cat V)$(cat A)$(cat R))\'\''; eval echo \$$(set -- *;echo ${3}${1}${2}))) + EOF' +} + +atf_test_case z_absurd_heredoc_cmdsub_combos +z_absurd_heredoc_cmdsub_combos_head() { + atf_set "descr" "perverse and unusual cmd substitutions & more" +} +z_absurd_heredoc_cmdsub_combos_body() { + + echo "Help!" > help + + # This version works in NetBSD (& FreeBSD)'s sh (and most others) + atf_check -s exit:0 -o inline:'Help!\nMe 2\n' -e empty ${TEST_SH} -c ' + cat <<- EOF + $( + cat <<- STOP + $( + cat `echo help` + ) + STOP + ) + $( + cat <<- END 4<<-TRASH + Me $(( 1 + 1 )) + END + This is unused noise! + TRASH + ) + EOF + ' + + # atf_expect_fail "PR bin/50993 - heredoc parsing done incorrectly" + atf_check -s exit:0 -o inline:'Help!\nMe 2\n' -e empty ${TEST_SH} -c ' + cat <<- EOF + $( + cat << STOP + $( + cat `echo help` + ) + STOP + ) + $( + cat <<- END 4< helper.sh << EOF +set -e +if eval false +then + echo "'eval false' returned true" + exit 1 +fi +echo "passed" +exit 0 +EOF + output="$($TEST_SH helper.sh)" + [ $? = 0 ] && return + + if [ -n "$output" ] + then + atf_fail "$output" + else + atf_fail "'eval false' exited from a tested context" + fi + +} + +atf_init_test_cases() { + atf_add_test_case evaltested +} diff --git a/contrib/netbsd-tests/bin/sh/t_exit.sh b/contrib/netbsd-tests/bin/sh/t_exit.sh new file mode 100755 index 0000000..17ed230 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_exit.sh @@ -0,0 +1,157 @@ +# $NetBSD: t_exit.sh,v 1.6 2016/05/07 23:51:30 kre Exp $ +# +# Copyright (c) 2007 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + + +atf_test_case background +background_head() { + atf_set "descr" "Tests that sh(1) sets '$?' properly when running " \ + "a command in the background (PR bin/46327)" +} +background_body() { + atf_check -o match:0 -e empty ${TEST_SH} -c 'true; true & echo $?' + # atf_expect_fail "PR bin/46327" (now fixed?) + atf_check -o match:0 -e empty ${TEST_SH} -c 'false; true & echo $?' +} + +atf_test_case function +function_head() { + atf_set "descr" "Tests that \$? is correctly updated inside " \ + "a function" +} +function_body() { + atf_check -s exit:0 -o match:STATUS=1-0 -e empty \ + ${TEST_SH} -c ' + crud() { + test yes = no + + cat <<-EOF + STATUS=$? + EOF + } + foo=$(crud) + echo "${foo}-$?" + ' +} + +atf_test_case readout +readout_head() { + atf_set "descr" "Tests that \$? is correctly updated in a " \ + "compound expression" +} +readout_body() { + atf_check -s exit:0 -o match:0 -e empty \ + ${TEST_SH} -c 'true && ! true | false; echo $?' +} + +atf_test_case trap_subshell +trap_subshell_head() { + atf_set "descr" "Tests that the trap statement in a subshell " \ + "works when the subshell exits" +} +trap_subshell_body() { + atf_check -s exit:0 -o inline:'exiting\n' -e empty \ + ${TEST_SH} -c '( trap "echo exiting" EXIT; /usr/bin/true )' +} + +atf_test_case trap_zero__implicit_exit +trap_zero__implicit_exit_head() { + atf_set "descr" "Tests that the trap statement in a subshell in a " \ + "script works when the subshell simply runs out of commands" +} +trap_zero__implicit_exit_body() { + # PR bin/6764: sh works but ksh does not + echo '( trap "echo exiting" 0 )' >helper.sh + atf_check -s exit:0 -o match:exiting -e empty ${TEST_SH} helper.sh + # test ksh by setting TEST_SH to /bin/ksh and run the entire set... + # atf_check -s exit:0 -o match:exiting -e empty /bin/ksh helper.sh +} + +atf_test_case trap_zero__explicit_exit +trap_zero__explicit_exit_head() { + atf_set "descr" "Tests that the trap statement in a subshell in a " \ + "script works when the subshell executes an explicit exit" +} +trap_zero__explicit_exit_body() { + echo '( trap "echo exiting" 0; exit; echo NO_NO_NO )' >helper.sh + atf_check -s exit:0 -o match:exiting -o not-match:NO_NO -e empty \ + ${TEST_SH} helper.sh + # test ksh by setting TEST_SH to /bin/ksh and run the entire set... + # atf_check -s exit:0 -o match:exiting -e empty /bin/ksh helper.sh +} + +atf_test_case simple_exit +simple_exit_head() { + atf_set "descr" "Tests that various values for exit status work" +} +# Note: ATF will not allow tests of exit values > 255, even if they would work +simple_exit_body() { + for N in 0 1 2 3 4 5 6 42 99 101 125 126 127 128 129 200 254 255 + do + atf_check -s exit:$N -o empty -e empty \ + ${TEST_SH} -c "exit $N; echo FOO; echo BAR >&2" + done +} + +atf_test_case subshell_exit +subshell_exit_head() { + atf_set "descr" "Tests that subshell exit status works and \$? gets it" +} +# Note: ATF will not allow tests of exit values > 255, even if they would work +subshell_exit_body() { + for N in 0 1 2 3 4 5 6 42 99 101 125 126 127 128 129 200 254 255 + do + atf_check -s exit:0 -o empty -e empty \ + ${TEST_SH} -c "(exit $N); test \$? -eq $N" + done +} + +atf_test_case subshell_background +subshell_background_head() { + atf_set "descr" "Tests that sh(1) sets '$?' properly when running " \ + "a subshell in the background" +} +subshell_background_body() { + atf_check -o match:0 -e empty \ + ${TEST_SH} -c 'true; (false || true) & echo $?' + # atf_expect_fail "PR bin/46327" (now fixed?) + atf_check -o match:0 -e empty \ + ${TEST_SH} -c 'false; (false || true) & echo $?' +} + +atf_init_test_cases() { + atf_add_test_case background + atf_add_test_case function + atf_add_test_case readout + atf_add_test_case trap_subshell + atf_add_test_case trap_zero__implicit_exit + atf_add_test_case trap_zero__explicit_exit + atf_add_test_case simple_exit + atf_add_test_case subshell_exit + atf_add_test_case subshell_background +} diff --git a/contrib/netbsd-tests/bin/sh/t_expand.sh b/contrib/netbsd-tests/bin/sh/t_expand.sh new file mode 100755 index 0000000..e785e1f --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_expand.sh @@ -0,0 +1,380 @@ +# $NetBSD: t_expand.sh,v 1.8 2016/04/29 18:29:17 christos Exp $ +# +# Copyright (c) 2007, 2009 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + +# +# This file tests the functions in expand.c. +# + +delim_argv() { + str= + while [ $# -gt 0 ]; do + if [ -z "${str}" ]; then + str=">$1<" + else + str="${str} >$1<" + fi + shift + done + echo ${str} +} + +atf_test_case dollar_at +dollar_at_head() { + atf_set "descr" "Somewhere between 2.0.2 and 3.0 the expansion" \ + "of the \$@ variable had been broken. Check for" \ + "this behavior." +} +dollar_at_body() { + # This one should work everywhere. + atf_check -s exit:0 -o inline:' EOL\n' -e empty \ + ${TEST_SH} -c 'echo "" "" | '" sed 's,\$,EOL,'" + + # This code triggered the bug. + atf_check -s exit:0 -o inline:' EOL\n' -e empty \ + ${TEST_SH} -c 'set -- "" ""; echo "$@" | '" sed 's,\$,EOL,'" + + atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ + 'set -- -; shift; n_arg() { echo $#; }; n_arg "$@"' +} + +atf_test_case dollar_at_with_text +dollar_at_with_text_head() { + atf_set "descr" "Test \$@ expansion when it is surrounded by text" \ + "within the quotes. PR bin/33956." +} +dollar_at_with_text_body() { + + cat <<'EOF' > h-f1 + +delim_argv() { + str= + while [ $# -gt 0 ]; do + if [ -z "${str}" ]; then + str=">$1<" + else + str="${str} >$1<" + fi + shift + done + echo "${str}" +} + +EOF + cat <<'EOF' > h-f2 + +delim_argv() { + str= + while [ $# -gt 0 ]; do + + str="${str}${str:+ }>$1<" + shift + + done + echo "${str}" +} + +EOF + + chmod +x h-f1 h-f2 + + for f in 1 2 + do + atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \ + ". ./h-f${f}; "'set -- ; delim_argv "$@"' + atf_check -s exit:0 -o inline:'>foobar<\n' -e empty \ + ${TEST_SH} -c \ + ". ./h-f${f}; "'set -- ; delim_argv "foo$@bar"' + atf_check -s exit:0 -o inline:'>foo bar<\n' -e empty \ + ${TEST_SH} -c \ + ". ./h-f${f}; "'set -- ; delim_argv "foo $@ bar"' + + atf_check -s exit:0 -o inline:'>a< >b< >c<\n' -e empty \ + ${TEST_SH} -c \ + ". ./h-f${f}; "'set -- a b c; delim_argv "$@"' + atf_check -s exit:0 -o inline:'>fooa< >b< >cbar<\n' -e empty \ + ${TEST_SH} -c \ + ". ./h-f${f}; "'set -- a b c; delim_argv "foo$@bar"' + atf_check -s exit:0 -o inline:'>foo a< >b< >c bar<\n' -e empty \ + ${TEST_SH} -c \ + ". ./h-f${f}; "'set -- a b c; delim_argv "foo $@ bar"' + done +} + +atf_test_case strip +strip_head() { + atf_set "descr" "Checks that the %% operator works and strips" \ + "the contents of a variable from the given point" \ + "to the end" +} +strip_body() { + line='#define bindir "/usr/bin" /* comment */' + stripped='#define bindir "/usr/bin" ' + + # atf_expect_fail "PR bin/43469" -- now fixed + for exp in \ + '${line%%/\**}' \ + '${line%%"/*"*}' \ + '${line%%'"'"'/*'"'"'*}' \ + '"${line%%/\**}"' \ + '"${line%%"/*"*}"' \ + '"${line%%'"'"'/*'"'"'*}"' \ + '${line%/\**}' \ + '${line%"/*"*}' \ + '${line%'"'"'/*'"'"'*}' \ + '"${line%/\**}"' \ + '"${line%"/*"*}"' \ + '"${line%'"'"'/*'"'"'*}"' + do + atf_check -o inline:":$stripped:\n" -e empty ${TEST_SH} -c \ + "line='${line}'; echo :${exp}:" + done +} + +atf_test_case varpattern_backslashes +varpattern_backslashes_head() { + atf_set "descr" "Tests that protecting wildcards with backslashes" \ + "works in variable patterns." +} +varpattern_backslashes_body() { + line='/foo/bar/*/baz' + stripped='/foo/bar/' + atf_check -o inline:'/foo/bar/\n' -e empty ${TEST_SH} -c \ + 'line="/foo/bar/*/baz"; echo ${line%%\**}' +} + +atf_test_case arithmetic +arithmetic_head() { + atf_set "descr" "POSIX requires shell arithmetic to use signed" \ + "long or a wider type. We use intmax_t, so at" \ + "least 64 bits should be available. Make sure" \ + "this is true." +} +arithmetic_body() { + + atf_check -o inline:'3' -e empty ${TEST_SH} -c \ + 'printf %s $((1 + 2))' + atf_check -o inline:'2147483647' -e empty ${TEST_SH} -c \ + 'printf %s $((0x7fffffff))' + atf_check -o inline:'9223372036854775807' -e empty ${TEST_SH} -c \ + 'printf %s $(((1 << 63) - 1))' +} + +atf_test_case iteration_on_null_parameter +iteration_on_null_parameter_head() { + atf_set "descr" "Check iteration of \$@ in for loop when set to null;" \ + "the error \"sh: @: parameter not set\" is incorrect." \ + "PR bin/48202." +} +iteration_on_null_parameter_body() { + atf_check -o empty -e empty ${TEST_SH} -c \ + 'N=; set -- ${N}; for X; do echo "[$X]"; done' +} + +atf_test_case iteration_on_quoted_null_parameter +iteration_on_quoted_null_parameter_head() { + atf_set "descr" \ + 'Check iteration of "$@" in for loop when set to null;' +} +iteration_on_quoted_null_parameter_body() { + atf_check -o inline:'[]\n' -e empty ${TEST_SH} -c \ + 'N=; set -- "${N}"; for X; do echo "[$X]"; done' +} + +atf_test_case iteration_on_null_or_null_parameter +iteration_on_null_or_null_parameter_head() { + atf_set "descr" \ + 'Check expansion of null parameter as default for another null' +} +iteration_on_null_or_null_parameter_body() { + atf_check -o empty -e empty ${TEST_SH} -c \ + 'N=; E=; set -- ${N:-${E}}; for X; do echo "[$X]"; done' +} + +atf_test_case iteration_on_null_or_missing_parameter +iteration_on_null_or_missing_parameter_head() { + atf_set "descr" \ + 'Check expansion of missing parameter as default for another null' +} +iteration_on_null_or_missing_parameter_body() { + # atf_expect_fail 'PR bin/50834' + atf_check -o empty -e empty ${TEST_SH} -c \ + 'N=; set -- ${N:-}; for X; do echo "[$X]"; done' +} + +nl=' +' +reset() +{ + TEST_NUM=0 + TEST_FAILURES='' + TEST_FAIL_COUNT=0 + TEST_ID="$1" +} + +check() +{ + fail=false + TEMP_FILE=$( mktemp OUT.XXXXXX ) + TEST_NUM=$(( $TEST_NUM + 1 )) + MSG= + + # our local shell (ATF_SHELL) better do quoting correctly... + # some of the tests expect us to expand $nl internally... + CMD="$1" + + result="$( ${TEST_SH} -c "${CMD}" 2>"${TEMP_FILE}" )" + STATUS=$? + + if [ "${STATUS}" -ne "$3" ]; then + MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" + MSG="${MSG} expected exit code $3, got ${STATUS}" + + # don't actually fail just because of wrong exit code + # unless we either expected, or received "good" + case "$3/${STATUS}" in + (*/0|0/*) fail=true;; + esac + fi + + if [ "$3" -eq 0 ]; then + if [ -s "${TEMP_FILE}" ]; then + MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" + MSG="${MSG} Messages produced on stderr unexpected..." + MSG="${MSG}${nl}$( cat "${TEMP_FILE}" )" + fail=true + fi + else + if ! [ -s "${TEMP_FILE}" ]; then + MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" + MSG="${MSG} Expected messages on stderr," + MSG="${MSG} nothing produced" + fail=true + fi + fi + rm -f "${TEMP_FILE}" + + # Remove newlines (use local shell for this) + oifs="$IFS" + IFS="$nl" + result="$(echo $result)" + IFS="$oifs" + if [ "$2" != "$result" ] + then + MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" + MSG="${MSG} Expected output '$2', received '$result'" + fail=true + fi + + if $fail + then + MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" + MSG="${MSG} Full command: <<${CMD}>>" + fi + + $fail && test -n "$TEST_ID" && { + TEST_FAILURES="${TEST_FAILURES}${TEST_FAILURES:+${nl}}" + TEST_FAILURES="${TEST_FAILURES}${TEST_ID}[$TEST_NUM]:" + TEST_FAILURES="${TEST_FAILURES} Test of '$1' failed."; + TEST_FAILURES="${TEST_FAILURES}${nl}${MSG}" + TEST_FAIL_COUNT=$(( $TEST_FAIL_COUNT + 1 )) + return 0 + } + $fail && atf_fail "Test[$TEST_NUM] of '$1' failed${nl}${MSG}" + return 0 +} + +results() +{ + test -z "${TEST_ID}" && return 0 + test -z "${TEST_FAILURES}" && return 0 + + echo >&2 "==========================================" + echo >&2 "While testing '${TEST_ID}'" + echo >&2 " - - - - - - - - - - - - - - - - -" + echo >&2 "${TEST_FAILURES}" + atf_fail \ + "Test ${TEST_ID}: $TEST_FAIL_COUNT subtests (of $TEST_NUM) failed - see stderr" +} + +atf_test_case shell_params +shell_params_head() { + atf_set "descr" "Test correct operation of the numeric parameters" +} +shell_params_body() { + atf_require_prog mktemp + + reset shell_params + + check 'set -- a b c; echo "$#: $1 $2 $3"' '3: a b c' 0 + check 'set -- a b c d e f g h i j k l m; echo "$#: ${1}0 ${10} $10"' \ + '13: a0 j a0' 0 + check 'x="$0"; set -- a b; y="$0"; + [ "x${x}y" = "x${y}y" ] && echo OK || echo x="$x" y="$y"' \ + 'OK' 0 + check "${TEST_SH} -c 'echo 0=\$0 1=\$1 2=\$2' a b c" '0=a 1=b 2=c' 0 + + echo 'echo 0="$0" 1="$1" 2="$2"' > helper.sh + check "${TEST_SH} helper.sh a b c" '0=helper.sh 1=a 2=b' 0 + + check 'set -- a bb ccc dddd eeeee ffffff ggggggg hhhhhhhh \ + iiiiiiiii jjjjjjjjjj kkkkkkkkkkk + echo "${#}: ${#1} ${#2} ${#3} ${#4} ... ${#9} ${#10} ${#11}"' \ + '11: 1 2 3 4 ... 9 10 11' 0 + + check 'set -- a b c; echo "$#: ${1-A} ${2-B} ${3-C} ${4-D} ${5-E}"' \ + '3: a b c D E' 0 + check 'set -- a "" c "" e + echo "$#: ${1:-A} ${2:-B} ${3:-C} ${4:-D} ${5:-E}"' \ + '5: a B c D e' 0 + check 'set -- a "" c "" e + echo "$#: ${1:+A} ${2:+B} ${3:+C} ${4:+D} ${5:+E}"' \ + '5: A C E' 0 + check 'set -- "abab*cbb" + echo "${1} ${1#a} ${1%b} ${1##ab} ${1%%b} ${1#*\*} ${1%\**}"' \ + 'abab*cbb bab*cbb abab*cb ab*cbb abab*cb cbb abab' 0 + check 'set -- "abab?cbb" + echo "${1}:${1#*a}+${1%b*}-${1##*a}_${1%%b*}%${1#[ab]}=${1%?*}/${1%\?*}"' \ + 'abab?cbb:bab?cbb+abab?cb-b?cbb_a%bab?cbb=abab?cb/abab' 0 + check 'set -- a "" c "" e; echo "${2:=b}"' '' 1 + + results +} + +atf_init_test_cases() { + atf_add_test_case dollar_at + atf_add_test_case dollar_at_with_text + atf_add_test_case strip + atf_add_test_case varpattern_backslashes + atf_add_test_case arithmetic + atf_add_test_case iteration_on_null_parameter + atf_add_test_case iteration_on_quoted_null_parameter + atf_add_test_case iteration_on_null_or_null_parameter + atf_add_test_case iteration_on_null_or_missing_parameter + atf_add_test_case shell_params +} diff --git a/contrib/netbsd-tests/bin/sh/t_fsplit.sh b/contrib/netbsd-tests/bin/sh/t_fsplit.sh new file mode 100755 index 0000000..a37804b --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_fsplit.sh @@ -0,0 +1,360 @@ +# $NetBSD: t_fsplit.sh,v 1.4 2016/03/27 14:50:01 christos Exp $ +# +# Copyright (c) 2007-2016 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# The standard +# http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html +# explains (section 2.6) that Field splitting should be performed on the +# result of variable expansions. +# In particular this means that in ${x-word}, 'word' must be expanded as if +# the "${x-" and "}" were absent from the input line. +# +# So: sh -c 'set ${x-a b c}; echo $#' should give 3. +# and: sh -c 'set -- ${x-}' echo $#' shold give 0 +# + +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + +nl=' +' + +check() +{ + TEST=$((${TEST} + 1)) + + case "$#" in + (2) ;; + (*) atf_fail "Internal test error, $# args to check test ${TEST}";; + esac + + result=$( ${TEST_SH} -c "unset x; $1" ) + STATUS="$?" + + # Remove newlines + oifs="$IFS" + IFS="$nl" + result="$(echo $result)" + IFS="$oifs" + + # trim the test text in case we use it in a message below + case "$1" in + ????????????????*) + set -- "$(expr "$1" : '\(............\).*')..." "$2" ;; + esac + + if [ "$2" != "$result" ] + then + if [ "${STATUS}" = "0" ] + then + atf_fail "Test ${TEST} '$1': expected [$2], found [$result]" + else + atf_fail \ + "TEST ${TEST} '$1' failed ($STATUS): expected [$2], found [$result]" + fi + elif [ "${STATUS}" != 0 ] + then + atf_fail "TEST ${TEST} '$1' failed ($STATUS)" + fi +} + +atf_test_case for +for_head() { + atf_set "descr" "Checks field splitting in for loops" +} +for_body() { + unset x + + TEST=0 + # Since I managed to break this, leave the test in + check 'for f in $x; do echo x${f}y; done' '' +} + +atf_test_case default_val +default_val_head() { + atf_set "descr" "Checks field splitting in variable default values" +} +default_val_body() { + TEST=0 + # Check that IFS is applied to text from ${x-...} unless it is inside + # any set of "..." + check 'set -- ${x-a b c}; echo $#' 3 + + check 'set -- ${x-"a b" c}; echo $#' 2 + check 'set -- ${x-a "b c"}; echo $#' 2 + check 'set -- ${x-"a b c"}; echo $#' 1 + + check "set -- \${x-'a b' c}; echo \$#" 2 + check "set -- \${x-a 'b c'}; echo \$#" 2 + check "set -- \${x-'a b c'}; echo \$#" 1 + + check 'set -- ${x-a\ b c}; echo $#' 2 + check 'set -- ${x-a b\ c}; echo $#' 2 + check 'set -- ${x-a\ b\ c}; echo $#' 1 + + check 'set -- ${x}; echo $#' 0 + check 'set -- ${x-}; echo $#' 0 + check 'set -- ${x-""}; echo $#' 1 + check 'set -- ""${x}; echo $#' 1 + check 'set -- ""${x-}; echo $#' 1 + check 'set -- ""${x-""}; echo $#' 1 + check 'set -- ${x}""; echo $#' 1 + check 'set -- ${x-}""; echo $#' 1 + check 'set -- ${x-""}""; echo $#' 1 + check 'set -- ""${x}""; echo $#' 1 + check 'set -- ""${x-}""; echo $#' 1 + check 'set -- ""${x-""}""; echo $#' 1 + + check 'for i in ${x-a b c}; do echo "z${i}z"; done' \ + 'zaz zbz zcz' + check 'for i in ${x-"a b" c}; do echo "z${i}z"; done' \ + 'za bz zcz' + check 'for i in ${x-"a ${x-b c}" d}; do echo "z${i}z"; done' \ + 'za b cz zdz' + check 'for i in ${x-a ${x-b c} d}; do echo "z${i}z"; done' \ + 'zaz zbz zcz zdz' + + # I am not sure these two are correct, the rules on quoting word + # in ${var-word} are peculiar, and hard to fathom... + # They are what the NetBSD shell does, and bash, not the freebsd shell + # (as of Mar 1, 2016) + + check 'for i in ${x-"a ${x-"b c"}" d}; do echo "z${i}z"; done' \ + 'za b cz zdz' + check 'for i in ${x-a ${x-"b c"} d}; do echo "z${i}z"; done' \ + 'zaz zb cz zdz' +} + +atf_test_case replacement_val +replacement_val_head() { + atf_set "descr" "Checks field splitting in variable replacement values" +} +replacement_val_body() { + TEST=0 + + # Check that IFS is applied to text from ${x+...} unless it is inside + # any set of "...", or whole expansion is quoted, or both... + + check 'x=BOGUS; set -- ${x+a b c}; echo $#' 3 + + check 'x=BOGUS; set -- ${x+"a b" c}; echo $#' 2 + check 'x=BOGUS; set -- ${x+a "b c"}; echo $#' 2 + check 'x=BOGUS; set -- ${x+"a b c"}; echo $#' 1 + + check "x=BOGUS; set -- \${x+'a b' c}; echo \$#" 2 + check "x=BOGUS; set -- \${x+a 'b c'}; echo \$#" 2 + check "x=BOGUS; set -- \${x+'a b c'}; echo \$#" 1 + + check 'x=BOGUS; set -- ${x+a\ b c}; echo $#' 2 + check 'x=BOGUS; set -- ${x+a b\ c}; echo $#' 2 + check 'x=BOGUS; set -- ${x+a\ b\ c}; echo $#' 1 + + check 'x=BOGUS; set -- ${x+}; echo $#' 0 + check 'x=BOGUS; set -- ${x+""}; echo $#' 1 + check 'x=BOGUS; set -- ""${x+}; echo $#' 1 + check 'x=BOGUS; set -- ""${x+""}; echo $#' 1 + check 'x=BOGUS; set -- ${x+}""; echo $#' 1 + check 'x=BOGUS; set -- ${x+""}""; echo $#' 1 + check 'x=BOGUS; set -- ""${x+}""; echo $#' 1 + check 'x=BOGUS; set -- ""${x+""}""; echo $#' 1 + + # verify that the value of $x does not affecty the value of ${x+...} + check 'x=BOGUS; set -- ${x+}; echo X$1' X + check 'x=BOGUS; set -- ${x+""}; echo X$1' X + check 'x=BOGUS; set -- ""${x+}; echo X$1' X + check 'x=BOGUS; set -- ""${x+""}; echo X$1' X + check 'x=BOGUS; set -- ${x+}""; echo X$1' X + check 'x=BOGUS; set -- ${x+""}""; echo X$1' X + check 'x=BOGUS; set -- ""${x+}""; echo X$1' X + check 'x=BOGUS; set -- ""${x+""}""; echo X$1' X + + check 'x=BOGUS; set -- ${x+}; echo X${1-:}X' X:X + check 'x=BOGUS; set -- ${x+""}; echo X${1-:}X' XX + check 'x=BOGUS; set -- ""${x+}; echo X${1-:}X' XX + check 'x=BOGUS; set -- ""${x+""}; echo X${1-:}X' XX + check 'x=BOGUS; set -- ${x+}""; echo X${1-:}X' XX + check 'x=BOGUS; set -- ${x+""}""; echo X${1-:}X' XX + check 'x=BOGUS; set -- ""${x+}""; echo X${1-:}X' XX + check 'x=BOGUS; set -- ""${x+""}""; echo X${1-:}X' XX + + # and validate that the replacement can be used as expected + check 'x=BOGUS; for i in ${x+a b c}; do echo "z${i}z"; done'\ + 'zaz zbz zcz' + check 'x=BOGUS; for i in ${x+"a b" c}; do echo "z${i}z"; done'\ + 'za bz zcz' + check 'x=BOGUS; for i in ${x+"a ${x+b c}" d}; do echo "z${i}z"; done'\ + 'za b cz zdz' + check 'x=BOGUS; for i in ${x+"a ${x+"b c"}" d}; do echo "z${i}z"; done'\ + 'za b cz zdz' + check 'x=BOGUS; for i in ${x+a ${x+"b c"} d}; do echo "z${i}z"; done'\ + 'zaz zb cz zdz' + check 'x=BOGUS; for i in ${x+a ${x+b c} d}; do echo "z${i}z"; done'\ + 'zaz zbz zcz zdz' +} + +atf_test_case ifs_alpha +ifs_alpha_head() { + atf_set "descr" "Checks that field splitting works with alphabetic" \ + "characters" +} +ifs_alpha_body() { + unset x + + TEST=0 + # repeat with an alphabetic in IFS + check 'IFS=q; set ${x-aqbqc}; echo $#' 3 + check 'IFS=q; for i in ${x-aqbqc}; do echo "z${i}z"; done' \ + 'zaz zbz zcz' + check 'IFS=q; for i in ${x-"aqb"qc}; do echo "z${i}z"; done' \ + 'zaqbz zcz' + check 'IFS=q; for i in ${x-"aq${x-bqc}"qd}; do echo "z${i}z"; done' \ + 'zaqbqcz zdz' + check 'IFS=q; for i in ${x-"aq${x-"bqc"}"qd}; do echo "z${i}z"; done' \ + 'zaqbqcz zdz' + check 'IFS=q; for i in ${x-aq${x-"bqc"}qd}; do echo "z${i}z"; done' \ + 'zaz zbqcz zdz' +} + +atf_test_case quote +quote_head() { + atf_set "descr" "Checks that field splitting works with multi-word" \ + "fields" +} +quote_body() { + unset x + + TEST=0 + # Some quote propagation checks + check 'set "${x-a b c}"; echo $#' 1 + check 'set "${x-"a b" c}"; echo $1' 'a b c' + check 'for i in "${x-a b c}"; do echo "z${i}z"; done' 'za b cz' +} + +atf_test_case dollar_at +dollar_at_head() { + atf_set "descr" "Checks that field splitting works when expanding" \ + "\$@" +} +dollar_at_body() { + unset x + + TEST=0 + # Check we get "$@" right + + check 'set --; for i in x"$@"x; do echo "z${i}z"; done' 'zxxz' + check 'set a; for i in x"$@"x; do echo "z${i}z"; done' 'zxaxz' + check 'set a b; for i in x"$@"x; do echo "z${i}z"; done' 'zxaz zbxz' + + check 'set --; for i; do echo "z${i}z"; done' '' + check 'set --; for i in $@; do echo "z${i}z"; done' '' + check 'set --; for i in "$@"; do echo "z${i}z"; done' '' + # atf_expect_fail "PR bin/50834" + check 'set --; for i in ""$@; do echo "z${i}z"; done' 'zz' + # atf_expect_pass + check 'set --; for i in $@""; do echo "z${i}z"; done' 'zz' + check 'set --; for i in ""$@""; do echo "z${i}z"; done' 'zz' + check 'set --; for i in """$@"; do echo "z${i}z"; done' 'zz' + check 'set --; for i in "$@"""; do echo "z${i}z"; done' 'zz' + check 'set --; for i in """$@""";do echo "z${i}z"; done' 'zz' + + check 'set ""; for i; do echo "z${i}z"; done' 'zz' + check 'set ""; for i in "$@"; do echo "z${i}z"; done' 'zz' + check 'set "" ""; for i; do echo "z${i}z"; done' 'zz zz' + check 'set "" ""; for i in "$@"; do echo "z${i}z"; done' 'zz zz' + check 'set "" ""; for i in $@; do echo "z${i}z"; done' '' + + check 'set "a b" c; for i; do echo "z${i}z"; done' \ + 'za bz zcz' + check 'set "a b" c; for i in "$@"; do echo "z${i}z"; done' \ + 'za bz zcz' + check 'set "a b" c; for i in $@; do echo "z${i}z"; done' \ + 'zaz zbz zcz' + check 'set " a b " c; for i in "$@"; do echo "z${i}z"; done' \ + 'z a b z zcz' + + check 'set a b c; for i in "$@$@"; do echo "z${i}z"; done' \ + 'zaz zbz zcaz zbz zcz' + check 'set a b c; for i in "$@""$@";do echo "z${i}z"; done' \ + 'zaz zbz zcaz zbz zcz' +} + +atf_test_case ifs +ifs_head() { + atf_set "descr" "Checks that IFS correctly configures field" \ + "splitting behavior" +} +ifs_body() { + unset x + + TEST=0 + # Some IFS tests + check 't="-- "; IFS=" "; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '0' + check 't=" x"; IFS=" x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '1' + check 't=" x "; IFS=" x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '1' + check 't=axb; IFS="x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '2 a:b' + check 't="a x b"; IFS="x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '2 a : b' + check 't="a xx b"; IFS="x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '3 a :: b' + check 't="a xx b"; IFS="x "; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '3 a::b' + # A recent 'clarification' means that a single trailing IFS non-whitespace + # doesn't generate an empty parameter + check 't="xax"; IFS="x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '2 :a' + check 't="xax "; IFS="x "; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '2 :a' + # Verify that IFS isn't being applied where it shouldn't be. + check 'IFS="x"; set axb; IFS=":"; r="$*"; IFS=; echo $# $r' '1 axb' +} + +atf_test_case var_length +var_length_head() { + atf_set "descr" "Checks that field splitting works when expanding" \ + "a variable's length" +} +var_length_body() { + TEST=0 + + long=12345678123456781234567812345678 + long=$long$long$long$long + export long + + # first test that the test method works... + check 'set -u; : ${long}; echo ${#long}' '128' + + # Check that we apply IFS to ${#var} + check 'echo ${#long}; IFS=2; echo ${#long}; set 1 ${#long};echo $#' \ + '128 1 8 3' + check 'IFS=2; set ${x-${#long}}; IFS=" "; echo $* $#' '1 8 2' + check 'IFS=2; set ${x-"${#long}"}; IFS=" "; echo $* $#' '128 1' +} + +atf_init_test_cases() { + atf_add_test_case for + atf_add_test_case default_val + atf_add_test_case replacement_val + atf_add_test_case ifs_alpha + atf_add_test_case quote + atf_add_test_case dollar_at + atf_add_test_case ifs + atf_add_test_case var_length +} diff --git a/contrib/netbsd-tests/bin/sh/t_here.sh b/contrib/netbsd-tests/bin/sh/t_here.sh new file mode 100755 index 0000000..27307f5 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_here.sh @@ -0,0 +1,565 @@ +# $NetBSD: t_here.sh,v 1.6 2016/03/31 16:21:52 christos Exp $ +# +# Copyright (c) 2007 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + +nl=' +' + +reset() +{ + TEST_NUM=0 + TEST_FAILURES='' + TEST_FAIL_COUNT=0 + TEST_ID="$1" +} + +check() +{ + fail=false + TEMP_FILE=$( mktemp OUT.XXXXXX ) + TEST_NUM=$(( $TEST_NUM + 1 )) + + # our local shell (ATF_SHELL) better do quoting correctly... + # some of the tests expect us to expand $nl internally... + CMD="nl='${nl}'; $1" + + result="$( ${TEST_SH} -c "${CMD}" 2>"${TEMP_FILE}" )" + STATUS=$? + + if [ "${STATUS}" -ne "$3" ]; then + echo >&2 "[$TEST_NUM] expected exit code $3, got ${STATUS}" + + # don't actually fail just because of wrong exit code + # unless we either expected, or received "good" + case "$3/${STATUS}" in + (*/0|0/*) fail=true;; + esac + fi + + if [ "$3" -eq 0 ]; then + if [ -s "${TEMP_FILE}" ]; then + echo >&2 \ + "[$TEST_NUM] Messages produced on stderr unexpected..." + cat "${TEMP_FILE}" >&2 + fail=true + fi + else + if ! [ -s "${TEMP_FILE}" ]; then + echo >&2 \ + "[$TEST_NUM] Expected messages on stderr, nothing produced" + fail=true + fi + fi + rm -f "${TEMP_FILE}" + + # Remove newlines (use local shell for this) + oifs="$IFS" + IFS="$nl" + result="$(echo $result)" + IFS="$oifs" + if [ "$2" != "$result" ] + then + echo >&2 "[$TEST_NUM] Expected output '$2', received '$result'" + fail=true + fi + + if $fail + then + echo >&2 "[$TEST_NUM] Full command: <<${CMD}>>" + fi + + $fail && test -n "$TEST_ID" && { + TEST_FAILURES="${TEST_FAILURES}${TEST_FAILURES:+ +}${TEST_ID}[$TEST_NUM]: test of '$1' failed"; + TEST_FAIL_COUNT=$(( $TEST_FAIL_COUNT + 1 )) + return 0 + } + $fail && atf_fail "Test[$TEST_NUM] of '$1' failed" + return 0 +} + +results() +{ + test -z "${TEST_ID}" && return 0 + test -z "${TEST_FAILURES}" && return 0 + + echo >&2 "==========================================" + echo >&2 "While testing '${TEST_ID}'" + echo >&2 " - - - - - - - - - - - - - - - - -" + echo >&2 "${TEST_FAILURES}" + atf_fail \ + "Test ${TEST_ID}: $TEST_FAIL_COUNT subtests (of $TEST_NUM) failed - see stderr" +} + +atf_test_case do_simple +do_simple_head() { + atf_set "descr" "Basic tests for here documents" +} +do_simple_body() { + y=x + + reset 'simple' + IFS=' ' + check 'x=`cat < + E0F + ' '<'\''"'\'' \\$X\$X "'\''" \\>' 0 + + check 'X=!; cat <<- E0F + <'\''"'\'' \\$X\$X "'\''" \\> + E0F + ' '<'\''"'\'' \!$X "'\''" \>' 0 + + check 'cat <<- END + $( echo "'\''" ) $( echo '\''"'\'' ) $( echo \\ ) + END + ' "' \" \\" 0 + + check 'X=12345; Y="string1 line1?-line2"; Z=; unset W; cat <<-EOF + ${#X}${Z:-${Y}}${W+junk}${Y%%l*}${Y#*\?} + "$Z"'\''$W'\'' ${Y%" "*} $(( X + 54321 )) + EOF + ' '5string1 line1?-line2string1 -line2 ""'\'\'' string1 66666' 0 + + results +} + +atf_test_case side_effects +side_effects_head() { + atf_set "descr" "Tests how side effects in here documents are handled" +} +side_effects_body() { + + atf_check -s exit:0 -o inline:'2\n1\n' -e empty ${TEST_SH} -c ' + unset X + cat <<-EOF + ${X=2} + EOF + echo "${X-1}" + ' +} + +atf_test_case vicious +vicious_head() { + atf_set "descr" "Tests for obscure and obnoxious uses of here docs" +} +vicious_body() { + reset + + cat <<- \END_SCRIPT > script + cat < script + prefix() { sed -e "s/^/$1:/"; } + DASH_CODE() { :; } + + prefix A <&2 + exit 1 + } + s() { + set -"$1" + t="$-" + x=$(echo "$t" | tr -d "$1") + test "$t" = "$x" && x set "$1" + return 0 + } + c() { + set +"$1" + t="$-" + x=$(echo "$t" | tr -d "$1") + test "$t" != "$x" && x clear "$1" + return 0 + } + '"${CLEAR}"' + + # if we do not do this, -x tracing splatters stderr + # for some shells, -v does as well (is that correct?) + case "${opt}" in + (*[xv]*) exec 2>/dev/null;; + esac + + o="$-" + x=$(echo "$o" | tr -d "$opt") + + if [ "$o" = "$x" ]; then # option was off + s "${opt}" + c "${opt}" + else + c "${opt}" + s "${opt}" + fi + ' + done +} + +test_optional_on_off() +{ + RET=0 + OPTS= + for opt + do + test "${opt}" = n && continue + ${TEST_SH} -c "set -${opt}" 2>/dev/null && + OPTS="${OPTS} ${opt}" || RET=1 + done + + test -n "${OPTS}" && test_option_on_off ${OPTS} + + return "${RET}" +} + +atf_test_case set_a +set_a_head() { + atf_set "descr" "Tests that 'set -a' turns on all var export " \ + "and that it behaves as defined by the standard" +} +set_a_body() { + atf_require_prog env + atf_require_prog grep + + test_option_on_off a + + # without -a, new variables should not be exported (so grep "fails") + atf_check -s exit:1 -o empty -e empty ${TEST_SH} -ce \ + 'unset VAR; set +a; VAR=value; env | grep "^VAR="' + + # with -a, they should be + atf_check -s exit:0 -o match:VAR=value -e empty ${TEST_SH} -ce \ + 'unset VAR; set -a; VAR=value; env | grep "^VAR="' +} + +atf_test_case set_C +set_C_head() { + atf_set "descr" "Tests that 'set -C' turns on no clobber mode " \ + "and that it behaves as defined by the standard" +} +set_C_body() { + atf_require_prog ls + + test_option_on_off C + + # Check that the environment to use for the tests is sane ... + # we assume current dir is a new tempory directory & is empty + + test -z "$(ls)" || atf_skip "Test execution directory not clean" + test -c "/dev/null" || atf_skip "Problem with /dev/null" + + echo Dummy_Content > Junk_File + echo Precious_Content > Important_File + + # Check that we can redirect onto file when -C is not set + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ + ' + D=$(ls -l Junk_File) || exit 1 + set +C + echo "Overwrite it now" > Junk_File + A=$(ls -l Junk_File) || exit 1 + test "${A}" != "${D}" + ' + + # Check that we cannot redirect onto file when -C is set + atf_check -s exit:0 -o empty -e not-empty ${TEST_SH} -c \ + ' + D=$(ls -l Important_File) || exit 1 + set -C + echo "Fail to Overwrite it now" > Important_File + A=$(ls -l Important_File) || exit 1 + test "${A}" = "${D}" + ' + + # Check that we can append to file, even when -C is set + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ + ' + D=$(ls -l Junk_File) || exit 1 + set -C + echo "Append to it now" >> Junk_File + A=$(ls -l Junk_File) || exit 1 + test "${A}" != "${D}" + ' + + # Check that we abort on attempt to redirect onto file when -Ce is set + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \ + ' + set -Ce + echo "Fail to Overwrite it now" > Important_File + echo "Should not reach this point" + ' + + # Last check that we can override -C for when we really need to + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ + ' + D=$(ls -l Junk_File) || exit 1 + set -C + echo "Change the poor bugger again" >| Junk_File + A=$(ls -l Junk_File) || exit 1 + test "${A}" != "${D}" + ' +} + +atf_test_case set_e +set_e_head() { + atf_set "descr" "Tests that 'set -e' turns on error detection " \ + "and that a simple case behaves as defined by the standard" +} +set_e_body() { + test_option_on_off e + + # Check that -e does nothing if no commands fail + atf_check -s exit:0 -o match:I_am_OK -e empty \ + ${TEST_SH} -c \ + 'false; printf "%s" I_am; set -e; true; printf "%s\n" _OK' + + # and that it (silently, but with exit status) aborts if cmd fails + atf_check -s not-exit:0 -o match:I_am -o not-match:Broken -e empty \ + ${TEST_SH} -c \ + 'false; printf "%s" I_am; set -e; false; printf "%s\n" _Broken' + + # same, except -e this time is on from the beginning + atf_check -s not-exit:0 -o match:I_am -o not-match:Broken -e empty \ + ${TEST_SH} -ec 'printf "%s" I_am; false; printf "%s\n" _Broken' + + # More checking of -e in other places, there is lots to deal with. +} + +atf_test_case set_f +set_f_head() { + atf_set "descr" "Tests that 'set -f' turns off pathname expansion " \ + "and that it behaves as defined by the standard" +} +set_f_body() { + atf_require_prog ls + + test_option_on_off f + + # Check that the environment to use for the tests is sane ... + # we assume current dir is a new tempory directory & is empty + + test -z "$(ls)" || atf_skip "Test execution directory not clean" + + # we will assume that atf will clean up this junk directory + # when we are done. But for testing pathname expansion + # we need files + + for f in a b c d e f aa ab ac ad ae aaa aab aac aad aba abc bbb ccc + do + echo "$f" > "$f" + done + + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -ec \ + 'X=$(echo b*); Y=$(echo b*); test "${X}" != "a*"; + test "${X}" = "${Y}"' + + # now test expansion is different when -f is set + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -ec \ + 'X=$(echo b*); Y=$(set -f; echo b*); test "${X}" != "${Y}"' +} + +atf_test_case set_n +set_n_head() { + atf_set "descr" "Tests that 'set -n' supresses command execution " \ + "and that it behaves as defined by the standard" +} +set_n_body() { + # pointless to test this, if it turns on, it stays on... + # test_option_on_off n + # so just allow the tests below to verify it can be turned on + + # nothing should be executed, hence no output... + atf_check -s exit:0 -o empty -e empty \ + ${TEST_SH} -enc 'echo ABANDON HOPE; echo ALL YE; echo ...' + + # this is true even when the "commands" do not exist + atf_check -s exit:0 -o empty -e empty \ + ${TEST_SH} -enc 'ERR; FAIL; ABANDON HOPE' + + # but if there is a syntax error, it should be detected (w or w/o -e) + atf_check -s not-exit:0 -o empty -e not-empty \ + ${TEST_SH} -enc 'echo JUMP; for frogs swim; echo in puddles' + atf_check -s not-exit:0 -o empty -e not-empty \ + ${TEST_SH} -nc 'echo ABANDON HOPE; echo "ALL YE; echo ...' + atf_check -s not-exit:0 -o empty -e not-empty \ + ${TEST_SH} -enc 'echo ABANDON HOPE;; echo ALL YE; echo ...' + atf_check -s not-exit:0 -o empty -e not-empty \ + ${TEST_SH} -nc 'do YOU ABANDON HOPE; for all eternity?' + + # now test enabling -n in the middle of a script + # note that once turned on, it cannot be turned off again. + # + # omit more complex cases, as those can send some shells + # into infinite loops, and believe it or not, that might be OK! + + atf_check -s exit:0 -o match:first -o not-match:second -e empty \ + ${TEST_SH} -c 'echo first; set -n; echo second' + atf_check -s exit:0 -o match:first -o not-match:third -e empty \ + ${TEST_SH} -c 'echo first; set -n; echo second; set +n; echo third' + atf_check -s exit:0 -o inline:'a\nb\n' -e empty \ + ${TEST_SH} -c 'for x in a b c d + do + case "$x" in + a);; b);; c) set -n;; d);; + esac + printf "%s\n" "$x" + done' + + # This last one is a bit more complex to explain, so I will not try + + # First, we need to know what signal number is used for SIGUSR1 on + # the local (testing) system (signal number is $(( $XIT - 128 )) ) + + # this will take slightly over 1 second elapsed time (the sleep 1) + # The "10" for the first sleep just needs to be something big enough + # that the rest of the commands have time to complete, even on + # very slow testing systems. 10 should be enough. Otherwise irrelevant + + # The shell will usually blather to stderr about the sleep 10 being + # killed, but it affects nothing, so just allow it to cry. + + (sleep 10 & sleep 1; kill -USR1 $!; wait $!) + XIT="$?" + + # The exit value should be an integer > 128 and < 256 (often 158) + # If it is not just skip the test + + # If we do run the test, it should take (slightly over) either 1 or 2 + # seconds to complete, depending upon the shell being tested. + + case "${XIT}" in + ( 129 | 1[3-9][0-9] | 2[0-4][0-9] | 25[0-5] ) + + # The script below should exit with the same code - no output + + # Or that is the result that seems best explanable. + # "set -n" in uses like this is not exactly well defined... + + # This script comes from a member of the austin group + # (they author changes to the posix shell spec - and more.) + # The author is also an (occasional?) NetBSD user. + atf_check -s exit:${XIT} -o empty -e empty ${TEST_SH} -c ' + trap "set -n" USR1 + { sleep 1; kill -USR1 $$; sleep 1; } & + false + wait && echo t || echo f + wait + echo foo + ' + ;; + esac +} + +atf_test_case set_u +set_u_head() { + atf_set "descr" "Tests that 'set -u' turns on unset var detection " \ + "and that it behaves as defined by the standard" +} +set_u_body() { + test_option_on_off u + + # first make sure it is OK to unset an unset variable + atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -ce \ + 'unset _UNSET_VARIABLE_; echo OK' + # even if -u is set + atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -cue \ + 'unset _UNSET_VARIABLE_; echo OK' + + # and that without -u accessing an unset variable is harmless + atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -ce \ + 'unset X; echo ${X}; echo OK' + # and that the unset variable test expansion works properly + atf_check -s exit:0 -o match:OKOK -e empty ${TEST_SH} -ce \ + 'unset X; printf "%s" ${X-OK}; echo OK' + + # Next test that with -u set, the shell aborts on access to unset var + # do not use -e, want to make sure it is -u that causes abort + atf_check -s not-exit:0 -o not-match:ERR -e not-empty ${TEST_SH} -c \ + 'unset X; set -u; echo ${X}; echo ERR' + # quoting should make no difference... + atf_check -s not-exit:0 -o not-match:ERR -e not-empty ${TEST_SH} -c \ + 'unset X; set -u; echo "${X}"; echo ERR' + + # Now a bunch of accesses to unset vars, with -u, in ways that are OK + atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -ce \ + 'unset X; set -u; echo ${X-GOOD}; echo OK' + atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -ce \ + 'unset X; set -u; echo ${X-OK}' + atf_check -s exit:0 -o not-match:ERR -o match:OK -e empty \ + ${TEST_SH} -ce 'unset X; set -u; echo ${X+ERR}; echo OK' + + # and some more ways that are not OK + atf_check -s not-exit:0 -o not-match:ERR -e not-empty ${TEST_SH} -c \ + 'unset X; set -u; echo ${X#foo}; echo ERR' + atf_check -s not-exit:0 -o not-match:ERR -e not-empty ${TEST_SH} -c \ + 'unset X; set -u; echo ${X%%bar}; echo ERR' + + # lastly, just while we are checking unset vars, test aborts w/o -u + atf_check -s not-exit:0 -o not-match:ERR -e not-empty ${TEST_SH} -c \ + 'unset X; echo ${X?}; echo ERR' + atf_check -s not-exit:0 -o not-match:ERR -e match:X_NOT_SET \ + ${TEST_SH} -c 'unset X; echo ${X?X_NOT_SET}; echo ERR' +} + +atf_test_case set_v +set_v_head() { + atf_set "descr" "Tests that 'set -v' turns on input read echoing " \ + "and that it behaves as defined by the standard" +} +set_v_body() { + test_option_on_off v + + # check that -v does nothing if no later input line is read + atf_check -s exit:0 \ + -o match:OKOK -o not-match:echo -o not-match:printf \ + -e empty \ + ${TEST_SH} -ec 'printf "%s" OK; set -v; echo OK; exit 0' + + # but that it does when there are multiple lines + cat <<- 'EOF' | + set -v + printf %s OK + echo OK + exit 0 + EOF + atf_check -s exit:0 \ + -o match:OKOK -o not-match:echo -o not-match:printf \ + -e match:printf -e match:OK -e match:echo \ + -e not-match:set ${TEST_SH} + + # and that it can be disabled again + cat <<- 'EOF' | + set -v + printf %s OK + set +v + echo OK + exit 0 + EOF + atf_check -s exit:0 \ + -o match:OKOK -o not-match:echo -o not-match:printf \ + -e match:printf -e match:OK -e not-match:echo \ + ${TEST_SH} + + # and lastly, that shell keywords do get output when "read" + cat <<- 'EOF' | + set -v + for i in 111 222 333 + do + printf %s $i + done + exit 0 + EOF + atf_check -s exit:0 \ + -o match:111222333 -o not-match:printf \ + -o not-match:for -o not-match:do -o not-match:done \ + -e match:printf -e match:111 -e not-match:111222 \ + -e match:for -e match:do -e match:done \ + ${TEST_SH} +} + +atf_test_case set_x +set_x_head() { + atf_set "descr" "Tests that 'set -x' turns on command exec logging " \ + "and that it behaves as defined by the standard" +} +set_x_body() { + test_option_on_off x + + # check that cmd output appears after -x is enabled + atf_check -s exit:0 \ + -o match:OKOK -o not-match:echo -o not-match:printf \ + -e not-match:printf -e match:OK -e match:echo \ + ${TEST_SH} -ec 'printf "%s" OK; set -x; echo OK; exit 0' + + # and that it stops again afer -x is disabled + atf_check -s exit:0 \ + -o match:OKOK -o not-match:echo -o not-match:printf \ + -e match:printf -e match:OK -e not-match:echo \ + ${TEST_SH} -ec 'set -x; printf "%s" OK; set +x; echo OK; exit 0' + + # also check that PS4 is output correctly + atf_check -s exit:0 \ + -o match:OK -o not-match:echo \ + -e match:OK -e match:Run:echo \ + ${TEST_SH} -ec 'PS4=Run:; set -x; echo OK; exit 0' + + return 0 + + # This one seems controversial... I suspect it is NetBSD's sh + # that is wrong to not output "for" "while" "if" ... etc + + # and lastly, that shell keywords do not get output when "executed" + atf_check -s exit:0 \ + -o match:111222333 -o not-match:printf \ + -o not-match:for \ + -e match:printf -e match:111 -e not-match:111222 \ + -e not-match:for -e not-match:do -e not-match:done \ + ${TEST_SH} -ec \ + 'set -x; for i in 111 222 333; do printf "%s" $i; done; echo; exit 0' +} + +opt_test_setup() +{ + test -n "$1" || { echo >&2 "Internal error"; exit 1; } + + cat > "$1" << 'END_OF_FUNCTIONS' +local_opt_check() +{ + local - +} + +instr() +{ + expr "$2" : "\(.*$1\)" >/dev/null +} + +save_opts() +{ + local - + + set -e + set -u + + instr e "$-" && instr u "$-" && return 0 + echo ERR +} + +fiddle_opts() +{ + set -e + set -u + + instr e "$-" && instr u "$-" && return 0 + echo ERR +} + +local_test() +{ + set +eu + + save_opts + instr '[eu]' "$-" || printf %s "OK" + + fiddle_opts + instr e "$-" && instr u "$-" && printf %s "OK" + + set +eu +} +END_OF_FUNCTIONS +} + +atf_test_case restore_local_opts +restore_local_opts_head() { + atf_set "descr" "Tests that 'local -' saves and restores options. " \ + "Note that "local" is a local shell addition" +} +restore_local_opts_body() { + atf_require_prog cat + atf_require_prog expr + + FN="test-funcs.$$" + opt_test_setup "${FN}" || atf_skip "Cannot setup test environment" + + ${TEST_SH} -ec ". './${FN}'; local_opt_check" 2>/dev/null || + atf_skip "sh extension 'local -' not supported by ${TEST_SH}" + + atf_check -s exit:0 -o match:OKOK -o not-match:ERR -e empty \ + ${TEST_SH} -ec ". './${FN}'; local_test" +} + +atf_test_case vi_emacs_VE_toggle +vi_emacs_VE_toggle_head() { + atf_set "descr" "Tests enabling vi disables emacs (and v.v - but why?)"\ + " Note that -V and -E are local shell additions" +} +vi_emacs_VE_toggle_body() { + + test_optional_on_off V E || + atf_skip "One or both V & E opts unsupported by ${TEST_SH}" + + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c ' + q() { + eval "case \"$-\" in + (*${2}*) return 1;; + (*${1}*) return 0;; + esac" + return 1 + } + x() { + echo >&2 "Option set or toggle failure:" \ + " on=$1 off=$2 set=$-" + exit 1 + } + set -V; q V E || x V E + set -E; q E V || x E V + set -V; q V E || x V E + set +EV; q "" "[VE]" || x "" VE + exit 0 + ' +} + +atf_test_case xx_bogus +xx_bogus_head() { + atf_set "descr" "Tests that attempting to set a nonsense option fails." +} +xx_bogus_body() { + # Biggest problem here is picking a "nonsense option" that is + # not implemented by any shell, anywhere. Hopefully this will do. + + # 'set' is a special builtin, so a conforming shell should exit + # on an arg error, and the ERR should not be printed. + atf_check -s not-exit:0 -o empty -e not-empty \ + ${TEST_SH} -c 'set -% ; echo ERR' +} + +atf_test_case Option_switching +Option_switching_head() { + atf_set "descr" "options can be enabled and disabled" +} +Option_switching_body() { + + # Cannot test -m, setting it causes test shell to fail... + # (test shell gets SIGKILL!) Wonder why ... something related to atf + # That is, it works if just run as "sh -c 'echo $-; set -m; echo $-'" + + # Don't bother testing toggling -n, once on, it stays on... + # (and because the test fn refuses to allow us to try) + + # Cannot test -o or -c here, or the extension -s + # they can only be used, not switched + + # these are the posix options, that all shells should implement + test_option_on_off a b C e f h u v x # m + + # and these are extensions that might not exist (non-fatal to test) + # -i and -s (and -c) are posix options, but are not required to + # be accessable via the "set" command, just the command line. + # We allow for -i to work with set, as that makes some sense, + # -c and -s do not. + test_optional_on_off E i I p q V || true + + # Also test (some) option combinations ... + # only testing posix options here, because it is easier... + test_option_on_off aeu vx Ca aCefux +} + +atf_init_test_cases() { + # tests are run in order sort of names produces, so choose names wisely + + # this one tests turning on/off all the mandatory. and extra flags + atf_add_test_case Option_switching + # and this tests the NetBSD "local -" functionality in functions. + atf_add_test_case restore_local_opts + + # no tests for -m (no idea how to do that one) + # -I (no easy way to generate the EOF it ignores) + # -i (not sure how to test that one at the minute) + # -p (because we aren't going to run tests setuid) + # -V/-E (too much effort, and a real test would be huge) + # -c (because almost all the other tests test it anyway) + # -q (because, for now, I am lazy) + # -s (coming soon, hopefully) + # -o (really +o: again, hopefully soon) + # -o longname (again, just laziness, don't wait...) + # -h/-b (because NetBSD doesn't implement them) + atf_add_test_case set_a + atf_add_test_case set_C + atf_add_test_case set_e + atf_add_test_case set_f + atf_add_test_case set_n + atf_add_test_case set_u + atf_add_test_case set_v + atf_add_test_case set_x + + atf_add_test_case vi_emacs_VE_toggle + atf_add_test_case xx_bogus +} diff --git a/contrib/netbsd-tests/bin/sh/t_redir.sh b/contrib/netbsd-tests/bin/sh/t_redir.sh new file mode 100755 index 0000000..580de88 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_redir.sh @@ -0,0 +1,903 @@ +# $NetBSD: t_redir.sh,v 1.9 2016/05/14 00:33:02 kre Exp $ +# +# Copyright (c) 2016 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + +# Any failures in this first test means it is not worth bothering looking +# for causes of failures in any other tests, make this one work first. + +# Problems with this test usually mean inadequate ATF_SHELL used for testing. +# (though if all pass but the last, it might be a TEST_SH problem.) + +atf_test_case basic_test_method_test +basic_test_method_test_head() +{ + atf_set "descr" "Tests that test method works as expected" +} +basic_test_method_test_body() +{ + cat <<- 'DONE' | + DONE + atf_check -s exit:0 -o empty -e empty ${TEST_SH} + cat <<- 'DONE' | + DONE + atf_check -s exit:0 -o match:0 -e empty ${TEST_SH} -c 'wc -l' + + cat <<- 'DONE' | + echo hello + DONE + atf_check -s exit:0 -o match:hello -e empty ${TEST_SH} + cat <<- 'DONE' | + echo hello + DONE + atf_check -s exit:0 -o match:1 -e empty ${TEST_SH} -c 'wc -l' + + cat <<- 'DONE' | + echo hello\ + world + DONE + atf_check -s exit:0 -o match:helloworld -e empty ${TEST_SH} + cat <<- 'DONE' | + echo hello\ + world + DONE + atf_check -s exit:0 -o match:2 -e empty ${TEST_SH} -c 'wc -l' + + printf '%s\n%s\n%s\n' Line1 Line2 Line3 > File + atf_check -s exit:0 -o inline:'Line1\nLine2\nLine3\n' -e empty \ + ${TEST_SH} -c 'cat File' + + cat <<- 'DONE' | + set -- X "" '' Y + echo ARGS="${#}" + echo '' -$1- -$2- -$3- -$4- + cat <File + + atf_check -s exit:0 -e empty \ + -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \ + ${TEST_SH} -c 'cat < File' + atf_check -s exit:0 -e empty \ + -o inline:'First Line\nSecond Line\nLine 3\nEND\n' \ + ${TEST_SH} -c 'cat /dev/null || : + test -f Output && atf_fail "Unable to remove Output file" +#1 + i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '> Output' + test -f Output || atf_fail "#$T: Did not make Output file" +#2 + rm -f Output 2>/dev/null || : + i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '>> Output' + test -f Output || atf_fail "#$T: Did not make Output file" +#3 + rm -f Output 2>/dev/null || : + i; atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '>| Output' + test -f Output || atf_fail "#$T: Did not make Output file" + +#4 + rm -f Output 2>/dev/null || : + i + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Hello >Output' + test -s Output || atf_fail "#$T: Did not make non-empty Output file" + test "$(cat Output)" = "Hello" || + atf_fail "#$T: Incorrect Output: Should be 'Hello' is '$(cat Output)'" +#5 + i + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Hello>!Output' + test -s Output || atf_fail "#$T: Did not make non-empty Output file" + test "$(cat Output)" = "Hello" || + atf_fail "#$T: Incorrect Output: Should be 'Hello' is '$(cat Output)'" +#6 + i + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'echo Bye >>Output' + test -s Output || atf_fail "#$T: Removed Output file" + test "$(cat Output)" = "Hello${nl}Bye" || atf_fail \ + "#$T: Incorrect Output: Should be 'Hello\\nBye' is '$(cat Output)'" +#7 + i; atf_check -s exit:0 -o inline:'line 1\nline 2\n' -e empty \ + ${TEST_SH} -c \ + 'echo line 1 > Output; echo line 2 >> Output; cat Output' + test "$(cat Output)" = "line 1${nl}line 2" || atf_fail \ + "#$T: Incorrect Output: Should be 'line 1\\nline 2' is '$(cat Output)'" +#8 + i; atf_check -s exit:0 -o inline:'line 2\n' -e empty \ + ${TEST_SH} -c 'echo line 1 > Output; echo line 2' + test "$(cat Output)" = "line 1" || atf_fail \ + "#$T: Incorrect Output: Should be 'line 1' is '$(cat Output)'" +#9 + i; atf_check -s exit:0 -o empty -e empty \ + ${TEST_SH} -c '(echo line 1; echo line 2 > Out2) > Out1' + test "$(cat Out1)" = "line 1" || atf_fail \ + "#$T: Incorrect Out1: Should be 'line 1' is '$(cat Out1)'" + test "$(cat Out2)" = "line 2" || atf_fail \ + "#$T: Incorrect Out2: Should be 'line 2' is '$(cat Out2)'" +#10 + i; atf_check -s exit:0 -o empty -e empty \ + ${TEST_SH} -c '{ echo line 1; echo line 2 > Out2;} > Out1' + test "$(cat Out1)" = "line 1" || atf_fail \ + "#$T: Incorrect Out1: Should be 'line 1' is '$(cat Out1)'" + test "$(cat Out2)" = "line 2" || atf_fail \ + "#$T: Incorrect Out2: Should be 'line 2' is '$(cat Out2)'" +#11 + i; rm -f Out1 Out2 2>/dev/null || : + cat <<- 'EOF' | + for arg in 'line 1' 'line 2' 'line 3' + do + echo "$arg" + echo "$arg" > Out1 + done > Out2 + EOF + atf_check -s exit:0 -o empty -e empty ${TEST_SH} + test "$(cat Out1)" = "line 3" || atf_fail \ + "#$T: Incorrect Out1: Should be 'line 3' is '$(cat Out1)'" + test "$(cat Out2)" = "line 1${nl}line 2${nl}line 3" || atf_fail \ + "#$T: Incorrect Out2: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out2)'" +#12 + i; rm -f Out1 Out2 2>/dev/null || : + cat <<- 'EOF' | + for arg in 'line 1' 'line 2' 'line 3' + do + echo "$arg" + echo "$arg" >> Out1 + done > Out2 + EOF + atf_check -s exit:0 -o empty -e empty ${TEST_SH} + test "$(cat Out1)" = "line 1${nl}line 2${nl}line 3" || atf_fail \ + "#$T: Incorrect Out1: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out1)'" + test "$(cat Out2)" = "line 1${nl}line 2${nl}line 3" || atf_fail \ + "#$T: Incorrect Out2: Should be 'line 1\\nline 2\\nline 3' is '$(cat Out2)'" +} + +atf_test_case fd_redirections +fd_redirections_head() +{ + atf_set "descr" "Tests redirections to/from specific descriptors" +} +fd_redirections_body() +{ + atf_require_prog /bin/echo + + cat <<- 'DONE' > helper.sh + f() { + /bin/echo nothing "$1" >& "$1" + } + for n + do + eval "f $n $n"'> file-$n' + done + DONE + cat <<- 'DONE' > reread.sh + f() { + (read -r var; echo "${var}") <&"$1" + } + for n + do + x=$( eval "f $n $n"'< file-$n' ) + test "${x}" = "nothing $n" || echo "$n" + done + DONE + + validate() + { + for n + do + test -e "file-$n" || atf_fail "file-$n not created" + C=$(cat file-"$n") + test "$C" = "nothing $n" || + atf_fail "file-$n contains '$C' not 'nothing $n'" + done + } + + atf_check -s exit:0 -e empty -o empty \ + ${TEST_SH} helper.sh 1 2 3 4 5 6 7 8 9 + validate 1 2 3 4 5 6 7 8 9 + atf_check -s exit:0 -e empty -o empty \ + ${TEST_SH} reread.sh 3 4 5 6 7 8 9 + + L=$(ulimit -n) + if [ "$L" -ge 30 ] + then + atf_check -s exit:0 -e empty -o empty \ + ${TEST_SH} helper.sh 10 15 19 20 25 29 + validate 10 15 19 20 25 29 + atf_check -s exit:0 -e empty -o empty \ + ${TEST_SH} reread.sh 10 15 19 20 25 29 + fi + if [ "$L" -ge 100 ] + then + atf_check -s exit:0 -e empty -o empty \ + ${TEST_SH} helper.sh 32 33 49 50 51 63 64 65 77 88 99 + validate 32 33 49 50 51 63 64 65 77 88 99 + atf_check -s exit:0 -e empty -o empty \ + ${TEST_SH} reread.sh 32 33 49 50 51 63 64 65 77 88 99 + fi + if [ "$L" -ge 500 ] + then + atf_check -s exit:0 -e empty -o empty \ + ${TEST_SH} helper.sh 100 101 199 200 222 333 444 499 + validate 100 101 199 200 222 333 444 499 + atf_check -s exit:0 -e empty -o empty \ + ${TEST_SH} reread.sh 100 101 199 200 222 333 444 499 + fi + if [ "$L" -gt 1005 ] + then + atf_check -s exit:0 -e empty -o empty \ + ${TEST_SH} helper.sh 1000 1001 1002 1003 1004 1005 + validate 1000 1001 1002 1003 1004 1005 + atf_check -s exit:0 -e empty -o empty \ + ${TEST_SH} reread.sh 1000 1001 1002 1003 1004 1005 + fi +} + +atf_test_case local_redirections +local_redirections_head() +{ + atf_set "descr" \ + "Tests that exec can reassign file descriptors in the shell itself" +} +local_redirections_body() +{ + cat <<- 'DONE' > helper.sh + for f + do + eval "exec $f"'> file-$f' + done + + for f + do + printf '%s\n' "Hello $f" >&"$f" + done + + for f + do + eval "exec $f"'>&-' + done + + for f + do + eval "exec $f"'< file-$f' + done + + for f + do + exec <& "$f" + read -r var || echo >&2 "No data in file-$f" + read -r x && echo >&2 "Too much data in file-${f}: $x" + test "${var}" = "Hello $f" || + echo >&2 "file-$f contains '${var}' not 'Hello $f'" + done + DONE + + atf_check -s exit:0 -o empty -e empty \ + ${TEST_SH} helper.sh 3 4 5 6 7 8 9 + + L=$(ulimit -n) + if [ "$L" -ge 30 ] + then + atf_check -s exit:0 -o empty -e empty \ + ${TEST_SH} helper.sh 10 11 13 15 16 19 20 28 29 + fi + if [ "$L" -ge 100 ] + then + atf_check -s exit:0 -o empty -e empty \ + ${TEST_SH} helper.sh 30 31 32 63 64 65 77 88 99 + fi + if [ "$L" -ge 500 ] + then + atf_check -s exit:0 -o empty -e empty \ + ${TEST_SH} helper.sh 100 101 111 199 200 201 222 333 499 + fi + if [ "$L" -ge 1005 ] + then + atf_check -s exit:0 -o empty -e empty \ + ${TEST_SH} helper.sh 1000 1001 1002 1003 1004 1005 + fi +} + +atf_test_case named_fd_redirections +named_fd_redirections_head() +{ + atf_set "descr" "Tests redirections to /dev/stdout (etc)" + +} +named_fd_redirections_body() +{ + if test -c /dev/stdout + then + atf_check -s exit:0 -o inline:'OK\n' -e empty \ + ${TEST_SH} -c 'echo OK >/dev/stdout' + atf_check -s exit:0 -o inline:'OK\n' -e empty \ + ${TEST_SH} -c '/bin/echo OK >/dev/stdout' + fi + + if test -c /dev/stdin + then + atf_require_prog cat + + echo GOOD | atf_check -s exit:0 -o inline:'GOOD\n' -e empty \ + ${TEST_SH} -c 'read var /dev/stderr >&2' + atf_check -s exit:0 -e inline:'OK\n' -o empty \ + ${TEST_SH} -c '/bin/echo OK 2>/dev/stderr >&2' + fi + + if test -c /dev/fd/8 && test -c /dev/fd/9 + then + atf_check -s exit:0 -o inline:'EIGHT\n' -e empty \ + ${TEST_SH} -c 'printf "%s\n" EIGHT 8>&1 >/dev/fd/8 | + cat 9<&0 foo;; esac' + + atf_check -s exit:0 -o empty -e empty \ + ${TEST_SH} -c 'case x in (whatever) >foo 2>&1;; esac' + + atf_check -s exit:0 -o empty -e empty \ + ${TEST_SH} -c 'case x in (whatever) >foo 2>&1 ${somewhere};; esac' +} + +atf_test_case incorrect_redirections +incorrect_redirections_head() +{ + atf_set "descr" "Tests that sh(1) correctly ignores non-redirections" +} +incorrect_redirections_body() { + + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'echo foo>' + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'read foo<' + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c 'echo foo<>' + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \ + 'echo x > '"$nl" + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \ + 'read x < '"$nl" + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \ + 'echo x <> '"$nl" + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \ + 'echo x >< anything' + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \ + 'echo x >>< anything' + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \ + 'echo x >|< anything' + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \ + 'echo x > ; read x < /dev/null || echo bad' + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \ + 'read x < & echo y > /dev/null; wait && echo bad' + + rm -f Output 2>/dev/null || : + atf_check -s exit:0 -e empty -o inline:'A Line > Output\n' \ + ${TEST_SH} -c 'echo A Line \> Output' + test -f Output && atf_file "File 'Output' appeared and should not have" + + rm -f Output 2>/dev/null || : + atf_check -s exit:0 -e empty -o empty \ + ${TEST_SH} -c 'echo A Line \>> Output' + test -f Output || atf_file "File 'Output' not created when it should" + test "$(cat Output)" = 'A Line >' || atf_fail \ + "Output file contains '$(cat Output)' instead of '"'A Line >'\' + + rm -f Output \> 2>/dev/null || : + atf_check -s exit:0 -e empty -o empty \ + ${TEST_SH} -c 'echo A Line >\> Output' + test -f Output && atf_file "File 'Output' appeared and should not have" + test -f '>' || atf_file "File '>' not created when it should" + test "$(cat '>')" = 'A Line Output' || atf_fail \ + "Output file ('>') contains '$(cat '>')' instead of 'A Line Output'" +} + +# Many more tests in t_here, so here we have just rudimentary checks +atf_test_case redir_here_doc +redir_here_doc_head() +{ + atf_set "descr" "Tests that sh(1) correctly processes 'here' doc " \ + "input redirections" +} +redir_here_doc_body() +{ + # nb: the printf is not executed, it is data + cat <<- 'DONE' | + cat <output-file + + ( printf "hello\n" >&6 ) + + exec 8&2 Hello ) + + ( printf "bye-bye\n" >&6 ) + + ( exec 8<&- ) + read bye <&8 || echo >&2 "Closed?" + echo Bye="$bye" + DONE + atf_check -s exit:0 -o match:Bye=bye-bye -e empty \ + ${TEST_SH} + + cat <<- 'DONE' | + for arg in one-4 two-24 three-14 + do + fd=${arg#*-} + file=${arg%-*} + eval "exec ${fd}>${file}" + done + + for arg in one-5 two-7 three-19 + do + fd=${arg#*-} + file=${arg%-*} + eval "exec ${fd}<${file}" + done + + ( + echo line-1 >&4 + echo line-2 >&24 + echo line-3 >&14 + echo go + ) | ( + read go + read x <&5 + read y <&7 + read z <&19 + + printf "%s\n" "${x}" "${y}" "${z}" + ) + DONE + atf_check -s exit:0 -o inline:'line-1\nline-2\nline-3\n' \ + -e empty ${TEST_SH} + + cat <<- 'DONE' | + for arg in one-4-5 two-6-7 three-8-9 four-11-10 five-3-12 + do + ofd=${arg##*-} + file=${arg%-*} + ifd=${file#*-} + file=${file%-*} + eval "exec ${ofd}>${file}" + eval "exec ${ifd}<${file}" + done + + ( ( ( echo line-1 >& 13 ) 13>&12 ) 12>&5 ) >stdout 2>errout + ( ( ( echo line-2 >& 4) 13>&12 ) 4>&7 ) >>stdout 2>>errout + ( ( ( echo line-3 >& 6) 8>&1 6>&11 >&12) 11>&9 >&7 ) >>stdout + + ( ( ( cat <&13 >&12 ) 13<&8 12>&10 ) 10>&1 8<&6 ) 6<&4 + ( ( ( cat <&4 ) <&4 6<&8 8<&11 ) + <&4 4<&6 6<&8 8<&11 ) <&4 4<&6 6<&8 8<&11 11<&3 + ( ( ( cat <&7 >&1 ) 7<&6 >&10 ) 10>&2 6<&8 ) 2>&1 + DONE + atf_check -s exit:0 -o inline:'line-1\nline-2\nline-3\n' \ + -e empty ${TEST_SH} +} + +atf_test_case ulimit_redirection_interaction +ulimit_redirection_interaction_head() +{ + atf_set "descr" "Tests interactions between redirect and ulimit -n " +} +ulimit_redirection_interaction_body() +{ + atf_require_prog ls + + cat <<- 'DONE' > helper.sh + oLIM=$(ulimit -n) + HRD=$(ulimit -H -n) + test "${oLIM}" -lt "${HRD}" && ulimit -n "${HRD}" + LIM=$(ulimit -n) + + FDs= + LFD=-1 + while [ ${LIM} -gt 16 ] + do + FD=$(( ${LIM} - 1 )) + if [ "${FD}" -eq "${LFD}" ]; then + echo >&2 "Infinite loop... (busted $(( )) ??)" + exit 1 + fi + LFD="${FD}" + + eval "exec ${FD}"'> /dev/null' + FDs="${FD}${FDs:+ }${FDs}" + + ( + FD=$(( ${LIM} + 1 )) + eval "exec ${FD}"'> /dev/null' + echo "Reached unreachable command" + ) 2>/dev/null && echo >&2 "Opened beyond limit!" + + (eval 'ls 2>&1 3>&1 4>&1 5>&1 '"${FD}"'>&1') >&"${FD}" + + LIM=$(( ${LIM} / 2 )) + ulimit -S -n "${LIM}" + done + + # Even though ulimit has been reduced, open fds should work + for FD in ${FDs} + do + echo ${FD} in ${FDs} >&"${FD}" || exit 1 + done + + ulimit -S -n "${oLIM}" + + # maybe more later... + + DONE + + atf_check -s exit:0 -o empty -e empty ${TEST_SH} helper.sh +} + +atf_test_case validate_fn_redirects +validate_fn_redirects_head() +{ + # These test cases inspired by PR bin/48875 and the sh + # changes that were required to fix it. + + atf_set "descr" "Tests various redirections applied to functions " \ + "See PR bin/48875" +} +validate_fn_redirects_body() +{ + cat <<- 'DONE' > f-def + f() { + printf '%s\n' In-Func + } + DONE + + atf_check -s exit:0 -o inline:'In-Func\nsuccess1\n' -e empty \ + ${TEST_SH} -c ". ./f-def; f ; printf '%s\n' success1" + atf_check -s exit:0 -o inline:'success2\n' -e empty \ + ${TEST_SH} -c ". ./f-def; f >/dev/null; printf '%s\n' success2" + atf_check -s exit:0 -o inline:'success3\n' -e empty \ + ${TEST_SH} -c ". ./f-def; f >&- ; printf '%s\n' success3" + atf_check -s exit:0 -o inline:'In-Func\nsuccess4\n' -e empty \ + ${TEST_SH} -c ". ./f-def; f & wait; printf '%s\n' success4" + atf_check -s exit:0 -o inline:'success5\n' -e empty \ + ${TEST_SH} -c ". ./f-def; f >&- & wait; printf '%s\n' success5" + atf_check -s exit:0 -o inline:'In-Func\nIn-Func\nsuccess6\n' -e empty \ + ${TEST_SH} -c ". ./f-def; f;f; printf '%s\n' success6" + atf_check -s exit:0 -o inline:'In-Func\nIn-Func\nsuccess7\n' -e empty \ + ${TEST_SH} -c ". ./f-def; { f;f;}; printf '%s\n' success7" + atf_check -s exit:0 -o inline:'In-Func\nIn-Func\nsuccess8\n' -e empty \ + ${TEST_SH} -c ". ./f-def; { f;f;}& wait; printf '%s\n' success8" + atf_check -s exit:0 -o inline:'In-Func\nsuccess9\n' -e empty \ + ${TEST_SH} -c \ + ". ./f-def; { f>/dev/null;f;}& wait; printf '%s\n' success9" + atf_check -s exit:0 -o inline:'In-Func\nsuccess10\n' -e empty \ + ${TEST_SH} -c \ + ". ./f-def; { f;f>/dev/null;}& wait; printf '%s\n' success10" + + # This one tests the issue etcupdate had with the original 48875 fix + atf_check -s exit:0 -o inline:'Func a\nFunc b\nFunc c\n' -e empty \ + ${TEST_SH} -c ' + f() { + echo Func "$1" + } + exec 3<&0 4>&1 + ( echo x-a; echo y-b; echo z-c ) | + while read A + do + B=${A#?-} + f "$B" <&3 >&4 + done >&2' + + # And this tests a similar condition with that same fix + cat <<- 'DONE' >Script + f() { + printf '%s' " hello $1" + } + exec 3>&1 + echo $( for i in a b c + do printf '%s' @$i; f $i >&3; done >foo + ) + printf '%s\n' foo=$(cat foo) + DONE + atf_check -s exit:0 -e empty \ + -o inline:' hello a hello b hello c\nfoo=@a@b@c\n' \ + ${TEST_SH} Script + + # Tests with sh reading stdin, which is not quite the same internal + # mechanism. + echo ". ./f-def || echo >&2 FAIL + f + printf '%s\n' stdin1 + "| atf_check -s exit:0 -o inline:'In-Func\nstdin1\n' -e empty ${TEST_SH} + + echo ' + . ./f-def || echo >&2 FAIL + f >&- + printf "%s\n" stdin2 + ' | atf_check -s exit:0 -o inline:'stdin2\n' -e empty ${TEST_SH} + + cat <<- 'DONE' > fgh.def + f() { + echo -n f >&3 + sleep 4 + echo -n F >&3 + } + g() { + echo -n g >&3 + sleep 2 + echo -n G >&3 + } + h() { + echo -n h >&3 + } + DONE + + atf_check -s exit:0 -o inline:'fFgGh' -e empty \ + ${TEST_SH} -c '. ./fgh.def || echo >&2 FAIL + exec 3>&1 + f; g; h' + + atf_check -s exit:0 -o inline:'fghGF' -e empty \ + ${TEST_SH} -c '. ./fgh.def || echo >&2 FAIL + exec 3>&1 + f & sleep 1; g & sleep 1; h; wait' + + atf_check -s exit:0 -o inline:'fFgGhX Y\n' -e empty \ + ${TEST_SH} -c '. ./fgh.def || echo >&2 FAIL + exec 3>&1 + echo X $( f ; g ; h ) Y' + + # This one is the real test for PR bin/48875. If the + # cmdsub does not complete before f g (and h) exit, + # then the 'F' & 'G' will precede 'X Y' in the output. + # If the cmdsub finishes while f & g are still running, + # then the X Y will appear before the F and G. + # The trailing "sleep 3" is just so we catch all the + # output (otherwise atf_check will be finished while + # f & g are still sleeping). + + atf_check -s exit:0 -o inline:'fghX Y\nGF' -e empty \ + ${TEST_SH} -c '. ./fgh.def || echo >&2 FAIL + exec 3>&1 + echo X $( f >&- & sleep 1; g >&- & sleep 1 ; h ) Y + sleep 3 + exec 4>&1 || echo FD_FAIL + ' + + # Do the test again to verify it also all works reading stdin + # (which is a slightly different path through the shell) + echo ' + . ./fgh.def || echo >&2 FAIL + exec 3>&1 + echo X $( f >&- & sleep 1; g >&- & sleep 1 ; h ) Y + sleep 3 + exec 4>&1 || echo FD_FAIL + ' | atf_check -s exit:0 -o inline:'fghX Y\nGF' -e empty ${TEST_SH} +} + +atf_init_test_cases() { + atf_add_test_case basic_test_method_test + atf_add_test_case do_input_redirections + atf_add_test_case do_output_redirections + atf_add_test_case fd_redirections + atf_add_test_case local_redirections + atf_add_test_case incorrect_redirections + atf_add_test_case named_fd_redirections + atf_add_test_case redir_here_doc + atf_add_test_case redir_in_case + atf_add_test_case subshell_redirections + atf_add_test_case ulimit_redirection_interaction + atf_add_test_case validate_fn_redirects +} diff --git a/contrib/netbsd-tests/bin/sh/t_redircloexec.sh b/contrib/netbsd-tests/bin/sh/t_redircloexec.sh new file mode 100755 index 0000000..7659606 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_redircloexec.sh @@ -0,0 +1,178 @@ +# $NetBSD: t_redircloexec.sh,v 1.3 2016/05/15 15:44:43 kre Exp $ +# +# Copyright (c) 2016 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Christos Zoulas. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + +mkhelper() { + name=$1 + fd=$2 + shift 2 + + echo "$@" > ./"${name}1" + echo "echo ${name}2" ">&${fd}" > ./"${name}2" +} + +runhelper() { + ${TEST_SH} "./${1}1" +} + +cleanhelper() { + # not really needed, atf cleans up... + rm -f ./"${1}1" ./"${1}2" out +} + +atf_test_case exec_redir_closed +exec_redir_closed_head() { + atf_set "descr" "Tests that redirections created by exec are closed on exec" +} +exec_redir_closed_body() { + + mkhelper exec 6 \ + "exec 6> out; echo exec1 >&6; ${TEST_SH} exec2; exec 6>&-" + + atf_check -s exit:0 -o empty -e not-empty ${TEST_SH} ./exec1 + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -e ./exec1 + + mkhelper exec 9 \ + "exec 9> out; echo exec1 >&9; ${TEST_SH} exec2" + + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} ./exec1 + + mkhelper exec 8 \ + "exec 8> out; printf OK; echo exec1 >&8;" \ + "printf OK; ${TEST_SH} exec2; printf ERR" + + atf_check -s not-exit:0 -o match:OKOK -o not-match:ERR -e not-empty \ + ${TEST_SH} -e ./exec1 + + mkhelper exec 7 \ + "exec 7> out; printf OK; echo exec1 >&7;" \ + "printf OK; ${TEST_SH} exec2 || printf ERR" + + atf_check -s exit:0 -o match:OKOKERR -e not-empty \ + ${TEST_SH} ./exec1 + + cleanhelper exec +} + +atf_test_case exec_redir_open +exec_redir_open_head() { + atf_set "descr" "Tests that redirections created by exec can remain open" +} +exec_redir_open_body() { + + mkhelper exec 6 \ + "exec 6> out 6>&6; echo exec1 >&6; ${TEST_SH} exec2; exec 6>&-" + + atf_check -s exit:0 -o empty -e empty ${TEST_SH} ./exec1 + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -e ./exec1 + + mkhelper exec 9 \ + "exec 9> out ; echo exec1 >&9; ${TEST_SH} exec2 9>&9" + + atf_check -s exit:0 -o empty -e empty ${TEST_SH} ./exec1 + + mkhelper exec 8 \ + "exec 8> out; printf OK; exec 8>&8; echo exec1 >&8;" \ + "printf OK; ${TEST_SH} exec2; printf OK" + + atf_check -s exit:0 -o match:OKOKOK -e empty \ + ${TEST_SH} -e ./exec1 + + mkhelper exec 7 \ + "exec 7> out; printf OK; echo exec1 >&7;" \ + "printf OK; ${TEST_SH} 7>&7 exec2; printf OK" + + atf_check -s exit:0 -o match:OKOKOK -e empty \ + ${TEST_SH} -e ./exec1 + + cleanhelper exec +} + +atf_test_case loop_redir_open +loop_redir_open_head() { + atf_set "descr" "Tests that redirections in loops don't close on exec" +} +loop_redir_open_body() { + mkhelper for 3 "for x in x; do ${TEST_SH} ./for2; done 3>out" + atf_check -s exit:0 \ + -o empty \ + -e empty \ + ${TEST_SH} ./for1 + cleanhelper for +} + +atf_test_case compound_redir_open +compound_redir_open_head() { + atf_set "descr" "Tests that redirections in compound statements don't close on exec" +} +compound_redir_open_body() { + mkhelper comp 3 "{ ${TEST_SH} ./comp2; } 3>out" + atf_check -s exit:0 \ + -o empty \ + -e empty \ + ${TEST_SH} ./comp1 + cleanhelper comp +} + +atf_test_case simple_redir_open +simple_redir_open_head() { + atf_set "descr" "Tests that redirections in simple commands don't close on exec" +} +simple_redir_open_body() { + mkhelper simp 4 "${TEST_SH} ./simp2 4>out" + atf_check -s exit:0 \ + -o empty \ + -e empty \ + ${TEST_SH} ./simp1 + cleanhelper simp +} + +atf_test_case subshell_redir_open +subshell_redir_open_head() { + atf_set "descr" "Tests that redirections on subshells don't close on exec" +} +subshell_redir_open_body() { + mkhelper comp 5 "( ${TEST_SH} ./comp2; ${TEST_SH} ./comp2 ) 5>out" + atf_check -s exit:0 \ + -o empty \ + -e empty \ + ${TEST_SH} ./comp1 + cleanhelper comp +} + +atf_init_test_cases() { + atf_add_test_case exec_redir_closed + atf_add_test_case exec_redir_open + atf_add_test_case loop_redir_open + atf_add_test_case compound_redir_open + atf_add_test_case simple_redir_open + atf_add_test_case subshell_redir_open +} diff --git a/contrib/netbsd-tests/bin/sh/t_set_e.sh b/contrib/netbsd-tests/bin/sh/t_set_e.sh new file mode 100755 index 0000000..b56ab22 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_set_e.sh @@ -0,0 +1,305 @@ +# $NetBSD: t_set_e.sh,v 1.4 2016/03/31 16:22:27 christos Exp $ +# +# Copyright (c) 2007 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# references: +# http://www.opengroup.org/onlinepubs/009695399/utilities/set.html +# http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html + +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + +failwith() +{ + case "$SH_FAILS" in + "") SH_FAILS=`echo "$1"`;; + *) SH_FAILS="$SH_FAILS"`echo; echo "$1"`;; + esac +} + +check1() +{ + #echo "$TEST_SH -c $1" + result=`$TEST_SH -c "$1" 2>/dev/null | tr '\n' ' ' | sed 's/ *$//'` + if [ "$result" != "$2" ]; then + MSG=`printf "%-56s %-8s %s" "$3" "$result" "$2"` + failwith "$MSG" + failcount=`expr $failcount + 1` + fi + count=`expr $count + 1` +} + +# direct check: try the given expression. +dcheck() +{ + check1 "$1" "$2" "$1" +} + +# eval check: indirect through eval. +# as of this writing, this changes the behavior pretty drastically and +# is thus important to test. (PR bin/29861) +echeck() +{ + check1 'eval '"'( $1 )'" "$2" "eval '($1)'" +} + +atf_test_case all +all_head() { + atf_set "descr" "Tests that 'set -e' works correctly" +} +all_body() { + count=0 + failcount=0 + + # make sure exiting from a subshell behaves as expected + dcheck '(set -e; exit 1; echo ERR$?); echo OK$?' 'OK1' + echeck '(set -e; exit 1; echo ERR$?); echo OK$?' 'OK1' + + # first, check basic functioning. + # The ERR shouldn't print; the result of the () should be 1. + # Henceforth we'll assume that we don't need to check $?. + dcheck '(set -e; false; echo ERR$?); echo OK$?' 'OK1' + echeck '(set -e; false; echo ERR$?); echo OK$?' 'OK1' + + # these cases should be equivalent to the preceding. + dcheck '(set -e; /nonexistent; echo ERR); echo OK' 'OK' + echeck '(set -e; /nonexistent; echo ERR); echo OK' 'OK' + dcheck '(set -e; nonexistent-program-on-path; echo ERR); echo OK' 'OK' + echeck '(set -e; nonexistent-program-on-path; echo ERR); echo OK' 'OK' + dcheck 'f() { false; }; (set -e; f; echo ERR); echo OK' 'OK' + echeck 'f() { false; }; (set -e; f; echo ERR); echo OK' 'OK' + dcheck 'f() { return 1; }; (set -e; f; echo ERR); echo OK' 'OK' + echeck 'f() { return 1; }; (set -e; f; echo ERR); echo OK' 'OK' + + # but! with set -e, the false should cause an *immediate* exit. + # The return form should not, as such, but there's no way to + # distinguish it. + dcheck 'f() { false; echo ERR; }; (set -e; f); echo OK' 'OK' + echeck 'f() { false; echo ERR; }; (set -e; f); echo OK' 'OK' + + # set is not scoped, so these should not exit at all. + dcheck 'f() { set +e; false; echo OK; }; (set -e; f); echo OK' 'OK OK' + echeck 'f() { set +e; false; echo OK; }; (set -e; f); echo OK' 'OK OK' + + # according to the standard, only failing *simple* commands + # cause an exit under -e. () is not a simple command. + # Correct (per POSIX): + #dcheck '(set -e; (set +e; false; echo OK; false); echo OK)' 'OK OK' + #echeck '(set -e; (set +e; false; echo OK; false); echo OK)' 'OK OK' + # Wrong current behavior: + dcheck '(set -e; (set +e; false; echo OK; false); echo OK)' 'OK' + echeck '(set -e; (set +e; false; echo OK; false); echo OK)' 'OK' + + # make sure an inner nested shell does exit though. + dcheck '(set -e; (false; echo ERR)); echo OK' 'OK' + + # The left hand side of an || or && is explicitly tested and + # thus should not cause an exit. Furthermore, because a || or + # && expression is not a simple command, there should be no + # exit even if the overall result is false. + dcheck '(set -e; false || true; echo OK); echo OK' 'OK OK' + echeck '(set -e; false || true; echo OK); echo OK' 'OK OK' + dcheck '(set -e; false && true; echo OK); echo OK' 'OK OK' + echeck '(set -e; false && true; echo OK); echo OK' 'OK OK' + + # However, the right hand side is not tested, so a failure + # there *should* cause an exit, regardless of whether it + # appears inside a non-simple command. + # + # Note that in at least one place the standard does not + # distinguish between the left and right hand sides of + # logical operators. It is possible that for strict + # compliance these need to not exit; however, if so that + # should probably be limited to when some strict-posix setting + # is in effect and tested accordingly. + # + dcheck '(set -e; false || false; echo ERR); echo OK' 'OK' + dcheck '(set -e; true && false; echo ERR); echo OK' 'OK' + echeck '(set -e; false || false; echo ERR); echo OK' 'OK' + echeck '(set -e; true && false; echo ERR); echo OK' 'OK' + + # correct: + #dcheck '(set -e; false && false; echo ERR); echo OK' 'OK' + #echeck '(set -e; false && false; echo ERR); echo OK' 'OK' + + # wrong current behavior: + dcheck '(set -e; false && false; echo ERR); echo OK' 'ERR OK' + echeck '(set -e; false && false; echo ERR); echo OK' 'ERR OK' + + # A failure that is not reached because of short-circuit + # evaluation should not cause an exit, however. + dcheck '(set -e; true || false; echo OK); echo OK' 'OK OK' + echeck '(set -e; true || false; echo OK); echo OK' 'OK OK' + + # For completeness, test the other two combinations. + dcheck '(set -e; true || true; echo OK); echo OK' 'OK OK' + dcheck '(set -e; true && true; echo OK); echo OK' 'OK OK' + echeck '(set -e; true || true; echo OK); echo OK' 'OK OK' + echeck '(set -e; true && true; echo OK); echo OK' 'OK OK' + + # likewise, none of these should exit. + dcheck '(set -e; while false; do :; done; echo OK); echo OK' 'OK OK' + dcheck '(set -e; if false; then :; fi; echo OK); echo OK' 'OK OK' + # problematic :-) + #dcheck '(set -e; until false; do :; done; echo OK); echo OK' 'OK OK' + dcheck '(set -e; until [ "$t" = 1 ]; do t=1; done; echo OK); echo OK' \ + 'OK OK' + echeck '(set -e; while false; do :; done; echo OK); echo OK' 'OK OK' + echeck '(set -e; if false; then :; fi; echo OK); echo OK' 'OK OK' + echeck '(set -e; until [ "$t" = 1 ]; do t=1; done; echo OK); echo OK' \ + 'OK OK' + + # the bang operator tests its argument and thus the argument + # should not cause an exit. it is also not a simple command (I + # believe) so it also shouldn't exit even if it yields a false + # result. + dcheck '(set -e; ! false; echo OK); echo OK' 'OK OK' + dcheck '(set -e; ! true; echo OK); echo OK' 'OK OK' + echeck '(set -e; ! false; echo OK); echo OK' 'OK OK' + echeck '(set -e; ! true; echo OK); echo OK' 'OK OK' + + # combined case with () and &&; the inner expression is false + # but does not itself exit, and the () should not cause an + # exit even when failing. + # correct: + #dcheck '(set -e; (false && true); echo OK); echo OK' 'OK OK' + #echeck '(set -e; (false && true); echo OK); echo OK' 'OK OK' + # wrong current behavior: + dcheck '(set -e; (false && true); echo OK); echo OK' 'OK' + echeck '(set -e; (false && true); echo OK); echo OK' 'OK' + + # pipelines. only the right-hand end is significant. + dcheck '(set -e; false | true; echo OK); echo OK' 'OK OK' + echeck '(set -e; false | true; echo OK); echo OK' 'OK OK' + dcheck '(set -e; true | false; echo ERR); echo OK' 'OK' + echeck '(set -e; true | false; echo ERR); echo OK' 'OK' + + dcheck '(set -e; while true | false; do :; done; echo OK); echo OK' \ + 'OK OK' + dcheck '(set -e; if true | false; then :; fi; echo OK); echo OK' \ + 'OK OK' + + + # According to dsl@ in PR bin/32282, () is not defined as a + # subshell, only as a grouping operator [and a scope, I guess] + + # (This is incorrect. () is definitely a sub-shell) + + # so the nested false ought to cause the whole shell to exit, + # not just the subshell. dholland@ would like to see C&V, + # because that seems like a bad idea. (Among other things, it + # would break all the above test logic, which relies on being + # able to isolate set -e behavior inside ().) However, I'm + # going to put these tests here to make sure the issue gets + # dealt with sometime. + # + # XXX: the second set has been disabled in the name of making + # all tests "pass". + # + # As they should be, they are utter nonsense. + + # 1. error if the whole shell exits (current correct behavior) + dcheck 'echo OK; (set -e; false); echo OK' 'OK OK' + echeck 'echo OK; (set -e; false); echo OK' 'OK OK' + # 2. error if the whole shell does not exit (dsl's suggested behavior) + #dcheck 'echo OK; (set -e; false); echo ERR' 'OK' + #echeck 'echo OK; (set -e; false); echo ERR' 'OK' + + # The current behavior of the shell is that it exits out as + # far as -e is set and then stops. This is probably a + # consequence of it handling () wrong, but it's a somewhat + # curious compromise position between 1. and 2. above. + dcheck '(set -e; (false; echo ERR); echo ERR); echo OK' 'OK' + echeck '(set -e; (false; echo ERR); echo ERR); echo OK' 'OK' + + # backquote expansion (PR bin/17514) + + # (in-)correct + #dcheck '(set -e; echo ERR `false`; echo ERR); echo OK' 'OK' + #dcheck '(set -e; echo ERR $(false); echo ERR); echo OK' 'OK' + #dcheck '(set -e; echo ERR `exit 3`; echo ERR); echo OK' 'OK' + #dcheck '(set -e; echo ERR $(exit 3); echo ERR); echo OK' 'OK' + # Not-wrong current behavior + # the exit status of ommand substitution is ignored in most cases + # None of these should be causing the shell to exit. + dcheck '(set -e; echo ERR `false`; echo ERR); echo OK' 'ERR ERR OK' + dcheck '(set -e; echo ERR $(false); echo ERR); echo OK' 'ERR ERR OK' + dcheck '(set -e; echo ERR `exit 3`; echo ERR); echo OK' 'ERR ERR OK' + dcheck '(set -e; echo ERR $(exit 3); echo ERR); echo OK' 'ERR ERR OK' + + # This is testing one case (the case?) where the exit status is used + dcheck '(set -e; x=`false`; echo ERR); echo OK' 'OK' + dcheck '(set -e; x=$(false); echo ERR); echo OK' 'OK' + dcheck '(set -e; x=`exit 3`; echo ERR); echo OK' 'OK' + dcheck '(set -e; x=$(exit 3); echo ERR); echo OK' 'OK' + + # correct (really just commented out incorrect nonsense) + #echeck '(set -e; echo ERR `false`; echo ERR); echo OK' 'OK' + #echeck '(set -e; echo ERR $(false); echo ERR); echo OK' 'OK' + #echeck '(set -e; echo ERR `exit 3`; echo ERR); echo OK' 'OK' + #echeck '(set -e; echo ERR $(exit 3); echo ERR); echo OK' 'OK' + + # not-wrong current behavior (as above) + echeck '(set -e; echo ERR `false`; echo ERR); echo OK' 'ERR ERR OK' + echeck '(set -e; echo ERR $(false); echo ERR); echo OK' 'ERR ERR OK' + echeck '(set -e; echo ERR `exit 3`; echo ERR); echo OK' 'ERR ERR OK' + echeck '(set -e; echo ERR $(exit 3); echo ERR); echo OK' 'ERR ERR OK' + + echeck '(set -e; x=`false`; echo ERR); echo OK' 'OK' + echeck '(set -e; x=$(false); echo ERR); echo OK' 'OK' + echeck '(set -e; x=`exit 3`; echo ERR); echo OK' 'OK' + echeck '(set -e; x=$(exit 3); echo ERR); echo OK' 'OK' + + # shift (PR bin/37493) + # correct + # Actually, both ways are correct, both are permitted + #dcheck '(set -e; shift || true; echo OK); echo OK' 'OK OK' + #echeck '(set -e; shift || true; echo OK); echo OK' 'OK OK' + # (not-) wrong current behavior + #dcheck '(set -e; shift || true; echo OK); echo OK' 'OK' + #echeck '(set -e; shift || true; echo OK); echo OK' 'OK' + + # what is wrong is this test assuming one behaviour or the other + # (and incidentally this has nothing whatever to do with "-e", + # the test should really be moved elsewhere...) + # But for now, leave it here, and correct it: + dcheck '(set -e; shift && echo OK); echo OK' 'OK' + echeck '(set -e; shift && echo OK); echo OK' 'OK' + + # Done. + + if [ "x$SH_FAILS" != x ]; then + printf '%-56s %-8s %s\n' "Expression" "Result" "Should be" + echo "$SH_FAILS" + atf_fail "$failcount of $count failed cases" + else + atf_pass + fi +} + +atf_init_test_cases() { + atf_add_test_case all +} diff --git a/contrib/netbsd-tests/bin/sh/t_shift.sh b/contrib/netbsd-tests/bin/sh/t_shift.sh new file mode 100755 index 0000000..f65c6c2 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_shift.sh @@ -0,0 +1,181 @@ +# $NetBSD: t_shift.sh,v 1.2 2016/05/17 09:05:14 kre Exp $ +# +# Copyright (c) 2016 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + +atf_test_case basic_shift_test +basic_shift_test_head() { + atf_set "descr" "Test correct operation of valid shifts" +} +basic_shift_test_body() { + + for a in \ + "one-arg::0:one-arg" \ + "one-arg:1:0:one-arg" \ + "one-arg:0:1 one-arg" \ + "a b c::2 b c:a" \ + "a b c:1:2 b c:a" \ + "a b c:2:1 c:a:b" \ + "a b c:3:0:a:b:c" \ + "a b c:0:3 a b c" \ + "a b c d e f g h i j k l m n o p:1:15 b c d e f g h i j k l m n o p"\ + "a b c d e f g h i j k l m n o p:9:7 j k l m n o p:a:b:c:g:h:i" \ + "a b c d e f g h i j k l m n o p:13:3 n o p:a:b:c:d:k:l:m" \ + "a b c d e f g h i j k l m n o p:16:0:a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p" + do + oIFS="${IFS}" + IFS=:; set -- $a + IFS="${oIFS}" + + init="$1"; n="$2"; res="$3"; shift 3 + + not= + for b + do + not="${not} -o not-match:$b" + done + + atf_check -s exit:0 -o "match:${res}" ${not} -e empty \ + ${TEST_SH} -c "set -- ${init}; shift $n;"' echo "$# $*"' + done + + atf_check -s exit:0 -o match:complete -o not-match:ERR -e empty \ + ${TEST_SH} -c \ + 'set -- a b c d e;while [ $# -gt 0 ];do shift||echo ERR;done;echo complete' +} + +atf_test_case excessive_shift +excessive_shift_head() { + atf_set "descr" "Test acceptable operation of shift too many" +} +# In: +# +# http://pubs.opengroup.org/onlinepubs/9699919799 +# /utilities/V3_chap02.html#tag_18_26_01 +# +# (that URL should be one line, with the /util... immediately after ...9799) +# +# POSIX says of shift (in the "EXIT STATUS" paragraph): +# +# If the n operand is invalid or is greater than "$#", this may be considered +# a syntax error and a non-interactive shell may exit; if the shell does not +# exit in this case, a non-zero exit status shall be returned. +# Otherwise, zero shall be returned. +# +# NetBSD's sh treats it as an error and exits (if non-interactive, as here), +# other shells do not. +# +# Either behaviour is acceptable - so the test allows for both +# (and checks that if the shell does not exit, "shift" returns status != 0) + +excessive_shift_body() { + for a in \ + "one-arg:2" \ + "one-arg:4" \ + "one-arg:13" \ + "one two:3" \ + "one two:7" \ + "one two three four five:6" \ + "I II III IV V VI VII VIII IX X XI XII XIII XIV XV:16" \ + "I II III IV V VI VII VIII IX X XI XII XIII XIV XV:17" \ + "I II III IV V VI VII VIII IX X XI XII XIII XIV XV:30" \ + "I II III IV V VI VII VIII IX X XI XII XIII XIV XV:9999" + do + oIFS="${IFS}" + IFS=:; set -- $a + IFS="${oIFS}" + + atf_check -s not-exit:0 -o match:OK -o not-match:ERR \ + -e ignore ${TEST_SH} -c \ + "set -- $1 ;"'echo OK:$#-'"$2;shift $2 && echo ERR" + done +} + +atf_test_case function_shift +function_shift_head() { + atf_set "descr" "Test that shift in a function does not affect outside" +} +function_shift_body() { + : # later... +} + +atf_test_case non_numeric_shift +non_numeric_shift_head() { + atf_set "descr" "Test that non-numeric args to shift are detected" +} + +# from the DESCRIPTION section at the URL mentioned with the excessive_shift +# test: +# +# The value n shall be an unsigned decimal integer ... +# +# That is not hex (octal will be treated as if it were decimal, a leading 0 +# will simply be ignored - we test for this by giving an "octal" value that +# would be OK if parsed as octal, but not if parsed (correctly) as decimal) +# +# Obviously total trash like roman numerals or alphabetic strings are out. +# +# Also no signed values (no + or -) and not a string that looks kind of like +# a number, but only if you're generous +# +# But as the EXIT STATUS section quoted above says, with an invalid 'n' +# the shell has the option of exiting, or returning status != 0, so +# again this test allows both. + +non_numeric_shift_body() { + + # there are 9 args set, 010 is 8 if parsed octal, 10 decimal + for a in a I 0x12 010 5V -1 ' ' '' +1 ' 1' + do + atf_check -s not-exit:0 -o empty -e ignore ${TEST_SH} -c \ + "set -- a b c d e f g h i; shift '$a' && echo ERROR" + done +} + +atf_test_case too_many_args +too_many_args_head() { + # See PR bin/50896 + atf_set "descr" "Test that sh detects invalid extraneous args to shift" +} +# This is a syntax error, a non-interactive shell (us) must exit $? != 0 +too_many_args_body() { + # This tests the bug in PR bin/50896 is fixed + + for a in "1 1" "1 0" "1 2 3" "1 foo" "1 --" "-- 1" + do + atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \ + " set -- a b c d; shift ${a} ; echo FAILED " + done +} + +atf_init_test_cases() { + atf_add_test_case basic_shift_test + atf_add_test_case excessive_shift + atf_add_test_case function_shift + atf_add_test_case non_numeric_shift + atf_add_test_case too_many_args +} diff --git a/contrib/netbsd-tests/bin/sh/t_ulimit.sh b/contrib/netbsd-tests/bin/sh/t_ulimit.sh new file mode 100755 index 0000000..094a2ee --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_ulimit.sh @@ -0,0 +1,57 @@ +# $NetBSD: t_ulimit.sh,v 1.3 2016/03/27 14:50:01 christos Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + +# ulimit builtin test. + +atf_test_case limits +limits_head() { + atf_set "descr" "Checks for limits flags" +} + +get_ulimits() { + local limits=$(${TEST_SH} -c 'ulimit -a' | + sed -e 's/.*\(-[A-Za-z0-9]\)[^A-Za-z0-9].*/\1/' | sort -u) + if [ -z "$limits" ]; then + # grr ksh + limits="-a -b -c -d -f -l -m -n -p -r -s -t -v" + fi + echo "$limits" +} + +limits_body() { + atf_check -s eq:0 -o ignore -e empty ${TEST_SH} -c "ulimit -a" + for l in $(get_ulimits) + do + atf_check -s eq:0 -o ignore -e empty ${TEST_SH} -c "ulimit $l" + done +} + +atf_init_test_cases() { + atf_add_test_case limits +} diff --git a/contrib/netbsd-tests/bin/sh/t_varquote.sh b/contrib/netbsd-tests/bin/sh/t_varquote.sh new file mode 100755 index 0000000..3811d85 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_varquote.sh @@ -0,0 +1,134 @@ +# $NetBSD: t_varquote.sh,v 1.5 2016/03/27 14:50:01 christos Exp $ +# +# Copyright (c) 2007 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + +# Variable quoting test. + +check() { + if [ "$1" != "$2" ] + then + atf_fail "expected [$2], found [$1]" 1>&2 + fi +} + +atf_test_case all +all_head() { + atf_set "descr" "Basic checks for variable quoting" +} +all_body() { + + cat <<-'EOF' > script.sh + T=0 + check() { + T=$((${T} + 1)) + + if [ "$1" != "$2" ] + then + printf '%s\n' "T${T}: expected [$2], found [$1]" + exit 1 + fi + } + + #1 + foo='${a:-foo}' + check "$foo" '${a:-foo}' + #2 + foo="${a:-foo}" + check "$foo" "foo" + #3 + foo=${a:-"'{}'"} + check "$foo" "'{}'" + #4 + foo=${a:-${b:-"'{}'"}} + check "$foo" "'{}'" + #5 + # ${ } The ' are inside ".." so are literal (not quotes). + foo="${a-'}'}" + check "$foo" "''}" + #6 + # The rules for quoting in ${var-word} expressions are somewhat + # weird, in the following there is not one quoted string being + # assigned to foo (with internally quoted sub-strings), rather + # it is a mixed quoted/unquoted string, with parts that are + # quoted, separated by 2 unquoted sections... + # qqqqqqqqqq uuuuuuuuuu qq uuuu qqqq + foo="${a:-${b:-"${c:-${d:-"x}"}}y}"}}z}" + # " z*" + # ${a:- } + # ${b:- } + # " y*" + # ${c:- } + # ${d:- } + # "x*" + check "$foo" "x}y}z}" + #7 + # And believe it or not, this is the one that gives + # most problems, with 3 different observed outputs... + # qqqqq qq q is one interpretation + # qqqqq QQQQ q is another (most common) + # (the third is syntax error...) + foo="${a:-"'{}'"}" + check "$foo" "'{}'" + + EOF + + OUT=$( ${TEST_SH} script.sh 2>&1 ) + if [ $? -ne 0 ] + then + atf_fail "${OUT}" + elif [ -n "${OUT}" ] + then + atf_fail "script.sh unexpectedly said: ${OUT}" + fi +} + +atf_test_case nested_quotes_multiword +nested_quotes_multiword_head() { + atf_set "descr" "Tests that having nested quoting in a multi-word" \ + "string works (PR bin/43597)" +} +nested_quotes_multiword_body() { + atf_check -s eq:0 -o match:"first-word second-word" -e empty \ + ${TEST_SH} -c 'echo "${foo:="first-word"} second-word"' +} + +atf_test_case default_assignment_with_arith +default_assignment_with_arith_head() { + atf_set "descr" "Tests default variable assignment with arithmetic" \ + "string works (PR bin/50827)" +} +default_assignment_with_arith_body() { + atf_check -s eq:0 -o empty -e empty ${TEST_SH} -c ': "${x=$((1))}"' + atf_check -s eq:0 -o match:1 -e empty ${TEST_SH} -c 'echo "${x=$((1))}"' +} + +atf_init_test_cases() { + atf_add_test_case all + atf_add_test_case nested_quotes_multiword + atf_add_test_case default_assignment_with_arith +} diff --git a/contrib/netbsd-tests/bin/sh/t_varval.sh b/contrib/netbsd-tests/bin/sh/t_varval.sh new file mode 100755 index 0000000..94e306b --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_varval.sh @@ -0,0 +1,251 @@ +# $NetBSD: t_varval.sh,v 1.1 2016/03/16 15:49:19 christos Exp $ +# +# Copyright (c) 2016 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + +# Test all kinds of weird values in various ways to use shell $... expansions + +oneline() +{ + q="'" + test $# -eq 4 && q="" + + v=$( printf '\\%3.3o' $(( $2 & 0xFF )) ) + printf "%s" "$1" + if [ $2 != 39 ]; then + printf "%sprefix${v}suffix%s" "$q" "$q" + elif [ $# -ne 4 ]; then + printf %s prefix\"\'\"suffix + else + printf %s prefix\'suffix + fi + printf "%s\n" "$3" +} + +mkdata() { + quote= pfx= + while [ $# -gt 0 ] + do + case "$1" in + --) shift; break;; + -q) quote=no; shift; continue;; + esac + + pfx="${pfx}${pfx:+ }${1}" + shift + done + + sfx= + while [ $# -gt 0 ] + do + sfx="${sfx}${sfx:+ }${1}" + shift + done + + i=1 # '\0' is not expected to work, anywhere... + while [ $i -lt 256 ] + do + oneline "${pfx}" "$i" "${sfx}" $quote + i=$(( $i + 1 )) + done +} + +atf_test_case aaa +aaa_head() { + atf_set "descr" "Check that this test has a hope of working. " \ + "Just give up on these tests if the aaa test fails". +} +aaa_body() { + oneline "echo " 9 '' | + atf_check -s exit:0 -o inline:'prefix\tsuffix\n' -e empty \ + ${TEST_SH} + + oneline "VAR=" 65 '; echo "${#VAR}:${VAR}"' | + atf_check -s exit:0 -o inline:'13:prefixAsuffix\n' -e empty \ + ${TEST_SH} + + oneline "VAR=" 1 '; echo "${#VAR}:${VAR}"' | + atf_check -s exit:0 -o inline:'13:prefixsuffix\n' -e empty \ + ${TEST_SH} + + oneline "VAR=" 10 '; echo "${#VAR}:${VAR}"' | + atf_check -s exit:0 -o inline:'13:prefix\nsuffix\n' -e empty \ + ${TEST_SH} + + rm -f prefix* 2>/dev/null || : + oneline "echo hello >" 45 "" | + atf_check -s exit:0 -o empty -e empty ${TEST_SH} + test -f "prefix-suffix" || + atf_fail "failed to create prefix-suffix (45)" + test -s "prefix-suffix" || + atf_fail "no data in prefix-suffix (45)" + test "$(cat prefix-suffix)" = "hello" || + atf_fail "incorrect data in prefix-suffix (45)" + + return 0 +} + +atf_test_case assignment +assignment_head() { + atf_set "descr" "Check that all chars can be assigned to vars" +} +assignment_body() { + atf_require_prog grep + atf_require_prog rm + + rm -f results || : + mkdata "VAR=" -- '; echo ${#VAR}' | + atf_check -s exit:0 -o save:results -e empty ${TEST_SH} + test -z $( grep -v "^13$" results ) || + atf_fail "Incorrect lengths: $(grep -nv '^13$' results)" + + return 0 +} + +atf_test_case cmdline +cmdline_head() { + atf_set "descr" "Check vars containing all chars can be used" +} +cmdline_body() { + atf_require_prog rm + atf_require_prog wc + + rm -f results || : + mkdata "VAR=" -- '; echo "${VAR}"' | + atf_check -s exit:0 -o save:results -e empty ${TEST_SH} + + # 256 because one output line contains a \n ... + test $( wc -l < results ) -eq 256 || + atf_fail "incorrect line count in results" + test $(wc -c < results) -eq $(( 255 * 14 )) || + atf_fail "incorrect character count in results" + + return 0 +} + +atf_test_case redirect +redirect_head() { + atf_set "descr" "Check vars containing all chars can be used" +} +redirect_body() { + atf_require_prog ls + atf_require_prog wc + atf_require_prog rm + atf_require_prog mkdir + atf_require_prog rmdir + + nl=' +' + + rm -f prefix* suffix || : + + mkdir prefix # one of the files will be prefix/suffix + mkdata "VAR=" -- '; echo "${VAR}" > "${VAR}"' | + atf_check -s exit:0 -o empty -e empty ${TEST_SH} + + test -f "prefix/suffix" || + atf_fail "Failed to create file in subdirectory" + test $( wc -l < "prefix/suffix" ) -eq 1 || + atf_fail "Not exactly one line in prefix/suffix file" + + atf_check -s exit:0 -o empty -e empty rm "prefix/suffix" + atf_check -s exit:0 -o empty -e empty rmdir "prefix" + + test -f "prefix${nl}suffix" || + atf_fail "Failed to create file with newline in its name" + test $( wc -l < "prefix${nl}suffix" ) -eq 2 || + atf_fail "NewLine file did not contain embedded newline" + + atf_check -s exit:0 -o empty -e empty rm "prefix${nl}suffix" + + # Now there should be 253 files left... + test $( ls | wc -l ) -eq 253 || + atf_fail \ + "Did not create all expected files: wanted: 253, found ($( ls | wc -l ))" + + # and each of them should have a name that is 13 chars long (+ \n) + test $( ls | wc -c ) -eq $(( 253 * 14 )) || + atf_fail "File names do not appear to be as expected" + + return 0 +} + +atf_test_case read +read_head() { + atf_set "descr" "Check vars containing all chars can be used" +} +read_body() { + atf_require_prog ls + atf_require_prog wc + atf_require_prog rm + atf_require_prog mkdir + atf_require_prog rmdir + + nl=' +' + + rm -f prefix* suffix || : + + mkdir prefix # one of the files will be prefix/suffix + mkdata -q | + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c ' + while read -r VAR + do + # skip the mess made by embedded newline + case "${VAR}" in + (prefix | suffix) continue;; + esac + echo "${VAR}" > "${VAR}" + done' + + test -f "prefix/suffix" || + atf_fail "Failed to create file in subdirectory" + test $( wc -l < "prefix/suffix" ) -eq 1 || + atf_fail "Not exactly one line in prefix/suffix file" + + atf_check -s exit:0 -o empty -e empty rm "prefix/suffix" + atf_check -s exit:0 -o empty -e empty rmdir "prefix" + + # Now there should be 253 files left... + test $( ls | wc -l ) -eq 253 || + atf_fail \ + "Did not create all expected files: wanted: 253, found ($( ls | wc -l ))" + + # and each of them should have a name that is 13 chars long (+ \n) + test $( ls | wc -c ) -eq $(( 253 * 14 )) || + atf_fail "File names do not appear to be as expected" + + return 0 +} + +atf_init_test_cases() { + atf_add_test_case aaa + atf_add_test_case assignment + atf_add_test_case cmdline + atf_add_test_case redirect + atf_add_test_case read +} diff --git a/contrib/netbsd-tests/bin/sh/t_wait.sh b/contrib/netbsd-tests/bin/sh/t_wait.sh new file mode 100755 index 0000000..eaad7e0 --- /dev/null +++ b/contrib/netbsd-tests/bin/sh/t_wait.sh @@ -0,0 +1,195 @@ +# $NetBSD: t_wait.sh,v 1.8 2016/03/31 16:22:54 christos Exp $ +# +# Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# the implementation of "sh" to test +: ${TEST_SH:="/bin/sh"} + +atf_test_case basic_wait +basic_wait_head() { + atf_set "descr" "Tests simple uses of wait" +} +basic_wait_body() { + atf_require_prog sleep + + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ + '(echo nothing >/dev/null) & wait' + + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ + '(exit 3) & wait $!; S=$?; test $S -eq 3 || { + echo "status: $S"; exit 1; }' + + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ + 'sleep 3 & sleep 2 & sleep 1 & wait' + + atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ + 'sleep 3 & (exit 2) & sleep 1 & wait' +} + +atf_test_case individual +individual_head() { + atf_set "descr" "Tests that waiting for individual processes works" +} +individual_body() { + atf_require_prog sleep + + cat >individualhelper.sh <<\EOF +sleep 3 & P1=$! +sleep 1 & P2=$! + +wait ${P1} +S=$? +if [ $S -ne 0 ]; then + echo "Waiting for first process failed: $S" + exit 1 +fi + +wait ${P2} +S=$? +if [ $? -ne 0 ]; then + echo "Waiting for second process failed" + exit 1 +fi + +exit 0 +EOF + output=$(${TEST_SH} individualhelper.sh 2>&1) + [ $? -eq 0 ] || atf_fail "${output}" +} + +atf_test_case jobs +jobs_head() { + atf_set "descr" "Tests that waiting for individual jobs works" +} +jobs_body() { + # atf-sh confuses wait for some reason; work it around by creating + # a helper script that executes /bin/sh directly. + + if ! ${TEST_SH} -c 'sleep 1 & wait %1' 2>/dev/null + then + atf_skip "No job control support in this shell" + fi + + cat >individualhelper.sh <<\EOF +sleep 3 & +sleep 1 & + +wait %1 +if [ $? -ne 0 ]; then + echo "Waiting for first job failed" + exit 1 +fi + +wait %2 +if [ $? -ne 0 ]; then + echo "Waiting for second job failed" + exit 1 +fi + +exit 0 +EOF + output=$(${TEST_SH} individualhelper.sh 2>&1) + [ $? -eq 0 ] || atf_fail "${output}" + + cat >individualhelper.sh <<\EOF +{ sleep 3; exit 3; } & +{ sleep 1; exit 7; } & + +wait %1 +S=$? +if [ $S -ne 3 ]; then + echo "Waiting for first job failed - status: $S != 3 (expected)" + exit 1 +fi + +wait %2 +S=$? +if [ $S -ne 7 ]; then + echo "Waiting for second job failed - status: $S != 7 (expected)" + exit 1 +fi + +exit 0 +EOF + + output=$(${TEST_SH} individualhelper.sh 2>&1) + [ $? -eq 0 ] || atf_fail "${output}" +} + +atf_test_case kill +kill_head() { + atf_set "descr" "Tests that killing the shell while in wait calls trap" +} +kill_body() { + atf_require_prog sleep + atf_require_prog kill + + s=killhelper.sh + z=killhelper.$$ + pid= + + # waiting for a specific process that is not a child + # should return exit status of 127 according to the spec + # This test is here before the next, to avoid that one + # entering an infinite loop should the shell have a bug here. + + atf_check -s exit:127 -o empty -e ignore ${TEST_SH} -c 'wait 1' + + cat > "${s}" <<'EOF' + +trap "echo SIGHUP" 1 +(sleep 5; exit 3) & +sl=$! +wait +S=$? +echo $S +LS=9999 +while [ $S -ne 0 ] && [ $S != 127 ]; do + wait $sl; S=$?; echo $S + test $S = $LS && { echo "wait repeats..."; exit 2; } + LS=$S + done +EOF + + ${TEST_SH} $s > $z & + pid=$! + sleep 1 + + kill -HUP "${pid}" + wait + + output="$(cat $z | tr '\n' ' ')" + + if [ "$output" != "SIGHUP 129 3 127 " ]; then + atf_fail "${output} != 'SIGHUP 129 3 127 '" + fi +} + +atf_init_test_cases() { + atf_add_test_case basic_wait + atf_add_test_case individual + atf_add_test_case jobs + atf_add_test_case kill +} diff --git a/contrib/netbsd-tests/bin/sleep/t_sleep.sh b/contrib/netbsd-tests/bin/sleep/t_sleep.sh new file mode 100755 index 0000000..d79ab67 --- /dev/null +++ b/contrib/netbsd-tests/bin/sleep/t_sleep.sh @@ -0,0 +1,72 @@ +# $NetBSD: t_sleep.sh,v 1.1 2012/03/30 09:27:10 jruoho Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case fraction +fraction_head() { + atf_set "descr" "Test that sleep(1) handles " \ + "fractions of a second (PR bin/3914)" +} + +fraction_body() { + + atf_check -s exit:0 -o empty -e empty -x "sleep 0.1" + atf_check -s exit:0 -o empty -e empty -x "sleep 0.2" + atf_check -s exit:0 -o empty -e empty -x "sleep 0.3" +} + +atf_test_case hex +hex_head() { + atf_set "descr" "Test that sleep(1) handles hexadecimal arguments" +} + +hex_body() { + + atf_check -s exit:0 -o empty -e empty -x "sleep 0x01" +} + +atf_test_case nonnumeric +nonnumeric_head() { + atf_set "descr" "Test that sleep(1) errors out with " \ + "non-numeric argument (PR bin/27140)" +} + +nonnumeric_body() { + + atf_check -s not-exit:0 -o empty -e not-empty -x "sleep xyz" + atf_check -s not-exit:0 -o empty -e not-empty -x "sleep x21" + atf_check -s not-exit:0 -o empty -e not-empty -x "sleep /3" +} + +atf_init_test_cases() { + + atf_add_test_case fraction + atf_add_test_case hex + atf_add_test_case nonnumeric +} diff --git a/contrib/netbsd-tests/bin/tar/t_tar.sh b/contrib/netbsd-tests/bin/tar/t_tar.sh new file mode 100755 index 0000000..133d39c --- /dev/null +++ b/contrib/netbsd-tests/bin/tar/t_tar.sh @@ -0,0 +1,51 @@ +# $NetBSD: t_tar.sh,v 1.1 2012/03/17 16:33:11 jruoho Exp $ +# +# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case append +append_head() { + atf_set "descr" "Ensure that appending a file to an archive" \ + "produces the same results as if the file" \ + "had been there during the archive's creation" +} +append_body() { + touch foo bar + + # store both foo and bar into file1.tar + atf_check -s eq:0 -o empty -e empty tar -cf file1.tar foo bar + + # store foo into file2.tar, then append bar to file2.tar + atf_check -s eq:0 -o empty -e empty tar -cf file2.tar foo + atf_check -s eq:0 -o empty -e empty tar -rf file2.tar bar + + # ensure that file1.tar and file2.tar are equal + atf_check -s eq:0 -o empty -e empty cmp file1.tar file2.tar +} + +atf_init_test_cases() +{ + atf_add_test_case append +} diff --git a/contrib/netbsd-tests/crypto/libcrypto/conf/d_conf.out b/contrib/netbsd-tests/crypto/libcrypto/conf/d_conf.out new file mode 100644 index 0000000..6bd76a2 --- /dev/null +++ b/contrib/netbsd-tests/crypto/libcrypto/conf/d_conf.out @@ -0,0 +1,94 @@ +num_items = 47 +num_nodes = 24 +num_alloc_nodes = 32 +num_expands = 16 +num_expand_reallocs = 1 +num_contracts = 0 +num_contract_reallocs = 0 +num_hash_calls = 60 +num_comp_calls = 5 +num_insert = 47 +num_replace = 0 +num_delete = 0 +num_no_delete = 0 +num_retrieve = 5 +num_retrieve_miss = 8 +num_hash_comps = 132 +node 0 -> 4 +node 1 -> 1 +node 2 -> 1 +node 3 -> 4 +node 4 -> 0 +node 5 -> 2 +node 6 -> 1 +node 7 -> 1 +node 8 -> 6 +node 9 -> 2 +node 10 -> 1 +node 11 -> 1 +node 12 -> 3 +node 13 -> 1 +node 14 -> 4 +node 15 -> 3 +node 16 -> 5 +node 17 -> 0 +node 18 -> 2 +node 19 -> 0 +node 20 -> 2 +node 21 -> 2 +node 22 -> 0 +node 23 -> 1 +20 nodes used out of 24 +47 items +load 1.95 actual load 2.35 +init2=10 +cipher1=NULL +s_client:cipher1=DES_CBC_MD5:DES_CBC_SHA:DES_EDE_SHA:RC4_MD5cipher2 = DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5 +---------------------------- DUMP ------------------------ +[req] Attribute_text_7=Email Address +[req] Attribute_text_2=State or Province Name (full name) +[default] tmp_cert_dir=/tmp/eay/.ca_certs +[req] Attribute_text_1=Country Name (2 letter code) +[[genrsa]] +[req] Attribute_default_5=TR +[req] Attribute_text_6=Common Name (eg, YOUR name) +[req] Attribute_default_1=AU +[[req]] +[[special]] +[[gendh]] +[req] Attribute_text_3=Locality Name (eg, city) +[req] Attribute_type_1=countryName +[default] init5==10' again +[req] Attribute_type_3=localityName +[s_client] cipher3=DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5 +[default] in\#it1=10 +[req] Attribute_text_4=Organization Name (eg, company) +[req] Attribute_type_7=emailAddress +[gendh] def_generator=2 +[default] HOME=/tmp/eay +[s_client] cipher4=DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5 +[default] init=5 +[SSLeay] version=0.5.0 +[req] Attribute_type_4=organizationName +[default] tmp2_cert_dir=thisis/tmp/eaystuff +[req] Attribute_type_5=organizationalUnitName +[[SSLEAY]] +[default] init4=10' +[[default]] +[default] LOGNAME=Eric Young (home=/tmp/eay) +[special] RANDFILE=/tmp/eay/.rand +[req] default_keyfile=privkey.pem +[req] Attribute_default_4=Mincom Pty Ltd +[req] Attribute_default_2=Queensland +[gendh] default_bits=512 +[req] default_bits=512 +[default] init2=10 +[SSLEAY] version=0.5.0 +[s_client] cipher1=DES_CBC_MD5:DES_CBC_SHA:DES_EDE_SHA:RC4_MD5cipher2 = DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5 +[req] Attribute_text_5=Organizational Unit Name (eg, section) +[req] Attribute_type_2=stateOrProvinceName +[genrsa] default_bits=512 +[default] init3=10' +[[SSLeay]] +[[s_client]] +[req] Attribute_type_6=commonName diff --git a/contrib/netbsd-tests/crypto/libcrypto/conf/d_conf_ssleay.cnf b/contrib/netbsd-tests/crypto/libcrypto/conf/d_conf_ssleay.cnf new file mode 100644 index 0000000..3fdde34 --- /dev/null +++ b/contrib/netbsd-tests/crypto/libcrypto/conf/d_conf_ssleay.cnf @@ -0,0 +1,78 @@ +# +# This is a test configuration file for use in SSLeay etc... +# + +init = 5 +in\#it1 =10 +init2='10' +init3='10\'' +init4="10'" +init5='='10\'' again' + +SSLeay::version = 0.5.0 + +[genrsa] +default_bits = 512 +SSLEAY::version = 0.5.0 + +[gendh] +default_bits = 512 +def_generator = 2 + +[s_client] +cipher1 = DES_CBC_MD5:DES_CBC_SHA:DES_EDE_SHA:RC4_MD5\ +cipher2 = 'DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5' +cipher3 = "DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5" +cipher4 = DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5 + +[ default ] +#cert_dir = $ENV::HOME/.ca_certs + +HOME = /tmp/eay + +tmp_cert_dir = $HOME/.ca_certs +tmp2_cert_dir = thisis$(HOME)stuff + +LOGNAME = Eric Young (home=$HOME) + +[ special ] + +#H=$HOME +#H=$default::HOME +#H=$ENV::HOME +# +# SSLeay example configuration file. +# This is mostly being used for generation of certificate requests. +# + +RANDFILE = $HOME/.rand + +[ req ] +default_bits = 512 +default_keyfile = privkey.pem + +Attribute_type_1 = countryName +Attribute_text_1 = Country Name (2 letter code) +Attribute_default_1 = AU + +Attribute_type_2 = stateOrProvinceName +Attribute_text_2 = State or Province Name (full name) +Attribute_default_2 = Queensland + +Attribute_type_3 = localityName +Attribute_text_3 = Locality Name (eg, city) + +Attribute_type_4 = organizationName +Attribute_text_4 = Organization Name (eg, company) +Attribute_default_4 = Mincom Pty Ltd + +Attribute_type_5 = organizationalUnitName +Attribute_text_5 = Organizational Unit Name (eg, section) +Attribute_default_5 = TR + +Attribute_type_6 = commonName +Attribute_text_6 = Common Name (eg, YOUR name) + +Attribute_type_7 = emailAddress +Attribute_text_7 = Email Address + diff --git a/contrib/netbsd-tests/crypto/libcrypto/t_certs.sh b/contrib/netbsd-tests/crypto/libcrypto/t_certs.sh new file mode 100755 index 0000000..6965a57 --- /dev/null +++ b/contrib/netbsd-tests/crypto/libcrypto/t_certs.sh @@ -0,0 +1,41 @@ +# $NetBSD: t_certs.sh,v 1.1 2010/07/10 16:43:25 jmmv Exp $ +# +# Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case x509v3 +x509v3_head() +{ + atf_set "descr" "Checks x509v3 certificates" +} +x509v3_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_x509v3test" +} + +atf_init_test_cases() +{ + atf_add_test_case x509v3 +} diff --git a/contrib/netbsd-tests/crypto/libcrypto/t_ciphers.sh b/contrib/netbsd-tests/crypto/libcrypto/t_ciphers.sh new file mode 100755 index 0000000..1270407 --- /dev/null +++ b/contrib/netbsd-tests/crypto/libcrypto/t_ciphers.sh @@ -0,0 +1,122 @@ +# $NetBSD: t_ciphers.sh,v 1.4 2012/07/14 16:04:06 spz Exp $ +# +# Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case bf +bf_head() +{ + atf_set "descr" "Checks blowfish cipher" +} +bf_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_bftest" +} + +atf_test_case cast +cast_head() +{ + atf_set "descr" "Checks CAST cipher" + atf_set "timeout" "300" +} +cast_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_casttest" +} + +atf_test_case des +des_head() +{ + atf_set "descr" "Checks DES cipher (libdes)" +} +des_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_destest" +} + +atf_test_case evp +evp_head() +{ + atf_set "descr" "Checks EVP cipher" +} +evp_body() +{ + atf_check -o ignore -e ignore $(atf_get_srcdir)/h_evp_test $(atf_get_srcdir)/evptests.txt +} + +atf_test_case rc2 +rc2_head() +{ + atf_set "descr" "Checks RC2 cipher" +} +rc2_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_rc2test" +} + +atf_test_case rc4 +rc4_head() +{ + atf_set "descr" "Checks RC4 cipher" +} +rc4_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_rc4test" +} + +atf_test_case idea +idea_head() +{ + atf_set "descr" "Checks IDEA cipher" +} +idea_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_ideatest" +} + +atf_test_case rc5 +rc5_head() +{ + atf_set "descr" "Checks RC5 cipher" +} +rc5_body() +{ + [ -x "$(atf_get_srcdir)/h_rc5test" ] \ + || atf_skip "RC5 support not available; system built" \ + "with MKCRYPTO_RC5=no" + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_rc5test" +} + +atf_init_test_cases() +{ + atf_add_test_case bf + atf_add_test_case cast + atf_add_test_case des + atf_add_test_case evp + atf_add_test_case rc2 + atf_add_test_case rc4 + atf_add_test_case idea + atf_add_test_case rc5 +} diff --git a/contrib/netbsd-tests/crypto/libcrypto/t_hashes.sh b/contrib/netbsd-tests/crypto/libcrypto/t_hashes.sh new file mode 100755 index 0000000..700dbdb --- /dev/null +++ b/contrib/netbsd-tests/crypto/libcrypto/t_hashes.sh @@ -0,0 +1,108 @@ +# $NetBSD: t_hashes.sh,v 1.2 2012/07/14 16:04:06 spz Exp $ +# +# Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case hmac +hmac_head() +{ + atf_set "descr" "Checks HMAC message authentication code" +} +hmac_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_hmactest" +} + +atf_test_case md2 +md2_head() +{ + atf_set "descr" "Checks MD2 digest" +} +md2_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_md2test" +} + +atf_test_case md4 +md4_head() +{ + atf_set "descr" "Checks MD4 digest" +} +md4_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_md4test" +} + +atf_test_case md5 +md5_head() +{ + atf_set "descr" "Checks MD5 digest" +} +md5_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_md5test" +} + +atf_test_case ripemd +ripemd_head() +{ + atf_set "descr" "Checks RMD-160 digest" +} +ripemd_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_ripemdtest" +} + +atf_test_case sha +sha_head() +{ + atf_set "descr" "Checks SHA-1 digest" +} +sha_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_shatest" +} + + +atf_test_case mdc2 +mdc2_head() +{ + atf_set "descr" "Checks MDC2 digest" +} +mdc2_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_mdc2test" +} + +atf_init_test_cases() +{ + atf_add_test_case hmac + atf_add_test_case md2 + atf_add_test_case md4 + atf_add_test_case md5 + atf_add_test_case ripemd + atf_add_test_case sha + atf_add_test_case mdc2 +} diff --git a/contrib/netbsd-tests/crypto/libcrypto/t_libcrypto.sh b/contrib/netbsd-tests/crypto/libcrypto/t_libcrypto.sh new file mode 100755 index 0000000..f460cf5 --- /dev/null +++ b/contrib/netbsd-tests/crypto/libcrypto/t_libcrypto.sh @@ -0,0 +1,107 @@ +# $NetBSD: t_libcrypto.sh,v 1.4 2016/10/13 09:25:37 martin Exp $ +# +# Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case engine +engine_head() +{ + atf_set "descr" "Checks ENGINE framework" +} +engine_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_enginetest" +} + +atf_test_case rand +rand_head() +{ + atf_set "descr" "Checks peudo-random number generator" +} +rand_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_randtest" +} + +atf_test_case bn +bn_head() +{ + atf_set "descr" "Checks BIGNUM library" + atf_set "timeout" "360" +} +bn_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_bntest" + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_divtest" + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_exptest" +} + +atf_test_case conf +conf_head() +{ + atf_set "descr" "Checks configuration modules" +} +conf_body() +{ + cp $(atf_get_srcdir)/d_conf_ssleay.cnf ssleay.cnf + + atf_check -o file:$(atf_get_srcdir)/d_conf.out \ + $(atf_get_srcdir)/h_conftest +} + +atf_test_case lhash +lhash_head() +{ + atf_set "descr" "Checks lhash - dynamic hash tables" +} +lhash_body() +{ + atf_check -o ignore -e ignore -x \ + "echo hoge | $(atf_get_srcdir)/h_lhashtest" +} + +atf_test_case threads +threads_head() +{ + atf_set "descr" "Checks threading" +} +threads_body() +{ + $(atf_get_srcdir)/h_threadstest \ + -cert $(atf_get_srcdir)/d_server.pem \ + -ccert $(atf_get_srcdir)/d_client.pem \ + 2>&1 | tee out + atf_check -s eq:1 -o empty -e empty grep :error: out +} + +atf_init_test_cases() +{ + atf_add_test_case engine + atf_add_test_case rand + atf_add_test_case bn + atf_add_test_case conf + atf_add_test_case lhash + atf_add_test_case threads +} diff --git a/contrib/netbsd-tests/crypto/libcrypto/t_pubkey.sh b/contrib/netbsd-tests/crypto/libcrypto/t_pubkey.sh new file mode 100755 index 0000000..eb8d0f5 --- /dev/null +++ b/contrib/netbsd-tests/crypto/libcrypto/t_pubkey.sh @@ -0,0 +1,110 @@ +# $NetBSD: t_pubkey.sh,v 1.4 2016/10/13 09:25:37 martin Exp $ +# +# Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case dsa +dsa_head() +{ + atf_set "descr" "Checks DSA cipher" +} +dsa_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_dsatest" +} + +atf_test_case dh +dh_head() +{ + atf_set "descr" "Checks Diffie-Hellman key agreement protocol" +} +dh_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_dhtest" +} + +atf_test_case rsa +rsa_head() +{ + atf_set "descr" "Checks RSA" + atf_set "timeout" "420" +} +rsa_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_rsatest" +} + +atf_test_case ec +ec_head() +{ + atf_set "descr" "Checks EC cipher" + atf_set "timeout" "480" +} +ec_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_ectest" +} + +atf_test_case ecdh +ecdh_head() +{ + atf_set "descr" "Checks ECDH key agreement protocol" +} +ecdh_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_ecdhtest" +} + +atf_test_case ecdsa +ecdsa_head() +{ + atf_set "descr" "Checks ECDSA algorithm" + atf_set "timeout" "480" +} +ecdsa_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_ecdsatest" +} + +atf_test_case srp +srp_head() +{ + atf_set "descr" "Checks SRP key agreement protocol" +} +srp_body() +{ + atf_check -o ignore -e ignore "$(atf_get_srcdir)/h_srptest" +} + +atf_init_test_cases() +{ + atf_add_test_case dsa + atf_add_test_case dh + atf_add_test_case rsa + atf_add_test_case ec + atf_add_test_case ecdh + atf_add_test_case ecdsa + atf_add_test_case srp +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_aesctr1.c b/contrib/netbsd-tests/crypto/opencrypto/h_aesctr1.c new file mode 100644 index 0000000..41d866c --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_aesctr1.c @@ -0,0 +1,250 @@ +/* $NetBSD: h_aesctr1.c,v 1.4 2014/01/19 13:40:59 pgoyette Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include + +#include +#include + +#include + +/* + * Test vectors from RFC 3686 + * + * Test vectors 3, 6, and 9 are disabled because we don't support + * 36-byte (ie, unpadded) operations. + */ + +const struct { + size_t len; + size_t key_len; + unsigned char key[36]; /* Includes 32-bit nonce */ + unsigned char iv[8]; + unsigned char plaintx[36]; + unsigned char ciphertx[36]; +} tests[] = { + /* Test Vector #1: Encrypting 16 octets using AES-CTR w/ 128-bit key*/ + { 16, 20, + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E, + 0x00, 0x00, 0x00, 0x30 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, + 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 } + }, + + /* Test Vector #2: Encrypting 32 octets using AES-CTR w/ 128-bit key */ + { 32, 20, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63, + 0x00, 0x6C, 0xB6, 0xDB }, + { 0xC0, 0x54, 0x3B, 0x59, 0xDA, 0x48, 0xD9, 0x0B }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, + 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, + 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, + 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 } + }, + + /* Test Vector #3: Encrypting 36 octets using AES-CTR w/ 128-bit key */ +/* { 36, 20, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC, + 0x00, 0xE0, 0x01, 0x7B }, + { 0x27, 0x77, 0x7F, 0x3F, 0x4A, 0x17, 0x86, 0xF0 }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 }, + { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, + 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, + 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, + 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, + 0x25, 0xB2, 0x07, 0x2F } + }, +*/ + /* Test Vector #4: Encrypting 16 octets using AES-CTR w/ 192-bit key */ + { 16, 28, + { 0x16, 0xAF, 0x5B, 0x14, 0x5F, 0xC9, 0xF5, 0x79, + 0xC1, 0x75, 0xF9, 0x3E, 0x3B, 0xFB, 0x0E, 0xED, + 0x86, 0x3D, 0x06, 0xCC, 0xFD, 0xB7, 0x85, 0x15, + 0x00, 0x00, 0x00, 0x48 }, + { 0x36, 0x73, 0x3C, 0x14, 0x7D, 0x6D, 0x93, 0xCB }, + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + { 0x4B, 0x55, 0x38, 0x4F, 0xE2, 0x59, 0xC9, 0xC8, + 0x4E, 0x79, 0x35, 0xA0, 0x03, 0xCB, 0xE9, 0x28 } + }, + + /* Test Vector #5: Encrypting 32 octets using AES-CTR w/ 192-bit key */ + { 32, 28, + { 0x7C, 0x5C, 0xB2, 0x40, 0x1B, 0x3D, 0xC3, 0x3C, + 0x19, 0xE7, 0x34, 0x08, 0x19, 0xE0, 0xF6, 0x9C, + 0x67, 0x8C, 0x3D, 0xB8, 0xE6, 0xF6, 0xA9, 0x1A, + 0x00, 0x96, 0xB0, 0x3B }, + { 0x02, 0x0C, 0x6E, 0xAD, 0xC2, 0xCB, 0x50, 0x0D }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + { 0x45, 0x32, 0x43, 0xFC, 0x60, 0x9B, 0x23, 0x32, + 0x7E, 0xDF, 0xAA, 0xFA, 0x71, 0x31, 0xCD, 0x9F, + 0x84, 0x90, 0x70, 0x1C, 0x5A, 0xD4, 0xA7, 0x9C, + 0xFC, 0x1F, 0xE0, 0xFF, 0x42, 0xF4, 0xFB, 0x00 } + }, + + /* Test Vector #6: Encrypting 36 octets using AES-CTR w/ 192-bit key */ +/* + { 36, 28, + { 0x02, 0xBF, 0x39, 0x1E, 0xE8, 0xEC, 0xB1, 0x59, + 0xB9, 0x59, 0x61, 0x7B, 0x09, 0x65, 0x27, 0x9B, + 0xF5, 0x9B, 0x60, 0xA7, 0x86, 0xD3, 0xE0, 0xFE, + 0x00, 0x07, 0xBD, 0xFD }, + { 0x5C, 0xBD, 0x60, 0x27, 0x8D, 0xCC, 0x09, 0x12 }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 }, + { 0x96, 0x89, 0x3F, 0xC5, 0x5E, 0x5C, 0x72, 0x2F, + 0x54, 0x0B, 0x7D, 0xD1, 0xDD, 0xF7, 0xE7, 0x58, + 0xD2, 0x88, 0xBC, 0x95, 0xC6, 0x91, 0x65, 0x88, + 0x45, 0x36, 0xC8, 0x11, 0x66, 0x2F, 0x21, 0x88, + 0xAB, 0xEE, 0x09, 0x35 }, + }, +*/ + /* Test Vector #7: Encrypting 16 octets using AES-CTR w/ 256-bit key */ + { 16, 36, + { 0x77, 0x6B, 0xEF, 0xF2, 0x85, 0x1D, 0xB0, 0x6F, + 0x4C, 0x8A, 0x05, 0x42, 0xC8, 0x69, 0x6F, 0x6C, + 0x6A, 0x81, 0xAF, 0x1E, 0xEC, 0x96, 0xB4, 0xD3, + 0x7F, 0xC1, 0xD6, 0x89, 0xE6, 0xC1, 0xC1, 0x04, + 0x00, 0x00, 0x00, 0x60 }, + { 0xDB, 0x56, 0x72, 0xC9, 0x7A, 0xA8, 0xF0, 0xB2 }, + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + { 0x14, 0x5A, 0xD0, 0x1D, 0xBF, 0x82, 0x4E, 0xC7, + 0x56, 0x08, 0x63, 0xDC, 0x71, 0xE3, 0xE0, 0xC0 }, + }, + + /* Test Vector #8: Encrypting 32 octets using AES-CTR w/ 256-bit key */ + { 32, 36, + { 0xF6, 0xD6, 0x6D, 0x6B, 0xD5, 0x2D, 0x59, 0xBB, + 0x07, 0x96, 0x36, 0x58, 0x79, 0xEF, 0xF8, 0x86, + 0xC6, 0x6D, 0xD5, 0x1A, 0x5B, 0x6A, 0x99, 0x74, + 0x4B, 0x50, 0x59, 0x0C, 0x87, 0xA2, 0x38, 0x84, + 0x00, 0xFA, 0xAC, 0x24 }, + { 0xC1, 0x58, 0x5E, 0xF1, 0x5A, 0x43, 0xD8, 0x75 }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + { 0xF0, 0x5E, 0x23, 0x1B, 0x38, 0x94, 0x61, 0x2C, + 0x49, 0xEE, 0x00, 0x0B, 0x80, 0x4E, 0xB2, 0xA9, + 0xB8, 0x30, 0x6B, 0x50, 0x8F, 0x83, 0x9D, 0x6A, + 0x55, 0x30, 0x83, 0x1D, 0x93, 0x44, 0xAF, 0x1C }, + }, + + /* Test Vector #9: Encrypting 36 octets using AES-CTR w/ 256-bit key */ +/* + { 36, 36, + { 0xFF 0x7A 0x61 0x7C 0xE6 0x91 0x48 0xE4, + 0xF1 0x72 0x6E 0x2F 0x43 0x58 0x1D 0xE2, + 0xAA 0x62 0xD9 0xF8 0x05 0x53 0x2E 0xDF, + 0xF1 0xEE 0xD6 0x87 0xFB 0x54 0x15 0x3D, + 0x00 0x1C 0xC5 0xB7 }, + { 0x51 0xA5 0x1D 0x70 0xA1 0xC1 0x11 0x48 }, + { 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07, + 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F, + 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17, + 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F, + 0x20 0x21 0x22 0x23 }, + { 0xEB 0x6C 0x52 0x82 0x1D 0x0B 0xBB 0xF7, + 0xCE 0x75 0x94 0x46 0x2A 0xCA 0x4F 0xAA, + 0xB4 0x07 0xDF 0x86 0x65 0x69 0xFD 0x07, + 0xF4 0x8C 0xC0 0xB5 0x83 0xD6 0x07 0x1F, + 0x1E 0xC0 0xE6 0xB8 }, + }, +*/ +}; + +int +main(void) +{ + int fd, res; + size_t i; + struct session_op cs; + struct crypt_op co; + unsigned char buf[36]; + + for (i = 0; i < __arraycount(tests); i++) { + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open %zu", i); + memset(&cs, 0, sizeof(cs)); + cs.cipher = CRYPTO_AES_CTR; + cs.keylen = tests[i].key_len; + cs.key = __UNCONST(&tests[i].key); + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION %zu", i); + + memset(&co, 0, sizeof(co)); + co.ses = cs.ses; + co.op = COP_ENCRYPT; + co.len = tests[i].len; + co.src = __UNCONST(&tests[i].plaintx); + co.dst = buf; + co.dst_len = sizeof(buf); + co.iv = __UNCONST(&tests[i].iv); + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT %zu", i); + + if (memcmp(co.dst, tests[i].ciphertx, tests[i].len)) { + size_t j; + printf(" Loc Actual Golden\n"); + for (j = 0; j < tests[i].len; j++) + printf("0x%2zu: 0x%2x 0x%2x\n", j, + buf[j], tests[i].ciphertx[j]); + warnx("verification failed %zu", i); + } + close(fd); + } + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_aesctr2.c b/contrib/netbsd-tests/crypto/opencrypto/h_aesctr2.c new file mode 100644 index 0000000..4bbd30e --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_aesctr2.c @@ -0,0 +1,97 @@ +/* $NetBSD: h_aesctr2.c,v 1.2 2014/01/17 14:16:08 pgoyette Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include +#include + +#include + +unsigned char key[20] = {0xae, 0x68, 0x52, 0xf8, 0x12, 0x10, 0x67, 0xcc, + 0x4b, 0xf7, 0xa5, 0x76, 0x55, 0x77, 0xf3, 0x9e, + 0x00, 0x00, 0x00, 0x30}; +unsigned char iv[8] = {0}; +char plaintx[16] = "Single block msg"; +const unsigned char ciphertx[16] = { + 0xe4, 0x09, 0x5d, 0x4f, 0xb7, 0xa7, 0xb3, 0x79, + 0x2d, 0x61, 0x75, 0xa3, 0x26, 0x13, 0x11, 0xb8 +}; + +int +main(void) +{ + int fd, res; + struct session_op cs; + struct crypt_op co; + unsigned char ibuf[24]; + unsigned char obuf[24]; + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + memset(&cs, 0, sizeof(cs)); + cs.cipher = CRYPTO_AES_CTR; + cs.keylen = 20; + cs.key = key; + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION"); + + memcpy(ibuf, iv, 8); + memcpy(ibuf + 8, plaintx, 16); + memset(&co, 0, sizeof(co)); + co.ses = cs.ses; + co.op = COP_ENCRYPT; + co.len = sizeof(ibuf); + co.src = ibuf; + co.dst = obuf; + co.dst_len = sizeof(obuf); + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT"); + memset(ibuf, 0, sizeof(ibuf)); + memset(&co, 0, sizeof(co)); + co.ses = cs.ses; + co.op = COP_DECRYPT; + co.len = sizeof(obuf); + co.src = obuf; + co.dst = ibuf; + co.dst_len = sizeof(ibuf); + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT"); + + if (memcmp((char *)co.dst + 8, plaintx, sizeof(plaintx))) + warnx("verification failed"); + + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_arc4.c b/contrib/netbsd-tests/crypto/opencrypto/h_arc4.c new file mode 100644 index 0000000..4bf8428 --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_arc4.c @@ -0,0 +1,80 @@ +/* $NetBSD: h_arc4.c,v 1.2 2014/01/17 14:16:08 pgoyette Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include +#include + +#include + +unsigned char key[] = "abcdefgh"; +char plaintx[16] = "1234567890123456"; +const unsigned char ciphertx[16] = { + 0x21, 0xc6, 0x0d, 0xa5, 0x34, 0x24, 0x8b, 0xce, + 0x95, 0x86, 0x64, 0xb3, 0x66, 0x77, 0x9b, 0x4c +}; + +int +main(void) +{ + int fd, res; + struct session_op cs; + struct crypt_op co; + unsigned char buf[16]; + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + memset(&cs, 0, sizeof(cs)); + cs.cipher = CRYPTO_ARC4; + cs.keylen = 8; + cs.key = key; + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION"); + + memset(&co, 0, sizeof(co)); + co.ses = cs.ses; + co.op = COP_ENCRYPT; + co.len = sizeof(plaintx); + co.src = plaintx; + co.dst = buf; + co.dst_len = sizeof(buf); + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT"); + + if (memcmp(co.dst, ciphertx, sizeof(ciphertx))) + errx(1, "verification failed"); + + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_camellia.c b/contrib/netbsd-tests/crypto/opencrypto/h_camellia.c new file mode 100644 index 0000000..bb489e7 --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_camellia.c @@ -0,0 +1,87 @@ +/* $NetBSD: h_camellia.c,v 1.3 2014/01/17 19:39:51 pgoyette Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include +#include + +#include + +/* Test vector from RFC3713 */ +unsigned char key[32] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; +unsigned char iv[16] = {0}; +char plaintx[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}; +const unsigned char ciphertx[16] = { + 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, + 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 +}; + +int +main(void) +{ + int fd, res; + struct session_op cs; + struct crypt_op co; + unsigned char buf[16]; + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + memset(&cs, 0, sizeof(cs)); + cs.cipher = CRYPTO_CAMELLIA_CBC; + cs.keylen = 32; + cs.key = key; + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION"); + + memset(&co, 0, sizeof(co)); + co.ses = cs.ses; + co.op = COP_ENCRYPT; + co.len = sizeof(plaintx); + co.src = plaintx; + co.dst = buf; + co.dst_len = sizeof(buf); + co.iv = iv; + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT"); + + if (memcmp(co.dst, ciphertx, sizeof(ciphertx))) + warnx("verification failed"); + + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_cbcdes.c b/contrib/netbsd-tests/crypto/opencrypto/h_cbcdes.c new file mode 100644 index 0000000..4861d78 --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_cbcdes.c @@ -0,0 +1,82 @@ +/* $NetBSD: h_cbcdes.c,v 1.2 2014/01/17 14:16:08 pgoyette Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include +#include + +#include + +unsigned char key[] = "abcdefgh"; +unsigned char iv[8] = {0}; +char plaintx[16] = "1234567890123456"; +const unsigned char ciphertx[16] = { + 0x21, 0xc6, 0x0d, 0xa5, 0x34, 0x24, 0x8b, 0xce, + 0x95, 0x86, 0x64, 0xb3, 0x66, 0x77, 0x9b, 0x4c +}; + +int +main(void) +{ + int fd, res; + struct session_op cs; + struct crypt_op co; + unsigned char buf[16]; + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + memset(&cs, 0, sizeof(cs)); + cs.cipher = CRYPTO_DES_CBC; + cs.keylen = 8; + cs.key = key; + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION"); + + memset(&co, 0, sizeof(co)); + co.ses = cs.ses; + co.op = COP_ENCRYPT; + co.len = sizeof(plaintx); + co.src = plaintx; + co.dst = buf; + co.dst_len = sizeof(buf); + co.iv = iv; + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT"); + + if (memcmp(co.dst, ciphertx, sizeof(ciphertx))) + errx(1, "verification failed"); + + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_comp.c b/contrib/netbsd-tests/crypto/opencrypto/h_comp.c new file mode 100644 index 0000000..dd5f647 --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_comp.c @@ -0,0 +1,90 @@ +/* $NetBSD: h_comp.c,v 1.1 2014/01/14 17:51:39 pgoyette Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include + +#include +#include + +#include + +char text[100000] = {0}; + +int +main(void) +{ + int fd, res; + struct session_op cs; + struct crypt_op co1, co2; + unsigned char buf1[10000], buf2[100000]; + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + memset(&cs, 0, sizeof(cs)); + cs.comp_alg = CRYPTO_GZIP_COMP; + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION"); + + memset(&co1, 0, sizeof(co1)); + co1.ses = cs.ses; + co1.op = COP_COMP; + co1.len = sizeof(text); + co1.src = text; + co1.dst = buf1; + co1.dst_len = sizeof(buf1); + res = ioctl(fd, CIOCCRYPT, &co1); + if (res < 0) + err(1, "CIOCCRYPT1"); + fprintf(stderr, "len %d/%d\n", co1.len, co1.dst_len); +#if 0 + buf1[co1.dst_len - 8]++; /* modify CRC */ +#endif + write(1, buf1, co1.dst_len); + memset(&co2, 0, sizeof(co2)); + co2.ses = cs.ses; + co2.op = COP_DECOMP; + co2.len = co1.dst_len; + co2.src = buf1; + co2.dst = buf2; + co2.dst_len = sizeof(buf2); + buf2[10] = 0x33; + res = ioctl(fd, CIOCCRYPT, &co2); + fprintf(stderr, "canary: %x\n", buf2[10]); + if (res < 0) + err(1, "CIOCCRYPT2"); + fprintf(stderr, "len %d/%d\n", co2.len, co2.dst_len); + if (memcmp(text, buf2, co2.dst_len)) + errx(1, "memcmp"); + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_comp_zlib.c b/contrib/netbsd-tests/crypto/opencrypto/h_comp_zlib.c new file mode 100644 index 0000000..7a57ceb --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_comp_zlib.c @@ -0,0 +1,92 @@ +/* $NetBSD: h_comp_zlib.c,v 1.1 2014/01/14 17:51:39 pgoyette Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include +#include + +#include + +char text[10000] = {0}; + +int +main(void) +{ + int fd, res; + struct session_op cs; + struct crypt_op co1; + unsigned char buf1[10000], buf2[10000]; + z_stream z; + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + memset(&cs, 0, sizeof(cs)); + cs.comp_alg = CRYPTO_DEFLATE_COMP; + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION"); + + memset(&co1, 0, sizeof(co1)); + co1.ses = cs.ses; + co1.op = COP_COMP; + co1.len = sizeof(text); + co1.src = text; + co1.dst = buf1; + co1.dst_len = sizeof(buf1); + co1.flags = COP_F_BATCH; + res = ioctl(fd, CIOCCRYPT, &co1); + if (res < 0) + err(1, "CIOCCRYPT"); + + memset(&z, 0, sizeof(z)); + z.next_in = buf1; + z.avail_in = co1.dst_len; + z.zalloc = Z_NULL; + z.zfree = Z_NULL; + z.opaque = 0; + z.next_out = buf2; + z.avail_out = sizeof(buf2); + res = inflateInit2(&z, -15); + if (res != Z_OK) + errx(1, "inflateInit: %d", res); + do { + res = inflate(&z, Z_SYNC_FLUSH); + } while (res == Z_OK); + if (res != Z_STREAM_END) + errx(1, "inflate: %d", res); + if (z.total_out != sizeof(text)) + errx(1, "decomp len %lu", z.total_out); + if (memcmp(buf2, text, sizeof(text))) + errx(1, "decomp data mismatch"); + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_comp_zlib_rnd.c b/contrib/netbsd-tests/crypto/opencrypto/h_comp_zlib_rnd.c new file mode 100644 index 0000000..86ed55a --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_comp_zlib_rnd.c @@ -0,0 +1,96 @@ +/* $NetBSD: h_comp_zlib_rnd.c,v 1.1 2014/01/14 17:51:39 pgoyette Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include + +#include +#include + +#include + +char text[1000]; + +int +main(void) +{ + unsigned int i; + int fd, res; + struct session_op cs; + struct crypt_op co1; + unsigned char buf1[10000], buf2[10000]; + z_stream z; + + for (i = 0; i < sizeof(text)/sizeof(long); i++) + *(long *)(text + i * sizeof(long)) = random(); + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + memset(&cs, 0, sizeof(cs)); + cs.comp_alg = CRYPTO_DEFLATE_COMP; + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION"); + + memset(&co1, 0, sizeof(co1)); + co1.ses = cs.ses; + co1.op = COP_COMP; + co1.len = sizeof(text); + co1.src = text; + co1.dst = buf1; + co1.dst_len = sizeof(buf1); + res = ioctl(fd, CIOCCRYPT, &co1); + if (res < 0) + err(1, "CIOCCRYPT"); + + memset(&z, 0, sizeof(z)); + z.next_in = buf1; + z.avail_in = co1.dst_len; + z.zalloc = Z_NULL; + z.zfree = Z_NULL; + z.opaque = 0; + z.next_out = buf2; + z.avail_out = sizeof(buf2); + res = inflateInit2(&z, -15); + if (res != Z_OK) + errx(1, "inflateInit: %d", res); + do { + res = inflate(&z, Z_SYNC_FLUSH); + } while (res == Z_OK); + if (res != Z_STREAM_END) + errx(1, "inflate: %d", res); + if (z.total_out != sizeof(text)) + errx(1, "decomp len %lu", z.total_out); + if (memcmp(buf2, text, sizeof(text))) + errx(1, "decomp data mismatch"); + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_gcm.c b/contrib/netbsd-tests/crypto/opencrypto/h_gcm.c new file mode 100644 index 0000000..33f41f0 --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_gcm.c @@ -0,0 +1,126 @@ +/* $NetBSD: h_gcm.c,v 1.2 2014/01/17 14:16:08 pgoyette Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include +#include + +#include + +unsigned char key[20] = { 0 }; +char plaintx[16] = { 0 }; +unsigned char iv[16] = { 0 }; +const unsigned char ciphertx[16] = { + 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 +}; +const unsigned char hash[16] = { + 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf +}; + +int +main(void) +{ + int fd, res; + struct session_op cs; + struct crypt_op co; + unsigned char databuf[16]; + unsigned char macbuf[16]; + unsigned char databuf2[16]; + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + memset(&cs, 0, sizeof(cs)); + cs.mac = CRYPTO_AES_128_GMAC; + cs.mackeylen = sizeof(key); + cs.mackey = key; + cs.cipher = CRYPTO_AES_GCM_16; + cs.key = key; + cs.keylen = sizeof(key); + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION"); + + memset(&co, 0, sizeof(co)); + memset(databuf, 0, sizeof(databuf)); + memset(macbuf, 0, sizeof(macbuf)); + co.ses = cs.ses; + co.op = COP_ENCRYPT; + co.len = sizeof(plaintx); + co.src = plaintx; + co.dst = databuf; + co.mac = macbuf; + co.iv = iv; + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT"); +#if 1 + if (memcmp(co.dst, ciphertx, sizeof(ciphertx))) + errx(1, "verification failed"); + if (memcmp(macbuf, hash, sizeof(hash))) + errx(1, "hash failed"); +#else + { + int i; + for (i = 0; i < sizeof(databuf); i++) + printf("%02x ", databuf[i]); + printf("\n"); + } + { + int i; + for (i = 0; i < sizeof(macbuf); i++) + printf("%02x ", macbuf[i]); + printf("\n"); + } +#endif + memset(databuf2, 0, sizeof(databuf2)); + memset(macbuf, 0, sizeof(macbuf)); + co.ses = cs.ses; + co.op = COP_DECRYPT; + co.len = sizeof(databuf); + co.src = databuf; + co.dst = databuf2; + co.mac = macbuf; + co.iv = iv; + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT"); + + if (memcmp(co.dst, plaintx, sizeof(plaintx))) + errx(1, "verification failed"); + if (memcmp(macbuf, hash, sizeof(hash))) + errx(1, "hash failed"); + + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_md5.c b/contrib/netbsd-tests/crypto/opencrypto/h_md5.c new file mode 100644 index 0000000..98379c7 --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_md5.c @@ -0,0 +1,109 @@ +/* $NetBSD: h_md5.c,v 1.5 2014/01/18 20:10:34 pgoyette Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include +#include + +#include + +/* Test vectors from RFC1321 */ + +const struct { + size_t len; + unsigned char plaintx[80]; + unsigned char digest[16]; +} tests[] = { + { 0, "", + { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, + { 1, "a", + { 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, + 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, + { 3, "abc", + { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, + 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, + { 14, "message digest", + { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, + 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, + { 26, "abcdefghijklmnopqrstuvwxyz", + { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, + 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, + { 62, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, + 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, + { 80, "123456789012345678901234567890123456789012345678901234567890" + "12345678901234567890", + { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, + 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }, +}; + +int +main(void) +{ + int fd, res; + size_t i; + struct session_op cs; + struct crypt_op co; + unsigned char buf[16]; + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + memset(&cs, 0, sizeof(cs)); + cs.mac = CRYPTO_MD5; + + for (i = 0; i < __arraycount(tests); i++) { + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION test %zu", i); + + memset(&co, 0, sizeof(co)); + memset(&buf, 0, sizeof(buf)); + co.ses = cs.ses; + co.op = COP_ENCRYPT; + co.len = tests[i].len; + co.src = __UNCONST(&tests[i].plaintx); + co.mac = buf; + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT test %zu", i); + + if (memcmp(co.mac, tests[i].digest, sizeof(tests[i].digest))) + errx(1, "verification failed test %zu", i); + + res = ioctl(fd, CIOCFSESSION, &cs.ses); + if (res < 0) + err(1, "CIOCFSESSION test %zu", i); + } + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_md5hmac.c b/contrib/netbsd-tests/crypto/opencrypto/h_md5hmac.c new file mode 100644 index 0000000..6753094 --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_md5hmac.c @@ -0,0 +1,181 @@ +/* $NetBSD: h_md5hmac.c,v 1.4 2014/01/18 02:31:14 joerg Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include +#include + +#include + +#define MD5_HMAC_KEYLEN 16 /* Fixed key length supported */ + +/* Test data from RFC2202 */ +const struct { + int num; + size_t key_len; + size_t len; + unsigned char key[80]; + unsigned char data[80]; + unsigned char mac[16]; +} tests[] = { + /* Test #1 */ + { 1, 16, 8, + { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }, + "Hi There", + { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, + 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d } + }, + /* Test #2 */ + { 2, 4, 28, + "Jefe", + "what do ya want for nothing?", + { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, + 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 } + }, + /* Test #3 */ + { 3, 16, 50, + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, + { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd }, + { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, + 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 } + }, + /* Test #4 */ + { 4, 25, 50, + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19 }, + { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd }, + { 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, + 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 } + }, + /* Test #5 */ + { 5, 16, 20, + { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, + "Test With Truncation", + { 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, + 0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c } + }, + /* Test #6 */ + { 6, 80, 54, + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, + "Test Using Larger Than Block-Size Key - Hash Key First", + { 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, + 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd } + }, + /* Test #7 */ + { 7, 80, 73, + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, + "Test Using Larger Than Block-Size Key and Larger " + "Than One Block-Size Data", + { 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, + 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e } + }, +}; + +int +main(void) +{ + size_t i; + int fd, res; + struct session_op cs; + struct crypt_op co; + unsigned char buf[16]; + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + for (i = 0; i < __arraycount(tests); i++) { + if (tests[i].key_len != MD5_HMAC_KEYLEN) + continue; + + memset(&cs, 0, sizeof(cs)); + cs.mac = CRYPTO_MD5_HMAC; + cs.mackeylen = tests[i].key_len; + cs.mackey = __UNCONST(&tests[i].key); + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION test %d", tests[i].num); + + memset(&co, 0, sizeof(co)); + memset(buf, 0, sizeof(buf)); + co.ses = cs.ses; + co.op = COP_ENCRYPT; + co.len = tests[i].len; + co.src = __UNCONST(&tests[i].data); + co.mac = buf; + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT test %d", tests[i].num); + + if (memcmp(co.mac, tests[i].mac, sizeof(tests[i].mac))) + errx(1, "verification failed test %d", tests[i].num); + + res = ioctl(fd, CIOCFSESSION, &cs.ses); + if (res < 0) + err(1, "CIOCFSESSION test %d", tests[i].num); + } + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_null.c b/contrib/netbsd-tests/crypto/opencrypto/h_null.c new file mode 100644 index 0000000..85e4805 --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_null.c @@ -0,0 +1,76 @@ +/* $NetBSD: h_null.c,v 1.3 2014/01/17 19:35:33 pgoyette Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include +#include + +#include + +unsigned char key[] = "abcdefgh"; +char plaintx[16] = "1234567890123456"; + +int +main(void) +{ + int fd, res; + struct session_op cs; + struct crypt_op co; + unsigned char buf[16]; + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + memset(&cs, 0, sizeof(cs)); + cs.cipher = CRYPTO_NULL_CBC; + cs.keylen = 8; + cs.key = key; + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION"); + + memset(&co, 0, sizeof(co)); + co.ses = cs.ses; + co.op = COP_ENCRYPT; + co.len = sizeof(plaintx); + co.src = plaintx; + co.dst = buf; + co.dst_len = sizeof(buf); + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT"); + + if (memcmp(co.dst, plaintx, sizeof(plaintx))) + errx(1, "verification failed"); + + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_sha1hmac.c b/contrib/netbsd-tests/crypto/opencrypto/h_sha1hmac.c new file mode 100644 index 0000000..c153f76 --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_sha1hmac.c @@ -0,0 +1,191 @@ +/* $NetBSD: h_sha1hmac.c,v 1.2 2014/01/18 02:31:14 joerg Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include +#include + +#include + +#define SHA1_HMAC_KEYLEN 20 /* Only key-length we support */ + +/* Test data from RFC2202 */ +const struct { + int num; + size_t key_len; + size_t len; + unsigned char key[80]; + unsigned char data[80]; + unsigned char mac[20]; +} tests[] = { + /* Test #1 */ + { 1, 20, 8, + { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b }, + "Hi There", + { 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, + 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, + 0xf1, 0x46, 0xbe, 0x00 } + }, + /* Test #2 */ + { 2, 4, 28, + "Jefe", + "what do ya want for nothing?", + { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, + 0xd2, 0x74, 0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, + 0x25, 0x9a, 0x7c, 0x79 } + }, + /* Test #3 */ + { 3, 20, 50, + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa }, + { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd }, + { 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, + 0x91, 0xa3, 0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f, + 0x63, 0xf1, 0x75, 0xd3 } + }, + /* Test #4 */ + { 4, 25, 50, + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19 }, + { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd }, + { 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, + 0xbc, 0x84, 0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c, + 0x2d, 0x72, 0x35, 0xda } + }, + /* Test #5 */ + { 5, 20, 20, + { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c }, + "Test With Truncation", + { 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, + 0xe7, 0xf2, 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, + 0x4a, 0x9a, 0x5a, 0x04 } + }, + /* Test #6 */ + { 6, 80, 54, + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, + "Test Using Larger Than Block-Size Key - Hash Key First", + { 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, + 0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, + 0xed, 0x40, 0x21, 0x12 } + }, + /* Test #7 */ + { 7, 80, 73, + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, + "Test Using Larger Than Block-Size Key and Larger Than " + "One Block-Size Data", + { 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, + 0x6d, 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, + 0xbb, 0xff, 0x1a, 0x91 } + }, +}; + +int +main(void) +{ + size_t i; + int fd, res; + struct session_op cs; + struct crypt_op co; + unsigned char buf[20]; + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + for (i = 0; i < __arraycount(tests); i++) { + if (tests[i].key_len != SHA1_HMAC_KEYLEN) + continue; + + memset(&cs, 0, sizeof(cs)); + cs.mac = CRYPTO_SHA1_HMAC; + cs.mackeylen = tests[i].key_len; + cs.mackey = __UNCONST(&tests[i].key); + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION test %d", tests[i].num); + + memset(&co, 0, sizeof(co)); + memset(buf, 0, sizeof(buf)); + co.ses = cs.ses; + co.op = COP_ENCRYPT; + co.len = tests[i].len; + co.src = __UNCONST(&tests[i].data); + co.mac = buf; + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT test %d", tests[i].num); + + if (memcmp(co.mac, &tests[i].mac, sizeof(tests[i].mac))) + errx(1, "verification failed test %d", tests[i].num); + + res = ioctl(fd, CIOCFSESSION, &cs.ses); + if (res < 0) + err(1, "CIOCFSESSION test %d", tests[i].num); + } + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/h_xcbcmac.c b/contrib/netbsd-tests/crypto/opencrypto/h_xcbcmac.c new file mode 100644 index 0000000..3f89c6e --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/h_xcbcmac.c @@ -0,0 +1,109 @@ +/* $NetBSD: h_xcbcmac.c,v 1.4 2014/01/16 23:56:04 joerg Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include +#include + +#include + + +/* test vectors from RFC3566 */ +unsigned char key[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f +}; +char plaintx[1000] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21 +}; +const struct { + size_t len; + unsigned char mac[12]; +} tests[] = { + { 0, { 0x75, 0xf0, 0x25, 0x1d, 0x52, 0x8a, + 0xc0, 0x1c, 0x45, 0x73, 0xdf, 0xd5 } }, + { 3, { 0x5b, 0x37, 0x65, 0x80, 0xae, 0x2f, + 0x19, 0xaf, 0xe7, 0x21, 0x9c, 0xee } }, + { 16, { 0xd2, 0xa2, 0x46, 0xfa, 0x34, 0x9b, + 0x68, 0xa7, 0x99, 0x98, 0xa4, 0x39 } }, + { 20, { 0x47, 0xf5, 0x1b, 0x45, 0x64, 0x96, + 0x62, 0x15, 0xb8, 0x98, 0x5c, 0x63 } }, + { 32, { 0xf5, 0x4f, 0x0e, 0xc8, 0xd2, 0xb9, + 0xf3, 0xd3, 0x68, 0x07, 0x73, 0x4b } }, + { 34, { 0xbe, 0xcb, 0xb3, 0xbc, 0xcd, 0xb5, + 0x18, 0xa3, 0x06, 0x77, 0xd5, 0x48 } }, + { 1000, { 0xf0, 0xda, 0xfe, 0xe8, 0x95, 0xdb, + 0x30, 0x25, 0x37, 0x61, 0x10, 0x3b } }, +}; + +int +main(void) +{ + int fd, res; + size_t i; + struct session_op cs; + struct crypt_op co; + unsigned char buf[16]; + + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) + err(1, "open"); + memset(&cs, 0, sizeof(cs)); + cs.mac = CRYPTO_AES_XCBC_MAC_96; + cs.mackeylen = sizeof(key); + cs.mackey = key; + res = ioctl(fd, CIOCGSESSION, &cs); + if (res < 0) + err(1, "CIOCGSESSION"); + + for (i = 0; i < __arraycount(tests); i++) { + memset(&co, 0, sizeof(co)); + memset(buf, 0, sizeof(buf)); + if (tests[i].len == sizeof(plaintx)) + memset(&plaintx, 0, sizeof(plaintx)); + co.ses = cs.ses; + co.op = COP_ENCRYPT; + co.len = tests[i].len; + co.src = plaintx; + co.mac = buf; + res = ioctl(fd, CIOCCRYPT, &co); + if (res < 0) + err(1, "CIOCCRYPT test %zu", i); + if (memcmp(buf, &tests[i].mac, sizeof(tests[i].mac))) + errx(1, "verification failed test %zu", i); + } + return 0; +} diff --git a/contrib/netbsd-tests/crypto/opencrypto/t_opencrypto.sh b/contrib/netbsd-tests/crypto/opencrypto/t_opencrypto.sh new file mode 100755 index 0000000..e8e3f28 --- /dev/null +++ b/contrib/netbsd-tests/crypto/opencrypto/t_opencrypto.sh @@ -0,0 +1,276 @@ +# $NetBSD: t_opencrypto.sh,v 1.6 2015/12/26 07:10:03 pgoyette Exp $ +# +# Copyright (c) 2014 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# Start a rumpserver, load required modules, and set requires sysctl vars + +start_rump() { + rump_libs="-l rumpvfs -l rumpdev -l rumpdev_opencrypto" + rump_libs="${rump_libs} -l rumpkern_z -l rumpkern_crypto" + + rump_server ${rump_libs} ${RUMP_SERVER} || \ + return 1 + + rump.sysctl -w kern.cryptodevallowsoft=-1 && \ + return 0 + + rump.halt + + return 1 +} + +common_head() { + atf_set descr "$1" + atf_set timeout 10 + atf_set require.progs rump_server rump.sysctl rump.halt +} + +common_body() { + local status + + start_rump || atf_skip "Cannot set-up rump environment" + LD_PRELOAD="/usr/lib/librumphijack.so" ; export LD_PRELOAD + RUMPHIJACK="blanket=/dev/crypto" ; export RUMPHIJACK + $(atf_get_srcdir)/$1 + status=$? + unset RUMPHIJACK + unset LD_PRELOAD + if [ $status -ne 0 ] ; then + atf_fail "$1 returned non-zero status, check output/error" + fi +} + +common_cleanup() { + unset RUMPHIJACK + unset LD_PRELOAD + rump.halt +} + +atf_test_case arc4 cleanup +arc4_head() { + common_head "Test ARC4 crypto" +} + +arc4_body() { + atf_skip "ARC4 not implemented by swcrypto" + common_body h_arc4 +} + +arc4_cleanup() { + # No cleanup required since test is skipped. Trying to run rump.halt + # at this point fails, causing the ATF environment to erroneously + # report a failed test! + # + # common_cleanup +} + +atf_test_case camellia cleanup +camellia_head() { + common_head "Test CAMELLIA_CBC crypto" +} + +camellia_body() { + common_body h_camellia +} + +camellia_cleanup() { + common_cleanup +} + +atf_test_case cbcdes cleanup +cbcdes_head() { + common_head "Test DES_CBC crypto" +} + +cbcdes_body() { + common_body h_cbcdes +} + +cbcdes_cleanup() { + common_cleanup +} + +atf_test_case comp cleanup +comp_head() { + common_head "Test GZIP_COMP Compression" +} + +comp_body() { + common_body h_comp +} + +comp_cleanup() { + common_cleanup +} + +atf_test_case comp_deflate cleanup +comp_deflate_head() { + common_head "Test DEFLATE_COMP Compression" +} + +comp_deflate_body() { + common_body h_comp_zlib +} + +comp_deflate_cleanup() { + common_cleanup +} + +atf_test_case comp_zlib_rnd cleanup +comp_zlib_rnd_head() { + common_head "Test DEFLATE_COMP Compression with random data" +} + +comp_zlib_rnd_body() { + common_body h_comp_zlib_rnd +} + +comp_zlib_rnd_cleanup() { + common_cleanup +} + +atf_test_case aesctr1 cleanup +aesctr1_head() { + common_head "Test AES_CTR crypto" +} + +aesctr1_body() { + common_body h_aesctr1 +} + +aesctr1_cleanup() { + common_cleanup +} + +atf_test_case aesctr2 cleanup +aesctr2_head() { + common_head "Test AES_CTR crypto" +} + +aesctr2_body() { + common_body h_aesctr2 +} + +aesctr2_cleanup() { + common_cleanup +} + +atf_test_case gcm cleanup +gcm_head() { + common_head "Test AES_GCM_16 crypto" +} + +gcm_body() { + common_body h_gcm +} + +gcm_cleanup() { + common_cleanup +} + +atf_test_case md5 cleanup +md5_head() { + common_head "Test MD5 crypto" +} + +md5_body() { + common_body h_md5 +} + +md5_cleanup() { + common_cleanup +} + +atf_test_case md5_hmac cleanup +md5_hmac_head() { + common_head "Test MD5_HMAC crypto" +} + +md5_hmac_body() { + common_body h_md5hmac +} + +md5_hmac_cleanup() { + common_cleanup +} + +atf_test_case null cleanup +null_head() { + common_head "Test NULL_CBC crypto" +} + +null_body() { + common_body h_null +} + +null_cleanup() { + common_cleanup +} + +atf_test_case sha1_hmac cleanup +sha1_hmac_head() { + common_head "Test SHA1_HMAC crypto" +} + +sha1_hmac_body() { + common_body h_sha1hmac +} + +sha1_hmac_cleanup() { + common_cleanup +} + +atf_test_case xcbcmac cleanup +xcbcmac_head() { + common_head "Test XCBC_MAC_96 crypto" +} + +xcbcmac_body() { + common_body h_xcbcmac +} + +xcbcmac_cleanup() { + common_cleanup +} + +atf_init_test_cases() { + RUMP_SERVER="unix://t_opencrypto_socket" ; export RUMP_SERVER + + atf_add_test_case arc4 + atf_add_test_case camellia + atf_add_test_case cbcdes + atf_add_test_case comp + atf_add_test_case comp_deflate + atf_add_test_case comp_zlib_rnd + atf_add_test_case aesctr1 + atf_add_test_case aesctr2 + atf_add_test_case gcm + atf_add_test_case md5 + atf_add_test_case md5_hmac + atf_add_test_case null + atf_add_test_case sha1_hmac + atf_add_test_case xcbcmac +} diff --git a/contrib/netbsd-tests/dev/audio/h_pad.c b/contrib/netbsd-tests/dev/audio/h_pad.c new file mode 100644 index 0000000..b760d04 --- /dev/null +++ b/contrib/netbsd-tests/dev/audio/h_pad.c @@ -0,0 +1,76 @@ +/* $NetBSD: h_pad.c,v 1.2 2016/10/15 07:08:06 nat Exp $ */ + +/* + * Copyright (c) 2010 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "h_pad_musa.c" + +/* + * Stuff some audio into /dev/audio, read it from /dev/pad. Use in + * conjunction with t_pad, which tests that we got sensible output + * by comparing against a previous audibly good result. + */ + +#define BUFSIZE 1024 + +int +main(int argc, char *argv[]) +{ + char buf[BUFSIZE]; + char zeros[BUFSIZE]; + int padfd, audiofd; + ssize_t n; + + rump_init(); + padfd = rump_sys_open("/dev/pad0", O_RDONLY); + if (padfd == -1) + err(1, "open pad"); + + audiofd = rump_sys_open("/dev/audio0", O_RDWR); + if (audiofd == -1) + err(1, "open audio"); + + if ((n = rump_sys_write(audiofd, musa, sizeof(musa))) != sizeof(musa)) + err(1, "write"); + + memset(zeros, 0, sizeof(zeros)); + while ((n = rump_sys_read(padfd, buf, sizeof(buf))) > 0) { + if (memcmp(buf, zeros, sizeof(buf)) == 0) + break; + write(STDOUT_FILENO, buf, n); + } +} diff --git a/contrib/netbsd-tests/dev/audio/h_pad_musa.c b/contrib/netbsd-tests/dev/audio/h_pad_musa.c new file mode 100644 index 0000000..322305e --- /dev/null +++ b/contrib/netbsd-tests/dev/audio/h_pad_musa.c @@ -0,0 +1,344 @@ +unsigned char musa[] = { +0x46, 0xdb, 0x76, 0x67, 0x61, 0xff, 0xfc, 0x67, 0xff, 0xe9, 0xdb, 0x79, +0x5d, 0x53, 0x5b, 0x79, 0xef, 0x65, 0x67, 0x5b, 0x67, 0x67, 0x72, 0x66, +0x4f, 0x5b, 0xe7, 0xf5, 0x5e, 0x53, 0x61, 0xe7, 0x5c, 0x53, 0x67, 0x67, +0x67, 0x5b, 0x54, 0x60, 0x4e, 0xec, 0xef, 0x5b, 0x5b, 0x6f, 0x69, 0xff, +0x71, 0x53, 0x77, 0x67, 0x67, 0x5b, 0x5b, 0x5b, 0x75, 0x6c, 0x67, 0x6d, +0x67, 0x7e, 0xff, 0x63, 0x66, 0x61, 0x67, 0x5b, 0x5b, 0x67, 0x67, 0x5f, +0x5b, 0x64, 0x5b, 0x5b, 0x55, 0x53, 0x5c, 0x5d, 0x67, 0x53, 0x63, 0x5e, +0xe7, 0xf5, 0x51, 0x5b, 0x5e, 0x5e, 0x67, 0x5b, 0x67, 0xff, 0x67, 0x67, +0xe9, 0x6e, 0x67, 0x5c, 0x60, 0x67, 0x7a, 0xff, 0xe7, 0xff, 0x58, 0x5b, +0x64, 0x6e, 0x67, 0x55, 0x5f, 0xff, 0xff, 0xff, 0xff, 0x56, 0x5b, 0x53, +0x5b, 0x67, 0x54, 0x58, 0x67, 0x67, 0x6e, 0x67, 0x5c, 0x58, 0x67, 0x67, +0x5b, 0x65, 0x64, 0x70, 0x5b, 0x5b, 0x67, 0xfc, 0xf7, 0xf2, 0xff, 0xec, +0x73, 0x67, 0x67, 0xff, 0x67, 0x74, 0xff, 0x67, 0x5e, 0x5e, 0x67, 0x72, +0x77, 0x7c, 0x67, 0x5d, 0x5b, 0x67, 0x5b, 0x55, 0x67, 0x5c, 0x67, 0x60, +0x5b, 0x5b, 0x61, 0x54, 0x67, 0x5b, 0xe8, 0x75, 0xe2, 0x67, 0xff, 0x62, +0x5b, 0x5b, 0xff, 0xe8, 0xff, 0xe7, 0x6a, 0xee, 0x78, 0x67, 0xff, 0x67, +0x7a, 0xff, 0x6a, 0xff, 0xff, 0x67, 0xff, 0x71, 0xfd, 0x6c, 0x5e, 0xfe, +0xff, 0x6d, 0xe7, 0xff, 0xec, 0x68, 0x5b, 0xff, 0x5c, 0x6a, 0xeb, 0x69, +0x60, 0xff, 0x67, 0x67, 0x67, 0x7a, 0xdf, 0xec, 0x55, 0x5b, 0x5b, 0x5b, +0x71, 0x5c, 0x77, 0x72, 0x68, 0xe7, 0x6d, 0xff, 0xff, 0xff, 0xdb, 0xe7, +0xde, 0xdb, 0xff, 0xff, 0x69, 0xee, 0x78, 0x67, 0xef, 0xea, 0x5b, 0x5b, +0x67, 0x5d, 0x6f, 0xff, 0xff, 0x67, 0x67, 0x67, 0x61, 0x54, 0x5b, 0xff, +0x67, 0x67, 0x5b, 0x67, 0xf4, 0x67, 0x67, 0x67, 0x5b, 0x65, 0xf2, 0x67, +0xff, 0xe7, 0xe7, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0xfc, +0xf7, 0xf2, 0x7d, 0x5b, 0x56, 0x67, 0x5e, 0xe2, 0x7f, 0x67, 0x75, 0x67, +0x6d, 0x63, 0x66, 0x67, 0x5b, 0x5b, 0x5b, 0x5b, 0x65, 0xf0, 0x6a, 0xe7, +0x5f, 0x67, 0xff, 0x6f, 0x7b, 0x67, 0x5b, 0xff, 0xff, 0x72, 0x67, 0xff, +0xff, 0xff, 0xff, 0x67, 0x7e, 0x6d, 0xff, 0xff, 0xff, 0x67, 0xff, 0xee, +0xe7, 0xff, 0xff, 0x6a, 0xe7, 0xe7, 0x7a, 0x67, 0xff, 0xff, 0xff, 0x67, +0x67, 0xff, 0xff, 0x67, 0x67, 0x67, 0x5c, 0x5b, 0x67, 0x7f, 0x67, 0xdb, +0xfe, 0xde, 0xec, 0x5c, 0x61, 0x5b, 0x67, 0x6e, 0x67, 0x67, 0xfe, 0xff, +0xe7, 0xff, 0xe7, 0xff, 0xff, 0xe6, 0xd9, 0xe7, 0xff, 0xff, 0x73, 0x68, +0x6c, 0x55, 0xe7, 0xe7, 0xec, 0x67, 0x5b, 0x71, 0xfd, 0xff, 0xff, 0xff, +0x71, 0x67, 0x5b, 0x53, 0x5e, 0x5e, 0x5b, 0x5d, 0x79, 0x70, 0x67, 0x67, +0x60, 0x5c, 0x67, 0xff, 0x7d, 0x75, 0xff, 0xff, 0xe7, 0xec, 0xff, 0xff, +0xe7, 0xfd, 0x67, 0xf7, 0xdc, 0xf1, 0x6b, 0xe9, 0xff, 0x79, 0x7a, 0x6f, +0xfa, 0xf9, 0xff, 0x5b, 0x53, 0x5b, 0x67, 0x77, 0x67, 0x66, 0x67, 0x5b, +0x67, 0x5b, 0x67, 0x67, 0x74, 0x75, 0x7e, 0xf3, 0x67, 0x5c, 0x67, 0x67, +0x5c, 0x67, 0x6a, 0xea, 0xff, 0xff, 0x67, 0xff, 0x7b, 0x78, 0xdf, 0xff, +0xdd, 0xee, 0xfd, 0xf6, 0x67, 0xe7, 0xff, 0x74, 0x67, 0x67, 0xe7, 0xfe, +0xff, 0xec, 0x5c, 0x61, 0xe7, 0x6a, 0x5b, 0xf8, 0xfb, 0xef, 0x79, 0x65, +0x5f, 0x5b, 0x67, 0x60, 0x67, 0x55, 0xf2, 0xff, 0xe7, 0x61, 0x5b, 0x67, +0x67, 0x5b, 0x5e, 0x5e, 0xe8, 0xf3, 0x67, 0xe8, 0xe7, 0xdd, 0xff, 0xe7, +0xdb, 0xf7, 0x70, 0xff, 0xff, 0x6f, 0xff, 0xff, 0xe7, 0x67, 0xff, 0x60, +0x5c, 0x5d, 0x6e, 0xff, 0xec, 0xff, 0x67, 0x67, 0x67, 0x5b, 0x5b, 0x67, +0x5c, 0xff, 0xff, 0x67, 0x6e, 0x67, 0x67, 0x60, 0x67, 0x67, 0x67, 0x67, +0x67, 0x70, 0xff, 0xff, 0x67, 0xff, 0xff, 0xff, 0xfd, 0xf6, 0xff, 0xff, +0xf5, 0xff, 0xff, 0xe2, 0x6c, 0x67, 0x67, 0xff, 0x67, 0xff, 0x63, 0x5b, +0x67, 0x5b, 0x7b, 0x67, 0x67, 0x5d, 0x49, 0x5b, 0x67, 0xe7, 0xff, 0xdf, +0xe5, 0x4d, 0x3b, 0x55, 0xbe, 0xbf, 0x66, 0x41, 0x5b, 0xc3, 0xd3, 0x47, +0x43, 0x79, 0xcf, 0x67, 0x3e, 0x51, 0xc4, 0xbc, 0x6d, 0x3e, 0x50, 0xdf, +0xe7, 0xf9, 0xd4, 0xca, 0x46, 0x37, 0xee, 0xaf, 0xba, 0x40, 0x34, 0x4b, +0xc9, 0xc7, 0x56, 0x39, 0x46, 0xc5, 0xbc, 0x4f, 0x33, 0x4f, 0xbc, 0xc8, +0x4b, 0x39, 0x7e, 0xb6, 0xbc, 0x4b, 0x39, 0x45, 0xcc, 0xc1, 0xec, 0x41, +0x4a, 0xc5, 0xce, 0x48, 0x4c, 0xc9, 0xc4, 0x59, 0x41, 0x53, 0xd9, 0xdb, +0x56, 0x56, 0xdd, 0xcd, 0xdf, 0x4e, 0x5c, 0xda, 0xc6, 0xf0, 0x5b, 0x5b, +0x53, 0x4f, 0x67, 0x71, 0x53, 0x49, 0x4f, 0xfa, 0xd9, 0xff, 0x5b, 0x4d, +0x5b, 0x45, 0x5e, 0xcb, 0xcd, 0x63, 0x49, 0x49, 0xdf, 0xc9, 0xd3, 0x45, +0x4b, 0xdf, 0xbf, 0xcc, 0x3e, 0x39, 0xc6, 0xb4, 0xc9, 0x44, 0x3c, 0x69, +0xbe, 0xcd, 0x45, 0x37, 0x46, 0xc4, 0xbd, 0x62, 0x3c, 0x4d, 0xbe, 0xce, +0x3d, 0x32, 0x47, 0xc7, 0xc2, 0x69, 0x3f, 0x42, 0xce, 0xbd, 0xcb, 0x4b, +0x38, 0x47, 0xcc, 0xc1, 0xd7, 0xdb, 0xef, 0x42, 0x3f, 0x5f, 0xd8, 0xce, +0xe7, 0xdb, 0xff, 0x51, 0xff, 0xff, 0x73, 0xe7, 0xe7, 0x7a, 0x6b, 0xd4, +0x66, 0x5d, 0x7a, 0x6f, 0x55, 0xed, 0xd3, 0xdc, 0x6b, 0x50, 0x5b, 0x53, +0x6e, 0x68, 0x4c, 0x50, 0x54, 0xd0, 0xc5, 0xe7, 0x48, 0x49, 0xdc, 0xdd, +0xff, 0x5c, 0x3a, 0x4e, 0xce, 0xc1, 0xda, 0x4a, 0x5c, 0x67, 0x67, 0x67, +0x52, 0x5a, 0xf0, 0xd3, 0xd3, 0xd7, 0xcd, 0xdb, 0xed, 0x5b, 0x57, 0xcf, +0xd4, 0x51, 0x47, 0x4d, 0x48, 0x5d, 0xe6, 0xff, 0x59, 0x79, 0xcf, 0xf4, +0x46, 0x4c, 0xd0, 0xc1, 0xcf, 0x4c, 0x3c, 0x41, 0xe0, 0xbd, 0xd5, 0x3e, +0x3e, 0x4e, 0xc5, 0xd4, 0x61, 0x53, 0x56, 0x74, 0xcd, 0xc7, 0xe6, 0x4e, +0x6b, 0xd9, 0xce, 0xe0, 0x52, 0x4a, 0x54, 0xd2, 0xd2, 0xe8, 0x4d, 0x46, +0x4d, 0x69, 0xeb, 0xee, 0x5d, 0xff, 0xff, 0x7d, 0x67, 0x55, 0x4a, 0x67, +0xff, 0xff, 0xdb, 0xf5, 0x68, 0x53, 0x71, 0xdc, 0xe7, 0xeb, 0x54, 0x4d, +0x6b, 0xdc, 0xdb, 0xed, 0x4b, 0x4f, 0xfb, 0xce, 0xdb, 0x53, 0x4a, 0x4b, +0xe4, 0xc3, 0xc5, 0x65, 0x40, 0x4c, 0x67, 0xdb, 0xe7, 0xfe, 0x5b, 0xe7, +0x5c, 0x61, 0x6f, 0xfc, 0x60, 0xff, 0x67, 0x5b, 0x4b, 0x65, 0xe7, 0x65, +0x5a, 0x6f, 0x5a, 0x52, 0x7a, 0xcd, 0xd1, 0x55, 0x5c, 0xdb, 0x4c, 0x54, +0xd1, 0xd6, 0x54, 0x4c, 0x72, 0xdb, 0x4f, 0xef, 0xdb, 0x65, 0x4e, 0xed, +0xc9, 0xd0, 0x4f, 0x6f, 0xff, 0x56, 0x5b, 0xe7, 0x5f, 0x65, 0xe6, 0xf7, +0x4c, 0x46, 0x4c, 0xdd, 0xdc, 0x5e, 0x51, 0x45, 0x56, 0xdf, 0xc6, 0xfa, +0x4c, 0x49, 0x55, 0xd9, 0xe6, 0x5f, 0x53, 0x4d, 0x4f, 0xe7, 0xe7, 0x70, +0x5b, 0x78, 0x71, 0x69, 0xdb, 0xcd, 0xe9, 0x5b, 0x4d, 0x68, 0xe7, 0xd9, +0xd3, 0x75, 0x51, 0x53, 0x6b, 0xd3, 0xe6, 0x67, 0x59, 0x53, 0x49, 0x4e, +0x65, 0x67, 0x6a, 0x5e, 0x4b, 0x53, 0x49, 0xf0, 0xe7, 0xdb, 0x63, 0x4e, +0x77, 0xff, 0xfc, 0xcd, 0xe3, 0x53, 0x49, 0x4f, 0x5b, 0x4b, 0x61, 0xd4, +0xd0, 0xeb, 0xe7, 0xe0, 0xeb, 0xff, 0xe7, 0x61, 0x49, 0xef, 0xd3, 0x6d, +0x53, 0xfb, 0xe7, 0xff, 0xfc, 0xce, 0x79, 0x41, 0x43, 0x48, 0x42, 0x4f, +0xcf, 0xc1, 0xcc, 0xcc, 0xc9, 0x64, 0x40, 0x45, 0x61, 0x78, 0xeb, 0xd7, +0xdd, 0x4f, 0x3d, 0x46, 0x4d, 0x4b, 0x6c, 0xdb, 0xc8, 0xca, 0xd1, 0xe4, +0x52, 0x45, 0x51, 0x68, 0xd8, 0xd3, 0xcd, 0xec, 0x59, 0x4e, 0x53, 0x56, +0x7d, 0x6e, 0x55, 0x7c, 0x67, 0xf8, 0xd4, 0xd3, 0xde, 0x55, 0x53, 0x5a, +0x42, 0x56, 0xcd, 0xd1, 0xd3, 0xcd, 0xc9, 0x57, 0x3c, 0x35, 0x35, 0x3b, +0xe2, 0xbc, 0xb7, 0xbd, 0xcb, 0x6a, 0x47, 0x41, 0x52, 0x71, 0x5a, 0x77, +0xcd, 0xce, 0xe7, 0xdb, 0x59, 0x46, 0x3c, 0x3f, 0x58, 0xe3, 0xc1, 0xc0, +0xc1, 0xe9, 0x58, 0x45, 0x4e, 0x67, 0xe2, 0xe7, 0xd3, 0xd3, 0x69, 0x47, +0x44, 0x45, 0x4a, 0x67, 0xdd, 0x7c, 0x6e, 0xd5, 0xdf, 0xff, 0xdd, 0xdf, +0x4d, 0x64, 0xd8, 0xd3, 0xca, 0xbc, 0xbd, 0x5c, 0x35, 0x2d, 0x2c, 0x34, +0xe8, 0xb7, 0xab, 0xae, 0xb1, 0xc6, 0x43, 0x39, 0x38, 0x34, 0x4a, 0x67, +0x5b, 0x67, 0xd2, 0xcd, 0xd3, 0xce, 0x52, 0x3e, 0x39, 0x47, 0x65, 0xc9, +0xb4, 0xb3, 0xbf, 0x73, 0x4b, 0x3a, 0x43, 0x66, 0xce, 0xcc, 0xc8, 0xcd, +0xea, 0x48, 0x3f, 0x3c, 0x3f, 0x49, 0x72, 0xc9, 0xc1, 0xcb, 0xca, 0x67, +0x38, 0x3d, 0xe6, 0xb5, 0xab, 0xa8, 0xb1, 0x4c, 0x28, 0x1f, 0x23, 0x32, +0xc4, 0xaa, 0xa2, 0xa5, 0xb6, 0x53, 0x2f, 0x29, 0x2b, 0x2f, 0x4b, 0xe7, +0xc9, 0xc9, 0xdb, 0x4d, 0x50, 0xff, 0xd2, 0xcd, 0xe5, 0x48, 0x37, 0x3c, +0x55, 0xc9, 0xb4, 0xad, 0xb3, 0xc9, 0x4a, 0x39, 0x3d, 0x49, 0xde, 0xcc, +0xc1, 0xd9, 0x4b, 0x3c, 0x38, 0x3f, 0x52, 0xff, 0xda, 0xca, 0xc5, 0xcf, +0x4b, 0x3c, 0x37, 0x54, 0xc1, 0xa8, 0xa7, 0xad, 0x50, 0x23, 0x1e, 0x1f, +0x31, 0xc2, 0xa2, 0x9f, 0xa4, 0xbb, 0x36, 0x25, 0x27, 0x34, 0xea, 0xbb, +0xb6, 0xbc, 0x4c, 0x3b, 0x37, 0x43, 0xe1, 0xc2, 0xda, 0x55, 0x49, 0x49, +0x5e, 0xc1, 0xb8, 0xba, 0xbd, 0xdb, 0x62, 0x4a, 0x66, 0xe3, 0xfd, 0x5b, +0x49, 0x45, 0x49, 0x45, 0x51, 0x53, 0x5b, 0x53, 0x67, 0xe7, 0x6d, 0x5f, +0x67, 0x5b, 0xd4, 0xc5, 0x5e, 0x35, 0x3f, 0x6e, 0xbe, 0xaa, 0xa4, 0xb4, +0x3d, 0x28, 0x1d, 0x23, 0x44, 0xaf, 0xa6, 0xa3, 0xb2, 0x51, 0x2a, 0x29, +0x3a, 0x69, 0xaf, 0xb0, 0xc3, 0x47, 0x2d, 0x28, 0x31, 0x4d, 0xc2, 0xb8, +0xbc, 0x52, 0x3a, 0x3b, 0xde, 0xb0, 0xa6, 0xa9, 0xc1, 0x40, 0x2b, 0x28, +0x2f, 0x66, 0xb7, 0xb6, 0xb6, 0xd6, 0x3d, 0x38, 0x30, 0x3d, 0x57, 0xe7, +0xc2, 0xcf, 0xdd, 0xf5, 0x46, 0x4d, 0x78, 0xcd, 0xcb, 0x3c, 0x39, 0x49, +0xbf, 0xa7, 0x9f, 0xa0, 0xbd, 0x39, 0x1e, 0x17, 0x1e, 0x3a, 0xbd, 0xa2, +0xa4, 0xac, 0x60, 0x2c, 0x29, 0x32, 0xdc, 0xb2, 0xbc, 0xc7, 0x38, 0x2a, +0x28, 0x2e, 0x53, 0xb2, 0xad, 0xaf, 0xc5, 0x42, 0x3f, 0x79, 0xba, 0xaa, +0xa7, 0xbf, 0x3e, 0x29, 0x26, 0x2d, 0x52, 0xb5, 0xad, 0xaf, 0xbf, 0x3c, +0x2f, 0x2d, 0x37, 0x4d, 0xbd, 0xbe, 0xc3, 0xd3, 0x66, 0x49, 0x48, 0x45, +0x7d, 0xc3, 0x5d, 0x37, 0x3f, 0x78, 0xba, 0xa3, 0x9d, 0xa9, 0x66, 0x24, +0x19, 0x1c, 0x2b, 0xd9, 0xab, 0x9f, 0xa6, 0xc5, 0x43, 0x33, 0x33, 0xf3, +0xbc, 0xbf, 0x4e, 0x37, 0x28, 0x27, 0x33, 0x65, 0xb5, 0xaa, 0xad, 0xbf, +0x5f, 0x42, 0x41, 0xdb, 0xb5, 0xac, 0xac, 0xcc, 0x35, 0x25, 0x20, 0x29, +0x4e, 0xb1, 0xab, 0xab, 0xbb, 0x42, 0x2a, 0x28, 0x2d, 0x4a, 0xc7, 0xb4, +0xb4, 0xc8, 0x46, 0x3b, 0x37, 0x3f, 0xbe, 0xb1, 0x4d, 0x48, 0x49, 0x41, +0xb6, 0x9c, 0x9d, 0xab, 0x5d, 0x1c, 0x14, 0x1c, 0x2d, 0xca, 0xa3, 0x9d, +0xa9, 0xb7, 0x5a, 0x38, 0x36, 0x5b, 0x44, 0x3e, 0x39, 0x2e, 0x2d, 0x38, +0x42, 0xc9, 0xb3, 0xad, 0xaf, 0xbc, 0xdc, 0x5a, 0x4a, 0x4d, 0x60, 0xc7, +0xb5, 0xb7, 0xca, 0x3f, 0x2e, 0x28, 0x30, 0x4a, 0xb5, 0xa8, 0xaa, 0xb6, +0x47, 0x2e, 0x27, 0x2d, 0x51, 0xbd, 0xad, 0xb2, 0xed, 0x3a, 0x39, 0x38, +0x3c, 0xc9, 0xb0, 0x4e, 0x36, 0x3f, 0xee, 0xad, 0x9b, 0x9e, 0xb2, 0x32, +0x17, 0x12, 0x1b, 0x2d, 0xc4, 0x9d, 0x98, 0x9e, 0xae, 0x5f, 0x2d, 0x2b, +0x2c, 0x32, 0x3d, 0x3f, 0x38, 0x3d, 0x4c, 0x5f, 0xc2, 0xaf, 0xae, 0xac, +0xb9, 0xd9, 0x41, 0x3c, 0x3c, 0x3d, 0x5c, 0xc0, 0xae, 0xaf, 0xbc, 0x3b, +0x28, 0x24, 0x2a, 0x4b, 0xb5, 0xa8, 0xab, 0xbe, 0x40, 0x2a, 0x29, 0x33, +0x54, 0xbb, 0xb4, 0xc9, 0x63, 0x4a, 0x3d, 0x3d, 0x4a, 0xb9, 0xbb, 0x48, +0x37, 0x5d, 0xbd, 0xa5, 0x9a, 0xa1, 0xc6, 0x23, 0x13, 0x11, 0x20, 0x39, +0xaa, 0x99, 0x97, 0xa2, 0xb9, 0x45, 0x2c, 0x28, 0x2a, 0x2e, 0x34, 0x38, +0x35, 0x43, 0x6b, 0xc5, 0xba, 0xad, 0xad, 0xb5, 0xcc, 0x41, 0x32, 0x34, +0x41, 0xe3, 0xd3, 0xc6, 0xbc, 0xbb, 0xbe, 0xe2, 0x38, 0x2a, 0x2b, 0x32, +0x5c, 0xb8, 0xad, 0xae, 0xbb, 0x59, 0x36, 0x2c, 0x31, 0x57, 0xc2, 0xb6, +0xbb, 0xd1, 0x45, 0x3b, 0x36, 0x53, 0xaa, 0xaf, 0x33, 0x3b, 0x4a, 0x4c, +0xa8, 0x9c, 0xad, 0x48, 0x1e, 0x13, 0x19, 0x2e, 0xc5, 0x9d, 0x94, 0x9c, +0xb0, 0x70, 0x2d, 0x24, 0x28, 0x2d, 0x36, 0x46, 0x4b, 0x4e, 0xd3, 0xc0, +0xb6, 0xaf, 0xae, 0xbc, 0xe4, 0x3f, 0x30, 0x34, 0x5d, 0xc8, 0xbb, 0xba, +0xc4, 0xe4, 0xf0, 0xc9, 0x79, 0x38, 0x30, 0x2e, 0x36, 0x56, 0xb9, 0xaf, +0xb1, 0xc3, 0x4d, 0x36, 0x38, 0x3a, 0x3c, 0x6b, 0xd9, 0xca, 0xd0, 0xd3, +0xf9, 0x5b, 0x5f, 0xc3, 0xba, 0x46, 0x34, 0x3d, 0x51, 0xb5, 0xa3, 0xab, +0xd0, 0x32, 0x1f, 0x21, 0x2f, 0xf4, 0xad, 0xa5, 0xa8, 0xb9, 0xfe, 0x3d, +0x38, 0x3d, 0x45, 0x48, 0x48, 0x49, 0x4d, 0x6b, 0xcb, 0xbe, 0xbe, 0xbe, +0xcd, 0x5a, 0x4a, 0x45, 0x4e, 0x71, 0xce, 0xc1, 0xc4, 0xdf, 0x7d, 0x67, +0xf3, 0xe7, 0x6c, 0x4c, 0x41, 0x40, 0x4c, 0xe9, 0xc3, 0xc1, 0xc5, 0xd0, +0x58, 0x46, 0x43, 0x42, 0x49, 0x4f, 0xfa, 0xd5, 0xc9, 0xc5, 0xd0, 0x71, +0x49, 0x4f, 0xd9, 0xd7, 0x33, 0x31, 0x46, 0xcd, 0xa9, 0xa0, 0xae, 0x3c, +0x1e, 0x19, 0x1e, 0x35, 0xb5, 0x9f, 0x9e, 0xa9, 0xca, 0x47, 0x36, 0x30, +0x34, 0x3b, 0x34, 0x32, 0x3b, 0x4e, 0xd1, 0xb9, 0xb0, 0xb7, 0xc9, 0x66, +0x44, 0x3b, 0x41, 0x4b, 0xd1, 0xbb, 0xbc, 0xcd, 0x5c, 0x53, 0xef, 0xe6, +0x57, 0x35, 0x2c, 0x2f, 0x44, 0x49, 0xbc, 0xb7, 0xc4, 0xe7, 0x77, 0x3b, +0x2f, 0x3f, 0x42, 0x49, 0x3e, 0x59, 0xb1, 0xb7, 0x62, 0xed, 0xc2, 0xd2, +0x36, 0x36, 0xc3, 0xaf, 0x2d, 0x21, 0x3a, 0xa6, 0x9c, 0xa4, 0xc0, 0x2b, +0x21, 0x1a, 0x18, 0x37, 0xa3, 0xa0, 0xa9, 0xa7, 0xb1, 0x4b, 0x26, 0x2b, +0x37, 0x4f, 0x43, 0x2c, 0x2f, 0xc8, 0xb9, 0xb5, 0xcf, 0xe6, 0x6e, 0x59, +0x3f, 0x2f, 0x52, 0xba, 0xd8, 0xc3, 0xb8, 0xc3, 0xc4, 0xb5, 0x6d, 0x2f, +0x27, 0x2b, 0x33, 0xed, 0xbb, 0xad, 0xb3, 0x70, 0x35, 0x40, 0x4d, 0x42, +0x3e, 0x48, 0xea, 0xc8, 0xdb, 0xc6, 0xbe, 0xce, 0x6d, 0x3c, 0x34, 0x3f, +0xc9, 0xd5, 0xdd, 0xf0, 0xde, 0x4d, 0x6e, 0x6a, 0xca, 0xb4, 0xbf, 0x48, +0x2d, 0x29, 0x31, 0x3f, 0x53, 0xbf, 0xab, 0xb0, 0xc2, 0xf0, 0x5b, 0x52, +0x3e, 0x39, 0x36, 0x3e, 0x5b, 0xcf, 0xbc, 0xb9, 0xbd, 0x63, 0x4d, 0x4f, +0x5b, 0x67, 0x4c, 0x4d, 0x5f, 0xc8, 0xba, 0xb6, 0xbe, 0xe7, 0x37, 0x2c, +0x32, 0x3e, 0xd5, 0xbf, 0xbc, 0xc2, 0xda, 0x4f, 0x3c, 0x39, 0x36, 0x37, +0x4f, 0xbe, 0xb8, 0xb8, 0xc5, 0xd6, 0x55, 0x53, 0x4d, 0x59, 0xff, 0xe7, +0xd6, 0xde, 0xdb, 0xc8, 0xdb, 0x68, 0x67, 0x56, 0x54, 0x50, 0xe3, 0xfc, +0x52, 0x46, 0x45, 0x54, 0xd7, 0xc9, 0xcd, 0xec, 0x5d, 0x50, 0x4e, 0x5b, +0x5b, 0xe7, 0x60, 0x57, 0x5c, 0xde, 0xc8, 0xce, 0xff, 0x67, 0x67, 0x5e, +0x4f, 0x45, 0x4d, 0xef, 0xc6, 0xc4, 0xcf, 0xff, 0x57, 0x52, 0x49, 0x5f, +0xd1, 0xc9, 0xd7, 0xd2, 0xc9, 0xd2, 0x63, 0x3f, 0x3c, 0x42, 0x4f, 0x67, +0xdb, 0xe2, 0xe2, 0xff, 0x5b, 0x67, 0x7e, 0xe7, 0xec, 0x5b, 0x67, 0xd9, +0xd3, 0xe7, 0x79, 0x4e, 0x5b, 0x55, 0x79, 0x60, 0x54, 0x78, 0xdb, 0xff, +0x57, 0x5a, 0xdc, 0x6c, 0xff, 0x7e, 0x62, 0xff, 0x5b, 0x5e, 0xde, 0xdc, +0xe7, 0x67, 0xe9, 0xe7, 0xdd, 0xe7, 0xe0, 0xe7, 0xce, 0xf0, 0x5a, 0x5a, +0x6f, 0x6a, 0xe7, 0x67, 0xe5, 0xf0, 0x4e, 0x49, 0x45, 0x5d, 0xdc, 0xe7, +0xd3, 0xe7, 0xe7, 0xf4, 0x5c, 0x4f, 0x59, 0x53, 0xff, 0xff, 0xff, 0x57, +0x57, 0xe9, 0x6f, 0xe4, 0xd3, 0xef, 0xde, 0x67, 0xe7, 0xff, 0xdd, 0xd8, +0xe7, 0xe7, 0x58, 0x5c, 0x67, 0x5b, 0x5b, 0x4f, 0x5b, 0x67, 0xf6, 0xd6, +0xdb, 0x67, 0x77, 0x67, 0x57, 0x55, 0x5b, 0x70, 0x67, 0x67, 0x5b, 0x5e, +0xff, 0x5f, 0xe7, 0xff, 0x5b, 0xff, 0xeb, 0xe7, 0xff, 0xff, 0xdb, 0xe7, +0xe7, 0xff, 0xff, 0x5e, 0x67, 0xff, 0x6d, 0x6c, 0xe7, 0x72, 0xff, 0x69, +0x60, 0x67, 0x67, 0xdb, 0xed, 0x7a, 0x6f, 0x5b, 0x78, 0x67, 0xff, 0x67, +0xff, 0x7d, 0x67, 0x67, 0x5b, 0x5b, 0x6d, 0x5b, 0x74, 0x5e, 0xdc, 0x67, +0xdb, 0xce, 0x79, 0x5f, 0xe7, 0x67, 0x6f, 0x55, 0x60, 0xf9, 0xe5, 0xdf, +0xff, 0xdd, 0xfd, 0x69, 0xff, 0x5b, 0x67, 0x67, 0x78, 0xdc, 0x76, 0x73, +0x68, 0xf5, 0x62, 0x5b, 0x73, 0xff, 0xe8, 0xe7, 0xe3, 0xfc, 0x71, 0xe7, +0x6b, 0x58, 0x53, 0x65, 0x6f, 0x7a, 0x67, 0xff, 0x7b, 0x67, 0x5b, 0x5b, +0x53, 0x6e, 0x66, 0x76, 0xed, 0xfe, 0xd6, 0x67, 0x7f, 0xf4, 0xe7, 0xfe, +0xff, 0xff, 0xff, 0x72, 0xeb, 0x67, 0x71, 0xff, 0x67, 0x6f, 0x6a, 0xdb, +0x70, 0xe7, 0x6b, 0x6e, 0x7c, 0x67, 0x5b, 0x53, 0x4d, 0x4d, 0x5c, 0x67, +0xf4, 0xe7, 0xe2, 0xe7, 0xfe, 0x5e, 0x67, 0x67, 0xe7, 0xeb, 0xff, 0x5f, +0x67, 0x67, 0xef, 0x67, 0x5b, 0xff, 0xff, 0xe7, 0xdb, 0xe7, 0xe7, 0x71, +0x67, 0xeb, 0xff, 0x7d, 0x62, 0xed, 0xe7, 0xed, 0x75, 0xff, 0xe7, 0x63, +0x66, 0x5f, 0x5b, 0x66, 0xe7, 0xff, 0xff, 0x67, 0x6a, 0xe7, 0x5f, 0x5d, +0x67, 0x5b, 0xff, 0x6b, 0x5f, 0xe7, 0xff, 0xe7, 0xe8, 0x56, 0x6d, 0x67, +0x59, 0xff, 0x53, 0x66, 0xd0, 0x67, 0x67, 0xf6, 0x68, 0xff, 0xff, 0x67, +0xdf, 0xea, 0xdd, 0xdc, 0x5d, 0xde, 0x5c, 0x50, 0xdb, 0x71, 0xe7, 0xff, +0x72, 0xff, 0x6c, 0x67, 0x67, 0x5b, 0x5b, 0xff, 0xff, 0x5b, 0xe8, 0xff, +0x5b, 0x53, 0x5b, 0x67, 0x67, 0x74, 0xdb, 0xfb, 0x70, 0xed, 0x7a, 0xe7, +0xec, 0x5b, 0x67, 0x64, 0x52, 0xe1, 0xe8, 0xe7, 0x73, 0x68, 0xde, 0x74, +0x68, 0xdb, 0xdb, 0x68, 0x5b, 0xff, 0xff, 0x6e, 0x67, 0x5c, 0x60, 0x53, +0x5a, 0x70, 0x61, 0x52, 0x5b, 0xff, 0x5b, 0xe7, 0xfb, 0xf8, 0x6e, 0x7c, +0x5d, 0x78, 0x7d, 0x5b, 0xff, 0x7e, 0x5b, 0x5b, 0x67, 0x6d, 0xff, 0x5c, +0x72, 0xf7, 0xe7, 0xe7, 0x67, 0xff, 0x5f, 0x6a, 0xff, 0x67, 0xe7, 0xf9, +0x67, 0xff, 0x67, 0x60, 0x5c, 0xff, 0x67, 0x66, 0x63, 0xff, 0xe7, 0xe7, +0x6d, 0xe7, 0x5e, 0xf5, 0xfe, 0x67, 0x56, 0x67, 0xe7, 0xff, 0x67, 0x67, +0x78, 0x4b, 0x5c, 0xd6, 0x5d, 0xdf, 0xe7, 0xff, 0xff, 0x5b, 0x77, 0xff, +0xff, 0xff, 0x53, 0x7e, 0x5b, 0x6d, 0xe7, 0x56, 0x73, 0xfd, 0xe7, 0xf6, +0xfd, 0xff, 0x6f, 0x5b, 0xfb, 0xee, 0x7b, 0xff, 0x79, 0x5b, 0x53, 0x55, +0x53, 0x58, 0x49, 0x5a, 0x6e, 0xdc, 0xff, 0xff, 0xe8, 0x67, 0x67, 0xdb, +0x67, 0x56, 0x54, 0x5b, 0x51, 0x4d, 0x58, 0x5b, 0xea, 0xf1, 0x5d, 0xff, +0xe7, 0xda, 0xe5, 0xd7, 0xde, 0xea, 0xef, 0x67, 0xff, 0x60, 0x5b, 0x67, +0x53, 0x67, 0x50, 0xeb, 0x5b, 0x67, 0x5b, 0x67, 0xed, 0x4a, 0x65, 0xff, +0x5b, 0xd5, 0x57, 0xdd, 0xff, 0x5c, 0xbe, 0x3c, 0xd3, 0x47, 0x5c, 0x68, +0x63, 0x4d, 0xd3, 0x4d, 0xf6, 0x5b, 0x5f, 0xbe, 0x50, 0xdb, 0xe2, 0x74, +0xe7, 0xd8, 0x4f, 0xce, 0x5f, 0x44, 0x41, 0x5f, 0x4e, 0x3d, 0x5d, 0xeb, +0x5c, 0xd3, 0xdd, 0xff, 0xd7, 0xbd, 0x53, 0xca, 0x5e, 0x43, 0xd1, 0xf4, +0x38, 0x67, 0x5b, 0x47, 0x56, 0x5b, 0x67, 0x59, 0x46, 0x57, 0xc5, 0xc5, +0xbc, 0xe4, 0x3f, 0x4b, 0x37, 0xec, 0xc8, 0xcd, 0x49, 0xd7, 0x48, 0x40, +0xe8, 0xd9, 0xbd, 0xca, 0x55, 0xcc, 0xdd, 0x52, 0x3a, 0x4c, 0xe6, 0xc1, +0x74, 0x4d, 0xe7, 0x61, 0x4e, 0x3d, 0xcb, 0xfa, 0x5b, 0x5b, 0xeb, 0x7c, +0x5d, 0xff, 0x5f, 0xfa, 0x45, 0x3c, 0x5e, 0x67, 0xd0, 0xe9, 0xdd, 0x78, +0x3f, 0xed, 0xc7, 0x5b, 0x53, 0x75, 0xff, 0xcf, 0xce, 0x67, 0x6d, 0xf6, +0x68, 0xf9, 0xe7, 0xfc, 0xfb, 0xe1, 0x4b, 0x45, 0x4e, 0x53, 0xdf, 0xea, +0xdf, 0x69, 0xe5, 0xe4, 0x72, 0x67, 0x56, 0x3c, 0x4a, 0xe7, 0x59, 0x53, +0x49, 0x67, 0x46, 0x4d, 0xd7, 0xc6, 0xc1, 0xeb, 0xe7, 0x60, 0xdd, 0xff, +0xe7, 0x67, 0xea, 0xe7, 0x4d, 0xd5, 0xcd, 0x49, 0x46, 0x49, 0xcd, 0xca, +0xda, 0xdb, 0x72, 0x4c, 0x68, 0xde, 0xec, 0x5b, 0xd9, 0x4d, 0x5b, 0x3c, +0x5a, 0xfc, 0x48, 0xdd, 0x4a, 0xfc, 0x57, 0x4d, 0x5f, 0x7a, 0x67, 0xdc, +0xc2, 0xd0, 0xcd, 0xe9, 0xd7, 0x4d, 0x45, 0x43, 0xd8, 0xe7, 0x5b, 0x40, +0x5b, 0xd9, 0xf5, 0xce, 0xe3, 0xd8, 0xdd, 0xca, 0x6b, 0xff, 0xcf, 0xee, +0x5b, 0x4b, 0x5d, 0x67, 0x4c, 0xf6, 0x5f, 0xe0, 0xff, 0x77, 0xd7, 0xe7, +0xe7, 0x53, 0x5c, 0x5e, 0x59, 0xe7, 0x5b, 0x61, 0x68, 0x3b, 0x4a, 0x5c, +0x58, 0x40, 0xef, 0xc9, 0xf4, 0x53, 0xe6, 0xce, 0xf5, 0x5b, 0xe5, 0xce, +0xd0, 0xc6, 0x53, 0x52, 0xe7, 0xf7, 0x4a, 0x5c, 0xff, 0x61, 0x68, 0xf5, +0x4b, 0x7e, 0xff, 0xcb, 0xda, 0x58, 0xff, 0x5c, 0x6a, 0x4d, 0x5a, 0x4f, +0x5e, 0x5d, 0x5f, 0x5e, 0xe7, 0x53, 0xd6, 0x4d, 0xe0, 0xe6, 0xeb, 0x61, +0xeb, 0x4f, 0x65, 0x5c, 0x5e, 0x4d, 0x53, 0x5e, 0x5b, 0x67, 0xff, 0x59, +0xeb, 0xea, 0x55, 0xeb, 0xc5, 0xbf, 0x6e, 0x68, 0xce, 0xd5, 0x60, 0x57, +0xdb, 0x6b, 0x46, 0x59, 0xda, 0x4d, 0x3f, 0x6a, 0xdc, 0x48, 0x54, 0xe7, +0xcc, 0x68, 0x4a, 0x52, 0xd7, 0xc2, 0xe4, 0x5b, 0x53, 0x57, 0x43, 0x77, +0xdf, 0xed, 0x4f, 0x53, 0xfa, 0x6a, 0x7c, 0xd5, 0x55, 0x6e, 0x69, 0xdd, +0xcb, 0xff, 0xd6, 0xff, 0x4d, 0x43, 0xed, 0xc2, 0xcd, 0x4d, 0x4d, 0x79, +0xd1, 0xda, 0x5f, 0x53, 0x4a, 0x53, 0xda, 0xe2, 0x4f, 0x5d, 0x67, 0x5b, +0x54, 0xdd, 0x60, 0x55, 0xe7, 0xf2, 0xd4, 0x5e, 0xe7, 0x53, 0x62, 0x4f, +0x5b, 0xd3, 0x57, 0x4d, 0x73, 0xec, 0x5b, 0x5b, 0x5f, 0xfb, 0x53, 0xf9, +0xfa, 0x5f, 0xcd, 0xda, 0x68, 0x6e, 0xcd, 0x67, 0xf9, 0xd9, 0xee, 0x5b, +0x59, 0x4c, 0x4a, 0x75, 0x4c, 0xff, 0x59, 0x54, 0x45, 0xed, 0xec, 0x54, +0x77, 0xc9, 0x6c, 0xd3, 0x5e, 0x72, 0x66, 0x4c, 0xd5, 0x4e, 0x55, 0x53, +0xff, 0x52, 0x49, 0x7a, 0xe8, 0x67, 0xd8, 0xe7, 0xd1, 0x67, 0x7f, 0xed, +0xe2, 0xfe, 0x67, 0x5e, 0xdc, 0x53, 0x59, 0x5b, 0x67, 0xff, 0x5d, 0x58, +0x53, 0x5a, 0xef, 0x67, 0x79, 0xee, 0x6b, 0xd3, 0xf1, 0xd5, 0xeb, 0x5d, +0x54, 0x56, 0x63, 0xdb, 0xe2, 0x59, 0xdc, 0x76, 0x53, 0x53, 0x53, 0x5d, +0x54, 0x57, 0x5f, 0xe7, 0xf0, 0xcf, 0xd0, 0x57, 0xd7, 0xde, 0x5b, 0x77, +0x60, 0xd7, 0x5b, 0x59, 0xd7, 0x53, 0x76, 0x6d, 0x5c, 0xec, 0x4d, 0x7f, +0x5e, 0xff, 0x5c, 0xe3, 0xf1, 0x5b, 0x5f, 0xf7, 0x5d, 0x60, 0x64, 0x7b, +0x6f, 0x55, 0xea, 0x53, 0x5b, 0x5b, 0x71, 0x5b, 0x5d, 0x67, 0x66, 0x63, +0xe7, 0xe8, 0xff, 0xd9, 0xd3, 0xf4, 0xe7, 0x68, 0xed, 0xd6, 0x5c, 0x6a, +0x77, 0x7c, 0x65, 0x53, 0x65, 0x4d, 0x4f, 0x67, 0x5b, 0x65, 0x53, 0x70, +0x5d, 0xdd, 0x5b, 0xff, 0xeb, 0xda, 0xfc, 0xe9, 0x4c, 0xff, 0x67, 0x6d, +0x53, 0x67, 0x5b, 0x5b, 0x5b, 0x5f, 0x4d, 0xdb, 0x5b, 0xff, 0xe6, 0xea, +0xea, 0xef, 0xe5, 0xe7, 0xe7, 0xda, 0xe0, 0xff, 0x67, 0xe7, 0x4e, 0x68, +0x50, 0x59, 0x5c, 0xec, 0xff, 0xe7, 0x5b, 0xf5, 0xfe, 0x73, 0xf6, 0xe7, +0xff, 0x63, 0xeb, 0x6e, 0x67, 0x5d, 0x68, 0x65, 0x5b, 0x57, 0xff, 0xff, +0xe0, 0xff, 0x5d, 0x5f, 0x68, 0xff, 0xff, 0x68, 0xde, 0x5e, 0x67, 0x74, +0xff, 0x68, 0x73, 0xf6, 0xfd, 0xe7, 0xff, 0xfc, 0xdf, 0xff, 0xe7, 0x67, +0x67, 0xea, 0xdf, 0x7a, 0x5b, 0x67, 0xff, 0x5b, 0x60, 0x5b, 0x53, 0x56, +0xfe, 0xf5, 0x74, 0x67, 0x62, 0xff, 0x67, 0x6d, 0x5b, 0x7d, 0x72, 0xe7, +0x5c, 0xe7, 0x5b, 0x65, 0xf0, 0xff, 0x6a, 0xef, 0xfa, 0xe4, 0x67, 0x69, +0xff, 0x5b, 0xdb, 0xe3, 0xdf, 0x67, 0x76, 0xe7, 0x7e, 0x5b, 0xff, 0x67, +0x67, 0xe7, 0x5c, 0x61, 0x53, 0xea, 0x5b, 0x64, 0x65, 0x7c, 0x5d, 0x67, +0x6f, 0x67, 0x5d, 0x5b, 0xfb, 0xff, 0xd7, 0xff, 0xdd, 0x6a, 0x67, 0x6c, +0x56, 0xe8, 0xec, 0xe2, 0x5b, 0x67, 0x6c, 0xfe, 0x5e, 0x60, 0xe6, 0x53, +0x67, 0x7c, 0x5f, 0xf8, 0xfb, 0x67, 0xe7, 0xff, 0xe7, 0xe7, 0xdb, 0xdf, +0x67, 0x55, 0x61, 0x5c, 0x6c, 0x53, 0x69, 0xe7, 0x5b, 0x67, 0x62, 0x56, +0x67, 0x61, 0x67, 0xe8, 0xdb, 0x77, 0xdd, 0xdb, 0xeb, 0x67, 0x5b, 0xff, +0x5d, 0x6f, 0x67, 0x67, 0xe7, 0xff, 0x67, 0xe0, 0xe9, 0xeb, 0xe4, 0x67, +0xff, 0x67, 0x67, 0x75, 0x5b, 0x7f, 0xf4, 0xff, 0xff, 0x72, 0x77, 0x5b, +0x67, 0x5b, 0x67, 0xe7, 0x5b, 0x7a, 0x6f, 0x5d, 0xea, 0x61, 0x4d, 0x60, +0xe7, 0x79, 0x59, 0xff, 0x7d, 0x56, 0x5e, 0x67, 0x59, 0x5b, 0xe7, 0xde, +0x75, 0x7e, 0xf7, 0x6f, 0x66, 0x67, 0xf0, 0xfc, 0xe7, 0x67, 0xff, 0x7e, +0x6a, 0x6a, 0x67, 0x67, 0xff, 0xee, 0x67, 0x77, 0xee, 0x67, 0x67, 0x61, +0x67, 0x67, 0x67, 0x67, 0x51, 0xe7, 0x5c, 0x5b, 0xff, 0x5c, 0x72, 0x67, +0x67, 0xff, 0x5d, 0xff, 0x53, 0x6a, 0x5e, 0x57, 0x5d, 0xea, 0xe7, 0xfb, +0xe7, 0xe7, 0xfc, 0xe7, 0xdb, 0xff, 0xff, 0xf3, 0xe7, 0x67, 0xff, 0xff, +0xe7, 0x76, 0x66, 0x5b, 0xff, 0x69, 0xff, 0x64, 0x4e, 0x60, 0xea, 0x5b, +0x67, 0x67, 0x67, 0x5b, 0x67, 0x5b, 0x57, 0x67, 0x77, 0xee, 0xe7, 0xe7, +0xed, 0xff, 0xff, 0x62, 0x5b, 0x67, 0x6c, 0xff, 0x5b, 0x6c, 0xdc, 0x5a, +0x5d, 0x67, 0x71, 0x79, 0x67, 0xd3, 0xe7, 0xff, 0xe7, 0xfb, 0xff, 0xe0, +0x66, 0x67, 0xe7, 0x67, 0x76, 0xe7, 0x67, 0x67, 0x5e, 0xff, 0x6d, 0x5e, +0x68, 0x61, 0x6c, 0xff, 0x53, 0x5d, 0xe9, 0x5f, 0x55, 0xe9, 0x5b, 0x67, +0x67, 0x5f, 0xfa, 0x57, 0x66, 0xe7, 0x6b, 0x67, 0xff, 0xff, 0xe7, 0xff, +0xd8, 0xed, 0xff, 0x74, 0xec, 0x68, 0x67, 0xe7, 0x68, 0xee, 0xff, 0x7c, +0xf1, 0x64, 0x5a, 0x67, 0x53, 0x65, 0x67, 0x5b, 0x79, 0x70, 0x67, 0x5d, +0x4f, 0x54, 0xff, 0xf2, 0x7d, 0x76, 0xe7, 0xe8, 0x75, 0xde, 0xff, 0x5b, +0x75, 0x5b, 0xed, 0x76, 0x66, 0x6e, 0x67, 0x7b, 0x5f, 0x67, 0x67, 0x5b, +0x5d, 0xdd, 0xef, 0xf7, 0xda, 0x60, 0xe6, 0xe3, 0x61, 0xfd, 0xf6, 0xff, +0x67, 0x62, 0x59, 0x53, 0x74, 0x6d, 0x5b, 0xff, 0x5b, 0x67, 0x72, 0x6f, +0x5b, 0xff, 0x6b, 0xe7, 0xe7, 0x67, 0x67, 0xef, 0xdd, 0x6a, 0x60, 0x67, +0xe7, 0xe7, 0x65, 0x63, 0xf3, 0xe9, 0x62, 0x74, 0x67, 0xff, 0xf5, 0xe7, +0xff, 0xff, 0x68, 0x53, 0x6b, 0x69, 0xff, 0xe7, 0xe7, 0xf0, 0x79, 0x55, +0x53, 0x5d, 0xff, 0x67, 0xdb, 0xf8, 0x6e, 0x7a, 0x53, 0xff, 0x5b, 0x51, +0x5e, 0x67, 0x5e, 0x5e, 0x67, 0x67, 0x5b, 0x5b, 0x5b, 0x5b, 0x67, 0xe7, +0x78, 0x7b, 0xf0, 0xea, 0x67, 0xff, 0x67, 0x79, 0xff, 0xe7, 0xf8, 0x6e, +0xe9, 0xff, 0x61, 0xff, 0x58, 0x67, 0x5b, 0x75, 0x67, 0xff, 0x5b, 0x67, +0x67, 0x6d, 0x5b, 0x5b, 0x5f, 0x5d, 0x67, 0x5b, 0x53, 0x5b, 0x67, 0x79, +0xff, 0xf0, 0xe9, 0x67, 0x60, 0x5b, 0x67, 0x6e, 0x67, 0xff, 0xe7, 0xe8, +0x6c, 0xf4, 0x67, 0x67, 0xf5, 0xdc, 0x6d, 0xff, 0xff, 0x6e, 0x67, 0xff, +0x65, 0xf8, 0xf7, 0x5c, 0xea, 0xff, 0xd7, 0xff, 0xff, 0x70, 0x5b, 0x5d, +0xff, 0x66, 0x53, 0x6e, 0x66, 0x76, 0xff, 0x67, 0x67, 0x53, 0x5b, 0x73, +0x76, 0x67, 0xe7, 0xdd, 0x67, 0xff, 0x5b, 0x65, 0x67, 0x67, 0xff, 0x6f, +0x7a, 0x79, 0x67, 0x69, 0xe7, 0xee, 0xe7, 0xe7, 0xe7, 0xff, 0x4d, 0xe7, +0xe8, 0xff, 0x67, 0x7f, 0xff, 0x67, 0x67, 0x6d, 0x58, 0xe7, 0x67, 0x6b, +0xff, 0x5b, 0x67, 0x5d, 0x5b, 0x52, 0x59, 0xfe, 0x53, 0x78, 0xff, 0x53, +0x63, 0x72, 0x5b, 0x51, 0x5b, 0x5c, 0xec, 0xf4, 0xe7, 0xd9, 0xd6, 0xfe, +0xed, 0x63, 0x5b, 0xff, 0x67, 0x7c, 0xff, 0x67, 0xe9, 0x6f, 0x67, 0x67, +0xff, 0xdb, 0xe4, 0x67, 0x5c, 0x67, 0x5f, 0x5b, 0x5b, 0x5b, 0x5b, 0x75, +0x67, 0x67, 0x67, 0xe7, 0x67, 0x5b, 0x67, 0x67, 0x5f, 0x67, 0xe9, 0xff, +0x5b, 0x65, 0xe7, 0xea, 0x7a, 0xff, 0x7a, 0x67, 0x5f, 0x67, 0x6b, 0x5b, +0x67, 0x67, 0x61, 0x67, 0x67, 0xff, 0xe8, 0x5b, 0xff, 0xe7, 0xe7, 0xe7, +0xe7, 0xe7, 0x67, 0x5c, 0x5b, 0x5b, 0x67, 0xff, 0x67, 0xea, 0x6f, 0x67, +0x67, 0x67, 0x4e, 0x53, 0xe9, 0x79, 0x59, 0xdd, 0xd4, 0xe3, 0xdd, 0xe8, +0x5b, 0x62, 0x7f, 0xd1, 0x6d, 0x53, 0xed, 0x6e, 0x66, 0x67, 0x67, 0x67, +0x67, 0xff, 0x69, 0x67, 0xea, 0x5d, 0x6f, 0xdb, 0x5f, 0x5b, 0xe7, 0xf7, +0xd0, 0xe8, 0xec, 0x73, 0x5b, 0x67, 0xf4, 0x67, 0x74, 0x67, 0x5b, 0x5b, +0x5b, 0x66, 0x53, 0x55, 0x5b, 0x71, 0x5b, 0x5c, 0x70, 0xed, 0x4e, 0x4d, +0x6a, 0xe7, 0x6f, 0xfb, 0xd5, 0xdf, 0x67, 0x77, 0x72, 0xfd, 0xe7, 0xed, +0x68, 0xff, 0x74, 0x67, 0x61, 0xff, 0x68, 0x6e, 0x53, 0x5b, 0x67, 0x5a, +0x5a, 0xff, 0xdd, 0x5e, 0x57, 0xea, 0xff, 0x4d, 0x6b, 0xf8, 0x53, 0x67, +0x67, 0xf2, 0x7b, 0x53, 0x58, 0x5b, 0x56, 0x67, 0xe7, 0xf4, 0x6c, 0xff, +0xe7, 0xff, 0x68, 0xee, 0x77, 0x7c, 0xf1, 0x67, 0xe7, 0x5f, 0x6a, 0xff, +0xff, 0xff, 0xff, 0x60, 0xfc, 0xe7, 0x72, 0x54, 0x76, 0x67, 0x67, 0x67, +0xd9, 0xdb, 0x4f, 0x67, 0x5b, 0x5b, 0x56, 0x67, 0xe7, 0x4e, 0xea, 0x7b, +}; diff --git a/contrib/netbsd-tests/dev/audio/t_pad.sh b/contrib/netbsd-tests/dev/audio/t_pad.sh new file mode 100755 index 0000000..8caf23a --- /dev/null +++ b/contrib/netbsd-tests/dev/audio/t_pad.sh @@ -0,0 +1,47 @@ +# $NetBSD: t_pad.sh,v 1.3 2010/11/07 17:51:17 jmmv Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case pad_output +pad_output_head() +{ + + atf_set "descr" "Check pad driver output against known-good output" +} + +pad_output_body() +{ + + atf_check -s exit:0 uudecode $(atf_get_srcdir)/t_pad_output.bz2.uue + atf_check -s exit:0 bunzip2 t_pad_output.bz2 + atf_check -s exit:0 -o file:t_pad_output $(atf_get_srcdir)/h_pad +} + +atf_init_test_cases() +{ + + atf_add_test_case pad_output +} diff --git a/contrib/netbsd-tests/dev/audio/t_pad_output.bz2.uue b/contrib/netbsd-tests/dev/audio/t_pad_output.bz2.uue new file mode 100644 index 0000000..e0cbf52 --- /dev/null +++ b/contrib/netbsd-tests/dev/audio/t_pad_output.bz2.uue @@ -0,0 +1,1035 @@ +begin 644 t_pad_output.bz2 +M0EIH.3%!629369%IQ#X`MT#FU'+1O7<;MT;NYNNYW<[N[OO;K>W7+>^Y[M;[LV]??=M] +MYZ[MMMO>WO;6=W.KIOKNUF:EFEJVK5I"+:J;8:B5K1JJIJVUJV,K6IK5MJJ6 +M--%5FJLS55K158M5K:U5FU4RVMJ(K0BK-6Q0-L+6JVLJ6MK559M5556*M54J +MJMIMFS-"U6LJRUBRJJRV;55::M6U[G=0JI5-4W66J=KVZ]LNW=]W=FW=S;YM +MDO<]LW>Z[WW%E@WUOD-[G!SN<'=W$CD8@[KN<36:PVO=W;*I*E%4SC +MV]XE)5!54*"@*JJMH)J0H*`4&V4`!11(``!4BJI27O>Z(]5()`22)**%4``I +M0`!*B5`D(DB*5@:5``AH`"8F3"8`F0#3(Q,FF@#1H&(&C)H-#3330!ID,C`C +M!-,F)IIA`TQ-,!,33$831@@R9&$T`!,`@TD@FC$``````&@```:-`3`F$P0T +M,$!@`$``#03T!H-`U,`33$TTQJ-,$P$P%/$R8",!-02FDI"!$QJ>S,`0`$!H +M:!#":$Q-,28$V@0-`34]$:;*:>D]1I[0H'HGDRC:AD&@]0&@/4`]0R`R,AH- +M!H`VHS2`:`(4E)*)&R>J-^GBGL!2,:::2;48GI$IO%)Y)Y)[3TE/U1^FFC*C +MQ&H>IZC$T,AIZAZF31H>4``'J!DTTT---```#U```-`9#0T``T!(I((28-)B +M>A3TTF>14]3VT&IJ>R,@F$TQ'DT3&@FU3\4GFDT>J>333&IBFTPF$T]$-,32 +MGM-4]IDTR)ZI^1I3V332;(93-4_5/R>D#":GDU-D:FIZ>IM3U-HTH)-25)%1 +MM3:3]L/-2$FWD4S4U-B:::FB;4V3"4_4R4>H>U0;4]JGJ&33T]4T`#(T-&0] +M0!HT-`_5`!Z@T````9!IH:```````_Q$/Z:,D&8X$&L.'B.D00+!M12TQ2"> +MGH4)$$U776'(,NA5T"`@H&+#%`;<'^;2<4$`CK#I>?6\SY]KTOQX,LDD%=#] +M=K=W[.S5.*PD:9EE+#8V,8RRL@"_3]+%\'Y\OE<[XY25)9,&QL(&#!(B3@T. +MCTYNF5=LVA0D0'QD+"T]J]AX/R0)P"P$\13QX$Q,/GR(O5_U5.R7J.DE`0K( +MEC0PL$_ONQ0)A@@60_";^_OE&;Q_:\_3BPGL8?\=O:KUNG!-MF0A03X9PPMX +MF'WE;&SK)O(N2J"`80_J9Y6*=6(?DZ7*_=I%;(JB,Q$/X5S@P$*M6IZ6$>F. +M&L;Y&C($S\KC'O`Q#')%M:;\FTP-4ET5[;UV7JU<$0D7*H[&KC\]MFO+$`\& +MK%L^,?8,8N-=10VF1`%ZT<0V#-6C#OCSQ<+:D1!\*'M+14@>!P\/!T&+LDA` +MM>S!`Y))"PU-A7RRF1#XLD2TAAXFXPES0HB!="\G,MI5;+<6\:#8!?:^9F[% +ME',L8MFO;T)7.GR!;_`/D0:1+;UF7Y[3=J&V"``O/U.NE!"#*9$.X86#N,8I +M`#2>Y2VR.+WM3?[`$7UIE`R.12-/ADE3=;A$1!:]O_:**7`0NS1[]JFWB&;, +M9H]?3J1$29(D`##!T*ZI]K?Y2?W`!+<"-:V[)FM&)64CY`27=R&1(43Q0:.3 +M57.RL\G5'0B!%DUBC6R2:/8GH36'00V/_3FF$$BHG7;+O%I3X!8&S2LK'/>1 +M8OS=Z#;4Y$43X>>W=G@!;JCZJXZ+CG@"_SV[O7ZI=P8DJ:+_5D',I4)`;G=/ +M'LMX@K6`@UZ4;>CQD0!>G1L^>LPH@:>W<=.CS^7@)?+I``+POTESZ]3/ZA2! +M75?3@*BYG9V,AZN4Q4&IJ@(<=6[N*2:B4T)ITB]VC:@%[*8[4SK5EZR_]5WDD@B*BP]Z +MM&`(P"9NX?<(%_4:IX/(`!5M=`Y*J0ALV/=9UEH,?/)])PN4S.3Q*JX(OE@. +M2:Z?"+C-^RQK#(AH^YZF'"(N4H(.K.`QOV&@=HI"`,-P0@1,W5)#ZE916Z/V +MDMCV8^`4YS\-7R*L!D&Y@OT/@[O\HB+8?+K:EP*>6KQIHI#9&]*\I@AOG`B[ +ME!(1^\3.":TV[8($^"X\PV,D"7'@5IA +M_&HS5?4^K5(@17-'D>"%FJ8^%HE-%-GP07=Y"M@$+JL?O=<_H_;+X"$$)/+$ +M(#&Y%>VSVDIS6@!!PH[W&3U(!SXV;RV<\".VZ\"A!%NDZM&LY*JMTR0+GH5% +M-UD0(OWQ1PM=G=;!V2D>(AEP2@)MH6&EBU77QS:R7B0`5P)?N)=]4'"%!``L +M6>;IEY>3]?^J#F8Y((@VJ'9(3=(Y;EL/U*W3_M""&*6LOPA)`2G2\;XHZ?,1 +MN@9?--I!`7BU)`)6&?V2\RV=GPPO_+AI`13_]&!9NI8WF&D8=EAD>=1@A]-M +M2*,@.#^UP_^]`1,'Y@7\>&O=GPWW86]K`46*"9"107H9R&2FIS4QC(C9?S9E +M0`/+,`K\G03>F3F0D&K]O^I"WC##9]90$6;P/K*\,L":#V^TRY\OGS?!Z.>D +M($R4A>S*K^+BN!7^#D(`!):^.YO0(#Y_7L:3*O#7:[G5>S#2DD#:[ZDW8'GX +M2)284[['@*/]+TCLR$C2\R=8*W5,5CI?!P%6`2B(:+04!>;6K6S6]](_;T]*B(`QH.-:D+F0Y(DOX[O8A^D&ZOMFWV'@4'P8^/`G6' +M4MT7D&'K95`"'TM;8HC'LCRM8)T%MM8^D+N/=;2(V#3NCX`4ISMR_2ZY!(<< +MODMH/*.`-_8\FLT9T`6L6N;B +ML+\].#\V8R;3BE920@#2V1+PA(E.R3ONAYKUN//A^GSGB+*OAX\D`:G4 +M:N6A>'`4Q\%%^V;+*\"K@=4D2`OFKMZ-$0*_[`*>S-)N7WOTB9UK:P8!A_-* +M!#IK6Q(LWF_4F>(UJO>>(9:Z7`0D,+EMF0/N3>?#*1()V)O8Z86&8^!<^ZRS=X!-^V>ZVP;`ZT!\%Z,_M4O]>(!*Q +M%78V.MY[N[_RBAL(JLA?)W_"-+S/ZED0 +M;/3I;2@T6N\'?(;S])2EU,C6-+$@`&SZ+)688"[5QVM98;-GB%YN\`AY&9IE +MW6!=**T2J@+$5]."ANQ]8K\>S;J0'=Q541?&&5H]>H.:O/8H/BC(H+5TL-!% +MC&+N0$H<`3/0LN='R;P@R<.!'<-C*;7FPP#W3-Z"8=_X,P_=A +MXHKO&(2"G=D,QU$C((T6%6GP&!#S"XF5-4V6YAT`'5EB!2_H5R+\+"TB'N$` +M+T%X4&3]-]G#I0>*@2%GIH7 +MSW9O]0D`OIGB+^\1)&P36=Y]RD/%JD1%"5@`[_O_LUM7*JV1\K6;+I3/![/Q +M.#`S2;N_U[:(B>+8XRN,SF.'J%WW8:0"&DUMP7D:"XONX&O-1"LFTT^RG +MR+S^5?!8/;3Y9K[##DDM+1(B+E*B/MD%:Y4H%W4-P>!,]+^'3!:;H\PZRRFC +M,*N]1$`Y3OHLIC/@I?18G7MEW5J04*WZE9NVEJCX]O3A@!"*.^XTQR#K_H+B +MK`_GST-]:GHOXGP6;!7_\>WC/V4[-<>[Y"(A'>SUX`+BNS=W40.$/SF;@#%7 +M/G9ZN`.E)(9E.O"`OX'_/=0TANWS\@%ZGZ"Q`@[-KB[#G4C"?(+B9O2!?3V? +MU(RWC7&#H]VG6T@"3_+P0#-+4"/+:-K195`'/]=0!>5EY/E\%"0EO%WYN;I\ +M,!92L^L[-@(=H^*F`-%2+>M'^T?2W +M'C:U,6=Z7MD- +M!S,3Y&RP>BX!RT^M!(O4_R)^"A]\?+TU4;M'@"5;;:ZIS@]DEP@`GW#)=.K] +MO\7W&3'^J?:TH`>FSXA%M?%/2O67]%.K"6EKOD22)U:K(B^/TNND%OAGR,>$A17>EHS;U89'SEZ,TK*[C@G2H>W_/QJP2&S5GGO +MJE2]X=O]U=K22`\/)G.A*\;1D5Y8TB9-1"S]]V@!)?#_OC6ZNP(-L@?M71N) +MF5SY`+]]\X//8((6RI`6'=Q>`,79HH,_*7BDQ5B$ +MF#C;\$,9E\_=O%KQ8180+*XJ:0$1[TM:]]/]?3>UY$I,\SDOR,#I1E=JFS"! +M)D6KO$6H8D4OU,[!)!$>B\C[>U3$!Z^KJW(<\.5K:U&!G41!!%$5_Y/6QC+5MNVCN4"&]Z]DJO`(9_'6]7?*ZF8/$&+R1H`D$,1>.+._G@W*)DDB;]VG`*5YF7 +MWD]IU[X\&5T,-")):A_]LR"]=;MJN5!LX6;D=]@@KQ`@^-G`>;-=H$6+3?0; +MYG3YLP?<=K)H?)5`"JW_5R6!`Q9OZ8Z#_17/+4<,$0*_:]M +M['1B(#.(QC+-;7CH'N\LREOH(>W0-/OY\=&_S[F9)"7_77XA@06;X>OJ&IOK +M]_"/D$]\6"(#S']/.AK:OAKS"CC7-%WN:`*S+_$Q\,^Z5>:9-EA;.ZD`(GSF +MIQ:L*`\3U-]F](KQ2F<&;.+!Y/Y?&`$JI5%RF94'0/-]9,`:CO;'C<7'S6Y/ +MC(IK?C@3Z*)/UJ'6-^%6!`"074SY(^7^GX$0[^K\-)/;:';#_=4R9TB+O0^G +M[]]7D3#&W$Q$WJ'_>WZV-KK`!WGEP^O)3UHKSY6'>%*ZJN$_$'M>40"Y'4TKT[6!UHFC)`&?/)6ALNE4_=YKB+#=*OU0?%/4DSB6RY5I(*1T +MBS_(D<8`16E0,O"KK9W:_/'P9`7LW2]VZ=L6P&CX1W4GLP1+"_P[R>#N[U"/ +M6WJ(6I\K#MUC,*=$& +M1:KI+^\1_-\P/5`$`\H[779:X^25NX"RC<8`-!NW(+E)7#8<-$0NNC.=8%;Y +M""W5''H1A\USP=7IXRZHLP`5SU[KII-+72^YR&2"Z82`/&[YW!C^'UK5S(MO +MW&B.-PG"G%8BH=8XL2#/=7#/E$X>/AR(5Z^AT]%#>CG.$(E5&]2?[<@D>*0/ +MLZ<&PTK&10ST<\S7A0!X<3B>_3^EJE_\RHP"TFVYCEX^77UK9&C9T20A*]99 +M7K6E``:<-TKEE8"N>WK92J@43N+VH+CGZ#],-YHU(37CX]<0)-RJOCFS%/>< +MAQN%3[ZBT6R(:O24[5N6@(0PW=6K8XBYT._;F*0;7N`AGO:TU&>^N%)?1CJ+ +MGA$!F/HR`O_,-OQ]:S+*EE+7F; +M)8:Y8$Z23!0[=.AU<55;Y+G00EZ:%X+;4.QH1$7K^V(=S>;QJF5!%*(66:M6 +M[]<2>?+NA5:@B'.L/3K#D=IF8CCD"I:=]2]C(V:VB`Z +MOS\_5M\P`2K/>9)C:#G,^D1A32(@7>9.&JW(0D0'@NOJ*)ZVW.3&/)46P09QKXZA5D`53`!D=\)LX*R1 +M!$VM(PTC]$J02F,8P,".;C\K*?9X_7%;MH6>P6<2HYV8U=JFL3)L0P;&-M=6 +MQ"QWM=K46:O@8B=]_\<9C+E\'NRM?3;$*AU\"9&FVFFQH!@"],<7:RQP[:(X +M(.&1#:N&(>`2H-SY3E0:Q```RU<;/1R="%-3!('Y%^`@'U3/^:?U'4DDD^2K +M_QSJ>F@<3(!_5_39XX%+[S0)3Q!$2G$(CR,W5,0ALWVR5@^PNW\Z?G(" +M`E5V)'F?/MYL@H'05?I>U/0;5$JNX(9@PLAMWF/]5Y=G2)KZA/W]\6KGP7TW +M=W;`93G$(W[@47APG.]9PXDV619K+/GQ=Y"H#*8MA2K<.U0:]J +M:[P_S0(`0S@3L$R/6W=-GT;+A'"+='OL8`Z36_XSN)T+M;(@*I\0Q$P[W.QU +M75`U^S3T[*WDD"J.S-BXH)4"-NVA`QPE7A^H`7^G#K^Y#]GW?Z@6;MLN!LH;Y8V[TBAUSY!77`-3DZ).?CA%NN(3U]N[8L)PO7=2[[? +MK?+IP4G)+./7E[L39T%%XY?YT$-0U[8TLY4Z3UDGQ6P.(=`BEAE9/#\#15F/ +M`>_ME9OM"".@E3DR84IGAU)L@Y9W1:M_[OX_)?[G)6:Y=`;!--*(GTMVGOC@ +M"M.:85V$\*TYC78\0T]2+KO*6=_-F75H3!"RI[5E%MF-L:((=8,M2&70#ZW- +M$O9J/0@H[BV!#T_DCO-3-M>J1$32[58X'"UIXHV&4I<18I##UHY6XXEJN&P/ +M[+_)I,DH:BVYVQQZ_O,X=!-]/8)XA,][37V[KG"[%TA.S(Y(\1:.1<'+8>P! +MTC2B]U(SYL#9%1^*\-#T-R]I/8`]M.T2RK3'>,$!HM`\3#=>9@\`-?GY`S\] +M'^7GF;T%I/11:4V6BU8@[1!]C9"PV\A^?P9`WL8!?79D"YCUK:`64G<=<^![ +MM#C.5F/_>8BBW!5>]G?,QPK`MOE8>+$X\S@'%B3EB66;K,\3Q-+A\#K:&\@;TVTVP'I=^: +MY=HX3U'3"E-E/-<7;]7*'2RO(T-)_@5+]/#*EW,7;/R1#'2:/\X@06H4X2+? +M`);^=S>ZPX(A-FAP#!KYMMM\W+;4D_I/>>`'+KI;G\$G;W7IKB3!)@6L?=9B +M8*,D]4:LO-(+-(:$GC_"'/22E/38XZ!EYB]IL#7&,F0SV+_9H#_L$NH_NN$; +M`YY;>`WRW)2(R_EGS0Y>4R/2%0UT!H>XOSJ#,5UEL#1:S819LJ2Y9YXR$;:* +M+2R9H5&H;4'TW\@&]O?C08ZIYG"M.?O$WF_L;$_+KZ/I@,;.8VO8-DAQLE_@ +M*F+&8>S(8K^[BR.2[.:J/%0B[B^IOZ/H"=7ELT(5Z3P-M%;0Y0'"PW0%B^-L +M^CHCB]9>CRF/0VMBJ084\S(]"?`EVGY&D]WJF)<7_849]9\T%NQU1^_WH&,_ +M5^:^K6L2FR(J\PH/W*3)P.C^9',6$)OO0-%D1.;GY>Z%(/[H^5!\IJCTY>TVV!=^XZ] +M/D?;R_(6)'WW?`>S2].TI:(%$?*%L3XD%Z`_[1*CVU3[S"EBV,S3O&V(D7C? +MCX7#((A-/5OOM."4.=)P3%-$'!ZQ;SBG8+&8(;Y]WO/QB!8>_ +M1`09PN#_L;#77^>^Z%CSS_RF*D%4_LM6Y\0W(7R&+SJ10?Z[!0X^R(2VMM<7 +MZ#@QIZ_ML697.F[D/>_WWC^,Z;,J'`[$<)J(QAJ.R^W['JQ@*YSF!LV#'(0G +MINP0WMHSPE6@)+;2#N0I#RQP\XZOY8'[VWX$,"E;-W,?+W,3.!;[=@838['X +MN'5^;;`/^,,G%+:5H+V&^EX>L`)7RZ=4\T.LI[4M4,2"M_G>?%I`_EHW'7=U +M+'\NP(?YXV&)GD&EZ'@@71ZH48<^!BD^E^U2EAOE3@"A4:9C6">_N/?-+AH: +MV$R>6I6S($%7H_C2_"R$&>,CKU`#E3X^\=.6!@_1^I.?=:Q_$04>S+1J?7[P +MOT8K<\G7.YV1#T(@W_3_Y[^,B6: +MEF)6-335TB(-Y'S(@B&TWK?H@"KS3:49A_AC%$T#$SB3$_&C7A%PGX%@U%E# +MH3OAQ,#V+C%%TJMF6WRU[G>I.+H?NE^<7ZO7[4$JNYWJ7W[J"60W_3]NLWF+ +MRZ7*TDY,V)/9C`GOL=[=+.]8$$0`E5TIH!H:),G*`Y\F'SZ6&"/IHYD84M7- +MB@SK9"-\W8^A%&3A-3T0L_8UBV6.(/_'+6Y_4<_W0:X/95G9K[]6,VW;)RW[BL&"4QI*+FQIL3-;]0MTG,P&5];4I-/<#MZ[$G6F\QXH3/S1?6PP?`?+Q$ +M]R*YE='TQ>X[,Z+H34N>&#L0FK==ON$!U>%8>&^_LQ7N:&03DMT_&/"P/5EL4ZUQPD"B_ +M&<%C2OQET?ZHSC`WFH*3S?D6R3B,6V'?[-W>B$Q@W>M,_N;\<`M2)=NG;C07 +M>9]X%OU`=]09"9P(UX,A^TM<,V7&O82A?MG/#`EKFD#9CS(HRZ_O6S(@.2:6 +M92'[SCA]-D@A0XX!P&6[(P'*M+1[4=/><0R]>^8MH)B>5ZXD?R9(8"OG#+]/ +MXU#^`[.XMGMC-!X*,,;J-L\ZJ[9JT&"-'.[P5%`A]1L53J-Z8O^1B&F(?/F? +MEZ6-.7H;)E,M&+ISG+`U?ZT)VCVXY'G]3\C'Y&&]UV(.+R!'\3#[M"',]^NSG/W!-`R+(=B;KN?>=B0!7YM]TGPN?R]6>&E? +M2\]9^5R5!!-?`^QG\F?HCEEH)^F(2RF_6)I0OS;,8,&8'4?ISN> +M4>5)YWW/\][[2T/#PW\^+!DC(RF'_+C\3NG0WN\FGH(:C?6_:G#U_-QO`]/L +MS0O9V;_2/OARD3*]*Q#?(@?>WP$_1TUJX%51#[8U%HU5L747&5+ST6H,!2 +M$X;-DZ;MV/:X!CJ#M-XM6U]D;/`Z@0PP% +MF8::)8Q5B+;K[!7`EGD7FR+Y68,^N&P?O`G.GY'PAY'?!EACMOFL9%XRW$LB +M2'AGMOZ+&XPU;+URN9\?W'D-6+ZHR5Y\[7_/)CNNL@J\UM&A5Q%+NN]]&.=% +M$U4\8`_>`>'`,HH/SN[`*'XE]#\?44AD&_N:@Q(@E("%]S%59Y!(SB/1:].4 +MW5K]Z+_CFN-\O"ZRF5<<61,*,QBBQXIKL0[ZB\?,S(&W)JZN4#'B-$WN"P)EZU%:7!\\_ +MG(CG+4Z09+L97)['"&1WNL:^#0DW7G*"RRF!3,OP,:)>2;LNA)RV"3ZU,^R* +M4.IG6(!CK#(+B8.'T2_W^NROX2A*1LH=*[VT&VU\\HRN/SG/#=KGH['/O<.# +M:MD,GO^/']`S!X]Q"]Y&MNP8FX^)U,5ME6[+T>)FM#Q2_S3_%VXB)5LUEX +M>+7;'D@[U-(:=6'&SD-&)[Z=DZAX<8/0;,9:/#^/J'9@J"U5#Z%&CSR(T0)V +MS.Y84,1>/W<3VO2T.].F:1;VG!XQH@Z)_,\(KV&\\PX%;;=Y/2.8S_ZS4_/=LX2 +MVN:NW,>H7RAPLCFW?KW"Q0#G0^A/!= +MP<([\FPL?J-D>"ZJB[,K_26\6@VQVD7L_`CR2IQ76S4JX\.6S6#&)2VE,7G+ +M3%:>?-AUK$ZV[*N&],3ZW.J+FV#:*#KV,^YD]6>2I*C$JJL2\7L&MZ:5Y\?> +MFZC=+!FI!PQTM68V@V7$888RN<*)`:TP=[R\]U$&_C;4F:,-':'75;7BZ?)[ +M:->K&P^#J_ZP.M(R$//!/IKX:D:#WJ/O*#T_!J)VF3#.,JZ\9GIRTY"\23IL +M[7GQWV+W#DZXJ?S*:M^Z^94<4.IJO:%]CN=[Q=&N1;J5O3Q6`BS@%]",K!&? +M;D]5YWW9KDY8FPV5)@E1M^=X="Z=95@N+B?B8A2[V.&;T3V!F^:R\7J"K&^5 +M>B4GI=!W*.@Q0$I:WC\K%/[R=-92FE"N;C72E0_U$DRCA%.MAXU7G#%G=*5W +MI'''Q@<"!KUFH=&EX?'G-2+BX\H72GD2#6;J3 +M[M!IO)0^%X\.1R"A\;JB^=/["Q?9"(*5_A_;RO;D:8MIG2$S]>8SN=@NGQZ!RY9'U7`WG;M>";K1[:9B$VB\<#)XCYV; +M=D8C`ZWY0NRS5^#$]6^RGZ#%!X6[A\IPI9-IA:KV)FG'(/%)6F0^4=H#ORE_ +M*0>K[,L;Z_OVL8YXT+^_I!BDS)"A]8R=)C$#HPW9[!%AT8K$*`W/?%^($=7/ +M/-ZT&8!)T'',A*Z_B'#V'B]3DQ^DB%LP^Q@P=[K[VNN&\-&V'3QK#)OQF7R\ +MFB_T=B?K>K6-_0.T;6*KK4E4X#0C.>C4:EL'),%X?6]^.;BY*,:3(RVI;K0V +MI[FDQ7J;,?GN#^M[3F%'KBU\L#)1LG0X1[*W:)RE3#6CW,.?@//J)#2\"S.7 +M\V1XS`6JQ\L>$'K==I'+F\KS.N7_RHPC6R$*9!3;CI.^%Q=1UM%9F-Q?P-S> +M(&DQZ8'4\=.>PAJ9Y&'[81 +MBU!XS]NLQK6PEH;8R@A[%F-;+C15JNUH\4:WSVWW3D58ZQC'T*'*;JUU&XJ] +M#N=&QG:27'&21/0F)\3F"IFV').61IE7[!M*A;^'0B$[B$\*?;3:B4PT!,MM +MV]HA%3>-R?[A1Y@YT&.I$4SEF+:OI;\2-Z= +ML]CLQ!48G=#\+[HFA=8$Z`M'\!.(#Y[H%J!SPR$VV6OSF^<;N#%^;%&+/.9X +M<1/#3.YW.`TMZ^`)[L%G??@EE0P*+I1[JR1HX-+>6VK/.YF!JF1=*7EX2< +M&\7:DPEVSXTW??#PV/G7),\&,=;;=K]5#?].'AT6,RM<:`P/@U)IC%WH198Q +MC8S]Z`=Z<\:7=5](-56M?`RKAS^Z6_U>.S9=BA> +M)FZ)9&HQ^$]0W`M`C@`MH[9.[]RRC`@'1U3UI.T)PQ?1`T>:%K'RVC:S61OF +M96XXV.DU^PY,-S60)MG3"YC3OQ1/0^5!`.$YAEIHL@@R(=G'A:'QT<;8&&6B0)61_[4IJ!K'%5).TB*[WJ(['O&K_"$ +MP$-C#YE/FZP?AHLWGK#.ZO)7=WF;NSUC]+%,.U^W9IENONCJG0L,UFK*QS+I +M%S&LUI;]C3FAE2]T<$T!A,?%YRAGK\H[/*_Q)?;TJN)Q11Z^0ZXM@CO`,Q7B1->Q(S2S3NE6Q,$\^N-[]M +M1#Z^YM_X?!J&J"7*?,7LP:X$1;"MH6LVCJPR95[HKIT&G2N8VCU_J>[:,:=I +MJ#/6K>VTNSHABWO(Z7/Y-";,/35L^NXO69)D49Q#L]CE5QHC(,4+Q,T.9E6@ +M:5,#D!PM!]1[$]'\A\OH^![X>_)[X(P_1H3YA^>2:6T0BP#\<`OX=I&,1(?2 +ML7WQ4]NC\&D])_,[`,]4^F]_R_(,!I-!(`.QYJ5Y<\^:0[1&>5F:=3<86763 +M!N/,2PEV>JAC'AO9<=`8_-=]Z#%(C&5/W9CQ+BE0`- +M.9S0/H5)3M.4S:$9%/._OL]QH;?'^,3RS')<,<\?MF9[#C7.+@:5Z]ZEO,KR +ME&C4<'I%0M]O&,0GL[;V9P,XS?P2[@;&REA!(_8PSB01DFHU7")L([$DQ&<\`-5A(EH'/YZ& +M=,[$\]=\SCN#4*CN^;=T#K3V883?\TMN,R.2\4'>;]@ZS_72Y[?)_"W>'L7< +M6S9N9LKFPQX5>+Q[H."G=U6,'0O>D]RQTDUN/$"'[M9/W[T+`N8A!'?APTSB +MUX-PK>+,MGQ&37<+7?8)Z6O:AA4LBV5&3&998%K7DR'LO32L%#.]P:9?V-WN +M5F"FOXC?#\V_(()7\#XSU)[\7J,M%BE,%9#(/;5&H!5ML6(*M/+*UHXU]<#U(GFTE* +MIAIAV7%BBJF6EJ'QU#M"4C4X343C7D\K6(DS]"^KIX/PIJ;[N]&0_;AO"[MW +M1YGT_YZW*_/\5:_R +M@.?#1+X.-.[U4RU-((0^J_)?%17?S*GO@H5/`-LFI3L]0&&\"&M>> +MK3+DQ&F*>4+\=]-4F,H*JJJBEFR,^VJH-*J&VQ55U?=10H7!N*"'0$E,@8?D +M0<]8&>G6D=/Z?+9K_1DT?J-A(F!@1WXT)R4QD1AT^U7G946<)I]*P]2=QG[4 +M?J*3?,"%^*QR;#>]SV6%A?:S4VEMRJA.W1CV!+^`G?']ZBKBM1MXM7@4U,X7 +M^:-=#C%L<>8VH1\Y*&+2%M12J_`ALFD'S9_^S,=]FY3N?\74R_+_6+D#0K`- +MT996(1ZC!"&>_NE(M;>W#?"*WR<\F;P<:,$==RB8?65C6S-",BY")BF^G<*: +M^01=&:?=^"];C^^CO_V)=K"JHI^[6K87'QF7-<+]9E +MCXU-JIP89K=QN6ZV+HZJ_%\\^ZQ7M^RFI@CRYG!])\`F+C>`TK]HQSK*WYW_ +M>S(4V@?L.P5IF"2+BJF^D/-8"SE.1BXW,+[-XL."9%:OKI%"RDF>VR>>GEH; +MJ-?AXUC\+B)TS7N7IZ#^P-1^*8PYL\([&0QD6L0FR7W80IY-&(ZM/`O,#(,4 +M6$\C/6FHI[\5ZAU=1J\#V.K?;26[DZ>H3IZAJEA3*FI@(S%>X"@T/W6W\/55 +M`'U`*B3[R1_OYH+QC?'/MQM2M +MQ]E>Y&()C1, +M\JZ-O^KYF1&Y,L$N+Z-X3L\`PK+H\0ZT.LH>'D]K/._PL&MQ<:^N;K`\:%B# +MTD?I(+1L#TB/'3T_.P$4R3L[AY8GZWWZ50??!-3]]JQ`@BB;PX*,5L-A_:I(TIALLN=V?KPE63I3Z#68#WDT#*0 +M""I&=IDJE4$?6:_-4$-UWUDY +M*LR^RI'^7TO'-RPH'381J9M:5V>Z9<8O,$<U!QB!YP79`\>/!3-*Q(*#Z09/T@DE/A&J@HD#Z26L< +MOI9`2@,:;2Y+2P6<1@FE7QM7:*,N'"&"P:9@Y8N_>Y[!6`,1X6X5Z>`?TE3R +MY1ZJN(Y7N3UKJF)57>OWMAGD^E4O_?+VRJ+/(,4H!@;)1&PSZRR(6S4(/UPV +M;NN+-;=)77]FW +M85FS>;!F.S)_5")LW'2CW'RZ+IT="*+5:Z.N.'/D1=]'H;B2'AN<37AXKL+T*Z_9KOR7,/I=-+1_+?NCBO&6NVI^-ITR6QVBZC:97@K&2^6_JV +MF(2A@,"Q3<7%_SXJ]:P2%4H0:7CG#')";RDM,^?+9U3#21D':*7=*RJD5"M# +MDON*3<,;#HE^;A9%@<$+2BA7Q_=E_-IH9B+CM%)'22X<(N=-F[]F?L[WOYX^ +MO?%_!^NE$>+PX_@TQ)T?7#W1=_=&I%:&,*DV$-(EQ.[TY7,RU-I&A+".'68<*R6U[G4 +M:5"4/:5=4B@_RNQWM>EV[4%*:3QRUOC+JW@I=MUU#N,:Q'I/Q/FNY@-'+Q_8 +MR6*,8YE^C@U[.O5SL)H='FT^/@HDZ,USGWLF+\^GYGM-#M&W)Y/:@;7M)W/) +M\EH6.PR'"TEJ\TE>8J,\T6"*(0L`QD/,0Q@8XX1YB!HX""!C0XCK0TJ\ON9Y +M\5(R-SU;YR3\Q]Y$JLKBM(_QAL[!@JXPGA2V[E=JERN_#Q'E;N+I]?/:]@6% +MAA1K*L;7+:TJ/M^##4LS[3&8#C4S\$V'J/!ZMGJLQO%\LE/<^6:M2?+JHHA/ +M?6UBQM&TG,"'$F`@EJ)MH;$_K-Y9]34,[\_V#^#G9M7H$N;ZVK=M6JKM3YJO +M!K?P@3RYE3#I+LIJ?3:K9]?8+;UL&UG%32(SZRQ'VE7_&3LJO +M]_Q^4\@4UA'UVW>L;TP*ZNKJR\KZC3+J1_7%PT^@K>'[+8F1;+%/4TVS'*LPR@H4,,L,PQCU0 +M/[63`H)YB@X!.SR@X!/3S+F=\.DWUABBNIU7.WE`4%W[QV(N_'T>2R*0?+4Q +M7AB5@(3UN?\ND$VJ3-H[MZS.LJ_^_[P#2N+JU[UI>>.N%5@A&1?782V0H>K\ +M[?:VO.OZS7J>I.KO+/30Z83I#NT5"=,!G2T+(`J`&(Q`!`1\!Z3!,8)CB/GP +M>ERR"9^?CGUN?*E\M#JG.R/YK_^4Y6WWV[5I+[QQF6NE&L07E;V/:A-($MF3 +M9[U)?V,DI+">K(3JDLIZB;Z0;YC&2-\$D)54AWP[]5$12!1$8I#OC&3X0=^3UCUL4UC;:C\Y,UE'G^ +MKGAV>S_PO?Q#-AO2[I3XQ__(=FP6?24:T(+8Y8(?"E)E:J*2@E*6=HR<[Z]C +M@]B/I0EK2Q19]?G:7RMI;7WAKMKLMA/OU>)K<>WYZD26[Z5M"]ZLHGC[_'QA +MY7:SZEFD_7S'S/BHNK*)5\?HYVAT>?XGC^1T?'[?17R-3'[O%6R`^3"-A,1B +M<@[LR=,[IQ5(^<"AH0\X$D>>!\^M:)="><^[/J8.=0Z#OL[N-4'2UY7;2)_: +MXWALJV0D`I0N^IUIW;-EI104$;71QVZ.34/"R'/J]-R.!94"2UYVVQ:'*;-,?2HT"5(>+SNAT/%Y_/. +MAT?]W.^?^J1]UZM[%B/44&QH$D8PY^/$C$F!\9WZQ#2$,5$@;!G9:T9"'H39 +MKOQ&0F,`F0B#)GF6XS^?]^^^59,<^4OO!UJ+GN_??DI,1+/0$:84$A`C.(D1 +M])26$[,^I]H^]>UR>;S3FY:.:C<:>8.8YN8G-(C!!('(![D&665K,E#220ON +M20_(`]S,Q/<`Z.X=CHX6P?%YX#OPLAJZ;.JM\?K*C3FU3W90Z58.0*7O4S*Z +M155T:O9/+-$/7D:GH6,.,,=]\)BAB/$Q0$V)H`03H8Q,"$(3,W>!)44#WMY\ +MPS%\^N]-FR'8?,_6?XV?Q9];Y!YOK<>LX$LX,YI#3_JX_^6)E.0AADV+C"-QT$ +M%OWF[P_3;0AL^+S. +M=[:MM[;<\+(K+6K*+53L[0$DDF"TP)`-@!B1233`1DS(LTG!14X(:=(L:SD( +M?@UOHG!'#1X":+-3?:_.8/5R>NIH3FM`CZB0R)--34;-"M#8X'!P;VV:R*A>@297S%1F!T4'F^"[C#R7W67;^\U\' +M^[_&=_]I^A_Y_V]G\WYW,SL^'@^=X;_VY:*BAKEEV03E0E2G3.#4C"$0E>0, +M30/,:/;UH-49*'B6CQ2E4F20;0]DL[:VW>VK1R6_?W-S[#_/K?@^1G?1T/MS +M0S_QO4S]@RJK+GZ)G,UK-3,BS@EJRM*'882TFTE(@R`[,A,%10AT/2FJI"F?9,_R_V!^Z-#SNU;^#[K*^)]E(N7B_X\"\7AKI +M>82&+PD-:S**:$.T*I8A3M&[;"(UCBA$AMQX`-%K+87$T/4R=]RCY-9A8W-( +MV^C..RYZNN43Z_P9HFJ+V?9B/@.SCG)X\.08E!R62-2,+,%`'GS_*R<]J(99 +M5*A0+D(SQ9AXU/5]5/6/'W_F?+_*_TN?]OKD/Q>E9SXWKBYL'9@O(/UG[ +MWJZS:-JYH.%LR6[0K;F>]M"4>.@]H?'X]:-9B&EO'K0&#!-`'Q%/#!P:VQ;: +MU;!%NVXY;A;A`M'@J%U;]^^7;PK8@5ZZG +M"\$"XBXAQKS`D$$Y6IZ+9L$(`BI4\H>5HI/+W';YO;_5GZWU]SXGW3IM6BV. +MA+X7,+JEAM>S%,+T#>J\ZJ(6`&"(K)#8DET*5D*EJHN@)@S%6'@LB<=Q-CV< +M9O[_\C?^M_@]A_DD(;W^'EX/3+=NWAJZ:LEE#52R+F9JHB!D!F(1@,51DF89 +ML*4$"@6`YE.:"0H0,O7,O7];OGP^Q8AN]3\DG.665-)DER23*"":#"&F=W:6 +M9IG=,.S$%E)MQ'@B:@RUC@!P'4AA4+A/#.@PY,3.+'!G,A`X:)Z.W1_:R?6^ +M/A^B.\.YAZ6&S245550/%G+'Q&.O$\XYQ)XEU?'UB!H#Q892FQ!*HA:#25(9 +M994J;^4XS)JIQYZ.[I/-JU>;L>F&3\;\3?7YKKQ/+U![MXNW++%PMW&>Y`0D +M)!<&=!:@SS41IV+0#L`+%).I(,0FD>P2LLV.>71:6I^AJB_![$F:+J]7:CDC +MD(H1R00.!([C.,))),&Y&J:!W`[H##+%<-UE,IC[EFM0$VI+"P:DPIG1@^T^ +MJ\=R.WL7$;"'!Y%$.I"*1VDGA_`?SFLUFSPKM3T-FD*@H;(4RA(;,#9 +M84BR%2,8I#9BJ39V:H*ZLX=DV=7PML>]_*YO1[1MF_A-S?Q*)B"K,8.+02B& +M+`&&*2HPE28I!I#%PQ5%](ZVBX7T3W#7WT^O^G^57L:].E*HY]O/ESNWFC'GS(RH<1H38!0$U`:8$I@FD<&=F+A5A,@8K1,AV+1%0AP:`Z%,#S +M7Y^ILH2HZB]QP^'\CR^]DEEDRS#K*G>>>=W=)IB8.`L,+P%FS,%X)$02/!R$ +MWE,PDTS2J9H;%81BG6OS=[?HW_.ZVK_6_\^O^5N^'=N]E];=WGV%>O":[2CR +M%>[=N)VAVE4O:">50F![4.-0:UA2NA[2(\C)'E[=9VGSK+#R'D\??]#P]_A] +M<0JB;8[=1FW!2;<@]5H#;(BC(;9%),=)CVZ`6>[MTNDZQ:*-%\0ZV3!?KOL' +MA[511Q6)&D,W1N#<;@I-U!1&W`=R153,4)B,SMC)3"D[-V9MUV'I]C[;[GN[ +M>GU_#AY'1FM:RCIZ;,/7Z8]>RI.D=`TA$"=*!0$2'3`DI3EC"=(=,Y4A@69E +M#;-S*80X(0ROV,]T@I0%F>8A\4^/['C\?UWQOOA\TX3J^=[GFR\<1XR]JS/' +MX\#Q^,\9XPU/V?C1R#QK3*2%B2S(:IJ2A)0"PU!JRF@\/9[>YMG5V?0*.J=4 +M39LU):+$9U06*;+5JD+2'50*!"&R0LBQHJ`5#9#9.(VN'A-.K5Y/KNYZ_Q#B +M_2?*]ST]I],XG&X''3@8\`<4XV;,30IQ6XXG&<4I]_,B!T''#%X\L +MG8-%#, +M:@?M$*-XN\"MX5O-V_?1ORW-JC[>'CO?28:=GOTWRNGVCZ6'T/5_#'R#L]CU?-/0:=QXG=F9NL@S=E@1 +MNS*#!;=@;A"J0P'=A@.)MW;C=J/B;MQN\7Z'T;SD-LW-L]_[C-@))YLF/+A$ +M*IREZ2D8B9A)(&I9AY`PD>:ERQ.99''2<9V!SN9AT'/P5R-\S9I9M2_$2)F% +MK(&1?4HI94AB6M(]\FDFA`F8UF.Q`B.!(PL0)P#=..L`X-$H::99XXTPE*3% +MZ_1J4G7U*L'=>UP8.N<%JBIBJ:A4.J'4/%"8#D)L@,I@I`Y#J=1J$*`2H"BA +MWH>!0034$RG)YY\M&KAK82(B%$6[DD,PW1%!NC]%%$=QV=D9G9J.S69V)V02G +ML&8)V`'7&0.)%I`-B7T6M*L+IOIT\^[W<,*VC:-J;2S:-H-DE#0GA$I\,F$# +M@>&$PDJE?CU[.SQ:K_3W^K\7)9[^SLFRK(6=NFI% +M44,I,D!@9-"LA1!9,F%,A02DPE\04AS&(.>S6/,\3WYZ.'?]C^5ZNF/>ZNH[ +MO27P1=YV=C2=G9F8TT=@/7AB!@!V9@&(TP10GL#[$=CAWSE[!EHVY>?WN_M\ +MW[?HHI34SO0]`4!0[NT[!0AJ&9D@*&`2!J&)T,)4.BB>=(WM +MC"074X>#'P1UU%%%?C:-1D<84FU`B#9`[5:VP$@;8)R"MI''?@)G:33:27@E +M,V*PF':/:[7F'5-_?V+$S[CS\.!Y_B5QQN/"XV&5)Q7A. +MR'B)PCC:8#H1JD8B,P324)QJ@Z*'C<>.LM;?Z'K'9[_/HT:+F*7:I#$PPHQM +M:J7"JA6%J,4(=63B/7!Z\]$;"I=B4]<&69@F`QG)TP5S2KK2R"LY2)6MK(?5 +M_`^%>EEM)I`DM(BE4JU!@&\[)#?&R'!**!6(7>"1B<8K`)DS2!+*[I,X26I2 +M5\`1YD2/U+>\<9=TWS;XLP-#H=`:`T(H"30P*40E%TFBIT2!@FNC,M5`8!9A +MG98Y=F7EA@THPCC2+I<-N]-BFVR;S_!W35*2B_1?TPI*54D.U"(XWB?$63B> +M*;,4P79(85`&(9#5!4BM!V(#4U.R9W03U4E)=IH[L_8KV+$5?%&8B!M#;Z^W +M&-N&+B-#M!:3:!6V*`(0D@SW42(V=KHDT1BED5V]!Y9I;LO%K<&_RX<.'-BS +M7;A=OJO-Z#ROC\KY4P"E\H^2!\MJ!Q/+)080F+,)L"O+EF$'EC3E'E\KY#T= +MN9XO%\O^/EC[IEUY"6/3FU-6,9HV&2`C9@2",8C3,($(-4&@N8'$>7L[7QO@ +M_!,WT,PS.JKF%06/H5*51(;,$8L1`L0ALDV4A20J.=0&;5JA0YT[66YGT8_> +M>UOF]OX8"WQ,;8VCB@ABLK9B'6E!U%UFL`-*Z)"=1T]4#MO"?O]S-KZNOB>FJFI%105"35`5#,Z!U0,B3*JIA%("`LG`JAP91][FYRW+N]PJ&R/W?N7?ZURY[OO79['RH._;M-M-=^6$;B(W.Z('=F#@!NS!,$HW5& +M29FW6C=`6XV?)WWHST7HS@=]&7.0YR'?W?#^IWO1M'+M7,=TLU6K>\D0$BV[ +MN6RVG3.>.D]KQZT&*Y!H#4^.1E/'!E11@!;3""TK:<=EC+@0>FYM4[NWL<(D +M19(H\.31EHPW&49CB[LQ<4H=PKN1R-VL!V2$FD2"0C"/$^.52CUL9R +M[\K\,_6V?8_A>7O;V"S9JWH6L].DJ.FDTR:4C!RHI-(&ED$!=A"4,"@AI0I) +M41%)IFEJJB+F<>>FDK/O>KZ?XO9YSW._.PW[]V[:;C=6Z"MSNB$-UNLD)"W8 +M@Z&D<2C<5N*=V;MV[N+=N[[W#O\_VWU?>UM8GIN[\**A5((D544,E0P]#IFH +M3"$:"!V8H#("S$<4Y60YPUF$$5'(Y&XWW:M^4XNL;'6S38,2DCEDDP2X1Y@4 +MT$TR$,3`),PTJE`G`:2DWA54[^&_/: +MM6IRW&_VN'M7O9GO\MG+T_8^GS\F_LH[#KZNO'*,&"NO,#$ZX**`E.N,D<%R +M7J'KDEZ]=.!U7P&CKT;5O9ZZ-$]/U]?P]8O2<1=DT[UYDB<=VG@B<0F2)F%) +MQAD*WYB&"4<;(,`B.)7;QCB4+65+TE_4LC\'A]SI7C(\=C1B'B,Z#Q$0T2<0 +M:#,R3J"%>P"D*0[$J@["*@[-=G1I"KZ)?1QUTFHTXZ#&[>U2K4 +M5+X5)0*"DPD610+`7O04142I=ED*+E8E#A=J] +M%WM%5O*&\19L4J@:0W4FV+,B1P3LW80&62XD1HD'=/&\CH)&DP/>O]G?J]?3 +M.#M12J5WE4I(T$ +MO+9Q=_:DX)!0;HJ<7/B=Z7SJ$J!S$4I@1R`.8%`IEX*;$:45@PQ1HVL]EAM%ITE+MC)'$*:-LA(I! +M&$8J[@\<5:Q'A>0>&O'N'F:NJ2;UV]J6DIQ5^J9(M..,C:.*-1NXY&$8Q2;5VSDY#`4+0F +MU`VP$!V"2C:VA*,MRJ.0P+=VL1W.6V1S3#S2RRJ4E4J3L*44YF.^2#?8VZ34 +M4++0IO"ET--.\WY8;H,WQ&ZV:]K*+A=![A[GCW?H.X][?>7K+MRXL,2XQ27( +MI%"%X"S%"Y%`4H0$)A>(+-P,>IJV^+7PGNGI]WDT7Y#DU<0\1Y3><.#OUAPW +M[*.`.`7#!]B5P%RR0Q8F3,E,X"9Y(3#JZ.IT(U\E*>Q`""`0,ZL/7.EB1?.EPYN+E+N_?[=Z]=)&E=Y +M;LG!X!PF#?OA#A++5)9B2IOA.`-2;\ZRQ0X3A/2[7A[S[>[X^4W>7><9BF+4 +M*Q#:MA:K$ZHZNO#0FO!K2NA"ET]5UR%`0U#&6F-<5!Q:#I$Z=WR^#OZL,W3A +M>Y>]ZHPJ@L799DHEV2#)%4;T>YR=RO/K0:S;ZVX< +M/%A2XTN.*8T&&-+#B=<9+@-'39`/6!J,@ZR$^U,S!:$H92D-0TLE'L!Z +MQ>MAJU)H(GUHD*%]8;9A\>U(&"GK#]F'K7K?:>MF9LQS#CQFPDEB.SAQ=KN; +MG%:M;F6Y;MA;II*6HH=J0$F'8I=V'&&*6!T,%*I!TU%-%-%#VF@$*JLK(JX> +MWR=B68FPSF&4$)*4G@Y,$PD$KIQD!,[H09`P$0+P1VPO`'@[,,.#T.\X%;22 +M7J[F%^0V_*E+$A'(6[DI+,TR221+,FE0$PR3$TP!2;YV0ZAQ#A-#&RM_#,R# +MR<=W#P[W6Y.R8F[C>L+LNWBW-QN1$EV,(WJ`A%D-@A>&+3>FE"]38*B51@'! +MCP8+PZ/#V.]YVOU>3DQ;>9[-ZBFJF#JH2*G14DJL^`[-4[L5)F@TR01L,819 +M"DC)E5`B!9(6)E64&$!`J80@NWK5IK0M;6N'%FB]MHM?B?I5])AW=QM&8>KI +MP<0H0^R"BCJ"Z>AUU9!J;/7^3TFP[AXCU.][7LNG2XUS&6C/&KV-CIS:O'[7'R<$\'!6OO^IISSZAQ +M]=R3(TLV(4AF&8"A,LZC+KV<0-@&0%`0>S,>SD'H[\##9KQZPU.KTLWIU:N] +MO[VO=Q*;IHN8J"PN!BA+)+DLP62)%-BJEF2\4QO+U11>]ZKJ8%SBUE^V>CV^ +MO?%QV\<>O2I4O30,<;V$)/.)"S")%DNQ:8%03:HC%+MS%P/1-M];GU\_N?=O +MI?)[?+]N.GEZ3@/!EGEV3,SS0SI,Z0I4S'IRST^]/5R\WAZ?2WC#6G5O,;I,1;-K0HA=NEF%D$A9DB!YU4I* +M%A<,871V+6O>[YV/%K^&?/_'[^G/+`PF$<4*(F-1),80Q0$`PM03%DL%("D2 +M8CAMEDW*J8XY<"Y2]]'9[7E^Y]S@WNX]SSAY_E<3E%RM-N\/3Y>I8-+1TC2$C11I#LD-I)+IM2FE>HLE3`(NDFD +MDHI.ANDH3!:VZW-O2,CM7<[?O=WE\L\E^SK;INO4561:]H. +M--.K5*SU1-0B:5`U*$4U)$FG502U.,(&@F$R06W1;M,ZP-KW,2(/6850&20<6RY'+9OX% +MW\.[._O*39R]/(9.UYOKU&GO;.S/+.\Z<<@E.)A,$Z9(81"R'&$9#C+D&)OB +M/?LGB\BX]%=V'9 +MDA)IYT(E,I)+,^7?Y>2[VXRN:1L5_=S6:?-GL9V-LS9&P'LF0NLUFA.Q#80& +M1*`NAH2%$4-"6==]!KW9T;V]T6X^@[AXGA-/3;3=V/7M=VLPW6X#H1W9C0%! +MB[BS=FY=34ZG4-4LX5EGIJLC-3,, +MZI2I)FD9#-(1A'@SL2E#.G'=#50(/!D69Z<.&K!O:I:Y)Y8XT16(E@>.-HU# +MMU@8.W;CJ-2]$CB)L@90VPP;5&F<3)\`21R.\F"(\/L6-B+>NO%92C(FC0B- +M((FZMNI=ILP3%-L(2!2&V!A?!F68B8TG=HV2(V49''H&1HZM:6S[SYE_!EQ9 +MB\KVQ*TJ!22N6(;Y,C!-X1OEP`S,6AR&@88)20)22,5C8BZ]:O>KV+%LM +MW'N$5B)E!X*P,Q8$ZO8]CLV"FAU(RQ;'LUFK3V9KQ^38;KQ^2.'!>[W_-\KI +MW[F.Z,N7#07`T--:**)*A-"+`$#&J4"F1DO12E!L-F:#`QNZ+%%]C1K5L^!B +M.38WEZ_ON]Z/GO/ZG:S;FYL[ES*9+H[O=+MVZ@97+KH,'QR0ODO+(4LIY81A +MU&&8$4>5"9U=:RPKCJU;M]-]DW;TDLFL9IL>:AZTY.MBB`XZH;D\GE$W)Y1` +M3R6!*Y%;7I=3KWJY=(BS:%(6;1-*TS5G9PD4Q +M!5H,X;))3?(4,!NM^8#(4#2&+OG$2J`SDC8732P@^&3"_%-Q=[W$]<.D:)HM +MHH0:+,:)*R'3(9#B'3"$O2GM)TDW5F=/KGAZ?:T'PZ6[BR9-6HJ:J-Q$1%&X +M[$97K0:`"591IDS1K*@<1VUF/L2AH#XL?%@,#;09S#=""NTBYKJ-Z:V"MPQ& +M]O6]0L11#Q(2NMHM$D$:9$8&ZD4!@*!NDEV$$#=9NL*8D-TW1&;NDOEUST=> +MX;2FV[4V6SM(J6VD&*;0&T)3(5`#902;(@A6U0L-FIM*;4KK:LY]&A$M[M9. +MQU/6Z??\GP>AEWZ>79M6K]J^)%M[5M-2BV-;9.G":8A%!A-40+,*"=29I$>I +M1J.!S-1J-<=8-A;'?-3NYI8S(5Y(FBC=AVC0FC`KI(83,[9R3HDU#"[0S$`P +M=GD)C?/`<)WQB/ +M`E"`T30,!P(,G@F:#.[RIB#30K.#LE-=N2%R@GVJ?7W\9TM)%P\?2'0=2'5& +MR-0Z'J"&1V0E)#U&8N2P@TDYI#FD8:XA>/O^Z]YV>3O[&S@X2XKUV%X=%UY& +MEEK6H-6\B"MY$AO@LUOV!L##AT7ICM?-K +MJ0()SBPWRK"C?/`4%_S-2FE3$LSN[*4F@F:-3(0VL*-D;5=Q`=&L4-">`LER +M$@=\P*5#(E2$I3`387=R,DCDPMYO&W7.P98R3+>DD16XRK<;G=MQU.D-T&2X +MH4[(6`(02$2DA)6@[OW)'7"OI.]<"#U=>)#C-($-' +MQH!A>N:2E)-%)W*Z"%=W:"1!(M6[<Y#DG.'+6LUNN4ZU02"ZXBJ"CY@FC+S0Z$,)-0Y+`'FD)\V92FLUJ<.OL' +MGZ\O;W>,\7:[FY?$QQQIF`LQIH2&*,2#)Z#%BA$)3),8&*.PF)CA,3`R6!TG +M?6T\AC@NW,Y>2X\^9AF6%+R +M8"$YSSD.4II71%`LO.B6'EG1HV0;-5S/0'EO0>^?H^]N]OHY./T=\IPQ2Z71 +M,=BB\ED278%"2B1$)C)<8L(R&-5+B4R47"_43CJY3=8'OZV;'P][T?4]3V-[ +M?T\<^/&U.)Z1ZG!-4#U.PBH"IE(P,A@)#)%)3(5"9"(U14C,N"IE:THR%4[O +M@^%VL=''HQ,3%QQQG->K72T+K5AL4+:`WIH:`2%UC)&!=A%(D+HI!`NA25+H +MP2]`\VM->LX=?I^GX?:Z.CWO[V;OT]+;-G%CVML@/=K.[7;;%UU=>Z7;HURZ +M"2'=V+KXX!Y925\L'VLC`%+28/EK,*P+B=0NU@NM=%L[5O3O*Z=;COKDS=VXAQJI@>)-`P(;UXYB&+Q>)QH]^"8G((U#9U#'U>M%BCQ0>*.,2L!%$XXS. +MS$43.DDPR8&<&$$-`D2*:$B;DT=GLF'P^/#V/,?<##`<,\7$QF>/4L6ES8D+ +ME502ZL(D"XJ0$A+@6$R$]F%@B51&T:(JI.KK]O\[S?>[GO:V;=TZJ=RBEJ6I +MH#EPUSV#L4YP%+*=%1$#('T^Q[ +M[T3;-AF*N:JD#/1`R`RF2Y5*A41F0Q@*"PR@+UTDR(4,4`23@.YG0AT63,TN +M?K<_1US]__O?7[5KXW/2-$T:)?1!00#0*D$DT(BB`P*ZB2(.SH9!$-62KQ.A +M%@Y%CBWCN8ML_E%KM]HY/T7RS/5YO5SN8#F_.W<):X:SVNYQ']XYEOO]4[-K8M54U,J2@*$U+` +M[)W&*44ZS"@)3G$0)"SQ\9Q>E^/II>3'&-DCTW1 +M*2A*DTJ$U9$H[EWQ2$`6_'(`P4W5OL6MELM!6R.XY#'D%,1[6/3VIINM\'M5 +M_PSSO<9#U=,T[74JM<\M-:69T)O&'M>T.>UEK,B!,CVB$H2!*4>:%I#(!U:+ +M6FF?4+E8S0<@)75;3U/4X>=UBH\&>?!DY=O/(>O#@!F3*`,F#"<" +M*!P6HI(%B!DL6,A$DL'`!E5%&67`=O-[QWN?7Z=[P_;'^MUR>?J4ST\F["BR +MZJ*K)G)&JK3LK36F23)K0!>T>UFM0L)HD-D!@'M&S$P/:G),]I&:1TG`?\B_ +M#?AG?^)NUO&]NM;SO;"7EZ2]Z2E%Q"7&"D$DO54R*`P+F#0*1DJ#N5Q)J]^Q +M=MG>][H'9Y9HIGZQ8W(BU%;MRRC2LTHA,2DDANB(20W;\I&`RI"6\>'`Q-I? +M%G)X(2XTA(*6_N;9M'5ZF_A]+V7O7Y9>;(T1&A$9&-'$XSC1IEE#1$04%*0O8 +M42$.V2VE$3*)U&W34FOP%92S;$^*CZ7USR.O\/L[7?T-G0VGWQ<4,HFI%@D.(03B8AQ4TJ'$CPTG8.QPZ?C?E3Z +M_ZDNSY_NFT]W;V.LVEM3LVA=ED&MJ[&0A=I020#M*)2E@=M[$N;8C069M#Y& +M2>.+36,\SX7F:_K=7R]AZ_JUO>OW.(ZGJ\5;X6Y#F&VC*9S(ZDT,H4F_O`-]V11)-$9`9"XBA$DT#'0,.6"P6$E8;>-D7)ZLG!*?5 +M^ELEGW?Z8K?[\_ZG#!<4%]QMYOX/1[//Q>0UTZYQ=R+PZ]8:Y#7$@L!8)#7$ +M#4&*^:(BD(1\R^;Y.:\&!I-AGF\W=LSY/G7'R6S!/*R]48IY8@A(3R20'ELC@9L;FX- +MP@QBH."A#CA!P2@1<)"RASENG2ON,!Q^AC(3W8&4A)^C//5EF,7M?:O/[LA\'@X.PFE2)=^932\V8'9E,Z9/F$?'D@#@Q10[)3%=Q&0F +M(%!,)G0.$Q,!O%A1R2%.WV.WER_47+!Q,BB>1WGH>>M8<]G/[CT'V_MF?/_4_OOW +M-]?/IY;MWR'>;]YO@S`WVYH#%=VLP8)`MV4TY(&#^/.ZU#O#1OMYM=>_PK>3 +M9%V3WZJF/M38F1(&9F/(PT6K9 +M)B&^Z(AY&N,4)$*U:?L^8N9O]R[Q=?M<>UMP16(GW6>/64 +MD<4@%4RNZAIDD:-U5&Z,7"6`D@FL($TC.[B3<+1+6#64%8DUMZ7XWRN/ZAC_ +M$K<_P_4^SSGYO.SNO]-?`Y_0_2^S[[P:]YB_>:^=&Z%Y)7B\RO.DF9KB$DDP +M23AMQ!9CR4=2T*).H(`S64AQ37SO/SEG`N=WSVOP_R?E_,A?SOZ?TK3\S.K5 +MN9S.IZONKO`6^FBU::S9W!QVM%2;2V&B66`78(Y,"I`J(Q",CG0B9`64BET6 +M0LJH[9NEE[6;=?=6X=KZ'T^]_M\D]SUU6K>A>YF;WOK=IWYS>)\;>P>,K^ZV +M&_@;!A@-?AA0L,`%A3NS&%DWF@<0\]LUK12,)L)/^F<3O)([I[PPG*`!@XF< +MS1Z>;9,S80K*?Y?)8UO+]U$RJ:+E(3(>8J-34IAI2DT,QYI/-#2"9)#H@,L0 +M/$5XLR3KG$#X\)L_#L`$,%E`BR9\'++.GLAN)6FS=Z7TZJH?SOW'X7S?Q=WY +MSZ&A^9\W._7_CZ-;@YU;0S_O?D^)H>=P8/.;"8,`L`Q@#!:08`>"9BZ24A`U +MTRLAY6"?)%Y/+!Y?T?J^Z/5W9]S_&][DY?]O=M7.'YGC^+^)E)20T:)#MCUO +MD9*T<3I%Q<0XPH1N0C*3T2![:VHQ3VX38&;,]NT)D21('MQ1[>&4TDJY,FJ/->7D7W>;F^B\BOE>`<[A7LU:R[O3-Z-%FD!O#F#3?N4DWL +M0JZ`^J,SUO&)79@XJKDY*SC%!R<`Y.0/'9#C(=6"*,`XT4C).L"*?BF%=#25 +MMB+=S30?'OM3BO?&;,H21HTG? +M$1G,@XF%HZ1I^-,Z!U/68=XP^[!V,:9I*W[I17!U1X9;3JN9'Y+:%\/\R_HO +M6V(0SNAT.9G\_Q.=@PX7\3R/6.)L38C2383$R98G0"1B=#RG?+1DAB!WQ7?+ +MDC"&40R.9@1@H/@]3ZC[2E]54!ZE]50DC[_JS/PMFE1(48;;30PGE%%"=?@PM +MU%@L!DIJQ3WL457XVUUGV:DI])L.PU&12:I2OU)R>OT8WI4YZ1=G=X?9LDO: +MWJXXS#_;.O,:18>$*LMKB:##2S,:RLLZ$*3>R;?HYGMT:O[+;^!_$?@?.!@SLME +ME:CC/#<\M9AQXQAYCX7:BS?J7/[1,R^P0"7P3.74$F&AU.\M<_P/=&PX\V%` +MYY56;R<0JMXU;+X)%QH94;'PCA4ZRJ:V2P5]$RQ+`IL3E`LS9L7K'E,KM/E`XYY"\H\IOA +MI^$'X:\D`9.14$2A\,I(_>990,0$H86IP.,>YZCSRJ@E!E"A1M%#GH,P^<]- +M]^NQN\BMKF>GUEI]YOD86)25S9RJK%S]]QZ^\8/S(SZ;%)?18KRVTJ21A4V+ +MJ3/#.64OG;6!D9T3FW,AP\(L/3.FJNF +MQT_&882=#.R$;SM@)JU/XF.+LAP&^<&?5C']/!]`Q]5F/S_G^%;U2"//6FI= +M#TBXF\S%[9UTQCN>U*0A;_R9^71"DS$SD(<(DJ53_YF7O6*VNVWO64NMAL!X +M[:+60#:TH#[7UD>;K'@-RZLKRVA95MR:E^+S+,X$KM=,&=SQXV3'#Q#-MIG7$GW'@F@NLF<8WD&RX/!SK\IJ'WWP.8+S>P9G'0[LLWQ<]GA"YO)2,B@T5E";(XDXC@^W\"ZA4= +M_*FR5:S3UC)*'N@U5%T6]*Y/H#%Z,:I+C`SKBVRJ3$P\)5R4Y`[-Y;&40[&2 +M`Y>18#,NMB6,=V)9:&IN;$BRP!I6&`^=GE\?C/5\1X8=92'B62>PB,1!).YX +M*+,I4D80\]@@HA$D\#3*$9X/!/D8>'U_#ZGK^`G]MFI/PH]O1J*!E8>]MY7< +M^;?2L5JM%M$` +MUIEBVI5O;M'1<5M*DADH\GW+-6Q)65H:EL-+HE=FI?6`Y+OSQ[';Z_/S^][W +MO>3+M^,^K[)PP\3Y)-;Y!&/DZA`5&**+!)/(J)^QK]8DM`\"##V5#V3OD\IY +M?9]XXS9IBCHB/]AFKP>(]T-C#(>-V=_#^R6#U0QGO,XY7L:NK\>A2[;]5]LY +MK'%L-3RJD,OVP]$N+0/SYS)F6C[+_<;F)F56U)--:PZ34&O-:^WN#>QI,TNH +MW=68'!J:41\,+EQ=GR>3C\?C\6Z3PU7AW=@GL69&54HD\"(BD8$?G8?/B8*$ +MA;,^59#`8_//G:_WOH?0=G#Y_Y7SC]KF%:V!J#N#%!M6^I$,=U-[MJP_ZS)S +M;=M'2=Z(^+3P$_<&ZNP/4&\5F^)F<5]TY9Y\;!*(4T*9*F^O1,OO01REU(M; +MGD$-I4@P?"BC3T*HJ(QDE==T*6GF4_@+[&TL"H_Z9NG"=CD4S?1)Y0QWQ?$:2NUZA0+'[Q +M2WE,5H[QJ-SV#H0KK1I(_!U>5\PC6JA;Z:NONJ@HCNL31S5E.VK//!>S43^^ +MR:G/V=^_ENZ.YXVV48/&K_>GP^B&AKU=?L[:#L]ANR;-9,=E*6^['Q`!3SWS +M*/FJI!`*9OI0L(OF&#-@^<>[)W]R*"%.-(VF@DS6!X'OZ:_W%KHAB:OA969S +M43C,9<4%@/VOPR9?>0.73_BPZJ<*RU'6/5:.F6N`O^-2-5.QYYEKO0*M\U):WF"?[[.^=I&L+ZP)EMG? +MLWAK<7Q7#4M1#$_C^$CLMGO,T%^!SOL]Z3I_4WL._N^-9D-?>U]K`W[?ZQT] +MDN7/(/Y/N3TDN%JU@(>@_F'H+5@?-^L?5UAB'WTS40A]68AOWN9!3(E2-T1` +M1!"I!HN\!%(-D&,\/$&(C^O$&MD/M\4'X3XG_16SOGH`=);1T?75?BY]_:6& +M+FT%^Z7W?9-_TK0D!];^AB(/R$=CHKZG26/T]%JW+P:6,Y;4V!Z9H".;EJ:?'Z((@VO%,U>X;6FAG:!56R'M;Z-1.7$=[KMNMM?QEYO]G +M.23COHYBZ8K$`\0'9#&B?I%>6P.^/OR^;@&6D7/T631$10L+]]'U/O=:#IC! +M?D=&!F&5[MEY(Q-@_4_A,^'9L#'\/9GT#][F4@2E(Q^+B#_N+0>),Y^3&RNR +MTEOQ!36APMM+HG37+@P^']\4WP-Q\M3*\%<:K60_' +MX&92+LOS&'>.-V;AT>LW.$9O,.=#??D*RGB_/JMQLG+2YH[&A,/>+7Y1,[M9\0-6^1R +M=\<18SVQ_.37F&$E#9OEL-/`!-=-9Y@^,BLSX6C4\8*6:F5]6+LNCM*+4O5+ +M-!1;X2L+,S([83MX-/ORULE>KRMN+@'R;*MM*JM2LK,B%H1B,=K-(D".BJJ" +MA`2D2E"*D%D9"(A&)`60(L)!@?+3\:C_%6+*[-!@2?&)#(^/!$9!A^0_^-_+ +M)^0EM+4\/&_6S!O;;[7!WNN!>*/;%10]_#V'\1AW2D5J,2S/.;^=,.1A"W2E/8#J +MU<+M<9^A7F3E:$+HXG7J9#2=3J0LK^'$6[*5[%\W_37+S4\TGP7=4;)Q2G!4 +M[H:@D;6!MZYW)/:/N.CKS'X^3<0OU/H=FT.E(=!X[36&2D71[KW@7KJ!/U,/ +MH%%!+43UF'D/=5]8QF:7PH%;RM<'V#K5RA:>6RZ&MBF"J/QNAT-7CIJN.@+8 +MP=DP8+AH8QF@,[57.7F?R/@6)BSPX?I/TVCX:0^]:H_.0/Y=4444"?EIA9?# +M!0$>(R(;J?H[?SS5'0VKOH-CZ$=;4H^*? +M"[MQL#Y9)--Y>*2_R6J21P'OI\#!W_AUJ;7-<5<'2A +M'99R]BXQ^PX;JA;M@*[+''S>!!B('((BA"E*-OZ4`/"X>AI(>M@8]3^9B(3[-?IA(ILD?>:: +MBTU0QTOE3ACA<3-X]WG,T5@84>:!41KR]1H:A"[/B65Y]) +MYA?BS'ZZ!*JD_6R!@CRB#]=GZ_64C/QHJE_SIUX,\%&K']I^PPT'V1)?"QHS +M#6\-%HC11X$-"RLRD7S?.M(?;XF)Q?`@J0L[?4H)>P4FM]7.)WW$*03=!N;& +MH.\SF62KS\5R.\L&6GG1U2KT2?6A-EFIS>HXVO@KWIM+?5&1G;MA.3_ +MKK%.P8PT^S^^"U[O&\.`D@WRQS]Y.Y_3UPXZY"JV1HU+Z;XL/K%_K81C&^KM +M\(-\_\W[Y[A->IF?X*G[C>^P;B(`D\?#86,8L_49PPR4+W<.:RTM!Y"0W;^Z +MKJH?`TSS%NUNX[G$G8@9]G%^K5&4?Y*&PJZ>EQ-9.:JIZ).3QYJ1\^6+2BI6 +MR8A1O)[5D`J)QBK":D8BB&;;H497&3G-9!2MVQFLA<:ZRD9Z/#[9/F.NUAI= +M89JD73,B4>S6E>H%***JG9%]R,!&9-J,=6Y'-`N4G,9P;GNT,5EE!H9$\6=! +M@8OHY^,+^4U1NE#\H*D)$_*JJ_)S*OU__5FF)R[;$3;2&CVW.UE97,#'JXX0 +M:D!6!PV9,;SR]F,&1WFK[,5,Q!C*.JEX1\BQ-W%K2XV5%2^+"]UE\5?Q@.1R +M7AMH?+G?LX#[#Z'RTG\Y0?6>!L?/1S:AJVAK[W^Q_W8&8:AU#:1JD;&=U6=C +M]^8.L[WM?U=@^VZVWMVF9?[([7+#0RR&(-.A'PY/B1LUK?C'+O]+\MS;UC$\ +MC"P9J'55NY$"%/R:-]XIA6)N+#[E\H9VKW/6S,YXQ_YC29"^>*,X:5N1)R?H.=D99V8:*BQ +M&1X$BSEJSC08#0^O&/7UFON42L(?^ESRY6[E)<; +MQ`\22F?CL?53^ZCZ@4VF8EL-DG.+=:F[8A1FIMB?=9J:CJ948&DL5H:."K'9 +MA?"TKWG8@*98\D%\HV?6ZT@%=RLFC/,<5;F9+7.G:CU"KM6>7+(+6.+J--FN +M@:'6[%W`7TT'LV>XUX!XXM9>2Z8I\^"&R5MG;H#^S*"E/Y_\S]9\0V3$`?&C +M]A\M-F@P1TWGD<$]:/RZB*G_LP,@_-_8I^QUAL_5;#7[+#_/VPPX1NCM;^O. +M./FQFA`\C#(/L[G<'I1^WV>P.U?--D5VQYJ!.G_:CNPOP9QHQ?Z!O[+S<%@W +MSR_\K>C>BD21,8<73+]&G9[W>>H+OXPP6'5H,!XQ.TEVW68%@LB9N.`*G'/7 +M',''2,O[HH]LOF3>YUE+>,4SG$!C!M@`J3*TP>F,WZU@5HT2UX#`7+OD%%1S +MGM&G3OJP4F[?#(MN]=GU#"V37 +M>@Y^KD/)A\V6ZC/;7N3@5FZY+/UQ]9M$D1>Z!/`HACQH),ZXT.GQE?`%M&)6*Q +MGB[K)O(/[7^B/1+>'\ORT(FI(X15F$)FJ&7ETPM:O`3(F[C7',=(OA4TU7O5 +M3A9E46C7^0UM%K\P+^V>[!MG*II`;MC^28+)M&_[LU[G+C);'%*-/N-?48%\ +MZ@+$,[T^PNE]K"^G#]27F;OHO1,>,#X6=XV5GS7^U.4M)HQ1A1E8N_M-F'?: +M'#`FF.DO`4:@"&U-96>9`BO^NAJ,^UV;"0Z]_#;K;N4@+SXQ!H"CB4&."_K( +MP4_;0.?W@8T_J8<5*#P2?N>N\A:UW$B/%HGX']HQZ^:8@!I'^8_"U:$A^NK?^FH3;_B$@',-)T7HUOJ +MR'OHLBT-NOL?QBZ* +M2\K*O]D?*2NH\EG+J_VO\,8N>SJMIQ7ZQ$L<*#W,E<<,:_]N?CCY`4SU@;]AZN!@#8 +MST"]\>`6B[#B1_&GND-DZEK[G?FIUOHH_,Y,P1#8>@4RKE7^RD*VPF^"(D^7 +MS2C(K#ZN7:X'D-!I@=ZVG/"X`6:K$^!M*,Z<2-9TJW#@'SA)Y\E;:U1HF`H^?J!4]X'N5?YPS@2Z:\&47!)R +M;`O'Q@BOUO"VV@%U]3LW$3PRK5K^\$!2$FO]U6QO#7#+X^\\:DN*R=\^0SF^K]!&)CR* +MJ9:0"%H8S"ES>QI*V.L'8K%<$@!(K^5?,CO_/@KJT1I7T/C/9]!5N98:,>O@&8L,K$% +MT;,6P14,DMM-#&!/YZ$^2SB?):D2?C$J'SS%A/YWLT?U7^'>H'VQA?H7R*.I +M5DD'O6?PB-NU@E&",KSPR)J,8>ZFO-D^*V]0@IA!R#L: +M=/2Q)OU,.<=Q)[3ES\%G\I00Y<'`O14"#2IKA1IPWLK^:2_O>KJ6,ZQPZN;A +M>\8L[8X[M]@>WDR5X-;MG74S_3FY\94&,;)R5S2Y%%1^[M;@6ERKAVJ3-=S8$MJDF!!N79% +MY;)^J\4OQ^_TU:TFFG/?6/UOU&-QE^-^0]K73^@ACQ&4S +M;U5T\D`Y(\(I4^??LG"[V(?O!:,]?=&@]^MI!- +M<5;CW_8;$X"`@!J#?W5P\N<'&N\PA?-FK+S6WWQ/0FOUL_%]RWOF9KC?39=C +M\4[VEL)C#P.9DEP,'?'UNI>.@6S=],^GF954%[U-%P]YE,KRS`Z;6F$DP+'[ +M]:]'DT?%&JG2:9#99+;O_JOMM9TN9WI\"G432$RQ^',Q+3LF`YR_]]J5#*M* +MCYIOXMDEZRX=.+ENC30F-'OI%BZV6G3(S`$F8BAH>AU6XLDD;;SA%V<&XYXJ +MG[CX\V,FM5N@#'J_W?2&D,.5/1&$W47ENY8^\#DU* +MW^7!6WE=H9KI;VRU>&TT,O0'"[>SQ*C[;T?H9+A9'L5@(]857IY"E +ME!+ZZ[L6P<+G%,F'R:]@=X=7I-Q*&1T^W(F';ZNA)A@+FY&A"Z8G:J6)MZER +M>6667-Y[#9#7=,[BE`:],6]^APSV;K17V8XQNT*!1$;0M2:-V1?J'Y5"Z;*1 +MW)Z*G)G%85!"-,/VYG`*22+'*W_Z9B-56GBC,*BU?EJG,5/17G,K%D.$I4NL +M'B]:5_BNA%-1SK&I>E_#KI!G(("'^^WZF2V=X!U%4Y/6%N37P%'AI*RA+CU1 +MSI7%F^O/G'233ENB&KG=[@TVDF$_Z=AE8YXHJSY&*?BE\@=TM"5`M_QQ*S97 +M)>O+:FMPE[SR52T'!:";XB\^1L?5W^2MWG\#E3VL#?O*YLQN=*'W.)V"[FPB +M"";-H\>8()>Y)$)4\!S,67%8P[WM5;]]?,5M>LGKBF,&9PR&%^A#!%%+3/<* +M+X0XX>.UL3=\6`HL7P06+OOIQ+K0'IX4W50$>0PV1-4#]6']SJP@G[V#/CM2 +M_JF/S?Q<#;L3N4#A98H\*TQ0_WN^>::P?R>Z)Y.ZXF$F[@":SV/;2B#M0\1G +M^S.$[LW1Z:`"AU#\?V_Y0@8[!/J4SF'YJ7M^KSVJM;_]T,,;`X?&M*6A(*.Z +M8_>S&2SWAL^:N[X\)#`J&8?8-(]G@R22Q&=Z-AF"-T<7$=MUENMN;%QX[3#Q!1X.;X?\CI_.SUND2BB2MH&VOM;Q!4MA$D&>E%S;?+"<+A4_H&H.6Y@L_6VO]T&AH?HE:3M$_QV.I +M7CD&A&FY09.`6:_CI!I&W9G@MC<_X@_HO\AKSYF\W85]A'&'\36-&)U +MN\.;4'`<"%XOX\C27J^^/-*^& +M1C9ZP>S(S57HHXR.W7Y%X4M;F2B/Z^ONZ.%)SOH_#]2UBT8$Q4P1AML^*(`P +M3?1#"T^C&/'OSK3_9Y1VRM>9XS>S_W]D-9C,^R]TPJ +MJ_U]_:'P\0@_77#*89PU,(.M^75TGODAXWKTL6( +M43O0)-!Q.UJ/8P6($A8#P&KUA,"XQ4Z(R8,EYJ^;'P2;#W?,_#V=O(@:OR;8 +MT(8?OA&>J%#)F1IG>Y&&ZF=-TKVG,6]I+X>R?!?I$?F:&&!XP(*%IMMUSSE> +M6:08]B85"[?]'_KU)->WH'(,"!I[[O.X++S$$Z(CA4.!Z!=?;TP'7?3*N%)_O!V-O2RY9OTYD]H(&8+B4.'[>/;$/(WR9XMG8"<,2B77@ +MNIH6E_BZ)7<#LR!6=&<@3?`Q-#H,?J2#E&.IKU=I6QY0600$A(=#!G+P=M.S +M*.77NX!J="T;<:)U._N6(OY@#APKYP."LPX`'?,F`D,Y[#`+W)B5`7779$!"8F=YFP]@5ZL\L" +M6(S/CAF"$Y=[;W_*Y'F^M!*?T>#L>F8COJ'O]G&0CQ^(T%FYF`^7Z8![7%TT +M%F?9`\7G8FM1<<7\/L!PJ6Y=_!=#2WR`5+#WB.TBI:7NC;,B]^L_)L40_-_; +M?\.A?!`%(00K7[*``7(II^+9$2`4A$BE115143,55%1(@%04P`T(20[K]`R! +ML*"?ZD_K-G7_9HGUNP?!BQ40156;A?)],0$@,6Y]!P)_9*LU-SVO,_^ +M(./;XT4O]EGOL_.;@DN4W2G\KL$=9A0X`E-LEVGHNYD`'W +M&/U;K3J21`0'%AU-C%?^\Y[=(YG2&2.`]4U\L;`D\IKY!S%;Q[@T,XY&*9"E +MN)*XGE5]]^2DAW_!P'%F#>9(,CD>,5NFJNQ7=![`4%KOW,/B?4AJM=Q-OBAZ,-*@!: +MK/QWF-@ZG'XXZX@VJ:1$038,#*I<](GB*(R&3`@(RVDRD=6.4>"9AW$JA3P)W6R?X(2+O=A +M@3`N0PJIXEW+$IWLL*B(.)!2_\>+;<"M9/-K+";R6&"QO5_"<#[`N- +M6CO$)`/:[\A"]R@Y3U1Y\M,C,@:M\D55@1$"R1'C:?,^=M@I +M@-TS`N%,RGR-E:=UU>*HE]AYM47(;-^>*CWOJJ2;XSFQ9\"4 +M((-2.U];6QH%(DR:I,`:;1#S]5?3#876*V=OK*,W8,@46MC<;5N'W(1QE/X@ +MXF)KS13VED"LJV1.&QO.6][>K'!X.;-%FH73.AHJZ-SLL*/Z\"KU1P"]7+Q: +MFS8&'F/^UIE(HM;;&(W^$.SER>O^WU=KD7J/$(2MLL*M+^"O,BGWO.H"]5OL +M5$V);;U8'([XHC07/E5[?*\O198X0RQ0[;KCV.Q6G/`EILZU[067?=S($/AS +M)@@#MT9!?3'LU)"UE_]#(W\-5F@1U0H\B+Z^,EV//:=I+SIHA'LSB,N9@>R_ +M.'&/`MQ+(%*R>>FSZ)2!>QLTET0C(BE:U7AH_M9WYXA&&YCP?$V3O@J?#B"]TM,Z'F'"#WVJ>\H3!4FP^$T,Z8W/H@XL +MR&*U42.(G[5)@[5+CM#Y8?OY+E:1G@TE#\2&>8^47]9#-G +M@,/[KE1+D/6]6[1>'"Y-3W0-'GFC\XR8Y%.?(0GK!K7^8T1#A9F*(2O+F/=2 +MNAWHF`'Z&YLJFQ)!?_?SXR5CSH%,I3X#:FZS9&R^34`P>T:!NLL<=`NE^,L! +M)4G[-FR&'O^#9-?7!NGUM4;+0.TX!=AXV!S$.!V:IK$G/P9+RIKRX$4=4>O. +M!GC:KP?.`]*(%;9&!S*\0WZ=M#1J=K1''-FX/)PAV_^Z-&N&B8X/REJL['>L +MV!`=O!V0&5F=*P'P'^YYA>%E.'[U>M`QN^OSP/Z,"5A<3^/'WD)6J81UNW+Y +ML%O?S\W^G#RP3RU=G`&/2`L27L=<]<`Z6G+AN@.!L.]XC9&J6"5"GS&HKRZ/Z.+2)R.D2FO%E +M[_4V!L3>[B@4HWOQHK)>CRS\354Z/@*IX#;KGAY@6<9RS0<_N2=%%8Q/=IUW +MN'2'8_%0!4;"YD.@<`ZRYP`.M.XBX;=YD@R1^.V!MP=]%S/FNZTR75+SRIG2 +MTQ"HJ7.U&F;3I4?:4(R)2O\`I,''>P%ONF5O=E[,IJI\V5#1RQ%[-DQ=5CSL +M^I%^63(O1ZN[Z4>3OU(3\L1/SMOO0?D,T!2^;$^Z.0#4C3P9TAZQ#&&1Y\-6 +M@3D&JZ4VJ9X5]GF\"=!>[[>>RFS@W'`F@`S?4(O,,W/+E0?`>-%>#%,AGO\L +M@"AUJU>GBVE[0@"WDD +MI[K)\Z2-\G88%LUR@AS8M:@IC6'31(SW)*XGKHT%Y%$D!L5'UZR4LSI2ZK?T +M:(E1CQR`(ZUT1KX`4 +M%WG30=OSMB&:S<33<\`=*DQKV;+H0440NM<99Y4OA8.>:FZ$'0/3C9D7AJ<<^;8N' +MX%KS;XA'QQPVS/[<&%`":VX.0H^..E2!$4SM;]QHK`I:YMJ-=OB'>.Y +MMR-TW*(O+Y,6H1D8=WQ#40F-WS\<'.]TR`L[=X;EZ*!.'9X$'0:!"7^?B16. +MXQ.,".%]>$7X8QX/`@M&(">,`W)XTA%8*GF&AL!/':@X&G)^X?X%4<=W:=?!"TNG?&TR#(PH`9X>!X\3OYH^QDQ^4; +ME9,Z=R=R`ZT@XY0WAPX`X$IIL(^+_'D4TRXT\.\V5N"`'?\,ZROLG!EZ,1_@ +M#]GL+8$\S3SE-%^-!:D7NMO-8<(#A:#PXKL#\BR?8)L`*JTGSTR>\,FI.GQ1 +M^8>$OG%D34U8K_M5/`$OFS0_3Y?)7L+^RLJ!KT5T0$\SQ[_HD'#I/&!5]];I +MC]KZ]:;,)0`"L3%VZ.XB$@1A::%Q:$&2:0EG6))&0K[>:/I +M1Q!UJ%^ZT9[A7J.@-NQ(ZUB=^@04'C931XJU$<$>A6^UL[[_GRI*`KO]_Y0_ +M4XR7I,[*7E]KJK_*%D0VVFV-L;8VBA;>D>AWVCO/EZ:S1<9R@E8?]_1[K.Q6 +M!6`;3?(LN#B;/].ET_D@F/^N,\CD[CDY^2A2YM-![A._OKRDS)+S- +M'I^FGGP0A%G>_'[=5)/73K][:X,'0"5-U8[EZJG/:I.\_/MN'SAZ9AS>00D1 +M(DR*[G9VT+@?*`^,!4Y.`S5>`7->J5=J55(>ZG8]N8-:2@\#KZ&>'K-] +MM[W2QEP>!!-3,XF\?FWDIV\#<;F*6'0QO>0=(" +M0ZSIW'^)X?!0?PQ\C@(*EET/SX-GS_?TD&*8E#XZSHH2(+:XTSTMP_MTT.JR +M.K;6Z"HY1``5#L7/PZ3'8]8?/8_,=/3'@"5]A+.*1CV?V;NIW&] +M*[2``8MS0:)O)__$>-^F-`MX%G]=ZC(%V:#/ED1QV/GPJPYT$<(!4!!N8QSF +MPI<*M:)_A_WIG@0TFU^W$?RVU)MF%LFTRP:K):V:0`4SW83`H-:3[&<^R +MN>!"'O_#OO-OA.063TC[^V3F]#QDUHB`$WT?.TO4T-$T)D%OO/)\L^`2_YHA +MVF0)''_)?TT?S%B"G7*)2"(..*V7^01SSEKZF;Z2\(A7??Y^*@97!K6):OL\4=E6)R:I0Z"CWG/M:UEI#\@D'(W^U^E@Z[AM]['T_4`&ZL^U9 +MN^HSR+W7#B[Q^!G.;?]NYX@'&Y7NUT]/%HP2Y,:H)VBL$YM/D0V26U_CM"SY +M[CQ1-J,!M.]O50`KE\>_,XUPO]+$Y'S)!@ZE$1#!^GQNOY`0Z0U!$;B]-7*0 +M`ZN9?%/RA(?W&?Y*1CAF)Y_0D"2(R_@U,AMFO+*LUE_G.9VRHD1`6+[@!*G8 +M-6LTG*'@!IVC`"`/NXH[?SG0`P8W<$WY;=S&4B>JH^NIQ:(@$=A3RFZSU3TR +MCI:N2XEODORF<="1#0)\1UBZ>&/W/)#[FYJO:4(`$&XZ3MV0':I[3>[R29DV +M3'M0D"W*.)P5,N'T9/?\#=)(@OL@(OUL]KS)HJSFFX/P0#\VGP`I^S>!S=Z# +M7?B\SG^`)H=X5!M.;O-MDIPZ>!#&T&'<5N(=(*_D?TB%@B&15G'?4FQW]2IH`!GN3>E +M=:J8DP3OOYW,MNW>+X^`K(/M*DLRJ#>[MHGQ$T:XA!!=4O2V$4!%><'SFR@0 +MXJP\.]1D07GJ5P$(`PN:;=/(74ROQ-P?W,)->)U`0'T[F$!'J2TH<6[G(2+S7F'ZNN7]C=[P\A221X"AWT +MY_U:0[1,-127"0=`"\UOL/##L^DOE[56D-EP82X\LP0&%UOSS_%U\@1JJN:B +M-G20`"TOC4BK\6N:%A/;ZGVQ;L,K]^JE)GP^YKO8S:>]2`%4SLQ,+)>[Q[K) +M\[M)PI`#:^M,S-W``BW+0QW6SC]E]NI@N!P03AD,U'5]I4;&#EK>S_*RE$0= +M75L*\X:O!2+L8.&WX\`.;4D)_SR2^A4,$\11U&!*4W%=Z8,?IUQKY("`QE0] +M+IF!"2Y;/09[,?&J/D7&NB+RUN'#]XS@92:5DV#1@#AP(+S>H3J:@1_*QM%, +M%EWCS@(ZT)W/8OFT]"(`/_TB5;[P!\/--HQ7O/)HDMN0@M!`@8/I;A1)Q\'0 +M7'A?."->7=[3'X*WA6R`#1>D%GCZ+(M10U]R]7!-'(Y/Q0$3E5?W +MM]H`9L-]33<1;SFQG=]Z>,D`#+=7CD5`.FNJ'(UQT"9<78`6GW0J"^G??IC( +M">4J=3.KJ4"$1A1`*!SSS'O>ZHG/R^+;6/Z^_H1@B8.)Z"#!#7*=J@]9@SWC +MY%9(\R"US[ZPVZ;63M)&NA!RA5B2A$8`'XYU002QX>;>>W)L!X$N>:>`_NBL +M.4B1BO.^!ZVW?W78TJ(\1*7( +MF>D012>Y;[XX+_JN6U!"P$XM[QI:F>/26/3+H^I]$DD78`%+DS@M>7":?Z/E +M0-;L60)=::9DLB)>QE\`L6#?33Z&=VNPW[=5)!$&:1Z!)76;M<-S-G2&S5/F +M14_\U?=_[8QB@?`@\S4$6%]GUL_<8)&65,01J(BSG.O""G_.]_LG;;')GP4% +M:J_E`N^#F*++HMMP>:Y;QRBQ[THB"7^M7/`#TW[E +MAM3?&42,-3EY$@`?2.E%7P$)U-#.:#-!R7F(1Z)(GM%.+DNE$`U0DHMLBP5.TUT;J'.II@!D(2A +M94I0T'JM<%"1/.[R9#^)\NZ5JD=*1PX_C$43SA:VF20O[Y!(""^922+\:=HV +M3J<+QUUQZ02+6XJ9R9S(R@)E@9,]NG7)W=]QXJ&2`!FH<`?50]2P.0C?JND? +MU=&188`PI,4DV_'>48+^[*!(!^_YB51V!T6[,-EEM7A(06,^0%+A(] +MJY[8Q1;JF2>\%ZX200V'8E`5O%6*6T,&KGCX&$]Z>.4_."$M2=OZ8B7>ME.@ +M*1(M%BNT>&B4V5E&4RCGOD@`51$HC-+45]:EED,?4(05K5Q:.>!<#,;)22%% +M^]I\$O^2EJ`!EWV47;\5-X*+)H`51)R&7\H'OKOHB"-D2/[1$7N;%:_(1+NQ +M/L9O*FHY"F"^='1D01[^DC<1F?L?1*8%O@W&](MWWW2D/4VBBLY`$,A[D9`N +MR`/QMQOA6A/R?.I!P_F_(!!AH05%,=4FMRB +MYGC#-'0,C?S`()(@OMJ:H;*4XKNW9@(B*AO"*FN8%(LOD=#YZ90@/WU;_RM_ +M8:%-_K)CHLNW2@4GJXN^QX`YZA(064OA.]*F#6A!:T@%KG4\G(0GPB( +M@S];2D30M_45-;R64'B'OA4[3D&O^:%O2]2MH@$N^2].0*$R,@'F*KO3UJE='8:(1)!?:-,0<'9$0 +MT'G?][N@NQZE;4<")2C206+O@4/JA#@*262!=[[5&K2%5 +MWVN59(CLOH:\KX'IG300X-!0@!E\]F3B_.Z2>)#D(\ARG:($`Z4#43J?!"?K +MFF:_J;SB(2VF=O#G]UD>3W4!"VR/5!#V\+\1@G>XAG3Y*%CY)SM\4B'6:G-G +MRW".WDY9_:+`#!4U>\X:YT*-Q;$)",BVC_HT@.K8^>SE*1+C-'C$UN6=`_(R +M`D(TB&LQB5J!$]7S_M83O,B+M>*ZX!%CKU$$2+9\\\7P?N#F^,"'EO?(O=56 +MW![SJ6W-$*N>(G=%QW->Y5HYLB`F#GZA)("EE1VMZE(TI^9('S(@5_S2(6'A +MS]FN#(]#O/'0HC"`BVO=G`0U6OBFW/Z.@JN;:2&B2`$+>"%- +MX)1A\239!5UT@JH@%TQ_2',7-?]HYW:[8?S\]-<<-B$O2.OP@!5,*1 +M;6,@7-FFK&-/E[=K_R/$96($!LL]D]#BMFYU^JZ#&>X'2SO?9T>\3""^\PP! +M8S$RMV\!03.LX.]DO7B802@"VEIMIX@6@1C/[:GS,TC>JM"!8ZX@&SC7GU8A +MN91JAI=)1`IN_Q.B0#7190>6/G$A>/E]\F"T3G7]CH=)K/#AO2H"8''))S?B +MG<)DBF0[)%KLORUMBC@A+F+-8=_I$+$_G(SMJV54@K7/H\J^"'5?*F_T*=^I +M'.]\,5OR(?3=/VW9#(2]'J9*MJ0B!0^(C^>.R9`3S=U!GWM>Y!T\!L%@@%I< +MG[Z[IGWJH@Q)[_UY8B#)45W18%;6Z#.UT5DQ4)0!,01B!+:Y<8]6@#E;'-%# +M$A64Z5*`,PSD0/JM7OY^&F4&0B#RF0S]>0*2Z.VVJ1J0\>MX;^1!]:S:#@JA +MUVSW">?Q^;-?D%@$`]1&+OQ`27&QKIC=&[,"2%R29X2*(DBX^N3Y#5ISL2?( +M:NQ<_UQ2(MJW.VP9J<[-KT?I@"XE)UHE4L,CZ-)VT(>-W%RBIHP1/7F>,?]@ +MF.,)N^5"9%(+^.I`>+H3"1M5_IK`D5!""W?LH(@@5?Z"^NFT_#D`P(BR&F[U +MB`*_V^:!O-C%A#LK93!02&:``K*"T8+9D;74T^./JD8Z$1_7^7O\T:X=!$MI +M]!IU77]E.-K.I,H0-E41\7787$.@ABM#':CU(K[-S#G#1Z07VHO\D*K^L60& +M_FOO^L$UR2D578:+-D06K*AN<.G1RM;&BOTJ0A$$2N[N]?$R*)J/EC9O.D1: +MK9X'5-1=ZI#JGQXZO+<\B+RR=?O9_PYJSV+[/&00#0XY^5C?'4?!I2W46D=$ +MX(MBV*OIZ?YS[[FX=4+2XKC44PQ@B;*%^_:,J&(;*/"F&$81P"K]^$"*$R'` +MNZ-)GC`RBR>0`9SHKOFX.,`)>2Z3`2H@PE+SH@#5):^HB;1:(`1HD7=0IDO= +M'3*8ZKJNB"B[`B=MOV4MYN^NA&75TU$0C-;[+.XPE$$!S6GC,*NCQC](^[+Q +M[C$*I-+>8B((?VA%."V6X6;$P8O#`N(9G(.*N"]G@I[_/^=>5TKZ7=,99KIW +MDHF,^QKSX)ZE_NR1J!W/XT@.WU44%G5IEWA\NW_4Y[VF!.9?)@` +MH/1?W^?@?/=E"(F=';L*D<O7,&Y2%2N.MM_)SWER%]2H@":=@QZSN-*%"*1OCY;ZJ-A7+-:J`B#( +M9U56UH,+TV=ZU%"'ZM$FJSD:0HI5GOK_QX`@R.%94^3^%)+;#Y9.JU"[?0:W +MX7M`""(O=553(ZNYT)+MG>P;(@0%&8!,!@`EXPO]'">>%47\GMYU:^+(!^%! +M]:[I_CI%/P8U=15T0?HVQIC;6P:X=3+\"CI\!\_&Y4L!!UK,#O0/%Q,SIU4_.H@" +M"B1%>=6T4D!P1)@B('T&8,>[-W6G/$"$*VFS00@=%Q-110A5WC(_OC'@,-E' +MVW'NTSLOD_+;:SMI6]Z-Y#544T4-3*X*C[F%'F:_:,?7>WK8]!)N]-F-M9+C +M'BE^OM:;$VFQV6$&6P80@7RT=JJ^)'>3'/L_>=7U;33 +M$PY[K;)#P-WI_,SKB=(@]L3WOIEVT=OU]_L@6*,%T$U9O(K`T`/``-FFZ?EO +M^W[*/LK-NG$N<:._G+1;K_1ROO=BD$`'9-V@]9]C\)A-$V*!>]:#WS^C\B'[TLBW0&38H``"*E\]\EL%DN5PAHV.P4H;]VD0Q- +M[>U.*60`YV^^;MT,/6C@37+I&L;4`LI.3J>)V*VR:";D4$0ZJ_%P1NCX(KRT[&SOUN"RY*SU.,6G[*)B<"! +M3]#\:?1&\U/?!J9\:D;D0`"2R[FR_:9RF:G0]V4E=9WZ^+XD`-+SW5V4"-GZ +M^26[/5SR(`57$Y-OWTXG:>LW8QLXW-+ +M.%5_ZGON1TEP@13&6N''D2*LX[/./W^FEU/B<_7I!`!LF9'&#>3/?0]]GV1O(0@BM&>Y\[S& +M*X$#7I! +M^&G/\%YU;:VU743Y9$0*\WD!\./25O0S8&#Q:I[U';?J9`NG472C;`.@14E +M6Q*T7,^>4\B,B%[9\:J_]XG"D`NG2;9ZR\:?-37LX9&"*]EK\"P:'^G5A,FF +M?L.N[#;HR(I^UFMST;=<]J]H"$VT];C=%J>IH4OSY4C(*B4")8>\&>5H:5TF +M[2S&]DH-`0)(,OZ9&CJLN:Y*4/!CCP(9_MMP`5GFQTB]LX;K]J#'-6_W=+'] +M2DLB+Y[=XQ!`RP8_P\L<-1U\BY]]"0+G$!N(8<%;6V[7^'K[O1(@15VAC5+- +MD6J3(ZZGZ21:.8ZLLX@XJ>$"4"`E7OY\7@EQ6)^>W++?#=L2&S>5XT+$.LZB!"D] +M;U@;WFBWE=;=S[JKXJ>1;6RDD@!2&S[^@K2*%5-![7BW3*X@5,``.[J)VWG)*HB9BVRG-G;Y-]W&6R(=R5QV)VI+$PN;A@OLR-$WKF.;YS +M!7SZ,@/;=Z3<\@%R>-C^(__YTC>7ZKA62"(;X]Q[W[4'EYY%EDU-K@_9/+]? +M7*\-8S"2"$W'R06=`DK.=1.AX@,M64!!>A^N'+*NYT$*529ONZ$!M;M<[F,Q +MF@55S>6K)GUP9^ZJ;^SX-MH>K8+X!";\7=T7-(4]749F]V&1B[&AIT8`BK\B +M6U5PJL="23=Q*V];'9KS;4]+!$7?]_'!-WS?6A6Q:$M9XK468+%E];_H4G-@ +M$B(B&\<+KQ(R%9P7E=2>9JTF!NEA$`2)RFXH@:>L_*Q\Y1P%#KO-2)!$3Y]3 +M?:(N;Q<>F_3>L.7U/!@<*120![:6,(A8P?$Q)-_ZSNT\IXTK8)<+OUD4PB'? +MS&8N@\)C.SNS\VHRFYF;S7LTZ4`!S>-_J`%JDY +M*V6"`$U[K\`7#1W=$&VW>L&WB+>L>_W500TSGI`!HVN>A5G\6U?51VHEDT:4 +M`*'3(NWA\39LR5J;-_@ZS@6R2"'Z]48""6XID;//*:QOC]UDT9O7T50M)@(= +M[9S)`9UY']H9/G[^2QE1GN\SUJ40$LN8.IIR%NO^%TXUKTL=CG!D1`!3YGJ[ +M7RZG!!?AMIK-9:0:YRWPNDC!6VK!,R5S#)';&/5=PC!#10VW:2(1^XOQFL_GZ#I47O]2(B^=3]^N1=WE +M0G!XN%I-WUTWP]).200G7^04_N.FA>N<3;N=Y!?#SH2(O>DTE:[+Q%4O#-OM +MZNZ%A=[G]DI!4XK"`VIO^=K +M2C]S,_^)""$S(Z&;(!ZFF1DT"PL.$OQ>TB)A8."1!Z/W-5MIH]^X:OVWWF>K)+(# +M4XOK)``IF//,:=LY_L-Z-;]NY8^1I^Z^"S7D\@!;09`=."=D_CQ\W#-[W7T* +M00W](0'I12GI6[Z4K.+D/"M0G62?4C(A_/7\'A>2B+S35FEK7"SS<8R]Z/3@ +M\==52`AHK\R&-[K5#S4;>V4+VQ[D9`?RT2M7R0+@,V\N:*2812*JF0&\4/U- +M$/;,9^ERFQRE#%IDXQ=7<,:,$(8]G0`D^Q@6&RDN^(T9_D/5(DD!"*6)-D!] +MA:].>?VHT2L--GG$E/A*I`>=YY$_HB(2HYD#DJ#&GU;>HNJ9Z[L'R`8?QW5B5(#(I1;- +M42Z2=T&;Y;[/Z=)!>;L=ZN`A8!+0YCFW76S<:A`'\6T2VA>T,WRCY`O3NB`N +M-RXYKF^"`K*J\QZ(%+8%S*$4$B9MN?WW$2<"S7+U(`'"E[`@7>L1I'_M_C%, +MS1'U-EM-T&PHJ0,EXN]GIHP604)D`:+$I)9-D9V:T$^A(?BN(L3QYW5;SQP&5Z,%!AX +M5/G+(P0V?RO^_RR+:Z9X2(&P3-<.Z@`J"`A[YV\E+K9C'Q>FXSXD$.3_WNN; +M(`=W[TKTEN3VXK*<,8,56))`3;M`V)%LNGXQH4RS[;`X/Z9R+M)`'TR!!)B5 +M:[[:#WE +M_R(/VHB'/2:7H$0C/KU%S=>3T4GH;%1=\#;)2B6"G.-ZB+Q2'U3UOO9CFV3J +MR:M(!6]N"';6NG8?.UY'"X_9^L&\=Y*!"BS8!2\[F6QY$=ZXMDVSK]=C4O2@ +M]IA`;+./5R1#P!MVZWG^[E56]Z&_3/RD@#9\ZX!-W.M4X]4>;%2B`$UMO:(! +M.X>5_(BF7OUPTEML7\Q$Y;. +M:H3X97Z[18:,ED +M/.E`L;HG[[-H`DDZY]*6WS[%>-B:_:!)!10[`(0!RVY"AQ,IH?7J6?LS]+0= +MF16"`H'/>$-$Y;59P:U)2=+,)T8`^X%XDM'J:%5\$#P(7X8>2RG7Z2$#\)L."&X@VC0#:V.(B2O?\OW/>E+[=/3Z\;E +M;XNX8.+_4TB&;5;(%9J^\0#B/HU$PFRJ$$+SYRL#D*L"$HOT[;4[:9_/8-L$ +M1`0\O>?7Z2\.K$!O,]MY3-,Y["8/K(:+N*8/-J,@("S`#__=[FT]/[*#9^F) +MSB01,'F("F[/_6Y8N5JYP^!L\>10I_.SEXM;#._)`1,B\1#M0;MJXOC(Z_AC +ME;84K@EM\"E@!%KM-ZP`P$TZUM:3^@%:CODTE_RW'W_'[[W +M+S4A;4DW`K*:1#L^S[=F6_4""*7026@EJQ5W^\9]W"K%/;R7#B1\?*G@$8!! +M08,;?/G$Q?9XB07:JD@`5,2`5OILA#>>N3OAKY.M4.5U?:C(1;WVY1N(!Q'5 +MKOBEQU8MIM%(,0@J:2Z:6"$GQ*3N-&Q`+5G-"0S#L[KM2B('J":GB(M!Y +MHYYA3_6,9A-UPT4:FRG)&Z2P0JUR.`'ZSD_MNAX]OWEQ`!PLU-?V=(#Q^OV? +M"JUD"8M_8[.5#Q:FV60[B% +MFW-ZSIB,%\F*`(B\N>U(R7LG>K&.:L0@6\ACR!8M(W6,GE5+U8E(YS&T=."U:>]A=3_2X0*29O!BP!GD"C!X" +MS<[F/OE0@]>!+AT=,1!;]N[_WE[03>+6UZR>4@#Q*7%Z`5S4>R_P\7D5..K] +M/X$A"+7YL/X(?AO0E)&9@F3CUW"G$0*QR((>)A]1CBU_@OC^-GUGN9-PS-(E +MD!0QVS[K&*2W!5_U_B0U^XW$QN7J73E)I2(;SS9/NW-"")HM9RPX/LM5YQK@ +MXR+`OR:L"FJW'>G)D3B&_1T3SUTI*8HE"18?XB8C##U\\Z0$/;++7NH.;DHV +M7B!8_3H)0`U,55-?1`+#3\\Y6*?\M\H24ZGSB2!@S!$6?_%,&GW[Z)E:].7, +MJN:/-Q#8]]]?3R`7L$$<@^FG16^V\CJC"`BGW^XRWV`%F]^?QO^GV^<94C;N +MT\D@#1VEMMH1Y(!FMKW!JN/*3QIIW6LLD!3/9(%VFBU&3:>!#BIM:.!5?\2@ +M65-Y<^\VY$&%WKE2!W-K:X.AD;Z^^1KPM +MV\?4=I*0UC;70WH:&8&I]:@=$/\SF4E>B0+LR9SQ$!VI;N>Y_":W!HAAW%6PH.IU> +M71JR2A`[.M=NN0*-=ME+1KTPL+!;(0LM4J1#J1^1Y5O*/"!_FF%$!?*G#.P) +M$.]^G:W'8J,-O%EFP@C!,_E[ +M&HUX(G>C7[OW[R,S?8=,'QQ<@HJ.R[^FU]B/BH@@R2M9)$`(7DM8>LWHB"6S_>4AP!=_?B):9I99F1TJ$AI^2`'.!5$"DW*F\*VN5V<7?[:FQW5B'OFO1Y +M/YY:4B`RHQ>\B)OI+U,&X&E,!O"H$A#S]_SH0`$$;^E_AM+(K.[)+CHI`6L< +MUAK(#FQF_CTM\0M.9TNP1$&?Z6'N42!/]%;>17JZ[3041T,RD%`WM`>(AL.A +MD_I9[Y5QZ4@)1_4)-[B:!!'8M'>XAP(N>)-*!LA04$NM_Q1`)J[2SJT>L7NF +MT[>GCT@L9J51EX74]_(:`"%_[E)0T>N4O`CUG4ZC1%:80K&U*U<$\B'`Z/TJ +M/[!S?2(B02"CT8Q5W..P%?2.IAYE4,;QDL`,7ZHF/W;<`":^IV7U_YW6H/EE +MYMQ@LF1"5KN$J2K+'YUH9):E2$+'K8\$6U]M9\F5TB!`*MTMHP)"Y[-5B*,A +MYO9TY,@6=\U;*Y3`A^"[\UU5;+_P(NT=$Q)\N[)?6&/`B2R3DSVV^J;W@^YR +MKEE952&@RRRVV1`8E.[7"66,;54J($\?E1;]E(`'K/F.L-Y-5E5*E89O'32H +MMVU\H8M-!6.LVSN`-N%'-?'3+QQK2]],QR(BCO16_A]R`("'A*6FG+GQMN[@ +M\N+3J.*ZC%Y,Y"!M8G7@`M=J\;M9&E_/&A[[/LWC,1#I;I9;G`XA`KVLS/:7 +M+WJ,2-3%!F+4@6`P:ETZ*-&ZL"]2-B0H+3K4H`!)+VO[BDGHZ$5RPUGIHQEF +MY504K%*A$.=J\C)R4-I,^B$_!X.4'MN#[V`3"I:[D)=O^_19RW;8%6E55&3E:\"H4GNR3=("`V%YKL?J_+H +M%+O\X_IU%@]B4!#6E![8_&@A+;Y)B=Y3_+D`+9HNUI(3Y)?WY8H@4)9\3#D?1 +ME0HX7U@GG=GN>YD"%P_W6DC^W0[CPOFE:5H[3-12VMKJFO[EK8`"G=AT[Z2SPX,E9?G4#KR&08@0H5]\U8GT'Q\>UV[ +M*"(9J/D)1WDZL;[+[[FL,#D]$[I8%A^,KX>O2+K``0VKJXS-/!G$U/#XG(0O +M"OJ_&SOB`$`QJDECIERVTTTSVI6G-&2C?GU8O)+ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_macros.h" + +#define SECSIZE 512 + +struct testvec { + unsigned int blkno; + const uint8_t *ptxt; /* PlainText */ + const uint8_t *ctxt; /* CipherText */ +}; + +/* + * 192 bits CBC key, NUL terminated. + */ +static const char c3des_cbc_192_key[25] = { + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, /* ABCDEFGH */ + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* IJKLMNOP */ + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* QRSTUVWX */ + 0 +}; + +static const uint8_t c3des_cbc_ptxt[SECSIZE] = + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop"; + +/* + * IV method encblkno1, blkno 0. + */ +static const uint8_t c3des_cbc_192_encblkno1_vec0_ctxt[SECSIZE] = { + 0x19, 0x92, 0xc8, 0xce, 0xdf, 0xa3, 0x14, 0xef, + 0xff, 0x88, 0x9f, 0x01, 0xfa, 0x6f, 0xfa, 0xa6, + 0xdd, 0x2b, 0x43, 0x67, 0xfa, 0xce, 0x37, 0x95, + 0x73, 0x4d, 0x18, 0x33, 0x0c, 0x29, 0xb6, 0xbb, + 0x37, 0x77, 0x31, 0x74, 0xf6, 0x62, 0x03, 0xd2, + 0x78, 0x13, 0x55, 0xf6, 0x58, 0x49, 0xaf, 0x2a, + 0x15, 0x4c, 0xc2, 0x4a, 0x55, 0x99, 0x82, 0xb9, + 0xfb, 0x8b, 0x4f, 0x92, 0xe3, 0xbc, 0x9b, 0x09, + 0x42, 0x7b, 0x5f, 0x54, 0xed, 0xf0, 0xcb, 0x5d, + 0x93, 0xba, 0x09, 0x4b, 0x20, 0xf3, 0xe6, 0x44, + 0x30, 0x5e, 0x9e, 0xfc, 0x7a, 0x3c, 0x7d, 0x11, + 0x63, 0xea, 0x40, 0x94, 0xaa, 0xd0, 0xa9, 0xf6, + 0xc7, 0x1e, 0x8f, 0xc8, 0xa6, 0x2c, 0xf7, 0xeb, + 0x51, 0x26, 0xdc, 0xf8, 0x73, 0xf9, 0xb4, 0xa8, + 0x80, 0x4a, 0xe5, 0x6f, 0xb6, 0x33, 0x13, 0x6b, + 0x1b, 0x7d, 0x00, 0xde, 0x44, 0x7e, 0x26, 0xa2, + 0x82, 0xa7, 0x80, 0x16, 0x34, 0xde, 0xb9, 0x82, + 0x4c, 0x42, 0x8e, 0x0d, 0x48, 0x7e, 0x38, 0xbd, + 0x1d, 0x7d, 0x98, 0xbb, 0x11, 0x8a, 0x72, 0x14, + 0x4e, 0xaa, 0xd0, 0xef, 0x4d, 0x7f, 0xa3, 0xa6, + 0xfc, 0x85, 0x9d, 0x74, 0x63, 0x9d, 0xe4, 0x5c, + 0xf7, 0xa8, 0xd0, 0xd7, 0x95, 0xb4, 0x28, 0x64, + 0x41, 0x2d, 0x5d, 0xd9, 0xba, 0x79, 0xa7, 0xb3, + 0x9c, 0x16, 0xfa, 0xb8, 0x10, 0x5d, 0x1d, 0xd4, + 0xce, 0xad, 0x67, 0x27, 0x91, 0x8a, 0xb3, 0xbc, + 0x37, 0x20, 0x95, 0xac, 0xf7, 0x0d, 0xe0, 0x1e, + 0x59, 0xa7, 0xe5, 0x81, 0x82, 0x6a, 0x71, 0x07, + 0x85, 0x43, 0x43, 0xdb, 0xbf, 0x56, 0xb0, 0x0a, + 0x4c, 0xf1, 0xcd, 0xcd, 0xa3, 0x9a, 0x10, 0x8e, + 0x0c, 0xe2, 0x6d, 0xf2, 0x16, 0xd0, 0x4c, 0xac, + 0xf9, 0xfc, 0xc9, 0x56, 0x1f, 0x31, 0x89, 0x1c, + 0xfa, 0xb7, 0x49, 0xea, 0x69, 0x91, 0xfe, 0x45, + 0x96, 0x5e, 0x45, 0xc3, 0x2c, 0xb1, 0x40, 0xd9, + 0x1f, 0x82, 0x3f, 0xc1, 0x45, 0x7c, 0x39, 0x72, + 0x6f, 0x52, 0xe4, 0xaf, 0x15, 0xa4, 0xe2, 0xd4, + 0xa1, 0xa4, 0xb2, 0xb5, 0x4a, 0x0b, 0xad, 0xe4, + 0x1e, 0x5c, 0x26, 0x62, 0x81, 0x78, 0x3e, 0xd3, + 0x6a, 0x98, 0x94, 0x2a, 0x00, 0xa7, 0xe4, 0x04, + 0x9d, 0x9a, 0xfc, 0xcf, 0xad, 0x2b, 0xba, 0x9b, + 0x40, 0x1e, 0x71, 0x3a, 0xb6, 0x92, 0xc4, 0xc5, + 0x56, 0x58, 0x92, 0x2a, 0x69, 0xbe, 0x0f, 0xb0, + 0x91, 0xae, 0xaa, 0x3f, 0x07, 0xe8, 0xf9, 0x71, + 0x20, 0x06, 0xed, 0xe0, 0x80, 0xec, 0xc9, 0xe7, + 0x54, 0xaa, 0xaa, 0xf4, 0x4c, 0xb2, 0x34, 0xf7, + 0x8a, 0x76, 0xc2, 0x4a, 0xae, 0x71, 0x7a, 0x07, + 0xd7, 0xec, 0x75, 0x2f, 0x8a, 0x99, 0x59, 0x13, + 0xd0, 0x8d, 0x18, 0x69, 0x0d, 0xd9, 0x39, 0x73, + 0x2b, 0xd0, 0xa3, 0xbc, 0x9e, 0x29, 0x4d, 0x88, + 0xff, 0x98, 0x02, 0xb4, 0xcf, 0xa1, 0xf9, 0x2a, + 0xa6, 0xef, 0x7c, 0x72, 0x26, 0x4e, 0xd7, 0xdf, + 0xec, 0x3a, 0xbc, 0x8e, 0xe6, 0xb3, 0x2b, 0x43, + 0xcd, 0x67, 0x8b, 0x72, 0x00, 0x6f, 0xe5, 0x85, + 0xe2, 0x2a, 0x4c, 0x8d, 0x02, 0x44, 0x6b, 0x7a, + 0x89, 0x7a, 0x18, 0x3b, 0xc8, 0x9c, 0x8d, 0x60, + 0xec, 0x79, 0x58, 0x15, 0x98, 0x71, 0x4b, 0x1a, + 0x34, 0x69, 0x96, 0xd0, 0x0f, 0x01, 0x27, 0x2e, + 0x19, 0x02, 0xf0, 0x17, 0x8c, 0x89, 0xbf, 0x05, + 0xf0, 0xfe, 0xc3, 0xe6, 0x90, 0x9d, 0xa2, 0xb1, + 0x40, 0x06, 0x7e, 0xcd, 0x20, 0x7e, 0x5f, 0x54, + 0x31, 0xfb, 0x79, 0x84, 0x47, 0x38, 0x71, 0x69, + 0xe1, 0xd5, 0x4e, 0x84, 0xa3, 0x2b, 0x4a, 0x86, + 0xc2, 0x21, 0x5b, 0x15, 0xc3, 0x63, 0xbb, 0xc5, + 0x5c, 0xc1, 0xfb, 0x31, 0x3a, 0x4d, 0xb1, 0x9e, + 0xe1, 0xd8, 0x67, 0x4b, 0x08, 0x42, 0xc4, 0xe8, +}; + +/* + * IV method encblkno1, blkno 1. + */ +static const uint8_t c3des_cbc_192_encblkno1_vec1_ctxt[SECSIZE] = { + 0x1d, 0x65, 0xdf, 0x01, 0x9b, 0x24, 0xa5, 0x10, + 0x94, 0x9a, 0x5b, 0x81, 0x96, 0x4e, 0xa3, 0x42, + 0x42, 0xd5, 0x05, 0x52, 0xab, 0x3c, 0x67, 0x40, + 0x79, 0xf9, 0x4b, 0x58, 0x39, 0xf6, 0xd0, 0x97, + 0x48, 0xf4, 0x77, 0xb8, 0xac, 0xe2, 0x10, 0x66, + 0xa8, 0x04, 0x0a, 0x1e, 0xa6, 0xbb, 0x4c, 0xd9, + 0x5d, 0x0c, 0x11, 0xb5, 0xe0, 0x26, 0x84, 0x50, + 0x10, 0x80, 0xbf, 0xd6, 0xdc, 0x82, 0x53, 0x0a, + 0xcf, 0xf6, 0xd3, 0x07, 0x45, 0xb0, 0x8e, 0x36, + 0x2e, 0x60, 0x0f, 0xd0, 0xc1, 0xb9, 0xd8, 0x29, + 0x6e, 0x13, 0x8e, 0xc1, 0xa8, 0x63, 0x20, 0xe0, + 0x8d, 0x47, 0x8b, 0xf9, 0xa0, 0x60, 0x55, 0x53, + 0x1d, 0xaf, 0x43, 0x46, 0xe5, 0x10, 0xd5, 0xcd, + 0x91, 0x9e, 0x11, 0x4a, 0x6f, 0x6a, 0x13, 0xdf, + 0xee, 0x7a, 0x88, 0xbe, 0x59, 0x96, 0xdb, 0x65, + 0x25, 0x57, 0x9e, 0x82, 0xad, 0xc2, 0xd6, 0x28, + 0x96, 0xb3, 0x7f, 0x57, 0x5d, 0xb2, 0xfa, 0x60, + 0x43, 0x22, 0xa5, 0x33, 0x14, 0x99, 0x8f, 0x68, + 0x5a, 0x7f, 0xaf, 0x9e, 0xe9, 0x23, 0x57, 0x9b, + 0x52, 0xe9, 0x20, 0x59, 0x26, 0x89, 0x9b, 0x59, + 0xb0, 0xee, 0xe8, 0x6d, 0x06, 0x8c, 0x01, 0xc2, + 0xea, 0xbc, 0x7d, 0x93, 0x3f, 0x79, 0x7f, 0xeb, + 0x57, 0xc9, 0x0a, 0xca, 0x37, 0x81, 0xa7, 0x82, + 0xde, 0x37, 0x7d, 0x69, 0x01, 0xaa, 0x19, 0x98, + 0x26, 0xfe, 0x06, 0x83, 0xeb, 0x9d, 0x26, 0xdc, + 0x04, 0x5d, 0xc9, 0x05, 0xee, 0x1a, 0xd3, 0xeb, + 0x20, 0x8c, 0xb7, 0x99, 0x75, 0xe0, 0x19, 0x98, + 0xca, 0x83, 0xae, 0x94, 0x28, 0xbf, 0x47, 0x42, + 0x92, 0x05, 0x8c, 0xaa, 0xeb, 0x99, 0x0f, 0xcc, + 0x33, 0x79, 0x24, 0x62, 0xa0, 0x7a, 0x65, 0xcb, + 0x53, 0xb7, 0x86, 0x0d, 0xcb, 0x44, 0x2d, 0xbf, + 0xe8, 0x5d, 0x62, 0xeb, 0x21, 0x4d, 0x35, 0x86, + 0x56, 0x6c, 0x51, 0xff, 0xa3, 0x45, 0xcc, 0x88, + 0x09, 0x43, 0x08, 0x97, 0x13, 0x7d, 0x00, 0xd8, + 0x82, 0x2d, 0xbe, 0xbe, 0x44, 0x0c, 0x2c, 0xa4, + 0x4f, 0x84, 0x07, 0x20, 0x9c, 0x3f, 0xf6, 0x5b, + 0x9e, 0xe8, 0x68, 0x40, 0xd3, 0x64, 0x8f, 0xb4, + 0x9e, 0xac, 0xc6, 0x41, 0x11, 0xda, 0xf2, 0x60, + 0xfa, 0x29, 0x9d, 0x26, 0x68, 0x5b, 0x79, 0x3a, + 0xd1, 0x66, 0x78, 0xca, 0x80, 0x87, 0xae, 0xab, + 0x7b, 0x29, 0x3c, 0xb0, 0xe6, 0xa2, 0x6b, 0x24, + 0x81, 0xeb, 0x51, 0xf9, 0xcb, 0x4a, 0x08, 0x37, + 0x2a, 0x75, 0xb5, 0xd3, 0xb3, 0x8f, 0x3d, 0x13, + 0x11, 0x0c, 0xa9, 0xf7, 0xf6, 0x57, 0x7e, 0xb7, + 0xa6, 0x22, 0xe8, 0x13, 0xfd, 0xf1, 0x6a, 0xe9, + 0xc1, 0x94, 0xa6, 0xf5, 0xa5, 0xec, 0xfa, 0x31, + 0xd2, 0x66, 0x8f, 0xe3, 0x6e, 0x9a, 0xaa, 0xb0, + 0xe3, 0x04, 0x09, 0x00, 0x1e, 0x67, 0x3c, 0xbe, + 0x2a, 0x8c, 0xd5, 0x1f, 0x4f, 0x55, 0x2c, 0x1d, + 0x26, 0x7f, 0xc9, 0x27, 0x00, 0x88, 0x7d, 0x45, + 0x4e, 0xe1, 0x36, 0xf6, 0xf5, 0xa8, 0xd4, 0xef, + 0x8b, 0x26, 0x76, 0x41, 0x28, 0x87, 0xf4, 0x51, + 0x14, 0x36, 0xad, 0x60, 0x8d, 0xe9, 0xe2, 0x9d, + 0x3c, 0xea, 0x09, 0x51, 0x3c, 0x81, 0xdf, 0x1a, + 0xc2, 0xc2, 0xf6, 0x45, 0xe1, 0x73, 0xac, 0xae, + 0x85, 0x74, 0x83, 0x8f, 0x56, 0x3c, 0x36, 0x1c, + 0xe0, 0x07, 0xc6, 0x6a, 0x48, 0xe4, 0x34, 0xe9, + 0x81, 0x53, 0xb7, 0x53, 0x95, 0xa7, 0x94, 0x21, + 0x7e, 0x32, 0x53, 0xda, 0x83, 0xd8, 0x57, 0x92, + 0xd1, 0x15, 0x45, 0x86, 0x40, 0xac, 0xf1, 0x6f, + 0x3c, 0x29, 0xef, 0x8d, 0x12, 0xe1, 0x9d, 0x04, + 0x17, 0x3a, 0xcc, 0xa6, 0xc5, 0xe4, 0x27, 0x41, + 0xcb, 0xfb, 0x5e, 0x77, 0x73, 0x5a, 0x2c, 0x03, + 0xe9, 0x2b, 0x76, 0x4e, 0x69, 0xea, 0xcb, 0xb3, +}; + +/* + * IV method encblkno1, blkno 2. + */ +static const uint8_t c3des_cbc_192_encblkno1_vec2_ctxt[SECSIZE] = { + 0x87, 0xb1, 0x3c, 0xd6, 0x60, 0xa0, 0x5a, 0x35, + 0xf7, 0xe1, 0x6b, 0x87, 0xa0, 0x90, 0x2f, 0xc7, + 0x8c, 0xed, 0x53, 0xda, 0x93, 0x32, 0x78, 0x5d, + 0x24, 0x23, 0x42, 0xdd, 0x93, 0x5b, 0x2e, 0x40, + 0xa1, 0xb1, 0x3b, 0xbb, 0xf0, 0x50, 0xb4, 0x61, + 0xea, 0x15, 0x37, 0xf3, 0x49, 0xe1, 0xa0, 0x32, + 0x88, 0x85, 0x81, 0xfd, 0xb7, 0x96, 0xd7, 0x9d, + 0xd7, 0x29, 0x4b, 0x14, 0xf9, 0x18, 0x6a, 0xf6, + 0x46, 0xae, 0x69, 0xdf, 0x63, 0x9a, 0xe0, 0x0b, + 0x2c, 0x53, 0xd7, 0x82, 0x6f, 0xe5, 0xa0, 0x95, + 0x2f, 0x61, 0x7f, 0x15, 0xff, 0xc7, 0xe8, 0x83, + 0xfc, 0xfc, 0x16, 0x1c, 0x37, 0x0f, 0x9b, 0xbb, + 0x14, 0xb2, 0xe2, 0xb7, 0x1f, 0x85, 0xb7, 0x07, + 0x8a, 0x18, 0xed, 0xf7, 0x5f, 0x27, 0xff, 0x2f, + 0x07, 0xf9, 0x9d, 0xe3, 0x79, 0x45, 0x1f, 0x51, + 0x08, 0x54, 0x0f, 0x56, 0x84, 0xee, 0x87, 0x9a, + 0xa9, 0x46, 0xb8, 0x77, 0x85, 0x40, 0x46, 0x50, + 0xc1, 0x58, 0x07, 0xfd, 0xfa, 0x2b, 0x20, 0xd6, + 0x4e, 0xba, 0x08, 0x02, 0x59, 0x3d, 0x23, 0x3b, + 0x5d, 0xf9, 0x5e, 0x2f, 0xac, 0x9e, 0xa0, 0xd7, + 0x3f, 0x9a, 0xdf, 0x50, 0x66, 0xcc, 0x28, 0xce, + 0x93, 0xc8, 0x11, 0x5c, 0x74, 0xe2, 0x4f, 0xfd, + 0xaf, 0x33, 0xbb, 0xce, 0x96, 0x1f, 0xb3, 0x46, + 0x6e, 0xcd, 0xe4, 0xef, 0xfa, 0x2f, 0x93, 0xb1, + 0xe5, 0x7c, 0x54, 0xbc, 0x17, 0x1f, 0xd5, 0x31, + 0x0e, 0x88, 0xe7, 0xcd, 0xb0, 0xb5, 0x2e, 0x1e, + 0x9e, 0x40, 0x36, 0xa5, 0xbb, 0xa7, 0x4e, 0xc8, + 0x11, 0x6c, 0xae, 0x1c, 0x2d, 0xdb, 0x55, 0xd8, + 0x14, 0x40, 0x02, 0xad, 0xaf, 0x19, 0x28, 0x59, + 0xd7, 0x4f, 0x81, 0xd0, 0xc1, 0x54, 0x63, 0x73, + 0x0e, 0xfb, 0x26, 0xf2, 0xa6, 0x80, 0xca, 0x2e, + 0xf3, 0xca, 0x1e, 0xa4, 0x62, 0x07, 0x22, 0x10, + 0x11, 0x6a, 0x57, 0x28, 0x45, 0x80, 0xdf, 0x34, + 0x88, 0xe5, 0xf1, 0x23, 0xe0, 0xb6, 0x44, 0x51, + 0x54, 0xd8, 0xb3, 0x66, 0xac, 0x46, 0x4d, 0xdf, + 0xa2, 0x8e, 0x72, 0x3a, 0x1c, 0x87, 0x2a, 0x43, + 0xfe, 0xdb, 0x00, 0xff, 0xb7, 0x1c, 0x13, 0xc3, + 0x18, 0xfc, 0x71, 0x13, 0xe3, 0xd1, 0x1f, 0xde, + 0x16, 0x63, 0x73, 0xf5, 0x0e, 0xf7, 0x18, 0xe5, + 0x48, 0x8d, 0x30, 0xd9, 0x26, 0x20, 0x6d, 0xa1, + 0xba, 0xde, 0xe8, 0x7d, 0x77, 0x02, 0x33, 0x0d, + 0x73, 0xb2, 0xab, 0x35, 0xfd, 0xa5, 0x6e, 0x4c, + 0x5c, 0x27, 0xc7, 0x7e, 0x4a, 0x28, 0xf8, 0xf5, + 0x00, 0xbe, 0x4c, 0xd7, 0x2c, 0x27, 0x83, 0x16, + 0x37, 0xda, 0x0c, 0xb1, 0xd7, 0x89, 0xd8, 0x8f, + 0x17, 0x69, 0x1b, 0x6b, 0x48, 0x2b, 0xce, 0x9c, + 0xbd, 0xf4, 0x0d, 0xb5, 0x4d, 0x12, 0x11, 0x36, + 0x49, 0xd3, 0x8b, 0x52, 0xce, 0x7e, 0x47, 0xb0, + 0xb5, 0x54, 0x77, 0xef, 0x90, 0xb8, 0x0e, 0xaf, + 0x6f, 0x97, 0x88, 0xde, 0x6b, 0x37, 0x24, 0xdd, + 0x91, 0x84, 0x00, 0x51, 0xab, 0x06, 0x96, 0x3c, + 0x82, 0x73, 0xcf, 0xae, 0x8d, 0x23, 0x86, 0x59, + 0x62, 0x5b, 0xeb, 0x2a, 0xaf, 0x40, 0x17, 0xed, + 0x2b, 0x60, 0x73, 0x7d, 0x99, 0x95, 0x3f, 0xd6, + 0x6c, 0xca, 0x1e, 0xf3, 0xb0, 0xcd, 0xd5, 0x1d, + 0x53, 0xe0, 0xd2, 0x8b, 0x57, 0x7b, 0xac, 0x67, + 0x5a, 0x5a, 0x0a, 0x64, 0x82, 0xab, 0x8f, 0x5a, + 0x36, 0xe2, 0x45, 0x50, 0xec, 0x3e, 0x14, 0x80, + 0x7c, 0xfd, 0x0c, 0xa9, 0x94, 0xfb, 0xfe, 0x72, + 0xec, 0x47, 0x71, 0x2e, 0x90, 0x97, 0xf6, 0x33, + 0xbd, 0x7d, 0x7e, 0x77, 0x8f, 0xad, 0xd4, 0x1d, + 0x1d, 0x53, 0x0f, 0x28, 0x39, 0x77, 0x06, 0x1a, + 0x75, 0xfc, 0x12, 0xe6, 0x45, 0xfc, 0x87, 0xe1, + 0x46, 0xac, 0xb0, 0x73, 0xca, 0x24, 0x7c, 0x71, +}; + +/* + * IV method encblkno1, blkno 3. + */ +static const uint8_t c3des_cbc_192_encblkno1_vec3_ctxt[SECSIZE] = { + 0xb1, 0xef, 0x7c, 0xd0, 0xa0, 0x6b, 0xe4, 0x88, + 0x5c, 0xd7, 0xf1, 0xbf, 0x5f, 0xce, 0xda, 0x19, + 0x81, 0x32, 0xbb, 0x96, 0x7e, 0xb9, 0x6e, 0xa1, + 0x43, 0xde, 0x53, 0x66, 0x9c, 0x27, 0x94, 0x85, + 0xcb, 0x09, 0x4e, 0x16, 0xd8, 0x60, 0x7a, 0x38, + 0x27, 0x21, 0x4d, 0x08, 0xaa, 0xe2, 0x1e, 0x6e, + 0xa3, 0xcb, 0x9a, 0x7f, 0xd1, 0xbf, 0x18, 0x36, + 0x5a, 0x4d, 0x7a, 0x7f, 0xcf, 0x3f, 0xba, 0xa5, + 0x77, 0x5b, 0xb4, 0x79, 0xdc, 0xbf, 0x2a, 0x28, + 0x16, 0x27, 0x0f, 0x8b, 0xd7, 0x95, 0xc3, 0xcb, + 0xa1, 0x6a, 0x49, 0x53, 0xa8, 0x0c, 0x70, 0xde, + 0x90, 0x2e, 0x36, 0x74, 0x40, 0x5d, 0x81, 0x74, + 0x03, 0x11, 0xbd, 0xba, 0x40, 0x8d, 0x03, 0x86, + 0x2b, 0x17, 0x55, 0x20, 0xd8, 0x81, 0x30, 0xd2, + 0x2a, 0xbd, 0xea, 0xff, 0x5c, 0x69, 0x9b, 0xe6, + 0xe3, 0x21, 0x9a, 0x10, 0x3e, 0xb0, 0xf4, 0x7a, + 0xfc, 0x6e, 0x66, 0xec, 0x44, 0x0b, 0x95, 0x8d, + 0x13, 0xd4, 0xf6, 0x3e, 0xa1, 0xa1, 0xac, 0xb1, + 0xd8, 0x3d, 0x86, 0xaf, 0x5e, 0xef, 0x14, 0x6a, + 0x32, 0xf3, 0x13, 0x75, 0x3b, 0x64, 0x9a, 0xf4, + 0xd0, 0xf5, 0x00, 0x36, 0x9e, 0xdb, 0xfd, 0xcb, + 0xda, 0x1f, 0xed, 0x9d, 0x6d, 0x52, 0xd7, 0xb5, + 0x48, 0xce, 0x53, 0x5e, 0xdc, 0xc8, 0xe4, 0x96, + 0x04, 0x32, 0xa5, 0xcf, 0x0c, 0xba, 0xa0, 0xd0, + 0x44, 0xb3, 0xe8, 0x72, 0xc6, 0xff, 0x8f, 0xd4, + 0x4d, 0x0a, 0x22, 0x89, 0x74, 0x50, 0xaa, 0x65, + 0x15, 0xab, 0x99, 0xc8, 0xf9, 0xa4, 0x10, 0xe6, + 0xa6, 0x4b, 0x0c, 0xc8, 0xb9, 0xa7, 0x60, 0x41, + 0xe7, 0x57, 0x31, 0xfa, 0x86, 0x55, 0xdf, 0x29, + 0x49, 0xac, 0x55, 0x7b, 0x21, 0xf9, 0x3b, 0x1e, + 0x1f, 0xb4, 0x1c, 0x0b, 0x77, 0xcb, 0x88, 0xbf, + 0xa6, 0x79, 0xbf, 0x9a, 0x51, 0xc4, 0x8e, 0x59, + 0x9c, 0xb3, 0x9d, 0x9d, 0x6b, 0xb2, 0x15, 0x41, + 0x0d, 0x6c, 0xf7, 0x5e, 0xe2, 0xf9, 0xb3, 0x80, + 0x8f, 0x03, 0x67, 0x68, 0x6e, 0x4b, 0x4d, 0x52, + 0xbc, 0x9b, 0xa2, 0xd8, 0x29, 0x1e, 0x5c, 0xd7, + 0x59, 0x67, 0x94, 0x40, 0x9e, 0x08, 0x15, 0x0d, + 0x7e, 0xc9, 0x14, 0x53, 0xa8, 0x67, 0xb3, 0xb8, + 0xaa, 0x21, 0x0f, 0x79, 0x69, 0x48, 0x52, 0xea, + 0x56, 0x03, 0x7b, 0x55, 0xb7, 0xf3, 0xfe, 0xb1, + 0x8a, 0x22, 0x7d, 0x75, 0x55, 0x31, 0xad, 0x20, + 0x6a, 0xc2, 0xa4, 0xd1, 0x1e, 0xab, 0xdd, 0x29, + 0xb5, 0xf8, 0xdd, 0x9b, 0x1a, 0xb8, 0xe7, 0xde, + 0xae, 0xa1, 0xab, 0xbb, 0xf6, 0x00, 0x87, 0xc4, + 0x29, 0xee, 0x2b, 0xa1, 0xa9, 0x1a, 0x46, 0x05, + 0x5a, 0x12, 0x3f, 0x32, 0x81, 0x25, 0x20, 0x71, + 0xb6, 0xfa, 0x1f, 0x27, 0x2a, 0x33, 0x49, 0xfc, + 0x95, 0x00, 0x72, 0x6b, 0x03, 0x53, 0x94, 0x57, + 0x2f, 0x47, 0x3d, 0x2d, 0x7c, 0xb4, 0xde, 0xa7, + 0x96, 0x81, 0x12, 0xff, 0x2c, 0xec, 0x5c, 0x03, + 0x2a, 0x8c, 0x76, 0xc4, 0xed, 0x09, 0xe6, 0x00, + 0x28, 0xdb, 0x9b, 0x44, 0xb0, 0xb4, 0x7b, 0x57, + 0x3b, 0xb6, 0x4f, 0x0b, 0xff, 0xf2, 0xf5, 0x02, + 0x56, 0xcf, 0xd5, 0xbf, 0x71, 0xe6, 0x66, 0xf3, + 0x08, 0x8e, 0x8b, 0x15, 0x57, 0x07, 0x41, 0xa3, + 0x91, 0xc1, 0xe4, 0x64, 0x92, 0x89, 0xed, 0x22, + 0x88, 0x8f, 0x17, 0x91, 0xde, 0xea, 0x0c, 0xa6, + 0x86, 0x8e, 0x4c, 0xd9, 0x63, 0xc9, 0xe5, 0xdc, + 0xd6, 0xd3, 0x7b, 0x2b, 0x65, 0xfa, 0x36, 0x47, + 0x20, 0xa4, 0xe7, 0x0b, 0x52, 0xfa, 0xa6, 0xeb, + 0x1d, 0x20, 0xd0, 0x4b, 0xfd, 0x88, 0x8c, 0xbb, + 0x52, 0x9c, 0x2f, 0xb7, 0xba, 0x8b, 0xdd, 0x10, + 0x2d, 0x7d, 0x77, 0x79, 0x40, 0xa7, 0xed, 0xf9, + 0xbd, 0x2a, 0x55, 0x1f, 0x87, 0x1e, 0x3c, 0xfc, +}; + +const struct testvec c3des_cbc_192_1_vectors[] = { + { + .blkno = 0, + .ptxt = c3des_cbc_ptxt, + .ctxt = c3des_cbc_192_encblkno1_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = c3des_cbc_ptxt, + .ctxt = c3des_cbc_192_encblkno1_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = c3des_cbc_ptxt, + .ctxt = c3des_cbc_192_encblkno1_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = c3des_cbc_ptxt, + .ctxt = c3des_cbc_192_encblkno1_vec3_ctxt, + }, +}; + +/* + * IV method encblkno8, blkno 0. + */ +static const uint8_t c3des_cbc_192_encblkno8_vec0_ctxt[SECSIZE] = { + 0x9e, 0x5d, 0x35, 0x56, 0xa7, 0xcc, 0xc0, 0x1c, + 0x60, 0x4c, 0x42, 0x90, 0x35, 0xf3, 0xc1, 0x20, + 0xf2, 0x07, 0x6f, 0xf8, 0x7c, 0x33, 0x6a, 0x74, + 0xdc, 0x85, 0xbc, 0x9c, 0xa2, 0x29, 0xc6, 0x69, + 0x0e, 0xef, 0x0f, 0xa9, 0x6e, 0xec, 0xf2, 0x23, + 0x2f, 0x9a, 0xbe, 0x1a, 0x89, 0x22, 0x00, 0xc4, + 0x5a, 0xaf, 0x4a, 0xa0, 0x4f, 0x30, 0x8f, 0x99, + 0xd2, 0x93, 0x6d, 0xfa, 0xcd, 0x2f, 0xad, 0x19, + 0x10, 0x14, 0x90, 0x3a, 0x4b, 0xab, 0x17, 0x2e, + 0x2c, 0xe1, 0x26, 0xe5, 0x76, 0xf1, 0xd1, 0x1d, + 0x4c, 0x77, 0x68, 0xfb, 0x45, 0x9a, 0x3e, 0x19, + 0xe0, 0xfb, 0xdc, 0xd4, 0x0e, 0x29, 0x7c, 0x06, + 0xd3, 0x45, 0xa8, 0xf7, 0x39, 0x91, 0xe6, 0x18, + 0x0f, 0x81, 0xe6, 0x7d, 0x6c, 0x65, 0x2e, 0x16, + 0x24, 0xa4, 0x16, 0x96, 0x0a, 0x7b, 0x5f, 0x3a, + 0x0c, 0xe9, 0x0e, 0x3f, 0x34, 0x38, 0xb0, 0xe1, + 0x39, 0x23, 0x5c, 0x3c, 0x00, 0xb4, 0xa0, 0xf7, + 0x42, 0x18, 0x70, 0x25, 0x82, 0x13, 0x24, 0x49, + 0xbb, 0x3f, 0xfb, 0xef, 0xb6, 0xc6, 0x7f, 0x3d, + 0x8c, 0x17, 0x62, 0x60, 0x6f, 0xd5, 0xda, 0x2c, + 0xf8, 0x85, 0xee, 0xa7, 0xc2, 0x76, 0x5d, 0x34, + 0x4c, 0xe1, 0x0d, 0x36, 0x6e, 0x02, 0xdd, 0x08, + 0x85, 0xe4, 0x90, 0xfe, 0x1f, 0x81, 0x4a, 0x06, + 0xa6, 0x72, 0x81, 0x79, 0x47, 0xd7, 0x6d, 0x92, + 0x8f, 0xb7, 0xb2, 0xfd, 0xd0, 0x60, 0x6c, 0x06, + 0x44, 0xcd, 0x20, 0x28, 0xef, 0x16, 0xc3, 0x01, + 0x19, 0x14, 0x34, 0x39, 0xad, 0x87, 0x9f, 0xde, + 0x76, 0xb9, 0xb9, 0x87, 0x1a, 0xbd, 0x8e, 0x2c, + 0xe6, 0xb3, 0xe7, 0xb6, 0x80, 0xf8, 0xc5, 0x22, + 0x5f, 0x53, 0xed, 0x03, 0xfe, 0x09, 0x2c, 0x9d, + 0xb6, 0x61, 0x4a, 0xbb, 0x07, 0x5d, 0xbd, 0x68, + 0x74, 0xab, 0x02, 0x81, 0x64, 0x7b, 0x97, 0xa3, + 0xad, 0x15, 0x99, 0x7a, 0x04, 0x33, 0xbd, 0x50, + 0x94, 0x11, 0xcc, 0xf7, 0x8b, 0x77, 0x88, 0x78, + 0x80, 0xfe, 0x5f, 0xa1, 0x63, 0xbc, 0xb0, 0x65, + 0xcb, 0x9d, 0x4c, 0xfe, 0x66, 0x4e, 0xff, 0xe3, + 0x43, 0x61, 0x99, 0x88, 0x88, 0x4c, 0xbc, 0x8a, + 0xf1, 0x69, 0x00, 0xc2, 0xe5, 0xb9, 0x65, 0x8b, + 0x10, 0xdf, 0x38, 0x3e, 0x9e, 0x9f, 0x87, 0xed, + 0x84, 0x71, 0xe7, 0xf2, 0xb5, 0xb6, 0x11, 0xed, + 0x1e, 0xd4, 0xc0, 0x6d, 0x77, 0x08, 0x4b, 0xfd, + 0x95, 0xd5, 0xc0, 0xbe, 0xa6, 0xcc, 0x3b, 0xea, + 0x11, 0x38, 0xa5, 0x59, 0x36, 0x2a, 0xf4, 0x98, + 0x52, 0x9d, 0x3b, 0x8c, 0x8a, 0x19, 0xbd, 0xfb, + 0x49, 0xcb, 0xb0, 0x57, 0x91, 0xc7, 0xf8, 0x2a, + 0x89, 0xa8, 0x85, 0x03, 0xdf, 0x6e, 0xad, 0xf4, + 0x8a, 0x88, 0x9a, 0x2b, 0x5d, 0xe8, 0xca, 0xa9, + 0x8f, 0x18, 0xa3, 0x6a, 0x37, 0x84, 0xa9, 0x24, + 0x5b, 0xce, 0xd6, 0xbe, 0x7e, 0x40, 0x86, 0x6a, + 0xc3, 0x47, 0x28, 0x66, 0xf0, 0x8c, 0x2d, 0x69, + 0x22, 0x64, 0x61, 0x36, 0x6a, 0x0c, 0xc4, 0x18, + 0x5f, 0xd7, 0xff, 0xbc, 0xf1, 0x94, 0x16, 0xfb, + 0x26, 0xa7, 0x80, 0xa4, 0x2d, 0x72, 0xc6, 0x9d, + 0xa7, 0xed, 0x04, 0x13, 0x0f, 0xe7, 0xf8, 0x93, + 0x57, 0x6b, 0xd5, 0xa4, 0xad, 0x9a, 0x97, 0xeb, + 0x97, 0xe7, 0x60, 0x01, 0x89, 0x3f, 0x88, 0xf2, + 0xee, 0xf3, 0x79, 0xd6, 0x5a, 0x03, 0x94, 0x07, + 0xd3, 0x33, 0xc8, 0xda, 0x15, 0x17, 0x0a, 0x8f, + 0xbd, 0x58, 0x1b, 0xfe, 0x3d, 0x77, 0x5d, 0x8f, + 0x4e, 0x0e, 0x98, 0x7d, 0x02, 0x63, 0x94, 0x73, + 0x4a, 0x58, 0x47, 0xed, 0x52, 0xfc, 0x85, 0x19, + 0x5d, 0x2f, 0xfa, 0x07, 0x44, 0xbd, 0x8e, 0xcb, + 0x20, 0x63, 0x9d, 0x2b, 0x61, 0x5c, 0x19, 0x71, + 0x80, 0xe5, 0x25, 0x5b, 0x2e, 0xc5, 0xfe, 0x1a, +}; + +/* + * IV method encblkno8, blkno 1. + */ +static const uint8_t c3des_cbc_192_encblkno8_vec1_ctxt[SECSIZE] = { + 0xf4, 0xb0, 0xb0, 0xcb, 0x79, 0xcc, 0x8c, 0x0a, + 0x3b, 0xc7, 0x43, 0x4e, 0x62, 0x9d, 0xde, 0xb4, + 0xab, 0xa5, 0x62, 0x63, 0x32, 0xa7, 0x18, 0x2b, + 0xe3, 0xee, 0x44, 0xc6, 0x6f, 0xb2, 0xdc, 0x21, + 0xc5, 0xc8, 0x9e, 0x32, 0x71, 0x4c, 0x7a, 0x82, + 0x8d, 0xe0, 0xad, 0x91, 0x88, 0x0c, 0x41, 0x83, + 0x28, 0x0d, 0xed, 0xa7, 0xeb, 0x48, 0xb1, 0x31, + 0xfa, 0x40, 0xd9, 0x44, 0x19, 0xee, 0x8d, 0x2c, + 0x7d, 0xe2, 0x39, 0xa0, 0x39, 0xaa, 0x86, 0xab, + 0xb5, 0x68, 0xe5, 0x83, 0x06, 0x61, 0xec, 0xe6, + 0xc2, 0x85, 0xb2, 0x46, 0xf4, 0x5b, 0x0e, 0x34, + 0x7e, 0x0c, 0xa0, 0xda, 0xef, 0x58, 0x9c, 0x39, + 0x95, 0xa2, 0xca, 0xd3, 0x3b, 0x4d, 0x76, 0xe3, + 0x34, 0x6d, 0x08, 0xa4, 0xba, 0x88, 0x58, 0x39, + 0xb4, 0xe4, 0x6b, 0xb6, 0x32, 0x50, 0x2c, 0xe2, + 0x0a, 0x37, 0xbc, 0x98, 0x38, 0x32, 0x17, 0x1b, + 0x12, 0xef, 0xdc, 0x9d, 0x91, 0x09, 0x8e, 0xd8, + 0xc3, 0xf8, 0x7b, 0x35, 0x41, 0x3b, 0xf8, 0xf5, + 0x37, 0x48, 0x04, 0xf7, 0x94, 0xbf, 0x54, 0x8d, + 0x79, 0x49, 0x8f, 0xf0, 0x3f, 0xb7, 0x90, 0x76, + 0x14, 0x09, 0xc6, 0x8c, 0xba, 0x1a, 0x30, 0x1b, + 0xbb, 0xd9, 0xe2, 0xb5, 0xe8, 0xd9, 0x9b, 0x68, + 0x60, 0x90, 0xd3, 0x4a, 0xe8, 0x65, 0x7b, 0xaa, + 0xb0, 0xda, 0x69, 0x1d, 0x45, 0x78, 0x2c, 0x3b, + 0x59, 0x29, 0x3c, 0x26, 0x9a, 0xd2, 0xa5, 0xfd, + 0xb7, 0x16, 0x59, 0x7c, 0x46, 0xea, 0x99, 0xd0, + 0x06, 0x01, 0x3f, 0xd2, 0x23, 0xcc, 0xde, 0xb8, + 0xaa, 0x88, 0x17, 0x03, 0xe1, 0x48, 0x2c, 0xdd, + 0xce, 0xd1, 0x2c, 0xce, 0x37, 0xee, 0xe6, 0xa6, + 0x47, 0x8c, 0x07, 0xe5, 0xfe, 0x01, 0xc6, 0x27, + 0xfe, 0x3f, 0x9d, 0x30, 0x18, 0x36, 0xe7, 0xa7, + 0x37, 0x1d, 0xcf, 0x6d, 0x4c, 0x82, 0xec, 0x58, + 0xa1, 0x6f, 0x56, 0xc6, 0x08, 0x25, 0x94, 0xda, + 0xae, 0x1a, 0x4f, 0xda, 0xb2, 0xf4, 0xbf, 0x94, + 0xff, 0x66, 0x6a, 0xb1, 0x1f, 0x42, 0xfe, 0x32, + 0xa4, 0x0e, 0x3d, 0x6a, 0x16, 0x44, 0xe0, 0xac, + 0xe8, 0xc1, 0xe2, 0xa8, 0x73, 0xab, 0xac, 0x58, + 0xb1, 0xbc, 0x94, 0xb2, 0x6a, 0xe4, 0x45, 0xf5, + 0x90, 0x6b, 0x82, 0xeb, 0x9e, 0x22, 0x9e, 0xb2, + 0x27, 0x3e, 0xc8, 0x55, 0xf4, 0x8f, 0xda, 0x04, + 0xa3, 0x9c, 0xa4, 0x79, 0xbd, 0x79, 0xd3, 0xbd, + 0xbe, 0x72, 0x7f, 0x90, 0xef, 0xc3, 0x34, 0x17, + 0x72, 0x6f, 0xb4, 0xfe, 0x62, 0x56, 0xc3, 0xd6, + 0x43, 0xc8, 0x4c, 0x76, 0x91, 0x04, 0x97, 0x4c, + 0x84, 0x98, 0x56, 0xb7, 0x7b, 0x4f, 0xd5, 0xcf, + 0x1b, 0x9c, 0x09, 0xe3, 0x1d, 0xdf, 0x0e, 0xfa, + 0x39, 0xc8, 0x48, 0x43, 0x84, 0xec, 0x79, 0xc8, + 0x7f, 0x4f, 0xa8, 0xc0, 0xb4, 0xde, 0x8b, 0x79, + 0xcb, 0x9c, 0x42, 0x81, 0x49, 0xdc, 0x39, 0xb5, + 0x31, 0xa6, 0x22, 0xba, 0x71, 0xb8, 0x2d, 0x1d, + 0xc8, 0x17, 0xd8, 0x9d, 0x26, 0x2b, 0xd5, 0xcf, + 0x57, 0x46, 0x0a, 0x61, 0x7e, 0xb7, 0xc3, 0x9c, + 0xa6, 0x44, 0x60, 0x2d, 0x30, 0xb8, 0x10, 0x47, + 0x7d, 0x7e, 0x87, 0x76, 0xc1, 0x4e, 0x85, 0x77, + 0xbc, 0x30, 0x32, 0x56, 0x0a, 0x5b, 0x1c, 0xd0, + 0xf6, 0x47, 0x48, 0x22, 0xf4, 0x6e, 0x38, 0xc5, + 0xab, 0xe2, 0xd0, 0x4d, 0x40, 0x27, 0xab, 0x8f, + 0x43, 0xb1, 0x60, 0x29, 0x07, 0xd0, 0xf5, 0x25, + 0xe5, 0xfa, 0xe7, 0x46, 0x32, 0x37, 0xb9, 0xae, + 0x2e, 0x02, 0x8c, 0x94, 0x15, 0x69, 0xd6, 0x74, + 0xb4, 0x36, 0xdd, 0x94, 0x70, 0xa7, 0x16, 0x7b, + 0x4c, 0xd3, 0x48, 0x83, 0xc5, 0xb2, 0xb0, 0x6a, + 0xfe, 0x7e, 0xd4, 0xe5, 0x6d, 0xa5, 0x96, 0x20, + 0x08, 0x59, 0xbd, 0x0c, 0x3d, 0x55, 0xa5, 0x03, +}; + +/* + * IV method encblkno8, blkno 2. + */ +static const uint8_t c3des_cbc_192_encblkno8_vec2_ctxt[SECSIZE] = { + 0xea, 0x7c, 0x8c, 0x8e, 0x3e, 0x61, 0x34, 0x3d, + 0xe0, 0x7f, 0xd3, 0xe1, 0x3a, 0xb9, 0xc8, 0xf2, + 0x98, 0xdc, 0x59, 0x26, 0xd2, 0xd8, 0xa7, 0x7f, + 0x41, 0x98, 0x24, 0xa8, 0x28, 0x0c, 0x88, 0x55, + 0x91, 0xdb, 0x29, 0x17, 0x70, 0xd7, 0x03, 0xff, + 0xbd, 0x0e, 0xbf, 0xf8, 0x73, 0x92, 0x19, 0xe9, + 0x92, 0x67, 0xdb, 0x08, 0x94, 0x77, 0x71, 0x2d, + 0x00, 0xad, 0x26, 0x42, 0x2d, 0xac, 0x8c, 0x67, + 0x6f, 0xb3, 0x8e, 0x36, 0x22, 0xeb, 0x1f, 0x8c, + 0xd4, 0x9b, 0x9f, 0xa6, 0xa9, 0xb1, 0x52, 0x65, + 0x9a, 0xfe, 0xcc, 0x92, 0x48, 0x75, 0xf6, 0xb8, + 0x59, 0xfe, 0x0e, 0x67, 0x93, 0xce, 0x3b, 0x7e, + 0x51, 0x74, 0xe5, 0x24, 0x35, 0x08, 0x68, 0x21, + 0x6a, 0x7f, 0xdd, 0x8c, 0xfd, 0xcd, 0x6d, 0x90, + 0xc5, 0x3b, 0x26, 0x9e, 0x00, 0xf4, 0x1e, 0x70, + 0xd3, 0xe7, 0xe8, 0x2f, 0x52, 0x87, 0x76, 0x84, + 0xbb, 0x5c, 0x76, 0x5a, 0xc8, 0xea, 0x74, 0xe2, + 0x9e, 0x85, 0xf6, 0x53, 0x85, 0x1a, 0x6e, 0x02, + 0x0d, 0x32, 0x11, 0xc4, 0xec, 0xee, 0x79, 0x27, + 0xda, 0xca, 0xc0, 0x0b, 0x8e, 0x2d, 0xb7, 0x7d, + 0x8c, 0x6e, 0xfb, 0xa3, 0xa8, 0x24, 0x24, 0x62, + 0xc8, 0xdd, 0xc7, 0x16, 0x09, 0x33, 0x0f, 0xe5, + 0xc8, 0x60, 0x3d, 0xb6, 0xbf, 0x6c, 0x28, 0xd2, + 0x0b, 0x9c, 0xd9, 0xcb, 0x64, 0x49, 0xe4, 0x80, + 0x72, 0x58, 0xaa, 0xaa, 0x7e, 0x1d, 0x9f, 0xd7, + 0x29, 0x15, 0x65, 0xfc, 0xfd, 0x3f, 0xe1, 0x82, + 0x25, 0x3c, 0xd4, 0xbe, 0x59, 0x79, 0x63, 0xd1, + 0xd6, 0x0e, 0xda, 0x00, 0xf3, 0xaa, 0x13, 0xd3, + 0xed, 0xef, 0xca, 0x8b, 0x97, 0x15, 0x2d, 0x10, + 0x6f, 0xcf, 0xee, 0xc7, 0x21, 0xad, 0xe3, 0xe4, + 0xd8, 0x95, 0x21, 0x1f, 0xc0, 0x06, 0x3a, 0xbc, + 0xbb, 0x2a, 0x92, 0x78, 0x76, 0x9d, 0x1e, 0x7b, + 0xb5, 0x29, 0xaf, 0x96, 0x75, 0x2b, 0x41, 0xbd, + 0xae, 0x79, 0x28, 0x72, 0xe7, 0x54, 0xc4, 0x08, + 0xd3, 0xd2, 0xac, 0x96, 0xd0, 0x0f, 0x9b, 0x68, + 0x7d, 0x3f, 0xc2, 0xdd, 0x3d, 0xfc, 0xca, 0xcd, + 0x11, 0x71, 0xd9, 0x48, 0x53, 0x9f, 0xd3, 0x79, + 0x7d, 0x47, 0x71, 0x2a, 0x6d, 0x9e, 0xa9, 0x47, + 0xa1, 0xf7, 0x97, 0x80, 0x83, 0x70, 0x6b, 0xfe, + 0x10, 0x11, 0x6a, 0x0e, 0xdd, 0xde, 0x22, 0x3c, + 0x19, 0x30, 0x73, 0x73, 0x2e, 0x4b, 0x54, 0x17, + 0xc3, 0x2e, 0xe9, 0xce, 0xe0, 0xe3, 0xa0, 0x1a, + 0x28, 0xd1, 0x50, 0xa8, 0xd2, 0x40, 0xe2, 0x1b, + 0xfa, 0x49, 0x06, 0x49, 0x8b, 0x4b, 0xd9, 0xd5, + 0xf5, 0x50, 0xae, 0x64, 0x19, 0xe1, 0xd9, 0x4e, + 0xbb, 0x29, 0x70, 0x66, 0x46, 0xa8, 0x7e, 0x5b, + 0xdc, 0xe2, 0xd5, 0x9d, 0x56, 0x6d, 0x4c, 0xe6, + 0x0e, 0x6b, 0x71, 0x40, 0x82, 0xf7, 0xb3, 0xad, + 0x23, 0x17, 0xe3, 0x1c, 0x61, 0x1d, 0x3b, 0x71, + 0xfc, 0x06, 0x17, 0xec, 0x6c, 0x77, 0x98, 0x27, + 0xc7, 0x4b, 0x65, 0x17, 0x81, 0xe7, 0xcb, 0xce, + 0x09, 0x76, 0x82, 0x82, 0x4a, 0x53, 0x67, 0xa0, + 0x05, 0x25, 0x4c, 0xc4, 0xa7, 0xad, 0xa7, 0xaf, + 0xa0, 0x11, 0xd7, 0x73, 0x3b, 0x30, 0xbf, 0x53, + 0x50, 0x9b, 0xd8, 0xf3, 0x32, 0x15, 0xdd, 0x36, + 0x88, 0xc2, 0x39, 0x51, 0xb6, 0xb8, 0x0d, 0x5c, + 0x20, 0x4e, 0x24, 0xee, 0x95, 0x32, 0x61, 0x25, + 0xda, 0x73, 0x0d, 0x8a, 0x58, 0xe6, 0xcc, 0xad, + 0x79, 0x3d, 0xef, 0x29, 0x0c, 0x9f, 0xe1, 0xa7, + 0x22, 0x1e, 0xea, 0x7a, 0x4f, 0xfb, 0xc1, 0x1f, + 0x17, 0xca, 0x69, 0xd6, 0xa4, 0xce, 0x6e, 0xc0, + 0x70, 0xa3, 0x08, 0x32, 0x87, 0xb4, 0x6b, 0x80, + 0x5c, 0x7f, 0x88, 0x5c, 0xbf, 0x07, 0xd8, 0xe9, + 0xdd, 0xd2, 0x76, 0xa9, 0xaa, 0xd9, 0x55, 0x48, +}; + +/* + * IV method encblkno8, blkno 3. + */ +static const uint8_t c3des_cbc_192_encblkno8_vec3_ctxt[SECSIZE] = { + 0xf3, 0x49, 0xda, 0x5c, 0xde, 0x9d, 0x3e, 0x9d, + 0xb9, 0xc2, 0x6e, 0x96, 0xa9, 0x93, 0x10, 0x73, + 0x0e, 0x26, 0x39, 0xd6, 0x9f, 0x04, 0x5f, 0x69, + 0x54, 0xa3, 0x7c, 0x46, 0x7b, 0x18, 0x93, 0xc0, + 0xbb, 0x0c, 0x96, 0x6f, 0xb0, 0xbf, 0xce, 0x67, + 0x33, 0x3e, 0x56, 0xe8, 0x6b, 0x4d, 0x3f, 0xc8, + 0x3c, 0xc6, 0x89, 0x2c, 0x0b, 0x95, 0x3a, 0xaf, + 0xc0, 0xf3, 0x1f, 0x0e, 0x07, 0x01, 0xa6, 0x35, + 0x19, 0x79, 0x91, 0x24, 0xaa, 0x0d, 0xf0, 0x53, + 0x27, 0x7d, 0xbb, 0xa6, 0xb6, 0x44, 0x31, 0x4b, + 0xd4, 0xcf, 0xf6, 0x6d, 0x18, 0xa2, 0x28, 0x8a, + 0xc1, 0x0a, 0xbe, 0x57, 0x0c, 0x61, 0x5f, 0xd9, + 0x12, 0x14, 0xfe, 0xe2, 0xc7, 0x10, 0x72, 0xee, + 0x19, 0xb8, 0x16, 0x0b, 0x88, 0x87, 0xce, 0xf3, + 0xfe, 0x57, 0x37, 0xd1, 0xa2, 0xf7, 0xd0, 0x5e, + 0x73, 0xde, 0x39, 0x35, 0xbc, 0xde, 0xed, 0x61, + 0x4b, 0x31, 0xdc, 0xfe, 0x3c, 0x4d, 0x98, 0xa9, + 0x36, 0xb0, 0x34, 0x5b, 0xb4, 0xb7, 0x79, 0x25, + 0x6e, 0x24, 0x7e, 0x10, 0xfe, 0x20, 0xd5, 0x16, + 0x86, 0xaf, 0xcd, 0x26, 0x34, 0xd3, 0x2e, 0xdc, + 0x7c, 0x69, 0xe3, 0xc5, 0x62, 0x0c, 0xba, 0x29, + 0x9c, 0x4b, 0x2f, 0x39, 0x45, 0xe1, 0xcf, 0xc5, + 0xfe, 0x35, 0xb6, 0x2f, 0xb1, 0x1a, 0x90, 0xe1, + 0xa7, 0x39, 0xe8, 0x1e, 0x5f, 0xac, 0xab, 0x1e, + 0x32, 0xba, 0xc5, 0x92, 0x39, 0x62, 0x37, 0x2c, + 0x49, 0xf1, 0x62, 0x90, 0xf7, 0x1e, 0x10, 0xce, + 0x8e, 0x95, 0xa3, 0xc6, 0xd8, 0xe5, 0xc8, 0xdf, + 0xcc, 0x94, 0x7d, 0x26, 0xab, 0x29, 0xbb, 0x9d, + 0xf3, 0x73, 0xce, 0xac, 0x76, 0xdf, 0x75, 0x2a, + 0x3e, 0x8f, 0x47, 0xff, 0x76, 0xfe, 0xea, 0xd4, + 0x4a, 0xa9, 0x36, 0x9d, 0x12, 0x45, 0xb7, 0x99, + 0x81, 0xb6, 0x77, 0x98, 0x13, 0xfb, 0x5a, 0xe5, + 0x40, 0x87, 0x61, 0x0d, 0x10, 0x76, 0xf6, 0x3e, + 0x48, 0xac, 0xc4, 0x27, 0x87, 0xcd, 0x07, 0xde, + 0x0b, 0x23, 0x97, 0x61, 0x3d, 0x18, 0x64, 0x7f, + 0xbf, 0xd6, 0x87, 0xc1, 0x11, 0xfb, 0xf9, 0xda, + 0x14, 0xa1, 0x01, 0xf8, 0x7e, 0xea, 0x5b, 0x5b, + 0xdd, 0x09, 0xf9, 0x31, 0x80, 0x3c, 0xee, 0x34, + 0x2d, 0xda, 0x71, 0xd9, 0x32, 0x7d, 0x45, 0xb2, + 0x53, 0xea, 0xd5, 0x7c, 0x85, 0x45, 0xce, 0x1d, + 0x2b, 0xe9, 0xd7, 0x95, 0xf8, 0x8c, 0x08, 0xe4, + 0xd0, 0x2f, 0x60, 0x75, 0x02, 0xf3, 0xde, 0xeb, + 0x46, 0x40, 0xa8, 0xd2, 0x37, 0xd6, 0xca, 0x5d, + 0xb9, 0xf4, 0x51, 0x31, 0x8a, 0x1a, 0x82, 0xbd, + 0x6f, 0x6d, 0x88, 0x2b, 0x63, 0x0f, 0xe1, 0xf0, + 0xcf, 0x13, 0x79, 0x1d, 0x78, 0x82, 0x66, 0xa1, + 0xef, 0xdb, 0x34, 0x50, 0xd2, 0x71, 0x47, 0x49, + 0x41, 0x74, 0xd9, 0x0b, 0x14, 0x38, 0x1f, 0xc3, + 0x09, 0x4d, 0xb3, 0xa6, 0x03, 0x3f, 0x56, 0x67, + 0xd7, 0x51, 0x4c, 0x8a, 0x1d, 0x37, 0x99, 0xfb, + 0xe1, 0x84, 0x57, 0x55, 0x9b, 0xf8, 0x73, 0x63, + 0x68, 0x73, 0x89, 0x52, 0x06, 0xe7, 0x34, 0xe7, + 0x1a, 0x15, 0x7e, 0xd9, 0x84, 0xa3, 0x0e, 0x68, + 0x14, 0x1c, 0xe8, 0x23, 0x9e, 0xe3, 0x8f, 0x71, + 0x02, 0x9b, 0x87, 0xd4, 0xd9, 0x1b, 0xd1, 0x9e, + 0x9e, 0xa0, 0x7e, 0x49, 0x8e, 0xaa, 0x89, 0xb5, + 0x16, 0x48, 0x07, 0xb3, 0x3d, 0x9e, 0x4c, 0x35, + 0x3e, 0x94, 0xa9, 0xf8, 0x82, 0x50, 0x6a, 0x41, + 0x28, 0x3e, 0x9f, 0x9a, 0x1a, 0x5d, 0x02, 0x7c, + 0xd0, 0x32, 0x52, 0xa5, 0xee, 0x09, 0x27, 0x2d, + 0x49, 0x17, 0xf7, 0x92, 0xa1, 0x63, 0x9d, 0x2a, + 0xfd, 0x53, 0x26, 0x14, 0x7c, 0x92, 0x72, 0xa6, + 0x38, 0x18, 0x8f, 0xb5, 0x54, 0xb3, 0x69, 0x63, + 0x6a, 0xdc, 0xb1, 0x5a, 0x12, 0x7a, 0x0b, 0xa3, +}; + +const struct testvec c3des_cbc_192_8_vectors[] = { + { + .blkno = 0, + .ptxt = c3des_cbc_ptxt, + .ctxt = c3des_cbc_192_encblkno8_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = c3des_cbc_ptxt, + .ctxt = c3des_cbc_192_encblkno8_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = c3des_cbc_ptxt, + .ctxt = c3des_cbc_192_encblkno8_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = c3des_cbc_ptxt, + .ctxt = c3des_cbc_192_encblkno8_vec3_ctxt, + }, +}; + +static int +open_disk(const char *devpath, const char *imgpath, size_t size) +{ + int fd; + + fd = open(imgpath, O_CREAT | O_RDWR | O_TRUNC, 0600); + if (fd < 0) + return -1; + + if (ftruncate(fd, size) < 0) + goto fail; + + if (rump_pub_etfs_register_withsize(devpath, + imgpath, RUMP_ETFS_BLK, 0, size) < 0) { + goto fail; + } + + unlink(imgpath); + return fd; +fail: + close(fd); + unlink(imgpath); + return -1; +} + +static int +open_cgd(int devno) +{ + char devpath[32]; + + sprintf(devpath, "/dev/rcgd%d%c", devno, getrawpartition() + 'a'); + + return rump_sys_open(devpath, O_RDWR, 0); +} + +static int +configure_cgd(int fd, const char *dkpath, const char *alg, + const char *ivmethod, const char *key, size_t keylen) +{ + struct cgd_ioctl ci; + + memset(&ci, 0, sizeof(ci)); + ci.ci_disk = dkpath; + ci.ci_alg = alg; + ci.ci_ivmethod = ivmethod; + ci.ci_keylen = 8 * keylen - 8; /* Exclude the NUL terminator. */ + ci.ci_key = key; + ci.ci_blocksize = 64; + + return rump_sys_ioctl(fd, CGDIOCSET, &ci); +} + +static int +unconfigure_cgd(int fd) +{ + struct cgd_ioctl ci; + + return rump_sys_ioctl(fd, CGDIOCCLR, &ci); +} + +static int +write_testvec(int cgdfd, const struct testvec *tv) +{ + + if (rump_sys_lseek(cgdfd, tv->blkno * SECSIZE, SEEK_SET) < 0) + return -1; + + if (rump_sys_write(cgdfd, tv->ptxt, SECSIZE) != SECSIZE) + return -1; + + return 0; +} + +static int +read_testvec(int cgdfd, const struct testvec *tv) +{ + char *buf; + int res = -1; + + buf = malloc(SECSIZE); + if (buf == NULL) + return -1; + + if (rump_sys_lseek(cgdfd, tv->blkno * SECSIZE, SEEK_SET) < 0) + goto fail; + + if (rump_sys_read(cgdfd, buf, SECSIZE) != SECSIZE) + goto fail; + + res = memcmp(buf, tv->ptxt, SECSIZE); +fail: + free(buf); + return res; +} + +static int +check_testvec(int dkfd, const struct testvec *tv) +{ + char *buf; + int res = -1; + + buf = malloc(SECSIZE); + if (buf == NULL) + return -1; + + if (lseek(dkfd, tv->blkno * SECSIZE, SEEK_SET) < 0) + goto fail; + + if (read(dkfd, buf, SECSIZE) != SECSIZE) + goto fail; + + res = memcmp(buf, tv->ctxt, SECSIZE); +fail: + free(buf); + return res; +} + +ATF_TC(cgd_3des_cbc_192_encblkno1); +ATF_TC_HEAD(cgd_3des_cbc_192_encblkno1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test 3des-cbc with 192 bits key, ivmethod encblkno1"); +} + +ATF_TC_BODY(cgd_3des_cbc_192_encblkno1, tc) +{ + const char imgpath[] = "3des-cbc-192-encblkno1.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "3des-cbc", "encblkno1", + c3des_cbc_192_key, sizeof(c3des_cbc_192_key))); + + ATF_CHECK_EQ(write_testvec(cgdfd, &c3des_cbc_192_1_vectors[0]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &c3des_cbc_192_1_vectors[1]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &c3des_cbc_192_1_vectors[2]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &c3des_cbc_192_1_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "3des-cbc", "encblkno1", + c3des_cbc_192_key, sizeof(c3des_cbc_192_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &c3des_cbc_192_1_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &c3des_cbc_192_1_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &c3des_cbc_192_1_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &c3des_cbc_192_1_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &c3des_cbc_192_1_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &c3des_cbc_192_1_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &c3des_cbc_192_1_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &c3des_cbc_192_1_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_3des_cbc_192_encblkno8); +ATF_TC_HEAD(cgd_3des_cbc_192_encblkno8, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test 3des-cbc with 192 bits key, ivmethod encblkno8"); +} + +ATF_TC_BODY(cgd_3des_cbc_192_encblkno8, tc) +{ + const char imgpath[] = "3des-cbc-192-encblkno8.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "3des-cbc", "encblkno8", + c3des_cbc_192_key, sizeof(c3des_cbc_192_key))); + + ATF_CHECK_EQ(write_testvec(cgdfd, &c3des_cbc_192_8_vectors[0]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &c3des_cbc_192_8_vectors[1]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &c3des_cbc_192_8_vectors[2]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &c3des_cbc_192_8_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "3des-cbc", "encblkno8", + c3des_cbc_192_key, sizeof(c3des_cbc_192_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &c3des_cbc_192_8_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &c3des_cbc_192_8_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &c3des_cbc_192_8_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &c3des_cbc_192_8_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &c3des_cbc_192_8_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &c3des_cbc_192_8_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &c3des_cbc_192_8_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &c3des_cbc_192_8_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cgd_3des_cbc_192_encblkno1); + ATF_TP_ADD_TC(tp, cgd_3des_cbc_192_encblkno8); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/dev/cgd/t_cgd_aes.c b/contrib/netbsd-tests/dev/cgd/t_cgd_aes.c new file mode 100644 index 0000000..edda1eb --- /dev/null +++ b/contrib/netbsd-tests/dev/cgd/t_cgd_aes.c @@ -0,0 +1,3606 @@ +/* $NetBSD: t_cgd_aes.c,v 1.6 2017/01/13 21:30:39 christos Exp $ */ +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * Copyright (c) 2007 The Institute of Electrical and Electronics Engineers, Inc + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Alexander Nasonov. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_macros.h" + +#define SECSIZE 512 + +struct testvec { + unsigned int blkno; + const uint8_t *ptxt; /* PlainText */ + const uint8_t *ctxt; /* CipherText */ +}; + +/* + * 128 bits CBC key, NUL terminated. + */ +static const char aes_cbc_128_key[17] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 01234567 */ + 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, /* 89ABCDEF */ + 0 +}; + +/* + * 192 bits CBC key, NUL terminated. + */ +static const char aes_cbc_192_key[25] = { + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, /* ABCDEFGH */ + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* IJKLMNOP */ + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* QRSTUVWX */ + 0 +}; + +/* + * 256 bits CBC key, NUL terminated. + */ +static const char aes_cbc_256_key[33] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 01234567 */ + 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, /* 89ABCDEF */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 01234567 */ + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* 89abcdef */ + 0 +}; + +static const uint8_t aes_cbc_ptxt[SECSIZE] = + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop"; + +/* + * IV method encblkno1, blkno 0. + */ +static const uint8_t aes_cbc_128_encblkno1_vec0_ctxt[SECSIZE] = { + 0x1e, 0x95, 0x12, 0x15, 0xf6, 0xe0, 0xa7, 0x56, + 0x95, 0xa0, 0xa7, 0x35, 0x77, 0xf4, 0xdd, 0xdc, + 0x37, 0xc0, 0x28, 0x20, 0x00, 0x79, 0xa0, 0x35, + 0xe0, 0x83, 0x23, 0x95, 0x4e, 0xea, 0x8d, 0xa2, + 0x11, 0xbf, 0x9a, 0xd5, 0x21, 0x1e, 0x15, 0xb9, + 0xd1, 0x2e, 0xd2, 0xd9, 0xa5, 0xcc, 0x26, 0x75, + 0xba, 0x3e, 0x30, 0x11, 0xb2, 0x40, 0xdd, 0x1d, + 0x07, 0x3b, 0xe6, 0x00, 0xa7, 0x31, 0x9e, 0x58, + 0x41, 0xf3, 0x02, 0xf5, 0xad, 0x35, 0x79, 0x9a, + 0x9e, 0x03, 0xc8, 0x7a, 0x9d, 0x1d, 0x58, 0x9f, + 0x98, 0x67, 0xe2, 0x49, 0x81, 0x0c, 0x23, 0x90, + 0xd8, 0xc6, 0xf0, 0xc5, 0x73, 0x46, 0xd5, 0x14, + 0x1d, 0x78, 0x24, 0x7c, 0x9f, 0x5c, 0x8c, 0xe6, + 0x5d, 0x85, 0x7a, 0x5f, 0x76, 0xcc, 0xd8, 0xe9, + 0x03, 0xff, 0xfd, 0xd4, 0x12, 0x3f, 0xcb, 0xb0, + 0xfe, 0xfd, 0x86, 0x00, 0x0c, 0xe3, 0xdd, 0xa6, + 0x89, 0x92, 0xfe, 0xc8, 0x07, 0x5a, 0x94, 0x55, + 0x75, 0xae, 0x68, 0x47, 0xba, 0x84, 0x75, 0x58, + 0x33, 0x30, 0x2c, 0x16, 0x5b, 0xe9, 0x3f, 0x2a, + 0x09, 0xf9, 0x69, 0x23, 0x77, 0xd7, 0x2b, 0x95, + 0x4b, 0x78, 0x59, 0xcc, 0xfa, 0xf5, 0x79, 0xd2, + 0x05, 0x87, 0x66, 0x57, 0x93, 0xbf, 0x05, 0x90, + 0x4d, 0x6d, 0xd2, 0x72, 0x92, 0x24, 0xec, 0x14, + 0xe7, 0xbf, 0x82, 0x57, 0xbb, 0x14, 0x51, 0xe6, + 0xce, 0x3f, 0xa1, 0xfc, 0x63, 0x75, 0xee, 0xde, + 0xf9, 0x31, 0xd3, 0xa0, 0x07, 0xcd, 0x4d, 0x8f, + 0x83, 0x7d, 0x65, 0xe1, 0xc6, 0x60, 0x9e, 0x5c, + 0x51, 0x76, 0xfa, 0x64, 0xdf, 0xdc, 0xaf, 0x38, + 0xee, 0xe9, 0x8f, 0x4b, 0xa0, 0x3a, 0x21, 0xdf, + 0x58, 0x3b, 0x73, 0xf5, 0x30, 0xbb, 0x29, 0xe0, + 0xff, 0x60, 0xf0, 0x05, 0x5e, 0x37, 0xbc, 0x78, + 0x95, 0x3f, 0xa8, 0xd4, 0xb4, 0x82, 0x0d, 0xe1, + 0x10, 0xe3, 0xa7, 0x61, 0x37, 0x58, 0x28, 0x14, + 0x22, 0x57, 0x32, 0x28, 0x80, 0x98, 0x3e, 0x5f, + 0x71, 0xcf, 0x34, 0xb8, 0x6d, 0x6b, 0xc0, 0x23, + 0xc1, 0x9e, 0x58, 0x4f, 0xd5, 0xa4, 0x14, 0x03, + 0x2a, 0xed, 0xc4, 0xa7, 0x77, 0x7c, 0x4f, 0x94, + 0x91, 0x1d, 0x47, 0x34, 0x82, 0xe8, 0x9d, 0x32, + 0x5c, 0xc7, 0x38, 0xe9, 0x92, 0xcd, 0x35, 0xfd, + 0x1c, 0xcc, 0x3c, 0x28, 0x75, 0x6f, 0xff, 0xd5, + 0xe8, 0xbf, 0x90, 0x92, 0x34, 0x13, 0x11, 0x89, + 0xe0, 0xa2, 0x25, 0xeb, 0x82, 0x63, 0x31, 0x80, + 0x50, 0x6c, 0x99, 0xaa, 0x97, 0x0e, 0x59, 0x45, + 0x64, 0xb8, 0x77, 0x78, 0x6b, 0x24, 0xac, 0xc0, + 0xc9, 0xa9, 0xbc, 0x13, 0xd1, 0x5e, 0x50, 0x9a, + 0x91, 0x1a, 0x08, 0xf7, 0xc5, 0x18, 0x9f, 0x87, + 0x97, 0x9c, 0x0a, 0x27, 0xf1, 0x66, 0xf8, 0x09, + 0x52, 0x09, 0x41, 0x07, 0xc1, 0xa1, 0x91, 0xa4, + 0x59, 0x09, 0x75, 0x57, 0x5b, 0x53, 0x79, 0x58, + 0xa2, 0x9e, 0x49, 0xa2, 0x5e, 0xf7, 0x28, 0x1c, + 0x43, 0xa6, 0xcb, 0x88, 0x46, 0x84, 0xc9, 0x7f, + 0x84, 0xdb, 0x45, 0x0c, 0xb3, 0x7f, 0x01, 0x40, + 0x71, 0x3e, 0x48, 0x12, 0x1f, 0xbc, 0x1e, 0xdf, + 0x41, 0x50, 0xb2, 0x11, 0x67, 0x83, 0x19, 0x04, + 0x0e, 0x21, 0xd5, 0xf2, 0x54, 0x99, 0xfb, 0x47, + 0xf2, 0x5e, 0x02, 0x4b, 0x61, 0x6d, 0xef, 0x78, + 0x29, 0xe4, 0x3a, 0x56, 0x14, 0x20, 0x6f, 0x70, + 0x82, 0xea, 0x5d, 0xbc, 0x48, 0x89, 0x34, 0x69, + 0xdb, 0x4a, 0x06, 0xa7, 0xd6, 0xc7, 0xb7, 0x06, + 0x8e, 0x64, 0x21, 0x3e, 0xa6, 0x32, 0x61, 0x59, + 0x03, 0xea, 0xc3, 0x71, 0xf0, 0x26, 0x02, 0xe0, + 0x71, 0x95, 0x38, 0x11, 0x32, 0xe6, 0x3b, 0x25, + 0x53, 0x14, 0x24, 0x34, 0xe8, 0x8c, 0xa8, 0xef, + 0x52, 0xfe, 0x06, 0x2c, 0x20, 0x88, 0x4f, 0xa6, +}; + +/* + * IV method encblkno1, blkno 1. + */ +static const uint8_t aes_cbc_128_encblkno1_vec1_ctxt[SECSIZE] = { + 0x2f, 0x69, 0x3e, 0x95, 0x87, 0x91, 0x99, 0xd4, + 0xd9, 0x5d, 0xf2, 0x52, 0x32, 0x54, 0x2a, 0x80, + 0xa0, 0x77, 0x6e, 0x73, 0x15, 0xb4, 0xc9, 0x13, + 0x85, 0xed, 0x79, 0x9b, 0x84, 0x0a, 0x7e, 0xdb, + 0xee, 0x09, 0x78, 0x11, 0x28, 0xd5, 0x26, 0xec, + 0x1d, 0x52, 0xba, 0x33, 0x26, 0xeb, 0x91, 0xc6, + 0x4b, 0xf0, 0x38, 0xdf, 0x9f, 0x9d, 0x6c, 0xd8, + 0x49, 0x83, 0x88, 0xbe, 0x62, 0x2d, 0x5e, 0x88, + 0xc0, 0x35, 0xe4, 0xc3, 0xc9, 0x9f, 0x62, 0x59, + 0x16, 0xa7, 0x2e, 0xc0, 0xda, 0x3c, 0x2e, 0x10, + 0x53, 0xf0, 0x84, 0x27, 0x38, 0xd0, 0xf4, 0xb5, + 0x7c, 0x4a, 0x63, 0x04, 0x51, 0x22, 0xae, 0xf3, + 0xe7, 0x97, 0x53, 0xee, 0xe6, 0xaf, 0xc3, 0x49, + 0x3a, 0x5a, 0x74, 0x83, 0x18, 0xa3, 0x6b, 0xf3, + 0x6a, 0x3b, 0xe2, 0x1b, 0xd4, 0x64, 0x41, 0xdf, + 0xd1, 0xd2, 0xdd, 0x22, 0xa8, 0x66, 0xbd, 0x8e, + 0xc4, 0x9a, 0x6d, 0x15, 0x38, 0x5b, 0x50, 0x9a, + 0x65, 0x48, 0x97, 0xf1, 0x04, 0x85, 0x8b, 0x5c, + 0x44, 0x32, 0x15, 0xea, 0x28, 0x5f, 0x98, 0x53, + 0xb4, 0x80, 0xd0, 0x2c, 0x59, 0x04, 0x08, 0xaf, + 0xa4, 0xb7, 0x49, 0xd1, 0x98, 0x87, 0xb9, 0xb6, + 0x3d, 0x89, 0xd1, 0xbe, 0xf4, 0x89, 0xec, 0xf9, + 0x2d, 0xc7, 0xc6, 0xe9, 0xe6, 0xfa, 0x1e, 0x67, + 0x68, 0xe7, 0xb7, 0x91, 0x55, 0x77, 0xf3, 0x27, + 0x38, 0x23, 0xcf, 0x2e, 0x3e, 0x8b, 0xfd, 0xb3, + 0x90, 0xd8, 0x6b, 0x1e, 0x93, 0x8f, 0xb6, 0xc1, + 0x27, 0xc2, 0xb7, 0x76, 0x10, 0x69, 0xe8, 0x7f, + 0xfc, 0x03, 0x59, 0xa4, 0xd3, 0x7f, 0x2f, 0x03, + 0x1c, 0x21, 0x6d, 0x2e, 0xae, 0xba, 0xa2, 0x04, + 0x67, 0xe9, 0x33, 0xc9, 0x3a, 0x96, 0xb6, 0x7c, + 0xf6, 0x21, 0x6b, 0x34, 0x9a, 0x5b, 0xa0, 0x8b, + 0x51, 0xf0, 0xd4, 0x3a, 0xa3, 0xcb, 0x22, 0xfb, + 0x8a, 0x56, 0xab, 0x9a, 0x15, 0x75, 0x07, 0x87, + 0x32, 0xa7, 0x15, 0xc7, 0xd9, 0x40, 0x95, 0xe5, + 0xfb, 0xb0, 0xc5, 0xb1, 0x60, 0xf8, 0xcc, 0x8b, + 0x30, 0x20, 0xd9, 0x84, 0x6f, 0xa2, 0xcb, 0x72, + 0xf5, 0xa5, 0x2c, 0xa3, 0xc6, 0x1c, 0xd2, 0x74, + 0x01, 0x74, 0xdd, 0xb4, 0x68, 0x3b, 0x3b, 0x3e, + 0x4f, 0xb5, 0x67, 0x9a, 0x9c, 0x37, 0x3d, 0xbf, + 0xd3, 0xab, 0xd7, 0x70, 0x03, 0x28, 0x5c, 0x3b, + 0xb7, 0x08, 0x38, 0x3d, 0x69, 0xa9, 0xcb, 0x63, + 0x04, 0x95, 0x8a, 0x16, 0x4c, 0xff, 0x9f, 0x0c, + 0xe2, 0x51, 0x95, 0x44, 0x52, 0x3b, 0x59, 0x9d, + 0x0b, 0x77, 0xa0, 0x39, 0x40, 0xea, 0x33, 0x25, + 0xc8, 0xc5, 0x90, 0x47, 0x23, 0xe3, 0x03, 0x8c, + 0x6a, 0xe0, 0x4f, 0x76, 0xe7, 0x72, 0x82, 0xcc, + 0xb2, 0xfd, 0xfb, 0x82, 0x1a, 0x28, 0x30, 0x89, + 0x0e, 0x25, 0xa7, 0x63, 0x85, 0x2e, 0x9b, 0xa6, + 0x0b, 0xa0, 0xb5, 0x34, 0xa2, 0x2e, 0x7f, 0xd4, + 0xe5, 0xd6, 0x95, 0xe8, 0x09, 0x3d, 0x4d, 0xdf, + 0xd9, 0xc0, 0x63, 0x17, 0xa5, 0x9c, 0xf6, 0xa3, + 0x59, 0x17, 0xc0, 0xf8, 0xa2, 0x11, 0x14, 0x88, + 0xf0, 0x1e, 0x4a, 0x4b, 0x13, 0xf6, 0xd6, 0x09, + 0xac, 0xf8, 0x39, 0x5d, 0x4c, 0x68, 0x69, 0x99, + 0x08, 0xd4, 0xf5, 0x39, 0x6d, 0x78, 0xde, 0xb5, + 0x6f, 0x34, 0xc4, 0x28, 0x73, 0x6c, 0x29, 0xa1, + 0xef, 0xfe, 0xed, 0x56, 0xb2, 0x70, 0x7b, 0xd5, + 0x5b, 0xd1, 0x09, 0x6a, 0x9a, 0x59, 0xe9, 0x79, + 0xe9, 0xee, 0xa4, 0x03, 0xc1, 0x67, 0xce, 0x62, + 0xf6, 0x4f, 0x04, 0xa5, 0x04, 0x71, 0x13, 0xeb, + 0x3d, 0x0a, 0x65, 0x2f, 0x57, 0xb0, 0xc0, 0xa4, + 0xf2, 0x8d, 0x78, 0x90, 0xeb, 0xc9, 0x5e, 0x8b, + 0xd8, 0xfb, 0xbc, 0x74, 0x1a, 0x70, 0x94, 0x2c, + 0xeb, 0xf2, 0x5e, 0x6d, 0xbb, 0x96, 0x7a, 0x2c, +}; + +/* + * IV method encblkno1, blkno 2. + */ +static const uint8_t aes_cbc_128_encblkno1_vec2_ctxt[SECSIZE] = { + 0xbc, 0x49, 0x35, 0x2c, 0xe3, 0x10, 0x12, 0x65, + 0x7a, 0xf4, 0xde, 0xd3, 0xf8, 0xe1, 0x49, 0x97, + 0x0a, 0x07, 0x93, 0x6c, 0xf8, 0x0e, 0xb7, 0xdf, + 0x53, 0xba, 0x1e, 0x8e, 0x14, 0xbd, 0xf6, 0x81, + 0xd6, 0xf6, 0x3d, 0xb2, 0xe7, 0x6a, 0x9d, 0x50, + 0x68, 0xc2, 0x75, 0x8e, 0xfb, 0x44, 0xfa, 0xc8, + 0x9f, 0x30, 0x15, 0xd5, 0xbe, 0xce, 0x04, 0xc1, + 0x99, 0xde, 0x3d, 0x2b, 0xc1, 0xc4, 0x8a, 0xb1, + 0xc5, 0x54, 0x47, 0x52, 0xf6, 0x38, 0x11, 0xcb, + 0x11, 0xf6, 0xb7, 0xbd, 0x4d, 0x24, 0xa1, 0xac, + 0x04, 0x17, 0x7e, 0x3c, 0xbc, 0x3b, 0xa0, 0x8d, + 0xfb, 0x22, 0x82, 0x56, 0xa2, 0xbe, 0xfe, 0xe7, + 0xde, 0xa4, 0xe9, 0xeb, 0xa0, 0x7a, 0x45, 0xc9, + 0x18, 0x0b, 0x14, 0xd5, 0xff, 0x4c, 0xe5, 0x86, + 0xac, 0xac, 0xaa, 0xb4, 0x70, 0x0c, 0x4a, 0x20, + 0xb6, 0xd8, 0x2d, 0xac, 0x09, 0xd8, 0xf6, 0x24, + 0xdf, 0xa5, 0x62, 0xef, 0x8c, 0x01, 0xa8, 0x1d, + 0x8f, 0x52, 0xee, 0xa6, 0x2f, 0x9b, 0x81, 0x18, + 0x0e, 0x6b, 0xa3, 0xe5, 0x67, 0xb3, 0xd5, 0x30, + 0xb1, 0x9f, 0x87, 0x05, 0xd0, 0x52, 0x62, 0x6f, + 0xb9, 0x3b, 0xbc, 0x0c, 0x0c, 0xcb, 0x73, 0x55, + 0x23, 0x83, 0x14, 0x78, 0x05, 0x5b, 0x05, 0xf5, + 0x3e, 0xa7, 0xf3, 0x4d, 0x0d, 0x34, 0x6f, 0xe0, + 0x58, 0x52, 0x0a, 0x82, 0xa7, 0x49, 0x8a, 0xd2, + 0x23, 0xb1, 0xc5, 0x0d, 0xa7, 0x0f, 0x56, 0xfc, + 0x7e, 0xf6, 0x19, 0x4b, 0xe7, 0x63, 0x72, 0x4c, + 0xb8, 0x5c, 0x80, 0x54, 0xf5, 0x1f, 0xb0, 0x29, + 0x40, 0x88, 0x75, 0x54, 0x42, 0xca, 0x2c, 0xc3, + 0xcf, 0xd7, 0xc1, 0xb2, 0xd6, 0x90, 0x70, 0x5e, + 0xf5, 0x58, 0x70, 0xe0, 0xff, 0x5a, 0xf5, 0xee, + 0x32, 0x4f, 0x61, 0x1c, 0xf6, 0xbf, 0xd5, 0x7c, + 0x73, 0xb9, 0x1d, 0x30, 0xc2, 0xfb, 0x2f, 0x9a, + 0xf7, 0x57, 0x2e, 0x87, 0x7d, 0xcb, 0xdd, 0x7e, + 0xda, 0xec, 0x47, 0x1a, 0x0e, 0x70, 0x2d, 0x6e, + 0x18, 0x2b, 0x89, 0xc1, 0x85, 0x58, 0x6d, 0x4b, + 0x45, 0x11, 0xcf, 0x82, 0x9f, 0x31, 0xd0, 0x42, + 0x11, 0xca, 0xa8, 0x52, 0x66, 0xf7, 0xf1, 0x1d, + 0x86, 0xe3, 0xb4, 0x41, 0xcb, 0x92, 0xb1, 0x9f, + 0x8d, 0x8e, 0x08, 0xe9, 0xc4, 0x66, 0xce, 0x9d, + 0xae, 0x91, 0xaf, 0xe6, 0xa6, 0x2e, 0x06, 0x3a, + 0xf5, 0x27, 0x48, 0xe4, 0x31, 0x0f, 0xc5, 0xdf, + 0x29, 0x56, 0xed, 0x62, 0xf3, 0xef, 0xca, 0xa6, + 0x58, 0xd1, 0x84, 0x99, 0xd3, 0x34, 0x67, 0x92, + 0x6a, 0xb2, 0xd1, 0xd1, 0x50, 0x1f, 0xe9, 0xd8, + 0x3c, 0xbe, 0x12, 0x97, 0x7c, 0x4f, 0xc0, 0xbe, + 0x91, 0x32, 0x15, 0xd5, 0xf2, 0x5e, 0xe6, 0x13, + 0x86, 0xfa, 0xc6, 0xde, 0xd8, 0xe1, 0x70, 0xb4, + 0xf7, 0x5b, 0x9f, 0x79, 0x55, 0x22, 0x7a, 0xe1, + 0x54, 0x40, 0x39, 0x11, 0xe1, 0x78, 0x01, 0x01, + 0xc0, 0x44, 0xeb, 0x92, 0xb9, 0x01, 0xdd, 0x56, + 0xb9, 0x7e, 0xa0, 0x50, 0x41, 0x58, 0xb2, 0x13, + 0x12, 0x44, 0xd2, 0x39, 0xf2, 0x76, 0x3c, 0x53, + 0x36, 0xfe, 0x17, 0x74, 0x91, 0x8d, 0xbe, 0xc5, + 0x40, 0xf7, 0xa2, 0xe9, 0x65, 0xd9, 0xdf, 0x80, + 0x7b, 0xd9, 0xc3, 0x1f, 0xb4, 0xfc, 0x9f, 0x8d, + 0x7a, 0x4e, 0x1e, 0x32, 0x6d, 0xb1, 0x82, 0x1e, + 0x0c, 0xb6, 0x0b, 0xe6, 0x15, 0x82, 0x5c, 0xcc, + 0xc8, 0x4a, 0x73, 0x56, 0x9d, 0x11, 0xfa, 0xcd, + 0x21, 0x95, 0x23, 0x71, 0xe8, 0xfe, 0x06, 0x43, + 0xf6, 0x17, 0x51, 0x28, 0x0d, 0xfb, 0x0a, 0x49, + 0x1b, 0x35, 0x1e, 0x4a, 0x38, 0x08, 0x6b, 0xcd, + 0x67, 0x21, 0x94, 0x09, 0x28, 0xca, 0x0a, 0x18, + 0xdf, 0x6c, 0x86, 0x47, 0x10, 0x29, 0x81, 0x9a, + 0x73, 0xba, 0x78, 0xbd, 0xc0, 0x61, 0xee, 0x23, +}; + +/* + * IV method encblkno1, blkno 3. + */ +static const uint8_t aes_cbc_128_encblkno1_vec3_ctxt[SECSIZE] = { + 0x29, 0x9f, 0xb1, 0x0f, 0x7d, 0xb4, 0xd9, 0xbb, + 0xf9, 0x06, 0x60, 0xdc, 0xb9, 0xeb, 0x73, 0x6e, + 0xfe, 0xdb, 0x99, 0x29, 0xe8, 0x42, 0x46, 0xe7, + 0x49, 0xcf, 0x90, 0x2d, 0x08, 0xd7, 0xd5, 0xbf, + 0x0f, 0x4f, 0x66, 0xce, 0xcd, 0xb1, 0x8a, 0xc7, + 0x47, 0xc9, 0x8e, 0xe3, 0x9f, 0x80, 0x79, 0xc6, + 0xa8, 0xe5, 0x20, 0x66, 0x58, 0xde, 0xab, 0x87, + 0x5e, 0x7e, 0xcd, 0x55, 0x81, 0x09, 0x40, 0xd9, + 0x8b, 0x7e, 0xd3, 0xf9, 0x16, 0x55, 0x72, 0x7d, + 0xe8, 0x36, 0x76, 0x06, 0x77, 0x47, 0xa5, 0xdc, + 0x80, 0x33, 0x7d, 0x88, 0x5f, 0x56, 0x48, 0x0f, + 0x66, 0xb5, 0x91, 0x9d, 0xf8, 0xdb, 0x83, 0x0d, + 0xd4, 0xc6, 0x13, 0xfc, 0xd4, 0xe5, 0x34, 0x81, + 0x70, 0x4d, 0x96, 0x82, 0x5d, 0xb2, 0x36, 0x37, + 0xdf, 0xd2, 0x5e, 0x31, 0xf0, 0x9d, 0x6d, 0xb7, + 0xf9, 0x2d, 0xcb, 0x77, 0xb8, 0x59, 0xa0, 0xbb, + 0x4f, 0x8d, 0xa0, 0xd1, 0x49, 0x17, 0x93, 0x3c, + 0xf0, 0x4e, 0x72, 0xdd, 0x99, 0x9a, 0x87, 0xf1, + 0x01, 0x89, 0xdf, 0xef, 0xed, 0x04, 0x86, 0x3d, + 0x9b, 0xab, 0x6c, 0xa7, 0xef, 0x1b, 0xbb, 0x24, + 0xbc, 0x65, 0x01, 0x06, 0x12, 0x3f, 0x7e, 0x9f, + 0x83, 0xf3, 0xd4, 0x43, 0x18, 0x03, 0xa3, 0x07, + 0xbc, 0x85, 0xe8, 0xdb, 0x6c, 0x8f, 0xaf, 0x70, + 0x71, 0x5d, 0xbc, 0x6d, 0x14, 0x05, 0xdf, 0xce, + 0x9f, 0xe2, 0xa3, 0x51, 0x66, 0x92, 0x52, 0x19, + 0x98, 0xbd, 0xb2, 0x68, 0x79, 0xf4, 0x5d, 0x71, + 0xcb, 0xa0, 0x1b, 0x77, 0x34, 0x46, 0x69, 0x3c, + 0xa4, 0x0f, 0x72, 0xf5, 0x73, 0xf6, 0xa0, 0xe9, + 0x72, 0xef, 0xa1, 0xcc, 0x43, 0xfc, 0xb7, 0xf3, + 0x59, 0xeb, 0x40, 0x61, 0x02, 0x26, 0x9b, 0x71, + 0x57, 0x17, 0x36, 0xac, 0xc8, 0xd5, 0x9d, 0xcb, + 0x4d, 0x4f, 0xf7, 0xc1, 0x58, 0xce, 0xbf, 0x73, + 0xe7, 0xd0, 0x58, 0x0d, 0x08, 0x01, 0x8f, 0x68, + 0x1b, 0x3f, 0x3a, 0x7b, 0xdb, 0x9e, 0xa7, 0x33, + 0x59, 0x91, 0xa8, 0xe3, 0x58, 0x22, 0x3f, 0x97, + 0xe1, 0xdb, 0xd6, 0x99, 0x0e, 0xdd, 0x76, 0xcd, + 0x4d, 0x02, 0x28, 0x43, 0x8a, 0xdd, 0x10, 0xad, + 0x55, 0xe0, 0x62, 0xf7, 0x44, 0xbc, 0x3f, 0x99, + 0x3c, 0x09, 0x25, 0xfb, 0xfd, 0x1e, 0x4c, 0x45, + 0x0e, 0x6e, 0x75, 0x15, 0x48, 0x19, 0x08, 0xc3, + 0x2b, 0x81, 0x60, 0x5f, 0x19, 0x09, 0x74, 0x0a, + 0xbd, 0x0d, 0x8d, 0x94, 0x55, 0x04, 0x2b, 0x8e, + 0x0d, 0x10, 0x60, 0x64, 0x0d, 0x7f, 0x63, 0x2e, + 0x89, 0x0b, 0xfc, 0x1c, 0xbc, 0xf3, 0x66, 0xc5, + 0x80, 0x93, 0x3a, 0x74, 0x15, 0x11, 0xd5, 0xba, + 0xbc, 0x06, 0x3f, 0x85, 0xcc, 0x6c, 0xd3, 0xf2, + 0x74, 0xc6, 0x10, 0x15, 0x0a, 0x02, 0x66, 0xa4, + 0xa8, 0x93, 0x0b, 0x5c, 0xe7, 0x13, 0x96, 0x90, + 0xdd, 0xe3, 0x25, 0x22, 0x46, 0x7b, 0x49, 0xde, + 0x72, 0x55, 0xf3, 0x30, 0x62, 0x5f, 0x7a, 0x2a, + 0x37, 0x88, 0xea, 0x57, 0x99, 0x64, 0x50, 0x2d, + 0xd3, 0x6a, 0x09, 0x4b, 0xd6, 0x61, 0xf2, 0x22, + 0x53, 0x36, 0xf7, 0x42, 0x21, 0xde, 0xda, 0xcb, + 0x8b, 0x6f, 0xf3, 0x4e, 0x2c, 0x16, 0xfb, 0xfc, + 0x13, 0xa7, 0xd1, 0xd8, 0xfd, 0x16, 0x39, 0x20, + 0xe0, 0xb2, 0xb4, 0xd5, 0x40, 0x93, 0x30, 0xf3, + 0xab, 0x88, 0xe3, 0xfb, 0xbe, 0xb8, 0x02, 0x3a, + 0x78, 0x2d, 0x56, 0x4b, 0x92, 0x5b, 0x0a, 0x8d, + 0x18, 0xa4, 0x5b, 0x11, 0x60, 0x0b, 0x45, 0xad, + 0x0b, 0x64, 0x96, 0x7d, 0x84, 0xf2, 0x20, 0xa8, + 0x95, 0x78, 0xb3, 0xb5, 0x98, 0x1f, 0xa7, 0x3e, + 0x30, 0x77, 0x43, 0xd2, 0x8c, 0x20, 0xc5, 0x5e, + 0x76, 0xcd, 0x2c, 0x7c, 0xfa, 0x34, 0x36, 0xda, + 0x39, 0x00, 0x2e, 0x69, 0x4a, 0xb3, 0x0f, 0x6f, +}; + +const struct testvec aes_cbc_128_1_vectors[] = { + { + .blkno = 0, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_128_encblkno1_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_128_encblkno1_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_128_encblkno1_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_128_encblkno1_vec3_ctxt, + }, +}; + +/* + * IV method encblkno8, blkno 0. + */ +static const uint8_t aes_cbc_128_encblkno8_vec0_ctxt[SECSIZE] = { + 0xa6, 0x64, 0xef, 0x0f, 0xc4, 0x45, 0xcc, 0x5e, + 0xf8, 0x27, 0x42, 0x5e, 0xbd, 0x93, 0x99, 0xcd, + 0x79, 0xa8, 0x7d, 0x72, 0xc4, 0x02, 0x99, 0xa6, + 0xe4, 0x69, 0x57, 0x82, 0xdf, 0x32, 0x4e, 0x67, + 0x2a, 0xd9, 0x58, 0x8c, 0x9f, 0xfc, 0x4d, 0xcf, + 0x7b, 0xa4, 0xa1, 0xfa, 0xd9, 0x4d, 0xb5, 0x67, + 0x06, 0x4a, 0x9e, 0x6d, 0xe8, 0xaa, 0xdd, 0xae, + 0x8c, 0xda, 0xcf, 0x26, 0xd5, 0x94, 0x8d, 0x12, + 0xf8, 0xdd, 0x21, 0x4c, 0xcb, 0xc8, 0x5d, 0xd1, + 0x6a, 0x89, 0x37, 0xd0, 0x32, 0xe4, 0x87, 0xbc, + 0x5d, 0xef, 0xca, 0x38, 0xd5, 0x08, 0xfb, 0xcf, + 0xb7, 0x8d, 0x65, 0x52, 0x13, 0xea, 0x2d, 0x30, + 0xd3, 0x9a, 0xe8, 0x9c, 0x76, 0x25, 0x44, 0x2a, + 0xf1, 0xe1, 0xbb, 0xcd, 0xbc, 0x9c, 0xf5, 0xa3, + 0xfb, 0x23, 0x53, 0x95, 0x61, 0xea, 0x46, 0x97, + 0xf6, 0xbf, 0xdf, 0xf9, 0xb7, 0x94, 0x73, 0xa8, + 0xc1, 0xaa, 0x64, 0xfb, 0x66, 0x26, 0x0f, 0x4c, + 0xee, 0x3c, 0xb6, 0x3f, 0x13, 0x88, 0xaa, 0x7d, + 0x91, 0x01, 0x1a, 0x95, 0x3b, 0xb5, 0x7e, 0x1f, + 0xc1, 0x84, 0xa6, 0x83, 0x99, 0xe6, 0xaf, 0x21, + 0x33, 0xff, 0x2e, 0xc9, 0xfe, 0xf2, 0xa1, 0x37, + 0xed, 0x91, 0x73, 0x70, 0x4f, 0xb4, 0x69, 0x69, + 0x98, 0x1d, 0x6d, 0xd4, 0xa4, 0xac, 0x73, 0x61, + 0x04, 0xf5, 0x13, 0x50, 0x2a, 0xa9, 0xf7, 0x61, + 0x78, 0xf5, 0x87, 0x26, 0xc5, 0x4a, 0x30, 0xbb, + 0x94, 0x55, 0x51, 0xb4, 0xa0, 0x83, 0x30, 0xe6, + 0xf7, 0xc7, 0x89, 0x61, 0x73, 0xd9, 0xbd, 0xe1, + 0x4e, 0x14, 0x8a, 0x02, 0x3d, 0x7a, 0x58, 0x92, + 0x41, 0xe7, 0x90, 0x8d, 0xd7, 0x67, 0x62, 0xf8, + 0x99, 0xa7, 0x9d, 0x55, 0xec, 0x18, 0x6b, 0x42, + 0xaf, 0x27, 0x97, 0xe5, 0x51, 0xa9, 0x10, 0x27, + 0x5e, 0x3f, 0xac, 0xda, 0xd3, 0xb5, 0x2b, 0x43, + 0x2e, 0x10, 0xdc, 0xd9, 0xe2, 0x2f, 0x4f, 0xfe, + 0xf3, 0x0d, 0x06, 0x76, 0xf9, 0x25, 0xcd, 0x26, + 0xef, 0x8e, 0x9b, 0xc2, 0xb3, 0x20, 0x2b, 0x00, + 0xb6, 0xe6, 0x2e, 0xf7, 0x17, 0xc7, 0xa8, 0x3c, + 0x00, 0xfc, 0x78, 0x8d, 0x10, 0x38, 0xd1, 0x11, + 0x94, 0xed, 0xb4, 0x22, 0x13, 0xcb, 0x52, 0x0f, + 0x0f, 0xd7, 0x33, 0x3b, 0xbd, 0x01, 0x04, 0x56, + 0xfa, 0x2c, 0xaa, 0xaf, 0x2b, 0x93, 0xde, 0xf4, + 0x31, 0x36, 0x13, 0x71, 0xef, 0x7a, 0xf0, 0xae, + 0xbd, 0xa7, 0x4a, 0x57, 0xa5, 0xc5, 0xf3, 0x5c, + 0x08, 0x2b, 0xe7, 0x12, 0x42, 0x4b, 0x4b, 0x12, + 0x49, 0x3a, 0x2e, 0x26, 0x67, 0x67, 0xa1, 0xd5, + 0x59, 0xa6, 0x18, 0x96, 0x22, 0x2b, 0xeb, 0x56, + 0x1e, 0x0a, 0x08, 0x75, 0xb4, 0x2b, 0x5c, 0x0a, + 0x4e, 0x9d, 0x17, 0xd4, 0x0c, 0xfe, 0x46, 0x60, + 0x6d, 0xfa, 0xc0, 0xb9, 0x5e, 0x1f, 0x88, 0x0e, + 0x08, 0x2c, 0xf3, 0xb4, 0x3a, 0x15, 0xc5, 0xf9, + 0x5b, 0x85, 0x92, 0x94, 0xa8, 0x8f, 0x2c, 0x3a, + 0x7e, 0x22, 0x86, 0x88, 0x51, 0x03, 0xee, 0xf9, + 0x2e, 0x83, 0xce, 0x39, 0x0c, 0x76, 0x64, 0xe5, + 0x5a, 0x88, 0xef, 0xc5, 0x06, 0xb2, 0xe4, 0x13, + 0x82, 0xc9, 0xee, 0xba, 0x6d, 0x56, 0xa8, 0x87, + 0x51, 0x69, 0x3b, 0x86, 0x29, 0x8e, 0xe8, 0xb4, + 0x44, 0x42, 0x07, 0x5b, 0xff, 0x0e, 0x1e, 0x9f, + 0x42, 0xb1, 0xc8, 0x5f, 0xab, 0x3b, 0xc7, 0xba, + 0x75, 0x20, 0xe6, 0x9f, 0x93, 0xb5, 0xcf, 0x8f, + 0x7c, 0x1c, 0xf3, 0xdb, 0x6a, 0xf4, 0xde, 0x00, + 0xe9, 0xaf, 0xd5, 0xf4, 0x36, 0x98, 0x14, 0x2d, + 0x53, 0x20, 0x74, 0xab, 0x0c, 0xf6, 0xcd, 0x15, + 0x32, 0xa6, 0x01, 0x8d, 0x24, 0x1b, 0x4b, 0x1f, + 0xa3, 0xfc, 0x38, 0x82, 0x3a, 0xa1, 0xb5, 0x52, + 0x53, 0xc7, 0x2b, 0x30, 0x7c, 0x65, 0xb9, 0x7d, +}; + +/* + * IV method encblkno8, blkno 1. + */ +static const uint8_t aes_cbc_128_encblkno8_vec1_ctxt[SECSIZE] = { + 0x63, 0x45, 0x16, 0x0c, 0xe4, 0x4f, 0x51, 0xde, + 0x74, 0xf8, 0x7b, 0xf5, 0x05, 0x17, 0x13, 0x1e, + 0xa5, 0x3d, 0x84, 0xfa, 0x35, 0x5a, 0x2d, 0x3c, + 0xb7, 0x61, 0x68, 0xff, 0xcd, 0x33, 0x1f, 0x0b, + 0x53, 0x79, 0xf2, 0x2f, 0xbc, 0x8d, 0xac, 0xb9, + 0xf9, 0xb7, 0x9c, 0x0a, 0x9d, 0xa1, 0x4d, 0x78, + 0x9e, 0x4e, 0xfa, 0xe8, 0xc8, 0x46, 0x4b, 0x99, + 0x91, 0x7e, 0x33, 0x6e, 0x18, 0x24, 0x01, 0xc3, + 0x9f, 0x8c, 0x43, 0xb5, 0x15, 0x7e, 0xdd, 0xf9, + 0x1b, 0xb0, 0xf2, 0xc3, 0x97, 0x1f, 0x7c, 0x3f, + 0x43, 0x4c, 0x9f, 0x93, 0x29, 0x83, 0x8f, 0xad, + 0xd1, 0x5e, 0x92, 0x1a, 0x17, 0xd1, 0xa0, 0x05, + 0x6e, 0x62, 0x59, 0x80, 0x50, 0x6d, 0xe3, 0x28, + 0x9a, 0x43, 0xdc, 0x81, 0x4f, 0x49, 0xc4, 0x98, + 0xcd, 0x6d, 0x28, 0xb4, 0x86, 0xe4, 0x83, 0x45, + 0xd4, 0x43, 0x52, 0x8a, 0xd6, 0xc8, 0x1c, 0x90, + 0xeb, 0xf0, 0xe7, 0x76, 0xb4, 0x43, 0x9b, 0x56, + 0x48, 0x73, 0xdd, 0x01, 0x50, 0x1c, 0x61, 0xfc, + 0x22, 0xac, 0xf4, 0x27, 0x94, 0x02, 0x54, 0xd3, + 0x7d, 0x25, 0xf6, 0x14, 0x29, 0xbb, 0x2b, 0x22, + 0xc8, 0xe8, 0x7f, 0xa1, 0xfe, 0x19, 0x79, 0x97, + 0xb6, 0xa6, 0xba, 0x5b, 0x89, 0xdf, 0x73, 0x6d, + 0x79, 0x38, 0x5b, 0xf8, 0x89, 0xa2, 0x95, 0x1d, + 0xda, 0x38, 0x17, 0x4b, 0x01, 0xf1, 0x7d, 0x0a, + 0xa2, 0x8f, 0x5a, 0x02, 0x51, 0xb0, 0x88, 0x10, + 0x16, 0xc8, 0x82, 0xb9, 0x06, 0x9f, 0x01, 0x94, + 0xf9, 0xe0, 0x2e, 0x86, 0x8a, 0xb1, 0x7f, 0x74, + 0x22, 0xce, 0xee, 0xa6, 0x66, 0xee, 0xe2, 0x1d, + 0x98, 0x1b, 0x46, 0x22, 0x7e, 0x89, 0x0c, 0xc4, + 0x91, 0xfb, 0xe4, 0xd7, 0x36, 0x2a, 0xa9, 0x53, + 0xe9, 0xaf, 0x6c, 0xc1, 0xdd, 0x69, 0x4f, 0xde, + 0xd8, 0xd0, 0x7f, 0xc9, 0xf4, 0x8f, 0x84, 0xfe, + 0x0f, 0x16, 0x36, 0x90, 0x09, 0xd6, 0x0f, 0xbc, + 0x85, 0xad, 0xe9, 0xc3, 0xa1, 0x8d, 0x14, 0x5c, + 0x40, 0x7d, 0x0f, 0x22, 0xfe, 0x5e, 0xaf, 0xd9, + 0x0f, 0xe5, 0x2e, 0xa6, 0x04, 0xda, 0x35, 0x90, + 0x7f, 0x9a, 0x1f, 0xb8, 0x34, 0x1c, 0xd0, 0xf5, + 0x5c, 0x29, 0xce, 0xbe, 0x57, 0xd8, 0x55, 0x15, + 0x2d, 0x4c, 0x3c, 0x16, 0x93, 0x96, 0x3c, 0xf3, + 0xa8, 0x2f, 0x09, 0xb3, 0x8b, 0xe3, 0xce, 0xf7, + 0x3e, 0x8e, 0xcf, 0x47, 0xe2, 0xf2, 0xad, 0x06, + 0x00, 0x9a, 0x3a, 0x55, 0xf5, 0x9e, 0xbf, 0x5a, + 0x2e, 0x5a, 0x6c, 0x2b, 0x8f, 0x33, 0x71, 0x2c, + 0x56, 0x43, 0xd1, 0x8b, 0xd2, 0x98, 0x14, 0xb7, + 0x5a, 0xdc, 0x8b, 0xbc, 0xfe, 0x50, 0x99, 0x84, + 0x48, 0x5f, 0xcd, 0xed, 0xce, 0x61, 0x6f, 0xa6, + 0x83, 0xa3, 0x34, 0xbe, 0xf2, 0x66, 0xf3, 0x09, + 0xf3, 0xd3, 0x97, 0xd4, 0xee, 0x66, 0x9a, 0x81, + 0x62, 0x84, 0x85, 0x7f, 0x79, 0x18, 0xd2, 0x82, + 0xd6, 0x96, 0x09, 0x61, 0x1e, 0x53, 0x97, 0x80, + 0x0a, 0x81, 0x4b, 0x93, 0xf0, 0x03, 0x65, 0x18, + 0x93, 0x5b, 0x60, 0x2f, 0xb5, 0xfe, 0x82, 0xaf, + 0x85, 0xb7, 0x79, 0x7c, 0xee, 0xad, 0xea, 0xfa, + 0x9b, 0xad, 0xca, 0x38, 0x21, 0x3d, 0x46, 0x8a, + 0x5b, 0xa7, 0x55, 0x3d, 0x88, 0x4a, 0x52, 0xdb, + 0xf2, 0x07, 0xed, 0xd6, 0x3c, 0x9f, 0x1b, 0x42, + 0xb4, 0x14, 0x12, 0xb7, 0x00, 0xfc, 0x6a, 0x79, + 0x61, 0x0b, 0x43, 0xaa, 0x44, 0x48, 0x30, 0x15, + 0x48, 0x76, 0x27, 0x32, 0x7a, 0x2e, 0x25, 0x6a, + 0x8c, 0x8c, 0x64, 0x67, 0x86, 0x54, 0x4a, 0x93, + 0x14, 0xfe, 0x81, 0xf5, 0xcf, 0x98, 0x92, 0xd3, + 0x92, 0xf5, 0x6a, 0x74, 0x28, 0x10, 0x6b, 0xd4, + 0x1d, 0x64, 0x7e, 0x05, 0x32, 0xba, 0xf7, 0x4c, + 0xe9, 0xa8, 0xa9, 0xc5, 0x35, 0x34, 0x26, 0x41, +}; + +/* + * IV method encblkno8, blkno 2. + */ +static const uint8_t aes_cbc_128_encblkno8_vec2_ctxt[SECSIZE] = { + 0x64, 0x7b, 0x62, 0x7a, 0xa6, 0xa9, 0xb3, 0x47, + 0xbc, 0x03, 0x14, 0x3d, 0x9b, 0x56, 0xfc, 0x13, + 0x08, 0x32, 0x81, 0xe3, 0x57, 0x3c, 0x0d, 0xbb, + 0x85, 0x44, 0x47, 0x12, 0xc4, 0x80, 0x35, 0x37, + 0xe1, 0xb4, 0x3f, 0x35, 0x98, 0x7c, 0xb0, 0x3b, + 0x85, 0xab, 0x3d, 0x0b, 0xd3, 0x6f, 0xf9, 0x92, + 0x00, 0x6b, 0x18, 0xe7, 0x31, 0x8b, 0x77, 0x4c, + 0xd0, 0x7b, 0x1d, 0xfc, 0x95, 0xe6, 0x02, 0x01, + 0x9c, 0x17, 0x4d, 0x9b, 0x3a, 0x1d, 0x12, 0x23, + 0xd4, 0x24, 0xf8, 0x47, 0x5e, 0x2d, 0xfd, 0xc8, + 0x74, 0x28, 0xb4, 0x3a, 0x99, 0x6b, 0xcc, 0xba, + 0xe5, 0x51, 0x0b, 0xab, 0x4d, 0x63, 0xfc, 0x6d, + 0x2d, 0xd9, 0x2b, 0x4f, 0xa4, 0x26, 0xc7, 0x8d, + 0x9d, 0x12, 0x7f, 0xc7, 0x6b, 0x15, 0x8b, 0x4a, + 0x41, 0xf8, 0x50, 0x32, 0x76, 0x10, 0xca, 0x8e, + 0xfe, 0x08, 0x7d, 0x9a, 0xb5, 0x1a, 0xdb, 0x10, + 0xb3, 0x6a, 0x5f, 0xd9, 0x0a, 0x5f, 0x31, 0x19, + 0x3e, 0xa9, 0xa1, 0x72, 0x1f, 0x6c, 0x97, 0x20, + 0xd4, 0xab, 0xb8, 0xad, 0xf7, 0x70, 0x12, 0xd0, + 0x8f, 0x70, 0x24, 0x58, 0x2e, 0x99, 0xcd, 0xd4, + 0xf4, 0xcd, 0xef, 0x93, 0xfb, 0x4f, 0x9a, 0x40, + 0x46, 0x92, 0x6b, 0xd0, 0x25, 0x24, 0xec, 0x4d, + 0x4c, 0x42, 0x50, 0x61, 0xb6, 0x21, 0xa6, 0x2e, + 0xc1, 0x42, 0x9e, 0x86, 0x9f, 0x57, 0x2a, 0x2c, + 0x82, 0xbd, 0xc2, 0x25, 0xb6, 0x9f, 0x2d, 0x9f, + 0xba, 0xe0, 0xa6, 0x06, 0x04, 0x08, 0xc5, 0x1d, + 0x8c, 0x0f, 0xbf, 0x21, 0x85, 0x6d, 0x61, 0x4d, + 0x93, 0xc0, 0xa2, 0x8b, 0xca, 0x07, 0xd0, 0x88, + 0x74, 0xf9, 0x42, 0x92, 0xd5, 0x0d, 0x0c, 0x34, + 0xa6, 0xa5, 0x86, 0x51, 0xcf, 0x40, 0x36, 0x66, + 0x35, 0x9f, 0xa8, 0x95, 0x0b, 0xfb, 0x0c, 0xe8, + 0xdc, 0x12, 0x78, 0x4c, 0x52, 0xf4, 0xfc, 0x4a, + 0x77, 0xdd, 0x77, 0x34, 0xf7, 0x35, 0x94, 0x7a, + 0x31, 0x16, 0x86, 0x44, 0x50, 0x30, 0x1c, 0x6d, + 0x9f, 0x66, 0x49, 0xb5, 0xe6, 0x71, 0x00, 0x83, + 0xd1, 0xa0, 0x01, 0xff, 0xc3, 0x27, 0xaa, 0x9a, + 0xdb, 0xad, 0x24, 0xdb, 0xbd, 0xde, 0xfd, 0xa6, + 0xaa, 0x87, 0x98, 0x98, 0xde, 0x90, 0xd5, 0x40, + 0x20, 0x8f, 0xe9, 0xdd, 0xa8, 0xec, 0xd3, 0x18, + 0x20, 0x85, 0x5e, 0xd5, 0xe7, 0x50, 0x58, 0x15, + 0x69, 0x03, 0xa5, 0xe8, 0xa9, 0x7a, 0x0f, 0xd1, + 0x7d, 0x22, 0x8a, 0xe0, 0xc6, 0x17, 0x33, 0x00, + 0x57, 0xcb, 0xf6, 0x8d, 0xf0, 0xc1, 0x7b, 0xb5, + 0x96, 0x0f, 0x08, 0x84, 0x5b, 0x7e, 0xa6, 0x1e, + 0xd8, 0x5e, 0x0c, 0xca, 0x30, 0x4b, 0xe0, 0x87, + 0x2f, 0xbc, 0x07, 0x83, 0x35, 0x76, 0x36, 0x17, + 0xcf, 0xdb, 0x27, 0x53, 0x43, 0xf5, 0x07, 0xd0, + 0x91, 0x83, 0xa1, 0xaa, 0x8d, 0xdb, 0x00, 0x2b, + 0xd1, 0x88, 0xe5, 0x59, 0x47, 0x17, 0xf0, 0xe8, + 0xce, 0x3b, 0xa0, 0x73, 0x1f, 0x22, 0x9b, 0x1b, + 0x59, 0x02, 0xe6, 0xaf, 0x3f, 0xdd, 0xfe, 0xba, + 0xc3, 0x6b, 0xe5, 0x82, 0x02, 0x92, 0x0c, 0x5e, + 0x5a, 0x87, 0x88, 0x91, 0x00, 0xb5, 0x30, 0x37, + 0xf5, 0xc6, 0xdf, 0x0a, 0x7f, 0x03, 0x1c, 0x1f, + 0x20, 0xf1, 0xd4, 0x5f, 0x94, 0xc3, 0x6f, 0x21, + 0x5e, 0xf2, 0x77, 0x5a, 0x42, 0xfd, 0xd3, 0xc4, + 0x31, 0xaf, 0xd6, 0x6c, 0x6c, 0xde, 0x8c, 0x50, + 0x01, 0x8f, 0x57, 0x90, 0x88, 0x43, 0xf9, 0x44, + 0x09, 0x4d, 0x27, 0x58, 0x9f, 0xae, 0x50, 0x28, + 0x12, 0x47, 0x20, 0x79, 0x2b, 0xe4, 0x02, 0x97, + 0xcd, 0xab, 0x53, 0x28, 0x8f, 0x8f, 0xe3, 0x3b, + 0xd6, 0xc9, 0xc8, 0xff, 0xbf, 0x18, 0x3b, 0x75, + 0xdb, 0xcf, 0x07, 0x8c, 0xfe, 0x58, 0xee, 0x75, + 0x01, 0x98, 0x98, 0xe4, 0x60, 0xfe, 0xe6, 0x7f, +}; + +/* + * IV method encblkno8, blkno 3. + */ +static const uint8_t aes_cbc_128_encblkno8_vec3_ctxt[SECSIZE] = { + 0x98, 0xae, 0x82, 0x1d, 0x76, 0x3a, 0xfe, 0x80, + 0x04, 0xa3, 0x43, 0xf0, 0x06, 0x45, 0x83, 0xb7, + 0xe2, 0xb5, 0x73, 0x46, 0x78, 0x01, 0x2f, 0xd6, + 0x0d, 0x49, 0x64, 0x4c, 0xeb, 0x8d, 0xdc, 0xa9, + 0xdc, 0xea, 0x22, 0x25, 0xd4, 0x8f, 0xba, 0x9f, + 0xd4, 0x7a, 0x3c, 0x9e, 0xd0, 0xd9, 0xcd, 0xa4, + 0x12, 0xdf, 0x8f, 0x50, 0x24, 0x18, 0xa2, 0x0b, + 0xd9, 0x7f, 0xda, 0x78, 0xd6, 0x11, 0xf3, 0x99, + 0xc4, 0xec, 0x95, 0xe2, 0x85, 0xe1, 0xa0, 0x0d, + 0x07, 0x22, 0x56, 0xaf, 0x2f, 0xf5, 0x7d, 0x63, + 0xf2, 0x90, 0x6c, 0x26, 0x4f, 0xa5, 0x47, 0xcd, + 0x66, 0x2d, 0x4c, 0x4d, 0x94, 0x6a, 0x3c, 0x98, + 0xe4, 0x5e, 0x3b, 0x42, 0x3a, 0x93, 0x02, 0xd0, + 0x90, 0xc7, 0xcd, 0x87, 0x0e, 0x84, 0x82, 0xf5, + 0x77, 0x7b, 0x29, 0xe4, 0xea, 0x5b, 0x60, 0x50, + 0xf7, 0x60, 0x8d, 0xf7, 0xd8, 0xd7, 0x7d, 0x99, + 0x8a, 0xdc, 0xe2, 0xb9, 0x40, 0xac, 0x4b, 0x9f, + 0x55, 0x30, 0xcb, 0x5a, 0x73, 0x64, 0xf2, 0xca, + 0x76, 0x88, 0xf7, 0x55, 0xb5, 0x33, 0xc0, 0x44, + 0xdf, 0x42, 0xee, 0xc9, 0xc5, 0x2a, 0x47, 0x18, + 0x8b, 0x74, 0xb9, 0x4f, 0x2c, 0xd8, 0x7a, 0xd1, + 0x12, 0x19, 0xf9, 0x21, 0x8d, 0x21, 0x7e, 0x2a, + 0xcf, 0xd5, 0xbb, 0x69, 0xaa, 0x20, 0x25, 0xe0, + 0xf5, 0x3b, 0x33, 0x77, 0x63, 0xb2, 0x05, 0x5c, + 0x10, 0x9c, 0x61, 0x48, 0xf5, 0xe6, 0x04, 0xd3, + 0xc8, 0xb4, 0xf6, 0xcf, 0x22, 0x1c, 0xf6, 0xbb, + 0x4b, 0xd7, 0x5d, 0x23, 0xfa, 0x0e, 0xc0, 0xac, + 0x27, 0x38, 0x95, 0xd0, 0xdd, 0x83, 0xad, 0x9e, + 0xcf, 0xde, 0x99, 0xe7, 0x04, 0xb7, 0x23, 0x9f, + 0x46, 0x91, 0xb8, 0xcb, 0x18, 0xd0, 0xc5, 0xf8, + 0xec, 0xfc, 0x33, 0xb7, 0xbe, 0x2d, 0xe9, 0x3a, + 0x7f, 0x83, 0x5e, 0x44, 0x0f, 0x12, 0x6d, 0x05, + 0xaa, 0xfb, 0x80, 0x7a, 0xf6, 0xdb, 0x25, 0xc6, + 0x51, 0xf3, 0x5d, 0xf3, 0xa9, 0xb8, 0x34, 0x88, + 0x88, 0x25, 0xd5, 0xa3, 0xe5, 0x8e, 0xb2, 0xc7, + 0xdc, 0xd5, 0x2e, 0x99, 0xb9, 0xc5, 0x1d, 0x91, + 0x49, 0x7b, 0xa3, 0x5e, 0x4b, 0xaf, 0x29, 0x7b, + 0x37, 0xb5, 0x39, 0x2c, 0xdf, 0x3b, 0xb1, 0xd8, + 0xba, 0x14, 0xc9, 0xd3, 0x6d, 0x67, 0x6a, 0x80, + 0x89, 0x6f, 0x11, 0xc8, 0xbc, 0xd6, 0xc7, 0xab, + 0x42, 0x1f, 0xf4, 0xa2, 0xc0, 0x9c, 0x2d, 0xca, + 0x5f, 0xe6, 0x65, 0xfa, 0x28, 0x49, 0x99, 0xa3, + 0x0b, 0x7b, 0x7d, 0x39, 0xaa, 0xa6, 0xd8, 0x0a, + 0xfd, 0xde, 0x31, 0x86, 0x15, 0x95, 0x1e, 0x5c, + 0x05, 0x4e, 0x3c, 0x18, 0xee, 0xa9, 0x56, 0x9c, + 0x3c, 0xc3, 0x67, 0x84, 0x57, 0x77, 0x8d, 0xff, + 0xea, 0x34, 0x3c, 0xf9, 0x58, 0xb8, 0xdc, 0x4e, + 0xa1, 0x92, 0x2d, 0x9a, 0x91, 0x61, 0x23, 0x6a, + 0xd9, 0xb7, 0x41, 0xc5, 0x0d, 0xb6, 0x57, 0x58, + 0x42, 0x39, 0x4a, 0x86, 0x7e, 0x9d, 0xeb, 0x7d, + 0xa8, 0x14, 0x1a, 0x5c, 0xa1, 0x54, 0x34, 0xb6, + 0xb6, 0xbc, 0x1f, 0xf5, 0xe2, 0xb5, 0xe4, 0xa8, + 0x42, 0xe3, 0x3d, 0x06, 0x6b, 0x50, 0xbb, 0xa1, + 0x6b, 0x63, 0xe5, 0x60, 0x28, 0x07, 0x49, 0x06, + 0x61, 0x0e, 0xa3, 0x6c, 0xc3, 0xc8, 0x3e, 0x5a, + 0x9c, 0xa5, 0xb3, 0x9b, 0x8d, 0x46, 0xb9, 0xf5, + 0x4a, 0x4d, 0xbe, 0xc0, 0xc1, 0x24, 0x92, 0x09, + 0x7c, 0x9a, 0x21, 0x2c, 0x08, 0x8a, 0x0d, 0xfc, + 0xff, 0xda, 0xdc, 0xf1, 0x45, 0x66, 0xf9, 0xcd, + 0x64, 0x7c, 0x2f, 0x0e, 0x95, 0x5e, 0xec, 0x92, + 0xd1, 0x03, 0x03, 0xa0, 0xcc, 0x73, 0x92, 0x15, + 0x74, 0x42, 0x54, 0x48, 0x77, 0xbe, 0x96, 0xfb, + 0x1f, 0x0c, 0x7a, 0x25, 0x67, 0x6b, 0x85, 0x71, + 0x06, 0x15, 0xd3, 0x11, 0xfe, 0xf7, 0xa9, 0xb1, +}; + +const struct testvec aes_cbc_128_8_vectors[] = { + { + .blkno = 0, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_128_encblkno8_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_128_encblkno8_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_128_encblkno8_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_128_encblkno8_vec3_ctxt, + }, +}; + +/* + * IV method encblkno1, blkno 0. + */ +static const uint8_t aes_cbc_192_encblkno1_vec0_ctxt[SECSIZE] = { + 0x7c, 0xc4, 0xec, 0x89, 0x7c, 0x13, 0xac, 0x99, + 0x49, 0xa9, 0x96, 0xe7, 0xb1, 0x1a, 0xd6, 0xb0, + 0xeb, 0x89, 0x27, 0x0f, 0x8b, 0x1b, 0xab, 0x8e, + 0x2c, 0xd4, 0x00, 0x66, 0x12, 0x3a, 0x9a, 0x03, + 0xc4, 0x49, 0xa4, 0xf0, 0xc1, 0x90, 0xf9, 0x38, + 0xb2, 0x5c, 0xa5, 0x0d, 0x1b, 0x60, 0x94, 0xf6, + 0x31, 0x4a, 0x72, 0xdb, 0xfc, 0xe1, 0x3c, 0xd6, + 0x9d, 0x03, 0x07, 0x45, 0xdb, 0xad, 0xdb, 0xb3, + 0x86, 0xfa, 0xce, 0x2c, 0xeb, 0xa2, 0xac, 0x05, + 0xd9, 0x52, 0xb8, 0xae, 0xa9, 0x91, 0x86, 0x4b, + 0xbb, 0xf8, 0x03, 0xb0, 0x6c, 0x40, 0xcc, 0xbf, + 0xa3, 0x76, 0x60, 0xf7, 0x29, 0x03, 0xe6, 0x44, + 0xcc, 0x2a, 0xe7, 0x74, 0x8e, 0x62, 0xfe, 0x99, + 0x6a, 0x6d, 0x04, 0x1b, 0xe7, 0xf7, 0x9f, 0x13, + 0xa7, 0x1d, 0x93, 0x0e, 0x8f, 0xe0, 0x77, 0x9b, + 0xe3, 0x91, 0x67, 0x12, 0x33, 0x12, 0x42, 0x55, + 0x28, 0x04, 0x2d, 0x01, 0x2b, 0xd2, 0xda, 0xbe, + 0x7c, 0x83, 0xf2, 0x87, 0x71, 0x67, 0xaf, 0x6b, + 0x50, 0x6c, 0x8c, 0x9f, 0x48, 0xee, 0x90, 0x0c, + 0x9a, 0x9e, 0x40, 0xa8, 0x13, 0x2f, 0x58, 0xfb, + 0xdc, 0xb1, 0xda, 0xff, 0x06, 0x9c, 0xeb, 0x5e, + 0x0f, 0xaf, 0xc0, 0x9a, 0x47, 0x88, 0x25, 0xfd, + 0x19, 0x5e, 0xd4, 0xe0, 0x7f, 0xe0, 0x71, 0x7a, + 0x60, 0x54, 0xe7, 0x0d, 0xfe, 0x11, 0x9d, 0x77, + 0xbd, 0x9b, 0xd0, 0xf8, 0x77, 0xe4, 0x5b, 0x88, + 0x90, 0x12, 0x29, 0x88, 0xb6, 0xd9, 0x1e, 0x6c, + 0xbf, 0xa4, 0x18, 0xe1, 0xe0, 0x5e, 0xed, 0x48, + 0x9b, 0x05, 0x13, 0x37, 0x0f, 0x41, 0x54, 0xc8, + 0xe4, 0x25, 0x0e, 0x82, 0x5f, 0x81, 0xba, 0x5d, + 0x79, 0x8f, 0x9c, 0x17, 0x4b, 0x59, 0xf4, 0x5d, + 0xd6, 0x83, 0xfd, 0x44, 0xd0, 0xe1, 0x89, 0x09, + 0xf9, 0xe2, 0xb6, 0x9c, 0x1c, 0xbd, 0x13, 0xaa, + 0xa0, 0x43, 0xaa, 0xaf, 0x6d, 0x65, 0x73, 0xba, + 0x3a, 0x55, 0x69, 0x51, 0xb9, 0x52, 0x09, 0xaa, + 0x9f, 0x91, 0x3c, 0x65, 0xe2, 0x81, 0xdb, 0xe8, + 0x5a, 0xe3, 0x74, 0x11, 0x7b, 0xec, 0x2f, 0x18, + 0x8d, 0x4c, 0x8f, 0xf2, 0x06, 0x3d, 0x22, 0xc6, + 0x43, 0xef, 0x42, 0x7d, 0xe1, 0xe7, 0xde, 0x4c, + 0x58, 0xad, 0x40, 0xbb, 0x8b, 0xce, 0x1f, 0x57, + 0x8e, 0x6a, 0x27, 0x43, 0x46, 0x7f, 0x94, 0xe5, + 0x45, 0x67, 0x12, 0xc8, 0x99, 0x85, 0x08, 0x2a, + 0x37, 0x40, 0x0b, 0xb5, 0xd9, 0xa3, 0xf7, 0xc8, + 0x87, 0xb1, 0xe6, 0x87, 0x2f, 0x86, 0xd8, 0x9c, + 0x7b, 0xec, 0xcf, 0xa4, 0xe5, 0xd5, 0x50, 0x3f, + 0xdf, 0xc9, 0xb7, 0x29, 0x97, 0xd6, 0x33, 0xba, + 0xf0, 0x72, 0xf0, 0x76, 0x12, 0xd3, 0x99, 0x4f, + 0x1b, 0x36, 0xda, 0xa1, 0x83, 0xfe, 0xf5, 0x94, + 0x9e, 0x61, 0x82, 0x62, 0xe0, 0x08, 0x3a, 0xbd, + 0xba, 0x8b, 0x3d, 0xd6, 0xbd, 0x16, 0x5f, 0xd7, + 0x1d, 0x6c, 0x0e, 0x92, 0x89, 0x8c, 0x38, 0x62, + 0x80, 0xee, 0x7e, 0x63, 0x82, 0x88, 0x0b, 0xbf, + 0xdd, 0x9f, 0xbc, 0xba, 0xa7, 0x5a, 0xc6, 0x0d, + 0x87, 0x59, 0xbf, 0x0a, 0x85, 0x06, 0xa3, 0xb4, + 0x66, 0x63, 0xda, 0x12, 0x29, 0x5f, 0x2e, 0x4d, + 0x60, 0xfd, 0x85, 0x76, 0xaf, 0xf7, 0x87, 0xed, + 0x1f, 0x46, 0xc2, 0xd6, 0x6c, 0x98, 0x6b, 0x4b, + 0x60, 0x04, 0xed, 0x89, 0x3b, 0x85, 0x6c, 0xe9, + 0x46, 0xd9, 0xfa, 0x35, 0x61, 0xe8, 0x0c, 0x84, + 0x1b, 0x93, 0xc0, 0xfe, 0x5d, 0x29, 0x14, 0xe1, + 0x1c, 0x66, 0x73, 0xc8, 0x0b, 0x98, 0xff, 0x1a, + 0x78, 0x2b, 0x6a, 0x93, 0x7a, 0x29, 0xd8, 0x7b, + 0xb1, 0x39, 0xf0, 0xad, 0x93, 0x4d, 0x2d, 0xab, + 0x67, 0x3c, 0xa4, 0xa1, 0x08, 0x36, 0x0b, 0xe9, + 0x77, 0xd0, 0xe3, 0x45, 0x7d, 0x99, 0x75, 0xc3, +}; + +/* + * IV method encblkno1, blkno 1. + */ +static const uint8_t aes_cbc_192_encblkno1_vec1_ctxt[SECSIZE] = { + 0xe6, 0x41, 0x75, 0xd6, 0x80, 0xdf, 0x44, 0x37, + 0xa7, 0xa2, 0xb2, 0x29, 0x0d, 0xf0, 0x02, 0x78, + 0x92, 0xb2, 0x06, 0x5f, 0x86, 0xd3, 0x9c, 0xa3, + 0xd0, 0xc5, 0x08, 0x03, 0x6d, 0x41, 0x9d, 0x61, + 0xb4, 0xb9, 0xa1, 0x69, 0x6e, 0x3a, 0x78, 0xd7, + 0x04, 0x94, 0xf2, 0x53, 0xed, 0xd1, 0xf6, 0xd8, + 0x98, 0xe2, 0x49, 0x75, 0x15, 0x85, 0xe0, 0x78, + 0x5b, 0x28, 0x5e, 0xe6, 0xfa, 0x60, 0x3d, 0x4b, + 0x8c, 0xf1, 0x1a, 0xfd, 0x1f, 0xe8, 0xad, 0xb4, + 0xa1, 0xe7, 0xd3, 0x71, 0x16, 0xdf, 0xc6, 0x95, + 0xd4, 0x43, 0xaf, 0x92, 0xab, 0x74, 0x0f, 0x77, + 0x75, 0x4d, 0xd7, 0x13, 0x97, 0x18, 0xea, 0x43, + 0x92, 0x0d, 0x88, 0xc8, 0x41, 0xf7, 0x15, 0x34, + 0x0f, 0x63, 0xbf, 0x50, 0x18, 0xbe, 0x9d, 0x3b, + 0xfc, 0x17, 0x7d, 0x03, 0x39, 0xc2, 0x39, 0x28, + 0xb2, 0x23, 0x1c, 0x7f, 0x3f, 0x19, 0x6c, 0x2f, + 0x64, 0xbd, 0xc9, 0x7d, 0xbe, 0x98, 0xe0, 0x83, + 0xa4, 0x48, 0xfc, 0x89, 0xe7, 0xe0, 0x93, 0x93, + 0x7b, 0x15, 0x35, 0xaf, 0xf8, 0x00, 0x81, 0xcc, + 0x04, 0x80, 0x8b, 0x20, 0xc8, 0x6a, 0xb7, 0x5e, + 0x95, 0xce, 0x69, 0x50, 0x39, 0x88, 0x90, 0x41, + 0x3f, 0xa8, 0x62, 0x42, 0xf1, 0xa9, 0x56, 0xce, + 0x25, 0x53, 0x1d, 0x97, 0x5d, 0x3a, 0x4e, 0x6b, + 0x1f, 0xd6, 0xea, 0x20, 0x81, 0x6c, 0xe5, 0xa1, + 0x0d, 0x9a, 0xd9, 0x3c, 0xbb, 0xbc, 0xc1, 0x77, + 0xe2, 0xf4, 0x9c, 0x11, 0x3a, 0x2f, 0xd0, 0x77, + 0x10, 0xa6, 0x36, 0xd1, 0xbf, 0x3b, 0x50, 0x39, + 0x4b, 0x2c, 0x62, 0x06, 0x1a, 0xe4, 0x18, 0xc0, + 0x35, 0x7c, 0xc3, 0xd0, 0x22, 0xf8, 0xee, 0x19, + 0xa5, 0x3d, 0x69, 0xa9, 0x34, 0xe6, 0x29, 0xf9, + 0xf1, 0xff, 0x26, 0x7a, 0x66, 0x13, 0x1a, 0xa2, + 0xc6, 0xac, 0x84, 0xf6, 0x6b, 0x09, 0xbd, 0x32, + 0x6f, 0x26, 0x37, 0x7c, 0x7d, 0x74, 0xe4, 0xa0, + 0xeb, 0x85, 0x7a, 0xa1, 0x92, 0x19, 0x2e, 0x64, + 0x82, 0x7c, 0x89, 0x1b, 0x14, 0x92, 0xd1, 0xf4, + 0x1f, 0x29, 0x84, 0x04, 0x70, 0x09, 0x13, 0x4c, + 0x62, 0x9a, 0xb4, 0xf7, 0xc1, 0x7b, 0x83, 0xd1, + 0x2d, 0x1a, 0xbe, 0x83, 0x9b, 0x73, 0xba, 0x8d, + 0xbb, 0xb0, 0xf2, 0x5c, 0x72, 0x75, 0x01, 0x0b, + 0xa6, 0x43, 0x6b, 0x76, 0x56, 0x4e, 0x71, 0x1b, + 0xb2, 0x34, 0x1f, 0x70, 0x44, 0xe6, 0xfb, 0x67, + 0xd1, 0x4d, 0x63, 0xce, 0x17, 0x46, 0x9b, 0x11, + 0xda, 0x93, 0xf8, 0x03, 0x11, 0x8f, 0x90, 0xff, + 0x80, 0x85, 0x02, 0x1f, 0xb6, 0x6a, 0x28, 0x3f, + 0x01, 0xa8, 0x36, 0x2e, 0xc7, 0x42, 0xd4, 0x02, + 0x26, 0xea, 0xb5, 0x84, 0x6c, 0x9f, 0xa0, 0x4a, + 0x73, 0x49, 0xea, 0x91, 0x4d, 0x62, 0xf8, 0x23, + 0xe4, 0x3d, 0x91, 0xfb, 0x53, 0x2c, 0x8c, 0xa4, + 0xfe, 0x81, 0x05, 0x5d, 0x4b, 0x9a, 0x75, 0x29, + 0xf8, 0xbe, 0x3f, 0x05, 0xb4, 0x8f, 0xdc, 0xcc, + 0xfa, 0xcc, 0xd7, 0xb2, 0x06, 0x03, 0xd4, 0xf3, + 0x8e, 0x09, 0x09, 0x80, 0xf8, 0xc3, 0x3b, 0x66, + 0xe9, 0x9c, 0x5b, 0x16, 0xed, 0x2d, 0x35, 0x1c, + 0x99, 0x3b, 0x1f, 0x0e, 0x04, 0x30, 0x23, 0x3a, + 0x83, 0x0c, 0xec, 0x76, 0xf2, 0x5d, 0x13, 0x54, + 0x15, 0x62, 0x36, 0x26, 0x6b, 0x21, 0x62, 0xdd, + 0xb4, 0x1a, 0x57, 0x16, 0xfd, 0xa0, 0x9c, 0xfa, + 0x37, 0xb3, 0xda, 0xe0, 0x46, 0x91, 0xb3, 0x20, + 0xe7, 0xe2, 0xf3, 0x0e, 0x20, 0x3c, 0x98, 0x1b, + 0xe4, 0xc2, 0xd3, 0xa9, 0x97, 0xaf, 0x12, 0x69, + 0x23, 0x97, 0x62, 0x6e, 0xae, 0x54, 0x9c, 0x82, + 0x92, 0x50, 0x74, 0x07, 0x4a, 0xb1, 0xdc, 0xcf, + 0x53, 0x1d, 0xc8, 0x29, 0x1f, 0x6e, 0xf1, 0x13, + 0xec, 0xb6, 0x60, 0xb1, 0x4c, 0x9d, 0xd7, 0x77, +}; + +/* + * IV method encblkno1, blkno 2. + */ +static const uint8_t aes_cbc_192_encblkno1_vec2_ctxt[SECSIZE] = { + 0x33, 0xfd, 0xfa, 0x44, 0x64, 0x75, 0x22, 0x7e, + 0xe3, 0xb3, 0xa0, 0x75, 0x99, 0x96, 0xc0, 0xec, + 0x56, 0x06, 0x7d, 0x19, 0x0b, 0x66, 0x89, 0xe0, + 0x69, 0x1d, 0x93, 0x91, 0xd7, 0x0f, 0xf8, 0xf5, + 0x5a, 0x39, 0x30, 0xad, 0x64, 0x42, 0x06, 0xa3, + 0xce, 0x3f, 0x67, 0xd6, 0x6e, 0xcd, 0x3b, 0xf5, + 0x03, 0x2b, 0x07, 0x83, 0x18, 0x1a, 0x4f, 0x4c, + 0xe7, 0x6b, 0xe8, 0xf9, 0x19, 0xa5, 0x23, 0x8f, + 0x46, 0x35, 0x13, 0x7b, 0x61, 0x05, 0xfc, 0x7d, + 0x17, 0x39, 0x03, 0xa8, 0xec, 0x7a, 0xd2, 0x5f, + 0x91, 0xa7, 0x26, 0x07, 0x9d, 0xd7, 0x0c, 0xd7, + 0xd4, 0x8e, 0x37, 0xf3, 0x1a, 0x3c, 0x04, 0x83, + 0x04, 0x71, 0x06, 0xa6, 0x5f, 0x82, 0xe0, 0x6d, + 0x87, 0x5c, 0x7c, 0x03, 0x25, 0x03, 0x4b, 0x24, + 0x07, 0x40, 0xad, 0xe4, 0x1d, 0x1d, 0xcb, 0x34, + 0xc2, 0x53, 0x1d, 0x13, 0xc5, 0x87, 0xab, 0xa7, + 0x95, 0x11, 0x8b, 0xbb, 0xf0, 0xc3, 0x00, 0xeb, + 0xe5, 0xb0, 0x9e, 0x88, 0x8b, 0xad, 0xca, 0xcb, + 0x17, 0xf8, 0x92, 0x4d, 0x00, 0xb0, 0x08, 0x74, + 0x08, 0xb9, 0x8b, 0x95, 0x96, 0xd9, 0x36, 0x35, + 0x31, 0x92, 0x89, 0xf6, 0x35, 0x33, 0xfb, 0x18, + 0x5b, 0x84, 0xa1, 0xfe, 0xe1, 0x62, 0x04, 0x6f, + 0x3c, 0xc1, 0xd2, 0xc2, 0x10, 0xd7, 0x97, 0xba, + 0x29, 0x7c, 0xe3, 0x85, 0xee, 0x59, 0x90, 0xaf, + 0x7f, 0x6f, 0x97, 0x97, 0xa2, 0x41, 0x18, 0x7f, + 0x2f, 0x06, 0x15, 0xb2, 0x46, 0x82, 0x49, 0x39, + 0xd0, 0xfb, 0xa8, 0x48, 0x44, 0x28, 0x58, 0xff, + 0xd8, 0xf2, 0x65, 0xf9, 0x4f, 0x2c, 0xbe, 0xec, + 0xb6, 0xdf, 0x27, 0x1a, 0xf2, 0x05, 0x15, 0x5e, + 0xe3, 0x2a, 0x98, 0x29, 0x92, 0x4a, 0x1b, 0x5d, + 0x5c, 0x2c, 0x70, 0xf6, 0x41, 0xd4, 0xbe, 0x64, + 0xa1, 0xd9, 0x79, 0xf1, 0x11, 0x16, 0xda, 0xa2, + 0xaf, 0xdd, 0x4d, 0xa8, 0xed, 0xec, 0xbe, 0x7d, + 0x49, 0x6c, 0x30, 0xf2, 0xf5, 0x36, 0x3c, 0xae, + 0x4b, 0xa7, 0x77, 0xa3, 0xca, 0x22, 0xa5, 0xe2, + 0x4d, 0x44, 0xcb, 0x36, 0xd5, 0x3f, 0x20, 0x13, + 0xb6, 0xfb, 0xcd, 0x79, 0xd7, 0x42, 0xf9, 0x75, + 0x09, 0x45, 0x28, 0x9e, 0xf2, 0xbd, 0x15, 0x57, + 0xf8, 0x4b, 0xc0, 0xd3, 0xb3, 0xb8, 0xde, 0x55, + 0x9e, 0x11, 0x67, 0xab, 0xc5, 0x5d, 0x58, 0xdb, + 0x4d, 0x20, 0x34, 0x77, 0x33, 0x9c, 0x46, 0x76, + 0x9b, 0x1e, 0x0e, 0x6b, 0x4e, 0xd9, 0x63, 0x68, + 0x78, 0x5e, 0x7c, 0x52, 0xa2, 0x64, 0xa9, 0xfc, + 0x21, 0x35, 0x17, 0x93, 0x18, 0x9e, 0x10, 0xcf, + 0x95, 0x6b, 0xf0, 0x55, 0x46, 0xc3, 0x4b, 0xfc, + 0x86, 0x8b, 0x0d, 0x3b, 0x5c, 0x30, 0xcc, 0xf1, + 0x4c, 0x43, 0xf0, 0xd6, 0xf6, 0x3b, 0x0b, 0x68, + 0x6f, 0x21, 0xd1, 0x61, 0xda, 0x35, 0x92, 0x94, + 0xa5, 0x5d, 0x47, 0x39, 0x96, 0x50, 0x5f, 0xbd, + 0x57, 0x22, 0xd2, 0x65, 0x73, 0x05, 0x8f, 0x2b, + 0xf2, 0x96, 0x53, 0x6b, 0x8e, 0xd3, 0x1e, 0xe7, + 0x92, 0xd4, 0xea, 0x41, 0xee, 0x92, 0x4d, 0x10, + 0x9f, 0x68, 0xd8, 0xe9, 0xac, 0x1f, 0x38, 0x0b, + 0x12, 0xa4, 0x1c, 0xb2, 0x63, 0x2b, 0x87, 0x07, + 0xb8, 0x1e, 0x02, 0x2b, 0x4d, 0xad, 0x99, 0xdf, + 0xe3, 0x98, 0x69, 0x29, 0x11, 0xe3, 0x77, 0x45, + 0x9a, 0xe9, 0x6c, 0x47, 0x4e, 0xc0, 0x85, 0x15, + 0x68, 0x58, 0x41, 0x37, 0xab, 0x96, 0x11, 0x94, + 0x9e, 0xbb, 0xa8, 0x5d, 0x51, 0x05, 0x93, 0xdd, + 0x2e, 0xb8, 0xdf, 0xcf, 0x83, 0xbc, 0xf6, 0x53, + 0x95, 0x93, 0x27, 0xda, 0xa5, 0x20, 0x1b, 0x7d, + 0x1d, 0xd9, 0x0c, 0xde, 0xe5, 0x3f, 0xc8, 0x60, + 0x16, 0x32, 0x95, 0x24, 0xa7, 0x2b, 0x74, 0xf1, + 0x67, 0xf9, 0xf2, 0x49, 0xda, 0x12, 0x97, 0xdd, +}; + +/* + * IV method encblkno1, blkno 3. + */ +static const uint8_t aes_cbc_192_encblkno1_vec3_ctxt[SECSIZE] = { + 0xa5, 0x81, 0x86, 0x78, 0x4a, 0xd7, 0x5b, 0x83, + 0xcf, 0xbf, 0x7e, 0x3c, 0xd7, 0xcd, 0xaf, 0xfa, + 0x82, 0x18, 0xce, 0xbd, 0x8b, 0xe6, 0xd9, 0x39, + 0x22, 0x2d, 0x1e, 0x75, 0x65, 0xee, 0x61, 0xf2, + 0xc3, 0x8b, 0xf4, 0x40, 0x03, 0x73, 0x8a, 0x21, + 0x9f, 0xf3, 0xcc, 0x93, 0x08, 0x3d, 0xff, 0x8a, + 0xbc, 0x0f, 0x19, 0xa1, 0x9f, 0xc8, 0x73, 0xe8, + 0xa6, 0x14, 0x2e, 0x43, 0x19, 0x79, 0x61, 0x35, + 0x8d, 0x55, 0x06, 0xeb, 0x96, 0xe7, 0xf5, 0x4b, + 0x95, 0x5f, 0x9b, 0xb2, 0x18, 0x0d, 0x13, 0xc2, + 0x96, 0x79, 0x50, 0x78, 0x98, 0x50, 0x88, 0x2b, + 0xab, 0x05, 0x66, 0xa1, 0x3a, 0x25, 0x85, 0xe2, + 0xd0, 0xe2, 0xac, 0xb5, 0x26, 0xde, 0x95, 0x04, + 0x45, 0xe7, 0x22, 0x71, 0x02, 0xb3, 0x84, 0x4c, + 0xb5, 0xad, 0x64, 0x5c, 0x27, 0x5c, 0x71, 0xcd, + 0x0b, 0x62, 0x91, 0xd6, 0x84, 0x00, 0x62, 0x52, + 0x54, 0xbd, 0x22, 0xc8, 0x57, 0xa7, 0x41, 0xac, + 0xc7, 0xa8, 0x56, 0x6f, 0x1b, 0x7e, 0xce, 0x02, + 0x29, 0x3b, 0xc0, 0x5d, 0x8e, 0x11, 0xa9, 0x54, + 0xc2, 0xf2, 0xf0, 0x81, 0x6c, 0x9a, 0x24, 0x5b, + 0x81, 0x7d, 0xf3, 0x84, 0x93, 0xc6, 0x2a, 0xd4, + 0xd3, 0x1a, 0x2f, 0x97, 0x2e, 0x31, 0x8a, 0x62, + 0x43, 0xcb, 0xc7, 0x3d, 0x73, 0x8e, 0xd6, 0x86, + 0x17, 0x8f, 0x63, 0xd4, 0xb1, 0x50, 0x92, 0xce, + 0x90, 0x37, 0x91, 0xce, 0x37, 0x13, 0x8e, 0x61, + 0x21, 0xd8, 0x1a, 0xbf, 0x42, 0x65, 0x1d, 0x86, + 0x07, 0x04, 0x9b, 0xd1, 0xd3, 0x26, 0x6b, 0x7c, + 0xa1, 0x77, 0x54, 0x5b, 0x9f, 0x95, 0x62, 0x43, + 0xb3, 0x71, 0x1e, 0x4c, 0x32, 0xd1, 0x3e, 0xe8, + 0x60, 0x9c, 0x0c, 0x15, 0x55, 0xf0, 0x38, 0xb7, + 0x1e, 0x40, 0xe5, 0x26, 0x4e, 0x46, 0x49, 0x47, + 0x59, 0x3d, 0x49, 0x76, 0x28, 0xd3, 0xed, 0x03, + 0xdd, 0xf8, 0x1a, 0xf4, 0x1a, 0xfe, 0xe4, 0x03, + 0xb9, 0xa5, 0x8e, 0x7c, 0x91, 0x7a, 0xb2, 0x17, + 0x84, 0x97, 0x3f, 0x12, 0x68, 0xaa, 0xf5, 0x73, + 0xbc, 0x84, 0xdd, 0x03, 0x4a, 0xc4, 0xcd, 0xdb, + 0xb0, 0x8a, 0x3b, 0xac, 0xf1, 0xdd, 0x10, 0x20, + 0x69, 0xee, 0x94, 0xcd, 0x60, 0x3f, 0x01, 0xcf, + 0xf4, 0xff, 0xdb, 0x91, 0x8a, 0xf3, 0xb8, 0x44, + 0x62, 0xdc, 0xdc, 0xc8, 0x2b, 0xaf, 0x0d, 0x5e, + 0x1b, 0x58, 0x7f, 0x6b, 0x0d, 0xc4, 0xd4, 0x1c, + 0x89, 0x29, 0x60, 0x5d, 0xe9, 0x59, 0xbb, 0x19, + 0x03, 0x7c, 0x25, 0x63, 0xc6, 0x89, 0x6f, 0xe6, + 0xbe, 0xcd, 0xaa, 0xf2, 0xbf, 0x16, 0xcb, 0x47, + 0xc6, 0x74, 0xdd, 0x90, 0x41, 0x75, 0x7f, 0x26, + 0x7b, 0x5a, 0xb9, 0x11, 0xa0, 0xc7, 0x75, 0x60, + 0xc5, 0x54, 0x7d, 0xb0, 0xb4, 0xd0, 0x95, 0x01, + 0xff, 0x07, 0x49, 0x56, 0xfb, 0xec, 0xa9, 0x4c, + 0x68, 0x28, 0x41, 0x81, 0x80, 0x05, 0x88, 0x58, + 0xf5, 0xdc, 0x42, 0x99, 0xd8, 0xb7, 0x47, 0xd9, + 0xf7, 0x0e, 0x2c, 0x0f, 0x95, 0x04, 0xb3, 0xc8, + 0x8a, 0xe2, 0x21, 0x57, 0x8d, 0x64, 0x54, 0x40, + 0xf6, 0xd0, 0x3c, 0x97, 0xcf, 0x22, 0xce, 0xcd, + 0xbf, 0x05, 0x15, 0xaa, 0x89, 0xd9, 0x2b, 0x48, + 0xaf, 0x34, 0xe0, 0xf5, 0xe3, 0x58, 0x06, 0xd7, + 0x49, 0x00, 0x95, 0x3a, 0xb3, 0xc8, 0xcd, 0x2b, + 0x3e, 0xe8, 0x1b, 0x60, 0xe8, 0xea, 0xaf, 0x09, + 0xbb, 0xee, 0xce, 0xbc, 0xa0, 0x9b, 0x17, 0x90, + 0x42, 0x40, 0x18, 0x35, 0x2e, 0x17, 0xa0, 0x6e, + 0x43, 0xe7, 0xac, 0x89, 0x96, 0x3c, 0x16, 0xe0, + 0xdb, 0x09, 0x51, 0x4a, 0x45, 0x33, 0x63, 0xe9, + 0x4e, 0x3f, 0x32, 0x34, 0x36, 0x43, 0xd5, 0x0c, + 0x5a, 0x2e, 0x0e, 0x8b, 0x80, 0xb7, 0xf4, 0xe4, + 0x99, 0x9b, 0x05, 0xf5, 0xb2, 0xe4, 0x03, 0xe4, +}; + +const struct testvec aes_cbc_192_1_vectors[] = { + { + .blkno = 0, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_192_encblkno1_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_192_encblkno1_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_192_encblkno1_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_192_encblkno1_vec3_ctxt, + }, +}; + +/* + * IV method encblkno8, blkno 0. + */ +static const uint8_t aes_cbc_192_encblkno8_vec0_ctxt[SECSIZE] = { + 0x87, 0x9c, 0x05, 0xd6, 0x25, 0xb9, 0xe0, 0xbe, + 0x78, 0x21, 0x85, 0x81, 0x8e, 0x2f, 0x13, 0x5e, + 0xf2, 0x73, 0x11, 0xfa, 0x73, 0x77, 0x93, 0x5e, + 0x71, 0x16, 0x98, 0x68, 0x6f, 0xe8, 0x22, 0x34, + 0xf5, 0x11, 0xfa, 0x61, 0xe6, 0x1a, 0xfb, 0x42, + 0xa7, 0xa3, 0x2e, 0x0d, 0xc1, 0x9d, 0x7d, 0xd9, + 0xfb, 0xbb, 0xc5, 0x08, 0x9d, 0xc2, 0xab, 0x5c, + 0xdf, 0x9b, 0x3c, 0x1a, 0xbd, 0x66, 0x5a, 0x91, + 0x1c, 0x00, 0x59, 0x2e, 0x92, 0xe9, 0x23, 0xf6, + 0x90, 0x3d, 0x5b, 0x72, 0x76, 0x78, 0xd9, 0xa2, + 0x48, 0x33, 0x29, 0xe2, 0xfd, 0x77, 0x14, 0xda, + 0x01, 0x92, 0x63, 0xdd, 0x8c, 0x1c, 0x2e, 0xf7, + 0x61, 0xfb, 0xc5, 0x76, 0xec, 0x7f, 0xef, 0xdc, + 0xbe, 0x2d, 0x3b, 0x69, 0x30, 0xb9, 0x08, 0x00, + 0xe8, 0x37, 0x09, 0xaa, 0x2a, 0x02, 0x80, 0x11, + 0x91, 0x16, 0x94, 0x7d, 0xb5, 0xdc, 0x9f, 0xb3, + 0xb0, 0x26, 0x72, 0x85, 0x93, 0x85, 0x19, 0x08, + 0x97, 0xef, 0x97, 0x57, 0xa8, 0x76, 0x0e, 0x85, + 0xb1, 0x1d, 0x79, 0xe3, 0x7a, 0xe8, 0x06, 0x3b, + 0xc4, 0x00, 0xbd, 0xaa, 0xd9, 0x17, 0x81, 0x37, + 0x12, 0x86, 0x52, 0xea, 0x04, 0xb2, 0x11, 0x0f, + 0x5a, 0x08, 0x68, 0xcb, 0x48, 0xca, 0x2f, 0xda, + 0xa3, 0x0a, 0x60, 0x57, 0xc7, 0x80, 0x36, 0x60, + 0x05, 0xce, 0xd5, 0x43, 0xc9, 0xbc, 0x6c, 0xe6, + 0x63, 0x38, 0x2e, 0x81, 0x90, 0x34, 0x11, 0x2c, + 0x84, 0x0c, 0x62, 0x68, 0xde, 0x17, 0x57, 0x43, + 0x19, 0xa5, 0x92, 0x9d, 0x91, 0x2b, 0xa2, 0x95, + 0x7c, 0x20, 0x72, 0xaa, 0x83, 0x24, 0x54, 0x94, + 0x10, 0x80, 0xd4, 0x3f, 0x58, 0xb9, 0x7b, 0x74, + 0x68, 0xd5, 0xfb, 0x3e, 0xdd, 0xb4, 0xdf, 0x65, + 0x72, 0x88, 0x45, 0x8a, 0xd0, 0x93, 0x6e, 0x99, + 0x84, 0xad, 0x39, 0x73, 0x16, 0x88, 0xdc, 0x89, + 0x33, 0x34, 0xd7, 0xd8, 0x97, 0xfb, 0x90, 0xd2, + 0xc5, 0x8e, 0x94, 0xc4, 0xf1, 0xfe, 0xbe, 0x23, + 0xf1, 0x3a, 0x10, 0x1c, 0x42, 0x6b, 0xf5, 0xee, + 0xe4, 0x78, 0x8a, 0x7e, 0x13, 0x02, 0x25, 0xcb, + 0xd1, 0x61, 0x1f, 0xab, 0x45, 0x1f, 0x90, 0x88, + 0x0f, 0x6b, 0xff, 0x61, 0xba, 0xf3, 0xac, 0x8e, + 0x13, 0xc2, 0xfb, 0xca, 0x41, 0xed, 0xfe, 0x6c, + 0xcb, 0xdf, 0x97, 0x60, 0x29, 0x8a, 0x72, 0x8d, + 0x7d, 0xad, 0x6e, 0xe9, 0x7b, 0xc4, 0x92, 0x14, + 0x5e, 0x33, 0x27, 0xe2, 0xda, 0x2f, 0x95, 0x5f, + 0x40, 0x27, 0xeb, 0xdb, 0x0d, 0x1e, 0xc5, 0xd4, + 0x43, 0x50, 0x1a, 0x62, 0x82, 0xbe, 0x24, 0x7f, + 0xb7, 0x46, 0xa8, 0x70, 0x10, 0x33, 0xb6, 0x3f, + 0xbf, 0xa8, 0xa8, 0x85, 0xab, 0x1d, 0xb4, 0x3f, + 0x84, 0x06, 0x91, 0xd6, 0x18, 0x3d, 0xeb, 0x8b, + 0x3f, 0x9b, 0x37, 0x9e, 0x2e, 0xd2, 0xec, 0xe5, + 0x2d, 0xf0, 0x3f, 0x45, 0xd5, 0x9d, 0xb9, 0x28, + 0x89, 0xe4, 0x0c, 0xa9, 0x38, 0xca, 0x22, 0x56, + 0x53, 0xdf, 0x49, 0xba, 0x5d, 0x99, 0xd6, 0x4b, + 0x1d, 0x0d, 0x6d, 0xee, 0x7c, 0xf2, 0x6f, 0x50, + 0x04, 0xf1, 0xf8, 0x49, 0xd1, 0x2f, 0x50, 0x3e, + 0xf1, 0x08, 0x49, 0x17, 0x08, 0xd2, 0xac, 0x5d, + 0x58, 0xe7, 0x27, 0xe6, 0x59, 0x02, 0x9f, 0x1c, + 0x40, 0xff, 0x6c, 0x67, 0xae, 0x49, 0x1a, 0x2a, + 0xab, 0xd9, 0x63, 0x25, 0x2d, 0x9b, 0xd8, 0x1a, + 0x41, 0xa6, 0xea, 0x72, 0xfd, 0x56, 0xa1, 0x57, + 0x59, 0xdd, 0xf5, 0xa3, 0xb2, 0x2f, 0x64, 0xb1, + 0xc5, 0xfe, 0x8d, 0x9b, 0x93, 0xd1, 0x51, 0x77, + 0x13, 0x50, 0x74, 0x30, 0x28, 0xe4, 0x7a, 0x06, + 0x69, 0xd4, 0xa8, 0x0a, 0xae, 0x02, 0x4a, 0x61, + 0x24, 0xc2, 0xcd, 0xc8, 0xd3, 0x12, 0x2e, 0xac, + 0x9a, 0x0c, 0x24, 0x06, 0xb8, 0x1e, 0x3d, 0x29, +}; + +/* + * IV method encblkno8, blkno 1. + */ +static const uint8_t aes_cbc_192_encblkno8_vec1_ctxt[SECSIZE] = { + 0x1e, 0x3b, 0x66, 0x76, 0xd9, 0x9e, 0xf7, 0x82, + 0x17, 0x76, 0x69, 0x4d, 0x64, 0x63, 0xf1, 0x01, + 0x81, 0x8a, 0xa4, 0x97, 0x05, 0x42, 0xdb, 0x8c, + 0x27, 0xc8, 0xfd, 0x08, 0x21, 0x17, 0x87, 0xa9, + 0x0c, 0x86, 0x2d, 0xda, 0x17, 0xd5, 0x5d, 0x67, + 0x12, 0x93, 0x8d, 0x34, 0x5a, 0xfc, 0x2a, 0x49, + 0x1a, 0x1a, 0x77, 0x20, 0xfb, 0x1d, 0x5d, 0xd8, + 0x99, 0xb0, 0x8f, 0x1c, 0x13, 0x4d, 0x28, 0x6d, + 0x2d, 0x79, 0xa9, 0x8e, 0x04, 0x0c, 0x5a, 0xd5, + 0x52, 0x09, 0x15, 0x4a, 0xfb, 0x7a, 0xf8, 0xdc, + 0x3b, 0x77, 0xaf, 0xe0, 0x80, 0x6b, 0xac, 0x5f, + 0xc0, 0x0f, 0x0f, 0x29, 0xf5, 0xcc, 0xbc, 0x85, + 0x77, 0xe7, 0x9f, 0x59, 0x23, 0x83, 0x67, 0x74, + 0x3b, 0x1c, 0x0f, 0x75, 0xd8, 0x58, 0xa2, 0xce, + 0x8c, 0x3a, 0x80, 0xd7, 0xff, 0xa1, 0x83, 0xa3, + 0xe0, 0xad, 0x18, 0x7a, 0xc5, 0x28, 0x28, 0x71, + 0x46, 0xb5, 0x13, 0x76, 0x4d, 0x67, 0x37, 0x38, + 0x3f, 0x9e, 0xa6, 0x8b, 0xc2, 0xaf, 0x83, 0x7d, + 0x8b, 0x82, 0xd0, 0xe2, 0xec, 0x13, 0xce, 0x2b, + 0x1e, 0x13, 0xe7, 0xb6, 0xfa, 0x9e, 0xa2, 0x32, + 0xb7, 0xdc, 0xe5, 0xb5, 0x35, 0xa3, 0xb4, 0x84, + 0x57, 0x05, 0x2d, 0x3e, 0xb0, 0x0a, 0x52, 0x61, + 0x00, 0xe4, 0x84, 0xab, 0xf4, 0x98, 0xe4, 0xe6, + 0xcd, 0xb1, 0xd4, 0x40, 0x31, 0x5f, 0x8f, 0x73, + 0x16, 0x6e, 0xc0, 0x3d, 0x07, 0x5d, 0x6b, 0x91, + 0x70, 0x71, 0x8a, 0x4b, 0xfe, 0xeb, 0xbe, 0x04, + 0x5d, 0x75, 0x0a, 0x74, 0x52, 0x1e, 0xd3, 0x94, + 0xc5, 0xcd, 0xc1, 0xd6, 0x12, 0x6a, 0x58, 0x52, + 0x6e, 0x45, 0x1f, 0x49, 0x09, 0x4c, 0x32, 0xf3, + 0x3d, 0x3d, 0x73, 0x15, 0xa3, 0xa5, 0x2f, 0xf2, + 0x02, 0x10, 0x1e, 0xaf, 0xf5, 0xb4, 0x78, 0x48, + 0x8a, 0x6c, 0x58, 0x71, 0x77, 0x91, 0x95, 0x57, + 0x79, 0xbf, 0x1f, 0x3e, 0xb3, 0xf8, 0xc4, 0x33, + 0x07, 0x5d, 0x96, 0x41, 0x76, 0xb1, 0xe1, 0xe0, + 0xa9, 0x97, 0x14, 0x99, 0x1d, 0xaa, 0x91, 0xbb, + 0xdf, 0x89, 0xf1, 0x0d, 0xd0, 0x52, 0xf9, 0xa7, + 0x4c, 0x82, 0xc0, 0xeb, 0xb7, 0xaf, 0x7b, 0x4b, + 0x5a, 0x2a, 0x7a, 0x4e, 0xb2, 0x69, 0x87, 0x28, + 0x84, 0xf7, 0x76, 0x56, 0xee, 0xf8, 0x37, 0x35, + 0xc9, 0xbc, 0x08, 0x8b, 0xfe, 0x1e, 0x54, 0xb3, + 0x01, 0xa7, 0x0f, 0x20, 0x70, 0xac, 0xa6, 0x6b, + 0x9f, 0x98, 0xfe, 0xdb, 0x3e, 0x4f, 0x9f, 0xfc, + 0x95, 0x37, 0xf4, 0x90, 0x61, 0x62, 0x60, 0xeb, + 0x7a, 0x4a, 0x56, 0xae, 0x49, 0xcc, 0x92, 0xff, + 0xd3, 0x06, 0xc6, 0x62, 0x4c, 0x05, 0x28, 0xa7, + 0x3f, 0xe9, 0xee, 0x70, 0x6f, 0xd2, 0x80, 0x41, + 0x4d, 0xa0, 0xbc, 0x00, 0xaf, 0x30, 0xe4, 0x34, + 0x61, 0xda, 0xb4, 0xff, 0x2a, 0x85, 0x8b, 0x1a, + 0xbf, 0xb5, 0xe4, 0x7f, 0x27, 0xee, 0xf3, 0x25, + 0xe6, 0x52, 0x2a, 0x83, 0xbe, 0xe4, 0x64, 0xc3, + 0x67, 0x0c, 0x9e, 0x0f, 0xba, 0xb4, 0x67, 0xd1, + 0x1b, 0x4a, 0xb0, 0xb2, 0xb4, 0xf2, 0x8a, 0x1b, + 0x21, 0x34, 0x3c, 0x97, 0x5a, 0xdb, 0x92, 0x8b, + 0x2d, 0xe9, 0x94, 0x4e, 0x11, 0xfb, 0xd4, 0x2e, + 0xc2, 0xed, 0xf9, 0x75, 0xfd, 0x1a, 0xef, 0x3b, + 0x98, 0x5d, 0xa9, 0x75, 0xd5, 0x14, 0x0a, 0xe3, + 0xda, 0x07, 0xa6, 0x20, 0x7b, 0x49, 0x47, 0x87, + 0xff, 0xf0, 0xe8, 0x7e, 0xcf, 0xc4, 0x2c, 0x02, + 0xdd, 0x53, 0xe9, 0x79, 0xc7, 0x6d, 0x16, 0x9f, + 0x2b, 0xd7, 0x1a, 0x36, 0x25, 0x5c, 0xba, 0x5c, + 0xdb, 0x44, 0x88, 0x99, 0x32, 0x2e, 0xb6, 0x3f, + 0xb4, 0xdd, 0x15, 0xeb, 0xec, 0x2a, 0x9e, 0xc5, + 0x37, 0x30, 0x2a, 0xd5, 0xc4, 0x2a, 0x9b, 0x40, + 0x97, 0x83, 0x94, 0xe7, 0x79, 0x79, 0x63, 0x4b, +}; + +/* + * IV method encblkno8, blkno 2. + */ +static const uint8_t aes_cbc_192_encblkno8_vec2_ctxt[SECSIZE] = { + 0x34, 0x07, 0x20, 0x14, 0x64, 0x0b, 0xa2, 0x2c, + 0xed, 0xba, 0x46, 0x24, 0xa0, 0xe6, 0x99, 0x8a, + 0x20, 0x75, 0x5f, 0x9f, 0x2a, 0x10, 0xa6, 0x1c, + 0x52, 0x60, 0x18, 0x67, 0xd6, 0x0d, 0x90, 0x4e, + 0xbc, 0x25, 0x5f, 0x81, 0xb4, 0x10, 0xdb, 0xd9, + 0xaf, 0x36, 0x84, 0x5c, 0x20, 0x25, 0x25, 0xbf, + 0x0d, 0xfa, 0xc5, 0x75, 0x2b, 0xec, 0xf2, 0xa6, + 0x69, 0x5c, 0xfe, 0xee, 0x21, 0xd8, 0x87, 0xdf, + 0xe3, 0x83, 0xeb, 0xb3, 0x3f, 0x5b, 0xda, 0x37, + 0x11, 0x05, 0xf7, 0xd8, 0xe0, 0x94, 0x08, 0x2b, + 0x75, 0x6b, 0xf3, 0x40, 0x53, 0x85, 0xde, 0x7a, + 0x64, 0xb1, 0x0e, 0x5f, 0x01, 0xb5, 0xfb, 0x74, + 0x48, 0x9a, 0xd4, 0x41, 0x33, 0x70, 0x9b, 0x08, + 0x7e, 0x34, 0x60, 0xfc, 0xfa, 0xe6, 0x2c, 0xec, + 0x0e, 0xb7, 0x1a, 0xf1, 0x49, 0x48, 0x0c, 0xd4, + 0xd7, 0xbc, 0x60, 0x28, 0xdb, 0x57, 0xa4, 0x29, + 0x55, 0x2d, 0x92, 0xa6, 0xca, 0x9a, 0xaf, 0x4d, + 0x7f, 0xb8, 0x29, 0x9f, 0x50, 0x98, 0x21, 0x94, + 0x7a, 0x94, 0x44, 0x3d, 0xd1, 0xcf, 0xf4, 0x6f, + 0xad, 0xb4, 0x58, 0x66, 0x74, 0x01, 0x2c, 0x5b, + 0x8f, 0x1b, 0xa6, 0x09, 0xd0, 0x3f, 0x79, 0xc9, + 0x4f, 0x3b, 0x37, 0x0d, 0xb8, 0x07, 0xb0, 0x61, + 0xbc, 0x5a, 0x40, 0x3a, 0x10, 0x3c, 0x12, 0xe6, + 0x04, 0xc7, 0xd1, 0xe1, 0x18, 0x6f, 0xde, 0x72, + 0xf5, 0xcf, 0x24, 0x58, 0x76, 0xe1, 0xcd, 0x62, + 0x90, 0xc3, 0x16, 0xcc, 0x3f, 0xda, 0xd6, 0x6b, + 0x6a, 0xcc, 0x61, 0x76, 0xc1, 0xaf, 0xdc, 0x53, + 0xef, 0x06, 0x23, 0x22, 0x93, 0x11, 0x59, 0xf5, + 0x7f, 0x46, 0xac, 0xb8, 0x6c, 0x3b, 0x36, 0x69, + 0xc5, 0x14, 0x0a, 0x51, 0xa1, 0x5f, 0xb9, 0xc7, + 0x37, 0xe3, 0xd9, 0xaf, 0x8c, 0xe9, 0x49, 0xd4, + 0xf9, 0xf9, 0x5e, 0x1f, 0x5f, 0x7c, 0x07, 0xb5, + 0x1c, 0x9e, 0xbd, 0x10, 0x75, 0xc3, 0x93, 0x48, + 0xdc, 0x32, 0xe7, 0x55, 0x90, 0x48, 0x42, 0xc0, + 0x73, 0x20, 0x40, 0x17, 0xbb, 0x71, 0x30, 0xfe, + 0xd1, 0x84, 0xe9, 0x7d, 0x92, 0xd4, 0xff, 0xbe, + 0x3e, 0xd9, 0x41, 0xfb, 0x41, 0x43, 0x2b, 0x9f, + 0x04, 0x7b, 0xe7, 0x81, 0xbb, 0x2a, 0xd6, 0x7b, + 0x96, 0x72, 0x29, 0x30, 0x52, 0x5c, 0xea, 0xcc, + 0x4c, 0x77, 0xed, 0x5a, 0xd9, 0xab, 0x51, 0x90, + 0x21, 0x3b, 0x5b, 0x26, 0xeb, 0x14, 0xd5, 0xea, + 0x01, 0xb0, 0x7c, 0xbd, 0xa6, 0x3d, 0x7f, 0x42, + 0xd7, 0x7e, 0xf1, 0x6c, 0x71, 0x7d, 0xc0, 0x25, + 0x61, 0xe9, 0x66, 0xe1, 0xf2, 0x67, 0x99, 0xa1, + 0xe7, 0x3a, 0x6f, 0x88, 0x1e, 0x8b, 0x76, 0xed, + 0x50, 0x2c, 0x4e, 0xac, 0x73, 0xd7, 0xf2, 0x85, + 0x8f, 0xcc, 0xb1, 0x4f, 0x6c, 0x9a, 0xf7, 0x45, + 0x28, 0x4f, 0xfc, 0x3f, 0xf1, 0x80, 0xc3, 0xf3, + 0xce, 0x5e, 0xfc, 0x56, 0xd9, 0x45, 0xdd, 0x81, + 0xe3, 0x48, 0x22, 0xc9, 0xb8, 0x13, 0xc1, 0x48, + 0x6c, 0x95, 0x97, 0xc0, 0x91, 0x37, 0xf5, 0x8a, + 0x11, 0x3b, 0xab, 0xce, 0x7a, 0xb0, 0xb4, 0x4c, + 0xba, 0xc0, 0x91, 0x7f, 0x3c, 0x27, 0xe9, 0xc0, + 0x58, 0x92, 0x70, 0x67, 0xf4, 0x80, 0x40, 0x92, + 0x51, 0x80, 0x8e, 0x9d, 0x2d, 0x87, 0x89, 0x8e, + 0xe7, 0xd1, 0xb5, 0xc5, 0x4f, 0xd0, 0x86, 0x31, + 0x7f, 0x90, 0x77, 0x05, 0x35, 0xfe, 0xa7, 0xcb, + 0x9d, 0x94, 0xf3, 0xf8, 0xbb, 0x4f, 0xe1, 0xb3, + 0x48, 0x57, 0xbf, 0xd1, 0x77, 0xe8, 0x72, 0x31, + 0x4d, 0x2f, 0xe8, 0xa0, 0xf4, 0x7c, 0x25, 0x9c, + 0xcd, 0xa5, 0x7e, 0xd3, 0x30, 0xda, 0x46, 0xf5, + 0x48, 0x9e, 0x39, 0x34, 0x94, 0xd6, 0x24, 0x10, + 0xfc, 0x74, 0x2b, 0x6d, 0xcc, 0x00, 0x76, 0x3e, + 0x3b, 0x85, 0xfa, 0xef, 0x87, 0x70, 0x53, 0x4e, +}; + +/* + * IV method encblkno8, blkno 3. + */ +static const uint8_t aes_cbc_192_encblkno8_vec3_ctxt[SECSIZE] = { + 0xfe, 0xad, 0xf3, 0x4a, 0x9d, 0x64, 0x4e, 0x5d, + 0xaf, 0xa8, 0x44, 0x7e, 0xc9, 0x75, 0xe8, 0xd0, + 0x87, 0x73, 0x66, 0x4c, 0x77, 0x00, 0xfb, 0x7b, + 0x04, 0xe7, 0xd8, 0x82, 0x75, 0xe3, 0xa5, 0xbc, + 0xf3, 0x80, 0xae, 0x7c, 0xc9, 0x75, 0x9a, 0xc1, + 0x73, 0x49, 0x69, 0xf6, 0xa0, 0x49, 0x6e, 0x77, + 0x5f, 0x9b, 0x95, 0x9b, 0x9f, 0x41, 0x54, 0x57, + 0x0e, 0x3c, 0xe5, 0x2c, 0xbb, 0xbf, 0xd5, 0x76, + 0xf6, 0xb6, 0x05, 0xaa, 0x20, 0x5b, 0xdb, 0xcb, + 0x81, 0xad, 0x0c, 0x8a, 0x68, 0x94, 0x7d, 0x88, + 0xdc, 0x15, 0x6c, 0x89, 0x97, 0x53, 0x30, 0x96, + 0x4a, 0x54, 0xf9, 0x88, 0x00, 0xf7, 0x3b, 0x99, + 0xfc, 0x82, 0xe3, 0x48, 0xd2, 0x16, 0x2b, 0xba, + 0xd4, 0xba, 0x24, 0xd0, 0xd1, 0xb0, 0x8e, 0xcd, + 0x77, 0xdc, 0x01, 0xdf, 0xb2, 0x20, 0xc5, 0xa7, + 0x48, 0x2a, 0xcf, 0x56, 0xc8, 0x63, 0x6e, 0xc9, + 0xa8, 0xa4, 0xc2, 0x9c, 0x66, 0x25, 0x50, 0x77, + 0x08, 0x51, 0x92, 0xce, 0x3c, 0xaf, 0xff, 0xee, + 0x3e, 0x6d, 0x61, 0x37, 0xcd, 0x85, 0x67, 0x9c, + 0xe0, 0x7e, 0xa6, 0x17, 0x7b, 0x5f, 0x6a, 0xe2, + 0x4e, 0x76, 0xca, 0x95, 0x88, 0xdf, 0xad, 0x78, + 0x91, 0xfa, 0x9e, 0x71, 0x3e, 0xfd, 0x10, 0x78, + 0x32, 0x2b, 0x75, 0xbc, 0x3a, 0x06, 0x55, 0x8b, + 0x9b, 0xfb, 0x9c, 0x4b, 0xa1, 0x7d, 0x35, 0x3d, + 0x63, 0x80, 0x30, 0x61, 0xe0, 0x2d, 0x8a, 0x28, + 0xb4, 0x2d, 0x48, 0x9d, 0x27, 0x1a, 0x28, 0x86, + 0xfc, 0xfa, 0x93, 0xcf, 0x3e, 0x9c, 0x41, 0xc8, + 0xc5, 0x5e, 0x88, 0x22, 0xb8, 0xaf, 0x1d, 0x92, + 0xc5, 0x91, 0x1b, 0x1e, 0x95, 0x62, 0xbb, 0x80, + 0x0c, 0xae, 0x2a, 0xb3, 0x55, 0x77, 0x86, 0x39, + 0xa6, 0xed, 0xc1, 0xd2, 0xc4, 0x95, 0x7e, 0xd4, + 0xbe, 0xf3, 0x1b, 0xbc, 0x5e, 0x92, 0x0d, 0x9c, + 0x38, 0xb1, 0xb9, 0xd3, 0xf6, 0x3f, 0x97, 0xf9, + 0x48, 0x08, 0x2b, 0xa6, 0x98, 0x50, 0xc9, 0x84, + 0xec, 0x54, 0xe0, 0x1a, 0x65, 0x76, 0xf2, 0xbe, + 0x62, 0xb9, 0x40, 0x3a, 0xb1, 0xef, 0xa0, 0x51, + 0xab, 0x3a, 0xfa, 0xaf, 0x33, 0x32, 0xa5, 0x0c, + 0xc7, 0x9a, 0x9c, 0x5c, 0xa7, 0x8e, 0xc6, 0x4e, + 0x61, 0xe3, 0x83, 0xa1, 0xd4, 0x2c, 0xb2, 0x2c, + 0x46, 0x5a, 0xbf, 0x96, 0xeb, 0xda, 0x45, 0x2d, + 0x25, 0x37, 0x69, 0x1a, 0x6b, 0xd6, 0xbc, 0xe1, + 0x28, 0x65, 0xf9, 0xfc, 0xa7, 0xda, 0xf8, 0x79, + 0x87, 0x18, 0x99, 0x01, 0x74, 0x5a, 0x42, 0x79, + 0x8e, 0xe4, 0x23, 0x1a, 0x6c, 0xda, 0x93, 0x0f, + 0x19, 0xf0, 0xff, 0x0e, 0x25, 0x45, 0x1e, 0xbb, + 0x17, 0xca, 0x87, 0x6a, 0x9e, 0xd0, 0xd3, 0xd5, + 0x22, 0x5f, 0xce, 0x92, 0xeb, 0x82, 0x8e, 0x3e, + 0x4e, 0x99, 0x44, 0xa2, 0x9e, 0x78, 0x53, 0x89, + 0x4e, 0x45, 0x51, 0x41, 0x28, 0x91, 0xdb, 0x7e, + 0x8f, 0xac, 0xc2, 0xee, 0x09, 0xcb, 0xed, 0x04, + 0x7b, 0x37, 0xa1, 0x1d, 0x9c, 0x90, 0x19, 0xb1, + 0xdd, 0xc3, 0x22, 0xc8, 0x70, 0x07, 0x26, 0xce, + 0x4a, 0xc4, 0xde, 0xee, 0x87, 0xf3, 0x62, 0x69, + 0xed, 0xb2, 0x2d, 0x10, 0xc4, 0xfa, 0x86, 0x2e, + 0xd1, 0xb8, 0x58, 0xa3, 0xa4, 0x0b, 0x30, 0x87, + 0x23, 0x62, 0xed, 0xf3, 0x7b, 0x80, 0x7e, 0x4f, + 0xc2, 0xb3, 0xe8, 0xba, 0x25, 0x3e, 0xd3, 0x12, + 0x7e, 0x27, 0xd5, 0x72, 0x3b, 0x02, 0xf4, 0xfd, + 0x2f, 0x8b, 0xc2, 0x5f, 0x44, 0x40, 0x31, 0x88, + 0x73, 0x81, 0xa3, 0xcc, 0xc4, 0x78, 0x2b, 0xfc, + 0x41, 0x2e, 0xb2, 0xd0, 0xb4, 0x00, 0x29, 0xc1, + 0x46, 0xdf, 0xc1, 0xbd, 0x15, 0x59, 0xa3, 0x6a, + 0xc8, 0x2f, 0x29, 0x28, 0x12, 0x9b, 0x1e, 0xea, + 0x4e, 0xa9, 0x80, 0xa1, 0xb8, 0x89, 0x21, 0x3b, +}; + +const struct testvec aes_cbc_192_8_vectors[] = { + { + .blkno = 0, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_192_encblkno8_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_192_encblkno8_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_192_encblkno8_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_192_encblkno8_vec3_ctxt, + }, +}; + +/* + * IV method encblkno1, blkno 0. + */ +static const uint8_t aes_cbc_256_encblkno1_vec0_ctxt[SECSIZE] = { + 0x1a, 0xa4, 0xe3, 0x09, 0x23, 0x2e, 0x91, 0x1b, + 0xa8, 0x3e, 0xda, 0x92, 0xb3, 0x22, 0xd2, 0xe8, + 0x8b, 0xed, 0x6c, 0xa7, 0x78, 0xe6, 0x32, 0x25, + 0xc4, 0x88, 0xd5, 0xb7, 0x6e, 0xef, 0xbf, 0x37, + 0x00, 0xd9, 0xb2, 0x55, 0x10, 0x4f, 0x7d, 0x84, + 0x3a, 0xae, 0xd2, 0xc6, 0x48, 0xdd, 0x3c, 0xd5, + 0x9b, 0xa7, 0xf8, 0xc2, 0xda, 0x6d, 0x14, 0xa2, + 0xdc, 0x54, 0x12, 0x8f, 0x1c, 0x22, 0x98, 0x6a, + 0xc0, 0x5f, 0x47, 0xa7, 0x78, 0xec, 0x79, 0x5d, + 0x04, 0xed, 0x5e, 0x20, 0x33, 0x53, 0x66, 0x40, + 0x83, 0x94, 0x5b, 0x34, 0x05, 0x25, 0x2e, 0x17, + 0xba, 0x23, 0x60, 0xb1, 0xd0, 0x27, 0xf0, 0x24, + 0xd2, 0x0b, 0xd3, 0xea, 0xa7, 0x13, 0x1e, 0xf9, + 0x56, 0xe1, 0xd4, 0xa2, 0x89, 0x5a, 0xaa, 0x42, + 0xa9, 0xd7, 0x85, 0x64, 0x9e, 0x44, 0x71, 0xa2, + 0xf9, 0xc3, 0xf4, 0x81, 0xbd, 0xa0, 0x40, 0xed, + 0x33, 0xeb, 0x09, 0x0f, 0x7f, 0x78, 0xe4, 0xd5, + 0x7b, 0x61, 0x42, 0xee, 0x65, 0x25, 0xcc, 0xba, + 0xc6, 0x99, 0x29, 0x25, 0x71, 0x9a, 0xf0, 0x0e, + 0x98, 0x3f, 0x12, 0xf2, 0xf9, 0x4d, 0x00, 0x3c, + 0xbe, 0x9f, 0x2b, 0x83, 0x1e, 0x5b, 0xab, 0x80, + 0x4c, 0x81, 0x82, 0x29, 0xbb, 0xeb, 0xc0, 0x89, + 0x07, 0x43, 0xdd, 0x69, 0xd3, 0x02, 0x6c, 0x1c, + 0x4b, 0xab, 0x44, 0x42, 0x6c, 0x25, 0xfc, 0xf5, + 0x73, 0xaa, 0x60, 0x48, 0xbc, 0xd2, 0x1c, 0x77, + 0x8b, 0x64, 0x3e, 0x5f, 0x24, 0xae, 0x14, 0x65, + 0xea, 0x18, 0xb1, 0xab, 0xbc, 0x3d, 0xa3, 0xb9, + 0xfc, 0xcc, 0x0f, 0x8d, 0x8e, 0x13, 0x0f, 0x4d, + 0x4e, 0xeb, 0x90, 0x9b, 0x1e, 0xbf, 0x2a, 0xc7, + 0xac, 0x5b, 0x11, 0xeb, 0x67, 0xf2, 0x9d, 0xef, + 0xf3, 0x66, 0x9e, 0x81, 0x9f, 0x24, 0x4d, 0xcd, + 0x4f, 0x31, 0xce, 0xc9, 0xa4, 0x2c, 0xd7, 0x58, + 0x7c, 0x2e, 0x88, 0xa2, 0xec, 0x4c, 0x02, 0x29, + 0x00, 0xbd, 0x14, 0x0f, 0xaa, 0xd8, 0xc3, 0x02, + 0x64, 0xdc, 0xa0, 0x15, 0xc8, 0xf6, 0x17, 0x8b, + 0x9c, 0xb3, 0xf2, 0x27, 0xc1, 0x3f, 0x60, 0x94, + 0x33, 0x10, 0x89, 0x49, 0x5f, 0xd2, 0x0e, 0xfe, + 0x9e, 0x99, 0x68, 0x95, 0xe4, 0x12, 0xfc, 0xe3, + 0x7f, 0xc4, 0xb1, 0x88, 0x4f, 0x66, 0xcd, 0x24, + 0x89, 0x09, 0xbb, 0x01, 0xf6, 0x9a, 0xe4, 0x41, + 0xee, 0x83, 0xd2, 0x28, 0xf5, 0x28, 0x49, 0x13, + 0x78, 0xfb, 0xb2, 0x0d, 0x5c, 0x97, 0xf4, 0x9c, + 0xe0, 0xdf, 0xef, 0x84, 0x36, 0x7d, 0xe5, 0x45, + 0xe0, 0xf8, 0xce, 0x82, 0x39, 0xc4, 0x54, 0x69, + 0xf1, 0x62, 0x7d, 0x1a, 0xf6, 0x6c, 0x20, 0x86, + 0x72, 0x4b, 0xf9, 0x3d, 0x87, 0x68, 0xec, 0x74, + 0x67, 0xee, 0xbd, 0xb8, 0xc6, 0x12, 0x91, 0x0f, + 0xf6, 0xd9, 0x4f, 0x34, 0x96, 0xa9, 0xe7, 0x52, + 0x7b, 0xe0, 0x08, 0x57, 0x0a, 0x8b, 0x09, 0xcb, + 0xd3, 0x3e, 0x4e, 0x64, 0xca, 0x38, 0x50, 0x07, + 0x0e, 0x7b, 0x95, 0x69, 0x1b, 0x82, 0xba, 0x50, + 0x93, 0x4f, 0x9a, 0x8e, 0x11, 0x9b, 0x64, 0xf5, + 0x6a, 0xd4, 0x81, 0xf0, 0x1f, 0xb8, 0x85, 0x90, + 0x9c, 0x79, 0xde, 0xcb, 0x50, 0xba, 0xa9, 0x56, + 0x66, 0xd1, 0x1e, 0x78, 0xa8, 0x6a, 0xd5, 0xa5, + 0x83, 0x73, 0xe2, 0x88, 0xf2, 0x04, 0x33, 0x61, + 0xdf, 0x89, 0xd5, 0x3d, 0x03, 0x4e, 0x94, 0xb0, + 0x0f, 0x8d, 0x4d, 0xb4, 0x09, 0xb2, 0xf1, 0xb0, + 0xe7, 0xfe, 0xb0, 0x18, 0xe2, 0xfc, 0x92, 0xeb, + 0x2d, 0x7d, 0x56, 0x29, 0xbd, 0x34, 0x20, 0x7c, + 0xb6, 0xe7, 0x7b, 0xd7, 0x95, 0xa5, 0x0d, 0x10, + 0xbc, 0x7d, 0x9d, 0xd9, 0xbe, 0xc7, 0x23, 0x44, + 0x37, 0xb3, 0x98, 0x36, 0x33, 0x1a, 0x11, 0xfe, + 0x41, 0xea, 0x59, 0x48, 0x75, 0x34, 0xf6, 0xc4, +}; + +/* + * IV method encblkno1, blkno 1. + */ +static const uint8_t aes_cbc_256_encblkno1_vec1_ctxt[SECSIZE] = { + 0x58, 0xfc, 0x1e, 0x48, 0x66, 0x7d, 0x91, 0xc7, + 0x56, 0xa3, 0x41, 0x89, 0xe8, 0x1e, 0x02, 0x77, + 0x93, 0x38, 0x12, 0x99, 0x06, 0x0d, 0xf3, 0x6d, + 0x2a, 0x5d, 0x3d, 0x7b, 0x4e, 0x05, 0x4f, 0x8f, + 0xe3, 0x86, 0x76, 0xfe, 0x11, 0x9d, 0xde, 0xd4, + 0x83, 0xd9, 0x47, 0x8d, 0x51, 0xdf, 0x4a, 0x24, + 0x2d, 0x11, 0xf0, 0xbd, 0xde, 0x17, 0x7e, 0x52, + 0x20, 0xc7, 0x17, 0x88, 0x2e, 0xa4, 0xd5, 0xa0, + 0x1e, 0xbc, 0x61, 0x15, 0x1e, 0x52, 0xa1, 0x8b, + 0xe9, 0xe4, 0x1f, 0x81, 0x49, 0x64, 0x17, 0xd4, + 0xef, 0xb6, 0x40, 0x05, 0x2f, 0x36, 0xf7, 0x39, + 0x03, 0x05, 0x80, 0xff, 0xf2, 0x1a, 0x15, 0xf1, + 0xfc, 0xaf, 0x71, 0x51, 0x73, 0xc5, 0x9e, 0x2f, + 0xd1, 0x7a, 0x2d, 0xd7, 0xed, 0x90, 0x11, 0xd2, + 0x80, 0x49, 0x46, 0x9f, 0x13, 0xa7, 0x32, 0x33, + 0x24, 0x39, 0x59, 0xf1, 0xed, 0x64, 0x75, 0x61, + 0xc3, 0x14, 0x68, 0x48, 0xf7, 0xc7, 0xbd, 0xe0, + 0x21, 0x59, 0x91, 0x07, 0x70, 0x83, 0x8f, 0xfc, + 0x59, 0x72, 0xca, 0xdd, 0x60, 0xa0, 0xbb, 0xb1, + 0x2f, 0xb8, 0x98, 0x8d, 0xf2, 0x4d, 0x3a, 0x19, + 0xbc, 0x6b, 0x37, 0xad, 0xd2, 0xb5, 0x7d, 0x1c, + 0x4a, 0x7b, 0x58, 0x76, 0x2e, 0xf5, 0x6b, 0xaf, + 0x4c, 0x92, 0x00, 0x8a, 0xb4, 0xa3, 0x86, 0x66, + 0x07, 0xc7, 0xfc, 0x57, 0x3c, 0x73, 0xf4, 0x8b, + 0xef, 0xb6, 0xae, 0x01, 0xfb, 0x88, 0x13, 0x04, + 0xa8, 0xc7, 0xec, 0xc4, 0xe0, 0x67, 0x3a, 0xfb, + 0x67, 0xce, 0x83, 0x9b, 0x8e, 0x66, 0xff, 0xa6, + 0x17, 0x1b, 0x66, 0x27, 0xdf, 0x2a, 0xfe, 0xf3, + 0x9a, 0xba, 0x59, 0xce, 0x28, 0xd4, 0xd2, 0x40, + 0x78, 0xb6, 0xe9, 0x7d, 0x8b, 0xcc, 0x47, 0x5c, + 0xf6, 0x5d, 0xc2, 0x5d, 0xe0, 0xa7, 0x61, 0x8b, + 0xe6, 0x7d, 0x38, 0xb6, 0xea, 0xfb, 0x13, 0x31, + 0x33, 0x2a, 0xb5, 0x45, 0x7b, 0xf6, 0x9f, 0x29, + 0x06, 0x2d, 0xd8, 0xab, 0x36, 0x27, 0xe4, 0x6c, + 0xf1, 0xab, 0xcd, 0xb9, 0x08, 0x0f, 0x4b, 0x8f, + 0x22, 0xea, 0xe4, 0x5d, 0x22, 0x05, 0x2e, 0xd4, + 0xd7, 0xff, 0x58, 0x50, 0x38, 0x17, 0x6f, 0x80, + 0x61, 0x98, 0xdc, 0xd4, 0x9f, 0x8f, 0xeb, 0x13, + 0xd3, 0x86, 0xe9, 0xa9, 0xe7, 0x07, 0x6f, 0x4f, + 0x54, 0x9e, 0x37, 0x3d, 0xbc, 0x82, 0x5f, 0x4f, + 0xd5, 0x0c, 0x21, 0xaa, 0x91, 0xcb, 0x06, 0x9a, + 0xaf, 0x57, 0x14, 0xfb, 0x57, 0xd8, 0x63, 0x58, + 0x0a, 0x03, 0x12, 0x0e, 0xd3, 0x37, 0x0b, 0xbf, + 0x67, 0xb7, 0x9d, 0xb7, 0x6b, 0x38, 0xeb, 0x17, + 0xd8, 0xb9, 0x5a, 0x37, 0x9f, 0x98, 0xa6, 0xca, + 0x7e, 0x95, 0xa7, 0x27, 0xc4, 0xd3, 0x15, 0x00, + 0x7b, 0x5e, 0x05, 0xc0, 0xc1, 0xb0, 0xe0, 0x13, + 0x7d, 0x91, 0xed, 0x2b, 0x99, 0x74, 0x1c, 0x16, + 0x45, 0x55, 0x21, 0xbc, 0x7c, 0x52, 0x87, 0x0f, + 0xb9, 0xbf, 0x71, 0x7c, 0x3a, 0x81, 0x72, 0x97, + 0xf8, 0x86, 0x61, 0x20, 0x17, 0xd8, 0xc8, 0xe0, + 0xfc, 0x42, 0x0f, 0x5b, 0xd6, 0x7e, 0x99, 0x81, + 0x5c, 0x2e, 0x2e, 0x3e, 0xe8, 0xce, 0x12, 0xcf, + 0x2c, 0xe6, 0x7a, 0x00, 0x5d, 0x36, 0x00, 0x92, + 0x60, 0xc5, 0xc0, 0xfd, 0xe0, 0xa3, 0xb9, 0x3e, + 0x92, 0xf8, 0x8f, 0xe2, 0x0f, 0xe5, 0xb4, 0x6a, + 0xd6, 0x5b, 0xa4, 0x5d, 0xf9, 0xef, 0x7e, 0xae, + 0xdd, 0xd0, 0x5d, 0x40, 0xfe, 0xa7, 0xed, 0xda, + 0xa9, 0x48, 0x1d, 0x6f, 0xc2, 0xd3, 0x35, 0x65, + 0xd8, 0x67, 0xc2, 0x9d, 0xed, 0xf7, 0x9f, 0x7b, + 0x7c, 0xd4, 0x03, 0xe0, 0xa6, 0xf9, 0x3c, 0xd0, + 0x21, 0x98, 0x60, 0xa6, 0x59, 0x86, 0xbd, 0x40, + 0x17, 0x47, 0x82, 0xb9, 0xe1, 0x11, 0x8d, 0x4b, + 0xcd, 0x1f, 0x54, 0x96, 0x17, 0x42, 0x22, 0x44, +}; + +/* + * IV method encblkno1, blkno 2. + */ +static const uint8_t aes_cbc_256_encblkno1_vec2_ctxt[SECSIZE] = { + 0x1d, 0x65, 0xb2, 0x4e, 0xfa, 0x3f, 0xdb, 0xab, + 0x34, 0x9d, 0x37, 0x03, 0x17, 0x44, 0xed, 0x5b, + 0xf7, 0x1b, 0x6b, 0xc0, 0x5c, 0xfe, 0x5b, 0xcd, + 0xf0, 0xaf, 0x26, 0x82, 0x97, 0x12, 0xb8, 0x4f, + 0x76, 0x3d, 0x07, 0xd8, 0x29, 0x56, 0x3c, 0xbd, + 0x0e, 0xac, 0xd1, 0x8f, 0x53, 0x1a, 0x8f, 0xcd, + 0x04, 0x5b, 0x49, 0xe0, 0xf0, 0xea, 0xc9, 0x8a, + 0x08, 0x3d, 0x1f, 0x2d, 0x8c, 0xec, 0xb8, 0xea, + 0xe9, 0x24, 0xd1, 0x93, 0xd7, 0x9a, 0x0f, 0xd7, + 0x0f, 0x6b, 0xa0, 0x08, 0x58, 0x81, 0x68, 0x2f, + 0xde, 0x36, 0xb5, 0x87, 0xd9, 0xcd, 0x82, 0x13, + 0x36, 0x16, 0x6a, 0x9a, 0x02, 0xca, 0xda, 0x6f, + 0x51, 0x87, 0x75, 0x47, 0x89, 0xa4, 0x10, 0x60, + 0xfb, 0x1a, 0x74, 0x55, 0x6d, 0x18, 0x8d, 0x42, + 0x74, 0x2d, 0x12, 0x56, 0xc0, 0xcd, 0xa2, 0x57, + 0x53, 0x31, 0x8c, 0x7a, 0x8b, 0xa8, 0x6d, 0x89, + 0x81, 0xaf, 0x9c, 0xd9, 0x56, 0xe6, 0xdc, 0xe7, + 0x84, 0x0f, 0x81, 0x56, 0x1a, 0xc8, 0x5d, 0xa3, + 0xe0, 0x93, 0xea, 0x62, 0x7d, 0xa4, 0x5a, 0x58, + 0x8f, 0x05, 0x85, 0x34, 0x0c, 0x74, 0x8e, 0xe7, + 0xb4, 0x47, 0x93, 0x61, 0xbf, 0x61, 0x0a, 0xa2, + 0x37, 0xcd, 0x82, 0x9d, 0x55, 0x9e, 0x32, 0x9e, + 0x30, 0xce, 0x61, 0x89, 0xed, 0x25, 0x9e, 0x7c, + 0x2a, 0xcd, 0x39, 0x45, 0x56, 0xbb, 0x1a, 0xe8, + 0xb0, 0x75, 0x8f, 0xa1, 0x59, 0x09, 0xf8, 0x7a, + 0xbd, 0x4f, 0x69, 0x8b, 0xe2, 0xf3, 0xbe, 0x9b, + 0xea, 0x5f, 0x2c, 0x1e, 0x84, 0x69, 0xb2, 0xfa, + 0xaf, 0x1d, 0xc8, 0xcf, 0x76, 0x91, 0xd0, 0x7a, + 0xc9, 0xd1, 0x3d, 0xa5, 0xae, 0xae, 0xd7, 0x23, + 0xbb, 0xb3, 0x5e, 0x8a, 0x10, 0xc6, 0xbe, 0xa6, + 0x79, 0x69, 0x40, 0x83, 0x81, 0xe6, 0xb1, 0xa3, + 0x7e, 0x57, 0x44, 0x66, 0xc9, 0x2e, 0x84, 0xdd, + 0x00, 0xb4, 0x93, 0xae, 0x8f, 0x23, 0x12, 0xd6, + 0x54, 0x56, 0xc3, 0x51, 0xe5, 0xf7, 0x69, 0x47, + 0x00, 0x97, 0x71, 0x29, 0xcb, 0xcf, 0xeb, 0xd9, + 0xaf, 0xc0, 0x2f, 0x5c, 0xd7, 0x3e, 0xe4, 0x07, + 0xc9, 0x65, 0x2e, 0x8c, 0xf4, 0x54, 0xce, 0x8b, + 0xc7, 0x0c, 0xb4, 0x74, 0x56, 0x79, 0xa6, 0x40, + 0x4a, 0x58, 0xfd, 0x3f, 0x7b, 0x4c, 0xe9, 0xdb, + 0x33, 0x85, 0x6f, 0xf7, 0x5a, 0x9f, 0x6f, 0xc4, + 0x60, 0xad, 0x1b, 0xe2, 0xf5, 0xeb, 0x42, 0x7d, + 0xa4, 0x43, 0x8d, 0x40, 0xfa, 0x53, 0xcc, 0xf0, + 0x5f, 0x90, 0x0d, 0x04, 0x51, 0xb1, 0x48, 0xc7, + 0x90, 0x65, 0xb2, 0xef, 0xca, 0xc5, 0x9a, 0xec, + 0xde, 0x84, 0x21, 0x22, 0xeb, 0x97, 0xdd, 0xa2, + 0x9d, 0x71, 0xb1, 0xe0, 0x86, 0x58, 0xc3, 0x57, + 0xd5, 0x5a, 0x6f, 0xdc, 0xe5, 0xcc, 0x64, 0xc7, + 0x80, 0x2a, 0xef, 0x90, 0x91, 0x96, 0xb4, 0xeb, + 0xda, 0x3b, 0x7b, 0xbc, 0x14, 0x60, 0x52, 0xe5, + 0xe5, 0xc8, 0x6a, 0x99, 0x46, 0x9d, 0x00, 0x77, + 0x3b, 0x60, 0x75, 0x04, 0x06, 0x4a, 0x5a, 0x64, + 0x6f, 0x2f, 0x58, 0x77, 0x27, 0x9a, 0xc5, 0x90, + 0x37, 0xa7, 0xf3, 0x89, 0x72, 0x47, 0x4e, 0x08, + 0xa5, 0x79, 0x11, 0x2f, 0x22, 0x5a, 0xbb, 0xcf, + 0x76, 0xb9, 0x28, 0xc8, 0xc4, 0x5a, 0xe5, 0x90, + 0xf7, 0x02, 0xe4, 0xf9, 0x0c, 0x4c, 0x9a, 0xb1, + 0xa7, 0x99, 0x34, 0xd4, 0x77, 0x66, 0xff, 0x3c, + 0x50, 0x9a, 0xff, 0x13, 0x49, 0xd6, 0x5a, 0xf6, + 0x17, 0x6f, 0xca, 0x1a, 0xef, 0x0a, 0x2d, 0xf1, + 0xdf, 0xd0, 0xa5, 0x6f, 0xa6, 0x22, 0x3c, 0x1f, + 0xcf, 0xe7, 0xec, 0x23, 0x39, 0x6e, 0xc0, 0x37, + 0x31, 0x84, 0xff, 0xe2, 0x5a, 0xd6, 0x88, 0x74, + 0x15, 0x15, 0x46, 0x21, 0x00, 0xe4, 0x13, 0x9a, + 0xfa, 0xb2, 0x49, 0x7e, 0x79, 0xfb, 0x8a, 0x2a, +}; + +/* + * IV method encblkno1, blkno 3. + */ +static const uint8_t aes_cbc_256_encblkno1_vec3_ctxt[SECSIZE] = { + 0xc1, 0x4a, 0x3c, 0x90, 0xba, 0xd4, 0x9c, 0xe7, + 0xf2, 0x5b, 0x3a, 0xc4, 0xce, 0x4a, 0x26, 0x4a, + 0x9c, 0x3f, 0xe5, 0x7a, 0x15, 0xbb, 0xbd, 0x3e, + 0xc6, 0x49, 0x47, 0x04, 0x4e, 0x8b, 0x73, 0xa6, + 0x02, 0x3a, 0xc1, 0xa3, 0xfa, 0x1a, 0xd0, 0x03, + 0xf7, 0x26, 0x9f, 0xad, 0x06, 0x8f, 0x86, 0xdc, + 0xb8, 0x73, 0x87, 0xa2, 0x82, 0xc6, 0x80, 0xe1, + 0xac, 0x3d, 0x16, 0x4c, 0xc3, 0x7c, 0x86, 0x01, + 0xa5, 0x7a, 0x1c, 0x4b, 0x56, 0x68, 0xf6, 0x06, + 0x99, 0x32, 0x42, 0x40, 0xf1, 0xb7, 0x44, 0x4b, + 0xd1, 0xdb, 0xad, 0x4e, 0xa6, 0xc2, 0x5f, 0xee, + 0x21, 0x1d, 0x58, 0xc6, 0xd5, 0x02, 0xef, 0xb2, + 0x38, 0xef, 0x29, 0x25, 0xfd, 0x28, 0x8a, 0x5b, + 0x8b, 0x36, 0x1a, 0xd6, 0x68, 0xf8, 0x77, 0xed, + 0xba, 0xb3, 0xa5, 0x6f, 0x76, 0x5e, 0xb5, 0xd4, + 0xc3, 0xb8, 0xf9, 0x67, 0x7a, 0x18, 0x43, 0xb6, + 0x65, 0x07, 0x48, 0x1d, 0x56, 0x20, 0x11, 0xe1, + 0x62, 0x6b, 0x70, 0xc9, 0x18, 0xa9, 0xa7, 0x36, + 0xbf, 0x31, 0x74, 0xe3, 0x33, 0x02, 0x96, 0x7a, + 0xf5, 0xd9, 0x8d, 0x05, 0x2b, 0xfd, 0x85, 0x4f, + 0x03, 0x0f, 0xe1, 0xfb, 0x1a, 0x57, 0xaf, 0xdc, + 0xff, 0xff, 0x5a, 0x96, 0x27, 0xca, 0xf3, 0x0c, + 0xd8, 0x39, 0x3e, 0xbe, 0x41, 0x5a, 0x21, 0x95, + 0x66, 0xe0, 0x69, 0x14, 0x2b, 0x18, 0xf2, 0x9b, + 0xf4, 0x22, 0xdf, 0xa9, 0xe4, 0x7d, 0x32, 0x5d, + 0x98, 0xa0, 0xe0, 0xe1, 0xe1, 0xbe, 0xae, 0x58, + 0x63, 0xbe, 0x4b, 0x97, 0x83, 0xaa, 0x67, 0xd3, + 0x1a, 0x70, 0xca, 0x82, 0x98, 0x77, 0x74, 0x1a, + 0xf2, 0x3d, 0x6a, 0x7b, 0x8e, 0xc8, 0xca, 0x34, + 0x44, 0xb8, 0xc0, 0xd0, 0x77, 0x8c, 0x4a, 0x5c, + 0xae, 0xd3, 0x17, 0x7c, 0x12, 0x47, 0x3e, 0xe2, + 0x2e, 0x51, 0xe0, 0x52, 0x88, 0x8e, 0xe9, 0x68, + 0xb6, 0x13, 0xf8, 0x69, 0xc9, 0x4b, 0xdd, 0x91, + 0x27, 0xb0, 0x22, 0x0c, 0x7d, 0xad, 0xb0, 0x75, + 0xe8, 0x76, 0x34, 0xc2, 0xd9, 0xf3, 0x20, 0xf7, + 0x1d, 0x0f, 0x07, 0x61, 0xc2, 0xb8, 0x7d, 0x00, + 0xa6, 0x68, 0xad, 0xd4, 0x0b, 0xa4, 0xa0, 0x32, + 0x6d, 0xa5, 0xc0, 0x07, 0x65, 0xae, 0xda, 0x2e, + 0xd6, 0xb7, 0xd3, 0x99, 0x8b, 0x37, 0x08, 0x13, + 0x6a, 0x94, 0xe9, 0xe4, 0xea, 0x34, 0xee, 0x07, + 0xee, 0x77, 0xb1, 0x3f, 0x54, 0x05, 0xbe, 0x66, + 0x7f, 0xf2, 0x70, 0x34, 0x45, 0xa7, 0x4b, 0x27, + 0xef, 0xe6, 0x39, 0x2e, 0x13, 0x41, 0xdb, 0x2d, + 0x1f, 0x76, 0x11, 0x76, 0x33, 0xf3, 0x92, 0x33, + 0x69, 0x16, 0x34, 0x86, 0x23, 0xc5, 0xfa, 0xaf, + 0xff, 0xbf, 0xee, 0x84, 0x56, 0xf6, 0x1e, 0x54, + 0x37, 0x32, 0x79, 0x83, 0x45, 0x04, 0x6f, 0x0e, + 0x75, 0x75, 0xd9, 0xd6, 0x4a, 0x87, 0xfb, 0x3c, + 0xb1, 0xcf, 0x66, 0xab, 0xa4, 0xaa, 0xf6, 0x96, + 0xb0, 0xcd, 0xaf, 0xac, 0x2c, 0x6d, 0x72, 0xca, + 0x43, 0xef, 0xb7, 0xa0, 0x4c, 0x62, 0xba, 0x7e, + 0x59, 0x0b, 0xff, 0x90, 0x49, 0x63, 0xf6, 0x31, + 0x8b, 0x50, 0x20, 0x82, 0x7d, 0xf0, 0x2d, 0xe4, + 0x5b, 0xda, 0xdf, 0xb0, 0xfb, 0x07, 0x7b, 0xe3, + 0x5f, 0xac, 0xd8, 0xe5, 0xa0, 0x3e, 0xc5, 0x60, + 0x94, 0xbc, 0xf7, 0x7e, 0xdc, 0x18, 0x27, 0x20, + 0xb1, 0xdd, 0x51, 0x4a, 0xb2, 0xe0, 0xc0, 0xe7, + 0x5d, 0x0f, 0x88, 0xb2, 0xa0, 0x42, 0x73, 0xfb, + 0xc4, 0x24, 0xa7, 0x17, 0x8a, 0xc9, 0x6d, 0x34, + 0xe8, 0x7b, 0x51, 0x37, 0x32, 0x3f, 0xf8, 0x7e, + 0x92, 0xe4, 0x87, 0xd2, 0x89, 0x66, 0xb0, 0xf6, + 0xc2, 0xba, 0x2f, 0x42, 0x8f, 0x1d, 0x5d, 0x81, + 0xad, 0xfd, 0x00, 0xbc, 0xa9, 0x11, 0x96, 0xae, + 0x80, 0xf1, 0x27, 0xe0, 0xeb, 0x5b, 0x60, 0x39, +}; + +const struct testvec aes_cbc_256_1_vectors[] = { + { + .blkno = 0, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_256_encblkno1_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_256_encblkno1_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_256_encblkno1_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_256_encblkno1_vec3_ctxt, + }, +}; + +/* + * IV method encblkno8, blkno 0. + */ +static const uint8_t aes_cbc_256_encblkno8_vec0_ctxt[SECSIZE] = { + 0xe5, 0x55, 0xd9, 0xae, 0xc0, 0x66, 0x2d, 0x2f, + 0x11, 0xb1, 0x27, 0xd2, 0xb2, 0x73, 0xe4, 0x0a, + 0x85, 0xb5, 0x3c, 0x79, 0x78, 0xd6, 0x35, 0x3d, + 0x46, 0xac, 0xa3, 0x81, 0x55, 0x76, 0x86, 0xfc, + 0x37, 0xa0, 0x95, 0xc2, 0x30, 0xc9, 0x19, 0xc2, + 0x5f, 0xb0, 0x13, 0xa2, 0xa8, 0xe1, 0xc7, 0xb7, + 0x61, 0x54, 0xd8, 0xe6, 0xca, 0x94, 0x6f, 0x47, + 0x87, 0x33, 0x58, 0xd9, 0xd5, 0xd2, 0x95, 0x73, + 0x87, 0x9a, 0x31, 0xe5, 0x2e, 0x95, 0x83, 0x7d, + 0xdc, 0x0f, 0xc5, 0x2f, 0x14, 0xbc, 0x80, 0xac, + 0x47, 0xd6, 0xd8, 0x17, 0x9e, 0xf7, 0xff, 0x5b, + 0x85, 0x05, 0x91, 0xe0, 0x73, 0xd2, 0x5c, 0xa7, + 0x41, 0xf8, 0xcb, 0x3d, 0x38, 0x14, 0x28, 0x3e, + 0x89, 0x6f, 0xd4, 0xac, 0xb6, 0x11, 0x35, 0x67, + 0x7b, 0xef, 0x0d, 0xd8, 0x4d, 0xdd, 0x7e, 0x73, + 0xcd, 0x58, 0x0f, 0x5a, 0xcf, 0x42, 0xc5, 0x2f, + 0x61, 0x62, 0x13, 0xde, 0xcd, 0x2e, 0x22, 0xab, + 0xb0, 0x47, 0x5c, 0x1e, 0x5c, 0xc5, 0x49, 0xc6, + 0x3b, 0x0c, 0xe3, 0xb3, 0x59, 0xbf, 0xbf, 0x85, + 0xf6, 0x0a, 0x3d, 0x14, 0x74, 0x2a, 0xcd, 0xea, + 0x67, 0xd6, 0x80, 0x42, 0x3c, 0x6a, 0x92, 0x50, + 0x95, 0x73, 0xb5, 0x7a, 0xb2, 0xbc, 0x76, 0xe5, + 0x8f, 0xf3, 0x85, 0x5e, 0xcd, 0xf9, 0xb4, 0x9d, + 0xa8, 0x0a, 0xda, 0x95, 0x11, 0x2e, 0x22, 0x0c, + 0x2f, 0xb0, 0xbf, 0x92, 0x6b, 0x45, 0xec, 0x20, + 0xd2, 0x2b, 0x98, 0x3f, 0x4f, 0x97, 0xf2, 0xed, + 0xf7, 0x9b, 0x89, 0x4e, 0xd6, 0x59, 0xbb, 0x24, + 0x22, 0x44, 0x9f, 0x03, 0xb5, 0x42, 0xc8, 0x97, + 0xc7, 0xdb, 0x21, 0xfc, 0xcf, 0x33, 0xa1, 0xf1, + 0xc0, 0x1f, 0x28, 0x77, 0xee, 0xa5, 0x6a, 0x12, + 0xef, 0x8b, 0x48, 0xd1, 0xb3, 0xac, 0x65, 0x69, + 0x46, 0x04, 0x39, 0xb1, 0x9e, 0xfa, 0xab, 0x21, + 0x51, 0xa4, 0x33, 0xe9, 0x58, 0x5d, 0xf1, 0xc6, + 0x69, 0x44, 0x8c, 0x17, 0xf9, 0xaa, 0x96, 0xcb, + 0x40, 0xb4, 0x5c, 0x83, 0x76, 0x1e, 0x8a, 0x2b, + 0x5f, 0x6b, 0xc1, 0x73, 0xd4, 0x5f, 0x48, 0xa3, + 0x0e, 0x07, 0x69, 0x12, 0xc1, 0xbd, 0x13, 0xad, + 0xe2, 0xcf, 0x3d, 0x96, 0xd8, 0xaf, 0xed, 0xdc, + 0x4c, 0x72, 0xf6, 0xce, 0x15, 0x86, 0x88, 0x8c, + 0xbb, 0x60, 0xb3, 0xb9, 0xde, 0x42, 0x58, 0x6e, + 0xc4, 0x58, 0xac, 0x77, 0x8d, 0x35, 0x23, 0x5f, + 0xc3, 0xf9, 0x33, 0x46, 0x17, 0x80, 0x31, 0xfd, + 0xcd, 0x0a, 0x1e, 0x9b, 0xac, 0x42, 0xda, 0x70, + 0x54, 0x9a, 0xeb, 0x22, 0x27, 0x09, 0x0c, 0x6c, + 0x18, 0x1d, 0x1a, 0x5b, 0x86, 0x4d, 0x80, 0xca, + 0x4d, 0xda, 0x0e, 0x9a, 0x8e, 0x61, 0x04, 0x68, + 0x29, 0x08, 0x3b, 0xae, 0x14, 0x7d, 0x8e, 0x43, + 0x7a, 0xa7, 0x83, 0xcf, 0xb3, 0x95, 0xd3, 0x42, + 0x2d, 0x6b, 0xd8, 0x5c, 0x43, 0x31, 0x5b, 0x9c, + 0x18, 0x30, 0x0d, 0x61, 0x9c, 0xab, 0x29, 0x55, + 0xdd, 0x84, 0x24, 0x21, 0xec, 0x44, 0xad, 0xf3, + 0xb3, 0x70, 0x77, 0x2b, 0xfc, 0x3f, 0x99, 0xb8, + 0x50, 0x26, 0x8d, 0x96, 0xa2, 0x22, 0x99, 0x33, + 0x53, 0xa8, 0x5d, 0x84, 0x9b, 0x76, 0x26, 0x6e, + 0x75, 0x14, 0x7e, 0x63, 0xc6, 0x7a, 0x4f, 0x5c, + 0xfe, 0x4b, 0x80, 0xee, 0xb3, 0x32, 0x8d, 0x25, + 0x1c, 0x80, 0x7b, 0x3d, 0xd3, 0x84, 0x01, 0x1e, + 0x16, 0xa4, 0xca, 0x0d, 0x38, 0x40, 0x03, 0x6f, + 0x81, 0x8b, 0x5c, 0xad, 0x22, 0xfa, 0x6f, 0xeb, + 0x60, 0xa1, 0xcb, 0x2d, 0x97, 0xf8, 0xa6, 0x5e, + 0xbe, 0x93, 0xb7, 0xe6, 0x66, 0xbf, 0x9b, 0xd2, + 0x5c, 0x31, 0xcc, 0x70, 0x0c, 0xf1, 0xfb, 0x9f, + 0x09, 0x1b, 0xc2, 0x85, 0x2f, 0x22, 0x7c, 0x95, + 0x58, 0x09, 0xce, 0x9c, 0x7c, 0x50, 0xca, 0x89, +}; + +/* + * IV method encblkno8, blkno 1. + */ +static const uint8_t aes_cbc_256_encblkno8_vec1_ctxt[SECSIZE] = { + 0x37, 0x4d, 0x25, 0xdb, 0x35, 0xe0, 0x8b, 0x82, + 0x5f, 0x77, 0xd2, 0x53, 0xd1, 0x1f, 0xf0, 0x91, + 0x5b, 0xd8, 0x93, 0x2f, 0xb2, 0x81, 0xbd, 0x75, + 0xf0, 0xd8, 0xff, 0x46, 0x8c, 0x9d, 0xf6, 0xe2, + 0x99, 0x1e, 0x76, 0x9d, 0x00, 0x3a, 0xe3, 0xcf, + 0x6d, 0x24, 0xa8, 0xe8, 0xb4, 0xa7, 0xa0, 0x87, + 0xa8, 0x43, 0x01, 0x21, 0x29, 0x70, 0x39, 0x2d, + 0x0b, 0x2a, 0xe9, 0x11, 0x57, 0x86, 0x13, 0xd4, + 0x1c, 0x1b, 0x59, 0x19, 0xc4, 0x7d, 0x2c, 0x94, + 0xc7, 0x01, 0xb8, 0x96, 0x01, 0xd2, 0x01, 0x17, + 0x97, 0x41, 0x68, 0xab, 0xba, 0x9c, 0xc8, 0xad, + 0x4e, 0xd7, 0xa8, 0x4c, 0x96, 0x3f, 0xf9, 0xfc, + 0x7e, 0xd7, 0x59, 0xe8, 0x25, 0x51, 0x4d, 0x1d, + 0x99, 0xfd, 0x0b, 0xe9, 0x88, 0x23, 0xd1, 0x4b, + 0x30, 0x6e, 0x18, 0x7c, 0xe3, 0x7a, 0x54, 0x2a, + 0x4f, 0x2a, 0x99, 0x8f, 0xaf, 0xd7, 0x5e, 0x25, + 0xfe, 0x9c, 0x47, 0x09, 0x63, 0x38, 0x0d, 0x5f, + 0xb3, 0x43, 0xa6, 0x66, 0x9b, 0xc5, 0x3d, 0x88, + 0x5e, 0xc7, 0x60, 0x99, 0x8e, 0xcb, 0x6a, 0x65, + 0x60, 0x92, 0x88, 0xe1, 0x2b, 0xfe, 0x83, 0x34, + 0x92, 0xa6, 0x6c, 0x22, 0x56, 0x5b, 0x75, 0x8a, + 0x93, 0xc3, 0x72, 0xca, 0xff, 0x59, 0x3b, 0xd8, + 0xa0, 0x80, 0x56, 0x98, 0x62, 0x8a, 0x70, 0xf2, + 0x5d, 0xd9, 0x40, 0x6b, 0xbf, 0x9f, 0x71, 0x8d, + 0x2e, 0x38, 0xe8, 0x06, 0x42, 0xa9, 0x95, 0x70, + 0x31, 0xd1, 0xe9, 0x6c, 0xab, 0xbb, 0xed, 0x25, + 0xe8, 0xca, 0xe8, 0xa4, 0x98, 0x82, 0xf5, 0xe3, + 0x11, 0x3c, 0xc4, 0xea, 0xea, 0x88, 0x56, 0x91, + 0xd6, 0x5d, 0xaa, 0xf7, 0xe9, 0x49, 0x2f, 0x42, + 0x5b, 0x76, 0xef, 0xed, 0x03, 0x9e, 0x5f, 0x4d, + 0x65, 0x25, 0xa5, 0xe8, 0x26, 0xba, 0x03, 0x4f, + 0x0e, 0x39, 0xd2, 0x53, 0x62, 0x98, 0x81, 0x9d, + 0x8e, 0xad, 0x50, 0x17, 0x9f, 0xcc, 0x34, 0x45, + 0x19, 0x5c, 0x1c, 0xd1, 0xbc, 0x71, 0x89, 0xaa, + 0x9a, 0x65, 0x55, 0x6f, 0x78, 0xd4, 0xd3, 0x5b, + 0x27, 0x8d, 0x94, 0x46, 0xd9, 0x95, 0xb3, 0x5f, + 0xc4, 0x35, 0x8d, 0xba, 0x1c, 0x40, 0x52, 0xd1, + 0x99, 0x27, 0x5d, 0x42, 0x28, 0xef, 0xcb, 0x9b, + 0x10, 0x7a, 0x19, 0xbf, 0x72, 0xa3, 0x4a, 0xb9, + 0x56, 0x83, 0x39, 0xa6, 0xb2, 0xcd, 0x48, 0x85, + 0xf9, 0xcc, 0x72, 0x88, 0xb3, 0x5a, 0x9b, 0x45, + 0xb2, 0xd3, 0x66, 0x2d, 0x24, 0x51, 0x68, 0x91, + 0x9d, 0x47, 0x6a, 0xb3, 0x9a, 0x60, 0xb3, 0xcd, + 0x6b, 0x43, 0x96, 0x21, 0xa0, 0x65, 0x43, 0xde, + 0x4f, 0x6e, 0xb5, 0x81, 0x50, 0x7e, 0xca, 0x4b, + 0xdb, 0x30, 0xf2, 0xcb, 0x28, 0x3b, 0x19, 0x6a, + 0x0a, 0xfa, 0x05, 0x5e, 0x61, 0xde, 0x76, 0x7e, + 0xdf, 0xd9, 0xa9, 0x1b, 0xd0, 0x8a, 0xb5, 0x04, + 0x51, 0xf5, 0x66, 0xa2, 0x32, 0x21, 0xb2, 0xa9, + 0x40, 0x78, 0x60, 0x9d, 0xdc, 0x45, 0xbe, 0xb4, + 0x3a, 0xba, 0xd1, 0xec, 0x31, 0x53, 0x24, 0x22, + 0x70, 0x99, 0xda, 0xc8, 0x17, 0x04, 0x87, 0x2c, + 0x89, 0x86, 0x24, 0xec, 0x52, 0x12, 0x6a, 0x51, + 0x1e, 0x2a, 0x5e, 0x96, 0xfb, 0xac, 0x95, 0x4a, + 0x1a, 0x06, 0x8f, 0xdf, 0xa7, 0x26, 0xeb, 0x6c, + 0x79, 0x4a, 0x77, 0xea, 0xb3, 0xb1, 0x3a, 0x19, + 0xe6, 0x5e, 0xe2, 0x26, 0x1b, 0x85, 0x3c, 0x9b, + 0x1d, 0x05, 0x1d, 0xbe, 0x5c, 0x25, 0x7f, 0x45, + 0x4c, 0x09, 0x4c, 0xc1, 0x47, 0xa5, 0x44, 0xfc, + 0x04, 0x2b, 0xad, 0x53, 0xac, 0x57, 0x22, 0x54, + 0x13, 0x7c, 0xc9, 0x96, 0x44, 0xda, 0x74, 0x95, + 0x6e, 0x8c, 0xe6, 0x6a, 0x05, 0x05, 0xf3, 0x8c, + 0x81, 0xaf, 0xbc, 0xb1, 0x91, 0xe7, 0xfd, 0x81, + 0x3f, 0x47, 0xc2, 0x6f, 0x0d, 0x62, 0xf6, 0x6e, +}; + +/* + * IV method encblkno8, blkno 2. + */ +static const uint8_t aes_cbc_256_encblkno8_vec2_ctxt[SECSIZE] = { + 0x5a, 0x24, 0xfd, 0xee, 0x9a, 0x44, 0xfb, 0xac, + 0x3e, 0x46, 0x53, 0x95, 0x9e, 0xeb, 0x1f, 0xd9, + 0xfd, 0xc6, 0x4f, 0xae, 0x0b, 0xc8, 0xf2, 0xbd, + 0x77, 0x16, 0x7a, 0x2e, 0x8e, 0xec, 0x7a, 0x53, + 0xf4, 0xe0, 0x34, 0xba, 0x6e, 0xfa, 0xc4, 0x69, + 0xd7, 0x50, 0x13, 0x03, 0xfb, 0xb9, 0x66, 0x96, + 0xd4, 0x21, 0x67, 0xcc, 0x4c, 0x4d, 0x10, 0x2f, + 0x17, 0xeb, 0x41, 0xf4, 0x65, 0x80, 0x0b, 0x57, + 0x2d, 0xdf, 0xcf, 0x9f, 0xb9, 0xd8, 0x53, 0x36, + 0xbc, 0x1d, 0x9a, 0xe3, 0x17, 0xe7, 0x08, 0x23, + 0xb3, 0x60, 0xfe, 0xdf, 0x24, 0x06, 0xc5, 0x86, + 0x74, 0x89, 0xa3, 0xb2, 0xfc, 0x4a, 0x57, 0xf5, + 0xa6, 0x96, 0xfb, 0x56, 0xf0, 0xf4, 0xdc, 0xdc, + 0xb8, 0x53, 0x5f, 0xb2, 0xb0, 0x8d, 0x2d, 0x90, + 0x3d, 0x78, 0x4d, 0x42, 0x3a, 0x74, 0xa4, 0x8e, + 0x41, 0x7c, 0x2a, 0xff, 0xe4, 0x57, 0x1c, 0x9d, + 0x94, 0xc5, 0x5d, 0xd8, 0x8b, 0x88, 0x48, 0x15, + 0x16, 0x8a, 0xf3, 0x07, 0x3a, 0xee, 0x65, 0x24, + 0xbc, 0x7f, 0x58, 0xad, 0xed, 0xf2, 0xbd, 0x18, + 0x88, 0x1a, 0x80, 0x6e, 0xb7, 0x93, 0xe0, 0x45, + 0x04, 0xb0, 0xfc, 0xf9, 0x48, 0x76, 0xaf, 0xec, + 0x08, 0xca, 0x99, 0x64, 0x85, 0x98, 0x2c, 0xd8, + 0x85, 0x72, 0x32, 0xbe, 0x92, 0x18, 0xdd, 0xab, + 0x20, 0x8f, 0x8e, 0x11, 0xc6, 0x08, 0xf9, 0x8b, + 0xaf, 0x5f, 0xa9, 0xe5, 0x11, 0xc7, 0x45, 0x91, + 0x6e, 0x47, 0xaa, 0x0f, 0x4c, 0xf4, 0xc1, 0xb0, + 0x75, 0x4c, 0xba, 0x1d, 0xb3, 0x33, 0xf7, 0x47, + 0xbe, 0x94, 0x0b, 0x2e, 0xfa, 0x38, 0x5e, 0x5f, + 0x0a, 0xc2, 0x0c, 0x4e, 0x72, 0x29, 0x16, 0xc1, + 0x82, 0x70, 0xd4, 0xd3, 0x1b, 0x25, 0xbe, 0x0d, + 0x6b, 0x0a, 0x13, 0x9f, 0x4d, 0x3d, 0x7b, 0x10, + 0x9f, 0x93, 0x43, 0x50, 0xd1, 0x17, 0x08, 0x77, + 0x23, 0x58, 0x35, 0x41, 0x23, 0xf6, 0x9c, 0x6f, + 0x2e, 0x81, 0x6e, 0x75, 0x9b, 0x9f, 0x37, 0x4f, + 0xb7, 0xa1, 0xce, 0xde, 0x0c, 0x74, 0x99, 0x31, + 0x0e, 0x27, 0x42, 0x99, 0xdd, 0x93, 0x03, 0x6b, + 0x44, 0x22, 0xd4, 0xc8, 0x67, 0xb5, 0xb2, 0x4d, + 0x11, 0x2e, 0x80, 0x09, 0xa2, 0x5b, 0xcf, 0x0c, + 0xff, 0xfa, 0x51, 0xe5, 0x9b, 0xdd, 0x11, 0xa1, + 0x17, 0x04, 0x9e, 0xc8, 0xd8, 0x1d, 0xc1, 0x5c, + 0xc3, 0xde, 0x83, 0x77, 0xa3, 0xec, 0x59, 0x7e, + 0xfb, 0xe8, 0x45, 0xff, 0xc3, 0xb3, 0xd3, 0x9e, + 0x3e, 0xc4, 0x75, 0xca, 0xc1, 0x77, 0xee, 0x1a, + 0xdc, 0x58, 0xab, 0x27, 0xc1, 0xfe, 0x21, 0x26, + 0x9a, 0xe0, 0x15, 0xab, 0x35, 0x8d, 0xbc, 0x22, + 0x37, 0xbb, 0x4e, 0xab, 0x9d, 0xa2, 0xaf, 0xf9, + 0x45, 0x17, 0xb1, 0xb8, 0xd4, 0x52, 0x1e, 0x67, + 0xeb, 0xac, 0xe0, 0x87, 0x6c, 0xe4, 0x7a, 0x03, + 0x73, 0xe4, 0x43, 0xeb, 0x3b, 0x57, 0x3f, 0x56, + 0x4b, 0x6c, 0x26, 0x81, 0x27, 0xbf, 0x7e, 0x59, + 0xcd, 0xab, 0x67, 0x8c, 0x4b, 0x6f, 0xa5, 0x47, + 0x2c, 0x45, 0x28, 0x5a, 0x3d, 0x88, 0x53, 0xf9, + 0x25, 0xdf, 0x5d, 0xba, 0xf7, 0x18, 0xa7, 0x3d, + 0x79, 0xb4, 0x43, 0x59, 0x77, 0xf9, 0xd5, 0x5d, + 0x4f, 0x31, 0x56, 0x8c, 0x21, 0xb5, 0xc0, 0xa2, + 0xca, 0x04, 0x62, 0x2c, 0xc8, 0xa8, 0x11, 0x82, + 0x1b, 0xde, 0xad, 0x20, 0x5b, 0xd2, 0x63, 0xfb, + 0x6d, 0xba, 0xd4, 0xcc, 0xb4, 0x9d, 0xe8, 0xa8, + 0xd1, 0x06, 0x81, 0xf0, 0xb9, 0xd4, 0x90, 0x30, + 0xcd, 0x0a, 0xe8, 0xd2, 0x8c, 0x7a, 0xbf, 0xf6, + 0x0d, 0xa0, 0xae, 0x1b, 0x21, 0x18, 0x93, 0x18, + 0x71, 0xe1, 0xa0, 0x63, 0x5a, 0x9d, 0x4e, 0x6a, + 0x52, 0x90, 0xaf, 0xdb, 0x26, 0x1e, 0xa9, 0xa1, + 0xc7, 0xf9, 0xf8, 0xa7, 0x3f, 0x85, 0xa1, 0xa4, +}; + +/* + * IV method encblkno8, blkno 3. + */ +static const uint8_t aes_cbc_256_encblkno8_vec3_ctxt[SECSIZE] = { + 0x83, 0x77, 0xd8, 0xa8, 0x6a, 0x36, 0x41, 0x72, + 0xb6, 0x03, 0x4e, 0x5e, 0x39, 0x36, 0xe3, 0xf5, + 0xd0, 0x1b, 0x0d, 0x97, 0x78, 0x46, 0xee, 0xfd, + 0x34, 0x34, 0x16, 0xa0, 0x44, 0xcf, 0x0b, 0xdc, + 0xfb, 0x82, 0x98, 0xa2, 0x79, 0xc2, 0xe7, 0x1c, + 0x43, 0x43, 0x4c, 0x7f, 0xe7, 0xa6, 0xe6, 0x10, + 0x9e, 0x65, 0xb2, 0x09, 0xc7, 0x5f, 0xaa, 0xb7, + 0xb8, 0xad, 0x83, 0xd5, 0x9e, 0xd1, 0xb2, 0xce, + 0x4b, 0xa4, 0x5d, 0xbc, 0xd6, 0xf6, 0x0a, 0xe7, + 0x1b, 0xe9, 0x86, 0xbc, 0x72, 0xcc, 0x6f, 0xcc, + 0xf2, 0xde, 0x08, 0x48, 0xa2, 0x20, 0x31, 0x6a, + 0xdd, 0xbe, 0xc5, 0x36, 0x55, 0xff, 0xce, 0xfa, + 0xdf, 0x60, 0x26, 0x77, 0x7f, 0xd0, 0xfa, 0xd7, + 0x76, 0x70, 0x14, 0x11, 0xbf, 0x57, 0xc2, 0xdd, + 0x5f, 0xd3, 0x50, 0x49, 0xf8, 0xd1, 0xa7, 0xe2, + 0x8b, 0x89, 0xa0, 0xbc, 0x44, 0x42, 0x45, 0x10, + 0xfe, 0x66, 0x3d, 0x56, 0x09, 0x21, 0x7c, 0x49, + 0x30, 0xde, 0xe2, 0x4b, 0x26, 0x65, 0x8a, 0xe4, + 0x79, 0x08, 0x3a, 0xca, 0x36, 0x4f, 0x97, 0x3c, + 0xe4, 0x6a, 0xc3, 0xdb, 0xce, 0xac, 0x78, 0x76, + 0x25, 0x81, 0x7a, 0x01, 0x7b, 0xd8, 0xf1, 0x00, + 0x8d, 0x2e, 0xb7, 0x98, 0x3c, 0x86, 0x20, 0xa3, + 0x4c, 0x24, 0x2a, 0x78, 0x3a, 0x8d, 0xeb, 0xcd, + 0xae, 0xe1, 0x32, 0xf8, 0x21, 0x37, 0x30, 0x27, + 0xe1, 0xf3, 0x14, 0x60, 0x96, 0x77, 0x37, 0x50, + 0xa2, 0x92, 0xae, 0xe5, 0xd8, 0xea, 0x1a, 0x7e, + 0xa3, 0xd1, 0x04, 0x17, 0x03, 0x51, 0x2f, 0x21, + 0xa7, 0x00, 0x23, 0xb3, 0x24, 0xd8, 0x7d, 0xb7, + 0x4c, 0x51, 0xb1, 0xaf, 0xb0, 0x64, 0xe4, 0x62, + 0x91, 0x4c, 0xd5, 0x4b, 0xe8, 0xfb, 0x95, 0x61, + 0xa4, 0x6f, 0xf8, 0xb8, 0xea, 0xa9, 0xb2, 0x10, + 0xd3, 0x96, 0xcb, 0x1c, 0xdc, 0x86, 0x43, 0x26, + 0x2d, 0x39, 0xc2, 0xa7, 0x69, 0xfa, 0x8f, 0x3a, + 0xe7, 0xe0, 0x27, 0xbe, 0xc2, 0xe8, 0xd5, 0x05, + 0xbe, 0x5a, 0x96, 0xdc, 0x86, 0xcd, 0x93, 0x75, + 0x1b, 0x61, 0x40, 0x8c, 0x60, 0x64, 0x79, 0x85, + 0x6c, 0xed, 0x39, 0x72, 0x26, 0x69, 0xba, 0xb2, + 0xff, 0xa8, 0x68, 0x29, 0x03, 0xf7, 0x26, 0xe7, + 0x0f, 0x53, 0x1b, 0x5b, 0x37, 0x21, 0x68, 0x70, + 0x1c, 0x39, 0x7f, 0x5b, 0x31, 0xca, 0xde, 0xed, + 0x33, 0x8d, 0xaf, 0xe6, 0x01, 0xd5, 0x72, 0x5f, + 0x46, 0x44, 0x34, 0x1b, 0x4c, 0xd7, 0x75, 0xf0, + 0x47, 0x16, 0x6c, 0xd6, 0x65, 0x3c, 0xd3, 0xc2, + 0xb1, 0x46, 0x7d, 0xd5, 0x5c, 0x48, 0x5b, 0x61, + 0x3e, 0x88, 0xff, 0x24, 0x5c, 0x7b, 0xf7, 0xa9, + 0x44, 0xcb, 0x3b, 0x3e, 0x3b, 0x93, 0x24, 0x46, + 0x7e, 0x34, 0x8d, 0xc4, 0x2b, 0xb7, 0x8e, 0x22, + 0x9e, 0x87, 0x62, 0xca, 0xbc, 0x10, 0x09, 0x4a, + 0x4b, 0x0b, 0xdb, 0x57, 0x9b, 0xa9, 0x3e, 0xa8, + 0x99, 0x59, 0xa0, 0x12, 0xf3, 0xa5, 0xe4, 0x91, + 0xbb, 0xb9, 0x05, 0x8d, 0xcf, 0xb9, 0xcb, 0x36, + 0x97, 0xb2, 0x6a, 0x31, 0x8f, 0xcb, 0xf8, 0x5a, + 0x2f, 0x9e, 0xa1, 0xf9, 0x7a, 0xf4, 0x10, 0x0e, + 0xe7, 0x7f, 0x4c, 0xcb, 0xe3, 0x83, 0x17, 0x39, + 0x34, 0xef, 0x49, 0x35, 0x68, 0x50, 0x80, 0xf9, + 0xcd, 0x3a, 0x10, 0xf6, 0x71, 0x1a, 0x94, 0xc3, + 0xec, 0xb9, 0x36, 0x84, 0x36, 0xe7, 0x3f, 0x6f, + 0x9b, 0xa9, 0x2b, 0x5c, 0x96, 0x49, 0x26, 0xda, + 0xb3, 0x08, 0x3d, 0x5e, 0x9e, 0x59, 0xdf, 0x0f, + 0xfc, 0xbe, 0xa8, 0x0b, 0xbc, 0xaa, 0x32, 0xf0, + 0xa5, 0x21, 0x50, 0x15, 0x7e, 0x46, 0xb9, 0x76, + 0x09, 0x4e, 0x4b, 0x6f, 0x9f, 0xc7, 0x8c, 0x6d, + 0x80, 0x37, 0xf9, 0xaa, 0xd1, 0x5f, 0x12, 0xb9, + 0xb3, 0x15, 0xe4, 0x96, 0xa1, 0x01, 0xd5, 0xa0, +}; + +const struct testvec aes_cbc_256_8_vectors[] = { + { + .blkno = 0, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_256_encblkno8_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_256_encblkno8_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_256_encblkno8_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = aes_cbc_ptxt, + .ctxt = aes_cbc_256_encblkno8_vec3_ctxt, + }, +}; + +/* + * 256 bits key from IEEE 1619/D16, NUL terminated. + */ +static const char aes_xts_256_key[33] = { + 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, + 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, + 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, + 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, + 0 +}; + +/* + * 512 bits key from IEEE 1619/D16, NUL terminated. + */ +static const char aes_xts_512_key[65] = { + 0x27, 0x18, 0x28, 0x18, 0x28, 0x45, 0x90, 0x45, + 0x23, 0x53, 0x60, 0x28, 0x74, 0x71, 0x35, 0x26, + 0x62, 0x49, 0x77, 0x57, 0x24, 0x70, 0x93, 0x69, + 0x99, 0x59, 0x57, 0x49, 0x66, 0x96, 0x76, 0x27, + 0x31, 0x41, 0x59, 0x26, 0x53, 0x58, 0x97, 0x93, + 0x23, 0x84, 0x62, 0x64, 0x33, 0x83, 0x27, 0x95, + 0x02, 0x88, 0x41, 0x97, 0x16, 0x93, 0x99, 0x37, + 0x51, 0x05, 0x82, 0x09, 0x74, 0x94, 0x45, 0x92, + 0 +}; + +/* + * Vector 4 from IEEE 1619/D16, blkno 0. + */ +static const uint8_t aes_xts_256_vec4_ptxt[SECSIZE] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +static const uint8_t aes_xts_256_vec4_ctxt[SECSIZE] = { + 0x27, 0xa7, 0x47, 0x9b, 0xef, 0xa1, 0xd4, 0x76, + 0x48, 0x9f, 0x30, 0x8c, 0xd4, 0xcf, 0xa6, 0xe2, + 0xa9, 0x6e, 0x4b, 0xbe, 0x32, 0x08, 0xff, 0x25, + 0x28, 0x7d, 0xd3, 0x81, 0x96, 0x16, 0xe8, 0x9c, + 0xc7, 0x8c, 0xf7, 0xf5, 0xe5, 0x43, 0x44, 0x5f, + 0x83, 0x33, 0xd8, 0xfa, 0x7f, 0x56, 0x00, 0x00, + 0x05, 0x27, 0x9f, 0xa5, 0xd8, 0xb5, 0xe4, 0xad, + 0x40, 0xe7, 0x36, 0xdd, 0xb4, 0xd3, 0x54, 0x12, + 0x32, 0x80, 0x63, 0xfd, 0x2a, 0xab, 0x53, 0xe5, + 0xea, 0x1e, 0x0a, 0x9f, 0x33, 0x25, 0x00, 0xa5, + 0xdf, 0x94, 0x87, 0xd0, 0x7a, 0x5c, 0x92, 0xcc, + 0x51, 0x2c, 0x88, 0x66, 0xc7, 0xe8, 0x60, 0xce, + 0x93, 0xfd, 0xf1, 0x66, 0xa2, 0x49, 0x12, 0xb4, + 0x22, 0x97, 0x61, 0x46, 0xae, 0x20, 0xce, 0x84, + 0x6b, 0xb7, 0xdc, 0x9b, 0xa9, 0x4a, 0x76, 0x7a, + 0xae, 0xf2, 0x0c, 0x0d, 0x61, 0xad, 0x02, 0x65, + 0x5e, 0xa9, 0x2d, 0xc4, 0xc4, 0xe4, 0x1a, 0x89, + 0x52, 0xc6, 0x51, 0xd3, 0x31, 0x74, 0xbe, 0x51, + 0xa1, 0x0c, 0x42, 0x11, 0x10, 0xe6, 0xd8, 0x15, + 0x88, 0xed, 0xe8, 0x21, 0x03, 0xa2, 0x52, 0xd8, + 0xa7, 0x50, 0xe8, 0x76, 0x8d, 0xef, 0xff, 0xed, + 0x91, 0x22, 0x81, 0x0a, 0xae, 0xb9, 0x9f, 0x91, + 0x72, 0xaf, 0x82, 0xb6, 0x04, 0xdc, 0x4b, 0x8e, + 0x51, 0xbc, 0xb0, 0x82, 0x35, 0xa6, 0xf4, 0x34, + 0x13, 0x32, 0xe4, 0xca, 0x60, 0x48, 0x2a, 0x4b, + 0xa1, 0xa0, 0x3b, 0x3e, 0x65, 0x00, 0x8f, 0xc5, + 0xda, 0x76, 0xb7, 0x0b, 0xf1, 0x69, 0x0d, 0xb4, + 0xea, 0xe2, 0x9c, 0x5f, 0x1b, 0xad, 0xd0, 0x3c, + 0x5c, 0xcf, 0x2a, 0x55, 0xd7, 0x05, 0xdd, 0xcd, + 0x86, 0xd4, 0x49, 0x51, 0x1c, 0xeb, 0x7e, 0xc3, + 0x0b, 0xf1, 0x2b, 0x1f, 0xa3, 0x5b, 0x91, 0x3f, + 0x9f, 0x74, 0x7a, 0x8a, 0xfd, 0x1b, 0x13, 0x0e, + 0x94, 0xbf, 0xf9, 0x4e, 0xff, 0xd0, 0x1a, 0x91, + 0x73, 0x5c, 0xa1, 0x72, 0x6a, 0xcd, 0x0b, 0x19, + 0x7c, 0x4e, 0x5b, 0x03, 0x39, 0x36, 0x97, 0xe1, + 0x26, 0x82, 0x6f, 0xb6, 0xbb, 0xde, 0x8e, 0xcc, + 0x1e, 0x08, 0x29, 0x85, 0x16, 0xe2, 0xc9, 0xed, + 0x03, 0xff, 0x3c, 0x1b, 0x78, 0x60, 0xf6, 0xde, + 0x76, 0xd4, 0xce, 0xcd, 0x94, 0xc8, 0x11, 0x98, + 0x55, 0xef, 0x52, 0x97, 0xca, 0x67, 0xe9, 0xf3, + 0xe7, 0xff, 0x72, 0xb1, 0xe9, 0x97, 0x85, 0xca, + 0x0a, 0x7e, 0x77, 0x20, 0xc5, 0xb3, 0x6d, 0xc6, + 0xd7, 0x2c, 0xac, 0x95, 0x74, 0xc8, 0xcb, 0xbc, + 0x2f, 0x80, 0x1e, 0x23, 0xe5, 0x6f, 0xd3, 0x44, + 0xb0, 0x7f, 0x22, 0x15, 0x4b, 0xeb, 0xa0, 0xf0, + 0x8c, 0xe8, 0x89, 0x1e, 0x64, 0x3e, 0xd9, 0x95, + 0xc9, 0x4d, 0x9a, 0x69, 0xc9, 0xf1, 0xb5, 0xf4, + 0x99, 0x02, 0x7a, 0x78, 0x57, 0x2a, 0xee, 0xbd, + 0x74, 0xd2, 0x0c, 0xc3, 0x98, 0x81, 0xc2, 0x13, + 0xee, 0x77, 0x0b, 0x10, 0x10, 0xe4, 0xbe, 0xa7, + 0x18, 0x84, 0x69, 0x77, 0xae, 0x11, 0x9f, 0x7a, + 0x02, 0x3a, 0xb5, 0x8c, 0xca, 0x0a, 0xd7, 0x52, + 0xaf, 0xe6, 0x56, 0xbb, 0x3c, 0x17, 0x25, 0x6a, + 0x9f, 0x6e, 0x9b, 0xf1, 0x9f, 0xdd, 0x5a, 0x38, + 0xfc, 0x82, 0xbb, 0xe8, 0x72, 0xc5, 0x53, 0x9e, + 0xdb, 0x60, 0x9e, 0xf4, 0xf7, 0x9c, 0x20, 0x3e, + 0xbb, 0x14, 0x0f, 0x2e, 0x58, 0x3c, 0xb2, 0xad, + 0x15, 0xb4, 0xaa, 0x5b, 0x65, 0x50, 0x16, 0xa8, + 0x44, 0x92, 0x77, 0xdb, 0xd4, 0x77, 0xef, 0x2c, + 0x8d, 0x6c, 0x01, 0x7d, 0xb7, 0x38, 0xb1, 0x8d, + 0xeb, 0x4a, 0x42, 0x7d, 0x19, 0x23, 0xce, 0x3f, + 0xf2, 0x62, 0x73, 0x57, 0x79, 0xa4, 0x18, 0xf2, + 0x0a, 0x28, 0x2d, 0xf9, 0x20, 0x14, 0x7b, 0xea, + 0xbe, 0x42, 0x1e, 0xe5, 0x31, 0x9d, 0x05, 0x68, +}; + +/* + * Vector 5 from IEEE 1619/D16, blkno 1. + */ +static const uint8_t aes_xts_256_vec5_ptxt[SECSIZE] = { + 0x27, 0xa7, 0x47, 0x9b, 0xef, 0xa1, 0xd4, 0x76, + 0x48, 0x9f, 0x30, 0x8c, 0xd4, 0xcf, 0xa6, 0xe2, + 0xa9, 0x6e, 0x4b, 0xbe, 0x32, 0x08, 0xff, 0x25, + 0x28, 0x7d, 0xd3, 0x81, 0x96, 0x16, 0xe8, 0x9c, + 0xc7, 0x8c, 0xf7, 0xf5, 0xe5, 0x43, 0x44, 0x5f, + 0x83, 0x33, 0xd8, 0xfa, 0x7f, 0x56, 0x00, 0x00, + 0x05, 0x27, 0x9f, 0xa5, 0xd8, 0xb5, 0xe4, 0xad, + 0x40, 0xe7, 0x36, 0xdd, 0xb4, 0xd3, 0x54, 0x12, + 0x32, 0x80, 0x63, 0xfd, 0x2a, 0xab, 0x53, 0xe5, + 0xea, 0x1e, 0x0a, 0x9f, 0x33, 0x25, 0x00, 0xa5, + 0xdf, 0x94, 0x87, 0xd0, 0x7a, 0x5c, 0x92, 0xcc, + 0x51, 0x2c, 0x88, 0x66, 0xc7, 0xe8, 0x60, 0xce, + 0x93, 0xfd, 0xf1, 0x66, 0xa2, 0x49, 0x12, 0xb4, + 0x22, 0x97, 0x61, 0x46, 0xae, 0x20, 0xce, 0x84, + 0x6b, 0xb7, 0xdc, 0x9b, 0xa9, 0x4a, 0x76, 0x7a, + 0xae, 0xf2, 0x0c, 0x0d, 0x61, 0xad, 0x02, 0x65, + 0x5e, 0xa9, 0x2d, 0xc4, 0xc4, 0xe4, 0x1a, 0x89, + 0x52, 0xc6, 0x51, 0xd3, 0x31, 0x74, 0xbe, 0x51, + 0xa1, 0x0c, 0x42, 0x11, 0x10, 0xe6, 0xd8, 0x15, + 0x88, 0xed, 0xe8, 0x21, 0x03, 0xa2, 0x52, 0xd8, + 0xa7, 0x50, 0xe8, 0x76, 0x8d, 0xef, 0xff, 0xed, + 0x91, 0x22, 0x81, 0x0a, 0xae, 0xb9, 0x9f, 0x91, + 0x72, 0xaf, 0x82, 0xb6, 0x04, 0xdc, 0x4b, 0x8e, + 0x51, 0xbc, 0xb0, 0x82, 0x35, 0xa6, 0xf4, 0x34, + 0x13, 0x32, 0xe4, 0xca, 0x60, 0x48, 0x2a, 0x4b, + 0xa1, 0xa0, 0x3b, 0x3e, 0x65, 0x00, 0x8f, 0xc5, + 0xda, 0x76, 0xb7, 0x0b, 0xf1, 0x69, 0x0d, 0xb4, + 0xea, 0xe2, 0x9c, 0x5f, 0x1b, 0xad, 0xd0, 0x3c, + 0x5c, 0xcf, 0x2a, 0x55, 0xd7, 0x05, 0xdd, 0xcd, + 0x86, 0xd4, 0x49, 0x51, 0x1c, 0xeb, 0x7e, 0xc3, + 0x0b, 0xf1, 0x2b, 0x1f, 0xa3, 0x5b, 0x91, 0x3f, + 0x9f, 0x74, 0x7a, 0x8a, 0xfd, 0x1b, 0x13, 0x0e, + 0x94, 0xbf, 0xf9, 0x4e, 0xff, 0xd0, 0x1a, 0x91, + 0x73, 0x5c, 0xa1, 0x72, 0x6a, 0xcd, 0x0b, 0x19, + 0x7c, 0x4e, 0x5b, 0x03, 0x39, 0x36, 0x97, 0xe1, + 0x26, 0x82, 0x6f, 0xb6, 0xbb, 0xde, 0x8e, 0xcc, + 0x1e, 0x08, 0x29, 0x85, 0x16, 0xe2, 0xc9, 0xed, + 0x03, 0xff, 0x3c, 0x1b, 0x78, 0x60, 0xf6, 0xde, + 0x76, 0xd4, 0xce, 0xcd, 0x94, 0xc8, 0x11, 0x98, + 0x55, 0xef, 0x52, 0x97, 0xca, 0x67, 0xe9, 0xf3, + 0xe7, 0xff, 0x72, 0xb1, 0xe9, 0x97, 0x85, 0xca, + 0x0a, 0x7e, 0x77, 0x20, 0xc5, 0xb3, 0x6d, 0xc6, + 0xd7, 0x2c, 0xac, 0x95, 0x74, 0xc8, 0xcb, 0xbc, + 0x2f, 0x80, 0x1e, 0x23, 0xe5, 0x6f, 0xd3, 0x44, + 0xb0, 0x7f, 0x22, 0x15, 0x4b, 0xeb, 0xa0, 0xf0, + 0x8c, 0xe8, 0x89, 0x1e, 0x64, 0x3e, 0xd9, 0x95, + 0xc9, 0x4d, 0x9a, 0x69, 0xc9, 0xf1, 0xb5, 0xf4, + 0x99, 0x02, 0x7a, 0x78, 0x57, 0x2a, 0xee, 0xbd, + 0x74, 0xd2, 0x0c, 0xc3, 0x98, 0x81, 0xc2, 0x13, + 0xee, 0x77, 0x0b, 0x10, 0x10, 0xe4, 0xbe, 0xa7, + 0x18, 0x84, 0x69, 0x77, 0xae, 0x11, 0x9f, 0x7a, + 0x02, 0x3a, 0xb5, 0x8c, 0xca, 0x0a, 0xd7, 0x52, + 0xaf, 0xe6, 0x56, 0xbb, 0x3c, 0x17, 0x25, 0x6a, + 0x9f, 0x6e, 0x9b, 0xf1, 0x9f, 0xdd, 0x5a, 0x38, + 0xfc, 0x82, 0xbb, 0xe8, 0x72, 0xc5, 0x53, 0x9e, + 0xdb, 0x60, 0x9e, 0xf4, 0xf7, 0x9c, 0x20, 0x3e, + 0xbb, 0x14, 0x0f, 0x2e, 0x58, 0x3c, 0xb2, 0xad, + 0x15, 0xb4, 0xaa, 0x5b, 0x65, 0x50, 0x16, 0xa8, + 0x44, 0x92, 0x77, 0xdb, 0xd4, 0x77, 0xef, 0x2c, + 0x8d, 0x6c, 0x01, 0x7d, 0xb7, 0x38, 0xb1, 0x8d, + 0xeb, 0x4a, 0x42, 0x7d, 0x19, 0x23, 0xce, 0x3f, + 0xf2, 0x62, 0x73, 0x57, 0x79, 0xa4, 0x18, 0xf2, + 0x0a, 0x28, 0x2d, 0xf9, 0x20, 0x14, 0x7b, 0xea, + 0xbe, 0x42, 0x1e, 0xe5, 0x31, 0x9d, 0x05, 0x68, +}; + +static const uint8_t aes_xts_256_vec5_ctxt[SECSIZE] = { + 0x26, 0x4d, 0x3c, 0xa8, 0x51, 0x21, 0x94, 0xfe, + 0xc3, 0x12, 0xc8, 0xc9, 0x89, 0x1f, 0x27, 0x9f, + 0xef, 0xdd, 0x60, 0x8d, 0x0c, 0x02, 0x7b, 0x60, + 0x48, 0x3a, 0x3f, 0xa8, 0x11, 0xd6, 0x5e, 0xe5, + 0x9d, 0x52, 0xd9, 0xe4, 0x0e, 0xc5, 0x67, 0x2d, + 0x81, 0x53, 0x2b, 0x38, 0xb6, 0xb0, 0x89, 0xce, + 0x95, 0x1f, 0x0f, 0x9c, 0x35, 0x59, 0x0b, 0x8b, + 0x97, 0x8d, 0x17, 0x52, 0x13, 0xf3, 0x29, 0xbb, + 0x1c, 0x2f, 0xd3, 0x0f, 0x2f, 0x7f, 0x30, 0x49, + 0x2a, 0x61, 0xa5, 0x32, 0xa7, 0x9f, 0x51, 0xd3, + 0x6f, 0x5e, 0x31, 0xa7, 0xc9, 0xa1, 0x2c, 0x28, + 0x60, 0x82, 0xff, 0x7d, 0x23, 0x94, 0xd1, 0x8f, + 0x78, 0x3e, 0x1a, 0x8e, 0x72, 0xc7, 0x22, 0xca, + 0xaa, 0xa5, 0x2d, 0x8f, 0x06, 0x56, 0x57, 0xd2, + 0x63, 0x1f, 0xd2, 0x5b, 0xfd, 0x8e, 0x5b, 0xaa, + 0xd6, 0xe5, 0x27, 0xd7, 0x63, 0x51, 0x75, 0x01, + 0xc6, 0x8c, 0x5e, 0xdc, 0x3c, 0xdd, 0x55, 0x43, + 0x5c, 0x53, 0x2d, 0x71, 0x25, 0xc8, 0x61, 0x4d, + 0xee, 0xd9, 0xad, 0xaa, 0x3a, 0xca, 0xde, 0x58, + 0x88, 0xb8, 0x7b, 0xef, 0x64, 0x1c, 0x4c, 0x99, + 0x4c, 0x80, 0x91, 0xb5, 0xbc, 0xd3, 0x87, 0xf3, + 0x96, 0x3f, 0xb5, 0xbc, 0x37, 0xaa, 0x92, 0x2f, + 0xbf, 0xe3, 0xdf, 0x4e, 0x5b, 0x91, 0x5e, 0x6e, + 0xb5, 0x14, 0x71, 0x7b, 0xdd, 0x2a, 0x74, 0x07, + 0x9a, 0x50, 0x73, 0xf5, 0xc4, 0xbf, 0xd4, 0x6a, + 0xdf, 0x7d, 0x28, 0x2e, 0x7a, 0x39, 0x3a, 0x52, + 0x57, 0x9d, 0x11, 0xa0, 0x28, 0xda, 0x4d, 0x9c, + 0xd9, 0xc7, 0x71, 0x24, 0xf9, 0x64, 0x8e, 0xe3, + 0x83, 0xb1, 0xac, 0x76, 0x39, 0x30, 0xe7, 0x16, + 0x2a, 0x8d, 0x37, 0xf3, 0x50, 0xb2, 0xf7, 0x4b, + 0x84, 0x72, 0xcf, 0x09, 0x90, 0x20, 0x63, 0xc6, + 0xb3, 0x2e, 0x8c, 0x2d, 0x92, 0x90, 0xce, 0xfb, + 0xd7, 0x34, 0x6d, 0x1c, 0x77, 0x9a, 0x0d, 0xf5, + 0x0e, 0xdc, 0xde, 0x45, 0x31, 0xda, 0x07, 0xb0, + 0x99, 0xc6, 0x38, 0xe8, 0x3a, 0x75, 0x59, 0x44, + 0xdf, 0x2a, 0xef, 0x1a, 0xa3, 0x17, 0x52, 0xfd, + 0x32, 0x3d, 0xcb, 0x71, 0x0f, 0xb4, 0xbf, 0xbb, + 0x9d, 0x22, 0xb9, 0x25, 0xbc, 0x35, 0x77, 0xe1, + 0xb8, 0x94, 0x9e, 0x72, 0x9a, 0x90, 0xbb, 0xaf, + 0xea, 0xcf, 0x7f, 0x78, 0x79, 0xe7, 0xb1, 0x14, + 0x7e, 0x28, 0xba, 0x0b, 0xae, 0x94, 0x0d, 0xb7, + 0x95, 0xa6, 0x1b, 0x15, 0xec, 0xf4, 0xdf, 0x8d, + 0xb0, 0x7b, 0x82, 0x4b, 0xb0, 0x62, 0x80, 0x2c, + 0xc9, 0x8a, 0x95, 0x45, 0xbb, 0x2a, 0xae, 0xed, + 0x77, 0xcb, 0x3f, 0xc6, 0xdb, 0x15, 0xdc, 0xd7, + 0xd8, 0x0d, 0x7d, 0x5b, 0xc4, 0x06, 0xc4, 0x97, + 0x0a, 0x34, 0x78, 0xad, 0xa8, 0x89, 0x9b, 0x32, + 0x91, 0x98, 0xeb, 0x61, 0xc1, 0x93, 0xfb, 0x62, + 0x75, 0xaa, 0x8c, 0xa3, 0x40, 0x34, 0x4a, 0x75, + 0xa8, 0x62, 0xae, 0xbe, 0x92, 0xee, 0xe1, 0xce, + 0x03, 0x2f, 0xd9, 0x50, 0xb4, 0x7d, 0x77, 0x04, + 0xa3, 0x87, 0x69, 0x23, 0xb4, 0xad, 0x62, 0x84, + 0x4b, 0xf4, 0xa0, 0x9c, 0x4d, 0xbe, 0x8b, 0x43, + 0x97, 0x18, 0x4b, 0x74, 0x71, 0x36, 0x0c, 0x95, + 0x64, 0x88, 0x0a, 0xed, 0xdd, 0xb9, 0xba, 0xa4, + 0xaf, 0x2e, 0x75, 0x39, 0x4b, 0x08, 0xcd, 0x32, + 0xff, 0x47, 0x9c, 0x57, 0xa0, 0x7d, 0x3e, 0xab, + 0x5d, 0x54, 0xde, 0x5f, 0x97, 0x38, 0xb8, 0xd2, + 0x7f, 0x27, 0xa9, 0xf0, 0xab, 0x11, 0x79, 0x9d, + 0x7b, 0x7f, 0xfe, 0xfb, 0x27, 0x04, 0xc9, 0x5c, + 0x6a, 0xd1, 0x2c, 0x39, 0xf1, 0xe8, 0x67, 0xa4, + 0xb7, 0xb1, 0xd7, 0x81, 0x8a, 0x4b, 0x75, 0x3d, + 0xfd, 0x2a, 0x89, 0xcc, 0xb4, 0x5e, 0x00, 0x1a, + 0x03, 0xa8, 0x67, 0xb1, 0x87, 0xf2, 0x25, 0xdd, +}; + +/* + * Vector 6 from IEEE 1619/D16, blkno 2. + */ +static const uint8_t aes_xts_256_vec6_ptxt[SECSIZE] = { + 0x26, 0x4d, 0x3c, 0xa8, 0x51, 0x21, 0x94, 0xfe, + 0xc3, 0x12, 0xc8, 0xc9, 0x89, 0x1f, 0x27, 0x9f, + 0xef, 0xdd, 0x60, 0x8d, 0x0c, 0x02, 0x7b, 0x60, + 0x48, 0x3a, 0x3f, 0xa8, 0x11, 0xd6, 0x5e, 0xe5, + 0x9d, 0x52, 0xd9, 0xe4, 0x0e, 0xc5, 0x67, 0x2d, + 0x81, 0x53, 0x2b, 0x38, 0xb6, 0xb0, 0x89, 0xce, + 0x95, 0x1f, 0x0f, 0x9c, 0x35, 0x59, 0x0b, 0x8b, + 0x97, 0x8d, 0x17, 0x52, 0x13, 0xf3, 0x29, 0xbb, + 0x1c, 0x2f, 0xd3, 0x0f, 0x2f, 0x7f, 0x30, 0x49, + 0x2a, 0x61, 0xa5, 0x32, 0xa7, 0x9f, 0x51, 0xd3, + 0x6f, 0x5e, 0x31, 0xa7, 0xc9, 0xa1, 0x2c, 0x28, + 0x60, 0x82, 0xff, 0x7d, 0x23, 0x94, 0xd1, 0x8f, + 0x78, 0x3e, 0x1a, 0x8e, 0x72, 0xc7, 0x22, 0xca, + 0xaa, 0xa5, 0x2d, 0x8f, 0x06, 0x56, 0x57, 0xd2, + 0x63, 0x1f, 0xd2, 0x5b, 0xfd, 0x8e, 0x5b, 0xaa, + 0xd6, 0xe5, 0x27, 0xd7, 0x63, 0x51, 0x75, 0x01, + 0xc6, 0x8c, 0x5e, 0xdc, 0x3c, 0xdd, 0x55, 0x43, + 0x5c, 0x53, 0x2d, 0x71, 0x25, 0xc8, 0x61, 0x4d, + 0xee, 0xd9, 0xad, 0xaa, 0x3a, 0xca, 0xde, 0x58, + 0x88, 0xb8, 0x7b, 0xef, 0x64, 0x1c, 0x4c, 0x99, + 0x4c, 0x80, 0x91, 0xb5, 0xbc, 0xd3, 0x87, 0xf3, + 0x96, 0x3f, 0xb5, 0xbc, 0x37, 0xaa, 0x92, 0x2f, + 0xbf, 0xe3, 0xdf, 0x4e, 0x5b, 0x91, 0x5e, 0x6e, + 0xb5, 0x14, 0x71, 0x7b, 0xdd, 0x2a, 0x74, 0x07, + 0x9a, 0x50, 0x73, 0xf5, 0xc4, 0xbf, 0xd4, 0x6a, + 0xdf, 0x7d, 0x28, 0x2e, 0x7a, 0x39, 0x3a, 0x52, + 0x57, 0x9d, 0x11, 0xa0, 0x28, 0xda, 0x4d, 0x9c, + 0xd9, 0xc7, 0x71, 0x24, 0xf9, 0x64, 0x8e, 0xe3, + 0x83, 0xb1, 0xac, 0x76, 0x39, 0x30, 0xe7, 0x16, + 0x2a, 0x8d, 0x37, 0xf3, 0x50, 0xb2, 0xf7, 0x4b, + 0x84, 0x72, 0xcf, 0x09, 0x90, 0x20, 0x63, 0xc6, + 0xb3, 0x2e, 0x8c, 0x2d, 0x92, 0x90, 0xce, 0xfb, + 0xd7, 0x34, 0x6d, 0x1c, 0x77, 0x9a, 0x0d, 0xf5, + 0x0e, 0xdc, 0xde, 0x45, 0x31, 0xda, 0x07, 0xb0, + 0x99, 0xc6, 0x38, 0xe8, 0x3a, 0x75, 0x59, 0x44, + 0xdf, 0x2a, 0xef, 0x1a, 0xa3, 0x17, 0x52, 0xfd, + 0x32, 0x3d, 0xcb, 0x71, 0x0f, 0xb4, 0xbf, 0xbb, + 0x9d, 0x22, 0xb9, 0x25, 0xbc, 0x35, 0x77, 0xe1, + 0xb8, 0x94, 0x9e, 0x72, 0x9a, 0x90, 0xbb, 0xaf, + 0xea, 0xcf, 0x7f, 0x78, 0x79, 0xe7, 0xb1, 0x14, + 0x7e, 0x28, 0xba, 0x0b, 0xae, 0x94, 0x0d, 0xb7, + 0x95, 0xa6, 0x1b, 0x15, 0xec, 0xf4, 0xdf, 0x8d, + 0xb0, 0x7b, 0x82, 0x4b, 0xb0, 0x62, 0x80, 0x2c, + 0xc9, 0x8a, 0x95, 0x45, 0xbb, 0x2a, 0xae, 0xed, + 0x77, 0xcb, 0x3f, 0xc6, 0xdb, 0x15, 0xdc, 0xd7, + 0xd8, 0x0d, 0x7d, 0x5b, 0xc4, 0x06, 0xc4, 0x97, + 0x0a, 0x34, 0x78, 0xad, 0xa8, 0x89, 0x9b, 0x32, + 0x91, 0x98, 0xeb, 0x61, 0xc1, 0x93, 0xfb, 0x62, + 0x75, 0xaa, 0x8c, 0xa3, 0x40, 0x34, 0x4a, 0x75, + 0xa8, 0x62, 0xae, 0xbe, 0x92, 0xee, 0xe1, 0xce, + 0x03, 0x2f, 0xd9, 0x50, 0xb4, 0x7d, 0x77, 0x04, + 0xa3, 0x87, 0x69, 0x23, 0xb4, 0xad, 0x62, 0x84, + 0x4b, 0xf4, 0xa0, 0x9c, 0x4d, 0xbe, 0x8b, 0x43, + 0x97, 0x18, 0x4b, 0x74, 0x71, 0x36, 0x0c, 0x95, + 0x64, 0x88, 0x0a, 0xed, 0xdd, 0xb9, 0xba, 0xa4, + 0xaf, 0x2e, 0x75, 0x39, 0x4b, 0x08, 0xcd, 0x32, + 0xff, 0x47, 0x9c, 0x57, 0xa0, 0x7d, 0x3e, 0xab, + 0x5d, 0x54, 0xde, 0x5f, 0x97, 0x38, 0xb8, 0xd2, + 0x7f, 0x27, 0xa9, 0xf0, 0xab, 0x11, 0x79, 0x9d, + 0x7b, 0x7f, 0xfe, 0xfb, 0x27, 0x04, 0xc9, 0x5c, + 0x6a, 0xd1, 0x2c, 0x39, 0xf1, 0xe8, 0x67, 0xa4, + 0xb7, 0xb1, 0xd7, 0x81, 0x8a, 0x4b, 0x75, 0x3d, + 0xfd, 0x2a, 0x89, 0xcc, 0xb4, 0x5e, 0x00, 0x1a, + 0x03, 0xa8, 0x67, 0xb1, 0x87, 0xf2, 0x25, 0xdd, +}; + +static const uint8_t aes_xts_256_vec6_ctxt[SECSIZE] = { + 0xfa, 0x76, 0x2a, 0x36, 0x80, 0xb7, 0x60, 0x07, + 0x92, 0x8e, 0xd4, 0xa4, 0xf4, 0x9a, 0x94, 0x56, + 0x03, 0x1b, 0x70, 0x47, 0x82, 0xe6, 0x5e, 0x16, + 0xce, 0xcb, 0x54, 0xed, 0x7d, 0x01, 0x7b, 0x5e, + 0x18, 0xab, 0xd6, 0x7b, 0x33, 0x8e, 0x81, 0x07, + 0x8f, 0x21, 0xed, 0xb7, 0x86, 0x8d, 0x90, 0x1e, + 0xbe, 0x9c, 0x73, 0x1a, 0x7c, 0x18, 0xb5, 0xe6, + 0xde, 0xc1, 0xd6, 0xa7, 0x2e, 0x07, 0x8a, 0xc9, + 0xa4, 0x26, 0x2f, 0x86, 0x0b, 0xee, 0xfa, 0x14, + 0xf4, 0xe8, 0x21, 0x01, 0x82, 0x72, 0xe4, 0x11, + 0xa9, 0x51, 0x50, 0x2b, 0x6e, 0x79, 0x06, 0x6e, + 0x84, 0x25, 0x2c, 0x33, 0x46, 0xf3, 0xaa, 0x62, + 0x34, 0x43, 0x51, 0xa2, 0x91, 0xd4, 0xbe, 0xdc, + 0x7a, 0x07, 0x61, 0x8b, 0xde, 0xa2, 0xaf, 0x63, + 0x14, 0x5c, 0xc7, 0xa4, 0xb8, 0xd4, 0x07, 0x06, + 0x91, 0xae, 0x89, 0x0c, 0xd6, 0x57, 0x33, 0xe7, + 0x94, 0x6e, 0x90, 0x21, 0xa1, 0xdf, 0xfc, 0x4c, + 0x59, 0xf1, 0x59, 0x42, 0x5e, 0xe6, 0xd5, 0x0c, + 0xa9, 0xb1, 0x35, 0xfa, 0x61, 0x62, 0xce, 0xa1, + 0x8a, 0x93, 0x98, 0x38, 0xdc, 0x00, 0x0f, 0xb3, + 0x86, 0xfa, 0xd0, 0x86, 0xac, 0xce, 0x5a, 0xc0, + 0x7c, 0xb2, 0xec, 0xe7, 0xfd, 0x58, 0x0b, 0x00, + 0xcf, 0xa5, 0xe9, 0x85, 0x89, 0x63, 0x1d, 0xc2, + 0x5e, 0x8e, 0x2a, 0x3d, 0xaf, 0x2f, 0xfd, 0xec, + 0x26, 0x53, 0x16, 0x59, 0x91, 0x2c, 0x9d, 0x8f, + 0x7a, 0x15, 0xe5, 0x86, 0x5e, 0xa8, 0xfb, 0x58, + 0x16, 0xd6, 0x20, 0x70, 0x52, 0xbd, 0x71, 0x28, + 0xcd, 0x74, 0x3c, 0x12, 0xc8, 0x11, 0x87, 0x91, + 0xa4, 0x73, 0x68, 0x11, 0x93, 0x5e, 0xb9, 0x82, + 0xa5, 0x32, 0x34, 0x9e, 0x31, 0xdd, 0x40, 0x1e, + 0x0b, 0x66, 0x0a, 0x56, 0x8c, 0xb1, 0xa4, 0x71, + 0x1f, 0x55, 0x2f, 0x55, 0xde, 0xd5, 0x9f, 0x1f, + 0x15, 0xbf, 0x71, 0x96, 0xb3, 0xca, 0x12, 0xa9, + 0x1e, 0x48, 0x8e, 0xf5, 0x9d, 0x64, 0xf3, 0xa0, + 0x2b, 0xf4, 0x52, 0x39, 0x49, 0x9a, 0xc6, 0x17, + 0x6a, 0xe3, 0x21, 0xc4, 0xa2, 0x11, 0xec, 0x54, + 0x53, 0x65, 0x97, 0x1c, 0x5d, 0x3f, 0x4f, 0x09, + 0xd4, 0xeb, 0x13, 0x9b, 0xfd, 0xf2, 0x07, 0x3d, + 0x33, 0x18, 0x0b, 0x21, 0x00, 0x2b, 0x65, 0xcc, + 0x98, 0x65, 0xe7, 0x6c, 0xb2, 0x4c, 0xd9, 0x2c, + 0x87, 0x4c, 0x24, 0xc1, 0x83, 0x50, 0x39, 0x9a, + 0x93, 0x6a, 0xb3, 0x63, 0x70, 0x79, 0x29, 0x5d, + 0x76, 0xc4, 0x17, 0x77, 0x6b, 0x94, 0xef, 0xce, + 0x3a, 0x0e, 0xf7, 0x20, 0x6b, 0x15, 0x11, 0x05, + 0x19, 0x65, 0x5c, 0x95, 0x6c, 0xbd, 0x8b, 0x24, + 0x89, 0x40, 0x5e, 0xe2, 0xb0, 0x9a, 0x6b, 0x6e, + 0xeb, 0xe0, 0xc5, 0x37, 0x90, 0xa1, 0x2a, 0x89, + 0x98, 0x37, 0x8b, 0x33, 0xa5, 0xb7, 0x11, 0x59, + 0x62, 0x5f, 0x4b, 0xa4, 0x9d, 0x2a, 0x2f, 0xdb, + 0xa5, 0x9f, 0xbf, 0x08, 0x97, 0xbc, 0x7a, 0xab, + 0xd8, 0xd7, 0x07, 0xdc, 0x14, 0x0a, 0x80, 0xf0, + 0xf3, 0x09, 0xf8, 0x35, 0xd3, 0xda, 0x54, 0xab, + 0x58, 0x4e, 0x50, 0x1d, 0xfa, 0x0e, 0xe9, 0x77, + 0xfe, 0xc5, 0x43, 0xf7, 0x41, 0x86, 0xa8, 0x02, + 0xb9, 0xa3, 0x7a, 0xdb, 0x3e, 0x82, 0x91, 0xec, + 0xa0, 0x4d, 0x66, 0x52, 0x0d, 0x22, 0x9e, 0x60, + 0x40, 0x1e, 0x72, 0x82, 0xbe, 0xf4, 0x86, 0xae, + 0x05, 0x9a, 0xa7, 0x06, 0x96, 0xe0, 0xe3, 0x05, + 0xd7, 0x77, 0x14, 0x0a, 0x7a, 0x88, 0x3e, 0xcd, + 0xcb, 0x69, 0xb9, 0xff, 0x93, 0x8e, 0x8a, 0x42, + 0x31, 0x86, 0x4c, 0x69, 0xca, 0x2c, 0x20, 0x43, + 0xbe, 0xd0, 0x07, 0xff, 0x3e, 0x60, 0x5e, 0x01, + 0x4b, 0xcf, 0x51, 0x81, 0x38, 0xdc, 0x3a, 0x25, + 0xc5, 0xe2, 0x36, 0x17, 0x1a, 0x2d, 0x01, 0xd6, +}; + +/* + * Vector 7 from IEEE 1619/D16, blkno 0xfd. + */ +static const uint8_t aes_xts_256_vec7_ptxt[SECSIZE] = { + 0x8e, 0x41, 0xb7, 0x8c, 0x39, 0x0b, 0x5a, 0xf9, + 0xd7, 0x58, 0xbb, 0x21, 0x4a, 0x67, 0xe9, 0xf6, + 0xbf, 0x77, 0x27, 0xb0, 0x9a, 0xc6, 0x12, 0x40, + 0x84, 0xc3, 0x76, 0x11, 0x39, 0x8f, 0xa4, 0x5d, + 0xaa, 0xd9, 0x48, 0x68, 0x60, 0x0e, 0xd3, 0x91, + 0xfb, 0x1a, 0xcd, 0x48, 0x57, 0xa9, 0x5b, 0x46, + 0x6e, 0x62, 0xef, 0x9f, 0x4b, 0x37, 0x72, 0x44, + 0xd1, 0xc1, 0x52, 0xe7, 0xb3, 0x0d, 0x73, 0x1a, + 0xad, 0x30, 0xc7, 0x16, 0xd2, 0x14, 0xb7, 0x07, + 0xae, 0xd9, 0x9e, 0xb5, 0xb5, 0xe5, 0x80, 0xb3, + 0xe8, 0x87, 0xcf, 0x74, 0x97, 0x46, 0x56, 0x51, + 0xd4, 0xb6, 0x0e, 0x60, 0x42, 0x05, 0x1d, 0xa3, + 0x69, 0x3c, 0x3b, 0x78, 0xc1, 0x44, 0x89, 0x54, + 0x3b, 0xe8, 0xb6, 0xad, 0x0b, 0xa6, 0x29, 0x56, + 0x5b, 0xba, 0x20, 0x23, 0x13, 0xba, 0x7b, 0x0d, + 0x0c, 0x94, 0xa3, 0x25, 0x2b, 0x67, 0x6f, 0x46, + 0xcc, 0x02, 0xce, 0x0f, 0x8a, 0x7d, 0x34, 0xc0, + 0xed, 0x22, 0x91, 0x29, 0x67, 0x3c, 0x1f, 0x61, + 0xae, 0xd5, 0x79, 0xd0, 0x8a, 0x92, 0x03, 0xa2, + 0x5a, 0xac, 0x3a, 0x77, 0xe9, 0xdb, 0x60, 0x26, + 0x79, 0x96, 0xdb, 0x38, 0xdf, 0x63, 0x73, 0x56, + 0xd9, 0xdc, 0xd1, 0x63, 0x2e, 0x36, 0x99, 0x39, + 0xf2, 0xa2, 0x9d, 0x89, 0x34, 0x5c, 0x66, 0xe0, + 0x50, 0x66, 0xf1, 0xa3, 0x67, 0x7a, 0xef, 0x18, + 0xde, 0xa4, 0x11, 0x3f, 0xae, 0xb6, 0x29, 0xe4, + 0x67, 0x21, 0xa6, 0x6d, 0x0a, 0x7e, 0x78, 0x5d, + 0x3e, 0x29, 0xaf, 0x25, 0x94, 0xeb, 0x67, 0xdf, + 0xa9, 0x82, 0xaf, 0xfe, 0x0a, 0xac, 0x05, 0x8f, + 0x6e, 0x15, 0x86, 0x42, 0x69, 0xb1, 0x35, 0x41, + 0x82, 0x61, 0xfc, 0x3a, 0xfb, 0x08, 0x94, 0x72, + 0xcf, 0x68, 0xc4, 0x5d, 0xd7, 0xf2, 0x31, 0xc6, + 0x24, 0x9b, 0xa0, 0x25, 0x5e, 0x1e, 0x03, 0x38, + 0x33, 0xfc, 0x4d, 0x00, 0xa3, 0xfe, 0x02, 0x13, + 0x2d, 0x7b, 0xc3, 0x87, 0x36, 0x14, 0xb8, 0xae, + 0xe3, 0x42, 0x73, 0x58, 0x1e, 0xa0, 0x32, 0x5c, + 0x81, 0xf0, 0x27, 0x0a, 0xff, 0xa1, 0x36, 0x41, + 0xd0, 0x52, 0xd3, 0x6f, 0x07, 0x57, 0xd4, 0x84, + 0x01, 0x43, 0x54, 0xd0, 0x2d, 0x68, 0x83, 0xca, + 0x15, 0xc2, 0x4d, 0x8c, 0x39, 0x56, 0xb1, 0xbd, + 0x02, 0x7b, 0xcf, 0x41, 0xf1, 0x51, 0xfd, 0x80, + 0x23, 0xc5, 0x34, 0x0e, 0x56, 0x06, 0xf3, 0x7e, + 0x90, 0xfd, 0xb8, 0x7c, 0x86, 0xfb, 0x4f, 0xa6, + 0x34, 0xb3, 0x71, 0x8a, 0x30, 0xba, 0xce, 0x06, + 0xa6, 0x6e, 0xaf, 0x8f, 0x63, 0xc4, 0xaa, 0x3b, + 0x63, 0x78, 0x26, 0xa8, 0x7f, 0xe8, 0xcf, 0xa4, + 0x42, 0x82, 0xe9, 0x2c, 0xb1, 0x61, 0x5a, 0xf3, + 0xa2, 0x8e, 0x53, 0xbc, 0x74, 0xc7, 0xcb, 0xa1, + 0xa0, 0x97, 0x7b, 0xe9, 0x06, 0x5d, 0x0c, 0x1a, + 0x5d, 0xec, 0x6c, 0x54, 0xae, 0x38, 0xd3, 0x7f, + 0x37, 0xaa, 0x35, 0x28, 0x3e, 0x04, 0x8e, 0x55, + 0x30, 0xa8, 0x5c, 0x4e, 0x7a, 0x29, 0xd7, 0xb9, + 0x2e, 0xc0, 0xc3, 0x16, 0x9c, 0xdf, 0x2a, 0x80, + 0x5c, 0x76, 0x04, 0xbc, 0xe6, 0x00, 0x49, 0xb9, + 0xfb, 0x7b, 0x8e, 0xaa, 0xc1, 0x0f, 0x51, 0xae, + 0x23, 0x79, 0x4c, 0xeb, 0xa6, 0x8b, 0xb5, 0x81, + 0x12, 0xe2, 0x93, 0xb9, 0xb6, 0x92, 0xca, 0x72, + 0x1b, 0x37, 0xc6, 0x62, 0xf8, 0x57, 0x4e, 0xd4, + 0xdb, 0xa6, 0xf8, 0x8e, 0x17, 0x08, 0x81, 0xc8, + 0x2c, 0xdd, 0xc1, 0x03, 0x4a, 0x0c, 0xa7, 0xe2, + 0x84, 0xbf, 0x09, 0x62, 0xb6, 0xb2, 0x62, 0x92, + 0xd8, 0x36, 0xfa, 0x9f, 0x73, 0xc1, 0xac, 0x77, + 0x0e, 0xef, 0x0f, 0x2d, 0x3a, 0x1e, 0xaf, 0x61, + 0xd3, 0xe0, 0x35, 0x55, 0xfd, 0x42, 0x4e, 0xed, + 0xd6, 0x7e, 0x18, 0xa1, 0x80, 0x94, 0xf8, 0x88, +}; + +static const uint8_t aes_xts_256_vec7_ctxt[SECSIZE] = { + 0xd5, 0x5f, 0x68, 0x4f, 0x81, 0xf4, 0x42, 0x6e, + 0x9f, 0xde, 0x92, 0xa5, 0xff, 0x02, 0xdf, 0x2a, + 0xc8, 0x96, 0xaf, 0x63, 0x96, 0x28, 0x88, 0xa9, + 0x79, 0x10, 0xc1, 0x37, 0x9e, 0x20, 0xb0, 0xa3, + 0xb1, 0xdb, 0x61, 0x3f, 0xb7, 0xfe, 0x2e, 0x07, + 0x00, 0x43, 0x29, 0xea, 0x5c, 0x22, 0xbf, 0xd3, + 0x3e, 0x3d, 0xbe, 0x4c, 0xf5, 0x8c, 0xc6, 0x08, + 0xc2, 0xc2, 0x6c, 0x19, 0xa2, 0xe2, 0xfe, 0x22, + 0xf9, 0x87, 0x32, 0xc2, 0xb5, 0xcb, 0x84, 0x4c, + 0xc6, 0xc0, 0x70, 0x2d, 0x91, 0xe1, 0xd5, 0x0f, + 0xc4, 0x38, 0x2a, 0x7e, 0xba, 0x56, 0x35, 0xcd, + 0x60, 0x24, 0x32, 0xa2, 0x30, 0x6a, 0xc4, 0xce, + 0x82, 0xf8, 0xd7, 0x0c, 0x8d, 0x9b, 0xc1, 0x5f, + 0x91, 0x8f, 0xe7, 0x1e, 0x74, 0xc6, 0x22, 0xd5, + 0xcf, 0x71, 0x17, 0x8b, 0xf6, 0xe0, 0xb9, 0xcc, + 0x9f, 0x2b, 0x41, 0xdd, 0x8d, 0xbe, 0x44, 0x1c, + 0x41, 0xcd, 0x0c, 0x73, 0xa6, 0xdc, 0x47, 0xa3, + 0x48, 0xf6, 0x70, 0x2f, 0x9d, 0x0e, 0x9b, 0x1b, + 0x14, 0x31, 0xe9, 0x48, 0xe2, 0x99, 0xb9, 0xec, + 0x22, 0x72, 0xab, 0x2c, 0x5f, 0x0c, 0x7b, 0xe8, + 0x6a, 0xff, 0xa5, 0xde, 0xc8, 0x7a, 0x0b, 0xee, + 0x81, 0xd3, 0xd5, 0x00, 0x07, 0xed, 0xaa, 0x2b, + 0xcf, 0xcc, 0xb3, 0x56, 0x05, 0x15, 0x5f, 0xf3, + 0x6e, 0xd8, 0xed, 0xd4, 0xa4, 0x0d, 0xcd, 0x4b, + 0x24, 0x3a, 0xcd, 0x11, 0xb2, 0xb9, 0x87, 0xbd, + 0xbf, 0xaf, 0x91, 0xa7, 0xca, 0xc2, 0x7e, 0x9c, + 0x5a, 0xea, 0x52, 0x5e, 0xe5, 0x3d, 0xe7, 0xb2, + 0xd3, 0x33, 0x2c, 0x86, 0x44, 0x40, 0x2b, 0x82, + 0x3e, 0x94, 0xa7, 0xdb, 0x26, 0x27, 0x6d, 0x2d, + 0x23, 0xaa, 0x07, 0x18, 0x0f, 0x76, 0xb4, 0xfd, + 0x29, 0xb9, 0xc0, 0x82, 0x30, 0x99, 0xc9, 0xd6, + 0x2c, 0x51, 0x98, 0x80, 0xae, 0xe7, 0xe9, 0x69, + 0x76, 0x17, 0xc1, 0x49, 0x7d, 0x47, 0xbf, 0x3e, + 0x57, 0x19, 0x50, 0x31, 0x14, 0x21, 0xb6, 0xb7, + 0x34, 0xd3, 0x8b, 0x0d, 0xb9, 0x1e, 0xb8, 0x53, + 0x31, 0xb9, 0x1e, 0xa9, 0xf6, 0x15, 0x30, 0xf5, + 0x45, 0x12, 0xa5, 0xa5, 0x2a, 0x4b, 0xad, 0x58, + 0x9e, 0xb6, 0x97, 0x81, 0xd5, 0x37, 0xf2, 0x32, + 0x97, 0xbb, 0x45, 0x9b, 0xda, 0xd2, 0x94, 0x8a, + 0x29, 0xe1, 0x55, 0x0b, 0xf4, 0x78, 0x7e, 0x0b, + 0xe9, 0x5b, 0xb1, 0x73, 0xcf, 0x5f, 0xab, 0x17, + 0xda, 0xb7, 0xa1, 0x3a, 0x05, 0x2a, 0x63, 0x45, + 0x3d, 0x97, 0xcc, 0xec, 0x1a, 0x32, 0x19, 0x54, + 0x88, 0x6b, 0x7a, 0x12, 0x99, 0xfa, 0xae, 0xec, + 0xae, 0x35, 0xc6, 0xea, 0xac, 0xa7, 0x53, 0xb0, + 0x41, 0xb5, 0xe5, 0xf0, 0x93, 0xbf, 0x83, 0x39, + 0x7f, 0xd2, 0x1d, 0xd6, 0xb3, 0x01, 0x20, 0x66, + 0xfc, 0xc0, 0x58, 0xcc, 0x32, 0xc3, 0xb0, 0x9d, + 0x75, 0x62, 0xde, 0xe2, 0x95, 0x09, 0xb5, 0x83, + 0x93, 0x92, 0xc9, 0xff, 0x05, 0xf5, 0x1f, 0x31, + 0x66, 0xaa, 0xac, 0x4a, 0xc5, 0xf2, 0x38, 0x03, + 0x8a, 0x30, 0x45, 0xe6, 0xf7, 0x2e, 0x48, 0xef, + 0x0f, 0xe8, 0xbc, 0x67, 0x5e, 0x82, 0xc3, 0x18, + 0xa2, 0x68, 0xe4, 0x39, 0x70, 0x27, 0x1b, 0xf1, + 0x19, 0xb8, 0x1b, 0xf6, 0xa9, 0x82, 0x74, 0x65, + 0x54, 0xf8, 0x4e, 0x72, 0xb9, 0xf0, 0x02, 0x80, + 0xa3, 0x20, 0xa0, 0x81, 0x42, 0x92, 0x3c, 0x23, + 0xc8, 0x83, 0x42, 0x3f, 0xf9, 0x49, 0x82, 0x7f, + 0x29, 0xbb, 0xac, 0xdc, 0x1c, 0xcd, 0xb0, 0x49, + 0x38, 0xce, 0x60, 0x98, 0xc9, 0x5b, 0xa6, 0xb3, + 0x25, 0x28, 0xf4, 0xef, 0x78, 0xee, 0xd7, 0x78, + 0xb2, 0xe1, 0x22, 0xdd, 0xfd, 0x1c, 0xbd, 0xd1, + 0x1d, 0x1c, 0x0a, 0x67, 0x83, 0xe0, 0x11, 0xfc, + 0x53, 0x6d, 0x63, 0xd0, 0x53, 0x26, 0x06, 0x37, +}; + +/* + * Vector 8 from IEEE 1619/D16, blkno 0xfe. + */ +static const uint8_t aes_xts_256_vec8_ptxt[SECSIZE] = { + 0xd5, 0x5f, 0x68, 0x4f, 0x81, 0xf4, 0x42, 0x6e, + 0x9f, 0xde, 0x92, 0xa5, 0xff, 0x02, 0xdf, 0x2a, + 0xc8, 0x96, 0xaf, 0x63, 0x96, 0x28, 0x88, 0xa9, + 0x79, 0x10, 0xc1, 0x37, 0x9e, 0x20, 0xb0, 0xa3, + 0xb1, 0xdb, 0x61, 0x3f, 0xb7, 0xfe, 0x2e, 0x07, + 0x00, 0x43, 0x29, 0xea, 0x5c, 0x22, 0xbf, 0xd3, + 0x3e, 0x3d, 0xbe, 0x4c, 0xf5, 0x8c, 0xc6, 0x08, + 0xc2, 0xc2, 0x6c, 0x19, 0xa2, 0xe2, 0xfe, 0x22, + 0xf9, 0x87, 0x32, 0xc2, 0xb5, 0xcb, 0x84, 0x4c, + 0xc6, 0xc0, 0x70, 0x2d, 0x91, 0xe1, 0xd5, 0x0f, + 0xc4, 0x38, 0x2a, 0x7e, 0xba, 0x56, 0x35, 0xcd, + 0x60, 0x24, 0x32, 0xa2, 0x30, 0x6a, 0xc4, 0xce, + 0x82, 0xf8, 0xd7, 0x0c, 0x8d, 0x9b, 0xc1, 0x5f, + 0x91, 0x8f, 0xe7, 0x1e, 0x74, 0xc6, 0x22, 0xd5, + 0xcf, 0x71, 0x17, 0x8b, 0xf6, 0xe0, 0xb9, 0xcc, + 0x9f, 0x2b, 0x41, 0xdd, 0x8d, 0xbe, 0x44, 0x1c, + 0x41, 0xcd, 0x0c, 0x73, 0xa6, 0xdc, 0x47, 0xa3, + 0x48, 0xf6, 0x70, 0x2f, 0x9d, 0x0e, 0x9b, 0x1b, + 0x14, 0x31, 0xe9, 0x48, 0xe2, 0x99, 0xb9, 0xec, + 0x22, 0x72, 0xab, 0x2c, 0x5f, 0x0c, 0x7b, 0xe8, + 0x6a, 0xff, 0xa5, 0xde, 0xc8, 0x7a, 0x0b, 0xee, + 0x81, 0xd3, 0xd5, 0x00, 0x07, 0xed, 0xaa, 0x2b, + 0xcf, 0xcc, 0xb3, 0x56, 0x05, 0x15, 0x5f, 0xf3, + 0x6e, 0xd8, 0xed, 0xd4, 0xa4, 0x0d, 0xcd, 0x4b, + 0x24, 0x3a, 0xcd, 0x11, 0xb2, 0xb9, 0x87, 0xbd, + 0xbf, 0xaf, 0x91, 0xa7, 0xca, 0xc2, 0x7e, 0x9c, + 0x5a, 0xea, 0x52, 0x5e, 0xe5, 0x3d, 0xe7, 0xb2, + 0xd3, 0x33, 0x2c, 0x86, 0x44, 0x40, 0x2b, 0x82, + 0x3e, 0x94, 0xa7, 0xdb, 0x26, 0x27, 0x6d, 0x2d, + 0x23, 0xaa, 0x07, 0x18, 0x0f, 0x76, 0xb4, 0xfd, + 0x29, 0xb9, 0xc0, 0x82, 0x30, 0x99, 0xc9, 0xd6, + 0x2c, 0x51, 0x98, 0x80, 0xae, 0xe7, 0xe9, 0x69, + 0x76, 0x17, 0xc1, 0x49, 0x7d, 0x47, 0xbf, 0x3e, + 0x57, 0x19, 0x50, 0x31, 0x14, 0x21, 0xb6, 0xb7, + 0x34, 0xd3, 0x8b, 0x0d, 0xb9, 0x1e, 0xb8, 0x53, + 0x31, 0xb9, 0x1e, 0xa9, 0xf6, 0x15, 0x30, 0xf5, + 0x45, 0x12, 0xa5, 0xa5, 0x2a, 0x4b, 0xad, 0x58, + 0x9e, 0xb6, 0x97, 0x81, 0xd5, 0x37, 0xf2, 0x32, + 0x97, 0xbb, 0x45, 0x9b, 0xda, 0xd2, 0x94, 0x8a, + 0x29, 0xe1, 0x55, 0x0b, 0xf4, 0x78, 0x7e, 0x0b, + 0xe9, 0x5b, 0xb1, 0x73, 0xcf, 0x5f, 0xab, 0x17, + 0xda, 0xb7, 0xa1, 0x3a, 0x05, 0x2a, 0x63, 0x45, + 0x3d, 0x97, 0xcc, 0xec, 0x1a, 0x32, 0x19, 0x54, + 0x88, 0x6b, 0x7a, 0x12, 0x99, 0xfa, 0xae, 0xec, + 0xae, 0x35, 0xc6, 0xea, 0xac, 0xa7, 0x53, 0xb0, + 0x41, 0xb5, 0xe5, 0xf0, 0x93, 0xbf, 0x83, 0x39, + 0x7f, 0xd2, 0x1d, 0xd6, 0xb3, 0x01, 0x20, 0x66, + 0xfc, 0xc0, 0x58, 0xcc, 0x32, 0xc3, 0xb0, 0x9d, + 0x75, 0x62, 0xde, 0xe2, 0x95, 0x09, 0xb5, 0x83, + 0x93, 0x92, 0xc9, 0xff, 0x05, 0xf5, 0x1f, 0x31, + 0x66, 0xaa, 0xac, 0x4a, 0xc5, 0xf2, 0x38, 0x03, + 0x8a, 0x30, 0x45, 0xe6, 0xf7, 0x2e, 0x48, 0xef, + 0x0f, 0xe8, 0xbc, 0x67, 0x5e, 0x82, 0xc3, 0x18, + 0xa2, 0x68, 0xe4, 0x39, 0x70, 0x27, 0x1b, 0xf1, + 0x19, 0xb8, 0x1b, 0xf6, 0xa9, 0x82, 0x74, 0x65, + 0x54, 0xf8, 0x4e, 0x72, 0xb9, 0xf0, 0x02, 0x80, + 0xa3, 0x20, 0xa0, 0x81, 0x42, 0x92, 0x3c, 0x23, + 0xc8, 0x83, 0x42, 0x3f, 0xf9, 0x49, 0x82, 0x7f, + 0x29, 0xbb, 0xac, 0xdc, 0x1c, 0xcd, 0xb0, 0x49, + 0x38, 0xce, 0x60, 0x98, 0xc9, 0x5b, 0xa6, 0xb3, + 0x25, 0x28, 0xf4, 0xef, 0x78, 0xee, 0xd7, 0x78, + 0xb2, 0xe1, 0x22, 0xdd, 0xfd, 0x1c, 0xbd, 0xd1, + 0x1d, 0x1c, 0x0a, 0x67, 0x83, 0xe0, 0x11, 0xfc, + 0x53, 0x6d, 0x63, 0xd0, 0x53, 0x26, 0x06, 0x37, +}; + +static const uint8_t aes_xts_256_vec8_ctxt[SECSIZE] = { + 0x72, 0xef, 0xc1, 0xeb, 0xfe, 0x1e, 0xe2, 0x59, + 0x75, 0xa6, 0xeb, 0x3a, 0xa8, 0x58, 0x9d, 0xda, + 0x2b, 0x26, 0x1f, 0x1c, 0x85, 0xbd, 0xab, 0x44, + 0x2a, 0x9e, 0x5b, 0x2d, 0xd1, 0xd7, 0xc3, 0x95, + 0x7a, 0x16, 0xfc, 0x08, 0xe5, 0x26, 0xd4, 0xb1, + 0x22, 0x3f, 0x1b, 0x12, 0x32, 0xa1, 0x1a, 0xf2, + 0x74, 0xc3, 0xd7, 0x0d, 0xac, 0x57, 0xf8, 0x3e, + 0x09, 0x83, 0xc4, 0x98, 0xf1, 0xa6, 0xf1, 0xae, + 0xcb, 0x02, 0x1c, 0x3e, 0x70, 0x08, 0x5a, 0x1e, + 0x52, 0x7f, 0x1c, 0xe4, 0x1e, 0xe5, 0x91, 0x1a, + 0x82, 0x02, 0x01, 0x61, 0x52, 0x9c, 0xd8, 0x27, + 0x73, 0x76, 0x2d, 0xaf, 0x54, 0x59, 0xde, 0x94, + 0xa0, 0xa8, 0x2a, 0xda, 0xe7, 0xe1, 0x70, 0x3c, + 0x80, 0x85, 0x43, 0xc2, 0x9e, 0xd6, 0xfb, 0x32, + 0xd9, 0xe0, 0x04, 0x32, 0x7c, 0x13, 0x55, 0x18, + 0x0c, 0x99, 0x5a, 0x07, 0x74, 0x14, 0x93, 0xa0, + 0x9c, 0x21, 0xba, 0x01, 0xa3, 0x87, 0x88, 0x2d, + 0xa4, 0xf6, 0x25, 0x34, 0xb8, 0x7b, 0xb1, 0x5d, + 0x60, 0xd1, 0x97, 0x20, 0x1c, 0x0f, 0xd3, 0xbf, + 0x30, 0xc1, 0x50, 0x0a, 0x3e, 0xcf, 0xec, 0xdd, + 0x66, 0xd8, 0x72, 0x1f, 0x90, 0xbc, 0xc4, 0xc1, + 0x7e, 0xe9, 0x25, 0xc6, 0x1b, 0x0a, 0x03, 0x72, + 0x7a, 0x9c, 0x0d, 0x5f, 0x5c, 0xa4, 0x62, 0xfb, + 0xfa, 0x0a, 0xf1, 0xc2, 0x51, 0x3a, 0x9d, 0x9d, + 0x4b, 0x53, 0x45, 0xbd, 0x27, 0xa5, 0xf6, 0xe6, + 0x53, 0xf7, 0x51, 0x69, 0x3e, 0x6b, 0x6a, 0x2b, + 0x8e, 0xad, 0x57, 0xd5, 0x11, 0xe0, 0x0e, 0x58, + 0xc4, 0x5b, 0x7b, 0x8d, 0x00, 0x5a, 0xf7, 0x92, + 0x88, 0xf5, 0xc7, 0xc2, 0x2f, 0xd4, 0xf1, 0xbf, + 0x7a, 0x89, 0x8b, 0x03, 0xa5, 0x63, 0x4c, 0x6a, + 0x1a, 0xe3, 0xf9, 0xfa, 0xe5, 0xde, 0x4f, 0x29, + 0x6a, 0x28, 0x96, 0xb2, 0x3e, 0x7e, 0xd4, 0x3e, + 0xd1, 0x4f, 0xa5, 0xa2, 0x80, 0x3f, 0x4d, 0x28, + 0xf0, 0xd3, 0xff, 0xcf, 0x24, 0x75, 0x76, 0x77, + 0xae, 0xbd, 0xb4, 0x7b, 0xb3, 0x88, 0x37, 0x87, + 0x08, 0x94, 0x8a, 0x8d, 0x41, 0x26, 0xed, 0x18, + 0x39, 0xe0, 0xda, 0x29, 0xa5, 0x37, 0xa8, 0xc1, + 0x98, 0xb3, 0xc6, 0x6a, 0xb0, 0x07, 0x12, 0xdd, + 0x26, 0x16, 0x74, 0xbf, 0x45, 0xa7, 0x3d, 0x67, + 0xf7, 0x69, 0x14, 0xf8, 0x30, 0xca, 0x01, 0x4b, + 0x65, 0x59, 0x6f, 0x27, 0xe4, 0xcf, 0x62, 0xde, + 0x66, 0x12, 0x5a, 0x55, 0x66, 0xdf, 0x99, 0x75, + 0x15, 0x56, 0x28, 0xb4, 0x00, 0xfb, 0xfb, 0x3a, + 0x29, 0x04, 0x0e, 0xd5, 0x0f, 0xaf, 0xfd, 0xbb, + 0x18, 0xae, 0xce, 0x7c, 0x5c, 0x44, 0x69, 0x32, + 0x60, 0xaa, 0xb3, 0x86, 0xc0, 0xa3, 0x7b, 0x11, + 0xb1, 0x14, 0xf1, 0xc4, 0x15, 0xae, 0xbb, 0x65, + 0x3b, 0xe4, 0x68, 0x17, 0x94, 0x28, 0xd4, 0x3a, + 0x4d, 0x8b, 0xc3, 0xec, 0x38, 0x81, 0x3e, 0xca, + 0x30, 0xa1, 0x3c, 0xf1, 0xbb, 0x18, 0xd5, 0x24, + 0xf1, 0x99, 0x2d, 0x44, 0xd8, 0xb1, 0xa4, 0x2e, + 0xa3, 0x0b, 0x22, 0xe6, 0xc9, 0x5b, 0x19, 0x9d, + 0x8d, 0x18, 0x2f, 0x88, 0x40, 0xb0, 0x9d, 0x05, + 0x95, 0x85, 0xc3, 0x1a, 0xd6, 0x91, 0xfa, 0x06, + 0x19, 0xff, 0x03, 0x8a, 0xca, 0x2c, 0x39, 0xa9, + 0x43, 0x42, 0x11, 0x57, 0x36, 0x17, 0x17, 0xc4, + 0x9d, 0x32, 0x20, 0x28, 0xa7, 0x46, 0x48, 0x11, + 0x3b, 0xd8, 0xc9, 0xd7, 0xec, 0x77, 0xcf, 0x3c, + 0x89, 0xc1, 0xec, 0x87, 0x18, 0xce, 0xff, 0x85, + 0x16, 0xd9, 0x6b, 0x34, 0xc3, 0xc6, 0x14, 0xf1, + 0x06, 0x99, 0xc9, 0xab, 0xc4, 0xed, 0x04, 0x11, + 0x50, 0x62, 0x23, 0xbe, 0xa1, 0x6a, 0xf3, 0x5c, + 0x88, 0x3a, 0xcc, 0xdb, 0xe1, 0x10, 0x4e, 0xef, + 0x0c, 0xfd, 0xb5, 0x4e, 0x12, 0xfb, 0x23, 0x0a, +}; + +/* + * Vector 9 from IEEE 1619/D16, blkno 0xff. + */ +static const uint8_t aes_xts_256_vec9_ptxt[SECSIZE] = { + 0x72, 0xef, 0xc1, 0xeb, 0xfe, 0x1e, 0xe2, 0x59, + 0x75, 0xa6, 0xeb, 0x3a, 0xa8, 0x58, 0x9d, 0xda, + 0x2b, 0x26, 0x1f, 0x1c, 0x85, 0xbd, 0xab, 0x44, + 0x2a, 0x9e, 0x5b, 0x2d, 0xd1, 0xd7, 0xc3, 0x95, + 0x7a, 0x16, 0xfc, 0x08, 0xe5, 0x26, 0xd4, 0xb1, + 0x22, 0x3f, 0x1b, 0x12, 0x32, 0xa1, 0x1a, 0xf2, + 0x74, 0xc3, 0xd7, 0x0d, 0xac, 0x57, 0xf8, 0x3e, + 0x09, 0x83, 0xc4, 0x98, 0xf1, 0xa6, 0xf1, 0xae, + 0xcb, 0x02, 0x1c, 0x3e, 0x70, 0x08, 0x5a, 0x1e, + 0x52, 0x7f, 0x1c, 0xe4, 0x1e, 0xe5, 0x91, 0x1a, + 0x82, 0x02, 0x01, 0x61, 0x52, 0x9c, 0xd8, 0x27, + 0x73, 0x76, 0x2d, 0xaf, 0x54, 0x59, 0xde, 0x94, + 0xa0, 0xa8, 0x2a, 0xda, 0xe7, 0xe1, 0x70, 0x3c, + 0x80, 0x85, 0x43, 0xc2, 0x9e, 0xd6, 0xfb, 0x32, + 0xd9, 0xe0, 0x04, 0x32, 0x7c, 0x13, 0x55, 0x18, + 0x0c, 0x99, 0x5a, 0x07, 0x74, 0x14, 0x93, 0xa0, + 0x9c, 0x21, 0xba, 0x01, 0xa3, 0x87, 0x88, 0x2d, + 0xa4, 0xf6, 0x25, 0x34, 0xb8, 0x7b, 0xb1, 0x5d, + 0x60, 0xd1, 0x97, 0x20, 0x1c, 0x0f, 0xd3, 0xbf, + 0x30, 0xc1, 0x50, 0x0a, 0x3e, 0xcf, 0xec, 0xdd, + 0x66, 0xd8, 0x72, 0x1f, 0x90, 0xbc, 0xc4, 0xc1, + 0x7e, 0xe9, 0x25, 0xc6, 0x1b, 0x0a, 0x03, 0x72, + 0x7a, 0x9c, 0x0d, 0x5f, 0x5c, 0xa4, 0x62, 0xfb, + 0xfa, 0x0a, 0xf1, 0xc2, 0x51, 0x3a, 0x9d, 0x9d, + 0x4b, 0x53, 0x45, 0xbd, 0x27, 0xa5, 0xf6, 0xe6, + 0x53, 0xf7, 0x51, 0x69, 0x3e, 0x6b, 0x6a, 0x2b, + 0x8e, 0xad, 0x57, 0xd5, 0x11, 0xe0, 0x0e, 0x58, + 0xc4, 0x5b, 0x7b, 0x8d, 0x00, 0x5a, 0xf7, 0x92, + 0x88, 0xf5, 0xc7, 0xc2, 0x2f, 0xd4, 0xf1, 0xbf, + 0x7a, 0x89, 0x8b, 0x03, 0xa5, 0x63, 0x4c, 0x6a, + 0x1a, 0xe3, 0xf9, 0xfa, 0xe5, 0xde, 0x4f, 0x29, + 0x6a, 0x28, 0x96, 0xb2, 0x3e, 0x7e, 0xd4, 0x3e, + 0xd1, 0x4f, 0xa5, 0xa2, 0x80, 0x3f, 0x4d, 0x28, + 0xf0, 0xd3, 0xff, 0xcf, 0x24, 0x75, 0x76, 0x77, + 0xae, 0xbd, 0xb4, 0x7b, 0xb3, 0x88, 0x37, 0x87, + 0x08, 0x94, 0x8a, 0x8d, 0x41, 0x26, 0xed, 0x18, + 0x39, 0xe0, 0xda, 0x29, 0xa5, 0x37, 0xa8, 0xc1, + 0x98, 0xb3, 0xc6, 0x6a, 0xb0, 0x07, 0x12, 0xdd, + 0x26, 0x16, 0x74, 0xbf, 0x45, 0xa7, 0x3d, 0x67, + 0xf7, 0x69, 0x14, 0xf8, 0x30, 0xca, 0x01, 0x4b, + 0x65, 0x59, 0x6f, 0x27, 0xe4, 0xcf, 0x62, 0xde, + 0x66, 0x12, 0x5a, 0x55, 0x66, 0xdf, 0x99, 0x75, + 0x15, 0x56, 0x28, 0xb4, 0x00, 0xfb, 0xfb, 0x3a, + 0x29, 0x04, 0x0e, 0xd5, 0x0f, 0xaf, 0xfd, 0xbb, + 0x18, 0xae, 0xce, 0x7c, 0x5c, 0x44, 0x69, 0x32, + 0x60, 0xaa, 0xb3, 0x86, 0xc0, 0xa3, 0x7b, 0x11, + 0xb1, 0x14, 0xf1, 0xc4, 0x15, 0xae, 0xbb, 0x65, + 0x3b, 0xe4, 0x68, 0x17, 0x94, 0x28, 0xd4, 0x3a, + 0x4d, 0x8b, 0xc3, 0xec, 0x38, 0x81, 0x3e, 0xca, + 0x30, 0xa1, 0x3c, 0xf1, 0xbb, 0x18, 0xd5, 0x24, + 0xf1, 0x99, 0x2d, 0x44, 0xd8, 0xb1, 0xa4, 0x2e, + 0xa3, 0x0b, 0x22, 0xe6, 0xc9, 0x5b, 0x19, 0x9d, + 0x8d, 0x18, 0x2f, 0x88, 0x40, 0xb0, 0x9d, 0x05, + 0x95, 0x85, 0xc3, 0x1a, 0xd6, 0x91, 0xfa, 0x06, + 0x19, 0xff, 0x03, 0x8a, 0xca, 0x2c, 0x39, 0xa9, + 0x43, 0x42, 0x11, 0x57, 0x36, 0x17, 0x17, 0xc4, + 0x9d, 0x32, 0x20, 0x28, 0xa7, 0x46, 0x48, 0x11, + 0x3b, 0xd8, 0xc9, 0xd7, 0xec, 0x77, 0xcf, 0x3c, + 0x89, 0xc1, 0xec, 0x87, 0x18, 0xce, 0xff, 0x85, + 0x16, 0xd9, 0x6b, 0x34, 0xc3, 0xc6, 0x14, 0xf1, + 0x06, 0x99, 0xc9, 0xab, 0xc4, 0xed, 0x04, 0x11, + 0x50, 0x62, 0x23, 0xbe, 0xa1, 0x6a, 0xf3, 0x5c, + 0x88, 0x3a, 0xcc, 0xdb, 0xe1, 0x10, 0x4e, 0xef, + 0x0c, 0xfd, 0xb5, 0x4e, 0x12, 0xfb, 0x23, 0x0a, +}; + +static const uint8_t aes_xts_256_vec9_ctxt[SECSIZE] = { + 0x32, 0x60, 0xae, 0x8d, 0xad, 0x1f, 0x4a, 0x32, + 0xc5, 0xca, 0xfe, 0x3a, 0xb0, 0xeb, 0x95, 0x54, + 0x9d, 0x46, 0x1a, 0x67, 0xce, 0xb9, 0xe5, 0xaa, + 0x2d, 0x3a, 0xfb, 0x62, 0xde, 0xce, 0x05, 0x53, + 0x19, 0x3b, 0xa5, 0x0c, 0x75, 0xbe, 0x25, 0x1e, + 0x08, 0xd1, 0xd0, 0x8f, 0x10, 0x88, 0x57, 0x6c, + 0x7e, 0xfd, 0xfa, 0xaf, 0x3f, 0x45, 0x95, 0x59, + 0x57, 0x1e, 0x12, 0x51, 0x17, 0x53, 0xb0, 0x7a, + 0xf0, 0x73, 0xf3, 0x5d, 0xa0, 0x6a, 0xf0, 0xce, + 0x0b, 0xbf, 0x6b, 0x8f, 0x5c, 0xcc, 0x5c, 0xea, + 0x50, 0x0e, 0xc1, 0xb2, 0x11, 0xbd, 0x51, 0xf6, + 0x3b, 0x60, 0x6b, 0xf6, 0x52, 0x87, 0x96, 0xca, + 0x12, 0x17, 0x3b, 0xa3, 0x9b, 0x89, 0x35, 0xee, + 0x44, 0xcc, 0xce, 0x64, 0x6f, 0x90, 0xa4, 0x5b, + 0xf9, 0xcc, 0xc5, 0x67, 0xf0, 0xac, 0xe1, 0x3d, + 0xc2, 0xd5, 0x3e, 0xbe, 0xed, 0xc8, 0x1f, 0x58, + 0xb2, 0xe4, 0x11, 0x79, 0xdd, 0xdf, 0x0d, 0x5a, + 0x5c, 0x42, 0xf5, 0xd8, 0x50, 0x6c, 0x1a, 0x5d, + 0x2f, 0x8f, 0x59, 0xf3, 0xea, 0x87, 0x3c, 0xbc, + 0xd0, 0xee, 0xc1, 0x9a, 0xcb, 0xf3, 0x25, 0x42, + 0x3b, 0xd3, 0xdc, 0xb8, 0xc2, 0xb1, 0xbf, 0x1d, + 0x1e, 0xae, 0xd0, 0xeb, 0xa7, 0xf0, 0x69, 0x8e, + 0x43, 0x14, 0xfb, 0xeb, 0x2f, 0x15, 0x66, 0xd1, + 0xb9, 0x25, 0x30, 0x08, 0xcb, 0xcc, 0xf4, 0x5a, + 0x2b, 0x0d, 0x9c, 0x5c, 0x9c, 0x21, 0x47, 0x4f, + 0x40, 0x76, 0xe0, 0x2b, 0xe2, 0x60, 0x50, 0xb9, + 0x9d, 0xee, 0x4f, 0xd6, 0x8a, 0x4c, 0xf8, 0x90, + 0xe4, 0x96, 0xe4, 0xfc, 0xae, 0x7b, 0x70, 0xf9, + 0x4e, 0xa5, 0xa9, 0x06, 0x2d, 0xa0, 0xda, 0xeb, + 0xa1, 0x99, 0x3d, 0x2c, 0xcd, 0x1d, 0xd3, 0xc2, + 0x44, 0xb8, 0x42, 0x88, 0x01, 0x49, 0x5a, 0x58, + 0xb2, 0x16, 0x54, 0x7e, 0x7e, 0x84, 0x7c, 0x46, + 0xd1, 0xd7, 0x56, 0x37, 0x7b, 0x62, 0x42, 0xd2, + 0xe5, 0xfb, 0x83, 0xbf, 0x75, 0x2b, 0x54, 0xe0, + 0xdf, 0x71, 0xe8, 0x89, 0xf3, 0xa2, 0xbb, 0x0f, + 0x4c, 0x10, 0x80, 0x5b, 0xf3, 0xc5, 0x90, 0x37, + 0x6e, 0x3c, 0x24, 0xe2, 0x2f, 0xf5, 0x7f, 0x7f, + 0xa9, 0x65, 0x57, 0x73, 0x75, 0x32, 0x5c, 0xea, + 0x5d, 0x92, 0x0d, 0xb9, 0x4b, 0x9c, 0x33, 0x6b, + 0x45, 0x5f, 0x6e, 0x89, 0x4c, 0x01, 0x86, 0x6f, + 0xe9, 0xfb, 0xb8, 0xc8, 0xd3, 0xf7, 0x0a, 0x29, + 0x57, 0x28, 0x5f, 0x6d, 0xfb, 0x5d, 0xcd, 0x8c, + 0xbf, 0x54, 0x78, 0x2f, 0x8f, 0xe7, 0x76, 0x6d, + 0x47, 0x23, 0x81, 0x99, 0x13, 0xac, 0x77, 0x34, + 0x21, 0xe3, 0xa3, 0x10, 0x95, 0x86, 0x6b, 0xad, + 0x22, 0xc8, 0x6a, 0x60, 0x36, 0xb2, 0x51, 0x8b, + 0x20, 0x59, 0xb4, 0x22, 0x9d, 0x18, 0xc8, 0xc2, + 0xcc, 0xbd, 0xf9, 0x06, 0xc6, 0xcc, 0x6e, 0x82, + 0x46, 0x4e, 0xe5, 0x7b, 0xdd, 0xb0, 0xbe, 0xbc, + 0xb1, 0xdc, 0x64, 0x53, 0x25, 0xbf, 0xb3, 0xe6, + 0x65, 0xef, 0x72, 0x51, 0x08, 0x2c, 0x88, 0xeb, + 0xb1, 0xcf, 0x20, 0x3b, 0xd7, 0x79, 0xfd, 0xd3, + 0x86, 0x75, 0x71, 0x3c, 0x8d, 0xaa, 0xdd, 0x17, + 0xe1, 0xca, 0xbe, 0xe4, 0x32, 0xb0, 0x97, 0x87, + 0xb6, 0xdd, 0xf3, 0x30, 0x4e, 0x38, 0xb7, 0x31, + 0xb4, 0x5d, 0xf5, 0xdf, 0x51, 0xb7, 0x8f, 0xcf, + 0xb3, 0xd3, 0x24, 0x66, 0x02, 0x8d, 0x0b, 0xa3, + 0x65, 0x55, 0xe7, 0xe1, 0x1a, 0xb0, 0xee, 0x06, + 0x66, 0x06, 0x1d, 0x16, 0x45, 0xd9, 0x62, 0x44, + 0x4b, 0xc4, 0x7a, 0x38, 0x18, 0x89, 0x30, 0xa8, + 0x4b, 0x4d, 0x56, 0x13, 0x95, 0xc7, 0x3c, 0x08, + 0x70, 0x21, 0x92, 0x7c, 0xa6, 0x38, 0xb7, 0xaf, + 0xc8, 0xa8, 0x67, 0x9c, 0xcb, 0x84, 0xc2, 0x65, + 0x55, 0x44, 0x0e, 0xc7, 0xf1, 0x04, 0x45, 0xcd, +}; + +const struct testvec aes_xts_256_vectors[] = { + { + .blkno = 0, + .ptxt = aes_xts_256_vec4_ptxt, + .ctxt = aes_xts_256_vec4_ctxt, + }, + { + .blkno = 1, + .ptxt = aes_xts_256_vec5_ptxt, + .ctxt = aes_xts_256_vec5_ctxt, + }, + { + .blkno = 2, + .ptxt = aes_xts_256_vec6_ptxt, + .ctxt = aes_xts_256_vec6_ctxt, + }, + { + .blkno = 0xfd, + .ptxt = aes_xts_256_vec7_ptxt, + .ctxt = aes_xts_256_vec7_ctxt, + }, + { + .blkno = 0xfe, + .ptxt = aes_xts_256_vec8_ptxt, + .ctxt = aes_xts_256_vec8_ctxt, + }, + { + .blkno = 0xff, + .ptxt = aes_xts_256_vec9_ptxt, + .ctxt = aes_xts_256_vec9_ctxt, + }, +}; + +/* + * Vector 10 from IEEE 1619/D16, blkno 0xff. + */ +static const uint8_t aes_xts_512_vec10_ptxt[SECSIZE] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +static const uint8_t aes_xts_512_vec10_ctxt[SECSIZE] = { + 0x1c, 0x3b, 0x3a, 0x10, 0x2f, 0x77, 0x03, 0x86, + 0xe4, 0x83, 0x6c, 0x99, 0xe3, 0x70, 0xcf, 0x9b, + 0xea, 0x00, 0x80, 0x3f, 0x5e, 0x48, 0x23, 0x57, + 0xa4, 0xae, 0x12, 0xd4, 0x14, 0xa3, 0xe6, 0x3b, + 0x5d, 0x31, 0xe2, 0x76, 0xf8, 0xfe, 0x4a, 0x8d, + 0x66, 0xb3, 0x17, 0xf9, 0xac, 0x68, 0x3f, 0x44, + 0x68, 0x0a, 0x86, 0xac, 0x35, 0xad, 0xfc, 0x33, + 0x45, 0xbe, 0xfe, 0xcb, 0x4b, 0xb1, 0x88, 0xfd, + 0x57, 0x76, 0x92, 0x6c, 0x49, 0xa3, 0x09, 0x5e, + 0xb1, 0x08, 0xfd, 0x10, 0x98, 0xba, 0xec, 0x70, + 0xaa, 0xa6, 0x69, 0x99, 0xa7, 0x2a, 0x82, 0xf2, + 0x7d, 0x84, 0x8b, 0x21, 0xd4, 0xa7, 0x41, 0xb0, + 0xc5, 0xcd, 0x4d, 0x5f, 0xff, 0x9d, 0xac, 0x89, + 0xae, 0xba, 0x12, 0x29, 0x61, 0xd0, 0x3a, 0x75, + 0x71, 0x23, 0xe9, 0x87, 0x0f, 0x8a, 0xcf, 0x10, + 0x00, 0x02, 0x08, 0x87, 0x89, 0x14, 0x29, 0xca, + 0x2a, 0x3e, 0x7a, 0x7d, 0x7d, 0xf7, 0xb1, 0x03, + 0x55, 0x16, 0x5c, 0x8b, 0x9a, 0x6d, 0x0a, 0x7d, + 0xe8, 0xb0, 0x62, 0xc4, 0x50, 0x0d, 0xc4, 0xcd, + 0x12, 0x0c, 0x0f, 0x74, 0x18, 0xda, 0xe3, 0xd0, + 0xb5, 0x78, 0x1c, 0x34, 0x80, 0x3f, 0xa7, 0x54, + 0x21, 0xc7, 0x90, 0xdf, 0xe1, 0xde, 0x18, 0x34, + 0xf2, 0x80, 0xd7, 0x66, 0x7b, 0x32, 0x7f, 0x6c, + 0x8c, 0xd7, 0x55, 0x7e, 0x12, 0xac, 0x3a, 0x0f, + 0x93, 0xec, 0x05, 0xc5, 0x2e, 0x04, 0x93, 0xef, + 0x31, 0xa1, 0x2d, 0x3d, 0x92, 0x60, 0xf7, 0x9a, + 0x28, 0x9d, 0x6a, 0x37, 0x9b, 0xc7, 0x0c, 0x50, + 0x84, 0x14, 0x73, 0xd1, 0xa8, 0xcc, 0x81, 0xec, + 0x58, 0x3e, 0x96, 0x45, 0xe0, 0x7b, 0x8d, 0x96, + 0x70, 0x65, 0x5b, 0xa5, 0xbb, 0xcf, 0xec, 0xc6, + 0xdc, 0x39, 0x66, 0x38, 0x0a, 0xd8, 0xfe, 0xcb, + 0x17, 0xb6, 0xba, 0x02, 0x46, 0x9a, 0x02, 0x0a, + 0x84, 0xe1, 0x8e, 0x8f, 0x84, 0x25, 0x20, 0x70, + 0xc1, 0x3e, 0x9f, 0x1f, 0x28, 0x9b, 0xe5, 0x4f, + 0xbc, 0x48, 0x14, 0x57, 0x77, 0x8f, 0x61, 0x60, + 0x15, 0xe1, 0x32, 0x7a, 0x02, 0xb1, 0x40, 0xf1, + 0x50, 0x5e, 0xb3, 0x09, 0x32, 0x6d, 0x68, 0x37, + 0x8f, 0x83, 0x74, 0x59, 0x5c, 0x84, 0x9d, 0x84, + 0xf4, 0xc3, 0x33, 0xec, 0x44, 0x23, 0x88, 0x51, + 0x43, 0xcb, 0x47, 0xbd, 0x71, 0xc5, 0xed, 0xae, + 0x9b, 0xe6, 0x9a, 0x2f, 0xfe, 0xce, 0xb1, 0xbe, + 0xc9, 0xde, 0x24, 0x4f, 0xbe, 0x15, 0x99, 0x2b, + 0x11, 0xb7, 0x7c, 0x04, 0x0f, 0x12, 0xbd, 0x8f, + 0x6a, 0x97, 0x5a, 0x44, 0xa0, 0xf9, 0x0c, 0x29, + 0xa9, 0xab, 0xc3, 0xd4, 0xd8, 0x93, 0x92, 0x72, + 0x84, 0xc5, 0x87, 0x54, 0xcc, 0xe2, 0x94, 0x52, + 0x9f, 0x86, 0x14, 0xdc, 0xd2, 0xab, 0xa9, 0x91, + 0x92, 0x5f, 0xed, 0xc4, 0xae, 0x74, 0xff, 0xac, + 0x6e, 0x33, 0x3b, 0x93, 0xeb, 0x4a, 0xff, 0x04, + 0x79, 0xda, 0x9a, 0x41, 0x0e, 0x44, 0x50, 0xe0, + 0xdd, 0x7a, 0xe4, 0xc6, 0xe2, 0x91, 0x09, 0x00, + 0x57, 0x5d, 0xa4, 0x01, 0xfc, 0x07, 0x05, 0x9f, + 0x64, 0x5e, 0x8b, 0x7e, 0x9b, 0xfd, 0xef, 0x33, + 0x94, 0x30, 0x54, 0xff, 0x84, 0x01, 0x14, 0x93, + 0xc2, 0x7b, 0x34, 0x29, 0xea, 0xed, 0xb4, 0xed, + 0x53, 0x76, 0x44, 0x1a, 0x77, 0xed, 0x43, 0x85, + 0x1a, 0xd7, 0x7f, 0x16, 0xf5, 0x41, 0xdf, 0xd2, + 0x69, 0xd5, 0x0d, 0x6a, 0x5f, 0x14, 0xfb, 0x0a, + 0xab, 0x1c, 0xbb, 0x4c, 0x15, 0x50, 0xbe, 0x97, + 0xf7, 0xab, 0x40, 0x66, 0x19, 0x3c, 0x4c, 0xaa, + 0x77, 0x3d, 0xad, 0x38, 0x01, 0x4b, 0xd2, 0x09, + 0x2f, 0xa7, 0x55, 0xc8, 0x24, 0xbb, 0x5e, 0x54, + 0xc4, 0xf3, 0x6f, 0xfd, 0xa9, 0xfc, 0xea, 0x70, + 0xb9, 0xc6, 0xe6, 0x93, 0xe1, 0x48, 0xc1, 0x51, +}; + +/* + * Vector 11 from IEEE 1619/D16, blkno 0xffff. + */ +static const uint8_t aes_xts_512_vec11_ptxt[SECSIZE] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +static const uint8_t aes_xts_512_vec11_ctxt[SECSIZE] = { + 0x77, 0xa3, 0x12, 0x51, 0x61, 0x8a, 0x15, 0xe6, + 0xb9, 0x2d, 0x1d, 0x66, 0xdf, 0xfe, 0x7b, 0x50, + 0xb5, 0x0b, 0xad, 0x55, 0x23, 0x05, 0xba, 0x02, + 0x17, 0xa6, 0x10, 0x68, 0x8e, 0xff, 0x7e, 0x11, + 0xe1, 0xd0, 0x22, 0x54, 0x38, 0xe0, 0x93, 0x24, + 0x2d, 0x6d, 0xb2, 0x74, 0xfd, 0xe8, 0x01, 0xd4, + 0xca, 0xe0, 0x6f, 0x20, 0x92, 0xc7, 0x28, 0xb2, + 0x47, 0x85, 0x59, 0xdf, 0x58, 0xe8, 0x37, 0xc2, + 0x46, 0x9e, 0xe4, 0xa4, 0xfa, 0x79, 0x4e, 0x4b, + 0xbc, 0x7f, 0x39, 0xbc, 0x02, 0x6e, 0x3c, 0xb7, + 0x2c, 0x33, 0xb0, 0x88, 0x8f, 0x25, 0xb4, 0xac, + 0xf5, 0x6a, 0x2a, 0x98, 0x04, 0xf1, 0xce, 0x6d, + 0x3d, 0x6e, 0x1d, 0xc6, 0xca, 0x18, 0x1d, 0x4b, + 0x54, 0x61, 0x79, 0xd5, 0x55, 0x44, 0xaa, 0x77, + 0x60, 0xc4, 0x0d, 0x06, 0x74, 0x15, 0x39, 0xc7, + 0xe3, 0xcd, 0x9d, 0x2f, 0x66, 0x50, 0xb2, 0x01, + 0x3f, 0xd0, 0xee, 0xb8, 0xc2, 0xb8, 0xe3, 0xd8, + 0xd2, 0x40, 0xcc, 0xae, 0x2d, 0x4c, 0x98, 0x32, + 0x0a, 0x74, 0x42, 0xe1, 0xc8, 0xd7, 0x5a, 0x42, + 0xd6, 0xe6, 0xcf, 0xa4, 0xc2, 0xec, 0xa1, 0x79, + 0x8d, 0x15, 0x8c, 0x7a, 0xec, 0xdf, 0x82, 0x49, + 0x0f, 0x24, 0xbb, 0x9b, 0x38, 0xe1, 0x08, 0xbc, + 0xda, 0x12, 0xc3, 0xfa, 0xf9, 0xa2, 0x11, 0x41, + 0xc3, 0x61, 0x3b, 0x58, 0x36, 0x7f, 0x92, 0x2a, + 0xaa, 0x26, 0xcd, 0x22, 0xf2, 0x3d, 0x70, 0x8d, + 0xae, 0x69, 0x9a, 0xd7, 0xcb, 0x40, 0xa8, 0xad, + 0x0b, 0x6e, 0x27, 0x84, 0x97, 0x3d, 0xcb, 0x60, + 0x56, 0x84, 0xc0, 0x8b, 0x8d, 0x69, 0x98, 0xc6, + 0x9a, 0xac, 0x04, 0x99, 0x21, 0x87, 0x1e, 0xbb, + 0x65, 0x30, 0x1a, 0x46, 0x19, 0xca, 0x80, 0xec, + 0xb4, 0x85, 0xa3, 0x1d, 0x74, 0x42, 0x23, 0xce, + 0x8d, 0xdc, 0x23, 0x94, 0x82, 0x8d, 0x6a, 0x80, + 0x47, 0x0c, 0x09, 0x2f, 0x5b, 0xa4, 0x13, 0xc3, + 0x37, 0x8f, 0xa6, 0x05, 0x42, 0x55, 0xc6, 0xf9, + 0xdf, 0x44, 0x95, 0x86, 0x2b, 0xbb, 0x32, 0x87, + 0x68, 0x1f, 0x93, 0x1b, 0x68, 0x7c, 0x88, 0x8a, + 0xbf, 0x84, 0x4d, 0xfc, 0x8f, 0xc2, 0x83, 0x31, + 0xe5, 0x79, 0x92, 0x8c, 0xd1, 0x2b, 0xd2, 0x39, + 0x0a, 0xe1, 0x23, 0xcf, 0x03, 0x81, 0x8d, 0x14, + 0xde, 0xdd, 0xe5, 0xc0, 0xc2, 0x4c, 0x8a, 0xb0, + 0x18, 0xbf, 0xca, 0x75, 0xca, 0x09, 0x6f, 0x2d, + 0x53, 0x1f, 0x3d, 0x16, 0x19, 0xe7, 0x85, 0xf1, + 0xad, 0xa4, 0x37, 0xca, 0xb9, 0x2e, 0x98, 0x05, + 0x58, 0xb3, 0xdc, 0xe1, 0x47, 0x4a, 0xfb, 0x75, + 0xbf, 0xed, 0xbf, 0x8f, 0xf5, 0x4c, 0xb2, 0x61, + 0x8e, 0x02, 0x44, 0xc9, 0xac, 0x0d, 0x3c, 0x66, + 0xfb, 0x51, 0x59, 0x8c, 0xd2, 0xdb, 0x11, 0xf9, + 0xbe, 0x39, 0x79, 0x1a, 0xbe, 0x44, 0x7c, 0x63, + 0x09, 0x4f, 0x7c, 0x45, 0x3b, 0x7f, 0xf8, 0x7c, + 0xb5, 0xbb, 0x36, 0xb7, 0xc7, 0x9e, 0xfb, 0x08, + 0x72, 0xd1, 0x70, 0x58, 0xb8, 0x3b, 0x15, 0xab, + 0x08, 0x66, 0xad, 0x8a, 0x58, 0x65, 0x6c, 0x5a, + 0x7e, 0x20, 0xdb, 0xdf, 0x30, 0x8b, 0x24, 0x61, + 0xd9, 0x7c, 0x0e, 0xc0, 0x02, 0x4a, 0x27, 0x15, + 0x05, 0x52, 0x49, 0xcf, 0x3b, 0x47, 0x8d, 0xdd, + 0x47, 0x40, 0xde, 0x65, 0x4f, 0x75, 0xca, 0x68, + 0x6e, 0x0d, 0x73, 0x45, 0xc6, 0x9e, 0xd5, 0x0c, + 0xdc, 0x2a, 0x8b, 0x33, 0x2b, 0x1f, 0x88, 0x24, + 0x10, 0x8a, 0xc9, 0x37, 0xeb, 0x05, 0x05, 0x85, + 0x60, 0x8e, 0xe7, 0x34, 0x09, 0x7f, 0xc0, 0x90, + 0x54, 0xfb, 0xff, 0x89, 0xee, 0xae, 0xea, 0x79, + 0x1f, 0x4a, 0x7a, 0xb1, 0xf9, 0x86, 0x82, 0x94, + 0xa4, 0xf9, 0xe2, 0x7b, 0x42, 0xaf, 0x81, 0x00, + 0xcb, 0x9d, 0x59, 0xce, 0xf9, 0x64, 0x58, 0x03, +}; + +const struct testvec aes_xts_512_vectors[] = { + { + .blkno = 0xff, + .ptxt = aes_xts_512_vec10_ptxt, + .ctxt = aes_xts_512_vec10_ctxt, + }, + { + .blkno = 0xffff, + .ptxt = aes_xts_512_vec11_ptxt, + .ctxt = aes_xts_512_vec11_ctxt, + }, +}; + +static int +open_disk(const char *devpath, const char *imgpath, size_t size) +{ + int fd; + + fd = open(imgpath, O_CREAT | O_RDWR | O_TRUNC, 0600); + if (fd < 0) + return -1; + + if (ftruncate(fd, size) < 0) + goto fail; + + if (rump_pub_etfs_register_withsize(devpath, + imgpath, RUMP_ETFS_BLK, 0, size) < 0) { + goto fail; + } + + unlink(imgpath); + return fd; +fail: + close(fd); + unlink(imgpath); + return -1; +} + +static int +open_cgd(int devno) +{ + char devpath[32]; + + sprintf(devpath, "/dev/rcgd%d%c", devno, getrawpartition() + 'a'); + + return rump_sys_open(devpath, O_RDWR, 0); +} + +static int +configure_cgd(int fd, const char *dkpath, const char *alg, + const char *ivmethod, const char *key, size_t keylen) +{ + struct cgd_ioctl ci; + + memset(&ci, 0, sizeof(ci)); + ci.ci_disk = dkpath; + ci.ci_alg = alg; + ci.ci_ivmethod = ivmethod; + ci.ci_keylen = 8 * keylen - 8; /* Exclude the NUL terminator. */ + ci.ci_key = key; + ci.ci_blocksize = 128; + + return rump_sys_ioctl(fd, CGDIOCSET, &ci); +} + +static int +unconfigure_cgd(int fd) +{ + struct cgd_ioctl ci; + + return rump_sys_ioctl(fd, CGDIOCCLR, &ci); +} + +static int +write_testvec(int cgdfd, const struct testvec *tv) +{ + ssize_t written; + + if (rump_sys_lseek(cgdfd, tv->blkno * SECSIZE, SEEK_SET) < 0) + return -1; + + written = rump_sys_write(cgdfd, tv->ptxt, SECSIZE); + if (written < 0) + return -1; + if (written != SECSIZE) { + errno = EDOM; /* Something distinct. */ + return -1; + } + + return 0; +} + +static int +read_testvec(int cgdfd, const struct testvec *tv) +{ + char *buf; + int res = -1; + + buf = malloc(SECSIZE); + if (buf == NULL) + return -1; + + if (rump_sys_lseek(cgdfd, tv->blkno * SECSIZE, SEEK_SET) < 0) + goto fail; + + if (rump_sys_read(cgdfd, buf, SECSIZE) != SECSIZE) + goto fail; + + res = memcmp(buf, tv->ptxt, SECSIZE); +fail: + free(buf); + return res; +} + +static int +check_testvec(int dkfd, const struct testvec *tv) +{ + char *buf; + int res = -1; + + buf = malloc(SECSIZE); + if (buf == NULL) + return -1; + + if (lseek(dkfd, tv->blkno * SECSIZE, SEEK_SET) < 0) + goto fail; + + if (read(dkfd, buf, SECSIZE) != SECSIZE) + goto fail; + + res = memcmp(buf, tv->ctxt, SECSIZE); +fail: + free(buf); + return res; +} + +ATF_TC(cgd_aes_cbc_128_encblkno1); +ATF_TC_HEAD(cgd_aes_cbc_128_encblkno1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test aes-cbc with 128 bits key, ivmethod encblkno1"); +} + +ATF_TC_BODY(cgd_aes_cbc_128_encblkno1, tc) +{ + const char imgpath[] = "aes-cbc-128-encblkno1.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "aes-cbc", "encblkno1", + aes_cbc_128_key, sizeof(aes_cbc_128_key))); + + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_128_1_vectors[0]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_128_1_vectors[1]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_128_1_vectors[2]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_128_1_vectors[3]), -1); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "aes-cbc", "encblkno1", + aes_cbc_128_key, sizeof(aes_cbc_128_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_128_1_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_128_1_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_128_1_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_128_1_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_128_1_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_128_1_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_128_1_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_128_1_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_aes_cbc_128_encblkno8); +ATF_TC_HEAD(cgd_aes_cbc_128_encblkno8, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test aes-cbc with 128 bits key, ivmethod encblkno8"); +} + +ATF_TC_BODY(cgd_aes_cbc_128_encblkno8, tc) +{ + const char imgpath[] = "aes-cbc-128-encblkno8.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "aes-cbc", "encblkno8", + aes_cbc_128_key, sizeof(aes_cbc_128_key))); + + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_128_8_vectors[0]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_128_8_vectors[1]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_128_8_vectors[2]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_128_8_vectors[3]), -1); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "aes-cbc", "encblkno8", + aes_cbc_128_key, sizeof(aes_cbc_128_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_128_8_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_128_8_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_128_8_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_128_8_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_128_8_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_128_8_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_128_8_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_128_8_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_aes_cbc_192_encblkno1); +ATF_TC_HEAD(cgd_aes_cbc_192_encblkno1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test aes-cbc with 192 bits key, ivmethod encblkno1"); +} + +ATF_TC_BODY(cgd_aes_cbc_192_encblkno1, tc) +{ + const char imgpath[] = "aes-cbc-192-encblkno1.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "aes-cbc", "encblkno1", + aes_cbc_192_key, sizeof(aes_cbc_192_key))); + + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_192_1_vectors[0]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_192_1_vectors[1]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_192_1_vectors[2]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_192_1_vectors[3]), -1); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "aes-cbc", "encblkno1", + aes_cbc_192_key, sizeof(aes_cbc_192_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_192_1_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_192_1_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_192_1_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_192_1_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_192_1_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_192_1_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_192_1_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_192_1_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_aes_cbc_192_encblkno8); +ATF_TC_HEAD(cgd_aes_cbc_192_encblkno8, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test aes-cbc with 192 bits key, ivmethod encblkno8"); +} + +ATF_TC_BODY(cgd_aes_cbc_192_encblkno8, tc) +{ + const char imgpath[] = "aes-cbc-192-encblkno8.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "aes-cbc", "encblkno8", + aes_cbc_192_key, sizeof(aes_cbc_192_key))); + + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_192_8_vectors[0]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_192_8_vectors[1]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_192_8_vectors[2]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_192_8_vectors[3]), -1); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "aes-cbc", "encblkno8", + aes_cbc_192_key, sizeof(aes_cbc_192_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_192_8_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_192_8_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_192_8_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_192_8_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_192_8_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_192_8_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_192_8_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_192_8_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_aes_cbc_256_encblkno1); +ATF_TC_HEAD(cgd_aes_cbc_256_encblkno1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test aes-cbc with 256 bits key, ivmethod encblkno1"); +} + +ATF_TC_BODY(cgd_aes_cbc_256_encblkno1, tc) +{ + const char imgpath[] = "aes-cbc-256-encblkno1.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "aes-cbc", "encblkno1", + aes_cbc_256_key, sizeof(aes_cbc_256_key))); + + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_256_1_vectors[0]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_256_1_vectors[1]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_256_1_vectors[2]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_256_1_vectors[3]), -1); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "aes-cbc", "encblkno1", + aes_cbc_256_key, sizeof(aes_cbc_256_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_256_1_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_256_1_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_256_1_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_256_1_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_256_1_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_256_1_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_256_1_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_256_1_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_aes_cbc_256_encblkno8); +ATF_TC_HEAD(cgd_aes_cbc_256_encblkno8, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test aes-cbc with 256 bits key, ivmethod encblkno8"); +} + +ATF_TC_BODY(cgd_aes_cbc_256_encblkno8, tc) +{ + const char imgpath[] = "aes-cbc-256-encblkno8.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "aes-cbc", "encblkno8", + aes_cbc_256_key, sizeof(aes_cbc_256_key))); + + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_256_8_vectors[0]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_256_8_vectors[1]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_256_8_vectors[2]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_cbc_256_8_vectors[3]), -1); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "aes-cbc", "encblkno8", + aes_cbc_256_key, sizeof(aes_cbc_256_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_256_8_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_256_8_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_256_8_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_cbc_256_8_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_256_8_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_256_8_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_256_8_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_cbc_256_8_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_aes_xts_256); +ATF_TC_HEAD(cgd_aes_xts_256, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test aes-xts with 256 bits key"); +} + +ATF_TC_BODY(cgd_aes_xts_256, tc) +{ + const char imgpath[] = "aes-xts-256.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 256 * SECSIZE; /* Last blkno is 0xff. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "aes-xts", "encblkno1", + aes_xts_256_key, sizeof(aes_xts_256_key))); + + CHECK_LIBC(write_testvec(cgdfd, &aes_xts_256_vectors[0]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_xts_256_vectors[1]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_xts_256_vectors[2]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_xts_256_vectors[3]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_xts_256_vectors[4]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_xts_256_vectors[5]), -1); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "aes-xts", "encblkno1", + aes_xts_256_key, sizeof(aes_xts_256_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_xts_256_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_xts_256_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_xts_256_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_xts_256_vectors[3]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_xts_256_vectors[4]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_xts_256_vectors[5]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &aes_xts_256_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_xts_256_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_xts_256_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_xts_256_vectors[3]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_xts_256_vectors[4]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_xts_256_vectors[5]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_aes_xts_512); +ATF_TC_HEAD(cgd_aes_xts_512, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test aes-xts with 512 bits key"); +} + +ATF_TC_BODY(cgd_aes_xts_512, tc) +{ + const char imgpath[] = "aes-xts-512.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 65536 * SECSIZE; /* Last blkno is 0xffff. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "aes-xts", "encblkno1", + aes_xts_512_key, sizeof(aes_xts_512_key))); + + CHECK_LIBC(write_testvec(cgdfd, &aes_xts_512_vectors[0]), -1); + CHECK_LIBC(write_testvec(cgdfd, &aes_xts_512_vectors[1]), -1); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "aes-xts", "encblkno1", + aes_xts_512_key, sizeof(aes_xts_512_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_xts_512_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &aes_xts_512_vectors[1]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &aes_xts_512_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &aes_xts_512_vectors[1]), 0); + + RL(close(dkfd)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cgd_aes_cbc_128_encblkno1); + ATF_TP_ADD_TC(tp, cgd_aes_cbc_128_encblkno8); + ATF_TP_ADD_TC(tp, cgd_aes_cbc_192_encblkno1); + ATF_TP_ADD_TC(tp, cgd_aes_cbc_192_encblkno8); + ATF_TP_ADD_TC(tp, cgd_aes_cbc_256_encblkno1); + ATF_TP_ADD_TC(tp, cgd_aes_cbc_256_encblkno8); + ATF_TP_ADD_TC(tp, cgd_aes_xts_256); + ATF_TP_ADD_TC(tp, cgd_aes_xts_512); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/dev/cgd/t_cgd_blowfish.c b/contrib/netbsd-tests/dev/cgd/t_cgd_blowfish.c new file mode 100644 index 0000000..93aa834 --- /dev/null +++ b/contrib/netbsd-tests/dev/cgd/t_cgd_blowfish.c @@ -0,0 +1,2341 @@ +/* $NetBSD: t_cgd_blowfish.c,v 1.2 2017/01/13 21:30:39 christos Exp $ */ +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Alexander Nasonov. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_macros.h" + +#define SECSIZE 512 + +struct testvec { + unsigned int blkno; + const uint8_t *ptxt; /* PlainText */ + const uint8_t *ctxt; /* CipherText */ +}; + +/* + * 128 bits Blowfish key, NUL terminated. + */ +static const char bf_cbc_128_key[17] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 01234567 */ + 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, /* 89ABCDEF */ + 0 +}; + +/* + * 256 bits Blowfish key, NUL terminated. + */ +static const char bf_cbc_256_key[33] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 01234567 */ + 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, /* 89ABCDEF */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 01234567 */ + 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* 89abcdef */ + 0 +}; + +/* + * 448 bits Blowfish key, NUL terminated. + */ +static const char bf_cbc_448_key[57] = { + 0x3a, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* :ABCDEFG */ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* HIJKLMNO */ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* PQRSTUVW */ + 0x58, 0x59, 0x5a, 0x7e, 0x3a, 0x61, 0x62, 0x63, /* XYZ~:abc */ + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, /* defghijk */ + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, /* lmnopqrs */ + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x23, /* tuvwxyz# */ + 0 +}; + +static const uint8_t bf_cbc_ptxt[SECSIZE] = + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop" + " abcdefghijklmnop"; + +/* + * IV method encblkno1, blkno 0. + */ +static const uint8_t bf_cbc_128_encblkno1_vec0_ctxt[SECSIZE] = { + 0x78, 0x53, 0x43, 0x2a, 0x08, 0xe7, 0x84, 0x3f, + 0xb7, 0x61, 0x9c, 0x17, 0x81, 0xbe, 0x38, 0xb9, + 0x65, 0x51, 0x68, 0xa2, 0x29, 0xd7, 0x45, 0xc9, + 0xee, 0x0e, 0x9d, 0xe1, 0x69, 0xc6, 0x81, 0x81, + 0xf3, 0x93, 0xa6, 0x62, 0xc9, 0x05, 0x2c, 0x1b, + 0x0e, 0x05, 0xca, 0xbe, 0x12, 0x25, 0x37, 0xd8, + 0x98, 0x66, 0xa2, 0xd3, 0xd0, 0x8a, 0x89, 0x57, + 0x44, 0x91, 0x1e, 0xe9, 0x07, 0x03, 0x5c, 0xa6, + 0xb8, 0x30, 0xf1, 0xc7, 0x8c, 0x66, 0x05, 0xb0, + 0x2d, 0xc3, 0xc3, 0xd7, 0x60, 0xef, 0x62, 0xd3, + 0x34, 0x9c, 0xa9, 0xd2, 0x0c, 0x1a, 0x9c, 0xfe, + 0x74, 0x92, 0xcb, 0x90, 0x80, 0xfa, 0x71, 0x5c, + 0xaa, 0x29, 0x39, 0xdd, 0x3b, 0x62, 0xa1, 0xfc, + 0xa5, 0x35, 0xcd, 0xa3, 0x29, 0x41, 0x1a, 0x03, + 0xf7, 0xe1, 0x36, 0xb2, 0xdc, 0x1a, 0xb3, 0x9f, + 0x46, 0xa3, 0xf7, 0xc3, 0xd1, 0x29, 0x83, 0xcf, + 0x0d, 0x88, 0x0b, 0xd1, 0xb7, 0xc7, 0x87, 0x21, + 0xb7, 0x1f, 0xe7, 0xa2, 0x8e, 0x5f, 0xac, 0x6b, + 0x49, 0x9c, 0x93, 0x6b, 0x6b, 0x05, 0x8e, 0x4c, + 0xbd, 0x31, 0x13, 0x5f, 0x4a, 0xd0, 0x35, 0x0c, + 0x67, 0x8f, 0xd0, 0x7a, 0xc9, 0xe3, 0x52, 0x50, + 0x4f, 0x85, 0x09, 0xf1, 0x27, 0xb9, 0xb1, 0x1e, + 0xe4, 0x6a, 0x40, 0xf6, 0x5a, 0x4f, 0x5f, 0xbe, + 0xab, 0xe8, 0xb9, 0xfe, 0xc7, 0x59, 0x6b, 0x0c, + 0xcd, 0x46, 0x4e, 0x90, 0x99, 0xde, 0xf7, 0x43, + 0xee, 0x6e, 0xb6, 0xae, 0xc2, 0x5e, 0x08, 0xbb, + 0xe9, 0x30, 0x2d, 0xb2, 0x91, 0xcc, 0xb9, 0xc7, + 0x58, 0xea, 0x35, 0xae, 0xa2, 0xd8, 0x00, 0xf7, + 0xc0, 0x01, 0xc4, 0x34, 0x2b, 0x34, 0x43, 0xae, + 0xeb, 0x27, 0xbc, 0x5c, 0x91, 0x5f, 0x5f, 0xc1, + 0x61, 0x42, 0x45, 0x68, 0x31, 0xbc, 0xce, 0xb4, + 0x5c, 0xd3, 0x07, 0xdf, 0x4e, 0x65, 0x65, 0x9d, + 0x2e, 0x26, 0x28, 0xfa, 0xcd, 0x53, 0x77, 0x6a, + 0x77, 0xad, 0x96, 0x0b, 0x1f, 0xea, 0x03, 0xc1, + 0xdd, 0xca, 0xe8, 0xfe, 0xe8, 0x36, 0x01, 0x61, + 0x72, 0xbb, 0xed, 0xfd, 0x8d, 0xa3, 0xc2, 0x15, + 0x25, 0x4f, 0xa6, 0x1a, 0x73, 0xbd, 0xcd, 0x45, + 0xdb, 0x08, 0x74, 0x7b, 0xa8, 0x23, 0xf5, 0x74, + 0x3a, 0x18, 0x6d, 0x90, 0xe0, 0xee, 0xae, 0xfe, + 0xc8, 0xac, 0x00, 0x57, 0xa0, 0xe1, 0xfe, 0x10, + 0xd4, 0xf3, 0xa8, 0x00, 0x21, 0x3e, 0x2d, 0xf9, + 0x63, 0xb8, 0xe9, 0xa4, 0x2e, 0xf4, 0x6b, 0xd7, + 0x5c, 0xfd, 0x32, 0x6c, 0x98, 0x05, 0x38, 0x0d, + 0x29, 0xb5, 0x5a, 0x5b, 0xbb, 0xad, 0xfd, 0x46, + 0x9b, 0x6a, 0x97, 0x4c, 0x24, 0xcc, 0x7d, 0x13, + 0x25, 0xe8, 0x2c, 0xb9, 0x13, 0x54, 0xb2, 0x8a, + 0x28, 0xa0, 0x8a, 0x3a, 0x4d, 0x7e, 0xf4, 0x29, + 0xff, 0xfb, 0x4f, 0xd6, 0x3d, 0xf7, 0xca, 0x89, + 0x2a, 0x58, 0x9e, 0x42, 0x00, 0x84, 0x61, 0x58, + 0x7c, 0x94, 0xf6, 0x50, 0x48, 0x2f, 0x34, 0x88, + 0xec, 0x97, 0xef, 0x8b, 0x2f, 0x84, 0xca, 0x23, + 0xe1, 0xb7, 0x63, 0x99, 0xdd, 0x4a, 0x76, 0xdd, + 0x20, 0xc1, 0xc2, 0x56, 0x45, 0xbe, 0x75, 0x9a, + 0x40, 0x72, 0xc8, 0xfb, 0x7e, 0x40, 0x6f, 0x38, + 0xfd, 0x76, 0xa4, 0x78, 0xf5, 0xde, 0x5f, 0xb7, + 0x4a, 0xa9, 0xaf, 0xad, 0xa1, 0x8b, 0x25, 0x8f, + 0xea, 0xb3, 0xeb, 0x54, 0x39, 0x5a, 0x91, 0xfe, + 0x86, 0x18, 0xea, 0x8c, 0xd6, 0x66, 0xd5, 0x85, + 0x02, 0x2b, 0x00, 0x5d, 0x7e, 0x13, 0xa0, 0x1f, + 0x73, 0x46, 0x6d, 0x5e, 0xcd, 0xe0, 0x82, 0x02, + 0x28, 0x88, 0xbf, 0x17, 0xfd, 0x9b, 0x83, 0x2c, + 0xa2, 0xf7, 0xde, 0x51, 0x98, 0x3f, 0xe2, 0x80, + 0x66, 0x14, 0x17, 0xce, 0x8e, 0x30, 0x2d, 0xe2, + 0x24, 0x68, 0x4b, 0xe5, 0xd1, 0x09, 0xfb, 0x6e, +}; + +/* + * IV method encblkno1, blkno 1. + */ +static const uint8_t bf_cbc_128_encblkno1_vec1_ctxt[SECSIZE] = { + 0x87, 0xae, 0x01, 0x52, 0xe8, 0xe9, 0xd9, 0xba, + 0xa9, 0x18, 0x31, 0x2c, 0x1b, 0xab, 0x57, 0xad, + 0x45, 0x0e, 0x25, 0x5e, 0x0e, 0x04, 0xfa, 0xdd, + 0xf1, 0x59, 0xe6, 0xea, 0x78, 0x4b, 0x83, 0x07, + 0x8b, 0x46, 0x91, 0x09, 0x58, 0x5a, 0x11, 0x2e, + 0x54, 0x43, 0xa4, 0xc1, 0x04, 0x35, 0xd3, 0x3e, + 0xc9, 0xc8, 0xf5, 0xff, 0x69, 0x1e, 0x57, 0x85, + 0x6d, 0x91, 0x03, 0xeb, 0x8c, 0xa7, 0xe8, 0xcc, + 0x3f, 0xac, 0xf9, 0x14, 0x1e, 0x88, 0x50, 0xa5, + 0x38, 0x66, 0xa9, 0xf4, 0xf5, 0xc6, 0x30, 0x95, + 0xd6, 0x84, 0x0b, 0x81, 0xf9, 0x51, 0x05, 0x80, + 0x9a, 0x89, 0xbf, 0xd4, 0x7d, 0x6a, 0x26, 0x59, + 0x29, 0x44, 0xe7, 0x1d, 0x0e, 0xad, 0x8c, 0xa0, + 0x93, 0xe9, 0x4b, 0x4b, 0x51, 0x46, 0xa5, 0x07, + 0xe8, 0xcb, 0x59, 0xf4, 0x63, 0xb5, 0x36, 0xdb, + 0xbc, 0x54, 0x2d, 0xec, 0xf0, 0x90, 0x3a, 0xa5, + 0xed, 0xc8, 0x28, 0x0e, 0xd3, 0x79, 0xb8, 0x57, + 0xc6, 0x7f, 0x02, 0x22, 0x5e, 0x80, 0xe8, 0x7f, + 0xdf, 0xa0, 0x0f, 0xbc, 0x98, 0x79, 0x6f, 0xd2, + 0xb0, 0xb2, 0x4f, 0x9b, 0x1a, 0x21, 0x8f, 0x63, + 0xce, 0x54, 0x41, 0x64, 0xbf, 0xb9, 0xa7, 0x93, + 0xd6, 0x5b, 0x89, 0x86, 0xda, 0x90, 0x23, 0x2e, + 0x25, 0x35, 0x1a, 0x9a, 0xf5, 0x1e, 0x8f, 0xb4, + 0xe6, 0x66, 0x8e, 0x0e, 0x2d, 0x91, 0x06, 0x4b, + 0x3d, 0x4a, 0x97, 0xab, 0x9b, 0x92, 0x09, 0xaa, + 0x07, 0xbf, 0xc1, 0x7d, 0xe2, 0xbc, 0xd2, 0xf1, + 0x38, 0x8d, 0x02, 0x45, 0xc8, 0x13, 0x12, 0xda, + 0xaa, 0x53, 0xa2, 0x2c, 0x96, 0x69, 0x64, 0xce, + 0x86, 0xe4, 0x84, 0x56, 0xd0, 0xe5, 0x81, 0x99, + 0x27, 0xad, 0x86, 0x47, 0x5f, 0xaf, 0xa2, 0xa2, + 0x90, 0x7f, 0xe7, 0x86, 0xec, 0x7f, 0xf4, 0xa3, + 0xcd, 0x4f, 0x60, 0xcc, 0x1e, 0x35, 0x44, 0xe8, + 0xe9, 0x06, 0xaf, 0x5e, 0x53, 0x3d, 0x30, 0x91, + 0xfe, 0x44, 0x59, 0x66, 0x82, 0xc2, 0xea, 0x9f, + 0xc8, 0x3b, 0xe2, 0xe5, 0x58, 0xf7, 0x34, 0xd5, + 0x9e, 0xfc, 0x20, 0x84, 0x34, 0xaa, 0x4f, 0xe1, + 0xd4, 0x95, 0x76, 0x11, 0x59, 0x90, 0x90, 0xfd, + 0x4d, 0xf9, 0xb8, 0x41, 0xe1, 0xdb, 0x36, 0x05, + 0xe3, 0x0f, 0xa4, 0x4f, 0x0c, 0x61, 0x70, 0xa5, + 0x1b, 0xbf, 0xab, 0x65, 0x67, 0x75, 0x5c, 0x7d, + 0x46, 0x3b, 0x29, 0xd0, 0x3d, 0x06, 0x40, 0x25, + 0x47, 0x3e, 0x8d, 0x62, 0xf8, 0xd8, 0x08, 0xc1, + 0x03, 0x04, 0x4b, 0x5a, 0x40, 0x65, 0x84, 0x52, + 0x34, 0xa2, 0x4a, 0xcc, 0x3a, 0x9c, 0x1e, 0xbf, + 0x2d, 0xed, 0x08, 0x8b, 0xc3, 0x8f, 0x48, 0xba, + 0x06, 0x03, 0xea, 0x5b, 0xba, 0x6a, 0xac, 0x23, + 0x5a, 0x5e, 0x31, 0x08, 0x29, 0x69, 0x64, 0x44, + 0x1c, 0x31, 0xae, 0xb1, 0x86, 0x7b, 0x26, 0x89, + 0xa6, 0xbe, 0xef, 0x69, 0x81, 0xf7, 0x77, 0xd5, + 0x8e, 0x78, 0xa5, 0x11, 0x51, 0xca, 0xec, 0xd0, + 0x86, 0xa5, 0x33, 0xf3, 0x65, 0x5d, 0x04, 0xc5, + 0xd2, 0x17, 0x2a, 0xfe, 0x4a, 0x58, 0x0f, 0x98, + 0x61, 0xad, 0xc3, 0xb8, 0x5b, 0x45, 0xcc, 0x28, + 0x3d, 0x4d, 0x00, 0xf5, 0x4a, 0xe2, 0xbc, 0x6c, + 0x1b, 0x80, 0x7a, 0x2b, 0x40, 0xb8, 0x34, 0x0e, + 0x44, 0x53, 0x16, 0xda, 0x7c, 0x46, 0x8b, 0x42, + 0x5e, 0xa8, 0xe1, 0xb8, 0xf8, 0xcf, 0xff, 0x48, + 0xcf, 0x2c, 0x4c, 0x98, 0xdb, 0xe5, 0x55, 0xfe, + 0x45, 0xfa, 0xf8, 0xde, 0x72, 0xf9, 0x84, 0x3c, + 0xc0, 0x0c, 0x1f, 0x86, 0x97, 0x86, 0xb8, 0xfe, + 0x7d, 0xff, 0xa3, 0xaf, 0x68, 0x00, 0x66, 0x90, + 0xac, 0xb5, 0xd8, 0xde, 0x35, 0x01, 0xf7, 0xab, + 0xab, 0xe3, 0xe9, 0x85, 0x4c, 0x6f, 0xe6, 0xbc, + 0xce, 0x67, 0x4a, 0xbd, 0xad, 0x7b, 0xec, 0xa1, +}; + +/* + * IV method encblkno1, blkno 2. + */ +static const uint8_t bf_cbc_128_encblkno1_vec2_ctxt[SECSIZE] = { + 0x17, 0xdd, 0x0f, 0x4b, 0x28, 0x33, 0x03, 0x89, + 0x21, 0x7b, 0x67, 0x15, 0x15, 0x65, 0x08, 0x4f, + 0x65, 0x18, 0xa6, 0x4b, 0x62, 0xdb, 0x1e, 0xc2, + 0xaa, 0x82, 0xb6, 0x1d, 0xf7, 0x12, 0x9e, 0x73, + 0xfe, 0xac, 0x2f, 0x1e, 0x2b, 0xea, 0x3a, 0x4f, + 0xc3, 0x0a, 0x59, 0x80, 0x0d, 0x3d, 0xbc, 0x62, + 0x8d, 0x70, 0xef, 0x1b, 0xfb, 0xdc, 0x4e, 0xc4, + 0x97, 0xf4, 0x77, 0xb7, 0x25, 0x94, 0x13, 0x48, + 0xf2, 0x3d, 0x4c, 0xa7, 0xb8, 0x8c, 0xf5, 0x26, + 0xa4, 0x35, 0xeb, 0xa0, 0xe7, 0x68, 0xb0, 0x69, + 0xf4, 0xf6, 0x13, 0x3a, 0x57, 0xa3, 0xd2, 0x26, + 0xe6, 0x70, 0xd8, 0xd4, 0x05, 0xb5, 0x01, 0xda, + 0xc7, 0x4a, 0x79, 0x1a, 0x6d, 0xb6, 0xf6, 0xb5, + 0x7d, 0x9a, 0x5c, 0xf1, 0x6a, 0xf8, 0xd1, 0x0a, + 0xbc, 0xe7, 0xea, 0xb4, 0x99, 0x72, 0x19, 0x97, + 0x41, 0x4f, 0x14, 0x5f, 0xa3, 0xb3, 0x9b, 0x36, + 0x00, 0x08, 0x88, 0x8c, 0xce, 0x7f, 0x3a, 0x9b, + 0xb0, 0x24, 0x17, 0x95, 0xc4, 0x59, 0x30, 0x5d, + 0xc6, 0x92, 0x19, 0x12, 0x99, 0xb0, 0x08, 0xa6, + 0x04, 0xdb, 0xc6, 0xd5, 0x61, 0xe4, 0xe1, 0x68, + 0xa8, 0xd7, 0x07, 0xfe, 0x2f, 0x47, 0xea, 0x14, + 0xe5, 0xf7, 0x61, 0x9b, 0xbb, 0x98, 0xcb, 0x3b, + 0x8c, 0x41, 0xd1, 0x55, 0x59, 0xb2, 0x41, 0x61, + 0x8e, 0x60, 0x17, 0xcd, 0xe8, 0xf7, 0x1d, 0xbd, + 0x28, 0x5d, 0x1e, 0x15, 0x28, 0x80, 0x8c, 0x29, + 0x34, 0x96, 0x31, 0xda, 0xe1, 0x19, 0x88, 0xd5, + 0xe0, 0xc8, 0xb4, 0xaa, 0x04, 0x21, 0xf5, 0xef, + 0xfa, 0x0e, 0xc9, 0xa5, 0x88, 0x77, 0x49, 0xf4, + 0x02, 0x22, 0x0b, 0x8b, 0x5e, 0xe1, 0xab, 0xd4, + 0xb1, 0xb6, 0x48, 0x54, 0x96, 0x08, 0xaf, 0xa1, + 0x0b, 0xc0, 0xfe, 0x2a, 0x12, 0x36, 0x56, 0x85, + 0x6a, 0xf7, 0x3d, 0x82, 0xe6, 0xda, 0x5d, 0xfe, + 0x4f, 0x4f, 0xc9, 0x43, 0xdc, 0x0f, 0x53, 0x05, + 0x09, 0xd4, 0x9c, 0x2e, 0x6e, 0xf3, 0x52, 0x6a, + 0x10, 0xc6, 0x48, 0xb1, 0x54, 0x70, 0xab, 0x7c, + 0x31, 0xf6, 0x47, 0xef, 0x64, 0x5f, 0xff, 0x45, + 0x8c, 0x3f, 0x87, 0x3a, 0x2d, 0xa6, 0xaf, 0xb2, + 0x44, 0xdf, 0x80, 0x2e, 0x89, 0x4c, 0x94, 0x67, + 0xfc, 0x20, 0x98, 0xb4, 0xcf, 0x58, 0x1e, 0x33, + 0x55, 0x6a, 0x7c, 0x67, 0x5c, 0x28, 0x2f, 0x19, + 0x02, 0x14, 0x06, 0x93, 0x8c, 0x84, 0xae, 0x62, + 0x14, 0xf9, 0x87, 0xae, 0x85, 0xa3, 0x60, 0x26, + 0xfc, 0x8d, 0x04, 0x92, 0x27, 0xfe, 0x35, 0x7b, + 0x45, 0x9d, 0x4a, 0x86, 0x75, 0xa6, 0xb3, 0xa1, + 0x59, 0xe4, 0x4b, 0x1c, 0xd2, 0x71, 0x36, 0xfe, + 0x73, 0xed, 0x54, 0x0d, 0x9d, 0xde, 0x63, 0xb2, + 0xc0, 0x7c, 0xf2, 0xb3, 0x36, 0x62, 0x06, 0x1f, + 0xcd, 0x41, 0x92, 0x73, 0xbc, 0x11, 0x68, 0xc9, + 0x69, 0x20, 0xf9, 0xbb, 0x9a, 0xe9, 0x6c, 0x05, + 0xcf, 0x01, 0x57, 0xc4, 0x1d, 0x95, 0x5e, 0xe3, + 0xb7, 0x15, 0xde, 0xa7, 0xb5, 0x1a, 0x4e, 0x78, + 0x44, 0x5b, 0x9a, 0xee, 0x29, 0xe2, 0x22, 0x8b, + 0xe9, 0xe3, 0xe6, 0x70, 0x3e, 0xcb, 0x9f, 0x7f, + 0xc3, 0xd0, 0x2c, 0xdc, 0x55, 0xb4, 0x0d, 0x67, + 0xf5, 0xd8, 0xff, 0xbb, 0xb1, 0x02, 0xbf, 0xf6, + 0x33, 0x4e, 0x7a, 0x3a, 0x50, 0xb1, 0x01, 0x77, + 0x51, 0xef, 0xb5, 0x75, 0xb3, 0x66, 0xe8, 0xe6, + 0xd6, 0x53, 0x7d, 0x33, 0x51, 0x62, 0x5d, 0xf2, + 0x77, 0x02, 0x34, 0x42, 0xda, 0xee, 0xd9, 0xee, + 0x0b, 0x4d, 0x71, 0x5c, 0xc0, 0xec, 0xdd, 0xc0, + 0x34, 0x6f, 0xf4, 0x65, 0x32, 0xde, 0xc5, 0xb2, + 0x97, 0x60, 0x89, 0x4e, 0x3b, 0x0c, 0xf2, 0xa7, + 0x74, 0x61, 0xd7, 0xe4, 0xa6, 0x80, 0x78, 0x76, + 0xe5, 0x7d, 0xab, 0x96, 0x04, 0x00, 0x76, 0x22, +}; + +/* + * IV method encblkno1, blkno 3. + */ +static const uint8_t bf_cbc_128_encblkno1_vec3_ctxt[SECSIZE] = { + 0xdd, 0x8e, 0xce, 0x5b, 0xb8, 0x2a, 0xc8, 0x0e, + 0xd2, 0xbe, 0xcf, 0xa7, 0x2a, 0x5b, 0x0c, 0x1a, + 0xb2, 0x68, 0x5b, 0xe7, 0x53, 0xaf, 0xce, 0x56, + 0xfd, 0xbd, 0x73, 0x3c, 0x44, 0x02, 0x96, 0x57, + 0xaa, 0x47, 0x8d, 0xf1, 0x28, 0x59, 0xb6, 0xce, + 0xba, 0x1e, 0xc9, 0x78, 0x76, 0xdd, 0x43, 0x3a, + 0xbc, 0x43, 0x4c, 0x17, 0xd2, 0xba, 0xb1, 0xda, + 0xa8, 0xbf, 0x32, 0x25, 0xaa, 0xc0, 0xf7, 0xb6, + 0x72, 0x65, 0xe2, 0x67, 0xdb, 0xf0, 0xa8, 0x60, + 0xda, 0x9b, 0x70, 0xad, 0x8f, 0x1d, 0x34, 0x24, + 0x1a, 0xfd, 0x77, 0x2e, 0x1c, 0xb6, 0xc0, 0x6b, + 0xa0, 0x4b, 0x4a, 0xa0, 0xd5, 0x8b, 0xbb, 0xd4, + 0xcc, 0x7b, 0x4e, 0x4c, 0x71, 0x9a, 0x50, 0x12, + 0x36, 0xd4, 0xfd, 0x1f, 0xf1, 0xfc, 0x19, 0x31, + 0xec, 0x54, 0x24, 0xb4, 0x9f, 0xa9, 0xea, 0xd2, + 0x87, 0x11, 0x03, 0x29, 0xbb, 0x20, 0x20, 0x37, + 0xa0, 0xeb, 0x93, 0xa1, 0x60, 0x5f, 0x83, 0x9f, + 0x00, 0x09, 0xe4, 0x9c, 0x79, 0xcb, 0xfc, 0x4f, + 0x9e, 0xd2, 0x76, 0x9f, 0x56, 0x3b, 0x88, 0x1d, + 0x29, 0x8f, 0x36, 0x07, 0xf7, 0x7e, 0xf1, 0xa1, + 0xa4, 0x25, 0xfb, 0xa0, 0xbe, 0xc6, 0xa2, 0x76, + 0xd3, 0x59, 0x2a, 0x7f, 0xb7, 0x9b, 0xb8, 0x75, + 0xc7, 0xc1, 0xc0, 0xe9, 0x9b, 0x83, 0x16, 0x00, + 0xc8, 0x9c, 0x25, 0x2a, 0x8b, 0xd1, 0x8d, 0x16, + 0x9f, 0xd6, 0xd3, 0x03, 0x5b, 0xc7, 0x40, 0xac, + 0xb6, 0xf3, 0xbb, 0x22, 0xa3, 0x3e, 0x56, 0x55, + 0xdf, 0x06, 0x76, 0xe0, 0x7b, 0xd0, 0x52, 0x54, + 0x38, 0xb0, 0xaa, 0xab, 0x62, 0x31, 0xd1, 0x79, + 0x19, 0xec, 0x82, 0x36, 0x58, 0x31, 0xf9, 0x01, + 0xf9, 0x5e, 0xaf, 0x24, 0xb3, 0xc9, 0xb2, 0x30, + 0x3d, 0xbc, 0xf1, 0xbe, 0x17, 0xeb, 0xa0, 0x31, + 0x43, 0xed, 0xd7, 0x50, 0xcc, 0xc2, 0xe2, 0xaa, + 0x68, 0xc8, 0xf0, 0xd3, 0x89, 0xbd, 0xf5, 0x69, + 0x56, 0xe3, 0x88, 0x92, 0x32, 0x56, 0x85, 0x6f, + 0x25, 0x30, 0x28, 0x37, 0xd5, 0xe2, 0xa6, 0xf7, + 0x6e, 0xa9, 0x71, 0xda, 0x4a, 0x25, 0x94, 0x0b, + 0x84, 0x7f, 0x1f, 0x6b, 0x89, 0x2a, 0xf8, 0x30, + 0xcb, 0x60, 0x75, 0x21, 0xbd, 0xe2, 0x34, 0xf7, + 0x8f, 0x30, 0xd5, 0xd5, 0x1f, 0x17, 0x0d, 0x00, + 0x6c, 0x50, 0xde, 0x56, 0x15, 0x33, 0x1b, 0x83, + 0x68, 0x7b, 0x24, 0xe3, 0xa0, 0xda, 0xd5, 0x7a, + 0x3e, 0x93, 0x6d, 0xe0, 0x02, 0x79, 0x62, 0x5d, + 0x71, 0xe3, 0x7b, 0xa9, 0x0b, 0x7a, 0xcd, 0xb3, + 0xb2, 0x6f, 0x96, 0x19, 0x8f, 0xf8, 0x8b, 0x26, + 0x7a, 0x40, 0xc8, 0xae, 0xfe, 0x0d, 0x6f, 0x67, + 0xce, 0x5e, 0xa0, 0x04, 0x7e, 0x93, 0x1d, 0x17, + 0x1c, 0x32, 0x82, 0xf4, 0x54, 0xb9, 0x80, 0xdd, + 0x82, 0xae, 0xf5, 0xc5, 0x1e, 0x15, 0xab, 0xc2, + 0x5c, 0x60, 0xd2, 0x08, 0xc2, 0xa1, 0x1f, 0x89, + 0x0b, 0x59, 0x36, 0x07, 0xdc, 0x57, 0xd3, 0xa0, + 0x32, 0x42, 0xac, 0xa6, 0x90, 0x0b, 0xc0, 0xe4, + 0x91, 0x45, 0x85, 0x27, 0xb9, 0x48, 0x2a, 0x88, + 0x0a, 0xbf, 0xf6, 0x2d, 0xef, 0x4d, 0x1b, 0x64, + 0x49, 0x23, 0x47, 0x30, 0x29, 0x25, 0xb2, 0xc9, + 0xaf, 0xcd, 0xae, 0x56, 0x43, 0x28, 0xcf, 0x81, + 0x95, 0xa7, 0x3e, 0x51, 0x5b, 0x3b, 0xf7, 0x87, + 0x13, 0xc6, 0xee, 0x50, 0x2f, 0x78, 0xdd, 0xcf, + 0x63, 0xef, 0x15, 0xb9, 0x4f, 0x21, 0x27, 0x5e, + 0x94, 0x78, 0xad, 0xcd, 0x9b, 0x3d, 0xf2, 0xdb, + 0xed, 0xf2, 0xa2, 0x39, 0xca, 0xa3, 0xa8, 0x2e, + 0x68, 0xd5, 0xc3, 0xcf, 0x71, 0xec, 0x92, 0xdc, + 0xce, 0xe7, 0x7d, 0x2b, 0xf7, 0xbc, 0xe9, 0x2b, + 0x2e, 0xae, 0xaf, 0x0b, 0x92, 0x72, 0xac, 0x6e, + 0x49, 0xe1, 0xb3, 0x1f, 0xe5, 0x43, 0x2f, 0xa7, +}; + +const struct testvec bf_cbc_128_1_vectors[] = { + { + .blkno = 0, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_128_encblkno1_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_128_encblkno1_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_128_encblkno1_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_128_encblkno1_vec3_ctxt, + }, +}; + +/* + * IV method encblkno8, blkno 0. + */ +static const uint8_t bf_cbc_128_encblkno8_vec0_ctxt[SECSIZE] = { + 0xb8, 0x65, 0x67, 0x8e, 0xe4, 0xd8, 0xb4, 0x93, + 0xa5, 0xbb, 0x13, 0x92, 0x27, 0x4b, 0xdd, 0xeb, + 0x0d, 0xad, 0x80, 0x6a, 0x57, 0x37, 0xc0, 0x23, + 0x23, 0xbf, 0xed, 0x86, 0x0c, 0x18, 0x48, 0x19, + 0xcd, 0x84, 0x66, 0xa7, 0xd6, 0xa0, 0x44, 0xd3, + 0x05, 0x4e, 0xf4, 0xfe, 0x6a, 0x57, 0x69, 0x01, + 0xaa, 0x91, 0x9c, 0x6e, 0x4f, 0x79, 0xc9, 0x8f, + 0x4c, 0xdf, 0x5b, 0x9c, 0xc4, 0xf7, 0x63, 0x16, + 0x20, 0x09, 0x07, 0x3f, 0x5e, 0x31, 0xcc, 0x81, + 0x71, 0xe3, 0x7b, 0xb5, 0xea, 0x2c, 0xb5, 0x14, + 0x1e, 0xf9, 0x0d, 0xe0, 0x45, 0xbc, 0x9f, 0x92, + 0x6c, 0xc9, 0x0a, 0x85, 0x62, 0x42, 0xf1, 0x4b, + 0xac, 0xe2, 0xfa, 0xad, 0x97, 0x7a, 0x43, 0x3d, + 0xb6, 0x5f, 0xcb, 0xe7, 0x17, 0x23, 0x28, 0xde, + 0x4e, 0xf8, 0xa1, 0x3c, 0x22, 0x63, 0x49, 0x31, + 0xa7, 0xbe, 0xbf, 0xfe, 0xee, 0xd9, 0x1f, 0xa0, + 0x2a, 0x0e, 0xf2, 0x4f, 0x3e, 0xf8, 0xbb, 0xae, + 0x9e, 0x0d, 0x2c, 0xaa, 0x2a, 0x2c, 0xf0, 0x6c, + 0x37, 0x2a, 0x5d, 0x96, 0x70, 0x9c, 0x87, 0xcc, + 0x2b, 0xca, 0x95, 0x37, 0xf4, 0x4d, 0x78, 0xae, + 0x4f, 0xb5, 0xe6, 0xad, 0xb1, 0xc1, 0x31, 0xd3, + 0x2d, 0xa6, 0xaf, 0xc1, 0x8c, 0xe4, 0x72, 0x05, + 0xb0, 0xfc, 0xb0, 0xf7, 0xfe, 0xf9, 0x3e, 0xa3, + 0xb9, 0xea, 0xc8, 0x69, 0xe3, 0x4e, 0x6d, 0xd1, + 0x8b, 0x2b, 0xf9, 0x2f, 0xd9, 0x40, 0x69, 0xff, + 0x90, 0x98, 0x7a, 0x82, 0xe3, 0x0d, 0x4e, 0x19, + 0x2f, 0x77, 0xf9, 0xab, 0x36, 0xa9, 0x4e, 0xbc, + 0x25, 0x32, 0xbd, 0x44, 0xea, 0x5a, 0x18, 0x31, + 0x37, 0xcd, 0x6c, 0x98, 0xdd, 0x1d, 0xf9, 0xf7, + 0x8f, 0x0b, 0x79, 0xbc, 0xe6, 0xf5, 0xf1, 0xa3, + 0x13, 0xe9, 0x39, 0xaf, 0xa4, 0x8a, 0x74, 0xae, + 0x60, 0x30, 0x63, 0x6e, 0xee, 0x97, 0x83, 0xee, + 0xc0, 0xdd, 0xde, 0xad, 0x92, 0x83, 0xc9, 0x3c, + 0xd8, 0x58, 0x6c, 0xcb, 0xe4, 0x29, 0x04, 0x69, + 0x4f, 0x45, 0xc2, 0x59, 0x98, 0x20, 0x91, 0x6e, + 0x95, 0x82, 0xb3, 0x47, 0x2c, 0xef, 0xdb, 0x96, + 0x38, 0xba, 0x01, 0x89, 0x84, 0x96, 0x71, 0xf9, + 0x2b, 0x23, 0xe0, 0x89, 0xb8, 0xb9, 0x80, 0xbf, + 0x0c, 0xdc, 0xf0, 0x5c, 0xd6, 0x4f, 0x18, 0x19, + 0xfe, 0x23, 0x5a, 0x1e, 0x20, 0x9a, 0x05, 0xf2, + 0x62, 0xd4, 0x04, 0x92, 0x24, 0xfc, 0xc0, 0x48, + 0xf0, 0x00, 0xb4, 0xbe, 0x2e, 0xea, 0x25, 0x17, + 0x5d, 0xab, 0x73, 0x26, 0x79, 0x77, 0xc5, 0x96, + 0xd3, 0xbf, 0x38, 0xda, 0x0f, 0xe1, 0x26, 0x9a, + 0x38, 0xfc, 0x43, 0x82, 0xd1, 0x4d, 0xf2, 0xae, + 0x98, 0x1e, 0xb0, 0x0d, 0xec, 0x7b, 0x56, 0x66, + 0xcb, 0x30, 0x57, 0x4f, 0xe7, 0x03, 0xe3, 0xa6, + 0x4a, 0x4a, 0xf9, 0xa3, 0xbf, 0x44, 0xac, 0x1a, + 0xe7, 0x4b, 0xc1, 0x5b, 0x03, 0x25, 0x4e, 0xc6, + 0x1f, 0x96, 0x4d, 0xf7, 0xbe, 0xa7, 0x5d, 0x60, + 0x20, 0x62, 0x10, 0xd7, 0xab, 0x64, 0xce, 0x22, + 0x8b, 0x52, 0x76, 0xa1, 0xa1, 0x8b, 0x1e, 0xb2, + 0x18, 0x29, 0x8f, 0xc5, 0x24, 0x39, 0xd4, 0xf8, + 0x75, 0x1e, 0x30, 0x57, 0x12, 0x01, 0x04, 0x78, + 0x68, 0x97, 0xa8, 0x65, 0x8c, 0xac, 0xb4, 0x3b, + 0x37, 0x45, 0x41, 0xbc, 0x7d, 0x4b, 0x09, 0xd7, + 0x46, 0x40, 0x99, 0x59, 0xa1, 0xb5, 0x9e, 0x84, + 0x24, 0x6d, 0xfb, 0x74, 0x22, 0xac, 0x4e, 0x5f, + 0x11, 0xd3, 0xa7, 0x9f, 0xa5, 0xca, 0x38, 0x54, + 0xe2, 0x65, 0x52, 0x02, 0x69, 0xe9, 0xa8, 0xf1, + 0xd7, 0x9d, 0x9a, 0x17, 0x54, 0xa0, 0xda, 0xbb, + 0x37, 0xb4, 0x0c, 0xb6, 0x00, 0xad, 0x6f, 0x88, + 0x84, 0xa7, 0x69, 0xd7, 0x0b, 0xbe, 0xb4, 0xbe, + 0x96, 0xbc, 0xcd, 0x08, 0xf1, 0x28, 0xe0, 0x6f, +}; + +/* + * IV method encblkno8, blkno 1. + */ +static const uint8_t bf_cbc_128_encblkno8_vec1_ctxt[SECSIZE] = { + 0x7d, 0x95, 0x5a, 0x66, 0x23, 0x98, 0xa8, 0xbe, + 0x53, 0x63, 0x0d, 0x46, 0x4e, 0x38, 0x1b, 0x1d, + 0x36, 0xdd, 0x2a, 0x57, 0x3c, 0x17, 0x01, 0xba, + 0x4e, 0xf8, 0xaa, 0x22, 0x74, 0x05, 0xa2, 0x40, + 0xd0, 0x30, 0x61, 0x6c, 0x65, 0x5e, 0xfb, 0x21, + 0x63, 0xef, 0x62, 0x01, 0x74, 0x15, 0xf6, 0x87, + 0x92, 0xc1, 0x4e, 0x46, 0xdd, 0x76, 0xdb, 0x8b, + 0x20, 0x44, 0xc4, 0xfa, 0x7c, 0xd2, 0x07, 0x32, + 0x11, 0xeb, 0x5b, 0x38, 0x44, 0x32, 0xa1, 0xe7, + 0xcb, 0xa6, 0x1a, 0x12, 0xb9, 0x53, 0x13, 0x6f, + 0xc2, 0x0e, 0x6a, 0x77, 0x8b, 0x96, 0x14, 0x0a, + 0x23, 0x48, 0x65, 0xa5, 0xcd, 0x39, 0x38, 0x03, + 0xc8, 0x3a, 0x98, 0x69, 0x3d, 0x14, 0xae, 0xad, + 0x54, 0x57, 0xf6, 0x5a, 0xdd, 0x46, 0x4c, 0x3a, + 0x68, 0xa8, 0xb7, 0x57, 0xdd, 0x1e, 0x66, 0x0e, + 0xc2, 0x4c, 0x17, 0xba, 0xa4, 0x7e, 0x83, 0x45, + 0xc6, 0xf2, 0x34, 0x3b, 0x4e, 0xab, 0x67, 0x0c, + 0x73, 0xbf, 0x87, 0x7e, 0x93, 0x2b, 0x14, 0x33, + 0xd6, 0x24, 0x8d, 0xc7, 0x90, 0x11, 0xd2, 0x38, + 0xe6, 0xe0, 0x39, 0x1f, 0x00, 0x74, 0x40, 0xab, + 0xdc, 0xdd, 0x46, 0xe8, 0x85, 0x14, 0xb1, 0x78, + 0x34, 0x24, 0x04, 0x97, 0xde, 0xf9, 0x04, 0x69, + 0x0b, 0x15, 0x72, 0x37, 0xf4, 0x0d, 0xf4, 0x76, + 0x6f, 0xd8, 0x05, 0x75, 0x8f, 0x7e, 0x6b, 0xca, + 0x55, 0x20, 0x4a, 0x29, 0x16, 0xc1, 0x6e, 0x91, + 0x22, 0x01, 0x0d, 0x39, 0x5d, 0xb9, 0x09, 0xa4, + 0xe8, 0xc7, 0xff, 0x60, 0x39, 0xc6, 0xe4, 0x2a, + 0x1c, 0xf2, 0x3c, 0xf7, 0xf9, 0xd7, 0xde, 0x0b, + 0x0e, 0x30, 0xf1, 0x20, 0x7c, 0x93, 0x2f, 0x74, + 0x72, 0x40, 0x47, 0x2d, 0xeb, 0x8a, 0x5f, 0x69, + 0x60, 0xdf, 0xe9, 0x4d, 0x06, 0x24, 0x9c, 0x79, + 0xe7, 0x61, 0xd3, 0xa7, 0x57, 0x44, 0x49, 0x97, + 0x3a, 0xa3, 0x11, 0xc4, 0x70, 0xf4, 0x3d, 0xb5, + 0x4b, 0xb7, 0xae, 0x77, 0x36, 0xcf, 0x65, 0x3e, + 0xb6, 0x51, 0x83, 0xcb, 0x43, 0x5f, 0xd0, 0xfb, + 0x69, 0xc4, 0x1b, 0x77, 0x71, 0xcc, 0x72, 0xf4, + 0x5f, 0xc2, 0xda, 0xea, 0xa4, 0x33, 0xec, 0x8e, + 0x92, 0x22, 0x6a, 0x55, 0x34, 0x6a, 0x10, 0xb8, + 0x62, 0x66, 0xc1, 0x6f, 0x65, 0xdd, 0x9a, 0x40, + 0xa0, 0xbf, 0x88, 0xbb, 0x79, 0x1c, 0xa4, 0xaa, + 0xdf, 0xe8, 0xe7, 0x40, 0x88, 0xc6, 0x0f, 0xa2, + 0x2c, 0xee, 0xe7, 0x41, 0x32, 0x46, 0xa2, 0x46, + 0x85, 0xbf, 0x4c, 0xca, 0x4d, 0xd3, 0x9b, 0x49, + 0x43, 0x98, 0xae, 0xfc, 0x93, 0xa7, 0x94, 0x98, + 0x86, 0xa1, 0x0a, 0x85, 0x77, 0x67, 0xa6, 0x16, + 0x94, 0x76, 0xe5, 0x2f, 0x88, 0x5f, 0x24, 0x16, + 0xe5, 0x84, 0x4c, 0xd2, 0x58, 0x59, 0x82, 0x59, + 0x2c, 0xe2, 0x8d, 0xba, 0x08, 0x01, 0x67, 0x1f, + 0x2a, 0x9e, 0x4d, 0x53, 0x57, 0x2d, 0x6e, 0x35, + 0x38, 0xd5, 0x50, 0xa7, 0x0c, 0xe6, 0x77, 0x71, + 0xbe, 0x45, 0x2e, 0xf4, 0x7a, 0x3a, 0x51, 0x03, + 0x04, 0x2b, 0xd7, 0x42, 0x6c, 0x5b, 0x82, 0xba, + 0xb4, 0x09, 0xee, 0x9d, 0xea, 0x8f, 0xf0, 0xb3, + 0xb2, 0x9d, 0x0e, 0x09, 0x72, 0x8c, 0xd9, 0x1e, + 0x6d, 0x78, 0x57, 0x10, 0x1f, 0xeb, 0x4e, 0x53, + 0x57, 0x65, 0xe5, 0x43, 0xe8, 0xb4, 0xb6, 0xb8, + 0x25, 0x8a, 0xe2, 0xb3, 0x99, 0x95, 0x2c, 0xd0, + 0xc7, 0x89, 0xad, 0xdb, 0x72, 0xf0, 0x83, 0xe3, + 0x2f, 0x30, 0x33, 0xf4, 0x03, 0x14, 0x86, 0xa0, + 0xe0, 0x57, 0x15, 0x53, 0x26, 0xd0, 0x6d, 0x12, + 0x51, 0x96, 0x9b, 0x00, 0x8e, 0x41, 0xea, 0x05, + 0x75, 0x5d, 0xb3, 0x8d, 0x44, 0x7f, 0x41, 0x7f, + 0xd1, 0xed, 0x7c, 0xf7, 0xac, 0x6b, 0x21, 0xc7, + 0x0c, 0x49, 0xa1, 0x2e, 0x57, 0xa1, 0x21, 0xe2, +}; + +/* + * IV method encblkno8, blkno 2. + */ +static const uint8_t bf_cbc_128_encblkno8_vec2_ctxt[SECSIZE] = { + 0x28, 0x0c, 0x49, 0x08, 0x84, 0xcb, 0xba, 0x4a, + 0xa5, 0xb6, 0x12, 0x4c, 0x14, 0x11, 0x1f, 0x88, + 0x57, 0x78, 0x1e, 0x51, 0x7c, 0x9d, 0xba, 0x31, + 0x80, 0x14, 0xeb, 0x4a, 0x98, 0x8a, 0xb5, 0x4d, + 0xc5, 0xbd, 0xd2, 0x48, 0x1e, 0x19, 0x43, 0x54, + 0x48, 0x1d, 0x24, 0x76, 0x7d, 0xd8, 0xcc, 0xe9, + 0xd9, 0x7b, 0xa9, 0xdf, 0xe3, 0x65, 0x85, 0x10, + 0xb8, 0x11, 0xce, 0xa3, 0x07, 0x4d, 0x87, 0x3f, + 0x95, 0xfb, 0xa5, 0x06, 0xa4, 0x37, 0xb0, 0x89, + 0x03, 0xa9, 0xef, 0x62, 0x98, 0xd3, 0x85, 0xe8, + 0xb3, 0x21, 0xab, 0xe9, 0xdc, 0x03, 0x2a, 0x20, + 0xf7, 0xb1, 0xa4, 0x7a, 0xd5, 0xdc, 0x61, 0x2e, + 0x15, 0x81, 0x3e, 0xcf, 0x8d, 0x8d, 0x54, 0x19, + 0x70, 0xde, 0xa9, 0x57, 0x93, 0x87, 0xc7, 0x16, + 0x06, 0x25, 0xf3, 0x93, 0x8f, 0x73, 0x92, 0x29, + 0x1e, 0xcd, 0x5a, 0x9d, 0x8f, 0x8d, 0x44, 0x15, + 0x8d, 0x92, 0x44, 0x95, 0x7a, 0x5e, 0x1b, 0xfd, + 0x31, 0xa5, 0x8c, 0x22, 0x89, 0xbb, 0x91, 0x15, + 0xad, 0x0a, 0x73, 0x94, 0x65, 0xae, 0xca, 0xfc, + 0x7e, 0xae, 0x85, 0x45, 0xe7, 0xd7, 0x8f, 0x89, + 0x8e, 0x44, 0x62, 0x7a, 0xe0, 0xee, 0x78, 0xbd, + 0x88, 0x62, 0x8e, 0xb8, 0x35, 0x7a, 0xa9, 0x12, + 0x56, 0x2d, 0xe4, 0xbb, 0x2d, 0xc8, 0x98, 0x0e, + 0x35, 0x9e, 0xea, 0x14, 0x43, 0x80, 0xde, 0x9e, + 0x2e, 0xf8, 0xf9, 0xcd, 0x61, 0xa6, 0x22, 0xc8, + 0x77, 0xfc, 0x32, 0x71, 0x4b, 0xcb, 0x00, 0x9b, + 0x9f, 0x85, 0x02, 0x92, 0xfa, 0x84, 0xd8, 0xd8, + 0x09, 0xa4, 0x08, 0xc1, 0x96, 0xd3, 0x9a, 0x27, + 0xa3, 0x82, 0x05, 0xd0, 0x78, 0x18, 0x0a, 0x7d, + 0xb6, 0x95, 0xc0, 0x27, 0x3e, 0x76, 0x77, 0xf3, + 0xd9, 0x62, 0x8e, 0x77, 0xa0, 0x1f, 0x9e, 0x41, + 0xdb, 0x24, 0xaa, 0xdd, 0x8f, 0x94, 0x7b, 0x1f, + 0xff, 0xaa, 0xfd, 0xe2, 0x19, 0xc2, 0x71, 0x80, + 0x0a, 0xda, 0xc5, 0x98, 0x57, 0xde, 0x4e, 0xfb, + 0x38, 0xe6, 0x9b, 0xe5, 0xa6, 0x1f, 0x7d, 0x2c, + 0x41, 0x5f, 0x4d, 0x13, 0xb8, 0x0c, 0xac, 0x9a, + 0x7d, 0xc0, 0x7c, 0x44, 0x64, 0x1e, 0xbc, 0x7d, + 0x16, 0xaa, 0x45, 0xda, 0x62, 0x4e, 0x64, 0x69, + 0xd6, 0x71, 0xd9, 0x64, 0x2a, 0x5d, 0x20, 0x34, + 0xb0, 0xcb, 0x9d, 0xd3, 0x69, 0xd6, 0x60, 0xad, + 0x78, 0x72, 0xb8, 0x36, 0x17, 0xe7, 0xaf, 0x0a, + 0x11, 0x84, 0x43, 0x32, 0x38, 0x43, 0xe5, 0xc5, + 0x1b, 0xf4, 0x48, 0xb6, 0x0e, 0x72, 0x48, 0x2f, + 0x9b, 0xe3, 0xce, 0x27, 0xcd, 0x66, 0x28, 0x5c, + 0x2a, 0xd7, 0x28, 0x52, 0x6e, 0x86, 0x03, 0x60, + 0x7b, 0xbd, 0xbd, 0x53, 0xfb, 0x7d, 0xa1, 0xba, + 0x6a, 0x46, 0x0c, 0xf3, 0x1a, 0xbf, 0xa7, 0xa2, + 0x46, 0x87, 0x40, 0xaa, 0x7d, 0x76, 0x36, 0x85, + 0xa5, 0xbf, 0x0b, 0xd4, 0x56, 0x4c, 0x37, 0xe3, + 0x60, 0x93, 0xdc, 0x3b, 0xca, 0x34, 0x78, 0xcf, + 0xdb, 0x0c, 0x9d, 0x5c, 0x52, 0xb2, 0xd5, 0x7b, + 0xbb, 0x4e, 0xe1, 0xa9, 0x2a, 0xc6, 0x42, 0xf5, + 0x21, 0x9c, 0x15, 0xae, 0xb9, 0x08, 0x3a, 0xc4, + 0x50, 0x7e, 0x0e, 0xb6, 0xc3, 0xfe, 0xf4, 0xd9, + 0x1a, 0x97, 0x30, 0x9f, 0x51, 0x2c, 0xac, 0xd2, + 0x13, 0x93, 0x62, 0x56, 0xcb, 0x34, 0xf3, 0xca, + 0x26, 0xc6, 0x32, 0xbe, 0xf6, 0xd5, 0x1e, 0x5b, + 0x3a, 0x5c, 0x31, 0x08, 0xa1, 0x47, 0x6b, 0x75, + 0x95, 0x8e, 0x3d, 0xbf, 0x2e, 0x81, 0x02, 0x0d, + 0x17, 0x66, 0x6f, 0x04, 0xe0, 0x1e, 0x03, 0x27, + 0xd3, 0xcf, 0x45, 0xc6, 0x08, 0xdb, 0xdf, 0x83, + 0xd5, 0xc2, 0x7f, 0xe8, 0x5f, 0x4a, 0x36, 0x0a, + 0x6d, 0x3c, 0x91, 0x8e, 0x52, 0xf3, 0xdd, 0x62, + 0xff, 0x78, 0x87, 0xd9, 0x4c, 0xad, 0x5c, 0x9f, +}; + +/* + * IV method encblkno8, blkno 3. + */ +static const uint8_t bf_cbc_128_encblkno8_vec3_ctxt[SECSIZE] = { + 0xa3, 0x9a, 0x21, 0xbd, 0x1c, 0x97, 0x4f, 0xe2, + 0x7d, 0x63, 0xfe, 0x52, 0x07, 0xac, 0x81, 0x75, + 0x15, 0x04, 0x8c, 0xc7, 0x7c, 0x11, 0x8d, 0x53, + 0x17, 0x87, 0xe8, 0x5d, 0xb1, 0xe8, 0xcb, 0x43, + 0xe2, 0x4b, 0xce, 0x9b, 0xf7, 0x51, 0x0a, 0xee, + 0x0a, 0x49, 0xae, 0x9a, 0xbd, 0x33, 0x3f, 0x0b, + 0xd4, 0xe8, 0x57, 0x77, 0xb1, 0xe1, 0xa5, 0x22, + 0x83, 0xbf, 0x7c, 0x63, 0x6c, 0x3b, 0x25, 0xde, + 0x2c, 0x6a, 0x28, 0x66, 0x0e, 0xc4, 0x8d, 0x66, + 0x66, 0xb6, 0xc6, 0xb5, 0x38, 0x40, 0x84, 0x81, + 0xec, 0x03, 0xdb, 0xbf, 0xe1, 0x8f, 0xf4, 0xb3, + 0xc4, 0x50, 0x24, 0xa2, 0x48, 0x66, 0x73, 0xed, + 0x4b, 0x00, 0x12, 0xd5, 0x15, 0x5f, 0xfb, 0xd9, + 0x6c, 0x76, 0x3b, 0xa2, 0x68, 0x41, 0xc1, 0x96, + 0x50, 0xff, 0x8a, 0x83, 0xac, 0x02, 0x42, 0xcb, + 0xed, 0x93, 0xbf, 0xd9, 0x51, 0x46, 0x50, 0xd1, + 0xeb, 0x02, 0x61, 0x64, 0xa7, 0x0e, 0x95, 0xc2, + 0x95, 0x5a, 0x93, 0xd9, 0x77, 0x17, 0xa4, 0xc7, + 0x51, 0x42, 0xa3, 0xd4, 0x32, 0x4e, 0x4f, 0xe1, + 0xaa, 0x6d, 0xab, 0x08, 0xd9, 0xe9, 0xfe, 0x72, + 0xf3, 0x2c, 0xfb, 0x43, 0xdf, 0x88, 0x44, 0x94, + 0x0b, 0x5c, 0x85, 0x54, 0xe3, 0x13, 0xe2, 0x10, + 0x64, 0xa7, 0xcf, 0xe3, 0x2a, 0x3e, 0xfe, 0xd1, + 0x67, 0xcd, 0xd1, 0x66, 0x06, 0x26, 0x2f, 0x6f, + 0x6f, 0x44, 0xe7, 0xf4, 0xac, 0xe4, 0x58, 0x2f, + 0x61, 0xad, 0x64, 0xc6, 0x0c, 0xf0, 0x9a, 0x3b, + 0x85, 0x1f, 0x3c, 0xea, 0x8e, 0x84, 0xbb, 0x1a, + 0x51, 0x19, 0x3c, 0x6f, 0x5b, 0xf5, 0x6c, 0xb1, + 0x8c, 0x91, 0x25, 0x89, 0x3a, 0x45, 0xb5, 0x35, + 0x13, 0x74, 0xec, 0x68, 0x44, 0xb8, 0xfd, 0xd6, + 0x20, 0x78, 0x7b, 0xe3, 0xe0, 0x82, 0xb7, 0x4a, + 0x38, 0xb6, 0xe4, 0x1b, 0xbf, 0xd9, 0xd3, 0xe9, + 0xbf, 0xd7, 0xdc, 0x8e, 0x90, 0x7d, 0xcb, 0x39, + 0xc4, 0x6c, 0xa4, 0x70, 0x15, 0xf7, 0xa2, 0x16, + 0x04, 0x9b, 0xc0, 0x85, 0x04, 0x1e, 0x69, 0x73, + 0xf3, 0xbd, 0x64, 0x95, 0xfb, 0x21, 0xcb, 0xca, + 0x72, 0xd4, 0x33, 0xe5, 0x11, 0xc3, 0x46, 0xa6, + 0xd2, 0x4c, 0x8a, 0xbb, 0xba, 0x45, 0xcc, 0x45, + 0xdb, 0x8a, 0xec, 0xef, 0x8c, 0x04, 0xcc, 0xeb, + 0x42, 0xad, 0xc3, 0x87, 0xe2, 0x59, 0x3b, 0xed, + 0x2a, 0x11, 0x74, 0xc1, 0x28, 0x8a, 0xc2, 0x17, + 0xca, 0x5a, 0x88, 0xcc, 0x17, 0x2c, 0x03, 0xf6, + 0xcd, 0xd6, 0x92, 0xbd, 0x68, 0x26, 0x41, 0x40, + 0x15, 0x3e, 0x54, 0xf5, 0xb7, 0x4a, 0x82, 0x68, + 0xca, 0x27, 0xed, 0xed, 0x25, 0xd6, 0x0d, 0x0f, + 0x86, 0x62, 0xf0, 0x86, 0x5b, 0xed, 0x94, 0x0b, + 0xd0, 0xec, 0xc7, 0xfd, 0x9c, 0x8a, 0xdf, 0x4f, + 0x65, 0x7e, 0x63, 0x40, 0xeb, 0xe4, 0x79, 0xcb, + 0x67, 0xc6, 0x0e, 0x45, 0xf9, 0xb1, 0x48, 0x27, + 0x16, 0xfc, 0x99, 0x76, 0xac, 0xd0, 0xbc, 0xe6, + 0x9b, 0x29, 0x2d, 0xa5, 0x6c, 0x88, 0x45, 0x7a, + 0x01, 0xf3, 0xe3, 0x15, 0xfb, 0x29, 0xd4, 0x3b, + 0x9a, 0xa8, 0xc6, 0x98, 0x92, 0x19, 0x16, 0xba, + 0xdc, 0x41, 0x70, 0x40, 0x51, 0xfb, 0x7f, 0xb5, + 0xe4, 0x3f, 0x3f, 0x73, 0xb0, 0xb3, 0xd7, 0x6d, + 0x3e, 0x4d, 0x6b, 0x9e, 0x42, 0x8e, 0xbb, 0xd7, + 0xb5, 0x26, 0xa9, 0x19, 0xf5, 0x68, 0xf3, 0x8d, + 0x35, 0x91, 0x06, 0x48, 0xfa, 0x0e, 0x7d, 0xe2, + 0xd3, 0x71, 0x75, 0x44, 0xbd, 0xe6, 0xe6, 0xd6, + 0x36, 0x43, 0x64, 0x3a, 0xd5, 0x97, 0xfa, 0xc0, + 0x10, 0xf7, 0x6c, 0x26, 0xf1, 0xb4, 0xbc, 0xf5, + 0xf6, 0xa3, 0xec, 0x0a, 0xb5, 0x34, 0x55, 0x1a, + 0x67, 0xcb, 0xec, 0x2c, 0x2e, 0x2e, 0x74, 0xed, + 0xfc, 0x85, 0x53, 0x01, 0x87, 0xa7, 0xa0, 0x1f, +}; + +const struct testvec bf_cbc_128_8_vectors[] = { + { + .blkno = 0, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_128_encblkno8_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_128_encblkno8_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_128_encblkno8_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_128_encblkno8_vec3_ctxt, + }, +}; + +/* + * IV method encblkno1, blkno 0. + */ +static const uint8_t bf_cbc_256_encblkno1_vec0_ctxt[SECSIZE] = { + 0x14, 0xec, 0xa9, 0xa0, 0x51, 0x9f, 0x5e, 0xb5, + 0x81, 0x6f, 0xa2, 0xbf, 0x5e, 0xf7, 0x91, 0xad, + 0xc5, 0x1a, 0x7e, 0xe6, 0x7a, 0x82, 0x4a, 0xba, + 0x54, 0x60, 0xcb, 0xc3, 0x2f, 0x69, 0x5c, 0xd9, + 0x1e, 0x58, 0xa1, 0x88, 0xa1, 0xe5, 0xa8, 0x52, + 0xdf, 0xf3, 0x8d, 0x5e, 0x2f, 0x81, 0x54, 0xab, + 0x67, 0xb5, 0x05, 0x63, 0x20, 0x10, 0x98, 0xf5, + 0xa5, 0xc3, 0x9e, 0x6d, 0x80, 0x4d, 0xb6, 0x82, + 0x80, 0x5e, 0xb3, 0xc5, 0xd8, 0x77, 0x94, 0xa0, + 0xb8, 0x67, 0xb8, 0x2d, 0x9b, 0x11, 0x3c, 0x24, + 0xbd, 0xb7, 0x0b, 0x1d, 0xeb, 0x1d, 0x6c, 0xab, + 0x3f, 0x8c, 0x91, 0xa0, 0x3a, 0xa6, 0x0c, 0x5a, + 0x88, 0xa0, 0xb5, 0xea, 0x49, 0x58, 0xfb, 0x37, + 0x7c, 0x94, 0xc4, 0x22, 0x35, 0x84, 0xda, 0xd1, + 0x1b, 0x4a, 0x42, 0xa1, 0xd4, 0x90, 0xcd, 0xfb, + 0x77, 0x29, 0xd2, 0xe3, 0x89, 0xec, 0x9e, 0x6a, + 0x4b, 0xbc, 0xc0, 0xfa, 0xb8, 0xdd, 0x5c, 0x2b, + 0xc5, 0x49, 0xb1, 0x6d, 0x6f, 0x2c, 0xb5, 0x50, + 0xd1, 0xd4, 0x9b, 0x15, 0x1c, 0xd7, 0x44, 0xf3, + 0x2e, 0x1f, 0x46, 0xee, 0x38, 0x40, 0xaa, 0x73, + 0xca, 0xf2, 0xc3, 0x83, 0xe2, 0xff, 0xd6, 0xc7, + 0x20, 0xea, 0x70, 0x95, 0x48, 0x58, 0x29, 0x6e, + 0xac, 0x10, 0x75, 0x69, 0x1d, 0xb2, 0x08, 0x3e, + 0x68, 0x43, 0xff, 0x69, 0x1e, 0x88, 0x0a, 0x34, + 0x40, 0xae, 0xb9, 0xf4, 0xb9, 0x3f, 0xa5, 0xd2, + 0xfb, 0xa0, 0xfd, 0x10, 0xa5, 0xbb, 0xd7, 0x22, + 0x8c, 0xd1, 0xf5, 0xc4, 0x11, 0xc6, 0x1e, 0xb5, + 0xfc, 0x90, 0x84, 0xa2, 0x49, 0x38, 0x64, 0x92, + 0x6e, 0xf2, 0xaa, 0xed, 0xe8, 0x9d, 0xac, 0x86, + 0xb7, 0xb3, 0xd9, 0x98, 0x11, 0x8f, 0x51, 0x33, + 0x84, 0x06, 0x40, 0x26, 0x3f, 0xe1, 0xb3, 0x4a, + 0x76, 0x53, 0x68, 0x8b, 0xfe, 0x6f, 0xcd, 0x66, + 0x92, 0x24, 0x42, 0xf4, 0x11, 0x02, 0x01, 0x00, + 0xaa, 0x15, 0x35, 0x42, 0xab, 0x6f, 0x2b, 0x3b, + 0x9a, 0x23, 0x73, 0x18, 0xa8, 0x9b, 0x43, 0x4b, + 0xfb, 0xef, 0x07, 0x75, 0xd7, 0xd6, 0x08, 0x94, + 0xe3, 0x2d, 0xd9, 0xd4, 0x8e, 0x6b, 0x7c, 0xe0, + 0xae, 0xef, 0xcb, 0x5c, 0x46, 0x39, 0x64, 0x34, + 0x48, 0x77, 0x2c, 0x87, 0x68, 0x57, 0xef, 0xba, + 0xd3, 0x3b, 0xb8, 0x68, 0xc5, 0x65, 0x73, 0x44, + 0x0b, 0xef, 0xc7, 0x5e, 0xe6, 0xa2, 0xba, 0x24, + 0x8c, 0x67, 0xa0, 0xf4, 0xef, 0x18, 0x8c, 0x72, + 0x5b, 0x81, 0x8c, 0x81, 0x4f, 0x9a, 0xed, 0x46, + 0x5d, 0x05, 0x9a, 0xdc, 0x01, 0xbe, 0xe8, 0x3f, + 0xb7, 0x5c, 0x8b, 0x2f, 0x92, 0x2c, 0x93, 0x54, + 0x68, 0xfa, 0xd4, 0x27, 0x81, 0xab, 0xa9, 0xfd, + 0x20, 0x21, 0x1b, 0x3a, 0x6e, 0x6b, 0x02, 0x57, + 0x6e, 0xd6, 0x7b, 0x7e, 0x5d, 0x84, 0x47, 0x69, + 0x86, 0x7b, 0x8f, 0x8b, 0xff, 0xb5, 0xcd, 0xc1, + 0x03, 0x18, 0x23, 0x7f, 0x23, 0x2e, 0x3a, 0x48, + 0xe2, 0xf6, 0xb1, 0x78, 0x13, 0x81, 0xbb, 0x80, + 0x91, 0x89, 0x54, 0x7d, 0x1f, 0x1a, 0xd5, 0x35, + 0xad, 0x56, 0x6a, 0x0f, 0xeb, 0x4d, 0x00, 0xdf, + 0xe0, 0xf3, 0x7c, 0xd3, 0x2c, 0x5a, 0x48, 0x39, + 0xa1, 0xc1, 0xfa, 0x34, 0x5f, 0xf9, 0x0b, 0xcd, + 0x1f, 0x21, 0xc6, 0x46, 0xb3, 0xd8, 0x45, 0xc5, + 0x37, 0xf7, 0xd0, 0xda, 0x27, 0x0f, 0xec, 0xec, + 0x05, 0x81, 0x6f, 0x97, 0xca, 0x6d, 0xfa, 0x71, + 0xc9, 0x59, 0x84, 0xc3, 0x0d, 0x55, 0x12, 0xbf, + 0xe1, 0xd2, 0x7c, 0x51, 0x65, 0x8c, 0xc3, 0x8a, + 0x73, 0x2f, 0x1c, 0xd8, 0x13, 0x4a, 0xd1, 0x78, + 0xb2, 0xc8, 0x19, 0x09, 0xce, 0x7b, 0xb6, 0x77, + 0xcc, 0xc3, 0xe6, 0xee, 0x3a, 0x82, 0xf9, 0xc6, + 0x5a, 0x36, 0x46, 0xc0, 0x25, 0xee, 0xaf, 0x78, +}; + +/* + * IV method encblkno1, blkno 1. + */ +static const uint8_t bf_cbc_256_encblkno1_vec1_ctxt[SECSIZE] = { + 0x0b, 0xb6, 0x26, 0x92, 0x1d, 0x74, 0xc2, 0x10, + 0xb5, 0x99, 0x5f, 0x62, 0x7f, 0x3b, 0x49, 0x10, + 0xc1, 0x20, 0x9f, 0x38, 0x25, 0x0f, 0x59, 0xde, + 0xe4, 0xc8, 0xb5, 0x27, 0xb1, 0xec, 0x96, 0x40, + 0xe8, 0x05, 0x15, 0x40, 0x96, 0xe0, 0xff, 0xaf, + 0x53, 0x73, 0xa1, 0xa6, 0x73, 0x03, 0xcf, 0x1f, + 0x87, 0x48, 0x7d, 0x81, 0x0e, 0x35, 0x23, 0x7b, + 0xde, 0x12, 0xd8, 0xcd, 0x0a, 0xcb, 0x03, 0xc5, + 0x07, 0xf7, 0x7a, 0x04, 0xf3, 0xda, 0x7d, 0x3b, + 0x73, 0xc6, 0x31, 0xbc, 0x24, 0xde, 0x23, 0x05, + 0x3a, 0xdc, 0xe2, 0x96, 0x85, 0x06, 0xeb, 0x89, + 0xb0, 0x49, 0x3c, 0x79, 0x8e, 0xcf, 0x49, 0x0e, + 0x34, 0x04, 0xa5, 0xcf, 0x45, 0x56, 0xb6, 0xc2, + 0xf1, 0xf1, 0xab, 0x7c, 0x8a, 0xfc, 0xeb, 0xa0, + 0x8a, 0xe6, 0x73, 0xb4, 0xc3, 0x0c, 0x03, 0x5f, + 0x03, 0x53, 0x6f, 0x69, 0xa2, 0xd0, 0xa7, 0x48, + 0xc4, 0x11, 0x88, 0x75, 0xe1, 0xf3, 0xd0, 0x72, + 0x98, 0x6f, 0x84, 0xa6, 0xa8, 0x35, 0xbb, 0xac, + 0x4d, 0xac, 0x55, 0x88, 0x85, 0x86, 0x5a, 0xd9, + 0xb6, 0x57, 0xf9, 0x40, 0xf6, 0x7f, 0x1b, 0x4e, + 0x87, 0xc0, 0x56, 0x8a, 0x2f, 0x3a, 0xe5, 0xa6, + 0x67, 0x68, 0x21, 0x2b, 0xea, 0xfa, 0xee, 0x47, + 0xa0, 0x34, 0x56, 0x7d, 0xa0, 0x3d, 0x58, 0xd7, + 0xff, 0xa2, 0xb6, 0x03, 0x52, 0x16, 0xa5, 0x15, + 0x65, 0xdb, 0xe1, 0x1b, 0xdf, 0x69, 0xb1, 0x48, + 0x6a, 0xdf, 0xc1, 0x00, 0x07, 0xdc, 0x46, 0x4b, + 0x59, 0xcf, 0x15, 0x6b, 0xee, 0x4f, 0x72, 0x77, + 0x6e, 0xbf, 0x47, 0x0e, 0x84, 0x0b, 0xb1, 0xac, + 0x85, 0xce, 0x2b, 0x47, 0x7a, 0xcc, 0x30, 0x0c, + 0x2f, 0x10, 0x27, 0xaa, 0x83, 0x3f, 0x17, 0x39, + 0x84, 0x45, 0x8c, 0xb7, 0x31, 0xb3, 0x7c, 0xcd, + 0xed, 0x86, 0x7d, 0xa9, 0x06, 0x25, 0x1f, 0xe3, + 0x9a, 0x9b, 0x92, 0xdd, 0x07, 0x63, 0x3b, 0x51, + 0x32, 0x2e, 0xae, 0xdf, 0xad, 0xd4, 0x54, 0x5d, + 0x71, 0x36, 0xe9, 0xda, 0x70, 0xe9, 0xec, 0x75, + 0x0b, 0xbb, 0xcc, 0x5d, 0xc5, 0x45, 0x8e, 0x56, + 0x12, 0x87, 0x95, 0x0f, 0x0f, 0x5b, 0x22, 0xc2, + 0xe9, 0x71, 0xf2, 0x7e, 0x7b, 0xc2, 0xce, 0x1f, + 0xb4, 0x43, 0xa5, 0xf1, 0x80, 0x03, 0xd9, 0x44, + 0x3e, 0x97, 0xd6, 0x32, 0x80, 0x99, 0x6b, 0x5b, + 0x25, 0x8b, 0x73, 0x0c, 0x21, 0xda, 0x87, 0x29, + 0x57, 0x1e, 0xa3, 0x1f, 0xc1, 0xb2, 0xd6, 0xa4, + 0x72, 0x64, 0x4a, 0x6b, 0x6f, 0x4d, 0xa8, 0x03, + 0x59, 0x6f, 0xce, 0x8a, 0xd6, 0x1c, 0x63, 0x30, + 0x60, 0xd1, 0x55, 0xc5, 0x44, 0x9a, 0xa8, 0x69, + 0x9f, 0xc7, 0xbe, 0xca, 0x92, 0x83, 0xe9, 0xea, + 0x51, 0x00, 0x5a, 0xdc, 0xbb, 0xbd, 0x5d, 0xf2, + 0x6d, 0x3c, 0x09, 0xde, 0x68, 0x33, 0x5f, 0x5c, + 0x80, 0x8e, 0x22, 0x93, 0x28, 0x5b, 0x77, 0xae, + 0xcd, 0x0d, 0x08, 0xab, 0x94, 0xd6, 0x12, 0x72, + 0x3f, 0xd2, 0xb3, 0xff, 0x87, 0x0a, 0x6f, 0x72, + 0xa7, 0xff, 0xc1, 0xdc, 0x8a, 0x64, 0xdf, 0xeb, + 0x0e, 0x63, 0x71, 0x42, 0x88, 0x2b, 0x13, 0x17, + 0xf2, 0x3b, 0xf9, 0xbb, 0xc9, 0xcc, 0x32, 0x1f, + 0x12, 0x7f, 0xa0, 0x8e, 0x77, 0x31, 0x42, 0x46, + 0x3d, 0xb6, 0xa9, 0x14, 0x6e, 0x02, 0x5a, 0x4f, + 0xf1, 0x5b, 0x91, 0x7e, 0x93, 0xea, 0x94, 0xf1, + 0xcf, 0x0e, 0x10, 0xf8, 0xc2, 0x55, 0x87, 0x68, + 0xf9, 0x49, 0xfa, 0xeb, 0x0f, 0x2c, 0xd7, 0xd8, + 0x26, 0x1a, 0x5b, 0x1a, 0x42, 0x06, 0xea, 0x8a, + 0xb6, 0xec, 0x6e, 0xb0, 0x00, 0xb9, 0x3b, 0x50, + 0xe8, 0x9e, 0xc2, 0x51, 0x4f, 0x03, 0xcd, 0x9f, + 0x36, 0x27, 0xca, 0xa2, 0x98, 0x87, 0x5a, 0xae, + 0xd8, 0x87, 0x76, 0xb6, 0xb6, 0x19, 0x7d, 0x75, +}; + +/* + * IV method encblkno1, blkno 2. + */ +static const uint8_t bf_cbc_256_encblkno1_vec2_ctxt[SECSIZE] = { + 0x91, 0x45, 0x4e, 0xe8, 0xad, 0xe3, 0x95, 0x0f, + 0x40, 0x35, 0x21, 0x21, 0x77, 0x62, 0x1d, 0x65, + 0xe4, 0x93, 0x11, 0xd2, 0x20, 0xa4, 0xe4, 0x53, + 0x44, 0xff, 0x60, 0xe9, 0x34, 0xb2, 0x33, 0x87, + 0x3d, 0xb0, 0xd8, 0x37, 0x7e, 0x0e, 0x9a, 0x53, + 0x92, 0xeb, 0xee, 0x16, 0x41, 0x25, 0xe3, 0x80, + 0x0c, 0x53, 0xd8, 0x1f, 0xf0, 0x99, 0xcb, 0x31, + 0xd1, 0x00, 0x82, 0x03, 0xcc, 0xa9, 0x5c, 0x8d, + 0x1a, 0xbb, 0x03, 0x81, 0x80, 0x0d, 0x5d, 0x4a, + 0x96, 0x74, 0x79, 0xf4, 0xa7, 0x46, 0x97, 0x42, + 0x5e, 0xb6, 0x8d, 0xc1, 0x95, 0x1d, 0x98, 0x4d, + 0xe5, 0xe9, 0x70, 0x1a, 0x5a, 0xad, 0xf4, 0x3d, + 0xe1, 0xa7, 0x25, 0xc7, 0xfa, 0x0a, 0x75, 0x98, + 0x2f, 0xef, 0x16, 0x2e, 0xf2, 0x02, 0x8a, 0x4c, + 0x1f, 0x5a, 0xbb, 0x06, 0x1b, 0x4e, 0x50, 0xfb, + 0x03, 0xed, 0x2a, 0x53, 0xdc, 0x2a, 0x65, 0xad, + 0x57, 0x84, 0x48, 0xdb, 0xd2, 0x9b, 0xc0, 0x01, + 0x5f, 0x7d, 0x3e, 0x84, 0xe5, 0x15, 0x7d, 0xc5, + 0x60, 0x4b, 0x18, 0xa1, 0xf3, 0x00, 0x82, 0xd3, + 0x39, 0x2a, 0x1f, 0x8f, 0x6a, 0xb7, 0xeb, 0x76, + 0xfb, 0xf0, 0x5e, 0x66, 0xd8, 0xf1, 0x85, 0xa8, + 0x17, 0xdc, 0x6a, 0xee, 0x53, 0xd9, 0x72, 0x27, + 0xd1, 0x47, 0x73, 0x97, 0x2c, 0xd7, 0xd2, 0xb8, + 0xcd, 0xbe, 0x7b, 0xcc, 0xcc, 0x7d, 0x82, 0x10, + 0x05, 0x5d, 0xff, 0xb0, 0xe0, 0x3a, 0xda, 0x1b, + 0x39, 0x7b, 0x11, 0x30, 0x4f, 0xe7, 0xf9, 0xa6, + 0x43, 0x56, 0x01, 0xe4, 0xed, 0x1a, 0x22, 0x5b, + 0x53, 0x6b, 0x34, 0x58, 0x21, 0x3f, 0x0d, 0xca, + 0x95, 0x24, 0x9a, 0xb0, 0x03, 0xe3, 0x97, 0xf5, + 0x9b, 0xcb, 0x10, 0x6f, 0x1d, 0x8a, 0x8b, 0xaa, + 0x14, 0x0a, 0x89, 0x92, 0xa1, 0x07, 0xb1, 0x35, + 0x40, 0x7f, 0xb0, 0xc3, 0x9a, 0x2a, 0x1f, 0x94, + 0x6c, 0x8f, 0xd8, 0x40, 0x52, 0xec, 0x0e, 0xbf, + 0x91, 0x27, 0xbd, 0x65, 0x25, 0xf2, 0x36, 0xe8, + 0x8f, 0x49, 0x08, 0xa6, 0x8f, 0x82, 0xb3, 0x47, + 0xe9, 0xa4, 0xa6, 0x8e, 0xfb, 0x30, 0xb2, 0x4c, + 0xad, 0x76, 0x65, 0x25, 0xdb, 0x60, 0xa8, 0xeb, + 0xb9, 0xf9, 0x9a, 0x9c, 0x9c, 0x12, 0xab, 0xeb, + 0x4b, 0x96, 0xa5, 0xc3, 0x58, 0x9b, 0x68, 0x2c, + 0x41, 0xac, 0xe5, 0x03, 0xbc, 0xee, 0xb8, 0x05, + 0xf7, 0xe6, 0xb1, 0x07, 0xde, 0x46, 0x28, 0xc1, + 0x2c, 0x15, 0xa2, 0x34, 0xea, 0xe7, 0xc3, 0x36, + 0xe6, 0x18, 0x20, 0x4e, 0x20, 0x3f, 0x32, 0xa8, + 0x29, 0x05, 0xf6, 0xa5, 0xf2, 0xa3, 0xeb, 0x7a, + 0x25, 0x5e, 0x14, 0x1f, 0xd0, 0xe1, 0x8e, 0xfb, + 0x28, 0xc5, 0xa2, 0x42, 0xed, 0x4c, 0x12, 0x15, + 0x2a, 0x08, 0xfb, 0x0b, 0xfb, 0x94, 0x64, 0xc0, + 0x8b, 0xbb, 0xbb, 0x2c, 0xef, 0xab, 0x0b, 0x4c, + 0x27, 0x40, 0x94, 0x3e, 0x93, 0x77, 0x98, 0xcc, + 0x64, 0xe3, 0xba, 0x22, 0x95, 0xd7, 0xc1, 0xe3, + 0xa7, 0xcd, 0xf9, 0x25, 0xdc, 0xc4, 0xd2, 0xee, + 0x5b, 0x53, 0x72, 0x59, 0x8b, 0xea, 0xbf, 0xde, + 0x2b, 0x35, 0xd5, 0x27, 0x57, 0x2e, 0x13, 0xa7, + 0x50, 0x2d, 0xa5, 0xd5, 0x43, 0x0b, 0x49, 0x87, + 0xd0, 0xbd, 0xdd, 0xec, 0x4b, 0xd1, 0x8b, 0xf6, + 0xf6, 0xd0, 0x97, 0xcb, 0x8d, 0x58, 0x35, 0x27, + 0xa5, 0x7e, 0x4a, 0xda, 0x93, 0xa4, 0x1e, 0x39, + 0x53, 0x59, 0x87, 0xfe, 0x82, 0x09, 0xda, 0x03, + 0x33, 0xcf, 0x94, 0x60, 0xb1, 0x0c, 0xa1, 0x0e, + 0xd6, 0xaa, 0xb0, 0x09, 0x96, 0x8b, 0x72, 0x15, + 0xfb, 0xb0, 0x7d, 0x06, 0xf5, 0x2d, 0x64, 0xcd, + 0x03, 0xf0, 0xfa, 0xed, 0x6f, 0x43, 0xe3, 0xf3, + 0x33, 0xaf, 0x65, 0x82, 0x1d, 0xad, 0x03, 0x62, + 0xbe, 0x12, 0x14, 0x85, 0x66, 0x45, 0x03, 0x79, +}; + +/* + * IV method encblkno1, blkno 3. + */ +static const uint8_t bf_cbc_256_encblkno1_vec3_ctxt[SECSIZE] = { + 0x65, 0xbb, 0x30, 0x13, 0x9a, 0x26, 0xe9, 0x3d, + 0x54, 0x28, 0x77, 0xf1, 0x3f, 0x9b, 0xe1, 0x3e, + 0x70, 0x90, 0x6f, 0x16, 0xfc, 0x2f, 0x27, 0xb3, + 0xc6, 0x3c, 0x38, 0x31, 0x11, 0xe1, 0x3b, 0x72, + 0x22, 0x1c, 0x01, 0xc5, 0xa6, 0x70, 0x16, 0x4d, + 0xd2, 0xbd, 0xcb, 0x15, 0x00, 0x22, 0xab, 0x65, + 0x6a, 0x96, 0x5e, 0x45, 0x7f, 0xfd, 0x76, 0x18, + 0x43, 0x25, 0x75, 0x73, 0xa4, 0x24, 0xe4, 0x5b, + 0xca, 0xf7, 0x6f, 0xfe, 0xc6, 0x4c, 0x81, 0x77, + 0xe5, 0x1b, 0xb4, 0x7b, 0x64, 0xc2, 0x0d, 0x2b, + 0xa9, 0x76, 0xae, 0x5d, 0xab, 0x81, 0x77, 0xa6, + 0x48, 0xe9, 0x0c, 0x6d, 0x93, 0xbd, 0x7e, 0xdc, + 0x39, 0x89, 0x72, 0xd2, 0x07, 0x87, 0x44, 0xa6, + 0x7d, 0x08, 0x54, 0xc6, 0x90, 0x1d, 0xa2, 0xd7, + 0xfd, 0xd5, 0x59, 0x67, 0xd9, 0x5f, 0x5c, 0xbc, + 0x60, 0xc7, 0xf6, 0x98, 0xad, 0x21, 0xdf, 0xde, + 0x27, 0xca, 0x73, 0x2f, 0x56, 0xb7, 0xd7, 0x54, + 0x6e, 0xc3, 0x09, 0x6f, 0x1b, 0x82, 0x6f, 0xf8, + 0x1b, 0xb2, 0x54, 0x47, 0x54, 0x55, 0x67, 0x1c, + 0x4a, 0x10, 0x44, 0xb8, 0x8e, 0x85, 0x71, 0x70, + 0x02, 0x49, 0xdd, 0x4f, 0xd4, 0xd4, 0x8a, 0x60, + 0x04, 0x17, 0x84, 0xbf, 0xb4, 0x0a, 0x6f, 0xc1, + 0xec, 0x1f, 0x5d, 0x79, 0x59, 0x15, 0x7b, 0x87, + 0xa2, 0xfe, 0x81, 0xa1, 0x0b, 0x74, 0xfa, 0xef, + 0xce, 0x96, 0xec, 0x4b, 0xd8, 0x8e, 0xe9, 0xc2, + 0x6b, 0x15, 0xd9, 0xe4, 0x1d, 0x81, 0xb2, 0x12, + 0xb9, 0x8b, 0x64, 0x3d, 0xfa, 0xf6, 0x29, 0x25, + 0x88, 0x4f, 0xfa, 0x56, 0x34, 0x85, 0xa6, 0xbe, + 0xf7, 0x9f, 0x54, 0xc4, 0xb7, 0x17, 0xd5, 0x00, + 0x2d, 0x06, 0xca, 0xf0, 0xec, 0xf9, 0x52, 0x62, + 0x12, 0xef, 0xc0, 0x57, 0xd1, 0xf3, 0xf2, 0xb1, + 0x3d, 0xc5, 0x69, 0x04, 0x95, 0xaf, 0xc6, 0x54, + 0x18, 0x08, 0x2f, 0xe2, 0xc2, 0xdb, 0x28, 0x63, + 0x7c, 0xf5, 0xba, 0xa4, 0xdf, 0xbd, 0xdd, 0xac, + 0x98, 0xec, 0x9e, 0x07, 0x48, 0xee, 0xb9, 0x6f, + 0x40, 0xba, 0x08, 0xd5, 0x74, 0x97, 0x34, 0x98, + 0x7a, 0x80, 0xc5, 0x78, 0x69, 0x11, 0xd9, 0xcb, + 0x3b, 0x6f, 0xe7, 0xb7, 0x78, 0xb0, 0x5e, 0x02, + 0xaf, 0x6c, 0xef, 0x36, 0x00, 0xca, 0x97, 0x1a, + 0x01, 0x2e, 0xe8, 0xc0, 0x8b, 0xc6, 0x78, 0xf4, + 0x2d, 0x60, 0x2c, 0x04, 0x3f, 0x0b, 0xca, 0x7e, + 0xf1, 0x2e, 0x67, 0x8f, 0x9d, 0xa7, 0xaa, 0xab, + 0xcf, 0xb3, 0x84, 0x9e, 0x14, 0x35, 0x15, 0x3b, + 0x88, 0x9a, 0x33, 0x5d, 0x68, 0x82, 0x29, 0x53, + 0x94, 0x18, 0x0d, 0x14, 0x9e, 0x5f, 0xc1, 0x32, + 0x0a, 0x95, 0x6e, 0xa3, 0x82, 0x4b, 0x58, 0x0f, + 0x9c, 0xf0, 0x26, 0x4b, 0x2f, 0x02, 0x60, 0x85, + 0xdd, 0x2c, 0xb8, 0x87, 0x8b, 0x14, 0x9c, 0x54, + 0x0a, 0x5a, 0x02, 0xbe, 0xe2, 0x71, 0xcc, 0x07, + 0xae, 0x67, 0x00, 0xa8, 0xd4, 0x09, 0x7c, 0xee, + 0x0d, 0x29, 0x17, 0x67, 0x96, 0x68, 0x41, 0xfa, + 0x72, 0x29, 0x98, 0x2b, 0x23, 0xd1, 0xa9, 0x89, + 0x1c, 0xcc, 0xaf, 0x88, 0xdb, 0xb5, 0x1e, 0xb1, + 0xae, 0x17, 0x5f, 0x29, 0x8d, 0x1c, 0x0a, 0x5c, + 0xb9, 0xa7, 0x59, 0x8b, 0x91, 0x41, 0xee, 0x89, + 0xe1, 0x0e, 0x7e, 0x0a, 0xee, 0xbc, 0x35, 0xab, + 0xf1, 0x5a, 0x58, 0x03, 0xa2, 0xcf, 0x33, 0xa3, + 0x74, 0x82, 0xd3, 0xa0, 0x32, 0xfc, 0x3b, 0x9c, + 0xdf, 0xc0, 0x3a, 0x76, 0xe1, 0xea, 0xf0, 0x6d, + 0xc8, 0xe7, 0x97, 0xec, 0x03, 0xc1, 0x72, 0x94, + 0xe5, 0xc4, 0x04, 0x2a, 0x38, 0xb4, 0xef, 0x47, + 0x1d, 0xf9, 0xb8, 0x0a, 0xa9, 0x45, 0xc1, 0x63, + 0xf8, 0x32, 0xdb, 0x5d, 0xb1, 0xa2, 0x80, 0x8c, + 0x23, 0xd3, 0x60, 0xfb, 0xf8, 0x84, 0x57, 0x8b, +}; + +const struct testvec bf_cbc_256_1_vectors[] = { + { + .blkno = 0, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_256_encblkno1_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_256_encblkno1_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_256_encblkno1_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_256_encblkno1_vec3_ctxt, + }, +}; + +/* + * IV method encblkno8, blkno 0. + */ +static const uint8_t bf_cbc_256_encblkno8_vec0_ctxt[SECSIZE] = { + 0x90, 0x3d, 0xd2, 0xc0, 0xd3, 0x75, 0xe8, 0x04, + 0x34, 0x66, 0x76, 0x25, 0x70, 0xde, 0x41, 0xf1, + 0x35, 0x63, 0x5c, 0xac, 0x8f, 0x28, 0x17, 0xd3, + 0xae, 0x43, 0xfd, 0x8a, 0xb8, 0xc2, 0xd3, 0x88, + 0xef, 0xfa, 0x21, 0xeb, 0xb4, 0x33, 0x75, 0x69, + 0x7d, 0xe9, 0x27, 0x1c, 0x03, 0xcf, 0x90, 0xcf, + 0xf0, 0xaa, 0x3e, 0x01, 0x41, 0x24, 0xdc, 0x01, + 0x5a, 0xe8, 0x92, 0xea, 0xde, 0x87, 0xbf, 0x75, + 0xe4, 0x0b, 0xf7, 0xa3, 0x42, 0x27, 0xc4, 0xde, + 0x01, 0x6f, 0x5c, 0xec, 0x6d, 0x37, 0x38, 0xd7, + 0x4f, 0x85, 0xc0, 0xc2, 0x3a, 0xa7, 0x2d, 0x15, + 0xd5, 0x1c, 0xee, 0x15, 0x13, 0x7a, 0x4e, 0x33, + 0xc7, 0x59, 0x93, 0x73, 0xe9, 0xf5, 0x39, 0xb0, + 0xad, 0x8b, 0x61, 0xca, 0x4d, 0x31, 0xaa, 0x44, + 0xf6, 0x5c, 0xb7, 0x99, 0xe5, 0x92, 0x3d, 0x47, + 0x79, 0x9b, 0x29, 0x16, 0xe1, 0x2c, 0x30, 0x8b, + 0x1e, 0x17, 0xf0, 0x91, 0x59, 0x00, 0xab, 0x6d, + 0x4d, 0xa7, 0x4d, 0x96, 0xc3, 0xe4, 0x3d, 0x17, + 0x5c, 0x8e, 0xfc, 0x59, 0x48, 0xd4, 0xdd, 0xf4, + 0xea, 0x3a, 0x68, 0xc8, 0xb1, 0x74, 0x69, 0xcb, + 0x49, 0x1a, 0xec, 0x24, 0x4e, 0x7e, 0xe9, 0xba, + 0x75, 0xfb, 0x52, 0x85, 0x75, 0xe9, 0x41, 0x9a, + 0xc6, 0x40, 0x9c, 0x92, 0x3f, 0xe8, 0x99, 0x81, + 0x84, 0x14, 0x2b, 0x62, 0x94, 0xba, 0x56, 0x00, + 0xde, 0x88, 0xe1, 0x35, 0xea, 0x25, 0x88, 0xd1, + 0xce, 0xd4, 0xfc, 0xde, 0xee, 0x1a, 0xfd, 0xb1, + 0xa7, 0x46, 0x9d, 0x0c, 0x99, 0xa6, 0xab, 0x23, + 0x55, 0x2f, 0x46, 0xd7, 0xb3, 0xcd, 0x2c, 0xab, + 0x93, 0x3e, 0xdb, 0xe2, 0x34, 0x69, 0x1a, 0x56, + 0x21, 0x92, 0x56, 0xf4, 0x05, 0xe1, 0x24, 0xee, + 0x4d, 0x5e, 0x89, 0xeb, 0x23, 0x26, 0xdc, 0x14, + 0xde, 0x56, 0x3f, 0x0c, 0x15, 0x3e, 0x42, 0x71, + 0x9b, 0xe8, 0xc5, 0xfd, 0x5e, 0x4a, 0xb6, 0xd9, + 0xa0, 0x18, 0x5d, 0xbd, 0xef, 0x80, 0xb4, 0xf6, + 0x1e, 0x56, 0x2a, 0x57, 0x13, 0xba, 0x24, 0xa4, + 0x6f, 0x4c, 0xd4, 0xaa, 0x31, 0x5e, 0x69, 0x26, + 0xd2, 0xee, 0xef, 0x7f, 0x83, 0x9c, 0x8e, 0x6a, + 0x17, 0xe3, 0xda, 0xf4, 0x59, 0xad, 0x26, 0x83, + 0x53, 0x4c, 0x0d, 0x62, 0xe5, 0x9a, 0x30, 0xc5, + 0x0a, 0xa8, 0xb1, 0x3b, 0x1b, 0x41, 0x5c, 0x74, + 0x42, 0x7b, 0x0c, 0x9e, 0x3c, 0x12, 0x04, 0x46, + 0xc3, 0xc7, 0x10, 0xea, 0xf1, 0x3b, 0xb1, 0x01, + 0xfe, 0x1b, 0xe8, 0xf8, 0x42, 0xbc, 0xe9, 0x11, + 0x9b, 0x63, 0x29, 0x99, 0x18, 0x79, 0x9e, 0xd2, + 0xbf, 0x9d, 0x93, 0x4d, 0x16, 0x0f, 0x14, 0x41, + 0xb6, 0x0c, 0xa5, 0x07, 0x13, 0x29, 0x21, 0x0d, + 0x8f, 0xf9, 0x0a, 0x0a, 0x54, 0xaf, 0xa6, 0x22, + 0x25, 0x79, 0x07, 0xe5, 0x3e, 0x49, 0x6b, 0x12, + 0x9e, 0xfc, 0x91, 0xdb, 0xf3, 0x7c, 0xdf, 0x03, + 0x9c, 0x78, 0xa7, 0xc3, 0x5e, 0x14, 0xde, 0xb5, + 0x6a, 0x7b, 0x3b, 0xe3, 0x4f, 0x8a, 0x49, 0xce, + 0xc9, 0x14, 0x29, 0x96, 0x84, 0xca, 0xe1, 0x49, + 0x41, 0x73, 0xb3, 0x2a, 0xbe, 0x37, 0xb6, 0x2d, + 0xff, 0xf2, 0x8e, 0x3d, 0x02, 0xeb, 0xd4, 0xd3, + 0x15, 0x8f, 0xc0, 0x00, 0x91, 0xd5, 0xe7, 0x76, + 0xf5, 0x6e, 0x81, 0x38, 0x38, 0x07, 0xa6, 0xe8, + 0x72, 0x14, 0x3b, 0x36, 0xef, 0xbc, 0x5b, 0x26, + 0xb0, 0x60, 0x25, 0x49, 0x7e, 0xfc, 0xd8, 0x3b, + 0x63, 0xdc, 0x7f, 0x80, 0xd5, 0x43, 0x78, 0xbb, + 0xf1, 0xf9, 0x3e, 0x75, 0x1d, 0x58, 0xb2, 0xc7, + 0xb6, 0x52, 0xfb, 0xe7, 0x42, 0xef, 0x87, 0xfd, + 0x3a, 0x02, 0x7a, 0xf9, 0xbc, 0xa8, 0x2f, 0xd6, + 0xc1, 0x5f, 0xa4, 0x57, 0x62, 0x83, 0x82, 0x8e, + 0x1e, 0xbb, 0x85, 0xf7, 0x1b, 0x2e, 0xe2, 0xb0, +}; + +/* + * IV method encblkno8, blkno 1. + */ +static const uint8_t bf_cbc_256_encblkno8_vec1_ctxt[SECSIZE] = { + 0x2b, 0xf6, 0xd4, 0x61, 0x3b, 0x1f, 0x5b, 0xe9, + 0x32, 0xab, 0x27, 0xa1, 0xaf, 0x5e, 0xf4, 0xa7, + 0xaa, 0xc5, 0x2a, 0x3c, 0x0d, 0x34, 0xd8, 0xb3, + 0xfd, 0xb2, 0xca, 0xfb, 0x3c, 0x38, 0x96, 0x71, + 0x47, 0xaa, 0xa7, 0x2f, 0x48, 0x2c, 0x39, 0x88, + 0x2d, 0xc6, 0xb1, 0xf7, 0xc7, 0x2d, 0xda, 0xe9, + 0xfb, 0x4f, 0x9b, 0x1f, 0xe1, 0x0c, 0x24, 0x89, + 0xfe, 0x70, 0xe0, 0xb2, 0x51, 0x89, 0x51, 0xa9, + 0xae, 0xd1, 0x92, 0x4f, 0x56, 0x5c, 0x2a, 0xf4, + 0xbc, 0x4e, 0x77, 0x4a, 0xb8, 0xab, 0x02, 0x76, + 0xef, 0x69, 0xfb, 0x5e, 0x06, 0xb5, 0xff, 0x31, + 0xce, 0x2b, 0xfc, 0x48, 0x4c, 0x82, 0xe9, 0x3c, + 0x61, 0x69, 0x68, 0x1d, 0xb1, 0xc6, 0x40, 0x10, + 0xd7, 0x0e, 0xd2, 0x26, 0x33, 0x5b, 0x0b, 0xe7, + 0xc2, 0xbe, 0xf4, 0x24, 0x1a, 0xa6, 0x70, 0x31, + 0xa7, 0x15, 0x76, 0xc7, 0x90, 0x8d, 0x60, 0xe0, + 0xee, 0x5b, 0x73, 0xa9, 0xe1, 0xe1, 0xaf, 0xf0, + 0x5e, 0x6f, 0x32, 0x98, 0x92, 0xbe, 0x24, 0x81, + 0x26, 0x9f, 0xb8, 0x67, 0xd0, 0xca, 0x9d, 0x8f, + 0x14, 0xc8, 0x81, 0x2e, 0x57, 0x1c, 0x3a, 0xe0, + 0xdb, 0x49, 0xad, 0x47, 0x51, 0x07, 0x7d, 0xec, + 0xbc, 0xa5, 0x8f, 0xdf, 0x84, 0xe4, 0xdf, 0x76, + 0x8f, 0x0b, 0xef, 0xc4, 0x41, 0xd5, 0x7c, 0xf5, + 0x3c, 0x21, 0x62, 0xc0, 0x1f, 0xbd, 0x39, 0xbe, + 0xe5, 0x75, 0x64, 0xcd, 0xa4, 0xa0, 0x03, 0xf4, + 0x8a, 0x16, 0x3e, 0xde, 0x79, 0x9a, 0x96, 0xff, + 0xf2, 0xbe, 0x88, 0xfd, 0xac, 0xc1, 0x9d, 0x5b, + 0xbf, 0x2f, 0xde, 0xf0, 0x26, 0x2f, 0xc9, 0x45, + 0xbd, 0x26, 0xa5, 0x2c, 0x3c, 0x12, 0x8b, 0xc0, + 0xc8, 0x7a, 0x71, 0xbb, 0xc3, 0xe9, 0xf6, 0x15, + 0x01, 0x6e, 0x94, 0x37, 0xbc, 0xc5, 0x9a, 0x93, + 0x6f, 0x9c, 0x04, 0x7e, 0xe9, 0xb2, 0xba, 0xe8, + 0x86, 0xa1, 0x9c, 0x1f, 0x4b, 0x77, 0x6f, 0x99, + 0x2d, 0x8f, 0x23, 0x34, 0x32, 0x1a, 0x82, 0x2d, + 0x32, 0x41, 0x3e, 0xb8, 0x6a, 0x67, 0xa9, 0x81, + 0xd5, 0x1b, 0x76, 0x9f, 0xd1, 0xb0, 0x06, 0xaf, + 0x10, 0x9e, 0x00, 0x2e, 0xb3, 0x80, 0xde, 0xae, + 0xf2, 0x96, 0x12, 0x5b, 0xe7, 0xc7, 0x25, 0xb7, + 0xd9, 0x1c, 0x04, 0xe5, 0x05, 0xaf, 0x77, 0xfa, + 0x6d, 0xa8, 0x04, 0x74, 0xf8, 0x9c, 0x09, 0xcf, + 0xe2, 0xc2, 0xd1, 0xb6, 0xac, 0xed, 0xb4, 0xbc, + 0x2e, 0xc2, 0xf6, 0x3c, 0xc4, 0x47, 0xc8, 0x81, + 0x3a, 0x50, 0x3c, 0x5c, 0x7c, 0x86, 0x17, 0x22, + 0xe7, 0xa3, 0xff, 0x73, 0x5e, 0x91, 0xbf, 0xb3, + 0x59, 0x07, 0xb7, 0xa4, 0xd5, 0x1b, 0x5c, 0xce, + 0x56, 0xde, 0x5f, 0xae, 0x89, 0xcb, 0x6a, 0xfe, + 0xaf, 0xe7, 0xd4, 0x34, 0x8d, 0x18, 0x22, 0x4d, + 0xd9, 0x91, 0xa6, 0xec, 0x97, 0x0e, 0x29, 0x4d, + 0xf6, 0xd8, 0xb3, 0x50, 0x1c, 0xc9, 0x66, 0x9d, + 0x2e, 0x5e, 0x27, 0xce, 0x36, 0xcb, 0x47, 0x35, + 0x41, 0x16, 0x0c, 0x4e, 0x73, 0x90, 0x52, 0xc5, + 0x65, 0xb8, 0x0c, 0xdc, 0x36, 0x8d, 0xdc, 0xca, + 0x97, 0x0b, 0xbc, 0xcb, 0x79, 0xc7, 0x4c, 0xd2, + 0x21, 0x5c, 0xbd, 0xeb, 0xea, 0xfb, 0x87, 0xe1, + 0xe0, 0x75, 0x39, 0xb9, 0x84, 0x1e, 0xa7, 0xfe, + 0x7d, 0x41, 0x75, 0x15, 0x88, 0x98, 0xd4, 0x80, + 0x42, 0x57, 0xb5, 0x65, 0xbf, 0xb8, 0xbd, 0x19, + 0x28, 0xd8, 0xa7, 0x6c, 0xe7, 0xc1, 0x00, 0xdc, + 0xde, 0xcb, 0x30, 0x3d, 0x29, 0x5e, 0xa6, 0x9c, + 0xbb, 0xb8, 0xec, 0x28, 0x23, 0x36, 0x23, 0x27, + 0xee, 0xdd, 0x24, 0x7d, 0x9a, 0xc9, 0xb5, 0x3c, + 0x7a, 0x3f, 0x1d, 0xd9, 0x32, 0x47, 0xc0, 0x4d, + 0x86, 0x9b, 0x2d, 0xa9, 0x5c, 0x93, 0x90, 0x51, + 0x70, 0xe6, 0x8f, 0x35, 0x96, 0xe0, 0x11, 0x00, +}; + +/* + * IV method encblkno8, blkno 2. + */ +static const uint8_t bf_cbc_256_encblkno8_vec2_ctxt[SECSIZE] = { + 0x28, 0x93, 0x0f, 0x23, 0xfb, 0xa4, 0x9e, 0xe5, + 0x11, 0x38, 0x2b, 0xbd, 0x8d, 0x2d, 0xdb, 0x11, + 0xfa, 0xac, 0x74, 0x28, 0x95, 0x29, 0xf2, 0x92, + 0x8d, 0x00, 0x8a, 0x8a, 0x04, 0x92, 0x92, 0x33, + 0x8c, 0x4b, 0x29, 0x8e, 0xde, 0x59, 0xf4, 0x72, + 0xae, 0x2f, 0xe4, 0xe9, 0xd4, 0xe4, 0xb6, 0x69, + 0xc5, 0x1b, 0xbe, 0x02, 0x85, 0x4b, 0x24, 0x1e, + 0x79, 0xb9, 0x22, 0x29, 0x4c, 0x60, 0x8c, 0xc5, + 0x03, 0x1d, 0x79, 0xfe, 0x3d, 0x9e, 0x47, 0xb6, + 0xf7, 0x17, 0x65, 0x24, 0x15, 0x5d, 0x75, 0x4d, + 0xdb, 0xbc, 0x68, 0x67, 0x3b, 0xc3, 0x5a, 0x7e, + 0x9d, 0x98, 0x67, 0xe4, 0x8f, 0x9a, 0xd1, 0x31, + 0xe0, 0x26, 0xa1, 0x68, 0xbe, 0x53, 0x73, 0x7c, + 0xfd, 0xce, 0x6c, 0xd6, 0x1f, 0x51, 0xe6, 0x84, + 0x54, 0x7a, 0xe3, 0x7f, 0x7c, 0x8f, 0x2f, 0x88, + 0x58, 0xfe, 0x5e, 0x82, 0x11, 0xc9, 0xa5, 0x89, + 0xa4, 0x49, 0x92, 0x21, 0x0f, 0x03, 0xdb, 0x16, + 0xc4, 0xc0, 0x80, 0xb7, 0x16, 0x4c, 0x29, 0xbe, + 0x18, 0xfa, 0x2d, 0xdf, 0x4a, 0x23, 0x34, 0x9a, + 0x27, 0xea, 0xed, 0x95, 0x25, 0x14, 0xa8, 0x2e, + 0x17, 0x59, 0x04, 0xb0, 0x5c, 0x6d, 0xc7, 0xeb, + 0xed, 0xf6, 0x73, 0xae, 0x18, 0x0e, 0x4b, 0xec, + 0xc6, 0xb7, 0x39, 0xe7, 0x62, 0xf0, 0x84, 0x30, + 0x10, 0xb6, 0xf3, 0x27, 0x6d, 0xfe, 0x32, 0xe7, + 0xfe, 0xff, 0x43, 0xba, 0x89, 0xfe, 0x24, 0xa8, + 0x0e, 0x7c, 0xf2, 0x23, 0x9d, 0x66, 0x6f, 0x9c, + 0xe6, 0x88, 0xbc, 0x3f, 0x44, 0x4c, 0x73, 0x13, + 0x77, 0x95, 0x6f, 0xcb, 0xc8, 0xa5, 0x7a, 0xa9, + 0xeb, 0xe1, 0x0f, 0x9e, 0x25, 0xbe, 0x99, 0x1a, + 0x99, 0x7f, 0xbb, 0xec, 0x89, 0x91, 0x3e, 0x52, + 0xb5, 0xac, 0xc9, 0xd3, 0xea, 0xb0, 0xf2, 0x0c, + 0xc8, 0x58, 0x4b, 0x93, 0xa3, 0x9f, 0xad, 0x5a, + 0x80, 0x4e, 0x02, 0x20, 0x9d, 0xac, 0x4b, 0xe0, + 0x59, 0x4d, 0xb5, 0x51, 0x07, 0xf5, 0xa6, 0xb3, + 0xc9, 0x20, 0x58, 0x7e, 0x45, 0xec, 0x58, 0xea, + 0x49, 0xbb, 0x03, 0xf5, 0x6c, 0xdd, 0xcc, 0xa3, + 0x13, 0x21, 0x79, 0xc9, 0xc2, 0x92, 0x60, 0xd5, + 0xb2, 0x3b, 0x74, 0xbc, 0x57, 0xa6, 0x70, 0x36, + 0x75, 0xf5, 0x01, 0xd1, 0xb2, 0xe9, 0xfd, 0xc5, + 0x93, 0x5e, 0x60, 0x6b, 0xfd, 0xd2, 0x56, 0xc0, + 0x1f, 0xe4, 0xcd, 0x4c, 0xfa, 0xc4, 0xd8, 0xc2, + 0x2d, 0xf9, 0x9f, 0x82, 0x0f, 0x40, 0x7b, 0xad, + 0x35, 0x63, 0x95, 0x7e, 0x49, 0x4a, 0xfe, 0x8f, + 0xaa, 0x57, 0x3a, 0x0c, 0x59, 0x69, 0xe7, 0xb8, + 0xfc, 0x71, 0x5c, 0x4f, 0x18, 0x12, 0xe5, 0xef, + 0xdb, 0x1f, 0x66, 0x9a, 0xe2, 0x1a, 0x92, 0x1f, + 0xfe, 0x20, 0x81, 0xe5, 0x83, 0x97, 0xfb, 0xaf, + 0xeb, 0x31, 0x6c, 0x81, 0xf2, 0x2f, 0xf4, 0x41, + 0xf1, 0xd9, 0x61, 0xfb, 0x36, 0x4e, 0xab, 0xc5, + 0x8b, 0x9c, 0x37, 0xea, 0x88, 0xeb, 0x1e, 0x4c, + 0x84, 0x1a, 0xac, 0x4c, 0x19, 0x39, 0x51, 0x53, + 0xe0, 0x50, 0xb0, 0xdf, 0xe6, 0xc5, 0xbb, 0x80, + 0x06, 0x30, 0x14, 0xf5, 0x0e, 0x73, 0xd2, 0xdb, + 0x19, 0x45, 0x30, 0xdc, 0xd0, 0x4d, 0xe6, 0xd6, + 0x0e, 0x2d, 0x77, 0xa3, 0xb3, 0x27, 0xda, 0x99, + 0x62, 0x88, 0x35, 0xba, 0x64, 0x15, 0xec, 0xaf, + 0x70, 0x97, 0x94, 0x81, 0x30, 0x6d, 0x63, 0x42, + 0x71, 0x3e, 0x06, 0xec, 0x50, 0x96, 0x87, 0x59, + 0xe7, 0x26, 0x9c, 0xcf, 0xc7, 0xe7, 0x62, 0x82, + 0x3b, 0xd7, 0xfe, 0xb4, 0x48, 0x45, 0x9d, 0x54, + 0x18, 0x15, 0x13, 0x74, 0x92, 0x6f, 0x43, 0xb3, + 0xa9, 0x82, 0xd4, 0xc2, 0xef, 0x61, 0x9d, 0x5e, + 0x1d, 0xc6, 0x80, 0xd3, 0xe9, 0xdd, 0x52, 0x9c, + 0x4d, 0x04, 0x05, 0xa0, 0x43, 0x36, 0xb6, 0x89, +}; + +/* + * IV method encblkno8, blkno 3. + */ +static const uint8_t bf_cbc_256_encblkno8_vec3_ctxt[SECSIZE] = { + 0x60, 0x91, 0x19, 0x89, 0xee, 0xac, 0x12, 0xe5, + 0x60, 0x6c, 0xfd, 0xf9, 0xe4, 0xc6, 0xc9, 0xbd, + 0x75, 0xe1, 0xa5, 0xe6, 0xf4, 0xed, 0x4b, 0xf4, + 0x16, 0xf4, 0x57, 0xa4, 0xe6, 0x60, 0x8e, 0x1b, + 0x97, 0x0e, 0xd5, 0x09, 0xa1, 0x3c, 0x6c, 0xe8, + 0x91, 0xaf, 0x19, 0x96, 0x2a, 0x7b, 0x77, 0x30, + 0xc7, 0x99, 0xe6, 0xaa, 0xb0, 0xe2, 0x29, 0x1c, + 0x39, 0x54, 0x1c, 0x0a, 0x4a, 0x51, 0xa2, 0xa2, + 0x22, 0x96, 0x05, 0x8b, 0x12, 0x80, 0x16, 0x28, + 0xdc, 0xfa, 0x22, 0x90, 0xa4, 0x33, 0xb1, 0x84, + 0x13, 0x52, 0x5d, 0xb5, 0xd4, 0xe8, 0x60, 0x18, + 0x6a, 0xb8, 0x1b, 0xdb, 0xb4, 0x69, 0xf6, 0x09, + 0x95, 0x71, 0xdd, 0x43, 0x21, 0xad, 0x7e, 0xf7, + 0x8e, 0x7a, 0x0d, 0xf0, 0x52, 0x54, 0xb8, 0xdc, + 0x7d, 0x72, 0x29, 0x97, 0x2b, 0x9c, 0x2c, 0xef, + 0xc3, 0x26, 0x68, 0x72, 0xae, 0x29, 0x0f, 0x67, + 0xbf, 0xea, 0x92, 0x27, 0xd1, 0xba, 0x8d, 0x32, + 0x8b, 0x26, 0x91, 0x30, 0x88, 0xcc, 0x47, 0xaf, + 0x54, 0x8c, 0x88, 0x88, 0x2f, 0x59, 0x76, 0x34, + 0x43, 0x35, 0x44, 0xc3, 0x16, 0x28, 0x62, 0x4b, + 0xbb, 0x47, 0x99, 0x7c, 0x26, 0x51, 0xe2, 0x7d, + 0xd8, 0x2c, 0x35, 0xf4, 0x24, 0xf1, 0x5b, 0x01, + 0xcc, 0x9a, 0x54, 0xd8, 0xc1, 0x73, 0x85, 0x83, + 0xdd, 0x0d, 0xd5, 0x75, 0xac, 0x67, 0x68, 0x59, + 0x3e, 0x6e, 0x9a, 0x4a, 0x7f, 0xbd, 0x85, 0xeb, + 0x36, 0x3e, 0xfd, 0x03, 0xfe, 0x2b, 0xe6, 0x97, + 0x16, 0x6b, 0xd0, 0x22, 0xb1, 0x00, 0xcc, 0x7c, + 0x03, 0xb1, 0x7c, 0x23, 0x7a, 0xca, 0x5e, 0x0b, + 0xba, 0x37, 0xa6, 0x08, 0x5b, 0xa6, 0x2b, 0x57, + 0x58, 0x0b, 0x5a, 0x58, 0x91, 0x3c, 0xf9, 0x46, + 0x05, 0x03, 0x0a, 0x9b, 0xca, 0x2d, 0x71, 0xe2, + 0xbb, 0x1e, 0xd3, 0xc5, 0xc2, 0xb4, 0xde, 0x7b, + 0xbb, 0x8b, 0x45, 0x39, 0xf5, 0x3d, 0xa2, 0xe5, + 0xb1, 0x40, 0x3b, 0x9e, 0x47, 0x93, 0xf9, 0x9c, + 0x50, 0x5c, 0x9b, 0x8d, 0x18, 0x47, 0xd3, 0xe8, + 0x61, 0xbc, 0x93, 0xdc, 0xf7, 0x20, 0x5a, 0x00, + 0x0e, 0xb8, 0xee, 0x5e, 0x83, 0x06, 0x48, 0x06, + 0x91, 0x08, 0x9e, 0x9c, 0x73, 0x6d, 0xb9, 0x31, + 0x62, 0xdc, 0x8a, 0x37, 0x17, 0x47, 0x2f, 0x0f, + 0xc0, 0x02, 0x02, 0xf3, 0x06, 0x26, 0x6c, 0x9d, + 0x96, 0x9f, 0xb0, 0xb3, 0x3b, 0x72, 0x18, 0x59, + 0xf4, 0xb7, 0x26, 0xcc, 0xa4, 0x46, 0xdb, 0x51, + 0xad, 0xed, 0xd8, 0x3a, 0xc4, 0x3a, 0x09, 0x30, + 0x72, 0xd9, 0x2c, 0xfe, 0x5f, 0xa8, 0x46, 0x75, + 0xf7, 0xba, 0x46, 0x1e, 0x7e, 0x4c, 0xd6, 0xdd, + 0x92, 0x2b, 0x23, 0xc6, 0x59, 0x19, 0xda, 0x9a, + 0x01, 0x9c, 0x5c, 0xc1, 0xaa, 0xcf, 0x6d, 0xd0, + 0xa5, 0x06, 0xc7, 0x5e, 0x6b, 0x60, 0x64, 0x9f, + 0xfe, 0xa8, 0x3f, 0x64, 0xa8, 0xed, 0xf8, 0x62, + 0xd7, 0x6d, 0x34, 0x41, 0x3e, 0x5e, 0x74, 0xc7, + 0xe6, 0x62, 0xb1, 0x5a, 0xec, 0x6a, 0xc1, 0x71, + 0x19, 0xf3, 0xf1, 0xe7, 0x46, 0x13, 0xd6, 0xb6, + 0x5a, 0xf4, 0xca, 0x3f, 0xe3, 0xa1, 0x1f, 0xe4, + 0xda, 0xd6, 0x0c, 0x62, 0x6a, 0x33, 0x42, 0x99, + 0x6f, 0x5d, 0x3a, 0xe0, 0xe7, 0xfa, 0x2d, 0x47, + 0x4a, 0xec, 0xaa, 0x71, 0xb5, 0xeb, 0x62, 0xb8, + 0x31, 0x34, 0x07, 0x44, 0xa2, 0x18, 0xec, 0x76, + 0xf7, 0x77, 0x56, 0x86, 0xc7, 0xe0, 0x1e, 0x8e, + 0xec, 0x16, 0x2b, 0xeb, 0xff, 0xaa, 0xba, 0x83, + 0x1f, 0xdc, 0x32, 0x23, 0x27, 0xea, 0xea, 0x0c, + 0x3a, 0x5f, 0x2b, 0xb4, 0xee, 0x0c, 0xf2, 0x73, + 0xbb, 0x59, 0x9b, 0x73, 0xf7, 0xfa, 0xe1, 0x1f, + 0x3b, 0xdb, 0x40, 0x29, 0xf0, 0x6c, 0xbe, 0x8f, + 0x2e, 0xd0, 0x83, 0xf7, 0xe8, 0x2a, 0x81, 0x82, +}; + +const struct testvec bf_cbc_256_8_vectors[] = { + { + .blkno = 0, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_256_encblkno8_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_256_encblkno8_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_256_encblkno8_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_256_encblkno8_vec3_ctxt, + }, +}; + +/* + * IV method encblkno1, blkno 0. + */ +static const uint8_t bf_cbc_448_encblkno1_vec0_ctxt[SECSIZE] = { + 0xb0, 0x1b, 0x43, 0xc9, 0x84, 0x53, 0x51, 0x72, + 0x1f, 0x93, 0x62, 0x94, 0x13, 0x1f, 0xe3, 0xc1, + 0x30, 0xee, 0xc4, 0x35, 0x98, 0xb8, 0x11, 0x9b, + 0xd1, 0x23, 0xfa, 0x2d, 0xc1, 0xe6, 0xf3, 0x8f, + 0x8b, 0x05, 0x8d, 0xc5, 0x1d, 0xc3, 0x29, 0x1a, + 0xff, 0x08, 0xb0, 0x97, 0x88, 0x50, 0x8f, 0x41, + 0x66, 0xc6, 0x70, 0x37, 0xca, 0xb2, 0xcd, 0x91, + 0x89, 0x41, 0x1b, 0x42, 0xce, 0x02, 0xec, 0xe8, + 0x9b, 0xf3, 0x50, 0x95, 0x5f, 0xba, 0xda, 0xd5, + 0x0c, 0x2f, 0x29, 0x2a, 0x14, 0x96, 0x4a, 0x60, + 0x04, 0x43, 0x62, 0x80, 0x89, 0xcf, 0xfd, 0xb6, + 0xc7, 0x2d, 0xb2, 0xac, 0xce, 0x51, 0xf5, 0xd1, + 0xcd, 0x41, 0x59, 0x8b, 0xf5, 0x02, 0x2d, 0xe8, + 0xc4, 0xee, 0xe9, 0x40, 0x6f, 0xcd, 0xbe, 0x3b, + 0xd0, 0x8d, 0x3e, 0x6c, 0x42, 0x2a, 0x17, 0xfd, + 0x78, 0xf6, 0xb2, 0xde, 0x69, 0x81, 0xbb, 0xae, + 0xd9, 0x1f, 0x49, 0xa6, 0x4c, 0x5a, 0xe9, 0x94, + 0x49, 0x9b, 0x7e, 0x32, 0x6d, 0x11, 0xea, 0x88, + 0xda, 0xf0, 0xc7, 0x8d, 0x07, 0x98, 0xab, 0xc7, + 0xf3, 0xcf, 0x2e, 0xda, 0x27, 0x44, 0x68, 0xc7, + 0xdc, 0xda, 0x00, 0xd0, 0x6d, 0x64, 0x5b, 0x39, + 0x46, 0x3d, 0x98, 0x24, 0xee, 0x3b, 0x36, 0x23, + 0x62, 0xf6, 0x8e, 0xb9, 0x8d, 0xc1, 0x9a, 0x7b, + 0xd7, 0x03, 0x6b, 0xb7, 0x81, 0x19, 0xec, 0x2f, + 0x0c, 0x0b, 0x32, 0x5a, 0xb3, 0x25, 0xf5, 0xcc, + 0xa3, 0x60, 0xe6, 0x4e, 0x03, 0xcd, 0xdc, 0x67, + 0xe5, 0x26, 0xda, 0xe0, 0x1f, 0x33, 0x99, 0xc3, + 0x43, 0x8c, 0x9c, 0x1a, 0x85, 0xb1, 0x15, 0x04, + 0xc1, 0x06, 0xd1, 0x2d, 0xc9, 0x67, 0x72, 0xe7, + 0xd6, 0x6d, 0x1f, 0x22, 0x56, 0x56, 0xfa, 0x8a, + 0xd7, 0x16, 0x37, 0x3f, 0x3e, 0x67, 0xa5, 0xb7, + 0xee, 0x3e, 0xd2, 0x38, 0xd5, 0xce, 0xa9, 0x62, + 0x82, 0x17, 0xae, 0xae, 0x62, 0xe6, 0xb7, 0xf2, + 0x73, 0xf1, 0xc1, 0xb7, 0xe9, 0x62, 0x79, 0x3b, + 0x3b, 0x3f, 0xaa, 0x0d, 0x42, 0x03, 0x35, 0x3f, + 0x5d, 0xa4, 0xba, 0x02, 0x23, 0x65, 0x40, 0x0e, + 0x61, 0x31, 0xc9, 0xd5, 0x79, 0x36, 0x76, 0x7c, + 0x21, 0x4a, 0x75, 0xb2, 0xa0, 0x2b, 0xc1, 0xb8, + 0xba, 0xf8, 0x10, 0x7a, 0x85, 0x32, 0x81, 0xbf, + 0x2d, 0x58, 0x3c, 0x22, 0x2f, 0x0b, 0xce, 0x03, + 0x12, 0xce, 0x13, 0xce, 0x4a, 0x81, 0x77, 0x1d, + 0x68, 0x99, 0xc0, 0x25, 0xeb, 0xd9, 0x80, 0x0d, + 0xe7, 0x17, 0xc8, 0x41, 0xbd, 0x4b, 0x9c, 0xdd, + 0x41, 0x74, 0x90, 0x2a, 0x65, 0x92, 0x05, 0xff, + 0x06, 0x24, 0xeb, 0x89, 0xd8, 0x41, 0xaa, 0x41, + 0xac, 0x8a, 0x31, 0xc6, 0x82, 0x44, 0x12, 0x5a, + 0xd9, 0x1c, 0xca, 0x76, 0x2b, 0x4e, 0xe8, 0x18, + 0x7e, 0x50, 0xf5, 0x8c, 0x7c, 0x11, 0xe7, 0x0e, + 0xfd, 0x08, 0x5e, 0x64, 0x8b, 0x5b, 0x9f, 0x94, + 0x8b, 0x0d, 0x83, 0x7e, 0xef, 0x89, 0x30, 0x4a, + 0x55, 0xce, 0x10, 0x5f, 0x15, 0xd2, 0xe7, 0x07, + 0x0c, 0x34, 0x92, 0xda, 0xae, 0x84, 0x26, 0x28, + 0x36, 0x1a, 0x96, 0xc6, 0xf1, 0x41, 0x2b, 0xb6, + 0x01, 0xfe, 0x20, 0x05, 0x43, 0x80, 0x45, 0xdf, + 0x5c, 0xc2, 0x96, 0xc8, 0x41, 0x68, 0x87, 0x78, + 0xbc, 0xf8, 0x34, 0xfb, 0x19, 0x61, 0xab, 0x7f, + 0x15, 0x56, 0x7f, 0x1a, 0xf5, 0x08, 0xf1, 0x1c, + 0x59, 0x70, 0x92, 0x3a, 0xda, 0x1a, 0xfd, 0xfc, + 0x4d, 0xe1, 0x12, 0x61, 0xc1, 0xd8, 0xdb, 0x63, + 0x6e, 0x6b, 0x19, 0x96, 0x68, 0x17, 0x9b, 0xf5, + 0xa9, 0x5d, 0x2c, 0xaf, 0xad, 0xc6, 0x26, 0x9e, + 0x09, 0xcb, 0x67, 0x4e, 0x50, 0x7d, 0x2f, 0xae, + 0x4e, 0x73, 0xd9, 0x5a, 0xaa, 0x5d, 0x54, 0x20, + 0x7b, 0x77, 0xcf, 0xf8, 0xad, 0x88, 0x6b, 0xc8, +}; + +/* + * IV method encblkno1, blkno 1. + */ +static const uint8_t bf_cbc_448_encblkno1_vec1_ctxt[SECSIZE] = { + 0x8b, 0x2a, 0xcf, 0x7d, 0x38, 0x1b, 0xaa, 0x33, + 0x1c, 0xe6, 0xa1, 0x37, 0x6e, 0x9e, 0xb3, 0x48, + 0x2a, 0xb8, 0x61, 0x11, 0x00, 0xe5, 0x48, 0xea, + 0xb5, 0x9f, 0x6c, 0xa4, 0xdf, 0x8d, 0x5a, 0xd8, + 0x03, 0x55, 0x4d, 0x07, 0x7d, 0x5f, 0x1b, 0x18, + 0xd1, 0x86, 0x52, 0xc1, 0x13, 0xda, 0x99, 0x23, + 0xeb, 0xab, 0xb2, 0x93, 0x40, 0x7c, 0x6a, 0x8a, + 0xaa, 0xf8, 0xf1, 0x66, 0xf1, 0x10, 0x1d, 0xcd, + 0x25, 0xc7, 0x84, 0x55, 0x02, 0x1d, 0xc0, 0x3c, + 0xba, 0xf4, 0xbf, 0xe2, 0xe4, 0xc3, 0x57, 0xdc, + 0x0d, 0xfd, 0xeb, 0xb3, 0x7d, 0x31, 0x82, 0x6b, + 0x5c, 0x0e, 0x92, 0xa5, 0x42, 0x8b, 0x7f, 0x36, + 0x74, 0x4d, 0xfd, 0x2f, 0xd7, 0x19, 0x0d, 0x23, + 0xa7, 0x36, 0xe8, 0xe4, 0xe5, 0xff, 0xc8, 0x0d, + 0xe1, 0x48, 0x25, 0x79, 0xa9, 0x22, 0xac, 0x72, + 0x86, 0x28, 0xcb, 0x63, 0xa6, 0xa0, 0x46, 0x08, + 0x53, 0xb8, 0x59, 0xab, 0x0f, 0x8f, 0xb1, 0x78, + 0xf8, 0x4e, 0x6d, 0x1a, 0xb5, 0xdd, 0x12, 0x02, + 0x57, 0x55, 0xf8, 0xab, 0x78, 0x7d, 0x75, 0x61, + 0x81, 0x20, 0xd6, 0x4b, 0x7d, 0x76, 0x05, 0xc9, + 0x56, 0xf2, 0xe9, 0x3f, 0xb6, 0xb5, 0x02, 0x2b, + 0x1c, 0x29, 0xbf, 0x07, 0xe9, 0x5f, 0x9b, 0x18, + 0x38, 0x26, 0xa0, 0x09, 0xde, 0x24, 0x5b, 0x37, + 0x72, 0x74, 0xf4, 0x9f, 0x86, 0x28, 0x89, 0xb6, + 0x0c, 0x95, 0x24, 0x2f, 0x88, 0x80, 0x6a, 0xc7, + 0x3a, 0xdc, 0x89, 0xb0, 0xa3, 0xfe, 0x6e, 0x38, + 0xec, 0x0b, 0x1d, 0xbc, 0xd5, 0x90, 0x48, 0xfb, + 0xb1, 0x54, 0xac, 0x6e, 0x35, 0xb0, 0x71, 0x9e, + 0x57, 0x07, 0x81, 0x90, 0xcb, 0x63, 0xb2, 0x7f, + 0x4c, 0x81, 0xe1, 0x58, 0xda, 0x27, 0xef, 0x77, + 0xe7, 0xde, 0x96, 0x83, 0x2a, 0xb1, 0x6b, 0x08, + 0x62, 0x89, 0xdc, 0x3a, 0x3f, 0x08, 0xff, 0xdc, + 0x50, 0x3e, 0xc1, 0xe4, 0x33, 0x8b, 0xad, 0x19, + 0x90, 0x0b, 0x8e, 0xc3, 0x55, 0x77, 0xf0, 0xc2, + 0x24, 0xf9, 0x0c, 0x99, 0x84, 0xb2, 0xcc, 0x23, + 0x8c, 0xab, 0x79, 0x0d, 0xff, 0x75, 0x3a, 0xe0, + 0xc9, 0xe8, 0x1e, 0x15, 0x02, 0xd5, 0x67, 0x8e, + 0x32, 0xe3, 0x1f, 0xda, 0xfb, 0x88, 0xeb, 0xa5, + 0x23, 0xea, 0x1d, 0xaa, 0xc3, 0x62, 0x7f, 0x27, + 0x38, 0x2a, 0xf6, 0xa2, 0x6a, 0x0e, 0x05, 0xff, + 0xe4, 0x63, 0x70, 0xec, 0xf8, 0x25, 0x96, 0x08, + 0xcb, 0x22, 0x2a, 0xaa, 0xbc, 0x45, 0x04, 0xb9, + 0xbc, 0x64, 0x07, 0x09, 0x31, 0xee, 0x5f, 0x9a, + 0xb1, 0x71, 0x85, 0x10, 0x60, 0xfb, 0x3c, 0x56, + 0xeb, 0xfe, 0x91, 0xab, 0x3f, 0x09, 0x76, 0xba, + 0x3c, 0xfc, 0xa6, 0x0d, 0xce, 0x9f, 0x59, 0xd4, + 0x83, 0x8d, 0x98, 0xf5, 0x0d, 0x60, 0x1f, 0xd1, + 0x10, 0x61, 0x77, 0x0d, 0xd1, 0xcd, 0xc2, 0xc2, + 0x2c, 0x7d, 0xf6, 0x15, 0x16, 0x90, 0xc9, 0xc5, + 0x1e, 0xe9, 0xf5, 0x7b, 0xb4, 0x49, 0x47, 0x91, + 0x6a, 0x94, 0x26, 0x94, 0xb3, 0xb5, 0xa7, 0x9e, + 0xcb, 0xb1, 0x9c, 0xb7, 0x5d, 0x25, 0x3c, 0x2d, + 0x8c, 0xa8, 0xa1, 0xb1, 0x79, 0x8e, 0x60, 0xa2, + 0x3e, 0x04, 0xfa, 0x3f, 0xb4, 0x43, 0xde, 0x0a, + 0xde, 0xf4, 0x58, 0xe7, 0xd1, 0x04, 0x1d, 0xb7, + 0x1d, 0xa6, 0xcb, 0x49, 0x41, 0x30, 0xb5, 0x41, + 0xb5, 0x14, 0x19, 0xe4, 0xeb, 0x2c, 0xe2, 0xf0, + 0x66, 0x59, 0xe3, 0xc6, 0xb0, 0xd0, 0x1e, 0xaa, + 0x9f, 0xa5, 0x0b, 0xb8, 0xfd, 0xae, 0x62, 0xcf, + 0x3e, 0xe2, 0xea, 0x79, 0xc5, 0x3e, 0xcf, 0xf0, + 0x40, 0x00, 0x8c, 0x81, 0x97, 0xed, 0xac, 0xf9, + 0x61, 0x75, 0x4e, 0xd7, 0xb7, 0xb2, 0x02, 0x14, + 0x04, 0xf6, 0xbf, 0x25, 0xbe, 0x78, 0x2a, 0xea, + 0xd2, 0x61, 0xf2, 0x7e, 0x45, 0x6b, 0x20, 0xca, +}; + +/* + * IV method encblkno1, blkno 2. + */ +static const uint8_t bf_cbc_448_encblkno1_vec2_ctxt[SECSIZE] = { + 0x35, 0x34, 0x49, 0x29, 0x12, 0x3f, 0xc6, 0x2f, + 0xc9, 0x3d, 0xc9, 0x54, 0x46, 0xf3, 0x26, 0xf9, + 0x5e, 0x45, 0xb4, 0xba, 0x6d, 0x0f, 0x98, 0x53, + 0x8b, 0x7a, 0x00, 0x47, 0xb6, 0xbd, 0x70, 0x89, + 0x60, 0x8e, 0x52, 0x0b, 0xe3, 0x0a, 0xd8, 0x0e, + 0x48, 0xf3, 0xcc, 0x66, 0x8d, 0x71, 0xaa, 0x0e, + 0xc2, 0x68, 0x03, 0x05, 0xf9, 0xef, 0x1d, 0x14, + 0x5a, 0x85, 0x88, 0x70, 0x77, 0xcf, 0xe3, 0xdf, + 0x18, 0xe5, 0xfb, 0xea, 0xe1, 0xe8, 0xe0, 0x25, + 0xb2, 0x14, 0x61, 0x5d, 0x2f, 0xce, 0x61, 0xec, + 0x68, 0xc8, 0x06, 0x60, 0x41, 0xc1, 0xe3, 0x0a, + 0x5e, 0x96, 0x15, 0x9b, 0x2c, 0x5b, 0xfd, 0xba, + 0x17, 0x2e, 0x50, 0xb6, 0x68, 0x39, 0x21, 0x56, + 0x31, 0x2e, 0xb5, 0x29, 0xff, 0x4a, 0x12, 0x34, + 0x02, 0x54, 0xb1, 0x7f, 0xd8, 0x35, 0xec, 0x79, + 0x9e, 0xef, 0x62, 0xf3, 0x4b, 0x58, 0x96, 0xf1, + 0x83, 0x26, 0x57, 0x3d, 0x55, 0xb9, 0xb0, 0xa7, + 0x48, 0x65, 0x06, 0xee, 0x14, 0x88, 0xb5, 0x58, + 0xc8, 0x4d, 0x6e, 0xd8, 0x44, 0x76, 0x21, 0x16, + 0xa4, 0xdf, 0x68, 0x4b, 0xff, 0x69, 0x23, 0x66, + 0x18, 0x75, 0xe6, 0x29, 0xea, 0x95, 0x87, 0x1c, + 0xed, 0x2d, 0xbd, 0xbf, 0x22, 0x56, 0x11, 0xd5, + 0x59, 0x90, 0x24, 0xd7, 0xae, 0xda, 0x99, 0x49, + 0xe3, 0x23, 0x03, 0x24, 0x3b, 0x02, 0x49, 0x1d, + 0xa5, 0x57, 0x2f, 0xea, 0xd1, 0x6a, 0x17, 0x53, + 0x0f, 0xb3, 0xa9, 0x64, 0x8a, 0xdb, 0x62, 0x17, + 0xad, 0x5c, 0x7d, 0x56, 0x14, 0x0f, 0xfb, 0x14, + 0xbe, 0x7e, 0xa1, 0xa8, 0x27, 0xf0, 0xf0, 0x3a, + 0xe7, 0xc5, 0x26, 0x98, 0x9d, 0x29, 0xf7, 0xfd, + 0x43, 0x13, 0x34, 0xe2, 0xb8, 0x0b, 0x14, 0xe9, + 0x79, 0x66, 0x7a, 0xf2, 0xed, 0x79, 0x37, 0x16, + 0x75, 0x2b, 0xf2, 0x99, 0xa1, 0xba, 0xf1, 0xc1, + 0x61, 0x8d, 0x78, 0x46, 0x3a, 0x67, 0x58, 0x6a, + 0x55, 0x0d, 0x2e, 0x08, 0x47, 0xfc, 0x94, 0x2f, + 0x65, 0xa1, 0x1a, 0xfe, 0x05, 0xfa, 0x41, 0x00, + 0x6c, 0x42, 0xbc, 0x65, 0x37, 0xd9, 0x25, 0x9c, + 0xf4, 0x83, 0x8a, 0xdb, 0x91, 0x96, 0xc5, 0xa9, + 0x02, 0x44, 0xbc, 0x9a, 0x26, 0x9c, 0xd1, 0xfa, + 0x06, 0x8b, 0xd6, 0x40, 0x8f, 0x0a, 0xd2, 0x5b, + 0xd8, 0x57, 0xd5, 0x61, 0x1b, 0x86, 0xa6, 0x49, + 0x15, 0xe4, 0x06, 0x6c, 0x48, 0x24, 0xb8, 0xe3, + 0x23, 0xed, 0xcf, 0x39, 0x44, 0x4d, 0xf0, 0x4e, + 0x89, 0x44, 0x0d, 0x3a, 0xe6, 0x1b, 0x7c, 0x39, + 0xfd, 0x79, 0x0e, 0x78, 0xc7, 0xf6, 0xa3, 0x91, + 0x18, 0x2a, 0xfb, 0x92, 0x48, 0xcc, 0x8b, 0xbb, + 0x33, 0x07, 0x42, 0xf5, 0xd0, 0x01, 0x8b, 0x12, + 0xd9, 0x5e, 0x9d, 0xe4, 0x13, 0x99, 0x11, 0x18, + 0x86, 0x8a, 0xb7, 0xa6, 0xe2, 0x38, 0x34, 0x12, + 0x67, 0xd6, 0x4b, 0xc0, 0x23, 0x56, 0xba, 0x53, + 0xbe, 0x20, 0xe5, 0xec, 0x16, 0xf9, 0x74, 0x92, + 0x62, 0xfc, 0xb9, 0xe8, 0xa3, 0xbf, 0x3b, 0x06, + 0x76, 0xa5, 0xf5, 0x56, 0x81, 0x72, 0x50, 0xc8, + 0x55, 0x80, 0x7d, 0xe1, 0x46, 0x92, 0xa1, 0xeb, + 0x41, 0xaf, 0xce, 0x52, 0xb1, 0xb3, 0x51, 0xf2, + 0xba, 0x03, 0xb4, 0xcb, 0x16, 0xd2, 0x92, 0x3d, + 0x0c, 0x9b, 0xe9, 0xd9, 0x5d, 0xcf, 0x79, 0x05, + 0xbd, 0xe0, 0x44, 0x39, 0xf0, 0x35, 0x2d, 0x7a, + 0x31, 0x3b, 0x24, 0xb3, 0xb4, 0xa5, 0x08, 0xf5, + 0xac, 0x51, 0xf1, 0x09, 0x52, 0x14, 0xc7, 0xb5, + 0xe0, 0x65, 0x47, 0x30, 0xdd, 0xa4, 0xfd, 0x71, + 0x68, 0xa5, 0x4b, 0x00, 0x72, 0xe2, 0xc4, 0xa9, + 0x5d, 0x21, 0x6d, 0x83, 0x4e, 0x88, 0xaa, 0x76, + 0x07, 0xf0, 0xf7, 0x36, 0xa2, 0x5e, 0xd5, 0x4c, + 0x7f, 0x9b, 0x74, 0x89, 0x0a, 0x18, 0xdc, 0x9a, +}; + +/* + * IV method encblkno1, blkno 3. + */ +static const uint8_t bf_cbc_448_encblkno1_vec3_ctxt[SECSIZE] = { + 0xc3, 0xd3, 0xae, 0x7e, 0x4f, 0xbe, 0x0d, 0x50, + 0xd6, 0x63, 0x2c, 0xa2, 0xfd, 0x07, 0xf1, 0x33, + 0x2a, 0x15, 0x8f, 0xd7, 0x63, 0xb6, 0x5f, 0x04, + 0x69, 0x90, 0xa3, 0x1a, 0xd3, 0xdd, 0xe0, 0x70, + 0xb1, 0xcd, 0xd5, 0xe0, 0x75, 0xd2, 0x31, 0x38, + 0xcc, 0x65, 0xbb, 0xc3, 0x3b, 0xc6, 0xc9, 0x33, + 0x43, 0x9c, 0x32, 0x69, 0x95, 0x10, 0x74, 0x36, + 0x3a, 0x05, 0x9c, 0x26, 0x2f, 0x80, 0x20, 0x92, + 0x74, 0x31, 0xc0, 0xf4, 0xb1, 0x42, 0x58, 0xc8, + 0x3e, 0xaa, 0xd4, 0xba, 0xba, 0x4b, 0x5f, 0x47, + 0x1a, 0x9e, 0x43, 0xaf, 0x25, 0x64, 0x0c, 0x2e, + 0xa3, 0xf5, 0xde, 0x6e, 0x28, 0x5e, 0xb9, 0x9e, + 0xc9, 0xdf, 0x85, 0xda, 0xc9, 0xa8, 0x30, 0xf9, + 0x44, 0x9b, 0x16, 0xcb, 0x4b, 0x47, 0x6f, 0x11, + 0x5c, 0xd7, 0xc9, 0xb7, 0x9c, 0x50, 0x04, 0x3b, + 0x2f, 0x13, 0xab, 0xb6, 0x72, 0xe7, 0x11, 0x29, + 0x35, 0xf3, 0xae, 0x5e, 0x2a, 0xa7, 0x1a, 0xac, + 0xb7, 0x4c, 0x7b, 0x69, 0x89, 0xfc, 0xff, 0x37, + 0x24, 0xf8, 0x65, 0xc0, 0x87, 0x89, 0x69, 0x1e, + 0xa6, 0x7e, 0xe7, 0xb3, 0xb7, 0xa8, 0x42, 0x73, + 0x83, 0xdb, 0x56, 0x4f, 0xce, 0xb9, 0x6e, 0x38, + 0x40, 0x24, 0xb8, 0xdd, 0xab, 0x25, 0x3b, 0xc6, + 0x58, 0xed, 0xc7, 0x2b, 0xe0, 0x11, 0x8b, 0x62, + 0xe8, 0x4f, 0xcf, 0xba, 0x2e, 0xd7, 0x6d, 0xf0, + 0x14, 0xa5, 0xee, 0x24, 0xd3, 0x3a, 0xb4, 0xf2, + 0xdc, 0x0d, 0x79, 0xc6, 0x14, 0x52, 0x14, 0x4b, + 0xd1, 0x8c, 0x18, 0xef, 0x1f, 0xd8, 0xe7, 0x60, + 0xf3, 0x28, 0xce, 0xf1, 0x59, 0xc8, 0x43, 0x02, + 0x0e, 0x08, 0x72, 0xe5, 0x7d, 0x5b, 0xc5, 0x80, + 0xfb, 0xca, 0x2a, 0x63, 0x8d, 0x3c, 0x54, 0x04, + 0x1e, 0xdf, 0x94, 0x53, 0xf8, 0x44, 0xe5, 0xc2, + 0x5c, 0x36, 0xc9, 0x75, 0x1c, 0xa2, 0x98, 0x3d, + 0xd6, 0xee, 0x38, 0xf9, 0xab, 0x2d, 0x1a, 0xdb, + 0x87, 0x2c, 0x86, 0xfd, 0xf9, 0xb2, 0x4d, 0x21, + 0xb7, 0xc0, 0x8f, 0x75, 0x21, 0x53, 0xc7, 0xd7, + 0x3e, 0xc6, 0x6c, 0x98, 0x2c, 0x6d, 0x44, 0x13, + 0x40, 0xea, 0xaa, 0x84, 0xd9, 0x47, 0xfd, 0x65, + 0x2c, 0x3d, 0xb0, 0x76, 0xe7, 0xdd, 0xd7, 0x06, + 0x8a, 0x79, 0xa7, 0x6c, 0x3a, 0x2d, 0x32, 0xf7, + 0xae, 0xe7, 0xd2, 0xb1, 0xf2, 0xe0, 0x3a, 0x10, + 0x19, 0xa1, 0x79, 0x7b, 0x76, 0x0b, 0xeb, 0xf3, + 0x01, 0x6e, 0x9f, 0xa1, 0x5d, 0x16, 0x09, 0xec, + 0x6b, 0x64, 0xe3, 0x96, 0xb8, 0x89, 0x99, 0x8c, + 0x77, 0xcf, 0x3f, 0x37, 0x42, 0x51, 0x82, 0x5a, + 0x63, 0x89, 0x12, 0x12, 0x59, 0x38, 0xe3, 0xcf, + 0xa0, 0xda, 0xbc, 0x69, 0x75, 0x48, 0x7c, 0x3e, + 0x56, 0x75, 0x12, 0x10, 0xc5, 0x96, 0x5b, 0x34, + 0x52, 0x2e, 0xce, 0xba, 0xd2, 0x7f, 0x8f, 0x1c, + 0xbd, 0x35, 0x3b, 0x74, 0x5b, 0x6c, 0xfe, 0xa7, + 0xf1, 0x4a, 0x07, 0x95, 0xff, 0xa8, 0xa0, 0x2a, + 0x85, 0xec, 0xd7, 0x56, 0x3b, 0x28, 0x2e, 0x09, + 0x50, 0x43, 0xbd, 0x49, 0x22, 0xdc, 0x78, 0x0e, + 0x7e, 0x68, 0x78, 0xd5, 0x57, 0xc2, 0xd6, 0x7c, + 0x2f, 0xd0, 0x4a, 0x62, 0x16, 0x38, 0x04, 0x23, + 0x43, 0x21, 0xaa, 0xe1, 0x96, 0x0e, 0xa9, 0x22, + 0xe7, 0x2c, 0xb8, 0x5e, 0x8f, 0xc6, 0x2d, 0xbd, + 0x99, 0x25, 0x33, 0xb8, 0x47, 0x99, 0x8d, 0xf5, + 0x22, 0x08, 0x9b, 0xd5, 0xad, 0x83, 0x67, 0xec, + 0x05, 0x89, 0xda, 0xd6, 0xe4, 0xe2, 0xd5, 0xef, + 0x7f, 0x61, 0x1e, 0x03, 0x81, 0x03, 0xb1, 0x98, + 0x5a, 0x29, 0x69, 0x13, 0xb2, 0xe6, 0xe1, 0x2c, + 0x66, 0x88, 0x39, 0x90, 0xf9, 0xae, 0x5d, 0x71, + 0xfe, 0x07, 0x30, 0x7d, 0xba, 0xa9, 0x37, 0xb5, + 0xff, 0x2c, 0xa9, 0xe6, 0x95, 0x48, 0xb2, 0xc8, +}; + +const struct testvec bf_cbc_448_1_vectors[] = { + { + .blkno = 0, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_448_encblkno1_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_448_encblkno1_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_448_encblkno1_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_448_encblkno1_vec3_ctxt, + }, +}; + +/* + * IV method encblkno8, blkno 0. + */ +static const uint8_t bf_cbc_448_encblkno8_vec0_ctxt[SECSIZE] = { + 0x91, 0xb4, 0x8f, 0x78, 0x34, 0xbe, 0x03, 0xe9, + 0x4b, 0xca, 0xf4, 0xfa, 0x27, 0x99, 0xa0, 0xd0, + 0xa0, 0x85, 0xf9, 0xca, 0xcc, 0x2e, 0x0d, 0x41, + 0x91, 0xdb, 0xf9, 0x71, 0xcd, 0x49, 0xf7, 0x66, + 0x9b, 0x0c, 0x70, 0x49, 0x36, 0x72, 0xf4, 0xc0, + 0x17, 0xdd, 0xd8, 0x6a, 0xd2, 0x17, 0xfe, 0x50, + 0xa3, 0x2b, 0xa8, 0x7c, 0x9c, 0x12, 0x8c, 0x08, + 0x3d, 0xb5, 0x20, 0xc0, 0x83, 0xc1, 0xf5, 0x34, + 0x4b, 0xa5, 0xcc, 0x7c, 0xc6, 0x9f, 0x4b, 0x7f, + 0x09, 0x0c, 0x04, 0xe3, 0x02, 0xfe, 0xe2, 0x5a, + 0x45, 0xee, 0x4a, 0xcb, 0xc0, 0xe1, 0xf1, 0xae, + 0x1a, 0x22, 0x95, 0xb9, 0x30, 0xe8, 0x2d, 0x90, + 0xe5, 0x6a, 0x2f, 0x0a, 0x59, 0x15, 0xfc, 0x60, + 0xa5, 0x91, 0x95, 0x1a, 0xa2, 0xf5, 0x87, 0xa3, + 0x97, 0x45, 0x1b, 0xfb, 0x78, 0x62, 0x8b, 0xb6, + 0x86, 0xc6, 0x94, 0x9a, 0x9d, 0x09, 0x46, 0xc9, + 0x1f, 0x5f, 0x2e, 0x6c, 0xed, 0x5e, 0xe2, 0xab, + 0xca, 0x30, 0xdb, 0x13, 0x37, 0x8d, 0xb7, 0xc6, + 0xce, 0x74, 0xe3, 0xe2, 0x64, 0x7b, 0x74, 0x3e, + 0x9f, 0x18, 0x4e, 0xe2, 0x2b, 0x52, 0x08, 0x60, + 0x2b, 0x6d, 0x17, 0x1a, 0xff, 0xae, 0xfb, 0xea, + 0x59, 0x1d, 0x45, 0xe8, 0xf9, 0x0c, 0x56, 0xb8, + 0xb5, 0xc7, 0x8f, 0xa7, 0x9e, 0x67, 0x87, 0xbb, + 0xe2, 0x37, 0x56, 0x49, 0xed, 0x75, 0x27, 0x54, + 0xb5, 0x16, 0x34, 0xb6, 0xa6, 0xe0, 0x27, 0x48, + 0x91, 0xfb, 0x80, 0x4f, 0x5e, 0xef, 0x40, 0x6d, + 0x28, 0x8f, 0x2e, 0x56, 0xab, 0x6c, 0x7d, 0xde, + 0xbd, 0xa5, 0xa6, 0x47, 0xe2, 0xc9, 0xb0, 0xc5, + 0x69, 0x5d, 0x57, 0x18, 0x59, 0x08, 0x66, 0x1b, + 0xdc, 0x4f, 0xa4, 0xe2, 0xb5, 0xff, 0x72, 0x4d, + 0x25, 0x79, 0x38, 0x8f, 0xca, 0x23, 0x81, 0x31, + 0x1d, 0xeb, 0x7b, 0x7e, 0x04, 0xc3, 0xa6, 0xac, + 0x12, 0x92, 0x95, 0x44, 0x08, 0xae, 0x25, 0xb5, + 0xc2, 0x39, 0x88, 0x28, 0xc5, 0xc7, 0x3c, 0xfe, + 0x95, 0xe1, 0x1a, 0x27, 0xbe, 0xfd, 0x0a, 0xc7, + 0xd1, 0x02, 0x1a, 0xae, 0x03, 0xfb, 0xce, 0x79, + 0xe6, 0xea, 0x4a, 0xa1, 0x0e, 0x68, 0x61, 0x2f, + 0xfa, 0x7a, 0xb8, 0xda, 0xd1, 0x4a, 0xbe, 0x88, + 0xd2, 0xa0, 0x6b, 0x90, 0xc3, 0x37, 0x18, 0x77, + 0x2e, 0xc8, 0x44, 0x2e, 0x9d, 0xa2, 0x4a, 0xc7, + 0x54, 0xb2, 0x38, 0x9b, 0x60, 0x5e, 0x5b, 0xb0, + 0x31, 0x4c, 0x10, 0xf0, 0x1d, 0x8c, 0xab, 0x9b, + 0x25, 0x86, 0x05, 0xfc, 0xd9, 0x39, 0x11, 0x2b, + 0x7e, 0x07, 0xfd, 0x6b, 0xb3, 0x28, 0x57, 0x66, + 0x94, 0xc6, 0xfc, 0x48, 0x71, 0xeb, 0x7b, 0x9a, + 0x26, 0x8f, 0x9f, 0x97, 0xb6, 0x83, 0x9a, 0xdc, + 0x5d, 0x84, 0x96, 0x9d, 0xe3, 0xa5, 0x12, 0x97, + 0x8c, 0x87, 0xa6, 0x2a, 0xa8, 0x15, 0x9a, 0xb0, + 0x0e, 0x31, 0x55, 0xf7, 0x1b, 0x5c, 0x9c, 0xaf, + 0x13, 0x20, 0x13, 0x50, 0xaf, 0xc9, 0xf4, 0xd9, + 0x47, 0x16, 0xcc, 0x9d, 0xec, 0xa9, 0x2d, 0xfc, + 0x3d, 0x5d, 0x48, 0x89, 0x86, 0x91, 0x6f, 0x1a, + 0xa5, 0xf0, 0xb6, 0x9b, 0xa9, 0x08, 0xf2, 0x05, + 0xad, 0xe5, 0xe0, 0xd8, 0x2e, 0x09, 0xbe, 0x3a, + 0xf2, 0xdc, 0xeb, 0x14, 0xe6, 0x8c, 0x21, 0x20, + 0xbb, 0x42, 0x6a, 0xba, 0x55, 0x79, 0x54, 0x8b, + 0xa8, 0x43, 0x14, 0x28, 0x66, 0xd2, 0x44, 0x65, + 0x9c, 0xa9, 0xdc, 0x3b, 0x3f, 0xab, 0x36, 0xb4, + 0xbc, 0x9d, 0x22, 0x92, 0x24, 0xa8, 0x29, 0x18, + 0x98, 0x3a, 0xbe, 0xa1, 0xb4, 0xf8, 0x7f, 0xea, + 0x2f, 0x58, 0x69, 0xce, 0xee, 0x99, 0x76, 0x2c, + 0x53, 0x84, 0xf5, 0x9e, 0xa3, 0x98, 0xe6, 0x94, + 0x39, 0xfa, 0xfa, 0x6d, 0x66, 0xe2, 0x39, 0x2b, + 0x4b, 0x84, 0x14, 0x89, 0x18, 0xa2, 0x03, 0xdd, +}; + +/* + * IV method encblkno8, blkno 1. + */ +static const uint8_t bf_cbc_448_encblkno8_vec1_ctxt[SECSIZE] = { + 0x90, 0x3d, 0xee, 0x58, 0xf7, 0xe3, 0xc4, 0x18, + 0xaf, 0xfa, 0xaf, 0xed, 0x9a, 0x45, 0xe7, 0xa8, + 0xbe, 0xcd, 0x0f, 0xb9, 0x53, 0x18, 0xc6, 0x14, + 0xbe, 0xbb, 0x90, 0x1c, 0x5c, 0x60, 0x93, 0xcb, + 0x62, 0xb3, 0xdb, 0x31, 0x19, 0x39, 0xce, 0x3f, + 0xe4, 0x8f, 0x44, 0xc1, 0x10, 0x80, 0x05, 0x6b, + 0x77, 0xe3, 0xe1, 0xe5, 0xd2, 0x6d, 0x93, 0xf2, + 0xb3, 0x81, 0x03, 0xf8, 0xbc, 0x7b, 0x5a, 0x71, + 0x15, 0x16, 0x3a, 0x2f, 0x03, 0xbb, 0x67, 0x6a, + 0xd9, 0xf5, 0x63, 0x6f, 0x3d, 0x75, 0x1b, 0x0a, + 0x4b, 0x9d, 0x04, 0x11, 0x7e, 0xe8, 0x3e, 0x2d, + 0x04, 0x8f, 0xbf, 0x8a, 0xb2, 0x35, 0x76, 0xc5, + 0xcc, 0x6d, 0x9e, 0x99, 0x71, 0x13, 0xf6, 0x5e, + 0xeb, 0x74, 0x96, 0x8a, 0x29, 0x38, 0x0b, 0x25, + 0x4b, 0x89, 0xa9, 0x43, 0x3c, 0x2f, 0x03, 0x14, + 0x8d, 0x0f, 0xe3, 0xe7, 0x01, 0xd1, 0x2e, 0x14, + 0x08, 0x51, 0xba, 0x06, 0x39, 0x76, 0x35, 0xbc, + 0x14, 0xa6, 0x16, 0x36, 0x47, 0xcc, 0x48, 0xe0, + 0xd6, 0xd7, 0x07, 0xb0, 0xf0, 0x30, 0x6c, 0xf8, + 0x68, 0x9d, 0x6c, 0x4b, 0x69, 0x33, 0x78, 0x0e, + 0x4a, 0xfa, 0x97, 0xfb, 0x0c, 0x0d, 0x0a, 0xc3, + 0x4b, 0x7b, 0x77, 0x77, 0x18, 0x9a, 0x74, 0x85, + 0x2f, 0xae, 0xc7, 0x90, 0x45, 0x4b, 0xa2, 0x06, + 0x3e, 0xa2, 0x48, 0xe7, 0x6c, 0x86, 0x65, 0x78, + 0x97, 0x0b, 0x97, 0xc1, 0x70, 0x91, 0x12, 0x79, + 0xae, 0xf0, 0x2b, 0x44, 0xe9, 0x84, 0x8d, 0x78, + 0x53, 0xf8, 0x3a, 0xf5, 0x9f, 0x27, 0x3d, 0x49, + 0x69, 0xd1, 0x18, 0xa4, 0xb2, 0xd0, 0xbb, 0xf2, + 0x57, 0x76, 0xb7, 0x77, 0x16, 0x2f, 0xf8, 0x0c, + 0xa5, 0x86, 0x43, 0x0d, 0x2d, 0xfe, 0x84, 0xc6, + 0xbb, 0x58, 0x81, 0x47, 0x3d, 0xa3, 0x93, 0xb0, + 0x50, 0xfc, 0x25, 0xf7, 0xc5, 0x05, 0xe5, 0xf2, + 0xb3, 0x79, 0x12, 0xe4, 0x37, 0x71, 0x2d, 0xe8, + 0xa5, 0x0b, 0xce, 0x67, 0x51, 0x4f, 0xab, 0xc7, + 0x7b, 0x3b, 0xac, 0x78, 0x97, 0x82, 0x02, 0xf4, + 0x62, 0x20, 0x1b, 0x8b, 0xac, 0x07, 0x3b, 0xd7, + 0x0b, 0x99, 0x27, 0x85, 0x52, 0x7a, 0x79, 0x18, + 0xfb, 0x81, 0x3a, 0x05, 0x76, 0x6c, 0x3c, 0x6a, + 0x35, 0xe1, 0x2b, 0x03, 0x48, 0x70, 0x1a, 0xa8, + 0x30, 0x33, 0x61, 0xe2, 0xd8, 0x99, 0x86, 0x7f, + 0xfd, 0xe0, 0x4a, 0xe4, 0x62, 0xa1, 0xac, 0xcb, + 0xb8, 0x8a, 0xf3, 0xaa, 0xd6, 0x61, 0x9d, 0xc5, + 0xdb, 0xf5, 0x53, 0x39, 0x1d, 0xd7, 0xf8, 0x96, + 0xc6, 0x2b, 0xca, 0xbf, 0x83, 0x4e, 0x89, 0x63, + 0x53, 0x6f, 0x17, 0xaa, 0xf3, 0x61, 0x9b, 0x75, + 0x8c, 0x5a, 0xf8, 0x21, 0x84, 0x52, 0xb8, 0x76, + 0xbc, 0xf5, 0x9b, 0xd6, 0x98, 0x26, 0x58, 0xec, + 0xdd, 0xa8, 0xf1, 0xee, 0x9e, 0x14, 0x24, 0x94, + 0x7c, 0xb6, 0x45, 0x8b, 0xc7, 0x85, 0x50, 0x4e, + 0x30, 0xd7, 0x51, 0x8c, 0x33, 0xeb, 0xeb, 0x5d, + 0x52, 0x58, 0x43, 0xcb, 0x25, 0x4a, 0x77, 0x34, + 0xe6, 0x70, 0x5b, 0x6f, 0x8f, 0xe8, 0x07, 0xee, + 0x76, 0x4a, 0xad, 0xab, 0x11, 0x8a, 0x1b, 0x92, + 0x60, 0x79, 0xb8, 0xe0, 0x88, 0xa7, 0x3a, 0xe0, + 0x15, 0xf6, 0x57, 0xf0, 0xe8, 0x87, 0xda, 0xf8, + 0x90, 0x4e, 0xe7, 0xb3, 0xb4, 0xe7, 0x73, 0x5c, + 0xd3, 0x69, 0xfb, 0x23, 0x4f, 0x4f, 0xc8, 0xd2, + 0xfb, 0xf5, 0xf5, 0x76, 0x80, 0xb6, 0xb7, 0xe2, + 0xb7, 0x96, 0x1a, 0x97, 0x12, 0x40, 0x16, 0x86, + 0xd6, 0x66, 0xf5, 0x46, 0x9e, 0x04, 0x62, 0xaa, + 0x9c, 0xc9, 0x45, 0x39, 0x5c, 0xd3, 0x58, 0x40, + 0xb4, 0x32, 0xd8, 0x6c, 0x19, 0xfa, 0xa5, 0x5f, + 0x1e, 0x83, 0x5a, 0x32, 0x5e, 0x1d, 0xab, 0xa9, + 0x48, 0x1b, 0x1b, 0x37, 0x66, 0xf8, 0x67, 0xd7, +}; + +/* + * IV method encblkno8, blkno 2. + */ +static const uint8_t bf_cbc_448_encblkno8_vec2_ctxt[SECSIZE] = { + 0xb3, 0x2d, 0x0d, 0x90, 0x7a, 0x50, 0xb6, 0x29, + 0x9d, 0xd4, 0x12, 0x1a, 0xc9, 0x71, 0x56, 0xc4, + 0xce, 0x3d, 0x74, 0xf9, 0x91, 0xe4, 0x79, 0x8a, + 0x42, 0x34, 0x1a, 0xd4, 0x84, 0xaa, 0x01, 0x85, + 0x13, 0xe8, 0xab, 0xaa, 0xb6, 0x81, 0x82, 0xd6, + 0x32, 0xd6, 0x9f, 0x63, 0x69, 0x55, 0x10, 0x5f, + 0x2e, 0xb3, 0x51, 0x74, 0x80, 0x5c, 0xe9, 0x8d, + 0x27, 0xd8, 0x41, 0x2d, 0x27, 0x07, 0xb4, 0x13, + 0xcd, 0xc0, 0xb3, 0x96, 0xaa, 0x59, 0x9c, 0x3e, + 0x16, 0x9e, 0x18, 0xa5, 0x92, 0x52, 0x59, 0x19, + 0x19, 0x62, 0xeb, 0xd9, 0xdf, 0x9d, 0x10, 0x77, + 0xfb, 0x3c, 0xf1, 0xeb, 0x70, 0xf6, 0x6a, 0x9b, + 0xad, 0x99, 0x35, 0xd7, 0xf8, 0xde, 0x2b, 0x52, + 0x85, 0xdd, 0x36, 0x07, 0x3a, 0x88, 0xa6, 0xbb, + 0x98, 0x7a, 0xe3, 0xb0, 0xe6, 0xae, 0x33, 0x5d, + 0x47, 0x0c, 0x6c, 0xd4, 0x84, 0x33, 0x7e, 0xf4, + 0xea, 0xfd, 0xf1, 0x1c, 0xdb, 0x8b, 0xfe, 0x01, + 0x77, 0xa3, 0x07, 0x21, 0x09, 0xac, 0x0c, 0xe4, + 0x63, 0xaa, 0x3d, 0xb3, 0x05, 0xf8, 0x73, 0x03, + 0x69, 0x53, 0x2f, 0xd3, 0x53, 0x29, 0xf2, 0x02, + 0x60, 0x41, 0xed, 0xc7, 0xe9, 0x2e, 0xba, 0x54, + 0xa4, 0xfe, 0x26, 0xf0, 0xd9, 0x2c, 0x58, 0x2d, + 0x90, 0x94, 0x19, 0xf9, 0xe5, 0xaa, 0xe2, 0x13, + 0x9a, 0x67, 0x90, 0x44, 0x61, 0x36, 0xd0, 0x3f, + 0xe7, 0xe8, 0x7e, 0x47, 0x2b, 0x84, 0x97, 0xe2, + 0x0b, 0x8a, 0xfa, 0x2f, 0xbc, 0x1a, 0x70, 0xed, + 0xb2, 0x93, 0x36, 0x0e, 0xe6, 0xb1, 0xa2, 0x5a, + 0x04, 0x04, 0x8d, 0x2f, 0x82, 0xdb, 0x49, 0x5e, + 0x1b, 0x90, 0xc1, 0x27, 0x2a, 0x2f, 0x64, 0x5b, + 0xce, 0x35, 0x06, 0x0d, 0xb6, 0x05, 0x50, 0x5a, + 0x90, 0xc8, 0x21, 0xd0, 0xf0, 0xb9, 0xf3, 0x43, + 0x25, 0xd8, 0xb9, 0x86, 0xb7, 0xd0, 0x29, 0x75, + 0xdc, 0xf6, 0xf6, 0x14, 0x5e, 0x1f, 0xad, 0x54, + 0x28, 0x63, 0x92, 0xcd, 0xcd, 0x75, 0xb2, 0xe8, + 0xf3, 0x1f, 0xfd, 0x88, 0x72, 0x04, 0xab, 0xe2, + 0x77, 0x21, 0xc1, 0xb4, 0x87, 0xa7, 0x98, 0x86, + 0x2d, 0x7f, 0x01, 0x24, 0xed, 0x3a, 0x23, 0x83, + 0xb7, 0xa4, 0xb7, 0x08, 0x4e, 0xee, 0x10, 0x77, + 0x29, 0x22, 0xab, 0xea, 0x4a, 0x68, 0x1f, 0x7f, + 0xd6, 0xe6, 0x90, 0x11, 0xbc, 0x23, 0x2e, 0x47, + 0x78, 0xea, 0x1d, 0x33, 0x7c, 0x02, 0x09, 0x55, + 0x7a, 0xbc, 0xa7, 0x3d, 0x9a, 0xd0, 0x4d, 0x40, + 0x6c, 0xc2, 0x99, 0xc2, 0xe9, 0x0e, 0xcf, 0x06, + 0x82, 0x61, 0x5c, 0x76, 0xca, 0xef, 0x8f, 0xd3, + 0x78, 0x2a, 0xae, 0x39, 0x29, 0x4e, 0xc1, 0x2c, + 0xb1, 0xbc, 0xcd, 0x76, 0x4f, 0x25, 0xf0, 0x5b, + 0x78, 0x3a, 0xa4, 0x39, 0x52, 0x5a, 0xc7, 0xcf, + 0x17, 0x3d, 0xb0, 0x39, 0x63, 0xf9, 0xf9, 0xfb, + 0x6f, 0x35, 0xb7, 0xf1, 0x49, 0x10, 0xd8, 0x12, + 0x8d, 0xa2, 0xdf, 0xc5, 0x26, 0x37, 0xd1, 0xb8, + 0xef, 0xdc, 0x04, 0x1b, 0x0d, 0x60, 0xbf, 0xbc, + 0xc0, 0xff, 0x56, 0x8b, 0xd3, 0x6e, 0x71, 0xfc, + 0x87, 0x00, 0x86, 0x10, 0x78, 0x3b, 0xce, 0x8b, + 0xe8, 0x5f, 0x8c, 0xce, 0x03, 0xa2, 0x89, 0x8c, + 0x16, 0x00, 0x0e, 0xd8, 0x53, 0xaf, 0x7f, 0x77, + 0x78, 0x40, 0x5e, 0x5e, 0xd1, 0x7d, 0xf8, 0x41, + 0xa8, 0x1e, 0xa5, 0xe5, 0xe9, 0xd6, 0x17, 0x2c, + 0x2f, 0x1b, 0xff, 0xef, 0xf5, 0x53, 0x31, 0xf3, + 0x5b, 0xe4, 0x84, 0x7c, 0xe2, 0x45, 0x3c, 0x82, + 0x5b, 0xf6, 0x03, 0x35, 0xdd, 0x03, 0x22, 0xbe, + 0x77, 0x9c, 0x6a, 0x7d, 0xc8, 0x29, 0x41, 0x53, + 0xbb, 0xab, 0x6e, 0xa5, 0x00, 0xaf, 0x3b, 0x1d, + 0x76, 0x12, 0xac, 0x44, 0x5c, 0x7d, 0xd2, 0x3b, + 0x3a, 0x95, 0xb0, 0xa9, 0x4f, 0x27, 0x76, 0x17, +}; + +/* + * IV method encblkno8, blkno 3. + */ +static const uint8_t bf_cbc_448_encblkno8_vec3_ctxt[SECSIZE] = { + 0x8e, 0xc4, 0x56, 0x64, 0x1e, 0x2a, 0x0d, 0x60, + 0x54, 0x5c, 0xcd, 0xe0, 0x6d, 0xa7, 0x4c, 0x30, + 0x7e, 0x85, 0x21, 0xdf, 0xaa, 0xb2, 0x32, 0xde, + 0xc0, 0xc6, 0x56, 0xe0, 0x43, 0xc2, 0x3e, 0x6c, + 0x8c, 0x62, 0x35, 0xaa, 0xf9, 0xba, 0xc9, 0x52, + 0x38, 0x72, 0x06, 0xcc, 0x02, 0xa2, 0xb8, 0x85, + 0xf7, 0xcc, 0xe6, 0x8c, 0x86, 0x8f, 0x9c, 0xd6, + 0x1f, 0xf8, 0x24, 0x9d, 0xca, 0xe8, 0xed, 0x3c, + 0x80, 0x0b, 0xaf, 0x0c, 0x78, 0x4f, 0x5b, 0x2a, + 0x0f, 0xfe, 0xe5, 0xe6, 0x12, 0x8a, 0xff, 0xc7, + 0x6a, 0x97, 0xd9, 0xcb, 0xc8, 0x6a, 0x83, 0x12, + 0xa1, 0x12, 0x84, 0xc8, 0x72, 0x1c, 0xb7, 0x68, + 0x23, 0x24, 0xff, 0x5a, 0x78, 0x99, 0x9d, 0xb8, + 0x03, 0x70, 0x0a, 0x09, 0xa1, 0x3d, 0xfe, 0xe0, + 0xc5, 0x1b, 0xea, 0x58, 0xbc, 0x52, 0x70, 0xa2, + 0x4e, 0xcc, 0x43, 0xfb, 0xb7, 0xc4, 0xbd, 0xb6, + 0xa9, 0x1e, 0xff, 0xf6, 0x69, 0xaa, 0xab, 0xa4, + 0xd7, 0x07, 0x0d, 0xda, 0x41, 0x4b, 0xe3, 0xa5, + 0xef, 0x94, 0x9f, 0xb4, 0xd8, 0xd1, 0x41, 0xd0, + 0x9e, 0xa0, 0x0a, 0x70, 0xdb, 0xb8, 0x5e, 0x27, + 0xc6, 0x08, 0x38, 0x6a, 0x31, 0xe3, 0xa0, 0xd6, + 0x90, 0xad, 0x19, 0x0c, 0x7e, 0x1d, 0x21, 0xc8, + 0x66, 0x30, 0x73, 0x8e, 0x06, 0x97, 0xec, 0xc6, + 0xfe, 0x5c, 0xc6, 0xc0, 0xd1, 0x5c, 0x5f, 0xf8, + 0x01, 0xb3, 0xac, 0x18, 0x66, 0x1e, 0x04, 0xaf, + 0xa7, 0xd3, 0x6d, 0x10, 0x74, 0xa1, 0x9a, 0x36, + 0x10, 0xa0, 0xd6, 0x28, 0x61, 0x93, 0x98, 0x14, + 0x67, 0x6f, 0x7d, 0x52, 0x86, 0x48, 0x17, 0x99, + 0x53, 0xa3, 0xee, 0xe5, 0x93, 0xf6, 0x80, 0xe1, + 0x52, 0xf0, 0x39, 0x48, 0x5c, 0x20, 0x05, 0xd9, + 0xae, 0xa2, 0xe3, 0x25, 0x4e, 0x60, 0x84, 0xf8, + 0xad, 0xd6, 0xf6, 0x95, 0x8e, 0x95, 0xd0, 0x49, + 0x1c, 0x65, 0xd0, 0xc8, 0xa5, 0x26, 0xc0, 0xdf, + 0x32, 0xbe, 0xbc, 0xb7, 0x6d, 0xe5, 0x5e, 0x6d, + 0x38, 0x7d, 0x03, 0xd5, 0x94, 0x7a, 0x14, 0x2b, + 0x02, 0xe0, 0x09, 0x00, 0x50, 0xf1, 0x52, 0x69, + 0x06, 0x33, 0x4b, 0x5b, 0xa2, 0xbc, 0x2e, 0xa9, + 0x1a, 0xb7, 0xca, 0xa8, 0xb4, 0xa2, 0x5b, 0xcd, + 0x35, 0xe4, 0x03, 0xdd, 0x8f, 0x66, 0x3a, 0x34, + 0xc6, 0x2a, 0xd6, 0x90, 0xa2, 0xef, 0xe2, 0xfa, + 0x7c, 0xc1, 0x6c, 0x21, 0xd0, 0xfd, 0x96, 0x92, + 0xb5, 0x99, 0xe4, 0xb7, 0x66, 0xd4, 0xf2, 0x50, + 0x22, 0xef, 0x66, 0x1e, 0x5f, 0x62, 0xd1, 0x77, + 0x87, 0x52, 0xed, 0x40, 0x69, 0xfd, 0xab, 0x66, + 0xe4, 0x0e, 0x2b, 0xa8, 0x67, 0x4c, 0x6d, 0xce, + 0xb0, 0x61, 0x8e, 0x6c, 0xc5, 0x34, 0xab, 0x03, + 0x3e, 0x8a, 0xe5, 0x2b, 0xa2, 0xa4, 0x04, 0xa2, + 0x01, 0x81, 0x79, 0x72, 0xfc, 0x19, 0xbd, 0x38, + 0x39, 0xee, 0xb3, 0x95, 0xc5, 0x6f, 0xed, 0xaa, + 0x6e, 0xca, 0xeb, 0xc6, 0xaf, 0xeb, 0x76, 0xb4, + 0xd7, 0xc3, 0x1b, 0x65, 0x99, 0xc6, 0xa3, 0xe8, + 0x96, 0x5e, 0xc1, 0x0c, 0xd2, 0xf8, 0x65, 0xcf, + 0x42, 0xc5, 0x8f, 0x52, 0x5d, 0x90, 0x21, 0x55, + 0xec, 0x9d, 0x93, 0x81, 0xb7, 0x9a, 0xa4, 0x35, + 0xe7, 0xef, 0xef, 0x2d, 0x4c, 0x02, 0xf7, 0x2b, + 0x26, 0xe0, 0x9e, 0x3a, 0x31, 0xfd, 0x94, 0xb3, + 0xa7, 0x8a, 0x93, 0xf3, 0xe1, 0x77, 0x79, 0xdf, + 0xcf, 0x1f, 0x99, 0x55, 0x20, 0xc3, 0x7d, 0x8a, + 0xbc, 0xff, 0x63, 0x64, 0x87, 0xa9, 0x42, 0x63, + 0xc9, 0x67, 0x7e, 0x51, 0x99, 0x9c, 0xcb, 0x47, + 0xa9, 0xc8, 0x5e, 0x83, 0x87, 0x55, 0x7c, 0x45, + 0x3a, 0xb4, 0xfe, 0x97, 0x24, 0x17, 0x1d, 0x5e, + 0xdf, 0xe0, 0xe8, 0x17, 0xa6, 0x31, 0x99, 0xeb, + 0xb7, 0xb5, 0xd5, 0xd7, 0x7c, 0x2f, 0x22, 0x26, +}; + +const struct testvec bf_cbc_448_8_vectors[] = { + { + .blkno = 0, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_448_encblkno8_vec0_ctxt, + }, + { + .blkno = 1, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_448_encblkno8_vec1_ctxt, + }, + { + .blkno = 2, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_448_encblkno8_vec2_ctxt, + }, + { + .blkno = 3, + .ptxt = bf_cbc_ptxt, + .ctxt = bf_cbc_448_encblkno8_vec3_ctxt, + }, +}; + +static int +open_disk(const char *devpath, const char *imgpath, size_t size) +{ + int fd; + + fd = open(imgpath, O_CREAT | O_RDWR | O_TRUNC, 0600); + if (fd < 0) + return -1; + + if (ftruncate(fd, size) < 0) + goto fail; + + if (rump_pub_etfs_register_withsize(devpath, + imgpath, RUMP_ETFS_BLK, 0, size) < 0) { + goto fail; + } + + unlink(imgpath); + return fd; +fail: + close(fd); + unlink(imgpath); + return -1; +} + +static int +open_cgd(int devno) +{ + char devpath[32]; + + sprintf(devpath, "/dev/rcgd%d%c", devno, getrawpartition() + 'a'); + + return rump_sys_open(devpath, O_RDWR, 0); +} + +static int +configure_cgd(int fd, const char *dkpath, const char *alg, + const char *ivmethod, const char *key, size_t keylen) +{ + struct cgd_ioctl ci; + + memset(&ci, 0, sizeof(ci)); + ci.ci_disk = dkpath; + ci.ci_alg = alg; + ci.ci_ivmethod = ivmethod; + ci.ci_keylen = 8 * keylen - 8; /* Exclude the NUL terminator. */ + ci.ci_key = key; + ci.ci_blocksize = 64; + + return rump_sys_ioctl(fd, CGDIOCSET, &ci); +} + +static int +unconfigure_cgd(int fd) +{ + struct cgd_ioctl ci; + + return rump_sys_ioctl(fd, CGDIOCCLR, &ci); +} + +static int +write_testvec(int cgdfd, const struct testvec *tv) +{ + + if (rump_sys_lseek(cgdfd, tv->blkno * SECSIZE, SEEK_SET) < 0) + return -1; + + if (rump_sys_write(cgdfd, tv->ptxt, SECSIZE) != SECSIZE) + return -1; + + return 0; +} + +static int +read_testvec(int cgdfd, const struct testvec *tv) +{ + char *buf; + int res = -1; + + buf = malloc(SECSIZE); + if (buf == NULL) + return -1; + + if (rump_sys_lseek(cgdfd, tv->blkno * SECSIZE, SEEK_SET) < 0) + goto fail; + + if (rump_sys_read(cgdfd, buf, SECSIZE) != SECSIZE) + goto fail; + + res = memcmp(buf, tv->ptxt, SECSIZE); +fail: + free(buf); + return res; +} + +static int +check_testvec(int dkfd, const struct testvec *tv) +{ + char *buf; + int res = -1; + + buf = malloc(SECSIZE); + if (buf == NULL) + return -1; + + if (lseek(dkfd, tv->blkno * SECSIZE, SEEK_SET) < 0) + goto fail; + + if (read(dkfd, buf, SECSIZE) != SECSIZE) + goto fail; + + res = memcmp(buf, tv->ctxt, SECSIZE); +fail: + free(buf); + return res; +} + +ATF_TC(cgd_bf_cbc_128_encblkno1); +ATF_TC_HEAD(cgd_bf_cbc_128_encblkno1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test blowfish-cbc with 128 bits key, ivmethod encblkno1"); +} + +ATF_TC_BODY(cgd_bf_cbc_128_encblkno1, tc) +{ + const char imgpath[] = "blowfish-cbc-128-encblkno1.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "blowfish-cbc", "encblkno1", + bf_cbc_128_key, sizeof(bf_cbc_128_key))); + + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_128_1_vectors[0]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_128_1_vectors[1]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_128_1_vectors[2]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_128_1_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "blowfish-cbc", "encblkno1", + bf_cbc_128_key, sizeof(bf_cbc_128_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_128_1_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_128_1_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_128_1_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_128_1_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_128_1_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_128_1_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_128_1_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_128_1_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_bf_cbc_128_encblkno8); +ATF_TC_HEAD(cgd_bf_cbc_128_encblkno8, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test blowfish-cbc with 128 bits key, ivmethod encblkno8"); +} + +ATF_TC_BODY(cgd_bf_cbc_128_encblkno8, tc) +{ + const char imgpath[] = "blowfish-cbc-128-encblkno8.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "blowfish-cbc", "encblkno8", + bf_cbc_128_key, sizeof(bf_cbc_128_key))); + + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_128_8_vectors[0]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_128_8_vectors[1]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_128_8_vectors[2]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_128_8_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "blowfish-cbc", "encblkno8", + bf_cbc_128_key, sizeof(bf_cbc_128_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_128_8_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_128_8_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_128_8_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_128_8_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_128_8_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_128_8_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_128_8_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_128_8_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_bf_cbc_256_encblkno1); +ATF_TC_HEAD(cgd_bf_cbc_256_encblkno1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test blowfish-cbc with 256 bits key, ivmethod encblkno1"); +} + +ATF_TC_BODY(cgd_bf_cbc_256_encblkno1, tc) +{ + const char imgpath[] = "blowfish-cbc-256-encblkno1.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "blowfish-cbc", "encblkno1", + bf_cbc_256_key, sizeof(bf_cbc_256_key))); + + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_256_1_vectors[0]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_256_1_vectors[1]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_256_1_vectors[2]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_256_1_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "blowfish-cbc", "encblkno1", + bf_cbc_256_key, sizeof(bf_cbc_256_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_256_1_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_256_1_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_256_1_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_256_1_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_256_1_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_256_1_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_256_1_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_256_1_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_bf_cbc_256_encblkno8); +ATF_TC_HEAD(cgd_bf_cbc_256_encblkno8, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test blowfish-cbc with 256 bits key, ivmethod encblkno8"); +} + +ATF_TC_BODY(cgd_bf_cbc_256_encblkno8, tc) +{ + const char imgpath[] = "blowfish-cbc-256-encblkno8.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "blowfish-cbc", "encblkno8", + bf_cbc_256_key, sizeof(bf_cbc_256_key))); + + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_256_8_vectors[0]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_256_8_vectors[1]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_256_8_vectors[2]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_256_8_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "blowfish-cbc", "encblkno8", + bf_cbc_256_key, sizeof(bf_cbc_256_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_256_8_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_256_8_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_256_8_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_256_8_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_256_8_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_256_8_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_256_8_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_256_8_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_bf_cbc_448_encblkno1); +ATF_TC_HEAD(cgd_bf_cbc_448_encblkno1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test blowfish-cbc with 448 bits key, ivmethod encblkno1"); +} + +ATF_TC_BODY(cgd_bf_cbc_448_encblkno1, tc) +{ + const char imgpath[] = "blowfish-cbc-448-encblkno1.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "blowfish-cbc", "encblkno1", + bf_cbc_448_key, sizeof(bf_cbc_448_key))); + + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_448_1_vectors[0]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_448_1_vectors[1]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_448_1_vectors[2]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_448_1_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "blowfish-cbc", "encblkno1", + bf_cbc_448_key, sizeof(bf_cbc_448_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_448_1_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_448_1_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_448_1_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_448_1_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_448_1_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_448_1_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_448_1_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_448_1_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TC(cgd_bf_cbc_448_encblkno8); +ATF_TC_HEAD(cgd_bf_cbc_448_encblkno8, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test blowfish-cbc with 448 bits key, ivmethod encblkno8"); +} + +ATF_TC_BODY(cgd_bf_cbc_448_encblkno8, tc) +{ + const char imgpath[] = "blowfish-cbc-448-encblkno8.img"; + const char *dkpath = "/dev/dk"; + const size_t dksize = 4 * SECSIZE; /* Last blkno is 3. */ + int dkfd, cgdfd; + + rump_init(); + + RL(dkfd = open_disk(dkpath, imgpath, dksize)); + + RL(cgdfd = open_cgd(0)); + RL(configure_cgd(cgdfd, dkpath, "blowfish-cbc", "encblkno8", + bf_cbc_448_key, sizeof(bf_cbc_448_key))); + + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_448_8_vectors[0]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_448_8_vectors[1]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_448_8_vectors[2]), 0); + ATF_CHECK_EQ(write_testvec(cgdfd, &bf_cbc_448_8_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(configure_cgd(cgdfd, dkpath, "blowfish-cbc", "encblkno8", + bf_cbc_448_key, sizeof(bf_cbc_448_key))); + + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_448_8_vectors[0]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_448_8_vectors[1]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_448_8_vectors[2]), 0); + ATF_CHECK_EQ(read_testvec(cgdfd, &bf_cbc_448_8_vectors[3]), 0); + + RL(unconfigure_cgd(cgdfd)); + RL(rump_sys_close(cgdfd)); + + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_448_8_vectors[0]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_448_8_vectors[1]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_448_8_vectors[2]), 0); + ATF_CHECK_EQ(check_testvec(dkfd, &bf_cbc_448_8_vectors[3]), 0); + + RL(close(dkfd)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cgd_bf_cbc_128_encblkno1); + ATF_TP_ADD_TC(tp, cgd_bf_cbc_128_encblkno8); + ATF_TP_ADD_TC(tp, cgd_bf_cbc_256_encblkno1); + ATF_TP_ADD_TC(tp, cgd_bf_cbc_256_encblkno8); + ATF_TP_ADD_TC(tp, cgd_bf_cbc_448_encblkno1); + ATF_TP_ADD_TC(tp, cgd_bf_cbc_448_encblkno8); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/dev/clock_subr/clock_subr_test_data_gen.sh b/contrib/netbsd-tests/dev/clock_subr/clock_subr_test_data_gen.sh new file mode 100755 index 0000000..2da21a8 --- /dev/null +++ b/contrib/netbsd-tests/dev/clock_subr/clock_subr_test_data_gen.sh @@ -0,0 +1,25 @@ +#!/bin/ksh + +export TZ=Etc/Universal + +datesub() { + gdate "$@" '+ FILL(%_11s,%_4Y,%_m,%_d,%w,%_H,%_M,%_S), // %a %b %e %H:%M:%S %Z %Y' +} + +( + datesub -d '1970/01/01 00:00:00' + datesub -d '1981/04/12 12:00:03' + datesub -d '2011/07/21 09:57:00' + datesub -d @2147483647 + datesub -d @2147483648 + datesub -d '2063/04/05 00:00:00' + for year in `seq 1970 1 2030`; do + datesub -d "${year}/01/01 00:00:00" + datesub -d "${year}/07/01 00:00:00" + done + for year in `seq 2000 25 2600`; do + datesub -d "$((${year} - 1))/12/31 23:59:59" + datesub -d "$((${year} + 0))/01/01 00:00:00" + datesub -d "$((${year} + 1))/01/01 00:00:00" + done +)|sort -u diff --git a/contrib/netbsd-tests/dev/clock_subr/t_clock_subr.c b/contrib/netbsd-tests/dev/clock_subr/t_clock_subr.c new file mode 100644 index 0000000..bb03c68 --- /dev/null +++ b/contrib/netbsd-tests/dev/clock_subr/t_clock_subr.c @@ -0,0 +1,309 @@ +/* $NetBSD: t_clock_subr.c,v 1.3 2017/01/13 21:30:39 christos Exp $ */ + +/* + * Copyright (c) 2016 Jonathan A. Kollasch + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 +__COPYRIGHT("@(#) Copyright (c) 2016\ + Jonathan A. Kollasch. All rights reserved."); +__RCSID("$NetBSD: t_clock_subr.c,v 1.3 2017/01/13 21:30:39 christos Exp $"); + +#include +#include + +#include +#include +#include + +#include + +#include "h_macros.h" + +#define FILL(ti,ye,mo,da,wd,ho,mi,se) \ +{ .time = (ti), .clock = { .dt_year = (ye), .dt_mon = (mo), .dt_day = (da), \ + .dt_wday = (wd), .dt_hour = (ho), .dt_min = (mi), .dt_sec = (se), } } + +static struct clock_test { + time_t time; + struct clock_ymdhms clock; +} const clock_tests[] = { + FILL( 0,1970, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 1970 + FILL( 15638400,1970, 7, 1,3, 0, 0, 0), // Wed Jul 1 00:00:00 UTC 1970 + FILL( 31536000,1971, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 1971 + FILL( 47174400,1971, 7, 1,4, 0, 0, 0), // Thu Jul 1 00:00:00 UTC 1971 + FILL( 63072000,1972, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 1972 + FILL( 78796800,1972, 7, 1,6, 0, 0, 0), // Sat Jul 1 00:00:00 UTC 1972 + FILL( 94694400,1973, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 1973 + FILL( 110332800,1973, 7, 1,0, 0, 0, 0), // Sun Jul 1 00:00:00 UTC 1973 + FILL( 126230400,1974, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 1974 + FILL( 141868800,1974, 7, 1,1, 0, 0, 0), // Mon Jul 1 00:00:00 UTC 1974 + FILL( 157766400,1975, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 1975 + FILL( 173404800,1975, 7, 1,2, 0, 0, 0), // Tue Jul 1 00:00:00 UTC 1975 + FILL( 189302400,1976, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 1976 + FILL( 205027200,1976, 7, 1,4, 0, 0, 0), // Thu Jul 1 00:00:00 UTC 1976 + FILL( 220924800,1977, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 1977 + FILL( 236563200,1977, 7, 1,5, 0, 0, 0), // Fri Jul 1 00:00:00 UTC 1977 + FILL( 252460800,1978, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 1978 + FILL( 268099200,1978, 7, 1,6, 0, 0, 0), // Sat Jul 1 00:00:00 UTC 1978 + FILL( 283996800,1979, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 1979 + FILL( 299635200,1979, 7, 1,0, 0, 0, 0), // Sun Jul 1 00:00:00 UTC 1979 + FILL( 315532800,1980, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 1980 + FILL( 331257600,1980, 7, 1,2, 0, 0, 0), // Tue Jul 1 00:00:00 UTC 1980 + FILL( 347155200,1981, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 1981 + FILL( 355924803,1981, 4,12,0,12, 0, 3), // Sun Apr 12 12:00:03 UTC 1981 + FILL( 362793600,1981, 7, 1,3, 0, 0, 0), // Wed Jul 1 00:00:00 UTC 1981 + FILL( 378691200,1982, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 1982 + FILL( 394329600,1982, 7, 1,4, 0, 0, 0), // Thu Jul 1 00:00:00 UTC 1982 + FILL( 410227200,1983, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 1983 + FILL( 425865600,1983, 7, 1,5, 0, 0, 0), // Fri Jul 1 00:00:00 UTC 1983 + FILL( 441763200,1984, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 1984 + FILL( 457488000,1984, 7, 1,0, 0, 0, 0), // Sun Jul 1 00:00:00 UTC 1984 + FILL( 473385600,1985, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 1985 + FILL( 489024000,1985, 7, 1,1, 0, 0, 0), // Mon Jul 1 00:00:00 UTC 1985 + FILL( 504921600,1986, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 1986 + FILL( 520560000,1986, 7, 1,2, 0, 0, 0), // Tue Jul 1 00:00:00 UTC 1986 + FILL( 536457600,1987, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 1987 + FILL( 552096000,1987, 7, 1,3, 0, 0, 0), // Wed Jul 1 00:00:00 UTC 1987 + FILL( 567993600,1988, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 1988 + FILL( 583718400,1988, 7, 1,5, 0, 0, 0), // Fri Jul 1 00:00:00 UTC 1988 + FILL( 599616000,1989, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 1989 + FILL( 615254400,1989, 7, 1,6, 0, 0, 0), // Sat Jul 1 00:00:00 UTC 1989 + FILL( 631152000,1990, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 1990 + FILL( 646790400,1990, 7, 1,0, 0, 0, 0), // Sun Jul 1 00:00:00 UTC 1990 + FILL( 662688000,1991, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 1991 + FILL( 678326400,1991, 7, 1,1, 0, 0, 0), // Mon Jul 1 00:00:00 UTC 1991 + FILL( 694224000,1992, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 1992 + FILL( 709948800,1992, 7, 1,3, 0, 0, 0), // Wed Jul 1 00:00:00 UTC 1992 + FILL( 725846400,1993, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 1993 + FILL( 741484800,1993, 7, 1,4, 0, 0, 0), // Thu Jul 1 00:00:00 UTC 1993 + FILL( 757382400,1994, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 1994 + FILL( 773020800,1994, 7, 1,5, 0, 0, 0), // Fri Jul 1 00:00:00 UTC 1994 + FILL( 788918400,1995, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 1995 + FILL( 804556800,1995, 7, 1,6, 0, 0, 0), // Sat Jul 1 00:00:00 UTC 1995 + FILL( 820454400,1996, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 1996 + FILL( 836179200,1996, 7, 1,1, 0, 0, 0), // Mon Jul 1 00:00:00 UTC 1996 + FILL( 852076800,1997, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 1997 + FILL( 867715200,1997, 7, 1,2, 0, 0, 0), // Tue Jul 1 00:00:00 UTC 1997 + FILL( 883612800,1998, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 1998 + FILL( 899251200,1998, 7, 1,3, 0, 0, 0), // Wed Jul 1 00:00:00 UTC 1998 + FILL( 915148800,1999, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 1999 + FILL( 930787200,1999, 7, 1,4, 0, 0, 0), // Thu Jul 1 00:00:00 UTC 1999 + FILL( 946684799,1999,12,31,5,23,59,59), // Fri Dec 31 23:59:59 UTC 1999 + FILL( 946684800,2000, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 2000 + FILL( 962409600,2000, 7, 1,6, 0, 0, 0), // Sat Jul 1 00:00:00 UTC 2000 + FILL( 978307200,2001, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 2001 + FILL( 993945600,2001, 7, 1,0, 0, 0, 0), // Sun Jul 1 00:00:00 UTC 2001 + FILL( 1009843200,2002, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 2002 + FILL( 1025481600,2002, 7, 1,1, 0, 0, 0), // Mon Jul 1 00:00:00 UTC 2002 + FILL( 1041379200,2003, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 2003 + FILL( 1057017600,2003, 7, 1,2, 0, 0, 0), // Tue Jul 1 00:00:00 UTC 2003 + FILL( 1072915200,2004, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 2004 + FILL( 1088640000,2004, 7, 1,4, 0, 0, 0), // Thu Jul 1 00:00:00 UTC 2004 + FILL( 1104537600,2005, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 2005 + FILL( 1120176000,2005, 7, 1,5, 0, 0, 0), // Fri Jul 1 00:00:00 UTC 2005 + FILL( 1136073600,2006, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 2006 + FILL( 1151712000,2006, 7, 1,6, 0, 0, 0), // Sat Jul 1 00:00:00 UTC 2006 + FILL( 1167609600,2007, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 2007 + FILL( 1183248000,2007, 7, 1,0, 0, 0, 0), // Sun Jul 1 00:00:00 UTC 2007 + FILL( 1199145600,2008, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 2008 + FILL( 1214870400,2008, 7, 1,2, 0, 0, 0), // Tue Jul 1 00:00:00 UTC 2008 + FILL( 1230768000,2009, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 2009 + FILL( 1246406400,2009, 7, 1,3, 0, 0, 0), // Wed Jul 1 00:00:00 UTC 2009 + FILL( 1262304000,2010, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 2010 + FILL( 1277942400,2010, 7, 1,4, 0, 0, 0), // Thu Jul 1 00:00:00 UTC 2010 + FILL( 1293840000,2011, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 2011 + FILL( 1309478400,2011, 7, 1,5, 0, 0, 0), // Fri Jul 1 00:00:00 UTC 2011 + FILL( 1311242220,2011, 7,21,4, 9,57, 0), // Thu Jul 21 09:57:00 UTC 2011 + FILL( 1325376000,2012, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 2012 + FILL( 1341100800,2012, 7, 1,0, 0, 0, 0), // Sun Jul 1 00:00:00 UTC 2012 + FILL( 1356998400,2013, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 2013 + FILL( 1372636800,2013, 7, 1,1, 0, 0, 0), // Mon Jul 1 00:00:00 UTC 2013 + FILL( 1388534400,2014, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 2014 + FILL( 1404172800,2014, 7, 1,2, 0, 0, 0), // Tue Jul 1 00:00:00 UTC 2014 + FILL( 1420070400,2015, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 2015 + FILL( 1435708800,2015, 7, 1,3, 0, 0, 0), // Wed Jul 1 00:00:00 UTC 2015 + FILL( 1451606400,2016, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 2016 + FILL( 1467331200,2016, 7, 1,5, 0, 0, 0), // Fri Jul 1 00:00:00 UTC 2016 + FILL( 1483228800,2017, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 2017 + FILL( 1498867200,2017, 7, 1,6, 0, 0, 0), // Sat Jul 1 00:00:00 UTC 2017 + FILL( 1514764800,2018, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 2018 + FILL( 1530403200,2018, 7, 1,0, 0, 0, 0), // Sun Jul 1 00:00:00 UTC 2018 + FILL( 1546300800,2019, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 2019 + FILL( 1561939200,2019, 7, 1,1, 0, 0, 0), // Mon Jul 1 00:00:00 UTC 2019 + FILL( 1577836800,2020, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 2020 + FILL( 1593561600,2020, 7, 1,3, 0, 0, 0), // Wed Jul 1 00:00:00 UTC 2020 + FILL( 1609459200,2021, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 2021 + FILL( 1625097600,2021, 7, 1,4, 0, 0, 0), // Thu Jul 1 00:00:00 UTC 2021 + FILL( 1640995200,2022, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 2022 + FILL( 1656633600,2022, 7, 1,5, 0, 0, 0), // Fri Jul 1 00:00:00 UTC 2022 + FILL( 1672531200,2023, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 2023 + FILL( 1688169600,2023, 7, 1,6, 0, 0, 0), // Sat Jul 1 00:00:00 UTC 2023 + FILL( 1704067200,2024, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 2024 + FILL( 1719792000,2024, 7, 1,1, 0, 0, 0), // Mon Jul 1 00:00:00 UTC 2024 + FILL( 1735689599,2024,12,31,2,23,59,59), // Tue Dec 31 23:59:59 UTC 2024 + FILL( 1735689600,2025, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 2025 + FILL( 1751328000,2025, 7, 1,2, 0, 0, 0), // Tue Jul 1 00:00:00 UTC 2025 + FILL( 1767225600,2026, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 2026 + FILL( 1782864000,2026, 7, 1,3, 0, 0, 0), // Wed Jul 1 00:00:00 UTC 2026 + FILL( 1798761600,2027, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 2027 + FILL( 1814400000,2027, 7, 1,4, 0, 0, 0), // Thu Jul 1 00:00:00 UTC 2027 + FILL( 1830297600,2028, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 2028 + FILL( 1846022400,2028, 7, 1,6, 0, 0, 0), // Sat Jul 1 00:00:00 UTC 2028 + FILL( 1861920000,2029, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 2029 + FILL( 1877558400,2029, 7, 1,0, 0, 0, 0), // Sun Jul 1 00:00:00 UTC 2029 + FILL( 1893456000,2030, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 2030 + FILL( 1909094400,2030, 7, 1,1, 0, 0, 0), // Mon Jul 1 00:00:00 UTC 2030 + FILL( 2147483647,2038, 1,19,2, 3,14, 7), // Tue Jan 19 03:14:07 UTC 2038 + FILL( 2147483648,2038, 1,19,2, 3,14, 8), // Tue Jan 19 03:14:08 UTC 2038 + FILL( 2524607999,2049,12,31,5,23,59,59), // Fri Dec 31 23:59:59 UTC 2049 + FILL( 2524608000,2050, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 2050 + FILL( 2556144000,2051, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 2051 + FILL( 2942956800,2063, 4, 5,4, 0, 0, 0), // Thu Apr 5 00:00:00 UTC 2063 + FILL( 3313526399,2074,12,31,1,23,59,59), // Mon Dec 31 23:59:59 UTC 2074 + FILL( 3313526400,2075, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 2075 + FILL( 3345062400,2076, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 2076 + FILL( 4102444799,2099,12,31,4,23,59,59), // Thu Dec 31 23:59:59 UTC 2099 + FILL( 4102444800,2100, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 2100 + FILL( 4133980800,2101, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 2101 + FILL( 4891363199,2124,12,31,0,23,59,59), // Sun Dec 31 23:59:59 UTC 2124 + FILL( 4891363200,2125, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 2125 + FILL( 4922899200,2126, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 2126 + FILL( 5680281599,2149,12,31,3,23,59,59), // Wed Dec 31 23:59:59 UTC 2149 + FILL( 5680281600,2150, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 2150 + FILL( 5711817600,2151, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 2151 + FILL( 6469199999,2174,12,31,6,23,59,59), // Sat Dec 31 23:59:59 UTC 2174 + FILL( 6469200000,2175, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 2175 + FILL( 6500736000,2176, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 2176 + FILL( 7258118399,2199,12,31,2,23,59,59), // Tue Dec 31 23:59:59 UTC 2199 + FILL( 7258118400,2200, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 2200 + FILL( 7289654400,2201, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 2201 + FILL( 8047036799,2224,12,31,5,23,59,59), // Fri Dec 31 23:59:59 UTC 2224 + FILL( 8047036800,2225, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 2225 + FILL( 8078572800,2226, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 2226 + FILL( 8835955199,2249,12,31,1,23,59,59), // Mon Dec 31 23:59:59 UTC 2249 + FILL( 8835955200,2250, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 2250 + FILL( 8867491200,2251, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 2251 + FILL( 9624873599,2274,12,31,4,23,59,59), // Thu Dec 31 23:59:59 UTC 2274 + FILL( 9624873600,2275, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 2275 + FILL( 9656409600,2276, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 2276 + FILL(10413791999,2299,12,31,0,23,59,59), // Sun Dec 31 23:59:59 UTC 2299 + FILL(10413792000,2300, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 2300 + FILL(10445328000,2301, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 2301 + FILL(11202710399,2324,12,31,3,23,59,59), // Wed Dec 31 23:59:59 UTC 2324 + FILL(11202710400,2325, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 2325 + FILL(11234246400,2326, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 2326 + FILL(11991628799,2349,12,31,6,23,59,59), // Sat Dec 31 23:59:59 UTC 2349 + FILL(11991628800,2350, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 2350 + FILL(12023164800,2351, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 2351 + FILL(12780547199,2374,12,31,2,23,59,59), // Tue Dec 31 23:59:59 UTC 2374 + FILL(12780547200,2375, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 2375 + FILL(12812083200,2376, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 2376 + FILL(13569465599,2399,12,31,5,23,59,59), // Fri Dec 31 23:59:59 UTC 2399 + FILL(13569465600,2400, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 2400 + FILL(13601088000,2401, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 2401 + FILL(14358470399,2424,12,31,2,23,59,59), // Tue Dec 31 23:59:59 UTC 2424 + FILL(14358470400,2425, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 2425 + FILL(14390006400,2426, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 2426 + FILL(15147388799,2449,12,31,5,23,59,59), // Fri Dec 31 23:59:59 UTC 2449 + FILL(15147388800,2450, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 2450 + FILL(15178924800,2451, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 2451 + FILL(15936307199,2474,12,31,1,23,59,59), // Mon Dec 31 23:59:59 UTC 2474 + FILL(15936307200,2475, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 2475 + FILL(15967843200,2476, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 2476 + FILL(16725225599,2499,12,31,4,23,59,59), // Thu Dec 31 23:59:59 UTC 2499 + FILL(16725225600,2500, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 2500 + FILL(16756761600,2501, 1, 1,6, 0, 0, 0), // Sat Jan 1 00:00:00 UTC 2501 + FILL(17514143999,2524,12,31,0,23,59,59), // Sun Dec 31 23:59:59 UTC 2524 + FILL(17514144000,2525, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 2525 + FILL(17545680000,2526, 1, 1,2, 0, 0, 0), // Tue Jan 1 00:00:00 UTC 2526 + FILL(18303062399,2549,12,31,3,23,59,59), // Wed Dec 31 23:59:59 UTC 2549 + FILL(18303062400,2550, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 2550 + FILL(18334598400,2551, 1, 1,5, 0, 0, 0), // Fri Jan 1 00:00:00 UTC 2551 + FILL(19091980799,2574,12,31,6,23,59,59), // Sat Dec 31 23:59:59 UTC 2574 + FILL(19091980800,2575, 1, 1,0, 0, 0, 0), // Sun Jan 1 00:00:00 UTC 2575 + FILL(19123516800,2576, 1, 1,1, 0, 0, 0), // Mon Jan 1 00:00:00 UTC 2576 + FILL(19880899199,2599,12,31,2,23,59,59), // Tue Dec 31 23:59:59 UTC 2599 + FILL(19880899200,2600, 1, 1,3, 0, 0, 0), // Wed Jan 1 00:00:00 UTC 2600 + FILL(19912435200,2601, 1, 1,4, 0, 0, 0), // Thu Jan 1 00:00:00 UTC 2601 +}; +#undef FILL + +ATF_TC(ymdhms_to_secs); +ATF_TC_HEAD(ymdhms_to_secs, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check clock_ymdhms_to_secs"); +} +ATF_TC_BODY(ymdhms_to_secs, tc) +{ + time_t secs; + size_t i; + + for (i = 0; i < __arraycount(clock_tests); i++) { + secs = clock_ymdhms_to_secs(__UNCONST(&clock_tests[i].clock)); + ATF_CHECK_EQ_MSG(clock_tests[i].time, secs, "%jd != %jd", + (intmax_t)clock_tests[i].time, (intmax_t)secs); + } +} + +ATF_TC(secs_to_ymdhms); +ATF_TC_HEAD(secs_to_ymdhms, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check clock_secs_to_ymdhms"); +} +ATF_TC_BODY(secs_to_ymdhms, tc) +{ + struct clock_ymdhms ymdhms; + size_t i; + +#define CHECK_FIELD(f) \ + ATF_CHECK_EQ_MSG(ymdhms.dt_##f, clock_tests[i].clock.dt_##f, \ + "%jd != %jd for %jd", (intmax_t)ymdhms.dt_##f, \ + (intmax_t)clock_tests[i].clock.dt_##f, \ + (intmax_t)clock_tests[i].time) + + for (i = 0; i < __arraycount(clock_tests); i++) { + clock_secs_to_ymdhms(clock_tests[i].time, &ymdhms); + CHECK_FIELD(year); + CHECK_FIELD(mon); + CHECK_FIELD(day); + CHECK_FIELD(wday); + CHECK_FIELD(hour); + CHECK_FIELD(min); + CHECK_FIELD(sec); + } +#undef CHECK_FIELD +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ymdhms_to_secs); + ATF_TP_ADD_TC(tp, secs_to_ymdhms); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/dev/dm/dm_targets_cmd.plist b/contrib/netbsd-tests/dev/dm/dm_targets_cmd.plist new file mode 100644 index 0000000..f029dfb --- /dev/null +++ b/contrib/netbsd-tests/dev/dm/dm_targets_cmd.plist @@ -0,0 +1,20 @@ + + + + + cmd_data + + command + targets + event_nr + 0x0 + flags + 0x4 + version + + 0x4 + 0x1 + 0x0 + + + \ No newline at end of file diff --git a/contrib/netbsd-tests/dev/dm/dm_version_cmd.plist b/contrib/netbsd-tests/dev/dm/dm_version_cmd.plist new file mode 100644 index 0000000..e40e53e --- /dev/null +++ b/contrib/netbsd-tests/dev/dm/dm_version_cmd.plist @@ -0,0 +1,20 @@ + + + + + cmd_data + + command + version + event_nr + 0x0 + flags + 0x4 + version + + 0x4 + 0x0 + 0x0 + + + \ No newline at end of file diff --git a/contrib/netbsd-tests/dev/dm/h_dm.c b/contrib/netbsd-tests/dev/dm/h_dm.c new file mode 100644 index 0000000..d4ccb3a --- /dev/null +++ b/contrib/netbsd-tests/dev/dm/h_dm.c @@ -0,0 +1,148 @@ +/* $NetBSD: h_dm.c,v 1.2 2016/01/23 21:18:27 christos Exp $ */ + +/* + * Copyright (c) 2010 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int dm_test_targets(void); +int dm_test_versions(void); + +/* + * Test simple dm versions command on device-mapper device. + */ +int +dm_test_versions(void) { + int fd; + int error; + prop_dictionary_t dict_in, dict_out; + struct plistref prefp; + char *xml; + + error = 0; + + error = rump_init(); + if (error != 0) + err(1, "Rump init failed"); + + fd = rump_sys_open("/dev/mapper/control", O_RDWR, 0); + if (fd == -1) + err(1, "Open dm device failed"); + + dict_in = prop_dictionary_internalize_from_file("dm_version_cmd.plist"); + dict_out = prop_dictionary_create(); + + prop_dictionary_externalize_to_pref(dict_in, &prefp); + + error = rump_sys_ioctl(fd, NETBSD_DM_IOCTL, &prefp); + if (error < 0) + err(1, "Dm control ioctl failed"); + + dict_out = prop_dictionary_internalize(prefp.pref_plist); + + xml = prop_dictionary_externalize(dict_out); + __USE(xml); + + rump_sys_close(fd); + + return error; +} + +/* + * Test simple dm targets command on device-mapper device. + */ +int +dm_test_targets(void) { + int fd; + int error; + prop_dictionary_t dict_in, dict_out; + struct plistref prefp; + char *xml; + + error = 0; + + error = rump_init(); + if (error != 0) + err(1, "Rump init failed"); + + fd = rump_sys_open("/dev/mapper/control", O_RDWR, 0); + if (fd == -1) + err(1, "Open dm device failed"); + + dict_in = prop_dictionary_internalize_from_file("dm_targets_cmd.plist"); + dict_out = prop_dictionary_create(); + + prop_dictionary_externalize_to_pref(dict_in, &prefp); + + error = rump_sys_ioctl(fd, NETBSD_DM_IOCTL, &prefp); + if (error < 0) + err(1, "Dm control ioctl failed"); + + dict_out = prop_dictionary_internalize(prefp.pref_plist); + + xml = prop_dictionary_externalize(dict_out); + __USE(xml); + + rump_sys_close(fd); + + return error; +} + +int +main(int argc, char **argv) { + int error; + + error = 0; + + error = dm_test_versions(); + if (error != 0) + err(1, "dm_test_versions failed"); + + error = dm_test_targets(); + if (error != 0) + err(1, "dm_test_targets failed"); + + return error; +} diff --git a/contrib/netbsd-tests/dev/dm/t_dm.sh b/contrib/netbsd-tests/dev/dm/t_dm.sh new file mode 100755 index 0000000..02d1ee3 --- /dev/null +++ b/contrib/netbsd-tests/dev/dm/t_dm.sh @@ -0,0 +1,47 @@ +# $NetBSD: t_dm.sh,v 1.2 2010/11/07 17:51:17 jmmv Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case dm_test +dm_test_head() +{ + atf_set "descr" "Check dm driver routines and create lineary, stripe mapped disks" +} + +dm_test_body() +{ + # XXX Actually we need disks than 1 for stripe check let it leave for later now. + #atf_check -s exit:0 uudecode $(atf_get_srcdir)/t_dm_disk_1.bz2.uue + #atf_check -s exit:0 bunzip2 t_dm_disk_1.bz2 + #atf_check -s exit:0 -o file:t_dm_disk_1 $(atf_get_srcdir)/h_dm + atf_check -s exit:0 $(atf_get_srcdir)/h_dm +} + +atf_init_test_cases() +{ + + atf_add_test_case dm_test +} diff --git a/contrib/netbsd-tests/dev/fss/t_fss.sh b/contrib/netbsd-tests/dev/fss/t_fss.sh new file mode 100755 index 0000000..cb3341f --- /dev/null +++ b/contrib/netbsd-tests/dev/fss/t_fss.sh @@ -0,0 +1,84 @@ +# $NetBSD: t_fss.sh,v 1.2 2016/07/29 20:27:37 pgoyette Exp $ +# +# Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verify basic operation of fss(4) file system snapshot device +# + +orig_data="Original data" +repl_data="Replacement data" + +atf_test_case basic cleanup +basic_body() { + +# create of mount-points for the file system and snapshot + + mkdir ./m1 + mkdir ./m2 + +# create a small 4MB file, treat it as a disk, init a file-system on it, +# and mount it + + dd if=/dev/zero of=./image bs=32k count=64 + vndconfig -c vnd0 ./image + newfs /dev/vnd0a + mount /dev/vnd0a ./m1 + + echo "${orig_data}" > ./m1/text + +# configure and mount a snapshot of the file system + + fssconfig -c fss0 ./m1 ./backup + mount -o rdonly /dev/fss0 ./m2 + +# Modify the data on the underlying file system + + echo "${repl_data}" > ./m1/text || abort + +# Verify that original data is still visible in the snapshot + + read test_data < ./m2/text + atf_check_equal "${orig_data}" "${test_data}" + +# Unmount our temporary stuff + + umount /dev/fss0 || true + fssconfig -u fss0 || true + umount /dev/vnd0a || true + vndconfig -u vnd0 || true +} + +basic_cleanup() { + umount /dev/vnd0a || true + fssconfig -u fss0 || true + umount /dev/fss0 || true + vndconfig -u vnd0 || true +} + +atf_init_test_cases() +{ + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/dev/md/h_mdserv.c b/contrib/netbsd-tests/dev/md/h_mdserv.c new file mode 100644 index 0000000..f5ac6a9 --- /dev/null +++ b/contrib/netbsd-tests/dev/md/h_mdserv.c @@ -0,0 +1,109 @@ +/* $NetBSD: h_mdserv.c,v 1.4 2011/02/10 13:29:02 pooka Exp $ */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define MDSIZE (1024*1024) + +#define REQUIRE(a, msg) if ((a) != 0) err(1, msg); + +static void * +prober(void *arg) +{ + int fd, error; + char buf[4]; + ssize_t n; + + fd = rump_sys_open(arg, O_RDONLY); + for (;;) { + n = rump_sys_read(fd, buf, sizeof(buf)); + + switch (n) { + case 4: + error = 0; + goto out; + + case -1: + if (errno == ENXIO) { + usleep(1000); + continue; + } + + /* FALLTHROUGH */ + default: + error = EPIPE; + goto out; + } + } + out: + + error = rump_daemonize_done(error); + REQUIRE(error, "rump_daemonize_done"); + + if (error) + exit(1); + + return NULL; +} + +int +main(int argc, char *argv[]) +{ + pthread_t pt; + struct md_conf md; + int fd, error; + + if (argc != 2) + exit(1); + + md.md_addr = calloc(1, MDSIZE); + md.md_size = MDSIZE; + md.md_type = MD_UMEM_SERVER; + + error = rump_daemonize_begin(); + REQUIRE(error, "rump_daemonize_begin"); + + error = rump_init(); + REQUIRE(error, "rump_init"); + + error = rump_init_server("unix://commsock"); + REQUIRE(error, "init server"); + + if ((fd = rump_sys_open(argv[1], O_RDWR)) == -1) + err(1, "open"); + + /* + * Now, configuring the md driver also causes our process + * to start acting as the worker for the md. Splitting it + * into two steps in the driver is not easy, since md is + * supposed to be unconfigured when the process dies + * (process may exit between calling ioctl1 and ioctl2). + * So, start a probe thread which attempts to read the md + * and declares the md as configured when the read is + * succesful. + */ + error = pthread_create(&pt, NULL, prober, argv[1]); + REQUIRE(error, "pthread_create"); + pthread_detach(pt); + + if (rump_sys_ioctl(fd, MD_SETCONF, &md) == -1) { + rump_daemonize_done(errno); + exit(1); + } + + return 0; +} diff --git a/contrib/netbsd-tests/dev/md/t_md.sh b/contrib/netbsd-tests/dev/md/t_md.sh new file mode 100755 index 0000000..85de73e --- /dev/null +++ b/contrib/netbsd-tests/dev/md/t_md.sh @@ -0,0 +1,65 @@ +# $NetBSD: t_md.sh,v 1.7 2011/05/14 17:42:28 jmmv Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +rawpart=`sysctl -n kern.rawpartition | tr '01234' 'abcde'` +rawmd=/dev/rmd0${rawpart} + +atf_test_case basic cleanup +basic_head() +{ + + atf_set "descr" "Check that md can be created, read and written" +} + +basic_body() +{ + + # Scope out raw part. This is actually the *host* raw partition, + # but just let it slide for now, since they *should* be the same. + rawpart=`sysctl -n kern.rawpartition | tr '01234' 'abcde'` + + atf_check -s exit:0 $(atf_get_srcdir)/h_mdserv ${rawmd} + + export RUMP_SERVER=unix://commsock + atf_check -s exit:0 -e ignore -x \ + "dd if=/bin/ls count=10 | rump.dd of=${rawmd} seek=100" + atf_check -s exit:0 -e ignore -x \ + "rump.dd if=${rawmd} skip=100 count=10 | dd of=testfile" + atf_check -s exit:0 -e ignore -o file:testfile dd if=/bin/ls count=10 +} + +basic_cleanup() +{ + + env RUMP_SERVER=unix://commsock rump.halt +} + +atf_init_test_cases() +{ + + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/dev/raidframe/t_raid.sh b/contrib/netbsd-tests/dev/raidframe/t_raid.sh new file mode 100755 index 0000000..ae21eed --- /dev/null +++ b/contrib/netbsd-tests/dev/raidframe/t_raid.sh @@ -0,0 +1,323 @@ +#! /usr/bin/atf-sh +# $NetBSD: t_raid.sh,v 1.12 2013/02/19 21:08:24 joerg Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +rawpart=`sysctl -n kern.rawpartition | tr '01234' 'abcde'` +rawraid=/dev/rraid0${rawpart} +raidserver="rump_server -lrumpvfs -lrumpdev -lrumpdev_disk -lrumpdev_raidframe" + +makecfg() +{ + level=${1} + ncol=${2} + + printf "START array\n1 ${ncol} 0\nSTART disks\n" > raid.conf + diskn=0 + while [ ${ncol} -gt ${diskn} ] ; do + echo "/disk${diskn}" >> raid.conf + diskn=$((diskn+1)) + done + + printf "START layout\n32 1 1 ${level}\nSTART queue\nfifo 100\n" \ + >> raid.conf +} + +atf_test_case smalldisk cleanup +smalldisk_head() +{ + atf_set "descr" "Checks the raidframe works on small disks " \ + "(PR kern/44239)" + atf_set "require.progs" "rump_server" +} + +smalldisk_body() +{ + makecfg 1 2 + export RUMP_SERVER=unix://sock + atf_check -s exit:0 ${raidserver} \ + -d key=/disk0,hostpath=disk0.img,size=1m \ + -d key=/disk1,hostpath=disk1.img,size=1m \ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.raidctl -C raid.conf raid0 +} + +smalldisk_cleanup() +{ + export RUMP_SERVER=unix://sock + rump.halt +} + + +# make this smaller once 44239 is fixed +export RAID_MEDIASIZE=32m + +atf_test_case raid1_compfail cleanup +raid1_compfail_head() +{ + atf_set "descr" "Checks that RAID1 works after component failure" + atf_set "require.progs" "rump_server" +} + +raid1_compfail_body() +{ + makecfg 1 2 + export RUMP_SERVER=unix://sock + atf_check -s exit:0 ${raidserver} \ + -d key=/disk0,hostpath=disk0.img,size=${RAID_MEDIASIZE} \ + -d key=/disk1,hostpath=disk1.img,size=${RAID_MEDIASIZE} \ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.raidctl -C raid.conf raid0 + atf_check -s exit:0 rump.raidctl -I 12345 raid0 + atf_check -s exit:0 -o ignore rump.raidctl -iv raid0 + + # put some data there + atf_check -s exit:0 -e ignore \ + dd if=$(atf_get_srcdir)/t_raid of=testfile count=4 + atf_check -s exit:0 -e ignore -x \ + "dd if=testfile | rump.dd of=${rawraid} conv=sync" + + # restart server with failed component + rump.halt + rm disk1.img # FAIL + atf_check -s exit:0 ${raidserver} \ + -d key=/disk0,hostpath=disk0.img,size=${RAID_MEDIASIZE} \ + -d key=/disk1,hostpath=disk1.img,size=${RAID_MEDIASIZE} \ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.raidctl -c raid.conf raid0 + + # check if we we get what we wrote + atf_check -s exit:0 -o file:testfile -e ignore \ + rump.dd if=${rawraid} count=4 +} + +raid1_compfail_cleanup() +{ + export RUMP_SERVER=unix://sock + rump.halt +} + + + +atf_test_case raid1_comp0fail cleanup +raid1_comp0fail_head() +{ + atf_set "descr" "Checks configuring RAID1 after component 0 fails" \ + "(PR kern/44251)" + atf_set "require.progs" "rump_server" +} + +raid1_comp0fail_body() +{ + makecfg 1 2 + export RUMP_SERVER=unix://sock + atf_check -s exit:0 ${raidserver} \ + -d key=/disk0,hostpath=disk0.img,size=${RAID_MEDIASIZE} \ + -d key=/disk1,hostpath=disk1.img,size=${RAID_MEDIASIZE} \ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.raidctl -C raid.conf raid0 + atf_check -s exit:0 rump.raidctl -I 12345 raid0 + atf_check -s exit:0 -o ignore rump.raidctl -iv raid0 + + # restart server with failed component + rump.halt + rm disk0.img # FAIL + atf_check -s exit:0 ${raidserver} \ + -d key=/disk0,hostpath=disk0.img,size=${RAID_MEDIASIZE} \ + -d key=/disk1,hostpath=disk1.img,size=${RAID_MEDIASIZE} \ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.raidctl -c raid.conf raid0 +} + +raid1_comp0fail_cleanup() +{ + export RUMP_SERVER=unix://sock + rump.halt +} + +atf_test_case raid1_normal cleanup +raid1_normal_head() +{ + atf_set "descr" "Checks that RAID1 -c configurations work " \ + "in the normal case" + atf_set "require.progs" "rump_server" +} + +raid1_normal_body() +{ + makecfg 1 2 + export RUMP_SERVER=unix://sock + atf_check -s exit:0 ${raidserver} \ + -d key=/disk0,hostpath=disk0.img,size=${RAID_MEDIASIZE} \ + -d key=/disk1,hostpath=disk1.img,size=${RAID_MEDIASIZE} \ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.raidctl -C raid.conf raid0 + atf_check -s exit:0 rump.raidctl -I 12345 raid0 + atf_check -s exit:0 -o ignore rump.raidctl -iv raid0 + + # put some data there + atf_check -s exit:0 -e ignore \ + dd if=$(atf_get_srcdir)/t_raid of=testfile count=4 + atf_check -s exit:0 -e ignore -x \ + "dd if=testfile | rump.dd of=${rawraid} conv=sync" + + # restart server, disks remain normal + rump.halt + + atf_check -s exit:0 ${raidserver} \ + -d key=/disk0,hostpath=disk0.img,size=${RAID_MEDIASIZE} \ + -d key=/disk1,hostpath=disk1.img,size=${RAID_MEDIASIZE} \ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.raidctl -c raid.conf raid0 + + # check if we we get what we wrote + atf_check -s exit:0 -o file:testfile -e ignore \ + rump.dd if=${rawraid} count=4 + +} + +raid1_normal_cleanup() +{ + export RUMP_SERVER=unix://sock + rump.halt +} + + +atf_test_case raid5_compfail cleanup +raid5_compfail_head() +{ + atf_set "descr" "Checks that RAID5 works after component failure" + atf_set "require.progs" "rump_server" +} + +raid5_compfail_body() +{ + makecfg 5 3 + export RUMP_SERVER=unix://sock + atf_check -s exit:0 ${raidserver} \ + -d key=/disk0,hostpath=disk0.img,size=${RAID_MEDIASIZE} \ + -d key=/disk1,hostpath=disk1.img,size=${RAID_MEDIASIZE} \ + -d key=/disk2,hostpath=disk2.img,size=${RAID_MEDIASIZE} \ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.raidctl -C raid.conf raid0 + atf_check -s exit:0 rump.raidctl -I 12345 raid0 + atf_check -s exit:0 -o ignore rump.raidctl -iv raid0 + + # put some data there + atf_check -s exit:0 -e ignore \ + dd if=$(atf_get_srcdir)/t_raid of=testfile count=4 + atf_check -s exit:0 -e ignore -x \ + "dd if=testfile | rump.dd of=${rawraid} conv=sync" + + # restart server with failed component + rump.halt + rm disk2.img # FAIL + atf_check -s exit:0 ${raidserver} \ + -d key=/disk0,hostpath=disk0.img,size=${RAID_MEDIASIZE} \ + -d key=/disk1,hostpath=disk1.img,size=${RAID_MEDIASIZE} \ + -d key=/disk2,hostpath=disk2.img,size=${RAID_MEDIASIZE} \ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.raidctl -c raid.conf raid0 + + # check if we we get what we wrote + atf_check -s exit:0 -o file:testfile -e ignore \ + rump.dd if=${rawraid} count=4 +} + +raid5_compfail_cleanup() +{ + export RUMP_SERVER=unix://sock + rump.halt +} + +atf_test_case raid5_normal cleanup +raid5_normal_head() +{ + atf_set "descr" "Checks that RAID5 works after normal shutdown " \ + "and 'raidctl -c' startup" + atf_set "require.progs" "rump_server" +} + +raid5_normal_body() +{ + makecfg 5 3 + export RUMP_SERVER=unix://sock + atf_check -s exit:0 ${raidserver} \ + -d key=/disk0,hostpath=disk0.img,size=${RAID_MEDIASIZE} \ + -d key=/disk1,hostpath=disk1.img,size=${RAID_MEDIASIZE} \ + -d key=/disk2,hostpath=disk2.img,size=${RAID_MEDIASIZE} \ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.raidctl -C raid.conf raid0 + atf_check -s exit:0 rump.raidctl -I 12345 raid0 + atf_check -s exit:0 -o ignore rump.raidctl -iv raid0 + + # put some data there + atf_check -s exit:0 -e ignore \ + dd if=$(atf_get_srcdir)/t_raid of=testfile count=4 + atf_check -s exit:0 -e ignore -x \ + "dd if=testfile | rump.dd of=${rawraid} conv=sync" + + # restart server after normal shutdown + rump.halt + + atf_check -s exit:0 ${raidserver} \ + -d key=/disk0,hostpath=disk0.img,size=${RAID_MEDIASIZE} \ + -d key=/disk1,hostpath=disk1.img,size=${RAID_MEDIASIZE} \ + -d key=/disk2,hostpath=disk2.img,size=${RAID_MEDIASIZE} \ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.raidctl -c raid.conf raid0 + + # check if we we get what we wrote + atf_check -s exit:0 -o file:testfile -e ignore \ + rump.dd if=${rawraid} count=4 +} + +raid5_normal_cleanup() +{ + export RUMP_SERVER=unix://sock + rump.halt +} + +atf_init_test_cases() +{ + atf_add_test_case smalldisk + atf_add_test_case raid1_normal + atf_add_test_case raid1_comp0fail + atf_add_test_case raid1_compfail + atf_add_test_case raid5_normal + atf_add_test_case raid5_compfail +} diff --git a/contrib/netbsd-tests/dev/scsipi/libscsitest/SCSITEST.ioconf b/contrib/netbsd-tests/dev/scsipi/libscsitest/SCSITEST.ioconf new file mode 100644 index 0000000..afee6c8 --- /dev/null +++ b/contrib/netbsd-tests/dev/scsipi/libscsitest/SCSITEST.ioconf @@ -0,0 +1,12 @@ +# $NetBSD: SCSITEST.ioconf,v 1.1 2014/04/24 21:46:44 pooka Exp $ +# + +ioconf scsitest + +include "conf/files" +include "dev/scsipi/files.scsipi" +include "rump/dev/files.rump" + +pseudo-root mainbus* + +scsitest0 at mainbus? diff --git a/contrib/netbsd-tests/dev/scsipi/libscsitest/scsitest.c b/contrib/netbsd-tests/dev/scsipi/libscsitest/scsitest.c new file mode 100644 index 0000000..8f214f7 --- /dev/null +++ b/contrib/netbsd-tests/dev/scsipi/libscsitest/scsitest.c @@ -0,0 +1,259 @@ +/* $NetBSD: scsitest.c,v 1.2 2014/04/25 00:24:39 pooka Exp $ */ + +/* + * Copyright (c) 2010 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/* + * A SCSI target which is useful for debugging our scsipi driver stack. + * Currently it pretends to be a single CD. + * + * Freely add the necessary features for your tests. Just remember to + * run the atf test suite to make sure you didn't cause regressions to + * other tests. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: scsitest.c,v 1.2 2014/04/25 00:24:39 pooka Exp $"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "scsitest.h" + +int scsitest_match(device_t, cfdata_t, void *); +void scsitest_attach(device_t, device_t, void *); + +struct scsitest { + struct scsipi_channel sc_channel; + struct scsipi_adapter sc_adapter; +}; + +CFATTACH_DECL_NEW(scsitest, sizeof(struct scsitest), scsitest_match, + scsitest_attach, NULL, NULL); + +/* + * tosi.iso can be used to deliver CD requests to a host file with the + * name in USE_TOSI_ISO (yes, it's extrasimplistic). + */ +//#define USE_TOSI_ISO + +#define CDBLOCKSIZE 2048 +static uint32_t mycdsize = 2048; +static int isofd; + +#define MYCDISO "tosi.iso" + +unsigned rump_scsitest_err[RUMP_SCSITEST_MAXERROR]; + +static void +sense_notready(struct scsipi_xfer *xs) +{ + struct scsi_sense_data *sense = &xs->sense.scsi_sense; + + xs->error = XS_SENSE; + + sense->response_code = 0x70; + sense->flags = SKEY_NOT_READY; + sense->asc = 0x3A; + sense->ascq = 0x00; + sense->extra_len = 6; +} + +/* + * This is pretty much a CD target for now + */ +static void +scsitest_request(struct scsipi_channel *chan, + scsipi_adapter_req_t req, void *arg) +{ + struct scsipi_xfer *xs = arg; + struct scsipi_generic *cmd = xs->cmd; +#ifdef USE_TOSI_ISO + int error; +#endif + + if (req != ADAPTER_REQ_RUN_XFER) + return; + + //show_scsipi_xs(xs); + + switch (cmd->opcode) { + case SCSI_TEST_UNIT_READY: + if (isofd == -1) + sense_notready(xs); + + break; + case INQUIRY: { + struct scsipi_inquiry_data *inqbuf = (void *)xs->data; + + memset(inqbuf, 0, sizeof(*inqbuf)); + inqbuf->device = T_CDROM; + inqbuf->dev_qual2 = SID_REMOVABLE; + strcpy(inqbuf->vendor, "RUMPHOBO"); + strcpy(inqbuf->product, "It's a LIE"); + strcpy(inqbuf->revision, "0.00"); + break; + } + case READ_CD_CAPACITY: { + struct scsipi_read_cd_cap_data *ret = (void *)xs->data; + + _lto4b(CDBLOCKSIZE, ret->length); + _lto4b(mycdsize, ret->addr); + + break; + } + case READ_DISCINFO: { + struct scsipi_read_discinfo_data *ret = (void *)xs->data; + + memset(ret, 0, sizeof(*ret)); + break; + } + case READ_TRACKINFO: { + struct scsipi_read_trackinfo_data *ret = (void *)xs->data; + + _lto4b(mycdsize, ret->track_size); + break; + } + case READ_TOC: { + struct scsipi_toc_header *ret = (void *)xs->data; + + memset(ret, 0, sizeof(*ret)); + break; + } + case START_STOP: { + struct scsipi_start_stop *param = (void *)cmd; + + if (param->how & SSS_LOEJ) { +#ifdef USE_TOSI_ISO + rumpuser_close(isofd, &error); +#endif + isofd = -1; + } + break; + } + case SCSI_SYNCHRONIZE_CACHE_10: { + if (isofd == -1) { + if ((xs->xs_control & XS_CTL_SILENT) == 0) + atomic_inc_uint(&rump_scsitest_err + [RUMP_SCSITEST_NOISYSYNC]); + + sense_notready(xs); + } + + break; + } + case GET_CONFIGURATION: { + memset(xs->data, 0, sizeof(struct scsipi_get_conf_data)); + break; + } + case SCSI_READ_6_COMMAND: { +#ifdef USE_TOSI_ISO + struct scsi_rw_6 *param = (void *)cmd; + + printf("reading %d bytes from %d\n", + param->length * CDBLOCKSIZE, + _3btol(param->addr) * CDBLOCKSIZE); + rumpuser_pread(isofd, xs->data, + param->length * CDBLOCKSIZE, + _3btol(param->addr) * CDBLOCKSIZE, + &error); +#endif + + break; + } + case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL: + /* hardcoded for now */ + break; + default: + printf("unhandled opcode 0x%x\n", cmd->opcode); + break; + } + + scsipi_done(xs); +} + +int +scsitest_match(device_t parent, cfdata_t match, void *aux) +{ +#ifdef USE_TOSI_ISO + uint64_t fsize; + int error, ft; + + if (rumpuser_getfileinfo(MYCDISO, &fsize, &ft, &error)) + return 0; + if (ft != RUMPUSER_FT_REG) + return 0; + mycdsize = fsize / CDBLOCKSIZE; + + if ((isofd = rumpuser_open(MYCDISO, RUMPUSER_OPEN_RDWR, &error)) == -1) + return 0; +#else + /* + * We pretend to have a medium present initially, so != -1. + */ + isofd = -2; +#endif + + return 1; +} + +void +scsitest_attach(device_t parent, device_t self, void *aux) +{ + struct scsitest *sc = device_private(self); + + aprint_naive("\n"); + aprint_normal("\n"); + + memset(&sc->sc_adapter, 0, sizeof(sc->sc_adapter)); + sc->sc_adapter.adapt_nchannels = 1; + sc->sc_adapter.adapt_request = scsitest_request; + sc->sc_adapter.adapt_minphys = minphys; + sc->sc_adapter.adapt_dev = self; + sc->sc_adapter.adapt_max_periph = 1; + sc->sc_adapter.adapt_openings = 1; + + memset(&sc->sc_channel, 0, sizeof(sc->sc_channel)); + sc->sc_channel.chan_bustype = &scsi_bustype; + sc->sc_channel.chan_ntargets = 2; + sc->sc_channel.chan_nluns = 1; + sc->sc_channel.chan_id = 0; + sc->sc_channel.chan_flags = SCSIPI_CHAN_NOSETTLE; + sc->sc_channel.chan_adapter = &sc->sc_adapter; + + config_found_ia(self, "scsi", &sc->sc_channel, scsiprint); +} diff --git a/contrib/netbsd-tests/dev/scsipi/libscsitest/scsitest.h b/contrib/netbsd-tests/dev/scsipi/libscsitest/scsitest.h new file mode 100644 index 0000000..ba9b84a --- /dev/null +++ b/contrib/netbsd-tests/dev/scsipi/libscsitest/scsitest.h @@ -0,0 +1,38 @@ +/* $NetBSD: scsitest.h,v 1.1 2014/04/25 00:24:39 pooka Exp $ */ + +/* + * Copyright (c) 2010 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#ifndef _RUMP_SCSITEST_H_ +#define _RUMP_SCSITEST_H_ + +enum { + RUMP_SCSITEST_NOISYSYNC, + RUMP_SCSITEST_MAXERROR +}; + +extern unsigned rump_scsitest_err[RUMP_SCSITEST_MAXERROR]; + +#endif /* _RUMP_SCSITEST_H_ */ diff --git a/contrib/netbsd-tests/dev/scsipi/libscsitest/scsitest_component.c b/contrib/netbsd-tests/dev/scsipi/libscsitest/scsitest_component.c new file mode 100644 index 0000000..db0e209 --- /dev/null +++ b/contrib/netbsd-tests/dev/scsipi/libscsitest/scsitest_component.c @@ -0,0 +1,46 @@ +/* $NetBSD: scsitest_component.c,v 1.1 2014/04/24 21:46:44 pooka Exp $ */ + +/* + * Copyright (c) 2010 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__KERNEL_RCSID(0, "$NetBSD: scsitest_component.c,v 1.1 2014/04/24 21:46:44 pooka Exp $"); + +#include +#include +#include +#include +#include + +#include "ioconf.c" + +#include "rump_private.h" + +RUMP_COMPONENT(RUMP_COMPONENT_DEV) +{ + + config_init_component(cfdriver_ioconf_scsitest, + cfattach_ioconf_scsitest, cfdata_ioconf_scsitest); +} diff --git a/contrib/netbsd-tests/dev/scsipi/t_cd.c b/contrib/netbsd-tests/dev/scsipi/t_cd.c new file mode 100644 index 0000000..6e856de --- /dev/null +++ b/contrib/netbsd-tests/dev/scsipi/t_cd.c @@ -0,0 +1,81 @@ +/* $NetBSD: t_cd.c,v 1.8 2017/01/13 21:30:39 christos Exp $ */ + +/* + * Copyright (c) 2010 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "scsitest.h" + +#include "h_macros.h" + +ATF_TC(noisyeject); +ATF_TC_HEAD(noisyeject, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test for CD eject noisyness " + "(PR kern/43785)"); +} + +ATF_TC_BODY(noisyeject, tc) +{ + static char fname[] = "/dev/rcd0_"; + int part, fd, arg = 0; + + RL(part = getrawpartition()); + fname[strlen(fname)-1] = 'a' + part; + rump_init(); + /* + * Rump CD emulation has been fixed, so no longer a problem. + * + atf_tc_expect_signal(SIGSEGV, "PR kern/47646: Broken test or " + "a real problem in rump or the driver"); + */ + RL(fd = rump_sys_open(fname, O_RDWR)); + RL(rump_sys_ioctl(fd, DIOCEJECT, &arg)); + + ATF_REQUIRE_EQ(rump_scsitest_err[RUMP_SCSITEST_NOISYSYNC], 0); + RL(rump_sys_close(fd)); + // atf_tc_expect_fail("PR kern/43785"); + ATF_REQUIRE_EQ(rump_scsitest_err[RUMP_SCSITEST_NOISYSYNC], 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, noisyeject); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/dev/sysmon/t_swsensor.sh b/contrib/netbsd-tests/dev/sysmon/t_swsensor.sh new file mode 100755 index 0000000..7f98c1a --- /dev/null +++ b/contrib/netbsd-tests/dev/sysmon/t_swsensor.sh @@ -0,0 +1,404 @@ +# $NetBSD: t_swsensor.sh,v 1.9 2015/04/23 23:23:28 pgoyette Exp $ + +get_sensor_info() { + rump.envstat -x | \ + sed -e "\;swsensor;,\;/array;p" -e "d" +} + +get_sensor_key() { + local v + v=$(get_sensor_info | grep -A1 $1 | grep integer | \ + sed -e 's;<[/a-z]*>;;g') + if [ -z "$v" ] ; then + v="key_$1_not_found" + fi + echo $v +} + +get_powerd_event_count() { + grep "not running" powerd.log | wc -l +} + +get_rnd_bits_count() { + env RUMPHIJACK=blanket=/dev/random:/dev/urandom \ + RUMP_SERVER=unix://t_swsensor_socket \ + LD_PRELOAD=/usr/lib/librumphijack.so rndctl -l | \ + grep "swsensor-sensor" | \ + awk '{print $2}' +} + +check_powerd_event() { + event=$(grep "not running" powerd.log | \ + sed -e "$1p" -e "d" ) + event=${event##*//} + script=${event%% *} + event=${event#* } + device=${event%% *} + event=${event#* } + state=${event%% *} + sensor=${event#* } + sensor=${sensor% *} + + if [ "${script}" != "sensor_indicator" ] ; then + echo "Event uses wrong script: ${script}" + elif [ "${device}" != "swsensor" ] ; then + echo "Event uses wrong device: ${device}" + elif [ "${sensor}" != "sensor" ] ; then + echo "Event uses wrong sensor: ${sensor}" + elif [ "${state}" != "$2" ] ; then + echo "Event uses wrong state: ${state}" + fi +} + +# Start the rump server, then load the swsensor module with the +# requested properties + +start_rump() { + rump_allserver -l rumpvfs -l rumpdev -l rumpdev_sysmon ${RUMP_SERVER} + if [ $( get_sensor_info | wc -l ) -ne 0 ] ; then + rump.modunload swsensor + rump.modload -f $1 swsensor + else + rump.modload $1 swsensor + fi + return $? +} + +common_head() { + atf_set descr "$1" + atf_set timeout 120 + atf_set require.progs rump.powerd rump.envstat rump.modload \ + rump.halt rump.sysctl rump_server \ + sed grep awk \ + rndctl expr +} + +common_cleanup() { + rump.modunload swsensor + rump.halt +} + +create_envsys_conf_files() { + cat << ENV0 > env0.conf + swsensor { + refresh-timeout = 2s; + } +ENV0 + cat << ENV1 > env1.conf + swsensor { + sensor0 { critical-min = $(( $1 - $2 )); } + } +ENV1 + cat << ENV2 > env2.conf + swsensor { + sensor0 { critical-min = $1; } + } +ENV2 +} + +# Test body common to all sensors +# $1 sensor mode +# $2 initial sensor value +# $3 initial limit +# $4 amount to lower limit +# $5 difference from limit to trigger event +# $6 sensor flags, for FHAS_ENTROPY and FMONNOTSUPP + +common_body() { + # Start the rump-server process and load the module + modload_args="-i mode=$1 -i value=$2 -i limit=$3 ${6:+-i flags=$6}" + start_rump "$modload_args" + + # create configuration files for updates + create_envsys_conf_files $3 $4 + + if [ $? -ne 0 ] ; then + atf_skip "Cannot set-up rump environment" + fi + + # start powerd so we can detect sensor events + rump.powerd -n -d > powerd.log 2>&1 & + if [ -z "$(jobs)" ] ; then + skip_events=1 + echo "Skipping event sub-tests - powerd did not start" + else + skip_events=0 + expected_event=1 + fi + + # Step 0 - verify that sensor is registered + get_sensor_info | grep -q swsensor || + atf_fail "0: Device swsensor not registered" + + # Step 1 - update the refresh-timeout and verify + # (use $(( ... )) since the timeout is displayed in hex!) + rump.envstat -c env0.conf + if [ $(( $( get_sensor_key refresh-timeout ) )) -ne 2 ] ; then + atf_fail "1: Could not set refresh-timout to 2s" + fi + + # Step 2 - verify that we can read sensor's value + if [ $1 -ne 0 -a $( get_sensor_key cur-value ) -ne $2 ] ; then + atf_fail "2: Value not available" + fi + + # Step 3 - verify that changes in sensor value are seen + rump.sysctl -w hw.swsensor.cur_value=$(( $2 + 1 )) + if [ $( get_sensor_key cur-value ) -ne $(( $2 + 1 )) ] ; then + atf_fail "3: Value not updated" + fi + + # Step 4 - if sensor provides hw limit, make sure we can read it + if [ $1 -ne 0 ] ; then + if [ $( get_sensor_key critical-min ) -ne $3 ] ; then + atf_fail "4: Limit not set by device" + fi + fi + + # Step 5 - if sensor provides hw limit, make sure it works + if [ $1 -ne 0 -a ${skip_events} -eq 0 ] ; then + rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $5 )) + sleep 5 + cnt=$(get_powerd_event_count) + if [ ${cnt} -lt ${expected_event} ] ; then + atf_fail "5: No event triggered" + elif [ ${cnt} -gt ${expected_event} ] ; then + atf_fail "5: Multiple events triggered" + fi + evt=$( check_powerd_event ${cnt} "critical-under") + if [ -n "${evt}" ] ; then + atf_fail "5: ${evt}" + fi + expected_event=$(( 1 + ${expected_event} )) + fi + + # Step 6 - verify that we return to normal state + if [ $1 -ne 0 -a ${skip_events} -eq 0 ] ; then + rump.sysctl -w hw.swsensor.cur_value=$(( $3 + $5 )) + sleep 5 + cnt=$(get_powerd_event_count) + if [ ${cnt} -lt ${expected_event} ] ; then + atf_fail "6: No event triggered" + elif [ ${cnt} -gt ${expected_event} ] ; then + atf_fail "6: Multiple events triggered" + fi + evt=$( check_powerd_event ${cnt} "normal") + if [ -n "${evt}" ] ; then + atf_fail "6: ${evt}" + fi + expected_event=$(( 1 + ${expected_event} )) + fi + + # Step 7 - verify that we can set our own limit + + # Steps 7 thru 12 are skipped if the sensor cannot be monitored + if [ $( expr \( 0$6 / 2048 \) % 2 ) -ne 1 ] ; then + rump.envstat -c env1.conf + if [ $( get_sensor_key critical-min ) -ne $(( $3 - $4 )) ] ; then + atf_fail "7: Limit not set by envstat -c" + fi + + # Step 8 - make sure user-set limit works + if [ ${skip_events} -eq 0 ] ; then + rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $4 - $5 )) + sleep 5 + cnt=$(get_powerd_event_count) + if [ ${cnt} -lt ${expected_event} ] ; then + atf_fail "8: No event triggered" + elif [ ${cnt} -gt ${expected_event} ] ; then + atf_fail "8: Multiple events triggered" + fi + evt=$( check_powerd_event ${cnt} "critical-under") + if [ -n "${evt}" ] ; then + atf_fail "8: ${evt}" + fi + expected_event=$(( 1 + ${expected_event} )) + fi + + # Step 9 - verify that we return to normal state + if [ ${skip_events} -eq 0 ] ; then + rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $4 + $5 )) + sleep 5 + cnt=$(get_powerd_event_count) + if [ ${cnt} -lt ${expected_event} ] ; then + atf_fail "9: No event triggered" + elif [ ${cnt} -gt ${expected_event} ] ; then + atf_fail "9: Multiple events triggered" + fi + evt=$( check_powerd_event ${cnt} "normal") + if [ -n "${evt}" ] ; then + atf_fail "9: ${evt}" + fi + expected_event=$(( 1 + ${expected_event} )) + fi + + # Step 10 - reset to defaults + rump.envstat -S + if [ $1 -eq 0 ] ; then + get_sensor_info | grep -q critical-min && + atf_fail "10: Failed to clear a limit with envstat -S" + else + if [ $( get_sensor_key critical-min ) -ne $3 ] ; then + atf_fail "10: Limit not reset to initial value" + fi + fi + + # Step 11 - see if more events occur + if [ ${skip_events} -eq 0 ] ; then + rump.envstat -c env0.conf + rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $4 - $5 )) + sleep 5 + cnt=$(get_powerd_event_count) + if [ ${cnt} -ge ${expected_event} ] ; then + if [ $1 -ne 2 ] ; then + atf_fail "11b Event triggered after reset" + fi + evt=$( check_powerd_event ${cnt} "critical-under") + if [ -n "${evt}" ] ; then + atf_fail "11a: ${evt}" + fi + fi + fi + + # Step 12 - make sure we can set new limits once more + rump.envstat -c env2.conf + if [ $( get_sensor_key critical-min ) -ne $3 ] ; then + atf_fail "12a: Limit not reset to same value" + fi + rump.envstat -c env1.conf + if [ $( get_sensor_key critical-min ) -ne $(( $3 - $4 )) ] ; then + atf_fail "12b: Limit not reset to new value" + fi + fi + + # Step 13 - confirm registration (or lack thereof) with rndctl + rnd_bits=$( get_rnd_bits_count ) + if [ $( expr \( 0$6 / 8192 \) % 2 ) -eq 1 ] ; then + if [ -z "$rnd_bits" ] ; then + atf_fail "13a: Not registered with rndctl" + fi + else + if [ -n "$rnd_bits" ] ; then + atf_fail "13b: Wrongly registered with rndctl" + fi + fi + + # Steps 14 and 15 are only if sensor is providing entropy + if [ $( expr \( 0$6 / 8192 \) % 2 ) -ne 1 ] ; then + return + fi + + # Step 14 - make sure entropy collected when device is being polled + rump.envstat -c env0.conf + rump.sysctl -w hw.swsensor.cur_value=$3 + sleep 5 + rump.sysctl -w hw.swsensor.cur_value=$(( $3 + $4 )) + sleep 5 + new_rnd_bits=$( get_rnd_bits_count ) + if [ $new_rnd_bits -le $rnd_bits ] ; then + atf_expect_fail "PR kern/47661" + atf_fail "14a: entropy bits did not increase after polling" + fi + rnd_bits=$new_rnd_bits + sleep 5 + new_rnd_bits=$( get_rnd_bits_count ) + if [ $new_rnd_bits -gt $rnd_bits ] ; then + atf_expect_fail "PR kern/47661" + atf_fail "14b: entropy bits increased after poll with no value change" + fi + + # Step 15 - make sure entropy collected when device is interrogated + # + rump.envstat -c env0.conf + rump.sysctl -w hw.swsensor.cur_value=$3 + get_sensor_key cur-value + rnd_bits=$( get_rnd_bits_count ) + rump.sysctl -w hw.swsensor.cur_value=$(( $3 + $4 )) + get_sensor_key cur-value + new_rnd_bits=$( get_rnd_bits_count ) + if [ $new_rnd_bits -le $rnd_bits ] ; then + atf_expect_fail "PR kern/47661" + atf_fail "15a: entropy bits did not increase after interrogation" + fi + rnd_bits=$new_rnd_bits + get_sensor_key cur-value + new_rnd_bits=$( get_rnd_bits_count ) + if [ $new_rnd_bits -gt $rnd_bits ] ; then + atf_expect_fail "PR kern/47661" + atf_fail "15b: entropy bits increased after interrogation with no value change" + fi +} + +atf_test_case simple_sensor cleanup +simple_sensor_head() { + common_head "Test a simple sensor" +} + +simple_sensor_body() { + common_body 0 50 30 10 1 +} + +simple_sensor_cleanup() { + common_cleanup +} + +atf_test_case limit_sensor cleanup +limit_sensor_head() { + common_head "Test a sensor with internal limit" +} + +limit_sensor_body() { + common_body 1 45 25 8 2 +} + +limit_sensor_cleanup() { + common_cleanup +} + +atf_test_case alarm_sensor cleanup +alarm_sensor_head() { + common_head "Test a sensor with internal checking" +} + +alarm_sensor_body() { + common_body 2 40 20 6 3 +} + +alarm_sensor_cleanup() { + common_cleanup +} + +atf_test_case entropy_polled_sensor cleanup +entropy_polled_sensor_head() { + common_head "Test a simple sensor that provides entropy" +} + +entropy_polled_sensor_body() { + common_body 0 50 30 10 1 8192 +} + +entropy_polled_sensor_cleanup() { + common_cleanup +} + +atf_test_case entropy_interrupt_sensor cleanup +entropy_interrupt_sensor_head() { + common_head "Test a sensor that provides entropy without polling" +} + +entropy_interrupt_sensor_body() { + common_body 0 50 30 10 1 10240 +} + +entropy_interrupt_sensor_cleanup() { + common_cleanup +} + +atf_init_test_cases() { + RUMP_SERVER="unix://t_swsensor_socket" ; export RUMP_SERVER + atf_add_test_case simple_sensor + atf_add_test_case limit_sensor + atf_add_test_case alarm_sensor + atf_add_test_case entropy_polled_sensor + atf_add_test_case entropy_interrupt_sensor +} diff --git a/contrib/netbsd-tests/dev/sysmon/t_swwdog.c b/contrib/netbsd-tests/dev/sysmon/t_swwdog.c new file mode 100644 index 0000000..5e5fd99 --- /dev/null +++ b/contrib/netbsd-tests/dev/sysmon/t_swwdog.c @@ -0,0 +1,193 @@ +/* $NetBSD: t_swwdog.c,v 1.7 2017/01/13 21:30:39 christos Exp $ */ + +/* + * Copyright (c) 2010 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "h_macros.h" + +static volatile sig_atomic_t tcount; + +static void +sigcount(int sig) +{ + + assert(sig == SIGUSR1); + tcount++; +} + +/* + * Since we are testing for swwdog's ability to reboot/panic, we need + * to fork and monitor the exit status from the parent and report + * something sensible back to atf. + */ +static int +testbody(int max) +{ + char wname[WDOG_NAMESIZE]; + struct wdog_conf wc; + struct wdog_mode wm; + pid_t p1, p2; + int status; + int fd; + + signal(SIGUSR1, sigcount); + + switch ((p1 = fork())) { + case 0: + break; + case -1: + atf_tc_fail_errno("fork"); + break; + default: + p2 = wait(&status); + ATF_REQUIRE_EQ(p1, p2); + ATF_REQUIRE_EQ(tcount, max); + return status; + } + + rump_init(); + + fd = rump_sys_open("/dev/watchdog", O_RDWR); + if (fd == -1) + err(1, "open watchdog"); + + wc.wc_count = 1; + wc.wc_names = wname; + + if (rump_sys_ioctl(fd, WDOGIOC_GWDOGS, &wc) == -1) + err(1, "can't fetch watchdog names"); + + if (wc.wc_count) { + assert(wc.wc_count == 1); + + strlcpy(wm.wm_name, wc.wc_names, sizeof(wm.wm_name)); + wm.wm_mode = WDOG_MODE_ETICKLE; + wm.wm_period = 1; + if (rump_sys_ioctl(fd, WDOGIOC_SMODE, &wm) == -1) + atf_tc_fail_errno("failed to set tickle"); + + usleep(400000); + if (max == 1) + rump_sys_ioctl(fd, WDOGIOC_TICKLE); + else { + wm.wm_mode = WDOG_MODE_DISARMED; + rump_sys_ioctl(fd, WDOGIOC_SMODE, &wm); + } + kill(getppid(), SIGUSR1); + + sleep(2); + printf("staying alive\n"); + kill(getppid(), SIGUSR1); + _exit(2); + } + /* fail */ + printf("no watchdog registered!\n"); + _exit(1); +} + +ATF_TC(reboot); +ATF_TC_HEAD(reboot, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check swwdog reboot capability"); +} + +ATF_TC_BODY(reboot, tc) +{ + extern bool rumpns_swwdog_reboot; + int status; + + /* XXX: should use sysctl */ + rumpns_swwdog_reboot = true; + status = testbody(1); + + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE_EQ(WEXITSTATUS(status), 0); +} + +ATF_TC(panic); +ATF_TC_HEAD(panic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check swwdog panic capability"); +} + +ATF_TC_BODY(panic, tc) +{ + extern bool rumpns_swwdog_reboot; + int status; + + /* XXX: should use sysctl */ + rumpns_swwdog_reboot = false; + status = testbody(1); + + ATF_REQUIRE(WIFSIGNALED(status)); + ATF_REQUIRE_EQ(WTERMSIG(status), SIGABRT); +} + +ATF_TC(disarm); +ATF_TC_HEAD(disarm, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check swwdog disarm capability"); +} + +ATF_TC_BODY(disarm, tc) +{ + int status; + + status = testbody(2); + + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE_EQ(WEXITSTATUS(status), 2); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, panic); + ATF_TP_ADD_TC(tp, reboot); + ATF_TP_ADD_TC(tp, disarm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/dev/usb/t_hid.c b/contrib/netbsd-tests/dev/usb/t_hid.c new file mode 100644 index 0000000..31c289b --- /dev/null +++ b/contrib/netbsd-tests/dev/usb/t_hid.c @@ -0,0 +1,267 @@ +/* $NetBSD: t_hid.c,v 1.8 2016/05/05 17:40:26 jakllsch Exp $ */ + +/* + * Copyright (c) 2016 Jonathan A. Kollasch + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 +__RCSID("$NetBSD: t_hid.c,v 1.8 2016/05/05 17:40:26 jakllsch Exp $"); + +#include +#include +#include +#include +#include + +#include + +#define hid_start_parse rumpns_hid_start_parse +#define hid_end_parse rumpns_hid_end_parse +#define hid_get_item rumpns_hid_get_item +#define hid_locate rumpns_hid_locate +#define hid_report_size rumpns_hid_report_size +#define hid_get_data rumpns_hid_get_data +#define hid_get_udata rumpns_hid_get_udata +#define uhidevdebug rumpns_uhidevdebug +#include +#include +#include + +#include "../../lib/libusbhid/hid_test_data.c" + +#define MYd_ATF_CHECK_EQ(d, v) \ + ATF_CHECK_EQ_MSG(d, v, "== %d", (d)) + +#define MYld_ATF_CHECK_EQ(d, v) \ + ATF_CHECK_EQ_MSG(d, v, "== %ld", (d)) + +#define MYu_ATF_CHECK_EQ(d, v) \ + ATF_CHECK_EQ_MSG(d, v, "== %u", (d)) + +#define MYlu_ATF_CHECK_EQ(d, v) \ + ATF_CHECK_EQ_MSG(d, v, "== %lu", (d)) + +#define MYx_ATF_CHECK_EQ(d, v) \ + ATF_CHECK_EQ_MSG(d, v, "== 0x%x", (d)) + +#define MYlx_ATF_CHECK_EQ(d, v) \ + ATF_CHECK_EQ_MSG(d, v, "== 0x%lx", (d)) + +int uhidevdebug; + +ATF_TC(khid); + +ATF_TC_HEAD(khid, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check kernel hid.c"); +} + +static int +locate_item(const void *desc, int size, u_int32_t u, u_int8_t id, + enum hid_kind k, struct hid_item *hip) +{ + struct hid_data *d; + struct hid_item h; + + h.report_ID = 0; + for (d = hid_start_parse(desc, size, k); hid_get_item(d, &h); ) { + if (h.kind == k && !(h.flags & HIO_CONST) && + (/*XXX*/uint32_t)h.usage == u && h.report_ID == id) { + if (hip != NULL) + *hip = h; + hid_end_parse(d); + return (1); + } + } + hid_end_parse(d); + return (0); +} + +ATF_TC_BODY(khid, tc) +{ + int ret; + struct hid_item hi; + + uhidevdebug = 0; + + rump_init(); + + rump_schedule(); + + ret = locate_item(range_test_report_descriptor, + sizeof(range_test_report_descriptor), 0xff000003, 0, hid_input, + &hi); + ATF_REQUIRE(ret > 0); + MYu_ATF_CHECK_EQ(hi.loc.size, 32); + MYu_ATF_CHECK_EQ(hi.loc.count, 1); + MYu_ATF_CHECK_EQ(hi.loc.pos, 0); + MYx_ATF_CHECK_EQ(hi.flags, 0); + MYd_ATF_CHECK_EQ(hi.logical_minimum, -2147483648); + MYd_ATF_CHECK_EQ(hi.logical_maximum, 2147483647); + MYd_ATF_CHECK_EQ(hi.physical_minimum, -2147483648); + MYd_ATF_CHECK_EQ(hi.physical_maximum, 2147483647); + MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report, + &hi.loc), -2147483648); + MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report, + &hi.loc), -1); + MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report, + &hi.loc), 1); + MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report, + &hi.loc), 2147483647); + + ret = locate_item(range_test_report_descriptor, + sizeof(range_test_report_descriptor), 0xff000002, 0, hid_input, + &hi); + ATF_REQUIRE(ret > 0); + MYu_ATF_CHECK_EQ(hi.loc.size, 16); + MYu_ATF_CHECK_EQ(hi.loc.count, 1); + MYu_ATF_CHECK_EQ(hi.loc.pos, 32); + MYx_ATF_CHECK_EQ(hi.flags, 0); + MYd_ATF_CHECK_EQ(hi.logical_minimum, -32768); + MYd_ATF_CHECK_EQ(hi.logical_maximum, 32767); + MYd_ATF_CHECK_EQ(hi.physical_minimum, -32768); + MYd_ATF_CHECK_EQ(hi.physical_maximum, 32767); + MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report, + &hi.loc), -32768); + MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report, + &hi.loc), -1); + MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report, + &hi.loc), 1); + MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report, + &hi.loc), 32767); + + ret = locate_item(range_test_report_descriptor, + sizeof(range_test_report_descriptor), 0xff000001, 0, hid_input, + &hi); + ATF_REQUIRE(ret > 0); + MYu_ATF_CHECK_EQ(hi.loc.size, 8); + MYu_ATF_CHECK_EQ(hi.loc.count, 1); + MYu_ATF_CHECK_EQ(hi.loc.pos, 48); + MYx_ATF_CHECK_EQ(hi.flags, 0); + MYd_ATF_CHECK_EQ(hi.logical_minimum, -128); + MYd_ATF_CHECK_EQ(hi.logical_maximum, 127); + MYd_ATF_CHECK_EQ(hi.physical_minimum, -128); + MYd_ATF_CHECK_EQ(hi.physical_maximum, 127); + MYld_ATF_CHECK_EQ(hid_get_data(range_test_minimum_report, + &hi.loc), -128); + MYld_ATF_CHECK_EQ(hid_get_data(range_test_negative_one_report, + &hi.loc), -1); + MYld_ATF_CHECK_EQ(hid_get_data(range_test_positive_one_report, + &hi.loc), 1); + MYld_ATF_CHECK_EQ(hid_get_data(range_test_maximum_report, + &hi.loc), 127); + + + ret = locate_item(unsigned_range_test_report_descriptor, + sizeof(unsigned_range_test_report_descriptor), 0xff000013, 0, + hid_input, &hi); + ATF_REQUIRE(ret > 0); + MYu_ATF_CHECK_EQ(hi.loc.size, 32); + MYu_ATF_CHECK_EQ(hi.loc.count, 1); + MYu_ATF_CHECK_EQ(hi.loc.pos, 0); + MYx_ATF_CHECK_EQ(hi.flags, 0); + MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report, + &hi.loc), 0x0); + MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report, + &hi.loc), 0x1); + MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report, + &hi.loc), 0xfffffffe); + MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report, + &hi.loc), 0xffffffff); + + ret = locate_item(unsigned_range_test_report_descriptor, + sizeof(unsigned_range_test_report_descriptor), 0xff000012, 0, + hid_input, &hi); + ATF_REQUIRE(ret > 0); + MYu_ATF_CHECK_EQ(hi.loc.size, 16); + MYu_ATF_CHECK_EQ(hi.loc.count, 1); + MYu_ATF_CHECK_EQ(hi.loc.pos, 32); + MYx_ATF_CHECK_EQ(hi.flags, 0); + MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report, + &hi.loc), 0x0); + MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report, + &hi.loc), 0x1); + MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report, + &hi.loc), 0xfffe); + MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report, + &hi.loc), 0xffff); + + ret = locate_item(unsigned_range_test_report_descriptor, + sizeof(unsigned_range_test_report_descriptor), 0xff000011, 0, + hid_input, &hi); + ATF_REQUIRE(ret > 0); + MYu_ATF_CHECK_EQ(hi.loc.size, 8); + MYu_ATF_CHECK_EQ(hi.loc.count, 1); + MYu_ATF_CHECK_EQ(hi.loc.pos, 48); + MYx_ATF_CHECK_EQ(hi.flags, 0); + MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_minimum_report, + &hi.loc), 0x0); + MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_positive_one_report, + &hi.loc), 0x1); + MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_negative_one_report, + &hi.loc), 0xfe); + MYlx_ATF_CHECK_EQ(hid_get_udata(unsigned_range_test_maximum_report, + &hi.loc), 0xff); + + rump_unschedule(); +} + +ATF_TC(khid_parse_just_pop); + +ATF_TC_HEAD(khid_parse_just_pop, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check kernel hid.c for " + "Pop on empty stack bug"); +} + +ATF_TC_BODY(khid_parse_just_pop, tc) +{ + struct hid_data *hdp; + struct hid_item hi; + + rump_init(); + + rump_schedule(); + + hdp = hid_start_parse(just_pop_report_descriptor, + sizeof just_pop_report_descriptor, hid_none); + while (hid_get_item(hdp, &hi) > 0) { + } + hid_end_parse(hdp); + + rump_unschedule(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, khid); + ATF_TP_ADD_TC(tp, khid_parse_just_pop); + + return atf_no_error(); +} + diff --git a/contrib/netbsd-tests/fs/cd9660/pr_48787.image.bz2.uue b/contrib/netbsd-tests/fs/cd9660/pr_48787.image.bz2.uue new file mode 100644 index 0000000..d8f7488 --- /dev/null +++ b/contrib/netbsd-tests/fs/cd9660/pr_48787.image.bz2.uue @@ -0,0 +1,103 @@ +begin 644 pr_48787.image.bz2 +M0EIH.3%!62936>D^3`0``+M_V?_7U17T!W_H/^_?8..V$"1DB`0``B$`0I-H +MP`+N-!HLI8)131H4](]3TC(VH`S4;4````T&@R&C0R:!*$1D(8B:C!,(Q-&3 +M-`!,``"&:`FC'&AH&C3(TT:9`8F"``&@-`:9`8$R`J1(A&A$R&391FA#TC0V +MHQ'J8@&T@VHT`QII&Z!"B5;S7YT+1"ZB8Y+5"M,5_J`!]Y:[$2%,%W`ZAA2@ +MVE)'DK^*?'3QU`DFQ4@22)(B[N3GZN?E<)`DDB.C)7\X71*B1K*2))(DD1HI +MU5$TUVF[4JP89^FHY$B*FEBC(RN$5"8O'XO]1++(._=;ZKXR%:QK3^W7/>RT +M8EODZ#MX53U8C0F]6O.G4J/9YNQA$B2))$<[H5(]"2=])+_3RW)O*AI[)9@D^JV5RK3?43-;"G;69#AH8,(5;:7UN,<5%98$9;9; +M\G*RT*37_9[;D'P/`1(R-$D.!36\S6N:_M>!][4*&3?'S858VCD+-3PINFR8 +M,C9?J+9ME:9.,_OR\C;3K'27W:K<<&>MMC;HS".>68$Y&.B608>JM?)+3$:Z +MY539A<7-E*'_YY..1'ECZBIG5%1%U93-9*1-5T_C!\)&2@?*CQB>(Q\0G(J< +M6%PDB4L,2$>Q4IM%6A+%4K/0-!7*348,9!&#<9@JNP&+LBI>+9&*JC6ZE293 +MY%-8H^HI12#5$9J;"0@$DA.](1+1.SH#B10&H6C48:PMPI7=#M2A@I%'\J2P +M.Y(+0C:B.&>F(^[(>)1+M\+QH%@O#4OE(\RE*14IZ7+9R*G8IYV^O=Y<=4HY +M1C@SCIZ=$DT]"`>IH&@`#1Z)M3"-#(T#$4:I[4U`/4T-````````````!PT-&31H +MT::&1D,(`R`&0::``!D#(`D4IZIZ0-`T````````````]&II7`12+EV$9U/B +MB!*_@T]?CB(F_;A17-%[AD,R8`JV@70VUC,Y6`FQ"$@1@M3"$@0)"3F`Y&Q/$XJBC2?^*)EA9:/'NE+<&E/_K^ +M-Z0($"0E11*I%KQK=*`$'NO&"YPP%*V4`5T>42;8B[:=M@:9#;@')!UFD +M8$)CB(&5G68PD`TD`[D"*AV+N\79)G^Q/SOS[CLC2P3T;\WCMH#X(5\++`-# +ML-+?DXEFS9H@P06,,HP2-X<1W%B*AY`JW`=,R?NG%O?)8;N6134$BXK2#F&& +M*"8&QUDIX$R\2.;XAFVSP/=K'6.!M8;%=UGWD84CA7$<.IJ0]NS'LEV@J(Q[ +MA='$&9W%-><1MMG8-JCG-DG+D,4"H>!`EJIEKV61?:5TW2M97U?>B%$S@N0G +M4!Q5$=A,ES!Z%;4P):4`FG@`X=YHB%#"PIU084Y4 +M@/JFD\8E9G8Y\8:0TJYP'=17J(:!3R>)1/FE%'Z2XBYRI259/935.OC-50: +M#[&,:!IG0R$A"P8>:89+I+'"&$B")A'5G8B+ZJ14JXH:'.:@IH0&T(0($A+" +/#6J,VO\7="Thomas Schmitt (scdbackup@gmx.net)", +# ="Thomas Schmitt" and ="1999" +# an Open Source license approved by opensource.org +# + +mntpnt="" + +atf_test_case pr_kern_48787 cleanup +pr_kern_48787_head() { + atf_set "descr" "Verifies 32bit overflow isssues from PR kern/48787 are fixed" + atf_set "require.user" "root" + atf_set "require.progs" "rump_cd9660 bunzip2 stat" + atf_set "timeout" 6000 +} + +pr_kern_48787_body() { + avail=$( df -Pk . | awk '{if (NR==2) print $4}' ) + if [ $avail -lt 4500000 ]; then + atf_skip "not enough free disk space, have ${avail} Kbytes, need ~ 4500000 Kbytes" + fi + bunzip2 < $(atf_get_srcdir)/pr_48787.image.bz2 > pr_48787.image + mntpnt=$(pwd)/mnt + mkdir ${mntpnt} + rump_cd9660 -o norrip ./pr_48787.image ${mntpnt} + if [ ! -r ${mntpnt}/small_file ]; then + atf_fail "${mntpnt}/small_file does not exist" + fi + if [ ! -r ${mntpnt}/my/large_file ]; then + atf_fail "${mntpnt}/my/large_file does not exist" + fi + umount ${mntpnt} + rump_cd9660 ./pr_48787.image ${mntpnt} + if [ ! -r ${mntpnt}/small_file ]; then + atf_fail "${mntpnt}/small_file does not exist" + fi + if [ ! -r ${mntpnt}/my/large_file ]; then + atf_fail "${mntpnt}/my/large_file does not exist" + fi + echo "this assumes current cd9660 inode encoding - adapt on changes" + atf_check -o match:"^4329541966$" stat -f "%i" ${mntpnt}/small_file + atf_check -o match:"^4329545920$" stat -f "%i" ${mntpnt}/my/large_file + umount ${mntpnt} + touch "done" +} + +pr_kern_48787_cleanup() { + if [ ! -f done ]; then + if [ "x${mntpnt}" != "x" ]; then + umount -f ${mntpnt} || true + fi + fi +} + +atf_init_test_cases() { + atf_add_test_case pr_kern_48787 +} diff --git a/contrib/netbsd-tests/fs/common/fstest_ext2fs.c b/contrib/netbsd-tests/fs/common/fstest_ext2fs.c new file mode 100644 index 0000000..85bb79f --- /dev/null +++ b/contrib/netbsd-tests/fs/common/fstest_ext2fs.c @@ -0,0 +1,139 @@ +/* $NetBSD: fstest_ext2fs.c,v 1.2 2010/07/30 16:15:05 pooka Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nicolas Joly. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_fsmacros.h" + +struct ext2fstestargs { + struct ufs_args ta_uargs; + char ta_devpath[MAXPATHLEN]; + char ta_imgpath[MAXPATHLEN]; +}; + +int +ext2fs_fstest_newfs(const atf_tc_t *tc, void **buf, const char *image, + off_t size, void *fspriv) +{ + char cmd[1024]; + int res; + static unsigned int num = 0; + struct ext2fstestargs *args; + + size /= 512; + snprintf(cmd, 1024, "newfs_ext2fs -F -s %"PRId64" %s >/dev/null", + size, image); + res = system(cmd); + if (res != 0) + return res; + + res = rump_init(); + if (res != 0) + return res; + + args = calloc(1, sizeof(*args)); + if (args == NULL) + return -1; + + snprintf(args->ta_devpath, MAXPATHLEN, "/dev/device%d.ext2fs", num); + snprintf(args->ta_imgpath, MAXPATHLEN, "%s", image); + args->ta_uargs.fspec = args->ta_devpath; + + res = rump_pub_etfs_register(args->ta_devpath, image, RUMP_ETFS_BLK); + if (res != 0) { + free(args); + return res; + } + + *buf = args; + num++; + + return res; +} + +int +ext2fs_fstest_delfs(const atf_tc_t *tc, void *buf) +{ + int res; + struct ext2fstestargs *args = buf; + + res = rump_pub_etfs_remove(args->ta_devpath); + if (res != 0) + return res; + + res = unlink(args->ta_imgpath); + if (res != 0) + return res; + + free(args); + + return 0; +} + +int +ext2fs_fstest_mount(const atf_tc_t *tc, void *buf, const char *path, int flags) +{ + int res; + struct ext2fstestargs *args = buf; + + res = rump_sys_mkdir(path, 0777); + if (res == -1) + return res; + + res = rump_sys_mount(MOUNT_EXT2FS, path, flags, &args->ta_uargs, + sizeof(args->ta_uargs)); + return res; +} + +int +ext2fs_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + int res; + + res = rump_sys_unmount(path, flags); + if (res == -1) + return res; + + res = rump_sys_rmdir(path); + return res; +} diff --git a/contrib/netbsd-tests/fs/common/fstest_ffs.c b/contrib/netbsd-tests/fs/common/fstest_ffs.c new file mode 100644 index 0000000..7ae4e8f --- /dev/null +++ b/contrib/netbsd-tests/fs/common/fstest_ffs.c @@ -0,0 +1,156 @@ +/* $NetBSD: fstest_ffs.c,v 1.6 2012/08/05 02:03:05 riastradh Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nicolas Joly. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_fsmacros.h" + +struct ffstestargs { + struct ufs_args ta_uargs; + char ta_devpath[MAXPATHLEN]; + char ta_imgpath[MAXPATHLEN]; +}; + +int +ffs_fstest_newfs(const atf_tc_t *tc, void **buf, const char *image, off_t size, + void *fspriv) +{ + char cmd[1024]; + int res; + static unsigned int num = 0; + struct ffstestargs *args; + struct sigaction act, oact; + + size /= 512; + snprintf(cmd, 1024, "newfs -F -s %"PRId64" %s >/dev/null", size, image); + memset(&act, 0, sizeof(act)); + act.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &act, &oact); + res = system(cmd); + sigaction(SIGCHLD, &oact, NULL); + if (res != 0) + return res; + + res = rump_init(); + if (res != 0) + return res; + + args = calloc(1, sizeof(*args)); + if (args == NULL) + return -1; + + snprintf(args->ta_devpath, MAXPATHLEN, "/dev/device%d.ffs", num); + snprintf(args->ta_imgpath, MAXPATHLEN, "%s", image); + args->ta_uargs.fspec = args->ta_devpath; + + res = rump_pub_etfs_register(args->ta_devpath, image, RUMP_ETFS_BLK); + if (res != 0) { + free(args); + return res; + } + + *buf = args; + num++; + + return 0; +} +__strong_alias(ffslog_fstest_newfs,ffs_fstest_newfs); + +int +ffs_fstest_delfs(const atf_tc_t *tc, void *buf) +{ + int res; + struct ffstestargs *args = buf; + + res = rump_pub_etfs_remove(args->ta_devpath); + if (res != 0) { + errno = res; + return -1; + } + + res = unlink(args->ta_imgpath); + if (res != 0) + return res; + + free(args); + + return 0; +} +__strong_alias(ffslog_fstest_delfs,ffs_fstest_delfs); + +int +ffs_fstest_mount(const atf_tc_t *tc, void *buf, const char *path, int flags) +{ + int res; + struct ffstestargs *args = buf; + + res = rump_sys_mkdir(path, 0777); + if (res == -1) + return res; + + res = rump_sys_mount(MOUNT_FFS, path, flags, &args->ta_uargs, + sizeof(args->ta_uargs)); + return res; +} + +int +ffslog_fstest_mount(const atf_tc_t *tc, void *buf, const char *path, int flags) +{ + + return ffs_fstest_mount(tc, buf, path, flags | MNT_LOG); +} + +int +ffs_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + int res; + + res = rump_sys_unmount(path, flags); + if (res == -1) + return res; + + res = rump_sys_rmdir(path); + return res; +} +__strong_alias(ffslog_fstest_unmount,ffs_fstest_unmount); diff --git a/contrib/netbsd-tests/fs/common/fstest_lfs.c b/contrib/netbsd-tests/fs/common/fstest_lfs.c new file mode 100644 index 0000000..597ca23 --- /dev/null +++ b/contrib/netbsd-tests/fs/common/fstest_lfs.c @@ -0,0 +1,190 @@ +/* $NetBSD: fstest_lfs.c,v 1.5 2015/08/30 18:27:26 dholland Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nicolas Joly. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_fsmacros.h" +#include "mount_lfs.h" + +struct lfstestargs { + struct ufs_args ta_uargs; + pthread_t ta_cleanerthread; + sem_t ta_cleanerloop; + char ta_devpath[MAXPATHLEN]; + char ta_imgpath[MAXPATHLEN]; + char ta_mntpath[MAXPATHLEN]; + char ta_hostpath[MAXPATHLEN]; +}; + +int +lfs_fstest_newfs(const atf_tc_t *tc, void **buf, const char *image, off_t size, + void *fspriv) +{ + char cmd[1024]; + int res; + static unsigned int num = 0; + struct lfstestargs *args; + + size /= 512; + snprintf(cmd, 1024, "newfs_lfs -D -F -s %"PRId64" ./%s >/dev/null", + size, image); + res = system(cmd); + if (res != 0) + return res; + + res = rump_init(); + if (res != 0) + return res; + + args = calloc(1, sizeof(*args)); + if (args == NULL) + return -1; + + strcpy(args->ta_hostpath, image); + snprintf(args->ta_devpath, MAXPATHLEN, "/dev/device%d.lfs", num); + snprintf(args->ta_imgpath, MAXPATHLEN, "%s", image); + args->ta_uargs.fspec = args->ta_devpath; + sem_init(&args->ta_cleanerloop, 0, 0); + + res = rump_pub_etfs_register(args->ta_devpath, image, RUMP_ETFS_BLK); + if (res != 0) { + free(args); + return res; + } + + *buf = args; + num++; + + return 0; +} + +int +lfs_fstest_delfs(const atf_tc_t *tc, void *buf) +{ + int res; + struct lfstestargs *args = buf; + + res = rump_pub_etfs_remove(args->ta_devpath); + if (res != 0) + return res; + + res = unlink(args->ta_imgpath); + if (res != 0) + return res; + + pthread_join(args->ta_cleanerthread, NULL); + free(args); + + return 0; +} + +static void * +cleaner(void *arg) +{ + char thepath[MAXPATHLEN]; + struct lfstestargs *args = arg; + const char *the_argv[7]; + char buf[64]; + + /* this inspired by the cleaner code. fixme */ + sprintf(thepath, "/dev/r%s", args->ta_devpath+5); + rump_pub_etfs_register(thepath, args->ta_hostpath, RUMP_ETFS_CHR); + sprintf(buf, "%p", &args->ta_cleanerloop); + + the_argv[0] = "megamaid"; + the_argv[1] = "-D"; /* don't fork() & detach */ + the_argv[2] = "-S"; + the_argv[3] = buf; + the_argv[4] = args->ta_mntpath; + the_argv[5] = NULL; + + /* xxxatf */ + optind = 1; + opterr = 1; + + lfs_cleaner_main(5, __UNCONST(the_argv)); + + return NULL; +} + +int +lfs_fstest_mount(const atf_tc_t *tc, void *buf, const char *path, int flags) +{ + struct lfstestargs *args = buf; + int res; + + res = rump_sys_mkdir(path, 0777); + if (res == -1) + return res; + + res = rump_sys_mount(MOUNT_LFS, path, flags, &args->ta_uargs, + sizeof(args->ta_uargs)); + if (res == -1) + return res; + + strcpy(args->ta_mntpath, path); + res = pthread_create(&args->ta_cleanerthread, NULL, cleaner, args); + if (res) + return res; + + /* wait for cleaner to initialize */ + sem_wait(&args->ta_cleanerloop); + + return 0; +} + +int +lfs_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + int res; + + res = rump_sys_unmount(path, flags); + if (res == -1) { + return res; + } + + res = rump_sys_rmdir(path); + return res; +} diff --git a/contrib/netbsd-tests/fs/common/fstest_msdosfs.c b/contrib/netbsd-tests/fs/common/fstest_msdosfs.c new file mode 100644 index 0000000..2c94e3f --- /dev/null +++ b/contrib/netbsd-tests/fs/common/fstest_msdosfs.c @@ -0,0 +1,140 @@ +/* $NetBSD: fstest_msdosfs.c,v 1.3 2012/03/26 15:10:26 njoly Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nicolas Joly. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_fsmacros.h" + +struct msdosfstestargs { + struct msdosfs_args ta_uargs; + char ta_devpath[MAXPATHLEN]; + char ta_imgpath[MAXPATHLEN]; +}; + +int +msdosfs_fstest_newfs(const atf_tc_t *tc, void **buf, const char *image, + off_t size, void *fspriv) +{ + char cmd[1024]; + int res; + static unsigned int num = 0; + struct msdosfstestargs *args; + + size /= 512; size -= (size % 63); + snprintf(cmd, 1024, "newfs_msdos -C %"PRId64"s %s >/dev/null", + size, image); + res = system(cmd); + if (res != 0) + return res; + + res = rump_init(); + if (res != 0) + return res; + + args = calloc(1, sizeof(*args)); + if (args == NULL) + return -1; + + snprintf(args->ta_devpath, MAXPATHLEN, "/dev/device%d.msdosfs", num); + snprintf(args->ta_imgpath, MAXPATHLEN, "%s", image); + args->ta_uargs.fspec = args->ta_devpath; + args->ta_uargs.mask = 0755; + + res = rump_pub_etfs_register(args->ta_devpath, image, RUMP_ETFS_BLK); + if (res != 0) { + free(args); + return res; + } + + *buf = args; + num++; + + return 0; +} + +int +msdosfs_fstest_delfs(const atf_tc_t *tc, void *buf) +{ + int res; + struct msdosfstestargs *args = buf; + + res = rump_pub_etfs_remove(args->ta_devpath); + if (res != 0) + return res; + + res = unlink(args->ta_imgpath); + if (res != 0) + return res; + + free(args); + + return 0; +} + +int +msdosfs_fstest_mount(const atf_tc_t *tc, void *buf, const char *path, int flags) +{ + int res; + struct msdosfstestargs *args = buf; + + res = rump_sys_mkdir(path, 0777); + if (res == -1) + return res; + + res = rump_sys_mount(MOUNT_MSDOS, path, flags, &args->ta_uargs, + sizeof(args->ta_uargs)); + return res; +} + +int +msdosfs_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + int res; + + res = rump_sys_unmount(path, flags); + if (res == -1) + return res; + + res = rump_sys_rmdir(path); + return res; +} diff --git a/contrib/netbsd-tests/fs/common/fstest_nfs.c b/contrib/netbsd-tests/fs/common/fstest_nfs.c new file mode 100644 index 0000000..5ef256f --- /dev/null +++ b/contrib/netbsd-tests/fs/common/fstest_nfs.c @@ -0,0 +1,326 @@ +/* $NetBSD: fstest_nfs.c,v 1.9 2011/02/28 21:08:46 pooka Exp $ */ + +/* + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "h_fsmacros.h" +#include "mount_nfs.h" +#include "../../net/config/netconfig.c" + +#define SERVERADDR "10.3.2.1" +#define SERVERROADDR "10.4.2.1" +#define CLIENTADDR "10.3.2.2" +#define CLIENTROADDR "10.4.2.2" +#define NETNETMASK "255.255.255.0" +#define EXPORTPATH "/myexport" + +static void +childfail(int status) +{ + + atf_tc_fail("child died"); +} + +/* fork rump nfsd, configure interface */ +static int +donewfs(const atf_tc_t *tc, void **argp, + const char *image, off_t size, void *fspriv) +{ + const char *srcdir; + char *nfsdargv[16]; + char nfsdpath[MAXPATHLEN]; + char imagepath[MAXPATHLEN]; + char ethername[MAXPATHLEN], ethername_ro[MAXPATHLEN]; + char ifname[IFNAMSIZ], ifname_ro[IFNAMSIZ]; + char cwd[MAXPATHLEN]; + struct nfstestargs *args; + pid_t childpid; + int pipes[2]; + int devnull; + + /* + * First, we start the nfs service. + */ + srcdir = atf_tc_get_config_var(tc, "srcdir"); + sprintf(nfsdpath, "%s/../nfs/nfsservice/rumpnfsd", srcdir); + sprintf(ethername, "/%s/%s.etherbus", getcwd(cwd, sizeof(cwd)), image); + sprintf(ethername_ro, "%s_ro", ethername); + sprintf(imagepath, "/%s/%s", cwd, image); + + nfsdargv[0] = nfsdpath; + nfsdargv[1] = ethername; + nfsdargv[2] = ethername_ro; + nfsdargv[3] = __UNCONST(SERVERADDR); + nfsdargv[4] = __UNCONST(SERVERROADDR); + nfsdargv[5] = __UNCONST(NETNETMASK); + nfsdargv[6] = __UNCONST(EXPORTPATH); + nfsdargv[7] = imagepath; + nfsdargv[8] = NULL; + + signal(SIGCHLD, childfail); + if (pipe(pipes) == -1) + return errno; + + switch ((childpid = fork())) { + case 0: + if (chdir(dirname(nfsdpath)) == -1) + err(1, "chdir"); + close(pipes[0]); + if (dup2(pipes[1], 3) == -1) + err(1, "dup2"); + if (execvp(nfsdargv[0], nfsdargv) == -1) + err(1, "execvp"); + case -1: + return errno; + default: + close(pipes[1]); + break; + } + + /* + * Ok, nfsd has been run. The following sleep helps with the + * theoretical problem that nfsd can't start fast enough to + * process our mount request and we end up doing a timeout + * before the mount. This would take several seconds. So + * try to make sure nfsd is up&running already at this stage. + */ + if (read(pipes[0], &devnull, 4) == -1) + return errno; + + /* + * Configure our networking interface. + */ + rump_init(); + netcfg_rump_makeshmif(ethername, ifname); + netcfg_rump_if(ifname, CLIENTADDR, NETNETMASK); + netcfg_rump_makeshmif(ethername_ro, ifname_ro); + netcfg_rump_if(ifname_ro, CLIENTROADDR, NETNETMASK); + + /* + * That's it. The rest is done in mount, since we don't have + * the mountpath available here. + */ + args = malloc(sizeof(*args)); + if (args == NULL) + return errno; + memset(args, 0, sizeof(*args)); + args->ta_childpid = childpid; + strcpy(args->ta_ethername, ethername); + + *argp = args; + + return 0; +} + +int +nfs_fstest_newfs(const atf_tc_t *tc, void **argp, + const char *image, off_t size, void *fspriv) +{ + + return donewfs(tc, argp, image, size, fspriv); +} + +int +nfsro_fstest_newfs(const atf_tc_t *tc, void **argp, + const char *image, off_t size, void *fspriv) +{ + + return donewfs(tc, argp, image, size, fspriv); +} + +/* mount the file system */ +static int +domount(const atf_tc_t *tc, void *arg, const char *serverpath, + const char *path, int flags) +{ + char canon_dev[MAXPATHLEN], canon_dir[MAXPATHLEN]; + const char *nfscliargs[] = { + "nfsclient", + serverpath, + path, + NULL, + }; + struct nfs_args args; + int mntflags; + + if (rump_sys_mkdir(path, 0777) == -1) + return errno; + + /* XXX: atf does not reset values */ + optind = 1; + opterr = 1; + + /* + * We use nfs parseargs here, since as a side effect it + * takes care of the RPC hulabaloo. + */ + mount_nfs_parseargs(__arraycount(nfscliargs)-1, __UNCONST(nfscliargs), + &args, &mntflags, canon_dev, canon_dir); + + if (rump_sys_mount(MOUNT_NFS, path, flags, &args, sizeof(args)) == -1) { + return errno; + } + + return 0; +} + +int +nfs_fstest_mount(const atf_tc_t *tc, void *arg, const char *path, int flags) +{ + + return domount(tc, arg, SERVERADDR ":" EXPORTPATH, path, flags); +} + +/* + * This is where the magic happens! + * + * If we are mounting r/w, do the normal thing. However, if we are + * doing a r/o mount, switch use the r/o server export address + * and do a r/w mount. This way we end up testing the r/o export policy + * of the server! (yes, slightly questionable semantics, but at least + * we notice very quickly if our assumption is broken in the future ;) + */ +int +nfsro_fstest_mount(const atf_tc_t *tc, void *arg, const char *path, int flags) +{ + + if (flags & MNT_RDONLY) { + flags &= ~MNT_RDONLY; + return domount(tc, arg, SERVERROADDR":"EXPORTPATH, path, flags); + } else { + return domount(tc, arg, SERVERADDR":"EXPORTPATH, path, flags); + } +} + +static int +dodelfs(const atf_tc_t *tc, void *arg) +{ + + /* + * XXX: no access to "args" since we're called from "cleanup". + * Trust atf to kill nfsd process and remove etherfile. + */ +#if 0 + /* + * It's highly expected that the child will die next, so we + * don't need that information anymore thank you very many. + */ + signal(SIGCHLD, SIG_IGN); + + /* + * Just KILL it. Sending it SIGTERM first causes it to try + * to send some unmount RPCs, leading to sticky situations. + */ + kill(args->ta_childpid, SIGKILL); + wait(&status); + + /* remove ethernet bus */ + if (unlink(args->ta_ethername) == -1) + atf_tc_fail_errno("unlink ethername"); +#endif + + return 0; +} + +int +nfs_fstest_delfs(const atf_tc_t *tc, void *arg) +{ + + return dodelfs(tc, arg); +} + +int +nfsro_fstest_delfs(const atf_tc_t *tc, void *arg) +{ + + return dodelfs(tc, arg); +} + +static int +dounmount(const atf_tc_t *tc, const char *path, int flags) +{ + int status, i, sverrno; + + /* + * NFS handles sillyrenames in an workqueue. Some of them might + * be still in the queue even if all user activity has ceased. + * We try to unmount for 2 seconds to give them a chance + * to flush out. + * + * PR kern/43799 + */ + for (i = 0; i < 20; i++) { + if ((status = rump_sys_unmount(path, flags)) == 0) + break; + sverrno = errno; + if (sverrno != EBUSY) + break; + usleep(100000); + } + if (status == -1) + return sverrno; + + if (rump_sys_rmdir(path) == -1) + return errno; + + return 0; +} + +int +nfs_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + + return dounmount(tc, path, flags); +} + +int +nfsro_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + + return dounmount(tc, path, flags); +} diff --git a/contrib/netbsd-tests/fs/common/fstest_puffs.c b/contrib/netbsd-tests/fs/common/fstest_puffs.c new file mode 100644 index 0000000..14e4bfb --- /dev/null +++ b/contrib/netbsd-tests/fs/common/fstest_puffs.c @@ -0,0 +1,452 @@ +/* $NetBSD: fstest_puffs.c,v 1.11 2013/09/09 19:47:38 pooka Exp $ */ + +/* + * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "h_fsmacros.h" + +#define BUFSIZE (128*1024) +#define DTFS_DUMP "-o","dump" + +static bool mayquit = false; + +static ssize_t +xread(int fd, void *vp, size_t n) +{ + size_t left; + + left = n; + do { + ssize_t ssz; + + ssz = read(fd, vp, left); + if (ssz == -1) { + return ssz; + } + left -= ssz; + vp = (char *)vp + ssz; + } while (left > 0); + return n; +} + +static ssize_t +xwrite(int fd, const void *vp, size_t n) +{ + size_t left; + + left = n; + do { + ssize_t ssz; + + ssz = write(fd, vp, left); + if (ssz == -1) { + return ssz; + } + left -= ssz; + vp = (const char *)vp + ssz; + } while (left > 0); + return n; +} + +/* + * Threads which shovel data between comfd and /dev/puffs. + * (cannot use polling since fd's are in different namespaces) + */ +static void * +readshovel(void *arg) +{ + struct putter_hdr *phdr; + struct puffs_req *preq; + struct puffstestargs *args = arg; + char buf[BUFSIZE]; + ssize_t n; + int comfd, puffsfd; + + comfd = args->pta_servfd; + puffsfd = args->pta_rumpfd; + + phdr = (void *)buf; + preq = (void *)buf; + + rump_pub_lwproc_newlwp(1); + + for (;;) { + n = rump_sys_read(puffsfd, buf, sizeof(*phdr)); + if (n <= 0) { + fprintf(stderr, "readshovel r1 %zd / %d\n", n, errno); + break; + } + + assert(phdr->pth_framelen < BUFSIZE); + n = rump_sys_read(puffsfd, buf+sizeof(*phdr), + phdr->pth_framelen - sizeof(*phdr)); + if (n <= 0) { + fprintf(stderr, "readshovel r2 %zd / %d\n", n, errno); + break; + } + + /* Analyze request */ + if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS) { + assert(preq->preq_optype < PUFFS_VFS_MAX); + args->pta_vfs_toserv_ops[preq->preq_optype]++; + } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) { + assert(preq->preq_optype < PUFFS_VN_MAX); + args->pta_vn_toserv_ops[preq->preq_optype]++; + } + + n = phdr->pth_framelen; + if (xwrite(comfd, buf, n) != n) { + fprintf(stderr, "readshovel write %zd / %d\n", n, errno); + break; + } + } + + if (n != 0 && mayquit == false) + abort(); + return NULL; +} + +static void * +writeshovel(void *arg) +{ + struct puffstestargs *args = arg; + struct putter_hdr *phdr; + struct puffs_req *preq; + char buf[BUFSIZE]; + size_t toread; + ssize_t n; + int comfd, puffsfd; + + rump_pub_lwproc_newlwp(1); + + comfd = args->pta_servfd; + puffsfd = args->pta_rumpfd; + + phdr = (struct putter_hdr *)buf; + preq = (void *)buf; + + for (;;) { + uint64_t off; + + /* + * Need to write everything to the "kernel" in one chunk, + * so make sure we have it here. + */ + off = 0; + toread = sizeof(struct putter_hdr); + assert(toread < BUFSIZE); + do { + n = xread(comfd, buf+off, toread); + if (n <= 0) { + fprintf(stderr, "writeshovel read %zd / %d\n", + n, errno); + goto out; + } + off += n; + if (off >= sizeof(struct putter_hdr)) + toread = phdr->pth_framelen - off; + else + toread = off - sizeof(struct putter_hdr); + } while (toread); + + if (__predict_false( + PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS + && preq->preq_optype == PUFFS_VFS_UNMOUNT)) { + if (preq->preq_rv == 0) + mayquit = true; + } + + n = rump_sys_write(puffsfd, buf, phdr->pth_framelen); + if ((size_t)n != phdr->pth_framelen) { + fprintf(stderr, "writeshovel wr %zd / %d\n", n, errno); + break; + } + } + + out: + if (n != 0) + abort(); + return NULL; +} + +static void +rumpshovels(struct puffstestargs *args) +{ + pthread_t pt; + int rv; + + if ((rv = rump_init()) == -1) + err(1, "rump_init"); + + if (pthread_create(&pt, NULL, readshovel, args) == -1) + err(1, "read shovel"); + pthread_detach(pt); + + if (pthread_create(&pt, NULL, writeshovel, args) == -1) + err(1, "write shovel"); + pthread_detach(pt); +} + +static void +childfail(int sign) +{ + + atf_tc_fail("child died"); /* almost signal-safe */ +} + +struct puffstestargs *theargs; /* XXX */ + +/* XXX: we don't support size */ +static int +donewfs(const atf_tc_t *tc, void **argp, + const char *image, off_t size, void *fspriv, char **theargv) +{ + struct puffstestargs *args; + pid_t childpid; + int *pflags; + char comfd[16]; + int sv[2]; + int mntflags; + size_t len; + ssize_t n; + + *argp = NULL; + + args = malloc(sizeof(*args)); + if (args == NULL) + return errno; + memset(args, 0, sizeof(*args)); + + pflags = &args->pta_pflags; + + /* Create sucketpair for communication with the real file server */ + if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sv) == -1) + return errno; + + signal(SIGCHLD, childfail); + + switch ((childpid = fork())) { + case 0: + close(sv[1]); + snprintf(comfd, sizeof(sv[0]), "%d", sv[0]); + if (setenv("PUFFS_COMFD", comfd, 1) == -1) + return errno; + + if (execvp(theargv[0], theargv) == -1) + return errno; + case -1: + return errno; + default: + close(sv[0]); + break; + } + + /* read args */ + if ((n = xread(sv[1], &len, sizeof(len))) != sizeof(len)) + err(1, "mp 1 %zd", n); + if (len > MAXPATHLEN) + err(1, "mntpath > MAXPATHLEN"); + if ((size_t)xread(sv[1], args->pta_dir, len) != len) + err(1, "mp 2"); + if (xread(sv[1], &len, sizeof(len)) != sizeof(len)) + err(1, "fn 1"); + if (len > MAXPATHLEN) + err(1, "devpath > MAXPATHLEN"); + if ((size_t)xread(sv[1], args->pta_dev, len) != len) + err(1, "fn 2"); + if (xread(sv[1], &mntflags, sizeof(mntflags)) != sizeof(mntflags)) + err(1, "mntflags"); + if (xread(sv[1], &args->pta_pargslen, sizeof(args->pta_pargslen)) + != sizeof(args->pta_pargslen)) + err(1, "puffstest_args len"); + args->pta_pargs = malloc(args->pta_pargslen); + if (args->pta_pargs == NULL) + err(1, "malloc"); + if (xread(sv[1], args->pta_pargs, args->pta_pargslen) + != (ssize_t)args->pta_pargslen) + err(1, "puffstest_args"); + if (xread(sv[1], pflags, sizeof(*pflags)) != sizeof(*pflags)) + err(1, "pflags"); + + args->pta_childpid = childpid; + args->pta_servfd = sv[1]; + strlcpy(args->pta_dev, image, sizeof(args->pta_dev)); + + *argp = theargs = args; + + return 0; +} + +int +puffs_fstest_newfs(const atf_tc_t *tc, void **argp, + const char *image, off_t size, void *fspriv) +{ + char dtfs_path[MAXPATHLEN]; + char *dtfsargv[6]; + char **theargv; + + /* build dtfs exec path from atf test dir */ + sprintf(dtfs_path, "%s/../puffs/h_dtfs/h_dtfs", + atf_tc_get_config_var(tc, "srcdir")); + + if (fspriv) { + theargv = fspriv; + theargv[0] = dtfs_path; + } else { + dtfsargv[0] = dtfs_path; + dtfsargv[1] = __UNCONST("-i"); + dtfsargv[2] = __UNCONST("-s"); + dtfsargv[3] = __UNCONST("dtfs"); + dtfsargv[4] = __UNCONST("fictional"); + dtfsargv[5] = NULL; + + theargv = dtfsargv; + } + + return donewfs(tc, argp, image, size, fspriv, theargv); +} + +int +p2k_ffs_fstest_newfs(const atf_tc_t *tc, void **argp, + const char *image, off_t size, void *fspriv) +{ + char *rumpffs_argv[5]; + int rv; + + rump_init(); + if ((rv = ffs_fstest_newfs(tc, argp, image, size, fspriv)) != 0) + return rv; + if (mkdir("p2kffsfake", 0777) == -1 && errno != EEXIST) + return errno; + + setenv("P2K_NODETACH", "1", 1); + rumpffs_argv[0] = __UNCONST("rump_ffs"); + rumpffs_argv[1] = __UNCONST(image); + rumpffs_argv[2] = __UNCONST("p2kffsfake"); /* NOTUSED */ + rumpffs_argv[3] = NULL; + + if ((rv = donewfs(tc, argp, image, size, fspriv, rumpffs_argv)) != 0) + ffs_fstest_delfs(tc, argp); + return rv; +} + +int +puffs_fstest_mount(const atf_tc_t *tc, void *arg, const char *path, int flags) +{ + struct puffstestargs *pargs = arg; + int fd; + + rump_init(); + fd = rump_sys_open("/dev/puffs", O_RDWR); + if (fd == -1) + return fd; + + if (rump_sys_mkdir(path, 0777) == -1) + return -1; + + if (rump_sys_mount(MOUNT_PUFFS, path, flags, + pargs->pta_pargs, pargs->pta_pargslen) == -1) { + /* apply "to kill a child" to avoid atf hang (kludge) */ + kill(pargs->pta_childpid, SIGKILL); + return -1; + } + + pargs->pta_rumpfd = fd; + rumpshovels(pargs); + + return 0; +} +__strong_alias(p2k_ffs_fstest_mount,puffs_fstest_mount); + +int +puffs_fstest_delfs(const atf_tc_t *tc, void *arg) +{ + + /* useless ... */ + return 0; +} + +int +p2k_ffs_fstest_delfs(const atf_tc_t *tc, void *arg) +{ + + return ffs_fstest_delfs(tc, arg); +} + +int +puffs_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + struct puffstestargs *pargs = theargs; + int status; + int rv; + + /* ok, child might exit here */ + signal(SIGCHLD, SIG_IGN); + + rv = rump_sys_unmount(path, flags); + if (rv) + return rv; + + if ((rv = rump_sys_rmdir(path)) != 0) + return rv; + + if (waitpid(pargs->pta_childpid, &status, WNOHANG) > 0) + return 0; + kill(pargs->pta_childpid, SIGTERM); + usleep(10); + if (waitpid(pargs->pta_childpid, &status, WNOHANG) > 0) + return 0; + kill(pargs->pta_childpid, SIGKILL); + usleep(500); + wait(&status); + + rmdir("p2kffsfake"); + + return 0; +} +__strong_alias(p2k_ffs_fstest_unmount,puffs_fstest_unmount); diff --git a/contrib/netbsd-tests/fs/common/fstest_rumpfs.c b/contrib/netbsd-tests/fs/common/fstest_rumpfs.c new file mode 100644 index 0000000..e4003db --- /dev/null +++ b/contrib/netbsd-tests/fs/common/fstest_rumpfs.c @@ -0,0 +1,90 @@ +/* $NetBSD: fstest_rumpfs.c,v 1.2 2014/03/16 10:28:03 njoly Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nicolas Joly. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "h_fsmacros.h" + +int +rumpfs_fstest_newfs(const atf_tc_t *tc, void **buf, const char *image, + off_t size, void *fspriv) +{ + char tmp[64]; + int res; + + snprintf(tmp, sizeof(tmp), "%"PRId64, size); + res = setenv("RUMP_MEMLIMIT", tmp, 0); + if (res == -1) + return res; + + return rump_init(); +} + +int +rumpfs_fstest_delfs(const atf_tc_t *tc, void *buf) +{ + + return 0; +} + +int +rumpfs_fstest_mount(const atf_tc_t *tc, void *buf, const char *path, int flags) +{ + int res; + + res = rump_sys_mkdir(path, 0777); + if (res == -1) + return res; + + return rump_sys_mount(MOUNT_RUMPFS, path, flags, NULL, 0); +} + +int +rumpfs_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + int res; + + res = rump_sys_unmount(path, flags); + if (res == -1) + return res; + + return rump_sys_rmdir(path); +} diff --git a/contrib/netbsd-tests/fs/common/fstest_sysvbfs.c b/contrib/netbsd-tests/fs/common/fstest_sysvbfs.c new file mode 100644 index 0000000..a7cf7f4 --- /dev/null +++ b/contrib/netbsd-tests/fs/common/fstest_sysvbfs.c @@ -0,0 +1,139 @@ +/* $NetBSD: fstest_sysvbfs.c,v 1.2 2010/07/30 16:15:05 pooka Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nicolas Joly. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_fsmacros.h" + +struct sysvbfstestargs { + struct ufs_args ta_uargs; + char ta_devpath[MAXPATHLEN]; + char ta_imgpath[MAXPATHLEN]; +}; + +int +sysvbfs_fstest_newfs(const atf_tc_t *tc, void **buf, const char *image, + off_t size, void *fspriv) +{ + char cmd[1024]; + int res; + static unsigned int num = 0; + struct sysvbfstestargs *args; + + size /= 512; + snprintf(cmd, 1024, "newfs_sysvbfs -F -s %"PRId64" %s >/dev/null", + size, image); + res = system(cmd); + if (res != 0) + return res; + + res = rump_init(); + if (res != 0) + return res; + + args = calloc(1, sizeof(*args)); + if (args == NULL) + return -1; + + snprintf(args->ta_devpath, MAXPATHLEN, "/dev/device%d.sysvbfs", num); + snprintf(args->ta_imgpath, MAXPATHLEN, "%s", image); + args->ta_uargs.fspec = args->ta_devpath; + + res = rump_pub_etfs_register(args->ta_devpath, image, RUMP_ETFS_BLK); + if (res != 0) { + free(args); + return res; + } + + *buf = args; + num++; + + return 0; +} + +int +sysvbfs_fstest_delfs(const atf_tc_t *tc, void *buf) +{ + int res; + struct sysvbfstestargs *args = buf; + + res = rump_pub_etfs_remove(args->ta_devpath); + if (res != 0) + return res; + + res = unlink(args->ta_imgpath); + if (res != 0) + return res; + + free(args); + + return 0; +} + +int +sysvbfs_fstest_mount(const atf_tc_t *tc, void *buf, const char *path, int flags) +{ + int res; + struct sysvbfstestargs *args = buf; + + res = rump_sys_mkdir(path, 0777); + if (res == -1) + return res; + + res = rump_sys_mount(MOUNT_SYSVBFS, path, flags, &args->ta_uargs, + sizeof(args->ta_uargs)); + return res; +} + +int +sysvbfs_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + int res; + + res = rump_sys_unmount(path, flags); + if (res == -1) + return res; + + res = rump_sys_rmdir(path); + return res; +} diff --git a/contrib/netbsd-tests/fs/common/fstest_tmpfs.c b/contrib/netbsd-tests/fs/common/fstest_tmpfs.c new file mode 100644 index 0000000..8384843 --- /dev/null +++ b/contrib/netbsd-tests/fs/common/fstest_tmpfs.c @@ -0,0 +1,112 @@ +/* $NetBSD: fstest_tmpfs.c,v 1.2 2010/07/30 16:15:05 pooka Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nicolas Joly. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_fsmacros.h" + +struct tmpfstestargs { + struct tmpfs_args ta_uargs; +}; + +int +tmpfs_fstest_newfs(const atf_tc_t *tc, void **buf, const char *image, + off_t size, void *fspriv) +{ + int res; + struct tmpfstestargs *args; + + res = rump_init(); + if (res != 0) + return res; + + args = calloc(1, sizeof(*args)); + if (args == NULL) + return -1; + + args->ta_uargs.ta_version = TMPFS_ARGS_VERSION; + args->ta_uargs.ta_root_mode = 0777; + args->ta_uargs.ta_size_max = size; + + *buf = args; + + return 0; +} + +int +tmpfs_fstest_delfs(const atf_tc_t *tc, void *buf) +{ + struct tmpfstestargs *args = buf; + + free(args); + + return 0; +} + +int +tmpfs_fstest_mount(const atf_tc_t *tc, void *buf, const char *path, int flags) +{ + int res; + struct tmpfstestargs *args = buf; + + res = rump_sys_mkdir(path, 0777); + if (res == -1) + return res; + + res = rump_sys_mount(MOUNT_TMPFS, path, flags, &args->ta_uargs, + sizeof(args->ta_uargs)); + return res; +} + +int +tmpfs_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + int res; + + res = rump_sys_unmount(path, flags); + if (res == -1) + return res; + + res = rump_sys_rmdir(path); + return res; +} diff --git a/contrib/netbsd-tests/fs/common/fstest_udf.c b/contrib/netbsd-tests/fs/common/fstest_udf.c new file mode 100644 index 0000000..3c9e017 --- /dev/null +++ b/contrib/netbsd-tests/fs/common/fstest_udf.c @@ -0,0 +1,153 @@ +/* $NetBSD: fstest_udf.c,v 1.4 2013/07/02 15:00:55 reinoud Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nicolas Joly. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_fsmacros.h" + +struct udftestargs { + struct udf_args ta_uargs; + char ta_devpath[MAXPATHLEN]; + char ta_imgpath[MAXPATHLEN]; +}; + +int +udf_fstest_newfs(const atf_tc_t *tc, void **buf, const char *image, off_t size, + void *fspriv) +{ + char cmd[1024]; + int res; + static unsigned int num = 0; + struct udftestargs *args; + struct sigaction act, oact; + + /* + * Sectorsize can be specified with -S, as a multiple of 512. + * newfs_udf takes humanized number as size in bytes as -s parameter! + */ + snprintf(cmd, 1024, "newfs_udf -F -s %"PRId64" %s >/dev/null", size, image); + memset(&act, 0, sizeof(act)); + act.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &act, &oact); + res = system(cmd); + sigaction(SIGCHLD, &oact, NULL); + if (res != 0) + return res; + + res = rump_init(); + if (res != 0) + return res; + + args = calloc(1, sizeof(*args)); + if (args == NULL) + return -1; + + snprintf(args->ta_devpath, MAXPATHLEN, "/dev/device%d.udf", num); + snprintf(args->ta_imgpath, MAXPATHLEN, "%s", image); + args->ta_uargs.fspec = args->ta_devpath; + args->ta_uargs.version = UDFMNT_VERSION; + + res = rump_pub_etfs_register(args->ta_devpath, image, RUMP_ETFS_BLK); + if (res != 0) { + free(args); + return res; + } + + *buf = args; + num++; + + return 0; +} +__strong_alias(udflog_fstest_newfs,udf_fstest_newfs); + +int +udf_fstest_delfs(const atf_tc_t *tc, void *buf) +{ + int res; + struct udftestargs *args = buf; + + res = rump_pub_etfs_remove(args->ta_devpath); + if (res != 0) { + errno = res; + return -1; + } + + res = unlink(args->ta_imgpath); + if (res != 0) + return res; + + free(args); + + return 0; +} +__strong_alias(udflog_fstest_delfs,udf_fstest_delfs); + +int +udf_fstest_mount(const atf_tc_t *tc, void *buf, const char *path, int flags) +{ + int res; + struct udftestargs *args = buf; + + res = rump_sys_mkdir(path, 0777); + if (res == -1) + return res; + + res = rump_sys_mount(MOUNT_UDF, path, flags, &args->ta_uargs, + sizeof(args->ta_uargs)); + return res; +} + +int +udf_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + int res; + + res = rump_sys_unmount(path, flags); + if (res == -1) + return res; + + res = rump_sys_rmdir(path); + return res; +} +__strong_alias(udflog_fstest_unmount,udf_fstest_unmount); diff --git a/contrib/netbsd-tests/fs/common/fstest_v7fs.c b/contrib/netbsd-tests/fs/common/fstest_v7fs.c new file mode 100644 index 0000000..92110e4 --- /dev/null +++ b/contrib/netbsd-tests/fs/common/fstest_v7fs.c @@ -0,0 +1,140 @@ +/* $NetBSD: fstest_v7fs.c,v 1.1 2011/08/11 10:52:12 uch Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nicolas Joly. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_fsmacros.h" + +struct v7fstestargs { + struct v7fs_args ta_uargs; + char ta_devpath[MAXPATHLEN]; + char ta_imgpath[MAXPATHLEN]; +}; + +int +v7fs_fstest_newfs(const atf_tc_t *tc, void **buf, const char *image, + off_t size, void *fspriv) +{ + char cmd[1024]; + int res; + static unsigned int num = 0; + struct v7fstestargs *args; + + size /= 512; + snprintf(cmd, 1024, "newfs_v7fs -F -s %"PRId64" %s >/dev/null", + size, image); + res = system(cmd); + if (res != 0) + return res; + + res = rump_init(); + if (res != 0) + return res; + + args = calloc(1, sizeof(*args)); + if (args == NULL) + return -1; + + snprintf(args->ta_devpath, MAXPATHLEN, "/dev/device%d.v7fs", num); + snprintf(args->ta_imgpath, MAXPATHLEN, "%s", image); + args->ta_uargs.fspec = args->ta_devpath; + args->ta_uargs.endian = _BYTE_ORDER; + + res = rump_pub_etfs_register(args->ta_devpath, image, RUMP_ETFS_BLK); + if (res != 0) { + free(args); + return res; + } + + *buf = args; + num++; + + return 0; +} + +int +v7fs_fstest_delfs(const atf_tc_t *tc, void *buf) +{ + int res; + struct v7fstestargs *args = buf; + + res = rump_pub_etfs_remove(args->ta_devpath); + if (res != 0) + return res; + + res = unlink(args->ta_imgpath); + if (res != 0) + return res; + + free(args); + + return 0; +} + +int +v7fs_fstest_mount(const atf_tc_t *tc, void *buf, const char *path, int flags) +{ + int res; + struct v7fstestargs *args = buf; + + res = rump_sys_mkdir(path, 0777); + if (res == -1) + return res; + + res = rump_sys_mount(MOUNT_V7FS, path, flags, &args->ta_uargs, + sizeof(args->ta_uargs)); + return res; +} + +int +v7fs_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + int res; + + res = rump_sys_unmount(path, flags); + if (res == -1) + return res; + + res = rump_sys_rmdir(path); + return res; +} diff --git a/contrib/netbsd-tests/fs/common/fstest_zfs.c b/contrib/netbsd-tests/fs/common/fstest_zfs.c new file mode 100644 index 0000000..88aa05f --- /dev/null +++ b/contrib/netbsd-tests/fs/common/fstest_zfs.c @@ -0,0 +1,134 @@ +/* $NetBSD: fstest_zfs.c,v 1.1 2012/08/20 16:37:35 pooka Exp $ */ + +/*- + * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nicolas Joly. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "h_fsmacros.h" + +#define SRVPATH "zfssurvo" +#define SRVURL "unix://" SRVPATH +#define ZFSDEV "/zfsdev" + +int +zfs_fstest_newfs(const atf_tc_t *tc, void **buf, const char *image, + off_t size, void *fspriv) +{ + int res; + int fd; + + /* XXX: hardcoded zfs minimum size */ + size = MAX(64*1024*1024, size); + + res = rump_init(); + if (res != 0) { + errno = res; + return -1; + } + + /* create backing image, sparse file is enough */ + if ((fd = open(image, O_RDWR | O_CREAT, 0777)) == -1) + return -1; + if (ftruncate(fd, size) == -1) { + close(fd); + return -1; + } + close(fd); + + res = rump_pub_etfs_register(ZFSDEV, image, RUMP_ETFS_BLK); + if (res != 0) { + errno = res; + return -1; + } + + res = rump_init_server(SRVURL); + if (res != 0) { + errno = res; + return -1; + } + *buf = NULL; + + return 0; +} + +int +zfs_fstest_delfs(const atf_tc_t *tc, void *buf) +{ + + unlink(SRVPATH); + return 0; +} + +int +zfs_fstest_mount(const atf_tc_t *tc, void *buf, const char *path, int flags) +{ + char tmpbuf[128]; + int error; + + /* set up the hijack env for running zpool */ + setenv("RUMP_SERVER", SRVURL, 1); + snprintf(tmpbuf, sizeof(tmpbuf)-1, "blanket=/dev/zfs:%s:%s", + ZFSDEV, path); + setenv("RUMPHIJACK", tmpbuf, 1); + setenv("LD_PRELOAD", "/usr/lib/librumphijack.so", 1); + + while (*path == '/') + path++; + + /* run zpool create */ + snprintf(tmpbuf, sizeof(tmpbuf)-1, "zpool create %s %s", + path, ZFSDEV); + if ((error = system(tmpbuf)) != 0) { + errno = error; + return -1; + } + + return 0; +} + +int +zfs_fstest_unmount(const atf_tc_t *tc, const char *path, int flags) +{ + + unmount(path, flags); + unlink(SRVPATH); + + return 0; +} diff --git a/contrib/netbsd-tests/fs/common/h_fsmacros.h b/contrib/netbsd-tests/fs/common/h_fsmacros.h new file mode 100644 index 0000000..eb83768 --- /dev/null +++ b/contrib/netbsd-tests/fs/common/h_fsmacros.h @@ -0,0 +1,329 @@ +/* $NetBSD: h_fsmacros.h,v 1.41 2017/01/13 21:30:39 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nicolas Joly. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef __H_FSMACROS_H_ +#define __H_FSMACROS_H_ + +#include + +#include +#include +#include + +#include + +#include "h_macros.h" + +#define FSPROTOS(_fs_) \ +int _fs_##_fstest_newfs(const atf_tc_t *, void **, const char *, \ + off_t, void *); \ +int _fs_##_fstest_delfs(const atf_tc_t *, void *); \ +int _fs_##_fstest_mount(const atf_tc_t *, void *, const char *, int); \ +int _fs_##_fstest_unmount(const atf_tc_t *, const char *, int); + +FSPROTOS(ext2fs); +FSPROTOS(ffs); +FSPROTOS(ffslog); +FSPROTOS(lfs); +FSPROTOS(msdosfs); +FSPROTOS(nfs); +FSPROTOS(nfsro); +FSPROTOS(p2k_ffs); +FSPROTOS(puffs); +FSPROTOS(rumpfs); +FSPROTOS(sysvbfs); +FSPROTOS(tmpfs); +FSPROTOS(udf); +FSPROTOS(v7fs); +FSPROTOS(zfs); + +#ifndef FSTEST_IMGNAME +#define FSTEST_IMGNAME "image.fs" +#endif +#ifndef FSTEST_IMGSIZE +#define FSTEST_IMGSIZE (10000 * 512) +#endif +#ifndef FSTEST_MNTNAME +#define FSTEST_MNTNAME "/mnt" +#endif + +#define FSTEST_CONSTRUCTOR(_tc_, _fs_, _args_) \ +do { \ + if (_fs_##_fstest_newfs(_tc_, &_args_, \ + FSTEST_IMGNAME, FSTEST_IMGSIZE, NULL) != 0) \ + atf_tc_fail_errno("newfs failed"); \ + if (_fs_##_fstest_mount(_tc_, _args_, FSTEST_MNTNAME, 0) != 0) \ + atf_tc_fail_errno("mount failed"); \ +} while (/*CONSTCOND*/0); + +#define FSTEST_CONSTRUCTOR_FSPRIV(_tc_, _fs_, _args_, _privargs_) \ +do { \ + if (_fs_##_fstest_newfs(_tc_, &_args_, \ + FSTEST_IMGNAME, FSTEST_IMGSIZE, _privargs_) != 0) \ + atf_tc_fail_errno("newfs failed"); \ + if (_fs_##_fstest_mount(_tc_, _args_, FSTEST_MNTNAME, 0) != 0) \ + atf_tc_fail_errno("mount failed"); \ +} while (/*CONSTCOND*/0); + +#define FSTEST_DESTRUCTOR(_tc_, _fs_, _args_) \ +do { \ + if (_fs_##_fstest_unmount(_tc_, FSTEST_MNTNAME, 0) != 0) { \ + rump_pub_vfs_mount_print(FSTEST_MNTNAME, 1); \ + atf_tc_fail_errno("unmount failed"); \ + } \ + if (_fs_##_fstest_delfs(_tc_, _args_) != 0) \ + atf_tc_fail_errno("delfs failed"); \ +} while (/*CONSTCOND*/0); + +#define ATF_TC_FSADD(fs,type,func,desc) \ + ATF_TC(fs##_##func); \ + ATF_TC_HEAD(fs##_##func,tc) \ + { \ + atf_tc_set_md_var(tc, "descr", type " test for " desc); \ + atf_tc_set_md_var(tc, "X-fs.type", #fs); \ + atf_tc_set_md_var(tc, "X-fs.mntname", type); \ + } \ + void *fs##func##tmp; \ + \ + ATF_TC_BODY(fs##_##func,tc) \ + { \ + if (!atf_check_fstype(tc, #fs)) \ + atf_tc_skip("filesystem not selected"); \ + FSTEST_CONSTRUCTOR(tc,fs,fs##func##tmp); \ + func(tc,FSTEST_MNTNAME); \ + if (fs##_fstest_unmount(tc, FSTEST_MNTNAME, 0) != 0) { \ + rump_pub_vfs_mount_print(FSTEST_MNTNAME, 1); \ + atf_tc_fail_errno("unmount failed"); \ + } \ + } + +#define ATF_TC_FSADD_RO(_fs_,_type_,_func_,_desc_,_gen_) \ + ATF_TC(_fs_##_##_func_); \ + ATF_TC_HEAD(_fs_##_##_func_,tc) \ + { \ + atf_tc_set_md_var(tc, "descr",_type_" test for "_desc_);\ + atf_tc_set_md_var(tc, "X-fs.type", #_fs_); \ + atf_tc_set_md_var(tc, "X-fs.mntname", _type_); \ + } \ + void *_fs_##_func_##tmp; \ + \ + ATF_TC_BODY(_fs_##_##_func_,tc) \ + { \ + if (!atf_check_fstype(tc, #_fs_)) \ + atf_tc_skip("filesystem not selected"); \ + FSTEST_CONSTRUCTOR(tc,_fs_,_fs_##_func_##tmp); \ + _gen_(tc,FSTEST_MNTNAME); \ + if (_fs_##_fstest_unmount(tc, FSTEST_MNTNAME, 0) != 0) \ + atf_tc_fail_errno("unmount r/w failed"); \ + if (_fs_##_fstest_mount(tc, _fs_##_func_##tmp, \ + FSTEST_MNTNAME, MNT_RDONLY) != 0) \ + atf_tc_fail_errno("mount ro failed"); \ + _func_(tc,FSTEST_MNTNAME); \ + if (_fs_##_fstest_unmount(tc, FSTEST_MNTNAME, 0) != 0) {\ + rump_pub_vfs_mount_print(FSTEST_MNTNAME, 1); \ + atf_tc_fail_errno("unmount failed"); \ + } \ + } + +#define ATF_TP_FSADD(fs,func) \ + ATF_TP_ADD_TC(tp,fs##_##func) + +#define ATF_TC_FSAPPLY_NOZFS(func,desc) \ + ATF_TC_FSADD(ext2fs,MOUNT_EXT2FS,func,desc) \ + ATF_TC_FSADD(ffs,MOUNT_FFS,func,desc) \ + ATF_TC_FSADD(ffslog,MOUNT_FFS,func,desc) \ + ATF_TC_FSADD(lfs,MOUNT_LFS,func,desc) \ + ATF_TC_FSADD(msdosfs,MOUNT_MSDOS,func,desc) \ + ATF_TC_FSADD(nfs,MOUNT_NFS,func,desc) \ + ATF_TC_FSADD(puffs,MOUNT_PUFFS,func,desc) \ + ATF_TC_FSADD(p2k_ffs,MOUNT_PUFFS,func,desc) \ + ATF_TC_FSADD(rumpfs,MOUNT_RUMPFS,func,desc) \ + ATF_TC_FSADD(sysvbfs,MOUNT_SYSVBFS,func,desc) \ + ATF_TC_FSADD(tmpfs,MOUNT_TMPFS,func,desc) \ + ATF_TC_FSADD(udf,MOUNT_UDF,func,desc) \ + ATF_TC_FSADD(v7fs,MOUNT_V7FS,func,desc) + +#define ATF_TP_FSAPPLY_NOZFS(func) \ + ATF_TP_FSADD(ext2fs,func); \ + ATF_TP_FSADD(ffs,func); \ + ATF_TP_FSADD(ffslog,func); \ + ATF_TP_FSADD(lfs,func); \ + ATF_TP_FSADD(msdosfs,func); \ + ATF_TP_FSADD(nfs,func); \ + ATF_TP_FSADD(puffs,func); \ + ATF_TP_FSADD(p2k_ffs,func); \ + ATF_TP_FSADD(rumpfs,func); \ + ATF_TP_FSADD(sysvbfs,func); \ + ATF_TP_FSADD(tmpfs,func); \ + ATF_TP_FSADD(udf,func); \ + ATF_TP_FSADD(v7fs,func); + +/* XXX: this will not scale */ +#ifdef WANT_ZFS_TESTS +#define ATF_TC_FSAPPLY(func,desc) \ + ATF_TC_FSAPPLY_NOZFS(func,desc) \ + ATF_TC_FSADD(zfs,MOUNT_ZFS,func,desc) +#define ATF_TP_FSAPPLY(func) \ + ATF_TP_FSAPPLY_NOZFS(func) \ + ATF_TP_FSADD(zfs,func); + +#else /* !WANT_ZFS_TESTS */ + +#define ATF_TC_FSAPPLY(func,desc) \ + ATF_TC_FSAPPLY_NOZFS(func,desc) +#define ATF_TP_FSAPPLY(func) \ + ATF_TP_FSAPPLY_NOZFS(func) + +#endif /* WANT_ZFS_TESTS */ + +/* + * Same as above, but generate a file system image first and perform + * tests for a r/o mount. + * + * Missing the following file systems: + * + lfs (fstest_lfs routines cannot handle remount. FIXME!) + * + tmpfs (memory backend) + * + rumpfs (memory backend) + * + puffs (memory backend, but could be run in theory) + */ + +#define ATF_TC_FSAPPLY_RO(func,desc,gen) \ + ATF_TC_FSADD_RO(ext2fs,MOUNT_EXT2FS,func,desc,gen) \ + ATF_TC_FSADD_RO(ffs,MOUNT_FFS,func,desc,gen) \ + ATF_TC_FSADD_RO(ffslog,MOUNT_FFS,func,desc,gen) \ + ATF_TC_FSADD_RO(msdosfs,MOUNT_MSDOS,func,desc,gen) \ + ATF_TC_FSADD_RO(nfs,MOUNT_NFS,func,desc,gen) \ + ATF_TC_FSADD_RO(nfsro,MOUNT_NFS,func,desc,gen) \ + ATF_TC_FSADD_RO(sysvbfs,MOUNT_SYSVBFS,func,desc,gen) \ + ATF_TC_FSADD_RO(udf,MOUNT_UDF,func,desc,gen) \ + ATF_TC_FSADD_RO(v7fs,MOUNT_V7FS,func,desc,gen) + +#define ATF_TP_FSAPPLY_RO(func) \ + ATF_TP_FSADD(ext2fs,func); \ + ATF_TP_FSADD(ffs,func); \ + ATF_TP_FSADD(ffslog,func); \ + ATF_TP_FSADD(msdosfs,func); \ + ATF_TP_FSADD(nfs,func); \ + ATF_TP_FSADD(nfsro,func); \ + ATF_TP_FSADD(sysvbfs,func); \ + ATF_TP_FSADD(udf,func); \ + ATF_TP_FSADD(v7fs,func); + +#define ATF_FSAPPLY(func,desc) \ + ATF_TC_FSAPPLY(func,desc); \ + ATF_TP_ADD_TCS(tp) \ + { \ + ATF_TP_FSAPPLY(func); \ + return atf_no_error(); \ + } + +static __inline bool +atf_check_fstype(const atf_tc_t *tc, const char *fs) +{ + const char *fstype; + + if (!atf_tc_has_config_var(tc, "fstype")) + return true; + + fstype = atf_tc_get_config_var(tc, "fstype"); + if (strcmp(fstype, fs) == 0) + return true; + return false; +} + +#define FSTYPE_EXT2FS(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "ext2fs") == 0) +#define FSTYPE_FFS(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "ffs") == 0) +#define FSTYPE_FFSLOG(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "ffslog") == 0) +#define FSTYPE_LFS(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "lfs") == 0) +#define FSTYPE_MSDOS(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "msdosfs") == 0) +#define FSTYPE_NFS(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "nfs") == 0) +#define FSTYPE_NFSRO(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "nfsro") == 0) +#define FSTYPE_P2K_FFS(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "p2k_ffs") == 0) +#define FSTYPE_PUFFS(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "puffs") == 0) +#define FSTYPE_RUMPFS(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "rumpfs") == 0) +#define FSTYPE_SYSVBFS(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "sysvbfs") == 0) +#define FSTYPE_TMPFS(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "tmpfs") == 0) +#define FSTYPE_UDF(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "udf") == 0) +#define FSTYPE_V7FS(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "v7fs") == 0) +#define FSTYPE_ZFS(tc)\ + (strcmp(atf_tc_get_md_var(tc, "X-fs.type"), "zfs") == 0) + +#define FSTEST_ENTER() \ + if (rump_sys_chdir(FSTEST_MNTNAME) == -1) \ + atf_tc_fail_errno("failed to cd into test mount") + +#define FSTEST_EXIT() \ + if (rump_sys_chdir("/") == -1) \ + atf_tc_fail_errno("failed to cd out of test mount") + +/* + * file system args structures + */ + +struct nfstestargs { + pid_t ta_childpid; + char ta_ethername[MAXPATHLEN]; +}; + +struct puffstestargs { + uint8_t *pta_pargs; + size_t pta_pargslen; + + int pta_pflags; + pid_t pta_childpid; + + int pta_rumpfd; + int pta_servfd; + + char pta_dev[MAXPATHLEN]; + char pta_dir[MAXPATHLEN]; + + int pta_mntflags; + + int pta_vfs_toserv_ops[PUFFS_VFS_MAX]; + int pta_vn_toserv_ops[PUFFS_VN_MAX]; +}; + +#endif /* __H_FSMACROS_H_ */ diff --git a/contrib/netbsd-tests/fs/common/snapshot.c b/contrib/netbsd-tests/fs/common/snapshot.c new file mode 100644 index 0000000..7baf611 --- /dev/null +++ b/contrib/netbsd-tests/fs/common/snapshot.c @@ -0,0 +1,228 @@ +/* $NetBSD: snapshot.c,v 1.7 2013/02/06 09:05:01 hannken Exp $ */ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +ATF_TC_WITH_CLEANUP(snapshot); +ATF_TC_HEAD(snapshot, tc) +{ + + atf_tc_set_md_var(tc, "descr", "basic snapshot features"); +} + +static void +makefile(const char *path) +{ + int fd; + + fd = rump_sys_open(path, O_CREAT | O_RDWR, 0777); + if (fd == -1) + atf_tc_fail_errno("create %s", path); + rump_sys_close(fd); +} + +ATF_TC_BODY(snapshot, tc) +{ + char buf[1024]; + struct fss_set fss; + int fssfd; + int fd, fd2, i; + + if (system(NEWFS) == -1) + atf_tc_fail_errno("cannot create file system"); + + rump_init(); + begin(); + + if (rump_sys_mkdir("/mnt", 0777) == -1) + atf_tc_fail_errno("mount point create"); + if (rump_sys_mkdir("/snap", 0777) == -1) + atf_tc_fail_errno("mount point 2 create"); + + rump_pub_etfs_register("/diskdev", IMGNAME, RUMP_ETFS_BLK); + + mount_diskfs("/diskdev", "/mnt"); + +#define TESTSTR1 "huihai\n" +#define TESTSZ1 (sizeof(TESTSTR1)-1) +#define TESTSTR2 "baana liten\n" +#define TESTSZ2 (sizeof(TESTSTR2)-1) + + fd = rump_sys_open("/mnt/myfile", O_RDWR | O_CREAT, 0777); + if (fd == -1) + atf_tc_fail_errno("create file"); + if (rump_sys_write(fd, TESTSTR1, TESTSZ1) != TESTSZ1) + atf_tc_fail_errno("write fail"); + + fssfd = rump_sys_open("/dev/rfss0", O_RDWR); + if (fssfd == -1) + atf_tc_fail_errno("cannot open fss"); + makefile(BAKNAME); + memset(&fss, 0, sizeof(fss)); + fss.fss_mount = __UNCONST("/mnt"); + fss.fss_bstore = __UNCONST(BAKNAME); + fss.fss_csize = 0; + if (rump_sys_ioctl(fssfd, FSSIOCSET, &fss) == -1) + atf_tc_fail_errno("create snapshot"); + + for (i = 0; i < 10000; i++) { + if (rump_sys_write(fd, TESTSTR2, TESTSZ2) != TESTSZ2) + atf_tc_fail_errno("write fail"); + } + rump_sys_sync(); + + /* technically we should fsck it first? */ + mount_diskfs("/dev/fss0", "/snap"); + + /* check for old contents */ + fd2 = rump_sys_open("/snap/myfile", O_RDONLY); + if (fd2 == -1) + atf_tc_fail_errno("fail"); + memset(buf, 0, sizeof(buf)); + if (rump_sys_read(fd2, buf, sizeof(buf)) == -1) + atf_tc_fail_errno("read snap"); + ATF_CHECK(strcmp(buf, TESTSTR1) == 0); + + /* check that new files are invisible in the snapshot */ + makefile("/mnt/newfile"); + if (rump_sys_open("/snap/newfile", O_RDONLY) != -1) + atf_tc_fail("newfile exists in snapshot"); + if (errno != ENOENT) + atf_tc_fail_errno("newfile open should fail with ENOENT"); + + /* check that removed files are still visible in the snapshot */ + rump_sys_unlink("/mnt/myfile"); + if (rump_sys_open("/snap/myfile", O_RDONLY) == -1) + atf_tc_fail_errno("unlinked file no longer in snapshot"); + + /* done for now */ +} + +ATF_TC_CLEANUP(snapshot, tc) +{ + + unlink(IMGNAME); +} + +ATF_TC_WITH_CLEANUP(snapshotstress); +ATF_TC_HEAD(snapshotstress, tc) +{ + + atf_tc_set_md_var(tc, "descr", "snapshot on active file system"); +} + +#define NACTIVITY 4 + +static bool activity_stop = false; +static pid_t wrkpid; + +static void * +fs_activity(void *arg) +{ + int di, fi; + char *prefix = arg, path[128]; + + rump_pub_lwproc_newlwp(wrkpid); + + RL(rump_sys_mkdir(prefix, 0777)); + while (! activity_stop) { + for (di = 0; di < 5; di++) { + snprintf(path, sizeof(path), "%s/d%d", prefix, di); + RL(rump_sys_mkdir(path, 0777)); + for (fi = 0; fi < 5; fi++) { + snprintf(path, sizeof(path), "%s/d%d/f%d", + prefix, di, fi); + makefile(path); + } + } + for (di = 0; di < 5; di++) { + for (fi = 0; fi < 5; fi++) { + snprintf(path, sizeof(path), "%s/d%d/f%d", + prefix, di, fi); + RL(rump_sys_unlink(path)); + } + snprintf(path, sizeof(path), "%s/d%d", prefix, di); + RL(rump_sys_rmdir(path)); + } + } + RL(rump_sys_rmdir(prefix)); + + rump_pub_lwproc_releaselwp(); + + return NULL; +} + +ATF_TC_BODY(snapshotstress, tc) +{ + pthread_t at[NACTIVITY]; + struct fss_set fss; + char prefix[NACTIVITY][128]; + int i, fssfd; + + if (system(NEWFS) == -1) + atf_tc_fail_errno("cannot create file system"); + /* Force SMP so the stress makes sense. */ + RL(setenv("RUMP_NCPU", "4", 1)); + RZ(rump_init()); + /* Prepare for fsck to use the RUMP /dev/fss0. */ + RL(rump_init_server("unix://commsock")); + RL(setenv("LD_PRELOAD", "/usr/lib/librumphijack.so", 1)); + RL(setenv("RUMP_SERVER", "unix://commsock", 1)); + RL(setenv("RUMPHIJACK", "blanket=/dev/rfss0", 1)); + begin(); + + RL(rump_sys_mkdir("/mnt", 0777)); + + rump_pub_etfs_register("/diskdev", IMGNAME, RUMP_ETFS_BLK); + + mount_diskfs("/diskdev", "/mnt"); + + /* Start file system activity. */ + RL(wrkpid = rump_sys_getpid()); + for (i = 0; i < NACTIVITY; i++) { + snprintf(prefix[i], sizeof(prefix[i]), "/mnt/a%d", i); + RL(pthread_create(&at[i], NULL, fs_activity, prefix[i])); + sleep(1); + } + + fssfd = rump_sys_open("/dev/rfss0", O_RDWR); + if (fssfd == -1) + atf_tc_fail_errno("cannot open fss"); + makefile(BAKNAME); + memset(&fss, 0, sizeof(fss)); + fss.fss_mount = __UNCONST("/mnt"); + fss.fss_bstore = __UNCONST(BAKNAME); + fss.fss_csize = 0; + if (rump_sys_ioctl(fssfd, FSSIOCSET, &fss) == -1) + atf_tc_fail_errno("create snapshot"); + + activity_stop = true; + for (i = 0; i < NACTIVITY; i++) + RL(pthread_join(at[i], NULL)); + + RL(system(FSCK " /dev/rfss0")); +} + +ATF_TC_CLEANUP(snapshotstress, tc) +{ + + unlink(IMGNAME); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, snapshot); + ATF_TP_ADD_TC(tp, snapshotstress); + return 0; +} diff --git a/contrib/netbsd-tests/fs/ffs/ffs_common.sh b/contrib/netbsd-tests/fs/ffs/ffs_common.sh new file mode 100755 index 0000000..ee94a15 --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/ffs_common.sh @@ -0,0 +1,99 @@ +# $NetBSD: ffs_common.sh,v 1.3 2016/10/08 13:23:53 gson Exp $ + +create_ffs() +{ + local endian=$1; shift + local vers=$1; shift + local type=$1; shift + local op; + if [ ${type} = "both" ]; then + op="-q user -q group" + else + op="-q ${type}" + fi + atf_check -o ignore -e ignore newfs ${op} \ + -B ${endian} -O ${vers} -s 4000 -F ${IMG} +} + +create_ffs_server() +{ + local sarg=$1; shift + create_ffs $* + atf_check -o ignore -e ignore $(atf_get_srcdir)/h_ffs_server \ + ${sarg} ${IMG} ${RUMP_SERVER} +} + +rump_shutdown() +{ + for s in ${RUMP_SOCKETS_LIST}; do + atf_check -s exit:0 env RUMP_SERVER=unix://${s} rump.halt; + done +# check that the quota inode creation didn't corrupt the filesystem + atf_check -s exit:0 -o "match:already clean" \ + -o "match:Phase 6 - Check Quotas" \ + fsck_ffs -nf -F ${IMG} +} + +# from tests/ipf/h_common.sh via tests/sbin/resize_ffs +test_case() +{ + local name="${1}"; shift + local check_function="${1}"; shift + local descr="${1}"; shift + + atf_test_case "${name}" cleanup + + eval "${name}_head() { \ + atf_set "descr" "${descr}" + atf_set "timeout" "120" + }" + eval "${name}_body() { \ + RUMP_SOCKETS_LIST=\${RUMP_SOCKET}; \ + export RUMP_SERVER=unix://\${RUMP_SOCKET}; \ + ${check_function} " "${@}" "; \ + }" + eval "${name}_cleanup() { \ + for s in \${RUMP_SOCKETS_LIST}; do \ + export RUMP_SERVER=unix://\${s}; \ + atf_check -s exit:1 -o ignore -e ignore rump.halt; \ + done; \ + }" + tests="${tests} ${name}" +} + +test_case_root() +{ + local name="${1}"; shift + local check_function="${1}"; shift + local descr="${1}"; shift + + atf_test_case "${name}" cleanup + + eval "${name}_head() { \ + atf_set "descr" "${descr}" + atf_set "require.user" "root" + atf_set "timeout" "360" + }" + eval "${name}_body() { \ + RUMP_SOCKETS_LIST=\${RUMP_SOCKET}; \ + export RUMP_SERVER=unix://\${RUMP_SOCKET}; \ + ${check_function} " "${@}" "; \ + }" + eval "${name}_cleanup() { \ + for s in \${RUMP_SOCKETS_LIST}; do \ + export RUMP_SERVER=unix://\${s}; \ + atf_check -s exit:1 -o ignore -e ignore rump.halt; \ + done; \ + }" + tests="${tests} ${name}" +} + +atf_init_test_cases() +{ + IMG=fsimage + DIR=target + RUMP_SOCKET=test; + for i in ${tests}; do + atf_add_test_case $i + done +} diff --git a/contrib/netbsd-tests/fs/ffs/h_ffs_server.c b/contrib/netbsd-tests/fs/ffs/h_ffs_server.c new file mode 100644 index 0000000..dd22d9f --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/h_ffs_server.c @@ -0,0 +1,113 @@ +/* $NetBSD: h_ffs_server.c,v 1.2 2012/08/24 20:25:50 jmmv Exp $ */ + +/* + * rump server for advanced quota tests + */ + +#include "../common/h_fsmacros.h" + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +int background = 0; + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [-b] [-l] diskimage bindurl\n", + getprogname()); + exit(1); +} + +static void +die(const char *reason, int error) +{ + + warnx("%s: %s", reason, strerror(error)); + if (background) + rump_daemonize_done(error); + exit(1); +} + +static sem_t sigsem; +static void +sigreboot(int sig) +{ + + sem_post(&sigsem); +} + +int +main(int argc, char **argv) +{ + int error; + struct ufs_args uargs; + const char *filename; + const char *serverurl; + int log = 0; + int ch; + + while ((ch = getopt(argc, argv, "bl")) != -1) { + switch(ch) { + case 'b': + background = 1; + break; + case 'l': + log = 1; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (argc != 2) + usage(); + + filename = argv[0]; + serverurl = argv[1]; + + if (background) { + error = rump_daemonize_begin(); + if (error) + errx(1, "rump daemonize: %s", strerror(error)); + } + + error = rump_init(); + if (error) + die("rump init failed", error); + + if (rump_sys_mkdir(FSTEST_MNTNAME, 0777) == -1) + die("mount point create", errno); + rump_pub_etfs_register("/diskdev", filename, RUMP_ETFS_BLK); + uargs.fspec = __UNCONST("/diskdev"); + if (rump_sys_mount(MOUNT_FFS, FSTEST_MNTNAME, (log) ? MNT_LOG : 0, + &uargs, sizeof(uargs)) == -1) + die("mount ffs", errno); + + error = rump_init_server(serverurl); + if (error) + die("rump server init failed", error); + if (background) + rump_daemonize_done(RUMP_DAEMONIZE_SUCCESS); + + sem_init(&sigsem, 0, 0); + signal(SIGTERM, sigreboot); + signal(SIGINT, sigreboot); + sem_wait(&sigsem); + + rump_sys_reboot(0, NULL); + /*NOTREACHED*/ + return 0; +} diff --git a/contrib/netbsd-tests/fs/ffs/h_quota2_tests.c b/contrib/netbsd-tests/fs/ffs/h_quota2_tests.c new file mode 100644 index 0000000..71cf3b4 --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/h_quota2_tests.c @@ -0,0 +1,468 @@ +/* $NetBSD: h_quota2_tests.c,v 1.5 2017/01/13 21:30:39 christos Exp $ */ + +/* + * rump server for advanced quota tests + * this one includes functions to run against the filesystem before + * starting to handle rump requests from clients. + */ + +#include "../common/h_fsmacros.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include "h_macros.h" + +int background = 0; + +#define TEST_NONROOT_ID 1 + +static int +quota_test0(const char *testopts) +{ + static char buf[512]; + int fd; + int error; + unsigned int i; + int chowner = 1; + for (i =0; testopts && i < strlen(testopts); i++) { + switch(testopts[i]) { + case 'C': + chowner = 0; + break; + default: + errx(1, "test4: unknown option %c", testopts[i]); + } + } + if (chowner) + rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID); + rump_sys_chmod(".", 0777); + if (rump_sys_setegid(TEST_NONROOT_ID) != 0) { + error = errno; + warn("rump_sys_setegid"); + return error; + } + if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) { + error = errno; + warn("rump_sys_seteuid"); + return error; + } + fd = rump_sys_open("test_fillup", O_CREAT | O_RDWR, 0644); + if (fd < 0) { + error = errno; + warn("rump_sys_open"); + } else { + while (rump_sys_write(fd, buf, sizeof(buf)) == sizeof(buf)) + error = 0; + error = errno; + } + rump_sys_close(fd); + rump_sys_seteuid(0); + rump_sys_setegid(0); + return error; +} + +static int +quota_test1(const char *testopts) +{ + static char buf[512]; + int fd; + int error; + rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID); + rump_sys_chmod(".", 0777); + if (rump_sys_setegid(TEST_NONROOT_ID) != 0) { + error = errno; + warn("rump_sys_setegid"); + return error; + } + if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) { + error = errno; + warn("rump_sys_seteuid"); + return error; + } + fd = rump_sys_open("test_fillup", O_CREAT | O_RDWR, 0644); + if (fd < 0) { + error = errno; + warn("rump_sys_open"); + } else { + /* + * write up to the soft limit, wait a bit, an try to + * keep on writing + */ + int i; + + /* write 2k: with the directory this makes 2.5K */ + for (i = 0; i < 4; i++) { + error = rump_sys_write(fd, buf, sizeof(buf)); + if (error != sizeof(buf)) + err(1, "write failed early"); + } + sleep(2); + /* now try to write an extra .5k */ + if (rump_sys_write(fd, buf, sizeof(buf)) != sizeof(buf)) + error = errno; + else + error = 0; + } + rump_sys_close(fd); + rump_sys_seteuid(0); + rump_sys_setegid(0); + return error; +} + +static int +quota_test2(const char *testopts) +{ + static char buf[512]; + int fd; + int error; + int i; + rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID); + rump_sys_chmod(".", 0777); + if (rump_sys_setegid(TEST_NONROOT_ID) != 0) { + error = errno; + warn("rump_sys_setegid"); + return error; + } + if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) { + error = errno; + warn("rump_sys_seteuid"); + return error; + } + + for (i = 0; ; i++) { + sprintf(buf, "file%d", i); + fd = rump_sys_open(buf, O_CREAT | O_RDWR, 0644); + if (fd < 0) + break; + sprintf(buf, "test file no %d", i); + rump_sys_write(fd, buf, strlen(buf)); + rump_sys_close(fd); + } + error = errno; + + rump_sys_close(fd); + rump_sys_seteuid(0); + rump_sys_setegid(0); + return error; +} + +static int +quota_test3(const char *testopts) +{ + static char buf[512]; + int fd; + int error; + int i; + rump_sys_chown(".", TEST_NONROOT_ID, TEST_NONROOT_ID); + rump_sys_chmod(".", 0777); + if (rump_sys_setegid(TEST_NONROOT_ID) != 0) { + error = errno; + warn("rump_sys_setegid"); + return error; + } + if (rump_sys_seteuid(TEST_NONROOT_ID) != 0) { + error = errno; + warn("rump_sys_seteuid"); + return error; + } + + /* + * create files one past the soft limit: one less as we already own the + * root directory + */ + for (i = 0; i < 4; i++) { + sprintf(buf, "file%d", i); + fd = rump_sys_open(buf, O_EXCL| O_CREAT | O_RDWR, 0644); + if (fd < 0) + err(1, "file create failed early"); + sprintf(buf, "test file no %d", i); + rump_sys_write(fd, buf, strlen(buf)); + rump_sys_close(fd); + } + /* now create an extra file after grace time: this should fail */ + sleep(2); + sprintf(buf, "file%d", i); + fd = rump_sys_open(buf, O_EXCL| O_CREAT | O_RDWR, 0644); + if (fd < 0) + error = errno; + else + error = 0; + + rump_sys_close(fd); + rump_sys_seteuid(0); + rump_sys_setegid(0); + return error; +} + +static int +quota_test4(const char *testopts) +{ + static char buf[512]; + int fd, fssfd; + struct fss_set fss; + unsigned int i; + int unl=0; + int unconf=0; + + /* + * take an internal snapshot of the filesystem, and create a new + * file with some data + */ + rump_sys_chown(".", 0, 0); + rump_sys_chmod(".", 0777); + + for (i =0; testopts && i < strlen(testopts); i++) { + switch(testopts[i]) { + case 'L': + unl++; + break; + case 'C': + unconf++; + break; + default: + errx(1, "test4: unknown option %c", testopts[i]); + } + } + + /* first create the snapshot */ + + fd = rump_sys_open(FSTEST_MNTNAME "/le_snap", O_CREAT | O_RDWR, 0777); + if (fd == -1) + err(1, "create " FSTEST_MNTNAME "/le_snap"); + rump_sys_close(fd); + fssfd = rump_sys_open("/dev/rfss0", O_RDWR); + if (fssfd == -1) + err(1, "cannot open fss"); + memset(&fss, 0, sizeof(fss)); + fss.fss_mount = __UNCONST("/mnt"); + fss.fss_bstore = __UNCONST(FSTEST_MNTNAME "/le_snap"); + fss.fss_csize = 0; + if (rump_sys_ioctl(fssfd, FSSIOCSET, &fss) == -1) + err(1, "create snapshot"); + if (unl) { + if (rump_sys_unlink(FSTEST_MNTNAME "/le_snap") == -1) + err(1, "unlink snapshot"); + } + + /* now create some extra files */ + + for (i = 0; i < 4; i++) { + sprintf(buf, "file%d", i); + fd = rump_sys_open(buf, O_EXCL| O_CREAT | O_RDWR, 0644); + if (fd < 0) + err(1, "create %s", buf); + sprintf(buf, "test file no %d", i); + rump_sys_write(fd, buf, strlen(buf)); + rump_sys_close(fd); + } + if (unconf) + if (rump_sys_ioctl(fssfd, FSSIOCCLR, NULL) == -1) + err(1, "unconfigure snapshot"); + return 0; +} + +static int +quota_test5(const char *testopts) +{ + static char buf[512]; + int fd; + int remount = 0; + int unlnk = 0; + int log = 0; + unsigned int i; + + for (i =0; testopts && i < strlen(testopts); i++) { + switch(testopts[i]) { + case 'L': + log++; + break; + case 'R': + remount++; + break; + case 'U': + unlnk++; + break; + default: + errx(1, "test4: unknown option %c", testopts[i]); + } + } + if (remount) { + struct ufs_args uargs; + uargs.fspec = __UNCONST("/diskdev"); + /* remount the fs read/write */ + if (rump_sys_mount(MOUNT_FFS, FSTEST_MNTNAME, + MNT_UPDATE | (log ? MNT_LOG : 0), + &uargs, sizeof(uargs)) == -1) + err(1, "mount ffs rw %s", FSTEST_MNTNAME); + } + + if (unlnk) { + /* + * open and unlink a file + */ + + fd = rump_sys_open("unlinked_file", + O_EXCL| O_CREAT | O_RDWR, 0644); + if (fd < 0) + err(1, "create %s", "unlinked_file"); + sprintf(buf, "test unlinked_file"); + rump_sys_write(fd, buf, strlen(buf)); + if (rump_sys_unlink("unlinked_file") == -1) + err(1, "unlink unlinked_file"); + if (rump_sys_fsync(fd) == -1) + err(1, "fsync unlinked_file"); + rump_sys_reboot(RUMP_RB_NOSYNC, NULL); + errx(1, "reboot failed"); + return 1; + } + return 0; +} + +struct quota_test { + int (*func)(const char *); + const char *desc; +}; + +struct quota_test quota_tests[] = { + { quota_test0, "write up to hard limit"}, + { quota_test1, "write beyond the soft limit after grace time"}, + { quota_test2, "create file up to hard limit"}, + { quota_test3, "create file beyond the soft limit after grace time"}, + { quota_test4, "take a snapshot and add some data"}, + { quota_test5, "open and unlink a file"}, +}; + +static void +usage(void) +{ + unsigned int test; + fprintf(stderr, "usage: %s [-b] [-l] test# diskimage bindurl\n", + getprogname()); + fprintf(stderr, "available tests:\n"); + for (test = 0; test < sizeof(quota_tests) / sizeof(quota_tests[0]); + test++) + fprintf(stderr, "\t%d: %s\n", test, quota_tests[test].desc); + exit(1); +} + +static void +die(const char *reason, int error) +{ + + warnx("%s: %s", reason, strerror(error)); + if (background) + rump_daemonize_done(error); + exit(1); +} + +static sem_t sigsem; +static void +sigreboot(int sig) +{ + + sem_post(&sigsem); +} + +int +main(int argc, char **argv) +{ + int error; + u_long test; + char *end; + struct ufs_args uargs; + const char *filename; + const char *serverurl; + const char *topts = NULL; + int mntopts = 0; + int ch; + + while ((ch = getopt(argc, argv, "blo:r")) != -1) { + switch(ch) { + case 'b': + background = 1; + break; + case 'l': + mntopts |= MNT_LOG; + break; + case 'r': + mntopts |= MNT_RDONLY; + break; + case 'o': + topts = optarg; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (argc != 3) + usage(); + + filename = argv[1]; + serverurl = argv[2]; + + test = strtoul(argv[0], &end, 10); + if (*end != '\0') { + usage(); + } + if (test > sizeof(quota_tests) / sizeof(quota_tests[0])) { + usage(); + } + + if (background) { + error = rump_daemonize_begin(); + if (error) + errx(1, "rump daemonize: %s", strerror(error)); + } + + error = rump_init(); + if (error) + die("rump init failed", error); + + if (rump_sys_mkdir(FSTEST_MNTNAME, 0777) == -1) + err(1, "mount point create"); + rump_pub_etfs_register("/diskdev", filename, RUMP_ETFS_BLK); + uargs.fspec = __UNCONST("/diskdev"); + if (rump_sys_mount(MOUNT_FFS, FSTEST_MNTNAME, mntopts, + &uargs, sizeof(uargs)) == -1) + die("mount ffs", errno); + + if (rump_sys_chdir(FSTEST_MNTNAME) == -1) + err(1, "cd %s", FSTEST_MNTNAME); + error = quota_tests[test].func(topts); + if (error) { + fprintf(stderr, " test %lu: %s returned %d: %s\n", + test, quota_tests[test].desc, error, strerror(error)); + } + if (rump_sys_chdir("/") == -1) + err(1, "cd /"); + + error = rump_init_server(serverurl); + if (error) + die("rump server init failed", error); + if (background) + rump_daemonize_done(RUMP_DAEMONIZE_SUCCESS); + + sem_init(&sigsem, 0, 0); + signal(SIGTERM, sigreboot); + signal(SIGINT, sigreboot); + sem_wait(&sigsem); + + rump_sys_reboot(0, NULL); + /*NOTREACHED*/ + return 0; +} diff --git a/contrib/netbsd-tests/fs/ffs/quotas_common.sh b/contrib/netbsd-tests/fs/ffs/quotas_common.sh new file mode 100755 index 0000000..0ad002f --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/quotas_common.sh @@ -0,0 +1,12 @@ +# $NetBSD: quotas_common.sh,v 1.4 2012/01/18 20:51:23 bouyer Exp $ + +rump_quota_shutdown() +{ + for s in ${RUMP_SOCKETS_LIST}; do + atf_check -s exit:0 env RUMP_SERVER=unix://${s} rump.halt; + done +# check that the quota inode creation didn't corrupt the filesystem + atf_check -s exit:0 -o "match:already clean" \ + -o "match:Phase 6 - Check Quotas" \ + fsck_ffs -nf -F ${IMG} +} diff --git a/contrib/netbsd-tests/fs/ffs/t_clearquota.sh b/contrib/netbsd-tests/fs/ffs/t_clearquota.sh new file mode 100755 index 0000000..f62a494 --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/t_clearquota.sh @@ -0,0 +1,91 @@ +# $NetBSD: t_clearquota.sh,v 1.4 2012/01/18 20:51:23 bouyer Exp $ +# +# Copyright (c) 2011 Manuel Bouyer +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +for e in le be; do + for v in 1 2; do + for q in "user" "group"; do + test_case_root clear_${e}_${v}_${q} clear_quota \ + "clear quota with ${q} enabled" -b ${e} ${v} ${q} + done + test_case_root clear_${e}_${v}_"both" clear_quota \ + "clear quota with both enabled" -b ${e} ${v} "both" + test_case_root clear_${e}_${v}_"both_log" clear_quota \ + "clear quota for new id with both enabled, WAPBL" -bl ${e} ${v} "both" + done +done + +clear_quota() +{ + create_ffs_server $* + local q=$4 + local expect + local fail + local id=1 + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + both) + expect="u g" + fail="" + ;; + *) + atf_fail "wrong quota type" + ;; + esac + +#set and check the expected quota + for q in ${expect} ; do + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s10k/20 -h40M/50k \ + -t 2W/3D ${id} + atf_check -s exit:0 \ +-o "match:/mnt 0 10 40960 2weeks 0 20 51200 3days" \ +-o "match:Disk quotas for .*: $" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -${q} -v ${id} + done +#now clear the quotas + for q in ${expect} ; do + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -c ${id} + done; + +#check that we do not get positive reply for any quota type + for q in u g ; do + atf_check -s exit:0 -o "not-match:/mnt" \ + -o "not-match:Disk quotas for .*: $" \ + -o "match:Disk quotas for .*: none$" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -${q} -v ${id} + done + rump_quota_shutdown +} diff --git a/contrib/netbsd-tests/fs/ffs/t_fifos.c b/contrib/netbsd-tests/fs/ffs/t_fifos.c new file mode 100644 index 0000000..10b50bb --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/t_fifos.c @@ -0,0 +1,158 @@ +/* $NetBSD: t_fifos.c,v 1.6 2017/01/13 21:30:39 christos Exp $ */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC_WITH_CLEANUP(fifos); +ATF_TC_HEAD(fifos, tc) +{ + atf_tc_set_md_var(tc, "descr", "test fifo support in ffs"); + atf_tc_set_md_var(tc, "timeout", "5"); +} + +#define teststr1 "raving & drooling" +#define teststr2 "haha, charade" + +static void * +w1(void *arg) +{ + int fd; + + fd = rump_sys_open("sheep", O_WRONLY); + if (fd == -1) + atf_tc_fail_errno("w1 open"); + if (rump_sys_write(fd, teststr1, sizeof(teststr1)) != sizeof(teststr1)) + atf_tc_fail_errno("w1 write"); + rump_sys_close(fd); + + return NULL; +} + +static void * +w2(void *arg) +{ + int fd; + + fd = rump_sys_open("pigs", O_WRONLY); + if (fd == -1) + atf_tc_fail_errno("w2 open"); + if (rump_sys_write(fd, teststr2, sizeof(teststr2)) != sizeof(teststr2)) + atf_tc_fail_errno("w2 write"); + rump_sys_close(fd); + + return NULL; +} + +static void * +r1(void *arg) +{ + char buf[32]; + int fd; + + fd = rump_sys_open("sheep", O_RDONLY); + if (fd == -1) + atf_tc_fail_errno("r1 open"); + if (rump_sys_read(fd, buf, sizeof(buf)) != sizeof(teststr1)) + atf_tc_fail_errno("r1 read"); + rump_sys_close(fd); + + if (strcmp(teststr1, buf) != 0) + atf_tc_fail("got invalid str, %s vs. %s", buf, teststr1); + + return NULL; +} + +static void * +r2(void *arg) +{ + char buf[32]; + int fd; + + fd = rump_sys_open("pigs", O_RDONLY); + if (fd == -1) + atf_tc_fail_errno("r2 open"); + if (rump_sys_read(fd, buf, sizeof(buf)) != sizeof(teststr2)) + atf_tc_fail_errno("r2 read"); + rump_sys_close(fd); + + if (strcmp(teststr2, buf) != 0) + atf_tc_fail("got invalid str, %s vs. %s", buf, teststr2); + + return NULL; +} + +#define IMGNAME "atf.img" + +const char *newfs = "newfs -F -s 10000 " IMGNAME; +#define FAKEBLK "/dev/sp00ka" + +ATF_TC_BODY(fifos, tc) +{ + struct ufs_args args; + pthread_t ptw1, ptw2, ptr1, ptr2; + + if (system(newfs) == -1) + atf_tc_fail_errno("newfs failed"); + + memset(&args, 0, sizeof(args)); + args.fspec = __UNCONST(FAKEBLK); + + rump_init(); + if (rump_sys_mkdir("/animals", 0777) == -1) + atf_tc_fail_errno("cannot create mountpoint"); + rump_pub_etfs_register(FAKEBLK, IMGNAME, RUMP_ETFS_BLK); + if (rump_sys_mount(MOUNT_FFS, "/animals", 0, &args, sizeof(args))==-1) + atf_tc_fail_errno("rump_sys_mount failed"); + + /* create fifos */ + if (rump_sys_chdir("/animals") == 1) + atf_tc_fail_errno("chdir"); + if (rump_sys_mkfifo("pigs", S_IFIFO | 0777) == -1) + atf_tc_fail_errno("mknod1"); + if (rump_sys_mkfifo("sheep", S_IFIFO | 0777) == -1) + atf_tc_fail_errno("mknod2"); + + pthread_create(&ptw1, NULL, w1, NULL); + pthread_create(&ptw2, NULL, w2, NULL); + pthread_create(&ptr1, NULL, r1, NULL); + pthread_create(&ptr2, NULL, r2, NULL); + + pthread_join(ptw1, NULL); + pthread_join(ptw2, NULL); + pthread_join(ptr1, NULL); + pthread_join(ptr2, NULL); + + if (rump_sys_chdir("/") == 1) + atf_tc_fail_errno("chdir"); + + if (rump_sys_unmount("/animals", 0) == -1) + atf_tc_fail_errno("unmount failed"); +} + +ATF_TC_CLEANUP(fifos, tc) +{ + + unlink(IMGNAME); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, fifos); + return 0; +} diff --git a/contrib/netbsd-tests/fs/ffs/t_getquota.sh b/contrib/netbsd-tests/fs/ffs/t_getquota.sh new file mode 100755 index 0000000..80f3cc7 --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/t_getquota.sh @@ -0,0 +1,112 @@ +# $NetBSD: t_getquota.sh,v 1.4 2012/01/18 20:51:23 bouyer Exp $ +# +# Copyright (c) 2011 Manuel Bouyer +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +for e in le be; do + for v in 1 2; do + for q in "user" "group"; do + test_case get_${e}_${v}_${q} get_quota \ + "get quota with ${q} enabled" -b ${e} ${v} ${q} + done + test_case get_${e}_${v}_"both" get_quota \ + "get quota with both enabled" -b ${e} ${v} "both" + done +done + +get_quota() +{ + create_ffs_server $* + local q=$4 + local expect + local fail + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + both) + expect="u g" + fail="" + ;; + *) + atf_fail "wrong quota type" + ;; + esac + +#check that we can get the expected quota + for q in ${expect} ; do + atf_check -s exit:0 \ +-o "match:/mnt 0 - - 7days 1 - - 7days" \ +-o "match:Disk quotas for .*: $" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -${q} -v + atf_check -s exit:0 \ +-o "match:-- 0 - - 1 - -" \ +-o "not-match:\+\+" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt repquota -${q} /mnt + done + +#check that we do not get positive reply for non-expected quota + for q in ${fail} ; do + atf_check -s exit:0 -o "not-match:/mnt" \ + -o "not-match:Disk quotas for .*: $" \ + -o "match:Disk quotas for .*: none$" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -${q} -v + atf_check -s exit:0 \ +-o "not-match:-- 0 - - 1 - -" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt repquota -${q} /mnt + done + rump_quota_shutdown +} + +quota_walk_list() +{ + create_ffs_server $* + local q=$4 + local expect + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + both) + expect="u g" + fail="" + ;; + *) + atf_fail "wrong quota type" + ;; + esac +} diff --git a/contrib/netbsd-tests/fs/ffs/t_miscquota.sh b/contrib/netbsd-tests/fs/ffs/t_miscquota.sh new file mode 100755 index 0000000..904ea37 --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/t_miscquota.sh @@ -0,0 +1,213 @@ +# $NetBSD: t_miscquota.sh,v 1.8 2013/01/22 06:24:11 dholland Exp $ +# +# Copyright (c) 2011 Manuel Bouyer +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +test_case_root walk_list_user quota_walk_list \ + "walk user quota list over several disk blocks" -b le 1 user + +test_case_root psnapshot_user quota_snap \ + "create a persistent shapshot of quota-enabled fs, and do some writes" \ + -b le 1 user + +test_case_root npsnapshot_user quota_snap \ + "create a non-persistent shapshot of quota-enabled fs, and do some writes" \ + -boL le 1 user + +test_case_root psnapshot_unconf_user quota_snap \ + "create a persistent shapshot of quota-enabled fs, and do some writes and unconf" \ + -boC le 1 user + +test_case_root npsnapshot_unconf_user quota_snap \ + "create a non-persistent shapshot of quota-enabled fs, and do some writes and unconf" \ + -boLC le 1 user + +test_case log_unlink quota_log \ + "an unlinked file cleaned by the log replay should update quota" \ + -l le 1 user + +test_case log_unlink_remount quota_log \ + "an unlinked file cleaned by the log replay after remount" \ + -oRL le 1 user + + +test_case_root default_deny_user quota_default_deny \ + "new quota entry denied by default entry" 5 -b le 1 user + +test_case_root default_deny_user_big quota_default_deny \ + "new quota entry denied by default entry, with list on more than one block" 5000 -b le 1 user + + +quota_walk_list() +{ + create_ffs_server $* + local q=$4 + local expect + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + *) + atf_fail "wrong quota type" + ;; + esac + + # create 100 users, all in the same hash list + local i=1; + while [ $i -lt 101 ]; do + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -${expect} \ + -s10k/20 -h40M/50k -t 2W/3D $((i * 4096)) + i=$((i + 1)) + done + # do a repquota + atf_check -s exit:0 -o 'match:user 409600 block *81920 20 0' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt repquota -x -${expect} /mnt + rump_quota_shutdown +} + +quota_snap() +{ + local flag=$1; shift + create_ffs $* + local q=$3 + local expect + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + *) + atf_fail "wrong quota type" + ;; + esac + + #start our server which takes a snapshot + atf_check -s exit:0 -o ignore \ + $(atf_get_srcdir)/h_quota2_tests ${flag} 4 ${IMG} ${RUMP_SERVER} + # create a few users + local i=1; + while [ $i -lt 11 ]; do + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -${expect} \ + -s10k/20 -h40M/50k -t 2W/3D $i + i=$((i + 1)) + done + # we should have 5 files (root + 4 regular files) + atf_check -s exit:0 \ + -o 'match:- - 7days 5 - - 7days' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt repquota -av + #shutdown and check filesystem + rump_quota_shutdown +} + +quota_log() +{ + local srv2args=$1; shift + create_ffs $* + local q=$3 + local expect + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + *) + atf_fail "wrong quota type" + ;; + esac + + #start our server which create a file and unlink while keeping + # it open. The server halts itself without flush + atf_check -s exit:0 -o ignore \ + $(atf_get_srcdir)/h_quota2_tests -loU 5 ${IMG} ${RUMP_SERVER} + # we should have one unlinked file, but the log covers it. + atf_check -s exit:0 -o match:'3 files' -e ignore \ + fsck_ffs -nf -F ${IMG} + # have a kernel mount the fs again; it should cleanup the + # unlinked file + atf_check -o ignore -e ignore $(atf_get_srcdir)/h_quota2_tests \ + ${srv2args} -b 5 ${IMG} ${RUMP_SERVER} + #shutdown and check filesystem + rump_quota_shutdown +} + +quota_default_deny() +{ + local nusers=$1; shift + create_ffs_server $* + local q=$4 + local expect + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + *) + atf_fail "wrong quota type" + ;; + esac + + # create $nusers users, so we are sure the free list has entries + # from block 1. Start from 10, as non-root id is 1. + # set default to deny all + ( echo "@format netbsd-quota-dump v1" + echo "# idtype id objtype hard soft usage expire grace" + echo "$q default block 0 0 0 0 0" + echo "$q default file 0 0 0 0 0" + local i=10; + while [ $i -lt $(($nusers + 10)) ]; do + echo "$q $i block 0 0 0 0 0" + echo "$q $i file 0 0 0 0 0" + i=$((i + 1)) + done + ) | atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quotarestore -d /mnt + atf_check -s exit:0 rump.halt + #now start the server which does the limits tests + $(atf_get_srcdir)/h_quota2_tests -oC -b 0 ${IMG} ${RUMP_SERVER} + rump_quota_shutdown +} diff --git a/contrib/netbsd-tests/fs/ffs/t_mount.c b/contrib/netbsd-tests/fs/ffs/t_mount.c new file mode 100644 index 0000000..2096095 --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/t_mount.c @@ -0,0 +1,138 @@ +/* $NetBSD: t_mount.c,v 1.14 2017/01/13 21:30:39 christos Exp $ */ + +/* + * Basic tests for mounting + */ + +/* + * 48Kimage: + * Adapted for rump and atf from a testcase supplied + * by Hubert Feyrer on netbsd-users@ + */ + +#include + +#define FSTEST_IMGSIZE (96 * 512) +#include "../common/h_fsmacros.h" + +#include +#include + +#include + +#include + +#include +#include + +#include "h_macros.h" + +ATF_TC(48Kimage); +ATF_TC_HEAD(48Kimage, tc) +{ + atf_tc_set_md_var(tc, "descr", "mount small 48K ffs image"); +} + +ATF_TC_BODY(48Kimage, tc) +{ + void *tmp; + + atf_tc_expect_fail("PR kern/43573"); + FSTEST_CONSTRUCTOR(tc, ffs, tmp); + atf_tc_expect_pass(); + + FSTEST_DESTRUCTOR(tc, ffs, tmp); +} + +ATF_TC(fsbsizeovermaxphys); +ATF_TC_HEAD(fsbsizeovermaxphys, tc) +{ + + atf_tc_set_md_var(tc, "descr", "mounts file system with " + "blocksize > MAXPHYS"); + /* PR kern/43727 */ +} + +ATF_TC_BODY(fsbsizeovermaxphys, tc) +{ + char cmd[1024]; + struct ufs_args args; + struct statvfs svb; + + /* + * We cannot pass newfs parameters via the fstest interface, + * so do things the oldfashioned manual way. + */ + snprintf(cmd, sizeof(cmd), "newfs -G -b %d -F -s 10000 " + "ffs.img > /dev/null", MAXPHYS * 2); + if (system(cmd)) + atf_tc_fail("cannot create file system"); + + rump_init(); + if (rump_pub_etfs_register("/devdisk", "ffs.img", RUMP_ETFS_BLK)) + atf_tc_fail("cannot register rump fake device"); + + args.fspec = __UNCONST("/devdisk"); + + if (rump_sys_mkdir("/mp", 0777) == -1) + atf_tc_fail_errno("create mountpoint"); + + /* mount succeeded? bad omen. confirm we're in trouble. */ + if (rump_sys_mount(MOUNT_FFS, "/mp", 0, &args, sizeof(args)) != -1) { + rump_sys_statvfs1("/mp", &svb, ST_WAIT); + atf_tc_fail("not expecting to be alive"); + } + + /* otherwise we're do-ne */ +} + +ATF_TC(fsbsizeovermaxbsize); +ATF_TC_HEAD(fsbsizeovermaxbsize, tc) +{ + + atf_tc_set_md_var(tc, "descr", "mounts file system with " + "blocksize > MAXBSIZE"); +} + +ATF_TC_BODY(fsbsizeovermaxbsize, tc) +{ + char cmd[1024]; + struct ufs_args args; + struct statvfs svb; + + /* + * We cannot pass newfs parameters via the fstest interface, + * so do things the oldfashioned manual way. + */ + snprintf(cmd, sizeof(cmd), "newfs -G -b %d -F -s 10000 " + "ffs.img > /dev/null", MAXBSIZE * 2); + if (system(cmd)) + atf_tc_fail("cannot create file system"); + + rump_init(); + if (rump_pub_etfs_register("/devdisk", "ffs.img", RUMP_ETFS_BLK)) + atf_tc_fail("cannot register rump fake device"); + + args.fspec = __UNCONST("/devdisk"); + + if (rump_sys_mkdir("/mp", 0777) == -1) + atf_tc_fail_errno("create mountpoint"); + + /* mount succeeded? bad omen. confirm we're in trouble. */ + if (rump_sys_mount(MOUNT_FFS, "/mp", 0, &args, sizeof(args)) != -1) { + rump_sys_statvfs1("/mp", &svb, ST_WAIT); + atf_tc_fail("not expecting to be alive"); + } + + /* otherwise we're do-ne */ +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, 48Kimage); + ATF_TP_ADD_TC(tp, fsbsizeovermaxphys); + ATF_TP_ADD_TC(tp, fsbsizeovermaxbsize); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/ffs/t_quota2_1.c b/contrib/netbsd-tests/fs/ffs/t_quota2_1.c new file mode 100644 index 0000000..22cd5d2 --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/t_quota2_1.c @@ -0,0 +1,114 @@ +/* $NetBSD: t_quota2_1.c,v 1.5 2017/01/13 21:30:39 christos Exp $ */ + +/* + * Basic tests for quota2 + */ + +#include + +#include "../common/h_fsmacros.h" + +#include +#include + +#include + +#include + +#include +#include + +#include "h_macros.h" + +static void +do_quota(const atf_tc_t *tc, int n, const char *newfs_opts, int log) +{ + int i; + char buf[1024]; + int res; + int fd; + struct ufs_args uargs; + + snprintf(buf, sizeof(buf), "newfs -q user -q group -F -s 4000 -n %d " + "%s %s", (n + 3), newfs_opts, FSTEST_IMGNAME); + if (system(buf) == -1) + atf_tc_fail_errno("cannot create file system"); + + rump_init(); + if (rump_sys_mkdir(FSTEST_MNTNAME, 0777) == -1) + atf_tc_fail_errno("mount point create"); + + rump_pub_etfs_register("/diskdev", FSTEST_IMGNAME, RUMP_ETFS_BLK); + + uargs.fspec = __UNCONST("/diskdev"); + if (rump_sys_mount(MOUNT_FFS, FSTEST_MNTNAME, (log) ? MNT_LOG : 0, + &uargs, sizeof(uargs)) == -1) + atf_tc_fail_errno("mount ffs %s", FSTEST_MNTNAME); + + atf_tc_expect_pass(); + FSTEST_ENTER(); + RL(rump_sys_chown(".", 0, 0)); + for (i = 0 ; i < n; i++) { + sprintf(buf, "file%d", i); + RL(fd = rump_sys_open(buf, O_CREAT | O_RDWR, 0755)); + sprintf(buf, "test file no %d", i); + RL(rump_sys_write(fd, buf, strlen(buf))); + RL(rump_sys_fchown(fd, i, i+80000)); + rump_sys_close(fd); + } + FSTEST_EXIT(); + if (rump_sys_unmount(FSTEST_MNTNAME, 0) != 0) { + rump_pub_vfs_mount_print(FSTEST_MNTNAME, 1); + atf_tc_fail_errno("unmount failed"); + } + snprintf(buf, 1024, "fsck_ffs -fn -F %s", FSTEST_IMGNAME); + res = system(buf); + if (res != 0) + atf_tc_fail("fsck returned %d", res); +} + +#define DECL_TEST(nent, newops, name, descr, log) \ +ATF_TC(quota_##name); \ + \ +ATF_TC_HEAD(quota_##name, tc) \ +{ \ + atf_tc_set_md_var(tc, "descr", \ + "test quotas with %d users and groups, %s", \ + nent, descr); \ +} \ + \ +ATF_TC_BODY(quota_##name, tc) \ +{ \ + do_quota(tc, nent, newops, log); \ +} + +DECL_TEST(40, "-O1 -B le", 40_O1_le, "UFS1 little-endian", 0) +DECL_TEST(40, "-O1 -B be", 40_O1_be, "UFS1 big-endian", 0) + +DECL_TEST(40, "-O2 -B le", 40_O2_le, "UFS2 little-endian", 0) +DECL_TEST(40, "-O2 -B be", 40_O2_be, "UFS2 big-endian", 0) + +DECL_TEST(40, "-O1", 40_O1_log, "UFS1 log", 1) +DECL_TEST(40, "-O2", 40_O2_log, "UFS2 log", 1) + +DECL_TEST(1000, "-O1 -B le", 1000_O1_le, "UFS1 little-endian", 0) +DECL_TEST(1000, "-O1 -B be", 1000_O1_be, "UFS1 big-endian", 0) + +DECL_TEST(1000, "-O2 -B le", 1000_O2_le, "UFS2 little-endian", 0) +DECL_TEST(1000, "-O2 -B be", 1000_O2_be, "UFS2 big-endian", 0) + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, quota_40_O1_le); + ATF_TP_ADD_TC(tp, quota_40_O1_be); + ATF_TP_ADD_TC(tp, quota_40_O2_le); + ATF_TP_ADD_TC(tp, quota_40_O2_be); + ATF_TP_ADD_TC(tp, quota_40_O1_log); + ATF_TP_ADD_TC(tp, quota_40_O2_log); + ATF_TP_ADD_TC(tp, quota_1000_O1_le); + ATF_TP_ADD_TC(tp, quota_1000_O1_be); + ATF_TP_ADD_TC(tp, quota_1000_O2_le); + ATF_TP_ADD_TC(tp, quota_1000_O2_be); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/ffs/t_quota2_remount.c b/contrib/netbsd-tests/fs/ffs/t_quota2_remount.c new file mode 100644 index 0000000..d843cf8 --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/t_quota2_remount.c @@ -0,0 +1,139 @@ +/* $NetBSD: t_quota2_remount.c,v 1.5 2017/01/13 21:30:39 christos Exp $ */ + +/* + * Basic tests for quota2 + */ + +#include + +#include "../common/h_fsmacros.h" + +#include +#include +#include + +#include + +#include + +#include +#include + +#include "h_macros.h" + +static void +do_quota(const atf_tc_t *tc, int n, const char *newfs_opts, int log) +{ + int i; + char buf[1024]; + int res; + int fd; + struct ufs_args uargs; + struct statvfs fst; + + snprintf(buf, sizeof(buf), "newfs -q user -q group -F -s 4000 -n %d " + "%s %s", (n + 3), newfs_opts, FSTEST_IMGNAME); + if (system(buf) == -1) + atf_tc_fail_errno("cannot create file system"); + + rump_init(); + if (rump_sys_mkdir(FSTEST_MNTNAME, 0777) == -1) + atf_tc_fail_errno("mount point create"); + + rump_pub_etfs_register("/diskdev", FSTEST_IMGNAME, RUMP_ETFS_BLK); + + uargs.fspec = __UNCONST("/diskdev"); + + /* read-only doens't have quota enabled */ + if (rump_sys_mount(MOUNT_FFS, FSTEST_MNTNAME, MNT_RDONLY, + &uargs, sizeof(uargs)) == -1) + atf_tc_fail_errno("mount ffs ro %s", FSTEST_MNTNAME); + + if (rump_sys_statvfs1(FSTEST_MNTNAME, &fst, 0) != 0) + atf_tc_fail_errno("statbfs %s (1)", FSTEST_MNTNAME); + + if ((fst.f_flag & ST_QUOTA) != 0) + atf_tc_fail("R/O filesystem has quota"); + + /* updating to read-write enables quota */ + if (rump_sys_mount(MOUNT_FFS, FSTEST_MNTNAME, + MNT_UPDATE | (log ? MNT_LOG : 0), &uargs, sizeof(uargs)) == -1) + atf_tc_fail_errno("mount ffs rw %s", FSTEST_MNTNAME); + + if (rump_sys_statvfs1(FSTEST_MNTNAME, &fst, 0) != 0) + atf_tc_fail_errno("statbfs %s (2)", FSTEST_MNTNAME); + + if ((fst.f_flag & ST_QUOTA) == 0) + atf_tc_fail("R/W filesystem has no quota"); + + /* we can update a second time */ + if (rump_sys_mount(MOUNT_FFS, FSTEST_MNTNAME, + MNT_UPDATE | (log ? MNT_LOG : 0), &uargs, sizeof(uargs)) == -1) + atf_tc_fail_errno("mount ffs rw(2) %s", FSTEST_MNTNAME); + + if (rump_sys_statvfs1(FSTEST_MNTNAME, &fst, 0) != 0) + atf_tc_fail_errno("statbfs %s (3)", FSTEST_MNTNAME); + + if ((fst.f_flag & ST_QUOTA) == 0) + atf_tc_fail("R/W filesystem has no quota"); + + /* create some files so fsck has something to check */ + FSTEST_ENTER(); + RL(rump_sys_chown(".", 0, 0)); + for (i = 0 ; i < n; i++) { + sprintf(buf, "file%d", i); + RL(fd = rump_sys_open(buf, O_CREAT | O_RDWR, 0755)); + sprintf(buf, "test file no %d", i); + RL(rump_sys_write(fd, buf, strlen(buf))); + RL(rump_sys_fchown(fd, i, i+80000)); + rump_sys_close(fd); + } + FSTEST_EXIT(); + if (rump_sys_unmount(FSTEST_MNTNAME, 0) != 0) { + rump_pub_vfs_mount_print(FSTEST_MNTNAME, 1); + atf_tc_fail_errno("unmount failed"); + } + snprintf(buf, 1024, "fsck_ffs -fn -F %s", FSTEST_IMGNAME); + res = system(buf); + if (res != 0) + atf_tc_fail("fsck returned %d", res); +} + +#define DECL_TEST(nent, newops, name, descr, log) \ +ATF_TC(quota_##name); \ + \ +ATF_TC_HEAD(quota_##name, tc) \ +{ \ + atf_tc_set_md_var(tc, "descr", \ + "test filesystem remount with quotas, %s", descr); \ +} \ + \ +ATF_TC_BODY(quota_##name, tc) \ +{ \ + do_quota(tc, nent, newops, log); \ +} + +DECL_TEST(10, "-O1 -B le", 10_O1_le, "UFS1 little-endian", 0) +DECL_TEST(10, "-O1 -B be", 10_O1_be, "UFS1 big-endian", 0) + +#if 0 +/* + * this cause fsck to complain about summaries at the end. + * This sems to be related to -o log (reproductible on a fs with no + * quota enabled). not reproductible with a real kernel ... + */ +DECL_TEST(10, "-O1", 10_O1_log, "UFS1 log", 1) +DECL_TEST(10, "-O2", 10_O2_log, "UFS2 log", 1) +#endif + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, quota_10_O1_le); + ATF_TP_ADD_TC(tp, quota_10_O1_be); +#if 0 + ATF_TP_ADD_TC(tp, quota_10_O1_log); + ATF_TP_ADD_TC(tp, quota_10_O2_log); +#endif + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/ffs/t_quotalimit.sh b/contrib/netbsd-tests/fs/ffs/t_quotalimit.sh new file mode 100755 index 0000000..16e47b7 --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/t_quotalimit.sh @@ -0,0 +1,345 @@ +# $NetBSD: t_quotalimit.sh,v 1.4 2012/01/18 20:51:23 bouyer Exp $ +# +# Copyright (c) 2011 Manuel Bouyer +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +for e in le; do + for v in 1; do + for q in "user" "group"; do + test_case_root limit_${e}_${v}_${q} limit_quota \ + "hit hard limit quota with ${q} enabled" -b ${e} ${v} ${q} + test_case_root limit_${e}_${v}_${q}_log limit_quota \ + "hit hard limit quota with ${q} enabled, WAPBL" -bl ${e} ${v} ${q} + test_case_root slimit_${e}_${v}_${q} limit_softquota \ + "hit soft limit quota with ${q} enabled after grace time" \ + -b ${e} ${v} ${q} + test_case_root inolimit_${e}_${v}_${q} limit_iquota \ + "hit hard limit ino quota with ${q} enabled" -b ${e} ${v} ${q} + test_case_root inolimit_${e}_${v}_${q}_log limit_iquota \ + "hit hard limit ino quota with ${q} enabled, WAPBL" -bl ${e} ${v} ${q} + test_case_root sinolimit_${e}_${v}_${q} limit_softiquota \ + "hit soft limit ino quota with ${q} enabled after grace time" \ + -b ${e} ${v} ${q} + test_case_root herit_defq_${e}_${v}_${q} inherit_defaultquota \ + "new id herit from default for ${q} quota" -b ${e} ${v} ${q} + test_case_root herit_defq_${e}_${v}_${q}_log inherit_defaultquota \ + "new id herit from default for ${q} quota, WAPBL" -bl ${e} ${v} ${q} + test_case_root herit_idefq_${e}_${v}_${q}_log inherit_defaultiquota \ + "new id herit from default for ${q} ino quota, WAPBL" -bl ${e} ${v} ${q} + done + done +done + +limit_quota() +{ + create_ffs_server $* + local q=$4 + local expect + local id=1 + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + both) + expect="u g" + fail="" + ;; + *) + atf_fail "wrong quota type" + ;; + esac + + for q in ${expect} ; do + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s2k/4 -h3k/6 \ + -t 2h/2h ${id} + done + atf_check -s exit:0 rump.halt + + #now start the server which does the limits tests + atf_check -s exit:0 -o ignore \ +-e match:'test 0: write up to hard limit returned 69: Disc quota exceeded' \ + $(atf_get_srcdir)/h_quota2_tests -b 0 ${IMG} ${RUMP_SERVER} + for q in ${expect} ; do + atf_check -s exit:0 \ + -o match:'/mnt 3072 B\* 2048 B 3072 B 2:0 2 4 6 ' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -$q -h ${id} + atf_check -s exit:0 \ + -o match:'daemon \+- 3 2 3 2:0 2 4 6' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt repquota -$q /mnt + done + rump_quota_shutdown +} + +limit_softquota() +{ + create_ffs_server $* + local q=$4 + local expect + local id=1 + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + both) + expect="u g" + fail="" + ;; + *) + atf_fail "wrong quota type" + ;; + esac + + for q in ${expect} ; do + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s2k/4 -h3k/6 \ + -t 1s/1d ${id} + done + atf_check -s exit:0 rump.halt + + #now start the server which does the limits tests + atf_check -s exit:0 -o ignore \ +-e match:'test 1: write beyond the soft limit after grace time returned 69: Disc quota exceeded' \ + $(atf_get_srcdir)/h_quota2_tests -b 1 ${IMG} ${RUMP_SERVER} + for q in ${expect} ; do + atf_check -s exit:0 \ + -o match:'/mnt 2560 B\* 2048 B 3072 B none 2 4 6 ' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -$q -h ${id} + atf_check -s exit:0 \ + -o match:'daemon \+- 2 2 3 none 2 4 6' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt repquota -$q /mnt + done + rump_quota_shutdown +} + +limit_iquota() +{ + create_ffs_server $* + local q=$4 + local expect + local id=1 + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + both) + expect="u g" + fail="" + ;; + *) + atf_fail "wrong quota type" + ;; + esac + + for q in ${expect} ; do + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s2m/4 -h3m/6 \ + -t 2h/2h ${id} + done + atf_check -s exit:0 rump.halt + + #now start the server which does the limits tests + atf_check -s exit:0 -o ignore \ +-e match:'test 2: create file up to hard limit returned 69: Disc quota exceeded' \ + $(atf_get_srcdir)/h_quota2_tests -b 2 ${IMG} ${RUMP_SERVER} + for q in ${expect} ; do + atf_check -s exit:0 \ + -o match:'/mnt 3072 B 2048 K 3072 K 6 \* 4 6 2:0' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -$q -h ${id} + atf_check -s exit:0 \ + -o match:'daemon -\+ 3 2048 3072 6 4 6 2:0' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt repquota -$q /mnt + done + rump_quota_shutdown +} + +limit_softiquota() +{ + create_ffs_server $* + local q=$4 + local expect + local id=1 + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + both) + expect="u g" + fail="" + ;; + *) + atf_fail "wrong quota type" + ;; + esac + + for q in ${expect} ; do + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s2m/4 -h3m/6 \ + -t 1d/1s ${id} + done + atf_check -s exit:0 rump.halt + + #now start the server which does the limits tests + atf_check -s exit:0 -o ignore \ +-e match:'test 3: create file beyond the soft limit after grace time returned 69: Disc quota exceeded' \ + $(atf_get_srcdir)/h_quota2_tests -b 3 ${IMG} ${RUMP_SERVER} + for q in ${expect} ; do + atf_check -s exit:0 \ + -o match:'/mnt 2560 B 2048 K 3072 K 5 \* 4 6 none' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -$q -h ${id} + atf_check -s exit:0 \ + -o match:'daemon -\+ 2 2048 3072 5 4 6 none' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt repquota -$q /mnt + done + rump_quota_shutdown +} + +inherit_defaultquota() +{ + create_ffs_server $* + local q=$4 + local expect + local id=1 + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + both) + expect="u g" + fail="" + ;; + *) + atf_fail "wrong quota type" + ;; + esac + + for q in ${expect} ; do + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s2k/4 -h3k/6 \ + -t 2h/2h -d + done + for q in ${expect} ; do + atf_check -s exit:0 \ + -o match:'Disk quotas for .*id 1\): none' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -$q -v ${id} + done + atf_check -s exit:0 rump.halt + + #now start the server which does the limits tests + atf_check -s exit:0 -o ignore \ +-e match:'test 0: write up to hard limit returned 69: Disc quota exceeded' \ + $(atf_get_srcdir)/h_quota2_tests -b 0 ${IMG} ${RUMP_SERVER} + for q in ${expect} ; do + atf_check -s exit:0 \ + -o match:'/mnt 3072 B\* 2048 B 3072 B 2:0 2 4 6 ' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -$q -h ${id} + atf_check -s exit:0 \ + -o match:'daemon \+- 3 2 3 2:0 2 4 6' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt repquota -$q /mnt + done + rump_quota_shutdown +} + +inherit_defaultiquota() +{ + create_ffs_server $* + local q=$4 + local expect + local id=1 + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + both) + expect="u g" + fail="" + ;; + *) + atf_fail "wrong quota type" + ;; + esac + + for q in ${expect} ; do + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s2m/4 -h3m/6 \ + -t 2h/2h -d + done + for q in ${expect} ; do + atf_check -s exit:0 \ + -o match:'Disk quotas for .*id 1\): none' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -$q -v ${id} + done + atf_check -s exit:0 rump.halt + + #now start the server which does the limits tests + atf_check -s exit:0 -o ignore \ +-e match:'test 2: create file up to hard limit returned 69: Disc quota exceeded' \ + $(atf_get_srcdir)/h_quota2_tests -b 2 ${IMG} ${RUMP_SERVER} + for q in ${expect} ; do + atf_check -s exit:0 \ + -o match:'/mnt 3072 B 2048 K 3072 K 6 \* 4 6 2:0' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -$q -h ${id} + atf_check -s exit:0 \ + -o match:'daemon -\+ 3 2048 3072 6 4 6 2:0' \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt repquota -$q /mnt + done + rump_quota_shutdown +} diff --git a/contrib/netbsd-tests/fs/ffs/t_setquota.sh b/contrib/netbsd-tests/fs/ffs/t_setquota.sh new file mode 100755 index 0000000..5795fe4 --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/t_setquota.sh @@ -0,0 +1,203 @@ +# $NetBSD: t_setquota.sh,v 1.4 2012/01/18 20:51:23 bouyer Exp $ +# +# Copyright (c) 2011 Manuel Bouyer +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +for e in le be; do + for v in 1 2; do + for q in "user" "group"; do + test_case_root set_${e}_${v}_${q} set_quota \ + "set quota with ${q} enabled" -b ${e} ${v} ${q} + test_case_root set_new_${e}_${v}_${q} set_quota_new \ + "set quota for new id with ${q} enabled" -b ${e} ${v} ${q} + test_case_root set_default_${e}_${v}_${q} set_quota_default \ + "set default quota with ${q} enabled" -b ${e} ${v} ${q} + done + test_case_root set_${e}_${v}_"both" set_quota \ + "set quota with both enabled" -b ${e} ${v} "both" + test_case_root set_new_${e}_${v}_"both" set_quota_new \ + "set quota for new id with both enabled" -b ${e} ${v} "both" + test_case_root set_new_${e}_${v}_"both_log" set_quota_new \ + "set quota for new id with both enabled, WAPBL" -bl ${e} ${v} "both" + test_case_root set_default_${e}_${v}_"both" set_quota_default \ + "set default quota with both enabled" -b ${e} ${v} "both" + done +done + +set_quota() +{ + create_ffs_server $* + local q=$4 + local expect + local fail + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + both) + expect="u g" + fail="" + ;; + *) + atf_fail "wrong quota type" + ;; + esac + +#check that we can set the expected quota + for q in ${expect} ; do + local id=$(id -${q}) + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s10k/20 -h40M/50k \ + -t 2W/3D ${id} + atf_check -s exit:0 \ +-o "match:/mnt 0 10 40960 2weeks 1 20 51200 3days" \ +-o "match:Disk quotas for .*: $" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -${q} -v + atf_check -s exit:0 \ +-o "match:-- 0 10 40960 1 20 51200" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt repquota -${q} /mnt + done + +#check that we do not get positive reply for non-expected quota + for q in ${fail} ; do + local id=$(id -${q}) + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s10k/20 -h40M/50k ${id} + atf_check -s exit:0 -o "not-match:/mnt" \ + -o "not-match:Disk quotas for .*: $" \ + -o "match:Disk quotas for .*: none$" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -${q} -v + atf_check -s exit:0 \ +-o "not-match:-- 0 - -" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt repquota -${q} /mnt + done + rump_quota_shutdown +} + +set_quota_new() +{ + create_ffs_server $* + local q=$4 + local expect + local fail + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + both) + expect="u g" + fail="" + ;; + *) + atf_fail "wrong quota type" + ;; + esac + +#check that we can set the expected quota + for q in ${expect} ; do + local id=1 + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s10k/20 -h40M/50k \ + -t 120W/255D ${id} + atf_check -s exit:0 \ +-o "match:/mnt 0 10 40960 2years 0 20 51200 9months" \ +-o "match:Disk quotas for .*: $" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -${q} -v ${id} + done + +#check that we do not get positive reply for non-expected quota + for q in ${fail} ; do + local id=$(id -${q}) + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s10k/20 -h40M/50k ${id} + atf_check -s exit:0 -o "not-match:/mnt" \ + -o "not-match:Disk quotas for .*: $" \ + -o "match:Disk quotas for .*: none$" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -${q} -v ${id} + done + rump_quota_shutdown +} + +set_quota_default() +{ + create_ffs_server $* + local q=$4 + local expect + local fail + + case ${q} in + user) + expect=u + fail=g + ;; + group) + expect=g + fail=u + ;; + both) + expect="u g" + fail="" + ;; + *) + atf_fail "wrong quota type" + ;; + esac + +#check that we can set the expected quota + for q in ${expect} ; do + local id="-d" + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s10k/20 -h40M/50k \ + -t 2H2M/3540 ${id} + atf_check -s exit:0 \ +-o "match:/mnt 0 10 40960 2:2 0 20 51200 59" \ +-o "match:Default (user|group) disk quotas: $" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -${q} -v ${id} + done + +#check that we do not get positive reply for non-expected quota + for q in ${fail} ; do + local id="-d" + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt edquota -$q -s10k/20 -h40M/50k ${id} + atf_check -s exit:0 -o "not-match:/mnt" \ + -o "not-match:Default (user|group) disk quotas: $" \ + -o "match:Default (user|group) disk quotas: none$" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/mnt quota -${q} -v ${id} + done + rump_quota_shutdown +} diff --git a/contrib/netbsd-tests/fs/ffs/t_snapshot.c b/contrib/netbsd-tests/fs/ffs/t_snapshot.c new file mode 100644 index 0000000..f661bec --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/t_snapshot.c @@ -0,0 +1,43 @@ +/* $NetBSD: t_snapshot.c,v 1.7 2017/01/13 21:30:39 christos Exp $ */ + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "h_macros.h" + +#define IMGNAME "ffs.img" +#define NEWFS "newfs -F -s 10000 " IMGNAME +#define FSCK "fsck_ffs -fn -F" +#define BAKNAME "/mnt/le_snapp" + +static void +mount_diskfs(const char *fspec, const char *path) +{ + struct ufs_args uargs; + + uargs.fspec = __UNCONST(fspec); + + if (rump_sys_mount(MOUNT_FFS, path, 0, &uargs, sizeof(uargs)) == -1) + atf_tc_fail_errno("mount ffs %s", path); +} + +static void +begin(void) +{ + + /* empty */ +} + +#include "../common/snapshot.c" diff --git a/contrib/netbsd-tests/fs/ffs/t_snapshot_log.c b/contrib/netbsd-tests/fs/ffs/t_snapshot_log.c new file mode 100644 index 0000000..31b28e5 --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/t_snapshot_log.c @@ -0,0 +1,46 @@ +/* $NetBSD: t_snapshot_log.c,v 1.3 2017/01/13 21:30:39 christos Exp $ */ + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "h_macros.h" + +#define IMGNAME "ffs.img" +#define NEWFS "newfs -F -s 10000 " IMGNAME +#define FSCK "fsck_ffs -fn -F" +#define BAKNAME "/mnt/le_snapp" + +static void +mount_diskfs(const char *fspec, const char *path) +{ + struct ufs_args uargs; + static int flags = MNT_LOG; + + uargs.fspec = __UNCONST(fspec); + + if (rump_sys_mount(MOUNT_FFS, + path, flags, &uargs, sizeof(uargs)) == -1) + atf_tc_fail_errno("mount ffs %s", path); + flags = 0; +} + +static void +begin(void) +{ + + /* empty */ +} + +#include "../common/snapshot.c" diff --git a/contrib/netbsd-tests/fs/ffs/t_snapshot_v2.c b/contrib/netbsd-tests/fs/ffs/t_snapshot_v2.c new file mode 100644 index 0000000..b27929c --- /dev/null +++ b/contrib/netbsd-tests/fs/ffs/t_snapshot_v2.c @@ -0,0 +1,43 @@ +/* $NetBSD: t_snapshot_v2.c,v 1.3 2017/01/13 21:30:39 christos Exp $ */ + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "h_macros.h" + +#define IMGNAME "ffs.img" +#define NEWFS "newfs -F -s 10000 -O 2 " IMGNAME +#define FSCK "fsck_ffs -fn -F" +#define BAKNAME "/mnt/le_snapp" + +static void +mount_diskfs(const char *fspec, const char *path) +{ + struct ufs_args uargs; + + uargs.fspec = __UNCONST(fspec); + + if (rump_sys_mount(MOUNT_FFS, path, 0, &uargs, sizeof(uargs)) == -1) + atf_tc_fail_errno("mount ffs %s", path); +} + +static void +begin(void) +{ + + /* empty */ +} + +#include "../common/snapshot.c" diff --git a/contrib/netbsd-tests/fs/fifofs/t_fifo.c b/contrib/netbsd-tests/fs/fifofs/t_fifo.c new file mode 100644 index 0000000..4b37bb8 --- /dev/null +++ b/contrib/netbsd-tests/fs/fifofs/t_fifo.c @@ -0,0 +1,238 @@ +/* Test case written by Bharat Joshi */ +#include +__RCSID("$NetBSD: t_fifo.c,v 1.2 2017/01/10 22:36:29 christos Exp $"); + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef STANDALONE +#include +#endif + +#define FIFO_FILE_PATH "./fifo_file" +#define NUM_MESSAGES 20 +#define MSG_SIZE 240 +#define MESSAGE "I am fine" + +static int verbose = 0; + +/* + * child_writer + * + * Function that runs in child context and opens and write to the FIFO. + */ +static void +child_writer(void) +{ + ssize_t rv; + int fd; + size_t count; + char message[MSG_SIZE] = MESSAGE; + static const struct timespec ts = { 0, 10000 }; + + /* Open the fifo in write-mode */ + for (;;) { + fd = open(FIFO_FILE_PATH, O_WRONLY, 0); + if (fd == -1) { + if (errno == EINTR) + continue; + err(1, "Child: can't open fifo in write mode"); + } + break; + } + + for (count = 0; count < NUM_MESSAGES; count++) { + rv = write(fd, message, MSG_SIZE); + if (rv == -1) { + warn("Child: Failed to write"); + break; + } + if (rv != MSG_SIZE) + warnx("Child: wrote only %zd", rv); + nanosleep(&ts, NULL); + } + + close(fd); + if (verbose) { + printf("Child: Closed the fifo file\n"); + fflush(stdout); + } +} + +/* + * _sigchild_handler + * + * Called when a sigchild is delivered + */ +static void +sigchild_handler(int signo) +{ + if (verbose) { + if (signo == SIGCHLD) { + printf("Got sigchild\n"); + } else { + printf("Got %d signal\n", signo); + } + fflush(stdout); + } + +} + +static int +run(void) +{ + pid_t pid; + ssize_t rv; + int fd, status; + size_t buf_size = MSG_SIZE; + char buf[MSG_SIZE]; + struct sigaction action; + static const struct timespec ts = { 0, 500000000 }; + + /* Catch sigchild Signal */ + memset(&action, 0, sizeof(action)); + action.sa_handler = sigchild_handler; + sigemptyset(&action.sa_mask); + + if (sigaction(SIGCHLD, &action, NULL) == -1) + err(1, "sigaction"); + + (void)unlink(FIFO_FILE_PATH); + /* First create a fifo */ + if (mkfifo(FIFO_FILE_PATH, S_IRUSR | S_IWUSR) == -1) + err(1, "mkfifo"); + + switch ((pid = fork())) { + case -1: + err(1, "fork"); + case 0: + /* Open the file in write mode so that subsequent read + * from parent side does not block the parent.. + */ + if ((fd = open(FIFO_FILE_PATH, O_WRONLY, 0)) == -1) + err(1, "failed to open fifo"); + + /* In child */ + child_writer(); + return 0; + + default: + break; + } + + if (verbose) { + printf("Child pid is %d\n", pid ); + fflush(stdout); + } + + /* In parent */ + for (;;) { + if ((fd = open(FIFO_FILE_PATH, O_RDONLY, 0)) == -1) { + if (errno == EINTR) + continue; + else + err(1, "Failed to open the fifo in read mode"); + } + /* Read mode is opened */ + break; + + } + + nanosleep(&ts, NULL); + if (verbose) { + printf("Was sleeping...\n"); + fflush(stdout); + } + + for (;;) { + rv = read(fd, buf, buf_size); + + if (rv == -1) { + warn("Failed to read"); + if (errno == EINTR) { + if (verbose) { + printf("Parent interrupted, " + "continuing...\n"); + fflush(stdout); + } + continue; + } + + break; + } + + if (rv == 0) { + if (verbose) { + printf("Writers have closed, looks like we " + "are done\n"); + fflush(stdout); + } + break; + } + + if (verbose) { + printf("Received %zd bytes message '%s'\n", rv, buf); + fflush(stdout); + } + } + + close(fd); + + if (verbose) { + printf("We are done.. now reap the child"); + fflush(stdout); + } + + // Read the child... + while (waitpid(pid, &status, 0) == -1) + if (errno != EINTR) { + warn("Failed to reap the child"); + return 1; + } + + if (verbose) { + printf("We are done completely\n"); + fflush(stdout); + } + return 0; +} + +#ifndef STANDALONE +ATF_TC(parent_child); + +ATF_TC_HEAD(parent_child, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that when a fifo is shared " + "between a reader parent and a writer child, that read will " + "return EOF, and not get stuck after the child exits"); +} + +ATF_TC_BODY(parent_child, tc) +{ + ATF_REQUIRE(run() == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, parent_child); + + return atf_no_error(); +} +#else +int +main(void) +{ + verbose = 1; + return run(); +} +#endif diff --git a/contrib/netbsd-tests/fs/h_funcs.subr b/contrib/netbsd-tests/fs/h_funcs.subr new file mode 100644 index 0000000..21bdd97 --- /dev/null +++ b/contrib/netbsd-tests/fs/h_funcs.subr @@ -0,0 +1,75 @@ +#!/bin/sh +# +# $NetBSD: h_funcs.subr,v 1.3 2010/06/23 11:19:17 pooka Exp $ +# +# Copyright (c) 2007 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# require_fs name +# +# Checks that the given file system is built into the kernel and +# that its corresponding mount(8) utility is available. Otherwise +# skips the test. +# +require_fs() { + local name + local autoload + name="${1}" + + atf_require_prog mount + atf_require_prog mount_${name} + atf_require_prog umount + + # if we have autoloadable modules, just assume the file system + atf_require_prog sysctl + # Begin FreeBSD + if true; then + if kldstat -m ${name}; then + found=yes + else + found=no + fi + else + # End FreeBSD + autoload=$(sysctl -n kern.module.autoload) + [ "${autoload}" = "1" ] && return 0 + + set -- $(sysctl -n vfs.generic.fstypes) + found=no + while [ ${#} -gt 1 ]; do + if [ ${1} = ${name} ]; then + found=yes + break + fi + shift + done + # Begin FreeBSD + fi + # End FreeBSD + [ ${found} = yes ] || \ + atf_skip "The kernel does not include support the " \ + "\`${name}' file system" +} diff --git a/contrib/netbsd-tests/fs/hfs/colon.hfs.bz2.uue b/contrib/netbsd-tests/fs/hfs/colon.hfs.bz2.uue new file mode 100644 index 0000000..9240e7b --- /dev/null +++ b/contrib/netbsd-tests/fs/hfs/colon.hfs.bz2.uue @@ -0,0 +1,35 @@ +begin 644 colon.hfs.bz2 +M0EIH.3%!629363%?)5P``$+____[_UOQ>_]__^_O\+____1K30045,CBA$'P +M'DA:2!KIT`3V\VRA*B& +M`$,"8C$P$T9!HR:81B,":`D20A3T:GI`9``#(>H-`:-```:````````````` +M08!#1B:`R:83)ID`&$:-,`F`)A!H9`Q,@#``"8F3`3`30%241HC(4_4GJ>U- +M1Y31IM)ID`]3(T>H`#0#0T`:!H!A&@!H`````*9A\>L.>@+P;@Y:4C2%YM29 +M)Z`H>8SU&'"0U30JHOQ^.'A/7!GQK%#A5RVH"2$4VDL&T@ +M65#T*A/GU+(_VI$+*$`TJ"4J1(B1S&-YV+\J^"\Z6EK+@TU[0OQJ+;*HW.MN +M=HTL,CQHCE$C3#EW'>#8!IGYY[*)]U$!0W6L;#U:*4X6IT<@^*5!16E)%(:* +MA["$B&JX1022R8T4#20D@+ZHA_2_9$72HDSJ-FJ"7Z15%U2`@<>BJGD5'+*A +M@M6>?K^MS^LOC8I)EI6[`O3`#CCKU:M6F6A00-$/:LH+!E7(G33<))OZ27I4`@;= +M4C<-$,N=UX98G_0DK)BTS-^)R+8NZ,B3JU:@85&-MM@FCNQW/?= +M'ZL4BR[\&3S\>.K"S#1Z&>2I>^+16EM54PV3%K7M$"E`.N2"E*,8-@V.E<3$ +M,K\RU$&5E//5.'K6A+44]9=\"WF$J@Q1!43!WLA!?"XLR2GOU6G-,W]92)1` +MC@M4A4'FVAA`Q&&_%1B@L_`Z;T`0>[W6SCI%W&=H%Y>2"#E>IN[R3+(:S +MLMC<>N$1&APB(&6_#U<"!5*#IDA;MLNX`J(:/B8I,UNWB3CDPU2.@"(ORCKK +MK(1*"RZ+9V>$I2"PLER`U4BFIY'VTJ#\NYN2-9DRCIP1([QBLNKT:%1K"-P5 +MY)2NL9KM8=ACP>MLBS&J(00HA*QYRUL:'A%8F5]&22@@@D,;3[C,4.9$P)DK +M>\N+DK'4TLDI*LD&>8DEV@DT9B\,_CR;`,Y-E8*MM?Z*?BPU`I[I5^G-B$$A. +M\7&8DC*:*',@VKX0HL8O)DL<-9GG!8>NK.2XS2I.;Z3%Q9OIL8?(6-*DEGHW +MX^&A?%APXI:C@,A/&<6=)7#$UI;1Y6A'C<#/EW-*T(8WC9=`B`%\)M5HIS[\ +MV1%+H,,()X19<,:)U:Y?V\-T!^]'A\%%%+Z6.PQ"QI$]3#11IRB<#.9-L)^! +MB-WJYVQVMP^;7V*W5MG' +MKUWYE^[,*T:U)Y]NUI,00H%8>74G/?LJ0K)51^BXZ+AI*2O[PI`V*%Q@X\YV +M!V?D08"^;*TYO4R)T6G5:M;_M5M*;H4V)1IKCL$01$`#1R%N5,'_B[DBG"A( +%&*^2K@"^ +` +end diff --git a/contrib/netbsd-tests/fs/hfs/t_pathconvert.c b/contrib/netbsd-tests/fs/hfs/t_pathconvert.c new file mode 100644 index 0000000..056726a --- /dev/null +++ b/contrib/netbsd-tests/fs/hfs/t_pathconvert.c @@ -0,0 +1,83 @@ +/* $NetBSD: t_pathconvert.c,v 1.6 2017/01/13 21:30:40 christos Exp $ */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(colonslash); +ATF_TC_HEAD(colonslash, tc) +{ + atf_tc_set_md_var(tc, "descr", "HFS+ colons/slashes (PR kern/44523)"); + atf_tc_set_md_var(tc, "timeout", "20"); +} + +#define IMGNAME "colon.hfs" +#define FAKEBLK "/dev/blk" +#define FUNNY_FILENAME "foo:bar" +ATF_TC_BODY(colonslash, tc) +{ + struct hfs_args args; + int dirfd, fd; + char thecmd[1024]; + char buf[DIRBLKSIZ]; + struct dirent *dirent; + int offset, nbytes; + bool ok = false; + + snprintf(thecmd, sizeof(thecmd), "uudecode %s/colon.hfs.bz2.uue", + atf_tc_get_config_var(tc, "srcdir")); + RZ(system(thecmd)); + + snprintf(thecmd, sizeof(thecmd), "bunzip2 " IMGNAME ".bz2"); + RZ(system(thecmd)); + + memset(&args, 0, sizeof args); + args.fspec = __UNCONST(FAKEBLK); + RZ(rump_init()); + + RL(rump_sys_mkdir("/mp", 0777)); + RZ(rump_pub_etfs_register(FAKEBLK, IMGNAME, RUMP_ETFS_BLK)); + RL(rump_sys_mount(MOUNT_HFS, "/mp", 0, &args, sizeof args)); + + RL(dirfd = rump_sys_open("/mp", O_RDONLY)); + + RL(nbytes = rump_sys_getdents(dirfd, buf, sizeof buf)); + + for (offset = 0; offset < nbytes; offset += dirent->d_reclen) { + dirent = (struct dirent *)(buf + offset); + if (strchr(dirent->d_name, '/')) + atf_tc_fail("dirent with slash: %s", dirent->d_name); + if (0 == strcmp(FUNNY_FILENAME, dirent->d_name)) + ok = true; + } + + if (!ok) + atf_tc_fail("no dirent for file: %s", FUNNY_FILENAME); + + RL(rump_sys_close(dirfd)); + RL(fd = rump_sys_open("/mp/" FUNNY_FILENAME, O_RDONLY)); + RL(rump_sys_close(fd)); + RL(rump_sys_unmount("/mp", 0)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, colonslash); + return 0; +} diff --git a/contrib/netbsd-tests/fs/kernfs/t_basic.c b/contrib/netbsd-tests/fs/kernfs/t_basic.c new file mode 100644 index 0000000..77acd11 --- /dev/null +++ b/contrib/netbsd-tests/fs/kernfs/t_basic.c @@ -0,0 +1,133 @@ +/* $NetBSD: t_basic.c,v 1.4 2017/01/13 21:30:40 christos Exp $ */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(getdents); +ATF_TC_HEAD(getdents, tc) +{ + + atf_tc_set_md_var(tc, "descr", "kernfs directory contains files"); +} + +static void +mountkernfs(void) +{ + + rump_init(); + + if (rump_sys_mkdir("/kern", 0777) == -1) + atf_tc_fail_errno("mkdir /kern"); + if (rump_sys_mount(MOUNT_KERNFS, "/kern", 0, NULL, 0) == -1) + atf_tc_fail_errno("could not mount kernfs"); +} + +ATF_TC_BODY(getdents, tc) +{ + struct dirent *dent; + char buf[8192]; + int dfd; + + mountkernfs(); + + if ((dfd = rump_sys_open("/kern", O_RDONLY)) == -1) + atf_tc_fail_errno("can't open directory"); + if (rump_sys_getdents(dfd, buf, sizeof(buf)) == -1) + atf_tc_fail_errno("getdents"); + + /* + * Check that we get the first three values (., .., boottime). + * Make more complete by autogenerating list from kernfs_vnops.c? + */ + dent = (void *)buf; + ATF_REQUIRE_STREQ(dent->d_name, "."); + dent = _DIRENT_NEXT(dent); + ATF_REQUIRE_STREQ(dent->d_name, ".."); + dent = _DIRENT_NEXT(dent); + ATF_REQUIRE_STREQ(dent->d_name, "boottime"); + + /* done */ +} + +ATF_TC(hostname); +ATF_TC_HEAD(hostname, tc) +{ + + atf_tc_set_md_var(tc, "descr", "/kern/hostname changes hostname"); +} + +static char * +getthehost(void) +{ + static char buf[8192]; + int mib[2]; + size_t blen; + + mib[0] = CTL_KERN; + mib[1] = KERN_HOSTNAME; + blen = sizeof(buf); + if (rump_sys___sysctl(mib, 2, buf, &blen, NULL, 0) == -1) + atf_tc_fail_errno("sysctl gethostname"); + + return buf; +} + +#define NEWHOSTNAME "turboton roos-berg" +ATF_TC_BODY(hostname, tc) +{ + char buf[8192]; + char *shost, *p; + int fd; + + mountkernfs(); + if ((fd = rump_sys_open("/kern/hostname", O_RDWR)) == -1) + atf_tc_fail_errno("open hostname"); + + /* check initial match */ + shost = getthehost(); + buf[0] = '\0'; + if (rump_sys_read(fd, buf, sizeof(buf)) == -1) + atf_tc_fail_errno("read hostname"); + p = strchr(buf, '\n'); + if (p) + *p = '\0'; + ATF_REQUIRE_STREQ_MSG(buf, shost, "initial hostname mismatch"); + + /* check changing hostname works */ + if (rump_sys_pwrite(fd, NEWHOSTNAME, strlen(NEWHOSTNAME), 0) + != strlen(NEWHOSTNAME)) { + atf_tc_fail_errno("write new hostname"); + } + + shost = getthehost(); + ATF_REQUIRE_STREQ_MSG(NEWHOSTNAME, shost, "modified hostname mismatch"); + + /* done */ +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, hostname); + ATF_TP_ADD_TC(tp, getdents); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/lfs/t_pr.c b/contrib/netbsd-tests/fs/lfs/t_pr.c new file mode 100644 index 0000000..ed676d8 --- /dev/null +++ b/contrib/netbsd-tests/fs/lfs/t_pr.c @@ -0,0 +1,60 @@ +/* $NetBSD: t_pr.c,v 1.7 2017/01/13 21:30:40 christos Exp $ */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(mknod); +ATF_TC_HEAD(mknod, tc) +{ + + atf_tc_set_md_var(tc, "descr", "mknod(2) hangs on LFS (PR kern/43503)"); + atf_tc_set_md_var(tc, "timeout", "20"); +} + +#define IMGNAME "disk.img" +#define FAKEBLK "/dev/blk" +ATF_TC_BODY(mknod, tc) +{ + struct ufs_args args; + + /* hmm, maybe i should fix newfs_lfs instead? */ + if (system("newfs_lfs -D -F -s 10000 ./" IMGNAME) == -1) + atf_tc_fail_errno("newfs failed"); + + memset(&args, 0, sizeof(args)); + args.fspec = __UNCONST(FAKEBLK); + + rump_init(); + if (rump_sys_mkdir("/mp", 0777) == -1) + atf_tc_fail_errno("cannot create mountpoint"); + rump_pub_etfs_register(FAKEBLK, IMGNAME, RUMP_ETFS_BLK); + if (rump_sys_mount(MOUNT_LFS, "/mp", 0, &args, sizeof(args)) == -1) + atf_tc_fail_errno("rump_sys_mount failed"); + + //atf_tc_expect_timeout("PR kern/43503"); + if (rump_sys_mknod("/mp/node", S_IFCHR | 0777, 0) == -1) + atf_tc_fail_errno("mknod failed"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mknod); + return 0; +} diff --git a/contrib/netbsd-tests/fs/msdosfs/t_snapshot.c b/contrib/netbsd-tests/fs/msdosfs/t_snapshot.c new file mode 100644 index 0000000..449e625 --- /dev/null +++ b/contrib/netbsd-tests/fs/msdosfs/t_snapshot.c @@ -0,0 +1,51 @@ +/* $NetBSD: t_snapshot.c,v 1.4 2017/01/13 21:30:40 christos Exp $ */ + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "h_macros.h" + +#define IMGNAME "msdosfs.img" +#define NEWFS "newfs_msdos -C 5M " IMGNAME +#define FSCK "fsck_msdos -fn" +#define BAKNAME "/stor/snap" + +static void +mount_diskfs(const char *fspec, const char *path) +{ + struct msdosfs_args margs; + + memset(&margs, 0, sizeof(margs)); + margs.fspec = __UNCONST(fspec); + margs.version = MSDOSFSMNT_VERSION; + + if (rump_sys_mount(MOUNT_MSDOS, path, 0, &margs, sizeof(margs)) == -1) + err(1, "mount msdosfs %s", path); +} + +static void +begin(void) +{ + struct tmpfs_args targs = { .ta_version = TMPFS_ARGS_VERSION, }; + + if (rump_sys_mkdir("/stor", 0777) == -1) + atf_tc_fail_errno("mkdir /stor"); + if (rump_sys_mount(MOUNT_TMPFS, "/stor", 0, &targs,sizeof(targs)) == -1) + atf_tc_fail_errno("mount storage"); +} + +#include "../common/snapshot.c" diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/README b/contrib/netbsd-tests/fs/nfs/nfsservice/README new file mode 100644 index 0000000..8cfa8af --- /dev/null +++ b/contrib/netbsd-tests/fs/nfs/nfsservice/README @@ -0,0 +1,16 @@ + $NetBSD: README,v 1.1 2010/07/26 15:53:00 pooka Exp $ + +This directory contains the necessary bits to get an NFS server +running in a rump kernel. In essence, it's: + + * rpcbind + * mountd + * nfsd + +Additionally, you need the libc rpc code which is in +tests/fs/common/nfsrpc. + +TODO: make the standard nfs userspace services usable (the challenge +comes from rpc being in libc). + +questions? ==> pooka@netbsd.org diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/exports b/contrib/netbsd-tests/fs/nfs/nfsservice/exports new file mode 100644 index 0000000..6cc8c5f --- /dev/null +++ b/contrib/netbsd-tests/fs/nfs/nfsservice/exports @@ -0,0 +1,12 @@ +# $NetBSD: exports,v 1.2 2010/12/31 18:11:27 pooka Exp $ +# + +# +# The export dir is currently hardcoded and is exposed to the +# world, where "world" in this case means inside the rump shmif +# IP network, i.e. not a very big world. Probably needs some +# adjustments if we want to test NFS features more carefully, +# but this is enough for the current VFS level tests. +# +/myexport -noresvport -noresvmnt -maproot=0:0 10.3.2.2 +/myexport -ro -noresvport -noresvmnt -maproot=0:0 10.4.2.2 diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/getmntinfo.c b/contrib/netbsd-tests/fs/nfs/nfsservice/getmntinfo.c new file mode 100644 index 0000000..0c0587a --- /dev/null +++ b/contrib/netbsd-tests/fs/nfs/nfsservice/getmntinfo.c @@ -0,0 +1,85 @@ +/* $NetBSD: getmntinfo.c,v 1.1 2010/07/26 15:53:00 pooka 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 +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)getmntinfo.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: getmntinfo.c,v 1.1 2010/07/26 15:53:00 pooka Exp $"); +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#define getvfsstat(a,b,c) rump_sys_getvfsstat(a,b,c) + +/* + * Return information about mounted filesystems. + */ +int +getmntinfo(mntbufp, flags) + struct statvfs **mntbufp; + int flags; +{ + static struct statvfs *mntbuf; + static int mntsize; + static size_t bufsize; + + _DIAGASSERT(mntbufp != NULL); + + if (mntsize <= 0 && + (mntsize = getvfsstat(NULL, (size_t)0, MNT_NOWAIT)) == -1) + return (0); + if (bufsize > 0 && + (mntsize = getvfsstat(mntbuf, bufsize, flags)) == -1) + return (0); + while (bufsize <= mntsize * sizeof(struct statvfs)) { + if (mntbuf) + free(mntbuf); + bufsize = (mntsize + 1) * sizeof(struct statvfs); + if ((mntbuf = malloc(bufsize)) == NULL) + return (0); + if ((mntsize = getvfsstat(mntbuf, bufsize, flags)) == -1) + return (0); + } + *mntbufp = mntbuf; + return (mntsize); +} diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/pathnames.h b/contrib/netbsd-tests/fs/nfs/nfsservice/pathnames.h new file mode 100644 index 0000000..3985af9 --- /dev/null +++ b/contrib/netbsd-tests/fs/nfs/nfsservice/pathnames.h @@ -0,0 +1,37 @@ +/* $NetBSD: pathnames.h,v 1.1 2010/07/26 15:53:00 pooka 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. + * + * @(#)pathnames.h 8.1 (Berkeley) 6/5/93 + */ + +#include + +#define _PATH_EXPORTS "/etc/exports" +#define _PATH_RMOUNTLIST "/var/db/mountdtab" diff --git a/contrib/netbsd-tests/fs/nfs/nfsservice/rumpnfsd.c b/contrib/netbsd-tests/fs/nfs/nfsservice/rumpnfsd.c new file mode 100644 index 0000000..5f8e152 --- /dev/null +++ b/contrib/netbsd-tests/fs/nfs/nfsservice/rumpnfsd.c @@ -0,0 +1,166 @@ +/* $NetBSD: rumpnfsd.c,v 1.9 2015/11/08 02:45:16 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void *mountd_main(void *); +void *rpcbind_main(void *); +int nfsd_main(int, char **); + +sem_t gensem; + +#include "../../../net/config/netconfig.c" +#include "../../common/h_fsmacros.h" +#include "svc_fdset.h" + +#include +#include + +int +main(int argc, char *argv[]) +{ + const char *ethername, *ethername_ro; + const char *serveraddr, *serveraddr_ro; + const char *netmask; + const char *exportpath; + const char *imagename; + char ifname[IFNAMSIZ], ifname_ro[IFNAMSIZ]; + void *fsarg; + pthread_t t; + int rv; + + /* for netcfg */ + noatf = 1; + + /* use defaults? */ + if (argc == 1) { + ethername = "etherbus"; + ethername_ro = "etherbus_ro"; + serveraddr = "10.3.2.1"; + serveraddr_ro = "10.4.2.1"; + netmask = "255.255.255.0"; + exportpath = "/myexport"; + imagename = "ffs.img"; + } else { + ethername = argv[1]; + ethername_ro = argv[2]; + serveraddr = argv[3]; + serveraddr_ro = argv[4]; + netmask = argv[5]; + exportpath = argv[6]; + imagename = argv[7]; + } + + rump_init(); + svc_fdset_init(SVC_FDSET_MT); + + rv = rump_pub_etfs_register("/etc/exports", "./exports", RUMP_ETFS_REG); + if (rv) { + errx(1, "register /etc/exports: %s", strerror(rv)); + } + + /* mini-mtree for mountd */ + static const char *const dirs[] = { "/var", "/var/run", "/var/db" }; + for (size_t i = 0; i < __arraycount(dirs); i++) + if (rump_sys_mkdir(dirs[i], 0777) == -1) + err(1, "can't mkdir `%s'", dirs[i]); + + if (ffs_fstest_newfs(NULL, &fsarg, + imagename, FSTEST_IMGSIZE, NULL) != 0) + err(1, "newfs failed"); + if (ffs_fstest_mount(NULL, fsarg, exportpath, 0) != 0) + err(1, "mount failed"); + +#if 0 + /* + * Serve from host instead of dedicated mount? + * THIS IS MORE EVIL THAN MURRAY THE DEMONIC TALKING SKULL! + */ + + if (ukfs_modload("/usr/lib/librumpfs_syspuffs.so") < 1) + errx(1, "modload"); + + mount_syspuffs_parseargs(__arraycount(pnullarg), pnullarg, + &args, &mntflags, canon_dev, canon_dir); + if ((ukfs = ukfs_mount(MOUNT_PUFFS, "/", UKFS_DEFAULTMP, MNT_RDONLY, + &args, sizeof(args))) == NULL) + err(1, "mount"); + + if (ukfs_modload("/usr/lib/librumpfs_nfsserver.so") < 1) + errx(1, "modload"); +#endif + + if (sem_init(&gensem, 1, 0) == -1) + err(1, "gensem init"); + + /* create interface */ + netcfg_rump_makeshmif(ethername, ifname); + netcfg_rump_if(ifname, serveraddr, netmask); + + netcfg_rump_makeshmif(ethername_ro, ifname_ro); + netcfg_rump_if(ifname_ro, serveraddr_ro, netmask); + + /* + * No syslogging, thanks. + * XXX: "0" does not modify the mask, so pick something + * which is unlikely to cause any logging + */ + setlogmask(0x10000000); + + if (pthread_create(&t, NULL, rpcbind_main, NULL) == -1) + err(1, "rpcbind"); + sem_wait(&gensem); + + if (pthread_create(&t, NULL, mountd_main, NULL) == -1) + err(1, "mountd"); + sem_wait(&gensem); + + rv = 0; + /* signal the other process we're almost done */ + if (write(3, &rv, 4) != 4) + errx(1, "magic write failed"); + + { + char *nfsargv[] = { __UNCONST("nfsd"), NULL }; + nfsd_main(1, nfsargv); + } + /*NOTREACHED*/ + + return 0; +} diff --git a/contrib/netbsd-tests/fs/nfs/t_mountd.c b/contrib/netbsd-tests/fs/nfs/t_mountd.c new file mode 100644 index 0000000..6272587 --- /dev/null +++ b/contrib/netbsd-tests/fs/nfs/t_mountd.c @@ -0,0 +1,121 @@ +/* $NetBSD: t_mountd.c,v 1.6 2017/01/13 21:30:40 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "h_macros.h" +#include "../common/h_fsmacros.h" + +ATF_TC(mountdhup); +ATF_TC_HEAD(mountdhup, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test for service interrupt while " + "mountd handles SIGHUP"); +} + +static volatile int quit; + +static void * +wrkwrkwrk(void *unused) +{ + int fd, fail; + + fail = 0; + + rump_sys_chdir(FSTEST_MNTNAME); + while (!quit) { + fd = rump_sys_open("file", O_RDWR | O_CREAT); + if (fd == -1) { + if (errno == EACCES) { + fail++; + break; + } + } + rump_sys_close(fd); + if (rump_sys_unlink("file") == -1) { + if (errno == EACCES) { + fail++; + break; + } + } + } + rump_sys_chdir("/"); + quit = 1; + + return fail ? wrkwrkwrk : NULL; +} + +ATF_TC_BODY(mountdhup, tc) +{ + pthread_t pt; + struct nfstestargs *nfsargs; + void *voidargs; + int attempts; + void *fail; + + FSTEST_CONSTRUCTOR(tc, nfs, voidargs); + nfsargs = voidargs; + + pthread_create(&pt, NULL, wrkwrkwrk, NULL); + for (attempts = 100; attempts && !quit; attempts--) { + usleep(100000); + kill(nfsargs->ta_childpid, SIGHUP); + } + quit = 1; + pthread_join(pt, &fail); + + FSTEST_DESTRUCTOR(tc, nfs, voidargs); + + atf_tc_expect_fail("PR kern/5844"); + if (fail) + atf_tc_fail("op failed with EACCES"); + else + atf_tc_fail("race did not trigger this time"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mountdhup); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/nfs/t_rquotad.sh b/contrib/netbsd-tests/fs/nfs/t_rquotad.sh new file mode 100755 index 0000000..dc9226c --- /dev/null +++ b/contrib/netbsd-tests/fs/nfs/t_rquotad.sh @@ -0,0 +1,142 @@ +# $NetBSD: t_rquotad.sh,v 1.5 2016/08/10 23:25:39 kre Exp $ +# +# Copyright (c) 2011 Manuel Bouyer +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +for e in le be; do + for v in 1; do + for q in "user" "group" "both"; do + test_case_root get_nfs_${e}_${v}_${q} get_nfs_quota \ + "get NFS quota with ${q} enabled" ${e} ${v} ${q} + done + done +done + +get_nfs_quota() +{ + create_ffs $* + local q=$3 + local expect + + case ${q} in + user) + expect=u + ;; + group) + expect=g + ;; + both) + expect="u g" + ;; + *) + atf_fail "wrong quota type" + ;; + esac + +#start a a nfs server + + atf_check -s exit:0 rump_server -lrumpvfs -lrumpdev -lrumpnet \ + -lrumpnet_net -lrumpnet_netinet -lrumpnet_netinet6 \ + -lrumpnet_local -lrumpnet_shmif -lrumpdev_disk -lrumpfs_ffs \ + -lrumpfs_nfs -lrumpfs_nfsserver \ + -d key=/dk,hostpath=${IMG},size=host ${RUMP_SERVER} + + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.1.1.1 + + export RUMPHIJACK_RETRYCONNECT=die + export LD_PRELOAD=/usr/lib/librumphijack.so + + atf_check -s exit:0 mkdir /rump/etc + atf_check -s exit:0 mkdir /rump/export + atf_check -s exit:0 mkdir -p /rump/var/run + atf_check -s exit:0 mkdir -p /rump/var/db + atf_check -s exit:0 touch /rump/var/db/mountdtab + + /bin/echo "/export -noresvport -noresvmnt 10.1.1.100" | \ + dd of=/rump/etc/exports 2> /dev/null + + atf_check -s exit:0 -e ignore mount_ffs /dk /rump/export + +#set a quota limit (and check that we can read it back) + for q in ${expect} ; do + local id=$(id -${q}) + atf_check -s exit:0 \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/export edquota -$q -s10k/20 -h40M/50k \ + -t 2W/3D ${id} + atf_check -s exit:0 \ +-o "match:0 10 40960 2weeks 1 20 51200 3days" \ +-o "match:Disk quotas for .*: $" \ + env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=vfs=getvfsstat,blanket=/export quota -${q} -v + done + + # start rpcbind. we want /var/run/rpcbind.sock + export RUMPHIJACK='blanket=/var/run,socket=all' + atf_check -s exit:0 rpcbind + + # ok, then we want mountd in the similar fashion + export RUMPHIJACK='blanket=/var/run:/var/db:/export,socket=all,path=/rump,vfs=all' + atf_check -s exit:0 mountd /rump/etc/exports + + # and nfs + export RUMPHIJACK='blanket=/var/run,socket=all,vfs=all' + atf_check -s exit:0 nfsd + + #finally, rpc.rquotad + export RUMPHIJACK='blanket=/var/run:/export,vfs=getvfsstat,socket=all' + atf_check -s exit:0 /usr/libexec/rpc.rquotad + + # now start a client server + export RUMP_SERVER=unix://clientsock + RUMP_SOCKETS_LIST="${RUMP_SOCKETS_LIST} clientsock" + unset RUMPHIJACK + unset LD_PRELOAD + + atf_check -s exit:0 rump_server -lrumpvfs -lrumpnet -lrumpdev \ + -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpfs_nfs\ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.1.1.100 + + export LD_PRELOAD=/usr/lib/librumphijack.so + + atf_check -s exit:0 mkdir /rump/mnt + atf_check -s exit:0 mount_nfs 10.1.1.1:/export /rump/mnt + + #now try a quota(8) call + export RUMPHIJACK='blanket=/mnt,socket=all,path=/rump,vfs=getvfsstat' + for q in ${expect} ; do + local id=$(id -${q}) + atf_check -s exit:0 \ +-o "match:/mnt 0 10 40960 1 20 51200 " \ +-o "match:Disk quotas for .*: $" \ + quota -${q} -v + done + + unset LD_PRELOAD + rump_quota_shutdown +} diff --git a/contrib/netbsd-tests/fs/nullfs/t_basic.c b/contrib/netbsd-tests/fs/nullfs/t_basic.c new file mode 100644 index 0000000..d54f773 --- /dev/null +++ b/contrib/netbsd-tests/fs/nullfs/t_basic.c @@ -0,0 +1,174 @@ +/* $NetBSD: t_basic.c,v 1.4 2017/01/13 21:30:40 christos Exp $ */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "h_macros.h" + +ATF_TC(basic); +ATF_TC_HEAD(basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "basic nullfs functionality"); +} + +#define MSTR "magic bus" + +static void +xput_tfile(const char *path, const char *mstr) +{ + int fd; + + fd = rump_sys_open(path, O_CREAT | O_RDWR, 0777); + if (fd == -1) + atf_tc_fail_errno("create %s", path); + if (rump_sys_write(fd, MSTR, sizeof(MSTR)) != sizeof(MSTR)) + atf_tc_fail_errno("write to testfile"); + rump_sys_close(fd); +} + +static int +xread_tfile(const char *path, const char *mstr) +{ + char buf[128]; + int fd; + + fd = rump_sys_open(path, O_RDONLY); + if (fd == -1) + return errno; + if (rump_sys_read(fd, buf, sizeof(buf)) == -1) + atf_tc_fail_errno("read tfile"); + rump_sys_close(fd); + if (strcmp(buf, MSTR) == 0) + return 0; + return EPROGMISMATCH; +} + +static void +mountnull(const char *what, const char *mp, int flags) +{ + struct null_args nargs; + + memset(&nargs, 0, sizeof(nargs)); + nargs.nulla_target = __UNCONST(what); + if (rump_sys_mount(MOUNT_NULL, mp, flags, &nargs, sizeof(nargs)) == -1) + atf_tc_fail_errno("could not mount nullfs"); + +} + +ATF_TC_BODY(basic, tc) +{ + struct tmpfs_args targs; + struct stat sb; + int error; + + rump_init(); + if (rump_sys_mkdir("/td1", 0777) == -1) + atf_tc_fail_errno("mp1"); + if (rump_sys_mkdir("/td2", 0777) == -1) + atf_tc_fail_errno("mp1"); + + /* use tmpfs because rumpfs doesn't support regular files */ + memset(&targs, 0, sizeof(targs)); + targs.ta_version = TMPFS_ARGS_VERSION; + targs.ta_root_mode = 0777; + if (rump_sys_mount(MOUNT_TMPFS, "/td1", 0, &targs, sizeof(targs)) == -1) + atf_tc_fail_errno("could not mount tmpfs td1"); + + mountnull("/td1", "/td2", 0); + + /* test unnull -> null */ + xput_tfile("/td1/tensti", "jeppe"); + error = xread_tfile("/td2/tensti", "jeppe"); + if (error != 0) + atf_tc_fail("null compare failed: %d (%s)", + error, strerror(error)); + + /* test null -> unnull */ + xput_tfile("/td2/kiekko", "keppi"); + error = xread_tfile("/td1/kiekko", "keppi"); + if (error != 0) + atf_tc_fail("unnull compare failed: %d (%s)", + error, strerror(error)); + + /* test unnull -> null overwrite */ + xput_tfile("/td1/tensti", "se oolannin sota"); + error = xread_tfile("/td2/tensti", "se oolannin sota"); + if (error != 0) + atf_tc_fail("unnull compare failed: %d (%s)", + error, strerror(error)); + + /* test that /td2 is unaffected in "real life" */ + if (rump_sys_unmount("/td2", 0) == -1) + atf_tc_fail_errno("cannot unmount nullfs"); + if ((error = rump_sys_stat("/td2/tensti", &sb)) != -1 + || errno != ENOENT) { + atf_tc_fail("stat tensti should return ENOENT, got %d", error); + } + if ((error = rump_sys_stat("/td2/kiekko", &sb)) != -1 + || errno != ENOENT) { + atf_tc_fail("stat kiekko should return ENOENT, got %d", error); + } + + /* done */ +} + +ATF_TC(twistymount); +ATF_TC_HEAD(twistymount, tc) +{ + + /* this is expected to fail until the PR is fixed */ + atf_tc_set_md_var(tc, "descr", "\"recursive\" mounts deadlock" + " (kern/43439)"); +} + +/* + * Mapping to identifiers in kern/43439: + * /td = /home/current/pkgsrc + * /td/dist = /home/current/pkgsrc/distiles + * /mp = /usr/pkgsrc + * /mp/dist = /usr/pkgsrc/distfiles -- "created" by first null mount + */ + +ATF_TC_BODY(twistymount, tc) +{ + int mkd = 0; + + rump_init(); + + if (rump_sys_mkdir("/td", 0777) == -1) + atf_tc_fail_errno("mkdir %d", mkd++); + if (rump_sys_mkdir("/td/dist", 0777) == -1) + atf_tc_fail_errno("mkdir %d", mkd++); + if (rump_sys_mkdir("/mp", 0777) == -1) + atf_tc_fail_errno("mkdir %d", mkd++); + + /* MNT_RDONLY doesn't matter, but just for compat with the PR */ + mountnull("/td", "/mp", MNT_RDONLY); + mountnull("/td/dist", "/mp/dist", 0); + + /* if we didn't get a locking-against-meself panic, we passed */ +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, basic); + ATF_TP_ADD_TC(tp, twistymount); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/psshfs/h_have_puffs.c b/contrib/netbsd-tests/fs/psshfs/h_have_puffs.c new file mode 100644 index 0000000..9d34950 --- /dev/null +++ b/contrib/netbsd-tests/fs/psshfs/h_have_puffs.c @@ -0,0 +1,58 @@ +/* $NetBSD: h_have_puffs.c,v 1.1 2010/07/06 14:06:22 pooka Exp $ */ +/* + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include + +int +main(void) +{ + int exitcode, fd; + + fd = open("/dev/puffs", O_RDWR); + if (fd != -1) { + printf("yes\n"); + close(fd); + exitcode = EXIT_SUCCESS; + } else { + if (errno == ENXIO) { + printf("enxio\n"); + exitcode = EXIT_SUCCESS; + } else if (errno == EACCES) { + printf("eacces\n"); + exitcode = EXIT_SUCCESS; + } else { + printf("failed\n"); + exitcode = EXIT_FAILURE; + } + } + + return exitcode; +} diff --git a/contrib/netbsd-tests/fs/psshfs/ssh_config.in b/contrib/netbsd-tests/fs/psshfs/ssh_config.in new file mode 100644 index 0000000..3ebd68b --- /dev/null +++ b/contrib/netbsd-tests/fs/psshfs/ssh_config.in @@ -0,0 +1,14 @@ +# $NetBSD: ssh_config.in,v 1.1 2010/07/06 14:06:22 pooka Exp $ + +# Basic settings. +Port 10000 +Protocol 2 + +# The temporary key used for login. +IdentityFile @WORKDIR@/ssh_user_key + +# Prevent the client from complaining about unknown host keys. +GlobalKnownHostsFile @WORKDIR@/known_hosts + +# Do not attempt password authentication in case keys fail. +IdentitiesOnly yes diff --git a/contrib/netbsd-tests/fs/psshfs/ssh_host_key b/contrib/netbsd-tests/fs/psshfs/ssh_host_key new file mode 100644 index 0000000..ebdbc8b --- /dev/null +++ b/contrib/netbsd-tests/fs/psshfs/ssh_host_key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQDJnMpSG1lGmApk8F7ZH7TGtjjP/WUs+vqHyFsyS2lilJzereen +a/ME6S0d0HTOeCdKldjbtDpfNXbh+XnJMlJMEgEs4Mg1jluuEV0GOJoMt7cGzku2 +gAYGx++2+wqYw6Y+M8Tb1M4AO+PcxD/3BkdUyIKO63v6STl2VQn1BzsTQwIBIwKB +gAuFTWPHDGpvFols0jhK9GMgWwSSIwnidLdNRwowMehgQ3pwVmFWoCwqlN0h2sn4 +PMJu9nL0WxtiJAzprzARgQuPI25t9LiKTF7scC/cNUiHPplUjvoDXA9ccY1eIf4R +e6wwZz1jfCWen0eRsvMyoYvFmEH8hILAk1bY9heymOGLAkEA/WhC49n+gtloVMow +iKQOO6+u3ouxTOTQ3sV2wCaLaO2pEbHP2//5SlUJLp6QrjC7bg9Kr+f56+zT2he9 +f6GCwwJBAMus3XizmZdJyJLnkCJRiT0/3Kf57fhWKRdnFkuRLyjET9MEWavRdJmr +bx/lxmILi1iKwXiFEDM6MqYfmNImJYECQQCtw9YYlXtSaTGZOi/oqwJyEhGCqO6b +II85q/moVPHhjQY4BOZNttbT4on0FPV+wlSjPa+OkHDcSp/mAaaDZ2+bAkEAujel +6rLVkaKLfv+ZuPoXE22WivMityo0Mqdk12ArHfVQS+a4YpOdzlOYzLTSosi56o19 +sAShGOTAl+Jf1hQ/iwJAKpPviX5w292H/m5T0m4l0NRdQ3pRujOLMSVmY+/HFZTW +GJMYLr1eBKNfLsKzJgB88GzuF2O/O8hNi3XSiOP+9w== +-----END RSA PRIVATE KEY----- diff --git a/contrib/netbsd-tests/fs/psshfs/ssh_host_key.pub b/contrib/netbsd-tests/fs/psshfs/ssh_host_key.pub new file mode 100644 index 0000000..8d08795 --- /dev/null +++ b/contrib/netbsd-tests/fs/psshfs/ssh_host_key.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAyZzKUhtZRpgKZPBe2R+0xrY4z/1lLPr6h8hbMktpYpSc3q3np2vzBOktHdB0zngnSpXY27Q6XzV24fl5yTJSTBIBLODINY5brhFdBjiaDLe3Bs5LtoAGBsfvtvsKmMOmPjPE29TOADvj3MQ/9wZHVMiCjut7+kk5dlUJ9Qc7E0M= test@test.example.net diff --git a/contrib/netbsd-tests/fs/psshfs/sshd_config.in b/contrib/netbsd-tests/fs/psshfs/sshd_config.in new file mode 100644 index 0000000..a7f86b1 --- /dev/null +++ b/contrib/netbsd-tests/fs/psshfs/sshd_config.in @@ -0,0 +1,40 @@ +# $NetBSD: sshd_config.in,v 1.2 2011/02/11 13:19:46 pooka Exp $ + +# Basic settings. +Port 10000 +Protocol 2 + +# Provide information to the user in case something goes wrong. +LogLevel DEBUG1 + +# The host key. It lives in the work directory because we need to set +# very strict permissions on it and cannot modify the copy on the source +# directory. +HostKey @WORKDIR@/ssh_host_key + +# The authorized keys file we set up during the test to allow the client +# to safely log in. We need to disable strict modes because ATF_WORKDIR +# usually lives in /tmp, which has 1777 permissions and are not liked by +# sshd. +AuthorizedKeysFile @WORKDIR@/authorized_keys +StrictModes no + +# Some settings to allow user runs of sshd. +PidFile @WORKDIR@/sshd.pid +Subsystem sftp @WORKDIR@/sftp-server +UsePam no +UsePrivilegeSeparation no + +# The root user should also be able to run the tests. +PermitRootLogin yes + +# Be restrictive about access to the temporary server. Only allow key-based +# authentication. +ChallengeResponseAuthentication no +GSSAPIAuthentication no +HostbasedAuthentication no +KerberosAuthentication no +MaxAuthTries 1 +MaxStartups 1 +PasswordAuthentication no +PubkeyAuthentication yes diff --git a/contrib/netbsd-tests/fs/psshfs/t_psshfs.sh b/contrib/netbsd-tests/fs/psshfs/t_psshfs.sh new file mode 100755 index 0000000..4d8fede --- /dev/null +++ b/contrib/netbsd-tests/fs/psshfs/t_psshfs.sh @@ -0,0 +1,295 @@ +# $NetBSD: t_psshfs.sh,v 1.8 2016/09/05 08:53:57 christos Exp $ +# +# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# ------------------------------------------------------------------------- +# Auxiliary functions. +# ------------------------------------------------------------------------- + +# +# Skips the calling test case if puffs is not supported in the kernel +# or if the calling user does not have the necessary permissions to mount +# file systems. +# +require_puffs() { + case "$($(atf_get_srcdir)/h_have_puffs)" in + eacces) + atf_skip "Cannot open /dev/puffs for read/write access" + ;; + enxio) + atf_skip "puffs support not built into the kernel" + ;; + failed) + atf_skip "Unknown error trying to access /dev/puffs" + ;; + yes) + ;; + *) + atf_fail "Unknown value returned by h_have_puffs" + ;; + esac + + if [ $(id -u) -ne 0 -a $(sysctl -n vfs.generic.usermount) -eq 0 ] + then + atf_skip "Regular users cannot mount file systems" \ + "(vfs.generic.usermount is set to 0)" + fi +} + +# +# Starts a SSH server and sets up the client to access it. +# Authentication is allowed and done using an RSA key exclusively, which +# is generated on the fly as part of the test case. +# XXX: Ideally, all the tests in this test program should be able to share +# the generated key, because creating it can be a very slow process on some +# machines. +# +start_ssh() { + echo "Setting up SSH server configuration" + sed -e "s,@SRCDIR@,$(atf_get_srcdir),g" -e "s,@WORKDIR@,$(pwd),g" \ + $(atf_get_srcdir)/sshd_config.in >sshd_config || \ + atf_fail "Failed to create sshd_config" + atf_check -s eq:0 -o empty -e empty cp /usr/libexec/sftp-server . + atf_check -s eq:0 -o empty -e empty \ + cp $(atf_get_srcdir)/ssh_host_key . + atf_check -s eq:0 -o empty -e empty \ + cp $(atf_get_srcdir)/ssh_host_key.pub . + atf_check -s eq:0 -o empty -e empty chmod 400 ssh_host_key + atf_check -s eq:0 -o empty -e empty chmod 444 ssh_host_key.pub + + /usr/sbin/sshd -e -f ./sshd_config >sshd.log 2>&1 & + while [ ! -f sshd.pid ]; do + sleep 0.01 + done + echo "SSH server started (pid $(cat sshd.pid))" + + echo "Setting up SSH client configuration" + atf_check -s eq:0 -o empty -e empty \ + ssh-keygen -f ssh_user_key -t rsa -b 1024 -N "" -q + atf_check -s eq:0 -o empty -e empty \ + cp ssh_user_key.pub authorized_keys + echo "[localhost]:10000,[127.0.0.1]:10000,[::1]:10000" \ + "$(cat $(atf_get_srcdir)/ssh_host_key.pub)" >known_hosts || \ + atf_fail "Failed to create known_hosts" + atf_check -s eq:0 -o empty -e empty chmod 600 authorized_keys + sed -e "s,@SRCDIR@,$(atf_get_srcdir),g" -e "s,@WORKDIR@,$(pwd),g" \ + $(atf_get_srcdir)/ssh_config.in >ssh_config || \ + atf_fail "Failed to create ssh_config" +} + +# +# Stops the SSH server spawned by start_ssh and prints diagnosis data. +# +stop_ssh() { + if [ -f sshd.pid ]; then + echo "Stopping SSH server (pid $(cat sshd.pid))" + kill $(cat sshd.pid) + fi + if [ -f sshd.log ]; then + echo "Server output was:" + sed -e 's,^, ,' sshd.log + fi +} + +# +# Mounts the given source directory on the target directory using psshfs. +# Both directories are supposed to live on the current directory. +# +mount_psshfs() { + atf_check -s eq:0 -o empty -e empty \ + mount -t psshfs -o -F=$(pwd)/ssh_config localhost:$(pwd)/${1} ${2} +} + +# ------------------------------------------------------------------------- +# The test cases. +# ------------------------------------------------------------------------- + +atf_test_case inode_nos cleanup +inode_nos_head() { + atf_set "descr" "Checks that different files get different inode" \ + "numbers" +} +inode_nos_body() { + require_puffs + + start_ssh + + mkdir root + mkdir root/dir + touch root/dir/file1 + touch root/dir/file2 + touch root/file3 + touch root/file4 + + cat >ne_inodes.sh </dev/null && /bin/pwd' +} +pwd_cleanup() { + umount mnt + stop_ssh +} + +atf_test_case ls cleanup +ls_head() { + atf_set "descr" "Uses ls, attempts to exercise puffs_cc" +} +ls_body() { + require_puffs + + start_ssh + + mkdir mnt + mkdir root + mkdir root/dir + touch root/dir/file1 + touch root/dir/file2 + touch root/file3 + touch root/file4 + + mount_psshfs root mnt + + ls -l mnt & + + IFS=' ' +lsout='dir +file3 +file4 + +mnt/dir: +file1 +file2 +' + atf_check -s exit:0 -o inline:"$lsout" ls -R mnt +} +ls_cleanup() { + umount mnt + stop_ssh +} + +atf_test_case setattr_cache cleanup +setattr_cache_head() { + atf_set "descr" "Checks that setattr caches" + # Don't wait for the eternity that atf usually waits. Twenty + # seconds should be good enough, except maybe on a VAX... + atf_set "timeout" 20 +} +setattr_cache_body() { + require_puffs + start_ssh + atf_check -s exit:0 mkdir root + atf_check -s exit:0 mkdir mnt + mount_psshfs root mnt + atf_check -s exit:0 -x ': > mnt/loser' + atf_check -s exit:0 -o save:stat stat mnt/loser + # Oops -- this doesn't work. We need to stop the child of the + # sshd that is handling the sftp session. + atf_check -s exit:0 kill -STOP $(cat sshd.pid) + atf_check -s exit:0 -x ': > mnt/loser' + atf_check -s exit:0 -o file:stat stat mnt/loser +} +setattr_cache_cleanup() { + umount mnt + kill -CONT $(cat sshd.pid) + stop_ssh +} + +atf_test_case read_empty_file cleanup +read_empty_file_head() { + atf_set "descr" "Checks whether an empty file can be read" + # This test is supposed to make sure psshfs does not hang + # when reading from an empty file, hence the timeout. + atf_set "timeout" 8 +} +read_empty_file_body() { + require_puffs + start_ssh + atf_check mkdir root mnt + atf_check -x ': > root/empty' + mount_psshfs root mnt + atf_check cat mnt/empty +} +read_empty_file_cleanup() { + umount mnt + stop_ssh +} + +# ------------------------------------------------------------------------- +# Initialization. +# ------------------------------------------------------------------------- + +atf_init_test_cases() { + atf_add_test_case inode_nos + atf_add_test_case pwd + atf_add_test_case ls + #atf_add_test_case setattr_cache + atf_add_test_case read_empty_file +} diff --git a/contrib/netbsd-tests/fs/ptyfs/t_nullpts.c b/contrib/netbsd-tests/fs/ptyfs/t_nullpts.c new file mode 100644 index 0000000..fcc7e47 --- /dev/null +++ b/contrib/netbsd-tests/fs/ptyfs/t_nullpts.c @@ -0,0 +1,128 @@ +/* $NetBSD: t_nullpts.c,v 1.6 2017/01/13 21:30:40 christos Exp $ */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "h_macros.h" + +static void +mountptyfs(const char *mp, int flags) +{ + struct ptyfs_args args; + + if (rump_sys_mkdir(mp, 0777) == -1) { + if (errno != EEXIST) + atf_tc_fail_errno("null create %s", mp); + } + memset(&args, 0, sizeof(args)); + args.version = PTYFS_ARGSVERSION; + args.mode = 0777; + if (rump_sys_mount(MOUNT_PTYFS, mp, flags, &args, sizeof(args)) == -1) + atf_tc_fail_errno("could not mount ptyfs"); +} + +static void +mountnull(const char *what, const char *mp, int flags) +{ + struct null_args nargs; + + if (rump_sys_mkdir(what, 0777) == -1) { + if (errno != EEXIST) + atf_tc_fail_errno("null create %s", what); + } + if (rump_sys_mkdir(mp, 0777) == -1) { + if (errno != EEXIST) + atf_tc_fail_errno("null create %s", mp); + } + memset(&nargs, 0, sizeof(nargs)); + nargs.nulla_target = __UNCONST(what); + if (rump_sys_mount(MOUNT_NULL, mp, flags, &nargs, sizeof(nargs)) == -1) + atf_tc_fail_errno("could not mount nullfs"); +} + +ATF_TC(nullrevoke); +ATF_TC_HEAD(nullrevoke, tc) +{ + atf_tc_set_md_var(tc, "descr", "null mount ptyfs and revoke"); +} + +ATF_TC_BODY(nullrevoke, tc) +{ + char path[MAXPATHLEN]; + struct ptmget ptg; + int ptm; + + rump_init(); + + /* + * mount /dev/pts + */ + mountptyfs("/dev/pts", 0); + + /* + * null mount /dev/pts to /null/dev/pts + */ + if (rump_sys_mkdir("/null", 0777) == -1) { + if (errno != EEXIST) + atf_tc_fail_errno("null create /null"); + } + if (rump_sys_mkdir("/null/dev", 0777) == -1) { + if (errno != EEXIST) + atf_tc_fail_errno("null create /null/dev"); + } + + mountnull("/dev/pts", "/null/dev/pts", 0); + + /* + * get slave/master pair. + */ + ptm = rump_sys_open("/dev/ptm", O_RDWR); + if (rump_sys_ioctl(ptm, TIOCPTMGET, &ptg) == -1) + atf_tc_fail_errno("get pty"); + + /* + * Build nullfs path to slave. + */ + strcpy(path, "/null"); + strcat(path, ptg.sn); + + /* + * Open slave tty via nullfs. + */ + if (rump_sys_open(path, O_RDWR) == -1) + atf_tc_fail_errno("slave null open"); + + /* + * Close slave opened with /dev/ptm. Need purely non-null refs to it. + */ + rump_sys_close(ptg.sfd); + + /* revoke slave tty. */ + rump_sys_revoke(path); + + /* done */ +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, nullrevoke); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/ptyfs/t_ptyfs.c b/contrib/netbsd-tests/fs/ptyfs/t_ptyfs.c new file mode 100644 index 0000000..108c344 --- /dev/null +++ b/contrib/netbsd-tests/fs/ptyfs/t_ptyfs.c @@ -0,0 +1,62 @@ +/* $NetBSD: t_ptyfs.c,v 1.2 2017/01/13 21:30:40 christos Exp $ */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "h_macros.h" + +static void +mountptyfs(const char *mp, int flags) +{ + struct ptyfs_args args; + + if (rump_sys_mkdir("/mp", 0777) == -1) { + if (errno != EEXIST) + atf_tc_fail_errno("mp1"); + } + memset(&args, 0, sizeof(args)); + args.version = PTYFS_ARGSVERSION; + args.mode = 0777; + if (rump_sys_mount(MOUNT_PTYFS, mp, flags, &args, sizeof(args)) == -1) + atf_tc_fail_errno("could not mount ptyfs"); +} + +ATF_TC(basic); +ATF_TC_HEAD(basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "mount ptyfs"); +} + +ATF_TC_BODY(basic, tc) +{ + + rump_init(); + + mountptyfs("/mp", 0); + if (rump_sys_unmount("/mp", 0) == -1) + atf_tc_fail_errno("unmount failed"); + + /* done */ +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs.c b/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs.c new file mode 100644 index 0000000..c625f90 --- /dev/null +++ b/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs.c @@ -0,0 +1,255 @@ +/* $NetBSD: dtfs.c,v 1.2 2010/07/21 06:58:25 pooka Exp $ */ + +/* + * Copyright (c) 2006 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/* + * Delectable Test File System: a simple in-memory file system which + * demonstrates the use of puffs. + * (a.k.a. Detrempe FS ...) + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dtfs.h" + +#ifdef DEEP_ROOTED_CLUE +#define FSNAME "detrempe" +#else +#define FSNAME "dt" +#endif +#define MAXREQMAGIC -37 + +static struct puffs_usermount *gpu; +static struct dtfs_mount gdtm; +int dynamicfh; +int straightflush; + +static void usage(void); + +static void +usage() +{ + + fprintf(stderr, "usage: %s [-bsdftl] [-c hashbuckets] [-m maxreqsize] " + "[-n typename]\n [-o mntopt] [-o puffsopt] [-p prot] " + "[-r rootnodetype]\n detrempe /mountpoint\n", getprogname()); + exit(1); +} + +static void +wipe_the_sleep_out_of_my_eyes(int v) +{ + + gdtm.dtm_needwakeup++; +} + +static void +loopfun(struct puffs_usermount *pu) +{ + struct dtfs_mount *dtm = puffs_getspecific(pu); + struct dtfs_poll *dp; + + while (dtm->dtm_needwakeup) { + dtm->dtm_needwakeup--; + dp = LIST_FIRST(&dtm->dtm_pollent); + if (dp == NULL) + return; + + LIST_REMOVE(dp, dp_entries); + puffs_cc_continue(dp->dp_pcc); + } +} + +int +main(int argc, char *argv[]) +{ + extern char *optarg; + extern int optind; + struct puffs_usermount *pu; + struct puffs_pathobj *po_root; + struct puffs_ops *pops; + struct timespec ts; + const char *typename; + char *rtstr; + mntoptparse_t mp; + int pflags, detach, mntflags; + int ch; + int khashbuckets; + int maxreqsize; + + setprogname(argv[0]); + + rtstr = NULL; + detach = 1; + mntflags = 0; + khashbuckets = 256; + pflags = PUFFS_KFLAG_IAONDEMAND; + typename = FSNAME; + maxreqsize = MAXREQMAGIC; + gdtm.dtm_allowprot = VM_PROT_ALL; + while ((ch = getopt(argc, argv, "bc:dfilm:n:o:p:r:st")) != -1) { + switch (ch) { + case 'b': /* build paths, for debugging the feature */ + pflags |= PUFFS_FLAG_BUILDPATH; + break; + case 'c': + khashbuckets = atoi(optarg); + break; + case 'd': + dynamicfh = 1; + break; + case 'f': + pflags |= PUFFS_KFLAG_LOOKUP_FULLPNBUF; + break; + case 'i': + pflags &= ~PUFFS_KFLAG_IAONDEMAND; + break; + case 'l': + straightflush = 1; + break; + case 'm': + maxreqsize = atoi(optarg); + break; + case 'n': + typename = optarg; + break; + case 'o': + mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags); + if (mp == NULL) + err(1, "getmntopts"); + freemntopts(mp); + break; + case 'p': + gdtm.dtm_allowprot = atoi(optarg); + if ((gdtm.dtm_allowprot | VM_PROT_ALL) != VM_PROT_ALL) + usage(); + break; + case 'r': + rtstr = optarg; + break; + case 's': /* stay on top */ + detach = 0; + break; + case 't': + pflags |= PUFFS_KFLAG_WTCACHE; + break; + default: + usage(); + /*NOTREACHED*/ + } + } + if (pflags & PUFFS_FLAG_OPDUMP) + detach = 0; + argc -= optind; + argv += optind; + + if (argc != 2) + usage(); + + PUFFSOP_INIT(pops); + + PUFFSOP_SET(pops, dtfs, fs, statvfs); + PUFFSOP_SET(pops, dtfs, fs, unmount); + PUFFSOP_SETFSNOP(pops, sync); + PUFFSOP_SET(pops, dtfs, fs, fhtonode); + PUFFSOP_SET(pops, dtfs, fs, nodetofh); + + PUFFSOP_SET(pops, dtfs, node, lookup); + PUFFSOP_SET(pops, dtfs, node, access); + PUFFSOP_SET(pops, puffs_genfs, node, getattr); + PUFFSOP_SET(pops, dtfs, node, setattr); + PUFFSOP_SET(pops, dtfs, node, create); + PUFFSOP_SET(pops, dtfs, node, remove); + PUFFSOP_SET(pops, dtfs, node, readdir); + PUFFSOP_SET(pops, dtfs, node, poll); + PUFFSOP_SET(pops, dtfs, node, mmap); + PUFFSOP_SET(pops, dtfs, node, mkdir); + PUFFSOP_SET(pops, dtfs, node, rmdir); + PUFFSOP_SET(pops, dtfs, node, rename); + PUFFSOP_SET(pops, dtfs, node, read); + PUFFSOP_SET(pops, dtfs, node, write); + PUFFSOP_SET(pops, dtfs, node, link); + PUFFSOP_SET(pops, dtfs, node, symlink); + PUFFSOP_SET(pops, dtfs, node, readlink); + PUFFSOP_SET(pops, dtfs, node, mknod); + PUFFSOP_SET(pops, dtfs, node, inactive); + PUFFSOP_SET(pops, dtfs, node, pathconf); + PUFFSOP_SET(pops, dtfs, node, reclaim); + + srandom(time(NULL)); /* for random generation numbers */ + + pu = puffs_init(pops, _PATH_PUFFS, typename, &gdtm, pflags); + if (pu == NULL) + err(1, "init"); + gpu = pu; + + puffs_setfhsize(pu, sizeof(struct dtfs_fid), + PUFFS_FHFLAG_NFSV2 | PUFFS_FHFLAG_NFSV3 + | (dynamicfh ? PUFFS_FHFLAG_DYNAMIC : 0)); + puffs_setncookiehash(pu, khashbuckets); + + if (signal(SIGALRM, wipe_the_sleep_out_of_my_eyes) == SIG_ERR) + warn("cannot set alarm sighandler"); + + /* init */ + if (dtfs_domount(pu, rtstr) != 0) + errx(1, "dtfs_domount failed"); + + po_root = puffs_getrootpathobj(pu); + po_root->po_path = argv[0]; + po_root->po_len = strlen(argv[0]); + + /* often enough for testing poll */ + ts.tv_sec = 1; + ts.tv_nsec = 0; + puffs_ml_setloopfn(pu, loopfun); + puffs_ml_settimeout(pu, &ts); + + if (maxreqsize != MAXREQMAGIC) + puffs_setmaxreqlen(pu, maxreqsize); + + puffs_set_errnotify(pu, puffs_kernerr_abort); + if (detach) + if (puffs_daemon(pu, 1, 1) == -1) + err(1, "puffs_daemon"); + + if (puffs_mount(pu, argv[1], mntflags, puffs_getroot(pu)) == -1) + err(1, "mount"); + if (puffs_mainloop(pu) == -1) + err(1, "mainloop"); + + return 0; +} diff --git a/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs.h b/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs.h new file mode 100644 index 0000000..de4d958 --- /dev/null +++ b/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs.h @@ -0,0 +1,127 @@ +/* $NetBSD: dtfs.h,v 1.2 2010/07/14 13:09:52 pooka Exp $ */ + +/* + * Copyright (c) 2006 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#ifndef DTFS_H_ +#define DTFS_H_ + +#include + +#include + +PUFFSOP_PROTOS(dtfs); +int dtfs_domount(struct puffs_usermount *, const char *); + +#define DTFS_BLOCKSHIFT (12) +#define DTFS_BLOCKSIZE (1<> (b)) + +struct dtfs_fid; +struct dtfs_mount { + ino_t dtm_nextfileid; /* running number for file id */ + + size_t dtm_fsizes; /* sum of file sizes in bytes */ + fsfilcnt_t dtm_nfiles; /* number of files */ + + LIST_HEAD(, dtfs_poll) dtm_pollent; + int dtm_needwakeup; + vm_prot_t dtm_allowprot; +}; + +struct dtfs_file { + union { + struct { + uint8_t **blocks; + size_t numblocks; + size_t datalen; + } reg; + struct { + struct puffs_node *dotdot; + LIST_HEAD(, dtfs_dirent) dirents; + } dir; + struct { + char *target; + } link; + } u; +#define df_blocks u.reg.blocks +#define df_numblocks u.reg.numblocks +#define df_datalen u.reg.datalen +#define df_dotdot u.dir.dotdot +#define df_dirents u.dir.dirents +#define df_linktarget u.link.target +}; + +struct dtfs_dirent { + struct puffs_node *dfd_node; + struct puffs_node *dfd_parent; + char *dfd_name; + size_t dfd_namelen; + + LIST_ENTRY(dtfs_dirent) dfd_entries; +}; + +struct dtfs_fid { + struct puffs_node *dfid_addr; + + /* best^Wsome-effort extra sanity check */ + ino_t dfid_fileid; + u_long dfid_gen; +}; +#define DTFS_FIDSIZE (sizeof(struct dtfs_fid)) + +struct dtfs_poll { + struct puffs_cc *dp_pcc; + LIST_ENTRY(dtfs_poll) dp_entries; +}; + +struct puffs_node * dtfs_genfile(struct puffs_node *, + const struct puffs_cn *, enum vtype); +struct dtfs_file * dtfs_newdir(void); +struct dtfs_file * dtfs_newfile(void); +struct dtfs_dirent * dtfs_dirgetnth(struct dtfs_file *, int); +struct dtfs_dirent * dtfs_dirgetbyname(struct dtfs_file *, + const char *, size_t); + +void dtfs_nukenode(struct puffs_node *, struct puffs_node *, + const char *, size_t); +void dtfs_freenode(struct puffs_node *); +void dtfs_setsize(struct puffs_node *, off_t); + +void dtfs_adddent(struct puffs_node *, struct dtfs_dirent *); +void dtfs_removedent(struct puffs_node *, struct dtfs_dirent *); + +void dtfs_baseattrs(struct vattr *, enum vtype, ino_t); +void dtfs_updatetimes(struct puffs_node *, int, int, int); + +bool dtfs_isunder(struct puffs_node *, struct puffs_node *); + + +#define DTFS_CTOF(a) ((struct dtfs_file *)(((struct puffs_node *)a)->pn_data)) +#define DTFS_PTOF(a) ((struct dtfs_file *)(a->pn_data)) + +#endif /* DTFS_H_ */ diff --git a/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs_subr.c b/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs_subr.c new file mode 100644 index 0000000..fcb8176 --- /dev/null +++ b/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs_subr.c @@ -0,0 +1,358 @@ +/* $NetBSD: dtfs_subr.c,v 1.4 2013/10/19 17:45:00 christos Exp $ */ + +/* + * Copyright (c) 2006 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dtfs.h" + +void +dtfs_baseattrs(struct vattr *vap, enum vtype type, ino_t id) +{ + struct timeval tv; + struct timespec ts; + + gettimeofday(&tv, NULL); + TIMEVAL_TO_TIMESPEC(&tv, &ts); + + vap->va_type = type; + if (type == VDIR) { + vap->va_mode = 0777; + vap->va_nlink = 1; /* n + 1 after adding dent */ + } else { + vap->va_mode = 0666; + vap->va_nlink = 0; /* n + 1 */ + } + vap->va_uid = 0; + vap->va_gid = 0; + vap->va_fileid = id; + vap->va_size = 0; + vap->va_blocksize = getpagesize(); + vap->va_gen = random(); + vap->va_flags = 0; + vap->va_rdev = PUFFS_VNOVAL; + vap->va_bytes = 0; + vap->va_filerev = 1; + vap->va_vaflags = 0; + + vap->va_atime = vap->va_mtime = vap->va_ctime = vap->va_birthtime = ts; +} + +/* + * Well, as you can probably see, this interface has the slight problem + * of assuming file creation will always be succesful, or at least not + * giving a reason for the failure. Be sure to do better when you + * implement your own fs. + */ +struct puffs_node * +dtfs_genfile(struct puffs_node *dir, const struct puffs_cn *pcn, + enum vtype type) +{ + struct dtfs_file *dff; + struct dtfs_dirent *dfd; + struct dtfs_mount *dtm; + struct puffs_node *newpn; + uid_t uid; + int rv; + + assert(dir->pn_va.va_type == VDIR); + assert(dir->pn_mnt != NULL); + + uid = 0; + rv = puffs_cred_getuid(pcn->pcn_cred, &uid); + assert(rv == 0); + + if (type == VDIR) { + dff = dtfs_newdir(); + dff->df_dotdot = dir; + } else + dff = dtfs_newfile(); + + dtm = puffs_pn_getmntspecific(dir); + newpn = puffs_pn_new(dir->pn_mnt, dff); + if (newpn == NULL) + errx(1, "getnewpnode"); + dtfs_baseattrs(&newpn->pn_va, type, dtm->dtm_nextfileid++); + + dfd = emalloc(sizeof(struct dtfs_dirent)); + dfd->dfd_node = newpn; + dfd->dfd_name = estrndup(pcn->pcn_name, pcn->pcn_namelen); + dfd->dfd_namelen = strlen(dfd->dfd_name); + dfd->dfd_parent = dir; + dtfs_adddent(dir, dfd); + + newpn->pn_va.va_uid = uid; + newpn->pn_va.va_gid = dir->pn_va.va_gid; + + return newpn; +} + +struct dtfs_file * +dtfs_newdir() +{ + struct dtfs_file *dff; + + dff = emalloc(sizeof(struct dtfs_file)); + memset(dff, 0, sizeof(struct dtfs_file)); + LIST_INIT(&dff->df_dirents); + + return dff; +} + +struct dtfs_file * +dtfs_newfile() +{ + struct dtfs_file *dff; + + dff = emalloc(sizeof(struct dtfs_file)); + memset(dff, 0, sizeof(struct dtfs_file)); + + return dff; +} + +struct dtfs_dirent * +dtfs_dirgetnth(struct dtfs_file *searchdir, int n) +{ + struct dtfs_dirent *dirent; + int i; + + i = 0; + LIST_FOREACH(dirent, &searchdir->df_dirents, dfd_entries) { + if (i == n) + return dirent; + i++; + } + + return NULL; +} + +struct dtfs_dirent * +dtfs_dirgetbyname(struct dtfs_file *searchdir, const char *fname, size_t fnlen) +{ + struct dtfs_dirent *dirent; + + LIST_FOREACH(dirent, &searchdir->df_dirents, dfd_entries) + if (dirent->dfd_namelen == fnlen + && strncmp(dirent->dfd_name, fname, fnlen) == 0) + return dirent; + + return NULL; +} + +/* + * common nuke, kill dirent from parent node + */ +void +dtfs_nukenode(struct puffs_node *nukeme, struct puffs_node *pn_parent, + const char *fname, size_t fnlen) +{ + struct dtfs_dirent *dfd; + struct dtfs_mount *dtm; + + assert(pn_parent->pn_va.va_type == VDIR); + + dfd = dtfs_dirgetbyname(DTFS_PTOF(pn_parent), fname, fnlen); + assert(dfd); + + dtm = puffs_pn_getmntspecific(nukeme); + dtm->dtm_nfiles--; + assert(dtm->dtm_nfiles >= 1); + + dtfs_removedent(pn_parent, dfd); + free(dfd); +} + +/* free lingering information */ +void +dtfs_freenode(struct puffs_node *pn) +{ + struct dtfs_file *df = DTFS_PTOF(pn); + struct dtfs_mount *dtm; + int i; + + assert(pn->pn_va.va_nlink == 0); + dtm = puffs_pn_getmntspecific(pn); + + switch (pn->pn_va.va_type) { + case VREG: + assert(dtm->dtm_fsizes >= pn->pn_va.va_size); + dtm->dtm_fsizes -= pn->pn_va.va_size; + for (i = 0; i < BLOCKNUM(df->df_datalen, DTFS_BLOCKSHIFT); i++) + free(df->df_blocks[i]); + if (df->df_datalen > i << DTFS_BLOCKSHIFT) + free(df->df_blocks[i]); + break; + case VLNK: + free(df->df_linktarget); + break; + case VCHR: + case VBLK: + case VDIR: + case VSOCK: + case VFIFO: + break; + default: + assert(0); + break; + } + + free(df); + puffs_pn_put(pn); +} + +void +dtfs_setsize(struct puffs_node *pn, off_t newsize) +{ + struct dtfs_file *df = DTFS_PTOF(pn); + struct dtfs_mount *dtm; + size_t newblocks; + int needalloc, shrinks; + int i; + + needalloc = newsize > ROUNDUP(df->df_datalen, DTFS_BLOCKSIZE); + shrinks = newsize < pn->pn_va.va_size; + + if (needalloc || shrinks) { + newblocks = BLOCKNUM(newsize, DTFS_BLOCKSHIFT) + 1; + + if (shrinks) + for (i = newblocks; i < df->df_numblocks; i++) + free(df->df_blocks[i]); + + df->df_blocks = erealloc(df->df_blocks, + newblocks * sizeof(uint8_t *)); + /* + * if extended, set storage to zero + * to match correct behaviour + */ + if (!shrinks) { + for (i = df->df_numblocks; i < newblocks; i++) { + df->df_blocks[i] = emalloc(DTFS_BLOCKSIZE); + memset(df->df_blocks[i], 0, DTFS_BLOCKSIZE); + } + } + + df->df_datalen = newsize; + df->df_numblocks = newblocks; + } + + dtm = puffs_pn_getmntspecific(pn); + if (!shrinks) { + dtm->dtm_fsizes += newsize - pn->pn_va.va_size; + } else { + dtm->dtm_fsizes -= pn->pn_va.va_size - newsize; + } + + pn->pn_va.va_size = newsize; + pn->pn_va.va_bytes = BLOCKNUM(newsize,DTFS_BLOCKSHIFT)>>DTFS_BLOCKSHIFT; +} + +/* add & bump link count */ +void +dtfs_adddent(struct puffs_node *pn_dir, struct dtfs_dirent *dent) +{ + struct dtfs_file *dir = DTFS_PTOF(pn_dir); + struct puffs_node *pn_file = dent->dfd_node; + struct dtfs_file *file = DTFS_PTOF(pn_file); + struct dtfs_mount *dtm; + + assert(pn_dir->pn_va.va_type == VDIR); + LIST_INSERT_HEAD(&dir->df_dirents, dent, dfd_entries); + pn_file->pn_va.va_nlink++; + + dtm = puffs_pn_getmntspecific(pn_file); + dtm->dtm_nfiles++; + + dent->dfd_parent = pn_dir; + if (dent->dfd_node->pn_va.va_type == VDIR) { + file->df_dotdot = pn_dir; + pn_dir->pn_va.va_nlink++; + } + + dtfs_updatetimes(pn_dir, 0, 1, 1); +} + +/* remove & lower link count */ +void +dtfs_removedent(struct puffs_node *pn_dir, struct dtfs_dirent *dent) +{ + struct puffs_node *pn_file = dent->dfd_node; + + assert(pn_dir->pn_va.va_type == VDIR); + LIST_REMOVE(dent, dfd_entries); + if (pn_file->pn_va.va_type == VDIR) { + struct dtfs_file *df = DTFS_PTOF(pn_file); + + pn_dir->pn_va.va_nlink--; + df->df_dotdot = NULL; + } + pn_file->pn_va.va_nlink--; + assert(pn_dir->pn_va.va_nlink >= 2); + + dtfs_updatetimes(pn_dir, 0, 1, 1); +} + +void +dtfs_updatetimes(struct puffs_node *pn, int doatime, int doctime, int domtime) +{ + struct timeval tv; + struct timespec ts; + + gettimeofday(&tv, NULL); + TIMEVAL_TO_TIMESPEC(&tv, &ts); + + if (doatime) + pn->pn_va.va_atime = ts; + if (doctime) + pn->pn_va.va_ctime = ts; + if (domtime) + pn->pn_va.va_mtime = ts; +} + +bool +dtfs_isunder(struct puffs_node *pn, struct puffs_node *pn_parent) +{ + struct dtfs_file *df; + + while (pn) { + if (pn == pn_parent) + return true; + df = DTFS_CTOF(pn); + pn = df->df_dotdot; + } + + return false; +} diff --git a/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs_vfsops.c b/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs_vfsops.c new file mode 100644 index 0000000..6f0c72e --- /dev/null +++ b/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs_vfsops.c @@ -0,0 +1,298 @@ +/* $NetBSD: dtfs_vfsops.c,v 1.3 2012/11/04 23:37:02 christos Exp $ */ + +/* + * Copyright (c) 2006 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dtfs.h" + +static int +rtstr(struct puffs_usermount *pu, const char *str, enum vtype vt) +{ + struct puffs_node *pn = puffs_getroot(pu); + struct vattr *va = &pn->pn_va; + struct dtfs_file *df = DTFS_PTOF(pn); + char ltarg[256+1]; + + if (sscanf(str, "%*s %256s", ltarg) != 1) + return 1; + + dtfs_baseattrs(va, vt, 2); + df->df_linktarget = estrdup(ltarg); + + va->va_nlink = 1; + va->va_size = strlen(df->df_linktarget); + + puffs_setrootinfo(pu, vt, 0, 0); + + return 0; +} + +static int +rtdev(struct puffs_usermount *pu, const char *str, enum vtype vt) +{ + struct puffs_node *pn = puffs_getroot(pu); + struct vattr *va = &pn->pn_va; + int major, minor; + + if (sscanf(str, "%*s %d %d", &major, &minor) != 2) + return 1; + + dtfs_baseattrs(va, vt, 2); + va->va_nlink = 1; + va->va_rdev = makedev(major, minor); + + if (vt == VBLK) + va->va_mode |= S_IFBLK; + else + va->va_mode |= S_IFCHR; + + puffs_setrootinfo(pu, vt, 0, va->va_rdev); + + return 0; +} + +static int +rtnorm(struct puffs_usermount *pu, const char *str, enum vtype vt) +{ + struct puffs_node *pn = puffs_getroot(pu); + struct vattr *va = &pn->pn_va; + + dtfs_baseattrs(va, vt, 2); + if (vt == VDIR) + va->va_nlink = 2; + else + va->va_nlink = 1; + + puffs_setrootinfo(pu, vt, 0, 0); + + return 0; +} + +struct rtype { + char *tstr; + enum vtype vt; + int (*pfunc)(struct puffs_usermount *, const char *, enum vtype); +} rtypes[] = { + { "reg", VREG, rtnorm }, + { "dir", VDIR, rtnorm }, + { "blk", VBLK, rtdev }, + { "chr", VCHR, rtdev }, + { "lnk", VLNK, rtstr }, + { "sock", VSOCK, rtnorm }, + { "fifo", VFIFO, rtnorm } +}; +#define NTYPES (sizeof(rtypes) / sizeof(rtypes[0])) + +int +dtfs_domount(struct puffs_usermount *pu, const char *typestr) +{ + struct dtfs_mount *dtm; + struct dtfs_file *dff; + struct puffs_node *pn; + int i; + + /* create mount-local thingie */ + dtm = puffs_getspecific(pu); + dtm->dtm_nextfileid = 3; + dtm->dtm_nfiles = 1; + dtm->dtm_fsizes = 0; + LIST_INIT(&dtm->dtm_pollent); + + /* + * create root directory, do it "by hand" to avoid special-casing + * dtfs_genfile() + */ + dff = dtfs_newdir(); + dff->df_dotdot = NULL; + pn = puffs_pn_new(pu, dff); + if (!pn) + errx(1, "puffs_newpnode"); + puffs_setroot(pu, pn); + + if (!typestr) { + rtnorm(pu, NULL, VDIR); + } else { + for (i = 0; i < NTYPES; i++) { + if (strncmp(rtypes[i].tstr, typestr, + strlen(rtypes[i].tstr)) == 0) { + if (rtypes[i].pfunc(pu, typestr, + rtypes[i].vt) != 0) { + fprintf(stderr, "failed to parse " + "\"%s\"\n", typestr); + return 1; + } + break; + } + } + if (i == NTYPES) { + fprintf(stderr, "no maching type for %s\n", typestr); + return 1; + } + } + + return 0; +} + +/* + * statvfs() should fill in the following members of struct statvfs: + * + * unsigned long f_bsize; file system block size + * unsigned long f_frsize; fundamental file system block size + * unsigned long f_iosize; optimal file system block size + * fsblkcnt_t f_blocks; number of blocks in file system, + * (in units of f_frsize) + * + * fsblkcnt_t f_bfree; free blocks avail in file system + * fsblkcnt_t f_bavail; free blocks avail to non-root + * fsblkcnt_t f_bresvd; blocks reserved for root + * + * fsfilcnt_t f_files; total file nodes in file system + * fsfilcnt_t f_ffree; free file nodes in file system + * fsfilcnt_t f_favail; free file nodes avail to non-root + * fsfilcnt_t f_fresvd; file nodes reserved for root + * + * + * The rest are filled in by the kernel. + */ +#define ROUND(a,b) (((a) + ((b)-1)) & ~((b)-1)) +#define NFILES 1024*1024 +int +dtfs_fs_statvfs(struct puffs_usermount *pu, struct statvfs *sbp) +{ + struct rlimit rlim; + struct dtfs_mount *dtm; + off_t btot, bfree; + int pgsize; + + dtm = puffs_getspecific(pu); + pgsize = getpagesize(); + memset(sbp, 0, sizeof(struct statvfs)); + + /* + * Use datasize rlimit as an _approximation_ for free size. + * This, of course, is not accurate due to overhead and not + * accounting for metadata. + */ + if (getrlimit(RLIMIT_DATA, &rlim) == 0) + btot = rlim.rlim_cur; + else + btot = 16*1024*1024; + bfree = btot - dtm->dtm_fsizes; + + sbp->f_blocks = ROUND(btot, pgsize) / pgsize; + sbp->f_files = NFILES; + + sbp->f_bsize = sbp->f_frsize = sbp->f_iosize = pgsize; + sbp->f_bfree = sbp->f_bavail = ROUND(bfree, pgsize) / pgsize; + sbp->f_ffree = sbp->f_favail = NFILES - dtm->dtm_nfiles; + + sbp->f_bresvd = sbp->f_fresvd = 0; + + return 0; +} +#undef ROUND + +static void * +addrcmp(struct puffs_usermount *pu, struct puffs_node *pn, void *arg) +{ + + if (pn == arg) + return pn; + + return NULL; +} + +int +dtfs_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize, + struct puffs_newinfo *pni) +{ + struct dtfs_fid *dfid; + struct puffs_node *pn; + + assert(fidsize == sizeof(struct dtfs_fid)); + dfid = fid; + + pn = puffs_pn_nodewalk(pu, addrcmp, dfid->dfid_addr); + if (pn == NULL) + return ESTALE; + + if (pn->pn_va.va_fileid != dfid->dfid_fileid + || pn->pn_va.va_gen != dfid->dfid_gen) + return ESTALE; + + puffs_newinfo_setcookie(pni, pn); + puffs_newinfo_setvtype(pni, pn->pn_va.va_type); + puffs_newinfo_setsize(pni, pn->pn_va.va_size); + puffs_newinfo_setrdev(pni, pn->pn_va.va_rdev); + + return 0; +} + +int +dtfs_fs_nodetofh(struct puffs_usermount *pu, void *cookie, + void *fid, size_t *fidsize) +{ + struct puffs_node *pn = cookie; + struct dtfs_fid *dfid; + extern int dynamicfh; + + if (dynamicfh == 0) { + assert(*fidsize >= sizeof(struct dtfs_fid)); + } else { + if (*fidsize < sizeof(struct dtfs_fid)) { + *fidsize = sizeof(struct dtfs_fid); + return E2BIG; + } + *fidsize = sizeof(struct dtfs_fid); + } + + dfid = fid; + + dfid->dfid_addr = pn; + dfid->dfid_fileid = pn->pn_va.va_fileid; + dfid->dfid_gen = pn->pn_va.va_gen; + + return 0; +} + +int +dtfs_fs_unmount(struct puffs_usermount *pu, int flags) +{ + + return 0; +} diff --git a/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs_vnops.c b/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs_vnops.c new file mode 100644 index 0000000..875109c --- /dev/null +++ b/contrib/netbsd-tests/fs/puffs/h_dtfs/dtfs_vnops.c @@ -0,0 +1,586 @@ +/* $NetBSD: dtfs_vnops.c,v 1.10 2013/10/19 17:45:00 christos Exp $ */ + +/* + * Copyright (c) 2006 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dtfs.h" + +int +dtfs_node_lookup(struct puffs_usermount *pu, void *opc, + struct puffs_newinfo *pni, const struct puffs_cn *pcn) +{ + struct puffs_node *pn_dir = opc; + struct dtfs_file *df = DTFS_CTOF(opc); + struct dtfs_dirent *dfd; + extern int straightflush; + int rv; + + /* parent dir? */ + if (PCNISDOTDOT(pcn)) { + if (df->df_dotdot == NULL) + return ENOENT; + + assert(df->df_dotdot->pn_va.va_type == VDIR); + puffs_newinfo_setcookie(pni, df->df_dotdot); + puffs_newinfo_setvtype(pni, df->df_dotdot->pn_va.va_type); + + return 0; + } + + dfd = dtfs_dirgetbyname(df, pcn->pcn_name, pcn->pcn_namelen); + if (dfd) { + if ((pcn->pcn_flags & NAMEI_ISLASTCN) && + (pcn->pcn_nameiop == NAMEI_DELETE)) { + rv = puffs_access(VDIR, pn_dir->pn_va.va_mode, + pn_dir->pn_va.va_uid, pn_dir->pn_va.va_gid, + PUFFS_VWRITE, pcn->pcn_cred); + if (rv) + return rv; + } + puffs_newinfo_setcookie(pni, dfd->dfd_node); + puffs_newinfo_setvtype(pni, dfd->dfd_node->pn_va.va_type); + puffs_newinfo_setsize(pni, dfd->dfd_node->pn_va.va_size); + puffs_newinfo_setrdev(pni, dfd->dfd_node->pn_va.va_rdev); + + if (straightflush) + puffs_flush_pagecache_node(pu, dfd->dfd_node); + + return 0; + } + + if ((pcn->pcn_flags & NAMEI_ISLASTCN) + && (pcn->pcn_nameiop == NAMEI_CREATE || + pcn->pcn_nameiop == NAMEI_RENAME)) { + rv = puffs_access(VDIR, pn_dir->pn_va.va_mode, + pn_dir->pn_va.va_uid, pn_dir->pn_va.va_gid, + PUFFS_VWRITE, pcn->pcn_cred); + if (rv) + return rv; + } + + return ENOENT; +} + +int +dtfs_node_access(struct puffs_usermount *pu, void *opc, int acc_mode, + const struct puffs_cred *pcr) +{ + struct puffs_node *pn = opc; + + return puffs_access(pn->pn_va.va_type, pn->pn_va.va_mode, + pn->pn_va.va_uid, pn->pn_va.va_gid, acc_mode, pcr); +} + +int +dtfs_node_setattr(struct puffs_usermount *pu, void *opc, + const struct vattr *va, const struct puffs_cred *pcr) +{ + struct puffs_node *pn = opc; + int rv; + + /* check permissions */ + if (va->va_flags != PUFFS_VNOVAL) + return EOPNOTSUPP; + + if (va->va_uid != PUFFS_VNOVAL || va->va_gid != PUFFS_VNOVAL) { + rv = puffs_access_chown(pn->pn_va.va_uid, pn->pn_va.va_gid, + va->va_uid, va->va_gid, pcr); + if (rv) + return rv; + } + + if (va->va_mode != PUFFS_VNOVAL) { + rv = puffs_access_chmod(pn->pn_va.va_uid, pn->pn_va.va_gid, + pn->pn_va.va_type, va->va_mode, pcr); + if (rv) + return rv; + } + + if ((va->va_atime.tv_sec != PUFFS_VNOVAL + && va->va_atime.tv_nsec != PUFFS_VNOVAL) + || (va->va_mtime.tv_sec != PUFFS_VNOVAL + && va->va_mtime.tv_nsec != PUFFS_VNOVAL)) { + rv = puffs_access_times(pn->pn_va.va_uid, pn->pn_va.va_gid, + pn->pn_va.va_mode, va->va_vaflags & VA_UTIMES_NULL, pcr); + if (rv) + return rv; + } + + if (va->va_size != PUFFS_VNOVAL) { + switch (pn->pn_va.va_type) { + case VREG: + dtfs_setsize(pn, va->va_size); + pn->pn_va.va_bytes = va->va_size; + break; + case VBLK: + case VCHR: + case VFIFO: + break; + case VDIR: + return EISDIR; + default: + return EOPNOTSUPP; + } + } + + puffs_setvattr(&pn->pn_va, va); + + return 0; +} + +/* create a new node in the parent directory specified by opc */ +int +dtfs_node_create(struct puffs_usermount *pu, void *opc, + struct puffs_newinfo *pni, const struct puffs_cn *pcn, + const struct vattr *va) +{ + struct puffs_node *pn_parent = opc; + struct puffs_node *pn_new; + + if (!(va->va_type == VREG || va->va_type == VSOCK)) + return ENODEV; + + pn_new = dtfs_genfile(pn_parent, pcn, va->va_type); + puffs_setvattr(&pn_new->pn_va, va); + + puffs_newinfo_setcookie(pni, pn_new); + + return 0; +} + +int +dtfs_node_remove(struct puffs_usermount *pu, void *opc, void *targ, + const struct puffs_cn *pcn) +{ + struct puffs_node *pn_parent = opc; + struct puffs_node *pn = targ; + + if (pn->pn_va.va_type == VDIR) + return EPERM; + + dtfs_nukenode(targ, pn_parent, pcn->pcn_name, pcn->pcn_namelen); + + if (pn->pn_va.va_nlink == 0) + puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N2); + + return 0; +} + +int +dtfs_node_mkdir(struct puffs_usermount *pu, void *opc, + struct puffs_newinfo *pni, const struct puffs_cn *pcn, + const struct vattr *va) +{ + struct puffs_node *pn_parent = opc; + struct puffs_node *pn_new; + + pn_new = dtfs_genfile(pn_parent, pcn, VDIR); + puffs_setvattr(&pn_new->pn_va, va); + + puffs_newinfo_setcookie(pni, pn_new); + + return 0; +} + +int +dtfs_node_rmdir(struct puffs_usermount *pu, void *opc, void *targ, + const struct puffs_cn *pcn) +{ + struct puffs_node *pn_parent = opc; + struct dtfs_file *df = DTFS_CTOF(targ); + + if (!LIST_EMPTY(&df->df_dirents)) + return ENOTEMPTY; + + dtfs_nukenode(targ, pn_parent, pcn->pcn_name, pcn->pcn_namelen); + puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N2); + + return 0; +} + +int +dtfs_node_readdir(struct puffs_usermount *pu, void *opc, + struct dirent *dent, off_t *readoff, size_t *reslen, + const struct puffs_cred *pcr, + int *eofflag, off_t *cookies, size_t *ncookies) +{ + struct puffs_node *pn = opc; + struct puffs_node *pn_nth; + struct dtfs_dirent *dfd_nth; + + if (pn->pn_va.va_type != VDIR) + return ENOTDIR; + + dtfs_updatetimes(pn, 1, 0, 0); + + *ncookies = 0; + again: + if (*readoff == DENT_DOT || *readoff == DENT_DOTDOT) { + puffs_gendotdent(&dent, pn->pn_va.va_fileid, *readoff, reslen); + (*readoff)++; + PUFFS_STORE_DCOOKIE(cookies, ncookies, *readoff); + goto again; + } + + for (;;) { + dfd_nth = dtfs_dirgetnth(pn->pn_data, DENT_ADJ(*readoff)); + if (!dfd_nth) { + *eofflag = 1; + break; + } + pn_nth = dfd_nth->dfd_node; + + if (!puffs_nextdent(&dent, dfd_nth->dfd_name, + pn_nth->pn_va.va_fileid, + puffs_vtype2dt(pn_nth->pn_va.va_type), + reslen)) + break; + + (*readoff)++; + PUFFS_STORE_DCOOKIE(cookies, ncookies, *readoff); + } + + return 0; +} + +int +dtfs_node_poll(struct puffs_usermount *pu, void *opc, int *events) +{ + struct dtfs_mount *dtm = puffs_getspecific(pu); + struct dtfs_poll dp; + struct itimerval it; + + memset(&it, 0, sizeof(struct itimerval)); + it.it_value.tv_sec = 4; + if (setitimer(ITIMER_REAL, &it, NULL) == -1) + return errno; + + dp.dp_pcc = puffs_cc_getcc(pu); + LIST_INSERT_HEAD(&dtm->dtm_pollent, &dp, dp_entries); + puffs_cc_yield(dp.dp_pcc); + + *events = *events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM); + return 0; +} + +int +dtfs_node_mmap(struct puffs_usermount *pu, void *opc, vm_prot_t prot, + const struct puffs_cred *pcr) +{ + struct dtfs_mount *dtm = puffs_getspecific(pu); + + if ((dtm->dtm_allowprot & prot) != prot) + return EACCES; + + return 0; +} + +int +dtfs_node_rename(struct puffs_usermount *pu, void *opc, void *src, + const struct puffs_cn *pcn_src, void *targ_dir, void *targ, + const struct puffs_cn *pcn_targ) +{ + struct dtfs_dirent *dfd_src; + struct dtfs_file *df_targ; + struct puffs_node *pn_sdir = opc; + struct puffs_node *pn_sfile = src; + struct puffs_node *pn_tdir = targ_dir; + struct puffs_node *pn_tfile = targ; + + /* check that we don't do the old amigados trick */ + if (pn_sfile->pn_va.va_type == VDIR) { + if (dtfs_isunder(pn_tdir, pn_sfile)) + return EINVAL; + + if ((pcn_src->pcn_namelen == 1 && pcn_src->pcn_name[0]=='.') || + opc == src || + PCNISDOTDOT(pcn_src) || + PCNISDOTDOT(pcn_targ)) { + return EINVAL; + } + } + + dfd_src = dtfs_dirgetbyname(DTFS_PTOF(pn_sdir), + pcn_src->pcn_name, pcn_src->pcn_namelen); + + /* does it still exist, or did someone race us here? */ + if (dfd_src == NULL) { + return ENOENT; + } + + /* if there's a target file, nuke it for atomic replacement */ + if (pn_tfile) { + if (pn_tfile->pn_va.va_type == VDIR) { + df_targ = DTFS_CTOF(pn_tfile); + if (!LIST_EMPTY(&df_targ->df_dirents)) + return ENOTEMPTY; + } + dtfs_nukenode(pn_tfile, pn_tdir, + pcn_targ->pcn_name, pcn_targ->pcn_namelen); + } + + /* out with the old */ + dtfs_removedent(pn_sdir, dfd_src); + /* and in with the new */ + dtfs_adddent(pn_tdir, dfd_src); + + /* update name */ + free(dfd_src->dfd_name); + dfd_src->dfd_name = estrndup(pcn_targ->pcn_name,pcn_targ->pcn_namelen); + dfd_src->dfd_namelen = strlen(dfd_src->dfd_name); + + dtfs_updatetimes(src, 0, 1, 0); + + return 0; +} + +int +dtfs_node_link(struct puffs_usermount *pu, void *opc, void *targ, + const struct puffs_cn *pcn) +{ + struct puffs_node *pn_dir = opc; + struct dtfs_dirent *dfd; + + dfd = emalloc(sizeof(struct dtfs_dirent)); + dfd->dfd_node = targ; + dfd->dfd_name = estrndup(pcn->pcn_name, pcn->pcn_namelen); + dfd->dfd_namelen = strlen(dfd->dfd_name); + dtfs_adddent(pn_dir, dfd); + + dtfs_updatetimes(targ, 0, 1, 0); + + return 0; +} + +int +dtfs_node_symlink(struct puffs_usermount *pu, void *opc, + struct puffs_newinfo *pni, const struct puffs_cn *pcn_src, + const struct vattr *va, const char *link_target) +{ + struct puffs_node *pn_parent = opc; + struct puffs_node *pn_new; + struct dtfs_file *df_new; + + if (va->va_type != VLNK) + return ENODEV; + + pn_new = dtfs_genfile(pn_parent, pcn_src, VLNK); + puffs_setvattr(&pn_new->pn_va, va); + df_new = DTFS_PTOF(pn_new); + df_new->df_linktarget = estrdup(link_target); + pn_new->pn_va.va_size = strlen(df_new->df_linktarget); + + puffs_newinfo_setcookie(pni, pn_new); + + return 0; +} + +int +dtfs_node_readlink(struct puffs_usermount *pu, void *opc, + const struct puffs_cred *cred, char *linkname, size_t *linklen) +{ + struct dtfs_file *df = DTFS_CTOF(opc); + struct puffs_node *pn = opc; + + assert(pn->pn_va.va_type == VLNK); + strlcpy(linkname, df->df_linktarget, *linklen); + *linklen = strlen(linkname); + + return 0; +} + +int +dtfs_node_mknod(struct puffs_usermount *pu, void *opc, + struct puffs_newinfo *pni, const struct puffs_cn *pcn, + const struct vattr *va) +{ + struct puffs_node *pn_parent = opc; + struct puffs_node *pn_new; + + if (!(va->va_type == VBLK || va->va_type == VCHR + || va->va_type == VFIFO)) + return EINVAL; + + pn_new = dtfs_genfile(pn_parent, pcn, va->va_type); + puffs_setvattr(&pn_new->pn_va, va); + + puffs_newinfo_setcookie(pni, pn_new); + + return 0; +} + +#define BLOCKOFF(a,b) ((a) & ((b)-1)) +#define BLOCKLEFT(a,b) ((b) - BLOCKOFF(a,b)) + +/* + * Read operation, used both for VOP_READ and VOP_GETPAGES + */ +int +dtfs_node_read(struct puffs_usermount *pu, void *opc, uint8_t *buf, + off_t offset, size_t *resid, const struct puffs_cred *pcr, int ioflag) +{ + struct puffs_node *pn = opc; + struct dtfs_file *df = DTFS_CTOF(opc); + quad_t xfer, origxfer; + uint8_t *src, *dest; + size_t copylen; + + if (pn->pn_va.va_type != VREG) + return EISDIR; + + xfer = MIN(*resid, df->df_datalen - offset); + if (xfer < 0) + return EINVAL; + + dest = buf; + origxfer = xfer; + while (xfer > 0) { + copylen = MIN(xfer, BLOCKLEFT(offset, DTFS_BLOCKSIZE)); + src = df->df_blocks[BLOCKNUM(offset, DTFS_BLOCKSHIFT)] + + BLOCKOFF(offset, DTFS_BLOCKSIZE); + memcpy(dest, src, copylen); + offset += copylen; + dest += copylen; + xfer -= copylen; + } + *resid -= origxfer; + + dtfs_updatetimes(pn, 1, 0, 0); + + return 0; +} + +/* + * write operation on the wing + */ +int +dtfs_node_write(struct puffs_usermount *pu, void *opc, uint8_t *buf, + off_t offset, size_t *resid, const struct puffs_cred *pcr, int ioflag) +{ + struct puffs_node *pn = opc; + struct dtfs_file *df = DTFS_CTOF(opc); + uint8_t *src, *dest; + size_t copylen; + + if (pn->pn_va.va_type != VREG) + return EISDIR; + + if (ioflag & PUFFS_IO_APPEND) + offset = pn->pn_va.va_size; + + if (*resid + offset > pn->pn_va.va_size) + dtfs_setsize(pn, *resid + offset); + + src = buf; + while (*resid > 0) { + int i; + copylen = MIN(*resid, BLOCKLEFT(offset, DTFS_BLOCKSIZE)); + i = BLOCKNUM(offset, DTFS_BLOCKSHIFT); + dest = df->df_blocks[i] + + BLOCKOFF(offset, DTFS_BLOCKSIZE); + memcpy(dest, src, copylen); + offset += copylen; + dest += copylen; + *resid -= copylen; + } + + dtfs_updatetimes(pn, 0, 1, 1); + + return 0; +} + +int +dtfs_node_pathconf(struct puffs_usermount *pu, puffs_cookie_t opc, + int name, register_t *retval) +{ + + switch (name) { + case _PC_LINK_MAX: + *retval = LINK_MAX; + return 0; + case _PC_NAME_MAX: + *retval = NAME_MAX; + return 0; + case _PC_PATH_MAX: + *retval = PATH_MAX; + return 0; + case _PC_PIPE_BUF: + *retval = PIPE_BUF; + return 0; + case _PC_CHOWN_RESTRICTED: + *retval = 1; + return 0; + case _PC_NO_TRUNC: + *retval = 1; + return 0; + case _PC_SYNC_IO: + *retval = 1; + return 0; + case _PC_FILESIZEBITS: + *retval = 43; /* this one goes to 11 */ + return 0; + case _PC_SYMLINK_MAX: + *retval = MAXPATHLEN; + return 0; + case _PC_2_SYMLINKS: + *retval = 1; + return 0; + default: + return EINVAL; + } +} + +int +dtfs_node_inactive(struct puffs_usermount *pu, puffs_cookie_t opc) +{ + struct puffs_node *pn = opc; + + if (pn->pn_va.va_nlink == 0) + puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N1); + return 0; +} + +int +dtfs_node_reclaim(struct puffs_usermount *pu, void *opc) +{ + struct puffs_node *pn = opc; + + if (pn->pn_va.va_nlink == 0) + dtfs_freenode(pn); + + return 0; +} diff --git a/contrib/netbsd-tests/fs/puffs/t_basic.c b/contrib/netbsd-tests/fs/puffs/t_basic.c new file mode 100644 index 0000000..4b5b7b8 --- /dev/null +++ b/contrib/netbsd-tests/fs/puffs/t_basic.c @@ -0,0 +1,455 @@ +/* $NetBSD: t_basic.c,v 1.14 2017/01/13 21:30:40 christos Exp $ */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "h_macros.h" +#include "../common/h_fsmacros.h" + +/* + * Do a synchronous operation. When this returns, all FAF operations + * have at least been delivered to the file system. + * + * XXX: is this really good enough considering puffs(9)-issued + * callback operations? + */ +static void +syncbar(const char *fs) +{ + struct statvfs svb; + + if (rump_sys_statvfs1(fs, &svb, ST_WAIT) == -1) + atf_tc_fail_errno("statvfs"); +} + +#ifdef PUFFSDUMP +static void __unused +dumpopcount(struct puffstestargs *args) +{ + size_t i; + + printf("VFS OPS:\n"); + for (i = 0; i < MIN(puffsdump_vfsop_count, PUFFS_VFS_MAX); i++) { + printf("\t%s: %d\n", + puffsdump_vfsop_revmap[i], args->pta_vfs_toserv_ops[i]); + } + + printf("VN OPS:\n"); + for (i = 0; i < MIN(puffsdump_vnop_count, PUFFS_VN_MAX); i++) { + printf("\t%s: %d\n", + puffsdump_vnop_revmap[i], args->pta_vn_toserv_ops[i]); + } +} +#endif + +ATF_TC(mount); +ATF_TC_HEAD(mount, tc) +{ + + atf_tc_set_md_var(tc, "descr", "puffs+dtfs un/mount test"); +} + +ATF_TC_BODY(mount, tc) +{ + void *args; + + FSTEST_CONSTRUCTOR(tc, puffs, args); + FSTEST_DESTRUCTOR(tc, puffs, args); +} + +ATF_TC(root_reg); +ATF_TC_HEAD(root_reg, tc) +{ + atf_tc_set_md_var(tc, "descr", "root is a regular file"); +} + +#define MAKEOPTS(...) \ + char *theopts[] = {NULL, "-s", __VA_ARGS__, "dtfs", "n/a", NULL} + +ATF_TC_BODY(root_reg, tc) +{ + MAKEOPTS("-r", "reg"); + void *args; + int fd, rv; + + FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts); + + fd = rump_sys_open(FSTEST_MNTNAME, O_RDWR); + if (fd == -1) + atf_tc_fail_errno("open root"); + if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd)) + atf_tc_fail_errno("write to root"); + rv = rump_sys_mkdir(FSTEST_MNTNAME "/test", 0777); + ATF_REQUIRE(errno == ENOTDIR); + ATF_REQUIRE(rv == -1); + rump_sys_close(fd); + + FSTEST_DESTRUCTOR(tc, puffs, args); +} + +ATF_TC(root_lnk); +ATF_TC_HEAD(root_lnk, tc) +{ + + atf_tc_set_md_var(tc, "descr", "root is a symbolic link"); +} + +#define LINKSTR "/path/to/nowhere" +ATF_TC_BODY(root_lnk, tc) +{ + MAKEOPTS("-r", "lnk " LINKSTR); + void *args; + char buf[PATH_MAX]; + ssize_t len; + + FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts); + + if ((len = rump_sys_readlink(FSTEST_MNTNAME, buf, sizeof(buf)-1)) == -1) + atf_tc_fail_errno("readlink"); + buf[len] = '\0'; + + ATF_REQUIRE_STREQ(buf, LINKSTR); + +#if 0 /* XXX: unmount uses FOLLOW */ + if (rump_sys_unmount("/mp", 0) == -1) + atf_tc_fail_errno("unmount"); +#endif +} + +ATF_TC(root_fifo); +ATF_TC_HEAD(root_fifo, tc) +{ + + atf_tc_set_md_var(tc, "descr", "root is a symbolic link"); +} + +#define MAGICSTR "nakit ja muusiperunat maustevoilla" +static void * +dofifow(void *arg) +{ + int fd = (int)(uintptr_t)arg; + char buf[512]; + + printf("writing\n"); + strcpy(buf, MAGICSTR); + if (rump_sys_write(fd, buf, strlen(buf)+1) != strlen(buf)+1) + atf_tc_fail_errno("write to fifo"); + + return NULL; +} + +ATF_TC_BODY(root_fifo, tc) +{ + MAKEOPTS("-r", "fifo"); + void *args; + pthread_t pt; + char buf[512]; + int fd; + + FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts); + + fd = rump_sys_open(FSTEST_MNTNAME, O_RDWR); + if (fd == -1) + atf_tc_fail_errno("open fifo"); + + pthread_create(&pt, NULL, dofifow, (void *)(uintptr_t)fd); + + memset(buf, 0, sizeof(buf)); + if (rump_sys_read(fd, buf, sizeof(buf)) == -1) + atf_tc_fail_errno("read fifo"); + + ATF_REQUIRE_STREQ(buf, MAGICSTR); + rump_sys_close(fd); + + FSTEST_DESTRUCTOR(tc, puffs, args); +} + +ATF_TC(root_chrdev); +ATF_TC_HEAD(root_chrdev, tc) +{ + + atf_tc_set_md_var(tc, "descr", "root is /dev/null"); +} + +ATF_TC_BODY(root_chrdev, tc) +{ + MAKEOPTS("-r", "chr 2 2"); + void *args; + ssize_t rv; + char buf[512]; + int fd; + + FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts); + + fd = rump_sys_open(FSTEST_MNTNAME, O_RDWR); + if (fd == -1) + atf_tc_fail_errno("open null"); + + rv = rump_sys_write(fd, buf, sizeof(buf)); + ATF_REQUIRE(rv == sizeof(buf)); + + rv = rump_sys_read(fd, buf, sizeof(buf)); + ATF_REQUIRE(rv == 0); + + rump_sys_close(fd); + + FSTEST_DESTRUCTOR(tc, puffs, args); +} + +/* + * Inactive/reclaim tests + */ + +ATF_TC(inactive_basic); +ATF_TC_HEAD(inactive_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "inactive gets called"); +} + +ATF_TC_BODY(inactive_basic, tc) +{ + struct puffstestargs *pargs; + void *args; + int fd; + + FSTEST_CONSTRUCTOR(tc, puffs, args); + FSTEST_ENTER(); + pargs = args; + + fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777); + if (fd == -1) + atf_tc_fail_errno("create"); + + /* none yet */ + ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 0); + + rump_sys_close(fd); + + /* one for file */ + ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 1); + + FSTEST_EXIT(); + + /* another for the mountpoint */ + ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 2); + + FSTEST_DESTRUCTOR(tc, puffs, args); +} + +ATF_TC(inactive_reclaim); +ATF_TC_HEAD(inactive_reclaim, tc) +{ + + atf_tc_set_md_var(tc, "descr", "inactive/reclaim gets called"); +} + +ATF_TC_BODY(inactive_reclaim, tc) +{ + struct puffstestargs *pargs; + void *args; + int fd; + + FSTEST_CONSTRUCTOR(tc, puffs, args); + FSTEST_ENTER(); + pargs = args; + + fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777); + if (fd == -1) + atf_tc_fail_errno("create"); + + ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 0); + + if (rump_sys_unlink("file") == -1) + atf_tc_fail_errno("remove"); + + ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE], 0); + ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 0); + + rump_sys_close(fd); + syncbar(FSTEST_MNTNAME); + + ATF_REQUIRE(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE] > 0); + ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 1); + + FSTEST_EXIT(); + FSTEST_DESTRUCTOR(tc, puffs, args); +} + +ATF_TC(reclaim_hardlink); +ATF_TC_HEAD(reclaim_hardlink, tc) +{ + + atf_tc_set_md_var(tc, "descr", "reclaim gets called only after " + "final link is gone"); +} + +ATF_TC_BODY(reclaim_hardlink, tc) +{ + struct puffstestargs *pargs; + void *args; + int fd; + int ianow; + + FSTEST_CONSTRUCTOR(tc, puffs, args); + FSTEST_ENTER(); + pargs = args; + + fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777); + if (fd == -1) + atf_tc_fail_errno("create"); + + if (rump_sys_link("file", "anotherfile") == -1) + atf_tc_fail_errno("create link"); + rump_sys_close(fd); + + ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 0); + + /* unlink first hardlink */ + if (rump_sys_unlink("file") == -1) + atf_tc_fail_errno("unlink 1"); + + ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 0); + ianow = pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE]; + + /* unlink second hardlink */ + if (rump_sys_unlink("anotherfile") == -1) + atf_tc_fail_errno("unlink 2"); + + syncbar(FSTEST_MNTNAME); + + ATF_REQUIRE(ianow < pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE]); + ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 1); + + FSTEST_EXIT(); + FSTEST_DESTRUCTOR(tc, puffs, args); +} + +ATF_TC(unlink_accessible); +ATF_TC_HEAD(unlink_accessible, tc) +{ + + atf_tc_set_md_var(tc, "descr", "open file is accessible after " + "having been unlinked"); +} + +ATF_TC_BODY(unlink_accessible, tc) +{ + MAKEOPTS("-i", "-o", "nopagecache"); + struct puffstestargs *pargs; + void *args; + char buf[512]; + int fd, ianow; + + assert(sizeof(buf) > sizeof(MAGICSTR)); + + FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts); + FSTEST_ENTER(); + pargs = args; + + fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777); + if (fd == -1) + atf_tc_fail_errno("create"); + + if (rump_sys_write(fd, MAGICSTR, sizeof(MAGICSTR)) != sizeof(MAGICSTR)) + atf_tc_fail_errno("write"); + if (rump_sys_unlink("file") == -1) + atf_tc_fail_errno("unlink"); + + ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 0); + ianow = pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE]; + + if (rump_sys_pread(fd, buf, sizeof(buf), 0) == -1) + atf_tc_fail_errno("read"); + rump_sys_close(fd); + + syncbar(FSTEST_MNTNAME); + + ATF_REQUIRE_EQ(pargs->pta_vn_toserv_ops[PUFFS_VN_RECLAIM], 1); + ATF_REQUIRE(pargs->pta_vn_toserv_ops[PUFFS_VN_INACTIVE] > ianow); + + ATF_REQUIRE_STREQ(buf, MAGICSTR); + + FSTEST_EXIT(); + FSTEST_DESTRUCTOR(tc, puffs, args); +} + +ATF_TC(signals); +ATF_TC_HEAD(signals, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that sending a signal can " + "cause an interrupt to puffs wait"); +} + +extern struct proc *rumpns_initproc; +extern void rumpns_psignal(struct proc *, int); +extern void rumpns_sigclearall(struct proc *, void *, void *); +ATF_TC_BODY(signals, tc) +{ + struct stat sb; + void *args; + + rump_boot_setsigmodel(RUMP_SIGMODEL_RECORD); + + FSTEST_CONSTRUCTOR(tc, puffs, args); + FSTEST_ENTER(); + RL(rump_sys_stat(".", &sb)); + + /* send SIGUSR1, should not affect puffs ops */ + rump_schedule(); + rumpns_psignal(rumpns_initproc, SIGUSR1); + rump_unschedule(); + RL(rump_sys_stat(".", &sb)); + + /* send SIGTERM, should get EINTR */ + rump_schedule(); + rumpns_psignal(rumpns_initproc, SIGTERM); + rump_unschedule(); + ATF_REQUIRE_ERRNO(EINTR, rump_sys_stat(".", &sb) == -1); + + /* clear sigmask so that we can unmount */ + rump_schedule(); + rumpns_sigclearall(rumpns_initproc, NULL, NULL); + rump_unschedule(); + + FSTEST_EXIT(); + FSTEST_DESTRUCTOR(tc, puffs, args); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mount); + + ATF_TP_ADD_TC(tp, root_fifo); + ATF_TP_ADD_TC(tp, root_lnk); + ATF_TP_ADD_TC(tp, root_reg); + ATF_TP_ADD_TC(tp, root_chrdev); + + ATF_TP_ADD_TC(tp, inactive_basic); + ATF_TP_ADD_TC(tp, inactive_reclaim); + ATF_TP_ADD_TC(tp, reclaim_hardlink); + ATF_TP_ADD_TC(tp, unlink_accessible); + + ATF_TP_ADD_TC(tp, signals); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/puffs/t_fuzz.c b/contrib/netbsd-tests/fs/puffs/t_fuzz.c new file mode 100644 index 0000000..b2e000d --- /dev/null +++ b/contrib/netbsd-tests/fs/puffs/t_fuzz.c @@ -0,0 +1,283 @@ +/* $NetBSD: t_fuzz.c,v 1.6 2017/01/13 21:30:40 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Fuzztest puffs mount. There are n different levels of testing: + * each one pours more and more sane garbage into the args to that + * the mount progresses further and further. Level 8 (at least when + * writing this comment) should be the one where mounting actually + * succeeds. + * + * Our metric of success is crash / no crash. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_macros.h" + +#define ITERATIONS 100 + +static void +fixversion(struct puffs_kargs *kargs) +{ + + kargs->pa_vers = PUFFSVERSION; +} + +static void +fixkflag(struct puffs_kargs *kargs) +{ + + kargs->pa_flags &= PUFFS_KFLAG_MASK; + + /* + * PUFFS_KFLAG_CACHE_FS_TTL require extended behavior + * from the filesystem for which we have no test right now. + */ + kargs->pa_flags &= ~PUFFS_KFLAG_CACHE_FS_TTL; +} + +static void +fixfhflag(struct puffs_kargs *kargs) +{ + + kargs->pa_fhflags &= PUFFS_FHFLAG_MASK; +} + +static void +fixspare(struct puffs_kargs *kargs) +{ + + memset(&kargs->pa_spare, 0, sizeof(kargs->pa_spare)); +} + +static void +fixhandsize(struct puffs_kargs *kargs) +{ + + kargs->pa_fhsize %= PUFFS_FHSIZE_MAX+4; +} + +static void +fixhandsize2(struct puffs_kargs *kargs) +{ + + /* XXX: values */ + if (kargs->pa_fhflags & PUFFS_FHFLAG_NFSV3) + kargs->pa_fhsize %= 60; + if (kargs->pa_fhflags & PUFFS_FHFLAG_NFSV2) + kargs->pa_fhsize %= 28; +} + +static void +fixputter(struct puffs_kargs *kargs) +{ + + kargs->pa_fd = rump_sys_open("/dev/putter", O_RDWR); + if (kargs->pa_fd == -1) + atf_tc_fail_errno("open putter"); +} + +static void +fixroot(struct puffs_kargs *kargs) +{ + + kargs->pa_root_vtype %= VBAD; +} + +static void +unfixputter(struct puffs_kargs *kargs) +{ + + rump_sys_close(kargs->pa_fd); +} + +typedef void (*fixfn)(struct puffs_kargs *); +static fixfn fixstack[] = { + fixversion, + fixkflag, + fixfhflag, + fixspare, + fixhandsize, + fixhandsize2, + fixputter, + fixroot, +}; + +static void +fixup(int nfix, struct puffs_kargs *kargs) +{ + int i; + + assert(nfix <= __arraycount(fixstack)); + for (i = 0; i < nfix; i++) + fixstack[i](kargs); +} + +static void +unfixup(int nfix, struct puffs_kargs *kargs) +{ + + if (nfix >= 7) + unfixputter(kargs); +} + +static pthread_mutex_t damtx; +static pthread_cond_t dacv; +static int dafd = -1; + +static void * +respondthread(void *arg) +{ + char buf[PUFFS_MSG_MAXSIZE]; + struct puffs_req *preq = (void *)buf; + struct pollfd pfd; + ssize_t n; + + pthread_mutex_lock(&damtx); + for (;;) { + while (dafd == -1) + pthread_cond_wait(&dacv, &damtx); + + while (dafd != -1) { + pthread_mutex_unlock(&damtx); + pfd.fd = dafd; + pfd.events = POLLIN; + pfd.revents = 0; + if (rump_sys_poll(&pfd, 1, 10) == 0) { + pthread_mutex_lock(&damtx); + continue; + } + n = rump_sys_read(dafd, buf, sizeof(buf)); + if (n <= 0) { + pthread_mutex_lock(&damtx); + break; + } + + /* just say it was succesful */ + preq->preq_rv = 0; + rump_sys_write(dafd, buf, n); + pthread_mutex_lock(&damtx); + } + } + + return NULL; +} + +static void +testbody(int nfix) +{ + pthread_t pt; + struct puffs_kargs kargs; + unsigned long seed; + int i; + + seed = time(NULL); + srandom(seed); + printf("test seeded RNG with %lu\n", seed); + + rump_init(); + + pthread_mutex_init(&damtx, NULL); + pthread_cond_init(&dacv, NULL); + pthread_create(&pt, NULL, respondthread, NULL); + + ATF_REQUIRE(rump_sys_mkdir("/mnt", 0777) == 0); + + for (i = 0; i < ITERATIONS; i++) { + tests_makegarbage(&kargs, sizeof(kargs)); + fixup(nfix, &kargs); + if (rump_sys_mount(MOUNT_PUFFS, "/mnt", 0, + &kargs, sizeof(kargs)) == 0) { + struct stat sb; + + pthread_mutex_lock(&damtx); + dafd = kargs.pa_fd; + pthread_cond_signal(&dacv); + pthread_mutex_unlock(&damtx); + + rump_sys_stat("/mnt", &sb); + rump_sys_unmount("/mnt", MNT_FORCE); + } + unfixup(nfix, &kargs); + + pthread_mutex_lock(&damtx); + dafd = -1; + pthread_mutex_unlock(&damtx); + } +} + +#define MAKETEST(_n_) \ +ATF_TC(mountfuzz##_n_); \ +ATF_TC_HEAD(mountfuzz##_n_, tc) \ +{atf_tc_set_md_var(tc, "descr", "garbage kargs, " # _n_ " fix(es)");} \ +ATF_TC_BODY(mountfuzz##_n_, tc) {testbody(_n_);} + +MAKETEST(0); +MAKETEST(1); +MAKETEST(2); +MAKETEST(3); +MAKETEST(4); +MAKETEST(5); +MAKETEST(6); +MAKETEST(7); +MAKETEST(8); + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mountfuzz0); + ATF_TP_ADD_TC(tp, mountfuzz1); + ATF_TP_ADD_TC(tp, mountfuzz2); + ATF_TP_ADD_TC(tp, mountfuzz3); + ATF_TP_ADD_TC(tp, mountfuzz4); + ATF_TP_ADD_TC(tp, mountfuzz5); + ATF_TP_ADD_TC(tp, mountfuzz6); + ATF_TP_ADD_TC(tp, mountfuzz7); + ATF_TP_ADD_TC(tp, mountfuzz8); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/puffs/t_io.c b/contrib/netbsd-tests/fs/puffs/t_io.c new file mode 100644 index 0000000..72b5d85 --- /dev/null +++ b/contrib/netbsd-tests/fs/puffs/t_io.c @@ -0,0 +1,61 @@ +/* $NetBSD: t_io.c,v 1.2 2017/01/13 21:30:40 christos Exp $ */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "h_macros.h" +#include "../common/h_fsmacros.h" + +#define MAKEOPTS(...) \ + char *theopts[] = {NULL, "-s", __VA_ARGS__, "dtfs", "n/a", NULL} + +ATF_TC(nocache); +ATF_TC_HEAD(nocache, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests large i/o without page cache"); +} + +ATF_TC_BODY(nocache, tc) +{ + MAKEOPTS("-o", "nopagecache"); + char data[1024*1024]; + void *args; + int fd; + + FSTEST_CONSTRUCTOR_FSPRIV(tc, puffs, args, theopts); + FSTEST_ENTER(); + + RL(fd = rump_sys_open("afile", O_CREAT | O_RDWR, 0755)); + RL(rump_sys_write(fd, data, sizeof(data))); + rump_sys_close(fd); + + FSTEST_EXIT(); + FSTEST_DESTRUCTOR(tc, puffs, args); +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, nocache); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/tmpfs/README b/contrib/netbsd-tests/fs/tmpfs/README new file mode 100644 index 0000000..cdc3f2d --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/README @@ -0,0 +1,17 @@ +The tests in this directory where written at the same time tmpfs was +developed. This is why, if you follow the order of tests in the Atffile, +you will notice that they start checking the most basic things and end +checking the less common ones. Furthermore, tests try not to use features +tested by further tests in the lists. + +However, the above is not the most appropriate testing procedure when you +have a working file system because some separation in test programs does +not make sense afterwards. + +Many of the tests here are applicable to any file system. They should be +refactored to be reusable on any mounted file system, which could also +remove the need to do the mount/unmount steps in each and every test case. + +Possibly take a look at the file system tests in FreeBSD. They seem to be +much more complete, even though they are written in Perl and therefore not +directly usable. diff --git a/contrib/netbsd-tests/fs/tmpfs/h_funcs.subr b/contrib/netbsd-tests/fs/tmpfs/h_funcs.subr new file mode 100644 index 0000000..edab789 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/h_funcs.subr @@ -0,0 +1,115 @@ +#!/bin/sh +# +# $NetBSD: h_funcs.subr,v 1.5 2013/03/17 01:16:45 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +Mount_Point= + +# +# test_mount [args] +# +# Mounts tmpfs over ${Mount_Point} and changes the current directory +# to the mount point. Optional arguments may be passed to the +# mount command. +# +test_mount() { + require_fs tmpfs + + Mount_Point=$(pwd)/mntpt + atf_check -s eq:0 -o empty -e empty mkdir "${Mount_Point}" + echo "mount -t tmpfs ${*} tmpfs ${Mount_Point}" + mount -t tmpfs "${@}" tmpfs "${Mount_Point}" 2>mounterr + if [ "${?}" -ne 0 ]; then + cat mounterr 1>&2 + if grep 'Operation not supported' mounterr > /dev/null; then + atf_skip "tmpfs not supported" + fi + atf_fail "Failed to mount a tmpfs file system" + fi + cd "${Mount_Point}" +} + +# +# test_unmount +# +# Unmounts the file system mounted by test_mount. +# +test_unmount() { + # Begin FreeBSD + _test_unmount + exit_code=$? + atf_check_equal "$exit_code" "0" + return $exit_code + # End FreeBSD + cd - >/dev/null + atf_check -s eq:0 -o empty -e empty umount ${Mount_Point} + atf_check -s eq:0 -o empty -e empty rmdir ${Mount_Point} + Mount_Point= +} + +# Begin FreeBSD +_test_unmount() { + if [ -z "${Mount_Point}" -o ! -d "${Mount_Point}" ]; then + return 0 + fi + + cd - >/dev/null + umount ${Mount_Point} + rmdir ${Mount_Point} + Mount_Point= +} +# End FreeBSD + +# +# kqueue_monitor expected_nevents file1 [.. fileN] +# +# Monitors the commands given through stdin (one per line) using +# kqueue and stores the events raised in a log that can be later +# verified with kqueue_check. +# +kqueue_monitor() { + nev=${1}; shift + echo "Running kqueue-monitored commands and expecting" \ + "${nev} events" + $(atf_get_srcdir)/h_tools kqueue ${*} >kqueue.log || \ + atf_fail "Could not launch kqueue monitor" + got=$(wc -l kqueue.log | awk '{ print $1 }') + test ${got} -eq ${nev} || \ + atf_fail "Got ${got} events but expected ${nev}" +} + +# +# kqueue_check file event +# +# Checks if kqueue raised the given event when monitoring the +# given file. +# +kqueue_check() { + echo "Checking if ${1} received ${2}" + grep "^${1} - ${2}$" kqueue.log >/dev/null || \ + atf_fail "${1} did not receive ${2}" +} diff --git a/contrib/netbsd-tests/fs/tmpfs/h_tools.c b/contrib/netbsd-tests/fs/tmpfs/h_tools.c new file mode 100644 index 0000000..492e084 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/h_tools.c @@ -0,0 +1,321 @@ +/* $NetBSD: h_tools.c,v 1.4 2011/06/11 18:03:17 christos Exp $ */ + +/* + * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Helper tools for several tests. These are kept in a single file due + * to the limitations of bsd.prog.mk to build a single program in a + * given directory. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __FreeBSD__ +#include +#endif + +/* --------------------------------------------------------------------- */ + +static int getfh_main(int, char **); +static int kqueue_main(int, char **); +static int rename_main(int, char **); +static int sockets_main(int, char **); +static int statvfs_main(int, char **); + +/* --------------------------------------------------------------------- */ + +int +getfh_main(int argc, char **argv) +{ + int error; + void *fh; + size_t fh_size; + + if (argc < 2) + return EXIT_FAILURE; + +#ifdef __FreeBSD__ + fh_size = sizeof(fhandle_t); +#else + fh_size = 0; +#endif + + fh = NULL; + for (;;) { + if (fh_size) { + fh = malloc(fh_size); + if (fh == NULL) { + fprintf(stderr, "out of memory"); + return EXIT_FAILURE; + } + } + /* + * The kernel provides the necessary size in fh_size - + * but it may change if someone moves things around, + * so retry untill we have enough memory. + */ +#ifdef __FreeBSD__ + error = getfh(argv[1], fh); +#else + error = getfh(argv[1], fh, &fh_size); +#endif + if (error == 0) { + break; + } else { + if (fh != NULL) + free(fh); + if (errno != E2BIG) { + warn("getfh"); + return EXIT_FAILURE; + } + } + } + + error = write(STDOUT_FILENO, fh, fh_size); + if (error == -1) { + warn("write"); + return EXIT_FAILURE; + } + free(fh); + + return 0; +} + +/* --------------------------------------------------------------------- */ + +int +kqueue_main(int argc, char **argv) +{ + char *line; + int i, kq; + size_t len; + struct kevent *changes, event; + + if (argc < 2) + return EXIT_FAILURE; + + argc--; + argv++; + + changes = malloc(sizeof(struct kevent) * argc); + if (changes == NULL) + errx(EXIT_FAILURE, "not enough memory"); + + for (i = 0; i < argc; i++) { + int fd; + + fd = open(argv[i], O_RDONLY); + if (fd == -1) + err(EXIT_FAILURE, "cannot open %s", argv[i]); + + EV_SET(&changes[i], fd, EVFILT_VNODE, + EV_ADD | EV_ENABLE | EV_ONESHOT, + NOTE_ATTRIB | NOTE_DELETE | NOTE_EXTEND | NOTE_LINK | + NOTE_RENAME | NOTE_REVOKE | NOTE_WRITE, + 0, 0); + } + + kq = kqueue(); + if (kq == -1) + err(EXIT_FAILURE, "kqueue"); + + while ((line = fgetln(stdin, &len)) != NULL) { + int ec, nev; + struct timespec to; + + to.tv_sec = 0; + to.tv_nsec = 100000; + + (void)kevent(kq, changes, argc, &event, 1, &to); + + assert(len > 0); + assert(line[len - 1] == '\n'); + line[len - 1] = '\0'; + ec = system(line); + if (ec != EXIT_SUCCESS) + errx(ec, "%s returned %d", line, ec); + + do { + nev = kevent(kq, changes, argc, &event, 1, &to); + if (nev == -1) + err(EXIT_FAILURE, "kevent"); + else if (nev > 0) { + for (i = 0; i < argc; i++) + if (event.ident == changes[i].ident) + break; + + if (event.fflags & NOTE_ATTRIB) + printf("%s - NOTE_ATTRIB\n", argv[i]); + if (event.fflags & NOTE_DELETE) + printf("%s - NOTE_DELETE\n", argv[i]); + if (event.fflags & NOTE_EXTEND) + printf("%s - NOTE_EXTEND\n", argv[i]); + if (event.fflags & NOTE_LINK) + printf("%s - NOTE_LINK\n", argv[i]); + if (event.fflags & NOTE_RENAME) + printf("%s - NOTE_RENAME\n", argv[i]); + if (event.fflags & NOTE_REVOKE) + printf("%s - NOTE_REVOKE\n", argv[i]); + if (event.fflags & NOTE_WRITE) + printf("%s - NOTE_WRITE\n", argv[i]); + } + } while (nev > 0); + } + + for (i = 0; i < argc; i++) + close(changes[i].ident); + free(changes); + + return EXIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ + +int +rename_main(int argc, char **argv) +{ + + if (argc < 3) + return EXIT_FAILURE; + + if (rename(argv[1], argv[2]) == -1) { + warn("rename"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ + +int +sockets_main(int argc, char **argv) +{ + int error, fd; + struct sockaddr_un addr; + + if (argc < 2) + return EXIT_FAILURE; + + fd = socket(PF_LOCAL, SOCK_STREAM, 0); + if (fd == -1) { + warn("socket"); + return EXIT_FAILURE; + } + +#ifdef __FreeBSD__ + memset(&addr, 0, sizeof(addr)); +#endif + (void)strlcpy(addr.sun_path, argv[1], sizeof(addr.sun_path)); + addr.sun_family = PF_UNIX; +#ifdef __FreeBSD__ + error = bind(fd, (struct sockaddr *)&addr, SUN_LEN(&addr)); +#else + error = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); +#endif + if (error == -1) { + warn("connect"); +#ifdef __FreeBSD__ + (void)close(fd); +#endif + return EXIT_FAILURE; + } + + close(fd); + + return EXIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ + +int +statvfs_main(int argc, char **argv) +{ + int error; + struct statvfs buf; + + if (argc < 2) + return EXIT_FAILURE; + + error = statvfs(argv[1], &buf); + if (error != 0) { + warn("statvfs"); + return EXIT_FAILURE; + } + + (void)printf("f_bsize=%lu\n", buf.f_bsize); + (void)printf("f_blocks=%" PRId64 "\n", buf.f_blocks); + (void)printf("f_bfree=%" PRId64 "\n", buf.f_bfree); + (void)printf("f_files=%" PRId64 "\n", buf.f_files); + + return EXIT_SUCCESS; +} + +/* --------------------------------------------------------------------- */ + +int +main(int argc, char **argv) +{ + int error; + + if (argc < 2) + return EXIT_FAILURE; + + argc -= 1; + argv += 1; + + if (strcmp(argv[0], "getfh") == 0) + error = getfh_main(argc, argv); + else if (strcmp(argv[0], "kqueue") == 0) + error = kqueue_main(argc, argv); + else if (strcmp(argv[0], "rename") == 0) + error = rename_main(argc, argv); + else if (strcmp(argv[0], "sockets") == 0) + error = sockets_main(argc, argv); + else if (strcmp(argv[0], "statvfs") == 0) + error = statvfs_main(argc, argv); + else + error = EXIT_FAILURE; + + return error; +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_create.sh b/contrib/netbsd-tests/fs/tmpfs/t_create.sh new file mode 100755 index 0000000..f1f894d --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_create.sh @@ -0,0 +1,122 @@ +# $NetBSD: t_create.sh,v 1.8 2011/03/05 07:41:11 pooka Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that the create operation works. +# + +atf_test_case create +create_head() { + atf_set "descr" "Verifies that files can be created" + atf_set "require.user" "root" +} +create_body() { + test_mount + + atf_check -s eq:1 -o empty -e empty test -f a + atf_check -s eq:0 -o empty -e empty touch a + atf_check -s eq:0 -o empty -e empty test -f a + + test_unmount +} + +atf_test_case attrs +attrs_head() { + atf_set "descr" "Verifies that a new file gets the correct" \ + "attributes" + atf_set "require.config" "unprivileged-user" + atf_set "require.user" "root" +} +attrs_body() { + user=$(atf_config_get unprivileged-user) + # Allow the unprivileged user to access the work directory. + chown ${user} . + + test_mount + + umask 022 + atf_check -s eq:1 -o empty -e empty test -f a + atf_check -s eq:0 -o empty -e empty touch a + atf_check -s eq:0 -o empty -e empty test -f a + + eval $(stat -s . | sed -e 's|st_|dst_|g') + eval $(stat -s a) + test ${st_flags} -eq 0 || atf_fail "Incorrect flags" + test ${st_size} -eq 0 || atf_fail "Incorrect size" + test ${st_uid} -eq $(id -u) || atf_fail "Incorrect uid" + test ${st_gid} -eq ${dst_gid} || atf_fail "Incorrect gid" + test ${st_mode} = 0100644 || atf_fail "Incorrect mode" + + atf_check -s eq:0 -o empty -e empty mkdir b c + + atf_check -s eq:0 -o empty -e empty chown ${user}:0 b + eval $(stat -s b) + [ ${st_uid} -eq $(id -u ${user}) ] || atf_fail "Incorrect owner" + [ ${st_gid} -eq 0 ] || atf_fail "Incorrect group" + + atf_check -s eq:0 -o empty -e empty chown ${user}:100 c + eval $(stat -s c) + [ ${st_uid} -eq $(id -u ${user}) ] || atf_fail "Incorrect owner" + [ ${st_gid} -eq 100 ] || atf_fail "Incorrect group" + + atf_check -s eq:0 -o empty -e empty su -m ${user} -c 'touch b/a' + eval $(stat -s b/a) + [ ${st_uid} -eq $(id -u ${user}) ] || atf_fail "Incorrect owner" + [ ${st_gid} -eq 0 ] || atf_fail "Incorrect group" + + atf_check -s eq:0 -o empty -e empty su -m ${user} -c 'touch c/a' + eval $(stat -s c/a) + [ ${st_uid} -eq $(id -u ${user}) ] || atf_fail "Incorrect owner" + [ ${st_gid} -eq 100 ] || atf_fail "Incorrect group" + + test_unmount +} + +atf_test_case kqueue +kqueue_head() { + atf_set "descr" "Verifies that creating a file raises the correct" \ + "kqueue events" + atf_set "require.user" "root" +} +kqueue_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir dir + echo 'touch dir/a' | kqueue_monitor 1 dir + kqueue_check dir NOTE_WRITE + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case create + atf_add_test_case attrs + atf_add_test_case kqueue +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_devices.sh b/contrib/netbsd-tests/fs/tmpfs/t_devices.sh new file mode 100755 index 0000000..472d378 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_devices.sh @@ -0,0 +1,60 @@ +# $NetBSD: t_devices.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() { + atf_set "descr" "Tests that special devices work" + atf_set "require.user" "root" +} +basic_body() { + test_mount + + umask 022 + + atf_check -s eq:0 -o ignore -e ignore /dev/MAKEDEV std + atf_check -s eq:0 -o empty -e empty test -e zero + atf_check -s eq:0 -o empty -e empty test -e null + + echo "Reading from the 'zero' character device" + atf_check -s eq:0 -o ignore -e ignore dd if=zero of=a bs=10k count=1 + [ $(md5 a | cut -d ' ' -f 4) = 1276481102f218c981e0324180bafd9f ] || \ + atf_fail "Data read is invalid" + + echo "Writing to the 'null' device" + echo foo >null + eval $(stat -s null) + [ ${st_size} -eq 0 ] || atf_fail "Invalid size for device" + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_dots.sh b/contrib/netbsd-tests/fs/tmpfs/t_dots.sh new file mode 100755 index 0000000..e480de7 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_dots.sh @@ -0,0 +1,67 @@ +# $NetBSD: t_dots.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case topdir +topdir_head() { + atf_set "descr" "Verifies that looking up '.' and '..' in" \ + "top-level directories works" + atf_set "require.user" "root" +} +topdir_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:0 -o empty -e empty test -d ./a + atf_check -s eq:0 -o empty -e empty test -d a/../a + + test_unmount +} + +atf_test_case nesteddir +nesteddir_head() { + atf_set "descr" "Verifies that looking up '.' and '..' in" \ + "top-level directories works" + atf_set "require.user" "root" +} +nesteddir_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:0 -o empty -e empty mkdir a/b + atf_check -s eq:0 -o empty -e empty test -d a/b/../b + atf_check -s eq:0 -o empty -e empty test -d a/b/../../a + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case topdir + atf_add_test_case nesteddir +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_exec.sh b/contrib/netbsd-tests/fs/tmpfs/t_exec.sh new file mode 100755 index 0000000..9ffc600 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_exec.sh @@ -0,0 +1,52 @@ +# $NetBSD: t_exec.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() { + atf_set "descr" "Verifies that binary files can be executed from" \ + "within the file system (i.e., whether getpages" \ + "works)" + atf_set "require.user" "root" +} +basic_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty cp /bin/cp . + echo "Verifying copied file" + [ $(md5 cp | cut -d ' ' -f 4) = $(md5 /bin/cp | cut -d ' ' -f 4) ] || \ + atf_file "New binary file does not match original" + atf_check -s eq:0 -o empty -e empty ./cp cp foo + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_link.sh b/contrib/netbsd-tests/fs/tmpfs/t_link.sh new file mode 100755 index 0000000..612c1e2 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_link.sh @@ -0,0 +1,144 @@ +# $NetBSD: t_link.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that the link operation works. +# + +atf_test_case basic +basic_head() { + atf_set "descr" "Verifies that the link operation works on files" \ + "at the top directory" + atf_set "require.user" "root" +} +basic_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty touch a + atf_check -s eq:0 -o empty -e empty touch z + eval $(stat -s a | sed -e 's|st_|sta_|g') + eval $(stat -s z | sed -e 's|st_|stz_|g') + test ${sta_ino} != ${stz_ino} || \ + atf_fail "Node numbers are not different" + test ${sta_nlink} -eq 1 || atf_fail "Number of links is incorrect" + atf_check -s eq:0 -o empty -e empty ln a b + + echo "Checking if link count is correct after links are created" + eval $(stat -s a | sed -e 's|st_|sta_|g') + eval $(stat -s b | sed -e 's|st_|stb_|g') + test ${sta_ino} = ${stb_ino} || atf_fail "Node number changed" + test ${sta_nlink} -eq 2 || atf_fail "Link count is incorrect" + test ${stb_nlink} -eq 2 || atf_fail "Link count is incorrect" + + echo "Checking if link count is correct after links are deleted" + atf_check -s eq:0 -o empty -e empty rm a + eval $(stat -s b | sed -e 's|st_|stb_|g') + test ${stb_nlink} -eq 1 || atf_fail "Link count is incorrect" + atf_check -s eq:0 -o empty -e empty rm b + + test_unmount +} + +atf_test_case subdirs +subdirs_head() { + atf_set "descr" "Verifies that the link operation works if used" \ + "in subdirectories" + atf_set "require.user" "root" +} +subdirs_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty touch a + atf_check -s eq:0 -o empty -e empty mkdir c + atf_check -s eq:0 -o empty -e empty ln a c/b + + echo "Checking if link count is correct after links are created" + eval $(stat -s a | sed -e 's|st_|sta_|g') + eval $(stat -s c/b | sed -e 's|st_|stb_|g') + test ${sta_ino} = ${stb_ino} || atf_fail "Node number changed" + test ${sta_nlink} -eq 2 || atf_fail "Link count is incorrect" + test ${stb_nlink} -eq 2 || atf_fail "Link count is incorrect" + + echo "Checking if link count is correct after links are deleted" + atf_check -s eq:0 -o empty -e empty rm a + eval $(stat -s c/b | sed -e 's|st_|stb_|g') + test ${stb_nlink} -eq 1 || atf_fail "Link count is incorrect" + atf_check -s eq:0 -o empty -e empty rm c/b + atf_check -s eq:0 -o empty -e empty rmdir c + + test_unmount +} + +# Begin FreeBSD +if true; then +atf_test_case kqueue cleanup +kqueue_cleanup() { + Mount_Point=$(pwd)/mntpt _test_unmount || : +} +else +# End FreeBSD +atf_test_case kqueue +# Begin FreeBSD +fi +# End FreeBSD +kqueue_head() { + atf_set "descr" "Verifies that creating a link raises the correct" \ + "kqueue events" + atf_set "require.user" "root" +} +kqueue_body() { + test_mount + + # Begin FreeBSD + atf_expect_fail "fails with: dir/b did not receive NOTE_LINK - bug 213662" + # End FreeBSD + + atf_check -s eq:0 -o empty -e empty mkdir dir + atf_check -s eq:0 -o empty -e empty touch dir/a + echo 'ln dir/a dir/b' | kqueue_monitor 2 dir dir/a + kqueue_check dir/a NOTE_LINK + kqueue_check dir NOTE_WRITE + + echo 'rm dir/a' | kqueue_monitor 2 dir dir/b + # XXX According to the (short) kqueue(2) documentation, the following + # should raise a NOTE_LINK but FFS raises a NOTE_DELETE... + kqueue_check dir/b NOTE_LINK + kqueue_check dir NOTE_WRITE + atf_check -s eq:0 -o empty -e empty rm dir/b + atf_check -s eq:0 -o empty -e empty rmdir dir + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case basic + atf_add_test_case subdirs + atf_add_test_case kqueue +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_mkdir.sh b/contrib/netbsd-tests/fs/tmpfs/t_mkdir.sh new file mode 100755 index 0000000..db0d1e3 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_mkdir.sh @@ -0,0 +1,159 @@ +# $NetBSD: t_mkdir.sh,v 1.8 2011/03/05 07:41:11 pooka Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that mkdir works by creating some nested directories. It also +# checks, in part, the lookup operation. +# + +atf_test_case single +single_head() { + atf_set "descr" "Creates a single directory and checks the" \ + "mount point's hard link count" + atf_set "require.user" "root" +} +single_body() { + test_mount + + atf_check -s eq:1 -o empty -e empty test -d a + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:0 -o empty -e empty test -d a + test -d a + eval $(stat -s ${Mount_Point}) + [ ${st_nlink} = 3 ] || atf_fail "Link count is not 3" + + test_unmount +} + +atf_test_case many +many_head() { + atf_set "descr" "Creates multiple directories and checks the" \ + "mount point's hard link count" + atf_set "require.user" "root" +} +many_body() { + test_mount + + for d in $(jot 100); do + atf_check -s eq:1 -o empty -e empty test -d ${d} + atf_check -s eq:0 -o empty -e empty mkdir ${d} + atf_check -s eq:0 -o empty -e empty test -d ${d} + done + eval $(stat -s ${Mount_Point}) + [ ${st_nlink} = 102 ] || atf_fail "Link count is not 102" + + test_unmount +} + +atf_test_case nested +nested_head() { + atf_set "descr" "Checks if nested directories can be created" + atf_set "require.user" "root" +} +nested_body() { + test_mount + + atf_check -s eq:1 -o empty -e empty test -d a/b/c/d/e + atf_check -s eq:0 -o empty -e empty mkdir -p a/b/c/d/e + atf_check -s eq:0 -o empty -e empty test -d a/b/c/d/e + + test_unmount +} + +atf_test_case attrs +attrs_head() { + atf_set "descr" "Checks that new directories get the proper" \ + "attributes (owner and group)" + atf_set "require.config" "unprivileged-user" + atf_set "require.user" "root" +} +attrs_body() { + user=$(atf_config_get unprivileged-user) + # Allow the unprivileged user to access the work directory. + chown ${user} . + + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir b c + + atf_check -s eq:0 -o empty -e empty chown ${user}:0 b + eval $(stat -s b) + [ ${st_uid} -eq $(id -u ${user}) ] || atf_fail "Incorrect owner" + [ ${st_gid} -eq 0 ] || atf_fail "Incorrect group" + + atf_check -s eq:0 -o empty -e empty chown ${user}:100 c + eval $(stat -s c) + [ ${st_uid} -eq $(id -u ${user}) ] || atf_fail "Incorrect owner" + [ ${st_gid} -eq 100 ] || atf_fail "Incorrect group" + + atf_check -s eq:0 -o empty -e empty su -m ${user} -c 'mkdir b/a' + eval $(stat -s b/a) + [ ${st_uid} -eq $(id -u ${user}) ] || atf_fail "Incorrect owner" + [ ${st_gid} -eq 0 ] || atf_fail "Incorrect group" + + atf_check -s eq:0 -o empty -e empty su -m ${user} -c 'mkdir c/a' + eval $(stat -s c/a) + [ ${st_uid} -eq $(id -u ${user}) ] || atf_fail "Incorrect owner" + [ ${st_gid} -eq 100 ] || atf_fail "Incorrect group" + + test_unmount +} + +atf_test_case kqueue +kqueue_head() { + atf_set "descr" "Creates a directory and checks the kqueue events" \ + "raised" + atf_set "require.user" "root" +} +kqueue_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir dir + echo 'mkdir dir/a' | kqueue_monitor 2 dir + + # Creating a directory raises NOTE_LINK on the parent directory + kqueue_check dir NOTE_LINK + + # Creating a directory raises NOTE_WRITE on the parent directory + kqueue_check dir NOTE_WRITE + + atf_check -s eq:0 -o empty -e empty rmdir dir/a + atf_check -s eq:0 -o empty -e empty rmdir dir + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case single + atf_add_test_case many + atf_add_test_case nested + atf_add_test_case attrs + atf_add_test_case kqueue +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_mknod.sh b/contrib/netbsd-tests/fs/tmpfs/t_mknod.sh new file mode 100755 index 0000000..62c7cce --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_mknod.sh @@ -0,0 +1,143 @@ +# $NetBSD: t_mknod.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that the mknod operation works. +# + +atf_test_case block +block_head() { + atf_set "descr" "Tests that block devices can be created" + atf_set "require.user" "root" +} +block_body() { + test_mount + umask 022 + + atf_check -s eq:0 -o empty -e empty mknod fd0a b 2 0 + eval $(stat -s fd0a) + [ ${st_mode} = 060644 ] || atf_fail "Invalid mode" + [ ${st_rdev} -eq 512 ] || atf_fail "Invalid device" + + test_unmount +} + +atf_test_case block_kqueue +block_kqueue_head() { + atf_set "descr" "Tests that creating a block device raises the" \ + "appropriate kqueue events" + atf_set "require.user" "root" +} +block_kqueue_body() { + test_mount + umask 022 + + atf_check -s eq:0 -o empty -e empty mkdir dir + echo 'mknod dir/fd0a b 2 0' | kqueue_monitor 1 dir + kqueue_check dir NOTE_WRITE + + test_unmount +} + +atf_test_case char +char_head() { + atf_set "descr" "Tests that character devices can be created" + atf_set "require.user" "root" +} +char_body() { + test_mount + umask 022 + + atf_check -s eq:0 -o empty -e empty mknod null c 2 2 + eval $(stat -s null) + [ ${st_mode} = 020644 ] || atf_fail "Invalid mode" + [ ${st_rdev} -eq 514 ] || atf_fail "Invalid device" + + test_unmount +} + +atf_test_case char_kqueue +char_kqueue_head() { + atf_set "descr" "Tests that creating a character device raises the" \ + "appropriate kqueue events" + atf_set "require.user" "root" +} +char_kqueue_body() { + test_mount + umask 022 + + atf_check -s eq:0 -o empty -e empty mkdir dir + echo 'mknod dir/null c 2 2' | kqueue_monitor 1 dir + kqueue_check dir NOTE_WRITE + + test_unmount +} + +atf_test_case pipe +pipe_head() { + atf_set "descr" "Tests that named pipes can be created" + atf_set "require.user" "root" +} +pipe_body() { + test_mount + umask 022 + + atf_check -s eq:0 -o empty -e empty mknod pipe p + eval $(stat -s pipe) + [ ${st_mode} = 010644 ] || atf_fail "Invalid mode" + + test_unmount +} + +atf_test_case pipe_kqueue +pipe_kqueue_head() { + atf_set "descr" "Tests that creating a named pipe raises the" \ + "appropriate kqueue events" + atf_set "require.user" "root" +} +pipe_kqueue_body() { + test_mount + umask 022 + + atf_check -s eq:0 -o empty -e empty mkdir dir + echo 'mknod dir/pipe p' | kqueue_monitor 1 dir + kqueue_check dir NOTE_WRITE + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case block + atf_add_test_case block_kqueue + atf_add_test_case char + atf_add_test_case char_kqueue + atf_add_test_case pipe + atf_add_test_case pipe_kqueue +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_mount.sh b/contrib/netbsd-tests/fs/tmpfs/t_mount.sh new file mode 100755 index 0000000..9ec5e31 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_mount.sh @@ -0,0 +1,156 @@ +# $NetBSD: t_mount.sh,v 1.6 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that an execution of mount and umount works correctly without +# causing errors and that the root node gets correct attributes. +# Also verifies command line parsing from mount_tmpfs. +# + +atf_test_case plain +plain_head() { + atf_set "descr" "Tests a mount and unmount without any options" + atf_set "require.user" "root" +} +plain_body() { + test_mount + test_unmount +} + +atf_test_case links +links_head() { + atf_set "descr" "Tests that the mount point has two hard links" + atf_set "require.user" "root" +} +links_body() { + test_mount + eval $(stat -s ${Mount_Point}) + [ ${st_nlink} = 2 ] || \ + atf_fail "Root directory does not have two hard links" + test_unmount +} + +atf_test_case options +options_head() { + atf_set "descr" "Tests the read-only mount option" + atf_set "require.user" "root" +} +options_body() { + test_mount -o ro + mount | grep ${Mount_Point} | grep -q read-only || \ + atf_fail "read-only option (ro) does not work" + test_unmount +} + +atf_test_case attrs +attrs_head() { + atf_set "descr" "Tests that root directory attributes are set" \ + "correctly" + atf_set "require.user" "root" +} +attrs_body() { + test_mount -o -u1000 -o -g100 -o -m755 + eval $(stat -s ${Mount_Point}) + [ ${st_uid} = 1000 ] || atf_fail "uid is incorrect" + [ ${st_gid} = 100 ] || atf_fail "gid is incorrect" + [ ${st_mode} = 040755 ] || atf_fail "mode is incorrect" + test_unmount +} + +atf_test_case negative +negative_head() { + atf_set "descr" "Tests that negative values passed to to -s are" \ + "handled correctly" + atf_set "require.user" "root" +} +negative_body() { + mkdir tmp + test_mount -o -s-10 + test_unmount +} + +# Begin FreeBSD +if true; then +atf_test_case large cleanup +large_cleanup() { + umount -f tmp 2>/dev/null || : + Mount_Point=$(pwd)/mnt _test_unmount || : +} +else +# End FreeBSD +atf_test_case large +# Begin FreeBSD +fi +# End FreeBSD +large_head() { + atf_set "descr" "Tests that extremely long values passed to -s" \ + "are handled correctly" + atf_set "require.user" "root" +} +large_body() { + test_mount -o -s9223372036854775807 + test_unmount + + # Begin FreeBSD + atf_expect_fail "-o -s succeeds unexpectedly on FreeBSD - bug 212862" + # End FreeBSD + + mkdir tmp + atf_check -s eq:1 -o empty -e ignore \ + mount -t tmpfs -o -s9223372036854775808 tmpfs tmp + atf_check -s eq:1 -o empty -e ignore \ + mount -t tmpfs -o -s9223372036854775808g tmpfs tmp + rmdir tmp +} + +atf_test_case mntpt +mntpt_head() { + atf_set "descr" "Tests that the error messages printed when the" \ + "mount point is invalid do not show the source" \ + "unused parameter" +} +mntpt_body() { + mount_tmpfs unused $(pwd)/mnt >out 2>&1 + atf_check -s eq:1 -o empty -e empty grep unused out + atf_check -s eq:0 -o ignore -e empty grep "$(pwd)/mnt" out + + mount_tmpfs unused mnt >out 2>&1 + atf_check -s eq:1 -o empty -e empty grep unused out + atf_check -s eq:0 -o ignore -e empty grep mnt out +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case plain + atf_add_test_case options + atf_add_test_case attrs + atf_add_test_case negative + atf_add_test_case large + atf_add_test_case mntpt +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_pipes.sh b/contrib/netbsd-tests/fs/tmpfs/t_pipes.sh new file mode 100755 index 0000000..7c0065a --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_pipes.sh @@ -0,0 +1,52 @@ +# $NetBSD: t_pipes.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() { + atf_set "descr" "Verifies that pipes work" + atf_set "require.user" "root" +} +basic_body() { + test_mount + + umask 022 + + atf_check -s eq:0 -o empty -e empty mknod pipe p + + echo "Writing to pipe and waiting for response" + echo -n foo >pipe & + [ "$(cat pipe)" = foo ] || atf_fail "Received data is incorrect" + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_read_write.sh b/contrib/netbsd-tests/fs/tmpfs/t_read_write.sh new file mode 100755 index 0000000..13cc256 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_read_write.sh @@ -0,0 +1,87 @@ +# $NetBSD: t_read_write.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that the read and write operations work. +# + +atf_test_case basic +basic_head() { + atf_set "descr" "Checks that file removal works" + atf_set "require.user" "root" +} +basic_body() { + test_mount + + echo "Testing write to a small file" + echo foo >a || atf_fail "Failed to write to file" + [ $(md5 a | cut -d ' ' -f 4) = d3b07384d113edec49eaa6238ad5ff00 ] || \ + atf_fail "Invalid file contents" + + echo "Testing appending to a small file" + echo bar >>a || atf_fail "Failed to append data to file" + [ $(md5 a | cut -d ' ' -f 4) = f47c75614087a8dd938ba4acff252494 ] || \ + atf_fail "Invalid file contents" + + echo "Testing write to a big file (bigger than a page)" + jot 10000 >b || atf_fail "Failed to create a big file" + [ $(md5 b | cut -d ' ' -f 4) = 72d4ff27a28afbc066d5804999d5a504 ] || \ + atf_fail "Invalid file contents" + + test_unmount +} + +atf_test_case kqueue +kqueue_head() { + atf_set "descr" "Checks that writing to a file raises the" \ + "appropriate kqueue events" + atf_set "require.user" "root" +} +kqueue_body() { + test_mount + + atf_check -s eq:0 -o ignore -e ignore \ + dd if=/dev/zero of=c bs=1k count=10 + echo 'dd if=/dev/zero of=c seek=2 bs=1k count=1 conv=notrunc' \ + '>/dev/null 2>&1' | kqueue_monitor 1 c + kqueue_check c NOTE_WRITE + + echo foo >d + echo 'echo bar >>d' | kqueue_monitor 2 d + kqueue_check d NOTE_EXTEND + kqueue_check d NOTE_WRITE + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case basic + atf_add_test_case kqueue +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_readdir.sh b/contrib/netbsd-tests/fs/tmpfs/t_readdir.sh new file mode 100755 index 0000000..6f5dc3e --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_readdir.sh @@ -0,0 +1,116 @@ +# $NetBSD: t_readdir.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that the readdir operation works. +# + +atf_test_case dots +dots_head() { + atf_set "descr" "Verifies that readdir returns the '.' and '..'" \ + "entries" + atf_set "require.user" "root" +} +dots_body() { + test_mount + + atf_check -s eq:0 -o save:stdout -e empty /bin/ls -a + atf_check -s eq:0 -o ignore -e empty grep '^\.$' stdout + atf_check -s eq:0 -o ignore -e empty grep '^\..$' stdout + + test_unmount +} + +atf_test_case types +types_head() { + atf_set "descr" "Verifies that readdir works for all different" \ + "file types" + atf_set "require.user" "root" +} +types_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir dir + atf_check -s eq:0 -o empty -e empty touch reg + atf_check -s eq:0 -o empty -e empty ln -s reg lnk + atf_check -s eq:0 -o empty -e empty mknod blk b 0 0 + atf_check -s eq:0 -o empty -e empty mknod chr c 0 0 + atf_check -s eq:0 -o empty -e empty mknod fifo p + atf_check -s eq:0 -o empty -e empty \ + $(atf_get_srcdir)/h_tools sockets sock + + atf_check -s eq:0 -o ignore -e empty ls + atf_check -s eq:0 -o empty -e empty rm -rf * + + test_unmount +} + +atf_test_case caching +caching_head() { + atf_set "descr" "Catch a bug caused by incorrect invalidation of" \ + "readdir caching variables" + atf_set "require.user" "root" +} +caching_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty touch $(jot 10) + atf_check -s eq:0 -o empty -e empty rm * + atf_check -s eq:0 -o empty -e empty touch $(jot 20) + atf_check -s eq:0 -o empty -e empty -x "ls >/dev/null" + + test_unmount +} + +atf_test_case many +many_head() { + atf_set "descr" "Verifies that readdir works with many files" + atf_set "require.user" "root" +} +many_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + echo "Creating 500 files" + for f in $(jot 500); do + touch a/$f + done + atf_check -s eq:0 -o empty -e empty rm a/* + atf_check -s eq:0 -o empty -e empty rmdir a + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case dots + atf_add_test_case types + atf_add_test_case caching + atf_add_test_case many +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_remove.sh b/contrib/netbsd-tests/fs/tmpfs/t_remove.sh new file mode 100755 index 0000000..f75032c --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_remove.sh @@ -0,0 +1,125 @@ +# $NetBSD: t_remove.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that the remove operation works. +# + +atf_test_case single +single_head() { + atf_set "descr" "Checks that file removal works" + atf_set "require.user" "root" +} +single_body() { + test_mount + + atf_check -s eq:1 -o empty -e empty test -f a + atf_check -s eq:0 -o empty -e empty touch a + atf_check -s eq:0 -o empty -e empty test -f a + atf_check -s eq:0 -o empty -e empty rm a + atf_check -s eq:1 -o empty -e empty test -f a + + test_unmount +} + +# Begin FreeBSD +if true; then +atf_test_case uchg cleanup +uchg_cleanup() { + Mount_Point=$(pwd)/mntpt _test_unmount +} +else +# End FreeBSD +atf_test_case uchg +# Begin FreeBSD +fi +# End FreeBSD +uchg_head() { + atf_set "descr" "Checks that files with the uchg flag set cannot" \ + "be removed" + atf_set "require.user" "root" +} +uchg_body() { + # Begin FreeBSD + atf_expect_fail "this fails on FreeBSD with root - bug 212861" + # End FreeBSD + + test_mount + + atf_check -s eq:0 -o empty -e empty touch a + atf_check -s eq:0 -o empty -e empty chflags uchg a + atf_check -s eq:1 -o empty -e ignore rm -f a + atf_check -s eq:0 -o empty -e empty chflags nouchg a + atf_check -s eq:0 -o empty -e empty rm a + atf_check -s eq:1 -o empty -e empty test -f a + + test_unmount +} + +atf_test_case dot +dot_head() { + atf_set "descr" "Checks that '.' cannot be removed" + atf_set "require.user" "root" +} +dot_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:1 -o empty -e ignore unlink a/. + atf_check -s eq:0 -o empty -e empty rmdir a + + test_unmount +} + +atf_test_case kqueue +kqueue_head() { + atf_set "descr" "Removes a file and checks the kqueue events" \ + "raised" + atf_set "require.user" "root" +} +kqueue_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir dir + atf_check -s eq:0 -o empty -e empty touch dir/a + echo 'rm dir/a' | kqueue_monitor 2 dir dir/a + kqueue_check dir/a NOTE_DELETE + kqueue_check dir NOTE_WRITE + atf_check -s eq:0 -o empty -e empty rmdir dir + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case single + atf_add_test_case uchg + atf_add_test_case dot + atf_add_test_case kqueue +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_rename.sh b/contrib/netbsd-tests/fs/tmpfs/t_rename.sh new file mode 100755 index 0000000..7613f1f --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_rename.sh @@ -0,0 +1,278 @@ +# $NetBSD: t_rename.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that the rename operation works (either by renaming entries or +# by moving them). +# + +atf_test_case dots +dots_head() { + atf_set "descr" "Tests that '.' and '..' cannot be renamed" + atf_set "require.user" "root" +} +dots_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:1 -o empty -e ignore mv a/. c + atf_check -s eq:1 -o empty -e ignore mv a/.. c + atf_check -s eq:0 -o empty -e empty rmdir a + + test_unmount +} + +atf_test_case crossdev +crossdev_head() { + atf_set "descr" "Tests that cross-device renames do not work" + atf_set "require.user" "root" +} +crossdev_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:1 -o empty -e save:stderr \ + $(atf_get_srcdir)/h_tools rename a /var/tmp/a + atf_check -s eq:0 -o ignore -e empty grep "Cross-device link" stderr + atf_check -s eq:0 -o empty -e empty test -d a + atf_check -s eq:0 -o empty -e empty rmdir a + + test_unmount +} + +atf_test_case basic +basic_head() { + atf_set "descr" "Tests that basic renames work" + atf_set "require.user" "root" +} +basic_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:0 -o empty -e empty mv a c + atf_check -s eq:1 -o empty -e empty test -d a + atf_check -s eq:0 -o empty -e empty test -d c + atf_check -s eq:0 -o empty -e empty rmdir c + + test_unmount +} + +atf_test_case dotdot +dotdot_head() { + atf_set "descr" "Tests that the '..' entry is properly updated" \ + "during moves" + atf_set "require.user" "root" +} +dotdot_body() { + test_mount + + echo "Checking if the '..' entry is updated after moves" + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:0 -o empty -e empty mkdir b + atf_check -s eq:0 -o empty -e empty mv b a + atf_check -s eq:0 -o empty -e empty test -d a/b/../b + atf_check -s eq:0 -o empty -e empty test -d a/b/../../a + eval $(stat -s a/b) + [ ${st_nlink} = 2 ] || atf_fail "Incorrect number of links" + eval $(stat -s a) + [ ${st_nlink} = 3 ] || atf_fail "Incorrect number of links" + atf_check -s eq:0 -o empty -e empty rmdir a/b + atf_check -s eq:0 -o empty -e empty rmdir a + + echo "Checking if the '..' entry is correct after renames" + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:0 -o empty -e empty mkdir b + atf_check -s eq:0 -o empty -e empty mv b a + atf_check -s eq:0 -o empty -e empty mv a c + atf_check -s eq:0 -o empty -e empty test -d c/b/../b + atf_check -s eq:0 -o empty -e empty test -d c/b/../../c + atf_check -s eq:0 -o empty -e empty rmdir c/b + atf_check -s eq:0 -o empty -e empty rmdir c + + echo "Checking if the '..' entry is correct after multiple moves" + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:0 -o empty -e empty mkdir b + atf_check -s eq:0 -o empty -e empty mv b a + atf_check -s eq:0 -o empty -e empty mv a c + atf_check -s eq:0 -o empty -e empty mv c/b d + atf_check -s eq:0 -o empty -e empty test -d d/../c + atf_check -s eq:0 -o empty -e empty rmdir d + atf_check -s eq:0 -o empty -e empty rmdir c + + test_unmount +} + +atf_test_case dir_to_emptydir +dir_to_emptydir_head() { + atf_set "descr" "Tests that renaming a directory to override an" \ + "empty directory works" + atf_set "require.user" "root" +} +dir_to_emptydir_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:0 -o empty -e empty touch a/c + atf_check -s eq:0 -o empty -e empty mkdir b + atf_check -s eq:0 -o empty -e empty \ + $(atf_get_srcdir)/h_tools rename a b + atf_check -s eq:1 -o empty -e empty test -e a + atf_check -s eq:0 -o empty -e empty test -d b + atf_check -s eq:0 -o empty -e empty test -f b/c + rm b/c + rmdir b + + test_unmount +} + +atf_test_case dir_to_fulldir +dir_to_fulldir_head() { + atf_set "descr" "Tests that renaming a directory to override a" \ + "non-empty directory fails" + atf_set "require.user" "root" +} +dir_to_fulldir_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:0 -o empty -e empty touch a/c + atf_check -s eq:0 -o empty -e empty mkdir b + atf_check -s eq:0 -o empty -e empty touch b/d + atf_check -s eq:1 -o empty -e save:stderr \ + $(atf_get_srcdir)/h_tools rename a b + atf_check -s eq:0 -o ignore -e empty grep "Directory not empty" stderr + atf_check -s eq:0 -o empty -e empty test -d a + atf_check -s eq:0 -o empty -e empty test -f a/c + atf_check -s eq:0 -o empty -e empty test -d b + atf_check -s eq:0 -o empty -e empty test -f b/d + rm a/c + rm b/d + rmdir a + rmdir b + + test_unmount +} + +atf_test_case dir_to_file +dir_to_file_head() { + atf_set "descr" "Tests that renaming a directory to override a" \ + "file fails" + atf_set "require.user" "root" +} +dir_to_file_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:0 -o empty -e empty touch b + atf_check -s eq:1 -o empty -e save:stderr \ + $(atf_get_srcdir)/h_tools rename a b + atf_check -s eq:0 -o ignore -e empty grep "Not a directory" stderr + atf_check -s eq:0 -o empty -e empty test -d a + atf_check -s eq:0 -o empty -e empty test -f b + rmdir a + rm b + + test_unmount +} + +atf_test_case file_to_dir +file_to_dir_head() { + atf_set "descr" "Tests that renaming a file to override a" \ + "directory fails" + atf_set "require.user" "root" +} +file_to_dir_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty touch a + atf_check -s eq:0 -o empty -e empty mkdir b + atf_check -s eq:1 -o empty -e save:stderr \ + $(atf_get_srcdir)/h_tools rename a b + atf_check -s eq:0 -o ignore -e empty grep "Is a directory" stderr + atf_check -s eq:0 -o empty -e empty test -f a + atf_check -s eq:0 -o empty -e empty test -d b + rm a + rmdir b + + test_unmount +} + +atf_test_case kqueue +kqueue_head() { + atf_set "descr" "Tests that moving and renaming files raise the" \ + "correct kqueue events" + atf_set "require.user" "root" +} +kqueue_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir dir + atf_check -s eq:0 -o empty -e empty touch dir/a + echo 'mv dir/a dir/b' | kqueue_monitor 2 dir dir/a + kqueue_check dir/a NOTE_RENAME + kqueue_check dir NOTE_WRITE + atf_check -s eq:0 -o empty -e empty rm dir/b + atf_check -s eq:0 -o empty -e empty rmdir dir + + atf_check -s eq:0 -o empty -e empty mkdir dir + atf_check -s eq:0 -o empty -e empty touch dir/a + atf_check -s eq:0 -o empty -e empty touch dir/b + echo 'mv dir/a dir/b' | kqueue_monitor 3 dir dir/a dir/b + kqueue_check dir/a NOTE_RENAME + kqueue_check dir NOTE_WRITE + kqueue_check dir/b NOTE_DELETE + atf_check -s eq:0 -o empty -e empty rm dir/b + atf_check -s eq:0 -o empty -e empty rmdir dir + + atf_check -s eq:0 -o empty -e empty mkdir dir1 + atf_check -s eq:0 -o empty -e empty mkdir dir2 + atf_check -s eq:0 -o empty -e empty touch dir1/a + echo 'mv dir1/a dir2/a' | kqueue_monitor 3 dir1 dir1/a dir2 + kqueue_check dir1/a NOTE_RENAME + kqueue_check dir1 NOTE_WRITE + kqueue_check dir2 NOTE_WRITE + atf_check -s eq:0 -o empty -e empty rm dir2/a + atf_check -s eq:0 -o empty -e empty rmdir dir1 + atf_check -s eq:0 -o empty -e empty rmdir dir2 + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case dots + atf_add_test_case crossdev + atf_add_test_case basic + atf_add_test_case dotdot + atf_add_test_case dir_to_emptydir + atf_add_test_case dir_to_fulldir + atf_add_test_case dir_to_file + atf_add_test_case file_to_dir + atf_add_test_case kqueue +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_renamerace.c b/contrib/netbsd-tests/fs/tmpfs/t_renamerace.c new file mode 100644 index 0000000..d7c10e4 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_renamerace.c @@ -0,0 +1,115 @@ +/* $NetBSD: t_renamerace.c,v 1.14 2017/01/13 21:30:40 christos Exp $ */ + +/* + * Modified for rump and atf from a program supplied + * by Nicolas Joly in kern/40948 + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(renamerace2); +ATF_TC_HEAD(renamerace2, tc) +{ + atf_tc_set_md_var(tc, "descr", "rename(2) lock order inversion"); + atf_tc_set_md_var(tc, "timeout", "6"); +} + +static volatile int quittingtime = 0; +static pid_t wrkpid; + +static void * +r2w1(void *arg) +{ + int fd; + + rump_pub_lwproc_newlwp(wrkpid); + + fd = rump_sys_open("/file", O_CREAT | O_RDWR, 0777); + if (fd == -1) + atf_tc_fail_errno("creat"); + rump_sys_close(fd); + + while (!quittingtime) { + if (rump_sys_rename("/file", "/dir/file") == -1) + atf_tc_fail_errno("rename 1"); + if (rump_sys_rename("/dir/file", "/file") == -1) + atf_tc_fail_errno("rename 2"); + } + + return NULL; +} + +static void * +r2w2(void *arg) +{ + int fd; + + rump_pub_lwproc_newlwp(wrkpid); + + while (!quittingtime) { + fd = rump_sys_open("/dir/file1", O_RDWR); + if (fd != -1) + rump_sys_close(fd); + } + + return NULL; +} + +ATF_TC_BODY(renamerace2, tc) +{ + struct tmpfs_args args; + pthread_t pt[2]; + + /* + * Force SMP regardless of how many host CPUs there are. + * Deadlock is highly unlikely to trigger otherwise. + */ + setenv("RUMP_NCPU", "2", 1); + + rump_init(); + memset(&args, 0, sizeof(args)); + args.ta_version = TMPFS_ARGS_VERSION; + args.ta_root_mode = 0777; + if (rump_sys_mount(MOUNT_TMPFS, "/", 0, &args, sizeof(args)) == -1) + atf_tc_fail_errno("could not mount tmpfs"); + + if (rump_sys_mkdir("/dir", 0777) == -1) + atf_tc_fail_errno("cannot create directory"); + + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + RL(wrkpid = rump_sys_getpid()); + pthread_create(&pt[0], NULL, r2w1, NULL); + pthread_create(&pt[1], NULL, r2w2, NULL); + + /* usually triggers in <<1s for me */ + sleep(4); + quittingtime = 1; + + pthread_join(pt[0], NULL); + pthread_join(pt[1], NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, renamerace2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_rmdir.sh b/contrib/netbsd-tests/fs/tmpfs/t_rmdir.sh new file mode 100755 index 0000000..9e5d761 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_rmdir.sh @@ -0,0 +1,204 @@ +# $NetBSD: t_rmdir.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that rmdir works by creating and removing directories. Also +# checks multiple error conditions. +# + +atf_test_case mntpt +mntpt_head() { + atf_set "descr" "Checks that the mount point cannot be removed" + atf_set "require.user" "root" +} +mntpt_body() { + test_mount + + atf_check -s eq:1 -o empty -e ignore rmdir ${Mount_Point} + + test_unmount +} + +atf_test_case non_existent +non_existent_head() { + atf_set "descr" "Checks that non-existent directories cannot" \ + "be removed" + atf_set "require.user" "root" +} +non_existent_body() { + test_mount + + atf_check -s eq:1 -o empty -e ignore rmdir non-existent + + test_unmount +} + +atf_test_case single +single_head() { + atf_set "descr" "Checks that removing a single directory works" + atf_set "require.user" "root" +} +single_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + eval $(stat -s ${Mount_Point}) + [ ${st_nlink} = 3 ] || \ + atf_fail "Incorrect number of links after creation" + atf_check -s eq:0 -o empty -e empty rmdir a + eval $(stat -s ${Mount_Point}) + [ ${st_nlink} = 2 ] || \ + atf_fail "Incorrect number of links after removal" + + test_unmount +} + +atf_test_case nested +nested_head() { + atf_set "descr" "Checks that removing nested directories works" + atf_set "require.user" "root" +} +nested_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir -p a/b/c + atf_check -s eq:0 -o empty -e empty rmdir a/b/c + atf_check -s eq:0 -o empty -e empty rmdir a/b + atf_check -s eq:0 -o empty -e empty rmdir a + + test_unmount +} + +atf_test_case dots +dots_head() { + atf_set "descr" "Checks that '.' and '..' cannot be removed" + atf_set "require.user" "root" +} +dots_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:1 -o empty -e ignore rmdir a/. + atf_check -s eq:1 -o empty -e ignore rmdir a/.. + atf_check -s eq:0 -o empty -e empty rmdir a + + test_unmount +} + +atf_test_case non_empty +non_empty_head() { + atf_set "descr" "Checks that non-empty directories cannot be removed" + atf_set "require.user" "root" +} +non_empty_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:0 -o empty -e empty mkdir a/b + atf_check -s eq:0 -o empty -e empty mkdir a/c + atf_check -s eq:1 -o empty -e ignore rmdir a + atf_check -s eq:0 -o empty -e empty rmdir a/b + atf_check -s eq:0 -o empty -e empty rmdir a/c + atf_check -s eq:0 -o empty -e empty rmdir a + + test_unmount +} + +atf_test_case links +links_head() { + atf_set "descr" "Checks the root directory's links after removals" + atf_set "require.user" "root" +} +links_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + atf_check -s eq:0 -o empty -e empty mkdir a/b + atf_check -s eq:0 -o empty -e empty mkdir c + + atf_check -s eq:0 -o empty -e empty rmdir c + atf_check -s eq:0 -o empty -e empty rmdir a/b + atf_check -s eq:0 -o empty -e empty rmdir a + + eval $(stat -s ${Mount_Point}) + [ ${st_nlink} = 2 ] || atf_fail "Incorrect number of links" + + test_unmount +} + +atf_test_case curdir +curdir_head() { + atf_set "descr" "Checks that the current directory cannot be removed" + atf_set "require.user" "root" +} +curdir_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a + # Catch a bug that would panic the system when accessing the + # current directory after being deleted: vop_open cannot assume + # that open files are still linked to a directory. + atf_check -s eq:1 -o empty -e ignore -x '( cd a && rmdir ../a && ls )' + atf_check -s eq:1 -o empty -e empty test -e a + + test_unmount +} + +atf_test_case kqueue +kqueue_head() { + atf_set "descr" "Checks that removing a directory raises the" \ + "correct kqueue events" + atf_set "require.user" "root" +} +kqueue_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir dir + atf_check -s eq:0 -o empty -e empty mkdir dir/a + echo 'rmdir dir/a' | kqueue_monitor 3 dir dir/a + kqueue_check dir/a NOTE_DELETE + kqueue_check dir NOTE_LINK + kqueue_check dir NOTE_WRITE + atf_check -s eq:0 -o empty -e empty rmdir dir + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case mntpt + atf_add_test_case non_existent + atf_add_test_case single + atf_add_test_case nested + atf_add_test_case dots + atf_add_test_case non_empty + atf_add_test_case links + atf_add_test_case curdir + atf_add_test_case kqueue +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_setattr.sh b/contrib/netbsd-tests/fs/tmpfs/t_setattr.sh new file mode 100755 index 0000000..f643446 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_setattr.sh @@ -0,0 +1,216 @@ +# $NetBSD: t_setattr.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that the setattr vnode operation works, using several commands +# that require this function. +# + +atf_test_case chown +chown_head() { + atf_set "descr" "Tests that the file owner can be changed" + atf_set "require.user" "root" +} +chown_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir own + eval $(stat -s own | sed -e 's|st_|ost_|g') + atf_check -s eq:0 -o empty -e empty chown 1234 own + eval $(stat -s own) + [ ${st_uid} -eq 1234 ] || atf_fail "uid was not set" + [ ${st_gid} -eq ${ost_gid} ] || atf_fail "gid was modified" + + test_unmount +} + +atf_test_case chown_kqueue +chown_kqueue_head() { + atf_set "descr" "Tests that changing the file owner raises" \ + "NOTE_ATTRIB on it" + atf_set "require.user" "root" +} +chown_kqueue_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir ownq + echo 'chown 1234 ownq' | kqueue_monitor 1 ownq + kqueue_check ownq NOTE_ATTRIB + + test_unmount +} + +atf_test_case chgrp +chgrp_head() { + atf_set "descr" "Tests that the file group can be changed" + atf_set "require.user" "root" +} +chgrp_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir grp + eval $(stat -s grp | sed -e 's|st_|ost_|g') + atf_check -s eq:0 -o empty -e empty chgrp 5678 grp + eval $(stat -s grp) + [ ${st_uid} -eq ${ost_uid} ] || atf_fail "uid was modified" + [ ${st_gid} -eq 5678 ] || atf_fail "gid was not set" + + test_unmount +} + +atf_test_case chgrp_kqueue +chgrp_kqueue_head() { + atf_set "descr" "Tests that changing the file group raises" \ + "NOTE_ATTRIB on it" + atf_set "require.user" "root" +} +chgrp_kqueue_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir grpq + echo 'chgrp 1234 grpq' | kqueue_monitor 1 grpq + kqueue_check grpq NOTE_ATTRIB + + test_unmount +} + +atf_test_case chowngrp +chowngrp_head() { + atf_set "descr" "Tests that the file owner and group can be" \ + "changed at once" + atf_set "require.user" "root" +} +chowngrp_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir owngrp + atf_check -s eq:0 -o empty -e empty chown 1234:5678 owngrp + eval $(stat -s owngrp) + [ ${st_uid} -eq 1234 ] || atf_fail "uid was not modified" + [ ${st_gid} -eq 5678 ] || atf_fail "gid was not modified" + + test_unmount +} + +atf_test_case chowngrp_kqueue +chowngrp_kqueue_head() { + atf_set "descr" "Tests that changing the file owner and group" \ + "raises NOTE_ATTRIB on it" + atf_set "require.user" "root" +} +chowngrp_kqueue_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir owngrpp + echo 'chown 1234:5678 owngrpp' | kqueue_monitor 1 owngrpp + kqueue_check owngrpp NOTE_ATTRIB + + test_unmount +} + +atf_test_case chmod +chmod_head() { + atf_set "descr" "Tests that the file mode can be changed" + atf_set "require.user" "root" +} +chmod_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir mode + atf_check -s eq:0 -o empty -e empty chmod 0000 mode + eval $(stat -s mode) + [ ${st_mode} -eq 40000 ] || af_fail "mode was not set" + + test_unmount +} + +atf_test_case chmod_kqueue +chmod_kqueue_head() { + atf_set "descr" "Tests that changing the file mode raises" \ + "NOTE_ATTRIB on it" + atf_set "require.user" "root" +} +chmod_kqueue_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir modeq + echo 'chmod 0000 modeq' | kqueue_monitor 1 modeq + kqueue_check modeq NOTE_ATTRIB + + test_unmount +} + +atf_test_case chtimes +chtimes_head() { + atf_set "descr" "Tests that file times can be changed" + atf_set "require.user" "root" +} +chtimes_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir times + atf_check -s eq:0 -o empty -e empty \ + -x 'TZ=GMT touch -t 200501010101 times' + eval $(stat -s times) + [ ${st_atime} = ${st_mtime} ] || \ + atf_fail "atime does not match mtime" + [ ${st_atime} = 1104541260 ] || atf_fail "atime does not match" + + test_unmount +} + +atf_test_case chtimes_kqueue +chtimes_kqueue_head() { + atf_set "descr" "Tests that changing the file times raises" \ + "NOTE_ATTRIB on it" + atf_set "require.user" "root" +} +chtimes_kqueue_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir timesq + echo 'touch timesq' | kqueue_monitor 1 timesq + kqueue_check timesq NOTE_ATTRIB + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case chown + atf_add_test_case chown_kqueue + atf_add_test_case chgrp + atf_add_test_case chgrp_kqueue + atf_add_test_case chowngrp + atf_add_test_case chowngrp_kqueue + atf_add_test_case chmod + atf_add_test_case chmod_kqueue + atf_add_test_case chtimes + atf_add_test_case chtimes_kqueue +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_sizes.sh b/contrib/netbsd-tests/fs/tmpfs/t_sizes.sh new file mode 100755 index 0000000..35abe8a --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_sizes.sh @@ -0,0 +1,139 @@ +# $NetBSD: t_sizes.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that the file system controls memory usage correctly. +# + +atf_test_case small +small_head() { + atf_set "descr" "Checks the status after creating a small file" + atf_set "require.user" "root" +} +small_body() { + test_mount -o -s10M + + echo a >a || atf_fail "Could not create file" + eval $($(atf_get_srcdir)/h_tools statvfs .) + f_bused=$((${f_blocks} - ${f_bfree})) + [ ${f_bused} -gt 1 ] || atf_fail "Incorrect bused count" + atf_check -s eq:0 -o empty -e empty rm a + + test_unmount +} + +atf_test_case big +big_head() { + atf_set "descr" "Checks the status after creating a big file" + atf_set "require.user" "root" +} +big_body() { + test_mount -o -s10M + + # Begin FreeBSD + if true; then + pagesize=$(sysctl -n hw.pagesize) + else + # End FreeBSD + pagesize=$(sysctl hw.pagesize | cut -d ' ' -f 3) + # Begin FreeBSD + fi + # End FreeBSD + eval $($(atf_get_srcdir)/h_tools statvfs . | sed -e 's|^f_|cf_|') + cf_bused=$((${cf_blocks} - ${cf_bfree})) + + atf_check -s eq:0 -o ignore -e ignore \ + dd if=/dev/zero of=a bs=1m count=5 + eval $($(atf_get_srcdir)/h_tools statvfs .) + f_bused=$((${f_blocks} - ${f_bfree})) + [ ${f_bused} -ne ${cf_bused} ] || atf_fail "bused did not change" + [ ${f_bused} -gt $((5 * 1024 * 1024 / ${pagesize})) ] || \ + atf_fail "bused too big" + of_bused=${f_bused} + atf_check -s eq:0 -o empty -e empty rm a + eval $($(atf_get_srcdir)/h_tools statvfs .) + f_bused=$((${f_blocks} - ${f_bfree})) + [ ${f_bused} -lt ${of_bused} ] || \ + atf_fail "bused was not correctly restored" + + test_unmount +} + +atf_test_case overflow +overflow_head() { + atf_set "descr" "Checks the status after creating a big file that" \ + "overflows the file system limits" + atf_set "require.user" "root" +} +overflow_body() { + test_mount -o -s10M + + atf_check -s eq:0 -o empty -e empty touch a + atf_check -s eq:0 -o empty -e empty rm a + eval $($(atf_get_srcdir)/h_tools statvfs .) + of_bused=$((${f_blocks} - ${f_bfree})) + atf_check -s eq:1 -o ignore -e ignore \ + dd if=/dev/zero of=a bs=1m count=15 + atf_check -s eq:0 -o empty -e empty rm a + eval $($(atf_get_srcdir)/h_tools statvfs .) + f_bused=$((${f_blocks} - ${f_bfree})) + [ ${f_bused} -ge ${of_bused} -a ${f_bused} -le $((${of_bused} + 1)) ] \ + || atf_fail "Incorrect bused" + + test_unmount +} + +atf_test_case overwrite +overwrite_head() { + atf_set "descr" "Checks that writing to the middle of a file" \ + "does not change its size" + atf_set "require.user" "root" +} +overwrite_body() { + test_mount -o -s10M + + atf_check -s eq:0 -o ignore -e ignore \ + dd if=/dev/zero of=a bs=1024 count=10 + sync + atf_check -s eq:0 -o ignore -e ignore \ + dd if=/dev/zero of=a bs=1024 conv=notrunc seek=1 count=1 + sync + eval $(stat -s a) + [ ${st_size} -eq 10240 ] || atf_fail "Incorrect file size" + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case small + atf_add_test_case big + atf_add_test_case overflow + atf_add_test_case overwrite +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_sockets.sh b/contrib/netbsd-tests/fs/tmpfs/t_sockets.sh new file mode 100755 index 0000000..6b97248 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_sockets.sh @@ -0,0 +1,52 @@ +# $NetBSD: t_sockets.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() { + atf_set "descr" "Verifies that sockets can be created using" \ + "socket/bind" + atf_set "require.user" "root" +} +basic_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty $(atf_get_srcdir)/h_tools sockets a + atf_check -s eq:0 -o empty -e empty rm a + + atf_check -s eq:0 -o empty -e empty mkdir dir + echo "$(atf_get_srcdir)/h_tools sockets dir/a" | kqueue_monitor 1 dir + kqueue_check dir NOTE_WRITE + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_statvfs.sh b/contrib/netbsd-tests/fs/tmpfs/t_statvfs.sh new file mode 100755 index 0000000..d0e7ac2 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_statvfs.sh @@ -0,0 +1,67 @@ +# $NetBSD: t_statvfs.sh,v 1.4 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that the statvfs system call works properly (returning the +# correct values) over a tmpfs mount point. +# + +atf_test_case values +values_head() { + atf_set "descr" "Tests that statvfs(2) returns correct values" + atf_set "require.user" "root" +} +values_body() { + test_mount -o -s10M + + # Begin FreeBSD + if true; then + pagesize=$(sysctl -n hw.pagesize) + else + # End FreeBSD + pagesize=$(sysctl hw.pagesize | cut -d ' ' -f 3) + # Begin FreeBSD + fi + # End FreeBSD + eval $($(atf_get_srcdir)/h_tools statvfs .) + [ ${pagesize} -eq ${f_bsize} ] || \ + atf_fail "Invalid bsize" + [ $((${f_bsize} * ${f_blocks})) -ge $((10 * 1024 * 1024)) ] || \ + atf_file "bsize * blocks too small" + [ $((${f_bsize} * ${f_blocks})) -le \ + $((10 * 1024 * 1024 + ${pagesize})) ] || \ + atf_fail "bsize * blocks too big" + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case values +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_symlink.sh b/contrib/netbsd-tests/fs/tmpfs/t_symlink.sh new file mode 100755 index 0000000..2cc66c0 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_symlink.sh @@ -0,0 +1,114 @@ +# $NetBSD: t_symlink.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that the symlink and readlink operations work. +# + +atf_test_case file +file_head() { + atf_set "descr" "Tests that symlinks to files work" + atf_set "require.user" "root" +} +file_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty touch a + atf_check -s eq:0 -o empty -e empty ln -s a b + [ $(md5 b | cut -d ' ' -f 4) = d41d8cd98f00b204e9800998ecf8427e ] || \ + atf_fail "Symlink points to an incorrect file" + + atf_check -s eq:0 -o empty -e empty -x 'echo foo >a' + [ $(md5 b | cut -d ' ' -f 4) = d3b07384d113edec49eaa6238ad5ff00 ] || \ + atf_fail "Symlink points to an incorrect file" + + test_unmount +} + +atf_test_case exec +exec_head() { + atf_set "descr" "Tests symlinking to a known system binary and" \ + "executing it through the symlink" + atf_set "require.user" "root" +} +exec_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty touch b + atf_check -s eq:0 -o empty -e empty ln -s /bin/cp cp + atf_check -s eq:0 -o empty -e empty ./cp b c + atf_check -s eq:0 -o empty -e empty test -f c + + test_unmount +} + +atf_test_case dir +dir_head() { + atf_set "descr" "Tests that symlinks to directories work" + atf_set "require.user" "root" +} +dir_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir d + atf_check -s eq:1 -o empty -e empty test -f d/foo + atf_check -s eq:1 -o empty -e empty test -f e/foo + atf_check -s eq:0 -o empty -e empty ln -s d e + atf_check -s eq:0 -o empty -e empty touch d/foo + atf_check -s eq:0 -o empty -e empty test -f d/foo + atf_check -s eq:0 -o empty -e empty test -f e/foo + + test_unmount +} + +atf_test_case kqueue +kqueue_head() { + atf_set "descr" "Tests that creating a symlink raises the" \ + "appropriate kqueue events" + atf_set "require.user" "root" +} +kqueue_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir dir + echo 'ln -s non-existent dir/a' | kqueue_monitor 1 dir + kqueue_check dir NOTE_WRITE + atf_check -s eq:0 -o empty -e empty rm dir/a + atf_check -s eq:0 -o empty -e empty rmdir dir + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case file + atf_add_test_case exec + atf_add_test_case dir + atf_add_test_case kqueue +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_times.sh b/contrib/netbsd-tests/fs/tmpfs/t_times.sh new file mode 100755 index 0000000..f83dfe8 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_times.sh @@ -0,0 +1,141 @@ +# $NetBSD: t_times.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that node times are properly handled. +# + +atf_test_case empty +empty_head() { + atf_set "descr" "Tests that creating an empty file and later" \ + "manipulating it updates times correctly" + atf_set "require.user" "root" +} +empty_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty touch a + eval $(stat -s a | sed -e 's|st_|ost_|g') || atf_fail "stat failed" + [ ${ost_birthtime} -eq ${ost_atime} ] || atf_fail "Incorrect atime" + [ ${ost_birthtime} -eq ${ost_ctime} ] || atf_fail "Incorrect ctime" + [ ${ost_birthtime} -eq ${ost_mtime} ] || atf_fail "Incorrect mtime" + + sleep 1 + atf_check -s eq:0 -o ignore -e empty cat a + eval $(stat -s a) || atf_fail "stat failed" + [ ${st_atime} -gt ${ost_atime} ] || atf_fail "Incorrect atime" + [ ${st_ctime} -eq ${ost_ctime} ] || atf_fail "Incorrect ctime" + [ ${st_mtime} -eq ${ost_mtime} ] || atf_fail "Incorrect mtime" + + sleep 1 + echo foo >a || atf_fail "Write failed" + eval $(stat -s a) || atf_fail "stat failed" + [ ${st_atime} -gt ${ost_atime} ] || atf_fail "Incorrect atime" + [ ${st_ctime} -gt ${ost_ctime} ] || atf_fail "Incorrect ctime" + [ ${st_mtime} -gt ${ost_mtime} ] || atf_fail "Incorrect mtime" + + test_unmount +} + +atf_test_case non_empty +non_empty_head() { + atf_set "descr" "Tests that creating a non-empty file and later" \ + "manipulating it updates times correctly" + atf_set "require.user" "root" +} +non_empty_body() { + test_mount + + echo foo >b || atf_fail "Non-empty creation failed" + eval $(stat -s b | sed -e 's|st_|ost_|g') || atf_fail "stat failed" + + sleep 1 + atf_check -s eq:0 -o ignore -e empty cat b + eval $(stat -s b) || atf_fail "stat failed" + [ ${st_atime} -gt ${ost_atime} ] || atf_fail "Incorrect atime" + [ ${st_ctime} -eq ${ost_ctime} ] || atf_fail "Incorrect ctime" + [ ${st_mtime} -eq ${ost_mtime} ] || atf_fail "Incorrect mtime" + + test_unmount +} + +atf_test_case link +link_head() { + atf_set "descr" "Tests that linking to an existing file updates" \ + "times correctly" + atf_set "require.user" "root" +} +link_body() { + test_mount + + echo foo >c || atf_fail "Non-empty creation failed" + eval $(stat -s c | sed -e 's|st_|ost_|g') || atf_fail "stat failed" + + sleep 1 + atf_check -s eq:0 -o empty -e empty ln c d + eval $(stat -s c) || atf_fail "stat failed" + [ ${st_atime} -eq ${ost_atime} ] || atf_fail "Incorrect atime" + [ ${st_ctime} -gt ${ost_ctime} ] || atf_fail "Incorrect ctime" + [ ${st_mtime} -eq ${ost_mtime} ] || atf_fail "Incorrect mtime" + + test_unmount +} + +atf_test_case rename +rename_head() { + atf_set "descr" "Tests that renaming an existing file updates" \ + "times correctly" + atf_set "require.user" "root" +} +rename_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir e + echo foo >e/a || atf_fail "Creation failed" + eval $(stat -s e | sed -e 's|st_|dost_|g') || atf_fail "stat failed" + eval $(stat -s e/a | sed -e 's|st_|ost_|g') || atf_fail "stat failed" + sleep 1 + atf_check -s eq:0 -o empty -e empty mv e/a e/b + eval $(stat -s e | sed -e 's|st_|dst_|g') || atf_fail "stat failed" + eval $(stat -s e/b) || atf_fail "stat failed" + [ ${st_atime} -eq ${ost_atime} ] || atf_fail "Incorrect atime" + [ ${st_ctime} -gt ${ost_ctime} ] || atf_fail "Incorrect ctime" + [ ${st_mtime} -eq ${ost_mtime} ] || atf_fail "Incorrect mtime" + [ ${dst_mtime} -gt ${dost_mtime} ] || atf_fail "Incorrect mtime" + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case empty + atf_add_test_case non_empty + atf_add_test_case link + atf_add_test_case rename +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_trail_slash.sh b/contrib/netbsd-tests/fs/tmpfs/t_trail_slash.sh new file mode 100755 index 0000000..df5b023 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_trail_slash.sh @@ -0,0 +1,52 @@ +# $NetBSD: t_trail_slash.sh,v 1.5 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case main +main_head() { + atf_set "descr" "Verifies that trailing slashes are not stored" \ + "in directory names and that they do not cause" \ + "crashes" + atf_set "require.user" "root" +} +main_body() { + test_mount + + atf_check -s eq:0 -o empty -e empty mkdir a/ + atf_check -s eq:0 -o empty -e empty touch a/b + atf_check -s eq:0 -o empty -e empty test -f a/b + atf_check -s eq:0 -o empty -e empty rm a/b + atf_check -s eq:0 -o empty -e empty rmdir a/ + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case main +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_truncate.sh b/contrib/netbsd-tests/fs/tmpfs/t_truncate.sh new file mode 100755 index 0000000..2bc1902 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_truncate.sh @@ -0,0 +1,56 @@ +# $NetBSD: t_truncate.sh,v 1.4 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() { + atf_set "descr" "Verifies that the truncate operation works" + atf_set "require.user" "root" +} +basic_body() { + test_mount + + echo "Creating big file" + jot 10000 >a || atf_fail "Failed to create big file" + echo "Trunctaing the file to a smaller size" + echo foo >a || atf_fail "Failed to truncate file to a smaller size" + [ $(md5 a | cut -d ' ' -f 4) = d3b07384d113edec49eaa6238ad5ff00 ] || \ + echo "Truncated file is incorrect" + + echo "Truncating to zero bytes" + >a || atf_fail "Failed to truncate to 0" + echo "Truncating to zero bytes, second try" + >a || atf_fail "Failed to re-truncate to 0" + + test_unmount +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_vnd.sh b/contrib/netbsd-tests/fs/tmpfs/t_vnd.sh new file mode 100755 index 0000000..0929b55 --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_vnd.sh @@ -0,0 +1,102 @@ +# $NetBSD: t_vnd.sh,v 1.9 2016/07/29 05:23:24 pgoyette Exp $ +# +# Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Verifies that vnd works with files stored in tmpfs. +# + +# Begin FreeBSD +MD_DEVICE_FILE=md.device +# End FreeBSD + +atf_test_case basic cleanup +basic_head() { + atf_set "descr" "Verifies that vnd works with files stored in tmpfs" + atf_set "require.user" "root" +} +basic_body() { + test_mount + + atf_check -s eq:0 -o ignore -e ignore \ + dd if=/dev/zero of=disk.img bs=1m count=10 + # Begin FreeBSD + if true; then + atf_check -s eq:0 -o empty -e empty mkdir mnt + atf_check -s eq:0 -o empty -e empty mdmfs -F disk.img md mnt + md_dev=$(df mnt | awk 'NR != 1 { print $1 }' | xargs basename) + atf_check test -c /dev/$md_dev # Sanity check + echo -n $md_dev > $TMPDIR/$MD_DEVICE_FILE + else + # End FreeBSD + atf_check -s eq:0 -o empty -e empty vndconfig /dev/vnd3 disk.img + + atf_check -s eq:0 -o ignore -e ignore newfs /dev/rvnd3a + + atf_check -s eq:0 -o empty -e empty mkdir mnt + atf_check -s eq:0 -o empty -e empty mount /dev/vnd3a mnt + # Begin FreeBSD + fi + # End FreeBSD + + echo "Creating test files" + for f in $(jot -w %u 100 | uniq); do + jot 1000 >mnt/${f} || atf_fail "Failed to create file ${f}" + done + + echo "Verifying created files" + for f in $(jot -w %u 100 | uniq); do + [ $(md5 mnt/${f} | cut -d ' ' -f 4) = \ + 53d025127ae99ab79e8502aae2d9bea6 ] || \ + atf_fail "Invalid checksum for file ${f}" + done + + atf_check -s eq:0 -o empty -e empty umount mnt + atf_check -s eq:0 -o empty -e empty vndconfig -u /dev/vnd3 + + test_unmount + touch done +} +basic_cleanup() { + # Begin FreeBSD + if md_dev=$(cat $TMPDIR/$MD_DEVICE_FILE); then + echo "Will try disconnecting $md_dev" + else + echo "$MD_DEVICE_FILE doesn't exist in $TMPDIR; returning early" + return 0 + fi + # End FreeBSD + if [ ! -f done ]; then + umount mnt 2>/dev/null 1>&2 + vndconfig -u /dev/vnd3 2>/dev/null 1>&2 + fi +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/fs/tmpfs/t_vnode_leak.sh b/contrib/netbsd-tests/fs/tmpfs/t_vnode_leak.sh new file mode 100755 index 0000000..4630a7c --- /dev/null +++ b/contrib/netbsd-tests/fs/tmpfs/t_vnode_leak.sh @@ -0,0 +1,68 @@ +# $NetBSD: t_vnode_leak.sh,v 1.6 2010/11/07 17:51:18 jmmv Exp $ +# +# Copyright (c) 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case main cleanup +main_head() { + atf_set "descr" "Verifies that vnodes are not leaked and that" \ + "their reclaim operation works as expected: i.e.," \ + "when all free vnodes are exhausted, unused ones" \ + "have to be recycled, which is what the reclaim" \ + "operation does." + atf_set "require.user" "root" +} +main_body() { + echo "Lowering kern.maxvnodes to 2000" + # Begin FreeBSD + if true; then + sysctl -n kern.maxvnodes > oldvnodes + else + # End FreeBSD + sysctl kern.maxvnodes | awk '{ print $3; }' >oldvnodes + # Begin FreeBSD + fi + # End FreeBSD + atf_check -s eq:0 -o ignore -e empty sysctl -w kern.maxvnodes=2000 + + test_mount -o -s$(((4000 + 2) * 4096)) + echo "Creating 4000 directories" + for f in $(jot 4000); do + mkdir ${f} + done + test_unmount +} +main_cleanup() { + oldvnodes=$(cat oldvnodes) + echo "Restoring kern.maxvnodes to ${oldvnodes}" + sysctl -w kern.maxvnodes=${oldvnodes} +} + +atf_init_test_cases() { + . $(atf_get_srcdir)/../h_funcs.subr + . $(atf_get_srcdir)/h_funcs.subr + + atf_add_test_case main +} diff --git a/contrib/netbsd-tests/fs/umapfs/t_basic.c b/contrib/netbsd-tests/fs/umapfs/t_basic.c new file mode 100644 index 0000000..c9b2d9b --- /dev/null +++ b/contrib/netbsd-tests/fs/umapfs/t_basic.c @@ -0,0 +1,145 @@ +/* $NetBSD: t_basic.c,v 1.5 2017/01/13 21:30:40 christos Exp $ */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "h_macros.h" + +ATF_TC(basic); +ATF_TC_HEAD(basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "basic umapfs mapping"); +} + +static void +xtouch(const char *path) +{ + int fd; + + fd = rump_sys_open(path, O_CREAT | O_RDWR, 0777); + if (fd == -1) + atf_tc_fail_errno("create %s", path); + rump_sys_close(fd); +} + +static void +xchown(const char *path, uid_t uid, gid_t gid) +{ + + if (rump_sys_chown(path, uid, gid) == -1) + atf_tc_fail_errno("chown %s failed", path); +} + +static void +testuidgid(const char *path, uid_t uid, gid_t gid) +{ + struct stat sb; + + if (rump_sys_stat(path, &sb) == -1) + atf_tc_fail_errno("stat %s", path); + if (uid != (uid_t)-1) { + if (sb.st_uid != uid) + atf_tc_fail("%s: expected uid %d, got %d", + path, uid, sb.st_uid); + } + if (gid != (gid_t)-1) { + if (sb.st_gid != gid) + atf_tc_fail("%s: expected gid %d, got %d", + path, gid, sb.st_gid); + } +} + +ATF_TC_BODY(basic, tc) +{ + struct umap_args umargs; + struct tmpfs_args targs; + u_long umaps[2][2]; + u_long gmaps[2][2]; + + rump_init(); + if (rump_sys_mkdir("/td1", 0777) == -1) + atf_tc_fail_errno("mp1"); + if (rump_sys_mkdir("/td2", 0777) == -1) + atf_tc_fail_errno("mp1"); + + /* use tmpfs because rumpfs doesn't support ownership */ + memset(&targs, 0, sizeof(targs)); + targs.ta_version = TMPFS_ARGS_VERSION; + targs.ta_root_mode = 0777; + if (rump_sys_mount(MOUNT_TMPFS, "/td1", 0, &targs, sizeof(targs)) == -1) + atf_tc_fail_errno("could not mount tmpfs td1"); + + memset(&umargs, 0, sizeof(umargs)); + + /* + * Map td1 uid 555 to td2 uid 777 (yes, IMHO the umapfs + * mapping format is counter-intuitive). + */ + umaps[0][0] = 777; + umaps[0][1] = 555; + umaps[1][0] = 0; + umaps[1][1] = 0; + gmaps[0][0] = 4321; + gmaps[0][1] = 1234; + gmaps[1][0] = 0; + gmaps[1][1] = 0; + + umargs.umap_target = __UNCONST("/td1"); + umargs.nentries = 2; + umargs.gnentries = 2; + umargs.mapdata = umaps; + umargs.gmapdata = gmaps; + + if (rump_sys_mount(MOUNT_UMAP, "/td2", 0, &umargs,sizeof(umargs)) == -1) + atf_tc_fail_errno("could not mount umapfs"); + + xtouch("/td1/noch"); + testuidgid("/td1/noch", 0, 0); + testuidgid("/td2/noch", 0, 0); + + xtouch("/td1/nomap"); + xchown("/td1/nomap", 1, 2); + testuidgid("/td1/nomap", 1, 2); + testuidgid("/td2/nomap", -1, -1); + + xtouch("/td1/forwmap"); + xchown("/td1/forwmap", 555, 1234); + testuidgid("/td1/forwmap", 555, 1234); + testuidgid("/td2/forwmap", 777, 4321); + + /* + * this *CANNOT* be correct??? + */ + xtouch("/td1/revmap"); + /* + * should be 777 / 4321 (?), but makes first test fail since + * it gets 777 / 4321, i.e. unmapped results. + */ + xchown("/td2/revmap", 555, 1234); + testuidgid("/td1/revmap", 555, 1234); + testuidgid("/td2/revmap", 777, 4321); + +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, basic); + return 0; /*XXX?*/ +} diff --git a/contrib/netbsd-tests/fs/union/t_pr.c b/contrib/netbsd-tests/fs/union/t_pr.c new file mode 100644 index 0000000..fc70bca --- /dev/null +++ b/contrib/netbsd-tests/fs/union/t_pr.c @@ -0,0 +1,130 @@ +/* $NetBSD: t_pr.c,v 1.9 2017/01/13 21:30:40 christos Exp $ */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(multilayer); +ATF_TC_HEAD(multilayer, tc) +{ + atf_tc_set_md_var(tc, "descr", "mount_union -b twice"); +} + +ATF_TC_BODY(multilayer, tc) +{ + struct union_args unionargs; + + rump_init(); + + if (rump_sys_mkdir("/Tunion", 0777) == -1) + atf_tc_fail_errno("mkdir mp1"); + if (rump_sys_mkdir("/Tunion2", 0777) == -1) + atf_tc_fail_errno("mkdir mp2"); + if (rump_sys_mkdir("/Tunion2/A", 0777) == -1) + atf_tc_fail_errno("mkdir A"); + if (rump_sys_mkdir("/Tunion2/B", 0777) == -1) + atf_tc_fail_errno("mkdir B"); + + unionargs.target = __UNCONST("/Tunion2/A"); + unionargs.mntflags = UNMNT_BELOW; + + if (rump_sys_mount(MOUNT_UNION, "/Tunion", 0, + &unionargs, sizeof(unionargs)) == -1) + atf_tc_fail_errno("union mount"); + + unionargs.target = __UNCONST("/Tunion2/B"); + unionargs.mntflags = UNMNT_BELOW; + + rump_sys_mount(MOUNT_UNION, "/Tunion", 0,&unionargs,sizeof(unionargs)); +} + +ATF_TC(devnull1); +ATF_TC_HEAD(devnull1, tc) +{ + atf_tc_set_md_var(tc, "descr", "mount_union -b and " + "'echo x > /un/null'"); +} + +ATF_TC_BODY(devnull1, tc) +{ + struct union_args unionargs; + int fd, res; + + rump_init(); + + if (rump_sys_mkdir("/mp", 0777) == -1) + atf_tc_fail_errno("mkdir mp"); + + unionargs.target = __UNCONST("/dev"); + unionargs.mntflags = UNMNT_BELOW; + + if (rump_sys_mount(MOUNT_UNION, "/mp", 0, + &unionargs, sizeof(unionargs)) == -1) + atf_tc_fail_errno("union mount"); + + fd = rump_sys_open("/mp/null", O_WRONLY | O_CREAT | O_TRUNC); + + if (fd == -1) + atf_tc_fail_errno("open"); + + res = rump_sys_write(fd, &fd, sizeof(fd)); + if (res != sizeof(fd)) + atf_tc_fail("write"); +} + +ATF_TC(devnull2); +ATF_TC_HEAD(devnull2, tc) +{ + atf_tc_set_md_var(tc, "descr", "mount_union -b and " + "'echo x >> /un/null'"); +} + +ATF_TC_BODY(devnull2, tc) +{ + struct union_args unionargs; + int fd, res; + + rump_init(); + + if (rump_sys_mkdir("/mp", 0777) == -1) + atf_tc_fail_errno("mkdir mp"); + + unionargs.target = __UNCONST("/dev"); + unionargs.mntflags = UNMNT_BELOW; + + if (rump_sys_mount(MOUNT_UNION, "/mp", 0, + &unionargs, sizeof(unionargs)) == -1) + atf_tc_fail_errno("union mount"); + + fd = rump_sys_open("/mp/null", O_WRONLY | O_CREAT | O_APPEND); + if (fd == -1) + atf_tc_fail_errno("open"); + + res = rump_sys_write(fd, &fd, sizeof(fd)); + if (res != sizeof(fd)) + atf_tc_fail("write"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, multilayer); + ATF_TP_ADD_TC(tp, devnull1); + ATF_TP_ADD_TC(tp, devnull2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/vfs/t_full.c b/contrib/netbsd-tests/fs/vfs/t_full.c new file mode 100644 index 0000000..51347de --- /dev/null +++ b/contrib/netbsd-tests/fs/vfs/t_full.c @@ -0,0 +1,101 @@ +/* $NetBSD: t_full.c,v 1.9 2017/01/13 21:30:40 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/h_fsmacros.h" +#include "h_macros.h" + +/* + * Write this much over the image size. This is to force an NFS commit, + * since we might just stuff data into the cache and miss the problem. + */ +#define NFSBONUS (1<<16) + +static void +fillfs(const atf_tc_t *tc, const char *mp) +{ + char buf[8192]; + size_t written; + ssize_t n = 0; /* xxxgcc */ + size_t bonus; + int fd, i = 0; + + if (FSTYPE_P2K_FFS(tc) || FSTYPE_PUFFS(tc) || FSTYPE_RUMPFS(tc)) { + atf_tc_skip("fs does not support explicit block allocation " + "(GOP_ALLOC)"); + } + + bonus = 0; + if (FSTYPE_NFS(tc)) + bonus = NFSBONUS; + + if (rump_sys_chdir(mp) == -1) + atf_tc_fail_errno("chdir mountpoint"); + fd = rump_sys_open("afile", O_CREAT | O_RDWR); + if (fd == -1) + atf_tc_fail_errno("create file"); + + for (written = 0; written < FSTEST_IMGSIZE + bonus; written +=n) { + memset(buf, i++, sizeof(buf)); /* known garbage */ + n = rump_sys_write(fd, buf, sizeof(buf)); + if (n == -1) + break; + } + if (FSTYPE_ZFS(tc)) + atf_tc_expect_fail("PR kern/47656: Test known to be broken"); + if (n == -1) { + if (errno != ENOSPC) + atf_tc_fail_errno("write"); + } else { + atf_tc_fail("filled file system over size limit"); + } + + rump_sys_close(fd); + rump_sys_chdir("/"); +} + +ATF_TC_FSAPPLY(fillfs, "fills file system, expects ENOSPC"); + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_FSAPPLY(fillfs); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/vfs/t_io.c b/contrib/netbsd-tests/fs/vfs/t_io.c new file mode 100644 index 0000000..b7f6529 --- /dev/null +++ b/contrib/netbsd-tests/fs/vfs/t_io.c @@ -0,0 +1,268 @@ +/* $NetBSD: t_io.c,v 1.17 2017/01/13 21:30:40 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/h_fsmacros.h" +#include "h_macros.h" + +#define TESTSTR "this is a string. collect enough and you'll have Em" +#define TESTSZ sizeof(TESTSTR) + +static void +holywrite(const atf_tc_t *tc, const char *mp) +{ + char buf[1024]; + char *b2, *b3; + size_t therange = getpagesize()+1; + int fd; + + FSTEST_ENTER(); + + RL(fd = rump_sys_open("file", O_RDWR|O_CREAT|O_TRUNC, 0666)); + + memset(buf, 'A', sizeof(buf)); + RL(rump_sys_pwrite(fd, buf, 1, getpagesize())); + + memset(buf, 'B', sizeof(buf)); + RL(rump_sys_pwrite(fd, buf, 2, getpagesize()-1)); + + REQUIRE_LIBC(b2 = malloc(2 * getpagesize()), NULL); + REQUIRE_LIBC(b3 = malloc(2 * getpagesize()), NULL); + + RL(rump_sys_pread(fd, b2, therange, 0)); + + memset(b3, 0, therange); + memset(b3 + getpagesize() - 1, 'B', 2); + + ATF_REQUIRE_EQ(memcmp(b2, b3, therange), 0); + + rump_sys_close(fd); + FSTEST_EXIT(); +} + +static void +extendbody(const atf_tc_t *tc, off_t seekcnt) +{ + char buf[TESTSZ+1]; + struct stat sb; + int fd; + + FSTEST_ENTER(); + RL(fd = rump_sys_open("testfile", + O_CREAT | O_RDWR | (seekcnt ? O_APPEND : 0))); + RL(rump_sys_ftruncate(fd, seekcnt)); + RL(rump_sys_fstat(fd, &sb)); + ATF_REQUIRE_EQ(sb.st_size, seekcnt); + + ATF_REQUIRE_EQ(rump_sys_write(fd, TESTSTR, TESTSZ), TESTSZ); + ATF_REQUIRE_EQ(rump_sys_pread(fd, buf, TESTSZ, seekcnt), TESTSZ); + ATF_REQUIRE_STREQ(buf, TESTSTR); + + RL(rump_sys_fstat(fd, &sb)); + ATF_REQUIRE_EQ(sb.st_size, (off_t)TESTSZ + seekcnt); + RL(rump_sys_close(fd)); + FSTEST_EXIT(); +} + +static void +extendfile(const atf_tc_t *tc, const char *mp) +{ + + extendbody(tc, 0); +} + +static void +extendfile_append(const atf_tc_t *tc, const char *mp) +{ + + extendbody(tc, 37); +} + +static void +overwritebody(const atf_tc_t *tc, off_t count, bool dotrunc) +{ + char *buf; + int fd; + + REQUIRE_LIBC(buf = malloc(count), NULL); + FSTEST_ENTER(); + RL(fd = rump_sys_open("testi", O_CREAT | O_RDWR, 0666)); + ATF_REQUIRE_EQ(rump_sys_write(fd, buf, count), count); + RL(rump_sys_close(fd)); + + RL(fd = rump_sys_open("testi", O_RDWR)); + if (dotrunc) + RL(rump_sys_ftruncate(fd, 0)); + ATF_REQUIRE_EQ(rump_sys_write(fd, buf, count), count); + RL(rump_sys_close(fd)); + FSTEST_EXIT(); +} + +static void +overwrite512(const atf_tc_t *tc, const char *mp) +{ + + overwritebody(tc, 512, false); +} + +static void +overwrite64k(const atf_tc_t *tc, const char *mp) +{ + + overwritebody(tc, 1<<16, false); +} + +static void +overwrite_trunc(const atf_tc_t *tc, const char *mp) +{ + + overwritebody(tc, 1<<16, true); +} + +static void +shrinkfile(const atf_tc_t *tc, const char *mp) +{ + int fd; + + FSTEST_ENTER(); + RL(fd = rump_sys_open("file", O_RDWR|O_CREAT|O_TRUNC, 0666)); + RL(rump_sys_ftruncate(fd, 2)); + RL(rump_sys_ftruncate(fd, 1)); + rump_sys_close(fd); + FSTEST_EXIT(); +} + +#define TBSIZE 9000 +static void +read_after_unlink(const atf_tc_t *tc, const char *mp) +{ + char buf[TBSIZE], buf2[TBSIZE]; + int fd; + + FSTEST_ENTER(); + + /* create file and put some content into it */ + RL(fd = rump_sys_open("file", O_RDWR|O_CREAT, 0666)); + memset(buf, 'D', TBSIZE); + ATF_REQUIRE_EQ(rump_sys_write(fd, buf, TBSIZE), TBSIZE); + rump_sys_close(fd); + + /* flush buffers from UBC to file system */ + ATF_REQUIRE_ERRNO(EBUSY, rump_sys_unmount(mp, 0) == -1); + + RL(fd = rump_sys_open("file", O_RDWR)); + RL(rump_sys_unlink("file")); + + ATF_REQUIRE_EQ(rump_sys_read(fd, buf2, TBSIZE), TBSIZE); + ATF_REQUIRE_EQ(memcmp(buf, buf2, TBSIZE), 0); + rump_sys_close(fd); + + FSTEST_EXIT(); +} + +static void +wrrd_after_unlink(const atf_tc_t *tc, const char *mp) +{ + int value = 0x11; + int v2; + int fd; + + FSTEST_ENTER(); + + RL(fd = rump_sys_open("file", O_RDWR|O_CREAT, 0666)); + RL(rump_sys_unlink("file")); + + RL(rump_sys_pwrite(fd, &value, sizeof(value), 654321)); + + /* + * We can't easily invalidate the buffer since we hold a + * reference, but try to get them to flush anyway. + */ + RL(rump_sys_fsync(fd)); + RL(rump_sys_pread(fd, &v2, sizeof(v2), 654321)); + rump_sys_close(fd); + + ATF_REQUIRE_EQ(value, v2); + FSTEST_EXIT(); +} + +static void +read_fault(const atf_tc_t *tc, const char *mp) +{ + char ch = 123; + int fd; + + FSTEST_ENTER(); + RL(fd = rump_sys_open("file", O_CREAT | O_RDWR, 0777)); + ATF_REQUIRE_EQ(rump_sys_write(fd, &ch, 1), 1); + RL(rump_sys_close(fd)); + RL(fd = rump_sys_open("file", O_RDONLY | O_SYNC | O_RSYNC)); + ATF_REQUIRE_ERRNO(EFAULT, rump_sys_read(fd, NULL, 1) == -1); + RL(rump_sys_close(fd)); + FSTEST_EXIT(); +} + +ATF_TC_FSAPPLY(holywrite, "create a sparse file and fill hole"); +ATF_TC_FSAPPLY(extendfile, "check that extending a file works"); +ATF_TC_FSAPPLY(extendfile_append, "check that extending a file works " + "with a append-only fd (PR kern/44307)"); +ATF_TC_FSAPPLY(overwrite512, "write a 512 byte file twice"); +ATF_TC_FSAPPLY(overwrite64k, "write a 64k byte file twice"); +ATF_TC_FSAPPLY(overwrite_trunc, "write 64k + truncate + rewrite"); +ATF_TC_FSAPPLY(shrinkfile, "shrink file"); +ATF_TC_FSAPPLY(read_after_unlink, "contents can be read off disk after unlink"); +ATF_TC_FSAPPLY(wrrd_after_unlink, "file can be written and read after unlink"); +ATF_TC_FSAPPLY(read_fault, "read at bad address must return EFAULT"); + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_FSAPPLY(holywrite); + ATF_TP_FSAPPLY(extendfile); + ATF_TP_FSAPPLY(extendfile_append); + ATF_TP_FSAPPLY(overwrite512); + ATF_TP_FSAPPLY(overwrite64k); + ATF_TP_FSAPPLY(overwrite_trunc); + ATF_TP_FSAPPLY(shrinkfile); + ATF_TP_FSAPPLY(read_after_unlink); + ATF_TP_FSAPPLY(wrrd_after_unlink); + ATF_TP_FSAPPLY(read_fault); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/vfs/t_mtime_otrunc.c b/contrib/netbsd-tests/fs/vfs/t_mtime_otrunc.c new file mode 100644 index 0000000..bb07609 --- /dev/null +++ b/contrib/netbsd-tests/fs/vfs/t_mtime_otrunc.c @@ -0,0 +1,86 @@ +/*- + * Copyright (c) 2017 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2013\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mtime_otrunc.c,v 1.1 2017/02/02 22:07:05 martin Exp $"); + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/h_fsmacros.h" + +#define LOCKFILE "lock" + +static time_t +lock_it(void) +{ + struct stat st; + + if (rump_sys_stat(LOCKFILE, &st) != 0) + st.st_mtime = 0; + + int f = rump_sys_open(LOCKFILE, O_WRONLY|O_CREAT|O_TRUNC, 0666); + if (f == -1) return 0; + rump_sys_close(f); + + return st.st_mtime; +} + +static void +otrunc_mtime_update(const atf_tc_t *tc, const char *path) +{ + time_t last_ts = 0; + int res; + + /* atf_tc_expect_fail("PR kern/51762"); */ + + res = rump_sys_chdir(path); + if (res == -1) + atf_tc_fail("chdir failed"); + + for (int i = 0; i < 5; i++) { + time_t l = lock_it(); + printf("last lock: %ld\n", (long)l); + ATF_REQUIRE_MSG(i == 0 || l > last_ts, + "iteration %d: lock time did not increase, old time %lu, " + "new time %lu", i, + (unsigned long)last_ts, (unsigned long)l); + last_ts = l; + sleep(2); + } + rump_sys_chdir("/"); +} + +ATF_FSAPPLY(otrunc_mtime_update, "Checks for mtime updates by open(O_TRUNC) (PR kern/51762)"); diff --git a/contrib/netbsd-tests/fs/vfs/t_renamerace.c b/contrib/netbsd-tests/fs/vfs/t_renamerace.c new file mode 100644 index 0000000..63cfb44 --- /dev/null +++ b/contrib/netbsd-tests/fs/vfs/t_renamerace.c @@ -0,0 +1,190 @@ +/* $NetBSD: t_renamerace.c,v 1.34 2017/01/13 21:30:40 christos Exp $ */ + +/* + * Modified for rump and atf from a program supplied + * by Nicolas Joly in kern/40948 + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Bump the size of the test file system image to a larger value. + * + * These tests cause a lot of churn in the file system by creating and + * deleting files/directories in quick succession. A faster CPU will cause + * more churn because the tests are capped by a run time period in seconds, + * not number of operations. + * + * This is all fine except for LFS, because the lfs_cleanerd cannot keep up + * with the churn and thus causes the test to fail on fast machines. Hence + * the reason for this hack. */ +#define FSTEST_IMGSIZE (50000 * 512) + +#include "../common/h_fsmacros.h" +#include "h_macros.h" + +static volatile int quittingtime; +pid_t wrkpid; + +static void * +w1(void *arg) +{ + int fd; + + rump_pub_lwproc_newlwp(wrkpid); + + while (!quittingtime) { + fd = rump_sys_open("rename.test1", + O_WRONLY|O_CREAT|O_TRUNC, 0666); + if (fd == -1 && errno != EEXIST) + atf_tc_fail_errno("create"); + rump_sys_unlink("rename.test1"); + rump_sys_close(fd); + } + + return NULL; +} + +static void * +w1_dirs(void *arg) +{ + + rump_pub_lwproc_newlwp(wrkpid); + + while (!quittingtime) { + if (rump_sys_mkdir("rename.test1", 0777) == -1) + atf_tc_fail_errno("mkdir"); + rump_sys_rmdir("rename.test1"); + } + + return NULL; +} + +static void * +w2(void *arg) +{ + + rump_pub_lwproc_newlwp(wrkpid); + + while (!quittingtime) { + rump_sys_rename("rename.test1", "rename.test2"); + } + + return NULL; +} + +#define NWRK 8 +static void +renamerace(const atf_tc_t *tc, const char *mp) +{ + pthread_t pt1[NWRK], pt2[NWRK]; + int i; + + /* + * Sysvbfs supports only 8 inodes so this test would exhaust + * the inode table and creating files would fail with ENOSPC. + */ + if (FSTYPE_SYSVBFS(tc)) + atf_tc_skip("filesystem has not enough inodes"); + if (FSTYPE_RUMPFS(tc)) + atf_tc_skip("rename not supported by file system"); + if (FSTYPE_UDF(tc)) + atf_tc_expect_fail("PR kern/49046"); + + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + RL(wrkpid = rump_sys_getpid()); + + RL(rump_sys_chdir(mp)); + for (i = 0; i < NWRK; i++) + pthread_create(&pt1[i], NULL, w1, NULL); + + for (i = 0; i < NWRK; i++) + pthread_create(&pt2[i], NULL, w2, NULL); + + sleep(5); + quittingtime = 1; + + for (i = 0; i < NWRK; i++) + pthread_join(pt1[i], NULL); + for (i = 0; i < NWRK; i++) + pthread_join(pt2[i], NULL); + RL(rump_sys_chdir("/")); + + if (FSTYPE_UDF(tc)) + atf_tc_fail("race did not trigger this time"); + + if (FSTYPE_MSDOS(tc)) { + atf_tc_expect_fail("PR kern/43626"); + /* + * XXX: race does not trigger every time at least + * on amd64/qemu. + */ + if (msdosfs_fstest_unmount(tc, mp, 0) != 0) { + rump_pub_vfs_mount_print(mp, 1); + atf_tc_fail_errno("unmount failed"); + } + atf_tc_fail("race did not trigger this time"); + } +} + +static void +renamerace_dirs(const atf_tc_t *tc, const char *mp) +{ + pthread_t pt1, pt2; + + if (FSTYPE_SYSVBFS(tc)) + atf_tc_skip("directories not supported by file system"); + + if (FSTYPE_RUMPFS(tc)) + atf_tc_skip("rename not supported by file system"); + + /* XXX: msdosfs also sometimes hangs */ + if (FSTYPE_MSDOS(tc)) + atf_tc_expect_signal(-1, "PR kern/43626"); + + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + RL(wrkpid = rump_sys_getpid()); + + RL(rump_sys_chdir(mp)); + pthread_create(&pt1, NULL, w1_dirs, NULL); + pthread_create(&pt2, NULL, w2, NULL); + + sleep(5); + quittingtime = 1; + + pthread_join(pt1, NULL); + pthread_join(pt2, NULL); + RL(rump_sys_chdir("/")); + + /* + * Doesn't always trigger when run on a slow backend + * (i.e. not on tmpfs/mfs). So do the usual kludge. + */ + if (FSTYPE_MSDOS(tc)) + abort(); +} + +ATF_TC_FSAPPLY(renamerace, "rename(2) race with file unlinked mid-operation"); +ATF_TC_FSAPPLY(renamerace_dirs, "rename(2) race with directories"); + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_FSAPPLY(renamerace); /* PR kern/41128 */ + ATF_TP_FSAPPLY(renamerace_dirs); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/vfs/t_rmdirrace.c b/contrib/netbsd-tests/fs/vfs/t_rmdirrace.c new file mode 100644 index 0000000..839dbad --- /dev/null +++ b/contrib/netbsd-tests/fs/vfs/t_rmdirrace.c @@ -0,0 +1,106 @@ +/* $NetBSD: t_rmdirrace.c,v 1.9 2012/02/16 02:47:56 perseant Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nicolas Joly. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/h_fsmacros.h" + +#define DIRNAME "rmdir.test" + +static void *func1(void *arg) +{ + + while (*(int *)arg != 1) + rump_sys_mkdir(DIRNAME, 0755); + + return NULL; +} + +static void *func2(void *arg) +{ + + while (*(int *)arg != 1) + rump_sys_rmdir(DIRNAME); + + return NULL; +} + +static void +race(const atf_tc_t *tc, const char *path) +{ + int res, fd, quit; + pthread_t th1, th2; + + if (FSTYPE_SYSVBFS(tc)) + atf_tc_skip("directories not supported by file system"); + + fd = rump_sys_open(".", O_RDONLY, 0666); + if (fd == -1) + atf_tc_fail("open failed"); + res = rump_sys_chdir(path); + if (res == -1) + atf_tc_fail("chdir failed"); + + quit = 0; + + res = pthread_create(&th1, NULL, func1, &quit); + if (res != 0) + atf_tc_fail("pthread_create1 failed"); + res = pthread_create(&th2, NULL, func2, &quit); + if (res != 0) + atf_tc_fail("pthread_create2 failed"); + + sleep(10); + + quit = 1; + + res = pthread_join(th2, NULL); + if (res != 0) + atf_tc_fail("pthread_join2 failed"); + res = pthread_join(th1, NULL); + if (res != 0) + atf_tc_fail("pthread_join1 failed"); + + res = rump_sys_fchdir(fd); + if (res == -1) + atf_tc_fail("fchdir failed"); +} + +ATF_FSAPPLY(race, "rmdir(2) race"); diff --git a/contrib/netbsd-tests/fs/vfs/t_ro.c b/contrib/netbsd-tests/fs/vfs/t_ro.c new file mode 100644 index 0000000..f7f4581 --- /dev/null +++ b/contrib/netbsd-tests/fs/vfs/t_ro.c @@ -0,0 +1,203 @@ +/* $NetBSD: t_ro.c,v 1.6 2017/01/13 21:30:40 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/h_fsmacros.h" +#include "h_macros.h" + +#define AFILE "testfile" +#define ADIR "testdir" +#define AFIFO "testfifo" +#define ASYMLINK "testsymlink" +#define ALINK "testlink" +#define FUNTEXT "this is some non-humppa text" +#define FUNSIZE (sizeof(FUNTEXT)-1) + +static void +nullgen(const atf_tc_t *tc, const char *mp) +{ + + return; +} + +static void +filegen(const atf_tc_t *tc, const char *mp) +{ + int fd; + + FSTEST_ENTER(); + RL(fd = rump_sys_open(AFILE, O_CREAT | O_RDWR, 0777)); + ATF_REQUIRE_EQ(rump_sys_write(fd, FUNTEXT, FUNSIZE), FUNSIZE); + RL(rump_sys_close(fd)); + FSTEST_EXIT(); +} + +/* + * + * BEGIN tests + * + */ + +static void +create(const atf_tc_t *tc, const char *mp) +{ + + FSTEST_ENTER(); + ATF_REQUIRE_ERRNO(EROFS, rump_sys_open(AFILE, O_CREAT|O_RDONLY) == -1); + FSTEST_EXIT(); +} + +static void +rmfile(const atf_tc_t *tc, const char *mp) +{ + + FSTEST_ENTER(); + ATF_REQUIRE_ERRNO(EROFS, rump_sys_unlink(AFILE) == -1); + FSTEST_EXIT(); +} + +static void +fileio(const atf_tc_t *tc, const char *mp) +{ + int fd; + char buf[FUNSIZE+1]; + int expected; + + if (FSTYPE_NFSRO(tc)) + expected = EACCES; + else + expected = EROFS; + + FSTEST_ENTER(); + RL(fd = rump_sys_open(AFILE, O_RDONLY)); + ATF_REQUIRE_EQ(rump_sys_read(fd, buf, FUNSIZE), FUNSIZE); + buf[FUNSIZE] = '\0'; + ATF_REQUIRE_STREQ(buf, FUNTEXT); + RL(rump_sys_close(fd)); + + ATF_REQUIRE_ERRNO(expected, rump_sys_open(AFILE, O_WRONLY) == -1); + ATF_REQUIRE_ERRNO(expected, rump_sys_open(AFILE, O_RDWR) == -1); + FSTEST_EXIT(); +} + +static void +attrs(const atf_tc_t *tc, const char *mp) +{ + struct timeval sometvs[2]; + struct stat sb; + int fd; + + FSTEST_ENTER(); + + RL(rump_sys_stat(AFILE, &sb)); + + ATF_REQUIRE_ERRNO(EROFS, rump_sys_chmod(AFILE, 0775) == -1); + if (!FSTYPE_MSDOS(tc)) + ATF_REQUIRE_ERRNO(EROFS, rump_sys_chown(AFILE, 1, 1) == -1); + ATF_REQUIRE_ERRNO(EROFS, rump_sys_utimes(AFILE, sometvs) == -1); + + RL(fd = rump_sys_open(AFILE, O_RDONLY)); + ATF_REQUIRE_ERRNO(EROFS, rump_sys_fchmod(fd, 0775) == -1); + if (!FSTYPE_MSDOS(tc)) + ATF_REQUIRE_ERRNO(EROFS, rump_sys_fchown(fd, 1, 1) == -1); + ATF_REQUIRE_ERRNO(EROFS, rump_sys_futimes(fd, sometvs) == -1); + RL(rump_sys_close(fd)); + + FSTEST_EXIT(); +} + +static void +createdir(const atf_tc_t *tc, const char *mp) +{ + + FSTEST_ENTER(); + ATF_REQUIRE_ERRNO(EROFS, rump_sys_mkdir(ADIR, 0775) == -1); + FSTEST_EXIT(); +} + +static void +createfifo(const atf_tc_t *tc, const char *mp) +{ + + FSTEST_ENTER(); + ATF_REQUIRE_ERRNO(EROFS, rump_sys_mkfifo(AFIFO, 0775) == -1); + FSTEST_EXIT(); +} + +static void +createsymlink(const atf_tc_t *tc, const char *mp) +{ + + FSTEST_ENTER(); + ATF_REQUIRE_ERRNO(EROFS, rump_sys_symlink("hoge", ASYMLINK) == -1); + FSTEST_EXIT(); +} + +static void +createlink(const atf_tc_t *tc, const char *mp) +{ + + FSTEST_ENTER(); + ATF_REQUIRE_ERRNO(EROFS, rump_sys_link(AFILE, ALINK) == -1); + FSTEST_EXIT(); +} + +ATF_TC_FSAPPLY_RO(create, "create file on r/o mount", nullgen); +ATF_TC_FSAPPLY_RO(rmfile, "remove file from r/o mount", filegen); +ATF_TC_FSAPPLY_RO(fileio, "can read a file but not write it", filegen); +ATF_TC_FSAPPLY_RO(attrs, "can query but not change attributes", filegen); +ATF_TC_FSAPPLY_RO(createdir, "create directory on r/o mount", nullgen); +ATF_TC_FSAPPLY_RO(createfifo, "create fifo on r/o mount", nullgen); +ATF_TC_FSAPPLY_RO(createsymlink, "create symlink on r/o mount", nullgen); +ATF_TC_FSAPPLY_RO(createlink, "create hardlink on r/o mount", filegen); + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_FSAPPLY_RO(create); + ATF_TP_FSAPPLY_RO(rmfile); + ATF_TP_FSAPPLY_RO(fileio); + ATF_TP_FSAPPLY_RO(attrs); + ATF_TP_FSAPPLY_RO(createdir); + ATF_TP_FSAPPLY_RO(createfifo); + ATF_TP_FSAPPLY_RO(createsymlink); + ATF_TP_FSAPPLY_RO(createlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/vfs/t_rwtoro.c b/contrib/netbsd-tests/fs/vfs/t_rwtoro.c new file mode 100644 index 0000000..ca8af07 --- /dev/null +++ b/contrib/netbsd-tests/fs/vfs/t_rwtoro.c @@ -0,0 +1,233 @@ +/* $NetBSD: t_rwtoro.c,v 1.1 2017/01/27 10:45:11 hannken Exp $ */ + +/*- + * Copyright (c) 2017 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "../common/h_fsmacros.h" +#include "../../h_macros.h" + +static const char *unsupported = "fs does not support r/o remount"; +static char file_path[MAXPATHLEN]; +static int file_fd; + +/* + * Remount the filesystem read-only and test errno. + * Skip filesystems that don't implement read-write -> read-only. + */ +static void +remount_ro(const atf_tc_t *tc, const char *mp, int expected_errno) +{ + int error; + union { + struct tmpfs_args tmpfs; + char data[4095]; + } mount_args; + int mount_args_length; + struct statvfs sbuf; + + if (FSTYPE_ZFS(tc)) + atf_tc_skip("%s", unsupported); + + /* Prepare mount arguments. */ + RL(rump_sys_statvfs1(mp, &sbuf, ST_WAIT)); + mount_args_length = sizeof(mount_args); + memset(&mount_args, 0, mount_args_length); + if (FSTYPE_TMPFS(tc)) + mount_args.tmpfs.ta_version = TMPFS_ARGS_VERSION; + mount_args_length = rump_sys_mount(sbuf.f_fstypename, mp, MNT_GETARGS, + &mount_args, mount_args_length); + ATF_CHECK(mount_args_length >= 0); + + /* Remount and test result. */ + error = rump_sys_mount(sbuf.f_fstypename, mp, MNT_UPDATE | MNT_RDONLY, + &mount_args, mount_args_length); + if (errno == EOPNOTSUPP) + atf_tc_skip("%s", unsupported); + if (expected_errno == 0) + ATF_CHECK(error == 0); + else + ATF_CHECK_ERRNO(expected_errno, error == -1); +} + +static void +open_file_ro(const char *prefix) +{ + + snprintf(file_path, sizeof(file_path), "%s/file", prefix); + RL(file_fd = rump_sys_open(file_path, O_CREAT | O_RDWR, 0777)); + RL(rump_sys_close(file_fd)); + RL(file_fd = rump_sys_open(file_path, O_RDONLY)); +} + +static void +open_file_ro_unlink(const char *prefix) +{ + + snprintf(file_path, sizeof(file_path), "%s/file", prefix); + RL(file_fd = rump_sys_open(file_path, O_CREAT | O_RDWR, 0777)); + RL(rump_sys_close(file_fd)); + RL(file_fd = rump_sys_open(file_path, O_RDONLY)); + RL(rump_sys_unlink(file_path)); +} + +static void +open_file_rw(const char *prefix) +{ + + snprintf(file_path, sizeof(file_path), "%s/file", prefix); + RL(file_fd = rump_sys_open(file_path, O_CREAT | O_RDWR, 0777)); +} + +static void +close_file(const char *unused) +{ + + RL(rump_sys_close(file_fd)); +} + +static void +basic_test(const atf_tc_t *tc, const char *mp, int expected_errno, + bool use_layer, void (*pre)(const char *), void (*post)(const char *)) +{ + const char *null_mount = "/nullm"; + struct null_args nargs; + + if (use_layer) { + RL(rump_sys_mkdir(null_mount, 0777)); + memset(&nargs, 0, sizeof(nargs)); + nargs.nulla_target = __UNCONST(mp);; + RL(rump_sys_mount(MOUNT_NULL, null_mount, 0, + &nargs, sizeof(nargs))); + } + if (pre) + (*pre)(use_layer ? null_mount : mp); + remount_ro(tc, mp, expected_errno); + if (post) + (*post)(use_layer ? null_mount : mp); + if (use_layer) + RL(rump_sys_unmount(null_mount, 0)); +} + +static void +noneopen(const atf_tc_t *tc, const char *mp) +{ + + basic_test(tc, mp, 0, false, NULL, NULL); +} + +static void +readopen(const atf_tc_t *tc, const char *mp) +{ + + basic_test(tc, mp, 0, false, open_file_ro, close_file); +} + +static void +writeopen(const atf_tc_t *tc, const char *mp) +{ + + basic_test(tc, mp, EBUSY, false, open_file_rw, close_file); +} + +static void +read_unlinked(const atf_tc_t *tc, const char *mp) +{ + + basic_test(tc, mp, EBUSY, false, open_file_ro_unlink, close_file); +} + +static void +layer_noneopen(const atf_tc_t *tc, const char *mp) +{ + + basic_test(tc, mp, 0, true, NULL, NULL); +} + +static void +layer_readopen(const atf_tc_t *tc, const char *mp) +{ + + basic_test(tc, mp, 0, true, open_file_ro, close_file); +} + +static void +layer_writeopen(const atf_tc_t *tc, const char *mp) +{ + + basic_test(tc, mp, EBUSY, true, open_file_rw, close_file); +} + +static void +layer_read_unlinked(const atf_tc_t *tc, const char *mp) +{ + + basic_test(tc, mp, EBUSY, true, open_file_ro_unlink, close_file); +} + +ATF_TC_FSAPPLY(noneopen, "remount r/o with no file open"); +ATF_TC_FSAPPLY(readopen, "remount r/o with file open for reading"); +ATF_TC_FSAPPLY(writeopen, "remount r/o with file open for writing"); +ATF_TC_FSAPPLY(read_unlinked, + "remount r/o with unlinked file open for reading"); +ATF_TC_FSAPPLY(layer_noneopen, "remount r/o with no file open on layer"); +ATF_TC_FSAPPLY(layer_readopen, + "remount r/o with file open for reading on layer"); +ATF_TC_FSAPPLY(layer_writeopen, + "remount r/o with file open for writing on layer"); +ATF_TC_FSAPPLY(layer_read_unlinked, + "remount r/o with unlinked file open for reading on layer"); + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_FSAPPLY(noneopen); + ATF_TP_FSAPPLY(readopen); + ATF_TP_FSAPPLY(writeopen); + ATF_TP_FSAPPLY(read_unlinked); + ATF_TP_FSAPPLY(layer_noneopen); + ATF_TP_FSAPPLY(layer_readopen); + ATF_TP_FSAPPLY(layer_writeopen); + ATF_TP_FSAPPLY(layer_read_unlinked); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/vfs/t_union.c b/contrib/netbsd-tests/fs/vfs/t_union.c new file mode 100644 index 0000000..5da1ea1 --- /dev/null +++ b/contrib/netbsd-tests/fs/vfs/t_union.c @@ -0,0 +1,204 @@ +/* $NetBSD: t_union.c,v 1.9 2017/01/13 21:30:40 christos Exp $ */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "h_macros.h" +#include "../common/h_fsmacros.h" + +#define MSTR "magic bus" + +static void +xput_tfile(const char *mp, const char *path) +{ + char pathb[MAXPATHLEN]; + int fd; + + strcpy(pathb, mp); + strcat(pathb, "/"); + strcat(pathb, path); + + RL(fd = rump_sys_open(pathb, O_CREAT | O_RDWR, 0777)); + if (rump_sys_write(fd, MSTR, sizeof(MSTR)) != sizeof(MSTR)) + atf_tc_fail_errno("write to testfile"); + RL(rump_sys_close(fd)); +} + +static int +xread_tfile(const char *mp, const char *path) +{ + char pathb[MAXPATHLEN]; + char buf[128]; + int fd; + + strcpy(pathb, mp); + strcat(pathb, "/"); + strcat(pathb, path); + + fd = rump_sys_open(pathb, O_RDONLY); + if (fd == -1) + return errno; + if (rump_sys_read(fd, buf, sizeof(buf)) == -1) + atf_tc_fail_errno("read tfile"); + RL(rump_sys_close(fd)); + if (strcmp(buf, MSTR) == 0) + return 0; + return EPROGMISMATCH; +} + +/* + * Mount a unionfs for testing. Before calling, "mp" contains + * the upper layer. Lowerpath is constructed so that the directory + * contains rumpfs. + */ +static void +mountunion(const char *mp, char *lowerpath) +{ + struct union_args unionargs; + + sprintf(lowerpath, "/lower"); + rump_sys_mkdir(lowerpath, 0777); + + /* mount the union with our testfs as the upper layer */ + memset(&unionargs, 0, sizeof(unionargs)); + unionargs.target = lowerpath; + unionargs.mntflags = UNMNT_BELOW; + + if (rump_sys_mount(MOUNT_UNION, mp, 0, + &unionargs, sizeof(unionargs)) == -1) { + if (errno == EOPNOTSUPP) { + atf_tc_skip("fs does not support VOP_WHITEOUT"); + } else { + atf_tc_fail_errno("union mount"); + } + } +} + +#if 0 +static void +toggleroot(void) +{ + static int status; + + status ^= MNT_RDONLY; + + printf("0x%x\n", status); + RL(rump_sys_mount(MOUNT_RUMPFS, "/", status | MNT_UPDATE, NULL, 0)); +} +#endif + +#define TFILE "tensti" +#define TDIR "testdir" +#define TDFILE TDIR "/indir" + +static void +basic(const atf_tc_t *tc, const char *mp) +{ + char lowerpath[MAXPATHLEN]; + char dbuf[8192]; + struct stat sb; + struct dirent *dp; + int error, fd, dsize; + + mountunion(mp, lowerpath); + + /* create a file in the lower layer */ + xput_tfile(lowerpath, TFILE); + + /* first, test we can read the old file from the new namespace */ + error = xread_tfile(mp, TFILE); + if (error != 0) + atf_tc_fail("union compare failed: %d (%s)", + error, strerror(error)); + + /* then, test upper layer writes don't affect the lower layer */ + xput_tfile(mp, "kiekko"); + if ((error = xread_tfile(lowerpath, "kiekko")) != ENOENT) + atf_tc_fail("invisibility failed: %d (%s)", + error, strerror(error)); + + /* check that we can whiteout stuff in the upper layer */ + FSTEST_ENTER(); + RL(rump_sys_unlink(TFILE)); + ATF_REQUIRE_ERRNO(ENOENT, rump_sys_stat(TFILE, &sb) == -1); + FSTEST_EXIT(); + + /* check that the removed node is not in the directory listing */ + RL(fd = rump_sys_open(mp, O_RDONLY)); + RL(dsize = rump_sys_getdents(fd, dbuf, sizeof(dbuf))); + for (dp = (struct dirent *)dbuf; + (char *)dp < dbuf + dsize; + dp = _DIRENT_NEXT(dp)) { + if (strcmp(dp->d_name, TFILE) == 0 && dp->d_type != DT_WHT) + atf_tc_fail("removed file non-white-outed"); + } + RL(rump_sys_close(fd)); + + RL(rump_sys_unmount(mp, 0)); +} + +static void +whiteout(const atf_tc_t *tc, const char *mp) +{ + char lower[MAXPATHLEN]; + struct stat sb; + void *fsarg; + + /* + * XXX: use ffs here to make sure any screwups in rumpfs don't + * affect the test + */ + RL(ffs_fstest_newfs(tc, &fsarg, "daimage", 1024*1024*5, NULL)); + RL(ffs_fstest_mount(tc, fsarg, "/lower", 0)); + + /* create a file in the lower layer */ + RL(rump_sys_chdir("/lower")); + RL(rump_sys_mkdir(TDIR, 0777)); + RL(rump_sys_mkdir(TDFILE, 0777)); + RL(rump_sys_chdir("/")); + + RL(ffs_fstest_unmount(tc, "/lower", 0)); + RL(ffs_fstest_mount(tc, fsarg, "/lower", MNT_RDONLY)); + + mountunion(mp, lower); + + FSTEST_ENTER(); + ATF_REQUIRE_ERRNO(ENOTEMPTY, rump_sys_rmdir(TDIR) == -1); + RL(rump_sys_rmdir(TDFILE)); + RL(rump_sys_rmdir(TDIR)); + ATF_REQUIRE_ERRNO(ENOENT, rump_sys_stat(TDFILE, &sb) == -1); + ATF_REQUIRE_ERRNO(ENOENT, rump_sys_stat(TDIR, &sb) == -1); + + RL(rump_sys_mkdir(TDIR, 0777)); + RL(rump_sys_stat(TDIR, &sb)); + ATF_REQUIRE_ERRNO(ENOENT, rump_sys_stat(TDFILE, &sb) == -1); + FSTEST_EXIT(); + + RL(rump_sys_unmount(mp, 0)); +} + +ATF_TC_FSAPPLY(basic, "check basic union functionality"); +ATF_TC_FSAPPLY(whiteout, "create whiteout in upper layer"); + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_FSAPPLY(basic); + ATF_TP_FSAPPLY(whiteout); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/vfs/t_unpriv.c b/contrib/netbsd-tests/fs/vfs/t_unpriv.c new file mode 100644 index 0000000..6536c21 --- /dev/null +++ b/contrib/netbsd-tests/fs/vfs/t_unpriv.c @@ -0,0 +1,239 @@ +/* $NetBSD: t_unpriv.c,v 1.13 2017/01/13 21:30:40 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include + +#include +#include + +#include "../common/h_fsmacros.h" +#include "h_macros.h" + +#define USES_OWNER \ + if (FSTYPE_MSDOS(tc)) \ + atf_tc_skip("owner not supported by file system") + +static void +owner(const atf_tc_t *tc, const char *mp) +{ + + USES_OWNER; + + FSTEST_ENTER(); + + rump_pub_lwproc_rfork(RUMP_RFCFDG); + if (rump_sys_setuid(1) == -1) + atf_tc_fail_errno("setuid"); + if (rump_sys_chown(".", 1, -1) != -1 || errno != EPERM) + atf_tc_fail_errno("chown"); + if (rump_sys_chmod(".", 0000) != -1 || errno != EPERM) + atf_tc_fail_errno("chmod"); + rump_pub_lwproc_releaselwp(); + + if (rump_sys_chown(".", 1, -1) == -1) + atf_tc_fail_errno("chown"); + + rump_pub_lwproc_rfork(RUMP_RFCFDG); + if (rump_sys_setuid(1) == -1) + atf_tc_fail_errno("setuid"); + if (rump_sys_chown(".", 1, -1) == -1) + atf_tc_fail_errno("chown"); + if (rump_sys_chmod(".", 0000) == -1) + atf_tc_fail_errno("chmod"); + rump_pub_lwproc_releaselwp(); + + FSTEST_EXIT(); +} + +static void +dirperms(const atf_tc_t *tc, const char *mp) +{ + char name[] = "dir.test/file.test"; + char *dir = dirname(name); + int fd; + + if (FSTYPE_SYSVBFS(tc)) + atf_tc_skip("directories not supported by file system"); + + FSTEST_ENTER(); + + if (rump_sys_mkdir(dir, 0777) == -1) + atf_tc_fail_errno("mkdir"); + + rump_pub_lwproc_rfork(RUMP_RFCFDG); + if (rump_sys_setuid(1) == -1) + atf_tc_fail_errno("setuid"); + if (FSTYPE_ZFS(tc)) + atf_tc_expect_fail("PR kern/47656: Test known to be broken"); + if (rump_sys_open(name, O_RDWR|O_CREAT, 0666) != -1 || errno != EACCES) + atf_tc_fail_errno("open"); + rump_pub_lwproc_releaselwp(); + + if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) + atf_tc_fail_errno("open"); + if (rump_sys_close(fd) == -1) + atf_tc_fail_errno("close"); + + rump_pub_lwproc_rfork(RUMP_RFCFDG); + if (rump_sys_setuid(1) == -1) + atf_tc_fail_errno("setuid"); + if (rump_sys_unlink(name) != -1 || errno != EACCES) + atf_tc_fail_errno("unlink"); + rump_pub_lwproc_releaselwp(); + + if (rump_sys_unlink(name) == -1) + atf_tc_fail_errno("unlink"); + + if (rump_sys_rmdir(dir) == -1) + atf_tc_fail_errno("rmdir"); + + FSTEST_EXIT(); +} + +static void +times(const atf_tc_t *tc, const char *mp) +{ + const char *name = "file.test"; + int fd; + unsigned int i, j; + struct timeval tmv[2]; + static struct timeval tmvs[] = { + { QUAD_MIN, 0 }, + { 0, 0 }, + { QUAD_MAX, 999999 } + }; + + FSTEST_ENTER(); + + if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) + atf_tc_fail_errno("open"); + if (rump_sys_close(fd) == -1) + atf_tc_fail_errno("close"); + + rump_pub_lwproc_rfork(RUMP_RFCFDG); + if (rump_sys_setuid(1) == -1) + atf_tc_fail_errno("setuid"); + if (FSTYPE_ZFS(tc)) + atf_tc_expect_fail("PR kern/47656: Test known to be broken"); + if (rump_sys_utimes(name, NULL) != -1 || errno != EACCES) + atf_tc_fail_errno("utimes"); + rump_pub_lwproc_releaselwp(); + + if (rump_sys_utimes(name, NULL) == -1) + atf_tc_fail_errno("utimes"); + + for (i = 0; i < sizeof(tmvs) / sizeof(tmvs[0]); i++) { + for (j = 0; j < sizeof(tmvs) / sizeof(tmvs[0]); j++) { + tmv[0] = tmvs[i]; + tmv[1] = tmvs[j]; + rump_pub_lwproc_rfork(RUMP_RFCFDG); + if (rump_sys_setuid(1) == -1) + atf_tc_fail_errno("setuid"); + if (rump_sys_utimes(name, tmv) != -1 || errno != EPERM) + atf_tc_fail_errno("utimes"); + rump_pub_lwproc_releaselwp(); + + if (rump_sys_utimes(name, tmv) == -1) + atf_tc_fail_errno("utimes"); + } + } + + if (rump_sys_unlink(name) == -1) + atf_tc_fail_errno("unlink"); + + FSTEST_EXIT(); +} + +static void +flags(const atf_tc_t *tc, const char *mp) +{ + const char *name = "file.test"; + int fd, fflags; + struct stat st; + + FSTEST_ENTER(); + + if ((fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)) == -1) + atf_tc_fail_errno("open"); + if (rump_sys_close(fd) == -1) + atf_tc_fail_errno("close"); + + if (rump_sys_stat(name, &st) == -1) + atf_tc_fail_errno("stat"); + if (FSTYPE_ZFS(tc)) + atf_tc_expect_fail("PR kern/47656: Test known to be broken"); + if (rump_sys_chflags(name, st.st_flags) == -1) { + if (errno == EOPNOTSUPP) + atf_tc_skip("file flags not supported by file system"); + atf_tc_fail_errno("chflags"); + } + + fflags = st.st_flags | UF_IMMUTABLE; + + rump_pub_lwproc_rfork(RUMP_RFCFDG); + if (rump_sys_setuid(1) == -1) + atf_tc_fail_errno("setuid"); + fflags |= UF_IMMUTABLE; + if (rump_sys_chflags(name, fflags) != -1 || errno != EPERM) + atf_tc_fail_errno("chflags"); + rump_pub_lwproc_releaselwp(); + + if (rump_sys_chflags(name, fflags) == -1) + atf_tc_fail_errno("chflags"); + + fflags &= ~UF_IMMUTABLE; + if (rump_sys_chflags(name, fflags) == -1) + atf_tc_fail_errno("chflags"); + + if (rump_sys_unlink(name) == -1) + atf_tc_fail_errno("unlink"); + + FSTEST_EXIT(); +} + +ATF_TC_FSAPPLY(owner, "owner unprivileged checks"); +ATF_TC_FSAPPLY(dirperms, "directory permission checks"); +ATF_TC_FSAPPLY(times, "time set checks"); +ATF_TC_FSAPPLY(flags, "file flags checks"); + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_FSAPPLY(owner); + ATF_TP_FSAPPLY(dirperms); + ATF_TP_FSAPPLY(times); + ATF_TP_FSAPPLY(flags); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/vfs/t_vfsops.c b/contrib/netbsd-tests/fs/vfs/t_vfsops.c new file mode 100644 index 0000000..bbed9f9 --- /dev/null +++ b/contrib/netbsd-tests/fs/vfs/t_vfsops.c @@ -0,0 +1,211 @@ +/* $NetBSD: t_vfsops.c,v 1.12 2017/01/13 21:30:40 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/h_fsmacros.h" +#include "h_macros.h" + +static void +tmount(const atf_tc_t *tc, const char *path) +{ + + return; +} + +static void +tstatvfs(const atf_tc_t *tc, const char *path) +{ + const char *fstype = atf_tc_get_md_var(tc, "X-fs.mntname"); + struct statvfs svb; + + if (rump_sys_statvfs1(path, &svb, ST_WAIT) == -1) + atf_tc_fail_errno("statvfs"); + + ATF_REQUIRE(svb.f_namemax > 0 && svb.f_namemax <= MAXNAMLEN); + if (!(FSTYPE_PUFFS(tc) || FSTYPE_P2K_FFS(tc))) + ATF_REQUIRE_STREQ(svb.f_fstypename, fstype); + ATF_REQUIRE_STREQ(svb.f_mntonname, path); +} + +static void +tsync(const atf_tc_t *tc, const char *path) +{ + + rump_sys_sync(); +} + +#define MAGICSTR "just a string, I like A" +static void +tfilehandle(const atf_tc_t *tc, const char *path) +{ + char fpath[MAXPATHLEN]; + char buf[sizeof(MAGICSTR)]; + size_t fhsize; + void *fhp; + int fd; + + sprintf(fpath, "%s/file", path); + fd = rump_sys_open(fpath, O_RDWR | O_CREAT, 0777); + if (fd == -1) + atf_tc_fail_errno("open"); + + if (rump_sys_write(fd, MAGICSTR, sizeof(MAGICSTR)) != sizeof(MAGICSTR)) + atf_tc_fail("write to file"); + rump_sys_close(fd); + + /* + * Get file handle size. + * This also weeds out unsupported file systems. + */ + fhsize = 0; + if (rump_sys_getfh(fpath, NULL, &fhsize) == -1) { + if (errno == EOPNOTSUPP) { + atf_tc_skip("file handles not supported"); + } else if (errno != E2BIG) { + atf_tc_fail_errno("getfh size"); + } + } + + fhp = malloc(fhsize); + if (rump_sys_getfh(fpath, fhp, &fhsize) == -1) + atf_tc_fail_errno("getfh"); + + /* open file based on file handle */ + fd = rump_sys_fhopen(fhp, fhsize, O_RDONLY); + if (fd == -1) { + atf_tc_fail_errno("fhopen"); + } + + /* check that we got the same file */ + if (rump_sys_read(fd, buf, sizeof(buf)) != sizeof(MAGICSTR)) + atf_tc_fail("read fhopened file"); + + ATF_REQUIRE_STREQ(buf, MAGICSTR); + + rump_sys_close(fd); +} + +#define FNAME "a_file" +static void +tfhremove(const atf_tc_t *tc, const char *path) +{ + size_t fhsize; + void *fhp; + int fd; + + RL(rump_sys_chdir(path)); + RL(fd = rump_sys_open(FNAME, O_RDWR | O_CREAT, 0777)); + RL(rump_sys_close(fd)); + + fhsize = 0; + if (rump_sys_getfh(FNAME, NULL, &fhsize) == -1) { + if (errno == EOPNOTSUPP) { + atf_tc_skip("file handles not supported"); + } else if (errno != E2BIG) { + atf_tc_fail_errno("getfh size"); + } + } + + fhp = malloc(fhsize); + RL(rump_sys_getfh(FNAME, fhp, &fhsize)); + RL(rump_sys_unlink(FNAME)); + + if (FSTYPE_LFS(tc)) + atf_tc_expect_fail("fhopen() for removed file succeeds " + "(PR kern/43745)"); + ATF_REQUIRE_ERRNO(ESTALE, rump_sys_fhopen(fhp, fhsize, O_RDONLY) == -1); + atf_tc_expect_pass(); + + RL(rump_sys_chdir("/")); +} +#undef FNAME + +/* + * This test only checks the file system doesn't crash. We *might* + * try a valid file handle. + */ +static void +tfhinval(const atf_tc_t *tc, const char *path) +{ + size_t fhsize; + void *fhp; + unsigned long seed; + int fd; + + srandom(seed = time(NULL)); + printf("RNG seed %lu\n", seed); + + RL(rump_sys_chdir(path)); + fhsize = 0; + if (rump_sys_getfh(".", NULL, &fhsize) == -1) { + if (errno == EOPNOTSUPP) { + atf_tc_skip("file handles not supported"); + } else if (errno != E2BIG) { + atf_tc_fail_errno("getfh size"); + } + } + + fhp = malloc(fhsize); + tests_makegarbage(fhp, fhsize); + fd = rump_sys_fhopen(fhp, fhsize, O_RDWR); + if (fd != -1) + rump_sys_close(fd); + + RL(rump_sys_chdir("/")); +} + +ATF_TC_FSAPPLY(tmount, "mount/unmount"); +ATF_TC_FSAPPLY(tstatvfs, "statvfs"); +ATF_TC_FSAPPLY(tsync, "sync"); +ATF_TC_FSAPPLY(tfilehandle, "file handles"); +ATF_TC_FSAPPLY(tfhremove, "fhtovp for removed file"); +ATF_TC_FSAPPLY(tfhinval, "fhopen invalid filehandle"); + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_FSAPPLY(tmount); + ATF_TP_FSAPPLY(tstatvfs); + ATF_TP_FSAPPLY(tsync); + ATF_TP_FSAPPLY(tfilehandle); + ATF_TP_FSAPPLY(tfhremove); + ATF_TP_FSAPPLY(tfhinval); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/vfs/t_vnops.c b/contrib/netbsd-tests/fs/vfs/t_vnops.c new file mode 100644 index 0000000..7da53c8 --- /dev/null +++ b/contrib/netbsd-tests/fs/vfs/t_vnops.c @@ -0,0 +1,1080 @@ +/* $NetBSD: t_vnops.c,v 1.59 2017/01/13 21:30:40 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../common/h_fsmacros.h" +#include "h_macros.h" + +#define TESTFILE "afile" + +#define USES_DIRS \ + if (FSTYPE_SYSVBFS(tc)) \ + atf_tc_skip("directories not supported by file system") + +#define USES_SYMLINKS \ + if (FSTYPE_SYSVBFS(tc) || FSTYPE_MSDOS(tc)) \ + atf_tc_skip("symlinks not supported by file system") + +static char * +md(char *buf, size_t buflen, const char *base, const char *tail) +{ + + snprintf(buf, buflen, "%s/%s", base, tail); + return buf; +} + +static void +lookup_simple(const atf_tc_t *tc, const char *mountpath) +{ + char pb[MAXPATHLEN], final[MAXPATHLEN]; + struct stat sb1, sb2; + + strcpy(final, mountpath); + snprintf(pb, sizeof(pb), "%s/../%s", mountpath, basename(final)); + if (rump_sys_stat(pb, &sb1) == -1) + atf_tc_fail_errno("stat 1"); + + snprintf(pb, sizeof(pb), "%s/./../%s", mountpath, basename(final)); + if (rump_sys_stat(pb, &sb2) == -1) + atf_tc_fail_errno("stat 2"); + + ATF_REQUIRE(memcmp(&sb1, &sb2, sizeof(sb1)) == 0); +} + +static void +lookup_complex(const atf_tc_t *tc, const char *mountpath) +{ + char pb[MAXPATHLEN]; + struct stat sb1, sb2; + struct timespec atplus1, onesec; + + USES_DIRS; + + snprintf(pb, sizeof(pb), "%s/dir", mountpath); + if (rump_sys_mkdir(pb, 0777) == -1) + atf_tc_fail_errno("mkdir"); + if (rump_sys_stat(pb, &sb1) == -1) + atf_tc_fail_errno("stat 1"); + + snprintf(pb, sizeof(pb), "%s/./dir/../././dir/.", mountpath); + if (rump_sys_stat(pb, &sb2) == -1) + atf_tc_fail_errno("stat 2"); + + /* + * The lookup is permitted to modify the access time of + * any directories searched - such a directory is the + * subject of this test. Any difference should cause + * the 2nd lookup atime tp be >= the first, if it is ==, all is + * OK (atime is not required to be modified by the search, or + * both references may happen within the came clock tick), if the + * 2nd lookup atime is > the first, but not "too much" greater, + * just set it back, so the memcmp just below succeeds + * (assuming all else is OK). + */ + onesec.tv_sec = 1; + onesec.tv_nsec = 0; + timespecadd(&sb1.st_atimespec, &onesec, &atplus1); + if (timespeccmp(&sb2.st_atimespec, &sb1.st_atimespec, >) && + timespeccmp(&sb2.st_atimespec, &atplus1, <)) + sb2.st_atimespec = sb1.st_atimespec; + + if (memcmp(&sb1, &sb2, sizeof(sb1)) != 0) { + printf("what\tsb1\t\tsb2\n"); + +#define FIELD(FN) \ + printf(#FN "\t%lld\t%lld\n", \ + (long long)sb1.FN, (long long)sb2.FN) +#define TIME(FN) \ + printf(#FN "\t%lld.%ld\t%lld.%ld\n", \ + (long long)sb1.FN.tv_sec, sb1.FN.tv_nsec, \ + (long long)sb2.FN.tv_sec, sb2.FN.tv_nsec) + + FIELD(st_dev); + FIELD(st_mode); + FIELD(st_ino); + FIELD(st_nlink); + FIELD(st_uid); + FIELD(st_gid); + FIELD(st_rdev); + TIME(st_atimespec); + TIME(st_mtimespec); + TIME(st_ctimespec); + TIME(st_birthtimespec); + FIELD(st_size); + FIELD(st_blocks); + FIELD(st_flags); + FIELD(st_gen); + +#undef FIELD +#undef TIME + + atf_tc_fail("stat results differ, see ouput for more details"); + } +} + +static void +dir_simple(const atf_tc_t *tc, const char *mountpath) +{ + char pb[MAXPATHLEN]; + struct stat sb; + + USES_DIRS; + + /* check we can create directories */ + snprintf(pb, sizeof(pb), "%s/dir", mountpath); + if (rump_sys_mkdir(pb, 0777) == -1) + atf_tc_fail_errno("mkdir"); + if (rump_sys_stat(pb, &sb) == -1) + atf_tc_fail_errno("stat new directory"); + + /* check we can remove then and that it makes them unreachable */ + if (rump_sys_rmdir(pb) == -1) + atf_tc_fail_errno("rmdir"); + if (rump_sys_stat(pb, &sb) != -1 || errno != ENOENT) + atf_tc_fail("ENOENT expected from stat"); +} + +static void +dir_notempty(const atf_tc_t *tc, const char *mountpath) +{ + char pb[MAXPATHLEN], pb2[MAXPATHLEN]; + int fd, rv; + + USES_DIRS; + + /* check we can create directories */ + snprintf(pb, sizeof(pb), "%s/dir", mountpath); + if (rump_sys_mkdir(pb, 0777) == -1) + atf_tc_fail_errno("mkdir"); + + snprintf(pb2, sizeof(pb2), "%s/dir/file", mountpath); + fd = rump_sys_open(pb2, O_RDWR | O_CREAT, 0777); + if (fd == -1) + atf_tc_fail_errno("create file"); + rump_sys_close(fd); + + rv = rump_sys_rmdir(pb); + if (rv != -1 || errno != ENOTEMPTY) + atf_tc_fail("non-empty directory removed succesfully"); + + if (rump_sys_unlink(pb2) == -1) + atf_tc_fail_errno("cannot remove dir/file"); + + if (rump_sys_rmdir(pb) == -1) + atf_tc_fail_errno("remove directory"); +} + +static void +dir_rmdirdotdot(const atf_tc_t *tc, const char *mp) +{ + char pb[MAXPATHLEN]; + int xerrno; + + USES_DIRS; + + FSTEST_ENTER(); + RL(rump_sys_mkdir("test", 0777)); + RL(rump_sys_chdir("test")); + + RL(rump_sys_mkdir("subtest", 0777)); + RL(rump_sys_chdir("subtest")); + + md(pb, sizeof(pb), mp, "test/subtest"); + RL(rump_sys_rmdir(pb)); + md(pb, sizeof(pb), mp, "test"); + RL(rump_sys_rmdir(pb)); + + if (FSTYPE_NFS(tc)) + xerrno = ESTALE; + else + xerrno = ENOENT; + ATF_REQUIRE_ERRNO(xerrno, rump_sys_chdir("..") == -1); + FSTEST_EXIT(); +} + +static void +checkfile(const char *path, struct stat *refp) +{ + char buf[MAXPATHLEN]; + struct stat sb; + static int n = 1; + + md(buf, sizeof(buf), path, "file"); + if (rump_sys_stat(buf, &sb) == -1) + atf_tc_fail_errno("cannot stat file %d (%s)", n, buf); + if (memcmp(&sb, refp, sizeof(sb)) != 0) + atf_tc_fail("stat mismatch %d", n); + n++; +} + +static void +rename_dir(const atf_tc_t *tc, const char *mp) +{ + char pb1[MAXPATHLEN], pb2[MAXPATHLEN], pb3[MAXPATHLEN]; + struct stat ref, sb; + + if (FSTYPE_RUMPFS(tc)) + atf_tc_skip("rename not supported by file system"); + + USES_DIRS; + + md(pb1, sizeof(pb1), mp, "dir1"); + if (rump_sys_mkdir(pb1, 0777) == -1) + atf_tc_fail_errno("mkdir 1"); + + md(pb2, sizeof(pb2), mp, "dir2"); + if (rump_sys_mkdir(pb2, 0777) == -1) + atf_tc_fail_errno("mkdir 2"); + md(pb2, sizeof(pb2), mp, "dir2/subdir"); + if (rump_sys_mkdir(pb2, 0777) == -1) + atf_tc_fail_errno("mkdir 3"); + + md(pb3, sizeof(pb3), mp, "dir1/file"); + if (rump_sys_mknod(pb3, S_IFREG | 0777, -1) == -1) + atf_tc_fail_errno("create file"); + if (rump_sys_stat(pb3, &ref) == -1) + atf_tc_fail_errno("stat of file"); + + /* + * First try ops which should succeed. + */ + + /* rename within directory */ + md(pb3, sizeof(pb3), mp, "dir3"); + if (rump_sys_rename(pb1, pb3) == -1) + atf_tc_fail_errno("rename 1"); + checkfile(pb3, &ref); + + /* rename directory onto itself (two ways, should fail) */ + md(pb1, sizeof(pb1), mp, "dir3/."); + if (rump_sys_rename(pb1, pb3) != -1 || errno != EINVAL) + atf_tc_fail_errno("rename 2"); + if (rump_sys_rename(pb3, pb1) != -1 || errno != EISDIR) + atf_tc_fail_errno("rename 3"); + + checkfile(pb3, &ref); + + /* rename father of directory into directory */ + md(pb1, sizeof(pb1), mp, "dir2/dir"); + md(pb2, sizeof(pb2), mp, "dir2"); + if (rump_sys_rename(pb2, pb1) != -1 || errno != EINVAL) + atf_tc_fail_errno("rename 4"); + + /* same for grandfather */ + md(pb1, sizeof(pb1), mp, "dir2/subdir/dir2"); + if (rump_sys_rename(pb2, pb1) != -1 || errno != EINVAL) + atf_tc_fail("rename 5"); + + checkfile(pb3, &ref); + + /* rename directory over a non-empty directory */ + if (rump_sys_rename(pb2, pb3) != -1 || errno != ENOTEMPTY) + atf_tc_fail("rename 6"); + + /* cross-directory rename */ + md(pb1, sizeof(pb1), mp, "dir3"); + md(pb2, sizeof(pb2), mp, "dir2/somedir"); + if (rump_sys_rename(pb1, pb2) == -1) + atf_tc_fail_errno("rename 7"); + checkfile(pb2, &ref); + + /* move to parent directory */ + md(pb1, sizeof(pb1), mp, "dir2/somedir/../../dir3"); + if (rump_sys_rename(pb2, pb1) == -1) + atf_tc_fail_errno("rename 8"); + md(pb1, sizeof(pb1), mp, "dir2/../dir3"); + checkfile(pb1, &ref); + + /* atomic cross-directory rename */ + md(pb3, sizeof(pb3), mp, "dir2/subdir"); + if (rump_sys_rename(pb1, pb3) == -1) + atf_tc_fail_errno("rename 9"); + checkfile(pb3, &ref); + + /* rename directory over an empty directory */ + md(pb1, sizeof(pb1), mp, "parent"); + md(pb2, sizeof(pb2), mp, "parent/dir1"); + md(pb3, sizeof(pb3), mp, "parent/dir2"); + RL(rump_sys_mkdir(pb1, 0777)); + RL(rump_sys_mkdir(pb2, 0777)); + RL(rump_sys_mkdir(pb3, 0777)); + RL(rump_sys_rename(pb2, pb3)); + + RL(rump_sys_stat(pb1, &sb)); + if (! FSTYPE_MSDOS(tc)) + ATF_CHECK_EQ(sb.st_nlink, 3); + RL(rump_sys_rmdir(pb3)); + RL(rump_sys_rmdir(pb1)); +} + +static void +rename_dotdot(const atf_tc_t *tc, const char *mp) +{ + + if (FSTYPE_RUMPFS(tc)) + atf_tc_skip("rename not supported by file system"); + + USES_DIRS; + + if (rump_sys_chdir(mp) == -1) + atf_tc_fail_errno("chdir mountpoint"); + + if (rump_sys_mkdir("dir1", 0777) == -1) + atf_tc_fail_errno("mkdir 1"); + if (rump_sys_mkdir("dir2", 0777) == -1) + atf_tc_fail_errno("mkdir 2"); + + if (rump_sys_rename("dir1", "dir1/..") != -1 || errno != EINVAL) + atf_tc_fail_errno("self-dotdot to"); + + if (rump_sys_rename("dir1/..", "sometarget") != -1 || errno != EINVAL) + atf_tc_fail_errno("self-dotdot from"); + + if (rump_sys_rename("dir1", "dir2/..") != -1 || errno != EINVAL) + atf_tc_fail("other-dotdot"); + + rump_sys_chdir("/"); +} + +static void +rename_reg_nodir(const atf_tc_t *tc, const char *mp) +{ + bool haslinks; + struct stat sb; + ino_t f1ino; + + if (FSTYPE_RUMPFS(tc)) + atf_tc_skip("rename not supported by file system"); + + if (rump_sys_chdir(mp) == -1) + atf_tc_fail_errno("chdir mountpoint"); + + if (FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc)) + haslinks = false; + else + haslinks = true; + + if (rump_sys_mknod("file1", S_IFREG | 0777, -1) == -1) + atf_tc_fail_errno("create file"); + if (rump_sys_mknod("file2", S_IFREG | 0777, -1) == -1) + atf_tc_fail_errno("create file"); + + if (rump_sys_stat("file1", &sb) == -1) + atf_tc_fail_errno("stat"); + f1ino = sb.st_ino; + + if (haslinks) { + if (rump_sys_link("file1", "file_link") == -1) + atf_tc_fail_errno("link"); + if (rump_sys_stat("file_link", &sb) == -1) + atf_tc_fail_errno("stat"); + ATF_REQUIRE_EQ(sb.st_ino, f1ino); + ATF_REQUIRE_EQ(sb.st_nlink, 2); + } + + if (rump_sys_stat("file2", &sb) == -1) + atf_tc_fail_errno("stat"); + + if (rump_sys_rename("file1", "file3") == -1) + atf_tc_fail_errno("rename 1"); + if (rump_sys_stat("file3", &sb) == -1) + atf_tc_fail_errno("stat 1"); + if (haslinks) { + ATF_REQUIRE_EQ(sb.st_ino, f1ino); + } + if (rump_sys_stat("file1", &sb) != -1 || errno != ENOENT) + atf_tc_fail_errno("source 1"); + + if (rump_sys_rename("file3", "file2") == -1) + atf_tc_fail_errno("rename 2"); + if (rump_sys_stat("file2", &sb) == -1) + atf_tc_fail_errno("stat 2"); + if (haslinks) { + ATF_REQUIRE_EQ(sb.st_ino, f1ino); + } + + if (rump_sys_stat("file3", &sb) != -1 || errno != ENOENT) + atf_tc_fail_errno("source 2"); + + if (haslinks) { + if (rump_sys_rename("file2", "file_link") == -1) + atf_tc_fail_errno("rename hardlink"); + if (rump_sys_stat("file2", &sb) != -1 || errno != ENOENT) + atf_tc_fail_errno("source 3"); + if (rump_sys_stat("file_link", &sb) == -1) + atf_tc_fail_errno("stat 2"); + ATF_REQUIRE_EQ(sb.st_ino, f1ino); + ATF_REQUIRE_EQ(sb.st_nlink, 1); + } + + ATF_CHECK_ERRNO(EFAULT, rump_sys_rename("file2", NULL) == -1); + ATF_CHECK_ERRNO(EFAULT, rump_sys_rename(NULL, "file2") == -1); + + rump_sys_chdir("/"); +} + +/* PR kern/50607 */ +static void +create_many(const atf_tc_t *tc, const char *mp) +{ + char buf[64]; + int nfiles = 2324; /* #Nancy */ + int i; + + /* takes forever with many files */ + if (FSTYPE_MSDOS(tc)) + nfiles /= 4; + + RL(rump_sys_chdir(mp)); + + if (FSTYPE_SYSVBFS(tc)) { + /* fs doesn't support many files or subdirectories */ + nfiles = 5; + } else { + /* msdosfs doesn't like many entries in the root directory */ + RL(rump_sys_mkdir("subdir", 0777)); + RL(rump_sys_chdir("subdir")); + } + + /* create them */ +#define TESTFN "testfile" + for (i = 0; i < nfiles; i++) { + int fd; + + snprintf(buf, sizeof(buf), TESTFN "%d", i); + RL(fd = rump_sys_open(buf, O_RDWR|O_CREAT|O_EXCL, 0666)); + RL(rump_sys_close(fd)); + } + + /* wipe them out */ + for (i = 0; i < nfiles; i++) { + snprintf(buf, sizeof(buf), TESTFN "%d", i); + RLF(rump_sys_unlink(buf), "%s", buf); + } +#undef TESTFN + + rump_sys_chdir("/"); +} + +/* + * Test creating files with one-character names using all possible + * character values. Failures to create the file are ignored as the + * characters allowed in file names vary by file system, but at least + * we can check that the fs does not crash, and if the file is + * successfully created, unlinking it should also succeed. + */ +static void +create_nonalphanum(const atf_tc_t *tc, const char *mp) +{ + char buf[64]; + int i; + + RL(rump_sys_chdir(mp)); + + for (i = 0; i < 256; i++) { + int fd; + snprintf(buf, sizeof(buf), "%c", i); + fd = rump_sys_open(buf, O_RDWR|O_CREAT|O_EXCL, 0666); + if (fd == -1) + continue; + RLF(rump_sys_close(fd), "%d", fd); + RLF(rump_sys_unlink(buf), "%s", buf); + } + printf("\n"); + + rump_sys_chdir("/"); +} + +static void +create_nametoolong(const atf_tc_t *tc, const char *mp) +{ + char *name; + int fd; + long val; + size_t len; + + if (rump_sys_chdir(mp) == -1) + atf_tc_fail_errno("chdir mountpoint"); + + val = rump_sys_pathconf(".", _PC_NAME_MAX); + if (val == -1) + atf_tc_fail_errno("pathconf"); + + len = val + 1; + name = malloc(len+1); + if (name == NULL) + atf_tc_fail_errno("malloc"); + + memset(name, 'a', len); + *(name+len) = '\0'; + + val = rump_sys_pathconf(".", _PC_NO_TRUNC); + if (val == -1) + atf_tc_fail_errno("pathconf"); + + fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666); + if (val != 0 && (fd != -1 || errno != ENAMETOOLONG)) + atf_tc_fail_errno("open"); + + if (val == 0 && rump_sys_close(fd) == -1) + atf_tc_fail_errno("close"); + if (val == 0 && rump_sys_unlink(name) == -1) + atf_tc_fail_errno("unlink"); + + free(name); + + rump_sys_chdir("/"); +} + +static void +create_exist(const atf_tc_t *tc, const char *mp) +{ + const char *name = "hoge"; + int fd; + + RL(rump_sys_chdir(mp)); + RL(fd = rump_sys_open(name, O_RDWR|O_CREAT|O_EXCL, 0666)); + RL(rump_sys_close(fd)); + RL(rump_sys_unlink(name)); + RL(fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)); + RL(rump_sys_close(fd)); + RL(fd = rump_sys_open(name, O_RDWR|O_CREAT, 0666)); + RL(rump_sys_close(fd)); + ATF_REQUIRE_ERRNO(EEXIST, + (fd = rump_sys_open(name, O_RDWR|O_CREAT|O_EXCL, 0666))); + RL(rump_sys_unlink(name)); + RL(rump_sys_chdir("/")); +} + +static void +rename_nametoolong(const atf_tc_t *tc, const char *mp) +{ + char *name; + int res, fd; + long val; + size_t len; + + if (FSTYPE_RUMPFS(tc)) + atf_tc_skip("rename not supported by file system"); + + if (rump_sys_chdir(mp) == -1) + atf_tc_fail_errno("chdir mountpoint"); + + val = rump_sys_pathconf(".", _PC_NAME_MAX); + if (val == -1) + atf_tc_fail_errno("pathconf"); + + len = val + 1; + name = malloc(len+1); + if (name == NULL) + atf_tc_fail_errno("malloc"); + + memset(name, 'a', len); + *(name+len) = '\0'; + + fd = rump_sys_open("dummy", O_RDWR|O_CREAT, 0666); + if (fd == -1) + atf_tc_fail_errno("open"); + if (rump_sys_close(fd) == -1) + atf_tc_fail_errno("close"); + + val = rump_sys_pathconf(".", _PC_NO_TRUNC); + if (val == -1) + atf_tc_fail_errno("pathconf"); + + res = rump_sys_rename("dummy", name); + if (val != 0 && (res != -1 || errno != ENAMETOOLONG)) + atf_tc_fail_errno("rename"); + + if (val == 0 && rump_sys_unlink(name) == -1) + atf_tc_fail_errno("unlink"); + + free(name); + + rump_sys_chdir("/"); +} + +/* + * Test creating a symlink whose length is "len" bytes, not including + * the terminating NUL. + */ +static void +symlink_len(const atf_tc_t *tc, const char *mp, size_t len) +{ + char *buf; + int r; + + USES_SYMLINKS; + + RLF(rump_sys_chdir(mp), "%s", mp); + + buf = malloc(len + 1); + ATF_REQUIRE(buf); + memset(buf, 'a', len); + buf[len] = '\0'; + r = rump_sys_symlink(buf, "afile"); + if (r == -1) { + ATF_REQUIRE_ERRNO(ENAMETOOLONG, r); + } else { + RL(rump_sys_unlink("afile")); + } + free(buf); + + RL(rump_sys_chdir("/")); +} + +static void +symlink_zerolen(const atf_tc_t *tc, const char *mp) +{ + symlink_len(tc, mp, 0); +} + +static void +symlink_long(const atf_tc_t *tc, const char *mp) +{ + /* + * Test lengths close to powers of two, as those are likely + * to be edge cases. + */ + size_t len; + int fuzz; + for (len = 2; len <= 65536; len *= 2) { + for (fuzz = -1; fuzz <= 1; fuzz++) { + symlink_len(tc, mp, len + fuzz); + } + } +} + +static void +symlink_root(const atf_tc_t *tc, const char *mp) +{ + + USES_SYMLINKS; + + RL(rump_sys_chdir(mp)); + RL(rump_sys_symlink("/", "foo")); + RL(rump_sys_chdir("foo")); +} + +static void +attrs(const atf_tc_t *tc, const char *mp) +{ + struct stat sb, sb2; + struct timeval tv[2]; + int fd; + + FSTEST_ENTER(); + RL(fd = rump_sys_open(TESTFILE, O_RDWR | O_CREAT, 0755)); + RL(rump_sys_close(fd)); + RL(rump_sys_stat(TESTFILE, &sb)); + if (!(FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))) { + RL(rump_sys_chown(TESTFILE, 1, 2)); + sb.st_uid = 1; + sb.st_gid = 2; + RL(rump_sys_chmod(TESTFILE, 0123)); + sb.st_mode = (sb.st_mode & ~ACCESSPERMS) | 0123; + } + + tv[0].tv_sec = 1000000000; /* need something >1980 for msdosfs */ + tv[0].tv_usec = 1; + tv[1].tv_sec = 1000000002; /* need even seconds for msdosfs */ + tv[1].tv_usec = 3; + RL(rump_sys_utimes(TESTFILE, tv)); + RL(rump_sys_utimes(TESTFILE, tv)); /* XXX: utimes & birthtime */ + sb.st_atimespec.tv_sec = 1000000000; + sb.st_atimespec.tv_nsec = 1000; + sb.st_mtimespec.tv_sec = 1000000002; + sb.st_mtimespec.tv_nsec = 3000; + + RL(rump_sys_stat(TESTFILE, &sb2)); +#define CHECK(a) ATF_REQUIRE_EQ(sb.a, sb2.a) + if (!(FSTYPE_MSDOS(tc) || FSTYPE_SYSVBFS(tc))) { + CHECK(st_uid); + CHECK(st_gid); + CHECK(st_mode); + } + if (!FSTYPE_MSDOS(tc)) { + /* msdosfs has only access date, not time */ + CHECK(st_atimespec.tv_sec); + } + CHECK(st_mtimespec.tv_sec); + if (!(FSTYPE_EXT2FS(tc) || FSTYPE_MSDOS(tc) || + FSTYPE_SYSVBFS(tc) || FSTYPE_V7FS(tc))) { + CHECK(st_atimespec.tv_nsec); + CHECK(st_mtimespec.tv_nsec); + } +#undef CHECK + + FSTEST_EXIT(); +} + +static void +fcntl_lock(const atf_tc_t *tc, const char *mp) +{ + int fd, fd2; + struct flock l; + struct lwp *lwp1, *lwp2; + + FSTEST_ENTER(); + l.l_pid = 0; + l.l_start = l.l_len = 1024; + l.l_type = F_RDLCK | F_WRLCK; + l.l_whence = SEEK_END; + + lwp1 = rump_pub_lwproc_curlwp(); + RL(fd = rump_sys_open(TESTFILE, O_RDWR | O_CREAT, 0755)); + RL(rump_sys_ftruncate(fd, 8192)); + + RL(rump_sys_fcntl(fd, F_SETLK, &l)); + + /* Next, we fork and try to lock the same area */ + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + lwp2 = rump_pub_lwproc_curlwp(); + RL(fd2 = rump_sys_open(TESTFILE, O_RDWR, 0)); + ATF_REQUIRE_ERRNO(EAGAIN, rump_sys_fcntl(fd2, F_SETLK, &l)); + + /* Switch back and unlock... */ + rump_pub_lwproc_switch(lwp1); + l.l_type = F_UNLCK; + RL(rump_sys_fcntl(fd, F_SETLK, &l)); + + /* ... and try to lock again */ + rump_pub_lwproc_switch(lwp2); + l.l_type = F_RDLCK | F_WRLCK; + RL(rump_sys_fcntl(fd2, F_SETLK, &l)); + + RL(rump_sys_close(fd2)); + rump_pub_lwproc_releaselwp(); + + RL(rump_sys_close(fd)); + + FSTEST_EXIT(); +} + +static int +flock_compare(const void *p, const void *q) +{ + int a = ((const struct flock *)p)->l_start; + int b = ((const struct flock *)q)->l_start; + return a < b ? -1 : (a > b ? 1 : 0); +} + +/* + * Find all locks set by fcntl_getlock_pids test + * using GETLK for a range [start, start+end], and, + * if there is a blocking lock, recursively find + * all locks to the left (toward the beginning of + * a file) and to the right of the lock. + * The function also understands "until end of file" + * convention when len==0. + */ +static unsigned int +fcntl_getlocks(int fildes, off_t start, off_t len, + struct flock *lock, struct flock *end) +{ + unsigned int rv = 0; + const struct flock l = { start, len, 0, F_RDLCK, SEEK_SET }; + + if (lock == end) + return rv; + + RL(rump_sys_fcntl(fildes, F_GETLK, &l)); + + if (l.l_type == F_UNLCK) + return rv; + + *lock++ = l; + rv += 1; + + ATF_REQUIRE(l.l_whence == SEEK_SET); + + if (l.l_start > start) { + unsigned int n = + fcntl_getlocks(fildes, start, l.l_start - start, lock, end); + rv += n; + lock += n; + if (lock == end) + return rv; + } + + if (l.l_len == 0) /* does l spans until the end? */ + return rv; + + if (len == 0) /* are we looking for locks until the end? */ { + rv += fcntl_getlocks(fildes, l.l_start + l.l_len, len, lock, end); + } else if (l.l_start + l.l_len < start + len) { + len -= l.l_start + l.l_len - start; + rv += fcntl_getlocks(fildes, l.l_start + l.l_len, len, lock, end); + } + + return rv; +} + +static void +fcntl_getlock_pids(const atf_tc_t *tc, const char *mp) +{ + /* test non-overlaping ranges */ + struct flock expect[4]; + const struct flock lock[4] = { + { 0, 2, 0, F_WRLCK, SEEK_SET }, + { 2, 1, 0, F_WRLCK, SEEK_SET }, + { 7, 5, 0, F_WRLCK, SEEK_SET }, + { 4, 3, 0, F_WRLCK, SEEK_SET }, + }; + + /* Add extra element to make sure recursion does't stop at array end */ + struct flock result[5]; + + /* Add 5th process */ + int fd[5]; + pid_t pid[5]; + struct lwp *lwp[5]; + + unsigned int i, j; + const off_t sz = 8192; + int omode = 0755; + int oflags = O_RDWR | O_CREAT; + + memcpy(expect, lock, sizeof(lock)); + + FSTEST_ENTER(); + + /* + * First, we create 4 processes and let each lock a range of the + * file. Note that the third and fourth processes lock in + * "reverse" order, i.e. the greater pid locks a range before + * the lesser pid. + * Then, we create 5th process which doesn't lock anything. + */ + for (i = 0; i < __arraycount(lwp); i++) { + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + + lwp[i] = rump_pub_lwproc_curlwp(); + pid[i] = rump_sys_getpid(); + + RL(fd[i] = rump_sys_open(TESTFILE, oflags, omode)); + oflags = O_RDWR; + omode = 0; + + RL(rump_sys_ftruncate(fd[i], sz)); + + if (i < __arraycount(lock)) { + RL(rump_sys_fcntl(fd[i], F_SETLK, &lock[i])); + expect[i].l_pid = pid[i]; + } + } + + qsort(expect, __arraycount(expect), sizeof(expect[0]), &flock_compare); + + /* + * In the context of each process, recursively find all locks + * that would block the current process. Processes 1-4 don't + * see their own lock, we insert it to simplify checks. + * Process 5 sees all 4 locks. + */ + for (i = 0; i < __arraycount(lwp); i++) { + unsigned int nlocks; + + rump_pub_lwproc_switch(lwp[i]); + + memset(result, 0, sizeof(result)); + nlocks = fcntl_getlocks(fd[i], 0, sz, + result, result + __arraycount(result)); + + if (i < __arraycount(lock)) { + ATF_REQUIRE(nlocks < __arraycount(result)); + result[nlocks] = lock[i]; + result[nlocks].l_pid = pid[i]; + nlocks++; + } + + ATF_CHECK_EQ(nlocks, __arraycount(expect)); + + qsort(result, nlocks, sizeof(result[0]), &flock_compare); + + for (j = 0; j < nlocks; j++) { + ATF_CHECK_EQ(result[j].l_start, expect[j].l_start ); + ATF_CHECK_EQ(result[j].l_len, expect[j].l_len ); + ATF_CHECK_EQ(result[j].l_pid, expect[j].l_pid ); + ATF_CHECK_EQ(result[j].l_type, expect[j].l_type ); + ATF_CHECK_EQ(result[j].l_whence, expect[j].l_whence); + } + } + + /* + * Release processes. This also releases the fds and locks + * making fs unmount possible + */ + for (i = 0; i < __arraycount(lwp); i++) { + rump_pub_lwproc_switch(lwp[i]); + rump_pub_lwproc_releaselwp(); + } + + FSTEST_EXIT(); +} + +static void +access_simple(const atf_tc_t *tc, const char *mp) +{ + int fd; + int tmode; + + FSTEST_ENTER(); + RL(fd = rump_sys_open("tfile", O_CREAT | O_RDWR, 0777)); + RL(rump_sys_close(fd)); + +#define ALLACC (F_OK | X_OK | W_OK | R_OK) + if (FSTYPE_SYSVBFS(tc) || FSTYPE_MSDOS(tc)) + tmode = F_OK; + else + tmode = ALLACC; + + RL(rump_sys_access("tfile", tmode)); + + /* PR kern/44648 */ + ATF_REQUIRE_ERRNO(EINVAL, rump_sys_access("tfile", ALLACC+1) == -1); +#undef ALLACC + FSTEST_EXIT(); +} + +static void +read_directory(const atf_tc_t *tc, const char *mp) +{ + char buf[1024]; + int fd, res; + ssize_t size; + + FSTEST_ENTER(); + fd = rump_sys_open(".", O_DIRECTORY | O_RDONLY, 0777); + ATF_REQUIRE(fd != -1); + + size = rump_sys_pread(fd, buf, sizeof(buf), 0); + ATF_CHECK(size != -1 || errno == EISDIR); + size = rump_sys_read(fd, buf, sizeof(buf)); + ATF_CHECK(size != -1 || errno == EISDIR); + + res = rump_sys_close(fd); + ATF_REQUIRE(res != -1); + FSTEST_EXIT(); +} + +static void +lstat_symlink(const atf_tc_t *tc, const char *mp) +{ + const char *src, *dst; + int res; + struct stat st; + + USES_SYMLINKS; + + FSTEST_ENTER(); + + src = "source"; + dst = "destination"; + + res = rump_sys_symlink(src, dst); + ATF_REQUIRE(res != -1); + res = rump_sys_lstat(dst, &st); + ATF_REQUIRE(res != -1); + + ATF_CHECK(S_ISLNK(st.st_mode) != 0); + ATF_CHECK(st.st_size == (off_t)strlen(src)); + + FSTEST_EXIT(); +} + +ATF_TC_FSAPPLY(lookup_simple, "simple lookup (./.. on root)"); +ATF_TC_FSAPPLY(lookup_complex, "lookup of non-dot entries"); +ATF_TC_FSAPPLY(dir_simple, "mkdir/rmdir"); +ATF_TC_FSAPPLY(dir_notempty, "non-empty directories cannot be removed"); +ATF_TC_FSAPPLY(dir_rmdirdotdot, "remove .. and try to cd out (PR kern/44657)"); +ATF_TC_FSAPPLY(rename_dir, "exercise various directory renaming ops " +"(PR kern/44288)"); +ATF_TC_FSAPPLY(rename_dotdot, "rename dir .. (PR kern/43617)"); +ATF_TC_FSAPPLY(rename_reg_nodir, "rename regular files, no subdirectories"); +ATF_TC_FSAPPLY(create_nametoolong, "create file with name too long"); +ATF_TC_FSAPPLY(create_exist, "create with O_EXCL"); +ATF_TC_FSAPPLY(rename_nametoolong, "rename to file with name too long"); +ATF_TC_FSAPPLY(symlink_zerolen, "symlink with target of length 0"); +ATF_TC_FSAPPLY(symlink_long, "symlink with target of length > 0"); +ATF_TC_FSAPPLY(symlink_root, "symlink to root directory"); +ATF_TC_FSAPPLY(attrs, "check setting attributes works"); +ATF_TC_FSAPPLY(fcntl_lock, "check fcntl F_SETLK"); +ATF_TC_FSAPPLY(fcntl_getlock_pids,"fcntl F_GETLK w/ many procs, PR kern/44494"); +ATF_TC_FSAPPLY(access_simple, "access(2)"); +ATF_TC_FSAPPLY(read_directory, "read(2) on directories"); +ATF_TC_FSAPPLY(lstat_symlink, "lstat(2) values for symbolic links"); + +#undef FSTEST_IMGSIZE +#define FSTEST_IMGSIZE (1024*1024*64) +ATF_TC_FSAPPLY(create_many, "create many directory entries"); +ATF_TC_FSAPPLY(create_nonalphanum, "non-alphanumeric filenames"); + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_FSAPPLY(lookup_simple); + ATF_TP_FSAPPLY(lookup_complex); + ATF_TP_FSAPPLY(dir_simple); + ATF_TP_FSAPPLY(dir_notempty); + ATF_TP_FSAPPLY(dir_rmdirdotdot); + ATF_TP_FSAPPLY(rename_dir); + ATF_TP_FSAPPLY(rename_dotdot); + ATF_TP_FSAPPLY(rename_reg_nodir); + ATF_TP_FSAPPLY(create_many); + ATF_TP_FSAPPLY(create_nonalphanum); + ATF_TP_FSAPPLY(create_nametoolong); + ATF_TP_FSAPPLY(create_exist); + ATF_TP_FSAPPLY(rename_nametoolong); + ATF_TP_FSAPPLY(symlink_zerolen); + ATF_TP_FSAPPLY(symlink_long); + ATF_TP_FSAPPLY(symlink_root); + ATF_TP_FSAPPLY(attrs); + ATF_TP_FSAPPLY(fcntl_lock); + ATF_TP_FSAPPLY(fcntl_getlock_pids); + ATF_TP_FSAPPLY(access_simple); + ATF_TP_FSAPPLY(read_directory); + ATF_TP_FSAPPLY(lstat_symlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/fs/zfs/t_zpool.sh b/contrib/netbsd-tests/fs/zfs/t_zpool.sh new file mode 100755 index 0000000..e3c2380 --- /dev/null +++ b/contrib/netbsd-tests/fs/zfs/t_zpool.sh @@ -0,0 +1,66 @@ +# $NetBSD: t_zpool.sh,v 1.3 2011/12/06 18:18:59 njoly Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +server='rump_server -lrumpvfs -lrumpkern_solaris -lrumpfs_zfs -lrumpdev -lrumpdev_rnd -d key=/dk,hostpath=zfs.img,size=100m' + +export RUMP_SERVER=unix://zsuck + +atf_test_case create cleanup +create_head() +{ + atf_set "descr" "basic zpool create" +} + +IFS=' ' +exmount='rumpfs on / type rumpfs (local) +jippo on /jippo type zfs (local) +' + +create_body() +{ + + atf_check -s exit:0 -o ignore -e ignore ${server} ${RUMP_SERVER} + + export LD_PRELOAD=/usr/lib/librumphijack.so + export RUMPHIJACK=blanket=/dev/zfs:/dk:/jippo + atf_check -s exit:0 zpool create jippo /dk + + export RUMPHIJACK=vfs=all + atf_check -s exit:0 -o inline:"${exmount}" mount +} + +create_cleanup() +{ + + rump.halt +} + +atf_init_test_cases() +{ + + atf_add_test_case create +} diff --git a/contrib/netbsd-tests/games/t_factor.sh b/contrib/netbsd-tests/games/t_factor.sh new file mode 100755 index 0000000..45a54bc --- /dev/null +++ b/contrib/netbsd-tests/games/t_factor.sh @@ -0,0 +1,81 @@ +# $NetBSD: t_factor.sh,v 1.9 2016/06/27 05:29:32 pgoyette Exp $ +# +# Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +expect() { + echo "${2}" >expout + ncrypt=$( ldd /usr/games/factor | grep -c -- -lcrypt ) + if [ "X$3" != "X" -a $ncrypt -eq 0 ] ; then + atf_skip "crypto needed for huge non-prime factors - PR bin/23663" + fi + atf_check -s eq:0 -o file:expout -e empty /usr/games/factor ${1} +} + +atf_test_case overflow1 +overflow1_head() { + atf_set "descr" "Tests for overflow conditions" + atf_set "require.progs" "/usr/games/factor" +} +overflow1_body() { + expect '8675309' '8675309: 8675309' +} + +atf_test_case overflow2 +overflow2_head() { + atf_set "descr" "Tests for overflow conditions" + atf_set "require.progs" "/usr/games/factor" +} +overflow2_body() { + expect '6172538568' '6172538568: 2 2 2 3 7 17 2161253' +} + +atf_test_case loop1 +loop1_head() { + atf_set "descr" "Tests some cases that once locked the program" \ + "in an infinite loop" + atf_set "require.progs" "/usr/games/factor" +} +loop1_body() { + expect '2147483647111311' '2147483647111311: 3 3 3 131 607148331103' +} + +atf_test_case loop2 +loop2_head() { + atf_set "descr" "Tests some cases that once locked the program" \ + "in an infinite loop" + atf_set "require.progs" "/usr/games/factor" +} +loop2_body() { + expect '99999999999991' '99999999999991: 7 13 769231 1428571' Need_Crypto +} + +atf_init_test_cases() +{ + atf_add_test_case overflow1 + atf_add_test_case overflow2 + atf_add_test_case loop1 + atf_add_test_case loop2 +} diff --git a/contrib/netbsd-tests/h_macros.h b/contrib/netbsd-tests/h_macros.h new file mode 100644 index 0000000..dd730c9 --- /dev/null +++ b/contrib/netbsd-tests/h_macros.h @@ -0,0 +1,87 @@ +/* $NetBSD: h_macros.h,v 1.13 2016/08/20 15:49:08 christos Exp $ */ + +/*- + * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef SRC_TESTS_H_MACROS_H_ +#define SRC_TESTS_H_MACROS_H_ + +#include +#include +#include +#include +#include +#include + +#include + +#define REQUIRE_LIBC(x, v) \ + ATF_REQUIRE_MSG((x) != (v), "%s: %s", #x, strerror(errno)) + +#define CHECK_LIBC(x, v) \ + ATF_CHECK_MSG((x) != (v), "%s: %s", #x, strerror(errno)) + +#define RL(x) REQUIRE_LIBC(x, -1) +#define RLF(x, fmt, arg) \ + ATF_CHECK_MSG((x) != -1, "%s [" fmt "]: %s", #x, arg, strerror(errno)) +#define RZ(x) \ +do { \ + int RZ_rv = x; \ + ATF_REQUIRE_MSG(RZ_rv == 0, "%s: %s", #x, strerror(RZ_rv)); \ +} while (/*CONSTCOND*/0) + +__dead static __inline __printflike(1, 2) void +atf_tc_fail_errno(const char *fmt, ...) +{ + va_list ap; + char buf[1024]; + int sverrno = errno; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + strlcat(buf, ": ", sizeof(buf)); + strlcat(buf, strerror(sverrno), sizeof(buf)); + + atf_tc_fail("%s", buf); +} + +static __inline void +tests_makegarbage(void *space, size_t len) +{ + uint16_t *sb = space; + uint16_t randval; + + while (len >= sizeof(randval)) { + *sb++ = (uint16_t)random(); + len -= sizeof(*sb); + } + randval = (uint16_t)random(); + memcpy(sb, &randval, len); +} + +#endif diff --git a/contrib/netbsd-tests/include/d_bitstring_27.out b/contrib/netbsd-tests/include/d_bitstring_27.out new file mode 100644 index 0000000..55ba39e --- /dev/null +++ b/contrib/netbsd-tests/include/d_bitstring_27.out @@ -0,0 +1,263 @@ +Testing with TEST_LENGTH = 27 + +test _bit_byte, _bit_mask, and bitstr_size + i _bit_byte(i) _bit_mask(i) bitstr_size(i) + 0 0 1 0 + 1 0 2 1 + 2 0 4 1 + 3 0 8 1 + 4 0 16 1 + 5 0 32 1 + 6 0 64 1 + 7 0 128 1 + 8 1 1 1 + 9 1 2 2 + 10 1 4 2 + 11 1 8 2 + 12 1 16 2 + 13 1 32 2 + 14 1 64 2 + 15 1 128 2 + 16 2 1 2 + 17 2 2 3 + 18 2 4 3 + 19 2 8 3 + 20 2 16 3 + 21 2 32 3 + 22 2 64 3 + 23 2 128 3 + 24 3 1 3 + 25 3 2 4 + 26 3 4 4 + +test bit_alloc, clearbits, bit_ffc, bit_ffs +be: 0 -1 000000000000000000000000000 +is: 0 -1 000000000000000000000000000 + +test bit_set +be: 1 0 100100100100100100100100100 +is: 1 0 100100100100100100100100100 + +test bit_clear +be: 0 3 000100000100000100000100000 +is: 0 3 000100000100000100000100000 + +test bit_test using previous bitstring + i bit_test(i) + 0 0 + 1 0 + 2 0 + 3 8 + 4 0 + 5 0 + 6 0 + 7 0 + 8 0 + 9 2 + 10 0 + 11 0 + 12 0 + 13 0 + 14 0 + 15 128 + 16 0 + 17 0 + 18 0 + 19 0 + 20 0 + 21 32 + 22 0 + 23 0 + 24 0 + 25 0 + 26 0 + +test clearbits +be: 0 -1 000000000000000000000000000 +is: 0 -1 000000000000000000000000000 + +test bit_nset and bit_nclear +be: 0 1 011111111111111111111111110 +is: 0 1 011111111111111111111111110 +be: 0 1 010000000000000000000000010 +is: 0 1 010000000000000000000000010 +be: 0 -1 000000000000000000000000000 +is: 0 -1 000000000000000000000000000 +be: 26 0 111111111111111111111111110 +is: 26 0 111111111111111111111111110 +be: 0 -1 000000000000000000000000000 +is: 0 -1 000000000000000000000000000 + +first 1 bit should move right 1 position each line + 0 -1 0 111111111111111111111111111 + 1 0 1 011111111111111111111111111 + 2 0 2 001111111111111111111111111 + 3 0 3 000111111111111111111111111 + 4 0 4 000011111111111111111111111 + 5 0 5 000001111111111111111111111 + 6 0 6 000000111111111111111111111 + 7 0 7 000000011111111111111111111 + 8 0 8 000000001111111111111111111 + 9 0 9 000000000111111111111111111 + 10 0 10 000000000011111111111111111 + 11 0 11 000000000001111111111111111 + 12 0 12 000000000000111111111111111 + 13 0 13 000000000000011111111111111 + 14 0 14 000000000000001111111111111 + 15 0 15 000000000000000111111111111 + 16 0 16 000000000000000011111111111 + 17 0 17 000000000000000001111111111 + 18 0 18 000000000000000000111111111 + 19 0 19 000000000000000000011111111 + 20 0 20 000000000000000000001111111 + 21 0 21 000000000000000000000111111 + 22 0 22 000000000000000000000011111 + 23 0 23 000000000000000000000001111 + 24 0 24 000000000000000000000000111 + 25 0 25 000000000000000000000000011 + 26 0 26 000000000000000000000000001 + +first 0 bit should move right 1 position each line + 0 0 -1 000000000000000000000000000 + 1 1 0 100000000000000000000000000 + 2 2 0 110000000000000000000000000 + 3 3 0 111000000000000000000000000 + 4 4 0 111100000000000000000000000 + 5 5 0 111110000000000000000000000 + 6 6 0 111111000000000000000000000 + 7 7 0 111111100000000000000000000 + 8 8 0 111111110000000000000000000 + 9 9 0 111111111000000000000000000 + 10 10 0 111111111100000000000000000 + 11 11 0 111111111110000000000000000 + 12 12 0 111111111111000000000000000 + 13 13 0 111111111111100000000000000 + 14 14 0 111111111111110000000000000 + 15 15 0 111111111111111000000000000 + 16 16 0 111111111111111100000000000 + 17 17 0 111111111111111110000000000 + 18 18 0 111111111111111111000000000 + 19 19 0 111111111111111111100000000 + 20 20 0 111111111111111111110000000 + 21 21 0 111111111111111111111000000 + 22 22 0 111111111111111111111100000 + 23 23 0 111111111111111111111110000 + 24 24 0 111111111111111111111111000 + 25 25 0 111111111111111111111111100 + 26 26 0 111111111111111111111111110 + +first 0 bit should move left 1 position each line + 0 -1 0 111111111111111111111111111 + 1 26 0 111111111111111111111111110 + 2 25 0 111111111111111111111111100 + 3 24 0 111111111111111111111111000 + 4 23 0 111111111111111111111110000 + 5 22 0 111111111111111111111100000 + 6 21 0 111111111111111111111000000 + 7 20 0 111111111111111111110000000 + 8 19 0 111111111111111111100000000 + 9 18 0 111111111111111111000000000 + 10 17 0 111111111111111110000000000 + 11 16 0 111111111111111100000000000 + 12 15 0 111111111111111000000000000 + 13 14 0 111111111111110000000000000 + 14 13 0 111111111111100000000000000 + 15 12 0 111111111111000000000000000 + 16 11 0 111111111110000000000000000 + 17 10 0 111111111100000000000000000 + 18 9 0 111111111000000000000000000 + 19 8 0 111111110000000000000000000 + 20 7 0 111111100000000000000000000 + 21 6 0 111111000000000000000000000 + 22 5 0 111110000000000000000000000 + 23 4 0 111100000000000000000000000 + 24 3 0 111000000000000000000000000 + 25 2 0 110000000000000000000000000 + 26 1 0 100000000000000000000000000 + +first 1 bit should move left 1 position each line + 0 0 -1 000000000000000000000000000 + 1 0 26 000000000000000000000000001 + 2 0 25 000000000000000000000000011 + 3 0 24 000000000000000000000000111 + 4 0 23 000000000000000000000001111 + 5 0 22 000000000000000000000011111 + 6 0 21 000000000000000000000111111 + 7 0 20 000000000000000000001111111 + 8 0 19 000000000000000000011111111 + 9 0 18 000000000000000000111111111 + 10 0 17 000000000000000001111111111 + 11 0 16 000000000000000011111111111 + 12 0 15 000000000000000111111111111 + 13 0 14 000000000000001111111111111 + 14 0 13 000000000000011111111111111 + 15 0 12 000000000000111111111111111 + 16 0 11 000000000001111111111111111 + 17 0 10 000000000011111111111111111 + 18 0 9 000000000111111111111111111 + 19 0 8 000000001111111111111111111 + 20 0 7 000000011111111111111111111 + 21 0 6 000000111111111111111111111 + 22 0 5 000001111111111111111111111 + 23 0 4 000011111111111111111111111 + 24 0 3 000111111111111111111111111 + 25 0 2 001111111111111111111111111 + 26 0 1 011111111111111111111111111 + +0 bit should move right 1 position each line + 0 0 1 011111111111111111111111111 + 1 1 0 101111111111111111111111111 + 2 2 0 110111111111111111111111111 + 3 3 0 111011111111111111111111111 + 4 4 0 111101111111111111111111111 + 5 5 0 111110111111111111111111111 + 6 6 0 111111011111111111111111111 + 7 7 0 111111101111111111111111111 + 8 8 0 111111110111111111111111111 + 9 9 0 111111111011111111111111111 + 10 10 0 111111111101111111111111111 + 11 11 0 111111111110111111111111111 + 12 12 0 111111111111011111111111111 + 13 13 0 111111111111101111111111111 + 14 14 0 111111111111110111111111111 + 15 15 0 111111111111111011111111111 + 16 16 0 111111111111111101111111111 + 17 17 0 111111111111111110111111111 + 18 18 0 111111111111111111011111111 + 19 19 0 111111111111111111101111111 + 20 20 0 111111111111111111110111111 + 21 21 0 111111111111111111111011111 + 22 22 0 111111111111111111111101111 + 23 23 0 111111111111111111111110111 + 24 24 0 111111111111111111111111011 + 25 25 0 111111111111111111111111101 + 26 26 0 111111111111111111111111110 + +1 bit should move right 1 position each line + 0 1 0 100000000000000000000000000 + 1 0 1 010000000000000000000000000 + 2 0 2 001000000000000000000000000 + 3 0 3 000100000000000000000000000 + 4 0 4 000010000000000000000000000 + 5 0 5 000001000000000000000000000 + 6 0 6 000000100000000000000000000 + 7 0 7 000000010000000000000000000 + 8 0 8 000000001000000000000000000 + 9 0 9 000000000100000000000000000 + 10 0 10 000000000010000000000000000 + 11 0 11 000000000001000000000000000 + 12 0 12 000000000000100000000000000 + 13 0 13 000000000000010000000000000 + 14 0 14 000000000000001000000000000 + 15 0 15 000000000000000100000000000 + 16 0 16 000000000000000010000000000 + 17 0 17 000000000000000001000000000 + 18 0 18 000000000000000000100000000 + 19 0 19 000000000000000000010000000 + 20 0 20 000000000000000000001000000 + 21 0 21 000000000000000000000100000 + 22 0 22 000000000000000000000010000 + 23 0 23 000000000000000000000001000 + 24 0 24 000000000000000000000000100 + 25 0 25 000000000000000000000000010 + 26 0 26 000000000000000000000000001 diff --git a/contrib/netbsd-tests/include/d_bitstring_32.out b/contrib/netbsd-tests/include/d_bitstring_32.out new file mode 100644 index 0000000..2e1ca55 --- /dev/null +++ b/contrib/netbsd-tests/include/d_bitstring_32.out @@ -0,0 +1,303 @@ +Testing with TEST_LENGTH = 32 + +test _bit_byte, _bit_mask, and bitstr_size + i _bit_byte(i) _bit_mask(i) bitstr_size(i) + 0 0 1 0 + 1 0 2 1 + 2 0 4 1 + 3 0 8 1 + 4 0 16 1 + 5 0 32 1 + 6 0 64 1 + 7 0 128 1 + 8 1 1 1 + 9 1 2 2 + 10 1 4 2 + 11 1 8 2 + 12 1 16 2 + 13 1 32 2 + 14 1 64 2 + 15 1 128 2 + 16 2 1 2 + 17 2 2 3 + 18 2 4 3 + 19 2 8 3 + 20 2 16 3 + 21 2 32 3 + 22 2 64 3 + 23 2 128 3 + 24 3 1 3 + 25 3 2 4 + 26 3 4 4 + 27 3 8 4 + 28 3 16 4 + 29 3 32 4 + 30 3 64 4 + 31 3 128 4 + +test bit_alloc, clearbits, bit_ffc, bit_ffs +be: 0 -1 00000000000000000000000000000000 +is: 0 -1 00000000000000000000000000000000 + +test bit_set +be: 1 0 10010010010010010010010010010010 +is: 1 0 10010010010010010010010010010010 + +test bit_clear +be: 0 3 00010000010000010000010000010000 +is: 0 3 00010000010000010000010000010000 + +test bit_test using previous bitstring + i bit_test(i) + 0 0 + 1 0 + 2 0 + 3 8 + 4 0 + 5 0 + 6 0 + 7 0 + 8 0 + 9 2 + 10 0 + 11 0 + 12 0 + 13 0 + 14 0 + 15 128 + 16 0 + 17 0 + 18 0 + 19 0 + 20 0 + 21 32 + 22 0 + 23 0 + 24 0 + 25 0 + 26 0 + 27 8 + 28 0 + 29 0 + 30 0 + 31 0 + +test clearbits +be: 0 -1 00000000000000000000000000000000 +is: 0 -1 00000000000000000000000000000000 + +test bit_nset and bit_nclear +be: 0 1 01111111111111111111111111111110 +is: 0 1 01111111111111111111111111111110 +be: 0 1 01000000000000000000000000000010 +is: 0 1 01000000000000000000000000000010 +be: 0 -1 00000000000000000000000000000000 +is: 0 -1 00000000000000000000000000000000 +be: 31 0 11111111111111111111111111111110 +is: 31 0 11111111111111111111111111111110 +be: 0 -1 00000000000000000000000000000000 +is: 0 -1 00000000000000000000000000000000 + +first 1 bit should move right 1 position each line + 0 -1 0 11111111111111111111111111111111 + 1 0 1 01111111111111111111111111111111 + 2 0 2 00111111111111111111111111111111 + 3 0 3 00011111111111111111111111111111 + 4 0 4 00001111111111111111111111111111 + 5 0 5 00000111111111111111111111111111 + 6 0 6 00000011111111111111111111111111 + 7 0 7 00000001111111111111111111111111 + 8 0 8 00000000111111111111111111111111 + 9 0 9 00000000011111111111111111111111 + 10 0 10 00000000001111111111111111111111 + 11 0 11 00000000000111111111111111111111 + 12 0 12 00000000000011111111111111111111 + 13 0 13 00000000000001111111111111111111 + 14 0 14 00000000000000111111111111111111 + 15 0 15 00000000000000011111111111111111 + 16 0 16 00000000000000001111111111111111 + 17 0 17 00000000000000000111111111111111 + 18 0 18 00000000000000000011111111111111 + 19 0 19 00000000000000000001111111111111 + 20 0 20 00000000000000000000111111111111 + 21 0 21 00000000000000000000011111111111 + 22 0 22 00000000000000000000001111111111 + 23 0 23 00000000000000000000000111111111 + 24 0 24 00000000000000000000000011111111 + 25 0 25 00000000000000000000000001111111 + 26 0 26 00000000000000000000000000111111 + 27 0 27 00000000000000000000000000011111 + 28 0 28 00000000000000000000000000001111 + 29 0 29 00000000000000000000000000000111 + 30 0 30 00000000000000000000000000000011 + 31 0 31 00000000000000000000000000000001 + +first 0 bit should move right 1 position each line + 0 0 -1 00000000000000000000000000000000 + 1 1 0 10000000000000000000000000000000 + 2 2 0 11000000000000000000000000000000 + 3 3 0 11100000000000000000000000000000 + 4 4 0 11110000000000000000000000000000 + 5 5 0 11111000000000000000000000000000 + 6 6 0 11111100000000000000000000000000 + 7 7 0 11111110000000000000000000000000 + 8 8 0 11111111000000000000000000000000 + 9 9 0 11111111100000000000000000000000 + 10 10 0 11111111110000000000000000000000 + 11 11 0 11111111111000000000000000000000 + 12 12 0 11111111111100000000000000000000 + 13 13 0 11111111111110000000000000000000 + 14 14 0 11111111111111000000000000000000 + 15 15 0 11111111111111100000000000000000 + 16 16 0 11111111111111110000000000000000 + 17 17 0 11111111111111111000000000000000 + 18 18 0 11111111111111111100000000000000 + 19 19 0 11111111111111111110000000000000 + 20 20 0 11111111111111111111000000000000 + 21 21 0 11111111111111111111100000000000 + 22 22 0 11111111111111111111110000000000 + 23 23 0 11111111111111111111111000000000 + 24 24 0 11111111111111111111111100000000 + 25 25 0 11111111111111111111111110000000 + 26 26 0 11111111111111111111111111000000 + 27 27 0 11111111111111111111111111100000 + 28 28 0 11111111111111111111111111110000 + 29 29 0 11111111111111111111111111111000 + 30 30 0 11111111111111111111111111111100 + 31 31 0 11111111111111111111111111111110 + +first 0 bit should move left 1 position each line + 0 -1 0 11111111111111111111111111111111 + 1 31 0 11111111111111111111111111111110 + 2 30 0 11111111111111111111111111111100 + 3 29 0 11111111111111111111111111111000 + 4 28 0 11111111111111111111111111110000 + 5 27 0 11111111111111111111111111100000 + 6 26 0 11111111111111111111111111000000 + 7 25 0 11111111111111111111111110000000 + 8 24 0 11111111111111111111111100000000 + 9 23 0 11111111111111111111111000000000 + 10 22 0 11111111111111111111110000000000 + 11 21 0 11111111111111111111100000000000 + 12 20 0 11111111111111111111000000000000 + 13 19 0 11111111111111111110000000000000 + 14 18 0 11111111111111111100000000000000 + 15 17 0 11111111111111111000000000000000 + 16 16 0 11111111111111110000000000000000 + 17 15 0 11111111111111100000000000000000 + 18 14 0 11111111111111000000000000000000 + 19 13 0 11111111111110000000000000000000 + 20 12 0 11111111111100000000000000000000 + 21 11 0 11111111111000000000000000000000 + 22 10 0 11111111110000000000000000000000 + 23 9 0 11111111100000000000000000000000 + 24 8 0 11111111000000000000000000000000 + 25 7 0 11111110000000000000000000000000 + 26 6 0 11111100000000000000000000000000 + 27 5 0 11111000000000000000000000000000 + 28 4 0 11110000000000000000000000000000 + 29 3 0 11100000000000000000000000000000 + 30 2 0 11000000000000000000000000000000 + 31 1 0 10000000000000000000000000000000 + +first 1 bit should move left 1 position each line + 0 0 -1 00000000000000000000000000000000 + 1 0 31 00000000000000000000000000000001 + 2 0 30 00000000000000000000000000000011 + 3 0 29 00000000000000000000000000000111 + 4 0 28 00000000000000000000000000001111 + 5 0 27 00000000000000000000000000011111 + 6 0 26 00000000000000000000000000111111 + 7 0 25 00000000000000000000000001111111 + 8 0 24 00000000000000000000000011111111 + 9 0 23 00000000000000000000000111111111 + 10 0 22 00000000000000000000001111111111 + 11 0 21 00000000000000000000011111111111 + 12 0 20 00000000000000000000111111111111 + 13 0 19 00000000000000000001111111111111 + 14 0 18 00000000000000000011111111111111 + 15 0 17 00000000000000000111111111111111 + 16 0 16 00000000000000001111111111111111 + 17 0 15 00000000000000011111111111111111 + 18 0 14 00000000000000111111111111111111 + 19 0 13 00000000000001111111111111111111 + 20 0 12 00000000000011111111111111111111 + 21 0 11 00000000000111111111111111111111 + 22 0 10 00000000001111111111111111111111 + 23 0 9 00000000011111111111111111111111 + 24 0 8 00000000111111111111111111111111 + 25 0 7 00000001111111111111111111111111 + 26 0 6 00000011111111111111111111111111 + 27 0 5 00000111111111111111111111111111 + 28 0 4 00001111111111111111111111111111 + 29 0 3 00011111111111111111111111111111 + 30 0 2 00111111111111111111111111111111 + 31 0 1 01111111111111111111111111111111 + +0 bit should move right 1 position each line + 0 0 1 01111111111111111111111111111111 + 1 1 0 10111111111111111111111111111111 + 2 2 0 11011111111111111111111111111111 + 3 3 0 11101111111111111111111111111111 + 4 4 0 11110111111111111111111111111111 + 5 5 0 11111011111111111111111111111111 + 6 6 0 11111101111111111111111111111111 + 7 7 0 11111110111111111111111111111111 + 8 8 0 11111111011111111111111111111111 + 9 9 0 11111111101111111111111111111111 + 10 10 0 11111111110111111111111111111111 + 11 11 0 11111111111011111111111111111111 + 12 12 0 11111111111101111111111111111111 + 13 13 0 11111111111110111111111111111111 + 14 14 0 11111111111111011111111111111111 + 15 15 0 11111111111111101111111111111111 + 16 16 0 11111111111111110111111111111111 + 17 17 0 11111111111111111011111111111111 + 18 18 0 11111111111111111101111111111111 + 19 19 0 11111111111111111110111111111111 + 20 20 0 11111111111111111111011111111111 + 21 21 0 11111111111111111111101111111111 + 22 22 0 11111111111111111111110111111111 + 23 23 0 11111111111111111111111011111111 + 24 24 0 11111111111111111111111101111111 + 25 25 0 11111111111111111111111110111111 + 26 26 0 11111111111111111111111111011111 + 27 27 0 11111111111111111111111111101111 + 28 28 0 11111111111111111111111111110111 + 29 29 0 11111111111111111111111111111011 + 30 30 0 11111111111111111111111111111101 + 31 31 0 11111111111111111111111111111110 + +1 bit should move right 1 position each line + 0 1 0 10000000000000000000000000000000 + 1 0 1 01000000000000000000000000000000 + 2 0 2 00100000000000000000000000000000 + 3 0 3 00010000000000000000000000000000 + 4 0 4 00001000000000000000000000000000 + 5 0 5 00000100000000000000000000000000 + 6 0 6 00000010000000000000000000000000 + 7 0 7 00000001000000000000000000000000 + 8 0 8 00000000100000000000000000000000 + 9 0 9 00000000010000000000000000000000 + 10 0 10 00000000001000000000000000000000 + 11 0 11 00000000000100000000000000000000 + 12 0 12 00000000000010000000000000000000 + 13 0 13 00000000000001000000000000000000 + 14 0 14 00000000000000100000000000000000 + 15 0 15 00000000000000010000000000000000 + 16 0 16 00000000000000001000000000000000 + 17 0 17 00000000000000000100000000000000 + 18 0 18 00000000000000000010000000000000 + 19 0 19 00000000000000000001000000000000 + 20 0 20 00000000000000000000100000000000 + 21 0 21 00000000000000000000010000000000 + 22 0 22 00000000000000000000001000000000 + 23 0 23 00000000000000000000000100000000 + 24 0 24 00000000000000000000000010000000 + 25 0 25 00000000000000000000000001000000 + 26 0 26 00000000000000000000000000100000 + 27 0 27 00000000000000000000000000010000 + 28 0 28 00000000000000000000000000001000 + 29 0 29 00000000000000000000000000000100 + 30 0 30 00000000000000000000000000000010 + 31 0 31 00000000000000000000000000000001 diff --git a/contrib/netbsd-tests/include/d_bitstring_49.out b/contrib/netbsd-tests/include/d_bitstring_49.out new file mode 100644 index 0000000..d63c069 --- /dev/null +++ b/contrib/netbsd-tests/include/d_bitstring_49.out @@ -0,0 +1,439 @@ +Testing with TEST_LENGTH = 49 + +test _bit_byte, _bit_mask, and bitstr_size + i _bit_byte(i) _bit_mask(i) bitstr_size(i) + 0 0 1 0 + 1 0 2 1 + 2 0 4 1 + 3 0 8 1 + 4 0 16 1 + 5 0 32 1 + 6 0 64 1 + 7 0 128 1 + 8 1 1 1 + 9 1 2 2 + 10 1 4 2 + 11 1 8 2 + 12 1 16 2 + 13 1 32 2 + 14 1 64 2 + 15 1 128 2 + 16 2 1 2 + 17 2 2 3 + 18 2 4 3 + 19 2 8 3 + 20 2 16 3 + 21 2 32 3 + 22 2 64 3 + 23 2 128 3 + 24 3 1 3 + 25 3 2 4 + 26 3 4 4 + 27 3 8 4 + 28 3 16 4 + 29 3 32 4 + 30 3 64 4 + 31 3 128 4 + 32 4 1 4 + 33 4 2 5 + 34 4 4 5 + 35 4 8 5 + 36 4 16 5 + 37 4 32 5 + 38 4 64 5 + 39 4 128 5 + 40 5 1 5 + 41 5 2 6 + 42 5 4 6 + 43 5 8 6 + 44 5 16 6 + 45 5 32 6 + 46 5 64 6 + 47 5 128 6 + 48 6 1 6 + +test bit_alloc, clearbits, bit_ffc, bit_ffs +be: 0 -1 0000000000000000000000000000000000000000000000000 +is: 0 -1 0000000000000000000000000000000000000000000000000 + +test bit_set +be: 1 0 1001001001001001001001001001001001001001001001001 +is: 1 0 1001001001001001001001001001001001001001001001001 + +test bit_clear +be: 0 3 0001000001000001000001000001000001000001000001000 +is: 0 3 0001000001000001000001000001000001000001000001000 + +test bit_test using previous bitstring + i bit_test(i) + 0 0 + 1 0 + 2 0 + 3 8 + 4 0 + 5 0 + 6 0 + 7 0 + 8 0 + 9 2 + 10 0 + 11 0 + 12 0 + 13 0 + 14 0 + 15 128 + 16 0 + 17 0 + 18 0 + 19 0 + 20 0 + 21 32 + 22 0 + 23 0 + 24 0 + 25 0 + 26 0 + 27 8 + 28 0 + 29 0 + 30 0 + 31 0 + 32 0 + 33 2 + 34 0 + 35 0 + 36 0 + 37 0 + 38 0 + 39 128 + 40 0 + 41 0 + 42 0 + 43 0 + 44 0 + 45 32 + 46 0 + 47 0 + 48 0 + +test clearbits +be: 0 -1 0000000000000000000000000000000000000000000000000 +is: 0 -1 0000000000000000000000000000000000000000000000000 + +test bit_nset and bit_nclear +be: 0 1 0111111111111111111111111111111111111111111111110 +is: 0 1 0111111111111111111111111111111111111111111111110 +be: 0 1 0100000000000000000000000000000000000000000000010 +is: 0 1 0100000000000000000000000000000000000000000000010 +be: 0 -1 0000000000000000000000000000000000000000000000000 +is: 0 -1 0000000000000000000000000000000000000000000000000 +be: 48 0 1111111111111111111111111111111111111111111111110 +is: 48 0 1111111111111111111111111111111111111111111111110 +be: 0 -1 0000000000000000000000000000000000000000000000000 +is: 0 -1 0000000000000000000000000000000000000000000000000 + +first 1 bit should move right 1 position each line + 0 -1 0 1111111111111111111111111111111111111111111111111 + 1 0 1 0111111111111111111111111111111111111111111111111 + 2 0 2 0011111111111111111111111111111111111111111111111 + 3 0 3 0001111111111111111111111111111111111111111111111 + 4 0 4 0000111111111111111111111111111111111111111111111 + 5 0 5 0000011111111111111111111111111111111111111111111 + 6 0 6 0000001111111111111111111111111111111111111111111 + 7 0 7 0000000111111111111111111111111111111111111111111 + 8 0 8 0000000011111111111111111111111111111111111111111 + 9 0 9 0000000001111111111111111111111111111111111111111 + 10 0 10 0000000000111111111111111111111111111111111111111 + 11 0 11 0000000000011111111111111111111111111111111111111 + 12 0 12 0000000000001111111111111111111111111111111111111 + 13 0 13 0000000000000111111111111111111111111111111111111 + 14 0 14 0000000000000011111111111111111111111111111111111 + 15 0 15 0000000000000001111111111111111111111111111111111 + 16 0 16 0000000000000000111111111111111111111111111111111 + 17 0 17 0000000000000000011111111111111111111111111111111 + 18 0 18 0000000000000000001111111111111111111111111111111 + 19 0 19 0000000000000000000111111111111111111111111111111 + 20 0 20 0000000000000000000011111111111111111111111111111 + 21 0 21 0000000000000000000001111111111111111111111111111 + 22 0 22 0000000000000000000000111111111111111111111111111 + 23 0 23 0000000000000000000000011111111111111111111111111 + 24 0 24 0000000000000000000000001111111111111111111111111 + 25 0 25 0000000000000000000000000111111111111111111111111 + 26 0 26 0000000000000000000000000011111111111111111111111 + 27 0 27 0000000000000000000000000001111111111111111111111 + 28 0 28 0000000000000000000000000000111111111111111111111 + 29 0 29 0000000000000000000000000000011111111111111111111 + 30 0 30 0000000000000000000000000000001111111111111111111 + 31 0 31 0000000000000000000000000000000111111111111111111 + 32 0 32 0000000000000000000000000000000011111111111111111 + 33 0 33 0000000000000000000000000000000001111111111111111 + 34 0 34 0000000000000000000000000000000000111111111111111 + 35 0 35 0000000000000000000000000000000000011111111111111 + 36 0 36 0000000000000000000000000000000000001111111111111 + 37 0 37 0000000000000000000000000000000000000111111111111 + 38 0 38 0000000000000000000000000000000000000011111111111 + 39 0 39 0000000000000000000000000000000000000001111111111 + 40 0 40 0000000000000000000000000000000000000000111111111 + 41 0 41 0000000000000000000000000000000000000000011111111 + 42 0 42 0000000000000000000000000000000000000000001111111 + 43 0 43 0000000000000000000000000000000000000000000111111 + 44 0 44 0000000000000000000000000000000000000000000011111 + 45 0 45 0000000000000000000000000000000000000000000001111 + 46 0 46 0000000000000000000000000000000000000000000000111 + 47 0 47 0000000000000000000000000000000000000000000000011 + 48 0 48 0000000000000000000000000000000000000000000000001 + +first 0 bit should move right 1 position each line + 0 0 -1 0000000000000000000000000000000000000000000000000 + 1 1 0 1000000000000000000000000000000000000000000000000 + 2 2 0 1100000000000000000000000000000000000000000000000 + 3 3 0 1110000000000000000000000000000000000000000000000 + 4 4 0 1111000000000000000000000000000000000000000000000 + 5 5 0 1111100000000000000000000000000000000000000000000 + 6 6 0 1111110000000000000000000000000000000000000000000 + 7 7 0 1111111000000000000000000000000000000000000000000 + 8 8 0 1111111100000000000000000000000000000000000000000 + 9 9 0 1111111110000000000000000000000000000000000000000 + 10 10 0 1111111111000000000000000000000000000000000000000 + 11 11 0 1111111111100000000000000000000000000000000000000 + 12 12 0 1111111111110000000000000000000000000000000000000 + 13 13 0 1111111111111000000000000000000000000000000000000 + 14 14 0 1111111111111100000000000000000000000000000000000 + 15 15 0 1111111111111110000000000000000000000000000000000 + 16 16 0 1111111111111111000000000000000000000000000000000 + 17 17 0 1111111111111111100000000000000000000000000000000 + 18 18 0 1111111111111111110000000000000000000000000000000 + 19 19 0 1111111111111111111000000000000000000000000000000 + 20 20 0 1111111111111111111100000000000000000000000000000 + 21 21 0 1111111111111111111110000000000000000000000000000 + 22 22 0 1111111111111111111111000000000000000000000000000 + 23 23 0 1111111111111111111111100000000000000000000000000 + 24 24 0 1111111111111111111111110000000000000000000000000 + 25 25 0 1111111111111111111111111000000000000000000000000 + 26 26 0 1111111111111111111111111100000000000000000000000 + 27 27 0 1111111111111111111111111110000000000000000000000 + 28 28 0 1111111111111111111111111111000000000000000000000 + 29 29 0 1111111111111111111111111111100000000000000000000 + 30 30 0 1111111111111111111111111111110000000000000000000 + 31 31 0 1111111111111111111111111111111000000000000000000 + 32 32 0 1111111111111111111111111111111100000000000000000 + 33 33 0 1111111111111111111111111111111110000000000000000 + 34 34 0 1111111111111111111111111111111111000000000000000 + 35 35 0 1111111111111111111111111111111111100000000000000 + 36 36 0 1111111111111111111111111111111111110000000000000 + 37 37 0 1111111111111111111111111111111111111000000000000 + 38 38 0 1111111111111111111111111111111111111100000000000 + 39 39 0 1111111111111111111111111111111111111110000000000 + 40 40 0 1111111111111111111111111111111111111111000000000 + 41 41 0 1111111111111111111111111111111111111111100000000 + 42 42 0 1111111111111111111111111111111111111111110000000 + 43 43 0 1111111111111111111111111111111111111111111000000 + 44 44 0 1111111111111111111111111111111111111111111100000 + 45 45 0 1111111111111111111111111111111111111111111110000 + 46 46 0 1111111111111111111111111111111111111111111111000 + 47 47 0 1111111111111111111111111111111111111111111111100 + 48 48 0 1111111111111111111111111111111111111111111111110 + +first 0 bit should move left 1 position each line + 0 -1 0 1111111111111111111111111111111111111111111111111 + 1 48 0 1111111111111111111111111111111111111111111111110 + 2 47 0 1111111111111111111111111111111111111111111111100 + 3 46 0 1111111111111111111111111111111111111111111111000 + 4 45 0 1111111111111111111111111111111111111111111110000 + 5 44 0 1111111111111111111111111111111111111111111100000 + 6 43 0 1111111111111111111111111111111111111111111000000 + 7 42 0 1111111111111111111111111111111111111111110000000 + 8 41 0 1111111111111111111111111111111111111111100000000 + 9 40 0 1111111111111111111111111111111111111111000000000 + 10 39 0 1111111111111111111111111111111111111110000000000 + 11 38 0 1111111111111111111111111111111111111100000000000 + 12 37 0 1111111111111111111111111111111111111000000000000 + 13 36 0 1111111111111111111111111111111111110000000000000 + 14 35 0 1111111111111111111111111111111111100000000000000 + 15 34 0 1111111111111111111111111111111111000000000000000 + 16 33 0 1111111111111111111111111111111110000000000000000 + 17 32 0 1111111111111111111111111111111100000000000000000 + 18 31 0 1111111111111111111111111111111000000000000000000 + 19 30 0 1111111111111111111111111111110000000000000000000 + 20 29 0 1111111111111111111111111111100000000000000000000 + 21 28 0 1111111111111111111111111111000000000000000000000 + 22 27 0 1111111111111111111111111110000000000000000000000 + 23 26 0 1111111111111111111111111100000000000000000000000 + 24 25 0 1111111111111111111111111000000000000000000000000 + 25 24 0 1111111111111111111111110000000000000000000000000 + 26 23 0 1111111111111111111111100000000000000000000000000 + 27 22 0 1111111111111111111111000000000000000000000000000 + 28 21 0 1111111111111111111110000000000000000000000000000 + 29 20 0 1111111111111111111100000000000000000000000000000 + 30 19 0 1111111111111111111000000000000000000000000000000 + 31 18 0 1111111111111111110000000000000000000000000000000 + 32 17 0 1111111111111111100000000000000000000000000000000 + 33 16 0 1111111111111111000000000000000000000000000000000 + 34 15 0 1111111111111110000000000000000000000000000000000 + 35 14 0 1111111111111100000000000000000000000000000000000 + 36 13 0 1111111111111000000000000000000000000000000000000 + 37 12 0 1111111111110000000000000000000000000000000000000 + 38 11 0 1111111111100000000000000000000000000000000000000 + 39 10 0 1111111111000000000000000000000000000000000000000 + 40 9 0 1111111110000000000000000000000000000000000000000 + 41 8 0 1111111100000000000000000000000000000000000000000 + 42 7 0 1111111000000000000000000000000000000000000000000 + 43 6 0 1111110000000000000000000000000000000000000000000 + 44 5 0 1111100000000000000000000000000000000000000000000 + 45 4 0 1111000000000000000000000000000000000000000000000 + 46 3 0 1110000000000000000000000000000000000000000000000 + 47 2 0 1100000000000000000000000000000000000000000000000 + 48 1 0 1000000000000000000000000000000000000000000000000 + +first 1 bit should move left 1 position each line + 0 0 -1 0000000000000000000000000000000000000000000000000 + 1 0 48 0000000000000000000000000000000000000000000000001 + 2 0 47 0000000000000000000000000000000000000000000000011 + 3 0 46 0000000000000000000000000000000000000000000000111 + 4 0 45 0000000000000000000000000000000000000000000001111 + 5 0 44 0000000000000000000000000000000000000000000011111 + 6 0 43 0000000000000000000000000000000000000000000111111 + 7 0 42 0000000000000000000000000000000000000000001111111 + 8 0 41 0000000000000000000000000000000000000000011111111 + 9 0 40 0000000000000000000000000000000000000000111111111 + 10 0 39 0000000000000000000000000000000000000001111111111 + 11 0 38 0000000000000000000000000000000000000011111111111 + 12 0 37 0000000000000000000000000000000000000111111111111 + 13 0 36 0000000000000000000000000000000000001111111111111 + 14 0 35 0000000000000000000000000000000000011111111111111 + 15 0 34 0000000000000000000000000000000000111111111111111 + 16 0 33 0000000000000000000000000000000001111111111111111 + 17 0 32 0000000000000000000000000000000011111111111111111 + 18 0 31 0000000000000000000000000000000111111111111111111 + 19 0 30 0000000000000000000000000000001111111111111111111 + 20 0 29 0000000000000000000000000000011111111111111111111 + 21 0 28 0000000000000000000000000000111111111111111111111 + 22 0 27 0000000000000000000000000001111111111111111111111 + 23 0 26 0000000000000000000000000011111111111111111111111 + 24 0 25 0000000000000000000000000111111111111111111111111 + 25 0 24 0000000000000000000000001111111111111111111111111 + 26 0 23 0000000000000000000000011111111111111111111111111 + 27 0 22 0000000000000000000000111111111111111111111111111 + 28 0 21 0000000000000000000001111111111111111111111111111 + 29 0 20 0000000000000000000011111111111111111111111111111 + 30 0 19 0000000000000000000111111111111111111111111111111 + 31 0 18 0000000000000000001111111111111111111111111111111 + 32 0 17 0000000000000000011111111111111111111111111111111 + 33 0 16 0000000000000000111111111111111111111111111111111 + 34 0 15 0000000000000001111111111111111111111111111111111 + 35 0 14 0000000000000011111111111111111111111111111111111 + 36 0 13 0000000000000111111111111111111111111111111111111 + 37 0 12 0000000000001111111111111111111111111111111111111 + 38 0 11 0000000000011111111111111111111111111111111111111 + 39 0 10 0000000000111111111111111111111111111111111111111 + 40 0 9 0000000001111111111111111111111111111111111111111 + 41 0 8 0000000011111111111111111111111111111111111111111 + 42 0 7 0000000111111111111111111111111111111111111111111 + 43 0 6 0000001111111111111111111111111111111111111111111 + 44 0 5 0000011111111111111111111111111111111111111111111 + 45 0 4 0000111111111111111111111111111111111111111111111 + 46 0 3 0001111111111111111111111111111111111111111111111 + 47 0 2 0011111111111111111111111111111111111111111111111 + 48 0 1 0111111111111111111111111111111111111111111111111 + +0 bit should move right 1 position each line + 0 0 1 0111111111111111111111111111111111111111111111111 + 1 1 0 1011111111111111111111111111111111111111111111111 + 2 2 0 1101111111111111111111111111111111111111111111111 + 3 3 0 1110111111111111111111111111111111111111111111111 + 4 4 0 1111011111111111111111111111111111111111111111111 + 5 5 0 1111101111111111111111111111111111111111111111111 + 6 6 0 1111110111111111111111111111111111111111111111111 + 7 7 0 1111111011111111111111111111111111111111111111111 + 8 8 0 1111111101111111111111111111111111111111111111111 + 9 9 0 1111111110111111111111111111111111111111111111111 + 10 10 0 1111111111011111111111111111111111111111111111111 + 11 11 0 1111111111101111111111111111111111111111111111111 + 12 12 0 1111111111110111111111111111111111111111111111111 + 13 13 0 1111111111111011111111111111111111111111111111111 + 14 14 0 1111111111111101111111111111111111111111111111111 + 15 15 0 1111111111111110111111111111111111111111111111111 + 16 16 0 1111111111111111011111111111111111111111111111111 + 17 17 0 1111111111111111101111111111111111111111111111111 + 18 18 0 1111111111111111110111111111111111111111111111111 + 19 19 0 1111111111111111111011111111111111111111111111111 + 20 20 0 1111111111111111111101111111111111111111111111111 + 21 21 0 1111111111111111111110111111111111111111111111111 + 22 22 0 1111111111111111111111011111111111111111111111111 + 23 23 0 1111111111111111111111101111111111111111111111111 + 24 24 0 1111111111111111111111110111111111111111111111111 + 25 25 0 1111111111111111111111111011111111111111111111111 + 26 26 0 1111111111111111111111111101111111111111111111111 + 27 27 0 1111111111111111111111111110111111111111111111111 + 28 28 0 1111111111111111111111111111011111111111111111111 + 29 29 0 1111111111111111111111111111101111111111111111111 + 30 30 0 1111111111111111111111111111110111111111111111111 + 31 31 0 1111111111111111111111111111111011111111111111111 + 32 32 0 1111111111111111111111111111111101111111111111111 + 33 33 0 1111111111111111111111111111111110111111111111111 + 34 34 0 1111111111111111111111111111111111011111111111111 + 35 35 0 1111111111111111111111111111111111101111111111111 + 36 36 0 1111111111111111111111111111111111110111111111111 + 37 37 0 1111111111111111111111111111111111111011111111111 + 38 38 0 1111111111111111111111111111111111111101111111111 + 39 39 0 1111111111111111111111111111111111111110111111111 + 40 40 0 1111111111111111111111111111111111111111011111111 + 41 41 0 1111111111111111111111111111111111111111101111111 + 42 42 0 1111111111111111111111111111111111111111110111111 + 43 43 0 1111111111111111111111111111111111111111111011111 + 44 44 0 1111111111111111111111111111111111111111111101111 + 45 45 0 1111111111111111111111111111111111111111111110111 + 46 46 0 1111111111111111111111111111111111111111111111011 + 47 47 0 1111111111111111111111111111111111111111111111101 + 48 48 0 1111111111111111111111111111111111111111111111110 + +1 bit should move right 1 position each line + 0 1 0 1000000000000000000000000000000000000000000000000 + 1 0 1 0100000000000000000000000000000000000000000000000 + 2 0 2 0010000000000000000000000000000000000000000000000 + 3 0 3 0001000000000000000000000000000000000000000000000 + 4 0 4 0000100000000000000000000000000000000000000000000 + 5 0 5 0000010000000000000000000000000000000000000000000 + 6 0 6 0000001000000000000000000000000000000000000000000 + 7 0 7 0000000100000000000000000000000000000000000000000 + 8 0 8 0000000010000000000000000000000000000000000000000 + 9 0 9 0000000001000000000000000000000000000000000000000 + 10 0 10 0000000000100000000000000000000000000000000000000 + 11 0 11 0000000000010000000000000000000000000000000000000 + 12 0 12 0000000000001000000000000000000000000000000000000 + 13 0 13 0000000000000100000000000000000000000000000000000 + 14 0 14 0000000000000010000000000000000000000000000000000 + 15 0 15 0000000000000001000000000000000000000000000000000 + 16 0 16 0000000000000000100000000000000000000000000000000 + 17 0 17 0000000000000000010000000000000000000000000000000 + 18 0 18 0000000000000000001000000000000000000000000000000 + 19 0 19 0000000000000000000100000000000000000000000000000 + 20 0 20 0000000000000000000010000000000000000000000000000 + 21 0 21 0000000000000000000001000000000000000000000000000 + 22 0 22 0000000000000000000000100000000000000000000000000 + 23 0 23 0000000000000000000000010000000000000000000000000 + 24 0 24 0000000000000000000000001000000000000000000000000 + 25 0 25 0000000000000000000000000100000000000000000000000 + 26 0 26 0000000000000000000000000010000000000000000000000 + 27 0 27 0000000000000000000000000001000000000000000000000 + 28 0 28 0000000000000000000000000000100000000000000000000 + 29 0 29 0000000000000000000000000000010000000000000000000 + 30 0 30 0000000000000000000000000000001000000000000000000 + 31 0 31 0000000000000000000000000000000100000000000000000 + 32 0 32 0000000000000000000000000000000010000000000000000 + 33 0 33 0000000000000000000000000000000001000000000000000 + 34 0 34 0000000000000000000000000000000000100000000000000 + 35 0 35 0000000000000000000000000000000000010000000000000 + 36 0 36 0000000000000000000000000000000000001000000000000 + 37 0 37 0000000000000000000000000000000000000100000000000 + 38 0 38 0000000000000000000000000000000000000010000000000 + 39 0 39 0000000000000000000000000000000000000001000000000 + 40 0 40 0000000000000000000000000000000000000000100000000 + 41 0 41 0000000000000000000000000000000000000000010000000 + 42 0 42 0000000000000000000000000000000000000000001000000 + 43 0 43 0000000000000000000000000000000000000000000100000 + 44 0 44 0000000000000000000000000000000000000000000010000 + 45 0 45 0000000000000000000000000000000000000000000001000 + 46 0 46 0000000000000000000000000000000000000000000000100 + 47 0 47 0000000000000000000000000000000000000000000000010 + 48 0 48 0000000000000000000000000000000000000000000000001 diff --git a/contrib/netbsd-tests/include/d_bitstring_64.out b/contrib/netbsd-tests/include/d_bitstring_64.out new file mode 100644 index 0000000..7e9308e --- /dev/null +++ b/contrib/netbsd-tests/include/d_bitstring_64.out @@ -0,0 +1,559 @@ +Testing with TEST_LENGTH = 64 + +test _bit_byte, _bit_mask, and bitstr_size + i _bit_byte(i) _bit_mask(i) bitstr_size(i) + 0 0 1 0 + 1 0 2 1 + 2 0 4 1 + 3 0 8 1 + 4 0 16 1 + 5 0 32 1 + 6 0 64 1 + 7 0 128 1 + 8 1 1 1 + 9 1 2 2 + 10 1 4 2 + 11 1 8 2 + 12 1 16 2 + 13 1 32 2 + 14 1 64 2 + 15 1 128 2 + 16 2 1 2 + 17 2 2 3 + 18 2 4 3 + 19 2 8 3 + 20 2 16 3 + 21 2 32 3 + 22 2 64 3 + 23 2 128 3 + 24 3 1 3 + 25 3 2 4 + 26 3 4 4 + 27 3 8 4 + 28 3 16 4 + 29 3 32 4 + 30 3 64 4 + 31 3 128 4 + 32 4 1 4 + 33 4 2 5 + 34 4 4 5 + 35 4 8 5 + 36 4 16 5 + 37 4 32 5 + 38 4 64 5 + 39 4 128 5 + 40 5 1 5 + 41 5 2 6 + 42 5 4 6 + 43 5 8 6 + 44 5 16 6 + 45 5 32 6 + 46 5 64 6 + 47 5 128 6 + 48 6 1 6 + 49 6 2 7 + 50 6 4 7 + 51 6 8 7 + 52 6 16 7 + 53 6 32 7 + 54 6 64 7 + 55 6 128 7 + 56 7 1 7 + 57 7 2 8 + 58 7 4 8 + 59 7 8 8 + 60 7 16 8 + 61 7 32 8 + 62 7 64 8 + 63 7 128 8 + +test bit_alloc, clearbits, bit_ffc, bit_ffs +be: 0 -1 0000000000000000000000000000000000000000000000000000000000000000 +is: 0 -1 0000000000000000000000000000000000000000000000000000000000000000 + +test bit_set +be: 1 0 1001001001001001001001001001001001001001001001001001001001001001 +is: 1 0 1001001001001001001001001001001001001001001001001001001001001001 + +test bit_clear +be: 0 3 0001000001000001000001000001000001000001000001000001000001000001 +is: 0 3 0001000001000001000001000001000001000001000001000001000001000001 + +test bit_test using previous bitstring + i bit_test(i) + 0 0 + 1 0 + 2 0 + 3 8 + 4 0 + 5 0 + 6 0 + 7 0 + 8 0 + 9 2 + 10 0 + 11 0 + 12 0 + 13 0 + 14 0 + 15 128 + 16 0 + 17 0 + 18 0 + 19 0 + 20 0 + 21 32 + 22 0 + 23 0 + 24 0 + 25 0 + 26 0 + 27 8 + 28 0 + 29 0 + 30 0 + 31 0 + 32 0 + 33 2 + 34 0 + 35 0 + 36 0 + 37 0 + 38 0 + 39 128 + 40 0 + 41 0 + 42 0 + 43 0 + 44 0 + 45 32 + 46 0 + 47 0 + 48 0 + 49 0 + 50 0 + 51 8 + 52 0 + 53 0 + 54 0 + 55 0 + 56 0 + 57 2 + 58 0 + 59 0 + 60 0 + 61 0 + 62 0 + 63 128 + +test clearbits +be: 0 -1 0000000000000000000000000000000000000000000000000000000000000000 +is: 0 -1 0000000000000000000000000000000000000000000000000000000000000000 + +test bit_nset and bit_nclear +be: 0 1 0111111111111111111111111111111111111111111111111111111111111110 +is: 0 1 0111111111111111111111111111111111111111111111111111111111111110 +be: 0 1 0100000000000000000000000000000000000000000000000000000000000010 +is: 0 1 0100000000000000000000000000000000000000000000000000000000000010 +be: 0 -1 0000000000000000000000000000000000000000000000000000000000000000 +is: 0 -1 0000000000000000000000000000000000000000000000000000000000000000 +be: 63 0 1111111111111111111111111111111111111111111111111111111111111110 +is: 63 0 1111111111111111111111111111111111111111111111111111111111111110 +be: 0 -1 0000000000000000000000000000000000000000000000000000000000000000 +is: 0 -1 0000000000000000000000000000000000000000000000000000000000000000 + +first 1 bit should move right 1 position each line + 0 -1 0 1111111111111111111111111111111111111111111111111111111111111111 + 1 0 1 0111111111111111111111111111111111111111111111111111111111111111 + 2 0 2 0011111111111111111111111111111111111111111111111111111111111111 + 3 0 3 0001111111111111111111111111111111111111111111111111111111111111 + 4 0 4 0000111111111111111111111111111111111111111111111111111111111111 + 5 0 5 0000011111111111111111111111111111111111111111111111111111111111 + 6 0 6 0000001111111111111111111111111111111111111111111111111111111111 + 7 0 7 0000000111111111111111111111111111111111111111111111111111111111 + 8 0 8 0000000011111111111111111111111111111111111111111111111111111111 + 9 0 9 0000000001111111111111111111111111111111111111111111111111111111 + 10 0 10 0000000000111111111111111111111111111111111111111111111111111111 + 11 0 11 0000000000011111111111111111111111111111111111111111111111111111 + 12 0 12 0000000000001111111111111111111111111111111111111111111111111111 + 13 0 13 0000000000000111111111111111111111111111111111111111111111111111 + 14 0 14 0000000000000011111111111111111111111111111111111111111111111111 + 15 0 15 0000000000000001111111111111111111111111111111111111111111111111 + 16 0 16 0000000000000000111111111111111111111111111111111111111111111111 + 17 0 17 0000000000000000011111111111111111111111111111111111111111111111 + 18 0 18 0000000000000000001111111111111111111111111111111111111111111111 + 19 0 19 0000000000000000000111111111111111111111111111111111111111111111 + 20 0 20 0000000000000000000011111111111111111111111111111111111111111111 + 21 0 21 0000000000000000000001111111111111111111111111111111111111111111 + 22 0 22 0000000000000000000000111111111111111111111111111111111111111111 + 23 0 23 0000000000000000000000011111111111111111111111111111111111111111 + 24 0 24 0000000000000000000000001111111111111111111111111111111111111111 + 25 0 25 0000000000000000000000000111111111111111111111111111111111111111 + 26 0 26 0000000000000000000000000011111111111111111111111111111111111111 + 27 0 27 0000000000000000000000000001111111111111111111111111111111111111 + 28 0 28 0000000000000000000000000000111111111111111111111111111111111111 + 29 0 29 0000000000000000000000000000011111111111111111111111111111111111 + 30 0 30 0000000000000000000000000000001111111111111111111111111111111111 + 31 0 31 0000000000000000000000000000000111111111111111111111111111111111 + 32 0 32 0000000000000000000000000000000011111111111111111111111111111111 + 33 0 33 0000000000000000000000000000000001111111111111111111111111111111 + 34 0 34 0000000000000000000000000000000000111111111111111111111111111111 + 35 0 35 0000000000000000000000000000000000011111111111111111111111111111 + 36 0 36 0000000000000000000000000000000000001111111111111111111111111111 + 37 0 37 0000000000000000000000000000000000000111111111111111111111111111 + 38 0 38 0000000000000000000000000000000000000011111111111111111111111111 + 39 0 39 0000000000000000000000000000000000000001111111111111111111111111 + 40 0 40 0000000000000000000000000000000000000000111111111111111111111111 + 41 0 41 0000000000000000000000000000000000000000011111111111111111111111 + 42 0 42 0000000000000000000000000000000000000000001111111111111111111111 + 43 0 43 0000000000000000000000000000000000000000000111111111111111111111 + 44 0 44 0000000000000000000000000000000000000000000011111111111111111111 + 45 0 45 0000000000000000000000000000000000000000000001111111111111111111 + 46 0 46 0000000000000000000000000000000000000000000000111111111111111111 + 47 0 47 0000000000000000000000000000000000000000000000011111111111111111 + 48 0 48 0000000000000000000000000000000000000000000000001111111111111111 + 49 0 49 0000000000000000000000000000000000000000000000000111111111111111 + 50 0 50 0000000000000000000000000000000000000000000000000011111111111111 + 51 0 51 0000000000000000000000000000000000000000000000000001111111111111 + 52 0 52 0000000000000000000000000000000000000000000000000000111111111111 + 53 0 53 0000000000000000000000000000000000000000000000000000011111111111 + 54 0 54 0000000000000000000000000000000000000000000000000000001111111111 + 55 0 55 0000000000000000000000000000000000000000000000000000000111111111 + 56 0 56 0000000000000000000000000000000000000000000000000000000011111111 + 57 0 57 0000000000000000000000000000000000000000000000000000000001111111 + 58 0 58 0000000000000000000000000000000000000000000000000000000000111111 + 59 0 59 0000000000000000000000000000000000000000000000000000000000011111 + 60 0 60 0000000000000000000000000000000000000000000000000000000000001111 + 61 0 61 0000000000000000000000000000000000000000000000000000000000000111 + 62 0 62 0000000000000000000000000000000000000000000000000000000000000011 + 63 0 63 0000000000000000000000000000000000000000000000000000000000000001 + +first 0 bit should move right 1 position each line + 0 0 -1 0000000000000000000000000000000000000000000000000000000000000000 + 1 1 0 1000000000000000000000000000000000000000000000000000000000000000 + 2 2 0 1100000000000000000000000000000000000000000000000000000000000000 + 3 3 0 1110000000000000000000000000000000000000000000000000000000000000 + 4 4 0 1111000000000000000000000000000000000000000000000000000000000000 + 5 5 0 1111100000000000000000000000000000000000000000000000000000000000 + 6 6 0 1111110000000000000000000000000000000000000000000000000000000000 + 7 7 0 1111111000000000000000000000000000000000000000000000000000000000 + 8 8 0 1111111100000000000000000000000000000000000000000000000000000000 + 9 9 0 1111111110000000000000000000000000000000000000000000000000000000 + 10 10 0 1111111111000000000000000000000000000000000000000000000000000000 + 11 11 0 1111111111100000000000000000000000000000000000000000000000000000 + 12 12 0 1111111111110000000000000000000000000000000000000000000000000000 + 13 13 0 1111111111111000000000000000000000000000000000000000000000000000 + 14 14 0 1111111111111100000000000000000000000000000000000000000000000000 + 15 15 0 1111111111111110000000000000000000000000000000000000000000000000 + 16 16 0 1111111111111111000000000000000000000000000000000000000000000000 + 17 17 0 1111111111111111100000000000000000000000000000000000000000000000 + 18 18 0 1111111111111111110000000000000000000000000000000000000000000000 + 19 19 0 1111111111111111111000000000000000000000000000000000000000000000 + 20 20 0 1111111111111111111100000000000000000000000000000000000000000000 + 21 21 0 1111111111111111111110000000000000000000000000000000000000000000 + 22 22 0 1111111111111111111111000000000000000000000000000000000000000000 + 23 23 0 1111111111111111111111100000000000000000000000000000000000000000 + 24 24 0 1111111111111111111111110000000000000000000000000000000000000000 + 25 25 0 1111111111111111111111111000000000000000000000000000000000000000 + 26 26 0 1111111111111111111111111100000000000000000000000000000000000000 + 27 27 0 1111111111111111111111111110000000000000000000000000000000000000 + 28 28 0 1111111111111111111111111111000000000000000000000000000000000000 + 29 29 0 1111111111111111111111111111100000000000000000000000000000000000 + 30 30 0 1111111111111111111111111111110000000000000000000000000000000000 + 31 31 0 1111111111111111111111111111111000000000000000000000000000000000 + 32 32 0 1111111111111111111111111111111100000000000000000000000000000000 + 33 33 0 1111111111111111111111111111111110000000000000000000000000000000 + 34 34 0 1111111111111111111111111111111111000000000000000000000000000000 + 35 35 0 1111111111111111111111111111111111100000000000000000000000000000 + 36 36 0 1111111111111111111111111111111111110000000000000000000000000000 + 37 37 0 1111111111111111111111111111111111111000000000000000000000000000 + 38 38 0 1111111111111111111111111111111111111100000000000000000000000000 + 39 39 0 1111111111111111111111111111111111111110000000000000000000000000 + 40 40 0 1111111111111111111111111111111111111111000000000000000000000000 + 41 41 0 1111111111111111111111111111111111111111100000000000000000000000 + 42 42 0 1111111111111111111111111111111111111111110000000000000000000000 + 43 43 0 1111111111111111111111111111111111111111111000000000000000000000 + 44 44 0 1111111111111111111111111111111111111111111100000000000000000000 + 45 45 0 1111111111111111111111111111111111111111111110000000000000000000 + 46 46 0 1111111111111111111111111111111111111111111111000000000000000000 + 47 47 0 1111111111111111111111111111111111111111111111100000000000000000 + 48 48 0 1111111111111111111111111111111111111111111111110000000000000000 + 49 49 0 1111111111111111111111111111111111111111111111111000000000000000 + 50 50 0 1111111111111111111111111111111111111111111111111100000000000000 + 51 51 0 1111111111111111111111111111111111111111111111111110000000000000 + 52 52 0 1111111111111111111111111111111111111111111111111111000000000000 + 53 53 0 1111111111111111111111111111111111111111111111111111100000000000 + 54 54 0 1111111111111111111111111111111111111111111111111111110000000000 + 55 55 0 1111111111111111111111111111111111111111111111111111111000000000 + 56 56 0 1111111111111111111111111111111111111111111111111111111100000000 + 57 57 0 1111111111111111111111111111111111111111111111111111111110000000 + 58 58 0 1111111111111111111111111111111111111111111111111111111111000000 + 59 59 0 1111111111111111111111111111111111111111111111111111111111100000 + 60 60 0 1111111111111111111111111111111111111111111111111111111111110000 + 61 61 0 1111111111111111111111111111111111111111111111111111111111111000 + 62 62 0 1111111111111111111111111111111111111111111111111111111111111100 + 63 63 0 1111111111111111111111111111111111111111111111111111111111111110 + +first 0 bit should move left 1 position each line + 0 -1 0 1111111111111111111111111111111111111111111111111111111111111111 + 1 63 0 1111111111111111111111111111111111111111111111111111111111111110 + 2 62 0 1111111111111111111111111111111111111111111111111111111111111100 + 3 61 0 1111111111111111111111111111111111111111111111111111111111111000 + 4 60 0 1111111111111111111111111111111111111111111111111111111111110000 + 5 59 0 1111111111111111111111111111111111111111111111111111111111100000 + 6 58 0 1111111111111111111111111111111111111111111111111111111111000000 + 7 57 0 1111111111111111111111111111111111111111111111111111111110000000 + 8 56 0 1111111111111111111111111111111111111111111111111111111100000000 + 9 55 0 1111111111111111111111111111111111111111111111111111111000000000 + 10 54 0 1111111111111111111111111111111111111111111111111111110000000000 + 11 53 0 1111111111111111111111111111111111111111111111111111100000000000 + 12 52 0 1111111111111111111111111111111111111111111111111111000000000000 + 13 51 0 1111111111111111111111111111111111111111111111111110000000000000 + 14 50 0 1111111111111111111111111111111111111111111111111100000000000000 + 15 49 0 1111111111111111111111111111111111111111111111111000000000000000 + 16 48 0 1111111111111111111111111111111111111111111111110000000000000000 + 17 47 0 1111111111111111111111111111111111111111111111100000000000000000 + 18 46 0 1111111111111111111111111111111111111111111111000000000000000000 + 19 45 0 1111111111111111111111111111111111111111111110000000000000000000 + 20 44 0 1111111111111111111111111111111111111111111100000000000000000000 + 21 43 0 1111111111111111111111111111111111111111111000000000000000000000 + 22 42 0 1111111111111111111111111111111111111111110000000000000000000000 + 23 41 0 1111111111111111111111111111111111111111100000000000000000000000 + 24 40 0 1111111111111111111111111111111111111111000000000000000000000000 + 25 39 0 1111111111111111111111111111111111111110000000000000000000000000 + 26 38 0 1111111111111111111111111111111111111100000000000000000000000000 + 27 37 0 1111111111111111111111111111111111111000000000000000000000000000 + 28 36 0 1111111111111111111111111111111111110000000000000000000000000000 + 29 35 0 1111111111111111111111111111111111100000000000000000000000000000 + 30 34 0 1111111111111111111111111111111111000000000000000000000000000000 + 31 33 0 1111111111111111111111111111111110000000000000000000000000000000 + 32 32 0 1111111111111111111111111111111100000000000000000000000000000000 + 33 31 0 1111111111111111111111111111111000000000000000000000000000000000 + 34 30 0 1111111111111111111111111111110000000000000000000000000000000000 + 35 29 0 1111111111111111111111111111100000000000000000000000000000000000 + 36 28 0 1111111111111111111111111111000000000000000000000000000000000000 + 37 27 0 1111111111111111111111111110000000000000000000000000000000000000 + 38 26 0 1111111111111111111111111100000000000000000000000000000000000000 + 39 25 0 1111111111111111111111111000000000000000000000000000000000000000 + 40 24 0 1111111111111111111111110000000000000000000000000000000000000000 + 41 23 0 1111111111111111111111100000000000000000000000000000000000000000 + 42 22 0 1111111111111111111111000000000000000000000000000000000000000000 + 43 21 0 1111111111111111111110000000000000000000000000000000000000000000 + 44 20 0 1111111111111111111100000000000000000000000000000000000000000000 + 45 19 0 1111111111111111111000000000000000000000000000000000000000000000 + 46 18 0 1111111111111111110000000000000000000000000000000000000000000000 + 47 17 0 1111111111111111100000000000000000000000000000000000000000000000 + 48 16 0 1111111111111111000000000000000000000000000000000000000000000000 + 49 15 0 1111111111111110000000000000000000000000000000000000000000000000 + 50 14 0 1111111111111100000000000000000000000000000000000000000000000000 + 51 13 0 1111111111111000000000000000000000000000000000000000000000000000 + 52 12 0 1111111111110000000000000000000000000000000000000000000000000000 + 53 11 0 1111111111100000000000000000000000000000000000000000000000000000 + 54 10 0 1111111111000000000000000000000000000000000000000000000000000000 + 55 9 0 1111111110000000000000000000000000000000000000000000000000000000 + 56 8 0 1111111100000000000000000000000000000000000000000000000000000000 + 57 7 0 1111111000000000000000000000000000000000000000000000000000000000 + 58 6 0 1111110000000000000000000000000000000000000000000000000000000000 + 59 5 0 1111100000000000000000000000000000000000000000000000000000000000 + 60 4 0 1111000000000000000000000000000000000000000000000000000000000000 + 61 3 0 1110000000000000000000000000000000000000000000000000000000000000 + 62 2 0 1100000000000000000000000000000000000000000000000000000000000000 + 63 1 0 1000000000000000000000000000000000000000000000000000000000000000 + +first 1 bit should move left 1 position each line + 0 0 -1 0000000000000000000000000000000000000000000000000000000000000000 + 1 0 63 0000000000000000000000000000000000000000000000000000000000000001 + 2 0 62 0000000000000000000000000000000000000000000000000000000000000011 + 3 0 61 0000000000000000000000000000000000000000000000000000000000000111 + 4 0 60 0000000000000000000000000000000000000000000000000000000000001111 + 5 0 59 0000000000000000000000000000000000000000000000000000000000011111 + 6 0 58 0000000000000000000000000000000000000000000000000000000000111111 + 7 0 57 0000000000000000000000000000000000000000000000000000000001111111 + 8 0 56 0000000000000000000000000000000000000000000000000000000011111111 + 9 0 55 0000000000000000000000000000000000000000000000000000000111111111 + 10 0 54 0000000000000000000000000000000000000000000000000000001111111111 + 11 0 53 0000000000000000000000000000000000000000000000000000011111111111 + 12 0 52 0000000000000000000000000000000000000000000000000000111111111111 + 13 0 51 0000000000000000000000000000000000000000000000000001111111111111 + 14 0 50 0000000000000000000000000000000000000000000000000011111111111111 + 15 0 49 0000000000000000000000000000000000000000000000000111111111111111 + 16 0 48 0000000000000000000000000000000000000000000000001111111111111111 + 17 0 47 0000000000000000000000000000000000000000000000011111111111111111 + 18 0 46 0000000000000000000000000000000000000000000000111111111111111111 + 19 0 45 0000000000000000000000000000000000000000000001111111111111111111 + 20 0 44 0000000000000000000000000000000000000000000011111111111111111111 + 21 0 43 0000000000000000000000000000000000000000000111111111111111111111 + 22 0 42 0000000000000000000000000000000000000000001111111111111111111111 + 23 0 41 0000000000000000000000000000000000000000011111111111111111111111 + 24 0 40 0000000000000000000000000000000000000000111111111111111111111111 + 25 0 39 0000000000000000000000000000000000000001111111111111111111111111 + 26 0 38 0000000000000000000000000000000000000011111111111111111111111111 + 27 0 37 0000000000000000000000000000000000000111111111111111111111111111 + 28 0 36 0000000000000000000000000000000000001111111111111111111111111111 + 29 0 35 0000000000000000000000000000000000011111111111111111111111111111 + 30 0 34 0000000000000000000000000000000000111111111111111111111111111111 + 31 0 33 0000000000000000000000000000000001111111111111111111111111111111 + 32 0 32 0000000000000000000000000000000011111111111111111111111111111111 + 33 0 31 0000000000000000000000000000000111111111111111111111111111111111 + 34 0 30 0000000000000000000000000000001111111111111111111111111111111111 + 35 0 29 0000000000000000000000000000011111111111111111111111111111111111 + 36 0 28 0000000000000000000000000000111111111111111111111111111111111111 + 37 0 27 0000000000000000000000000001111111111111111111111111111111111111 + 38 0 26 0000000000000000000000000011111111111111111111111111111111111111 + 39 0 25 0000000000000000000000000111111111111111111111111111111111111111 + 40 0 24 0000000000000000000000001111111111111111111111111111111111111111 + 41 0 23 0000000000000000000000011111111111111111111111111111111111111111 + 42 0 22 0000000000000000000000111111111111111111111111111111111111111111 + 43 0 21 0000000000000000000001111111111111111111111111111111111111111111 + 44 0 20 0000000000000000000011111111111111111111111111111111111111111111 + 45 0 19 0000000000000000000111111111111111111111111111111111111111111111 + 46 0 18 0000000000000000001111111111111111111111111111111111111111111111 + 47 0 17 0000000000000000011111111111111111111111111111111111111111111111 + 48 0 16 0000000000000000111111111111111111111111111111111111111111111111 + 49 0 15 0000000000000001111111111111111111111111111111111111111111111111 + 50 0 14 0000000000000011111111111111111111111111111111111111111111111111 + 51 0 13 0000000000000111111111111111111111111111111111111111111111111111 + 52 0 12 0000000000001111111111111111111111111111111111111111111111111111 + 53 0 11 0000000000011111111111111111111111111111111111111111111111111111 + 54 0 10 0000000000111111111111111111111111111111111111111111111111111111 + 55 0 9 0000000001111111111111111111111111111111111111111111111111111111 + 56 0 8 0000000011111111111111111111111111111111111111111111111111111111 + 57 0 7 0000000111111111111111111111111111111111111111111111111111111111 + 58 0 6 0000001111111111111111111111111111111111111111111111111111111111 + 59 0 5 0000011111111111111111111111111111111111111111111111111111111111 + 60 0 4 0000111111111111111111111111111111111111111111111111111111111111 + 61 0 3 0001111111111111111111111111111111111111111111111111111111111111 + 62 0 2 0011111111111111111111111111111111111111111111111111111111111111 + 63 0 1 0111111111111111111111111111111111111111111111111111111111111111 + +0 bit should move right 1 position each line + 0 0 1 0111111111111111111111111111111111111111111111111111111111111111 + 1 1 0 1011111111111111111111111111111111111111111111111111111111111111 + 2 2 0 1101111111111111111111111111111111111111111111111111111111111111 + 3 3 0 1110111111111111111111111111111111111111111111111111111111111111 + 4 4 0 1111011111111111111111111111111111111111111111111111111111111111 + 5 5 0 1111101111111111111111111111111111111111111111111111111111111111 + 6 6 0 1111110111111111111111111111111111111111111111111111111111111111 + 7 7 0 1111111011111111111111111111111111111111111111111111111111111111 + 8 8 0 1111111101111111111111111111111111111111111111111111111111111111 + 9 9 0 1111111110111111111111111111111111111111111111111111111111111111 + 10 10 0 1111111111011111111111111111111111111111111111111111111111111111 + 11 11 0 1111111111101111111111111111111111111111111111111111111111111111 + 12 12 0 1111111111110111111111111111111111111111111111111111111111111111 + 13 13 0 1111111111111011111111111111111111111111111111111111111111111111 + 14 14 0 1111111111111101111111111111111111111111111111111111111111111111 + 15 15 0 1111111111111110111111111111111111111111111111111111111111111111 + 16 16 0 1111111111111111011111111111111111111111111111111111111111111111 + 17 17 0 1111111111111111101111111111111111111111111111111111111111111111 + 18 18 0 1111111111111111110111111111111111111111111111111111111111111111 + 19 19 0 1111111111111111111011111111111111111111111111111111111111111111 + 20 20 0 1111111111111111111101111111111111111111111111111111111111111111 + 21 21 0 1111111111111111111110111111111111111111111111111111111111111111 + 22 22 0 1111111111111111111111011111111111111111111111111111111111111111 + 23 23 0 1111111111111111111111101111111111111111111111111111111111111111 + 24 24 0 1111111111111111111111110111111111111111111111111111111111111111 + 25 25 0 1111111111111111111111111011111111111111111111111111111111111111 + 26 26 0 1111111111111111111111111101111111111111111111111111111111111111 + 27 27 0 1111111111111111111111111110111111111111111111111111111111111111 + 28 28 0 1111111111111111111111111111011111111111111111111111111111111111 + 29 29 0 1111111111111111111111111111101111111111111111111111111111111111 + 30 30 0 1111111111111111111111111111110111111111111111111111111111111111 + 31 31 0 1111111111111111111111111111111011111111111111111111111111111111 + 32 32 0 1111111111111111111111111111111101111111111111111111111111111111 + 33 33 0 1111111111111111111111111111111110111111111111111111111111111111 + 34 34 0 1111111111111111111111111111111111011111111111111111111111111111 + 35 35 0 1111111111111111111111111111111111101111111111111111111111111111 + 36 36 0 1111111111111111111111111111111111110111111111111111111111111111 + 37 37 0 1111111111111111111111111111111111111011111111111111111111111111 + 38 38 0 1111111111111111111111111111111111111101111111111111111111111111 + 39 39 0 1111111111111111111111111111111111111110111111111111111111111111 + 40 40 0 1111111111111111111111111111111111111111011111111111111111111111 + 41 41 0 1111111111111111111111111111111111111111101111111111111111111111 + 42 42 0 1111111111111111111111111111111111111111110111111111111111111111 + 43 43 0 1111111111111111111111111111111111111111111011111111111111111111 + 44 44 0 1111111111111111111111111111111111111111111101111111111111111111 + 45 45 0 1111111111111111111111111111111111111111111110111111111111111111 + 46 46 0 1111111111111111111111111111111111111111111111011111111111111111 + 47 47 0 1111111111111111111111111111111111111111111111101111111111111111 + 48 48 0 1111111111111111111111111111111111111111111111110111111111111111 + 49 49 0 1111111111111111111111111111111111111111111111111011111111111111 + 50 50 0 1111111111111111111111111111111111111111111111111101111111111111 + 51 51 0 1111111111111111111111111111111111111111111111111110111111111111 + 52 52 0 1111111111111111111111111111111111111111111111111111011111111111 + 53 53 0 1111111111111111111111111111111111111111111111111111101111111111 + 54 54 0 1111111111111111111111111111111111111111111111111111110111111111 + 55 55 0 1111111111111111111111111111111111111111111111111111111011111111 + 56 56 0 1111111111111111111111111111111111111111111111111111111101111111 + 57 57 0 1111111111111111111111111111111111111111111111111111111110111111 + 58 58 0 1111111111111111111111111111111111111111111111111111111111011111 + 59 59 0 1111111111111111111111111111111111111111111111111111111111101111 + 60 60 0 1111111111111111111111111111111111111111111111111111111111110111 + 61 61 0 1111111111111111111111111111111111111111111111111111111111111011 + 62 62 0 1111111111111111111111111111111111111111111111111111111111111101 + 63 63 0 1111111111111111111111111111111111111111111111111111111111111110 + +1 bit should move right 1 position each line + 0 1 0 1000000000000000000000000000000000000000000000000000000000000000 + 1 0 1 0100000000000000000000000000000000000000000000000000000000000000 + 2 0 2 0010000000000000000000000000000000000000000000000000000000000000 + 3 0 3 0001000000000000000000000000000000000000000000000000000000000000 + 4 0 4 0000100000000000000000000000000000000000000000000000000000000000 + 5 0 5 0000010000000000000000000000000000000000000000000000000000000000 + 6 0 6 0000001000000000000000000000000000000000000000000000000000000000 + 7 0 7 0000000100000000000000000000000000000000000000000000000000000000 + 8 0 8 0000000010000000000000000000000000000000000000000000000000000000 + 9 0 9 0000000001000000000000000000000000000000000000000000000000000000 + 10 0 10 0000000000100000000000000000000000000000000000000000000000000000 + 11 0 11 0000000000010000000000000000000000000000000000000000000000000000 + 12 0 12 0000000000001000000000000000000000000000000000000000000000000000 + 13 0 13 0000000000000100000000000000000000000000000000000000000000000000 + 14 0 14 0000000000000010000000000000000000000000000000000000000000000000 + 15 0 15 0000000000000001000000000000000000000000000000000000000000000000 + 16 0 16 0000000000000000100000000000000000000000000000000000000000000000 + 17 0 17 0000000000000000010000000000000000000000000000000000000000000000 + 18 0 18 0000000000000000001000000000000000000000000000000000000000000000 + 19 0 19 0000000000000000000100000000000000000000000000000000000000000000 + 20 0 20 0000000000000000000010000000000000000000000000000000000000000000 + 21 0 21 0000000000000000000001000000000000000000000000000000000000000000 + 22 0 22 0000000000000000000000100000000000000000000000000000000000000000 + 23 0 23 0000000000000000000000010000000000000000000000000000000000000000 + 24 0 24 0000000000000000000000001000000000000000000000000000000000000000 + 25 0 25 0000000000000000000000000100000000000000000000000000000000000000 + 26 0 26 0000000000000000000000000010000000000000000000000000000000000000 + 27 0 27 0000000000000000000000000001000000000000000000000000000000000000 + 28 0 28 0000000000000000000000000000100000000000000000000000000000000000 + 29 0 29 0000000000000000000000000000010000000000000000000000000000000000 + 30 0 30 0000000000000000000000000000001000000000000000000000000000000000 + 31 0 31 0000000000000000000000000000000100000000000000000000000000000000 + 32 0 32 0000000000000000000000000000000010000000000000000000000000000000 + 33 0 33 0000000000000000000000000000000001000000000000000000000000000000 + 34 0 34 0000000000000000000000000000000000100000000000000000000000000000 + 35 0 35 0000000000000000000000000000000000010000000000000000000000000000 + 36 0 36 0000000000000000000000000000000000001000000000000000000000000000 + 37 0 37 0000000000000000000000000000000000000100000000000000000000000000 + 38 0 38 0000000000000000000000000000000000000010000000000000000000000000 + 39 0 39 0000000000000000000000000000000000000001000000000000000000000000 + 40 0 40 0000000000000000000000000000000000000000100000000000000000000000 + 41 0 41 0000000000000000000000000000000000000000010000000000000000000000 + 42 0 42 0000000000000000000000000000000000000000001000000000000000000000 + 43 0 43 0000000000000000000000000000000000000000000100000000000000000000 + 44 0 44 0000000000000000000000000000000000000000000010000000000000000000 + 45 0 45 0000000000000000000000000000000000000000000001000000000000000000 + 46 0 46 0000000000000000000000000000000000000000000000100000000000000000 + 47 0 47 0000000000000000000000000000000000000000000000010000000000000000 + 48 0 48 0000000000000000000000000000000000000000000000001000000000000000 + 49 0 49 0000000000000000000000000000000000000000000000000100000000000000 + 50 0 50 0000000000000000000000000000000000000000000000000010000000000000 + 51 0 51 0000000000000000000000000000000000000000000000000001000000000000 + 52 0 52 0000000000000000000000000000000000000000000000000000100000000000 + 53 0 53 0000000000000000000000000000000000000000000000000000010000000000 + 54 0 54 0000000000000000000000000000000000000000000000000000001000000000 + 55 0 55 0000000000000000000000000000000000000000000000000000000100000000 + 56 0 56 0000000000000000000000000000000000000000000000000000000010000000 + 57 0 57 0000000000000000000000000000000000000000000000000000000001000000 + 58 0 58 0000000000000000000000000000000000000000000000000000000000100000 + 59 0 59 0000000000000000000000000000000000000000000000000000000000010000 + 60 0 60 0000000000000000000000000000000000000000000000000000000000001000 + 61 0 61 0000000000000000000000000000000000000000000000000000000000000100 + 62 0 62 0000000000000000000000000000000000000000000000000000000000000010 + 63 0 63 0000000000000000000000000000000000000000000000000000000000000001 diff --git a/contrib/netbsd-tests/include/d_bitstring_67.out b/contrib/netbsd-tests/include/d_bitstring_67.out new file mode 100644 index 0000000..e5decc3 --- /dev/null +++ b/contrib/netbsd-tests/include/d_bitstring_67.out @@ -0,0 +1,583 @@ +Testing with TEST_LENGTH = 67 + +test _bit_byte, _bit_mask, and bitstr_size + i _bit_byte(i) _bit_mask(i) bitstr_size(i) + 0 0 1 0 + 1 0 2 1 + 2 0 4 1 + 3 0 8 1 + 4 0 16 1 + 5 0 32 1 + 6 0 64 1 + 7 0 128 1 + 8 1 1 1 + 9 1 2 2 + 10 1 4 2 + 11 1 8 2 + 12 1 16 2 + 13 1 32 2 + 14 1 64 2 + 15 1 128 2 + 16 2 1 2 + 17 2 2 3 + 18 2 4 3 + 19 2 8 3 + 20 2 16 3 + 21 2 32 3 + 22 2 64 3 + 23 2 128 3 + 24 3 1 3 + 25 3 2 4 + 26 3 4 4 + 27 3 8 4 + 28 3 16 4 + 29 3 32 4 + 30 3 64 4 + 31 3 128 4 + 32 4 1 4 + 33 4 2 5 + 34 4 4 5 + 35 4 8 5 + 36 4 16 5 + 37 4 32 5 + 38 4 64 5 + 39 4 128 5 + 40 5 1 5 + 41 5 2 6 + 42 5 4 6 + 43 5 8 6 + 44 5 16 6 + 45 5 32 6 + 46 5 64 6 + 47 5 128 6 + 48 6 1 6 + 49 6 2 7 + 50 6 4 7 + 51 6 8 7 + 52 6 16 7 + 53 6 32 7 + 54 6 64 7 + 55 6 128 7 + 56 7 1 7 + 57 7 2 8 + 58 7 4 8 + 59 7 8 8 + 60 7 16 8 + 61 7 32 8 + 62 7 64 8 + 63 7 128 8 + 64 8 1 8 + 65 8 2 9 + 66 8 4 9 + +test bit_alloc, clearbits, bit_ffc, bit_ffs +be: 0 -1 0000000000000000000000000000000000000000000000000000000000000000000 +is: 0 -1 0000000000000000000000000000000000000000000000000000000000000000000 + +test bit_set +be: 1 0 1001001001001001001001001001001001001001001001001001001001001001001 +is: 1 0 1001001001001001001001001001001001001001001001001001001001001001001 + +test bit_clear +be: 0 3 0001000001000001000001000001000001000001000001000001000001000001000 +is: 0 3 0001000001000001000001000001000001000001000001000001000001000001000 + +test bit_test using previous bitstring + i bit_test(i) + 0 0 + 1 0 + 2 0 + 3 8 + 4 0 + 5 0 + 6 0 + 7 0 + 8 0 + 9 2 + 10 0 + 11 0 + 12 0 + 13 0 + 14 0 + 15 128 + 16 0 + 17 0 + 18 0 + 19 0 + 20 0 + 21 32 + 22 0 + 23 0 + 24 0 + 25 0 + 26 0 + 27 8 + 28 0 + 29 0 + 30 0 + 31 0 + 32 0 + 33 2 + 34 0 + 35 0 + 36 0 + 37 0 + 38 0 + 39 128 + 40 0 + 41 0 + 42 0 + 43 0 + 44 0 + 45 32 + 46 0 + 47 0 + 48 0 + 49 0 + 50 0 + 51 8 + 52 0 + 53 0 + 54 0 + 55 0 + 56 0 + 57 2 + 58 0 + 59 0 + 60 0 + 61 0 + 62 0 + 63 128 + 64 0 + 65 0 + 66 0 + +test clearbits +be: 0 -1 0000000000000000000000000000000000000000000000000000000000000000000 +is: 0 -1 0000000000000000000000000000000000000000000000000000000000000000000 + +test bit_nset and bit_nclear +be: 0 1 0111111111111111111111111111111111111111111111111111111111111111110 +is: 0 1 0111111111111111111111111111111111111111111111111111111111111111110 +be: 0 1 0100000000000000000000000000000000000000000000000000000000000000010 +is: 0 1 0100000000000000000000000000000000000000000000000000000000000000010 +be: 0 -1 0000000000000000000000000000000000000000000000000000000000000000000 +is: 0 -1 0000000000000000000000000000000000000000000000000000000000000000000 +be: 66 0 1111111111111111111111111111111111111111111111111111111111111111110 +is: 66 0 1111111111111111111111111111111111111111111111111111111111111111110 +be: 0 -1 0000000000000000000000000000000000000000000000000000000000000000000 +is: 0 -1 0000000000000000000000000000000000000000000000000000000000000000000 + +first 1 bit should move right 1 position each line + 0 -1 0 1111111111111111111111111111111111111111111111111111111111111111111 + 1 0 1 0111111111111111111111111111111111111111111111111111111111111111111 + 2 0 2 0011111111111111111111111111111111111111111111111111111111111111111 + 3 0 3 0001111111111111111111111111111111111111111111111111111111111111111 + 4 0 4 0000111111111111111111111111111111111111111111111111111111111111111 + 5 0 5 0000011111111111111111111111111111111111111111111111111111111111111 + 6 0 6 0000001111111111111111111111111111111111111111111111111111111111111 + 7 0 7 0000000111111111111111111111111111111111111111111111111111111111111 + 8 0 8 0000000011111111111111111111111111111111111111111111111111111111111 + 9 0 9 0000000001111111111111111111111111111111111111111111111111111111111 + 10 0 10 0000000000111111111111111111111111111111111111111111111111111111111 + 11 0 11 0000000000011111111111111111111111111111111111111111111111111111111 + 12 0 12 0000000000001111111111111111111111111111111111111111111111111111111 + 13 0 13 0000000000000111111111111111111111111111111111111111111111111111111 + 14 0 14 0000000000000011111111111111111111111111111111111111111111111111111 + 15 0 15 0000000000000001111111111111111111111111111111111111111111111111111 + 16 0 16 0000000000000000111111111111111111111111111111111111111111111111111 + 17 0 17 0000000000000000011111111111111111111111111111111111111111111111111 + 18 0 18 0000000000000000001111111111111111111111111111111111111111111111111 + 19 0 19 0000000000000000000111111111111111111111111111111111111111111111111 + 20 0 20 0000000000000000000011111111111111111111111111111111111111111111111 + 21 0 21 0000000000000000000001111111111111111111111111111111111111111111111 + 22 0 22 0000000000000000000000111111111111111111111111111111111111111111111 + 23 0 23 0000000000000000000000011111111111111111111111111111111111111111111 + 24 0 24 0000000000000000000000001111111111111111111111111111111111111111111 + 25 0 25 0000000000000000000000000111111111111111111111111111111111111111111 + 26 0 26 0000000000000000000000000011111111111111111111111111111111111111111 + 27 0 27 0000000000000000000000000001111111111111111111111111111111111111111 + 28 0 28 0000000000000000000000000000111111111111111111111111111111111111111 + 29 0 29 0000000000000000000000000000011111111111111111111111111111111111111 + 30 0 30 0000000000000000000000000000001111111111111111111111111111111111111 + 31 0 31 0000000000000000000000000000000111111111111111111111111111111111111 + 32 0 32 0000000000000000000000000000000011111111111111111111111111111111111 + 33 0 33 0000000000000000000000000000000001111111111111111111111111111111111 + 34 0 34 0000000000000000000000000000000000111111111111111111111111111111111 + 35 0 35 0000000000000000000000000000000000011111111111111111111111111111111 + 36 0 36 0000000000000000000000000000000000001111111111111111111111111111111 + 37 0 37 0000000000000000000000000000000000000111111111111111111111111111111 + 38 0 38 0000000000000000000000000000000000000011111111111111111111111111111 + 39 0 39 0000000000000000000000000000000000000001111111111111111111111111111 + 40 0 40 0000000000000000000000000000000000000000111111111111111111111111111 + 41 0 41 0000000000000000000000000000000000000000011111111111111111111111111 + 42 0 42 0000000000000000000000000000000000000000001111111111111111111111111 + 43 0 43 0000000000000000000000000000000000000000000111111111111111111111111 + 44 0 44 0000000000000000000000000000000000000000000011111111111111111111111 + 45 0 45 0000000000000000000000000000000000000000000001111111111111111111111 + 46 0 46 0000000000000000000000000000000000000000000000111111111111111111111 + 47 0 47 0000000000000000000000000000000000000000000000011111111111111111111 + 48 0 48 0000000000000000000000000000000000000000000000001111111111111111111 + 49 0 49 0000000000000000000000000000000000000000000000000111111111111111111 + 50 0 50 0000000000000000000000000000000000000000000000000011111111111111111 + 51 0 51 0000000000000000000000000000000000000000000000000001111111111111111 + 52 0 52 0000000000000000000000000000000000000000000000000000111111111111111 + 53 0 53 0000000000000000000000000000000000000000000000000000011111111111111 + 54 0 54 0000000000000000000000000000000000000000000000000000001111111111111 + 55 0 55 0000000000000000000000000000000000000000000000000000000111111111111 + 56 0 56 0000000000000000000000000000000000000000000000000000000011111111111 + 57 0 57 0000000000000000000000000000000000000000000000000000000001111111111 + 58 0 58 0000000000000000000000000000000000000000000000000000000000111111111 + 59 0 59 0000000000000000000000000000000000000000000000000000000000011111111 + 60 0 60 0000000000000000000000000000000000000000000000000000000000001111111 + 61 0 61 0000000000000000000000000000000000000000000000000000000000000111111 + 62 0 62 0000000000000000000000000000000000000000000000000000000000000011111 + 63 0 63 0000000000000000000000000000000000000000000000000000000000000001111 + 64 0 64 0000000000000000000000000000000000000000000000000000000000000000111 + 65 0 65 0000000000000000000000000000000000000000000000000000000000000000011 + 66 0 66 0000000000000000000000000000000000000000000000000000000000000000001 + +first 0 bit should move right 1 position each line + 0 0 -1 0000000000000000000000000000000000000000000000000000000000000000000 + 1 1 0 1000000000000000000000000000000000000000000000000000000000000000000 + 2 2 0 1100000000000000000000000000000000000000000000000000000000000000000 + 3 3 0 1110000000000000000000000000000000000000000000000000000000000000000 + 4 4 0 1111000000000000000000000000000000000000000000000000000000000000000 + 5 5 0 1111100000000000000000000000000000000000000000000000000000000000000 + 6 6 0 1111110000000000000000000000000000000000000000000000000000000000000 + 7 7 0 1111111000000000000000000000000000000000000000000000000000000000000 + 8 8 0 1111111100000000000000000000000000000000000000000000000000000000000 + 9 9 0 1111111110000000000000000000000000000000000000000000000000000000000 + 10 10 0 1111111111000000000000000000000000000000000000000000000000000000000 + 11 11 0 1111111111100000000000000000000000000000000000000000000000000000000 + 12 12 0 1111111111110000000000000000000000000000000000000000000000000000000 + 13 13 0 1111111111111000000000000000000000000000000000000000000000000000000 + 14 14 0 1111111111111100000000000000000000000000000000000000000000000000000 + 15 15 0 1111111111111110000000000000000000000000000000000000000000000000000 + 16 16 0 1111111111111111000000000000000000000000000000000000000000000000000 + 17 17 0 1111111111111111100000000000000000000000000000000000000000000000000 + 18 18 0 1111111111111111110000000000000000000000000000000000000000000000000 + 19 19 0 1111111111111111111000000000000000000000000000000000000000000000000 + 20 20 0 1111111111111111111100000000000000000000000000000000000000000000000 + 21 21 0 1111111111111111111110000000000000000000000000000000000000000000000 + 22 22 0 1111111111111111111111000000000000000000000000000000000000000000000 + 23 23 0 1111111111111111111111100000000000000000000000000000000000000000000 + 24 24 0 1111111111111111111111110000000000000000000000000000000000000000000 + 25 25 0 1111111111111111111111111000000000000000000000000000000000000000000 + 26 26 0 1111111111111111111111111100000000000000000000000000000000000000000 + 27 27 0 1111111111111111111111111110000000000000000000000000000000000000000 + 28 28 0 1111111111111111111111111111000000000000000000000000000000000000000 + 29 29 0 1111111111111111111111111111100000000000000000000000000000000000000 + 30 30 0 1111111111111111111111111111110000000000000000000000000000000000000 + 31 31 0 1111111111111111111111111111111000000000000000000000000000000000000 + 32 32 0 1111111111111111111111111111111100000000000000000000000000000000000 + 33 33 0 1111111111111111111111111111111110000000000000000000000000000000000 + 34 34 0 1111111111111111111111111111111111000000000000000000000000000000000 + 35 35 0 1111111111111111111111111111111111100000000000000000000000000000000 + 36 36 0 1111111111111111111111111111111111110000000000000000000000000000000 + 37 37 0 1111111111111111111111111111111111111000000000000000000000000000000 + 38 38 0 1111111111111111111111111111111111111100000000000000000000000000000 + 39 39 0 1111111111111111111111111111111111111110000000000000000000000000000 + 40 40 0 1111111111111111111111111111111111111111000000000000000000000000000 + 41 41 0 1111111111111111111111111111111111111111100000000000000000000000000 + 42 42 0 1111111111111111111111111111111111111111110000000000000000000000000 + 43 43 0 1111111111111111111111111111111111111111111000000000000000000000000 + 44 44 0 1111111111111111111111111111111111111111111100000000000000000000000 + 45 45 0 1111111111111111111111111111111111111111111110000000000000000000000 + 46 46 0 1111111111111111111111111111111111111111111111000000000000000000000 + 47 47 0 1111111111111111111111111111111111111111111111100000000000000000000 + 48 48 0 1111111111111111111111111111111111111111111111110000000000000000000 + 49 49 0 1111111111111111111111111111111111111111111111111000000000000000000 + 50 50 0 1111111111111111111111111111111111111111111111111100000000000000000 + 51 51 0 1111111111111111111111111111111111111111111111111110000000000000000 + 52 52 0 1111111111111111111111111111111111111111111111111111000000000000000 + 53 53 0 1111111111111111111111111111111111111111111111111111100000000000000 + 54 54 0 1111111111111111111111111111111111111111111111111111110000000000000 + 55 55 0 1111111111111111111111111111111111111111111111111111111000000000000 + 56 56 0 1111111111111111111111111111111111111111111111111111111100000000000 + 57 57 0 1111111111111111111111111111111111111111111111111111111110000000000 + 58 58 0 1111111111111111111111111111111111111111111111111111111111000000000 + 59 59 0 1111111111111111111111111111111111111111111111111111111111100000000 + 60 60 0 1111111111111111111111111111111111111111111111111111111111110000000 + 61 61 0 1111111111111111111111111111111111111111111111111111111111111000000 + 62 62 0 1111111111111111111111111111111111111111111111111111111111111100000 + 63 63 0 1111111111111111111111111111111111111111111111111111111111111110000 + 64 64 0 1111111111111111111111111111111111111111111111111111111111111111000 + 65 65 0 1111111111111111111111111111111111111111111111111111111111111111100 + 66 66 0 1111111111111111111111111111111111111111111111111111111111111111110 + +first 0 bit should move left 1 position each line + 0 -1 0 1111111111111111111111111111111111111111111111111111111111111111111 + 1 66 0 1111111111111111111111111111111111111111111111111111111111111111110 + 2 65 0 1111111111111111111111111111111111111111111111111111111111111111100 + 3 64 0 1111111111111111111111111111111111111111111111111111111111111111000 + 4 63 0 1111111111111111111111111111111111111111111111111111111111111110000 + 5 62 0 1111111111111111111111111111111111111111111111111111111111111100000 + 6 61 0 1111111111111111111111111111111111111111111111111111111111111000000 + 7 60 0 1111111111111111111111111111111111111111111111111111111111110000000 + 8 59 0 1111111111111111111111111111111111111111111111111111111111100000000 + 9 58 0 1111111111111111111111111111111111111111111111111111111111000000000 + 10 57 0 1111111111111111111111111111111111111111111111111111111110000000000 + 11 56 0 1111111111111111111111111111111111111111111111111111111100000000000 + 12 55 0 1111111111111111111111111111111111111111111111111111111000000000000 + 13 54 0 1111111111111111111111111111111111111111111111111111110000000000000 + 14 53 0 1111111111111111111111111111111111111111111111111111100000000000000 + 15 52 0 1111111111111111111111111111111111111111111111111111000000000000000 + 16 51 0 1111111111111111111111111111111111111111111111111110000000000000000 + 17 50 0 1111111111111111111111111111111111111111111111111100000000000000000 + 18 49 0 1111111111111111111111111111111111111111111111111000000000000000000 + 19 48 0 1111111111111111111111111111111111111111111111110000000000000000000 + 20 47 0 1111111111111111111111111111111111111111111111100000000000000000000 + 21 46 0 1111111111111111111111111111111111111111111111000000000000000000000 + 22 45 0 1111111111111111111111111111111111111111111110000000000000000000000 + 23 44 0 1111111111111111111111111111111111111111111100000000000000000000000 + 24 43 0 1111111111111111111111111111111111111111111000000000000000000000000 + 25 42 0 1111111111111111111111111111111111111111110000000000000000000000000 + 26 41 0 1111111111111111111111111111111111111111100000000000000000000000000 + 27 40 0 1111111111111111111111111111111111111111000000000000000000000000000 + 28 39 0 1111111111111111111111111111111111111110000000000000000000000000000 + 29 38 0 1111111111111111111111111111111111111100000000000000000000000000000 + 30 37 0 1111111111111111111111111111111111111000000000000000000000000000000 + 31 36 0 1111111111111111111111111111111111110000000000000000000000000000000 + 32 35 0 1111111111111111111111111111111111100000000000000000000000000000000 + 33 34 0 1111111111111111111111111111111111000000000000000000000000000000000 + 34 33 0 1111111111111111111111111111111110000000000000000000000000000000000 + 35 32 0 1111111111111111111111111111111100000000000000000000000000000000000 + 36 31 0 1111111111111111111111111111111000000000000000000000000000000000000 + 37 30 0 1111111111111111111111111111110000000000000000000000000000000000000 + 38 29 0 1111111111111111111111111111100000000000000000000000000000000000000 + 39 28 0 1111111111111111111111111111000000000000000000000000000000000000000 + 40 27 0 1111111111111111111111111110000000000000000000000000000000000000000 + 41 26 0 1111111111111111111111111100000000000000000000000000000000000000000 + 42 25 0 1111111111111111111111111000000000000000000000000000000000000000000 + 43 24 0 1111111111111111111111110000000000000000000000000000000000000000000 + 44 23 0 1111111111111111111111100000000000000000000000000000000000000000000 + 45 22 0 1111111111111111111111000000000000000000000000000000000000000000000 + 46 21 0 1111111111111111111110000000000000000000000000000000000000000000000 + 47 20 0 1111111111111111111100000000000000000000000000000000000000000000000 + 48 19 0 1111111111111111111000000000000000000000000000000000000000000000000 + 49 18 0 1111111111111111110000000000000000000000000000000000000000000000000 + 50 17 0 1111111111111111100000000000000000000000000000000000000000000000000 + 51 16 0 1111111111111111000000000000000000000000000000000000000000000000000 + 52 15 0 1111111111111110000000000000000000000000000000000000000000000000000 + 53 14 0 1111111111111100000000000000000000000000000000000000000000000000000 + 54 13 0 1111111111111000000000000000000000000000000000000000000000000000000 + 55 12 0 1111111111110000000000000000000000000000000000000000000000000000000 + 56 11 0 1111111111100000000000000000000000000000000000000000000000000000000 + 57 10 0 1111111111000000000000000000000000000000000000000000000000000000000 + 58 9 0 1111111110000000000000000000000000000000000000000000000000000000000 + 59 8 0 1111111100000000000000000000000000000000000000000000000000000000000 + 60 7 0 1111111000000000000000000000000000000000000000000000000000000000000 + 61 6 0 1111110000000000000000000000000000000000000000000000000000000000000 + 62 5 0 1111100000000000000000000000000000000000000000000000000000000000000 + 63 4 0 1111000000000000000000000000000000000000000000000000000000000000000 + 64 3 0 1110000000000000000000000000000000000000000000000000000000000000000 + 65 2 0 1100000000000000000000000000000000000000000000000000000000000000000 + 66 1 0 1000000000000000000000000000000000000000000000000000000000000000000 + +first 1 bit should move left 1 position each line + 0 0 -1 0000000000000000000000000000000000000000000000000000000000000000000 + 1 0 66 0000000000000000000000000000000000000000000000000000000000000000001 + 2 0 65 0000000000000000000000000000000000000000000000000000000000000000011 + 3 0 64 0000000000000000000000000000000000000000000000000000000000000000111 + 4 0 63 0000000000000000000000000000000000000000000000000000000000000001111 + 5 0 62 0000000000000000000000000000000000000000000000000000000000000011111 + 6 0 61 0000000000000000000000000000000000000000000000000000000000000111111 + 7 0 60 0000000000000000000000000000000000000000000000000000000000001111111 + 8 0 59 0000000000000000000000000000000000000000000000000000000000011111111 + 9 0 58 0000000000000000000000000000000000000000000000000000000000111111111 + 10 0 57 0000000000000000000000000000000000000000000000000000000001111111111 + 11 0 56 0000000000000000000000000000000000000000000000000000000011111111111 + 12 0 55 0000000000000000000000000000000000000000000000000000000111111111111 + 13 0 54 0000000000000000000000000000000000000000000000000000001111111111111 + 14 0 53 0000000000000000000000000000000000000000000000000000011111111111111 + 15 0 52 0000000000000000000000000000000000000000000000000000111111111111111 + 16 0 51 0000000000000000000000000000000000000000000000000001111111111111111 + 17 0 50 0000000000000000000000000000000000000000000000000011111111111111111 + 18 0 49 0000000000000000000000000000000000000000000000000111111111111111111 + 19 0 48 0000000000000000000000000000000000000000000000001111111111111111111 + 20 0 47 0000000000000000000000000000000000000000000000011111111111111111111 + 21 0 46 0000000000000000000000000000000000000000000000111111111111111111111 + 22 0 45 0000000000000000000000000000000000000000000001111111111111111111111 + 23 0 44 0000000000000000000000000000000000000000000011111111111111111111111 + 24 0 43 0000000000000000000000000000000000000000000111111111111111111111111 + 25 0 42 0000000000000000000000000000000000000000001111111111111111111111111 + 26 0 41 0000000000000000000000000000000000000000011111111111111111111111111 + 27 0 40 0000000000000000000000000000000000000000111111111111111111111111111 + 28 0 39 0000000000000000000000000000000000000001111111111111111111111111111 + 29 0 38 0000000000000000000000000000000000000011111111111111111111111111111 + 30 0 37 0000000000000000000000000000000000000111111111111111111111111111111 + 31 0 36 0000000000000000000000000000000000001111111111111111111111111111111 + 32 0 35 0000000000000000000000000000000000011111111111111111111111111111111 + 33 0 34 0000000000000000000000000000000000111111111111111111111111111111111 + 34 0 33 0000000000000000000000000000000001111111111111111111111111111111111 + 35 0 32 0000000000000000000000000000000011111111111111111111111111111111111 + 36 0 31 0000000000000000000000000000000111111111111111111111111111111111111 + 37 0 30 0000000000000000000000000000001111111111111111111111111111111111111 + 38 0 29 0000000000000000000000000000011111111111111111111111111111111111111 + 39 0 28 0000000000000000000000000000111111111111111111111111111111111111111 + 40 0 27 0000000000000000000000000001111111111111111111111111111111111111111 + 41 0 26 0000000000000000000000000011111111111111111111111111111111111111111 + 42 0 25 0000000000000000000000000111111111111111111111111111111111111111111 + 43 0 24 0000000000000000000000001111111111111111111111111111111111111111111 + 44 0 23 0000000000000000000000011111111111111111111111111111111111111111111 + 45 0 22 0000000000000000000000111111111111111111111111111111111111111111111 + 46 0 21 0000000000000000000001111111111111111111111111111111111111111111111 + 47 0 20 0000000000000000000011111111111111111111111111111111111111111111111 + 48 0 19 0000000000000000000111111111111111111111111111111111111111111111111 + 49 0 18 0000000000000000001111111111111111111111111111111111111111111111111 + 50 0 17 0000000000000000011111111111111111111111111111111111111111111111111 + 51 0 16 0000000000000000111111111111111111111111111111111111111111111111111 + 52 0 15 0000000000000001111111111111111111111111111111111111111111111111111 + 53 0 14 0000000000000011111111111111111111111111111111111111111111111111111 + 54 0 13 0000000000000111111111111111111111111111111111111111111111111111111 + 55 0 12 0000000000001111111111111111111111111111111111111111111111111111111 + 56 0 11 0000000000011111111111111111111111111111111111111111111111111111111 + 57 0 10 0000000000111111111111111111111111111111111111111111111111111111111 + 58 0 9 0000000001111111111111111111111111111111111111111111111111111111111 + 59 0 8 0000000011111111111111111111111111111111111111111111111111111111111 + 60 0 7 0000000111111111111111111111111111111111111111111111111111111111111 + 61 0 6 0000001111111111111111111111111111111111111111111111111111111111111 + 62 0 5 0000011111111111111111111111111111111111111111111111111111111111111 + 63 0 4 0000111111111111111111111111111111111111111111111111111111111111111 + 64 0 3 0001111111111111111111111111111111111111111111111111111111111111111 + 65 0 2 0011111111111111111111111111111111111111111111111111111111111111111 + 66 0 1 0111111111111111111111111111111111111111111111111111111111111111111 + +0 bit should move right 1 position each line + 0 0 1 0111111111111111111111111111111111111111111111111111111111111111111 + 1 1 0 1011111111111111111111111111111111111111111111111111111111111111111 + 2 2 0 1101111111111111111111111111111111111111111111111111111111111111111 + 3 3 0 1110111111111111111111111111111111111111111111111111111111111111111 + 4 4 0 1111011111111111111111111111111111111111111111111111111111111111111 + 5 5 0 1111101111111111111111111111111111111111111111111111111111111111111 + 6 6 0 1111110111111111111111111111111111111111111111111111111111111111111 + 7 7 0 1111111011111111111111111111111111111111111111111111111111111111111 + 8 8 0 1111111101111111111111111111111111111111111111111111111111111111111 + 9 9 0 1111111110111111111111111111111111111111111111111111111111111111111 + 10 10 0 1111111111011111111111111111111111111111111111111111111111111111111 + 11 11 0 1111111111101111111111111111111111111111111111111111111111111111111 + 12 12 0 1111111111110111111111111111111111111111111111111111111111111111111 + 13 13 0 1111111111111011111111111111111111111111111111111111111111111111111 + 14 14 0 1111111111111101111111111111111111111111111111111111111111111111111 + 15 15 0 1111111111111110111111111111111111111111111111111111111111111111111 + 16 16 0 1111111111111111011111111111111111111111111111111111111111111111111 + 17 17 0 1111111111111111101111111111111111111111111111111111111111111111111 + 18 18 0 1111111111111111110111111111111111111111111111111111111111111111111 + 19 19 0 1111111111111111111011111111111111111111111111111111111111111111111 + 20 20 0 1111111111111111111101111111111111111111111111111111111111111111111 + 21 21 0 1111111111111111111110111111111111111111111111111111111111111111111 + 22 22 0 1111111111111111111111011111111111111111111111111111111111111111111 + 23 23 0 1111111111111111111111101111111111111111111111111111111111111111111 + 24 24 0 1111111111111111111111110111111111111111111111111111111111111111111 + 25 25 0 1111111111111111111111111011111111111111111111111111111111111111111 + 26 26 0 1111111111111111111111111101111111111111111111111111111111111111111 + 27 27 0 1111111111111111111111111110111111111111111111111111111111111111111 + 28 28 0 1111111111111111111111111111011111111111111111111111111111111111111 + 29 29 0 1111111111111111111111111111101111111111111111111111111111111111111 + 30 30 0 1111111111111111111111111111110111111111111111111111111111111111111 + 31 31 0 1111111111111111111111111111111011111111111111111111111111111111111 + 32 32 0 1111111111111111111111111111111101111111111111111111111111111111111 + 33 33 0 1111111111111111111111111111111110111111111111111111111111111111111 + 34 34 0 1111111111111111111111111111111111011111111111111111111111111111111 + 35 35 0 1111111111111111111111111111111111101111111111111111111111111111111 + 36 36 0 1111111111111111111111111111111111110111111111111111111111111111111 + 37 37 0 1111111111111111111111111111111111111011111111111111111111111111111 + 38 38 0 1111111111111111111111111111111111111101111111111111111111111111111 + 39 39 0 1111111111111111111111111111111111111110111111111111111111111111111 + 40 40 0 1111111111111111111111111111111111111111011111111111111111111111111 + 41 41 0 1111111111111111111111111111111111111111101111111111111111111111111 + 42 42 0 1111111111111111111111111111111111111111110111111111111111111111111 + 43 43 0 1111111111111111111111111111111111111111111011111111111111111111111 + 44 44 0 1111111111111111111111111111111111111111111101111111111111111111111 + 45 45 0 1111111111111111111111111111111111111111111110111111111111111111111 + 46 46 0 1111111111111111111111111111111111111111111111011111111111111111111 + 47 47 0 1111111111111111111111111111111111111111111111101111111111111111111 + 48 48 0 1111111111111111111111111111111111111111111111110111111111111111111 + 49 49 0 1111111111111111111111111111111111111111111111111011111111111111111 + 50 50 0 1111111111111111111111111111111111111111111111111101111111111111111 + 51 51 0 1111111111111111111111111111111111111111111111111110111111111111111 + 52 52 0 1111111111111111111111111111111111111111111111111111011111111111111 + 53 53 0 1111111111111111111111111111111111111111111111111111101111111111111 + 54 54 0 1111111111111111111111111111111111111111111111111111110111111111111 + 55 55 0 1111111111111111111111111111111111111111111111111111111011111111111 + 56 56 0 1111111111111111111111111111111111111111111111111111111101111111111 + 57 57 0 1111111111111111111111111111111111111111111111111111111110111111111 + 58 58 0 1111111111111111111111111111111111111111111111111111111111011111111 + 59 59 0 1111111111111111111111111111111111111111111111111111111111101111111 + 60 60 0 1111111111111111111111111111111111111111111111111111111111110111111 + 61 61 0 1111111111111111111111111111111111111111111111111111111111111011111 + 62 62 0 1111111111111111111111111111111111111111111111111111111111111101111 + 63 63 0 1111111111111111111111111111111111111111111111111111111111111110111 + 64 64 0 1111111111111111111111111111111111111111111111111111111111111111011 + 65 65 0 1111111111111111111111111111111111111111111111111111111111111111101 + 66 66 0 1111111111111111111111111111111111111111111111111111111111111111110 + +1 bit should move right 1 position each line + 0 1 0 1000000000000000000000000000000000000000000000000000000000000000000 + 1 0 1 0100000000000000000000000000000000000000000000000000000000000000000 + 2 0 2 0010000000000000000000000000000000000000000000000000000000000000000 + 3 0 3 0001000000000000000000000000000000000000000000000000000000000000000 + 4 0 4 0000100000000000000000000000000000000000000000000000000000000000000 + 5 0 5 0000010000000000000000000000000000000000000000000000000000000000000 + 6 0 6 0000001000000000000000000000000000000000000000000000000000000000000 + 7 0 7 0000000100000000000000000000000000000000000000000000000000000000000 + 8 0 8 0000000010000000000000000000000000000000000000000000000000000000000 + 9 0 9 0000000001000000000000000000000000000000000000000000000000000000000 + 10 0 10 0000000000100000000000000000000000000000000000000000000000000000000 + 11 0 11 0000000000010000000000000000000000000000000000000000000000000000000 + 12 0 12 0000000000001000000000000000000000000000000000000000000000000000000 + 13 0 13 0000000000000100000000000000000000000000000000000000000000000000000 + 14 0 14 0000000000000010000000000000000000000000000000000000000000000000000 + 15 0 15 0000000000000001000000000000000000000000000000000000000000000000000 + 16 0 16 0000000000000000100000000000000000000000000000000000000000000000000 + 17 0 17 0000000000000000010000000000000000000000000000000000000000000000000 + 18 0 18 0000000000000000001000000000000000000000000000000000000000000000000 + 19 0 19 0000000000000000000100000000000000000000000000000000000000000000000 + 20 0 20 0000000000000000000010000000000000000000000000000000000000000000000 + 21 0 21 0000000000000000000001000000000000000000000000000000000000000000000 + 22 0 22 0000000000000000000000100000000000000000000000000000000000000000000 + 23 0 23 0000000000000000000000010000000000000000000000000000000000000000000 + 24 0 24 0000000000000000000000001000000000000000000000000000000000000000000 + 25 0 25 0000000000000000000000000100000000000000000000000000000000000000000 + 26 0 26 0000000000000000000000000010000000000000000000000000000000000000000 + 27 0 27 0000000000000000000000000001000000000000000000000000000000000000000 + 28 0 28 0000000000000000000000000000100000000000000000000000000000000000000 + 29 0 29 0000000000000000000000000000010000000000000000000000000000000000000 + 30 0 30 0000000000000000000000000000001000000000000000000000000000000000000 + 31 0 31 0000000000000000000000000000000100000000000000000000000000000000000 + 32 0 32 0000000000000000000000000000000010000000000000000000000000000000000 + 33 0 33 0000000000000000000000000000000001000000000000000000000000000000000 + 34 0 34 0000000000000000000000000000000000100000000000000000000000000000000 + 35 0 35 0000000000000000000000000000000000010000000000000000000000000000000 + 36 0 36 0000000000000000000000000000000000001000000000000000000000000000000 + 37 0 37 0000000000000000000000000000000000000100000000000000000000000000000 + 38 0 38 0000000000000000000000000000000000000010000000000000000000000000000 + 39 0 39 0000000000000000000000000000000000000001000000000000000000000000000 + 40 0 40 0000000000000000000000000000000000000000100000000000000000000000000 + 41 0 41 0000000000000000000000000000000000000000010000000000000000000000000 + 42 0 42 0000000000000000000000000000000000000000001000000000000000000000000 + 43 0 43 0000000000000000000000000000000000000000000100000000000000000000000 + 44 0 44 0000000000000000000000000000000000000000000010000000000000000000000 + 45 0 45 0000000000000000000000000000000000000000000001000000000000000000000 + 46 0 46 0000000000000000000000000000000000000000000000100000000000000000000 + 47 0 47 0000000000000000000000000000000000000000000000010000000000000000000 + 48 0 48 0000000000000000000000000000000000000000000000001000000000000000000 + 49 0 49 0000000000000000000000000000000000000000000000000100000000000000000 + 50 0 50 0000000000000000000000000000000000000000000000000010000000000000000 + 51 0 51 0000000000000000000000000000000000000000000000000001000000000000000 + 52 0 52 0000000000000000000000000000000000000000000000000000100000000000000 + 53 0 53 0000000000000000000000000000000000000000000000000000010000000000000 + 54 0 54 0000000000000000000000000000000000000000000000000000001000000000000 + 55 0 55 0000000000000000000000000000000000000000000000000000000100000000000 + 56 0 56 0000000000000000000000000000000000000000000000000000000010000000000 + 57 0 57 0000000000000000000000000000000000000000000000000000000001000000000 + 58 0 58 0000000000000000000000000000000000000000000000000000000000100000000 + 59 0 59 0000000000000000000000000000000000000000000000000000000000010000000 + 60 0 60 0000000000000000000000000000000000000000000000000000000000001000000 + 61 0 61 0000000000000000000000000000000000000000000000000000000000000100000 + 62 0 62 0000000000000000000000000000000000000000000000000000000000000010000 + 63 0 63 0000000000000000000000000000000000000000000000000000000000000001000 + 64 0 64 0000000000000000000000000000000000000000000000000000000000000000100 + 65 0 65 0000000000000000000000000000000000000000000000000000000000000000010 + 66 0 66 0000000000000000000000000000000000000000000000000000000000000000001 diff --git a/contrib/netbsd-tests/include/d_bitstring_8.out b/contrib/netbsd-tests/include/d_bitstring_8.out new file mode 100644 index 0000000..aba6440 --- /dev/null +++ b/contrib/netbsd-tests/include/d_bitstring_8.out @@ -0,0 +1,111 @@ +Testing with TEST_LENGTH = 8 + +test _bit_byte, _bit_mask, and bitstr_size + i _bit_byte(i) _bit_mask(i) bitstr_size(i) + 0 0 1 0 + 1 0 2 1 + 2 0 4 1 + 3 0 8 1 + 4 0 16 1 + 5 0 32 1 + 6 0 64 1 + 7 0 128 1 + +test bit_alloc, clearbits, bit_ffc, bit_ffs +be: 0 -1 00000000 +is: 0 -1 00000000 + +test bit_set +be: 1 0 10010010 +is: 1 0 10010010 + +test bit_clear +be: 0 3 00010000 +is: 0 3 00010000 + +test bit_test using previous bitstring + i bit_test(i) + 0 0 + 1 0 + 2 0 + 3 8 + 4 0 + 5 0 + 6 0 + 7 0 + +test clearbits +be: 0 -1 00000000 +is: 0 -1 00000000 + +test bit_nset and bit_nclear +be: 0 1 01111110 +is: 0 1 01111110 +be: 0 1 01000010 +is: 0 1 01000010 +be: 0 -1 00000000 +is: 0 -1 00000000 +be: 7 0 11111110 +is: 7 0 11111110 +be: 0 -1 00000000 +is: 0 -1 00000000 + +first 1 bit should move right 1 position each line + 0 -1 0 11111111 + 1 0 1 01111111 + 2 0 2 00111111 + 3 0 3 00011111 + 4 0 4 00001111 + 5 0 5 00000111 + 6 0 6 00000011 + 7 0 7 00000001 + +first 0 bit should move right 1 position each line + 0 0 -1 00000000 + 1 1 0 10000000 + 2 2 0 11000000 + 3 3 0 11100000 + 4 4 0 11110000 + 5 5 0 11111000 + 6 6 0 11111100 + 7 7 0 11111110 + +first 0 bit should move left 1 position each line + 0 -1 0 11111111 + 1 7 0 11111110 + 2 6 0 11111100 + 3 5 0 11111000 + 4 4 0 11110000 + 5 3 0 11100000 + 6 2 0 11000000 + 7 1 0 10000000 + +first 1 bit should move left 1 position each line + 0 0 -1 00000000 + 1 0 7 00000001 + 2 0 6 00000011 + 3 0 5 00000111 + 4 0 4 00001111 + 5 0 3 00011111 + 6 0 2 00111111 + 7 0 1 01111111 + +0 bit should move right 1 position each line + 0 0 1 01111111 + 1 1 0 10111111 + 2 2 0 11011111 + 3 3 0 11101111 + 4 4 0 11110111 + 5 5 0 11111011 + 6 6 0 11111101 + 7 7 0 11111110 + +1 bit should move right 1 position each line + 0 1 0 10000000 + 1 0 1 01000000 + 2 0 2 00100000 + 3 0 3 00010000 + 4 0 4 00001000 + 5 0 5 00000100 + 6 0 6 00000010 + 7 0 7 00000001 diff --git a/contrib/netbsd-tests/include/machine/t_bswap.c b/contrib/netbsd-tests/include/machine/t_bswap.c new file mode 100644 index 0000000..a7bb42a --- /dev/null +++ b/contrib/netbsd-tests/include/machine/t_bswap.c @@ -0,0 +1,178 @@ +/* $NetBSD: t_bswap.c,v 1.1 2011/05/05 05:39:11 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_bswap.c,v 1.1 2011/05/05 05:39:11 jruoho Exp $"); + +#include +#include + +#include + +static uint16_t x16; +static uint32_t x32; +static uint64_t x64; + +static uint16_t unconst16(uint16_t); +static uint32_t unconst32(uint32_t); +static uint64_t unconst64(uint64_t); + +/* + * Given the use of __builtin_constant_p(3), + * these functions try to avoid gcc(1) from + * treating the arguments as constants. + */ +static uint16_t +unconst16(uint16_t val) +{ + return val + x16; +} + +static uint32_t +unconst32(uint32_t val) +{ + return val + x32; +} + +static uint64_t +unconst64(uint64_t val) +{ + return val + x64; +} + +ATF_TC(bswap16_basic); +ATF_TC_HEAD(bswap16_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of bswap16(3), #1"); +} + +ATF_TC_BODY(bswap16_basic, tc) +{ + ATF_REQUIRE_EQ(bswap16(0x0000), 0x0000); + ATF_REQUIRE_EQ(bswap16(0xff00), 0x00ff); + ATF_REQUIRE_EQ(bswap16(0xffff), 0xffff); + ATF_REQUIRE_EQ(bswap16(0x1234), 0x3412); +} + +ATF_TC(bswap16_unconst); +ATF_TC_HEAD(bswap16_unconst, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of bswap16(3), #2"); +} + +ATF_TC_BODY(bswap16_unconst, tc) +{ + x16 = 0; + + ATF_REQUIRE_EQ(bswap16(unconst16(0x0000)), 0x0000); + ATF_REQUIRE_EQ(bswap16(unconst16(0xff00)), 0x00ff); + ATF_REQUIRE_EQ(bswap16(unconst16(0xffff)), 0xffff); + ATF_REQUIRE_EQ(bswap16(unconst16(0x1234)), 0x3412); +} + +ATF_TC(bswap32_basic); +ATF_TC_HEAD(bswap32_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of bswap32(3), #1"); +} + +ATF_TC_BODY(bswap32_basic, tc) +{ + ATF_REQUIRE_EQ(bswap32(0x00000000), 0x00000000); + ATF_REQUIRE_EQ(bswap32(0xffff0000), 0x0000ffff); + ATF_REQUIRE_EQ(bswap32(0xffffffff), 0xffffffff); + ATF_REQUIRE_EQ(bswap32(0x12345678), 0x78563412); +} + +ATF_TC(bswap32_unconst); +ATF_TC_HEAD(bswap32_unconst, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of bswap32(3), #2"); +} + +ATF_TC_BODY(bswap32_unconst, tc) +{ + x32 = 0; + + ATF_REQUIRE_EQ(bswap32(unconst32(0x00000000)), 0x00000000); + ATF_REQUIRE_EQ(bswap32(unconst32(0xffff0000)), 0x0000ffff); + ATF_REQUIRE_EQ(bswap32(unconst32(0xffffffff)), 0xffffffff); + ATF_REQUIRE_EQ(bswap32(unconst32(0x12345678)), 0x78563412); +} + +ATF_TC(bswap64_basic); +ATF_TC_HEAD(bswap64_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of bswap64(3), #1"); +} + +ATF_TC_BODY(bswap64_basic, tc) +{ + ATF_REQUIRE_EQ(bswap64(0x0000000000000000), 0x0000000000000000); + ATF_REQUIRE_EQ(bswap64(0xffffffff00000000), 0x00000000ffffffff); + ATF_REQUIRE_EQ(bswap64(0xffffffffffffffff), 0xffffffffffffffff); + ATF_REQUIRE_EQ(bswap64(0x123456789abcdeff), 0xffdebc9a78563412); +} + +ATF_TC(bswap64_unconst); +ATF_TC_HEAD(bswap64_unconst, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of bswap64(3), #2"); +} + +ATF_TC_BODY(bswap64_unconst, tc) +{ + x64 = 0; + + ATF_REQUIRE_EQ(bswap64(unconst64(0x0000000000000000)), + 0x0000000000000000); + + ATF_REQUIRE_EQ(bswap64(unconst64(0xffffffff00000000)), + 0x00000000ffffffff); + + ATF_REQUIRE_EQ(bswap64(unconst64(0xffffffffffffffff)), + 0xffffffffffffffff); + + ATF_REQUIRE_EQ(bswap64(unconst64(0x123456789abcdeff)), + 0xffdebc9a78563412); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, bswap16_basic); + ATF_TP_ADD_TC(tp, bswap16_unconst); + ATF_TP_ADD_TC(tp, bswap32_basic); + ATF_TP_ADD_TC(tp, bswap32_unconst); + ATF_TP_ADD_TC(tp, bswap64_basic); + ATF_TP_ADD_TC(tp, bswap64_unconst); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/sys/t_bitops.c b/contrib/netbsd-tests/include/sys/t_bitops.c new file mode 100644 index 0000000..6bdeb2b --- /dev/null +++ b/contrib/netbsd-tests/include/sys/t_bitops.c @@ -0,0 +1,364 @@ +/* $NetBSD: t_bitops.c,v 1.19 2015/03/21 05:50:19 isaki Exp $ */ + +/*- + * Copyright (c) 2011, 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas and Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_bitops.c,v 1.19 2015/03/21 05:50:19 isaki Exp $"); + +#include + +#include +#include + +#include +#include +#include +#include + +static const struct { + uint32_t val; + int ffs; + int fls; +} bits[] = { + + { 0x00, 0, 0 }, { 0x01, 1, 1 }, { 0x02, 2, 2 }, { 0x03, 1, 2 }, + { 0x04, 3, 3 }, { 0x05, 1, 3 }, { 0x06, 2, 3 }, { 0x07, 1, 3 }, + { 0x08, 4, 4 }, { 0x09, 1, 4 }, { 0x0A, 2, 4 }, { 0x0B, 1, 4 }, + { 0x0C, 3, 4 }, { 0x0D, 1, 4 }, { 0x0E, 2, 4 }, { 0x0F, 1, 4 }, + + { 0x10, 5, 5 }, { 0x11, 1, 5 }, { 0x12, 2, 5 }, { 0x13, 1, 5 }, + { 0x14, 3, 5 }, { 0x15, 1, 5 }, { 0x16, 2, 5 }, { 0x17, 1, 5 }, + { 0x18, 4, 5 }, { 0x19, 1, 5 }, { 0x1A, 2, 5 }, { 0x1B, 1, 5 }, + { 0x1C, 3, 5 }, { 0x1D, 1, 5 }, { 0x1E, 2, 5 }, { 0x1F, 1, 5 }, + + { 0xF0, 5, 8 }, { 0xF1, 1, 8 }, { 0xF2, 2, 8 }, { 0xF3, 1, 8 }, + { 0xF4, 3, 8 }, { 0xF5, 1, 8 }, { 0xF6, 2, 8 }, { 0xF7, 1, 8 }, + { 0xF8, 4, 8 }, { 0xF9, 1, 8 }, { 0xFA, 2, 8 }, { 0xFB, 1, 8 }, + { 0xFC, 3, 8 }, { 0xFD, 1, 8 }, { 0xFE, 2, 8 }, { 0xFF, 1, 8 }, + +}; + +ATF_TC(bitmap_basic); +ATF_TC_HEAD(bitmap_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of __BITMAP_*"); +} + +ATF_TC_BODY(bitmap_basic, tc) +{ + __BITMAP_TYPE(, uint32_t, 65536) bm; + __BITMAP_ZERO(&bm); + + ATF_REQUIRE(__BITMAP_SIZE(uint32_t, 65536) == 2048); + + ATF_REQUIRE(__BITMAP_SHIFT(uint32_t) == 5); + + ATF_REQUIRE(__BITMAP_MASK(uint32_t) == 31); + + for (size_t i = 0; i < 65536; i += 2) + __BITMAP_SET(i, &bm); + + for (size_t i = 0; i < 2048; i++) + ATF_REQUIRE(bm._b[i] == 0x55555555); + + for (size_t i = 0; i < 65536; i++) + if (i & 1) + ATF_REQUIRE(!__BITMAP_ISSET(i, &bm)); + else { + ATF_REQUIRE(__BITMAP_ISSET(i, &bm)); + __BITMAP_CLR(i, &bm); + } + + for (size_t i = 0; i < 65536; i += 2) + ATF_REQUIRE(!__BITMAP_ISSET(i, &bm)); +} + +ATF_TC(fast_divide32); +ATF_TC_HEAD(fast_divide32, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fast_divide32(3)"); +} + +ATF_TC_BODY(fast_divide32, tc) +{ + uint32_t a, b, q, r, m; + uint8_t i, s1, s2; + + a = 0xFFFF; + b = 0x000F; + + fast_divide32_prepare(b, &m, &s1, &s2); + + q = fast_divide32(a, b, m, s1, s2); + r = fast_remainder32(a, b, m, s1, s2); + + ATF_REQUIRE(q == 0x1111 && r == 0); + + for (i = 1; i < __arraycount(bits); i++) { + + a = bits[i].val; + b = bits[i].ffs; + + fast_divide32_prepare(b, &m, &s1, &s2); + + q = fast_divide32(a, b, m, s1, s2); + r = fast_remainder32(a, b, m, s1, s2); + + ATF_REQUIRE(q == a / b); + ATF_REQUIRE(r == a % b); + } +} + +ATF_TC(ffsfls); +ATF_TC_HEAD(ffsfls, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ffs32(3)-family for correctness"); +} + +ATF_TC_BODY(ffsfls, tc) +{ + uint8_t i; + + ATF_REQUIRE(ffs32(0) == 0x00); + ATF_REQUIRE(fls32(0) == 0x00); + ATF_REQUIRE(ffs64(0) == 0x00); + ATF_REQUIRE(fls64(0) == 0x00); + + ATF_REQUIRE(ffs32(UINT32_MAX) == 0x01); + ATF_REQUIRE(fls32(UINT32_MAX) == 0x20); + ATF_REQUIRE(ffs64(UINT64_MAX) == 0x01); + ATF_REQUIRE(fls64(UINT64_MAX) == 0x40); + + for (i = 1; i < __arraycount(bits); i++) { + + ATF_REQUIRE(ffs32(bits[i].val) == bits[i].ffs); + ATF_REQUIRE(fls32(bits[i].val) == bits[i].fls); + ATF_REQUIRE(ffs64(bits[i].val) == bits[i].ffs); + ATF_REQUIRE(fls64(bits[i].val) == bits[i].fls); + + ATF_REQUIRE(ffs32(bits[i].val << 1) == bits[i].ffs + 1); + ATF_REQUIRE(fls32(bits[i].val << 1) == bits[i].fls + 1); + ATF_REQUIRE(ffs64(bits[i].val << 1) == bits[i].ffs + 1); + ATF_REQUIRE(fls64(bits[i].val << 1) == bits[i].fls + 1); + + ATF_REQUIRE(ffs32(bits[i].val << 9) == bits[i].ffs + 9); + ATF_REQUIRE(fls32(bits[i].val << 9) == bits[i].fls + 9); + ATF_REQUIRE(ffs64(bits[i].val << 9) == bits[i].ffs + 9); + ATF_REQUIRE(fls64(bits[i].val << 9) == bits[i].fls + 9); + } +} + +ATF_TC(ilog2_32bit); +ATF_TC_HEAD(ilog2_32bit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ilog2(3) for 32bit variable"); +} + +ATF_TC_BODY(ilog2_32bit, tc) +{ + int i; + uint32_t x; + + for (i = 0; i < 32; i++) { + x = 1 << i; + ATF_REQUIRE(ilog2(x) == i); + } +} + +ATF_TC(ilog2_64bit); +ATF_TC_HEAD(ilog2_64bit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ilog2(3) for 64bit variable"); +} + +ATF_TC_BODY(ilog2_64bit, tc) +{ + int i; + uint64_t x; + + for (i = 0; i < 64; i++) { + x = ((uint64_t)1) << i; + ATF_REQUIRE(ilog2(x) == i); + } +} + +ATF_TC(ilog2_const); +ATF_TC_HEAD(ilog2_const, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ilog2(3) for constant"); +} + +ATF_TC_BODY(ilog2_const, tc) +{ + /* + * These inlines test __builtin_constant_p() part of ilog2() + * at compile time, so don't change it to loop. PR lib/49745 + */ + ATF_REQUIRE(ilog2(0x0000000000000001ULL) == 0); + ATF_REQUIRE(ilog2(0x0000000000000002ULL) == 1); + ATF_REQUIRE(ilog2(0x0000000000000004ULL) == 2); + ATF_REQUIRE(ilog2(0x0000000000000008ULL) == 3); + ATF_REQUIRE(ilog2(0x0000000000000010ULL) == 4); + ATF_REQUIRE(ilog2(0x0000000000000020ULL) == 5); + ATF_REQUIRE(ilog2(0x0000000000000040ULL) == 6); + ATF_REQUIRE(ilog2(0x0000000000000080ULL) == 7); + ATF_REQUIRE(ilog2(0x0000000000000100ULL) == 8); + ATF_REQUIRE(ilog2(0x0000000000000200ULL) == 9); + ATF_REQUIRE(ilog2(0x0000000000000400ULL) == 10); + ATF_REQUIRE(ilog2(0x0000000000000800ULL) == 11); + ATF_REQUIRE(ilog2(0x0000000000001000ULL) == 12); + ATF_REQUIRE(ilog2(0x0000000000002000ULL) == 13); + ATF_REQUIRE(ilog2(0x0000000000004000ULL) == 14); + ATF_REQUIRE(ilog2(0x0000000000008000ULL) == 15); + ATF_REQUIRE(ilog2(0x0000000000010000ULL) == 16); + ATF_REQUIRE(ilog2(0x0000000000020000ULL) == 17); + ATF_REQUIRE(ilog2(0x0000000000040000ULL) == 18); + ATF_REQUIRE(ilog2(0x0000000000080000ULL) == 19); + ATF_REQUIRE(ilog2(0x0000000000100000ULL) == 20); + ATF_REQUIRE(ilog2(0x0000000000200000ULL) == 21); + ATF_REQUIRE(ilog2(0x0000000000400000ULL) == 22); + ATF_REQUIRE(ilog2(0x0000000000800000ULL) == 23); + ATF_REQUIRE(ilog2(0x0000000001000000ULL) == 24); + ATF_REQUIRE(ilog2(0x0000000002000000ULL) == 25); + ATF_REQUIRE(ilog2(0x0000000004000000ULL) == 26); + ATF_REQUIRE(ilog2(0x0000000008000000ULL) == 27); + ATF_REQUIRE(ilog2(0x0000000010000000ULL) == 28); + ATF_REQUIRE(ilog2(0x0000000020000000ULL) == 29); + ATF_REQUIRE(ilog2(0x0000000040000000ULL) == 30); + ATF_REQUIRE(ilog2(0x0000000080000000ULL) == 31); + ATF_REQUIRE(ilog2(0x0000000100000000ULL) == 32); + ATF_REQUIRE(ilog2(0x0000000200000000ULL) == 33); + ATF_REQUIRE(ilog2(0x0000000400000000ULL) == 34); + ATF_REQUIRE(ilog2(0x0000000800000000ULL) == 35); + ATF_REQUIRE(ilog2(0x0000001000000000ULL) == 36); + ATF_REQUIRE(ilog2(0x0000002000000000ULL) == 37); + ATF_REQUIRE(ilog2(0x0000004000000000ULL) == 38); + ATF_REQUIRE(ilog2(0x0000008000000000ULL) == 39); + ATF_REQUIRE(ilog2(0x0000010000000000ULL) == 40); + ATF_REQUIRE(ilog2(0x0000020000000000ULL) == 41); + ATF_REQUIRE(ilog2(0x0000040000000000ULL) == 42); + ATF_REQUIRE(ilog2(0x0000080000000000ULL) == 43); + ATF_REQUIRE(ilog2(0x0000100000000000ULL) == 44); + ATF_REQUIRE(ilog2(0x0000200000000000ULL) == 45); + ATF_REQUIRE(ilog2(0x0000400000000000ULL) == 46); + ATF_REQUIRE(ilog2(0x0000800000000000ULL) == 47); + ATF_REQUIRE(ilog2(0x0001000000000000ULL) == 48); + ATF_REQUIRE(ilog2(0x0002000000000000ULL) == 49); + ATF_REQUIRE(ilog2(0x0004000000000000ULL) == 50); + ATF_REQUIRE(ilog2(0x0008000000000000ULL) == 51); + ATF_REQUIRE(ilog2(0x0010000000000000ULL) == 52); + ATF_REQUIRE(ilog2(0x0020000000000000ULL) == 53); + ATF_REQUIRE(ilog2(0x0040000000000000ULL) == 54); + ATF_REQUIRE(ilog2(0x0080000000000000ULL) == 55); + ATF_REQUIRE(ilog2(0x0100000000000000ULL) == 56); + ATF_REQUIRE(ilog2(0x0200000000000000ULL) == 57); + ATF_REQUIRE(ilog2(0x0400000000000000ULL) == 58); + ATF_REQUIRE(ilog2(0x0800000000000000ULL) == 59); + ATF_REQUIRE(ilog2(0x1000000000000000ULL) == 60); + ATF_REQUIRE(ilog2(0x2000000000000000ULL) == 61); + ATF_REQUIRE(ilog2(0x4000000000000000ULL) == 62); + ATF_REQUIRE(ilog2(0x8000000000000000ULL) == 63); + + ATF_REQUIRE(ilog2(0x0000000000000003ULL) == 1); + ATF_REQUIRE(ilog2(0x0000000000000007ULL) == 2); + ATF_REQUIRE(ilog2(0x000000000000000fULL) == 3); + ATF_REQUIRE(ilog2(0x000000000000001fULL) == 4); + ATF_REQUIRE(ilog2(0x000000000000003fULL) == 5); + ATF_REQUIRE(ilog2(0x000000000000007fULL) == 6); + ATF_REQUIRE(ilog2(0x00000000000000ffULL) == 7); + ATF_REQUIRE(ilog2(0x00000000000001ffULL) == 8); + ATF_REQUIRE(ilog2(0x00000000000003ffULL) == 9); + ATF_REQUIRE(ilog2(0x00000000000007ffULL) == 10); + ATF_REQUIRE(ilog2(0x0000000000000fffULL) == 11); + ATF_REQUIRE(ilog2(0x0000000000001fffULL) == 12); + ATF_REQUIRE(ilog2(0x0000000000003fffULL) == 13); + ATF_REQUIRE(ilog2(0x0000000000007fffULL) == 14); + ATF_REQUIRE(ilog2(0x000000000000ffffULL) == 15); + ATF_REQUIRE(ilog2(0x000000000001ffffULL) == 16); + ATF_REQUIRE(ilog2(0x000000000003ffffULL) == 17); + ATF_REQUIRE(ilog2(0x000000000007ffffULL) == 18); + ATF_REQUIRE(ilog2(0x00000000000fffffULL) == 19); + ATF_REQUIRE(ilog2(0x00000000001fffffULL) == 20); + ATF_REQUIRE(ilog2(0x00000000003fffffULL) == 21); + ATF_REQUIRE(ilog2(0x00000000007fffffULL) == 22); + ATF_REQUIRE(ilog2(0x0000000000ffffffULL) == 23); + ATF_REQUIRE(ilog2(0x0000000001ffffffULL) == 24); + ATF_REQUIRE(ilog2(0x0000000003ffffffULL) == 25); + ATF_REQUIRE(ilog2(0x0000000007ffffffULL) == 26); + ATF_REQUIRE(ilog2(0x000000000fffffffULL) == 27); + ATF_REQUIRE(ilog2(0x000000001fffffffULL) == 28); + ATF_REQUIRE(ilog2(0x000000003fffffffULL) == 29); + ATF_REQUIRE(ilog2(0x000000007fffffffULL) == 30); + ATF_REQUIRE(ilog2(0x00000000ffffffffULL) == 31); + ATF_REQUIRE(ilog2(0x00000001ffffffffULL) == 32); + ATF_REQUIRE(ilog2(0x00000003ffffffffULL) == 33); + ATF_REQUIRE(ilog2(0x00000007ffffffffULL) == 34); + ATF_REQUIRE(ilog2(0x0000000fffffffffULL) == 35); + ATF_REQUIRE(ilog2(0x0000001fffffffffULL) == 36); + ATF_REQUIRE(ilog2(0x0000003fffffffffULL) == 37); + ATF_REQUIRE(ilog2(0x0000007fffffffffULL) == 38); + ATF_REQUIRE(ilog2(0x000000ffffffffffULL) == 39); + ATF_REQUIRE(ilog2(0x000001ffffffffffULL) == 40); + ATF_REQUIRE(ilog2(0x000003ffffffffffULL) == 41); + ATF_REQUIRE(ilog2(0x000007ffffffffffULL) == 42); + ATF_REQUIRE(ilog2(0x00000fffffffffffULL) == 43); + ATF_REQUIRE(ilog2(0x00001fffffffffffULL) == 44); + ATF_REQUIRE(ilog2(0x00003fffffffffffULL) == 45); + ATF_REQUIRE(ilog2(0x00007fffffffffffULL) == 46); + ATF_REQUIRE(ilog2(0x0000ffffffffffffULL) == 47); + ATF_REQUIRE(ilog2(0x0001ffffffffffffULL) == 48); + ATF_REQUIRE(ilog2(0x0003ffffffffffffULL) == 49); + ATF_REQUIRE(ilog2(0x0007ffffffffffffULL) == 50); + ATF_REQUIRE(ilog2(0x000fffffffffffffULL) == 51); + ATF_REQUIRE(ilog2(0x001fffffffffffffULL) == 52); + ATF_REQUIRE(ilog2(0x003fffffffffffffULL) == 53); + ATF_REQUIRE(ilog2(0x007fffffffffffffULL) == 54); + ATF_REQUIRE(ilog2(0x00ffffffffffffffULL) == 55); + ATF_REQUIRE(ilog2(0x01ffffffffffffffULL) == 56); + ATF_REQUIRE(ilog2(0x03ffffffffffffffULL) == 57); + ATF_REQUIRE(ilog2(0x07ffffffffffffffULL) == 58); + ATF_REQUIRE(ilog2(0x0fffffffffffffffULL) == 59); + ATF_REQUIRE(ilog2(0x1fffffffffffffffULL) == 60); + ATF_REQUIRE(ilog2(0x3fffffffffffffffULL) == 61); + ATF_REQUIRE(ilog2(0x7fffffffffffffffULL) == 62); + ATF_REQUIRE(ilog2(0xffffffffffffffffULL) == 63); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, bitmap_basic); + ATF_TP_ADD_TC(tp, fast_divide32); + ATF_TP_ADD_TC(tp, ffsfls); + ATF_TP_ADD_TC(tp, ilog2_32bit); + ATF_TP_ADD_TC(tp, ilog2_64bit); + ATF_TP_ADD_TC(tp, ilog2_const); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/sys/t_bootblock.c b/contrib/netbsd-tests/include/sys/t_bootblock.c new file mode 100644 index 0000000..13af2dd --- /dev/null +++ b/contrib/netbsd-tests/include/sys/t_bootblock.c @@ -0,0 +1,73 @@ +/* $NetBSD: t_bootblock.c,v 1.1 2010/07/17 19:26:27 jmmv Exp $ */ + +/* + * Copyright (c) 2004, 2008, 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_bootblock.c,v 1.1 2010/07/17 19:26:27 jmmv Exp $"); + +#include +#include + +#include +#include +#include + +#include + +ATF_TC_WITHOUT_HEAD(mbr_sector); +ATF_TC_BODY(mbr_sector, tc) +{ + ATF_CHECK_EQ(512, sizeof(struct mbr_sector)); + + ATF_CHECK_EQ(MBR_BPB_OFFSET, offsetof(struct mbr_sector, mbr_bpb)); + ATF_CHECK_EQ(MBR_BS_OFFSET, offsetof(struct mbr_sector, mbr_bootsel)); + + ATF_CHECK_EQ(440, offsetof(struct mbr_sector, mbr_dsn)); + + ATF_CHECK_EQ(446, MBR_PART_OFFSET); + ATF_CHECK_EQ(MBR_PART_OFFSET, offsetof(struct mbr_sector, mbr_parts)); + + ATF_CHECK_EQ(510, MBR_MAGIC_OFFSET); + ATF_CHECK_EQ(MBR_MAGIC_OFFSET, offsetof(struct mbr_sector, mbr_magic)); +} + +ATF_TC_WITHOUT_HEAD(mbr_partition); +ATF_TC_BODY(mbr_partition, tc) +{ + ATF_CHECK_EQ(16, sizeof(struct mbr_partition)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mbr_sector); + ATF_TP_ADD_TC(tp, mbr_partition); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/sys/t_cdefs.c b/contrib/netbsd-tests/include/sys/t_cdefs.c new file mode 100644 index 0000000..14f5cf2 --- /dev/null +++ b/contrib/netbsd-tests/include/sys/t_cdefs.c @@ -0,0 +1,267 @@ +/* $NetBSD: t_cdefs.c,v 1.4 2016/03/16 07:21:36 mrg Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_cdefs.c,v 1.4 2016/03/16 07:21:36 mrg Exp $"); + +#include +#include +#include +#include + +static const struct { + const char *name; + intmax_t min; + intmax_t max; +} s[] = { + { "signed char", SCHAR_MIN, SCHAR_MAX }, + { "signed short", SHRT_MIN, SHRT_MAX }, + { "signed int", INT_MIN, INT_MAX }, + { "signed long", LONG_MIN, LONG_MAX }, + { "signed long long", LLONG_MIN, LLONG_MAX }, +}; + +static const struct { + const char *name; + uintmax_t min; + uintmax_t max; +} u[] = { + { "unsigned char", 0, UCHAR_MAX }, + { "unsigned short", 0, USHRT_MAX }, + { "unsigned int", 0, UINT_MAX }, + { "unsigned long", 0, ULONG_MAX }, + { "unsigned long long", 0, ULLONG_MAX }, +}; + +ATF_TC(stypeminmax); +ATF_TC_HEAD(stypeminmax, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks signed type min/max macros"); +} + + +ATF_TC_BODY(stypeminmax, tc) +{ +#define CHECK(a, b) ATF_REQUIRE(__type_min(a) == s[b].min); \ + ATF_REQUIRE(__type_max(a) == s[b].max) + + CHECK(signed char, 0); + CHECK(signed short, 1); + CHECK(signed int, 2); + CHECK(signed long, 3); + CHECK(signed long long, 4); +#undef CHECK +} + +ATF_TC(utypeminmax); +ATF_TC_HEAD(utypeminmax, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks unsigned type min/max macros"); +} + +ATF_TC_BODY(utypeminmax, tc) +{ +#define CHECK(a, b) ATF_REQUIRE(__type_min(a) == u[b].min); \ + ATF_REQUIRE(__type_max(a) == u[b].max) + + CHECK(unsigned char, 0); + CHECK(unsigned short, 1); + CHECK(unsigned int, 2); + CHECK(unsigned long, 3); + CHECK(unsigned long long, 4); +#undef CHECK +} + +ATF_TC(sissigned); +ATF_TC_HEAD(sissigned, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks issigned macro for signed"); +} + +ATF_TC_BODY(sissigned, tc) +{ +#define CHECK(a) ATF_REQUIRE(__type_is_signed(a) == 1) + + CHECK(signed char); + CHECK(signed short); + CHECK(signed int); + CHECK(signed long); + CHECK(signed long long); +#undef CHECK +} + +ATF_TC(uissigned); +ATF_TC_HEAD(uissigned, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks issigned macro for unsigned"); +} + +ATF_TC_BODY(uissigned, tc) +{ +#define CHECK(a) ATF_REQUIRE(__type_is_signed(a) == 0) + + CHECK(unsigned char); + CHECK(unsigned short); + CHECK(unsigned int); + CHECK(unsigned long); + CHECK(unsigned long long); +#undef CHECK +} + +ATF_TC(utypemask); +ATF_TC_HEAD(utypemask, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks type mask macro for unsigned"); +} + +ATF_TC_BODY(utypemask, tc) +{ +#define CHECK(a, b) ATF_REQUIRE(__type_mask(a) == b) + + CHECK(unsigned char, 0xffffffffffffff00ULL); + CHECK(unsigned short, 0xffffffffffff0000ULL); + CHECK(unsigned int, 0xffffffff00000000ULL); + CHECK(unsigned long long, 0x0000000000000000ULL); +#undef CHECK +} + +ATF_TC(stypemask); +ATF_TC_HEAD(stypemask, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks type mask macro for signed"); +} + +ATF_TC_BODY(stypemask, tc) +{ +#define CHECK(a, b) ATF_REQUIRE(__type_mask(a) == b) + + CHECK(signed char, 0xffffffffffffff00LL); + CHECK(signed short, 0xffffffffffff0000LL); + CHECK(signed int, 0xffffffff00000000LL); + CHECK(signed long long, 0x0000000000000000LL); +#undef CHECK +} + +ATF_TC(stypefit); +ATF_TC_HEAD(stypefit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks typefit macro for signed"); +} + +ATF_TC_BODY(stypefit, tc) +{ +#define CHECK(a, b, c) ATF_REQUIRE(__type_fit(a, b) == c) + + CHECK(signed char, -1, 1); + CHECK(signed char, 1, 1); + CHECK(signed char, 0x7f, 1); + CHECK(signed char, 0x80, 0); + CHECK(signed char, 0xff, 0); + CHECK(signed char, 0x1ff, 0); + + CHECK(signed short, -1, 1); + CHECK(signed short, 1, 1); + CHECK(signed short, 0x7fff, 1); + CHECK(signed short, 0x8000, 0); + CHECK(signed short, 0xffff, 0); + CHECK(signed short, 0x1ffff, 0); + + CHECK(signed int, -1, 1); + CHECK(signed int, 1, 1); + CHECK(signed int, 0x7fffffff, 1); + CHECK(signed int, 0x80000000, 0); + CHECK(signed int, 0xffffffff, 0); + CHECK(signed int, 0x1ffffffffLL, 0); + + CHECK(signed long long, -1, 1); + CHECK(signed long long, 1, 1); + CHECK(signed long long, 0x7fffffffffffffffLL, 1); + CHECK(signed long long, 0x8000000000000000LL, 0); + CHECK(signed long long, 0xffffffffffffffffLL, 0); + +#undef CHECK +} + +ATF_TC(utypefit); +ATF_TC_HEAD(utypefit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks typefit macro for unsigned"); +} + +ATF_TC_BODY(utypefit, tc) +{ +#define CHECK(a, b, c) ATF_REQUIRE(__type_fit(a, b) == c) + + CHECK(unsigned char, -1, 0); + CHECK(unsigned char, 1, 1); + CHECK(unsigned char, 0x7f, 1); + CHECK(unsigned char, 0x80, 1); + CHECK(unsigned char, 0xff, 1); + CHECK(unsigned char, 0x1ff, 0); + + CHECK(unsigned short, -1, 0); + CHECK(unsigned short, 1, 1); + CHECK(unsigned short, 0x7fff, 1); + CHECK(unsigned short, 0x8000, 1); + CHECK(unsigned short, 0xffff, 1); + CHECK(unsigned short, 0x1ffff, 0); + + CHECK(unsigned int, -1, 0); + CHECK(unsigned int, 1, 1); + CHECK(unsigned int, 0x7fffffff, 1); + CHECK(unsigned int, 0x80000000, 1); + CHECK(unsigned int, 0xffffffff, 1); + CHECK(unsigned int, 0x1ffffffffLL, 0); + + CHECK(unsigned long long, -1, 0); + CHECK(unsigned long long, 1, 1); + CHECK(unsigned long long, 0x7fffffffffffffffULL, 1); + CHECK(unsigned long long, 0x8000000000000000ULL, 1); + CHECK(unsigned long long, 0xffffffffffffffffULL, 1); + +#undef CHECK +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, stypeminmax); + ATF_TP_ADD_TC(tp, utypeminmax); + ATF_TP_ADD_TC(tp, sissigned); + ATF_TP_ADD_TC(tp, uissigned); + ATF_TP_ADD_TC(tp, stypemask); + ATF_TP_ADD_TC(tp, utypemask); + ATF_TP_ADD_TC(tp, stypefit); + ATF_TP_ADD_TC(tp, utypefit); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/sys/t_pslist.c b/contrib/netbsd-tests/include/sys/t_pslist.c new file mode 100644 index 0000000..f46ed57 --- /dev/null +++ b/contrib/netbsd-tests/include/sys/t_pslist.c @@ -0,0 +1,125 @@ +/* $NetBSD: t_pslist.c,v 1.1 2016/04/09 04:39:47 riastradh Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Taylor R. Campbell. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include + +/* + * XXX This is a limited test to make sure the operations behave as + * described on a sequential machine. It does nothing to test the + * pserialize-safety of any operations. + */ + +ATF_TC(misc); +ATF_TC_HEAD(misc, tc) +{ + atf_tc_set_md_var(tc, "descr", "pserialize-safe list tests"); +} +ATF_TC_BODY(misc, tc) +{ + struct pslist_head h = PSLIST_INITIALIZER; + struct element { + unsigned i; + struct pslist_entry entry; + } elements[] = { + { .i = 0, .entry = PSLIST_ENTRY_INITIALIZER }, + { .i = 1 }, + { .i = 2 }, + { .i = 3 }, + { .i = 4 }, + { .i = 5 }, + { .i = 6 }, + { .i = 7 }, + }; + struct element *element; + unsigned i; + + /* Check PSLIST_INITIALIZER is destroyable. */ + PSLIST_DESTROY(&h); + PSLIST_INIT(&h); + + /* Check PSLIST_ENTRY_INITIALIZER is destroyable. */ + PSLIST_ENTRY_DESTROY(&elements[0], entry); + + for (i = 0; i < __arraycount(elements); i++) + PSLIST_ENTRY_INIT(&elements[i], entry); + + PSLIST_WRITER_INSERT_HEAD(&h, &elements[4], entry); + PSLIST_WRITER_INSERT_BEFORE(&elements[4], &elements[2], entry); + PSLIST_WRITER_INSERT_BEFORE(&elements[4], &elements[3], entry); + PSLIST_WRITER_INSERT_BEFORE(&elements[2], &elements[1], entry); + PSLIST_WRITER_INSERT_HEAD(&h, &elements[0], entry); + PSLIST_WRITER_INSERT_AFTER(&elements[4], &elements[5], entry); + PSLIST_WRITER_INSERT_AFTER(&elements[5], &elements[7], entry); + PSLIST_WRITER_INSERT_AFTER(&elements[5], &elements[6], entry); + + PSLIST_WRITER_REMOVE(&elements[0], entry); + ATF_CHECK(elements[0].entry.ple_next != NULL); + PSLIST_ENTRY_DESTROY(&elements[0], entry); + + PSLIST_WRITER_REMOVE(&elements[4], entry); + ATF_CHECK(elements[4].entry.ple_next != NULL); + PSLIST_ENTRY_DESTROY(&elements[4], entry); + + PSLIST_ENTRY_INIT(&elements[0], entry); + PSLIST_WRITER_INSERT_HEAD(&h, &elements[0], entry); + + PSLIST_ENTRY_INIT(&elements[4], entry); + PSLIST_WRITER_INSERT_AFTER(&elements[3], &elements[4], entry); + + i = 0; + PSLIST_WRITER_FOREACH(element, &h, struct element, entry) { + ATF_CHECK_EQ(i, element->i); + i++; + } + i = 0; + PSLIST_READER_FOREACH(element, &h, struct element, entry) { + ATF_CHECK_EQ(i, element->i); + i++; + } + + while ((element = PSLIST_WRITER_FIRST(&h, struct element, entry)) + != NULL) { + PSLIST_WRITER_REMOVE(element, entry); + PSLIST_ENTRY_DESTROY(element, entry); + } + + PSLIST_DESTROY(&h); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, misc); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/sys/t_socket.c b/contrib/netbsd-tests/include/sys/t_socket.c new file mode 100644 index 0000000..9db2247 --- /dev/null +++ b/contrib/netbsd-tests/include/sys/t_socket.c @@ -0,0 +1,205 @@ +/* $NetBSD: t_socket.c,v 1.5 2017/01/13 21:30:41 christos Exp $ */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "h_macros.h" + +ATF_TC(cmsg_sendfd_bounds); +ATF_TC_HEAD(cmsg_sendfd_bounds, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that attempting to pass an " + "invalid fd returns an error"); +} + +ATF_TC_BODY(cmsg_sendfd_bounds, tc) +{ + struct cmsghdr *cmp; + struct msghdr msg; + struct iovec iov; + int s[2]; + int fd; + + rump_init(); + + if (rump_sys_socketpair(AF_LOCAL, SOCK_STREAM, 0, s) == -1) + atf_tc_fail("rump_sys_socket"); + + cmp = malloc(CMSG_SPACE(sizeof(int))); + + iov.iov_base = &fd; + iov.iov_len = sizeof(int); + + cmp->cmsg_level = SOL_SOCKET; + cmp->cmsg_type = SCM_RIGHTS; + cmp->cmsg_len = CMSG_LEN(sizeof(int)); + + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_control = cmp; + msg.msg_controllen = CMSG_SPACE(sizeof(int)); + + /* + * ERROR HERE: trying to pass invalid fd + * (This value was previously directly used to index the fd + * array and therefore we are passing a hyperspace index) + */ + *(int *)CMSG_DATA(cmp) = 0x12345678; + + rump_sys_sendmsg(s[0], &msg, 0); + if (errno != EBADF) + atf_tc_fail("descriptor passing failed: expected EBADF (9), " + "got %d\n(%s)", errno, strerror(errno)); +} + + +ATF_TC(cmsg_sendfd); +ATF_TC_HEAD(cmsg_sendfd, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that fd passing works"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(cmsg_sendfd, tc) +{ + char buf[128]; + struct cmsghdr *cmp; + struct msghdr msg; + struct sockaddr_un sun; + struct lwp *l1; + struct iovec iov; + socklen_t sl; + int s1, s2, sgot; + int rfd, fd[2], storage; + + rump_init(); + + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + l1 = rump_pub_lwproc_curlwp(); + + /* create unix socket and bind it to a path */ + memset(&sun, 0, sizeof(sun)); + sun.sun_family = AF_LOCAL; +#define SOCKPATH "/com" + strncpy(sun.sun_path, SOCKPATH, sizeof(SOCKPATH)); + s1 = rump_sys_socket(AF_LOCAL, SOCK_STREAM, 0); + if (s1 == -1) + atf_tc_fail_errno("socket 1"); + if (rump_sys_bind(s1, (struct sockaddr *)&sun, SUN_LEN(&sun)) == -1) + atf_tc_fail_errno("socket 1 bind"); + if (rump_sys_listen(s1, 1) == -1) + atf_tc_fail_errno("socket 1 listen"); + + /* create second process for test */ + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + (void)rump_pub_lwproc_curlwp(); + + /* connect to unix domain socket */ + memset(&sun, 0, sizeof(sun)); + sun.sun_family = AF_LOCAL; + strncpy(sun.sun_path, SOCKPATH, sizeof(SOCKPATH)); + s2 = rump_sys_socket(AF_LOCAL, SOCK_STREAM, 0); + if (s2 == -1) + atf_tc_fail_errno("socket 2"); + if (rump_sys_connect(s2, (struct sockaddr *)&sun, SUN_LEN(&sun)) == -1) + atf_tc_fail_errno("socket 2 connect"); + + /* open a pipe and write stuff to it */ + if (rump_sys_pipe(fd) == -1) + atf_tc_fail_errno("can't open pipe"); +#define MAGICSTRING "duam xnaht" + if (rump_sys_write(fd[1], MAGICSTRING, sizeof(MAGICSTRING)) != + sizeof(MAGICSTRING)) + atf_tc_fail_errno("pipe write"); /* XXX: errno */ + + cmp = malloc(CMSG_SPACE(sizeof(int))); + + iov.iov_base = &storage; + iov.iov_len = sizeof(int); + + cmp->cmsg_level = SOL_SOCKET; + cmp->cmsg_type = SCM_RIGHTS; + cmp->cmsg_len = CMSG_LEN(sizeof(int)); + + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_control = cmp; + msg.msg_controllen = CMSG_SPACE(sizeof(int)); + *(int *)CMSG_DATA(cmp) = fd[0]; + + /* pass the fd */ + if (rump_sys_sendmsg(s2, &msg, 0) == -1) + atf_tc_fail_errno("sendmsg failed"); + + /* + * We will read to the same cmsg space. Overwrite the space + * with an invalid fd to make sure we get an explicit error + * if we don't manage to read the fd. + */ + *(int *)CMSG_DATA(cmp) = -1; + + /* switch back to original proc */ + rump_pub_lwproc_switch(l1); + + /* accept connection and read fd */ + sl = sizeof(sun); + sgot = rump_sys_accept(s1, (struct sockaddr *)&sun, &sl); + if (sgot == -1) + atf_tc_fail_errno("accept"); + if (rump_sys_recvmsg(sgot, &msg, 0) == -1) + atf_tc_fail_errno("recvmsg failed"); + rfd = *(int *)CMSG_DATA(cmp); + + /* read from the fd */ + memset(buf, 0, sizeof(buf)); + if (rump_sys_read(rfd, buf, sizeof(buf)) == -1) + atf_tc_fail_errno("read rfd"); + + /* check that we got the right stuff */ + if (strcmp(buf, MAGICSTRING) != 0) + atf_tc_fail("expected \"%s\", got \"%s\"", MAGICSTRING, buf); +} + +ATF_TC(sock_cloexec); +ATF_TC_HEAD(sock_cloexec, tc) +{ + atf_tc_set_md_var(tc, "descr", "SOCK_CLOEXEC kernel invariant failure"); +} + +ATF_TC_BODY(sock_cloexec, tc) +{ + + rump_init(); + rump_pub_lwproc_rfork(RUMP_RFFDG); + if (rump_sys_socket(-1, SOCK_CLOEXEC, 0) != -1) + atf_tc_fail("invalid socket parameters unexpectedly worked"); + rump_pub_lwproc_releaselwp(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, cmsg_sendfd); + ATF_TP_ADD_TC(tp, cmsg_sendfd_bounds); + ATF_TP_ADD_TC(tp, sock_cloexec); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/sys/t_tree.c b/contrib/netbsd-tests/include/sys/t_tree.c new file mode 100644 index 0000000..498f7ee --- /dev/null +++ b/contrib/netbsd-tests/include/sys/t_tree.c @@ -0,0 +1,124 @@ +/* $NetBSD: t_tree.c,v 1.1 2011/05/05 13:36:05 jruoho Exp $ */ + +/*- + * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include + +struct mist { + RB_ENTRY(mist) rbentry; + int key; +}; +RB_HEAD(head, mist) tt; + +static int +mistcmp(struct mist *a, struct mist *b) +{ +#if 0 + return (b->key - a->key); /* wrong, can overflow */ +#else + if (b->key > a->key) + return 1; + else if (b->key < a->key) + return (-1); + else + return 0; +#endif +} + +RB_PROTOTYPE(head, mist, rbentry, mistcmp) +RB_GENERATE(head, mist, rbentry, mistcmp) + +static struct mist * +addmist(int key) +{ + struct mist *m; + + m = malloc(sizeof(struct mist)); + m->key = key; + RB_INSERT(head, &tt, m); + return m; +} + +static int +findmist(struct mist *m) +{ + + return (!!RB_FIND(head, &tt, m)); +} + +#define N 1000 +static int +test(void) +{ + struct mist *m[N]; + int fail, i, j; + + RB_INIT(&tt); + fail = 0; + for (i = 0; i < N; i++) { + m[i] = addmist(random() << 1); /* use all 32 bits */ + for (j = 0; j <= i; j++) + if (!findmist(m[j])) + fail++; + } + return fail; +} + +ATF_TC(tree_rbstress); +ATF_TC_HEAD(tree_rbstress, tc) +{ + + atf_tc_set_md_var(tc, "descr", "rb-tree stress test"); +} + +ATF_TC_BODY(tree_rbstress, tc) +{ + int i, fail, f; + + srandom(4711); + fail = 0; + for (i = 0; i < 10; i++) { + f = test(); + if (f) { + atf_tc_fail_nonfatal("loop %d: %d errors\n", i, f); + fail += f; + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, tree_rbstress); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/sys/t_types.c b/contrib/netbsd-tests/include/sys/t_types.c new file mode 100644 index 0000000..45b715f --- /dev/null +++ b/contrib/netbsd-tests/include/sys/t_types.c @@ -0,0 +1,144 @@ +/* $NetBSD: t_types.c,v 1.4 2012/03/18 07:14:08 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_types.c,v 1.4 2012/03/18 07:14:08 jruoho Exp $"); + +#include + +#include +#include +#include + +#include + +ATF_TC(types_limits); +ATF_TC_HEAD(types_limits, tc) +{ + atf_tc_set_md_var(tc, "descr", "Known limits for types(3)"); +} + +ATF_TC_BODY(types_limits, tc) +{ + useconds_t usec; + ssize_t size; + + /* + * IEEE Std 1003.1-2008: + * + * "The type ssize_t shall be capable of storing + * values at least in the range [-1, {SSIZE_MAX}]." + * + */ + size = SSIZE_MAX; + ATF_REQUIRE(size > 0); + + size = size + 1; + ATF_REQUIRE(size < 0); + + /* + * IEEE Std 1003.1-2008: + * + * "The type suseconds_t shall be a signed integer type capable + * of storing values at least in the range [-1, 1000000]." + */ + usec = 1000000; + ATF_REQUIRE(usec > 0); +} + +ATF_TC(types_signed); +ATF_TC_HEAD(types_signed, tc) +{ + atf_tc_set_md_var(tc, "descr", "Signed types(3)" + " (PR standards/44847)"); +} + +ATF_TC_BODY(types_signed, tc) +{ + blkcnt_t bc; + blksize_t bs; + ssize_t size; + off_t off; + pid_t pid; + + /* + * As noted in types(3), the following + * types should be signed integers. + */ + bc = 0; + bs = 0; + off = 0; + pid = 0; + size = 0; + + ATF_CHECK((bc - 1) <= 0); + ATF_CHECK((bs - 1) <= 0); + ATF_CHECK((off - 1) <= 0); + ATF_CHECK((pid - 1) <= 0); + ATF_CHECK((size - 1) <= 0); +} + +ATF_TC(types_unsigned); +ATF_TC_HEAD(types_unsigned, tc) +{ + atf_tc_set_md_var(tc, "descr", "Unsigned types(3)" + " (PR standards/18067)"); +} + +ATF_TC_BODY(types_unsigned, tc) +{ + fsblkcnt_t fb; + fsfilcnt_t ff; + size_t size; + rlim_t lim; + ino_t ino; + + fb = 0; + ff = 0; + ino = 0; + lim = 0; + size = 0; + + ATF_CHECK((fb - 1) > 0); + ATF_CHECK((ff - 1) > 0); + ATF_CHECK((ino - 1) > 0); + ATF_CHECK((lim - 1) > 0); + ATF_CHECK((size - 1) > 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, types_limits); + ATF_TP_ADD_TC(tp, types_signed); + ATF_TP_ADD_TC(tp, types_unsigned); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/t_bitstring.c b/contrib/netbsd-tests/include/t_bitstring.c new file mode 100644 index 0000000..1dda3c2 --- /dev/null +++ b/contrib/netbsd-tests/include/t_bitstring.c @@ -0,0 +1,298 @@ +/* $NetBSD: t_bitstring.c,v 1.4 2012/03/25 06:54:04 joerg Exp $ */ + +/*- + * Copyright (c) 1993, 2008, 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#include + +static void +clearbits(bitstr_t *b, int n) +{ + int i = bitstr_size(n); + + while(i--) + *(b + i) = 0; +} + +static void +printbits(FILE *file, bitstr_t *b, int n) +{ + int i; + int jc, js; + + bit_ffc(b, n, &jc); + bit_ffs(b, n, &js); + + (void) fprintf(file, "%3d %3d ", jc, js); + + for (i=0; i < n; i++) { + (void) fprintf(file, "%c", (bit_test(b, i) ? '1' : '0')); + } + + (void) fprintf(file, "%c", '\n'); +} + +static void +calculate_data(FILE *file, const int test_length) +{ + int i; + bitstr_t *bs; + + assert(test_length >= 4); + + (void) fprintf(file, "Testing with TEST_LENGTH = %d\n\n", test_length); + + (void) fprintf(file, "test _bit_byte, _bit_mask, and bitstr_size\n"); + (void) fprintf(file, " i _bit_byte(i) _bit_mask(i) bitstr_size(i)\n"); + + for (i=0; i < test_length; i++) { + (void) fprintf(file, "%3d%15u%15u%15zu\n", + i, _bit_byte(i), _bit_mask(i), bitstr_size(i)); + } + + bs = bit_alloc(test_length); + clearbits(bs, test_length); + (void) fprintf(file, "\ntest bit_alloc, clearbits, bit_ffc, bit_ffs\n"); + (void) fprintf(file, "be: 0 -1 "); + for (i=0; i < test_length; i++) + (void) fprintf(file, "%c", '0'); + (void) fprintf(file, "\nis: "); + printbits(file, bs, test_length); + + (void) fprintf(file, "\ntest bit_set\n"); + for (i=0; i < test_length; i+=3) + bit_set(bs, i); + (void) fprintf(file, "be: 1 0 "); + for (i=0; i < test_length; i++) + (void) fprintf(file, "%c", "100"[i % 3]); + (void) fprintf(file, "\nis: "); + printbits(file, bs, test_length); + + (void) fprintf(file, "\ntest bit_clear\n"); + for (i=0; i < test_length; i+=6) + bit_clear(bs, i); + (void) fprintf(file, "be: 0 3 "); + for (i=0; i < test_length; i++) + (void) fprintf(file, "%c", "000100"[i % 6]); + (void) fprintf(file, "\nis: "); + printbits(file, bs, test_length); + + (void) fprintf(file, "\ntest bit_test using previous bitstring\n"); + (void) fprintf(file, " i bit_test(i)\n"); + for (i=0; i < test_length; i++) + (void) fprintf(file, "%3d%15d\n", i, bit_test(bs, i)); + + clearbits(bs, test_length); + (void) fprintf(file, "\ntest clearbits\n"); + (void) fprintf(file, "be: 0 -1 "); + for (i=0; i < test_length; i++) + (void) fprintf(file, "%c", '0'); + (void) fprintf(file, "\nis: "); + printbits(file, bs, test_length); + + (void) fprintf(file, "\ntest bit_nset and bit_nclear\n"); + bit_nset(bs, 1, test_length - 2); + (void) fprintf(file, "be: 0 1 0"); + for (i=0; i < test_length - 2; i++) + (void) fprintf(file, "%c", '1'); + (void) fprintf(file, "0\nis: "); + printbits(file, bs, test_length); + + bit_nclear(bs, 2, test_length - 3); + (void) fprintf(file, "be: 0 1 01"); + for (i=0; i < test_length - 4; i++) + (void) fprintf(file, "%c", '0'); + (void) fprintf(file, "10\nis: "); + printbits(file, bs, test_length); + + bit_nclear(bs, 0, test_length - 1); + (void) fprintf(file, "be: 0 -1 "); + for (i=0; i < test_length; i++) + (void) fprintf(file, "%c", '0'); + (void) fprintf(file, "\nis: "); + printbits(file, bs, test_length); + bit_nset(bs, 0, test_length - 2); + (void) fprintf(file, "be: %3d 0 ",test_length - 1); + for (i=0; i < test_length - 1; i++) + (void) fprintf(file, "%c", '1'); + fprintf(file, "%c", '0'); + (void) fprintf(file, "\nis: "); + printbits(file, bs, test_length); + bit_nclear(bs, 0, test_length - 1); + (void) fprintf(file, "be: 0 -1 "); + for (i=0; i < test_length; i++) + (void) fprintf(file, "%c", '0'); + (void) fprintf(file, "\nis: "); + printbits(file, bs, test_length); + + (void) fprintf(file, "\n"); + (void) fprintf(file, "first 1 bit should move right 1 position each line\n"); + for (i=0; i < test_length; i++) { + bit_nclear(bs, 0, test_length - 1); + bit_nset(bs, i, test_length - 1); + (void) fprintf(file, "%3d ", i); printbits(file, bs, test_length); + } + + (void) fprintf(file, "\n"); + (void) fprintf(file, "first 0 bit should move right 1 position each line\n"); + for (i=0; i < test_length; i++) { + bit_nset(bs, 0, test_length - 1); + bit_nclear(bs, i, test_length - 1); + (void) fprintf(file, "%3d ", i); printbits(file, bs, test_length); + } + + (void) fprintf(file, "\n"); + (void) fprintf(file, "first 0 bit should move left 1 position each line\n"); + for (i=0; i < test_length; i++) { + bit_nclear(bs, 0, test_length - 1); + bit_nset(bs, 0, test_length - 1 - i); + (void) fprintf(file, "%3d ", i); printbits(file, bs, test_length); + } + + (void) fprintf(file, "\n"); + (void) fprintf(file, "first 1 bit should move left 1 position each line\n"); + for (i=0; i < test_length; i++) { + bit_nset(bs, 0, test_length - 1); + bit_nclear(bs, 0, test_length - 1 - i); + (void) fprintf(file, "%3d ", i); printbits(file, bs, test_length); + } + + (void) fprintf(file, "\n"); + (void) fprintf(file, "0 bit should move right 1 position each line\n"); + for (i=0; i < test_length; i++) { + bit_nset(bs, 0, test_length - 1); + bit_nclear(bs, i, i); + (void) fprintf(file, "%3d ", i); printbits(file, bs, test_length); + } + + (void) fprintf(file, "\n"); + (void) fprintf(file, "1 bit should move right 1 position each line\n"); + for (i=0; i < test_length; i++) { + bit_nclear(bs, 0, test_length - 1); + bit_nset(bs, i, i); + (void) fprintf(file, "%3d ", i); printbits(file, bs, test_length); + } + + (void) free(bs); +} + +static void +one_check(const atf_tc_t *tc, const int test_length) +{ + FILE *out; + char command[1024]; + + ATF_REQUIRE((out = fopen("out", "w")) != NULL); + calculate_data(out, test_length); + fclose(out); + + /* XXX The following is a huge hack that was added to simplify the + * conversion of these tests from src/regress/ to src/tests/. The + * tests in this file should be checking their own results, without + * having to resort to external data files. */ + snprintf(command, sizeof(command), "diff -u %s/d_bitstring_%d.out out", + atf_tc_get_config_var(tc, "srcdir"), test_length); + if (system(command) != EXIT_SUCCESS) + atf_tc_fail("Test failed; see output for details"); +} + +ATF_TC(bits_8); +ATF_TC_HEAD(bits_8, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks 8-bit long bitstrings"); +} +ATF_TC_BODY(bits_8, tc) +{ + one_check(tc, 8); +} + +ATF_TC(bits_27); +ATF_TC_HEAD(bits_27, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks 27-bit long bitstrings"); +} +ATF_TC_BODY(bits_27, tc) +{ + one_check(tc, 27); +} + +ATF_TC(bits_32); +ATF_TC_HEAD(bits_32, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks 32-bit long bitstrings"); +} +ATF_TC_BODY(bits_32, tc) +{ + one_check(tc, 32); +} + +ATF_TC(bits_49); +ATF_TC_HEAD(bits_49, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks 49-bit long bitstrings"); +} +ATF_TC_BODY(bits_49, tc) +{ + one_check(tc, 49); +} + +ATF_TC(bits_64); +ATF_TC_HEAD(bits_64, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks 64-bit long bitstrings"); +} +ATF_TC_BODY(bits_64, tc) +{ + one_check(tc, 64); +} + +ATF_TC(bits_67); +ATF_TC_HEAD(bits_67, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks 67-bit long bitstrings"); +} +ATF_TC_BODY(bits_67, tc) +{ + one_check(tc, 67); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, bits_8); + ATF_TP_ADD_TC(tp, bits_27); + ATF_TP_ADD_TC(tp, bits_32); + ATF_TP_ADD_TC(tp, bits_49); + ATF_TP_ADD_TC(tp, bits_64); + ATF_TP_ADD_TC(tp, bits_67); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/t_errno.c b/contrib/netbsd-tests/include/t_errno.c new file mode 100644 index 0000000..763e569 --- /dev/null +++ b/contrib/netbsd-tests/include/t_errno.c @@ -0,0 +1,765 @@ +/* $NetBSD: t_errno.c,v 1.1 2011/05/01 17:07:05 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_errno.c,v 1.1 2011/05/01 17:07:05 jruoho Exp $"); + +#include +#include + +ATF_TC(errno_constants); +ATF_TC_HEAD(errno_constants, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test POSIX constants in "); +} + +ATF_TC_BODY(errno_constants, tc) +{ + bool fail; + + /* + * The following definitions should be available + * according to IEEE Std 1003.1-2008, issue 7. + */ + atf_tc_expect_fail("PR standards/44921"); + + fail = true; + +#ifdef E2BIG + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("E2BIG not defined"); + + fail = true; + +#ifdef EACCES + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EACCES not defined"); + + fail = true; + +#ifdef EADDRINUSE + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EADDRINUSE not defined"); + + fail = true; + +#ifdef EADDRNOTAVAIL + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EADDRNOTAVAIL not defined"); + + fail = true; + +#ifdef EAFNOSUPPORT + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EAFNOSUPPORT not defined"); + + fail = true; + +#ifdef EAGAIN + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EAGAIN not defined"); + + fail = true; + +#ifdef EALREADY + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EALREADY not defined"); + + fail = true; + +#ifdef EBADF + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EBADF not defined"); + + fail = true; + +#ifdef EBADMSG + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EBADMSG not defined"); + + fail = true; + +#ifdef EBUSY + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EBUSY not defined"); + + fail = true; + +#ifdef ECANCELED + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("ECANCELED not defined"); + + fail = true; + +#ifdef ECHILD + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("ECHILD not defined"); + + fail = true; + +#ifdef ECONNABORTED + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("ECONNABORTED not defined"); + + fail = true; + +#ifdef ECONNREFUSED + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("ECONNREFUSED not defined"); + + fail = true; + +#ifdef ECONNRESET + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("ECONNRESET not defined"); + + fail = true; + +#ifdef EDEADLK + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EDEADLK not defined"); + + fail = true; + +#ifdef EDESTADDRREQ + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EDESTADDRREQ not defined"); + + fail = true; + +#ifdef EDOM + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EDOM not defined"); + + fail = true; + +#ifdef EDQUOT + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EDQUOT not defined"); + + fail = true; + +#ifdef EEXIST + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EEXIST not defined"); + + fail = true; + +#ifdef EFAULT + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EFAULT not defined"); + + fail = true; + +#ifdef EFBIG + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EFBIG not defined"); + + fail = true; + +#ifdef EHOSTUNREACH + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EHOSTUNREACH not defined"); + + fail = true; + +#ifdef EIDRM + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EIDRM not defined"); + + fail = true; + +#ifdef EILSEQ + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EILSEQ not defined"); + + fail = true; + +#ifdef EINPROGRESS + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EINPROGRESS not defined"); + + fail = true; + +#ifdef EINTR + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EINTR not defined"); + + fail = true; + +#ifdef EINVAL + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EINVAL not defined"); + + fail = true; + +#ifdef EIO + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EIO not defined"); + + fail = true; + +#ifdef EISCONN + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EISCONN not defined"); + + fail = true; + +#ifdef EISDIR + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EISDIR not defined"); + + fail = true; + +#ifdef ELOOP + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ELOOP not defined"); + + fail = true; + +#ifdef EMFILE + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EMFILE not defined"); + + fail = true; + +#ifdef EMLINK + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EMLINK not defined"); + + fail = true; + +#ifdef EMSGSIZE + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EMSGSIZE not defined"); + + fail = true; + +#ifdef EMULTIHOP + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EMULTIHOP not defined"); + + fail = true; + +#ifdef ENAMETOOLONG + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENAMETOOLONG not defined"); + + fail = true; + +#ifdef ENETDOWN + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENETDOWN not defined"); + + fail = true; + +#ifdef ENETRESET + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENETRESET not defined"); + + fail = true; + +#ifdef ENETUNREACH + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENETUNREACH not defined"); + + fail = true; + +#ifdef ENFILE + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENFILE not defined"); + + fail = true; + +#ifdef ENOBUFS + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOBUFS not defined"); + + fail = true; + +#ifdef ENODATA + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENODATA not defined"); + + fail = true; + +#ifdef ENODEV + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENODEV not defined"); + + fail = true; + +#ifdef ENOENT + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOENT not defined"); + + fail = true; + +#ifdef ENOEXEC + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOEXEC not defined"); + + fail = true; + +#ifdef ENOLCK + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOLCK not defined"); + + fail = true; + +#ifdef ENOLINK + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOLINK not defined"); + + fail = true; + +#ifdef ENOMEM + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOMEM not defined"); + + fail = true; + +#ifdef ENOMSG + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOMSG not defined"); + + fail = true; + +#ifdef ENOPROTOOPT + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOPROTOOPT not defined"); + + fail = true; + +#ifdef ENOSPC + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOSPC not defined"); + + fail = true; + +#ifdef ENOSR + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOSR not defined"); + + fail = true; + +#ifdef ENOSTR + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOSTR not defined"); + + fail = true; + +#ifdef ENOSYS + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOSYS not defined"); + + fail = true; + +#ifdef ENOTCONN + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOTCONN not defined"); + + fail = true; + +#ifdef ENOTDIR + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOTDIR not defined"); + + fail = true; + +#ifdef ENOTEMPTY + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOTEMPTY not defined"); + + fail = true; + +#ifdef ENOTRECOVERABLE + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOTRECOVERABLE not defined"); + + fail = true; + +#ifdef ENOTSOCK + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOTSOCK not defined"); + + fail = true; + +#ifdef ENOTSUP + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOTSUP not defined"); + + fail = true; + +#ifdef ENOTTY + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENOTTY not defined"); + + fail = true; + +#ifdef ENXIO + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ENXIO not defined"); + + fail = true; + +#ifdef EOPNOTSUPP + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EOPNOTSUPP not defined"); + + fail = true; + +#ifdef EOVERFLOW + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EOVERFLOW not defined"); + + fail = true; + +#ifdef EOWNERDEAD + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EOWNERDEAD not defined"); + + fail = true; + +#ifdef EPERM + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EPERM not defined"); + + fail = true; + +#ifdef EPIPE + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EPIPE not defined"); + + fail = true; + +#ifdef EPROTO + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EPROTO not defined"); + + fail = true; + +#ifdef EPROTONOSUPPORT + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EPROTONOSUPPORT not defined"); + + fail = true; + +#ifdef EPROTOTYPE + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EPROTOTYPE not defined"); + + fail = true; + +#ifdef ERANGE + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ERANGE not defined"); + + fail = true; + +#ifdef EROFS + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EROFS not defined"); + + fail = true; + +#ifdef ESPIPE + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ESPIPE not defined"); + + fail = true; + +#ifdef ESRCH + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ESRCH not defined"); + + fail = true; + +#ifdef ESTALE + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ESTALE not defined"); + + fail = true; + +#ifdef ETIME + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ETIME not defined"); + + fail = true; + +#ifdef ETIMEDOUT + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ETIMEDOUT not defined"); + + fail = true; + +#ifdef ETXTBSY + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("ETXTBSY not defined"); + + fail = true; + +#ifdef EWOULDBLOCK + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EWOULDBLOCK not defined"); + + fail = true; + +#ifdef EXDEV + fail = false; +#endif + + if (fail != false) + atf_tc_fail_nonfatal("EXDEV not defined"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, errno_constants); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/t_glob.c b/contrib/netbsd-tests/include/t_glob.c new file mode 100644 index 0000000..da6a4ad --- /dev/null +++ b/contrib/netbsd-tests/include/t_glob.c @@ -0,0 +1,75 @@ +/* $NetBSD: t_glob.c,v 1.1 2011/04/10 08:35:48 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_glob.c,v 1.1 2011/04/10 08:35:48 jruoho Exp $"); + +#include +#include +#include + +ATF_TC(glob_types); +ATF_TC_HEAD(glob_types, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test glob(3) types"); +} + +ATF_TC_BODY(glob_types, tc) +{ + glob_t g; + + /* + * IEEE Std 1003.1-2008: + * + * "The header shall define the glob_t structure type, + * which shall include at least the following members: + * + * size_t gl_pathc Count of paths matched by pattern. + * char **gl_pathv Pointer to a list of matched pathnames. + * size_t gl_offs Slots to reserve at the beginning of gl_pathv." + * + * Verify that gl_pathc and gl_offs are unsigned; PR standards/21401. + */ + (void)memset(&g, 0, sizeof(glob_t)); + + g.gl_offs = g.gl_offs - 1; + g.gl_pathc = g.gl_pathc - 1; + + ATF_REQUIRE(g.gl_pathc > 0); + ATF_REQUIRE(g.gl_offs > 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, glob_types); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/t_inttypes.c b/contrib/netbsd-tests/include/t_inttypes.c new file mode 100644 index 0000000..d713615 --- /dev/null +++ b/contrib/netbsd-tests/include/t_inttypes.c @@ -0,0 +1,250 @@ +/* $NetBSD: t_inttypes.c,v 1.3 2013/10/19 17:44:37 christos Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include + +ATF_TC_WITHOUT_HEAD(int_fmtio); +ATF_TC_BODY(int_fmtio, tc) +{ + char buf[64]; + + int8_t i8 = 0; + int16_t i16 = 0; + int32_t i32 = 0; + int64_t i64 = 0; + int_least8_t il8 = 0; + int_least16_t il16 = 0; + int_least32_t il32 = 0; + int_least64_t il64 = 0; + int_fast8_t if8 = 0; + int_fast16_t if16 = 0; + int_fast32_t if32 = 0; + int_fast64_t if64 = 0; + intmax_t im = 0; + intptr_t ip = 0; + uint8_t ui8 = 0; + uint16_t ui16 = 0; + uint32_t ui32 = 0; + uint64_t ui64 = 0; + uint_least8_t uil8 = 0; + uint_least16_t uil16 = 0; + uint_least32_t uil32 = 0; + uint_least64_t uil64 = 0; + uint_fast8_t uif8 = 0; + uint_fast16_t uif16 = 0; + uint_fast32_t uif32 = 0; + uint_fast64_t uif64 = 0; + uintmax_t uim = 0; + uintptr_t uip = 0; + +#define PRINT(fmt, var) \ + snprintf(buf, sizeof(buf), "%" fmt, var) +#define SCAN(fmt, var) \ + sscanf(buf, "%" fmt, &var) + + PRINT(PRId8, i8); + PRINT(PRId16, i16); + PRINT(PRId32, i32); + PRINT(PRId64, i64); + PRINT(PRIdLEAST8, il8); + PRINT(PRIdLEAST16, il16); + PRINT(PRIdLEAST32, il32); + PRINT(PRIdLEAST64, il64); + PRINT(PRIdFAST8, if8); + PRINT(PRIdFAST16, if16); + PRINT(PRIdFAST32, if32); + PRINT(PRIdFAST64, if64); + PRINT(PRIdMAX, im); + PRINT(PRIdPTR, ip); + + PRINT(PRIi8, i8); + PRINT(PRIi16, i16); + PRINT(PRIi32, i32); + PRINT(PRIi64, i64); + PRINT(PRIiLEAST8, il8); + PRINT(PRIiLEAST16, il16); + PRINT(PRIiLEAST32, il32); + PRINT(PRIiLEAST64, il64); + PRINT(PRIiFAST8, if8); + PRINT(PRIiFAST16, if16); + PRINT(PRIiFAST32, if32); + PRINT(PRIiFAST64, if64); + PRINT(PRIiMAX, im); + PRINT(PRIiPTR, ip); + + PRINT(PRIo8, ui8); + PRINT(PRIo16, ui16); + PRINT(PRIo32, ui32); + PRINT(PRIo64, ui64); + PRINT(PRIoLEAST8, uil8); + PRINT(PRIoLEAST16, uil16); + PRINT(PRIoLEAST32, uil32); + PRINT(PRIoLEAST64, uil64); + PRINT(PRIoFAST8, uif8); + PRINT(PRIoFAST16, uif16); + PRINT(PRIoFAST32, uif32); + PRINT(PRIoFAST64, uif64); + PRINT(PRIoMAX, uim); + PRINT(PRIoPTR, uip); + + PRINT(PRIu8, ui8); + PRINT(PRIu16, ui16); + PRINT(PRIu32, ui32); + PRINT(PRIu64, ui64); + PRINT(PRIuLEAST8, uil8); + PRINT(PRIuLEAST16, uil16); + PRINT(PRIuLEAST32, uil32); + PRINT(PRIuLEAST64, uil64); + PRINT(PRIuFAST8, uif8); + PRINT(PRIuFAST16, uif16); + PRINT(PRIuFAST32, uif32); + PRINT(PRIuFAST64, uif64); + PRINT(PRIuMAX, uim); + PRINT(PRIuPTR, uip); + + PRINT(PRIx8, ui8); + PRINT(PRIx16, ui16); + PRINT(PRIx32, ui32); + PRINT(PRIx64, ui64); + PRINT(PRIxLEAST8, uil8); + PRINT(PRIxLEAST16, uil16); + PRINT(PRIxLEAST32, uil32); + PRINT(PRIxLEAST64, uil64); + PRINT(PRIxFAST8, uif8); + PRINT(PRIxFAST16, uif16); + PRINT(PRIxFAST32, uif32); + PRINT(PRIxFAST64, uif64); + PRINT(PRIxMAX, uim); + PRINT(PRIxPTR, uip); + + PRINT(PRIX8, ui8); + PRINT(PRIX16, ui16); + PRINT(PRIX32, ui32); + PRINT(PRIX64, ui64); + PRINT(PRIXLEAST8, uil8); + PRINT(PRIXLEAST16, uil16); + PRINT(PRIXLEAST32, uil32); + PRINT(PRIXLEAST64, uil64); + PRINT(PRIXFAST8, uif8); + PRINT(PRIXFAST16, uif16); + PRINT(PRIXFAST32, uif32); + PRINT(PRIXFAST64, uif64); + PRINT(PRIXMAX, uim); + PRINT(PRIXPTR, uip); + + + SCAN(SCNd8, i8); + SCAN(SCNd16, i16); + SCAN(SCNd32, i32); + SCAN(SCNd64, i64); + SCAN(SCNdLEAST8, il8); + SCAN(SCNdLEAST16, il16); + SCAN(SCNdLEAST32, il32); + SCAN(SCNdLEAST64, il64); + SCAN(SCNdFAST8, if8); + SCAN(SCNdFAST16, if16); + SCAN(SCNdFAST32, if32); + SCAN(SCNdFAST64, if64); + SCAN(SCNdMAX, im); + SCAN(SCNdPTR, ip); + + SCAN(SCNi8, i8); + SCAN(SCNi16, i16); + SCAN(SCNi32, i32); + SCAN(SCNi64, i64); + SCAN(SCNiLEAST8, il8); + SCAN(SCNiLEAST16, il16); + SCAN(SCNiLEAST32, il32); + SCAN(SCNiLEAST64, il64); + SCAN(SCNiFAST8, if8); + SCAN(SCNiFAST16, if16); + SCAN(SCNiFAST32, if32); + SCAN(SCNiFAST64, if64); + SCAN(SCNiMAX, im); + SCAN(SCNiPTR, ip); + + SCAN(SCNo8, ui8); + SCAN(SCNo16, ui16); + SCAN(SCNo32, ui32); + SCAN(SCNo64, ui64); + SCAN(SCNoLEAST8, uil8); + SCAN(SCNoLEAST16, uil16); + SCAN(SCNoLEAST32, uil32); + SCAN(SCNoLEAST64, uil64); + SCAN(SCNoFAST8, uif8); + SCAN(SCNoFAST16, uif16); + SCAN(SCNoFAST32, uif32); + SCAN(SCNoFAST64, uif64); + SCAN(SCNoMAX, uim); + SCAN(SCNoPTR, uip); + + SCAN(SCNu8, ui8); + SCAN(SCNu16, ui16); + SCAN(SCNu32, ui32); + SCAN(SCNu64, ui64); + SCAN(SCNuLEAST8, uil8); + SCAN(SCNuLEAST16, uil16); + SCAN(SCNuLEAST32, uil32); + SCAN(SCNuLEAST64, uil64); + SCAN(SCNuFAST8, uif8); + SCAN(SCNuFAST16, uif16); + SCAN(SCNuFAST32, uif32); + SCAN(SCNuFAST64, uif64); + SCAN(SCNuMAX, uim); + SCAN(SCNuPTR, uip); + + SCAN(SCNx8, ui8); + SCAN(SCNx16, ui16); + SCAN(SCNx32, ui32); + SCAN(SCNx64, ui64); + SCAN(SCNxLEAST8, uil8); + SCAN(SCNxLEAST16, uil16); + SCAN(SCNxLEAST32, uil32); + SCAN(SCNxLEAST64, uil64); + SCAN(SCNxFAST8, uif8); + SCAN(SCNxFAST16, uif16); + SCAN(SCNxFAST32, uif32); + SCAN(SCNxFAST64, uif64); + SCAN(SCNxMAX, uim); + SCAN(SCNxPTR, uip); + +#undef SCAN +#undef PRINT +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, int_fmtio); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/t_limits.c b/contrib/netbsd-tests/include/t_limits.c new file mode 100644 index 0000000..625750a --- /dev/null +++ b/contrib/netbsd-tests/include/t_limits.c @@ -0,0 +1,287 @@ +/* $NetBSD: t_limits.c,v 1.2 2011/04/04 18:02:01 jruoho Exp $ */ + +/* + * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Copyright (c) 2009, Stathis Kamperis + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_limits.c,v 1.2 2011/04/04 18:02:01 jruoho Exp $"); + +#include + +#include + +struct psxentry { + const char *psx_desc; + int psx_constant; + int psx_minval; +} psxtable[] = { + + /* + * POSIX symbolic constants. + */ +#ifdef _POSIX_AIO_LISTIO_MAX + { "_POSIX_AIO_LISTIO_MAX", _POSIX_AIO_LISTIO_MAX, 2 }, +#endif +#ifdef _POSIX_AIO_MAX + { "_POSIX_AIO_MAX", _POSIX_AIO_MAX, 1 }, +#endif +#ifdef _POSIX_ARG_MAX + { "_POSIX_ARG_MAX", _POSIX_ARG_MAX, 4096 }, +#endif +#ifdef _POSIX_CHILD_MAX + { "_POSIX_CHILD_MAX" , _POSIX_CHILD_MAX, 25 }, +#endif +#ifdef _POSIX_DELAYTIMER_MAX + { "_POSIX_DELAYTIMER_MAX", _POSIX_DELAYTIMER_MAX, 32 }, +#endif +#ifdef _POSIX_HOST_NAME_MAX + { "_POSIX_HOST_NAME_MAX", _POSIX_HOST_NAME_MAX, 255 }, +#endif +#ifdef _POSIX_LINK_MAX + { "_POSIX_LINK_MAX", _POSIX_LINK_MAX, 8 }, +#endif +#ifdef _POSIX_LOGIN_NAME_MAX + { "_POSIX_LOGIN_NAME_MAX", _POSIX_LOGIN_NAME_MAX, 9 }, +#endif +#ifdef _POSIX_MAX_CANON + { "_POSIX_MAX_CANON", _POSIX_MAX_CANON, 255 }, +#endif +#ifdef _POSIX_MAX_INPUT + { "_POSIX_MAX_INPUT", _POSIX_MAX_INPUT, 255 }, +#endif +#ifdef _POSIX_MQ_OPEN_MAX + { "_POSIX_MQ_OPEN_MAX", _POSIX_MQ_OPEN_MAX, 8 }, +#endif +#ifdef _POSIX_MQ_PRIO_MAX + { "_POSIX_MQ_PRIO_MAX", _POSIX_MQ_PRIO_MAX, 32 }, +#endif +#ifdef _POSIX_NAME_MAX + { "_POSIX_NAME_MAX", _POSIX_NAME_MAX, 9 }, +#endif +#ifdef _POSIX_NGROUPS_MAX + { "_POSIX_NGROUPS_MAX", _POSIX_NGROUPS_MAX, 8 }, +#endif +#ifdef _POSIX_OPEN_MAX + { "_POSIX_OPEN_MAX", _POSIX_OPEN_MAX, 20 }, +#endif +#ifdef _POSIX_PATH_MAX + { "_POSIX_PATH_MAX", _POSIX_PATH_MAX, 256 }, +#endif +#ifdef _POSIX_PIPE_BUF + { "_POSIX_PIPE_BUF", _POSIX_PIPE_BUF, 512 }, +#endif +#ifdef _POSIX_RE_DUP_MAX + { "_POSIX_RE_DUP_MAX", _POSIX_RE_DUP_MAX, 255 }, +#endif +#ifdef _POSIX_RTSIG_MAX + { "_POSIX_RTSIG_MAX", _POSIX_RTSIG_MAX, 8 }, +#endif +#ifdef _POSIX_SEM_NSEMS_MAX + { "_POSIX_SEM_NSEMS_MAX", _POSIX_SEM_NSEMS_MAX, 256 }, +#endif +#ifdef _POSIX_SEM_VALUE_MAX + { "_POSIX_SEM_VALUE_MAX", _POSIX_SEM_VALUE_MAX, 32767}, +#endif +#ifdef _POSIX_SIGQUEUE_MAX + { "_POSIX_SIGQUEUE_MAX", _POSIX_SIGQUEUE_MAX, 32 }, +#endif +#ifdef _POSIX_SSIZE_MAX + { "_POSIX_SSIZE_MAX", _POSIX_SSIZE_MAX, 32767}, +#endif +#ifdef _POSIX_STREAM_MAX + { "_POSIX_STREAM_MAX", _POSIX_STREAM_MAX, 8 }, +#endif +#ifdef _POSIX_SS_REPL_MAX + { "_POSIX_SS_REPL_MAX", _POSIX_SS_REPL_MAX, 4 }, +#endif +#ifdef _POSIX_SYMLINK_MAX + { "_POSIX_SYMLINK_MAX", _POSIX_SYMLINK_MAX, 255 }, +#endif +#ifdef _POSIX_SYMLOOP_MAX + { "_POSIX_SYMLOOP_MAX", _POSIX_SYMLOOP_MAX, 8 }, +#endif +#ifdef _POSIX_THREAD_DESTRUCTOR_ITERATIONS + { "_POSIX_THREAD_DESTRUCTOR_ITERATIONS", + _POSIX_THREAD_DESTRUCTOR_ITERATIONS, 4 }, +#endif +#ifdef _POSIX_THREAD_KEYS_MAX + { "_POSIX_THREAD_KEYS_MAX", _POSIX_THREAD_KEYS_MAX, 128 }, +#endif +#ifdef _POSIX_THREAD_THREADS_MAX + { "_POSIX_THREAD_THREADS_MAX", _POSIX_THREAD_THREADS_MAX, 64 }, +#endif +#ifdef _POSIX_TIMER_MAX + { "_POSIX_TIMER_MAX", _POSIX_TIMER_MAX, 32 }, +#endif +#ifdef _POSIX_TRACE_EVENT_NAME_MAX + { "_POSIX_TRACE_EVENT_NAME_MAX",_POSIX_TRACE_EVENT_NAME_MAX, 30 }, +#endif +#ifdef _POSIX_TRACE_NAME_MAX + { "_POSIX_TRACE_NAME_MAX", _POSIX_TRACE_NAME_MAX, 8 }, +#endif +#ifdef _POSIX_TRACE_SYS_MAX + { "_POSIX_TRACE_SYS_MAX", _POSIX_TRACE_SYS_MAX, 8 }, +#endif +#ifdef _POSIX_TRACE_USER_EVENT_MAX + { "_POSIX_TRACE_USER_EVENT_MAX",_POSIX_TRACE_USER_EVENT_MAX, 32 }, +#endif +#ifdef _POSIX_TTY_NAME_MAX + { "_POSIX_TTY_NAME_MAX", _POSIX_TTY_NAME_MAX, 9 }, +#endif +#ifdef _POSIX_TZNAME_MAX + { "_POSIX_TZNAME_MAX", _POSIX_TZNAME_MAX, 6 }, +#endif +#ifdef _POSIX2_BC_BASE_MAX + { "_POSIX2_BC_BASE_MAX", _POSIX2_BC_BASE_MAX, 99 }, +#endif +#ifdef _POSIX2_BC_DIM_MAX + { "_POSIX2_BC_DIM_MAX", _POSIX2_BC_DIM_MAX, 2048 }, +#endif +#ifdef _POSIX2_BC_SCALE_MAX + { "_POSIX2_BC_SCALE_MAX", _POSIX2_BC_SCALE_MAX, 99 }, +#endif +#ifdef _POSIX2_BC_STRING_MAX + { "_POSIX2_BC_STRING_MAX", _POSIX2_BC_STRING_MAX, 1000 }, +#endif +#ifdef _POSIX2_CHARCLASS_NAME_MAX + { "_POSIX2_CHARCLASS_NAME_MAX", _POSIX2_CHARCLASS_NAME_MAX, 14 }, +#endif +#ifdef _POSIX2_COLL_WEIGHTS_MAX + { "_POSIX2_COLL_WEIGHTS_MAX", _POSIX2_COLL_WEIGHTS_MAX, 2 }, +#endif +#ifdef _POSIX2_EXPR_NEST_MAX + { "_POSIX2_EXPR_NEST_MAX", _POSIX2_EXPR_NEST_MAX, 32 }, +#endif +#ifdef _POSIX2_LINE_MAX + { "_POSIX2_LINE_MAX", _POSIX2_LINE_MAX, 2048 }, +#endif +#ifdef _POSIX2_RE_DUP_MAX + { "_POSIX2_RE_DUP_MAX", _POSIX2_RE_DUP_MAX, 255 }, +#endif +#ifdef _XOPEN_IOV_MAX + { "_XOPEN_IOV_MAX", _XOPEN_IOV_MAX, 16 }, +#endif +#ifdef _XOPEN_NAME_MAX + { "_XOPEN_NAME_MAX", _XOPEN_NAME_MAX, 255 }, +#endif +#ifdef _XOPEN_PATH_MAX + { "_XOPEN_PATH_MAX", _XOPEN_PATH_MAX, 1024 }, +#endif + + /* + * Other invariant values. + */ +#ifdef NL_ARGMAX + { "NL_ARGMAX", NL_ARGMAX, 9 }, +#endif +#ifdef NL_LANGMAX + { "NL_LANGMAX", NL_LANGMAX, 14 }, +#endif +#ifdef NL_MSGMAX + { "NL_MSGMAX", NL_MSGMAX, 32767}, +#endif +#ifdef NL_SETMAX + { "NL_SETMAX", NL_SETMAX, 255 }, +#endif +#ifdef NL_TEXTMAX +#ifdef _POSIX2_LINE_MAX + { "NL_TEXTMAX", NL_TEXTMAX, _POSIX2_LINE_MAX}, +#endif +#endif +#ifdef NZERO + { "NZERO", NZERO, 20 }, +#endif +}; + +ATF_TC_WITHOUT_HEAD(char); +ATF_TC_BODY(char, tc) +{ + ATF_CHECK(CHAR_MIN < UCHAR_MAX); +} + +ATF_TC(posix); +ATF_TC_HEAD(posix, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test POSIX limits"); +} + +ATF_TC_BODY(posix, tc) +{ + size_t i; + + for (i = 0; i < __arraycount(psxtable); i++) { + + if (psxtable[i].psx_constant < psxtable[i].psx_minval) { + + atf_tc_fail("%s is less than the minimum", + psxtable[i].psx_desc); + } + } +} + +ATF_TC_WITHOUT_HEAD(short); +ATF_TC_BODY(short, tc) +{ + ATF_CHECK(SHRT_MIN < USHRT_MAX); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, char); + ATF_TP_ADD_TC(tp, posix); + ATF_TP_ADD_TC(tp, short); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/t_netdb.c b/contrib/netbsd-tests/include/t_netdb.c new file mode 100644 index 0000000..c7f946f --- /dev/null +++ b/contrib/netbsd-tests/include/t_netdb.c @@ -0,0 +1,244 @@ +/* $NetBSD: t_netdb.c,v 1.2 2011/04/25 20:51:14 njoly Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_netdb.c,v 1.2 2011/04/25 20:51:14 njoly Exp $"); + +#include +#include + +ATF_TC(netdb_constants); +ATF_TC_HEAD(netdb_constants, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test constants in "); +} + +ATF_TC_BODY(netdb_constants, tc) +{ + bool fail; + + /* + * The following definitions should be available + * according to IEEE Std 1003.1-2008, issue 7. + */ + atf_tc_expect_fail("PR standards/44777"); + + fail = true; + +#ifdef AI_PASSIVE + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("AI_PASSIVE not defined"); + + fail = true; + +#ifdef AI_CANONNAME + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("AI_CANONNAME not defined"); + + fail = true; + +#ifdef AI_NUMERICHOST + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("AI_NUMERICHOST not defined"); + + fail = true; + +#ifdef AI_NUMERICSERV + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("AI_NUMERICSERV not defined"); + + fail = true; + +#ifdef AI_V4MAPPED + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("AI_V4MAPPED not defined"); + + fail = true; + +#ifdef AI_ALL + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("AI_ALL not defined"); + + fail = true; + +#ifdef AI_ADDRCONFIG + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("AI_ADDRCONFIG not defined"); + + fail = true; + +#ifdef NI_NOFQDN + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("NI_NOFQDN not defined"); + + fail = true; + +#ifdef NI_NUMERICHOST + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("NI_NUMERICHOST not defined"); + + fail = true; + +#ifdef NI_NAMEREQD + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("NI_NAMEREQD not defined"); + + fail = true; + +#ifdef NI_NUMERICSERV + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("NI_NUMERICSERV not defined"); + + fail = true; + +#ifdef NI_NUMERICSCOPE + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("NI_NUMERICSCOPE not defined"); + + fail = true; + +#ifdef NI_DGRAM + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("NI_DGRAM not defined"); + + fail = true; + +#ifdef EAI_AGAIN + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EAI_AGAIN not defined"); + + fail = true; + +#ifdef EAI_BADFLAGS + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EAI_BADFLAGS not defined"); + + fail = true; + +#ifdef EAI_FAIL + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EAI_FAIL not defined"); + + fail = true; + +#ifdef EAI_FAMILY + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EAI_FAMILY not defined"); + + fail = true; + +#ifdef EAI_MEMORY + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EAI_MEMORY not defined"); + + fail = true; + +#ifdef EAI_NONAME + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EAI_NONAME not defined"); + + fail = true; + +#ifdef EAI_SERVICE + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EAI_SERVICE not defined"); + + fail = true; + +#ifdef EAI_SOCKTYPE + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EAI_SOCKTYPE not defined"); + + fail = true; + +#ifdef EAI_SYSTEM + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EAI_SYSTEM not defined"); + + fail = true; + +#ifdef EAI_OVERFLOW + fail = false; +#endif + if (fail != false) + atf_tc_fail_nonfatal("EAI_OVERFLOW not defined"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, netdb_constants); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/t_paths.c b/contrib/netbsd-tests/include/t_paths.c new file mode 100644 index 0000000..52a150e --- /dev/null +++ b/contrib/netbsd-tests/include/t_paths.c @@ -0,0 +1,215 @@ +/* $NetBSD: t_paths.c,v 1.16 2015/05/07 06:23:23 pgoyette Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_paths.c,v 1.16 2015/05/07 06:23:23 pgoyette Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#define PATH_DEV __BIT(0) /* A device node */ +#define PATH_DIR __BIT(1) /* A directory */ +#define PATH_FILE __BIT(2) /* A file */ +#define PATH_ROOT __BIT(3) /* Access for root only */ +#define PATH_OPT __BIT(3) /* Optional, ENODEV if not supported */ + +static const struct { + const char *path; + int flags; +} paths[] = { + { _PATH_AUDIO, PATH_DEV }, + { _PATH_AUDIO0, PATH_DEV }, + { _PATH_AUDIOCTL, PATH_DEV }, + { _PATH_AUDIOCTL0, PATH_DEV }, + { _PATH_BPF, PATH_DEV | PATH_ROOT }, + { _PATH_CLOCKCTL, PATH_DEV | PATH_ROOT }, + { _PATH_CONSOLE, PATH_DEV | PATH_ROOT }, + { _PATH_CONSTTY, PATH_DEV | PATH_ROOT }, + { _PATH_CPUCTL, PATH_DEV }, + { _PATH_CSMAPPER, PATH_DIR }, + { _PATH_DEFTAPE, PATH_DEV | PATH_ROOT }, + { _PATH_DEVCDB, PATH_FILE }, + { _PATH_DEVDB, PATH_FILE }, + { _PATH_DEVNULL, PATH_DEV }, + { _PATH_DRUM, PATH_DEV | PATH_ROOT }, + { _PATH_ESDB, PATH_DIR }, + { _PATH_FTPUSERS, PATH_FILE }, + { _PATH_GETTYTAB, PATH_FILE }, + { _PATH_I18NMODULE, PATH_DIR }, + { _PATH_ICONV, PATH_DIR }, + { _PATH_KMEM, PATH_DEV | PATH_ROOT }, + { _PATH_KSYMS, PATH_DEV }, + { _PATH_KVMDB, PATH_FILE }, + { _PATH_LOCALE, PATH_DIR }, + { _PATH_MAILDIR, PATH_DIR }, + { _PATH_MAN, PATH_DIR }, + { _PATH_MEM, PATH_DEV | PATH_ROOT }, + { _PATH_MIXER, PATH_DEV }, + { _PATH_MIXER0, PATH_DEV }, + { _PATH_NOLOGIN, PATH_FILE }, + { _PATH_POWER, PATH_DEV | PATH_ROOT | PATH_OPT }, + { _PATH_PRINTCAP, PATH_FILE }, + { _PATH_PUD, PATH_DEV | PATH_ROOT }, + { _PATH_PUFFS, PATH_DEV | PATH_ROOT }, + { _PATH_RANDOM, PATH_DEV }, + { _PATH_SENDMAIL, PATH_FILE }, + { _PATH_SHELLS, PATH_FILE }, + { _PATH_SKEYKEYS, PATH_FILE | PATH_ROOT }, + { _PATH_SOUND, PATH_DEV }, + { _PATH_SOUND0, PATH_DEV }, + { _PATH_SYSMON, PATH_DEV | PATH_OPT }, + { _PATH_TTY, PATH_DEV }, + { _PATH_UNIX, PATH_FILE | PATH_ROOT }, + { _PATH_URANDOM, PATH_DEV }, + { _PATH_VIDEO, PATH_DEV }, + { _PATH_VIDEO0, PATH_DEV }, + { _PATH_WATCHDOG, PATH_DEV | PATH_OPT }, + + { _PATH_DEV, PATH_DIR }, + { _PATH_DEV_PTS, PATH_DIR }, + { _PATH_EMUL_AOUT, PATH_DIR }, + { _PATH_TMP, PATH_DIR }, + { _PATH_VARDB, PATH_DIR }, + { _PATH_VARRUN, PATH_DIR }, + { _PATH_VARTMP, PATH_DIR }, + + { _PATH_BSHELL, PATH_FILE }, + { _PATH_CSHELL, PATH_FILE }, + { _PATH_VI, PATH_FILE }, +}; + +ATF_TC(paths); +ATF_TC_HEAD(paths, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test for "); +} + +ATF_TC_BODY(paths, tc) +{ + struct stat st; + uid_t uid; + mode_t m; + size_t i; + int fd; + +#if defined(__sparc__) + atf_tc_skip("PR port-sparc/45580"); +#endif + + uid = getuid(); + + for (i = 0; i < __arraycount(paths); i++) { + + (void)fprintf(stderr, "testing '%s'\n", paths[i].path); + + errno = 0; + fd = open(paths[i].path, O_RDONLY); + + if (fd < 0) { + + switch (errno) { + + case ENODEV: + if ((paths[i].flags & PATH_OPT) == 0) { + + atf_tc_fail("Required path %s does " + "not exist", paths[i].path); + } + break; + + case EPERM: /* FALLTHROUGH */ + case EACCES: /* FALLTHROUGH */ + + if ((paths[i].flags & PATH_ROOT) == 0) { + + atf_tc_fail("UID %u failed to open %s, " + "error %d", (uint32_t)uid, + paths[i].path, errno); + } + + case EBUSY: /* FALLTHROUGH */ + case ENXIO: /* FALLTHROUGH */ + case ENOENT: /* FALLTHROUGH */ + + default: + continue; + } + } + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(fstat(fd, &st) == 0); + + m = st.st_mode; + + if ((paths[i].flags & PATH_DEV) != 0) { + + ATF_CHECK(S_ISBLK(m) != 0 || S_ISCHR(m) != 0); + + ATF_CHECK((paths[i].flags & PATH_DIR) == 0); + ATF_CHECK((paths[i].flags & PATH_FILE) == 0); + } + + if ((paths[i].flags & PATH_DIR) != 0) { + + ATF_CHECK(S_ISDIR(m) != 0); + + ATF_CHECK((paths[i].flags & PATH_DEV) == 0); + ATF_CHECK((paths[i].flags & PATH_FILE) == 0); + } + + if ((paths[i].flags & PATH_FILE) != 0) { + + ATF_CHECK(S_ISREG(m) != 0); + + ATF_CHECK((paths[i].flags & PATH_DEV) == 0); + ATF_CHECK((paths[i].flags & PATH_DIR) == 0); + } + + ATF_REQUIRE(close(fd) == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, paths); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/include/t_stdint.c b/contrib/netbsd-tests/include/t_stdint.c new file mode 100644 index 0000000..6a57d9a --- /dev/null +++ b/contrib/netbsd-tests/include/t_stdint.c @@ -0,0 +1,57 @@ +/* $NetBSD: t_stdint.c,v 1.1 2010/07/17 19:26:27 jmmv Exp $ */ + +/* + * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_stdint.c,v 1.1 2010/07/17 19:26:27 jmmv Exp $"); + +#include + +#include + +ATF_TC_WITHOUT_HEAD(int8); +ATF_TC_BODY(int8, tc) +{ + ATF_CHECK(INT8_MIN < UINT8_MAX); +} + +ATF_TC_WITHOUT_HEAD(int16); +ATF_TC_BODY(int16, tc) +{ + ATF_CHECK(INT16_MIN < UINT16_MAX); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, int8); + ATF_TP_ADD_TC(tp, int16); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/ipf/expected/.cvsignore b/contrib/netbsd-tests/ipf/expected/.cvsignore new file mode 100644 index 0000000..47a4237 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/.cvsignore @@ -0,0 +1 @@ +i19 diff --git a/contrib/netbsd-tests/ipf/expected/bpf-f1 b/contrib/netbsd-tests/ipf/expected/bpf-f1 new file mode 100644 index 0000000..85ce84c --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/bpf-f1 @@ -0,0 +1,20 @@ +nomatch +pass +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +pass +-------- +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/bpf1 b/contrib/netbsd-tests/ipf/expected/bpf1 new file mode 100644 index 0000000..76381a7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/bpf1 @@ -0,0 +1,4 @@ +pass in bpf-v4 { "0x20 0 0 0xc 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass out bpf-v4 { "0 0 0 0 0x20 0 0 0xc 0x15 0 0x1 0x1010101 0x6 0 0 0x1 0x6 0 0 0" } +pass in bpf-v4 { "0x20 0 0 0x10 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass out bpf-v4 { "0 0 0 0 0x20 0 0 0x10 0x15 0 0x1 0x1010101 0x6 0 0 0x1 0x6 0 0 0" } diff --git a/contrib/netbsd-tests/ipf/expected/f1 b/contrib/netbsd-tests/ipf/expected/f1 new file mode 100644 index 0000000..86d9592 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f1 @@ -0,0 +1,20 @@ +block +block +nomatch +nomatch +-------- +pass +pass +nomatch +nomatch +-------- +nomatch +nomatch +block +block +-------- +nomatch +nomatch +pass +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f10 b/contrib/netbsd-tests/ipf/expected/f10 new file mode 100644 index 0000000..da6c312 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f10 @@ -0,0 +1,126 @@ +nomatch +block +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +nomatch +nomatch +pass +-------- +block +block +block +nomatch +nomatch +block +-------- +pass +pass +pass +nomatch +nomatch +pass +-------- +block +block +nomatch +nomatch +nomatch +block +-------- +pass +pass +nomatch +nomatch +nomatch +pass +-------- +block +block +block +block +block +block +-------- +pass +pass +pass +pass +pass +pass +-------- +nomatch +block +block +block +nomatch +block +-------- +nomatch +pass +pass +pass +nomatch +pass +-------- +nomatch +pass +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +block +block +block +block +block +-------- +nomatch +pass +pass +pass +pass +pass +-------- +block +block +nomatch +block +nomatch +block +-------- +pass +pass +nomatch +pass +nomatch +pass +-------- +block +block +block +block +block +block +-------- +pass +pass +pass +pass +pass +pass +-------- +block +block +block +nomatch +nomatch +block +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f11 b/contrib/netbsd-tests/ipf/expected/f11 new file mode 100644 index 0000000..d7ab889 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f11 @@ -0,0 +1,283 @@ +pass +nomatch +nomatch +pass +pass +nomatch +pass +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +1 pass in proto tcp from any to any port = 23 flags S/SA keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +-------- +block +nomatch +nomatch +block +block +nomatch +block +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +1 block in proto tcp from any to any port = 23 flags S/SA keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +2 pass in proto udp from any to any port = 53 keep frags +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +nomatch +nomatch +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +2 block in proto udp from any to any port = 53 keep frags +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +nomatch +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +4:udp src:2.2.2.2,2 dst:4.4.4.4,53 240 + FWD: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[e1],X[] out X[],X[] + Sync status: not synchronized +4:udp src:1.1.1.1,1 dst:4.4.4.4,53 24 + FWD: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + REV: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[e1],X[e0] out X[],X[] + Sync status: not synchronized +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +2 pass in proto udp from any to any port = 53 keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +nomatch +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +4:udp src:2.2.2.2,2 dst:4.4.4.4,53 240 + FWD: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008401 = block in keep state + interfaces: in X[e1],X[] out X[],X[] + Sync status: not synchronized +4:udp src:1.1.1.1,1 dst:4.4.4.4,53 24 + FWD: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + REV: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + tag 0 pass 0x2008401 = block in keep state + interfaces: in X[e1],X[e0] out X[],X[] + Sync status: not synchronized +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +2 block in proto udp from any to any port = 53 keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +pass +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +4:tcp src:1.1.1.1,1 dst:2.1.2.2,25 state:3/4 864000 + 2:66 4096<<0:16384<<0 + FWD: IN pkts 1 bytes 40 OUT pkts 0 bytes 0 + REV: IN pkts 1 bytes 40 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[e0],X[e1] out X[],X[] + Sync status: not synchronized +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +1 pass in on e0 proto tcp from any to any port = 25 keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f12 b/contrib/netbsd-tests/ipf/expected/f12 new file mode 100644 index 0000000..094d8c0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f12 @@ -0,0 +1,60 @@ +pass +pass +pass +bad-packet +nomatch +nomatch +bad-packet +nomatch +nomatch +-------- +pass +pass +pass +bad-packet +nomatch +nomatch +bad-packet +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +bad-packet +block +nomatch +bad-packet +nomatch +nomatch +-------- +nomatch +nomatch +block +bad-packet +block +nomatch +bad-packet +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +bad-packet +nomatch +nomatch +bad-packet +nomatch +pass +-------- +nomatch +nomatch +nomatch +bad-packet +nomatch +nomatch +bad-packet +nomatch +block +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f13 b/contrib/netbsd-tests/ipf/expected/f13 new file mode 100644 index 0000000..ac7947b --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f13 @@ -0,0 +1,180 @@ +pass +bad-packet +nomatch +pass +bad-packet +nomatch +nomatch +bad-packet +nomatch +bad-packet +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +block +bad-packet +nomatch +block +bad-packet +nomatch +nomatch +bad-packet +nomatch +bad-packet +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +bad-packet +nomatch +nomatch +bad-packet +nomatch +nomatch +bad-packet +pass +bad-packet +nomatch +nomatch +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +bad-packet +nomatch +nomatch +bad-packet +nomatch +nomatch +bad-packet +block +bad-packet +nomatch +nomatch +block +block +block +nomatch +nomatch +nomatch +nomatch +-------- +block +bad-packet +nomatch +pass +bad-packet +nomatch +nomatch +bad-packet +nomatch +bad-packet +nomatch +nomatch +nomatch +nomatch +nomatch +pass +nomatch +pass +pass +-------- +block +bad-packet +nomatch +block +bad-packet +nomatch +nomatch +bad-packet +nomatch +bad-packet +nomatch +nomatch +nomatch +nomatch +nomatch +block +nomatch +block +block +-------- +nomatch +bad-packet +nomatch +nomatch +bad-packet +nomatch +nomatch +bad-packet +pass +bad-packet +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +-------- +block +bad-packet +nomatch +pass +bad-packet +nomatch +nomatch +bad-packet +nomatch +bad-packet +nomatch +nomatch +nomatch +nomatch +nomatch +pass +block +block +pass +-------- +block +bad-packet +nomatch +pass +bad-packet +nomatch +nomatch +bad-packet +nomatch +bad-packet +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f14 b/contrib/netbsd-tests/ipf/expected/f14 new file mode 100644 index 0000000..1c6ed5c --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f14 @@ -0,0 +1,48 @@ +block +nomatch +block +block +block +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +nomatch +nomatch +pass +pass +-------- +block +nomatch +nomatch +nomatch +block +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +block +block +block +block +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f15 b/contrib/netbsd-tests/ipf/expected/f15 new file mode 100644 index 0000000..9b31258 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f15 @@ -0,0 +1,9 @@ +block return-rst +pass +block return-icmp +pass +block +nomatch +pass +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f16 b/contrib/netbsd-tests/ipf/expected/f16 new file mode 100644 index 0000000..b6cb3fa --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f16 @@ -0,0 +1,9 @@ +block +block +pass +block +pass +pass +block +block +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f17 b/contrib/netbsd-tests/ipf/expected/f17 new file mode 100644 index 0000000..c586e5b --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f17 @@ -0,0 +1,7 @@ +pass +block return-rst +pass +pass +pass +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f18 b/contrib/netbsd-tests/ipf/expected/f18 new file mode 100644 index 0000000..1af5de5 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f18 @@ -0,0 +1,27 @@ +pass +pass +pass +pass +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +2 pass in inet from 1.1.1.1/32 to any +Rules configured (set 0, out) +2 pass out inet from 2.2.2.2/32 to any +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +1 count in inet from 1.1.1.1/32 to 3.3.3.3/32 +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +1 count out inet from 2.2.2.2/32 to 4.4.4.4/32 +Accounting rules configured (set 1, out) +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f19 b/contrib/netbsd-tests/ipf/expected/f19 new file mode 100644 index 0000000..5ee2e9d --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f19 @@ -0,0 +1,10 @@ +pass +pass +pass +nomatch +-------- +pass +nomatch +nomatch +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f2 b/contrib/netbsd-tests/ipf/expected/f2 new file mode 100644 index 0000000..7093a41 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f2 @@ -0,0 +1,42 @@ +block +block +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +block +block +nomatch +nomatch +-------- +nomatch +nomatch +pass +pass +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +block +block +-------- +nomatch +nomatch +nomatch +nomatch +pass +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f20 b/contrib/netbsd-tests/ipf/expected/f20 new file mode 100644 index 0000000..86308a0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f20 @@ -0,0 +1,3 @@ +pass +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f21 b/contrib/netbsd-tests/ipf/expected/f21 new file mode 100644 index 0000000..525daca --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f21 @@ -0,0 +1,5 @@ +pass +pass +nomatch +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f22 b/contrib/netbsd-tests/ipf/expected/f22 new file mode 100644 index 0000000..525daca --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f22 @@ -0,0 +1,5 @@ +pass +pass +nomatch +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f24 b/contrib/netbsd-tests/ipf/expected/f24 new file mode 100644 index 0000000..801abd3 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f24 @@ -0,0 +1,5 @@ +pass +pass +pass +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f25 b/contrib/netbsd-tests/ipf/expected/f25 new file mode 100644 index 0000000..a87b084 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f25 @@ -0,0 +1,35 @@ +pass +pass +pass +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +4:udp src:192.168.1.235,8008 dst:239.255.255.250,1900 240 + FWD: IN pkts 1 bytes 129 OUT pkts 0 bytes 0 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[hme0],X[] out X[],X[] + Sync status: not synchronized +4:udp src:192.168.1.235,8008 dst:192.168.1.254,1900 24 + FWD: IN pkts 1 bytes 129 OUT pkts 0 bytes 0 + REV: IN pkts 0 bytes 0 OUT pkts 1 bytes 264 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[hme0],X[] out X[],X[hme0] + Sync status: not synchronized +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +2 pass in on hme0 proto udp from any to any with mcast keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f26 b/contrib/netbsd-tests/ipf/expected/f26 new file mode 100644 index 0000000..9e4d62b --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f26 @@ -0,0 +1,84 @@ +pass +pass +pass +pass +pass +pass +nomatch +pass +pass +nomatch +pass +pass +nomatch +-------- +pass +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +pass +nomatch +pass +pass +nomatch +pass +pass +nomatch +-------- +pass +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f27 b/contrib/netbsd-tests/ipf/expected/f27 new file mode 100644 index 0000000..c62f588 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f27 @@ -0,0 +1,90 @@ +pass +pass +pass +pass +pass +pass +nomatch +pass +pass +nomatch +pass +pass +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +pass +nomatch +pass +pass +nomatch +pass +pass +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f28 b/contrib/netbsd-tests/ipf/expected/f28 new file mode 100644 index 0000000..e5867e6 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f28 @@ -0,0 +1,32 @@ +block +block +block +> nic0 ip #0 20(20) 0 4.4.3.1 > 4.2.3.2 +pass +> nic1 ip #0 20(20) 0 4.4.1.1 > 4.2.1.2 +pass +> nic2 ip #0 20(20) 0 4.4.2.1 > 4.2.2.2 +pass +> nic3 ip #0 20(20) 0 4.4.3.1 > 4.2.3.2 +pass +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +7 block in all +4 pass in on nic0 to dstlist/spread inet from 4.4.0.0/16 to any +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/f29 b/contrib/netbsd-tests/ipf/expected/f29 new file mode 100644 index 0000000..a650c1b --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f29 @@ -0,0 +1,64 @@ +block +block +block +> nic0 ip #0 28(20) 17 4.4.3.1,1000 > 4.2.3.2,2000 +pass +> nic0 ip #0 28(20) 17 4.4.3.1,1000 > 4.2.3.2,2000 +pass +> nic1 ip #0 28(20) 17 4.4.1.1,1001 > 4.2.1.2,2001 +pass +> nic1 ip #0 28(20) 17 4.4.1.1,1001 > 4.2.1.2,2001 +pass +> nic2 ip #0 28(20) 17 4.4.2.1,1002 > 4.2.2.2,2002 +pass +> nic2 ip #0 28(20) 17 4.4.2.1,1002 > 4.2.2.2,2002 +pass +> nic3 ip #0 28(20) 17 4.4.3.1,1003 > 4.2.3.2,2003 +pass +> nic3 ip #0 28(20) 17 4.4.3.1,1003 > 4.2.3.2,2003 +pass +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +4:udp src:4.4.3.1,1003 dst:4.2.3.2,2003 240 + FWD: IN pkts 2 bytes 56 OUT pkts 2 bytes 56 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[nic0],X[] out X[nic3],X[] + Sync status: not synchronized +4:udp src:4.4.2.1,1002 dst:4.2.2.2,2002 240 + FWD: IN pkts 2 bytes 56 OUT pkts 2 bytes 56 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[nic0],X[] out X[nic2],X[] + Sync status: not synchronized +4:udp src:4.4.1.1,1001 dst:4.2.1.2,2001 240 + FWD: IN pkts 2 bytes 56 OUT pkts 2 bytes 56 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[nic0],X[] out X[nic1],X[] + Sync status: not synchronized +4:udp src:4.4.3.1,1000 dst:4.2.3.2,2000 240 + FWD: IN pkts 2 bytes 56 OUT pkts 2 bytes 56 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[nic0],X[] out X[nic0],X[] + Sync status: not synchronized +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +7 block in all +4 pass in on nic0 to dstlist/spread inet from 4.4.0.0/16 to any keep state +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/f3 b/contrib/netbsd-tests/ipf/expected/f3 new file mode 100644 index 0000000..5df3ac4 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f3 @@ -0,0 +1,48 @@ +nomatch +block +nomatch +nomatch +nomatch +-------- +nomatch +pass +nomatch +nomatch +nomatch +-------- +nomatch +block +block +nomatch +nomatch +-------- +nomatch +pass +pass +nomatch +nomatch +-------- +nomatch +block +block +block +nomatch +-------- +nomatch +pass +pass +pass +nomatch +-------- +block +block +block +block +block +-------- +pass +pass +pass +pass +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f30 b/contrib/netbsd-tests/ipf/expected/f30 new file mode 100644 index 0000000..30b9d40 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f30 @@ -0,0 +1,68 @@ +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +pass +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +nomatch +nomatch +pass +nomatch +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f4 b/contrib/netbsd-tests/ipf/expected/f4 new file mode 100644 index 0000000..5df3ac4 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f4 @@ -0,0 +1,48 @@ +nomatch +block +nomatch +nomatch +nomatch +-------- +nomatch +pass +nomatch +nomatch +nomatch +-------- +nomatch +block +block +nomatch +nomatch +-------- +nomatch +pass +pass +nomatch +nomatch +-------- +nomatch +block +block +block +nomatch +-------- +nomatch +pass +pass +pass +nomatch +-------- +block +block +block +block +block +-------- +pass +pass +pass +pass +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f5 b/contrib/netbsd-tests/ipf/expected/f5 new file mode 100644 index 0000000..36c7d40 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f5 @@ -0,0 +1,1392 @@ +nomatch +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +nomatch +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +block +block +block +block +block +block +block +block +block +block +block +nomatch +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +block +block +nomatch +nomatch +block +-------- +block +block +block +block +block +block +block +block +block +block +block +nomatch +nomatch +block +block +block +block +block +block +block +block +block +block +block +block +nomatch +nomatch +block +-------- +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +pass +-------- +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +pass +-------- +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +block +block +block +nomatch +block +block +block +block +block +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +nomatch +block +block +block +block +block +block +block +block +block +block +-------- +block +block +block +nomatch +block +block +block +block +block +block +block +block +block +block +block +block +block +nomatch +block +block +block +block +block +block +block +block +block +block +-------- +pass +pass +pass +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +pass +pass +pass +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f6 b/contrib/netbsd-tests/ipf/expected/f6 new file mode 100644 index 0000000..36c7d40 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f6 @@ -0,0 +1,1392 @@ +nomatch +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +nomatch +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +block +block +block +block +block +block +block +block +block +block +block +nomatch +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +block +block +nomatch +nomatch +block +-------- +block +block +block +block +block +block +block +block +block +block +block +nomatch +nomatch +block +block +block +block +block +block +block +block +block +block +block +block +nomatch +nomatch +block +-------- +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +pass +-------- +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +pass +-------- +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +block +block +block +nomatch +block +block +block +block +block +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +nomatch +block +block +block +block +block +block +block +block +block +block +-------- +block +block +block +nomatch +block +block +block +block +block +block +block +block +block +block +block +block +block +nomatch +block +block +block +block +block +block +block +block +block +block +-------- +pass +pass +pass +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +pass +pass +pass +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +block +block +block +block +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f7 b/contrib/netbsd-tests/ipf/expected/f7 new file mode 100644 index 0000000..7a4daed --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f7 @@ -0,0 +1,144 @@ +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f8 b/contrib/netbsd-tests/ipf/expected/f8 new file mode 100644 index 0000000..ad42ff2 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f8 @@ -0,0 +1,42 @@ +block +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +block +nomatch +block +nomatch +nomatch +nomatch +-------- +pass +nomatch +pass +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/f9 b/contrib/netbsd-tests/ipf/expected/f9 new file mode 100644 index 0000000..cc5be68 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/f9 @@ -0,0 +1,180 @@ +block +block +block +block +block +block +block +block +block +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +pass +pass +pass +pass +-------- +block +block +block +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +block +block +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/i1 b/contrib/netbsd-tests/ipf/expected/i1 new file mode 100644 index 0000000..19ae393 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i1 @@ -0,0 +1,17 @@ +pass in all +block out all +log in all +log body in all +count in from any to any +pass in from !any to any pps 10 +block in from any to !any +pass in on ed0(!) inet from 127.0.0.1/32 to 127.0.0.1/32 +pass in on ed0(!),vx0(!) inet from 127.0.0.1/32 to 127.0.0.1/32 +block in log first on lo0(!) from any to any +pass in log body or-block quick from any to any +block return-rst in quick on le0(!) proto tcp from any to any +block return-icmp in on qe0(!) from any to any +block return-icmp(host-unr) in on qe0(!) from any to any +block return-icmp-as-dest in on le0(!) from any to any +block return-icmp-as-dest(port-unr) in on qe0(!) from any to any +pass out on longNICname0(!) inet from 254.220.186.152/32 to 254.220.186.152/32 diff --git a/contrib/netbsd-tests/ipf/expected/i10 b/contrib/netbsd-tests/ipf/expected/i10 new file mode 100644 index 0000000..24137c1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i10 @@ -0,0 +1,5 @@ +pass in inet from 127.0.0.1/32 to 127.0.0.1/32 with opt sec +pass in inet from 127.0.0.1/32 to 127.0.0.1/32 with opt lsrr not opt sec +block in inet from any to any with not opt sec-class topsecret +block in inet from any to any with not opt sec-class topsecret,secret +pass in inet from any to any with opt sec-class topsecret,confid not opt sec-class unclass diff --git a/contrib/netbsd-tests/ipf/expected/i11 b/contrib/netbsd-tests/ipf/expected/i11 new file mode 100644 index 0000000..d1d2cf6 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i11 @@ -0,0 +1,12 @@ +pass in on ed0(!) inet proto tcp from 127.0.0.1/32 to 127.0.0.1/32 port = 23 keep state # count 0 +block in log first on lo0(!) proto tcp/udp from any to any port = 7 keep state # count 0 +pass in inet proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 20499 keep frags +pass in inet proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 2049 keep frags (strict) +pass in inet proto udp from 127.0.0.1/32 to 127.0.0.1/32 port = 53 keep state keep frags # count 0 +pass in on ed0(!) out-via vx0(!) proto udp from any to any keep state # count 0 +pass out on ppp0(!) in-via le0(!) proto tcp from any to any keep state # count 0 +pass in on ed0(!),vx0(!) out-via vx0(!),ed0(!) proto udp from any to any keep state # count 0 +pass in inet proto tcp from any port > 1024 to 127.0.0.1/32 port = 1024 keep state # count 0 +pass in proto tcp from any to any flags S/FSRPAU keep state (limit 101,strict,newisn,no-icmp-err,age 600/600) # count 0 +pass in proto tcp from any to any flags S/FSRPAU keep state (limit 101,loose,newisn,no-icmp-err,age 600/600) # count 0 +pass in proto udp from any to any keep state (sync,age 10/20) # count 0 diff --git a/contrib/netbsd-tests/ipf/expected/i12 b/contrib/netbsd-tests/ipf/expected/i12 new file mode 100644 index 0000000..6747d93 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i12 @@ -0,0 +1,39 @@ +pass in inet from 1.1.1.1/32 to 2.2.2.2/32 +pass in inet from 2.2.2.0/24 to 4.4.4.4/32 +pass in inet from 3.3.3.3/32 to 4.4.4.4/32 +pass in inet from 2.2.2.0/24 to 5.5.5.5/32 +pass in inet from 3.3.3.3/32 to 5.5.5.5/32 +pass in inet from 2.2.2.0/24 to 6.6.6.6/32 +pass in inet from 3.3.3.3/32 to 6.6.6.6/32 +pass in inet from 2.2.2.0/24 to 5.5.5.5/32 port = 22 +pass in inet from 3.3.3.3/32 to 5.5.5.5/32 port = 22 +pass in inet from 2.2.2.0/24 to 6.6.6.6/32 port = 22 +pass in inet from 3.3.3.3/32 to 6.6.6.6/32 port = 22 +pass in inet from 2.2.2.0/24 to 5.5.5.5/32 port = 25 +pass in inet from 3.3.3.3/32 to 5.5.5.5/32 port = 25 +pass in inet from 2.2.2.0/24 to 6.6.6.6/32 port = 25 +pass in inet from 3.3.3.3/32 to 6.6.6.6/32 port = 25 +pass in inet proto tcp from 2.2.2.0/24 port = 53 to 5.5.5.5/32 +pass in inet proto tcp from 3.3.3.3/32 port = 53 to 5.5.5.5/32 +pass in inet proto tcp from 2.2.2.0/24 port = 9 to 5.5.5.5/32 +pass in inet proto tcp from 3.3.3.3/32 port = 9 to 5.5.5.5/32 +pass in inet proto tcp from 2.2.2.0/24 port = 53 to 6.6.6.6/32 +pass in inet proto tcp from 3.3.3.3/32 port = 53 to 6.6.6.6/32 +pass in inet proto tcp from 2.2.2.0/24 port = 9 to 6.6.6.6/32 +pass in inet proto tcp from 3.3.3.3/32 port = 9 to 6.6.6.6/32 +pass in inet proto udp from 2.2.2.0/24 to 5.5.5.5/32 port = 53 +pass in inet proto udp from 3.3.3.3/32 to 5.5.5.5/32 port = 53 +pass in inet proto udp from 2.2.2.0/24 to 6.6.6.6/32 port = 53 +pass in inet proto udp from 3.3.3.3/32 to 6.6.6.6/32 port = 53 +pass in inet proto udp from 2.2.2.0/24 to 5.5.5.5/32 port = 9 +pass in inet proto udp from 3.3.3.3/32 to 5.5.5.5/32 port = 9 +pass in inet proto udp from 2.2.2.0/24 to 6.6.6.6/32 port = 9 +pass in inet proto udp from 3.3.3.3/32 to 6.6.6.6/32 port = 9 +pass in inet from 10.10.10.10/32 to 11.11.11.11/32 +pass in from pool/101 to hash/202 +pass in from hash/303 to pool/404 +table role=ipf type=tree number= + { ! 2.2.0.0/16; 2.2.2.2/32; ! 1.1.1.1/32; }; +table role=ipf type=tree number= + { 1.1.0.0/16; }; +pass in from pool/0 to pool/0 diff --git a/contrib/netbsd-tests/ipf/expected/i13 b/contrib/netbsd-tests/ipf/expected/i13 new file mode 100644 index 0000000..5c8d945 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i13 @@ -0,0 +1,2 @@ +block in from any to any +pass in from any to any diff --git a/contrib/netbsd-tests/ipf/expected/i14 b/contrib/netbsd-tests/ipf/expected/i14 new file mode 100644 index 0000000..0f2430f --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i14 @@ -0,0 +1,15 @@ +block in on eri0(!) all head 1 +pass in on eri0(!) proto icmp from any to any group 1 +pass out on ed0(!) all head 1000000 +block out on ed0(!) proto udp from any to any group 1000000 +block in on vm0(!) proto tcp/udp from any to any head 101 +pass in inet proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 group 101 +pass in inet proto tcp from 1.0.0.1/32 to 2.0.0.2/32 group 101 +pass in inet proto udp from 2.0.0.2/32 to 3.0.0.3/32 group 101 +block in on vm0(!) proto tcp/udp from any to any head vm0-group +pass in inet proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 group vm0-group +block in on vm0(!) proto tcp/udp from any to any head vm0-group +pass in inet proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 group vm0-group +pass in inet6 from 8f::/128 to f8::/128 +block in inet6 proto udp from any to any +block in inet6 all diff --git a/contrib/netbsd-tests/ipf/expected/i15 b/contrib/netbsd-tests/ipf/expected/i15 new file mode 100644 index 0000000..4974659 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i15 @@ -0,0 +1,4 @@ +pass out on fxp0(!) all set-tag(log=100) +pass out on fxp0(!) all set-tag(nat=foo) +pass out on fxp0(!) all set-tag(log=100, nat=200) +pass out on fxp0(!) all set-tag(log=2147483648, nat=overtherainbowis) diff --git a/contrib/netbsd-tests/ipf/expected/i16 b/contrib/netbsd-tests/ipf/expected/i16 new file mode 100644 index 0000000..c5b3cf3 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i16 @@ -0,0 +1,3 @@ +block out all +100 pass in all +10101 pass out proto tcp from any to any diff --git a/contrib/netbsd-tests/ipf/expected/i17 b/contrib/netbsd-tests/ipf/expected/i17 new file mode 100644 index 0000000..9e71cb1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i17 @@ -0,0 +1,29 @@ +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +0 pass in inet from 1.1.1.1/32 to any +0 pass in all +0 pass in inet from 3.3.3.3/32 to any +0 pass in inet from any to 127.0.0.1/32 +0 pass in inet from 127.0.0.1/32 to any +0 100 pass in inet from 127.0.0.1/32 to any +0 100 pass in all +0 110 pass in proto udp from any to any +0 110 pass in inet from 2.2.2.2/32 to any +0 110 pass in inet from 127.0.0.1/32 to any +0 200 pass in proto tcp from any to any +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) diff --git a/contrib/netbsd-tests/ipf/expected/i18 b/contrib/netbsd-tests/ipf/expected/i18 new file mode 100644 index 0000000..2c7e493 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i18 @@ -0,0 +1,11 @@ +pass in tos 0x50 from any to any +pass in tos 0x80 from any to any +pass out tos 0x80 from any to any +pass out tos 0x50 from any to any +block in ttl 0 from any to any +block in ttl 1 from any to any +block in ttl 2 from any to any +block in ttl 3 from any to any +block in ttl 4 from any to any +block in ttl 5 from any to any +block in ttl 6 from any to any diff --git a/contrib/netbsd-tests/ipf/expected/i19.dist b/contrib/netbsd-tests/ipf/expected/i19.dist new file mode 100644 index 0000000..5d9c26c --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i19.dist @@ -0,0 +1,22 @@ +block in log level user.debug quick proto icmp from any to any +block in log level mail.info quick proto icmp from any to any +block in log level daemon.notice quick proto icmp from any to any +block in log level auth.warn quick proto icmp from any to any +block in log level syslog.err quick proto icmp from any to any +block in log level lpr.crit quick proto icmp from any to any +block in log level news.alert quick proto icmp from any to any +block in log level uucp.emerg quick proto icmp from any to any +block in log level cron.debug quick proto icmp from any to any +block in log level ftp.info quick proto icmp from any to any +block in log level authpriv.notice quick proto icmp from any to any +block in log level logalert.warn quick proto icmp from any to any +block in log level local0.err quick proto icmp from any to any +block in log level local1.crit quick proto icmp from any to any +block in log level local2.alert quick proto icmp from any to any +block in log level local3.emerg quick proto icmp from any to any +block in log level local4.debug quick proto icmp from any to any +block in log level local5.info quick proto icmp from any to any +block in log level local6.notice quick proto icmp from any to any +block in log level local7.warn quick proto icmp from any to any +block in log level kern.err quick proto icmp from any to any +block in log level security.emerg quick proto icmp from any to any diff --git a/contrib/netbsd-tests/ipf/expected/i2 b/contrib/netbsd-tests/ipf/expected/i2 new file mode 100644 index 0000000..17b9d07 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i2 @@ -0,0 +1,9 @@ +log in proto tcp from any to any +pass in proto tcp from any to any +pass in inet proto udp from 127.0.0.1/32 to 127.0.0.1/32 +block in proto ipv6 from any to any +block in proto udp from any to any +block in proto 250 from any to any +pass in proto tcp/udp from any to any +block in proto tcp/udp from any to any +block in proto tcp/udp from any to any diff --git a/contrib/netbsd-tests/ipf/expected/i20 b/contrib/netbsd-tests/ipf/expected/i20 new file mode 100644 index 0000000..25e35cd --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i20 @@ -0,0 +1,4 @@ +pass in on ppp0(!) inet from ppp0/peer to ppp0/32 +block in on hme0(!) inet from any to hme0/bcast +pass in on bge0(!) inet from bge0/net to bge0/32 +block in on eri0(!) inet from any to eri0/netmasked diff --git a/contrib/netbsd-tests/ipf/expected/i21 b/contrib/netbsd-tests/ipf/expected/i21 new file mode 100644 index 0000000..d4d28da --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i21 @@ -0,0 +1,16 @@ +pass in from any port = 10101 to any +pass out from any to any port != 22 +block in from any port 20:21 to any +block out from any to any port 10 <> 100 +pass out from any to any port = 3 +pass out from any to any port = 5 +pass out from any to any port = 7 +pass out from any to any port = 9 +block in from any port = 20 to any +block in from any port = 25 to any +pass in from any port 11:12 to any port 1:2 +pass in from any port 21:22 to any port 1:2 +pass in from any port 11:12 to any port 4:5 +pass in from any port 21:22 to any port 4:5 +pass in from any port 11:12 to any port 8:9 +pass in from any port 21:22 to any port 8:9 diff --git a/contrib/netbsd-tests/ipf/expected/i22 b/contrib/netbsd-tests/ipf/expected/i22 new file mode 100644 index 0000000..6e5a07d --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i22 @@ -0,0 +1,5 @@ +pass in exp { "ip.src != 1.1.1.0/24; tcp.dport = 80;" } +pass in exp { "ip.addr = 1.2.3.4/32,5.6.7.8/32;" } +block out exp { "ip.dst = 127.0.0.0/8;" } +block in exp { "udp.sport = 53; udp.dport = 53;" } +pass out exp { "tcp.sport = 22; tcp.port = 25;" } diff --git a/contrib/netbsd-tests/ipf/expected/i23 b/contrib/netbsd-tests/ipf/expected/i23 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i23 diff --git a/contrib/netbsd-tests/ipf/expected/i3 b/contrib/netbsd-tests/ipf/expected/i3 new file mode 100644 index 0000000..691ad25 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i3 @@ -0,0 +1,11 @@ +log in all +pass in inet from 128.16.0.0/16 to 129.10.10.0/24 +pass in inet from 128.0.0.0/24 to 128.0.0.0/16 +pass in inet from 128.0.0.0/24 to 128.0.0.0/16 +pass in inet from 128.0.0.0/24 to 128.0.0.0/16 +pass in inet from 128.0.0.0/24 to 128.0.0.0/16 +pass in inet from 128.0.0.0/24 to 128.0.0.0/16 +pass in inet from 127.0.0.1/32 to 127.0.0.1/32 +block in log inet from any to any +block in log level auth.info on hme0(!) all +log level local5.warn out all diff --git a/contrib/netbsd-tests/ipf/expected/i4 b/contrib/netbsd-tests/ipf/expected/i4 new file mode 100644 index 0000000..1198714 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i4 @@ -0,0 +1,9 @@ +log in proto tcp from any port > 0 to any +log in proto tcp from any to any port > 0 +pass in proto tcp from any port != 0 to any port 0 >< 65535 +pass in inet proto udp from 127.0.0.1/32 port > 32000 to 127.0.0.1/32 port < 29000 +block in proto udp from any port != 123 to any port < 7 +block in proto tcp from any port = 25 to any port > 25 +pass in proto tcp/udp from any port 1 >< 3 to any port 1 <> 3 +pass in proto tcp/udp from any port 2:2 to any port 10:20 +pass in log first quick proto tcp from any port > 1023 to any port = 1723 flags S/FSRPAU keep state # count 0 diff --git a/contrib/netbsd-tests/ipf/expected/i5 b/contrib/netbsd-tests/ipf/expected/i5 new file mode 100644 index 0000000..0dbc859 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i5 @@ -0,0 +1,9 @@ +log in all +count in tos 0x80 from any to any +pass in on ed0(!) inet tos 0x40 from 127.0.0.1/32 to 127.0.0.1/32 +block in log on lo0(!) ttl 0 from any to any +pass in quick ttl 1 from any to any +skip 3 out inet from 127.0.0.1/32 to any +auth out on foo0(!) proto tcp from any to any port = 80 +preauth out on foo0(!) proto tcp from any to any port = 22 +nomatch out on foo0(!) proto tcp from any port < 1024 to any diff --git a/contrib/netbsd-tests/ipf/expected/i6 b/contrib/netbsd-tests/ipf/expected/i6 new file mode 100644 index 0000000..29c33a2 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i6 @@ -0,0 +1,12 @@ +pass in on lo0(!) fastroute from any to any +pass in on lo0(!) to qe0(!) inet from 127.0.0.1/32 to 127.0.0.1/32 +pass in on le0(!) to qe0:127.0.0.1 inet from 127.0.0.1/32 to 127.0.0.1/32 +pass in on lo0(!) dup-to qe0(!) inet from 127.0.0.1/32 to 127.0.0.1/32 +pass in on le0(!) dup-to qe0:127.0.0.1 inet from 127.0.0.1/32 to 127.0.0.1/32 +pass in on le0(!) to hme0:10.1.1.1 dup-to qe0:127.0.0.1 inet from 127.0.0.1/32 to 127.0.0.1/32 +block in quick on qe0(!) to qe1(!) from any to any +block in quick to qe1(!) from any to any +pass out quick dup-to hme0(!) from any to any +pass out quick on hme0(!) reply-to hme1(!) from any to any +pass in on le0(!) dup-to qe0:127.0.0.1 reply-to hme1:10.10.10.10 inet all +pass in quick fastroute all diff --git a/contrib/netbsd-tests/ipf/expected/i7 b/contrib/netbsd-tests/ipf/expected/i7 new file mode 100644 index 0000000..552f7f8 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i7 @@ -0,0 +1,14 @@ +pass in on ed0(!) inet proto tcp from 127.0.0.1/32 to 127.0.0.1/32 port = 23 flags S/SA +block in on lo0(!) proto tcp from any to any flags A/FSRPAU +pass in on lo0(!) proto tcp from any to any flags /SPA +block in on lo0(!) proto tcp from any to any flags C/A +pass in on lo0(!) proto tcp from any to any flags S/SA +block in on lo0(!) proto tcp from any to any flags S/SA +pass in on lo0(!) proto tcp from any to any flags S/FSRPAU +block in on lo0(!) proto tcp from any to any flags /A +pass in on lo0(!) proto tcp from any to any flags S/SA +pass in on lo0(!) proto tcp from any to any flags S/SA +block in on lo0(!) proto tcp from any to any flags S/SA +pass in on lo0(!) proto tcp from any to any flags S/FSRPAU +block in on lo0(!) proto tcp from any to any flags /A +pass in on lo0(!) proto tcp from any to any flags S/SA diff --git a/contrib/netbsd-tests/ipf/expected/i8 b/contrib/netbsd-tests/ipf/expected/i8 new file mode 100644 index 0000000..a85f1de --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i8 @@ -0,0 +1,66 @@ +pass in inet proto icmp from 127.0.0.1/32 to 127.0.0.1/32 icmp-type timest +block in inet proto icmp from any to any icmp-type unreach code 1 +pass in inet proto icmp from any to any icmp-type unreach code 15 +pass in inet proto icmp from any to any icmp-type unreach code 13 +pass in inet proto icmp from any to any icmp-type unreach code 8 +pass in inet proto icmp from any to any icmp-type unreach code 4 +pass in inet proto icmp from any to any icmp-type unreach code 9 +pass in inet proto icmp from any to any icmp-type unreach code 11 +pass in inet proto icmp from any to any icmp-type unreach code 14 +pass in inet proto icmp from any to any icmp-type unreach code 10 +pass in inet proto icmp from any to any icmp-type unreach code 12 +pass in inet proto icmp from any to any icmp-type unreach code 7 +pass in inet proto icmp from any to any icmp-type unreach code 1 +pass in inet proto icmp from any to any icmp-type unreach code 6 +pass in inet proto icmp from any to any icmp-type unreach code 0 +pass in inet proto icmp from any to any icmp-type unreach code 3 +pass in inet proto icmp from any to any icmp-type unreach code 2 +pass in inet proto icmp from any to any icmp-type unreach code 5 +pass in inet proto icmp from any to any icmp-type echo +pass in inet proto icmp from any to any icmp-type echorep +pass in inet proto icmp from any to any icmp-type inforeq +pass in inet proto icmp from any to any icmp-type inforep +pass in inet proto icmp from any to any icmp-type maskrep +pass in inet proto icmp from any to any icmp-type maskreq +pass in inet proto icmp from any to any icmp-type paramprob +pass in inet proto icmp from any to any icmp-type redir +pass in inet proto icmp from any to any icmp-type unreach +pass in inet proto icmp from any to any icmp-type routerad +pass in inet proto icmp from any to any icmp-type routersol +pass in inet proto icmp from any to any icmp-type squench +pass in inet proto icmp from any to any icmp-type timest +pass in inet proto icmp from any to any icmp-type timestrep +pass in inet proto icmp from any to any icmp-type timex +pass in inet proto icmp from any to any icmp-type 254 +pass in inet proto icmp from any to any icmp-type 253 code 254 +pass in inet proto icmp from any to any icmp-type unreach code 15 +pass in inet proto icmp from any to any icmp-type unreach code 13 +pass in inet proto icmp from any to any icmp-type unreach code 8 +pass in inet proto icmp from any to any icmp-type unreach code 4 +pass in inet proto icmp from any to any icmp-type unreach code 9 +pass in inet proto icmp from any to any icmp-type unreach code 11 +pass in inet proto icmp from any to any icmp-type unreach code 14 +pass in inet proto icmp from any to any icmp-type unreach code 10 +pass in inet proto icmp from any to any icmp-type unreach code 12 +pass in inet proto icmp from any to any icmp-type unreach code 7 +pass in inet proto icmp from any to any icmp-type unreach code 1 +pass in inet proto icmp from any to any icmp-type unreach code 6 +pass in inet proto icmp from any to any icmp-type unreach code 0 +pass in inet proto icmp from any to any icmp-type unreach code 3 +pass in inet proto icmp from any to any icmp-type unreach code 2 +pass in inet proto icmp from any to any icmp-type unreach code 5 +pass in inet proto icmp from any to any icmp-type echo +pass in inet proto icmp from any to any icmp-type echorep +pass in inet proto icmp from any to any icmp-type inforeq +pass in inet proto icmp from any to any icmp-type inforep +pass in inet proto icmp from any to any icmp-type maskrep +pass in inet proto icmp from any to any icmp-type maskreq +pass in inet proto icmp from any to any icmp-type paramprob +pass in inet proto icmp from any to any icmp-type redir +pass in inet proto icmp from any to any icmp-type unreach +pass in inet proto icmp from any to any icmp-type routerad +pass in inet proto icmp from any to any icmp-type routersol +pass in inet proto icmp from any to any icmp-type squench +pass in inet proto icmp from any to any icmp-type timest +pass in inet proto icmp from any to any icmp-type timestrep +pass in inet proto icmp from any to any icmp-type timex diff --git a/contrib/netbsd-tests/ipf/expected/i9 b/contrib/netbsd-tests/ipf/expected/i9 new file mode 100644 index 0000000..deecd17 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/i9 @@ -0,0 +1,17 @@ +pass in inet from 127.0.0.1/32 to 127.0.0.1/32 with short,frag +block in from any to any with ipopts +pass in inet from any to any with opt nop,rr,zsu +pass in inet from any to any with opt nop,rr,zsu not opt lsrr,ssrr +pass in inet from 127.0.0.1/32 to 127.0.0.1/32 with not frag +pass in inet from 127.0.0.1/32 to 127.0.0.1/32 with frag,frag-body +pass in proto tcp from any to any flags S/FSRPAU with not oow keep state # count 0 +block in proto tcp from any to any with oow +pass in proto tcp from any to any flags S/FSRPAU with not bad,bad-src,bad-nat +block in proto tcp from any to any flags S/FSRPAU with bad,not bad-src,not bad-nat +pass in quick from any to any with not short +block in quick from any to any with not nat +pass in quick from any to any with not frag-body +block in quick from any to any with not lowttl +pass in from any to any with not ipopts,mbcast,not bcast,mcast,not state +block in from any to any with not mbcast,bcast,not mcast,state +pass in inet from any to any with opt mtup,mtur,encode,ts,tr,sec,e-sec,cipso,satid,ssrr,addext,visa,imitd,eip,finn,dps,sdb,nsapa,rtralrt,ump diff --git a/contrib/netbsd-tests/ipf/expected/in1 b/contrib/netbsd-tests/ipf/expected/in1 new file mode 100644 index 0000000..2f1cf31 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in1 @@ -0,0 +1,31 @@ +map le0 0/0 -> 0/32 +map le0 0.0.0.1/32 -> 0.0.0.1/32 +map le0 128.0.0.0/1 -> 0/0 +map le0 10.0.0.0/8 -> 1.2.3.0/24 +map le0 10.0.0.0/8 -> 1.2.3.0/24 +map le0 10.0.0.0/8 -> 1.2.3.0/24 +map le0 0.0.0.5/0.0.0.255 -> 1.2.3.0/24 +map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 +map ppp0 192.168.0.0/16 -> 0/32 portmap udp 20000:29999 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp/udp 30000:39999 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp auto +map ppp0 192.168.0.0/16 -> 0/32 portmap udp auto +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp/udp auto +map ppp0 192.168.0.0/16 -> 0/32 proxy port 21 ftp/tcp +map ppp0 192.168.0.0/16 -> 0/32 proxy port 1010 ftp/tcp +map le0 0/0 -> 0/32 frag +map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 frag +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 frag +map ppp0 192.168.0.0/16 -> 0/32 proxy port 21 ftp/tcp frag +map le0 0/0 -> 0/32 age 10/10 +map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 age 10/20 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 age 30/30 +map le0 0/0 -> 0/32 frag age 10/10 +map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 frag age 10/20 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 frag age 30/30 +map fxp0 from 192.168.0.0/18 to 0/0 port = 21 -> 1.2.3.4/32 proxy port 21 ftp/tcp +map thisisalonginte 0/0 -> 0/32 mssclamp 1452 tag freddyliveshere +map bar0 0/0 -> 0/32 icmpidmap icmp 1000:2000 +map ppp0,adsl0 0/0 -> 0/32 +map ppp0 from 192.168.0.0/16 to 0/0 port = 123 -> 0/32 age 30/1 udp diff --git a/contrib/netbsd-tests/ipf/expected/in100 b/contrib/netbsd-tests/ipf/expected/in100 new file mode 100644 index 0000000..dcf3097 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in100 @@ -0,0 +1,3 @@ +rewrite in on bge0 from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.3/32 dst 4.4.4.4/32; +rewrite out on bge0 from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.0/24 dst 4.4.4.4/32; +rewrite in on bge0 from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.0/24 dst 4.4.4.0/24; diff --git a/contrib/netbsd-tests/ipf/expected/in100_6 b/contrib/netbsd-tests/ipf/expected/in100_6 new file mode 100644 index 0000000..b81fa60 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in100_6 @@ -0,0 +1,3 @@ +rewrite in on bge0 inet6 from 1:1:1::1/128 to 2:2::2:2/128 -> src 3:3:3::3/128 dst 4::4:4:4/128; +rewrite out on bge0 inet6 from 1:1:1::1/128 to 2:2::2:2/128 -> src 3:3:3::/96 dst 4::4:4:4/128; +rewrite in on bge0 inet6 from 1:1:1::1/128 to 2:2::2:2/128 -> src 3:3:3::/96 dst 4::4:0:0/96; diff --git a/contrib/netbsd-tests/ipf/expected/in101 b/contrib/netbsd-tests/ipf/expected/in101 new file mode 100644 index 0000000..04e234c --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in101 @@ -0,0 +1,4 @@ +rewrite in on bge0 proto icmp from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.3/32 dst 4.4.4.4/32; +rewrite in on bge0 proto udp from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.3/32 dst 4.4.4.4/32; +rewrite out on bge0 proto tcp from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.0/24 dst 4.4.4.4/32; +rewrite in on bge0 proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.0/24,20202 dst 4.4.4.0/24,10101; diff --git a/contrib/netbsd-tests/ipf/expected/in101_6 b/contrib/netbsd-tests/ipf/expected/in101_6 new file mode 100644 index 0000000..baed807 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in101_6 @@ -0,0 +1,4 @@ +rewrite in on bge0 inet6 proto icmp from 1:1:1::1/128 to 2:2::2:2/128 -> src 3:3:3::3/128 dst 4::4:4:4/128; +rewrite in on bge0 inet6 proto udp from 1:1:1::1/128 to 2:2::2:2/128 -> src 3:3:3::3/128 dst 4::4:4:4/128; +rewrite out on bge0 inet6 proto tcp from 1:1:1::1/128 to 2:2::2:2/128 -> src 3::/24 dst 4::4:4:4/128; +rewrite in on bge0 inet6 proto tcp/udp from 1:1:1::1/128 to 2:2::/32 -> src 3::/24,20202 dst 4::/24,10101; diff --git a/contrib/netbsd-tests/ipf/expected/in102 b/contrib/netbsd-tests/ipf/expected/in102 new file mode 100644 index 0000000..0a1b612 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in102 @@ -0,0 +1,5 @@ +rewrite in on bge0 proto tcp from 0/0 to 0/0 -> src 0/0 dst dstlist/a; +rewrite in on bge0 proto tcp from 1.1.1.1/32 to 0/0 -> src 0/0 dst dstlist/bee; +rewrite in on bge0 proto tcp from 1.1.1.1/32 to 2.2.2.2/32 -> src 0/0 dst dstlist/cat; +rewrite in on bge0 proto tcp from pool/a to 2.2.2.2/32 -> src 0/0 dst dstlist/bat; +rewrite in on bge0 proto tcp from pool/a to pool/1 -> src 0/0 dst dstlist/ant; diff --git a/contrib/netbsd-tests/ipf/expected/in102_6 b/contrib/netbsd-tests/ipf/expected/in102_6 new file mode 100644 index 0000000..0e3fa8e --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in102_6 @@ -0,0 +1,5 @@ +rewrite in on bge0 inet6 proto tcp from any to any -> src any dst dstlist/a; +rewrite in on bge0 inet6 proto tcp from 1:1:1::1/128 to any -> src any dst dstlist/bee; +rewrite in on bge0 inet6 proto tcp from 1:1:1::1/128 to 2:2::2:2/128 -> src any dst dstlist/cat; +rewrite in on bge0 inet6 proto tcp from pool/a to 2:2::2:2/128 -> src any dst dstlist/bat; +rewrite in on bge0 inet6 proto tcp from pool/a to pool/1 -> src any dst dstlist/ant; diff --git a/contrib/netbsd-tests/ipf/expected/in1_6 b/contrib/netbsd-tests/ipf/expected/in1_6 new file mode 100644 index 0000000..7651337 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in1_6 @@ -0,0 +1,29 @@ +map le0 inet6 any -> ::/128 +map le0 inet6 any -> any +map le0 inet6 ::/1 -> any +map le0 inet6 10::/16 -> 1:2:3::/96 +map le0 inet6 10::/16 -> 1:2:3::/96 +map le0 inet6 192:168::/32 -> range 203:1:1::23-203:1:3::45 +map ppp0 inet6 192:168::/32 -> ::/128 portmap tcp 10000:19999 +map ppp0 inet6 192:168::/32 -> ::/128 portmap udp 20000:29999 +map ppp0 inet6 192:168::/32 -> ::/128 portmap tcp/udp 30000:39999 +map ppp0 inet6 192:168::/32 -> ::/128 portmap tcp auto +map ppp0 inet6 192:168::/32 -> ::/128 portmap udp auto +map ppp0 inet6 192:168::/32 -> ::/128 portmap tcp/udp auto +map ppp0 inet6 192:168::/32 -> ::/128 proxy port 21 ftp/tcp +map ppp0 inet6 192:168::/32 -> ::/128 proxy port 1010 ftp/tcp +map le0 inet6 any -> ::/128 frag +map le0 inet6 192:168::/32 -> range 203:1:1::23-203:1:3::45 frag +map ppp0 inet6 192:168::/32 -> ::/128 portmap tcp 10000:19999 frag +map ppp0 inet6 192:168::/32 -> ::/128 proxy port 21 ftp/tcp frag +map le0 inet6 any -> ::/128 age 10/10 +map le0 inet6 192:168::/32 -> range 203:1:1::23-203:1:3::45 age 10/20 +map ppp0 inet6 192:168::/32 -> ::/128 portmap tcp 10000:19999 age 30/30 +map le0 inet6 any -> ::/128 frag age 10/10 +map le0 inet6 192:168::/32 -> range 203:1:1::23-203:1:3::45 frag age 10/20 +map ppp0 inet6 192:168::/32 -> ::/128 portmap tcp 10000:19999 frag age 30/30 +map fxp0 inet6 from 192::/18 to any port = 21 -> 1:2:3::4/128 proxy port 21 ftp/tcp +map thisisalonginte inet6 any -> ::/128 mssclamp 1452 tag freddyliveshere +map bar0 inet6 any -> ::/128 icmpidmap icmp 1000:2000 +map ppp0,adsl0 inet6 any -> ::/128 +map ppp0 inet6 from 192:168::/32 to any port = 123 -> ::/128 age 30/1 udp diff --git a/contrib/netbsd-tests/ipf/expected/in2 b/contrib/netbsd-tests/ipf/expected/in2 new file mode 100644 index 0000000..068db50 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in2 @@ -0,0 +1,71 @@ +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1/32 port 0 tcp +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 reserved +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip +rdr le0 9.0.0.0/8 -> 1.1.1.1/32 ip +rdr le0 9.8.0.0/16 -> 1.1.1.1/32 ip +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp +rdr le0 9.8.7.6/32 port 80 -> 0/0 port 80 tcp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 udp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp/udp +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp/udp frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/10 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/20 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag age 10/10 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag age 30/30 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/10 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/20 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag age 10/10 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag age 30/30 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 sticky +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/10 mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/20 mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag age 10/10 mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag age 30/30 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/10 mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/20 mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 -> 1.1.1.1/32 icmp frag age 10/10 mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20/20 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1/32 port 80 tcp round-robin frag age 30/30 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40/40 sticky mssclamp 1000 tag nattagcacheline +rdr ge0 9.8.7.6/32 port 21 -> 1.1.1.1/32 port 21 tcp proxy ftp +rdr ge0 9.8.7.6/32 port 21 -> 1.1.1.1/32 port 21 tcp proxy ftp +rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1/32 port 5555 tcp +rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1/32 port = 5555 tcp +rdr le0 0/0 -> 254.220.186.152/32 ip +rdr le0 0/0 -> 254.220.186.152,254.220.186.152 ip +rdr adsl0,ppp0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1/32 port 5555-7777 tcp diff --git a/contrib/netbsd-tests/ipf/expected/in2_6 b/contrib/netbsd-tests/ipf/expected/in2_6 new file mode 100644 index 0000000..7e9ef01 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in2_6 @@ -0,0 +1,71 @@ +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1/128 port 0 tcp +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 reserved +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 tcp +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip +rdr le0 inet6 9:8::/32 -> 1:1:1::1/128 ip +rdr le0 inet6 9:8:7::/64 -> 1:1:1::1/128 ip +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 tcp +rdr le0 inet6 9:8:7::6/128 port 80 -> any port 80 tcp +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 udp +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 tcp/udp +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 icmp +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 tcp round-robin +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip frag +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 icmp frag +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp/udp frag +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 tcp round-robin frag +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip frag age 10/10 +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip frag age 10/20 +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 icmp frag age 10/10 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag age 20/20 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 tcp round-robin frag age 30/30 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag age 40/40 +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip frag +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 icmp frag +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag sticky +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 tcp round-robin frag sticky +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag sticky +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip frag age 10/10 +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip frag age 10/20 +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 icmp frag age 10/10 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag age 20/20 sticky +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 tcp round-robin frag age 30/30 sticky +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag age 40/40 sticky +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip frag mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 icmp frag mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip frag age 10/10 mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip frag age 10/20 mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 icmp frag age 10/10 mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag age 20/20 sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 tcp round-robin frag age 30/30 sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag age 40/40 sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip frag mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 icmp frag mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip frag age 10/10 mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 ip frag age 10/20 mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1/128 icmp frag age 10/10 mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag age 20/20 sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1/128 port 80 tcp round-robin frag age 30/30 sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag age 40/40 sticky mssclamp 1000 tag nattagcacheline +rdr ge0 inet6 9:8:7::6/128 port 21 -> 1:1:1::1/128 port 21 tcp proxy ftp +rdr ge0 inet6 9:8:7::6/128 port 21 -> 1:1:1::1/128 port 21 tcp proxy ftp +rdr le0 inet6 9:8:7::6/128 port 1000-2000 -> 1:1:1::1/128 port 5555 tcp +rdr le0 inet6 9:8:7::6/128 port 1000-2000 -> 1:1:1::1/128 port = 5555 tcp +rdr le0 inet6 any -> fe80:aa55:1234:5678:5a5a:a5a5:fedc:ba98/128 ip +rdr le0 inet6 any -> fe80:aa55:1234:5678:5a5a:a5a5:fedc:ba98,fe80:aa55:1234:5678:5a5a:a5a5:fedc:ba98 ip +rdr adsl0,ppp0 inet6 9:8:7::6/128 port 1000-2000 -> 1:1:1::1/128 port 5555-7777 tcp diff --git a/contrib/netbsd-tests/ipf/expected/in3 b/contrib/netbsd-tests/ipf/expected/in3 new file mode 100644 index 0000000..dac97c7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in3 @@ -0,0 +1,5 @@ +bimap le0 0/0 -> 0/32 +bimap le0 0.0.0.1/32 -> 0.0.0.1/32 +bimap le0 128.0.0.0/1 -> 0/0 +bimap le0 10.0.0.0/8 -> 1.2.3.0/24 +bimap le0 10.0.5.0/24 -> 1.2.3.0/24 diff --git a/contrib/netbsd-tests/ipf/expected/in3_6 b/contrib/netbsd-tests/ipf/expected/in3_6 new file mode 100644 index 0000000..60f3091 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in3_6 @@ -0,0 +1,5 @@ +bimap le0 inet6 any -> ::/128 +bimap le0 inet6 any -> any +bimap le0 inet6 ::/1 -> any +bimap le0 inet6 10::/16 -> 1:2:3::/96 +bimap le0 inet6 10:0:5::/96 -> 1:2:3::/96 diff --git a/contrib/netbsd-tests/ipf/expected/in4 b/contrib/netbsd-tests/ipf/expected/in4 new file mode 100644 index 0000000..ac8dce1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in4 @@ -0,0 +1,5 @@ +map-block le0 10.0.0.0/24 -> 203.1.1.0/24 ports 0 +map-block le0 10.0.0.0/24 -> 203.1.1.0/24 ports 0 +map-block le0 10.0.0.0/24 -> 203.1.1.0/24 ports 256 +map-block le0 10.0.0.0/24 -> 203.1.1.0/24 ports auto +map-block le0 10.0.0.0/16 -> 203.1.1.0/24 ports auto diff --git a/contrib/netbsd-tests/ipf/expected/in4_6 b/contrib/netbsd-tests/ipf/expected/in4_6 new file mode 100644 index 0000000..0e9bfd2 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in4_6 @@ -0,0 +1,5 @@ +map-block le0 inet6 10::/96 -> 203:1:1::/96 ports 0 +map-block le0 inet6 10::/96 -> 203:1:1::/96 ports 0 +map-block le0 inet6 10::/96 -> 203:1:1::/96 ports 256 +map-block le0 inet6 10::/96 -> 203:1:1::/96 ports auto +map-block le0 inet6 10::/16 -> 203:1:1::/96 ports auto diff --git a/contrib/netbsd-tests/ipf/expected/in5 b/contrib/netbsd-tests/ipf/expected/in5 new file mode 100644 index 0000000..b7c6ef5 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in5 @@ -0,0 +1,24 @@ +map le0 from 9.8.7.6/32 port > 1024 to 0/0 -> 1.1.1.1/32 portmap tcp 10000:20000 +map le0 from 9.8.7.6/32 port > 1024 ! to 1.2.3.4/32 -> 1.1.1.1/32 portmap tcp 10000:20000 +rdr le0 from 0/0 to 9.8.7.6/32 port = 0 -> 1.1.1.1/32 port 0 tcp +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 ip +rdr le0 ! from 1.2.3.4/32 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 tcp +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 ip +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 tcp +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 udp +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 tcp/udp +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 icmp +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 tcp round-robin +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 ip frag +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 icmp frag +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp frag +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 tcp round-robin frag +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin frag +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/10 +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 ip frag age 10/20 +rdr le0 from 0/0 to 9.8.7.6/32 -> 1.1.1.1/32 icmp frag age 10/10 +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp frag age 20/20 +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1/32 port 888 tcp round-robin frag age 30/30 +rdr le0 from 0/0 to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin frag age 40/40 diff --git a/contrib/netbsd-tests/ipf/expected/in5_6 b/contrib/netbsd-tests/ipf/expected/in5_6 new file mode 100644 index 0000000..a1925a2 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in5_6 @@ -0,0 +1,24 @@ +map le0 inet6 from 9:8:7::6/128 port > 1024 to any -> 1:1:1::1/128 portmap tcp 10000:20000 +map le0 inet6 from 9:8:7::6/128 port > 1024 ! to 1:2:3::4/128 -> 1:1:1::1/128 portmap tcp 10000:20000 +rdr le0 inet6 from any to 9:8:7::6/128 port = 0 -> 1:1:1::1/128 port 0 tcp +rdr le0 inet6 from any to 9:8:7::6/128 -> 1:1:1::1/128 ip +rdr le0 inet6 ! from 1:2:3::4/128 to 9:8:7::6/128 port = 8888 -> 1:1:1::1/128 port 888 tcp +rdr le0 inet6 from any to 9:8:7::6/128 -> 1:1:1::1/128 ip +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1/128 port 888 tcp +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1/128 port 888 udp +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1/128 port 888 tcp/udp +rdr le0 inet6 from any to 9:8:7::6/128 -> 1:1:1::1/128 icmp +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1,1:1:1::2 port 888 tcp +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1/128 port 888 tcp round-robin +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1,1:1:1::2 port 888 tcp round-robin +rdr le0 inet6 from any to 9:8:7::6/128 -> 1:1:1::1/128 ip frag +rdr le0 inet6 from any to 9:8:7::6/128 -> 1:1:1::1/128 icmp frag +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1,1:1:1::2 port 888 tcp frag +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1/128 port 888 tcp round-robin frag +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1,1:1:1::2 port 888 tcp round-robin frag +rdr le0 inet6 from any to 9:8:7::6/128 -> 1:1:1::1/128 ip frag age 10/10 +rdr le0 inet6 from any to 9:8:7::6/128 -> 1:1:1::1/128 ip frag age 10/20 +rdr le0 inet6 from any to 9:8:7::6/128 -> 1:1:1::1/128 icmp frag age 10/10 +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1,1:1:1::2 port 888 tcp frag age 20/20 +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1/128 port 888 tcp round-robin frag age 30/30 +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1,1:1:1::2 port 888 tcp round-robin frag age 40/40 diff --git a/contrib/netbsd-tests/ipf/expected/in6 b/contrib/netbsd-tests/ipf/expected/in6 new file mode 100644 index 0000000..fefc052 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in6 @@ -0,0 +1,8 @@ +map foo0 from 0/0 port = 1 to 0/0 port != 0 -> 0/32 udp +map foo0 from 0/0 port = 1 to 0/0 port != 0 -> 0/32 udp +map foo0 from 0/0 port < 1 to 0/0 port > 0 -> 0/32 tcp +map foo0 from 0/0 port < 1 to 0/0 port > 0 -> 0/32 tcp +map foo0 from 0/0 port <= 1 to 0/0 port >= 0 -> 0/32 tcp/udp +map foo0 from 0/0 port <= 1 to 0/0 port >= 0 -> 0/32 tcp/udp +map foo0 from 0/0 port 1 >< 20 to 0/0 port 20 <> 40 -> 0/32 tcp/udp +map foo0 from 0/0 port 10:20 to 0/0 port 30:40 -> 0/32 tcp/udp diff --git a/contrib/netbsd-tests/ipf/expected/in6_6 b/contrib/netbsd-tests/ipf/expected/in6_6 new file mode 100644 index 0000000..ee8a35c --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in6_6 @@ -0,0 +1,8 @@ +map foo0 inet6 from any port = 1 to any port != 0 -> ::/32 udp +map foo0 inet6 from any port = 1 to any port != 0 -> ::/32 udp +map foo0 inet6 from any port < 1 to any port > 0 -> ::/32 tcp +map foo0 inet6 from any port < 1 to any port > 0 -> ::/32 tcp +map foo0 inet6 from any port <= 1 to any port >= 0 -> ::/32 tcp/udp +map foo0 inet6 from any port <= 1 to any port >= 0 -> ::/32 tcp/udp +map foo0 inet6 from any port 1 >< 20 to any port 20 <> 40 -> ::/32 tcp/udp +map foo0 inet6 from any port 10:20 to any port 30:40 -> ::/32 tcp/udp diff --git a/contrib/netbsd-tests/ipf/expected/in7 b/contrib/netbsd-tests/ipf/expected/in7 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in7 diff --git a/contrib/netbsd-tests/ipf/expected/in8_6 b/contrib/netbsd-tests/ipf/expected/in8_6 new file mode 100644 index 0000000..ab23b84 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/in8_6 @@ -0,0 +1,6 @@ +map zx0 inet6 10:1::1:1/128 -> 10:2:2::2/128 purge +map zx0 inet6 10:1::1:1/128 -> 10:2:2::2/128 tcp purge +map zx0 inet6 10:1::1:1/128 -> 10:2:2::2/128 mssclamp 1000 purge +map zx0 inet6 10:1::1:1/128 -> 10:2:2::2/128 portmap tcp/udp 10000:11000 purge +map zx0 inet6 10:1::1:1/128 -> 10:2:2::2/128 portmap tcp/udp 10000:11000 sequential purge +map zx0 inet6 10:1::1:1/128 -> 10:2:2::2/128 portmap tcp/udp 10000:11000 sequential purge diff --git a/contrib/netbsd-tests/ipf/expected/ip1 b/contrib/netbsd-tests/ipf/expected/ip1 new file mode 100644 index 0000000..cee7831 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ip1 @@ -0,0 +1,68 @@ +table role=ipf type=tree number=1 + {; }; +table role=ipf type=tree number=100 + { 1.2.3.4/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +table role=nat type=tree number=110 + { 1.2.3.4/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +table role=auth type=tree number=120 + { 1.2.3.4/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +table role=count type=tree number=130 + { 1.2.3.4/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +table role=ipf type=hash number=2 size=1 + {; }; +table role=ipf type=hash number=200 size=5 + { 0/0; 1/32; 1.2.3.4/32; }; +table role=nat type=hash number=210 size=5 + { 0/0; 2/32; 1.2.3.4/32; }; +table role=auth type=hash number=220 size=5 + { 0/0; 3/32; 1.2.3.4/32; }; +table role=count type=hash number=230 size=5 + { 0/0; 4/32; 1.2.3.4/32; }; +table role=ipf type=hash number=240 size=5 seed=101 + { 0/0; 1/32; 1.2.3.4/32; }; +table role=nat type=hash number=250 size=5 seed=101 + { 0/0; 2/32; 1.2.3.4/32; }; +table role=auth type=hash number=260 size=5 seed=101 + { 0/0; 3/32; 1.2.3.4/32; }; +table role=count type=hash number=270 size=5 seed=101 + { 0/0; 4/32; 1.2.3.4/32; }; +table role=ipf type=hash number=2000 size=1001 + { 0/0; 1/32; 1.2.3.4/32; }; +table role=nat type=hash number=2000 size=1001 + { 0/0; 2/32; 1.2.3.4/32; }; +table role=auth type=hash number=2000 size=1001 + { 0/0; 3/32; 1.2.3.4/32; }; +table role=count type=hash number=2000 size=1001 + { 0/0; 4/32; 1.2.3.4/32; }; +table role=ipf type=hash number=100 size=1001 seed=101 + { 0/0; 1/32; 1.2.3.4/32; }; +table role=nat type=hash number=100 size=1001 seed=101 + { 0/0; 2/32; 1.2.3.4/32; }; +table role=auth type=hash number=100 size=1001 seed=101 + { 0/0; 3/32; 1.2.3.4/32; }; +table role=count type=hash number=100 size=1001 seed=101 + { 0/0; 4/32; 1.2.3.4/32; }; +group-map in role=ipf number=300 size=5 + { 0/0, group=303; 5/32, group=303; 1.2.3.4/32, group=303; }; +group-map in role=nat number=300 size=5 + { 0/0, group=303; 6/32, group=303; 1.2.3.4/32, group=303; }; +group-map in role=auth number=300 size=5 + { 0/0, group=303; 7/32, group=303; 1.2.3.4/32, group=303; }; +group-map in role=count number=300 size=5 + { 0/0, group=303; 8/32, group=303; 1.2.3.4/32, group=303; }; +group-map out role=ipf number=400 size=5 + { 0/0, group=303; 5/32, group=303; 1.2.3.4/32, group=606; }; +group-map out role=nat number=400 size=5 + { 0/0, group=303; 6/32, group=303; 1.2.3.4/32, group=606; }; +group-map out role=auth number=400 size=5 + { 0/0, group=303; 7/32, group=303; 1.2.3.4/32, group=606; }; +group-map out role=count number=400 size=5 + { 0/0, group=303; 8/32, group=303; 1.2.3.4/32, group=606; }; +group-map in role=ipf number=500 size=5 + { 0/0, group=10; 5/32, group=800; 1.2.3.4/32, group=606; }; +group-map in role=nat number=500 size=5 + { 0/0, group=10; 6/32, group=800; 1.2.3.4/32, group=606; }; +group-map in role=auth number=500 size=5 + { 0/0, group=10; 7/32, group=800; 1.2.3.4/32, group=606; }; +group-map in role=count number=500 size=5 + { 0/0, group=10; 8/32, group=800; 1.2.3.4/32, group=606; }; diff --git a/contrib/netbsd-tests/ipf/expected/ip2 b/contrib/netbsd-tests/ipf/expected/ip2 new file mode 100644 index 0000000..3de3c47 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ip2 @@ -0,0 +1,2 @@ +table role=ipf type=tree name=letters + { 1.1.1.1/32; ! 2.2.0.0/16; 2.2.2.0/24; }; diff --git a/contrib/netbsd-tests/ipf/expected/ip3 b/contrib/netbsd-tests/ipf/expected/ip3 new file mode 100644 index 0000000..48dd074 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ip3 @@ -0,0 +1,14 @@ +pool ipf/dstlist (name fred; policy round-robin;) + { 3.3.3.3; }; +pool ipf/dstlist (name jack; policy weighting connection;) + { 4.4.4.4; bge0:5.5.5.5; }; +pool ipf/dstlist (name jill; policy random;) + { 1.1.1.1; bge0:2.2.2.2; }; +table role=nat type=hash name=noproxy size=3 + { 1.1.1.1/32; 2.2.2.2/32; }; +table role=nat type=tree name=raw + { 1.1.1.1/32; 2.2.2.2/32; }; +pool all/dstlist (name jill; policy random;) + { 1.1.1.1; bge0:2.2.2.2; }; +table role=all type=hash name=noproxy size=3 + { 1.1.1.1/32; 2.2.2.2/32; }; diff --git a/contrib/netbsd-tests/ipf/expected/ipv6.1 b/contrib/netbsd-tests/ipf/expected/ipv6.1 new file mode 100644 index 0000000..9fd5437 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ipv6.1 @@ -0,0 +1,4 @@ +pass +pass +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/ipv6.2 b/contrib/netbsd-tests/ipf/expected/ipv6.2 new file mode 100644 index 0000000..ba1581b --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ipv6.2 @@ -0,0 +1,15 @@ +nomatch +block +nomatch +block +-------- +block +nomatch +block +nomatch +-------- +pass +pass +pass +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/ipv6.3 b/contrib/netbsd-tests/ipf/expected/ipv6.3 new file mode 100644 index 0000000..58cddec --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ipv6.3 @@ -0,0 +1,6 @@ +pass +nomatch +nomatch +nomatch +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/ipv6.4 b/contrib/netbsd-tests/ipf/expected/ipv6.4 new file mode 100644 index 0000000..e3ae842 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ipv6.4 @@ -0,0 +1,51 @@ +pass +pass +nomatch +nomatch +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +pass +pass +pass +pass +pass +pass +pass +pass +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +-------- +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +nomatch +pass +pass +block +nomatch +nomatch +nomatch +pass +pass +-------- diff --git a/contrib/netbsd-tests/ipf/expected/ipv6.5 b/contrib/netbsd-tests/ipf/expected/ipv6.5 new file mode 100644 index 0000000..3133a7f --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ipv6.5 @@ -0,0 +1,6 @@ +pass +nomatch +-------- +block +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/ipv6.6 b/contrib/netbsd-tests/ipf/expected/ipv6.6 new file mode 100644 index 0000000..efd0421 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ipv6.6 @@ -0,0 +1,10 @@ +pass +pass +pass +pass +-------- +nomatch +nomatch +block +nomatch +-------- diff --git a/contrib/netbsd-tests/ipf/expected/l1 b/contrib/netbsd-tests/ipf/expected/l1 new file mode 100644 index 0000000..e4a081d --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/l1 @@ -0,0 +1,56 @@ +log in all +missed 1 ipf log entries: 0 1 +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF IN +01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 56 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2 -> 4.4.4.4 PR ip len 20 (20) IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 3.3.3.3,1023 -> 1.1.1.1,2049 PR udp len 20 28 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,2049 -> 3.3.3.3,1023 PR udp len 20 28 IN +-------- +pass in on anon0 all head 100 +-------- +pass in log quick from 3.3.3.3 to any group 100 +-------- +pass in log body quick from 2.2.2.2 to any +missed 1 ipf log entries: 0 1 +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 56 IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2 -> 4.4.4.4 PR ip len 20 (20) IN +-------- +pass in log quick proto tcp from 1.1.1.1 to any flags S keep state +missed 1 ipf log entries: 0 1 +01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A K-S IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS K-S IN +01/01/1970 00:00:00.000000 e1 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -A K-S OUT +01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF K-S IN +-------- +pass in log first quick proto tcp from 1.1.1.1 to any flags S keep state +missed 1 ipf log entries: 0 1 +01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN +-------- +missed 1 ipf log entries: 0 1 +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S IN +01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN +01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A K-S IN +01/01/1970 00:00:00.000000 anon0 @0:4 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS K-S IN +01/01/1970 00:00:00.000000 e1 @0:4 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -A K-S OUT +01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF K-S IN +01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @0:3 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 56 IN +01/01/1970 00:00:00.000000 anon0 @0:3 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 56 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2 -> 4.4.4.4 PR ip len 20 (20) IN +01/01/1970 00:00:00.000000 anon0 @0:3 p 2.2.2.2 -> 4.4.4.4 PR ip len 20 (20) IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 3.3.3.3,1023 -> 1.1.1.1,2049 PR udp len 20 28 IN +01/01/1970 00:00:00.000000 anon0 @100:1 p 3.3.3.3,1023 -> 1.1.1.1,2049 PR udp len 20 28 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,2049 -> 3.3.3.3,1023 PR udp len 20 28 IN +-------- diff --git a/contrib/netbsd-tests/ipf/expected/l1.b b/contrib/netbsd-tests/ipf/expected/l1.b new file mode 100644 index 0000000..e06e486 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/l1.b @@ -0,0 +1,56 @@ +missed 1 ipf log entries: 0 1 +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF IN +01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 56 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2 -> 4.4.4.4 PR ip len 20 (20) IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 3.3.3.3,1023 -> 1.1.1.1,2049 PR udp len 20 28 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,2049 -> 3.3.3.3,1023 PR udp len 20 28 IN +-------- +-------- +-------- +missed 1 ipf log entries: 0 1 +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01 02 03 04 05 06 07 08 09 0a 0b 0d ............ +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 56 IN +01 02 03 04 05 06 07 08 09 0a 0b 0d 0e 0f 40 61 ..............@a +42 63 44 65 46 67 48 69 4a 6b 4c 6d BcDeFgHiJkLm +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2 -> 4.4.4.4 PR ip len 20 (20) IN +-------- +missed 1 ipf log entries: 0 1 +01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A K-S IN +01/01/1970 00:00:00.000000 anon0 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS K-S IN +01/01/1970 00:00:00.000000 e1 @0:1 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -A K-S OUT +01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF K-S IN +-------- +missed 1 ipf log entries: 0 1 +01/01/1970 00:00:00.000000 anon0 @0:1 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN +-------- +missed 1 ipf log entries: 0 1 +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S IN +01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -S K-S IN +01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A K-S IN +01/01/1970 00:00:00.000000 anon0 @0:4 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -AS K-S IN +01/01/1970 00:00:00.000000 e1 @0:4 p 2.2.2.2,25 -> 1.1.1.1,1025 PR tcp len 20 40 -A K-S OUT +01/01/1970 00:00:00.000000 anon0 @0:4 p 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -AF K-S IN +01/01/1970 00:00:00.000000 2x anon0 @-1:-1 L 1.1.1.1,1025 -> 2.2.2.2,25 PR tcp len 20 40 -A IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01/01/1970 00:00:00.000000 anon0 @0:3 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 40 IN +01 02 03 04 05 06 07 08 09 0a 0b 0d ............ +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 56 IN +01/01/1970 00:00:00.000000 anon0 @0:3 p 2.2.2.2,1 -> 4.4.4.4,53 PR udp len 20 56 IN +01 02 03 04 05 06 07 08 09 0a 0b 0d 0e 0f 40 61 ..............@a +42 63 44 65 46 67 48 69 4a 6b 4c 6d BcDeFgHiJkLm +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 2.2.2.2 -> 4.4.4.4 PR ip len 20 (20) IN +01/01/1970 00:00:00.000000 anon0 @0:3 p 2.2.2.2 -> 4.4.4.4 PR ip len 20 (20) IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 3.3.3.3,1023 -> 1.1.1.1,2049 PR udp len 20 28 IN +01/01/1970 00:00:00.000000 anon0 @100:1 p 3.3.3.3,1023 -> 1.1.1.1,2049 PR udp len 20 28 IN +01/01/1970 00:00:00.000000 anon0 @-1:-1 L 1.1.1.1,2049 -> 3.3.3.3,1023 PR udp len 20 28 IN +-------- diff --git a/contrib/netbsd-tests/ipf/expected/n1 b/contrib/netbsd-tests/ipf/expected/n1 new file mode 100644 index 0000000..20eaedc --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n1 @@ -0,0 +1,197 @@ +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.2.2.2 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.1.1.1 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.1 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.4 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +List of active MAP/Redirect filters: +map zx0 10.1.1.1/32 -> 10.2.2.2/32 + +List of active sessions: +MAP 10.1.1.1 <- -> 10.2.2.2 [10.4.3.2] +MAP 10.1.1.1 <- -> 10.2.2.2 [10.1.1.2] + +Hostmap table: +10.1.1.1,10.4.3.2 -> 10.2.2.2,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.2 -> 10.2.2.2,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip #0 20(20) 255 10.3.4.5 > 10.1.1.2 +15 +> zx0 ip #0 20(20) 255 10.3.4.5 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.0 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +> zx0 ip #0 48(20) 1 10.3.4.5 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.1 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.4 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.1.1.1 +> zx0 ip #0 20(20) 34 10.3.4.5 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.3.4.5 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.1.1.2 +15 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.3.4.5 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +List of active MAP/Redirect filters: +map zx0 10.1.1.0/24 -> 10.3.4.5/32 + +List of active sessions: +MAP 10.1.1.3 <- -> 10.3.4.5 [10.4.3.4] +MAP 10.1.1.2 <- -> 10.3.4.5 [10.4.3.4] +MAP 10.1.1.2 <- -> 10.3.4.5 [10.4.3.2] +MAP 10.1.1.1 <- -> 10.3.4.5 [10.4.3.2] +MAP 10.1.1.2 1026 <- -> 10.3.4.5 1026 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 1025 [10.1.1.1 1025] +MAP 10.1.1.2 <- -> 10.3.4.5 [10.1.1.1] +MAP 10.1.1.0 <- -> 10.3.4.5 [10.1.1.2] + +Hostmap table: +10.1.1.3,10.4.3.4 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.4.3.4 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.4.3.2 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.1,10.4.3.2 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 3) +10.1.1.0,10.1.1.2 -> 10.3.4.5,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip #0 20(20) 255 10.3.4.1 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.3.4.2 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.3.4.3 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.3,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.3,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.3.4.3 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.1 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.1.1.1 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.4 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.3.4.3 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.3.4.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.3.4.4 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.3.4.4 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +List of active MAP/Redirect filters: +map zx0 10.1.1.0/24 -> 10.3.4.0/24 + +List of active sessions: +MAP 10.1.1.3 <- -> 10.3.4.4 [10.4.3.4] +MAP 10.1.1.3 <- -> 10.3.4.4 [10.4.3.4] +MAP 10.1.1.2 <- -> 10.3.4.3 [10.4.3.4] +MAP 10.1.1.2 <- -> 10.3.4.3 [10.4.3.2] +MAP 10.1.1.1 <- -> 10.3.4.3 [10.4.3.2] +MAP 10.1.1.2 1026 <- -> 10.3.4.3 1026 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.3 1025 [10.1.1.1 1025] +MAP 10.1.1.2 <- -> 10.3.4.3 [10.1.1.1] +MAP 10.1.1.1 <- -> 10.3.4.2 [10.1.1.2] +MAP 10.1.1.0 <- -> 10.3.4.1 [10.1.1.2] + +Hostmap table: +10.1.1.3,10.4.3.4 -> 10.3.4.4,0.0.0.0 (use = 2) +10.1.1.2,10.4.3.4 -> 10.3.4.3,0.0.0.0 (use = 1) +10.1.1.2,10.4.3.2 -> 10.3.4.3,0.0.0.0 (use = 1) +10.1.1.1,10.4.3.2 -> 10.3.4.3,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.3,0.0.0.0 (use = 3) +10.1.1.1,10.1.1.2 -> 10.3.4.2,0.0.0.0 (use = 1) +10.1.1.0,10.1.1.2 -> 10.3.4.1,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n10 b/contrib/netbsd-tests/ipf/expected/n10 new file mode 100644 index 0000000..0c03ff0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n10 @@ -0,0 +1,72 @@ +4500 002c 10c9 4000 ff06 5c9d cbcb cbcb 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 655d 0000 0204 0064 + +List of active MAP/Redirect filters: +map ppp0 0/0 -> 203.203.203.203/32 mssclamp 100 + +List of active sessions: +MAP 192.168.1.3 32818 <- -> 203.203.203.203 32818 [150.203.224.2 21] + +Hostmap table: +192.168.1.3,150.203.224.2 -> 203.203.203.203,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +4500 002c 10c9 4000 ff06 5c9d cbcb cbcb 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 61d9 0000 0204 03e8 + +List of active MAP/Redirect filters: +map ppp0 0/0 -> 203.203.203.203/32 mssclamp 1000 + +List of active sessions: +MAP 192.168.1.3 32818 <- -> 203.203.203.203 32818 [150.203.224.2 21] + +Hostmap table: +192.168.1.3,150.203.224.2 -> 203.203.203.203,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +4500 002c 10c9 4000 ff06 5c9d cbcb cbcb 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 600d 0000 0204 05b4 + +List of active MAP/Redirect filters: +map ppp0 0/0 -> 203.203.203.203/32 mssclamp 10000 + +List of active sessions: +MAP 192.168.1.3 32818 <- -> 203.203.203.203 32818 [150.203.224.2 21] + +Hostmap table: +192.168.1.3,150.203.224.2 -> 203.203.203.203,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n100 b/contrib/netbsd-tests/ipf/expected/n100 new file mode 100644 index 0000000..80f00a1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n100 @@ -0,0 +1,33 @@ +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.3.2.3 +> zx0 ip #0 20(20) 255 4.4.4.4 > 6.6.0.1 +> zx0 ip #0 20(20) 255 4.4.4.4 > 6.6.0.2 +> zx0 ip #0 20(20) 255 4.4.4.4 > 6.6.0.3 +> zx0 ip #0 20(20) 255 4.4.4.4 > 6.6.0.4 +> zx0 ip #0 20(20) 255 4.4.4.4 > 6.6.0.1 +> zx0 ip #0 40(20) 6 1.1.1.1,101 > 2.3.2.3,203 +> zx0 ip #0 40(20) 6 4.4.4.4,101 > 6.6.0.5,203 +List of active MAP/Redirect filters: +rewrite out on zx0 from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32 dst 6.6.0.0/16; + +List of active sessions: +RWR-MAP 1.1.1.1 101 2.2.2.3 203 <- -> 4.4.4.4 101 6.6.0.5 203 +RWR-MAP 1.1.1.1 2.2.2.4 <- -> 4.4.4.4 6.6.0.4 +RWR-MAP 1.2.1.2 2.2.2.3 <- -> 4.4.4.4 6.6.0.3 +RWR-MAP 1.1.1.2 2.2.2.3 <- -> 4.4.4.4 6.6.0.2 +RWR-MAP 1.1.1.1 2.2.2.3 <- -> 4.4.4.4 6.6.0.1 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n101 b/contrib/netbsd-tests/ipf/expected/n101 new file mode 100644 index 0000000..ad0ad97 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n101 @@ -0,0 +1,29 @@ +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.3.2.3 +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.2.2.3 +> zx0 ip #0 20(20) 255 1.1.1.2 > 2.2.2.3 +> zx0 ip #0 20(20) 255 1.2.1.2 > 2.2.2.3 +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.2.2.4 +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.2.2.3 +> zx0 ip #0 40(20) 6 1.1.1.1,101 > 2.3.2.3,203 +> zx0 ip #0 40(20) 6 4.4.4.4,101 > 6.6.0.1,203 +List of active MAP/Redirect filters: +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32 dst 6.6.0.0/16; + +List of active sessions: +RWR-MAP 1.1.1.1 101 2.2.2.3 203 <- -> 4.4.4.4 101 6.6.0.1 203 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n102 b/contrib/netbsd-tests/ipf/expected/n102 new file mode 100644 index 0000000..a2f130e --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n102 @@ -0,0 +1,29 @@ +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.3.2.3 +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.2.2.3 +> zx0 ip #0 20(20) 255 1.1.1.2 > 2.2.2.3 +> zx0 ip #0 20(20) 255 1.2.1.2 > 2.2.2.3 +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.2.2.4 +> zx0 ip #0 20(20) 255 1.1.1.1 > 2.2.2.3 +> zx0 ip #0 40(20) 6 1.1.1.1,101 > 2.3.2.3,203 +> zx0 ip #0 40(20) 6 4.4.4.4,1000 > 6.6.0.1,203 +List of active MAP/Redirect filters: +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32,1000-2000 dst 6.6.0.0/16; + +List of active sessions: +RWR-MAP 1.1.1.1 101 2.2.2.3 203 <- -> 4.4.4.4 1000 6.6.0.1 203 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n103 b/contrib/netbsd-tests/ipf/expected/n103 new file mode 100644 index 0000000..31ed740 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n103 @@ -0,0 +1,33 @@ +> zx0 ip #0 40(20) 6 1.1.1.1,101 > 2.3.2.3,203 +> zx0 ip #0 40(20) 6 4.4.4.4,1000 > 6.6.0.1,4000 +> zx0 ip #0 40(20) 6 4.4.4.4,1000 > 6.6.0.1,4000 +> zx0 ip #0 40(20) 6 4.4.4.4,1001 > 6.6.0.1,4000 +> zx0 ip #0 40(20) 6 4.4.4.4,1001 > 6.6.0.2,4000 +> zx0 ip #0 40(20) 6 4.4.4.4,1001 > 6.6.0.2,4001 +< zx0 ip #0 40(20) 6 2.2.2.3,4000 > 4.4.4.4,1000 +> zx0 ip #0 40(20) 6 4.4.4.4,1000 > 6.6.0.2,4001 +List of active MAP/Redirect filters: +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32,1000-1001 dst 6.6.0.0/16,4000-4001; + +List of active sessions: +RWR-MAP 7.7.7.7 101 2.2.2.3 203 <- -> 4.4.4.4 1000 6.6.0.2 4001 +RWR-MAP 5.5.5.5 101 2.2.2.3 203 <- -> 4.4.4.4 1001 6.6.0.2 4001 +RWR-MAP 10.10.10.10 101 2.2.2.3 203 <- -> 4.4.4.4 1001 6.6.0.2 4000 +RWR-MAP 1.1.1.2 101 2.2.2.3 203 <- -> 4.4.4.4 1001 6.6.0.1 4000 +RWR-MAP 1.1.1.1 101 2.2.2.3 203 <- -> 4.4.4.4 1000 6.6.0.1 4000 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n104 b/contrib/netbsd-tests/ipf/expected/n104 new file mode 100644 index 0000000..3b8a9de --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n104 @@ -0,0 +1,50 @@ +4500 0028 0001 0000 ff06 b1c3 0404 0001 0606 0001 03e8 0fa0 0000 0001 1000 0001 5010 2000 623f 0000 + +4500 0028 0002 0000 ff06 b5c8 0202 0202 0101 0101 00cb 0065 0000 0001 1000 0001 5010 2000 789d 0000 + +4500 0028 0003 0000 ff06 b1c0 0404 0002 0606 0001 03e8 0fa0 0000 0001 1000 0001 5010 2000 623e 0000 + +4500 0028 0004 0000 ff06 b5c6 0202 0202 0101 0101 00cb 0066 0000 0001 1000 0001 5010 2000 789c 0000 + +4500 0028 0005 0000 ff06 b1be 0404 0002 0606 0001 03e9 0fa0 0000 0001 1000 0001 5010 2000 623d 0000 + +4500 0028 0006 0000 ff06 b5c4 0202 0202 0101 0101 00cb 0067 0000 0001 1000 0001 5010 2000 789b 0000 + +4500 0028 0007 0000 ff06 b1bb 0404 0002 0606 0002 03e9 0fa0 0000 0001 1000 0001 5010 2000 623c 0000 + +4500 0028 0008 0000 ff06 b5c2 0202 0202 0101 0101 00cb 0068 0000 0001 1000 0001 5010 2000 789a 0000 + +4500 0028 0009 0000 ff06 b1b9 0404 0002 0606 0002 03e9 0fa1 0000 0001 1000 0001 5010 2000 623b 0000 + +4500 0028 000a 0000 ff06 b5c0 0202 0202 0101 0101 00cb 0069 0000 0001 1000 0001 5010 2000 7899 0000 + +4500 0028 000b 0000 ff06 b1b6 0404 0003 0606 0002 03e9 0fa1 0000 0001 1000 0001 5010 2000 623a 0000 + +4500 0028 000c 0000 ff06 b5be 0202 0202 0101 0101 00cb 006a 0000 0001 1000 0001 5010 2000 7898 0000 + +List of active MAP/Redirect filters: +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.0.0/24,1000-1001 dst 6.6.0.0/16,4000-4001; + +List of active sessions: +RWR-MAP 1.1.1.1 106 2.2.2.2 203 <- -> 4.4.0.3 1001 6.6.0.2 4001 +RWR-MAP 1.1.1.1 105 2.2.2.2 203 <- -> 4.4.0.2 1001 6.6.0.2 4001 +RWR-MAP 1.1.1.1 104 2.2.2.2 203 <- -> 4.4.0.2 1001 6.6.0.2 4000 +RWR-MAP 1.1.1.1 103 2.2.2.2 203 <- -> 4.4.0.2 1001 6.6.0.1 4000 +RWR-MAP 1.1.1.1 102 2.2.2.2 203 <- -> 4.4.0.2 1000 6.6.0.1 4000 +RWR-MAP 1.1.1.1 101 2.2.2.2 203 <- -> 4.4.0.1 1000 6.6.0.1 4000 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n105 b/contrib/netbsd-tests/ipf/expected/n105 new file mode 100644 index 0000000..d45a4af --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n105 @@ -0,0 +1,25 @@ +4500 0028 0001 0000 ff06 adc0 0404 0404 0606 0001 03e8 0c38 0000 0001 1000 0001 5010 2000 61a4 0000 + +4500 0028 0001 0000 ff06 b5c9 0202 0202 0101 0101 0050 0065 0000 0001 1000 0001 5010 2000 7918 0000 + +List of active MAP/Redirect filters: +rewrite in on zx0 proto tcp from 0/0 to 2.2.0.0/16 port = 80 -> src 4.4.4.4/32,1000-1001 dst 6.6.0.0/16,port = 3128; + +List of active sessions: +RWR-RDR 1.1.1.1 101 2.2.2.2 80 <- -> 4.4.4.4 1000 6.6.0.1 3128 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n106 b/contrib/netbsd-tests/ipf/expected/n106 new file mode 100644 index 0000000..d466e65 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n106 @@ -0,0 +1,25 @@ +4500 0028 0001 0000 ff06 adc0 0404 0404 0606 0001 03e8 0c38 0000 0001 1000 0001 5010 2000 61a4 0000 + +4500 0028 0001 0000 ff06 b5c9 0202 0202 0101 0101 0050 0065 0000 0001 1000 0001 5010 2000 7918 0000 + +List of active MAP/Redirect filters: +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 port = 80 -> src 4.4.4.4/32,1000-1001 dst 6.6.0.0/16,port = 3128; + +List of active sessions: +RWR-MAP 1.1.1.1 101 2.2.2.2 80 <- -> 4.4.4.4 1000 6.6.0.1 3128 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n11 b/contrib/netbsd-tests/ipf/expected/n11 new file mode 100644 index 0000000..ea11b93 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n11 @@ -0,0 +1,124 @@ +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 1.6.7.8 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +List of active MAP/Redirect filters: +bimap zx0 10.1.1.1/32 -> 1.6.7.8/32 + +List of active sessions: +BIMAP 10.1.1.1 <- -> 1.6.7.8 [10.1.1.2] + +Hostmap table: +10.1.1.1,10.1.1.2 -> 1.6.7.8,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.1.2 +15 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.1.1 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.1.1.0 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.0 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +List of active MAP/Redirect filters: +bimap zx0 10.1.1.0/24 -> 10.2.2.2/32 + +List of active sessions: +BIMAP 10.1.1.0 <- -> 10.2.2.2 [10.2.3.4] +BIMAP 10.1.1.2 <- -> 10.2.2.2 [10.1.1.1] +BIMAP 10.1.1.0 <- -> 10.2.2.2 [10.1.1.2] + +Hostmap table: +10.1.1.2,10.1.1.1 -> 10.2.2.2,0.0.0.0 (use = 1) +10.1.1.0,10.1.1.2 -> 10.2.2.2,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip #0 20(20) 255 10.3.4.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.3.4.1 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.3.4.2 > 10.1.1.1 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.5 +List of active MAP/Redirect filters: +bimap zx0 10.1.1.0/24 -> 10.3.4.0/24 + +List of active sessions: +BIMAP 10.1.1.5 <- -> 10.3.4.5 [10.1.1.2] +BIMAP 10.1.1.5 <- -> 10.3.4.5 [10.1.1.1] +BIMAP 10.1.1.5 <- -> 10.3.4.5 [10.1.1.0] +BIMAP 10.1.1.2 <- -> 10.3.4.2 [10.1.1.1] +BIMAP 10.1.1.1 <- -> 10.3.4.1 [10.1.1.2] +BIMAP 10.1.1.0 <- -> 10.3.4.0 [10.1.1.2] + +Hostmap table: +10.1.1.2,10.1.1.1 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.2 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.0,10.1.1.2 -> 10.3.4.1,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n11_6 b/contrib/netbsd-tests/ipf/expected/n11_6 new file mode 100644 index 0000000..f1c80de --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n11_6 @@ -0,0 +1,124 @@ +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 1:0:0:0:0:6:7:8 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +List of active MAP/Redirect filters: +bimap zx0 inet6 10:1:1::1/128 -> 1::6:7:8/128 + +List of active sessions: +BIMAP 10:1:1::1 <- -> 1::6:7:8 [10:1:1::2] + +Hostmap table: +10:1:1::1,10:1:1::2 -> 1::6:7:8,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:1:0:0:0:0:2 +16 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:1:1:0:0:0:0:0 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:0 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +List of active MAP/Redirect filters: +bimap zx0 inet6 10:1:1::/112 -> 10::2:2:2/128 + +List of active sessions: +BIMAP 10:1:1:: <- -> 10::2:2:2 [10::2:3:4] +BIMAP 10:1:1::2 <- -> 10::2:2:2 [10:1:1::1] +BIMAP 10:1:1:: <- -> 10::2:2:2 [10:1:1::2] + +Hostmap table: +10:1:1::2,10:1:1::1 -> 10::2:2:2,any (use = 1) +10:1:1::,10:1:1::2 -> 10::2:2:2,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:1 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:5 +List of active MAP/Redirect filters: +bimap zx0 inet6 10:1:1::/112 -> 10::3:4:0/112 + +List of active sessions: +BIMAP 10:1:1::5 <- -> 10::3:4:5 [10:1:1::2] +BIMAP 10:1:1::5 <- -> 10::3:4:5 [10:1:1::1] +BIMAP 10:1:1::5 <- -> 10::3:4:5 [10:1:1::] +BIMAP 10:1:1::2 <- -> 10::3:4:2 [10:1:1::1] +BIMAP 10:1:1::1 <- -> 10::3:4:1 [10:1:1::2] +BIMAP 10:1:1:: <- -> 10::3:4:0 [10:1:1::2] + +Hostmap table: +10:1:1::2,10:1:1::1 -> 10::3:4:1,any (use = 1) +10:1:1::1,10:1:1::2 -> 10::3:4:1,any (use = 1) +10:1:1::,10:1:1::2 -> 10::3:4:1,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n12 b/contrib/netbsd-tests/ipf/expected/n12 new file mode 100644 index 0000000..56b3a78 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n12 @@ -0,0 +1,28 @@ +4510 0040 2020 4000 4006 9478 c0a8 01bc c0a8 0303 2710 0017 4e33 298e 0000 0000 b002 4000 6ff8 0000 0204 05b4 0101 0402 0103 0300 0101 080a 0c72 549e 0000 0000 + +4500 003c 00b0 4000 fe06 7964 c0a8 0303 c0a8 7e53 0017 12c2 f674 e02c 4e33 298f a012 2798 7ace 0000 0101 080a 2c05 b797 0c72 549e 0103 0300 0204 05b4 + +4510 0034 493b 4000 4006 6b69 c0a8 01bc c0a8 0303 2710 0017 4e33 298f f674 e02d 8010 4000 f673 0000 0101 080a 0c72 549e 2c05 b797 + +List of active MAP/Redirect filters: +map le0 192.168.126.0/24 -> 0/32 portmap tcp/udp 10000:20000 sequential + +List of active sessions: +MAP 192.168.126.83 4802 <- -> 192.168.1.188 10000 [192.168.3.3 23] + +Hostmap table: +192.168.126.83,192.168.3.3 -> 0.0.0.0,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n12_6 b/contrib/netbsd-tests/ipf/expected/n12_6 new file mode 100644 index 0000000..9ef040a --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n12_6 @@ -0,0 +1,28 @@ +6000 0000 002c 0640 c0a8 0100 0000 0000 0000 0000 0000 00bc c0a8 0300 0000 0000 0000 0000 0000 0003 2710 0017 4e33 298e 0000 0000 b002 4000 6ff8 0000 0204 05b4 0101 0402 0103 0300 0101 080a 0c72 549e 0000 0000 + +6000 0000 0028 06fe c0a8 0300 0000 0000 0000 0000 0000 0003 c0a8 7e00 0000 0000 0000 0000 0000 0053 0017 12c2 f674 e02c 4e33 298f a012 2798 7ace 0000 0101 080a 2c05 b797 0c72 549e 0103 0300 0204 05b4 + +6000 0000 0020 0640 c0a8 0100 0000 0000 0000 0000 0000 00bc c0a8 0300 0000 0000 0000 0000 0000 0003 2710 0017 4e33 298f f674 e02d 8010 4000 f673 0000 0101 080a 0c72 549e 2c05 b797 + +List of active MAP/Redirect filters: +map le0 inet6 c0a8:7e00::/112 -> ::/128 portmap tcp/udp 10000:20000 + +List of active sessions: +MAP c0a8:7e00::53 4802 <- -> c0a8:100::bc 10000 [c0a8:300::3 23] + +Hostmap table: +c0a8:7e00::53,c0a8:300::3 -> any,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n13 b/contrib/netbsd-tests/ipf/expected/n13 new file mode 100644 index 0000000..e6d26b2 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n13 @@ -0,0 +1,32 @@ +> le0 ip #0 20(20) 0 203.1.1.23 > 150.1.1.1 +> le0 ip #0 20(20) 0 203.1.1.23 > 150.1.1.2 +> le0 ip #0 20(20) 0 203.1.1.24 > 150.1.1.2 +> le0 ip #0 20(20) 0 203.1.1.25 > 150.1.1.1 +List of active MAP/Redirect filters: +map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 + +List of active sessions: +MAP 192.168.1.3 <- -> 203.1.1.25 [150.1.1.1] +MAP 192.168.1.2 <- -> 203.1.1.24 [150.1.1.2] +MAP 192.168.1.1 <- -> 203.1.1.23 [150.1.1.2] +MAP 192.168.1.1 <- -> 203.1.1.23 [150.1.1.1] + +Hostmap table: +192.168.1.3,150.1.1.1 -> 203.1.1.25,0.0.0.0 (use = 1) +192.168.1.2,150.1.1.2 -> 203.1.1.24,0.0.0.0 (use = 1) +192.168.1.1,150.1.1.2 -> 203.1.1.23,0.0.0.0 (use = 1) +192.168.1.1,150.1.1.1 -> 203.1.1.23,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n13_6 b/contrib/netbsd-tests/ipf/expected/n13_6 new file mode 100644 index 0000000..d3b5fe7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n13_6 @@ -0,0 +1,32 @@ +> le0 ip6/0 1 0 41 203:0:1:0:0:0:1:23 > 150.1.1.1 +> le0 ip6/0 1 0 41 203:0:1:0:0:0:1:23 > 150.1.1.2 +> le0 ip6/0 1 0 41 203:0:1:0:0:0:1:24 > 150.1.1.2 +> le0 ip6/0 1 0 41 203:0:1:0:0:0:1:25 > 150.1.1.1 +List of active MAP/Redirect filters: +map le0 inet6 192:168:0::0/48 -> range 203:0:1::1:23-203:0:1::3:45 + +List of active sessions: +MAP 192.168.1.3 <- -> 203:0:1::1:25 [150.1.1.1] +MAP 192.168.1.2 <- -> 203:0:1::1:24 [150.1.1.2] +MAP 192.168.1.1 <- -> 203:0:1::1:23 [150.1.1.2] +MAP 192.168.1.1 <- -> 203:0:1::1:23 [150.1.1.1] + +Hostmap table: +192.168.1.3,150.1.1.1 -> 203:0:1:0:0:0:1:25,any (use = 1) +192.168.1.2,150.1.1.2 -> 203:0:1:0:0:0:1:24,any (use = 1) +192.168.1.1,150.1.1.2 -> 203:0:1:0:0:0:1:23,any (use = 1) +192.168.1.1,150.1.1.1 -> 203:0:1:0:0:0:1:23,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n14 b/contrib/netbsd-tests/ipf/expected/n14 new file mode 100644 index 0000000..14e1401 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n14 @@ -0,0 +1,30 @@ +< gre0 ip #0 40(20) 6 10.2.2.5,2000 > 10.1.1.254,80 +< gre0 ip #0 40(20) 6 10.2.2.6,2000 > 10.1.1.253,80 +< gre0 ip #0 40(20) 6 10.2.2.7,2000 > 10.1.1.254,80 +15 +List of active MAP/Redirect filters: +rdr gre0 0/0 port 80 -> 10.1.1.254,10.1.1.253 port 80 tcp sticky + +List of active sessions: +RDR 10.1.1.254 80 <- -> 203.1.1.1 80 [10.2.2.7 2000] +RDR 10.1.1.253 80 <- -> 203.1.1.1 80 [10.2.2.6 2000] +RDR 10.1.1.254 80 <- -> 203.1.1.1 80 [10.2.2.5 2000] + +Hostmap table: +10.2.2.7,203.1.1.1 -> 10.1.1.254,0.0.0.0 (use = 1) +10.2.2.6,203.1.1.1 -> 10.1.1.253,0.0.0.0 (use = 1) +10.2.2.5,203.1.1.1 -> 10.1.1.254,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n14_6 b/contrib/netbsd-tests/ipf/expected/n14_6 new file mode 100644 index 0000000..c177b62 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n14_6 @@ -0,0 +1,30 @@ +< gre0 ip6/0 20 0 6 10:0:0:0:0:2:2:5,2000 > 10:1:1:0:0:0:0:254,80 +< gre0 ip6/0 20 0 6 10:0:0:0:0:2:2:6,2000 > 10:1:1:0:0:0:0:253,80 +< gre0 ip6/0 20 0 6 10:0:0:0:0:2:2:7,2000 > 10:1:1:0:0:0:0:254,80 +< gre0 ip6/0 20 0 6 10:0:0:0:0:2:2:5,2001 > 203:0:1:0:0:0:1:1,80 +List of active MAP/Redirect filters: +rdr gre0 inet6 any port 80 -> 10:1:1::254,10:1:1::253 port 80 tcp sticky + +List of active sessions: +RDR 10:1:1::254 80 <- -> 203:0:1::1:1 80 [10::2:2:7 2000] +RDR 10:1:1::253 80 <- -> 203:0:1::1:1 80 [10::2:2:6 2000] +RDR 10:1:1::254 80 <- -> 203:0:1::1:1 80 [10::2:2:5 2000] + +Hostmap table: +10::2:2:7,203:0:1:0:0:0:1:1 -> 10:1:1::254,any (use = 1) +10::2:2:6,203:0:1:0:0:0:1:1 -> 10:0:1:0:0:0:1:253,any (use = 1) +10::2:2:5,203:0:1:0:0:0:1:1 -> 10:1:1::254,any (use = 3) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n15 b/contrib/netbsd-tests/ipf/expected/n15 new file mode 100644 index 0000000..3889f82 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n15 @@ -0,0 +1,47 @@ +< le0 ip #0 40(20) 6 9.9.9.9,10011 > 3.3.3.3,80 +15 +List of active MAP/Redirect filters: +rdr le0 0/0 port 80 -> 3.3.3.3/32 port 80 tcp + +List of active sessions: +RDR 3.3.3.3 80 <- -> 5.5.5.5 80 [9.9.9.9 10011] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< le0 ip #0 40(20) 6 9.9.9.9,10011 > 3.3.3.3,80 +< le0 ip #0 40(20) 6 9.9.9.9,10011 > 3.3.3.3,81 +List of active MAP/Redirect filters: +rdr le0 0/0 port 80 -> 3.3.3.3/32 port 80-88 tcp + +List of active sessions: +RDR 3.3.3.3 81 <- -> 2.2.2.2 80 [9.9.9.9 10011] +RDR 3.3.3.3 80 <- -> 5.5.5.5 80 [9.9.9.9 10011] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n15_6 b/contrib/netbsd-tests/ipf/expected/n15_6 new file mode 100644 index 0000000..f01b72b --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n15_6 @@ -0,0 +1,47 @@ +< le0 ip6/0 20 0 6 9:9:9:0:0:0:0:9,10011 > 3:0:3:0:0:0:3:3,80 +16 +List of active MAP/Redirect filters: +rdr le0 inet6 any port 80 -> 3:0:3::3:3/128 port 80 tcp + +List of active sessions: +RDR 3:0:3::3:3 80 <- -> 5:5::5:5 80 [9:9:9::9 10011] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< le0 ip6/0 20 0 6 9:9:9:0:0:0:0:9,10011 > 3:0:3:0:0:0:3:3,80 +< le0 ip6/0 20 0 6 9:9:9:0:0:0:0:9,10011 > 3:0:3:0:0:0:3:3,81 +List of active MAP/Redirect filters: +rdr le0 inet6 any port 80 -> 3:0:3::3:3/128 port 80-88 tcp + +List of active sessions: +RDR 3:0:3::3:3 81 <- -> 2::2:2:2 80 [9:9:9::9 10011] +RDR 3:0:3::3:3 80 <- -> 5:5::5:5 80 [9:9:9::9 10011] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n16 b/contrib/netbsd-tests/ipf/expected/n16 new file mode 100644 index 0000000..0eb3954 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n16 @@ -0,0 +1,29 @@ +4520 0068 17e4 0000 6b11 cbba c05b ac33 ac1f 5318 1194 07dd 0054 0000 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 + +4520 0068 17e4 0000 6a11 ccba c05b ac33 ac1f 5318 1194 07dd 0054 0000 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 + +4500 0084 ee0f 0000 8001 e0a2 ac1f 5318 c05b ac33 0303 4ca1 0000 0000 4520 0068 17e4 0000 6a11 ccba c05b ac33 ac1f 5318 1194 07dd 0054 0000 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 + +4500 0084 ee0f 0000 8001 4a21 45f8 4fc1 c05b ac33 0303 bf85 0000 0000 4520 0068 17e4 0000 6a11 3639 c05b ac33 45f8 4fc1 1194 94f8 0054 0000 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 + +List of active MAP/Redirect filters: +rdr vlan0 from 0/0 to 69.248.79.193/32 port = 38136 -> 172.31.83.24/32 port 2013 udp + +List of active sessions: +RDR 172.31.83.24 2013 <- -> 69.248.79.193 38136 [192.91.172.51 4500] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n17 b/contrib/netbsd-tests/ipf/expected/n17 new file mode 100644 index 0000000..f336bb0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n17 @@ -0,0 +1,24 @@ +4500 00a0 0000 0100 3f06 7555 0101 0101 0201 0101 0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 00a0 0000 0100 3f06 7553 0201 0101 0101 0103 0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +List of active MAP/Redirect filters: +bimap zx0 0/0 -> 1.1.1.3/32 + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n18 b/contrib/netbsd-tests/ipf/expected/n18 new file mode 100644 index 0000000..c51c11c --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n18 @@ -0,0 +1,111 @@ +> z0 ip #0 40(20) 6 1.1.1.1,1 > 3.3.3.3,30 +> z0 ip #0 40(20) 6 1.1.1.1,2 > 3.3.3.3,31 +> z0 ip #0 40(20) 6 1.1.1.1,3 > 3.3.3.3,32 +> z0 ip #0 40(20) 6 1.1.1.1,4 > 3.3.3.3,33 +> z0 ip #0 40(20) 6 1.1.1.1,1 > 3.3.3.3,34 +> z0 ip #0 40(20) 6 1.1.1.1,2 > 3.3.3.3,35 +> z0 ip #0 40(20) 6 1.1.1.1,3 > 3.3.3.3,36 +> z0 ip #0 40(20) 6 1.1.1.1,4 > 3.3.3.3,37 +List of active MAP/Redirect filters: +map z0 0/0 -> 1.1.1.1/32 portmap tcp/udp 1:4 sequential + +List of active sessions: +MAP 2.2.2.2 29 <- -> 1.1.1.1 4 [3.3.3.3 37] +MAP 2.2.2.2 28 <- -> 1.1.1.1 3 [3.3.3.3 36] +MAP 2.2.2.2 27 <- -> 1.1.1.1 2 [3.3.3.3 35] +MAP 2.2.2.2 26 <- -> 1.1.1.1 1 [3.3.3.3 34] +MAP 2.2.2.2 25 <- -> 1.1.1.1 4 [3.3.3.3 33] +MAP 2.2.2.2 24 <- -> 1.1.1.1 3 [3.3.3.3 32] +MAP 2.2.2.2 23 <- -> 1.1.1.1 2 [3.3.3.3 31] +MAP 2.2.2.2 22 <- -> 1.1.1.1 1 [3.3.3.3 30] + +Hostmap table: +2.2.2.2,3.3.3.3 -> 1.1.1.1,0.0.0.0 (use = 8) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> z0 ip #0 40(20) 6 1.1.1.1,1000 > 3.3.3.3,30 +> z0 ip #0 40(20) 6 1.1.1.1,1001 > 3.3.3.3,31 +> z0 ip #0 40(20) 6 1.1.1.1,1002 > 3.3.3.3,32 +> z0 ip #0 40(20) 6 1.1.1.1,1003 > 3.3.3.3,33 +> z0 ip #0 40(20) 6 1.1.1.1,1004 > 3.3.3.3,34 +> z0 ip #0 40(20) 6 1.1.1.1,1005 > 3.3.3.3,35 +> z0 ip #0 40(20) 6 1.1.1.1,1006 > 3.3.3.3,36 +> z0 ip #0 40(20) 6 1.1.1.1,1007 > 3.3.3.3,37 +List of active MAP/Redirect filters: +map z0 0/0 -> 1.1.1.1/32 portmap tcp/udp 1000:5000 sequential + +List of active sessions: +MAP 2.2.2.2 29 <- -> 1.1.1.1 1007 [3.3.3.3 37] +MAP 2.2.2.2 28 <- -> 1.1.1.1 1006 [3.3.3.3 36] +MAP 2.2.2.2 27 <- -> 1.1.1.1 1005 [3.3.3.3 35] +MAP 2.2.2.2 26 <- -> 1.1.1.1 1004 [3.3.3.3 34] +MAP 2.2.2.2 25 <- -> 1.1.1.1 1003 [3.3.3.3 33] +MAP 2.2.2.2 24 <- -> 1.1.1.1 1002 [3.3.3.3 32] +MAP 2.2.2.2 23 <- -> 1.1.1.1 1001 [3.3.3.3 31] +MAP 2.2.2.2 22 <- -> 1.1.1.1 1000 [3.3.3.3 30] + +Hostmap table: +2.2.2.2,3.3.3.3 -> 1.1.1.1,0.0.0.0 (use = 8) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> z0 ip #0 40(20) 6 1.1.1.1,1000 > 3.3.3.3,30 +> z0 ip #0 40(20) 6 1.1.1.1,1001 > 3.3.3.3,31 +> z0 ip #0 40(20) 6 1.1.1.1,1002 > 3.3.3.3,32 +> z0 ip #0 40(20) 6 1.1.1.1,1003 > 3.3.3.3,33 +> z0 ip #0 40(20) 6 1.1.1.1,1004 > 3.3.3.3,34 +> z0 ip #0 40(20) 6 1.1.1.1,1005 > 3.3.3.3,35 +> z0 ip #0 40(20) 6 1.1.1.1,1006 > 3.3.3.3,36 +> z0 ip #0 40(20) 6 1.1.1.1,1007 > 3.3.3.3,37 +List of active MAP/Redirect filters: +map z0 0/0 -> 1.1.1.1/32 portmap tcp/udp 1000:50000 sequential + +List of active sessions: +MAP 2.2.2.2 29 <- -> 1.1.1.1 1007 [3.3.3.3 37] +MAP 2.2.2.2 28 <- -> 1.1.1.1 1006 [3.3.3.3 36] +MAP 2.2.2.2 27 <- -> 1.1.1.1 1005 [3.3.3.3 35] +MAP 2.2.2.2 26 <- -> 1.1.1.1 1004 [3.3.3.3 34] +MAP 2.2.2.2 25 <- -> 1.1.1.1 1003 [3.3.3.3 33] +MAP 2.2.2.2 24 <- -> 1.1.1.1 1002 [3.3.3.3 32] +MAP 2.2.2.2 23 <- -> 1.1.1.1 1001 [3.3.3.3 31] +MAP 2.2.2.2 22 <- -> 1.1.1.1 1000 [3.3.3.3 30] + +Hostmap table: +2.2.2.2,3.3.3.3 -> 1.1.1.1,0.0.0.0 (use = 8) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n1_6 b/contrib/netbsd-tests/ipf/expected/n1_6 new file mode 100644 index 0000000..347bf4a --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n1_6 @@ -0,0 +1,197 @@ +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:0:0:0:0:2:2:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:1 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::1/128 -> 10::2:2:2/128 + +List of active sessions: +MAP 10:1:1::1 <- -> 10::2:2:2 [10:4:3::2] +MAP 10:1:1::1 <- -> 10::2:2:2 [10:1:1::2] + +Hostmap table: +10:1:1::1,10:4:3::2 -> 10::2:2:2,any (use = 1) +10:1:1::1,10:1:1::2 -> 10::2:2:2,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:5 > 10:1:1:0:0:0:0:2 +16 +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:5 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:0 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 88 0 58 10:0:0:0:0:3:4:5 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:1 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:5 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:5 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:1:1:0:0:0:0:2 +16 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:0:0:0:0:3:4:5 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::/112 -> 10::3:4:5/128 + +List of active sessions: +MAP 10:1:1::3 <- -> 10::3:4:5 [10:4:3::4] +MAP 10:1:1::2 <- -> 10::3:4:5 [10:4:3::4] +MAP 10:1:1::2 <- -> 10::3:4:5 [10:4:3::2] +MAP 10:1:1::1 <- -> 10::3:4:5 [10:4:3::2] +MAP 10:1:1::2 1026 <- -> 10::3:4:5 1026 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 1025 [10:1:1::1 1025] +MAP 10:1:1::2 <- -> 10::3:4:5 [10:1:1::1] +MAP 10:1:1:: <- -> 10::3:4:5 [10:1:1::2] + +Hostmap table: +10:1:1::3,10:4:3::4 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:4:3::4 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:4:3::2 -> 10::3:4:5,any (use = 1) +10:1:1::1,10:4:3::2 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:5,any (use = 3) +10:1:1::,10:1:1::2 -> 10::3:4:5,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:1 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:2 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:3 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:3,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:3,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:0:0:0:0:3:4:3 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:1 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:3 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:4 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:0:0:0:0:3:4:4 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::/112 -> 10::3:4:0/112 + +List of active sessions: +MAP 10:1:1::3 <- -> 10::3:4:4 [10:4:3::4] +MAP 10:1:1::3 <- -> 10::3:4:4 [10:4:3::4] +MAP 10:1:1::2 <- -> 10::3:4:3 [10:4:3::4] +MAP 10:1:1::2 <- -> 10::3:4:3 [10:4:3::2] +MAP 10:1:1::1 <- -> 10::3:4:3 [10:4:3::2] +MAP 10:1:1::2 1026 <- -> 10::3:4:3 1026 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:3 1025 [10:1:1::1 1025] +MAP 10:1:1::2 <- -> 10::3:4:3 [10:1:1::1] +MAP 10:1:1::1 <- -> 10::3:4:2 [10:1:1::2] +MAP 10:1:1:: <- -> 10::3:4:1 [10:1:1::2] + +Hostmap table: +10:1:1::3,10:4:3::4 -> 10::3:4:4,any (use = 2) +10:1:1::2,10:4:3::4 -> 10::3:4:3,any (use = 1) +10:1:1::2,10:4:3::2 -> 10::3:4:3,any (use = 1) +10:1:1::1,10:4:3::2 -> 10::3:4:3,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:3,any (use = 3) +10:1:1::1,10:1:1::2 -> 10::3:4:2,any (use = 1) +10:1:1::,10:1:1::2 -> 10::3:4:1,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n2 b/contrib/netbsd-tests/ipf/expected/n2 new file mode 100644 index 0000000..836608a --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n2 @@ -0,0 +1,191 @@ +> zx0 ip #0 40(20) 6 10.2.2.2,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.2.2.2,10001 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.1.1/32 -> 10.2.2.2/32 portmap tcp 10000:20000 sequential + +List of active sessions: +MAP 10.1.1.1 1025 <- -> 10.2.2.2 10001 [10.1.1.2 1025] +MAP 10.1.1.1 1025 <- -> 10.2.2.2 10000 [10.1.1.1 1025] + +Hostmap table: +10.1.1.1,10.1.1.2 -> 10.2.2.2,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.1 -> 10.2.2.2,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.3.4.5,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000 sequential + +List of active sessions: +MAP 10.1.1.2 1025 <- -> 10.3.4.5 10000 [10.1.1.1 1025] + +Hostmap table: +10.1.1.2,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip #0 40(20) 6 10.3.4.1,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10001 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.3.4.1,10002 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10002 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10003 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.3.4.1,10004 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10005 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.3.4.1,10006 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.3.4.1,10007 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.3.4.1,10008 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000 sequential + +List of active sessions: +MAP 10.1.1.3 2003 <- -> 10.3.4.1 10008 [10.1.4.1 80] +MAP 10.1.1.3 2002 <- -> 10.3.4.1 10007 [10.1.4.1 80] +MAP 10.1.1.3 2001 <- -> 10.3.4.1 10006 [10.1.3.1 80] +MAP 10.1.1.3 2000 <- -> 10.3.4.1 10005 [10.1.2.1 80] +MAP 10.1.1.2 1025 <- -> 10.3.4.1 10004 [10.1.1.1 1025] +MAP 10.1.1.2 1026 <- -> 10.3.4.1 10003 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.1 10002 [10.1.1.1 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.1 10001 [10.1.1.2 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.1 10000 [10.1.1.1 1025] + +Hostmap table: +10.1.1.3,10.1.4.1 -> 10.3.4.1,0.0.0.0 (use = 2) +10.1.1.3,10.1.3.1 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.3,10.1.2.1 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.1,0.0.0.0 (use = 3) +10.1.1.1,10.1.1.2 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.1 -> 10.3.4.1,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.1,1025 +15 +> zx0 ip #0 28(20) 17 10.3.4.5,40000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.1.1.3,2000 +List of active MAP/Redirect filters: +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001 sequential + +List of active sessions: +MAP 10.1.1.3 2003 <- -> 10.3.4.5 40000 [10.1.4.1 80] +MAP 10.1.1.3 2002 <- -> 10.3.4.5 40001 [10.1.4.1 80] +MAP 10.1.1.3 2001 <- -> 10.3.4.5 40000 [10.1.3.1 80] +MAP 10.1.1.3 2000 <- -> 10.3.4.5 40001 [10.1.2.1 80] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 40000 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 40001 [10.1.1.1 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.5 40001 [10.1.1.2 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.5 40000 [10.1.1.1 1025] + +Hostmap table: +10.1.1.3,10.1.4.1 -> 10.3.4.5,0.0.0.0 (use = 2) +10.1.1.3,10.1.3.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.3,10.1.2.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 2) +10.1.1.1,10.1.1.2 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n200 b/contrib/netbsd-tests/ipf/expected/n200 new file mode 100644 index 0000000..0f3c6a5 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n200 @@ -0,0 +1,25 @@ +4500 0044 0000 0000 ff11 bda6 7f00 0001 7f00 0001 2775 2775 0030 0000 4500 0028 0000 0000 0006 435a 6363 6363 5858 5858 038d 0050 0000 0000 0000 0000 5000 1000 2491 0000 + +4500 0028 0000 0000 0006 435a 6363 6363 5858 5858 038d 0050 0000 0000 0000 0000 5000 1000 2491 0000 + +List of active MAP/Redirect filters: +divert in on bar0 proto tcp from 0/0 to 0/0 -> src 127.0.0.1/32,10101 dst 127.0.0.1/32,10101 udp; + +List of active sessions: +DIV-RDR 127.0.0.1 10101 <- -> 88.88.88.88 80 [99.99.99.99 909] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n2_6 b/contrib/netbsd-tests/ipf/expected/n2_6 new file mode 100644 index 0000000..08abc8f --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n2_6 @@ -0,0 +1,191 @@ +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,10001 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2002 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2003 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::1/128 -> 10::2:2:2/128 portmap tcp 10000:20000 sequential + +List of active sessions: +MAP 10:1:1::1 1025 <- -> 10::2:2:2 10001 [10:1:1::2 1025] +MAP 10:1:1::1 1025 <- -> 10::2:2:2 10000 [10:1:1::1 1025] + +Hostmap table: +10:1:1::1,10:1:1::2 -> 10::2:2:2,any (use = 1) +10:1:1::1,10:1:1::1 -> 10::2:2:2,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2002 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2003 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::/112 -> 10::3:4:5/128 portmap udp 10000:20000 sequential + +List of active sessions: +MAP 10:1:1::2 1025 <- -> 10::3:4:5 10000 [10:1:1::1 1025] + +Hostmap table: +10:1:1::2,10:1:1::1 -> 10::3:4:5,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10001 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10002 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10002 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10003 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:1,10004 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10005 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10006 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10007 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10008 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1::/32 -> 10::3:4:0/112 portmap tcp/udp 10000:20000 sequential + +List of active sessions: +MAP 10:1:1::3 2003 <- -> 10::3:4:1 10008 [10:1:4::1 80] +MAP 10:1:1::3 2002 <- -> 10::3:4:1 10007 [10:1:4::1 80] +MAP 10:1:1::3 2001 <- -> 10::3:4:1 10006 [10:1:3::1 80] +MAP 10:1:1::3 2000 <- -> 10::3:4:1 10005 [10:1:2::1 80] +MAP 10:1:1::2 1025 <- -> 10::3:4:1 10004 [10:1:1::1 1025] +MAP 10:1:1::2 1026 <- -> 10::3:4:1 10003 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:1 10002 [10:1:1::1 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:1 10001 [10:1:1::2 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:1 10000 [10:1:1::1 1025] + +Hostmap table: +10:1:1::3,10:1:4::1 -> 10::3:4:1,any (use = 2) +10:1:1::3,10:1:3::1 -> 10::3:4:1,any (use = 1) +10:1:1::3,10:1:2::1 -> 10::3:4:1,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:1,any (use = 3) +10:1:1::1,10:1:1::2 -> 10::3:4:1,any (use = 1) +10:1:1::1,10:1:1::1 -> 10::3:4:1,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:1:0:0:0:0:1,1025 +16 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,40000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:1,1025 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:1:1:0:0:0:0:3,2000 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::/112 -> 10::3:4:5/128 portmap tcp/udp 40000:40001 sequential + +List of active sessions: +MAP 10:1:1::3 2003 <- -> 10::3:4:5 40000 [10:1:4::1 80] +MAP 10:1:1::3 2002 <- -> 10::3:4:5 40001 [10:1:4::1 80] +MAP 10:1:1::3 2001 <- -> 10::3:4:5 40000 [10:1:3::1 80] +MAP 10:1:1::3 2000 <- -> 10::3:4:5 40001 [10:1:2::1 80] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 40000 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 40001 [10:1:1::1 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:5 40001 [10:1:1::2 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:5 40000 [10:1:1::1 1025] + +Hostmap table: +10:1:1::3,10:1:4::1 -> 10::3:4:5,any (use = 2) +10:1:1::3,10:1:3::1 -> 10::3:4:5,any (use = 1) +10:1:1::3,10:1:2::1 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:5,any (use = 2) +10:1:1::1,10:1:1::2 -> 10::3:4:5,any (use = 1) +10:1:1::1,10:1:1::1 -> 10::3:4:5,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n3 b/contrib/netbsd-tests/ipf/expected/n3 new file mode 100644 index 0000000..66ada76 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n3 @@ -0,0 +1,66 @@ +> zz0 ip #0 40(20) 6 192.168.2.1,1488 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.2.1,1276 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.2.1,1032 > 203.1.1.1,80 +> zz0 ip #0 28(20) 17 192.168.2.1,1032 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.2.1,65299 > 203.1.1.1,80 +List of active MAP/Redirect filters: +map zz0 10.1.0.0/16 -> 192.168.2.0/24 portmap tcp/udp auto + +List of active sessions: +MAP 10.1.255.255 65535 <- -> 192.168.2.1 65299 [203.1.1.1 80] +MAP 10.1.0.0 32768 <- -> 192.168.2.1 1032 [203.1.1.1 80] +MAP 10.1.0.0 32768 <- -> 192.168.2.1 1032 [203.1.1.1 80] +MAP 10.1.1.1 252 <- -> 192.168.2.1 1276 [203.1.1.1 80] +MAP 10.1.1.1 5000 <- -> 192.168.2.1 1488 [203.1.1.1 80] + +Hostmap table: +10.1.255.255,203.1.1.1 -> 192.168.2.1,0.0.0.0 (use = 1) +10.1.0.0,203.1.1.1 -> 192.168.2.1,0.0.0.0 (use = 2) +10.1.1.1,203.1.1.1 -> 192.168.2.1,0.0.0.0 (use = 2) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zz0 ip #0 40(20) 6 192.168.1.1,1488 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.1.1,1276 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.1.0,1032 > 203.1.1.1,80 +> zz0 ip #0 28(20) 17 192.168.1.0,1032 > 203.1.1.1,80 +> zz0 ip #0 40(20) 6 192.168.1.255,65299 > 203.1.1.1,80 +List of active MAP/Redirect filters: +map-block zz0 10.1.0.0/16 -> 192.168.1.0/24 ports 252 + +List of active sessions: +MAP-BLOCK 10.1.255.255 65535 <- -> 192.168.1.255 65299 [203.1.1.1 80] +MAP-BLOCK 10.1.0.0 32768 <- -> 192.168.1.0 1032 [203.1.1.1 80] +MAP-BLOCK 10.1.0.0 32768 <- -> 192.168.1.0 1032 [203.1.1.1 80] +MAP-BLOCK 10.1.1.1 252 <- -> 192.168.1.1 1276 [203.1.1.1 80] +MAP-BLOCK 10.1.1.1 5000 <- -> 192.168.1.1 1488 [203.1.1.1 80] + +Hostmap table: +10.1.255.255,203.1.1.1 -> 192.168.1.1,0.0.0.0 (use = 1) +10.1.0.0,203.1.1.1 -> 192.168.1.1,0.0.0.0 (use = 2) +10.1.1.1,203.1.1.1 -> 192.168.1.1,0.0.0.0 (use = 2) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n4 b/contrib/netbsd-tests/ipf/expected/n4 new file mode 100644 index 0000000..746ef7e --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n4 @@ -0,0 +1,190 @@ +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +> zx0 ip #0 40(20) 6 10.1.1.1,23 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +> zx0 ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.1/32 port 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +> zx0 ip #0 40(20) 6 10.1.1.1,23 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +> zx0 ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.0/24 port 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +> zx0 ip #0 40(20) 6 10.1.1.1,23 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +> zx0 ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12346 > 10.2.2.1,10023 +> zx0 ip #0 40(20) 6 10.1.0.0,23 > 10.3.3.3,12346 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 +List of active MAP/Redirect filters: +rdr zx0 0/0 port 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.0.0 23 [10.3.3.3 12346] +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +> zx0 ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.2.2.1,10053 +> zx0 ip #0 28(20) 17 10.1.1.0,53 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 40(20) 6 10.2.2.1,53 > 10.3.3.3,12345 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.0/24 port 53 -> 10.2.2.1/32 port 10053 udp + +List of active sessions: +RDR 10.2.2.1 10053 <- -> 10.1.1.0 53 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,53 +> zx0 ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +> zx0 ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 +15 +> zx0 ip #0 40(20) 6 10.1.1.1,53 > 10.3.3.3,12345 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.0/24 port 0 -> 10.2.2.1/32 port 0 tcp + +List of active sessions: +RDR 10.2.2.1 53 <- -> 10.1.1.1 53 [10.3.3.3 12345] +RDR 10.2.2.1 23 <- -> 10.1.1.1 23 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,53 +> zx0 ip #0 40(20) 6 10.2.2.1,10053 > 10.3.3.3,12345 +< zx0 ip #0 40(20) 6 10.3.3.3,12346 > 10.1.0.0,23 +> zx0 ip #0 40(20) 6 10.2.2.1,10023 > 10.3.3.3,12346 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.2.2.1,53 +> zx0 ip #0 28(20) 17 10.2.2.1,10053 > 10.3.3.3,12345 +15 +> zx0 ip #0 40(20) 6 10.1.1.1,53 > 10.3.3.3,12345 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.0/24 -> 10.2.2.1/32 ip + +List of active sessions: +RDR 10.2.2.1 53 <- -> 10.1.1.0 53 [10.3.3.3 12345] +RDR 10.2.2.1 53 <- -> 10.1.1.1 53 [10.3.3.3 12345] +RDR 10.2.2.1 23 <- -> 10.1.1.1 23 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n4_6 b/contrib/netbsd-tests/ipf/expected/n4_6 new file mode 100644 index 0000000..e9a5ce3 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n4_6 @@ -0,0 +1,190 @@ +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10023 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,23 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12346 > 10:1:0:0:0:0:0:0,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12346 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,53 > 10:3:3:0:0:0:0:3,12345 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::1/128 port 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10023 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,23 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12346 > 10:1:0:0:0:0:0:0,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12346 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,53 > 10:3:3:0:0:0:0:3,12345 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::/112 port 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10023 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,23 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12346 > 10:0:0:0:0:2:2:1,10023 +> zx0 ip6/0 20 0 6 10:1:0:0:0:0:0:0,23 > 10:3:3:0:0:0:0:3,12346 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,53 > 10:3:3:0:0:0:0:3,12345 +List of active MAP/Redirect filters: +rdr zx0 inet6 any port 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:: 23 [10:3:3::3 12346] +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12346 > 10:1:0:0:0:0:0:0,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12346 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10053 +> zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:0,53 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,53 > 10:3:3:0:0:0:0:3,12345 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::/112 port 53 -> 10::2:2:1/128 port 10053 udp + +List of active sessions: +RDR 10::2:2:1 10053 <- -> 10:1:1:: 53 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12346 > 10:1:0:0:0:0:0:0,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12346 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +> zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +16 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,53 > 10:3:3:0:0:0:0:3,12345 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::/112 port 0 -> 10::2:2:1/128 port 0 tcp + +List of active sessions: +RDR 10::2:2:1 53 <- -> 10:1:1::1 53 [10:3:3::3 12345] +RDR 10::2:2:1 23 <- -> 10:1:1::1 23 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,53 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12346 > 10:1:0:0:0:0:0:0,23 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:1,10023 > 10:3:3:0:0:0:0:3,12346 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,53 +> zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:1,10053 > 10:3:3:0:0:0:0:3,12345 +16 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,53 > 10:3:3:0:0:0:0:3,12345 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::/112 -> 10::2:2:1/128 ip + +List of active sessions: +RDR 10::2:2:1 53 <- -> 10:1:1:: 53 [10:3:3::3 12345] +RDR 10::2:2:1 53 <- -> 10:1:1::1 53 [10:3:3::3 12345] +RDR 10::2:2:1 23 <- -> 10:1:1::1 23 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n5 b/contrib/netbsd-tests/ipf/expected/n5 new file mode 100644 index 0000000..423bf48 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n5 @@ -0,0 +1,533 @@ +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.2.2.2 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.1.1.1 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +> zx0 ip #0 40(20) 6 10.2.2.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.2.2.2,1025 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.2.2.2 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.2.2.2,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +> zx0 ip #0 40(20) 6 10.2.2.2,1025 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +> zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.1.1/32 -> 10.2.2.2/32 + +List of active sessions: +MAP 10.1.1.1 1025 <- -> 10.2.2.2 1025 [10.3.4.5 40000] +MAP 10.1.1.1 1026 <- -> 10.2.2.2 1026 [10.3.4.5 40000] +MAP 10.1.1.1 <- -> 10.2.2.2 [10.1.2.1] +MAP 10.1.1.1 1025 <- -> 10.2.2.2 1025 [10.1.1.2 1025] +MAP 10.1.1.1 1025 <- -> 10.2.2.2 1025 [10.1.1.1 1025] +MAP 10.1.1.1 <- -> 10.2.2.2 [10.4.3.2] +MAP 10.1.1.1 <- -> 10.2.2.2 [10.1.1.2] + +Hostmap table: +10.1.1.1,10.3.4.5 -> 10.2.2.2,0.0.0.0 (use = 2) +10.1.1.1,10.1.2.1 -> 10.2.2.2,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.1 -> 10.2.2.2,0.0.0.0 (use = 1) +10.1.1.1,10.4.3.2 -> 10.2.2.2,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.2 -> 10.2.2.2,0.0.0.0 (use = 2) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip #0 20(20) 255 10.3.4.5 > 10.1.1.2 +15 +> zx0 ip #0 20(20) 255 10.3.4.5 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.0 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +> zx0 ip #0 48(20) 1 10.1.1.1 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +15 +> zx0 ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.3.4.5 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.3.4.5 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,1026 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.3.4.5,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,2000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,2001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,2002 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,2003 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +> zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 from 10.1.1.0/24 to 10.1.0.0/16 -> 10.3.4.5/32 + +List of active sessions: +MAP 10.1.1.3 2003 <- -> 10.3.4.5 2003 [10.1.4.1 80] +MAP 10.1.1.3 2002 <- -> 10.3.4.5 2002 [10.1.4.1 80] +MAP 10.1.1.3 2001 <- -> 10.3.4.5 2001 [10.1.3.1 80] +MAP 10.1.1.3 2000 <- -> 10.3.4.5 2000 [10.1.2.1 80] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 1025 [10.1.1.1 1025] +MAP 10.1.1.1 <- -> 10.3.4.5 [10.1.2.1] +MAP 10.1.1.0 <- -> 10.3.4.5 [10.1.1.2] +MAP 10.1.1.1 1025 <- -> 10.3.4.5 1025 [10.1.1.2 1025] +MAP 10.1.1.2 1026 <- -> 10.3.4.5 1026 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 1025 [10.1.1.1 1025] +MAP 10.1.1.2 <- -> 10.3.4.5 [10.1.1.1] +MAP 10.1.1.0 <- -> 10.3.4.5 [10.1.1.2] + +Hostmap table: +10.1.1.3,10.1.4.1 -> 10.3.4.5,0.0.0.0 (use = 2) +10.1.1.3,10.1.3.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.3,10.1.2.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.1,10.1.2.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.2 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 4) +10.1.1.0,10.1.1.2 -> 10.3.4.5,0.0.0.0 (use = 2) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.3.4.1 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.3.4.1 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.3.4.1 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.3.4.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.3.4.2 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.3,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +> zx0 ip #0 40(20) 6 10.3.4.3,1025 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +> zx0 ip #0 28(20) 17 10.3.4.3,1025 > 10.3.4.5,40001 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 from 10.1.1.0/24 ! to 10.1.0.0/16 -> 10.3.4.0/24 + +List of active sessions: +MAP 10.1.1.2 1025 <- -> 10.3.4.3 1025 [10.3.4.5 40001] +MAP 10.1.1.1 1025 <- -> 10.3.4.3 1025 [10.3.4.5 40000] +MAP 10.1.1.1 1026 <- -> 10.3.4.3 1026 [10.3.4.5 40000] +MAP 10.1.1.3 <- -> 10.3.4.2 [10.4.3.4] +MAP 10.1.1.3 <- -> 10.3.4.2 [10.4.3.4] +MAP 10.1.1.2 <- -> 10.3.4.1 [10.4.3.4] +MAP 10.1.1.2 <- -> 10.3.4.1 [10.4.3.2] +MAP 10.1.1.1 <- -> 10.3.4.1 [10.4.3.2] + +Hostmap table: +10.1.1.2,10.3.4.5 -> 10.3.4.3,0.0.0.0 (use = 1) +10.1.1.1,10.3.4.5 -> 10.3.4.3,0.0.0.0 (use = 2) +10.1.1.3,10.4.3.4 -> 10.3.4.2,0.0.0.0 (use = 2) +10.1.1.2,10.4.3.4 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.2,10.4.3.2 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.1,10.4.3.2 -> 10.3.4.1,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.1.1.1 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1025 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.2,1026 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.3.4.5,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.1.1.3,2000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2002 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.1.1.3,2003 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +> zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +> zx0 ip #0 28(20) 17 10.3.4.5,10001 > 10.3.4.5,40001 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000 sequential + +List of active sessions: +MAP 10.1.1.2 1025 <- -> 10.3.4.5 10001 [10.3.4.5 40001] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 10000 [10.1.1.1 1025] + +Hostmap table: +10.1.1.2,10.3.4.5 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.1,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10001 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.1.1.1 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +> zx0 ip #0 40(20) 6 10.3.4.1,10002 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10003 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.3.4.1,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10001 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.3.4.1,10004 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.1,10005 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.3.4.1,10006 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.3.4.1,10007 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.3.4.1,10008 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.1,10009 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +> zx0 ip #0 40(20) 6 10.3.4.1,10010 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,40000 +> zx0 ip #0 28(20) 17 10.3.4.1,10011 > 10.3.4.5,40001 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.3.4.1,10012 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000 sequential + +List of active sessions: +MAP 10.1.2.1 80 <- -> 10.3.4.1 10012 [10.3.4.5 40001] +MAP 10.1.1.2 1025 <- -> 10.3.4.1 10011 [10.3.4.5 40001] +MAP 10.1.1.1 1025 <- -> 10.3.4.1 10010 [10.3.4.5 40000] +MAP 10.1.1.1 1026 <- -> 10.3.4.1 10009 [10.3.4.5 40000] +MAP 10.1.1.3 2003 <- -> 10.3.4.1 10008 [10.1.4.1 80] +MAP 10.1.1.3 2002 <- -> 10.3.4.1 10007 [10.1.4.1 80] +MAP 10.1.1.3 2001 <- -> 10.3.4.1 10006 [10.1.3.1 80] +MAP 10.1.1.3 2000 <- -> 10.3.4.1 10005 [10.1.2.1 80] +MAP 10.1.1.2 1025 <- -> 10.3.4.1 10004 [10.1.1.1 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.1 10003 [10.1.1.2 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.1 10002 [10.1.1.1 1025] +MAP 10.1.1.2 1026 <- -> 10.3.4.1 10001 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.1 10000 [10.1.1.1 1025] + +Hostmap table: +10.1.2.1,10.3.4.5 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.2,10.3.4.5 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.1,10.3.4.5 -> 10.3.4.1,0.0.0.0 (use = 2) +10.1.1.3,10.1.4.1 -> 10.3.4.1,0.0.0.0 (use = 2) +10.1.1.3,10.1.3.1 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.3,10.1.2.1 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.2 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.1 -> 10.3.4.1,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.1,0.0.0.0 (use = 3) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip #0 20(20) 255 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +> zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.1,1025 +> zx0 ip #0 20(20) 255 10.2.2.1 > 10.1.2.1 +> zx0 ip #0 20(20) 255 10.2.2.2 > 10.1.2.1 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.2.1 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.2 > 10.2.1.1 +< zx0 ip #0 20(20) 255 10.2.2.3 > 10.1.1.1 +< zx0 ip #0 20(20) 255 10.2.3.4 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.2.2.2 +< zx0 ip #0 20(20) 255 10.1.1.0 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.1 > 10.3.4.5 +< zx0 ip #0 20(20) 255 10.1.1.2 > 10.3.4.5 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.3.4.5,1025 +> zx0 ip #0 48(20) 1 10.1.1.1 > 10.4.3.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.2.2.2 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.3 +< zx0 ip #0 48(20) 1 10.4.3.2 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.2 +< zx0 ip #0 20(20) 34 10.4.3.2 > 10.3.4.4 +> zx0 ip #0 20(20) 34 10.1.1.2 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.5 +> zx0 ip #0 20(20) 34 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 34 10.4.3.4 > 10.3.4.6 +> zx0 ip #0 20(20) 35 10.1.1.3 > 10.4.3.4 +< zx0 ip #0 20(20) 35 10.4.3.4 > 10.3.4.7 +15 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.2,1025 +> zx0 ip #0 20(20) 0 10.1.1.0 > 10.1.1.2 +> zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.2.1 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.1.1,1025 +> zx0 ip #0 28(20) 17 10.3.4.5,40001 > 10.1.1.1,1025 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.2.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.3.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.1.4.1,80 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.1.4.1,80 +< zx0 ip #0 20(20) 0 10.1.1.1 > 10.1.1.2 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +< zx0 ip #0 20(20) 0 10.1.1.2 > 10.1.1.1 +> zx0 ip #0 40(20) 6 10.3.4.5,40000 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1026 > 10.3.4.5,40000 +> zx0 ip #0 40(20) 6 10.3.4.5,40001 > 10.3.4.5,40000 +< zx0 ip #0 40(20) 6 10.1.1.1,1025 > 10.1.1.2,1025 +> zx0 ip #0 28(20) 17 10.3.4.5,40000 > 10.3.4.5,40001 +< zx0 ip #0 28(20) 17 10.1.1.2,1025 > 10.3.4.5,40001 +> zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +< zx0 ip #0 40(20) 6 10.1.2.1,80 > 10.3.4.5,40001 +List of active MAP/Redirect filters: +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001 sequential + +List of active sessions: +MAP 10.1.1.2 1025 <- -> 10.3.4.5 40000 [10.3.4.5 40001] +MAP 10.1.1.1 1025 <- -> 10.3.4.5 40001 [10.3.4.5 40000] +MAP 10.1.1.1 1026 <- -> 10.3.4.5 40000 [10.3.4.5 40000] +MAP 10.1.1.3 2003 <- -> 10.3.4.5 40001 [10.1.4.1 80] +MAP 10.1.1.3 2002 <- -> 10.3.4.5 40000 [10.1.4.1 80] +MAP 10.1.1.3 2001 <- -> 10.3.4.5 40001 [10.1.3.1 80] +MAP 10.1.1.3 2000 <- -> 10.3.4.5 40000 [10.1.2.1 80] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 40001 [10.1.1.1 1025] +MAP 10.1.1.1 1025 <- -> 10.3.4.5 40000 [10.1.1.2 1025] +MAP 10.1.1.2 1026 <- -> 10.3.4.5 40001 [10.1.1.1 1025] +MAP 10.1.1.2 1025 <- -> 10.3.4.5 40000 [10.1.1.1 1025] + +Hostmap table: +10.1.1.2,10.3.4.5 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.1,10.3.4.5 -> 10.3.4.5,0.0.0.0 (use = 2) +10.1.1.3,10.1.4.1 -> 10.3.4.5,0.0.0.0 (use = 2) +10.1.1.3,10.1.3.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.3,10.1.2.1 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.1,10.1.1.2 -> 10.3.4.5,0.0.0.0 (use = 1) +10.1.1.2,10.1.1.1 -> 10.3.4.5,0.0.0.0 (use = 3) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n5_6 b/contrib/netbsd-tests/ipf/expected/n5_6 new file mode 100644 index 0000000..1e7bc8e --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n5_6 @@ -0,0 +1,533 @@ +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:0:0:0:0:2:2:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2002 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2003 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +> zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::1/128 -> 10::2:2:2/128 + +List of active sessions: +MAP 10:1:1::1 1025 <- -> 10::2:2:2 1025 [10::3:4:5 40000] +MAP 10:1:1::1 1026 <- -> 10::2:2:2 1026 [10::3:4:5 40000] +MAP 10:1:1::1 <- -> 10::2:2:2 [10:1:2::1] +MAP 10:1:1::1 1025 <- -> 10::2:2:2 1025 [10:1:1::2 1025] +MAP 10:1:1::1 1025 <- -> 10::2:2:2 1025 [10:1:1::1 1025] +MAP 10:1:1::1 <- -> 10::2:2:2 [10:4:3::2] +MAP 10:1:1::1 <- -> 10::2:2:2 [10:1:1::2] + +Hostmap table: +10:1:1::1,10::3:4:5 -> 10::2:2:2,any (use = 2) +10:1:1::1,10:1:2::1 -> 10::2:2:2,any (use = 1) +10:1:1::1,10:1:1::1 -> 10::2:2:2,any (use = 1) +10:1:1::1,10:4:3::2 -> 10::2:2:2,any (use = 1) +10:1:1::1,10:1:1::2 -> 10::2:2:2,any (use = 2) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:5 > 10:1:1:0:0:0:0:2 +16 +> zx0 ip6/0 1 0 255 10:0:0:0:0:3:4:5 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:0 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 88 0 58 10:1:1:0:0:0:0:1 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +16 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:0:0:0:0:3:4:5 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:0:0:0:0:3:4:5 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,2000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,2001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,2002 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,2003 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +> zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 from 10:1:1::/112 to 10:1::/32 -> 10::3:4:5/128 + +List of active sessions: +MAP 10:1:1::3 2003 <- -> 10::3:4:5 2003 [10:1:4::1 80] +MAP 10:1:1::3 2002 <- -> 10::3:4:5 2002 [10:1:4::1 80] +MAP 10:1:1::3 2001 <- -> 10::3:4:5 2001 [10:1:3::1 80] +MAP 10:1:1::3 2000 <- -> 10::3:4:5 2000 [10:1:2::1 80] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 1025 [10:1:1::1 1025] +MAP 10:1:1::1 <- -> 10::3:4:5 [10:1:2::1] +MAP 10:1:1:: <- -> 10::3:4:5 [10:1:1::2] +MAP 10:1:1::1 1025 <- -> 10::3:4:5 1025 [10:1:1::2 1025] +MAP 10:1:1::2 1026 <- -> 10::3:4:5 1026 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 1025 [10:1:1::1 1025] +MAP 10:1:1::2 <- -> 10::3:4:5 [10:1:1::1] +MAP 10:1:1:: <- -> 10::3:4:5 [10:1:1::2] + +Hostmap table: +10:1:1::3,10:1:4::1 -> 10::3:4:5,any (use = 2) +10:1:1::3,10:1:3::1 -> 10::3:4:5,any (use = 1) +10:1:1::3,10:1:2::1 -> 10::3:4:5,any (use = 1) +10:1:1::1,10:1:2::1 -> 10::3:4:5,any (use = 1) +10:1:1::1,10:1:1::2 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:5,any (use = 4) +10:1:1::,10:1:1::2 -> 10::3:4:5,any (use = 2) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:0:0:0:0:3:4:1 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:1 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:1 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:0:0:0:0:3:4:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:0:0:0:0:3:4:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2002 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2003 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:3,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:3,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:3,1025 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +> zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 from 10:1:1::/112 ! to 10:1::/32 -> 10::3:4:0/112 + +List of active sessions: +MAP 10:1:1::2 1025 <- -> 10::3:4:3 1025 [10::3:4:5 40001] +MAP 10:1:1::1 1025 <- -> 10::3:4:3 1025 [10::3:4:5 40000] +MAP 10:1:1::1 1026 <- -> 10::3:4:3 1026 [10::3:4:5 40000] +MAP 10:1:1::3 <- -> 10::3:4:2 [10:4:3::4] +MAP 10:1:1::3 <- -> 10::3:4:2 [10:4:3::4] +MAP 10:1:1::2 <- -> 10::3:4:1 [10:4:3::4] +MAP 10:1:1::2 <- -> 10::3:4:1 [10:4:3::2] +MAP 10:1:1::1 <- -> 10::3:4:1 [10:4:3::2] + +Hostmap table: +10:1:1::2,10::3:4:5 -> 10::3:4:3,any (use = 1) +10:1:1::1,10::3:4:5 -> 10::3:4:3,any (use = 2) +10:1:1::3,10:4:3::4 -> 10::3:4:2,any (use = 2) +10:1:1::2,10:4:3::4 -> 10::3:4:1,any (use = 1) +10:1:1::2,10:4:3::2 -> 10::3:4:1,any (use = 1) +10:1:1::1,10:4:3::2 -> 10::3:4:1,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:1:1:0:0:0:0:1 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1025 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:2,1026 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2002 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:3,2003 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,10001 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +> zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::/112 -> 10::3:4:5/128 portmap udp 10000:20000 sequential + +List of active sessions: +MAP 10:1:1::2 1025 <- -> 10::3:4:5 10001 [10::3:4:5 40001] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 10000 [10:1:1::1 1025] + +Hostmap table: +10:1:1::2,10::3:4:5 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:5,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10001 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:1:1:0:0:0:0:1 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10002 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10003 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10001 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:1,10004 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10005 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10006 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10007 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10008 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10009 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10010 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:1,10011 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:1,10012 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1::/32 -> 10::3:4:0/112 portmap tcp/udp 10000:20000 sequential + +List of active sessions: +MAP 10:1:2::1 80 <- -> 10::3:4:1 10012 [10::3:4:5 40001] +MAP 10:1:1::2 1025 <- -> 10::3:4:1 10011 [10::3:4:5 40001] +MAP 10:1:1::1 1025 <- -> 10::3:4:1 10010 [10::3:4:5 40000] +MAP 10:1:1::1 1026 <- -> 10::3:4:1 10009 [10::3:4:5 40000] +MAP 10:1:1::3 2003 <- -> 10::3:4:1 10008 [10:1:4::1 80] +MAP 10:1:1::3 2002 <- -> 10::3:4:1 10007 [10:1:4::1 80] +MAP 10:1:1::3 2001 <- -> 10::3:4:1 10006 [10:1:3::1 80] +MAP 10:1:1::3 2000 <- -> 10::3:4:1 10005 [10:1:2::1 80] +MAP 10:1:1::2 1025 <- -> 10::3:4:1 10004 [10:1:1::1 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:1 10003 [10:1:1::2 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:1 10002 [10:1:1::1 1025] +MAP 10:1:1::2 1026 <- -> 10::3:4:1 10001 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:1 10000 [10:1:1::1 1025] + +Hostmap table: +10:1:2::1,10::3:4:5 -> 10::3:4:1,any (use = 1) +10:1:1::2,10::3:4:5 -> 10::3:4:1,any (use = 1) +10:1:1::1,10::3:4:5 -> 10::3:4:1,any (use = 2) +10:1:1::3,10:1:4::1 -> 10::3:4:1,any (use = 2) +10:1:1::3,10:1:3::1 -> 10::3:4:1,any (use = 1) +10:1:1::3,10:1:2::1 -> 10::3:4:1,any (use = 1) +10:1:1::1,10:1:1::2 -> 10::3:4:1,any (use = 1) +10:1:1::1,10:1:1::1 -> 10::3:4:1,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:1,any (use = 3) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:1:2:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:1 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:2 > 10:0:0:0:0:2:1:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:2:3 > 10:1:1:0:0:0:0:1 +< zx0 ip6/0 1 0 255 10:0:0:0:0:2:3:4 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:0 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:1 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 1 0 255 10:1:1:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:0:0:0:0:3:4:5,1025 +> zx0 ip6/0 88 0 58 10:1:1:0:0:0:0:1 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:2:2:2 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:3 +< zx0 ip6/0 88 0 58 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:2 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:2 > 10:0:0:0:0:3:4:4 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:2 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:5 +> zx0 ip6/0 1 0 34 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 34 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:6 +> zx0 ip6/0 1 0 35 10:1:1:0:0:0:0:3 > 10:4:3:0:0:0:0:4 +< zx0 ip6/0 1 0 35 10:4:3:0:0:0:0:4 > 10:0:0:0:0:3:4:7 +16 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:0 > 10:1:1:0:0:0:0:2 +> zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:2:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,40001 > 10:1:1:0:0:0:0:1,1025 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:2:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:3:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:1:4:0:0:0:0:1,80 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:1:4:0:0:0:0:1,80 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:1 > 10:1:1:0:0:0:0:2 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +< zx0 ip6/0 1 0 41 10:1:1:0:0:0:0:2 > 10:1:1:0:0:0:0:1 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40000 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1026 > 10:0:0:0:0:3:4:5,40000 +> zx0 ip6/0 20 0 6 10:0:0:0:0:3:4:5,40001 > 10:0:0:0:0:3:4:5,40000 +< zx0 ip6/0 20 0 6 10:1:1:0:0:0:0:1,1025 > 10:1:1:0:0:0:0:2,1025 +> zx0 ip6/0 8 0 17 10:0:0:0:0:3:4:5,40000 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 8 0 17 10:1:1:0:0:0:0:2,1025 > 10:0:0:0:0:3:4:5,40001 +> zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +< zx0 ip6/0 20 0 6 10:1:2:0:0:0:0:1,80 > 10:0:0:0:0:3:4:5,40001 +List of active MAP/Redirect filters: +map zx0 inet6 10:1:1::/112 -> 10::3:4:5/128 portmap tcp/udp 40000:40001 sequential + +List of active sessions: +MAP 10:1:1::2 1025 <- -> 10::3:4:5 40000 [10::3:4:5 40001] +MAP 10:1:1::1 1025 <- -> 10::3:4:5 40001 [10::3:4:5 40000] +MAP 10:1:1::1 1026 <- -> 10::3:4:5 40000 [10::3:4:5 40000] +MAP 10:1:1::3 2003 <- -> 10::3:4:5 40001 [10:1:4::1 80] +MAP 10:1:1::3 2002 <- -> 10::3:4:5 40000 [10:1:4::1 80] +MAP 10:1:1::3 2001 <- -> 10::3:4:5 40001 [10:1:3::1 80] +MAP 10:1:1::3 2000 <- -> 10::3:4:5 40000 [10:1:2::1 80] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 40001 [10:1:1::1 1025] +MAP 10:1:1::1 1025 <- -> 10::3:4:5 40000 [10:1:1::2 1025] +MAP 10:1:1::2 1026 <- -> 10::3:4:5 40001 [10:1:1::1 1025] +MAP 10:1:1::2 1025 <- -> 10::3:4:5 40000 [10:1:1::1 1025] + +Hostmap table: +10:1:1::2,10::3:4:5 -> 10::3:4:5,any (use = 1) +10:1:1::1,10::3:4:5 -> 10::3:4:5,any (use = 2) +10:1:1::3,10:1:4::1 -> 10::3:4:5,any (use = 2) +10:1:1::3,10:1:3::1 -> 10::3:4:5,any (use = 1) +10:1:1::3,10:1:2::1 -> 10::3:4:5,any (use = 1) +10:1:1::1,10:1:1::2 -> 10::3:4:5,any (use = 1) +10:1:1::2,10:1:1::1 -> 10::3:4:5,any (use = 3) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n6 b/contrib/netbsd-tests/ipf/expected/n6 new file mode 100644 index 0000000..1afd94e --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n6 @@ -0,0 +1,173 @@ +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.1.2.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 +< zx0 ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.1/32 port 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.3.3.3 12345] +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.2.2.2 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.2.2.1,10023 +15 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.1.2.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 +< zx0 ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +List of active MAP/Redirect filters: +rdr zx0 from 0/0 to 10.1.1.0/24 port = 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.3.3.3 12345] +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.2.2.2 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.2.2.1,10023 +15 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.1.2.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,23 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 +< zx0 ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +List of active MAP/Redirect filters: +rdr zx0 from 10.2.0.0/16 to 10.1.1.0/24 port = 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.2.2.2 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,23 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 +15 +< zx0 ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +List of active MAP/Redirect filters: +rdr zx0 from 10.3.0.0/16 to 10.1.0.0/16 port = 23 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.3.3.3 12345] +RDR 10.2.2.1 10023 <- -> 10.1.2.2 23 [10.3.0.1 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,23 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.1.2.2,23 +< zx0 ip #0 40(20) 6 10.3.0.1,12345 > 10.2.2.2,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,23 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.1,53 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.0.0,23 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.0.0,23 +< zx0 ip #0 28(20) 17 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 28(20) 17 10.3.3.3,12345 > 10.2.2.1,10053 +< zx0 ip #0 40(20) 6 10.2.2.2,12345 > 10.1.1.0,53 +< zx0 ip #0 40(20) 6 10.3.3.3,12345 > 10.1.1.0,53 +List of active MAP/Redirect filters: +rdr zx0 ! from 10.2.0.0/16 to 10.1.1.0/24 port = 53 -> 10.2.2.1/32 port 10053 udp + +List of active sessions: +RDR 10.2.2.1 10053 <- -> 10.1.1.0 53 [10.3.3.3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n6_6 b/contrib/netbsd-tests/ipf/expected/n6_6 new file mode 100644 index 0000000..e10f9bd --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n6_6 @@ -0,0 +1,173 @@ +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:1:2:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:0:0:0:0:2:2:2,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::1/128 port 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10:3:3::3 12345] +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10::2:2:2 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:0:0:0:0:2:2:1,10023 +16 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:1:2:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:0:0:0:0:2:2:2,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +List of active MAP/Redirect filters: +rdr zx0 inet6 from any to 10:1:1::/112 port = 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10:3:3::3 12345] +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10::2:2:2 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:0:0:0:0:2:2:1,10023 +16 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:1:2:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:0:0:0:0:2:2:2,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,23 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +List of active MAP/Redirect filters: +rdr zx0 inet6 from 10::/32 to 10:1:1::/112 port = 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10::2:2:2 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,23 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:0:0:0:0:2:2:2,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:0:0:0:0:0:0,23 +16 +< zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +List of active MAP/Redirect filters: +rdr zx0 inet6 from 10:3::/32 to 10:1::/32 port = 23 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10:3:3::3 12345] +RDR 10::2:2:1 10023 <- -> 10:1:2::2 23 [10:3::1 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,23 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:1:2:0:0:0:0:2,23 +< zx0 ip6/0 20 0 6 10:3:0:0:0:0:0:1,12345 > 10:0:0:0:0:2:2:2,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,23 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:1,53 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:0:0:0:0:0:0,23 +< zx0 ip6/0 8 0 17 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 8 0 17 10:3:3:0:0:0:0:3,12345 > 10:0:0:0:0:2:2:1,10053 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:2:2,12345 > 10:1:1:0:0:0:0:0,53 +< zx0 ip6/0 20 0 6 10:3:3:0:0:0:0:3,12345 > 10:1:1:0:0:0:0:0,53 +List of active MAP/Redirect filters: +rdr zx0 inet6 ! from 10::/32 to 10:1:1::/112 port = 53 -> 10::2:2:1/128 port 10053 udp + +List of active sessions: +RDR 10::2:2:1 10053 <- -> 10:1:1:: 53 [10:3:3::3 12345] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n7 b/contrib/netbsd-tests/ipf/expected/n7 new file mode 100644 index 0000000..11b8115 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n7 @@ -0,0 +1,98 @@ +< zx0 ip #0 40(20) 6 10.2.3.1,1230 > 10.1.1.1,22 +< zx0 ip #0 40(20) 6 10.2.3.1,1231 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.3.1,1232 > 10.2.2.1,10050 +< zx0 ip #0 40(20) 6 10.2.3.1,1233 > 10.2.2.1,10079 +< zx0 ip #0 40(20) 6 10.2.3.1,1234 > 10.1.1.1,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1235 > 10.1.1.2,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1236 > 10.1.1.3,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1237 > 10.1.1.4,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1238 > 10.1.1.4,80 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.1/32 port 23-79 -> 10.2.2.1/32 port 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10079 <- -> 10.1.1.1 79 [10.2.3.1 1233] +RDR 10.2.2.1 10050 <- -> 10.1.1.1 50 [10.2.3.1 1232] +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.2.3.1 1231] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip #0 40(20) 6 10.2.3.1,1230 > 10.1.1.1,22 +< zx0 ip #0 40(20) 6 10.2.3.1,1231 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.3.1,1232 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.3.1,1233 > 10.2.2.1,10023 +< zx0 ip #0 40(20) 6 10.2.3.1,1234 > 10.1.1.1,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1235 > 10.1.1.2,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1236 > 10.1.1.3,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1237 > 10.1.1.4,80 +< zx0 ip #0 40(20) 6 10.2.3.1,1238 > 10.1.1.4,80 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.1/32 port 23-79 -> 10.2.2.1/32 port = 10023 tcp + +List of active sessions: +RDR 10.2.2.1 10023 <- -> 10.1.1.1 79 [10.2.3.1 1233] +RDR 10.2.2.1 10023 <- -> 10.1.1.1 50 [10.2.3.1 1232] +RDR 10.2.2.1 10023 <- -> 10.1.1.1 23 [10.2.3.1 1231] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip #0 40(20) 6 10.2.3.1,1230 > 10.1.1.1,22 +< zx0 ip #0 40(20) 6 10.2.3.1,1231 > 10.1.1.1,23 +< zx0 ip #0 40(20) 6 10.2.3.1,1232 > 10.1.1.1,50 +< zx0 ip #0 40(20) 6 10.2.3.1,1233 > 10.1.1.1,79 +< zx0 ip #0 40(20) 6 10.2.3.1,1234 > 10.2.2.1,3128 +< zx0 ip #0 40(20) 6 10.2.3.1,1235 > 1.2.2.129,3128 +< zx0 ip #0 40(20) 6 10.2.3.1,1236 > 10.2.2.1,3128 +< zx0 ip #0 40(20) 6 10.2.3.1,1237 > 1.2.2.129,3128 +< zx0 ip #0 40(20) 6 10.2.3.1,1238 > 10.2.2.1,3128 +List of active MAP/Redirect filters: +rdr zx0 10.1.1.0/24 port 80 -> 10.2.2.1,1.2.2.129 port 3128 tcp + +List of active sessions: +RDR 10.2.2.1 3128 <- -> 10.1.1.4 80 [10.2.3.1 1238] +RDR 1.2.2.129 3128 <- -> 10.1.1.4 80 [10.2.3.1 1237] +RDR 10.2.2.1 3128 <- -> 10.1.1.3 80 [10.2.3.1 1236] +RDR 1.2.2.129 3128 <- -> 10.1.1.2 80 [10.2.3.1 1235] +RDR 10.2.2.1 3128 <- -> 10.1.1.1 80 [10.2.3.1 1234] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n7_6 b/contrib/netbsd-tests/ipf/expected/n7_6 new file mode 100644 index 0000000..2563033 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n7_6 @@ -0,0 +1,98 @@ +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1230 > 10:1:1:0:0:0:0:1,22 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1231 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1232 > 10:0:0:0:0:2:2:1,10050 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1233 > 10:0:0:0:0:2:2:1,10079 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1234 > 10:1:1:0:0:0:0:1,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1235 > 10:1:1:0:0:0:0:2,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1236 > 10:1:1:0:0:0:0:3,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1237 > 10:1:1:0:0:0:0:4,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1238 > 10:1:1:0:0:0:0:4,80 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::1/128 port 23-79 -> 10::2:2:1/128 port 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10079 <- -> 10:1:1::1 79 [10::2:3:1 1233] +RDR 10::2:2:1 10050 <- -> 10:1:1::1 50 [10::2:3:1 1232] +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10::2:3:1 1231] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1230 > 10:1:1:0:0:0:0:1,22 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1231 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1232 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1233 > 10:0:0:0:0:2:2:1,10023 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1234 > 10:1:1:0:0:0:0:1,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1235 > 10:1:1:0:0:0:0:2,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1236 > 10:1:1:0:0:0:0:3,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1237 > 10:1:1:0:0:0:0:4,80 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1238 > 10:1:1:0:0:0:0:4,80 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::1/128 port 23-79 -> 10::2:2:1/128 port = 10023 tcp + +List of active sessions: +RDR 10::2:2:1 10023 <- -> 10:1:1::1 79 [10::2:3:1 1233] +RDR 10::2:2:1 10023 <- -> 10:1:1::1 50 [10::2:3:1 1232] +RDR 10::2:2:1 10023 <- -> 10:1:1::1 23 [10::2:3:1 1231] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1230 > 10:1:1:0:0:0:0:1,22 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1231 > 10:1:1:0:0:0:0:1,23 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1232 > 10:1:1:0:0:0:0:1,50 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1233 > 10:1:1:0:0:0:0:1,79 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1234 > 10:0:0:0:0:2:2:1,3128 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1235 > 1:0:0:0:0:2:2:129,3128 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1236 > 10:0:0:0:0:2:2:1,3128 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1237 > 1:0:0:0:0:2:2:129,3128 +< zx0 ip6/0 20 0 6 10:0:0:0:0:2:3:1,1238 > 10:0:0:0:0:2:2:1,3128 +List of active MAP/Redirect filters: +rdr zx0 inet6 10:1:1::/112 port 80 -> 10::2:2:1,1::2:2:129 port 3128 tcp + +List of active sessions: +RDR 10::2:2:1 3128 <- -> 10:1:1::4 80 [10::2:3:1 1238] +RDR 1::2:2:129 3128 <- -> 10:1:1::4 80 [10::2:3:1 1237] +RDR 10::2:2:1 3128 <- -> 10:1:1::3 80 [10::2:3:1 1236] +RDR 1::2:2:129 3128 <- -> 10:1:1::2 80 [10::2:3:1 1235] +RDR 10::2:2:1 3128 <- -> 10:1:1::1 80 [10::2:3:1 1234] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n8 b/contrib/netbsd-tests/ipf/expected/n8 new file mode 100644 index 0000000..a5e938f --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n8 @@ -0,0 +1,30 @@ +4500 0054 8bc1 0000 ff01 13d5 0a0a 0a01 0404 0404 0800 efdf 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +4500 0054 3fd5 4000 ff01 2fc8 0404 0404 0202 0202 0000 f7df 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +4500 0054 8bc1 0000 ff01 13d5 0a0a 0a01 0404 0404 0800 efde 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +4500 0054 3fd5 4000 ff01 2fc8 0404 0404 0202 0202 0000 f7de 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +List of active MAP/Redirect filters: +map icmp0 2.2.2.0/24 -> 10.10.10.0/24 + +List of active sessions: +MAP 2.2.2.2 <- -> 10.10.10.1 [4.4.4.4] + +Hostmap table: +2.2.2.2,4.4.4.4 -> 10.10.10.1,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n8_6 b/contrib/netbsd-tests/ipf/expected/n8_6 new file mode 100644 index 0000000..4d08efe --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n8_6 @@ -0,0 +1,30 @@ +6000 0000 0040 3aff 0010 0010 0010 0000 0000 0000 0000 0001 0004 0004 0004 0000 0000 0000 0000 0004 8000 7724 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +6000 0000 0040 3aff 0004 0004 0004 0000 0000 0000 0000 0004 0002 0000 0000 0000 0000 0002 0002 0002 8100 764d 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +6000 0000 0040 3aff 0010 0010 0010 0000 0000 0000 0000 0001 0004 0004 0004 0000 0000 0000 0000 0004 8000 7723 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +6000 0000 0040 3aff 0004 0004 0004 0000 0000 0000 0000 0004 0002 0000 0000 0000 0000 0002 0002 0002 8100 764c 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +List of active MAP/Redirect filters: +map icmp0 inet6 2::2:2:0/112 -> 10:10:10::/112 + +List of active sessions: +MAP 2::2:2:2 <- -> 10:10:10::1 [4:4:4::4] + +Hostmap table: +2::2:2:2,4:4:4::4 -> 10:10:10::1,any (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n9 b/contrib/netbsd-tests/ipf/expected/n9 new file mode 100644 index 0000000..2c762be --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n9 @@ -0,0 +1,29 @@ +4500 0054 8bc1 0000 ff01 17d9 0202 0202 0a0a 0a01 0800 efdf 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +4500 0054 3fd5 4000 ff01 2fc8 0404 0404 0202 0202 0000 f7df 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +4500 0054 8bc1 0000 ff01 17d9 0202 0202 0a0a 0a01 0800 efde 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +4500 0054 3fd5 4000 ff01 2fc8 0404 0404 0202 0202 0000 f7de 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +List of active MAP/Redirect filters: +rdr icmp0 4.4.4.0/24 -> 10.10.10.1/32 ip + +List of active sessions: +RDR 10.10.10.1 <- -> 4.4.4.4 [2.2.2.2] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/n9_6 b/contrib/netbsd-tests/ipf/expected/n9_6 new file mode 100644 index 0000000..134d74c --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/n9_6 @@ -0,0 +1,29 @@ +6000 0000 0040 3aff 0002 0000 0000 0000 0000 0002 0002 0002 0010 0010 0010 0000 0000 0000 0000 0001 8000 772c 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +6000 0000 0040 3aff 0004 0004 0004 0000 0000 0000 0000 0004 0002 0000 0000 0000 0000 0002 0002 0002 8100 764d 6220 0000 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +6000 0000 0040 3aff 0002 0000 0000 0000 0000 0002 0002 0002 0010 0010 0010 0000 0000 0000 0000 0001 8000 772b 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +6000 0000 0040 3aff 0004 0004 0004 0000 0000 0000 0000 0004 0002 0000 0000 0000 0000 0002 0002 0002 8100 764c 6220 0001 3f6f 6e80 000b 0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 + +List of active MAP/Redirect filters: +rdr icmp0 inet6 4:4:4::/112 -> 10:10:10::1/128 ip + +List of active sessions: +RDR 10:10:10::1 <- -> 4:4:4::4 [2::2:2:2] + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni1 b/contrib/netbsd-tests/ipf/expected/ni1 new file mode 100644 index 0000000..d4e2de2 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni1 @@ -0,0 +1,19 @@ +4500 0028 0000 4000 0111 65b2 0606 0606 0404 0404 afc9 829e 0014 6308 0402 0000 3be5 468d 000a cfc3 + +4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0b00 5773 0000 0000 4500 0028 0000 4000 0111 6dba 0202 0202 0404 0404 afc9 829e 0014 6b10 + +4500 0044 809a 0000 ff01 3115 0303 0303 0202 0202 0b00 0131 0000 0000 4500 0028 0000 4000 0111 6dba 0202 0202 0404 0404 afc9 829e 0014 6b10 0402 0000 3be5 468d 000a cfc3 + +4500 0028 0001 4000 0111 65b0 0606 0607 0404 0404 4e20 829e 0014 c4b0 0402 0000 3be5 468d 000a cfc3 + +4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0b00 5773 0000 0000 4500 0028 0000 4000 0111 6dba 0202 0202 0404 0404 0800 829e 0014 12da + +4500 0044 809a 0000 ff01 3115 0303 0303 0202 0202 0b00 0131 0000 0000 4500 0028 0000 4000 0111 6dba 0202 0202 0404 0404 0800 829e 0014 12da 0402 0000 3be5 468d 000a cfc3 + +4500 0028 0002 4000 0111 65ae 0606 0608 0404 0404 07d0 829e 0014 0b00 0402 0000 3be5 468d 000a cfc3 + +4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0b00 ff6a 0000 0000 4500 0028 0000 4000 0111 6dba 0202 0202 0404 0404 5000 829e 0014 22e2 + +4500 0044 809a 0000 ff01 3115 0303 0303 0202 0202 0b00 0131 0000 0000 4500 0028 0000 4000 0111 6dba 0202 0202 0404 0404 5000 829e 0014 cad9 0402 0000 3be5 468d 000a cfc3 + +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni10 b/contrib/netbsd-tests/ipf/expected/ni10 new file mode 100644 index 0000000..050fb40 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni10 @@ -0,0 +1,8 @@ +4500 003c 4706 4000 ff06 20a2 0404 0404 0606 0606 5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +4500 0038 0000 0000 ff01 afb9 0202 0202 0404 0404 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0404 0404 0202 0202 5000 0050 0000 0001 + +4500 0058 0001 0000 ff01 af98 0202 0202 0404 0404 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0404 0404 0202 0202 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +0 +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni11 b/contrib/netbsd-tests/ipf/expected/ni11 new file mode 100644 index 0000000..6ed8ecc --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni11 @@ -0,0 +1,8 @@ +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +4500 0038 0000 0000 ff01 a7b9 0a02 0202 0404 0404 0303 a7fc 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 + +4500 0058 0001 0000 ff01 a798 0a02 0202 0404 0404 0303 1137 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +0 +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni12 b/contrib/netbsd-tests/ipf/expected/ni12 new file mode 100644 index 0000000..590ec23 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni12 @@ -0,0 +1,8 @@ +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9c40 0000 0001 0000 0000 a002 16d0 3ef4 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +4500 0038 0000 0000 ff01 a7b9 0a02 0202 0404 0404 0303 a7fc 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 + +4500 0058 0001 0000 ff01 a798 0a02 0202 0404 0404 0303 1137 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +0 +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni13 b/contrib/netbsd-tests/ipf/expected/ni13 new file mode 100644 index 0000000..897bef3 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni13 @@ -0,0 +1,63 @@ +4500 0030 5e11 4000 8006 3961 c0a8 7101 c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 7002 faf0 21a1 0000 0204 05b4 0101 0402 + +4500 002c 0000 4000 4006 d776 c0a8 7103 c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 6012 8000 a348 0000 0204 05b4 + +4500 00c4 5e12 4000 8006 38cc c0a8 7101 c0a8 7103 05e7 06bb abf0 4aa6 a564 68db 5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d 0001 0000 0100 0000 0000 0001 0000 0001 0000 0a28 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 4d69 6372 6f73 6f66 7420 5769 6e64 6f77 7320 4e54 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 00c4 0001 4000 4006 d6dd c0a8 7103 c0a8 7101 06bb 05e7 a564 68db abf0 4b42 5018 832c cecf 0000 009c 0001 1a2b 3c4d 0002 0000 0100 0100 0000 0000 0000 0000 0001 0001 6c6f 6361 6c00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 6c69 6e75 7800 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 00d0 5e13 4000 8006 38bf c0a8 7101 c0a8 7103 05e7 06bb abf0 4b42 a564 6977 5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d 0007 0000 4000 1331 0000 012c 05f5 e100 0000 0003 0000 0003 0040 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 0048 0002 4000 4006 d758 c0a8 7103 c0a8 7101 06bb 05e7 a564 6977 abf0 4bea 5018 832c 36fa 0000 0020 0001 1a2b 3c4d 0008 0000 0000 4000 0100 0000 05f5 e100 0040 0000 0000 0000 + +4500 0040 5e14 4000 8006 394e c0a8 7101 c0a8 7103 05e7 06bb abf0 4bea a564 6997 5018 fa34 e810 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 ffff ffff ffff ffff + +4500 0039 5e15 0000 802f 792b c0a8 7101 c0a8 7103 3001 880b 0019 0000 0000 0000 ff03 c021 0100 0015 0104 0578 0506 577f 7c5b 0702 0802 0d03 06 + +4500 0020 0003 0000 ff2f 5856 c0a8 7103 c0a8 7101 2081 880b 0000 4000 ffff ffff + +4500 0028 0004 4000 4006 d776 c0a8 7103 c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 5010 832c b5c1 0000 + +4500 0038 0005 0000 ff2f 583c c0a8 7103 c0a8 7101 3001 880b 0018 4000 0000 0000 ff03 c021 0101 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 + +4500 002f 0006 0000 ff2f 5844 c0a8 7103 c0a8 7101 3081 880b 000b 4000 0000 0001 0000 0000 ff03 c021 0400 0007 0d03 06 + +4500 003c 5e16 0000 802f 7927 c0a8 7101 c0a8 7103 3081 880b 0018 0000 0000 0001 0000 0001 ff03 c021 0201 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 + +4500 0036 5e17 0000 802f 792c c0a8 7101 c0a8 7103 3001 880b 0016 0000 0000 0002 ff03 c021 0101 0012 0104 0578 0506 577f 7c5b 0702 0802 + +4500 003a 0007 0000 ff2f 5838 c0a8 7103 c0a8 7101 3081 880b 0016 4000 0000 0002 0000 0002 ff03 c021 0201 0012 0104 0578 0506 577f 7c5b 0702 0802 + +4500 0032 0008 0000 ff2f 583f c0a8 7103 c0a8 7101 3001 880b 0012 4000 0000 0003 8021 0101 0010 0306 c0a8 0001 0206 002d 0f01 + +4500 0040 5e18 4000 8006 394a c0a8 7101 c0a8 7103 05e7 06bb abf0 4c02 a564 6997 5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 0000 0000 ffff ffff + +4500 0038 5e19 0000 802f 7928 c0a8 7101 c0a8 7103 3081 880b 0014 0000 0000 0003 0000 0003 c021 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 + +4500 003e 0009 0000 ff2f 5832 c0a8 7103 c0a8 7101 3081 880b 001a 4000 0000 0004 0000 0003 ff03 c021 0702 0016 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 + +4500 003e 5e1a 0000 802f 7921 c0a8 7101 c0a8 7103 3081 880b 001a 0000 0000 0004 0000 0004 c021 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 + +4500 0044 000a 0000 ff2f 582b c0a8 7103 c0a8 7101 3081 880b 0020 4000 0000 0005 0000 0004 ff03 c021 0703 001c 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 + +4500 0030 5e1b 0000 802f 792e c0a8 7101 c0a8 7103 3081 880b 000c 0000 0000 0005 0000 0005 80fd 0104 000a 1206 0100 0001 + +4500 002a 000b 0000 ff2f 5844 c0a8 7103 c0a8 7101 3081 880b 0006 4000 0000 0006 0000 0005 80fd 0101 0004 + +4500 002c 000c 0000 ff2f 5841 c0a8 7103 c0a8 7101 3001 880b 000c 4000 0000 0007 80fd 0404 000a 1206 0100 0001 + +4500 0048 5e1c 0000 802f 7915 c0a8 7101 c0a8 7103 3081 880b 0024 0000 0000 0006 0000 0007 8021 0105 0022 0306 0000 0000 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 + +4500 0042 000d 0000 ff2f 582a c0a8 7103 c0a8 7101 3081 880b 001e 4000 0000 0008 0000 0006 8021 0405 001c 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 + +4500 0030 5e1d 0000 802f 792c c0a8 7101 c0a8 7103 3081 880b 000c 0000 0000 0007 0000 0008 8021 0401 000a 0206 002d 0f01 + +4500 0030 000e 0000 ff2f 583b c0a8 7103 c0a8 7101 3081 880b 000c 4000 0000 0009 0000 0007 8021 0102 000a 0306 c0a8 0001 + +4500 002a 5e1e 0000 802f 7931 c0a8 7101 c0a8 7103 3081 880b 0006 0000 0000 0008 0000 0009 80fd 0201 0004 + +4500 0032 5e1f 0000 802f 7928 c0a8 7101 c0a8 7103 3001 880b 0012 0000 0000 0009 80fd 0506 0010 577f 7c5b 003c cd74 0000 02dc + +4500 002a 000f 0000 ff2f 5840 c0a8 7103 c0a8 7101 3081 880b 0006 4000 0000 000a 0000 0009 80fd 0606 0004 + +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni14 b/contrib/netbsd-tests/ipf/expected/ni14 new file mode 100644 index 0000000..5ad5a1b --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni14 @@ -0,0 +1,63 @@ +4500 0030 5e11 4000 8006 ec0b c0a8 7101 7f00 0001 05e7 06bb abf0 4aa5 0000 0000 7002 faf0 d44b 0000 0204 05b4 0101 0402 + +4500 002c 0000 4000 4006 d776 c0a8 7103 c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 6012 8000 a348 0000 0204 05b4 + +4500 00c4 5e12 4000 8006 eb76 c0a8 7101 7f00 0001 05e7 06bb abf0 4aa6 a564 68db 5018 faf0 954b 0000 009c 0001 1a2b 3c4d 0001 0000 0100 0000 0000 0001 0000 0001 0000 0a28 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 4d69 6372 6f73 6f66 7420 5769 6e64 6f77 7320 4e54 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 00c4 0001 4000 4006 d6dd c0a8 7103 c0a8 7101 06bb 05e7 a564 68db abf0 4b42 5018 832c cecf 0000 009c 0001 1a2b 3c4d 0002 0000 0100 0100 0000 0000 0000 0000 0001 0001 6c6f 6361 6c00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 6c69 6e75 7800 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 00d0 5e13 4000 8006 eb69 c0a8 7101 7f00 0001 05e7 06bb abf0 4b42 a564 6977 5018 fa54 5eb2 0000 00a8 0001 1a2b 3c4d 0007 0000 4000 1331 0000 012c 05f5 e100 0000 0003 0000 0003 0040 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 0048 0002 4000 4006 d758 c0a8 7103 c0a8 7101 06bb 05e7 a564 6977 abf0 4bea 5018 832c 36fa 0000 0020 0001 1a2b 3c4d 0008 0000 0000 4000 0100 0000 05f5 e100 0040 0000 0000 0000 + +4500 0040 5e14 4000 8006 ebf8 c0a8 7101 7f00 0001 05e7 06bb abf0 4bea a564 6997 5018 fa34 9abb 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 ffff ffff ffff ffff + +4500 0039 5e15 0000 802f 2bd6 c0a8 7101 7f00 0001 3001 880b 0019 0000 0000 0000 ff03 c021 0100 0015 0104 0578 0506 577f 7c5b 0702 0802 0d03 06 + +4500 0020 0003 0000 ff2f 5856 c0a8 7103 c0a8 7101 2081 880b 0000 4000 ffff ffff + +4500 0028 0004 4000 4006 d776 c0a8 7103 c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 5010 832c b5c1 0000 + +4500 0038 0005 0000 ff2f 583c c0a8 7103 c0a8 7101 3001 880b 0018 4000 0000 0000 ff03 c021 0101 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 + +4500 002f 0006 0000 ff2f 5844 c0a8 7103 c0a8 7101 3081 880b 000b 4000 0000 0001 0000 0000 ff03 c021 0400 0007 0d03 06 + +4500 003c 5e16 0000 802f 2bd2 c0a8 7101 7f00 0001 3081 880b 0018 0000 0000 0001 0000 0001 ff03 c021 0201 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 + +4500 0036 5e17 0000 802f 2bd7 c0a8 7101 7f00 0001 3001 880b 0016 0000 0000 0002 ff03 c021 0101 0012 0104 0578 0506 577f 7c5b 0702 0802 + +4500 003a 0007 0000 ff2f 5838 c0a8 7103 c0a8 7101 3081 880b 0016 4000 0000 0002 0000 0002 ff03 c021 0201 0012 0104 0578 0506 577f 7c5b 0702 0802 + +4500 0032 0008 0000 ff2f 583f c0a8 7103 c0a8 7101 3001 880b 0012 4000 0000 0003 8021 0101 0010 0306 c0a8 0001 0206 002d 0f01 + +4500 0040 5e18 4000 8006 ebf4 c0a8 7101 7f00 0001 05e7 06bb abf0 4c02 a564 6997 5018 fa34 9aa3 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 0000 0000 ffff ffff + +4500 0038 5e19 0000 802f 2bd3 c0a8 7101 7f00 0001 3081 880b 0014 0000 0000 0003 0000 0003 c021 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 + +4500 003e 0009 0000 ff2f 5832 c0a8 7103 c0a8 7101 3081 880b 001a 4000 0000 0004 0000 0003 ff03 c021 0702 0016 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 + +4500 003e 5e1a 0000 802f 2bcc c0a8 7101 7f00 0001 3081 880b 001a 0000 0000 0004 0000 0004 c021 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 + +4500 0044 000a 0000 ff2f 582b c0a8 7103 c0a8 7101 3081 880b 0020 4000 0000 0005 0000 0004 ff03 c021 0703 001c 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 + +4500 0030 5e1b 0000 802f 2bd9 c0a8 7101 7f00 0001 3081 880b 000c 0000 0000 0005 0000 0005 80fd 0104 000a 1206 0100 0001 + +4500 002a 000b 0000 ff2f 5844 c0a8 7103 c0a8 7101 3081 880b 0006 4000 0000 0006 0000 0005 80fd 0101 0004 + +4500 002c 000c 0000 ff2f 5841 c0a8 7103 c0a8 7101 3001 880b 000c 4000 0000 0007 80fd 0404 000a 1206 0100 0001 + +4500 0048 5e1c 0000 802f 2bc0 c0a8 7101 7f00 0001 3081 880b 0024 0000 0000 0006 0000 0007 8021 0105 0022 0306 0000 0000 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 + +4500 0042 000d 0000 ff2f 582a c0a8 7103 c0a8 7101 3081 880b 001e 4000 0000 0008 0000 0006 8021 0405 001c 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 + +4500 0030 5e1d 0000 802f 2bd7 c0a8 7101 7f00 0001 3081 880b 000c 0000 0000 0007 0000 0008 8021 0401 000a 0206 002d 0f01 + +4500 0030 000e 0000 ff2f 583b c0a8 7103 c0a8 7101 3081 880b 000c 4000 0000 0009 0000 0007 8021 0102 000a 0306 c0a8 0001 + +4500 002a 5e1e 0000 802f 2bdc c0a8 7101 7f00 0001 3081 880b 0006 0000 0000 0008 0000 0009 80fd 0201 0004 + +4500 0032 5e1f 0000 802f 2bd3 c0a8 7101 7f00 0001 3001 880b 0012 0000 0000 0009 80fd 0506 0010 577f 7c5b 003c cd74 0000 02dc + +4500 002a 000f 0000 ff2f 5840 c0a8 7103 c0a8 7101 3081 880b 0006 4000 0000 000a 0000 0009 80fd 0606 0004 + +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni15 b/contrib/netbsd-tests/ipf/expected/ni15 new file mode 100644 index 0000000..3820d56 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni15 @@ -0,0 +1,63 @@ +4500 0030 0000 4000 8006 9772 c0a8 7101 c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 7002 faf0 21a1 0000 0204 05b4 0101 0402 + +4500 002c 69a6 4000 4006 6dd0 c0a8 7103 c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 6012 8000 a348 0000 0204 05b4 + +4500 00c4 0001 4000 8006 96dd c0a8 7101 c0a8 7103 05e7 06bb abf0 4aa6 a564 68db 5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d 0001 0000 0100 0000 0000 0001 0000 0001 0000 0a28 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 4d69 6372 6f73 6f66 7420 5769 6e64 6f77 7320 4e54 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 00c4 69a7 4000 4006 6d37 c0a8 7103 c0a8 7101 06bb 05e7 a564 68db abf0 4b42 5018 832c cecf 0000 009c 0001 1a2b 3c4d 0002 0000 0100 0100 0000 0000 0000 0000 0001 0001 6c6f 6361 6c00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 6c69 6e75 7800 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 00d0 0002 4000 8006 96d0 c0a8 7101 c0a8 7103 05e7 06bb abf0 4b42 a564 6977 5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d 0007 0000 4000 1331 0000 012c 05f5 e100 0000 0003 0000 0003 0040 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 0048 69a8 4000 4006 6db2 c0a8 7103 c0a8 7101 06bb 05e7 a564 6977 abf0 4bea 5018 832c 36fa 0000 0020 0001 1a2b 3c4d 0008 0000 0000 4000 0100 0000 05f5 e100 0040 0000 0000 0000 + +4500 0040 0003 4000 8006 975f c0a8 7101 c0a8 7103 05e7 06bb abf0 4bea a564 6997 5018 fa34 e810 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 ffff ffff ffff ffff + +4500 0039 0004 0000 802f d73c c0a8 7101 c0a8 7103 3001 880b 0019 0000 0000 0000 ff03 c021 0100 0015 0104 0578 0506 577f 7c5b 0702 0802 0d03 06 + +4500 0020 69a9 0000 ff2f eeaf c0a8 7103 c0a8 7101 2081 880b 0000 4000 ffff ffff + +4500 0028 69aa 4000 4006 6dd0 c0a8 7103 c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 5010 832c b5c1 0000 + +4500 0038 69ab 0000 ff2f ee95 c0a8 7103 c0a8 7101 3001 880b 0018 4000 0000 0000 ff03 c021 0101 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 + +4500 002f 69ac 0000 ff2f ee9d c0a8 7103 c0a8 7101 3081 880b 000b 4000 0000 0001 0000 0000 ff03 c021 0400 0007 0d03 06 + +4500 003c 0005 0000 802f d738 c0a8 7101 c0a8 7103 3081 880b 0018 0000 0000 0001 0000 0001 ff03 c021 0201 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 + +4500 0036 0006 0000 802f d73d c0a8 7101 c0a8 7103 3001 880b 0016 0000 0000 0002 ff03 c021 0101 0012 0104 0578 0506 577f 7c5b 0702 0802 + +4500 003a 69ad 0000 ff2f ee91 c0a8 7103 c0a8 7101 3081 880b 0016 4000 0000 0002 0000 0002 ff03 c021 0201 0012 0104 0578 0506 577f 7c5b 0702 0802 + +4500 0032 69ae 0000 ff2f ee98 c0a8 7103 c0a8 7101 3001 880b 0012 4000 0000 0003 8021 0101 0010 0306 c0a8 0001 0206 002d 0f01 + +4500 0040 0007 4000 8006 975b c0a8 7101 c0a8 7103 05e7 06bb abf0 4c02 a564 6997 5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 0000 0000 ffff ffff + +4500 0038 0008 0000 802f d739 c0a8 7101 c0a8 7103 3081 880b 0014 0000 0000 0003 0000 0003 c021 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 + +4500 003e 69af 0000 ff2f ee8b c0a8 7103 c0a8 7101 3081 880b 001a 4000 0000 0004 0000 0003 ff03 c021 0702 0016 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 + +4500 003e 0009 0000 802f d732 c0a8 7101 c0a8 7103 3081 880b 001a 0000 0000 0004 0000 0004 c021 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 + +4500 0044 69b0 0000 ff2f ee84 c0a8 7103 c0a8 7101 3081 880b 0020 4000 0000 0005 0000 0004 ff03 c021 0703 001c 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 + +4500 0030 000a 0000 802f d73f c0a8 7101 c0a8 7103 3081 880b 000c 0000 0000 0005 0000 0005 80fd 0104 000a 1206 0100 0001 + +4500 002a 69b1 0000 ff2f ee9d c0a8 7103 c0a8 7101 3081 880b 0006 4000 0000 0006 0000 0005 80fd 0101 0004 + +4500 002c 69b2 0000 ff2f ee9a c0a8 7103 c0a8 7101 3001 880b 000c 4000 0000 0007 80fd 0404 000a 1206 0100 0001 + +4500 0048 000b 0000 802f d726 c0a8 7101 c0a8 7103 3081 880b 0024 0000 0000 0006 0000 0007 8021 0105 0022 0306 0000 0000 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 + +4500 0042 69b3 0000 ff2f ee83 c0a8 7103 c0a8 7101 3081 880b 001e 4000 0000 0008 0000 0006 8021 0405 001c 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 + +4500 0030 000c 0000 802f d73d c0a8 7101 c0a8 7103 3081 880b 000c 0000 0000 0007 0000 0008 8021 0401 000a 0206 002d 0f01 + +4500 0030 69b4 0000 ff2f ee94 c0a8 7103 c0a8 7101 3081 880b 000c 4000 0000 0009 0000 0007 8021 0102 000a 0306 c0a8 0001 + +4500 002a 000d 0000 802f d742 c0a8 7101 c0a8 7103 3081 880b 0006 0000 0000 0008 0000 0009 80fd 0201 0004 + +4500 0032 000e 0000 802f d739 c0a8 7101 c0a8 7103 3001 880b 0012 0000 0000 0009 80fd 0506 0010 577f 7c5b 003c cd74 0000 02dc + +4500 002a 69b5 0000 ff2f ee99 c0a8 7103 c0a8 7101 3081 880b 0006 4000 0000 000a 0000 0009 80fd 0606 0004 + +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni16 b/contrib/netbsd-tests/ipf/expected/ni16 new file mode 100644 index 0000000..2c34f5c --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni16 @@ -0,0 +1,63 @@ +4500 0030 0000 4000 8006 9772 c0a8 7101 c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 7002 faf0 21a1 0000 0204 05b4 0101 0402 + +4500 002c 69a6 4000 4006 9376 c0a8 7103 0a02 0202 06bb 05e7 a564 68da abf0 4aa6 6012 8000 c8ee 0000 0204 05b4 + +4500 00c4 0001 4000 8006 96dd c0a8 7101 c0a8 7103 05e7 06bb abf0 4aa6 a564 68db 5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d 0001 0000 0100 0000 0000 0001 0000 0001 0000 0a28 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 4d69 6372 6f73 6f66 7420 5769 6e64 6f77 7320 4e54 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 00c4 69a7 4000 4006 92dd c0a8 7103 0a02 0202 06bb 05e7 a564 68db abf0 4b42 5018 832c f475 0000 009c 0001 1a2b 3c4d 0002 0000 0100 0100 0000 0000 0000 0000 0001 0001 6c6f 6361 6c00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 6c69 6e75 7800 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 00d0 0002 4000 8006 96d0 c0a8 7101 c0a8 7103 05e7 06bb abf0 4b42 a564 6977 5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d 0007 0000 4000 1331 0000 012c 05f5 e100 0000 0003 0000 0003 0040 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 0048 69a8 4000 4006 9358 c0a8 7103 0a02 0202 06bb 05e7 a564 6977 abf0 4bea 5018 832c 5ca0 0000 0020 0001 1a2b 3c4d 0008 0000 0000 4000 0100 0000 05f5 e100 0040 0000 0000 0000 + +4500 0040 0003 4000 8006 975f c0a8 7101 c0a8 7103 05e7 06bb abf0 4bea a564 6997 5018 fa34 e810 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 ffff ffff ffff ffff + +4500 0039 0004 0000 802f d73c c0a8 7101 c0a8 7103 3001 880b 0019 0000 0000 0000 ff03 c021 0100 0015 0104 0578 0506 577f 7c5b 0702 0802 0d03 06 + +4500 0020 69a9 0000 ff2f 1456 c0a8 7103 0a02 0202 2081 880b 0000 4000 ffff ffff + +4500 0028 69aa 4000 4006 9376 c0a8 7103 0a02 0202 06bb 05e7 a564 6997 abf0 4c02 5010 832c db67 0000 + +4500 0038 69ab 0000 ff2f 143c c0a8 7103 0a02 0202 3001 880b 0018 4000 0000 0000 ff03 c021 0101 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 + +4500 002f 69ac 0000 ff2f 1444 c0a8 7103 0a02 0202 3081 880b 000b 4000 0000 0001 0000 0000 ff03 c021 0400 0007 0d03 06 + +4500 003c 0005 0000 802f d738 c0a8 7101 c0a8 7103 3081 880b 0018 0000 0000 0001 0000 0001 ff03 c021 0201 0014 0206 0000 0000 0506 22d9 0cfa 0702 0802 + +4500 0036 0006 0000 802f d73d c0a8 7101 c0a8 7103 3001 880b 0016 0000 0000 0002 ff03 c021 0101 0012 0104 0578 0506 577f 7c5b 0702 0802 + +4500 003a 69ad 0000 ff2f 1438 c0a8 7103 0a02 0202 3081 880b 0016 4000 0000 0002 0000 0002 ff03 c021 0201 0012 0104 0578 0506 577f 7c5b 0702 0802 + +4500 0032 69ae 0000 ff2f 143f c0a8 7103 0a02 0202 3001 880b 0012 4000 0000 0003 8021 0101 0010 0306 c0a8 0001 0206 002d 0f01 + +4500 0040 0007 4000 8006 975b c0a8 7101 c0a8 7103 05e7 06bb abf0 4c02 a564 6997 5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d 000f 0000 0000 0000 0000 0000 ffff ffff + +4500 0038 0008 0000 802f d739 c0a8 7101 c0a8 7103 3081 880b 0014 0000 0000 0003 0000 0003 c021 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 + +4500 003e 69af 0000 ff2f 1432 c0a8 7103 0a02 0202 3081 880b 001a 4000 0000 0004 0000 0003 ff03 c021 0702 0016 0c02 0012 577f 7c5b 4d53 5241 5356 352e 3130 + +4500 003e 0009 0000 802f d732 c0a8 7101 c0a8 7103 3081 880b 001a 0000 0000 0004 0000 0004 c021 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 + +4500 0044 69b0 0000 ff2f 142b c0a8 7103 0a02 0202 3081 880b 0020 4000 0000 0005 0000 0004 ff03 c021 0703 001c 0c03 0018 577f 7c5b 4d53 5241 532d 302d 434c 4159 4d4f 4f52 + +4500 0030 000a 0000 802f d73f c0a8 7101 c0a8 7103 3081 880b 000c 0000 0000 0005 0000 0005 80fd 0104 000a 1206 0100 0001 + +4500 002a 69b1 0000 ff2f 1444 c0a8 7103 0a02 0202 3081 880b 0006 4000 0000 0006 0000 0005 80fd 0101 0004 + +4500 002c 69b2 0000 ff2f 1441 c0a8 7103 0a02 0202 3001 880b 000c 4000 0000 0007 80fd 0404 000a 1206 0100 0001 + +4500 0048 000b 0000 802f d726 c0a8 7101 c0a8 7103 3081 880b 0024 0000 0000 0006 0000 0007 8021 0105 0022 0306 0000 0000 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 + +4500 0042 69b3 0000 ff2f 142a c0a8 7103 0a02 0202 3081 880b 001e 4000 0000 0008 0000 0006 8021 0405 001c 8106 0000 0000 8206 0000 0000 8306 0000 0000 8406 0000 0000 + +4500 0030 000c 0000 802f d73d c0a8 7101 c0a8 7103 3081 880b 000c 0000 0000 0007 0000 0008 8021 0401 000a 0206 002d 0f01 + +4500 0030 69b4 0000 ff2f 143b c0a8 7103 0a02 0202 3081 880b 000c 4000 0000 0009 0000 0007 8021 0102 000a 0306 c0a8 0001 + +4500 002a 000d 0000 802f d742 c0a8 7101 c0a8 7103 3081 880b 0006 0000 0000 0008 0000 0009 80fd 0201 0004 + +4500 0032 000e 0000 802f d739 c0a8 7101 c0a8 7103 3001 880b 0012 0000 0000 0009 80fd 0506 0010 577f 7c5b 003c cd74 0000 02dc + +4500 002a 69b5 0000 ff2f 1440 c0a8 7103 0a02 0202 3081 880b 0006 4000 0000 000a 0000 0009 80fd 0606 0004 + +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni17 b/contrib/netbsd-tests/ipf/expected/ni17 new file mode 100644 index 0000000..74eb4dd --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni17 @@ -0,0 +1,7 @@ +< le0 ip #0 40(20) 6 10.2.2.5,2000 > 10.1.1.252,3128 +< le0 ip #0 40(20) 6 10.2.2.6,2000 > 10.1.2.252,3128 +< le0 ip #0 40(20) 6 10.2.2.7,2000 > 10.1.3.252,3128 +< le0 ip #0 40(20) 6 10.2.2.7,2001 > 10.1.3.252,3128 +< le0 ip #0 40(20) 6 10.2.2.8,2000 > 10.1.1.253,3128 +< le0 ip #0 40(20) 6 10.2.2.9,2000 > 10.1.2.253,3128 +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni18 b/contrib/netbsd-tests/ipf/expected/ni18 new file mode 100644 index 0000000..defc59c --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni18 @@ -0,0 +1,5 @@ +< hme0 ip #0 40(20) 6 2.2.2.2,3000 > 1.1.1.1,80 +< hme0 ip #0 40(20) 6 2.2.2.2,3000 > 192.168.1.1,80 +> hme1 ip #0 40(20) 6 203.1.1.1,10000 > 4.5.6.7,80 +> hme1 ip #0 40(20) 6 10.1.1.2,5050 > 4.5.6.7,80 +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni19 b/contrib/netbsd-tests/ipf/expected/ni19 new file mode 100644 index 0000000..e55c75d --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni19 @@ -0,0 +1,43 @@ +4500 0040 e3fc 4000 4006 40b5 0a01 0101 0a01 0104 03f1 0202 6523 90b2 0000 0000 b002 8000 a431 0000 0204 05b4 0103 0300 0402 0101 0101 080a 0000 0000 0000 0000 + +4500 0034 0000 4000 4006 fe13 0a01 0104 c0a8 7103 0202 03f1 915a a5c4 6523 90b3 8012 16d0 e89c 0000 0204 05b4 0101 0402 0103 0302 + +4500 0028 e3fd 4000 4006 40cc 0a01 0101 0a01 0104 03f1 0202 6523 90b3 915a a5c5 5010 832c e3b7 0000 + +4500 002d e3fe 4000 4006 40c6 0a01 0101 0a01 0104 03f1 0202 6523 90b3 915a a5c5 5018 832c 8242 0000 3130 3038 00 + +4500 0028 7ce5 4000 4006 813a 0a01 0104 c0a8 7103 0202 03f1 915a a5c5 6523 90b8 5010 05b4 3a81 0000 + +4500 003c 1186 4000 4006 ec85 0a01 0104 c0a8 7103 03ff 03f0 91d4 c8a2 0000 0000 a002 16d0 b8c0 0000 0204 05b4 0402 080a 0039 d924 0000 0000 0103 0302 + +4500 0040 e3ff 4000 4006 40b2 0a01 0101 0a01 0104 03f0 03ff 66e5 b810 91d4 c8a3 b012 8000 452f 0000 0204 05b4 0103 0300 0101 080a 0000 0000 0039 d924 0402 0101 + +4500 0034 1188 4000 4006 ec8b 0a01 0104 c0a8 7103 03ff 03f0 91d4 c8a3 66e5 b811 8010 05b4 d99b 0000 0101 080a 0039 d925 0000 0000 + +4500 0030 e400 4000 4006 40c1 0a01 0101 0a01 0104 03f1 0202 6523 90b8 915a a5c5 5018 832c 3560 0000 6461 7272 656e 7200 + +4500 0028 7ce7 4000 4006 8138 0a01 0104 c0a8 7103 0202 03f1 915a a5c5 6523 90c0 5010 05b4 3a79 0000 + +4500 0053 e401 4000 4006 409d 0a01 0101 0a01 0104 03f1 0202 6523 90c0 915a a5c5 5018 832c cce7 0000 6461 7272 656e 7200 7368 202d 6320 2265 6368 6f20 666f 6f20 3e26 313b 2065 6368 6f20 6261 7220 3e26 3222 00 + +4500 0028 7ce9 4000 4006 8136 0a01 0104 c0a8 7103 0202 03f1 915a a5c5 6523 90eb 5010 05b4 3a4e 0000 + +4500 0029 7ceb 4000 4006 8133 0a01 0104 c0a8 7103 0202 03f1 915a a5c5 6523 90eb 5018 05b4 3a45 0000 00 + +4500 0028 e403 4000 4006 40c6 0a01 0101 0a01 0104 03f1 0202 6523 90eb 915a a5c6 5010 832c e37e 0000 + +4500 002c 7ced 4000 4006 812e 0a01 0104 c0a8 7103 0202 03f1 915a a5c6 6523 90eb 5018 05b4 64c7 0000 666f 6f0a + +4500 0038 118a 4000 4006 ec85 0a01 0104 c0a8 7103 03ff 03f0 91d4 c8a3 66e5 b811 8018 05b4 00dd 0000 0101 080a 0039 dd6c 0000 0000 6261 720a + +4500 0028 7cef 4000 4006 8130 0a01 0104 c0a8 7103 0202 03f1 915a a5ca 6523 90eb 5011 05b4 3a48 0000 + +4500 0034 118c 4000 4006 ec87 0a01 0104 c0a8 7103 03ff 03f0 91d4 c8a7 66e5 b811 8011 05b4 d54e 0000 0101 080a 0039 dd6d 0000 0000 + +0 +0 +0 +0 +0 +0 +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni2 b/contrib/netbsd-tests/ipf/expected/ni2 new file mode 100644 index 0000000..69a5272 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni2 @@ -0,0 +1,19 @@ +4510 002c 0000 4000 3e06 78df 0101 0101 c0a8 0133 9c40 0077 a664 2485 0000 0000 6002 4000 2ca8 0000 0204 05b4 + +4500 002c ce83 4000 7e06 606b c0a8 0133 0a01 0201 0077 05f6 fbdf 1a21 a664 2486 6012 2238 c0a8 0000 0204 05b4 + +4510 0028 0001 4000 3e06 78e2 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a22 5010 4470 29e3 0000 + +4500 005b cf83 4000 7e06 5f3c c0a8 0133 0a01 0201 0077 05f6 fbdf 1a22 a664 2486 5018 2238 ce2a 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0a + +4510 0028 0002 4000 3e06 78e1 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a55 5010 4470 29b0 0000 + +4510 002e 0003 4000 3e06 78da 0101 0101 c0a8 0133 9c40 0077 a664 2486 fbdf 1a55 5018 4470 1c98 0000 0000 0000 0d0a + +4500 0048 e383 4000 7e06 4b4f c0a8 0133 0a01 0201 0077 05f6 fbdf 1a55 a664 248c 5018 2232 d80a 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 05dc e483 4000 7e06 44bb c0a8 0133 0a01 0201 0077 05f6 fbdf 1a75 a664 248c 5010 2232 9f2d 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3331 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 1111 2222 3333 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 + +4500 0038 0004 4000 4001 76e4 0101 0101 c0a8 0133 0304 444f 0000 05a0 4500 05dc e483 4000 7e06 4ebb c0a8 0133 0101 0101 0077 9c40 fbdf 1a75 + +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni20 b/contrib/netbsd-tests/ipf/expected/ni20 new file mode 100644 index 0000000..913ef0b --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni20 @@ -0,0 +1,69 @@ +4500 0040 e3fc 4000 4006 f362 c0a8 7103 c0a8 7104 03f1 0202 6523 90b2 0000 0000 b002 8000 56df 0000 0204 05b4 0103 0300 0402 0101 0101 080a 0000 0000 0000 0000 + +4500 0034 0000 4000 4006 fe13 0a01 0104 c0a8 7103 0202 03f1 915a a5c4 6523 90b3 8012 16d0 e89c 0000 0204 05b4 0101 0402 0103 0302 + +4500 0028 e3fd 4000 4006 f379 c0a8 7103 c0a8 7104 03f1 0202 6523 90b3 915a a5c5 5010 832c 9665 0000 + +4500 002d e3fe 4000 4006 f373 c0a8 7103 c0a8 7104 03f1 0202 6523 90b3 915a a5c5 5018 832c 34f0 0000 3130 3038 00 + +4500 0028 7ce5 4000 4006 813a 0a01 0104 c0a8 7103 0202 03f1 915a a5c5 6523 90b8 5010 05b4 3a81 0000 + +4500 003c 1186 4000 4006 ec85 0a01 0104 c0a8 7103 03ff 03f0 91d4 c8a2 0000 0000 a002 16d0 b8c0 0000 0204 05b4 0402 080a 0039 d924 0000 0000 0103 0302 + +4500 0040 e3ff 4000 4006 f35f c0a8 7103 c0a8 7104 03f0 03ff 66e5 b810 91d4 c8a3 b012 8000 f7dc 0000 0204 05b4 0103 0300 0101 080a 0000 0000 0039 d924 0402 0101 + +4500 0034 1188 4000 4006 ec8b 0a01 0104 c0a8 7103 03ff 03f0 91d4 c8a3 66e5 b811 8010 05b4 d99b 0000 0101 080a 0039 d925 0000 0000 + +4500 0030 e400 4000 4006 f36e c0a8 7103 c0a8 7104 03f1 0202 6523 90b8 915a a5c5 5018 832c e80d 0000 6461 7272 656e 7200 + +4500 0028 7ce7 4000 4006 8138 0a01 0104 c0a8 7103 0202 03f1 915a a5c5 6523 90c0 5010 05b4 3a79 0000 + +4500 0053 e401 4000 4006 f34a c0a8 7103 c0a8 7104 03f1 0202 6523 90c0 915a a5c5 5018 832c 7f95 0000 6461 7272 656e 7200 7368 202d 6320 2265 6368 6f20 666f 6f20 3e26 313b 2065 6368 6f20 6261 7220 3e26 3222 00 + +4500 0028 7ce9 4000 4006 8136 0a01 0104 c0a8 7103 0202 03f1 915a a5c5 6523 90eb 5010 05b4 3a4e 0000 + +4500 0029 7ceb 4000 4006 8133 0a01 0104 c0a8 7103 0202 03f1 915a a5c5 6523 90eb 5018 05b4 3a45 0000 00 + +4500 0028 e403 4000 4006 f373 c0a8 7103 c0a8 7104 03f1 0202 6523 90eb 915a a5c6 5010 832c 962c 0000 + +4500 002c 7ced 4000 4006 812e 0a01 0104 c0a8 7103 0202 03f1 915a a5c6 6523 90eb 5018 05b4 64c7 0000 666f 6f0a + +4500 0038 118a 4000 4006 ec85 0a01 0104 c0a8 7103 03ff 03f0 91d4 c8a3 66e5 b811 8018 05b4 00dd 0000 0101 080a 0039 dd6c 0000 0000 6261 720a + +4500 0028 7cef 4000 4006 8130 0a01 0104 c0a8 7103 0202 03f1 915a a5ca 6523 90eb 5011 05b4 3a48 0000 + +4500 0034 118c 4000 4006 ec87 0a01 0104 c0a8 7103 03ff 03f0 91d4 c8a7 66e5 b811 8011 05b4 d54e 0000 0101 080a 0039 dd6d 0000 0000 + +0 +0 +0 +0 +0 +0 +List of active MAP/Redirect filters: +rdr bge0 10.1.1.4/32 port 514 -> 192.168.113.4/32 port 514 tcp proxy rcmd + +List of active sessions: +MAP 192.168.113.4 1023 <- -> 10.1.1.4 1023 [192.168.113.3 1008] +RDR 192.168.113.4 514 <- -> 10.1.1.4 514 [192.168.113.3 1009] + proxy active + +Hostmap table: +192.168.113.4,192.168.113.3 -> 10.1.1.4,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +5 block in all +1 pass in quick on bge0 proto tcp from any to any port = 514 flags S/FSRPAU keep state +Rules configured (set 0, out) +2 block out all +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni21 b/contrib/netbsd-tests/ipf/expected/ni21 new file mode 100644 index 0000000..53e64a5 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni21 @@ -0,0 +1,6 @@ +> eri0 ip #0 20(20) 0 4.4.4.4 > 3.3.3.3 +0 +< lan0 ip #0 20(20) 0 3.3.3.3 > 2.2.2.2 +> eri0 ip #0 20(20) 0 4.4.4.4 > 3.3.3.3 +0 +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni23 b/contrib/netbsd-tests/ipf/expected/ni23 new file mode 100644 index 0000000..586373c --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni23 @@ -0,0 +1,37 @@ +> ppp0 ip #0 28(20) 17 4.4.4.4,6700 > 2.2.2.2,4500 +0 +< hme0 ip #0 28(20) 17 2.2.2.2,4500 > 3.3.3.1,6700 +> bge0 ip #0 28(20) 17 1.1.2.3,4500 > 3.3.3.1,6700 +List of active MAP/Redirect filters: +rdr le0,bge0 1.1.0.0/16 -> 2.2.2.2/32 ip +map hme0,ppp0 3.3.3.0/24 -> 4.4.4.4/32 + +List of active sessions: +MAP 3.3.3.1 6700 <- -> 4.4.4.4 6700 [2.2.2.2 4500] +RDR 2.2.2.2 4500 <- -> 1.1.2.3 4500 [3.3.3.1 6700] + +Hostmap table: +3.3.3.1,2.2.2.2 -> 4.4.4.4,0.0.0.0 (use = 1) +List of active state sessions: +4:udp src:3.3.3.1,6700 dst:2.2.2.2,4500 24 + FWD: IN pkts 1 bytes 28 OUT pkts 1 bytes 28 + REV: IN pkts 1 bytes 28 OUT pkts 1 bytes 28 + tag 0 pass 0x2008402 = pass in keep state + interfaces: in X[le0],X[hme0] out X[ppp0],X[bge0] + Sync status: not synchronized +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +1 block in all +1 pass in on le0,hme0 to ppp0:3.3.3.254 out-via ppp0,bge0 inet proto udp from any to any keep state +Rules configured (set 0, out) +0 block out all +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni3 b/contrib/netbsd-tests/ipf/expected/ni3 new file mode 100644 index 0000000..107d5d9 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni3 @@ -0,0 +1,7 @@ +4500 003c 0000 4000 ff06 67a8 0606 0606 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0303 acab 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 + +4500 0058 809a 0000 ff01 3101 0303 0303 0202 0202 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni4 b/contrib/netbsd-tests/ipf/expected/ni4 new file mode 100644 index 0000000..627aa19 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni4 @@ -0,0 +1,7 @@ +4500 003c 0000 4000 ff06 67a8 0606 0606 0404 0404 9c40 0050 0000 0001 0000 0000 a002 16d0 849a 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +4500 0038 809a 0000 ff01 3121 0303 0303 0202 0202 0303 acac 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 + +4500 0058 809a 0000 ff01 3101 0303 0303 0202 0202 0303 0937 0000 0000 4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni5 b/contrib/netbsd-tests/ipf/expected/ni5 new file mode 100644 index 0000000..14d9837 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni5 @@ -0,0 +1,96 @@ +4500 002c 0000 4000 ff06 02fc 0101 0101 96cb e002 8032 0015 bd6b c9c8 0000 0000 6002 2238 f5a2 0000 0204 05b4 + +4500 002c ffdd 4000 ef06 5374 96cb e002 c0a8 0103 0015 8032 3786 76c4 bd6b c9c9 6012 269c 8369 0000 0204 0584 + +4500 0028 0001 4000 ff06 02ff 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 76c5 5010 269c 5aa0 0000 + +ipf_p_ftp_servert_valid:i(0) < 5 +4500 006f ffde 4000 ef06 5330 96cb e002 c0a8 0103 0015 8032 3786 76c5 bd6b c9c9 5018 269c 967e 0000 3232 302d 636f 6f6d 6273 2e61 6e75 2e65 6475 2e61 7520 4e63 4654 5064 2053 6572 7665 7220 2866 7265 6520 6564 7563 6174 696f 6e61 6c20 6c69 6365 6e73 6529 2072 6561 6479 2e0d 0a + +4500 0028 0002 4000 ff06 02fe 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 770c 5010 269c 5a59 0000 + +4500 00c7 ffdf 4000 ef06 52d7 96cb e002 c0a8 0103 0015 8032 3786 770c bd6b c9c9 5018 269c 1087 0000 3232 302d 0d0a 3232 302d 4d61 696e 7461 696e 6564 2062 7920 5253 5353 2061 6e64 2052 5350 4153 2049 5420 5374 6166 6620 2870 7265 7669 6f75 736c 7920 6b6e 6f77 6e20 6173 2043 6f6f 6d62 7320 436f 6d70 7574 696e 6720 556e 6974 290d 0a32 3230 2d41 6e79 2070 726f 626c 656d 7320 636f 6e74 6163 7420 6674 706d 6173 7465 7240 636f 6f6d 6273 2e61 6e75 2e65 6475 2e61 750d 0a32 3230 2d0d 0a32 3230 200d 0a + +4500 0028 0003 4000 ff06 02fd 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 77ab 5010 269c 59ba 0000 + +4500 0038 0004 4000 ff06 02ec 0101 0101 96cb e002 8032 0015 bd6b c9c9 3786 77ab 5018 269c d1c5 0000 5553 4552 2061 6e6f 6e79 6d6f 7573 0d0a + +4500 0028 ffe0 4000 ef06 5375 96cb e002 c0a8 0103 0015 8032 3786 77ab bd6b c9d9 5010 269c 9a00 0000 + +4500 006c ffe1 4000 ef06 5330 96cb e002 c0a8 0103 0015 8032 3786 77ab bd6b c9d9 5018 269c b00f 0000 3333 3120 4775 6573 7420 6c6f 6769 6e20 6f6b 2c20 7365 6e64 2079 6f75 7220 636f 6d70 6c65 7465 2065 2d6d 6169 6c20 6164 6472 6573 7320 6173 2070 6173 7377 6f72 642e 0d0a + +4500 0028 0005 4000 ff06 02fb 0101 0101 96cb e002 8032 0015 bd6b c9d9 3786 77ef 5010 269c 5966 0000 + +4500 0036 0006 4000 ff06 02ec 0101 0101 96cb e002 8032 0015 bd6b c9d9 3786 77ef 5018 269c 373f 0000 5041 5353 2061 7661 6c6f 6e40 0d0a + +ipf_p_ftp_servert_valid:i(0) < 5 +4500 005f ffe2 4000 ef06 533c 96cb e002 c0a8 0103 0015 8032 3786 77ef bd6b c9e7 5018 269c 895e 0000 3233 302d 596f 7520 6172 6520 7573 6572 2023 3420 6f66 2035 3020 7369 6d75 6c74 616e 656f 7573 2075 7365 7273 2061 6c6c 6f77 6564 2e0d 0a + +4500 0028 0007 4000 ff06 02f9 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7826 5010 269c 5921 0000 + +4500 0099 ffe3 4000 ef06 5301 96cb e002 c0a8 0103 0015 8032 3786 7826 bd6b c9e7 5018 269c d399 0000 3233 302d 0d0a 3233 302d 0d0a 3233 302d 4869 2e20 2057 6527 7265 2063 6c65 616e 696e 6720 7570 2e20 2041 6e79 2066 6565 6462 6163 6b20 6d6f 7374 2077 656c 636f 6d65 2e20 3130 2041 7567 2030 300d 0a32 3330 2d0d 0a32 3330 204c 6f67 6765 6420 696e 2061 6e6f 6e79 6d6f 7573 6c79 2e0d 0a + +4500 0028 0008 4000 ff06 02f8 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7897 5010 269c 58b0 0000 + +4500 0030 0009 4000 ff06 02ef 0101 0101 96cb e002 8032 0015 bd6b c9e7 3786 7897 5018 269c 86ae 0000 5459 5045 2049 0d0a + +4500 0038 ffe4 4000 ef06 5361 96cb e002 c0a8 0103 0015 8032 3786 7897 bd6b c9ef 5018 269c 5fae 0000 3230 3020 5479 7065 206f 6b61 792e 0d0a + +4500 0028 000a 4000 ff06 02f6 0101 0101 96cb e002 8032 0015 bd6b c9ef 3786 78a7 5010 269c 5898 0000 + +4500 003d 000b 4000 ff06 02e0 0101 0101 96cb e002 8032 0015 bd6b c9ef 3786 78a7 5018 269c 4b67 0000 504f 5254 2031 2c31 2c31 2c31 2c31 3238 2c35 310d 0a + +4500 0046 ffe5 4000 ef06 5352 96cb e002 c0a8 0103 0015 8032 3786 78a7 bd6b ca0c 5018 269c dbc3 0000 3230 3020 504f 5254 2063 6f6d 6d61 6e64 2073 7563 6365 7373 6675 6c2e 0d0a + +4500 0030 000c 4000 ff06 02ec 0101 0101 96cb e002 8032 0015 bd6b ca04 3786 78c5 5018 269c 866b 0000 5459 5045 2041 0d0a + +4500 0038 ffe6 4000 ef06 535f 96cb e002 c0a8 0103 0015 8032 3786 78c5 bd6b ca14 5018 269c 5f5b 0000 3230 3020 5479 7065 206f 6b61 792e 0d0a + +4500 002e 000d 4000 ff06 02ed 0101 0101 96cb e002 8032 0015 bd6b ca0c 3786 78d5 5018 269c a994 0000 4e4c 5354 0d0a + +4500 002c ffe7 4000 ef06 536a 96cb e002 c0a8 0103 0014 8033 d9f8 11d4 0000 0000 6002 2238 d190 0000 0204 0584 + +4500 002c 000e 4000 ff06 02ee 0101 0101 96cb e002 8033 0014 bd78 5c12 d9f8 11d5 6012 02f8 96de 0000 0204 0584 + +4500 0028 ffe8 4000 ef06 536d 96cb e002 c0a8 0103 0014 8033 d9f8 11d5 bd78 5c13 5010 269c cb1d 0000 + +4500 005d ffe9 4000 ef06 5337 96cb e002 c0a8 0103 0015 8032 3786 78d5 bd6b ca1a 5018 269c eed0 0000 3135 3020 4f70 656e 696e 6720 4153 4349 4920 6d6f 6465 2064 6174 6120 636f 6e6e 6563 7469 6f6e 2066 6f72 202f 6269 6e2f 6c73 2e0d 0a + +4500 0028 000f 4000 ff06 02f1 0101 0101 96cb e002 8033 0014 bd78 5c13 d9f8 11d5 5010 6348 4e1b 0000 + +4500 003d 0010 4000 ff06 02db 0101 0101 96cb e002 8032 0015 bd6b ca12 3786 78d5 5018 269c 4a16 0000 504f 5254 2031 2c31 2c31 2c31 2c31 3238 2c35 320d 0a + +4500 0046 ffea 4000 ef06 534d 96cb e002 c0a8 0103 0015 8032 3786 78d5 bd6b ca37 5018 269c db6a 0000 3230 3020 504f 5254 2063 6f6d 6d61 6e64 2073 7563 6365 7373 6675 6c2e 0d0a + +4500 0030 0011 4000 ff06 02e7 0101 0101 96cb e002 8032 0015 bd6b ca27 3786 78f3 5018 269c 861a 0000 5459 5045 2041 0d0a + +4500 0038 ffeb 4000 ef06 535a 96cb e002 c0a8 0103 0015 8032 3786 78f3 bd6b ca3f 5018 269c 5ef2 0000 3230 3020 5479 7065 206f 6b61 793e 0d0a + +4500 002e 0012 4000 ff06 02e8 0101 0101 96cb e002 8032 0015 bd6b ca2f 3786 7903 5018 269c a943 0000 4e4c 5354 0d0a + +4500 002c ffec 4000 ef06 5365 96cb e002 c0a8 0103 0014 8034 d9f8 11d4 0000 0000 6002 2238 d18f 0000 0204 0584 + +4500 002c 0013 4000 ff06 02e9 0101 0101 96cb e002 8034 0014 bd78 5c12 d9f8 11d5 6012 02f8 96dd 0000 0204 0584 + +4500 0028 ffec 4000 ef06 5369 96cb e002 c0a8 0103 0014 8034 d9f8 11d4 0000 0000 5010 2238 e90d 0000 + +0 +0 +0 +0 +0 +0 +4500 0040 fff0 4000 ef06 534d 96cb e002 c0a8 0103 0015 8032 3786 7903 bd6b ca3f 5018 269c 7c80 0000 3232 3620 4c69 7374 696e 6720 636f 6d70 6c65 7465 642e 0d0a + +4500 0028 0014 4000 ff06 02ec 0101 0101 96cb e002 8032 0015 bd6b ca2f 3786 791b 5010 269c 57e4 0000 + +4500 002e 0015 4000 ff06 02e5 0101 0101 96cb e002 8032 0015 bd6b ca2f 3786 791b 5018 269c b022 0000 5155 4954 0d0a + +4500 0036 fff2 4000 ef06 5355 96cb e002 c0a8 0103 0015 8032 3786 791b bd6b ca45 5018 269c a936 0000 3232 3120 476f 6f64 6279 652e 0d0a + +4500 0028 0016 4000 ff06 02ea 0101 0101 96cb e002 8032 0015 bd6b ca35 3786 7929 5011 269c 57cf 0000 + +0 +0 +0 +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni6 b/contrib/netbsd-tests/ipf/expected/ni6 new file mode 100644 index 0000000..e70412b --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni6 @@ -0,0 +1,63 @@ +< nf0 ip #52618 84(20) 17 192.168.6.1,32885 > 192.168.7.1,111 +> qfe0 ip #0 84(20) 17 192.168.7.2,32885 > 192.168.7.1,111 +< qfe0 ip #52611 56(20) 17 192.168.7.1,111 > 192.168.6.1,32885 +> nf0 ip #1 56(20) 17 192.168.6.2,111 > 192.168.6.1,32885 +< nf0 ip #54694 68(20) 17 192.168.6.1,32991 > 192.168.7.1,2049 +> qfe0 ip #2 68(20) 17 192.168.7.2,32991 > 192.168.7.1,2049 +< qfe0 ip #0 52(20) 17 192.168.7.1,2049 > 192.168.6.1,32991 +> nf0 ip #3 52(20) 17 192.168.6.2,2049 > 192.168.6.1,32991 +List of active MAP/Redirect filters: +rdr nf0 192.168.6.2/32 port 111 -> 192.168.7.1/32 port 111 udp proxy rpcbu +rdr nf0 192.168.6.2/32 port 111 -> 192.168.7.1/32 port 111 tcp proxy rpcbt +map qfe0 192.168.6.0/24 -> 192.168.7.2/32 + +List of active sessions: +MAP 192.168.6.1 32991 <- -> 192.168.7.2 32991 [192.168.7.1 2049] +RDR 192.168.7.1 2049 <- -> 192.168.6.2 2049 [192.168.6.1 32991] +RDR CLONE 192.168.7.1 2049 <- -> 192.168.6.2 2049 [192.168.6.1 0] +MAP 192.168.6.1 32885 <- -> 192.168.7.2 32885 [192.168.7.1 111] +RDR 192.168.7.1 111 <- -> 192.168.6.2 111 [192.168.6.1 32885] + proxy active + +Hostmap table: +192.168.6.1,192.168.7.1 -> 192.168.7.2,0.0.0.0 (use = 2) +List of active state sessions: +4:udp src:192.168.6.1,32991 dst:192.168.7.1,2049 24 + FWD: IN pkts 2 bytes 96 OUT pkts 1 bytes 68 + REV: IN pkts 1 bytes 52 OUT pkts 1 bytes 52 + tag 0 pass 0x502 = pass in quick keep state + interfaces: in X[nf0],X[qfe0] out X[qfe0],X[nf0] + Sync status: not synchronized +4:udp src:192.168.6.1,* dst:192.168.7.1,2049 240 CLONE + FWD: IN pkts 1 bytes 28 OUT pkts 0 bytes 0 + REV: IN pkts 0 bytes 0 OUT pkts 0 bytes 0 + tag 0 pass 0x502 = pass in quick keep state + interfaces: in X[nf0],X[] out X[],X[] + Sync status: not synchronized +4:udp src:192.168.6.1,32885 dst:192.168.7.1,111 24 + FWD: IN pkts 1 bytes 84 OUT pkts 1 bytes 84 + REV: IN pkts 1 bytes 56 OUT pkts 1 bytes 56 + tag 0 pass 0x2008502 = pass in quick keep state + interfaces: in X[nf0],X[qfe0] out X[qfe0],X[nf0] + Sync status: not synchronized +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +0 pass in quick on nf0 proto tcp from any to any port = 111 flags S/FSRPAU keep state +1 pass in quick on nf0 proto udp from any to any port = 111 keep state +0 block return-rst in log quick on nf0 proto tcp from any to any +0 block in log quick on nf0 inet from 192.168.7.0/24 to any +0 block return-rst in log quick on qfe0 proto tcp from any to any +0 block in log quick on qfe0 inet from 192.168.6.0/24 to any +Rules configured (set 0, out) +0 block out log quick on qfe0 inet from 192.168.7.0/24 to any +0 block out log quick on nf0 inet from 192.168.6.0/24 to any +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni7 b/contrib/netbsd-tests/ipf/expected/ni7 new file mode 100644 index 0000000..38c39ab --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni7 @@ -0,0 +1,5 @@ +4500 0028 4706 4000 0111 1eac 0404 0404 0606 0606 afc9 829e 0014 6308 0402 0000 3be5 468d 000a cfc3 + +4500 0038 0000 0000 ff01 afb9 0202 0202 0404 0404 0b00 f91c 0000 0000 4500 0028 4706 4000 0111 26b4 0404 0404 0202 0202 afc9 829e 0014 c966 + +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni8 b/contrib/netbsd-tests/ipf/expected/ni8 new file mode 100644 index 0000000..e0d5182 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni8 @@ -0,0 +1,9 @@ +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +4500 0038 0000 0000 ff01 a7b9 0a02 0202 0404 0404 0303 a7fc 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 + +4500 0058 0001 0000 ff01 a798 0a02 0202 0404 0404 0303 1137 0000 0000 4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +4500 0038 0002 0000 ff01 abb3 0303 0303 0505 0505 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 + +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/ni9 b/contrib/netbsd-tests/ipf/expected/ni9 new file mode 100644 index 0000000..1eb6fbc --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/ni9 @@ -0,0 +1,9 @@ +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9c40 0000 0001 0000 0000 a002 16d0 3ef4 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +4500 0038 0000 0000 ff01 adb7 0303 0303 0404 0404 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 + +4500 0058 0001 0000 ff01 ad96 0303 0303 0404 0404 0303 0735 0000 0000 4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +4500 0038 0002 0000 ff01 abb3 0303 0303 0505 0505 0303 0fa3 0000 0000 4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 + +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/p1 b/contrib/netbsd-tests/ipf/expected/p1 new file mode 100644 index 0000000..58dc681 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/p1 @@ -0,0 +1,30 @@ +nomatch +pass +nomatch +nomatch +nomatch +pass +nomatch +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +table role=ipf type=tree number=100 + { 1.1.1.1/32; ! 2.2.0.0/16; 2.2.2.0/24; ef00::5/128; }; +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +2 pass in from pool/100 to any +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/p10 b/contrib/netbsd-tests/ipf/expected/p10 new file mode 100644 index 0000000..9f09502 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/p10 @@ -0,0 +1,40 @@ +< bge0 ip #0 40(20) 6 5.5.5.5,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.5.6,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.5.7,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.5.8,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.5.9,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.6.5,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.6.6,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.6.7,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.8,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.9,10000 > 1.1.1.9,80 +List of active MAP/Redirect filters: +rewrite in on bge0 proto tcp from 0/0 to 0/0 port = 80 -> src 0/0 dst dstlist/servers; + +List of active sessions: +RWR-RDR 5.5.6.9 10000 9.9.9.9 80 <- -> 5.5.6.9 10000 1.1.1.9 80 +RWR-RDR 5.5.6.8 10000 9.9.9.9 80 <- -> 5.5.6.8 10000 1.1.1.5 80 +RWR-RDR 5.5.6.7 10000 9.9.9.9 80 <- -> 5.5.6.7 10000 1.1.1.5 80 +RWR-RDR 5.5.6.6 10000 9.9.9.9 80 <- -> 5.5.6.6 10000 1.1.1.9 80 +RWR-RDR 5.5.6.5 10000 9.9.9.9 80 <- -> 5.5.6.5 10000 1.1.1.4 80 +RWR-RDR 5.5.5.9 10000 9.9.9.9 80 <- -> 5.5.5.9 10000 1.1.1.4 80 +RWR-RDR 5.5.5.8 10000 9.9.9.9 80 <- -> 5.5.5.8 10000 1.1.1.9 80 +RWR-RDR 5.5.5.7 10000 9.9.9.9 80 <- -> 5.5.5.7 10000 1.1.1.2 80 +RWR-RDR 5.5.5.6 10000 9.9.9.9 80 <- -> 5.5.5.6 10000 1.1.1.9 80 +RWR-RDR 5.5.5.5 10000 9.9.9.9 80 <- -> 5.5.5.5 10000 1.1.1.2 80 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/p11 b/contrib/netbsd-tests/ipf/expected/p11 new file mode 100644 index 0000000..e907fbb --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/p11 @@ -0,0 +1,40 @@ +< bge0 ip #0 40(20) 6 5.5.5.5,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.6,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.7,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.8,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.9,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.5,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.6,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.7,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.8,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.9,10000 > 1.1.1.5,80 +List of active MAP/Redirect filters: +rewrite in on bge0 proto tcp from 0/0 to 0/0 port = 80 -> src 0/0 dst dstlist/servers; + +List of active sessions: +RWR-RDR 5.5.6.9 10000 9.9.9.9 80 <- -> 5.5.6.9 10000 1.1.1.5 80 +RWR-RDR 5.5.6.8 10000 9.9.9.9 80 <- -> 5.5.6.8 10000 1.1.1.5 80 +RWR-RDR 5.5.6.7 10000 9.9.9.9 80 <- -> 5.5.6.7 10000 1.1.1.5 80 +RWR-RDR 5.5.6.6 10000 9.9.9.9 80 <- -> 5.5.6.6 10000 1.1.1.5 80 +RWR-RDR 5.5.6.5 10000 9.9.9.9 80 <- -> 5.5.6.5 10000 1.1.1.5 80 +RWR-RDR 5.5.5.9 10000 9.9.9.9 80 <- -> 5.5.5.9 10000 1.1.1.5 80 +RWR-RDR 5.5.5.8 10000 9.9.9.9 80 <- -> 5.5.5.8 10000 1.1.1.5 80 +RWR-RDR 5.5.5.7 10000 9.9.9.9 80 <- -> 5.5.5.7 10000 1.1.1.5 80 +RWR-RDR 5.5.5.6 10000 9.9.9.9 80 <- -> 5.5.5.6 10000 1.1.1.5 80 +RWR-RDR 5.5.5.5 10000 9.9.9.9 80 <- -> 5.5.5.5 10000 1.1.1.5 80 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/p12 b/contrib/netbsd-tests/ipf/expected/p12 new file mode 100644 index 0000000..d097d51 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/p12 @@ -0,0 +1,40 @@ +< bge0 ip #0 40(20) 6 5.5.5.5,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.5.6,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.7,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.5.8,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.5.9,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.6.5,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.6.6,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.6.7,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.6.8,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.6.9,10000 > 1.1.1.5,80 +List of active MAP/Redirect filters: +rewrite in on bge0 proto tcp from 0/0 to 0/0 port = 80 -> src 0/0 dst dstlist/servers; + +List of active sessions: +RWR-RDR 5.5.6.9 10000 9.9.9.9 80 <- -> 5.5.6.9 10000 1.1.1.5 80 +RWR-RDR 5.5.6.8 10000 9.9.9.9 80 <- -> 5.5.6.8 10000 1.1.1.9 80 +RWR-RDR 5.5.6.7 10000 9.9.9.9 80 <- -> 5.5.6.7 10000 1.1.1.9 80 +RWR-RDR 5.5.6.6 10000 9.9.9.9 80 <- -> 5.5.6.6 10000 1.1.1.4 80 +RWR-RDR 5.5.6.5 10000 9.9.9.9 80 <- -> 5.5.6.5 10000 1.1.1.4 80 +RWR-RDR 5.5.5.9 10000 9.9.9.9 80 <- -> 5.5.5.9 10000 1.1.1.9 80 +RWR-RDR 5.5.5.8 10000 9.9.9.9 80 <- -> 5.5.5.8 10000 1.1.1.4 80 +RWR-RDR 5.5.5.7 10000 9.9.9.9 80 <- -> 5.5.5.7 10000 1.1.1.4 80 +RWR-RDR 5.5.5.6 10000 9.9.9.9 80 <- -> 5.5.5.6 10000 1.1.1.5 80 +RWR-RDR 5.5.5.5 10000 9.9.9.9 80 <- -> 5.5.5.5 10000 1.1.1.2 80 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/p13 b/contrib/netbsd-tests/ipf/expected/p13 new file mode 100644 index 0000000..aa529ea --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/p13 @@ -0,0 +1,30 @@ +nomatch +pass +nomatch +nomatch +nomatch +pass +nomatch +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +table role=all type=tree number=100 + { 1.1.1.1/32; ! 2.2.0.0/16; 2.2.2.0/24; ef00::5/128; }; +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +2 pass in from pool/100 to any +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/p2 b/contrib/netbsd-tests/ipf/expected/p2 new file mode 100644 index 0000000..5388742 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/p2 @@ -0,0 +1,35 @@ +block +nomatch +pass +nomatch +nomatch +nomatch +nomatch +pass +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +# 'anonymous' table refs 2 +table role=ipf type=hash number=2147483650 size=3 + { 127.0.0.1/32; 4.4.0.0/16; }; +# 'anonymous' table refs 2 +table role=ipf type=hash number=2147483649 size=3 + { 127.0.0.1/32; 4.4.0.0/16; }; +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +1 block in from hash/2147483650 to any +Rules configured (set 0, out) +2 pass out from hash/2147483649 to any +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/p3 b/contrib/netbsd-tests/ipf/expected/p3 new file mode 100644 index 0000000..c1e0343 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/p3 @@ -0,0 +1,45 @@ +pass +nomatch +nomatch +nomatch +nomatch +pass +block +nomatch +nomatch +pass +nomatch +block +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +group-map out role=ipf number=2010 size=5 + { 2.2.2.2/32, group=2020; 4.4.0.0/16, group=2020; 5.0.0.0/8, group=2040; }; +group-map in role=ipf number=1010 size=3 + { 1.1.1.1/32, group=1020; 3.3.0.0/16, group=1030; }; +List of groups configured (set 0) +Dev.0. Group 1020 Ref 2 Flags 0x8000 +2 pass in all group 1020 +Dev.0. Group 1030 Ref 2 Flags 0x8000 +2 block in all group 1030 +Dev.0. Group 2020 Ref 3 Flags 0x4000 +4 pass out all group 2020 +Dev.0. Group 2040 Ref 2 Flags 0x4000 +2 block out all group 2040 +List of groups configured (set 1) +Rules configured (set 0, in) +6 call now srcgrpmap/1010 in all +Rules configured (set 0, out) +6 call now dstgrpmap/2010 out all +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/p4 b/contrib/netbsd-tests/ipf/expected/p4 new file mode 100644 index 0000000..e7aa73f --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/p4 @@ -0,0 +1,38 @@ +< anon0 ip #0 20(20) 0 127.0.0.1 > 127.0.0.1 +< anon0 ip #0 20(20) 0 1.1.1.1 > 1.2.1.1 +> anon0 ip #0 20(20) 0 127.0.0.1 > 127.0.0.1 +> anon0 ip #0 20(20) 0 1.2.3.4 > 1.2.1.1 +< anon0 ip #0 20(20) 0 2.3.0.1 > 1.2.1.1 +< anon0 ip #0 20(20) 0 2.2.2.1 > 1.2.1.1 +< anon0 ip #0 20(20) 0 2.2.0.1 > 1.2.1.1 +15 +> anon0 ip #0 20(20) 0 1.2.3.4 > 1.2.1.2 +> anon0 ip #0 20(20) 0 2.2.0.1 > 1.2.1.1 +> anon0 ip #0 20(20) 0 2.2.0.1 > 1.2.1.3 +> anon0 ip #0 20(20) 0 4.4.1.1 > 1.2.1.1 +List of active MAP/Redirect filters: +map * from pool/100 to 0/0 -> 1.2.3.4/32 + +List of active sessions: +MAP 2.2.2.1 <- -> 1.2.3.4 [1.2.1.2] +MAP 1.1.1.1 <- -> 1.2.3.4 [1.2.1.1] + +Hostmap table: +2.2.2.1,1.2.1.2 -> 1.2.3.4,0.0.0.0 (use = 1) +1.1.1.1,1.2.1.1 -> 1.2.3.4,0.0.0.0 (use = 1) +List of active state sessions: +List of configured pools +table role=nat type=tree number=100 + { 1.1.1.1/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/p5 b/contrib/netbsd-tests/ipf/expected/p5 new file mode 100644 index 0000000..b56c3bc --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/p5 @@ -0,0 +1,21 @@ +nomatch +pass +nomatch +nomatch +nomatch +pass +nomatch +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +table role=ipf type=tree name=letters + { 1.1.1.1/32; ! 2.2.0.0/16; 2.2.2.0/24; }; +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/p6 b/contrib/netbsd-tests/ipf/expected/p6 new file mode 100644 index 0000000..413f94b --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/p6 @@ -0,0 +1,24 @@ +block +nomatch +List of active MAP/Redirect filters: + +List of active sessions: + +Hostmap table: +List of active state sessions: +List of configured pools +table role=ipf type=tree name=microsoft + { 131.107.0.0/16; 192.92.90.0/24; 198.105.232.0/22; 204.231.58.0/24; 204.140.77.0/24; 204.140.80.0/22; 199.60.28.0/24; 199.103.90.0/23; 199.103.122.0/24; 204.79.101.0/24; 192.237.67.0/24; 198.137.97.0/24; 204.79.135.0/24; 204.79.179.0/24; 204.79.180.0/23; 204.79.188.0/24; 204.79.7.0/24; 204.79.27.0/24; 198.180.74.0/23; 204.231.236.0/24; 205.163.63.0/24; 205.163.62.0/24; 205.163.144.0/20; 205.248.50.0/23; 205.248.72.0/24; 205.248.212.0/22; 205.248.228.0/24; 205.248.235.0/24; 204.231.76.0/24; 204.231.192.0/24; 207.78.80.0/24; 207.78.81.0/24; 207.78.82.0/24; 207.117.3.0/24; 207.18.117.0/24; 208.139.27.0/24; 209.28.213.0/24; 207.209.68.0/24; 204.95.96.0/20; 207.158.93.192/27; 207.240.123.192/27; 208.26.205.0/24; 192.197.157.0/24; 204.133.231.0/24; 216.72.96.0/22; 207.229.166.152/29; 204.95.149.0/24; 209.192.213.72/29; 206.73.203.0/24; 206.73.118.0/24; 208.45.54.16/29; 208.45.54.8/29; 206.73.31.0/24; 63.161.50.128/25; 63.161.50.0/25; 207.240.8.224/28; 208.45.89.248/29; 206.182.69.0/24; 206.182.240.0/24; 206.182.241.0/24; 206.73.67.0/24; 206.182.251.0/24; 206.182.247.0/24; 206.182.236.0/24; 63.236.198.64/29; 63.236.198.152/29; 165.121.253.232/29; 63.236.170.64/29; 63.236.186.64/29; 63.236.187.104/29; 63.236.187.128/29; 63.236.187.160/29; 199.2.137.0/24; 216.222.104.224/28; 63.151.87.64/29; 64.77.82.96/29; 64.77.93.80/28; 65.52.0.0/14; 207.46.0.0/16; 204.182.144.0/20; 206.107.34.0/24; 205.240.158.0/23; 204.79.252.0/24; 64.200.211.16/28; 12.178.163.0/27; 69.44.126.80/28; 63.173.42.128/25; 12.28.108.0/25; 65.170.29.0/29; 67.132.133.96/29; 8.6.176.0/24; 63.148.123.240/29; 64.41.193.0/24; 64.85.70.32/28; 64.85.81.96/29; 64.85.81.104/29; 216.32.168.224/27; 206.79.74.32/28; 216.32.175.224/27; 216.32.180.0/22; 216.33.229.224/27; 216.33.236.0/22; 216.33.240.0/22; 216.32.240.0/22; 216.34.51.0/24; 209.1.112.0/24; 209.1.113.0/24; 209.1.15.0/24; 216.34.53.176/28; 216.35.8.224/28; 209.185.128.0/22; 65.114.175.128/27; 64.15.229.96/27; 64.15.177.0/24; 64.15.170.192/29; 209.143.238.0/24; 64.15.178.0/24; 66.35.209.120/29; 66.35.211.128/26; 66.35.208.48/28; 216.33.148.0/22; 216.35.66.88/29; 12.230.32.160/29; 12.53.124.0/27; 12.232.18.96/27; 12.190.158.0/24; 12.71.196.32/28; 209.240.192.0/19; 70.37.128.0/23; 70.37.135.0/24; 12.49.87.192/26; 74.93.205.144/29; 74.93.205.152/29; 74.93.206.64/29; 70.89.139.120/29; 206.71.119.0/24; 206.71.117.0/24; 206.71.118.0/24; 209.154.155.112/29; 65.68.62.152/29; 67.39.208.168/29; 65.242.67.0/24; 204.71.191.0/24; 63.194.155.144/29; 66.136.85.192/29; 64.124.184.72/29; 216.200.206.0/24; 63.80.93.0/25; 67.192.225.208/28; 69.74.162.0/24; 65.221.5.0/24; 65.248.85.0/24; 199.243.157.192/27; 199.243.157.112/29; 65.194.210.224/27; 208.194.139.0/24; 208.204.49.128/25; 208.205.26.0/24; 208.217.184.0/22; 208.222.172.0/24; 208.224.200.64/27; 208.229.100.0/23; 208.241.19.0/28; 208.241.19.16/28; 208.241.9.224/28; 208.244.108.0/28; 208.245.16.0/27; 208.249.17.160/28; 63.104.216.0/25; 63.69.245.0/24; 68.90.141.72/29; 63.198.123.160/29; 68.248.48.64/29; 68.248.48.72/29; 99.49.8.248/29; 65.38.172.72/29; 65.38.172.96/28; 75.149.174.16/29; 75.151.100.240/28; 64.81.8.96/27; 67.112.255.144/29; 63.240.201.176/28; 206.16.209.208/28; 63.240.195.208/28; 206.16.204.64/28; 206.16.223.0/24; 63.240.216.0/22; 63.240.220.0/22; 206.16.246.24/29; 63.240.195.192/28; 206.16.224.160/27; 67.192.39.48/28; 72.32.240.160/28; 72.32.201.152/29; 67.39.81.152/29; 69.20.127.32/29; 216.52.28.0/24; 70.42.230.0/23; 63.251.97.0/24; 67.120.132.128/29; 67.120.132.152/29; 67.120.132.192/28; }; +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +1 block in from pool/microsoft to any +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/p7 b/contrib/netbsd-tests/ipf/expected/p7 new file mode 100644 index 0000000..89bfc11 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/p7 @@ -0,0 +1,40 @@ +< bge0 ip #0 40(20) 6 5.5.5.5,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.5.6,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.5.7,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.8,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.5.9,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.6.5,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.6.6,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.7,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.6.8,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.6.9,10000 > 1.1.1.4,80 +List of active MAP/Redirect filters: +rewrite in on bge0 proto tcp from 0/0 to 0/0 port = 80 -> src 0/0 dst dstlist/servers; + +List of active sessions: +RWR-RDR 5.5.6.9 10000 9.9.9.9 80 <- -> 5.5.6.9 10000 1.1.1.4 80 +RWR-RDR 5.5.6.8 10000 9.9.9.9 80 <- -> 5.5.6.8 10000 1.1.1.2 80 +RWR-RDR 5.5.6.7 10000 9.9.9.9 80 <- -> 5.5.6.7 10000 1.1.1.9 80 +RWR-RDR 5.5.6.6 10000 9.9.9.9 80 <- -> 5.5.6.6 10000 1.1.1.5 80 +RWR-RDR 5.5.6.5 10000 9.9.9.9 80 <- -> 5.5.6.5 10000 1.1.1.4 80 +RWR-RDR 5.5.5.9 10000 9.9.9.9 80 <- -> 5.5.5.9 10000 1.1.1.2 80 +RWR-RDR 5.5.5.8 10000 9.9.9.9 80 <- -> 5.5.5.8 10000 1.1.1.9 80 +RWR-RDR 5.5.5.7 10000 9.9.9.9 80 <- -> 5.5.5.7 10000 1.1.1.5 80 +RWR-RDR 5.5.5.6 10000 9.9.9.9 80 <- -> 5.5.5.6 10000 1.1.1.4 80 +RWR-RDR 5.5.5.5 10000 9.9.9.9 80 <- -> 5.5.5.5 10000 1.1.1.2 80 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/expected/p9 b/contrib/netbsd-tests/ipf/expected/p9 new file mode 100644 index 0000000..89bfc11 --- /dev/null +++ b/contrib/netbsd-tests/ipf/expected/p9 @@ -0,0 +1,40 @@ +< bge0 ip #0 40(20) 6 5.5.5.5,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.5.6,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.5.7,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.5.8,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.5.9,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.6.5,10000 > 1.1.1.4,80 +< bge0 ip #0 40(20) 6 5.5.6.6,10000 > 1.1.1.5,80 +< bge0 ip #0 40(20) 6 5.5.6.7,10000 > 1.1.1.9,80 +< bge0 ip #0 40(20) 6 5.5.6.8,10000 > 1.1.1.2,80 +< bge0 ip #0 40(20) 6 5.5.6.9,10000 > 1.1.1.4,80 +List of active MAP/Redirect filters: +rewrite in on bge0 proto tcp from 0/0 to 0/0 port = 80 -> src 0/0 dst dstlist/servers; + +List of active sessions: +RWR-RDR 5.5.6.9 10000 9.9.9.9 80 <- -> 5.5.6.9 10000 1.1.1.4 80 +RWR-RDR 5.5.6.8 10000 9.9.9.9 80 <- -> 5.5.6.8 10000 1.1.1.2 80 +RWR-RDR 5.5.6.7 10000 9.9.9.9 80 <- -> 5.5.6.7 10000 1.1.1.9 80 +RWR-RDR 5.5.6.6 10000 9.9.9.9 80 <- -> 5.5.6.6 10000 1.1.1.5 80 +RWR-RDR 5.5.6.5 10000 9.9.9.9 80 <- -> 5.5.6.5 10000 1.1.1.4 80 +RWR-RDR 5.5.5.9 10000 9.9.9.9 80 <- -> 5.5.5.9 10000 1.1.1.2 80 +RWR-RDR 5.5.5.8 10000 9.9.9.9 80 <- -> 5.5.5.8 10000 1.1.1.9 80 +RWR-RDR 5.5.5.7 10000 9.9.9.9 80 <- -> 5.5.5.7 10000 1.1.1.5 80 +RWR-RDR 5.5.5.6 10000 9.9.9.9 80 <- -> 5.5.5.6 10000 1.1.1.4 80 +RWR-RDR 5.5.5.5 10000 9.9.9.9 80 <- -> 5.5.5.5 10000 1.1.1.2 80 + +Hostmap table: +List of active state sessions: +List of configured pools +List of configured hash tables +List of groups configured (set 0) +List of groups configured (set 1) +Rules configured (set 0, in) +Rules configured (set 0, out) +Rules configured (set 1, in) +Rules configured (set 1, out) +Accounting rules configured (set 0, in) +Accounting rules configured (set 0, out) +Accounting rules configured (set 1, in) +Accounting rules configured (set 1, out) +------------------------------- diff --git a/contrib/netbsd-tests/ipf/h_common.sh b/contrib/netbsd-tests/ipf/h_common.sh new file mode 100755 index 0000000..8f11c2f --- /dev/null +++ b/contrib/netbsd-tests/ipf/h_common.sh @@ -0,0 +1,100 @@ +# $NetBSD: h_common.sh,v 1.8 2013/05/16 07:20:29 martin Exp $ +# +# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# +# (C)opyright 1993-1996 by Darren Reed. +# +# See the IPFILTER.LICENCE file for details on licencing. +# + +h_copydata() +{ + test -f $(atf_get_srcdir)/input/$1 && \ + cp $(atf_get_srcdir)/input/$1 in + test -f $(atf_get_srcdir)/regress/$1 && \ + cp $(atf_get_srcdir)/regress/$1 reg + test -f $(atf_get_srcdir)/expected/$1 && \ + cp $(atf_get_srcdir)/expected/$1 exp +} + +test_case() +{ + local name="${1}"; shift + local check_function="${1}"; shift + + atf_test_case "${name}" + eval "${name}_body() { \ + ${check_function} '${name}' " "${@}" "; \ + }" +} + +broken_test_case() +{ + local name="${1}"; shift + local check_function="${1}"; shift + + atf_test_case "${name}" + eval "${name}_body() { \ + atf_skip 'This test case is probably broken'; \ + ${check_function} '${name}' " "${@}" "; \ + }" +} + +failing_test_case() +{ + local name="${1}"; shift + local check_function="${1}"; shift + local reason="${1}"; shift + + atf_test_case "${name}" + eval "${name}_body() { \ + atf_expect_fail '${reason}'; \ + ${check_function} '${name}' " "${@}" "; \ + }" +} + +failing_test_case_be() +{ + # this test fails on some architectures - not fully analyzed, assume + # an endianess bug + local name="${1}"; shift + local check_function="${1}"; shift + local reason="${1}"; shift + + atf_test_case "${name}" + + if [ `sysctl -n hw.byteorder` = 4321 ]; then + eval "${name}_body() { \ + atf_expect_fail '${reason}'; \ + ${check_function} '${name}' " "${@}" "; \ + }" + else + eval "${name}_body() { \ + ${check_function} '${name}' " "${@}" "; \ + }" + fi +} + diff --git a/contrib/netbsd-tests/ipf/input/f1 b/contrib/netbsd-tests/ipf/input/f1 new file mode 100644 index 0000000..7c3ae8a --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f1 @@ -0,0 +1,4 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.2.1.1 +out 127.0.0.1 127.0.0.1 +out 1.1.1.1 1.2.1.1 diff --git a/contrib/netbsd-tests/ipf/input/f10 b/contrib/netbsd-tests/ipf/input/f10 new file mode 100644 index 0000000..254cee7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f10 @@ -0,0 +1,6 @@ +in 1.1.1.1 2.1.1.1 opt lsrr +in 1.1.1.1 2.1.1.1 +in 1.1.1.1 2.1.1.1 opt ts +in 1.1.1.1 2.1.1.1 opt sec-class=topsecret +in 1.1.1.1 2.1.1.1 opt ssrr,sec-class=topsecret +in 1.1.1.1 2.1.1.1 opt sec diff --git a/contrib/netbsd-tests/ipf/input/f11 b/contrib/netbsd-tests/ipf/input/f11 new file mode 100644 index 0000000..d558150 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f11 @@ -0,0 +1,16 @@ +in on e0 tcp 1.1.1.1,1 2.1.2.2,23 S seq=1 ack=0 +in on e0 tcp 1.1.1.1,1 2.1.2.2,24 SA seq=1 ack=1 +in on e1 tcp 2.1.2.2,23 1.1.1.1,2 SA seq=101 ack=2 +in on e1 tcp 2.1.2.2,23 1.1.1.1,1 SA seq=101 ack=2 +in on e0 tcp 1.1.1.1,1 2.1.2.2,23 A seq=2 ack=102 +in on e0 tcp 1.1.1.1,1 2.1.2.2,25 A seq=2 ack=102 +in on e1 tcp 2.1.2.2,23 1.1.1.1,1 A seq=102 ack=2 +in on e1 tcp 2.1.2.2,25 1.1.1.1,1 A seq=102 ack=2 +in on e0 tcp 1.1.1.1,1 2.1.2.2,23 FA seq=2 ack=102 +in on e0 tcp 1.1.1.1,1 2.1.2.2,23 A seq=2 ack=102 +in on e0 tcp 1.1.1.1,2 2.1.2.2,23 A seq=2 ack=102 +in on e1 udp 1.1.1.1,1 4.4.4.4,53 +in on e1 udp 2.2.2.2,2 4.4.4.4,53 +in on e0 udp 4.4.4.4,53 1.1.1.1,1 +in on e0 udp 4.4.4.4,1023 1.1.1.1,2049 +in on e0 udp 4.4.4.4,2049 1.1.1.1,1023 diff --git a/contrib/netbsd-tests/ipf/input/f12 b/contrib/netbsd-tests/ipf/input/f12 new file mode 100644 index 0000000..52edde1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f12 @@ -0,0 +1,44 @@ +# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF SYN +[] +4500 0028 0000 4000 3f06 36cd 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 5002 2000 86c5 0000 + +# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF ACK +[] +4500 0028 0000 4000 3f06 36cd 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 + +# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF MF FO=0 ACK +[] +4500 0028 0000 6000 3f06 16cd 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 + +# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF FO=0 +[] +4500 001c 0000 6000 3f06 16d9 0101 0101 0201 0101 +0401 0019 0000 0000 + +# 1.1.1.1 -> 2.1.1.1 TTL=63 TCP DF FO=1 ACK +[] +4500 001c 0000 6001 3f06 16d8 0101 0101 0201 0101 +0000 0000 5010 2000 + +# 1.1.1.1 -> 2.1.1.1 TTL=63 UDP DF MF FO=0 +[] +4500 0014 0000 6000 3f11 16d6 0101 0101 0201 0101 + +# 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0 +[] +4500 0018 0000 2000 3f11 56d2 0101 0101 0201 0101 +0035 0035 + +# 1.1.1.1,1 -> 2.1.1.1,1 TTL=63 UDP MF FO=0 +[] +4500 001c 0000 2000 3f11 56ce 0101 0101 0201 0101 +0001 0001 0004 fadc + +# 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0 +[] +4500 001c 0000 2000 3f11 56ce 0101 0101 0201 0101 +0035 0035 0004 fa74 + diff --git a/contrib/netbsd-tests/ipf/input/f13 b/contrib/netbsd-tests/ipf/input/f13 new file mode 100644 index 0000000..ccd370a --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f13 @@ -0,0 +1,95 @@ +# This checksum is deliberately incorrect. +# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF,FO=0 SYN +[in] +4500 0028 0001 4000 3f06 36cc 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 50 02 2000 86bb 0000 + +# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP MF ACK +[in] +4500 0024 0002 2000 3f06 56cf 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 5010 2000 + +# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP FO=2 ACK +[in] +4500 002c 0002 0002 3f06 76c5 0101 0101 0201 0101 +0000 0000 0001 0203 0405 0607 0809 0a0b 0c0d 0e0f 1011 1213 + +# 1.1.1.1,1024 -> 2.1.1.1,25 TTL=63 TCP DF MF FO=0 SYN +[in] +4500 0028 0003 6000 3f06 16ca 0101 0101 0201 0101 +0400 0019 7000 0000 0000 0000 5002 2000 16c6 0000 + +# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF FO=0 +[in] +4500 001c 0004 6000 3f06 16d5 0101 0101 0201 0101 +0401 0019 0000 0000 + +# 1.1.1.1 -> 2.1.1.1 TTL=63 TCP DF FO=1 SYN +[in] +4500 001c 0005 6001 3f06 16d3 0101 0101 0201 0101 +0000 0000 5010 2000 + +# 1.1.1.1 -> 2.1.1.1 TTL=63 UDP DF MF FO=0 +[in] +4500 0014 0006 6000 3f11 16d0 0101 0101 0201 0101 + +# 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0 +[in] +4500 0018 0007 2000 3f11 56cb 0101 0101 0201 0101 +0035 0035 + +# 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0 +[in] +4500 001c 0008 2000 3f11 56c6 0101 0101 0201 0101 +0035 0035 0004 0000 + +# 1.1.1.1,53 -> 2.1.1.1,54 TTL=63 UDP MF FO=0 (short) +[in] +4500 0018 0008 2000 3f11 56ca 0101 0101 0201 0101 +0035 0036 + +# 1.1.1.1,21 -> 2.1.1.1,54 TTL=63 UDP MF FO=0 +[in] +4500 001c 0008 2000 3f11 56c6 0101 0101 0201 0101 +0015 0036 0004 0000 + +# 1.1.1.1,21 -> 2.1.1.1,54 TTL=63 TCP MF FO=0 +[in] +4500 001c 0008 2000 3f06 56d1 0101 0101 0201 0101 +0015 0036 0000 0000 0000 0000 50 02 2000 0000 0000 + +# 1.1.1.1 -> 2.1.1.1 TTL=63 UDP FO=3 +[in] +4500 001c 0008 0003 3f11 76c3 0101 0101 0201 0101 +0000 0000 0000 0000 + +# 1.1.1.1 -> 2.1.1.1 TTL=63 UDP FO=1 +[in] +4500 001c 0008 0001 3f11 76c5 0101 0101 0201 0101 +0000 0000 0000 0000 + +# 2.1.1.1,53 -> 1.1.1.1,53 TTL=63 UDP +[out] +4500 001c 0008 0000 3f11 76c6 0201 0101 0101 0101 +0035 0035 0004 0000 + +# 2.1.1.1,25 -> 1.1.1.1,1014 TTL=63 TCP DF SYN-ACK +[out] +4500 0028 0003 4000 3f06 36ca 0201 0101 0101 0101 +0019 0400 0000 0001 7000 0001 5012 2000 16b4 0000 + +# 1.1.1.1,1024 -> 2.1.1.1,25 TTL=63 TCP DF ACK (OOW) +[in] +4500 0028 0003 4000 3f06 36ca 0101 0101 0201 0101 +0400 0019 0040 0000 0000 0000 5010 2000 8678 0000 + +# 1.1.1.1,1024 -> 2.1.1.1,25 TTL=63 TCP DF ACK (out-of-order) +[in] +4500 0028 0003 4000 3f06 36ca 0101 0101 0201 0101 +0400 0019 7000 0004 0000 0002 5010 2000 16b2 0000 + +# 1.1.1.1,1024 -> 2.1.1.1,25 TTL=63 TCP DF ACK +[in] +4500 0028 0003 4000 3f06 36ca 0101 0101 0201 0101 +0400 0019 7000 0001 0000 0002 5010 2000 16b5 0000 + diff --git a/contrib/netbsd-tests/ipf/input/f14 b/contrib/netbsd-tests/ipf/input/f14 new file mode 100644 index 0000000..16a806f --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f14 @@ -0,0 +1,5 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.2.1.1 +in 1.1.1.2 1.2.1.1 +in 1.1.2.2 1.2.1.1 +in 1.2.2.2 1.2.1.1 diff --git a/contrib/netbsd-tests/ipf/input/f15 b/contrib/netbsd-tests/ipf/input/f15 new file mode 100644 index 0000000..db547cb --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f15 @@ -0,0 +1,8 @@ +in on hme0 tcp 10.1.2.3,1200 195.134.65.10,100 S +in on hme0 tcp 10.1.2.3,1200 195.134.65.10,22 S +in on hme0 udp 10.1.2.3,1200 195.134.65.10,100 +in on hme0 udp 10.1.2.3,53 195.134.65.10,53 +in on hme0 10.1.2.3 195.134.65.10 +in on hme1 195.134.65.10 10.1.2.3 +in on hme1 udp 195.134.65.10,53 10.1.2.3,53 +in on hme1 tcp 195.134.65.10,22 10.1.2.3,1200 SA diff --git a/contrib/netbsd-tests/ipf/input/f16 b/contrib/netbsd-tests/ipf/input/f16 new file mode 100644 index 0000000..a17f41f --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f16 @@ -0,0 +1,8 @@ +in 2.2.2.2 5.5.5.5 +in 2.2.2.2 1.1.1.1 +in udp 4.4.4.4,110 1.1.1.1,53 +in udp 4.4.4.9,101 1.1.1.3,35 +in udp 4.4.4.8,111 1.1.1.2,53 +in tcp 4.4.4.7,220 1.1.1.1,23 +in tcp 4.4.4.6,202 1.1.1.3,22 +in tcp 4.4.4.5,222 1.1.1.2,52 diff --git a/contrib/netbsd-tests/ipf/input/f17 b/contrib/netbsd-tests/ipf/input/f17 new file mode 100644 index 0000000..a0d44d7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f17 @@ -0,0 +1,39 @@ +# TCP 1.1.1.1,54076 -> 2.2.2.2,27 SYN +[out,ppp0] +4500 003c 8262 0000 4006 f254 0101 0101 +0202 0202 d33c 0019 bfd0 8989 0000 0000 +a002 4000 cfcd 0000 0204 05b4 0103 0300 +0101 080a 008e 17f7 0000 0000 + +# TCP 2.2.2.2,27 -> 1.1.1.1,54076 ACK +[in,ppp0] +4500 003c 8262 0000 1106 2155 0202 0202 +0101 0101 0019 d33c 4020 3436 bfdf cbc9 +5010 4000 694a 0000 0204 0584 0103 0300 +0101 080a 008e 17f7 0000 0000 + +# TCP 1.1.1.1,54076 -> 2.2.2.2,27 SYN +[out,ppp0] +4500 003c 8265 0000 4006 f251 0101 0101 +0202 0202 d33c 0019 bfd0 8989 0000 0000 +a002 4000 cfc2 0000 0204 05b4 0103 0300 +0101 080a 008e 1802 0000 0000 + +# TCP 2.2.2.2,27 -> 1.1.1.1,54076 SYN-ACK +[in,ppp0] +4500 002c 7442 4000 2906 d784 0202 0202 +0101 0101 0019 d33c ed67 4d4e bfd0 898a +6012 2118 19c2 0000 0204 0584 + +# TCP 1.1.1.1,54076 -> 2.2.2.2,27 ACK +[out,ppp0] +4500 0028 8262 0000 4006 f268 0101 0101 +0202 0202 d33c 0019 bfd0 898a ed67 4d4e +5010 4000 1268 0000 + +# TCP 2.2.2.2,27 -> 1.1.1.1,54076 ACK+data +[in,ppp0] +4500 002a 7442 4000 2906 d786 0202 0202 +0101 0101 0019 d33c ed67 4d4e bfd0 8990 +5012 2118 2f43 0000 0203 + diff --git a/contrib/netbsd-tests/ipf/input/f18 b/contrib/netbsd-tests/ipf/input/f18 new file mode 100644 index 0000000..9ecbb7f --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f18 @@ -0,0 +1,4 @@ +in on le1 1.1.1.1 3.3.3.3 +in on le1 1.1.1.1 5.5.5.5 +out on le1 2.2.2.2 4.4.4.4 +out on le1 2.2.2.2 6.6.6.6 diff --git a/contrib/netbsd-tests/ipf/input/f19 b/contrib/netbsd-tests/ipf/input/f19 new file mode 100644 index 0000000..6cab988 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f19 @@ -0,0 +1,4 @@ +in tcp 127.0.0.1,1 127.0.0.1,21 S +in tcp 127.0.0.1,2 127.0.0.1,21 S +in tcp 127.0.0.1,3 127.0.0.1,21 S +in tcp 127.0.0.1,4 127.0.0.1,21 S diff --git a/contrib/netbsd-tests/ipf/input/f2 b/contrib/netbsd-tests/ipf/input/f2 new file mode 100644 index 0000000..f4e9d23 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f2 @@ -0,0 +1,6 @@ +in tcp 127.0.0.1,1 127.0.0.1,ftp +in tcp 1.1.1.1,1 1.2.1.1,ftp +in udp 127.0.0.1,1 127.0.0.1,21 +in udp 1.1.1.1,1 1.2.1.1,21 +in icmp 127.0.0.1 127.0.0.1 +in icmp 1.1.1.1 1.2.1.1 diff --git a/contrib/netbsd-tests/ipf/input/f20 b/contrib/netbsd-tests/ipf/input/f20 new file mode 100644 index 0000000..605ba7c --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f20 @@ -0,0 +1,2 @@ +out on de0 1.1.1.1 2.2.2.2 +out on ab0 1.1.1.1 2.2.2.2 diff --git a/contrib/netbsd-tests/ipf/input/f21 b/contrib/netbsd-tests/ipf/input/f21 new file mode 100644 index 0000000..1135cbd --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f21 @@ -0,0 +1,31 @@ +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going out) +# IP 4.4.4.4 2.2.2.2 TCP(20480,80) +[out,df0] +4500 003c 4706 4000 ff06 28aa 0404 0404 +0202 0202 5000 0050 0000 0001 0000 0000 +a002 16d0 d8e2 0000 0204 05b4 0402 080a +0047 fbb0 0000 0000 0103 0300 + +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) UNREACH +[in,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 +0404 0404 0303 acab 0000 0000 4500 003c +4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 + +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) REDIRECT +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[in,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 +0404 0404 0501 9a9d 0808 0808 4500 003c +4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 + +# IP 3.3.3.3 -> 5.5.5.5 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) UNREACH +[in,df0] +4500 0038 809a 0000 ff01 2b1b 0303 0303 +0505 0505 0303 acab 0000 0000 4500 003c +4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 + diff --git a/contrib/netbsd-tests/ipf/input/f22 b/contrib/netbsd-tests/ipf/input/f22 new file mode 100644 index 0000000..a5221c1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f22 @@ -0,0 +1,31 @@ +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going out) +# IP 4.4.4.4 2.2.2.2 TCP(20480,80) +[in,df0] +4500 003c 4706 4000 ff06 28aa 0404 0404 +0202 0202 5000 0050 0000 0001 0000 0000 +a002 16d0 d8e2 0000 0204 05b4 0402 080a +0047 fbb0 0000 0000 0103 0300 + +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) UNREACH +[out,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 +0404 0404 0303 acab 0000 0000 4500 003c +4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 + +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) REDIRECT +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[out,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 +0404 0404 0501 9a9d 0808 0808 4500 003c +4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 + +# IP 3.3.3.3 -> 5.5.5.5 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) UNREACH +[out,df0] +4500 0038 809a 0000 ff01 2b1b 0303 0303 +0505 0505 0303 acab 0000 0000 4500 003c +4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 + diff --git a/contrib/netbsd-tests/ipf/input/f24 b/contrib/netbsd-tests/ipf/input/f24 new file mode 100644 index 0000000..030772b --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f24 @@ -0,0 +1,27 @@ +[out,hme0] +4500 003f 6e48 0000 4011 8816 c0a8 0101 +c0a8 01fe eb22 0035 002b d9e6 4a82 0100 +0001 0000 0000 0000 0663 6f6f 6d62 7303 +616e 7503 6564 7502 6175 0000 0100 01 + +[in,hme0] +4500 004c fc96 2000 4011 d9ba c0a8 01fe +c0a8 0101 0035 eb22 00a9 d7b9 4a82 8180 +0001 0001 0003 0003 0663 6f6f 6d62 7303 +616e 7503 6564 7502 6175 0000 0100 01c0 +0c00 0100 0100 0000 3c00 0496 + +[in,hme0] +4500 004c fc96 2007 4011 d9b3 c0a8 01fe +c0a8 0101 cbe7 50c0 1300 0200 0100 0078 +8c00 0603 6e73 31c0 13c0 1300 0200 0100 +0078 8c00 0e02 6e73 0861 6465 6c61 6964 +65c0 17c0 1300 0200 0100 0078 + +[in,hme0] +4500 004d fc96 000c 4011 f9ad c0a8 01fe +c0a8 0101 8c00 0603 756e 61c0 13c0 6b00 +0100 0100 0027 5800 0496 cb16 1cc0 5100 +0100 0100 0018 4700 0481 7f28 03c0 3f00 +0100 0100 0027 5800 0496 cb01 0a + diff --git a/contrib/netbsd-tests/ipf/input/f25 b/contrib/netbsd-tests/ipf/input/f25 new file mode 100644 index 0000000..a4e3139 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f25 @@ -0,0 +1,41 @@ +[in,hme0]+mcast +4500 0081 b02d 0000 0411 53b1 c0a8 01eb +efff fffa 1f48 076c 006d 1bd2 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0a + +[out,hme0] +4500 0108 7aca 0000 4011 79e1 c0a8 01fe +c0a8 01eb 076c 1f48 00f4 5218 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 + +[in,hme0]+mcast +4500 0081 b02d 0000 0411 53b1 c0a8 01eb +efff fffa 1f48 076c 006d 1bd2 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0a + diff --git a/contrib/netbsd-tests/ipf/input/f26 b/contrib/netbsd-tests/ipf/input/f26 new file mode 100644 index 0000000..2151f72 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f26 @@ -0,0 +1,13 @@ +in tcp 1.1.1.1,1001 2.2.2.2,22 S +in tcp 1.1.1.1,1002 2.2.2.2,22 S +in tcp 1.1.1.1,1003 2.2.2.2,22 S +in tcp 1.1.1.1,1004 2.2.2.2,22 S +in tcp 1.1.1.2,1002 2.2.2.2,22 S +in tcp 1.1.1.3,1003 2.2.2.2,22 S +in tcp 1.1.1.4,1004 2.2.2.2,22 S +in tcp 1.1.1.2,1005 2.2.2.2,22 S +in tcp 1.1.1.3,1006 2.2.2.2,22 S +in tcp 1.1.1.4,1007 2.2.2.2,22 S +in tcp 1.1.1.2,1008 2.2.2.2,22 S +in tcp 1.1.1.3,1009 2.2.2.2,22 S +in tcp 1.1.1.4,1010 2.2.2.2,22 S diff --git a/contrib/netbsd-tests/ipf/input/f27 b/contrib/netbsd-tests/ipf/input/f27 new file mode 100644 index 0000000..f01bf7e --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f27 @@ -0,0 +1,84 @@ +[in,hme0] +45000028 0000 0000 FF06 b5ca +01010101 02020202 +03e9 0016 00000000 00000000 5002 0000 +a5de 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5ca +01010101 02020202 +03ea 0016 00000000 00000000 5002 0000 +a5dd 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5ca +01010101 02020202 +03eb 0016 00000000 00000000 5002 0000 +a5dc 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5ca +01010101 02020202 +03ec 0016 00000000 00000000 5002 0000 +a5db 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c9 +01010102 02020202 +03ed 0016 00000000 00000000 5002 0000 +a5d9 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c8 +01010103 02020202 +03ee 0016 00000000 00000000 5002 0000 +a5d7 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c7 +01010104 02020202 +03ef 0016 00000000 00000000 5002 0000 +a5d5 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c9 +01010102 02020202 +03f0 0016 00000000 00000000 5002 0000 +a5d6 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c8 +01010103 02020202 +03f1 0016 00000000 00000000 5002 0000 +a5d4 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c7 +01010104 02020202 +03f2 0016 00000000 00000000 5002 0000 +a5d2 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c9 +01010102 02020202 +03f3 0016 00000000 00000000 5002 0000 +a5d3 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c8 +01010103 02020202 +03f4 0016 00000000 00000000 5002 0000 +a5d1 0000 + +[in,hme0] +45000028 0000 0000 FF06 b5c7 +01010104 02020202 +03f5 0016 00000000 00000000 5002 0000 +a5cf 0000 + +[in,hme0] +6000 0000 0014 06FF +ef00 1001 2002 0001 0000 0000 0000 0070 +2001 1002 3333 0001 0000 0000 0000 0001 +03f6 0016 0000 0000 0000 0000 5002 0000 292a 0000 + diff --git a/contrib/netbsd-tests/ipf/input/f28 b/contrib/netbsd-tests/ipf/input/f28 new file mode 100644 index 0000000..8849c14 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f28 @@ -0,0 +1,7 @@ +in on nic1 4.4.0.1 4.2.0.2 +in on nic2 4.4.1.1 4.2.1.2 +in on nic3 4.4.2.1 4.2.2.2 +in on nic0 4.4.3.1 4.2.3.2 +in on nic0 4.4.1.1 4.2.1.2 +in on nic0 4.4.2.1 4.2.2.2 +in on nic0 4.4.3.1 4.2.3.2 diff --git a/contrib/netbsd-tests/ipf/input/f29 b/contrib/netbsd-tests/ipf/input/f29 new file mode 100644 index 0000000..2e717af --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f29 @@ -0,0 +1,11 @@ +in on nic1 4.4.0.1 4.2.0.2 +in on nic2 4.4.1.1 4.2.1.2 +in on nic3 4.4.2.1 4.2.2.2 +in on nic0 udp 4.4.3.1,1000 4.2.3.2,2000 +in on nic0 udp 4.4.3.1,1000 4.2.3.2,2000 +in on nic0 udp 4.4.1.1,1001 4.2.1.2,2001 +in on nic0 udp 4.4.1.1,1001 4.2.1.2,2001 +in on nic0 udp 4.4.2.1,1002 4.2.2.2,2002 +in on nic0 udp 4.4.2.1,1002 4.2.2.2,2002 +in on nic0 udp 4.4.3.1,1003 4.2.3.2,2003 +in on nic0 udp 4.4.3.1,1003 4.2.3.2,2003 diff --git a/contrib/netbsd-tests/ipf/input/f3 b/contrib/netbsd-tests/ipf/input/f3 new file mode 100644 index 0000000..16a806f --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f3 @@ -0,0 +1,5 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.2.1.1 +in 1.1.1.2 1.2.1.1 +in 1.1.2.2 1.2.1.1 +in 1.2.2.2 1.2.1.1 diff --git a/contrib/netbsd-tests/ipf/input/f30 b/contrib/netbsd-tests/ipf/input/f30 new file mode 100644 index 0000000..ebf7dc0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f30 @@ -0,0 +1,16 @@ +in on hme0 udp 1.1.1.1,53 2.1.1.1,53 opt lsrr +in on hme1 udp 2.1.1.1,53 1.1.1.1,53 opt ts,lsrr +in on hme1 udp 2.1.1.1,53 1.1.1.1,53 opt lsrr +in on hme0 udp 1.1.1.1,53 2.1.1.1,53 +in on hme1 udp 2.1.1.1,53 1.1.1.1,53 +in on hme0 tcp 1.1.1.1,12345 2.1.1.1,22 S opt rr +in on hme0 tcp 1.1.1.1,12345 2.1.1.1,22 S +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12345 SA opt rr,ts +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12345 SA opt rr +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12345 SA +in on hme0 tcp 1.1.1.1,12346 2.1.1.1,22 S opt sec-class=secret +in on hme0 tcp 1.1.1.1,12346 2.1.1.1,22 S +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12346 SA opt sec-class=topsecret +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12346 SA opt ts,sec-class=secret +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12346 SA opt sec-class=secret +in on hme1 tcp 2.1.1.1,22 1.1.1.1,12346 SA diff --git a/contrib/netbsd-tests/ipf/input/f4 b/contrib/netbsd-tests/ipf/input/f4 new file mode 100644 index 0000000..2956d1b --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f4 @@ -0,0 +1,5 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.1.1.1 +in 1.1.1.1 1.1.1.2 +in 1.1.1.1 1.1.2.2 +in 1.1.1.1 1.2.2.2 diff --git a/contrib/netbsd-tests/ipf/input/f5 b/contrib/netbsd-tests/ipf/input/f5 new file mode 100644 index 0000000..41600c1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f5 @@ -0,0 +1,28 @@ +in tcp 1.1.1.1,0 2.2.2.2,2222 +in tcp 1.1.1.1,1 2.2.2.2,2222 +in tcp 1.1.1.1,23 2.2.2.2,2222 +in tcp 1.1.1.1,21 2.2.2.2,2222 +in tcp 1.1.1.1,1023 2.2.2.2,2222 +in tcp 1.1.1.1,1024 2.2.2.2,2222 +in tcp 1.1.1.1,1025 2.2.2.2,2222 +in tcp 1.1.1.1,32767 2.2.2.2,2222 +in tcp 1.1.1.1,32768 2.2.2.2,2222 +in tcp 1.1.1.1,65535 2.2.2.2,2222 +in tcp 1.1.1.1,5999 2.2.2.2,2222 +in tcp 1.1.1.1,6000 2.2.2.2,2222 +in tcp 1.1.1.1,6009 2.2.2.2,2222 +in tcp 1.1.1.1,6010 2.2.2.2,2222 +in udp 1.1.1.1,0 2.2.2.2,2222 +in udp 1.1.1.1,1 2.2.2.2,2222 +in udp 1.1.1.1,23 2.2.2.2,2222 +in udp 1.1.1.1,21 2.2.2.2,2222 +in udp 1.1.1.1,1023 2.2.2.2,2222 +in udp 1.1.1.1,1024 2.2.2.2,2222 +in udp 1.1.1.1,1025 2.2.2.2,2222 +in udp 1.1.1.1,32767 2.2.2.2,2222 +in udp 1.1.1.1,32768 2.2.2.2,2222 +in udp 1.1.1.1,65535 2.2.2.2,2222 +in udp 1.1.1.1,5999 2.2.2.2,2222 +in udp 1.1.1.1,6000 2.2.2.2,2222 +in udp 1.1.1.1,6009 2.2.2.2,2222 +in udp 1.1.1.1,6010 2.2.2.2,2222 diff --git a/contrib/netbsd-tests/ipf/input/f6 b/contrib/netbsd-tests/ipf/input/f6 new file mode 100644 index 0000000..21f0be3 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f6 @@ -0,0 +1,28 @@ +in tcp 2.2.2.2,2222 1.1.1.1,0 +in tcp 2.2.2.2,2222 1.1.1.1,1 +in tcp 2.2.2.2,2222 1.1.1.1,23 +in tcp 2.2.2.2,2222 1.1.1.1,21 +in tcp 2.2.2.2,2222 1.1.1.1,1023 +in tcp 2.2.2.2,2222 1.1.1.1,1024 +in tcp 2.2.2.2,2222 1.1.1.1,1025 +in tcp 2.2.2.2,2222 1.1.1.1,32767 +in tcp 2.2.2.2,2222 1.1.1.1,32768 +in tcp 2.2.2.2,2222 1.1.1.1,65535 +in tcp 2.2.2.2,2222 1.1.1.1,5999 +in tcp 2.2.2.2,2222 1.1.1.1,6000 +in tcp 2.2.2.2,2222 1.1.1.1,6009 +in tcp 2.2.2.2,2222 1.1.1.1,6010 +in udp 2.2.2.2,2222 1.1.1.1,0 +in udp 2.2.2.2,2222 1.1.1.1,1 +in udp 2.2.2.2,2222 1.1.1.1,23 +in udp 2.2.2.2,2222 1.1.1.1,21 +in udp 2.2.2.2,2222 1.1.1.1,1023 +in udp 2.2.2.2,2222 1.1.1.1,1024 +in udp 2.2.2.2,2222 1.1.1.1,1025 +in udp 2.2.2.2,2222 1.1.1.1,32767 +in udp 2.2.2.2,2222 1.1.1.1,32768 +in udp 2.2.2.2,2222 1.1.1.1,65535 +in udp 2.2.2.2,2222 1.1.1.1,5999 +in udp 2.2.2.2,2222 1.1.1.1,6000 +in udp 2.2.2.2,2222 1.1.1.1,6009 +in udp 2.2.2.2,2222 1.1.1.1,6010 diff --git a/contrib/netbsd-tests/ipf/input/f7 b/contrib/netbsd-tests/ipf/input/f7 new file mode 100644 index 0000000..dbc9e33 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f7 @@ -0,0 +1,15 @@ +in icmp 1.1.1.1 2.1.1.1 echo +in icmp 1.1.1.1 2.1.1.1 echo,1 +in icmp 1.1.1.1 2.1.1.1 echo,3 +in icmp 1.1.1.1 2.1.1.1 unreach +in icmp 1.1.1.1 2.1.1.1 unreach,1 +in icmp 1.1.1.1 2.1.1.1 unreach,3 +in icmp 1.1.1.1 2.1.1.1 echorep +in icmp 1.1.1.1 2.1.1.1 echorep,1 +in icmp 1.1.1.1 2.1.1.1 echorep,3 +in icmp 2.2.2.2 3.3.3.3 maskreq +out icmp 3.3.3.3 2.2.2.2 maskrep +in icmp 4.4.4.4 5.5.5.5 timest +out icmp 5.5.5.5 4.4.4.4 timestrep +in icmp 6.6.6.6 7.7.7.7 inforeq +out icmp 7.7.7.7 6.6.6.6 inforep diff --git a/contrib/netbsd-tests/ipf/input/f8 b/contrib/netbsd-tests/ipf/input/f8 new file mode 100644 index 0000000..cace511 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f8 @@ -0,0 +1,6 @@ +in tcp 1.1.1.1,1 2.1.2.2,1 S +in tcp 1.1.1.1,1 2.1.2.2,1 SA +in tcp 1.1.1.1,1 2.1.2.2,1 SF +in tcp 1.1.1.1,1 2.1.2.2,1 SFPAUR +in tcp 1.1.1.1,1 2.1.2.2,1 PAU +in tcp 1.1.1.1,1 2.1.2.2,1 A diff --git a/contrib/netbsd-tests/ipf/input/f9 b/contrib/netbsd-tests/ipf/input/f9 new file mode 100644 index 0000000..e64e299 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/f9 @@ -0,0 +1,9 @@ +in 1.1.1.1 2.1.1.1 opt lsrr +in 1.1.1.1 2.1.1.1 opt lsrr=1.1.1.1 +in 1.1.1.1 2.1.1.1 opt lsrr,ssrr +in 1.1.1.1 2.1.1.1 opt ts +in 1.1.1.1 2.1.1.1 opt satid +in 1.1.1.1 2.1.1.1 opt satid=234 +in 1.1.1.1 2.1.1.1 opt sec-class=topsecret +in 1.1.1.1 2.1.1.1 opt ssrr,sec-class=topsecret +in 1.1.1.1 2.1.1.1 opt sec diff --git a/contrib/netbsd-tests/ipf/input/ip2.data b/contrib/netbsd-tests/ipf/input/ip2.data new file mode 100644 index 0000000..ef34eb5 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ip2.data @@ -0,0 +1,3 @@ +1.1.1.1/32 +!2.2.0.0/16 +2.2.2.0/24 diff --git a/contrib/netbsd-tests/ipf/input/ipv6.1 b/contrib/netbsd-tests/ipf/input/ipv6.1 new file mode 100644 index 0000000..6da8da0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ipv6.1 @@ -0,0 +1,45 @@ +# +# traceroute simulation +# +# UDP +# +[out,gif0] 6000 0000 0018 1101 +ef00 1001 2002 0001 0000 0000 0000 0070 +2001 1002 3333 0001 0000 0000 0000 0001 +8083 829a +0018 +f4c1 +0000 0344 0000 0004 f8f1 9d3c ddba 0e00 + +# +# ICMPV6 +# - Time exceeded +# +[in,gif0] 6000 0000 0048 3a40 +ef00 1001 0880 6cbf 0000 0000 0000 0001 +ef00 1001 2002 0001 0000 0000 0000 0070 +0300 f86f 0000 0000 +6000 0000 0018 1101 +ef00 1001 2002 0001 0000 0000 0000 0070 +2001 1002 3333 0001 0000 0000 0000 0001 +8083 829a +0018 +f427 +0000 0344 0000 0004 f8f1 9d3c ddba 0e00 + +# +# ICMPV6 +# - Time exceeded +# +[in,gif0] 6000 0000 0048 3a40 +ef00 1001 0880 6cbf 0000 0000 0000 0001 +ef00 1001 2002 0001 0000 0000 0000 0070 +0300 7266 0000 0000 +6000 0000 0018 1101 +ef00 1001 2002 1001 0000 0000 0000 0070 +2001 1002 3333 0001 0000 0000 0000 0001 +8083 f8a3 +0018 +f427 +0000 0344 0000 0004 f8f1 9d3c ddba 0e00 + diff --git a/contrib/netbsd-tests/ipf/input/ipv6.2 b/contrib/netbsd-tests/ipf/input/ipv6.2 new file mode 100644 index 0000000..8cc2d17 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ipv6.2 @@ -0,0 +1,26 @@ +[out,de0] +6000 0000 0020 3aff ef00 0000 0000 0000 +0000 0000 0001 0013 ff02 0000 0000 0000 +0000 0001 ff01 000b 8700 ea32 0000 0000 +ef00 0000 0000 0000 0000 0000 0001 000b +0101 0048 5487 5c6f + +[in,de0] +6000 0000 0020 3aff ef00 0000 0000 0000 +0000 0000 0001 000b ef00 0000 0000 0000 +0000 0000 0001 0013 8800 5322 6000 0000 +ef00 0000 0000 0000 0000 0000 0001 000b +0201 0800 2071 cce1 + +[out,de0] +6000 0000 0010 3a40 ef00 0000 0000 0000 +0000 0000 0001 0013 ef00 0000 0000 0000 +0000 0000 0001 000b 8000 3210 06ff 0002 +9ec3 3c3c 8a82 0300 + +[in,de0] +6000 0000 0010 3aff ef00 0000 0000 0000 +0000 0000 0001 000b ef00 0000 0000 0000 +0000 0000 0001 0013 8100 3110 06ff 0002 +9ec3 3c3c 8a82 0300 + diff --git a/contrib/netbsd-tests/ipf/input/ipv6.3 b/contrib/netbsd-tests/ipf/input/ipv6.3 new file mode 100644 index 0000000..3b2ef4d --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ipv6.3 @@ -0,0 +1,30 @@ +[out,gif0] +6000 0000 0010 3a40 3ffe 8280 0000 2001 +0000 0000 0000 4395 3ffe 8280 0000 2001 +0000 0000 0000 4394 8000 3f77 085c 0038 +0c06 b73d 1b3d 0d00 + +[in,gif0] +6000 0000 0010 3a40 3ffe 8280 0000 2001 +0000 0000 0000 4393 3ffe 8280 0000 2001 +0000 0000 0000 4395 8100 3e78 085c 0038 +0c06 b73d 1b3d 0d00 + +[in,gif0] +6000 0000 0010 3a40 3ffe 8280 0000 2001 +0000 0000 0000 4394 3ffe 8280 0000 2001 +0000 0000 0000 4395 8300 3c77 085c 0038 +0c06 b73d 1b3d 0d00 + +[in,gif0] +6000 0000 0010 3a40 3ffe 8280 0000 2001 +0000 0000 0000 4394 3ffe 8280 0000 2001 +0000 0000 0000 4395 8000 3f77 085c 0038 +0c06 b73d 1b3d 0d00 + +[in,gif0] +6000 0000 0010 3a40 3ffe 8280 0000 2001 +0000 0000 0000 4394 3ffe 8280 0000 2001 +0000 0000 0000 4395 8100 3e77 085c 0038 +0c06 b73d 1b3d 0d00 + diff --git a/contrib/netbsd-tests/ipf/input/ipv6.4 b/contrib/netbsd-tests/ipf/input/ipv6.4 new file mode 100644 index 0000000..eb986ae --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ipv6.4 @@ -0,0 +1,522 @@ +# fe80::20c:29ff:fe13:6899 > fe80::20c:29ff:fe21:5742: frag (0|1448) icmp6: echo request +[in,eth0] +6000 0000 05b0 2c40 fe80 0000 0000 0000 +020c 29ff fe13 6899 fe80 0000 0000 0000 +020c 29ff fe21 5742 3a00 0001 0000 0008 +8000 f400 2c0a 0001 fd38 4a42 9e59 0900 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f + +# fe80::20c:29ff:fe13:6899 > fe80::20c:29ff:fe21:5742: frag (1448|160) +[in,eth0] +6000 0000 00a8 2c40 fe80 0000 0000 0000 +020c 29ff fe13 6899 fe80 0000 0000 0000 +020c 29ff fe21 5742 3a00 05a8 0000 0008 +a0a1 a2a3 a4a5 a6a7 a8a9 aaab acad aeaf +b0b1 b2b3 b4b5 b6b7 b8b9 babb bcbd bebf +c0c1 c2c3 c4c5 c6c7 c8c9 cacb cccd cecf +d0d1 d2d3 d4d5 d6d7 d8d9 dadb dcdd dedf +e0e1 e2e3 e4e5 e6e7 e8e9 eaeb eced eeef +f0f1 f2f3 f4f5 f6f7 f8f9 fafb fcfd feff +0001 0203 0405 0607 0809 0a0b 0c0d 0e0f +1011 1213 1415 1617 1819 1a1b 1c1d 1e1f +2021 2223 2425 2627 2829 2a2b 2c2d 2e2f +3031 3233 3435 3637 3839 3a3b 3c3d 3e3f + +# fe80::20c:29ff:fe21:5742 > fe80::20c:29ff:fe13:6899: frag (0|1232) icmp6: echo reply +[out,eth0] +6000 0000 04d8 2c40 fe80 0000 0000 0000 +020c 29ff fe21 5742 fe80 0000 0000 0000 +020c 29ff fe13 6899 3a00 0001 9c56 86dd +8100 f300 2c0a 0001 fd38 4a42 9e59 0900 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 + +# fe80::20c:29ff:fe21:5742 > fe80::20c:29ff:fe13:6899: frag (1232|376) +[out,eth0] +6000 0000 0180 2c40 fe80 0000 0000 0000 +020c 29ff fe21 5742 fe80 0000 0000 0000 +020c 29ff fe13 6899 3a00 04d0 9c56 86dd +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f + +# fe80::20c:29ff:fe13:6899 > fe80::20c:29ff:fe21:5742: frag (0|1448) icmp6: echo request +[in,eth0] +6000 0000 05b0 2c40 fe80 0000 0000 0000 +020c 29ff fe13 6899 fe80 0000 0000 0000 +020c 29ff fe21 5742 3a00 0001 0000 0009 +8000 80fb 2c0a 0002 fe38 4a42 105e 0900 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f + +# fe80::20c:29ff:fe13:6899 > fe80::20c:29ff:fe21:5742: frag (1448|160) +[in,eth0] +6000 0000 00a8 2c40 fe80 0000 0000 0000 +020c 29ff fe13 6899 fe80 0000 0000 0000 +020c 29ff fe21 5742 3a00 05a8 0000 0009 +a0a1 a2a3 a4a5 a6a7 a8a9 aaab acad aeaf +b0b1 b2b3 b4b5 b6b7 b8b9 babb bcbd bebf +c0c1 c2c3 c4c5 c6c7 c8c9 cacb cccd cecf +d0d1 d2d3 d4d5 d6d7 d8d9 dadb dcdd dedf +e0e1 e2e3 e4e5 e6e7 e8e9 eaeb eced eeef +f0f1 f2f3 f4f5 f6f7 f8f9 fafb fcfd feff +0001 0203 0405 0607 0809 0a0b 0c0d 0e0f +1011 1213 1415 1617 1819 1a1b 1c1d 1e1f +2021 2223 2425 2627 2829 2a2b 2c2d 2e2f +3031 3233 3435 3637 3839 3a3b 3c3d 3e3f + +# fe80::20c:29ff:fe21:5742 > fe80::20c:29ff:fe13:6899: frag (0|1232) icmp6: echo reply +[out,eth0] +6000 0000 04d8 2c40 fe80 0000 0000 0000 +020c 29ff fe21 5742 fe80 0000 0000 0000 +020c 29ff fe13 6899 3a00 0001 9889 f4c1 +8100 7ffb 2c0a 0002 fe38 4a42 105e 0900 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 + +# fe80::20c:29ff:fe21:5742 > fe80::20c:29ff:fe13:6899: frag (1232|376) +[out,eth0] +6000 0000 0180 2c40 fe80 0000 0000 0000 +020c 29ff fe21 5742 fe80 0000 0000 0000 +020c 29ff fe13 6899 3a00 04d0 9889 f4c1 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f 4041 4243 4445 4647 +4849 4a4b 4c4d 4e4f 5051 5253 5455 5657 +5859 5a5b 5c5d 5e5f 6061 6263 6465 6667 +6869 6a6b 6c6d 6e6f 7071 7273 7475 7677 +7879 7a7b 7c7d 7e7f 8081 8283 8485 8687 +8889 8a8b 8c8d 8e8f 9091 9293 9495 9697 +9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 a6a7 +a8a9 aaab acad aeaf b0b1 b2b3 b4b5 b6b7 +b8b9 babb bcbd bebf c0c1 c2c3 c4c5 c6c7 +c8c9 cacb cccd cecf d0d1 d2d3 d4d5 d6d7 +d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 e6e7 +e8e9 eaeb eced eeef f0f1 f2f3 f4f5 f6f7 +f8f9 fafb fcfd feff 0001 0203 0405 0607 +0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 +1819 1a1b 1c1d 1e1f 2021 2223 2425 2627 +2829 2a2b 2c2d 2e2f 3031 3233 3435 3637 +3839 3a3b 3c3d 3e3f + +# frag: [0-7:nh][8-15:res][16-31:off][32-64:id] +# Case 4: ipv6,fragment[id=10,off=0,m=1],tcp +[in,eth0] +600a af74 0038 2c40 +fe80 0000 0000 0000 020c 29ff fe21 5742 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +0600 0001 0000 0010 +fff3 0017 52ac fbab 0000 0000 c002 8000 d36b 0000 +0204 05a0 0103 0300 0402 0101 0101 080a 0000 0000 0000 0000 0000 0000 + +# Case 5: ipv6,fragment[id=10,off=5,m=1],data +[in,eth0] +600a af74 0010 2c40 +fe80 0000 0000 0000 020c 29ff fe21 5742 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +0600 0030 0000 0010 +0000 0000 0000 0000 + +# Case 3: ipv6,fragment[id=10,off=1,m=0],tcp +[in,eth0] +600a af74 0034 2c40 +fe80 0000 0000 0000 020c 29ff fe21 5742 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +0600 0008 0000 0010 +0000 0000 b002 8000 d36b 0000 +0204 05a0 0103 0300 0402 0101 0101 080a 0000 0000 0000 0000 + +# Case 1: ipv6,fragment[id=11,off=0,m=1],hopopts,ah[next=dstopts] +[in,eth0] +600a af74 0020 2c40 +fe80 0000 0000 0000 020c 29ff fe21 5742 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +0000 0001 0000 0011 +3300 0000 0000 0000 +3c01 0000 0000 0000 0000 0000 0000 0000 + +# Case 2: ipv6,fragment[id=11,off=3,m=0],dstopts,hop,tcp +[in,eth0] +600a af74 002c 2c40 +fe80 0000 0000 0000 020c 29ff fe21 5742 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +3c00 0008 0000 0011 +0000 0000 0000 0000 +0600 0000 0000 0000 +fff3 0017 52ac fbab 0000 0000 5002 8000 d36b 0000 + +# Case 4: ipv6,fragment[id=10,off=0,m=1],tcp +[out,eth0] +6000 0000 001c 2c40 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +fe80 0000 0000 0000 020c 29ff fe21 5742 +0600 0001 0000 0010 +0017 fff3 0000 0000 52ac fbac 5014 0000 cd26 0000 + +# Normal TCP Reset +[out,eth0] +6000 0000 0014 0640 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +fe80 0000 0000 0000 020c 29ff fe21 5742 +0017 fff3 0000 0000 52ac fbac 5014 0000 cd26 0000 + +# Case 4: ipv6,fragment[id=12,off=0,m=1],tcp +[in,eth0] +600a af74 0038 2c40 +fe80 0000 0000 0000 020c 29ff fe21 5742 +fe80 0000 0000 0000 020c 29ff fe6e eb5a +0600 0001 0000 0012 +fff3 0017 52ac fbab 0000 0000 c002 8000 d36b 0000 +0204 05a0 0103 0300 0402 0101 0101 080a 0000 0000 0000 0000 0000 0000 + diff --git a/contrib/netbsd-tests/ipf/input/ipv6.5 b/contrib/netbsd-tests/ipf/input/ipv6.5 new file mode 100644 index 0000000..e46407c --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ipv6.5 @@ -0,0 +1,14 @@ +[out,de0] +6000 0000 002c 2bff +ef00 0000 0000 0000 0000 0000 0001 0013 +ff02 0000 0000 0000 0000 0001 ff01 000b +0602 0000 0000 0000 +ff02 0000 0000 0000 0000 0001 ff01 000b +0401 0019 0000 0000 0000 0000 5002 2000 9ea3 0000 + +[out,de0] +6000 0000 0014 06ff +ef00 0000 0000 0000 0000 0000 0001 0013 +ff02 0000 0000 0000 0000 0001 ff01 000b +0401 0019 0000 0000 0000 0000 5002 2000 9ea3 0000 + diff --git a/contrib/netbsd-tests/ipf/input/ipv6.6 b/contrib/netbsd-tests/ipf/input/ipv6.6 new file mode 100644 index 0000000..fffbad2 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ipv6.6 @@ -0,0 +1,31 @@ +[out,gif0] +6000 0000 0020 2c01 +ef00 1001 2002 0001 0000 0000 0000 0070 +2001 1002 3333 0001 0000 0000 0000 0001 +1100 0001 0000 0001 +8083 829a +0020 +f4c1 +0000 0000 0000 0000 0000 0000 0000 0000 + +[out,gif0] +6000 0000 0020 2c01 +ef00 1001 2002 0001 0000 0000 0000 0070 +2001 1002 3333 0001 0000 0000 0000 0001 +1100 0008 0000 0001 +0000 0000 0000 0000 0000 0000 0000 0000 + +[out,gif0] +6000 0000 001e 2c01 +ef00 1001 2002 0001 0000 0000 0000 0070 +2001 1002 3333 0001 0000 0000 0000 0001 +1100 0001 0000 0001 +0000 0000 0000 0000 0000 0000 0000 + +[out,gif0] +6000 0000 0020 2c01 +ef00 1001 2002 0001 0000 0000 0000 0070 +2001 1002 3333 0001 0000 0000 0000 0001 +1100 001c 0000 0001 +0000 0000 0000 0000 0000 0000 0000 0000 + diff --git a/contrib/netbsd-tests/ipf/input/l1 b/contrib/netbsd-tests/ipf/input/l1 new file mode 100644 index 0000000..a59dbe3 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/l1 @@ -0,0 +1,64 @@ +# 1.1.1.1,1025 -> 2.2.2.2,25 TTL=63 TCP DF SYN +[] +4500 0028 0000 4000 3f06 35cb 0101 0101 0202 0202 +0401 0019 0000 0001 0000 0000 5002 2000 85c2 0000 + +#in on e0 tcp 1.1.1.1,1025 2.1.2.2,25 A +[] +4500 0028 0000 4000 3f06 35cb 0101 0101 0202 0202 +0401 0019 0000 0001 0000 0000 5010 2000 85b4 0000 + +#in on e1 tcp 2.1.2.2,25 1.1.1.1,1025 AS +[] +4500 0028 0000 4000 3f06 35cb 0202 0202 0101 0101 +0019 0401 0000 0011 0000 0002 5012 2000 85a0 0000 + +#in on e1 tcp 2.1.2.2,25 1.1.1.1,1025 A +[out,e1] 4500 0028 0000 4000 3f06 35cb 0202 0202 0101 0101 +0019 0401 0000 0012 0000 0002 5010 2000 85a1 0000 + +#in on e0 tcp 1.1.1.1,1025 2.1.2.2,25 AF +[] +4500 0028 0000 4000 3f06 35cb 0101 0101 0202 0202 +0401 0019 0000 0002 0000 0012 5011 2000 85a0 0000 + +#in on e0 tcp 1.1.1.1,1025 2.1.2.2,25 A +[] +4500 0028 0000 4000 3f06 35cb 0101 0101 0202 0202 +0401 0019 0000 0012 0000 0003 5010 2000 85a0 0000 + +#in on e0 tcp 1.1.1.1,1025 2.1.2.2,25 A +[] +4500 0028 0000 4000 3f06 35cb 0101 0101 0202 0202 +0401 0019 0000 0012 0000 0003 5010 2000 85a0 0000 + +#in on e1 udp 1.1.1.1,1 4.4.4.4,53 +[] +4500 0028 0000 4000 3f11 31bc 0101 0101 0404 0404 +0001 0035 0000 d16f 0102 0304 0506 0708 090a 0b0d + +#in on e1 udp 2.2.2.2,2 4.4.4.4,53 +[] +4500 0028 0000 4000 3f11 2fba 0202 0202 0404 0404 +0001 0035 0000 0000 0102 0304 0506 0708 090a 0b0d + +#in on e1 udp 2.2.2.2,2 4.4.4.4,53 +[] +4500 0038 0000 4000 3f11 2faa 0202 0202 0404 0404 +0001 0035 0000 d47b 0102 0304 0506 0708 090a 0b0d +0e0f 4061 4263 4465 4667 4869 4a6b 4c6d + +#in on e0 ip 4.4.4.4,53 1.1.1.1,1 +[] +4500 0014 0000 4000 3f00 2fdf 0202 0202 0404 0404 + +#in on e0 udp 3.3.3.3,1023 1.1.1.1,2049 +[] +4500 001c 0000 4000 3f11 33ca 0303 0303 0101 0101 +03ff 0801 0000 ebde + +#in on e0 udp 1.1.1.1,2049 3.3.3.3,1023 +[] +4500 001c 0000 4000 3f11 33ca 0101 0101 0303 0303 +0801 03ff 0000 0000 + diff --git a/contrib/netbsd-tests/ipf/input/n1 b/contrib/netbsd-tests/ipf/input/n1 new file mode 100644 index 0000000..04b24ef --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n1 @@ -0,0 +1,34 @@ +out on zx0 255 10.1.1.0 10.1.1.2 +out on zx0 255 10.1.1.1 10.1.1.2 +out on zx0 255 10.1.1.2 10.1.1.1 +out on zx0 tcp 10.1.1.2,1025 10.1.1.1,1025 +out on zx0 tcp 10.1.1.2,1026 10.1.1.1,1025 +out on zx0 255 10.2.2.1 10.1.2.1 +out on zx0 255 10.2.2.2 10.1.2.1 +in on zx0 255 10.1.1.1 10.1.1.2 +in on zx0 255 10.1.1.2 10.1.1.1 +in on zx0 255 10.2.2.1 10.2.1.1 +in on zx0 255 10.2.2.2 10.2.1.1 +in on zx0 255 10.2.2.3 10.1.1.1 +in on zx0 255 10.2.3.4 10.2.2.2 +in on zx0 255 10.1.1.1 10.2.2.2 +in on zx0 255 10.1.1.2 10.2.2.2 +in on zx0 255 10.1.1.0 10.3.4.5 +in on zx0 255 10.1.1.1 10.3.4.5 +in on zx0 255 10.1.1.2 10.3.4.5 +in on zx0 tcp 10.1.1.1,1025 10.3.4.5,1025 +out on zx0 icmp 10.1.1.1 10.4.3.2 +in on zx0 icmp 10.4.3.2 10.2.2.2 +in on zx0 icmp 10.4.3.2 10.3.4.1 +in on zx0 icmp 10.4.3.2 10.3.4.2 +in on zx0 icmp 10.4.3.2 10.3.4.3 +in on zx0 icmp 10.4.3.2 10.3.4.4 +in on zx0 icmp 10.4.3.2 10.3.4.5 +out on zx0 34 10.1.1.2 10.4.3.2 +in on zx0 34 10.4.3.2 10.3.4.4 +out on zx0 34 10.1.1.2 10.4.3.4 +in on zx0 34 10.4.3.4 10.3.4.5 +out on zx0 34 10.1.1.3 10.4.3.4 +in on zx0 34 10.4.3.4 10.3.4.6 +out on zx0 35 10.1.1.3 10.4.3.4 +in on zx0 35 10.4.3.4 10.3.4.7 diff --git a/contrib/netbsd-tests/ipf/input/n10 b/contrib/netbsd-tests/ipf/input/n10 new file mode 100644 index 0000000..1e919cc --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n10 @@ -0,0 +1,6 @@ +# TCP SYN packet with an MSS option +[out,ppp0] +4500 002c 10c9 4000 ff06 3289 c0a8 0103 96cb e002 +8032 0015 bd6b c9c8 0000 0000 +6002 2238 35f9 0000 0204 05b4 + diff --git a/contrib/netbsd-tests/ipf/input/n100 b/contrib/netbsd-tests/ipf/input/n100 new file mode 100644 index 0000000..94ff8c4 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n100 @@ -0,0 +1,8 @@ +out on zx0 255 1.1.1.1 2.3.2.3 +out on zx0 255 1.1.1.1 2.2.2.3 +out on zx0 255 1.1.1.2 2.2.2.3 +out on zx0 255 1.2.1.2 2.2.2.3 +out on zx0 255 1.1.1.1 2.2.2.4 +out on zx0 255 1.1.1.1 2.2.2.3 +out on zx0 tcp 1.1.1.1,101 2.3.2.3,203 +out on zx0 tcp 1.1.1.1,101 2.2.2.3,203 diff --git a/contrib/netbsd-tests/ipf/input/n101 b/contrib/netbsd-tests/ipf/input/n101 new file mode 100644 index 0000000..94ff8c4 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n101 @@ -0,0 +1,8 @@ +out on zx0 255 1.1.1.1 2.3.2.3 +out on zx0 255 1.1.1.1 2.2.2.3 +out on zx0 255 1.1.1.2 2.2.2.3 +out on zx0 255 1.2.1.2 2.2.2.3 +out on zx0 255 1.1.1.1 2.2.2.4 +out on zx0 255 1.1.1.1 2.2.2.3 +out on zx0 tcp 1.1.1.1,101 2.3.2.3,203 +out on zx0 tcp 1.1.1.1,101 2.2.2.3,203 diff --git a/contrib/netbsd-tests/ipf/input/n102 b/contrib/netbsd-tests/ipf/input/n102 new file mode 100644 index 0000000..94ff8c4 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n102 @@ -0,0 +1,8 @@ +out on zx0 255 1.1.1.1 2.3.2.3 +out on zx0 255 1.1.1.1 2.2.2.3 +out on zx0 255 1.1.1.2 2.2.2.3 +out on zx0 255 1.2.1.2 2.2.2.3 +out on zx0 255 1.1.1.1 2.2.2.4 +out on zx0 255 1.1.1.1 2.2.2.3 +out on zx0 tcp 1.1.1.1,101 2.3.2.3,203 +out on zx0 tcp 1.1.1.1,101 2.2.2.3,203 diff --git a/contrib/netbsd-tests/ipf/input/n103 b/contrib/netbsd-tests/ipf/input/n103 new file mode 100644 index 0000000..7957799 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n103 @@ -0,0 +1,8 @@ +out on zx0 tcp 1.1.1.1,101 2.3.2.3,203 +out on zx0 tcp 1.1.1.1,101 2.2.2.3,203 +out on zx0 tcp 1.1.1.1,101 2.2.2.3,203 +out on zx0 tcp 1.1.1.2,101 2.2.2.3,203 +out on zx0 tcp 10.10.10.10,101 2.2.2.3,203 +out on zx0 tcp 5.5.5.5,101 2.2.2.3,203 +in on zx0 tcp 2.2.2.3,4000 4.4.4.4,1000 +out on zx0 tcp 7.7.7.7,101 2.2.2.3,203 diff --git a/contrib/netbsd-tests/ipf/input/n104 b/contrib/netbsd-tests/ipf/input/n104 new file mode 100644 index 0000000..bb46b28 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n104 @@ -0,0 +1,48 @@ +[out,zx0] +4500 0028 0001 0000 ff06 b5c9 0101 0101 0202 0202 +0065 00cb 0000 0001 1000 0001 5010 2000 789d 0000 + +[in,zx0] +4500 0028 0002 0000 ff06 b1c2 0606 0001 0404 0001 +0fa0 03e8 0000 0001 1000 0001 5010 2000 623f 0000 + +[out,zx0] +4500 0028 0003 0000 ff06 b5c7 0101 0101 0202 0202 +0066 00cb 0000 0001 1000 0001 5010 2000 789c 0000 + +[in,zx0] +4500 0028 0004 0000 ff06 b1bf 0606 0001 0404 0002 +0fa0 03e8 0000 0001 1000 0001 5010 2000 623e 0000 + +[out,zx0] +4500 0028 0005 0000 ff06 b5c5 0101 0101 0202 0202 +0067 00cb 0000 0001 1000 0001 5010 2000 789b 0000 + +[in,zx0] +4500 0028 0006 0000 ff06 b1bd 0606 0001 0404 0002 +0fa0 03e9 0000 0001 1000 0001 5010 2000 623d 0000 + +[out,zx0] +4500 0028 0007 0000 ff06 b5c3 0101 0101 0202 0202 +0068 00cb 0000 0001 1000 0001 5010 2000 789a 0000 + +[in,zx0] +4500 0028 0008 0000 ff06 b1ba 0606 0002 0404 0002 +0fa0 03e9 0000 0001 1000 0001 5010 2000 623c 0000 + +[out,zx0] +4500 0028 0009 0000 ff06 b5c1 0101 0101 0202 0202 +0069 00cb 0000 0001 1000 0001 5010 2000 7899 0000 + +[in,zx0] +4500 0028 000a 0000 ff06 b1b8 0606 0002 0404 0002 +0fa1 03e9 0000 0001 1000 0001 5010 2000 623b 0000 + +[out,zx0] +4500 0028 000b 0000 ff06 b5bf 0101 0101 0202 0202 +006a 00cb 0000 0001 1000 0001 5010 2000 7898 0000 + +[in,zx0] +4500 0028 000c 0000 ff06 b1b5 0606 0002 0404 0003 +0fa1 03e9 0000 0001 1000 0001 5010 2000 623a 0000 + diff --git a/contrib/netbsd-tests/ipf/input/n105 b/contrib/netbsd-tests/ipf/input/n105 new file mode 100644 index 0000000..63b68f0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n105 @@ -0,0 +1,8 @@ +[in,zx0] +4500 0028 0001 0000 ff06 b5c9 0101 0101 0202 0202 +0065 0050 0000 0001 1000 0001 5010 2000 7918 0000 + +[out,zx0] +4500 0028 0001 0000 ff06 adc0 0606 0001 0404 0404 +0c38 03e8 0000 0001 1000 0001 5010 2000 61a4 0000 + diff --git a/contrib/netbsd-tests/ipf/input/n106 b/contrib/netbsd-tests/ipf/input/n106 new file mode 100644 index 0000000..4e93378 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n106 @@ -0,0 +1,8 @@ +[out,zx0] +4500 0028 0001 0000 ff06 b5c9 0101 0101 0202 0202 +0065 0050 0000 0001 1000 0001 5010 2000 7918 0000 + +[in,zx0] +4500 0028 0001 0000 ff06 adc0 0606 0001 0404 0404 +0c38 03e8 0000 0001 1000 0001 5010 2000 61a4 0000 + diff --git a/contrib/netbsd-tests/ipf/input/n10_6 b/contrib/netbsd-tests/ipf/input/n10_6 new file mode 100644 index 0000000..5c1f5af --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n10_6 @@ -0,0 +1,6 @@ +# TCP SYN packet with an MSS option +[out,ppp0] +6000 0000 0018 06ff c0a8 0100 0000 0000 0000 0000 0000 0003 96cb e000 0000 0000 0000 0000 0000 0002 +8032 0015 bd6b c9c8 0000 0000 +6002 2238 35f9 0000 0204 05b4 + diff --git a/contrib/netbsd-tests/ipf/input/n11 b/contrib/netbsd-tests/ipf/input/n11 new file mode 100644 index 0000000..8712674 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n11 @@ -0,0 +1,16 @@ +out on zx0 255 10.1.1.0 10.1.1.2 +out on zx0 255 10.1.1.1 10.1.1.2 +out on zx0 255 10.1.1.2 10.1.1.1 +out on zx0 255 10.2.2.1 10.1.2.1 +out on zx0 255 10.2.2.2 10.1.2.1 +in on zx0 255 10.1.1.1 10.1.1.2 +in on zx0 255 10.1.1.2 10.1.1.1 +in on zx0 255 10.2.2.1 10.2.1.1 +in on zx0 255 10.2.2.2 10.2.1.1 +in on zx0 255 10.2.2.3 10.1.1.1 +in on zx0 255 10.2.3.4 10.2.2.2 +in on zx0 255 10.1.1.1 10.2.2.2 +in on zx0 255 10.1.1.2 10.2.2.2 +in on zx0 255 10.1.1.0 10.3.4.5 +in on zx0 255 10.1.1.1 10.3.4.5 +in on zx0 255 10.1.1.2 10.3.4.5 diff --git a/contrib/netbsd-tests/ipf/input/n11_6 b/contrib/netbsd-tests/ipf/input/n11_6 new file mode 100644 index 0000000..128e45a --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n11_6 @@ -0,0 +1,16 @@ +out6 on zx0 255 10:1:1::0 10:1:1::2 +out6 on zx0 255 10:1:1::1 10:1:1::2 +out6 on zx0 255 10:1:1::2 10:1:1::1 +out6 on zx0 255 10::2:2:1 10:1:2::1 +out6 on zx0 255 10::2:2:2 10:1:2::1 +in6 on zx0 255 10:1:1::1 10:1:1::2 +in6 on zx0 255 10:1:1::2 10:1:1::1 +in6 on zx0 255 10::2:2:1 10::2:1:1 +in6 on zx0 255 10::2:2:2 10::2:1:1 +in6 on zx0 255 10::2:2:3 10:1:1::1 +in6 on zx0 255 10::2:3:4 10::2:2:2 +in6 on zx0 255 10:1:1::1 10::2:2:2 +in6 on zx0 255 10:1:1::2 10::2:2:2 +in6 on zx0 255 10:1:1::0 10::3:4:5 +in6 on zx0 255 10:1:1::1 10::3:4:5 +in6 on zx0 255 10:1:1::2 10::3:4:5 diff --git a/contrib/netbsd-tests/ipf/input/n12 b/contrib/netbsd-tests/ipf/input/n12 new file mode 100644 index 0000000..16e479e --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n12 @@ -0,0 +1,18 @@ +[out,le0=192.168.1.188] +4510 0040 2020 4000 4006 17e1 c0a8 7e53 c0a8 0303 +12c2 0017 4e33 298e 0000 0000 +b002 4000 07af 0000 0204 05b4 0101 0402 +0103 0300 0101 080a 0c72 549e 0000 0000 + +[in,le0] +4500 003c 00b0 4000 fe06 f5fb c0a8 0303 c0a8 01bc +0017 2710 f674 e02c 4e33 298f +a012 2798 e317 0000 0101 080a 2c05 b797 +0c72 549e 0103 0300 0204 05b4 + +[out,le0] +4510 0034 493b 4000 4006 eed1 c0a8 7e53 c0a8 0303 +12c2 0017 4e33 298f f674 e02d +8010 4000 8e2a 0000 0101 080a 0c72 549e +2c05 b797 + diff --git a/contrib/netbsd-tests/ipf/input/n12_6 b/contrib/netbsd-tests/ipf/input/n12_6 new file mode 100644 index 0000000..8583acb --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n12_6 @@ -0,0 +1,18 @@ +[out,le0=c0a8:0100::bc] +6000 0000 002c 0640 c0a8 7e00 0000 0000 0000 0000 0000 0053 c0a8 0300 0000 0000 0000 0000 0000 0003 +12c2 0017 4e33 298e 0000 0000 +b002 4000 07af 0000 0204 05b4 0101 0402 +0103 0300 0101 080a 0c72 549e 0000 0000 + +[in,le0] +6000 0000 0028 06fe c0a8 0300 0000 0000 0000 0000 0000 0003 c0a8 0100 0000 0000 0000 0000 0000 00bc +0017 2710 f674 e02c 4e33 298f +a012 2798 e317 0000 0101 080a 2c05 b797 +0c72 549e 0103 0300 0204 05b4 + +[out,le0] +6000 0000 0020 0640 c0a8 7e00 0000 0000 0000 0000 0000 0053 c0a8 0300 0000 0000 0000 0000 0000 0003 +12c2 0017 4e33 298f f674 e02d +8010 4000 8e2a 0000 0101 080a 0c72 549e +2c05 b797 + diff --git a/contrib/netbsd-tests/ipf/input/n13 b/contrib/netbsd-tests/ipf/input/n13 new file mode 100644 index 0000000..ac7bbbd --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n13 @@ -0,0 +1,4 @@ +out on le0 192.168.1.1 150.1.1.1 +out on le0 192.168.1.1 150.1.1.2 +out on le0 192.168.1.2 150.1.1.2 +out on le0 192.168.1.3 150.1.1.1 diff --git a/contrib/netbsd-tests/ipf/input/n13_6 b/contrib/netbsd-tests/ipf/input/n13_6 new file mode 100644 index 0000000..54b262d --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n13_6 @@ -0,0 +1,4 @@ +out6 on le0 192:168:1::1 150:1:1::1 +out6 on le0 192:168:1::1 150:1:1::2 +out6 on le0 192:168:1::2 150:1:1::2 +out6 on le0 192:168:1::3 150:1:1::1 diff --git a/contrib/netbsd-tests/ipf/input/n14 b/contrib/netbsd-tests/ipf/input/n14 new file mode 100644 index 0000000..969eb1c --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n14 @@ -0,0 +1,4 @@ +in on gre0 tcp 10.2.2.5,2000 203.1.1.1,80 +in on gre0 tcp 10.2.2.6,2000 203.1.1.1,80 +in on gre0 tcp 10.2.2.7,2000 203.1.1.1,80 +in on gre0 tcp 10.2.2.5,2001 203.1.1.1,80 diff --git a/contrib/netbsd-tests/ipf/input/n14_6 b/contrib/netbsd-tests/ipf/input/n14_6 new file mode 100644 index 0000000..f5dd5d3 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n14_6 @@ -0,0 +1,4 @@ +in6 on gre0 tcp 10::2:2:5,2000 203:1:1::1,80 +in6 on gre0 tcp 10::2:2:6,2000 203:1:1::1,80 +in6 on gre0 tcp 10::2:2:7,2000 203:1:1::1,80 +in6 on gre0 tcp 10::2:2:5,2001 203:1:1::1,80 diff --git a/contrib/netbsd-tests/ipf/input/n15 b/contrib/netbsd-tests/ipf/input/n15 new file mode 100644 index 0000000..715848e --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n15 @@ -0,0 +1,2 @@ +in on le0 tcp 9.9.9.9,10011 5.5.5.5,80 +in on le0 tcp 9.9.9.9,10011 2.2.2.2,80 diff --git a/contrib/netbsd-tests/ipf/input/n15_6 b/contrib/netbsd-tests/ipf/input/n15_6 new file mode 100644 index 0000000..4a56138 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n15_6 @@ -0,0 +1,2 @@ +in6 on le0 tcp 9:9:9::9,10011 5:5::5:5,80 +in6 on le0 tcp 9:9:9::9,10011 2::2:2:2,80 diff --git a/contrib/netbsd-tests/ipf/input/n16 b/contrib/netbsd-tests/ipf/input/n16 new file mode 100644 index 0000000..ad09a45 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n16 @@ -0,0 +1,40 @@ +[in,vlan0] +4520 0068 17e4 0000 6b11 3539 c05b ac33 45f8 4fc1 +1194 94f8 0054 0000 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 + +[out,vlan2] +4520 0068 17e4 0000 6a11 ccba c05b ac33 ac1f 5318 +1194 07dd 0054 0000 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 + +[in,vlan2] +4500 0084 ee0f 0000 8001 e0a2 ac1f 5318 c05b ac33 +0303 4ca1 0000 0000 +4520 0068 17e4 0000 6a11 ccba c05b ac33 ac1f 5318 +1194 07dd 0054 0000 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 + +[out,vlan0] +4500 0084 ee0f 0000 8001 e0a2 ac1f 5318 c05b ac33 +0303 4ca1 0000 0000 +4520 0068 17e4 0000 6a11 ccba c05b ac33 ac1f 5318 +1194 07dd 0054 0000 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 +a5a5 a5a5 a5a5 a5a5 a5a5 a5a5 + diff --git a/contrib/netbsd-tests/ipf/input/n17 b/contrib/netbsd-tests/ipf/input/n17 new file mode 100644 index 0000000..29709de --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n17 @@ -0,0 +1,24 @@ +[out,zx0] +4500 00a0 0000 0100 3f06 7555 0101 0101 0201 0101 +0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 + +[in,zx0] +4500 00a0 0000 0100 3f06 7553 0201 0101 0101 0103 +0401 0019 0000 0000 0000 0000 5010 2000 86b7 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 + diff --git a/contrib/netbsd-tests/ipf/input/n18 b/contrib/netbsd-tests/ipf/input/n18 new file mode 100644 index 0000000..a7a610c --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n18 @@ -0,0 +1,8 @@ +out on z0 tcp 2.2.2.2,22 3.3.3.3,30 +out on z0 tcp 2.2.2.2,23 3.3.3.3,31 +out on z0 tcp 2.2.2.2,24 3.3.3.3,32 +out on z0 tcp 2.2.2.2,25 3.3.3.3,33 +out on z0 tcp 2.2.2.2,26 3.3.3.3,34 +out on z0 tcp 2.2.2.2,27 3.3.3.3,35 +out on z0 tcp 2.2.2.2,28 3.3.3.3,36 +out on z0 tcp 2.2.2.2,29 3.3.3.3,37 diff --git a/contrib/netbsd-tests/ipf/input/n1_6 b/contrib/netbsd-tests/ipf/input/n1_6 new file mode 100644 index 0000000..c1badab --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n1_6 @@ -0,0 +1,34 @@ +out6 on zx0 255 10:1:1::0 10:1:1::2 +out6 on zx0 255 10:1:1::1 10:1:1::2 +out6 on zx0 255 10:1:1::2 10:1:1::1 +out6 on zx0 tcp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::2,1026 10:1:1::1,1025 +out6 on zx0 255 10::2:2:1 10:1:2::1 +out6 on zx0 255 10::2:2:2 10:1:2::1 +in6 on zx0 255 10:1:1::1 10:1:1::2 +in6 on zx0 255 10:1:1::2 10:1:1::1 +in6 on zx0 255 10::2:2:1 10::2:1:1 +in6 on zx0 255 10::2:2:2 10::2:1:1 +in6 on zx0 255 10::2:2:3 10:1:1::1 +in6 on zx0 255 10::2:3:4 10::2:2:2 +in6 on zx0 255 10:1:1::1 10::2:2:2 +in6 on zx0 255 10:1:1::2 10::2:2:2 +in6 on zx0 255 10:1:1::0 10::3:4:5 +in6 on zx0 255 10:1:1::1 10::3:4:5 +in6 on zx0 255 10:1:1::2 10::3:4:5 +in6 on zx0 tcp 10:1:1::1,1025 10::3:4:5,1025 +out6 on zx0 58 10:1:1::1 10:4:3::2 +in6 on zx0 58 10:4:3::2 10::2:2:2 +in6 on zx0 58 10:4:3::2 10::3:4:1 +in6 on zx0 58 10:4:3::2 10::3:4:2 +in6 on zx0 58 10:4:3::2 10::3:4:3 +in6 on zx0 58 10:4:3::2 10::3:4:4 +in6 on zx0 58 10:4:3::2 10::3:4:5 +out6 on zx0 34 10:1:1::2 10:4:3::2 +in6 on zx0 34 10:4:3::2 10::3:4:4 +out6 on zx0 34 10:1:1::2 10:4:3::4 +in6 on zx0 34 10:4:3::4 10::3:4:5 +out6 on zx0 34 10:1:1::3 10:4:3::4 +in6 on zx0 34 10:4:3::4 10::3:4:6 +out6 on zx0 35 10:1:1::3 10:4:3::4 +in6 on zx0 35 10:4:3::4 10::3:4:7 diff --git a/contrib/netbsd-tests/ipf/input/n2 b/contrib/netbsd-tests/ipf/input/n2 new file mode 100644 index 0000000..476f16e --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n2 @@ -0,0 +1,19 @@ +out on zx0 tcp 10.1.1.1,1025 10.1.1.1,1025 +out on zx0 tcp 10.1.1.1,1025 10.1.1.2,1025 +out on zx0 10.1.1.0 10.1.1.2 +out on zx0 10.1.1.1 10.1.2.1 +out on zx0 tcp 10.1.1.2,1025 10.1.1.1,1025 +out on zx0 tcp 10.1.1.2,1025 10.1.1.1,1025 +out on zx0 tcp 10.1.1.2,1026 10.1.1.1,1025 +out on zx0 udp 10.1.1.2,1025 10.1.1.1,1025 +out on zx0 tcp 10.1.1.3,2000 10.1.2.1,80 +out on zx0 tcp 10.1.1.3,2001 10.1.3.1,80 +out on zx0 tcp 10.1.1.3,2002 10.1.4.1,80 +out on zx0 tcp 10.1.1.3,2003 10.1.4.1,80 +in on zx0 10.1.1.1 10.1.1.2 +in on zx0 tcp 10.1.1.1,1025 10.1.1.2,1025 +in on zx0 10.1.1.2 10.1.1.1 +in on zx0 tcp 10.1.1.1,1026 10.3.4.5,40000 +in on zx0 tcp 10.1.1.1,1025 10.3.4.5,40000 +in on zx0 udp 10.1.1.2,1025 10.3.4.5,40001 +in on zx0 tcp 10.1.2.1,80 10.3.4.5,40001 diff --git a/contrib/netbsd-tests/ipf/input/n200 b/contrib/netbsd-tests/ipf/input/n200 new file mode 100644 index 0000000..9b02158 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n200 @@ -0,0 +1,6 @@ +[in,bar0] +4500 0028 0000 0000 0006 435a 6363 6363 5858 5858 038d 0050 0000 0000 0000 0000 5000 1000 2491 0000 + +[out,bar0] +4500 0044 0000 0000 ff11 bda6 7f00 0001 7f00 0001 2775 2775 0030 0000 4500 0028 0000 0000 0006 435a 6363 6363 5858 5858 038d 0050 0000 0000 0000 0000 5000 1000 2491 0000 + diff --git a/contrib/netbsd-tests/ipf/input/n2_6 b/contrib/netbsd-tests/ipf/input/n2_6 new file mode 100644 index 0000000..3ea74ff --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n2_6 @@ -0,0 +1,19 @@ +out6 on zx0 tcp 10:1:1::1,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::1,1025 10:1:1::2,1025 +out6 on zx0 10:1:1::0 10:1:1::2 +out6 on zx0 10:1:1::1 10:1:2::1 +out6 on zx0 tcp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::2,1026 10:1:1::1,1025 +out6 on zx0 udp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::3,2000 10:1:2::1,80 +out6 on zx0 tcp 10:1:1::3,2001 10:1:3::1,80 +out6 on zx0 tcp 10:1:1::3,2002 10:1:4::1,80 +out6 on zx0 tcp 10:1:1::3,2003 10:1:4::1,80 +in6 on zx0 10:1:1::1 10:1:1::2 +in6 on zx0 tcp 10:1:1::1,1025 10:1:1::2,1025 +in6 on zx0 10:1:1::2 10:1:1::1 +in6 on zx0 tcp 10:1:1::1,1026 10::3:4:5,40000 +in6 on zx0 tcp 10:1:1::1,1025 10::3:4:5,40000 +in6 on zx0 udp 10:1:1::2,1025 10::3:4:5,40001 +in6 on zx0 tcp 10:1:2::1,80 10::3:4:5,40001 diff --git a/contrib/netbsd-tests/ipf/input/n3 b/contrib/netbsd-tests/ipf/input/n3 new file mode 100644 index 0000000..deca317 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n3 @@ -0,0 +1,5 @@ +out on zz0 tcp 10.1.1.1,5000 203.1.1.1,80 +out on zz0 tcp 10.1.1.1,252 203.1.1.1,80 +out on zz0 tcp 10.1.0.0,32768 203.1.1.1,80 +out on zz0 udp 10.1.0.0,32768 203.1.1.1,80 +out on zz0 tcp 10.1.255.255,65535 203.1.1.1,80 diff --git a/contrib/netbsd-tests/ipf/input/n4 b/contrib/netbsd-tests/ipf/input/n4 new file mode 100644 index 0000000..1218ef9 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n4 @@ -0,0 +1,10 @@ +in on zx0 tcp 10.3.3.3,12345 10.1.1.1,23 +out on zx0 tcp 10.2.2.1,10023 10.3.3.3,12345 +in on zx0 tcp 10.3.3.3,12345 10.1.1.1,53 +out on zx0 tcp 10.2.2.1,10053 10.3.3.3,12345 +in on zx0 tcp 10.3.3.3,12346 10.1.0.0,23 +out on zx0 tcp 10.2.2.1,10023 10.3.3.3,12346 +in on zx0 udp 10.3.3.3,12345 10.1.1.0,53 +out on zx0 udp 10.2.2.1,10053 10.3.3.3,12345 +in on zx0 tcp 10.3.3.3,12345 10.1.1.0,53 +out on zx0 tcp 10.2.2.1,53 10.3.3.3,12345 diff --git a/contrib/netbsd-tests/ipf/input/n4_6 b/contrib/netbsd-tests/ipf/input/n4_6 new file mode 100644 index 0000000..8f0f423 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n4_6 @@ -0,0 +1,10 @@ +in6 on zx0 tcp 10:3:3::3,12345 10:1:1::1,23 +out6 on zx0 tcp 10::2:2:1,10023 10:3:3::3,12345 +in6 on zx0 tcp 10:3:3::3,12345 10:1:1::1,53 +out6 on zx0 tcp 10::2:2:1,10053 10:3:3::3,12345 +in6 on zx0 tcp 10:3:3::3,12346 10:1:0::0,23 +out6 on zx0 tcp 10::2:2:1,10023 10:3:3::3,12346 +in6 on zx0 udp 10:3:3::3,12345 10:1:1::0,53 +out6 on zx0 udp 10::2:2:1,10053 10:3:3::3,12345 +in6 on zx0 tcp 10:3:3::3,12345 10:1:1::0,53 +out6 on zx0 tcp 10::2:2:1,53 10:3:3::3,12345 diff --git a/contrib/netbsd-tests/ipf/input/n5 b/contrib/netbsd-tests/ipf/input/n5 new file mode 100644 index 0000000..579210b --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n5 @@ -0,0 +1,54 @@ +out on zx0 255 10.1.1.0 10.1.1.2 +out on zx0 255 10.1.1.1 10.1.1.2 +out on zx0 255 10.1.1.2 10.1.1.1 +out on zx0 tcp 10.1.1.2,1025 10.1.1.1,1025 +out on zx0 tcp 10.1.1.2,1026 10.1.1.1,1025 +out on zx0 255 10.2.2.1 10.1.2.1 +out on zx0 255 10.2.2.2 10.1.2.1 +in on zx0 255 10.1.1.1 10.1.1.2 +in on zx0 255 10.1.1.2 10.1.1.1 +in on zx0 255 10.2.2.1 10.2.1.1 +in on zx0 255 10.2.2.2 10.2.1.1 +in on zx0 255 10.2.2.3 10.1.1.1 +in on zx0 255 10.2.3.4 10.2.2.2 +in on zx0 255 10.1.1.1 10.2.2.2 +in on zx0 255 10.1.1.2 10.2.2.2 +in on zx0 255 10.1.1.0 10.3.4.5 +in on zx0 255 10.1.1.1 10.3.4.5 +in on zx0 255 10.1.1.2 10.3.4.5 +in on zx0 tcp 10.1.1.1,1025 10.3.4.5,1025 +out on zx0 icmp 10.1.1.1 10.4.3.2 +in on zx0 icmp 10.4.3.2 10.2.2.2 +in on zx0 icmp 10.4.3.2 10.3.4.3 +in on zx0 icmp 10.4.3.2 10.3.4.5 +out on zx0 34 10.1.1.2 10.4.3.2 +in on zx0 34 10.4.3.2 10.3.4.4 +out on zx0 34 10.1.1.2 10.4.3.4 +in on zx0 34 10.4.3.4 10.3.4.5 +out on zx0 34 10.1.1.3 10.4.3.4 +in on zx0 34 10.4.3.4 10.3.4.6 +out on zx0 35 10.1.1.3 10.4.3.4 +in on zx0 35 10.4.3.4 10.3.4.7 +out on zx0 tcp 10.1.1.1,1025 10.1.1.1,1025 +out on zx0 tcp 10.1.1.1,1025 10.1.1.2,1025 +out on zx0 10.1.1.0 10.1.1.2 +out on zx0 10.1.1.1 10.1.2.1 +out on zx0 tcp 10.1.1.2,1025 10.1.1.1,1025 +out on zx0 tcp 10.1.1.2,1025 10.1.1.1,1025 +out on zx0 tcp 10.1.1.2,1026 10.1.1.1,1025 +out on zx0 udp 10.1.1.2,1025 10.1.1.1,1025 +out on zx0 tcp 10.1.1.3,2000 10.1.2.1,80 +out on zx0 tcp 10.1.1.3,2001 10.1.3.1,80 +out on zx0 tcp 10.1.1.3,2002 10.1.4.1,80 +out on zx0 tcp 10.1.1.3,2003 10.1.4.1,80 +in on zx0 10.1.1.1 10.1.1.2 +in on zx0 tcp 10.1.1.1,1025 10.1.1.2,1025 +in on zx0 10.1.1.2 10.1.1.1 +out on zx0 tcp 10.1.1.1,1026 10.3.4.5,40000 +in on zx0 tcp 10.1.1.1,1026 10.3.4.5,40000 +out on zx0 tcp 10.1.1.1,1025 10.3.4.5,40000 +in on zx0 tcp 10.1.1.1,1025 10.3.4.5,40000 +out on zx0 udp 10.1.1.2,1025 10.3.4.5,40001 +in on zx0 udp 10.1.1.2,1025 10.3.4.5,40001 +out on zx0 tcp 10.1.2.1,80 10.3.4.5,40001 +in on zx0 tcp 10.1.2.1,80 10.3.4.5,40001 diff --git a/contrib/netbsd-tests/ipf/input/n5_6 b/contrib/netbsd-tests/ipf/input/n5_6 new file mode 100644 index 0000000..9ac0c29 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n5_6 @@ -0,0 +1,54 @@ +out6 on zx0 255 10:1:1::0 10:1:1::2 +out6 on zx0 255 10:1:1::1 10:1:1::2 +out6 on zx0 255 10:1:1::2 10:1:1::1 +out6 on zx0 tcp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::2,1026 10:1:1::1,1025 +out6 on zx0 255 10::2:2:1 10:1:2::1 +out6 on zx0 255 10::2:2:2 10:1:2::1 +in6 on zx0 255 10:1:1::1 10:1:1::2 +in6 on zx0 255 10:1:1::2 10:1:1::1 +in6 on zx0 255 10::2:2:1 10::2:1:1 +in6 on zx0 255 10::2:2:2 10::2:1:1 +in6 on zx0 255 10::2:2:3 10:1:1::1 +in6 on zx0 255 10::2:3:4 10::2:2:2 +in6 on zx0 255 10:1:1::1 10::2:2:2 +in6 on zx0 255 10:1:1::2 10::2:2:2 +in6 on zx0 255 10:1:1::0 10::3:4:5 +in6 on zx0 255 10:1:1::1 10::3:4:5 +in6 on zx0 255 10:1:1::2 10::3:4:5 +in6 on zx0 tcp 10:1:1::1,1025 10::3:4:5,1025 +out6 on zx0 58 10:1:1::1 10:4:3::2 +in6 on zx0 58 10:4:3::2 10::2:2:2 +in6 on zx0 58 10:4:3::2 10::3:4:3 +in6 on zx0 58 10:4:3::2 10::3:4:5 +out6 on zx0 34 10:1:1::2 10:4:3::2 +in6 on zx0 34 10:4:3::2 10::3:4:4 +out6 on zx0 34 10:1:1::2 10:4:3::4 +in6 on zx0 34 10:4:3::4 10::3:4:5 +out6 on zx0 34 10:1:1::3 10:4:3::4 +in6 on zx0 34 10:4:3::4 10::3:4:6 +out6 on zx0 35 10:1:1::3 10:4:3::4 +in6 on zx0 35 10:4:3::4 10::3:4:7 +out6 on zx0 tcp 10:1:1::1,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::1,1025 10:1:1::2,1025 +out6 on zx0 10:1:1::0 10:1:1::2 +out6 on zx0 10:1:1::1 10:1:2::1 +out6 on zx0 tcp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::2,1026 10:1:1::1,1025 +out6 on zx0 udp 10:1:1::2,1025 10:1:1::1,1025 +out6 on zx0 tcp 10:1:1::3,2000 10:1:2::1,80 +out6 on zx0 tcp 10:1:1::3,2001 10:1:3::1,80 +out6 on zx0 tcp 10:1:1::3,2002 10:1:4::1,80 +out6 on zx0 tcp 10:1:1::3,2003 10:1:4::1,80 +in6 on zx0 10:1:1::1 10:1:1::2 +in6 on zx0 tcp 10:1:1::1,1025 10:1:1::2,1025 +in6 on zx0 10:1:1::2 10:1:1::1 +out6 on zx0 tcp 10:1:1::1,1026 10::3:4:5,40000 +in6 on zx0 tcp 10:1:1::1,1026 10::3:4:5,40000 +out6 on zx0 tcp 10:1:1::1,1025 10::3:4:5,40000 +in6 on zx0 tcp 10:1:1::1,1025 10::3:4:5,40000 +out6 on zx0 udp 10:1:1::2,1025 10::3:4:5,40001 +in6 on zx0 udp 10:1:1::2,1025 10::3:4:5,40001 +out6 on zx0 tcp 10:1:2::1,80 10::3:4:5,40001 +in6 on zx0 tcp 10:1:2::1,80 10::3:4:5,40001 diff --git a/contrib/netbsd-tests/ipf/input/n6 b/contrib/netbsd-tests/ipf/input/n6 new file mode 100644 index 0000000..8a0c924 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n6 @@ -0,0 +1,13 @@ +in on zx0 tcp 10.2.2.2,12345 10.1.1.1,23 +in on zx0 tcp 10.2.2.2,12345 10.1.1.2,23 +in on zx0 tcp 10.3.0.1,12345 10.1.2.2,23 +in on zx0 tcp 10.3.0.1,12345 10.2.2.2,23 +in on zx0 tcp 10.3.3.3,12345 10.1.1.1,23 +in on zx0 tcp 10.2.2.2,12345 10.1.1.1,53 +in on zx0 tcp 10.3.3.3,12345 10.1.1.1,53 +in on zx0 tcp 10.2.2.2,12345 10.1.0.0,23 +in on zx0 tcp 10.3.3.3,12345 10.1.0.0,23 +in on zx0 udp 10.2.2.2,12345 10.1.1.0,53 +in on zx0 udp 10.3.3.3,12345 10.1.1.0,53 +in on zx0 tcp 10.2.2.2,12345 10.1.1.0,53 +in on zx0 tcp 10.3.3.3,12345 10.1.1.0,53 diff --git a/contrib/netbsd-tests/ipf/input/n6_6 b/contrib/netbsd-tests/ipf/input/n6_6 new file mode 100644 index 0000000..18300cd --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n6_6 @@ -0,0 +1,13 @@ +in6 on zx0 tcp 10::2:2:2,12345 10:1:1::1,23 +in6 on zx0 tcp 10::2:2:2,12345 10:1:1::2,23 +in6 on zx0 tcp 10:3:0::1,12345 10:1:2::2,23 +in6 on zx0 tcp 10:3:0::1,12345 10::2:2:2,23 +in6 on zx0 tcp 10:3:3::3,12345 10:1:1::1,23 +in6 on zx0 tcp 10::2:2:2,12345 10:1:1::1,53 +in6 on zx0 tcp 10:3:3::3,12345 10:1:1::1,53 +in6 on zx0 tcp 10::2:2:2,12345 10:1:0::0,23 +in6 on zx0 tcp 10:3:3::3,12345 10:1:0::0,23 +in6 on zx0 udp 10::2:2:2,12345 10:1:1::0,53 +in6 on zx0 udp 10:3:3::3,12345 10:1:1::0,53 +in6 on zx0 tcp 10::2:2:2,12345 10:1:1::0,53 +in6 on zx0 tcp 10:3:3::3,12345 10:1:1::0,53 diff --git a/contrib/netbsd-tests/ipf/input/n7 b/contrib/netbsd-tests/ipf/input/n7 new file mode 100644 index 0000000..79af901 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n7 @@ -0,0 +1,9 @@ +in on zx0 tcp 10.2.3.1,1230 10.1.1.1,22 +in on zx0 tcp 10.2.3.1,1231 10.1.1.1,23 +in on zx0 tcp 10.2.3.1,1232 10.1.1.1,50 +in on zx0 tcp 10.2.3.1,1233 10.1.1.1,79 +in on zx0 tcp 10.2.3.1,1234 10.1.1.1,80 +in on zx0 tcp 10.2.3.1,1235 10.1.1.2,80 +in on zx0 tcp 10.2.3.1,1236 10.1.1.3,80 +in on zx0 tcp 10.2.3.1,1237 10.1.1.4,80 +in on zx0 tcp 10.2.3.1,1238 10.1.1.4,80 diff --git a/contrib/netbsd-tests/ipf/input/n7_6 b/contrib/netbsd-tests/ipf/input/n7_6 new file mode 100644 index 0000000..b31a1de --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n7_6 @@ -0,0 +1,9 @@ +in6 on zx0 tcp 10::2:3:1,1230 10:1:1::1,22 +in6 on zx0 tcp 10::2:3:1,1231 10:1:1::1,23 +in6 on zx0 tcp 10::2:3:1,1232 10:1:1::1,50 +in6 on zx0 tcp 10::2:3:1,1233 10:1:1::1,79 +in6 on zx0 tcp 10::2:3:1,1234 10:1:1::1,80 +in6 on zx0 tcp 10::2:3:1,1235 10:1:1::2,80 +in6 on zx0 tcp 10::2:3:1,1236 10:1:1::3,80 +in6 on zx0 tcp 10::2:3:1,1237 10:1:1::4,80 +in6 on zx0 tcp 10::2:3:1,1238 10:1:1::4,80 diff --git a/contrib/netbsd-tests/ipf/input/n8 b/contrib/netbsd-tests/ipf/input/n8 new file mode 100644 index 0000000..c0a5b3f --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n8 @@ -0,0 +1,34 @@ +#v tos len id off ttl p sum src dst +# ICMP ECHO (ping) exchange +[out,icmp0] +4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 +0800 efdf 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[in,icmp0] +4500 0054 3fd5 4000 ff01 1fc1 0404 0404 0a0a 0a01 +0000 f7df 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[out,icmp0] +4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 +0800 efde 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[in,icmp0] +4500 0054 3fd5 4000 ff01 1fc1 0404 0404 0a0a 0a01 +0000 f7de 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + diff --git a/contrib/netbsd-tests/ipf/input/n8_6 b/contrib/netbsd-tests/ipf/input/n8_6 new file mode 100644 index 0000000..8039f78 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n8_6 @@ -0,0 +1,37 @@ +#v tos len id off ttl p sum src dst +# ICMP ECHO (ping) exchange +[out,icmp0] +6000 0000 0040 3aff 0002 0000 0000 0000 0000 0002 0002 0002 0004 0004 0004 0000 0000 0000 0000 0004 +8000 774d 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +# ECHO reply +[in,icmp0] +6000 0000 0040 3aff 0004 0004 0004 0000 0000 0000 0000 0004 0010 0010 0010 0000 0000 0000 0000 0001 +8100 7624 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +# ECHO request +[out,icmp0] +6000 0000 0040 3aff 0002 0000 0000 0000 0000 0002 0002 0002 0004 0004 0004 0000 0000 0000 0000 0004 +8000 774c 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +# ECHO reply +[in,icmp0] +6000 0000 0040 3aff 0004 0004 0004 0000 0000 0000 0000 0004 0010 0010 0010 0000 0000 0000 0000 0001 +8100 7623 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + diff --git a/contrib/netbsd-tests/ipf/input/n9 b/contrib/netbsd-tests/ipf/input/n9 new file mode 100644 index 0000000..5c2d3c7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n9 @@ -0,0 +1,34 @@ +#v tos len id off ttl p sum src dst +# ICMP ECHO (ping) exchange +[in,icmp0] +4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 +0800 efdf 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[out,icmp0] +4500 0054 3fd5 4000 ff01 23c5 0a0a 0a01 0202 0202 +0000 f7df 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[in,icmp0] +4500 0054 8bc1 0000 ff01 23dc 0202 0202 0404 0404 +0800 efde 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[out,icmp0] +4500 0054 3fd5 4000 ff01 23c5 0a0a 0a01 0202 0202 +0000 f7de 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + diff --git a/contrib/netbsd-tests/ipf/input/n9_6 b/contrib/netbsd-tests/ipf/input/n9_6 new file mode 100644 index 0000000..42db09d --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/n9_6 @@ -0,0 +1,34 @@ +#v tos len id off ttl p sum src dst +# ICMP ECHO (ping) exchange +[in,icmp0] +6000 0000 0040 3aff 0002 0000 0000 0000 0000 0002 0002 0002 0004 0004 0004 0000 0000 0000 0000 0004 +8000 774d 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[out,icmp0] +6000 0000 0040 3aff 0010 0010 0010 0000 0000 0000 0000 0001 0002 0000 0000 0000 0000 0002 0002 0002 +8100 762c 6220 0000 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[in,icmp0] +6000 0000 0040 3aff 0002 0000 0000 0000 0000 0002 0002 0002 0004 0004 0004 0000 0000 0000 0000 0004 +8000 774c 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + +[out,icmp0] +6000 0000 0040 3aff 0010 0010 0010 0000 0000 0000 0000 0001 0002 0000 0000 0000 0000 0002 0002 0002 +8100 762b 6220 0001 3f6f 6e80 000b +0d02 0809 0a0b 0c0d 0e0f 1011 1213 1415 +1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 +2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 +3637 + diff --git a/contrib/netbsd-tests/ipf/input/ni1 b/contrib/netbsd-tests/ipf/input/ni1 new file mode 100644 index 0000000..519325f --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni1 @@ -0,0 +1,59 @@ +#v tos len id off ttl p sum src dst +# ICMP timeout exceeded in reply to a ICMP packet going out. +# 2.2.2.2,44489 -> 4.4.4.4,33438 +[out,df0] +4500 0028 4706 4000 0111 26b4 0202 0202 0404 0404 +afc9 829e 0014 6b10 +0402 0000 3be5 468d 000a cfc3 + +[in,df0] +4500 0038 809a 0000 ff01 2919 0303 0303 0606 0606 +0b00 5f7b 0000 0000 +4500 0028 0000 4000 0111 65b2 0606 0606 0404 0404 +afc9 829e 0014 6308 + +[in,df0] +4500 0044 809a 0000 ff01 290d 0303 0303 0606 0606 +0b00 0939 0000 0000 +4500 0028 0000 4000 0111 65b2 0606 0606 0404 0404 +afc9 829e 0014 6308 +0402 0000 3be5 468d 000a cfc3 + +# 2.2.2.2,2048 -> 4.4.4.4,33438 +[out,df0] +4500 0028 4706 4000 0111 26b4 0202 0202 0404 0404 +0800 829e 0014 12da +0402 0000 3be5 468d 000a cfc3 + +[in,df0] +4500 0038 809a 0000 ff01 2918 0303 0303 0606 0607 +0b00 5f7c 0000 0000 +4500 0028 0000 4000 0111 65b1 0606 0607 0404 0404 +4e20 829e 0014 c4b0 + +[in,df0] +4500 0044 809a 0000 ff01 290c 0303 0303 0606 0607 +0b00 093a 0000 0000 +4500 0028 0000 4000 0111 65b1 0606 0607 0404 0404 +4e20 829e 0014 c4b0 +0402 0000 3be5 468d 000a cfc3 + +# 2.2.2.2,20480 -> 4.4.4.4,33438 +[out,df0] +4500 0028 4706 4000 0111 26b4 0202 0202 0404 0404 +5000 829e 0014 cad9 +0402 0000 3be5 468d 000a cfc3 + +[in,df0] +4500 0038 809a 0000 ff01 2917 0303 0303 0606 0608 +0b00 0775 0000 0000 +4500 0028 0000 4000 0111 65b0 0606 0608 0404 0404 +07d0 829e 0014 6308 + +[in,df0] +4500 0044 809a 0000 ff01 290b 0303 0303 0606 0608 +0b00 093b 0000 0000 +4500 0028 0000 4000 0111 65b0 0606 0608 0404 0404 +07d0 829e 0014 0b00 +0402 0000 3be5 468d 000a cfc3 + diff --git a/contrib/netbsd-tests/ipf/input/ni10 b/contrib/netbsd-tests/ipf/input/ni10 new file mode 100644 index 0000000..636c4f1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni10 @@ -0,0 +1,29 @@ +#v tos len id off ttl p sum src dst +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going out) +# IP 4.4.4.4 2.2.2.2 TCP(20480,80) +[in,df0] +4500 003c 4706 4000 ff06 28aa 0404 0404 0202 0202 +5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) +[out,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 +0303 acab 0000 0000 +4500 003c 4706 4000 ff06 20a2 0404 0404 0606 0606 +5000 0050 0000 0001 + +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[out,df0] +4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 +0303 113f 0000 0000 +4500 003c 4706 4000 ff06 20a2 0404 0404 0606 0606 +5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +# IP 3.3.3.3 -> 4.4.4.4 ICMP (IP(4.4.4.4,6.6.6.6) TCP(20480,80)) +[out,df0] +4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 +0303 acab 0000 0000 +4500 003c 4706 4000 ff06 28ab 0404 0404 0202 0201 5000 0050 0000 0001 + diff --git a/contrib/netbsd-tests/ipf/input/ni11 b/contrib/netbsd-tests/ipf/input/ni11 new file mode 100644 index 0000000..0650abb --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni11 @@ -0,0 +1,26 @@ +#v tos len id off ttl p sum src dst +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going out) +[in,df0] +4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 +5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +[out,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 +0303 0fa3 0000 0000 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 +5000 9d58 0000 0001 + +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[out,df0] +4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 +0303 0735 0000 0000 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 +5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 +0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +[out,df0] +4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 +0303 0fa3 0000 0000 +4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9d58 0000 0001 + diff --git a/contrib/netbsd-tests/ipf/input/ni12 b/contrib/netbsd-tests/ipf/input/ni12 new file mode 100644 index 0000000..c44aacc --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni12 @@ -0,0 +1,26 @@ +#v tos len id off ttl p sum src dst +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going out) +[in,df0] +4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 +5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +[out,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 +0303 10bb 0000 0000 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 +5000 9c40 0000 0001 + +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[out,df0] +4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 +0303 0735 0000 0000 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 +5000 9c40 0000 0001 0000 0000 a002 16d0 3ef4 0000 +0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +[out,df0] +4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 +0303 10bb 0000 0000 +4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 5000 9c40 0000 0001 + diff --git a/contrib/netbsd-tests/ipf/input/ni13 b/contrib/netbsd-tests/ipf/input/ni13 new file mode 100644 index 0000000..70c1952 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni13 @@ -0,0 +1,231 @@ +# 23:18:36.130424 192.168.113.1.1511 > 192.168.113.3.1723: S 2884651685:2884651685(0) win 64240 (DF) +[in,pcn1=192.168.113.3] +4500 0030 5e11 4000 8006 3961 c0a8 7101 c0a8 7103 +05e7 06bb abf0 4aa5 0000 0000 7002 faf0 21a1 0000 0204 05b4 0101 0402 + +# 23:18:36.130778 192.168.113.3.1723 > 192.168.113.1.1511: S 2774821082:2774821082(0) ack 2884651686 win 32768 (DF) +[out,pcn1] +4500 002c 69a6 4000 4006 6dd0 c0a8 7103 c0a8 7101 +06bb 05e7 a564 68da abf0 4aa6 6012 8000 a348 0000 0204 05b4 + +# 23:18:36.130784 192.168.113.1.1511 > 192.168.113.3.1723: P 1:157(156) ack 1 win 64240: pptp CTRL_MSGTYPE=SCCRQ PROTO_VER(1.0) FRAME_CAP(A) BEARER_CAP(A) MAX_CHAN(0) FIRM_REV(2600) HOSTNAME() VENDOR(Microsoft Windows NT) (DF) +[in,pcn1] +4500 00c4 5e12 4000 8006 38cc c0a8 7101 c0a8 7103 +05e7 06bb abf0 4aa6 a564 68db +5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d +0001 0000 0100 0000 0000 0001 0000 0001 +0000 0a28 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 4d69 6372 6f73 6f66 7420 5769 +6e64 6f77 7320 4e54 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260235 192.168.113.3.1723 > 192.168.113.1.1511: P 1:157(156) ack 157 win 33580: pptp CTRL_MSGTYPE=SCCRP PROTO_VER(1.0) RESULT_CODE(1) ERR_CODE(0) FRAME_CAP() BEARER_CAP() MAX_CHAN(1) FIRM_REV(1) HOSTNAME(local) VENDOR(linux) (DF) +[out,pcn1] +4500 00c4 69a7 4000 4006 6d37 c0a8 7103 c0a8 7101 +06bb 05e7 a564 68db abf0 4b42 +5018 832c cecf 0000 009c 0001 1a2b 3c4d +0002 0000 0100 0100 0000 0000 0000 0000 +0001 0001 6c6f 6361 6c00 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 6c69 6e75 7800 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260252 192.168.113.1.1511 > 192.168.113.3.1723: P 157:325(168) ack 157 win 64084: pptp CTRL_MSGTYPE=OCRQ CALL_ID(16384) CALL_SER_NUM(4913) MIN_BPS(300) MAX_BPS(100000000) BEARER_TYPE(Any) FRAME_TYPE(E) RECV_WIN(64) PROC_DELAY(0) PHONE_NO_LEN(0) PHONE_NO() SUB_ADDR() (DF) +[in,pcn1] +4500 00d0 5e13 4000 8006 38bf c0a8 7101 c0a8 7103 +05e7 06bb abf0 4b42 a564 6977 +5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d +0007 0000 4000 1331 0000 012c 05f5 e100 +0000 0003 0000 0003 0040 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 + +# 23:18:36.272856 192.168.113.3.1723 > 192.168.113.1.1511: P 157:189(32) ack 325 win 33580: pptp CTRL_MSGTYPE=OCRP CALL_ID(0) PEER_CALL_ID(16384) RESULT_CODE(1) ERR_CODE(0) CAUSE_CODE(0) CONN_SPEED(100000000) RECV_WIN(64) PROC_DELAY(0) PHY_CHAN_ID(0) (DF) +[out,pcn1] +4500 0048 69a8 4000 4006 6db2 c0a8 7103 c0a8 7101 +06bb 05e7 a564 6977 abf0 4bea +5018 832c 36fa 0000 0020 0001 1a2b 3c4d +0008 0000 0000 4000 0100 0000 05f5 e100 +0040 0000 0000 0000 + +# 23:18:36.321819 192.168.113.1.1511 > 192.168.113.3.1723: P 325:349(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0xffffffff) RECV_ACCM(0xffffffff) (DF) +[in,pcn1] +4500 0040 5e14 4000 8006 394e c0a8 7101 c0a8 7103 +05e7 06bb abf0 4bea a564 6997 +5018 fa34 e810 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 ffff ffff ffff ffff + +# 23:18:36.349759 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:0 ppp: LCP 25: Conf-Req(0), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC, Call-Back CBCP +[in,pcn1] +4500 0039 5e15 0000 802f 792b c0a8 7101 c0a8 7103 +3001 880b 0019 0000 0000 0000 +ff03 c021 0100 0015 0104 0578 0506 577f +7c5b 0702 0802 0d03 06 + +# 23:18:36.389970 192.168.113.3 > 192.168.113.1: gre [KAv1] ID:4000 A:4294967295 [|gre] +[out,pcn1] +4500 0020 69a9 0000 ff2f eeaf c0a8 7103 c0a8 7101 +2081 880b 0000 4000 ffff ffff + +# 23:18:36.518426 192.168.113.3.1723 > 192.168.113.1.1511: . ack 349 win 33580 (DF) +[out,pcn1] +4500 0028 69aa 4000 4006 6dd0 c0a8 7103 c0a8 7101 +06bb 05e7 a564 6997 abf0 4c02 5010 832c b5c1 0000 + +# 23:18:36.555363 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:0 ppp: LCP 24: Conf-Req(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[out,pcn1] +4500 0038 69ab 0000 ff2f ee95 c0a8 7103 c0a8 7101 +3001 880b 0018 4000 0000 0000 +ff03 c021 0101 0014 0206 0000 0000 0506 +22d9 0cfa 0702 0802 + +# 23:18:36.556030 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:1 A:0 ppp: LCP 11: Conf-Rej(0), Call-Back CBCP +[out,pcn1] +4500 002f 69ac 0000 ff2f ee9d c0a8 7103 c0a8 7101 +3081 880b 000b 4000 0000 0001 0000 0000 ff03 c021 0400 0007 0d03 06 + +# 23:18:36.557166 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:1 A:1 ppp: LCP 24: Conf-Ack(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[in,pcn1] +4500 003c 5e16 0000 802f 7927 c0a8 7101 c0a8 7103 +3081 880b 0018 0000 0000 0001 +0000 0001 ff03 c021 0201 0014 0206 0000 +0000 0506 22d9 0cfa 0702 0802 + +# 23:18:36.557764 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:2 ppp: LCP 22: Conf-Req(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[in,pcn1] +4500 0036 5e17 0000 802f 792c c0a8 7101 c0a8 7103 +3001 880b 0016 0000 0000 0002 +ff03 c021 0101 0012 0104 0578 0506 577f +7c5b 0702 0802 + +# 23:18:36.564658 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:2 A:2 ppp: LCP 22: Conf-Ack(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[out,pcn1] +4500 003a 69ad 0000 ff2f ee91 c0a8 7103 c0a8 7101 +3081 880b 0016 4000 0000 0002 +0000 0002 ff03 c021 0201 0012 0104 0578 +0506 577f 7c5b 0702 0802 + +# 23:18:36.564803 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:3 ppp: IPCP 18: Conf-Req(1), IP-Addr=192.168.0.1, IP-Comp VJ-Comp +[out,pcn1] +4500 0032 69ae 0000 ff2f ee98 c0a8 7103 c0a8 7101 +3001 880b 0012 4000 0000 0003 +8021 0101 0010 0306 c0a8 0001 0206 002d +0f01 + +# 23:18:36.570395 192.168.113.1.1511 > 192.168.113.3.1723: P 349:373(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0x00000000) RECV_ACCM(0xffffffff) (DF) +[in,pcn1] +4500 0040 5e18 4000 8006 394a c0a8 7101 c0a8 7103 +05e7 06bb abf0 4c02 a564 6997 +5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 0000 0000 ffff ffff + +# 23:18:36.573307 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:3 A:3 ppp: LCP 20: Ident(2), Magic-Num=577f7c5b +[in,pcn1] +4500 0038 5e19 0000 802f 7928 c0a8 7101 c0a8 7103 +3081 880b 0014 0000 0000 0003 +0000 0003 c021 0c02 0012 577f 7c5b 4d53 +5241 5356 352e 3130 + +# 23:18:36.573856 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:4 A:3 ppp: LCP 26: Code-Rej(2) +[out,pcn1] +4500 003e 69af 0000 ff2f ee8b c0a8 7103 c0a8 7101 +3081 880b 001a 4000 0000 0004 +0000 0003 ff03 c021 0702 0016 0c02 0012 +577f 7c5b 4d53 5241 5356 352e 3130 + +# 23:18:36.584936 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:4 A:4 ppp: LCP 26: Ident(3), Magic-Num=577f7c5b +[in,pcn1] +4500 003e 5e1a 0000 802f 7921 c0a8 7101 c0a8 7103 +3081 880b 001a 0000 0000 0004 +0000 0004 c021 0c03 0018 577f 7c5b 4d53 +5241 532d 302d 434c 4159 4d4f 4f52 + +# 23:18:36.585562 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:5 A:4 ppp: LCP 32: Code-Rej(3) +[out,pcn1] +4500 0044 69b0 0000 ff2f ee84 c0a8 7103 c0a8 7101 +3081 880b 0020 4000 0000 0005 +0000 0004 ff03 c021 0703 001c 0c03 0018 +577f 7c5b 4d53 5241 532d 302d 434c 4159 +4d4f 4f52 + +# 23:18:36.588721 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:5 A:5 ppp: CCP 12: Conf-Req(4), MPPC +[in,pcn1] +4500 0030 5e1b 0000 802f 792e c0a8 7101 c0a8 7103 +3081 880b 000c 0000 0000 0005 +0000 0005 80fd 0104 000a 1206 0100 0001 + +# 23:18:36.589445 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:6 A:5 ppp: CCP 6: Conf-Req(1) +[out,pcn1] +4500 002a 69b1 0000 ff2f ee9d c0a8 7103 c0a8 7101 +3081 880b 0006 4000 0000 0006 +0000 0005 80fd 0101 0004 + +# 23:18:36.589540 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:7 ppp: CCP 12: Conf-Rej(4), MPPC +[out,pcn1] +4500 002c 69b2 0000 ff2f ee9a c0a8 7103 c0a8 7101 +3001 880b 000c 4000 0000 0007 +80fd 0404 000a 1206 0100 0001 + +# 23:18:36.590023 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:6 A:7 ppp: IPCP 36: Conf-Req(5), IP-Addr=0.0.0.0, Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[in,pcn1] +4500 0048 5e1c 0000 802f 7915 c0a8 7101 c0a8 7103 +3081 880b 0024 0000 0000 0006 +0000 0007 8021 0105 0022 0306 0000 0000 +8106 0000 0000 8206 0000 0000 8306 0000 +0000 8406 0000 0000 + +# 23:18:36.590489 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:8 A:6 ppp: IPCP 30: Conf-Rej(5), Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[out,pcn1] +4500 0042 69b3 0000 ff2f ee83 c0a8 7103 c0a8 7101 +3081 880b 001e 4000 0000 0008 +0000 0006 8021 0405 001c 8106 0000 0000 +8206 0000 0000 8306 0000 0000 8406 0000 +0000 + +# 23:18:36.591003 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:7 A:8 ppp: IPCP 12: Conf-Rej(1), IP-Comp VJ-Comp +[in,pcn1] +4500 0030 5e1d 0000 802f 792c c0a8 7101 c0a8 7103 +3081 880b 000c 0000 0000 0007 +0000 0008 8021 0401 000a 0206 002d 0f01 + +# 23:18:36.593819 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:9 A:7 ppp: IPCP 12: Conf-Req(2), IP-Addr=192.168.0.1 +[out,pcn1] +4500 0030 69b4 0000 ff2f ee94 c0a8 7103 c0a8 7101 +3081 880b 000c 4000 0000 0009 +0000 0007 8021 0102 000a 0306 c0a8 0001 + +# 23:18:36.594840 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:8 A:9 ppp: CCP 6: Conf-Ack(1) +[in,pcn1] +4500 002a 5e1e 0000 802f 7931 c0a8 7101 c0a8 7103 +3081 880b 0006 0000 0000 0008 +0000 0009 80fd 0201 0004 + +# 23:18:36.595525 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:9 ppp: CCP 18: Term-Req(6) +[in,pcn1] +4500 0032 5e1f 0000 802f 7928 c0a8 7101 c0a8 7103 +3001 880b 0012 0000 0000 0009 +80fd 0506 0010 577f 7c5b 003c cd74 0000 +02dc + +# 23:18:36.595937 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:10 A:9 ppp: CCP 6: Term-Ack(6) +[out,pcn1] +4500 002a 69b5 0000 ff2f ee99 c0a8 7103 c0a8 7101 +3081 880b 0006 4000 0000 000a +0000 0009 80fd 0606 0004 + diff --git a/contrib/netbsd-tests/ipf/input/ni14 b/contrib/netbsd-tests/ipf/input/ni14 new file mode 100644 index 0000000..6bc1276 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni14 @@ -0,0 +1,235 @@ +# 23:18:36.130424 192.168.113.1.1511 > 192.168.113.3.1723: S 2884651685:2884651685(0) win 64240 (DF) +[in,pcn1=192.168.113.3] +4500 0030 5e11 4000 8006 3961 c0a8 7101 c0a8 7103 +05e7 06bb abf0 4aa5 0000 0000 +7002 faf0 21a1 0000 0204 05b4 0101 0402 + +# 23:18:36.130778 192.168.113.3.1723 > 192.168.113.1.1511: S 2774821082:2774821082(0) ack 2884651686 win 32768 (DF) +[out,pcn1] +4500 002c 69a6 4000 4006 207b 7f00 0001 c0a8 7101 +06bb 05e7 a564 68da abf0 4aa6 +6012 8000 55f3 0000 0204 05b4 + +# 23:18:36.130784 192.168.113.1.1511 > 192.168.113.3.1723: P 1:157(156) ack 1 win 64240: pptp CTRL_MSGTYPE=SCCRQ PROTO_VER(1.0) FRAME_CAP(A) BEARER_CAP(A) MAX_CHAN(0) FIRM_REV(2600) HOSTNAME() VENDOR(Microsoft Windows NT) (DF) +[in,pcn1] +4500 00c4 5e12 4000 8006 38cc c0a8 7101 c0a8 7103 +05e7 06bb abf0 4aa6 a564 68db +5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d +0001 0000 0100 0000 0000 0001 0000 0001 +0000 0a28 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 4d69 6372 6f73 6f66 7420 5769 +6e64 6f77 7320 4e54 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260235 192.168.113.3.1723 > 192.168.113.1.1511: P 1:157(156) ack 157 win 33580: pptp CTRL_MSGTYPE=SCCRP PROTO_VER(1.0) RESULT_CODE(1) ERR_CODE(0) FRAME_CAP() BEARER_CAP() MAX_CHAN(1) FIRM_REV(1) HOSTNAME(local) VENDOR(linux) (DF) +[out,pcn1] +4500 00c4 69a7 4000 4006 1fe2 7f00 0001 c0a8 7101 +06bb 05e7 a564 68db abf0 4b42 +5018 832c 817a 0000 009c 0001 1a2b 3c4d +0002 0000 0100 0100 0000 0000 0000 0000 +0001 0001 6c6f 6361 6c00 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 6c69 6e75 7800 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260252 192.168.113.1.1511 > 192.168.113.3.1723: P 157:325(168) ack 157 win 64084: pptp CTRL_MSGTYPE=OCRQ CALL_ID(16384) CALL_SER_NUM(4913) MIN_BPS(300) MAX_BPS(100000000) BEARER_TYPE(Any) FRAME_TYPE(E) RECV_WIN(64) PROC_DELAY(0) PHONE_NO_LEN(0) PHONE_NO() SUB_ADDR() (DF) +[in,pcn1] +4500 00d0 5e13 4000 8006 38bf c0a8 7101 c0a8 7103 +05e7 06bb abf0 4b42 a564 6977 +5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d +0007 0000 4000 1331 0000 012c 05f5 e100 +0000 0003 0000 0003 0040 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 + +# 23:18:36.272856 192.168.113.3.1723 > 192.168.113.1.1511: P 157:189(32) ack 325 win 33580: pptp CTRL_MSGTYPE=OCRP CALL_ID(0) PEER_CALL_ID(16384) RESULT_CODE(1) ERR_CODE(0) CAUSE_CODE(0) CONN_SPEED(100000000) RECV_WIN(64) PROC_DELAY(0) PHY_CHAN_ID(0) (DF) +[out,pcn1] +4500 0048 69a8 4000 4006 205d 7f00 0001 c0a8 7101 +06bb 05e7 a564 6977 abf0 4bea +5018 832c e9a4 0000 0020 0001 1a2b 3c4d +0008 0000 0000 4000 0100 0000 05f5 e100 +0040 0000 0000 0000 + +# 23:18:36.321819 192.168.113.1.1511 > 192.168.113.3.1723: P 325:349(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0xffffffff) RECV_ACCM(0xffffffff) (DF) +[in,pcn1] +4500 0040 5e14 4000 8006 394e c0a8 7101 c0a8 7103 +05e7 06bb abf0 4bea a564 6997 +5018 fa34 e810 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 ffff ffff ffff ffff + +# 23:18:36.349759 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:0 ppp: LCP 25: Conf-Req(0), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC, Call-Back CBCP +[in,pcn1] +4500 0039 5e15 0000 802f 792b c0a8 7101 c0a8 7103 +3001 880b 0019 0000 0000 0000 +ff03 c021 0100 0015 0104 0578 0506 577f +7c5b 0702 0802 0d03 06 + +# 23:18:36.389970 192.168.113.3 > 192.168.113.1: gre [KAv1] ID:4000 A:4294967295 [|gre] +[out,pcn1] +4500 0020 69a9 0000 ff2f a15a 7f00 0001 c0a8 7101 +2081 880b 0000 4000 ffff ffff + +# 23:18:36.518426 192.168.113.3.1723 > 192.168.113.1.1511: . ack 349 win 33580 (DF) +[out,pcn1] +4500 0028 69aa 4000 4006 207b 7f00 0001 c0a8 7101 +06bb 05e7 a564 6997 abf0 4c02 +5010 832c 686c 0000 + +# 23:18:36.555363 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:0 ppp: LCP 24: Conf-Req(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[out,pcn1] +4500 0038 69ab 0000 ff2f a140 7f00 0001 c0a8 7101 +3001 880b 0018 4000 0000 0000 +ff03 c021 0101 0014 0206 0000 0000 0506 +22d9 0cfa 0702 0802 + +# 23:18:36.556030 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:1 A:0 ppp: LCP 11: Conf-Rej(0), Call-Back CBCP +[out,pcn1] +4500 002f 69ac 0000 ff2f a148 7f00 0001 c0a8 7101 +3081 880b 000b 4000 0000 0001 +0000 0000 ff03 c021 0400 0007 0d03 06 + +# 23:18:36.557166 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:1 A:1 ppp: LCP 24: Conf-Ack(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[in,pcn1] +4500 003c 5e16 0000 802f 7927 c0a8 7101 c0a8 7103 +3081 880b 0018 0000 0000 0001 +0000 0001 ff03 c021 0201 0014 0206 0000 +0000 0506 22d9 0cfa 0702 0802 + +# 23:18:36.557764 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:2 ppp: LCP 22: Conf-Req(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[in,pcn1] +4500 0036 5e17 0000 802f 792c c0a8 7101 c0a8 7103 +3001 880b 0016 0000 0000 0002 +ff03 c021 0101 0012 0104 0578 0506 577f +7c5b 0702 0802 + +# 23:18:36.564658 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:2 A:2 ppp: LCP 22: Conf-Ack(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[out,pcn1] +4500 003a 69ad 0000 ff2f a13c 7f00 0001 c0a8 7101 +3081 880b 0016 4000 0000 0002 +0000 0002 ff03 c021 0201 0012 0104 0578 +0506 577f 7c5b 0702 0802 + +# 23:18:36.564803 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:3 ppp: IPCP 18: Conf-Req(1), IP-Addr=192.168.0.1, IP-Comp VJ-Comp +[out,pcn1] +4500 0032 69ae 0000 ff2f a143 7f00 0001 c0a8 7101 +3001 880b 0012 4000 0000 0003 +8021 0101 0010 0306 c0a8 0001 0206 002d +0f01 + +# 23:18:36.570395 192.168.113.1.1511 > 192.168.113.3.1723: P 349:373(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0x00000000) RECV_ACCM(0xffffffff) (DF) +[in,pcn1] +4500 0040 5e18 4000 8006 394a c0a8 7101 c0a8 7103 +05e7 06bb abf0 4c02 a564 6997 +5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 0000 0000 ffff ffff + +# 23:18:36.573307 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:3 A:3 ppp: LCP 20: Ident(2), Magic-Num=577f7c5b +[in,pcn1] +4500 0038 5e19 0000 802f 7928 c0a8 7101 c0a8 7103 +3081 880b 0014 0000 0000 0003 +0000 0003 c021 0c02 0012 577f 7c5b 4d53 +5241 5356 352e 3130 + +# 23:18:36.573856 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:4 A:3 ppp: LCP 26: Code-Rej(2) +[out,pcn1] +4500 003e 69af 0000 ff2f a136 7f00 0001 c0a8 7101 +3081 880b 001a 4000 0000 0004 +0000 0003 ff03 c021 0702 0016 0c02 0012 +577f 7c5b 4d53 5241 5356 352e 3130 + +# 23:18:36.584936 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:4 A:4 ppp: LCP 26: Ident(3), Magic-Num=577f7c5b +[in,pcn1] +4500 003e 5e1a 0000 802f 7921 c0a8 7101 c0a8 7103 +3081 880b 001a 0000 0000 0004 +0000 0004 c021 0c03 0018 577f 7c5b 4d53 +5241 532d 302d 434c 4159 4d4f 4f52 + +# 23:18:36.585562 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:5 A:4 ppp: LCP 32: Code-Rej(3) +[out,pcn1] +4500 0044 69b0 0000 ff2f a12f 7f00 0001 c0a8 7101 +3081 880b 0020 4000 0000 0005 +0000 0004 ff03 c021 0703 001c 0c03 0018 +577f 7c5b 4d53 5241 532d 302d 434c 4159 +4d4f 4f52 + +# 23:18:36.588721 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:5 A:5 ppp: CCP 12: Conf-Req(4), MPPC +[in,pcn1] +4500 0030 5e1b 0000 802f 792e c0a8 7101 c0a8 7103 +3081 880b 000c 0000 0000 0005 +0000 0005 80fd 0104 000a 1206 0100 0001 + +# 23:18:36.589445 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:6 A:5 ppp: CCP 6: Conf-Req(1) +[out,pcn1] +4500 002a 69b1 0000 ff2f a148 7f00 0001 c0a8 7101 +3081 880b 0006 4000 0000 0006 +0000 0005 80fd 0101 0004 + +# 23:18:36.589540 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:7 ppp: CCP 12: Conf-Rej(4), MPPC +[out,pcn1] +4500 002c 69b2 0000 ff2f a145 7f00 0001 c0a8 7101 +3001 880b 000c 4000 0000 0007 +80fd 0404 000a 1206 0100 0001 + +# 23:18:36.590023 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:6 A:7 ppp: IPCP 36: Conf-Req(5), IP-Addr=0.0.0.0, Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[in,pcn1] +4500 0048 5e1c 0000 802f 7915 c0a8 7101 c0a8 7103 +3081 880b 0024 0000 0000 0006 +0000 0007 8021 0105 0022 0306 0000 0000 +8106 0000 0000 8206 0000 0000 8306 0000 +0000 8406 0000 0000 + +# 23:18:36.590489 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:8 A:6 ppp: IPCP 30: Conf-Rej(5), Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[out,pcn1] +4500 0042 69b3 0000 ff2f a12e 7f00 0001 c0a8 7101 +3081 880b 001e 4000 0000 0008 +0000 0006 8021 0405 001c 8106 0000 0000 +8206 0000 0000 8306 0000 0000 8406 0000 +0000 + +# 23:18:36.591003 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:7 A:8 ppp: IPCP 12: Conf-Rej(1), IP-Comp VJ-Comp +[in,pcn1] +4500 0030 5e1d 0000 802f 792c c0a8 7101 c0a8 7103 +3081 880b 000c 0000 0000 0007 +0000 0008 8021 0401 000a 0206 002d 0f01 + +# 23:18:36.593819 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:9 A:7 ppp: IPCP 12: Conf-Req(2), IP-Addr=192.168.0.1 +[out,pcn1] +4500 0030 69b4 0000 ff2f a13f 7f00 0001 c0a8 7101 +3081 880b 000c 4000 0000 0009 +0000 0007 8021 0102 000a 0306 c0a8 0001 + +# 23:18:36.594840 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:8 A:9 ppp: CCP 6: Conf-Ack(1) +[in,pcn1] +4500 002a 5e1e 0000 802f 7931 c0a8 7101 c0a8 7103 +3081 880b 0006 0000 0000 0008 +0000 0009 80fd 0201 0004 + +# 23:18:36.595525 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:9 ppp: CCP 18: Term-Req(6) +[in,pcn1] +4500 0032 5e1f 0000 802f 7928 c0a8 7101 c0a8 7103 +3001 880b 0012 0000 0000 0009 +80fd 0506 0010 577f 7c5b 003c cd74 0000 +02dc + +# 23:18:36.595937 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:10 A:9 ppp: CCP 6: Term-Ack(6) +[out,pcn1] +4500 002a 69b5 0000 ff2f a144 7f00 0001 c0a8 7101 +3081 880b 0006 4000 0000 000a +0000 0009 80fd 0606 0004 + diff --git a/contrib/netbsd-tests/ipf/input/ni15 b/contrib/netbsd-tests/ipf/input/ni15 new file mode 100644 index 0000000..7e7aabd --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni15 @@ -0,0 +1,235 @@ +# 23:18:36.130424 192.168.113.1.1511 > 192.168.113.3.1723: S 2884651685:2884651685(0) win 64240 (DF) +[out,pcn1=192.168.113.3] +4500 0030 5e11 4000 8006 3961 c0a8 7101 +c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 +7002 faf0 21a1 0000 0204 05b4 0101 0402 + +# 23:18:36.130778 192.168.113.3.1723 > 192.168.113.1.1511: S 2774821082:2774821082(0) ack 2884651686 win 32768 (DF) +[in,pcn1] +4500 002c 69a6 4000 4006 6dd0 c0a8 7103 +c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 +6012 8000 a348 0000 0204 05b4 + +# 23:18:36.130784 192.168.113.1.1511 > 192.168.113.3.1723: P 1:157(156) ack 1 win 64240: pptp CTRL_MSGTYPE=SCCRQ PROTO_VER(1.0) FRAME_CAP(A) BEARER_CAP(A) MAX_CHAN(0) FIRM_REV(2600) HOSTNAME() VENDOR(Microsoft Windows NT) (DF) +[out,pcn1] +4500 00c4 5e12 4000 8006 38cc c0a8 7101 +c0a8 7103 05e7 06bb abf0 4aa6 a564 68db +5018 faf0 e2a0 0000 009c 0001 1a2b 3c4d +0001 0000 0100 0000 0000 0001 0000 0001 +0000 0a28 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 4d69 6372 6f73 6f66 7420 5769 +6e64 6f77 7320 4e54 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260235 192.168.113.3.1723 > 192.168.113.1.1511: P 1:157(156) ack 157 win 33580: pptp CTRL_MSGTYPE=SCCRP PROTO_VER(1.0) RESULT_CODE(1) ERR_CODE(0) FRAME_CAP() BEARER_CAP() MAX_CHAN(1) FIRM_REV(1) HOSTNAME(local) VENDOR(linux) (DF) +[in,pcn1] +4500 00c4 69a7 4000 4006 6d37 c0a8 7103 +c0a8 7101 06bb 05e7 a564 68db abf0 4b42 +5018 832c cecf 0000 009c 0001 1a2b 3c4d +0002 0000 0100 0100 0000 0000 0000 0000 +0001 0001 6c6f 6361 6c00 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 6c69 6e75 7800 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260252 192.168.113.1.1511 > 192.168.113.3.1723: P 157:325(168) ack 157 win 64084: pptp CTRL_MSGTYPE=OCRQ CALL_ID(16384) CALL_SER_NUM(4913) MIN_BPS(300) MAX_BPS(100000000) BEARER_TYPE(Any) FRAME_TYPE(E) RECV_WIN(64) PROC_DELAY(0) PHONE_NO_LEN(0) PHONE_NO() SUB_ADDR() (DF) +[out,pcn1] +4500 00d0 5e13 4000 8006 38bf c0a8 7101 +c0a8 7103 05e7 06bb abf0 4b42 a564 6977 +5018 fa54 ac07 0000 00a8 0001 1a2b 3c4d +0007 0000 4000 1331 0000 012c 05f5 e100 +0000 0003 0000 0003 0040 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 + +# 23:18:36.272856 192.168.113.3.1723 > 192.168.113.1.1511: P 157:189(32) ack 325 win 33580: pptp CTRL_MSGTYPE=OCRP CALL_ID(0) PEER_CALL_ID(16384) RESULT_CODE(1) ERR_CODE(0) CAUSE_CODE(0) CONN_SPEED(100000000) RECV_WIN(64) PROC_DELAY(0) PHY_CHAN_ID(0) (DF) +[in,pcn1] +4500 0048 69a8 4000 4006 6db2 c0a8 7103 +c0a8 7101 06bb 05e7 a564 6977 abf0 4bea +5018 832c 36fa 0000 0020 0001 1a2b 3c4d +0008 0000 0000 4000 0100 0000 05f5 e100 +0040 0000 0000 0000 + +# 23:18:36.321819 192.168.113.1.1511 > 192.168.113.3.1723: P 325:349(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0xffffffff) RECV_ACCM(0xffffffff) (DF) +[out,pcn1] +4500 0040 5e14 4000 8006 394e c0a8 7101 +c0a8 7103 05e7 06bb abf0 4bea a564 6997 +5018 fa34 e810 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 ffff ffff ffff ffff + +# 23:18:36.349759 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:0 ppp: LCP 25: Conf-Req(0), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC, Call-Back CBCP +[out,pcn1] +4500 0039 5e15 0000 802f 792b c0a8 7101 +c0a8 7103 3001 880b 0019 0000 0000 0000 +ff03 c021 0100 0015 0104 0578 0506 577f +7c5b 0702 0802 0d03 06 + +# 23:18:36.389970 192.168.113.3 > 192.168.113.1: gre [KAv1] ID:4000 A:4294967295 [|gre] +[in,pcn1] +4500 0020 69a9 0000 ff2f eeaf c0a8 7103 +c0a8 7101 2081 880b 0000 4000 ffff ffff + +# 23:18:36.518426 192.168.113.3.1723 > 192.168.113.1.1511: . ack 349 win 33580 (DF) +[in,pcn1] +4500 0028 69aa 4000 4006 6dd0 c0a8 7103 +c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 +5010 832c b5c1 0000 + +# 23:18:36.555363 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:0 ppp: LCP 24: Conf-Req(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[in,pcn1] +4500 0038 69ab 0000 ff2f ee95 c0a8 7103 +c0a8 7101 3001 880b 0018 4000 0000 0000 +ff03 c021 0101 0014 0206 0000 0000 0506 +22d9 0cfa 0702 0802 + +# 23:18:36.556030 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:1 A:0 ppp: LCP 11: Conf-Rej(0), Call-Back CBCP +[in,pcn1] +4500 002f 69ac 0000 ff2f ee9d c0a8 7103 +c0a8 7101 3081 880b 000b 4000 0000 0001 +0000 0000 ff03 c021 0400 0007 0d03 06 + +# 23:18:36.557166 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:1 A:1 ppp: LCP 24: Conf-Ack(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[out,pcn1] +4500 003c 5e16 0000 802f 7927 c0a8 7101 +c0a8 7103 3081 880b 0018 0000 0000 0001 +0000 0001 ff03 c021 0201 0014 0206 0000 +0000 0506 22d9 0cfa 0702 0802 + +# 23:18:36.557764 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:2 ppp: LCP 22: Conf-Req(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[out,pcn1] +4500 0036 5e17 0000 802f 792c c0a8 7101 +c0a8 7103 3001 880b 0016 0000 0000 0002 +ff03 c021 0101 0012 0104 0578 0506 577f +7c5b 0702 0802 + +# 23:18:36.564658 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:2 A:2 ppp: LCP 22: Conf-Ack(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[in,pcn1] +4500 003a 69ad 0000 ff2f ee91 c0a8 7103 +c0a8 7101 3081 880b 0016 4000 0000 0002 +0000 0002 ff03 c021 0201 0012 0104 0578 +0506 577f 7c5b 0702 0802 + +# 23:18:36.564803 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:3 ppp: IPCP 18: Conf-Req(1), IP-Addr=192.168.0.1, IP-Comp VJ-Comp +[in,pcn1] +4500 0032 69ae 0000 ff2f ee98 c0a8 7103 +c0a8 7101 3001 880b 0012 4000 0000 0003 +8021 0101 0010 0306 c0a8 0001 0206 002d +0f01 + +# 23:18:36.570395 192.168.113.1.1511 > 192.168.113.3.1723: P 349:373(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0x00000000) RECV_ACCM(0xffffffff) (DF) +[out,pcn1] +4500 0040 5e18 4000 8006 394a c0a8 7101 +c0a8 7103 05e7 06bb abf0 4c02 a564 6997 +5018 fa34 e7f8 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 0000 0000 ffff ffff + +# 23:18:36.573307 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:3 A:3 ppp: LCP 20: Ident(2), Magic-Num=577f7c5b +[out,pcn1] +4500 0038 5e19 0000 802f 7928 c0a8 7101 +c0a8 7103 3081 880b 0014 0000 0000 0003 +0000 0003 c021 0c02 0012 577f 7c5b 4d53 +5241 5356 352e 3130 + +# 23:18:36.573856 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:4 A:3 ppp: LCP 26: Code-Rej(2) +[in,pcn1] +4500 003e 69af 0000 ff2f ee8b c0a8 7103 +c0a8 7101 3081 880b 001a 4000 0000 0004 +0000 0003 ff03 c021 0702 0016 0c02 0012 +577f 7c5b 4d53 5241 5356 352e 3130 + +# 23:18:36.584936 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:4 A:4 ppp: LCP 26: Ident(3), Magic-Num=577f7c5b +[out,pcn1] +4500 003e 5e1a 0000 802f 7921 c0a8 7101 +c0a8 7103 3081 880b 001a 0000 0000 0004 +0000 0004 c021 0c03 0018 577f 7c5b 4d53 +5241 532d 302d 434c 4159 4d4f 4f52 + +# 23:18:36.585562 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:5 A:4 ppp: LCP 32: Code-Rej(3) +[in,pcn1] +4500 0044 69b0 0000 ff2f ee84 c0a8 7103 +c0a8 7101 3081 880b 0020 4000 0000 0005 +0000 0004 ff03 c021 0703 001c 0c03 0018 +577f 7c5b 4d53 5241 532d 302d 434c 4159 +4d4f 4f52 + +# 23:18:36.588721 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:5 A:5 ppp: CCP 12: Conf-Req(4), MPPC +[out,pcn1] +4500 0030 5e1b 0000 802f 792e c0a8 7101 +c0a8 7103 3081 880b 000c 0000 0000 0005 +0000 0005 80fd 0104 000a 1206 0100 0001 + +# 23:18:36.589445 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:6 A:5 ppp: CCP 6: Conf-Req(1) +[in,pcn1] +4500 002a 69b1 0000 ff2f ee9d c0a8 7103 +c0a8 7101 3081 880b 0006 4000 0000 0006 +0000 0005 80fd 0101 0004 + +# 23:18:36.589540 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:7 ppp: CCP 12: Conf-Rej(4), MPPC +[in,pcn1] +4500 002c 69b2 0000 ff2f ee9a c0a8 7103 +c0a8 7101 3001 880b 000c 4000 0000 0007 +80fd 0404 000a 1206 0100 0001 + +# 23:18:36.590023 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:6 A:7 ppp: IPCP 36: Conf-Req(5), IP-Addr=0.0.0.0, Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[out,pcn1] +4500 0048 5e1c 0000 802f 7915 c0a8 7101 +c0a8 7103 3081 880b 0024 0000 0000 0006 +0000 0007 8021 0105 0022 0306 0000 0000 +8106 0000 0000 8206 0000 0000 8306 0000 +0000 8406 0000 0000 + +# 23:18:36.590489 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:8 A:6 ppp: IPCP 30: Conf-Rej(5), Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[in,pcn1] +4500 0042 69b3 0000 ff2f ee83 c0a8 7103 +c0a8 7101 3081 880b 001e 4000 0000 0008 +0000 0006 8021 0405 001c 8106 0000 0000 +8206 0000 0000 8306 0000 0000 8406 0000 +0000 + +# 23:18:36.591003 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:7 A:8 ppp: IPCP 12: Conf-Rej(1), IP-Comp VJ-Comp +[out,pcn1] +4500 0030 5e1d 0000 802f 792c c0a8 7101 +c0a8 7103 3081 880b 000c 0000 0000 0007 +0000 0008 8021 0401 000a 0206 002d 0f01 + +# 23:18:36.593819 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:9 A:7 ppp: IPCP 12: Conf-Req(2), IP-Addr=192.168.0.1 +[in,pcn1] +4500 0030 69b4 0000 ff2f ee94 c0a8 7103 +c0a8 7101 3081 880b 000c 4000 0000 0009 +0000 0007 8021 0102 000a 0306 c0a8 0001 + +# 23:18:36.594840 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:8 A:9 ppp: CCP 6: Conf-Ack(1) +[out,pcn1] +4500 002a 5e1e 0000 802f 7931 c0a8 7101 +c0a8 7103 3081 880b 0006 0000 0000 0008 +0000 0009 80fd 0201 0004 + +# 23:18:36.595525 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:9 ppp: CCP 18: Term-Req(6) +[out,pcn1] +4500 0032 5e1f 0000 802f 7928 c0a8 7101 +c0a8 7103 3001 880b 0012 0000 0000 0009 +80fd 0506 0010 577f 7c5b 003c cd74 0000 +02dc + +# 23:18:36.595937 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:10 A:9 ppp: CCP 6: Term-Ack(6) +[in,pcn1] +4500 002a 69b5 0000 ff2f ee99 c0a8 7103 +c0a8 7101 3081 880b 0006 4000 0000 000a +0000 0009 80fd 0606 0004 + diff --git a/contrib/netbsd-tests/ipf/input/ni16 b/contrib/netbsd-tests/ipf/input/ni16 new file mode 100644 index 0000000..362b98d --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni16 @@ -0,0 +1,235 @@ +# 23:18:36.130424 192.168.113.1.1511 > 192.168.113.3.1723: S 2884651685:2884651685(0) win 64240 (DF) +[out,pcn1=192.168.113.1] +4500 0030 5e11 4000 8006 5f07 0a02 0202 +c0a8 7103 05e7 06bb abf0 4aa5 0000 0000 +7002 faf0 4747 0000 0204 05b4 0101 0402 + +# 23:18:36.130778 192.168.113.3.1723 > 192.168.113.1.1511: S 2774821082:2774821082(0) ack 2884651686 win 32768 (DF) +[in,pcn1] +4500 002c 69a6 4000 4006 6dd0 c0a8 7103 +c0a8 7101 06bb 05e7 a564 68da abf0 4aa6 +6012 8000 a348 0000 0204 05b4 + +# 23:18:36.130784 192.168.113.1.1511 > 192.168.113.3.1723: P 1:157(156) ack 1 win 64240: pptp CTRL_MSGTYPE=SCCRQ PROTO_VER(1.0) FRAME_CAP(A) BEARER_CAP(A) MAX_CHAN(0) FIRM_REV(2600) HOSTNAME() VENDOR(Microsoft Windows NT) (DF) +[out,pcn1] +4500 00c4 5e12 4000 8006 5e72 0a02 0202 +c0a8 7103 05e7 06bb abf0 4aa6 a564 68db +5018 faf0 0847 0000 009c 0001 1a2b 3c4d +0001 0000 0100 0000 0000 0001 0000 0001 +0000 0a28 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 4d69 6372 6f73 6f66 7420 5769 +6e64 6f77 7320 4e54 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260235 192.168.113.3.1723 > 192.168.113.1.1511: P 1:157(156) ack 157 win 33580: pptp CTRL_MSGTYPE=SCCRP PROTO_VER(1.0) RESULT_CODE(1) ERR_CODE(0) FRAME_CAP() BEARER_CAP() MAX_CHAN(1) FIRM_REV(1) HOSTNAME(local) VENDOR(linux) (DF) +[in,pcn1] +4500 00c4 69a7 4000 4006 6d37 c0a8 7103 +c0a8 7101 06bb 05e7 a564 68db abf0 4b42 +5018 832c cecf 0000 009c 0001 1a2b 3c4d +0002 0000 0100 0100 0000 0000 0000 0000 +0001 0001 6c6f 6361 6c00 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 6c69 6e75 7800 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +# 23:18:36.260252 192.168.113.1.1511 > 192.168.113.3.1723: P 157:325(168) ack 157 win 64084: pptp CTRL_MSGTYPE=OCRQ CALL_ID(16384) CALL_SER_NUM(4913) MIN_BPS(300) MAX_BPS(100000000) BEARER_TYPE(Any) FRAME_TYPE(E) RECV_WIN(64) PROC_DELAY(0) PHONE_NO_LEN(0) PHONE_NO() SUB_ADDR() (DF) +[out,pcn1] +4500 00d0 5e13 4000 8006 5e65 0a02 0202 +c0a8 7103 05e7 06bb abf0 4b42 a564 6977 +5018 fa54 d1ad 0000 00a8 0001 1a2b 3c4d +0007 0000 4000 1331 0000 012c 05f5 e100 +0000 0003 0000 0003 0040 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 + +# 23:18:36.272856 192.168.113.3.1723 > 192.168.113.1.1511: P 157:189(32) ack 325 win 33580: pptp CTRL_MSGTYPE=OCRP CALL_ID(0) PEER_CALL_ID(16384) RESULT_CODE(1) ERR_CODE(0) CAUSE_CODE(0) CONN_SPEED(100000000) RECV_WIN(64) PROC_DELAY(0) PHY_CHAN_ID(0) (DF) +[in,pcn1] +4500 0048 69a8 4000 4006 6db2 c0a8 7103 +c0a8 7101 06bb 05e7 a564 6977 abf0 4bea +5018 832c 36fa 0000 0020 0001 1a2b 3c4d +0008 0000 0000 4000 0100 0000 05f5 e100 +0040 0000 0000 0000 + +# 23:18:36.321819 192.168.113.1.1511 > 192.168.113.3.1723: P 325:349(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0xffffffff) RECV_ACCM(0xffffffff) (DF) +[out,pcn1] +4500 0040 5e14 4000 8006 5ef4 0a02 0202 +c0a8 7103 05e7 06bb abf0 4bea a564 6997 +5018 fa34 0db7 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 ffff ffff ffff ffff + +# 23:18:36.349759 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:0 ppp: LCP 25: Conf-Req(0), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC, Call-Back CBCP +[out,pcn1] +4500 0039 5e15 0000 802f 9ed1 0a02 0202 +c0a8 7103 3001 880b 0019 0000 0000 0000 +ff03 c021 0100 0015 0104 0578 0506 577f +7c5b 0702 0802 0d03 06 + +# 23:18:36.389970 192.168.113.3 > 192.168.113.1: gre [KAv1] ID:4000 A:4294967295 [|gre] +[in,pcn1] +4500 0020 69a9 0000 ff2f eeaf c0a8 7103 +c0a8 7101 2081 880b 0000 4000 ffff ffff + +# 23:18:36.518426 192.168.113.3.1723 > 192.168.113.1.1511: . ack 349 win 33580 (DF) +[in,pcn1] +4500 0028 69aa 4000 4006 6dd0 c0a8 7103 +c0a8 7101 06bb 05e7 a564 6997 abf0 4c02 +5010 832c b5c1 0000 + +# 23:18:36.555363 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:0 ppp: LCP 24: Conf-Req(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[in,pcn1] +4500 0038 69ab 0000 ff2f ee95 c0a8 7103 +c0a8 7101 3001 880b 0018 4000 0000 0000 +ff03 c021 0101 0014 0206 0000 0000 0506 +22d9 0cfa 0702 0802 + +# 23:18:36.556030 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:1 A:0 ppp: LCP 11: Conf-Rej(0), Call-Back CBCP +[in,pcn1] +4500 002f 69ac 0000 ff2f ee9d c0a8 7103 +c0a8 7101 3081 880b 000b 4000 0000 0001 +0000 0000 ff03 c021 0400 0007 0d03 06 + +# 23:18:36.557166 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:1 A:1 ppp: LCP 24: Conf-Ack(1), ACCM=00000000, Magic-Num=22d90cfa, PFC, ACFC +[out,pcn1] +4500 003c 5e16 0000 802f 9ecd 0a02 0202 +c0a8 7103 3081 880b 0018 0000 0000 0001 +0000 0001 ff03 c021 0201 0014 0206 0000 +0000 0506 22d9 0cfa 0702 0802 + +# 23:18:36.557764 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:2 ppp: LCP 22: Conf-Req(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[out,pcn1] +4500 0036 5e17 0000 802f 9ed2 0a02 0202 +c0a8 7103 3001 880b 0016 0000 0000 0002 +ff03 c021 0101 0012 0104 0578 0506 577f +7c5b 0702 0802 + +# 23:18:36.564658 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:2 A:2 ppp: LCP 22: Conf-Ack(1), MRU=1400, Magic-Num=577f7c5b, PFC, ACFC +[in,pcn1] +4500 003a 69ad 0000 ff2f ee91 c0a8 7103 +c0a8 7101 3081 880b 0016 4000 0000 0002 +0000 0002 ff03 c021 0201 0012 0104 0578 +0506 577f 7c5b 0702 0802 + +# 23:18:36.564803 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:3 ppp: IPCP 18: Conf-Req(1), IP-Addr=192.168.0.1, IP-Comp VJ-Comp +[in,pcn1] +4500 0032 69ae 0000 ff2f ee98 c0a8 7103 +c0a8 7101 3001 880b 0012 4000 0000 0003 +8021 0101 0010 0306 c0a8 0001 0206 002d +0f01 + +# 23:18:36.570395 192.168.113.1.1511 > 192.168.113.3.1723: P 349:373(24) ack 189 win 64052: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(0) SEND_ACCM(0x00000000) RECV_ACCM(0xffffffff) (DF) +[out,pcn1] +4500 0040 5e18 4000 8006 5ef0 0a02 0202 +c0a8 7103 05e7 06bb abf0 4c02 a564 6997 +5018 fa34 0d9f 0000 0018 0001 1a2b 3c4d +000f 0000 0000 0000 0000 0000 ffff ffff + +# 23:18:36.573307 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:3 A:3 ppp: LCP 20: Ident(2), Magic-Num=577f7c5b +[out,pcn1] +4500 0038 5e19 0000 802f 9ece 0a02 0202 +c0a8 7103 3081 880b 0014 0000 0000 0003 +0000 0003 c021 0c02 0012 577f 7c5b 4d53 +5241 5356 352e 3130 + +# 23:18:36.573856 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:4 A:3 ppp: LCP 26: Code-Rej(2) +[in,pcn1] +4500 003e 69af 0000 ff2f ee8b c0a8 7103 +c0a8 7101 3081 880b 001a 4000 0000 0004 +0000 0003 ff03 c021 0702 0016 0c02 0012 +577f 7c5b 4d53 5241 5356 352e 3130 + +# 23:18:36.584936 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:4 A:4 ppp: LCP 26: Ident(3), Magic-Num=577f7c5b +[out,pcn1] +4500 003e 5e1a 0000 802f 9ec7 0a02 0202 +c0a8 7103 3081 880b 001a 0000 0000 0004 +0000 0004 c021 0c03 0018 577f 7c5b 4d53 +5241 532d 302d 434c 4159 4d4f 4f52 + +# 23:18:36.585562 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:5 A:4 ppp: LCP 32: Code-Rej(3) +[in,pcn1] +4500 0044 69b0 0000 ff2f ee84 c0a8 7103 +c0a8 7101 3081 880b 0020 4000 0000 0005 +0000 0004 ff03 c021 0703 001c 0c03 0018 +577f 7c5b 4d53 5241 532d 302d 434c 4159 +4d4f 4f52 + +# 23:18:36.588721 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:5 A:5 ppp: CCP 12: Conf-Req(4), MPPC +[out,pcn1] +4500 0030 5e1b 0000 802f 9ed4 0a02 0202 +c0a8 7103 3081 880b 000c 0000 0000 0005 +0000 0005 80fd 0104 000a 1206 0100 0001 + +# 23:18:36.589445 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:6 A:5 ppp: CCP 6: Conf-Req(1) +[in,pcn1] +4500 002a 69b1 0000 ff2f ee9d c0a8 7103 +c0a8 7101 3081 880b 0006 4000 0000 0006 +0000 0005 80fd 0101 0004 + +# 23:18:36.589540 192.168.113.3 > 192.168.113.1: gre [KSv1] ID:4000 S:7 ppp: CCP 12: Conf-Rej(4), MPPC +[in,pcn1] +4500 002c 69b2 0000 ff2f ee9a c0a8 7103 +c0a8 7101 3001 880b 000c 4000 0000 0007 +80fd 0404 000a 1206 0100 0001 + +# 23:18:36.590023 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:6 A:7 ppp: IPCP 36: Conf-Req(5), IP-Addr=0.0.0.0, Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[out,pcn1] +4500 0048 5e1c 0000 802f 9ebb 0a02 0202 +c0a8 7103 3081 880b 0024 0000 0000 0006 +0000 0007 8021 0105 0022 0306 0000 0000 +8106 0000 0000 8206 0000 0000 8306 0000 +0000 8406 0000 0000 + +# 23:18:36.590489 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:8 A:6 ppp: IPCP 30: Conf-Rej(5), Pri-DNS=0.0.0.0, Pri-NBNS=0.0.0.0, Sec-DNS=0.0.0.0, Sec-NBNS=0.0.0.0 +[in,pcn1] +4500 0042 69b3 0000 ff2f ee83 c0a8 7103 +c0a8 7101 3081 880b 001e 4000 0000 0008 +0000 0006 8021 0405 001c 8106 0000 0000 +8206 0000 0000 8306 0000 0000 8406 0000 +0000 + +# 23:18:36.591003 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:7 A:8 ppp: IPCP 12: Conf-Rej(1), IP-Comp VJ-Comp +[out,pcn1] +4500 0030 5e1d 0000 802f 9ed2 0a02 0202 +c0a8 7103 3081 880b 000c 0000 0000 0007 +0000 0008 8021 0401 000a 0206 002d 0f01 + +# 23:18:36.593819 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:9 A:7 ppp: IPCP 12: Conf-Req(2), IP-Addr=192.168.0.1 +[in,pcn1] +4500 0030 69b4 0000 ff2f ee94 c0a8 7103 +c0a8 7101 3081 880b 000c 4000 0000 0009 +0000 0007 8021 0102 000a 0306 c0a8 0001 + +# 23:18:36.594840 192.168.113.1 > 192.168.113.3: gre [KSAv1] ID:0000 S:8 A:9 ppp: CCP 6: Conf-Ack(1) +[out,pcn1] +4500 002a 5e1e 0000 802f 9ed7 0a02 0202 +c0a8 7103 3081 880b 0006 0000 0000 0008 +0000 0009 80fd 0201 0004 + +# 23:18:36.595525 192.168.113.1 > 192.168.113.3: gre [KSv1] ID:0000 S:9 ppp: CCP 18: Term-Req(6) +[out,pcn1] +4500 0032 5e1f 0000 802f 9ece 0a02 0202 +c0a8 7103 3001 880b 0012 0000 0000 0009 +80fd 0506 0010 577f 7c5b 003c cd74 0000 +02dc + +# 23:18:36.595937 192.168.113.3 > 192.168.113.1: gre [KSAv1] ID:4000 S:10 A:9 ppp: CCP 6: Term-Ack(6) +[in,pcn1] +4500 002a 69b5 0000 ff2f ee99 c0a8 7103 +c0a8 7101 3081 880b 0006 4000 0000 000a +0000 0009 80fd 0606 0004 + diff --git a/contrib/netbsd-tests/ipf/input/ni17 b/contrib/netbsd-tests/ipf/input/ni17 new file mode 100644 index 0000000..f9dec94 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni17 @@ -0,0 +1,6 @@ +in on le0 tcp 10.2.2.5,2000 203.1.1.1,80 +in on le0 tcp 10.2.2.6,2000 203.1.1.1,80 +in on le0 tcp 10.2.2.7,2000 203.1.1.1,80 +in on le0 tcp 10.2.2.7,2001 203.1.1.1,80 +in on le0 tcp 10.2.2.8,2000 203.1.1.1,80 +in on le0 tcp 10.2.2.9,2000 203.1.1.1,80 diff --git a/contrib/netbsd-tests/ipf/input/ni18 b/contrib/netbsd-tests/ipf/input/ni18 new file mode 100644 index 0000000..4e06f79 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni18 @@ -0,0 +1,4 @@ +in on hme0 tcp 2.2.2.2,3000 192.168.1.2,80 +in on hme0 tcp 2.2.2.2,3000 192.168.1.1,80 +out on hme1 tcp 10.1.2.2,5050 4.5.6.7,80; +out on hme1 tcp 10.1.1.2,5050 4.5.6.7,80; diff --git a/contrib/netbsd-tests/ipf/input/ni19 b/contrib/netbsd-tests/ipf/input/ni19 new file mode 100644 index 0000000..3ea706f --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni19 @@ -0,0 +1,157 @@ +# 192.168.113.3.1009 > 10.1.1.4.shell: SYN win 32768 +[out,bge0] +4500 0040 e3fc 4000 4006 1a0b c0a8 7103 +0a01 0104 03f1 0202 6523 90b2 0000 0000 +b002 8000 7d87 0000 0204 05b4 0103 0300 +0402 0101 0101 080a 0000 0000 0000 0000 + +# 10.1.1.4.shell > 10.1.1.1.1009: SYN win 5840 +[in,bge0] +4500 0034 0000 4000 4006 24be 0a01 0104 +0a01 0101 0202 03f1 915a a5c4 6523 90b3 +8012 16d0 0f47 0000 0204 05b4 0101 0402 +0103 0302 + +# 192.168.113.3.1009 > 10.1.1.4.shell +[out,bge0] +4500 0028 e3fd 4000 4006 1a22 c0a8 7103 +0a01 0104 03f1 0202 6523 90b3 915a a5c5 +5010 832c bd0d 0000 + +# 192.168.113.3.1009 > 10.1.1.4.shell +[out,bge0] +4500 002d e3fe 4000 4006 1a1c c0a8 7103 +0a01 0104 03f1 0202 6523 90b3 915a a5c5 +5018 832c 5b98 0000 3130 3038 00 + +# 10.1.1.4.shell > 10.1.1.1.1009 +[in,bge0] +4500 0028 7ce5 4000 4006 a7e4 0a01 0104 +0a01 0101 0202 03f1 915a a5c5 6523 90b8 +5010 05b4 612b 0000 + +# 10.1.1.4.1023 > 10.1.1.1.1008: SYN win 5840 +[in,bge0] +4500 003c 1186 4000 4006 1330 0a01 0104 +0a01 0101 03ff 03f0 91d4 c8a2 0000 0000 +a002 16d0 df6a 0000 0204 05b4 0402 080a +0039 d924 0000 0000 0103 0302 + +# 192.168.113.3.1008 > 10.1.1.4.1023: SYN win 32768 +[out,bge0] +4500 0040 e3ff 4000 4006 1a08 c0a8 7103 +0a01 0104 03f0 03ff 66e5 b810 91d4 c8a3 +b012 8000 1e85 0000 0204 05b4 0103 0300 +0101 080a 0000 0000 0039 d924 0402 0101 + +# 10.1.1.4.1023 > 10.1.1.1.1008 +[in,bge0] +4500 0034 1188 4000 4006 1336 0a01 0104 +0a01 0101 03ff 03f0 91d4 c8a3 66e5 b811 +8010 05b4 0046 0000 0101 080a 0039 d925 +0000 0000 + +# 192.168.113.3.1009 > 10.1.1.4.shell +[out,bge0] +4500 0030 e400 4000 4006 1a17 c0a8 7103 +0a01 0104 03f1 0202 6523 90b8 915a a5c5 +5018 832c 0eb6 0000 6461 7272 656e 7200 + +# 10.1.1.4.shell > 10.1.1.1.1009 +[in,bge0] +4500 0028 7ce7 4000 4006 a7e2 0a01 0104 +0a01 0101 0202 03f1 915a a5c5 6523 90c0 +5010 05b4 6123 0000 + +# 192.168.113.3.1009 > 10.1.1.4.shell +[out,bge0] +4500 0053 e401 4000 4006 19f3 c0a8 7103 +0a01 0104 03f1 0202 6523 90c0 915a a5c5 +5018 832c a63d 0000 6461 7272 656e 7200 +7368 202d 6320 2265 6368 6f20 666f 6f20 +3e26 313b 2065 6368 6f20 6261 7220 3e26 +3222 00 + +# 10.1.1.4.shell > 10.1.1.1.1009 +[in,bge0] +4500 0028 7ce9 4000 4006 a7e0 0a01 0104 +0a01 0101 0202 03f1 915a a5c5 6523 90eb +5010 05b4 60f8 0000 + +# 10.1.1.4.shell > 10.1.1.1.1009 +[in,bge0] +4500 0029 7ceb 4000 4006 a7dd 0a01 0104 +0a01 0101 0202 03f1 915a a5c5 6523 90eb +5018 05b4 60ef 0000 00 + +# 192.168.113.3.1009 > 10.1.1.4.shell +[out,bge0] +4500 0028 e403 4000 4006 1a1c c0a8 7103 +0a01 0104 03f1 0202 6523 90eb 915a a5c6 +5010 832c bcd4 0000 + +# 10.1.1.4.shell > 10.1.1.1.1009 +[in,bge0] +4500 002c 7ced 4000 4006 a7d8 0a01 0104 +0a01 0101 0202 03f1 915a a5c6 6523 90eb +5018 05b4 8b71 0000 666f 6f0a + +# 10.1.1.4.1023 > 10.1.1.1.1008 +[in,bge0] +4500 0038 118a 4000 4006 1330 0a01 0104 +0a01 0101 03ff 03f0 91d4 c8a3 66e5 b811 +8018 05b4 2787 0000 0101 080a 0039 dd6c +0000 0000 6261 720a + +# 10.1.1.4.shell > 10.1.1.1.1009 +[in,bge0] +4500 0028 7cef 4000 4006 a7da 0a01 0104 +0a01 0101 0202 03f1 915a a5ca 6523 90eb +5011 05b4 60f2 0000 + +# 10.1.1.4.1023 > 10.1.1.1.1008 +[in,bge0] +4500 0034 118c 4000 4006 1332 0a01 0104 +0a01 0101 03ff 03f0 91d4 c8a7 66e5 b811 +8011 05b4 fbf8 0000 0101 080a 0039 dd6d +0000 0000 + +# 192.168.113.3.1009 > 10.1.1.4.shell +[out,bge0] +4500 0028 e404 4000 4006 1a1b c0a8 7103 +0a01 0104 03f1 0202 6523 90eb 915a a5cb +5010 8328 bcd3 0000 + +# 192.168.113.3.1008 > 10.1.1.4.1023 +[out,bge0] +4500 0034 e405 4000 4006 1a0e c0a8 7103 +0a01 0104 03f0 03ff 66e5 b811 91d4 c8a8 +8010 8328 57d7 0000 0101 080a 0000 0004 +0039 dd6c + +# 192.168.113.3.1009 > 10.1.1.4.shell +[out,bge0] +4500 0028 e40a 4000 4006 1a15 c0a8 7103 +0a01 0104 03f1 0202 6523 90eb 915a a5cb +5011 832c bcce 0000 + +# 192.168.113.3.1008 > 10.1.1.4.1023 +[out,bge0] +4500 0034 e40b 4000 4006 1a08 c0a8 7103 +0a01 0104 03f0 03ff 66e5 b811 91d4 c8a8 +8011 832c 57d2 0000 0101 080a 0000 0004 +0039 dd6c + +# 10.1.1.4.shell > 10.1.1.1.1009 +[in,bge0] +4500 0028 0004 4000 4006 24c6 0a01 0104 +0a01 0101 0202 03f1 915a a5cb 6523 90ec +5010 05b4 60f1 0000 + +# 10.1.1.4.1023 > 10.1.1.1.1008 +[in,bge0] +4500 0034 118e 4000 4006 1330 0a01 0104 +0a01 0101 03ff 03f0 91d4 c8a8 66e5 b812 +8010 05b4 fbf2 0000 0101 080a 0039 dd6e +0000 0004 + diff --git a/contrib/netbsd-tests/ipf/input/ni2 b/contrib/netbsd-tests/ipf/input/ni2 new file mode 100644 index 0000000..6dcedb7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni2 @@ -0,0 +1,143 @@ +# Test of fragmentation required coming from the inside. +[out,xl0] +4510 002c bd0d 4000 3e06 b1d1 0a01 0201 c0a8 0133 +05f6 0077 a664 2485 0000 0000 +6002 4000 b8f2 0000 0204 05b4 + +[in,xl0] +4500 002c ce83 4000 7e06 606b c0a8 0133 0a01 0201 +0077 05f6 fbdf 1a21 a664 2486 +6012 2238 c0a8 0000 0204 05b4 + +[out,xl0] +4510 0028 bd0e 4000 3e06 b1d4 0a01 0201 c0a8 0133 +05f6 0077 a664 2486 fbdf 1a22 +5010 4470 b62d 0000 + +[in,xl0] +4500 005b cf83 4000 7e06 5f3c c0a8 0133 0a01 0201 +0077 05f6 fbdf 1a22 a664 2486 +5018 2238 ce2a 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0a + +[out,xl0] +4510 0028 bd18 4000 3e06 b1ca 0a01 0201 c0a8 0133 +05f6 0077 a664 2486 fbdf 1a55 +5010 4470 b5fa 0000 + +[out,xl0] +4510 002e bd1e 4000 3e06 b1be 0a01 0201 c0a8 0133 +05f6 0077 a664 2486 fbdf 1a55 +5018 4470 a8e2 0000 0000 0000 0d0a + +[in,xl0] +4500 0048 e383 4000 7e06 4b4f c0a8 0133 0a01 0201 +0077 05f6 fbdf 1a55 a664 248c +5018 2232 d80a 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 + +[in,xl0] +4500 05dc e483 4000 7e06 44bb c0a8 0133 0a01 0201 +0077 05f6 fbdf 1a75 a664 248c +5010 2232 9f2d 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 1111 2222 3333 0000 0000 0000 0000 +0000 0000 1111 2222 3333 0000 0000 0000 +0000 0000 0000 1111 2222 3333 0000 0000 +0000 0000 0000 0000 1111 2222 3333 0000 +0000 0000 0000 0000 0000 1111 2222 3333 +0000 0000 0000 0000 0000 0000 1111 2222 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 1111 2222 3333 0000 0000 0000 0000 +0000 0000 1111 2222 3333 0000 0000 0000 +0000 0000 0000 1111 2222 3333 0000 0000 +0000 0000 0000 0000 1111 2222 3333 0000 +0000 0000 0000 0000 0000 1111 2222 3333 +0000 0000 0000 0000 0000 0000 1111 2222 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 1111 2222 3333 0000 0000 0000 0000 +0000 0000 1111 2222 3333 0000 0000 0000 +0000 0000 0000 1111 2222 3333 0000 0000 +0000 0000 0000 0000 1111 2222 3333 0000 +0000 0000 0000 0000 0000 1111 2222 3333 +0000 0000 0000 0000 0000 0000 1111 2222 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 1111 2222 3333 0000 0000 0000 0000 +0000 0000 1111 2222 3333 0000 0000 0000 +0000 0000 0000 1111 2222 3333 0000 0000 +0000 0000 0000 0000 1111 2222 3333 0000 +0000 0000 0000 0000 0000 1111 2222 3333 +0000 0000 0000 0000 0000 0000 1111 2222 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 1111 2222 3333 0000 0000 0000 0000 +0000 0000 1111 2222 3333 0000 0000 0000 +0000 0000 0000 1111 2222 3333 0000 0000 +0000 0000 0000 0000 1111 2222 3333 0000 +0000 0000 0000 0000 0000 1111 2222 3333 +0000 0000 0000 0000 0000 0000 1111 2222 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 1111 2222 3333 0000 0000 0000 0000 +0000 0000 1111 2222 3333 0000 0000 0000 +0000 0000 0000 1111 2222 3333 0000 0000 +0000 0000 0000 0000 1111 2222 3333 0000 +0000 0000 0000 0000 0000 1111 2222 3333 +0000 0000 0000 0000 0000 0000 1111 2222 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 1111 2222 3331 0000 0000 0000 0000 +0000 0000 1111 2222 3333 0000 0000 0000 +0000 0000 0000 1111 2222 3333 0000 0000 +0000 0000 0000 0000 1111 2222 3333 0000 +0000 0000 0000 0000 0000 1111 2222 3333 +0000 0000 0000 0000 0000 0000 1111 2222 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 1111 2222 3333 0000 0000 0000 0000 +0000 0000 1111 2222 3333 0000 0000 0000 +0000 0000 0000 1111 2222 3333 0000 0000 +0000 0000 0000 0000 1111 2222 3333 0000 +0000 0000 0000 0000 0000 1111 2222 3333 +0000 0000 0000 0000 0000 0000 1111 2222 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 1111 2222 3333 0000 0000 0000 0000 +0000 0000 1111 2222 3333 0000 0000 0000 +0000 0000 0000 1111 2222 3333 0000 0000 +0000 0000 0000 0000 1111 2222 3333 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 + +[out,xl0] +4500 0038 d71d 4000 4001 7d22 c0a8 6401 c0a8 0133 +0304 da99 0000 05a0 +4500 05dc e483 4000 7e06 44bb c0a8 0133 0a01 0201 +0077 05f6 fbdf 1a75 + diff --git a/contrib/netbsd-tests/ipf/input/ni20 b/contrib/netbsd-tests/ipf/input/ni20 new file mode 100644 index 0000000..065ed27 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni20 @@ -0,0 +1,157 @@ +# 192.168.113.3.1009 > 10.1.1.4.shell: SYN win 32768 +[in,bge0] +4500 0040 e3fc 4000 4006 1a0b c0a8 7103 +0a01 0104 03f1 0202 6523 90b2 0000 0000 +b002 8000 7d87 0000 0204 05b4 0103 0300 +0402 0101 0101 080a 0000 0000 0000 0000 + +# 192.168.113.4.shell > 192.168.113.3.1009: SYN win 5840 +[out,bge0] +4500 0034 0000 4000 4006 d76b c0a8 7104 +c0a8 7103 0202 03f1 915a a5c4 6523 90b3 +8012 16d0 c1f4 0000 0204 05b4 0101 0402 +0103 0302 + +# 192.168.113.3.1009 > 10.1.1.4.shell +[in,bge0] +4500 0028 e3fd 4000 4006 1a22 c0a8 7103 +0a01 0104 03f1 0202 6523 90b3 915a a5c5 +5010 832c bd0d 0000 + +# 192.168.113.3.1009 > 10.1.1.4.shell +[in,bge0] +4500 002d e3fe 4000 4006 1a1c c0a8 7103 +0a01 0104 03f1 0202 6523 90b3 915a a5c5 +5018 832c 5b98 0000 3130 3038 00 + +# 192.168.113.4.shell > 192.168.113.3.1009 +[out,bge0] +4500 0028 7ce5 4000 4006 5a92 c0a8 7104 +c0a8 7103 0202 03f1 915a a5c5 6523 90b8 +5010 05b4 13d9 0000 + +# 192.168.113.4.1023 > 192.168.113.3.1008: SYN win 5840 +[out,bge0] +4500 003c 1186 4000 4006 c5dd c0a8 7104 +c0a8 7103 03ff 03f0 91d4 c8a2 0000 0000 +a002 16d0 9218 0000 0204 05b4 0402 080a +0039 d924 0000 0000 0103 0302 + +# 192.168.113.3.1008 > 10.1.1.4.1023: SYN win 32768 +[in,bge0] +4500 0040 e3ff 4000 4006 1a08 c0a8 7103 +0a01 0104 03f0 03ff 66e5 b810 91d4 c8a3 +b012 8000 1e85 0000 0204 05b4 0103 0300 +0101 080a 0000 0000 0039 d924 0402 0101 + +# 192.168.113.4.1023 > 192.168.113.3.1008 ACK +[out,bge0] +4500 0034 1188 4000 4006 c5e3 c0a8 7104 +c0a8 7103 03ff 03f0 91d4 c8a3 66e5 b811 +8010 05b4 b2f3 0000 0101 080a 0039 d925 +0000 0000 + +# 192.168.113.3.1009 > 10.1.1.4.shell PUSH+ACK +[in,bge0] +4500 0030 e400 4000 4006 1a17 c0a8 7103 +0a01 0104 03f1 0202 6523 90b8 915a a5c5 +5018 832c 0eb6 0000 6461 7272 656e 7200 + +# 192.168.113.4.shell > 192.168.113.3.1009 ACK +[out,bge0] +4500 0028 7ce7 4000 4006 5a90 c0a8 7104 +c0a8 7103 0202 03f1 915a a5c5 6523 90c0 +5010 05b4 13d1 0000 + +# 192.168.113.3.1009 > 10.1.1.4.shell PUSH+ACK +[in,bge0] +4500 0053 e401 4000 4006 19f3 c0a8 7103 +0a01 0104 03f1 0202 6523 90c0 915a a5c5 +5018 832c a63d 0000 6461 7272 656e 7200 +7368 202d 6320 2265 6368 6f20 666f 6f20 +3e26 313b 2065 6368 6f20 6261 7220 3e26 +3222 00 + +# 192.168.113.4.shell > 192.168.113.3.1009 ACK +[out,bge0] +4500 0028 7ce9 4000 4006 5a8e c0a8 7104 +c0a8 7103 0202 03f1 915a a5c5 6523 90eb +5010 05b4 13a6 0000 + +# 192.168.113.4.shell > 192.168.113.3.1009 PUSH+ACK +[out,bge0] +4500 0029 7ceb 4000 4006 5a8b c0a8 7104 +c0a8 7103 0202 03f1 915a a5c5 6523 90eb +5018 05b4 139d 0000 00 + +# 192.168.113.3.1009 > 10.1.1.4.shell ACK +[in,bge0] +4500 0028 e403 4000 4006 1a1c c0a8 7103 +0a01 0104 03f1 0202 6523 90eb 915a a5c6 +5010 832c bcd4 0000 + +# 192.168.113.4.shell > 192.168.113.3.1009 PUSH+ACK +[out,bge0] +4500 002c 7ced 4000 4006 5a86 c0a8 7104 +c0a8 7103 0202 03f1 915a a5c6 6523 90eb +5018 05b4 3e1f 0000 666f 6f0a + +# 192.168.113.4.1023 > 192.168.113.3.1008 PUSH+ACK +[out,bge0] +4500 0038 118a 4000 4006 c5dd c0a8 7104 +c0a8 7103 03ff 03f0 91d4 c8a3 66e5 b811 +8018 05b4 da34 0000 0101 080a 0039 dd6c +0000 0000 6261 720a + +# 192.168.113.4.shell > 192.168.113.3.1009 FIN+ACK +[out,bge0] +4500 0028 7cef 4000 4006 5a88 c0a8 7104 +c0a8 7103 0202 03f1 915a a5ca 6523 90eb +5011 05b4 13a0 0000 + +# 192.168.113.4.1023 > 192.168.113.3.1008 FIN+ACK +[out,bge0] +4500 0034 118c 4000 4006 c5df c0a8 7104 +c0a8 7103 03ff 03f0 91d4 c8a7 66e5 b811 +8011 05b4 aea6 0000 0101 080a 0039 dd6d +0000 0000 + +# 192.168.113.3.1009 > 10.1.1.4.shell ACK +[in,bge0] +4500 0028 e404 4000 4006 1a1b c0a8 7103 +0a01 0104 03f1 0202 6523 90eb 915a a5cb +5010 8328 bcd3 0000 + +# 192.168.113.3.1008 > 10.1.1.4.1023 ACK +[in,bge0] +4500 0034 e405 4000 4006 1a0e c0a8 7103 +0a01 0104 03f0 03ff 66e5 b811 91d4 c8a8 +8010 8328 57d7 0000 0101 080a 0000 0004 +0039 dd6c + +# 192.168.113.3.1009 > 10.1.1.4.shell FIN+ACK +[in,bge0] +4500 0028 e40a 4000 4006 1a15 c0a8 7103 +0a01 0104 03f1 0202 6523 90eb 915a a5cb +5011 832c bcce 0000 + +# 192.168.113.3.1008 > 10.1.1.4.1023 FIN+ACK +[in,bge0] +4500 0034 e40b 4000 4006 1a08 c0a8 7103 +0a01 0104 03f0 03ff 66e5 b811 91d4 c8a8 +8011 832c 57d2 0000 0101 080a 0000 0004 +0039 dd6c + +# 192.168.113.4.shell > 192.168.113.3.1009 ACK +[out,bge0] +4500 0028 0004 4000 4006 d773 c0a8 7104 +c0a8 7103 0202 03f1 915a a5cb 6523 90ec +5010 05b4 139f 0000 + +# 192.168.113.4.1023 > 192.168.113.3.1008 ACK +[out,bge0] +4500 0034 118e 4000 4006 c5dd c0a8 7104 +c0a8 7103 03ff 03f0 91d4 c8a8 66e5 b812 +8010 05b4 aea0 0000 0101 080a 0039 dd6e +0000 0004 + diff --git a/contrib/netbsd-tests/ipf/input/ni21 b/contrib/netbsd-tests/ipf/input/ni21 new file mode 100644 index 0000000..daf741e --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni21 @@ -0,0 +1,3 @@ +out on lan0 2.2.2.2 3.3.3.3 +in on lan0 3.3.3.3 4.4.4.4 +out on lan0 2.2.2.2 3.3.3.3 diff --git a/contrib/netbsd-tests/ipf/input/ni23 b/contrib/netbsd-tests/ipf/input/ni23 new file mode 100644 index 0000000..938b7b8 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni23 @@ -0,0 +1,3 @@ +in on le0 udp 3.3.3.1,6700 1.1.2.3,4500 +in on hme0 udp 2.2.2.2,4500 4.4.4.4,6700 +out on bge0 udp 2.2.2.2,4500 3.3.3.1,6700 diff --git a/contrib/netbsd-tests/ipf/input/ni3 b/contrib/netbsd-tests/ipf/input/ni3 new file mode 100644 index 0000000..e4d12fe --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni3 @@ -0,0 +1,20 @@ +#v tos len id off ttl p sum src dst +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going out) +[out,df0] +4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 +5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +[in,df0] +4500 0038 809a 0000 ff01 2919 0303 0303 0606 0606 +0303 acab 0000 0000 +4500 003c 4706 4000 ff06 20a2 0606 0606 0404 0404 +5000 0050 0000 0001 + +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[in,df0] +4500 0058 809a 0000 ff01 28f9 0303 0303 0606 0606 +0303 113f 0000 0000 +4500 003c 4706 4000 ff06 20a2 0606 0606 0404 0404 +5000 0050 0000 0001 0000 0000 a002 16d0 d0da 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + diff --git a/contrib/netbsd-tests/ipf/input/ni4 b/contrib/netbsd-tests/ipf/input/ni4 new file mode 100644 index 0000000..dac9f53 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni4 @@ -0,0 +1,18 @@ +#v tos len id off ttl p sum src dst +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going out) +[out,df0] +4500 003c 4706 4000 ff06 28aa 0202 0202 0404 0404 +5000 0050 0000 0001 0000 0000 a002 16d0 d8e2 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +[in,df0] +4500 0038 809a 0000 ff01 2919 0303 0303 0606 0606 +0303 606b 0000 0000 4500 003c 4706 4000 ff06 20a2 0606 0606 0404 0404 9c40 0050 0000 0001 + +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[in,df0] +4500 0058 809a 0000 ff01 28f9 0303 0303 0606 0606 +0303 113f 0000 0000 +4500 003c 4706 4000 ff06 20a2 0606 0606 0404 0404 +9c40 0050 0000 0001 0000 0000 a002 16d0 849a 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + diff --git a/contrib/netbsd-tests/ipf/input/ni5 b/contrib/netbsd-tests/ipf/input/ni5 new file mode 100644 index 0000000..4b32e49 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni5 @@ -0,0 +1,363 @@ +# 32818,21 SYN +[out,ppp0] +4500 002c 10c9 4000 ff06 3289 c0a8 0103 +96cb e002 8032 0015 bd6b c9c8 0000 0000 +6002 2238 35f9 0000 0204 05b4 + +# 21,32818 SYN+ACK +[in,ppp0] +4500 002c ffdd 4000 ef06 131e 96cb e002 +0101 0101 0015 8032 3786 76c4 bd6b c9c9 +6012 269c 4313 0000 0204 0584 + +# 32818,21 ACK +[out,ppp0] +4500 0028 10ca 4000 ff06 328c c0a8 0103 +96cb e002 8032 0015 bd6b c9c9 3786 76c5 +5010 269c 9af6 0000 + +# ACK+PUSH "[220-coombs.anu.edu.au NcFTPd Server (free educational license) ready.\r\n" +[in,ppp0] +4500 006f ffde 4000 ef06 12da 96cb e002 +0101 0101 0015 8032 3786 76c5 bd6b c9c9 +5018 269c 5628 0000 3232 302d 636f 6f6d +6273 2e61 6e75 2e65 6475 2e61 7520 4e63 +4654 5064 2053 6572 7665 7220 2866 7265 +6520 6564 7563 6174 696f 6e61 6c20 6c69 +6365 6e73 6529 2072 6561 6479 2e0d 0a + +# 32818,21 ACK +[out,ppp0] +4500 0028 10cb 4000 ff06 328b c0a8 0103 +96cb e002 8032 0015 bd6b c9c9 3786 770c +5010 269c 9aaf 0000 + +# 21,32818 ACK+PUSH +# "220-Maintained by RSSS and RSPAS IT Staff (previously known as Coombs Computing Unit)\r\n +# "220-Any problems contact ftpmaster@coombs.anu.edu.au\r\n" +# "220-\r\n220 \r\n" +[in,ppp0] +4500 00c7 ffdf 4000 ef06 1281 96cb e002 +0101 0101 0015 8032 3786 770c bd6b c9c9 +5018 269c d030 0000 3232 302d 0d0a 3232 +302d 4d61 696e 7461 696e 6564 2062 7920 +5253 5353 2061 6e64 2052 5350 4153 2049 +5420 5374 6166 6620 2870 7265 7669 6f75 +736c 7920 6b6e 6f77 6e20 6173 2043 6f6f +6d62 7320 436f 6d70 7574 696e 6720 556e +6974 290d 0a32 3230 2d41 6e79 2070 726f +626c 656d 7320 636f 6e74 6163 7420 6674 +706d 6173 7465 7240 636f 6f6d 6273 2e61 +6e75 2e65 6475 2e61 750d 0a32 3230 2d0d +0a32 3230 200d 0a + +# 32818,21 ACK +[out,ppp0] +4500 0028 10cc 4000 ff06 328a c0a8 0103 +96cb e002 8032 0015 bd6b c9c9 3786 77ab +5010 269c 9a10 0000 + +# 32818,21 ACK+PUSH "USER anonymous\r\n" +[out,ppp0] +4500 0038 10cd 4000 ff06 3279 c0a8 0103 +96cb e002 8032 0015 bd6b c9c9 3786 77ab +5018 269c 121c 0000 5553 4552 2061 6e6f +6e79 6d6f 7573 0d0a + +# 21,32818 ACK +[in,ppp0] +4500 0028 ffe0 4000 ef06 131f 96cb e002 +0101 0101 0015 8032 3786 77ab bd6b c9d9 +5010 269c 59aa 0000 + +# 21,32818 ACK+PUSH "331 Guest login ok, send your complete e-mail address as password.\r\n" +[in,ppp0] +4500 006c ffe1 4000 ef06 12da 96cb e002 +0101 0101 0015 8032 3786 77ab bd6b c9d9 +5018 269c 6fb9 0000 3333 3120 4775 6573 +7420 6c6f 6769 6e20 6f6b 2c20 7365 6e64 +2079 6f75 7220 636f 6d70 6c65 7465 2065 +2d6d 6169 6c20 6164 6472 6573 7320 6173 +2070 6173 7377 6f72 642e 0d0a + +# 32818,21 ACK +[out,ppp0] +4500 0028 10ce 4000 ff06 3288 c0a8 0103 +96cb e002 8032 0015 bd6b c9d9 3786 77ef +5010 269c 99bc 0000 + +# 32818,21 ACK+PUSH "PASS avalon@\r\n" +[out,ppp0] +4500 0036 10cf 4000 ff06 3279 c0a8 0103 +96cb e002 8032 0015 bd6b c9d9 3786 77ef +5018 269c 7795 0000 5041 5353 2061 7661 +6c6f 6e40 0d0a + +# 21,32818 ACK+PUSH +# "230-You are user #4 of 50 simultaneous users allowed.\r\n" +[in,ppp0] +4500 005f ffe2 4000 ef06 12e6 96cb e002 +0101 0101 0015 8032 3786 77ef bd6b c9e7 +5018 269c 4908 0000 3233 302d 596f 7520 +6172 6520 7573 6572 2023 3420 6f66 2035 +3020 7369 6d75 6c74 616e 656f 7573 2075 +7365 7273 2061 6c6c 6f77 6564 2e0d 0a + +# 32818,21 ACK +[out,ppp0] +4500 0028 10d0 4000 ff06 3286 c0a8 0103 +96cb e002 8032 0015 bd6b c9e7 3786 7826 +5010 269c 9977 0000 + +# 21,32818 ACK+PUSH +# "230-\r\n230-\r\n" +# "230-Hi. We're cleaning up. Any feedback most welcome. 10 Aug 00\r\n" +# "230-\r\n230 Logged in anonymously.\r\n" +[in,ppp0] +4500 0099 ffe3 4000 ef06 12ab 96cb e002 +0101 0101 0015 8032 3786 7826 bd6b c9e7 +5018 269c 9343 0000 3233 302d 0d0a 3233 +302d 0d0a 3233 302d 4869 2e20 2057 6527 +7265 2063 6c65 616e 696e 6720 7570 2e20 +2041 6e79 2066 6565 6462 6163 6b20 6d6f +7374 2077 656c 636f 6d65 2e20 3130 2041 +7567 2030 300d 0a32 3330 2d0d 0a32 3330 +204c 6f67 6765 6420 696e 2061 6e6f 6e79 +6d6f 7573 6c79 2e0d 0a + +# 32818,21 ACK +[out,ppp0] +4500 0028 10d1 4000 ff06 3285 c0a8 0103 +96cb e002 8032 0015 bd6b c9e7 3786 7897 +5010 269c 9906 0000 + +# 32818,21 ACK "TYPE I\r\n" +[out,ppp0] +4500 0030 10d2 4000 ff06 327c c0a8 0103 +96cb e002 8032 0015 bd6b c9e7 3786 7897 +5018 269c c704 0000 5459 5045 2049 0d0a + +# 21,32818 "200 Type okay.\r\n" +[in,ppp0] +4500 0038 ffe4 4000 ef06 130b 96cb e002 +0101 0101 0015 8032 3786 7897 bd6b c9ef +5018 269c 1f58 0000 3230 3020 5479 7065 +206f 6b61 792e 0d0a + +# 32818,21 ACK +[out,ppp0] +4500 0028 10d3 4000 ff06 3283 c0a8 0103 +96cb e002 8032 0015 bd6b c9ef 3786 78a7 +5010 269c 98ee 0000 + +# 32818,21 ACK "PORT 192,158,1,3,128,51\r\n" +[out,ppp0] +4500 0041 10d4 4000 ff06 3269 c0a8 0103 +96cb e002 8032 0015 bd6b c9ef 3786 78a7 +5018 269c 1c4d 0000 504f 5254 2031 3932 +2c31 3638 2c31 2c33 2c31 3238 2c35 310d +0a + +# 32818,21 ACK "200 PORT command successful.\r\n" +[in,ppp0] +4500 0046 ffe5 4000 ef06 12fc 96cb e002 +0101 0101 0015 8032 3786 78a7 bd6b ca08 +5018 269c 9b71 0000 3230 3020 504f 5254 +2063 6f6d 6d61 6e64 2073 7563 6365 7373 +6675 6c2e 0d0a + +# 32818,21 "TYPE A\r\n" +[out,ppp0] +4500 0030 10d5 4000 ff06 3279 c0a8 0103 +96cb e002 8032 0015 bd6b ca08 3786 78c5 +5018 269c c6bd 0000 5459 5045 2041 0d0a + +# 21,32818 "200 Type okay.\r\n" +[in,ppp0] +4500 0038 ffe6 4000 ef06 1309 96cb e002 +0101 0101 0015 8032 3786 78c5 bd6b ca10 +5018 269c 1f09 0000 3230 3020 5479 7065 +206f 6b61 792e 0d0a + +# 32818,21 "NLST\r\n" +[out,ppp0] +4500 002e 10d6 4000 ff06 327a c0a8 0103 +96cb e002 8032 0015 bd6b ca10 3786 78d5 +5018 269c e9e6 0000 4e4c 5354 0d0a + +# 20,32819 SYN +[in,ppp0] +4500 002c ffe7 4000 ef06 1314 96cb e002 +0101 0101 0014 8033 d9f8 11d4 0000 0000 +6002 2238 913a 0000 0204 0584 + +# 32819,20 SYN+ACK +[out,ppp0] +4500 002c 10d7 4000 ff06 327b c0a8 0103 +96cb e002 8033 0014 bd78 5c12 d9f8 11d5 +6012 02f8 d734 0000 0204 0584 + +# 20,32819 ACK +[in,ppp0] +4500 0028 ffe8 4000 ef06 1317 96cb e002 +0101 0101 0014 8033 d9f8 11d5 bd78 5c13 +5010 269c 8ac7 0000 + +# 21,32818 ACK "150 Opening ASCII mode data connection for /bin/ls.\r\n" +[in,ppp0] +4500 005d ffe9 4000 ef06 12e1 96cb e002 +0101 0101 0015 8032 3786 78d5 bd6b ca16 +5018 269c ae7e 0000 3135 3020 4f70 656e +696e 6720 4153 4349 4920 6d6f 6465 2064 +6174 6120 636f 6e6e 6563 7469 6f6e 2066 +6f72 202f 6269 6e2f 6c73 2e0d 0a + +# 32819,20 ACK +[out,ppp0] +4500 0028 10d8 4000 ff06 327e c0a8 0103 +96cb e002 8033 0014 bd78 5c13 d9f8 11d5 +5010 6348 8e71 0000 + +# 32818,21 ACK+PUSH "PORT 192,158,1,3,128,52\r\n" +[out,ppp0] +4500 0041 10d9 4000 ff06 3264 c0a8 0103 +96cb e002 8032 0015 bd6b ca16 3786 78d5 +5018 269c 1af8 0000 504f 5254 2031 3932 +2c31 3638 2c31 2c33 2c31 3238 2c35 320d +0a + +# 21,32818 ACK+PUSH "200 PORT command successful\r\n" +[in,ppp0] +4500 0046 ffea 4000 ef06 12f7 96cb e002 +0101 0101 0015 8032 3786 78d5 bd6b ca2f +5018 269c 9b1c 0000 3230 3020 504f 5254 +2063 6f6d 6d61 6e64 2073 7563 6365 7373 +6675 6c2e 0d0a + +# 32818,21 ACK+PUSH "TYPE A\r\n" +[out,ppp0] +4500 0030 10da 4000 ff06 3274 c0a8 0103 +96cb e002 8032 0015 bd6b ca2f 3786 78f3 +5018 269c c668 0000 5459 5045 2041 0d0a + +# 21,32818 "200 Type okay.\r\n" +[in,ppp0] +4500 0038 ffeb 4000 ef06 1304 96cb e002 +0101 0101 0015 8032 3786 78f3 bd6b ca37 +5018 269c 1ea4 0000 3230 3020 5479 7065 +206f 6b61 793e 0d0a + +# 32818,21 ACK+PUSH "NLST\r\n" +[out,ppp0] +4500 002e 10db 4000 ff06 3275 c0a8 0103 +96cb e002 8032 0015 bd6b ca37 3786 7903 +5018 269c e991 0000 4e4c 5354 0d0a + +# 20,32820 2nd connection SYN +[in,ppp0] +4500 002c ffec 4000 ef06 130f 96cb e002 +0101 0101 0014 8034 d9f8 11d4 0000 0000 +6002 2238 9139 0000 0204 0584 + +# 32820,20 SYN+ACK +[out,ppp0] +4500 002c 10d7 4000 ff06 327b c0a8 0103 +96cb e002 8034 0014 bd78 5c12 d9f8 11d5 +6012 02f8 d733 0000 0204 0584 + +# 20,32820 ACK +[in,ppp0] +4500 0028 ffec 4000 ef06 1313 96cb e002 +0101 0101 0014 8034 d9f8 11d4 0000 0000 +5010 2238 a8b7 0000 + +# 20,32819 ACK+PUSH +[in,ppp0] +4500 0063 ffed 4000 ef06 12d7 96cb e002 +0101 0101 0014 8033 d9f8 11d5 bd78 5c13 +5018 269c 62bf 0000 636f 6f6d 6273 7061 +7065 7273 0d0a 6465 7074 730d 0a66 6f75 +6e64 2d66 696c 6573 0d0a 696e 636f 6d69 +6e67 0d0a 6e6c 632d 7465 7374 0d0a 7075 +620d 0a + +# 32819,20 ACK +[out,ppp0] +4500 0028 10dc 4000 ff06 327a c0a8 0103 +96cb e002 8033 0014 bd78 5c13 d9f8 1210 +5010 6348 8e36 0000 + +# 20,32819 FIN+ACK +[in,ppp0] +4500 0028 ffee 4000 ef06 1311 96cb e002 +0101 0101 0014 8033 d9f8 1210 bd78 5c13 +5011 269c 8a8b 0000 + +# 32819,20 ACK +[out,ppp0] +4500 0028 10dd 4000 ff06 3279 c0a8 0103 +96cb e002 8033 0014 bd78 5c13 d9f8 1211 +5010 6348 8e35 0000 + +# 32819,20 FIN+ACK +[out,ppp0] +4500 0028 10dd 4000 ff06 3279 c0a8 0103 +96cb e002 8033 0014 bd78 5c13 d9f8 1211 +5011 6348 8e34 0000 + +# 20,32819 ACK +[in,ppp0] +4500 0028 ffef 4000 ef06 1310 96cb e002 +0101 0101 0014 8033 d9f8 1211 bd78 5c14 +5010 269c 8a8a 0000 + +# 21,32818 220 "226 Listing completed.\r\n" +[in,ppp0] +4500 0040 fff0 4000 ef06 12f7 96cb e002 +0101 0101 0015 8032 3786 7903 bd6b ca37 +5018 269c 3c32 0000 3232 3620 4c69 7374 +696e 6720 636f 6d70 6c65 7465 642e 0d0a + +# 32818,21 ACK +[out,ppp0] +4500 0028 10e0 4000 ff06 3276 c0a8 0103 +96cb e002 8032 0015 bd6b ca37 3786 791b +5010 269c 9832 0000 + +# 32818,21 "QUIT\r\n" +[out,ppp0] +4500 002e 10e1 4000 ff06 326f c0a8 0103 +96cb e002 8032 0015 bd6b ca37 3786 791b +5018 269c f070 0000 5155 4954 0d0a + +# 21,32818 "221 Goodbye." +[in,ppp0] +4500 0036 fff2 4000 ef06 12ff 96cb e002 +0101 0101 0015 8032 3786 791b bd6b ca3d +5018 269c 68e8 0000 3232 3120 476f 6f64 +6279 652e 0d0a + +# 32818,21 ACK+FIN +[out,ppp0] +4500 0028 10e2 4000 ff06 3274 c0a8 0103 +96cb e002 8032 0015 bd6b ca3d 3786 7929 +5011 269c 981d 0000 + +# 21,32818 ACK+FIN +[in,ppp0] +4500 0028 fff3 4000 ef06 130c 96cb e002 +0101 0101 0015 8032 3786 7929 bd6b ca3d +5011 269c 57c7 0000 + +# 32818,21 ACK +[out,ppp0] +4500 0028 10e3 4000 ff06 3273 c0a8 0103 +96cb e002 8032 0015 bd6b ca3d 3786 792a +5010 269c 981d 0000 + +# 21,32818 ACK +[in,ppp0] +4500 0028 fff4 4000 ef06 130b 96cb e002 +0101 0101 0015 8032 3786 792a bd6b ca3e +5010 269c 57c6 0000 + diff --git a/contrib/netbsd-tests/ipf/input/ni6 b/contrib/netbsd-tests/ipf/input/ni6 new file mode 100644 index 0000000..70e80c0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni6 @@ -0,0 +1,54 @@ +[in,nf0] +4500 0054 cd8a 4000 ff11 20ba c0a8 0601 +c0a8 0602 8075 006f 0040 d36d 3e1d d249 +0000 0000 0000 0002 0001 86a0 0000 0002 +0000 0003 0000 0000 0000 0000 0000 0000 +0000 0000 0001 86a3 0000 0003 0000 0011 +0000 0000 + +[out,qfe0] +4500 0054 cd8a 4000 ff11 1fbb c0a8 0601 +c0a8 0701 8075 006f 0040 d26e 3e1d d249 +0000 0000 0000 0002 0001 86a0 0000 0002 +0000 0003 0000 0000 0000 0000 0000 0000 +0000 0000 0001 86a3 0000 0003 0000 0011 +0000 0000 + +[in,qfe0] +4500 0038 cd83 4000 ff11 1edd c0a8 0701 +c0a8 0702 006f 8075 0024 d704 3e1d d249 +0000 0001 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0801 + +[out,nf0] +4500 0038 cd83 4000 ff11 1fde c0a8 0701 +c0a8 0601 006f 8075 0024 d805 3e1d d249 +0000 0001 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0801 + +[in,nf0] +4500 0044 d5a6 4000 ff11 18ae c0a8 0601 +c0a8 0602 80df 0801 0030 04f0 3e10 1fb1 +0000 0000 0000 0002 0001 86a3 0000 0002 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +[out,qfe0] +4500 0044 d5a6 4000 ff11 17af c0a8 0601 +c0a8 0701 80df 0801 0030 03f1 3e10 1fb1 +0000 0000 0000 0002 0001 86a3 0000 0002 +0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 + +[in,qfe0] +4500 0034 0000 4000 fe11 ed64 c0a8 0701 +c0a8 0702 0801 80df 0020 89b7 3e10 1fb1 +0000 0001 0000 0000 0000 0000 0000 0000 +0000 0000 + +[out,nf0] +4500 0034 0000 4000 fe11 ee65 c0a8 0701 +c0a8 0601 0801 80df 0020 0000 3e10 1fb1 +0000 0001 0000 0000 0000 0000 0000 0000 +0000 0000 + diff --git a/contrib/netbsd-tests/ipf/input/ni7 b/contrib/netbsd-tests/ipf/input/ni7 new file mode 100644 index 0000000..8d07937 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni7 @@ -0,0 +1,13 @@ +#v tos len id off ttl p sum src dst +# ICMP timeout exceeded in reply to a ICMP packet coming in. +[in,df0] +4500 0028 4706 4000 0111 26b4 0404 0404 0202 0202 +afc9 829e 0014 6b10 0402 0000 +3be5 468d 000a cfc3 + +[out,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 +0b00 0125 0000 0000 +4500 0028 4706 4000 0111 1eac 0404 0404 0606 0606 +afc9 829e 0014 c15e + diff --git a/contrib/netbsd-tests/ipf/input/ni8 b/contrib/netbsd-tests/ipf/input/ni8 new file mode 100644 index 0000000..72205ee --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni8 @@ -0,0 +1,27 @@ +#v tos len id off ttl p sum src dst +[in,df0] +4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 +5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +[out,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 +0303 0fa3 0000 0000 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 +5000 9d58 0000 0001 + +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[out,df0] +4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 +0303 0735 0000 0000 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 +5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 +0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going in) +[out,df0] +4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 +0303 0fa3 0000 0000 +4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 +5000 9d58 0000 0001 + diff --git a/contrib/netbsd-tests/ipf/input/ni9 b/contrib/netbsd-tests/ipf/input/ni9 new file mode 100644 index 0000000..b8f4599 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/ni9 @@ -0,0 +1,27 @@ +#v tos len id off ttl p sum src dst +# ICMP dest unreachable with 64 bits in payload (in reply to a TCP packet +# going out) +[in,df0] +4500 003c 4706 4000 ff06 20aa 0404 0404 0a02 0202 +5000 0500 0000 0001 0000 0000 a002 16d0 cc32 0000 0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +[out,df0] +4500 0038 809a 0000 ff01 2d1d 0303 0303 0404 0404 +0303 0fa3 0000 0000 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 +5000 9d58 0000 0001 + +# ICMP dest unreachable with whole packet in payload (40 bytes = 320 bits) +[out,df0] +4500 0058 809a 0000 ff01 2cfd 0303 0303 0404 0404 +0303 0735 0000 0000 +4500 003c 4706 4000 ff06 2aac 0404 0404 0101 0101 +5000 9d58 0000 0001 0000 0000 a002 16d0 3ddc 0000 +0204 05b4 0402 080a 0047 fbb0 0000 0000 0103 0300 + +[out,df0] +4500 0038 809a 0000 ff01 2b1b 0303 0303 0505 0505 +0303 0fa3 0000 0000 +4500 003c 4706 4000 ff06 2aab 0404 0404 0101 0102 +5000 9d58 0000 0001 + diff --git a/contrib/netbsd-tests/ipf/input/p1 b/contrib/netbsd-tests/ipf/input/p1 new file mode 100644 index 0000000..f6753fa --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/p1 @@ -0,0 +1,8 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.2.1.1 +out 127.0.0.1 127.0.0.1 +out 1.1.1.1 1.2.1.1 +in 2.3.0.1 1.2.1.1 +in 2.2.2.1 1.2.1.1 +in 2.2.0.1 1.2.1.1 +out 4.4.1.1 1.2.1.1 diff --git a/contrib/netbsd-tests/ipf/input/p10 b/contrib/netbsd-tests/ipf/input/p10 new file mode 100644 index 0000000..f8162e8 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/p10 @@ -0,0 +1,10 @@ +in on bge0 tcp 5.5.5.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.9,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.9,10000 9.9.9.9,80 diff --git a/contrib/netbsd-tests/ipf/input/p11 b/contrib/netbsd-tests/ipf/input/p11 new file mode 100644 index 0000000..f8162e8 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/p11 @@ -0,0 +1,10 @@ +in on bge0 tcp 5.5.5.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.9,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.9,10000 9.9.9.9,80 diff --git a/contrib/netbsd-tests/ipf/input/p12 b/contrib/netbsd-tests/ipf/input/p12 new file mode 100644 index 0000000..f8162e8 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/p12 @@ -0,0 +1,10 @@ +in on bge0 tcp 5.5.5.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.9,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.9,10000 9.9.9.9,80 diff --git a/contrib/netbsd-tests/ipf/input/p13 b/contrib/netbsd-tests/ipf/input/p13 new file mode 100644 index 0000000..f6753fa --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/p13 @@ -0,0 +1,8 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.2.1.1 +out 127.0.0.1 127.0.0.1 +out 1.1.1.1 1.2.1.1 +in 2.3.0.1 1.2.1.1 +in 2.2.2.1 1.2.1.1 +in 2.2.0.1 1.2.1.1 +out 4.4.1.1 1.2.1.1 diff --git a/contrib/netbsd-tests/ipf/input/p2 b/contrib/netbsd-tests/ipf/input/p2 new file mode 100644 index 0000000..f6753fa --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/p2 @@ -0,0 +1,8 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.2.1.1 +out 127.0.0.1 127.0.0.1 +out 1.1.1.1 1.2.1.1 +in 2.3.0.1 1.2.1.1 +in 2.2.2.1 1.2.1.1 +in 2.2.0.1 1.2.1.1 +out 4.4.1.1 1.2.1.1 diff --git a/contrib/netbsd-tests/ipf/input/p3 b/contrib/netbsd-tests/ipf/input/p3 new file mode 100644 index 0000000..4a6666b --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/p3 @@ -0,0 +1,12 @@ +in 1.1.1.1 1.2.1.1 +in 1.2.1.1 1.1.1.1 +out 1.1.1.1 1.2.1.1 +out 1.2.1.1 1.1.1.1 +in 2.2.2.2 2.1.2.1 +out 2.1.2.1 2.2.2.2 +in 3.3.1.1 3.1.3.1 +out 3.1.3.1 3.3.1.1 +in 4.4.1.1 4.1.4.1 +out 4.1.4.1 4.4.1.1 +in 5.5.1.1 5.1.5.1 +out 5.1.5.1 5.5.1.1 diff --git a/contrib/netbsd-tests/ipf/input/p4 b/contrib/netbsd-tests/ipf/input/p4 new file mode 100644 index 0000000..46c0998 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/p4 @@ -0,0 +1,12 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.2.1.1 +out 127.0.0.1 127.0.0.1 +out 1.1.1.1 1.2.1.1 +in 2.3.0.1 1.2.1.1 +in 2.2.2.1 1.2.1.1 +in 2.2.0.1 1.2.1.1 +out 2.2.2.1 1.2.1.1 +out 2.2.2.1 1.2.1.2 +out 2.2.0.1 1.2.1.1 +out 2.2.0.1 1.2.1.3 +out 4.4.1.1 1.2.1.1 diff --git a/contrib/netbsd-tests/ipf/input/p5 b/contrib/netbsd-tests/ipf/input/p5 new file mode 100644 index 0000000..f6753fa --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/p5 @@ -0,0 +1,8 @@ +in 127.0.0.1 127.0.0.1 +in 1.1.1.1 1.2.1.1 +out 127.0.0.1 127.0.0.1 +out 1.1.1.1 1.2.1.1 +in 2.3.0.1 1.2.1.1 +in 2.2.2.1 1.2.1.1 +in 2.2.0.1 1.2.1.1 +out 4.4.1.1 1.2.1.1 diff --git a/contrib/netbsd-tests/ipf/input/p6 b/contrib/netbsd-tests/ipf/input/p6 new file mode 100644 index 0000000..37c26ce --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/p6 @@ -0,0 +1,2 @@ +in 131.107.1.1 10.1.1.1 +out 10.1.1.1 131.107.1.1 diff --git a/contrib/netbsd-tests/ipf/input/p7 b/contrib/netbsd-tests/ipf/input/p7 new file mode 100644 index 0000000..f8162e8 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/p7 @@ -0,0 +1,10 @@ +in on bge0 tcp 5.5.5.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.9,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.9,10000 9.9.9.9,80 diff --git a/contrib/netbsd-tests/ipf/input/p9 b/contrib/netbsd-tests/ipf/input/p9 new file mode 100644 index 0000000..f8162e8 --- /dev/null +++ b/contrib/netbsd-tests/ipf/input/p9 @@ -0,0 +1,10 @@ +in on bge0 tcp 5.5.5.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.5.9,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.5,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.6,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.7,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.8,10000 9.9.9.9,80 +in on bge0 tcp 5.5.6.9,10000 9.9.9.9,80 diff --git a/contrib/netbsd-tests/ipf/regress/bpf-f1 b/contrib/netbsd-tests/ipf/regress/bpf-f1 new file mode 100644 index 0000000..2c80283 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/bpf-f1 @@ -0,0 +1,4 @@ +pass in bpf-v4 { "0x20 0 0 0xc 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass out bpf-v4 { "0x20 0 0 0xc 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass in bpf-v4 { "0x20 0 0 0x10 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass out bpf-v4 { "0x20 0 0 0x10 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } diff --git a/contrib/netbsd-tests/ipf/regress/bpf1 b/contrib/netbsd-tests/ipf/regress/bpf1 new file mode 100644 index 0000000..5d83b77 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/bpf1 @@ -0,0 +1,4 @@ +pass in bpf-v4 { "0x20 0 0 0xc 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass out bpf-v4 { "src host 1.1.1.1" } +pass in bpf-v4 { "0x20 0 0 0x10 0x15 0 0x1 0x1010101 0x6 0 0 0x60 0x6 0 0 0" } +pass out bpf-v4 { "dst host 1.1.1.1" } diff --git a/contrib/netbsd-tests/ipf/regress/f1 b/contrib/netbsd-tests/ipf/regress/f1 new file mode 100644 index 0000000..6a2ede9 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f1 @@ -0,0 +1,4 @@ +block in all +pass in all +block out all +pass out all diff --git a/contrib/netbsd-tests/ipf/regress/f10 b/contrib/netbsd-tests/ipf/regress/f10 new file mode 100644 index 0000000..3552983 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f10 @@ -0,0 +1,18 @@ +block in from any to any with not ipopts +pass in from any to any with not opt sec-class topsecret +block in from any to any with not opt ssrr,sec-class topsecret +pass in from any to any with not opt ssrr,sec-class topsecret +block in from any to any with not opt ts,sec-class topsecret +pass in from any to any with not opt ts,sec-class topsecret +block in from any to any with not opt sec-class secret +pass in from any to any with not opt sec-class secret +block in from any to any with not opt lsrr,ssrr +pass in from any to any with not opt lsrr,ssrr +pass in from any to any with not ipopts +block in from any to any with not opt lsrr +pass in from any to any with not opt lsrr +block in from any to any with not opt ssrr,ts +pass in from any to any with not opt ssrr,ts +block in from any to any with not opt rr +pass in from any to any with not opt rr +block in from any to any with not opt sec-class topsecret diff --git a/contrib/netbsd-tests/ipf/regress/f11 b/contrib/netbsd-tests/ipf/regress/f11 new file mode 100644 index 0000000..a71e528 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f11 @@ -0,0 +1,7 @@ +pass in proto tcp from any to any port = 23 flags S/SA keep state +block in proto tcp from any to any port = 23 flags S/SA keep state +pass in proto udp from any to any port = 53 keep frags +block in proto udp from any to any port = 53 keep frags +pass in proto udp from any to any port = 53 keep state +block in proto udp from any to any port = 53 keep state +pass in on e0 proto tcp from any to any port = 25 keep state diff --git a/contrib/netbsd-tests/ipf/regress/f12 b/contrib/netbsd-tests/ipf/regress/f12 new file mode 100644 index 0000000..c29f839 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f12 @@ -0,0 +1,6 @@ +pass in proto tcp from any port > 1024 to any port = 25 with not short +pass in proto tcp from any port > 1024 to any port = 25 +block in proto tcp from any to any with short +block in proto tcp from any to any with frag +pass in proto udp from any port = 53 to any port = 53 +block in proto udp from any port = 53 to any port = 53 with not short diff --git a/contrib/netbsd-tests/ipf/regress/f13 b/contrib/netbsd-tests/ipf/regress/f13 new file mode 100644 index 0000000..393a65e --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f13 @@ -0,0 +1,9 @@ +pass in proto tcp from any to any port = 25 flags S/SA keep frags +block in proto tcp from any to any port = 25 flags S/SA keep frags +pass in proto udp from any to any port = 53 keep frags +block in proto udp from any to any port = 53 keep frags +pass in proto tcp from any to any port = 25 flags S/SA keep state keep frags +block in proto tcp from any to any port = 25 flags S/SA keep state keep frags +pass in proto udp from any to any port = 53 keep frags(strict) +pass in proto tcp from any to any port = 25 keep state(strict) +pass in proto tcp from any to any port = 25 keep state(loose) diff --git a/contrib/netbsd-tests/ipf/regress/f14 b/contrib/netbsd-tests/ipf/regress/f14 new file mode 100644 index 0000000..06ab519 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f14 @@ -0,0 +1,8 @@ +block in from !1.1.1.1 to any +pass in from 1.1.1.1 to !any +block in from 1.1.1.0/24 to !any +pass in from !1.1.1.0/24 to any +block in from !1.1.0.0/16 to any +pass in from 1.1.0.0/16 to !1.2.0.0/16 +block in from any to !127.0.0.0/8 +pass in from !any to any diff --git a/contrib/netbsd-tests/ipf/regress/f15 b/contrib/netbsd-tests/ipf/regress/f15 new file mode 100644 index 0000000..16185e1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f15 @@ -0,0 +1,8 @@ +block in log quick on hme0 from any to 195.134.65.0/25 head 10 +block return-rst in log quick proto tcp all flags S head 100 group 10 +pass in quick proto tcp from any to any port = 22 keep state group 100 +pass in quick proto tcp from any to any port = 23 keep state group 100 +pass in quick proto tcp from any to any port = 21 keep state group 100 +block return-icmp in quick proto udp all keep state head 110 group 10 +pass in quick proto udp from any to any port = 53 keep state group 110 +block in log quick on hme0 from any to any diff --git a/contrib/netbsd-tests/ipf/regress/f16 b/contrib/netbsd-tests/ipf/regress/f16 new file mode 100644 index 0000000..920ad8c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f16 @@ -0,0 +1,10 @@ +pass in all +skip 2 in proto tcp all +block in quick proto tcp all +skip 4 in proto udp all +block in quick proto udp all +pass in quick proto tcp from any to 1.1.1.1 +pass in quick proto tcp from any to 1.1.1.2 port = 22 +block in quick proto udp from any to any port = 53 +pass in quick proto udp from any to any port = 53 +block in all diff --git a/contrib/netbsd-tests/ipf/regress/f17 b/contrib/netbsd-tests/ipf/regress/f17 new file mode 100644 index 0000000..9a75ae3 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f17 @@ -0,0 +1,4 @@ +block in all +block out all +pass out quick on ppp0 proto tcp all flags S keep state +block return-rst in quick proto tcp all diff --git a/contrib/netbsd-tests/ipf/regress/f18 b/contrib/netbsd-tests/ipf/regress/f18 new file mode 100644 index 0000000..acba2b3 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f18 @@ -0,0 +1,4 @@ +pass in from 1.1.1.1 to any +pass out from 2.2.2.2 to any +count in from 1.1.1.1 to 3.3.3.3 +count out from 2.2.2.2 to 4.4.4.4 diff --git a/contrib/netbsd-tests/ipf/regress/f19 b/contrib/netbsd-tests/ipf/regress/f19 new file mode 100644 index 0000000..d7770b8 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f19 @@ -0,0 +1,2 @@ +pass in quick proto tcp all flags S keep state +pass in quick proto tcp all flags S keep state(limit 1) diff --git a/contrib/netbsd-tests/ipf/regress/f2 b/contrib/netbsd-tests/ipf/regress/f2 new file mode 100644 index 0000000..e2f02a4 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f2 @@ -0,0 +1,6 @@ +block in proto tcp from any to any +pass in proto tcp from any to any +block in proto udp from any to any +pass in proto udp from any to any +block in proto icmp from any to any +pass in proto icmp from any to any diff --git a/contrib/netbsd-tests/ipf/regress/f20 b/contrib/netbsd-tests/ipf/regress/f20 new file mode 100644 index 0000000..279523e --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f20 @@ -0,0 +1,4 @@ +block out quick on de0 head 100 +skip 1 out group 100 +block out quick group 100 +pass out quick group 100 diff --git a/contrib/netbsd-tests/ipf/regress/f21 b/contrib/netbsd-tests/ipf/regress/f21 new file mode 100644 index 0000000..26ffa87 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f21 @@ -0,0 +1,2 @@ +pass out proto tcp all flags S keep state(icmp-head icmpredir) +block in proto icmp all icmp-type redir group icmpredir diff --git a/contrib/netbsd-tests/ipf/regress/f22 b/contrib/netbsd-tests/ipf/regress/f22 new file mode 100644 index 0000000..10765db --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f22 @@ -0,0 +1,2 @@ +pass in proto tcp all flags S keep state(icmp-head icmpredir) +block out proto icmp all icmp-type redir group icmpredir diff --git a/contrib/netbsd-tests/ipf/regress/f24 b/contrib/netbsd-tests/ipf/regress/f24 new file mode 100644 index 0000000..5cb3bab --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f24 @@ -0,0 +1 @@ +pass out quick proto udp all keep state keep frags diff --git a/contrib/netbsd-tests/ipf/regress/f25 b/contrib/netbsd-tests/ipf/regress/f25 new file mode 100644 index 0000000..c018b49 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f25 @@ -0,0 +1 @@ +pass in on hme0 proto udp all with mcast keep state diff --git a/contrib/netbsd-tests/ipf/regress/f26 b/contrib/netbsd-tests/ipf/regress/f26 new file mode 100644 index 0000000..22357a4 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f26 @@ -0,0 +1,6 @@ +pass in quick proto tcp from 1.1.1.0/24 to any port = 22 flags S keep state(max-srcs 3) +pass in quick proto tcp from 1.1.1.0/24 to any port = 22 flags S keep state(max-srcs 3, max-per-src 1/32) +pass in quick proto tcp from 1.1.1.0/24 to any port = 22 flags S keep state(max-srcs 3, max-per-src 1/16) +pass in quick proto tcp all flags S keep state(max-srcs 3) +pass in quick proto tcp all flags S keep state(max-srcs 3, max-per-src 1/32) +pass in quick proto tcp all flags S keep state(max-srcs 3, max-per-src 1/16) diff --git a/contrib/netbsd-tests/ipf/regress/f27 b/contrib/netbsd-tests/ipf/regress/f27 new file mode 100644 index 0000000..22357a4 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f27 @@ -0,0 +1,6 @@ +pass in quick proto tcp from 1.1.1.0/24 to any port = 22 flags S keep state(max-srcs 3) +pass in quick proto tcp from 1.1.1.0/24 to any port = 22 flags S keep state(max-srcs 3, max-per-src 1/32) +pass in quick proto tcp from 1.1.1.0/24 to any port = 22 flags S keep state(max-srcs 3, max-per-src 1/16) +pass in quick proto tcp all flags S keep state(max-srcs 3) +pass in quick proto tcp all flags S keep state(max-srcs 3, max-per-src 1/32) +pass in quick proto tcp all flags S keep state(max-srcs 3, max-per-src 1/16) diff --git a/contrib/netbsd-tests/ipf/regress/f28.ipf b/contrib/netbsd-tests/ipf/regress/f28.ipf new file mode 100644 index 0000000..ca42771 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f28.ipf @@ -0,0 +1,2 @@ +block in all +pass in on nic0 to dstlist/spread from 4.4.0.0/16 to any diff --git a/contrib/netbsd-tests/ipf/regress/f28.pool b/contrib/netbsd-tests/ipf/regress/f28.pool new file mode 100644 index 0000000..499b603 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f28.pool @@ -0,0 +1,2 @@ +pool ipf/dstlist (name spread; policy round-robin;) + { nic0:1.1.0.2; nic1:1.1.1.2; nic2:1.1.2.2; nic3:1.1.3.2; }; diff --git a/contrib/netbsd-tests/ipf/regress/f29.ipf b/contrib/netbsd-tests/ipf/regress/f29.ipf new file mode 100644 index 0000000..e4634cc --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f29.ipf @@ -0,0 +1,2 @@ +block in all +pass in on nic0 to dstlist/spread from 4.4.0.0/16 to any keep state diff --git a/contrib/netbsd-tests/ipf/regress/f29.pool b/contrib/netbsd-tests/ipf/regress/f29.pool new file mode 100644 index 0000000..499b603 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f29.pool @@ -0,0 +1,2 @@ +pool ipf/dstlist (name spread; policy round-robin;) + { nic0:1.1.0.2; nic1:1.1.1.2; nic2:1.1.2.2; nic3:1.1.3.2; }; diff --git a/contrib/netbsd-tests/ipf/regress/f3 b/contrib/netbsd-tests/ipf/regress/f3 new file mode 100644 index 0000000..ee80729 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f3 @@ -0,0 +1,8 @@ +block in from 1.1.1.1 to any +pass in from 1.1.1.1 to any +block in from 1.1.1.1/24 to any +pass in from 1.1.1.1/24 to any +block in from 1.1.1.1/16 to any +pass in from 1.1.1.1/16 to any +block in from 1.1.1.1/0 to any +pass in from 1.1.1.1/0 to any diff --git a/contrib/netbsd-tests/ipf/regress/f30 b/contrib/netbsd-tests/ipf/regress/f30 new file mode 100644 index 0000000..84a8970 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f30 @@ -0,0 +1,4 @@ +pass in on hme0 proto udp all with not ipopts keep state +pass in on hme0 proto udp all with ipopts keep state +pass in on hme0 proto tcp all flags S with opt rr keep state +pass in on hme0 proto tcp all flags S with opt sec-class secret keep state diff --git a/contrib/netbsd-tests/ipf/regress/f4 b/contrib/netbsd-tests/ipf/regress/f4 new file mode 100644 index 0000000..bc8af2f --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f4 @@ -0,0 +1,8 @@ +block in from any to 1.1.1.1 +pass in from any to 1.1.1.1 +block in from any to 1.1.1.1/24 +pass in from any to 1.1.1.1/24 +block in from any to 1.1.1.1/16 +pass in from any to 1.1.1.1/16 +block in from any to 1.1.1.1/0 +pass in from any to 1.1.1.1/0 diff --git a/contrib/netbsd-tests/ipf/regress/f5 b/contrib/netbsd-tests/ipf/regress/f5 new file mode 100644 index 0000000..998eabd --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f5 @@ -0,0 +1,48 @@ +block in proto tcp from any port = 23 to any +block in proto udp from any port = 23 to any +block in proto tcp/udp from any port = 23 to any +pass in proto tcp from any port <= 1023 to any +pass in proto udp from any port <= 1023 to any +pass in proto tcp/udp from any port <= 1023 to any +block in proto tcp from any port >= 1024 to any +block in proto udp from any port >= 1024 to any +block in proto tcp/udp from any port >= 1024 to any +pass in proto tcp from any port >= 1024 to any +pass in proto udp from any port >= 1024 to any +pass in proto tcp/udp from any port >= 1024 to any +block in proto tcp from any port 0 >< 512 to any +block in proto udp from any port 0 >< 512 to any +block in proto tcp/udp from any port 0 >< 512 to any +pass in proto tcp from any port 0 >< 512 to any +pass in proto udp from any port 0 >< 512 to any +pass in proto tcp/udp from any port 0 >< 512 to any +block in proto tcp from any port 6000 <> 6009 to any +block in proto udp from any port 6000 <> 6009 to any +block in proto tcp/udp from any port 6000 <> 6009 to any +pass in proto tcp from any port 6000 <> 6009 to any +pass in proto udp from any port 6000 <> 6009 to any +pass in proto tcp/udp from any port 6000 <> 6009 to any +pass in proto tcp from any port = 23 to any +pass in proto udp from any port = 23 to any +pass in proto tcp/udp from any port = 23 to any +block in proto tcp from any port != 21 to any +block in proto udp from any port != 21 to any +block in proto tcp/udp from any port != 21 to any +pass in proto tcp from any port != 21 to any +pass in proto udp from any port != 21 to any +pass in proto tcp/udp from any port != 21 to any +block in proto tcp from any port < 1024 to any +block in proto udp from any port < 1024 to any +block in proto tcp/udp from any port < 1024 to any +pass in proto tcp from any port < 1024 to any +pass in proto udp from any port < 1024 to any +pass in proto tcp/udp from any port < 1024 to any +block in proto tcp from any port > 1023 to any +block in proto udp from any port > 1023 to any +block in proto tcp/udp from any port > 1023 to any +pass in proto tcp from any port > 1023 to any +pass in proto udp from any port > 1023 to any +pass in proto tcp/udp from any port > 1023 to any +block in proto tcp from any port <= 1023 to any +block in proto udp from any port <= 1023 to any +block in proto tcp/udp from any port <= 1023 to any diff --git a/contrib/netbsd-tests/ipf/regress/f6 b/contrib/netbsd-tests/ipf/regress/f6 new file mode 100644 index 0000000..291f09a --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f6 @@ -0,0 +1,48 @@ +block in proto tcp from any to any port = 23 +block in proto udp from any to any port = 23 +block in proto tcp/udp from any to any port = 23 +pass in proto tcp from any to any port <= 1023 +pass in proto udp from any to any port <= 1023 +pass in proto tcp/udp from any to any port <= 1023 +block in proto tcp from any to any port >= 1024 +block in proto udp from any to any port >= 1024 +block in proto tcp/udp from any to any port >= 1024 +pass in proto tcp from any to any port >= 1024 +pass in proto udp from any to any port >= 1024 +pass in proto tcp/udp from any to any port >= 1024 +block in proto tcp from any to any port 0 >< 512 +block in proto udp from any to any port 0 >< 512 +block in proto tcp/udp from any to any port 0 >< 512 +pass in proto tcp from any to any port 0 >< 512 +pass in proto udp from any to any port 0 >< 512 +pass in proto tcp/udp from any to any port 0 >< 512 +block in proto tcp from any to any port 6000 <> 6009 +block in proto udp from any to any port 6000 <> 6009 +block in proto tcp/udp from any to any port 6000 <> 6009 +pass in proto tcp from any to any port 6000 <> 6009 +pass in proto udp from any to any port 6000 <> 6009 +pass in proto tcp/udp from any to any port 6000 <> 6009 +pass in proto tcp from any to any port = 23 +pass in proto udp from any to any port = 23 +pass in proto tcp/udp from any to any port = 23 +block in proto tcp from any to any port != 21 +block in proto udp from any to any port != 21 +block in proto tcp/udp from any to any port != 21 +pass in proto tcp from any to any port != 21 +pass in proto udp from any to any port != 21 +pass in proto tcp/udp from any to any port != 21 +block in proto tcp from any to any port < 1024 +block in proto udp from any to any port < 1024 +block in proto tcp/udp from any to any port < 1024 +pass in proto tcp from any to any port < 1024 +pass in proto udp from any to any port < 1024 +pass in proto tcp/udp from any to any port < 1024 +block in proto tcp from any to any port > 1023 +block in proto udp from any to any port > 1023 +block in proto tcp/udp from any to any port > 1023 +pass in proto tcp from any to any port > 1023 +pass in proto udp from any to any port > 1023 +pass in proto tcp/udp from any to any port > 1023 +block in proto tcp from any to any port <= 1023 +block in proto udp from any to any port <= 1023 +block in proto tcp/udp from any to any port <= 1023 diff --git a/contrib/netbsd-tests/ipf/regress/f7 b/contrib/netbsd-tests/ipf/regress/f7 new file mode 100644 index 0000000..be1b969 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f7 @@ -0,0 +1,9 @@ +block in proto icmp from any to any icmp-type echo +pass in proto icmp from any to any icmp-type echo +block in proto icmp from any to any icmp-type unreach code 3 +pass in proto icmp from any to any icmp-type unreach code 3 +block in proto icmp from any to any icmp-type echorep +pass in proto icmp from any to any icmp-type echorep +pass in proto icmp all icmp-type maskreq keep state +pass in proto icmp all icmp-type timest keep state +pass in proto icmp all icmp-type inforeq keep state diff --git a/contrib/netbsd-tests/ipf/regress/f8 b/contrib/netbsd-tests/ipf/regress/f8 new file mode 100644 index 0000000..0f28fd2 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f8 @@ -0,0 +1,6 @@ +block in proto tcp from any to any flags S +pass in proto tcp from any to any flags S +block in proto tcp from any to any flags S/SA +pass in proto tcp from any to any flags S/SA +block in proto tcp from any to any flags S/APU +pass in proto tcp from any to any flags S/APU diff --git a/contrib/netbsd-tests/ipf/regress/f9 b/contrib/netbsd-tests/ipf/regress/f9 new file mode 100644 index 0000000..17bc967 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/f9 @@ -0,0 +1,18 @@ +block in from any to any with ipopts +pass in from any to any with opt sec-class topsecret +block in from any to any with opt ssrr,sec-class topsecret +pass in from any to any with opt ssrr,sec-class topsecret +block in from any to any with opt ts,sec-class topsecret +pass in from any to any with opt ts,sec-class topsecret +block in from any to any with opt sec-class secret +pass in from any to any with opt sec-class secret +block in from any to any with opt lsrr,ssrr +pass in from any to any with opt lsrr,ssrr +pass in from any to any with ipopts +block in from any to any with opt lsrr +pass in from any to any with opt lsrr +block in from any to any with opt ssrr,ts +pass in from any to any with opt ssrr,ts +block in from any to any with opt rr +pass in from any to any with opt rr +block in from any to any with opt sec-class topsecret diff --git a/contrib/netbsd-tests/ipf/regress/i1 b/contrib/netbsd-tests/ipf/regress/i1 new file mode 100644 index 0000000..0fd2c6e --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i1 @@ -0,0 +1,18 @@ +pass in all +block out \ +all +log in all +log body in all +count in from any to any +pass in from !any to any pps 10 +block in from any to !any +pass in on ed0 from localhost to localhost +pass in on ed0,vx0 from localhost to localhost +block in log first on lo0 from any to any +pass in log body or-block quick from any to any +block return-rst in quick on le0 proto tcp from any to any +block return-icmp in on qe0 from any to any +block return-icmp(1) in on qe0 from any to any +block return-icmp-as-dest in on le0 from any to any +block return-icmp-as-dest(port-unr) in on qe0 from any to any +pass out on longNICname0 from test.host.dots to test\.host.dots diff --git a/contrib/netbsd-tests/ipf/regress/i10 b/contrib/netbsd-tests/ipf/regress/i10 new file mode 100644 index 0000000..640ac84 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i10 @@ -0,0 +1,5 @@ +pass in from localhost to localhost with opt sec +pass in from localhost to localhost with opt lsrr not opt sec +block in from any to any with not opt sec-class topsecret +block in from any to any with not opt sec-class topsecret,secret +pass in from any to any with opt sec-class topsecret,confid not opt sec-class unclass diff --git a/contrib/netbsd-tests/ipf/regress/i11 b/contrib/netbsd-tests/ipf/regress/i11 new file mode 100644 index 0000000..ca65da3 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i11 @@ -0,0 +1,12 @@ +pass in on ed0 proto tcp from localhost to localhost port = telnet keep state +block in log first on lo0 proto tcp/udp from any to any port = echo keep state +pass in proto udp from localhost to localhost port = 20499 keep frag +pass in proto udp from localhost to localhost port = 2049 keep frag(strict) +pass in proto udp from localhost to localhost port = 53 keep state keep frags +pass in on ed0 out-via vx0 proto udp from any to any keep state +pass out on ppp0 in-via le0 proto tcp from any to any keep state +pass in on ed0,vx0 out-via vx0,ed0 proto udp from any to any keep state +pass in proto tcp from any port gt 1024 to localhost port eq 1024 keep state +pass in proto tcp all flags S keep state(strict,newisn,no-icmp-err,limit 101,age 600) +pass in proto tcp all flags S keep state(loose,newisn,no-icmp-err,limit 101,age 600) +pass in proto udp all keep state(age 10/20,sync) diff --git a/contrib/netbsd-tests/ipf/regress/i12 b/contrib/netbsd-tests/ipf/regress/i12 new file mode 100644 index 0000000..f42c2d5 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i12 @@ -0,0 +1,10 @@ +pass in from 1.1.1.1/32 to 2.2.2.2/32 +pass in from {2.2.2.2/24,3.3.3.3/32} to 4.4.4.4/32 +pass in from {2.2.2.2/24,3.3.3.3/32} to {5.5.5.5/32,6.6.6.6/32} +pass in from {2.2.2.2/24,3.3.3.3/32} to {5.5.5.5/32,6.6.6.6/32} port = {22,25} +pass in proto tcp from {2.2.2.2/24,3.3.3.3/32} port = {53,9} to {5.5.5.5/32,6.6.6.6/32} +pass in proto udp from {2.2.2.2/24,3.3.3.3/32} to {5.5.5.5/32,6.6.6.6/32} port = {53,9} +pass in from 10.10.10.10 to 11.11.11.11 +pass in from pool/101 to hash/202 +pass in from hash/303 to pool/404 +pass in from pool=(!1.1.1.1,2.2.2.2,!2.2.0.0/16) to pool = ( 1.1.0.0/16 ) diff --git a/contrib/netbsd-tests/ipf/regress/i13 b/contrib/netbsd-tests/ipf/regress/i13 new file mode 100644 index 0000000..3ba343d --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i13 @@ -0,0 +1,8 @@ +a=any; +b="from $a"; +c='to $a'; +d=block; +e="pass in"; +$d in $b $c +f=" $b $c"; +$e${f} diff --git a/contrib/netbsd-tests/ipf/regress/i14 b/contrib/netbsd-tests/ipf/regress/i14 new file mode 100644 index 0000000..6788af6 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i14 @@ -0,0 +1,15 @@ +block in on eri0 all head 1 +pass in on eri0 proto icmp all group 1 +pass out on ed0 all head 1000000 +block out on ed0 proto udp all group 1000000 +block in on vm0 proto tcp/udp all head 101 +pass in from 1.1.1.1 to 2.2.2.2 group 101 +pass in proto tcp from 1.0.0.1 to 2.0.0.2 group 101 +pass in proto udp from 2.0.0.2 to 3.0.0.3 group 101 +block in on vm0 proto tcp/udp all head vm0-group +pass in from 1.1.1.1 to 2.2.2.2 group vm0-group +block in on vm0 proto tcp/udp all head vm0-group +pass in from 1.1.1.1 to 2.2.2.2 group vm0-group +pass in from 8f:: to f8:: +block in inet6 proto udp +block in inet6 diff --git a/contrib/netbsd-tests/ipf/regress/i15 b/contrib/netbsd-tests/ipf/regress/i15 new file mode 100644 index 0000000..0e6b0d1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i15 @@ -0,0 +1,4 @@ +pass out on fxp0 all set-tag(log=100) +pass out on fxp0 all set-tag(nat=foo) +pass out on fxp0 all set-tag(log=100, nat=200) +pass out on fxp0 all set-tag(log=2147483648, nat=overtherainbowisapotof) diff --git a/contrib/netbsd-tests/ipf/regress/i16 b/contrib/netbsd-tests/ipf/regress/i16 new file mode 100644 index 0000000..5c9144a --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i16 @@ -0,0 +1,3 @@ +0 block out all +100 pass in all +10101 pass out proto tcp all diff --git a/contrib/netbsd-tests/ipf/regress/i17 b/contrib/netbsd-tests/ipf/regress/i17 new file mode 100644 index 0000000..139b86a --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i17 @@ -0,0 +1,13 @@ +100 pass in all +200 pass in proto tcp all +110 pass in proto udp all +110 pass in from localhost to any +pass in all +pass in from localhost to any +@0 100 pass in from localhost to any +@1 pass in from any to localhost +@0 pass in from 1.1.1.1 to any +@1 110 pass in from 2.2.2.2 to any +@2 pass in from 3.3.3.3 to any +call srcgrpmap/100 out from 10.1.0.0/16 to any +call now dstgrpmap/200 in from 10.2.0.0/16 to any diff --git a/contrib/netbsd-tests/ipf/regress/i18 b/contrib/netbsd-tests/ipf/regress/i18 new file mode 100644 index 0000000..b55b11a --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i18 @@ -0,0 +1,3 @@ +pass in tos {80,0x80} all +pass out tos {0x80,80} all +block in ttl {0,1,2,3,4,5,6} all diff --git a/contrib/netbsd-tests/ipf/regress/i19 b/contrib/netbsd-tests/ipf/regress/i19 new file mode 100644 index 0000000..a09fd56 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i19 @@ -0,0 +1,22 @@ +block in quick log level user.debug proto icmp all +block in quick log level mail.info proto icmp all +block in quick log level daemon.notice proto icmp all +block in quick log level auth.warn proto icmp all +block in quick log level syslog.err proto icmp all +block in quick log level lpr.crit proto icmp all +block in quick log level news.alert proto icmp all +block in quick log level uucp.emerg proto icmp all +block in quick log level cron.debug proto icmp all +block in quick log level ftp.info proto icmp all +block in quick log level authpriv.notice proto icmp all +block in quick log level logalert.warn proto icmp all +block in quick log level local0.err proto icmp all +block in quick log level local1.crit proto icmp all +block in quick log level local2.alert proto icmp all +block in quick log level local3.emerg proto icmp all +block in quick log level local4.debug proto icmp all +block in quick log level local5.info proto icmp all +block in quick log level local6.notice proto icmp all +block in quick log level local7.warn proto icmp all +block in quick log level kern.err proto icmp all +block in quick log level security.emerg proto icmp all diff --git a/contrib/netbsd-tests/ipf/regress/i2 b/contrib/netbsd-tests/ipf/regress/i2 new file mode 100644 index 0000000..f69e28e --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i2 @@ -0,0 +1,9 @@ +log in proto tcp all +pass in proto 6 from any to any +pass in proto udp from localhost to localhost +block in proto ipv6 from any to any +block in proto 17 from any to any +block in proto 250 from any to any +pass in proto tcp/udp from any to any +block in proto tcp-udp from any to any +block in proto tcp-udp from any to any diff --git a/contrib/netbsd-tests/ipf/regress/i20 b/contrib/netbsd-tests/ipf/regress/i20 new file mode 100644 index 0000000..99039ee --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i20 @@ -0,0 +1,4 @@ +pass in on ppp0 from ppp0/peer to ppp0/32 +block in on hme0 from any to hme0/broadcast +pass in on bge0 from bge0/network to bge0/32 +block in on eri0 from any to eri0/netmasked diff --git a/contrib/netbsd-tests/ipf/regress/i21 b/contrib/netbsd-tests/ipf/regress/i21 new file mode 100644 index 0000000..237f8fa --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i21 @@ -0,0 +1,7 @@ +pass in from port = 10101 +pass out from any to port != 22 +block in from port 20:21 +block out from any to port 10 <> 100 +pass out from any to port = {3,5,7,9} +block in from port = {20,25} +pass in from any port = {11:12, 21:22} to any port = {1:2, 4:5, 8:9} diff --git a/contrib/netbsd-tests/ipf/regress/i22 b/contrib/netbsd-tests/ipf/regress/i22 new file mode 100644 index 0000000..1ac8d12 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i22 @@ -0,0 +1,5 @@ +pass in exp { "ip.src != 1.1.1.0/24; tcp.dport = 80;" } +pass in exp { "ip.addr = 1.2.3.4,5.6.7.8;" } +block out exp { "ip.dst= 127.0.0.0/8;" } +block in exp { "udp.sport=53;udp.dport=53;" } +pass out exp { "tcp.sport=22; tcp.port=25;" } diff --git a/contrib/netbsd-tests/ipf/regress/i23 b/contrib/netbsd-tests/ipf/regress/i23 new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i23 @@ -0,0 +1 @@ +# diff --git a/contrib/netbsd-tests/ipf/regress/i3 b/contrib/netbsd-tests/ipf/regress/i3 new file mode 100644 index 0000000..390fc3c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i3 @@ -0,0 +1,14 @@ +log in all +pass in from 128.16/16 to 129.10.10/24 +pass in from 128.0.0.1/24 to 1\ +28\ +.\ +0.0.1/16 +pass in from 128.0.0.1/0xffffff00 to 128.0.0.1/0xffff0000 +pass in from 128.0.0.1/255.255.255.0 to 128.0.0.1/255.255.0.0 +pass in from 128.0.0.1 mask 0xffffff00 to 128.0.0.1 mask 0xffff0000 +pass in from 128.0.0.1 mask 255.255.255.0 to 128.0.0.1 mask 255.255.0.0 +pass in from localhost to localhost +block in log from 0/0 to 0/0 +block in log level auth.info on hme0 all +log level local5.warn out all diff --git a/contrib/netbsd-tests/ipf/regress/i4 b/contrib/netbsd-tests/ipf/regress/i4 new file mode 100644 index 0000000..8551f76 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i4 @@ -0,0 +1,9 @@ +log in proto tcp from any port > 0 to any +log in proto tcp from any to any port > 0 +pass in proto 6 from any port != 0 to any port 0 >< 65535 +pass in proto 17 from localhost port > 32000 to localhost port < 29000 +block in proto udp from any port != \ntp to any port < echo +block in proto tcp from any port = smtp to any port > 25 +pass in proto tcp/udp from any port 1 >< 3 to any port 1 <> 3 +pass in proto tcp/udp from any port 2:2 to any port 10:20 +pass in log first quick proto tcp from any port > 1023 to any port = 1723 flags S keep state diff --git a/contrib/netbsd-tests/ipf/regress/i5 b/contrib/netbsd-tests/ipf/regress/i5 new file mode 100644 index 0000000..788f971 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i5 @@ -0,0 +1,9 @@ +log in all +count in tos 0x80 from any to any +pass in on ed0 tos 64 from localhost to localhost +block in log on lo0 ttl 0 from any to any +pass in quick ttl 1 from any to any +skip 3 out from 127.0.0.1 to any +auth out on foo0 proto tcp from any to any port = 80 +preauth out on foo0 proto tcp from any to any port = 22 +nomatch out on foo0 proto tcp from any port < 1024 to any diff --git a/contrib/netbsd-tests/ipf/regress/i6 b/contrib/netbsd-tests/ipf/regress/i6 new file mode 100644 index 0000000..0b371bd --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i6 @@ -0,0 +1,12 @@ +pass in on lo0 fastroute from any to any +pass in on lo0 to qe0 from localhost to localhost +pass in on le0 to qe0:127.0.0.1 from localhost to localhost +pass in on lo0 dup-to qe0 from localhost to localhost +pass in on le0 dup-to qe0:127.0.0.1 from localhost to localhost +pass in on le0 to hme0:10.1.1.1 dup-to qe0:127.0.0.1 from localhost to localhost +block in quick on qe0 to qe1 from any to any +block in quick to qe1 from any to any +pass out quick dup-to hme0 from any to any +pass out quick on hme0 reply-to hme1 from any to any +pass in on le0 dup-to qe0:127.0.0.1 reply-to hme1:10.10.10.10 all +pass in quick fastroute all diff --git a/contrib/netbsd-tests/ipf/regress/i7 b/contrib/netbsd-tests/ipf/regress/i7 new file mode 100644 index 0000000..15b88a5 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i7 @@ -0,0 +1,14 @@ +pass in on ed0 proto tcp from localhost to localhost port = 23 flags S/SA +block in on lo0 proto tcp from any to any flags A +pass in on lo0 proto tcp from any to any flags /SAP +block in on lo0 proto tcp from any to any flags 0x80/A +pass in on lo0 proto tcp from any to any flags S/18 +block in on lo0 proto tcp from any to any flags 2/18 +pass in on lo0 proto tcp from any to any flags 2 +block in on lo0 proto tcp from any to any flags /16 +pass in on lo0 proto tcp from any to any flags 2/SA +pass in on lo0 proto tcp from any to any flags S/18 +block in on lo0 proto tcp from any to any flags 2/18 +pass in on lo0 proto tcp from any to any flags 2 +block in on lo0 proto tcp from any to any flags /16 +pass in on lo0 proto tcp from any to any flags 2/SA diff --git a/contrib/netbsd-tests/ipf/regress/i8 b/contrib/netbsd-tests/ipf/regress/i8 new file mode 100644 index 0000000..abf69d9 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i8 @@ -0,0 +1,62 @@ +pass in proto icmp from localhost to localhost icmp-type timest +block in proto icmp from any to any icmp-type unreach code 1 +pass in proto icmp all icmp-type unreach code cutoff-preced +pass in proto icmp all icmp-type unreach code filter-prohib +pass in proto icmp all icmp-type unreach code isolate +pass in proto icmp all icmp-type unreach code needfrag +pass in proto icmp all icmp-type unreach code net-prohib +pass in proto icmp all icmp-type unreach code net-tos +pass in proto icmp all icmp-type unreach code host-preced +pass in proto icmp all icmp-type unreach code host-prohib +pass in proto icmp all icmp-type unreach code host-tos +pass in proto icmp all icmp-type unreach code host-unk +pass in proto icmp all icmp-type unreach code host-unr +pass in proto icmp all icmp-type unreach code {net-unk,net-unr} +pass in proto icmp all icmp-type unreach code port-unr +pass in proto icmp all icmp-type unreach code proto-unr +pass in proto icmp all icmp-type unreach code srcfail +pass in proto icmp all icmp-type {echo,echorep} +pass in proto icmp all icmp-type inforeq +pass in proto icmp all icmp-type inforep +pass in proto icmp all icmp-type maskrep +pass in proto icmp all icmp-type maskreq +pass in proto icmp all icmp-type paramprob +pass in proto icmp all icmp-type redir +pass in proto icmp all icmp-type unreach +pass in proto icmp all icmp-type routerad +pass in proto icmp all icmp-type routersol +pass in proto icmp all icmp-type squench +pass in proto icmp all icmp-type timest +pass in proto icmp all icmp-type timestrep +pass in proto icmp all icmp-type timex +pass in proto icmp all icmp-type 254 +pass in proto icmp all icmp-type 253 code 254 +pass in proto icmp all icmp-type unreach code cutoff-preced +pass in proto icmp all icmp-type unreach code filter-prohib +pass in proto icmp all icmp-type unreach code isolate +pass in proto icmp all icmp-type unreach code needfrag +pass in proto icmp all icmp-type unreach code net-prohib +pass in proto icmp all icmp-type unreach code net-tos +pass in proto icmp all icmp-type unreach code host-preced +pass in proto icmp all icmp-type unreach code host-prohib +pass in proto icmp all icmp-type unreach code host-tos +pass in proto icmp all icmp-type unreach code host-unk +pass in proto icmp all icmp-type unreach code host-unr +pass in proto icmp all icmp-type unreach code {net-unk,net-unr} +pass in proto icmp all icmp-type unreach code port-unr +pass in proto icmp all icmp-type unreach code proto-unr +pass in proto icmp all icmp-type unreach code srcfail +pass in proto icmp all icmp-type {echo,echorep} +pass in proto icmp all icmp-type inforeq +pass in proto icmp all icmp-type inforep +pass in proto icmp all icmp-type maskrep +pass in proto icmp all icmp-type maskreq +pass in proto icmp all icmp-type paramprob +pass in proto icmp all icmp-type redir +pass in proto icmp all icmp-type unreach +pass in proto icmp all icmp-type routerad +pass in proto icmp all icmp-type routersol +pass in proto icmp all icmp-type squench +pass in proto icmp all icmp-type timest +pass in proto icmp all icmp-type timestrep +pass in proto icmp all icmp-type timex diff --git a/contrib/netbsd-tests/ipf/regress/i9 b/contrib/netbsd-tests/ipf/regress/i9 new file mode 100644 index 0000000..441cfa9 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/i9 @@ -0,0 +1,17 @@ +pass in from localhost to localhost with short,frags +block in from any to any with ipopts +pass in from any to any with opt nop,rr,zsu +pass in from any to any with opt nop,rr,zsu not opt ssrr,lsrr +pass in from localhost to localhost and not frag +pass in from localhost to localhost with frags,frag-body +pass in proto tcp all flags S with not oow keep state +block in proto tcp all with oow +pass in proto tcp all flags S with not bad,bad-src,bad-nat +block in proto tcp all flags S with bad,not bad-src,not bad-nat +pass in quick all with not short +block in quick all with not nat +pass in quick all with not frag-body +block in quick all with not lowttl +pass in all with mbcast,not bcast,multicast,not state,not ipopts +block in all with not mbcast,bcast,not multicast,state +pass in from any to any with opt mtur,mtup,encode,ts,tr,sec,cipso,satid,ssrr,visa,imitd,eip,finn,dps,sdb,nsapa,rtralrt,ump,addext,e-sec diff --git a/contrib/netbsd-tests/ipf/regress/in1 b/contrib/netbsd-tests/ipf/regress/in1 new file mode 100644 index 0000000..d5d0cf4 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in1 @@ -0,0 +1,31 @@ +map le0 0/0 -> 0/32 +map le0 1/32 -> 1/32 +map le0 128.0.0.0/1 -> 0/0 +map le0 10.0.0.0/8 -> 1.2.3.0/24 +map le0 10.0.0.5/8 -> 1.2.3.4/24 +map le0 10.0.0.5/0xff000000 -> 1.2.3.4/24 +map le0 10.0.0.5/0xff -> 1.2.3.4/24 +map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 +map ppp0 192.168.0.0/16 -> 0/32 portmap udp 20000:29999 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp/udp 30000:39999 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp auto +map ppp0 192.168.0.0/16 -> 0/32 portmap udp auto +map ppp0 192.168.0.0/16 -> 0/32 portmap tcpudp auto +map ppp0 192.168.0.0/16 -> 0/32 proxy port ftp ftp/6 +map ppp0 192.168.0.0/16 -> 0/32 proxy port 1010 ftp/tcp +map le0 0/0 -> 0/32 frag +map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 frag +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 frag +map ppp0 192.168.0.0/16 -> 0/32 proxy port ftp ftp/tcp frag +map le0 0/0 -> 0/32 age 10 +map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 age 10/20 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 age 30 +map le0 0/0 -> 0/32 frag age 10 +map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 frag age 10/20 +map ppp0 192.168.0.0/16 -> 0/32 portmap tcp 10000:19999 frag age 30 +map fxp0 from 192.168.0.0/18 to 0/0 port = 21 -> 1.2.3.4/32 proxy port 21 ftp/tcp +map thisisalonginte 0/0 -> 0/32 mssclamp 1452 tag freddyliveshere +map bar0 0/0 -> 0/32 icmpidmap icmp 1000:2000 +map ppp0,adsl0 0/0 -> 0/32 +map ppp0 from 192.168.0.0/16 to any port = 123 -> 0/32 age 30/1 udp diff --git a/contrib/netbsd-tests/ipf/regress/in100 b/contrib/netbsd-tests/ipf/regress/in100 new file mode 100644 index 0000000..5e2ab6c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in100 @@ -0,0 +1,3 @@ +rewrite in on bge0 from 1.1.1.1 to 2.2.2.2 -> src 3.3.3.3 dst 4.4.4.4; +rewrite out on bge0 from 1.1.1.1/32 to 2.2.2.2 -> src 3.3.3.0/24 dst 4.4.4.4; +rewrite in on bge0 from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.0/24 dst 4.4.4.0/24; diff --git a/contrib/netbsd-tests/ipf/regress/in100_6 b/contrib/netbsd-tests/ipf/regress/in100_6 new file mode 100644 index 0000000..533e2dd --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in100_6 @@ -0,0 +1,3 @@ +rewrite in on bge0 inet6 from 1:1:1::1 to 2:2::2:2 -> src 3:3:3::3 dst 4::4:4:4; +rewrite out on bge0 inet6 from 1:1:1::1/128 to 2:2::2:2 -> src 3:3:3::0/96 dst 4::4:4:4; +rewrite in on bge0 inet6 from 1:1:1::1/128 to 2:2::2:2/128 -> src 3:3:3::0/96 dst 4::4:4:4/96; diff --git a/contrib/netbsd-tests/ipf/regress/in101 b/contrib/netbsd-tests/ipf/regress/in101 new file mode 100644 index 0000000..afef53b --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in101 @@ -0,0 +1,4 @@ +rewrite in on bge0 proto icmp from 1.1.1.1 to 2.2.2.2 -> src 3.3.3.3 dst 4.4.4.4; +rewrite in on bge0 proto udp from 1.1.1.1 to 2.2.2.2 -> src 3.3.3.3 dst 4.4.4.4; +rewrite out on bge0 proto tcp from 1.1.1.1/32 to 2.2.2.2 -> src 3.3.3.0/24 dst 4.4.4.4; +rewrite in on bge0 proto tcp/udp from 1.1.1.1/32 to 2.2.2.2/32 -> src 3.3.3.0/24,20202 dst 4.4.4.0/24,10101; diff --git a/contrib/netbsd-tests/ipf/regress/in101_6 b/contrib/netbsd-tests/ipf/regress/in101_6 new file mode 100644 index 0000000..bb4af3d --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in101_6 @@ -0,0 +1,4 @@ +rewrite in on bge0 proto icmp from 1:1:1::1 to 2:2::2:2 -> src 3:3:3::3 dst 4::4:4:4; +rewrite in on bge0 proto udp from 1:1:1::1 to 2:2::2:2 -> src 3:3:3::3 dst 4::4:4:4; +rewrite out on bge0 proto tcp from 1:1:1::1/128 to 2:2::2:2 -> src 3:3:3::0/24 dst 4::4:4:4; +rewrite in on bge0 proto tcp/udp from 1:1:1::1/128 to 2:2::2:2/32 -> src 3:3:3::0/24,20202 dst 4::4:4:4/24,10101; diff --git a/contrib/netbsd-tests/ipf/regress/in102 b/contrib/netbsd-tests/ipf/regress/in102 new file mode 100644 index 0000000..57f3645 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in102 @@ -0,0 +1,5 @@ +rewrite in on bge0 proto tcp from any to any -> src 0/0 dst dstlist/a; +rewrite in on bge0 proto tcp from 1.1.1.1 to any -> src 0/0 dst dstlist/bee; +rewrite in on bge0 proto tcp from 1.1.1.1 to 2.2.2.2 -> src 0/0 dst dstlist/cat; +rewrite in on bge0 proto tcp from pool/a to 2.2.2.2 -> src 0/0 dst dstlist/bat; +rewrite in on bge0 proto tcp from pool/a to pool/1 -> src 0/0 dst dstlist/ant; diff --git a/contrib/netbsd-tests/ipf/regress/in102_6 b/contrib/netbsd-tests/ipf/regress/in102_6 new file mode 100644 index 0000000..e11906d --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in102_6 @@ -0,0 +1,5 @@ +rewrite in on bge0 inet6 proto tcp from any to any -> src 0/0 dst dstlist/a; +rewrite in on bge0 inet6 proto tcp from 1:1:1::1 to any -> src 0/0 dst dstlist/bee; +rewrite in on bge0 inet6 proto tcp from 1:1:1::1 to 2:2::2:2 -> src 0/0 dst dstlist/cat; +rewrite in on bge0 inet6 proto tcp from pool/a to 2:2::2:2 -> src 0/0 dst dstlist/bat; +rewrite in on bge0 inet6 proto tcp from pool/a to pool/1 -> src 0/0 dst dstlist/ant; diff --git a/contrib/netbsd-tests/ipf/regress/in1_6 b/contrib/netbsd-tests/ipf/regress/in1_6 new file mode 100644 index 0000000..e5050f8 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in1_6 @@ -0,0 +1,29 @@ +map le0 inet6 0/0 -> 0/128 +map le0 inet6 1/128 -> 1/128 +map le0 inet6 128::/1 -> 0/0 +map le0 inet6 10::0/16 -> 1:2:3::0/96 +map le0 inet6 10::5/16 -> 1:2:3::4/96 +map le0 inet6 192:168::/32 -> range 203:1:1::23-203:1:3::45 +map ppp0 inet6 192:168::/32 -> 0/128 portmap tcp 10000:19999 +map ppp0 inet6 192:168::/32 -> 0/128 portmap udp 20000:29999 +map ppp0 inet6 192:168::/32 -> 0/128 portmap tcp/udp 30000:39999 +map ppp0 inet6 192:168::/32 -> 0/128 portmap tcp auto +map ppp0 inet6 192:168::/32 -> 0/128 portmap udp auto +map ppp0 inet6 192:168::/32 -> 0/128 portmap tcpudp auto +map ppp0 inet6 192:168::/32 -> 0/128 proxy port ftp ftp/6 +map ppp0 inet6 192:168::/32 -> 0/128 proxy port 1010 ftp/tcp +map le0 inet6 0/0 -> 0/128 frag +map le0 inet6 192:168::/32 -> range 203:1:1::23-203:1:3::45 frag +map ppp0 inet6 192:168::/32 -> 0/128 portmap tcp 10000:19999 frag +map ppp0 inet6 192:168::/32 -> 0/128 proxy port ftp ftp/tcp frag +map le0 inet6 0/0 -> 0/128 age 10 +map le0 inet6 192:168::/32 -> range 203:1:1::23-203:1:3::45 age 10/20 +map ppp0 inet6 192:168::/32 -> 0/128 portmap tcp 10000:19999 age 30 +map le0 inet6 0/0 -> 0/128 frag age 10 +map le0 inet6 192:168::/32 -> range 203:1:1::23-203:1:3::45 frag age 10/20 +map ppp0 inet6 192:168::/32 -> 0/128 portmap tcp 10000:19999 frag age 30 +map fxp0 inet6 from 192:168::/18 to 0/0 port = 21 -> 1:2:3::4/128 proxy port 21 ftp/tcp +map thisisalonginte inet6 0/0 -> 0/128 mssclamp 1452 tag freddyliveshere +map bar0 inet6 0/0 -> 0/128 icmpidmap ipv6-icmp 1000:2000 +map ppp0,adsl0 inet6 0/0 -> 0/128 +map ppp0 inet6 from 192:168::/32 to any port = 123 -> 0/128 age 30/1 udp diff --git a/contrib/netbsd-tests/ipf/regress/in2 b/contrib/netbsd-tests/ipf/regress/in2 new file mode 100644 index 0000000..58556c0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in2 @@ -0,0 +1,71 @@ +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 tcp +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 255 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip +rdr le0 9.8.7.6/0xff000000 -> 1.1.1.1 ip +rdr le0 9.8.7.6/0xffff0000 -> 1.1.1.1 ip +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp +rdr le0 9.8.7.6/32 port 80 -> 0/0 port 80 tcp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 udp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp/udp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcpudp frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag +rdr le0 9.8.7.6/32 -> 1.1.1.1 ip frag age 10 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10/20 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag age 10 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip sticky +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10 sticky +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10/20 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag age 10 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30 sticky +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40 sticky +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip mssclamp 1000 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10/20 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag age 10 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40 sticky mssclamp 1000 +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip tag nattagcacheline +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 0 -> 1.1.1.1 port 0 ip frag age 10/20 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 icmp frag age 10 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp frag age 20 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1 port 80 tcp round-robin frag age 30 sticky mssclamp 1000 tag nattagcacheline +rdr le0 9.8.7.6/32 port 80 -> 1.1.1.1,1.1.1.2 port 80 tcp round-robin frag age 40 sticky mssclamp 1000 tag nattagcacheline +rdr ge0 9.8.7.6/32 -> 1.1.1.1 proxy port 21 ftp/tcp +rdr ge0 9.8.7.6/32 port 21 -> 1.1.1.1 port 21 tcp proxy ftp +rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1 port 5555 tcp +rdr le0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1 port = 5555 tcp +rdr le0 0/0 -> test.host.dots +rdr le0 any -> test.host.dots,test.host.dots +rdr adsl0,ppp0 9.8.7.6/32 port 1000-2000 -> 1.1.1.1 port 5555-7777 tcp diff --git a/contrib/netbsd-tests/ipf/regress/in2_6 b/contrib/netbsd-tests/ipf/regress/in2_6 new file mode 100644 index 0000000..1ee1f06 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in2_6 @@ -0,0 +1,71 @@ +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 tcp +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 255 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 tcp +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1 ip +rdr le0 inet6 9:8:7::6/32 -> 1:1:1::1 ip +rdr le0 inet6 9:8:7::6/64 -> 1:1:1::1 ip +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 tcp +rdr le0 inet6 9:8:7::6/128 port 80 -> 0/0 port 80 tcp +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 udp +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 tcp/udp +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 icmp +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 tcp round-robin +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip frag +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 icmp frag +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcpudp frag +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 tcp round-robin frag +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag +rdr le0 inet6 9:8:7::6/128 -> 1:1:1::1 ip frag age 10 +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip frag age 10/20 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 icmp frag age 10 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag age 20 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 tcp round-robin frag age 30 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag age 40 +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip sticky +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip frag sticky +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 icmp frag sticky +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag sticky +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 tcp round-robin frag sticky +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag sticky +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip frag age 10 sticky +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip frag age 10/20 sticky +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 icmp frag age 10 sticky +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag age 20 sticky +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 tcp round-robin frag age 30 sticky +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag age 40 sticky +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip frag sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 icmp frag sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip frag age 10 sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip frag age 10/20 sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 icmp frag age 10 sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag age 20 sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 tcp round-robin frag age 30 sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag age 40 sticky mssclamp 1000 +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 icmp frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip frag age 10 sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 0 -> 1:1:1::1 port 0 ip frag age 10/20 sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 icmp frag age 10 sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp frag age 20 sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1 port 80 tcp round-robin frag age 30 sticky mssclamp 1000 tag nattagcacheline +rdr le0 inet6 9:8:7::6/128 port 80 -> 1:1:1::1,1:1:1::2 port 80 tcp round-robin frag age 40 sticky mssclamp 1000 tag nattagcacheline +rdr ge0 9:8:7::6/128 -> 1:1:1::1 proxy port 21 ftp/tcp +rdr ge0 9:8:7::6/128 port 21 -> 1:1:1::1 port 21 tcp proxy ftp +rdr le0 inet6 9:8:7::6/128 port 1000-2000 -> 1:1:1::1 port 5555 tcp +rdr le0 inet6 9:8:7::6/128 port 1000-2000 -> 1:1:1::1 port = 5555 tcp +rdr le0 inet6 0/0 -> test.host.dots +rdr le0 inet6 any -> test.host.dots,test.host.dots +rdr adsl0,ppp0 9:8:7::6/128 port 1000-2000 -> 1:1:1::1 port 5555-7777 tcp diff --git a/contrib/netbsd-tests/ipf/regress/in3 b/contrib/netbsd-tests/ipf/regress/in3 new file mode 100644 index 0000000..d8016b6 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in3 @@ -0,0 +1,5 @@ +bimap le0 0/0 -> 0/32 +bimap le0 1/32 -> 1/32 +bimap le0 128.0.0.0/1 -> 0/0 +bimap le0 10.0.0.0/8 -> 1.2.3.0/24 +bimap le0 10.0.5.6/24 -> 1.2.3.4/24 diff --git a/contrib/netbsd-tests/ipf/regress/in3_6 b/contrib/netbsd-tests/ipf/regress/in3_6 new file mode 100644 index 0000000..a82ff09 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in3_6 @@ -0,0 +1,5 @@ +bimap le0 inet6 0/0 -> 0/128 +bimap le0 inet6 1/128 -> 1/128 +bimap le0 inet6 128::/1 -> 0/0 +bimap le0 inet6 10::/16 -> 1:2:3::0/96 +bimap le0 inet6 10:0:5::6/96 -> 1:2:3::4/96 diff --git a/contrib/netbsd-tests/ipf/regress/in4 b/contrib/netbsd-tests/ipf/regress/in4 new file mode 100644 index 0000000..46bbd81 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in4 @@ -0,0 +1,5 @@ +map-block le0 10.0.0.0/24 -> 203.1.1.0/24 +map-block le0 10.0.0.0/24 -> 203.1.1.0/24 ports 0 +map-block le0 10.0.0.0/24 -> 203.1.1.0/24 ports 256 +map-block le0 10.0.0.0/24 -> 203.1.1.0/24 ports auto +map-block le0 10.0.0.0/16 -> 203.1.1.0/24 ports auto diff --git a/contrib/netbsd-tests/ipf/regress/in4_6 b/contrib/netbsd-tests/ipf/regress/in4_6 new file mode 100644 index 0000000..b6b78c0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in4_6 @@ -0,0 +1,5 @@ +map-block le0 inet6 10::/96 -> 203:1:1::/96 +map-block le0 inet6 10::/96 -> 203:1:1::/96 ports 0 +map-block le0 inet6 10::/96 -> 203:1:1::/96 ports 256 +map-block le0 inet6 10::/96 -> 203:1:1::/96 ports auto +map-block le0 inet6 10::/16 -> 203:1:1::/96 ports auto diff --git a/contrib/netbsd-tests/ipf/regress/in5 b/contrib/netbsd-tests/ipf/regress/in5 new file mode 100644 index 0000000..766c3e3 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in5 @@ -0,0 +1,24 @@ +map le0 from 9.8.7.6/32 port > 1024 to any -> 1.1.1.1 portmap 10000:20000 tcp +map le0 from 9.8.7.6/32 port > 1024 to ! 1.2.3.4 -> 1.1.1.1 portmap 10000:20000 tcp +rdr le0 from any to 9.8.7.6/32 port = 0 -> 1.1.1.1 port 0 tcp +rdr le0 from any to 9.8.7.6/0xffffffff port = 0 -> 1.1.1.1 port 0 ip +rdr le0 ! from 1.2.3.4 to 9.8.7.6 port = 8888 -> 1.1.1.1 port 888 tcp +rdr le0 from any to 9.8.7.6/255.255.255.255 port = 8888 -> 1.1.1.1 port 888 ip +rdr le0 from any to 9.8.7.6 mask 0xffffffff port = 8888 -> 1.1.1.1 port 888 tcp +rdr le0 from any to 9.8.7.6 mask 255.255.255.255 port = 8888 -> 1.1.1.1 port 888 udp +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp/udp +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 port 888 icmp +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp round-robin +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 port 0 ip frag +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 icmp frag +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp frag +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp round-robin frag +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin frag +rdr le0 from any to 9.8.7.6/32 -> 1.1.1.1 port 0 ip frag age 10 +rdr le0 from any to 9.8.7.6/32 port = 0 -> 1.1.1.1 port 0 ip frag age 10/20 +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 icmp frag age 10 +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp frag age 20 +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1 port 888 tcp round-robin frag age 30 +rdr le0 from any to 9.8.7.6/32 port = 8888 -> 1.1.1.1,1.1.1.2 port 888 tcp round-robin frag age 40 diff --git a/contrib/netbsd-tests/ipf/regress/in5_6 b/contrib/netbsd-tests/ipf/regress/in5_6 new file mode 100644 index 0000000..f39d819 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in5_6 @@ -0,0 +1,24 @@ +map le0 inet6 from 9:8:7::6/128 port > 1024 to any -> 1:1:1::1 portmap 10000:20000 tcp +map le0 inet6 from 9:8:7::6/128 port > 1024 to ! 1:2:3::4 -> 1:1:1::1 portmap 10000:20000 tcp +rdr le0 inet6 from any to 9:8:7::6/128 port = 0 -> 1:1:1::1 port 0 tcp +rdr le0 inet6 from any to 9:8:7::6/128 port = 0 -> 1:1:1::1 port 0 ip +rdr le0 inet6 ! from 1:2:3::4 to 9:8:7::6 port = 8888 -> 1:1:1::1 port 888 tcp +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1 port 888 ip +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1 port 888 tcp +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1 port 888 udp +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1 port 888 tcp/udp +rdr le0 inet6 from any to 9:8:7::6/128 -> 1:1:1::1 port 888 icmp +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1,1:1:1::2 port 888 tcp +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1 port 888 tcp round-robin +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1,1:1:1::2 port 888 tcp round-robin +rdr le0 inet6 from any to 9:8:7::6/128 -> 1:1:1::1 port 0 ip frag +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1 port 888 icmp frag +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1,1:1:1::2 port 888 tcp frag +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1 port 888 tcp round-robin frag +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1,1:1:1::2 port 888 tcp round-robin frag +rdr le0 inet6 from any to 9:8:7::6/128 -> 1:1:1::1 port 0 ip frag age 10 +rdr le0 inet6 from any to 9:8:7::6/128 port = 0 -> 1:1:1::1 port 0 ip frag age 10/20 +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1 port 888 icmp frag age 10 +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1,1:1:1::2 port 888 tcp frag age 20 +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1 port 888 tcp round-robin frag age 30 +rdr le0 inet6 from any to 9:8:7::6/128 port = 8888 -> 1:1:1::1,1:1:1::2 port 888 tcp round-robin frag age 40 diff --git a/contrib/netbsd-tests/ipf/regress/in6 b/contrib/netbsd-tests/ipf/regress/in6 new file mode 100644 index 0000000..70e71dd --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in6 @@ -0,0 +1,8 @@ +map foo0 from any port = 1 to any port != 0 -> 0/32 udp +map foo0 from any port eq 1 to any port ne 0 -> 0/32 udp +map foo0 from any port < 1 to any port > 0 -> 0/32 tcp +map foo0 from any port lt 1 to any port gt 0 -> 0/32 tcp +map foo0 from any port <= 1 to any port >= 0 -> 0/32 tcp/udp +map foo0 from any port le 1 to any port ge 0 -> 0/32 tcp/udp +map foo0 from any port 1 >< 20 to any port 20 <> 40 -> 0/32 tcp/udp +map foo0 from any port 10:20 to any port 30:40 -> 0/32 tcp/udp diff --git a/contrib/netbsd-tests/ipf/regress/in6_6 b/contrib/netbsd-tests/ipf/regress/in6_6 new file mode 100644 index 0000000..556015d --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in6_6 @@ -0,0 +1,8 @@ +map foo0 inet6 from any port = 1 to any port != 0 -> 0/32 udp +map foo0 inet6 from any port eq 1 to any port ne 0 -> 0/32 udp +map foo0 inet6 from any port < 1 to any port > 0 -> 0/32 tcp +map foo0 inet6 from any port lt 1 to any port gt 0 -> 0/32 tcp +map foo0 inet6 from any port <= 1 to any port >= 0 -> 0/32 tcp/udp +map foo0 inet6 from any port le 1 to any port ge 0 -> 0/32 tcp/udp +map foo0 inet6 from any port 1 >< 20 to any port 20 <> 40 -> 0/32 tcp/udp +map foo0 inet6 from any port 10:20 to any port 30:40 -> 0/32 tcp/udp diff --git a/contrib/netbsd-tests/ipf/regress/in7 b/contrib/netbsd-tests/ipf/regress/in7 new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in7 @@ -0,0 +1 @@ +# diff --git a/contrib/netbsd-tests/ipf/regress/in8_6 b/contrib/netbsd-tests/ipf/regress/in8_6 new file mode 100644 index 0000000..ab23b84 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/in8_6 @@ -0,0 +1,6 @@ +map zx0 inet6 10:1::1:1/128 -> 10:2:2::2/128 purge +map zx0 inet6 10:1::1:1/128 -> 10:2:2::2/128 tcp purge +map zx0 inet6 10:1::1:1/128 -> 10:2:2::2/128 mssclamp 1000 purge +map zx0 inet6 10:1::1:1/128 -> 10:2:2::2/128 portmap tcp/udp 10000:11000 purge +map zx0 inet6 10:1::1:1/128 -> 10:2:2::2/128 portmap tcp/udp 10000:11000 sequential purge +map zx0 inet6 10:1::1:1/128 -> 10:2:2::2/128 portmap tcp/udp 10000:11000 sequential purge diff --git a/contrib/netbsd-tests/ipf/regress/ip1 b/contrib/netbsd-tests/ipf/regress/ip1 new file mode 100644 index 0000000..c31ba25 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ip1 @@ -0,0 +1,78 @@ +#:%s/ \(number = [0-9]*\) \(type = [a-z]*\)/ \2 \1/g + +table role = ipf type = tree number = 1 + {; }; +table role = ipf type = tree number = 100 + { 1.2.3.4/32; !2.2.0.0/16; 2.2.2.0/24; }; +table role = nat type = tree number = 110 + { 1.2.3.4/32; !2.2.0.0/16; 2.2.2.0/24; }; +table role = auth type = tree number = 120 + { 1.2.3.4/32; !2.2.0.0/16; 2.2.2.0/24; }; +table role = count type = tree number = 130 + { 1.2.3.4; !2.2.0.0/16; 2.2.2.0/24; }; + +table role = ipf type = hash number = 2 + {; }; +table role = ipf type = hash number = 200 + { 0/0; 1/32; 1.2.3.4/32; }; +table role = nat type = hash number = 210 + { 0/0; 2/32; 1.2.3.4/32; }; +table role = auth type = hash number = 220 + { 0/0; 3/32; 1.2.3.4/32; }; +table role = count type = hash number = 230 + { 0/0; 4/32; 1.2.3.4/32; }; + +table role = ipf type = hash number = 240 seed = 101 + { 0/0; 1/32; 1.2.3.4/32; }; +table role = nat type = hash number = 250 seed = 101 + { 0/0; 2/32; 1.2.3.4/32; }; +table role = auth type = hash number = 260 seed = 101 + { 0/0; 3/32; 1.2.3.4/32; }; +table role = count type = hash number = 270 seed = 101 + { 0/0; 4/32; 1.2.3.4/32; }; + +table role = ipf type = hash number = 2000 size = 1001 + { 0/0; 1/32; 1.2.3.4/32; }; +table role = nat type = hash number = 2000 size = 1001 + { 0/0; 2/32; 1.2.3.4/32; }; +table role = auth type = hash number = 2000 size = 1001 + { 0/0; 3/32; 1.2.3.4/32; }; +table role = count type = hash number = 2000 size = 1001 + { 0/0; 4/32; 1.2.3.4/32; }; + +table role = ipf type = hash number = 100 size = 1001 seed = 101 + { 0/0; 1/32; 1.2.3.4/32; }; +table role = nat type = hash number = 100 size = 1001 seed = 101 + { 0/0; 2/32; 1.2.3.4/32; }; +table role = auth type = hash number = 100 size = 1001 seed = 101 + { 0/0; 3/32; 1.2.3.4/32; }; +table role = count type = hash number = 100 size = 1001 seed = 101 + { 0/0; 4/32; 1.2.3.4/32; }; + +group-map in role = ipf number = 300 group = 303 + { 0/0; 5/32; 1.2.3.4/32; }; +group-map in role = nat number = 300 group = 303 + { 0/0; 6/32; 1.2.3.4/32; }; +group-map in role = auth number = 300 group = 303 + { 0/0; 7/32; 1.2.3.4/32; }; +group-map in role = count number = 300 group = 303 + { 0/0; 8/32; 1.2.3.4/32; }; + +group-map out role = ipf number = 400 group = 303 + { 0/0; 5/32; 1.2.3.4/32, group = 606; }; +group-map out role = nat number = 400 group = 303 + { 0/0; 6/32; 1.2.3.4/32, group = 606; }; +group-map out role = auth number = 400 group = 303 + { 0/0; 7/32; 1.2.3.4/32, group = 606; }; +group-map out role = count number = 400 group = 303 + { 0/0; 8/32; 1.2.3.4/32, group = 606; }; + +group-map in role = ipf number = 500 + { 0/0, group = 10; 5/32, group = 800; 1.2.3.4/32, group = 606; }; +group-map in role = nat number = 500 + { 0/0, group = 10; 6/32, group = 800; 1.2.3.4/32, group = 606; }; +group-map in role = auth number = 500 + { 0/0, group = 10; 7/32, group = 800; 1.2.3.4/32, group = 606; }; +group-map in role = count number = 500 + { 0/0, group = 10; 8/32, group = 800; 1.2.3.4/32, group = 606; }; + diff --git a/contrib/netbsd-tests/ipf/regress/ip2 b/contrib/netbsd-tests/ipf/regress/ip2 new file mode 100644 index 0000000..76f31b6 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ip2 @@ -0,0 +1,2 @@ +table role = ipf type = tree name = letters + { "file://input/ip2.data"; }; diff --git a/contrib/netbsd-tests/ipf/regress/ip3 b/contrib/netbsd-tests/ipf/regress/ip3 new file mode 100644 index 0000000..98d2b0b --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ip3 @@ -0,0 +1,14 @@ +pool ipf/dstlist (name fred; policy round-robin;) + { 3.3.3.3; }; +pool ipf/dstlist (name jack; policy weighted connection;) + { 4.4.4.4; bge0:5.5.5.5;}; +pool ipf/dstlist (name jill; policy random;) + { 1.1.1.1; bge0:2.2.2.2;}; +pool nat/hash (name noproxy; size 17;) + { 1.1.1.1; 2.2.2.2;}; +pool nat/tree (name raw;) + { 1.1.1.1; 2.2.2.2;}; +pool all/dstlist (name jill; policy random;) + { 1.1.1.1; bge0:2.2.2.2;}; +pool all/hash (name noproxy; size 17;) + { 1.1.1.1; 2.2.2.2;}; diff --git a/contrib/netbsd-tests/ipf/regress/ipv6.1 b/contrib/netbsd-tests/ipf/regress/ipv6.1 new file mode 100644 index 0000000..fc532b6 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ipv6.1 @@ -0,0 +1 @@ +pass out log quick on gif0 proto udp from ef00:1001:2002::/48 to any port 33433 >< 34000 keep state diff --git a/contrib/netbsd-tests/ipf/regress/ipv6.2 b/contrib/netbsd-tests/ipf/regress/ipv6.2 new file mode 100644 index 0000000..814dfd6 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ipv6.2 @@ -0,0 +1,3 @@ +block in all +block out all +pass out proto 58 all keep state diff --git a/contrib/netbsd-tests/ipf/regress/ipv6.3 b/contrib/netbsd-tests/ipf/regress/ipv6.3 new file mode 100644 index 0000000..6dc9e93 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ipv6.3 @@ -0,0 +1 @@ +pass out log quick on gif0 proto ipv6-icmp from any to any icmp-type 128 keep state diff --git a/contrib/netbsd-tests/ipf/regress/ipv6.4 b/contrib/netbsd-tests/ipf/regress/ipv6.4 new file mode 100644 index 0000000..b221744 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ipv6.4 @@ -0,0 +1,3 @@ +pass in proto ipv6-icmp all icmp-type echo keep frags +pass in proto ipv6-icmp all icmp-type echo keep frags keep state +pass in proto tcp all keep frags keep state diff --git a/contrib/netbsd-tests/ipf/regress/ipv6.5 b/contrib/netbsd-tests/ipf/regress/ipv6.5 new file mode 100644 index 0000000..d9ae23b --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ipv6.5 @@ -0,0 +1,2 @@ +pass out family inet6 all with v6hdr routing +block out family inet6 proto tcp all with v6hdr routing diff --git a/contrib/netbsd-tests/ipf/regress/ipv6.6 b/contrib/netbsd-tests/ipf/regress/ipv6.6 new file mode 100644 index 0000000..19a4df9 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ipv6.6 @@ -0,0 +1,2 @@ +pass out on gif0 proto udp all keep frag +block out all with bad diff --git a/contrib/netbsd-tests/ipf/regress/l1 b/contrib/netbsd-tests/ipf/regress/l1 new file mode 100644 index 0000000..88cca58 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/l1 @@ -0,0 +1,6 @@ +log in all +pass in on anon0 all head 100 +pass in log quick from 3.3.3.3 to any group 100 +pass in log body quick from 2.2.2.2 to any +pass in log quick proto tcp from 1.1.1.1 to any flags S keep state +pass in log first quick proto tcp from 1.1.1.1 to any flags S keep state diff --git a/contrib/netbsd-tests/ipf/regress/n1 b/contrib/netbsd-tests/ipf/regress/n1 new file mode 100644 index 0000000..9bcf29b --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n1 @@ -0,0 +1,3 @@ +map zx0 10.1.1.1/32 -> 10.2.2.2/32 +map zx0 10.1.1.0/24 -> 10.3.4.5/32 +map zx0 10.1.1.0/24 -> 10.3.4.0/24 diff --git a/contrib/netbsd-tests/ipf/regress/n10 b/contrib/netbsd-tests/ipf/regress/n10 new file mode 100644 index 0000000..0f48192 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n10 @@ -0,0 +1,3 @@ +map ppp0 0/0 -> 203.203.203.203/32 mssclamp 100 +map ppp0 0/0 -> 203.203.203.203/32 mssclamp 1000 +map ppp0 0/0 -> 203.203.203.203/32 mssclamp 10000 diff --git a/contrib/netbsd-tests/ipf/regress/n100 b/contrib/netbsd-tests/ipf/regress/n100 new file mode 100644 index 0000000..a8b6dee --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n100 @@ -0,0 +1 @@ +rewrite out on zx0 from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32 dst 6.6.0.0/16; diff --git a/contrib/netbsd-tests/ipf/regress/n101 b/contrib/netbsd-tests/ipf/regress/n101 new file mode 100644 index 0000000..2f5fcd9 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n101 @@ -0,0 +1 @@ +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32 dst 6.6.0.0/16; diff --git a/contrib/netbsd-tests/ipf/regress/n102 b/contrib/netbsd-tests/ipf/regress/n102 new file mode 100644 index 0000000..f056633 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n102 @@ -0,0 +1 @@ +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32,1000:2000 dst 6.6.0.0/16; diff --git a/contrib/netbsd-tests/ipf/regress/n103 b/contrib/netbsd-tests/ipf/regress/n103 new file mode 100644 index 0000000..c3c27d6 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n103 @@ -0,0 +1 @@ +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.4.4/32,1000-1001 dst 6.6.0.0/16,4000:4001; diff --git a/contrib/netbsd-tests/ipf/regress/n104 b/contrib/netbsd-tests/ipf/regress/n104 new file mode 100644 index 0000000..785f0ad --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n104 @@ -0,0 +1 @@ +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 -> src 4.4.0.0/24,1000-1001 dst 6.6.0.0/16,4000:4001; diff --git a/contrib/netbsd-tests/ipf/regress/n105 b/contrib/netbsd-tests/ipf/regress/n105 new file mode 100644 index 0000000..afe8966 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n105 @@ -0,0 +1 @@ +rewrite in on zx0 proto tcp from 0/0 to 2.2.0.0/16 port = 80 -> src 4.4.4.4/32,1000-1001 dst 6.6.0.0/16 port = 3128; diff --git a/contrib/netbsd-tests/ipf/regress/n106 b/contrib/netbsd-tests/ipf/regress/n106 new file mode 100644 index 0000000..6074ab0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n106 @@ -0,0 +1 @@ +rewrite out on zx0 proto tcp from 0/0 to 2.2.0.0/16 port = 80 -> src 4.4.4.4/32,1000-1001 dst 6.6.0.0/16 port = 3128; diff --git a/contrib/netbsd-tests/ipf/regress/n10_6 b/contrib/netbsd-tests/ipf/regress/n10_6 new file mode 100644 index 0000000..738152d --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n10_6 @@ -0,0 +1,3 @@ +map ppp0 any -> 203.203.203.203/128 mssclamp 100 +map ppp0 any -> 203.203.203.203/128 mssclamp 1000 +map ppp0 any -> 203.203.203.203/128 mssclamp 10000 diff --git a/contrib/netbsd-tests/ipf/regress/n11 b/contrib/netbsd-tests/ipf/regress/n11 new file mode 100644 index 0000000..8cdf7fc --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n11 @@ -0,0 +1,3 @@ +bimap zx0 10.1.1.1/32 -> 1.6.7.8/32 +bimap zx0 10.1.1.0/24 -> 10.2.2.2/32 +bimap zx0 10.1.1.0/24 -> 10.3.4.5/24 diff --git a/contrib/netbsd-tests/ipf/regress/n11_6 b/contrib/netbsd-tests/ipf/regress/n11_6 new file mode 100644 index 0000000..7b428cc --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n11_6 @@ -0,0 +1,3 @@ +bimap zx0 10:1:1::1/128 -> 1::6:7:8/128 +bimap zx0 10:1:1::/112 -> 10::2:2:2/128 +bimap zx0 10:1:1::/112 -> 10::3:4:5/112 diff --git a/contrib/netbsd-tests/ipf/regress/n12 b/contrib/netbsd-tests/ipf/regress/n12 new file mode 100644 index 0000000..933856b --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n12 @@ -0,0 +1 @@ +map le0 192.168.126.0/24 -> 0/32 portmap tcp/udp 10000:20000 sequential diff --git a/contrib/netbsd-tests/ipf/regress/n12_6 b/contrib/netbsd-tests/ipf/regress/n12_6 new file mode 100644 index 0000000..bf21848 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n12_6 @@ -0,0 +1 @@ +map le0 c0a8:7e00::/112 -> 0/128 portmap tcp/udp 10000:20000 diff --git a/contrib/netbsd-tests/ipf/regress/n13 b/contrib/netbsd-tests/ipf/regress/n13 new file mode 100644 index 0000000..8047930 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n13 @@ -0,0 +1 @@ +map le0 192.168.0.0/16 -> range 203.1.1.23-203.1.3.45 diff --git a/contrib/netbsd-tests/ipf/regress/n13_6 b/contrib/netbsd-tests/ipf/regress/n13_6 new file mode 100644 index 0000000..c1d1646 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n13_6 @@ -0,0 +1 @@ +map le0 192:168:1::0/48 -> range 203:0:1::1:23-203:0:1::3:45 diff --git a/contrib/netbsd-tests/ipf/regress/n14 b/contrib/netbsd-tests/ipf/regress/n14 new file mode 100644 index 0000000..6f5d571 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n14 @@ -0,0 +1 @@ +rdr gre0 0/0 port 80 -> 10.1.1.254,10.1.1.253 port 80 tcp sticky diff --git a/contrib/netbsd-tests/ipf/regress/n14_6 b/contrib/netbsd-tests/ipf/regress/n14_6 new file mode 100644 index 0000000..64e88ee --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n14_6 @@ -0,0 +1 @@ +rdr gre0 any port 80 -> 10:1:1::254,10:1:1::253 port 80 tcp sticky diff --git a/contrib/netbsd-tests/ipf/regress/n15 b/contrib/netbsd-tests/ipf/regress/n15 new file mode 100644 index 0000000..062b766 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n15 @@ -0,0 +1,2 @@ +rdr le0 0/0 port 80 -> 3.3.3.3 port 80 tcp +rdr le0 0/0 port 80 -> 3.3.3.3 port 80-88 tcp diff --git a/contrib/netbsd-tests/ipf/regress/n15_6 b/contrib/netbsd-tests/ipf/regress/n15_6 new file mode 100644 index 0000000..e82dd82 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n15_6 @@ -0,0 +1,2 @@ +rdr le0 any port 80 -> 3:0:3::3:3 port 80 tcp +rdr le0 any port 80 -> 3:0:3::3:3 port 80-88 tcp diff --git a/contrib/netbsd-tests/ipf/regress/n16 b/contrib/netbsd-tests/ipf/regress/n16 new file mode 100644 index 0000000..ff8958c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n16 @@ -0,0 +1 @@ +rdr vlan0 from any to 69.248.79.193 port = 38136 -> 172.31.83.24 port 2013 udp diff --git a/contrib/netbsd-tests/ipf/regress/n16_6 b/contrib/netbsd-tests/ipf/regress/n16_6 new file mode 100644 index 0000000..ff8958c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n16_6 @@ -0,0 +1 @@ +rdr vlan0 from any to 69.248.79.193 port = 38136 -> 172.31.83.24 port 2013 udp diff --git a/contrib/netbsd-tests/ipf/regress/n17 b/contrib/netbsd-tests/ipf/regress/n17 new file mode 100644 index 0000000..213f51f --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n17 @@ -0,0 +1 @@ +bimap zx0 0/0 -> 1.1.1.3 diff --git a/contrib/netbsd-tests/ipf/regress/n18 b/contrib/netbsd-tests/ipf/regress/n18 new file mode 100644 index 0000000..792f136 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n18 @@ -0,0 +1,3 @@ +map z0 0/0 -> 1.1.1.1/32 portmap tcp/udp 1:4 sequential +map z0 0/0 -> 1.1.1.1/32 portmap tcp/udp 1000:5000 sequential +map z0 0/0 -> 1.1.1.1/32 portmap tcp/udp 1000:50000 sequential diff --git a/contrib/netbsd-tests/ipf/regress/n1_6 b/contrib/netbsd-tests/ipf/regress/n1_6 new file mode 100644 index 0000000..341f136 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n1_6 @@ -0,0 +1,3 @@ +map zx0 10:1:1::1/128 -> 10::2:2:2/128 +map zx0 10:1:1::/112 -> 10::3:4:5/128 +map zx0 10:1:1::/112 -> 10::3:4:0/112 diff --git a/contrib/netbsd-tests/ipf/regress/n2 b/contrib/netbsd-tests/ipf/regress/n2 new file mode 100644 index 0000000..39a4d72 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n2 @@ -0,0 +1,4 @@ +map zx0 10.1.1.1/32 -> 10.2.2.2/32 portmap tcp 10000:20000 sequential +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000 sequential +map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000 sequential +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001 sequential diff --git a/contrib/netbsd-tests/ipf/regress/n200 b/contrib/netbsd-tests/ipf/regress/n200 new file mode 100644 index 0000000..c792e54 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n200 @@ -0,0 +1 @@ +divert in on bar0 from any to any -> src 127.0.0.1,10101 dst 127.0.0.1,10101 udp; diff --git a/contrib/netbsd-tests/ipf/regress/n2_6 b/contrib/netbsd-tests/ipf/regress/n2_6 new file mode 100644 index 0000000..3a04f33 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n2_6 @@ -0,0 +1,4 @@ +map zx0 10:1:1::1/128 -> 10::2:2:2/128 portmap tcp 10000:20000 sequential +map zx0 10:1:1::/112 -> 10::3:4:5/128 portmap udp 10000:20000 sequential +map zx0 10:1::/32 -> 10::3:4:0/112 portmap tcp/udp 10000:20000 sequential +map zx0 10:1:1::/112 -> 10::3:4:5/128 portmap tcp/udp 40000:40001 sequential diff --git a/contrib/netbsd-tests/ipf/regress/n3 b/contrib/netbsd-tests/ipf/regress/n3 new file mode 100644 index 0000000..82c83dd --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n3 @@ -0,0 +1,2 @@ +map zz0 10.1.0.0/16 -> 192.168.2.0/24 portmap tcp/udp auto +map-block zz0 10.1.0.0/16 -> 192.168.1.0/24 ports 252 diff --git a/contrib/netbsd-tests/ipf/regress/n4 b/contrib/netbsd-tests/ipf/regress/n4 new file mode 100644 index 0000000..e7c0314 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n4 @@ -0,0 +1,6 @@ +rdr zx0 10.1.1.1/32 port 23 -> 10.2.2.1 port 10023 tcp +rdr zx0 10.1.1.0/24 port 23 -> 10.2.2.1 port 10023 tcp +rdr zx0 0/0 port 23 -> 10.2.2.1 port 10023 tcp +rdr zx0 10.1.1.0/24 port 53 -> 10.2.2.1 port 10053 udp +rdr zx0 10.1.1.0/24 port 0 -> 10.2.2.1 port 0 tcp +rdr zx0 10.1.1.0/24 port 0 -> 10.2.2.1 port 0 ip diff --git a/contrib/netbsd-tests/ipf/regress/n4_6 b/contrib/netbsd-tests/ipf/regress/n4_6 new file mode 100644 index 0000000..72dad4c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n4_6 @@ -0,0 +1,6 @@ +rdr zx0 10:1:1::1/128 port 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 10:1:1::/112 port 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 any port 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 10:1:1::/112 port 53 -> 10::2:2:1 port 10053 udp +rdr zx0 10:1:1::/112 port 0 -> 10::2:2:1 port 0 tcp +rdr zx0 10:1:1::/112 port 0 -> 10::2:2:1 port 0 ip diff --git a/contrib/netbsd-tests/ipf/regress/n5 b/contrib/netbsd-tests/ipf/regress/n5 new file mode 100644 index 0000000..d9f1a88 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n5 @@ -0,0 +1,6 @@ +map zx0 10.1.1.1/32 -> 10.2.2.2/32 +map zx0 from 10.1.1.0/24 to 10.1.0.0/16 -> 10.3.4.5/32 +map zx0 from 10.1.1.0/24 ! to 10.1.0.0/16 -> 10.3.4.0/24 +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap udp 10000:20000 sequential +map zx0 10.1.0.0/16 -> 10.3.4.0/24 portmap tcp/udp 10000:20000 sequential +map zx0 10.1.1.0/24 -> 10.3.4.5/32 portmap tcp/udp 40000:40001 sequential diff --git a/contrib/netbsd-tests/ipf/regress/n5_6 b/contrib/netbsd-tests/ipf/regress/n5_6 new file mode 100644 index 0000000..acefd7b --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n5_6 @@ -0,0 +1,6 @@ +map zx0 10:1:1::1/128 -> 10::2:2:2/128 +map zx0 from 10:1:1::/112 to 10:1::/32 -> 10::3:4:5/128 +map zx0 from 10:1:1::/112 ! to 10:1::/32 -> 10::3:4:0/112 +map zx0 10:1:1::/112 -> 10::3:4:5/128 portmap udp 10000:20000 sequential +map zx0 10:1::/32 -> 10::3:4:0/112 portmap tcp/udp 10000:20000 sequential +map zx0 10:1:1::/112 -> 10::3:4:5/128 portmap tcp/udp 40000:40001 sequential diff --git a/contrib/netbsd-tests/ipf/regress/n6 b/contrib/netbsd-tests/ipf/regress/n6 new file mode 100644 index 0000000..79f11a4 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n6 @@ -0,0 +1,5 @@ +rdr zx0 10.1.1.1/32 port 23 -> 10.2.2.1 port 10023 tcp +rdr zx0 from any to 10.1.1.0/24 port = 23 -> 10.2.2.1 port 10023 tcp +rdr zx0 from 10.2.0.0/16 to 10.1.1.0/24 port = 23 -> 10.2.2.1 port 10023 tcp +rdr zx0 from 10.3.0.0/16 to 10.1.0.0/16 port = 23 -> 10.2.2.1 port 10023 tcp +rdr zx0 ! from 10.2.0.0/16 to 10.1.1.0/24 port = 53 -> 10.2.2.1 port 10053 udp diff --git a/contrib/netbsd-tests/ipf/regress/n6_6 b/contrib/netbsd-tests/ipf/regress/n6_6 new file mode 100644 index 0000000..3491c6b --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n6_6 @@ -0,0 +1,5 @@ +rdr zx0 10:1:1::1/128 port 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 from any to 10:1:1::/112 port = 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 from 10::/32 to 10:1:1::/112 port = 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 from 10:3::/32 to 10:1::/32 port = 23 -> 10::2:2:1 port 10023 tcp +rdr zx0 ! from 10::/32 to 10:1:1::/112 port = 53 -> 10::2:2:1 port 10053 udp diff --git a/contrib/netbsd-tests/ipf/regress/n7 b/contrib/netbsd-tests/ipf/regress/n7 new file mode 100644 index 0000000..be995c2 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n7 @@ -0,0 +1,3 @@ +rdr zx0 10.1.1.1/32 port 23-79 -> 10.2.2.1 port 10023 tcp +rdr zx0 10.1.1.1/32 port 23-79 -> 10.2.2.1 port = 10023 tcp +rdr zx0 10.1.1.0/24 port 80 -> 10.2.2.1,1.2.2.129 port 3128 tcp diff --git a/contrib/netbsd-tests/ipf/regress/n7_6 b/contrib/netbsd-tests/ipf/regress/n7_6 new file mode 100644 index 0000000..88055f6 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n7_6 @@ -0,0 +1,3 @@ +rdr zx0 10:1:1::1/128 port 23-79 -> 10::2:2:1 port 10023 tcp +rdr zx0 10:1:1::1/128 port 23-79 -> 10::2:2:1 port = 10023 tcp +rdr zx0 10:1:1::/112 port 80 -> 10::2:2:1,1::2:2:129 port 3128 tcp diff --git a/contrib/netbsd-tests/ipf/regress/n8 b/contrib/netbsd-tests/ipf/regress/n8 new file mode 100644 index 0000000..bf0e94f --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n8 @@ -0,0 +1 @@ +map icmp0 2.2.2.0/24 -> 10.10.10.0/24 diff --git a/contrib/netbsd-tests/ipf/regress/n8_6 b/contrib/netbsd-tests/ipf/regress/n8_6 new file mode 100644 index 0000000..2f96be0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n8_6 @@ -0,0 +1 @@ +map icmp0 2::2:2:0/112 -> 10:10:10::/112 diff --git a/contrib/netbsd-tests/ipf/regress/n9 b/contrib/netbsd-tests/ipf/regress/n9 new file mode 100644 index 0000000..81a7ccd --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n9 @@ -0,0 +1 @@ +rdr icmp0 4.4.4.0/24 port 0 -> 10.10.10.1 port 0 ip diff --git a/contrib/netbsd-tests/ipf/regress/n9_6 b/contrib/netbsd-tests/ipf/regress/n9_6 new file mode 100644 index 0000000..31e4615 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/n9_6 @@ -0,0 +1 @@ +rdr icmp0 4:4:4::/112 port 0 -> 10:10:10::1 port 0 ip diff --git a/contrib/netbsd-tests/ipf/regress/ni1.ipf b/contrib/netbsd-tests/ipf/regress/ni1.ipf new file mode 100644 index 0000000..c7e5797 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni1.ipf @@ -0,0 +1,4 @@ +block in all +block out all +pass out proto udp from any to any keep state +pass out proto tcp from any to any flags S keep state diff --git a/contrib/netbsd-tests/ipf/regress/ni1.nat b/contrib/netbsd-tests/ipf/regress/ni1.nat new file mode 100644 index 0000000..077aab1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni1.nat @@ -0,0 +1,3 @@ +map df0 from 2.2.2.2/32 port 20000 >< 25000 to any -> 6.6.6.8/32 portmap udp 2000:2500 sequential +map df0 from 2.2.2.2/32 port 2000 >< 2500 to any -> 6.6.6.7/32 portmap udp 20000:25000 sequential +map df0 from 2.2.2.2/32 to any -> 6.6.6.6/32 diff --git a/contrib/netbsd-tests/ipf/regress/ni10.ipf b/contrib/netbsd-tests/ipf/regress/ni10.ipf new file mode 100644 index 0000000..4151b6e --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni10.ipf @@ -0,0 +1,4 @@ +block in all +block out all +pass in proto udp from any to any keep state +pass in proto tcp from any to any flags S keep state diff --git a/contrib/netbsd-tests/ipf/regress/ni10.nat b/contrib/netbsd-tests/ipf/regress/ni10.nat new file mode 100644 index 0000000..2a04ef7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni10.nat @@ -0,0 +1 @@ +rdr df0 2.2.2.2/32 -> 6.6.6.6 diff --git a/contrib/netbsd-tests/ipf/regress/ni11.ipf b/contrib/netbsd-tests/ipf/regress/ni11.ipf new file mode 100644 index 0000000..4151b6e --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni11.ipf @@ -0,0 +1,4 @@ +block in all +block out all +pass in proto udp from any to any keep state +pass in proto tcp from any to any flags S keep state diff --git a/contrib/netbsd-tests/ipf/regress/ni11.nat b/contrib/netbsd-tests/ipf/regress/ni11.nat new file mode 100644 index 0000000..1d0018c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni11.nat @@ -0,0 +1 @@ +rdr df0 10.0.0.0/8 port 1000:2000 -> 1.1.1.1 port 40000 tcp/udp diff --git a/contrib/netbsd-tests/ipf/regress/ni12.ipf b/contrib/netbsd-tests/ipf/regress/ni12.ipf new file mode 100644 index 0000000..4151b6e --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni12.ipf @@ -0,0 +1,4 @@ +block in all +block out all +pass in proto udp from any to any keep state +pass in proto tcp from any to any flags S keep state diff --git a/contrib/netbsd-tests/ipf/regress/ni12.nat b/contrib/netbsd-tests/ipf/regress/ni12.nat new file mode 100644 index 0000000..8c36bc8 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni12.nat @@ -0,0 +1 @@ +rdr df0 10.0.0.0/8 port 1000:2000 -> 1.1.1.1 port = 40000 tcp/udp diff --git a/contrib/netbsd-tests/ipf/regress/ni13.ipf b/contrib/netbsd-tests/ipf/regress/ni13.ipf new file mode 100644 index 0000000..04b6d13 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni13.ipf @@ -0,0 +1,3 @@ +pass in quick on pcn1 proto tcp from any to any port = 1723 keep state +block in all +block out all diff --git a/contrib/netbsd-tests/ipf/regress/ni13.nat b/contrib/netbsd-tests/ipf/regress/ni13.nat new file mode 100644 index 0000000..ac2be49 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni13.nat @@ -0,0 +1 @@ +rdr pcn1 192.168.113.3/32 port 1723 -> 0.0.0.0 port 1723 tcp proxy pptp diff --git a/contrib/netbsd-tests/ipf/regress/ni14.ipf b/contrib/netbsd-tests/ipf/regress/ni14.ipf new file mode 100644 index 0000000..04b6d13 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni14.ipf @@ -0,0 +1,3 @@ +pass in quick on pcn1 proto tcp from any to any port = 1723 keep state +block in all +block out all diff --git a/contrib/netbsd-tests/ipf/regress/ni14.nat b/contrib/netbsd-tests/ipf/regress/ni14.nat new file mode 100644 index 0000000..72a8a4a --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni14.nat @@ -0,0 +1 @@ +rdr pcn1 192.168.113.3/32 port 1723 -> 127.0.0.1 port 1723 tcp proxy pptp diff --git a/contrib/netbsd-tests/ipf/regress/ni15.ipf b/contrib/netbsd-tests/ipf/regress/ni15.ipf new file mode 100644 index 0000000..1b9a013 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni15.ipf @@ -0,0 +1,3 @@ +pass out quick on pcn1 proto tcp from any to any port = 1723 keep state +block in all +block out all diff --git a/contrib/netbsd-tests/ipf/regress/ni15.nat b/contrib/netbsd-tests/ipf/regress/ni15.nat new file mode 100644 index 0000000..420c7b7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni15.nat @@ -0,0 +1 @@ +map pcn1 0/0 -> 0/0 proxy port 1723 pptp/tcp diff --git a/contrib/netbsd-tests/ipf/regress/ni16.ipf b/contrib/netbsd-tests/ipf/regress/ni16.ipf new file mode 100644 index 0000000..1b9a013 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni16.ipf @@ -0,0 +1,3 @@ +pass out quick on pcn1 proto tcp from any to any port = 1723 keep state +block in all +block out all diff --git a/contrib/netbsd-tests/ipf/regress/ni16.nat b/contrib/netbsd-tests/ipf/regress/ni16.nat new file mode 100644 index 0000000..5fad3cd --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni16.nat @@ -0,0 +1 @@ +map pcn1 10.2.2.2/32 -> 0/32 proxy port 1723 pptp/tcp diff --git a/contrib/netbsd-tests/ipf/regress/ni17.ipf b/contrib/netbsd-tests/ipf/regress/ni17.ipf new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni17.ipf diff --git a/contrib/netbsd-tests/ipf/regress/ni17.nat b/contrib/netbsd-tests/ipf/regress/ni17.nat new file mode 100644 index 0000000..3da6338 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni17.nat @@ -0,0 +1,4 @@ +rdr le0 0/0 port 80 -> 10.1.1.252 port 3128 tcp round-robin +rdr le0 0/0 port 80 -> 10.1.2.252 port 3128 tcp round-robin +rdr le0 0/0 port 80 -> 10.1.3.252 port 3128 tcp round-robin sticky +rdr le0 0/0 port 80 -> 10.1.1.253,10.1.2.253 port 3128 tcp round-robin sticky diff --git a/contrib/netbsd-tests/ipf/regress/ni18.ipf b/contrib/netbsd-tests/ipf/regress/ni18.ipf new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni18.ipf diff --git a/contrib/netbsd-tests/ipf/regress/ni18.nat b/contrib/netbsd-tests/ipf/regress/ni18.nat new file mode 100644 index 0000000..40113c1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni18.nat @@ -0,0 +1,4 @@ +rdr hme0 192.168.1.0/24 port 80 -> 1.1.1.1 port 80 tcp; +no rdr hme0 192.168.1.1 port 80 tcp; +map hme1 10.1.0.0/16 -> 203.1.1.1/32 portmap tcp/udp 10000:20000 +no map hme1 10.1.1.0/24 tcp; diff --git a/contrib/netbsd-tests/ipf/regress/ni19.ipf b/contrib/netbsd-tests/ipf/regress/ni19.ipf new file mode 100644 index 0000000..c6fcec1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni19.ipf @@ -0,0 +1,3 @@ +block in all +pass out quick on bge0 proto tcp from any to any port = shell flags S keep state +block out all diff --git a/contrib/netbsd-tests/ipf/regress/ni19.nat b/contrib/netbsd-tests/ipf/regress/ni19.nat new file mode 100644 index 0000000..56b81a9 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni19.nat @@ -0,0 +1 @@ +map bge0 192.168.113.0/24 -> 10.1.1.1/32 proxy port shell rcmd/tcp diff --git a/contrib/netbsd-tests/ipf/regress/ni2.ipf b/contrib/netbsd-tests/ipf/regress/ni2.ipf new file mode 100644 index 0000000..5956cf9 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni2.ipf @@ -0,0 +1 @@ +pass out quick proto tcp from any to any flags S/SAFR keep state diff --git a/contrib/netbsd-tests/ipf/regress/ni2.nat b/contrib/netbsd-tests/ipf/regress/ni2.nat new file mode 100644 index 0000000..43d2c83 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni2.nat @@ -0,0 +1 @@ +map xl0 10.0.0.0/8 -> 1.1.1.1/32 portmap tcp/udp 40000:60000 sequential diff --git a/contrib/netbsd-tests/ipf/regress/ni20.ipf b/contrib/netbsd-tests/ipf/regress/ni20.ipf new file mode 100644 index 0000000..c6f6d84 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni20.ipf @@ -0,0 +1,3 @@ +block in all +pass in quick on bge0 proto tcp from any to any port = shell flags S keep state +block out all diff --git a/contrib/netbsd-tests/ipf/regress/ni20.nat b/contrib/netbsd-tests/ipf/regress/ni20.nat new file mode 100644 index 0000000..f2dd0a7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni20.nat @@ -0,0 +1 @@ +rdr bge0 10.1.1.4/32 port shell -> 192.168.113.4 port shell tcp proxy rcmd diff --git a/contrib/netbsd-tests/ipf/regress/ni21.ipf b/contrib/netbsd-tests/ipf/regress/ni21.ipf new file mode 100644 index 0000000..6d6ed08 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni21.ipf @@ -0,0 +1 @@ +pass out on lan0 to eri0:1.1.1.1 from 2.2.2.2 to any diff --git a/contrib/netbsd-tests/ipf/regress/ni21.nat b/contrib/netbsd-tests/ipf/regress/ni21.nat new file mode 100644 index 0000000..6b2d46a --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni21.nat @@ -0,0 +1 @@ +map lan0,eri0 2.2.2.2 -> 4.4.4.4 diff --git a/contrib/netbsd-tests/ipf/regress/ni23.ipf b/contrib/netbsd-tests/ipf/regress/ni23.ipf new file mode 100644 index 0000000..49ebcf7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni23.ipf @@ -0,0 +1,3 @@ +block out all +block in all +pass in on le0,hme0 out-via ppp0,bge0 to ppp0:3.3.3.254 proto udp all keep state diff --git a/contrib/netbsd-tests/ipf/regress/ni23.nat b/contrib/netbsd-tests/ipf/regress/ni23.nat new file mode 100644 index 0000000..094d377 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni23.nat @@ -0,0 +1,2 @@ +rdr le0,bge0 1.1.0.0/16 -> 2.2.2.2 +map hme0,ppp0 3.3.3.0/24 -> 4.4.4.4/32 diff --git a/contrib/netbsd-tests/ipf/regress/ni3.ipf b/contrib/netbsd-tests/ipf/regress/ni3.ipf new file mode 100644 index 0000000..c7e5797 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni3.ipf @@ -0,0 +1,4 @@ +block in all +block out all +pass out proto udp from any to any keep state +pass out proto tcp from any to any flags S keep state diff --git a/contrib/netbsd-tests/ipf/regress/ni3.nat b/contrib/netbsd-tests/ipf/regress/ni3.nat new file mode 100644 index 0000000..4306f4b --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni3.nat @@ -0,0 +1 @@ +map df0 2.2.2.2/32 -> 6.6.6.6/32 diff --git a/contrib/netbsd-tests/ipf/regress/ni4.ipf b/contrib/netbsd-tests/ipf/regress/ni4.ipf new file mode 100644 index 0000000..c7e5797 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni4.ipf @@ -0,0 +1,4 @@ +block in all +block out all +pass out proto udp from any to any keep state +pass out proto tcp from any to any flags S keep state diff --git a/contrib/netbsd-tests/ipf/regress/ni4.nat b/contrib/netbsd-tests/ipf/regress/ni4.nat new file mode 100644 index 0000000..e9d5cc1 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni4.nat @@ -0,0 +1 @@ +map df0 2.2.2.2/32 -> 6.6.6.6/32 portmap tcp/udp 40000:60000 sequential diff --git a/contrib/netbsd-tests/ipf/regress/ni5.ipf b/contrib/netbsd-tests/ipf/regress/ni5.ipf new file mode 100644 index 0000000..8f11424 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni5.ipf @@ -0,0 +1,3 @@ +block in all +pass out quick on ppp0 proto tcp from any to any port = ftp flags S keep state +block out all diff --git a/contrib/netbsd-tests/ipf/regress/ni5.nat b/contrib/netbsd-tests/ipf/regress/ni5.nat new file mode 100644 index 0000000..8e80d22 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni5.nat @@ -0,0 +1 @@ +map ppp0 192.168.1.0/24 -> 1.1.1.1/32 proxy port ftp ftp/tcp diff --git a/contrib/netbsd-tests/ipf/regress/ni6.ipf b/contrib/netbsd-tests/ipf/regress/ni6.ipf new file mode 100644 index 0000000..f5b83b2 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni6.ipf @@ -0,0 +1,9 @@ +block out log quick on qfe0 from 192.168.7.0/24 to any +block out log quick on nf0 from 192.168.6.0/24 to any +pass in quick on nf0 proto tcp from any to any port = 111 flags S keep state +pass in quick on nf0 proto udp from any to any port = 111 keep state +block return-rst in log quick on nf0 proto tcp from any to any +block in log quick on nf0 from 192.168.7.0/24 to any +block return-rst in log quick on qfe0 proto tcp from any to any +block in log quick on qfe0 from 192.168.6.0/24 to any + diff --git a/contrib/netbsd-tests/ipf/regress/ni6.nat b/contrib/netbsd-tests/ipf/regress/ni6.nat new file mode 100644 index 0000000..00d57d0 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni6.nat @@ -0,0 +1,3 @@ +rdr nf0 192.168.6.2 port 111 -> 192.168.7.1 port 111 udp proxy rpcbu +rdr nf0 192.168.6.2 port 111 -> 192.168.7.1 port 111 tcp proxy rpcbt +map qfe0 192.168.6.0/24 -> 192.168.7.2/32 diff --git a/contrib/netbsd-tests/ipf/regress/ni7.ipf b/contrib/netbsd-tests/ipf/regress/ni7.ipf new file mode 100644 index 0000000..4151b6e --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni7.ipf @@ -0,0 +1,4 @@ +block in all +block out all +pass in proto udp from any to any keep state +pass in proto tcp from any to any flags S keep state diff --git a/contrib/netbsd-tests/ipf/regress/ni7.nat b/contrib/netbsd-tests/ipf/regress/ni7.nat new file mode 100644 index 0000000..2a04ef7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni7.nat @@ -0,0 +1 @@ +rdr df0 2.2.2.2/32 -> 6.6.6.6 diff --git a/contrib/netbsd-tests/ipf/regress/ni8.ipf b/contrib/netbsd-tests/ipf/regress/ni8.ipf new file mode 100644 index 0000000..6666241 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni8.ipf @@ -0,0 +1 @@ +pass in quick proto tcp from any to any flags S/SAFR keep state diff --git a/contrib/netbsd-tests/ipf/regress/ni8.nat b/contrib/netbsd-tests/ipf/regress/ni8.nat new file mode 100644 index 0000000..1d0018c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni8.nat @@ -0,0 +1 @@ +rdr df0 10.0.0.0/8 port 1000:2000 -> 1.1.1.1 port 40000 tcp/udp diff --git a/contrib/netbsd-tests/ipf/regress/ni9.ipf b/contrib/netbsd-tests/ipf/regress/ni9.ipf new file mode 100644 index 0000000..6666241 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni9.ipf @@ -0,0 +1 @@ +pass in quick proto tcp from any to any flags S/SAFR keep state diff --git a/contrib/netbsd-tests/ipf/regress/ni9.nat b/contrib/netbsd-tests/ipf/regress/ni9.nat new file mode 100644 index 0000000..8c36bc8 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/ni9.nat @@ -0,0 +1 @@ +rdr df0 10.0.0.0/8 port 1000:2000 -> 1.1.1.1 port = 40000 tcp/udp diff --git a/contrib/netbsd-tests/ipf/regress/p1.ipf b/contrib/netbsd-tests/ipf/regress/p1.ipf new file mode 100644 index 0000000..acaf639 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p1.ipf @@ -0,0 +1 @@ +pass in from pool/100 to any diff --git a/contrib/netbsd-tests/ipf/regress/p1.pool b/contrib/netbsd-tests/ipf/regress/p1.pool new file mode 100644 index 0000000..aa262a7 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p1.pool @@ -0,0 +1,2 @@ +table role = ipf type = tree number = 100 + { 1.1.1.1/32; !2.2.0.0/16; 2.2.2.0/24; ef00::5/128; }; diff --git a/contrib/netbsd-tests/ipf/regress/p10.nat b/contrib/netbsd-tests/ipf/regress/p10.nat new file mode 100644 index 0000000..3c3fa7c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p10.nat @@ -0,0 +1 @@ +rewrite in on bge0 proto tcp from any to any port = 80 -> src 0/0 dst dstlist/servers; diff --git a/contrib/netbsd-tests/ipf/regress/p10.pool b/contrib/netbsd-tests/ipf/regress/p10.pool new file mode 100644 index 0000000..2be554a --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p10.pool @@ -0,0 +1,2 @@ +pool nat/dstlist (name servers; policy hash;) + { 1.1.1.2; 1.1.1.4; 1.1.1.5; 1.1.1.9; }; diff --git a/contrib/netbsd-tests/ipf/regress/p11.nat b/contrib/netbsd-tests/ipf/regress/p11.nat new file mode 100644 index 0000000..3c3fa7c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p11.nat @@ -0,0 +1 @@ +rewrite in on bge0 proto tcp from any to any port = 80 -> src 0/0 dst dstlist/servers; diff --git a/contrib/netbsd-tests/ipf/regress/p11.pool b/contrib/netbsd-tests/ipf/regress/p11.pool new file mode 100644 index 0000000..a79d9ea --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p11.pool @@ -0,0 +1,2 @@ +pool nat/dstlist (name servers; policy dst-hash;) + { 1.1.1.2; 1.1.1.4; 1.1.1.5; 1.1.1.9; }; diff --git a/contrib/netbsd-tests/ipf/regress/p12.nat b/contrib/netbsd-tests/ipf/regress/p12.nat new file mode 100644 index 0000000..3c3fa7c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p12.nat @@ -0,0 +1 @@ +rewrite in on bge0 proto tcp from any to any port = 80 -> src 0/0 dst dstlist/servers; diff --git a/contrib/netbsd-tests/ipf/regress/p12.pool b/contrib/netbsd-tests/ipf/regress/p12.pool new file mode 100644 index 0000000..c9afcda --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p12.pool @@ -0,0 +1,2 @@ +pool nat/dstlist (name servers; policy src-hash;) + { 1.1.1.2; 1.1.1.4; 1.1.1.5; 1.1.1.9; }; diff --git a/contrib/netbsd-tests/ipf/regress/p13.ipf b/contrib/netbsd-tests/ipf/regress/p13.ipf new file mode 100644 index 0000000..acaf639 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p13.ipf @@ -0,0 +1 @@ +pass in from pool/100 to any diff --git a/contrib/netbsd-tests/ipf/regress/p13.pool b/contrib/netbsd-tests/ipf/regress/p13.pool new file mode 100644 index 0000000..de80f72 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p13.pool @@ -0,0 +1,2 @@ +table role = all type = tree number = 100 + { 1.1.1.1/32; !2.2.0.0/16; 2.2.2.0/24; ef00::5/128; }; diff --git a/contrib/netbsd-tests/ipf/regress/p2.ipf b/contrib/netbsd-tests/ipf/regress/p2.ipf new file mode 100644 index 0000000..4cfb388 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p2.ipf @@ -0,0 +1,2 @@ +pass out from hash=(127.0.0.1,4.4.0.0/16) to any +block in from hash=(127.0.0.1,4.4.0.0/16) to any diff --git a/contrib/netbsd-tests/ipf/regress/p3.ipf b/contrib/netbsd-tests/ipf/regress/p3.ipf new file mode 100644 index 0000000..a598d88 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p3.ipf @@ -0,0 +1,6 @@ +call now srcgrpmap/1010 in all +call now dstgrpmap/2010 out all +pass in all group 1020 +block in all group 1030 +pass out all group 2020 +block out all group 2040 diff --git a/contrib/netbsd-tests/ipf/regress/p3.pool b/contrib/netbsd-tests/ipf/regress/p3.pool new file mode 100644 index 0000000..3fadd59 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p3.pool @@ -0,0 +1,4 @@ +group-map in role = ipf number = 1010 + { 1.1.1.1/32, group = 1020; 3.3.0.0/16, group = 1030; }; +group-map out role = ipf number = 2010 group = 2020 + { 2.2.2.2/32; 4.4.0.0/16; 5.0.0.0/8, group = 2040; }; diff --git a/contrib/netbsd-tests/ipf/regress/p4.nat b/contrib/netbsd-tests/ipf/regress/p4.nat new file mode 100644 index 0000000..d504ac9 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p4.nat @@ -0,0 +1 @@ +map * from pool/100 to any -> 1.2.3.4/32 diff --git a/contrib/netbsd-tests/ipf/regress/p4.pool b/contrib/netbsd-tests/ipf/regress/p4.pool new file mode 100644 index 0000000..6ed0e49 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p4.pool @@ -0,0 +1,2 @@ +table role = nat type = tree number = 100 + { 1.1.1.1/32; !2.2.0.0/16; 2.2.2.0/24; }; diff --git a/contrib/netbsd-tests/ipf/regress/p5.ipf b/contrib/netbsd-tests/ipf/regress/p5.ipf new file mode 100644 index 0000000..ada9f56 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p5.ipf @@ -0,0 +1 @@ +pass in from pool/letters to any diff --git a/contrib/netbsd-tests/ipf/regress/p5.pool b/contrib/netbsd-tests/ipf/regress/p5.pool new file mode 100644 index 0000000..9a8eaa3 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p5.pool @@ -0,0 +1,2 @@ +table role = ipf type = tree name = letters + { 1.1.1.1/32; !2.2.0.0/16; 2.2.2.0/24; }; diff --git a/contrib/netbsd-tests/ipf/regress/p6.ipf b/contrib/netbsd-tests/ipf/regress/p6.ipf new file mode 100644 index 0000000..b9b8937 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p6.ipf @@ -0,0 +1 @@ +block in from pool/microsoft to any diff --git a/contrib/netbsd-tests/ipf/regress/p6.pool b/contrib/netbsd-tests/ipf/regress/p6.pool new file mode 100644 index 0000000..83e818c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p6.pool @@ -0,0 +1 @@ +pool ipf/tree (name microsoft;) { whois file "regress/p6.whois"; }; diff --git a/contrib/netbsd-tests/ipf/regress/p6.whois b/contrib/netbsd-tests/ipf/regress/p6.whois new file mode 100644 index 0000000..284244e --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p6.whois @@ -0,0 +1,241 @@ +# This query resulted in more than 256 records. Remaining results +# have been truncated. For more specific results, go to +# http://ws.arin.net/whois for help in refining your query. +Microsoft Corp (MSFT) +Microsoft Corp., MSN Operations (MCMO) +MICROSOFT CORPORATION (MICRO-101) +MICROSOFT CORPORATION (MICRO-97) +MICROSOFT CORPORATION (MICRO-100) +Microsoft Corporation (MICRO-111) +MICROSOFT CORPORATION (MICRO-117) +Microsoft Corporation (ZM23-ARIN) noc@microsoft.com +1-425-882-8080 +Microsoft (ZM39-ARIN) noc@microsoft.com +1-425-882-8080 +Microsoft Corp (AS8068) MICROSOFT-CORP---MSN-AS-BLOCK 8068 - 8075 +Microsoft Corp (AS13811) MSLI 13811 +Microsoft Corp (AS14719) MICROSOFT-CORP-BCENTRAL 14719 +Microsoft Corp (AS3598) MICROSOFT-CORP-AS 3598 +Microsoft Corp (AS5761) MICROSOFT-CORP---MSN-AS---SATURN 5761 +Microsoft Corp (AS6182) MICROSOFT-CORP--MSN-AS-4 6182 +Microsoft Corp (AS6194) MICROSOFT-CORP--MSN-AS-3 6194 +Microsoft Corp (AS6291) MICROSOFT-CORP---MSN-AS 6291 +Microsoft Corp (AS13399) MICROSOFT-CORP---MSN-AS-2 13399 +Microsoft Corp (AS23468) MICROSOFT-CORP-XBOX-ONLINE 23468 +Microsoft Corp MICROSOFT (NET-131-107-0-0-1) 131.107.0.0 - 131.107.255.255 +Microsoft Corp MICROSOFT-VEXCEL (NET-192-92-90-0-1) 192.92.90.0 - 192.92.90.255 +Microsoft Corp NETBLK-MSOFT-NET (NET-198-105-232-0-1) 198.105.232.0 - 198.105.235.255 +Microsoft Corp MICROSOFT19-NET58 (NET-204-231-58-0-1) 204.231.58.0 - 204.231.58.255 +Microsoft Corp MICROSOFT15 (NET-204-140-77-0-1) 204.140.77.0 - 204.140.77.255 +Microsoft Corp MICROSOFT16 (NET-204-140-80-0-1) 204.140.80.0 - 204.140.83.255 +Microsoft Corp MICROSOFT-CORP-MSN-1 (NET-199-60-28-0-1) 199.60.28.0 - 199.60.28.255 +Microsoft Corp MICROSOFT-1 (NET-199-103-90-0-1) 199.103.90.0 - 199.103.91.255 +Microsoft Corp MICROSOFT-CORP-MSN-3 (NET-199-103-122-0-1) 199.103.122.0 - 199.103.122.255 +Microsoft Corp MICROSOFT8 (NET-204-79-101-0-1) 204.79.101.0 - 204.79.101.255 +Microsoft Corp MICROSOFT18 (NET-192-237-67-0-1) 192.237.67.0 - 192.237.67.255 +Microsoft Corp MICROSOFT19 (NET-198-137-97-0-1) 198.137.97.0 - 198.137.97.255 +Microsoft Corp MICROSOFT-HK (NET-204-79-135-0-1) 204.79.135.0 - 204.79.135.255 +Microsoft Corp MICROSOFT-PLACEWARE-1 (NET-204-79-179-0-1) 204.79.179.0 - 204.79.179.255 +Microsoft Corp MICROSOFT11 (NET-204-79-180-0-1) 204.79.180.0 - 204.79.181.255 +Microsoft Corp MICROSOFT-PLACEWARE-2 (NET-204-79-188-0-1) 204.79.188.0 - 204.79.188.255 +Microsoft Corp MICROSOFT13 (NET-204-79-195-0-1) 204.79.195.0 - 204.79.197.255 +Microsoft Corp MICROSOFT17 (NET-199-6-92-0-1) 199.6.92.0 - 199.6.94.255 +Microsoft Corp MICROSOFT-2 (NET-204-79-7-0-1) 204.79.7.0 - 204.79.7.255 +Microsoft Corp MICROSOFT-NET1 (NET-204-79-27-0-1) 204.79.27.0 - 204.79.27.255 +Microsoft Corp MICROSOFT2 (NET-198-180-74-0-1) 198.180.74.0 - 198.180.75.255 +Microsoft Corp MICROSOFT3 (NET-198-180-95-0-1) 198.180.95.0 - 198.180.97.255 +Microsoft Corp MICROSOFT28 (NET-204-231-236-0-1) 204.231.236.0 - 204.231.236.255 +Microsoft Corp MICROSOFT29 (NET-205-248-10-0-1) 205.248.10.0 - 205.248.15.255 +Microsoft Corp SPRINT-CDA33F (NET-205-163-63-0-1) 205.163.63.0 - 205.163.63.255 +Microsoft Corp SPRINT-CDA33E (NET-205-163-62-0-1) 205.163.62.0 - 205.163.62.255 +Microsoft Corp SPRINT-CDA39F (NET-205-163-144-0-1) 205.163.144.0 - 205.163.159.255 +Microsoft Corp MICROSOFT30 (NET-205-248-41-0-1) 205.248.41.0 - 205.248.43.255 +Microsoft Corp MICROSOFT31 (NET-205-248-50-0-1) 205.248.50.0 - 205.248.51.255 +Microsoft Corp MICROSOFT32 (NET-205-248-61-0-1) 205.248.61.0 - 205.248.63.255 +Microsoft Corp MICROSOFT34 (NET-205-248-72-0-1) 205.248.72.0 - 205.248.72.255 +Microsoft Corp MICROSOFT35 (NET-205-248-212-0-1) 205.248.212.0 - 205.248.215.255 +Microsoft Corp MICROSOFT36 (NET-205-248-228-0-1) 205.248.228.0 - 205.248.228.255 +Microsoft Corp MICROSOFT37 (NET-205-248-235-0-1) 205.248.235.0 - 205.248.235.255 +Microsoft Corp MICROSOFT20 (NET-204-231-76-0-1) 204.231.76.0 - 204.231.76.255 +Microsoft Corp MICROSOFT26 (NET-204-231-192-0-1) 204.231.192.0 - 204.231.192.255 +Microsoft Corp MICROSOFT27 (NET-204-231-194-0-1) 204.231.194.0 - 204.231.223.255 +Microsoft Corp SOCRATIC (NET-207-78-80-0-1) 207.78.80.0 - 207.78.80.255 +Microsoft Corp DAVELADD (NET-207-78-81-0-1) 207.78.81.0 - 207.78.81.255 +Microsoft Corp RSEGAL (NET-207-78-82-0-1) 207.78.82.0 - 207.78.82.255 +Microsoft Corp MICROSOFT44 (NET-205-248-243-0-1) 205.248.243.0 - 205.248.244.255 +Microsoft Corp MICROSOFT48 (NET-207-117-3-0-1) 207.117.3.0 - 207.117.3.255 +Microsoft Corp UU-207-18-117 (NET-207-18-117-0-1) 207.18.117.0 - 207.18.117.255 +Microsoft Corp CW-208-139-27-B (NET-208-139-27-0-1) 208.139.27.0 - 208.139.27.255 +Microsoft Corp MICROSOFT55 (NET-209-28-213-0-1) 209.28.213.0 - 209.28.213.255 +Microsoft Corp MICROSOFT50 (NET-207-209-68-0-1) 207.209.68.0 - 207.209.68.255 +Microsoft Corp SPRINT-CC5F6F (NET-204-95-96-0-1) 204.95.96.0 - 204.95.111.255 +Microsoft Corp CYBR-LCCLAB (NET-207-158-93-192-1) 207.158.93.192 - 207.158.93.223 +Microsoft Corp MSBPN-2 (NET-207-240-123-192-1) 207.240.123.192 - 207.240.123.223 +Microsoft Corp SPRINT-D01ACD (NET-208-26-205-0-1) 208.26.205.0 - 208.26.205.255 +Microsoft Corp MICROSOFT-CORP-MSN-2 (NET-192-197-157-0-1) 192.197.157.0 - 192.197.157.255 +Microsoft Corp MICROSOFTDENVER (NET-204-133-231-0-1) 204.133.231.0 - 204.133.231.255 +Microsoft Corp MICROSOFTG1-COM (NET-216-72-96-0-1) 216.72.96.0 - 216.72.99.255 +Microsoft Corp EACT-CUST-JLEZNEK (NET-207-229-166-152-1) 207.229.166.152 - 207.229.166.159 +Microsoft Corp SPRINT-CC5F95-8 (NET-204-95-149-0-1) 204.95.149.0 - 204.95.149.255 +Microsoft Corp NET-CSAMSI (NET-209-192-213-72-1) 209.192.213.72 - 209.192.213.79 +Microsoft Corp MICROSOFT57 (NET-206-73-203-0-1) 206.73.203.0 - 206.73.203.255 +Microsoft Corp MICROSOFT56 (NET-206-73-118-0-1) 206.73.118.0 - 206.73.118.255 +Microsoft Corp QWEST-208-45-54-16 (NET-208-45-54-16-1) 208.45.54.16 - 208.45.54.23 +Microsoft Corp QWEST-208-45-54-8 (NET-208-45-54-8-1) 208.45.54.8 - 208.45.54.15 +Microsoft Corp MICROSOFT58 (NET-206-73-31-0-1) 206.73.31.0 - 206.73.31.255 +Microsoft Corp SPRINT-3FA132 (NET-63-161-50-128-1) 63.161.50.128 - 63.161.50.255 +Microsoft Corp SPRINT-3FA132-6 (NET-63-161-50-0-1) 63.161.50.0 - 63.161.50.127 +Microsoft Corp MICROSOFT-8-18 (NET-207-240-8-224-1) 207.240.8.224 - 207.240.8.239 +Microsoft Corp MICROSOFT-BBLK (NET-157-54-0-0-1) 157.54.0.0 - 157.60.255.255 +Microsoft Corp QWEST-208-45-89-248A (NET-208-45-89-248-1) 208.45.89.248 - 208.45.89.255 +Microsoft Corp MICROSOFT61 (NET-206-182-69-0-1) 206.182.69.0 - 206.182.69.255 +Microsoft Corp MICROSOFT63 (NET-206-182-240-0-1) 206.182.240.0 - 206.182.240.255 +Microsoft Corp MICROSOFT64 (NET-206-182-241-0-1) 206.182.241.0 - 206.182.241.255 +Microsoft Corp MICROSOFT59 (NET-206-73-67-0-1) 206.73.67.0 - 206.73.67.255 +Microsoft Corp MICROSOFT66 (NET-206-182-251-0-1) 206.182.251.0 - 206.182.251.255 +Microsoft Corp MICROSOFT65 (NET-206-182-247-0-1) 206.182.247.0 - 206.182.247.255 +Microsoft Corp MICROSOFT62 (NET-206-182-236-0-1) 206.182.236.0 - 206.182.236.255 +Microsoft Corp QWEST-63-236-198-64 (NET-63-236-198-64-1) 63.236.198.64 - 63.236.198.71 +Microsoft Corp QWEST-63-236-198-152 (NET-63-236-198-152-1) 63.236.198.152 - 63.236.198.159 +Microsoft Corp ERMS-6799349 (NET-165-121-253-232-1) 165.121.253.232 - 165.121.253.239 +Microsoft Corp QWEST-63-236-170-64 (NET-63-236-170-64-1) 63.236.170.64 - 63.236.170.71 +Microsoft Corp QWEST-63-236-186-64 (NET-63-236-186-64-1) 63.236.186.64 - 63.236.186.71 +Microsoft Corp QWEST-63-236-187-104 (NET-63-236-187-104-1) 63.236.187.104 - 63.236.187.111 +Microsoft Corp QWEST-63-236-187-128 (NET-63-236-187-128-1) 63.236.187.128 - 63.236.187.135 +Microsoft Corp QWEST-63-236-187-160 (NET-63-236-187-160-1) 63.236.187.160 - 63.236.187.167 +Microsoft Corp FON-3338832128690 (NET-199-2-137-0-1) 199.2.137.0 - 199.2.137.255 +Microsoft Corp CUST-86-24614 (NET-216-222-104-224-1) 216.222.104.224 - 216.222.104.239 +Microsoft Corp QWEST-63-151-87-64 (NET-63-151-87-64-1) 63.151.87.64 - 63.151.87.71 +Microsoft Corp HP-64-77-82-96 (NET-64-77-82-96-1) 64.77.82.96 - 64.77.82.103 +Microsoft Corp HP-64-77-93-80 (NET-64-77-93-80-1) 64.77.93.80 - 64.77.93.95 +Microsoft Corp MICROSOFT-1BLK (NET-65-52-0-0-1) 65.52.0.0 - 65.55.255.255 +Microsoft Corp MICROSOFT-GLOBAL-NET (NET-207-46-0-0-1) 207.46.0.0 - 207.46.255.255 +Microsoft Corp MICROSOFT-CORP-MSN-BLK (NET-207-68-128-0-1) 207.68.128.0 - 207.68.207.255 +Microsoft Corp FON-343451648081865 (NET-204-182-144-0-1) 204.182.144.0 - 204.182.159.255 +Microsoft Corp FON-346312755281299 (NET-206-107-34-0-1) 206.107.34.0 - 206.107.34.255 +Microsoft Corp FON-34550983681918 (NET-205-240-158-0-1) 205.240.158.0 - 205.240.159.255 +Microsoft Corp MICROSOFT-PLACEWARE-2 (NET-204-79-252-0-1) 204.79.252.0 - 204.79.252.255 +Microsoft Corp WLCO-TWC1057147-MICROSOFT (NET-64-200-211-16-1) 64.200.211.16 - 64.200.211.31 +Microsoft Corp MICROSOF81-163-0 (NET-12-178-163-0-1) 12.178.163.0 - 12.178.163.31 +Microsoft Corp WLCO-TWC1057147-MICROSOFT-1 (NET-69-44-126-80-1) 69.44.126.80 - 69.44.126.95 +Microsoft Corp SPRINTLINK (NET-63-173-42-128-1) 63.173.42.128 - 63.173.42.255 +Microsoft Corp MICROSOF33-108-0 (NET-12-28-108-0-1) 12.28.108.0 - 12.28.108.127 +Microsoft Corp SPRINTLINK (NET-65-170-29-0-1) 65.170.29.0 - 65.170.29.7 +Microsoft Corp Q0903-67-132-133-96 (NET-67-132-133-96-1) 67.132.133.96 - 67.132.133.103 +Microsoft Corp MICROSOFT-IPV6-BLK (NET6-2001-4898-1) 2001:4898:0000:0000:0000:0000:0000:0000 - 2001:4898:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF +Microsoft Corp LVLT-MSFT-8-6-176 (NET-8-6-176-0-1) 8.6.176.0 - 8.6.176.255 +Microsoft Corp MICROSOFT33 (NET-205-248-80-0-1) 205.248.80.0 - 205.248.129.255 +Microsoft Corp Q0523-63-148-123-240 (NET-63-148-123-240-1) 63.148.123.240 - 63.148.123.247 +Microsoft Corp SAVV-S233608-1 (NET-64-41-193-0-1) 64.41.193.0 - 64.41.193.255 +Microsoft Corp SAVV-S233053-1 (NET-64-85-70-32-1) 64.85.70.32 - 64.85.70.47 +Microsoft Corp SAVV-S233053-2 (NET-64-85-81-96-1) 64.85.81.96 - 64.85.81.103 +Microsoft Corp SAVV-S233053-3 (NET-64-85-81-104-1) 64.85.81.104 - 64.85.81.111 +Microsoft Corp SAVV-S233053-7 (NET-216-32-168-224-1) 216.32.168.224 - 216.32.168.255 +Microsoft Corp SAVV-S233053-6 (NET-206-79-74-32-1) 206.79.74.32 - 206.79.74.47 +Microsoft Corp SAVV-S233053-8 (NET-216-32-175-224-1) 216.32.175.224 - 216.32.175.255 +Microsoft Corp SAVV-S233053-9 (NET-216-32-180-0-1) 216.32.180.0 - 216.32.183.255 +Microsoft Corp SAVV-S233053-11 (NET-216-33-229-224-1) 216.33.229.224 - 216.33.229.255 +Microsoft Corp SAVV-S233053-12 (NET-216-33-236-0-1) 216.33.236.0 - 216.33.239.255 +Microsoft Corp SAVV-S233053-13 (NET-216-33-240-0-1) 216.33.240.0 - 216.33.243.255 +Microsoft Corp SAVV-S233053-10 (NET-216-32-240-0-1) 216.32.240.0 - 216.32.243.255 +Microsoft Corp SAVV-S233608-3 (NET-216-34-51-0-1) 216.34.51.0 - 216.34.51.255 +Microsoft Corp SAVV-S233053-4 (NET-209-1-112-0-1) 209.1.112.0 - 209.1.112.255 +Microsoft Corp SAVV-S233053-5 (NET-209-1-113-0-1) 209.1.113.0 - 209.1.113.255 +Microsoft Corp SAVV-S233608-2 (NET-209-1-15-0-1) 209.1.15.0 - 209.1.15.255 +Microsoft Corp SAVV-S233608-4 (NET-216-34-53-176-1) 216.34.53.176 - 216.34.53.191 +Microsoft Corp SAVV-S233608-5 (NET-216-35-8-224-1) 216.35.8.224 - 216.35.8.239 +Microsoft Corp SAVV-S233053-14 (NET-209-185-128-0-1) 209.185.128.0 - 209.185.131.255 +Microsoft Corp Q0112-65-114-175-128 (NET-65-114-175-128-1) 65.114.175.128 - 65.114.175.159 +Microsoft Corp SAVV-S233053-15 (NET-64-15-229-96-1) 64.15.229.96 - 64.15.229.127 +Microsoft Corp SAVV-S233050-5 (NET-64-15-177-0-1) 64.15.177.0 - 64.15.177.255 +Microsoft Corp SAVV-S233050-4 (NET-64-15-170-192-1) 64.15.170.192 - 64.15.170.199 +Microsoft Corp SAVV-S233050-2 (NET-209-143-238-0-1) 209.143.238.0 - 209.143.238.255 +Microsoft Corp SAVV-S233050-6 (NET-64-15-178-0-1) 64.15.178.0 - 64.15.178.255 +Microsoft Corp SAVV-S232995-2 (NET-66-35-209-120-1) 66.35.209.120 - 66.35.209.127 +Microsoft Corp SAVV-S232995-3 (NET-66-35-211-128-1) 66.35.211.128 - 66.35.211.191 +Microsoft Corp SAVV-S232995-1 (NET-66-35-208-48-1) 66.35.208.48 - 66.35.208.63 +Microsoft Corp SAVV-S233053-16 (NET-216-33-148-0-1) 216.33.148.0 - 216.33.151.255 +Microsoft Corp., MSN Operations SAVV-S233052-4 (NET-216-35-66-88-1) 216.35.66.88 - 216.35.66.95 +MICROSOFT CORPORATION MICROSOF32-32-160 (NET-12-230-32-160-1) 12.230.32.160 - 12.230.32.167 +MICROSOFT CORPORATION MICROSOF43-124-0 (NET-12-53-124-0-1) 12.53.124.0 - 12.53.124.31 +MICROSOFT CORPORATION MICROSOF82-18-96 (NET-12-232-18-96-1) 12.232.18.96 - 12.232.18.127 +MICROSOFT CORPORATION MICROSOF25-158 (NET-12-190-158-0-1) 12.190.158.0 - 12.190.158.255 +MICROSOFT CORPORATION MICROSOF61-196-32 (NET-12-71-196-32-1) 12.71.196.32 - 12.71.196.47 +Microsoft Corporation MICROSOFT-ONLINE-SERVICES (NET-209-240-192-0-1) 209.240.192.0 - 209.240.223.255 +Microsoft Corporation MICROSOFT-DYNAMIC-HOSTING (NET-70-37-0-0-1) 70.37.0.0 - 70.37.191.255 +Microsoft Corporation MS-ONLINE-SERVICES-NJ (NET-70-37-128-0-1) 70.37.128.0 - 70.37.129.255 +Microsoft Corporation MS-GLOBAL-ONLINE-SERVICES (NET-70-37-135-0-1) 70.37.135.0 - 70.37.135.255 +MICROSOFT CORPORATION MICROSOF82-87-192 (NET-12-49-87-192-1) 12.49.87.192 - 12.49.87.255 +Microsoft MICROSOFT (NET-74-93-205-144-1) 74.93.205.144 - 74.93.205.151 +Microsoft MICROSOFT (NET-74-93-205-152-1) 74.93.205.152 - 74.93.205.159 +Microsoft MICROSOFT (NET-74-93-206-64-1) 74.93.206.64 - 74.93.206.71 +Microsoft MICROSOFT (NET-70-89-139-120-1) 70.89.139.120 - 70.89.139.127 +Microsoft DIRECP-NET1-206-71-11 (NET-206-71-119-0-1) 206.71.119.0 - 206.71.119.255 +Microsoft DIRECP-NET1-117 (NET-206-71-117-0-1) 206.71.117.0 - 206.71.117.255 +Microsoft DIRECP-NET1-118 (NET-206-71-118-0-1) 206.71.118.0 - 206.71.118.255 +Microsoft UUHIL-BLK1-C155-112 (NET-209-154-155-112-1) 209.154.155.112 - 209.154.155.119 +Microsoft SBCIS-101411-164355 (NET-65-68-62-152-1) 65.68.62.152 - 65.68.62.159 +MICROSOFT SBC067039208168020503 (NET-67-39-208-168-1) 67.39.208.168 - 67.39.208.175 +Microsoft UU-65-242-67 (NET-65-242-67-0-1) 65.242.67.0 - 65.242.67.255 +Microsoft CW-204-71-191-0 (NET-204-71-191-0-1) 204.71.191.0 - 204.71.191.255 +Microsoft SBC063194155144021023 (NET-63-194-155-144-1) 63.194.155.144 - 63.194.155.151 +Microsoft SBC066136085192030113 (NET-66-136-85-192-1) 66.136.85.192 - 66.136.85.199 +MICROSOFT MFN-T280-64-124-184-72-29 (NET-64-124-184-72-1) 64.124.184.72 - 64.124.184.79 +MICROSOFT MFN-T133-216-200-206-0-24 (NET-216-200-206-0-1) 216.200.206.0 - 216.200.206.255 +Microsoft UU-63-80-93-D4 (NET-63-80-93-0-1) 63.80.93.0 - 63.80.93.127 +Microsoft RSPC-1218167167199384 (NET-67-192-225-208-1) 67.192.225.208 - 67.192.225.223 +Microsoft CVNET-454AA20 (NET-69-74-162-0-1) 69.74.162.0 - 69.74.162.255 +Microsoft UU-65-221-5 (NET-65-221-5-0-1) 65.221.5.0 - 65.221.5.255 +Microsoft - Partner Campaign Builder (PCB) MICROSOFT-PARTNER-CAMPAIGN-BUILDER-PCB (NET-216-182-89-192-1) 216.182.89.192 - 216.182.89.207 +Microsoft - Partner Campaign Builder (PCB) MICROSOFT-PARTNER-CAMPAIGN-BUILDER-PCB (NET-216-182-89-48-1) 216.182.89.48 - 216.182.89.63 +MICROSOFT AUSTIN-STO UU-65-248-85-D4 (NET-65-248-85-0-1) 65.248.85.0 - 65.248.85.255 +Microsoft Canada MIC0923-CA (NET-199-243-157-192-1) 199.243.157.192 - 199.243.157.223 +Microsoft Canada MIC0702-CA (NET-199-243-157-112-1) 199.243.157.112 - 199.243.157.119 +Microsoft Corp UU-65-194-210-224 (NET-65-194-210-224-1) 65.194.210.224 - 65.194.210.255 +Microsoft Corp UU-208-194-139 (NET-208-194-139-0-1) 208.194.139.0 - 208.194.139.255 +Microsoft Corp UU-208-204-49-128-B (NET-208-204-49-128-1) 208.204.49.128 - 208.204.49.255 +Microsoft Corp UU-208-205-26 (NET-208-205-26-0-1) 208.205.26.0 - 208.205.26.255 +Microsoft Corp UU-208-217-184-D1 (NET-208-217-184-0-1) 208.217.184.0 - 208.217.187.255 +Microsoft Corp UU-208-222-172 (NET-208-222-172-0-1) 208.222.172.0 - 208.222.172.255 +Microsoft Corp UU-208-224-200-64 (NET-208-224-200-64-1) 208.224.200.64 - 208.224.200.95 +Microsoft Corp UU-208-229-100-D1 (NET-208-229-100-0-1) 208.229.100.0 - 208.229.101.255 +Microsoft Corp UU-208-241-19 (NET-208-241-19-0-1) 208.241.19.0 - 208.241.19.15 +Microsoft Corp UU-208-241-19-16 (NET-208-241-19-16-1) 208.241.19.16 - 208.241.19.31 +Microsoft Corp UU-208-241-9-224 (NET-208-241-9-224-1) 208.241.9.224 - 208.241.9.239 +Microsoft Corp UU-208-244-108-D2 (NET-208-244-108-0-1) 208.244.108.0 - 208.244.108.15 +Microsoft Corp UU-208-245-16 (NET-208-245-16-0-1) 208.245.16.0 - 208.245.16.31 +Microsoft Corp UU-208-249-17-160 (NET-208-249-17-160-1) 208.249.17.160 - 208.249.17.175 +Microsoft Corp UU-63-104-216-D2 (NET-63-104-216-0-1) 63.104.216.0 - 63.104.216.127 +Microsoft Corp UU-63-69-245 (NET-63-69-245-0-1) 63.69.245.0 - 63.69.245.255 +Microsoft Corp SBC068090141072031030 (NET-68-90-141-72-1) 68.90.141.72 - 68.90.141.79 +Microsoft Corp 10825385 SBC06319812316029040317151513 (NET-63-198-123-160-1) 63.198.123.160 - 63.198.123.167 +MICROSOFT CORP-040821020257 SBC06824804806429040821020303 (NET-68-248-48-64-1) 68.248.48.64 - 68.248.48.71 +MICROSOFT CORP-040821020338 SBC06824804807229040821020347 (NET-68-248-48-72-1) 68.248.48.72 - 68.248.48.79 +MICROSOFT CORP-081024181821 SBC-99-49-8-248-29-0810241850 (NET-99-49-8-248-1) 99.49.8.248 - 99.49.8.255 +Microsoft Corp. HUGE-65-38-172-72-29 (NET-65-38-172-72-1) 65.38.172.72 - 65.38.172.79 +Microsoft Corp. HUGE-65-38-172-96-28 (NET-65-38-172-96-1) 65.38.172.96 - 65.38.172.111 +Microsoft Corporation MICROSOFT-CORPORATION (NET-75-149-174-16-1) 75.149.174.16 - 75.149.174.23 +Microsoft Corporation MICROSOFT-CORPORATION (NET-75-151-100-240-1) 75.151.100.240 - 75.151.100.255 +Microsoft Corporation SPEK-647057-0 (NET-64-81-8-96-1) 64.81.8.96 - 64.81.8.127 +Microsoft Corporation SBC067112255144030130 (NET-67-112-255-144-1) 67.112.255.144 - 67.112.255.151 +Microsoft Corporation ATTENS-010075-004522 (NET-63-240-201-176-1) 63.240.201.176 - 63.240.201.191 +Microsoft Corporation ATTENS-010075-004523 (NET-206-16-209-208-1) 206.16.209.208 - 206.16.209.223 +Microsoft Corporation ATTENS-010075-004525 (NET-63-240-195-208-1) 63.240.195.208 - 63.240.195.223 +Microsoft Corporation ATTENS-010075-004526 (NET-206-16-204-64-1) 206.16.204.64 - 206.16.204.79 +Microsoft Corporation ATTENS-010075-004450 (NET-206-16-223-0-1) 206.16.223.0 - 206.16.223.255 +Microsoft Corporation ATTENS-010075-005028 (NET-63-240-216-0-1) 63.240.216.0 - 63.240.219.255 +Microsoft Corporation ATTENS-010075-005057 (NET-63-240-220-0-1) 63.240.220.0 - 63.240.223.255 +Microsoft Corporation ATTENS-010075-005135 (NET-206-16-246-24-1) 206.16.246.24 - 206.16.246.31 +Microsoft Corporation ATTENS-010075-004524 (NET-63-240-195-192-1) 63.240.195.192 - 63.240.195.207 +Microsoft Corporation ATTENS-010075-005880 (NET-206-16-224-160-1) 206.16.224.160 - 206.16.224.191 +Microsoft Corporation (managed segment) RSPC-1229444888833780 (NET-98-129-187-144-1) 98.129.187.144 - 98.129.187.151 +Microsoft Corporation - Secure Dimensions ( RSPC-33955-12072007 (NET-67-192-39-48-1) 67.192.39.48 - 67.192.39.63 +Microsoft Corporation - Whale RSPC-108457-1170047010 (NET-72-32-240-160-1) 72.32.240.160 - 72.32.240.175 +Microsoft Corporation - Whale RSPC-108456-1173386392 (NET-72-32-201-152-1) 72.32.201.152 - 72.32.201.159 +MICROSOFT CROP SBC067039081152020503 (NET-67-39-81-152-1) 67.39.81.152 - 67.39.81.159 +Microsoft Education Programs RSPC-48725-1096578571 (NET-69-20-127-32-1) 69.20.127.32 - 69.20.127.39 +Microsoft License PNAP-SFJ-MSLI-RM-01 (NET-216-52-28-0-1) 216.52.28.0 - 216.52.28.255 +Microsoft License INAP-PHX003-MSLICENSE-25271 (NET-70-42-230-0-1) 70.42.230.0 - 70.42.231.255 +Microsoft License INAP-SFJ-MSLICENSE-13982 (NET-63-251-97-0-1) 63.251.97.0 - 63.251.97.255 +Microsoft Licensing SBC067120132128020815 (NET-67-120-132-128-1) 67.120.132.128 - 67.120.132.135 +Microsoft Licensing SBC067120132152020815 (NET-67-120-132-152-1) 67.120.132.152 - 67.120.132.159 +Microsoft Licensing SBC067120132192020816 (NET-67-120-132-192-1) 67.120.132.192 - 67.120.132.207 +Microsoft Licensing SBC0671201322080208 diff --git a/contrib/netbsd-tests/ipf/regress/p7.nat b/contrib/netbsd-tests/ipf/regress/p7.nat new file mode 100644 index 0000000..3c3fa7c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p7.nat @@ -0,0 +1 @@ +rewrite in on bge0 proto tcp from any to any port = 80 -> src 0/0 dst dstlist/servers; diff --git a/contrib/netbsd-tests/ipf/regress/p7.pool b/contrib/netbsd-tests/ipf/regress/p7.pool new file mode 100644 index 0000000..451b374 --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p7.pool @@ -0,0 +1,2 @@ +pool nat/dstlist (name servers; policy weighted connection;) + { 1.1.1.2; 1.1.1.4; 1.1.1.5; 1.1.1.9; }; diff --git a/contrib/netbsd-tests/ipf/regress/p9.nat b/contrib/netbsd-tests/ipf/regress/p9.nat new file mode 100644 index 0000000..3c3fa7c --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p9.nat @@ -0,0 +1 @@ +rewrite in on bge0 proto tcp from any to any port = 80 -> src 0/0 dst dstlist/servers; diff --git a/contrib/netbsd-tests/ipf/regress/p9.pool b/contrib/netbsd-tests/ipf/regress/p9.pool new file mode 100644 index 0000000..c452ffc --- /dev/null +++ b/contrib/netbsd-tests/ipf/regress/p9.pool @@ -0,0 +1,2 @@ +pool nat/dstlist (name servers; policy round-robin;) + { 1.1.1.2; 1.1.1.4; 1.1.1.5; 1.1.1.9; }; diff --git a/contrib/netbsd-tests/ipf/t_bpf.sh b/contrib/netbsd-tests/ipf/t_bpf.sh new file mode 100755 index 0000000..6d7d2e8 --- /dev/null +++ b/contrib/netbsd-tests/ipf/t_bpf.sh @@ -0,0 +1,68 @@ +# $NetBSD: t_bpf.sh,v 1.3 2012/11/29 16:05:34 pgoyette Exp $ +# +# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# +# (C)opyright 1993-1996 by Darren Reed. +# +# See the IPFILTER.LICENCE file for details on licencing. +# + +itest() +{ + h_copydata $1 + + case $3 in + ipf) + atf_check -o file:exp -e ignore ipf -Rnvf reg + ;; + ipftest) + atf_check -o file:exp ipftest -D -r reg -i /dev/null + ;; + esac +} + +bpftest() +{ + h_copydata $(echo ${1} | tr _ -) + cp "$(atf_get_srcdir)/input/$(echo ${1} | sed s,bpf_,,)" in + + { while read rule; do + atf_check -o save:save -x "echo '$rule' | ipftest -Rbr - -i in" + cat save >>out + echo "--------" >>out + done; } >out" + echo "--------" >>out + done; } >out + + diff -u exp out || atf_fail "results differ" +} + +dotest6() +{ + h_copydata $(echo ${1} | tr _ .) + infmt=$2 + outfmt=$3 + shift + shift + shift + args=$@ + + if [ $outfmt = hex ] ; then + output=-x + else + output= + fi + + + ipftest -6 -r /dev/null -i /dev/null >/dev/null 2>&1 \ + || atf_skip "skipping IPv6 tests" + + { while read rule; do + atf_check -o save:save -x "echo \"$rule\" | \ +ipftest -F $infmt $output -6br - -i in $args" + cat save >>out + echo "--------" >>out + done; } &1`" = "" ] ; then + if [ "`grep LOG_AUDIT /usr/include/sys/syslog.h 2>&1`" = "" ] ; then + sed -e 's/security/!!!/g' i19.dist > i19.p1; + else + sed -e 's/security/audit/g' i19.dist > i19.p1; + fi + else + cp i19.dist i19.p1; + fi + if [ "`grep LOG_AUTHPRIV /usr/include/sys/syslog.h 2>&1`" = "" ] ; then + sed -e 's/authpriv/!!!/g' i19.p1 > i19.p2; + else + cp i19.p1 i19.p2; + fi + if [ "`grep LOG_LOGALERT /usr/include/sys/syslog.h 2>&1`" = "" ] ; then + sed -e 's/logalert/!!!/g' i19.p2 > i19.p1; + else + cp i19.p2 i19.p1; + fi + if [ "`grep LOG_FTP /usr/include/sys/syslog.h 2>&1`" = "" ] ; then + sed -e 's/ftp/!!!/g' i19.p1 > i19.p2; + else + cp i19.p1 i19.p2; + fi + if [ "`egrep 'LOG_CRON.*15' /usr/include/sys/syslog.h 2>&1`" != "" ] ; then + sed -e 's/cron/cron2/g' i19.p2 > i19; + else + cp i19.p2 i19; + fi + /bin/rm i19.p? + + mv i19 exp + itest "$@" +} + +test_case i1 itest text ipf +test_case i2 itest text ipf +test_case i3 itest text ipf +test_case i4 itest text ipf +test_case i5 itest text ipf +test_case i6 itest text ipf +test_case i7 itest text ipf +test_case i8 itest text ipf +test_case i9 itest text ipf +test_case i10 itest text ipf +test_case i11 itest text ipf +test_case i12 itest text ipf +test_case i13 itest text ipf +test_case i14 itest text ipf +test_case i15 itest text ipf +test_case i16 itest text ipf +failing_test_case i17 itest "Known to be broken" text ipftest +test_case i18 itest text ipf +test_case i19 itest_i19 text ipf +test_case i20 itest text ipf +test_case i21 itest text ipf +test_case i22 itest text ipf +test_case i23 itest text ipf + +atf_init_test_cases() +{ + atf_add_test_case i1 + atf_add_test_case i2 + atf_add_test_case i3 + atf_add_test_case i4 + atf_add_test_case i5 + atf_add_test_case i6 + atf_add_test_case i7 + atf_add_test_case i8 + atf_add_test_case i9 + atf_add_test_case i10 + atf_add_test_case i11 + atf_add_test_case i12 + atf_add_test_case i13 + atf_add_test_case i14 + atf_add_test_case i15 + atf_add_test_case i16 + atf_add_test_case i17 + atf_add_test_case i18 + atf_add_test_case i19 + atf_add_test_case i20 + atf_add_test_case i21 + atf_add_test_case i22 + atf_add_test_case i23 +} + diff --git a/contrib/netbsd-tests/ipf/t_logging.sh b/contrib/netbsd-tests/ipf/t_logging.sh new file mode 100755 index 0000000..00317d9 --- /dev/null +++ b/contrib/netbsd-tests/ipf/t_logging.sh @@ -0,0 +1,80 @@ +# $NetBSD: t_logging.sh,v 1.2 2010/10/19 16:36:36 jmmv Exp $ +# +# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# +# (C)opyright 1993-1996 by Darren Reed. +# +# See the IPFILTER.LICENCE file for details on licencing. +# + +logtest() +{ + h_copydata $1 + cp $(atf_get_srcdir)/expected/$1.b exp.b + + case `uname -s` in + OSF1) + GMT=: + ;; + *) + GMT=GMT + ;; + esac + + { while read rule; do + echo $rule >>out + atf_check -o ignore -x \ + "echo $rule | ipftest -br - -F $2 -i in -l logout" + + atf_check -o save:save -x "TZ=$GMT ipmon -P /dev/null -f logout" + cat save >>out + echo "--------" >>out + + atf_check -o save:save -x "TZ=$GMT ipmon -P /dev/null -bf logout" + cat save >>out.b + echo "--------" >>out.b + done; } >out + echo "--------" >>out + + atf_check -o save:save -x "TZ=$GMT ipmon -P /dev/null -bf logout" + cat save >>out.b + echo "--------" >>out.b + + diff -u exp out || atf_fail "results differ" + diff -u exp.b out.b || atf_fail "results differ" +} + +test_case l1 logtest hex hex + +atf_init_test_cases() +{ + atf_add_test_case l1 +} diff --git a/contrib/netbsd-tests/ipf/t_nat_exec.sh b/contrib/netbsd-tests/ipf/t_nat_exec.sh new file mode 100755 index 0000000..ad99a84 --- /dev/null +++ b/contrib/netbsd-tests/ipf/t_nat_exec.sh @@ -0,0 +1,140 @@ +# $NetBSD: t_nat_exec.sh,v 1.22 2015/12/26 08:01:58 pgoyette Exp $ +# +# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# +# (C)opyright 1993-1996 by Darren Reed. +# +# See the IPFILTER.LICENCE file for details on licencing. +# + +nattest() +{ + h_copydata $1 + infmt=$2 + outfmt=$3 + shift + shift + shift + args=$@ + + if [ $outfmt = hex ] ; then + format="-xF $infmt" + else + format="-F $infmt" + fi + + format="$format" + + test -f in && test -f reg || atf_fail "Test input file missing" + + { while read rule; do + atf_check -o save:save -x \ + "echo \"$rule\" | ipftest $format -RDbN - -i in $args" + cat save >>out + echo "-------------------------------" >>out + done; } >out + echo "-------------------------------" >>out + done; } >out + ;; + esac + + diff -u exp out || atf_fail "results differ" +} + +test_case ni1 natipftest multi hex hex -T update_ipid=1 +test_case ni2 natipftest single hex hex -T update_ipid=1 +test_case ni3 natipftest single hex hex -T update_ipid=1 +test_case ni4 natipftest single hex hex -T update_ipid=1 +test_case ni5 natipftest single hex hex -T update_ipid=1 +test_case ni6 natipftest multi hex text -T update_ipid=1 -D +test_case ni7 natipftest single hex hex -T update_ipid=1 +test_case ni8 natipftest single hex hex -T update_ipid=1 +test_case ni9 natipftest single hex hex -T update_ipid=1 +test_case ni10 natipftest single hex hex -T update_ipid=1 +test_case ni11 natipftest single hex hex -T update_ipid=1 +test_case ni12 natipftest single hex hex -T update_ipid=1 +test_case ni13 natipftest single hex hex -T update_ipid=1 +test_case ni14 natipftest single hex hex -T update_ipid=1 +test_case ni15 natipftest single hex hex -T update_ipid=1 +test_case ni16 natipftest single hex hex -T update_ipid=1 +test_case ni17 natipftest multi text text +test_case ni18 natipftest multi text text +test_case ni19 natipftest single hex hex -T update_ipid=0 +test_case ni20 natipftest single hex hex -T update_ipid=0 -D +test_case ni21 natipftest multi text text +test_case ni23 natipftest multi text text -D + +atf_init_test_cases() +{ + atf_add_test_case ni1 + atf_add_test_case ni2 + atf_add_test_case ni3 + atf_add_test_case ni4 + atf_add_test_case ni5 + atf_add_test_case ni6 + atf_add_test_case ni7 + atf_add_test_case ni8 + atf_add_test_case ni9 + atf_add_test_case ni10 + atf_add_test_case ni11 + atf_add_test_case ni12 + atf_add_test_case ni13 + atf_add_test_case ni14 + atf_add_test_case ni15 + atf_add_test_case ni16 + atf_add_test_case ni17 + atf_add_test_case ni18 + atf_add_test_case ni19 + atf_add_test_case ni20 + atf_add_test_case ni21 + atf_add_test_case ni23 + +} diff --git a/contrib/netbsd-tests/ipf/t_nat_parse.sh b/contrib/netbsd-tests/ipf/t_nat_parse.sh new file mode 100755 index 0000000..ddc7a32 --- /dev/null +++ b/contrib/netbsd-tests/ipf/t_nat_parse.sh @@ -0,0 +1,83 @@ +# $NetBSD: t_nat_parse.sh,v 1.8 2014/06/29 09:26:32 darrenr Exp $ +# +# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# +# (C)opyright 1993-1996 by Darren Reed. +# +# See the IPFILTER.LICENCE file for details on licencing. +# + +intest() +{ + h_copydata $1 + + atf_check -o file:exp -e ignore ipnat -Rnvf reg +} + +test_case in1 intest text text +test_case in2 intest text text +test_case in3 intest text text +test_case in4 intest text text +test_case in5 intest text text +test_case in6 intest text text +test_case in7 intest text text +test_case in100 intest text text +test_case in101 intest text text +test_case in102 intest text text +test_case in1_6 intest text text +test_case in2_6 intest text text +test_case in3_6 intest text text +test_case in4_6 intest text text +test_case in5_6 intest text text +test_case in6_6 intest text text +test_case in8_6 intest text text +test_case in100_6 intest text text +test_case in101_6 intest text text +test_case in102_6 intest text text + +atf_init_test_cases() +{ + atf_add_test_case in1 + atf_add_test_case in2 + atf_add_test_case in3 + atf_add_test_case in4 + atf_add_test_case in5 + atf_add_test_case in6 + atf_add_test_case in7 + atf_add_test_case in100 + atf_add_test_case in101 + atf_add_test_case in102 + atf_add_test_case in1_6 + atf_add_test_case in2_6 + atf_add_test_case in3_6 + atf_add_test_case in4_6 + atf_add_test_case in5_6 + atf_add_test_case in6_6 + atf_add_test_case in8_6 + atf_add_test_case in100_6 + atf_add_test_case in101_6 + atf_add_test_case in102_6 +} diff --git a/contrib/netbsd-tests/ipf/t_pools.sh b/contrib/netbsd-tests/ipf/t_pools.sh new file mode 100755 index 0000000..33b5cb2 --- /dev/null +++ b/contrib/netbsd-tests/ipf/t_pools.sh @@ -0,0 +1,103 @@ +# $NetBSD: t_pools.sh,v 1.8 2012/12/03 23:39:30 pgoyette Exp $ +# +# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +# +# (C)opyright 1993-1996 by Darren Reed. +# +# See the IPFILTER.LICENCE file for details on licencing. +# + +iptest() +{ + h_copydata $1 + mkdir input + cp $(atf_get_srcdir)/input/ip2.data input/ + + atf_check -o file:exp -e ignore ippool -f reg -nRv +} + +ptest() +{ + h_copydata $1 + cp $(atf_get_srcdir)/regress/$1.pool pool 2>/dev/null + if [ -f $(atf_get_srcdir)/regress/$1.nat ] ; then + cp $(atf_get_srcdir)/regress/$1.nat nat + else + cp $(atf_get_srcdir)/regress/$1.ipf ipf + fi + + if [ -f pool ] ; then + if [ -f nat ] ; then + atf_check -o save:out ipftest -RD -b -P pool -N nat -i in + else + atf_check -o save:out ipftest -RD -b -P pool -r ipf -i in + fi + else + atf_check -o save:out ipftest -RD -b -r ipf -i in + fi + + echo "-------------------------------" >>out + +} + +test_case f28 ptest text text +test_case f29 ptest text text +test_case p1 ptest text text +test_case p2 ptest text text +test_case p3 ptest text text +test_case p4 ptest text text +test_case p5 ptest text text +test_case p6 ptest text text +test_case p7 ptest text text +test_case p9 ptest text text +test_case p10 ptest text text +test_case p11 ptest text text +test_case p12 ptest text text +test_case p13 ptest text text +test_case ip1 iptest text text +test_case ip2 iptest text text +test_case ip3 iptest text text + +atf_init_test_cases() +{ + atf_add_test_case f28 + atf_add_test_case f29 + atf_add_test_case p1 + atf_add_test_case p2 + atf_add_test_case p3 + atf_add_test_case p4 + atf_add_test_case p5 + atf_add_test_case p6 + atf_add_test_case p7 + atf_add_test_case p9 + atf_add_test_case p10 + atf_add_test_case p11 + atf_add_test_case p12 + atf_add_test_case p13 + atf_add_test_case ip1 + atf_add_test_case ip2 + atf_add_test_case ip3 +} diff --git a/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait.c b/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait.c new file mode 100644 index 0000000..09c17e1 --- /dev/null +++ b/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait.c @@ -0,0 +1,1606 @@ +/* $NetBSD: t_ptrace_wait.c,v 1.11 2017/01/18 05:14:34 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_ptrace_wait.c,v 1.11 2017/01/18 05:14:34 kamil Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +#include "../../t_ptrace_wait.h" + + +#if defined(HAVE_GPREGS) +ATF_TC(regs1); +ATF_TC_HEAD(regs1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_GETREGS and iterate over General Purpose registers"); +} + +ATF_TC_BODY(regs1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct reg r; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Call GETREGS for the child process\n"); + ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); + + printf("RAX=%#" PRIxREGISTER "\n", r.regs[_REG_RAX]); + printf("RBX=%#" PRIxREGISTER "\n", r.regs[_REG_RBX]); + printf("RCX=%#" PRIxREGISTER "\n", r.regs[_REG_RCX]); + printf("RDX=%#" PRIxREGISTER "\n", r.regs[_REG_RDX]); + + printf("RDI=%#" PRIxREGISTER "\n", r.regs[_REG_RDI]); + printf("RSI=%#" PRIxREGISTER "\n", r.regs[_REG_RSI]); + + printf("GS=%#" PRIxREGISTER "\n", r.regs[_REG_GS]); + printf("FS=%#" PRIxREGISTER "\n", r.regs[_REG_FS]); + printf("ES=%#" PRIxREGISTER "\n", r.regs[_REG_ES]); + printf("DS=%#" PRIxREGISTER "\n", r.regs[_REG_DS]); + printf("CS=%#" PRIxREGISTER "\n", r.regs[_REG_CS]); + printf("SS=%#" PRIxREGISTER "\n", r.regs[_REG_SS]); + + printf("RSP=%#" PRIxREGISTER "\n", r.regs[_REG_RSP]); + printf("RIP=%#" PRIxREGISTER "\n", r.regs[_REG_RIP]); + + printf("RFLAGS=%#" PRIxREGISTER "\n", r.regs[_REG_RFLAGS]); + + printf("R8=%#" PRIxREGISTER "\n", r.regs[_REG_R8]); + printf("R9=%#" PRIxREGISTER "\n", r.regs[_REG_R9]); + printf("R10=%#" PRIxREGISTER "\n", r.regs[_REG_R10]); + printf("R11=%#" PRIxREGISTER "\n", r.regs[_REG_R11]); + printf("R12=%#" PRIxREGISTER "\n", r.regs[_REG_R12]); + printf("R13=%#" PRIxREGISTER "\n", r.regs[_REG_R13]); + printf("R14=%#" PRIxREGISTER "\n", r.regs[_REG_R14]); + printf("R15=%#" PRIxREGISTER "\n", r.regs[_REG_R15]); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_count); +ATF_TC_HEAD(watchpoint_count, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and assert four available watchpoints"); +} + +ATF_TC_BODY(watchpoint_count, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + int N; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Call GETREGS for the child process\n"); + ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1); + printf("Reported %d watchpoints\n", N); + + ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_read); +ATF_TC_HEAD(watchpoint_read, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and assert four available watchpoints"); +} + +ATF_TC_BODY(watchpoint_read, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + int i, N; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Call GETREGS for the child process\n"); + ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1); + + ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N); + + for (i = 0; i < N; i++) { + printf("Before reading watchpoint %d\n", i); + pw.pw_index = i; + ATF_REQUIRE(ptrace(PT_READ_WATCHPOINT, child, &pw, len) != -1); + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + } + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_write_unmodified); +ATF_TC_HEAD(watchpoint_write_unmodified, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and assert functional write of " + "unmodified data"); +} + +ATF_TC_BODY(watchpoint_write_unmodified, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + int i, N; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Call GETREGS for the child process\n"); + ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1); + + ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N); + + for (i = 0; i < N; i++) { + printf("Before reading watchpoint %d\n", i); + pw.pw_index = i; + ATF_REQUIRE(ptrace(PT_READ_WATCHPOINT, child, &pw, len) != -1); + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d (unmodified)\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) + != -1); + } + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_trap_code0); +ATF_TC_HEAD(watchpoint_trap_code0, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 0"); +} + +ATF_TC_BODY(watchpoint_trap_code0, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + const int i = 0; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + int watchme = 1234; + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Preparing code watchpoint trap %d\n", i); + + pw.pw_index = i; + pw.pw_lwpid = 0; + pw.pw_type = PTRACE_PW_TYPE_DBREGS; + pw.pw_md.md_address = (void *)check_happy; + pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION; + pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off " + "and without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 0); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); + + pw.pw_md.md_address = NULL; + printf("Before writing watchpoint %d (disable it)\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_trap_code1); +ATF_TC_HEAD(watchpoint_trap_code1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 1"); +} + +ATF_TC_BODY(watchpoint_trap_code1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + const int i = 1; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + int watchme = 1234; + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Preparing code watchpoint trap %d\n", i); + + pw.pw_index = i; + pw.pw_lwpid = 0; + pw.pw_type = PTRACE_PW_TYPE_DBREGS; + pw.pw_md.md_address = (void *)check_happy; + pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION; + pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%d\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off " + "and without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 1); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); + + pw.pw_md.md_address = NULL; + printf("Before writing watchpoint %d (disable it)\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_trap_code2); +ATF_TC_HEAD(watchpoint_trap_code2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 2"); +} + +ATF_TC_BODY(watchpoint_trap_code2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + const int i = 2; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + int watchme = 1234; + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Preparing code watchpoint trap %d\n", i); + + pw.pw_index = i; + pw.pw_lwpid = 0; + pw.pw_type = PTRACE_PW_TYPE_DBREGS; + pw.pw_md.md_address = (void *)check_happy; + pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION; + pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off " + "and without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 2); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); + + pw.pw_md.md_address = NULL; + printf("Before writing watchpoint %d (disable it)\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_trap_code3); +ATF_TC_HEAD(watchpoint_trap_code3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 3"); +} + +ATF_TC_BODY(watchpoint_trap_code3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + const int i = 3; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + int watchme = 1234; + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Preparing code watchpoint trap %d\n", i); + + pw.pw_index = i; + pw.pw_lwpid = 0; + pw.pw_type = PTRACE_PW_TYPE_DBREGS; + pw.pw_md.md_address = (void *)check_happy; + pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION; + pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off " + "and without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 3); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); + + pw.pw_md.md_address = NULL; + printf("Before writing watchpoint %d (disable it)\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_trap_data_write0); +ATF_TC_HEAD(watchpoint_trap_data_write0, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 0"); +} + +ATF_TC_BODY(watchpoint_trap_data_write0, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + const int i = 0; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + int watchme = 1234; + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + ++watchme; + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Preparing code watchpoint trap %d\n", i); + + pw.pw_index = 0; + pw.pw_type = PTRACE_PW_TYPE_DBREGS; + pw.pw_md.md_address = &watchme; + pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE; + pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off " + "and without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 0); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_trap_data_write1); +ATF_TC_HEAD(watchpoint_trap_data_write1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 1"); +} + +ATF_TC_BODY(watchpoint_trap_data_write1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + const int i = 1; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + int watchme = 1234; + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + ++watchme; + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Preparing code watchpoint trap %d\n", i); + + pw.pw_index = i; + pw.pw_type = PTRACE_PW_TYPE_DBREGS; + pw.pw_md.md_address = &watchme; + pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE; + pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off " + "and without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 1); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_trap_data_write2); +ATF_TC_HEAD(watchpoint_trap_data_write2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 2"); +} + +ATF_TC_BODY(watchpoint_trap_data_write2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + const int i = 2; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + int watchme = 1234; + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + ++watchme; + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Preparing code watchpoint trap %d\n", i); + + pw.pw_index = i; + pw.pw_type = PTRACE_PW_TYPE_DBREGS; + pw.pw_md.md_address = &watchme; + pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE; + pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off " + "and without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 2); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_trap_data_write3); +ATF_TC_HEAD(watchpoint_trap_data_write3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 3"); +} + +ATF_TC_BODY(watchpoint_trap_data_write3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + const int i = 3; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + int watchme = 1234; + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + ++watchme; + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Preparing code watchpoint trap %d\n", i); + + pw.pw_index = i; + pw.pw_type = PTRACE_PW_TYPE_DBREGS; + pw.pw_md.md_address = &watchme; + pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE; + pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off " + "and without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 3); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_trap_data_rw0); +ATF_TC_HEAD(watchpoint_trap_data_rw0, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 0"); +} + +ATF_TC_BODY(watchpoint_trap_data_rw0, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + const int i = 0; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + int watchme = 1234; + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("watchme=%d\n", watchme); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Preparing code watchpoint trap %d\n", i); + + pw.pw_index = i; + pw.pw_type = PTRACE_PW_TYPE_DBREGS; + pw.pw_md.md_address = &watchme; + pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE; + pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off " + "and without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 0); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_trap_data_rw1); +ATF_TC_HEAD(watchpoint_trap_data_rw1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 1"); +} + +ATF_TC_BODY(watchpoint_trap_data_rw1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + const int i = 1; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + int watchme = 1234; + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("watchme=%d\n", watchme); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Preparing code watchpoint trap %d\n", i); + + pw.pw_index = i; + pw.pw_type = PTRACE_PW_TYPE_DBREGS; + pw.pw_md.md_address = &watchme; + pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE; + pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off " + "and without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 1); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_trap_data_rw2); +ATF_TC_HEAD(watchpoint_trap_data_rw2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 2"); +} + +ATF_TC_BODY(watchpoint_trap_data_rw2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + const int i = 2; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + int watchme = 1234; + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("watchme=%d\n", watchme); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Preparing code watchpoint trap %d\n", i); + + pw.pw_index = i; + pw.pw_type = PTRACE_PW_TYPE_DBREGS; + pw.pw_md.md_address = &watchme; + pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE; + pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off " + "and without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 2); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +ATF_TC(watchpoint_trap_data_rw3); +ATF_TC_HEAD(watchpoint_trap_data_rw3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 3"); +} + +ATF_TC_BODY(watchpoint_trap_data_rw3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + const int i = 3; + struct ptrace_watchpoint pw; + int len = sizeof(pw); + int watchme = 1234; + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("watchme=%d\n", watchme); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Preparing code watchpoint trap %d\n", i); + + pw.pw_index = i; + pw.pw_type = PTRACE_PW_TYPE_DBREGS; + pw.pw_md.md_address = &watchme; + pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE; + pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE; + + printf("struct ptrace {\n"); + printf("\t.pw_index=%d\n", pw.pw_index); + printf("\t.pw_lwpid=%d\n", pw.pw_lwpid); + printf("\t.pw_type=%#x\n", pw.pw_type); + printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address); + printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition); + printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length); + printf("}\n"); + + printf("Before writing watchpoint %d\n", i); + ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1); + + printf("Before resuming the child process where it left off " + "and without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_HWWPT); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap2, 3); + ATF_REQUIRE_EQ(info.psi_siginfo.si_trap3, X86_HW_WATCHPOINT_EVENT_FIRED); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1); + + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_count); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_read); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_write_unmodified); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code0); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code1); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code2); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code3); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write0); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write1); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write2); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write3); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw0); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw1); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw2); + ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw3); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait3.c b/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait3.c new file mode 100644 index 0000000..c5dfe73 --- /dev/null +++ b/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait3.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_wait3.c,v 1.1 2016/12/02 05:54:15 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAIT3 +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait4.c b/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait4.c new file mode 100644 index 0000000..7e1fed9 --- /dev/null +++ b/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait4.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_wait4.c,v 1.1 2016/12/02 05:54:15 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAIT4 +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait6.c b/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait6.c new file mode 100644 index 0000000..601efe3 --- /dev/null +++ b/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait6.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_wait6.c,v 1.1 2016/12/02 05:54:15 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAIT6 +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_waitid.c b/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_waitid.c new file mode 100644 index 0000000..5ec17a9 --- /dev/null +++ b/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_waitid.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_waitid.c,v 1.1 2016/12/02 05:54:15 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAITID +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_waitpid.c b/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_waitpid.c new file mode 100644 index 0000000..78b341c --- /dev/null +++ b/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_waitpid.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_waitpid.c,v 1.1 2016/12/02 05:54:15 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAITPID +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_wait.c b/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_wait.c new file mode 100644 index 0000000..698573b --- /dev/null +++ b/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_wait.c @@ -0,0 +1,141 @@ +/* $NetBSD: t_ptrace_wait.c,v 1.2 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_ptrace_wait.c,v 1.2 2017/01/13 21:30:41 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +#include "../../t_ptrace_wait.h" + + +#if defined(HAVE_GPREGS) +ATF_TC(regs1); +ATF_TC_HEAD(regs1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Call PT_GETREGS and iterate over General Purpose registers"); +} + +ATF_TC_BODY(regs1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct reg r; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Call GETREGS for the child process\n"); + ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); + + printf("EAX=%#" PRIxREGISTER "\n", r.r_eax); + printf("EBX=%#" PRIxREGISTER "\n", r.r_ebx); + printf("ECX=%#" PRIxREGISTER "\n", r.r_ecx); + printf("EDX=%#" PRIxREGISTER "\n", r.r_edx); + + printf("ESP=%#" PRIxREGISTER "\n", r.r_esp); + printf("EBP=%#" PRIxREGISTER "\n", r.r_ebp); + + printf("ESI=%#" PRIxREGISTER "\n", r.r_esi); + printf("EDI=%#" PRIxREGISTER "\n", r.r_edi); + + printf("EIP=%#" PRIxREGISTER "\n", r.r_eip); + + printf("EFLAGS=%#" PRIxREGISTER "\n", r.r_eflags); + + printf("CS=%#" PRIxREGISTER "\n", r.r_cs); + printf("SS=%#" PRIxREGISTER "\n", r.r_ss); + printf("DS=%#" PRIxREGISTER "\n", r.r_ds); + printf("ES=%#" PRIxREGISTER "\n", r.r_es); + printf("FS=%#" PRIxREGISTER "\n", r.r_fs); + printf("GS=%#" PRIxREGISTER "\n", r.r_gs); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_wait3.c b/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_wait3.c new file mode 100644 index 0000000..56dda8e --- /dev/null +++ b/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_wait3.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_wait3.c,v 1.1 2016/12/13 18:00:10 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAIT3 +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_wait4.c b/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_wait4.c new file mode 100644 index 0000000..5fbdb53 --- /dev/null +++ b/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_wait4.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_wait4.c,v 1.1 2016/12/13 18:00:10 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAIT4 +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_wait6.c b/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_wait6.c new file mode 100644 index 0000000..117c844 --- /dev/null +++ b/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_wait6.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_wait6.c,v 1.1 2016/12/13 18:00:10 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAIT6 +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_waitid.c b/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_waitid.c new file mode 100644 index 0000000..274e8bd --- /dev/null +++ b/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_waitid.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_waitid.c,v 1.1 2016/12/13 18:00:10 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAITID +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_waitpid.c b/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_waitpid.c new file mode 100644 index 0000000..2fe5c57 --- /dev/null +++ b/contrib/netbsd-tests/kernel/arch/i386/t_ptrace_waitpid.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_waitpid.c,v 1.1 2016/12/13 18:00:10 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAITPID +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/gen_t_subr_prf b/contrib/netbsd-tests/kernel/gen_t_subr_prf new file mode 100755 index 0000000..b58a6ba --- /dev/null +++ b/contrib/netbsd-tests/kernel/gen_t_subr_prf @@ -0,0 +1,134 @@ +#!/bin/sh + +cat << _EOF > $2 +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Avoid SSP re-definitions */ +#undef snprintf +#undef vsnprintf +#undef sprintf +#undef vsprintf + +#define KPRINTF_BUFSIZE 1024 +#undef putchar +#define putchar xputchar + +static int putchar(char c, int foo, void *b) +{ + return fputc(c, stderr); +} + +#define TOBUFONLY 1 +static const char HEXDIGITS[] = "0123456789ABCDEF"; +static const char hexdigits[] = "0123456789abcdef"; + +typedef int device_t; + +#if 0 +static SHA512_CTX kprnd_sha; +#endif + +#define timespec timeval +#define nanotime(ts) gettimeofday(ts, NULL) + +#define device_xname(a) "" +int kprintf(const char *, int, void *, char *, va_list) __printflike(1, 0); +void device_printf(device_t, const char *, ...) __printflike(2, 3); + +static void +empty(void) +{ +} + +static void (*v_flush)(void) = empty; + +ATF_TC(snprintf_print); +ATF_TC_HEAD(snprintf_print, tc) +{ + atf_tc_set_md_var(tc, "descr", "checks snprintf print"); +} + +ATF_TC_BODY(snprintf_print, tc) +{ + char buf[10]; + int i; + + memset(buf, 'x', sizeof(buf)); + i = snprintf(buf, sizeof(buf), "number %d", 10); + ATF_CHECK_EQ(i, 9); + ATF_CHECK_STREQ(buf, "number 10"); +} + +ATF_TC(snprintf_print_overflow); +ATF_TC_HEAD(snprintf_print_overflow, tc) +{ + atf_tc_set_md_var(tc, "descr", "checks snprintf print with overflow"); +} + +ATF_TC_BODY(snprintf_print_overflow, tc) +{ + char buf[10]; + int i; + + memset(buf, 'x', sizeof(buf)); + i = snprintf(buf, sizeof(buf), "fjsdfsdjfsdf %d\n", 10); + ATF_CHECK_EQ(i, 16); + ATF_CHECK_STREQ(buf, "fjsdfsdjf"); +} + +ATF_TC(snprintf_count); +ATF_TC_HEAD(snprintf_count, tc) +{ + atf_tc_set_md_var(tc, "descr", "checks snprintf count"); +} + +ATF_TC_BODY(snprintf_count, tc) +{ + int i; + + i = snprintf(NULL, 20, "number %d", 10); + ATF_CHECK_EQ(i, 9); +} + +ATF_TC(snprintf_count_overflow); +ATF_TC_HEAD(snprintf_count_overflow, tc) +{ + atf_tc_set_md_var(tc, "descr", "checks snprintf count with overflow"); +} + +ATF_TC_BODY(snprintf_count_overflow, tc) +{ + int i; + + i = snprintf(NULL, 10, "fjsdfsdjfsdf %d\n", 10); + ATF_CHECK_EQ(i, 16); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, snprintf_print); + ATF_TP_ADD_TC(tp, snprintf_print_overflow); + ATF_TP_ADD_TC(tp, snprintf_count); + ATF_TP_ADD_TC(tp, snprintf_count_overflow); + + return atf_no_error(); +} +_EOF + +awk ' +/^snprintf\(/ { + print prevline + out = 1 +} +{ + if (out) print + else prevline = $0 +}' $1 >>$2 diff --git a/contrib/netbsd-tests/kernel/h_ps_strings1.c b/contrib/netbsd-tests/kernel/h_ps_strings1.c new file mode 100644 index 0000000..64d8c71 --- /dev/null +++ b/contrib/netbsd-tests/kernel/h_ps_strings1.c @@ -0,0 +1,74 @@ +/* $NetBSD: h_ps_strings1.c,v 1.1 2011/03/05 18:14:33 pgoyette Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +#include +#include +#include + +extern struct ps_strings *__ps_strings; + +int +main(int argc, char **argv, char **environ) +{ + int ret = 0; + int nenv; + + if (__ps_strings->ps_nargvstr != argc) { + static const char nargv_err[] = "Wrong argc in ps_strings"; + write(STDOUT_FILENO, nargv_err, sizeof(nargv_err)); + ret = 1; + } + + if (__ps_strings->ps_argvstr != argv) { + static const char argv_err[] = "Wrong argv in ps_strings"; + write(STDOUT_FILENO, argv_err, sizeof(argv_err)); + ret = 1; + } + + if (__ps_strings->ps_envstr != environ) { + static const char env_err[] = "Wrong env in ps_strings"; + write(STDOUT_FILENO, env_err, sizeof(env_err)); + ret = 1; + } + nenv = 0; + while (environ[nenv]) + ++nenv; + if (__ps_strings->ps_nenvstr != nenv) { + static const char nenv_err[] = "Wrong nenv in ps_strings"; + write(STDOUT_FILENO, nenv_err, sizeof(nenv_err)); + ret = 1; + } + + return ret; +} diff --git a/contrib/netbsd-tests/kernel/h_ps_strings2.c b/contrib/netbsd-tests/kernel/h_ps_strings2.c new file mode 100644 index 0000000..d9c1c24 --- /dev/null +++ b/contrib/netbsd-tests/kernel/h_ps_strings2.c @@ -0,0 +1,69 @@ +/* $NetBSD: h_ps_strings2.c,v 1.1 2011/03/05 18:14:33 pgoyette Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +#include +#include +#include +#include +#include +#include +#include + +#define LEN 16384 + +extern struct ps_strings *__ps_strings; + +int +main(void) +{ + size_t i; + char buf[16]; + char **argv; + + if ((argv = calloc(LEN, sizeof(*argv))) == NULL) + errx(1, "calloc failed"); + for (i = 0; i < LEN; ++i) { + snprintf(buf, sizeof(buf), "arg%04zx", i); + if ((argv[i] = strdup(buf)) == NULL) + errx(1, "strdup failed"); + } + __ps_strings->ps_argvstr = argv; + __ps_strings->ps_nargvstr = LEN; + + printf("Sleeping forever...\n"); + do { + sleep(UINT_MAX); + } while /* CONSTCOND */ (1); + return 0; +} diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_fifo.c b/contrib/netbsd-tests/kernel/kqueue/read/t_fifo.c new file mode 100644 index 0000000..1f40ada --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/read/t_fifo.c @@ -0,0 +1,102 @@ +/* $NetBSD: t_fifo.c,v 1.4 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_fifo.c,v 1.4 2017/01/13 21:30:41 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +#define FIFONAME "fifo" + +ATF_TC(fifo); +ATF_TC_HEAD(fifo, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ on fifo"); +} +ATF_TC_BODY(fifo, tc) +{ + int kq, n, fd; + struct kevent event[1]; + char buffer[128]; + + RL(mkfifo(FIFONAME, 0644)); + RL(fd = open(FIFONAME, O_RDWR, 0644)); + + RL(kq = kqueue()); + + EV_SET(&event[0], fd, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + /* make sure there is something in the fifo */ + RL(write(fd, "foo", 3)); + (void)printf("fifo: wrote 'foo'\n"); + + (void)memset(event, 0, sizeof(event)); + + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + + (void)printf("kevent num %d filt %d flags: %#x, fflags: %#x, " +#ifdef __FreeBSD__ + "data: %" PRIdPTR "\n", n, event[0].filter, event[0].flags, +#else + "data: %" PRId64 "\n", n, event[0].filter, event[0].flags, +#endif + event[0].fflags, event[0].data); + + ATF_REQUIRE_EQ(event[0].filter, EVFILT_READ); + + RL(n = read(fd, buffer, event[0].data)); + buffer[n] = '\0'; + (void)printf("fifo: read '%s'\n", buffer); + + RL(close(fd)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, fifo); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_file.c b/contrib/netbsd-tests/kernel/kqueue/read/t_file.c new file mode 100644 index 0000000..f4669d2 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/read/t_file.c @@ -0,0 +1,143 @@ +/* $NetBSD: t_file.c,v 1.4 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_file.c,v 1.4 2017/01/13 21:30:41 christos Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +#define FILENAME "file" +#define NLINES 5 + +static void +child(void) +{ + int i, n, fd; + + (void)sleep(1); + + for (i = 0; i < NLINES; ++i) { + fd = open(FILENAME, O_WRONLY|O_APPEND, 0644); + if (fd < 0) + err(EXIT_FAILURE, "open()"); + + n = write(fd, "foo\n", 4); + if (n < 0) + err(EXIT_FAILURE, "write()"); + + (void)close(fd); + (void)sleep(1); + } + _exit(0); +} + +ATF_TC(file); +ATF_TC_HEAD(file, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ on regular file"); +} +ATF_TC_BODY(file, tc) +{ + char buffer[128]; + struct kevent event[1]; + pid_t pid; + int fd, kq, n, num, status; + + RL(pid = fork()); + if (pid == 0) { + child(); + /* NOTREACHED */ + } + + RL(fd = open(FILENAME, O_RDONLY|O_CREAT, 0644)); + +#if 1 /* XXX: why was this disabled? */ + RL(lseek(fd, 0, SEEK_END)); +#endif + + RL(kq = kqueue()); + + EV_SET(&event[0], fd, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + for (num = 0; num < NLINES;) { + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + num += n; + + (void)printf("kevent num %d flags: %#x, fflags: %#x, data: " +#ifdef __FreeBSD__ + "%" PRIdPTR "\n", n, event[0].flags, event[0].fflags, +#else + "%" PRId64 "\n", n, event[0].flags, event[0].fflags, +#endif + event[0].data); + + if (event[0].data < 0) +#if 1 /* XXXLUKEM */ + RL(lseek(fd, 0, SEEK_END)); +#else + RL(lseek(fd, event[0].data, SEEK_END)); +#endif + + RL(n = read(fd, buffer, 128)); + buffer[n] = '\0'; + (void)printf("file(%d): %s", num, buffer); + } + + (void)waitpid(pid, &status, 0); + + (void)printf("read: successful end\n"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, file); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_file2.c b/contrib/netbsd-tests/kernel/kqueue/read/t_file2.c new file mode 100644 index 0000000..733caeb --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/read/t_file2.c @@ -0,0 +1,79 @@ +/* $NetBSD: t_file2.c,v 1.4 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jaromir Dolecek. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_file2.c,v 1.4 2017/01/13 21:30:41 christos Exp $"); + +#include + +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(file2); +ATF_TC_HEAD(file2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks EVFILT_READ for regular files. This test used to " + "trigger deadlock caused by problem fixed in revision 1.79.2.10 " + "of sys/kern/kern_descrip.c"); +} +ATF_TC_BODY(file2, tc) +{ + int fd1, fd2, kq; + struct kevent event[1]; + + RL(fd1 = open("afile", O_RDONLY|O_CREAT, 0644)); + RL(fd2 = open("bfile", O_RDONLY|O_CREAT, 0644)); + +#if 1 /* XXX: why was this disabled? */ + RL(lseek(fd1, 0, SEEK_END)); +#endif + + RL(kq = kqueue()); + + EV_SET(&event[0], fd1, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + RL(dup2(fd2, fd1)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, file2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_pipe.c b/contrib/netbsd-tests/kernel/kqueue/read/t_pipe.c new file mode 100644 index 0000000..56cb037 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/read/t_pipe.c @@ -0,0 +1,88 @@ +/* $NetBSD: t_pipe.c,v 1.2 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_pipe.c,v 1.2 2017/01/13 21:30:41 christos Exp $"); + +#include + +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(pipe); +ATF_TC_HEAD(pipe, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ for pipes"); +} +ATF_TC_BODY(pipe, tc) +{ + struct kevent event[1]; + char buffer[128]; + int fds[2]; + int kq, n; + + RL(pipe(fds)); + RL(kq = kqueue()); + + EV_SET(&event[0], fds[0], EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + /* make sure there is something in the pipe */ + RL(write(fds[1], "foo", 3)); + (void)printf("pipe: wrote 'foo' to pipe\n"); + + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + (void)printf("kevent num %d flags: %#x, fflags: %#x, data: " +#ifdef __FreeBSD__ + "%" PRIdPTR "\n", n, event[0].flags, event[0].fflags, event[0].data); +#else + "%" PRId64 "\n", n, event[0].flags, event[0].fflags, event[0].data); +#endif + + RL(n = read(fds[0], buffer, event[0].data)); + buffer[n] = '\0'; + + (void)printf("pipe: read '%s'\n", buffer); + (void)printf("pipe: successful end\n"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pipe); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/read/t_ttypty.c b/contrib/netbsd-tests/kernel/kqueue/read/t_ttypty.c new file mode 100644 index 0000000..3703829 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/read/t_ttypty.c @@ -0,0 +1,148 @@ +/* $NetBSD: t_ttypty.c,v 1.2 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ttypty.c,v 1.2 2017/01/13 21:30:41 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +static void +h_check(bool check_master) +{ + char slavetty[1024]; + char buffer[128]; + struct kevent event[1]; + pid_t child; + int amaster, aslave, acurrent; + int kq, n, status; +#if 0 + int fl; +#endif + struct pollfd pfd; + struct termios tio; + + RL(openpty(&amaster, &aslave, slavetty, NULL, NULL)); + + (void)printf("tty: openpty master %d slave %d tty '%s'\n", + amaster, aslave, slavetty); + acurrent = check_master ? amaster : aslave; + + RL(child = fork()); + if (child == 0) { + sleep(1); + + (void)printf("tty: child writing 'f00\\n'\n"); + (void)write(check_master ? aslave : amaster, "f00\n", 4); + + _exit(0); + } + + /* switch ONLCR off, to not get confused by newline translation */ + RL(tcgetattr(acurrent, &tio)); + tio.c_oflag &= ~ONLCR; + RL(tcsetattr(acurrent, TCSADRAIN, &tio)); + + pfd.fd = acurrent; + pfd.events = POLLIN; + (void)printf("tty: polling ...\n"); + RL(poll(&pfd, 1, INFTIM)); + (void)printf("tty: returned from poll - %d\n", pfd.revents); + +#if 0 + fl = 1; + if (ioctl(acurrent, TIOCPKT, &fl) < 0) + err(1, "ioctl"); +#endif + + RL(kq = kqueue()); + + EV_SET(&event[0], acurrent, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + + (void)printf("kevent num %d filt %d flags: %#x, fflags: %#x, " +#ifdef __FreeBSD__ + "data: %" PRIdPTR "\n", n, event[0].filter, event[0].flags, +#else + "data: %" PRId64 "\n", n, event[0].filter, event[0].flags, +#endif + event[0].fflags, event[0].data); + + ATF_REQUIRE_EQ(event[0].filter, EVFILT_READ); + + RL(n = read(acurrent, buffer, 128)); + (void)printf("tty: read '%.*s' (n=%d)\n", n, buffer, n); + + (void)waitpid(child, &status, 0); + (void)printf("tty: successful end\n"); +} + +ATF_TC(master); +ATF_TC_HEAD(master, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ for master tty"); +} +ATF_TC_BODY(master, tc) +{ + h_check(true); +} + +ATF_TC(slave); +ATF_TC_HEAD(slave, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_READ for slave tty"); +} +ATF_TC_BODY(slave, tc) +{ + h_check(false); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, master); + ATF_TP_ADD_TC(tp, slave); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/t_ioctl.c b/contrib/netbsd-tests/kernel/kqueue/t_ioctl.c new file mode 100644 index 0000000..78b0587 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/t_ioctl.c @@ -0,0 +1,116 @@ +/* $NetBSD: t_ioctl.c,v 1.3 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ioctl.c,v 1.3 2017/01/13 21:30:41 christos Exp $"); + +#include +#include + +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(kfilter_byfilter); +ATF_TC_HEAD(kfilter_byfilter, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks KFILTER_BYFILTER ioctl"); +} +ATF_TC_BODY(kfilter_byfilter, tc) +{ + char buf[32]; + struct kfilter_mapping km; + int kq; + uint32_t i; + + RL(kq = kqueue()); + + km.name = buf; + km.len = sizeof(buf) - 1; + + for (i = 0; i < 7; ++i) { + km.filter = i; + RL(ioctl(kq, KFILTER_BYFILTER, &km)); + (void)printf(" map %d -> %s\n", km.filter, km.name); + } + + km.filter = 7; + ATF_REQUIRE_EQ(ioctl(kq, KFILTER_BYFILTER, &km), -1); +} + +ATF_TC(kfilter_byname); +ATF_TC_HEAD(kfilter_byname, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks KFILTER_BYNAME ioctl"); +} +ATF_TC_BODY(kfilter_byname, tc) +{ + const char *tests[] = { + "EVFILT_READ", + "EVFILT_WRITE", + "EVFILT_AIO", + "EVFILT_VNODE", + "EVFILT_PROC", + "EVFILT_SIGNAL", + "EVFILT_TIMER", + NULL + }; + char buf[32]; + struct kfilter_mapping km; + const char **test; + int kq; + + RL(kq = kqueue()); + + km.name = buf; + + for (test = &tests[0]; *test != NULL; ++test) { + (void)strlcpy(buf, *test, sizeof(buf)); + RL(ioctl(kq, KFILTER_BYNAME, &km)); + (void)printf(" map %s -> %d\n", km.name, km.filter); + } + + (void)strlcpy(buf, "NOTREG_FILTER", sizeof(buf)); + ATF_REQUIRE_EQ(ioctl(kq, KFILTER_BYNAME, &km), -1); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, kfilter_byfilter); + ATF_TP_ADD_TC(tp, kfilter_byname); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/t_proc1.c b/contrib/netbsd-tests/kernel/kqueue/t_proc1.c new file mode 100644 index 0000000..5f8c2a4 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/t_proc1.c @@ -0,0 +1,159 @@ +/* $NetBSD: t_proc1.c,v 1.3 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_proc1.c,v 1.3 2017/01/13 21:30:41 christos Exp $"); + +/* + * this also used to trigger problem fixed in + * rev. 1.1.1.1.2.13 of sys/kern/kern_event.c + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +static int +child(void) +{ + pid_t ch; + int status; + char *argv[] = { NULL, NULL }; + char *envp[] = { NULL, NULL }; + + if ((argv[0] = strdup("true")) == NULL) + err(EXIT_FAILURE, "strdup(\"true\")"); + + if ((envp[0] = strdup("FOO=BAZ")) == NULL) + err(EXIT_FAILURE, "strdup(\"FOO=BAZ\")"); + + /* Ensure parent is ready */ + (void)sleep(2); + + /* Do fork */ + switch (ch = fork()) { + case -1: + return EXIT_FAILURE; + /* NOTREACHED */ + case 0: + return EXIT_SUCCESS; + /* NOTREACHED */ + default: + wait(&status); + break; + } + + /* Exec */ + execve("/usr/bin/true", argv, envp); + + /* NOTREACHED */ + return EXIT_FAILURE; +} + +ATF_TC(proc1); +ATF_TC_HEAD(proc1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_PROC"); +} +ATF_TC_BODY(proc1, tc) +{ + struct kevent event[1]; + pid_t pid; + int kq, status; + u_int want; + + RL(kq = kqueue()); + + /* fork a child for doing the events */ + RL(pid = fork()); + if (pid == 0) { + _exit(child()); + /* NOTREACHED */ + } + + (void)sleep(1); /* give child some time to come up */ + + event[0].ident = (uintptr_t)pid; + event[0].filter = EVFILT_PROC; + event[0].flags = EV_ADD | EV_ENABLE; + event[0].fflags = NOTE_EXIT | NOTE_FORK | NOTE_EXEC; /* | NOTE_TRACK;*/ + want = NOTE_EXIT | NOTE_FORK | NOTE_EXEC; + + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + /* wait until we get all events we want */ + while (want) { + RL(kevent(kq, NULL, 0, event, 1, NULL)); + printf("%ld:", (long)event[0].ident); + + if (event[0].fflags & NOTE_EXIT) { + want &= ~NOTE_EXIT; + printf(" NOTE_EXIT"); + } + if (event[0].fflags & NOTE_EXEC) { + want &= ~NOTE_EXEC; + printf(" NOTE_EXEC"); + } + if (event[0].fflags & NOTE_FORK) { + want &= ~NOTE_FORK; + printf(" NOTE_FORK"); + } + if (event[0].fflags & NOTE_CHILD) +#ifdef __FreeBSD__ + printf(" NOTE_CHILD, parent = %" PRIdPTR, event[0].data); +#else + printf(" NOTE_CHILD, parent = %" PRId64, event[0].data); +#endif + + printf("\n"); + } + + (void)waitpid(pid, &status, 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, proc1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/t_proc2.c b/contrib/netbsd-tests/kernel/kqueue/t_proc2.c new file mode 100644 index 0000000..2d905ed --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/t_proc2.c @@ -0,0 +1,139 @@ +/* $NetBSD: t_proc2.c,v 1.3 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Peter Werner . + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_proc2.c,v 1.3 2017/01/13 21:30:41 christos Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +static void +child_two(void) +{ + _exit(EXIT_SUCCESS); +} + +static void +child_one(void) +{ + pid_t pid; + struct passwd *pwd; + const char *nam = "nobody"; + + pwd = getpwnam(nam); + if (pwd == NULL) + err(EXIT_FAILURE, "getpwnam(\"%s\")", nam); + + if ((setuid(pwd->pw_uid)) == -1) + err(EXIT_FAILURE, "setuid(%d)", pwd->pw_uid); + + pid = fork(); + if (pid == -1) + err(EXIT_FAILURE, "fork()"); + + if (pid == 0) + child_two(); + + _exit(EXIT_SUCCESS); +} + +ATF_TC(proc2); +ATF_TC_HEAD(proc2, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "descr", + "Checks EVFILT_PROC for NOTE_FORK|NOTE_TRACK error path problem " + "fixed in rev. 1.1.1.1.2.17 of sys/kern/kern_event.c"); +} +ATF_TC_BODY(proc2, tc) +{ + pid_t pid = 0; + int kq, status; + struct kevent ke; + struct timespec timeout; + + RL(kq = kqueue()); + + timeout.tv_sec = 0; + timeout.tv_nsec = 0; + + RL(pid = fork()); + if (pid == 0) { + (void)sleep(1); /* let parent set kevent */ + child_one(); + /* NOTREACHED */ + } + + EV_SET(&ke, (uintptr_t)pid, EVFILT_PROC, EV_ADD, NOTE_FORK|NOTE_TRACK, + 0, 0); + + RL(kevent(kq, &ke, 1, NULL, 0, &timeout)); + + (void)sleep(2); + + ke.ident = 0; + ke.fflags = 0; + ke.flags = EV_ENABLE; + + RL(kevent(kq, NULL, 0, &ke, 1, &timeout)); + RL(close(kq)); + + RL(waitpid(pid, &status, 0)); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE_EQ(WEXITSTATUS(status), EXIT_SUCCESS); + + /* + * we are expecting an error here as we should not have + * been able to add a knote to child 2. + */ + ATF_REQUIRE(ke.fflags & NOTE_TRACKERR); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, proc2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/t_proc3.c b/contrib/netbsd-tests/kernel/kqueue/t_proc3.c new file mode 100644 index 0000000..6def409 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/t_proc3.c @@ -0,0 +1,99 @@ +/* $NetBSD: t_proc3.c,v 1.3 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_proc3.c,v 1.3 2017/01/13 21:30:41 christos Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(proc3); +ATF_TC_HEAD(proc3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks EVFILT_PROC for NOTE_TRACK on self bug "); +} + +ATF_TC_BODY(proc3, tc) +{ + pid_t pid = 0; + int kq, status; + struct kevent ke; + struct timespec timeout; + + RL(kq = kqueue()); + + EV_SET(&ke, (uintptr_t)getpid(), EVFILT_PROC, EV_ADD, NOTE_TRACK, 0, 0); + + RL(kevent(kq, &ke, 1, NULL, 0, NULL)); + + RL(pid = fork()); + if (pid == 0) { + _exit(EXIT_SUCCESS); + /* NOTREACHED */ + } + + RL(waitpid(pid, &status, 0)); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE_EQ(WEXITSTATUS(status), EXIT_SUCCESS); + + timeout.tv_sec = 0; + timeout.tv_nsec = 0; + ke.ident = 0; + ke.fflags = 0; + ke.flags = EV_ENABLE; + + RL(kevent(kq, NULL, 0, &ke, 1, &timeout)); + RL(close(kq)); + + ATF_REQUIRE(ke.fflags & NOTE_CHILD); + ATF_REQUIRE((ke.fflags & NOTE_TRACKERR) == 0); + ATF_REQUIRE_EQ((pid_t)ke.ident, pid); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, proc3); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/t_sig.c b/contrib/netbsd-tests/kernel/kqueue/t_sig.c new file mode 100644 index 0000000..12e3d61 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/t_sig.c @@ -0,0 +1,147 @@ +/* $NetBSD: t_sig.c,v 1.3 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sig.c,v 1.3 2017/01/13 21:30:41 christos Exp $"); + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +#define NSIGNALS 5 + +ATF_TC(sig); +ATF_TC_HEAD(sig, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_SIGNAL"); +} +ATF_TC_BODY(sig, tc) +{ + struct timespec timeout; +#ifdef __NetBSD__ + struct kfilter_mapping km; +#endif + struct kevent event[1]; +#ifdef __NetBSD__ + char namebuf[32]; +#endif + pid_t pid, child; + int kq, n, num, status; + + pid = getpid(); + (void)printf("my pid: %d\n", pid); + + /* fork a child to send signals */ + RL(child = fork()); + if (child == 0) { + int i; + (void)sleep(2); + for(i = 0; i < NSIGNALS; ++i) { + (void)kill(pid, SIGUSR1); + (void)sleep(2); + } + _exit(0); + /* NOTREACHED */ + } + + RL(kq = kqueue()); + +#ifdef __NetBSD__ + (void)strlcpy(namebuf, "EVFILT_SIGNAL", sizeof(namebuf)); + km.name = namebuf; + RL(ioctl(kq, KFILTER_BYNAME, &km)); + (void)printf("got %d as filter number for `%s'.\n", km.filter, km.name); +#endif + + /* ignore the signal to avoid taking it for real */ + REQUIRE_LIBC(signal(SIGUSR1, SIG_IGN), SIG_ERR); + + event[0].ident = SIGUSR1; +#ifdef __NetBSD__ + event[0].filter = km.filter; +#else + event[0].filter = EVFILT_SIGNAL; +#endif + event[0].flags = EV_ADD | EV_ENABLE; + + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + (void)sleep(1); + + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + for (num = 0; num < NSIGNALS; num += n) { + struct timeval then, now, diff; + + RL(gettimeofday(&then, NULL)); + RL(n = kevent(kq, NULL, 0, event, 1, &timeout)); + RL(gettimeofday(&now, NULL)); + timersub(&now, &then, &diff); + + (void)printf("sig: kevent returned %d in %lld.%06ld\n", + n, (long long)diff.tv_sec, (long)diff.tv_usec); + + if (n == 0) + continue; + +#ifdef __FreeBSD__ + (void)printf("sig: kevent flags: 0x%x, data: %" PRIdPTR " (# " +#else + (void)printf("sig: kevent flags: 0x%x, data: %" PRId64 " (# " +#endif + "times signal posted)\n", event[0].flags, event[0].data); + } + + (void)waitpid(child, &status, 0); + (void)printf("sig: finished successfully\n"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, sig); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/t_vnode.c b/contrib/netbsd-tests/kernel/kqueue/t_vnode.c new file mode 100644 index 0000000..e87c2b2 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/t_vnode.c @@ -0,0 +1,533 @@ +#include +#include +#include +#include +#include +#include + +#include + +/* + * Test cases for events triggered by manipulating a target directory + * content. Using EVFILT_VNODE filter on the target directory descriptor. + * + */ + +static const char *dir_target = "foo"; +static const char *dir_inside1 = "foo/bar1"; +static const char *dir_inside2 = "foo/bar2"; +static const char *dir_outside = "bar"; +static const char *file_inside1 = "foo/baz1"; +static const char *file_inside2 = "foo/baz2"; +static const char *file_outside = "qux"; +static const struct timespec ts = {0, 0}; +static int kq = -1; +static int target = -1; + +int init_target(void); +int init_kqueue(void); +int create_file(const char *); +void cleanup(void); + +int +init_target(void) +{ + if (mkdir(dir_target, S_IRWXU) < 0) { + return -1; + } + target = open(dir_target, O_RDONLY, 0); + return target; +} + +int +init_kqueue(void) +{ + struct kevent eventlist[1]; + + kq = kqueue(); + if (kq < 0) { + return -1; + } + EV_SET(&eventlist[0], (uintptr_t)target, EVFILT_VNODE, + EV_ADD | EV_ONESHOT, NOTE_DELETE | + NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | + NOTE_LINK | NOTE_RENAME | NOTE_REVOKE, 0, 0); + return kevent(kq, eventlist, 1, NULL, 0, NULL); +} + +int +create_file(const char *file) +{ + int fd; + + fd = open(file, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + if (fd < 0) { + return -1; + } + return close(fd); +} + +void +cleanup(void) +{ + (void)unlink(file_inside1); + (void)unlink(file_inside2); + (void)unlink(file_outside); + (void)rmdir(dir_inside1); + (void)rmdir(dir_inside2); + (void)rmdir(dir_outside); + (void)rmdir(dir_target); + (void)close(kq); + (void)close(target); +} + +ATF_TC_WITH_CLEANUP(dir_no_note_link_create_file_in); +ATF_TC_HEAD(dir_no_note_link_create_file_in, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) does not return NOTE_LINK for the directory " + "'foo' if a file 'foo/baz' is created."); +} +ATF_TC_BODY(dir_no_note_link_create_file_in, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(create_file(file_inside1) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_LINK, 0); +} +ATF_TC_CLEANUP(dir_no_note_link_create_file_in, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_no_note_link_delete_file_in); +ATF_TC_HEAD(dir_no_note_link_delete_file_in, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) does not return NOTE_LINK for the directory " + "'foo' if a file 'foo/baz' is deleted."); +} +ATF_TC_BODY(dir_no_note_link_delete_file_in, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(create_file(file_inside1) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(unlink(file_inside1) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_LINK, 0); +} +ATF_TC_CLEANUP(dir_no_note_link_delete_file_in, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_no_note_link_mv_dir_within); +ATF_TC_HEAD(dir_no_note_link_mv_dir_within, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) does not return NOTE_LINK for the directory " + "'foo' if a directory 'foo/bar' is renamed to 'foo/baz'."); +} +ATF_TC_BODY(dir_no_note_link_mv_dir_within, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(mkdir(dir_inside1, S_IRWXU) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(rename(dir_inside1, dir_inside2) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_LINK, 0); +} +ATF_TC_CLEANUP(dir_no_note_link_mv_dir_within, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_no_note_link_mv_file_within); +ATF_TC_HEAD(dir_no_note_link_mv_file_within, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) does not return NOTE_LINK for the directory " + "'foo' if a file 'foo/baz' is renamed to 'foo/qux'."); +} +ATF_TC_BODY(dir_no_note_link_mv_file_within, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(create_file(file_inside1) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(rename(file_inside1, file_inside2) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_LINK, 0); +} +ATF_TC_CLEANUP(dir_no_note_link_mv_file_within, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_link_create_dir_in); +ATF_TC_HEAD(dir_note_link_create_dir_in, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_LINK for the directory " + "'foo' if a directory 'foo/bar' is created."); +} +ATF_TC_BODY(dir_note_link_create_dir_in, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(mkdir(dir_inside1, S_IRWXU) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_LINK, NOTE_LINK); +} +ATF_TC_CLEANUP(dir_note_link_create_dir_in, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_link_delete_dir_in); +ATF_TC_HEAD(dir_note_link_delete_dir_in, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_LINK for the directory " + "'foo' if a directory 'foo/bar' is deleted."); +} +ATF_TC_BODY(dir_note_link_delete_dir_in, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(mkdir(dir_inside1, S_IRWXU) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(rmdir(dir_inside1) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_LINK, NOTE_LINK); +} +ATF_TC_CLEANUP(dir_note_link_delete_dir_in, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_link_mv_dir_in); +ATF_TC_HEAD(dir_note_link_mv_dir_in, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_LINK for the directory " + "'foo' if a directory 'bar' is renamed to 'foo/bar'."); +} +ATF_TC_BODY(dir_note_link_mv_dir_in, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(mkdir(dir_outside, S_IRWXU) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(rename(dir_outside, dir_inside1) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_LINK, NOTE_LINK); +} +ATF_TC_CLEANUP(dir_note_link_mv_dir_in, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_link_mv_dir_out); +ATF_TC_HEAD(dir_note_link_mv_dir_out, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_LINK for the directory " + "'foo' if a directory 'foo/bar' is renamed to 'bar'."); +} +ATF_TC_BODY(dir_note_link_mv_dir_out, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(mkdir(dir_inside1, S_IRWXU) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(rename(dir_inside1, dir_outside) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_LINK, NOTE_LINK); +} +ATF_TC_CLEANUP(dir_note_link_mv_dir_out, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_write_create_dir_in); +ATF_TC_HEAD(dir_note_write_create_dir_in, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_WRITE for the directory " + "'foo' if a directory 'foo/bar' is created."); +} +ATF_TC_BODY(dir_note_write_create_dir_in, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(mkdir(dir_inside1, S_IRWXU) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_WRITE, NOTE_WRITE); +} +ATF_TC_CLEANUP(dir_note_write_create_dir_in, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_write_create_file_in); +ATF_TC_HEAD(dir_note_write_create_file_in, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_WRITE for the directory " + "'foo' if a file 'foo/baz' is created."); +} +ATF_TC_BODY(dir_note_write_create_file_in, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(create_file(file_inside1) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_WRITE, NOTE_WRITE); +} +ATF_TC_CLEANUP(dir_note_write_create_file_in, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_write_delete_dir_in); +ATF_TC_HEAD(dir_note_write_delete_dir_in, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_WRITE for the directory " + "'foo' if a directory 'foo/bar' is deleted."); +} +ATF_TC_BODY(dir_note_write_delete_dir_in, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(mkdir(dir_inside1, S_IRWXU) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(rmdir(dir_inside1) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_WRITE, NOTE_WRITE); +} +ATF_TC_CLEANUP(dir_note_write_delete_dir_in, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_write_delete_file_in); +ATF_TC_HEAD(dir_note_write_delete_file_in, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_WRITE for the directory " + "'foo' if a file 'foo/baz' is deleted."); +} +ATF_TC_BODY(dir_note_write_delete_file_in, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(create_file(file_inside1) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(unlink(file_inside1) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_WRITE, NOTE_WRITE); +} +ATF_TC_CLEANUP(dir_note_write_delete_file_in, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_write_mv_dir_in); +ATF_TC_HEAD(dir_note_write_mv_dir_in, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_WRITE for the directory " + "'foo' if a directory 'bar' is renamed to 'foo/bar'."); +} +ATF_TC_BODY(dir_note_write_mv_dir_in, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(mkdir(dir_outside, S_IRWXU) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(rename(dir_outside, dir_inside1) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_WRITE, NOTE_WRITE); +} +ATF_TC_CLEANUP(dir_note_write_mv_dir_in, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_write_mv_dir_out); +ATF_TC_HEAD(dir_note_write_mv_dir_out, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_WRITE for the directory " + "'foo' if a directory 'foo/bar' is renamed to 'bar'."); +} +ATF_TC_BODY(dir_note_write_mv_dir_out, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(mkdir(dir_inside1, S_IRWXU) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(rename(dir_inside1, dir_outside) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_WRITE, NOTE_WRITE); +} +ATF_TC_CLEANUP(dir_note_write_mv_dir_out, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_write_mv_dir_within); +ATF_TC_HEAD(dir_note_write_mv_dir_within, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_WRITE for the directory " + "'foo' if a directory 'foo/bar' is renamed to 'foo/baz'."); +} +ATF_TC_BODY(dir_note_write_mv_dir_within, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(mkdir(dir_inside1, S_IRWXU) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(rename(dir_inside1, dir_inside2) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_WRITE, NOTE_WRITE); +} +ATF_TC_CLEANUP(dir_note_write_mv_dir_within, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_write_mv_file_in); +ATF_TC_HEAD(dir_note_write_mv_file_in, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_WRITE for the directory " + "'foo' if a file 'qux' is renamed to 'foo/baz'."); +} +ATF_TC_BODY(dir_note_write_mv_file_in, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(create_file(file_outside) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(rename(file_outside, file_inside1) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_WRITE, NOTE_WRITE); +} +ATF_TC_CLEANUP(dir_note_write_mv_file_in, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_write_mv_file_out); +ATF_TC_HEAD(dir_note_write_mv_file_out, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_WRITE for the directory " + "'foo' if a file 'foo/baz' is renamed to 'qux'."); +} +ATF_TC_BODY(dir_note_write_mv_file_out, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(create_file(file_inside1) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(rename(file_inside1, file_outside) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_WRITE, NOTE_WRITE); +} +ATF_TC_CLEANUP(dir_note_write_mv_file_out, tc) +{ + cleanup(); +} + +ATF_TC_WITH_CLEANUP(dir_note_write_mv_file_within); +ATF_TC_HEAD(dir_note_write_mv_file_within, tc) +{ + atf_tc_set_md_var(tc, "descr", "This test case ensures " + "that kevent(2) returns NOTE_WRITE for the directory " + "'foo' if a file 'foo/baz' is renamed to 'foo/qux'."); +} +ATF_TC_BODY(dir_note_write_mv_file_within, tc) +{ + struct kevent changelist[1]; + + ATF_REQUIRE(init_target() != -1); + ATF_REQUIRE(create_file(file_inside1) != -1); + ATF_REQUIRE(init_kqueue() != -1); + + ATF_REQUIRE(rename(file_inside1, file_inside2) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, changelist, 1, &ts) != -1); + ATF_CHECK_EQ(changelist[0].fflags & NOTE_WRITE, NOTE_WRITE); +} +ATF_TC_CLEANUP(dir_note_write_mv_file_within, tc) +{ + cleanup(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, dir_no_note_link_create_file_in); + ATF_TP_ADD_TC(tp, dir_no_note_link_delete_file_in); + ATF_TP_ADD_TC(tp, dir_no_note_link_mv_dir_within); + ATF_TP_ADD_TC(tp, dir_no_note_link_mv_file_within); + ATF_TP_ADD_TC(tp, dir_note_link_create_dir_in); + ATF_TP_ADD_TC(tp, dir_note_link_delete_dir_in); + ATF_TP_ADD_TC(tp, dir_note_link_mv_dir_in); + ATF_TP_ADD_TC(tp, dir_note_link_mv_dir_out); + ATF_TP_ADD_TC(tp, dir_note_write_create_dir_in); + ATF_TP_ADD_TC(tp, dir_note_write_create_file_in); + ATF_TP_ADD_TC(tp, dir_note_write_delete_dir_in); + ATF_TP_ADD_TC(tp, dir_note_write_delete_file_in); + ATF_TP_ADD_TC(tp, dir_note_write_mv_dir_in); + ATF_TP_ADD_TC(tp, dir_note_write_mv_dir_out); + ATF_TP_ADD_TC(tp, dir_note_write_mv_dir_within); + ATF_TP_ADD_TC(tp, dir_note_write_mv_file_in); + ATF_TP_ADD_TC(tp, dir_note_write_mv_file_out); + ATF_TP_ADD_TC(tp, dir_note_write_mv_file_within); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/write/t_fifo.c b/contrib/netbsd-tests/kernel/kqueue/write/t_fifo.c new file mode 100644 index 0000000..fe375b8 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/write/t_fifo.c @@ -0,0 +1,102 @@ +/* $NetBSD: t_fifo.c,v 1.4 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_fifo.c,v 1.4 2017/01/13 21:30:41 christos Exp $"); + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +#define FIFONAME "fifo" + +ATF_TC(fifo); +ATF_TC_HEAD(fifo, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_WRITE for fifo"); +} +ATF_TC_BODY(fifo, tc) +{ + char buffer[128]; + struct kevent event[1]; + pid_t child; + int kq, n, fd, status; + + RL(mkfifo(FIFONAME, 0644)); + RL(fd = open(FIFONAME, O_RDWR, 0644)); + RL(kq = kqueue()); + + /* spawn child reader */ + RL(child = fork()); + if (child == 0) { + int sz = read(fd, buffer, 128); + if (sz > 0) + (void)printf("fifo: child read '%.*s'\n", sz, buffer); + _exit(sz <= 0); + } + + EV_SET(&event[0], fd, EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + (void)memset(event, 0, sizeof(event)); + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + + (void)printf("kevent num %d filt %d flags: %#x, fflags: %#x, " + "data: %" PRId64 "\n", n, event[0].filter, event[0].flags, + event[0].fflags, event[0].data); + + ATF_REQUIRE_EQ(event[0].filter, EVFILT_WRITE); + + RL(write(fd, "foo", 3)); + (void)printf("fifo: wrote 'foo'\n"); + RL(close(fd)); + + (void)waitpid(child, &status, 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, fifo); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/write/t_pipe.c b/contrib/netbsd-tests/kernel/kqueue/write/t_pipe.c new file mode 100644 index 0000000..5b2ca8c --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/write/t_pipe.c @@ -0,0 +1,147 @@ +/* $NetBSD: t_pipe.c,v 1.2 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_pipe.c,v 1.2 2017/01/13 21:30:41 christos Exp $"); + +#include +#include + +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(pipe1); +ATF_TC_HEAD(pipe1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks EVFILT_WRITE for pipes. This test used to trigger " + "problem fixed in rev. 1.5.2.7 of sys/kern/sys_pipe.c"); +} +ATF_TC_BODY(pipe1, tc) +{ + struct kevent event[1]; + int fds[2]; + int kq, n; + + RL(pipe(fds)); + RL(kq = kqueue()); + RL(close(fds[0])); + + EV_SET(&event[0], fds[1], EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0); + ATF_REQUIRE_EQ_MSG((n = kevent(kq, event, 1, NULL, 0, NULL)), + -1, "got: %d", n); + ATF_REQUIRE_EQ_MSG(errno, EBADF, "got: %s", strerror(errno)); +} + +ATF_TC(pipe2); +ATF_TC_HEAD(pipe2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks EVFILT_WRITE for pipes. This test used to trigger problem " + "fixed in rev. 1.5.2.9 of sys/kern/sys_pipe.c"); +} +ATF_TC_BODY(pipe2, tc) +{ + struct kevent event[1]; + char buffer[128]; + int fds[2]; + int kq, n; + int status; + pid_t child; + + RL(pipe(fds)); + RL(kq = kqueue()); + + EV_SET(&event[0], fds[1], EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + /* spawn child reader */ + RL(child = fork()); + if (child == 0) { + int sz = read(fds[0], buffer, 128); + if (sz > 0) + (void)printf("pipe: child read '%.*s'\n", sz, buffer); + exit(sz <= 0); + } + + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + + (void)printf("kevent num %d flags: %#x, fflags: %#x, data: " + "%" PRId64 "\n", n, event[0].flags, event[0].fflags, event[0].data); + + RL(n = write(fds[1], "foo", 3)); + RL(close(fds[1])); + + (void)waitpid(child, &status, 0); +} + +ATF_TC(pipe3); +ATF_TC_HEAD(pipe3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks EVFILT_WRITE for pipes. This test used to trigger problem " + "fixed in rev. 1.5.2.10 of sys/kern/sys_pipe.c"); +} +ATF_TC_BODY(pipe3, tc) +{ + struct kevent event[1]; + int fds[2]; + int kq; + + RL(pipe(fds)); + RL(kq = kqueue()); + + EV_SET(&event[0], fds[1], EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + /* close 'read' end first, then 'write' */ + + RL(close(fds[0])); + RL(close(fds[1])); +} + + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pipe1); + ATF_TP_ADD_TC(tp, pipe2); + ATF_TP_ADD_TC(tp, pipe3); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/kqueue/write/t_ttypty.c b/contrib/netbsd-tests/kernel/kqueue/write/t_ttypty.c new file mode 100644 index 0000000..45a6750 --- /dev/null +++ b/contrib/netbsd-tests/kernel/kqueue/write/t_ttypty.c @@ -0,0 +1,130 @@ +/* $NetBSD: t_ttypty.c,v 1.2 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn and Jaromir Dolecek. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ttypty.c,v 1.2 2017/01/13 21:30:41 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +static void +h_check(bool check_master) +{ + char slavetty[1024]; + char buffer[128]; + struct kevent event[1]; + struct pollfd pfd; + pid_t child; + int status, kq, n; + int amaster, aslave, acurrent; + + RL(openpty(&amaster, &aslave, slavetty, NULL, NULL)); + (void)printf("tty: openpty master %d slave %d tty '%s'\n", + amaster, aslave, slavetty); + acurrent = check_master ? amaster : aslave; + + RL(child = fork()); + if (child == 0) { + (void)sleep(1); + + n = read(check_master ? aslave : amaster, buffer, 128); + (void)printf("tty: child read '%.*s'\n", n, buffer); + + _exit(0); + } + + pfd.fd = acurrent; + pfd.events = POLLOUT; + (void)printf("tty: polling ...\n"); + RL(poll(&pfd, 1, INFTIM)); + (void)printf("tty: returned from poll - %d\n", pfd.revents); + + RL(kq = kqueue()); + + EV_SET(&event[0], acurrent, EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0); + RL(kevent(kq, event, 1, NULL, 0, NULL)); + + RL(n = kevent(kq, NULL, 0, event, 1, NULL)); + + (void)printf("kevent num %d filt %d flags: %#x, fflags: %#x, data: " + "%" PRId64 "\n", n, event[0].filter, event[0].flags, event[0].fflags, + event[0].data); + + ATF_REQUIRE_EQ(event[0].filter, EVFILT_WRITE); + + RL(n = write(acurrent, "f00\n", 4)); + (void)printf("tty: wrote 'f00\\n' (wrote %d characters)\n", n); + + (void)waitpid(child, &status, 0); + (void)printf("tty: successful end\n"); +} + +ATF_TC(master); +ATF_TC_HEAD(master, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_WRITE for master tty"); +} +ATF_TC_BODY(master, tc) +{ + h_check(true); +} + +ATF_TC(slave); +ATF_TC_HEAD(slave, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks EVFILT_WRITE for slave tty"); +} +ATF_TC_BODY(slave, tc) +{ + h_check(false); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, master); + ATF_TP_ADD_TC(tp, slave); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/msg.h b/contrib/netbsd-tests/kernel/msg.h new file mode 100644 index 0000000..547400e --- /dev/null +++ b/contrib/netbsd-tests/kernel/msg.h @@ -0,0 +1,136 @@ +/* $NetBSD: msg.h,v 1.1 2016/12/05 20:10:10 christos Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +struct msg_fds { + int pfd[2]; + int cfd[2]; +}; + +#define CLOSEFD(fd) do { \ + if (fd != -1) { \ + close(fd); \ + fd = -1; \ + } \ +} while (/*CONSTCOND*/ 0) + +static int +msg_open(struct msg_fds *fds) +{ + if (pipe(fds->pfd) == -1) + return -1; + if (pipe(fds->cfd) == -1) { + close(fds->pfd[0]); + close(fds->pfd[1]); + return -1; + } + return 0; +} + +static void +msg_close(struct msg_fds *fds) +{ + CLOSEFD(fds->pfd[0]); + CLOSEFD(fds->pfd[1]); + CLOSEFD(fds->cfd[0]); + CLOSEFD(fds->cfd[1]); +} + +static int +msg_write_child(const char *info, struct msg_fds *fds, void *msg, size_t len) +{ + ssize_t rv; + CLOSEFD(fds->cfd[1]); + CLOSEFD(fds->pfd[0]); + + printf("Send %s\n", info); + rv = write(fds->pfd[1], msg, len); + if (rv != (ssize_t)len) + return 1; +// printf("Wait %s\n", info); + rv = read(fds->cfd[0], msg, len); + if (rv != (ssize_t)len) + return 1; + return 0; +} + +static int +msg_write_parent(const char *info, struct msg_fds *fds, void *msg, size_t len) +{ + ssize_t rv; + CLOSEFD(fds->pfd[1]); + CLOSEFD(fds->cfd[0]); + + printf("Send %s\n", info); + rv = write(fds->cfd[1], msg, len); + if (rv != (ssize_t)len) + return 1; +// printf("Wait %s\n", info); + rv = read(fds->pfd[0], msg, len); + if (rv != (ssize_t)len) + return 1; + return 0; +} + +static int +msg_read_parent(const char *info, struct msg_fds *fds, void *msg, size_t len) +{ + ssize_t rv; + CLOSEFD(fds->pfd[1]); + CLOSEFD(fds->cfd[0]); + + printf("Wait %s\n", info); + rv = read(fds->pfd[0], msg, len); + if (rv != (ssize_t)len) + return 1; +// printf("Send %s\n", info); + rv = write(fds->cfd[1], msg, len); + if (rv != (ssize_t)len) + return 1; + return 0; +} + +static int +msg_read_child(const char *info, struct msg_fds *fds, void *msg, size_t len) +{ + ssize_t rv; + CLOSEFD(fds->cfd[1]); + CLOSEFD(fds->pfd[0]); + + printf("Wait %s\n", info); + rv = read(fds->cfd[0], msg, len); + if (rv != (ssize_t)len) + return 1; +// printf("Send %s\n", info); + rv = write(fds->pfd[1], msg, len); + if (rv != (ssize_t)len) + return 1; + return 0; +} diff --git a/contrib/netbsd-tests/kernel/t_extattrctl.c b/contrib/netbsd-tests/kernel/t_extattrctl.c new file mode 100644 index 0000000..2f8932e --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_extattrctl.c @@ -0,0 +1,28 @@ +#include + +#include +#include + +#include + +ATF_TC(extattrctl_namei); +ATF_TC_HEAD(extattrctl_namei, tc) +{ + + atf_tc_set_md_var(tc, "descr", "extattrctl namei safety (kern/43328)"); +} + +ATF_TC_BODY(extattrctl_namei, tc) +{ + + rump_init(); + + rump_sys_extattrctl("/anyfile", 0, "/", 0, 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, extattrctl_namei); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_extent.c b/contrib/netbsd-tests/kernel/t_extent.c new file mode 100644 index 0000000..57dfc2b --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_extent.c @@ -0,0 +1,385 @@ +/* $NetBSD: t_extent.c,v 1.5 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_extent.c,v 1.5 2017/01/13 21:30:41 christos Exp $"); + +#include +#include +#include + +#include +#include +#include + +#include + +#include "h_macros.h" + +static int ret; +static struct extent *ex; + +#define h_create(name, start, end, flags) \ + ATF_REQUIRE((ex = extent_create(name, \ + start, end, 0, 0, flags)) != NULL); + +#define h_alloc_region(start, size) \ + ATF_REQUIRE_EQ_MSG(ret = extent_alloc_region(ex, \ + start, size, 0), 0, "%s", strerror(ret)); + +#define h_free(start, size) \ + ATF_REQUIRE_EQ_MSG(ret = extent_free(ex, \ + start, size, 0), 0, "%s", strerror(ret)); + +static void +h_alloc_subregion(u_long substart, u_long subend, u_long size, + u_long alignment, u_long boundary, int expret, u_long expres) +{ + u_long result; + +#define FAIL(fmt, ...) \ + atf_tc_fail("extent_alloc_subregion1(ex, %#lx, %#lx, %#lx, %#lx, 0, " \ + "%#lx, 0, &result): " fmt, substart, subend, size, alignment, \ + boundary, ##__VA_ARGS__) + + ret = extent_alloc_subregion1(ex, substart, subend, size, + alignment, 0, boundary, 0, &result); + + if (ret != expret) + FAIL("%s", strerror(errno)); + + if (expret == 0 && result != expres) + FAIL("result should be: %#lx, got: %#lx", expres, result); +#undef FAIL +} + +static void +h_require(const char *name, u_long start, + u_long end, int flags, const char *exp) +{ + char buf[4096]; + struct extent_region *rp; + int n = 0; + + ATF_REQUIRE_STREQ_MSG(ex->ex_name, name, + "expected: \"%s\", got: \"%s\"", name, ex->ex_name); + ATF_REQUIRE_EQ_MSG(ex->ex_start, start, + "expected: %#lx, got: %#lx", start, ex->ex_start); + ATF_REQUIRE_EQ_MSG(ex->ex_end, end, + "expected: %#lx, got: %#lx", end, ex->ex_end); + ATF_REQUIRE_EQ_MSG(ex->ex_flags, flags, + "expected: %#x, got: %#x", flags, ex->ex_flags); + + (void)memset(buf, 0, sizeof(buf)); + LIST_FOREACH(rp, &ex->ex_regions, er_link) + n += snprintf(buf + n, sizeof(buf) - n, + "0x%lx - 0x%lx\n", rp->er_start, rp->er_end); + + if (strcmp(buf, exp) == 0) + return; + + printf("Incorrect extent map\n"); + printf("Expected:\n%s\n", exp); + printf("Got:\n%s\n", buf); + atf_tc_fail("incorrect extent map"); +} + +ATF_TC(coalesce); +ATF_TC_HEAD(coalesce, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks coalescing of regions"); +} +ATF_TC_BODY(coalesce, tc) +{ + h_create("test1", 0, 0x4f, 0); + + h_alloc_region(0x00, 0x10); + h_alloc_region(0x20, 0x10); + h_alloc_region(0x40, 0x10); + h_alloc_region(0x10, 0x10); + h_alloc_subregion(0, 0x4f, 0x10, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x30); + + h_require("test1", 0x00, 0x4f, 0x00, + "0x0 - 0x4f\n"); + + extent_destroy(ex); +} + +ATF_TC(subregion1); +ATF_TC_HEAD(subregion1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that subregions work (PR kern/7539)"); +} +ATF_TC_BODY(subregion1, tc) +{ + h_create("test2", 0, 0x2f, EX_NOCOALESCE); + + h_alloc_region(0x00, 0x10); + h_alloc_subregion(0x20, 0x30, 0x10, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x20); + + h_require("test2", 0x00, 0x2f, 0x2, + "0x0 - 0xf\n" + "0x20 - 0x2f\n"); + + extent_destroy(ex); +} + +ATF_TC(subregion2); +ATF_TC_HEAD(subregion2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that subregion allocations don't overlap with existing " + "ones (fixed in 1.25)"); +} +ATF_TC_BODY(subregion2, tc) +{ + h_create("test3", 0, 0x3f, EX_NOCOALESCE); + + h_alloc_region(0x00, 0x20); + h_alloc_region(0x30, 0x10); + h_alloc_subregion(0x10, 0x3f, 0x10, + EX_NOALIGN, EX_NOBOUNDARY, 0, 0x20); + + h_require("test3", 0x00, 0x3f, 0x2, + "0x0 - 0x1f\n" + "0x20 - 0x2f\n" + "0x30 - 0x3f\n"); + + extent_destroy(ex); +} + +ATF_TC(bound1); +ATF_TC_HEAD(bound1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks for overflow in boundary check, before an allocated region " + "(fixed in 1.32)"); +} +ATF_TC_BODY(bound1, tc) +{ + h_create("test4", 0xf0000000, 0xffffffff, 0); + + h_alloc_region(0xf1000000, 0x1); + h_alloc_subregion(0xf0000000, 0xffffffff, 0x1, + EX_NOALIGN, 0x20000000, 0, 0xf0000000); + + h_require("test4", 0xf0000000, 0xffffffff, 0x0, + "0xf0000000 - 0xf0000000\n" + "0xf1000000 - 0xf1000000\n"); + + extent_destroy(ex); +} + +ATF_TC(bound2); +ATF_TC_HEAD(bound2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks for overflow in boundary checks, before the subregion end " + "(fixed in 1.32)"); +} +ATF_TC_BODY(bound2, tc) +{ + h_create("test5", 0xf0000000, 0xffffffff, 0); + + h_alloc_subregion(0xf0000000, 0xffffffff, 0x1, + EX_NOALIGN, 0x20000000, 0, 0xf0000000); + + h_require("test5", 0xf0000000, 0xffffffff, 0x0, + "0xf0000000 - 0xf0000000\n"); + + extent_destroy(ex); +} + +ATF_TC(bound3); +ATF_TC_HEAD(bound3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks allocation beyond last boundary line: last two " + "allocations should succeed without boundary \"fixups\""); +} +ATF_TC_BODY(bound3, tc) +{ + h_create("test6", 0, 11, 0); + + h_alloc_subregion(0, 11, 8, EX_NOALIGN, 8, 0, 0); + h_alloc_subregion(0, 11, 2, EX_NOALIGN, 8, 0, 0x8); + h_alloc_subregion(0, 11, 2, EX_NOALIGN, 8, 0, 0xa); + + h_require("test6", 0x0, 0xb, 0x0, "0x0 - 0xb\n"); + + extent_destroy(ex); +} + +ATF_TC(bound4); +ATF_TC_HEAD(bound4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks allocation beyond last boundary line: last allocation " + "should be bumped to the next boundary and exactly fit the " + "remaining space"); +} +ATF_TC_BODY(bound4, tc) +{ + h_create("test7", 0, 11, 0); + + h_alloc_subregion(0, 11, 7, EX_NOALIGN, 8, 0, 0); + h_alloc_subregion(0, 11, 4, EX_NOALIGN, 8, 0, 8); + + h_require("test7", 0x0, 0xb, 0x0, + "0x0 - 0x6\n" + "0x8 - 0xb\n"); + + extent_destroy(ex); +} + +ATF_TC(subregion3); +ATF_TC_HEAD(subregion3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that we don't allocate a region pasts the end of " + "subregion (i.e., the second alloc_subregion should fail). " + "subr_extent.c prior to rev. 1.43 allocated region starting " + "from 0x10"); +} +ATF_TC_BODY(subregion3, tc) +{ + h_create("test8", 0, 0x4f, EX_NOCOALESCE); + + h_alloc_region(0x30, 0x10); + h_alloc_subregion(0, 0xf, 0x10, EX_NOALIGN, EX_NOBOUNDARY, 0, 0); + h_alloc_subregion(0, 0xf, 0x10, EX_NOALIGN, EX_NOBOUNDARY, EAGAIN, 0); + + h_require("test8", 0x0, 0x4f, 0x2, + "0x0 - 0xf\n" + "0x30 - 0x3f\n"); + + extent_destroy(ex); +} + +ATF_TC(bound5); +ATF_TC_HEAD(bound5, tc) +{ + atf_tc_set_md_var(tc, "descr", + "When allocating a region with a boundary constraint, checks " + "proper detection of overflaps once the candidate region has " + "been aligned. subr_extent.c prior 1.45 could corrupt the extent " + "map in this situation"); +} +ATF_TC_BODY(bound5, tc) +{ + h_create("test9", 0, 0x4f, 0); + + h_alloc_subregion(0, 0x10, 4, EX_NOALIGN, 0, 0, 0); + h_alloc_subregion(0xd, 0x20, 2, EX_NOALIGN, 0, 0, 0xd); + h_alloc_subregion(0, 0x4f, 8, EX_NOALIGN, 8, 0, 0x10); + + h_require("test9", 0x0, 0x4f, 0x0, + "0x0 - 0x3\n" + "0xd - 0xe\n" + "0x10 - 0x17\n"); + + extent_destroy(ex); +} + +ATF_TC(free); +ATF_TC_HEAD(free, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks extent_free()"); +} +ATF_TC_BODY(free, tc) +{ + h_create("test10", 0xc0002000, 0xffffe000, EX_BOUNDZERO); + + h_alloc_subregion(0xc0002000, 0xffffe000, 0x2000, + 0x10000, 0x10000, 0, 0xc0010000); + h_alloc_subregion(0xc0002000, 0xffffe000, 0x2000, + 0x10000, 0x10000, 0, 0xc0020000); + + h_require("test10", 0xc0002000, 0xffffe000, 0x0, + "0xc0010000 - 0xc0011fff\n" + "0xc0020000 - 0xc0021fff\n"); + + h_free(0xc0020000, 0x2000); + h_require("test10", 0xc0002000, 0xffffe000, 0x0, + "0xc0010000 - 0xc0011fff\n"); + + h_alloc_subregion(0xc0002000, 0xffffe000, 0x10000, + 0x10000, 0x10000, 0, 0xc0022000); + + h_require("test10", 0xc0002000, 0xffffe000, 0x0, + "0xc0010000 - 0xc0011fff\n" + "0xc0022000 - 0xc0031fff\n"); + + extent_destroy(ex); +} + +ATF_TC(subregion4); +ATF_TC_HEAD(subregion4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks for off-by-one bug which would cause a region at the end " + "of the extent to be allocated multiple times (fixed in 1.51)"); +} +ATF_TC_BODY(subregion4, tc) +{ + h_create("test11", 0x10, 0x20, EX_NOCOALESCE); + + h_alloc_subregion(0x10, 0x13, 0x4, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x10); + h_alloc_subregion(0x1e, 0x1f, 0x2, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x1e); + h_alloc_subregion(0x20, 0x20, 0x1, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x20); + h_alloc_subregion(0x20, 0x20, 0x1, EX_NOALIGN, EX_NOBOUNDARY, EAGAIN, 0); + h_alloc_subregion(0x10, 0x20, 0x1, EX_NOALIGN, EX_NOBOUNDARY, 0, 0x14); + + h_require("test11", 0x10, 0x20, 0x2, + "0x10 - 0x13\n" + "0x14 - 0x14\n" + "0x1e - 0x1f\n" + "0x20 - 0x20\n"); + + extent_destroy(ex); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, coalesce); + ATF_TP_ADD_TC(tp, subregion1); + ATF_TP_ADD_TC(tp, subregion2); + ATF_TP_ADD_TC(tp, bound1); + ATF_TP_ADD_TC(tp, bound2); + ATF_TP_ADD_TC(tp, bound3); + ATF_TP_ADD_TC(tp, bound4); + ATF_TP_ADD_TC(tp, subregion3); + ATF_TP_ADD_TC(tp, bound5); + ATF_TP_ADD_TC(tp, free); + ATF_TP_ADD_TC(tp, subregion4); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_filedesc.c b/contrib/netbsd-tests/kernel/t_filedesc.c new file mode 100644 index 0000000..a938d6f --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_filedesc.c @@ -0,0 +1,108 @@ +/* $NetBSD: t_filedesc.c,v 1.6 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_filedesc.c,v 1.6 2017/01/13 21:30:41 christos Exp $"); + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "h_macros.h" + +ATF_TC(getfilerace); +ATF_TC_HEAD(getfilerace, tc) +{ + + atf_tc_set_md_var(tc, "descr", "race between multithreaded proc. " + "fd_getfile() and fd_close() (PR kern/43694)"); +} + +static int fd; +static volatile bool quit; + +static void * +wrkwrk(void *arg) +{ + + /* just something to cause fd_getfile() to be called */ + while (!quit) + rump_sys_write(fd, &fd, sizeof(fd)); + + return NULL; +} + +/* for me, 1000 triggers extremely seldom, 10k sometimes, 100k almost always */ +#define DEFAULT_ITERATIONS 10000 + +ATF_TC_BODY(getfilerace, tc) +{ + pthread_t pt; + int fd_wrk; + int i, iters; + + /* + * Want a multiprocessor virtual kernel. A multiprocessor host + * probably helps too, but that's harder to do in software... + */ + setenv("RUMP_NCPU", "2", 1); + rump_init(); + + fd = fd_wrk = rump_sys_open("/dev/null", O_RDWR, 0); + if (fd == -1) + atf_tc_fail_errno("cannot open /dev/null"); + + if (atf_tc_has_config_var(tc, "iters")) + iters = atoi(atf_tc_get_config_var(tc, "iters")); + else + iters = DEFAULT_ITERATIONS; + + pthread_create(&pt, NULL, wrkwrk, NULL); + for (i = 0; i < iters; i++) { + rump_sys_close(fd_wrk); + fd_wrk = rump_sys_open("/dev/null", O_RDWR, 0); + assert(fd == fd_wrk); + } + + quit = true; + pthread_join(pt, NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, getfilerace); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_kauth_pr_47598.c b/contrib/netbsd-tests/kernel/t_kauth_pr_47598.c new file mode 100644 index 0000000..f54b289 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_kauth_pr_47598.c @@ -0,0 +1,169 @@ +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2013\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_kauth_pr_47598.c,v 1.3 2014/04/28 08:34:16 martin Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * helper function + */ +static const char curtain_name[] = "security.models.bsd44.curtain"; +static const char securelevel_name[] = "security.models.bsd44.securelevel"; + +static bool may_lower_curtain(void); +static int get_curtain(void); +static void set_curtain(int newval); + +static bool +may_lower_curtain(void) +{ + int seclevel; + size_t len = sizeof(seclevel); + + if (sysctlbyname(securelevel_name, &seclevel, &len, NULL, 0) != 0) + atf_tc_fail("failed to read %s", securelevel_name); + + return seclevel <= 0; +} + +static int +get_curtain(void) +{ + int curtain; + size_t len = sizeof(curtain); + + if (sysctlbyname(curtain_name, &curtain, &len, NULL, 0) != 0) + atf_tc_fail("failed to read %s", curtain_name); + + return curtain; +} + +static void +set_curtain(int newval) +{ + + if (sysctlbyname(curtain_name, NULL, 0, &newval, sizeof(newval)) != 0) + atf_tc_fail("failed to set %s to %d", curtain_name, newval); +} + +/* + * PR kern/47598: if security.models.extensions.curtain = 1 we crash when + * doing a netstat while an embryonic (not yet fully accepted) connection + * exists. + * This has been fixed with rev. 1.5 of + * src/sys/secmodel/extensions/secmodel_extensions.c. + */ + + +ATF_TC(kauth_curtain); +ATF_TC_HEAD(kauth_curtain, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "require.progs", "netstat"); + atf_tc_set_md_var(tc, "descr", + "Checks for kernel crash with curtain active (PR kern/47598)"); +} + +ATF_TC_BODY(kauth_curtain, tc) +{ + + int old_curtain, s, s2, err; + socklen_t slen; + struct sockaddr_in sa; + + /* + * save old value of "curtain" and enable it + */ + old_curtain = get_curtain(); + if (old_curtain < 1 && !may_lower_curtain()) + atf_tc_skip("curtain is not enabled and we would not be able" + " to drop it later due to securelevel settings"); + + set_curtain(1); + + /* + * create a socket and bind it to some arbitray free port + */ + s = socket(PF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0); + ATF_REQUIRE(s != -1); + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_len = sizeof(sa); + sa.sin_addr.s_addr = inet_addr("127.0.0.1"); + ATF_REQUIRE(bind(s, (struct sockaddr *)&sa, sizeof(sa))==0); + ATF_REQUIRE(listen(s, 16)==0); + + /* + * extract address and open a connection to the port + */ + slen = sizeof(sa); + ATF_REQUIRE(getsockname(s, (struct sockaddr *)&sa, &slen)==0); + s2 = socket(PF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0); + ATF_REQUIRE(s2 != -1); + printf("port is %d\n", ntohs(sa.sin_port)); + err = connect(s2, (struct sockaddr *)&sa, sizeof(sa)); + ATF_REQUIRE_MSG(err == -1 && errno == EINPROGRESS, + "conect returned %d with errno %d", err, errno); + fflush(stdout); + fflush(stderr); + + /* + * we now have a pending, not yet accepted connection - run netstat + */ + system("netstat -aA"); + + /* + * cleanup + */ + close(s2); + close(s); + + /* + * restore old value of curtain + */ + set_curtain(old_curtain); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, kauth_curtain); + + return atf_no_error(); +} + + diff --git a/contrib/netbsd-tests/kernel/t_lock.c b/contrib/netbsd-tests/kernel/t_lock.c new file mode 100644 index 0000000..bd83abe --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_lock.c @@ -0,0 +1,87 @@ +/* $NetBSD: t_lock.c,v 1.2 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_lock.c,v 1.2 2017/01/13 21:30:41 christos Exp $"); + +#include + +#include +#include + +#include + +#include "h_macros.h" + +__cpu_simple_lock_t lk; +volatile int handled = 0; + +static void +handler(int sig) +{ + handled = 1; + __cpu_simple_unlock(&lk); +} + +ATF_TC(lock); +ATF_TC_HEAD(lock, tc) +{ + atf_tc_set_md_var(tc, "timeout", "3"); + atf_tc_set_md_var(tc, "descr", + "Checks __cpu_simple_lock()/__cpu_simple_unlock()"); +} +ATF_TC_BODY(lock, tc) +{ + struct itimerval itv; + + __cpu_simple_lock_init(&lk); + + REQUIRE_LIBC(signal(SIGVTALRM, handler), SIG_ERR); + + itv.it_interval.tv_sec = 0; + itv.it_interval.tv_usec = 0; + itv.it_value.tv_sec = 1; + itv.it_value.tv_usec = 0; + RL(setitimer(ITIMER_VIRTUAL, &itv, NULL)); + + __cpu_simple_lock(&lk); + __cpu_simple_lock(&lk); + + ATF_REQUIRE(handled); + + __cpu_simple_unlock(&lk); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, lock); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_lockf.c b/contrib/netbsd-tests/kernel/t_lockf.c new file mode 100644 index 0000000..702e612 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_lockf.c @@ -0,0 +1,265 @@ +/* $NetBSD: t_lockf.c,v 1.9 2013/10/19 17:45:00 christos Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * lockf1 regression test: + * + * Tests: + * Fork N child processes, each of which gets M random byte range locks + * on a common file. We ignore all lock errors (practically speaking, + * this means EDEADLK or ENOLOCK), but we make numerous passes over all + * the children to make sure that they are still awake. (We do this by + * verifying that we can ptrace(ATTACH/DETACH) to the children and get + * their status via waitpid().) + * When finished, reap all the children. + */ + +#define nlocks 500 /* number of locks per thread */ +#define nprocs 10 /* number of processes to spawn */ +#define npasses 50 /* number of passes to make over the children */ +#define sleeptime 150000 /* sleep time between locks, usec */ +#define filesize 8192 /* size of file to lock */ + +const char *lockfile = "lockf_test"; + +static u_int32_t +random_uint32(void) +{ + return lrand48(); +} + +static void +trylocks(int id) +{ + int i, fd; + + srand48(getpid()); + + fd = open (lockfile, O_RDWR, 0); + + if (fd < 0) + err(1, "%s", lockfile); + + printf("%d: start\n", id); + + for (i = 0; i < nlocks; i++) { + struct flock fl; + + fl.l_start = random_uint32() % filesize; + fl.l_len = random_uint32() % filesize; + switch (random_uint32() % 3) { + case 0: + fl.l_type = F_RDLCK; + break; + case 1: + fl.l_type = F_WRLCK; + break; + case 2: + fl.l_type = F_UNLCK; + break; + } + fl.l_whence = SEEK_SET; + + (void)fcntl(fd, F_SETLKW, &fl); + + if (usleep(sleeptime) < 0) +#if defined(__FreeBSD__) + if (errno != EINTR) +#endif + err(1, "usleep"); + } + printf("%d: done\n", id); + close (fd); +} + +ATF_TC(randlock); +ATF_TC_HEAD(randlock, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "300"); + atf_tc_set_md_var(tc, "descr", "Checks fcntl(2) locking"); +} + +ATF_TC_BODY(randlock, tc) +{ + int i, j, fd; + int pipe_fd[2]; + pid_t *pid; + int status; + char pipe_in, pipe_out; + const char pipe_errmsg[] = "child: pipe write failed\n"; + + (void)unlink(lockfile); + + fd = open (lockfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0666); + ATF_REQUIRE_MSG(fd >= 0, "open(%s): %s", lockfile, strerror(errno)); + + ATF_REQUIRE_MSG(ftruncate(fd, filesize) >= 0, + "ftruncate(%s): %s", lockfile, strerror(errno)); + + ATF_REQUIRE_MSG(pipe(pipe_fd) == 0, "pipe: %s", strerror(errno)); + + fsync(fd); + close(fd); + + pid = malloc(nprocs * sizeof(pid_t)); + + for (i = 0; i < nprocs; i++) { + pipe_out = (char)('A' + i); + pid[i] = fork(); + switch (pid[i]) { + case 0: + if (write(pipe_fd[1], &pipe_out, 1) != 1) + write(STDERR_FILENO, pipe_errmsg, + __arraycount(pipe_errmsg) - 1); + else + trylocks(i); + _exit(0); + break; + case -1: + atf_tc_fail("fork %d failed", i); + break; + default: + ATF_REQUIRE_MSG(read(pipe_fd[0], &pipe_in, 1) == 1, + "parent: read_pipe(%i): %s", i, strerror(errno)); + ATF_REQUIRE_MSG(pipe_in == pipe_out, + "parent: pipe does not match"); + break; + } + } + for (j = 0; j < npasses; j++) { + printf("parent: run %i\n", j+1); + for (i = 0; i < nprocs; i++) { + ATF_REQUIRE_MSG(ptrace(PT_ATTACH, pid[i], 0, 0) >= 0, + "ptrace attach %d", pid[i]); + ATF_REQUIRE_MSG(waitpid(pid[i], &status, WUNTRACED) >= 0, + "waitpid(ptrace)"); + usleep(sleeptime / 3); + ATF_REQUIRE_MSG(ptrace(PT_DETACH, pid[i], (caddr_t)1, + 0) >= 0, + "ptrace detach %d", pid[i]); + usleep(sleeptime / 3); + } + } + for (i = 0; i < nprocs; i++) { + printf("reap %d: ", i); + fflush(stdout); + kill(pid[i], SIGINT); + waitpid(pid[i], &status, 0); + printf(" status %d\n", status); + } + atf_tc_pass(); +} + +static int +dolock(int fd, int op, off_t lk_off, off_t lk_size) +{ + off_t result; + int ret; + + result = lseek(fd, lk_off, SEEK_SET); + if (result == -1) { + return errno; + } + ATF_REQUIRE_MSG(result == lk_off, "lseek to wrong offset"); + ret = lockf(fd, op, lk_size); + if (ret == -1) { + return errno; + } + return 0; +} + +ATF_TC(deadlock); +ATF_TC_HEAD(deadlock, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "30"); + atf_tc_set_md_var(tc, "descr", "Checks fcntl(2) deadlock detection"); +} + +ATF_TC_BODY(deadlock, tc) +{ + int fd; + int error; + int ret; + pid_t pid; + + (void)unlink(lockfile); + + fd = open (lockfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0666); + ATF_REQUIRE_MSG(fd >= 0, "open(%s): %s", lockfile, strerror(errno)); + + ATF_REQUIRE_MSG(ftruncate(fd, filesize) >= 0, + "ftruncate(%s): %s", lockfile, strerror(errno)); + + fsync(fd); + + error = dolock(fd, F_LOCK, 0, 1); + ATF_REQUIRE_MSG(error == 0, "initial dolock: %s", strerror(errno)); + + pid = fork(); + ATF_REQUIRE_MSG(pid != -1, "fork failed: %s", strerror(errno)); + if (pid == 0) { + error = dolock(fd, F_LOCK, 1, 1); + ATF_REQUIRE_MSG(error == 0, "child dolock: %s", + strerror(errno)); + dolock(fd, F_LOCK, 0, 1); /* will block */ + atf_tc_fail("child did not block"); + } + sleep(1); /* give child time to grab its lock then block */ + + error = dolock(fd, F_LOCK, 1, 1); + ATF_REQUIRE_MSG(error == EDEADLK, "parent did not detect deadlock: %s", + strerror(errno)); + ret = kill(pid, SIGKILL); + ATF_REQUIRE_MSG(ret != -1, "failed to kill child: %s", strerror(errno)); + + atf_tc_pass(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, randlock); + ATF_TP_ADD_TC(tp, deadlock); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_mqueue.c b/contrib/netbsd-tests/kernel/t_mqueue.c new file mode 100644 index 0000000..7edbbc9 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_mqueue.c @@ -0,0 +1,154 @@ +/* $NetBSD: t_mqueue.c,v 1.6 2017/01/14 20:57:24 christos Exp $ */ + +/* + * Test for POSIX message queue priority handling. + * + * This file is in the Public Domain. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __FreeBSD__ +#include "freebsd_test_suite/macros.h" +#endif + +#define MQ_PRIO_BASE 24 + +static void +send_msgs(mqd_t mqfd) +{ + char msg[2]; + + msg[1] = '\0'; + + msg[0] = 'a'; + ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1, + "mq_send 1 failed: %d", errno); + + msg[0] = 'b'; + ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1, + "mq_send 2 failed: %d", errno); + + msg[0] = 'c'; + ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE) != -1, + "mq_send 3 failed: %d", errno); + + msg[0] = 'd'; + ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE - 1) != -1, + "mq_send 4 failed: %d", errno); + + msg[0] = 'e'; + ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), 0) != -1, + "mq_send 5 failed: %d", errno); + + msg[0] = 'f'; + ATF_REQUIRE_MSG(mq_send(mqfd, msg, sizeof(msg), MQ_PRIO_BASE + 1) != -1, + "mq_send 6 failed: %d", errno); +} + +static void +receive_msgs(mqd_t mqfd) +{ + struct mq_attr mqa; + char *m; + unsigned p; + int len; + + ATF_REQUIRE_MSG(mq_getattr(mqfd, &mqa) != -1, "mq_getattr failed %d", + errno); + + len = mqa.mq_msgsize; + m = calloc(1, len); + ATF_REQUIRE_MSG(m != NULL, "calloc failed"); + + ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, + "mq_receive 1 failed: %d", errno); + ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'b', + "mq_receive 1 prio/data mismatch"); + + ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, + "mq_receive 2 failed: %d", errno); + ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE + 1) && m[0] == 'f', + "mq_receive 2 prio/data mismatch"); + + ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, + "mq_receive 3 failed: %d", errno); + ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'a', + "mq_receive 3 prio/data mismatch"); + + ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, + "mq_receive 4 failed: %d", errno); + ATF_REQUIRE_MSG(p == MQ_PRIO_BASE && m[0] == 'c', + "mq_receive 4 prio/data mismatch"); + + ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, + "mq_receive 5 failed: %d", errno); + ATF_REQUIRE_MSG(p == (MQ_PRIO_BASE - 1) && m[0] == 'd', + "mq_receive 5 prio/data mismatch"); + + ATF_REQUIRE_MSG(mq_receive(mqfd, m, len, &p) != -1, + "mq_receive 6 failed: %d", errno); + ATF_REQUIRE_MSG(p == 0 && m[0] == 'e', + "mq_receive 6 prio/data mismatch"); +} + +ATF_TC(mqueue); +ATF_TC_HEAD(mqueue, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "3"); + atf_tc_set_md_var(tc, "descr", "Checks mqueue send/receive"); +} + +ATF_TC_BODY(mqueue, tc) +{ + int status; + char *tmpdir; + char template[32]; + char mq_name[64]; + +#ifdef __FreeBSD__ + ATF_REQUIRE_KERNEL_MODULE("mqueuefs"); +#endif + + strlcpy(template, "./t_mqueue.XXXXXX", sizeof(template)); + tmpdir = mkdtemp(template); + ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp failed: %d", errno); +#ifdef __FreeBSD__ + snprintf(mq_name, sizeof(mq_name), "/t_mqueue"); +#else + snprintf(mq_name, sizeof(mq_name), "%s/mq", tmpdir); +#endif + + mqd_t mqfd; + + mqfd = mq_open(mq_name, O_RDWR | O_CREAT, + S_IRUSR | S_IRWXG | S_IROTH, NULL); +#ifdef __FreeBSD__ + ATF_REQUIRE_MSG(mqfd != (mqd_t)-1, "mq_open failed: %d", errno); +#else + ATF_REQUIRE_MSG(mqfd != -1, "mq_open failed: %d", errno); +#endif + + send_msgs(mqfd); + receive_msgs(mqfd); + + status = mq_close(mqfd); + ATF_REQUIRE_MSG(status == 0, "mq_close failed: %d", errno); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mqueue); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_ps_strings.sh b/contrib/netbsd-tests/kernel/t_ps_strings.sh new file mode 100755 index 0000000..8adba54 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_ps_strings.sh @@ -0,0 +1,85 @@ +# $NetBSD: t_ps_strings.sh,v 1.1 2011/03/05 18:14:33 pgoyette Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case validate +validate_head() +{ + atf_set "descr" "Validates ps_strings passed to program" +} +validate_body() +{ + atf_check -s exit:0 -o ignore -e ignore \ + $(atf_get_srcdir)/h_ps_strings1 +} + +# Function to parse and validate the output from ps + +parse_ps() { + local pid seq arg + + pid="$1" ; shift + + while [ "$1" != "$pid" ] ; do + echo $1 + shift + done + if [ $# -eq 0 ] ; then + echo "NO_PID" + return + fi + shift + + seq=0 + while [ $# -gt 1 ] ; do + arg=$(printf "arg%04x" $seq) + if [ "$arg" != "$1" ] ; then + echo BAD_$seq + return + fi + shift + done + echo "OK" +} + +atf_test_case update +update_head() +{ + atf_set "descr" "Check updating of ps_strings" +} +update_body() +{ + $(atf_get_srcdir)/h_ps_strings2 > /dev/null 2>&1 & + h_pid=$! + parse=$(parse_ps $h_pid $(ps -wwo pid,args -p $h_pid) ) + kill $h_pid +} + +atf_init_test_cases() +{ + atf_add_test_case validate + atf_add_test_case update +} diff --git a/contrib/netbsd-tests/kernel/t_ptrace.c b/contrib/netbsd-tests/kernel/t_ptrace.c new file mode 100644 index 0000000..dc0bbdb --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_ptrace.c @@ -0,0 +1,208 @@ +/* $NetBSD: t_ptrace.c,v 1.18 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_ptrace.c,v 1.18 2017/01/13 21:30:41 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +/* + * A child process cannot call atf functions and expect them to magically + * work like in the parent. + * The printf(3) messaging from a child will not work out of the box as well + * without estabilishing a communication protocol with its parent. To not + * overcomplicate the tests - do not log from a child and use err(3)/errx(3) + * wrapped with FORKEE_ASSERT()/FORKEE_ASSERTX() as that is guaranteed to work. + */ +#define FORKEE_ASSERTX(x) \ +do { \ + int ret = (x); \ + if (!ret) \ + errx(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: %s", \ + __FILE__, __LINE__, __func__, #x); \ +} while (0) + +#define FORKEE_ASSERT(x) \ +do { \ + int ret = (x); \ + if (!ret) \ + err(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: %s", \ + __FILE__, __LINE__, __func__, #x); \ +} while (0) + +ATF_TC(attach_pid0); +ATF_TC_HEAD(attach_pid0, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Assert that a debugger cannot attach to PID 0"); +} + +ATF_TC_BODY(attach_pid0, tc) +{ + errno = 0; + ATF_REQUIRE_ERRNO(EPERM, ptrace(PT_ATTACH, 0, NULL, 0) == -1); +} + +ATF_TC(attach_pid1); +ATF_TC_HEAD(attach_pid1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Assert that a debugger cannot attach to PID 1 (as non-root)"); + + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(attach_pid1, tc) +{ + ATF_REQUIRE_ERRNO(EPERM, ptrace(PT_ATTACH, 1, NULL, 0) == -1); +} + +ATF_TC(attach_pid1_securelevel); +ATF_TC_HEAD(attach_pid1_securelevel, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Assert that a debugger cannot attach to PID 1 with " + "securelevel >= 1 (as root)"); + + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(attach_pid1_securelevel, tc) +{ + int level; + size_t len = sizeof(level); + + ATF_REQUIRE(sysctlbyname("kern.securelevel", &level, &len, NULL, 0) + != -1); + + if (level < 1) { + atf_tc_skip("Test must be run with securelevel >= 1"); + } + + ATF_REQUIRE_ERRNO(EPERM, ptrace(PT_ATTACH, 1, NULL, 0) == -1); +} + +ATF_TC(attach_self); +ATF_TC_HEAD(attach_self, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Assert that a debugger cannot attach to self (as it's nonsense)"); +} + +ATF_TC_BODY(attach_self, tc) +{ + ATF_REQUIRE_ERRNO(EINVAL, ptrace(PT_ATTACH, getpid(), NULL, 0) == -1); +} + +ATF_TC(attach_chroot); +ATF_TC_HEAD(attach_chroot, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Assert that a debugger cannot trace another process unless the " + "process's root directory is at or below the tracing process's " + "root"); + + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(attach_chroot, tc) +{ + char buf[PATH_MAX]; + pid_t child; + int fds_toparent[2], fds_fromparent[2]; + int rv; + uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ + + (void)memset(buf, '\0', sizeof(buf)); + ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL); + (void)strlcat(buf, "/dir", sizeof(buf)); + + ATF_REQUIRE(mkdir(buf, 0500) == 0); + ATF_REQUIRE(chdir(buf) == 0); + + ATF_REQUIRE(pipe(fds_toparent) == 0); + ATF_REQUIRE(pipe(fds_fromparent) == 0); + child = atf_utils_fork(); + if (child == 0) { + FORKEE_ASSERT(close(fds_toparent[0]) == 0); + FORKEE_ASSERT(close(fds_fromparent[1]) == 0); + + FORKEE_ASSERT(chroot(buf) == 0); + + rv = write(fds_toparent[1], &msg, sizeof(msg)); + FORKEE_ASSERTX(rv == sizeof(msg)); + + ATF_REQUIRE_ERRNO(EPERM, + ptrace(PT_ATTACH, getppid(), NULL, 0) == -1); + + rv = read(fds_fromparent[0], &msg, sizeof(msg)); + FORKEE_ASSERTX(rv == sizeof(msg)); + + _exit(0); + } + ATF_REQUIRE(close(fds_toparent[1]) == 0); + ATF_REQUIRE(close(fds_fromparent[0]) == 0); + + printf("Waiting for chrooting of the child PID %d", child); + rv = read(fds_toparent[0], &msg, sizeof(msg)); + ATF_REQUIRE(rv == sizeof(msg)); + + printf("Child is ready, it will try to PT_ATTACH to parent\n"); + rv = write(fds_fromparent[1], &msg, sizeof(msg)); + ATF_REQUIRE(rv == sizeof(msg)); + + printf("fds_fromparent is no longer needed - close it\n"); + ATF_REQUIRE(close(fds_fromparent[1]) == 0); + + printf("fds_toparent is no longer needed - close it\n"); + ATF_REQUIRE(close(fds_toparent[0]) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + ATF_TP_ADD_TC(tp, attach_pid0); + ATF_TP_ADD_TC(tp, attach_pid1); + ATF_TP_ADD_TC(tp, attach_pid1_securelevel); + ATF_TP_ADD_TC(tp, attach_self); + ATF_TP_ADD_TC(tp, attach_chroot); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_ptrace_wait.c b/contrib/netbsd-tests/kernel/t_ptrace_wait.c new file mode 100644 index 0000000..9d08c0e --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_ptrace_wait.c @@ -0,0 +1,6700 @@ +/* $NetBSD: t_ptrace_wait.c,v 1.69 2017/01/27 16:43:07 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_ptrace_wait.c,v 1.69 2017/01/27 16:43:07 kamil Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +#include "t_ptrace_wait.h" +#include "msg.h" + +#define PARENT_TO_CHILD(info, fds, msg) \ + ATF_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0) + +#define CHILD_FROM_PARENT(info, fds, msg) \ + FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0) + +#define CHILD_TO_PARENT(info, fds, msg) \ + FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0) + +#define PARENT_FROM_CHILD(info, fds, msg) \ + ATF_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0) + + +ATF_TC(traceme1); +ATF_TC_HEAD(traceme1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify SIGSTOP followed by _exit(2) in a child"); +} + +ATF_TC_BODY(traceme1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(traceme2); +ATF_TC_HEAD(traceme2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify SIGSTOP followed by _exit(2) in a child"); +} + +static int traceme2_caught = 0; + +static void +traceme2_sighandler(int sig) +{ + FORKEE_ASSERT_EQ(sig, SIGINT); + + ++traceme2_caught; +} + +ATF_TC_BODY(traceme2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP, sigsent = SIGINT; + pid_t child, wpid; + struct sigaction sa; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + sa.sa_handler = traceme2_sighandler; + sa.sa_flags = SA_SIGINFO; + sigemptyset(&sa.sa_mask); + + FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(traceme2_caught, 1); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before resuming the child process where it left off and with " + "signal %s to be sent\n", strsignal(sigsent)); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the exited child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(traceme3); +ATF_TC_HEAD(traceme3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify SIGSTOP followed by termination by a signal in a child"); +} + +ATF_TC_BODY(traceme3, tc) +{ + const int sigval = SIGSTOP, sigsent = SIGINT /* Without core-dump */; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + /* NOTREACHED */ + FORKEE_ASSERTX(0 && + "Child should be terminated by a signal from its parent"); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before resuming the child process where it left off and with " + "signal %s to be sent\n", strsignal(sigsent)); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_signaled(status, sigsent, 0); + + printf("Before calling %s() for the exited child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(traceme4); +ATF_TC_HEAD(traceme4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify SIGSTOP followed by SIGCONT and _exit(2) in a child"); +} + +ATF_TC_BODY(traceme4, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP, sigsent = SIGCONT; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before raising %s from child\n", strsignal(sigsent)); + FORKEE_ASSERT(raise(sigsent) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(),child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigsent); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the exited child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +#if defined(TWAIT_HAVE_PID) +ATF_TC(attach1); +ATF_TC_HEAD(attach1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Assert that tracer sees process termination before the parent"); +} + +ATF_TC_BODY(attach1, tc) +{ + struct msg_fds parent_tracee, parent_tracer; + const int exitval_tracee = 5; + const int exitval_tracer = 10; + pid_t tracee, tracer, wpid; + uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Spawn tracee\n"); + ATF_REQUIRE(msg_open(&parent_tracee) == 0); + tracee = atf_utils_fork(); + if (tracee == 0) { + // Wait for parent to let us exit + CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); + _exit(exitval_tracee); + } + + printf("Spawn debugger\n"); + ATF_REQUIRE(msg_open(&parent_tracer) == 0); + tracer = atf_utils_fork(); + if (tracer == 0) { + printf("Before calling PT_ATTACH from tracee %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); + + /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + forkee_status_stopped(status, SIGSTOP); + + /* Resume tracee with PT_CONTINUE */ + FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); + + /* Inform parent that tracer has attached to tracee */ + CHILD_TO_PARENT("tracer ready", parent_tracer, msg); + + /* Wait for parent to tell use that tracee should have exited */ + CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); + + /* Wait for tracee and assert that it exited */ + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + forkee_status_exited(status, exitval_tracee); + printf("Tracee %d exited with %d\n", tracee, exitval_tracee); + + printf("Before exiting of the tracer process\n"); + _exit(exitval_tracer); + } + + printf("Wait for the tracer to attach to the tracee\n"); + PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); + + printf("Resume the tracee and let it exit\n"); + PARENT_TO_CHILD("exit tracee", parent_tracee, msg); + + printf("Detect that tracee is zombie\n"); + await_zombie(tracee); + + + printf("Assert that there is no status about tracee %d - " + "Tracer must detect zombie first - calling %s()\n", tracee, + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); + + printf("Tell the tracer child should have exited\n"); + PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); + printf("Wait for tracer to finish its job and exit - calling %s()\n", + TWAIT_FNAME); + + printf("Wait from tracer child to complete waiting for tracee\n"); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), + tracer); + + validate_status_exited(status, exitval_tracer); + + printf("Wait for tracee to finish its job and exit - calling %s()\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), + tracee); + + validate_status_exited(status, exitval_tracee); + + msg_close(&parent_tracer); + msg_close(&parent_tracee); +} +#endif + +#if defined(TWAIT_HAVE_PID) +ATF_TC(attach2); +ATF_TC_HEAD(attach2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Assert that any tracer sees process termination before its " + "parent"); +} + +ATF_TC_BODY(attach2, tc) +{ + struct msg_fds parent_tracer, parent_tracee; + const int exitval_tracee = 5; + const int exitval_tracer1 = 10, exitval_tracer2 = 20; + pid_t tracee, tracer, wpid; + uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Spawn tracee\n"); + ATF_REQUIRE(msg_open(&parent_tracee) == 0); + tracee = atf_utils_fork(); + if (tracee == 0) { + /* Wait for message from the parent */ + CHILD_FROM_PARENT("Message 1", parent_tracee, msg); + _exit(exitval_tracee); + } + + printf("Spawn debugger\n"); + ATF_REQUIRE(msg_open(&parent_tracer) == 0); + tracer = atf_utils_fork(); + if (tracer == 0) { + /* Fork again and drop parent to reattach to PID 1 */ + tracer = atf_utils_fork(); + if (tracer != 0) + _exit(exitval_tracer1); + + printf("Before calling PT_ATTACH from tracee %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); + + /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + forkee_status_stopped(status, SIGSTOP); + + /* Resume tracee with PT_CONTINUE */ + FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); + + /* Inform parent that tracer has attached to tracee */ + CHILD_TO_PARENT("Message 1", parent_tracer, msg); + CHILD_FROM_PARENT("Message 2", parent_tracer, msg); + + /* Wait for tracee and assert that it exited */ + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + forkee_status_exited(status, exitval_tracee); + + printf("Before exiting of the tracer process\n"); + _exit(exitval_tracer2); + } + printf("Wait for the tracer process (direct child) to exit calling " + "%s()\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); + + validate_status_exited(status, exitval_tracer1); + + printf("Wait for the non-exited tracee process with %s()\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); + + printf("Wait for the tracer to attach to the tracee\n"); + PARENT_FROM_CHILD("Message 1", parent_tracer, msg); + printf("Resume the tracee and let it exit\n"); + PARENT_TO_CHILD("Message 1", parent_tracee, msg); + + printf("Detect that tracee is zombie\n"); + await_zombie(tracee); + + printf("Assert that there is no status about tracee - " + "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); + + printf("Resume the tracer and let it detect exited tracee\n"); + PARENT_TO_CHILD("Message 2", parent_tracer, msg); + + printf("Wait for tracee to finish its job and exit - calling %s()\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), + tracee); + + validate_status_exited(status, exitval_tracee); + + msg_close(&parent_tracer); + msg_close(&parent_tracee); + +} +#endif + +ATF_TC(attach3); +ATF_TC_HEAD(attach3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Assert that tracer parent can PT_ATTACH to its child"); +} + +ATF_TC_BODY(attach3, tc) +{ + struct msg_fds parent_tracee; + const int exitval_tracee = 5; + pid_t tracee, wpid; + uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Spawn tracee\n"); + ATF_REQUIRE(msg_open(&parent_tracee) == 0); + tracee = atf_utils_fork(); + if (tracee == 0) { + CHILD_FROM_PARENT("Message 1", parent_tracee, msg); + printf("Parent should now attach to tracee\n"); + + CHILD_FROM_PARENT("Message 2", parent_tracee, msg); + /* Wait for message from the parent */ + _exit(exitval_tracee); + } + PARENT_TO_CHILD("Message 1", parent_tracee, msg); + + printf("Before calling PT_ATTACH for tracee %d\n", tracee); + ATF_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); + + printf("Wait for the stopped tracee process with %s()\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + validate_status_stopped(status, SIGSTOP); + + printf("Resume tracee with PT_CONTINUE\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); + + printf("Let the tracee exit now\n"); + PARENT_TO_CHILD("Message 2", parent_tracee, msg); + + printf("Wait for tracee to exit with %s()\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + validate_status_exited(status, exitval_tracee); + + printf("Before calling %s() for tracee\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, + wpid = TWAIT_GENERIC(tracee, &status, 0)); + + msg_close(&parent_tracee); +} + +ATF_TC(attach4); +ATF_TC_HEAD(attach4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Assert that tracer child can PT_ATTACH to its parent"); +} + +ATF_TC_BODY(attach4, tc) +{ + struct msg_fds parent_tracee; + const int exitval_tracer = 5; + pid_t tracer, wpid; + uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Spawn tracer\n"); + ATF_REQUIRE(msg_open(&parent_tracee) == 0); + tracer = atf_utils_fork(); + if (tracer == 0) { + + /* Wait for message from the parent */ + CHILD_FROM_PARENT("Message 1", parent_tracee, msg); + + printf("Attach to parent PID %d with PT_ATTACH from child\n", + getppid()); + FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); + + printf("Wait for the stopped parent process with %s()\n", + TWAIT_FNAME); + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); + + forkee_status_stopped(status, SIGSTOP); + + printf("Resume parent with PT_DETACH\n"); + FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) + != -1); + + /* Tell parent we are ready */ + CHILD_TO_PARENT("Message 1", parent_tracee, msg); + + _exit(exitval_tracer); + } + + printf("Wait for the tracer to become ready\n"); + PARENT_TO_CHILD("Message 1", parent_tracee, msg); + printf("Allow the tracer to exit now\n"); + PARENT_FROM_CHILD("Message 1", parent_tracee, msg); + + printf("Wait for tracer to exit with %s()\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); + + validate_status_exited(status, exitval_tracer); + + printf("Before calling %s() for tracer\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, + wpid = TWAIT_GENERIC(tracer, &status, 0)); + + msg_close(&parent_tracee); +} + +#if defined(TWAIT_HAVE_PID) +ATF_TC(attach5); +ATF_TC_HEAD(attach5, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Assert that tracer sees its parent when attached to tracer " + "(check getppid(2))"); +} + +ATF_TC_BODY(attach5, tc) +{ + struct msg_fds parent_tracer, parent_tracee; + const int exitval_tracee = 5; + const int exitval_tracer = 10; + pid_t parent, tracee, tracer, wpid; + uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Spawn tracee\n"); + ATF_REQUIRE(msg_open(&parent_tracer) == 0); + ATF_REQUIRE(msg_open(&parent_tracee) == 0); + tracee = atf_utils_fork(); + if (tracee == 0) { + parent = getppid(); + + /* Emit message to the parent */ + CHILD_TO_PARENT("tracee ready", parent_tracee, msg); + CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); + + FORKEE_ASSERT_EQ(parent, getppid()); + + _exit(exitval_tracee); + } + printf("Wait for child to record its parent identifier (pid)\n"); + PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); + + printf("Spawn debugger\n"); + tracer = atf_utils_fork(); + if (tracer == 0) { + /* No IPC to communicate with the child */ + printf("Before calling PT_ATTACH from tracee %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); + + /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + forkee_status_stopped(status, SIGSTOP); + + /* Resume tracee with PT_CONTINUE */ + FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); + + /* Inform parent that tracer has attached to tracee */ + CHILD_TO_PARENT("tracer ready", parent_tracer, msg); + + /* Wait for parent to tell use that tracee should have exited */ + CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); + + /* Wait for tracee and assert that it exited */ + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + forkee_status_exited(status, exitval_tracee); + + printf("Before exiting of the tracer process\n"); + _exit(exitval_tracer); + } + + printf("Wait for the tracer to attach to the tracee\n"); + PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); + + printf("Resume the tracee and let it exit\n"); + PARENT_TO_CHILD("exit tracee", parent_tracee, msg); + + printf("Detect that tracee is zombie\n"); + await_zombie(tracee); + + printf("Assert that there is no status about tracee - " + "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); + + printf("Tell the tracer child should have exited\n"); + PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); + + printf("Wait from tracer child to complete waiting for tracee\n"); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), + tracer); + + validate_status_exited(status, exitval_tracer); + + printf("Wait for tracee to finish its job and exit - calling %s()\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), + tracee); + + validate_status_exited(status, exitval_tracee); + + msg_close(&parent_tracer); + msg_close(&parent_tracee); +} +#endif + +#if defined(TWAIT_HAVE_PID) +ATF_TC(attach6); +ATF_TC_HEAD(attach6, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Assert that tracer sees its parent when attached to tracer " + "(check sysctl(7) and struct kinfo_proc2)"); +} + +ATF_TC_BODY(attach6, tc) +{ + struct msg_fds parent_tracee, parent_tracer; + const int exitval_tracee = 5; + const int exitval_tracer = 10; + pid_t parent, tracee, tracer, wpid; + uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + int name[CTL_MAXNAME]; + struct kinfo_proc2 kp; + size_t len = sizeof(kp); + unsigned int namelen; + + printf("Spawn tracee\n"); + ATF_REQUIRE(msg_open(&parent_tracee) == 0); + ATF_REQUIRE(msg_open(&parent_tracer) == 0); + tracee = atf_utils_fork(); + if (tracee == 0) { + parent = getppid(); + + /* Emit message to the parent */ + CHILD_TO_PARENT("Message 1", parent_tracee, msg); + CHILD_FROM_PARENT("Message 2", parent_tracee, msg); + + namelen = 0; + name[namelen++] = CTL_KERN; + name[namelen++] = KERN_PROC2; + name[namelen++] = KERN_PROC_PID; + name[namelen++] = getpid(); + name[namelen++] = len; + name[namelen++] = 1; + + FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0); + FORKEE_ASSERT_EQ(parent, kp.p_ppid); + + _exit(exitval_tracee); + } + + printf("Wait for child to record its parent identifier (pid)\n"); + PARENT_FROM_CHILD("Message 1", parent_tracee, msg); + + printf("Spawn debugger\n"); + tracer = atf_utils_fork(); + if (tracer == 0) { + /* No IPC to communicate with the child */ + printf("Before calling PT_ATTACH from tracee %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); + + /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + forkee_status_stopped(status, SIGSTOP); + + /* Resume tracee with PT_CONTINUE */ + FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); + + /* Inform parent that tracer has attached to tracee */ + CHILD_TO_PARENT("Message 1", parent_tracer, msg); + + CHILD_FROM_PARENT("Message 2", parent_tracer, msg); + + /* Wait for tracee and assert that it exited */ + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + forkee_status_exited(status, exitval_tracee); + + printf("Before exiting of the tracer process\n"); + _exit(exitval_tracer); + } + + printf("Wait for the tracer to attach to the tracee\n"); + PARENT_FROM_CHILD("Message 1", parent_tracer, msg); + + printf("Resume the tracee and let it exit\n"); + PARENT_TO_CHILD("Message 1", parent_tracee, msg); + + printf("Detect that tracee is zombie\n"); + await_zombie(tracee); + + printf("Assert that there is no status about tracee - " + "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); + + printf("Resume the tracer and let it detect exited tracee\n"); + PARENT_TO_CHILD("Message 2", parent_tracer, msg); + + printf("Wait for tracer to finish its job and exit - calling %s()\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), + tracer); + + validate_status_exited(status, exitval_tracer); + + printf("Wait for tracee to finish its job and exit - calling %s()\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), + tracee); + + validate_status_exited(status, exitval_tracee); + + msg_close(&parent_tracee); + msg_close(&parent_tracer); +} +#endif + +#if defined(TWAIT_HAVE_PID) +ATF_TC(attach7); +ATF_TC_HEAD(attach7, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Assert that tracer sees its parent when attached to tracer " + "(check /proc/curproc/status 3rd column)"); +} + +ATF_TC_BODY(attach7, tc) +{ + struct msg_fds parent_tracee, parent_tracer; + int rv; + const int exitval_tracee = 5; + const int exitval_tracer = 10; + pid_t parent, tracee, tracer, wpid; + uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + FILE *fp; + struct stat st; + const char *fname = "/proc/curproc/status"; + char s_executable[MAXPATHLEN]; + int s_pid, s_ppid; + /* + * Format: + * EXECUTABLE PID PPID ... + */ + + ATF_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT)); + if (rv != 0) { + atf_tc_skip("/proc/curproc/status not found"); + } + + printf("Spawn tracee\n"); + ATF_REQUIRE(msg_open(&parent_tracee) == 0); + ATF_REQUIRE(msg_open(&parent_tracer) == 0); + tracee = atf_utils_fork(); + if (tracee == 0) { + parent = getppid(); + + // Wait for parent to let us exit + CHILD_TO_PARENT("tracee ready", parent_tracee, msg); + CHILD_FROM_PARENT("tracee exit", parent_tracee, msg); + + FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); + fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); + FORKEE_ASSERT(fclose(fp) == 0); + FORKEE_ASSERT_EQ(parent, s_ppid); + + _exit(exitval_tracee); + } + + printf("Wait for child to record its parent identifier (pid)\n"); + PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); + + printf("Spawn debugger\n"); + tracer = atf_utils_fork(); + if (tracer == 0) { + printf("Before calling PT_ATTACH from tracee %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); + + /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + forkee_status_stopped(status, SIGSTOP); + + /* Resume tracee with PT_CONTINUE */ + FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); + + /* Inform parent that tracer has attached to tracee */ + CHILD_TO_PARENT("tracer ready", parent_tracer, msg); + + /* Wait for parent to tell use that tracee should have exited */ + CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); + + /* Wait for tracee and assert that it exited */ + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + forkee_status_exited(status, exitval_tracee); + + printf("Before exiting of the tracer process\n"); + _exit(exitval_tracer); + } + printf("Wait for the tracer to attach to the tracee\n"); + PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); + printf("Resume the tracee and let it exit\n"); + PARENT_TO_CHILD("tracee exit", parent_tracee, msg); + + printf("Detect that tracee is zombie\n"); + await_zombie(tracee); + + printf("Assert that there is no status about tracee - " + "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); + + printf("Resume the tracer and let it detect exited tracee\n"); + PARENT_TO_CHILD("Message 2", parent_tracer, msg); + + printf("Wait for tracer to finish its job and exit - calling %s()\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), + tracer); + + validate_status_exited(status, exitval_tracer); + + printf("Wait for tracee to finish its job and exit - calling %s()\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), + tracee); + + validate_status_exited(status, exitval_tracee); + + msg_close(&parent_tracee); + msg_close(&parent_tracer); +} +#endif + +ATF_TC(eventmask1); +ATF_TC_HEAD(eventmask1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that empty EVENT_MASK is preserved"); +} + +ATF_TC_BODY(eventmask1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_event_t set_event, get_event; + const int len = sizeof(ptrace_event_t); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + set_event.pe_set_event = 0; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); + ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); + ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(eventmask2); +ATF_TC_HEAD(eventmask2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that PTRACE_FORK in EVENT_MASK is preserved"); +} + +ATF_TC_BODY(eventmask2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_event_t set_event, get_event; + const int len = sizeof(ptrace_event_t); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + set_event.pe_set_event = PTRACE_FORK; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); + ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); + ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(eventmask3); +ATF_TC_HEAD(eventmask3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that PTRACE_VFORK in EVENT_MASK is preserved"); +} + +ATF_TC_BODY(eventmask3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_event_t set_event, get_event; + const int len = sizeof(ptrace_event_t); + + atf_tc_expect_fail("PR kern/51630"); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + set_event.pe_set_event = PTRACE_VFORK; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); + ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); + ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(eventmask4); +ATF_TC_HEAD(eventmask4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved"); +} + +ATF_TC_BODY(eventmask4, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_event_t set_event, get_event; + const int len = sizeof(ptrace_event_t); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + set_event.pe_set_event = PTRACE_VFORK_DONE; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); + ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); + ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(eventmask5); +ATF_TC_HEAD(eventmask5, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that PTRACE_LWP_CREATE in EVENT_MASK is preserved"); +} + +ATF_TC_BODY(eventmask5, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_event_t set_event, get_event; + const int len = sizeof(ptrace_event_t); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + set_event.pe_set_event = PTRACE_LWP_CREATE; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); + ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); + ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(eventmask6); +ATF_TC_HEAD(eventmask6, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that PTRACE_LWP_EXIT in EVENT_MASK is preserved"); +} + +ATF_TC_BODY(eventmask6, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_event_t set_event, get_event; + const int len = sizeof(ptrace_event_t); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + set_event.pe_set_event = PTRACE_LWP_EXIT; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); + ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); + ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +#if defined(TWAIT_HAVE_PID) +ATF_TC(fork1); +ATF_TC_HEAD(fork1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK " + "set to PTRACE_FORK"); +} + +ATF_TC_BODY(fork1, tc) +{ + const int exitval = 5; + const int exitval2 = 15; + const int sigval = SIGSTOP; + pid_t child, child2, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_state_t state; + const int slen = sizeof(state); + ptrace_event_t event; + const int elen = sizeof(event); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT((child2 = fork()) != 1); + + if (child2 == 0) + _exit(exitval2); + + FORKEE_REQUIRE_SUCCESS + (wpid = TWAIT_GENERIC(child2, &status, 0), child2); + + forkee_status_exited(status, exitval2); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); + event.pe_set_event = PTRACE_FORK; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); + + child2 = state.pe_other_pid; + printf("Reported PTRACE_FORK event with forkee %d\n", child2); + + printf("Before calling %s() for the forkee %d of the child %d\n", + TWAIT_FNAME, child2, child); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), + child2); + + validate_status_stopped(status, SIGTRAP); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); + ATF_REQUIRE_EQ(state.pe_other_pid, child); + + printf("Before resuming the forkee process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the forkee - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), + child2); + + validate_status_exited(status, exitval2); + + printf("Before calling %s() for the forkee - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, + wpid = TWAIT_GENERIC(child2, &status, 0)); + + printf("Before calling %s() for the child - expected stopped " + "SIGCHLD\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGCHLD); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +ATF_TC(fork2); +ATF_TC_HEAD(fork2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that fork(2) is not intercepted by ptrace(2) with empty " + "EVENT_MASK"); +} + +ATF_TC_BODY(fork2, tc) +{ + const int exitval = 5; + const int exitval2 = 15; + const int sigval = SIGSTOP; + pid_t child, child2, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_event_t event; + const int elen = sizeof(event); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT((child2 = fork()) != 1); + + if (child2 == 0) + _exit(exitval2); + + FORKEE_REQUIRE_SUCCESS + (wpid = TWAIT_GENERIC(child2, &status, 0), child2); + + forkee_status_exited(status, exitval2); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Set empty EVENT_MASK for the child %d\n", child); + event.pe_set_event = 0; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected stopped " + "SIGCHLD\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGCHLD); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +#if defined(TWAIT_HAVE_PID) +ATF_TC(vfork1); +ATF_TC_HEAD(vfork1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK " + "set to PTRACE_VFORK"); +} + +ATF_TC_BODY(vfork1, tc) +{ + const int exitval = 5; + const int exitval2 = 15; + const int sigval = SIGSTOP; + pid_t child, child2, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_state_t state; + const int slen = sizeof(state); + ptrace_event_t event; + const int elen = sizeof(event); + + atf_tc_expect_fail("PR kern/51630"); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT((child2 = vfork()) != 1); + + if (child2 == 0) + _exit(exitval2); + + FORKEE_REQUIRE_SUCCESS + (wpid = TWAIT_GENERIC(child2, &status, 0), child2); + + forkee_status_exited(status, exitval2); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); + event.pe_set_event = PTRACE_VFORK; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); + + child2 = state.pe_other_pid; + printf("Reported PTRACE_VFORK event with forkee %d\n", child2); + + printf("Before calling %s() for the forkee %d of the child %d\n", + TWAIT_FNAME, child2, child); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), + child2); + + validate_status_stopped(status, SIGTRAP); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); + ATF_REQUIRE_EQ(state.pe_other_pid, child); + + printf("Before resuming the forkee process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the forkee - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), + child2); + + validate_status_exited(status, exitval2); + + printf("Before calling %s() for the forkee - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, + wpid = TWAIT_GENERIC(child2, &status, 0)); + + printf("Before calling %s() for the child - expected stopped " + "SIGCHLD\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGCHLD); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +ATF_TC(vfork2); +ATF_TC_HEAD(vfork2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that vfork(2) is not intercepted by ptrace(2) with empty " + "EVENT_MASK"); +} + +ATF_TC_BODY(vfork2, tc) +{ + const int exitval = 5; + const int exitval2 = 15; + const int sigval = SIGSTOP; + pid_t child, child2, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_event_t event; + const int elen = sizeof(event); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT((child2 = vfork()) != 1); + + if (child2 == 0) + _exit(exitval2); + + FORKEE_REQUIRE_SUCCESS + (wpid = TWAIT_GENERIC(child2, &status, 0), child2); + + forkee_status_exited(status, exitval2); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Set empty EVENT_MASK for the child %d\n", child); + event.pe_set_event = 0; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected stopped " + "SIGCHLD\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGCHLD); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(vforkdone1); +ATF_TC_HEAD(vforkdone1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK " + "set to PTRACE_VFORK_DONE"); +} + +ATF_TC_BODY(vforkdone1, tc) +{ + const int exitval = 5; + const int exitval2 = 15; + const int sigval = SIGSTOP; + pid_t child, child2, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_state_t state; + const int slen = sizeof(state); + ptrace_event_t event; + const int elen = sizeof(event); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT((child2 = vfork()) != 1); + + if (child2 == 0) + _exit(exitval2); + + FORKEE_REQUIRE_SUCCESS + (wpid = TWAIT_GENERIC(child2, &status, 0), child2); + + forkee_status_exited(status, exitval2); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n", + child); + event.pe_set_event = PTRACE_VFORK_DONE; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); + + child2 = state.pe_other_pid; + printf("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected stopped " + "SIGCHLD\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGCHLD); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(vforkdone2); +ATF_TC_HEAD(vforkdone2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK " + "set to PTRACE_FORK | PTRACE_VFORK_DONE"); +} + +ATF_TC_BODY(vforkdone2, tc) +{ + const int exitval = 5; + const int exitval2 = 15; + const int sigval = SIGSTOP; + pid_t child, child2, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_state_t state; + const int slen = sizeof(state); + ptrace_event_t event; + const int elen = sizeof(event); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT((child2 = vfork()) != 1); + + if (child2 == 0) + _exit(exitval2); + + FORKEE_REQUIRE_SUCCESS + (wpid = TWAIT_GENERIC(child2, &status, 0), child2); + + forkee_status_exited(status, exitval2); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); + event.pe_set_event = PTRACE_FORK | PTRACE_VFORK_DONE; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); + + child2 = state.pe_other_pid; + printf("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected stopped " + "SIGCHLD\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGCHLD); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_read_d1); +ATF_TC_HEAD(io_read_d1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)"); +} + +ATF_TC_BODY(io_read_d1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint8_t lookup_me = 0; + const uint8_t magic = 0xab; + struct ptrace_io_desc io = { + .piod_op = PIOD_READ_D, + .piod_offs = &lookup_me, + .piod_addr = &lookup_me, + .piod_len = sizeof(lookup_me) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + lookup_me = magic; + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + ATF_REQUIRE_EQ_MSG(lookup_me, magic, + "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_read_d2); +ATF_TC_HEAD(io_read_d2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)"); +} + +ATF_TC_BODY(io_read_d2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint16_t lookup_me = 0; + const uint16_t magic = 0x1234; + struct ptrace_io_desc io = { + .piod_op = PIOD_READ_D, + .piod_offs = &lookup_me, + .piod_addr = &lookup_me, + .piod_len = sizeof(lookup_me) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + lookup_me = magic; + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + ATF_REQUIRE_EQ_MSG(lookup_me, magic, + "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_read_d3); +ATF_TC_HEAD(io_read_d3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)"); +} + +ATF_TC_BODY(io_read_d3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint32_t lookup_me = 0; + const uint32_t magic = 0x1234abcd; + struct ptrace_io_desc io = { + .piod_op = PIOD_READ_D, + .piod_offs = &lookup_me, + .piod_addr = &lookup_me, + .piod_len = sizeof(lookup_me) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + lookup_me = magic; + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + ATF_REQUIRE_EQ_MSG(lookup_me, magic, + "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_read_d4); +ATF_TC_HEAD(io_read_d4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)"); +} + +ATF_TC_BODY(io_read_d4, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint64_t lookup_me = 0; + const uint64_t magic = 0x1234abcd9876dcfa; + struct ptrace_io_desc io = { + .piod_op = PIOD_READ_D, + .piod_offs = &lookup_me, + .piod_addr = &lookup_me, + .piod_len = sizeof(lookup_me) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + lookup_me = magic; + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + ATF_REQUIRE_EQ_MSG(lookup_me, magic, + "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_write_d1); +ATF_TC_HEAD(io_write_d1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)"); +} + +ATF_TC_BODY(io_write_d1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint8_t lookup_me = 0; + const uint8_t magic = 0xab; + struct ptrace_io_desc io = { + .piod_op = PIOD_WRITE_D, + .piod_offs = &lookup_me, + .piod_addr = &lookup_me, + .piod_len = sizeof(lookup_me) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(lookup_me, magic); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + lookup_me = magic; + + printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_write_d2); +ATF_TC_HEAD(io_write_d2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)"); +} + +ATF_TC_BODY(io_write_d2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint16_t lookup_me = 0; + const uint16_t magic = 0xab12; + struct ptrace_io_desc io = { + .piod_op = PIOD_WRITE_D, + .piod_offs = &lookup_me, + .piod_addr = &lookup_me, + .piod_len = sizeof(lookup_me) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(lookup_me, magic); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + lookup_me = magic; + + printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_write_d3); +ATF_TC_HEAD(io_write_d3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)"); +} + +ATF_TC_BODY(io_write_d3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint32_t lookup_me = 0; + const uint32_t magic = 0xab127643; + struct ptrace_io_desc io = { + .piod_op = PIOD_WRITE_D, + .piod_offs = &lookup_me, + .piod_addr = &lookup_me, + .piod_len = sizeof(lookup_me) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(lookup_me, magic); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + lookup_me = magic; + + printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_write_d4); +ATF_TC_HEAD(io_write_d4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)"); +} + +ATF_TC_BODY(io_write_d4, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint64_t lookup_me = 0; + const uint64_t magic = 0xab12764376490123; + struct ptrace_io_desc io = { + .piod_op = PIOD_WRITE_D, + .piod_offs = &lookup_me, + .piod_addr = &lookup_me, + .piod_len = sizeof(lookup_me) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(lookup_me, magic); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + lookup_me = magic; + + printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_read_auxv1); +ATF_TC_HEAD(io_read_auxv1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_READ_AUXV called for tracee"); +} + +ATF_TC_BODY(io_read_auxv1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + AuxInfo ai[100], *aip; + struct ptrace_io_desc io = { + .piod_op = PIOD_READ_AUXV, + .piod_offs = 0, + .piod_addr = ai, + .piod_len = sizeof(ai) + }; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + printf("Asserting that AUXV length (%zu) is > 0\n", io.piod_len); + ATF_REQUIRE(io.piod_len > 0); + + for (aip = ai; aip->a_type != AT_NULL; aip++) + printf("a_type=%#llx a_v=%#llx\n", + (long long int)aip->a_type, (long long int)aip->a_v); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(read_d1); +ATF_TC_HEAD(read_d1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_READ_D called once"); +} + +ATF_TC_BODY(read_d1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me = 0; + const int magic = (int)random(); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + lookup_me = magic; + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me, magic, + "got value %#x != expected %#x", lookup_me, magic); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(read_d2); +ATF_TC_HEAD(read_d2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_READ_D called twice"); +} + +ATF_TC_BODY(read_d2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me1 = 0; + int lookup_me2 = 0; + const int magic1 = (int)random(); + const int magic2 = (int)random(); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + lookup_me1 = magic1; + lookup_me2 = magic2; + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, + "got value %#x != expected %#x", lookup_me1, magic1); + + printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, + "got value %#x != expected %#x", lookup_me2, magic2); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(read_d3); +ATF_TC_HEAD(read_d3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_READ_D called three times"); +} + +ATF_TC_BODY(read_d3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me1 = 0; + int lookup_me2 = 0; + int lookup_me3 = 0; + const int magic1 = (int)random(); + const int magic2 = (int)random(); + const int magic3 = (int)random(); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + lookup_me1 = magic1; + lookup_me2 = magic2; + lookup_me3 = magic3; + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, + "got value %#x != expected %#x", lookup_me1, magic1); + + printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, + "got value %#x != expected %#x", lookup_me2, magic2); + + printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me3, magic3, + "got value %#x != expected %#x", lookup_me3, magic3); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(read_d4); +ATF_TC_HEAD(read_d4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_READ_D called four times"); +} + +ATF_TC_BODY(read_d4, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me1 = 0; + int lookup_me2 = 0; + int lookup_me3 = 0; + int lookup_me4 = 0; + const int magic1 = (int)random(); + const int magic2 = (int)random(); + const int magic3 = (int)random(); + const int magic4 = (int)random(); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + lookup_me1 = magic1; + lookup_me2 = magic2; + lookup_me3 = magic3; + lookup_me4 = magic4; + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, + "got value %#x != expected %#x", lookup_me1, magic1); + + printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, + "got value %#x != expected %#x", lookup_me2, magic2); + + printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me3, magic3, + "got value %#x != expected %#x", lookup_me3, magic3); + + printf("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me4, magic4, + "got value %#x != expected %#x", lookup_me4, magic4); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(write_d1); +ATF_TC_HEAD(write_d1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_WRITE_D called once"); +} + +ATF_TC_BODY(write_d1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me = 0; + const int magic = (int)random(); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(lookup_me, magic); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(write_d2); +ATF_TC_HEAD(write_d2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_WRITE_D called twice"); +} + +ATF_TC_BODY(write_d2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me1 = 0; + int lookup_me2 = 0; + const int magic1 = (int)random(); + const int magic2 = (int)random(); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(lookup_me1, magic1); + FORKEE_ASSERT_EQ(lookup_me2, magic2); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1); + + printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(write_d3); +ATF_TC_HEAD(write_d3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_WRITE_D called three times"); +} + +ATF_TC_BODY(write_d3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me1 = 0; + int lookup_me2 = 0; + int lookup_me3 = 0; + const int magic1 = (int)random(); + const int magic2 = (int)random(); + const int magic3 = (int)random(); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(lookup_me1, magic1); + FORKEE_ASSERT_EQ(lookup_me2, magic2); + FORKEE_ASSERT_EQ(lookup_me3, magic3); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1); + + printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1); + + printf("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(write_d4); +ATF_TC_HEAD(write_d4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_WRITE_D called four times"); +} + +ATF_TC_BODY(write_d4, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me1 = 0; + int lookup_me2 = 0; + int lookup_me3 = 0; + int lookup_me4 = 0; + const int magic1 = (int)random(); + const int magic2 = (int)random(); + const int magic3 = (int)random(); + const int magic4 = (int)random(); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(lookup_me1, magic1); + FORKEE_ASSERT_EQ(lookup_me2, magic2); + FORKEE_ASSERT_EQ(lookup_me3, magic3); + FORKEE_ASSERT_EQ(lookup_me4, magic4); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1); + + printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1); + + printf("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1); + + printf("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_read_d_write_d_handshake1); +ATF_TC_HEAD(io_read_d_write_d_handshake1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake"); +} + +ATF_TC_BODY(io_read_d_write_d_handshake1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint8_t lookup_me_fromtracee = 0; + const uint8_t magic_fromtracee = (uint8_t)random(); + uint8_t lookup_me_totracee = 0; + const uint8_t magic_totracee = (uint8_t)random(); + struct ptrace_io_desc io_fromtracee = { + .piod_op = PIOD_READ_D, + .piod_offs = &lookup_me_fromtracee, + .piod_addr = &lookup_me_fromtracee, + .piod_len = sizeof(lookup_me_fromtracee) + }; + struct ptrace_io_desc io_totracee = { + .piod_op = PIOD_WRITE_D, + .piod_offs = &lookup_me_totracee, + .piod_addr = &lookup_me_totracee, + .piod_len = sizeof(lookup_me_totracee) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + lookup_me_fromtracee = magic_fromtracee; + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1); + + ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, + "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee, + magic_fromtracee); + + lookup_me_totracee = magic_totracee; + + printf("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1); + + ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee, + "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee, + magic_totracee); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_read_d_write_d_handshake2); +ATF_TC_HEAD(io_read_d_write_d_handshake2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake"); +} + +ATF_TC_BODY(io_read_d_write_d_handshake2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint8_t lookup_me_fromtracee = 0; + const uint8_t magic_fromtracee = (uint8_t)random(); + uint8_t lookup_me_totracee = 0; + const uint8_t magic_totracee = (uint8_t)random(); + struct ptrace_io_desc io_fromtracee = { + .piod_op = PIOD_READ_D, + .piod_offs = &lookup_me_fromtracee, + .piod_addr = &lookup_me_fromtracee, + .piod_len = sizeof(lookup_me_fromtracee) + }; + struct ptrace_io_desc io_totracee = { + .piod_op = PIOD_WRITE_D, + .piod_offs = &lookup_me_totracee, + .piod_addr = &lookup_me_totracee, + .piod_len = sizeof(lookup_me_totracee) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + lookup_me_fromtracee = magic_fromtracee; + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + lookup_me_totracee = magic_totracee; + + printf("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1); + + ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee, + "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee, + magic_totracee); + + printf("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1); + + ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, + "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee, + magic_fromtracee); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(read_d_write_d_handshake1); +ATF_TC_HEAD(read_d_write_d_handshake1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_READ_D with PT_WRITE_D handshake"); +} + +ATF_TC_BODY(read_d_write_d_handshake1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me_fromtracee = 0; + const int magic_fromtracee = (int)random(); + int lookup_me_totracee = 0; + const int magic_totracee = (int)random(); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + lookup_me_fromtracee = magic_fromtracee; + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me_fromtracee = + ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, + "got value %#x != expected %#x", lookup_me_fromtracee, + magic_fromtracee); + + printf("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE + (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee) + != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(read_d_write_d_handshake2); +ATF_TC_HEAD(read_d_write_d_handshake2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_WRITE_D with PT_READ_D handshake"); +} + +ATF_TC_BODY(read_d_write_d_handshake2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me_fromtracee = 0; + const int magic_fromtracee = (int)random(); + int lookup_me_totracee = 0; + const int magic_totracee = (int)random(); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + lookup_me_fromtracee = magic_fromtracee; + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE + (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee) + != -1); + + printf("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me_fromtracee = + ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, + "got value %#x != expected %#x", lookup_me_fromtracee, + magic_fromtracee); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +/* These dummy functions are used to be copied with ptrace(2) calls */ +static int __used +dummy_fn1(int a, int b, int c, int d) +{ + + a *= 1; + b += 2; + c -= 3; + d /= 4; + + return a + b * c - d; +} + +static int __used +dummy_fn2(int a, int b, int c, int d) +{ + + a *= 4; + b += 3; + c -= 2; + d /= 1; + + return a + b * c - d; +} + +static int __used +dummy_fn3(int a, int b, int c, int d) +{ + + a *= 10; + b += 20; + c -= 30; + d /= 40; + + return a + b * c - d; +} + +static int __used +dummy_fn4(int a, int b, int c, int d) +{ + + a *= 40; + b += 30; + c -= 20; + d /= 10; + + return a + b * c - d; +} + +ATF_TC(io_read_i1); +ATF_TC_HEAD(io_read_i1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)"); +} + +ATF_TC_BODY(io_read_i1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint8_t lookup_me = 0; + uint8_t magic; + memcpy(&magic, dummy_fn1, sizeof(magic)); + struct ptrace_io_desc io = { + .piod_op = PIOD_READ_I, + .piod_offs = dummy_fn1, + .piod_addr = &lookup_me, + .piod_len = sizeof(lookup_me) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + ATF_REQUIRE_EQ_MSG(lookup_me, magic, + "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_read_i2); +ATF_TC_HEAD(io_read_i2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_READ_I and len = sizeof(uint16_t)"); +} + +ATF_TC_BODY(io_read_i2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint16_t lookup_me = 0; + uint16_t magic; + memcpy(&magic, dummy_fn1, sizeof(magic)); + struct ptrace_io_desc io = { + .piod_op = PIOD_READ_I, + .piod_offs = dummy_fn1, + .piod_addr = &lookup_me, + .piod_len = sizeof(lookup_me) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + ATF_REQUIRE_EQ_MSG(lookup_me, magic, + "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_read_i3); +ATF_TC_HEAD(io_read_i3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_READ_I and len = sizeof(uint32_t)"); +} + +ATF_TC_BODY(io_read_i3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint32_t lookup_me = 0; + uint32_t magic; + memcpy(&magic, dummy_fn1, sizeof(magic)); + struct ptrace_io_desc io = { + .piod_op = PIOD_READ_I, + .piod_offs = dummy_fn1, + .piod_addr = &lookup_me, + .piod_len = sizeof(lookup_me) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + ATF_REQUIRE_EQ_MSG(lookup_me, magic, + "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(io_read_i4); +ATF_TC_HEAD(io_read_i4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_IO with PIOD_READ_I and len = sizeof(uint64_t)"); +} + +ATF_TC_BODY(io_read_i4, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + uint64_t lookup_me = 0; + uint64_t magic; + memcpy(&magic, dummy_fn1, sizeof(magic)); + struct ptrace_io_desc io = { + .piod_op = PIOD_READ_I, + .piod_offs = dummy_fn1, + .piod_addr = &lookup_me, + .piod_len = sizeof(lookup_me) + }; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); + + ATF_REQUIRE_EQ_MSG(lookup_me, magic, + "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(read_i1); +ATF_TC_HEAD(read_i1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_READ_I called once"); +} + +ATF_TC_BODY(read_i1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me = 0; + int magic; + memcpy(&magic, dummy_fn1, sizeof(magic)); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me = ptrace(PT_READ_I, child, dummy_fn1, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me, magic, + "got value %#x != expected %#x", lookup_me, magic); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(read_i2); +ATF_TC_HEAD(read_i2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_READ_I called twice"); +} + +ATF_TC_BODY(read_i2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me1 = 0; + int lookup_me2 = 0; + int magic1; + int magic2; + memcpy(&magic1, dummy_fn1, sizeof(magic1)); + memcpy(&magic2, dummy_fn2, sizeof(magic2)); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, + "got value %#x != expected %#x", lookup_me1, magic1); + + printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, + "got value %#x != expected %#x", lookup_me2, magic2); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(read_i3); +ATF_TC_HEAD(read_i3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_READ_I called three times"); +} + +ATF_TC_BODY(read_i3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me1 = 0; + int lookup_me2 = 0; + int lookup_me3 = 0; + int magic1; + int magic2; + int magic3; + memcpy(&magic1, dummy_fn1, sizeof(magic1)); + memcpy(&magic2, dummy_fn2, sizeof(magic2)); + memcpy(&magic3, dummy_fn3, sizeof(magic3)); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, + "got value %#x != expected %#x", lookup_me1, magic1); + + printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, + "got value %#x != expected %#x", lookup_me2, magic2); + + printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me3, magic3, + "got value %#x != expected %#x", lookup_me3, magic3); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(read_i4); +ATF_TC_HEAD(read_i4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_READ_I called four times"); +} + +ATF_TC_BODY(read_i4, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; + int lookup_me1 = 0; + int lookup_me2 = 0; + int lookup_me3 = 0; + int lookup_me4 = 0; + int magic1; + int magic2; + int magic3; + int magic4; + memcpy(&magic1, dummy_fn1, sizeof(magic1)); + memcpy(&magic2, dummy_fn2, sizeof(magic2)); + memcpy(&magic3, dummy_fn3, sizeof(magic3)); + memcpy(&magic4, dummy_fn4, sizeof(magic4)); +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me1 = ptrace(PT_READ_I, child, dummy_fn1, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, + "got value %#x != expected %#x", lookup_me1, magic1); + + printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me2 = ptrace(PT_READ_I, child, dummy_fn2, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, + "got value %#x != expected %#x", lookup_me2, magic2); + + printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me3 = ptrace(PT_READ_I, child, dummy_fn3, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me3, magic3, + "got value %#x != expected %#x", lookup_me3, magic3); + + printf("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n", + child, getpid()); + errno = 0; + lookup_me4 = ptrace(PT_READ_I, child, dummy_fn4, 0); + ATF_REQUIRE_EQ(errno, 0); + + ATF_REQUIRE_EQ_MSG(lookup_me4, magic4, + "got value %#x != expected %#x", lookup_me4, magic4); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +#if defined(HAVE_GPREGS) +ATF_TC(regs1); +ATF_TC_HEAD(regs1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify plain PT_GETREGS call without further steps"); +} + +ATF_TC_BODY(regs1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct reg r; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Call GETREGS for the child process\n"); + ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(HAVE_GPREGS) +ATF_TC(regs2); +ATF_TC_HEAD(regs2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify plain PT_GETREGS call and retrieve PC"); +} + +ATF_TC_BODY(regs2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct reg r; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Call GETREGS for the child process\n"); + ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); + + printf("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r)); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(HAVE_GPREGS) +ATF_TC(regs3); +ATF_TC_HEAD(regs3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify plain PT_GETREGS call and retrieve SP"); +} + +ATF_TC_BODY(regs3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct reg r; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Call GETREGS for the child process\n"); + ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); + + printf("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r)); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(HAVE_GPREGS) +ATF_TC(regs4); +ATF_TC_HEAD(regs4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify plain PT_GETREGS call and retrieve INTRV"); +} + +ATF_TC_BODY(regs4, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct reg r; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Call GETREGS for the child process\n"); + ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); + + printf("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r)); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(HAVE_GPREGS) +ATF_TC(regs5); +ATF_TC_HEAD(regs5, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_GETREGS and PT_SETREGS calls without changing regs"); +} + +ATF_TC_BODY(regs5, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct reg r; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Call GETREGS for the child process\n"); + ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); + + printf("Call SETREGS for the child process (without changed regs)\n"); + ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(HAVE_FPREGS) +ATF_TC(fpregs1); +ATF_TC_HEAD(fpregs1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify plain PT_GETFPREGS call without further steps"); +} + +ATF_TC_BODY(fpregs1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct fpreg r; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Call GETFPREGS for the child process\n"); + ATF_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(HAVE_FPREGS) +ATF_TC(fpregs2); +ATF_TC_HEAD(fpregs2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_GETFPREGS and PT_SETFPREGS calls without changing " + "regs"); +} + +ATF_TC_BODY(fpregs2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct fpreg r; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Call GETFPREGS for the child process\n"); + ATF_REQUIRE(ptrace(PT_GETFPREGS, child, &r, 0) != -1); + + printf("Call SETFPREGS for the child (without changed regs)\n"); + ATF_REQUIRE(ptrace(PT_SETFPREGS, child, &r, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(PT_STEP) +ATF_TC(step1); +ATF_TC_HEAD(step1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify single PT_STEP call"); +} + +ATF_TC_BODY(step1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + int happy; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + happy = check_happy(100); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(happy, check_happy(100)); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before resuming the child process where it left off and " + "without signal to be sent (use PT_STEP)\n"); + ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(PT_STEP) +ATF_TC(step2); +ATF_TC_HEAD(step2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_STEP called twice"); +} + +ATF_TC_BODY(step2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + int happy; + int N = 2; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + happy = check_happy(999); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(happy, check_happy(999)); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + while (N --> 0) { + printf("Before resuming the child process where it left off " + "and without signal to be sent (use PT_STEP)\n"); + ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), + child); + + validate_status_stopped(status, SIGTRAP); + } + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(PT_STEP) +ATF_TC(step3); +ATF_TC_HEAD(step3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_STEP called three times"); +} + +ATF_TC_BODY(step3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + int happy; + int N = 3; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + happy = check_happy(999); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(happy, check_happy(999)); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + while (N --> 0) { + printf("Before resuming the child process where it left off " + "and without signal to be sent (use PT_STEP)\n"); + ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), + child); + + validate_status_stopped(status, SIGTRAP); + } + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(PT_STEP) +ATF_TC(step4); +ATF_TC_HEAD(step4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify PT_STEP called four times"); +} + +ATF_TC_BODY(step4, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + int happy; + int N = 4; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + happy = check_happy(999); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(happy, check_happy(999)); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + while (N --> 0) { + printf("Before resuming the child process where it left off " + "and without signal to be sent (use PT_STEP)\n"); + ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), + child); + + validate_status_stopped(status, SIGTRAP); + } + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +ATF_TC(kill1); +ATF_TC_HEAD(kill1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that PT_CONTINUE with SIGKILL terminates child"); +} + +ATF_TC_BODY(kill1, tc) +{ + const int sigval = SIGSTOP, sigsent = SIGKILL; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + /* NOTREACHED */ + FORKEE_ASSERTX(0 && + "Child should be terminated by a signal from its parent"); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_signaled(status, sigsent, 0); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(kill2); +ATF_TC_HEAD(kill2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that PT_KILL terminates child"); +} + +ATF_TC_BODY(kill2, tc) +{ + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + /* NOTREACHED */ + FORKEE_ASSERTX(0 && + "Child should be terminated by a signal from its parent"); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_signaled(status, SIGKILL, 0); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(lwpinfo1); +ATF_TC_HEAD(lwpinfo1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify basic LWPINFO call for single thread (PT_TRACE_ME)"); +} + +ATF_TC_BODY(lwpinfo1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct ptrace_lwpinfo info = {0, 0}; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); + ATF_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1); + + printf("Assert that there exists a thread\n"); + ATF_REQUIRE(info.pl_lwpid > 0); + + printf("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n", + info.pl_lwpid); + ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL, + "Received event %d != expected event %d", + info.pl_event, PL_EVENT_SIGNAL); + + printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); + ATF_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1); + + printf("Assert that there are no more lwp threads in child\n"); + ATF_REQUIRE_EQ(info.pl_lwpid, 0); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +#if defined(TWAIT_HAVE_PID) +ATF_TC(lwpinfo2); +ATF_TC_HEAD(lwpinfo2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify basic LWPINFO call for single thread (PT_ATTACH from " + "tracer)"); +} + +ATF_TC_BODY(lwpinfo2, tc) +{ + struct msg_fds parent_tracee, parent_tracer; + const int exitval_tracee = 5; + const int exitval_tracer = 10; + pid_t tracee, tracer, wpid; + uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct ptrace_lwpinfo info = {0, 0}; + + printf("Spawn tracee\n"); + ATF_REQUIRE(msg_open(&parent_tracee) == 0); + ATF_REQUIRE(msg_open(&parent_tracer) == 0); + tracee = atf_utils_fork(); + if (tracee == 0) { + + /* Wait for message from the parent */ + CHILD_TO_PARENT("tracee ready", parent_tracee, msg); + CHILD_FROM_PARENT("tracee exit", parent_tracee, msg); + + _exit(exitval_tracee); + } + PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); + + printf("Spawn debugger\n"); + tracer = atf_utils_fork(); + if (tracer == 0) { + /* No IPC to communicate with the child */ + printf("Before calling PT_ATTACH from tracee %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); + + /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + forkee_status_stopped(status, SIGSTOP); + + printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); + FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info)) + != -1); + + printf("Assert that there exists a thread\n"); + FORKEE_ASSERTX(info.pl_lwpid > 0); + + printf("Assert that lwp thread %d received event " + "PL_EVENT_SIGNAL\n", info.pl_lwpid); + FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL); + + printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); + FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info)) + != -1); + + printf("Assert that there are no more lwp threads in child\n"); + FORKEE_ASSERTX(info.pl_lwpid == 0); + + /* Resume tracee with PT_CONTINUE */ + FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); + + /* Inform parent that tracer has attached to tracee */ + CHILD_TO_PARENT("tracer ready", parent_tracer, msg); + /* Wait for parent */ + CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); + + /* Wait for tracee and assert that it exited */ + FORKEE_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); + + forkee_status_exited(status, exitval_tracee); + + printf("Before exiting of the tracer process\n"); + _exit(exitval_tracer); + } + + printf("Wait for the tracer to attach to the tracee\n"); + PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); + + printf("Resume the tracee and let it exit\n"); + PARENT_TO_CHILD("tracee exit", parent_tracee, msg); + + printf("Detect that tracee is zombie\n"); + await_zombie(tracee); + + printf("Assert that there is no status about tracee - " + "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS( + wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); + + printf("Resume the tracer and let it detect exited tracee\n"); + PARENT_TO_CHILD("tracer wait", parent_tracer, msg); + + printf("Wait for tracer to finish its job and exit - calling %s()\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), + tracer); + + validate_status_exited(status, exitval_tracer); + + printf("Wait for tracee to finish its job and exit - calling %s()\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), + tracee); + + validate_status_exited(status, exitval_tracee); + + msg_close(&parent_tracer); + msg_close(&parent_tracee); +} +#endif + +ATF_TC(siginfo1); +ATF_TC_HEAD(siginfo1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee"); +} + +ATF_TC_BODY(siginfo1, tc) +{ + const int exitval = 5; + const int sigval = SIGTRAP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(siginfo2); +ATF_TC_HEAD(siginfo2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without " + "modification of SIGINT from tracee"); +} + +static int siginfo2_caught = 0; + +static void +siginfo2_sighandler(int sig) +{ + FORKEE_ASSERT_EQ(sig, SIGINT); + + ++siginfo2_caught; +} + +ATF_TC_BODY(siginfo2, tc) +{ + const int exitval = 5; + const int sigval = SIGINT; + pid_t child, wpid; + struct sigaction sa; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + sa.sa_handler = siginfo2_sighandler; + sa.sa_flags = SA_SIGINFO; + sigemptyset(&sa.sa_mask); + + FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(siginfo2_caught, 1); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(siginfo3); +ATF_TC_HEAD(siginfo3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with " + "setting signal to new value"); +} + +static int siginfo3_caught = 0; + +static void +siginfo3_sigaction(int sig, siginfo_t *info, void *ctx) +{ + FORKEE_ASSERT_EQ(sig, SIGTRAP); + + FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); + FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); + + ++siginfo3_caught; +} + +ATF_TC_BODY(siginfo3, tc) +{ + const int exitval = 5; + const int sigval = SIGINT; + const int sigfaked = SIGTRAP; + const int sicodefaked = TRAP_BRKPT; + pid_t child, wpid; + struct sigaction sa; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + sa.sa_sigaction = siginfo3_sigaction; + sa.sa_flags = SA_SIGINFO; + sigemptyset(&sa.sa_mask); + + FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(siginfo3_caught, 1); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + printf("Before setting new faked signal to signo=%d si_code=%d\n", + sigfaked, sicodefaked); + info.psi_siginfo.si_signo = sigfaked; + info.psi_siginfo.si_code = sicodefaked; + + printf("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(siginfo4); +ATF_TC_HEAD(siginfo4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Detect SIGTRAP TRAP_EXEC from tracee"); +} + +ATF_TC_BODY(siginfo4, tc) +{ + const int sigval = SIGTRAP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + + struct ptrace_siginfo info; + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before calling execve(2) from child\n"); + execlp("/bin/echo", "/bin/echo", NULL); + + FORKEE_ASSERT(0 && "Not reached"); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Signal traced to lwpid=%d\n", info.psi_lwpid); + printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +#if defined(TWAIT_HAVE_PID) +ATF_TC(siginfo5); +ATF_TC_HEAD(siginfo5, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK " + "set to PTRACE_FORK and reports correct signal information"); +} + +ATF_TC_BODY(siginfo5, tc) +{ + const int exitval = 5; + const int exitval2 = 15; + const int sigval = SIGSTOP; + pid_t child, child2, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_state_t state; + const int slen = sizeof(state); + ptrace_event_t event; + const int elen = sizeof(event); + struct ptrace_siginfo info; + + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT((child2 = fork()) != 1); + + if (child2 == 0) + _exit(exitval2); + + FORKEE_REQUIRE_SUCCESS + (wpid = TWAIT_GENERIC(child2, &status, 0), child2); + + forkee_status_exited(status, exitval2); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); + + printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); + event.pe_set_event = PTRACE_FORK; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); + + child2 = state.pe_other_pid; + printf("Reported PTRACE_FORK event with forkee %d\n", child2); + + printf("Before calling %s() for the forkee %d of the child %d\n", + TWAIT_FNAME, child2, child); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), + child2); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); + ATF_REQUIRE_EQ(state.pe_other_pid, child); + + printf("Before resuming the forkee process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the forkee - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), + child2); + + validate_status_exited(status, exitval2); + + printf("Before calling %s() for the forkee - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, + wpid = TWAIT_GENERIC(child2, &status, 0)); + + printf("Before calling %s() for the child - expected stopped " + "SIGCHLD\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGCHLD); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(PT_STEP) +ATF_TC(siginfo6); +ATF_TC_HEAD(siginfo6, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify single PT_STEP call with signal information check"); +} + +ATF_TC_BODY(siginfo6, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + int happy; + struct ptrace_siginfo info; + + memset(&info, 0, sizeof(info)); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + happy = check_happy(100); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(happy, check_happy(100)); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); + + printf("Before resuming the child process where it left off and " + "without signal to be sent (use PT_STEP)\n"); + ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); + ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); + + printf("Before checking siginfo_t\n"); + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +volatile lwpid_t the_lwp_id = 0; + +static void +lwp_main_func(void *arg) +{ + the_lwp_id = _lwp_self(); + _lwp_exit(); +} + +ATF_TC(lwp_create1); +ATF_TC_HEAD(lwp_create1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that 1 LWP creation is intercepted by ptrace(2) with " + "EVENT_MASK set to PTRACE_LWP_CREATE"); +} + +ATF_TC_BODY(lwp_create1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_state_t state; + const int slen = sizeof(state); + ptrace_event_t event; + const int elen = sizeof(event); + ucontext_t uc; + lwpid_t lid; + static const size_t ssize = 16*1024; + void *stack; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before allocating memory for stack in child\n"); + FORKEE_ASSERT((stack = malloc(ssize)) != NULL); + + printf("Before making context for new lwp in child\n"); + _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); + + printf("Before creating new in child\n"); + FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); + + printf("Before waiting for lwp %d to exit\n", lid); + FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); + + printf("Before verifying that reported %d and running lid %d " + "are the same\n", lid, the_lwp_id); + FORKEE_ASSERT_EQ(lid, the_lwp_id); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Set empty EVENT_MASK for the child %d\n", child); + event.pe_set_event = PTRACE_LWP_CREATE; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected stopped " + "SIGTRAP\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); + + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); + + lid = state.pe_lwp; + printf("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(lwp_exit1); +ATF_TC_HEAD(lwp_exit1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that 1 LWP creation is intercepted by ptrace(2) with " + "EVENT_MASK set to PTRACE_LWP_EXIT"); +} + +ATF_TC_BODY(lwp_exit1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + ptrace_state_t state; + const int slen = sizeof(state); + ptrace_event_t event; + const int elen = sizeof(event); + ucontext_t uc; + lwpid_t lid; + static const size_t ssize = 16*1024; + void *stack; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before allocating memory for stack in child\n"); + FORKEE_ASSERT((stack = malloc(ssize)) != NULL); + + printf("Before making context for new lwp in child\n"); + _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); + + printf("Before creating new in child\n"); + FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); + + printf("Before waiting for lwp %d to exit\n", lid); + FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); + + printf("Before verifying that reported %d and running lid %d " + "are the same\n", lid, the_lwp_id); + FORKEE_ASSERT_EQ(lid, the_lwp_id); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Set empty EVENT_MASK for the child %d\n", child); + event.pe_set_event = PTRACE_LWP_EXIT; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected stopped " + "SIGTRAP\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGTRAP); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); + + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); + + lid = state.pe_lwp; + printf("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(signal1); +ATF_TC_HEAD(signal1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that masking single unrelated signal does not stop tracer " + "from catching other signals"); +} + +ATF_TC_BODY(signal1, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + const int sigmasked = SIGTRAP; + const int signotmasked = SIGINT; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + sigset_t intmask; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + sigemptyset(&intmask); + sigaddset(&intmask, sigmasked); + sigprocmask(SIG_BLOCK, &intmask, NULL); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before raising %s from child\n", + strsignal(signotmasked)); + FORKEE_ASSERT(raise(signotmasked) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, signotmasked); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(signal2); +ATF_TC_HEAD(signal2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that masking SIGTRAP in tracee stops tracer from " + "catching this raised signal"); +} + +ATF_TC_BODY(signal2, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + const int sigmasked = SIGTRAP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + sigset_t intmask; + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + sigemptyset(&intmask); + sigaddset(&intmask, sigmasked); + sigprocmask(SIG_BLOCK, &intmask, NULL); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before raising %s breakpoint from child\n", + strsignal(sigmasked)); + FORKEE_ASSERT(raise(sigmasked) == 0); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(signal3); +ATF_TC_HEAD(signal3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that masking SIGTRAP in tracee does not stop tracer from " + "catching software breakpoints"); +} + +ATF_TC_BODY(signal3, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + const int sigmasked = SIGTRAP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + sigset_t intmask; + + atf_tc_expect_fail("PR kern/51918"); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + sigemptyset(&intmask); + sigaddset(&intmask, sigmasked); + sigprocmask(SIG_BLOCK, &intmask, NULL); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before raising software breakpoint from child\n"); +#if defined(__x86_64__) + __asm__ __volatile__ ("int3\n;"); +#else + /* port me */ +#endif + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigmasked); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +#if defined(PT_STEP) +ATF_TC(signal4); +ATF_TC_HEAD(signal4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that masking SIGTRAP in tracee does not stop tracer from " + "catching single step trap"); +} + +ATF_TC_BODY(signal4, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + const int sigmasked = SIGTRAP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + sigset_t intmask; + int happy; + + atf_tc_expect_fail("PR kern/51918"); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + happy = check_happy(100); + + sigemptyset(&intmask); + sigaddset(&intmask, sigmasked); + sigprocmask(SIG_BLOCK, &intmask, NULL); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT_EQ(happy, check_happy(100)); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigmasked); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +ATF_TC(signal5); +ATF_TC_HEAD(signal5, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that masking SIGTRAP in tracee does not stop tracer from " + "catching exec() breakpoint"); +} + +ATF_TC_BODY(signal5, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + const int sigmasked = SIGTRAP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + sigset_t intmask; + + atf_tc_expect_fail("PR kern/51918"); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + sigemptyset(&intmask); + sigaddset(&intmask, sigmasked); + sigprocmask(SIG_BLOCK, &intmask, NULL); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before calling execve(2) from child\n"); + execlp("/bin/echo", "/bin/echo", NULL); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigmasked); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +#if defined(TWAIT_HAVE_PID) +ATF_TC(signal6); +ATF_TC_HEAD(signal6, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that masking SIGTRAP in tracee does not stop tracer from " + "catching PTRACE_FORK breakpoint"); +} + +ATF_TC_BODY(signal6, tc) +{ + const int exitval = 5; + const int exitval2 = 15; + const int sigval = SIGSTOP; + const int sigmasked = SIGTRAP; + pid_t child, child2, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + sigset_t intmask; + ptrace_state_t state; + const int slen = sizeof(state); + ptrace_event_t event; + const int elen = sizeof(event); + + atf_tc_expect_fail("PR kern/51918"); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + sigemptyset(&intmask); + sigaddset(&intmask, sigmasked); + sigprocmask(SIG_BLOCK, &intmask, NULL); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT((child2 = fork()) != 1); + + if (child2 == 0) + _exit(exitval2); + + FORKEE_REQUIRE_SUCCESS + (wpid = TWAIT_GENERIC(child2, &status, 0), child2); + + forkee_status_exited(status, exitval2); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); + event.pe_set_event = PTRACE_FORK; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigmasked); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); + + child2 = state.pe_other_pid; + printf("Reported PTRACE_FORK event with forkee %d\n", child2); + + printf("Before calling %s() for the child2\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), + child2); + + validate_status_stopped(status, SIGTRAP); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); + ATF_REQUIRE_EQ(state.pe_other_pid, child); + + printf("Before resuming the forkee process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the forkee - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), + child2); + + validate_status_exited(status, exitval2); + + printf("Before calling %s() for the forkee - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, + wpid = TWAIT_GENERIC(child2, &status, 0)); + + printf("Before calling %s() for the child - expected stopped " + "SIGCHLD\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGCHLD); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +#if defined(TWAIT_HAVE_PID) +ATF_TC(signal7); +ATF_TC_HEAD(signal7, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that masking SIGTRAP in tracee does not stop tracer from " + "catching PTRACE_VFORK breakpoint"); +} + +ATF_TC_BODY(signal7, tc) +{ + const int exitval = 5; + const int exitval2 = 15; + const int sigval = SIGSTOP; + const int sigmasked = SIGTRAP; + pid_t child, child2, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + sigset_t intmask; + ptrace_state_t state; + const int slen = sizeof(state); + ptrace_event_t event; + const int elen = sizeof(event); + + atf_tc_expect_fail("PR kern/51918 PR kern/51630"); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + sigemptyset(&intmask); + sigaddset(&intmask, sigmasked); + sigprocmask(SIG_BLOCK, &intmask, NULL); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT((child2 = fork()) != 1); + + if (child2 == 0) + _exit(exitval2); + + FORKEE_REQUIRE_SUCCESS + (wpid = TWAIT_GENERIC(child2, &status, 0), child2); + + forkee_status_exited(status, exitval2); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); + event.pe_set_event = PTRACE_VFORK; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigmasked); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); + + child2 = state.pe_other_pid; + printf("Reported PTRACE_VFORK event with forkee %d\n", child2); + + printf("Before calling %s() for the child2\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), + child2); + + validate_status_stopped(status, SIGTRAP); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); + ATF_REQUIRE_EQ(state.pe_other_pid, child); + + printf("Before resuming the forkee process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the forkee - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), + child2); + + validate_status_exited(status, exitval2); + + printf("Before calling %s() for the forkee - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, + wpid = TWAIT_GENERIC(child2, &status, 0)); + + printf("Before calling %s() for the child - expected stopped " + "SIGCHLD\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGCHLD); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} +#endif + +ATF_TC(signal8); +ATF_TC_HEAD(signal8, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that masking SIGTRAP in tracee does not stop tracer from " + "catching PTRACE_VFORK_DONE breakpoint"); +} + +ATF_TC_BODY(signal8, tc) +{ + const int exitval = 5; + const int exitval2 = 15; + const int sigval = SIGSTOP; + const int sigmasked = SIGTRAP; + pid_t child, child2, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + sigset_t intmask; + ptrace_state_t state; + const int slen = sizeof(state); + ptrace_event_t event; + const int elen = sizeof(event); + + atf_tc_expect_fail("PR kern/51918"); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + sigemptyset(&intmask); + sigaddset(&intmask, sigmasked); + sigprocmask(SIG_BLOCK, &intmask, NULL); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + FORKEE_ASSERT((child2 = vfork()) != 1); + + if (child2 == 0) + _exit(exitval2); + + FORKEE_REQUIRE_SUCCESS + (wpid = TWAIT_GENERIC(child2, &status, 0), child2); + + forkee_status_exited(status, exitval2); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Enable PTRACE_VFORK_DONE in EVENT_MASK for the child %d\n", + child); + event.pe_set_event = PTRACE_VFORK_DONE; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigmasked); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); + + child2 = state.pe_other_pid; + printf("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected stopped " + "SIGCHLD\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, SIGCHLD); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(signal9); +ATF_TC_HEAD(signal9, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that masking SIGTRAP in tracee does not stop tracer from " + "catching PTRACE_LWP_CREATE breakpoint"); +} + +ATF_TC_BODY(signal9, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + const int sigmasked = SIGTRAP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + sigset_t intmask; + ptrace_state_t state; + const int slen = sizeof(state); + ptrace_event_t event; + const int elen = sizeof(event); + ucontext_t uc; + lwpid_t lid; + static const size_t ssize = 16*1024; + void *stack; + + atf_tc_expect_fail("PR kern/51918"); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + sigemptyset(&intmask); + sigaddset(&intmask, sigmasked); + sigprocmask(SIG_BLOCK, &intmask, NULL); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before allocating memory for stack in child\n"); + FORKEE_ASSERT((stack = malloc(ssize)) != NULL); + + printf("Before making context for new lwp in child\n"); + _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); + + printf("Before creating new in child\n"); + FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); + + printf("Before waiting for lwp %d to exit\n", lid); + FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); + + printf("Before verifying that reported %d and running lid %d " + "are the same\n", lid, the_lwp_id); + FORKEE_ASSERT_EQ(lid, the_lwp_id); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Set empty EVENT_MASK for the child %d\n", child); + event.pe_set_event = PTRACE_LWP_CREATE; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected stopped " + "SIGTRAP\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigmasked); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); + + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); + + lid = state.pe_lwp; + printf("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TC(signal10); +ATF_TC_HEAD(signal10, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that masking SIGTRAP in tracee does not stop tracer from " + "catching PTRACE_LWP_EXIT breakpoint"); +} + +ATF_TC_BODY(signal10, tc) +{ + const int exitval = 5; + const int sigval = SIGSTOP; + const int sigmasked = SIGTRAP; + pid_t child, wpid; +#if defined(TWAIT_HAVE_STATUS) + int status; +#endif + sigset_t intmask; + ptrace_state_t state; + const int slen = sizeof(state); + ptrace_event_t event; + const int elen = sizeof(event); + ucontext_t uc; + lwpid_t lid; + static const size_t ssize = 16*1024; + void *stack; + + atf_tc_expect_fail("PR kern/51918"); + + printf("Before forking process PID=%d\n", getpid()); + ATF_REQUIRE((child = fork()) != -1); + if (child == 0) { + printf("Before calling PT_TRACE_ME from child %d\n", getpid()); + FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); + + sigemptyset(&intmask); + sigaddset(&intmask, sigmasked); + sigprocmask(SIG_BLOCK, &intmask, NULL); + + printf("Before raising %s from child\n", strsignal(sigval)); + FORKEE_ASSERT(raise(sigval) == 0); + + printf("Before allocating memory for stack in child\n"); + FORKEE_ASSERT((stack = malloc(ssize)) != NULL); + + printf("Before making context for new lwp in child\n"); + _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); + + printf("Before creating new in child\n"); + FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); + + printf("Before waiting for lwp %d to exit\n", lid); + FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); + + printf("Before verifying that reported %d and running lid %d " + "are the same\n", lid, the_lwp_id); + FORKEE_ASSERT_EQ(lid, the_lwp_id); + + printf("Before exiting of the child process\n"); + _exit(exitval); + } + printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); + + printf("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigval); + + printf("Set empty EVENT_MASK for the child %d\n", child); + event.pe_set_event = PTRACE_LWP_EXIT; + ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected stopped " + "SIGTRAP\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_stopped(status, sigmasked); + + ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); + + ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); + + lid = state.pe_lwp; + printf("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); + + printf("Before resuming the child process where it left off and " + "without signal to be sent\n"); + ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + printf("Before calling %s() for the child - expected exited\n", + TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); + + validate_status_exited(status, exitval); + + printf("Before calling %s() for the child - expected no process\n", + TWAIT_FNAME); + TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); +} + +ATF_TP_ADD_TCS(tp) +{ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + ATF_TP_ADD_TC(tp, traceme1); + ATF_TP_ADD_TC(tp, traceme2); + ATF_TP_ADD_TC(tp, traceme3); + ATF_TP_ADD_TC(tp, traceme4); + + ATF_TP_ADD_TC_HAVE_PID(tp, attach1); + ATF_TP_ADD_TC_HAVE_PID(tp, attach2); + ATF_TP_ADD_TC(tp, attach3); + ATF_TP_ADD_TC(tp, attach4); + ATF_TP_ADD_TC_HAVE_PID(tp, attach5); + ATF_TP_ADD_TC_HAVE_PID(tp, attach6); + ATF_TP_ADD_TC_HAVE_PID(tp, attach7); + + ATF_TP_ADD_TC(tp, eventmask1); + ATF_TP_ADD_TC(tp, eventmask2); + ATF_TP_ADD_TC(tp, eventmask3); + ATF_TP_ADD_TC(tp, eventmask4); + ATF_TP_ADD_TC(tp, eventmask5); + ATF_TP_ADD_TC(tp, eventmask6); + + ATF_TP_ADD_TC_HAVE_PID(tp, fork1); + ATF_TP_ADD_TC(tp, fork2); + + ATF_TP_ADD_TC_HAVE_PID(tp, vfork1); + ATF_TP_ADD_TC(tp, vfork2); + + ATF_TP_ADD_TC(tp, vforkdone1); + ATF_TP_ADD_TC(tp, vforkdone2); + + ATF_TP_ADD_TC(tp, io_read_d1); + ATF_TP_ADD_TC(tp, io_read_d2); + ATF_TP_ADD_TC(tp, io_read_d3); + ATF_TP_ADD_TC(tp, io_read_d4); + + ATF_TP_ADD_TC(tp, io_write_d1); + ATF_TP_ADD_TC(tp, io_write_d2); + ATF_TP_ADD_TC(tp, io_write_d3); + ATF_TP_ADD_TC(tp, io_write_d4); + + ATF_TP_ADD_TC(tp, read_d1); + ATF_TP_ADD_TC(tp, read_d2); + ATF_TP_ADD_TC(tp, read_d3); + ATF_TP_ADD_TC(tp, read_d4); + + ATF_TP_ADD_TC(tp, write_d1); + ATF_TP_ADD_TC(tp, write_d2); + ATF_TP_ADD_TC(tp, write_d3); + ATF_TP_ADD_TC(tp, write_d4); + + ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1); + ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2); + + ATF_TP_ADD_TC(tp, read_d_write_d_handshake1); + ATF_TP_ADD_TC(tp, read_d_write_d_handshake2); + + ATF_TP_ADD_TC(tp, io_read_i1); + ATF_TP_ADD_TC(tp, io_read_i2); + ATF_TP_ADD_TC(tp, io_read_i3); + ATF_TP_ADD_TC(tp, io_read_i4); + + ATF_TP_ADD_TC(tp, read_i1); + ATF_TP_ADD_TC(tp, read_i2); + ATF_TP_ADD_TC(tp, read_i3); + ATF_TP_ADD_TC(tp, read_i4); + + ATF_TP_ADD_TC(tp, io_read_auxv1); + + ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1); + ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2); + ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3); + ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4); + ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5); + + ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1); + ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2); + + ATF_TP_ADD_TC_PT_STEP(tp, step1); + ATF_TP_ADD_TC_PT_STEP(tp, step2); + ATF_TP_ADD_TC_PT_STEP(tp, step3); + ATF_TP_ADD_TC_PT_STEP(tp, step4); + + ATF_TP_ADD_TC(tp, kill1); + ATF_TP_ADD_TC(tp, kill2); + + ATF_TP_ADD_TC(tp, lwpinfo1); + ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2); + + ATF_TP_ADD_TC(tp, siginfo1); + ATF_TP_ADD_TC(tp, siginfo2); + ATF_TP_ADD_TC(tp, siginfo3); + ATF_TP_ADD_TC(tp, siginfo4); + ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5); + ATF_TP_ADD_TC_PT_STEP(tp, siginfo6); + + ATF_TP_ADD_TC(tp, lwp_create1); + + ATF_TP_ADD_TC(tp, lwp_exit1); + + ATF_TP_ADD_TC(tp, signal1); + ATF_TP_ADD_TC(tp, signal2); + ATF_TP_ADD_TC(tp, signal3); + ATF_TP_ADD_TC_PT_STEP(tp, signal4); + ATF_TP_ADD_TC(tp, signal5); + ATF_TP_ADD_TC_HAVE_PID(tp, signal6); + ATF_TP_ADD_TC_HAVE_PID(tp, signal7); + ATF_TP_ADD_TC(tp, signal8); + ATF_TP_ADD_TC(tp, signal9); + ATF_TP_ADD_TC(tp, signal10); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_ptrace_wait.h b/contrib/netbsd-tests/kernel/t_ptrace_wait.h new file mode 100644 index 0000000..9c6921c --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_ptrace_wait.h @@ -0,0 +1,431 @@ +/* $NetBSD: t_ptrace_wait.h,v 1.7 2017/01/09 22:09:20 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* Detect plain wait(2) use-case */ +#if !defined(TWAIT_WAITPID) && \ + !defined(TWAIT_WAITID) && \ + !defined(TWAIT_WAIT3) && \ + !defined(TWAIT_WAIT4) && \ + !defined(TWAIT_WAIT6) +#define TWAIT_WAIT +#endif + +/* + * There are two classes of wait(2)-like functions: + * - wait4(2)-like accepting pid_t, optional options parameter, struct rusage* + * - wait6(2)-like accepting idtype_t, id_t, struct wrusage, mandatory options + * + * The TWAIT_FNAME value is to be used for convenience in debug messages. + * + * The TWAIT_GENERIC() macro is designed to reuse the same unmodified + * code with as many wait(2)-like functions as possible. + * + * In a common use-case wait4(2) and wait6(2)-like function can work the almost + * the same way, however there are few important differences: + * wait6(2) must specify P_PID for idtype to match wpid from wait4(2). + * To behave like wait4(2), wait6(2) the 'options' to wait must include + * WEXITED|WTRUNCATED. + * + * There are two helper macros (they purpose it to mach more than one + * wait(2)-like function): + * The TWAIT_HAVE_STATUS - specifies whether a function can retrieve + * status (as integer value). + * The TWAIT_HAVE_PID - specifies whether a function can request + * exact process identifier + * The TWAIT_HAVE_RUSAGE - specifies whether a function can request + * the struct rusage value + * + */ + +#if defined(TWAIT_WAIT) +# define TWAIT_FNAME "wait" +# define TWAIT_WAIT4TYPE(a,b,c,d) wait((b)) +# define TWAIT_GENERIC(a,b,c) wait((b)) +# define TWAIT_HAVE_STATUS 1 +#elif defined(TWAIT_WAITPID) +# define TWAIT_FNAME "waitpid" +# define TWAIT_WAIT4TYPE(a,b,c,d) waitpid((a),(b),(c)) +# define TWAIT_GENERIC(a,b,c) waitpid((a),(b),(c)) +# define TWAIT_HAVE_PID 1 +# define TWAIT_HAVE_STATUS 1 +#elif defined(TWAIT_WAITID) +# define TWAIT_FNAME "waitid" +# define TWAIT_GENERIC(a,b,c) \ + waitid(P_PID,(a),NULL,(c)|WEXITED|WTRAPPED) +# define TWAIT_WAIT6TYPE(a,b,c,d,e,f) waitid((a),(b),(f),(d)) +# define TWAIT_HAVE_PID 1 +#elif defined(TWAIT_WAIT3) +# define TWAIT_FNAME "wait3" +# define TWAIT_WAIT4TYPE(a,b,c,d) wait3((b),(c),(d)) +# define TWAIT_GENERIC(a,b,c) wait3((b),(c),NULL) +# define TWAIT_HAVE_STATUS 1 +# define TWAIT_HAVE_RUSAGE 1 +#elif defined(TWAIT_WAIT4) +# define TWAIT_FNAME "wait4" +# define TWAIT_WAIT4TYPE(a,b,c,d) wait4((a),(b),(c),(d)) +# define TWAIT_GENERIC(a,b,c) wait4((a),(b),(c),NULL) +# define TWAIT_HAVE_PID 1 +# define TWAIT_HAVE_STATUS 1 +# define TWAIT_HAVE_RUSAGE 1 +#elif defined(TWAIT_WAIT6) +# define TWAIT_FNAME "wait6" +# define TWAIT_WAIT6TYPE(a,b,c,d,e,f) wait6((a),(b),(c),(d),(e),(f)) +# define TWAIT_GENERIC(a,b,c) \ + wait6(P_PID,(a),(b),(c)|WEXITED|WTRAPPED,NULL,NULL) +# define TWAIT_HAVE_PID 1 +# define TWAIT_HAVE_STATUS 1 +#endif + +/* + * There are 3 groups of tests: + * - TWAIT_GENERIC() (wait, wait2, waitpid, wait3, wait4, wait6) + * - TWAIT_WAIT4TYPE() (wait2, waitpid, wait3, wait4) + * - TWAIT_WAIT6TYPE() (waitid, wait6) + * + * Tests only in the above categories are allowed. However some tests are not + * possible in the context requested functionality to be verified, therefore + * there are helper macros: + * - TWAIT_HAVE_PID (wait2, waitpid, waitid, wait4, wait6) + * - TWAIT_HAVE_STATUS (wait, wait2, waitpid, wait3, wait4, wait6) + * - TWAIT_HAVE_RUSAGE (wait3, wait4) + * - TWAIT_HAVE_RETPID (wait, wait2, waitpid, wait3, wait4, wait6) + * + * If there is an intention to test e.g. wait6(2) specific features in the + * ptrace(2) context, find the most matching group and with #ifdefs reduce + * functionality of less featured than wait6(2) interface (TWAIT_WAIT6TYPE). + * + * For clarity never use negative preprocessor checks, like: + * #if !defined(TWAIT_WAIT4) + * always refer to checks for positive values. + */ + +#define TEST_REQUIRE_EQ(x, y) \ +do { \ + uintmax_t vx = (x); \ + uintmax_t vy = (y); \ + int ret = vx == vy; \ + if (!ret) \ + ATF_REQUIRE_EQ_MSG(vx, vy, "%s(%ju) == %s(%ju)", \ + #x, vx, #y, vy); \ +} while (/*CONSTCOND*/0) + +/* + * A child process cannot call atf functions and expect them to magically + * work like in the parent. + * The printf(3) messaging from a child will not work out of the box as well + * without estabilishing a communication protocol with its parent. To not + * overcomplicate the tests - do not log from a child and use err(3)/errx(3) + * wrapped with FORKEE_ASSERT()/FORKEE_ASSERTX() as that is guaranteed to work. + */ +#define FORKEE_ASSERT_EQ(x, y) \ +do { \ + uintmax_t vx = (x); \ + uintmax_t vy = (y); \ + int ret = vx == vy; \ + if (!ret) \ + errx(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: " \ + "%s(%ju) == %s(%ju)", __FILE__, __LINE__, __func__, \ + #x, vx, #y, vy); \ +} while (/*CONSTCOND*/0) + +#define FORKEE_ASSERTX(x) \ +do { \ + int ret = (x); \ + if (!ret) \ + errx(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: %s",\ + __FILE__, __LINE__, __func__, #x); \ +} while (/*CONSTCOND*/0) + +#define FORKEE_ASSERT(x) \ +do { \ + int ret = (x); \ + if (!ret) \ + err(EXIT_FAILURE, "%s:%d %s(): Assertion failed for: %s",\ + __FILE__, __LINE__, __func__, #x); \ +} while (/*CONSTCOND*/0) + +/* + * Simplify logic for functions using general purpose registers add HAVE_GPREGS + * + * For platforms that do not implement all needed calls for simplicity assume + * that they are unsupported at all. + */ +#if defined(PT_GETREGS) \ + && defined(PT_SETREGS) \ + && defined(PTRACE_REG_PC) \ + && defined(PTRACE_REG_SET_PC) \ + && defined(PTRACE_REG_SP) \ + && defined(PTRACE_REG_INTRV) +#define HAVE_GPREGS +#endif + +/* Add guards for floating point registers */ +#if defined(PT_GETFPREGS) \ + && defined(PT_SETFPREGS) +#define HAVE_FPREGS +#endif + +/* Add guards for cpu debug registers */ +#if defined(PT_GETDBREGS) \ + && defined(PT_SETDBREGS) +#define HAVE_DBREGS +#endif + +/* + * If waitid(2) returns because one or more processes have a state change to + * report, 0 is returned. If an error is detected, a value of -1 is returned + * and errno is set to indicate the error. If WNOHANG is specified and there + * are no stopped, continued or exited children, 0 is returned. + */ +#if defined(TWAIT_WAITID) +#define TWAIT_REQUIRE_SUCCESS(a,b) TEST_REQUIRE_EQ((a), 0) +#define TWAIT_REQUIRE_FAILURE(a,b) ATF_REQUIRE_ERRNO((a),(b) == -1) +#define FORKEE_REQUIRE_SUCCESS(a,b) FORKEE_ASSERT_EQ(a, 0) +#define FORKEE_REQUIRE_FAILURE(a,b) \ + FORKEE_ASSERTX(((a) == errno) && ((b) == -1)) +#else +#define TWAIT_REQUIRE_SUCCESS(a,b) TEST_REQUIRE_EQ((a), (b)) +#define TWAIT_REQUIRE_FAILURE(a,b) ATF_REQUIRE_ERRNO((a),(b) == -1) +#define FORKEE_REQUIRE_SUCCESS(a,b) FORKEE_ASSERT_EQ(a, b) +#define FORKEE_REQUIRE_FAILURE(a,b) \ + FORKEE_ASSERTX(((a) == errno) && ((b) == -1)) +#endif + +/* + * Helper tools to verify whether status reports exited value + */ +#if TWAIT_HAVE_STATUS +static void __used +validate_status_exited(int status, int expected) +{ + ATF_REQUIRE_MSG(WIFEXITED(status), "Reported !exited process"); + ATF_REQUIRE_MSG(!WIFCONTINUED(status), "Reported continued process"); + ATF_REQUIRE_MSG(!WIFSIGNALED(status), "Reported signaled process"); + ATF_REQUIRE_MSG(!WIFSTOPPED(status), "Reported stopped process"); + + ATF_REQUIRE_EQ_MSG(WEXITSTATUS(status), expected, + "The process has exited with invalid value %d != %d", + WEXITSTATUS(status), expected); +} + +static void __used +forkee_status_exited(int status, int expected) +{ + FORKEE_ASSERTX(WIFEXITED(status)); + FORKEE_ASSERTX(!WIFCONTINUED(status)); + FORKEE_ASSERTX(!WIFSIGNALED(status)); + FORKEE_ASSERTX(!WIFSTOPPED(status)); + + FORKEE_ASSERT_EQ(WEXITSTATUS(status), expected); +} + +static void __used +validate_status_continued(int status) +{ + ATF_REQUIRE_MSG(!WIFEXITED(status), "Reported exited process"); + ATF_REQUIRE_MSG(WIFCONTINUED(status), "Reported !continued process"); + ATF_REQUIRE_MSG(!WIFSIGNALED(status), "Reported signaled process"); + ATF_REQUIRE_MSG(!WIFSTOPPED(status), "Reported stopped process"); +} + +static void __used +forkee_status_continued(int status) +{ + FORKEE_ASSERTX(!WIFEXITED(status)); + FORKEE_ASSERTX(WIFCONTINUED(status)); + FORKEE_ASSERTX(!WIFSIGNALED(status)); + FORKEE_ASSERTX(!WIFSTOPPED(status)); +} + +static void __used +validate_status_signaled(int status, int expected_termsig, int expected_core) +{ + ATF_REQUIRE_MSG(!WIFEXITED(status), "Reported exited process"); + ATF_REQUIRE_MSG(!WIFCONTINUED(status), "Reported continued process"); + ATF_REQUIRE_MSG(WIFSIGNALED(status), "Reported !signaled process"); + ATF_REQUIRE_MSG(!WIFSTOPPED(status), "Reported stopped process"); + + ATF_REQUIRE_EQ_MSG(WTERMSIG(status), expected_termsig, + "Unexpected signal received"); + + ATF_REQUIRE_EQ_MSG(WCOREDUMP(status), expected_core, + "Unexpectedly core file %s generated", expected_core ? "not" : ""); +} + +static void __used +forkee_status_signaled(int status, int expected_termsig, int expected_core) +{ + FORKEE_ASSERTX(!WIFEXITED(status)); + FORKEE_ASSERTX(!WIFCONTINUED(status)); + FORKEE_ASSERTX(WIFSIGNALED(status)); + FORKEE_ASSERTX(!WIFSTOPPED(status)); + + FORKEE_ASSERT_EQ(WTERMSIG(status), expected_termsig); + FORKEE_ASSERT_EQ(WCOREDUMP(status), expected_core); +} + +static void __used +validate_status_stopped(int status, int expected) +{ + ATF_REQUIRE_MSG(!WIFEXITED(status), "Reported exited process"); + ATF_REQUIRE_MSG(!WIFCONTINUED(status), "Reported continued process"); + ATF_REQUIRE_MSG(!WIFSIGNALED(status), "Reported signaled process"); + ATF_REQUIRE_MSG(WIFSTOPPED(status), "Reported !stopped process"); + + char st[128], ex[128]; + strlcpy(st, strsignal(WSTOPSIG(status)), sizeof(st)); + strlcpy(ex, strsignal(expected), sizeof(ex)); + + ATF_REQUIRE_EQ_MSG(WSTOPSIG(status), expected, + "Unexpected stop signal received [%s] != [%s]", st, ex); +} + +static void __used +forkee_status_stopped(int status, int expected) +{ + FORKEE_ASSERTX(!WIFEXITED(status)); + FORKEE_ASSERTX(!WIFCONTINUED(status)); + FORKEE_ASSERTX(!WIFSIGNALED(status)); + FORKEE_ASSERTX(WIFSTOPPED(status)); + + FORKEE_ASSERT_EQ(WSTOPSIG(status), expected); +} +#else +#define validate_status_exited(a,b) +#define forkee_status_exited(a,b) +#define validate_status_continued(a,b) +#define forkee_status_continued(a,b) +#define validate_status_signaled(a,b,c) +#define forkee_status_signaled(a,b,c) +#define validate_status_stopped(a,b) +#define forkee_status_stopped(a,b) +#endif + +/* This function is currently designed to be run in the main/parent process */ +static void __used +await_zombie(pid_t process) +{ + struct kinfo_proc2 p; + size_t len = sizeof(p); + + const int name[] = { + [0] = CTL_KERN, + [1] = KERN_PROC2, + [2] = KERN_PROC_PID, + [3] = process, + [4] = sizeof(p), + [5] = 1 + }; + + const size_t namelen = __arraycount(name); + + /* Await the process becoming a zombie */ + while(1) { + ATF_REQUIRE(sysctl(name, namelen, &p, &len, NULL, 0) == 0); + + if (p.p_stat == LSZOMB) + break; + + ATF_REQUIRE(usleep(1000) == 0); + } +} + +/* Happy number sequence -- this function is used to just consume cpu cycles */ +#define HAPPY_NUMBER 1 + +/* If n is not happy then its sequence ends in the cycle: + * 4, 16, 37, 58, 89, 145, 42, 20, 4, ... */ +#define SAD_NUMBER 4 + +/* Calculate the sum of the squares of the digits of n */ +static unsigned __used +dsum(unsigned n) +{ + unsigned sum, x; + for (sum = 0; n; n /= 10) { + x = n % 10; + sum += x * x; + } + return sum; +} + +/* + * XXX: Disabled optimization is required to make tests for hardware assisted + * traps in .text functional + * + * Tested with GCC 5.4 on NetBSD 7.99.47 amd64 + */ +static int __used +#ifdef __clang__ +__attribute__((__optnone__)) +#else +__attribute__((__optimize__("O0"))) +#endif +check_happy(unsigned n) +{ + for (;;) { + unsigned total = dsum(n); + + if (total == HAPPY_NUMBER) + return 1; + if (total == SAD_NUMBER) + return 0; + + n = total; + } +} + +#if defined(TWAIT_HAVE_PID) +#define ATF_TP_ADD_TC_HAVE_PID(a,b) ATF_TP_ADD_TC(a,b) +#else +#define ATF_TP_ADD_TC_HAVE_PID(a,b) +#endif + +#if defined(HAVE_GPREGS) +#define ATF_TP_ADD_TC_HAVE_GPREGS(a,b) ATF_TP_ADD_TC(a,b) +#else +#define ATF_TP_ADD_TC_HAVE_GPREGS(a,b) +#endif + +#if defined(HAVE_FPREGS) +#define ATF_TP_ADD_TC_HAVE_FPREGS(a,b) ATF_TP_ADD_TC(a,b) +#else +#define ATF_TP_ADD_TC_HAVE_FPREGS(a,b) +#endif + +#if defined(PT_STEP) +#define ATF_TP_ADD_TC_PT_STEP(a,b) ATF_TP_ADD_TC(a,b) +#else +#define ATF_TP_ADD_TC_PT_STEP(a,b) +#endif + +#if defined(__HAVE_PTRACE_WATCHPOINTS) +#define ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(a,b) ATF_TP_ADD_TC(a,b) +#else +#define ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(a,b) +#endif diff --git a/contrib/netbsd-tests/kernel/t_ptrace_wait3.c b/contrib/netbsd-tests/kernel/t_ptrace_wait3.c new file mode 100644 index 0000000..c136431 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_ptrace_wait3.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_wait3.c,v 1.1 2016/11/07 21:09:03 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAIT3 +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/t_ptrace_wait4.c b/contrib/netbsd-tests/kernel/t_ptrace_wait4.c new file mode 100644 index 0000000..7ae771b --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_ptrace_wait4.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_wait4.c,v 1.1 2016/11/07 21:09:03 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAIT4 +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/t_ptrace_wait6.c b/contrib/netbsd-tests/kernel/t_ptrace_wait6.c new file mode 100644 index 0000000..122cb1d --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_ptrace_wait6.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_wait6.c,v 1.1 2016/11/07 21:09:03 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAIT6 +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/t_ptrace_waitid.c b/contrib/netbsd-tests/kernel/t_ptrace_waitid.c new file mode 100644 index 0000000..1c09be7 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_ptrace_waitid.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_waitid.c,v 1.1 2016/11/07 21:09:03 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAITID +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/t_ptrace_waitpid.c b/contrib/netbsd-tests/kernel/t_ptrace_waitpid.c new file mode 100644 index 0000000..c8f107d --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_ptrace_waitpid.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_ptrace_waitpid.c,v 1.1 2016/11/07 21:09:03 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_WAITPID +#include "t_ptrace_wait.c" diff --git a/contrib/netbsd-tests/kernel/t_pty.c b/contrib/netbsd-tests/kernel/t_pty.c new file mode 100644 index 0000000..3b079ef --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_pty.c @@ -0,0 +1,351 @@ +/* $Id: t_pty.c,v 1.2 2017/01/13 21:30:41 christos Exp $ */ + +/* + * Allocates a pty(4) device, and sends the specified number of packets of the + * specified length though it, while a child reader process reads and reports + * results. + * + * Written by Matthew Mondor + */ + +#include +__RCSID("$NetBSD: t_pty.c,v 1.2 2017/01/13 21:30:41 christos Exp $"); + +#include +#include +#include +#include +#include +#ifdef __linux__ +#define _XOPEN_SOURCE +#define __USE_XOPEN +#endif +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef STANDALONE +static __dead void usage(const char *); +static void parse_args(int, char **); +#else +#include +#include "h_macros.h" +#endif + +static int pty_open(void); +static int tty_open(const char *); +static void fd_nonblock(int); +static pid_t child_spawn(const char *); +static void run(void); + +static size_t buffer_size = 4096; +static size_t packets = 2; +static uint8_t *dbuf; +static int verbose; +static int qsize; + + +static +void run(void) +{ + size_t i; + int pty; + int status; + pid_t child; + if ((dbuf = calloc(1, buffer_size)) == NULL) + err(EXIT_FAILURE, "malloc(%zu)", buffer_size); + + if (verbose) + (void)printf( + "parent: started; opening PTY and spawning child\n"); + pty = pty_open(); + child = child_spawn(ptsname(pty)); + if (verbose) + (void)printf("parent: sleeping to make sure child is ready\n"); + (void)sleep(1); + + for (i = 0; i < buffer_size; i++) + dbuf[i] = i & 0xff; + + if (verbose) + (void)printf("parent: writing\n"); + + for (i = 0; i < packets; i++) { + ssize_t size; + + if (verbose) + (void)printf( + "parent: attempting to write %zu bytes to PTY\n", + buffer_size); + if ((size = write(pty, dbuf, buffer_size)) == -1) { + err(EXIT_FAILURE, "parent: write()"); + break; + } + if (verbose) + (void)printf("parent: wrote %zd bytes to PTY\n", size); + } + + if (verbose) + (void)printf("parent: waiting for child to exit\n"); + if (waitpid(child, &status, 0) == -1) + err(EXIT_FAILURE, "waitpid"); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + errx(EXIT_FAILURE, "child failed"); + + if (verbose) + (void)printf("parent: closing PTY\n"); + (void)close(pty); + if (verbose) + (void)printf("parent: exiting\n"); +} + +static void +condition(int fd) +{ + struct termios tios; + + if (qsize) { + int opt = qsize; + if (ioctl(fd, TIOCSQSIZE, &opt) == -1) + err(EXIT_FAILURE, "Couldn't set tty(4) buffer size"); + if (ioctl(fd, TIOCGQSIZE, &opt) == -1) + err(EXIT_FAILURE, "Couldn't get tty(4) buffer size"); + if (opt != qsize) + errx(EXIT_FAILURE, "Wrong qsize %d != %d\n", + qsize, opt); + } + if (tcgetattr(fd, &tios) == -1) + err(EXIT_FAILURE, "tcgetattr()"); + cfmakeraw(&tios); + cfsetspeed(&tios, B921600); + if (tcsetattr(fd, TCSANOW, &tios) == -1) + err(EXIT_FAILURE, "tcsetattr()"); +} + +static int +pty_open(void) +{ + int fd; + + if ((fd = posix_openpt(O_RDWR)) == -1) + err(EXIT_FAILURE, "Couldn't pty(4) device"); + condition(fd); + if (grantpt(fd) == -1) + err(EXIT_FAILURE, + "Couldn't grant permissions on tty(4) device"); + + + condition(fd); + + if (unlockpt(fd) == -1) + err(EXIT_FAILURE, "unlockpt()"); + + return fd; +} + +static int +tty_open(const char *ttydev) +{ + int fd; + + if ((fd = open(ttydev, O_RDWR, 0)) == -1) + err(EXIT_FAILURE, "Couldn't open tty(4) device"); + +#ifdef USE_PPP_DISCIPLINE + { + int opt = PPPDISC; + if (ioctl(fd, TIOCSETD, &opt) == -1) + err(EXIT_FAILURE, + "Couldn't set tty(4) discipline to PPP"); + } +#endif + + condition(fd); + + return fd; +} + +static void +fd_nonblock(int fd) +{ + int opt; + + if ((opt = fcntl(fd, F_GETFL, NULL)) == -1) + err(EXIT_FAILURE, "fcntl()"); + if (fcntl(fd, F_SETFL, opt | O_NONBLOCK) == -1) + err(EXIT_FAILURE, "fcntl()"); +} + +static pid_t +child_spawn(const char *ttydev) +{ + pid_t pid; + int tty; + struct pollfd pfd; + size_t total = 0; + + if ((pid = fork()) == -1) + err(EXIT_FAILURE, "fork()"); + (void)setsid(); + if (pid != 0) + return pid; + + if (verbose) + (void)printf("child: started; open \"%s\"\n", ttydev); + tty = tty_open(ttydev); + fd_nonblock(tty); + + if (verbose) + (void)printf("child: TTY open, starting read loop\n"); + pfd.fd = tty; + pfd.events = POLLIN; + pfd.revents = 0; + for (;;) { + int ret; + ssize_t size; + + if (verbose) + (void)printf("child: polling\n"); + if ((ret = poll(&pfd, 1, 2000)) == -1) + err(EXIT_FAILURE, "child: poll()"); + if (ret == 0) + break; + if ((pfd.revents & POLLERR) != 0) + break; + if ((pfd.revents & POLLIN) != 0) { + for (;;) { + if (verbose) + (void)printf( + "child: attempting to read %zu" + " bytes\n", buffer_size); + if ((size = read(tty, dbuf, buffer_size)) + == -1) { + if (errno == EAGAIN) + break; + err(EXIT_FAILURE, "child: read()"); + } + if (qsize && size < qsize && + (size_t)size < buffer_size) + errx(EXIT_FAILURE, "read returned %zd " + "less than the queue size %d", + size, qsize); + if (verbose) + (void)printf( + "child: read %zd bytes from TTY\n", + size); + if (size == 0) + goto end; + total += size; + } + } + } +end: + if (verbose) + (void)printf("child: closing TTY %zu\n", total); + (void)close(tty); + if (verbose) + (void)printf("child: exiting\n"); + if (total != buffer_size * packets) + errx(EXIT_FAILURE, + "Lost data %zu != %zu\n", total, buffer_size * packets); + + exit(EXIT_SUCCESS); +} + +#ifdef STANDALONE +static void +usage(const char *msg) +{ + + if (msg != NULL) + (void) fprintf(stderr, "\n%s\n\n", msg); + + (void)fprintf(stderr, + "Usage: %s [-v] [-q ] [-s ] [-n ]\n", + getprogname()); + + exit(EXIT_FAILURE); +} + +static void +parse_args(int argc, char **argv) +{ + int ch; + + while ((ch = getopt(argc, argv, "n:q:s:v")) != -1) { + switch (ch) { + case 'n': + packets = (size_t)atoi(optarg); + break; + case 'q': + qsize = atoi(optarg); + break; + case 's': + buffer_size = (size_t)atoi(optarg); + break; + case 'v': + verbose++; + break; + default: + usage(NULL); + break; + } + } + if (buffer_size < 0 || buffer_size > 65536) + usage("-s must be between 0 and 65536"); + if (packets < 1 || packets > 100) + usage("-p must be between 1 and 100"); +} + +int +main(int argc, char **argv) +{ + + parse_args(argc, argv); + run(); + exit(EXIT_SUCCESS); +} + +#else +ATF_TC(pty_no_queue); + +ATF_TC_HEAD(pty_no_queue, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that writing to pty " + "does not lose data with the default queue size of 1024"); +} + +ATF_TC_BODY(pty_no_queue, tc) +{ + qsize = 0; + run(); +} + +ATF_TC(pty_queue); + +ATF_TC_HEAD(pty_queue, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that writing to pty " + "does not lose data with the a queue size of 4096"); +} + +ATF_TC_BODY(pty_queue, tc) +{ + qsize = 4096; + run(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pty_no_queue); + ATF_TP_ADD_TC(tp, pty_queue); + + return atf_no_error(); +} +#endif diff --git a/contrib/netbsd-tests/kernel/t_rnd.c b/contrib/netbsd-tests/kernel/t_rnd.c new file mode 100644 index 0000000..ae9ef55 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_rnd.c @@ -0,0 +1,114 @@ +/* $NetBSD: t_rnd.c,v 1.10 2017/01/13 21:30:41 christos Exp $ */ + +/* + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_rnd.c,v 1.10 2017/01/13 21:30:41 christos Exp $"); + +#include +#include +#include +#include + +#include + +#include +#include + +#include "h_macros.h" + +ATF_TC(RNDADDDATA); +ATF_TC_HEAD(RNDADDDATA, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks ioctl(RNDADDDATA) (PR kern/42020)"); +} + +/* Adapted from example provided by Juho Salminen in the noted PR. */ +ATF_TC_BODY(RNDADDDATA, tc) +{ + rnddata_t rd; + int fd; + + rump_init(); + fd = rump_sys_open("/dev/random", O_RDWR, 0); + if (fd == -1) + atf_tc_fail_errno("cannot open /dev/random"); + + rd.entropy = 1; + rd.len = 1; + if (rump_sys_ioctl(fd, RNDADDDATA, &rd) == -1) + atf_tc_fail_errno("RNDADDDATA"); +} + +ATF_TC(RNDADDDATA2); +ATF_TC_HEAD(RNDADDDATA2, tc) +{ + atf_tc_set_md_var(tc, "descr", "checks ioctl(RNDADDDATA) deals with " + "garbage len field"); +} +ATF_TC_BODY(RNDADDDATA2, tc) +{ + rnddata_t rd; + int fd; + + rump_init(); + fd = rump_sys_open("/dev/random", O_RDWR, 0); + if (fd == -1) + atf_tc_fail_errno("cannot open /dev/random"); + + rd.entropy = 1; + rd.len = -1; + ATF_REQUIRE_ERRNO(EINVAL, rump_sys_ioctl(fd, RNDADDDATA, &rd) == -1); +} + +ATF_TC(read_random); +ATF_TC_HEAD(read_random, tc) +{ + atf_tc_set_md_var(tc, "descr", "does reading /dev/random return " + "within reasonable time"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(read_random, tc) +{ + char buf[128]; + int fd; + + rump_init(); + RL(fd = rump_sys_open("/dev/random", O_RDONLY)); + RL(rump_sys_read(fd, buf, sizeof(buf))); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, RNDADDDATA); + ATF_TP_ADD_TC(tp, RNDADDDATA2); + ATF_TP_ADD_TC(tp, read_random); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_sysctl.c b/contrib/netbsd-tests/kernel/t_sysctl.c new file mode 100644 index 0000000..8b7c97e --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_sysctl.c @@ -0,0 +1,74 @@ +/* $NetBSD: t_sysctl.c,v 1.1 2014/08/09 07:04:03 gson Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2014\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sysctl.c,v 1.1 2014/08/09 07:04:03 gson Exp $"); + +#include +#include +#include + +#include + +ATF_TC(bufsize); +ATF_TC_HEAD(bufsize, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test sysctl integer reads with different buffer sizes"); +} +ATF_TC_BODY(bufsize, tc) +{ + union { + int int_val; + unsigned char space[256]; + } buf; + size_t len; + for (len = 0; len < sizeof(buf); len++) { + size_t oldlen = len; + int r; + memset(&buf, 0xFF, sizeof(buf)); + r = sysctlbyname("kern.job_control", &buf, &oldlen, 0, (size_t) 0); + if (len < sizeof(int)) { + ATF_REQUIRE_EQ(r, -1); + ATF_REQUIRE_EQ(errno, ENOMEM); + } else { + ATF_REQUIRE_EQ(r, 0); + ATF_REQUIRE_EQ(buf.int_val, 1); + ATF_REQUIRE_EQ(oldlen, sizeof(int)); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, bufsize); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/kernel/t_sysv.c b/contrib/netbsd-tests/kernel/t_sysv.c new file mode 100644 index 0000000..0860d4b --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_sysv.c @@ -0,0 +1,854 @@ +/* $NetBSD: t_sysv.c,v 1.4 2014/03/02 20:13:12 jmmv Exp $ */ + +/*- + * Copyright (c) 1999, 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center, and by Andrew Doran. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Test the SVID-compatible Message Queue facility. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +volatile int did_sigsys, did_sigchild; +volatile int child_status, child_count; + +void sigsys_handler(int); +void sigchld_handler(int); + +key_t get_ftok(int); + +void print_msqid_ds(struct msqid_ds *, mode_t); +void receiver(void); + +void print_semid_ds(struct semid_ds *, mode_t); +void waiter(void); + +void print_shmid_ds(struct shmid_ds *, mode_t); +void sharer(void); + +#define MESSAGE_TEXT_LEN 256 + +struct mymsg { + long mtype; + char mtext[MESSAGE_TEXT_LEN]; +}; + +const char *m1_str = "California is overrated."; +const char *m2_str = "The quick brown fox jumped over the lazy dog."; + +size_t pgsize; + +#define MTYPE_1 1 +#define MTYPE_1_ACK 2 + +#define MTYPE_2 3 +#define MTYPE_2_ACK 4 + +pid_t child_pid; + +key_t msgkey, semkey, shmkey; + +int maxloop = 1; + +union semun { + int val; /* value for SETVAL */ + struct semid_ds *buf; /* buffer for IPC_{STAT,SET} */ + u_short *array; /* array for GETALL & SETALL */ +}; + + +/* Writes an integer to a file. To be used from the body of the test + * cases below to pass any global identifiers to the cleanup routine. */ +static void +write_int(const char *path, const int value) +{ + int output; + + output = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600); + ATF_REQUIRE_MSG(output != -1, "Failed to create %s", path); + write(output, &value, sizeof(value)); + close(output); +} + + +/* Reads an integer from a file. To be used from the cleanup routines + * of the test cases below. */ +static int +read_int(const char *path) +{ + int input; + + input = open(path, O_RDONLY); + if (input == -1) + return -1; + else { + int value; + read(input, &value, sizeof(value)); + return value; + } +} + + +void +sigsys_handler(int signo) +{ + + did_sigsys = 1; +} + +void +sigchld_handler(int signo) +{ + int c_status; + + did_sigchild = 1; + /* + * Reap the child and return its status + */ + if (wait(&c_status) == -1) + child_status = -errno; + else + child_status = c_status; + + child_count--; +} + +key_t get_ftok(int id) +{ + int fd; + char token_key[64], token_dir[64]; + char *tmpdir; + key_t key; + + strlcpy(token_key, "/tmp/t_sysv.XXXXXX", sizeof(token_key)); + tmpdir = mkdtemp(token_key); + ATF_REQUIRE_MSG(tmpdir != NULL, "mkdtemp() failed: %d", errno); + + strlcpy(token_dir, tmpdir, sizeof(token_dir)); + strlcpy(token_key, tmpdir, sizeof(token_key)); + strlcat(token_key, "/token_key", sizeof(token_key)); + + /* Create the file, since ftok() requires it to exist! */ + + fd = open(token_key, O_RDWR | O_CREAT | O_EXCL); + if (fd == -1) { + rmdir(tmpdir); + atf_tc_fail("open() of temp file failed: %d", errno); + return (key_t)-1; + } else + close(fd); + + key = ftok(token_key, id); + + ATF_REQUIRE_MSG(unlink(token_key) != -1, "unlink() failed: %d", errno); + ATF_REQUIRE_MSG(rmdir(token_dir) != -1, "rmdir() failed: %d", errno); + + return key; +} + +ATF_TC_WITH_CLEANUP(msg); +ATF_TC_HEAD(msg, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "3"); + atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing"); +} + +ATF_TC_BODY(msg, tc) +{ + struct sigaction sa; + struct msqid_ds m_ds; + struct mymsg m; + sigset_t sigmask; + int sender_msqid; + int loop; + int c_status; + + /* + * Install a SIGSYS handler so that we can exit gracefully if + * System V Message Queue support isn't in the kernel. + */ + did_sigsys = 0; + sa.sa_handler = sigsys_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, + "sigaction SIGSYS: %d", errno); + + /* + * Install a SIGCHLD handler to deal with all possible exit + * conditions of the receiver. + */ + did_sigchild = 0; + child_count = 0; + sa.sa_handler = sigchld_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1, + "sigaction SIGCHLD: %d", errno); + + msgkey = get_ftok(4160); + ATF_REQUIRE_MSG(msgkey != (key_t)-1, "get_ftok failed"); + + sender_msqid = msgget(msgkey, IPC_CREAT | 0640); + ATF_REQUIRE_MSG(sender_msqid != -1, "msgget: %d", errno); + write_int("sender_msqid", sender_msqid); + + if (did_sigsys) { + atf_tc_skip("SYSV Message Queue not supported"); + return; + } + + ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1, + "msgctl IPC_STAT 1: %d", errno); + + print_msqid_ds(&m_ds, 0640); + + m_ds.msg_perm.mode = (m_ds.msg_perm.mode & ~0777) | 0600; + + ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_SET, &m_ds) != -1, + "msgctl IPC_SET: %d", errno); + + memset(&m_ds, 0, sizeof(m_ds)); + + ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) != -1, + "msgctl IPC_STAT 2: %d", errno); + + ATF_REQUIRE_MSG((m_ds.msg_perm.mode & 0777) == 0600, + "IPC_SET of mode didn't hold"); + + print_msqid_ds(&m_ds, 0600); + + switch ((child_pid = fork())) { + case -1: + atf_tc_fail("fork: %d", errno); + return; + + case 0: + child_count++; + receiver(); + break; + + default: + break; + } + + for (loop = 0; loop < maxloop; loop++) { + /* + * Send the first message to the receiver and wait for the ACK. + */ + m.mtype = MTYPE_1; + strcpy(m.mtext, m1_str); + ATF_REQUIRE_MSG(msgsnd(sender_msqid, &m, MESSAGE_TEXT_LEN, + 0) != -1, "sender: msgsnd 1: %d", errno); + + ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, MESSAGE_TEXT_LEN, + MTYPE_1_ACK, 0) == MESSAGE_TEXT_LEN, + "sender: msgrcv 1 ack: %d", errno); + + print_msqid_ds(&m_ds, 0600); + + /* + * Send the second message to the receiver and wait for the ACK. + */ + m.mtype = MTYPE_2; + strcpy(m.mtext, m2_str); + ATF_REQUIRE_MSG(msgsnd(sender_msqid, &m, MESSAGE_TEXT_LEN, 0) != -1, + "sender: msgsnd 2: %d", errno); + + ATF_REQUIRE_MSG(msgrcv(sender_msqid, &m, MESSAGE_TEXT_LEN, + MTYPE_2_ACK, 0) == MESSAGE_TEXT_LEN, + "sender: msgrcv 2 ack: %d", errno); + } + + /* + * Wait for child to finish + */ + sigemptyset(&sigmask); + (void) sigsuspend(&sigmask); + + /* + * ...and any other signal is an unexpected error. + */ + if (did_sigchild) { + c_status = child_status; + if (c_status < 0) + atf_tc_fail("waitpid: %d", -c_status); + else if (WIFEXITED(c_status) == 0) + atf_tc_fail("child abnormal exit: %d", c_status); + else if (WEXITSTATUS(c_status) != 0) + atf_tc_fail("c status: %d", WEXITSTATUS(c_status)); + else { + ATF_REQUIRE_MSG(msgctl(sender_msqid, IPC_STAT, &m_ds) + != -1, "msgctl IPC_STAT: %d", errno); + + print_msqid_ds(&m_ds, 0600); + atf_tc_pass(); + } + } else + atf_tc_fail("sender: received unexpected signal"); +} + +ATF_TC_CLEANUP(msg, tc) +{ + int sender_msqid; + + /* + * Remove the message queue if it exists. + */ + sender_msqid = read_int("sender_msqid"); + if (sender_msqid != -1) + if (msgctl(sender_msqid, IPC_RMID, NULL) == -1) + err(1, "msgctl IPC_RMID"); +} + +void +print_msqid_ds(mp, mode) + struct msqid_ds *mp; + mode_t mode; +{ + uid_t uid = geteuid(); + gid_t gid = getegid(); + + printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n", + mp->msg_perm.uid, mp->msg_perm.gid, + mp->msg_perm.cuid, mp->msg_perm.cgid, + mp->msg_perm.mode & 0777); + + printf("qnum %lu, qbytes %lu, lspid %d, lrpid %d\n", + mp->msg_qnum, (u_long)mp->msg_qbytes, mp->msg_lspid, + mp->msg_lrpid); + + printf("stime: %s", ctime(&mp->msg_stime)); + printf("rtime: %s", ctime(&mp->msg_rtime)); + printf("ctime: %s", ctime(&mp->msg_ctime)); + + /* + * Sanity check a few things. + */ + + ATF_REQUIRE_MSG(mp->msg_perm.uid == uid && mp->msg_perm.cuid == uid, + "uid mismatch"); + + ATF_REQUIRE_MSG(mp->msg_perm.gid == gid && mp->msg_perm.cgid == gid, + "gid mismatch"); + + ATF_REQUIRE_MSG((mp->msg_perm.mode & 0777) == mode, "mode mismatch"); +} + +void +receiver() +{ + struct mymsg m; + int msqid, loop; + + if ((msqid = msgget(msgkey, 0)) == -1) + err(1, "receiver: msgget"); + + for (loop = 0; loop < maxloop; loop++) { + /* + * Receive the first message, print it, and send an ACK. + */ + if (msgrcv(msqid, &m, MESSAGE_TEXT_LEN, MTYPE_1, 0) != MESSAGE_TEXT_LEN) + err(1, "receiver: msgrcv 1"); + + printf("%s\n", m.mtext); + if (strcmp(m.mtext, m1_str) != 0) + err(1, "receiver: message 1 data isn't correct"); + + m.mtype = MTYPE_1_ACK; + + if (msgsnd(msqid, &m, MESSAGE_TEXT_LEN, 0) == -1) + err(1, "receiver: msgsnd ack 1"); + + /* + * Receive the second message, print it, and send an ACK. + */ + + if (msgrcv(msqid, &m, MESSAGE_TEXT_LEN, MTYPE_2, 0) != MESSAGE_TEXT_LEN) + err(1, "receiver: msgrcv 2"); + + printf("%s\n", m.mtext); + if (strcmp(m.mtext, m2_str) != 0) + err(1, "receiver: message 2 data isn't correct"); + + m.mtype = MTYPE_2_ACK; + + if (msgsnd(msqid, &m, MESSAGE_TEXT_LEN, 0) == -1) + err(1, "receiver: msgsnd ack 2"); + } + + exit(0); +} + +/* + * Test the SVID-compatible Semaphore facility. + */ + +ATF_TC_WITH_CLEANUP(sem); +ATF_TC_HEAD(sem, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "3"); + atf_tc_set_md_var(tc, "descr", "Checks sysvmsg passing"); +} + +ATF_TC_BODY(sem, tc) +{ + struct sigaction sa; + union semun sun; + struct semid_ds s_ds; + sigset_t sigmask; + int sender_semid; + int i; + int c_status; + + /* + * Install a SIGSYS handler so that we can exit gracefully if + * System V Semaphore support isn't in the kernel. + */ + did_sigsys = 0; + sa.sa_handler = sigsys_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, + "sigaction SIGSYS: %d", errno); + + /* + * Install a SIGCHLD handler to deal with all possible exit + * conditions of the receiver. + */ + did_sigchild = 0; + child_count = 0; + sa.sa_handler = sigchld_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1, + "sigaction SIGCHLD: %d", errno); + + semkey = get_ftok(4160); + ATF_REQUIRE_MSG(semkey != (key_t)-1, "get_ftok failed"); + + sender_semid = semget(semkey, 1, IPC_CREAT | 0640); + ATF_REQUIRE_MSG(sender_semid != -1, "semget: %d", errno); + write_int("sender_semid", sender_semid); + + if (did_sigsys) { + atf_tc_skip("SYSV Semaphore not supported"); + return; + } + + sun.buf = &s_ds; + ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1, + "semctl IPC_STAT: %d", errno); + + print_semid_ds(&s_ds, 0640); + + s_ds.sem_perm.mode = (s_ds.sem_perm.mode & ~0777) | 0600; + + sun.buf = &s_ds; + ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_SET, sun) != -1, + "semctl IPC_SET: %d", errno); + + memset(&s_ds, 0, sizeof(s_ds)); + + sun.buf = &s_ds; + ATF_REQUIRE_MSG(semctl(sender_semid, 0, IPC_STAT, sun) != -1, + "semctl IPC_STAT: %d", errno); + + ATF_REQUIRE_MSG((s_ds.sem_perm.mode & 0777) == 0600, + "IPC_SET of mode didn't hold"); + + print_semid_ds(&s_ds, 0600); + + for (child_count = 0; child_count < 5; child_count++) { + switch ((child_pid = fork())) { + case -1: + atf_tc_fail("fork: %d", errno); + return; + + case 0: + waiter(); + break; + + default: + break; + } + } + + /* + * Wait for all of the waiters to be attempting to acquire the + * semaphore. + */ + for (;;) { + i = semctl(sender_semid, 0, GETNCNT); + if (i == -1) + atf_tc_fail("semctl GETNCNT: %d", i); + if (i == 5) + break; + } + + /* + * Now set the thundering herd in motion by initializing the + * semaphore to the value 1. + */ + sun.val = 1; + ATF_REQUIRE_MSG(semctl(sender_semid, 0, SETVAL, sun) != -1, + "sender: semctl SETVAL to 1: %d", errno); + + /* + * Wait for all children to finish + */ + sigemptyset(&sigmask); + for (;;) { + (void) sigsuspend(&sigmask); + if (did_sigchild) { + c_status = child_status; + if (c_status < 0) + atf_tc_fail("waitpid: %d", -c_status); + else if (WIFEXITED(c_status) == 0) + atf_tc_fail("c abnormal exit: %d", c_status); + else if (WEXITSTATUS(c_status) != 0) + atf_tc_fail("c status: %d", + WEXITSTATUS(c_status)); + else { + sun.buf = &s_ds; + ATF_REQUIRE_MSG(semctl(sender_semid, 0, + IPC_STAT, sun) != -1, + "semctl IPC_STAT: %d", errno); + + print_semid_ds(&s_ds, 0600); + atf_tc_pass(); + } + if (child_count <= 0) + break; + did_sigchild = 0; + } else { + atf_tc_fail("sender: received unexpected signal"); + break; + } + } +} + +ATF_TC_CLEANUP(sem, tc) +{ + int sender_semid; + + /* + * Remove the semaphore if it exists + */ + sender_semid = read_int("sender_semid"); + if (sender_semid != -1) + if (semctl(sender_semid, 0, IPC_RMID) == -1) + err(1, "semctl IPC_RMID"); +} + +void +print_semid_ds(sp, mode) + struct semid_ds *sp; + mode_t mode; +{ + uid_t uid = geteuid(); + gid_t gid = getegid(); + + printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n", + sp->sem_perm.uid, sp->sem_perm.gid, + sp->sem_perm.cuid, sp->sem_perm.cgid, + sp->sem_perm.mode & 0777); + + printf("nsems %u\n", sp->sem_nsems); + + printf("otime: %s", ctime(&sp->sem_otime)); + printf("ctime: %s", ctime(&sp->sem_ctime)); + + /* + * Sanity check a few things. + */ + + ATF_REQUIRE_MSG(sp->sem_perm.uid == uid && sp->sem_perm.cuid == uid, + "uid mismatch"); + + ATF_REQUIRE_MSG(sp->sem_perm.gid == gid && sp->sem_perm.cgid == gid, + "gid mismatch"); + + ATF_REQUIRE_MSG((sp->sem_perm.mode & 0777) == mode, + "mode mismatch %o != %o", (sp->sem_perm.mode & 0777), mode); +} + +void +waiter() +{ + struct sembuf s; + int semid; + + if ((semid = semget(semkey, 1, 0)) == -1) + err(1, "waiter: semget"); + + /* + * Attempt to acquire the semaphore. + */ + s.sem_num = 0; + s.sem_op = -1; + s.sem_flg = SEM_UNDO; + + if (semop(semid, &s, 1) == -1) + err(1, "waiter: semop -1"); + + printf("WOO! GOT THE SEMAPHORE!\n"); + sleep(1); + + /* + * Release the semaphore and exit. + */ + s.sem_num = 0; + s.sem_op = 1; + s.sem_flg = SEM_UNDO; + + if (semop(semid, &s, 1) == -1) + err(1, "waiter: semop +1"); + + exit(0); +} + +/* + * Test the SVID-compatible Shared Memory facility. + */ + +ATF_TC_WITH_CLEANUP(shm); +ATF_TC_HEAD(shm, tc) +{ + + atf_tc_set_md_var(tc, "timeout", "3"); + atf_tc_set_md_var(tc, "descr", "Checks sysv shared memory"); +} + +ATF_TC_BODY(shm, tc) +{ + struct sigaction sa; + struct shmid_ds s_ds; + sigset_t sigmask; + char *shm_buf; + int sender_shmid; + int c_status; + + /* + * Install a SIGSYS handler so that we can exit gracefully if + * System V Shared Memory support isn't in the kernel. + */ + did_sigsys = 0; + sa.sa_handler = sigsys_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + ATF_REQUIRE_MSG(sigaction(SIGSYS, &sa, NULL) != -1, + "sigaction SIGSYS: %d", errno); + + /* + * Install a SIGCHLD handler to deal with all possible exit + * conditions of the sharer. + */ + did_sigchild = 0; + child_count = 0; + sa.sa_handler = sigchld_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + ATF_REQUIRE_MSG(sigaction(SIGCHLD, &sa, NULL) != -1, + "sigaction SIGCHLD: %d", errno); + + pgsize = sysconf(_SC_PAGESIZE); + + shmkey = get_ftok(4160); + ATF_REQUIRE_MSG(shmkey != (key_t)-1, "get_ftok failed"); + + ATF_REQUIRE_MSG((sender_shmid = shmget(shmkey, pgsize, + IPC_CREAT | 0640)) != -1, + "shmget: %d", errno); + write_int("sender_shmid", sender_shmid); + + ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1, + "shmctl IPC_STAT: %d", errno); + + print_shmid_ds(&s_ds, 0640); + + s_ds.shm_perm.mode = (s_ds.shm_perm.mode & ~0777) | 0600; + + ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_SET, &s_ds) != -1, + "shmctl IPC_SET: %d", errno); + + memset(&s_ds, 0, sizeof(s_ds)); + + ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, &s_ds) != -1, + "shmctl IPC_STAT: %d", errno); + + ATF_REQUIRE_MSG((s_ds.shm_perm.mode & 0777) == 0600, + "IPC_SET of mode didn't hold"); + + print_shmid_ds(&s_ds, 0600); + + shm_buf = shmat(sender_shmid, NULL, 0); + ATF_REQUIRE_MSG(shm_buf != (void *) -1, "sender: shmat: %d", errno); + + /* + * Write the test pattern into the shared memory buffer. + */ + strcpy(shm_buf, m2_str); + + switch ((child_pid = fork())) { + case -1: + atf_tc_fail("fork: %d", errno); + return; + + case 0: + sharer(); + break; + + default: + break; + } + + /* + * Wait for child to finish + */ + sigemptyset(&sigmask); + (void) sigsuspend(&sigmask); + + if (did_sigchild) { + c_status = child_status; + if (c_status < 0) + atf_tc_fail("waitpid: %d", -c_status); + else if (WIFEXITED(c_status) == 0) + atf_tc_fail("c abnormal exit: %d", c_status); + else if (WEXITSTATUS(c_status) != 0) + atf_tc_fail("c status: %d", WEXITSTATUS(c_status)); + else { + ATF_REQUIRE_MSG(shmctl(sender_shmid, IPC_STAT, + &s_ds) != -1, + "shmctl IPC_STAT: %d", errno); + + print_shmid_ds(&s_ds, 0600); + atf_tc_pass(); + } + } else + atf_tc_fail("sender: received unexpected signal"); +} + +ATF_TC_CLEANUP(shm, tc) +{ + int sender_shmid; + + /* + * Remove the shared memory area if it exists. + */ + sender_shmid = read_int("sender_shmid"); + if (sender_shmid != -1) + if (shmctl(sender_shmid, IPC_RMID, NULL) == -1) + err(1, "shmctl IPC_RMID"); +} + +void +print_shmid_ds(sp, mode) + struct shmid_ds *sp; + mode_t mode; +{ + uid_t uid = geteuid(); + gid_t gid = getegid(); + + printf("PERM: uid %d, gid %d, cuid %d, cgid %d, mode 0%o\n", + sp->shm_perm.uid, sp->shm_perm.gid, + sp->shm_perm.cuid, sp->shm_perm.cgid, + sp->shm_perm.mode & 0777); + + printf("segsz %lu, lpid %d, cpid %d, nattch %u\n", + (u_long)sp->shm_segsz, sp->shm_lpid, sp->shm_cpid, + sp->shm_nattch); + + printf("atime: %s", ctime(&sp->shm_atime)); + printf("dtime: %s", ctime(&sp->shm_dtime)); + printf("ctime: %s", ctime(&sp->shm_ctime)); + + /* + * Sanity check a few things. + */ + + ATF_REQUIRE_MSG(sp->shm_perm.uid == uid && sp->shm_perm.cuid == uid, + "uid mismatch"); + + ATF_REQUIRE_MSG(sp->shm_perm.gid == gid && sp->shm_perm.cgid == gid, + "gid mismatch"); + + ATF_REQUIRE_MSG((sp->shm_perm.mode & 0777) == mode, "mode mismatch"); +} + +void +sharer() +{ + int shmid; + void *shm_buf; + + shmid = shmget(shmkey, pgsize, 0); + ATF_REQUIRE_MSG(shmid != -1, "receiver: shmget:%d", errno); + + shm_buf = shmat(shmid, NULL, 0); + ATF_REQUIRE_MSG(shm_buf != (void *) -1, "receiver: shmat: %d", errno); + + printf("%s\n", (const char *)shm_buf); + + ATF_REQUIRE_MSG(strcmp((const char *)shm_buf, m2_str) == 0, + "receiver: data isn't correct"); + + exit(0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msg); + ATF_TP_ADD_TC(tp, sem); + ATF_TP_ADD_TC(tp, shm); + + return atf_no_error(); +} + diff --git a/contrib/netbsd-tests/kernel/t_umount.sh b/contrib/netbsd-tests/kernel/t_umount.sh new file mode 100755 index 0000000..b62ba10 --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_umount.sh @@ -0,0 +1,95 @@ +# $NetBSD: t_umount.sh,v 1.5 2010/11/07 17:51:19 jmmv Exp $ +# +# Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +TMPMP=umount-f_mount +TMPIM=umount-f.im + +VND=vnd0 +BVND=/dev/${VND} +CVND=/dev/r${VND} +MPART=a + +atf_test_case umount cleanup +umount_head() +{ + atf_set "descr" "Checks forced unmounting" + atf_set "require.user" "root" +} +umount_body() +{ + cat >disktab <&1" + atf_check -s ne:0 -e ignore -o inline:"cd: can't cd to ..\n" \ + -x "cd .. 2>&1" + + cd "${mydir}" + + test -e "${TMPMP}/under_the_mount" || \ + atf_fail "Original mount point dissapeared!" +} +umount_cleanup() +{ + echo "*** Cleaning up ${TMPMP}, ${TMPIM}." + umount -f "${TMPMP}" + vnconfig -u "${VND}" +} + +atf_init_test_cases() +{ + atf_add_test_case umount +} diff --git a/contrib/netbsd-tests/kernel/t_umountstress.sh b/contrib/netbsd-tests/kernel/t_umountstress.sh new file mode 100755 index 0000000..fd50a1d --- /dev/null +++ b/contrib/netbsd-tests/kernel/t_umountstress.sh @@ -0,0 +1,209 @@ +# $NetBSD: t_umountstress.sh,v 1.5 2013/05/31 14:40:48 gson Exp $ +# +# Copyright (c) 2013 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +TMPMP=umount-stress_mount +TMPIM=umount-stress.im + +VND=vnd0 +BVND=/dev/${VND} +CVND=/dev/r${VND} +MPART=a + +atf_test_case fileop cleanup +fileop_head() +{ + atf_set "descr" "Checks unmounting a filesystem doing file operations" + atf_set "require.user" "root" +} +fileop_body() +{ + cat >disktab <result + exit + fi + done + done + echo 0 >result + ) & + busypid=$! + + while ! test -f result; do + if err=$(umount ${TMPMP} 2>&1); then + kill $busypid + exec 9<&- + wait + atf_fail "Unmount succeeded while busy" + return + fi + + case $err in + *:\ Device\ busy) + ;; + *) + kill $busypid + exec 9<&- + wait + atf_fail "Unmount failed: $err" + return + ;; + esac + done + + exec 9<&- + wait + + rc=`cat result` + rm -f result + + case $rc in + 0) ;; + *) atf_fail "File operation failed" + esac +} +fileop_cleanup() +{ + echo "*** Cleaning up ${TMPMP}, ${TMPIM}." + umount -f "${TMPMP}" + vnconfig -u "${VND}" +} + +atf_test_case mountlist cleanup +mountlist_head() +{ + atf_set "descr" "Checks unmounting a filesystem using mountlist" + atf_set "require.user" "root" +} +mountlist_body() +{ + cat >disktab <result + exit + fi + done + done + echo 0 >result + ) & + busypid=$! + + while ! test -f result; do + if err=$(umount ${TMPMP} 2>&1); then + if ! mount -o async ${BVND}${MPART} ${TMPMP}; then + kill $busypid + exec 9<&- + wait + atf_fail "Remount failed" + return + fi + continue + fi + + case $err in + *:\ Device\ busy) + ;; + *) + kill $busypid + exec 9<&- + wait + atf_fail "Unmount failed: $err" + return + ;; + esac + done + + exec 9<&- + wait + + rc=`cat result` + rm -f result + + case $rc in + 0) ;; + *) atf_fail "Mountlist operation failed" + esac +} +mountlist_cleanup() +{ + echo "*** Cleaning up ${TMPMP}, ${TMPIM}." + umount -f "${TMPMP}" + vnconfig -u "${VND}" +} + +atf_init_test_cases() +{ + atf_add_test_case fileop + atf_add_test_case mountlist +} diff --git a/contrib/netbsd-tests/kernel/tty/t_pr.c b/contrib/netbsd-tests/kernel/tty/t_pr.c new file mode 100644 index 0000000..c590ea5 --- /dev/null +++ b/contrib/netbsd-tests/kernel/tty/t_pr.c @@ -0,0 +1,186 @@ +/* $NetBSD: t_pr.c,v 1.7 2011/04/26 20:42:01 martin Exp $ */ + +/*- + * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Antti Kantee and Martin Husemann . + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +static int +sendsome(int from, int to) +{ + size_t i; + ssize_t cnt; + static const char msg[] = "hello world\n"; + char buf[sizeof(msg)+10]; + + memset(buf, 0, sizeof(buf)); + rump_sys_write(from, msg, strlen(msg)); + cnt = rump_sys_read(to, buf, sizeof(buf)); + if (cnt < (ssize_t)strlen(msg)) { + printf("short message read: %zd chars: \"%s\"\n", cnt, buf); + return 1; + } + for (i = 0; i < sizeof(buf); i++) { + if (buf[i] == '\r' || buf[i] == '\n') { + buf[i] = '\n'; + buf[i+1] = '\0'; + break; + } + } + + return strcmp(buf, msg) != 0; +} + +static int +exercise_ptytty(int master, int slave) +{ + int error, flags; + + /* + * send a few bytes from master to slave and read them back + */ + error = sendsome(master, slave); + if (error) + return error; + + flags = FREAD|FWRITE; + rump_sys_ioctl(master, TIOCFLUSH, &flags); + + /* + * and the same in the other direction + */ + error = sendsome(slave, master); + if (error) + return error; + + flags = FREAD|FWRITE; + rump_sys_ioctl(master, TIOCFLUSH, &flags); + return 0; +} + +ATF_TC(client_first); +ATF_TC_HEAD(client_first, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "test basic tty/pty operation when opening client side first"); +} + +ATF_TC_BODY(client_first, tc) +{ + int master, slave, error, v; + + rump_init(); + slave = rump_sys_open("/dev/ttyp1", O_RDWR|O_NONBLOCK); + ATF_CHECK(slave != -1); + + master = rump_sys_open("/dev/ptyp1", O_RDWR); + ATF_CHECK(master != -1); + + v = 0; + rump_sys_ioctl(slave, FIOASYNC, &v); + error = exercise_ptytty(master, slave); + ATF_CHECK(error == 0); + + rump_sys_close(master); + rump_sys_close(slave); +} + +ATF_TC(master_first); +ATF_TC_HEAD(master_first, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "test basic tty/pty operation when opening master side first"); +} + +ATF_TC_BODY(master_first, tc) +{ + int master, slave, error; + + rump_init(); + master = rump_sys_open("/dev/ptyp1", O_RDWR); + ATF_CHECK(master != -1); + + slave = rump_sys_open("/dev/ttyp1", O_RDWR); + ATF_CHECK(slave != -1); + + error = exercise_ptytty(master, slave); + ATF_CHECK(error == 0); + + rump_sys_close(master); + rump_sys_close(slave); +} + +ATF_TC(ptyioctl); +ATF_TC_HEAD(ptyioctl, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "ioctl on pty with client side not open"); +} + +ATF_TC_BODY(ptyioctl, tc) +{ + struct termios tio; + int fd; + + rump_init(); + fd = rump_sys_open("/dev/ptyp1", O_RDWR); + ATF_CHECK(fd != -1); + + /* + * This used to die with null deref under ptcwakeup() + * atf_tc_expect_signal(-1, "PR kern/40688"); + */ + rump_sys_ioctl(fd, TIOCGETA, &tio); + + rump_sys_close(fd); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ptyioctl); + ATF_TP_ADD_TC(tp, client_first); + ATF_TP_ADD_TC(tp, master_first); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/csu/arch/alpha/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/alpha/h_initfini_align.S new file mode 100644 index 0000000..b4382c1 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/alpha/h_initfini_align.S @@ -0,0 +1,16 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:55 matt Exp $ */ + +#include + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:55 matt Exp $") + +/* + * LINTSTUB: bool check_stack_alignment(void); + */ + +LEAF_NOPROFILE(check_stack_alignment, 0) + ldiq v0, 0 + and sp, 7, t0 + cmoveq t0, 1, v0 + ret +END(check_stack_alignment) diff --git a/contrib/netbsd-tests/lib/csu/arch/arm/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/arm/h_initfini_align.S new file mode 100644 index 0000000..2abc56f --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/arm/h_initfini_align.S @@ -0,0 +1,20 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $ */ + +#include + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $") + +/* + * LINTSTUB: bool check_stack_alignment(void); + */ + +ARM_ENTRY(check_stack_alignment) +#ifdef __ARM_EABI__ + tst sp, #7 +#else + tst sp, #3 +#endif + movne r0, #0 + moveq r0, #1 + RET +END(check_stack_alignment) diff --git a/contrib/netbsd-tests/lib/csu/arch/hppa/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/hppa/h_initfini_align.S new file mode 100644 index 0000000..c297e90 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/hppa/h_initfini_align.S @@ -0,0 +1,12 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/11/15 11:48:30 skrll Exp $ */ + +#include + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/11/15 11:48:30 skrll Exp $") + +LEAF_ENTRY(check_stack_alignment) + extru %sp,31,6,%ret0 + comiclr,<> 0, %ret0, %ret0 + ldi 1,%ret0 + bv,n %r0(%r2) +EXIT(check_stack_alignment) diff --git a/contrib/netbsd-tests/lib/csu/arch/i386/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/i386/h_initfini_align.S new file mode 100644 index 0000000..e212989 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/i386/h_initfini_align.S @@ -0,0 +1,12 @@ +/* $NetBSD: h_initfini_align.S,v 1.2 2010/12/12 18:21:21 joerg Exp $ */ + +#include + +RCSID("$NetBSD: h_initfini_align.S,v 1.2 2010/12/12 18:21:21 joerg Exp $") + +_ENTRY(check_stack_alignment) + movl %esp, %eax + andl $3, %eax + setz %al + movzbl %al, %eax + ret diff --git a/contrib/netbsd-tests/lib/csu/arch/ia64/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/ia64/h_initfini_align.S new file mode 100644 index 0000000..f7612a8 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/ia64/h_initfini_align.S @@ -0,0 +1,37 @@ +/* $NetBSD: h_initfini_align.S,v 1.2 2014/03/16 09:27:04 cherry Exp $ */ + +#include + +RCSID("$NetBSD: h_initfini_align.S,v 1.2 2014/03/16 09:27:04 cherry Exp $") + +ENTRY(check_stack_alignment, 0) + .prologue + .regstk 0, 2, 0, 0 + + alloc loc0 = ar.pfs, 0, 2, 0, 0 + + .body + mov ret0 = 1 + ;; + + /* ar.bsp has an 8-byte alignment requirement */ + mov loc1 = ar.bsp + ;; + + and loc1 = 7, loc1 + ;; + + cmp.eq p1, p0 = 0, loc1 + (p0) mov ret0 = 0 + ;; + + /* sp has a 16-byte alignment requirement */ + (p1) mov loc1 = sp + ;; + (p1) and loc1 = 15, loc1 + ;; + + (p1) cmp.eq p1, p0 = 0, loc1 + (p0) mov ret0 = 0 + + br.ret.sptk.few rp diff --git a/contrib/netbsd-tests/lib/csu/arch/mips/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/mips/h_initfini_align.S new file mode 100644 index 0000000..d6782ac --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/mips/h_initfini_align.S @@ -0,0 +1,19 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $ */ + +#include + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $") + +/* + * LINTSTUB: bool check_stack_alignment(void); + */ + +LEAF_NOPROFILE(check_stack_alignment) +#ifdef __mips_o32 + andi v1,sp,3 +#else + andi v1,sp,7 +#endif + sltiu v0,v1,1 + jr ra +END(check_stack_alignment) diff --git a/contrib/netbsd-tests/lib/csu/arch/powerpc/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/powerpc/h_initfini_align.S new file mode 100644 index 0000000..7abd9ea --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/powerpc/h_initfini_align.S @@ -0,0 +1,17 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $ */ + +#include + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $") + +/* + * LINTSTUB: bool check_stack_alignment(void); + */ + +_ENTRY(check_stack_alignment) + li %r3,0 + andis. %r0,%r1,15 + bnelr %cr0 + li %r3,1 + blr +END(check_stack_alignment) diff --git a/contrib/netbsd-tests/lib/csu/arch/sparc/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/sparc/h_initfini_align.S new file mode 100644 index 0000000..a770d39 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/sparc/h_initfini_align.S @@ -0,0 +1,10 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/12 11:22:26 martin Exp $ */ + +#include + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/12 11:22:26 martin Exp $") + +_ENTRY(check_stack_alignment) + and %sp, 7, %o1 + retl + not %o1, %o0 diff --git a/contrib/netbsd-tests/lib/csu/arch/sparc64/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/sparc64/h_initfini_align.S new file mode 100644 index 0000000..402ceb3 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/sparc64/h_initfini_align.S @@ -0,0 +1,11 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/11/15 20:00:20 martin Exp $ */ + +#include + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/11/15 20:00:20 martin Exp $") + +_ENTRY(check_stack_alignment) + add %sp, BIAS, %o1 + and %o1, 15, %o2 + retl + not %o2, %o0 diff --git a/contrib/netbsd-tests/lib/csu/arch/vax/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/vax/h_initfini_align.S new file mode 100644 index 0000000..a751e1f --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/vax/h_initfini_align.S @@ -0,0 +1,17 @@ +/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $ */ + +#include + +RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $") + +/* + * LINTSTUB: bool check_stack_alignment(void); + */ + +_ENTRY(check_stack_alignment, 0) + clrl %r0 + bitl $3,%sp + bneq 1f + incl %r0 +1: ret +END(check_stack_alignment) diff --git a/contrib/netbsd-tests/lib/csu/arch/x86_64/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/x86_64/h_initfini_align.S new file mode 100644 index 0000000..fbc1e56 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/arch/x86_64/h_initfini_align.S @@ -0,0 +1,13 @@ +/* $NetBSD: h_initfini_align.S,v 1.2 2010/12/12 18:21:21 joerg Exp $ */ + +#include + +RCSID("$NetBSD: h_initfini_align.S,v 1.2 2010/12/12 18:21:21 joerg Exp $") + +_ENTRY(check_stack_alignment) + movl %esp, %eax + andl $15, %eax + subl $8, %eax + sete %al + movzbl %al, %eax + ret diff --git a/contrib/netbsd-tests/lib/csu/dso/h_initfini3_dso.cxx b/contrib/netbsd-tests/lib/csu/dso/h_initfini3_dso.cxx new file mode 100644 index 0000000..ff90ce6 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/dso/h_initfini3_dso.cxx @@ -0,0 +1,37 @@ +#include + +#ifdef CHECK_STACK_ALIGNMENT +#include + +extern "C" int check_stack_alignment(void); +#endif + +class Test2 { +public: + Test2() + { + static const char msg[] = "constructor2 executed\n"; + write(STDOUT_FILENO, msg, sizeof(msg) - 1); +#ifdef CHECK_STACK_ALIGNMENT + if (!check_stack_alignment()) { + static const char msg2[] = "stack unaligned \n"; + write(STDOUT_FILENO, msg2, sizeof(msg2) - 1); + exit(1); + } +#endif + } + ~Test2() + { + static const char msg[] = "destructor2 executed\n"; + write(STDOUT_FILENO, msg, sizeof(msg) - 1); +#ifdef CHECK_STACK_ALIGNMENT + if (!check_stack_alignment()) { + static const char msg2[] = "stack unaligned \n"; + write(STDOUT_FILENO, msg2, sizeof(msg2) - 1); + exit(1); + } +#endif + } +}; + +Test2 test2; diff --git a/contrib/netbsd-tests/lib/csu/h_initfini1.cxx b/contrib/netbsd-tests/lib/csu/h_initfini1.cxx new file mode 100644 index 0000000..d410f70 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/h_initfini1.cxx @@ -0,0 +1,9 @@ +#include + +int +main(void) +{ + static const char msg[] = "main executed\n"; + write(STDOUT_FILENO, msg, sizeof(msg) - 1); + return 0; +} diff --git a/contrib/netbsd-tests/lib/csu/h_initfini3.cxx b/contrib/netbsd-tests/lib/csu/h_initfini3.cxx new file mode 100644 index 0000000..13f54ce --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/h_initfini3.cxx @@ -0,0 +1,22 @@ +#include +#include +#include + +int +main(void) +{ + static const char msg1[] = "main started\n"; + static const char msg2[] = "main after dlopen\n"; + static const char msg3[] = "main terminated\n"; + + void *handle; + + write(STDOUT_FILENO, msg1, sizeof(msg1) - 1); + handle = dlopen("h_initfini3_dso.so", RTLD_NOW | RTLD_LOCAL); + if (handle == NULL) + err(1, "dlopen"); + write(STDOUT_FILENO, msg2, sizeof(msg2) - 1); + dlclose(handle); + write(STDOUT_FILENO, msg3, sizeof(msg3) - 1); + return 0; +} diff --git a/contrib/netbsd-tests/lib/csu/h_initfini_common.cxx b/contrib/netbsd-tests/lib/csu/h_initfini_common.cxx new file mode 100644 index 0000000..dd34983 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/h_initfini_common.cxx @@ -0,0 +1,37 @@ +#include + +#ifdef CHECK_STACK_ALIGNMENT +#include + +extern "C" int check_stack_alignment(void); +#endif + +class Test { +public: + Test() + { + static const char msg[] = "constructor executed\n"; + write(STDOUT_FILENO, msg, sizeof(msg) - 1); +#ifdef CHECK_STACK_ALIGNMENT + if (!check_stack_alignment()) { + static const char msg2[] = "stack unaligned \n"; + write(STDOUT_FILENO, msg2, sizeof(msg2) - 1); + exit(1); + } +#endif + } + ~Test() + { + static const char msg[] = "destructor executed\n"; + write(STDOUT_FILENO, msg, sizeof(msg) - 1); +#ifdef CHECK_STACK_ALIGNMENT + if (!check_stack_alignment()) { + static const char msg2[] = "stack unaligned \n"; + write(STDOUT_FILENO, msg2, sizeof(msg2) - 1); + exit(1); + } +#endif + } +}; + +Test test; diff --git a/contrib/netbsd-tests/lib/csu/t_crt0.sh b/contrib/netbsd-tests/lib/csu/t_crt0.sh new file mode 100755 index 0000000..a36a9b7 --- /dev/null +++ b/contrib/netbsd-tests/lib/csu/t_crt0.sh @@ -0,0 +1,104 @@ +# $NetBSD: t_crt0.sh,v 1.4 2011/12/11 14:57:07 joerg Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case initfini1 +initfini1_head() +{ + atf_set "descr" "Checks support for init/fini sections" +} +initfini1_body() +{ + cat >expout <expout <expout <expout < + +#include +#include + +ATF_TC(check_bt_aton); + +ATF_TC_HEAD(check_bt_aton, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test bt_aton results"); +} + +ATF_TC_BODY(check_bt_aton, tc) +{ + bdaddr_t bdaddr; + + ATF_CHECK_EQ(bt_aton("0a:0b:0c:0d:0e", &bdaddr), 0); + ATF_CHECK_EQ(bt_aton("0a:0b:0c:0d0:0e:0f", &bdaddr), 0); + ATF_CHECK_EQ(bt_aton("0a:0b:0c:0d:0e:0f:00", &bdaddr), 0); + ATF_CHECK_EQ(bt_aton("0a:0b:0c:0d:0e:0f\n", &bdaddr), 0); + ATF_CHECK_EQ(bt_aton(" 0a:0b:0c:0d:0e:0f", &bdaddr), 0); + ATF_CHECK_EQ(bt_aton("0a:0b:0x:0d:0e:0f", &bdaddr), 0); + + ATF_REQUIRE(bt_aton("0a:0b:0c:0d:0e:0f", &bdaddr)); + ATF_CHECK_EQ(bdaddr.b[0], 0x0f); + ATF_CHECK_EQ(bdaddr.b[1], 0x0e); + ATF_CHECK_EQ(bdaddr.b[2], 0x0d); + ATF_CHECK_EQ(bdaddr.b[3], 0x0c); + ATF_CHECK_EQ(bdaddr.b[4], 0x0b); + ATF_CHECK_EQ(bdaddr.b[5], 0x0a); +} + +ATF_TC(check_bt_ntoa); + +ATF_TC_HEAD(check_bt_ntoa, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test bt_ntoa results"); +} + +ATF_TC_BODY(check_bt_ntoa, tc) +{ + bdaddr_t bdaddr = { { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 } }; + + ATF_CHECK_STREQ(bt_ntoa(&bdaddr, NULL), "55:44:33:22:11:00"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_bt_aton); + ATF_TP_ADD_TC(tp, check_bt_ntoa); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_data.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_data.c new file mode 100644 index 0000000..cff6627 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_data.c @@ -0,0 +1,136 @@ +/* $NetBSD: t_sdp_data.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Iain Hibbert. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include + +ATF_TC(check_sdp_data_type); + +ATF_TC_HEAD(check_sdp_data_type, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_data_type results"); +} + +ATF_TC_BODY(check_sdp_data_type, tc) +{ + uint8_t data[] = { + 0x00, // nil + 0x08, 0x00, // uint8 0x00 + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t value; + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UINT8); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_data_size); + +ATF_TC_HEAD(check_sdp_data_size, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_data_size results"); +} + +ATF_TC_BODY(check_sdp_data_size, tc) +{ + uint8_t data[] = { + 0x00, // nil + 0x08, 0x00, // uint8 + 0x11, 0x00, 0x00, // int16 + 0x1a, 0x00, 0x00, 0x00, // uuid32 + 0x00, + 0x28, 0x00, // bool + 0x25, 0x00, // str8(0) + 0x25, 0x02, 0x00, 0x00, // str8(2) + 0x36, 0x00, 0x00, // seq16(0) + 0x3e, 0x00, 0x05, 0x00, // alt16(5) + 0x00, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x00, 0x00, // seq32(0) + 0x00, + 0x47, 0x00, 0x00, 0x00, // url32(7) + 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t value; + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 1); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 2); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 3); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 5); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 2); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 2); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 4); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 3); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 8); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 5); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_size(&value), 12); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_sdp_data_type); + ATF_TP_ADD_TC(tp, check_sdp_data_size); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_get.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_get.c new file mode 100644 index 0000000..3ad8070 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_get.c @@ -0,0 +1,643 @@ +/* $NetBSD: t_sdp_get.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Iain Hibbert. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include + +ATF_TC(check_sdp_get_data); + +ATF_TC_HEAD(check_sdp_get_data, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_data results"); +} + +ATF_TC_BODY(check_sdp_get_data, tc) +{ + uint8_t data[] = { + 0x09, 0x00, 0x00, // uint16 0x0000 + 0x35, 0x05, // seq8(5) + 0x19, 0x00, 0x00, // uuid16 0x0000 + 0x08, 0x00, // uint8 0x00 + 0x36, 0x00, 0x01, // seq16(1) + 0x19, // uint16 /* invalid */ + 0x25, 0x04, 0x54, 0x45, // str8(4) "TEST" + 0x53, 0x54, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t value, seq; + + /* + * sdp_get_data constructs a new sdp_data_t containing + * the next data element, advancing test if successful + */ + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UINT16); + ATF_CHECK_EQ(sdp_data_size(&value), 3); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_SEQ8); + ATF_CHECK_EQ(sdp_data_size(&value), 7); + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_SEQ16); + ATF_CHECK_EQ(sdp_data_size(&value), 4); + ATF_REQUIRE_EQ(sdp_get_seq(&value, &seq), true); + ATF_REQUIRE_EQ(sdp_get_data(&seq, &value), false); /* invalid */ + + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_STR8); + ATF_CHECK_EQ(sdp_data_size(&value), 6); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_attr); + +ATF_TC_HEAD(check_sdp_get_attr, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_attr results"); +} + +ATF_TC_BODY(check_sdp_get_attr, tc) +{ + uint8_t data[] = { + 0x09, 0x00, 0x00, // uint16 0x0000 + 0x35, 0x05, // seq8(5) + 0x19, 0x00, 0x00, // uuid16 0x0000 + 0x08, 0x00, // uint8 0x00 + 0x08, 0x00, // uint8 0x00 + 0x09, 0x00, 0x01, // uint16 0x0001 + 0x19, 0x12, 0x34, // uuid16 0x1234 + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t value; + uint16_t attr; + + /* + * sdp_get_attr expects a UINT16 followed by any data item + * and advances test if successful + */ + ATF_REQUIRE(sdp_get_attr(&test, &attr, &value)); + ATF_CHECK_EQ(attr, 0x0000); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_SEQ8); + ATF_CHECK_EQ(sdp_data_size(&value), 7); + + ATF_REQUIRE_EQ(sdp_get_attr(&test, &attr, &value), false); + ATF_REQUIRE(sdp_get_data(&test, &value)); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UINT8); + ATF_CHECK_EQ(sdp_data_size(&value), 2); + + ATF_REQUIRE(sdp_get_attr(&test, &attr, &value)); + ATF_CHECK_EQ(attr, 0x0001); + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UUID16); + ATF_CHECK_EQ(sdp_data_size(&value), 3); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_uuid); + +ATF_TC_HEAD(check_sdp_get_uuid, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_uuid results"); +} + +ATF_TC_BODY(check_sdp_get_uuid, tc) +{ + uint8_t data[] = { + 0x19, 0x12, 0x34, // uuid16 0x1234 + 0x1a, 0x11, 0x22, 0x33, // uuid32 0x11223344 + 0x44, + 0x00, // nil + 0x1c, // uuid128 0x00112233-4444--5555-6666-778899aabbcc + 0x00, 0x11, 0x22, 0x33, + 0x44, 0x44, 0x55, 0x55, + 0x66, 0x66, 0x77, 0x88, + 0x99, 0xaa, 0xbb, 0xcc, + }; + sdp_data_t test = { data, data + sizeof(data) }; + uuid_t u16 = { + 0x00001234, + 0x0000, + 0x1000, + 0x80, + 0x00, + { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb } + }; + uuid_t u32 = { + 0x11223344, + 0x0000, + 0x1000, + 0x80, + 0x00, + { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb } + }; + uuid_t u128 = { + 0x00112233, + 0x4444, + 0x5555, + 0x66, + 0x66, + { 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc } + }; + sdp_data_t nil; + uuid_t value; + + /* + * sdp_get_uuid expects any UUID type returns the full uuid + * advancing test if successful + */ + ATF_REQUIRE(sdp_get_uuid(&test, &value)); + ATF_CHECK(uuid_equal(&value, &u16, NULL)); + + ATF_REQUIRE(sdp_get_uuid(&test, &value)); + ATF_CHECK(uuid_equal(&value, &u32, NULL)); + + ATF_REQUIRE_EQ(sdp_get_uuid(&test, &value), false); /* not uuid */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_uuid(&test, &value)); + ATF_CHECK(uuid_equal(&value, &u128, NULL)); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_bool); + +ATF_TC_HEAD(check_sdp_get_bool, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_bool results"); +} + +ATF_TC_BODY(check_sdp_get_bool, tc) +{ + uint8_t data[] = { + 0x28, 0x00, // bool false + 0x00, // nil + 0x28, 0x01, // bool true + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t nil; + bool value; + + /* + * sdp_get_bool expects a BOOL type + * advancing test if successful + */ + ATF_REQUIRE(sdp_get_bool(&test, &value)); + ATF_CHECK_EQ(value, false); + + ATF_REQUIRE_EQ(sdp_get_bool(&test, &value), false); /* not bool */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_bool(&test, &value)); + ATF_CHECK_EQ(value, true); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_uint); + +ATF_TC_HEAD(check_sdp_get_uint, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_uint results"); +} + +ATF_TC_BODY(check_sdp_get_uint, tc) +{ + uint8_t data[] = { + 0x08, 0x00, // uint8 0x00 + 0x08, 0xff, // uint8 0xff + 0x09, 0x01, 0x02, // uint16 0x0102 + 0x09, 0xff, 0xff, // uint16 0xffff + 0x00, // nil + 0x0a, 0x01, 0x02, 0x03, // uint32 0x01020304 + 0x04, + 0x0a, 0xff, 0xff, 0xff, // uint32 0xffffffff + 0xff, + 0x0b, 0x01, 0x02, 0x03, // uint64 0x0102030405060708 + 0x04, 0x05, 0x06, 0x07, + 0x08, + 0x0b, 0xff, 0xff, 0xff, // uint64 0xffffffffffffffff + 0xff, 0xff, 0xff, 0xff, + 0xff, + 0x0c, 0x00, 0x00, 0x00, // uint128 0x00000000000000000000000000000000 + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x0c, 0x00, 0x00, 0x00, // uint128 0x00000000000000010000000000000000 + 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x0c, 0x00, 0x00, 0x00, // uint128 0x0000000000000000ffffffffffffffff + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t nil; + uintmax_t value; + + /* + * sdp_get_uint expects any UINT type, advancing test if successful + */ + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, 0x00); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, UINT8_MAX); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, 0x0102); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, UINT16_MAX); + + ATF_REQUIRE_EQ(sdp_get_uint(&test, &value), false); /* not uint */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, 0x01020304); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, UINT32_MAX); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, 0x0102030405060708); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, UINT64_MAX); + + /* + * expected failure is that we cannot decode UINT128 values larger than UINT64 + */ + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, 0x00000000000000000000000000000000); + + ATF_REQUIRE_EQ(sdp_get_uint(&test, &value), false); /* overflow */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_UINT128); + + ATF_REQUIRE(sdp_get_uint(&test, &value)); + ATF_CHECK_EQ(value, UINT64_MAX); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_int); + +ATF_TC_HEAD(check_sdp_get_int, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_int results"); +} + +ATF_TC_BODY(check_sdp_get_int, tc) +{ + uint8_t data[] = { + 0x10, 0x00, // int8 0x00 + 0x10, 0x7f, // int8 0x7f + 0x10, 0x80, // int8 0x80 + 0x11, 0x01, 0x02, // int16 0x0102 + 0x11, 0x7f, 0xff, // int16 0x7fff + 0x11, 0x80, 0x00, // int16 0x8000 + 0x00, // nil + 0x12, 0x01, 0x02, 0x03, // int32 0x01020304 + 0x04, + 0x12, 0x7f, 0xff, 0xff, // int32 0x7fffffff + 0xff, + 0x12, 0x80, 0x00, 0x00, // int32 0x80000000 + 0x00, + 0x13, 0x01, 0x02, 0x03, // int64 0x0102030405060708 + 0x04, 0x05, 0x06, 0x07, + 0x08, + 0x13, 0x7f, 0xff, 0xff, // int64 0x7fffffffffffffff + 0xff, 0xff, 0xff, 0xff, + 0xff, + 0x13, 0x80, 0x00, 0x00, // int64 0x8000000000000000 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x14, 0x00, 0x00, 0x00, // int128 0x00000000000000000000000000000000 + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x14, 0x00, 0x00, 0x00, // int128 0x00000000000000007fffffffffffffff + 0x00, 0x00, 0x00, 0x00, // (INT64_MAX) + 0x00, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, + 0x14, 0x00, 0x00, 0x00, // int128 0x00000000000000008000000000000000 + 0x00, 0x00, 0x00, 0x00, // (INT64_MAX + 1) + 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x14, 0xff, 0xff, 0xff, // int128 0xffffffffffffffff8000000000000000 + 0xff, 0xff, 0xff, 0xff, // (INT64_MIN) + 0xff, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x14, 0xff, 0xff, 0xff, // int128 0xffffffffffffffff7fffffffffffffff + 0xff, 0xff, 0xff, 0xff, // (INT64_MIN - 1) + 0xff, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t nil; + intmax_t value; + + /* + * sdp_get_int expects any INT type, advancing test if successful + */ + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, 0); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT8_MAX); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT8_MIN); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, 0x0102); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT16_MAX); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT16_MIN); + + ATF_REQUIRE_EQ(sdp_get_int(&test, &value), false); /* not int */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, 0x01020304); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT32_MAX); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT32_MIN); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, 0x0102030405060708); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT64_MAX); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT64_MIN); + + /* + * expected failure is that we cannot decode INT128 values larger than INT64 + */ + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, 0); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT64_MAX); + + ATF_REQUIRE_EQ(sdp_get_int(&test, &value), false); /* overflow */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_INT128); + + ATF_REQUIRE(sdp_get_int(&test, &value)); + ATF_CHECK_EQ(value, INT64_MIN); + + ATF_REQUIRE_EQ(sdp_get_int(&test, &value), false); /* underflow */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_INT128); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_seq); + +ATF_TC_HEAD(check_sdp_get_seq, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_seq results"); +} + +ATF_TC_BODY(check_sdp_get_seq, tc) +{ + uint8_t data[] = { + 0x35, 0x00, // seq8(0) + 0x00, // nil + 0x36, 0x00, 0x00, // seq16(0) + 0x37, 0x00, 0x00, 0x00, // seq32(0) + 0x00, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t value; + + /* + * sdp_get_seq expects a SEQ type + * advancing test if successful + */ + ATF_REQUIRE(sdp_get_seq(&test, &value)); + ATF_CHECK_EQ(value.next, value.end); + + ATF_REQUIRE_EQ(sdp_get_seq(&test, &value), false); /* not seq */ + ATF_REQUIRE(sdp_get_data(&test, &value)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_seq(&test, &value)); + ATF_CHECK_EQ(value.next, value.end); + + ATF_REQUIRE(sdp_get_seq(&test, &value)); + ATF_CHECK_EQ(value.next, value.end); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_alt); + +ATF_TC_HEAD(check_sdp_get_alt, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_alt results"); +} + +ATF_TC_BODY(check_sdp_get_alt, tc) +{ + uint8_t data[] = { + 0x3d, 0x00, // alt8(0) + 0x00, // nil + 0x3e, 0x00, 0x00, // alt16(0) + 0x3f, 0x00, 0x00, 0x00, // alt32(0) + 0x00, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t value; + + /* + * sdp_get_alt expects a ALT type + * advancing test if successful + */ + ATF_REQUIRE(sdp_get_alt(&test, &value)); + ATF_CHECK_EQ(value.next, value.end); + + ATF_REQUIRE_EQ(sdp_get_alt(&test, &value), false); /* not alt */ + ATF_REQUIRE(sdp_get_data(&test, &value)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_alt(&test, &value)); + ATF_CHECK_EQ(value.next, value.end); + + ATF_REQUIRE(sdp_get_alt(&test, &value)); + ATF_CHECK_EQ(value.next, value.end); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_str); + +ATF_TC_HEAD(check_sdp_get_str, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_str results"); +} + +ATF_TC_BODY(check_sdp_get_str, tc) +{ + uint8_t data[] = { + 0x25, 0x04, 0x53, 0x54, // str8(4) "STR8" + 0x52, 0x38, + 0x00, // nil + 0x26, 0x00, 0x05, 0x53, // str16(5) "STR16" + 0x54, 0x52, 0x31, 0x36, + 0x27, 0x00, 0x00, 0x00, // str32(5) "STR32" + 0x05, 0x53, 0x54, 0x52, + 0x33, 0x32, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t nil; + char *str; + size_t len; + + /* + * sdp_get_str expects a STR type + * advancing test if successful + */ + ATF_REQUIRE(sdp_get_str(&test, &str, &len)); + ATF_CHECK(len == 4 && strncmp(str, "STR8", 4) == 0); + + ATF_REQUIRE_EQ(sdp_get_str(&test, &str, &len), false); /* not str */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_str(&test, &str, &len)); + ATF_CHECK(len == 5 && strncmp(str, "STR16", 5) == 0); + + ATF_REQUIRE(sdp_get_str(&test, &str, &len)); + ATF_CHECK(len == 5 && strncmp(str, "STR32", 5) == 0); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TC(check_sdp_get_url); + +ATF_TC_HEAD(check_sdp_get_url, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_get_url results"); +} + +ATF_TC_BODY(check_sdp_get_url, tc) +{ + uint8_t data[] = { + 0x45, 0x04, 0x55, 0x52, // url8(4) "URL8" + 0x4c, 0x38, + 0x00, // nil + 0x46, 0x00, 0x05, 0x55, // url16(5) "URL16" + 0x52, 0x4c, 0x31, 0x36, + 0x47, 0x00, 0x00, 0x00, // url32(5) "URL32" + 0x05, 0x55, 0x52, 0x4c, + 0x33, 0x32, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t nil; + char *url; + size_t len; + + /* + * sdp_get_url expects a URL type + * advancing test if successful + */ + ATF_REQUIRE(sdp_get_url(&test, &url, &len)); + ATF_CHECK(len == 4 && strncmp(url, "URL8", 4) == 0); + + ATF_REQUIRE_EQ(sdp_get_url(&test, &url, &len), false); /* not url */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + + ATF_REQUIRE(sdp_get_url(&test, &url, &len)); + ATF_CHECK(len == 5 && strncmp(url, "URL16", 5) == 0); + + ATF_REQUIRE(sdp_get_url(&test, &url, &len)); + ATF_CHECK(len == 5 && strncmp(url, "URL32", 5) == 0); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_sdp_get_data); + ATF_TP_ADD_TC(tp, check_sdp_get_attr); + ATF_TP_ADD_TC(tp, check_sdp_get_uuid); + ATF_TP_ADD_TC(tp, check_sdp_get_bool); + ATF_TP_ADD_TC(tp, check_sdp_get_uint); + ATF_TP_ADD_TC(tp, check_sdp_get_int); + ATF_TP_ADD_TC(tp, check_sdp_get_seq); + ATF_TP_ADD_TC(tp, check_sdp_get_alt); + ATF_TP_ADD_TC(tp, check_sdp_get_str); + ATF_TP_ADD_TC(tp, check_sdp_get_url); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_match.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_match.c new file mode 100644 index 0000000..54a5bd5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_match.c @@ -0,0 +1,87 @@ +/* $NetBSD: t_sdp_match.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Iain Hibbert. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include + +ATF_TC(check_sdp_match_uuid16); + +ATF_TC_HEAD(check_sdp_match_uuid16, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_match_uuid16 results"); +} + +ATF_TC_BODY(check_sdp_match_uuid16, tc) +{ + uint8_t data[] = { + 0x19, 0x11, 0x11, // uuid16 0x1111 + 0x00, // nil + 0x19, 0x12, 0x34, // uuid16 0x1234 + 0x1a, 0x00, 0x00, 0x34, // uuid32 0x00003456 + 0x56, + 0x1c, 0x00, 0x00, 0x43, // uuid128 00004321-0000-1000-8000-00805f9b34fb + 0x21, 0x00, 0x00, 0x10, + 0x00, 0x80, 0x00, 0x00, + 0x80, 0x5f, 0x9b, 0x34, + 0xfb, + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t nil; + + /* + * sdp_match_uuid16 advances if the UUID matches the 16-bit short alias given + */ + + ATF_REQUIRE_EQ(sdp_match_uuid16(&test, 0x1100), false); /* mismatch */ + ATF_REQUIRE(sdp_match_uuid16(&test, 0x1111)); + + ATF_REQUIRE_EQ(sdp_match_uuid16(&test, 0x1234), false); /* not uuid */ + ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */ + ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL); + ATF_REQUIRE(sdp_match_uuid16(&test, 0x1234)); + + ATF_REQUIRE(sdp_match_uuid16(&test, 0x3456)); + + ATF_REQUIRE_EQ(sdp_match_uuid16(&test, 0x1234), false); /* mismatch */ + ATF_REQUIRE(sdp_match_uuid16(&test, 0x4321)); + + ATF_CHECK_EQ(test.next, test.end); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_sdp_match_uuid16); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_put.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_put.c new file mode 100644 index 0000000..fff4119 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_put.c @@ -0,0 +1,875 @@ +/* $NetBSD: t_sdp_put.c,v 1.3 2011/04/16 07:32:27 plunky Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Iain Hibbert. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include + +ATF_TC(check_sdp_put_data); + +ATF_TC_HEAD(check_sdp_put_data, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_data results"); +} + +ATF_TC_BODY(check_sdp_put_data, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + uint8_t data[] = { + 0x35, 0x05, // seq8(5) + 0x08, 0x00, // uint8 0x00 + 0x09, 0x12, 0x34, // uint16 0x1234 + }; + sdp_data_t value = { data, data + sizeof(data) }; + + ATF_REQUIRE(sdp_put_data(&test, &value)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x35, 0x05, // seq8(5) + 0x08, 0x00, // uint8 0x00 + 0x09, 0x12, 0x34, // uint16 0x1234 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_attr); + +ATF_TC_HEAD(check_sdp_put_attr, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_attr results"); +} + +ATF_TC_BODY(check_sdp_put_attr, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + uint8_t data[] = { + 0x00, // nil + 0x19, 0x33, 0x44, // uuid16 0x3344 + }; + sdp_data_t value = { data, data + sizeof(data) }; + + ATF_REQUIRE_EQ(sdp_put_attr(&test, 0xabcd, &value), false); + value.next += 1; // skip "nil" + ATF_REQUIRE(sdp_put_attr(&test, 0x1337, &value)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x09, 0x13, 0x37, // uint16 0x1337 + 0x19, 0x33, 0x44, // uuid16 0x3344 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uuid); + +ATF_TC_HEAD(check_sdp_put_uuid, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uuid results"); +} + +ATF_TC_BODY(check_sdp_put_uuid, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + const uuid_t u16 = { + 0x00001234, + 0x0000, + 0x1000, + 0x80, + 0x00, + { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb } + }; + const uuid_t u32 = { + 0x12345678, + 0x0000, + 0x1000, + 0x80, + 0x00, + { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb } + }; + const uuid_t u128 = { + 0x00112233, + 0x4444, + 0x5555, + 0x66, + 0x77, + { 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd } + }; + + ATF_REQUIRE(sdp_put_uuid(&test, &u16)); + ATF_REQUIRE(sdp_put_uuid(&test, &u32)); + ATF_REQUIRE(sdp_put_uuid(&test, &u128)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x19, 0x12, 0x34, // uuid16 0x1234 + 0x1a, 0x12, 0x34, 0x56, // uuid32 0x12345678 + 0x78, + 0x1c, 0x00, 0x11, 0x22, // uuid128 00112233-4444-5555-6677-8899aabbccdd + 0x33, 0x44, 0x44, 0x55, + 0x55, 0x66, 0x77, 0x88, + 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uuid16); + +ATF_TC_HEAD(check_sdp_put_uuid16, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uuid16 results"); +} + +ATF_TC_BODY(check_sdp_put_uuid16, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uuid16(&test, 0x4567)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x19, 0x45, 0x67, // uuid16 0x4567 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uuid32); + +ATF_TC_HEAD(check_sdp_put_uuid32, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uuid32 results"); +} + +ATF_TC_BODY(check_sdp_put_uuid32, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uuid32(&test, 0xabcdef00)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x1a, 0xab, 0xcd, 0xef, // uuid32 0xabcdef00 + 0x00, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uuid128); + +ATF_TC_HEAD(check_sdp_put_uuid128, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uuid128 results"); +} + +ATF_TC_BODY(check_sdp_put_uuid128, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + uuid_t value = { + 0x00000100, + 0x0000, + 0x1000, + 0x80, + 0x00, + { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb } + }; + + ATF_REQUIRE(sdp_put_uuid128(&test, &value)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x1c, 0x00, 0x00, 0x01, // uuid128 0000100-0000-1000-8000-00805f9b34fb + 0x00, 0x00, 0x00, 0x10, // (L2CAP protocol) + 0x00, 0x80, 0x00, 0x00, + 0x80, 0x5f, 0x9b, 0x34, + 0xfb, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_bool); + +ATF_TC_HEAD(check_sdp_put_bool, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_bool results"); +} + +ATF_TC_BODY(check_sdp_put_bool, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_bool(&test, true)); + ATF_REQUIRE(sdp_put_bool(&test, false)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x28, 0x01, // bool true + 0x28, 0x00, // bool false + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uint); + +ATF_TC_HEAD(check_sdp_put_uint, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint results"); +} + +ATF_TC_BODY(check_sdp_put_uint, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)0)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT8_MAX)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT8_MAX + 1)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT16_MAX)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT16_MAX + 1)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT32_MAX)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT32_MAX + 1)); + ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT64_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x08, 0x00, // uint8 0x00 + 0x08, 0xff, // uint8 0xff + 0x09, 0x01, 0x00, // uint16 0x0100 + 0x09, 0xff, 0xff, // uint16 0xffff + 0x0a, 0x00, 0x01, 0x00, // uint32 0x00010000 + 0x00, + 0x0a, 0xff, 0xff, 0xff, // uint32 0xffffffff + 0xff, + 0x0b, 0x00, 0x00, 0x00, // uint64 0x0000000100000000 + 0x01, 0x00, 0x00, 0x00, + 0x00, + 0x0b, 0xff, 0xff, 0xff, // uint64 0xffffffffffffffff + 0xff, 0xff, 0xff, 0xff, + 0xff, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uint8); + +ATF_TC_HEAD(check_sdp_put_uint8, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint8 results"); +} + +ATF_TC_BODY(check_sdp_put_uint8, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uint8(&test, (uint8_t)0)); + ATF_REQUIRE(sdp_put_uint8(&test, (uint8_t)UINT8_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x08, 0x00, // uint8 0x00 + 0x08, 0xff, // uint8 0xff + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uint16); + +ATF_TC_HEAD(check_sdp_put_uint16, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint16 results"); +} + +ATF_TC_BODY(check_sdp_put_uint16, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uint16(&test, (uint16_t)0)); + ATF_REQUIRE(sdp_put_uint16(&test, (uint16_t)UINT8_MAX)); + ATF_REQUIRE(sdp_put_uint16(&test, (uint16_t)UINT16_MAX)); + ATF_REQUIRE(sdp_put_uint16(&test, (uint16_t)0xabcd)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x09, 0x00, 0x00, // uint16 0x0000 + 0x09, 0x00, 0xff, // uint16 0x00ff + 0x09, 0xff, 0xff, // uint16 0xffff + 0x09, 0xab, 0xcd, // uint16 0xabcd + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uint32); + +ATF_TC_HEAD(check_sdp_put_uint32, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint32 results"); +} + +ATF_TC_BODY(check_sdp_put_uint32, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)0)); + ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)UINT8_MAX)); + ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)UINT16_MAX)); + ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)UINT32_MAX)); + ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)0xdeadbeef)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000000 + 0x00, + 0x0a, 0x00, 0x00, 0x00, // uint32 0x000000ff + 0xff, + 0x0a, 0x00, 0x00, 0xff, // uint32 0x0000ffff + 0xff, + 0x0a, 0xff, 0xff, 0xff, // uint32 0xffffffff + 0xff, + 0x0a, 0xde, 0xad, 0xbe, // uint32 0xdeadbeef + 0xef, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_uint64); + +ATF_TC_HEAD(check_sdp_put_uint64, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint64 results"); +} + +ATF_TC_BODY(check_sdp_put_uint64, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)0)); + ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)UINT8_MAX)); + ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)UINT16_MAX)); + ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)UINT32_MAX)); + ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)UINT64_MAX)); + ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)0xc0ffeecafec0ffee)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x0b, 0x00, 0x00, 0x00, // uint64 0x0000000000000000 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x0b, 0x00, 0x00, 0x00, // uint64 0x00000000000000ff + 0x00, 0x00, 0x00, 0x00, + 0xff, + 0x0b, 0x00, 0x00, 0x00, // uint64 0x000000000000ffff + 0x00, 0x00, 0x00, 0xff, + 0xff, + 0x0b, 0x00, 0x00, 0x00, // uint64 0x00000000ffffffff + 0x00, 0xff, 0xff, 0xff, + 0xff, + 0x0b, 0xff, 0xff, 0xff, // uint64 0xffffffffffffffff + 0xff, 0xff, 0xff, 0xff, + 0xff, + 0x0b, 0xc0, 0xff, 0xee, // uint64 0xc0ffeecafec0ffee + 0xca, 0xfe, 0xc0, 0xff, + 0xee, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_int); + +ATF_TC_HEAD(check_sdp_put_int, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_int results"); +} + +ATF_TC_BODY(check_sdp_put_int, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)0)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT8_MIN)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT8_MAX)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT8_MIN - 1)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT8_MAX + 1)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT16_MIN)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT16_MAX)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT16_MIN - 1)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT16_MAX + 1)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT32_MIN)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT32_MAX)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT32_MIN - 1)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT32_MAX + 1)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT64_MIN)); + ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT64_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x10, 0x00, // int8 0 + 0x10, 0x80, // int8 -128 + 0x10, 0x7f, // int8 127 + 0x11, 0xff, 0x7f, // int16 -129 + 0x11, 0x00, 0x80, // int16 128 + 0x11, 0x80, 0x00, // int16 -32768 + 0x11, 0x7f, 0xff, // int16 32767 + 0x12, 0xff, 0xff, 0x7f, // int32 -32769 + 0xff, + 0x12, 0x00, 0x00, 0x80, // int32 32768 + 0x00, + 0x12, 0x80, 0x00, 0x00, // int32 -2147483648 + 0x00, + 0x12, 0x7f, 0xff, 0xff, // int32 2147483647 + 0xff, + 0x13, 0xff, 0xff, 0xff, // int64 -2147483649 + 0xff, 0x7f, 0xff, 0xff, + 0xff, + 0x13, 0x00, 0x00, 0x00, // int64 2147483648 + 0x00, 0x80, 0x00, 0x00, + 0x00, + 0x13, 0x80, 0x00, 0x00, // int64 -9223372036854775808 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x13, 0x7f, 0xff, 0xff, // int64 9223372036854775807 + 0xff, 0xff, 0xff, 0xff, + 0xff, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_int8); + +ATF_TC_HEAD(check_sdp_put_int8, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_int8 results"); +} + +ATF_TC_BODY(check_sdp_put_int8, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_int8(&test, (int8_t)0)); + ATF_REQUIRE(sdp_put_int8(&test, (int8_t)INT8_MIN)); + ATF_REQUIRE(sdp_put_int8(&test, (int8_t)INT8_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x10, 0x00, // int8 0 + 0x10, 0x80, // int8 -128 + 0x10, 0x7f, // int8 127 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_int16); + +ATF_TC_HEAD(check_sdp_put_int16, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_int16 results"); +} + +ATF_TC_BODY(check_sdp_put_int16, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_int16(&test, (int16_t)0)); + ATF_REQUIRE(sdp_put_int16(&test, (int16_t)INT8_MIN)); + ATF_REQUIRE(sdp_put_int16(&test, (int16_t)INT8_MAX)); + ATF_REQUIRE(sdp_put_int16(&test, (int16_t)INT16_MIN)); + ATF_REQUIRE(sdp_put_int16(&test, (int16_t)INT16_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x11, 0x00, 0x00, // int16 0 + 0x11, 0xff, 0x80, // int16 -128 + 0x11, 0x00, 0x7f, // int16 127 + 0x11, 0x80, 0x00, // int16 -32768 + 0x11, 0x7f, 0xff, // int16 32767 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_int32); + +ATF_TC_HEAD(check_sdp_put_int32, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_int32 results"); +} + +ATF_TC_BODY(check_sdp_put_int32, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)0)); + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT8_MIN)); + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT8_MAX)); + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT16_MIN)); + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT16_MAX)); + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT32_MIN)); + ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT32_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x12, 0x00, 0x00, 0x00, // int32 0 + 0x00, + 0x12, 0xff, 0xff, 0xff, // int32 -128 + 0x80, + 0x12, 0x00, 0x00, 0x00, // int32 127 + 0x7f, + 0x12, 0xff, 0xff, 0x80, // int32 -32768 + 0x00, + 0x12, 0x00, 0x00, 0x7f, // int32 32767 + 0xff, + 0x12, 0x80, 0x00, 0x00, // int32 -2147483648 + 0x00, + 0x12, 0x7f, 0xff, 0xff, // int32 2147483647 + 0xff, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_int64); + +ATF_TC_HEAD(check_sdp_put_int64, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_int64 results"); +} + +ATF_TC_BODY(check_sdp_put_int64, tc) +{ + uint8_t buf[256]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)0)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT8_MIN)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT8_MAX)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT16_MIN)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT16_MAX)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT32_MIN)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT32_MAX)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT64_MIN)); + ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT64_MAX)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x13, 0x00, 0x00, 0x00, // int64 0 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x13, 0xff, 0xff, 0xff, // int64 -128 + 0xff, 0xff, 0xff, 0xff, + 0x80, + 0x13, 0x00, 0x00, 0x00, // int64 127 + 0x00, 0x00, 0x00, 0x00, + 0x7f, + 0x13, 0xff, 0xff, 0xff, // int64 -32768 + 0xff, 0xff, 0xff, 0x80, + 0x00, + 0x13, 0x00, 0x00, 0x00, // int64 32767 + 0x00, 0x00, 0x00, 0x7f, + 0xff, + 0x13, 0xff, 0xff, 0xff, // int64 -2147483648 + 0xff, 0x80, 0x00, 0x00, + 0x00, + 0x13, 0x00, 0x00, 0x00, // int64 2147483647 + 0x00, 0x7f, 0xff, 0xff, + 0xff, + 0x13, 0x80, 0x00, 0x00, // int64 -9223372036854775808 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x13, 0x7f, 0xff, 0xff, // int64 9223372036854775807 + 0xff, 0xff, 0xff, 0xff, + 0xff, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_seq); + +ATF_TC_HEAD(check_sdp_put_seq, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_seq results"); +} + +ATF_TC_BODY(check_sdp_put_seq, tc) +{ + uint8_t buf[512]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_seq(&test, (ssize_t)0)); + ATF_REQUIRE(sdp_put_seq(&test, (ssize_t)UINT8_MAX)); + ATF_REQUIRE(sdp_put_seq(&test, (ssize_t)UINT8_MAX + 1)); + ATF_REQUIRE(sdp_put_seq(&test, (ssize_t)-1)); + ATF_CHECK_EQ(sdp_put_seq(&test, (ssize_t)UINT16_MAX), false); /* no room */ + ATF_CHECK_EQ(sdp_put_seq(&test, (ssize_t)SSIZE_MAX), false); /* no room */ + test.end = test.next; + test.next = buf; + + /* (not a valid element list) */ + const uint8_t expect[] = { + 0x35, 0x00, // seq8(0) + 0x35, 0xff, // seq8(255) + 0x36, 0x01, 0x00, // seq16(256) + 0x36, 0x01, 0xf6, // seq16(502) <- sizeof(buf) - 7 - 3 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_alt); + +ATF_TC_HEAD(check_sdp_put_alt, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_alt results"); +} + +ATF_TC_BODY(check_sdp_put_alt, tc) +{ + uint8_t buf[512]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + ATF_REQUIRE(sdp_put_alt(&test, (ssize_t)0)); + ATF_REQUIRE(sdp_put_alt(&test, (ssize_t)UINT8_MAX)); + ATF_REQUIRE(sdp_put_alt(&test, (ssize_t)UINT8_MAX + 1)); + ATF_REQUIRE(sdp_put_alt(&test, (ssize_t)-1)); + ATF_CHECK_EQ(sdp_put_alt(&test, (ssize_t)UINT16_MAX), false); /* no room */ + ATF_CHECK_EQ(sdp_put_alt(&test, (ssize_t)SSIZE_MAX), false); /* no room */ + test.end = test.next; + test.next = buf; + + /* (not a valid element list) */ + const uint8_t expect[] = { + 0x3d, 0x00, // alt8(0) + 0x3d, 0xff, // alt8(255) + 0x3e, 0x01, 0x00, // alt16(256) + 0x3e, 0x01, 0xf6, // alt16(502) <- sizeof(buf) - 7 - 3 + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_str); + +ATF_TC_HEAD(check_sdp_put_str, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_str results"); +} + +ATF_TC_BODY(check_sdp_put_str, tc) +{ + uint8_t buf[512]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + /* + * this does not test str16 or str32, but that is + * handled by the same code as sdp_put_seq above.. + */ + + ATF_REQUIRE(sdp_put_str(&test, "Hello World!", 5)); + ATF_REQUIRE(sdp_put_str(&test, "Hello\0World", 11)); + ATF_REQUIRE(sdp_put_str(&test, "Hello World!", -1)); + ATF_REQUIRE(sdp_put_str(&test, "Hello\0World", -1)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x25, 0x05, 0x48, 0x65, // str8 "Hello" + 0x6c, 0x6c, 0x6f, + 0x25, 0x0b, 0x48, 0x65, // str8 "Hello\0World" + 0x6c, 0x6c, 0x6f, 0x00, + 0x57, 0x6f, 0x72, 0x6c, + 0x64, + 0x25, 0x0c, 0x48, 0x65, // str8 "Hello World!" + 0x6c, 0x6c, 0x6f, 0x20, + 0x57, 0x6f, 0x72, 0x6c, + 0x64, 0x21, + 0x25, 0x05, 0x48, 0x65, // str8 "Hello" + 0x6c, 0x6c, 0x6f, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_put_url); + +ATF_TC_HEAD(check_sdp_put_url, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_put_url results"); +} + +ATF_TC_BODY(check_sdp_put_url, tc) +{ + uint8_t buf[512]; + sdp_data_t test = { buf, buf + sizeof(buf) }; + + /* + * this does not test url16 or url32, but that is + * handled by the same code as sdp_put_seq above.. + */ + + ATF_REQUIRE(sdp_put_url(&test, "http://www.netbsd.org/", 21)); + ATF_REQUIRE(sdp_put_url(&test, "http://www.netbsd.org/", -1)); + test.end = test.next; + test.next = buf; + + const uint8_t expect[] = { + 0x45, 0x15, 0x68, 0x74, // url8 "http://www.netbsd.org" + 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, + 0x2e, 0x6e, 0x65, 0x74, + 0x62, 0x73, 0x64, 0x2e, + 0x6f, 0x72, 0x67, + 0x45, 0x16, 0x68, 0x74, // url8 "http://www.netbsd.org/" + 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, + 0x2e, 0x6e, 0x65, 0x74, + 0x62, 0x73, 0x64, 0x2e, + 0x6f, 0x72, 0x67, 0x2f, + }; + + ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect)); + ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_sdp_put_data); + ATF_TP_ADD_TC(tp, check_sdp_put_attr); + ATF_TP_ADD_TC(tp, check_sdp_put_uuid); + ATF_TP_ADD_TC(tp, check_sdp_put_uuid16); + ATF_TP_ADD_TC(tp, check_sdp_put_uuid32); + ATF_TP_ADD_TC(tp, check_sdp_put_uuid128); + ATF_TP_ADD_TC(tp, check_sdp_put_bool); + ATF_TP_ADD_TC(tp, check_sdp_put_uint); + ATF_TP_ADD_TC(tp, check_sdp_put_uint8); + ATF_TP_ADD_TC(tp, check_sdp_put_uint16); + ATF_TP_ADD_TC(tp, check_sdp_put_uint32); + ATF_TP_ADD_TC(tp, check_sdp_put_uint64); + ATF_TP_ADD_TC(tp, check_sdp_put_int); + ATF_TP_ADD_TC(tp, check_sdp_put_int8); + ATF_TP_ADD_TC(tp, check_sdp_put_int16); + ATF_TP_ADD_TC(tp, check_sdp_put_int32); + ATF_TP_ADD_TC(tp, check_sdp_put_int64); + ATF_TP_ADD_TC(tp, check_sdp_put_seq); + ATF_TP_ADD_TC(tp, check_sdp_put_alt); + ATF_TP_ADD_TC(tp, check_sdp_put_str); + ATF_TP_ADD_TC(tp, check_sdp_put_url); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_set.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_set.c new file mode 100644 index 0000000..be5d953 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_set.c @@ -0,0 +1,359 @@ +/* $NetBSD: t_sdp_set.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Iain Hibbert. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include + +ATF_TC(check_sdp_set_bool); + +ATF_TC_HEAD(check_sdp_set_bool, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_set_bool results"); +} + +ATF_TC_BODY(check_sdp_set_bool, tc) +{ + uint8_t data[] = { + 0x28, 0x00, // bool false + 0x00, // nil + 0x28, // bool + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t discard; + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_BOOL); + ATF_REQUIRE(sdp_set_bool(&test, true)); + ATF_CHECK_EQ(test.next[1], 0x01); + ATF_REQUIRE(sdp_set_bool(&test, false)); + ATF_CHECK_EQ(test.next[1], 0x00); + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_NIL); + ATF_CHECK_EQ(sdp_set_bool(&test, true), false); /* not bool */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_BOOL); + ATF_CHECK_EQ(sdp_set_bool(&test, true), false); /* no value */ +} + +ATF_TC(check_sdp_set_uint); + +ATF_TC_HEAD(check_sdp_set_uint, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_set_uint results"); +} + +ATF_TC_BODY(check_sdp_set_uint, tc) +{ + uint8_t data[] = { + 0x08, 0x00, // uint8 0x00 + 0x00, // nil + 0x09, 0x00, 0x00, // uint16 0x0000 + 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000000 + 0x00, + 0x0b, 0x00, 0x00, 0x00, // uint64 0x0000000000000000 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x0c, 0x00, 0x44, 0x00, // uint128 0x00440044004400440044004400440044 + 0x44, 0x00, 0x44, 0x00, + 0x44, 0x00, 0x44, 0x00, + 0x44, 0x00, 0x44, 0x00, + 0x00, + 0x09, 0x00, // uint16 + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t discard; + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT8); + ATF_REQUIRE(sdp_set_uint(&test, 0x44)); + ATF_CHECK_EQ(sdp_set_uint(&test, UINT8_MAX + 1), false); /* too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_NIL); + ATF_CHECK_EQ(sdp_set_uint(&test, 0x00), false); /* not uint */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT16); + ATF_REQUIRE(sdp_set_uint(&test, 0xabcd)); + ATF_CHECK_EQ(sdp_set_uint(&test, UINT16_MAX + 1), false); /* too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT32); + ATF_REQUIRE(sdp_set_uint(&test, 0xdeadbeef)); + ATF_CHECK_EQ(sdp_set_uint(&test, (uintmax_t)UINT32_MAX + 1), false); /* too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT64); + ATF_REQUIRE(sdp_set_uint(&test, 0xc0ffeecafec0ffee)); + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT128); + ATF_REQUIRE(sdp_set_uint(&test, 0xabcdef0123456789)); + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT16); + ATF_CHECK_EQ(sdp_set_uint(&test, 0x3344), false); /* no value */ + + const uint8_t expect[] = { + 0x08, 0x44, // uint8 0x44 + 0x00, // nil + 0x09, 0xab, 0xcd, // uint16 0xabcd + 0x0a, 0xde, 0xad, 0xbe, // uint32 0xdeadbeef + 0xef, + 0x0b, 0xc0, 0xff, 0xee, // uint64 0xc0ffeecafec0ffee + 0xca, 0xfe, 0xc0, 0xff, + 0xee, + 0x0c, 0x00, 0x00, 0x00, // uint128 0x0000000000000000abcdef0123456789 + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xab, 0xcd, 0xef, + 0x01, 0x23, 0x45, 0x67, + 0x89, + 0x09, 0x00, // uint16 + }; + + ATF_REQUIRE_EQ(sizeof(data), sizeof(expect)); + ATF_CHECK(memcmp(expect, data, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_set_int); + +ATF_TC_HEAD(check_sdp_set_int, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_set_int results"); +} + +ATF_TC_BODY(check_sdp_set_int, tc) +{ + uint8_t data[] = { + 0x10, 0x00, // int8 0 + 0x00, // nil + 0x11, 0x00, 0x00, // int16 0 + 0x12, 0x00, 0x00, 0x00, // int32 0 + 0x00, + 0x13, 0x00, 0x00, 0x00, // int64 0 + 0x00, 0x00, 0x00, 0x00, + 0x00, + 0x14, 0x00, 0x44, 0x00, // int128 0x00440044004400440044004400440044 + 0x44, 0x00, 0x44, 0x00, + 0x44, 0x00, 0x44, 0x00, + 0x44, 0x00, 0x44, 0x00, + 0x00, + 0x11, 0x00, // int16 + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t discard; + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT8); + ATF_REQUIRE(sdp_set_int(&test, -1)); + ATF_CHECK_EQ(sdp_set_int(&test, INT8_MAX + 1), false); /* too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_NIL); + ATF_CHECK_EQ(sdp_set_int(&test, 33), false); /* not int */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT16); + ATF_REQUIRE(sdp_set_int(&test, 789)); + ATF_CHECK_EQ(sdp_set_int(&test, INT16_MIN - 1), false); /* too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT32); + ATF_REQUIRE(sdp_set_int(&test, -4567)); + ATF_CHECK_EQ(sdp_set_int(&test, (intmax_t)INT32_MAX + 1), false); /* too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT64); + ATF_REQUIRE(sdp_set_int(&test, -3483738234)); + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT128); + ATF_REQUIRE(sdp_set_int(&test, 3423489463464)); + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT16); + ATF_CHECK_EQ(sdp_set_int(&test, 1234), false); /* no value */ + + const uint8_t expect[] = { + 0x10, 0xff, // int8 -1 + 0x00, // nil + 0x11, 0x03, 0x15, // int16 789 + 0x12, 0xff, 0xff, 0xee, // int32 -4567 + 0x29, + 0x13, 0xff, 0xff, 0xff, // int64 -3483738234 + 0xff, 0x30, 0x5a, 0x5f, + 0x86, + 0x14, 0x00, 0x00, 0x00, // int128 3423489463464 + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, + 0x1d, 0x17, 0xdf, 0x94, + 0xa8, + 0x11, 0x00, // int16 + }; + + ATF_REQUIRE_EQ(sizeof(data), sizeof(expect)); + ATF_CHECK(memcmp(expect, data, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_set_seq); + +ATF_TC_HEAD(check_sdp_set_seq, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_set_seq results"); +} + +ATF_TC_BODY(check_sdp_set_seq, tc) +{ + uint8_t data[] = { + 0x35, 0x03, // seq8(3) + 0x11, 0xff, 0xff, // int16 -1 + 0x36, 0x01, 0x00, // seq16(256) + 0x09, 0xff, 0xff, // uint16 0xffff + 0x37, 0x01, 0x02, 0x03, // seq32(16909060) + 0x04, + 0x36, 0x00, // seq16() + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t discard; + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_SEQ8); + ATF_REQUIRE(sdp_set_seq(&test, 0)); + ATF_CHECK_EQ(sdp_set_seq(&test, UINT8_MAX), false); /* data too big */ + ATF_CHECK_EQ(sdp_set_seq(&test, UINT16_MAX), false); /* size too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT16); + ATF_CHECK_EQ(sdp_set_seq(&test, 33), false); /* not seq */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_SEQ16); + ATF_REQUIRE(sdp_set_seq(&test, 3)); + ATF_CHECK_EQ(sdp_set_seq(&test, SSIZE_MAX), false); /* size too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_SEQ32); + ATF_REQUIRE(sdp_set_seq(&test, 0)); + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_SEQ16); + ATF_CHECK_EQ(sdp_set_seq(&test, 22), false); /* no size */ + + const uint8_t expect[] = { + 0x35, 0x00, // seq8(0) + 0x11, 0xff, 0xff, // int16 -1 + 0x36, 0x00, 0x03, // seq16(3) + 0x09, 0xff, 0xff, // uint16 0xffff + 0x37, 0x00, 0x00, 0x00, // seq32(0) + 0x00, + 0x36, 0x00, // seq16() + }; + + ATF_REQUIRE_EQ(sizeof(data), sizeof(expect)); + ATF_CHECK(memcmp(expect, data, sizeof(expect)) == 0); +} + +ATF_TC(check_sdp_set_alt); + +ATF_TC_HEAD(check_sdp_set_alt, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sdp_set_alt results"); +} + +ATF_TC_BODY(check_sdp_set_alt, tc) +{ + uint8_t data[] = { + 0x3d, 0x06, // alt8(6) + 0x11, 0xff, 0xff, // int16 -1 + 0x3e, 0xff, 0xff, // alt16(65535) + 0x3f, 0x01, 0x02, 0x03, // alt32(16909060) + 0x04, + 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000003 + 0x03, + 0x3e, 0x00, // alt16() + }; + sdp_data_t test = { data, data + sizeof(data) }; + sdp_data_t discard; + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_ALT8); + ATF_REQUIRE(sdp_set_alt(&test, 0)); + ATF_CHECK_EQ(sdp_set_alt(&test, UINT8_MAX), false); /* data too big */ + ATF_CHECK_EQ(sdp_set_alt(&test, UINT16_MAX), false); /* size too big */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT16); + ATF_CHECK_EQ(sdp_set_alt(&test, 27), false); /* not alt */ + ATF_REQUIRE(sdp_get_data(&test, &discard)); + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_ALT16); + ATF_REQUIRE(sdp_set_alt(&test, 10)); + ATF_CHECK_EQ(sdp_set_alt(&test, SSIZE_MAX), false); /* size too big */ + ATF_REQUIRE(sdp_get_alt(&test, &discard)); + ATF_CHECK_EQ(sdp_data_type(&discard), SDP_DATA_ALT32); + ATF_CHECK(sdp_set_alt(&discard, -1)); /* end of alt16 */ + ATF_CHECK_EQ(sdp_set_alt(&discard, 6), false); /* data too big */ + + ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_ALT16); + ATF_CHECK_EQ(sdp_set_alt(&test, 22), false); /* no size */ + + const uint8_t expect[] = { + 0x3d, 0x00, // alt8(0) + 0x11, 0xff, 0xff, // int16 -1 + 0x3e, 0x00, 0x0a, // alt16(10) + 0x3f, 0x00, 0x00, 0x00, // alt32(5) + 0x05, + 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000003 + 0x03, + 0x3e, 0x00, // alt16() + }; + + ATF_REQUIRE_EQ(sizeof(data), sizeof(expect)); + ATF_CHECK(memcmp(expect, data, sizeof(expect)) == 0); +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_sdp_set_bool); + ATF_TP_ADD_TC(tp, check_sdp_set_uint); + ATF_TP_ADD_TC(tp, check_sdp_set_int); + ATF_TP_ADD_TC(tp, check_sdp_set_seq); + ATF_TP_ADD_TC(tp, check_sdp_set_alt); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbpfjit/t_bpfjit.c b/contrib/netbsd-tests/lib/libbpfjit/t_bpfjit.c new file mode 100644 index 0000000..4d81dd6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbpfjit/t_bpfjit.c @@ -0,0 +1,4753 @@ +/* $NetBSD: t_bpfjit.c,v 1.14 2015/02/14 22:40:18 alnsn Exp $ */ + +/*- + * Copyright (c) 2011-2012, 2014-2015 Alexander Nasonov. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_bpfjit.c,v 1.14 2015/02/14 22:40:18 alnsn Exp $"); + +#include +#include +#include + +#include +#include + +static uint8_t deadbeef_at_5[16] = { + 0, 0xf1, 2, 0xf3, 4, 0xde, 0xad, 0xbe, 0xef, 0xff +}; + +static inline +unsigned int jitcall(bpfjit_func_t fn, + const uint8_t *pkt, unsigned int wirelen, unsigned int buflen) +{ + bpf_args_t args; + + args.pkt = pkt; + args.wirelen = wirelen; + args.buflen = buflen; + + return fn(NULL, &args); +} + +ATF_TC(libbpfjit_empty); +ATF_TC_HEAD(libbpfjit_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that JIT compilation of an empty bpf program fails"); +} + +ATF_TC_BODY(libbpfjit_empty, tc) +{ + struct bpf_insn dummy; + + ATF_CHECK(!bpf_validate(&dummy, 0)); + ATF_CHECK(bpfjit_generate_code(NULL, &dummy, 0) == NULL); +} + +ATF_TC(libbpfjit_ret_k); +ATF_TC_HEAD(libbpfjit_ret_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of a trivial bpf program"); +} + +ATF_TC_BODY(libbpfjit_ret_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_RET+BPF_K, 17) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 17); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_bad_ret_k); +ATF_TC_HEAD(libbpfjit_bad_ret_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that JIT compilation of a program with bad BPF_RET fails"); +} + +ATF_TC_BODY(libbpfjit_bad_ret_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_RET+BPF_K+0x8000, 13) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + /* + * The point of this test is checking a bad instruction of + * a valid class and with a valid BPF_RVAL data. + */ + const uint16_t rcode = insns[0].code; + ATF_CHECK(BPF_CLASS(rcode) == BPF_RET && + (BPF_RVAL(rcode) == BPF_K || BPF_RVAL(rcode) == BPF_A)); + + ATF_CHECK(!bpf_validate(insns, insn_count)); + + /* Current implementation generates code. */ + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 13); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_add_k); +ATF_TC_HEAD(libbpfjit_alu_add_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_ADD+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_add_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 3), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 5); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_sub_k); +ATF_TC_HEAD(libbpfjit_alu_sub_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_SUB+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_sub_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), + BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mul_k); +ATF_TC_HEAD(libbpfjit_alu_mul_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MUL+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_mul_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0xfffffffd)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div0_k); +ATF_TC_HEAD(libbpfjit_alu_div0_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=0"); +} + +ATF_TC_BODY(libbpfjit_alu_div0_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + //ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div1_k); +ATF_TC_HEAD(libbpfjit_alu_div1_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=1"); +} + +ATF_TC_BODY(libbpfjit_alu_div1_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 7); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div2_k); +ATF_TC_HEAD(libbpfjit_alu_div2_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=2"); +} + +ATF_TC_BODY(libbpfjit_alu_div2_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 3); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div4_k); +ATF_TC_HEAD(libbpfjit_alu_div4_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=4"); +} + +ATF_TC_BODY(libbpfjit_alu_div4_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x3fffffff)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div10_k); +ATF_TC_HEAD(libbpfjit_alu_div10_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=10"); +} + +ATF_TC_BODY(libbpfjit_alu_div10_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 10), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(429484384)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div10000_k); +ATF_TC_HEAD(libbpfjit_alu_div10000_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=10000"); +} + +ATF_TC_BODY(libbpfjit_alu_div10000_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 10000), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(429484)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div7609801_k); +ATF_TC_HEAD(libbpfjit_alu_div7609801_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=7609801"); +} + +ATF_TC_BODY(libbpfjit_alu_div7609801_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(7609801)), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 564); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div80000000_k); +ATF_TC_HEAD(libbpfjit_alu_div80000000_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=0x80000000"); +} + +ATF_TC_BODY(libbpfjit_alu_div80000000_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(0x80000000)), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod0_k); +ATF_TC_HEAD(libbpfjit_alu_mod0_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=0"); +} + +ATF_TC_BODY(libbpfjit_alu_mod0_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + //ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod1_k); +ATF_TC_HEAD(libbpfjit_alu_mod1_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=1"); +} + +ATF_TC_BODY(libbpfjit_alu_mod1_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod2_k); +ATF_TC_HEAD(libbpfjit_alu_mod2_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=2"); +} + +ATF_TC_BODY(libbpfjit_alu_mod2_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod4_k); +ATF_TC_HEAD(libbpfjit_alu_mod4_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=4"); +} + +ATF_TC_BODY(libbpfjit_alu_mod4_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 3); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod10_k); +ATF_TC_HEAD(libbpfjit_alu_mod10_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=10"); +} + +ATF_TC_BODY(libbpfjit_alu_mod10_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 10), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 9); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod10000_k); +ATF_TC_HEAD(libbpfjit_alu_mod10000_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=10000"); +} + +ATF_TC_BODY(libbpfjit_alu_mod10000_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 10000), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 3849); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod7609801_k); +ATF_TC_HEAD(libbpfjit_alu_mod7609801_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_mod+BPF_K with k=7609801"); +} + +ATF_TC_BODY(libbpfjit_alu_mod7609801_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, UINT32_C(7609801)), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(3039531)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod80000000_k); +ATF_TC_HEAD(libbpfjit_alu_mod80000000_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=0x80000000"); +} + +ATF_TC_BODY(libbpfjit_alu_mod80000000_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, UINT32_C(0x80000000)), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x7fffffde)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_and_k); +ATF_TC_HEAD(libbpfjit_alu_and_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_AND+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_and_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead), + BPF_STMT(BPF_ALU+BPF_AND+BPF_K, 0xbeef), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == (0xdead&0xbeef)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_or_k); +ATF_TC_HEAD(libbpfjit_alu_or_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_OR+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_or_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead0000), + BPF_STMT(BPF_ALU+BPF_OR+BPF_K, 0x0000beef), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_xor_k); +ATF_TC_HEAD(libbpfjit_alu_xor_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_XOR+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_xor_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead0f0f), + BPF_STMT(BPF_ALU+BPF_XOR+BPF_K, 0x0000b1e0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_lsh_k); +ATF_TC_HEAD(libbpfjit_alu_lsh_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_lsh_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 16), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xbeef0000); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_lsh0_k); +ATF_TC_HEAD(libbpfjit_alu_lsh0_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_K with k=0"); +} + +ATF_TC_BODY(libbpfjit_alu_lsh0_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_rsh_k); +ATF_TC_HEAD(libbpfjit_alu_rsh_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_alu_rsh_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 16), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0x0000dead); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_rsh0_k); +ATF_TC_HEAD(libbpfjit_alu_rsh0_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_K with k=0"); +} + +ATF_TC_BODY(libbpfjit_alu_rsh0_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_modulo_k); +ATF_TC_HEAD(libbpfjit_alu_modulo_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of modulo logic of BPF_ALU+BPF_K operations"); +} + +ATF_TC_BODY(libbpfjit_alu_modulo_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)), + + /* (7FFFFF77 * 0FFFFF77) = 07FFFFB2,F0004951 */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, UINT32_C(0x0fffff77)), + + /* 07FFFFB2,F0004951 << 1 = 0FFFFF65,E00092A2 */ + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 1), + + /* 0FFFFF65,E00092A2 + DDDDDDDD = 0FFFFF66,BDDE707F */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xdddddddd)), + + /* 0FFFFF66,BDDE707F - FFFFFFFF = 0FFFFF65,BDDE7080 */ + BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, UINT32_C(0xffffffff)), + + /* 0FFFFF65,BDDE7080 | 0000030C = 0FFFFF65,BDDE738C */ + BPF_STMT(BPF_ALU+BPF_OR+BPF_K, UINT32_C(0x0000030c)), + + /* -0FFFFF65,BDDE738C mod(2^64) = F000009A,42218C74 */ + BPF_STMT(BPF_ALU+BPF_NEG, 0), + + /* F000009A,42218C74 & FFFFFF0F = F000009A,42218C04 */ + BPF_STMT(BPF_ALU+BPF_AND+BPF_K, UINT32_C(0xffffff0f)), + + /* F000009A,42218C74 >> 3 = 1E000013,48443180 */ + /* 00000000,42218C74 >> 3 = 00000000,08443180 */ + BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 3), + + /* 00000000,08443180 * 7FFFFF77 = 042218BB,93818280 */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, UINT32_C(0x7fffff77)), + + /* 042218BB,93818280 / DEAD = 000004C0,71CBBBC3 */ + /* 00000000,93818280 / DEAD = 00000000,0000A994 */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(0xdead)), + + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) != UINT32_C(0x71cbbbc3)); + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x0000a994)); + + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_add_x); +ATF_TC_HEAD(libbpfjit_alu_add_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_ADD+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_add_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 3), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 5); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_sub_x); +ATF_TC_HEAD(libbpfjit_alu_sub_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_SUB+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_sub_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_STMT(BPF_ALU+BPF_SUB+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mul_x); +ATF_TC_HEAD(libbpfjit_alu_mul_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MUL+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_mul_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0xfffffffd)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div0_x); +ATF_TC_HEAD(libbpfjit_alu_div0_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=0"); +} + +ATF_TC_BODY(libbpfjit_alu_div0_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div1_x); +ATF_TC_HEAD(libbpfjit_alu_div1_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=1"); +} + +ATF_TC_BODY(libbpfjit_alu_div1_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 7); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div2_x); +ATF_TC_HEAD(libbpfjit_alu_div2_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=2"); +} + +ATF_TC_BODY(libbpfjit_alu_div2_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 3); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div4_x); +ATF_TC_HEAD(libbpfjit_alu_div4_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=4"); +} + +ATF_TC_BODY(libbpfjit_alu_div4_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x3fffffff)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div10_x); +ATF_TC_HEAD(libbpfjit_alu_div10_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=10"); +} + +ATF_TC_BODY(libbpfjit_alu_div10_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(429484384)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div10000_x); +ATF_TC_HEAD(libbpfjit_alu_div10000_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=10000"); +} + +ATF_TC_BODY(libbpfjit_alu_div10000_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10000), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(429484)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div7609801_x); +ATF_TC_HEAD(libbpfjit_alu_div7609801_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=7609801"); +} + +ATF_TC_BODY(libbpfjit_alu_div7609801_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(7609801)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 564); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_div80000000_x); +ATF_TC_HEAD(libbpfjit_alu_div80000000_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=0x80000000"); +} + +ATF_TC_BODY(libbpfjit_alu_div80000000_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0x80000000)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod0_x); +ATF_TC_HEAD(libbpfjit_alu_mod0_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=0"); +} + +ATF_TC_BODY(libbpfjit_alu_mod0_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod1_x); +ATF_TC_HEAD(libbpfjit_alu_mod1_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=1"); +} + +ATF_TC_BODY(libbpfjit_alu_mod1_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod2_x); +ATF_TC_HEAD(libbpfjit_alu_mod2_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=2"); +} + +ATF_TC_BODY(libbpfjit_alu_mod2_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod4_x); +ATF_TC_HEAD(libbpfjit_alu_mod4_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=4"); +} + +ATF_TC_BODY(libbpfjit_alu_mod4_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 3); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod10_x); +ATF_TC_HEAD(libbpfjit_alu_mod10_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=10"); +} + +ATF_TC_BODY(libbpfjit_alu_mod10_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 9); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod10000_x); +ATF_TC_HEAD(libbpfjit_alu_mod10000_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=10000"); +} + +ATF_TC_BODY(libbpfjit_alu_mod10000_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10000), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 3849); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod7609801_x); +ATF_TC_HEAD(libbpfjit_alu_mod7609801_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=7609801"); +} + +ATF_TC_BODY(libbpfjit_alu_mod7609801_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(7609801)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(3039531)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_mod80000000_x); +ATF_TC_HEAD(libbpfjit_alu_mod80000000_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=0x80000000"); +} + +ATF_TC_BODY(libbpfjit_alu_mod80000000_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0x80000000)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x7fffffde)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_and_x); +ATF_TC_HEAD(libbpfjit_alu_and_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_AND+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_and_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0xbeef), + BPF_STMT(BPF_ALU+BPF_AND+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == (0xdead&0xbeef)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_or_x); +ATF_TC_HEAD(libbpfjit_alu_or_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_OR+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_or_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead0000), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0x0000beef), + BPF_STMT(BPF_ALU+BPF_OR+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_xor_x); +ATF_TC_HEAD(libbpfjit_alu_xor_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_XOR+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_xor_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead0f0f), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0x0000b1e0), + BPF_STMT(BPF_ALU+BPF_XOR+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_lsh_x); +ATF_TC_HEAD(libbpfjit_alu_lsh_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_lsh_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 16), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xbeef0000); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_lsh0_x); +ATF_TC_HEAD(libbpfjit_alu_lsh0_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_X with k=0"); +} + +ATF_TC_BODY(libbpfjit_alu_lsh0_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_rsh_x); +ATF_TC_HEAD(libbpfjit_alu_rsh_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_alu_rsh_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 16), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0x0000dead); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_rsh0_x); +ATF_TC_HEAD(libbpfjit_alu_rsh0_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_X with k=0"); +} + +ATF_TC_BODY(libbpfjit_alu_rsh0_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_modulo_x); +ATF_TC_HEAD(libbpfjit_alu_modulo_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of modulo logic of BPF_ALU+BPF_X operations"); +} + +ATF_TC_BODY(libbpfjit_alu_modulo_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)), + + /* (7FFFFF77 * 0FFFFF77) = 07FFFFB2,F0004951 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x0fffff77)), + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), + + /* 07FFFFB2,F0004951 << 1 = 0FFFFF65,E00092A2 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, 1), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0), + + /* 0FFFFF65,E00092A2 + DDDDDDDD = 0FFFFF66,BDDE707F */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xdddddddd)), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + + /* 0FFFFF66,BDDE707F - FFFFFFFF = 0FFFFF65,BDDE7080 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ALU+BPF_SUB+BPF_X, 0), + + /* 0FFFFF65,BDDE7080 | 0000030C = 0FFFFF65,BDDE738C */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x0000030c)), + BPF_STMT(BPF_ALU+BPF_OR+BPF_X, 0), + + /* -0FFFFF65,BDDE738C mod(2^64) = F000009A,42218C74 */ + BPF_STMT(BPF_ALU+BPF_NEG, 0), + + /* F000009A,42218C74 & FFFFFF0F = F000009A,42218C04 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xffffff0f)), + BPF_STMT(BPF_ALU+BPF_AND+BPF_X, 0), + + /* F000009A,42218C74 >> 3 = 1E000013,48443180 */ + /* 00000000,42218C74 >> 3 = 00000000,08443180 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, 3), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0), + + /* 00000000,08443180 * 7FFFFF77 = 042218BB,93818280 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x7fffff77)), + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), + + /* 042218BB,93818280 / DEAD = 000004C0,71CBBBC3 */ + /* 00000000,93818280 / DEAD = 00000000,0000A994 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xdead)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) != UINT32_C(0x71cbbbc3)); + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x0000a994)); + + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_alu_neg); +ATF_TC_HEAD(libbpfjit_alu_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_NEG"); +} + +ATF_TC_BODY(libbpfjit_alu_neg, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 777), + BPF_STMT(BPF_ALU+BPF_NEG, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0u-777u); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_ja); +ATF_TC_HEAD(libbpfjit_jmp_ja, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JA"); +} + +ATF_TC_BODY(libbpfjit_jmp_ja, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_JMP+BPF_JA, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_K, 3), + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_ja_invalid); +ATF_TC_HEAD(libbpfjit_jmp_ja_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test BPF_JMP+BPF_JA to invalid destination"); +} + +ATF_TC_BODY(libbpfjit_jmp_ja_invalid, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_JMP+BPF_JA, 4), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_K, 3), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(!bpf_validate(insns, insn_count)); + ATF_CHECK(bpfjit_generate_code(NULL, insns, insn_count) == NULL); +} + +ATF_TC(libbpfjit_jmp_ja_overflow); +ATF_TC_HEAD(libbpfjit_jmp_ja_overflow, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test BPF_JMP+BPF_JA with negative offset"); +} + +ATF_TC_BODY(libbpfjit_jmp_ja_overflow, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_JMP+BPF_JA, 1), + BPF_STMT(BPF_RET+BPF_K, 777), + BPF_STMT(BPF_JMP+BPF_JA, UINT32_MAX - 1), // -2 + BPF_STMT(BPF_RET+BPF_K, 0) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + /* Jumps with negative offsets work in userspace ... */ + ATF_CHECK(bpf_validate(insns, insn_count)); + + /* .. but not for bpfjit. */ + ATF_CHECK(bpfjit_generate_code(NULL, insns, insn_count) == NULL); +} + +ATF_TC(libbpfjit_jmp_jgt_k); +ATF_TC_HEAD(libbpfjit_jmp_jgt_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_jmp_jgt_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 7, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 2, 2, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 9, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 4, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 5, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 7); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jge_k); +ATF_TC_HEAD(libbpfjit_jmp_jge_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_jmp_jge_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 8, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 3, 2, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 9, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 5, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 6, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 1, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 7); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jeq_k); +ATF_TC_HEAD(libbpfjit_jmp_jeq_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_jmp_jeq_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 1, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 9, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 5, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 7, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 1, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 7); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 7); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 1); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jset_k); +ATF_TC_HEAD(libbpfjit_jmp_jset_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_K"); +} + +ATF_TC_BODY(libbpfjit_jmp_jset_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 8, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 4, 2, 0), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 3, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 1, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 7, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 1); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 5); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_modulo_k); +ATF_TC_HEAD(libbpfjit_jmp_modulo_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of modulo logic of BPF_JMP+BPF_K operations"); +} + +ATF_TC_BODY(libbpfjit_jmp_modulo_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 1, 0), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 0, 1), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 0, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 0, 3), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 2, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 1, 0), + BPF_STMT(BPF_JMP+BPF_JA, 1), + BPF_STMT(BPF_RET+BPF_K, 3), + + /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)), + + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 1, 0), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 0, 1), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 0, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 0, 3), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 2, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 1, 0), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jgt_x); +ATF_TC_HEAD(libbpfjit_jmp_jgt_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_jmp_jgt_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 4, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 7); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jge_x); +ATF_TC_HEAD(libbpfjit_jmp_jge_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_jmp_jge_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 3, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 4, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 7); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jeq_x); +ATF_TC_HEAD(libbpfjit_jmp_jeq_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_jmp_jeq_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 8), + BPF_STMT(BPF_RET+BPF_K, 9) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 8); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 8); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 2); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 8); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 3); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 9); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 6); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 1); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jset_x); +ATF_TC_HEAD(libbpfjit_jmp_jset_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_X"); +} + +ATF_TC_BODY(libbpfjit_jmp_jset_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 0), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 3, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 4, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 1); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 5); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jeq_x_noinit_ax); +ATF_TC_HEAD(libbpfjit_jmp_jeq_x_noinit_ax, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test JIT compilation " + "of BPF_JMP+BPF_EQ+BPF_X with uninitialised A and X"); +} + +ATF_TC_BODY(libbpfjit_jmp_jeq_x_noinit_ax, tc) +{ + static struct bpf_insn insns[] = { + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 10), + BPF_STMT(BPF_RET+BPF_K, 11) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 10); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jeq_x_noinit_a); +ATF_TC_HEAD(libbpfjit_jmp_jeq_x_noinit_a, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test JIT compilation " + "of BPF_JMP+BPF_EQ+BPF_X with uninitialised A"); +} + +ATF_TC_BODY(libbpfjit_jmp_jeq_x_noinit_a, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), /* X > 0 */ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 10), + BPF_STMT(BPF_RET+BPF_K, 11) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 11); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_jeq_x_noinit_x); +ATF_TC_HEAD(libbpfjit_jmp_jeq_x_noinit_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test JIT compilation " + "of BPF_JMP+BPF_EQ+BPF_X with uninitialised X"); +} + +ATF_TC_BODY(libbpfjit_jmp_jeq_x_noinit_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_LEN, 0), /* A > 0 */ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 10), + BPF_STMT(BPF_RET+BPF_K, 11) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 11); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_jmp_modulo_x); +ATF_TC_HEAD(libbpfjit_jmp_modulo_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of modulo logic of BPF_JMP+BPF_X operations"); +} + +ATF_TC_BODY(libbpfjit_jmp_modulo_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)), + /* FFFFF770 << 4 = FFFFF770 */ + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4), + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0), + BPF_STMT(BPF_JMP+BPF_JA, 1), + BPF_STMT(BPF_RET+BPF_K, 3), + + /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)), + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ld_abs); +ATF_TC_HEAD(libbpfjit_ld_abs, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_ABS"); +} + +ATF_TC_BODY(libbpfjit_ld_abs, tc) +{ + static struct bpf_insn insns[3][2] = { + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 5), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 5), + BPF_STMT(BPF_RET+BPF_A, 0) + } + }; + + static size_t lengths[3] = { 1, 2, 4 }; + static unsigned int expected[3] = { 0xde, 0xdead, 0xdeadbeef }; + + size_t i, l; + uint8_t *pkt = deadbeef_at_5; + size_t pktsize = sizeof(deadbeef_at_5); + + size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]); + + for (i = 0; i < 3; i++) { + bpfjit_func_t code; + + ATF_CHECK(bpf_validate(insns[i], insn_count)); + + code = bpfjit_generate_code(NULL, insns[i], insn_count); + ATF_REQUIRE(code != NULL); + + for (l = 1; l < 5 + lengths[i]; l++) { + ATF_CHECK(jitcall(code, pkt, l, l) == 0); + ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0); + } + + l = 5 + lengths[i]; + ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]); + ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]); + + l = pktsize; + ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]); + + bpfjit_free_code(code); + } +} + +ATF_TC(libbpfjit_ld_abs_k_overflow); +ATF_TC_HEAD(libbpfjit_ld_abs_k_overflow, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_ABS with overflow in k+4"); +} + +ATF_TC_BODY(libbpfjit_ld_abs_k_overflow, tc) +{ + static struct bpf_insn insns[12][3] = { + { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3), + BPF_STMT(BPF_RET+BPF_K, 1) + } + }; + + int i; + uint8_t pkt[8] = { 0 }; + + size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]); + + for (i = 0; i < 3; i++) { + bpfjit_func_t code; + + ATF_CHECK(bpf_validate(insns[i], insn_count)); + + code = bpfjit_generate_code(NULL, insns[i], insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); + } +} + +ATF_TC(libbpfjit_ld_ind); +ATF_TC_HEAD(libbpfjit_ld_ind, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(libbpfjit_ld_ind, tc) +{ + static struct bpf_insn insns[6][3] = { + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + } + }; + + static size_t lengths[6] = { 1, 2, 4, 1, 2, 4 }; + + static unsigned int expected[6] = { + 0xde, 0xdead, 0xdeadbeef, + 0xde, 0xdead, 0xdeadbeef + }; + + size_t i, l; + uint8_t *pkt = deadbeef_at_5; + size_t pktsize = sizeof(deadbeef_at_5); + + size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]); + + for (i = 0; i < 3; i++) { + bpfjit_func_t code; + + ATF_CHECK(bpf_validate(insns[i], insn_count)); + + code = bpfjit_generate_code(NULL, insns[i], insn_count); + ATF_REQUIRE(code != NULL); + + for (l = 1; l < 5 + lengths[i]; l++) { + ATF_CHECK(jitcall(code, pkt, l, l) == 0); + ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0); + } + + l = 5 + lengths[i]; + ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]); + ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]); + + l = pktsize; + ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]); + + bpfjit_free_code(code); + } +} + +ATF_TC(libbpfjit_ld_ind_k_overflow); +ATF_TC_HEAD(libbpfjit_ld_ind_k_overflow, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IND with overflow in k+4"); +} + +ATF_TC_BODY(libbpfjit_ld_ind_k_overflow, tc) +{ + static struct bpf_insn insns[12][3] = { + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3), + BPF_STMT(BPF_RET+BPF_K, 1) + } + }; + + int i; + uint8_t pkt[8] = { 0 }; + + size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]); + + for (i = 0; i < 3; i++) { + bpfjit_func_t code; + + ATF_CHECK(bpf_validate(insns[i], insn_count)); + + code = bpfjit_generate_code(NULL, insns[i], insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + bpfjit_free_code(code); + } +} + +ATF_TC(libbpfjit_ld_ind_x_overflow1); +ATF_TC_HEAD(libbpfjit_ld_ind_x_overflow1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4"); +} + +ATF_TC_BODY(libbpfjit_ld_ind_x_overflow1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_LEN, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)), + BPF_STMT(BPF_MISC+BPF_TAX, 0), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) { + ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i); + ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ld_ind_x_overflow2); +ATF_TC_HEAD(libbpfjit_ld_ind_x_overflow2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4"); +} + +ATF_TC_BODY(libbpfjit_ld_ind_x_overflow2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_LEN, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ST, 3), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) { + ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i); + ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ld_len); +ATF_TC_HEAD(libbpfjit_ld_len, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_W+BPF_LEN"); +} + +ATF_TC_BODY(libbpfjit_ld_len, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[32]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < sizeof(pkt); i++) + ATF_CHECK(jitcall(code, pkt, i, 1) == i); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ld_imm); +ATF_TC_HEAD(libbpfjit_ld_imm, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IMM"); +} + +ATF_TC_BODY(libbpfjit_ld_imm, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ldx_imm1); +ATF_TC_HEAD(libbpfjit_ldx_imm1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_IMM"); +} + +ATF_TC_BODY(libbpfjit_ldx_imm1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX - 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX - 5); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ldx_imm2); +ATF_TC_HEAD(libbpfjit_ldx_imm2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_IMM"); +} + +ATF_TC_BODY(libbpfjit_ldx_imm2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_STMT(BPF_LD+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ldx_len1); +ATF_TC_HEAD(libbpfjit_ldx_len1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_LEN"); +} + +ATF_TC_BODY(libbpfjit_ldx_len1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[5]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 1; i < sizeof(pkt); i++) { + ATF_CHECK(jitcall(code, pkt, i, 1) == i); + ATF_CHECK(jitcall(code, pkt, i + 1, i) == i + 1); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ldx_len2); +ATF_TC_HEAD(libbpfjit_ldx_len2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_LEN"); +} + +ATF_TC_BODY(libbpfjit_ldx_len2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LD+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX) + }; + + bpfjit_func_t code; + uint8_t pkt[5]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 5, 1) == UINT32_MAX); + ATF_CHECK(jitcall(code, pkt, 6, 5) == 7); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_ldx_msh); +ATF_TC_HEAD(libbpfjit_ldx_msh, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_MSH"); +} + +ATF_TC_BODY(libbpfjit_ldx_msh, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[2] = { 0, 0x7a }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 2, 2) == 40); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_misc_tax); +ATF_TC_HEAD(libbpfjit_misc_tax, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_MISC+BPF_TAX"); +} + +ATF_TC_BODY(libbpfjit_misc_tax, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 3), + BPF_STMT(BPF_MISC+BPF_TAX, 0), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[] = { 0, 11, 22, 33, 44, 55 }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, sizeof(pkt), sizeof(pkt)) == 55); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_misc_txa); +ATF_TC_HEAD(libbpfjit_misc_txa, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_MISC+BPF_TXA"); +} + +ATF_TC_BODY(libbpfjit_misc_txa, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 391), + BPF_STMT(BPF_MISC+BPF_TXA, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 391); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_st1); +ATF_TC_HEAD(libbpfjit_st1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(libbpfjit_st1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ST, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_LD+BPF_MEM, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[16]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) + ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_st2); +ATF_TC_HEAD(libbpfjit_st2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(libbpfjit_st2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ST, BPF_MEMWORDS-1), + BPF_STMT(BPF_LD+BPF_MEM, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_st3); +ATF_TC_HEAD(libbpfjit_st3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(libbpfjit_st3, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ST, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100), + BPF_STMT(BPF_ST, BPF_MEMWORDS-1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0), + BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1), + BPF_STMT(BPF_RET+BPF_A, 0), + BPF_STMT(BPF_LD+BPF_MEM, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[2]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_REQUIRE(BPF_MEMWORDS > 1); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 102); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_st4); +ATF_TC_HEAD(libbpfjit_st4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(libbpfjit_st4, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ST, 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100), + BPF_STMT(BPF_ST, BPF_MEMWORDS-1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0), + BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1), + BPF_STMT(BPF_RET+BPF_A, 0), + BPF_STMT(BPF_LD+BPF_MEM, 5), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[2]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_REQUIRE(BPF_MEMWORDS > 6); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 102); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_st5); +ATF_TC_HEAD(libbpfjit_st5, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(libbpfjit_st5, tc) +{ + struct bpf_insn insns[5*BPF_MEMWORDS+2]; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + size_t k; + bpfjit_func_t code; + uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */ + + memset(insns, 0, sizeof(insns)); + + /* for each k do M[k] = k */ + for (k = 0; k < BPF_MEMWORDS; k++) { + insns[2*k].code = BPF_LD+BPF_IMM; + insns[2*k].k = 3*k; + insns[2*k+1].code = BPF_ST; + insns[2*k+1].k = k; + } + + /* load wirelen into A */ + insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN; + + /* for each k, if (A == k + 1) return M[k] */ + for (k = 0; k < BPF_MEMWORDS; k++) { + insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K; + insns[2*BPF_MEMWORDS+3*k+1].k = k+1; + insns[2*BPF_MEMWORDS+3*k+1].jt = 0; + insns[2*BPF_MEMWORDS+3*k+1].jf = 2; + insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM; + insns[2*BPF_MEMWORDS+3*k+2].k = k; + insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A; + insns[2*BPF_MEMWORDS+3*k+3].k = 0; + } + + insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K; + insns[5*BPF_MEMWORDS+1].k = UINT32_MAX; + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (k = 1; k <= sizeof(pkt); k++) + ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_stx1); +ATF_TC_HEAD(libbpfjit_stx1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_STX"); +} + +ATF_TC_BODY(libbpfjit_stx1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_STX, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[16]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) + ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_stx2); +ATF_TC_HEAD(libbpfjit_stx2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_STX"); +} + +ATF_TC_BODY(libbpfjit_stx2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_STX, BPF_MEMWORDS-1), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), + BPF_STMT(BPF_MISC+BPF_TXA, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_stx3); +ATF_TC_HEAD(libbpfjit_stx3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_STX"); +} + +ATF_TC_BODY(libbpfjit_stx3, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_STX, 5), + BPF_STMT(BPF_STX, 2), + BPF_STMT(BPF_STX, 3), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 2), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 6), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[16]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) + ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == 3 * i); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_stx4); +ATF_TC_HEAD(libbpfjit_stx4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_STX"); +} + +ATF_TC_BODY(libbpfjit_stx4, tc) +{ + struct bpf_insn insns[5*BPF_MEMWORDS+2]; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + size_t k; + bpfjit_func_t code; + uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */ + + memset(insns, 0, sizeof(insns)); + + /* for each k do M[k] = k */ + for (k = 0; k < BPF_MEMWORDS; k++) { + insns[2*k].code = BPF_LDX+BPF_W+BPF_IMM; + insns[2*k].k = 3*k; + insns[2*k+1].code = BPF_STX; + insns[2*k+1].k = k; + } + + /* load wirelen into A */ + insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN; + + /* for each k, if (A == k + 1) return M[k] */ + for (k = 0; k < BPF_MEMWORDS; k++) { + insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K; + insns[2*BPF_MEMWORDS+3*k+1].k = k+1; + insns[2*BPF_MEMWORDS+3*k+1].jt = 0; + insns[2*BPF_MEMWORDS+3*k+1].jf = 2; + insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM; + insns[2*BPF_MEMWORDS+3*k+2].k = k; + insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A; + insns[2*BPF_MEMWORDS+3*k+3].k = 0; + } + + insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K; + insns[5*BPF_MEMWORDS+1].k = UINT32_MAX; + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (k = 1; k <= sizeof(pkt); k++) + ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_abs_1); +ATF_TC_HEAD(libbpfjit_opt_ld_abs_1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_ABS"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_abs_1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_abs_2); +ATF_TC_HEAD(libbpfjit_opt_ld_abs_2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_ABS"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_abs_2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_abs_3); +ATF_TC_HEAD(libbpfjit_opt_ld_abs_3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_ABS"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_abs_3, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 5), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_ind_1); +ATF_TC_HEAD(libbpfjit_opt_ld_ind_1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_ind_1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 12), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 14), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_ind_2); +ATF_TC_HEAD(libbpfjit_opt_ld_ind_2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_ind_2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_ind_3); +ATF_TC_HEAD(libbpfjit_opt_ld_ind_3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_ind_3, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 15), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_opt_ld_ind_4); +ATF_TC_HEAD(libbpfjit_opt_ld_ind_4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(libbpfjit_opt_ld_ind_4, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 11), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 19), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_abc_ja); +ATF_TC_HEAD(libbpfjit_abc_ja, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test ABC optimization with a single BPF_JMP+BPF_JA"); +} + +ATF_TC_BODY(libbpfjit_abc_ja, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */ + BPF_STMT(BPF_JMP+BPF_JA, 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 2), /* min. length 6 */ + BPF_STMT(BPF_RET+BPF_A, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 3), + }; + + bpfjit_func_t code; + uint8_t pkt[6] = {0, 0, /* UINT32_MAX: */ 255, 255, 255, 255}; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_abc_ja_over); +ATF_TC_HEAD(libbpfjit_abc_ja_over, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test ABC optimization when BPF_JMP+BPF_JA jumps over all loads"); +} + +ATF_TC_BODY(libbpfjit_abc_ja_over, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_JMP+BPF_JA, 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6), + BPF_STMT(BPF_RET+BPF_K, 3), + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_abc_ld_chain); +ATF_TC_HEAD(libbpfjit_abc_ld_chain, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test ABC optimization of a chain of BPF_LD instructions " + "with exits leading to a single BPF_RET"); +} + +ATF_TC_BODY(libbpfjit_abc_ld_chain, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 4), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4), /* min. length 6 */ + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 6), /* min. length 10 */ + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 123456789), + BPF_STMT(BPF_RET+BPF_K, 987654321), + }; + + bpfjit_func_t code; + uint8_t pkt[10] = {}; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + + /* !(pkt[3] == 8) => return 123456789 */ + ATF_CHECK(jitcall(code, pkt, 4, 4) == 123456789); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 123456789); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 123456789); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 123456789); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789); + + /* !(pkt[4:2] >= 7) => too short or return 123456789 */ + pkt[3] = 8; + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789); + + /* !(pkt[6:4] > 6) => too short or return 987654321 */ + pkt[4] = pkt[5] = 1; + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 987654321); + + /* (pkt[6:4] > 6) => too short or return 123456789 */ + pkt[6] = pkt[7] = pkt[8] = pkt[9] = 1; + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 123456789); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_examples_1); +ATF_TC_HEAD(libbpfjit_examples_1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the first example from bpf(4) - " + "accept Reverse ARP requests"); +} + +ATF_TC_BODY(libbpfjit_examples_1, tc) +{ + /* + * The following filter is taken from the Reverse ARP + * Daemon. It accepts only Reverse ARP requests. + */ + struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8035, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 42), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + bpfjit_func_t code; + uint8_t pkt[22] = {}; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + + /* The packet doesn't match. */ + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + + /* Still no match after setting the protocol field. */ + pkt[12] = 0x80; pkt[13] = 0x35; + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + + /* Set RARP message type. */ + pkt[21] = 3; + ATF_CHECK(jitcall(code, pkt, 22, 22) == 42); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + + /* Change RARP message type. */ + pkt[20] = 3; + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_examples_2); +ATF_TC_HEAD(libbpfjit_examples_2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the second example from bpf(4) - " + "accept IP packets between two specified hosts"); +} + +ATF_TC_BODY(libbpfjit_examples_2, tc) +{ + /* + * This filter accepts only IP packets between host 128.3.112.15 + * and 128.3.112.35. + */ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 8), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + bpfjit_func_t code; + uint8_t pkt[34] = {}; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + ATF_CHECK(jitcall(code, pkt, 23, 23) == 0); + ATF_CHECK(jitcall(code, pkt, 24, 24) == 0); + ATF_CHECK(jitcall(code, pkt, 25, 25) == 0); + ATF_CHECK(jitcall(code, pkt, 26, 26) == 0); + ATF_CHECK(jitcall(code, pkt, 27, 27) == 0); + ATF_CHECK(jitcall(code, pkt, 28, 28) == 0); + ATF_CHECK(jitcall(code, pkt, 29, 29) == 0); + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + ATF_CHECK(jitcall(code, pkt, 31, 31) == 0); + ATF_CHECK(jitcall(code, pkt, 32, 32) == 0); + ATF_CHECK(jitcall(code, pkt, 33, 33) == 0); + + /* The packet doesn't match. */ + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + /* Still no match after setting the protocol field. */ + pkt[12] = 8; + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 15; + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 35; + ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX); + + /* Swap the ip addresses. */ + pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 35; + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 15; + ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + ATF_CHECK(jitcall(code, pkt, 23, 23) == 0); + ATF_CHECK(jitcall(code, pkt, 24, 24) == 0); + ATF_CHECK(jitcall(code, pkt, 25, 25) == 0); + ATF_CHECK(jitcall(code, pkt, 26, 26) == 0); + ATF_CHECK(jitcall(code, pkt, 27, 27) == 0); + ATF_CHECK(jitcall(code, pkt, 28, 28) == 0); + ATF_CHECK(jitcall(code, pkt, 29, 29) == 0); + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + ATF_CHECK(jitcall(code, pkt, 31, 31) == 0); + ATF_CHECK(jitcall(code, pkt, 32, 32) == 0); + ATF_CHECK(jitcall(code, pkt, 33, 33) == 0); + + /* Change the protocol field. */ + pkt[13] = 8; + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_examples_3); +ATF_TC_HEAD(libbpfjit_examples_3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the third example from bpf(4) - " + "accept TCP finger packets"); +} + +ATF_TC_BODY(libbpfjit_examples_3, tc) +{ + /* + * This filter returns only TCP finger packets. + */ + struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 10), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 0, 8), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0), + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + bpfjit_func_t code; + uint8_t pkt[30] = {}; + + /* Set IP fragment offset to non-zero. */ + pkt[20] = 1; pkt[21] = 1; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_REQUIRE(code != NULL); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + ATF_CHECK(jitcall(code, pkt, 23, 23) == 0); + ATF_CHECK(jitcall(code, pkt, 24, 24) == 0); + ATF_CHECK(jitcall(code, pkt, 25, 25) == 0); + ATF_CHECK(jitcall(code, pkt, 26, 26) == 0); + ATF_CHECK(jitcall(code, pkt, 27, 27) == 0); + ATF_CHECK(jitcall(code, pkt, 28, 28) == 0); + ATF_CHECK(jitcall(code, pkt, 29, 29) == 0); + + /* The packet doesn't match. */ + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Still no match after setting the protocol field. */ + pkt[12] = 8; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Get one step closer to the match. */ + pkt[23] = 6; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Set IP fragment offset to zero. */ + pkt[20] = 0x20; pkt[21] = 0; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Set IP header length to 12. */ + pkt[14] = 0xd3; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Match one branch of the program. */ + pkt[27] = 79; + ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX); + + /* Match the other branch of the program. */ + pkt[29] = 79; pkt[27] = 0; + ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + ATF_CHECK(jitcall(code, pkt, 23, 23) == 0); + ATF_CHECK(jitcall(code, pkt, 24, 24) == 0); + ATF_CHECK(jitcall(code, pkt, 25, 25) == 0); + ATF_CHECK(jitcall(code, pkt, 26, 26) == 0); + ATF_CHECK(jitcall(code, pkt, 27, 27) == 0); + ATF_CHECK(jitcall(code, pkt, 28, 28) == 0); + ATF_CHECK(jitcall(code, pkt, 29, 29) == 0); + + /* Set IP header length to 16. Packet is too short. */ + pkt[14] = 4; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_no_ctx); +ATF_TC_HEAD(libbpfjit_cop_no_ctx, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COP " + "instruction can't be accepted without a context"); +} + +ATF_TC_BODY(libbpfjit_cop_no_ctx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_MISC+BPF_COP, 0), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(!bpf_validate(insns, insn_count)); + + ATF_CHECK(bpfjit_generate_code(NULL, insns, insn_count) == NULL); +} + +ATF_TC(libbpfjit_copx_no_ctx); +ATF_TC_HEAD(libbpfjit_copx_no_ctx, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COPX " + "instruction can't be accepted without a context"); +} + +ATF_TC_BODY(libbpfjit_copx_no_ctx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(!bpf_validate(insns, insn_count)); + + ATF_CHECK(bpfjit_generate_code(NULL, insns, insn_count) == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * For every new test please also add a similar test + * to ../../net/bpfjit/t_bpfjit.c + */ + ATF_TP_ADD_TC(tp, libbpfjit_empty); + ATF_TP_ADD_TC(tp, libbpfjit_ret_k); + ATF_TP_ADD_TC(tp, libbpfjit_bad_ret_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_add_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_sub_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mul_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div0_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div1_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div2_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div4_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div10_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div10000_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div7609801_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div80000000_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod0_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod1_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod2_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod4_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod10_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod10000_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod7609801_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod80000000_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_and_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_or_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_xor_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_lsh_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_lsh0_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_rsh_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_rsh0_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_modulo_k); + ATF_TP_ADD_TC(tp, libbpfjit_alu_add_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_sub_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mul_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div0_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div1_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div2_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div4_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div10_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div10000_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div7609801_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_div80000000_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod0_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod1_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod2_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod4_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod10_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod10000_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod7609801_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_mod80000000_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_and_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_or_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_xor_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_lsh_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_lsh0_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_rsh_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_rsh0_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_modulo_x); + ATF_TP_ADD_TC(tp, libbpfjit_alu_neg); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_ja); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_ja_invalid); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_ja_overflow); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jgt_k); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jge_k); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jeq_k); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jset_k); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_modulo_k); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jgt_x); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jge_x); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jeq_x); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jset_x); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jeq_x_noinit_ax); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jeq_x_noinit_a); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_jeq_x_noinit_x); + ATF_TP_ADD_TC(tp, libbpfjit_jmp_modulo_x); + ATF_TP_ADD_TC(tp, libbpfjit_ld_abs); + ATF_TP_ADD_TC(tp, libbpfjit_ld_abs_k_overflow); + ATF_TP_ADD_TC(tp, libbpfjit_ld_ind); + ATF_TP_ADD_TC(tp, libbpfjit_ld_ind_k_overflow); + ATF_TP_ADD_TC(tp, libbpfjit_ld_ind_x_overflow1); + ATF_TP_ADD_TC(tp, libbpfjit_ld_ind_x_overflow2); + ATF_TP_ADD_TC(tp, libbpfjit_ld_len); + ATF_TP_ADD_TC(tp, libbpfjit_ld_imm); + ATF_TP_ADD_TC(tp, libbpfjit_ldx_imm1); + ATF_TP_ADD_TC(tp, libbpfjit_ldx_imm2); + ATF_TP_ADD_TC(tp, libbpfjit_ldx_len1); + ATF_TP_ADD_TC(tp, libbpfjit_ldx_len2); + ATF_TP_ADD_TC(tp, libbpfjit_ldx_msh); + ATF_TP_ADD_TC(tp, libbpfjit_misc_tax); + ATF_TP_ADD_TC(tp, libbpfjit_misc_txa); + ATF_TP_ADD_TC(tp, libbpfjit_st1); + ATF_TP_ADD_TC(tp, libbpfjit_st2); + ATF_TP_ADD_TC(tp, libbpfjit_st3); + ATF_TP_ADD_TC(tp, libbpfjit_st4); + ATF_TP_ADD_TC(tp, libbpfjit_st5); + ATF_TP_ADD_TC(tp, libbpfjit_stx1); + ATF_TP_ADD_TC(tp, libbpfjit_stx2); + ATF_TP_ADD_TC(tp, libbpfjit_stx3); + ATF_TP_ADD_TC(tp, libbpfjit_stx4); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_abs_1); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_abs_2); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_abs_3); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_ind_1); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_ind_2); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_ind_3); + ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_ind_4); + ATF_TP_ADD_TC(tp, libbpfjit_abc_ja); + ATF_TP_ADD_TC(tp, libbpfjit_abc_ja_over); + ATF_TP_ADD_TC(tp, libbpfjit_abc_ld_chain); + ATF_TP_ADD_TC(tp, libbpfjit_examples_1); + ATF_TP_ADD_TC(tp, libbpfjit_examples_2); + ATF_TP_ADD_TC(tp, libbpfjit_examples_3); + ATF_TP_ADD_TC(tp, libbpfjit_cop_no_ctx); + ATF_TP_ADD_TC(tp, libbpfjit_copx_no_ctx); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbpfjit/t_cop.c b/contrib/netbsd-tests/lib/libbpfjit/t_cop.c new file mode 100644 index 0000000..7b3b086 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbpfjit/t_cop.c @@ -0,0 +1,657 @@ +/* $NetBSD: t_cop.c,v 1.4 2014/07/13 21:35:33 alnsn Exp $ */ + +/*- + * Copyright (c) 2013-2014 Alexander Nasonov. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_cop.c,v 1.4 2014/07/13 21:35:33 alnsn Exp $"); + +#include +#include +#include + +#define __BPF_PRIVATE +#include +#include + +static uint32_t retA(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); +static uint32_t retBL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); +static uint32_t retWL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); +static uint32_t retNF(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); +static uint32_t setARG(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); + +static const bpf_copfunc_t copfuncs[] = { + &retA, + &retBL, + &retWL, + &retNF, + &setARG +}; + +static const bpf_ctx_t ctx = { + .copfuncs = copfuncs, + .nfuncs = sizeof(copfuncs) / sizeof(copfuncs[0]), + .extwords = 0 +}; + +static uint32_t +retA(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return A; +} + +static uint32_t +retBL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return args->buflen; +} + +static uint32_t +retWL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return args->wirelen; +} + +static uint32_t +retNF(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return bc->nfuncs; +} + +/* + * COP function with a side effect. + */ +static uint32_t +setARG(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + bool *arg = (bool *)args->arg; + bool old = *arg; + + *arg = true; + return old; +} + +ATF_TC(libbpfjit_cop_no_ctx); +ATF_TC_HEAD(libbpfjit_cop_no_ctx, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that bpf program with BPF_COP " + "instruction isn't valid without a context"); +} + +ATF_TC_BODY(libbpfjit_cop_no_ctx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_MISC+BPF_COP, 0), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + bpfjit_func_t code; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(!bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_CHECK(code == NULL); +} + +ATF_TC(libbpfjit_cop_ret_A); +ATF_TC_HEAD(libbpfjit_cop_ret_A, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns a content of the A register"); +} + +ATF_TC_BODY(libbpfjit_cop_ret_A, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 0), // retA + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 13); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_ret_buflen); +ATF_TC_HEAD(libbpfjit_cop_ret_buflen, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns the buflen argument"); +} + +ATF_TC_BODY(libbpfjit_cop_ret_buflen, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 1), // retBL + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == sizeof(pkt)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_ret_wirelen); +ATF_TC_HEAD(libbpfjit_cop_ret_wirelen, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns the wirelen argument"); +} + +ATF_TC_BODY(libbpfjit_cop_ret_wirelen, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 2), // retWL + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == sizeof(pkt)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_ret_nfuncs); +ATF_TC_HEAD(libbpfjit_cop_ret_nfuncs, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns nfuncs member of the context argument"); +} + +ATF_TC_BODY(libbpfjit_cop_ret_nfuncs, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 3), // retNF + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == ctx.nfuncs); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_side_effect); +ATF_TC_HEAD(libbpfjit_cop_side_effect, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that ABC optimization doesn't skip BPF_COP call"); +} + +ATF_TC_BODY(libbpfjit_cop_side_effect, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), + BPF_STMT(BPF_MISC+BPF_COP, 4), // setARG + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99999), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + bool arg = false; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = NULL, + .arg = &arg + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + ATF_CHECK(arg == true); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_copx); +ATF_TC_HEAD(libbpfjit_cop_copx, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test BPF_COP call followed by BPF_COPX call"); +} + +ATF_TC_BODY(libbpfjit_cop_copx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), /* A <- 1 */ + BPF_STMT(BPF_MISC+BPF_COP, 0), /* retA */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A = P[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_MISC+BPF_COPX, 0), /* retNF */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 2 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3 + ctx.nfuncs); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_invalid_index); +ATF_TC_HEAD(libbpfjit_cop_invalid_index, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that out-of-range coprocessor function fails validation"); +} + +ATF_TC_BODY(libbpfjit_cop_invalid_index, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 6), // invalid index + BPF_STMT(BPF_RET+BPF_K, 27) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL); +} + +ATF_TC(libbpfjit_copx_no_ctx); +ATF_TC_HEAD(libbpfjit_copx_no_ctx, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that bpf program with BPF_COPX " + "instruction isn't valid without a context"); +} + +ATF_TC_BODY(libbpfjit_copx_no_ctx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_MISC+BPF_COP, 0), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + bpfjit_func_t code; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(!bpf_validate(insns, insn_count)); + + code = bpfjit_generate_code(NULL, insns, insn_count); + ATF_CHECK(code == NULL); +} + +ATF_TC(libbpfjit_copx_ret_A); +ATF_TC_HEAD(libbpfjit_copx_ret_A, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns a content of the A register"); +} + +ATF_TC_BODY(libbpfjit_copx_ret_A, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LDX+BPF_IMM, 0), // retA + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 13); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_ret_buflen); +ATF_TC_HEAD(libbpfjit_copx_ret_buflen, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns the buflen argument"); +} + +ATF_TC_BODY(libbpfjit_copx_ret_buflen, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LDX+BPF_IMM, 1), // retBL + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == sizeof(pkt)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_ret_wirelen); +ATF_TC_HEAD(libbpfjit_copx_ret_wirelen, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns the wirelen argument"); +} + +ATF_TC_BODY(libbpfjit_copx_ret_wirelen, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_IMM, 2), // retWL + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == sizeof(pkt)); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_ret_nfuncs); +ATF_TC_HEAD(libbpfjit_copx_ret_nfuncs, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns nfuncs member of the context argument"); +} + +ATF_TC_BODY(libbpfjit_copx_ret_nfuncs, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LDX+BPF_IMM, 3), // retNF + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == ctx.nfuncs); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_side_effect); +ATF_TC_HEAD(libbpfjit_copx_side_effect, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that ABC optimization doesn't skip BPF_COPX call"); +} + +ATF_TC_BODY(libbpfjit_copx_side_effect, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), + BPF_STMT(BPF_LDX+BPF_IMM, 4), // setARG + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99999), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + bool arg = false; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = NULL, + .arg = &arg + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + ATF_CHECK(arg == true); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_cop); +ATF_TC_HEAD(libbpfjit_copx_cop, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test BPF_COPX call followed by BPF_COP call"); +} + +ATF_TC_BODY(libbpfjit_copx_cop, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_IMM, 2), /* X <- 2 */ + BPF_STMT(BPF_MISC+BPF_COPX, 0), /* retWL */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A = P[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_MISC+BPF_COP, 3), /* retNF */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 2 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 5 + ctx.nfuncs); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_invalid_index); +ATF_TC_HEAD(libbpfjit_copx_invalid_index, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that out-of-range BPF_COPX call fails at runtime"); +} + +ATF_TC_BODY(libbpfjit_copx_invalid_index, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_IMM, 5), // invalid index + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_K, 27) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + + bpfjit_free_code(code); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * For every new test please also add a similar test + * to ../../net/bpfjit/t_cop.c + */ + ATF_TP_ADD_TC(tp, libbpfjit_cop_no_ctx); + ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_A); + ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_buflen); + ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_wirelen); + ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_nfuncs); + ATF_TP_ADD_TC(tp, libbpfjit_cop_side_effect); + ATF_TP_ADD_TC(tp, libbpfjit_cop_copx); + ATF_TP_ADD_TC(tp, libbpfjit_cop_invalid_index); + + ATF_TP_ADD_TC(tp, libbpfjit_copx_no_ctx); + ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_A); + ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_buflen); + ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_wirelen); + ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_nfuncs); + ATF_TP_ADD_TC(tp, libbpfjit_copx_side_effect); + ATF_TP_ADD_TC(tp, libbpfjit_copx_cop); + ATF_TP_ADD_TC(tp, libbpfjit_copx_invalid_index); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libbpfjit/t_extmem.c b/contrib/netbsd-tests/lib/libbpfjit/t_extmem.c new file mode 100644 index 0000000..ab6ea88 --- /dev/null +++ b/contrib/netbsd-tests/lib/libbpfjit/t_extmem.c @@ -0,0 +1,483 @@ +/* $NetBSD: t_extmem.c,v 1.3 2014/07/14 19:11:15 alnsn Exp $ */ + +/*- + * Copyright (c) 2014 Alexander Nasonov. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_extmem.c,v 1.3 2014/07/14 19:11:15 alnsn Exp $"); + +#include +#include +#include + +#define __BPF_PRIVATE +#include +#include + +static uint32_t retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); + +static const bpf_copfunc_t copfuncs[] = { + &retM +}; + +static const bpf_ctx_t ctx = { + .copfuncs = copfuncs, + .nfuncs = sizeof(copfuncs) / sizeof(copfuncs[0]), + .extwords = 4, + .preinited = BPF_MEMWORD_INIT(0) | BPF_MEMWORD_INIT(3), +}; + +static uint32_t +retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return args->mem[(uintptr_t)args->arg]; +} + + +ATF_TC(libbpfjit_extmem_load_default); +ATF_TC_HEAD(libbpfjit_extmem_load_default, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that external memory " + "is zero initialized by default"); +} + +ATF_TC_BODY(libbpfjit_extmem_load_default, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_MEM, 1), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_extmem_load_preinited); +ATF_TC_HEAD(libbpfjit_extmem_load_preinited, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test a load of external " + "pre-initialized memory"); +} + +ATF_TC_BODY(libbpfjit_extmem_load_preinited, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_MEM, 3), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_extmem_invalid_load); +ATF_TC_HEAD(libbpfjit_extmem_invalid_load, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that out-of-range load " + "fails validation"); +} + +ATF_TC_BODY(libbpfjit_extmem_invalid_load, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_MEM, 4), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL); +} + +ATF_TC(libbpfjit_extmem_store); +ATF_TC_HEAD(libbpfjit_extmem_store, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test stores to external memory"); +} + +ATF_TC_BODY(libbpfjit_extmem_store, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), /* A <- 1 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2 */ + BPF_STMT(BPF_ST, 1), /* M[1] <- A */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_STX, 2), /* M[2] <- X */ + BPF_STMT(BPF_ST, 3), /* M[3] <- A */ + BPF_STMT(BPF_RET+BPF_A, 0) /* ret A */ + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 7; + + mem[1] = mem[2] = 0xdeadbeef; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3); + + bpfjit_free_code(code); + + ATF_CHECK(mem[0] == 0); + ATF_CHECK(mem[1] == 1); + ATF_CHECK(mem[2] == 2); + ATF_CHECK(mem[3] == 3); +} + +ATF_TC(libbpfjit_extmem_side_effect); +ATF_TC_HEAD(libbpfjit_extmem_side_effect, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that ABC optimization doesn\'t " + "skip stores to external memory"); +} + +ATF_TC_BODY(libbpfjit_extmem_side_effect, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A <- P[0] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2 */ + BPF_STMT(BPF_ST, 1), /* M[1] <- A */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_STX, 2), /* M[2] <- X */ + BPF_STMT(BPF_ST, 3), /* M[3] <- A */ + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99), /* A <- P[99] */ + BPF_STMT(BPF_RET+BPF_A, 0) /* ret A */ + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 1 }; + uint32_t mem[ctx.extwords]; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 7; + + mem[1] = mem[2] = 0xdeadbeef; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + + bpfjit_free_code(code); + + ATF_CHECK(mem[0] == 0); + ATF_CHECK(mem[1] == 1); + ATF_CHECK(mem[2] == 2); + ATF_CHECK(mem[3] == 3); +} + +ATF_TC(libbpfjit_extmem_invalid_store); +ATF_TC_HEAD(libbpfjit_extmem_invalid_store, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that out-of-range store " + "fails validation"); +} + +ATF_TC_BODY(libbpfjit_extmem_invalid_store, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_ST, 4), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL); +} + +ATF_TC(libbpfjit_cop_ret_mem); +ATF_TC_HEAD(libbpfjit_cop_ret_mem, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns a content of external memory word"); +} + +ATF_TC_BODY(libbpfjit_cop_ret_mem, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_ST, 2), + BPF_STMT(BPF_LD+BPF_IMM, 137), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_MISC+BPF_COP, 0), // retM + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + void *arg = (void*)(uintptr_t)2; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .arg = arg, + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 13); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_cop_ret_preinited_mem); +ATF_TC_HEAD(libbpfjit_cop_ret_preinited_mem, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function that " + "returns a content of external pre-initialized memory word"); +} + +ATF_TC_BODY(libbpfjit_cop_ret_preinited_mem, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_ST, 2), + BPF_STMT(BPF_LD+BPF_IMM, 137), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_MISC+BPF_COP, 0), // retM + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + void *arg = (void*)(uintptr_t)3; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .arg = arg, + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_ret_mem); +ATF_TC_HEAD(libbpfjit_copx_ret_mem, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns a content of external memory word"); +} + +ATF_TC_BODY(libbpfjit_copx_ret_mem, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_ST, 2), + BPF_STMT(BPF_LD+BPF_IMM, 137), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + void *arg = (void*)(uintptr_t)2; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .arg = arg, + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 13); + + bpfjit_free_code(code); +} + +ATF_TC(libbpfjit_copx_ret_preinited_mem); +ATF_TC_HEAD(libbpfjit_copx_ret_preinited_mem, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function that " + "returns a content of external pre-initialized memory word"); +} + +ATF_TC_BODY(libbpfjit_copx_ret_preinited_mem, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_ST, 2), + BPF_STMT(BPF_LD+BPF_IMM, 137), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + void *arg = (void*)(uintptr_t)3; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .arg = arg, + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + code = bpfjit_generate_code(&ctx, insns, insn_count); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3); + + bpfjit_free_code(code); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * For every new test please also add a similar test + * to ../../net/bpfjit/t_extmem.c + */ + ATF_TP_ADD_TC(tp, libbpfjit_extmem_load_default); + ATF_TP_ADD_TC(tp, libbpfjit_extmem_load_preinited); + ATF_TP_ADD_TC(tp, libbpfjit_extmem_invalid_load); + ATF_TP_ADD_TC(tp, libbpfjit_extmem_store); + ATF_TP_ADD_TC(tp, libbpfjit_extmem_side_effect); + ATF_TP_ADD_TC(tp, libbpfjit_extmem_invalid_store); + ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_mem); + ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_preinited_mem); + ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_mem); + ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_preinited_mem); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c new file mode 100644 index 0000000..56a1be8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2014/08/10 05:47:38 matt Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2014/08/10 05:47:38 matt Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S new file mode 100644 index 0000000..d237982 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S @@ -0,0 +1,10 @@ +/* $NetBSD: return_one.S,v 1.1 2014/08/10 05:47:38 matt Exp $ */ + +#include + +ENTRY_NP(return_one) + mov x0, #1 + ret + .globl return_one_end +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S b/contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S new file mode 100644 index 0000000..5308876 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/arm/return_one.S b/contrib/netbsd-tests/lib/libc/arch/arm/return_one.S new file mode 100644 index 0000000..18800e2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/arm/return_one.S @@ -0,0 +1,11 @@ +/* $NetBSD: return_one.S,v 1.2 2014/01/26 20:42:06 matt Exp $ */ + +#include + +ENTRY_NP(return_one) + mov r0, #1 + RET + .align 0 + .globl return_one_end +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S b/contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S new file mode 100644 index 0000000..5308876 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c new file mode 100644 index 0000000..11a20f5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c @@ -0,0 +1,65 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include +#include + +#include "../../common/exec_prot.h" + +/* + * Support for executable space protection has always been erratic under i386. + * Originally IA-32 can't do per-page execute permission, so it is + * implemented using different executable segments for %cs (code segment). + * This only allows coarse grained protection, especially when memory starts + * being fragmented. + * Later, PAE was introduced together with a NX/XD bit in the page table + * entry to offer per-page permission. + */ +int +exec_prot_support(void) +{ + int pae; + size_t pae_len = sizeof(pae); + + if (sysctlbyname("machdep.pae", &pae, &pae_len, NULL, 0) == -1) + return PARTIAL_XP; + + if (pae == 1) { + if (system("cpuctl identify 0 | grep -q NOX") == 0 || + system("cpuctl identify 0 | grep -q XD") == 0) + return PERPAGE_XP; + } + + return PARTIAL_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/i386/return_one.S b/contrib/netbsd-tests/lib/libc/arch/i386/return_one.S new file mode 100644 index 0000000..f80fd74 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/i386/return_one.S @@ -0,0 +1,10 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include + +RCSID("$NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +_ENTRY(return_one) + movl $0x1,%eax + ret +LABEL(return_one_end) diff --git a/contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S new file mode 100644 index 0000000..5cb5f39 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S @@ -0,0 +1,11 @@ +/* $NetBSD: return_one.S,v 1.2 2016/08/05 15:02:29 scole Exp $ */ + +#include + +.globl return_one_end + +ENTRY(return_one,0) + mov ret0=1 + br.ret.sptk.few rp +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c new file mode 100644 index 0000000..ba1cd8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S b/contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S new file mode 100644 index 0000000..5308876 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */ + +#include + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/mips/return_one.S b/contrib/netbsd-tests/lib/libc/arch/mips/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/mips/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c new file mode 100644 index 0000000..623456b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2014/09/03 19:34:26 matt Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2014/09/03 19:34:26 matt Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return PERPAGE_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S b/contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S new file mode 100644 index 0000000..ba3d678 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S @@ -0,0 +1,12 @@ +/* $NetBSD: return_one.S,v 1.1 2014/09/03 19:34:26 matt Exp $ */ + +#include + +.globl return_one, return_one_end + +ENTRY_NP(return_one) + l.addi r11, r0, 1 + l.jr lr + l.nop +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c new file mode 100644 index 0000000..81c1d86 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c @@ -0,0 +1,52 @@ +/* $NetBSD: exec_prot_support.c,v 1.2 2012/03/16 08:51:47 matt Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.2 2012/03/16 08:51:47 matt Exp $"); + +#include "../../common/exec_prot.h" + +#include + +int +exec_prot_support(void) +{ + int execprot = 0; + size_t len = sizeof(execprot); + + if (sysctlbyname("machdep.execprot", &execprot, &len, NULL, 0) < 0) + return NOTIMPL; + + if (execprot) + return PERPAGE_XP; + + return NO_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S b/contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S new file mode 100644 index 0000000..10629c5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S @@ -0,0 +1,12 @@ +/* $NetBSD: return_one.S,v 1.3 2015/03/29 00:38:36 matt Exp $ */ + +#include + +.globl return_one_start, return_one_end + +_ENTRY(return_one) +return_one_start: + li %r3, 1 + blr +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c new file mode 100644 index 0000000..91c5ff4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2014/09/19 17:36:26 matt Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2014/09/19 17:36:26 matt Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return PERPAGE_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S b/contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S new file mode 100644 index 0000000..d393fd1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S @@ -0,0 +1,11 @@ +/* $NetBSD: return_one.S,v 1.2 2015/03/28 07:07:54 matt Exp $ */ + +#include + + .globl return_one_end + +ENTRY_NP(return_one) + li a0, 1 + ret +return_one_end: +END(return_one) diff --git a/contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S b/contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S b/contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c new file mode 100644 index 0000000..8ca38b4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c @@ -0,0 +1,42 @@ +/* $NetBSD: exec_prot_support.c,v 1.2 2016/12/31 11:51:20 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.2 2016/12/31 11:51:20 martin Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + + return PERPAGE_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S new file mode 100644 index 0000000..ec8bcdd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S @@ -0,0 +1,11 @@ +/* $NetBSD: return_one.S,v 1.2 2016/12/31 11:51:20 martin Exp $ */ + +#include + +.global return_one_end + +ENTRY(return_one) +return_one: + retl + mov 1, %o0 +return_one_end: diff --git a/contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c new file mode 100644 index 0000000..474cfc7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c @@ -0,0 +1,41 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $"); + +#include "../../common/exec_prot.h" + +int +exec_prot_support(void) +{ + return NOTIMPL; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/vax/return_one.S b/contrib/netbsd-tests/lib/libc/arch/vax/return_one.S new file mode 100644 index 0000000..3495260 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/vax/return_one.S @@ -0,0 +1,8 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */ + +#include + +.globl return_one, return_one_end; + +return_one: return_one_end: + nop diff --git a/contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c new file mode 100644 index 0000000..2d8363d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c @@ -0,0 +1,50 @@ +/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:11 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:11 jym Exp $"); + +#include + +#include "../../common/exec_prot.h" + +/* + * When the NX/XD flag is present, the protection should be enabled. + */ +int +exec_prot_support(void) +{ + if (system("cpuctl identify 0 | grep -q NOX") == 0 || + system("cpuctl identify 0 | grep -q XD") == 0) + return PERPAGE_XP; + + return NO_XP; +} diff --git a/contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S new file mode 100644 index 0000000..0903001 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S @@ -0,0 +1,10 @@ +/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:11 jym Exp $ */ + +#include + +RCSID("$NetBSD: return_one.S,v 1.1 2011/07/18 23:16:11 jym Exp $"); + +_ENTRY(return_one) + movq $0x1, %rax + retq +LABEL(return_one_end) diff --git a/contrib/netbsd-tests/lib/libc/c063/t_faccessat.c b/contrib/netbsd-tests/lib/libc/c063/t_faccessat.c new file mode 100644 index 0000000..7de4f61 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_faccessat.c @@ -0,0 +1,189 @@ +/* $NetBSD: t_faccessat.c,v 1.3 2017/01/10 15:13:56 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_faccessat.c,v 1.3 2017/01/10 15:13:56 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DIR "dir" +#define FILE "dir/faccessat" +#define BASEFILE "faccessat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/faccessaterr" + +ATF_TC(faccessat_fd); +ATF_TC_HEAD(faccessat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat works with fd"); +} +ATF_TC_BODY(faccessat_fd, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(faccessat(dfd, BASEFILE, F_OK, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(faccessat_fdcwd); +ATF_TC_HEAD(faccessat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that faccessat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(faccessat_fdcwd, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(faccessat(AT_FDCWD, BASEFILE, F_OK, 0) == 0); +} + +ATF_TC(faccessat_fdcwderr); +ATF_TC_HEAD(faccessat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that faccessat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(faccessat_fdcwderr, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(faccessat(AT_FDCWD, FILEERR, F_OK, 0) == -1); +} + +ATF_TC(faccessat_fderr1); +ATF_TC_HEAD(faccessat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat fail with bad path"); +} +ATF_TC_BODY(faccessat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(faccessat(dfd, FILEERR, F_OK, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(faccessat_fderr2); +ATF_TC_HEAD(faccessat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat fails with bad fdat"); +} +ATF_TC_BODY(faccessat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(faccessat(dfd, BASEFILE, F_OK, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(faccessat_fderr3); +ATF_TC_HEAD(faccessat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat fails with fd as -1"); +} +ATF_TC_BODY(faccessat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(faccessat(-1, FILE, F_OK, 0) == -1); +} + +ATF_TC(faccessat_fdlink); +ATF_TC_HEAD(faccessat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat works on symlink"); +} +ATF_TC_BODY(faccessat_fdlink, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); /* NB: FILE does not exists */ + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(faccessat(dfd, BASELINK, F_OK, 0) == -1); + ATF_REQUIRE(errno == ENOENT); + +#ifdef __FreeBSD__ + atf_tc_expect_fail("Depends on non-standard behavior not mentioned in POSIX.1-2008"); +#endif + ATF_REQUIRE(faccessat(dfd, BASELINK, F_OK, AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, faccessat_fd); + ATF_TP_ADD_TC(tp, faccessat_fdcwd); + ATF_TP_ADD_TC(tp, faccessat_fdcwderr); + ATF_TP_ADD_TC(tp, faccessat_fderr1); + ATF_TP_ADD_TC(tp, faccessat_fderr2); + ATF_TP_ADD_TC(tp, faccessat_fderr3); + ATF_TP_ADD_TC(tp, faccessat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c b/contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c new file mode 100644 index 0000000..a7bb683 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c @@ -0,0 +1,198 @@ +/* $NetBSD: t_fchmodat.c,v 1.3 2017/01/10 15:13:56 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_fchmodat.c,v 1.3 2017/01/10 15:13:56 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DIR "dir" +#define FILE "dir/fchmodat" +#define BASEFILE "fchmodat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/fchmodaterr" + +ATF_TC(fchmodat_fd); +ATF_TC_HEAD(fchmodat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat works with fd"); +} +ATF_TC_BODY(fchmodat_fd, tc) +{ + int dfd; + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchmodat(dfd, BASEFILE, 0600, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &st) == 0); + ATF_REQUIRE(st.st_mode = 0600); +} + +ATF_TC(fchmodat_fdcwd); +ATF_TC_HEAD(fchmodat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fchmodat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(fchmodat_fdcwd, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(fchmodat(AT_FDCWD, BASEFILE, 0600, 0) == 0); + + ATF_REQUIRE(stat(BASEFILE, &st) == 0); + ATF_REQUIRE(st.st_mode = 0600); +} + +ATF_TC(fchmodat_fdcwderr); +ATF_TC_HEAD(fchmodat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fchmodat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(fchmodat_fdcwderr, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(fchmodat(AT_FDCWD, FILEERR, 0600, 0) == -1); +} + +ATF_TC(fchmodat_fderr1); +ATF_TC_HEAD(fchmodat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat fail with bad path"); +} +ATF_TC_BODY(fchmodat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchmodat(dfd, FILEERR, 0600, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fchmodat_fderr2); +ATF_TC_HEAD(fchmodat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat fails with bad fdat"); +} +ATF_TC_BODY(fchmodat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchmodat(dfd, BASEFILE, 0600, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fchmodat_fderr3); +ATF_TC_HEAD(fchmodat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat fails with fd as -1"); +} +ATF_TC_BODY(fchmodat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmodat(-1, FILE, 0600, 0) == -1); +} + +ATF_TC(fchmodat_fdlink); +ATF_TC_HEAD(fchmodat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchmodat works on symlink"); +} +ATF_TC_BODY(fchmodat_fdlink, tc) +{ + int dfdlink; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); + + ATF_REQUIRE((dfdlink = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(fchmodat(dfdlink, BASELINK, 0600, 0) == -1); + ATF_REQUIRE(errno = ENOENT); + + ATF_REQUIRE(fchmodat(dfdlink, BASELINK, 0600, AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfdlink) == 0); + + ATF_REQUIRE(lstat(LINK, &st) == 0); + ATF_REQUIRE(st.st_mode = 0600); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fchmodat_fd); + ATF_TP_ADD_TC(tp, fchmodat_fdcwd); + ATF_TP_ADD_TC(tp, fchmodat_fdcwderr); + ATF_TP_ADD_TC(tp, fchmodat_fderr1); + ATF_TP_ADD_TC(tp, fchmodat_fderr2); + ATF_TP_ADD_TC(tp, fchmodat_fderr3); + ATF_TP_ADD_TC(tp, fchmodat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fchownat.c b/contrib/netbsd-tests/lib/libc/c063/t_fchownat.c new file mode 100644 index 0000000..631d55a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_fchownat.c @@ -0,0 +1,248 @@ +/* $NetBSD: t_fchownat.c,v 1.4 2017/01/10 15:13:56 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_fchownat.c,v 1.4 2017/01/10 15:13:56 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DIR "dir" +#define FILE "dir/fchownat" +#define BASEFILE "fchownat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/fchownaterr" +#define USER "nobody" + +static int getuser(uid_t *, gid_t *); + +static int getuser(uid_t *uid, gid_t *gid) +{ + struct passwd *pw; + + if ((pw = getpwnam(USER)) == NULL) + return -1; + + *uid = pw->pw_uid; + *gid = pw->pw_gid; + + return 0; +} + +ATF_TC(fchownat_fd); +ATF_TC_HEAD(fchownat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat works with fd"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fd, tc) +{ + int dfd; + int fd; + uid_t uid; + gid_t gid; + struct stat st; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchownat(dfd, BASEFILE, uid, gid, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &st) == 0); + ATF_REQUIRE(st.st_uid == uid); + ATF_REQUIRE(st.st_gid == gid); +} + +ATF_TC(fchownat_fdcwd); +ATF_TC_HEAD(fchownat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fchownat works with fd as AT_FDCWD"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fdcwd, tc) +{ + int fd; + uid_t uid; + gid_t gid; + struct stat st; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(fchownat(AT_FDCWD, BASEFILE, uid, gid, 0) == 0); + + ATF_REQUIRE(stat(BASEFILE, &st) == 0); + ATF_REQUIRE(st.st_uid == uid); + ATF_REQUIRE(st.st_gid == gid); +} + +ATF_TC(fchownat_fdcwderr); +ATF_TC_HEAD(fchownat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fchownat fails with fd as AT_FDCWD and bad path"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fdcwderr, tc) +{ + uid_t uid; + gid_t gid; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(fchownat(AT_FDCWD, FILEERR, uid, gid, 0) == -1); +} + +ATF_TC(fchownat_fderr1); +ATF_TC_HEAD(fchownat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat fail with bad path"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fderr1, tc) +{ + int dfd; + uid_t uid; + gid_t gid; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchownat(dfd, FILEERR, uid, gid, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fchownat_fderr2); +ATF_TC_HEAD(fchownat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat fails with bad fdat"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + uid_t uid; + gid_t gid; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(fchownat(dfd, BASEFILE, uid, gid, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fchownat_fderr3); +ATF_TC_HEAD(fchownat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat fails with fd as -1"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fderr3, tc) +{ + int fd; + uid_t uid; + gid_t gid; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchownat(-1, FILE, uid, gid, 0) == -1); +} + +ATF_TC(fchownat_fdlink); +ATF_TC_HEAD(fchownat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fchownat works on symlink"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(fchownat_fdlink, tc) +{ + int dfd; + uid_t uid; + gid_t gid; + struct stat st; + + ATF_REQUIRE(getuser(&uid, &gid) == 0); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); /* Target does not exists */ + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(fchownat(dfd, BASELINK, uid, gid, 0) == -1); + ATF_REQUIRE(errno == ENOENT); + + ATF_REQUIRE(fchownat(dfd, BASELINK, uid, gid, + AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(lstat(LINK, &st) == 0); + ATF_REQUIRE(st.st_uid == uid); + ATF_REQUIRE(st.st_gid == gid); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fchownat_fd); + ATF_TP_ADD_TC(tp, fchownat_fdcwd); + ATF_TP_ADD_TC(tp, fchownat_fdcwderr); + ATF_TP_ADD_TC(tp, fchownat_fderr1); + ATF_TP_ADD_TC(tp, fchownat_fderr2); + ATF_TP_ADD_TC(tp, fchownat_fderr3); + ATF_TP_ADD_TC(tp, fchownat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fexecve.c b/contrib/netbsd-tests/lib/libc/c063/t_fexecve.c new file mode 100644 index 0000000..b9aa017 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_fexecve.c @@ -0,0 +1,95 @@ +/* $NetBSD: t_fexecve.c,v 1.3 2017/01/10 15:15:09 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_fexecve.c,v 1.3 2017/01/10 15:15:09 christos Exp $"); + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ATF_TC(fexecve); +ATF_TC_HEAD(fexecve, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fexecve works"); +} +ATF_TC_BODY(fexecve, tc) +{ + int status; + pid_t pid; + const char *const argv[] = { "touch", "test", NULL }; + const char *const envp[] = { NULL }; + + ATF_REQUIRE((pid = fork()) != -1); + if (pid == 0) { + int fd; + + if ((fd = open("/usr/bin/touch", O_RDONLY, 0)) == -1) + err(EXIT_FAILURE, "open /usr/bin/touch"); + + if (fexecve(fd, __UNCONST(argv), __UNCONST(envp)) == -1) { + int error; + if (errno == ENOSYS) + error = 76; + else + error = EXIT_FAILURE; + (void)close(fd); + err(error, "fexecve"); + } + } + + ATF_REQUIRE(waitpid(pid, &status, 0) != -1); + if (!WIFEXITED(status)) + atf_tc_fail("child process did not exit cleanly"); + if (WEXITSTATUS(status) == 76) + atf_tc_expect_fail("fexecve not implemented"); + else + ATF_REQUIRE(WEXITSTATUS(status) == EXIT_SUCCESS); + + ATF_REQUIRE(access("test", F_OK) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fexecve); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fstatat.c b/contrib/netbsd-tests/lib/libc/c063/t_fstatat.c new file mode 100644 index 0000000..c17961f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_fstatat.c @@ -0,0 +1,197 @@ +/* $NetBSD: t_fstatat.c,v 1.3 2017/01/10 15:13:56 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_fstatat.c,v 1.3 2017/01/10 15:13:56 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DIR "dir" +#define FILE "dir/fstatat" +#define BASEFILE "fstatat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/symlink" + +ATF_TC(fstatat_fd); +ATF_TC_HEAD(fstatat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat works with fd"); +} +ATF_TC_BODY(fstatat_fd, tc) +{ + int dfd; + int fd; + struct stat st1, st2; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fstatat(dfd, BASEFILE, &st1, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &st2) == 0); + ATF_REQUIRE(memcmp(&st1, &st2, sizeof(st1)) == 0); +} + +ATF_TC(fstatat_fdcwd); +ATF_TC_HEAD(fstatat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fstatat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(fstatat_fdcwd, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(fstatat(AT_FDCWD, BASEFILE, &st, 0) == 0); +} + +ATF_TC(fstatat_fdcwderr); +ATF_TC_HEAD(fstatat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that fstatat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(fstatat_fdcwderr, tc) +{ + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(fstatat(AT_FDCWD, FILEERR, &st, 0) == -1); +} + +ATF_TC(fstatat_fderr1); +ATF_TC_HEAD(fstatat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat fail with bad path"); +} +ATF_TC_BODY(fstatat_fderr1, tc) +{ + int dfd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(fstatat(dfd, FILEERR, &st, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fstatat_fderr2); +ATF_TC_HEAD(fstatat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat fails with bad fdat"); +} +ATF_TC_BODY(fstatat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(fstatat(dfd, BASEFILE, &st, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(fstatat_fderr3); +ATF_TC_HEAD(fstatat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat fails with fd as -1"); +} +ATF_TC_BODY(fstatat_fderr3, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fstatat(-1, FILE, &st, 0) == -1); +} + +ATF_TC(fstatat_fdlink); +ATF_TC_HEAD(fstatat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat works on symlink"); +} +ATF_TC_BODY(fstatat_fdlink, tc) +{ + int dfd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); /* target does not exists */ + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(fstatat(dfd, BASELINK, &st, 0) == -1); + ATF_REQUIRE(errno == ENOENT); + + ATF_REQUIRE(fstatat(dfd, BASELINK, &st, AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fstatat_fd); + ATF_TP_ADD_TC(tp, fstatat_fdcwd); + ATF_TP_ADD_TC(tp, fstatat_fdcwderr); + ATF_TP_ADD_TC(tp, fstatat_fderr1); + ATF_TP_ADD_TC(tp, fstatat_fderr2); + ATF_TP_ADD_TC(tp, fstatat_fderr3); + ATF_TP_ADD_TC(tp, fstatat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_linkat.c b/contrib/netbsd-tests/lib/libc/c063/t_linkat.c new file mode 100644 index 0000000..b49a3f0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_linkat.c @@ -0,0 +1,217 @@ +/* $NetBSD: t_linkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_linkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ODIR "olddir" +#define NDIR "newdir" +#define FILE "olddir/old" +#define BASEFILE "old" +#define RELFILE "../olddir/old" +#define TARGET "newdir/new" +#define BASETARGET "new" +#define LINK "olddir/symlink" +#define BASELINK "symlink" +#define FILEERR "olddir/olderr" + +ATF_TC(linkat_fd); +ATF_TC_HEAD(linkat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that linkat works with fd"); +} +ATF_TC_BODY(linkat_fd, tc) +{ + int ofd, nfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(linkat(ofd, BASEFILE, nfd, BASETARGET, 0) == 0); + ATF_REQUIRE(close(ofd) == 0); + ATF_REQUIRE(close(nfd) == 0); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + ATF_REQUIRE(stat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(linkat_fdcwd); +ATF_TC_HEAD(linkat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that linkat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(linkat_fdcwd, tc) +{ + int fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(linkat(AT_FDCWD, FILE, AT_FDCWD, TARGET, 0) == 0); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + ATF_REQUIRE(stat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(linkat_fdcwderr); +ATF_TC_HEAD(linkat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that linkat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(linkat_fdcwderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(linkat(AT_FDCWD, FILEERR, AT_FDCWD, TARGET, 0) == -1); +} + +ATF_TC(linkat_fderr); +ATF_TC_HEAD(linkat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that linkat fails with fd as -1"); +} +ATF_TC_BODY(linkat_fderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(linkat(-1, FILE, AT_FDCWD, TARGET, 0) == -1); + ATF_REQUIRE(linkat(AT_FDCWD, FILE, -1, TARGET, 0) == -1); + ATF_REQUIRE(linkat(-1, FILE, -1, TARGET, 0) == -1); +} + +ATF_TC(linkat_fdlink1); +ATF_TC_HEAD(linkat_fdlink1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that linkat works on symlink target"); +} +ATF_TC_BODY(linkat_fdlink1, tc) +{ + int ofd, nfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + ATF_REQUIRE(symlink(RELFILE, LINK) == 0); + + ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(linkat(ofd, BASELINK, nfd, BASETARGET, + AT_SYMLINK_FOLLOW) == 0); + ATF_REQUIRE(close(ofd) == 0); + ATF_REQUIRE(close(nfd) == 0); + + ATF_REQUIRE(lstat(LINK, &ost) == 0); + ATF_REQUIRE(lstat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino != nst.st_ino); + + ATF_REQUIRE(lstat(FILE, &ost) == 0); + ATF_REQUIRE(lstat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + + +ATF_TC(linkat_fdlink2); +ATF_TC_HEAD(linkat_fdlink2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that linkat works on symlink source"); +} +ATF_TC_BODY(linkat_fdlink2, tc) +{ + int ofd, nfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + ATF_REQUIRE(symlink(RELFILE, LINK) == 0); + + ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(linkat(ofd, BASELINK, nfd, BASETARGET, 0) == 0); + ATF_REQUIRE(close(ofd) == 0); + ATF_REQUIRE(close(nfd) == 0); + + ATF_REQUIRE(lstat(LINK, &ost) == 0); + ATF_REQUIRE(lstat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); + + ATF_REQUIRE(lstat(FILE, &ost) == 0); + ATF_REQUIRE(lstat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino != nst.st_ino); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, linkat_fd); + ATF_TP_ADD_TC(tp, linkat_fdcwd); + ATF_TP_ADD_TC(tp, linkat_fdcwderr); + ATF_TP_ADD_TC(tp, linkat_fderr); + ATF_TP_ADD_TC(tp, linkat_fdlink1); + ATF_TP_ADD_TC(tp, linkat_fdlink2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c b/contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c new file mode 100644 index 0000000..23c53d7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c @@ -0,0 +1,120 @@ +/* $NetBSD: t_mkdirat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_mkdirat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DIR "dir" +#define SDIR "dir/openat" +#define BASESDIR "openat" +#define SDIRERR "dir/openaterr" + +ATF_TC(mkdirat_fd); +ATF_TC_HEAD(mkdirat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mkdirat works with fd"); +} +ATF_TC_BODY(mkdirat_fd, tc) +{ + int dfd; + mode_t mode = 0755; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(mkdirat(dfd, BASESDIR, mode) != -1); + ATF_REQUIRE(close(dfd) == 0); + ATF_REQUIRE(access(SDIR, F_OK) == 0); +} + +ATF_TC(mkdirat_fdcwd); +ATF_TC_HEAD(mkdirat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mkdirat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(mkdirat_fdcwd, tc) +{ + mode_t mode = 0755; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(mkdirat(AT_FDCWD, SDIR, mode) != -1); + ATF_REQUIRE(access(SDIR, F_OK) == 0); +} + +ATF_TC(mkdirat_fdcwderr); +ATF_TC_HEAD(mkdirat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mkdirat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(mkdirat_fdcwderr, tc) +{ + mode_t mode = 0755; + + ATF_REQUIRE(mkdirat(AT_FDCWD, SDIRERR, mode) == -1); +} + +ATF_TC(mkdirat_fderr); +ATF_TC_HEAD(mkdirat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mkdirat fails with fd as -1"); +} +ATF_TC_BODY(mkdirat_fderr, tc) +{ + int fd; + mode_t mode = 0755; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(SDIR, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(mkdirat(-1, SDIR, mode) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mkdirat_fd); + ATF_TP_ADD_TC(tp, mkdirat_fdcwd); + ATF_TP_ADD_TC(tp, mkdirat_fdcwderr); + ATF_TP_ADD_TC(tp, mkdirat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c b/contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c new file mode 100644 index 0000000..4f91afd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c @@ -0,0 +1,120 @@ +/* $NetBSD: t_mkfifoat.c,v 1.4 2017/01/14 20:55:26 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_mkfifoat.c,v 1.4 2017/01/14 20:55:26 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DIR "dir" +#define FIFO "dir/openat" +#define BASEFIFO "openat" +#define FIFOERR "dir/openaterr" + +ATF_TC(mkfifoat_fd); +ATF_TC_HEAD(mkfifoat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mkfifoat works with fd"); +} +ATF_TC_BODY(mkfifoat_fd, tc) +{ + int dfd; + mode_t mode = 0600; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(mkfifoat(dfd, BASEFIFO, mode) != -1); + ATF_REQUIRE(access(FIFO, F_OK) == 0); + (void)close(dfd); +} + +ATF_TC(mkfifoat_fdcwd); +ATF_TC_HEAD(mkfifoat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mkfifoat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(mkfifoat_fdcwd, tc) +{ + mode_t mode = 0600; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(mkfifoat(AT_FDCWD, FIFO, mode) != -1); + ATF_REQUIRE(access(FIFO, F_OK) == 0); +} + +ATF_TC(mkfifoat_fdcwderr); +ATF_TC_HEAD(mkfifoat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mkfifoat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(mkfifoat_fdcwderr, tc) +{ + mode_t mode = 0600; + + ATF_REQUIRE(mkfifoat(AT_FDCWD, FIFOERR, mode) == -1); +} + +ATF_TC(mkfifoat_fderr); +ATF_TC_HEAD(mkfifoat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mkfifoat fails with fd as -1"); +} +ATF_TC_BODY(mkfifoat_fderr, tc) +{ + int fd; + mode_t mode = 0600; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FIFO, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(mkfifoat(-1, FIFO, mode) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mkfifoat_fd); + ATF_TP_ADD_TC(tp, mkfifoat_fdcwd); + ATF_TP_ADD_TC(tp, mkfifoat_fdcwderr); + ATF_TP_ADD_TC(tp, mkfifoat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_mknodat.c b/contrib/netbsd-tests/lib/libc/c063/t_mknodat.c new file mode 100644 index 0000000..7c3ab9b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_mknodat.c @@ -0,0 +1,151 @@ +/* $NetBSD: t_mknodat.c,v 1.4 2017/01/10 15:15:09 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_mknodat.c,v 1.4 2017/01/10 15:15:09 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DIR "dir" +#define FILE "dir/openat" +#define BASEFILE "openat" +#define FILEERR "dir/openaterr" + +static dev_t get_devnull(void); + +static dev_t +get_devnull(void) +{ + struct stat st; + + if (stat(_PATH_DEVNULL, &st) != 0) + return NODEV; + + return st.st_rdev; +} + + +ATF_TC(mknodat_fd); +ATF_TC_HEAD(mknodat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mknodat works with fd"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(mknodat_fd, tc) +{ + int dfd; + int fd; + dev_t dev; + mode_t mode = S_IFCHR|0600; + + ATF_REQUIRE((dev = get_devnull()) != NODEV); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = mknodat(dfd, BASEFILE, mode, dev)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(access(FILE, F_OK) == 0); + (void)close(dfd); +} + +ATF_TC(mknodat_fdcwd); +ATF_TC_HEAD(mknodat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mknodat works with fd as AT_FDCWD"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(mknodat_fdcwd, tc) +{ + int fd; + dev_t dev; + mode_t mode = S_IFCHR|0600; + + ATF_REQUIRE((dev = get_devnull()) != NODEV); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = mknodat(AT_FDCWD, FILE, mode, dev)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(access(FILE, F_OK) == 0); +} + +ATF_TC(mknodat_fdcwderr); +ATF_TC_HEAD(mknodat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that mknodat fails with fd as AT_FDCWD and bad path"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(mknodat_fdcwderr, tc) +{ + int fd; + dev_t dev; + mode_t mode = S_IFCHR|0600; + + ATF_REQUIRE((dev = get_devnull()) != NODEV); + ATF_REQUIRE((fd = mknodat(AT_FDCWD, FILEERR, mode, dev)) == -1); +} + +ATF_TC(mknodat_fderr); +ATF_TC_HEAD(mknodat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that mknodat fails with fd as -1"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(mknodat_fderr, tc) +{ + int fd; + dev_t dev; + mode_t mode = S_IFCHR|0600; + + ATF_REQUIRE((dev = get_devnull()) != NODEV); + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE((fd = mknodat(-1, FILE, mode, dev)) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mknodat_fd); + ATF_TP_ADD_TC(tp, mknodat_fdcwd); + ATF_TP_ADD_TC(tp, mknodat_fdcwderr); + ATF_TP_ADD_TC(tp, mknodat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_o_search.c b/contrib/netbsd-tests/lib/libc/c063/t_o_search.c new file mode 100644 index 0000000..7cefa8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_o_search.c @@ -0,0 +1,281 @@ +/* $NetBSD: t_o_search.c,v 1.5 2017/01/10 22:25:01 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_o_search.c,v 1.5 2017/01/10 22:25:01 christos Exp $"); + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * dholland 20130112: disable tests that require O_SEARCH semantics + * until a decision is reached about the semantics of O_SEARCH and a + * non-broken implementation is available. + */ +#if (O_MASK & O_SEARCH) != 0 +#define USE_O_SEARCH +#endif + +#define DIR "dir" +#define FILE "dir/o_search" +#define BASEFILE "o_search" + + +ATF_TC(o_search_perm1); +ATF_TC_HEAD(o_search_perm1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat enforces search permission"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(o_search_perm1, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) == -1); + ATF_REQUIRE(errno == EACCES); + + ATF_REQUIRE(close(dfd) == 0); +} + +#ifdef USE_O_SEARCH + +ATF_TC(o_search_root_flag1); +ATF_TC_HEAD(o_search_root_flag1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that root openat honours O_SEARCH"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(o_search_root_flag1, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 444) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(o_search_unpriv_flag1); +ATF_TC_HEAD(o_search_unpriv_flag1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat honours O_SEARCH"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(o_search_unpriv_flag1, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(fchmod(dfd, 444) == 0); + + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); + + ATF_REQUIRE(close(dfd) == 0); +} + +#endif /* USE_O_SEARCH */ + +ATF_TC(o_search_perm2); +ATF_TC_HEAD(o_search_perm2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that faccessat enforces search permission"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(o_search_perm2, tc) +{ + int dfd; + int fd; + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == -1); + ATF_REQUIRE(errno == EACCES); + + ATF_REQUIRE(close(dfd) == 0); +} + +#ifdef USE_O_SEARCH + +ATF_TC(o_search_root_flag2); +ATF_TC_HEAD(o_search_root_flag2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that root fstatat honours O_SEARCH"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(o_search_root_flag2, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 444) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(o_search_unpriv_flag2); +ATF_TC_HEAD(o_search_unpriv_flag2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that fstatat honours O_SEARCH"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} +ATF_TC_BODY(o_search_unpriv_flag2, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 644) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(fchmod(dfd, 444) == 0); + + ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); + + ATF_REQUIRE(close(dfd) == 0); +} + +#endif /* USE_O_SEARCH */ + + +ATF_TC(o_search_notdir); +ATF_TC_HEAD(o_search_notdir, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat fails with non dir fd"); +} +ATF_TC_BODY(o_search_notdir, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(FILE, O_CREAT|O_RDWR|O_SEARCH, 0644)) != -1); + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) == -1); + ATF_REQUIRE(errno == ENOTDIR); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, o_search_perm1); +#ifdef USE_O_SEARCH + ATF_TP_ADD_TC(tp, o_search_root_flag1); + ATF_TP_ADD_TC(tp, o_search_unpriv_flag1); +#endif + ATF_TP_ADD_TC(tp, o_search_perm2); +#ifdef USE_O_SEARCH + ATF_TP_ADD_TC(tp, o_search_root_flag2); + ATF_TP_ADD_TC(tp, o_search_unpriv_flag2); +#endif + ATF_TP_ADD_TC(tp, o_search_notdir); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_openat.c b/contrib/netbsd-tests/lib/libc/c063/t_openat.c new file mode 100644 index 0000000..f7c8c74 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_openat.c @@ -0,0 +1,166 @@ +/* $NetBSD: t_openat.c,v 1.3 2017/01/10 15:13:56 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_openat.c,v 1.3 2017/01/10 15:13:56 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DIR "dir" +#define FILE "dir/openat" +#define BASEFILE "openat" +#define FILEERR "dir/openaterr" + +ATF_TC(openat_fd); +ATF_TC_HEAD(openat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat works with fd"); +} +ATF_TC_BODY(openat_fd, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDONLY, 0)) != -1); + ATF_REQUIRE(close(dfd) == 0); + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC(openat_fdcwd); +ATF_TC_HEAD(openat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that openat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(openat_fdcwd, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE((fd = openat(AT_FDCWD, BASEFILE, O_RDONLY, 0)) != -1); + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC(openat_fdcwderr); +ATF_TC_HEAD(openat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that openat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(openat_fdcwderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = openat(AT_FDCWD, FILEERR, O_RDONLY, 0)) == -1); +} + +ATF_TC(openat_fderr1); +ATF_TC_HEAD(openat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat fail with bad path"); +} +ATF_TC_BODY(openat_fderr1, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = openat(dfd, FILEERR, O_RDONLY, 0)) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(openat_fderr2); +ATF_TC_HEAD(openat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat fails with bad fdat"); +} +ATF_TC_BODY(openat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDONLY, 0)) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(openat_fderr3); +ATF_TC_HEAD(openat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that openat fails with fd as -1"); +} +ATF_TC_BODY(openat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((fd = openat(-1, FILE, O_RDONLY, 0)) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, openat_fd); + ATF_TP_ADD_TC(tp, openat_fdcwd); + ATF_TP_ADD_TC(tp, openat_fdcwderr); + ATF_TP_ADD_TC(tp, openat_fderr1); + ATF_TP_ADD_TC(tp, openat_fderr2); + ATF_TP_ADD_TC(tp, openat_fderr3); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c b/contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c new file mode 100644 index 0000000..cf14652 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c @@ -0,0 +1,158 @@ +/* $NetBSD: t_readlinkat.c,v 1.4 2017/01/10 15:13:56 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_readlinkat.c,v 1.4 2017/01/10 15:13:56 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DIR "dir" +#define FILE "dir/readlinkat" +#define BASEFILE "readlinkat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/readlinkaterr" + +ATF_TC(readlinkat_fd); +ATF_TC_HEAD(readlinkat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that readlinkat works with fd"); +} +ATF_TC_BODY(readlinkat_fd, tc) +{ + int dfd; + int fd; + ssize_t len; + char buf[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + len = readlinkat(dfd, BASELINK, buf, sizeof(buf)-1); + ATF_REQUIRE(len != -1); + buf[len] = 0; + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(strcmp(buf, FILE) == 0); +} + +ATF_TC(readlinkat_fdcwd); +ATF_TC_HEAD(readlinkat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that readlinkat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(readlinkat_fdcwd, tc) +{ + int fd; + ssize_t len; + char buf[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); + + len = readlinkat(AT_FDCWD, LINK, buf, sizeof(buf)-1); + ATF_REQUIRE(len != -1); + buf[len] = 0; + + ATF_REQUIRE(strcmp(buf, FILE) == 0); +} + +ATF_TC(readlinkat_fdcwderr); +ATF_TC_HEAD(readlinkat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that readlinkat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(readlinkat_fdcwderr, tc) +{ + char buf[MAXPATHLEN]; + + ATF_REQUIRE(readlinkat(AT_FDCWD, LINK, buf, sizeof(buf)) == -1); +} + +ATF_TC(readlinkat_fderr1); +ATF_TC_HEAD(readlinkat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that readlinkat fail with bad path"); +} +ATF_TC_BODY(readlinkat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(readlinkat(dfd, FILEERR, F_OK, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(readlinkat_fderr2); +ATF_TC_HEAD(readlinkat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that readlinkat fails with fd as -1"); +} +ATF_TC_BODY(readlinkat_fderr2, tc) +{ + int fd; + char buf[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); + + ATF_REQUIRE(readlinkat(-1, LINK, buf, sizeof(buf)) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, readlinkat_fd); + ATF_TP_ADD_TC(tp, readlinkat_fdcwd); + ATF_TP_ADD_TC(tp, readlinkat_fdcwderr); + ATF_TP_ADD_TC(tp, readlinkat_fderr1); + ATF_TP_ADD_TC(tp, readlinkat_fderr2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_renameat.c b/contrib/netbsd-tests/lib/libc/c063/t_renameat.c new file mode 100644 index 0000000..e297f2a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_renameat.c @@ -0,0 +1,152 @@ +/* $NetBSD: t_renameat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_renameat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ODIR "olddir" +#define NDIR "newdir" +#define FILE "olddir/old" +#define BASEFILE "old" +#define RELFILE "../olddir/old" +#define TARGET "newdir/new" +#define BASETARGET "new" +#define FILEERR "olddir/olderr" + +ATF_TC(renameat_fd); +ATF_TC_HEAD(renameat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that renameat works with fd"); +} +ATF_TC_BODY(renameat_fd, tc) +{ + int ofd, nfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + + ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(renameat(ofd, BASEFILE, nfd, BASETARGET) == 0); + ATF_REQUIRE(close(ofd) == 0); + ATF_REQUIRE(close(nfd) == 0); + + ATF_REQUIRE(stat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(renameat_fdcwd); +ATF_TC_HEAD(renameat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that renameat works with fd as AT_FDCWD"); +} + +ATF_TC_BODY(renameat_fdcwd, tc) +{ + int fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + + ATF_REQUIRE(renameat(AT_FDCWD, FILE, AT_FDCWD, TARGET) == 0); + + ATF_REQUIRE(stat(TARGET, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(renameat_fdcwderr); +ATF_TC_HEAD(renameat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that renameat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(renameat_fdcwderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(renameat(AT_FDCWD, FILEERR, AT_FDCWD, TARGET) == -1); +} + +ATF_TC(renameat_fderr); +ATF_TC_HEAD(renameat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that renameat fails with fd as -1"); +} +ATF_TC_BODY(renameat_fderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(renameat(-1, FILE, AT_FDCWD, TARGET) == -1); + ATF_REQUIRE(renameat(AT_FDCWD, FILE, -1, TARGET) == -1); + ATF_REQUIRE(renameat(-1, FILE, -1, TARGET) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, renameat_fd); + ATF_TP_ADD_TC(tp, renameat_fdcwd); + ATF_TP_ADD_TC(tp, renameat_fdcwderr); + ATF_TP_ADD_TC(tp, renameat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c b/contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c new file mode 100644 index 0000000..d62f289 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c @@ -0,0 +1,150 @@ +/* $NetBSD: t_symlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_symlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ODIR "olddir" +#define NDIR "newdir" +#define FILE "olddir/old" +#define BASEFILE "old" +#define RELFILE "../olddir/old" +#define LINK "newdir/symlink" +#define BASELINK "symlink" +#define FILEERR "olddir/olderr" + +ATF_TC(symlinkat_fd); +ATF_TC_HEAD(symlinkat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that symlinkat works with fd"); +} +ATF_TC_BODY(symlinkat_fd, tc) +{ + int dfd, fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE((dfd = open(NDIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(symlinkat(RELFILE, dfd, BASELINK) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + ATF_REQUIRE(stat(LINK, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(symlinkat_fdcwd); +ATF_TC_HEAD(symlinkat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that symlinkat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(symlinkat_fdcwd, tc) +{ + int fd; + struct stat ost, nst; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(symlinkat(RELFILE, AT_FDCWD, LINK) == 0); + + ATF_REQUIRE(stat(FILE, &ost) == 0); + ATF_REQUIRE(stat(LINK, &nst) == 0); + ATF_REQUIRE(ost.st_ino == nst.st_ino); +} + +ATF_TC(symlinkat_fdcwderr); +ATF_TC_HEAD(symlinkat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that symlinkat works with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(symlinkat_fdcwderr, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(symlinkat(FILEERR, AT_FDCWD, LINK) == 0); + ATF_REQUIRE(lstat(LINK, &st) == 0); + ATF_REQUIRE(stat(LINK, &st) == -1); + ATF_REQUIRE(errno == ENOENT); + +} + +ATF_TC(symlinkat_fderr); +ATF_TC_HEAD(symlinkat_fderr, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that symlinkat fails with fd as -1"); +} +ATF_TC_BODY(symlinkat_fderr, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(ODIR, 0755) == 0); + ATF_REQUIRE(mkdir(NDIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) != -1); + + ATF_REQUIRE(symlinkat(RELFILE, -1, LINK) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, symlinkat_fd); + ATF_TP_ADD_TC(tp, symlinkat_fdcwd); + ATF_TP_ADD_TC(tp, symlinkat_fdcwderr); + ATF_TP_ADD_TC(tp, symlinkat_fderr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c b/contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c new file mode 100644 index 0000000..9897b92 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c @@ -0,0 +1,177 @@ +/* $NetBSD: t_unlinkat.c,v 1.3 2017/01/10 15:13:56 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_unlinkat.c,v 1.3 2017/01/10 15:13:56 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DIR "dir" +#define FILE "dir/unlinkat" +#define BASEFILE "unlinkat" +#define FILEERR "dir/unlinkaterr" + +ATF_TC(unlinkat_fd); +ATF_TC_HEAD(unlinkat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that unlinkat works with fd"); +} +ATF_TC_BODY(unlinkat_fd, tc) +{ + int dfd; + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(unlinkat(dfd, BASEFILE, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(unlinkat_fdcwd); +ATF_TC_HEAD(unlinkat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that unlinkat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(unlinkat_fdcwd, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(unlinkat(AT_FDCWD, BASEFILE, 0) == 0); +} + +ATF_TC(unlinkat_fdcwderr); +ATF_TC_HEAD(unlinkat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that unlinkat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(unlinkat_fdcwderr, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(unlinkat(AT_FDCWD, FILEERR, 0) == -1); +} + +ATF_TC(unlinkat_fderr1); +ATF_TC_HEAD(unlinkat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that unlinkat fail with bad path"); +} +ATF_TC_BODY(unlinkat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(unlinkat(dfd, FILEERR, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(unlinkat_fderr2); +ATF_TC_HEAD(unlinkat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that unlinkat fails with bad fdat"); +} +ATF_TC_BODY(unlinkat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(unlinkat(dfd, BASEFILE, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(unlinkat_fderr3); +ATF_TC_HEAD(unlinkat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that unlinkat fails with fd as -1"); +} +ATF_TC_BODY(unlinkat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(unlinkat(-1, FILE, 0) == -1); +} + +ATF_TC(unlinkat_dir); +ATF_TC_HEAD(unlinkat_dir, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that unlinkat can remove directories"); +} +ATF_TC_BODY(unlinkat_dir, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + + ATF_REQUIRE(unlinkat(AT_FDCWD, DIR, 0) == -1); + ATF_REQUIRE(errno == EPERM); + ATF_REQUIRE(unlinkat(AT_FDCWD, DIR, AT_REMOVEDIR) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, unlinkat_fd); + ATF_TP_ADD_TC(tp, unlinkat_fdcwd); + ATF_TP_ADD_TC(tp, unlinkat_fdcwderr); + ATF_TP_ADD_TC(tp, unlinkat_fderr1); + ATF_TP_ADD_TC(tp, unlinkat_fderr2); + ATF_TP_ADD_TC(tp, unlinkat_fderr3); + ATF_TP_ADD_TC(tp, unlinkat_dir); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/c063/t_utimensat.c b/contrib/netbsd-tests/lib/libc/c063/t_utimensat.c new file mode 100644 index 0000000..682c2df --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/c063/t_utimensat.c @@ -0,0 +1,213 @@ +/* $NetBSD: t_utimensat.c,v 1.6 2017/01/10 15:13:56 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_utimensat.c,v 1.6 2017/01/10 15:13:56 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DIR "dir" +#define FILE "dir/utimensat" +#define BASEFILE "utimensat" +#define LINK "dir/symlink" +#define BASELINK "symlink" +#define FILEERR "dir/symlink" + +const struct timespec tptr[] = { + { 0x12345678, 987654321 }, + { 0x15263748, 123456789 }, +}; + +ATF_TC(utimensat_fd); +ATF_TC_HEAD(utimensat_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat works with fd"); +} +ATF_TC_BODY(utimensat_fd, tc) +{ + int dfd; + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(utimensat(dfd, BASEFILE, tptr, 0) == 0); + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(stat(FILE, &st) == 0); + ATF_REQUIRE(st.st_atimespec.tv_sec == tptr[0].tv_sec); + ATF_REQUIRE(st.st_atimespec.tv_nsec == tptr[0].tv_nsec); + ATF_REQUIRE(st.st_mtimespec.tv_sec == tptr[1].tv_sec); + ATF_REQUIRE(st.st_mtimespec.tv_nsec == tptr[1].tv_nsec); +} + +ATF_TC(utimensat_fdcwd); +ATF_TC_HEAD(utimensat_fdcwd, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that utimensat works with fd as AT_FDCWD"); +} +ATF_TC_BODY(utimensat_fdcwd, tc) +{ + int fd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(chdir(DIR) == 0); + ATF_REQUIRE(utimensat(AT_FDCWD, BASEFILE, tptr, 0) == 0); + + ATF_REQUIRE(stat(BASEFILE, &st) == 0); + ATF_REQUIRE(st.st_atimespec.tv_sec == tptr[0].tv_sec); + ATF_REQUIRE(st.st_atimespec.tv_nsec == tptr[0].tv_nsec); + ATF_REQUIRE(st.st_mtimespec.tv_sec == tptr[1].tv_sec); + ATF_REQUIRE(st.st_mtimespec.tv_nsec == tptr[1].tv_nsec); +} + +ATF_TC(utimensat_fdcwderr); +ATF_TC_HEAD(utimensat_fdcwderr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "See that utimensat fails with fd as AT_FDCWD and bad path"); +} +ATF_TC_BODY(utimensat_fdcwderr, tc) +{ + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(utimensat(AT_FDCWD, FILEERR, tptr, 0) == -1); +} + +ATF_TC(utimensat_fderr1); +ATF_TC_HEAD(utimensat_fderr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat fail with bad path"); +} +ATF_TC_BODY(utimensat_fderr1, tc) +{ + int dfd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + ATF_REQUIRE(utimensat(dfd, FILEERR, tptr, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(utimensat_fderr2); +ATF_TC_HEAD(utimensat_fderr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat fails with bad fdat"); +} +ATF_TC_BODY(utimensat_fderr2, tc) +{ + int dfd; + int fd; + char cwd[MAXPATHLEN]; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1); + ATF_REQUIRE(utimensat(dfd, BASEFILE, tptr, 0) == -1); + ATF_REQUIRE(close(dfd) == 0); +} + +ATF_TC(utimensat_fderr3); +ATF_TC_HEAD(utimensat_fderr3, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat fails with fd as -1"); +} +ATF_TC_BODY(utimensat_fderr3, tc) +{ + int fd; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(utimensat(-1, FILE, tptr, 0) == -1); +} + +ATF_TC(utimensat_fdlink); +ATF_TC_HEAD(utimensat_fdlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that utimensat works on symlink"); +} +ATF_TC_BODY(utimensat_fdlink, tc) +{ + int dfd; + struct stat st; + + ATF_REQUIRE(mkdir(DIR, 0755) == 0); + ATF_REQUIRE(symlink(FILE, LINK) == 0); /* NB: FILE does not exists */ + + ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1); + + ATF_REQUIRE(utimensat(dfd, BASELINK, tptr, 0) == -1); + ATF_REQUIRE(errno = ENOENT); + + ATF_REQUIRE(utimensat(dfd, BASELINK, tptr, AT_SYMLINK_NOFOLLOW) == 0); + + ATF_REQUIRE(close(dfd) == 0); + + ATF_REQUIRE(lstat(LINK, &st) == 0); + ATF_REQUIRE(st.st_atimespec.tv_sec == tptr[0].tv_sec); + ATF_REQUIRE(st.st_atimespec.tv_nsec == tptr[0].tv_nsec); + ATF_REQUIRE(st.st_mtimespec.tv_sec == tptr[1].tv_sec); + ATF_REQUIRE(st.st_mtimespec.tv_nsec == tptr[1].tv_nsec); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, utimensat_fd); + ATF_TP_ADD_TC(tp, utimensat_fdcwd); + ATF_TP_ADD_TC(tp, utimensat_fdcwderr); + ATF_TP_ADD_TC(tp, utimensat_fderr1); + ATF_TP_ADD_TC(tp, utimensat_fderr2); + ATF_TP_ADD_TC(tp, utimensat_fderr3); + ATF_TP_ADD_TC(tp, utimensat_fdlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/common/exec_prot.h b/contrib/netbsd-tests/lib/libc/common/exec_prot.h new file mode 100644 index 0000000..6e17f97 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/common/exec_prot.h @@ -0,0 +1,61 @@ +/* $NetBSD: exec_prot.h,v 1.1 2011/07/18 23:16:11 jym Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jean-Yves Migeon. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _TESTS_EXEC_PROT_H_ +#define _TESTS_EXEC_PROT_H_ + +/* + * Prototype definitions of external helper functions for executable + * mapping tests. + */ + +/* + * Trivial MD shellcode that justs returns 1. + */ +int return_one(void); /* begin marker -- shellcode entry */ +int return_one_end(void); /* end marker */ + +/* + * MD callback to verify whether host offers executable space protection. + * Returns execute protection level. + */ +int exec_prot_support(void); + +/* execute protection level */ +enum { + NOTIMPL = -1, /* callback not implemented */ + NO_XP, /* no execute protection */ + PERPAGE_XP, /* per-page execute protection */ + PARTIAL_XP /* partial execute protection. Depending on where the + page is located in virtual memory, executable space + protection may be enforced or not. */ +}; +#endif diff --git a/contrib/netbsd-tests/lib/libc/db/README b/contrib/netbsd-tests/lib/libc/db/README new file mode 100644 index 0000000..68f0ec7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/db/README @@ -0,0 +1,66 @@ +# $NetBSD: README,v 1.1 2011/01/07 15:05:58 pgoyette Exp $ +# @(#)README 8.8 (Berkeley) 7/31/94 + +Fairly large files (the command files) are built in this directory during +the test runs, and even larger files (the database files) are created in +"/var/tmp". If the latter directory doesn't exist, set the environmental +variable TMPDIR to a directory where the files can be built. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +The script file consists of lines with an initial character which is +the command for that line, or an initial character indicating a key +or data entry for a previous command. + +Legal command characters are as follows: + +c: compare a record + + must be followed by [kK][dD]; the data value in the database + associated with the specified key is compared to the specified + data value. +e: echo a string + + writes out the rest of the line into the output file; if the + last character is not a carriage-return, a newline is appended. +f: set the flags for the next command + + no value zero's the flags +g: do a get command + + must be followed by [kK] + + writes out the retrieved data DBT. +o [r]: dump [reverse] + + dump the database out, if 'r' is set, in reverse order. +p: do a put command + + must be followed by [kK][dD] +r: do a del command + + must be followed by [kK] unless R_CURSOR flag set. +S: sync the database +s: do a seq command + + must be followed by [kK] if R_CURSOR flag set. + + writes out the retrieved data DBT. + +Legal key/data characters are as follows: + +D [file]: data file + + set the current data value to the contents of the file +d [data]: + + set the current key value to the contents of the line. +K [file]: key file + + set the current key value to the contents of the file +k [data]: + + set the current key value to the contents of the line. + +Blank lines, lines with leading white space, and lines with leading +hash marks (#) are ignored. + +Options to dbtest are as follows: + + -d: Set the DB_LOCK flag. + -f: Use the file argument as the database file. + -i: Use the rest of the argument to set elements in the info + structure. If the type is btree, then "-i cachesize=10240" + will set BTREEINFO.cachesize to 10240. + -o: The rest of the argument is the output file instead of + using stdout. + -s: Don't delete the database file before opening it, i.e. + use the database file from a previous run. + +Dbtest requires two arguments, the type of access "hash", "recno" +or "btree", and the script name or "-" to indicate stdin. diff --git a/contrib/netbsd-tests/lib/libc/db/h_db.c b/contrib/netbsd-tests/lib/libc/db/h_db.c new file mode 100644 index 0000000..dd19a03 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/db/h_db.c @@ -0,0 +1,794 @@ +/* $NetBSD: h_db.c,v 1.3 2016/09/24 21:18:22 christos Exp $ */ + +/*- + * Copyright (c) 1992, 1993, 1994 + * 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 +#ifndef lint +__COPYRIGHT("@(#) Copyright (c) 1992, 1993, 1994\ + The Regents of the University of California. All rights reserved."); +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94"; +#else +__RCSID("$NetBSD: h_db.c,v 1.3 2016/09/24 21:18:22 christos Exp $"); +#endif +#endif /* not lint */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "btree.h" + +enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA }; + +static void compare(DBT *, DBT *); +static DBTYPE dbtype(const char *); +static void dump(DB *, int, int); +static void get(DB *, DBT *); +static void getdata(DB *, DBT *, DBT *); +static void put(DB *, DBT *, DBT *); +static void rem(DB *, DBT *); +static const char *sflags(int); +static void synk(DB *); +static void *rfile(char *, size_t *); +static void seq(DB *, DBT *); +static u_int setflags(char *); +static void *setinfo(DBTYPE, char *); +#ifdef __NetBSD__ +static void unlinkpg(DB *); +#endif +static void usage(void) __attribute__((__noreturn__)); +static void *xcopy(void *, size_t); +static void chkcmd(enum S); +static void chkdata(enum S); +static void chkkey(enum S); + +#ifdef STATISTICS +extern void __bt_stat(DB *); +#endif +#ifdef __NetBSD__ +extern int __bt_relink(BTREE *, PAGE *); +#endif + +static DBTYPE type; /* Database type. */ +static void *infop; /* Iflags. */ +static size_t lineno; /* Current line in test script. */ +static u_int flags; /* Current DB flags. */ +static int ofd = STDOUT_FILENO; /* Standard output fd. */ + +static DB *XXdbp; /* Global for gdb. */ +static size_t XXlineno; /* Fast breakpoint for gdb. */ + +int +main(int argc, char *argv[]) +{ + extern int optind; + extern char *optarg; + enum S command = COMMAND, state; + DB *dbp; + DBT data, key, keydata; + size_t len; + int ch, oflags, sflag; + char *fname, *infoarg, *p, *t, buf[8 * 1024]; + bool unlink_dbfile; + + infoarg = NULL; + fname = NULL; + unlink_dbfile = false; + oflags = O_CREAT | O_RDWR; + sflag = 0; + while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1) + switch (ch) { + case 'f': + fname = optarg; + break; + case 'i': + infoarg = optarg; + break; + case 'l': + oflags |= DB_LOCK; + break; + case 'o': + if ((ofd = open(optarg, + O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) + err(1, "Cannot create `%s'", optarg); + break; + case 's': + sflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 2) + usage(); + + /* Set the type. */ + type = dbtype(*argv++); + + /* Open the descriptor file. */ + if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL) + err(1, "Cannot reopen `%s'", *argv); + + /* Set up the db structure as necessary. */ + if (infoarg == NULL) + infop = NULL; + else + for (p = strtok(infoarg, ",\t "); p != NULL; + p = strtok(0, ",\t ")) + if (*p != '\0') + infop = setinfo(type, p); + + /* + * Open the DB. Delete any preexisting copy, you almost never + * want it around, and it often screws up tests. + */ + if (fname == NULL) { + const char *q = getenv("TMPDIR"); + if (q == NULL) + q = "/var/tmp"; + (void)snprintf(buf, sizeof(buf), "%s/__dbtest", q); + fname = buf; + (void)unlink(buf); + unlink_dbfile = true; + } else if (!sflag) + (void)unlink(fname); + + if ((dbp = dbopen(fname, + oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL) + err(1, "Cannot dbopen `%s'", fname); + XXdbp = dbp; + if (unlink_dbfile) + (void)unlink(fname); + + state = COMMAND; + for (lineno = 1; + (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) { + /* Delete the newline, displaying the key/data is easier. */ + if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL) + *t = '\0'; + if ((len = strlen(buf)) == 0 || isspace((unsigned char)*p) || + *p == '#') + continue; + + /* Convenient gdb break point. */ + if (XXlineno == lineno) + XXlineno = 1; + switch (*p) { + case 'c': /* compare */ + chkcmd(state); + state = KEY; + command = COMPARE; + break; + case 'e': /* echo */ + chkcmd(state); + /* Don't display the newline, if CR at EOL. */ + if (p[len - 2] == '\r') + --len; + if (write(ofd, p + 1, len - 1) != (ssize_t)len - 1 || + write(ofd, "\n", 1) != 1) + err(1, "write failed"); + break; + case 'g': /* get */ + chkcmd(state); + state = KEY; + command = GET; + break; + case 'p': /* put */ + chkcmd(state); + state = KEY; + command = PUT; + break; + case 'r': /* remove */ + chkcmd(state); + if (flags == R_CURSOR) { + rem(dbp, &key); + state = COMMAND; + } else { + state = KEY; + command = REMOVE; + } + break; + case 'S': /* sync */ + chkcmd(state); + synk(dbp); + state = COMMAND; + break; + case 's': /* seq */ + chkcmd(state); + if (flags == R_CURSOR) { + state = KEY; + command = SEQ; + } else + seq(dbp, &key); + break; + case 'f': + flags = setflags(p + 1); + break; + case 'D': /* data file */ + chkdata(state); + data.data = rfile(p + 1, &data.size); + goto ldata; + case 'd': /* data */ + chkdata(state); + data.data = xcopy(p + 1, len - 1); + data.size = len - 1; +ldata: switch (command) { + case COMPARE: + compare(&keydata, &data); + break; + case PUT: + put(dbp, &key, &data); + break; + default: + errx(1, "line %zu: command doesn't take data", + lineno); + } + if (type != DB_RECNO) + free(key.data); + free(data.data); + state = COMMAND; + break; + case 'K': /* key file */ + chkkey(state); + if (type == DB_RECNO) + errx(1, "line %zu: 'K' not available for recno", + lineno); + key.data = rfile(p + 1, &key.size); + goto lkey; + case 'k': /* key */ + chkkey(state); + if (type == DB_RECNO) { + static recno_t recno; + recno = atoi(p + 1); + key.data = &recno; + key.size = sizeof(recno); + } else { + key.data = xcopy(p + 1, len - 1); + key.size = len - 1; + } +lkey: switch (command) { + case COMPARE: + getdata(dbp, &key, &keydata); + state = DATA; + break; + case GET: + get(dbp, &key); + if (type != DB_RECNO) + free(key.data); + state = COMMAND; + break; + case PUT: + state = DATA; + break; + case REMOVE: + rem(dbp, &key); + if ((type != DB_RECNO) && (flags != R_CURSOR)) + free(key.data); + state = COMMAND; + break; + case SEQ: + seq(dbp, &key); + if ((type != DB_RECNO) && (flags != R_CURSOR)) + free(key.data); + state = COMMAND; + break; + default: + errx(1, "line %zu: command doesn't take a key", + lineno); + } + break; + case 'o': + dump(dbp, p[1] == 'r', 0); + break; +#ifdef __NetBSD__ + case 'O': + dump(dbp, p[1] == 'r', 1); + break; + case 'u': + unlinkpg(dbp); + break; +#endif + default: + errx(1, "line %zu: %s: unknown command character", + lineno, p); + } + } +#ifdef STATISTICS + /* + * -l must be used (DB_LOCK must be set) for this to be + * used, otherwise a page will be locked and it will fail. + */ + if (type == DB_BTREE && oflags & DB_LOCK) + __bt_stat(dbp); +#endif + if ((*dbp->close)(dbp)) + err(1, "db->close failed"); + (void)close(ofd); + return 0; +} + +#define NOOVERWRITE "put failed, would overwrite key\n" + +static void +compare(DBT *db1, DBT *db2) +{ + size_t len; + u_char *p1, *p2; + + if (db1->size != db2->size) + printf("compare failed: key->data len %zu != data len %zu\n", + db1->size, db2->size); + + len = MIN(db1->size, db2->size); + for (p1 = db1->data, p2 = db2->data; len--;) + if (*p1++ != *p2++) { + printf("compare failed at offset %lu\n", + (unsigned long)(p1 - (u_char *)db1->data)); + break; + } +} + +static void +get(DB *dbp, DBT *kp) +{ + DBT data; + + switch ((*dbp->get)(dbp, kp, &data, flags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case -1: + err(1, "line %zu: get failed", lineno); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "get failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else + (void)fprintf(stderr, "%zu: %.*s: %s", + lineno, (int)MIN(kp->size, 20), + (const char *)kp->data, + NOSUCHKEY); +#undef NOSUCHKEY + break; + } +} + +static void +getdata(DB *dbp, DBT *kp, DBT *dp) +{ + switch ((*dbp->get)(dbp, kp, dp, flags)) { + case 0: + return; + case -1: + err(1, "line %zu: getdata failed", lineno); + /* NOTREACHED */ + case 1: + errx(1, "line %zu: getdata failed, no such key", lineno); + /* NOTREACHED */ + } +} + +static void +put(DB *dbp, DBT *kp, DBT *dp) +{ + switch ((*dbp->put)(dbp, kp, dp, flags)) { + case 0: + break; + case -1: + err(1, "line %zu: put failed", lineno); + /* NOTREACHED */ + case 1: + (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1); + break; + } +} + +static void +rem(DB *dbp, DBT *kp) +{ + switch ((*dbp->del)(dbp, kp, flags)) { + case 0: + break; + case -1: + err(1, "line %zu: rem failed", lineno); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "rem failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else if (flags != R_CURSOR) + (void)fprintf(stderr, "%zu: %.*s: %s", + lineno, (int)MIN(kp->size, 20), + (const char *)kp->data, NOSUCHKEY); + else + (void)fprintf(stderr, + "%zu: rem of cursor failed\n", lineno); +#undef NOSUCHKEY + break; + } +} + +static void +synk(DB *dbp) +{ + switch ((*dbp->sync)(dbp, flags)) { + case 0: + break; + case -1: + err(1, "line %zu: synk failed", lineno); + /* NOTREACHED */ + } +} + +static void +seq(DB *dbp, DBT *kp) +{ + DBT data; + + switch (dbp->seq(dbp, kp, &data, flags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case -1: + err(1, "line %zu: seq failed", lineno); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "seq failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else if (flags == R_CURSOR) + (void)fprintf(stderr, "%zu: %.*s: %s", + lineno, (int)MIN(kp->size, 20), + (const char *)kp->data, NOSUCHKEY); + else + (void)fprintf(stderr, + "%zu: seq (%s) failed\n", lineno, sflags(flags)); +#undef NOSUCHKEY + break; + } +} + +static void +dump(DB *dbp, int rev, int recurse) +{ + DBT key, data; + int xflags, nflags; + + if (rev) { + xflags = R_LAST; +#ifdef __NetBSD__ + nflags = recurse ? R_RPREV : R_PREV; +#else + nflags = R_PREV; +#endif + } else { + xflags = R_FIRST; +#ifdef __NetBSD__ + nflags = recurse ? R_RNEXT : R_NEXT; +#else + nflags = R_NEXT; +#endif + } + for (;; xflags = nflags) + switch (dbp->seq(dbp, &key, &data, xflags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case 1: + goto done; + case -1: + err(1, "line %zu: (dump) seq failed", lineno); + /* NOTREACHED */ + } +done: return; +} + +#ifdef __NetBSD__ +void +unlinkpg(DB *dbp) +{ + BTREE *t = dbp->internal; + PAGE *h = NULL; + pgno_t pg; + + for (pg = P_ROOT; pg < t->bt_mp->npages; + mpool_put(t->bt_mp, h, 0), pg++) { + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) + break; + /* Look for a nonempty leaf page that has both left + * and right siblings. */ + if (h->prevpg == P_INVALID || h->nextpg == P_INVALID) + continue; + if (NEXTINDEX(h) == 0) + continue; + if ((h->flags & (P_BLEAF | P_RLEAF))) + break; + } + if (h == NULL || pg == t->bt_mp->npages) { + errx(1, "%s: no appropriate page found", __func__); + return; + } + if (__bt_relink(t, h) != 0) { + perror("unlinkpg"); + goto cleanup; + } + h->prevpg = P_INVALID; + h->nextpg = P_INVALID; +cleanup: + mpool_put(t->bt_mp, h, MPOOL_DIRTY); +} +#endif + +static u_int +setflags(char *s) +{ + char *p; + + for (; isspace((unsigned char)*s); ++s); + if (*s == '\n' || *s == '\0') + return 0; + if ((p = strchr(s, '\n')) != NULL) + *p = '\0'; + if (!strcmp(s, "R_CURSOR")) return R_CURSOR; + if (!strcmp(s, "R_FIRST")) return R_FIRST; + if (!strcmp(s, "R_IAFTER")) return R_IAFTER; + if (!strcmp(s, "R_IBEFORE")) return R_IBEFORE; + if (!strcmp(s, "R_LAST")) return R_LAST; + if (!strcmp(s, "R_NEXT")) return R_NEXT; + if (!strcmp(s, "R_NOOVERWRITE")) return R_NOOVERWRITE; + if (!strcmp(s, "R_PREV")) return R_PREV; + if (!strcmp(s, "R_SETCURSOR")) return R_SETCURSOR; + + errx(1, "line %zu: %s: unknown flag", lineno, s); + /* NOTREACHED */ +} + +static const char * +sflags(int xflags) +{ + switch (xflags) { + case R_CURSOR: return "R_CURSOR"; + case R_FIRST: return "R_FIRST"; + case R_IAFTER: return "R_IAFTER"; + case R_IBEFORE: return "R_IBEFORE"; + case R_LAST: return "R_LAST"; + case R_NEXT: return "R_NEXT"; + case R_NOOVERWRITE: return "R_NOOVERWRITE"; + case R_PREV: return "R_PREV"; + case R_SETCURSOR: return "R_SETCURSOR"; + } + + return "UNKNOWN!"; +} + +static DBTYPE +dbtype(const char *s) +{ + if (!strcmp(s, "btree")) + return DB_BTREE; + if (!strcmp(s, "hash")) + return DB_HASH; + if (!strcmp(s, "recno")) + return DB_RECNO; + errx(1, "%s: unknown type (use btree, hash or recno)", s); + /* NOTREACHED */ +} + +static void * +setinfo(DBTYPE dtype, char *s) +{ + static BTREEINFO ib; + static HASHINFO ih; + static RECNOINFO rh; + char *eq; + + if ((eq = strchr(s, '=')) == NULL) + errx(1, "%s: illegal structure set statement", s); + *eq++ = '\0'; + if (!isdigit((unsigned char)*eq)) + errx(1, "%s: structure set statement must be a number", s); + + switch (dtype) { + case DB_BTREE: + if (!strcmp("flags", s)) { + ib.flags = atoi(eq); + return &ib; + } + if (!strcmp("cachesize", s)) { + ib.cachesize = atoi(eq); + return &ib; + } + if (!strcmp("maxkeypage", s)) { + ib.maxkeypage = atoi(eq); + return &ib; + } + if (!strcmp("minkeypage", s)) { + ib.minkeypage = atoi(eq); + return &ib; + } + if (!strcmp("lorder", s)) { + ib.lorder = atoi(eq); + return &ib; + } + if (!strcmp("psize", s)) { + ib.psize = atoi(eq); + return &ib; + } + break; + case DB_HASH: + if (!strcmp("bsize", s)) { + ih.bsize = atoi(eq); + return &ih; + } + if (!strcmp("ffactor", s)) { + ih.ffactor = atoi(eq); + return &ih; + } + if (!strcmp("nelem", s)) { + ih.nelem = atoi(eq); + return &ih; + } + if (!strcmp("cachesize", s)) { + ih.cachesize = atoi(eq); + return &ih; + } + if (!strcmp("lorder", s)) { + ih.lorder = atoi(eq); + return &ih; + } + break; + case DB_RECNO: + if (!strcmp("flags", s)) { + rh.flags = atoi(eq); + return &rh; + } + if (!strcmp("cachesize", s)) { + rh.cachesize = atoi(eq); + return &rh; + } + if (!strcmp("lorder", s)) { + rh.lorder = atoi(eq); + return &rh; + } + if (!strcmp("reclen", s)) { + rh.reclen = atoi(eq); + return &rh; + } + if (!strcmp("bval", s)) { + rh.bval = atoi(eq); + return &rh; + } + if (!strcmp("psize", s)) { + rh.psize = atoi(eq); + return &rh; + } + break; + } + errx(1, "%s: unknown structure value", s); + /* NOTREACHED */ +} + +static void * +rfile(char *name, size_t *lenp) +{ + struct stat sb; + void *p; + int fd; + char *np; + + for (; isspace((unsigned char)*name); ++name) + continue; + if ((np = strchr(name, '\n')) != NULL) + *np = '\0'; + if ((fd = open(name, O_RDONLY, 0)) == -1 || fstat(fd, &sb) == -1) + err(1, "Cannot open `%s'", name); +#ifdef NOT_PORTABLE + if (sb.st_size > (off_t)SIZE_T_MAX) { + errno = E2BIG; + err("Cannot process `%s'", name); + } +#endif + if ((p = malloc((size_t)sb.st_size)) == NULL) + err(1, "Cannot allocate %zu bytes", (size_t)sb.st_size); + if (read(fd, p, (ssize_t)sb.st_size) != (ssize_t)sb.st_size) + err(1, "read failed"); + *lenp = (size_t)sb.st_size; + (void)close(fd); + return p; +} + +static void * +xcopy(void *text, size_t len) +{ + void *p; + + if ((p = malloc(len)) == NULL) + err(1, "Cannot allocate %zu bytes", len); + (void)memmove(p, text, len); + return p; +} + +static void +chkcmd(enum S state) +{ + if (state != COMMAND) + errx(1, "line %zu: not expecting command", lineno); +} + +static void +chkdata(enum S state) +{ + if (state != DATA) + errx(1, "line %zu: not expecting data", lineno); +} + +static void +chkkey(enum S state) +{ + if (state != KEY) + errx(1, "line %zu: not expecting a key", lineno); +} + +static void +usage(void) +{ + (void)fprintf(stderr, +#ifdef __NetBSD__ + "Usage: %s [-lu] [-f file] [-i info] [-o file] [-O file] " +#else + "Usage: %s [-l] [-f file] [-i info] [-o file] " +#endif + "type script\n", getprogname()); + exit(1); +} diff --git a/contrib/netbsd-tests/lib/libc/db/h_lfsr.c b/contrib/netbsd-tests/lib/libc/db/h_lfsr.c new file mode 100644 index 0000000..3f3d712 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/db/h_lfsr.c @@ -0,0 +1,179 @@ +/*- + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: h_lfsr.c,v 1.1 2015/11/18 18:35:35 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#define MAXKEY 0xffff +#ifdef DEBUG +#define DPRINTF(...) printf(__VA_ARGS__) +#else +#define DPRINTF(...) +#endif + +static uint16_t +next(uint16_t *cur) +{ + uint16_t lsb = *cur & 1; + *cur >>= 1; + *cur ^= (-lsb) & 0xB400u; + return *cur; +} + +int +main(int argc, char *argv[]) +{ + char buf[65536]; + char kb[256]; + DBT key, val; + DB *db; + HASHINFO hi; + uint8_t c; + uint16_t len; + uint32_t pagesize = atoi(argv[1]); + + memset(&hi, 0, sizeof(hi)); + memset(buf, 'a', sizeof(buf)); + hi.bsize = pagesize; + hi.nelem = 65536; + hi.ffactor = 128; + + key.data = kb; + val.data = buf; + + db = dbopen(NULL, O_CREAT|O_TRUNC|O_RDWR, 0, DB_HASH, &hi); + if (db == NULL) + err(EXIT_FAILURE, "dbopen"); + + len = 0xaec1; + for (size_t i = 0; i < MAXKEY; i++) { + key.size = (len & 0xff) + 1; + c = len >> 8; + memset(kb, c, key.size); + val.size = (next(&len) & 0xff) + 1; + switch ((*db->put)(db, &key, &val, R_NOOVERWRITE)) { + case 0: + DPRINTF("put %zu %zu %#x\n", + key.size, val.size, c); + break; + case -1: + err(EXIT_FAILURE, "put error %zu %zu %#x", + key.size, val.size, c); + case 1: + errx(EXIT_FAILURE, "put overwrite %zu %zu %#x", + key.size, val.size, c); + default: + abort(); + } + } + + len = 0xaec1; + for (size_t i = 0; i < MAXKEY; i++) { + key.size = (len & 0xff) + 1; + c = len >> 8; + memset(kb, c, key.size); + next(&len); + switch ((*db->get)(db, &key, &val, 0)) { + case 0: + DPRINTF("get %zu %zu %#x\n", + key.size, val.size, c); + break; + case -1: + err(EXIT_FAILURE, "get %zu %zu %#x", + key.size, val.size, c); + case 1: + errx(EXIT_FAILURE, "get not found %zu %zu %#x", + key.size, val.size, c); + default: + abort(); + } + if (memcmp(key.data, kb, key.size) != 0) + errx(EXIT_FAILURE, "get badkey %zu %zu %#x", + key.size, val.size, c); + if (val.size != (len & 0xff) + 1U) + errx(EXIT_FAILURE, "get badvallen %zu %zu %#x", + key.size, val.size, c); + if (memcmp(val.data, buf, val.size) != 0) + errx(EXIT_FAILURE, "get badval %zu %zu %#x", + key.size, val.size, c); + } + + len = 0xaec1; + for (size_t i = 0; i < MAXKEY; i++) { + key.size = (len & 0xff) + 1; + c = len >> 8; + memset(kb, c, key.size); + next(&len); + switch ((*db->del)(db, &key, 0)) { + case 0: + DPRINTF("del %zu %zu %#x\n", + key.size, val.size, c); + break; + case -1: + err(EXIT_FAILURE, "del %zu %zu %#x", key.size, + val.size, c); + case 1: + errx(EXIT_FAILURE, "del not found %zu %zu %#x", + key.size, val.size, c); + default: + abort(); + } + } + + len = 0xaec1; + for (size_t i = 0; i < MAXKEY; i++) { + key.size = (len & 0xff) + 1; + c = len >> 8; + memset(kb, c, key.size); + next(&len); + switch ((*db->get)(db, &key, &val, 0)) { + case 0: + errx(EXIT_FAILURE, "get2 found %zu %zu %#x", + key.size, val.size, c); + break; + case -1: + err(EXIT_FAILURE, "get2 %zu %zu %#x", + key.size, val.size, c); + case 1: + DPRINTF("get2 %zu %zu %#x\n", + key.size, val.size, c); + break; + default: + abort(); + } + } + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/db/t_db.sh b/contrib/netbsd-tests/lib/libc/db/t_db.sh new file mode 100755 index 0000000..93a7b1e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/db/t_db.sh @@ -0,0 +1,1302 @@ +# $NetBSD: t_db.sh,v 1.7 2016/09/24 20:12:33 christos Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +prog_db() +{ + echo $(atf_get_srcdir)/h_db +} + +prog_lfsr() +{ + echo $(atf_get_srcdir)/h_lfsr +} + +dict() +{ + if [ -f /usr/share/dict/words ]; then + echo /usr/share/dict/words + elif [ -f /usr/dict/words ]; then + echo /usr/dict/words + else + atf_fail "no dictionary found" + fi +} + +SEVEN_SEVEN="abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg" + +atf_test_case small_btree +small_btree_head() +{ + atf_set "descr" \ + "Checks btree database using small keys and small data" \ + "pairs: takes the first hundred entries in the dictionary," \ + "and makes them be key/data pairs." + # Begin FreeBSD + atf_set "require.files" /usr/share/dict/words + # End FreeBSD +} +small_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + sed 200q $(dict) >exp + + for i in `sed 200q $(dict)`; do + echo p + echo k$i + echo d$i + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog_db)" btree in +} + +atf_test_case small_hash +small_hash_head() +{ + atf_set "descr" \ + "Checks hash database using small keys and small data" \ + "pairs: takes the first hundred entries in the dictionary," \ + "and makes them be key/data pairs." + # Begin FreeBSD + atf_set "require.files" /usr/share/dict/words + # End FreeBSD +} +small_hash_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + sed 200q $(dict) >exp + + for i in `sed 200q $(dict)`; do + echo p + echo k$i + echo d$i + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog_db)" hash in +} + +atf_test_case small_recno +small_recno_head() +{ + atf_set "descr" \ + "Checks recno database using small keys and small data" \ + "pairs: takes the first hundred entries in the dictionary," \ + "and makes them be key/data pairs." + # Begin FreeBSD + atf_set "require.files" /usr/share/dict/words + # End FreeBSD +} +small_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + sed 200q $(dict) >exp + + sed 200q $(dict) | + awk '{ + ++i; + printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i); + }' >in + + atf_check -o file:exp "$(prog_db)" recno in +} + +atf_test_case medium_btree +medium_btree_head() +{ + atf_set "descr" \ + "Checks btree database using small keys and medium" \ + "data pairs: takes the first 200 entries in the" \ + "dictionary, and gives them each a medium size data entry." + # Begin FreeBSD + atf_set "require.files" /usr/share/dict/words + # End FreeBSD +} +medium_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp + + for i in $(sed 200q $(dict)); do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog_db)" btree in +} + +atf_test_case medium_hash +medium_hash_head() +{ + atf_set "descr" \ + "Checks hash database using small keys and medium" \ + "data pairs: takes the first 200 entries in the" \ + "dictionary, and gives them each a medium size data entry." + # Begin FreeBSD + atf_set "require.files" /usr/share/dict/words + # End FreeBSD +} +medium_hash_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp + + for i in $(sed 200q $(dict)); do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog_db)" hash in +} + +atf_test_case medium_recno +medium_recno_head() +{ + atf_set "descr" \ + "Checks recno database using small keys and medium" \ + "data pairs: takes the first 200 entries in the" \ + "dictionary, and gives them each a medium size data entry." +} +medium_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp + + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) + printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i); + }' >in + + atf_check -o file:exp "$(prog_db)" recno in +} + +atf_test_case big_btree +big_btree_head() +{ + atf_set "descr" \ + "Checks btree database using small keys and big data" \ + "pairs: inserts the programs in /bin with their paths" \ + "as their keys." +} +big_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + (find /bin -type f -print | xargs cat) >exp + + for psize in 512 16384 65536; do + echo "checking page size: $psize" + + for i in `find /bin -type f -print`; do + echo p + echo k$i + echo D$i + echo g + echo k$i + done >in + + atf_check "$(prog_db)" -o out btree in + cmp -s exp out || atf_fail "test failed for page size: $psize" + done +} + +atf_test_case big_hash +big_hash_head() +{ + atf_set "descr" \ + "Checks hash database using small keys and big data" \ + "pairs: inserts the programs in /bin with their paths" \ + "as their keys." +} +big_hash_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + (find /bin -type f -print | xargs cat) >exp + + for i in `find /bin -type f -print`; do + echo p + echo k$i + echo D$i + echo g + echo k$i + done >in + + atf_check "$(prog_db)" -o out hash in + cmp -s exp out || atf_fail "test failed" +} + +atf_test_case big_recno +big_recno_head() +{ + atf_set "descr" \ + "Checks recno database using small keys and big data" \ + "pairs: inserts the programs in /bin with their paths" \ + "as their keys." +} +big_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + (find /bin -type f -print | xargs cat) >exp + + find /bin -type f -print | + awk '{ + ++i; + printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i); + }' >in + + for psize in 512 16384 65536; do + echo "checking page size: $psize" + + atf_check "$(prog_db)" -o out recno in + cmp -s exp out || atf_fail "test failed for page size: $psize" + done +} + +atf_test_case random_recno +random_recno_head() +{ + atf_set "descr" "Checks recno database using random entries" +} +random_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 37; i <= 37 + 88 * 17; i += 17) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 1; i <= 15; ++i) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 19234; i <= 19234 + 61 * 27; i += 27) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit + }' >exp + + cat exp | + awk 'BEGIN { + i = 37; + incr = 17; + } + { + printf("p\nk%d\nd%s\n", i, $0); + if (i == 19234 + 61 * 27) + exit; + if (i == 37 + 88 * 17) { + i = 1; + incr = 1; + } else if (i == 15) { + i = 19234; + incr = 27; + } else + i += incr; + } + END { + for (i = 37; i <= 37 + 88 * 17; i += 17) + printf("g\nk%d\n", i); + for (i = 1; i <= 15; ++i) + printf("g\nk%d\n", i); + for (i = 19234; i <= 19234 + 61 * 27; i += 27) + printf("g\nk%d\n", i); + }' >in + + atf_check -o file:exp "$(prog_db)" recno in +} + +atf_test_case reverse_recno +reverse_recno_head() +{ + atf_set "descr" "Checks recno database using reverse order entries" +} +reverse_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk ' { + for (i = 1500; i; --i) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit; + }' >exp + + cat exp | + awk 'BEGIN { + i = 1500; + } + { + printf("p\nk%d\nd%s\n", i, $0); + --i; + } + END { + for (i = 1500; i; --i) + printf("g\nk%d\n", i); + }' >in + + atf_check -o file:exp "$(prog_db)" recno in +} + +atf_test_case alternate_recno +alternate_recno_head() +{ + atf_set "descr" "Checks recno database using alternating order entries" +} +alternate_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk ' { + for (i = 1; i < 1200; i += 2) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 2; i < 1200; i += 2) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit; + }' >exp + + cat exp | + awk 'BEGIN { + i = 1; + even = 0; + } + { + printf("p\nk%d\nd%s\n", i, $0); + i += 2; + if (i >= 1200) { + if (even == 1) + exit; + even = 1; + i = 2; + } + } + END { + for (i = 1; i < 1200; ++i) + printf("g\nk%d\n", i); + }' >in + + atf_check "$(prog_db)" -o out recno in + + sort -o exp exp + sort -o out out + + cmp -s exp out || atf_fail "test failed" +} + +h_delete() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + type=$1 + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 120; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + }' >exp + + cat exp | + awk '{ + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_NEXT\n"); + for (i = 1; i <= 120; ++i) + printf("s\n"); + printf("fR_CURSOR\ns\nkXX\n"); + printf("r\n"); + printf("fR_NEXT\ns\n"); + printf("fR_CURSOR\ns\nk1\n"); + printf("r\n"); + printf("fR_FIRST\ns\n"); + }' >in + + # For btree, the records are ordered by the string representation + # of the key value. So sort the expected output file accordingly, + # and set the seek_last key to the last expected key value. + + if [ "$type" = "btree" ] ; then + sed -e 's/kXX/k99/' < in > tmp + mv tmp in + sort -d -k4 < exp > tmp + mv tmp exp + echo $SEVEN_SEVEN | + awk '{ + printf("%05d: input key %d: %s\n", 99, 99, $0); + printf("seq failed, no such key\n"); + printf("%05d: input key %d: %s\n", 1, 1, $0); + printf("%05d: input key %d: %s\n", 10, 10, $0); + exit; + }' >> exp + else + # For recno, records are ordered by numerical key value. No sort + # is needed, but still need to set proper seek_last key value. + sed -e 's/kXX/k120/' < in > tmp + mv tmp in + echo $SEVEN_SEVEN | + awk '{ + printf("%05d: input key %d: %s\n", 120, 120, $0); + printf("seq failed, no such key\n"); + printf("%05d: input key %d: %s\n", 1, 1, $0); + printf("%05d: input key %d: %s\n", 2, 2, $0); + exit; + }' >> exp + fi + + atf_check "$(prog_db)" -o out $type in + atf_check -o file:exp cat out +} + +atf_test_case delete_btree +delete_btree_head() +{ + atf_set "descr" "Checks removing records in btree database" +} +delete_btree_body() +{ + h_delete btree +} + +atf_test_case delete_recno +delete_recno_head() +{ + atf_set "descr" "Checks removing records in recno database" +} +delete_recno_body() +{ + h_delete recno +} + +h_repeated() +{ + local type="$1" + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo "" | + awk 'BEGIN { + for (i = 1; i <= 10; ++i) { + printf("p\nkkey1\nD/bin/sh\n"); + printf("p\nkkey2\nD/bin/csh\n"); + if (i % 8 == 0) { + printf("c\nkkey2\nD/bin/csh\n"); + printf("c\nkkey1\nD/bin/sh\n"); + printf("e\t%d of 10 (comparison)\n", i); + } else + printf("e\t%d of 10 \n", i); + printf("r\nkkey1\nr\nkkey2\n"); + } + }' >in + + $(prog_db) $type in +} + +atf_test_case repeated_btree +repeated_btree_head() +{ + atf_set "descr" \ + "Checks btree database with repeated small keys and" \ + "big data pairs. Makes sure that overflow pages are reused" +} +repeated_btree_body() +{ + h_repeated btree +} + +atf_test_case repeated_hash +repeated_hash_head() +{ + atf_set "descr" \ + "Checks hash database with repeated small keys and" \ + "big data pairs. Makes sure that overflow pages are reused" +} +repeated_hash_body() +{ + h_repeated hash +} + +atf_test_case duplicate_btree +duplicate_btree_head() +{ + atf_set "descr" "Checks btree database with duplicate keys" +} +duplicate_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 543; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' >exp + + cat exp | + awk '{ + if (i++ % 2) + printf("p\nkduplicatekey\nd%s\n", $0); + else + printf("p\nkunique%dkey\nd%s\n", i, $0); + } + END { + printf("o\n"); + }' >in + + atf_check -o file:exp -x "$(prog_db) -iflags=1 btree in | sort" +} + +h_cursor_flags() +{ + local type=$1 + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 20; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' >exp + + # Test that R_CURSOR doesn't succeed before cursor initialized + cat exp | + awk '{ + if (i == 10) + exit; + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_CURSOR\nr\n"); + printf("eR_CURSOR SHOULD HAVE FAILED\n"); + }' >in + + atf_check -o ignore -e ignore -s ne:0 "$(prog_db)" -o out $type in + atf_check -s ne:0 test -s out + + cat exp | + awk '{ + if (i == 10) + exit; + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_CURSOR\np\nk1\ndsome data\n"); + printf("eR_CURSOR SHOULD HAVE FAILED\n"); + }' >in + + atf_check -o ignore -e ignore -s ne:0 "$(prog_db)" -o out $type in + atf_check -s ne:0 test -s out +} + +atf_test_case cursor_flags_btree +cursor_flags_btree_head() +{ + atf_set "descr" \ + "Checks use of cursor flags without initialization in btree database" +} +cursor_flags_btree_body() +{ + h_cursor_flags btree +} + +atf_test_case cursor_flags_recno +cursor_flags_recno_head() +{ + atf_set "descr" \ + "Checks use of cursor flags without initialization in recno database" +} +cursor_flags_recno_body() +{ + h_cursor_flags recno +} + +atf_test_case reverse_order_recno +reverse_order_recno_head() +{ + atf_set "descr" "Checks reverse order inserts in recno database" +} +reverse_order_recno_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 779; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' >exp + + cat exp | + awk '{ + if (i == 0) { + i = 1; + printf("p\nk1\nd%s\n", $0); + printf("%s\n", "fR_IBEFORE"); + } else + printf("p\nk1\nd%s\n", $0); + } + END { + printf("or\n"); + }' >in + + atf_check -o file:exp "$(prog_db)" recno in +} + +atf_test_case small_page_btree +small_page_btree_head() +{ + atf_set "descr" \ + "Checks btree database with lots of keys and small page" \ + "size: takes the first 20000 entries in the dictionary," \ + "reverses them, and gives them each a small size data" \ + "entry. Uses a small page size to make sure the btree" \ + "split code gets hammered." + # Begin FreeBSD + atf_set "require.files" /usr/share/dict/words + # End FreeBSD +} +small_page_btree_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + mdata=abcdefghijklmnopqrstuvwxy + echo $mdata | + awk '{ for (i = 1; i < 20001; ++i) print $0 }' >exp + + for i in `sed 20000q $(dict) | rev`; do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog_db)" -i psize=512 btree in +} + +h_byte_orders() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + type=$1 + + sed 50q $(dict) >exp + for order in 1234 4321; do + for i in `sed 50q $(dict)`; do + echo p + echo k$i + echo d$i + echo S + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog_db)" -ilorder=$order -f byte.file $type in + + for i in `sed 50q $(dict)`; do + echo g + echo k$i + done >in + + atf_check -o file:exp "$(prog_db)" -s -ilorder=$order -f byte.file $type in + done +} + +atf_test_case byte_orders_btree +byte_orders_btree_head() +{ + atf_set "descr" "Checks btree database using differing byte orders" + # Begin FreeBSD + atf_set "require.files" /usr/share/dict/words + # End FreeBSD +} +byte_orders_btree_body() +{ + h_byte_orders btree +} + +atf_test_case byte_orders_hash +byte_orders_hash_head() +{ + atf_set "descr" "Checks hash database using differing byte orders" +} +byte_orders_hash_body() +{ + h_byte_orders hash +} + +h_bsize_ffactor() +{ + bsize=$1 + ffactor=$2 + + echo "bucketsize $bsize, fill factor $ffactor" + atf_check -o file:exp "$(prog_db)" "-ibsize=$bsize,\ +ffactor=$ffactor,nelem=25000,cachesize=65536" hash in +} + +atf_test_case bsize_ffactor +bsize_ffactor_head() +{ + atf_set "timeout" "1800" + atf_set "descr" "Checks hash database with various" \ + "bucketsizes and fill factors" + # Begin FreeBSD + atf_set "require.files" /usr/share/dict/words + # End FreeBSD +} +bsize_ffactor_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + echo $SEVEN_SEVEN | + awk '{ + for (i = 1; i <= 10000; ++i) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("%s\n", s); + } + exit; + + }' >exp + + sed 10000q $(dict) | + awk 'BEGIN { + ds="'$SEVEN_SEVEN'" + } + { + if (++i % 34) + s = substr(ds, 1, i % 34); + else + s = substr(ds, 1); + printf("p\nk%s\nd%s\n", $0, s); + }' >in + + sed 10000q $(dict) | + awk '{ + ++i; + printf("g\nk%s\n", $0); + }' >>in + + h_bsize_ffactor 256 11 + h_bsize_ffactor 256 14 + h_bsize_ffactor 256 21 + + h_bsize_ffactor 512 21 + h_bsize_ffactor 512 28 + h_bsize_ffactor 512 43 + + h_bsize_ffactor 1024 43 + h_bsize_ffactor 1024 57 + h_bsize_ffactor 1024 85 + + h_bsize_ffactor 2048 85 + h_bsize_ffactor 2048 114 + h_bsize_ffactor 2048 171 + + h_bsize_ffactor 4096 171 + h_bsize_ffactor 4096 228 + h_bsize_ffactor 4096 341 + + h_bsize_ffactor 8192 341 + h_bsize_ffactor 8192 455 + h_bsize_ffactor 8192 683 + + h_bsize_ffactor 16384 341 + h_bsize_ffactor 16384 455 + h_bsize_ffactor 16384 683 + + h_bsize_ffactor 32768 341 + h_bsize_ffactor 32768 455 + h_bsize_ffactor 32768 683 + + # Begin FreeBSD + if false; then + # End FreeBSD + h_bsize_ffactor 65536 341 + h_bsize_ffactor 65536 455 + h_bsize_ffactor 65536 683 + # Begin FreeBSD + fi + # End FreeBSD +} + +# This tests 64K block size addition/removal +atf_test_case four_char_hash +four_char_hash_head() +{ + atf_set "descr" \ + "Checks hash database with 4 char key and" \ + "value insert on a 65536 bucket size" +} +four_char_hash_body() +{ + TMPDIR="$(pwd)/db_dir"; export TMPDIR + mkdir ${TMPDIR} + + cat >in < 0; ) { + s = sprintf("a%03d:%09d", i, kdsize); + for (j = 0; j < kdsize-20; j++) { + s = s "x"; + } + printf("p\nka%03d\nd%s\n", i, s); + } + print "o"; + }' /dev/null > in + sed -n 's/^d//p' in | sort > exp + atf_check -o file:exp \ + "$(prog_db)" -i psize=$psize btree in + done + done +} + +# Extremely tricky test attempting to replicate some unusual database +# corruption seen in the field: pieces of the database becoming +# inaccessible to random access, sequential access, or both. The +# hypothesis is that at least some of these are triggered by the bug +# in page splits on index 0 with a particular exact keylen+datalen. +# (See Test 40.) For psize=4096, this size is exactly 2024. + +# The order of operations here relies on very specific knowledge of +# the internals of the btree access method in order to place records +# at specific offsets in a page and to create certain keys on internal +# pages. The to-be-split page immediately prior to the bug-triggering +# split has the following properties: +# +# * is not the leftmost leaf page +# * key on the parent page is compares less than the key of the item +# on index 0 +# * triggering record's key also compares greater than the key on the +# parent page + +# Additionally, we prime the mpool LRU chain so that the head page on +# the chain has the following properties: +# +# * record at index 0 is located where it will not get overwritten by +# items written to the right-hand page during the split +# * key of the record at index 0 compares less than the key of the +# bug-triggering record + +# If the page-split bug exists, this test appears to create a database +# where some records are inaccessible to a search, but still remain in +# the file and are accessible by sequential traversal. At least one +# record gets duplicated out of sequence. + +atf_test_case btree_tricky_page_split +btree_tricky_page_split_head() +{ + atf_set "descr" \ + "btree: no unsearchables due to page split on index 0" +} +btree_tricky_page_split_body() +{ + list=`(for i in a b c d; do + for j in 990 998 999; do + echo g ${i}${j} 1024 + done + done; + echo g y997 2014 + for i in y z; do + for j in 998 999; do + echo g ${i}${j} 1024 + done + done)` + # Exact number for trigger condition accounts for newlines + # retained by dbtest with -ofile but not without; we use + # -ofile, so count newlines. keylen=5,datalen=5+2014 for + # psize=4096 here. + (cat - < in + (echo "$list"; echo "$list") | awk '{ + s = $2; + for (i = 0; i < $3; i++) { + s = s "x"; + } + print s; + }' > exp + atf_check -o file:exp \ + "$(prog_db)" -i psize=4096 btree in +} + +# Begin FreeBSD +if false; then +# End FreeBSD +atf_test_case btree_recursive_traversal +btree_recursive_traversal_head() +{ + atf_set "descr" \ + "btree: Test for recursive traversal successfully " \ + "retrieving records that are inaccessible to normal " \ + "sequential 'sibling-link' traversal. This works by " \ + "unlinking a few leaf pages but leaving their parent " \ + "links intact. To verify that the unlink actually makes " \ + "records inaccessible, the test first uses 'o' to do a " \ + "normal sequential traversal, followed by 'O' to do a " \ + "recursive traversal." +} +btree_recursive_traversal_body() +{ + fill="abcdefghijklmnopqrstuvwxyzy" + script='{ + for (i = 0; i < 20000; i++) { + printf("p\nkAA%05d\nd%05d%s\n", i, i, $0); + } + print "u"; + print "u"; + print "u"; + print "u"; + }' + (echo $fill | awk "$script"; echo o) > in1 + echo $fill | + awk '{ + for (i = 0; i < 20000; i++) { + if (i >= 5 && i <= 40) + continue; + printf("%05d%s\n", i, $0); + } + }' > exp1 + atf_check -o file:exp1 \ + "$(prog_db)" -i psize=512 btree in1 + echo $fill | + awk '{ + for (i = 0; i < 20000; i++) { + printf("%05d%s\n", i, $0); + } + }' > exp2 + (echo $fill | awk "$script"; echo O) > in2 + atf_check -o file:exp2 \ + "$(prog_db)" -i psize=512 btree in2 +} +# Begin FreeBSD +fi +# End FreeBSD + +atf_test_case btree_byteswap_unaligned_access_bksd +btree_byteswap_unaligned_access_bksd_head() +{ + atf_set "descr" \ + "btree: big key, small data, byteswap unaligned access" +} +btree_byteswap_unaligned_access_bksd_body() +{ + (echo foo; echo bar) | + awk '{ + s = $0 + for (i = 0; i < 488; i++) { + s = s "x"; + } + printf("p\nk%s\ndx\n", s); + }' > in + for order in 1234 4321; do + atf_check \ + "$(prog_db)" -o out -i psize=512,lorder=$order btree in + done +} + +atf_test_case btree_byteswap_unaligned_access_skbd +btree_byteswap_unaligned_access_skbd_head() +{ + atf_set "descr" \ + "btree: small key, big data, byteswap unaligned access" +} +btree_byteswap_unaligned_access_skbd_body() +{ + # 484 = 512 - 20 (header) - 7 ("foo1234") - 1 (newline) + (echo foo1234; echo bar1234) | + awk '{ + s = $0 + for (i = 0; i < 484; i++) { + s = s "x"; + } + printf("p\nk%s\nd%s\n", $0, s); + }' > in + for order in 1234 4321; do + atf_check \ + "$(prog_db)" -o out -i psize=512,lorder=$order btree in + done +} + +atf_test_case btree_known_byte_order +btree_known_byte_order_head() +{ + atf_set "descr" \ + "btree: small key, big data, known byte order" +} +btree_known_byte_order_body() +{ + local a="-i psize=512,lorder=" + + (echo foo1234; echo bar1234) | + awk '{ + s = $0 + for (i = 0; i < 484; i++) { + s = s "x"; + } + printf("%s\n", s); + }' > exp + (echo foo1234; echo bar1234) | + awk '{ + s = $0 + for (i = 0; i < 484; i++) { + s = s "x"; + } + printf("p\nk%s\nd%s\n", $0, s); + }' > in1 + for order in 1234 4321; do + atf_check \ + "$(prog_db)" -f out.$order $a$order btree in1 + done + (echo g; echo kfoo1234; echo g; echo kbar1234) > in2 + for order in 1234 4321; do + atf_check -o file:exp \ + "$(prog_db)" -s -f out.$order $a$order btree in2 + done +} + +atf_init_test_cases() +{ + atf_add_test_case small_btree + atf_add_test_case small_hash + atf_add_test_case small_recno + atf_add_test_case medium_btree + atf_add_test_case medium_hash + atf_add_test_case medium_recno + atf_add_test_case big_btree + atf_add_test_case big_hash + atf_add_test_case big_recno + atf_add_test_case random_recno + atf_add_test_case reverse_recno + atf_add_test_case alternate_recno + atf_add_test_case delete_btree + atf_add_test_case delete_recno + atf_add_test_case repeated_btree + atf_add_test_case repeated_hash + atf_add_test_case duplicate_btree + atf_add_test_case cursor_flags_btree + atf_add_test_case cursor_flags_recno + atf_add_test_case reverse_order_recno + atf_add_test_case small_page_btree + atf_add_test_case byte_orders_btree + atf_add_test_case byte_orders_hash + atf_add_test_case bsize_ffactor + atf_add_test_case four_char_hash + atf_add_test_case bsize_torture + atf_add_test_case btree_weird_page_split + atf_add_test_case btree_tricky_page_split + # Begin FreeBSD + if false; then + # End FreeBSD + atf_add_test_case btree_recursive_traversal + # Begin FreeBSD + fi + # End FreeBSD + atf_add_test_case btree_byteswap_unaligned_access_bksd + atf_add_test_case btree_byteswap_unaligned_access_skbd + atf_add_test_case btree_known_byte_order +} diff --git a/contrib/netbsd-tests/lib/libc/db/t_db_hash_seq.c b/contrib/netbsd-tests/lib/libc/db/t_db_hash_seq.c new file mode 100644 index 0000000..6e19e22 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/db/t_db_hash_seq.c @@ -0,0 +1,343 @@ +/* $NetBSD: t_db_hash_seq.c,v 1.2 2015/06/22 22:35:51 christos Exp $ */ + +/*- + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_db_hash_seq.c,v 1.2 2015/06/22 22:35:51 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ATF + +struct conf { + struct sockaddr_storage c_ss; + int c_lmask; + int c_port; + int c_proto; + int c_family; + int c_uid; + int c_nfail; + char c_name[128]; + int c_rmask; + int c_duration; +}; + +struct dbinfo { + int count; + time_t last; + char id[64]; +}; + +#ifdef ATF +#include + +#define DO_ERR(msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) +#define DO_WARNX(msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) +#else +#include + +#define DO_ERR(fmt, ...) err(EXIT_FAILURE, fmt, __VA_ARGS__) +#define DO_WARNX(fmt, ...) warnx(fmt, __VA_ARGS__) +#endif + +#define DO_DEBUG(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) + +static HASHINFO openinfo = { + 4096, /* bsize */ + 32, /* ffactor */ + 256, /* nelem */ + 8 * 1024 * 1024,/* cachesize */ + NULL, /* hash() */ + 0 /* lorder */ +}; + +static int debug = 0; + +static int +state_close(DB *db) +{ + if (db == NULL) + return -1; + if ((*db->close)(db) == -1) + DO_ERR("%s: can't close db", __func__); + return 0; +} + +static DB * +state_open(const char *dbname, int flags, mode_t perm) +{ + DB *db; + + db = dbopen(dbname, flags, perm, DB_HASH, &openinfo); + if (db == NULL) { + if (errno == ENOENT && (flags & O_CREAT) == 0) + return NULL; + DO_ERR("%s: can't open `%s'", __func__, dbname); + } + return db; +} + +static int +state_sizecheck(const DBT *t) +{ + if (sizeof(struct conf) == t->size) + return 0; + DO_WARNX("Key size mismatch %zu != %zu", sizeof(struct conf), t->size); + return 0; +} + +static int +state_del(DB *db, const struct conf *c) +{ + int rv; + DBT k; + + if (db == NULL) + return -1; + + k.data = __UNCONST(c); + k.size = sizeof(*c); + + switch (rv = (*db->del)(db, &k, 1)) { + case 0: + case 1: + if (debug > 1) { + DO_DEBUG("%s: returns %d", __func__, rv); + (*db->sync)(db, 0); + } + return 0; + default: + DO_ERR("%s: failed", __func__); + return -1; + } +} + +#if 0 +static int +state_get(DB *db, const struct conf *c, struct dbinfo *dbi) +{ + int rv; + DBT k, v; + + if (db == NULL) + return -1; + + k.data = __UNCONST(c); + k.size = sizeof(*c); + + switch (rv = (*db->get)(db, &k, &v, 0)) { + case 0: + case 1: + if (rv) + memset(dbi, 0, sizeof(*dbi)); + else + memcpy(dbi, v.data, sizeof(*dbi)); + if (debug > 1) + DO_DEBUG("%s: returns %d", __func__, rv); + return 0; + default: + DO_ERR("%s: failed", __func__); + return -1; + } +} +#endif + +static int +state_put(DB *db, const struct conf *c, const struct dbinfo *dbi) +{ + int rv; + DBT k, v; + + if (db == NULL) + return -1; + + k.data = __UNCONST(c); + k.size = sizeof(*c); + v.data = __UNCONST(dbi); + v.size = sizeof(*dbi); + + switch (rv = (*db->put)(db, &k, &v, 0)) { + case 0: + if (debug > 1) { + DO_DEBUG("%s: returns %d", __func__, rv); + (*db->sync)(db, 0); + } + return 0; + case 1: + errno = EEXIST; + /*FALLTHROUGH*/ + default: + DO_ERR("%s: failed", __func__); + } +} + +static int +state_iterate(DB *db, struct conf *c, struct dbinfo *dbi, unsigned int first) +{ + int rv; + DBT k, v; + + if (db == NULL) + return -1; + + first = first ? R_FIRST : R_NEXT; + + switch (rv = (*db->seq)(db, &k, &v, first)) { + case 0: + if (state_sizecheck(&k) == -1) + return -1; + memcpy(c, k.data, sizeof(*c)); + memcpy(dbi, v.data, sizeof(*dbi)); + if (debug > 1) + DO_DEBUG("%s: returns %d", __func__, rv); + return 1; + case 1: + if (debug > 1) + DO_DEBUG("%s: returns %d", __func__, rv); + return 0; + default: + DO_ERR("%s: failed", __func__); + return -1; + } +} + +#define MAXB 100 + +static int +testdb(int skip) +{ + size_t i; + int f; + char flag[MAXB]; + DB *db; + struct conf c; + struct dbinfo d; + + db = state_open(NULL, O_RDWR|O_CREAT|O_TRUNC, 0600); + if (db == NULL) + DO_ERR("%s: cannot open `%s'", __func__, "foo"); + + memset(&c, 0, sizeof(c)); + memset(&d, 0, sizeof(d)); + memset(flag, 0, sizeof(flag)); + + for (i = 0; i < __arraycount(flag); i++) { + c.c_port = i; + state_put(db, &c, &d); + } + + for (f = 1, i = 0; state_iterate(db, &c, &d, f) == 1; f = 0, i++) { + if (debug > 1) + DO_DEBUG("%zu %d\n", i, c.c_port); + if (flag[c.c_port]) + DO_WARNX("Already visited %d", c.c_port); + flag[c.c_port] = 1; + if (skip == 0 || c.c_port % skip != 0) + continue; + state_del(db, &c); + } + state_close(db); + for (i = 0; i < __arraycount(flag); i++) { + if (flag[i] == 0) + DO_WARNX("Not visited %zu", i); + } + return 0; +} + +#ifndef ATF +int +main(int argc, char *argv[]) +{ + return testdb(6); +} +#else + +ATF_TC(test_hash_del_none); +ATF_TC_HEAD(test_hash_del_none, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check sequential scan of hash tables deleting none"); +} + +ATF_TC_BODY(test_hash_del_none, tc) +{ + testdb(0); +} + +ATF_TC(test_hash_del_all); +ATF_TC_HEAD(test_hash_del_all, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check sequential scan of hash tables deleting all"); +} + +ATF_TC_BODY(test_hash_del_all, tc) +{ + testdb(1); +} + +ATF_TC(test_hash_del_alt); +ATF_TC_HEAD(test_hash_del_alt, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check sequential scan of hash tables alternating deletets"); +} + +ATF_TC_BODY(test_hash_del_alt, tc) +{ + testdb(2); +} + +ATF_TC(test_hash_del_every_7); +ATF_TC_HEAD(test_hash_del_every_7, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check sequential scan of hash tables deleting every 7 elements"); +} + +ATF_TC_BODY(test_hash_del_every_7, tc) +{ + testdb(7); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, test_hash_del_none); + ATF_TP_ADD_TC(tp, test_hash_del_all); + ATF_TP_ADD_TC(tp, test_hash_del_alt); + ATF_TP_ADD_TC(tp, test_hash_del_every_7); + + return 0; +} +#endif diff --git a/contrib/netbsd-tests/lib/libc/gen/exect/t_exect.c b/contrib/netbsd-tests/lib/libc/gen/exect/t_exect.c new file mode 100644 index 0000000..4c85e4b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/exect/t_exect.c @@ -0,0 +1,90 @@ +/* $NetBSD: t_exect.c,v 1.6 2016/12/12 10:34:55 joerg Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include +#include +#include + +ATF_TC(t_exect_null); + +ATF_TC_HEAD(t_exect_null, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests an empty exect(2) executing"); +} + +static volatile sig_atomic_t caught = 0; + +static void +sigtrap_handler(int sig, siginfo_t *info, void *ctx) +{ + ATF_REQUIRE_EQ(sig, SIGTRAP); + ATF_REQUIRE_EQ(info->si_code, TRAP_TRACE); + + ++caught; +} + +ATF_TC_BODY(t_exect_null, tc) +{ + struct sigaction act; + + /* + * Currently exect(3) is misdesigned -- see PR port-amd64/51700 and it + * needs to be redone from scratch. + * + * This test affects amd64 releng machines causing tests to hang or + * fail. As there is little point to test interface that is still not, + * designed and implemented and is breaking tests - skip it + * unconditionally for all ports. + */ + /* Prevent static analysis from requiring t_exec_null to be __dead. */ + if (!caught) + atf_tc_skip("exect(3) misdesigned and hangs - PR port-amd64/51700"); + + ATF_REQUIRE(sigemptyset(&act.sa_mask) == 0); + act.sa_sigaction = sigtrap_handler; + act.sa_flags = SA_SIGINFO; + + ATF_REQUIRE(sigaction(SIGTRAP, &act, 0) == 0); + + ATF_REQUIRE_ERRNO(EFAULT, exect(NULL, NULL, NULL) == -1); + + ATF_REQUIRE_EQ_MSG(caught, 1, "expected caught (1) != received (%d)", + (int)caught); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_exect_null); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c b/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c new file mode 100644 index 0000000..d3752cd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c @@ -0,0 +1,59 @@ +/* $NetBSD: t_execve.c,v 1.2 2015/09/12 15:21:33 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include +#include + +ATF_TC(t_execve_null); + +ATF_TC_HEAD(t_execve_null, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests an empty execve(2) executing"); +} + +ATF_TC_BODY(t_execve_null, tc) +{ + int err; + + err = execve(NULL, NULL, NULL); + ATF_REQUIRE(err == -1); + ATF_REQUIRE_MSG(errno == EFAULT, + "wrong error returned %d instead of %d", errno, EFAULT); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_execve_null); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/isqemu.h b/contrib/netbsd-tests/lib/libc/gen/isqemu.h new file mode 100644 index 0000000..c44ffda --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/isqemu.h @@ -0,0 +1,89 @@ +/* $NetBSD: isqemu.h,v 1.4 2015/01/03 14:21:05 gson Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include + +static __inline bool +isQEMU(void) { +#ifdef __FreeBSD__ + char *vm_guest_name_buf; + size_t len; + bool is_vm; + + if (sysctlbyname("kern.vm_guest", NULL, &len, NULL, 0) == -1) + err(EXIT_FAILURE, "sysctl"); + + if ((vm_guest_name_buf = malloc(len)) == NULL) + err(EXIT_FAILURE, "malloc"); + + if (sysctlbyname("kern.vm_guest", vm_guest_name_buf, &len, NULL, 0) + == -1) + err(EXIT_FAILURE, "sysctl"); + + if (strcmp(vm_guest_name_buf, "none") == 0) + is_vm = false; + else + is_vm = true; + + free(vm_guest_name_buf); + + return is_vm; +#else +#if defined(__i386__) || defined(__x86_64__) + char name[1024]; + size_t len = sizeof(name); + + if (sysctlbyname("machdep.cpu_brand", name, &len, NULL, 0) == -1) { + if (errno == ENOENT) + return false; + err(EXIT_FAILURE, "sysctl"); + } + return strstr(name, "QEMU") != NULL; +#else + return false; +#endif +#endif +} + +#ifdef TEST +int +main(void) { + return isQEMU(); +} +#endif diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c new file mode 100644 index 0000000..d923370 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c @@ -0,0 +1,104 @@ +/* $NetBSD: h_fileactions.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang and + * Martin Husemann . + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include + +#define BUFSIZE 16 + +/* + * This checks (hardcoded) the assumptions that are setup from the + * main test program via posix spawn file actions. + * Program exits with EXIT_SUCCESS or EXIT_FAILURE accordingly + * (and does some stderr diagnostics in case of errors). + */ +int +main(int argc, char **argv) +{ + int res = EXIT_SUCCESS; + char buf[BUFSIZE]; + struct stat sb0, sb1; + + strcpy(buf, "test..."); + /* file desc 3 should be closed via addclose */ + if (read(3, buf, BUFSIZE) != -1 || errno != EBADF) { + fprintf(stderr, "%s: filedesc 3 is not closed\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 4 should be closed via closeonexec */ + if (read(4, buf, BUFSIZE) != -1 || errno != EBADF) { + fprintf(stderr, "%s: filedesc 4 is not closed\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 5 remains open */ + if (write(5, buf, BUFSIZE) <= 0) { + fprintf(stderr, "%s: could not write to filedesc 5\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 6 should be open (via addopen) */ + if (write(6, buf, BUFSIZE) <= 0) { + fprintf(stderr, "%s: could not write to filedesc 6\n", + getprogname()); + res = EXIT_FAILURE; + } + /* file desc 7 should refer to stdout */ + fflush(stdout); + if (fstat(fileno(stdout), &sb0) != 0) { + fprintf(stderr, "%s: could not fstat stdout\n", + getprogname()); + res = EXIT_FAILURE; + } + if (fstat(7, &sb1) != 0) { + fprintf(stderr, "%s: could not fstat filedesc 7\n", + getprogname()); + res = EXIT_FAILURE; + } + if (write(7, buf, strlen(buf)) <= 0) { + fprintf(stderr, "%s: could not write to filedesc 7\n", + getprogname()); + res = EXIT_FAILURE; + } + if (memcmp(&sb0, &sb1, sizeof sb0) != 0) { + fprintf(stderr, "%s: stat results differ\n", getprogname()); + res = EXIT_FAILURE; + } + + return res; +} + diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh new file mode 100755 index 0000000..deee6fe --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh @@ -0,0 +1,3 @@ +#! /nonexistent + +# this is just a dummy script, trying to be non-executable diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c new file mode 100644 index 0000000..dbf5da5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c @@ -0,0 +1,50 @@ +/* $NetBSD: h_spawn.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang and + * Martin Husemann . + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +int +main(int argc, char **argv) +{ + unsigned long ret; + char *endp; + + if (argc < 2) { + fprintf(stderr, "usage:\n\t%s (retcode)\n", getprogname()); + exit(255); + } + ret = strtoul(argv[1], &endp, 10); + + fprintf(stderr, "%s exiting with status %lu\n", getprogname(), ret); + return ret; +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c new file mode 100644 index 0000000..1f13c54 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c @@ -0,0 +1,90 @@ +/* $NetBSD: h_spawnattr.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang and + * Martin Husemann . + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include + +/* + * Helper to test the hardcoded assumptions from t_spawnattr.c + * Exit with apropriate exit status and print diagnostics to + * stderr explaining what is wrong. + */ +int +main(int argc, char **argv) +{ + int parent_pipe, res = EXIT_SUCCESS; + sigset_t sig; + struct sigaction act; + ssize_t rd; + char tmp; + + sigemptyset(&sig); + if (sigprocmask(0, NULL, &sig) < 0) { + fprintf(stderr, "%s: sigprocmask error\n", getprogname()); + res = EXIT_FAILURE; + } + if (!sigismember(&sig, SIGUSR1)) { + fprintf(stderr, "%s: SIGUSR not in procmask\n", getprogname()); + res = EXIT_FAILURE; + } + if (sigaction(SIGUSR1, NULL, &act) < 0) { + fprintf(stderr, "%s: sigaction error\n", getprogname()); + res = EXIT_FAILURE; + } + if (act.sa_sigaction != (void *)SIG_DFL) { + fprintf(stderr, "%s: SIGUSR1 action != SIG_DFL\n", + getprogname()); + res = EXIT_FAILURE; + } + + if (argc >= 2) { + parent_pipe = atoi(argv[1]); + if (parent_pipe > 2) { + printf("%s: waiting for command from parent on pipe " + "%d\n", getprogname(), parent_pipe); + rd = read(parent_pipe, &tmp, 1); + if (rd == 1) { + printf("%s: got command %c from parent\n", + getprogname(), tmp); + } else if (rd == -1) { + printf("%s: %d is no pipe, errno %d\n", + getprogname(), parent_pipe, errno); + res = EXIT_FAILURE; + } + } + } + + return res; +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c new file mode 100644 index 0000000..74009a8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c @@ -0,0 +1,392 @@ +/* $NetBSD: t_fileactions.c,v 1.6 2017/01/10 22:36:29 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang and + * Martin Husemann . + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +ATF_TC(t_spawn_openmode); + +ATF_TC_HEAD(t_spawn_openmode, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the proper handling of 'mode' for 'open' fileactions"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +static off_t +filesize(const char * restrict fname) +{ + struct stat st; + int err; + + err = stat(fname, &st); + ATF_REQUIRE(err == 0); + return st.st_size; +} + +#define TESTFILE "./the_input_data" +#define CHECKFILE "./the_output_data" +#define TESTCONTENT "marry has a little lamb" + +static void +make_testfile(const char *restrict file) +{ + FILE *f; + size_t written; + + f = fopen(file, "w"); + ATF_REQUIRE(f != NULL); + written = fwrite(TESTCONTENT, 1, strlen(TESTCONTENT), f); + fclose(f); + ATF_REQUIRE(written == strlen(TESTCONTENT)); +} + +static void +empty_outfile(const char *restrict filename) +{ + FILE *f; + + f = fopen(filename, "w"); + ATF_REQUIRE(f != NULL); + fclose(f); +} + +ATF_TC_BODY(t_spawn_openmode, tc) +{ + int status, err; + pid_t pid; + size_t insize, outsize; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + + /* + * try a "cat < testfile > checkfile" + */ + make_testfile(TESTFILE); + unlink(CHECKFILE); + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + TESTFILE, O_RDONLY, 0); + posix_spawn_file_actions_addopen(&fa, fileno(stdout), + CHECKFILE, O_WRONLY|O_CREAT, 0600); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + /* now check that input and output have the same size */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(insize == outsize); + + /* + * try a "cat < testfile >> checkfile" + */ + make_testfile(TESTFILE); + make_testfile(CHECKFILE); + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + TESTFILE, O_RDONLY, 0); + posix_spawn_file_actions_addopen(&fa, fileno(stdout), + CHECKFILE, O_WRONLY|O_APPEND, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + /* now check that output is twice as long as input */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(insize*2 == outsize); + + /* + * try a "cat < testfile > checkfile" with input and output swapped + */ + make_testfile(TESTFILE); + empty_outfile(CHECKFILE); + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdout), + TESTFILE, O_RDONLY, 0); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + CHECKFILE, O_WRONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_FAILURE); + + /* now check that input and output are still the same size */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(outsize == 0); +} + +ATF_TC(t_spawn_reopen); + +ATF_TC_HEAD(t_spawn_reopen, tc) +{ + atf_tc_set_md_var(tc, "descr", + "an open filehandle can be replaced by a 'open' fileaction"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_reopen, tc) +{ + int status, err; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + + /* + * make sure stdin is open in the parent + */ + freopen("/dev/zero", "r", stdin); + /* + * now request an open for this fd again in the child + */ + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, fileno(stdin), + "/dev/null", O_RDONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); +} + +ATF_TC(t_spawn_open_nonexistent); + +ATF_TC_HEAD(t_spawn_open_nonexistent, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn fails when a file to open does not exist"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_open_nonexistent, tc) +{ + int err, status; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, STDIN_FILENO, + "./non/ex/ist/ent", O_RDONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + if (err == 0) { + /* + * The child has been created - it should fail and + * return exit code 127 + */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 127); + } else { + /* + * The error has been noticed early enough, no child has + * been run + */ + ATF_REQUIRE(err == ENOENT); + } + posix_spawn_file_actions_destroy(&fa); +} + +#ifdef __NetBSD__ +ATF_TC(t_spawn_open_nonexistent_diag); + +ATF_TC_HEAD(t_spawn_open_nonexistent_diag, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn fails when a file to open does not exist " + "and delivers proper diagnostic"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_open_nonexistent_diag, tc) +{ + int err; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawnattr_t attr; + posix_spawn_file_actions_t fa; + + posix_spawnattr_init(&attr); + /* + * POSIX_SPAWN_RETURNERROR is a NetBSD specific flag that + * will cause a "proper" return value from posix_spawn(2) + * instead of a (potential) success there and a 127 exit + * status from the child process (c.f. the non-diag variant + * of this test). + */ + posix_spawnattr_setflags(&attr, POSIX_SPAWN_RETURNERROR); + posix_spawn_file_actions_init(&fa); + posix_spawn_file_actions_addopen(&fa, STDIN_FILENO, + "./non/ex/ist/ent", O_RDONLY, 0); + err = posix_spawn(&pid, "/bin/cat", &fa, &attr, args, NULL); + ATF_REQUIRE(err == ENOENT); + posix_spawn_file_actions_destroy(&fa); + posix_spawnattr_destroy(&attr); +} +#endif + +ATF_TC(t_spawn_fileactions); + +ATF_TC_HEAD(t_spawn_fileactions, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests various complex fileactions"); +} + +ATF_TC_BODY(t_spawn_fileactions, tc) +{ + int fd1, fd2, fd3, status, err; + pid_t pid; + char * const args[2] = { __UNCONST("h_fileactions"), NULL }; + char helper[FILENAME_MAX]; + posix_spawn_file_actions_t fa; + + posix_spawn_file_actions_init(&fa); + + closefrom(fileno(stderr)+1); + + fd1 = open("/dev/null", O_RDONLY); + ATF_REQUIRE(fd1 == 3); + + fd2 = open("/dev/null", O_WRONLY, O_CLOEXEC); + ATF_REQUIRE(fd2 == 4); + + fd3 = open("/dev/null", O_WRONLY); + ATF_REQUIRE(fd3 == 5); + + posix_spawn_file_actions_addclose(&fa, fd1); + posix_spawn_file_actions_addopen(&fa, 6, "/dev/null", O_RDWR, 0); + posix_spawn_file_actions_adddup2(&fa, 1, 7); + + snprintf(helper, sizeof helper, "%s/h_fileactions", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(&pid, helper, &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); +} + +ATF_TC(t_spawn_empty_fileactions); + +ATF_TC_HEAD(t_spawn_empty_fileactions, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn with empty fileactions (PR kern/46038)"); + atf_tc_set_md_var(tc, "require.progs", "/bin/cat"); +} + +ATF_TC_BODY(t_spawn_empty_fileactions, tc) +{ + int status, err; + pid_t pid; + char * const args[2] = { __UNCONST("cat"), NULL }; + posix_spawn_file_actions_t fa; + size_t insize, outsize; + + /* + * try a "cat < testfile > checkfile", but set up stdin/stdout + * already in the parent and pass empty file actions to the child. + */ + make_testfile(TESTFILE); + unlink(CHECKFILE); + + freopen(TESTFILE, "r", stdin); + freopen(CHECKFILE, "w", stdout); + + posix_spawn_file_actions_init(&fa); + err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL); + posix_spawn_file_actions_destroy(&fa); + + ATF_REQUIRE(err == 0); + + /* ok, wait for the child to finish */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + /* now check that input and output have the same size */ + insize = filesize(TESTFILE); + outsize = filesize(CHECKFILE); + ATF_REQUIRE(insize == strlen(TESTCONTENT)); + ATF_REQUIRE(insize == outsize); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_spawn_fileactions); + ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent_diag); +#endif + ATF_TP_ADD_TC(tp, t_spawn_reopen); + ATF_TP_ADD_TC(tp, t_spawn_openmode); + ATF_TP_ADD_TC(tp, t_spawn_empty_fileactions); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c new file mode 100644 index 0000000..12f2760 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c @@ -0,0 +1,184 @@ +/* $NetBSD: t_spawn.c,v 1.2 2014/10/18 08:33:30 snj Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang and + * Martin Husemann . + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include + +ATF_TC(t_spawn_ls); + +ATF_TC_HEAD(t_spawn_ls, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests a simple posix_spawn executing /bin/ls"); +} + +ATF_TC_BODY(t_spawn_ls, tc) +{ + char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL }; + int err; + + err = posix_spawn(NULL, "/bin/ls", NULL, NULL, args, NULL); + ATF_REQUIRE(err == 0); +} + +ATF_TC(t_spawnp_ls); + +ATF_TC_HEAD(t_spawnp_ls, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests a simple posix_spawnp executing ls via $PATH"); +} + +ATF_TC_BODY(t_spawnp_ls, tc) +{ + char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL }; + int err; + + err = posix_spawnp(NULL, "ls", NULL, NULL, args, NULL); + ATF_REQUIRE(err == 0); +} + +ATF_TC(t_spawn_zero); + +ATF_TC_HEAD(t_spawn_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn an invalid binary"); +} + +ATF_TC_BODY(t_spawn_zero, tc) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST("h_zero"), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/h_zero", atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == ENOEXEC, "expected error %d, got %d when spawning %s", ENOEXEC, err, buf); +} + +ATF_TC(t_spawn_missing); + +ATF_TC_HEAD(t_spawn_missing, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn a non existant binary"); +} + +ATF_TC_BODY(t_spawn_missing, tc) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST("h_nonexist"), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/h_nonexist", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf); +} + +ATF_TC(t_spawn_nonexec); + +ATF_TC_HEAD(t_spawn_nonexec, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn a script with non existing interpreter"); +} + +ATF_TC_BODY(t_spawn_nonexec, tc) +{ + char buf[FILENAME_MAX]; + char * const args[] = { __UNCONST("h_nonexec"), NULL }; + int err; + + snprintf(buf, sizeof buf, "%s/h_nonexec", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(NULL, buf, NULL, NULL, args, NULL); + ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf); +} + +ATF_TC(t_spawn_child); + +ATF_TC_HEAD(t_spawn_child, tc) +{ + atf_tc_set_md_var(tc, "descr", + "posix_spawn a child and get its return code"); +} + +ATF_TC_BODY(t_spawn_child, tc) +{ + char buf[FILENAME_MAX]; + char * const args0[] = { __UNCONST("h_spawn"), __UNCONST("0"), NULL }; + char * const args1[] = { __UNCONST("h_spawn"), __UNCONST("1"), NULL }; + char * const args7[] = { __UNCONST("h_spawn"), __UNCONST("7"), NULL }; + int err, status; + pid_t pid; + + snprintf(buf, sizeof buf, "%s/h_spawn", + atf_tc_get_config_var(tc, "srcdir")); + + err = posix_spawn(&pid, buf, NULL, NULL, args0, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 0); + + err = posix_spawn(&pid, buf, NULL, NULL, args1, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 1); + + err = posix_spawn(&pid, buf, NULL, NULL, args7, NULL); + ATF_REQUIRE(err == 0); + ATF_REQUIRE(pid > 0); + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 7); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_spawn_ls); + ATF_TP_ADD_TC(tp, t_spawnp_ls); + ATF_TP_ADD_TC(tp, t_spawn_zero); + ATF_TP_ADD_TC(tp, t_spawn_missing); + ATF_TP_ADD_TC(tp, t_spawn_nonexec); + ATF_TP_ADD_TC(tp, t_spawn_child); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c new file mode 100644 index 0000000..8e4d30d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c @@ -0,0 +1,177 @@ +/* $NetBSD: t_spawnattr.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles Zhang and + * Martin Husemann . + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int get_different_scheduler(void); +static int get_different_priority(int scheduler); + +static const int schedulers[] = { + SCHED_OTHER, + SCHED_FIFO, + SCHED_RR +}; + +static int +get_different_scheduler(void) +{ + u_int i; + int scheduler; + + /* get current schedule policy */ + scheduler = sched_getscheduler(0); + for (i = 0; i < __arraycount(schedulers); i++) { + if (schedulers[i] == scheduler) + break; + } + ATF_REQUIRE_MSG(i < __arraycount(schedulers), + "Unknown current scheduler %d", scheduler); + + /* new scheduler */ + i++; + if (i >= __arraycount(schedulers)) + i = 0; + return schedulers[i]; +} + +static int +get_different_priority(int scheduler) +{ + int max, min, new, priority; + struct sched_param param; + + max = sched_get_priority_max(scheduler); + min = sched_get_priority_min(scheduler); + + sched_getparam(0, ¶m); + priority = param.sched_priority; + + /* + * Change numerical value of the priority, to ensure that it + * was set for the spawned child. + */ + new = priority + 1; + if (new > max) + new = min; + return new; +} + +ATF_TC(t_spawnattr); + +ATF_TC_HEAD(t_spawnattr, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "descr", + "Tests posix_spawn with scheduler attributes"); +} + +ATF_TC_BODY(t_spawnattr, tc) +{ + int pid, scheduler, child_scheduler, priority, status, err, pfd[2]; + char helper_arg[128]; + char * const args[] = { __UNCONST("h_spawnattr"), helper_arg, NULL }; + struct sched_param sp, child_sp; + sigset_t sig; + posix_spawnattr_t attr; + char helper[FILENAME_MAX]; + + /* + * create a pipe to controll the child + */ + err = pipe(pfd); + ATF_REQUIRE_MSG(err == 0, "could not create pipe, errno %d", errno); + sprintf(helper_arg, "%d", pfd[0]); + + posix_spawnattr_init(&attr); + + scheduler = get_different_scheduler(); + priority = get_different_priority(scheduler); + sp.sched_priority = priority; + + sigemptyset(&sig); + sigaddset(&sig, SIGUSR1); + + posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDULER | + POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETPGROUP | + POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF); + posix_spawnattr_setpgroup(&attr, 0); + posix_spawnattr_setschedparam(&attr, &sp); + posix_spawnattr_setschedpolicy(&attr, scheduler); + posix_spawnattr_setsigmask(&attr, &sig); + posix_spawnattr_setsigdefault(&attr, &sig); + + sprintf(helper, "%s/h_spawnattr", + atf_tc_get_config_var(tc, "srcdir")); + err = posix_spawn(&pid, helper, NULL, &attr, args, NULL); + ATF_REQUIRE_MSG(err == 0, "error %d", err); + + child_scheduler = sched_getscheduler(pid); + ATF_REQUIRE_MSG(scheduler == child_scheduler, + "scheduler = %d, child_scheduler = %d, pid %d, errno %d", + scheduler, child_scheduler, pid, errno); + + sched_getparam(pid, &child_sp); + ATF_REQUIRE_MSG(child_sp.sched_priority == sp.sched_priority, + "priority is: %d, but we requested: %d", + child_sp.sched_priority, sp.sched_priority); + + ATF_REQUIRE_MSG(pid == getpgid(pid), "child pid: %d, child pgid: %d", + pid, getpgid(pid)); + + /* ready, let child go */ + write(pfd[1], "q", 1); + close(pfd[0]); + close(pfd[1]); + + /* wait and check result from child */ + waitpid(pid, &status, 0); + ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS); + + posix_spawnattr_destroy(&attr); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_spawnattr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_alarm.c b/contrib/netbsd-tests/lib/libc/gen/t_alarm.c new file mode 100644 index 0000000..d9e903d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_alarm.c @@ -0,0 +1,150 @@ +/* $NetBSD: t_alarm.c,v 1.2 2011/05/10 06:58:17 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_alarm.c,v 1.2 2011/05/10 06:58:17 jruoho Exp $"); + +#include + +#include +#include +#include +#include + +static bool fail; +static void handler(int); + +static void +handler(int signo) +{ + + if (signo == SIGALRM) + fail = false; +} + +ATF_TC(alarm_basic); +ATF_TC_HEAD(alarm_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of alarm(3)"); +} + +ATF_TC_BODY(alarm_basic, tc) +{ + + ATF_REQUIRE(signal(SIGALRM, handler) == 0); + + fail = true; + + (void)alarm(1); + (void)sleep(2); + + if (fail != false) + atf_tc_fail("alarm(3) failed to deliver signal"); +} + +ATF_TC(alarm_fork); +ATF_TC_HEAD(alarm_fork, tc) +{ + atf_tc_set_md_var(tc, "descr", "Does fork(2) clear a pending alarm?"); +} + +ATF_TC_BODY(alarm_fork, tc) +{ + unsigned int rv; + pid_t pid; + int sta; + + /* + * Any pending alarms should be + * cleared in the child process. + */ + (void)alarm(60); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + rv = alarm(0); + + if (rv != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)alarm(0); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("pending alarm was not cleared for child"); +} + +ATF_TC(alarm_previous); +ATF_TC_HEAD(alarm_previous, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test return value from alarm(3)"); +} + +ATF_TC_BODY(alarm_previous, tc) +{ + unsigned int rv; + + /* + * See that alarm(3) returns the amount + * left on the timer from the previous call. + */ + rv = alarm(60); + + if (rv != 0) + goto fail; + + rv = alarm(0); + + if (rv < 50) + goto fail; + + (void)alarm(0); + + return; + +fail: + atf_tc_fail("invalid return value from alarm(3)"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, alarm_basic); + ATF_TP_ADD_TC(tp, alarm_fork); + ATF_TP_ADD_TC(tp, alarm_previous); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_assert.c b/contrib/netbsd-tests/lib/libc/gen/t_assert.c new file mode 100644 index 0000000..ce73015 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_assert.c @@ -0,0 +1,148 @@ +/* $NetBSD: t_assert.c,v 1.3 2017/01/10 15:17:57 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_assert.c,v 1.3 2017/01/10 15:17:57 christos Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static void +disable_corefile(void) +{ + struct rlimit limits; + + limits.rlim_cur = 0; + limits.rlim_max = 0; + + ATF_REQUIRE(setrlimit(RLIMIT_CORE, &limits) == 0); +} + +static void handler(int); + +static void +handler(int signo) +{ + /* Nothing. */ +} + +ATF_TC(assert_false); +ATF_TC_HEAD(assert_false, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that assert(3) works, #1"); +} + +ATF_TC_BODY(assert_false, tc) +{ + struct sigaction sa; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + disable_corefile(); + (void)closefrom(0); + (void)memset(&sa, 0, sizeof(struct sigaction)); + + sa.sa_flags = 0; + sa.sa_handler = handler; + + (void)sigemptyset(&sa.sa_mask); + (void)sigaction(SIGABRT, &sa, 0); + + assert(1 == 1); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFSIGNALED(sta) != 0 || WIFEXITED(sta) == 0) + atf_tc_fail("assert(3) fired haphazardly"); +} + +ATF_TC(assert_true); +ATF_TC_HEAD(assert_true, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that assert(3) works, #2"); +} + +ATF_TC_BODY(assert_true, tc) +{ + struct sigaction sa; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + disable_corefile(); + (void)closefrom(0); + (void)memset(&sa, 0, sizeof(struct sigaction)); + + sa.sa_flags = 0; + sa.sa_handler = handler; + + (void)sigemptyset(&sa.sa_mask); + (void)sigaction(SIGABRT, &sa, 0); + + assert(1 == 2); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGABRT) + atf_tc_fail("assert(3) did not fire"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, assert_false); + ATF_TP_ADD_TC(tp, assert_true); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_basedirname.c b/contrib/netbsd-tests/lib/libc/gen/t_basedirname.c new file mode 100644 index 0000000..6c82cb4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_basedirname.c @@ -0,0 +1,200 @@ +/* $NetBSD: t_basedirname.c,v 1.2 2011/07/07 09:49:59 jruoho Exp $ */ + +/* + * Regression test for basename(3). + * + * Written by Jason R. Thorpe , Oct. 2002. + * Public domain. + */ + +#include + +#include +#include +#include +#include +#include + +struct { + const char *input; + const char *output; +} test_basename_table[] = { +/* + * The following are taken from the "Sample Input and Output Strings + * for basename()" table in IEEE Std 1003.1-2001. + */ + { "/usr/lib", "lib" }, + { "/usr/", "usr" }, + { "/", "/" }, + { "///", "/" }, + { "//usr//lib//", "lib" }, +/* + * IEEE Std 1003.1-2001: + * + * If path is a null pointer or points to an empty string, + * basename() shall return a pointer to the string "." . + */ + { "", "." }, + { NULL, "." }, +/* + * IEEE Std 1003.1-2001: + * + * If the string is exactly "//", it is implementation-defined + * whether "/" or "//" is returned. + * + * The NetBSD implementation returns "/". + */ + { "//", "/" }, + + { NULL, NULL } +}; + +struct { + const char *input; + const char *output; +} test_dirname_table[] = { +/* + * The following are taken from the "Sample Input and Output Strings + * for dirname()" table in IEEE Std 1003.1-2001. + */ + { "/usr/lib", "/usr" }, + { "/usr/", "/" }, + { "usr", "." }, + { "/", "/" }, + { ".", "." }, + { "..", "." }, +/* + * IEEE Std 1003.1-2001: + * + * If path is a null pointer or points to an empty string, + * dirname() shall return a pointer to the string "." . + */ + { "", "." }, + { NULL, "." }, +/* + * IEEE Std 1003.1-2001: + * + * Since the meaning of the leading "//" is implementation-defined, + * dirname("//foo") may return either "//" or "/" (but nothing else). + * + * The NetBSD implementation returns "/". + */ + { "//foo", "/" }, +/* + * Make sure the trailing slashes after the directory name component + * get trimmed. The Std does not talk about this, but this is what + * Solaris 8's dirname(3) does. + */ + { "/usr///lib", "/usr" }, + + { NULL, NULL } +}; + +ATF_TC(basename_posix); +ATF_TC_HEAD(basename_posix, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test basename(3) with POSIX examples"); +} + +ATF_TC_BODY(basename_posix, tc) +{ + char testbuf[32], *base; + int i; + + for (i = 0; test_basename_table[i].output != NULL; i++) { + if (test_basename_table[i].input != NULL) { + if (strlen(test_basename_table[i].input) >= + sizeof(testbuf)) + atf_tc_skip("Testbuf too small!"); + strcpy(testbuf, test_basename_table[i].input); + base = basename(testbuf); + } else + base = basename(NULL); + + /* + * basename(3) is allowed to modify the input buffer. + * However, that is considered hostile by some programs, + * and so we elect to consider this an error. + * + * This is not a problem, as basename(3) is also allowed + * to return a pointer to a statically-allocated buffer + * (it is explicitly not required to be reentrant). + */ + if (test_basename_table[i].input != NULL && + strcmp(test_basename_table[i].input, testbuf) != 0) { + fprintf(stderr, + "Input buffer for \"%s\" was modified\n", + test_basename_table[i].input); + atf_tc_fail("Input buffer was modified."); + } + + /* Make sure the result is correct. */ + if (strcmp(test_basename_table[i].output, base) != 0) { + fprintf(stderr, + "Input \"%s\", output \"%s\", expected \"%s\"\n", + test_basename_table[i].input == + NULL ? "(null)" : test_basename_table[i].input, + base, test_basename_table[i].output); + atf_tc_fail("Output does not match expected value."); + } + } +} + + +ATF_TC(dirname_posix); +ATF_TC_HEAD(dirname_posix, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test dirname(3) with POSIX examples"); +} + +ATF_TC_BODY(dirname_posix, tc) +{ + char testbuf[32], *base; + int i; + + for (i = 0; test_dirname_table[i].output != NULL; i++) { + if (test_dirname_table[i].input != NULL) { + if (strlen(test_dirname_table[i].input) >= + sizeof(testbuf)) + atf_tc_skip("Testbuf too small!"); + strcpy(testbuf, test_dirname_table[i].input); + base = dirname(testbuf); + } else + base = dirname(NULL); + + /* + * dirname(3) is allowed to modify the input buffer. + * However, that is considered hostile by some programs, + * and so we elect to consider this an error. + * + * This is not a problem, as dirname(3) is also allowed + * to return a pointer to a statically-allocated buffer + * (it is explicitly not required to be reentrant). + */ + if (test_dirname_table[i].input != NULL && + strcmp(test_dirname_table[i].input, testbuf) != 0) { + fprintf(stderr, + "Input buffer for \"%s\" was modified\n", + test_dirname_table[i].input); + atf_tc_fail("Input buffer was modified."); + } + + /* Make sure the result is correct. */ + if (strcmp(test_dirname_table[i].output, base) != 0) { + fprintf(stderr, + "Input \"%s\", output \"%s\", expected \"%s\"\n", + test_dirname_table[i].input == + NULL ? "(null)" : test_dirname_table[i].input, + base, test_dirname_table[i].output); + atf_tc_fail("Output does not match expected value."); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, basename_posix); + ATF_TP_ADD_TC(tp, dirname_posix); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_closefrom.c b/contrib/netbsd-tests/lib/libc/gen/t_closefrom.c new file mode 100644 index 0000000..75ebabb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_closefrom.c @@ -0,0 +1,173 @@ +/* $NetBSD: t_closefrom.c,v 1.4 2011/05/11 08:11:36 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_closefrom.c,v 1.4 2011/05/11 08:11:36 jruoho Exp $"); + +#include + +#include +#include +#include +#include +#include + +static const char path[] = "closefrom"; + +ATF_TC_WITH_CLEANUP(closefrom_basic); +ATF_TC_HEAD(closefrom_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of closefrom(3), #1"); +} + +ATF_TC_BODY(closefrom_basic, tc) +{ + int fd, cur1, cur2; + + (void)closefrom(STDERR_FILENO + 1); + + fd = open(path, O_RDONLY | O_CREAT, 0400); + ATF_REQUIRE(fd >= 0); + + cur1 = fcntl(0, F_MAXFD); + + ATF_REQUIRE(cur1 == STDERR_FILENO + 1); + ATF_REQUIRE(closefrom(cur1) == 0); + + cur2 = fcntl(0, F_MAXFD); + + ATF_REQUIRE(cur1 - 1 == cur2); + ATF_REQUIRE(close(fd) == -1); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(closefrom_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(closefrom_buffer); +ATF_TC_HEAD(closefrom_buffer, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of closefrom(3), #2"); +} + +ATF_TC_BODY(closefrom_buffer, tc) +{ + int buf[16], cur, half; + size_t i; + + /* + * Open a buffer of descriptors, close the half of + * these and verify that the result is consistent. + */ + ATF_REQUIRE(closefrom(STDERR_FILENO + 1) == 0); + + cur = fcntl(0, F_MAXFD); + ATF_REQUIRE(cur == STDERR_FILENO); + + for (i = 0; i < __arraycount(buf); i++) { + buf[i] = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(buf[i] >= 0); + } + + cur = fcntl(0, F_MAXFD); + ATF_REQUIRE(cur == __arraycount(buf) + STDERR_FILENO); + + half = STDERR_FILENO + __arraycount(buf) / 2; + ATF_REQUIRE(closefrom(half) == 0); + + cur = fcntl(0, F_MAXFD); + ATF_REQUIRE(cur == half - 1); + + for (i = 0; i < __arraycount(buf); i++) + (void)close(buf[i]); +} + +ATF_TC_CLEANUP(closefrom_buffer, tc) +{ + (void)unlink(path); +} + +ATF_TC(closefrom_err); +ATF_TC_HEAD(closefrom_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from closefrom(3)"); +} + +ATF_TC_BODY(closefrom_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, closefrom(-INT_MAX) == -1); +} + +ATF_TC(closefrom_one); +ATF_TC_HEAD(closefrom_one, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test closefrom(1)"); +} + +ATF_TC_BODY(closefrom_one, tc) +{ + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (closefrom(1) != 0) + _exit(10); + + _exit(fcntl(0, F_MAXFD)); + } + + + (void)wait(&sta); + + /* + * STDIN_FILENO sould still be open; WEXITSTATUS(1) == 0. + */ + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != 0) + atf_tc_fail("not all descriptors were closed"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, closefrom_basic); + ATF_TP_ADD_TC(tp, closefrom_buffer); + ATF_TP_ADD_TC(tp, closefrom_err); + ATF_TP_ADD_TC(tp, closefrom_one); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_cpuset.c b/contrib/netbsd-tests/lib/libc/gen/t_cpuset.c new file mode 100644 index 0000000..9eca03b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_cpuset.c @@ -0,0 +1,114 @@ +/* $NetBSD: t_cpuset.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_cpuset.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $"); + +#include +#include +#include +#include + +ATF_TC(cpuset_err); +ATF_TC_HEAD(cpuset_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from cpuset(3)"); +} + +ATF_TC_BODY(cpuset_err, tc) +{ + cpuset_t *set; + + set = cpuset_create(); + ATF_REQUIRE(set != NULL); + + ATF_CHECK(cpuset_set(-1, set) == -1); + ATF_CHECK(cpuset_clr(-1, set) == -1); + ATF_CHECK(cpuset_isset(-1, set) == -1); + + ATF_CHECK(cpuset_set(INT_MAX, set) == -1); + ATF_CHECK(cpuset_clr(INT_MAX, set) == -1); + ATF_CHECK(cpuset_isset(INT_MAX, set) == -1); + + cpuset_destroy(set); +} + +ATF_TC(cpuset_set); +ATF_TC_HEAD(cpuset_set, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cpuset_set(3)"); +} + +ATF_TC_BODY(cpuset_set, tc) +{ + cpuset_t *set; + + set = cpuset_create(); + ATF_REQUIRE(set != NULL); + + ATF_REQUIRE(cpuset_set(0, set) == 0); + ATF_REQUIRE(cpuset_isset(0, set) > 0); + ATF_REQUIRE(cpuset_clr(0, set) == 0); + ATF_REQUIRE(cpuset_isset(0, set) == 0); + + cpuset_destroy(set); +} + +ATF_TC(cpuset_size); +ATF_TC_HEAD(cpuset_size, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test puset_size(3)"); +} + +ATF_TC_BODY(cpuset_size, tc) +{ + cpuset_t *set; + size_t size; + + set = cpuset_create(); + ATF_REQUIRE(set != NULL); + + size = cpuset_size(set); + + ATF_CHECK(cpuset_set((size * 8) - 1, set) == 0); + ATF_CHECK(cpuset_set((size * 8) + 1, set) == -1); + + cpuset_destroy(set); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cpuset_err); + ATF_TP_ADD_TC(tp, cpuset_set); + ATF_TP_ADD_TC(tp, cpuset_size); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_dir.c b/contrib/netbsd-tests/lib/libc/gen/t_dir.c new file mode 100644 index 0000000..362692f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_dir.c @@ -0,0 +1,193 @@ +/* $NetBSD: t_dir.c,v 1.10 2017/01/11 18:15:02 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +ATF_TC(seekdir_basic); +ATF_TC_HEAD(seekdir_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check telldir(3) and seekdir(3) " + "for correct behavior (PR lib/24324)"); +} + +ATF_TC_BODY(seekdir_basic, tc) +{ + DIR *dp; + char *wasname; + struct dirent *entry; + long here; + +#define CREAT(x, m) do { \ + int _creat_fd; \ + ATF_REQUIRE_MSG((_creat_fd = creat((x), (m))) != -1, \ + "creat(%s, %x) failed: %s", (x), (m), \ + strerror(errno)); \ + (void)close(_creat_fd); \ + } while(0); + + ATF_REQUIRE_MSG(mkdir("t", 0755) == 0, + "mkdir failed: %s", strerror(errno)); + CREAT("t/a", 0600); + CREAT("t/b", 0600); + CREAT("t/c", 0600); + + dp = opendir("t"); + if ( dp == NULL) + atf_tc_fail("Could not open temp directory."); + + /* skip two for . and .. */ + entry = readdir(dp); + ATF_REQUIRE_MSG(entry != NULL, "readdir[%s] failed: %s", + ".", strerror(errno)); + + entry = readdir(dp); + ATF_REQUIRE_MSG(entry != NULL, "readdir[%s] failed: %s", + "..", strerror(errno)); + + /* get first entry */ + entry = readdir(dp); + ATF_REQUIRE_MSG(entry != NULL, "readdir[%s] failed: %s", + "first", strerror(errno)); + + here = telldir(dp); + ATF_REQUIRE_MSG(here != -1, "telldir failed: %s", strerror(errno)); + + /* get second entry */ + entry = readdir(dp); + ATF_REQUIRE_MSG(entry != NULL, "readdir[%s] failed: %s", + "second", strerror(errno)); + + wasname = strdup(entry->d_name); + if (wasname == NULL) + atf_tc_fail("cannot allocate memory"); + + /* get third entry */ + entry = readdir(dp); + ATF_REQUIRE_MSG(entry != NULL, "readdir[%s] failed: %s", + "third", strerror(errno)); + + /* try to return to the position after the first entry */ + seekdir(dp, here); + entry = readdir(dp); + ATF_REQUIRE_MSG(entry != NULL, "readdir[%s] failed: %s", + "first[1]", strerror(errno)); + if (strcmp(entry->d_name, wasname) != 0) + atf_tc_fail("1st seekdir found wrong name"); + + /* try again, and throw in a telldir() for good measure */ + seekdir(dp, here); + here = telldir(dp); + entry = readdir(dp); + ATF_REQUIRE_MSG(entry != NULL, "readdir[%s] failed: %s", + "second[1]", strerror(errno)); + if (strcmp(entry->d_name, wasname) != 0) + atf_tc_fail("2nd seekdir found wrong name"); + + /* One more time, to make sure that telldir() doesn't affect result */ + seekdir(dp, here); + entry = readdir(dp); + ATF_REQUIRE_MSG(entry != NULL, "readdir[%s] failed: %s", + "third[1]", strerror(errno)); + + if (strcmp(entry->d_name, wasname) != 0) + atf_tc_fail("3rd seekdir found wrong name"); + + closedir(dp); + free(wasname); +} + +/* There is no sbrk on AArch64 and RISC-V */ +#if !defined(__aarch64__) && !defined(__riscv__) +ATF_TC(telldir_leak); +ATF_TC_HEAD(telldir_leak, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Check telldir(3) for memory leakage (PR lib/24324)"); +} + +ATF_TC_BODY(telldir_leak, tc) +{ + DIR *dp; + char *memused; + int i; + int oktouse = 4096; + + dp = opendir("."); + if (dp == NULL) + atf_tc_fail("Could not open current directory"); + + (void)telldir(dp); + memused = sbrk(0); + closedir(dp); + + for (i = 0; i < 1000; i++) { + dp = opendir("."); + if (dp == NULL) + atf_tc_fail("Could not open current directory"); + + (void)telldir(dp); + closedir(dp); + + if ((char *)sbrk(0) - memused > oktouse) { + (void)printf("Used %td extra bytes for %d telldir " + "calls", ((char *)sbrk(0) - memused), i); + oktouse = (char *)sbrk(0) - memused; + } + } + if (oktouse > 4096) { + atf_tc_fail("Failure: leaked %d bytes", oktouse); + } else { + (void)printf("OK: used %td bytes\n", (char *)(sbrk(0))-memused); + } +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, seekdir_basic); +#if !defined(__aarch64__) && !defined(__riscv__) + ATF_TP_ADD_TC(tp, telldir_leak); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c b/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c new file mode 100644 index 0000000..c3417bb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c @@ -0,0 +1,140 @@ +/* $NetBSD: t_floatunditf.c,v 1.6 2014/11/04 00:20:19 justin Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#ifdef __HAVE_LONG_DOUBLE +static const struct { + uint64_t u64; + long double ld; +} testcases[] = { + { 0xffffffffffffffffULL, 0xf.fffffffffffffffp+60L }, + { 0xfffffffffffffffeULL, 0xf.ffffffffffffffep+60L }, + { 0xfffffffffffffffdULL, 0xf.ffffffffffffffdp+60L }, + { 0xfffffffffffffffcULL, 0xf.ffffffffffffffcp+60L }, + { 0x7fffffffffffffffULL, 0xf.ffffffffffffffep+59L }, + { 0x3fffffffffffffffULL, 0xf.ffffffffffffffcp+58L }, + { 0x1fffffffffffffffULL, 0xf.ffffffffffffff8p+57L }, + { 0xfffffffffffffffULL, 0xf.ffffffffffffffp+56L }, + { 0x7ffffffffffffffULL, 0xf.fffffffffffffep+55L }, + { 0x3ffffffffffffffULL, 0xf.fffffffffffffcp+54L }, + { 0x1ffffffffffffffULL, 0xf.fffffffffffff8p+53L }, + { 0xffffffffffffffULL, 0xf.fffffffffffffp+52L }, + { 0x7fffffffffffffULL, 0xf.ffffffffffffep+51L }, + { 0x3fffffffffffffULL, 0xf.ffffffffffffcp+50L }, + { 0x1fffffffffffffULL, 0xf.ffffffffffff8p+49L }, + { 0xfffffffffffffULL, 0xf.ffffffffffffp+48L }, + { 0x7ffffffffffffULL, 0xf.fffffffffffep+47L }, + { 0x3ffffffffffffULL, 0xf.fffffffffffcp+46L }, + { 0x1ffffffffffffULL, 0xf.fffffffffff8p+45L }, + { 0xffffffffffffULL, 0xf.fffffffffffp+44L }, + { 0x7fffffffffffULL, 0xf.ffffffffffep+43L }, + { 0x3fffffffffffULL, 0xf.ffffffffffcp+42L }, + { 0x1fffffffffffULL, 0xf.ffffffffff8p+41L }, + { 0xfffffffffffULL, 0xf.ffffffffffp+40L }, + { 0x7ffffffffffULL, 0xf.fffffffffep+39L }, + { 0x3ffffffffffULL, 0xf.fffffffffcp+38L }, + { 0x1ffffffffffULL, 0xf.fffffffff8p+37L }, + { 0xffffffffffULL, 0xf.fffffffffp+36L }, + { 0x7fffffffffULL, 0xf.ffffffffep+35L }, + { 0x3fffffffffULL, 0xf.ffffffffcp+34L }, + { 0x1fffffffffULL, 0xf.ffffffff8p+33L }, + { 0xfffffffffULL, 0xf.ffffffffp+32L }, + { 0x7ffffffffULL, 0xf.fffffffep+31L }, + { 0x3ffffffffULL, 0xf.fffffffcp+30L }, + { 0x1ffffffffULL, 0xf.fffffff8p+29L }, + { 0xffffffffULL, 0xf.fffffffp+28L }, + { 0x7fffffffULL, 0xf.ffffffep+27L }, + { 0x3fffffffULL, 0xf.ffffffcp+26L }, + { 0x1fffffffULL, 0xf.ffffff8p+25L }, + { 0xfffffffULL, 0xf.ffffffp+24L }, + { 0x7ffffffULL, 0xf.fffffep+23L }, + { 0x3ffffffULL, 0xf.fffffcp+22L }, + { 0x1ffffffULL, 0xf.fffff8p+21L }, + { 0xffffffULL, 0xf.fffffp+20L }, + { 0x7fffffULL, 0xf.ffffep+19L }, + { 0x3fffffULL, 0xf.ffffcp+18L }, + { 0x1fffffULL, 0xf.ffff8p+17L }, + { 0xfffffULL, 0xf.ffffp+16L }, + { 0x7ffffULL, 0xf.fffep+15L }, + { 0x3ffffULL, 0xf.fffcp+14L }, + { 0x1ffffULL, 0xf.fff8p+13L }, + { 0xffffULL, 0xf.fffp+12L }, + { 0x7fffULL, 0xf.ffep+11L }, + { 0x3fffULL, 0xf.ffcp+10L }, + { 0x1fffULL, 0xf.ff8p+9L }, + { 0xfffULL, 0xf.ffp+8L }, + { 0x7ffULL, 0xf.fep+7L }, + { 0x3ffULL, 0xf.fcp+6L }, + { 0x1ffULL, 0xf.f8p+5L }, + { 0xffULL, 0xf.fp+4L }, + { 0x7fULL, 0xf.ep+3L }, + { 0x3fULL, 0xf.cp+2L }, + { 0x1fULL, 0xf.8p+1L }, + { 0xfULL, 0xfp+0L }, + { 0x7ULL, 0xep-1L }, + { 0x3ULL, 0xcp-2L }, + { 0x1ULL, 0x8p-3L }, +}; +#endif + +ATF_TC(floatunditf); +ATF_TC_HEAD(floatunditf, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that uint64 -> long double conversion works"); +} + +ATF_TC_BODY(floatunditf, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + size_t i; + +#if defined(__FreeBSD__) && defined(__i386__) + atf_tc_expect_fail("the floating point error on FreeBSD/i386 doesn't " + "match the expected floating point error on NetBSD"); +#endif + + for (i = 0; i < __arraycount(testcases); ++i) + ATF_CHECK_MSG( + testcases[i].ld == (long double)testcases[i].u64, + "#%zu: expected %.20Lf, got %.20Lf\n", i, + testcases[i].ld, + (long double)testcases[i].u64); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, floatunditf); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c b/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c new file mode 100644 index 0000000..ab95400 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c @@ -0,0 +1,117 @@ +/* $NetBSD: t_fmtcheck.c,v 1.3 2014/06/14 08:19:02 apb Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Allen Briggs. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include + +const char *fmtcheck(const char *f1, const char *f2) + __attribute__((__format_arg__(2))); + +#include + +struct test_fmt { + const char *fmt1; + const char *fmt2; + int correct; +} test_fmts[] = { + { "%d", "%d", 1 }, + { "%2d", "%2.2d", 1 }, + { "%x", "%d", 1 }, + { "%u", "%d", 1 }, + { "%03d", "%d", 1 }, + { "%-2d", "%d", 1 }, + { "%d", "%-12.1d", 1 }, + { "%d", "%-01.3d", 1 }, + { "%X", "%-01.3d", 1 }, + { "%D", "%ld", 1 }, + { "%s", "%s", 1 }, + { "%s", "This is a %s test", 1 }, + { "Hi, there. This is a %s test", "%s", 1 }, + { "%d", "%s", 2 }, + { "%e", "%s", 2 }, + { "%r", "%d", 2 }, + { "%*.2d", "%*d", 1 }, + { "%2.*d", "%*d", 2 }, + { "%*d", "%*d", 1 }, + { "%-3", "%d", 2 }, + { "%d %s", "%d", 2 }, + { "%*.*.*d", "%*.*.*d", 2 }, + { "%d", "%d %s", 1 }, + { "%40s", "%20s", 1 }, + { "%x %x %x", "%o %u %d", 1 }, + { "%o %u %d", "%x %x %X", 1 }, + { "%#o %u %#-d", "%x %#x %X", 1 }, + { "%qd", "%llx", 1 }, + { "%%", "%llx", 1 }, + { "%ld %30s %#llx %-10.*e", "This number %lu%% and string %s has %qd numbers and %.*g floats", 1 }, + { "%o", "%lx", 2 }, + { "%p", "%lu", 2 }, +}; + +ATF_TC(fmtcheck_basic); +ATF_TC_HEAD(fmtcheck_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test fmtcheck(3)"); +} + +ATF_TC_BODY(fmtcheck_basic, tc) +{ + unsigned int i, r; + const char *f, *cf, *f1, *f2; + + r = 0; + for (i = 0 ; i < __arraycount(test_fmts); i++) { + f1 = test_fmts[i].fmt1; + f2 = test_fmts[i].fmt2; + f = fmtcheck(f1, f2); + if (test_fmts[i].correct == 1) { + cf = f1; + } else { + cf = f2; + } + if (f != cf) { + r++; + atf_tc_fail_nonfatal("Test %d: (%s) vs. (%s) failed " + "(should have returned %s)", i, f1, f2, + (test_fmts[i].correct == 1) ? "1st" : "2nd"); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fmtcheck_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c b/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c new file mode 100644 index 0000000..69ee8d2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c @@ -0,0 +1,193 @@ +/* $NetBSD: t_fnmatch.c,v 1.7 2016/10/31 05:08:53 dholland Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_fnmatch.c,v 1.7 2016/10/31 05:08:53 dholland Exp $"); + +#include +#include +#include + +ATF_TC(fnmatch_backslashes); +ATF_TC_HEAD(fnmatch_backslashes, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test translation of '\\' with fnmatch(3) (PR lib/41558)"); +} + +ATF_TC_BODY(fnmatch_backslashes, tc) +{ + const int rv = fnmatch(/* pattern */ "\\", "\\", 0); + + if (rv != FNM_NOMATCH) + atf_tc_fail("fnmatch(3) did not translate '\\'"); +} + +ATF_TC(fnmatch_casefold); +ATF_TC_HEAD(fnmatch_casefold, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_CASEFOLD"); +} + +ATF_TC_BODY(fnmatch_casefold, tc) +{ + ATF_CHECK(fnmatch("xxx", "XXX", 0) != 0); + ATF_CHECK(fnmatch("XXX", "xxx", 0) != 0); + ATF_CHECK(fnmatch("xxx", "XxX", 0) != 0); + ATF_CHECK(fnmatch("XxX", "xxx", 0) != 0); + ATF_CHECK(fnmatch("x*x", "XXX", 0) != 0); + ATF_CHECK(fnmatch("**x", "XXX", 0) != 0); + ATF_CHECK(fnmatch("*?x", "XXX", 0) != 0); + + ATF_CHECK(fnmatch("xxx", "XXX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("XXX", "xxx", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("xxx", "XxX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("XxX", "xxx", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("x*x", "XXX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("**x", "XXX", FNM_CASEFOLD) == 0); + ATF_CHECK(fnmatch("*?x", "XXX", FNM_CASEFOLD) == 0); +} + +ATF_TC(fnmatch_leadingdir); +ATF_TC_HEAD(fnmatch_leadingdir, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_LEADING_DIR"); +} + +ATF_TC_BODY(fnmatch_leadingdir, tc) +{ + ATF_CHECK(fnmatch("", "/*", 0) != 0); + ATF_CHECK(fnmatch(" ", " /*", 0) != 0); + ATF_CHECK(fnmatch("x", "x/*", 0) != 0); + ATF_CHECK(fnmatch("///", "////*", 0) != 0); + + ATF_CHECK(fnmatch("", "/*", FNM_LEADING_DIR) == 0); + ATF_CHECK(fnmatch(" ", " /*", FNM_LEADING_DIR) == 0); + ATF_CHECK(fnmatch("x", "x/*", FNM_LEADING_DIR) == 0); + ATF_CHECK(fnmatch("///", "////*", FNM_LEADING_DIR) == 0); +} + +ATF_TC(fnmatch_noescape); +ATF_TC_HEAD(fnmatch_noescape, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_NOESCAPE"); +} + +ATF_TC_BODY(fnmatch_noescape, tc) +{ + ATF_CHECK(fnmatch(" \\x", " \\x", 0) != 0); + ATF_CHECK(fnmatch("xx\\x", "xx\\x", 0) != 0); + ATF_CHECK(fnmatch("\\xxx", "\\xxx", 0) != 0); + + ATF_CHECK(fnmatch(" \\x", " \\x", FNM_NOESCAPE) == 0); + ATF_CHECK(fnmatch("xx\\x", "xx\\x", FNM_NOESCAPE) == 0); + ATF_CHECK(fnmatch("\\xxx", "\\xxx", FNM_NOESCAPE) == 0); +} + +ATF_TC(fnmatch_pathname); +ATF_TC_HEAD(fnmatch_pathname, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_PATHNAME"); +} + +ATF_TC_BODY(fnmatch_pathname, tc) +{ + ATF_CHECK(fnmatch("???x", "xxx/x", FNM_PATHNAME) != 0); + ATF_CHECK(fnmatch("***x", "xxx/x", FNM_PATHNAME) != 0); + + ATF_CHECK(fnmatch("???x", "xxxx", FNM_PATHNAME) == 0); + ATF_CHECK(fnmatch("*/xxx", "/xxx", FNM_PATHNAME) == 0); + ATF_CHECK(fnmatch("x/*.y", "x/z.y", FNM_PATHNAME) == 0); +} + +ATF_TC(fnmatch_period); +ATF_TC_HEAD(fnmatch_period, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test FNM_PERIOD"); +} + +ATF_TC_BODY(fnmatch_period, tc) +{ + ATF_CHECK(fnmatch("*x*", "X", FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("*x*", "X", FNM_PERIOD | FNM_CASEFOLD) == 0); + + ATF_CHECK(fnmatch("x?y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("x*y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*.c", "x.c", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*/?", "x/y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*/*", "x/y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch(".*/?", ".x/y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("*/.?", "x/.y", FNM_PATHNAME | FNM_PERIOD) == 0); + ATF_CHECK(fnmatch("x[.]y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0); + + ATF_CHECK(fnmatch("?x/y", ".x/y", FNM_PATHNAME | FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("*x/y", ".x/y", FNM_PATHNAME | FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("x/?y", "x/.y", FNM_PATHNAME | FNM_PERIOD) != 0); + ATF_CHECK(fnmatch("x/*y", "x/.y", FNM_PATHNAME | FNM_PERIOD) != 0); +} + +ATF_TC(fnmatch_initialbracket); +ATF_TC_HEAD(fnmatch_initialbracket, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test fnmatch with initial ["); +} + +ATF_TC_BODY(fnmatch_initialbracket, tc) +{ + ATF_CHECK(fnmatch("[[?*\\\\]", "\\", 0) == 0); + ATF_CHECK(fnmatch("[]?*\\\\]", "]", 0) == 0); + ATF_CHECK(fnmatch("[!]a-]", "b", 0) == 0); + ATF_CHECK(fnmatch("[]-_]", "^", 0) == 0); /* range: ']', '^', '_' */ + ATF_CHECK(fnmatch("[!]-_]", "X", 0) == 0); + ATF_CHECK(fnmatch("[A-\\\\]", "[", 0) == 0); + ATF_CHECK(fnmatch("[a-z]/[a-z]", "a/b", 0) == 0); + ATF_CHECK(fnmatch("[*]/b", "*/b", 0) == 0); + ATF_CHECK(fnmatch("[?]/b", "?/b", 0) == 0); + ATF_CHECK(fnmatch("[[a]/b", "a/b", 0) == 0); + ATF_CHECK(fnmatch("[[a]/b", "[/b", 0) == 0); + ATF_CHECK(fnmatch("[/b", "[/b", 0) == 0); + + ATF_CHECK(fnmatch("[*]/b", "a/b", 0) != 0); + ATF_CHECK(fnmatch("[?]/b", "a/b", 0) != 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fnmatch_backslashes); + ATF_TP_ADD_TC(tp, fnmatch_casefold); + ATF_TP_ADD_TC(tp, fnmatch_leadingdir); + ATF_TP_ADD_TC(tp, fnmatch_noescape); + ATF_TP_ADD_TC(tp, fnmatch_pathname); + ATF_TP_ADD_TC(tp, fnmatch_period); + ATF_TP_ADD_TC(tp, fnmatch_initialbracket); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c b/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c new file mode 100644 index 0000000..21dea9e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c @@ -0,0 +1,206 @@ +/* $NetBSD: t_fpclassify.c,v 1.3 2011/10/01 21:47:08 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include +#include + +#ifndef _FLOAT_IEEE754 + +ATF_TC(no_test); +ATF_TC_HEAD(no_test, tc) +{ + atf_tc_set_md_var(tc, "descr", "Dummy test"); +} + +ATF_TC_BODY(no_test,tc) +{ + atf_tc_skip("Test not available on this architecture"); +} + +#else /* defined(_FLOAT_IEEE754) */ + +ATF_TC(fpclassify_float); +ATF_TC_HEAD(fpclassify_float, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test float operations"); +} + +ATF_TC_BODY(fpclassify_float, tc) +{ + float d0, d1, d2, f, ip; + int e, i; + + d0 = FLT_MIN; + ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL); + f = frexpf(d0, &e); + ATF_REQUIRE_EQ(e, FLT_MIN_EXP); + ATF_REQUIRE_EQ(f, 0.5); + d1 = d0; + + /* shift a "1" bit through the mantissa (skip the implicit bit) */ + for (i = 1; i < FLT_MANT_DIG; i++) { + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL); + ATF_REQUIRE(d1 > 0 && d1 < d0); + + d2 = ldexpf(d0, -i); + ATF_REQUIRE_EQ(d2, d1); + + d2 = modff(d1, &ip); + ATF_REQUIRE_EQ(d2, d1); + ATF_REQUIRE_EQ(ip, 0); + + f = frexpf(d1, &e); + ATF_REQUIRE_EQ(e, FLT_MIN_EXP - i); + ATF_REQUIRE_EQ(f, 0.5); + } + + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO); + f = frexpf(d1, &e); + ATF_REQUIRE_EQ(e, 0); + ATF_REQUIRE_EQ(f, 0); +} + +ATF_TC(fpclassify_double); +ATF_TC_HEAD(fpclassify_double, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test double operations"); +} + +ATF_TC_BODY(fpclassify_double, tc) +{ + double d0, d1, d2, f, ip; + int e, i; + + d0 = DBL_MIN; + ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL); + f = frexp(d0, &e); + ATF_REQUIRE_EQ(e, DBL_MIN_EXP); + ATF_REQUIRE_EQ(f, 0.5); + d1 = d0; + + /* shift a "1" bit through the mantissa (skip the implicit bit) */ + for (i = 1; i < DBL_MANT_DIG; i++) { + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL); + ATF_REQUIRE(d1 > 0 && d1 < d0); + + d2 = ldexp(d0, -i); + ATF_REQUIRE_EQ(d2, d1); + + d2 = modf(d1, &ip); + ATF_REQUIRE_EQ(d2, d1); + ATF_REQUIRE_EQ(ip, 0); + + f = frexp(d1, &e); + ATF_REQUIRE_EQ(e, DBL_MIN_EXP - i); + ATF_REQUIRE_EQ(f, 0.5); + } + + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO); + f = frexp(d1, &e); + ATF_REQUIRE_EQ(e, 0); + ATF_REQUIRE_EQ(f, 0); +} + +/* + * XXX NetBSD doesn't have long-double flavors of frexp, ldexp, and modf, + * XXX so this test is disabled. + */ + +#ifdef TEST_LONG_DOUBLE + +ATF_TC(fpclassify_long_double); +ATF_TC_HEAD(fpclassify_long_double, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test long double operations"); +} + +ATF_TC_BODY(fpclassify_long_double, tc) +{ + long double d0, d1, d2, f, ip; + int e, i; + + d0 = LDBL_MIN; + ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL); + f = frexpl(d0, &e); + ATF_REQUIRE_EQ(e, LDBL_MIN_EXP); + ATF_REQUIRE_EQ(f, 0.5); + d1 = d0; + + /* shift a "1" bit through the mantissa (skip the implicit bit) */ + for (i = 1; i < LDBL_MANT_DIG; i++) { + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL); + ATF_REQUIRE(d1 > 0 && d1 < d0); + + d2 = ldexpl(d0, -i); + ATF_REQUIRE_EQ(d2, d1); + + d2 = modfl(d1, &ip); + ATF_REQUIRE_EQ(d2, d1); + ATF_REQUIRE_EQ(ip, 0); + + f = frexpl(d1, &e); + ATF_REQUIRE_EQ(e, LDBL_MIN_EXP - i); + ATF_REQUIRE_EQ(f, 0.5); + } + + d1 /= 2; + ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO); + f = frexpl(d1, &e); + ATF_REQUIRE_EQ(e, 0); + ATF_REQUIRE_EQ(f, 0); +} +#endif /* TEST_LONG_DOUBLE */ +#endif /* _FLOAT_IEEE754 */ + +ATF_TP_ADD_TCS(tp) +{ + +#ifndef _FLOAT_IEEE754 + ATF_TP_ADD_TC(tp, no_test); +#else + ATF_TP_ADD_TC(tp, fpclassify_float); + ATF_TP_ADD_TC(tp, fpclassify_double); +#ifdef TEST_LONG_DOUBLE + ATF_TP_ADD_TC(tp, fpclassify_long_double); +#endif /* TEST_LONG_DOUBLE */ +#endif /* _FLOAT_IEEE754 */ + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c b/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c new file mode 100644 index 0000000..5edc583 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c @@ -0,0 +1,371 @@ +/* $NetBSD: t_fpsetmask.c,v 1.16 2016/03/12 11:55:14 martin Exp $ */ + +/*- + * Copyright (c) 1995 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include + +#include +#include +#include +#include +#include +#include + +#include "isqemu.h" + +#ifndef _FLOAT_IEEE754 + +ATF_TC(no_test); +ATF_TC_HEAD(no_test, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Dummy test case"); +} + +ATF_TC_BODY(no_test, tc) +{ + + atf_tc_skip("Test not available on this architecture."); +} + +#else /* defined(_FLOAT_IEEE754) */ + +#include + +#if __arm__ && !__SOFTFP__ + /* + * Some NEON fpus do not implement IEEE exception handling, + * skip these tests if running on them and compiled for + * hard float. + */ +#define FPU_PREREQ() \ + if (0 == fpsetmask(fpsetmask(FP_X_INV))) \ + atf_tc_skip("FPU does not implement exception handling"); +#endif + +#ifndef FPU_PREREQ +#define FPU_PREREQ() /* nothing */ +#endif + +void sigfpe(int, siginfo_t *, void *); + +volatile sig_atomic_t signal_caught; +volatile int sicode; + +static volatile const float f_one = 1.0; +static volatile const float f_zero = 0.0; +static volatile const double d_one = 1.0; +static volatile const double d_zero = 0.0; +static volatile const long double ld_one = 1.0; +static volatile const long double ld_zero = 0.0; + +static volatile const float f_huge = FLT_MAX; +static volatile const float f_tiny = FLT_MIN; +static volatile const double d_huge = DBL_MAX; +static volatile const double d_tiny = DBL_MIN; +static volatile const long double ld_huge = LDBL_MAX; +static volatile const long double ld_tiny = LDBL_MIN; + +static volatile float f_x; +static volatile double d_x; +static volatile long double ld_x; + +/* trip divide by zero */ +static void +f_dz(void) +{ + + f_x = f_one / f_zero; +} + +static void +d_dz(void) +{ + + d_x = d_one / d_zero; +} + +static void +ld_dz(void) +{ + + ld_x = ld_one / ld_zero; +} + +/* trip invalid operation */ +static void +d_inv(void) +{ + + d_x = d_zero / d_zero; +} + +static void +ld_inv(void) +{ + + ld_x = ld_zero / ld_zero; +} + +static void +f_inv(void) +{ + + f_x = f_zero / f_zero; +} + +/* trip overflow */ +static void +f_ofl(void) +{ + + f_x = f_huge * f_huge; +} + +static void +d_ofl(void) +{ + + d_x = d_huge * d_huge; +} + +static void +ld_ofl(void) +{ + + ld_x = ld_huge * ld_huge; +} + +/* trip underflow */ +static void +f_ufl(void) +{ + + f_x = f_tiny * f_tiny; +} + +static void +d_ufl(void) +{ + + d_x = d_tiny * d_tiny; +} + +static void +ld_ufl(void) +{ + + ld_x = ld_tiny * ld_tiny; +} + +struct ops { + void (*op)(void); + fp_except mask; + int sicode; +}; + +static const struct ops float_ops[] = { + { f_dz, FP_X_DZ, FPE_FLTDIV }, + { f_inv, FP_X_INV, FPE_FLTINV }, + { f_ofl, FP_X_OFL, FPE_FLTOVF }, + { f_ufl, FP_X_UFL, FPE_FLTUND }, + { NULL, 0, 0 } +}; + +static const struct ops double_ops[] = { + { d_dz, FP_X_DZ, FPE_FLTDIV }, + { d_inv, FP_X_INV, FPE_FLTINV }, + { d_ofl, FP_X_OFL, FPE_FLTOVF }, + { d_ufl, FP_X_UFL, FPE_FLTUND }, + { NULL, 0, 0 } +}; + +static const struct ops long_double_ops[] = { + { ld_dz, FP_X_DZ, FPE_FLTDIV }, + { ld_inv, FP_X_INV, FPE_FLTINV }, + { ld_ofl, FP_X_OFL, FPE_FLTOVF }, + { ld_ufl, FP_X_UFL, FPE_FLTUND }, + { NULL, 0, 0 } +}; + +static sigjmp_buf b; + +static void +fpsetmask_masked(const struct ops *test_ops) +{ + struct sigaction sa; + fp_except ex1, ex2; + const struct ops *t; + + /* mask all exceptions, clear history */ + fpsetmask(0); + fpsetsticky(0); + + /* set up signal handler */ + sa.sa_sigaction = sigfpe; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sigaction(SIGFPE, &sa, 0); + signal_caught = 0; + + /* + * exceptions masked, check whether "sticky" bits are set correctly + */ + for (t = test_ops; t->op != NULL; t++) { + (*t->op)(); + ex1 = fpgetsticky(); + ATF_CHECK_EQ(ex1 & t->mask, t->mask); + ATF_CHECK_EQ(signal_caught, 0); + + /* check correct fpsetsticky() behaviour */ + ex2 = fpsetsticky(0); + ATF_CHECK_EQ(fpgetsticky(), 0); + ATF_CHECK_EQ(ex1, ex2); + } +} + +/* force delayed exceptions to be delivered */ +#define BARRIER() fpsetmask(0); f_x = f_one * f_one + +static void +fpsetmask_unmasked(const struct ops *test_ops) +{ + struct sigaction sa; + int r; + const struct ops *volatile t; + + /* mask all exceptions, clear history */ + fpsetmask(0); + fpsetsticky(0); + + /* set up signal handler */ + sa.sa_sigaction = sigfpe; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sigaction(SIGFPE, &sa, 0); + signal_caught = 0; + + /* + * exception unmasked, check SIGFPE delivery and correct siginfo + */ + for (t = test_ops; t->op != NULL; t++) { + fpsetmask(t->mask); + r = sigsetjmp(b, 1); + if (!r) { + (*t->op)(); + BARRIER(); + } + ATF_CHECK_EQ(signal_caught, 1); + ATF_CHECK_EQ(sicode, t->sicode); + signal_caught = 0; + } +} + +void +sigfpe(int s, siginfo_t *si, void *c) +{ + signal_caught = 1; + sicode = si->si_code; + siglongjmp(b, 1); +} + +#define TEST(m, t) \ + ATF_TC(m##_##t); \ + \ + ATF_TC_HEAD(m##_##t, tc) \ + { \ + \ + atf_tc_set_md_var(tc, "descr", \ + "Test " ___STRING(m) " exceptions for " \ + ___STRING(t) "values"); \ + } \ + \ + ATF_TC_BODY(m##_##t, tc) \ + { \ + \ + FPU_PREREQ(); \ + \ + if (strcmp(MACHINE, "macppc") == 0) \ + atf_tc_expect_fail("PR port-macppc/46319"); \ + \ + if (isQEMU()) \ + atf_tc_expect_fail("PR misc/44767"); \ + \ + m(t##_ops); \ + } + +TEST(fpsetmask_masked, float) +TEST(fpsetmask_masked, double) +TEST(fpsetmask_masked, long_double) +TEST(fpsetmask_unmasked, float) +TEST(fpsetmask_unmasked, double) +TEST(fpsetmask_unmasked, long_double) + +ATF_TC(fpsetmask_basic); +ATF_TC_HEAD(fpsetmask_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fpsetmask(3)"); +} + +ATF_TC_BODY(fpsetmask_basic, tc) +{ + size_t i; + fp_except_t msk, lst[] = { FP_X_INV, FP_X_DZ, FP_X_OFL, FP_X_UFL }; + + FPU_PREREQ(); + + msk = fpgetmask(); + for (i = 0; i < __arraycount(lst); i++) { + fpsetmask(msk | lst[i]); + ATF_CHECK((fpgetmask() & lst[i]) != 0); + fpsetmask(msk & ~lst[i]); + ATF_CHECK((fpgetmask() & lst[i]) == 0); + } + +} + +#endif /* defined(_FLOAT_IEEE754) */ + +ATF_TP_ADD_TCS(tp) +{ + +#ifndef _FLOAT_IEEE754 + ATF_TP_ADD_TC(tp, no_test); +#else + ATF_TP_ADD_TC(tp, fpsetmask_basic); + ATF_TP_ADD_TC(tp, fpsetmask_masked_float); + ATF_TP_ADD_TC(tp, fpsetmask_masked_double); + ATF_TP_ADD_TC(tp, fpsetmask_masked_long_double); + ATF_TP_ADD_TC(tp, fpsetmask_unmasked_float); + ATF_TP_ADD_TC(tp, fpsetmask_unmasked_double); + ATF_TP_ADD_TC(tp, fpsetmask_unmasked_long_double); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c b/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c new file mode 100644 index 0000000..0f23e74 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c @@ -0,0 +1,163 @@ +/* $NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $"); + +#include +#include +#include +#include +#include + +#include + +ATF_TC(fpsetround_basic); +ATF_TC_HEAD(fpsetround_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Minimal testing of fpgetround(3) and fpsetround(3)"); +} + +#ifdef _FLOAT_IEEE754 +#include + +static const struct { + const char *n; + int rm; + int rf; +} rnd[] = { + { "RN", FP_RN, 1 }, + { "RP", FP_RP, 2 }, + { "RM", FP_RM, 3 }, + { "RZ", FP_RZ, 0 }, + +}; + +static const struct { + const char *n; + int v[4]; +} tst[] = { /* RN RP RM RZ */ + { "1.1", { 1, 1, 2, 1 } }, + { "1.5", { 1, 2, 2, 1 } }, + { "1.9", { 1, 2, 2, 1 } }, + { "2.1", { 2, 2, 3, 2 } }, + { "2.5", { 2, 2, 3, 2 } }, + { "2.9", { 2, 3, 3, 2 } }, + { "-1.1", { -1, -1, -1, -2 } }, + { "-1.5", { -1, -2, -1, -2 } }, + { "-1.9", { -1, -2, -1, -2 } }, + { "-2.1", { -2, -2, -2, -3 } }, + { "-2.5", { -2, -2, -2, -3 } }, + { "-2.9", { -2, -3, -2, -3 } }, +}; + +static const char * +getname(int r) +{ + for (size_t i = 0; i < __arraycount(rnd); i++) + if (rnd[i].rm == r) + return rnd[i].n; + return "*unknown*"; +} + +static void +test(int r) +{ + int did = 0; + for (size_t i = 0; i < __arraycount(tst); i++) { + double d = strtod(tst[i].n, NULL); + int g = (int)rint(d); + int e = tst[i].v[r]; + ATF_CHECK_EQ(g, e); + if (g != e) { + if (!did) { + fprintf(stderr, "Mode Value Result Expected\n"); + did = 1; + } + fprintf(stderr, "%4.4s %-5.5s %6d %8d\n", rnd[r].n, + tst[i].n, (int)rint(d), tst[i].v[r]); + } + } +} +#endif + + +ATF_TC_BODY(fpsetround_basic, tc) +{ + +#ifndef _FLOAT_IEEE754 + atf_tc_skip("Test not applicable on this architecture."); +#else + int r; + + ATF_CHECK_EQ(r = fpgetround(), FP_RN); + if (FP_RN != r) + fprintf(stderr, "default expected=%s got=%s\n", getname(FP_RN), + getname(r)); + ATF_CHECK_EQ(FLT_ROUNDS, 1); + + for (size_t i = 0; i < __arraycount(rnd); i++) { + const size_t j = (i + 1) & 3; + const int o = rnd[i].rm; + const int n = rnd[j].rm; + + ATF_CHECK_EQ(r = fpsetround(n), o); + if (o != r) + fprintf(stderr, "set %s expected=%s got=%s\n", + getname(n), getname(o), getname(r)); + ATF_CHECK_EQ(r = fpgetround(), n); + if (n != r) + fprintf(stderr, "get expected=%s got=%s\n", getname(n), + getname(r)); + ATF_CHECK_EQ(r = FLT_ROUNDS, rnd[j].rf); + if (r != rnd[j].rf) + fprintf(stderr, "rounds expected=%x got=%x\n", + rnd[j].rf, r); + test(r); + } +#endif /* _FLOAT_IEEE754 */ +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fpsetround_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_ftok.c b/contrib/netbsd-tests/lib/libc/gen/t_ftok.c new file mode 100644 index 0000000..4c1ab18 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_ftok.c @@ -0,0 +1,108 @@ +/* $NetBSD: t_ftok.c,v 1.2 2017/01/10 15:19:52 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_ftok.c,v 1.2 2017/01/10 15:19:52 christos Exp $"); + +#include +#include + +#include +#include +#include + +static const char *path = "ftok"; +static const char *hlnk = "hlnk"; +static const char *slnk = "slnk"; +static const int key = 123456789; + +ATF_TC(ftok_err); +ATF_TC_HEAD(ftok_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from ftok(3)"); +} + +ATF_TC_BODY(ftok_err, tc) +{ + ATF_REQUIRE(ftok("/a/b/c/d/e/f/g/h/i", key) == -1); +} + +ATF_TC_WITH_CLEANUP(ftok_link); +ATF_TC_HEAD(ftok_link, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that links return the same key"); +} + +ATF_TC_BODY(ftok_link, tc) +{ + key_t k1, k2, k3; + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + + ATF_REQUIRE(fd >= 0); + (void)close(fd); + ATF_REQUIRE(link(path, hlnk) == 0); + ATF_REQUIRE(symlink(path, slnk) == 0); + + k1 = ftok(path, key); + k2 = ftok(hlnk, key); + k3 = ftok(slnk, key); + + ATF_REQUIRE(k1 != -1); + ATF_REQUIRE(k2 != -1); + ATF_REQUIRE(k3 != -1); + + if (k1 != k2) + atf_tc_fail("ftok(3) gave different key for a hard link"); + + if (k1 != k3) + atf_tc_fail("ftok(3) gave different key for a symbolic link"); + + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(hlnk) == 0); + ATF_REQUIRE(unlink(slnk) == 0); +} + +ATF_TC_CLEANUP(ftok_link, tc) +{ + (void)unlink(path); + (void)unlink(hlnk); + (void)unlink(slnk); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ftok_err); + ATF_TP_ADD_TC(tp, ftok_link); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c new file mode 100644 index 0000000..1f39984 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c @@ -0,0 +1,153 @@ +/* $NetBSD: t_getcwd.c,v 1.3 2011/07/27 05:04:11 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_getcwd.c,v 1.3 2011/07/27 05:04:11 jruoho Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +ATF_TC(getcwd_err); +ATF_TC_HEAD(getcwd_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions in getcwd(3)"); +} + +ATF_TC_BODY(getcwd_err, tc) +{ + char buf[MAXPATHLEN]; + + errno = 0; + + ATF_REQUIRE(getcwd(buf, 0) == NULL); + ATF_REQUIRE(errno == EINVAL); + +#ifdef __NetBSD__ + errno = 0; + + ATF_REQUIRE(getcwd((void *)-1, sizeof(buf)) == NULL); + ATF_REQUIRE(errno == EFAULT); +#endif +} + +ATF_TC(getcwd_fts); +ATF_TC_HEAD(getcwd_fts, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of getcwd(3)"); +} + +ATF_TC_BODY(getcwd_fts, tc) +{ + const char *str = NULL; + char buf[MAXPATHLEN]; + char *argv[2]; + FTSENT *ftse; + FTS *fts; + int ops; + short depth; + + /* + * Do not traverse too deep; cf. PR bin/45180. + */ + depth = 2; + + argv[1] = NULL; + argv[0] = __UNCONST("/"); + + /* + * Test that getcwd(3) works with basic + * system directories. Note that having + * no FTS_NOCHDIR specified should ensure + * that the current directory is visited. + */ + ops = FTS_PHYSICAL | FTS_NOSTAT; + fts = fts_open(argv, ops, NULL); + + if (fts == NULL) { + str = "failed to initialize fts(3)"; + goto out; + } + + while ((ftse = fts_read(fts)) != NULL) { + + if (ftse->fts_level < 1) + continue; + + if (ftse->fts_level > depth) { + (void)fts_set(fts, ftse, FTS_SKIP); + continue; + } + + switch(ftse->fts_info) { + + case FTS_DP: + + (void)memset(buf, 0, sizeof(buf)); + + if (getcwd(buf, sizeof(buf)) == NULL) { + str = "getcwd(3) failed"; + goto out; + } + + if (strstr(ftse->fts_path, buf) == NULL) { + str = "getcwd(3) returned incorrect path"; + goto out; + } + + break; + + default: + break; + } + } + +out: + if (fts != NULL) + (void)fts_close(fts); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getcwd_err); + ATF_TP_ADD_TC(tp, getcwd_fts); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c b/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c new file mode 100644 index 0000000..df9cdd1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c @@ -0,0 +1,181 @@ +/* $NetBSD: t_getgrent.c,v 1.2 2011/05/11 19:06:45 njoly Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Copyright (c) 2009, Stathis Kamperis + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_getgrent.c,v 1.2 2011/05/11 19:06:45 njoly Exp $"); + +#include + +#include +#include +#include +#include + +ATF_TC(getgrent_loop); +ATF_TC_HEAD(getgrent_loop, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sequential getgrent(2)"); +} + +ATF_TC_BODY(getgrent_loop, tc) +{ + struct group *gr; + size_t i, j; + + /* + * Loop over the group database. The first + * call returns the first entry and subsequent + * calls return the rest of the entries. + */ + i = j = 0; + + while((gr = getgrent()) != NULL) + i++; + + /* + * Rewind the database to the beginning + * and loop over again until the end. + */ + setgrent(); + + while((gr = getgrent()) != NULL) + j++; + + if (i != j) + atf_tc_fail("sequential getgrent(3) failed"); + + /* + * Close the database and reopen it. + * The getgrent(3) call should always + * automatically rewind the database. + */ + endgrent(); + + j = 0; + + while((gr = getgrent()) != NULL) + j++; + + if (i != j) + atf_tc_fail("getgrent(3) did not rewind"); +} + +ATF_TC(getgrent_setgid); +ATF_TC_HEAD(getgrent_setgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test consistency of the group db"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(getgrent_setgid, tc) +{ + struct group *gr, *gr1, *gr2; + int rv, sta; + pid_t pid; + + /* + * Verify that the database is consistent. + * + * Note that because of the static buffers + * used by getgrent(3), fork(2) is required, + * even without the setgid(2) check. + */ + while((gr = getgrent()) != NULL) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + gr1 = getgrgid(gr->gr_gid); + + if (gr1 == NULL) + _exit(EXIT_FAILURE); + + gr2 = getgrnam(gr->gr_name); + + if (gr2 == NULL) + _exit(EXIT_FAILURE); + + rv = setgid(gr->gr_gid); + + if (rv != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + goto fail; + } + + return; + +fail: + atf_tc_fail("group database is inconsistent"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getgrent_loop); + ATF_TP_ADD_TC(tp, getgrent_setgid); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_glob.c b/contrib/netbsd-tests/lib/libc/gen/t_glob.c new file mode 100644 index 0000000..c53e183 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_glob.c @@ -0,0 +1,283 @@ +/* $NetBSD: t_glob.c,v 1.5 2017/01/14 20:47:41 christos Exp $ */ +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_glob.c,v 1.5 2017/01/14 20:47:41 christos Exp $"); + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "h_macros.h" + + +#ifdef DEBUG +#define DPRINTF(a) printf a +#else +#define DPRINTF(a) +#endif + +struct gl_file { + const char *name; + int dir; +}; + +static struct gl_file a[] = { + { "1", 0 }, + { "b", 1 }, + { "3", 0 }, + { "4", 0 }, +}; + +static struct gl_file b[] = { + { "x", 0 }, + { "y", 0 }, + { "z", 0 }, + { "w", 0 }, +}; + +struct gl_dir { + const char *name; /* directory name */ + const struct gl_file *dir; + size_t len, pos; +}; + +static struct gl_dir d[] = { + { "a", a, __arraycount(a), 0 }, + { "a/b", b, __arraycount(b), 0 }, +}; + +#ifdef GLOB_STAR +static const char *glob_star[] = { + "a/1", "a/3", "a/4", "a/b", "a/b/w", "a/b/x", "a/b/y", "a/b/z", +}; +#endif + +static const char *glob_star_not[] = { + "a/1", "a/3", "a/4", "a/b", +}; + +static void +trim(char *buf, size_t len, const char *name) +{ + char *path = buf, *epath = buf + len; + while (path < epath && (*path++ = *name++) != '\0') + continue; + path--; + while (path > buf && *--path == '/') + *path = '\0'; +} + +static void * +gl_opendir(const char *dir) +{ + size_t i; + char buf[MAXPATHLEN]; + trim(buf, sizeof(buf), dir); + + for (i = 0; i < __arraycount(d); i++) + if (strcmp(buf, d[i].name) == 0) { + DPRINTF(("opendir %s %zu\n", buf, i)); + return &d[i]; + } + errno = ENOENT; + return NULL; +} + +static struct dirent * +gl_readdir(void *v) +{ + static struct dirent dir; + struct gl_dir *dd = v; + if (dd->pos < dd->len) { + const struct gl_file *f = &dd->dir[dd->pos++]; + strcpy(dir.d_name, f->name); + dir.d_namlen = strlen(f->name); + dir.d_ino = dd->pos; + dir.d_type = f->dir ? DT_DIR : DT_REG; + DPRINTF(("readdir %s %d\n", dir.d_name, dir.d_type)); +#ifdef __FreeBSD__ + dir.d_reclen = -1; /* Does not have _DIRENT_RECLEN */ +#else + dir.d_reclen = _DIRENT_RECLEN(&dir, dir.d_namlen); +#endif + return &dir; + } + return NULL; +} + +static int +gl_stat(const char *name , __gl_stat_t *st) +{ + char buf[MAXPATHLEN]; + trim(buf, sizeof(buf), name); + memset(st, 0, sizeof(*st)); + + if (strcmp(buf, "a") == 0 || strcmp(buf, "a/b") == 0) { + st->st_mode |= S_IFDIR; + return 0; + } + + if (buf[0] == 'a' && buf[1] == '/') { + struct gl_file *f; + size_t offs, count; + + if (buf[2] == 'b' && buf[3] == '/') { + offs = 4; + count = __arraycount(b); + f = b; + } else { + offs = 2; + count = __arraycount(a); + f = a; + } + + for (size_t i = 0; i < count; i++) + if (strcmp(f[i].name, buf + offs) == 0) + return 0; + } + DPRINTF(("stat %s %d\n", buf, st->st_mode)); + errno = ENOENT; + return -1; +} + +static int +gl_lstat(const char *name , __gl_stat_t *st) +{ + return gl_stat(name, st); +} + +static void +gl_closedir(void *v) +{ + struct gl_dir *dd = v; + dd->pos = 0; + DPRINTF(("closedir %p\n", dd)); +} + +static void +run(const char *p, int flags, const char **res, size_t len) +{ + glob_t gl; + size_t i; + + memset(&gl, 0, sizeof(gl)); + gl.gl_opendir = gl_opendir; + gl.gl_readdir = gl_readdir; + gl.gl_closedir = gl_closedir; + gl.gl_stat = gl_stat; + gl.gl_lstat = gl_lstat; + + RZ(glob(p, GLOB_ALTDIRFUNC | flags, NULL, &gl)); + + for (i = 0; i < gl.gl_pathc; i++) + DPRINTF(("%s\n", gl.gl_pathv[i])); + + ATF_CHECK(len == gl.gl_pathc); + for (i = 0; i < gl.gl_pathc; i++) + ATF_CHECK_STREQ(gl.gl_pathv[i], res[i]); + + globfree(&gl); +} + + +#ifdef GLOB_STAR +ATF_TC(glob_star); +ATF_TC_HEAD(glob_star, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test glob(3) ** with GLOB_STAR"); +} + +ATF_TC_BODY(glob_star, tc) +{ + run("a/**", GLOB_STAR, glob_star, __arraycount(glob_star)); +} +#endif + +ATF_TC(glob_star_not); +ATF_TC_HEAD(glob_star_not, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test glob(3) ** without GLOB_STAR"); +} + + +ATF_TC_BODY(glob_star_not, tc) +{ + run("a/**", 0, glob_star_not, __arraycount(glob_star_not)); +} + +#if 0 +ATF_TC(glob_nocheck); +ATF_TC_HEAD(glob_nocheck, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test glob(3) pattern with backslash and GLOB_NOCHECK"); +} + + +ATF_TC_BODY(glob_nocheck, tc) +{ + static const char pattern[] = { 'f', 'o', 'o', '\\', ';', 'b', 'a', + 'r', '\0' }; + static const char *glob_nocheck[] = { + pattern + }; + run(pattern, GLOB_NOCHECK, glob_nocheck, __arraycount(glob_nocheck)); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ +#ifdef GLOB_STAR + ATF_TP_ADD_TC(tp, glob_star); +#endif + ATF_TP_ADD_TC(tp, glob_star_not); +/* + * Remove this test for now - the GLOB_NOCHECK return value has been + * re-defined to return a modified pattern in revision 1.33 of glob.c + * + * ATF_TP_ADD_TC(tp, glob_nocheck); + */ + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c new file mode 100644 index 0000000..54d798f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c @@ -0,0 +1,315 @@ +/* $NetBSD: t_humanize_number.c,v 1.9 2017/01/10 15:20:44 christos Exp $ */ + +/*- + * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include +#include +#include +#include +#include + +const struct hnopts { + size_t ho_len; + int64_t ho_num; + const char *ho_suffix; + int ho_scale; + int ho_flags; + int ho_retval; /* expected return value */ + const char *ho_retstr; /* expected string in buffer */ +} hnopts[] = { + /* + * Rev. 1.6 produces "10.0". + */ + { 5, 10737418236ULL * 1024, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10T" }, + + { 5, 10450000, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10M" }, + { 5, 10500000, "", /* just for reference */ + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10M" }, + + /* + * Trailing space. Rev. 1.7 produces "1 ". + */ + { 5, 1, "", 0, HN_NOSPACE, 1, "1" }, + + { 5, 1, "", 0, 0, 2, "1 " }, /* just for reference */ + { 5, 1, "", 0, HN_B, 3, "1 B" }, /* and more ... */ + { 5, 1, "", 0, HN_DECIMAL, 2, "1 " }, + { 5, 1, "", 0, HN_NOSPACE | HN_B, 2, "1B" }, + { 5, 1, "", 0, HN_B | HN_DECIMAL, 3, "1 B" }, + { 5, 1, "", 0, HN_NOSPACE | HN_B | HN_DECIMAL, 2, "1B" }, + + /* + * Space and HN_B. Rev. 1.7 produces "1B". + */ + { 5, 1, "", HN_AUTOSCALE, HN_B, 3, "1 B" }, + { 5, 1000, "", /* just for reference */ + HN_AUTOSCALE, HN_B, 3, "1 K" }, + + /* + * Truncated output. Rev. 1.7 produces "1.0 K". + */ +#ifndef __FreeBSD__ + { 6, 1000, "A", HN_AUTOSCALE, HN_DECIMAL, -1, "" }, + + /* + * Failure case reported by Greg Troxel . + * Rev. 1.11 incorrectly returns 5 with filling the buffer + * with "1000". + */ + { 5, 1048258238, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0G" }, + /* Similar case it prints 1000 where it shouldn't */ + { 5, 1023488, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0M" }, +#endif + { 5, 1023999, "", + HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0M" }, +}; + +struct hnflags { + int hf_flags; + const char *hf_name; +}; + +const struct hnflags scale_flags[] = { + { HN_GETSCALE, "HN_GETSCALE" }, + { HN_AUTOSCALE, "HN_AUTOSCALE" }, +}; +const struct hnflags normal_flags[] = { + { HN_DECIMAL, "HN_DECIMAL" }, + { HN_NOSPACE, "HN_NOSPACE" }, + { HN_B, "HN_B" }, + { HN_DIVISOR_1000, "HN_DIVISOR_1000" }, +}; + +const char *formatflags(char *, size_t, const struct hnflags *, size_t, int); +void newline(void); +void w_printf(const char *, ...) __printflike(1, 2); +int main(int, char *[]); + +const char * +formatflags(char *buf, size_t buflen, const struct hnflags *hfs, + size_t hfslen, int flags) +{ + const struct hnflags *hf; + char *p = buf; + ssize_t len = buflen; + unsigned int i, found; + int n; + + if (flags == 0) { + snprintf(buf, buflen, "0"); + return (buf); + } + for (i = found = 0; i < hfslen && flags & ~found; i++) { + hf = &hfs[i]; + if (flags & hf->hf_flags) { + found |= hf->hf_flags; + n = snprintf(p, len, "|%s", hf->hf_name); + if (n >= len) { + p = buf; + len = buflen; + /* Print `flags' as number */ + goto bad; + } + p += n; + len -= n; + } + } + flags &= ~found; + if (flags) +bad: + snprintf(p, len, "|0x%x", flags); + return (*buf == '|' ? buf + 1 : buf); +} + +static int col, bol = 1; +void +newline(void) +{ + + fprintf(stderr, "\n"); + col = 0; + bol = 1; +} + +void +w_printf(const char *fmt, ...) +{ + char buf[80]; + va_list ap; + int n; + + va_start(ap, fmt); + if (col >= 0) { + n = vsnprintf(buf, sizeof(buf), fmt, ap); + if (n >= (int)sizeof(buf)) { + col = -1; + goto overflow; + } else if (n == 0) + goto out; + + if (!bol) { + if (col + n > 75) + fprintf(stderr, "\n "), col = 4; + else + fprintf(stderr, " "), col++; + } + fprintf(stderr, "%s", buf); + col += n; + bol = 0; + } else { +overflow: + vfprintf(stderr, fmt, ap); + } +out: + va_end(ap); +} + +ATF_TC(humanize_number_basic); +ATF_TC_HEAD(humanize_number_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test humanize_number(3)"); +} + +ATF_TC_BODY(humanize_number_basic, tc) +{ + char fbuf[128]; + const struct hnopts *ho; + char *buf = NULL; + size_t buflen = 0; + unsigned int i; + int rv = 0; + + for (i = 0; i < __arraycount(hnopts); i++) { + ho = &hnopts[i]; + if (buflen < ho->ho_len) { + buflen = ho->ho_len; + buf = realloc(buf, buflen); + if (buf == NULL) + atf_tc_fail("realloc(..., %zu) failed", buflen); + } + + rv = humanize_number(buf, ho->ho_len, ho->ho_num, + ho->ho_suffix, ho->ho_scale, ho->ho_flags); + + if (rv == ho->ho_retval && + (rv == -1 || strcmp(buf, ho->ho_retstr) == 0)) + continue; + + w_printf("humanize_number(\"%s\", %zu, %" PRId64 ",", + ho->ho_retstr, ho->ho_len, ho->ho_num); + w_printf("\"%s\",", ho->ho_suffix); + w_printf("%s,", formatflags(fbuf, sizeof(fbuf), scale_flags, + sizeof(scale_flags) / sizeof(scale_flags[0]), + ho->ho_scale)); + w_printf("%s)", formatflags(fbuf, sizeof(fbuf), normal_flags, + sizeof(normal_flags) / sizeof(normal_flags[0]), + ho->ho_flags)); + w_printf("= %d,", ho->ho_retval); + w_printf("but got"); + w_printf("%d/[%s]", rv, rv == -1 ? "" : buf); + newline(); + atf_tc_fail_nonfatal("Failed for table entry %d", i); + } + free(buf); +} + +ATF_TC(humanize_number_big); +ATF_TC_HEAD(humanize_number_big, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test humanize " + "big numbers (PR lib/44097)"); +} + +ATF_TC_BODY(humanize_number_big, tc) +{ + char buf[1024]; + int rv; + + /* + * Seems to work. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, 10, 10000, "", HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); + ATF_CHECK_STREQ(buf, "10000"); + + /* + * A bogus value with large number. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, 10, INT64_MAX, "", HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); + ATF_REQUIRE(strcmp(buf, "0") != 0); + + /* + * Large buffer with HN_AUTOSCALE. Entirely bogus. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, sizeof(buf), 10000, "", + HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); + ATF_REQUIRE(strcmp(buf, "0%d%s%d%s%s%s") != 0); + + /* + * Tight buffer. + * + * The man page says that len must be at least 4. + * 3 works, but anything less that will not. This + * is because baselen starts with 2 for positive + * numbers. + */ + (void)memset(buf, 0, sizeof(buf)); + + rv = humanize_number(buf, 3, 1, "", HN_AUTOSCALE, HN_NOSPACE); + + ATF_REQUIRE(rv != -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, humanize_number_basic); + ATF_TP_ADD_TC(tp, humanize_number_big); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_isnan.c b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c new file mode 100644 index 0000000..2871e31 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c @@ -0,0 +1,66 @@ +/* $NetBSD: t_isnan.c,v 1.5 2014/11/04 00:20:19 justin Exp $ */ + +/* + * This file is in the Public Domain. + * + * The nan test is blatently copied by Simon Burge from the infinity + * test by Ben Harris. + */ + +#include + +#include + +#include +#include + +ATF_TC(isnan_basic); +ATF_TC_HEAD(isnan_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Verify that isnan(3) works"); +} + +ATF_TC_BODY(isnan_basic, tc) +{ +#if defined(__m68k__) + atf_tc_skip("Test not applicable on " MACHINE_ARCH); +#endif + +#ifdef NAN + /* NAN is meant to be a (float)NaN. */ + ATF_CHECK(isnan(NAN) != 0); + ATF_CHECK(isnan((double)NAN) != 0); +#else + atf_tc_skip("Test not applicable"); +#endif +} + +ATF_TC(isinf_basic); +ATF_TC_HEAD(isinf_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Verify that isinf(3) works"); +} + +ATF_TC_BODY(isinf_basic, tc) +{ +#if defined(__m68k__) + atf_tc_skip("Test not applicable on " MACHINE_ARCH); +#endif + + /* HUGE_VAL is meant to be an infinity. */ + ATF_CHECK(isinf(HUGE_VAL) != 0); + + /* HUGE_VALF is the float analog of HUGE_VAL. */ + ATF_CHECK(isinf(HUGE_VALF) != 0); + + /* HUGE_VALL is the long double analog of HUGE_VAL. */ + ATF_CHECK(isinf(HUGE_VALL) != 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, isnan_basic); + ATF_TP_ADD_TC(tp, isinf_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_nice.c b/contrib/netbsd-tests/lib/libc/gen/t_nice.c new file mode 100644 index 0000000..7c6d232 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_nice.c @@ -0,0 +1,216 @@ +/* $NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +static void *threadfunc(void *); + +static void * +threadfunc(void *arg) +{ + int pri, val; + + val = *(int *)arg; + + errno = 0; + pri = getpriority(PRIO_PROCESS, 0); + ATF_REQUIRE(errno == 0); + + if (pri != val) + atf_tc_fail("nice(3) value was not propagated to threads"); + + return NULL; +} + +ATF_TC(nice_err); +ATF_TC_HEAD(nice_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test nice(3) for invalid parameters (PR lib/42587)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(nice_err, tc) +{ + int i; + + /* + * The call should fail with EPERM if the + * supplied parameter is negative and the + * caller does not have privileges. + */ + for (i = -20; i < 0; i++) { + + errno = 0; + + ATF_REQUIRE_ERRNO(EPERM, nice(i) == -1); + } +} + +ATF_TC(nice_priority); +ATF_TC_HEAD(nice_priority, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test nice(3) vs. getpriority(2)"); +} + +ATF_TC_BODY(nice_priority, tc) +{ +#ifdef __FreeBSD__ + int i, pri, pri2, nic; +#else + int i, pri, nic; +#endif + pid_t pid; + int sta; + + for (i = 0; i <= 20; i++) { + + nic = nice(i); + ATF_REQUIRE(nic != -1); + + errno = 0; + pri = getpriority(PRIO_PROCESS, 0); + ATF_REQUIRE(errno == 0); + +#ifdef __NetBSD__ + if (nic != pri) + atf_tc_fail("nice(3) and getpriority(2) conflict"); +#endif + + /* + * Also verify that the nice(3) values + * are inherited by child processes. + */ + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + errno = 0; +#ifdef __FreeBSD__ + pri = getpriority(PRIO_PROCESS, 0); +#else + pri2 = getpriority(PRIO_PROCESS, 0); +#endif + ATF_REQUIRE(errno == 0); + +#ifdef __FreeBSD__ + if (pri != pri2) +#else + if (nic != pri) +#endif + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("nice(3) value was not inherited"); + } +} + +ATF_TC(nice_root); +ATF_TC_HEAD(nice_root, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that nice(3) works"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(nice_root, tc) +{ + int i; + + for (i = -20; i <= 20; i++) { + + ATF_REQUIRE(nice(i) != -1); + } +} + +ATF_TC(nice_thread); +ATF_TC_HEAD(nice_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test nice(3) with threads"); +} + +ATF_TC_BODY(nice_thread, tc) +{ + pthread_t tid[5]; +#ifdef __FreeBSD__ + int pri, rv, val; +#else + int rv, val; +#endif + size_t i; + + /* + * Test that the scheduling priority is + * propagated to all system scope threads. + */ + for (i = 0; i < __arraycount(tid); i++) { + + val = nice(i); + ATF_REQUIRE(val != -1); + +#ifdef __FreeBSD__ + pri = getpriority(PRIO_PROCESS, 0); + rv = pthread_create(&tid[i], NULL, threadfunc, &pri); +#else + rv = pthread_create(&tid[i], NULL, threadfunc, &val); +#endif + ATF_REQUIRE(rv == 0); + + rv = pthread_join(tid[i], NULL); + ATF_REQUIRE(rv == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, nice_err); + ATF_TP_ADD_TC(tp, nice_priority); + ATF_TP_ADD_TC(tp, nice_root); + ATF_TP_ADD_TC(tp, nice_thread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_pause.c b/contrib/netbsd-tests/lib/libc/gen/t_pause.c new file mode 100644 index 0000000..62a74c9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_pause.c @@ -0,0 +1,114 @@ +/* $NetBSD: t_pause.c,v 1.1 2011/05/10 13:03:06 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_pause.c,v 1.1 2011/05/10 13:03:06 jruoho Exp $"); + +#include + +#include +#include +#include +#include + +static bool fail; +static void handler(int); + +static void +handler(int signo) +{ + + if (signo == SIGALRM) + fail = false; +} + +ATF_TC(pause_basic); +ATF_TC_HEAD(pause_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of pause(3), #1"); +} + +ATF_TC_BODY(pause_basic, tc) +{ + + fail = true; + + ATF_REQUIRE(signal(SIGALRM, handler) == 0); + + (void)alarm(1); + + if (pause() != -1 || fail != false) + atf_tc_fail("pause(3) did not cancel out from a signal"); +} + +ATF_TC(pause_kill); +ATF_TC_HEAD(pause_kill, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of pause(3), #2"); +} + +ATF_TC_BODY(pause_kill, tc) +{ + pid_t pid; + int sta; + + fail = true; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)pause(); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + + if (fail != true) + atf_tc_fail("child terminated before signal"); + + (void)kill(pid, SIGKILL); + (void)sleep(1); + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("pause(3) did not cancel from SIGKILL"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pause_basic); + ATF_TP_ADD_TC(tp, pause_kill); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_raise.c b/contrib/netbsd-tests/lib/libc/gen/t_raise.c new file mode 100644 index 0000000..91a8c37 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_raise.c @@ -0,0 +1,194 @@ +/* $NetBSD: t_raise.c,v 1.6 2016/11/03 22:08:31 kamil Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_raise.c,v 1.6 2016/11/03 22:08:31 kamil Exp $"); + +#include + +#include +#include +#include +#include + +static bool fail; +static int count; +static void handler_err(int); +static void handler_ret(int); +static void handler_stress(int); +#ifdef __FreeBSD__ +static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2 }; +#else +static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2, SIGPWR }; +#endif + +static void +handler_stress(int signo) +{ + count++; +} + +static void +handler_err(int signo) +{ + size_t i; + + for (i = 0; i < __arraycount(sig); i++) { + + if (sig[i] == signo) { + fail = false; + break; + } + } +} + +static void +handler_ret(int signo) +{ + + (void)sleep(1); + + fail = false; +} + +ATF_TC(raise_err); +ATF_TC_HEAD(raise_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test raise(3) for invalid parameters"); +} + +ATF_TC_BODY(raise_err, tc) +{ + int i = 0; + + while (i < 10) { + + ATF_REQUIRE(raise(10240 + i) == -1); + + i++; + } +} + +ATF_TC(raise_ret); +ATF_TC_HEAD(raise_ret, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test return order of raise(3)"); +} + +ATF_TC_BODY(raise_ret, tc) +{ + struct sigaction sa; + + fail = true; + + sa.sa_flags = 0; + sa.sa_handler = handler_ret; + + /* + * Verify that raise(3) does not return + * before the signal handler returns. + */ + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(SIGUSR1, &sa, 0) == 0); + ATF_REQUIRE(raise(SIGUSR1) == 0); + + if (fail != false) + atf_tc_fail("raise(3) returned before signal handler"); +} + +ATF_TC(raise_sig); +ATF_TC_HEAD(raise_sig, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of raise(3)"); +} + +ATF_TC_BODY(raise_sig, tc) +{ + struct timespec tv, tr; + struct sigaction sa; + size_t i; + + for (i = 0; i < __arraycount(sig); i++) { + + (void)memset(&sa, 0, sizeof(struct sigaction)); + + fail = true; + + tv.tv_sec = 0; + tv.tv_nsec = 2; + + sa.sa_flags = 0; + sa.sa_handler = handler_err; + + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(sig[i], &sa, 0) == 0); + + ATF_REQUIRE(raise(sig[i]) == 0); + ATF_REQUIRE(nanosleep(&tv, &tr) == 0); + + if (fail != false) + atf_tc_fail("raise(3) did not raise a signal"); + } +} + +ATF_TC(raise_stress); +ATF_TC_HEAD(raise_stress, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic stress test with raise(3)"); +} + +ATF_TC_BODY(raise_stress, tc) +{ + static const int maxiter = 1000 * 10; + struct sigaction sa; + int i; + + sa.sa_flags = 0; + sa.sa_handler = handler_stress; + + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(SIGUSR1, &sa, 0) == 0); + + for (count = i = 0; i < maxiter; i++) + (void)raise(SIGUSR1); + + if (count != maxiter) + atf_tc_fail("not all signals were caught"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, raise_err); + ATF_TP_ADD_TC(tp, raise_ret); + ATF_TP_ADD_TC(tp, raise_sig); + ATF_TP_ADD_TC(tp, raise_stress); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_randomid.c b/contrib/netbsd-tests/lib/libc/gen/t_randomid.c new file mode 100644 index 0000000..9ab2cca --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_randomid.c @@ -0,0 +1,93 @@ +/* $NetBSD: t_randomid.c,v 1.5 2015/03/07 09:59:15 isaki Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include + +#include +#include +#include +#include +#include + +#define PERIOD 30000 + +uint32_t last[65536]; + +ATF_TC(randomid_basic); +ATF_TC_HEAD(randomid_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check randomid(3)"); +} + +ATF_TC_BODY(randomid_basic, tc) +{ + static randomid_t ctx = NULL; + uint32_t lowest, n, diff; + uint16_t id; + + memset(last, 0, sizeof(last)); + ctx = randomid_new(16, (long)3600); + + lowest = UINT32_MAX; + + for (n = 0; n < 100000; n++) { + id = randomid(ctx); + + if (last[id] > 0) { + diff = n - last[id]; + + if (diff <= lowest) { + if (lowest != UINT32_MAX) + printf("id %5d: last call at %9"PRIu32 + ", current call %9"PRIu32 + " (diff %5"PRIu32"), " + "lowest %"PRIu32"\n", + id, last[id], n, diff, lowest); + + ATF_REQUIRE_MSG(diff >= PERIOD, + "diff (%"PRIu32") less than minimum " + "period (%d)", diff, PERIOD); + + lowest = diff; + } + } + + last[id] = n; + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, randomid_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_realpath.c b/contrib/netbsd-tests/lib/libc/gen/t_realpath.c new file mode 100644 index 0000000..dfb360f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_realpath.c @@ -0,0 +1,162 @@ +/* $NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $"); + +#include + +#include +#ifdef __FreeBSD__ +#include +#endif +#include +#include +#include +#include +#include + +static const struct { + const char *path; + const char *result; +} paths[] = { + + { "/", "/" }, + { "///////", "/" }, + { "", NULL }, + { " ", NULL }, + { "/ ", NULL }, + { " /", NULL }, + { "/etc///", "/etc" }, + { "///////etc", "/etc" }, + { "/a/b/c/d/e", NULL }, + { " /usr/bin ", NULL }, + { "\\//////usr//bin", NULL }, + { "//usr//bin//", "/usr/bin" }, + { "//////usr//bin//", "/usr/bin" }, + { "/usr/bin//////////", "/usr/bin" }, +}; + +ATF_TC(realpath_basic); +ATF_TC_HEAD(realpath_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of realpath(3)"); +} + +ATF_TC_BODY(realpath_basic, tc) +{ + char buf[MAXPATHLEN]; + char *ptr; + size_t i; + + for (i = 0; i < __arraycount(paths); i++) { + + (void)memset(buf, '\0', sizeof(buf)); + + ptr = realpath(paths[i].path, buf); + + if (ptr == NULL && paths[i].result == NULL) + continue; + + if (ptr == NULL && paths[i].result != NULL) + atf_tc_fail("realpath failed for '%s'", paths[i].path); + + if (strcmp(paths[i].result, buf) != 0) + atf_tc_fail("expected '%s', got '%s'", + paths[i].result, buf); + } +} + +ATF_TC(realpath_huge); +ATF_TC_HEAD(realpath_huge, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test huge path with realpath(3)"); +} + +ATF_TC_BODY(realpath_huge, tc) +{ + char result[MAXPATHLEN] = { 0 }; + char buffer[MAXPATHLEN] = { 0 }; + + (void)memset(buffer, '/', sizeof(buffer) - 1); + + ATF_CHECK(realpath(buffer, result) != NULL); + ATF_CHECK(strlen(result) == 1); + ATF_CHECK(result[0] == '/'); +} + +ATF_TC(realpath_symlink); +ATF_TC_HEAD(realpath_symlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test symbolic link with realpath(3)"); +} + +ATF_TC_BODY(realpath_symlink, tc) +{ + char path[MAXPATHLEN] = { 0 }; + char slnk[MAXPATHLEN] = { 0 }; + char resb[MAXPATHLEN] = { 0 }; + int fd; + +#ifdef __FreeBSD__ + ATF_REQUIRE_MSG(getcwd(path, sizeof(path)) != NULL, + "getcwd(path) failed: %s", strerror(errno)); + ATF_REQUIRE_MSG(getcwd(slnk, sizeof(slnk)) != NULL, + "getcwd(slnk) failed: %s", strerror(errno)); +#else + (void)getcwd(path, sizeof(path)); + (void)getcwd(slnk, sizeof(slnk)); +#endif + + (void)strlcat(path, "/realpath", sizeof(path)); + (void)strlcat(slnk, "/symbolic", sizeof(slnk)); + + fd = open(path, O_RDONLY | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(symlink(path, slnk) == 0); + ATF_REQUIRE(close(fd) == 0); + + ATF_REQUIRE(realpath(slnk, resb) != NULL); + ATF_REQUIRE(strcmp(resb, path) == 0); + + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(slnk) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, realpath_basic); + ATF_TP_ADD_TC(tp, realpath_huge); + ATF_TP_ADD_TC(tp, realpath_symlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c new file mode 100644 index 0000000..02dd176 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c @@ -0,0 +1,148 @@ +/* $NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $"); + +#include + +#include +#include +#include +#include + +static char domain[MAXHOSTNAMELEN]; + +static const char domains[][MAXHOSTNAMELEN] = { + "1234567890", + "abcdefghijklmnopqrst", + "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8", + "--------------------------------------------------------------------" +}; + +ATF_TC_WITH_CLEANUP(setdomainname_basic); +ATF_TC_HEAD(setdomainname_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of setdomainname(3)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setdomainname_basic, tc) +{ + char name[MAXHOSTNAMELEN]; + size_t i; + + for (i = 0; i < __arraycount(domains); i++) { + + (void)memset(name, 0, sizeof(name)); + +#ifdef __FreeBSD__ + /* + * Sanity checks to ensure that the wrong invariant isn't being + * tested for per PR # 181127 + */ + ATF_REQUIRE_EQ(sizeof(domains[i]), MAXHOSTNAMELEN); + ATF_REQUIRE_EQ(sizeof(name), MAXHOSTNAMELEN); + + ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i]) - 1) == 0); + ATF_REQUIRE(getdomainname(name, sizeof(name) - 1) == 0); +#else + ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i])) == 0); + ATF_REQUIRE(getdomainname(name, sizeof(name)) == 0); +#endif + ATF_REQUIRE(strcmp(domains[i], name) == 0); + } + + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TC_CLEANUP(setdomainname_basic, tc) +{ + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TC_WITH_CLEANUP(setdomainname_limit); +ATF_TC_HEAD(setdomainname_limit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Too long domain name errors out?"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setdomainname_limit, tc) +{ + char name[MAXHOSTNAMELEN + 1]; + + (void)memset(name, 0, sizeof(name)); + +#ifdef __FreeBSD__ + ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN - 1 ) == 0); + ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN) == -1); +#endif + ATF_REQUIRE(setdomainname(name, sizeof(name)) == -1); +} + +ATF_TC_CLEANUP(setdomainname_limit, tc) +{ + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TC_WITH_CLEANUP(setdomainname_perm); +ATF_TC_HEAD(setdomainname_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Can normal user set the domain name?"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setdomainname_perm, tc) +{ + + errno = 0; + + ATF_REQUIRE_ERRNO(EPERM, setdomainname(domain, sizeof(domain)) == -1); +} + +ATF_TC_CLEANUP(setdomainname_perm, tc) +{ + (void)setdomainname(domain, sizeof(domain)); +} + +ATF_TP_ADD_TCS(tp) +{ + + (void)memset(domain, 0, sizeof(domain)); + + ATF_REQUIRE(getdomainname(domain, sizeof(domain)) == 0); + + ATF_TP_ADD_TC(tp, setdomainname_basic); + ATF_TP_ADD_TC(tp, setdomainname_limit); + ATF_TP_ADD_TC(tp, setdomainname_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c new file mode 100644 index 0000000..136fa7c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c @@ -0,0 +1,150 @@ +/* $NetBSD: t_sethostname.c,v 1.3 2012/03/25 08:17:54 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_sethostname.c,v 1.3 2012/03/25 08:17:54 joerg Exp $"); + +#include + +#include +#include +#include +#include + +static char host[MAXHOSTNAMELEN]; + +static const char hosts[][MAXHOSTNAMELEN] = { + "1234567890", + "abcdefghijklmnopqrst", + "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8", + "--------------------------------------------------------------------" +}; + +ATF_TC_WITH_CLEANUP(sethostname_basic); +ATF_TC_HEAD(sethostname_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of sethostname(3)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sethostname_basic, tc) +{ + char name[MAXHOSTNAMELEN]; + size_t i; + + atf_tc_skip("screws up the test host's hostname on FreeBSD"); + + for (i = 0; i < __arraycount(hosts); i++) { + + (void)memset(name, 0, sizeof(name)); + +#ifdef __FreeBSD__ + /* + * Sanity checks to ensure that the wrong invariant isn't being + * tested for per PR # 181127 + */ + ATF_REQUIRE_EQ(sizeof(hosts[i]), MAXHOSTNAMELEN); + ATF_REQUIRE_EQ(sizeof(name), MAXHOSTNAMELEN); + + ATF_REQUIRE(sethostname(hosts[i], sizeof(hosts[i]) - 1) == 0); + ATF_REQUIRE(gethostname(name, sizeof(name) - 1) == 0); +#else + ATF_REQUIRE(sethostname(hosts[i], sizeof(hosts[i])) == 0); + ATF_REQUIRE(gethostname(name, sizeof(name)) == 0); +#endif + ATF_REQUIRE(strcmp(hosts[i], name) == 0); + } + + (void)sethostname(host, sizeof(host)); +} + +ATF_TC_CLEANUP(sethostname_basic, tc) +{ + (void)sethostname(host, sizeof(host)); +} + +ATF_TC_WITH_CLEANUP(sethostname_limit); +ATF_TC_HEAD(sethostname_limit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Too long host name errors out?"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sethostname_limit, tc) +{ + char name[MAXHOSTNAMELEN + 1]; + + (void)memset(name, 0, sizeof(name)); + + ATF_REQUIRE(sethostname(name, sizeof(name)) == -1); +} + +ATF_TC_CLEANUP(sethostname_limit, tc) +{ +#ifdef __FreeBSD__ + ATF_REQUIRE(sethostname(host, MAXHOSTNAMELEN - 1 ) == 0); + ATF_REQUIRE(sethostname(host, MAXHOSTNAMELEN) == -1); +#endif + (void)sethostname(host, sizeof(host)); +} + +ATF_TC_WITH_CLEANUP(sethostname_perm); +ATF_TC_HEAD(sethostname_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Can normal user set the host name?"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(sethostname_perm, tc) +{ + + errno = 0; + + ATF_REQUIRE_ERRNO(EPERM, sethostname(host, sizeof(host)) == -1); +} + +ATF_TC_CLEANUP(sethostname_perm, tc) +{ + (void)sethostname(host, sizeof(host)); +} + +ATF_TP_ADD_TCS(tp) +{ + + (void)memset(host, 0, sizeof(host)); + + ATF_REQUIRE(gethostname(host, sizeof(host)) == 0); + + ATF_TP_ADD_TC(tp, sethostname_basic); + ATF_TP_ADD_TC(tp, sethostname_limit); + ATF_TP_ADD_TC(tp, sethostname_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c new file mode 100644 index 0000000..64f72ac --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c @@ -0,0 +1,518 @@ +/* $NetBSD: t_siginfo.c,v 1.30 2015/12/22 14:25:58 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#ifdef __NetBSD__ +#include +#endif +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef __HAVE_FENV +#include /* only need for ARM Cortex/Neon hack */ +#elif defined(_FLOAT_IEEE754) +#include +#endif + +#include "isqemu.h" + +/* for sigbus */ +volatile char *addr; + +/* for sigchild */ +pid_t child; +int code; +int status; + +/* for sigfpe */ +sig_atomic_t fltdiv_signalled = 0; +sig_atomic_t intdiv_signalled = 0; + +static void +sig_debug(int signo, siginfo_t *info, ucontext_t *ctx) +{ + unsigned int i; + + printf("%d %p %p\n", signo, info, ctx); + if (info != NULL) { + printf("si_signo=%d\n", info->si_signo); + printf("si_errno=%d\n", info->si_errno); + printf("si_code=%d\n", info->si_code); + printf("si_value.sival_int=%d\n", info->si_value.sival_int); + } + if (ctx != NULL) { + printf("uc_flags 0x%x\n", ctx->uc_flags); + printf("uc_link %p\n", ctx->uc_link); + for (i = 0; i < __arraycount(ctx->uc_sigmask.__bits); i++) + printf("uc_sigmask[%d] 0x%x\n", i, + ctx->uc_sigmask.__bits[i]); + printf("uc_stack %p %lu 0x%x\n", ctx->uc_stack.ss_sp, + (unsigned long)ctx->uc_stack.ss_size, + ctx->uc_stack.ss_flags); +#ifdef __NetBSD__ + for (i = 0; i < __arraycount(ctx->uc_mcontext.__gregs); i++) + printf("uc_mcontext.greg[%d] 0x%lx\n", i, + (long)ctx->uc_mcontext.__gregs[i]); +#endif + } +} + +static void +sigalrm_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + ATF_REQUIRE_EQ(info->si_signo, SIGALRM); + ATF_REQUIRE_EQ(info->si_code, SI_TIMER); + ATF_REQUIRE_EQ(info->si_value.sival_int, ITIMER_REAL); + + atf_tc_pass(); + /* NOTREACHED */ +} + +ATF_TC(sigalarm); + +ATF_TC_HEAD(sigalarm, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGALRM handler"); +} + +ATF_TC_BODY(sigalarm, tc) +{ + struct sigaction sa; + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigalrm_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGALRM, &sa, NULL); + for (;;) { + alarm(1); + sleep(1); + } + atf_tc_fail("SIGALRM handler wasn't called"); +} + +static void +sigchild_action(int signo, siginfo_t *info, void *ptr) +{ + if (info != NULL) { + printf("info=%p\n", info); + printf("ptr=%p\n", ptr); + printf("si_signo=%d\n", info->si_signo); + printf("si_errno=%d\n", info->si_errno); + printf("si_code=%d\n", info->si_code); + printf("si_uid=%d\n", info->si_uid); + printf("si_pid=%d\n", info->si_pid); + printf("si_status=%d\n", info->si_status); +#ifdef __NetBSD__ + printf("si_utime=%lu\n", (unsigned long int)info->si_utime); + printf("si_stime=%lu\n", (unsigned long int)info->si_stime); +#endif + } + ATF_REQUIRE_EQ(info->si_code, code); + ATF_REQUIRE_EQ(info->si_signo, SIGCHLD); + ATF_REQUIRE_EQ(info->si_uid, getuid()); + ATF_REQUIRE_EQ(info->si_pid, child); + if (WIFEXITED(info->si_status)) + ATF_REQUIRE_EQ(WEXITSTATUS(info->si_status), status); + else if (WIFSTOPPED(info->si_status)) + ATF_REQUIRE_EQ(WSTOPSIG(info->si_status), status); + else if (WIFSIGNALED(info->si_status)) + ATF_REQUIRE_EQ(WTERMSIG(info->si_status), status); +} + +static void +setchildhandler(void (*action)(int, siginfo_t *, void *)) +{ + struct sigaction sa; + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = action; + sigemptyset(&sa.sa_mask); + sigaction(SIGCHLD, &sa, NULL); +} + +static void +sigchild_setup(void) +{ + sigset_t set; + struct rlimit rlim; + + (void)getrlimit(RLIMIT_CORE, &rlim); + rlim.rlim_cur = rlim.rlim_max; + (void)setrlimit(RLIMIT_CORE, &rlim); + + setchildhandler(sigchild_action); + sigemptyset(&set); + sigaddset(&set, SIGCHLD); + sigprocmask(SIG_BLOCK, &set, NULL); +} + +ATF_TC(sigchild_normal); +ATF_TC_HEAD(sigchild_normal, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGCHLD handler " + "when child exits normally"); +} + +ATF_TC_BODY(sigchild_normal, tc) +{ + sigset_t set; + + sigchild_setup(); + + status = 25; + code = CLD_EXITED; + + switch ((child = fork())) { + case 0: + sleep(1); + exit(status); + case -1: + atf_tc_fail("fork failed"); + default: + sigemptyset(&set); + sigsuspend(&set); + } +} + +ATF_TC(sigchild_dump); +ATF_TC_HEAD(sigchild_dump, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGCHLD handler " + "when child segfaults"); +} + +ATF_TC_BODY(sigchild_dump, tc) +{ + sigset_t set; + + sigchild_setup(); + + status = SIGSEGV; + code = CLD_DUMPED; + + switch ((child = fork())) { + case 0: + sleep(1); + *(volatile long *)0 = 0; + atf_tc_fail("Child did not segfault"); + /* NOTREACHED */ + case -1: + atf_tc_fail("fork failed"); + default: + sigemptyset(&set); + sigsuspend(&set); + } +} + +ATF_TC(sigchild_kill); +ATF_TC_HEAD(sigchild_kill, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGCHLD handler " + "when child is killed"); +} + +ATF_TC_BODY(sigchild_kill, tc) +{ + sigset_t set; + + sigchild_setup(); + + status = SIGPIPE; + code = CLD_KILLED; + + switch ((child = fork())) { + case 0: + sigemptyset(&set); + sigsuspend(&set); + break; + case -1: + atf_tc_fail("fork failed"); + default: + kill(child, SIGPIPE); + sigemptyset(&set); + sigsuspend(&set); + } +} + +static sigjmp_buf sigfpe_flt_env; +static void +sigfpe_flt_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + if (fltdiv_signalled++ != 0) + atf_tc_fail("FPE handler called more than once"); + + ATF_REQUIRE_EQ(info->si_signo, SIGFPE); + ATF_REQUIRE_EQ(info->si_code, FPE_FLTDIV); + ATF_REQUIRE_EQ(info->si_errno, 0); + + siglongjmp(sigfpe_flt_env, 1); +} + +ATF_TC(sigfpe_flt); +ATF_TC_HEAD(sigfpe_flt, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGFPE handler " + "for floating div-by-zero"); +} + +ATF_TC_BODY(sigfpe_flt, tc) +{ + struct sigaction sa; + double d = strtod("0", NULL); + + if (isQEMU()) + atf_tc_skip("Test does not run correctly under QEMU"); +#if defined(__powerpc__) + atf_tc_skip("Test not valid on powerpc"); +#elif defined(__arm__) && !__SOFTFP__ + /* + * Some NEON fpus do not implement IEEE exception handling, + * skip these tests if running on them and compiled for + * hard float. + */ + if (0 == fpsetmask(fpsetmask(FP_X_INV))) + atf_tc_skip("FPU does not implement exception handling"); +#endif + if (sigsetjmp(sigfpe_flt_env, 0) == 0) { + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigfpe_flt_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGFPE, &sa, NULL); +#ifdef __HAVE_FENV + feenableexcept(FE_ALL_EXCEPT); +#elif defined(_FLOAT_IEEE754) + fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); +#endif + printf("%g\n", 1 / d); + } + if (fltdiv_signalled == 0) + atf_tc_fail("FPE signal handler was not invoked"); +} + +static sigjmp_buf sigfpe_int_env; +static void +sigfpe_int_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + if (intdiv_signalled++ != 0) + atf_tc_fail("INTDIV handler called more than once"); + + ATF_REQUIRE_EQ(info->si_signo, SIGFPE); + ATF_REQUIRE_EQ(info->si_code, FPE_INTDIV); + atf_tc_expect_pass(); + ATF_REQUIRE_EQ(info->si_errno, 0); + + siglongjmp(sigfpe_int_env, 1); +} + +ATF_TC(sigfpe_int); +ATF_TC_HEAD(sigfpe_int, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGFPE handler " + "for integer div-by-zero (PR port-i386/43655)"); +} + +ATF_TC_BODY(sigfpe_int, tc) +{ + struct sigaction sa; + long l = strtol("0", NULL, 10); + +#if defined(__powerpc__) + atf_tc_skip("Test not valid on powerpc"); +#endif + if (sigsetjmp(sigfpe_int_env, 0) == 0) { + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigfpe_int_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGFPE, &sa, NULL); +#ifdef __HAVE_FENV + feenableexcept(FE_ALL_EXCEPT); +#elif defined(_FLOAT_IEEE754) + fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); +#endif + printf("%ld\n", 1 / l); + } + if (intdiv_signalled == 0) + atf_tc_fail("FPE signal handler was not invoked"); +} + +static void +sigsegv_action(int signo, siginfo_t *info, void *ptr) +{ + + sig_debug(signo, info, (ucontext_t *)ptr); + + ATF_REQUIRE_EQ(info->si_signo, SIGSEGV); + ATF_REQUIRE_EQ(info->si_errno, 0); + ATF_REQUIRE_EQ(info->si_code, SEGV_MAPERR); + ATF_REQUIRE_EQ(info->si_addr, (void *)0); + + atf_tc_pass(); + /* NOTREACHED */ +} + +ATF_TC(sigsegv); +ATF_TC_HEAD(sigsegv, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGSEGV handler"); +} + +ATF_TC_BODY(sigsegv, tc) +{ + struct sigaction sa; + + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigsegv_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + + *(volatile long *)0 = 0; + atf_tc_fail("Test did not fault as expected"); +} + +static void +sigbus_action(int signo, siginfo_t *info, void *ptr) +{ + + printf("si_addr = %p\n", info->si_addr); + sig_debug(signo, info, (ucontext_t *)ptr); + + ATF_REQUIRE_EQ(info->si_signo, SIGBUS); + ATF_REQUIRE_EQ(info->si_errno, 0); + ATF_REQUIRE_EQ(info->si_code, BUS_ADRALN); + +#if defined(__i386__) || defined(__x86_64__) + atf_tc_expect_fail("x86 architecture does not correctly " + "report the address where the unaligned access occured"); +#endif + ATF_REQUIRE_EQ(info->si_addr, (volatile void *)addr); + + atf_tc_pass(); + /* NOTREACHED */ +} + +ATF_TC(sigbus_adraln); +ATF_TC_HEAD(sigbus_adraln, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that signal trampoline correctly calls SIGBUS handler " + "for invalid address alignment"); +} + +ATF_TC_BODY(sigbus_adraln, tc) +{ + struct sigaction sa; + +#if defined(__alpha__) || defined(__arm__) + int rv, val; + size_t len = sizeof(val); + rv = sysctlbyname("machdep.unaligned_sigbus", &val, &len, NULL, 0); + ATF_REQUIRE(rv == 0); + if (val == 0) + atf_tc_skip("No SIGBUS signal for unaligned accesses"); +#endif + + /* m68k (except sun2) never issue SIGBUS (PR lib/49653) */ + if (strcmp(MACHINE_ARCH, "m68k") == 0) + atf_tc_skip("No SIGBUS signal for unaligned accesses"); + + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = sigbus_action; + sigemptyset(&sa.sa_mask); + sigaction(SIGBUS, &sa, NULL); + + /* Enable alignment checks for x86. 0x40000 is PSL_AC. */ +#if defined(__i386__) + __asm__("pushf; orl $0x40000, (%esp); popf"); +#elif defined(__amd64__) + __asm__("pushf; orl $0x40000, (%rsp); popf"); +#endif + + addr = calloc(2, sizeof(int)); + ATF_REQUIRE(addr != NULL); + + if (isQEMU()) + atf_tc_expect_fail("QEMU fails to trap unaligned accesses"); + + /* Force an unaligned access */ + addr++; + printf("now trying to access unaligned address %p\n", addr); + ATF_REQUIRE_EQ(*(volatile int *)addr, 0); + + atf_tc_fail("Test did not fault as expected"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sigalarm); + ATF_TP_ADD_TC(tp, sigchild_normal); + ATF_TP_ADD_TC(tp, sigchild_dump); + ATF_TP_ADD_TC(tp, sigchild_kill); + ATF_TP_ADD_TC(tp, sigfpe_flt); + ATF_TP_ADD_TC(tp, sigfpe_int); + ATF_TP_ADD_TC(tp, sigsegv); + ATF_TP_ADD_TC(tp, sigbus_adraln); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sleep.c b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c new file mode 100644 index 0000000..d4bd271 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c @@ -0,0 +1,348 @@ +/* $NetBSD: t_sleep.c,v 1.11 2017/01/10 15:43:59 maya Exp $ */ + +/*- + * Copyright (c) 2006 Frank Kardel + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include /* for TIMESPEC_TO_TIMEVAL on FreeBSD */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "isqemu.h" + +#define BILLION 1000000000LL /* nano-seconds per second */ +#define MILLION 1000000LL /* nano-seconds per milli-second */ + +#define ALARM 6 /* SIGALRM after this many seconds */ +#define MAXSLEEP 22 /* Maximum delay in seconds */ +#define KEVNT_TIMEOUT 10300 /* measured in milli-seconds */ +#define FUZZ (40 * MILLION) /* scheduling fuzz accepted - 40 ms */ + +/* + * Timer notes + * + * Most tests use FUZZ as their initial delay value, but 'sleep' + * starts at 1sec (since it cannot handle sub-second intervals). + * Subsequent passes double the previous interval, up to MAXSLEEP. + * + * The current values result in 5 passes for the 'sleep' test (at 1, + * 2, 4, 8, and 16 seconds) and 10 passes for the other tests (at + * 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, and 20.48 + * seconds). + * + * The ALARM is only set if the current pass's delay is longer, and + * only if the ALARM has not already been triggered. + * + * The 'kevent' test needs the ALARM to be set on a different pass + * from when the KEVNT_TIMEOUT fires. So set ALARM to fire on the + * penultimate pass, and the KEVNT_TIMEOUT on the final pass. We + * set KEVNT_TIMEOUT just barely long enough to put it into the + * last test pass, and set MAXSLEEP a couple seconds longer than + * necessary, in order to avoid a QEMU bug which nearly doubles + * some timers. + */ + +static volatile int sig; + +int sleeptest(int (*)(struct timespec *, struct timespec *), bool, bool); +int do_nanosleep(struct timespec *, struct timespec *); +int do_select(struct timespec *, struct timespec *); +#ifdef __NetBSD__ +int do_poll(struct timespec *, struct timespec *); +#endif +int do_sleep(struct timespec *, struct timespec *); +int do_kevent(struct timespec *, struct timespec *); +void sigalrm(int); + +void +sigalrm(int s) +{ + + sig++; +} + +int +do_nanosleep(struct timespec *delay, struct timespec *remain) +{ + int ret; + + if (nanosleep(delay, remain) == -1) + ret = (errno == EINTR ? 0 : errno); + else + ret = 0; + return ret; +} + +int +do_select(struct timespec *delay, struct timespec *remain) +{ + int ret; + struct timeval tv; + + TIMESPEC_TO_TIMEVAL(&tv, delay); + if (select(0, NULL, NULL, NULL, &tv) == -1) + ret = (errno == EINTR ? 0 : errno); + else + ret = 0; + return ret; +} + +#ifdef __NetBSD__ +int +do_poll(struct timespec *delay, struct timespec *remain) +{ + int ret; + struct timeval tv; + + TIMESPEC_TO_TIMEVAL(&tv, delay); + if (pollts(NULL, 0, delay, NULL) == -1) + ret = (errno == EINTR ? 0 : errno); + else + ret = 0; + return ret; +} +#endif + +int +do_sleep(struct timespec *delay, struct timespec *remain) +{ + struct timeval tv; + + TIMESPEC_TO_TIMEVAL(&tv, delay); + remain->tv_sec = sleep(delay->tv_sec); + remain->tv_nsec = 0; + + return 0; +} + +int +do_kevent(struct timespec *delay, struct timespec *remain) +{ + struct kevent ktimer; + struct kevent kresult; + int rtc, kq, kerrno; + int tmo; + + ATF_REQUIRE_MSG((kq = kqueue()) != -1, "kqueue: %s", strerror(errno)); + + tmo = KEVNT_TIMEOUT; + + /* + * If we expect the KEVNT_TIMEOUT to fire, and we're running + * under QEMU, make sure the delay is long enough to account + * for the effects of PR kern/43997 ! + */ + if (isQEMU() && + tmo/1000 < delay->tv_sec && tmo/500 > delay->tv_sec) + delay->tv_sec = MAXSLEEP; + + EV_SET(&ktimer, 1, EVFILT_TIMER, EV_ADD, 0, tmo, 0); + + rtc = kevent(kq, &ktimer, 1, &kresult, 1, delay); + kerrno = errno; + + (void)close(kq); + + if (rtc == -1) { + ATF_REQUIRE_MSG(kerrno == EINTR, "kevent: %s", + strerror(kerrno)); + return 0; + } + + if (delay->tv_sec * BILLION + delay->tv_nsec > tmo * MILLION) + ATF_REQUIRE_MSG(rtc > 0, + "kevent: KEVNT_TIMEOUT did not cause EVFILT_TIMER event"); + + return 0; +} + +ATF_TC(nanosleep); +ATF_TC_HEAD(nanosleep, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test nanosleep(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(nanosleep, tc) +{ + + sleeptest(do_nanosleep, true, false); +} + +ATF_TC(select); +ATF_TC_HEAD(select, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test select(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(select, tc) +{ + + sleeptest(do_select, true, true); +} + +#ifdef __NetBSD__ +ATF_TC(poll); +ATF_TC_HEAD(poll, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test poll(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(poll, tc) +{ + + sleeptest(do_poll, true, true); +} +#endif + +ATF_TC(sleep); +ATF_TC_HEAD(sleep, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test sleep(3) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(sleep, tc) +{ + + sleeptest(do_sleep, false, false); +} + +ATF_TC(kevent); +ATF_TC_HEAD(kevent, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test kevent(2) timing"); + atf_tc_set_md_var(tc, "timeout", "65"); +} + +ATF_TC_BODY(kevent, tc) +{ + + sleeptest(do_kevent, true, true); +} + +int +sleeptest(int (*test)(struct timespec *, struct timespec *), + bool subsec, bool sim_remain) +{ + struct timespec tsa, tsb, tslp, tremain; + int64_t delta1, delta2, delta3, round; + + sig = 0; + signal(SIGALRM, sigalrm); + + if (subsec) { + round = 1; + delta3 = FUZZ; + } else { + round = 1000000000; + delta3 = round; + } + + tslp.tv_sec = delta3 / 1000000000; + tslp.tv_nsec = delta3 % 1000000000; + + while (tslp.tv_sec <= MAXSLEEP) { + /* + * disturb sleep by signal on purpose + */ + if (tslp.tv_sec > ALARM && sig == 0) + alarm(ALARM); + + clock_gettime(CLOCK_REALTIME, &tsa); + (*test)(&tslp, &tremain); + clock_gettime(CLOCK_REALTIME, &tsb); + + if (sim_remain) { + timespecsub(&tsb, &tsa, &tremain); + timespecsub(&tslp, &tremain, &tremain); + } + + delta1 = (int64_t)tsb.tv_sec - (int64_t)tsa.tv_sec; + delta1 *= BILLION; + delta1 += (int64_t)tsb.tv_nsec - (int64_t)tsa.tv_nsec; + + delta2 = (int64_t)tremain.tv_sec * BILLION; + delta2 += (int64_t)tremain.tv_nsec; + + delta3 = (int64_t)tslp.tv_sec * BILLION; + delta3 += (int64_t)tslp.tv_nsec - delta1 - delta2; + + delta3 /= round; + delta3 *= round; + + if (delta3 > FUZZ || delta3 < -FUZZ) { + if (!sim_remain) + atf_tc_expect_fail("Long reschedule latency " + "due to PR kern/43997"); + + atf_tc_fail("Reschedule latency %"PRId64" exceeds " + "allowable fuzz %lld", delta3, FUZZ); + } + delta3 = (int64_t)tslp.tv_sec * 2 * BILLION; + delta3 += (int64_t)tslp.tv_nsec * 2; + + delta3 /= round; + delta3 *= round; + if (delta3 < FUZZ) + break; + tslp.tv_sec = delta3 / BILLION; + tslp.tv_nsec = delta3 % BILLION; + } + ATF_REQUIRE_MSG(sig == 1, "Alarm did not fire!"); + + atf_tc_pass(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, nanosleep); + ATF_TP_ADD_TC(tp, select); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, poll); +#endif + ATF_TP_ADD_TC(tp, sleep); + ATF_TP_ADD_TC(tp, kevent); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_syslog.c b/contrib/netbsd-tests/lib/libc/gen/t_syslog.c new file mode 100644 index 0000000..c9417c0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_syslog.c @@ -0,0 +1,56 @@ +/* $NetBSD: t_syslog.c,v 1.2 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 + +#include +#include + +ATF_TC(syslog_pthread); +ATF_TC_HEAD(syslog_pthread, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test that syslog(3) " + "works when linked to pthread(3) (PR lib/44248)"); + atf_tc_set_md_var(tc, "timeout", "2"); +} + +ATF_TC_BODY(syslog_pthread, tc) +{ + syslog(LOG_DEBUG, "from tests/lib/libc/gen/t_syslog"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, syslog_pthread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_time.c b/contrib/netbsd-tests/lib/libc/gen/t_time.c new file mode 100644 index 0000000..15a8d58 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_time.c @@ -0,0 +1,116 @@ +/* $NetBSD: t_time.c,v 1.4 2017/01/10 15:32:46 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_time.c,v 1.4 2017/01/10 15:32:46 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ATF_TC(time_copy); +ATF_TC_HEAD(time_copy, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test the return values of time(3)"); +} + +ATF_TC_BODY(time_copy, tc) +{ + time_t t1, t2 = 0; + + t1 = time(&t2); + + if (t1 != t2) + atf_tc_fail("incorrect return values from time(3)"); +} + +ATF_TC(time_mono); +ATF_TC_HEAD(time_mono, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test monotonicity of time(3)"); +} + +ATF_TC_BODY(time_mono, tc) +{ + const size_t maxiter = 10; + time_t t1, t2; + size_t i; + + for (i = 0; i < maxiter; i++) { + + t1 = time(NULL); + (void)sleep(1); + t2 = time(NULL); + + (void)fprintf(stderr, "%"PRId64" vs. %"PRId64"\n", + (int64_t)t1, (int64_t)t2); + + if (t1 >= t2) + atf_tc_fail("time(3) is not monotonic"); + } +} + +ATF_TC(time_timeofday); +ATF_TC_HEAD(time_timeofday, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test time(3) vs. gettimeofday(2)"); +} + +ATF_TC_BODY(time_timeofday, tc) +{ + struct timeval tv = { 0, 0 }; + time_t t1, t2; + + t1 = time(NULL); + ATF_REQUIRE(gettimeofday(&tv, NULL) == 0); + t2 = time(NULL); + + (void)fprintf(stderr, "%"PRId64" vs. %"PRId64"\n", + (int64_t)t1, (int64_t)tv.tv_sec); + + if (t1 > tv.tv_sec || t2 < tv.tv_sec) + atf_tc_fail("time(3) and gettimeofday(2) differ"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, time_copy); + ATF_TP_ADD_TC(tp, time_mono); + ATF_TP_ADD_TC(tp, time_timeofday); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c new file mode 100644 index 0000000..61121b8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c @@ -0,0 +1,189 @@ +/* $NetBSD: t_ttyname.c,v 1.4 2017/01/10 15:33:40 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_ttyname.c,v 1.4 2017/01/10 15:33:40 christos Exp $"); + +#include +#include +#include +#include +#include +#include + +static long ttymax = 0; + +ATF_TC(ttyname_err); +ATF_TC_HEAD(ttyname_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors in ttyname(3)"); +} + +ATF_TC_BODY(ttyname_err, tc) +{ + int fd; + + fd = open("XXX", O_RDONLY); + + if (fd < 0) { + + errno = 0; + + ATF_REQUIRE(isatty(fd) != -1); + ATF_REQUIRE(errno == EBADF); + + errno = 0; + + ATF_REQUIRE(ttyname(fd) == NULL); + ATF_REQUIRE(errno == EBADF); + } + + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0) { + + errno = 0; + + ATF_REQUIRE(isatty(fd) != -1); + ATF_REQUIRE(errno == ENOTTY); + + errno = 0; + + ATF_REQUIRE(ttyname(fd) == NULL); + ATF_REQUIRE(errno == ENOTTY); + (void)close(fd); + } +} + +ATF_TC(ttyname_r_err); +ATF_TC_HEAD(ttyname_r_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors in ttyname_r(3)"); +} + +ATF_TC_BODY(ttyname_r_err, tc) +{ + char sbuf[0]; + char *buf; + int fd; + int rv; + + buf = malloc(ttymax + 1); + + if (buf == NULL) + return; + + (void)memset(buf, '\0', ttymax + 1); + + if (isatty(STDIN_FILENO) != 0) { + + rv = ttyname_r(STDIN_FILENO, sbuf, sizeof(sbuf)); + ATF_REQUIRE(rv == ERANGE); + } + + rv = ttyname_r(-1, buf, ttymax); + ATF_REQUIRE(rv == EBADF); + + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0) { + rv = ttyname_r(fd, buf, ttymax); + ATF_REQUIRE(rv == ENOTTY); + ATF_REQUIRE(close(fd) == 0); + } + + free(buf); +} + +ATF_TC(ttyname_r_stdin); +ATF_TC_HEAD(ttyname_r_stdin, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ttyname_r(3) with stdin(3)"); +} + +ATF_TC_BODY(ttyname_r_stdin, tc) +{ + const char *str; + char *buf; + int rv; + + if (isatty(STDIN_FILENO) == 0) + return; + + buf = malloc(ttymax + 1); + + if (buf == NULL) + return; + + (void)memset(buf, '\0', ttymax + 1); + + str = ttyname(STDIN_FILENO); + rv = ttyname_r(STDIN_FILENO, buf, ttymax); + + ATF_REQUIRE(rv == 0); + ATF_REQUIRE(str != NULL); + + if (strcmp(str, buf) != 0) + atf_tc_fail("ttyname(3) and ttyname_r(3) conflict"); + + free(buf); +} + +ATF_TC(ttyname_stdin); +ATF_TC_HEAD(ttyname_stdin, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ttyname(3) with stdin(3)"); +} + +ATF_TC_BODY(ttyname_stdin, tc) +{ + + if (isatty(STDIN_FILENO) != 0) + ATF_REQUIRE(ttyname(STDIN_FILENO) != NULL); + + (void)close(STDIN_FILENO); + + ATF_REQUIRE(isatty(STDIN_FILENO) != 1); + ATF_REQUIRE(ttyname(STDIN_FILENO) == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + ttymax = sysconf(_SC_TTY_NAME_MAX); + ATF_REQUIRE(ttymax >= 0); + + ATF_TP_ADD_TC(tp, ttyname_err); + ATF_TP_ADD_TC(tp, ttyname_r_err); + ATF_TP_ADD_TC(tp, ttyname_r_stdin); + ATF_TP_ADD_TC(tp, ttyname_stdin); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/gen/t_vis.c b/contrib/netbsd-tests/lib/libc/gen/t_vis.c new file mode 100644 index 0000000..adb0930 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/gen/t_vis.c @@ -0,0 +1,190 @@ +/* $NetBSD: t_vis.c,v 1.9 2017/01/10 15:16:57 christos Exp $ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include +#include +#include + +static int styles[] = { + VIS_OCTAL, + VIS_CSTYLE, + VIS_SP, + VIS_TAB, + VIS_NL, + VIS_WHITE, + VIS_SAFE, +#if 0 /* Not reversible */ + VIS_NOSLASH, +#endif + VIS_HTTP1808, + VIS_MIMESTYLE, +#if 0 /* Not supported by vis(3) */ + VIS_HTTP1866, +#endif +}; + +#define SIZE 256 + +ATF_TC(strvis_basic); +ATF_TC_HEAD(strvis_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test strvis(3)"); +} + +ATF_TC_BODY(strvis_basic, tc) +{ + char *srcbuf, *dstbuf, *visbuf; + unsigned int i, j; + + ATF_REQUIRE((dstbuf = malloc(SIZE)) != NULL); + ATF_REQUIRE((srcbuf = malloc(SIZE)) != NULL); + ATF_REQUIRE((visbuf = malloc(SIZE * 4 + 1)) != NULL); + + for (i = 0; i < SIZE; i++) + srcbuf[i] = (char)i; + + for (i = 0; i < __arraycount(styles); i++) { + ATF_REQUIRE(strsvisx(visbuf, srcbuf, SIZE, styles[i], "") > 0); + memset(dstbuf, 0, SIZE); + ATF_REQUIRE(strunvisx(dstbuf, visbuf, + styles[i] & (VIS_HTTP1808|VIS_MIMESTYLE)) > 0); + for (j = 0; j < SIZE; j++) + if (dstbuf[j] != (char)j) + atf_tc_fail_nonfatal("Failed for style %x, " + "char %d [%d]", styles[i], j, dstbuf[j]); + } + free(dstbuf); + free(srcbuf); + free(visbuf); +} + +ATF_TC(strvis_null); +ATF_TC_HEAD(strvis_null, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strvis(3) NULL"); +} + +ATF_TC_BODY(strvis_null, tc) +{ + char dst[] = "fail"; + strvis(dst, NULL, VIS_SAFE); + ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a'); +} + +ATF_TC(strvis_empty); +ATF_TC_HEAD(strvis_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strvis(3) empty"); +} + +ATF_TC_BODY(strvis_empty, tc) +{ + char dst[] = "fail"; + strvis(dst, "", VIS_SAFE); + ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a'); +} + +ATF_TC(strunvis_hex); +ATF_TC_HEAD(strunvis_hex, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strunvis(3) \\xXX"); +} + +ATF_TC_BODY(strunvis_hex, tc) +{ + static const struct { + const char *e; + const char *d; + int error; + } ed[] = { + { "\\xff", "\xff", 1 }, + { "\\x1", "\x1", 1 }, + { "\\x1\\x02", "\x1\x2", 2 }, + { "\\x1x", "\x1x", 2 }, + { "\\xx", "", -1 }, + }; + char uv[10]; + + for (size_t i = 0; i < __arraycount(ed); i++) { + ATF_REQUIRE(strunvis(uv, ed[i].e) == ed[i].error); + if (ed[i].error > 0) + ATF_REQUIRE(memcmp(ed[i].d, uv, ed[i].error) == 0); + } +} + +#ifdef VIS_NOLOCALE +ATF_TC(strvis_locale); +ATF_TC_HEAD(strvis_locale, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strvis(3) with locale"); +} + +ATF_TC_BODY(strvis_locale, tc) +{ + char s[256], cd[sizeof(s) * 4 + 1], jd[sizeof(cd)], *ol; + int jr, cr; + + for (size_t i = 0; i < sizeof(s) - 1; i++) + s[i] = i + 1; + s[sizeof(s) - 1] = '\0'; + + ol = setlocale(LC_CTYPE, "ja_JP.UTF-8"); + ATF_REQUIRE(ol != NULL); + jr = strvisx(jd, s, sizeof(s), VIS_WHITE | VIS_NOLOCALE); + ATF_REQUIRE(jr != -1); + ol = strdup(ol); + ATF_REQUIRE(ol != NULL); + ATF_REQUIRE(setlocale(LC_CTYPE, "C") != NULL); + cr = strvisx(cd, s, sizeof(s), VIS_WHITE); + ATF_REQUIRE(jr == cr); + ATF_REQUIRE(memcmp(jd, cd, jr) == 0); + setlocale(LC_CTYPE, ol); + free(ol); +} +#endif /* VIS_NOLOCALE */ + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strvis_basic); + ATF_TP_ADD_TC(tp, strvis_null); + ATF_TP_ADD_TC(tp, strvis_empty); + ATF_TP_ADD_TC(tp, strunvis_hex); +#ifdef VIS_NOLOCALE + ATF_TP_ADD_TC(tp, strvis_locale); +#endif /* VIS_NOLOCALE */ + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/hash/data/md5test-in b/contrib/netbsd-tests/lib/libc/hash/data/md5test-in new file mode 100644 index 0000000..763e4f9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/md5test-in @@ -0,0 +1,7 @@ + +a +abc +message digest +abcdefghijklmnopqrstuvwxyz +ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 diff --git a/contrib/netbsd-tests/lib/libc/hash/data/md5test-out b/contrib/netbsd-tests/lib/libc/hash/data/md5test-out new file mode 100644 index 0000000..bb86bb6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/md5test-out @@ -0,0 +1,7 @@ +d41d8cd98f00b204e9800998ecf8427e +0cc175b9c0f1b6a831c399e269772661 +900150983cd24fb0d6963f7d28e17f72 +f96b697d7cb7938d525a2f31aaf161d0 +c3fcd3d76192e4007dfb496cca67e13b +d174ab98d277d9f5a5611c2c9f419d9f +57edf4a22be3c955ac49da2e2107b67a diff --git a/contrib/netbsd-tests/lib/libc/hash/data/sha1test-in b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-in new file mode 100644 index 0000000..632d133 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-in @@ -0,0 +1,2 @@ +abc +abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq diff --git a/contrib/netbsd-tests/lib/libc/hash/data/sha1test-out b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-out new file mode 100644 index 0000000..c23a058 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-out @@ -0,0 +1,2 @@ +a9993e364706816aba3e25717850c26c9cd0d89d +84983e441c3bd26ebaae4aa1f95129e5e54670f1 diff --git a/contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out b/contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out new file mode 100644 index 0000000..a483a0e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out @@ -0,0 +1 @@ +34aa973cd4c4daa4f61eeb2bdbad27316534016f diff --git a/contrib/netbsd-tests/lib/libc/hash/h_hash.c b/contrib/netbsd-tests/lib/libc/hash/h_hash.c new file mode 100644 index 0000000..33b9f9a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/h_hash.c @@ -0,0 +1,167 @@ +/* $NetBSD: h_hash.c,v 1.1 2011/01/02 22:03:25 pgoyette Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Combined MD5/SHA1 time and regression test. + */ + +#include +#include +#include +#include +#include +#include + + +int mflag, rflag, sflag, tflag; + +static void +usage(void) +{ + (void)fprintf(stderr, + "Usage:\t%s -r[ms] < test-file\n" + "\t%s -t[ms]\n", + getprogname(), getprogname()); + exit(1); + /* NOTREACHED */ +} + +static void +hexdump (unsigned char *buf, int len) +{ + int i; + for (i=0; i 0) && \ + (buf[len-1] == '\n')) { \ + buf[len-1] = '\0'; \ + len--; \ + last = 1; \ + } + +static void +regress(void) +{ + unsigned char buf[1024]; + unsigned char out[20]; + int len, outlen, last; + + while (fgets((char *)buf, sizeof(buf), stdin) != NULL) { + last = 0; + + len = strlen((char *)buf); + CHOMP(buf, len, last); + if (mflag) { + MD5_CTX ctx; + + MD5Init(&ctx); + MD5Update(&ctx, buf, len); + while (!last && + fgets((char *)buf, sizeof(buf), stdin) != NULL) { + len = strlen((char *)buf); + CHOMP(buf, len, last); + MD5Update(&ctx, buf, len); + } + MD5Final(out, &ctx); + outlen = 16; + } else { + SHA1_CTX ctx; + + SHA1Init(&ctx); + SHA1Update(&ctx, buf, len); + while (!last && + fgets((char *)buf, sizeof(buf), stdin) != NULL) { + len = strlen((char *)buf); + CHOMP(buf, len, last); + SHA1Update(&ctx, buf, len); + } + SHA1Final(out, &ctx); + outlen = 20; + } + hexdump(out, outlen); + } +} + +int +main(int argc, char **argv) +{ + int ch; + + while ((ch = getopt(argc, argv, "mrst")) != -1) + switch (ch) { + case 'm': + mflag = 1; + break; + case 'r': + rflag = 1; + break; + case 's': + sflag = 1; + break; + case 't': + tflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + if (argc > 0) + usage(); + + if (!(mflag || sflag)) + mflag = 1; + + if ((mflag ^ sflag) != 1) + usage(); + + if ((tflag ^ rflag) != 1) + usage(); + + if (tflag) + timetest(); + + if (rflag) + regress(); + + exit(0); + +} diff --git a/contrib/netbsd-tests/lib/libc/hash/t_hash.sh b/contrib/netbsd-tests/lib/libc/hash/t_hash.sh new file mode 100755 index 0000000..719f19d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/t_hash.sh @@ -0,0 +1,67 @@ +# $NetBSD: t_hash.sh,v 1.1 2011/01/02 22:03:25 pgoyette Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +prog() +{ + echo "$(atf_get_srcdir)/h_hash" +} + +datadir() +{ + echo "$(atf_get_srcdir)/data" +} + +atf_test_case md5 +md5_head() +{ + atf_set "descr" "Checks MD5 functions" +} +md5_body() +{ + atf_check -o file:"$(datadir)/md5test-out" -x \ + "$(prog) -r < $(datadir)/md5test-in" +} + +atf_test_case sha1 +sha1_head() +{ + atf_set "descr" "Checks SHA1 functions" +} +sha1_body() +{ + atf_check -o file:"$(datadir)/sha1test-out" -x \ + "$(prog) -rs < $(datadir)/sha1test-in" + + atf_check -o file:"$(datadir)/sha1test2-out" -x \ + "jot -s '' -b 'a' -n 1000000 | $(prog) -rs" +} + +atf_init_test_cases() +{ + atf_add_test_case md5 + atf_add_test_case sha1 +} diff --git a/contrib/netbsd-tests/lib/libc/hash/t_hmac.c b/contrib/netbsd-tests/lib/libc/hash/t_hmac.c new file mode 100644 index 0000000..3dcbea9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/t_hmac.c @@ -0,0 +1,127 @@ +/* $NetBSD: t_hmac.c,v 1.1 2016/07/02 14:52:09 christos Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_hmac.c,v 1.1 2016/07/02 14:52:09 christos Exp $"); + +#include +#include +#include +#include +#include + +static void +test(void) +{ + uint8_t tmp1[EVP_MAX_MD_SIZE]; + uint8_t tmp2[EVP_MAX_MD_SIZE]; + uint8_t key[256]; + uint8_t data[4096]; + unsigned int tmp1len; + size_t tmp2len; + int stop; + void *e1; + const void *evps[] = { + EVP_md2(), + EVP_md4(), + EVP_md5(), + EVP_ripemd160(), + EVP_sha1(), + EVP_sha224(), + EVP_sha256(), + EVP_sha384(), + EVP_sha512(), + }; + const char *names[] = { + "md2", + "md4", + "md5", + "rmd160", + "sha1", + "sha224", + "sha256", + "sha384", + "sha512", + }; + + for (size_t k = 0; k < sizeof(key); k++) + key[k] = k; + for (size_t d = 0; d < sizeof(data); d++) + data[d] = d % 256; + + for (size_t t = 0; t < __arraycount(names); t++) + for (size_t i = 1; i < sizeof(key); i += 9) + for (size_t j = 3; j < sizeof(data); j += 111) { + stop = 0; +#ifdef DEBUG + printf("%s: keysize = %zu datasize = %zu\n", names[t], + i, j); +#endif + memset(tmp1, 0, sizeof(tmp1)); + memset(tmp2, 0, sizeof(tmp2)); + e1 = HMAC(evps[t], key, i, data, j, tmp1, &tmp1len); + ATF_REQUIRE(e1 != NULL); + tmp2len = hmac(names[t], key, i, data, j, tmp2, + sizeof(tmp2)); + ATF_REQUIRE_MSG(tmp1len == tmp2len, "hash %s len %u " + "!= %zu", names[t], tmp1len, tmp2len); + for (size_t k = 0; k < tmp2len; k++) + if (tmp1[k] != tmp2[k]) { +#ifdef DEBUG + printf("%zu %.2x %.2x\n", + k, tmp1[k], tmp2[k]); +#endif + stop = 1; + break; + } + ATF_REQUIRE_MSG(!stop, "hash %s failed for " + "keylen=%zu, datalen=%zu", names[t], i, j); + } +} + +ATF_TC(t_hmac); + +ATF_TC_HEAD(t_hmac, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test hmac functions for consistent results"); +} + +ATF_TC_BODY(t_hmac, tc) +{ + test(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_hmac); + return atf_no_error(); +} + diff --git a/contrib/netbsd-tests/lib/libc/hash/t_sha2.c b/contrib/netbsd-tests/lib/libc/hash/t_sha2.c new file mode 100644 index 0000000..a45e82a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/hash/t_sha2.c @@ -0,0 +1,243 @@ +/* $NetBSD: t_sha2.c,v 1.3 2012/09/26 22:23:30 joerg Exp $ */ +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_sha2.c,v 1.3 2012/09/26 22:23:30 joerg Exp $"); + +#include +#include +#include +#include + +ATF_TC(t_sha256); +ATF_TC(t_sha384); +ATF_TC(t_sha512); + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_sha256); + ATF_TP_ADD_TC(tp, t_sha384); + ATF_TP_ADD_TC(tp, t_sha512); + + return atf_no_error(); +} + +struct testvector { + const char *vector; + const char *hash; +}; + +static const struct testvector test256[] = { + { "hello, world", "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b" }, + { "", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }, + { "a", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb" }, + { "ab", "fb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603" }, + { "abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" }, + { "abcd", "88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589" }, + { "abcde", "36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c" }, + { "abcdef", "bef57ec7f53a6d40beb640a780a639c83bc29ac8a9816f1fc6c5c6dcd93c4721" }, + { "abcdefg", "7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a" }, + { "abcdefgh", "9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab" }, + { "abcdefghi", "19cc02f26df43cc571bc9ed7b0c4d29224a3ec229529221725ef76d021c8326f" }, + { "abcdefghij", "72399361da6a7754fec986dca5b7cbaf1c810a28ded4abaf56b2106d06cb78b0" }, + { "abcdefghijk", "ca2f2069ea0c6e4658222e06f8dd639659cbb5e67cbbba6734bc334a3799bc68" }, + { "abcdefghijkl", "d682ed4ca4d989c134ec94f1551e1ec580dd6d5a6ecde9f3d35e6e4a717fbde4" }, + { "abcdefghijklm", "ff10304f1af23606ede1e2d8abcdc94c229047a61458d809d8bbd53ede1f6598" }, + { "abcdefghijklmn", "0653c7e992d7aad40cb2635738b870e4c154afb346340d02c797d490dd52d5f9" }, + { "abcdefghijklmno", "41c7760c50efde99bf574ed8fffc7a6dd3405d546d3da929b214c8945acf8a97" }, + { "abcdefghijklmnop", "f39dac6cbaba535e2c207cd0cd8f154974223c848f727f98b3564cea569b41cf" }, + { "abcdefghijklmnopq", "918a954ac4dfb54ac39f068d9868227f69ab39bc362e2c9b0083bf6a109d6ad7" }, + { "abcdefghijklmnopqr", "2d1222692afaf56e95a8ab00879ed023a00db3e26fa14236e542748579285efa" }, + { "abcdefghijklmnopqrs", "e250f886728b77ba63722c7e65fc73e203101a84281b32332fd67cc6a1ae3e22" }, + { "abcdefghijklmnopqrst", "dd65eea0329dcb94b17187af9dff28c31a1d78026737a16af75979a1fa4618e5" }, + { "abcdefghijklmnopqrstu", "25f62a5a3d414ec6e20907df7f367f2b72625aade552db64c07933f6044fc49a" }, + { "abcdefghijklmnopqrstuv", "f69f9b70d1c9a5442258ca76f8b0a7a45fcb4e31c36141b6357ec591328b0624" }, + { "abcdefghijklmnopqrstuvw", "7f07818e14d08944ce145629ca54332f5cfad148c590efbcb5c377f4d336e5f4" }, + { "abcdefghijklmnopqrstuvwq", "063132d7fbec0acb79b2f228777eec8885e7f09bc1896b3ce5aa1843e83de048" }, +}; + +static const struct testvector test384[] = { + { "hello, world", "1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e" }, + { "", "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" }, + { "a", "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31" }, + { "ab", "c7be03ba5bcaa384727076db0018e99248e1a6e8bd1b9ef58a9ec9dd4eeebb3f48b836201221175befa74ddc3d35afdd" }, + { "abc", "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" }, + { "abcd", "1165b3406ff0b52a3d24721f785462ca2276c9f454a116c2b2ba20171a7905ea5a026682eb659c4d5f115c363aa3c79b" }, + { "abcde", "4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0" }, + { "abcdef", "c6a4c65b227e7387b9c3e839d44869c4cfca3ef583dea64117859b808c1e3d8ae689e1e314eeef52a6ffe22681aa11f5" }, + { "abcdefg", "9f11fc131123f844c1226f429b6a0a6af0525d9f40f056c7fc16cdf1b06bda08e302554417a59fa7dcf6247421959d22" }, + { "abcdefgh", "9000cd7cada59d1d2eb82912f7f24e5e69cc5517f68283b005fa27c285b61e05edf1ad1a8a9bded6fd29eb87d75ad806" }, + { "abcdefghi", "ef54915b60cf062b8dd0c29ae3cad69abe6310de63ac081f46ef019c5c90897caefd79b796cfa81139788a260ded52df" }, + { "abcdefghij", "a12070030a02d86b0ddacd0d3a5b598344513d0a051e7355053e556a0055489c1555399b03342845c4adde2dc44ff66c" }, + { "abcdefghijk", "2440d0e751fe5b8b1aba067e20be00b9deecc5e218b0b4b37202de824bcd04294d67c8d0b73e393afa844fa9ca25fa51" }, + { "abcdefghijkl", "103ca96c06a1ce798f08f8eff0dfb0ccdb567d48b285b23d0cd773454667a3c2fa5f1b58d9cdf2329bd9979730bfaaff" }, + { "abcdefghijklm", "89a7179df195462f047393c36e4843183eb38404bdfbacfd0b0f9c2556632a2799f19c3ecf48bdb7c9bdf95d3f6c3704" }, + { "abcdefghijklmn", "3bc463b0a5614d39fd207cbfd108534bce68d5438235c6c577b34b70fe219954adceaf8808d1fad4a44fc9c420ea8ff1" }, + { "abcdefghijklmno", "5149860ee76dd6666308189e60090d615e36ce0c0ef753a610cca0524a022900489d70167a47cc74c4dd9f9f340066af" }, + { "abcdefghijklmnop", "96d3c1b54b1938600abe5b57232e185df1c5856f74656b8f9837c5317cf5b22ac38226fafc8c946b9d20aca1b0c53a98" }, + { "abcdefghijklmnopq", "dae0d8c29d8f1137df3afb8f502dc474d3bbb56de0c10fc219547826f23f38f37ec29e4ed203908e6e7955c83a138129" }, + { "abcdefghijklmnopqr", "5cfa62716d985d3b1efab0ed3460e7b7f6af9439ae8ee5c58b20e68607eeec3e8c6df8481f5f36e726eaa56512acea6e" }, + { "abcdefghijklmnopqrs", "c5d404fc93b0e59ecb5f40446da201876faf18a0af46e577ae2f7a4fe56dc4c419afff7edec90ff3de160d0c5e7a5ec1" }, + { "abcdefghijklmnopqrst", "bc1511cd8b813544cb60b13d1ceb63e81f46aa3ca114a23fc5c3aba54f9965cdf9afa68e2dc2a680934e429dff5aa7f2" }, + { "abcdefghijklmnopqrstu", "8f18622d37e0aceabba191e3836b30e8970aca202ce6e811f586ec5f950edb7bf799cc88a18468a3effb063397242d95" }, + { "abcdefghijklmnopqrstuv", "c8a4f46e609626543ce6c1362721fcbe95c8e7405aaee61da4f2da1740f0351172c98a66530f8607bf8609e387ff8456" }, + { "abcdefghijklmnopqrstuvw", "2daff33b3bd67de61550070696b431d54b1397b40d053912b07a94260812185907726e3efbe9ae9fc078659cd2ce36db" }, + { "abcdefghijklmnopqrstuvwq", "87dc70a2eaa0dd0b687f91f26383866161026e41bb310a9e32b7a17c99284db85b9743476a30caeedf3fbb3c8072bc5e" }, +}; + +static const struct testvector test512[] = { + { "hello, world", "8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9" }, + { "", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" }, + { "a", "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75" }, + { "ab", "2d408a0717ec188158278a796c689044361dc6fdde28d6f04973b80896e1823975cdbf12eb63f9e0591328ee235d80e9b5bf1aa6a44f4617ff3caf6400eb172d" }, + { "abc", "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" }, + { "abcd", "d8022f2060ad6efd297ab73dcc5355c9b214054b0d1776a136a669d26a7d3b14f73aa0d0ebff19ee333368f0164b6419a96da49e3e481753e7e96b716bdccb6f" }, + { "abcde", "878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1" }, + { "abcdef", "e32ef19623e8ed9d267f657a81944b3d07adbb768518068e88435745564e8d4150a0a703be2a7d88b61e3d390c2bb97e2d4c311fdc69d6b1267f05f59aa920e7" }, + { "abcdefg", "d716a4188569b68ab1b6dfac178e570114cdf0ea3a1cc0e31486c3e41241bc6a76424e8c37ab26f096fc85ef9886c8cb634187f4fddff645fb099f1ff54c6b8c" }, + { "abcdefgh", "a3a8c81bc97c2560010d7389bc88aac974a104e0e2381220c6e084c4dccd1d2d17d4f86db31c2a851dc80e6681d74733c55dcd03dd96f6062cdda12a291ae6ce" }, + { "abcdefghi", "f22d51d25292ca1d0f68f69aedc7897019308cc9db46efb75a03dd494fc7f126c010e8ade6a00a0c1a5f1b75d81e0ed5a93ce98dc9b833db7839247b1d9c24fe" }, + { "abcdefghij", "ef6b97321f34b1fea2169a7db9e1960b471aa13302a988087357c520be957ca119c3ba68e6b4982c019ec89de3865ccf6a3cda1fe11e59f98d99f1502c8b9745" }, + { "abcdefghijk", "2798fd001ee8800e3da09ee99ae9600de2d0ccf464ab782c92fcc06ce3847cef0743365f1d49c2c8b4426db1635433f937d508672a9d0cb673b84f368eca1b23" }, + { "abcdefghijkl", "17807c728ee3ba35e7cf7af823116d26e41e5d4d6c2ff1f3720d3d96aacb6f69de642e63d5b73fc396c12be38b2bd5d884257c32c8f6d0854ae6b540f86dda2e" }, + { "abcdefghijklm", "e11a66f7b9a2acda5663e9434377137d73ea560a32782230412642a463c8558123bfb7c0dbf17851e9aa58cc9587c3b4f5e3f7f38dcb6f890702e5bed4d5b54a" }, + { "abcdefghijklmn", "8334134081070bf7fcc8bf1c242d24bb3182a5119e5fb19d8bbf6b9d0cdb7fed5336e83415fce93094c0e55123cf69e14d7ae41b22289232699824e31125b6d9" }, + { "abcdefghijklmno", "db723f341a042d8de1aa813efd5e02fc1745ccbe259486257514804e2ec4bcebb2a46f1e4ad442154943f9e97e1bc47c3ae0eddab7de0c01a9c51f15342a5b19" }, + { "abcdefghijklmnop", "d0cadd6834fa0c157b36cca30ee8b0b1435d841aa5b5ac850c11ae80a1440f51743e98fb1f1e7376c70f2f65404f088c28bcb4a511df2e64111f8f7424364b60" }, + { "abcdefghijklmnopq", "6196942a8495b721f82bbc385c74c1f10eeadf35db8adc9cf1a05ddeed19351228279644cd5d686ee48a31631ebb64747a2b68b733dd6015e3d27750878fa875" }, + { "abcdefghijklmnopqr", "fb3bd1fc157ea6f7a6728986a59b271b766fb723f6b7cf2b4194437435f2c497f33b6a56ae7eb3830fa9e04d5ebb4cb5e3f4d4bd812c498bdf0167e125de3fba" }, + { "abcdefghijklmnopqrs", "836f9ecf2aa02f522a94f1370af45a9fd538ac3c70e3b709d614b2f8981881d6b0070fc6387b74ee371fc2549309f82926e78084b401deb61a106c399089bee8" }, + { "abcdefghijklmnopqrst", "8cd9c137651425fb32d193d99b281735ec68eb5fd296f16459d1b33eac7badcfce0dca22eadaa5f209fa4ac3bbecd41342bac8b8a5dc3626e7f22cdc96e17cb4" }, + { "abcdefghijklmnopqrstu", "7079853a3e36241a8d83639f168ef38e883d7f72851a84ef3ed4d91c6a3896cf542b8b4518c2816fb19d4692a4b9aae65cb857e3642ce0a3936e20363bcbd4ca" }, + { "abcdefghijklmnopqrstuv", "a4e8a90b7058fb078e6cdcfd0c6a33c366437eb9084eac657830356804c9f9b53f121496d8e972d8707a4cf02615e6f58ed1a770c28ac79ffd845401fe18a928" }, + { "abcdefghijklmnopqrstuvw", "d91b1fd7c7785975493826719f333d090b214ff42351c84d8f8b2538509a28d2d59a36d0ac798d99d3908083b072a4be606ae391def5daa74156350fec71dd24" }, + { "abcdefghijklmnopqrstuvwq", "404eb5652173323320cac6bf8d9714aef0747693a8ab4570700c6262268d367f30e31c44fa66860568ff058fe39c9aa8dac76bc78566c691a884cb9052c4aa0a" }, +}; + +static void +digest2string(const uint8_t *digest, char *string, size_t len) +{ + while (len--) { + if (*digest / 16 < 10) + *string++ = '0' + *digest / 16; + else + *string++ = 'a' + *digest / 16 - 10; + if (*digest % 16 < 10) + *string++ = '0' + *digest % 16; + else + *string++ = 'a' + *digest % 16 - 10; + ++digest; + } + *string = '\0'; +} + +ATF_TC_HEAD(t_sha256, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test SHA256 functions for consistent results"); +} + +ATF_TC_BODY(t_sha256, tc) +{ + size_t i, j, len; + SHA256_CTX ctx; + unsigned char buf[256]; + unsigned char digest[8 + SHA256_DIGEST_LENGTH]; + char output[SHA256_DIGEST_STRING_LENGTH]; + + for (i = 0; i < sizeof(test256) / sizeof(test256[0]); ++i) { + len = strlen(test256[i].vector); + for (j = 0; j < 8; ++j) { + SHA256_Init(&ctx); + memcpy(buf + j, test256[i].vector, len); + SHA256_Update(&ctx, buf + j, len); + SHA256_Final(digest + j, &ctx); + digest2string(digest + j, output, SHA256_DIGEST_LENGTH); + ATF_CHECK_STREQ(test256[i].hash, output); + } + } +} + +ATF_TC_HEAD(t_sha384, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test SHA384 functions for consistent results"); +} + +ATF_TC_BODY(t_sha384, tc) +{ + size_t i, j, len; + SHA384_CTX ctx; + unsigned char buf[384]; + unsigned char digest[8 + SHA384_DIGEST_LENGTH]; + char output[SHA384_DIGEST_STRING_LENGTH]; + + for (i = 0; i < sizeof(test384) / sizeof(test384[0]); ++i) { + len = strlen(test384[i].vector); + for (j = 0; j < 8; ++j) { + SHA384_Init(&ctx); + memcpy(buf + j, test384[i].vector, len); + SHA384_Update(&ctx, buf + j, len); + SHA384_Final(digest + j, &ctx); + digest2string(digest + j, output, SHA384_DIGEST_LENGTH); + ATF_CHECK_STREQ(test384[i].hash, output); + } + } +} + +ATF_TC_HEAD(t_sha512, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test SHA512 functions for consistent results"); +} + +ATF_TC_BODY(t_sha512, tc) +{ + size_t i, j, len; + SHA512_CTX ctx; + unsigned char buf[512]; + unsigned char digest[8 + SHA512_DIGEST_LENGTH]; + char output[SHA512_DIGEST_STRING_LENGTH]; + + for (i = 0; i < sizeof(test512) / sizeof(test512[0]); ++i) { + len = strlen(test512[i].vector); + for (j = 0; j < 8; ++j) { + SHA512_Init(&ctx); + memcpy(buf + j, test512[i].vector, len); + SHA512_Update(&ctx, buf + j, len); + SHA512_Final(digest + j, &ctx); + digest2string(digest + j, output, SHA512_DIGEST_LENGTH); + ATF_CHECK_STREQ(test512[i].hash, output); + } + } +} diff --git a/contrib/netbsd-tests/lib/libc/inet/t_inet_addr.c b/contrib/netbsd-tests/lib/libc/inet/t_inet_addr.c new file mode 100644 index 0000000..d7547fd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/inet/t_inet_addr.c @@ -0,0 +1,109 @@ +/* $NetBSD: t_inet_addr.c,v 1.1 2015/04/09 16:47:56 ginsbach Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_inet_addr.c,v 1.1 2015/04/09 16:47:56 ginsbach Exp $"); + +#include + +#include +#include +#include + +ATF_TC(inet_addr_basic); +ATF_TC_HEAD(inet_addr_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks inet_addr(3)"); +} + +ATF_TC_BODY(inet_addr_basic, tc) +{ + static const char *addrs[] = { + "127.0.0.1", "99.99.99.99", "0.0.0.0", "255.255.255.255" }; + + struct in_addr ia; + const char *ian; + in_addr_t addr; + size_t i; + + for (i = 0; i < __arraycount(addrs); i++) { + + (void)fprintf(stderr, "checking %s\n", addrs[i]);; + + addr = inet_addr(addrs[i]); + ia.s_addr = addr; + ian = inet_ntoa(ia); + + ATF_REQUIRE(ian != NULL); + ATF_CHECK(strcmp(ian, addrs[i]) == 0); + } +} + +ATF_TC(inet_addr_err); +ATF_TC_HEAD(inet_addr_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Invalid addresses with inet_addr(3)"); +} + +ATF_TC_BODY(inet_addr_err, tc) +{ + static const char *addrs[] = { + ". . . .", "1.2.3.", "0.0.0.256", "255.255.255.256", + "................................................", + "a.b.c.d", "0x0.0x1.0x2.0x3", "-1.-1.-1.-1", "", " "}; + + struct in_addr ia; + const char *ian; + in_addr_t addr; + size_t i; + + for (i = 0; i < __arraycount(addrs); i++) { + + (void)fprintf(stderr, "checking %s\n", addrs[i]);; + + addr = inet_addr(addrs[i]); + ia.s_addr = addr; + ian = inet_ntoa(ia); + + ATF_REQUIRE(ian != NULL); + ATF_CHECK(strcmp(ian, addrs[i]) != 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, inet_addr_basic); + ATF_TP_ADD_TC(tp, inet_addr_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c b/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c new file mode 100644 index 0000000..c44fe11 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c @@ -0,0 +1,110 @@ +/* $NetBSD: t_inet_network.c,v 1.4 2015/04/09 16:47:56 ginsbach Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Brian Ginsbach. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_inet_network.c,v 1.4 2015/04/09 16:47:56 ginsbach Exp $"); + +#include + +#include + +#define H_REQUIRE(input, expected) \ + ATF_REQUIRE_EQ_MSG(inet_network(input), (in_addr_t) expected, \ + "inet_network(%s) returned: 0x%08X, expected: %s", #input, \ + inet_network(input), #expected) + +ATF_TC(inet_network_basic); +ATF_TC_HEAD(inet_network_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks inet_network(3)"); +} + +ATF_TC_BODY(inet_network_basic, tc) +{ + + H_REQUIRE("0x12", 0x00000012); + H_REQUIRE("127.1", 0x00007f01); + H_REQUIRE("127.1.2.3", 0x7f010203); + H_REQUIRE("0X12", 0x00000012); + H_REQUIRE("0", 0x0); + H_REQUIRE("01.02.07.077", 0x0102073f); + H_REQUIRE("0x1.23.045.0", 0x01172500); + H_REQUIRE("0x12.0x34", 0x00001234); + + /* This is valid (because of the trailing space after the digit). */ + H_REQUIRE("1 bar", 0x00000001); +} + +ATF_TC(inet_network_err); +ATF_TC_HEAD(inet_network_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Invalid addresses w/ inet_network(3)"); +} + +ATF_TC_BODY(inet_network_err, tc) +{ + /* Malformed requests. */ + H_REQUIRE("4.2.3.1.", 0xffffffff); + H_REQUIRE("0x123456", 0xffffffff); + H_REQUIRE("0x12.0x345", 0xffffffff); + H_REQUIRE("1.2.3.4.5", 0xffffffff); + H_REQUIRE("1..3.4", 0xffffffff); + H_REQUIRE(".", 0xffffffff); + H_REQUIRE("1.", 0xffffffff); + H_REQUIRE(".1", 0xffffffff); +#if defined(__FreeBSD__) || defined(__APPLE__) + H_REQUIRE("0x", 0x0); +#else + H_REQUIRE("0x", 0xffffffff); +#endif + H_REQUIRE("", 0xffffffff); + H_REQUIRE(" ", 0xffffffff); + H_REQUIRE("bar", 0xffffffff); + H_REQUIRE("1.2bar", 0xffffffff); + H_REQUIRE("1.", 0xffffffff); + H_REQUIRE("\xc3\x8a\xc3\x83\xc3\x95\xc3\x8b\xc3\x85\xc3\x8e", + 0xffffffff); + H_REQUIRE("255.255.255.255", 0xffffffff); + H_REQUIRE("x", 0xffffffff); + H_REQUIRE("078", 0xffffffff); + H_REQUIRE("127.0xfff", 0xffffffff); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, inet_network_basic); + ATF_TP_ADD_TC(tp, inet_network_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_io.c b/contrib/netbsd-tests/lib/libc/locale/t_io.c new file mode 100644 index 0000000..8c7f371 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_io.c @@ -0,0 +1,189 @@ +/* $NetBSD: t_io.c,v 1.4 2014/01/21 00:32:16 yamt Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_io.c,v 1.4 2014/01/21 00:32:16 yamt Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include + + +ATF_TC(bad_big5_wprintf); +ATF_TC_HEAD(bad_big5_wprintf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar wprintf"); +} + +ATF_TC_BODY(bad_big5_wprintf, tc) +{ +#ifdef __FreeBSD__ + atf_tc_skip("does not fail as expected (may be implementation " + "specific issue with the test)"); +#endif + /* XXX implementation detail knowledge (wchar_t encoding) */ + wchar_t ibuf[] = { 0xcf10, 0 }; + setlocale(LC_CTYPE, "zh_TW.Big5"); + ATF_REQUIRE_ERRNO(EILSEQ, wprintf(L"%ls\n", ibuf) < 0); + ATF_REQUIRE(ferror(stdout)); +} + +ATF_TC(bad_big5_swprintf); +ATF_TC_HEAD(bad_big5_swprintf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar swprintf"); +} + +ATF_TC_BODY(bad_big5_swprintf, tc) +{ +#ifdef __FreeBSD__ + atf_tc_skip("does not fail as expected (may be implementation " + "specific issue with the test)"); +#endif + /* XXX implementation detail knowledge (wchar_t encoding) */ + wchar_t ibuf[] = { 0xcf10, 0 }; + wchar_t obuf[20]; + setlocale(LC_CTYPE, "zh_TW.Big5"); + ATF_REQUIRE_ERRNO(EILSEQ, + swprintf(obuf, sizeof(obuf), L"%ls\n", ibuf) < 0); +} + +ATF_TC(good_big5_wprintf); +ATF_TC_HEAD(good_big5_wprintf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test good big5 wchar wprintf"); +} + +ATF_TC_BODY(good_big5_wprintf, tc) +{ + /* XXX implementation detail knowledge (wchar_t encoding) */ + wchar_t ibuf[] = { 0xcf40, 0 }; + setlocale(LC_CTYPE, "zh_TW.Big5"); + ATF_REQUIRE_EQ(wprintf(L"%ls\n", ibuf), 2); +} + +ATF_TC(good_big5_swprintf); +ATF_TC_HEAD(good_big5_swprintf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test good big5 wchar swprintf"); +} + +ATF_TC_BODY(good_big5_swprintf, tc) +{ + /* XXX implementation detail knowledge (wchar_t encoding) */ + wchar_t ibuf[] = { 0xcf40, 0 }; + wchar_t obuf[20]; + setlocale(LC_CTYPE, "zh_TW.Big5"); + ATF_REQUIRE_EQ(swprintf(obuf, sizeof(obuf), L"%ls\n", ibuf), 2); +} + +struct ibuf { + off_t off; + size_t buflen; + const char *buf; +}; + +static int +readfn(void *vp, char *buf, int len) +{ + struct ibuf *ib = vp; + size_t todo = MIN((size_t)len, ib->buflen - ib->off); + + memcpy(buf, ib->buf + ib->off, todo); + ib->off += todo; + return todo; +} + +ATF_TC(good_big5_getwc); +ATF_TC_HEAD(good_big5_getwc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test good big5 wchar getwc"); +} + +ATF_TC_BODY(good_big5_getwc, tc) +{ + const char buf[] = { 0xcf, 0x40 }; + struct ibuf ib = { + .buf = buf, + .buflen = sizeof(buf), + }; + FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL); + + ATF_REQUIRE(fp != NULL); + setlocale(LC_CTYPE, "zh_TW.Big5"); + /* XXX implementation detail knowledge (wchar_t encoding) */ + ATF_REQUIRE_EQ(getwc(fp), 0xcf40); + fclose(fp); +} + +ATF_TC(bad_big5_getwc); +ATF_TC_HEAD(bad_big5_getwc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar getwc"); +} + +ATF_TC_BODY(bad_big5_getwc, tc) +{ + const char buf[] = { 0xcf, 0x20 }; + struct ibuf ib = { + .buf = buf, + .buflen = sizeof(buf), + }; + FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL); + + ATF_REQUIRE(fp != NULL); + setlocale(LC_CTYPE, "zh_TW.Big5"); +#ifdef __FreeBSD__ + atf_tc_expect_fail("does not return WEOF as expected"); +#endif + ATF_REQUIRE_EQ(getwc(fp), WEOF); + fclose(fp); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, bad_big5_wprintf); + ATF_TP_ADD_TC(tp, bad_big5_swprintf); + ATF_TP_ADD_TC(tp, good_big5_wprintf); + ATF_TP_ADD_TC(tp, good_big5_swprintf); + ATF_TP_ADD_TC(tp, good_big5_getwc); + ATF_TP_ADD_TC(tp, bad_big5_getwc); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c new file mode 100644 index 0000000..e521110 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c @@ -0,0 +1,275 @@ +/* $NetBSD: t_mbrtowc.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by YAMAMOTO Takashi + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mbrtowc.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SIZE 256 + +static struct test { + const char *locale; + const char *data; + const wchar_t wchars[64]; + const wchar_t widths[64]; + size_t length; +} tests[] = { +{ + "C", + "ABCD01234_\\", + { 0x41, 0x42, 0x43, 0x44, 0x30, 0x31, 0x32, 0x33, 0x34, 0x5F, 0x5C }, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + 11 +}, { + "en_US.UTF-8", + "[\001\177][\302\200\337\277][\340\240\200\357\277\277][\360\220\200" + "\200\364\217\277\277]", + { 0x5b, 0x01, 0x7f, 0x5d, 0x5b, 0x80, 0x7ff, 0x5d, 0x5b, 0x800, 0xffff, + 0x5d, 0x5b, 0x10000, 0x10ffff, 0x5d }, + { 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 3, 1, 1, 4, 4, 1 }, + 16 +}, { + "ja_JP.ISO2022-JP2", + "\033$BF|K\1348l\033(BA\033$B$\"\033(BB\033$B$$\033(B", + { 0x4200467c, 0x42004b5c, 0x4200386c, 0x41, 0x42002422, 0x42, 0x42002424 }, + { 5, 2, 2, 4, 5, 4, 5 }, + 7 +}, { + "ja_JP.SJIS", + "\223\372\226{\214\352A\202\240B\202\242", + { 0x93fa, 0x967b, 0x8cea, 0x41, 0x82a0, 0x42, 0x82a2 }, + { 2, 2, 2, 1, 2, 1, 2 }, + 7 +}, { + "ja_JP.eucJP", + "\306\374\313\334\270\354A\244\242B\244\244", + { 0xc6fc, 0xcbdc, 0xb8ec, 0x41, 0xa4a2, 0x42, 0xa4a4 }, + { 2, 2, 2, 1, 2, 1, 2 }, + 7 +}, { + NULL, + NULL, + { }, + { }, + 0 +} +}; + +static void +h_ctype2(const struct test *t, bool use_mbstate) +{ + mbstate_t *stp; + mbstate_t st; + char buf[SIZE]; + char *str; + size_t n; + + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); +#ifdef __NetBSD__ + ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); +#else + if (setlocale(LC_CTYPE, t->locale) == NULL) { + fprintf(stderr, "Locale %s not found.\n", t->locale); + return; + } +#endif + + (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking string: \"%s\"\n", buf); + + ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); + (void)printf("Using locale: %s\n", str); + + (void)printf("Using mbstate: %s\n", use_mbstate ? "yes" : "no"); + + (void)memset(&st, 0, sizeof(st)); +// mbrtowc(0, 0, 0, &st); /* XXX for ISO2022-JP */ + stp = use_mbstate ? &st : 0; + + for (n = 9; n > 0; n--) { + const char *src = t->data; + wchar_t dst; + size_t nchar = 0; + int width = 0; + + ATF_REQUIRE(mbsinit(stp) != 0); + + for (;;) { + size_t rv = mbrtowc(&dst, src, n, stp); + + if (rv == 0) + break; + + if (rv == (size_t)-2) { + src += n; + width += n; + + continue; + } + if (rv == (size_t)-1) { + ATF_REQUIRE_EQ(errno, EILSEQ); + atf_tc_fail("Invalid sequence"); + /* NOTREACHED */ + } + + width += rv; + src += rv; + + if (dst != t->wchars[nchar] || + width != t->widths[nchar]) { + (void)printf("At position %zd:\n", nchar); + (void)printf(" expected: 0x%04X (%u)\n", + t->wchars[nchar], t->widths[nchar]); + (void)printf(" got : 0x%04X (%u)\n", + dst, width); + atf_tc_fail("Test failed"); + } + + nchar++; + width = 0; + } + + ATF_REQUIRE_EQ_MSG(dst, 0, "Incorrect terminating character: " + "0x%04X (expected: 0x00)", dst); + + ATF_REQUIRE_EQ_MSG(nchar, t->length, "Incorrect length: " + "%zd (expected: %zd)", nchar, t->length); + } + + { + wchar_t wbuf[SIZE]; + size_t rv; + char const *src = t->data; + int i; + + (void)memset(wbuf, 0xFF, sizeof(wbuf)); + + rv = mbsrtowcs(wbuf, &src, SIZE, stp); + + ATF_REQUIRE_EQ_MSG(rv, t->length, "Incorrect length: %zd " + "(expected: %zd)", rv, t->length); + ATF_REQUIRE_EQ(src, NULL); + + for (i = 0; wbuf[i] != 0; ++i) { + if (wbuf[i] == t->wchars[i]) + continue; + + (void)printf("At position %d:\n", i); + (void)printf(" expected: 0x%04X\n", t->wchars[i]); + (void)printf(" got : 0x%04X\n", wbuf[i]); + atf_tc_fail("Test failed"); + } + + ATF_REQUIRE_EQ_MSG((size_t)i, t->length, "Incorrect length: " + "%d (expected: %zd)", i, t->length); + } + + (void)printf("Ok.\n"); +} + +ATF_TC(mbrtowc_internal); +ATF_TC_HEAD(mbrtowc_internal, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks mbrtowc(3) and mbsrtowcs(3) (using internal " + "state) with different locales"); +} +ATF_TC_BODY(mbrtowc_internal, tc) +{ + struct test *t; + +#ifdef __FreeBSD__ + atf_tc_expect_fail("ja_* locale fails"); +#endif + for (t = &tests[0]; t->data != NULL; ++t) + h_ctype2(t, false); +} + +ATF_TC(mbrtowc_object); +ATF_TC_HEAD(mbrtowc_object, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks mbrtowc(3) and mbsrtowcs(3) (using state " + "object) with different locales"); +} +ATF_TC_BODY(mbrtowc_object, tc) +{ + struct test *t; + + for (t = &tests[0]; t->data != NULL; ++t) + h_ctype2(t, true); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mbrtowc_internal); + ATF_TP_ADD_TC(tp, mbrtowc_object); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c b/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c new file mode 100644 index 0000000..446d7ef --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c @@ -0,0 +1,98 @@ +/* $NetBSD: t_mbsnrtowcs.c,v 1.2 2014/05/06 00:41:26 yamt Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_mbsnrtowcs.c,v 1.2 2014/05/06 00:41:26 yamt Exp $"); + +#include +#include +#include + +#include + +static const struct test { + const char *locale; + const char *data; + size_t limit; + const wchar_t output1[64]; + size_t output1_len; + const wchar_t output2[64]; + size_t output2_len; +} tests[] = { + { "C", "ABCD0123", 4, { 0x41, 0x42, 0x43, 0x44 }, 4, + { 0x30, 0x31, 0x32, 0x33, 0x0 }, 5 }, + { "en_US.UTF-8", "ABCD0123", 4, { 0x41, 0x42, 0x43, 0x44 }, 4, + { 0x30, 0x31, 0x32, 0x33, 0x0 }, 5 }, + { "en_US.UTF-8", "ABC\303\2440123", 4, { 0x41, 0x42, 0x43, }, 3, + { 0xe4, 0x30, 0x31, 0x32, 0x33, 0x0 }, 6 }, +}; + +ATF_TC(mbsnrtowcs); +ATF_TC_HEAD(mbsnrtowcs, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks mbsnrtowc(3) with different locales"); +} +ATF_TC_BODY(mbsnrtowcs, tc) +{ + size_t i; + const struct test *t; + mbstate_t state; + wchar_t buf[64]; + const char *src; + size_t len; + + for (i = 0; i < __arraycount(tests); ++i) { + t = &tests[i]; + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); + ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); + memset(&state, 0, sizeof(state)); + src = t->data; + len = mbsnrtowcs(buf, &src, t->limit, + __arraycount(buf), &state); + ATF_REQUIRE_EQ(src, t->data + t->limit); + ATF_REQUIRE_EQ(len, t->output1_len); + ATF_REQUIRE(wmemcmp(t->output1, buf, len) == 0); + len = mbsnrtowcs(buf, &src, strlen(src) + 1, + __arraycount(buf), &state); + ATF_REQUIRE_EQ(len, strlen(t->data) - t->limit); + ATF_REQUIRE(wmemcmp(t->output2, buf, len + 1) == 0); + ATF_REQUIRE_EQ(src, NULL); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mbsnrtowcs); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c new file mode 100644 index 0000000..716a881 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c @@ -0,0 +1,211 @@ +/* $NetBSD: t_mbstowcs.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mbstowcs.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define REQUIRE_ERRNO(x, v) \ + ATF_REQUIRE_MSG((x) != (v), "%s: %s", #x, strerror(errno)) + +#define SIZE 256 + +static struct test { + const char *locale; + const char *data; + wchar_t wchars[64]; + int widths[64]; + int width; +} tests[] = { +{ + "en_US.UTF-8", + "[\001\177][\302\200\337\277][\340\240\200\357\277\277][\360\220\200" + "\200\364\217\277\277]", + { + 0x5B, 0x01, 0x7F, 0x5D, 0x5B, 0x80, 0x07FF, 0x5D, 0x5B, 0x0800, + 0xFFFF, 0x5D, 0x5B, 0x10000, 0x10FFFF, 0x5D, 0x0A + }, +#ifdef __FreeBSD__ + { 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, +#else + { 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, +#endif + 1, 1, -1, -1, 1, 1, -1, -1, 1, -1 + }, + -1 +}, { + "ja_JP.ISO2022-JP", + "\033$B#J#I#S$G$9!#\033(Baaaa\033$B$\"$$$&$($*\033(B", + { + 0x4200234A, 0x42002349, 0x42002353, 0x42002447, 0x42002439, + 0x42002123, 0x61, 0x61, 0x61, 0x61, 0x42002422, 0x42002424, + 0x42002426, 0x42002428, 0x4200242A, 0x0A + }, + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 }, + 26 +}, { + "ja_JP.SJIS", + "\202r\202i\202h\202r\202\305\202\267\201Baaaa\202\240\202\242" + "\202\244\202\246\202\250", + { + 0x8272, 0x8269, 0x8268, 0x8272, 0x82C5, 0x82B7, 0x8142, 0x61, + 0x61, 0x61, 0x61, 0x82A0, 0x82A2, 0x82A4, 0x82A6, 0x82A8, 0x0A + }, + { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 }, + 28 +}, { + "ja_JP.eucJP", + "\243\305\243\325\243\303\244\307\244\271\241\243aaaa\244\242\244" + "\244\244\246\244\250\244\252", + { + 0xA3C5, 0xA3D5, 0xA3C3, 0xA4C7, 0xA4B9, 0xA1A3, 0x61, 0x61, 0x61, + 0x61, 0xA4A2, 0xA4A4, 0xA4A6, 0xA4A8, 0xA4AA, 0x0A + }, + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 }, + 26 +}, { + NULL, + NULL, + {}, + {}, + 0 +} +}; + +ATF_TC(mbstowcs_basic); +ATF_TC_HEAD(mbstowcs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks wide character functions with different locales"); +} +ATF_TC_BODY(mbstowcs_basic, tc) +{ + struct test *t; + + for (t = &tests[0]; t->data != NULL; ++t) { + wchar_t wbuf[SIZE]; + char buf[SIZE]; + char visbuf[SIZE]; + char *str; + int i; + + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); +#ifdef __NetBSD__ + ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); +#else + if (setlocale(LC_CTYPE, t->locale) == NULL) { + fprintf(stderr, "Locale %s not found.\n", t->locale); + continue; + } +#endif + + (void)strvis(visbuf, t->data, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking string: \"%s\"\n", visbuf); + + ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); + (void)printf("Using locale: %s\n", str); + + REQUIRE_ERRNO((ssize_t)mbstowcs(wbuf, t->data, SIZE-1), -1); + REQUIRE_ERRNO((ssize_t)wcstombs(buf, wbuf, SIZE-1), -1); + + if (strcmp(buf, t->data) != 0) { + (void)strvis(visbuf, buf, VIS_WHITE | VIS_OCTAL); + (void)printf("Conversion to wcs and back failed: " + "\"%s\"\n", visbuf); + atf_tc_fail("Test failed"); + } + + /* The output here is implementation-dependent. */ + + for (i = 0; wbuf[i] != 0; ++i) { + if (wbuf[i] == t->wchars[i] && + wcwidth(wbuf[i]) == t->widths[i]) + continue; + + (void)printf("At position %d:\n", i); + (void)printf(" expected: 0x%04X (%d)\n", + t->wchars[i], t->widths[i]); + (void)printf(" got : 0x%04X (%d)\n", wbuf[i], + wcwidth(wbuf[i])); + atf_tc_fail("Test failed"); + } + + if (wcswidth(wbuf, SIZE-1) != t->width) { + (void)printf("Incorrect wcswidth:\n"); + (void)printf(" expected: %d\n", t->width); + (void)printf(" got : %d\n", wcswidth(wbuf, SIZE-1)); + atf_tc_fail("Test failed"); + } + + (void)printf("Ok.\n"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mbstowcs_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c new file mode 100644 index 0000000..e366344 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c @@ -0,0 +1,150 @@ +/* $NetBSD: t_mbtowc.c,v 1.1 2011/04/09 17:45:25 pgoyette Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c)2007 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mbtowc.c,v 1.1 2011/04/09 17:45:25 pgoyette Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +static void +h_mbtowc(const char *locale, const char *illegal, const char *legal) +{ + char buf[64]; + size_t stateful, ret; + char *str; + + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); +#ifdef __NetBSD__ + ATF_REQUIRE(setlocale(LC_CTYPE, locale) != NULL); +#else + if (setlocale(LC_CTYPE, locale) == NULL) { + fprintf(stderr, "Locale %s not found.\n", locale); + return; + } +#endif + + ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); + (void)printf("Using locale: %s\n", str); + + stateful = wctomb(NULL, L'\0'); + (void)printf("Locale is state-%sdependent\n", + stateful ? "in" : ""); + + /* initialize internal state */ + ret = mbtowc(NULL, NULL, 0); + ATF_REQUIRE(stateful ? ret : !ret); + + (void)strvis(buf, illegal, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking illegal sequence: \"%s\"\n", buf); + + ret = mbtowc(NULL, illegal, strlen(illegal)); + (void)printf("mbtowc() returned: %zd\n", ret); + ATF_REQUIRE_EQ(ret, (size_t)-1); + (void)printf("errno: %s\n", strerror(errno)); + ATF_REQUIRE_EQ(errno, EILSEQ); + + /* if this is stateless encoding, this re-initialization is not required. */ + if (stateful) { + /* re-initialize internal state */ + ret = mbtowc(NULL, NULL, 0); + ATF_REQUIRE(stateful ? ret : !ret); + } + + /* valid multibyte sequence case */ + (void)strvis(buf, legal, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking legal sequence: \"%s\"\n", buf); + + errno = 0; + ret = mbtowc(NULL, legal, strlen(legal)); + (void)printf("mbtowc() returned: %zd\n", ret); + ATF_REQUIRE(ret != (size_t)-1); + (void)printf("errno: %s\n", strerror(errno)); + ATF_REQUIRE_EQ(errno, 0); + + (void)printf("Ok.\n"); +} + +ATF_TC(mbtowc); +ATF_TC_HEAD(mbtowc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mbtowc(3)"); +} +ATF_TC_BODY(mbtowc, tc) +{ + h_mbtowc("en_US.UTF-8", "\240", "\302\240"); + h_mbtowc("ja_JP.ISO2022-JP", "\033$B", "\033$B$\"\033(B"); + h_mbtowc("ja_JP.SJIS", "\202", "\202\240"); + h_mbtowc("ja_JP.eucJP", "\244", "\244\242"); + h_mbtowc("zh_CN.GB18030", "\241", "\241\241"); + h_mbtowc("zh_TW.Big5", "\241", "\241@"); + h_mbtowc("zh_TW.eucTW", "\241", "\241\241"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mbtowc); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c b/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c new file mode 100644 index 0000000..10756b5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c @@ -0,0 +1,58 @@ +/* $NetBSD: t_wcscspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_wcscspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include +#include + +ATF_TC(wcscspn); +ATF_TC_HEAD(wcscspn, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test wcscspn(3)"); +} + +ATF_TC_BODY(wcscspn, tc) +{ + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L""), 16); + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"a"), 0); + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"b"), 1); + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"cd"), 2); + ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"qrstuvwxyz"), 16); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, wcscspn); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c b/contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c new file mode 100644 index 0000000..57c1ac5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c @@ -0,0 +1,62 @@ +/* $NetBSD: t_wcspbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_wcspbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include +#include + +ATF_TC(wcspbrk); +ATF_TC_HEAD(wcspbrk, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test wcspbrk(3)"); +} + +ATF_TC_BODY(wcspbrk, tc) +{ + static const wchar_t s[] = L"abcdefghijklmnop"; + + ATF_CHECK_EQ(wcspbrk(s, L""), NULL); + ATF_CHECK_EQ(wcspbrk(s, L"qrst"), NULL); + ATF_CHECK_EQ(wcspbrk(s, L"a"), s); + ATF_CHECK_EQ(wcspbrk(s, L"b"), s + 1); + ATF_CHECK_EQ(wcspbrk(s, L"ab"), s); + ATF_CHECK_EQ(wcspbrk(s, L"cdef"), s + 2); + ATF_CHECK_EQ(wcspbrk(s, L"fedc"), s + 2); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, wcspbrk); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c b/contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c new file mode 100644 index 0000000..2083650 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c @@ -0,0 +1,60 @@ +/* $NetBSD: t_wcsspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_wcsspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include +#include + +ATF_TC(wcsspn); +ATF_TC_HEAD(wcsspn, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test wcsspn(3)"); +} + +ATF_TC_BODY(wcsspn, tc) +{ + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L""), 0); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"a"), 1); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"b"), 0); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"ab"), 2); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"abc"), 3); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"abce"), 3); + ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"abcdefghijklmnop"), 16); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, wcsspn); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c b/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c new file mode 100644 index 0000000..8d1ef33 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c @@ -0,0 +1,460 @@ +/* $NetBSD: t_wcstod.c,v 1.3 2011/10/01 17:56:11 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c)2005 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_wcstod.c,v 1.3 2011/10/01 17:56:11 christos Exp $"); + +#include +#include +#include +#include +#include + +#include + +#ifdef __FreeBSD__ +#include +#endif + +#define ALT_HUGE_VAL -1 +#define ALT_MINUS_HUGE_VAL -2 +#define ALT_NAN -3 + +#if !defined(__vax__) +static struct test { + const wchar_t *wcs; + size_t len; + double val; + int err; +} tests[] = { +{ L"IN", 0, 0, 0 }, +{ L"+IN", 0, 0, 0 }, +{ L"-IN", 0, 0, 0 }, +{ L"INX", 0, 0, 0 }, +{ L"+INX", 0, 0, 0 }, +{ L"-INX", 0, 0, 0 }, +{ L"INF", 3, ALT_HUGE_VAL, 0 }, +{ L"+INF", 4, ALT_HUGE_VAL, 0 }, +{ L"-INF", 4, ALT_MINUS_HUGE_VAL, 0 }, +{ L"INFX", 3, ALT_HUGE_VAL, 0 }, +{ L"+INFX", 4, ALT_HUGE_VAL, 0 }, +{ L"-INFX", 4, ALT_MINUS_HUGE_VAL, 0 }, +{ L" IN", 0, 0, 0 }, +{ L" +IN", 0, 0, 0 }, +{ L" -IN", 0, 0, 0 }, +{ L" INX", 0, 0, 0 }, +{ L" +INX", 0, 0, 0 }, +{ L" -INX", 0, 0, 0 }, +{ L"+ INF", 0, 0, 0 }, +{ L"- INF", 0, 0, 0 }, +{ L" INF", 8, ALT_HUGE_VAL, 0 }, +{ L" +INF", 9, ALT_HUGE_VAL, 0 }, +{ L" -INF", 9, ALT_MINUS_HUGE_VAL, 0 }, +{ L" INFX", 8, ALT_HUGE_VAL, 0 }, +{ L" +INFX", 9, ALT_HUGE_VAL, 0 }, +{ L" -INFX", 9, ALT_MINUS_HUGE_VAL, 0 }, +{ L" INFINIT", 8, ALT_HUGE_VAL, 0 }, +{ L" +INFINIT", 9, ALT_HUGE_VAL, 0 }, +{ L" -INFINIT", 9, ALT_MINUS_HUGE_VAL, 0 }, +{ L" INFINITY", 13, ALT_HUGE_VAL, 0 }, +{ L" +INFINITY", 14, ALT_HUGE_VAL, 0 }, +{ L" -INFINITY", 14, ALT_MINUS_HUGE_VAL, 0 }, +{ L" INFINITYX", 13, ALT_HUGE_VAL, 0 }, +{ L" +INFINITYX", 14, ALT_HUGE_VAL, 0 }, +{ L" -INFINITYX", 14, ALT_MINUS_HUGE_VAL, 0 }, + +/* NAN */ +{ L"NA", 0, 0, 0 }, +{ L"+NA", 0, 0, 0 }, +{ L"-NA", 0, 0, 0 }, +{ L"NAX", 0, 0, 0 }, +{ L"+NAX", 0, 0, 0 }, +{ L"-NAX", 0, 0, 0 }, +{ L"NAN", 3, ALT_NAN, 0 }, +{ L"+NAN", 4, ALT_NAN, 0 }, +{ L"-NAN", 4, ALT_NAN, 0 }, +{ L"NANX", 3, ALT_NAN, 0 }, +{ L"+NANX", 4, ALT_NAN, 0 }, +{ L"-NANX", 4, ALT_NAN, 0 }, +{ L" NA", 0, 0, 0 }, +{ L" +NA", 0, 0, 0 }, +{ L" -NA", 0, 0, 0 }, +{ L" NAX", 0, 0, 0 }, +{ L" +NAX", 0, 0, 0 }, +{ L" -NAX", 0, 0, 0 }, +{ L"+ NAN", 0, 0, 0 }, +{ L"- NAN", 0, 0, 0 }, +{ L" NAN", 8, ALT_NAN, 0 }, +{ L" +NAN", 9, ALT_NAN, 0 }, +{ L" -NAN", 9, ALT_NAN, 0 }, +{ L" NANX", 8, ALT_NAN, 0 }, +{ L" +NANX", 9, ALT_NAN, 0 }, +{ L" -NANX", 9, ALT_NAN, 0 }, + +{ L"0", 1, 0, 0 }, +{ L"+0", 2, 0, 0 }, +{ L"-0", 2, 0, 0 }, +{ L" 0", 11, 0, 0 }, +{ L" +0", 12, 0, 0 }, +{ L" -0", 12, 0, 0 }, +{ L"+ 0", 0, 0, 0 }, +{ L"- 0", 0, 0, 0 }, + +{ L".", 0, 0, 0 }, +{ L".0", 2, 0, 0 }, +{ L".00", 3, 0, 0 }, +{ L".000", 4, 0, 0 }, + +{ L"0.", 2, 0, 0 }, +{ L"+0.", 3, 0, 0 }, +{ L"-0.", 3, 0, 0 }, +{ L" 0.", 12, 0, 0 }, +{ L" +0.", 13, 0, 0 }, +{ L" -0.", 13, 0, 0 }, + +{ L"0.0", 3, 0, 0 }, +{ L"+0.0", 4, 0, 0 }, +{ L"-0.0", 4, 0, 0 }, +{ L" 0.0", 13, 0, 0 }, +{ L" +0.0", 14, 0, 0 }, +{ L" -0.0", 14, 0, 0 }, + +{ L"000", 3, 0, 0 }, +{ L"+000", 4, 0, 0 }, +{ L"-000", 4, 0, 0 }, +{ L" 000", 13, 0, 0 }, +{ L" +000", 14, 0, 0 }, +{ L" -000", 14, 0, 0 }, + +{ L"000.", 4, 0, 0 }, +{ L"+000.", 5, 0, 0 }, +{ L"-000.", 5, 0, 0 }, +{ L" 000.", 14, 0, 0 }, +{ L" +000.", 15, 0, 0 }, +{ L" -000.", 15, 0, 0 }, + +{ L"000.0", 5, 0, 0 }, +{ L"+000.0", 6, 0, 0 }, +{ L"-000.0", 6, 0, 0 }, +{ L" 000.0", 15, 0, 0 }, +{ L" +000.0", 16, 0, 0 }, +{ L" -000.0", 16, 0, 0 }, + + +{ L"0.0.", 3, 0, 0 }, +{ L"+0.0.", 4, 0, 0 }, +{ L"-0.0.", 4, 0, 0 }, +{ L" 0.0.", 13, 0, 0 }, +{ L" +0.0.", 14, 0, 0 }, +{ L" -0.0.", 14, 0, 0 }, + +{ L"0.0.0", 3, 0, 0 }, +{ L"+0.0.0", 4, 0, 0 }, +{ L"-0.0.0", 4, 0, 0 }, +{ L" 0.0.0", 13, 0, 0 }, +{ L" +0.0.0", 14, 0, 0 }, +{ L" -0.0.0", 14, 0, 0 }, + +/* XXX: FIXME */ +#if defined(__linux__) +{ L"0X", 2, 0, 0 }, +{ L"+0X", 3, 0, 0 }, +{ L"-0X", 3, 0, 0 }, +#else +{ L"0X", 1, 0, 0 }, +{ L"+0X", 2, 0, 0 }, +{ L"-0X", 2, 0, 0 }, +#endif + +/* XXX: SunOS 5.8's wcstod(3) doesn't accept hex */ +#if !defined(__SunOS__) +#if defined(__linux__) +{ L"0X.", 3, 0, 0 }, +{ L"+0X.", 4, 0, 0 }, +{ L"-0X.", 4, 0, 0 }, +{ L" 0X.", 13, 0, 0 }, +{ L" +0X.", 14, 0, 0 }, +{ L" -0X.", 14, 0, 0 }, +#else +{ L"0X.", 1, 0, 0 }, +{ L"+0X.", 2, 0, 0 }, +{ L"-0X.", 2, 0, 0 }, +{ L" 0X.", 11, 0, 0 }, +{ L" +0X.", 12, 0, 0 }, +{ L" -0X.", 12, 0, 0 }, +#endif +/* XXX: FIXME */ +#if defined(__NetBSD__) || defined(__linux__) || defined(__FreeBSD__) +{ L"0X.0", 4, 0, 0 }, +{ L"+0X.0", 5, 0, 0 }, +{ L"-0X.0", 5, 0, 0 }, +{ L" 0X.0", 14, 0, 0 }, +{ L" +0X.0", 15, 0, 0 }, +{ L" -0X.0", 15, 0, 0 }, + +{ L"0X.0P", 4, 0, 0 }, +{ L"+0X.0P", 5, 0, 0 }, +{ L"-0X.0P", 5, 0, 0 }, +{ L" 0X.0P", 14, 0, 0 }, +{ L" +0X.0P", 15, 0, 0 }, +{ L" -0X.0P", 15, 0, 0 }, +#else +{ L"0X.0", 1, 0, 0 }, +{ L"+0X.0", 2, 0, 0 }, +{ L"-0X.0", 2, 0, 0 }, +{ L" 0X.0", 11, 0, 0 }, +{ L" +0X.0", 12, 0, 0 }, +{ L" -0X.0", 12, 0, 0 }, + +{ L"0X.0P", 1, 0, 0 }, +{ L"+0X.0P", 2, 0, 0 }, +{ L"-0X.0P", 2, 0, 0 }, +{ L" 0X.0P", 11, 0, 0 }, +{ L" +0X.0P", 12, 0, 0 }, +{ L" -0X.0P", 12, 0, 0 }, +#endif + +{ L"0X0", 3, 0, 0 }, +{ L"+0X0", 4, 0, 0 }, +{ L"-0X0", 4, 0, 0 }, +{ L" 0X0", 13, 0, 0 }, +{ L" +0X0", 14, 0, 0 }, +{ L" -0X0", 14, 0, 0 }, + +{ L"00X0.0", 2, 0, 0 }, +{ L"+00X0.0", 3, 0, 0 }, +{ L"-00X0.0", 3, 0, 0 }, +{ L" 00X0.0", 12, 0, 0 }, +{ L" +00X0.0", 13, 0, 0 }, +{ L" -00X0.0", 13, 0, 0 }, + +{ L"0X0P", 3, 0, 0 }, +{ L"+0X0P", 4, 0, 0 }, +{ L"-0X0P", 4, 0, 0 }, +{ L" 0X0P", 13, 0, 0 }, +{ L" +0X0P", 14, 0, 0 }, +{ L" -0X0P", 14, 0, 0 }, + +{ L"0X0.", 4, 0, 0 }, +{ L"+0X0.", 5, 0, 0 }, +{ L"-0X0.", 5, 0, 0 }, +{ L" 0X0.", 14, 0, 0 }, +{ L" +0X0.", 15, 0, 0 }, +{ L" -0X0.", 15, 0, 0 }, + +{ L"0X0.0", 5, 0, 0 }, +{ L"+0X0.0", 6, 0, 0 }, +{ L"-0X0.0", 6, 0, 0 }, +{ L" 0X0.0", 15, 0, 0 }, +{ L" +0X0.0", 16, 0, 0 }, +{ L" -0X0.0", 16, 0, 0 }, + +{ L"0X0.P", 4, 0, 0 }, +{ L"+0X0.P", 5, 0, 0 }, +{ L"-0X0.P", 5, 0, 0 }, +{ L" 0X0.P", 14, 0, 0 }, +{ L" +0X0.P", 15, 0, 0 }, +{ L" -0X0.P", 15, 0, 0 }, + +{ L"0X0.P", 4, 0, 0 }, +{ L"+0X0.P", 5, 0, 0 }, +{ L"-0X0.P", 5, 0, 0 }, +{ L" 0X0.P", 14, 0, 0 }, +{ L" +0X0.P", 15, 0, 0 }, +{ L" -0X0.P", 15, 0, 0 }, + +#endif +{ L"0.12345678", 10, 0.12345678, 0 }, +{ L"+0.12345678", 11, +0.12345678, 0 }, +{ L"-0.12345678", 11, -0.12345678, 0 }, +{ L" 0.12345678", 15, 0.12345678, 0 }, +{ L" +0.12345678", 16, +0.12345678, 0 }, +{ L" -0.12345678", 16, -0.12345678, 0 }, + +{ L"0.12345E67", 10, 0.12345E67, 0 }, +{ L"+0.12345E67", 11, +0.12345E67, 0 }, +{ L"-0.12345E67", 11, -0.12345E67, 0 }, +{ L" 0.12345E67", 15, 0.12345E67, 0 }, +{ L" +0.12345E67", 16, +0.12345E67, 0 }, +{ L" -0.12345E67", 16, -0.12345E67, 0 }, + +{ L"0.12345E+6", 10, 0.12345E+6, 0 }, +{ L"+0.12345E+6", 11, +0.12345E+6, 0 }, +{ L"-0.12345E+6", 11, -0.12345E+6, 0 }, +{ L" 0.12345E+6", 15, 0.12345E+6, 0 }, +{ L" +0.12345E+6", 16, +0.12345E+6, 0 }, +{ L" -0.12345E+6", 16, -0.12345E+6, 0 }, + +{ L"0.98765E-4", 10, 0.98765E-4, 0 }, +{ L"+0.98765E-4", 11, +0.98765E-4, 0 }, +{ L"-0.98765E-4", 11, -0.98765E-4, 0 }, +{ L" 0.98765E-4", 15, 0.98765E-4, 0 }, +{ L" +0.98765E-4", 16, +0.98765E-4, 0 }, +{ L" -0.98765E-4", 16, -0.98765E-4, 0 }, + +{ L"12345678E9", 10, 12345678E9, 0 }, +{ L"+12345678E9", 11, +12345678E9, 0 }, +{ L"-12345678E9", 11, -12345678E9, 0 }, +{ L" 12345678E9", 15, 12345678E9, 0 }, +{ L" +12345678E9", 16, +12345678E9, 0 }, +{ L" -12345678E9", 16, -12345678E9, 0 }, + +/* XXX: SunOS 5.8's wcstod(3) doesn't accept hex */ +#if !defined(__SunOS__) +{ L"0x1P+2", 6, 4, 0 }, +{ L"+0x1P+2", 7, +4, 0 }, +{ L"-0x1P+2", 7, -4, 0 }, +{ L" 0x1P+2", 11, 4, 0 }, +{ L" +0x1P+2", 12, +4, 0 }, +{ L" -0x1P+2", 12, -4, 0 }, + +{ L"0x1.0P+2", 8, 4, 0 }, +{ L"+0x1.0P+2", 9, +4, 0 }, +{ L"-0x1.0P+2", 9, -4, 0 }, +{ L" 0x1.0P+2", 13, 4, 0 }, +{ L" +0x1.0P+2", 14, +4, 0 }, +{ L" -0x1.0P+2", 14, -4, 0 }, + +{ L"0x1P-2", 6, 0.25, 0 }, +{ L"+0x1P-2", 7, +0.25, 0 }, +{ L"-0x1P-2", 7, -0.25, 0 }, +{ L" 0x1P-2", 11, 0.25, 0 }, +{ L" +0x1P-2", 12, +0.25, 0 }, +{ L" -0x1P-2", 12, -0.25, 0 }, + +{ L"0x1.0P-2", 8, 0.25, 0 }, +{ L"+0x1.0P-2", 9, +0.25, 0 }, +{ L"-0x1.0P-2", 9, -0.25, 0 }, +{ L" 0x1.0P-2", 13, 0.25, 0 }, +{ L" +0x1.0P-2", 14, +0.25, 0 }, +{ L" -0x1.0P-2", 14, -0.25, 0 }, +#endif + +{ NULL, 0, 0, 0 } +}; +#endif /* !defined(__vax__) */ + +ATF_TC(wcstod); +ATF_TC_HEAD(wcstod, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks wcstod(3)"); +} +ATF_TC_BODY(wcstod, tc) +{ +#if defined(__vax__) +#else + struct test *t; +#endif + +#if !defined(__vax__) + for (t = &tests[0]; t->wcs != NULL; ++t) { + double d; + size_t n; + wchar_t *tail; + char *buf; + + /* we do not supported %ls nor %S yet. */ + n = wcstombs(NULL, t->wcs, 0); + ATF_REQUIRE((buf = (void *)malloc(n + 1)) != NULL); + (void)wcstombs(buf, t->wcs, n + 1); + (void)printf("Checking wcstod(\"%s\", &tail):\n", buf); + free(buf); + + errno = 0; + d = wcstod(t->wcs, &tail); + (void)printf("[errno]\n"); + (void)printf(" got : %s\n", strerror(errno)); + (void)printf(" expected: %s\n", strerror(t->err)); + ATF_REQUIRE_EQ(errno, t->err); + + n = (size_t)(tail - t->wcs); + (void)printf("[endptr - nptr]\n"); + (void)printf(" got : %zd\n", n); + (void)printf(" expected: %zd\n", t->len); + ATF_REQUIRE_EQ(n, t->len); + + (void)printf("[result]\n"); + (void)printf(" real: %F\n", d); + if (t->val == ALT_HUGE_VAL) { + (void)printf(" expected: %F\n", HUGE_VAL); + ATF_REQUIRE(isinf(d)); + ATF_REQUIRE_EQ(d, HUGE_VAL); + } else if (t->val == ALT_MINUS_HUGE_VAL) { + (void)printf(" expected: %F\n", -HUGE_VAL); + ATF_REQUIRE(isinf(d)); + ATF_REQUIRE_EQ(d, -HUGE_VAL); + } else if (t->val == ALT_NAN) { + (void)printf(" expected: %F\n", NAN); + ATF_REQUIRE(isnan(d)); + } else { + (void)printf(" expected: %F\n", t->val); + ATF_REQUIRE_EQ(d, t->val); + } + + (void)printf("\n"); + } +#else /* !defined(__vax__) */ + atf_tc_skip("Test is unavailable on vax."); +#endif /* !defined(__vax__) */ +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, wcstod); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c new file mode 100644 index 0000000..3405e97 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c @@ -0,0 +1,212 @@ +/* $NetBSD: t_wctomb.c,v 1.3 2013/03/25 15:31:03 gson Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c)2004 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_wctomb.c,v 1.3 2013/03/25 15:31:03 gson Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define TC_WCTOMB 0 +#define TC_WCRTOMB 1 +#define TC_WCRTOMB_ST 2 + +static struct test { + const char *locale; + const char *data; + size_t wclen; + size_t mblen[16]; +} tests[] = { +{ + "ja_JP.ISO2022-JP", + "\x1b$B" /* JIS X 0208-1983 */ + "\x46\x7c\x4b\x5c\x38\x6c" /* "nihongo" */ + "\x1b(B" /* ISO 646 */ + "ABC" + "\x1b(I" /* JIS X 0201 katakana */ + "\xb1\xb2\xb3" /* "aiu" */ + "\x1b(B", /* ISO 646 */ + 3 + 3 + 3, + { 3+2, 2, 2, 3+1, 1, 1, 3+1, 1, 1, 3+1 } +}, { + "C", + "ABC", + 3, + { 1, 1, 1, 1 } +}, { NULL, NULL, 0, { } } +}; + +static void +h_wctomb(const struct test *t, char tc) +{ + wchar_t wcs[16 + 2]; + char buf[128]; + char cs[MB_LEN_MAX]; + const char *pcs; + char *str; + mbstate_t st; + mbstate_t *stp = NULL; + size_t sz, ret, i; + + ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); +#ifdef __NetBSD__ + ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); +#else + if (setlocale(LC_CTYPE, t->locale) == NULL) { + fprintf(stderr, "Locale %s not found.\n", t->locale); + return; + } +#endif + + (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL); + (void)printf("Checking sequence: \"%s\"\n", buf); + + ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); + (void)printf("Using locale: %s\n", str); + + if (tc == TC_WCRTOMB_ST) { + (void)memset(&st, 0, sizeof(st)); + stp = &st; + } + + wcs[t->wclen] = L'X'; /* poison */ + pcs = t->data; + sz = mbsrtowcs(wcs, &pcs, t->wclen + 2, NULL); + ATF_REQUIRE_EQ_MSG(sz, t->wclen, "mbsrtowcs() returned: " + "%zu, expected: %zu", sz, t->wclen); + ATF_REQUIRE_EQ(wcs[t->wclen], 0); + + for (i = 0; i < t->wclen + 1; i++) { + if (tc == TC_WCTOMB) + ret = wctomb(cs, wcs[i]); + else + ret = wcrtomb(cs, wcs[i], stp); + + if (ret == t->mblen[i]) + continue; + + (void)printf("At position %zd:\n", i); + (void)printf(" expected: %zd\n", t->mblen[i]); + (void)printf(" got : %zd\n", ret); + atf_tc_fail("Test failed"); + /* NOTREACHED */ + } + + (void)printf("Ok.\n"); +} + +ATF_TC(wctomb); +ATF_TC_HEAD(wctomb, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks wctomb(3)"); +} +ATF_TC_BODY(wctomb, tc) +{ + struct test *t; + + (void)printf("Checking wctomb()\n"); + + for (t = &tests[0]; t->data != NULL; ++t) + h_wctomb(t, TC_WCTOMB); +} + +ATF_TC(wcrtomb_state); +ATF_TC_HEAD(wcrtomb_state, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks wcrtomb(3) (using state object)"); +} +ATF_TC_BODY(wcrtomb_state, tc) +{ + struct test *t; + + (void)printf("Checking wcrtomb() (with state object)\n"); + + for (t = &tests[0]; t->data != NULL; ++t) + h_wctomb(t, TC_WCRTOMB_ST); +} + +ATF_TC(wcrtomb); +ATF_TC_HEAD(wcrtomb, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks wcrtomb(3) (using internal state)"); +} +ATF_TC_BODY(wcrtomb, tc) +{ + struct test *t; + + (void)printf("Checking wcrtomb() (using internal state)\n"); + + for (t = &tests[0]; t->data != NULL; ++t) + h_wctomb(t, TC_WCRTOMB); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, wctomb); + ATF_TP_ADD_TC(tp, wcrtomb); + ATF_TP_ADD_TC(tp, wcrtomb_state); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/net/gen_ether_subr b/contrib/netbsd-tests/lib/libc/net/gen_ether_subr new file mode 100755 index 0000000..9f9b63c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/gen_ether_subr @@ -0,0 +1,25 @@ +#!/bin/sh + +awk ' +BEGIN { + print + print "#include " + print "#include " + print "#include " + print + print "#define ETHER_ADDR_LEN 6" + print + print "int ether_aton_r(u_char *dest, size_t len, const char *str);" + print +} +/^ether_aton_r/ { + print prevline + out = 1 +} +{ + if (out) print + else prevline = $0 +} +/^}$/ { + if (out) exit(0) +}' $1 >$2 diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/README b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/README new file mode 100644 index 0000000..e856fe7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/README @@ -0,0 +1,7 @@ +This test may fail if + + - your /etc/services file is not in sync with what this test expects + - your /etc/hosts file or DNS have unusual entries for "localhost" + (a duplicate "localhost 127.0.0.1" line in /etc/hosts for example) + +On kernels without IPv6 support some of the tests are skipped. diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp new file mode 100644 index 0000000..d2945f2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp @@ -0,0 +1,36 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv tftp +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv tftp +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv tftp +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv echo +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv echo +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv echo +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp new file mode 100644 index 0000000..0238f83 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp @@ -0,0 +1,42 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv tftp +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv tftp +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv tftp +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv echo +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv echo +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv echo +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c new file mode 100644 index 0000000..939fcdb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c @@ -0,0 +1,186 @@ +/* $NetBSD: h_gai.c,v 1.1 2011/01/12 02:58:40 pgoyette Exp $ */ + +/* + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, and 2002 WIDE Project. + * 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 project 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 PROJECT 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 PROJECT 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 +#include +#include +#include +#include + +#include +#include + +#include + +#include + +struct addrinfo ai; + +char host[NI_MAXHOST]; +char serv[NI_MAXSERV]; +int vflag = 0; + +static void usage(void); +static void print1(const char *, const struct addrinfo *, char *, char *); +int main(int, char *[]); + +static void +usage() +{ + fprintf(stderr, "usage: test [-f family] [-s socktype] [-p proto] [-DPRSv46] host serv\n"); +} + +static void +print1(const char *title, const struct addrinfo *res, char *h, char *s) +{ + const char *start, *end; + int error; + const int niflag = NI_NUMERICHOST; + + if (res->ai_addr) { + error = getnameinfo(res->ai_addr, res->ai_addr->sa_len, + host, sizeof(host), serv, sizeof(serv), + niflag); + h = host; + s = serv; + } else + error = 0; + + if (vflag) { + start = "\t"; + end = "\n"; + } else { + start = " "; + end = ""; + } + printf("%s%s", title, end); + printf("%sflags 0x%x%s", start, res->ai_flags, end); + printf("%sfamily %d%s", start, res->ai_family, end); + printf("%ssocktype %d%s", start, res->ai_socktype, end); + printf("%sprotocol %d%s", start, res->ai_protocol, end); + printf("%saddrlen %d%s", start, res->ai_addrlen, end); + if (error) + printf("%serror %d%s", start, error, end); + else { + printf("%shost %s%s", start, h, end); + printf("%sserv %s%s", start, s, end); + } +#if 0 + if (res->ai_canonname) + printf("%scname \"%s\"%s", start, res->ai_canonname, end); +#endif + if (!vflag) + printf("\n"); + +} + +int +main(int argc, char *argv[]) +{ + struct addrinfo *res; + int error, i; + char *p, *q; + extern int optind; + extern char *optarg; + int c; + char nbuf[10]; + + memset(&ai, 0, sizeof(ai)); + ai.ai_family = PF_UNSPEC; + ai.ai_flags |= AI_CANONNAME; + while ((c = getopt(argc, argv, "Df:p:PRs:Sv46")) != -1) { + switch (c) { + case 'D': + ai.ai_socktype = SOCK_DGRAM; + break; + case 'f': + ai.ai_family = atoi(optarg); + break; + case 'p': + ai.ai_protocol = atoi(optarg); + break; + case 'P': + ai.ai_flags |= AI_PASSIVE; + break; + case 'R': + ai.ai_socktype = SOCK_RAW; + break; + case 's': + ai.ai_socktype = atoi(optarg); + break; + case 'S': + ai.ai_socktype = SOCK_STREAM; + break; + case 'v': + vflag++; + break; + case '4': + ai.ai_family = PF_INET; + break; + case '6': + ai.ai_family = PF_INET6; + break; + default: + usage(); + exit(1); + } + } + argc -= optind; + argv += optind; + + if (argc != 2){ + usage(); + exit(1); + } + + p = *argv[0] ? argv[0] : NULL; + q = *argv[1] ? argv[1] : NULL; + + strncpy(nbuf, "(empty)", sizeof(nbuf)); + print1("arg:", &ai, p ? p : nbuf , q ? q : nbuf); + + error = getaddrinfo(p, q, &ai, &res); + if (error) { + printf("%s\n", gai_strerror(error)); + exit(1); + } + + i = 1; + do { + snprintf(nbuf, sizeof(nbuf), "ai%d:", i); + print1(nbuf, res, NULL, NULL); + + i++; + } while ((res = res->ai_next) != NULL); + printf("\n"); + + exit(0); +} diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp new file mode 100644 index 0000000..21059c7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp @@ -0,0 +1,38 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http +ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http +ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo +ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv echo +ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv echo + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp +ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv tftp +ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv tftp + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http +ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http + +arg: flags 0x2 family 0 socktype 1 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 2 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp new file mode 100644 index 0000000..7d30fea --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp @@ -0,0 +1,56 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http +ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo +ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp +ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http +ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http +ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv http +ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv http +ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http +ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo +ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv echo +ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv echo +ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv echo +ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv echo + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp +ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv tftp +ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv tftp +ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv tftp +ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv tftp + +arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv http +ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv http +ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http +ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http + +arg: flags 0x2 family 0 socktype 1 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 0 socktype 2 protocol 0 addrlen 0 host (empty) serv 80 +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp new file mode 100644 index 0000000..9de5c56 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp @@ -0,0 +1,14 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv (empty) +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv (empty) +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0 +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0 +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv (empty) +hostname nor servname provided, or not known diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp new file mode 100644 index 0000000..1df5663 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp @@ -0,0 +1,16 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv (empty) +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv (empty) +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0 +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0 +ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv 0 +ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv (empty) +hostname nor servname provided, or not known diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp new file mode 100644 index 0000000..d06d163 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp @@ -0,0 +1,4 @@ +arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host fe80::1%lo0 serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host fe80::1%lo0 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host fe80::1%lo0 serv http + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp new file mode 100644 index 0000000..bc850e0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp @@ -0,0 +1,13 @@ +arg: flags 0x2 family 0 socktype 3 protocol 0 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 2 socktype 3 protocol 0 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 2 socktype 3 protocol 59 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv 80 +servname not supported for ai_socktype +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv www +servname not supported for ai_socktype +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host ::1 serv (empty) +ai1: flags 0x2 family 24 socktype 3 protocol 59 addrlen 28 host ::1 serv 0 + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp new file mode 100644 index 0000000..a4f2fb8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp @@ -0,0 +1,15 @@ +arg: flags 0x2 family 0 socktype 3 protocol 0 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 24 socktype 3 protocol 0 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 2 socktype 3 protocol 0 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv (empty) +ai1: flags 0x2 family 24 socktype 3 protocol 59 addrlen 28 host ::1 serv 0 +ai2: flags 0x2 family 2 socktype 3 protocol 59 addrlen 16 host 127.0.0.1 serv 0 + +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv 80 +servname not supported for ai_socktype +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv www +servname not supported for ai_socktype +arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host ::1 serv (empty) +ai1: flags 0x2 family 24 socktype 3 protocol 59 addrlen 28 host ::1 serv 0 + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp new file mode 100644 index 0000000..1c0ce43 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp @@ -0,0 +1,6 @@ +arg: flags 0x2 family 2 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 24 socktype 0 protocol 0 addrlen 0 host localhost serv http +No address associated with hostname diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp new file mode 100644 index 0000000..e24036e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp @@ -0,0 +1,8 @@ +arg: flags 0x2 family 2 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http +ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http + +arg: flags 0x2 family 24 socktype 0 protocol 0 addrlen 0 host localhost serv http +ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http +ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http + diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh new file mode 100755 index 0000000..94a3c0b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh @@ -0,0 +1,198 @@ +# $NetBSD: t_getaddrinfo.sh,v 1.2 2011/06/15 07:54:32 jmmv Exp $ + +# +# Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, and 2002 WIDE Project. +# 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 project 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 PROJECT 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 PROJECT 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. +# + +check_output() +{ + if [ "$2" = "none" ] ; then + exp="${1}.exp" + elif [ "$2" = "hosts" ] ; then + # Determine if localhost has an IPv6 address or not + lcl=$( cat /etc/hosts | \ + sed -e 's/#.*$//' -e 's/[ ][ ]*/ /g' | \ + awk '/ localhost($| )/ {printf "%s ", $1}' ) + if [ "${lcl%*::*}" = "${lcl}" ] ; then + exp="${1}_v4.exp" + else + exp="${1}_v4v6.exp" + fi + elif [ "$2" = "ifconfig" ] ; then + lcl=$( ifconfig lo0 | grep inet6 ) + if [ -n "${lcl}" ] ; then + exp="${1}_v4v6.exp" + else + exp="${1}_v4.exp" + fi + else + atf_fail "Invalid family_match_type $2 requested." + fi + + cmp -s $(atf_get_srcdir)/data/${exp} out && return + diff -u $(atf_get_srcdir)/data/${exp} out && \ + atf_fail "Actual output does not match expected output" +} + +atf_test_case basic +basic_head() +{ + atf_set "descr" "Testing basic ones" +} +basic_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST ::1 http + $TEST 127.0.0.1 http + $TEST localhost http + $TEST ::1 tftp + $TEST 127.0.0.1 tftp + $TEST localhost tftp + $TEST ::1 echo + $TEST 127.0.0.1 echo + $TEST localhost echo ) > out 2>&1 + + check_output basics hosts +} + +atf_test_case specific +specific_head() +{ + atf_set "descr" "Testing specific address family" +} +specific_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST -4 localhost http + $TEST -6 localhost http ) > out 2>&1 + + check_output spec_fam hosts +} + +atf_test_case empty_hostname +empty_hostname_head() +{ + atf_set "descr" "Testing empty hostname" +} +empty_hostname_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST '' http + $TEST '' echo + $TEST '' tftp + $TEST '' 80 + $TEST -P '' http + $TEST -P '' echo + $TEST -P '' tftp + $TEST -P '' 80 + $TEST -S '' 80 + $TEST -D '' 80 ) > out 2>&1 + + check_output no_host ifconfig +} + +atf_test_case empty_servname +empty_servname_head() +{ + atf_set "descr" "Testing empty service name" +} +empty_servname_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST ::1 '' + $TEST 127.0.0.1 '' + $TEST localhost '' + $TEST '' '' ) > out 2>&1 + + check_output no_serv hosts +} + +atf_test_case sock_raw +sock_raw_head() +{ + atf_set "descr" "Testing raw socket" +} +sock_raw_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST -R -p 0 localhost '' + $TEST -R -p 59 localhost '' + $TEST -R -p 59 localhost 80 + $TEST -R -p 59 localhost www + $TEST -R -p 59 ::1 '' ) > out 2>&1 + + check_output sock_raw hosts +} + +atf_test_case unsupported_family +unsupported_family_head() +{ + atf_set "descr" "Testing unsupported family" +} +unsupported_family_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST -f 99 localhost '' ) > out 2>&1 + + check_output unsup_fam none +} + +atf_test_case scopeaddr +scopeaddr_head() +{ + atf_set "descr" "Testing scoped address format" +} +scopeaddr_body() +{ + TEST=$(atf_get_srcdir)/h_gai + + ( $TEST fe80::1%lo0 http +# IF=`ifconfig -a | grep -v '^ ' | \ +# sed -e 's/:.*//' | head -1 | awk '{print $1}'` +# $TEST fe80::1%$IF http + ) > out 2>&1 + + check_output scoped none +} + +atf_init_test_cases() +{ + atf_add_test_case basic + atf_add_test_case specific + atf_add_test_case empty_hostname + atf_add_test_case empty_servname + atf_add_test_case sock_raw + atf_add_test_case unsupported_family + atf_add_test_case scopeaddr +} diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp new file mode 100644 index 0000000..b6133c0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp @@ -0,0 +1,2 @@ +arg: flags 0x2 family 99 socktype 0 protocol 0 addrlen 0 host localhost serv (empty) +ai_family not supported diff --git a/contrib/netbsd-tests/lib/libc/net/h_dns_server.c b/contrib/netbsd-tests/lib/libc/net/h_dns_server.c new file mode 100644 index 0000000..a8f0caa --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_dns_server.c @@ -0,0 +1,415 @@ +/* $NetBSD: h_dns_server.c,v 1.4 2014/03/29 16:10:54 gson Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andreas Gustafsson. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * A minimal DNS server capable of providing canned answers to the + * specific queries issued by t_hostent.sh and nothing more. + */ + +#include +__RCSID("$NetBSD: h_dns_server.c,v 1.4 2014/03/29 16:10:54 gson Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#ifdef __NetBSD__ +#include +#endif + +#ifdef __FreeBSD__ +#include +#endif + +union sockaddr_either { + struct sockaddr s; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; +}; + +#ifdef DEBUG +#define DPRINTF(...) fprintf(stderr, __VA_ARGS__) +#else +#define DPRINTF(...) +#endif + +/* A DNS question and its corresponding answer */ + +struct dns_data { + size_t qname_size; + const char *qname; /* Wire-encode question name */ + int qtype; + size_t answer_size; + const char *answer; /* One wire-encoded answer RDATA */ +}; + +/* Convert C string constant to length + data pair */ +#define STR_DATA(s) sizeof(s) - 1, s + +/* Canned DNS queestion-answer pairs */ +struct dns_data data[] = { + /* Forward mappings */ + /* localhost IN A -> 127.0.0.1 */ + { STR_DATA("\011localhost\000"), 1, + STR_DATA("\177\000\000\001") }, + /* localhost IN AAAA -> ::1 */ + { STR_DATA("\011localhost\000"), 28, + STR_DATA("\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001") }, + /* sixthavenue.astron.com IN A -> 38.117.134.16 */ + { STR_DATA("\013sixthavenue\006astron\003com\000"), 1, + STR_DATA("\046\165\206\020") }, + /* sixthavenue.astron.com IN AAAA -> 2620:106:3003:1f00:3e4a:92ff:fef4:e180 */ + { STR_DATA("\013sixthavenue\006astron\003com\000"), 28, + STR_DATA("\x26\x20\x01\x06\x30\x03\x1f\x00\x3e\x4a\x92\xff\xfe\xf4\xe1\x80") }, + /* Reverse mappings */ + { STR_DATA("\0011\0010\0010\003127\007in-addr\004arpa\000"), 12, + STR_DATA("\011localhost\000") }, + { STR_DATA("\0011\0010\0010\0010\0010\0010\0010\0010" + "\0010\0010\0010\0010\0010\0010\0010\0010" + "\0010\0010\0010\0010\0010\0010\0010\0010" + "\0010\0010\0010\0010\0010\0010\0010\0010" + "\003ip6\004arpa\000"), 12, + STR_DATA("\011localhost\000") }, + { STR_DATA("\00216\003134\003117\00238" + "\007in-addr\004arpa\000"), 12, + STR_DATA("\013sixthavenue\006astron\003com\000") }, + { STR_DATA("\0010\0018\0011\001e\0014\001f\001e\001f" + "\001f\001f\0012\0019\001a\0014\001e\0013" + "\0010\0010\001f\0011\0013\0010\0010\0013" + "\0016\0010\0011\0010\0010\0012\0016\0012" + "\003ip6\004arpa\000"), 12, + STR_DATA("\013sixthavenue\006astron\003com\000") }, + /* End marker */ + { STR_DATA(""), 0, STR_DATA("") } +}; + +/* + * Compare two DNS names for equality. If equal, return their + * length, and if not, return zero. Does not handle compression. + */ +static int +name_eq(const unsigned char *a, const unsigned char *b) { + const unsigned char *a_save = a; + for (;;) { + int i; + int lena = *a++; + int lenb = *b++; + if (lena != lenb) + return 0; + if (lena == 0) + return a - a_save; + for (i = 0; i < lena; i++) + if (tolower(a[i]) != tolower(b[i])) + return 0; + a += lena; + b += lena; + } +} + +#ifdef DEBUG +static char * +name2str(const void *v, char *buf, size_t buflen) { + const unsigned char *a = v; + char *b = buf; + char *eb = buf + buflen; + +#define ADDC(c) do { \ + if (b < eb) \ + *b++ = c; \ + else \ + return NULL; \ + } while (/*CONSTCOND*/0) + for (int did = 0;; did++) { + int lena = *a++; + if (lena == 0) { + ADDC('\0'); + return buf; + } + if (did) + ADDC('.'); + for (int i = 0; i < lena; i++) + ADDC(a[i]); + a += lena; + } +} +#endif + +#ifdef __FreeBSD__ +/* XXX the daemon2_* functions should be in a library */ + +int __daemon2_detach_pipe[2]; + +static int +daemon2_fork(void) +{ + int r; + int fd; + int i; + + /* + * Set up the pipe, making sure the write end does not + * get allocated one of the file descriptors that will + * be closed in daemon2_detach(). + */ + for (i = 0; i < 3; i++) { + r = pipe(__daemon2_detach_pipe); + if (r < 0) + return -1; + if (__daemon2_detach_pipe[1] <= STDERR_FILENO && + (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)dup2(fd, __daemon2_detach_pipe[0]); + (void)dup2(fd, __daemon2_detach_pipe[1]); + if (fd > STDERR_FILENO) + (void)close(fd); + continue; + } + break; + } + + r = fork(); + if (r < 0) { + return -1; + } else if (r == 0) { + /* child */ + close(__daemon2_detach_pipe[0]); + return 0; + } + /* Parent */ + + (void) close(__daemon2_detach_pipe[1]); + + for (;;) { + char dummy; + r = read(__daemon2_detach_pipe[0], &dummy, 1); + if (r < 0) { + if (errno == EINTR) + continue; + _exit(1); + } else if (r == 0) { + _exit(1); + } else { /* r > 0 */ + _exit(0); + } + } +} + +static int +daemon2_detach(int nochdir, int noclose) +{ + int r; + int fd; + + if (setsid() == -1) + return -1; + + if (!nochdir) + (void)chdir("/"); + + if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)dup2(fd, STDIN_FILENO); + (void)dup2(fd, STDOUT_FILENO); + (void)dup2(fd, STDERR_FILENO); + if (fd > STDERR_FILENO) + (void)close(fd); + } + + while (1) { + r = write(__daemon2_detach_pipe[1], "", 1); + if (r < 0) { + if (errno == EINTR) + continue; + /* May get "broken pipe" here if parent is killed */ + return -1; + } else if (r == 0) { + /* Should not happen */ + return -1; + } else { + break; + } + } + + (void) close(__daemon2_detach_pipe[1]); + + return 0; +} +#endif + +int main(int argc, char **argv) { + int s, r, protocol; + union sockaddr_either saddr; + struct dns_data *dp; + unsigned char *p; + char pidfile_name[40]; + FILE *f; + int one = 1; +#ifdef DEBUG + char buf1[1024], buf2[1024]; +#endif + +#ifdef __FreeBSD__ + daemon2_fork(); +#endif + if (argc < 2 || ((protocol = argv[1][0]) != '4' && protocol != '6')) + errx(1, "usage: dns_server 4 | 6"); + s = socket(protocol == '4' ? PF_INET : PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (s < 0) + err(1, "socket"); + if (protocol == '4') { + memset(&saddr.sin, 0, sizeof(saddr.sin)); + saddr.sin.sin_family = AF_INET; + saddr.sin.sin_len = sizeof(saddr.sin); + saddr.sin.sin_port = htons(53); + saddr.sin.sin_addr.s_addr = INADDR_ANY; + } else { + static struct in6_addr loopback = IN6ADDR_LOOPBACK_INIT; + memset(&saddr.sin6, 0, sizeof(saddr.sin6)); + saddr.sin6.sin6_family = AF_INET6; + saddr.sin6.sin6_len = sizeof(saddr.sin6); + saddr.sin6.sin6_port = htons(53); + saddr.sin6.sin6_addr = loopback; + } + + r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one); + if (r < 0) + err(1, "setsockopt"); + + r = bind(s, + (struct sockaddr *) &saddr, + protocol == '4' ? sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6)); + if (r < 0) + err(1, "bind"); + + snprintf(pidfile_name, sizeof pidfile_name, + "dns_server_%c.pid", protocol); + f = fopen(pidfile_name, "w"); + fprintf(f, "%d", getpid()); + fclose(f); +#ifdef __FreeBSD__ +#ifdef DEBUG + daemon2_detach(0, 1); +#else + daemon2_detach(0, 0); +#endif +#else +#ifdef DEBUG + daemon(0, 1); +#else + daemon(0, 0); +#endif +#endif + + for (;;) { + unsigned char buf[512]; + union sockaddr_either from; + ssize_t nrecv, nsent; + socklen_t fromlen = + protocol == '4' ? sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6); + memset(buf, 0, sizeof buf); + nrecv = recvfrom(s, buf, sizeof buf, 0, &from.s, &fromlen); + if (nrecv < 0) + err(1, "recvfrom"); + if (nrecv < 12) { + DPRINTF("Too short %zd\n", nrecv); + continue; + } + if ((buf[2] & 0x80) != 0) { + DPRINTF("Not a query 0x%x\n", buf[2]); + continue; + } + if (!(buf[4] == 0 && buf[5] == 1)) { + DPRINTF("QCOUNT is not 1 0x%x 0x%x\n", buf[4], buf[5]); + continue; /* QDCOUNT is not 1 */ + } + + for (dp = data; dp->qname_size != 0; dp++) { + int qtype, qclass; + p = buf + 12; /* Point to QNAME */ + int n = name_eq(p, (const unsigned char *) dp->qname); + if (n == 0) { + DPRINTF("no match name %s != %s\n", + name2str(p, buf1, sizeof(buf1)), + name2str(dp->qname, buf2, sizeof(buf2))); + continue; /* Name does not match */ + } + DPRINTF("match name %s\n", + name2str(p, buf1, sizeof(buf1))); + p += n; /* Skip QNAME */ + qtype = *p++ << 8; + qtype |= *p++; + if (qtype != dp->qtype) { + DPRINTF("no match name 0x%x != 0x%x\n", + qtype, dp->qtype); + continue; + } + DPRINTF("match type 0x%x\n", qtype); + qclass = *p++ << 8; + qclass |= *p++; + if (qclass != 1) { /* IN */ + DPRINTF("no match class %d != 1\n", qclass); + continue; + } + DPRINTF("match class %d\n", qclass); + goto found; + } + continue; + found: + buf[2] |= 0x80; /* QR */ + buf[3] |= 0x80; /* RA */ + memset(buf + 6, 0, 6); /* Clear ANCOUNT, NSCOUNT, ARCOUNT */ + buf[7] = 1; /* ANCOUNT */ + memcpy(p, dp->qname, dp->qname_size); + p += dp->qname_size; + *p++ = dp->qtype >> 8; + *p++ = dp->qtype & 0xFF; + *p++ = 0; + *p++ = 1; /* IN */ + memset(p, 0, 4); /* TTL = 0 */ + p += 4; + *p++ = 0; /* RDLENGTH MSB */ + *p++ = dp->answer_size; /* RDLENGTH LSB */ + memcpy(p, dp->answer, dp->answer_size); + p += dp->answer_size; + nsent = sendto(s, buf, p - buf, 0, &from.s, fromlen); + DPRINTF("sent %zd\n", nsent); + if (nsent != p - buf) + warn("sendto"); + } +} diff --git a/contrib/netbsd-tests/lib/libc/net/h_hostent.c b/contrib/netbsd-tests/lib/libc/net/h_hostent.c new file mode 100644 index 0000000..4a72923 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_hostent.c @@ -0,0 +1,195 @@ +/* $NetBSD: h_hostent.c,v 1.2 2014/01/09 02:18:10 christos Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: h_hostent.c,v 1.2 2014/01/09 02:18:10 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "hostent.h" + +extern const char *__res_conf_name; + +static void +phostent(const struct hostent *h) +{ + size_t i; + char buf[1024]; + const int af = h->h_length == NS_INADDRSZ ? AF_INET : AF_INET6; + + printf("name=%s, length=%d, addrtype=%d, aliases=[", + h->h_name, h->h_length, h->h_addrtype); + + for (i = 0; h->h_aliases[i]; i++) + printf("%s%s", i == 0 ? "" : " ", h->h_aliases[i]); + + printf("] addr_list=["); + + for (i = 0; h->h_addr_list[i]; i++) + printf("%s%s", i == 0 ? "" : " ", inet_ntop(af, + h->h_addr_list[i], buf, (socklen_t)sizeof(buf))); + + printf("]\n"); +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage: %s [-f ] " + "[-t ] " + "[-46a] \n", getprogname()); + exit(EXIT_FAILURE); +} + +static void +getby(int (*f)(void *, void *, va_list), struct getnamaddr *info, ...) +{ + va_list ap; + int e; + + va_start(ap, info); + e = (*f)(info, NULL, ap); + va_end(ap); + switch (e) { + case NS_SUCCESS: + phostent(info->hp); + break; + default: + printf("error %d\n", e); + break; + } +} + +static void +geta(struct hostent *hp) { + if (hp == NULL) + printf("error %d\n", h_errno); + else + phostent(hp); +} + +int +main(int argc, char *argv[]) +{ + int (*f)(void *, void *, va_list) = NULL; + const char *type = "any"; + int c, af, e, byaddr, len; + struct hostent hent; + struct getnamaddr info; + char buf[4096]; + + af = AF_INET; + byaddr = 0; + len = 0; + info.hp = &hent; + info.buf = buf; + info.buflen = sizeof(buf); + info.he = &e; + + while ((c = getopt(argc, argv, "46af:r:t:")) != -1) { + switch (c) { + case '4': + af = AF_INET; + break; + case '6': + af = AF_INET6; + break; + case 'a': + byaddr++; + break; + case 'f': + _hf_sethostsfile(optarg); + break; + case 'r': + __res_conf_name = optarg; + break; + case 't': + type = optarg; + break; + default: + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + switch (*type) { + case 'a': + break; + case 'd': + f = byaddr ? _dns_gethtbyaddr : _dns_gethtbyname; + break; +#ifdef YP + case 'n': + f = byaddr ? _yp_gethtbyaddr : _yp_gethtbyname; + break; +#endif + case 'f': + f = byaddr ? _hf_gethtbyaddr : _hf_gethtbyname; + break; + default: + errx(EXIT_FAILURE, "Unknown db type `%s'", type); + } + + if (byaddr) { + struct in6_addr addr; + af = strchr(*argv, ':') ? AF_INET6 : AF_INET; + len = af == AF_INET ? NS_INADDRSZ : NS_IN6ADDRSZ; + if (inet_pton(af, *argv, &addr) == -1) + err(EXIT_FAILURE, "Can't parse `%s'", *argv); + if (*type == 'a') + geta(gethostbyaddr((const char *)&addr, len, af)); + else + getby(f, &info, &addr, len, af); + } else { + if (*type == 'a') + geta(gethostbyname2(*argv, af)); + else + getby(f, &info, *argv, len, af); + } + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c b/contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c new file mode 100644 index 0000000..2f315d2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c @@ -0,0 +1,107 @@ +/* $NetBSD: h_nsd_recurse.c,v 1.2 2011/01/13 02:24:51 pgoyette Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_nsd_recurse.c,v 1.2 2011/01/13 02:24:51 pgoyette Exp $"); + +#define _REENTRANT + +#include +#include +#include +#include +#include +#include + +static const ns_src testsrc[] = { + { "test", NS_SUCCESS }, + { NULL, 0 } +}; + +static int +func3(void *rv, void *cb_data, va_list ap) +{ + (void)printf("func3: enter\n"); + (void)printf("func3: exit\n"); + + return NS_SUCCESS; +} + +static int +func2(void *rv, void *cb_data, va_list ap) +{ + static const ns_dtab dtab[] = { + { "test", func3, NULL }, + { NULL, NULL, NULL } + }; + int r; + + (void)printf("func2: enter\n"); + r = nsdispatch(NULL, dtab, "test", "test", testsrc); + (void)printf("func2: exit\n"); + + return r; +} + +static int +func1(void) +{ + static const ns_dtab dtab[] = { + { "test", func2, NULL }, + { NULL, NULL, NULL } + }; + int r; + + (void)printf("func1: enter\n"); + r = nsdispatch(NULL, dtab, "test", "test", testsrc); + (void)printf("func1: exit\n"); + + return r; +} + +static void * +thrfunc(void *arg) +{ + pthread_exit(NULL); +} + +int +main(int argc, char *argv[]) +{ + pthread_t thr; + void *threval; + + assert(pthread_create(&thr, NULL, thrfunc, NULL) == 0); + assert(func1() == NS_SUCCESS); + assert(pthread_join(thr, &threval) == 0); +} diff --git a/contrib/netbsd-tests/lib/libc/net/h_protoent.c b/contrib/netbsd-tests/lib/libc/net/h_protoent.c new file mode 100644 index 0000000..f37a85c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_protoent.c @@ -0,0 +1,97 @@ +/* $NetBSD: h_protoent.c,v 1.2 2011/04/07 18:14:09 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include + +static void +pserv(const struct protoent *prp) +{ + char **pp; + + printf("name=%s, proto=%d, aliases=", + prp->p_name, prp->p_proto); + for (pp = prp->p_aliases; *pp; pp++) + printf("%s ", *pp); + printf("\n"); +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage: %s\n" + "\t%s -p \n" + "\t%s -n \n", getprogname(), getprogname(), + getprogname()); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct protoent *prp; + const char *proto = NULL, *name = NULL; + int c; + + while ((c = getopt(argc, argv, "p:n:")) != -1) { + switch (c) { + case 'n': + name = optarg; + break; + case 'p': + proto = optarg; + break; + default: + usage(); + } + } + + if (proto && name) + usage(); + if (proto) { + if ((prp = getprotobynumber(atoi(proto))) != NULL) + pserv(prp); + return 0; + } + if (name) { + if ((prp = getprotobyname(name)) != NULL) + pserv(prp); + return 0; + } + + setprotoent(0); + while ((prp = getprotoent()) != NULL) + pserv(prp); + endprotoent(); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/net/h_servent.c b/contrib/netbsd-tests/lib/libc/net/h_servent.c new file mode 100644 index 0000000..6d7efd8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/h_servent.c @@ -0,0 +1,100 @@ +/* $NetBSD: h_servent.c,v 1.2 2011/04/07 18:14:09 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include + +static void +pserv(const struct servent *svp) +{ + char **pp; + + printf("name=%s, port=%d, proto=%s, aliases=", + svp->s_name, ntohs((uint16_t)svp->s_port), svp->s_proto); + for (pp = svp->s_aliases; *pp; pp++) + printf("%s ", *pp); + printf("\n"); +} + +static void +usage(void) +{ + (void)fprintf(stderr, "Usage: %s\n" + "\t%s -p [-P ]\n" + "\t%s -n [-P ]\n", getprogname(), getprogname(), + getprogname()); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct servent *svp; + const char *port = NULL, *proto = NULL, *name = NULL; + int c; + + while ((c = getopt(argc, argv, "p:n:P:")) != -1) { + switch (c) { + case 'n': + name = optarg; + break; + case 'p': + port = optarg; + break; + case 'P': + proto = optarg; + break; + default: + usage(); + } + } + + if (port && name) + usage(); + if (port) { + if ((svp = getservbyport(htons(atoi(port)), proto)) != NULL) + pserv(svp); + return 0; + } + if (name) { + if ((svp = getservbyname(name, proto)) != NULL) + pserv(svp); + return 0; + } + + setservent(0); + while ((svp = getservent()) != NULL) + pserv(svp); + endservent(); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/net/hosts b/contrib/netbsd-tests/lib/libc/net/hosts new file mode 100644 index 0000000..87ccbe8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/hosts @@ -0,0 +1,11 @@ +# $NetBSD: hosts,v 1.1 2013/08/16 15:29:45 christos Exp $ +# +# Host Database +# This file should contain the addresses and aliases +# for local hosts that share this file. +# It is used only for "ifconfig" and other operations +# before the nameserver is started. +# +# +::1 localhost localhost. localhost.localdomain. +127.0.0.1 localhost localhost. localhost.localdomain. diff --git a/contrib/netbsd-tests/lib/libc/net/resolv.conf b/contrib/netbsd-tests/lib/libc/net/resolv.conf new file mode 100644 index 0000000..bbc8559 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/resolv.conf @@ -0,0 +1 @@ +nameserver 127.0.0.1 diff --git a/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c b/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c new file mode 100644 index 0000000..2a91060 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c @@ -0,0 +1,137 @@ +/* $NetBSD: t_ether_aton.c,v 1.1 2011/11/01 22:36:53 pgoyette Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_ether_aton.c,v 1.1 2011/11/01 22:36:53 pgoyette Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#ifndef __NetBSD__ +#ifdef __linux__ +#include +#endif +#include +#endif + +#ifdef __NetBSD__ +#define ETHER_ADDR_LEN 6 + +int ether_aton_r(u_char *dest, size_t len, const char *str); +#endif + +static const struct { + u_char res[ETHER_ADDR_LEN]; + const char *str; + int error; +} tests[] = { + { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab }, "01:23:45:67:89:ab", 0 }, +#ifdef __NetBSD__ + { { 0x00, 0x01, 0x22, 0x03, 0x14, 0x05 }, "0:1:22-3:14:05", 0 }, + { { 0x00, 0x01, 0x22, 0x03, 0x14, 0x05 }, "000122031405", 0 }, + { { 0x0a, 0x0B, 0xcc, 0xdD, 0xEE, 0x0f }, "0a0BccdDEE0f", 0 }, +#endif +#define ZERO { 0, 0, 0, 0, 0, 0 } + { ZERO, "0:1:2-3:04:05:06", ENAMETOOLONG }, + { ZERO, "0:1:2-3:04:", ENOBUFS }, + { ZERO, "0:1:2-3:04:x7", EINVAL }, + { ZERO, "1:x-3:04:05:7", EINVAL }, + { ZERO, NULL, 0 }, +}; + +ATF_TC(tc_ether_aton); +ATF_TC_HEAD(tc_ether_aton, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that ether_aton(3) works"); +} + +ATF_TC_BODY(tc_ether_aton, tc) +{ +#ifdef __NetBSD__ + u_char dest[ETHER_ADDR_LEN]; +#else + struct ether_addr dest; +#endif + size_t t; +#ifdef __NetBSD__ + int e, r; +#else + int e; + struct ether_addr *r; +#endif + const char *s; + + for (t = 0; tests[t].str; t++) { + s = tests[t].str; + if ((e = tests[t].error) == 0) { +#ifdef __NetBSD__ + if (ether_aton_r(dest, sizeof(dest), s) != e) + atf_tc_fail("failed on `%s'", s); + if (memcmp(dest, tests[t].res, sizeof(dest)) != 0) + atf_tc_fail("unexpected result on `%s'", s); +#else + if (ether_aton_r(s, &dest) == NULL && e == 0) + atf_tc_fail("failed on `%s'", s); + if (memcmp(&dest, tests[t].res, sizeof(dest)) != 0) + atf_tc_fail("unexpected result on `%s'", s); +#endif + } else { +#ifdef __NetBSD__ + if ((r = ether_aton_r(dest, sizeof(dest), s)) != e) + atf_tc_fail("unexpectedly succeeded on `%s' " + "(%d != %d)", s, r, e); +#else + if ((r = ether_aton_r(s, &dest)) != NULL && e != 0) + atf_tc_fail("unexpectedly succeeded on `%s' " + "(%p != %d)", s, r, e); +#endif + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, tc_ether_aton); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c b/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c new file mode 100644 index 0000000..1c1a0e0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c @@ -0,0 +1,233 @@ +/* $NetBSD: t_getprotoent.c,v 1.2 2012/04/04 10:03:53 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_getprotoent.c,v 1.2 2012/04/04 10:03:53 joerg Exp $"); + +#include +#include +#include +#include +#include + +static const struct { + const char *name; + int number; +} protos[] = { + + { "icmp", 1 }, { "tcp", 6 }, { "udp", 17 }, { "gre", 47 }, + { "esp", 50 }, { "ah", 51 }, { "sctp", 132}, { "ipv6-icmp", 58 } +}; + +ATF_TC(endprotoent_rewind); +ATF_TC_HEAD(endprotoent_rewind, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that endprotoent(3) rewinds"); +} + +ATF_TC_BODY(endprotoent_rewind, tc) +{ + struct protoent *p; + int i = 0; + + setprotoent(0); + + while ((p = getprotoent()) != NULL && i <= 10) { + ATF_REQUIRE(p->p_proto == i); + i++; + } + + i = 0; + endprotoent(); + + while ((p = getprotoent()) != NULL && i <= 10) { + ATF_REQUIRE(p->p_proto == i); + i++; + } + + endprotoent(); +} + +ATF_TC(getprotobyname_basic); +ATF_TC_HEAD(getprotobyname_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of getprotobyname(3)"); +} + +ATF_TC_BODY(getprotobyname_basic, tc) +{ + struct protoent *p; + size_t i; + + for (i = 0; i < __arraycount(protos); i++) { + + p = getprotobyname(protos[i].name); + + ATF_REQUIRE(p != NULL); + ATF_REQUIRE(p->p_proto == protos[i].number); + ATF_REQUIRE(strcmp(p->p_name, protos[i].name) == 0); + } + + endprotoent(); +} + +ATF_TC(getprotobyname_err); +ATF_TC_HEAD(getprotobyname_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test EOF from getprotobyname(3)"); +} + +ATF_TC_BODY(getprotobyname_err, tc) +{ + static const char * name[] = + { "xxx", "yyy", "xyz", ".as.d}9x.._?!!#\xa4,\xa8^//&%%,", + "0", "", "tCp", "uDp", "t c p", "tcp ", " tcp" }; + + size_t i; + + for (i = 0; i < __arraycount(name); i++) + ATF_REQUIRE(getprotobyname(name[i]) == NULL); + + endprotoent(); +} + +ATF_TC(getprotobynumber_basic); +ATF_TC_HEAD(getprotobynumber_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of getprotobynumber(3)"); +} + +ATF_TC_BODY(getprotobynumber_basic, tc) +{ + struct protoent *p; + size_t i; + + /* + * No ATF_CHECK() due static storage. + */ + for (i = 0; i < __arraycount(protos); i++) { + + p = getprotobynumber(protos[i].number); + + ATF_REQUIRE(p != NULL); + ATF_REQUIRE(p->p_proto == protos[i].number); + ATF_REQUIRE(strcmp(p->p_name, protos[i].name) == 0); + } + + endprotoent(); +} + +ATF_TC(getprotobynumber_err); +ATF_TC_HEAD(getprotobynumber_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test EOF from getprotobynumber(3)"); +} + +ATF_TC_BODY(getprotobynumber_err, tc) +{ + static const int number[] = { -1, -99999, INT_MAX, 1000000000 }; + size_t i; + + for (i = 0; i < __arraycount(number); i++) + ATF_REQUIRE(getprotobynumber(number[i]) == NULL); + + endprotoent(); +} + +ATF_TC(getprotoent_next); +ATF_TC_HEAD(getprotoent_next, tc) +{ + atf_tc_set_md_var(tc, "descr", "getprotoent(3) returns next line?"); +} + +ATF_TC_BODY(getprotoent_next, tc) +{ + struct protoent *p; + int i = 0; + + /* + * The range [0, 60] is already reserved by IANA. + */ + while ((p = getprotoent()) != NULL && i <= 60) { + ATF_CHECK(p->p_proto == i); + i++; + } + + endprotoent(); +} + +ATF_TC(setprotoent_rewind); +ATF_TC_HEAD(setprotoent_rewind, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that setprotoent(3) rewinds"); +} + +ATF_TC_BODY(setprotoent_rewind, tc) +{ + struct protoent *p; + + setprotoent(0); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 0); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 1); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 2); + + setprotoent(0); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 0); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 1); + + p = getprotoent(); + ATF_REQUIRE(p->p_proto == 2); + + endprotoent(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getprotobyname_basic); + ATF_TP_ADD_TC(tp, getprotobyname_err); + ATF_TP_ADD_TC(tp, getprotobynumber_basic); + ATF_TP_ADD_TC(tp, getprotobynumber_err); + ATF_TP_ADD_TC(tp, endprotoent_rewind); + ATF_TP_ADD_TC(tp, getprotoent_next); + ATF_TP_ADD_TC(tp, setprotoent_rewind); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_hostent.sh b/contrib/netbsd-tests/lib/libc/net/t_hostent.sh new file mode 100755 index 0000000..b597b6d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_hostent.sh @@ -0,0 +1,240 @@ +# $NetBSD: t_hostent.sh,v 1.10 2014/01/13 11:08:14 gson Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +n6="sixthavenue.astron.com" +a6="2620:106:3003:1f00:3e4a:92ff:fef4:e180" +ans6="name=$n6, length=16, addrtype=24, aliases=[] addr_list=[$a6]\n" + +n4="sixthavenue.astron.com" +a4="38.117.134.16" +ans4="name=$n4, length=4, addrtype=2, aliases=[] addr_list=[$a4]\n" + +l6="localhost" +al6="::1" +loc6="name=$l6, length=16, addrtype=24, aliases=[localhost. localhost.localdomain.] addr_list=[$al6]\n" + +l4="localhost" +al4="127.0.0.1" +loc4="name=$l4, length=4, addrtype=2, aliases=[localhost. localhost.localdomain.] addr_list=[$al4]\n" + +dir="$(atf_get_srcdir)" +res="-r ${dir}/resolv.conf" + +# Hijack DNS traffic using a single rump server instance and a DNS +# server listening on its loopback address. + +start_dns_server() { + export RUMP_SERVER=unix:///tmp/rumpserver + rump_server -lrumpdev -lrumpnet -lrumpnet_net -lrumpnet_netinet \ + -lrumpnet_netinet6 -lrumpnet_local $RUMP_SERVER + HIJACK_DNS="LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK='socket=inet:inet6'" + eval $HIJACK_DNS ${dir}/h_dns_server $1 +} + +stop_dns_server() { + export RUMP_SERVER=unix:///tmp/rumpserver + kill $(cat dns_server_$1.pid) + rump.halt +} + +atf_test_case gethostbyname4 cleanup +gethostbyname4_head() +{ + atf_set "descr" "Checks gethostbyname2(3) for AF_INET (auto, as determined by nsswitch.conf(5)" +} +gethostbyname4_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -4 $n4" +} +gethostbyname4_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case gethostbyname6 cleanup cleanup +gethostbyname6_head() +{ + atf_set "descr" "Checks gethostbyname2(3) for AF_INET6 (auto, as determined by nsswitch.conf(5)" +} +gethostbyname6_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -6 $n6" +} +gethostbyname6_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case gethostbyaddr4 cleanup +gethostbyaddr4_head() +{ + atf_set "descr" "Checks gethostbyaddr(3) for AF_INET (auto, as determined by nsswitch.conf(5)" +} +gethostbyaddr4_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -a $a4" +} +gethostbyaddr4_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case gethostbyaddr6 cleanup +gethostbyaddr6_head() +{ + atf_set "descr" "Checks gethostbyaddr(3) for AF_INET6 (auto, as determined by nsswitch.conf(5)" +} +gethostbyaddr6_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -a $a6" +} +gethostbyaddr6_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case hostsbynamelookup4 +hostsbynamelookup4_head() +{ + atf_set "descr" "Checks /etc/hosts name lookup for AF_INET" +} +hostsbynamelookup4_body() +{ + atf_check -o inline:"$loc4" -x "${dir}/h_hostent -f ${dir}/hosts -t file -4 $l4" +} + +atf_test_case hostsbynamelookup6 +hostsbynamelookup6_head() +{ + atf_set "descr" "Checks /etc/hosts name lookup for AF_INET6" +} +hostsbynamelookup6_body() +{ + atf_check -o inline:"$loc6" -x "${dir}/h_hostent -f ${dir}/hosts -t file -6 $l6" +} + +atf_test_case hostsbyaddrlookup4 +hostsbyaddrlookup4_head() +{ + atf_set "descr" "Checks /etc/hosts address lookup for AF_INET" +} +hostsbyaddrlookup4_body() +{ + atf_check -o inline:"$loc4" -x "${dir}/h_hostent -f ${dir}/hosts -t file -4 -a $al4" +} + +atf_test_case hostsbyaddrlookup6 +hostsbyaddrlookup6_head() +{ + atf_set "descr" "Checks /etc/hosts address lookup for AF_INET6" +} +hostsbyaddrlookup6_body() +{ + atf_check -o inline:"$loc6" -x "${dir}/h_hostent -f ${dir}/hosts -t file -6 -a $al6" +} + +atf_test_case dnsbynamelookup4 cleanup +dnsbynamelookup4_head() +{ + atf_set "descr" "Checks DNS name lookup for AF_INET" +} +dnsbynamelookup4_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -4 $n4" +} +dnsbynamelookup4_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case dnsbynamelookup6 cleanup +dnsbynamelookup6_head() +{ + atf_set "descr" "Checks DNS name lookup for AF_INET6" +} +dnsbynamelookup6_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -6 $n6" +} +dnsbynamelookup6_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case dnsbyaddrlookup4 cleanup +dnsbyaddrlookup4_head() +{ + atf_set "descr" "Checks DNS address lookup for AF_INET" +} +dnsbyaddrlookup4_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -4 -a $a4" +} +dnsbyaddrlookup4_cleanup() +{ + stop_dns_server 4 +} + +atf_test_case dnsbyaddrlookup6 cleanup +dnsbyaddrlookup6_head() +{ + atf_set "descr" "Checks dns address lookup for AF_INET6" +} +dnsbyaddrlookup6_body() +{ + start_dns_server 4 + atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -6 -a $a6" +} +dnsbyaddrlookup6_cleanup() +{ + stop_dns_server 4 +} + +atf_init_test_cases() +{ + atf_add_test_case gethostbyname4 + atf_add_test_case gethostbyname6 + atf_add_test_case gethostbyaddr4 + atf_add_test_case gethostbyaddr6 + + atf_add_test_case hostsbynamelookup4 + atf_add_test_case hostsbynamelookup6 + atf_add_test_case hostsbyaddrlookup4 + atf_add_test_case hostsbyaddrlookup6 + + atf_add_test_case dnsbynamelookup4 + atf_add_test_case dnsbynamelookup6 + atf_add_test_case dnsbyaddrlookup4 + atf_add_test_case dnsbyaddrlookup6 +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh b/contrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh new file mode 100755 index 0000000..b584369 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh @@ -0,0 +1,51 @@ +# $NetBSD: t_nsdispatch.sh,v 1.1 2011/01/13 01:56:44 pgoyette Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case recurse +recurse_head() +{ + atf_set "descr" "Checks recursive calls to nsdispatch()" \ + "within threaded program" +} +recurse_body() +{ + cat >exp <exp + + # run test program + "$(atf_get_srcdir)/h_protoent" | sed 's/ *$//' | sort >out + + diff -u exp out || \ + atf_fail "Observed output does not match reference output" +} + +atf_init_test_cases() +{ + atf_add_test_case protoent +} diff --git a/contrib/netbsd-tests/lib/libc/net/t_servent.sh b/contrib/netbsd-tests/lib/libc/net/t_servent.sh new file mode 100755 index 0000000..4c23f00 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/net/t_servent.sh @@ -0,0 +1,113 @@ +# $NetBSD: t_servent.sh,v 1.2 2016/03/08 08:34:17 joerg Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case servent +servent_head() +{ + atf_set "descr" "Checks {get,set,end}servent(3)" + # libc doesn't include aliases + atf_set "require.files" "/var/db/services.cdb" +} +servent_body() +{ + # + # Munge original to: + # (1) match output format of the test program + # (2) fold all names for the same port/proto together + # (3) prune duplicates + # + tr '\t' ' ' exp + + case "$(uname)" in + FreeBSD) + # (3) Don't prune duplicates + tr '\t' ' ' < /etc/services | + sed 's/#.*//;s/ */ /g; /^$/d;s#\([0-9]\)/#\1 #;s/ *$//' | + sort | + while read l; do + set $l + name=$1; shift + port=$1; shift + proto=$1; shift + alias="$@" + printf "name=%s, port=%s, proto=%s, aliases=%s\n" \ + $name $port $proto "$alias" + done > exp + ;; + esac + + # run test program + "$(atf_get_srcdir)/h_servent" | sed 's/ *$//' | sort >out + + diff -u exp out || atf_fail "Observed output does not match reference output" +} + +atf_init_test_cases() +{ + atf_add_test_case servent +} diff --git a/contrib/netbsd-tests/lib/libc/regex/README b/contrib/netbsd-tests/lib/libc/regex/README new file mode 100644 index 0000000..6d9a28c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/README @@ -0,0 +1,33 @@ +regular expression test set +Lines are at least three fields, separated by one or more tabs. "" stands +for an empty field. First field is an RE. Second field is flags. If +C flag given, regcomp() is expected to fail, and the third field is the +error name (minus the leading REG_). + +Otherwise it is expected to succeed, and the third field is the string to +try matching it against. If there is no fourth field, the match is +expected to fail. If there is a fourth field, it is the substring that +the RE is expected to match. If there is a fifth field, it is a comma- +separated list of what the subexpressions should match, with - indicating +no match for that one. In both the fourth and fifth fields, a (sub)field +starting with @ indicates that the (sub)expression is expected to match +a null string followed by the stuff after the @; this provides a way to +test where null strings match. The character `N' in REs and strings +is newline, `S' is space, `T' is tab, `Z' is NUL. + +The full list of flags: + - placeholder, does nothing + b RE is a BRE, not an ERE + & try it as both an ERE and a BRE + C regcomp() error expected, third field is error name + i REG_ICASE + m ("mundane") REG_NOSPEC + s REG_NOSUB (not really testable) + n REG_NEWLINE + ^ REG_NOTBOL + $ REG_NOTEOL + # REG_STARTEND (see below) + p REG_PEND + +For REG_STARTEND, the start/end offsets are those of the substring +enclosed in (). diff --git a/contrib/netbsd-tests/lib/libc/regex/data/anchor.in b/contrib/netbsd-tests/lib/libc/regex/data/anchor.in new file mode 100644 index 0000000..d145408 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/anchor.in @@ -0,0 +1,33 @@ +# anchoring and REG_NEWLINE +^abc$ & abc abc +a^b - a^b +a^b b a^b a^b +a$b - a$b +a$b b a$b a$b +^ & abc @abc +$ & abc @ +^$ & "" @ +$^ - "" @ +\($\)\(^\) b "" @ +# stop retching, those are legitimate (although disgusting) +^^ - "" @ +$$ - "" @ +b$ & abNc +b$ &n abNc b +^b$ & aNbNc +^b$ &n aNbNc b +^$ &n aNNb @Nb +^$ n abc +^$ n abcN @ +$^ n aNNb @Nb +\($\)\(^\) bn aNNb @Nb +^^ n^ aNNb @Nb +$$ n aNNb @NN +^a ^ a +a$ $ a +^a ^n aNb +^b ^n aNb b +a$ $n bNa +b$ $n bNa b +a*(^b$)c* - b b +a*\(^b$\)c* b b b diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/README b/contrib/netbsd-tests/lib/libc/regex/data/att/README new file mode 100644 index 0000000..e2ee6f6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/README @@ -0,0 +1,8 @@ +AT&T test data from: http://www2.research.att.com/~gsf/testregex/ + +Quoting from the page: + testregex.c 2004-05-31 is the latest source for the AT&T Research + regression test harness for the X/Open regex pattern match interface. + See testregex(1) for option and test input details. The source and + test data posted here are license free. + diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat new file mode 100644 index 0000000..4399ca1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat @@ -0,0 +1,216 @@ +NOTE all standard compliant implementations should pass these : 2002-05-31 + +BE abracadabra$ abracadabracadabra (7,18) +BE a...b abababbb (2,7) +BE XXXXXX ..XXXXXX (2,8) +E \) () (1,2) +BE a] a]a (0,2) +B } } (0,1) +E \} } (0,1) +BE \] ] (0,1) +B ] ] (0,1) +E ] ] (0,1) +B { { (0,1) +B } } (0,1) +BE ^a ax (0,1) +BE \^a a^a (1,3) +BE a\^ a^ (0,2) +BE a$ aa (1,2) +BE a\$ a$ (0,2) +BE ^$ NULL (0,0) +E $^ NULL (0,0) +E a($) aa (1,2)(2,2) +E a*(^a) aa (0,1)(0,1) +E (..)*(...)* a (0,0) +E (..)*(...)* abcd (0,4)(2,4) +E (ab|a)(bc|c) abc (0,3)(0,2)(2,3) +E (ab)c|abc abc (0,3)(0,2) +E a{0}b ab (1,2) +E (a*)(b?)(b+)b{3} aaabbbbbbb (0,10)(0,3)(3,4)(4,7) +E (a*)(b{0,1})(b{1,})b{3} aaabbbbbbb (0,10)(0,3)(3,4)(4,7) +E a{9876543210} NULL BADBR +E ((a|a)|a) a (0,1)(0,1)(0,1) +E (a*)(a|aa) aaaa (0,4)(0,3)(3,4) +E a*(a.|aa) aaaa (0,4)(2,4) +E a(b)|c(d)|a(e)f aef (0,3)(?,?)(?,?)(1,2) +E (a|b)?.* b (0,1)(0,1) +E (a|b)c|a(b|c) ac (0,2)(0,1) +E (a|b)c|a(b|c) ab (0,2)(?,?)(1,2) +E (a|b)*c|(a|ab)*c abc (0,3)(1,2) +E (a|b)*c|(a|ab)*c xc (1,2) +E (.a|.b).*|.*(.a|.b) xa (0,2)(0,2) +E a?(ab|ba)ab abab (0,4)(0,2) +E a?(ac{0}b|ba)ab abab (0,4)(0,2) +E ab|abab abbabab (0,2) +E aba|bab|bba baaabbbaba (5,8) +E aba|bab baaabbbaba (6,9) +E (aa|aaa)*|(a|aaaaa) aa (0,2)(0,2) +E (a.|.a.)*|(a|.a...) aa (0,2)(0,2) +E ab|a xabc (1,3) +E ab|a xxabc (2,4) +Ei (Ab|cD)* aBcD (0,4)(2,4) +BE [^-] --a (2,3) +BE [a-]* --a (0,3) +BE [a-m-]* --amoma-- (0,4) +E :::1:::0:|:::1:1:0: :::0:::1:::1:::0: (8,17) +E :::1:::0:|:::1:1:1: :::0:::1:::1:::0: (8,17) +{E [[:upper:]] A (0,1) [[]] not supported +E [[:lower:]]+ `az{ (1,3) +E [[:upper:]]+ @AZ[ (1,3) +BE [[-]] [[-]] (2,4) +BE [[.NIL.]] NULL ECOLLATE +BE [[=aleph=]] NULL ECOLLATE +} +BE$ \n \n (0,1) +BEn$ \n \n (0,1) +BE$ [^a] \n (0,1) +BE$ \na \na (0,2) +E (a)(b)(c) abc (0,3)(0,1)(1,2)(2,3) +BE xxx xxx (0,3) +E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) feb 6, (0,6) +E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) 2/7 (0,3) +E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) feb 1,Feb 6 (5,11) +E3 ((((((((((((((((((((((((((((((x)))))))))))))))))))))))))))))) x (0,1)(0,1)(0,1) +E3 ((((((((((((((((((((((((((((((x))))))))))))))))))))))))))))))* xx (0,2)(1,2)(1,2) +E a?(ab|ba)* ababababababababababababababababababababababababababababababababababababababababa (0,81)(79,81) +E abaa|abbaa|abbbaa|abbbbaa ababbabbbabbbabbbbabbbbaa (18,25) +E abaa|abbaa|abbbaa|abbbbaa ababbabbbabbbabbbbabaa (18,22) +E aaac|aabc|abac|abbc|baac|babc|bbac|bbbc baaabbbabac (7,11) +BE$ .* \x01\xff (0,2) +E aaaa|bbbb|cccc|ddddd|eeeeee|fffffff|gggg|hhhh|iiiii|jjjjj|kkkkk|llll XaaaXbbbXcccXdddXeeeXfffXgggXhhhXiiiXjjjXkkkXlllXcbaXaaaa (53,57) +L aaaa\nbbbb\ncccc\nddddd\neeeeee\nfffffff\ngggg\nhhhh\niiiii\njjjjj\nkkkkk\nllll XaaaXbbbXcccXdddXeeeXfffXgggXhhhXiiiXjjjXkkkXlllXcbaXaaaa NOMATCH +E a*a*a*a*a*b aaaaaaaaab (0,10) +BE ^ NULL (0,0) +BE $ NULL (0,0) +BE ^$ NULL (0,0) +BE ^a$ a (0,1) +BE abc abc (0,3) +BE abc xabcy (1,4) +BE abc ababc (2,5) +BE ab*c abc (0,3) +BE ab*bc abc (0,3) +BE ab*bc abbc (0,4) +BE ab*bc abbbbc (0,6) +E ab+bc abbc (0,4) +E ab+bc abbbbc (0,6) +E ab?bc abbc (0,4) +E ab?bc abc (0,3) +E ab?c abc (0,3) +BE ^abc$ abc (0,3) +BE ^abc abcc (0,3) +BE abc$ aabc (1,4) +BE ^ abc (0,0) +BE $ abc (3,3) +BE a.c abc (0,3) +BE a.c axc (0,3) +BE a.*c axyzc (0,5) +BE a[bc]d abd (0,3) +BE a[b-d]e ace (0,3) +BE a[b-d] aac (1,3) +BE a[-b] a- (0,2) +BE a[b-] a- (0,2) +BE a] a] (0,2) +BE a[]]b a]b (0,3) +BE a[^bc]d aed (0,3) +BE a[^-b]c adc (0,3) +BE a[^]b]c adc (0,3) +E ab|cd abc (0,2) +E ab|cd abcd (0,2) +E a\(b a(b (0,3) +E a\(*b ab (0,2) +E a\(*b a((b (0,4) +E ((a)) abc (0,1)(0,1)(0,1) +E (a)b(c) abc (0,3)(0,1)(2,3) +E a+b+c aabbabc (4,7) +E a* aaa (0,3) +E (a*)* - (0,0)(0,0) +E (a*)+ - (0,0)(0,0) +E (a*|b)* - (0,0)(0,0) +E (a+|b)* ab (0,2)(1,2) +E (a+|b)+ ab (0,2)(1,2) +E (a+|b)? ab (0,1)(0,1) +BE [^ab]* cde (0,3) +E (^)* - (0,0)(0,0) +BE a* NULL (0,0) +E ([abc])*d abbbcd (0,6)(4,5) +E ([abc])*bcd abcd (0,4)(0,1) +E a|b|c|d|e e (0,1) +E (a|b|c|d|e)f ef (0,2)(0,1) +E ((a*|b))* - (0,0)(0,0)(0,0) +BE abcd*efg abcdefg (0,7) +BE ab* xabyabbbz (1,3) +BE ab* xayabbbz (1,2) +E (ab|cd)e abcde (2,5)(2,4) +BE [abhgefdc]ij hij (0,3) +E (a|b)c*d abcd (1,4)(1,2) +E (ab|ab*)bc abc (0,3)(0,1) +E a([bc]*)c* abc (0,3)(1,3) +E a([bc]*)(c*d) abcd (0,4)(1,3)(3,4) +E a([bc]+)(c*d) abcd (0,4)(1,3)(3,4) +E a([bc]*)(c+d) abcd (0,4)(1,2)(2,4) +E a[bcd]*dcdcde adcdcde (0,7) +E (ab|a)b*c abc (0,3)(0,2) +E ((a)(b)c)(d) abcd (0,4)(0,3)(0,1)(1,2)(3,4) +BE [A-Za-z_][A-Za-z0-9_]* alpha (0,5) +E ^a(bc+|b[eh])g|.h$ abh (1,3) +E (bc+d$|ef*g.|h?i(j|k)) effgz (0,5)(0,5) +E (bc+d$|ef*g.|h?i(j|k)) ij (0,2)(0,2)(1,2) +E (bc+d$|ef*g.|h?i(j|k)) reffgz (1,6)(1,6) +E (((((((((a))))))))) a (0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1) +BE multiple words multiple words yeah (0,14) +E (.*)c(.*) abcde (0,5)(0,2)(3,5) +BE abcd abcd (0,4) +E a(bc)d abcd (0,4)(1,3) +E a[-]?c ac (0,3) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Qaddafi (0,15)(?,?)(10,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mo'ammar Gadhafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Kaddafi (0,15)(?,?)(10,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Qadhafi (0,15)(?,?)(10,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Gadafi (0,14)(?,?)(10,11) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mu'ammar Qadafi (0,15)(?,?)(11,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moamar Gaddafi (0,14)(?,?)(9,11) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mu'ammar Qadhdhafi (0,18)(?,?)(13,15) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Khaddafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghaddafy (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghadafi (0,15)(?,?)(11,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghaddafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muamar Kaddafi (0,14)(?,?)(9,11) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Quathafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Gheddafi (0,16)(?,?)(11,13) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moammar Khadafy (0,15)(?,?)(11,12) +E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moammar Qudhafi (0,15)(?,?)(10,12) +E a+(b|c)*d+ aabcdd (0,6)(3,4) +E ^.+$ vivi (0,4) +E ^(.+)$ vivi (0,4)(0,4) +E ^([^!.]+).att.com!(.+)$ gryphon.att.com!eby (0,19)(0,7)(16,19) +E ^([^!]+!)?([^!]+)$ bas (0,3)(?,?)(0,3) +E ^([^!]+!)?([^!]+)$ bar!bas (0,7)(0,4)(4,7) +E ^([^!]+!)?([^!]+)$ foo!bas (0,7)(0,4)(4,7) +E ^.+!([^!]+!)([^!]+)$ foo!bar!bas (0,11)(4,8)(8,11) +E ((foo)|(bar))!bas bar!bas (0,7)(0,3)(?,?)(0,3) +E ((foo)|(bar))!bas foo!bar!bas (4,11)(4,7)(?,?)(4,7) +E ((foo)|(bar))!bas foo!bas (0,7)(0,3)(0,3) +E ((foo)|bar)!bas bar!bas (0,7)(0,3) +E ((foo)|bar)!bas foo!bar!bas (4,11)(4,7) +E ((foo)|bar)!bas foo!bas (0,7)(0,3)(0,3) +E (foo|(bar))!bas bar!bas (0,7)(0,3)(0,3) +E (foo|(bar))!bas foo!bar!bas (4,11)(4,7)(4,7) +E (foo|(bar))!bas foo!bas (0,7)(0,3) +E (foo|bar)!bas bar!bas (0,7)(0,3) +E (foo|bar)!bas foo!bar!bas (4,11)(4,7) +E (foo|bar)!bas foo!bas (0,7)(0,3) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bar!bas (0,11)(0,11)(?,?)(?,?)(4,8)(8,11) +E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ bas (0,3)(?,?)(0,3) +E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ bar!bas (0,7)(0,4)(4,7) +E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ foo!bar!bas (0,11)(?,?)(?,?)(4,8)(8,11) +E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ foo!bas (0,7)(0,4)(4,7) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ bas (0,3)(0,3)(?,?)(0,3) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ bar!bas (0,7)(0,7)(0,4)(4,7) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bar!bas (0,11)(0,11)(?,?)(?,?)(4,8)(8,11) +E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bas (0,7)(0,7)(0,4)(4,7) +E .*(/XXX).* /XXX (0,4)(0,4) +E .*(\\XXX).* \XXX (0,4)(0,4) +E \\XXX \XXX (0,4) +E .*(/000).* /000 (0,4)(0,4) +E .*(\\000).* \000 (0,4)(0,4) +E \\000 \000 (0,4) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat new file mode 100644 index 0000000..d348512 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat @@ -0,0 +1,62 @@ +NOTE regex implementation categorization 2004-05-31 + +?E aa* xaxaax (1,2) POSITION=leftmost +; POSITION=bug + +?E (a*)(ab)*(b*) abc (0,2)(0,1)(?,?)(1,2) ASSOCIATIVITY=right +|E (a*)(ab)*(b*) abc (0,2)(0,0)(0,2)(2,2) ASSOCIATIVITY=left +; ASSOCIATIVITY=bug + +?E ((a*)(ab)*)((b*)(a*)) aba (0,3)(0,2)(0,0)(0,2)(2,3)(2,2)(2,3) SUBEXPRESSION=precedence +|E ((a*)(ab)*)((b*)(a*)) aba (0,3)(0,1)(0,1)(?,?)(1,3)(1,2)(2,3) SUBEXPRESSION=grouping +; SUBEXPRESSION=bug + +?E (...?.?)* xxxxxx (0,6)(4,6) REPEAT_LONGEST=first +|E (...?.?)* xxxxxx (0,6)(2,6) REPEAT_LONGEST=last +|E (...?.?)* xxxxxx OK REPEAT_LONGEST=unknown +; REPEAT_LONGEST=bug + +?E (a|ab)(bc|c) abcabc (0,3)(0,2)(2,3) EXPECTED +|E (a|ab)(bc|c) abcabc (0,3)(0,1)(1,3) BUG=alternation-order +; BUG=alternation-order-UNKNOWN + +?E (aba|a*b)(aba|a*b) ababa (0,5)(0,2)(2,5) EXPECTED +|E (aba|a*b)(aba|a*b) ababa (0,4)(0,3)(3,4) BUG=first-match +; BUG=unknown-match + +?B a\(b\)*\1 a NOMATCH EXPECTED +|B a\(b\)*\1 a (0,1) BUG=nomatch-match +|B a\(b\)*\1 abab (0,2)(1,2) # BUG=repeat-any +; BUG=nomatch-match-UNKNOWN + +?E (a*){2} xxxxx (0,0)(0,0) EXPECTED +|E (a*){2} xxxxx (5,5)(5,5) BUG=range-null +; BUG=range-null-UNKNOWN + +?B a\(b\)*\1 abab NOMATCH EXPECTED +|B a\(b\)*\1 abab (0,1) # BUG=nomatch-match +|B a\(b\)*\1 abab (0,2)(1,2) BUG=repeat-any +; BUG=repeat-any-UNKNOWN + +?E (a*)* a (0,1)(0,1) EXPECTED +|E (a*)* ax (0,1)(0,1) BUG=repeat-null-unknown +|E (a*)* a (0,1)(1,1) BUG=repeat-null +; BUG=repeat-null-UNKNOWN + +?E (aba|a*b)* ababa (0,5)(2,5) EXPECTED +|E (aba|a*b)* ababa (0,5)(3,4) BUG=repeat-short +|E (aba|a*b)* ababa (0,4)(3,4) # LENGTH=first +; BUG=repeat-short-UNKNOWN + +?E (a(b)?)+ aba (0,3)(2,3) EXPECTED +|E (a(b)?)+ aba (0,3)(2,3)(1,2) BUG=repeat-artifact +; BUG=repeat-artifact-UNKNOWN + +?B \(a\(b\)*\)*\2 abab NOMATCH EXPECTED +|B \(a\(b\)*\)*\2 abab (0,4)(2,3)(1,2) BUG=repeat-artifact-nomatch +; BUG=repeat-artifact-nomatch-UNKNOWN + +?E (a?)((ab)?)(b?)a?(ab)?b? abab (0,4)(0,1)(1,1)(?,?)(1,2)(2,4) BUG=subexpression-first +|E .*(.*) ab (0,2)(2,2) EXPECTED +|E .*(.*) ab (0,2)(0,2) BUG=subexpression-first +; BUG=subexpression-first-UNKNOWN diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat new file mode 100644 index 0000000..39f3111 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat @@ -0,0 +1,30 @@ +NOTE left-assoc:pass-all right-assoc:pass-all : 2002-04-29 + +E (a|ab)(c|bcd) abcd (0,4)(0,1)(1,4) +E (a|ab)(bcd|c) abcd (0,4)(0,1)(1,4) +E (ab|a)(c|bcd) abcd (0,4)(0,1)(1,4) +E (ab|a)(bcd|c) abcd (0,4)(0,1)(1,4) +E ((a|ab)(c|bcd))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4) +E ((a|ab)(bcd|c))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4) +E ((ab|a)(c|bcd))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4) +E ((ab|a)(bcd|c))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4) +E (a|ab)((c|bcd)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4) +E (a|ab)((bcd|c)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4) +E (ab|a)((c|bcd)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4) +E (ab|a)((bcd|c)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4) +E (a*)(b|abc) abc (0,3)(0,0)(0,3) +E (a*)(abc|b) abc (0,3)(0,0)(0,3) +E ((a*)(b|abc))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3) +E ((a*)(abc|b))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3) +E (a*)((b|abc)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3) +E (a*)((abc|b)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3) +E (a*)(b|abc) abc (0,3)(0,0)(0,3) +E (a*)(abc|b) abc (0,3)(0,0)(0,3) +E ((a*)(b|abc))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3) +E ((a*)(abc|b))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3) +E (a*)((b|abc)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3) +E (a*)((abc|b)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3) +E (a|ab) ab (0,2)(0,2) +E (ab|a) ab (0,2)(0,2) +E (a|ab)(b*) ab (0,2)(0,2)(2,2) +E (ab|a)(b*) ab (0,2)(0,2)(2,2) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat new file mode 100644 index 0000000..9c068c6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat @@ -0,0 +1,16 @@ +NOTE left-assoc:pass-all right-assoc:pass-none : 2002-04-29 + +E (a|ab)(c|bcd)(d*) abcd (0,4)(0,1)(1,4)(4,4) +E (a|ab)(bcd|c)(d*) abcd (0,4)(0,1)(1,4)(4,4) +E (ab|a)(c|bcd)(d*) abcd (0,4)(0,1)(1,4)(4,4) +E (ab|a)(bcd|c)(d*) abcd (0,4)(0,1)(1,4)(4,4) + +E (a*)(b|abc)(c*) abc (0,3)(0,0)(0,3)(3,3) +E (a*)(abc|b)(c*) abc (0,3)(0,0)(0,3)(3,3) +E (a*)(b|abc)(c*) abc (0,3)(0,0)(0,3)(3,3) +E (a*)(abc|b)(c*) abc (0,3)(0,0)(0,3)(3,3) + +E (a|ab)(c|bcd)(d|.*) abcd (0,4)(0,1)(1,4)(4,4) +E (a|ab)(bcd|c)(d|.*) abcd (0,4)(0,1)(1,4)(4,4) +E (ab|a)(c|bcd)(d|.*) abcd (0,4)(0,1)(1,4)(4,4) +E (ab|a)(bcd|c)(d|.*) abcd (0,4)(0,1)(1,4)(4,4) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat new file mode 100644 index 0000000..c73d8f0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat @@ -0,0 +1,73 @@ +NOTE null subexpression matches : 2002-06-06 + +E (a*)* a (0,1)(0,1) +E SAME x (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E (a*)+ a (0,1)(0,1) +E SAME x (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E (a+)* a (0,1)(0,1) +E SAME x (0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E (a+)+ a (0,1)(0,1) +E SAME x NOMATCH +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) + +E ([a]*)* a (0,1)(0,1) +E SAME x (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E ([a]*)+ a (0,1)(0,1) +E SAME x (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaax (0,6)(0,6) +E ([^b]*)* a (0,1)(0,1) +E SAME b (0,0)(0,0) +E SAME aaaaaa (0,6)(0,6) +E SAME aaaaaab (0,6)(0,6) +E ([ab]*)* a (0,1)(0,1) +E SAME aaaaaa (0,6)(0,6) +E SAME ababab (0,6)(0,6) +E SAME bababa (0,6)(0,6) +E SAME b (0,1)(0,1) +E SAME bbbbbb (0,6)(0,6) +E SAME aaaabcde (0,5)(0,5) +E ([^a]*)* b (0,1)(0,1) +E SAME bbbbbb (0,6)(0,6) +E SAME aaaaaa (0,0)(0,0) +E ([^ab]*)* ccccxx (0,6)(0,6) +E SAME ababab (0,0)(0,0) + +E ((z)+|a)* zabcde (0,2)(1,2) + +{E a+? aaaaaa (0,1) no *? +? mimimal match ops +E (a) aaa (0,1)(0,1) +E (a*?) aaa (0,0)(0,0) +E (a)*? aaa (0,0) +E (a*?)*? aaa (0,0) +} + +B \(a*\)*\(x\) x (0,1)(0,0)(0,1) +B \(a*\)*\(x\) ax (0,2)(0,1)(1,2) +B \(a*\)*\(x\) axa (0,2)(0,1)(1,2) +B \(a*\)*\(x\)\(\1\) x (0,1)(0,0)(0,1)(1,1) +B \(a*\)*\(x\)\(\1\) ax (0,2)(1,1)(1,2)(2,2) +B \(a*\)*\(x\)\(\1\) axa (0,3)(0,1)(1,2)(2,3) +B \(a*\)*\(x\)\(\1\)\(x\) axax (0,4)(0,1)(1,2)(2,3)(3,4) +B \(a*\)*\(x\)\(\1\)\(x\) axxa (0,3)(1,1)(1,2)(2,2)(2,3) + +E (a*)*(x) x (0,1)(0,0)(0,1) +E (a*)*(x) ax (0,2)(0,1)(1,2) +E (a*)*(x) axa (0,2)(0,1)(1,2) + +E (a*)+(x) x (0,1)(0,0)(0,1) +E (a*)+(x) ax (0,2)(0,1)(1,2) +E (a*)+(x) axa (0,2)(0,1)(1,2) + +E (a*){2}(x) x (0,1)(0,0)(0,1) +E (a*){2}(x) ax (0,2)(1,1)(1,2) +E (a*){2}(x) axa (0,2)(1,1)(1,2) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat new file mode 100644 index 0000000..c24749c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat @@ -0,0 +1,140 @@ +NOTE implicit vs. explicit repetitions : 2009-02-02 + +# Glenn Fowler +# conforming matches (column 4) must match one of the following BREs +# NOMATCH +# (0,.)\((\(.\),\(.\))(?,?)(\2,\3)\)* +# (0,.)\((\(.\),\(.\))(\2,\3)(?,?)\)* +# i.e., each 3-tuple has two identical elements and one (?,?) + +E ((..)|(.)) NULL NOMATCH +E ((..)|(.))((..)|(.)) NULL NOMATCH +E ((..)|(.))((..)|(.))((..)|(.)) NULL NOMATCH + +E ((..)|(.)){1} NULL NOMATCH +E ((..)|(.)){2} NULL NOMATCH +E ((..)|(.)){3} NULL NOMATCH + +E ((..)|(.))* NULL (0,0) + +E ((..)|(.)) a (0,1)(0,1)(?,?)(0,1) +E ((..)|(.))((..)|(.)) a NOMATCH +E ((..)|(.))((..)|(.))((..)|(.)) a NOMATCH + +E ((..)|(.)){1} a (0,1)(0,1)(?,?)(0,1) +E ((..)|(.)){2} a NOMATCH +E ((..)|(.)){3} a NOMATCH + +E ((..)|(.))* a (0,1)(0,1)(?,?)(0,1) + +E ((..)|(.)) aa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aa (0,2)(0,1)(?,?)(0,1)(1,2)(?,?)(1,2) +E ((..)|(.))((..)|(.))((..)|(.)) aa NOMATCH + +E ((..)|(.)){1} aa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aa (0,2)(1,2)(?,?)(1,2) +E ((..)|(.)){3} aa NOMATCH + +E ((..)|(.))* aa (0,2)(0,2)(0,2)(?,?) + +E ((..)|(.)) aaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aaa (0,3)(0,2)(0,2)(?,?)(2,3)(?,?)(2,3) +E ((..)|(.))((..)|(.))((..)|(.)) aaa (0,3)(0,1)(?,?)(0,1)(1,2)(?,?)(1,2)(2,3)(?,?)(2,3) + +E ((..)|(.)){1} aaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aaa (0,3)(2,3)(?,?)(2,3) +E ((..)|(.)){3} aaa (0,3)(2,3)(?,?)(2,3) + +E ((..)|(.))* aaa (0,3)(2,3)(?,?)(2,3) + +E ((..)|(.)) aaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?) +E ((..)|(.))((..)|(.))((..)|(.)) aaaa (0,4)(0,2)(0,2)(?,?)(2,3)(?,?)(2,3)(3,4)(?,?)(3,4) + +E ((..)|(.)){1} aaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aaaa (0,4)(2,4)(2,4)(?,?) +E ((..)|(.)){3} aaaa (0,4)(3,4)(?,?)(3,4) + +E ((..)|(.))* aaaa (0,4)(2,4)(2,4)(?,?) + +E ((..)|(.)) aaaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aaaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?) +E ((..)|(.))((..)|(.))((..)|(.)) aaaaa (0,5)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)(4,5)(?,?)(4,5) + +E ((..)|(.)){1} aaaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aaaaa (0,4)(2,4)(2,4)(?,?) +E ((..)|(.)){3} aaaaa (0,5)(4,5)(?,?)(4,5) + +E ((..)|(.))* aaaaa (0,5)(4,5)(?,?)(4,5) + +E ((..)|(.)) aaaaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.))((..)|(.)) aaaaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?) +E ((..)|(.))((..)|(.))((..)|(.)) aaaaaa (0,6)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)(4,6)(4,6)(?,?) + +E ((..)|(.)){1} aaaaaa (0,2)(0,2)(0,2)(?,?) +E ((..)|(.)){2} aaaaaa (0,4)(2,4)(2,4)(?,?) +E ((..)|(.)){3} aaaaaa (0,6)(4,6)(4,6)(?,?) + +E ((..)|(.))* aaaaaa (0,6)(4,6)(4,6)(?,?) + +NOTE additional repetition tests graciously provided by Chris Kuklewicz www.haskell.org 2009-02-02 + +# These test a bug in OS X / FreeBSD / NetBSD, and libtree. +# Linux/GLIBC gets the {8,} and {8,8} wrong. + +:HA#100:E X(.?){0,}Y X1234567Y (0,9)(7,8) +:HA#101:E X(.?){1,}Y X1234567Y (0,9)(7,8) +:HA#102:E X(.?){2,}Y X1234567Y (0,9)(7,8) +:HA#103:E X(.?){3,}Y X1234567Y (0,9)(7,8) +:HA#104:E X(.?){4,}Y X1234567Y (0,9)(7,8) +:HA#105:E X(.?){5,}Y X1234567Y (0,9)(7,8) +:HA#106:E X(.?){6,}Y X1234567Y (0,9)(7,8) +:HA#107:E X(.?){7,}Y X1234567Y (0,9)(7,8) +:HA#108:E X(.?){8,}Y X1234567Y (0,9)(8,8) +:HA#110:E X(.?){0,8}Y X1234567Y (0,9)(7,8) +:HA#111:E X(.?){1,8}Y X1234567Y (0,9)(7,8) +:HA#112:E X(.?){2,8}Y X1234567Y (0,9)(7,8) +:HA#113:E X(.?){3,8}Y X1234567Y (0,9)(7,8) +:HA#114:E X(.?){4,8}Y X1234567Y (0,9)(7,8) +:HA#115:E X(.?){5,8}Y X1234567Y (0,9)(7,8) +:HA#116:E X(.?){6,8}Y X1234567Y (0,9)(7,8) +:HA#117:E X(.?){7,8}Y X1234567Y (0,9)(7,8) +:HA#118:E X(.?){8,8}Y X1234567Y (0,9)(8,8) + +# These test a fixed bug in my regex-tdfa that did not keep the expanded +# form properly grouped, so right association did the wrong thing with +# these ambiguous patterns (crafted just to test my code when I became +# suspicious of my implementation). The first subexpression should use +# "ab" then "a" then "bcd". + +# OS X / FreeBSD / NetBSD badly fail many of these, with impossible +# results like (0,6)(4,5)(6,6). + +:HA#260:E (a|ab|c|bcd){0,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#261:E (a|ab|c|bcd){1,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#262:E (a|ab|c|bcd){2,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#263:E (a|ab|c|bcd){3,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#264:E (a|ab|c|bcd){4,}(d*) ababcd NOMATCH +:HA#265:E (a|ab|c|bcd){0,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#266:E (a|ab|c|bcd){1,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#267:E (a|ab|c|bcd){2,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#268:E (a|ab|c|bcd){3,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#269:E (a|ab|c|bcd){4,10}(d*) ababcd NOMATCH +:HA#270:E (a|ab|c|bcd)*(d*) ababcd (0,6)(3,6)(6,6) +:HA#271:E (a|ab|c|bcd)+(d*) ababcd (0,6)(3,6)(6,6) + +# The above worked on Linux/GLIBC but the following often fail. +# They also trip up OS X / FreeBSD / NetBSD: + +:HA#280:E (ab|a|c|bcd){0,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#281:E (ab|a|c|bcd){1,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#282:E (ab|a|c|bcd){2,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#283:E (ab|a|c|bcd){3,}(d*) ababcd (0,6)(3,6)(6,6) +:HA#284:E (ab|a|c|bcd){4,}(d*) ababcd NOMATCH +:HA#285:E (ab|a|c|bcd){0,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#286:E (ab|a|c|bcd){1,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#287:E (ab|a|c|bcd){2,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#288:E (ab|a|c|bcd){3,10}(d*) ababcd (0,6)(3,6)(6,6) +:HA#289:E (ab|a|c|bcd){4,10}(d*) ababcd NOMATCH +:HA#290:E (ab|a|c|bcd)*(d*) ababcd (0,6)(3,6)(6,6) +:HA#291:E (ab|a|c|bcd)+(d*) ababcd (0,6)(3,6)(6,6) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat new file mode 100644 index 0000000..ed7f28e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat @@ -0,0 +1,16 @@ +NOTE left-assoc:pass-none right-assoc:pass-all : 2002-04-29 + +E (a|ab)(c|bcd)(d*) abcd (0,4)(0,2)(2,3)(3,4) +E (a|ab)(bcd|c)(d*) abcd (0,4)(0,2)(2,3)(3,4) +E (ab|a)(c|bcd)(d*) abcd (0,4)(0,2)(2,3)(3,4) +E (ab|a)(bcd|c)(d*) abcd (0,4)(0,2)(2,3)(3,4) + +E (a*)(b|abc)(c*) abc (0,3)(0,1)(1,2)(2,3) +E (a*)(abc|b)(c*) abc (0,3)(0,1)(1,2)(2,3) +E (a*)(b|abc)(c*) abc (0,3)(0,1)(1,2)(2,3) +E (a*)(abc|b)(c*) abc (0,3)(0,1)(1,2)(2,3) + +E (a|ab)(c|bcd)(d|.*) abcd (0,4)(0,2)(2,3)(3,4) +E (a|ab)(bcd|c)(d|.*) abcd (0,4)(0,2)(2,3)(3,4) +E (ab|a)(c|bcd)(d|.*) abcd (0,4)(0,2)(2,3)(3,4) +E (ab|a)(bcd|c)(d|.*) abcd (0,4)(0,2)(2,3)(3,4) diff --git a/contrib/netbsd-tests/lib/libc/regex/data/backref.in b/contrib/netbsd-tests/lib/libc/regex/data/backref.in new file mode 100644 index 0000000..cc59b06 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/backref.in @@ -0,0 +1,21 @@ +# back references, ugh +a\(b\)\2c bC ESUBREG +a\(b\1\)c bC ESUBREG +a\(b*\)c\1d b abbcbbd abbcbbd bb +a\(b*\)c\1d b abbcbd +a\(b*\)c\1d b abbcbbbd +^\(.\)\1 b abc +a\([bc]\)\1d b abcdabbd abbd b +a\(\([bc]\)\2\)*d b abbccd abbccd +a\(\([bc]\)\2\)*d b abbcbd +# actually, this next one probably ought to fail, but the spec is unclear +a\(\(b\)*\2\)*d b abbbd abbbd +# here is a case that no NFA implementation does right +\(ab*\)[ab]*\1 b ababaaa ababaaa a +# check out normal matching in the presence of back refs +\(a\)\1bcd b aabcd aabcd +\(a\)\1bc*d b aabcd aabcd +\(a\)\1bc*d b aabd aabd +\(a\)\1bc*d b aabcccd aabcccd +\(a\)\1bc*[ce]d b aabcccd aabcccd +^\(a\)\1b\(c\)*cd$ b aabcccd aabcccd diff --git a/contrib/netbsd-tests/lib/libc/regex/data/basic.in b/contrib/netbsd-tests/lib/libc/regex/data/basic.in new file mode 100644 index 0000000..d1e3aa9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/basic.in @@ -0,0 +1,5 @@ +# basics +a & a a +abc & abc abc +abc|de - abc abc +a|b|c - abc a diff --git a/contrib/netbsd-tests/lib/libc/regex/data/bracket.in b/contrib/netbsd-tests/lib/libc/regex/data/bracket.in new file mode 100644 index 0000000..53a0b20 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/bracket.in @@ -0,0 +1,55 @@ +# brackets, and numerous perversions thereof +a[b]c & abc abc +a[ab]c & abc abc +a[^ab]c & adc adc +a[]b]c & a]c a]c +a[[b]c & a[c a[c +a[-b]c & a-c a-c +a[^]b]c & adc adc +a[^-b]c & adc adc +a[b-]c & a-c a-c +a[b &C EBRACK +a[] &C EBRACK +a[1-3]c & a2c a2c +a[3-1]c &C ERANGE +a[1-3-5]c &C ERANGE +a[[.-.]--]c & a-c a-c +a[1- &C ERANGE +a[[. &C EBRACK +a[[.x &C EBRACK +a[[.x. &C EBRACK +a[[.x.] &C EBRACK +a[[.x.]] & ax ax +a[[.x,.]] &C ECOLLATE +a[[.one.]]b & a1b a1b +a[[.notdef.]]b &C ECOLLATE +a[[.].]]b & a]b a]b +a[[:alpha:]]c & abc abc +a[[:notdef:]]c &C ECTYPE +a[[: &C EBRACK +a[[:alpha &C EBRACK +a[[:alpha:] &C EBRACK +a[[:alpha,:] &C ECTYPE +a[[:]:]]b &C ECTYPE +a[[:-:]]b &C ECTYPE +a[[:alph:]] &C ECTYPE +a[[:alphabet:]] &C ECTYPE +[[:alnum:]]+ - -%@a0X- a0X +[[:alpha:]]+ - -%@aX0- aX +[[:blank:]]+ - aSSTb SST +[[:cntrl:]]+ - aNTb NT +[[:digit:]]+ - a019b 019 +[[:graph:]]+ - Sa%bS a%b +[[:lower:]]+ - AabC ab +[[:print:]]+ - NaSbN aSb +[[:punct:]]+ - S%-&T %-& +[[:space:]]+ - aSNTb SNT +[[:upper:]]+ - aBCd BC +[[:xdigit:]]+ - p0f3Cq 0f3C +a[[=b=]]c & abc abc +a[[= &C EBRACK +a[[=b &C EBRACK +a[[=b= &C EBRACK +a[[=b=] &C EBRACK +a[[=b,=]] &C ECOLLATE +a[[=one=]]b & a1b a1b diff --git a/contrib/netbsd-tests/lib/libc/regex/data/c_comments.in b/contrib/netbsd-tests/lib/libc/regex/data/c_comments.in new file mode 100644 index 0000000..ea3faf9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/c_comments.in @@ -0,0 +1,17 @@ +# Let's have some fun -- try to match a C comment. +# first the obvious, which looks okay at first glance... +/\*.*\*/ - /*x*/ /*x*/ +# but... +/\*.*\*/ - /*x*/y/*z*/ /*x*/y/*z*/ +# okay, we must not match */ inside; try to do that... +/\*([^*]|\*[^/])*\*/ - /*x*/ /*x*/ +/\*([^*]|\*[^/])*\*/ - /*x*/y/*z*/ /*x*/ +# but... +/\*([^*]|\*[^/])*\*/ - /*x**/y/*z*/ /*x**/y/*z*/ +# and a still fancier version, which does it right (I think)... +/\*([^*]|\*+[^*/])*\*+/ - /*x*/ /*x*/ +/\*([^*]|\*+[^*/])*\*+/ - /*x*/y/*z*/ /*x*/ +/\*([^*]|\*+[^*/])*\*+/ - /*x**/y/*z*/ /*x**/ +/\*([^*]|\*+[^*/])*\*+/ - /*x****/y/*z*/ /*x****/ +/\*([^*]|\*+[^*/])*\*+/ - /*x**x*/y/*z*/ /*x**x*/ +/\*([^*]|\*+[^*/])*\*+/ - /*x***x/y/*z*/ /*x***x/y/*z*/ diff --git a/contrib/netbsd-tests/lib/libc/regex/data/complex.in b/contrib/netbsd-tests/lib/libc/regex/data/complex.in new file mode 100644 index 0000000..e114058 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/complex.in @@ -0,0 +1,23 @@ +# complexities +a(((b)))c - abc abc +a(b|(c))d - abd abd +a(b*|c)d - abbd abbd +# just gotta have one DFA-buster, of course +a[ab]{20} - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab +# and an inline expansion in case somebody gets tricky +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab +# and in case somebody just slips in an NFA... +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) - aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights +# fish for anomalies as the number of states passes 32 +12345678901234567890123456789 - a12345678901234567890123456789b 12345678901234567890123456789 +123456789012345678901234567890 - a123456789012345678901234567890b 123456789012345678901234567890 +1234567890123456789012345678901 - a1234567890123456789012345678901b 1234567890123456789012345678901 +12345678901234567890123456789012 - a12345678901234567890123456789012b 12345678901234567890123456789012 +123456789012345678901234567890123 - a123456789012345678901234567890123b 123456789012345678901234567890123 +# and one really big one, beyond any plausible word width +1234567890123456789012345678901234567890123456789012345678901234567890 - a1234567890123456789012345678901234567890123456789012345678901234567890b 1234567890123456789012345678901234567890123456789012345678901234567890 +# fish for problems as brackets go past 8 +[ab][cd][ef][gh][ij][kl][mn] - xacegikmoq acegikm +[ab][cd][ef][gh][ij][kl][mn][op] - xacegikmoq acegikmo +[ab][cd][ef][gh][ij][kl][mn][op][qr] - xacegikmoqy acegikmoq +[ab][cd][ef][gh][ij][kl][mn][op][q] - xacegikmoqy acegikmoq diff --git a/contrib/netbsd-tests/lib/libc/regex/data/error.in b/contrib/netbsd-tests/lib/libc/regex/data/error.in new file mode 100644 index 0000000..61e0ea4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/error.in @@ -0,0 +1,30 @@ +# certain syntax errors and non-errors +| C EMPTY +| b | | +* C BADRPT +* b * * ++ C BADRPT +? C BADRPT +"" &C EMPTY +() - abc @abc +\(\) b abc @abc +a||b C EMPTY +|ab C EMPTY +ab| C EMPTY +(|a)b C EMPTY +(a|)b C EMPTY +(*a) C BADRPT +(+a) C BADRPT +(?a) C BADRPT +({1}a) C BADRPT +\(\{1\}a\) bC BADRPT +(a|*b) C BADRPT +(a|+b) C BADRPT +(a|?b) C BADRPT +(a|{1}b) C BADRPT +^* C BADRPT +^* b * * +^+ C BADRPT +^? C BADRPT +^{1} C BADRPT +^\{1\} bC BADRPT diff --git a/contrib/netbsd-tests/lib/libc/regex/data/meta.in b/contrib/netbsd-tests/lib/libc/regex/data/meta.in new file mode 100644 index 0000000..4533d35 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/meta.in @@ -0,0 +1,21 @@ +# metacharacters, backslashes +a.c & abc abc +a[bc]d & abd abd +a\*c & a*c a*c +a\\b & a\b a\b +a\\\*b & a\*b a\*b +a\bc & abc abc +a\ &C EESCAPE +a\\bc & a\bc a\bc +\{ bC BADRPT +a\[b & a[b a[b +a[b &C EBRACK +# trailing $ is a peculiar special case for the BRE code +a$ & a a +a$ & a$ +a\$ & a +a\$ & a$ a$ +a\\$ & a +a\\$ & a$ +a\\$ & a\$ +a\\$ & a\ a\ diff --git a/contrib/netbsd-tests/lib/libc/regex/data/nospec.in b/contrib/netbsd-tests/lib/libc/regex/data/nospec.in new file mode 100644 index 0000000..baf8d04 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/nospec.in @@ -0,0 +1,7 @@ +# plain strings, with the NOSPEC flag +abc m abc abc +abc m xabcy abc +abc m xyz +a*b m aba*b a*b +a*b m ab +"" mC EMPTY diff --git a/contrib/netbsd-tests/lib/libc/regex/data/paren.in b/contrib/netbsd-tests/lib/libc/regex/data/paren.in new file mode 100644 index 0000000..9d206ce --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/paren.in @@ -0,0 +1,19 @@ +# parentheses and perversions thereof +a(b)c - abc abc +a\(b\)c b abc abc +a( C EPAREN +a( b a( a( +a\( - a( a( +a\( bC EPAREN +a\(b bC EPAREN +a(b C EPAREN +a(b b a(b a(b +# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly) +a) - a) a) +) - ) ) +# end gagging (in a just world, those *should* give EPAREN) +a) b a) a) +a\) bC EPAREN +\) bC EPAREN +a()b - ab ab +a\(\)b b ab ab diff --git a/contrib/netbsd-tests/lib/libc/regex/data/regress.in b/contrib/netbsd-tests/lib/libc/regex/data/regress.in new file mode 100644 index 0000000..afd832a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/regress.in @@ -0,0 +1,9 @@ +# past problems, and suspected problems +(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A]) - A1 A1 +abcdefghijklmnop i abcdefghijklmnop abcdefghijklmnop +abcdefghijklmnopqrstuv i abcdefghijklmnopqrstuv abcdefghijklmnopqrstuv +(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN]) - CC11 CC11 +CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a - CC11 CC11 +Char \([a-z0-9_]*\)\[.* b Char xyz[k Char xyz[k xyz +a?b - ab ab +-\{0,1\}[0-9]*$ b -5 -5 diff --git a/contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in b/contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in new file mode 100644 index 0000000..ee6ff4c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in @@ -0,0 +1,45 @@ +# the dreaded bounded repetitions +{ & { { +{abc & {abc {abc +{1 C BADRPT +{1} C BADRPT +a{b & a{b a{b +a{1}b - ab ab +a\{1\}b b ab ab +a{1,}b - ab ab +a\{1,\}b b ab ab +a{1,2}b - aab aab +a\{1,2\}b b aab aab +a{1 C EBRACE +a\{1 bC EBRACE +a{1a C EBRACE +a\{1a bC EBRACE +a{1a} C BADBR +a\{1a\} bC BADBR +a{,2} - a{,2} a{,2} +a\{,2\} bC BADBR +a{,} - a{,} a{,} +a\{,\} bC BADBR +a{1,x} C BADBR +a\{1,x\} bC BADBR +a{1,x C EBRACE +a\{1,x bC EBRACE +a{300} C BADBR +a\{300\} bC BADBR +a{1,0} C BADBR +a\{1,0\} bC BADBR +ab{0,0}c - abcac ac +ab\{0,0\}c b abcac ac +ab{0,1}c - abcac abc +ab\{0,1\}c b abcac abc +ab{0,3}c - abbcac abbc +ab\{0,3\}c b abbcac abbc +ab{1,1}c - acabc abc +ab\{1,1\}c b acabc abc +ab{1,3}c - acabc abc +ab\{1,3\}c b acabc abc +ab{2,2}c - abcabbc abbc +ab\{2,2\}c b abcabbc abbc +ab{2,4}c - abcabbc abbc +ab\{2,4\}c b abcabbc abbc +((a{1,10}){1,10}){1,10} - a a a,a diff --git a/contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in b/contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in new file mode 100644 index 0000000..da97bad --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in @@ -0,0 +1,21 @@ +# multiple repetitions +a** &C BADRPT +a++ C BADRPT +a?? C BADRPT +a*+ C BADRPT +a*? C BADRPT +a+* C BADRPT +a+? C BADRPT +a?* C BADRPT +a?+ C BADRPT +a{1}{1} C BADRPT +a*{1} C BADRPT +a+{1} C BADRPT +a?{1} C BADRPT +a{1}* C BADRPT +a{1}+ C BADRPT +a{1}? C BADRPT +a*{b} - a{b} a{b} +a\{1\}\{1\} bC BADRPT +a*\{1\} bC BADRPT +a\{1\}* bC BADRPT diff --git a/contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in b/contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in new file mode 100644 index 0000000..08bc286 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in @@ -0,0 +1,10 @@ +# ordinary repetitions +ab*c & abc abc +ab+c - abc abc +ab?c - abc abc +a\(*\)b b a*b a*b +a\(**\)b b ab ab +a\(***\)b bC BADRPT +*a b *a *a +**a b a a +***a bC BADRPT diff --git a/contrib/netbsd-tests/lib/libc/regex/data/startend.in b/contrib/netbsd-tests/lib/libc/regex/data/startend.in new file mode 100644 index 0000000..c396e58 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/startend.in @@ -0,0 +1,9 @@ +# check out the STARTEND option +[abc] &# a(b)c b +[abc] &# a(d)c +[abc] &# a(bc)d b +[abc] &# a(dc)d c +. &# a()c +b.*c &# b(bc)c bc +b.* &# b(bc)c bc +.*c &# b(bc)c bc diff --git a/contrib/netbsd-tests/lib/libc/regex/data/subexp.in b/contrib/netbsd-tests/lib/libc/regex/data/subexp.in new file mode 100644 index 0000000..c7bcc06 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/subexp.in @@ -0,0 +1,57 @@ +# subexpressions +a(b)(c)d - abcd abcd b,c +a(((b)))c - abc abc b,b,b +a(b|(c))d - abd abd b,- +a(b*|c|e)d - abbd abbd bb +a(b*|c|e)d - acd acd c +a(b*|c|e)d - ad ad @d +a(b?)c - abc abc b +a(b?)c - ac ac @c +a(b+)c - abc abc b +a(b+)c - abbbc abbbc bbb +a(b*)c - ac ac @c +(a|ab)(bc([de]+)f|cde) - abcdef abcdef a,bcdef,de +# the regression tester only asks for 9 subexpressions +a(b)(c)(d)(e)(f)(g)(h)(i)(j)k - abcdefghijk abcdefghijk b,c,d,e,f,g,h,i,j +a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l - abcdefghijkl abcdefghijkl b,c,d,e,f,g,h,i,j,k +a([bc]?)c - abc abc b +a([bc]?)c - ac ac @c +a([bc]+)c - abc abc b +a([bc]+)c - abcc abcc bc +a([bc]+)bc - abcbc abcbc bc +a(bb+|b)b - abb abb b +a(bbb+|bb+|b)b - abb abb b +a(bbb+|bb+|b)b - abbb abbb bb +a(bbb+|bb+|b)bb - abbb abbb b +(.*).* - abcdef abcdef abcdef +(a*)* - bc @b @b + +# do we get the right subexpression when it is used more than once? +a(b|c)*d - ad ad - +a(b|c)*d - abcd abcd c +a(b|c)+d - abd abd b +a(b|c)+d - abcd abcd c +a(b|c?)+d - ad ad @d +a(b|c?)+d - abcd abcd @d +a(b|c){0,0}d - ad ad - +a(b|c){0,1}d - ad ad - +a(b|c){0,1}d - abd abd b +a(b|c){0,2}d - ad ad - +a(b|c){0,2}d - abcd abcd c +a(b|c){0,}d - ad ad - +a(b|c){0,}d - abcd abcd c +a(b|c){1,1}d - abd abd b +a(b|c){1,1}d - acd acd c +a(b|c){1,2}d - abd abd b +a(b|c){1,2}d - abcd abcd c +a(b|c){1,}d - abd abd b +a(b|c){1,}d - abcd abcd c +a(b|c){2,2}d - acbd acbd b +a(b|c){2,2}d - abcd abcd c +a(b|c){2,4}d - abcd abcd c +a(b|c){2,4}d - abcbd abcbd b +a(b|c){2,4}d - abcbcd abcbcd c +a(b|c){2,}d - abcd abcd c +a(b|c){2,}d - abcbd abcbd b +a(b+|((c)*))+d - abd abd @d,@d,- +a(b+|((c)*))+d - abcd abcd @d,@d,- diff --git a/contrib/netbsd-tests/lib/libc/regex/data/subtle.in b/contrib/netbsd-tests/lib/libc/regex/data/subtle.in new file mode 100644 index 0000000..92d68bb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/subtle.in @@ -0,0 +1,21 @@ +# subtleties of matching +abc & xabcy abc +a\(b\)?c\1d b acd +aBc i Abc Abc +a[Bc]*d i abBCcd abBCcd +0[[:upper:]]1 &i 0a1 0a1 +0[[:lower:]]1 &i 0A1 0A1 +a[^b]c &i abc +a[^b]c &i aBc +a[^b]c &i adc adc +[a]b[c] - abc abc +[a]b[a] - aba aba +[abc]b[abc] - abc abc +[abc]b[abd] - abd abd +a(b?c)+d - accd accd +(wee|week)(knights|night) - weeknights weeknights +(we|wee|week|frob)(knights|night|day) - weeknights weeknights +a[bc]d - xyzaaabcaababdacd abd +a[ab]c - aaabc abc +abc s abc abc +a* & b @b diff --git a/contrib/netbsd-tests/lib/libc/regex/data/word_bound.in b/contrib/netbsd-tests/lib/libc/regex/data/word_bound.in new file mode 100644 index 0000000..e09a329 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/word_bound.in @@ -0,0 +1,13 @@ +# word boundaries (ick) +[[:<:]]a & a a +[[:<:]]a & ba +[[:<:]]a & -a a +a[[:>:]] & a a +a[[:>:]] & ab +a[[:>:]] & a- a +[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc abc +[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc-q abc +[[:<:]]a.c[[:>:]] & axc-dayc-dazce-abc axc +[[:<:]]b.c[[:>:]] & a_bxc-byc_d-bzc-q bzc +[[:<:]].x..[[:>:]] & y_xa_-_xb_y-_xc_-axdc _xc_ +[[:<:]]a_b[[:>:]] & x_a_b diff --git a/contrib/netbsd-tests/lib/libc/regex/data/zero.in b/contrib/netbsd-tests/lib/libc/regex/data/zero.in new file mode 100644 index 0000000..2786944 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/data/zero.in @@ -0,0 +1,7 @@ +# cases involving NULs +aZb & a a +aZb &p a +aZb &p# (aZb) aZb +aZ*b &p# (ab) ab +a.b &# (aZb) aZb +a.* &# (aZb)c aZb diff --git a/contrib/netbsd-tests/lib/libc/regex/debug.c b/contrib/netbsd-tests/lib/libc/regex/debug.c new file mode 100644 index 0000000..18ab6ea --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/debug.c @@ -0,0 +1,275 @@ +/* $NetBSD: debug.c,v 1.3 2017/01/14 00:50:56 christos Exp $ */ + +/*- + * Copyright (c) 1993 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include +#include +#include + +/* Don't sort these! */ +#include "utils.h" +#include "regex2.h" + +#include "test_regex.h" + +#ifdef __NetBSD__ +static void s_print(struct re_guts *, FILE *); +static char *regchar(int); + +/* + * regprint - print a regexp for debugging + */ +void +regprint(regex_t *r, FILE *d) +{ + struct re_guts *g = r->re_g; + int c; + int last; + int nincat[NC]; + + fprintf(d, "%ld states, %zu categories", (long)g->nstates, + g->ncategories); + fprintf(d, ", first %ld last %ld", (long)g->firststate, + (long)g->laststate); + if (g->iflags&USEBOL) + fprintf(d, ", USEBOL"); + if (g->iflags&USEEOL) + fprintf(d, ", USEEOL"); + if (g->iflags&BAD) + fprintf(d, ", BAD"); + if (g->nsub > 0) + fprintf(d, ", nsub=%ld", (long)g->nsub); + if (g->must != NULL) + fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen, + g->must); + if (g->backrefs) + fprintf(d, ", backrefs"); + if (g->nplus > 0) + fprintf(d, ", nplus %ld", (long)g->nplus); + fprintf(d, "\n"); + s_print(g, d); + for (size_t i = 0; i < g->ncategories; i++) { + nincat[i] = 0; + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (g->categories[c] == i) + nincat[i]++; + } + fprintf(d, "cc0#%d", nincat[0]); + for (size_t i = 1; i < g->ncategories; i++) + if (nincat[i] == 1) { + for (c = CHAR_MIN; c <= CHAR_MAX; c++) + if (g->categories[c] == i) + break; + fprintf(d, ", %zu=%s", i, regchar(c)); + } + fprintf(d, "\n"); + for (size_t i = 1; i < g->ncategories; i++) + if (nincat[i] != 1) { + fprintf(d, "cc%zu\t", i); + last = -1; + for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */ + if (c <= CHAR_MAX && g->categories[c] == i) { + if (last < 0) { + fprintf(d, "%s", regchar(c)); + last = c; + } + } else { + if (last >= 0) { + if (last != c-1) + fprintf(d, "-%s", + regchar(c-1)); + last = -1; + } + } + fprintf(d, "\n"); + } +} + +/* + * s_print - print the strip for debugging + */ +static void +s_print(struct re_guts *g, FILE *d) +{ + sop *s; + cset *cs; + int done = 0; + sop opnd; + int col = 0; + ssize_t last; + sopno offset = 2; +# define GAP() { if (offset % 5 == 0) { \ + if (col > 40) { \ + fprintf(d, "\n\t"); \ + col = 0; \ + } else { \ + fprintf(d, " "); \ + col++; \ + } \ + } else \ + col++; \ + offset++; \ + } + + if (OP(g->strip[0]) != OEND) + fprintf(d, "missing initial OEND!\n"); + for (s = &g->strip[1]; !done; s++) { + opnd = OPND(*s); + switch (OP(*s)) { + case OEND: + fprintf(d, "\n"); + done = 1; + break; + case OCHAR: + if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL) + fprintf(d, "\\%c", (char)opnd); + else + fprintf(d, "%s", regchar((char)opnd)); + break; + case OBOL: + fprintf(d, "^"); + break; + case OEOL: + fprintf(d, "$"); + break; + case OBOW: + fprintf(d, "\\{"); + break; + case OEOW: + fprintf(d, "\\}"); + break; + case OANY: + fprintf(d, "."); + break; + case OANYOF: + fprintf(d, "[(%ld)", (long)opnd); + cs = &g->sets[opnd]; + last = -1; + for (size_t i = 0; i < g->csetsize+1; i++) /* +1 flushes */ + if (CHIN(cs, i) && i < g->csetsize) { + if (last < 0) { + fprintf(d, "%s", regchar(i)); + last = i; + } + } else { + if (last >= 0) { + if (last != (ssize_t)i - 1) + fprintf(d, "-%s", + regchar(i - 1)); + last = -1; + } + } + fprintf(d, "]"); + break; + case OBACK_: + fprintf(d, "(\\<%ld>", (long)opnd); + break; + case O_BACK: + fprintf(d, "<%ld>\\)", (long)opnd); + break; + case OPLUS_: + fprintf(d, "(+"); + if (OP(*(s+opnd)) != O_PLUS) + fprintf(d, "<%ld>", (long)opnd); + break; + case O_PLUS: + if (OP(*(s-opnd)) != OPLUS_) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, "+)"); + break; + case OQUEST_: + fprintf(d, "(?"); + if (OP(*(s+opnd)) != O_QUEST) + fprintf(d, "<%ld>", (long)opnd); + break; + case O_QUEST: + if (OP(*(s-opnd)) != OQUEST_) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, "?)"); + break; + case OLPAREN: + fprintf(d, "((<%ld>", (long)opnd); + break; + case ORPAREN: + fprintf(d, "<%ld>))", (long)opnd); + break; + case OCH_: + fprintf(d, "<"); + if (OP(*(s+opnd)) != OOR2) + fprintf(d, "<%ld>", (long)opnd); + break; + case OOR1: + if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, "|"); + break; + case OOR2: + fprintf(d, "|"); + if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH) + fprintf(d, "<%ld>", (long)opnd); + break; + case O_CH: + if (OP(*(s-opnd)) != OOR1) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, ">"); + break; + default: + fprintf(d, "!%d(%d)!", OP(*s), opnd); + break; + } + if (!done) + GAP(); + } +} + +/* + * regchar - make a character printable + */ +static char * /* -> representation */ +regchar(int ch) +{ + static char buf[10]; + + if (isprint(ch) || ch == ' ') + sprintf(buf, "%c", ch); + else + sprintf(buf, "\\%o", ch); + return(buf); +} +#else +void +regprint(regex_t *r, FILE *d) +{ + +} +#endif diff --git a/contrib/netbsd-tests/lib/libc/regex/main.c b/contrib/netbsd-tests/lib/libc/regex/main.c new file mode 100644 index 0000000..eac4e2d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/main.c @@ -0,0 +1,523 @@ +/* $NetBSD: main.c,v 1.2 2011/09/16 16:13:18 plunky Exp $ */ + +/*- + * Copyright (c) 1993 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include + +#include + +#include "test_regex.h" + +char *progname; +int debug = 0; +int line = 0; +int status = 0; + +int copts = REG_EXTENDED; +int eopts = 0; +regoff_t startoff = 0; +regoff_t endoff = 0; + +static char empty = '\0'; + +static char *eprint(int); +static int efind(char *); + +/* + * main - do the simple case, hand off to regress() for regression + */ +int +main(int argc, char *argv[]) +{ + regex_t re; +# define NS 10 + regmatch_t subs[NS]; + char erbuf[100]; + int err; + size_t len; + int c; + int errflg = 0; + int i; + extern int optind; + extern char *optarg; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "c:e:S:E:x")) != -1) + switch (c) { + case 'c': /* compile options */ + copts = options('c', optarg); + break; + case 'e': /* execute options */ + eopts = options('e', optarg); + break; + case 'S': /* start offset */ + startoff = (regoff_t)atoi(optarg); + break; + case 'E': /* end offset */ + endoff = (regoff_t)atoi(optarg); + break; + case 'x': /* Debugging. */ + debug++; + break; + case '?': + default: + errflg++; + break; + } + if (errflg) { + fprintf(stderr, "usage: %s ", progname); + fprintf(stderr, "[-c copt][-C][-d] [re]\n"); + exit(2); + } + + if (optind >= argc) { + regress(stdin); + exit(status); + } + + err = regcomp(&re, argv[optind++], copts); + if (err) { + len = regerror(err, &re, erbuf, sizeof(erbuf)); + fprintf(stderr, "error %s, %zd/%zd `%s'\n", + eprint(err), len, (size_t)sizeof(erbuf), erbuf); + exit(status); + } + regprint(&re, stdout); + + if (optind >= argc) { + regfree(&re); + exit(status); + } + + if (eopts®_STARTEND) { + subs[0].rm_so = startoff; + subs[0].rm_eo = strlen(argv[optind]) - endoff; + } + err = regexec(&re, argv[optind], (size_t)NS, subs, eopts); + if (err) { + len = regerror(err, &re, erbuf, sizeof(erbuf)); + fprintf(stderr, "error %s, %zd/%zd `%s'\n", + eprint(err), len, (size_t)sizeof(erbuf), erbuf); + exit(status); + } + if (!(copts®_NOSUB)) { + len = (int)(subs[0].rm_eo - subs[0].rm_so); + if (subs[0].rm_so != -1) { + if (len != 0) + printf("match `%.*s'\n", (int)len, + argv[optind] + subs[0].rm_so); + else + printf("match `'@%.1s\n", + argv[optind] + subs[0].rm_so); + } + for (i = 1; i < NS; i++) + if (subs[i].rm_so != -1) + printf("(%d) `%.*s'\n", i, + (int)(subs[i].rm_eo - subs[i].rm_so), + argv[optind] + subs[i].rm_so); + } + exit(status); +} + +/* + * regress - main loop of regression test + */ +void +regress(FILE *in) +{ + char inbuf[1000]; +# define MAXF 10 + char *f[MAXF]; + int nf; + int i; + char erbuf[100]; + size_t ne; + const char *badpat = "invalid regular expression"; +# define SHORT 10 + const char *bpname = "REG_BADPAT"; + regex_t re; + + while (fgets(inbuf, sizeof(inbuf), in) != NULL) { + line++; + if (inbuf[0] == '#' || inbuf[0] == '\n') + continue; /* NOTE CONTINUE */ + inbuf[strlen(inbuf)-1] = '\0'; /* get rid of stupid \n */ + if (debug) + fprintf(stdout, "%d:\n", line); + nf = split(inbuf, f, MAXF, "\t\t"); + if (nf < 3) { + fprintf(stderr, "bad input, line %d\n", line); + exit(1); + } + for (i = 0; i < nf; i++) + if (strcmp(f[i], "\"\"") == 0) + f[i] = ∅ + if (nf <= 3) + f[3] = NULL; + if (nf <= 4) + f[4] = NULL; + try(f[0], f[1], f[2], f[3], f[4], options('c', f[1])); + if (opt('&', f[1])) /* try with either type of RE */ + try(f[0], f[1], f[2], f[3], f[4], + options('c', f[1]) &~ REG_EXTENDED); + } + + ne = regerror(REG_BADPAT, NULL, erbuf, sizeof(erbuf)); + if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) { + fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n", + erbuf, badpat); + status = 1; + } + ne = regerror(REG_BADPAT, NULL, erbuf, (size_t)SHORT); + if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' || + ne != strlen(badpat)+1) { + fprintf(stderr, "end: regerror() short test gave `%s' not `%.*s'\n", + erbuf, SHORT-1, badpat); + status = 1; + } + ne = regerror(REG_ITOA|REG_BADPAT, NULL, erbuf, sizeof(erbuf)); + if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) { + fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n", + erbuf, bpname); + status = 1; + } + re.re_endp = bpname; + ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf)); + if (atoi(erbuf) != (int)REG_BADPAT) { + fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n", + erbuf, (long)REG_BADPAT); + status = 1; + } else if (ne != strlen(erbuf)+1) { + fprintf(stderr, "end: regerror() ATOI test len(`%s') = %ld\n", + erbuf, (long)REG_BADPAT); + status = 1; + } +} + +/* + - try - try it, and report on problems + == void try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts); + */ +void +try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts) +{ + regex_t re; +# define NSUBS 10 + regmatch_t subs[NSUBS]; +# define NSHOULD 15 + char *should[NSHOULD]; + int nshould; + char erbuf[100]; + int err; + int len; + const char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE"; + int i; + char *grump; + char f0copy[1000]; + char f2copy[1000]; + + strcpy(f0copy, f0); + re.re_endp = (opts®_PEND) ? f0copy + strlen(f0copy) : NULL; + fixstr(f0copy); + err = regcomp(&re, f0copy, opts); + if (err != 0 && (!opt('C', f1) || err != efind(f2))) { + /* unexpected error or wrong error */ + len = regerror(err, &re, erbuf, sizeof(erbuf)); + fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n", + line, type, eprint(err), len, + (int)sizeof(erbuf), erbuf); + status = 1; + } else if (err == 0 && opt('C', f1)) { + /* unexpected success */ + fprintf(stderr, "%d: %s should have given REG_%s\n", + line, type, f2); + status = 1; + err = 1; /* so we won't try regexec */ + } + + if (err != 0) { + regfree(&re); + return; + } + + strcpy(f2copy, f2); + fixstr(f2copy); + + if (options('e', f1)®_STARTEND) { + if (strchr(f2, '(') == NULL || strchr(f2, ')') == NULL) + fprintf(stderr, "%d: bad STARTEND syntax\n", line); + subs[0].rm_so = strchr(f2, '(') - f2 + 1; + subs[0].rm_eo = strchr(f2, ')') - f2; + } + err = regexec(&re, f2copy, NSUBS, subs, options('e', f1)); + + if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) { + /* unexpected error or wrong error */ + len = regerror(err, &re, erbuf, sizeof(erbuf)); + fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n", + line, type, eprint(err), len, + (int)sizeof(erbuf), erbuf); + status = 1; + } else if (err != 0) { + /* nothing more to check */ + } else if (f3 == NULL) { + /* unexpected success */ + fprintf(stderr, "%d: %s exec should have failed\n", + line, type); + status = 1; + err = 1; /* just on principle */ + } else if (opts®_NOSUB) { + /* nothing more to check */ + } else if ((grump = check(f2, subs[0], f3)) != NULL) { + fprintf(stderr, "%d: %s %s\n", line, type, grump); + status = 1; + err = 1; + } + + if (err != 0 || f4 == NULL) { + regfree(&re); + return; + } + + for (i = 1; i < NSHOULD; i++) + should[i] = NULL; + nshould = split(f4, &should[1], NSHOULD-1, ","); + if (nshould == 0) { + nshould = 1; + should[1] = ∅ + } + for (i = 1; i < NSUBS; i++) { + grump = check(f2, subs[i], should[i]); + if (grump != NULL) { + fprintf(stderr, "%d: %s $%d %s\n", line, + type, i, grump); + status = 1; + err = 1; + } + } + + regfree(&re); +} + +/* + - options - pick options out of a regression-test string + == int options(int type, char *s); + */ +int +options(int type, char *s) +{ + char *p; + int o = (type == 'c') ? copts : eopts; + const char *legal = (type == 'c') ? "bisnmp" : "^$#tl"; + + for (p = s; *p != '\0'; p++) + if (strchr(legal, *p) != NULL) + switch (*p) { + case 'b': + o &= ~REG_EXTENDED; + break; + case 'i': + o |= REG_ICASE; + break; + case 's': + o |= REG_NOSUB; + break; + case 'n': + o |= REG_NEWLINE; + break; + case 'm': + o &= ~REG_EXTENDED; + o |= REG_NOSPEC; + break; + case 'p': + o |= REG_PEND; + break; + case '^': + o |= REG_NOTBOL; + break; + case '$': + o |= REG_NOTEOL; + break; + case '#': + o |= REG_STARTEND; + break; + case 't': /* trace */ + o |= REG_TRACE; + break; + case 'l': /* force long representation */ + o |= REG_LARGE; + break; + case 'r': /* force backref use */ + o |= REG_BACKR; + break; + } + return(o); +} + +/* + - opt - is a particular option in a regression string? + == int opt(int c, char *s); + */ +int /* predicate */ +opt(int c, char *s) +{ + return(strchr(s, c) != NULL); +} + +/* + - fixstr - transform magic characters in strings + == void fixstr(char *p); + */ +void +fixstr(char *p) +{ + if (p == NULL) + return; + + for (; *p != '\0'; p++) + if (*p == 'N') + *p = '\n'; + else if (*p == 'T') + *p = '\t'; + else if (*p == 'S') + *p = ' '; + else if (*p == 'Z') + *p = '\0'; +} + +/* + * check - check a substring match + */ +char * /* NULL or complaint */ +check(char *str, regmatch_t sub, char *should) +{ + int len; + int shlen; + char *p; + static char grump[500]; + char *at = NULL; + + if (should != NULL && strcmp(should, "-") == 0) + should = NULL; + if (should != NULL && should[0] == '@') { + at = should + 1; + should = ∅ + } + + /* check rm_so and rm_eo for consistency */ + if (sub.rm_so > sub.rm_eo || (sub.rm_so == -1 && sub.rm_eo != -1) || + (sub.rm_so != -1 && sub.rm_eo == -1) || + (sub.rm_so != -1 && sub.rm_so < 0) || + (sub.rm_eo != -1 && sub.rm_eo < 0) ) { + sprintf(grump, "start %ld end %ld", (long)sub.rm_so, + (long)sub.rm_eo); + return(grump); + } + + /* check for no match */ + if (sub.rm_so == -1) { + if (should == NULL) + return(NULL); + else { + sprintf(grump, "did not match"); + return(grump); + } + } + + /* check for in range */ + if (sub.rm_eo > (ssize_t)strlen(str)) { + sprintf(grump, "start %ld end %ld, past end of string", + (long)sub.rm_so, (long)sub.rm_eo); + return(grump); + } + + len = (int)(sub.rm_eo - sub.rm_so); + p = str + sub.rm_so; + + /* check for not supposed to match */ + if (should == NULL) { + sprintf(grump, "matched `%.*s'", len, p); + return(grump); + } + + /* check for wrong match */ + shlen = (int)strlen(should); + if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) { + sprintf(grump, "matched `%.*s' instead", len, p); + return(grump); + } + if (shlen > 0) + return(NULL); + + /* check null match in right place */ + if (at == NULL) + return(NULL); + shlen = strlen(at); + if (shlen == 0) + shlen = 1; /* force check for end-of-string */ + if (strncmp(p, at, shlen) != 0) { + sprintf(grump, "matched null at `%.20s'", p); + return(grump); + } + return(NULL); +} + +/* + * eprint - convert error number to name + */ +static char * +eprint(int err) +{ + static char epbuf[100]; + size_t len; + + len = regerror(REG_ITOA|err, NULL, epbuf, sizeof(epbuf)); + assert(len <= sizeof(epbuf)); + return(epbuf); +} + +/* + * efind - convert error name to number + */ +static int +efind(char *name) +{ + static char efbuf[100]; + regex_t re; + + sprintf(efbuf, "REG_%s", name); + assert(strlen(efbuf) < sizeof(efbuf)); + re.re_endp = efbuf; + (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf)); + return(atoi(efbuf)); +} diff --git a/contrib/netbsd-tests/lib/libc/regex/split.c b/contrib/netbsd-tests/lib/libc/regex/split.c new file mode 100644 index 0000000..2a26b50 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/split.c @@ -0,0 +1,344 @@ +/* $NetBSD: split.c,v 1.1 2011/01/08 18:10:31 pgoyette Exp $ */ + +/*- + * Copyright (c) 1993 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include "test_regex.h" + +/* + * split - divide a string into fields, like awk split() + * + * returns number of fields, including overflow + * + * fields[] list is not NULL-terminated + * nfields number of entries available in fields[] + * sep "" white, "c" single char, "ab" [ab]+ + */ +int +split(char *string, char *fields[], int nfields, const char *sep) +{ + char *p = string; + char c; /* latest character */ + char sepc = *sep; + char sepc2; + int fn; + char **fp = fields; + const char *sepp; + int trimtrail; + + /* white space */ + if (sepc == '\0') { + while ((c = *p++) == ' ' || c == '\t') + continue; + p--; + trimtrail = 1; + sep = " \t"; /* note, code below knows this is 2 long */ + sepc = ' '; + } else + trimtrail = 0; + sepc2 = sep[1]; /* now we can safely pick this up */ + + /* catch empties */ + if (*p == '\0') + return(0); + + /* single separator */ + if (sepc2 == '\0') { + fn = nfields; + for (;;) { + *fp++ = p; + fn--; + if (fn == 0) + break; + while ((c = *p++) != sepc) + if (c == '\0') + return(nfields - fn); + *(p-1) = '\0'; + } + /* we have overflowed the fields vector -- just count them */ + fn = nfields; + for (;;) { + while ((c = *p++) != sepc) + if (c == '\0') + return(fn); + fn++; + } + /* not reached */ + } + + /* two separators */ + if (sep[2] == '\0') { + fn = nfields; + for (;;) { + *fp++ = p; + fn--; + while ((c = *p++) != sepc && c != sepc2) + if (c == '\0') { + if (trimtrail && **(fp-1) == '\0') + fn++; + return(nfields - fn); + } + if (fn == 0) + break; + *(p-1) = '\0'; + while ((c = *p++) == sepc || c == sepc2) + continue; + p--; + } + /* we have overflowed the fields vector -- just count them */ + fn = nfields; + while (c != '\0') { + while ((c = *p++) == sepc || c == sepc2) + continue; + p--; + fn++; + while ((c = *p++) != '\0' && c != sepc && c != sepc2) + continue; + } + /* might have to trim trailing white space */ + if (trimtrail) { + p--; + while ((c = *--p) == sepc || c == sepc2) + continue; + p++; + if (*p != '\0') { + if (fn == nfields+1) + *p = '\0'; + fn--; + } + } + return(fn); + } + + /* n separators */ + fn = 0; + for (;;) { + if (fn < nfields) + *fp++ = p; + fn++; + for (;;) { + c = *p++; + if (c == '\0') + return(fn); + sepp = sep; + while ((sepc = *sepp++) != '\0' && sepc != c) + continue; + if (sepc != '\0') /* it was a separator */ + break; + } + if (fn < nfields) + *(p-1) = '\0'; + for (;;) { + c = *p++; + sepp = sep; + while ((sepc = *sepp++) != '\0' && sepc != c) + continue; + if (sepc == '\0') /* it wasn't a separator */ + break; + } + p--; + } + + /* not reached */ +} + +#ifdef TEST_SPLIT + + +/* + * test program + * pgm runs regression + * pgm sep splits stdin lines by sep + * pgm str sep splits str by sep + * pgm str sep n splits str by sep n times + */ +int +main(int argc, char *argv[]) +{ + char buf[512]; + int n; +# define MNF 10 + char *fields[MNF]; + + if (argc > 4) + for (n = atoi(argv[3]); n > 0; n--) { + (void) strcpy(buf, argv[1]); + } + else if (argc > 3) + for (n = atoi(argv[3]); n > 0; n--) { + (void) strcpy(buf, argv[1]); + (void) split(buf, fields, MNF, argv[2]); + } + else if (argc > 2) + dosplit(argv[1], argv[2]); + else if (argc > 1) + while (fgets(buf, sizeof(buf), stdin) != NULL) { + buf[strlen(buf)-1] = '\0'; /* stomp newline */ + dosplit(buf, argv[1]); + } + else + regress(); + + exit(0); +} + +void +dosplit(char *string, char *seps) +{ +# define NF 5 + char *fields[NF]; + int nf; + + nf = split(string, fields, NF, seps); + print(nf, NF, fields); +} + +void +print(int nf, int nfp, char *fields) +{ + int fn; + int bound; + + bound = (nf > nfp) ? nfp : nf; + printf("%d:\t", nf); + for (fn = 0; fn < bound; fn++) + printf("\"%s\"%s", fields[fn], (fn+1 < nf) ? ", " : "\n"); +} + +#define RNF 5 /* some table entries know this */ +struct { + char *str; + char *seps; + int nf; + char *fi[RNF]; +} tests[] = { + "", " ", 0, { "" }, + " ", " ", 2, { "", "" }, + "x", " ", 1, { "x" }, + "xy", " ", 1, { "xy" }, + "x y", " ", 2, { "x", "y" }, + "abc def g ", " ", 5, { "abc", "def", "", "g", "" }, + " a bcd", " ", 4, { "", "", "a", "bcd" }, + "a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" }, + " a b c d ", " ", 6, { "", "a", "b", "c", "d " }, + + "", " _", 0, { "" }, + " ", " _", 2, { "", "" }, + "x", " _", 1, { "x" }, + "x y", " _", 2, { "x", "y" }, + "ab _ cd", " _", 2, { "ab", "cd" }, + " a_b c ", " _", 5, { "", "a", "b", "c", "" }, + "a b c_d e f", " _", 6, { "a", "b", "c", "d", "e f" }, + " a b c d ", " _", 6, { "", "a", "b", "c", "d " }, + + "", " _~", 0, { "" }, + " ", " _~", 2, { "", "" }, + "x", " _~", 1, { "x" }, + "x y", " _~", 2, { "x", "y" }, + "ab _~ cd", " _~", 2, { "ab", "cd" }, + " a_b c~", " _~", 5, { "", "a", "b", "c", "" }, + "a b_c d~e f", " _~", 6, { "a", "b", "c", "d", "e f" }, + "~a b c d ", " _~", 6, { "", "a", "b", "c", "d " }, + + "", " _~-", 0, { "" }, + " ", " _~-", 2, { "", "" }, + "x", " _~-", 1, { "x" }, + "x y", " _~-", 2, { "x", "y" }, + "ab _~- cd", " _~-", 2, { "ab", "cd" }, + " a_b c~", " _~-", 5, { "", "a", "b", "c", "" }, + "a b_c-d~e f", " _~-", 6, { "a", "b", "c", "d", "e f" }, + "~a-b c d ", " _~-", 6, { "", "a", "b", "c", "d " }, + + "", " ", 0, { "" }, + " ", " ", 2, { "", "" }, + "x", " ", 1, { "x" }, + "xy", " ", 1, { "xy" }, + "x y", " ", 2, { "x", "y" }, + "abc def g ", " ", 4, { "abc", "def", "g", "" }, + " a bcd", " ", 3, { "", "a", "bcd" }, + "a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" }, + " a b c d ", " ", 6, { "", "a", "b", "c", "d " }, + + "", "", 0, { "" }, + " ", "", 0, { "" }, + "x", "", 1, { "x" }, + "xy", "", 1, { "xy" }, + "x y", "", 2, { "x", "y" }, + "abc def g ", "", 3, { "abc", "def", "g" }, + "\t a bcd", "", 2, { "a", "bcd" }, + " a \tb\t c ", "", 3, { "a", "b", "c" }, + "a b c d e ", "", 5, { "a", "b", "c", "d", "e" }, + "a b\tc d e f", "", 6, { "a", "b", "c", "d", "e f" }, + " a b c d e f ", "", 6, { "a", "b", "c", "d", "e f " }, + + NULL, NULL, 0, { NULL }, +}; + +void +regress(void) +{ + char buf[512]; + int n; + char *fields[RNF+1]; + int nf; + int i; + int printit; + char *f; + + for (n = 0; tests[n].str != NULL; n++) { + (void) strcpy(buf, tests[n].str); + fields[RNF] = NULL; + nf = split(buf, fields, RNF, tests[n].seps); + printit = 0; + if (nf != tests[n].nf) { + printf("split `%s' by `%s' gave %d fields, not %d\n", + tests[n].str, tests[n].seps, nf, tests[n].nf); + printit = 1; + } else if (fields[RNF] != NULL) { + printf("split() went beyond array end\n"); + printit = 1; + } else { + for (i = 0; i < nf && i < RNF; i++) { + f = fields[i]; + if (f == NULL) + f = "(NULL)"; + if (strcmp(f, tests[n].fi[i]) != 0) { + printf("split `%s' by `%s', field %d is `%s', not `%s'\n", + tests[n].str, tests[n].seps, + i, fields[i], tests[n].fi[i]); + printit = 1; + } + } + } + if (printit) + print(nf, RNF, fields); + } +} +#endif diff --git a/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c b/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c new file mode 100644 index 0000000..f9bd276 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c @@ -0,0 +1,214 @@ +/* $NetBSD: t_exhaust.c,v 1.8 2017/01/14 00:50:56 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_exhaust.c,v 1.8 2017/01/14 00:50:56 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#ifndef REGEX_MAXSIZE +#define REGEX_MAXSIZE 9999 +#endif + +static char * +mkstr(const char *str, size_t len) +{ + size_t slen = strlen(str); + char *p = malloc(slen * len + 1); + ATF_REQUIRE(p != NULL); + for (size_t i = 0; i < len; i++) + strcpy(&p[i * slen], str); + return p; +} + +static char * +concat(const char *d, const char *s) +{ + size_t dlen = strlen(d); + size_t slen = strlen(s); + char *p = malloc(dlen + slen + 1); + + ATF_REQUIRE(p != NULL); + strcpy(p, d); + strcpy(p + dlen, s); + return p; +} + +static char * +p0(size_t len) +{ + char *d, *s1, *s2; + s1 = mkstr("\\(", len); + s2 = concat(s1, ")"); + free(s1); + d = concat("(", s2); + free(s2); + return d; +} + +static char * +p1(size_t len) +{ + char *d, *s1, *s2, *s3; + s1 = mkstr("\\(", 60); + s2 = mkstr("(.*)", len); + s3 = concat(s1, s2); + free(s2); + free(s1); + s1 = concat(s3, ")"); + free(s3); + d = concat("(", s1); + free(s1); + return d; +} + +static char * +ps(const char *m, const char *s, size_t len) +{ + char *d, *s1, *s2, *s3; + s1 = mkstr(m, len); + s2 = mkstr(s, len); + s3 = concat(s1, s2); + free(s2); + free(s1); + d = concat("(.?)", s3); + free(s3); + return d; +} + +static char * +p2(size_t len) +{ + return ps("((.*){0,255}", ")", len); +} + +static char * +p3(size_t len) +{ + return ps("(.\\{0,}", ")", len); +} + +static char * +p4(size_t len) +{ + return ps("((.*){1,255}", ")", len); +} + +static char * +p5(size_t len) +{ + return ps("(", "){1,100}", len); +} + +static char * +p6(size_t len) +{ + char *d, *s1, *s2; + s1 = mkstr("(?:(.*)|", len); + s2 = concat(s1, "(.*)"); + free(s1); + s1 = mkstr(")", len); + d = concat(s2, s1); + free(s1); + free(s2); + return d; +} + +static const struct { + char *(*pattern)(size_t); + int type; +} tests[] = { + { p0, REG_EXTENDED }, + { p1, REG_EXTENDED }, + { p2, REG_EXTENDED }, + { p3, REG_EXTENDED }, + { p4, REG_EXTENDED }, + { p5, REG_EXTENDED }, + { p6, REG_BASIC }, +}; + +ATF_TC(regcomp_too_big); + +ATF_TC_HEAD(regcomp_too_big, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that large patterns don't" + " crash, but return a proper error code"); + // libtre needs it. + atf_tc_set_md_var(tc, "timeout", "600"); + atf_tc_set_md_var(tc, "require.memory", "64M"); +} + +ATF_TC_BODY(regcomp_too_big, tc) +{ + regex_t re; + struct rlimit limit; + int e; + + limit.rlim_cur = limit.rlim_max = 64 * 1024 * 1024; + ATF_REQUIRE(setrlimit(RLIMIT_VMEM, &limit) != -1); + for (size_t i = 0; i < __arraycount(tests); i++) { + char *d = (*tests[i].pattern)(REGEX_MAXSIZE); + e = regcomp(&re, d, tests[i].type); + if (e) { + char ebuf[1024]; + (void)regerror(e, &re, ebuf, sizeof(ebuf)); + ATF_REQUIRE_MSG(e == REG_ESPACE, + "regcomp returned %d (%s) for pattern %zu [%s]", e, ebuf, + i, d); + free(d); + continue; + } + free(d); + (void)regexec(&re, "aaaaaaaaaaa", 0, NULL, 0); + regfree(&re); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, regcomp_too_big); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/regex/t_regex.sh b/contrib/netbsd-tests/lib/libc/regex/t_regex.sh new file mode 100755 index 0000000..bef3ac9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/t_regex.sh @@ -0,0 +1,73 @@ +# $NetBSD: t_regex.sh,v 1.1 2012/08/24 20:24:40 jmmv Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +check() +{ + local dataname="${1}"; shift + + prog="$(atf_get_srcdir)/h_regex" + data="$(atf_get_srcdir)/data/${dataname}.in" + + atf_check -x "${prog} <${data}" + atf_check -x "${prog} -el <${data}" + atf_check -x "${prog} -er <${data}" +} + +create_tc() +{ + local name="${1}"; shift + local descr="${1}"; shift + + atf_test_case "${name}" + eval "${name}_head() { atf_set 'descr' '${descr}'; }" + eval "${name}_body() { check '${name}'; }" + + atf_add_test_case "${name}" +} + +atf_init_test_cases() +{ + create_tc basic "Checks basic functionality" + create_tc paren "Checks parentheses" + create_tc anchor "Checks anchors and REG_NEWLINE" + create_tc error "Checks syntax errors and non-errors" + create_tc meta "Checks metacharacters and backslashes" + create_tc backref "Checks back references" + create_tc repet_ordinary "Checks ordinary repetitions" + create_tc repet_bounded "Checks bounded repetitions" + create_tc repet_multi "Checks multiple repetitions" + create_tc bracket "Checks brackets" + create_tc complex "Checks various complex examples" + create_tc subtle "Checks various subtle examples" + create_tc c_comments "Checks matching C comments" + create_tc subexp "Checks subexpressions" + create_tc startend "Checks STARTEND option" + create_tc nospec "Checks NOSPEC option" + create_tc zero "Checks NULs" + create_tc word_bound "Checks word boundaries" + create_tc regress "Checks various past problems and suspected problems" +} diff --git a/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c b/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c new file mode 100644 index 0000000..dd5b818 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c @@ -0,0 +1,630 @@ +/* $NetBSD: t_regex_att.c,v 1.3 2017/01/14 20:59:23 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_regex_att.c,v 1.3 2017/01/14 20:59:23 christos Exp $"); + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char sep[] = "\r\n\t"; +static const char delim[3] = "\\\\\0"; + + +static void +fail(const char *pattern, const char *input, size_t lineno) { + fprintf(stderr, + "skipping failed test at line %zu (pattern=%s, input=%s)\n", + lineno, pattern, input); +} + +static int +bug(const char *pattern, const char *input, size_t lineno) { + static const struct { + const char *p; + const char *i; + } b[] = { +#if defined(REGEX_SPENCER) + /* + * The default libc implementation by Henry Spencer + */ + { "a[-]?c", "ac" }, // basic.dat + { "(a*)*", "a" }, // categorization.dat + { "(aba|a*b)*", "ababa" }, // categorization.dat + { "\\(a\\(b\\)*\\)*\\2", "abab" }, // categorization.dat + { "(a*)*", "aaaaaa" }, // nullsubexpression.dat + { "(a*)*", "aaaaaax" }, // nullsubexpression.dat + { "(a*)+", "a" }, // nullsubexpression.dat + { "(a*)+", "aaaaaa" }, // nullsubexpression.dat + { "(a*)+", "aaaaaax" }, // nullsubexpression.dat + { "([a]*)*", "a" }, // nullsubexpression.dat + { "([a]*)*", "aaaaaa" }, // nullsubexpression.dat + { "([a]*)*", "aaaaaax" }, // nullsubexpression.dat + { "([a]*)+", "a" }, // nullsubexpression.dat + { "([a]*)+", "aaaaaa" }, // nullsubexpression.dat + { "([a]*)+", "aaaaaax" }, // nullsubexpression.dat + { "([^b]*)*", "a" }, // nullsubexpression.dat + { "([^b]*)*", "aaaaaa" }, // nullsubexpression.dat + { "([^b]*)*", "aaaaaab" }, // nullsubexpression.dat + { "([ab]*)*", "a" }, // nullsubexpression.dat + { "([ab]*)*", "aaaaaa" }, // nullsubexpression.dat + { "([ab]*)*", "ababab" }, // nullsubexpression.dat + { "([ab]*)*", "bababa" }, // nullsubexpression.dat + { "([ab]*)*", "b" }, // nullsubexpression.dat + { "([ab]*)*", "bbbbbb" }, // nullsubexpression.dat + { "([ab]*)*", "aaaabcde" }, // nullsubexpression.dat + { "([^a]*)*", "b" }, // nullsubexpression.dat + { "([^a]*)*", "bbbbbb" }, // nullsubexpression.dat + { "([^ab]*)*", "ccccxx" }, // nullsubexpression.dat + { "\\(a*\\)*\\(x\\)", "ax" }, // nullsubexpression.dat + { "\\(a*\\)*\\(x\\)", "axa" }, // nullsubexpression.dat + { "\\(a*\\)*\\(x\\)\\(\\1\\)", "x" }, // nullsubexpression.dat +/* crash! */ { "\\(a*\\)*\\(x\\)\\(\\1\\)", "ax" }, // nullsubexpression.dat +/* crash! */ { "\\(a*\\)*\\(x\\)\\(\\1\\)\\(x\\)", "axxa" }, // "" + { "(a*)*(x)", "ax" }, // nullsubexpression.dat + { "(a*)*(x)", "axa" }, // nullsubexpression.dat + { "(a*)+(x)", "ax" }, // nullsubexpression.dat + { "(a*)+(x)", "axa" }, // nullsubexpression.dat + { "((a|ab)(c|bcd))(d*)", "abcd" }, // forcedassoc.dat + { "((a|ab)(bcd|c))(d*)", "abcd" }, // forcedassoc.dat + { "((ab|a)(c|bcd))(d*)", "abcd" }, // forcedassoc.dat + { "((ab|a)(bcd|c))(d*)", "abcd" }, // forcedassoc.dat + { "((a*)(b|abc))(c*)", "abc" }, // forcedassoc.dat + { "((a*)(abc|b))(c*)", "abc" }, // forcedassoc.dat + { "((..)|(.)){2}", "aaa" }, // repetition.dat + { "((..)|(.)){3}", "aaa" }, // repetition.dat + { "((..)|(.)){3}", "aaaa" }, // repetition.dat + { "((..)|(.)){3}", "aaaaa" }, // repetition.dat + { "X(.?){0,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){1,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){2,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){3,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){4,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){5,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){6,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){7,}Y", "X1234567Y" }, // repetition.dat + { "X(.?){0,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){1,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){2,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){3,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){4,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){5,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){6,8}Y", "X1234567Y" }, // repetition.dat + { "X(.?){7,8}Y", "X1234567Y" }, // repetition.dat + { "(a|ab|c|bcd){0,}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){1,}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){2,}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){3,}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){1,10}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){2,10}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd){3,10}(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd)*(d*)", "ababcd" }, // repetition.dat + { "(a|ab|c|bcd)+(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){0,}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){1,}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){2,}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){3,}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){1,10}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){2,10}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd){3,10}(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd)*(d*)", "ababcd" }, // repetition.dat + { "(ab|a|c|bcd)+(d*)", "ababcd" }, // repetition.dat +#elif defined(REGEX_TRE) + { "a[-]?c", "ac" }, // basic.dat + { "a\\(b\\)*\\1", "a" }, // categorization.dat + { "a\\(b\\)*\\1", "abab" }, // categorization.dat + { "\\(a\\(b\\)*\\)*\\2", "abab" }, // categorization.dat + { "\\(a*\\)*\\(x\\)\\(\\1\\)", "ax" }, // categorization.dat + { "\\(a*\\)*\\(x\\)\\(\\1\\)\\(x\\)", "axxa" }, // "" + { "((..)|(.))*", "aa" }, // repetition.dat + { "((..)|(.))*", "aaa" }, // repetition.dat + { "((..)|(.))*", "aaaaa" }, // repetition.dat + { "X(.?){7,}Y", "X1234567Y" }, // repetition.dat +#else + { "", "" } +#endif + }; + + for (size_t i = 0; i < __arraycount(b); i++) { + if (strcmp(pattern, b[i].p) == 0 && + strcmp(input, b[i].i) == 0) { + fail(pattern, input, lineno); + return 1; + } + } + return 0; +} + +#ifdef REGEX_SPENCER +#define HAVE_BRACES 1 +#define HAVE_MINIMAL 0 +#endif +#ifndef HAVE_BRACES +#define HAVE_BRACES 1 +#endif +#ifndef HAVE_MINIMAL +#define HAVE_MINIMAL 1 +#endif + +static int +optional(const char *s) +{ + static const struct{ + const char *n; + int v; + } nv[]= { + { "[[]] not supported", HAVE_BRACES }, + { "no *? +? mimimal match ops", HAVE_MINIMAL }, + }; + + for (size_t i = 0; i < __arraycount(nv); i++) + if (strcmp(nv[i].n, s) == 0) { + if (nv[i].v) + return 0; + fprintf(stderr, "skipping unsupported [%s] tests\n", s); + return 1; + } + + ATF_REQUIRE_MSG(0, "Unknown feature: %s", s); + return 0; +} + +static int +unsupported(const char *s) +{ + static const char *we[] = { +#if defined(REGEX_SPENCER) + "ASSOCIATIVITY=left", // have right associativity + "SUBEXPRESSION=precedence", // have grouping subexpression + "REPEAT_LONGEST=last", // have first repeat longest + "BUG=alternation-order", // don't have it + "BUG=first-match", // don't have it + "BUG=nomatch-match", // don't have it + "BUG=repeat-any", // don't have it + "BUG=range-null", // don't have it + "BUG=repeat-null-unknown", // don't have it + "BUG=repeat-null", // don't have it + "BUG=repeat-artifact", // don't have it + "BUG=subexpression-first", // don't have it +#elif defined(REGEX_TRE) + "ASSOCIATIVITY=right", // have left associativity + "SUBEXPRESSION=grouping", // have precedence subexpression + "REPEAT_LONGEST=first", // have last repeat longest + "LENGTH=first", // have last length + "BUG=alternation-order", // don't have it + "BUG=first-match", // don't have it + "BUG=range-null", // don't have it + "BUG=repeat-null", // don't have it + "BUG=repeat-artifact", // don't have it + "BUG=subexpression-first", // don't have it + "BUG=repeat-short", // don't have it +#endif + }; + + if (s == NULL) + return 0; + + while (*s == '#' || isspace((unsigned char)*s)) + s++; + + for (size_t i = 0; i < __arraycount(we); i++) + if (strcmp(we[i], s) == 0) + return 1; + return 0; +} + +static void +geterror(const char *s, int *comp, int *exec) +{ + static const struct { + const char *n; + int v; + int ce; + } nv[] = { +#define COMP 1 +#define EXEC 2 + { "OK", 0, COMP|EXEC }, +#define _DO(a, b) { # a, REG_ ## a, b }, + _DO(NOMATCH, EXEC) + _DO(BADPAT, COMP) + _DO(ECOLLATE, COMP) + _DO(ECTYPE, COMP) + _DO(EESCAPE, COMP) + _DO(ESUBREG, COMP) + _DO(EBRACK, COMP) + _DO(EPAREN, COMP) + _DO(EBRACE, COMP) + _DO(BADBR, COMP) + _DO(ERANGE, COMP) + _DO(ESPACE, EXEC) + _DO(BADRPT, COMP) + _DO(EMPTY, COMP) + _DO(ASSERT, COMP) + _DO(INVARG, COMP) + _DO(ENOSYS, COMP) +#undef _DO + }; + *comp = 0; + *exec = 0; + for (size_t i = 0; i < __arraycount(nv); i++) + if (strcmp(s, nv[i].n) == 0) { + if (nv[i].ce & COMP) + *comp = nv[i].v; + if (nv[i].ce & EXEC) + *exec = nv[i].v; + return; + } + ATF_REQUIRE_MSG(0, "Unknown error %s", s); + return; +} + +static int +getflags(char *s) +{ + int flags = 0; + + for (;; s++) + switch (*s) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + *s = '\0'; + break; + case '\0': + return flags; + case 'B': + case 'E': + case 'F': + case 'L': + break; + case 'i': + flags |= REG_ICASE; + *s = '\0'; + break; + case '$': + *s = '\0'; + break; + case 'n': + *s = '\0'; + break; + default: + ATF_REQUIRE_MSG(0, "Unknown char %c", *s); + break; + } +} + +static size_t +getmatches(const char *s) +{ + size_t i; + char *q; + for (i = 0; (q = strchr(s, '(')) != NULL; i++, s = q + 1) + continue; + ATF_REQUIRE_MSG(i != 0, "No parentheses found"); + return i; +} + +static void +checkcomment(const char *s, size_t lineno) +{ + if (s && strstr(s, "BUG") != NULL) + fprintf(stderr, "Expected %s at line %zu\n", s, lineno); +} + +static void +checkmatches(const char *matches, size_t nm, const regmatch_t *pm, + size_t lineno) +{ + if (nm == 0) + return; + + char *res; + size_t len = strlen(matches) + 1, off = 0; + + ATF_REQUIRE((res = strdup(matches)) != NULL); + for (size_t i = 0; i < nm; i++) { + int l; + if (pm[i].rm_so == -1 && pm[i].rm_eo == -1) + l = snprintf(res + off, len - off, "(?,?)"); + else + l = snprintf(res + off, len - off, "(%lld,%lld)", + (long long)pm[i].rm_so, (long long)pm[i].rm_eo); + ATF_REQUIRE_MSG((size_t) l < len - off, "String too long %s" + " cur=%d, max=%zu", res, l, len - off); + off += l; + } + ATF_CHECK_STREQ_MSG(res, matches, " at line %zu", lineno); + free(res); +} + +static void +att_test(const struct atf_tc *tc, const char *data_name) +{ + regex_t re; + char *line, *lastpattern = NULL, data_path[MAXPATHLEN]; + size_t len, lineno = 0; + int skipping = 0; + FILE *input_file; + + snprintf(data_path, sizeof(data_path), "%s/data/%s.dat", + atf_tc_get_config_var(tc, "srcdir"), data_name); + + input_file = fopen(data_path, "r"); + if (input_file == NULL) + atf_tc_fail("Failed to open input file %s", data_path); + + for (; (line = fparseln(input_file, &len, &lineno, delim, 0)) + != NULL; free(line)) { + char *name, *pattern, *input, *matches, *comment; + regmatch_t *pm; + size_t nm; +#ifdef DEBUG + fprintf(stderr, "[%s]\n", line); +#endif + if ((name = strtok(line, sep)) == NULL) + continue; + + /* + * We check these early so that we skip the lines quickly + * in order to do more strict testing on the other arguments + * The same characters are also tested in the switch below + */ + if (*name == '}') { + skipping = 0; + continue; + } + if (skipping) + continue; + if (*name == ';' || *name == '#' || strcmp(name, "NOTE") == 0) + continue; + if (*name == ':') { + /* Skip ":HA#???:" prefix */ + while (*++name && *name != ':') + continue; + if (*name) + name++; + } + + ATF_REQUIRE_MSG((pattern = strtok(NULL, sep)) != NULL, + "Missing pattern at line %zu", lineno); + ATF_REQUIRE_MSG((input = strtok(NULL, sep)) != NULL, + "Missing input at line %zu", lineno); + + if (strchr(name, '$')) { + ATF_REQUIRE(strunvis(pattern, pattern) != -1); + ATF_REQUIRE(strunvis(input, input) != -1); + } + + + if (strcmp(input, "NULL") == 0) + *input = '\0'; + + if (strcmp(pattern, "SAME") == 0) { + ATF_REQUIRE(lastpattern != NULL); + pattern = lastpattern; + } else { + free(lastpattern); + ATF_REQUIRE((lastpattern = strdup(pattern)) != NULL); + } + + ATF_REQUIRE_MSG((matches = strtok(NULL, sep)) != NULL, + "Missing matches at line %zu", lineno); + + comment = strtok(NULL, sep); + switch (*name) { + case '{': /* Begin optional implementation */ + if (optional(comment)) { + skipping++; + continue; + } + name++; /* We have it, so ignore */ + break; + case '}': /* End optional implementation */ + skipping = 0; + continue; + case '?': /* Optional */ + case '|': /* Alternative */ + if (unsupported(comment)) + continue; + name++; /* We have it, so ignore */ + break; + case '#': /* Comment */ + case ';': /* Skip */ + continue; + default: + break; + } + + /* XXX: Our bug */ + if (bug(pattern, input, lineno)) + continue; + + int comp, exec; + if (*matches != '(') { + geterror(matches, &comp, &exec); + pm = NULL; + nm = 0; + } else { + comp = exec = 0; + nm = getmatches(matches); + ATF_REQUIRE((pm = calloc(nm, sizeof(*pm))) != NULL); + } + + + + int iflags = getflags(name); + for (; *name; name++) { + int flags; + switch (*name) { + case 'B': + flags = REG_BASIC; + break; + case 'E': + flags = REG_EXTENDED; + break; + case 'L': + flags = REG_NOSPEC; + break; + default: + ATF_REQUIRE_MSG(0, "Bad name %c", *name); + continue; + } + int c = regcomp(&re, pattern, flags | iflags); + ATF_REQUIRE_MSG(c == comp, + "regcomp returned %d for pattern %s at line %zu", + c, pattern, lineno); + if (c) + continue; + int e = regexec(&re, input, nm, pm, 0); + ATF_REQUIRE_MSG(e == exec, "Expected error %d," + " got %d at line %zu", exec, e, lineno); + checkmatches(matches, nm, pm, lineno); + checkcomment(comment, lineno); + regfree(&re); + } + free(pm); + } + + fclose(input_file); +} + +ATF_TC(basic); +ATF_TC_HEAD(basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests basic functionality"); +} +ATF_TC_BODY(basic, tc) +{ + att_test(tc, "basic"); +} + +ATF_TC(categorization); +ATF_TC_HEAD(categorization, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests implementation categorization"); +} +ATF_TC_BODY(categorization, tc) +{ + att_test(tc, "categorization"); +} + +ATF_TC(nullsubexpr); +ATF_TC_HEAD(nullsubexpr, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests (...)*"); +} +ATF_TC_BODY(nullsubexpr, tc) +{ + att_test(tc, "nullsubexpr"); +} + +ATF_TC(leftassoc); +ATF_TC_HEAD(leftassoc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests left-associative " + "implementations"); +} +ATF_TC_BODY(leftassoc, tc) +{ +#if SKIP_LEFTASSOC + /* jmmv: I converted the original shell-based tests to C and they + * disabled this test in a very unconventional way without giving + * any explation. Mark as broken here, but I don't know why. */ + atf_tc_expect_fail("Reason for breakage unknown"); +#endif + att_test(tc, "leftassoc"); +} + +ATF_TC(rightassoc); +ATF_TC_HEAD(rightassoc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests right-associative " + "implementations"); +} +ATF_TC_BODY(rightassoc, tc) +{ +#if SKIP_RIGHTASSOC + /* jmmv: I converted the original shell-based tests to C and they + * disabled this test in a very unconventional way without giving + * any explation. Mark as broken here, but I don't know why. */ + atf_tc_expect_fail("Reason for breakage unknown"); +#endif + att_test(tc, "rightassoc"); +} + +ATF_TC(forcedassoc); +ATF_TC_HEAD(forcedassoc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests subexpression grouping to " + "force association"); +} +ATF_TC_BODY(forcedassoc, tc) +{ + att_test(tc, "forcedassoc"); +} + +ATF_TC(repetition); +ATF_TC_HEAD(repetition, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests implicit vs. explicit " + "repetition"); +} +ATF_TC_BODY(repetition, tc) +{ + att_test(tc, "repetition"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, basic); + ATF_TP_ADD_TC(tp, categorization); + ATF_TP_ADD_TC(tp, nullsubexpr); + ATF_TP_ADD_TC(tp, leftassoc); + ATF_TP_ADD_TC(tp, rightassoc); + ATF_TP_ADD_TC(tp, forcedassoc); + ATF_TP_ADD_TC(tp, repetition); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/regex/test_regex.h b/contrib/netbsd-tests/lib/libc/regex/test_regex.h new file mode 100644 index 0000000..1d9f59d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/regex/test_regex.h @@ -0,0 +1,44 @@ +/* $NetBSD: test_regex.h,v 1.1 2011/01/08 18:10:31 pgoyette Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* from main.c */ +void regress(FILE *); +void try(char *, char *, char *, char *, char *, int); +int options(int, char *); +int opt(int, char *); +void fixstr(char *); +char *check(char *, regmatch_t, char *); + +/* from split.c */ +int split(char *string, char *fields[], int nfields, const char *sep); + +/* from debug.c */ +void regprint(regex_t *r, FILE *d); diff --git a/contrib/netbsd-tests/lib/libc/rpc/h_testbits.x b/contrib/netbsd-tests/lib/libc/rpc/h_testbits.x new file mode 100644 index 0000000..cbddfcc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/rpc/h_testbits.x @@ -0,0 +1,21 @@ +/* $NetBSD: h_testbits.x,v 1.1 2011/01/08 06:59:37 pgoyette Exp $ */ + +enum smallenum { + SE_ONE = 1, + SE_TWO = 2 +}; + +enum medenum { + ME_NEG = -1234, + ME_ONE = 1, + ME_TWO = 2, + ME_MANY = 1234 +}; + +enum bigenum { + BE_ONE = 1, + BE_TWO = 2, + BE_MANY = 1234, + BE_LOTS = 1234567 +}; + diff --git a/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c b/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c new file mode 100644 index 0000000..59bcd55 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c @@ -0,0 +1,405 @@ +/* $NetBSD: t_rpc.c,v 1.10 2016/08/27 14:36:22 christos Exp $ */ + +#include +__RCSID("$NetBSD: t_rpc.c,v 1.10 2016/08/27 14:36:22 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef TEST +#include + +#define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) + +#define SKIPX(ev, msg, ...) do { \ + atf_tc_skip(msg, __VA_ARGS__); \ + return ev; \ +} while(/*CONSTCOND*/0) + +#else +#define ERRX(ev, msg, ...) errx(EXIT_FAILURE, msg, __VA_ARGS__) +#define SKIPX(ev, msg, ...) errx(EXIT_FAILURE, msg, __VA_ARGS__) +#endif + +#ifdef DEBUG +#define DPRINTF(...) printf(__VA_ARGS__) +#else +#define DPRINTF(...) +#endif + + +#define RPCBPROC_NULL 0 + +static int +reply(caddr_t replyp, struct netbuf * raddrp, struct netconfig * nconf) +{ + char host[NI_MAXHOST]; + struct sockaddr *sock = raddrp->buf; + int error; + + + error = getnameinfo(sock, sock->sa_len, host, sizeof(host), NULL, 0, 0); + if (error) + warnx("Cannot resolve address (%s)", gai_strerror(error)); + else + printf("response from: %s\n", host); + return 0; +} + +#ifdef __FreeBSD__ +#define __rpc_control rpc_control +#endif + +extern bool_t __rpc_control(int, void *); + +static void +onehost(const char *host, const char *transp) +{ + CLIENT *clnt; + struct netbuf addr; + struct timeval tv; + + /* + * Magic! + */ + tv.tv_sec = 0; + tv.tv_usec = 500000; +#define CLCR_SET_RPCB_TIMEOUT 2 + __rpc_control(CLCR_SET_RPCB_TIMEOUT, &tv); + + if ((clnt = clnt_create(host, RPCBPROG, RPCBVERS, transp)) == NULL) + SKIPX(, "clnt_create (%s)", clnt_spcreateerror("")); + + tv.tv_sec = 1; + tv.tv_usec = 0; +#ifdef __FreeBSD__ + if (clnt_call(clnt, RPCBPROC_NULL, (xdrproc_t)xdr_void, NULL, + (xdrproc_t)xdr_void, NULL, tv) + != RPC_SUCCESS) +#else + if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv) + != RPC_SUCCESS) +#endif + ERRX(, "clnt_call (%s)", clnt_sperror(clnt, "")); + clnt_control(clnt, CLGET_SVC_ADDR, (char *) &addr); + reply(NULL, &addr, NULL); +} + +#define PROGNUM 0x81 +#define VERSNUM 0x01 +#define PLUSONE 1 +#define DESTROY 2 + +static struct timeval tout = {1, 0}; + +static void +server(struct svc_req *rqstp, SVCXPRT *transp) +{ + int num; + + DPRINTF("Starting server\n"); + + switch (rqstp->rq_proc) { + case NULLPROC: + if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL)) + ERRX(, "svc_sendreply failed %d", 0); + return; + case PLUSONE: + break; + case DESTROY: + if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL)) + ERRX(, "svc_sendreply failed %d", 0); + svc_destroy(transp); + exit(0); + default: + svcerr_noproc(transp); + return; + } + + if (!svc_getargs(transp, (xdrproc_t)xdr_int, (void *)&num)) { + svcerr_decode(transp); + return; + } + DPRINTF("About to increment\n"); + num++; + if (!svc_sendreply(transp, (xdrproc_t)xdr_int, (void *)&num)) + ERRX(, "svc_sendreply failed %d", 1); + DPRINTF("Leaving server procedure.\n"); +} + +static int +rawtest(const char *arg) +{ + CLIENT *clnt; + SVCXPRT *svc; + int num, resp; + enum clnt_stat rv; + + if (arg) + num = atoi(arg); + else + num = 0; + + svc = svc_raw_create(); + if (svc == NULL) + ERRX(EXIT_FAILURE, "Cannot create server %d", num); + if (!svc_reg(svc, PROGNUM, VERSNUM, server, NULL)) + ERRX(EXIT_FAILURE, "Cannot register server %d", num); + + clnt = clnt_raw_create(PROGNUM, VERSNUM); + if (clnt == NULL) + ERRX(EXIT_FAILURE, "%s", + clnt_spcreateerror("clnt_raw_create")); + rv = clnt_call(clnt, PLUSONE, (xdrproc_t)xdr_int, (void *)&num, + (xdrproc_t)xdr_int, (void *)&resp, tout); + if (rv != RPC_SUCCESS) + ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv)); + DPRINTF("Got %d\n", resp); + clnt_destroy(clnt); + svc_destroy(svc); + if (++num != resp) + ERRX(EXIT_FAILURE, "expected %d got %d", num, resp); + + return EXIT_SUCCESS; +} + +static int +regtest(const char *hostname, const char *transp, const char *arg, int p) +{ + CLIENT *clnt; + int num, resp; + enum clnt_stat rv; + pid_t pid; + + if (arg) + num = atoi(arg); + else + num = 0; + +#ifdef __NetBSD__ + svc_fdset_init(p ? SVC_FDSET_POLL : 0); +#endif + if (!svc_create(server, PROGNUM, VERSNUM, transp)) + { + SKIPX(EXIT_FAILURE, "Cannot create server %d", num); + } + + switch ((pid = fork())) { + case 0: + DPRINTF("Calling svc_run\n"); + svc_run(); + ERRX(EXIT_FAILURE, "svc_run returned %d!", num); + case -1: + ERRX(EXIT_FAILURE, "Fork failed (%s)", strerror(errno)); + default: + sleep(1); + break; + } + + DPRINTF("Initializing client\n"); + clnt = clnt_create(hostname, PROGNUM, VERSNUM, transp); + if (clnt == NULL) + ERRX(EXIT_FAILURE, "%s", + clnt_spcreateerror("clnt_raw_create")); + rv = clnt_call(clnt, PLUSONE, (xdrproc_t)xdr_int, (void *)&num, + (xdrproc_t)xdr_int, (void *)&resp, tout); + if (rv != RPC_SUCCESS) + ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv)); + DPRINTF("Got %d\n", resp); + if (++num != resp) + ERRX(EXIT_FAILURE, "expected %d got %d", num, resp); + rv = clnt_call(clnt, DESTROY, (xdrproc_t)xdr_void, NULL, + (xdrproc_t)xdr_void, NULL, tout); + if (rv != RPC_SUCCESS) + ERRX(EXIT_FAILURE, "clnt_call: %s", clnt_sperrno(rv)); + clnt_destroy(clnt); + + return EXIT_SUCCESS; +} + + +#ifdef TEST +static void +allhosts(const char *transp) +{ + enum clnt_stat clnt_stat; + + clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL, + (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, + NULL, (resultproc_t)reply, transp); + if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) + ERRX(EXIT_FAILURE, "%s", clnt_sperrno(clnt_stat)); +} + +int +main(int argc, char *argv[]) +{ + int ch; + int s, p; + const char *transp = "udp"; + + p = s = 0; + while ((ch = getopt(argc, argv, "prstu")) != -1) + switch (ch) { + case 'p': + p = 1; + break; + case 's': + s = 1; + break; + case 't': + transp = "tcp"; + break; + case 'u': + transp = "udp"; + break; + case 'r': + transp = NULL; + break; + default: + fprintf(stderr, + "Usage: %s -[r|s|t|u] [...]\n", + getprogname()); + return EXIT_FAILURE; + } + + if (argc == optind) { + if (transp) + allhosts(transp); + else + rawtest(NULL); + } else { + for (; optind < argc; optind++) { + if (transp) + s == 0 ? + onehost(argv[optind], transp) : + regtest(argv[optind], transp, "1", p); + else + rawtest(argv[optind]); + } + } + + return EXIT_SUCCESS; +} + +#else + +ATF_TC(get_svc_addr_tcp); +ATF_TC_HEAD(get_svc_addr_tcp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for tcp"); + +} + +ATF_TC_BODY(get_svc_addr_tcp, tc) +{ + onehost("localhost", "tcp"); + +} + +ATF_TC(get_svc_addr_udp); +ATF_TC_HEAD(get_svc_addr_udp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for udp"); +} + +ATF_TC_BODY(get_svc_addr_udp, tc) +{ + onehost("localhost", "udp"); + +} + +ATF_TC(raw); +ATF_TC_HEAD(raw, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks svc raw"); +} + +ATF_TC_BODY(raw, tc) +{ + rawtest(NULL); + +} + +ATF_TC(tcp); +ATF_TC_HEAD(tcp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks svc tcp (select)"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.user", "root"); +#endif +} + +ATF_TC_BODY(tcp, tc) +{ + regtest("localhost", "tcp", "1", 0); + +} + +ATF_TC(udp); +ATF_TC_HEAD(udp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks svc udp (select)"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.user", "root"); +#endif +} + +ATF_TC_BODY(udp, tc) +{ + regtest("localhost", "udp", "1", 0); + +} + +ATF_TC(tcp_poll); +ATF_TC_HEAD(tcp_poll, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks svc tcp (poll)"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.user", "root"); +#endif +} + +ATF_TC_BODY(tcp_poll, tc) +{ + regtest("localhost", "tcp", "1", 1); + +} + +ATF_TC(udp_poll); +ATF_TC_HEAD(udp_poll, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks svc udp (poll)"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.user", "root"); +#endif +} + +ATF_TC_BODY(udp_poll, tc) +{ + regtest("localhost", "udp", "1", 1); + +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, get_svc_addr_udp); + ATF_TP_ADD_TC(tp, get_svc_addr_tcp); + ATF_TP_ADD_TC(tp, raw); + ATF_TP_ADD_TC(tp, tcp); + ATF_TP_ADD_TC(tp, udp); + ATF_TP_ADD_TC(tp, tcp_poll); + ATF_TP_ADD_TC(tp, udp_poll); + + return atf_no_error(); +} + +#endif diff --git a/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c b/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c new file mode 100644 index 0000000..2a68eb4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c @@ -0,0 +1,129 @@ +/* $NetBSD: t_xdr.c,v 1.1 2011/01/08 06:59:37 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Ben Harris. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c) 2001 Ben Harris + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_xdr.c,v 1.1 2011/01/08 06:59:37 pgoyette Exp $"); + +#include +#include + +#include + +#include + +#include "h_testbits.h" + +char xdrdata[] = { + 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* double 1.0 */ + 0x00, 0x00, 0x00, 0x01, /* enum smallenum SE_ONE */ + 0xff, 0xff, 0xfb, 0x2e, /* enum medenum ME_NEG */ + 0x00, 0x12, 0xd6, 0x87, /* enum bigenum BE_LOTS */ +}; + +ATF_TC(xdr); +ATF_TC_HEAD(xdr, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks encoding/decoding of doubles and enumerations"); +} +ATF_TC_BODY(xdr, tc) +{ + XDR x; + double d; + smallenum s; + medenum m; + bigenum b; + char newdata[sizeof(xdrdata)]; + + xdrmem_create(&x, xdrdata, sizeof(xdrdata), XDR_DECODE); + + ATF_REQUIRE_MSG(xdr_double(&x, &d), "xdr_double DECODE failed"); + ATF_REQUIRE_EQ_MSG(d, 1.0, "double 1.0 decoded as %g", d); + + ATF_REQUIRE_MSG(xdr_smallenum(&x, &s), "xdr_smallenum DECODE failed"); + ATF_REQUIRE_EQ_MSG(s, SE_ONE, "SE_ONE decoded as %d", s); + + ATF_REQUIRE_MSG(xdr_medenum(&x, &m), "xdr_medenum DECODE failed"); + ATF_REQUIRE_EQ_MSG(m, ME_NEG, "ME_NEG decoded as %d", m); + + ATF_REQUIRE_MSG(xdr_bigenum(&x, &b), "xdr_bigenum DECODE failed"); + ATF_REQUIRE_EQ_MSG(b, BE_LOTS, "BE_LOTS decoded as %d", b); + + xdr_destroy(&x); + + + xdrmem_create(&x, newdata, sizeof(newdata), XDR_ENCODE); + + ATF_REQUIRE_MSG(xdr_double(&x, &d), "xdr_double ENCODE failed"); + ATF_REQUIRE_MSG(xdr_smallenum(&x, &s), "xdr_smallenum ENCODE failed"); + ATF_REQUIRE_MSG(xdr_medenum(&x, &m), "xdr_medenum ENCODE failed"); + ATF_REQUIRE_MSG(xdr_bigenum(&x, &b), "xdr_bigenum ENCODE failed"); + ATF_REQUIRE_MSG(memcmp(newdata, xdrdata, sizeof(xdrdata)) == 0, + "xdr ENCODE result differs"); + + xdr_destroy(&x); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, xdr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c b/contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c new file mode 100644 index 0000000..1f0f1ed --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c @@ -0,0 +1,196 @@ +/* $NetBSD: t_setjmp.c,v 1.2 2017/01/14 21:08:17 christos Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Copyright (c) 1994 Christopher G. Demetriou + * 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 for the + * NetBSD Project. See http://www.NetBSD.org/ for + * information about NetBSD. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_setjmp.c,v 1.2 2017/01/14 21:08:17 christos Exp $"); + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) + +#define TEST_SETJMP 0 +#define TEST_U_SETJMP 1 +#define TEST_SIGSETJMP_SAVE 2 +#define TEST_SIGSETJMP_NOSAVE 3 + +static int expectsignal; + +static void +aborthandler(int signo __unused) +{ + ATF_REQUIRE_MSG(expectsignal, "kill(SIGABRT) succeeded"); + atf_tc_pass(); +} + +static void +h_check(int test) +{ + struct sigaction sa; + jmp_buf jb; + sigjmp_buf sjb; + sigset_t ss; + int i, x; + + i = getpid(); + + if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE) + expectsignal = 0; + else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE) + expectsignal = 1; + else + atf_tc_fail("unknown test"); + + sa.sa_handler = aborthandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1); + REQUIRE_ERRNO(sigemptyset(&ss) != -1); + REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1); + REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1); + + if (test == TEST_SETJMP) + x = setjmp(jb); + else if (test == TEST_U_SETJMP) + x = _setjmp(jb); + else + x = sigsetjmp(sjb, !expectsignal); + + if (x != 0) { + ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value"); + kill(i, SIGABRT); + ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed"); + atf_tc_pass(); + } + + REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1); + + if (test == TEST_SETJMP) + longjmp(jb, i); + else if (test == TEST_U_SETJMP) + _longjmp(jb, i); + else + siglongjmp(sjb, i); + + atf_tc_fail("jmp failed"); +} + +ATF_TC(setjmp); +ATF_TC_HEAD(setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks setjmp(3)"); +} +ATF_TC_BODY(setjmp, tc) +{ + h_check(TEST_SETJMP); +} + +ATF_TC(_setjmp); +ATF_TC_HEAD(_setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks _setjmp(3)"); +} +ATF_TC_BODY(_setjmp, tc) +{ + h_check(TEST_U_SETJMP); +} + +ATF_TC(sigsetjmp_save); +ATF_TC_HEAD(sigsetjmp_save, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks sigsetjmp(3) with savemask enabled"); +} +ATF_TC_BODY(sigsetjmp_save, tc) +{ + h_check(TEST_SIGSETJMP_SAVE); +} + +ATF_TC(sigsetjmp_nosave); +ATF_TC_HEAD(sigsetjmp_nosave, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks sigsetjmp(3) with savemask disabled"); +} +ATF_TC_BODY(sigsetjmp_nosave, tc) +{ + h_check(TEST_SIGSETJMP_NOSAVE); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, setjmp); + ATF_TP_ADD_TC(tp, _setjmp); + ATF_TP_ADD_TC(tp, sigsetjmp_save); + ATF_TP_ADD_TC(tp, sigsetjmp_nosave); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c b/contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c new file mode 100644 index 0000000..44d7555 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c @@ -0,0 +1,218 @@ +/* $NetBSD: t_threadjmp.c,v 1.2 2017/01/14 21:08:17 christos Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Copyright (c) 1994 Christopher G. Demetriou + * 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 for the + * NetBSD Project. See http://www.NetBSD.org/ for + * information about NetBSD. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_threadjmp.c,v 1.2 2017/01/14 21:08:17 christos Exp $"); + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) + +#define TEST_SETJMP 0 +#define TEST_U_SETJMP 1 +#define TEST_SIGSETJMP_SAVE 2 +#define TEST_SIGSETJMP_NOSAVE 3 + +static pthread_t myself = NULL; + +static int expectsignal; + +static void +aborthandler(int signo __unused) +{ + ATF_REQUIRE(myself == pthread_self()); + ATF_REQUIRE_MSG(expectsignal, "kill(SIGABRT) succeeded"); + atf_tc_pass(); +} + +static void +h_check(int test) +{ + struct sigaction sa; + jmp_buf jb; + sigjmp_buf sjb; + sigset_t ss; + int i, x; + + myself = pthread_self(); + i = getpid(); + + if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE) + expectsignal = 0; + else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE) + expectsignal = 1; + else + atf_tc_fail("unknown test"); + + sa.sa_handler = aborthandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1); + REQUIRE_ERRNO(sigemptyset(&ss) != -1); + REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1); + REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1); + ATF_REQUIRE(myself == pthread_self()); + + if (test == TEST_SETJMP) + x = setjmp(jb); + else if (test == TEST_U_SETJMP) + x = _setjmp(jb); + else + x = sigsetjmp(sjb, !expectsignal); + + if (x != 0) { + ATF_REQUIRE(myself == pthread_self()); + ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value"); + kill(i, SIGABRT); + ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed"); + ATF_REQUIRE(myself == pthread_self()); + atf_tc_pass(); + } + + ATF_REQUIRE(myself == pthread_self()); + REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1); + + if (test == TEST_SETJMP) + longjmp(jb, i); + else if (test == TEST_U_SETJMP) + _longjmp(jb, i); + else + siglongjmp(sjb, i); + + atf_tc_fail("jmp failed"); +} + +ATF_TC(setjmp); +ATF_TC_HEAD(setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_self() and setjmp(3)"); +} +ATF_TC_BODY(setjmp, tc) +{ + h_check(TEST_SETJMP); +} + +ATF_TC(_setjmp); +ATF_TC_HEAD(_setjmp, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_self() and _setjmp(3)"); +} +ATF_TC_BODY(_setjmp, tc) +{ + h_check(TEST_U_SETJMP); +} + +ATF_TC(sigsetjmp_save); +ATF_TC_HEAD(sigsetjmp_save, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_self() and sigsetjmp(3) with savemask enabled"); +} +ATF_TC_BODY(sigsetjmp_save, tc) +{ + h_check(TEST_SIGSETJMP_SAVE); +} + +ATF_TC(sigsetjmp_nosave); +ATF_TC_HEAD(sigsetjmp_nosave, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_self() and sigsetjmp(3) with savemask disabled"); +} +ATF_TC_BODY(sigsetjmp_nosave, tc) +{ + h_check(TEST_SIGSETJMP_NOSAVE); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * These test cases try to verify setjmp and friends in a program + * linked with pthreads, and verify that pthread_self() stays + * consistent throughout the program. A setcontext() call invoked + * by *setjmp() might clobber the TLS special register used to + * implement pthread_self(). + */ + ATF_TP_ADD_TC(tp, setjmp); + ATF_TP_ADD_TC(tp, _setjmp); + ATF_TP_ADD_TC(tp, sigsetjmp_save); + ATF_TP_ADD_TC(tp, sigsetjmp_nosave); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_fgets.c b/contrib/netbsd-tests/lib/libc/ssp/h_fgets.c new file mode 100644 index 0000000..ad9376a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_fgets.c @@ -0,0 +1,46 @@ +/* $NetBSD: h_fgets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_fgets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + (void)fgets(b, len, stdin); + (void)printf("%s\n", b); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c b/contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c new file mode 100644 index 0000000..68e3a6f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c @@ -0,0 +1,47 @@ +/* $NetBSD: h_getcwd.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_getcwd.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[MAXPATHLEN]; + size_t len = atoi(argv[1]); + (void)getcwd(b, len); + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_gets.c b/contrib/netbsd-tests/lib/libc/ssp/h_gets.c new file mode 100644 index 0000000..8c601b0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_gets.c @@ -0,0 +1,43 @@ +/* $NetBSD: h_gets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_gets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + (void)gets(b); + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c new file mode 100644 index 0000000..1950f73 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c @@ -0,0 +1,48 @@ +/* $NetBSD: h_memcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_memcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + + (void)memcpy(b, "1020202020202", len); + (void)printf("%*.*s\n", len, len, b); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_memmove.c b/contrib/netbsd-tests/lib/libc/ssp/h_memmove.c new file mode 100644 index 0000000..0ebfd29 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_memmove.c @@ -0,0 +1,48 @@ +/* $NetBSD: h_memmove.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_memmove.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + + (void)memmove(b, "1020202020202", len); + (void)printf("%*.*s\n", len, len, b); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_memset.c b/contrib/netbsd-tests/lib/libc/ssp/h_memset.c new file mode 100644 index 0000000..f1acbbd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_memset.c @@ -0,0 +1,45 @@ +/* $NetBSD: h_memset.c,v 1.2 2017/01/16 16:34:24 christos Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_memset.c,v 1.2 2017/01/16 16:34:24 christos Exp $"); + +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + size_t len = atoi(argv[1]); + (void)memset(b, 0, len); + return b[0]; /* keeps optimizer from zapping the call to memset() */ +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_raw.c b/contrib/netbsd-tests/lib/libc/ssp/h_raw.c new file mode 100644 index 0000000..a232481 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_raw.c @@ -0,0 +1,57 @@ +/* $NetBSD: h_raw.c,v 1.6 2011/07/24 14:00:36 christos Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_raw.c,v 1.6 2011/07/24 14:00:36 christos Exp $"); + +#include +#include + +void poke(int *, size_t); + +void +poke(int *b, size_t index) +{ + size_t i; + volatile int sum = 0; + + b[index] = 42; + for (i = 0; i < 10; i++) + sum += b[i]; +} + +int +main(int argc, char *argv[]) +{ + int b[10]; + + poke(b, atoi(argv[1])); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_read.c b/contrib/netbsd-tests/lib/libc/ssp/h_read.c new file mode 100644 index 0000000..046ac62 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_read.c @@ -0,0 +1,54 @@ +/* $NetBSD: h_read.c,v 1.2 2017/01/16 16:35:57 christos Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_read.c,v 1.2 2017/01/16 16:35:57 christos Exp $"); + +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[MAXPATHLEN]; + int fd, n; + size_t len = atoi(argv[1]); + + if ((fd = open(_PATH_DEVZERO, O_RDONLY)) == -1) + abort(); + if ((n = read(fd, b, len)) == -1) + abort(); + (void)printf("%s\n", b); + return (0); +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c new file mode 100644 index 0000000..30e9c1e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c @@ -0,0 +1,65 @@ +/* $NetBSD: h_readlink.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_readlink.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include +#include +#include +#include + +#ifdef __FreeBSD__ +#include +#include +#endif + +int +main(int argc, char *argv[]) +{ +#ifdef __FreeBSD__ + char b[512], *sl; + size_t len = atoi(argv[1]); + sl = malloc(len); + memset(sl, 'a', len); + sl[len - 1] = 0; + unlink("symlink"); + if (symlink(sl, "symlink") == -1) + err(1, "symlink()"); + (void)readlink("symlink", b, len); + unlink("symlink"); +#else + char b[MAXPATHLEN]; + size_t len = atoi(argv[1]); + (void)readlink("/", b, len); +#endif + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c new file mode 100644 index 0000000..7576788 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c @@ -0,0 +1,51 @@ +/* $NetBSD: h_snprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_snprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + size_t len = atoi(argv[1]); +#ifdef __FreeBSD__ + char c[] = "01234567890123456789"; + c[len] = 0; + (void)snprintf(b, len, "%s", c); +#else + (void)snprintf(b, len, "%s", "0123456789"); +#endif + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c new file mode 100644 index 0000000..0f6d0cb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c @@ -0,0 +1,43 @@ +/* $NetBSD: h_sprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_sprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + (void)sprintf(b, "%s", argv[1]); + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c new file mode 100644 index 0000000..c8dfbb7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c @@ -0,0 +1,49 @@ +/* $NetBSD: h_stpcpy.c,v 1.1 2014/04/06 19:28:59 christos Exp $ */ + +/* + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_stpcpy.c,v 1.1 2014/04/06 19:28:59 christos Exp $"); + +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + char *q = stpcpy(b, argv[1]); + + if ((size_t)(q - b) != strlen(argv[1])) + abort(); + + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c new file mode 100644 index 0000000..c03d2a8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c @@ -0,0 +1,56 @@ +/* $NetBSD: h_stpncpy.c,v 1.2 2014/04/07 15:09:20 christos Exp $ */ + +/* + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_stpncpy.c,v 1.2 2014/04/07 15:09:20 christos Exp $"); + +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); +#if __GNUC_PREREQ__(4, 8) + char *q = stpncpy(b, "1020202020202", len); + + if (q - b != len) + abort(); +#else + // gcc-4.5 lacks __builtin___stpncpy_chk, lose. + (void)strncpy(b, "1020202020202", len); +#endif + + (void)printf("%*.*s\n", len, len, b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strcat.c b/contrib/netbsd-tests/lib/libc/ssp/h_strcat.c new file mode 100644 index 0000000..687acf7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_strcat.c @@ -0,0 +1,46 @@ +/* $NetBSD: h_strcat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_strcat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + (void)strcpy(b, "1"); + (void)strcat(b, argv[1]); + + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c new file mode 100644 index 0000000..2a7f1f5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c @@ -0,0 +1,45 @@ +/* $NetBSD: h_strcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_strcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + (void)strcpy(b, argv[1]); + + (void)printf("%s\n", b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strncat.c b/contrib/netbsd-tests/lib/libc/ssp/h_strncat.c new file mode 100644 index 0000000..0d66c7b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_strncat.c @@ -0,0 +1,48 @@ +/* $NetBSD: h_strncat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_strncat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + (void)strcpy(b, "1"); + (void)strncat(b, "1020202020202", len); + + (void)printf("%*.*s\n", len, len, b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c new file mode 100644 index 0000000..fddf67b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c @@ -0,0 +1,47 @@ +/* $NetBSD: h_strncpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_strncpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $"); + +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + char b[10]; + int len = atoi(argv[1]); + (void)strncpy(b, "1020202020202", len); + + (void)printf("%*.*s\n", len, len, b); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c new file mode 100644 index 0000000..0f6af85 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c @@ -0,0 +1,57 @@ +/* $NetBSD: h_vsnprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_vsnprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $"); + +#include +#include +#include + +static void wrap(size_t, const char *, ...) __printflike(2, 3); + +void +wrap(size_t len, const char *fmt, ...) +{ + char b[10]; + va_list ap; + va_start(ap, fmt); + (void)vsnprintf(b, len, fmt, ap); + (void)printf("%s\n", b); + va_end(ap); +} + +int +main(int argc, char *argv[]) +{ + size_t len = atoi(argv[1]); + wrap(len, "%s", "012345678901234567890"); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c new file mode 100644 index 0000000..c7fc780 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c @@ -0,0 +1,55 @@ +/* $NetBSD: h_vsprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_vsprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $"); + +#include +#include + +static void wrap(const char *, ...) __printflike(1, 2); + +static void +wrap(const char *fmt, ...) +{ + char b[10]; + va_list ap; + va_start(ap, fmt); + (void)vsprintf(b, fmt, ap); + (void)printf("%s\n", b); + va_end(ap); +} + +int +main(int argc, char *argv[]) +{ + wrap("%s", argv[1]); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh b/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh new file mode 100755 index 0000000..7b963d1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh @@ -0,0 +1,465 @@ +# $NetBSD: t_ssp.sh,v 1.7 2014/04/06 19:28:59 christos Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +h_pass() +{ + echo "Executing command [ $2$1 ]" + eval $2 atf_check -s exit:0 -o ignore -e ignore $1 +} + +h_fail() +{ + echo "Executing command [ $2$1 ]" + # Begin FreeBSD + ulimit -c 0 + if true; then + eval $2 atf_check -s signal -o ignore -e ignore $1 + else + # End FreeBSD + eval $2 atf_check -s signal:6 -o ignore -e ignore $1 + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case sprintf +sprintf_head() +{ + atf_set "descr" "Checks sprintf(3)" +} +sprintf_body() +{ + prog="$(atf_get_srcdir)/h_sprintf" + + h_pass "$prog ok" + # Begin FreeBSD + if true; then + h_fail "$prog 0123456789ab" + else + # End FreeBSD + h_fail "$prog 0123456789" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case vsprintf +vsprintf_head() +{ + atf_set "descr" "Checks vsprintf(3)" +} +vsprintf_body() +{ + prog="$(atf_get_srcdir)/h_vsprintf" + + h_pass "$prog ok" + # Begin FreeBSD + if true; then + h_fail "$prog 0123456789ab" + else + # End FreeBSD + h_fail "$prog 0123456789" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case snprintf +snprintf_head() +{ + atf_set "descr" "Checks snprintf(3)" +} +snprintf_body() +{ + prog="$(atf_get_srcdir)/h_snprintf" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case vsnprintf +vsnprintf_head() +{ + atf_set "descr" "Checks vsnprintf(3)" +} +vsnprintf_body() +{ + prog="$(atf_get_srcdir)/h_vsnprintf" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case gets +gets_head() +{ + atf_set "descr" "Checks gets(3)" +} +gets_body() +{ + prog="$(atf_get_srcdir)/h_gets" + + h_pass "$prog" "echo ok |" + # Begin FreeBSD + if true; then + h_fail "$prog" "echo 0123456789ab |" + else + # End FreeBSD + h_fail "$prog" "echo 0123456789 |" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case fgets +fgets_head() +{ + atf_set "descr" "Checks fgets(3)" +} +fgets_body() +{ + prog="$(atf_get_srcdir)/h_fgets" + + h_pass "$prog 10" "echo ok |" + # Begin FreeBSD + if true; then + h_fail "$prog 13" "echo 0123456789abc |" + else + # End FreeBSD + h_fail "$prog 11" "echo busted |" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case memcpy +memcpy_head() +{ + atf_set "descr" "Checks memcpy(3)" +} +memcpy_body() +{ + prog="$(atf_get_srcdir)/h_memcpy" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case memmove +memmove_head() +{ + atf_set "descr" "Checks memmove(3)" +} +memmove_body() +{ + prog="$(atf_get_srcdir)/h_memmove" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case memset +memset_head() +{ + atf_set "descr" "Checks memset(3)" +} +memset_body() +{ + prog="$(atf_get_srcdir)/h_memset" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case strcpy +strcpy_head() +{ + atf_set "descr" "Checks strcpy(3)" +} +strcpy_body() +{ + prog="$(atf_get_srcdir)/h_strcpy" + + h_pass "$prog 0123456" + # Begin FreeBSD + if true; then + h_fail "$prog 0123456789ab" + else + # End FreeBSD + h_fail "$prog 0123456789" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case stpcpy +stpcpy_head() +{ + atf_set "descr" "Checks stpcpy(3)" +} +stpcpy_body() +{ + prog="$(atf_get_srcdir)/h_stpcpy" + + h_pass "$prog 0123456" + # Begin FreeBSD + if true; then + h_fail "$prog 0123456789ab" + else + # End FreeBSD + h_fail "$prog 0123456789" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case strcat +strcat_head() +{ + atf_set "descr" "Checks strcat(3)" +} +strcat_body() +{ + prog="$(atf_get_srcdir)/h_strcat" + + h_pass "$prog 0123456" + h_fail "$prog 0123456789ABCDEF" +} + +atf_test_case strncpy +strncpy_head() +{ + atf_set "descr" "Checks strncpy(3)" +} +strncpy_body() +{ + prog="$(atf_get_srcdir)/h_strncpy" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case stpncpy +stpncpy_head() +{ + atf_set "descr" "Checks stpncpy(3)" +} +stpncpy_body() +{ + prog="$(atf_get_srcdir)/h_stpncpy" + + h_pass "$prog 10" + # Begin FreeBSD + if true; then + h_fail "$prog 13" + else + # End FreeBSD + h_fail "$prog 11" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case strncat +strncat_head() +{ + atf_set "descr" "Checks strncat(3)" +} +strncat_body() +{ + prog="$(atf_get_srcdir)/h_strncat" + + # Begin FreeBSD + h_pass "$prog 8" + if true; then + h_fail "$prog 11" + else + # End FreeBSD + h_fail "$prog 9" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case raw +raw_head() +{ + atf_set "descr" "Checks raw array overflow" +} +raw_body() +{ + prog="$(atf_get_srcdir)/h_raw" + # Begin FreeBSD + [ -x $prog ] || atf_skip "$prog is missing; skipping testcase" + # End FreeBSD + + h_pass "$prog 9" + # Begin FreeBSD + if true; then + h_fail "$prog 12" + else + # End FreeBSD + h_fail "$prog 10" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case read +read_head() +{ + atf_set "descr" "Checks read(2)" +} +read_body() +{ + prog="$(atf_get_srcdir)/h_read" + + # Begin FreeBSD + if true; then + MAX_PATH=$(getconf _XOPEN_PATH_MAX) || atf_fail "getconf failed" + h_pass "$prog $MAX_PATH" "echo foo |" + h_fail "$prog $(( $MAX_PATH + 3 ))" "echo bar |" + else + # End FreeBSD + h_pass "$prog 1024" "echo foo |" + h_fail "$prog 1025" "echo bar |" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case readlink +readlink_head() +{ + atf_set "descr" "Checks readlink(2)" +} +readlink_body() +{ + prog="$(atf_get_srcdir)/h_readlink" + + # Begin FreeBSD + if true; then + h_pass "$prog 512" + h_fail "$prog 523" + else + # End FreeBSD + h_pass "$prog 1024" + h_fail "$prog 1025" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_test_case getcwd +getcwd_head() +{ + atf_set "descr" "Checks getcwd(3)" +} +getcwd_body() +{ + prog="$(atf_get_srcdir)/h_getcwd" + + h_pass "$prog 1024" + # Begin FreeBSD + if false; then + # End FreeBSD + h_fail "$prog 1025" + # Begin FreeBSD + fi + # End FreeBSD +} + +atf_init_test_cases() +{ + atf_add_test_case sprintf + atf_add_test_case vsprintf + atf_add_test_case snprintf + atf_add_test_case vsnprintf + atf_add_test_case gets + atf_add_test_case fgets + atf_add_test_case memcpy + atf_add_test_case memmove + atf_add_test_case memset + atf_add_test_case stpcpy + atf_add_test_case stpncpy + atf_add_test_case strcat + atf_add_test_case strcpy + atf_add_test_case strncat + atf_add_test_case strncpy + atf_add_test_case raw + atf_add_test_case read + atf_add_test_case readlink + atf_add_test_case getcwd +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c b/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c new file mode 100644 index 0000000..251804e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c @@ -0,0 +1,93 @@ +/* $NetBSD: t_clearerr.c,v 1.1 2011/05/01 16:36:37 jruoho Exp $ */ + +/* + * Copyright (c) 2009, Stathis Kamperis + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_clearerr.c,v 1.1 2011/05/01 16:36:37 jruoho Exp $"); + +#include +#include +#include + +static const char path[] = "/etc/passwd"; + +ATF_TC(clearerr_basic); +ATF_TC_HEAD(clearerr_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of clearerr(3)"); +} + +ATF_TC_BODY(clearerr_basic, tc) +{ + char buf[2048]; + FILE *fp; + + fp = fopen(path, "r"); + ATF_REQUIRE(fp != NULL); + + while (feof(fp) == 0) + (void)fread(buf, sizeof(buf), 1, fp); + + ATF_REQUIRE(feof(fp) != 0); + + errno = 0; + clearerr(fp); + + ATF_REQUIRE(errno == 0); + ATF_REQUIRE(feof(fp) == 0); + ATF_REQUIRE(fclose(fp) != EOF); +} + +ATF_TC(clearerr_err); +ATF_TC_HEAD(clearerr_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that clearerr(3) does not fail"); +} + +ATF_TC_BODY(clearerr_err, tc) +{ + FILE *fp; + + fp = fopen(path, "r"); + + ATF_REQUIRE(fp != NULL); + ATF_REQUIRE(fclose(fp) == 0); + + errno = 0; + clearerr(fp); + + ATF_REQUIRE(errno == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clearerr_basic); + ATF_TP_ADD_TC(tp, clearerr_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c b/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c new file mode 100644 index 0000000..70498c3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c @@ -0,0 +1,175 @@ +/* $NetBSD: t_fflush.c,v 1.1 2011/09/11 05:15:55 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_fflush.c,v 1.1 2011/09/11 05:15:55 jruoho Exp $"); + +#include +#include +#include +#include + +static const char *path = "fflush"; + +ATF_TC_WITH_CLEANUP(fflush_err); +ATF_TC_HEAD(fflush_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fflush(3)"); +} + +ATF_TC_BODY(fflush_err, tc) +{ + FILE *f; + +#ifdef __FreeBSD__ + atf_tc_expect_fail("the EOF invariant fails on FreeBSD; this is new"); +#endif + + f = fopen(path, "w"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fflush(NULL) == 0); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r"); + ATF_REQUIRE(f != NULL); + + /* + * In NetBSD the call should fail if the supplied + * parameteris not an open stream or the stream is + * not open for writing. + */ + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fflush(f) == EOF); + + ATF_REQUIRE(fclose(f) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fflush(f) == EOF); + + (void)unlink(path); +} + +ATF_TC_CLEANUP(fflush_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fflush_seek); +ATF_TC_HEAD(fflush_seek, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test file offsets with fflush(3)"); +} + +ATF_TC_BODY(fflush_seek, tc) +{ + char buf[12]; + int fd = -1; + FILE *f; + + /* + * IEEE Std 1003.1-2008: + * + * "For a stream open for reading, if the file + * is not already at EOF, and the file is one + * capable of seeking, the file offset of the + * underlying open file description shall be + * adjusted so that the next operation on the + * open file description deals with the byte + * after the last one read from or written to + * the stream being flushed." + */ + f = fopen(path, "w"); + ATF_REQUIRE(f != NULL); + + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r+"); + ATF_REQUIRE(f != NULL); + + fd = fileno(f); + ATF_REQUIRE(fd != -1); + + ATF_REQUIRE(fread(buf, 1, 3, f) == 3); + ATF_REQUIRE(fflush(f) == 0); + ATF_REQUIRE(fseek(f, 0, SEEK_CUR) == 0); + + /* + * Verify that the offsets are right and that + * a read operation resumes at the correct location. + */ + ATF_REQUIRE(ftell(f) == 3); + ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == 3); + ATF_REQUIRE(fgetc(f) == 'b'); + + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fflush_seek, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fpurge_err); +ATF_TC_HEAD(fpurge_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fpurge(3)"); +} + +ATF_TC_BODY(fpurge_err, tc) +{ + FILE *f; + + f = fopen(path, "w"); + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fpurge(f) == EOF); + + (void)unlink(path); +} + +ATF_TC_CLEANUP(fpurge_err, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fflush_err); + ATF_TP_ADD_TC(tp, fflush_seek); + ATF_TP_ADD_TC(tp, fpurge_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c b/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c new file mode 100644 index 0000000..31b76d0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c @@ -0,0 +1,1181 @@ +/* $NetBSD: t_fmemopen.c,v 1.4 2013/10/19 17:45:00 christos Exp $ */ + +/*- + * Copyright (c)2010 Takehiko NOZAKI, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + */ + +#if defined(__FreeBSD__) || defined(__NetBSD__) +#include +#else +#if defined(__linux__) +#define _GNU_SOURCE +#include +#endif +#include +#include +#define ATF_TC(arg0) static void arg0##_head(void) +#define ATF_TC_HEAD(arg0, arg1) static void arg0##_head() +#define atf_tc_set_md_var(arg0, arg1, ...) do { \ + printf(__VA_ARGS__); \ + puts(""); \ +} while (/*CONSTCOND*/0) +#define ATF_TC_BODY(arg0, arg1) static void arg0##_body() +#define ATF_CHECK(arg0) assert(arg0) +#define ATF_TP_ADD_TCS(arg0) int main(void) +#define ATF_TP_ADD_TC(arg0, arg1) arg1##_head(); arg1##_body() +#define atf_no_error() 0 +#endif + +#include +#include +#include +#include +#include +#include + +const char *mode_rwa[] = { + "r", "rb", "r+", "rb+", "r+b", + "w", "wb", "w+", "wb+", "w+b", + "a", "ab", "a+", "ab+", "a+b", + NULL +}; + +const char *mode_r[] = { "r", "rb", "r+", "rb+", "r+b", NULL }; +const char *mode_w[] = { "w", "wb", "w+", "wb+", "w+b", NULL }; +const char *mode_a[] = { "a", "ab", "a+", "ab+", "a+b", NULL }; + +struct testcase { + const char *s; + off_t n; +} testcases[] = { +#define TESTSTR(s) { s, sizeof(s)-1 } + TESTSTR("\0he quick brown fox jumps over the lazy dog"), + TESTSTR("T\0e quick brown fox jumps over the lazy dog"), + TESTSTR("Th\0 quick brown fox jumps over the lazy dog"), + TESTSTR("The\0quick brown fox jumps over the lazy dog"), + TESTSTR("The \0uick brown fox jumps over the lazy dog"), + TESTSTR("The q\0ick brown fox jumps over the lazy dog"), + TESTSTR("The qu\0ck brown fox jumps over the lazy dog"), + TESTSTR("The qui\0k brown fox jumps over the lazy dog"), + TESTSTR("The quic\0 brown fox jumps over the lazy dog"), + TESTSTR("The quick\0brown fox jumps over the lazy dog"), + TESTSTR("The quick \0rown fox jumps over the lazy dog"), + TESTSTR("The quick b\0own fox jumps over the lazy dog"), + TESTSTR("The quick br\0wn fox jumps over the lazy dog"), + TESTSTR("The quick bro\0n fox jumps over the lazy dog"), + TESTSTR("The quick brow\0 fox jumps over the lazy dog"), + TESTSTR("The quick brown\0fox jumps over the lazy dog"), + TESTSTR("The quick brown \0ox jumps over the lazy dog"), + TESTSTR("The quick brown f\0x jumps over the lazy dog"), + TESTSTR("The quick brown fo\0 jumps over the lazy dog"), + TESTSTR("The quick brown fox\0jumps over the lazy dog"), + TESTSTR("The quick brown fox \0umps over the lazy dog"), + TESTSTR("The quick brown fox j\0mps over the lazy dog"), + TESTSTR("The quick brown fox ju\0ps over the lazy dog"), + TESTSTR("The quick brown fox jum\0s over the lazy dog"), + TESTSTR("The quick brown fox jump\0 over the lazy dog"), + TESTSTR("The quick brown fox jumps\0over the lazy dog"), + TESTSTR("The quick brown fox jumps \0ver the lazy dog"), + TESTSTR("The quick brown fox jumps o\0er the lazy dog"), + TESTSTR("The quick brown fox jumps ov\0r the lazy dog"), + TESTSTR("The quick brown fox jumps ove\0 the lazy dog"), + TESTSTR("The quick brown fox jumps over\0the lazy dog"), + TESTSTR("The quick brown fox jumps over \0he lazy dog"), + TESTSTR("The quick brown fox jumps over t\0e lazy dog"), + TESTSTR("The quick brown fox jumps over th\0 lazy dog"), + TESTSTR("The quick brown fox jumps over the\0lazy dog"), + TESTSTR("The quick brown fox jumps over the \0azy dog"), + TESTSTR("The quick brown fox jumps over the l\0zy dog"), + TESTSTR("The quick brown fox jumps over the la\0y dog"), + TESTSTR("The quick brown fox jumps over the laz\0 dog"), + TESTSTR("The quick brown fox jumps over the lazy\0dog"), + TESTSTR("The quick brown fox jumps over the lazy \0og"), + TESTSTR("The quick brown fox jumps over the lazy d\0g"), + TESTSTR("The quick brown fox jumps over the lazy do\0"), + TESTSTR("The quick brown fox jumps over the lazy dog"), + { NULL, 0 }, +}; + +ATF_TC(test00); +ATF_TC_HEAD(test00, tc) +{ + atf_tc_set_md_var(tc, "descr", "test00"); +} +ATF_TC_BODY(test00, tc) +{ + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (p = &mode_rwa[0]; *p != NULL; ++p) { + fp = fmemopen(&buf[0], sizeof(buf), *p); +/* + * Upon successful completion, fmemopen() shall return a pointer to the + * object controlling the stream. + */ + ATF_CHECK(fp != NULL); + + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test01); +ATF_TC_HEAD(test01, tc) +{ + atf_tc_set_md_var(tc, "descr", "test01"); +} +ATF_TC_BODY(test01, tc) +{ + const char **p; + const char *mode[] = { + "r+", "rb+", "r+b", + "w+", "wb+", "w+b", + "a+", "ab+", "a+b", + NULL + }; + FILE *fp; + + for (p = &mode[0]; *p != NULL; ++p) { +/* + * If a null pointer is specified as the buf argument, fmemopen() shall + * allocate size bytes of memory as if by a call to malloc(). + */ + fp = fmemopen(NULL, BUFSIZ, *p); + ATF_CHECK(fp != NULL); + +/* + * If buf is a null pointer, the initial position shall always be set + * to the beginning of the buffer. + */ + ATF_CHECK(ftello(fp) == (off_t)0); + + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test02); +ATF_TC_HEAD(test02, tc) +{ + atf_tc_set_md_var(tc, "descr", "test02"); +} +ATF_TC_BODY(test02, tc) +{ + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (p = &mode_r[0]; *p != NULL; ++p) { + + memset(&buf[0], 0x1, sizeof(buf)); + fp = fmemopen(&buf[0], sizeof(buf), *p); + ATF_CHECK(fp != NULL); + +/* + * This position is initially set to either the beginning of the buffer + * (for r and w modes) + */ + ATF_CHECK((unsigned char)buf[0] == 0x1); + ATF_CHECK(ftello(fp) == (off_t)0); + +/* + * The stream also maintains the size of the current buffer contents. + * For modes r and r+ the size is set to the value given by the size argument. + */ +#if !defined(__GLIBC__) + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == (off_t)sizeof(buf)); +#endif + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test03); +ATF_TC_HEAD(test03, tc) +{ + atf_tc_set_md_var(tc, "descr", "test03"); +} +ATF_TC_BODY(test03, tc) +{ + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (p = &mode_w[0]; *p != NULL; ++p) { + + memset(&buf[0], 0x1, sizeof(buf)); + fp = fmemopen(&buf[0], sizeof(buf), *p); + ATF_CHECK(fp != NULL); + +/* + * This position is initially set to either the beginning of the buffer + * (for r and w modes) + */ + ATF_CHECK(buf[0] == '\0'); + ATF_CHECK(ftello(fp) == (off_t)0); + +/* + * For modes w and w+ the initial size is zero + */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == (off_t)0); + + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test04); +ATF_TC_HEAD(test04, tc) +{ + atf_tc_set_md_var(tc, "descr", "test04"); +} +ATF_TC_BODY(test04, tc) +{ + const char **p; + char buf[BUFSIZ]; + FILE *fp; + +/* + * or to the first null byte in the buffer (for a modes) + */ + for (p = &mode_a[0]; *p != NULL; ++p) { + + memset(&buf[0], 0x1, sizeof(buf)); + fp = fmemopen(&buf[0], sizeof(buf), *p); + ATF_CHECK(fp != NULL); + + ATF_CHECK((unsigned char)buf[0] == 0x1); + +/* If no null byte is found in append mode, + * the initial position is set to one byte after the end of the buffer. + */ +#if !defined(__GLIBC__) + ATF_CHECK(ftello(fp) == (off_t)sizeof(buf)); +#endif + +/* + * and for modes a and a+ the initial size is either the position of the + * first null byte in the buffer or the value of the size argument + * if no null byte is found. + */ +#if !defined(__GLIBC__) + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == (off_t)sizeof(buf)); +#endif + + ATF_CHECK(fclose(fp) == 0); + } +} + +ATF_TC(test05); +ATF_TC_HEAD(test05, tc) +{ + atf_tc_set_md_var(tc, "descr", "test05"); +} +ATF_TC_BODY(test05, tc) +{ + const char **p; + FILE *fp; + char buf[BUFSIZ]; + + for (p = &mode_rwa[0]; *p != NULL; ++p) { +/* + * Otherwise, a null pointer shall be returned, and errno shall be set + * to indicate the error. + */ + errno = 0; + fp = fmemopen(NULL, (size_t)0, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == EINVAL); + + errno = 0; + fp = fmemopen((void *)&buf[0], 0, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == EINVAL); + } +} + +ATF_TC(test06); +ATF_TC_HEAD(test06, tc) +{ + atf_tc_set_md_var(tc, "descr", "test06"); +} +ATF_TC_BODY(test06, tc) +{ + const char **p; + const char *mode[] = { "", " ", "???", NULL }; + FILE *fp; + + for (p = &mode[0]; *p != NULL; ++p) { +/* + * The value of the mode argument is not valid. + */ + fp = fmemopen(NULL, 1, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == EINVAL); + } +} + +ATF_TC(test07); +ATF_TC_HEAD(test07, tc) +{ + atf_tc_set_md_var(tc, "descr", "test07"); +} +ATF_TC_BODY(test07, tc) +{ +#if !defined(__GLIBC__) + const char **p; + const char *mode[] = { + "r", "rb", + "w", "wb", + "a", "ab", + NULL + }; + FILE *fp; + + for (p = &mode[0]; *p != NULL; ++p) { +/* + * Because this feature is only useful when the stream is opened for updating + * (because there is no way to get a pointer to the buffer) the fmemopen() + * call may fail if the mode argument does not include a '+' . + */ + errno = 0; + fp = fmemopen(NULL, 1, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == EINVAL); + } +#endif +} + +ATF_TC(test08); +ATF_TC_HEAD(test08, tc) +{ + atf_tc_set_md_var(tc, "descr", "test08"); +} +ATF_TC_BODY(test08, tc) +{ +#if !defined(__GLIBC__) + const char **p; + const char *mode[] = { + "r+", "rb+", "r+b", + "w+", "wb+", "w+b", + "a+", "ab+", "a+b", + NULL + }; + FILE *fp; + + for (p = &mode[0]; *p != NULL; ++p) { +/* + * The buf argument is a null pointer and the allocation of a buffer of + * length size has failed. + */ + fp = fmemopen(NULL, SIZE_MAX, *p); + ATF_CHECK(fp == NULL); + ATF_CHECK(errno == ENOMEM); + } +#endif +} + +/* + * test09 - test14: + * An attempt to seek a memory buffer stream to a negative position or to a + * position larger than the buffer size given in the size argument shall fail. + */ + +ATF_TC(test09); +ATF_TC_HEAD(test09, tc) +{ + atf_tc_set_md_var(tc, "descr", "test09"); +} +ATF_TC_BODY(test09, tc) +{ + struct testcase *t; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + off_t i; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rwa[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); + +/* + * test fmemopen_seek(SEEK_SET) + */ + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_SET) == 0); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* positive */ + for (i = (off_t)1; i <= (off_t)t->n; ++i) { + ATF_CHECK(fseeko(fp, i, SEEK_SET) == 0); + ATF_CHECK(ftello(fp) == i); + } + /* positive + OOB */ + ATF_CHECK(fseeko(fp, t->n + 1, SEEK_SET) == -1); + ATF_CHECK(ftello(fp) == t->n); + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_SET) == -1); + ATF_CHECK(ftello(fp) == t->n); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +const char *mode_rw[] = { + "r", "rb", "r+", "rb+", "r+b", + "w", "wb", "w+", "wb+", "w+b", + NULL +}; + +ATF_TC(test10); +ATF_TC_HEAD(test10, tc) +{ + atf_tc_set_md_var(tc, "descr", "test10"); +} +ATF_TC_BODY(test10, tc) +{ + struct testcase *t; + off_t i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); + +/* + * test fmemopen_seek(SEEK_CUR) + */ + ATF_CHECK(ftello(fp) == (off_t)0); + + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* negative & OOB */ + ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* positive */ + for (i = 0; i < (off_t)t->n; ++i) { + ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == i + 1); + } + + /* positive & OOB */ + ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1); + ATF_CHECK(ftello(fp) == (off_t)t->n); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test11); +ATF_TC_HEAD(test11, tc) +{ + atf_tc_set_md_var(tc, "descr", "test11"); +} +ATF_TC_BODY(test11, tc) +{ + struct testcase *t; + off_t len, rest, i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + /* test fmemopen_seek(SEEK_CUR) */ + for (t = &testcases[0]; t->s != NULL; ++t) { + len = (off_t)strnlen(t->s, t->n); + rest = (off_t)t->n - len; + for (p = &mode_a[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_seek(SEEK_CUR) + */ +#if defined(__GLIBC__) + if (i < (off_t)t->n) { +#endif + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == len); + + /* posive */ + for (i = (off_t)1; i <= rest; ++i) { + ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == len + i); + } + + /* positive + OOB */ + ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1); + ATF_CHECK(ftello(fp) == (off_t)t->n); + + /* negative */ + for (i = (off_t)1; i <= (off_t)t->n; ++i) { + ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == 0); + ATF_CHECK(ftello(fp) == (off_t)t->n - i); + } + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1); + ATF_CHECK(ftello(fp) == (off_t)0); + +#if defined(__GLIBC__) + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +#ifndef __FreeBSD__ +ATF_TC(test12); +ATF_TC_HEAD(test12, tc) +{ + atf_tc_set_md_var(tc, "descr", "test12"); +} +ATF_TC_BODY(test12, tc) +{ + struct testcase *t; + off_t len, rest, i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + /* test fmemopen_seek(SEEK_END) */ + for (t = &testcases[0]; t->s != NULL; ++t) { + len = (off_t)strnlen(t->s, t->n); + rest = t->n - len; + for (p = &mode_r[0]; *p != NULL; ++p) { + + memcpy(buf, t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); + +/* + * test fmemopen_seek(SEEK_END) + */ +#if !defined(__GLIBC__) + ATF_CHECK(ftello(fp) == (off_t)0); + + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len); + + /* positive + OOB */ + ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1); + ATF_CHECK(ftello(fp) == len); + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1); + ATF_CHECK(ftello(fp) == len); + + /* positive */ + for (i = 1; i <= rest; ++i) { + ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len + i); + } + + /* negative */ + for (i = 1; i < len; ++i) { + ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len - i); + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} +#endif + +ATF_TC(test13); +ATF_TC_HEAD(test13, tc) +{ + atf_tc_set_md_var(tc, "descr", "test13"); +} +ATF_TC_BODY(test13, tc) +{ + struct testcase *t; +#ifndef __FreeBSD__ + off_t i; +#endif + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + /* test fmemopen_seek(SEEK_END) */ + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_w[0]; *p != NULL; ++p) { + + memcpy(buf, t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_seek(SEEK_END) + */ +#if !defined(__GLIBC__) + ATF_CHECK(ftello(fp) == (off_t)0); + ATF_CHECK(buf[0] == '\0'); + + /* zero */ + ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* positive + OOB */ + ATF_CHECK(fseeko(fp, (off_t)t->n + 1, SEEK_END) == -1); + ATF_CHECK(ftello(fp) == (off_t)0); + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, -1, SEEK_END) == -1); + ATF_CHECK(ftello(fp) == (off_t)0); +#endif + +#ifndef __FreeBSD__ + /* positive */ + for (i = 1; i <= t->n; ++i) { + ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == i); + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test14); +ATF_TC_HEAD(test14, tc) +{ + atf_tc_set_md_var(tc, "descr", "test14"); +} +ATF_TC_BODY(test14, tc) +{ + struct testcase *t; + off_t len, rest, i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + /* test fmemopen_seek(SEEK_END) */ + for (t = &testcases[0]; t->s != NULL; ++t) { + len = (off_t)strnlen(t->s, t->n); + rest = (off_t)t->n - len; + for (p = &mode_a[0]; *p != NULL; ++p) { + + memcpy(buf, t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_seek(SEEK_END) + */ +#if !defined(__GLIBC__) + ATF_CHECK(ftello(fp) == len); + + /* zero */ + ATF_CHECK(fseeko(fp, 0, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len); + + /* positive + OOB */ + ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1); + ATF_CHECK(ftello(fp) == len); + + /* negative + OOB */ + ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1); + ATF_CHECK(ftello(fp) == len); + +#ifndef __FreeBSD__ + /* positive */ + for (i = 1; i <= rest; ++i) { + ATF_CHECK(fseeko(fp, i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len + i); + } +#endif + + /* negative */ + for (i = 1; i < len; ++i) { + ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0); + ATF_CHECK(ftello(fp) == len - i); + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +const char *mode_rw1[] = { + "r", "rb", "r+", "rb+", "r+b", + "w+", "wb+", + NULL +}; + +#ifndef __FreeBSD__ + +/* test15 - 18: + * When a stream open for writing is flushed or closed, a null byte is written + * at the current position or at the end of the buffer, depending on the size + * of the contents. + */ + +ATF_TC(test15); +ATF_TC_HEAD(test15, tc) +{ + atf_tc_set_md_var(tc, "descr", "test15"); +} +ATF_TC_BODY(test15, tc) +{ + struct testcase *t; + const char **p; + char buf0[BUFSIZ]; + FILE *fp; + int i; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw1[0]; *p != NULL; ++p) { + + memcpy(&buf0[0], t->s, t->n); + fp = fmemopen(&buf0[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_read + fgetc(3) + */ + for (i = 0; i < t->n; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fgetc(fp) == buf0[i]); + ATF_CHECK(feof(fp) == 0); + ATF_CHECK(ftello(fp) == (off_t)i + 1); + } + ATF_CHECK(fgetc(fp) == EOF); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(ftello(fp) == (off_t)t->n); + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test16); +ATF_TC_HEAD(test16, tc) +{ + atf_tc_set_md_var(tc, "descr", "test16"); +} +ATF_TC_BODY(test16, tc) +{ + struct testcase *t; + const char **p; + char buf0[BUFSIZ], buf1[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw1[0]; *p != NULL; ++p) { + + memcpy(&buf0[0], t->s, t->n); + buf1[t->n] = 0x1; + fp = fmemopen(&buf0[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_read + fread(4) + */ + ATF_CHECK(ftello(fp) == (off_t)0); + ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) == (size_t)t->n); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(memcmp(&buf0[0], &buf1[0], t->n) == 0); + ATF_CHECK((unsigned char)buf1[t->n] == 0x1); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +const char *mode_a1[] = { "a+", "ab+", NULL }; + +ATF_TC(test17); +ATF_TC_HEAD(test17, tc) +{ + atf_tc_set_md_var(tc, "descr", "test17"); +} +ATF_TC_BODY(test17, tc) +{ + struct testcase *t; + size_t len; + int i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + len = strnlen(t->s, t->n); + for (p = &mode_a1[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_read + fgetc(3) + */ +#if defined(__GLIBC__) + if (i < t->n) { +#endif + for (i = len; i < t->n; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fgetc(fp) == buf[i]); + ATF_CHECK(feof(fp) == 0); + ATF_CHECK(ftello(fp) == (off_t)i + 1); + } + ATF_CHECK(fgetc(fp) == EOF); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(ftello(fp) == (off_t)t->n); + rewind(fp); + for (i = 0; i < t->n; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fgetc(fp) == buf[i]); + ATF_CHECK(feof(fp) == 0); + ATF_CHECK(ftello(fp) == (off_t)i + 1); + } + ATF_CHECK(fgetc(fp) == EOF); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(ftello(fp) == (off_t)t->n); +#if defined(__GLIBC__) + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test18); +ATF_TC_HEAD(test18, tc) +{ + atf_tc_set_md_var(tc, "descr", "test18"); +} +ATF_TC_BODY(test18, tc) +{ + struct testcase *t; + size_t len; + const char **p; + char buf0[BUFSIZ], buf1[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + len = strnlen(t->s, t->n); + for (p = &mode_a1[0]; *p != NULL; ++p) { + + memcpy(&buf0[0], t->s, t->n); + buf1[t->n - len] = 0x1; + fp = fmemopen(&buf0[0], t->n, *p); + ATF_CHECK(fp != NULL); +/* + * test fmemopen_read + fread(3) + */ +#if defined(__GLIBC__) + if (i < t->n) { +#endif + ATF_CHECK(ftello(fp) == (off_t)len); + ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) + == t->n - len); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(!memcmp(&buf0[len], &buf1[0], t->n - len)); + ATF_CHECK((unsigned char)buf1[t->n - len] == 0x1); + rewind(fp); + buf1[t->n] = 0x1; + ATF_CHECK(ftello(fp) == (off_t)0); + ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) + == (size_t)t->n); + ATF_CHECK(feof(fp) != 0); + ATF_CHECK(!memcmp(&buf0[0], &buf1[0], t->n)); + ATF_CHECK((unsigned char)buf1[t->n] == 0x1); +#if defined(__GLIBC__) + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } +} + +/* + * test19 - test22: + * If a stream open for update is flushed or closed and the last write has + * advanced the current buffer size, a null byte is written at the end of the + * buffer if it fits. + */ + +const char *mode_rw2[] = { + "r+", "rb+", "r+b", + "w", "wb", "w+", "wb+", "w+b", + NULL +}; + +ATF_TC(test19); +ATF_TC_HEAD(test19, tc) +{ + atf_tc_set_md_var(tc, "descr", "test19"); +} +ATF_TC_BODY(test19, tc) +{ + struct testcase *t; + int i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw2[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + buf[t->n] = 0x1; + fp = fmemopen(&buf[0], t->n + 1, *p); + ATF_CHECK(fp != NULL); + setbuf(fp, NULL); +/* + * test fmemopen_write + fputc(3) + */ + for (i = 0; i < t->n; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fputc(t->s[i], fp) == t->s[i]); + ATF_CHECK(buf[i] == t->s[i]); + ATF_CHECK(ftello(fp) == (off_t)i + 1); + ATF_CHECK(buf[i] == t->s[i]); +#if !defined(__GLIBC__) + ATF_CHECK(buf[i + 1] == '\0'); +#endif + } + +/* don't accept non nul character at end of buffer */ + ATF_CHECK(fputc(0x1, fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n); + ATF_CHECK(feof(fp) == 0); + +/* accept nul character at end of buffer */ + ATF_CHECK(fputc('\0', fp) == '\0'); + ATF_CHECK(ftello(fp) == (off_t)t->n + 1); + ATF_CHECK(feof(fp) == 0); + +/* reach EOF */ + ATF_CHECK(fputc('\0', fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n + 1); + + /* compare */ + ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0); + ATF_CHECK(buf[t->n] == '\0'); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test20); +ATF_TC_HEAD(test20, tc) +{ + atf_tc_set_md_var(tc, "descr", "test20"); +} +ATF_TC_BODY(test20, tc) +{ + struct testcase *t; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + for (p = &mode_rw2[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t->s, t->n); + buf[t->n] = 0x1; + fp = fmemopen(&buf[0], t->n + 1, *p); + ATF_CHECK(fp != NULL); + setbuf(fp, NULL); + ATF_CHECK(fwrite(t->s, 1, t->n, fp) == (size_t)t->n); +/* + * test fmemopen_write + fwrite(3) + */ +#if !defined(__GLIBC__) + ATF_CHECK(buf[t->n] == '\0'); + +/* don't accept non nul character at end of buffer */ + ATF_CHECK(fwrite("\x1", 1, 1, fp) == 0); + ATF_CHECK(ftello(fp) == (off_t)t->n); + ATF_CHECK(feof(fp) == 0); +#endif + +/* accept nul character at end of buffer */ + ATF_CHECK(fwrite("\x0", 1, 1, fp) == 1); + ATF_CHECK(ftello(fp) == (off_t)t->n + 1); + ATF_CHECK(feof(fp) == 0); + +/* reach EOF */ + ATF_CHECK(fputc('\0', fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n + 1); + +/* compare */ + ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0); + ATF_CHECK(buf[t->n] == '\0'); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test21); +ATF_TC_HEAD(test21, tc) +{ + atf_tc_set_md_var(tc, "descr", "test21"); +} +ATF_TC_BODY(test21, tc) +{ + struct testcase *t; + int len, i; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t = &testcases[0]; t->s != NULL; ++t) { + len = strnlen(t->s, t->n); + for (p = &mode_a[0]; *p != NULL; ++p) { + memcpy(&buf[0], t->s, t->n); + fp = fmemopen(&buf[0], t->n, *p); + ATF_CHECK(fp != NULL); + setbuf(fp, NULL); +/* + * test fmemopen_write + fputc(3) + */ + if (len < t->n) { + for (i = len; i < t->n - 1; ++i) { + ATF_CHECK(ftello(fp) == (off_t)i); + ATF_CHECK(fputc(t->s[i - len], fp) + == t->s[i - len]); + ATF_CHECK(buf[i] == t->s[i - len]); + ATF_CHECK(ftello(fp) == (off_t)i + 1); +#if !defined(__GLIBC__) + ATF_CHECK(buf[i + 1] == '\0'); +#endif + } + +/* don't accept non nul character at end of buffer */ + ATF_CHECK(ftello(fp) == (off_t)t->n - 1); + ATF_CHECK(fputc(0x1, fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n - 1); + +/* accept nul character at end of buffer */ + ATF_CHECK(ftello(fp) == (off_t)t->n - 1); + ATF_CHECK(fputc('\0', fp) == '\0'); + ATF_CHECK(ftello(fp) == (off_t)t->n); + } + +/* reach EOF */ + ATF_CHECK(ftello(fp) == (off_t)t->n); + ATF_CHECK(fputc('\0', fp) == EOF); + ATF_CHECK(ftello(fp) == (off_t)t->n); + + ATF_CHECK(fclose(fp) == 0); + } + } +} + +ATF_TC(test22); +ATF_TC_HEAD(test22, tc) +{ + atf_tc_set_md_var(tc, "descr", "test22"); +} +ATF_TC_BODY(test22, tc) +{ + struct testcase *t0, *t1; + size_t len0, len1, nleft; + const char **p; + char buf[BUFSIZ]; + FILE *fp; + + for (t0 = &testcases[0]; t0->s != NULL; ++t0) { + len0 = strnlen(t0->s, t0->n); + for (t1 = &testcases[0]; t1->s != NULL; ++t1) { + len1 = strnlen(t1->s, t1->n); + for (p = &mode_a[0]; *p != NULL; ++p) { + + memcpy(&buf[0], t0->s, t0->n); + fp = fmemopen(&buf[0], t0->n, *p); + ATF_CHECK(fp != NULL); + setbuf(fp, NULL); +/* + * test fmemopen_write + fwrite(3) + */ + nleft = t0->n - len0; +#if !defined(__GLIBC__) + if (nleft == 0 || len1 == nleft - 1) { + ATF_CHECK(fwrite(t1->s, 1, t1->n, fp) + == nleft); + ATF_CHECK(ftell(fp) == t1->n); + } else { + ATF_CHECK(fwrite(t1->s, 1, t1->n, fp) + == nleft - 1); + ATF_CHECK(ftell(fp) == t1->n - 1); + } +#endif + ATF_CHECK(fclose(fp) == 0); + } + } + } +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, test00); + ATF_TP_ADD_TC(tp, test01); + ATF_TP_ADD_TC(tp, test02); + ATF_TP_ADD_TC(tp, test03); + ATF_TP_ADD_TC(tp, test04); + ATF_TP_ADD_TC(tp, test05); + ATF_TP_ADD_TC(tp, test06); + ATF_TP_ADD_TC(tp, test07); + ATF_TP_ADD_TC(tp, test08); + ATF_TP_ADD_TC(tp, test09); + ATF_TP_ADD_TC(tp, test10); + ATF_TP_ADD_TC(tp, test11); +#ifndef __FreeBSD__ + ATF_TP_ADD_TC(tp, test12); +#endif + ATF_TP_ADD_TC(tp, test13); + ATF_TP_ADD_TC(tp, test14); +#ifndef __FreeBSD__ + ATF_TP_ADD_TC(tp, test15); + ATF_TP_ADD_TC(tp, test16); + ATF_TP_ADD_TC(tp, test17); + ATF_TP_ADD_TC(tp, test18); + ATF_TP_ADD_TC(tp, test19); + ATF_TP_ADD_TC(tp, test20); + ATF_TP_ADD_TC(tp, test21); + ATF_TP_ADD_TC(tp, test22); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c b/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c new file mode 100644 index 0000000..4083b80 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c @@ -0,0 +1,446 @@ +/* $NetBSD: t_fopen.c,v 1.3 2011/09/14 14:34:37 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_fopen.c,v 1.3 2011/09/14 14:34:37 martin Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *path = "fopen"; + +ATF_TC_WITH_CLEANUP(fdopen_close); +ATF_TC_HEAD(fdopen_close, tc) +{ + atf_tc_set_md_var(tc, "descr", "See that descriptors are closed"); +} + +ATF_TC_BODY(fdopen_close, tc) +{ + FILE *f; + int fd; + + /* + * Check that the file descriptor + * used to fdopen(3) a stream is + * closed once the stream is closed. + */ + fd = open(path, O_RDWR | O_CREAT); + + ATF_REQUIRE(fd >= 0); + + f = fdopen(fd, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(close(fd) == -1); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fdopen_close, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fdopen_err); +ATF_TC_HEAD(fdopen_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fdopen(3)"); +} + +ATF_TC_BODY(fdopen_err, tc) +{ + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, fdopen(fd, "w") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, fdopen(fd, "a") == NULL); + + ATF_REQUIRE(close(fd) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fdopen(fd, "r") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fdopen(-1, "w+") == NULL); + + (void)unlink(path); +} + +ATF_TC_CLEANUP(fdopen_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fdopen_seek); +ATF_TC_HEAD(fdopen_seek, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test stream position with fdopen(3)"); +} + +ATF_TC_BODY(fdopen_seek, tc) +{ + FILE *f; + int fd; + + /* + * Verify that the file position associated + * with the stream corresponds with the offset + * set earlier for the file descriptor. + */ + fd = open(path, O_RDWR | O_CREAT); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(write(fd, "garbage", 7) == 7); + ATF_REQUIRE(lseek(fd, 3, SEEK_SET) == 3); + + f = fdopen(fd, "r+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(ftell(f) == 3); + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fdopen_seek, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fopen_err); +ATF_TC_HEAD(fopen_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fopen(3)"); +} + +ATF_TC_BODY(fopen_err, tc) +{ + static const char *mode[] = { + "x", "xr", "xr", "+r+", "R", "W+", " aXX", "Xr", " r+", "" }; + + char buf[PATH_MAX + 1]; + size_t i; + FILE *f; + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + + /* + * Note that also "invalid" characters + * may follow the mode-string whenever + * the first character is valid. + */ + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + f = fopen(path, mode[i]); + + if (f == NULL && errno == EINVAL) + continue; + + if (f != NULL) + (void)fclose(f); + + atf_tc_fail_nonfatal("opened file as '%s'", mode[i]); + } + + (void)unlink(path); + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(EISDIR, fopen("/usr/bin", "w") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, fopen("/a/b/c/d/e/f", "r") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, fopen(buf, "r+") == NULL); +} + +ATF_TC_CLEANUP(fopen_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fopen_append); +ATF_TC_HEAD(fopen_append, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that append-mode works"); +} + +ATF_TC_BODY(fopen_append, tc) +{ + char buf[15]; + FILE *f; + + (void)memset(buf, 'x', sizeof(buf)); + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "a"); + + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r"); + + ATF_REQUIRE(fread(buf, 1, sizeof(buf), f) == 14); + ATF_REQUIRE(strncmp(buf, "garbagegarbage", 14) == 0); + + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fopen_append, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fopen_mode); +ATF_TC_HEAD(fopen_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test fopen(3) modes"); +} + +ATF_TC_BODY(fopen_mode, tc) +{ + size_t i; + FILE *f; + + static const char *mode[] = { + "r", "r+", "w", "w+", "a", "a+", + "rb", "r+b", "wb", "w+b", "ab", "a+b" + "re", "r+e", "we", "w+e", "ae", "a+e" + "rf", "r+f", "wf", "w+f", "af", "a+f" + }; + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + + /* + * Verify that various modes work. + */ + for (i = 0; i < __arraycount(mode); i++) { + + f = fopen(path, mode[i]); + + if (f != NULL) { + ATF_REQUIRE(fclose(f) == 0); + continue; + } + + atf_tc_fail_nonfatal("failed to open file as %s", mode[i]); + } + + (void)unlink(path); +} + +ATF_TC_CLEANUP(fopen_mode, tc) +{ + (void)unlink(path); +} + +ATF_TC(fopen_perm); +ATF_TC_HEAD(fopen_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with fopen(3)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(fopen_perm, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, fopen("/bin/ls", "a+") == NULL); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, fopen("/bin/ls", "w+") == NULL); +} + +#ifdef __NetBSD__ +ATF_TC(fopen_regular); +ATF_TC_HEAD(fopen_regular, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test fopen(3) with 'f' mode"); +} + +ATF_TC_BODY(fopen_regular, tc) +{ + static const char *mode[] = { "rf", "r+f", "wf", "w+f", "af", "a+f" }; + static const char *devs[] = { _PATH_DEVNULL }; + + size_t i, j; + FILE *f; + + for (i = 0; i < __arraycount(devs); i++) { + + for (j = 0; j < __arraycount(mode); j++) { + + errno = 0; + f = fopen(devs[i], mode[j]); + + if (f == NULL && errno == EFTYPE) + continue; + + if (f != NULL) + (void)fclose(f); + + atf_tc_fail_nonfatal("opened %s as %s", + devs[i], mode[j]); + } + } +} +#endif + +ATF_TC_WITH_CLEANUP(fopen_seek); +ATF_TC_HEAD(fopen_seek, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test initial stream position"); +} + +ATF_TC_BODY(fopen_seek, tc) +{ + FILE *f; + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fclose(f) == 0); + + /* + * The position of the stream should be + * at the start, except for append-mode. + */ + f = fopen(path, "r"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(ftello(f) == 0); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "a"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(ftello(f) == 7); + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(fopen_seek, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(freopen_std); +ATF_TC_HEAD(freopen_std, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of freopen(3)"); +} + +ATF_TC_BODY(freopen_std, tc) +{ + FILE *std[2] = { stdin, stdout }; + char buf[15]; + size_t i; + FILE *f; + + /* + * Associate a standard stream with a custom stream. + * Then write to the standard stream and verify that + * the result now appears in the custom stream. + */ + for (i = 0; i < __arraycount(std); i++) { + + (void)memset(buf, 'x', sizeof(buf)); + + f = fopen(path, "w+"); + ATF_REQUIRE(f != NULL); + + f = freopen(path, "w+", std[i]); + ATF_REQUIRE(f != NULL); + + ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7); + ATF_REQUIRE(fprintf(std[i], "garbage") == 7); + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fread(buf, 1, sizeof(buf), f) == 14); + ATF_REQUIRE(strncmp(buf, "garbagegarbage", 14) == 0); + + ATF_REQUIRE(fclose(f) == 0); + } + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(freopen_std, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fdopen_close); + ATF_TP_ADD_TC(tp, fdopen_err); + ATF_TP_ADD_TC(tp, fdopen_seek); + ATF_TP_ADD_TC(tp, fopen_append); + ATF_TP_ADD_TC(tp, fopen_err); + ATF_TP_ADD_TC(tp, fopen_mode); + ATF_TP_ADD_TC(tp, fopen_perm); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, fopen_regular); +#endif + ATF_TP_ADD_TC(tp, fopen_seek); + ATF_TP_ADD_TC(tp, freopen_std); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c b/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c new file mode 100644 index 0000000..ed7c0dc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c @@ -0,0 +1,194 @@ +/* $NetBSD: t_fputc.c,v 1.1 2011/09/11 09:02:46 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_fputc.c,v 1.1 2011/09/11 09:02:46 jruoho Exp $"); + +#include +#include +#include +#include +#include + +static const char *path = "fputc"; +static void puterr(int (*)(int, FILE *)); +static void putstr(int (*)(int, FILE *)); + +static void +puterr(int (*func)(int, FILE *)) +{ + FILE *f; + + f = fopen(path, "w+"); + + ATF_REQUIRE(f != NULL); + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(func('x', f) == EOF); +} + +static void +putstr(int (*func)(int, FILE *)) +{ + const char *str = "1234567890x"; + unsigned short i = 0; + char buf[10]; + FILE *f; + + (void)memset(buf, 'x', sizeof(buf)); + + f = fopen(path, "w+"); + ATF_REQUIRE(f != NULL); + + while (str[i] != 'x') { + ATF_REQUIRE(func(str[i], f) == str[i]); + i++; + } + + ATF_REQUIRE(fclose(f) == 0); + + f = fopen(path, "r"); + ATF_REQUIRE(f != NULL); + + ATF_REQUIRE(fread(buf, 1, 10, f) == 10); + ATF_REQUIRE(strncmp(buf, str, 10) == 0); + + ATF_REQUIRE(fclose(f) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_WITH_CLEANUP(fputc_basic); +ATF_TC_HEAD(fputc_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fputc(3)"); +} + +ATF_TC_BODY(fputc_basic, tc) +{ + putstr(fputc); +} + +ATF_TC_CLEANUP(fputc_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(fputc_err); +ATF_TC_HEAD(fputc_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from fputc(3)"); +} + +ATF_TC_BODY(fputc_err, tc) +{ + puterr(fputc); +} + +ATF_TC_CLEANUP(fputc_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(putc_basic); +ATF_TC_HEAD(putc_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of putc(3)"); +} + +ATF_TC_BODY(putc_basic, tc) +{ + putstr(putc); +} + +ATF_TC_CLEANUP(putc_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(putc_err); +ATF_TC_HEAD(putc_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from putc(3)"); +} + +ATF_TC_BODY(putc_err, tc) +{ + puterr(putc); +} + +ATF_TC_CLEANUP(putc_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(putc_unlocked_basic); +ATF_TC_HEAD(putc_unlocked_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of putc_unlocked(3)"); +} + +ATF_TC_BODY(putc_unlocked_basic, tc) +{ + putstr(putc_unlocked); +} + +ATF_TC_CLEANUP(putc_unlocked_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(putc_unlocked_err); +ATF_TC_HEAD(putc_unlocked_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from putc_unlocked(3)"); +} + +ATF_TC_BODY(putc_unlocked_err, tc) +{ + puterr(putc_unlocked); +} + +ATF_TC_CLEANUP(putc_unlocked_err, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fputc_basic); + ATF_TP_ADD_TC(tp, fputc_err); + ATF_TP_ADD_TC(tp, putc_basic); + ATF_TP_ADD_TC(tp, putc_err); + ATF_TP_ADD_TC(tp, putc_unlocked_basic); + ATF_TP_ADD_TC(tp, putc_unlocked_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c b/contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c new file mode 100644 index 0000000..e423060 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c @@ -0,0 +1,54 @@ +/* $NetBSD: t_mktemp.c,v 1.1 2013/04/22 21:05:12 christos Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_mktemp.c,v 1.1 2013/04/22 21:05:12 christos Exp $"); + +#include +#include + +ATF_TC(mktemp_not_exist); +ATF_TC_HEAD(mktemp_not_exist, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that mktemp does not fail on" + " a path that does not exist"); +} + +ATF_TC_BODY(mktemp_not_exist, tc) +{ + char template[] = "I will barf/XXXXXX"; + ATF_REQUIRE(mktemp(template) != NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mktemp_not_exist); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_open_memstream.c b/contrib/netbsd-tests/lib/libc/stdio/t_open_memstream.c new file mode 100644 index 0000000..950a258 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_open_memstream.c @@ -0,0 +1,96 @@ +/* + * Based on the OpenBSD test + * Copyright (c) 2011 Martin Pieuchot + * + * 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 +__RCSID("$NetBSD: t_open_memstream.c,v 1.2 2014/10/19 11:17:43 justin Exp $"); + +#include +#include +#include +#include +#include +#include + +ATF_TC(test_open_memstream); +ATF_TC_HEAD(test_open_memstream, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test open_memstream functionality"); +} + +#define OFFSET 16384 + +const char start[] = "start"; +const char hello[] = "hello"; + +ATF_TC_BODY(test_open_memstream, tc) +{ + FILE *fp; + char *buf = (char *)0xff; + size_t size = 0; + off_t off; + int i; + + fp = open_memstream(&buf, &size); + ATF_REQUIRE(fp != NULL); + + off = ftello(fp); + ATF_CHECK(off == 0); + + ATF_CHECK(fflush(fp) == 0); + ATF_CHECK(size == 0); + ATF_CHECK(buf != (char *)0xff); + ATF_CHECK(fseek(fp, -6, SEEK_SET) == -1); + ATF_CHECK(fseek(fp, OFFSET, SEEK_SET) == 0); + ATF_CHECK(fprintf(fp, hello) != EOF); + ATF_CHECK(fflush(fp) != EOF); + ATF_CHECK(size == OFFSET + sizeof(hello)-1); + ATF_CHECK(fseek(fp, 0, SEEK_SET) == 0); + ATF_CHECK(fprintf(fp, start) != EOF); + ATF_CHECK(fflush(fp) != EOF); + ATF_CHECK(size == sizeof(start)-1); + + /* Needed for sparse files */ + ATF_CHECK(strncmp(buf, start, sizeof(start)-1) == 0); + for (i = sizeof(start)-1; i < OFFSET; i++) + ATF_CHECK(buf[i] == '\0'); + + ATF_CHECK(memcmp(buf + OFFSET, hello, sizeof(hello)-1) == 0); + + /* verify that simply seeking past the end doesn't increase the size */ + ATF_CHECK(fseek(fp, 100, SEEK_END) == 0); + ATF_CHECK(fflush(fp) != EOF); + ATF_CHECK(size == OFFSET + sizeof(hello)-1); + ATF_CHECK(fseek(fp, 8, SEEK_SET) == 0); + ATF_CHECK(ftell(fp) == 8); + + /* Try to seek backward */ + ATF_CHECK(fseek(fp, -1, SEEK_CUR) == 0); + ATF_CHECK(ftell(fp) == 7); + ATF_CHECK(fseek(fp, 5, SEEK_CUR) == 0); + ATF_CHECK(fclose(fp) != EOF); + ATF_CHECK(size == 12); + + free(buf); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, test_open_memstream); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_popen.c b/contrib/netbsd-tests/lib/libc/stdio/t_popen.c new file mode 100644 index 0000000..699498c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_popen.c @@ -0,0 +1,135 @@ +/* $NetBSD: t_popen.c,v 1.4 2013/02/15 23:27:19 christos Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#ifndef lint +__COPYRIGHT("@(#) Copyright (c) 1999\ + The NetBSD Foundation, Inc. All rights reserved."); +#endif /* not lint */ + +#ifndef lint +__RCSID("$NetBSD: t_popen.c,v 1.4 2013/02/15 23:27:19 christos Exp $"); +#endif /* not lint */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define _PATH_CAT "/bin/cat" +#define BUFSIZE (640*1024) + /* 640KB ought to be enough for everyone. */ +#define DATAFILE "popen.data" + +#define TEST_ERROR(a) \ + do \ + { \ + warn(a); \ + atf_tc_fail("Check stderr for error details."); \ + } while ( /*CONSTCOND*/ 0 ) + +ATF_TC_WITH_CLEANUP(popen_zeropad); +ATF_TC_HEAD(popen_zeropad, tc) +{ + + atf_tc_set_md_var(tc, "descr", "output format zero padding"); +} + +ATF_TC_BODY(popen_zeropad, tc) +{ + char *buffer, command[MAXPATHLEN]; + int idx, in; + FILE *my_pipe; + + if ((buffer = malloc(BUFSIZE)) == NULL) + atf_tc_skip("Unable to allocate buffer."); + + srand ((unsigned int)time(NULL)); + + for (idx = 0; idx < BUFSIZE; idx++) + buffer[idx]=(char)rand(); + + (void)snprintf(command, sizeof(command), "%s >%s", + _PATH_CAT, DATAFILE); + + if ((my_pipe = popen(command, "w")) == NULL) + TEST_ERROR("popen write"); + + if (fwrite(buffer, sizeof(char), BUFSIZE, my_pipe) != BUFSIZE) + TEST_ERROR("fwrite"); + + if (pclose(my_pipe) == -1) + TEST_ERROR("pclose"); + + (void)snprintf(command, sizeof(command), "%s %s", _PATH_CAT, DATAFILE); + + if ((my_pipe = popen(command, "r")) == NULL) + TEST_ERROR("popen read"); + + idx = 0; + while ((in = fgetc(my_pipe)) != EOF) + if (idx == BUFSIZE) { + errno = EFBIG; + TEST_ERROR("read"); + } + else if ((char)in != buffer[idx++]) { + errno = EINVAL; + TEST_ERROR("read"); + } + + if (idx < BUFSIZE) { + errno = EIO; + TEST_ERROR("read"); + } + + if (pclose(my_pipe) == -1) + TEST_ERROR("pclose"); +} + +ATF_TC_CLEANUP(popen_zeropad, tc) +{ + (void)unlink(DATAFILE); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, popen_zeropad); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_printf.c b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c new file mode 100644 index 0000000..5ef58f2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c @@ -0,0 +1,204 @@ +/* $NetBSD: t_printf.c,v 1.8 2012/04/11 16:21:42 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __NetBSD__ +#include +#endif + +ATF_TC(snprintf_c99); +ATF_TC_HEAD(snprintf_c99, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Test printf(3) C99 conformance (PR lib/22019)"); +} + +ATF_TC_BODY(snprintf_c99, tc) +{ + char s[4]; + + (void)memset(s, '\0', sizeof(s)); + (void)snprintf(s, sizeof(s), "%#.o", 0); + (void)printf("printf = %#.o\n", 0); + (void)fprintf(stderr, "snprintf = %s", s); + + ATF_REQUIRE(strlen(s) == 1); + ATF_REQUIRE(s[0] == '0'); +} + +ATF_TC(snprintf_dotzero); +ATF_TC_HEAD(snprintf_dotzero, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "PR lib/32951: %%.0f formats (0.0,0.5] to \"0.\""); +} + +ATF_TC_BODY(snprintf_dotzero, tc) +{ + char s[4]; + + ATF_CHECK(snprintf(s, sizeof(s), "%.0f", 0.1) == 1); + ATF_REQUIRE_STREQ(s, "0"); +} + +ATF_TC(snprintf_posarg); +ATF_TC_HEAD(snprintf_posarg, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test for positional arguments"); +} + +ATF_TC_BODY(snprintf_posarg, tc) +{ + char s[16]; + + ATF_CHECK(snprintf(s, sizeof(s), "%1$d", -23) == 3); + ATF_REQUIRE_STREQ(s, "-23"); +} + +ATF_TC(snprintf_posarg_width); +ATF_TC_HEAD(snprintf_posarg_width, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test for positional arguments with " + "field width"); +} + +ATF_TC_BODY(snprintf_posarg_width, tc) +{ + char s[16]; + + ATF_CHECK(snprintf(s, sizeof(s), "%1$*2$d", -23, 4) == 4); + ATF_REQUIRE_STREQ(s, " -23"); +} + +ATF_TC(snprintf_posarg_error); +ATF_TC_HEAD(snprintf_posarg_error, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test for positional arguments out " + "of bounds"); +} + +ATF_TC_BODY(snprintf_posarg_error, tc) +{ + char s[16], fmt[32]; + +#ifndef __NetBSD__ + atf_tc_expect_signal(SIGSEGV, + "some non-NetBSD platforms including FreeBSD don't validate " + "negative size; testcase blows up with SIGSEGV"); +#endif + + snprintf(fmt, sizeof(fmt), "%%%zu$d", SIZE_MAX / sizeof(size_t)); + + ATF_CHECK(snprintf(s, sizeof(s), fmt, -23) == -1); +} + +ATF_TC(snprintf_float); +ATF_TC_HEAD(snprintf_float, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test that floating conversions don't" + " leak memory"); +} + +ATF_TC_BODY(snprintf_float, tc) +{ + union { + double d; + uint64_t bits; + } u; + uint32_t ul, uh; + time_t now; + char buf[1000]; + struct rlimit rl; + + rl.rlim_cur = rl.rlim_max = 1 * 1024 * 1024; + ATF_CHECK(setrlimit(RLIMIT_AS, &rl) != -1); + rl.rlim_cur = rl.rlim_max = 1 * 1024 * 1024; + ATF_CHECK(setrlimit(RLIMIT_DATA, &rl) != -1); + + time(&now); + srand(now); + for (size_t i = 0; i < 10000; i++) { + ul = rand(); + uh = rand(); + u.bits = (uint64_t)uh << 32 | ul; + ATF_CHECK(snprintf(buf, sizeof buf, " %.2f", u.d) != -1); + } +} + +ATF_TC(sprintf_zeropad); +ATF_TC_HEAD(sprintf_zeropad, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test output format zero padding (PR lib/44113)"); +} + +ATF_TC_BODY(sprintf_zeropad, tc) +{ + char str[1024]; + + ATF_CHECK(sprintf(str, "%010f", 0.0) == 10); + ATF_REQUIRE_STREQ(str, "000.000000"); + + /* ieeefp */ +#ifndef __vax__ + /* printf(3) should ignore zero padding for nan/inf */ + ATF_CHECK(sprintf(str, "%010f", NAN) == 10); + ATF_REQUIRE_STREQ(str, " nan"); + ATF_CHECK(sprintf(str, "%010f", INFINITY) == 10); + ATF_REQUIRE_STREQ(str, " inf"); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, snprintf_c99); + ATF_TP_ADD_TC(tp, snprintf_dotzero); + ATF_TP_ADD_TC(tp, snprintf_posarg); + ATF_TP_ADD_TC(tp, snprintf_posarg_width); + ATF_TP_ADD_TC(tp, snprintf_posarg_error); + ATF_TP_ADD_TC(tp, snprintf_float); + ATF_TP_ADD_TC(tp, sprintf_zeropad); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c b/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c new file mode 100644 index 0000000..194cd17 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c @@ -0,0 +1,85 @@ +/* $NetBSD: t_scanf.c,v 1.3 2012/03/18 07:00:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +#define NUM -0x1234 +#define STRNUM ___STRING(NUM) + +ATF_TC(sscanf_neghex); +ATF_TC_HEAD(sscanf_neghex, tc) +{ + atf_tc_set_md_var(tc, "descr", + "PR lib/21691: %%i and %%x fail with negative hex numbers"); +} + +ATF_TC_BODY(sscanf_neghex, tc) +{ + int i; + + sscanf(STRNUM, "%i", &i); + ATF_REQUIRE(i == NUM); + + sscanf(STRNUM, "%x", &i); + ATF_REQUIRE(i == NUM); +} + +ATF_TC(sscanf_whitespace); +ATF_TC_HEAD(sscanf_whitespace, tc) +{ + + atf_tc_set_md_var(tc, "descr", "verify sscanf skips all whitespace"); +} + +ATF_TC_BODY(sscanf_whitespace, tc) +{ + const char str[] = "\f\n\r\t\v%z"; + char c; + +#ifndef __NetBSD__ + atf_tc_expect_fail("fails on FreeBSD and some variants of Linux"); +#endif + + /* set of "white space" symbols from isspace(3) */ + c = 0; + (void)sscanf(str, "%%%c", &c); + ATF_REQUIRE(c == 'z'); +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sscanf_neghex); + ATF_TP_ADD_TC(tp, sscanf_whitespace); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c new file mode 100644 index 0000000..c0641db --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c @@ -0,0 +1,212 @@ +/* $NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Jason R. Thorpe. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $"); + +#include +#include +#include +#include +#include + +extern int __cxa_atexit(void (*func)(void *), void *, void *); +extern void __cxa_finalize(void *); + +#ifdef __FreeBSD__ +/* + * On shared object unload, in __cxa_finalize, call and clear all installed + * atexit and __cxa_atexit handlers that are either installed by unloaded + * dso, or points to the functions provided by the dso. + * + * The reason of the change is to ensure that there is no lingering pointers + * to the unloaded code after the dlclose(3). It is known reason for infinite + * stream of the crash reports for many programs which use loadable modules + * and fail to properly clean on module unload. Examples are apache, php, + * perl etc. + * + * You pass the &dso_handle_1 and &dso_handle_2, which points inside the + * main binary, to the registration function. The code from r211706, + * correctly detects that they are for the main binary, and on the first + * call to __cxa_finalize(), which also pass pointer to main binary, all + * registered functions from the main binary are executed. + */ + +static void *dso_handle_1 = (void *)1; +static void *dso_handle_2 = (void *)2; +static void *dso_handle_3 = (void *)3; +#else +static int dso_handle_1; +static int dso_handle_2; +static int dso_handle_3; +#endif + +static int arg_1; +static int arg_2; +static int arg_3; + +static int exiting_state; + +#define ASSERT(expr) \ +do { \ + if ((expr) == 0) { \ + write(STDERR_FILENO, __func__, strlen(__func__)); \ + write(STDERR_FILENO, ": ", 2); \ + write(STDERR_FILENO, __STRING(expr), \ + strlen(__STRING(expr))); \ + write(STDERR_FILENO, "\n", 1); \ + my_abort(); \ + } \ +} while (/*CONSTCOND*/0) + +#define SUCCESS() \ +do { \ + write(STDOUT_FILENO, __func__, strlen(__func__)); \ + write(STDOUT_FILENO, "\n", 1); \ +} while (/*CONSTCOND*/0) + +static void +my_abort(void) +{ + + kill(getpid(), SIGABRT); + /* NOTREACHED */ +} + +static void +cxa_handler_5(void *arg) +{ + static int cxa_handler_5_called; + + ASSERT(arg == (void *)&arg_1); + ASSERT(cxa_handler_5_called == 0); + ASSERT(exiting_state == 5); + + exiting_state--; + cxa_handler_5_called = 1; + SUCCESS(); +} + +static void +cxa_handler_4(void *arg) +{ + static int cxa_handler_4_called; + + ASSERT(arg == (void *)&arg_1); + ASSERT(cxa_handler_4_called == 0); + ASSERT(exiting_state == 4); + + exiting_state--; + cxa_handler_4_called = 1; + SUCCESS(); +} + +static void +cxa_handler_3(void *arg) +{ + static int cxa_handler_3_called; + + ASSERT(arg == (void *)&arg_2); + ASSERT(cxa_handler_3_called == 0); + ASSERT(exiting_state == 3); + + exiting_state--; + cxa_handler_3_called = 1; + SUCCESS(); +} + +static void +cxa_handler_2(void *arg) +{ + static int cxa_handler_2_called; + + ASSERT(arg == (void *)&arg_3); + ASSERT(cxa_handler_2_called == 0); + ASSERT(exiting_state == 2); + + exiting_state--; + cxa_handler_2_called = 1; + SUCCESS(); +} + +static void +normal_handler_1(void) +{ + static int normal_handler_1_called; + + ASSERT(normal_handler_1_called == 0); + ASSERT(exiting_state == 1); + + exiting_state--; + normal_handler_1_called = 1; + SUCCESS(); +} + +static void +normal_handler_0(void) +{ + static int normal_handler_0_called; + + ASSERT(normal_handler_0_called == 0); + ASSERT(exiting_state == 0); + + normal_handler_0_called = 1; + SUCCESS(); +} + +int +main(int argc, char *argv[]) +{ + + exiting_state = 5; + + ASSERT(0 == atexit(normal_handler_0)); + ASSERT(0 == atexit(normal_handler_1)); +#ifdef __FreeBSD__ + ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, dso_handle_2)); + ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, dso_handle_3)); + + __cxa_finalize(dso_handle_1); + __cxa_finalize(dso_handle_2); +#else + ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, &dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, &dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, &dso_handle_2)); + ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, &dso_handle_3)); + + __cxa_finalize(&dso_handle_1); + __cxa_finalize(&dso_handle_2); +#endif + exit(0); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c new file mode 100644 index 0000000..d53d2d9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c @@ -0,0 +1,134 @@ +/* $NetBSD: h_getopt.c,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#ifdef __FreeBSD__ +/* + * Needed to avoid libutil.h pollution in stdio.h, which causes grief with + * with hexdump(3) in lib/libc/db/h_hash.c + */ +#include +#endif + +#define WS "\t\n " +#define debug 0 + +int +main(int argc, char *argv[]) +{ + size_t len, lineno = 0; + char *line, *ptr, *optstring = NULL, *result = NULL; + char buf[1024]; + char *args[100]; + char arg[100]; + int nargs = -1; + int c; + + while ((line = fparseln(stdin, &len, &lineno, NULL, 0)) != NULL) { + if (strncmp(line, "load:", 5) == 0) { + if (optstring) + free(optstring); + optstring = strtok(&line[6], WS); + if (optstring == NULL) + errx(1, "missing optstring at line %ld", + (unsigned long)lineno); + optstring = strdup(optstring); + if (debug) + fprintf(stderr, "optstring = %s\n", optstring); + } else if (strncmp(line, "args:", 5) == 0) { + for (; nargs >= 0; nargs--) { + if (args[nargs] != NULL) + free(args[nargs]); + } + args[nargs = 0] = strtok(&line[6], WS); + if (args[nargs] == NULL) + errx(1, "missing args at line %ld", + (unsigned long)lineno); + + args[nargs] = strdup(args[nargs]); + while ((args[++nargs] = strtok(NULL, WS)) != NULL) + args[nargs] = strdup(args[nargs]); + if (debug) { + int i = 0; + for (i = 0; i < nargs; i++) + fprintf(stderr, "argv[%d] = %s\n", i, + args[i]); + } + } else if (strncmp(line, "result:", 7) == 0) { + buf[0] = '\0'; + optind = optreset = 1; + if (result) + free(result); + result = strtok(&line[8], WS); + if (result == NULL) + errx(1, "missing result at line %ld", + (unsigned long)lineno); + result = strdup(result); + if (nargs == -1) + errx(1, "result: without args:"); + if (debug) + fprintf(stderr, "result = %s\n", result); + while ((c = getopt(nargs, args, optstring)) != -1) { + if (c == ':') + err(1, "`:' found as argument char"); + if ((ptr = strchr(optstring, c)) == NULL) { + snprintf(arg, sizeof(arg), "!%c,", c); + strcat(buf, arg); + continue; + } + if (ptr[1] != ':') + snprintf(arg, sizeof(arg), "%c,", c); + else + snprintf(arg, sizeof(arg), "%c=%s,", + c, optarg); + strcat(buf, arg); + } + len = strlen(buf); + if (len > 0) { + buf[len - 1] = '|'; + buf[len] = '\0'; + } else { + buf[0] = '|'; + buf[1] = '\0'; + } + snprintf(arg, sizeof(arg), "%d", nargs - optind); + strcat(buf, arg); + if (strcmp(buf, result) != 0) + errx(1, "`%s' != `%s'", buf, result); + } + free(line); + } + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c new file mode 100644 index 0000000..c7cd83e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c @@ -0,0 +1,246 @@ +/* $NetBSD: h_getopt_long.c,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ */ + +/*- + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +/* + * Needed to avoid libutil.h pollution in stdio.h, which causes grief with + * with hexdump(3) in lib/libc/db/h_hash.c + */ +#include +#endif + +#define SKIPWS(p) while (isspace((int)(*p))) p++ +#define WS "\t\n " + +int +main(int argc, char *argv[]) +{ + size_t len, lineno = 0; + char *line, *eptr, *longopt, *ptr, *optstring = NULL, *result = NULL; + char buf[1024]; + char *args[128]; + char arg[256]; + int nargs = -1; + int c; + int nlongopts = 0; + int maxnlongopts = 0; + int *longopt_flags = NULL; + struct option *longopts = NULL; + + while ((line = fparseln(stdin, &len, &lineno, NULL, 0)) != NULL) { + if (strncmp(line, "optstring:", 10) == 0) { + if (optstring) + free(optstring); + optstring = strtok(&line[11], WS); + if (optstring == NULL) + errx(1, "missing optstring at line %ld", + (unsigned long)lineno); + optstring = strdup(optstring); + } else if (strncmp(line, "longopts:", 9) == 0) { + if (longopts) { + int i; + for (i = 0; i < nlongopts; i++) + if (longopts[i].name != NULL) + free(__UNCONST(longopts[i].name)); + free(longopts); + } + if (longopt_flags) + free(longopt_flags); + nlongopts = 0; + ptr = strtok(&line[10], WS); + if (ptr == NULL) + errx(1, "missing longopts at line %ld", + (unsigned long)lineno); + maxnlongopts = strtoul(ptr, &eptr, 10); + if (*eptr != '\0') + warnx("garbage in longopts at line %ld", + (unsigned long)lineno); + maxnlongopts++; /* space for trailer */ + longopts = + (struct option *)calloc(sizeof(struct option), + maxnlongopts); + if (longopts == NULL) + err(1, "calloc"); + longopt_flags = (int *)calloc(sizeof(int), maxnlongopts); + if (longopt_flags == NULL) + err(1, "calloc"); + } else if (strncmp(line, "longopt:", 8) == 0) { + if (longopts == NULL) + errx(1, "longopt: without longopts at line %ld", + (unsigned long)lineno); + if (nlongopts >= maxnlongopts) + errx(1, "longopt: too many options at line %ld", + (unsigned long)lineno); + /* name */ + ptr = &line[9]; + SKIPWS(ptr); + longopt = strsep(&ptr, ","); + if (longopt == NULL) + errx(1, "missing longopt at line %ld", + (unsigned long)lineno); + longopts[nlongopts].name = strdup(longopt); + /* has_arg */ + SKIPWS(ptr); + longopt = strsep(&ptr, ","); + if (*longopt != '\0') { + if (strncmp(longopt, "0", 1) == 0 || + strncmp(longopt, "no_argument", 2) == 0) + longopts[nlongopts].has_arg = no_argument; + else if (strncmp(longopt, "1", 1) == 0 || + strncmp(longopt, "required_argument", 8) == 0) + longopts[nlongopts].has_arg = required_argument; + else if (strncmp(longopt, "2", 1) == 0 || + strncmp(longopt, "optional_argument", 8) == 0) + longopts[nlongopts].has_arg = optional_argument; + else + errx(1, "unknown has_arg %s at line %ld", + longopt, (unsigned long)lineno); + } + /* flag */ + SKIPWS(ptr); + longopt = strsep(&ptr, ","); + if (*longopt != '\0' && + strncmp(longopt, "NULL", 4) != 0) + longopts[nlongopts].flag = &longopt_flags[nlongopts]; + /* val */ + SKIPWS(ptr); + longopt = strsep(&ptr, ","); + if (*longopt == '\0') + errx(1, "missing val at line %ld", + (unsigned long)lineno); + if (*longopt != '\'') { + longopts[nlongopts].val = + (int)strtoul(longopt, &eptr, 10); + if (*eptr != '\0') + errx(1, "invalid val at line %ld", + (unsigned long)lineno); + } else + longopts[nlongopts].val = (int)longopt[1]; + nlongopts++; + } else if (strncmp(line, "args:", 5) == 0) { + for (; nargs >= 0; nargs--) { + if (args[nargs] != NULL) + free(args[nargs]); + } + args[nargs = 0] = strtok(&line[6], WS); + if (args[nargs] == NULL) + errx(1, "Missing args"); + + args[nargs] = strdup(args[nargs]); + while ((args[++nargs] = strtok(NULL, WS)) != NULL) + args[nargs] = strdup(args[nargs]); + } else if (strncmp(line, "result:", 7) == 0) { + int li; + buf[0] = '\0'; + optind = optreset = 1; + if (result) + free(result); + result = strtok(&line[8], WS); + if (result == NULL) + errx(1, "missing result at line %ld", + (unsigned long)lineno); + if (optstring == NULL) + errx(1, "result: without optstring"); + if (longopts == NULL || nlongopts == 0) + errx(1, "result: without longopts"); + result = strdup(result); + if (nargs == -1) + errx(1, "result: without args"); + li = -2; + while ((c = getopt_long(nargs, args, optstring, + longopts, &li)) != -1) { + if (c == ':') + errx(1, "`:' found as argument char"); + if (li == -2) { + ptr = strchr(optstring, c); + if (ptr == NULL) { + snprintf(arg, sizeof(arg), + "!%c,", c); + strcat(buf, arg); + continue; + } + if (ptr[1] != ':') + snprintf(arg, sizeof(arg), + "%c,", c); + else + snprintf(arg, sizeof(arg), + "%c=%s,", c, optarg); + } else { + switch (longopts[li].has_arg) { + case no_argument: + snprintf(arg, sizeof(arg), "-%s,", + longopts[li].name); + break; + case required_argument: + snprintf(arg, sizeof(arg), + "-%s=%s,", + longopts[li].name, optarg); + break; + case optional_argument: + snprintf(arg, sizeof(arg), + "-%s%s%s,", + longopts[li].name, + (optarg)? "=" : "", + (optarg)? optarg : ""); + break; + default: + errx(1, "internal error"); + } + } + strcat(buf, arg); + li = -2; + } + len = strlen(buf); + if (len > 0) { + buf[len - 1] = '|'; + buf[len] = '\0'; + } else { + buf[0] = '|'; + buf[1] = '\0'; + } + snprintf(arg, sizeof(arg), "%d", nargs - optind); + strcat(buf, arg); + if (strcmp(buf, result) != 0) + errx(1, "`%s' != `%s'", buf, result); + } else + errx(1, "unknown directive at line %ld", + (unsigned long)lineno); + free(line); + } + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c b/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c new file mode 100644 index 0000000..282a125 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c @@ -0,0 +1,154 @@ +/* $NetBSD: t_abs.c,v 1.3 2014/03/01 22:38:13 joerg Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_abs.c,v 1.3 2014/03/01 22:38:13 joerg Exp $"); + +#include +#include +#include +#include + +ATF_TC(abs_basic); +ATF_TC_HEAD(abs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that abs(3) works"); +} + +ATF_TC_BODY(abs_basic, tc) +{ + static const struct { + int val; + int res; + } table[] = { + { 0, 0 }, + { +0, 0 }, + { -0, 0 }, + { -0x1010, 0x1010 }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + }; + + for (size_t i = 0; i < __arraycount(table); i++) + ATF_CHECK(abs(table[i].val) == table[i].res); +} + +ATF_TC(imaxabs_basic); +ATF_TC_HEAD(imaxabs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that imaxabs(3) works"); +} + +ATF_TC_BODY(imaxabs_basic, tc) +{ + static const struct { + intmax_t val; + intmax_t res; + } table[] = { + { 0, 0 }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + { LONG_MAX, LONG_MAX }, + { -LONG_MAX, LONG_MAX }, + { LLONG_MAX, LLONG_MAX }, + { -LLONG_MAX, LLONG_MAX }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + }; + + for (size_t i = 0; i < __arraycount(table); i++) + ATF_CHECK(imaxabs(table[i].val) == table[i].res); +} + +ATF_TC(labs_basic); +ATF_TC_HEAD(labs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that labs(3) works"); +} + +ATF_TC_BODY(labs_basic, tc) +{ + static const struct { + long val; + long res; + } table[] = { + { 0, 0 }, + { +0, 0 }, + { -0, 0 }, + { -1, 1 }, + { LONG_MAX, LONG_MAX }, + { -LONG_MAX, LONG_MAX }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + }; + + for (size_t i = 0; i < __arraycount(table); i++) + ATF_CHECK(labs(table[i].val) == table[i].res); +} + +ATF_TC(llabs_basic); +ATF_TC_HEAD(llabs_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that llabs(3) works"); +} + +ATF_TC_BODY(llabs_basic, tc) +{ + static const struct { + long long val; + long long res; + } table[] = { + { 0, 0 }, + { +0, 0 }, + { -0, 0 }, + { -1, 1 }, + { INT_MAX, INT_MAX }, + { -INT_MAX, INT_MAX }, + { LONG_MAX, LONG_MAX }, + { -LONG_MAX, LONG_MAX }, + { LLONG_MAX, LLONG_MAX }, + { -LLONG_MAX, LLONG_MAX }, + { -0x100000000LL, 0x100000000LL }, + }; + + for (size_t i = 0; i < __arraycount(table); i++) + ATF_CHECK(llabs(table[i].val) == table[i].res); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, abs_basic); + ATF_TP_ADD_TC(tp, imaxabs_basic); + ATF_TP_ADD_TC(tp, labs_basic); + ATF_TP_ADD_TC(tp, llabs_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh b/contrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh new file mode 100755 index 0000000..d11268b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh @@ -0,0 +1,54 @@ +# $NetBSD: t_atexit.sh,v 1.1 2011/01/12 19:44:08 pgoyette Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case atexit +atexit_head() +{ + atf_set "descr" "Checks atexit(3) and __cxa_atexit()/__cxa_finalize()" +} +atexit_body() +{ + $(atf_get_srcdir)/h_atexit >out \ + || atf_fail "h_exit failed, see output of the test for details" + + cat >exp < +__RCSID("$NetBSD: t_atoi.c,v 1.2 2012/03/29 05:56:36 jruoho Exp $"); + +#include +#include +#include +#include +#include + +ATF_TC(atof_strtod); +ATF_TC_HEAD(atof_strtod, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that atof(3) matches the corresponding strtod(3) call"); +} + +ATF_TC_BODY(atof_strtod, tc) +{ + char buf[128]; + + (void)snprintf(buf, sizeof(buf), "%f\n", DBL_MAX); + + ATF_REQUIRE(atof("0") == strtod("0", NULL)); + ATF_REQUIRE(atof("-1") == strtod("-1", NULL)); + ATF_REQUIRE(atof(buf) == strtod(buf, NULL)); +} + +ATF_TC(atoi_strtol); +ATF_TC_HEAD(atoi_strtol, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that atoi(3) matches the corresponding strtol(3) call"); +} + +ATF_TC_BODY(atoi_strtol, tc) +{ + char buf[64]; + + (void)snprintf(buf, sizeof(buf), "%d\n", INT_MAX); + + ATF_REQUIRE(atoi("0") == strtol("0", NULL, 10)); + ATF_REQUIRE(atoi("-1") == strtol("-1", NULL, 10)); + ATF_REQUIRE(atoi(buf) == strtol(buf, NULL, 10)); +} + +ATF_TC(atol_strtol); +ATF_TC_HEAD(atol_strtol, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that atol(3) matches the corresponding strtol(3) call"); +} + +ATF_TC_BODY(atol_strtol, tc) +{ + char buf[64]; + + (void)snprintf(buf, sizeof(buf), "%ld\n", LONG_MAX); + + ATF_REQUIRE(atol("0") == strtol("0", NULL, 10)); + ATF_REQUIRE(atol("-1") == strtol("-1", NULL, 10)); + ATF_REQUIRE(atol(buf) == strtol(buf, NULL, 10)); +} + +ATF_TC(atoll_strtoll); +ATF_TC_HEAD(atoll_strtoll, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that atoll(3) matches the corresponding strtoll(3) call"); +} + +ATF_TC_BODY(atoll_strtoll, tc) +{ + char buf[128]; + + (void)snprintf(buf, sizeof(buf), "%lld\n", LLONG_MAX); + + ATF_REQUIRE(atoll("0") == strtoll("0", NULL, 10)); + ATF_REQUIRE(atoll("-1") == strtoll("-1", NULL, 10)); + ATF_REQUIRE(atoll(buf) == strtoll(buf, NULL, 10)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, atof_strtod); + ATF_TP_ADD_TC(tp, atoi_strtol); + ATF_TP_ADD_TC(tp, atol_strtol); + ATF_TP_ADD_TC(tp, atoll_strtoll); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_div.c b/contrib/netbsd-tests/lib/libc/stdlib/t_div.c new file mode 100644 index 0000000..376f357 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_div.c @@ -0,0 +1,98 @@ +/* $NetBSD: t_div.c,v 1.2 2011/07/07 11:12:18 jruoho Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include + +#define NUM 1999236 +#define DENOM 1000000 +#define QUOT 1 +#define REM 999236 + +ATF_TC(div_basic); +ATF_TC_HEAD(div_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test div(3) for correctness"); +} + +ATF_TC_BODY(div_basic, tc) +{ + div_t d; + + d = div(NUM, DENOM); + + ATF_CHECK(d.quot == QUOT); + ATF_CHECK(d.rem == REM); +} + +ATF_TC(ldiv_basic); +ATF_TC_HEAD(ldiv_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test ldiv(3) for correctness"); +} + +ATF_TC_BODY(ldiv_basic, tc) +{ + ldiv_t ld; + + ld = ldiv(NUM, DENOM); + + ATF_CHECK(ld.quot == QUOT); + ATF_CHECK(ld.rem == REM); +} + +ATF_TC(lldiv_basic); +ATF_TC_HEAD(lldiv_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test lllldiv(3) for correctness"); +} + +ATF_TC_BODY(lldiv_basic, tc) +{ + lldiv_t lld; + + lld = lldiv(NUM, DENOM); + + ATF_CHECK(lld.quot == QUOT); + ATF_CHECK(lld.rem == REM); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, div_basic); + ATF_TP_ADD_TC(tp, ldiv_basic); + ATF_TP_ADD_TC(tp, lldiv_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c b/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c new file mode 100644 index 0000000..067cb51 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c @@ -0,0 +1,186 @@ +/* $NetBSD: t_exit.c,v 1.1 2011/05/09 07:31:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_exit.c,v 1.1 2011/05/09 07:31:51 jruoho Exp $"); + +#include + +#include +#include +#include +#include +#include + +static bool fail; +static void func(void); + +static void +func(void) +{ + fail = false; +} + +ATF_TC(exit_atexit); +ATF_TC_HEAD(exit_atexit, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of atexit(3)"); +} + +ATF_TC_BODY(exit_atexit, tc) +{ + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (atexit(func) != 0) + _exit(EXIT_FAILURE); + + fail = true; + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("atexit(3) failed"); + + if (fail != false) + atf_tc_fail("atexit(3) was not called"); +} + +ATF_TC(exit_basic); +ATF_TC_HEAD(exit_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of exit(3)"); +} + +ATF_TC_BODY(exit_basic, tc) +{ + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + exit(EXIT_SUCCESS); + exit(EXIT_FAILURE); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("exit(3) did not exit successfully"); +} + +ATF_TC(exit_status); +ATF_TC_HEAD(exit_status, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exit(3) status"); +} + +ATF_TC_BODY(exit_status, tc) +{ + const int n = 10; + int i, sta; + pid_t pid; + + for (i = 0; i < n; i++) { + + pid = fork(); + + if (pid < 0) + exit(EXIT_FAILURE); + + if (pid == 0) + exit(i); + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != i) + atf_tc_fail("invalid exit(3) status"); + } +} + +ATF_TC(exit_tmpfile); +ATF_TC_HEAD(exit_tmpfile, tc) +{ + atf_tc_set_md_var(tc, "descr", "Temporary files are unlinked?"); +} + +ATF_TC_BODY(exit_tmpfile, tc) +{ + int sta, fd = -1; + char buf[12]; + pid_t pid; + FILE *f; + + (void)strlcpy(buf, "exit.XXXXXX", sizeof(buf)); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + fd = mkstemp(buf); + + if (fd < 0) + exit(EXIT_FAILURE); + + exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("failed to create temporary file"); + + f = fdopen(fd, "r"); + + if (f != NULL) + atf_tc_fail("exit(3) did not clear temporary file"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, exit_atexit); + ATF_TP_ADD_TC(tp, exit_basic); + ATF_TP_ADD_TC(tp, exit_status); + ATF_TP_ADD_TC(tp, exit_tmpfile); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c new file mode 100644 index 0000000..7e29778 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c @@ -0,0 +1,211 @@ +/* $NetBSD: t_getenv.c,v 1.3 2015/02/27 08:55:35 martin Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_getenv.c,v 1.3 2015/02/27 08:55:35 martin Exp $"); + +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#endif + +extern char **environ; + +ATF_TC(clearenv_basic); +ATF_TC_HEAD(clearenv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test user clearing environment directly"); +} + +ATF_TC_BODY(clearenv_basic, tc) +{ + char name[1024], value[1024]; + + for (size_t i = 0; i < 1024; i++) { + snprintf(name, sizeof(name), "crap%zu", i); + snprintf(value, sizeof(value), "%zu", i); + ATF_CHECK(setenv(name, value, 1) != -1); + } + + *environ = NULL; + + for (size_t i = 0; i < 1; i++) { + snprintf(name, sizeof(name), "crap%zu", i); + snprintf(value, sizeof(value), "%zu", i); + ATF_CHECK(setenv(name, value, 1) != -1); + } + + ATF_CHECK_STREQ(getenv("crap0"), "0"); + ATF_CHECK(getenv("crap1") == NULL); + ATF_CHECK(getenv("crap2") == NULL); +} + +ATF_TC(getenv_basic); +ATF_TC_HEAD(getenv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test setenv(3), getenv(3)"); +} + +ATF_TC_BODY(getenv_basic, tc) +{ + ATF_CHECK(setenv("EVIL", "very=bad", 1) != -1); + ATF_CHECK_STREQ(getenv("EVIL"), "very=bad"); + ATF_CHECK(getenv("EVIL=very") == NULL); + ATF_CHECK(unsetenv("EVIL") != -1); +} + +ATF_TC(putenv_basic); +ATF_TC_HEAD(putenv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test putenv(3), getenv(3), unsetenv(3)"); +} + + +ATF_TC_BODY(putenv_basic, tc) +{ + char string[1024]; + + snprintf(string, sizeof(string), "crap=true"); + ATF_CHECK(putenv(string) != -1); + ATF_CHECK_STREQ(getenv("crap"), "true"); + string[1] = 'l'; + ATF_CHECK_STREQ(getenv("clap"), "true"); + ATF_CHECK(getenv("crap") == NULL); + string[1] = 'r'; + ATF_CHECK(unsetenv("crap") != -1); + ATF_CHECK(getenv("crap") == NULL); + + ATF_CHECK_ERRNO(EINVAL, putenv(NULL) == -1); + ATF_CHECK_ERRNO(EINVAL, putenv(__UNCONST("val")) == -1); + ATF_CHECK_ERRNO(EINVAL, putenv(__UNCONST("=val")) == -1); +} + +ATF_TC(setenv_basic); +ATF_TC_HEAD(setenv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test setenv(3), getenv(3), unsetenv(3)"); + atf_tc_set_md_var(tc, "timeout", "600"); +} + +ATF_TC_BODY(setenv_basic, tc) +{ + const size_t numvars = 8192; + size_t i, offset; + char name[1024]; + char value[1024]; + + offset = lrand48(); + for (i = 0; i < numvars; i++) { + (void)snprintf(name, sizeof(name), "var%zu", + (i * 7 + offset) % numvars); + (void)snprintf(value, sizeof(value), "value%ld", lrand48()); + ATF_CHECK(setenv(name, value, 1) != -1); + ATF_CHECK(setenv(name, "foo", 0) != -1); + ATF_CHECK_STREQ(getenv(name), value); + } + + offset = lrand48(); + for (i = 0; i < numvars; i++) { + (void)snprintf(name, sizeof(name), "var%zu", + (i * 11 + offset) % numvars); + ATF_CHECK(unsetenv(name) != -1); + ATF_CHECK(getenv(name) == NULL); + ATF_CHECK(unsetenv(name) != -1); + } + + ATF_CHECK_ERRNO(EINVAL, setenv(NULL, "val", 1) == -1); + ATF_CHECK_ERRNO(EINVAL, setenv("", "val", 1) == -1); + ATF_CHECK_ERRNO(EINVAL, setenv("v=r", "val", 1) == -1); +#ifdef __FreeBSD__ + /* + Both FreeBSD and OS/X does not validate the second + argument to setenv(3) + */ + atf_tc_expect_signal(SIGSEGV, "FreeBSD does not validate the second " + "argument to setenv(3); see bin/189805"); +#endif + + ATF_CHECK_ERRNO(EINVAL, setenv("var", NULL, 1) == -1); + + ATF_CHECK(setenv("var", "=val", 1) == 0); + ATF_CHECK_STREQ(getenv("var"), "=val"); +} + +ATF_TC(setenv_mixed); +ATF_TC_HEAD(setenv_mixed, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test mixing setenv(3), unsetenv(3) and putenv(3)"); +} + +ATF_TC_BODY(setenv_mixed, tc) +{ + char string[32]; + + (void)strcpy(string, "mixedcrap=putenv"); + + ATF_CHECK(setenv("mixedcrap", "setenv", 1) != -1); + ATF_CHECK_STREQ(getenv("mixedcrap"), "setenv"); + ATF_CHECK(putenv(string) != -1); + ATF_CHECK_STREQ(getenv("mixedcrap"), "putenv"); + ATF_CHECK(unsetenv("mixedcrap") != -1); + ATF_CHECK(getenv("mixedcrap") == NULL); + + ATF_CHECK(putenv(string) != -1); + ATF_CHECK_STREQ(getenv("mixedcrap"), "putenv"); + ATF_CHECK(setenv("mixedcrap", "setenv", 1) != -1); + ATF_CHECK_STREQ(getenv("mixedcrap"), "setenv"); + ATF_CHECK(unsetenv("mixedcrap") != -1); + ATF_CHECK(getenv("mixedcrap") == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clearenv_basic); + ATF_TP_ADD_TC(tp, getenv_basic); + ATF_TP_ADD_TC(tp, putenv_basic); + ATF_TP_ADD_TC(tp, setenv_basic); + ATF_TP_ADD_TC(tp, setenv_mixed); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c new file mode 100644 index 0000000..d935629 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c @@ -0,0 +1,250 @@ +/* $NetBSD: t_getenv_thread.c,v 1.2 2012/03/15 02:02:23 joerg Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_getenv_thread.c,v 1.2 2012/03/15 02:02:23 joerg Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#define THREADED_NUM_THREADS 8 +#define THREADED_NUM_VARS 16 +#define THREADED_VAR_NAME "THREADED%zu" +#define THREADED_RUN_TIME 10 + +static void *thread_getenv_r(void *); +static void *thread_putenv(void *); +static void *thread_setenv(void *); +static void *thread_unsetenv(void *); + +static void * +thread_getenv_r(void *arg) +{ + time_t endtime; + + endtime = *(time_t *)arg; + do { + size_t i; + char name[32], value[128]; + + i = lrand48() % THREADED_NUM_VARS; + (void)snprintf(name, sizeof(name), THREADED_VAR_NAME, i); + + if (getenv_r(name, value, sizeof(value)) == -1) { + ATF_CHECK(errno == ENOENT); + } + } while (time(NULL) < endtime); + + return NULL; +} + + +static void * +thread_putenv(void *arg) +{ + time_t endtime; + size_t i; + static char vars[THREADED_NUM_VARS][128]; + + for (i = 0; i < THREADED_NUM_VARS; i++) { + (void)snprintf(vars[i], sizeof(vars[i]), + THREADED_VAR_NAME "=putenv %ld", i, lrand48()); + } + + endtime = *(time_t *)arg; + do { + char name[128]; + + i = lrand48() % THREADED_NUM_VARS; + (void)strlcpy(name, vars[i], sizeof(name)); + *strchr(name, '=') = '\0'; + + ATF_CHECK(unsetenv(name) != -1); + ATF_CHECK(putenv(vars[i]) != -1); + } while (time(NULL) < endtime); + + return NULL; +} + +static void * +thread_setenv(void *arg) +{ + time_t endtime; + + endtime = *(time_t *)arg; + do { + size_t i; + char name[32], value[64]; + + i = lrand48() % THREADED_NUM_VARS; + (void)snprintf(name, sizeof(name), THREADED_VAR_NAME, i); + (void)snprintf(value, sizeof(value), "setenv %ld", lrand48()); + + ATF_CHECK(setenv(name, value, 1) != -1); + } while (time(NULL) < endtime); + + return NULL; +} + +static void * +thread_unsetenv(void *arg) +{ + time_t endtime; + + endtime = *(time_t *)arg; + do { + size_t i; + char name[32]; + + i = lrand48() % THREADED_NUM_VARS; + (void)snprintf(name, sizeof(name), THREADED_VAR_NAME, i); + + ATF_CHECK(unsetenv(name) != -1); + } while (time(NULL) < endtime); + + return NULL; +} + +ATF_TC(getenv_r_thread); +ATF_TC_HEAD(getenv_r_thread, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test getenv_r(3) with threads"); + atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5); +} + +ATF_TC_BODY(getenv_r_thread, tc) +{ + pthread_t threads[THREADED_NUM_THREADS]; + time_t endtime; + size_t i, j; + + endtime = time(NULL) + THREADED_RUN_TIME; + + for (i = j = 0; j < 2; j++) { + + ATF_CHECK(pthread_create(&threads[i++], NULL, thread_getenv_r, + &endtime) == 0); + } + + for (j = 0; j < i; j++) + ATF_CHECK(pthread_join(threads[j], NULL) == 0); +} + +ATF_TC(putenv_thread); +ATF_TC_HEAD(putenv_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test concurrent access by putenv(3)"); + atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5); +} + +ATF_TC_BODY(putenv_thread, tc) +{ + pthread_t threads[THREADED_NUM_THREADS]; + time_t endtime; + size_t i, j; + + endtime = time(NULL) + THREADED_RUN_TIME; + + for (i = j = 0; j < 2; j++) { + + ATF_CHECK(pthread_create(&threads[i++], NULL, thread_putenv, + &endtime) == 0); + } + + for (j = 0; j < i; j++) + ATF_CHECK(pthread_join(threads[j], NULL) == 0); +} + +ATF_TC(setenv_thread); +ATF_TC_HEAD(setenv_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test concurrent access by setenv(3)"); + atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5); +} + +ATF_TC_BODY(setenv_thread, tc) +{ + pthread_t threads[THREADED_NUM_THREADS]; + time_t endtime; + size_t i, j; + + endtime = time(NULL) + THREADED_RUN_TIME; + + for (i = j = 0; j < 2; j++) { + + ATF_CHECK(pthread_create(&threads[i++], NULL, thread_setenv, + &endtime) == 0); + } + + for (j = 0; j < i; j++) + ATF_CHECK(pthread_join(threads[j], NULL) == 0); +} + +ATF_TC(unsetenv_thread); +ATF_TC_HEAD(unsetenv_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test unsetenv(3) with threads"); + atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5); +} + +ATF_TC_BODY(unsetenv_thread, tc) +{ + pthread_t threads[THREADED_NUM_THREADS]; + time_t endtime; + size_t i, j; + + endtime = time(NULL) + THREADED_RUN_TIME; + + for (i = j = 0; j < 2; j++) { + + ATF_CHECK(pthread_create(&threads[i++], NULL, thread_unsetenv, + &endtime) == 0); + } + + for (j = 0; j < i; j++) + ATF_CHECK(pthread_join(threads[j], NULL) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getenv_r_thread); + ATF_TP_ADD_TC(tp, putenv_thread); + ATF_TP_ADD_TC(tp, setenv_thread); + ATF_TP_ADD_TC(tp, unsetenv_thread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh b/contrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh new file mode 100755 index 0000000..cc10f65 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh @@ -0,0 +1,123 @@ +# $NetBSD: t_getopt.sh,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +h_getopt() +{ + atf_check -e save:stderr -x "$(atf_get_srcdir)/h_getopt" <= this works + h_getopt_long "${load}" "foo --col" "-color|0" + + h_getopt_long "${load}" "foo --colour" "-colour|0" + + # This is the real GNU libc test! + args="foo -a -b -cfoobar --required foobar --optional=bazbug --none random --col --color --colour" + # GNU libc 2.1.3 this fails with ambiguous + #result="a,b,c=foobar,-required=foobar,-optional=bazbug,-none,!?,-color,-colour|1" + # + # GNU libc 2.2 >= this works + result="a,b,c=foobar,-required=foobar,-optional=bazbug,-none,-color,-color,-colour|1" + h_getopt_long "${load}" "${args}" "${result}" + + # + # The order of long options in the long option array should not matter. + # An exact match should never be treated as ambiguous. + # + load="optstring: fgl +longopts: 3 +longopt: list-foobar, no_argument, lopt, 'f' +longopt: list-goobar, no_argument, lopt, 'g' +longopt: list, no_argument, lopt, 'l'" + h_getopt_long "${load}" "foo --list" "-list|0" +} + + +atf_init_test_cases() +{ + atf_add_test_case getopt + atf_add_test_case getopt_long +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c new file mode 100644 index 0000000..5a13250 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c @@ -0,0 +1,416 @@ +/* $NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Copyright (c) 2001 Christopher G. Demetriou + * 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 for the + * NetBSD Project. See http://www.NetBSD.org/ for + * information about NetBSD. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $"); + +#include +#include +#include +#include +#include + +#include + +#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) + +ATF_TC(hsearch_basic); +ATF_TC_HEAD(hsearch_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching"); +} + +ATF_TC_BODY(hsearch_basic, tc) +{ + ENTRY e, *ep; + char ch[2]; + int i; + + REQUIRE_ERRNO(hcreate(16) != 0); + + /* ch[1] should be constant from here on down. */ + ch[1] = '\0'; + + /* Basic insertions. Check enough that there'll be collisions. */ + for (i = 0; i < 26; i++) { + ch[0] = 'a' + i; + e.key = strdup(ch); /* ptr to provided key is kept! */ + ATF_REQUIRE(e.key != NULL); + e.data = (void *)(intptr_t)i; + + ep = hsearch(e, ENTER); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, ch); + ATF_REQUIRE_EQ((intptr_t)ep->data, i); + } + + /* e.key should be constant from here on down. */ + e.key = ch; + + /* Basic lookups. */ + for (i = 0; i < 26; i++) { + ch[0] = 'a' + i; + + ep = hsearch(e, FIND); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, ch); + ATF_REQUIRE_EQ((intptr_t)ep->data, i); + } + +#ifdef __NetBSD__ + hdestroy1(free, NULL); +#else + hdestroy(); +#endif +} + +ATF_TC(hsearch_duplicate); +ATF_TC_HEAD(hsearch_duplicate, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate " + "doesn't overwrite existing data"); +} + +ATF_TC_BODY(hsearch_duplicate, tc) +{ + ENTRY e, *ep; + + REQUIRE_ERRNO(hcreate(16)); + + e.key = __UNCONST("a"); + e.data = (void *)(intptr_t) 0; + + ep = hsearch(e, ENTER); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + e.data = (void *)(intptr_t)12345; + + ep = hsearch(e, ENTER); + ep = hsearch(e, FIND); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + hdestroy(); +} + +ATF_TC(hsearch_nonexistent); +ATF_TC_HEAD(hsearch_nonexistent, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks searching for non-existent entry"); +} + +ATF_TC_BODY(hsearch_nonexistent, tc) +{ + ENTRY e, *ep; + + REQUIRE_ERRNO(hcreate(16)); + + e.key = __UNCONST("A"); + ep = hsearch(e, FIND); + ATF_REQUIRE_EQ(ep, NULL); + + hdestroy(); +} + +ATF_TC(hsearch_two); +ATF_TC_HEAD(hsearch_two, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that searching doesn't overwrite previous search results"); +} + +ATF_TC_BODY(hsearch_two, tc) +{ + ENTRY e, *ep, *ep2; + + REQUIRE_ERRNO(hcreate(16)); + + e.key = __UNCONST("a"); + e.data = (void*)(intptr_t)0; + + ep = hsearch(e, ENTER); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + e.key = __UNCONST("b"); + e.data = (void*)(intptr_t)1; + + ep = hsearch(e, ENTER); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "b"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 1); + + e.key = __UNCONST("a"); + ep = hsearch(e, FIND); + + e.key = __UNCONST("b"); + ep2 = hsearch(e, FIND); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + ATF_REQUIRE(ep2 != NULL); + ATF_REQUIRE_STREQ(ep2->key, "b"); + ATF_REQUIRE_EQ((intptr_t)ep2->data, 1); + + hdestroy(); +} + +#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version +ATF_TC(hsearch_r_basic); +ATF_TC_HEAD(hsearch_r_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching"); +} + +ATF_TC_BODY(hsearch_r_basic, tc) +{ + ENTRY e, *ep; + char ch[2]; + int i; + struct hsearch_data t; + + REQUIRE_ERRNO(hcreate_r(16, &t) != 0); + + /* ch[1] should be constant from here on down. */ + ch[1] = '\0'; + + /* Basic insertions. Check enough that there'll be collisions. */ + for (i = 0; i < 26; i++) { + ch[0] = 'a' + i; + e.key = strdup(ch); /* ptr to provided key is kept! */ + ATF_REQUIRE(e.key != NULL); + e.data = (void *)(intptr_t)i; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, ch); + ATF_REQUIRE_EQ((intptr_t)ep->data, i); + } + + /* e.key should be constant from here on down. */ + e.key = ch; + + /* Basic lookups. */ + for (i = 0; i < 26; i++) { + ch[0] = 'a' + i; + + ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, ch); + ATF_REQUIRE_EQ((intptr_t)ep->data, i); + } + +#ifdef __NetBSD__ + hdestroy1_r(&t, free, NULL); +#else + hdestroy_r(&t); +#endif +} +#endif + +#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version +ATF_TC(hsearch_r_duplicate); +ATF_TC_HEAD(hsearch_r_duplicate, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate " + "doesn't overwrite existing data"); +} + +ATF_TC_BODY(hsearch_r_duplicate, tc) +{ + ENTRY e, *ep; + struct hsearch_data t; + + REQUIRE_ERRNO(hcreate_r(16, &t)); + + e.key = __UNCONST("a"); + e.data = (void *)(intptr_t) 0; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + e.data = (void *)(intptr_t)12345; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + hdestroy_r(&t); +} + +ATF_TC(hsearch_r_nonexistent); +ATF_TC_HEAD(hsearch_r_nonexistent, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks searching for non-existent entry"); +} + +ATF_TC_BODY(hsearch_r_nonexistent, tc) +{ + ENTRY e, *ep; + struct hsearch_data t; + + REQUIRE_ERRNO(hcreate_r(16, &t)); + +#ifdef __FreeBSD__ + atf_tc_expect_fail("behavior doesn't match docs; see bug # 216872"); +#endif + e.key = __UNCONST("A"); + ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); + ATF_REQUIRE_EQ(ep, NULL); + + hdestroy_r(&t); +} + +ATF_TC(hsearch_r_two); +ATF_TC_HEAD(hsearch_r_two, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that searching doesn't overwrite previous search results"); +} + +ATF_TC_BODY(hsearch_r_two, tc) +{ + ENTRY e, *ep, *ep2; + struct hsearch_data t; + + REQUIRE_ERRNO(hcreate_r(16, &t)); + + e.key = __UNCONST("a"); + e.data = (void*)(intptr_t)0; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + e.key = __UNCONST("b"); + e.data = (void*)(intptr_t)1; + + ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1); + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "b"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 1); + + e.key = __UNCONST("a"); + ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1); + + e.key = __UNCONST("b"); + ATF_REQUIRE(hsearch_r(e, FIND, &ep2, &t) == 1); + + ATF_REQUIRE(ep != NULL); + ATF_REQUIRE_STREQ(ep->key, "a"); + ATF_REQUIRE_EQ((intptr_t)ep->data, 0); + + ATF_REQUIRE(ep2 != NULL); + ATF_REQUIRE_STREQ(ep2->key, "b"); + ATF_REQUIRE_EQ((intptr_t)ep2->data, 1); + + hdestroy_r(&t); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, hsearch_basic); + ATF_TP_ADD_TC(tp, hsearch_duplicate); + ATF_TP_ADD_TC(tp, hsearch_nonexistent); + ATF_TP_ADD_TC(tp, hsearch_two); + +#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version + ATF_TP_ADD_TC(tp, hsearch_r_basic); + ATF_TP_ADD_TC(tp, hsearch_r_duplicate); + ATF_TP_ADD_TC(tp, hsearch_r_nonexistent); + ATF_TP_ADD_TC(tp, hsearch_r_two); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c b/contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c new file mode 100644 index 0000000..77d6443 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c @@ -0,0 +1,95 @@ +/* $NetBSD: t_mi_vector_hash.c,v 1.3 2011/07/07 11:12:18 jruoho Exp $ */ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_mi_vector_hash.c,v 1.3 2011/07/07 11:12:18 jruoho Exp $"); + +#include +#include +#include + +ATF_TC(mi_vector_hash_basic); +ATF_TC_HEAD(mi_vector_hash_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test mi_vector_hash_vector_hash for consistent results"); +} + +static const struct testvector { + const char *vector; + uint32_t hashes[3]; +} testv[] = { + { "hello, world", { 0xd38f7f21, 0xbf6be9ab, 0x37a0e989 } }, + { "", { 0x9b2ec03d, 0xdb2b69ae, 0xbd49d10d } }, + { "a", { 0x9454baa3, 0xb711c708, 0x29eec818 } }, + { "ab", { 0x9a5dca90, 0xdd212644, 0x9879ac41 } }, + { "abc", { 0x0b91c470, 0x4770cdf5, 0x251e4793 } }, + { "abcd", { 0x5f128df3, 0xf5a667a6, 0x5ae61fa5 } }, + { "abcde", { 0x4cbae281, 0x799c0ed5, 0x03a96866 } }, + { "abcdef", { 0x507a54c8, 0xb6bd06f4, 0xde922732 } }, + { "abcdefg", { 0xae2bca5d, 0x61e960ef, 0xb9e6762c } }, + { "abcdefgh", { 0xd1021264, 0x87f6988f, 0x053f775e } }, + { "abcdefghi", { 0xe380defc, 0xfc35a811, 0x3a7b0a5f } }, + { "abcdefghij", { 0x9a504408, 0x70d2e89d, 0xc9cac242 } }, + { "abcdefghijk", { 0x376117d0, 0x89f434d4, 0xe52b8e4c } }, + { "abcdefghijkl", { 0x92253599, 0x7b6ff99e, 0x0b1b3ea5 } }, + { "abcdefghijklm", { 0x92ee6a52, 0x55587d47, 0x3122b031 } }, + { "abcdefghijklmn", { 0x827baf08, 0x1d0ada73, 0xfec330e0 } }, + { "abcdefghijklmno", { 0x06ab787d, 0xc1ad17c2, 0x11dccf31 } }, + { "abcdefghijklmnop", { 0x2cf18103, 0x638c9268, 0xfa1ecf51 } }, +}; + +ATF_TC_BODY(mi_vector_hash_basic, tc) +{ + size_t i, j, len; + uint32_t hashes[3]; + char buf[256]; + + for (j = 0; j < 8; ++j) { + for (i = 0; i < sizeof(testv) / sizeof(testv[0]); ++i) { + len = strlen(testv[i].vector); + strcpy(buf + j, testv[i].vector); + mi_vector_hash(buf + j, len, 0, hashes); + ATF_CHECK_EQ(hashes[0], testv[i].hashes[0]); + ATF_CHECK_EQ(hashes[1], testv[i].hashes[1]); + ATF_CHECK_EQ(hashes[2], testv[i].hashes[2]); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mi_vector_hash_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c b/contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c new file mode 100644 index 0000000..8db7880 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c @@ -0,0 +1,151 @@ +/* $NetBSD: t_posix_memalign.c,v 1.4 2015/11/07 17:35:31 nros Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_posix_memalign.c,v 1.4 2015/11/07 17:35:31 nros Exp $"); + +#include + +#include +#include +#include +#include +#include +#include + +ATF_TC(posix_memalign_basic); +ATF_TC_HEAD(posix_memalign_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks posix_memalign(3)"); +} +ATF_TC_BODY(posix_memalign_basic, tc) +{ + static const size_t size[] = { + 1, 2, 3, 4, 10, 100, 16384, 32768, 65536 + }; + static const size_t align[] = { + 512, 1024, 16, 32, 64, 4, 2048, 16, 2 + }; + + size_t i; + void *p; + + for (i = 0; i < __arraycount(size); i++) { + int ret; + p = (void*)0x1; + + (void)printf("Checking posix_memalign(&p, %zu, %zu)...\n", + align[i], size[i]); + ret = posix_memalign(&p, align[i], size[i]); + + if ( align[i] < sizeof(void *)) + ATF_REQUIRE_EQ_MSG(ret, EINVAL, + "posix_memalign: %s", strerror(ret)); + else { + ATF_REQUIRE_EQ_MSG(ret, 0, + "posix_memalign: %s", strerror(ret)); + ATF_REQUIRE_EQ_MSG(((intptr_t)p) & (align[i] - 1), 0, + "p = %p", p); + free(p); + } + } +} + + +ATF_TC(aligned_alloc_basic); +ATF_TC_HEAD(aligned_alloc_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks aligned_alloc(3)"); +} +ATF_TC_BODY(aligned_alloc_basic, tc) +{ + static const size_t size[] = { + 1, 2, 3, 4, 10, 100, 16384, 32768, 65536, 10000, 0 + }; + static const size_t align[] = { + 512, 1024, 16, 32, 64, 4, 2048, 16, 2, 2048, 0 + }; + + size_t i; + void *p; + + for (i = 0; i < __arraycount(size); i++) { + (void)printf("Checking aligned_alloc(%zu, %zu)...\n", + align[i], size[i]); + p = aligned_alloc(align[i], size[i]); + if (p == NULL) { + if (align[i] == 0 || ((align[i] - 1) & align[i]) != 0 || + size[i] % align[i] != 0) { + ATF_REQUIRE_EQ_MSG(errno, EINVAL, + "aligned_alloc: %s", strerror(errno)); + } + else { + ATF_REQUIRE_EQ_MSG(errno, ENOMEM, + "aligned_alloc: %s", strerror(errno)); + } + } + else { + ATF_REQUIRE_EQ_MSG(align[i] == 0, false, + "aligned_alloc: success when alignment was not " + "a power of 2"); + ATF_REQUIRE_EQ_MSG((align[i] - 1) & align[i], 0, + "aligned_alloc: success when alignment was not " + "a power of 2"); +#ifdef __NetBSD__ + /* + * NetBSD-specific invariant + * + * From aligned_alloc(3) on FreeBSD: + * + * Behavior is undefined if size is not an integral + * multiple of alignment. + */ + ATF_REQUIRE_EQ_MSG(size[i] % align[i], 0, + "aligned_alloc: success when size was not an " + "integer multiple of alignment"); +#endif + ATF_REQUIRE_EQ_MSG(((intptr_t)p) & (align[i] - 1), 0, + "p = %p", p); + free(p); + } + } +} + + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, posix_memalign_basic); + ATF_TP_ADD_TC(tp, aligned_alloc_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_random.c b/contrib/netbsd-tests/lib/libc/stdlib/t_random.c new file mode 100644 index 0000000..9a6d21e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_random.c @@ -0,0 +1,82 @@ +/* $NetBSD: t_random.c,v 1.3 2012/03/29 08:56:06 jruoho Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_random.c,v 1.3 2012/03/29 08:56:06 jruoho Exp $"); + +#include +#include +#include + +/* + * TODO: Add some general RNG tests (cf. the famous "diehard" tests?). + */ + +ATF_TC(random_same); +ATF_TC_HEAD(random_same, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that random(3) does not always return the same " + "value when the seed is initialized to zero"); +} + +#define MAX_ITER 10 + +ATF_TC_BODY(random_same, tc) +{ + long buf[MAX_ITER]; + size_t i, j; + + /* + * See CVE-2012-1577. + */ + srandom(0); + + for (i = 0; i < __arraycount(buf); i++) { + + buf[i] = random(); + + for (j = 0; j < i; j++) { + + (void)fprintf(stderr, "i = %zu, j = %zu: " + "%ld vs. %ld\n", i, j, buf[i], buf[j]); + + ATF_CHECK(buf[i] != buf[j]); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, random_same); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c b/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c new file mode 100644 index 0000000..4835e5d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c @@ -0,0 +1,334 @@ +/* $NetBSD: t_strtod.c,v 1.34 2015/12/22 14:19:25 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* Public domain, Otto Moerbeek , 2006. */ + +#include +__RCSID("$NetBSD: t_strtod.c,v 1.34 2015/12/22 14:19:25 christos Exp $"); + +#include +#include +#include +#include +#include + +#include + +#include + +#if !defined(__vax__) +static const char * const inf_strings[] = + { "Inf", "INF", "-Inf", "-INF", "Infinity", "+Infinity", + "INFINITY", "-INFINITY", "InFiNiTy", "+InFiNiTy" }; +const char *nan_string = "NaN(x)y"; +#endif + +ATF_TC(strtod_basic); +ATF_TC_HEAD(strtod_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strtod(3)"); +} + +ATF_TC_BODY(strtod_basic, tc) +{ + static const size_t n = 1024 * 1000; + + for (size_t i = 1; i < n; i = i + 1024) { + char buf[512]; + (void)snprintf(buf, sizeof(buf), "%zu.%zu", i, i + 1); + + errno = 0; + double d = strtod(buf, NULL); + + ATF_REQUIRE(d > 0.0); + ATF_REQUIRE(errno == 0); + } +} + +ATF_TC(strtod_hex); +ATF_TC_HEAD(strtod_hex, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtod(3) with hexadecimals"); +} + +#ifdef __vax__ +#define SMALL_NUM 1.0e-38 +#else +#define SMALL_NUM 1.0e-40 +#endif + +ATF_TC_BODY(strtod_hex, tc) +{ + const char *str; + char *end; + volatile double d; + + str = "-0x0"; + d = strtod(str, &end); /* -0.0 */ + + ATF_REQUIRE(end == str + 4); + ATF_REQUIRE(signbit(d) != 0); + ATF_REQUIRE(fabs(d) < SMALL_NUM); + + str = "-0x"; + d = strtod(str, &end); /* -0.0 */ + + ATF_REQUIRE(end == str + 2); + ATF_REQUIRE(signbit(d) != 0); + ATF_REQUIRE(fabs(d) < SMALL_NUM); +} + +ATF_TC(strtod_inf); +ATF_TC_HEAD(strtod_inf, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtod(3) with INF (PR lib/33262)"); +} + +ATF_TC_BODY(strtod_inf, tc) +{ +#ifndef __vax__ + for (size_t i = 0; i < __arraycount(inf_strings); i++) { + volatile double d = strtod(inf_strings[i], NULL); + ATF_REQUIRE(isinf(d) != 0); + } +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtof_inf); +ATF_TC_HEAD(strtof_inf, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtof(3) with INF (PR lib/33262)"); +} + +ATF_TC_BODY(strtof_inf, tc) +{ +#ifndef __vax__ + for (size_t i = 0; i < __arraycount(inf_strings); i++) { + volatile float f = strtof(inf_strings[i], NULL); + ATF_REQUIRE(isinf(f) != 0); + } +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtold_inf); +ATF_TC_HEAD(strtold_inf, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtold(3) with INF (PR lib/33262)"); +} + +ATF_TC_BODY(strtold_inf, tc) +{ +#ifndef __vax__ +# ifdef __HAVE_LONG_DOUBLE + + for (size_t i = 0; i < __arraycount(inf_strings); i++) { + volatile long double ld = strtold(inf_strings[i], NULL); + ATF_REQUIRE(isinf(ld) != 0); + } +# else + atf_tc_skip("Requires long double support"); +# endif +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtod_nan); +ATF_TC_HEAD(strtod_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtod(3) with NaN"); +} + +ATF_TC_BODY(strtod_nan, tc) +{ +#ifndef __vax__ + char *end; + + volatile double d = strtod(nan_string, &end); + ATF_REQUIRE(isnan(d) != 0); + ATF_REQUIRE(strcmp(end, "y") == 0); +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtof_nan); +ATF_TC_HEAD(strtof_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtof(3) with NaN"); +} + +ATF_TC_BODY(strtof_nan, tc) +{ +#ifndef __vax__ + char *end; + + volatile float f = strtof(nan_string, &end); + ATF_REQUIRE(isnanf(f) != 0); + ATF_REQUIRE(strcmp(end, "y") == 0); +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtold_nan); +ATF_TC_HEAD(strtold_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "A strtold(3) with NaN (PR lib/45020)"); +} + +ATF_TC_BODY(strtold_nan, tc) +{ +#ifndef __vax__ +# ifdef __HAVE_LONG_DOUBLE + + char *end; + + volatile long double ld = strtold(nan_string, &end); + ATF_REQUIRE(isnan(ld) != 0); +#ifndef __FreeBSD__ + ATF_REQUIRE(__isnanl(ld) != 0); +#endif + ATF_REQUIRE(strcmp(end, "y") == 0); +# else + atf_tc_skip("Requires long double support"); +# endif +#else + atf_tc_skip("vax not supported"); +#endif +} + +ATF_TC(strtod_round); +ATF_TC_HEAD(strtod_round, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test rouding in strtod(3)"); +} + +ATF_TC_BODY(strtod_round, tc) +{ +#ifdef __HAVE_FENV + + /* + * Test that strtod(3) honors the current rounding mode. + * The used value is somewhere near 1 + DBL_EPSILON + FLT_EPSILON. + */ + const char *val = + "1.00000011920928977282585492503130808472633361816406"; + + (void)fesetround(FE_UPWARD); + + volatile double d1 = strtod(val, NULL); + + (void)fesetround(FE_DOWNWARD); + + volatile double d2 = strtod(val, NULL); + + if (fabs(d1 - d2) > 0.0) + return; + else { + atf_tc_expect_fail("PR misc/44767"); + atf_tc_fail("strtod(3) did not honor fesetround(3)"); + } +#else + atf_tc_skip("Requires support"); +#endif +} + +ATF_TC(strtod_underflow); +ATF_TC_HEAD(strtod_underflow, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test underflow in strtod(3)"); +} + +ATF_TC_BODY(strtod_underflow, tc) +{ + + const char *tmp = + "0.0000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000" + "000000000000000002"; + + errno = 0; + volatile double d = strtod(tmp, NULL); + + if (d != 0 || errno != ERANGE) + atf_tc_fail("strtod(3) did not detect underflow"); +} + +/* + * Bug found by Geza Herman. + * See + * http://www.exploringbinary.com/a-bug-in-the-bigcomp-function-of-david-gays-strtod/ + */ +ATF_TC(strtod_gherman_bug); +ATF_TC_HEAD(strtod_gherman_bug, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test a bug found by Geza Herman"); +} + +ATF_TC_BODY(strtod_gherman_bug, tc) +{ + + const char *str = + "1.8254370818746402660437411213933955878019332885742187"; + + errno = 0; + volatile double d = strtod(str, NULL); + + ATF_CHECK(d == 0x1.d34fd8378ea83p+0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strtod_basic); + ATF_TP_ADD_TC(tp, strtod_hex); + ATF_TP_ADD_TC(tp, strtod_inf); + ATF_TP_ADD_TC(tp, strtof_inf); + ATF_TP_ADD_TC(tp, strtold_inf); + ATF_TP_ADD_TC(tp, strtod_nan); + ATF_TP_ADD_TC(tp, strtof_nan); + ATF_TP_ADD_TC(tp, strtold_nan); + ATF_TP_ADD_TC(tp, strtod_round); + ATF_TP_ADD_TC(tp, strtod_underflow); + ATF_TP_ADD_TC(tp, strtod_gherman_bug); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_strtoi.c b/contrib/netbsd-tests/lib/libc/stdlib/t_strtoi.c new file mode 100644 index 0000000..bf958a1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_strtoi.c @@ -0,0 +1,304 @@ +/* $NetBSD: t_strtoi.c,v 1.1 2015/05/01 14:17:56 christos Exp $ */ + +/*- + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Created by Kamil Rytarowski, vesed on ID: + * NetBSD: t_strtol.c,v 1.5 2011/06/14 02:45:58 jruoho Exp + */ + +#include +__RCSID("$NetBSD: t_strtoi.c,v 1.1 2015/05/01 14:17:56 christos Exp $"); + +#include +#include +#include +#include +#include +#include + +struct test { + const char *str; + intmax_t res; + int base; + const char *end; + intmax_t lo; + intmax_t hi; + int rstatus; +}; + +static void check(struct test *, intmax_t, char *, int); + +static void +check(struct test *t, intmax_t rv, char *end, int rstatus) +{ + + if (rv != t->res) + atf_tc_fail_nonfatal("strtoi(%s, &end, %d, %jd, %jd, &rstatus)" + " failed (rv = %jd)", t->str, t->base, t->lo, t->hi, rv); + + if (rstatus != t->rstatus) + atf_tc_fail_nonfatal("strtoi(%s, &end, %d, %jd, %jd, &rstatus)" + " failed (rstatus: %d ('%s'))", + t->str, t->base, t->lo, t->hi, rstatus, strerror(rstatus)); + + if ((t->end != NULL && strcmp(t->end, end) != 0) || + (t->end == NULL && *end != '\0')) + atf_tc_fail_nonfatal("invalid end pointer ('%s') from " + "strtoi(%s, &end, %d, %jd, %jd, &rstatus)", + end, t->str, t->base, t->lo, t->hi); +} + +ATF_TC(strtoi_base); +ATF_TC_HEAD(strtoi_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strtoi(3) with different bases"); +} + +ATF_TC_BODY(strtoi_base, tc) +{ + struct test t[] = { + { "123456789", 123456789, 0, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "111010110111100110100010101",123456789, 2, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "22121022020212200", 123456789, 3, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "13112330310111", 123456789, 4, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "223101104124", 123456789, 5, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "20130035113", 123456789, 6, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "3026236221", 123456789, 7, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "726746425", 123456789, 8, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "277266780", 123456789, 9, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "123456789", 123456789, 10, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "63762A05", 123456789, 11, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "35418A99", 123456789, 12, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "1C767471", 123456789, 13, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "12579781", 123456789, 14, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "AC89BC9", 123456789, 15, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "75BCD15", 123456789, 16, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "1234567", 342391, 8, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "01234567", 342391, 0, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "0123456789", 123456789, 10, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "0x75bcd15", 123456789, 0, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + }; + + intmax_t rv; + char *end; + int e; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + errno = 0; + rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e); + + if (errno != 0) + atf_tc_fail("strtoi(3) changed errno to %d ('%s')", + e, strerror(e)); + + check(&t[i], rv, end, e); + } +} + +ATF_TC(strtoi_case); +ATF_TC_HEAD(strtoi_case, tc) +{ + atf_tc_set_md_var(tc, "descr", "Case insensitivity with strtoi(3)"); +} + +ATF_TC_BODY(strtoi_case, tc) +{ + struct test t[] = { + { "abcd", 0xabcd, 16, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { " dcba", 0xdcba, 16, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "abcd dcba", 0xabcd, 16, " dcba", + INTMAX_MIN, INTMAX_MAX, ENOTSUP }, + { "abc0x123", 0xabc0, 16, "x123", + INTMAX_MIN, INTMAX_MAX, ENOTSUP }, + { "abcd\0x123", 0xabcd, 16, "\0x123", + INTMAX_MIN, INTMAX_MAX, 0 }, + { "ABCD", 0xabcd, 16, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "aBcD", 0xabcd, 16, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "0xABCD", 0xabcd, 16, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "0xABCDX", 0xabcd, 16, "X", + INTMAX_MIN, INTMAX_MAX, ENOTSUP}, + }; + + intmax_t rv; + char *end; + int e; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + errno = 0; + rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e); + + if (errno != 0) + atf_tc_fail("strtoi(3) changed errno to %d ('%s')", + e, strerror(e)); + + check(&t[i], rv, end, e); + } +} + +ATF_TC(strtoi_range); +ATF_TC_HEAD(strtoi_range, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ERANGE from strtoi(3)"); +} + +ATF_TC_BODY(strtoi_range, tc) +{ + struct test t[] = { +#if INTMAX_MAX == 0x7fffffffffffffff + { "1000000000000000000000", INTMAX_MAX, 8, NULL, + INTMAX_MIN, INTMAX_MAX, ERANGE }, + { "9223372036854775808", INTMAX_MAX, 10, NULL, + INTMAX_MIN, INTMAX_MAX, ERANGE }, + { "8000000000000000", INTMAX_MAX, 16, NULL, + INTMAX_MIN, INTMAX_MAX, ERANGE }, +#else +#error extend this test to your platform! +#endif + { "10", 1, 10, NULL, + -1, 1, ERANGE }, + { "10", 11, 10, NULL, + 11, 20, ERANGE }, + }; + + intmax_t rv; + char *end; + int e; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + errno = 0; + rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e); + + if (errno != 0) + atf_tc_fail("strtoi(3) changed errno to %d ('%s')", + e, strerror(e)); + + check(&t[i], rv, end, e); + } +} + +ATF_TC(strtoi_signed); +ATF_TC_HEAD(strtoi_signed, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strtoi(3)"); +} + +ATF_TC_BODY(strtoi_signed, tc) +{ + struct test t[] = { + { "1", 1, 0, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { " 2", 2, 0, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { " 3", 3, 0, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { " -3", -3, 0, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "--1", 0, 0, "--1", + INTMAX_MIN, INTMAX_MAX, ECANCELED }, + { "+-2", 0, 0, "+-2", + INTMAX_MIN, INTMAX_MAX, ECANCELED }, + { "++3", 0, 0, "++3", + INTMAX_MIN, INTMAX_MAX, ECANCELED }, + { "+9", 9, 0, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "+123", 123, 0, NULL, + INTMAX_MIN, INTMAX_MAX, 0 }, + { "-1 3", -1, 0, " 3", + INTMAX_MIN, INTMAX_MAX, ENOTSUP }, + { "-1.3", -1, 0, ".3", + INTMAX_MIN, INTMAX_MAX, ENOTSUP }, + { "- 3", 0, 0, "- 3", + INTMAX_MIN, INTMAX_MAX, ECANCELED }, + { "+33.", 33, 0, ".", + INTMAX_MIN, INTMAX_MAX, ENOTSUP }, + { "30x0", 30, 0, "x0", + INTMAX_MIN, INTMAX_MAX, ENOTSUP }, + }; + + intmax_t rv; + char *end; + int e; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + errno = 0; + rv = strtoi(t[i].str, &end, t[i].base, t[i].lo, t[i].hi, &e); + + if (errno != 0) + atf_tc_fail("strtoi(3) changed errno to %d ('%s')", + e, strerror(e)); + + check(&t[i], rv, end, e); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strtoi_base); + ATF_TP_ADD_TC(tp, strtoi_case); + ATF_TP_ADD_TC(tp, strtoi_range); + ATF_TP_ADD_TC(tp, strtoi_signed); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c b/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c new file mode 100644 index 0000000..54e1907 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c @@ -0,0 +1,235 @@ +/* $NetBSD: t_strtol.c,v 1.6 2016/06/01 01:12:02 pgoyette Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_strtol.c,v 1.6 2016/06/01 01:12:02 pgoyette Exp $"); + +#include +#include +#include +#include +#include + +struct test { + const char *str; + int64_t res; + int base; + const char *end; +}; + +static void check(struct test *, long int, long long int, char *); + +static void +check(struct test *t, long int li, long long int lli, char *end) +{ + + if (li != -1 && li != t->res) + atf_tc_fail_nonfatal("strtol(%s, &end, %d) failed " + "(rv = %ld)", t->str, t->base, li); + + if (lli != -1 && lli != t->res) + atf_tc_fail_nonfatal("strtoll(%s, NULL, %d) failed " + "(rv = %lld)", t->str, t->base, lli); + + if ((t->end != NULL && strcmp(t->end, end) != 0) || + (t->end == NULL && *end != '\0')) + atf_tc_fail_nonfatal("invalid end pointer ('%s') from " + "strtol(%s, &end, %d)", end, t->str, t->base); +} + +ATF_TC(strtol_base); +ATF_TC_HEAD(strtol_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strtol(3) with different bases"); +} + +ATF_TC_BODY(strtol_base, tc) +{ + struct test t[] = { + { "123456789", 123456789, 0, NULL }, + { "111010110111100110100010101", 123456789, 2, NULL }, + { "22121022020212200", 123456789, 3, NULL }, + { "13112330310111", 123456789, 4, NULL }, + { "223101104124", 123456789, 5, NULL }, + { "20130035113", 123456789, 6, NULL }, + { "3026236221", 123456789, 7, NULL }, + { "726746425", 123456789, 8, NULL }, + { "277266780", 123456789, 9, NULL }, + { "123456789", 123456789, 10, NULL }, + { "63762A05", 123456789, 11, NULL }, + { "35418A99", 123456789, 12, NULL }, + { "1C767471", 123456789, 13, NULL }, + { "12579781", 123456789, 14, NULL }, + { "AC89BC9", 123456789, 15, NULL }, + { "75BCD15", 123456789, 16, NULL }, + { "1234567", 342391, 8, NULL }, + { "01234567", 342391, 0, NULL }, + { "0123456789", 123456789, 10, NULL }, + { "0x75bcd15", 123456789, 0, NULL }, + }; + + long long int lli; + long int li; + char *end; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + li = strtol(t[i].str, &end, t[i].base); + lli = strtoll(t[i].str, NULL, t[i].base); + + check(&t[i], li, lli, end); + } +} + +ATF_TC(strtol_case); +ATF_TC_HEAD(strtol_case, tc) +{ + atf_tc_set_md_var(tc, "descr", "Case insensitivity with strtol(3)"); +} + +ATF_TC_BODY(strtol_case, tc) +{ + struct test t[] = { + { "abcd", 0xabcd, 16, NULL }, + { " dcba", 0xdcba, 16, NULL }, + { "abcd dcba", 0xabcd, 16, " dcba" }, + { "abc0x123", 0xabc0, 16, "x123" }, + { "abcd\0x123", 0xabcd, 16, "\0x123" }, + { "ABCD", 0xabcd, 16, NULL }, + { "aBcD", 0xabcd, 16, NULL }, + { "0xABCD", 0xabcd, 16, NULL }, + { "0xABCDX", 0xabcd, 16, "X" }, + }; + + long long int lli; + long int li; + char *end; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + li = strtol(t[i].str, &end, t[i].base); + lli = strtoll(t[i].str, NULL, t[i].base); + + check(&t[i], li, lli, end); + } +} + +ATF_TC(strtol_range); +ATF_TC_HEAD(strtol_range, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ERANGE from strtol(3)"); +} + +ATF_TC_BODY(strtol_range, tc) +{ + +#if LONG_MAX == 0x7fffffff /* XXX: Is this portable? */ + + struct test t[] = { + { "20000000000", 2147483647, 8, NULL }, + { "2147483648", 2147483647, 10, NULL }, + { "80000000", 2147483647, 16, NULL }, + }; +#else + struct test t[] = { + { "1000000000000000000000", 9223372036854775807, 8, NULL }, + { "9223372036854775808", 9223372036854775807, 10, NULL }, + { "8000000000000000", 9223372036854775807, 16, NULL }, + }; +#endif + + long int li; + char *end; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + errno = 0; + li = strtol(t[i].str, &end, t[i].base); + + if (errno != ERANGE) + atf_tc_fail("strtol(3) did not catch ERANGE"); + + check(&t[i], li, -1, end); + } +} + +ATF_TC(strtol_signed); +ATF_TC_HEAD(strtol_signed, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strtol(3)"); +} + +ATF_TC_BODY(strtol_signed, tc) +{ + struct test t[] = { + { "1", 1, 0, NULL }, + { " 2", 2, 0, NULL }, + { " 3", 3, 0, NULL }, + { " -3", -3, 0, NULL }, + { "--1", 0, 0, "--1" }, + { "+-2", 0, 0, "+-2" }, + { "++3", 0, 0, "++3" }, + { "+9", 9, 0, NULL }, + { "+123", 123, 0, NULL }, + { "-1 3", -1, 0, " 3" }, + { "-1.3", -1, 0, ".3" }, + { "- 3", 0, 0, "- 3" }, + { "+33.", 33, 0, "." }, + { "30x0", 30, 0, "x0" }, + }; + + long long int lli; + long int li; + char *end; + size_t i; + + for (i = 0; i < __arraycount(t); i++) { + + li = strtol(t[i].str, &end, t[i].base); + lli = strtoll(t[i].str, NULL, t[i].base); + + check(&t[i], li, lli, end); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strtol_base); + ATF_TP_ADD_TC(tp, strtol_case); + ATF_TP_ADD_TC(tp, strtol_range); + ATF_TP_ADD_TC(tp, strtol_signed); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_system.c b/contrib/netbsd-tests/lib/libc/stdlib/t_system.c new file mode 100644 index 0000000..235005b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_system.c @@ -0,0 +1,83 @@ +/* $NetBSD: t_system.c,v 1.1 2011/09/11 10:32:23 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_system.c,v 1.1 2011/09/11 10:32:23 jruoho Exp $"); + +#include +#include +#include +#include +#include + +static const char *path = "system"; + +ATF_TC_WITH_CLEANUP(system_basic); +ATF_TC_HEAD(system_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of system(3)"); +} + +ATF_TC_BODY(system_basic, tc) +{ + char buf[23]; + int fd, i = 2; + + ATF_REQUIRE(system("/bin/echo -n > system") == 0); + + while (i >= 0) { + ATF_REQUIRE(system("/bin/echo -n garbage >> system") == 0); + i--; + } + + fd = open(path, O_RDONLY); + ATF_REQUIRE(fd >= 0); + + (void)memset(buf, '\0', sizeof(buf)); + + ATF_REQUIRE(read(fd, buf, 21) == 21); + ATF_REQUIRE(strcmp(buf, "garbagegarbagegarbage") == 0); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(system_basic, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, system_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_bm.c b/contrib/netbsd-tests/lib/libc/string/t_bm.c new file mode 100644 index 0000000..5ec4022 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_bm.c @@ -0,0 +1,102 @@ +/* $Id: t_bm.c,v 1.1 2014/06/23 10:53:20 shm Exp $ */ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Mateusz Kocielski. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$Id: t_bm.c,v 1.1 2014/06/23 10:53:20 shm Exp $"); + +#include +#include +#include +#include +#include +#include + +ATF_TC(bm); +ATF_TC_HEAD(bm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bm(3)"); +} + +typedef struct { + const char *pattern; + const char *text; + const char *freq; + ssize_t match; +} t_testcase; + +const t_testcase testcases[] = { + {"test", "test", NULL, 0}, + {"test", "ttest", NULL, 1}, + {"test", "tes", NULL, -1}, + {"test", "testtesttest", NULL, 0}, + {"test", "testtesttesttesttesttest", NULL, 0}, + {"test", "------------------------", NULL, -1}, + {"a", "a", NULL, 0}, + {"a", "ba", NULL, 1}, + {"a", "bba", NULL, 2}, + {"bla", "bl", NULL, -1}, + {"a", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", NULL, -1}, + {"test", "qfwiofjqeiwofjioqewfjeiqwjfiqewjfioqewfjioewqjfioewqjfioewqjoi", + NULL, -1}, + {"needle", "haystack", NULL, -1}, + {"netbsd", "freebsd netbsd openbsd", NULL, 8}, +}; + +ATF_TC_BODY(bm, tc) +{ + size_t ts; + u_char *off; + char *text; + bm_pat *pattern; + + for (ts = 0; ts < sizeof(testcases)/sizeof(t_testcase); ts++) { + ATF_CHECK(pattern = bm_comp((const u_char *)testcases[ts].pattern, + strlen(testcases[ts].pattern), (const u_char *)testcases[ts].freq)); + + ATF_REQUIRE(text = strdup(testcases[ts].text)); + off = bm_exec(pattern, (u_char *)text, strlen(text)); + + if (testcases[ts].match == -1) + ATF_CHECK_EQ(off, NULL); + else + ATF_CHECK_EQ(testcases[ts].match, + (off-(u_char *)text)); + + bm_free(pattern); + free(text); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, bm); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_memchr.c b/contrib/netbsd-tests/lib/libc/string/t_memchr.c new file mode 100644 index 0000000..296f1f8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_memchr.c @@ -0,0 +1,194 @@ +/* $NetBSD: t_memchr.c,v 1.3 2012/04/06 07:53:10 jruoho Exp $ */ + +/* + * Written by J.T. Conklin + * Public domain. + */ + +#include +#include +#include +#include +#include + +ATF_TC(memchr_basic); +ATF_TC_HEAD(memchr_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memchr(3) results, #1"); +} + +ATF_TC_BODY(memchr_basic, tc) +{ + /* try to trick the compiler */ + void * (*f)(const void *, int, size_t) = memchr; + + unsigned int a, t; + void *off, *off2; + char buf[32]; + + struct tab { + const char *val; + size_t len; + char match; + ssize_t off; + }; + + const struct tab tab[] = { + { "", 0, 0, 0 }, + + { "/", 0, 0, 0 }, + { "/", 1, 1, 0 }, + { "/a", 2, 1, 0 }, + { "/ab", 3, 1, 0 }, + { "/abc", 4, 1, 0 }, + { "/abcd", 5, 1, 0 }, + { "/abcde", 6, 1, 0 }, + { "/abcdef", 7, 1, 0 }, + { "/abcdefg", 8, 1, 0 }, + + { "a/", 1, 0, 0 }, + { "a/", 2, 1, 1 }, + { "a/b", 3, 1, 1 }, + { "a/bc", 4, 1, 1 }, + { "a/bcd", 5, 1, 1 }, + { "a/bcde", 6, 1, 1 }, + { "a/bcdef", 7, 1, 1 }, + { "a/bcdefg", 8, 1, 1 }, + + { "ab/", 2, 0, 0 }, + { "ab/", 3, 1, 2 }, + { "ab/c", 4, 1, 2 }, + { "ab/cd", 5, 1, 2 }, + { "ab/cde", 6, 1, 2 }, + { "ab/cdef", 7, 1, 2 }, + { "ab/cdefg", 8, 1, 2 }, + + { "abc/", 3, 0, 0 }, + { "abc/", 4, 1, 3 }, + { "abc/d", 5, 1, 3 }, + { "abc/de", 6, 1, 3 }, + { "abc/def", 7, 1, 3 }, + { "abc/defg", 8, 1, 3 }, + + { "abcd/", 4, 0, 0 }, + { "abcd/", 5, 1, 4 }, + { "abcd/e", 6, 1, 4 }, + { "abcd/ef", 7, 1, 4 }, + { "abcd/efg", 8, 1, 4 }, + + { "abcde/", 5, 0, 0 }, + { "abcde/", 6, 1, 5 }, + { "abcde/f", 7, 1, 5 }, + { "abcde/fg", 8, 1, 5 }, + + { "abcdef/", 6, 0, 0 }, + { "abcdef/", 7, 1, 6 }, + { "abcdef/g", 8, 1, 6 }, + + { "abcdefg/", 7, 0, 0 }, + { "abcdefg/", 8, 1, 7 }, + + { "\xff\xff\xff\xff" "efg/", 8, 1, 7 }, + { "a" "\xff\xff\xff\xff" "fg/", 8, 1, 7 }, + { "ab" "\xff\xff\xff\xff" "g/", 8, 1, 7 }, + { "abc" "\xff\xff\xff\xff" "/", 8, 1, 7 }, + }; + + for (a = 1; a < 1 + sizeof(long); ++a) { + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + buf[a-1] = '/'; + strcpy(&buf[a], tab[t].val); + + off = f(&buf[a], '/', tab[t].len); + if (tab[t].match == 0) { + if (off != 0) { + fprintf(stderr, "a = %d, t = %d\n", + a, t); + atf_tc_fail("should not have found " + " char past len"); + } + } else if (tab[t].match == 1) { + if (tab[t].off != ((char*)off - &buf[a])) { + fprintf(stderr, "a = %d, t = %d\n", + a, t); + atf_tc_fail("char not found at " + "correct offset"); + } + } else { + fprintf(stderr, "a = %d, t = %d\n", a, t); + atf_tc_fail("Corrupt test case data"); + } + + /* check zero extension of char arg */ + off2 = f(&buf[a], 0xffffff00 | '/', tab[t].len); + if (off2 != off) + atf_tc_fail("zero extension of char arg " + "failed"); + } + } +} + +ATF_TC(memchr_simple); +ATF_TC_HEAD(memchr_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memchr(3) results, #2"); +} + +ATF_TC_BODY(memchr_simple, tc) +{ + char buf[] = "abcdefg"; + short i = 7; + + ATF_CHECK(memchr(buf, 'a', 0) == NULL); + ATF_CHECK(memchr(buf, 'g', 0) == NULL); + ATF_CHECK(memchr(buf, 'x', 7) == NULL); + + ATF_CHECK(memchr("\0", 'x', 0) == NULL); + ATF_CHECK(memchr("\0", 'x', 1) == NULL); + + while (i <= 14) { + + ATF_CHECK(memchr(buf, 'a', i) == buf + 0); + ATF_CHECK(memchr(buf, 'b', i) == buf + 1); + ATF_CHECK(memchr(buf, 'c', i) == buf + 2); + ATF_CHECK(memchr(buf, 'd', i) == buf + 3); + ATF_CHECK(memchr(buf, 'e', i) == buf + 4); + ATF_CHECK(memchr(buf, 'f', i) == buf + 5); + ATF_CHECK(memchr(buf, 'g', i) == buf + 6); + + i *= 2; + } +} + +ATF_TC(memrchr_simple); +ATF_TC_HEAD(memrchr_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memrchr(3) results"); +} + +ATF_TC_BODY(memrchr_simple, tc) +{ + char buf[] = "abcdabcd"; + + ATF_CHECK(memrchr(buf, 'a', 0) == NULL); + ATF_CHECK(memrchr(buf, 'g', 0) == NULL); + ATF_CHECK(memrchr(buf, 'x', 8) == NULL); + + ATF_CHECK(memrchr("\0", 'x', 0) == NULL); + ATF_CHECK(memrchr("\0", 'x', 1) == NULL); + + ATF_CHECK(memrchr(buf, 'a', 8) == buf + 4); + ATF_CHECK(memrchr(buf, 'b', 8) == buf + 5); + ATF_CHECK(memrchr(buf, 'c', 8) == buf + 6); + ATF_CHECK(memrchr(buf, 'd', 8) == buf + 7); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, memchr_basic); + ATF_TP_ADD_TC(tp, memchr_simple); + ATF_TP_ADD_TC(tp, memrchr_simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_memcpy.c b/contrib/netbsd-tests/lib/libc/string/t_memcpy.c new file mode 100644 index 0000000..64cdb29 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_memcpy.c @@ -0,0 +1,163 @@ +/* $NetBSD: t_memcpy.c,v 1.6 2017/01/11 18:05:54 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include +#include +#include + +#include + +#define ALIGNMENTS 16 +#define LENGTHS 4 +#define BLOCKTYPES 4 + +MD5_CTX mc[1]; + +typedef unsigned char testBlock_t[ALIGNMENTS * LENGTHS]; + +testBlock_t bss1, bss2; + +unsigned char *start[BLOCKTYPES] = { + bss1, bss2 +}; + +char result[100]; +#ifdef __NetBSD__ +const char goodResult[] = "7b405d24bc03195474c70ddae9e1f8fb"; +#else +const char goodResult[] = "5ab4443f0e3e058d94087d9f2a11ef5e"; +#endif + +static void +runTest(unsigned char *b1, unsigned char *b2) +{ + int i, j, k, m; + size_t n; + + for (i = 0; i < ALIGNMENTS; ++i) { + for (j = 0; j < ALIGNMENTS; ++j) { + k = sizeof(testBlock_t) - (i > j ? i : j); + for (m = 0; m < k; ++m) { + for (n = 0; n < sizeof(testBlock_t); ++n) { + b1[n] = (unsigned char)random(); + b2[n] = (unsigned char)random(); + } + memcpy(b1 + i, b2 + j, m); + MD5Update(mc, b1, sizeof(testBlock_t)); + MD5Update(mc, b2, sizeof(testBlock_t)); + } + } + } +} + +ATF_TC(memcpy_basic); +ATF_TC_HEAD(memcpy_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memcpy results"); +} + +ATF_TC_BODY(memcpy_basic, tc) +{ + int i, j; + testBlock_t auto1, auto2; + + start[2] = auto1; + start[3] = auto2; + +#ifdef __NetBSD__ + srandom(0L); +#else + /* + * random() shall produce by default a sequence of numbers that can be + * duplicated by calling srandom() with 1 as the seed. + */ + srandom(1); +#endif + MD5Init(mc); + for (i = 0; i < BLOCKTYPES; ++i) + for (j = 0; j < BLOCKTYPES; ++j) + if (i != j) + runTest(start[i], start[j]); + MD5End(mc, result); + ATF_REQUIRE_EQ_MSG(strcmp(result, goodResult), 0, "%s != %s", + result, goodResult); +} + +ATF_TC(memccpy_simple); +ATF_TC_HEAD(memccpy_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memccpy(3) results"); +} + +ATF_TC_BODY(memccpy_simple, tc) +{ + char buf[100]; + char c = ' '; + + (void)memset(buf, c, sizeof(buf)); + + ATF_CHECK(memccpy(buf, "foo bar", c, sizeof(buf)) != NULL); + ATF_CHECK(buf[4] == c); + + ATF_CHECK(memccpy(buf, "foo bar", '\0', sizeof(buf) - 1) != NULL); + ATF_CHECK(buf[8] == c); + + ATF_CHECK(memccpy(buf, "foo bar", 'x', 7) == NULL); + ATF_CHECK(strncmp(buf, "foo bar", 7) == 0); + + ATF_CHECK(memccpy(buf, "xxxxxxx", 'r', 7) == NULL); + ATF_CHECK(strncmp(buf, "xxxxxxx", 7) == 0); +} + +ATF_TC(memcpy_return); +ATF_TC_HEAD(memcpy_return, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memcpy(3) return value"); +} + +ATF_TC_BODY(memcpy_return, tc) +{ + char *b = (char *)0x1; + char c[2]; + ATF_REQUIRE_EQ(memcpy(b, b, 0), b); + ATF_REQUIRE_EQ(memcpy(c, "ab", sizeof(c)), c); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, memcpy_basic); + ATF_TP_ADD_TC(tp, memcpy_return); + ATF_TP_ADD_TC(tp, memccpy_simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_memmem.c b/contrib/netbsd-tests/lib/libc/string/t_memmem.c new file mode 100644 index 0000000..2f37788 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_memmem.c @@ -0,0 +1,105 @@ +/* $NetBSD: t_memmem.c,v 1.3 2017/01/11 18:07:37 christos Exp $ */ + +/*- + * Copyright (c) 2005 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Perry E. Metzger of Metzger, Dowdeswell & Co. LLC. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include + +char p0[] = ""; +int lp0 = 0; +char p1[] = "0123"; +int lp1 = 4; +char p2[] = "456"; +int lp2 = 3; +char p3[] = "789"; +int lp3 = 3; +char p4[] = "abc"; +int lp4 = 3; +char p5[] = "0"; +int lp5 = 1; +char p6[] = "9"; +int lp6 = 1; +char p7[] = "654"; +int lp7 = 3; + +char b0[] = ""; +int lb0 = 0; +char b1[] = "0"; +int lb1 = 1; +char b2[] = "0123456789"; +int lb2 = 10; + +#define expect(b) \ + if (!(b)) { \ + fprintf(stderr, "failed on line %d\n", __LINE__); \ + atf_tc_fail("Check stderr for test id/line"); \ + } + +ATF_TC(memmem_basic); +ATF_TC_HEAD(memmem_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test memmem results"); +} + +ATF_TC_BODY(memmem_basic, tc) +{ + +#if defined(__darwin__) + expect(memmem(b2, lb2, p0, lp0) == NULL); + expect(memmem(b0, lb0, p0, lp0) == NULL); +#else + expect(memmem(b2, lb2, p0, lp0) == b2); + expect(memmem(b0, lb0, p0, lp0) == b0); +#endif + expect(memmem(b0, lb0, p1, lp1) == NULL); + expect(memmem(b1, lb1, p1, lp1) == NULL); + + expect(memmem(b2, lb2, p1, lp1) == b2); + expect(memmem(b2, lb2, p2, lp2) == (b2 + 4)); + expect(memmem(b2, lb2, p3, lp3) == (b2 + 7)); + + expect(memmem(b2, lb2, p5, lp5) == b2); + expect(memmem(b2, lb2, p6, lp6) == (b2 + 9)); + + expect(memmem(b2, lb2, p4, lp4) == NULL); + expect(memmem(b2, lb2, p7, lp7) == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, memmem_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_memset.c b/contrib/netbsd-tests/lib/libc/string/t_memset.c new file mode 100644 index 0000000..5a2be28 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_memset.c @@ -0,0 +1,255 @@ +/* $NetBSD: t_memset.c,v 1.4 2015/09/11 09:25:52 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_memset.c,v 1.4 2015/09/11 09:25:52 martin Exp $"); + +#include + +#include +#include +#include +#include + +static long page = 0; +static void fill(char *, size_t, char); +static bool check(char *, size_t, char); + +int zero; /* always zero, but the compiler does not know */ + +ATF_TC(memset_array); +ATF_TC_HEAD(memset_array, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) with arrays"); +} + +ATF_TC_BODY(memset_array, tc) +{ + char buf[1024]; + + (void)memset(buf, 0, sizeof(buf)); + + if (check(buf, sizeof(buf), 0) != true) + atf_tc_fail("memset(3) did not fill a static buffer"); + + (void)memset(buf, 'x', sizeof(buf)); + + if (check(buf, sizeof(buf), 'x') != true) + atf_tc_fail("memset(3) did not fill a static buffer"); +} + +ATF_TC(memset_return); +ATF_TC_HEAD(memset_return, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) return value"); +} + +ATF_TC_BODY(memset_return, tc) +{ + char *b = (char *)0x1; + char c[2]; + ATF_REQUIRE_EQ(memset(b, 0, 0), b); + ATF_REQUIRE_EQ(memset(c, 2, sizeof(c)), c); +} + +ATF_TC(memset_basic); +ATF_TC_HEAD(memset_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of memset(3)"); +} + +ATF_TC_BODY(memset_basic, tc) +{ + char *buf, *ret; + + buf = malloc(page); + ret = malloc(page); + + ATF_REQUIRE(buf != NULL); + ATF_REQUIRE(ret != NULL); + + fill(ret, page, 0); + memset(buf, 0, page); + + ATF_REQUIRE(memcmp(ret, buf, page) == 0); + + fill(ret, page, 'x'); + memset(buf, 'x', page); + + ATF_REQUIRE(memcmp(ret, buf, page) == 0); + + free(buf); + free(ret); +} + +ATF_TC(memset_nonzero); +ATF_TC_HEAD(memset_nonzero, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) with non-zero params"); +} + +ATF_TC_BODY(memset_nonzero, tc) +{ + const size_t n = 0x7f; + char *buf; + size_t i; + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + for (i = 0x21; i < n; i++) { + + (void)memset(buf, i, page); + + if (check(buf, page, i) != true) + atf_tc_fail("memset(3) did not fill properly"); + } + + free(buf); +} + +ATF_TC(memset_zero_size); + +ATF_TC_HEAD(memset_zero_size, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) with zero size"); +} + +ATF_TC_BODY(memset_zero_size, tc) +{ + char buf[1024]; + + (void)memset(buf, 'x', sizeof(buf)); + + if (check(buf, sizeof(buf), 'x') != true) + atf_tc_fail("memset(3) did not fill a static buffer"); + + (void)memset(buf+sizeof(buf)/2, 0, zero); + + if (check(buf, sizeof(buf), 'x') != true) + atf_tc_fail("memset(3) with 0 size did change the buffer"); +} + +ATF_TC(bzero_zero_size); + +ATF_TC_HEAD(bzero_zero_size, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bzero(3) with zero size"); +} + +ATF_TC_BODY(bzero_zero_size, tc) +{ + char buf[1024]; + + (void)memset(buf, 'x', sizeof(buf)); + + if (check(buf, sizeof(buf), 'x') != true) + atf_tc_fail("memset(3) did not fill a static buffer"); + + (void)bzero(buf+sizeof(buf)/2, zero); + + if (check(buf, sizeof(buf), 'x') != true) + atf_tc_fail("bzero(3) with 0 size did change the buffer"); +} + +ATF_TC(memset_struct); +ATF_TC_HEAD(memset_struct, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test memset(3) with a structure"); +} + +ATF_TC_BODY(memset_struct, tc) +{ + struct stat st; + + st.st_dev = 0; + st.st_ino = 1; + st.st_mode = 2; + st.st_nlink = 3; + st.st_uid = 4; + st.st_gid = 5; + st.st_rdev = 6; + st.st_size = 7; + st.st_atime = 8; + st.st_mtime = 9; + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_CHECK(st.st_dev == 0); + ATF_CHECK(st.st_ino == 0); + ATF_CHECK(st.st_mode == 0); + ATF_CHECK(st.st_nlink == 0); + ATF_CHECK(st.st_uid == 0); + ATF_CHECK(st.st_gid == 0); + ATF_CHECK(st.st_rdev == 0); + ATF_CHECK(st.st_size == 0); + ATF_CHECK(st.st_atime == 0); + ATF_CHECK(st.st_mtime == 0); +} + +static void +fill(char *buf, size_t len, char x) +{ + size_t i; + + for (i = 0; i < len; i++) + buf[i] = x; +} + +static bool +check(char *buf, size_t len, char x) +{ + size_t i; + + for (i = 0; i < len; i++) { + + if (buf[i] != x) + return false; + } + + return true; +} + +ATF_TP_ADD_TCS(tp) +{ + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, memset_array); + ATF_TP_ADD_TC(tp, memset_basic); + ATF_TP_ADD_TC(tp, memset_nonzero); + ATF_TP_ADD_TC(tp, memset_struct); + ATF_TP_ADD_TC(tp, memset_return); + ATF_TP_ADD_TC(tp, memset_zero_size); + ATF_TP_ADD_TC(tp, bzero_zero_size); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_popcount.c b/contrib/netbsd-tests/lib/libc/string/t_popcount.c new file mode 100644 index 0000000..2bae52f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_popcount.c @@ -0,0 +1,198 @@ +/* $NetBSD: t_popcount.c,v 1.4 2011/07/07 08:27:36 jruoho Exp $ */ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_popcount.c,v 1.4 2011/07/07 08:27:36 jruoho Exp $"); + +#include +#include + +static unsigned int byte_count[256]; + +static void +popcount_init(const char *cfg_var) +{ + unsigned int i, j; + + if (strcasecmp(cfg_var, "YES") == 0 || + strcasecmp(cfg_var, "Y") == 0 || + strcasecmp(cfg_var, "1") == 0 || + strcasecmp(cfg_var, "T") == 0 || + strcasecmp(cfg_var, "TRUE") == 0) { + for (i = 0; i < 256; ++i) { + byte_count[i] = 0; + for (j = i; j != 0; j >>= 1) { + if (j & 1) + ++byte_count[i]; + } + } + return; + } + + atf_tc_skip("config variable \"run_popcount\" not set to YES/TRUE"); +} + +unsigned int test_parts[256] = { + 0x318e53e6U, 0x11710316U, 0x62608ffaU, 0x67e0f562U, + 0xe432e82cU, 0x9862e8b2U, 0x7d96a627U, 0x3f74ad31U, + 0x3cecf906U, 0xcdc0dcb4U, 0x241dab64U, 0x31e6133eU, + 0x23086ad4U, 0x721d5a91U, 0xc483da53U, 0x6a62af52U, + 0xf3f5c386U, 0xe0de3f77U, 0x65afe528U, 0xf4816485U, + 0x40ccbf08U, 0x25df49c1U, 0xae5a6ee0U, 0xab36ccadU, + 0x87e1ec29U, 0x60ca2407U, 0x49d62e47U, 0xa09f2df5U, + 0xaf4c1c68U, 0x8ef08d50U, 0x624cfd2fU, 0xa6a36f20U, + 0x68aaf879U, 0x0fe9deabU, 0x5c9a4060U, 0x215d8f08U, + 0x55e84712U, 0xea1f1681U, 0x3a10b8a1U, 0x08e06632U, + 0xcbc875e2U, 0x31e53258U, 0xcd3807a4U, 0xb9d17516U, + 0x8fbfd9abU, 0x6651b555U, 0x550fb381U, 0x05061b9dU, + 0x35aef3f2U, 0x9175078cU, 0xae0f14daU, 0x92a2d5f8U, + 0x70d968feU, 0xe86f41c5U, 0x5cfaf39fU, 0x8499b18dU, + 0xb33f879aU, 0x0a68ad3dU, 0x9323ecc1U, 0x060037ddU, + 0xb91a5051U, 0xa0dbebf6U, 0x3e6aa6f1U, 0x7b422b5bU, + 0x599e811eU, 0x199f7594U, 0xca453365U, 0x1cda6f48U, + 0xe9c75d2cU, 0x6a873217U, 0x79c45d72U, 0x143b8e37U, + 0xa11df26eU, 0xaf31f80aU, 0x311bf759U, 0x2378563cU, + 0x9ab95fa5U, 0xfcf4d47cU, 0x1f7db268U, 0xd64b09e1U, + 0xad7936daU, 0x7a59005cU, 0x45b173d3U, 0xc1a71b32U, + 0x7d9f0de2U, 0xa9ac3792U, 0x9e7f9966U, 0x7f0b8080U, + 0xece6c06fU, 0x78d92a3cU, 0x6d5f8f6cU, 0xc50ca544U, + 0x5d8ded27U, 0xd27a8462U, 0x4bcd13ccU, 0xd49075f2U, + 0xa8d52acfU, 0x41915d97U, 0x564f7062U, 0xefb046e2U, + 0xe296277aU, 0x605b0ea3U, 0x10b2c3a1U, 0x4e8e5c66U, + 0x4bd8ec04U, 0x29935be9U, 0x381839f3U, 0x555d8824U, + 0xd6befddbU, 0x5d8d6d6eU, 0xb2fdb7b4U, 0xb471c8fcU, + 0xc2fd325bU, 0x932d2487U, 0xbdbbadefU, 0x66c8895dU, + 0x5d77857aU, 0x259f1cc0U, 0x302037faU, 0xda9aa7a8U, + 0xb112c6aaU, 0x78f74192U, 0xfd4da741U, 0xfa5765c1U, + 0x6ea1bc5cU, 0xd283f39cU, 0x268ae67dU, 0xdedcd134U, + 0xbbf92410U, 0x6b45fb55U, 0x2f75ac71U, 0x64bf2ca5U, + 0x8b99675aU, 0x3f4923b6U, 0x7e610550U, 0x04b1c06dU, + 0x8f92e7c6U, 0x45cb608bU, 0x2d06d1f2U, 0x79cf387aU, + 0xfd3ed225U, 0x243eee20U, 0x2cbefc6fU, 0x8286cbaaU, + 0x70d4c182U, 0x054e3cc6U, 0xb66c5362U, 0x0c73fa5dU, + 0x539948feU, 0xec638563U, 0x0cf04ab6U, 0xec7b52f4U, + 0x58eeffceU, 0x6fe8049aU, 0xb3b33332U, 0x2e33bfdbU, + 0xcc817567U, 0x71ac57c8U, 0x4bab3ac7U, 0x327c558bU, + 0x82a6d279U, 0x5adf71daU, 0x1074a656U, 0x3c533c1fU, + 0x82fdbe69U, 0x21b4f6afU, 0xd59580e8U, 0x0de824ebU, + 0xa510941bU, 0x7cd91144U, 0xa8c10631U, 0x4c839267U, + 0x5d503c2fU, 0xe1567d55U, 0x23910cc7U, 0xdb1bdc34U, + 0x2a866704U, 0x33e21f0cU, 0x5c7681b4U, 0x818651caU, + 0xb1d18162U, 0x225ad014U, 0xadf7d6baU, 0xac548d9bU, + 0xe94736e5U, 0x2279c5f1U, 0x33215d2cU, 0xdc8ab90eU, + 0xf5e3d7f2U, 0xedcb15cfU, 0xc9a43c4cU, 0xfc678fc6U, + 0x43796b95U, 0x3f8b700cU, 0x867bbc72U, 0x81f71fecU, + 0xd00cad7dU, 0x302c458fU, 0x8ae21accU, 0x05850ce8U, + 0x7764d8e8U, 0x8a36cd68U, 0x40b44bd7U, 0x1cffaeb7U, + 0x2b248f34U, 0x1eefdbafU, 0x574d7437U, 0xe86cd935U, + 0xf53dd1c8U, 0x1b022513U, 0xef2d249bU, 0x94fb2b08U, + 0x15d3eff8U, 0x14245e1bU, 0x82aa8425U, 0x53959028U, + 0x9c5f9b80U, 0x325e0c82U, 0x3e236c24U, 0x74e1dd36U, + 0x9890df3fU, 0xaf9701a2U, 0x023b3413U, 0x7634c67eU, + 0x55cf5e45U, 0x56d2a95bU, 0xb6db869bU, 0xac19e260U, + 0xdd310740U, 0x26d68f84U, 0x45bebf17U, 0xe4a7728fU, + 0xf082e66eU, 0xb2fe3c10U, 0x2db1fa2cU, 0x4b3dfcfaU, + 0xc7b3a672U, 0xaeadc67bU, 0x6cce6f2bU, 0x8263dbbfU, + 0xd9724d5bU, 0xbcc767b5U, 0x8d563798U, 0x2db764b4U, + 0x76e0cee7U, 0xd34f9a67U, 0x035c810aU, 0x3f56bdc1U, + 0x5b3f2c84U, 0x0baca8c0U, 0xfe979a77U, 0x484ca775U, + 0xbdc7f104U, 0xc06c3efbU, 0xdbc5f32cU, 0x44b017e7U, +}; + +ATF_TC(popcount_basic); +ATF_TC_HEAD(popcount_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test popcount results"); + atf_tc_set_md_var(tc, "timeout", "0"); +} + +ATF_TC_BODY(popcount_basic, tc) +{ + unsigned int i, r; + + popcount_init(atf_tc_get_config_var_wd(tc, "run_popcount", "NO")); + + for (i = 0; i < 0xffffffff; ++i) { + r = byte_count[i & 255] + byte_count[(i >> 8) & 255] + + byte_count[(i >> 16) & 255] + + byte_count[(i >> 24) & 255]; + + ATF_CHECK_EQ(r, popcount(i)); + } + ATF_CHECK_EQ(popcount(0xffffffff), 32); +} + +ATF_TC(popcountll_basic); +ATF_TC_HEAD(popcountll_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test popcountll results"); + atf_tc_set_md_var(tc, "timeout", "0"); +} + +ATF_TC_BODY(popcountll_basic, tc) +{ + unsigned int i, j, r, r2, p; + unsigned long long v; + + popcount_init(atf_tc_get_config_var_wd(tc, "run_popcount", "NO")); + + for (j = 0; j < 256; ++j) { + p = test_parts[j]; + r2 = byte_count[p & 255] + byte_count[(p >> 8) & 255] + + byte_count[(p >> 16) & 255] + + byte_count[(p >> 24) & 255]; + + for (i = 0; i < 0xffffffff; ++i) { + r = byte_count[i & 255] + byte_count[(i >> 8) & 255] + + byte_count[(i >> 16) & 255] + + byte_count[(i >> 24) & 255] + r2; + + v = (((unsigned long long)i) << 32) + p; + ATF_CHECK_EQ(r, popcountll(v)); + v = (((unsigned long long)p) << 32) + i; + ATF_CHECK_EQ(r, popcountll(v)); + } + } + + ATF_CHECK_EQ(popcountll(0xffffffffffffffffULL), 64); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, popcount_basic); + ATF_TP_ADD_TC(tp, popcountll_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcat.c b/contrib/netbsd-tests/lib/libc/string/t_strcat.c new file mode 100644 index 0000000..bd98691 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strcat.c @@ -0,0 +1,153 @@ +/* $NetBSD: t_strcat.c,v 1.2 2011/07/14 05:46:04 jruoho Exp $ */ + +/* + * Written by J.T. Conklin + * Public domain. + */ + +#include +#include +#include +#include +#include + +ATF_TC(strcat_basic); +ATF_TC_HEAD(strcat_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcat(3) results"); +} + +ATF_TC_BODY(strcat_basic, tc) +{ + /* try to trick the compiler */ + char * (*f)(char *, const char *s) = strcat; + + unsigned int a0, a1, t0, t1; + char buf0[64]; + char buf1[64]; + char *ret; + + struct tab { + const char* val; + size_t len; + }; + + const struct tab tab[] = { + /* + * patterns that check for all combinations of leading and + * trailing unaligned characters (on a 64 bit processor) + */ + + { "", 0 }, + { "a", 1 }, + { "ab", 2 }, + { "abc", 3 }, + { "abcd", 4 }, + { "abcde", 5 }, + { "abcdef", 6 }, + { "abcdefg", 7 }, + { "abcdefgh", 8 }, + { "abcdefghi", 9 }, + { "abcdefghij", 10 }, + { "abcdefghijk", 11 }, + { "abcdefghijkl", 12 }, + { "abcdefghijklm", 13 }, + { "abcdefghijklmn", 14 }, + { "abcdefghijklmno", 15 }, + { "abcdefghijklmnop", 16 }, + { "abcdefghijklmnopq", 17 }, + { "abcdefghijklmnopqr", 18 }, + { "abcdefghijklmnopqrs", 19 }, + { "abcdefghijklmnopqrst", 20 }, + { "abcdefghijklmnopqrstu", 21 }, + { "abcdefghijklmnopqrstuv", 22 }, + { "abcdefghijklmnopqrstuvw", 23 }, + + /* + * patterns that check for the cases where the expression: + * + * ((word - 0x7f7f..7f) & 0x8080..80) + * + * returns non-zero even though there are no zero bytes in + * the word. + */ + + { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 }, + { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 }, + { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 }, + { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 }, + { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 }, + { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 }, + { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 }, + { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 }, + { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 }, + }; + + for (a0 = 0; a0 < sizeof(long); ++a0) { + for (a1 = 0; a1 < sizeof(long); ++a1) { + for (t0 = 0; t0 < __arraycount(tab); ++t0) { + for (t1 = 0; t1 < __arraycount(tab); ++t1) { + + memcpy(&buf0[a0], tab[t0].val, + tab[t0].len + 1); + memcpy(&buf1[a1], tab[t1].val, + tab[t1].len + 1); + + ret = f(&buf0[a0], &buf1[a1]); + + /* + * verify strcat returns address + * of first parameter + */ + if (&buf0[a0] != ret) { + fprintf(stderr, "a0 %d, a1 %d, " + "t0 %d, t1 %d\n", + a0, a1, t0, t1); + atf_tc_fail("strcat did not " + "return its first arg"); + } + + /* verify string copied correctly */ + if (memcmp(&buf0[a0] + tab[t0].len, + &buf1[a1], + tab[t1].len + 1) != 0) { + fprintf(stderr, "a0 %d, a1 %d, " + "t0 %d, t1 %d\n", + a0, a1, t0, t1); + atf_tc_fail("string not copied " + "correctly"); + } + } + } + } + } +} + +ATF_TC(strncat_simple); +ATF_TC_HEAD(strncat_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strncat(3) results"); +} + +ATF_TC_BODY(strncat_simple, tc) +{ + char buf[100] = "abcdefg"; + + ATF_CHECK(strncat(buf, "xxx", 0) == buf); + ATF_CHECK(strcmp(buf, "abcdefg") == 0); + ATF_CHECK(strncat(buf, "xxx", 1) == buf); + ATF_CHECK(strcmp(buf, "abcdefgx") == 0); + ATF_CHECK(strncat(buf, "xxx", 2) == buf); + ATF_CHECK(strcmp(buf, "abcdefgxxx") == 0); + ATF_CHECK(strncat(buf, "\0", 1) == buf); + ATF_CHECK(strcmp(buf, "abcdefgxxx") == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strcat_basic); + ATF_TP_ADD_TC(tp, strncat_simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strchr.c b/contrib/netbsd-tests/lib/libc/string/t_strchr.c new file mode 100644 index 0000000..5dd9a62 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strchr.c @@ -0,0 +1,294 @@ +/* $NetBSD: t_strchr.c,v 1.2 2017/01/10 15:34:49 christos Exp $ */ + +/* + * Written by J.T. Conklin + * Public domain. + */ + +#include +#include +#include +#include +#include +#include + +static char *slow_strchr(char *, int); +static void verify_strchr(char *, int, unsigned int, unsigned int); + +char * (*volatile strchr_fn)(const char *, int); + +static char * +slow_strchr(char *buf, int ch) +{ + unsigned char c = 1; + + ch &= 0xff; + + for (; c != 0; buf++) { + c = *buf; + if (c == ch) + return buf; + } + return 0; +} + +static void +verify_strchr(char *buf, int ch, unsigned int t, unsigned int a) +{ + const char *off, *ok_off; + + off = strchr_fn(buf, ch); + ok_off = slow_strchr(buf, ch); + if (off == ok_off) + return; + + fprintf(stderr, "test_strchr(\"%s\", %#x) gave %zd not %zd (test %d, " + "alignment %d)\n", + buf, ch, off ? off - buf : -1, ok_off ? ok_off - buf : -1, t, a); + + atf_tc_fail("Check stderr for details"); +} + +ATF_TC(strchr_basic); +ATF_TC_HEAD(strchr_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test strchr(3) results"); +} + +ATF_TC_BODY(strchr_basic, tc) +{ + void *dl_handle; + char *off; + char buf[32]; + unsigned int t, a; + + const char *tab[] = { + "", + "a", + "aa", + "abc", + "abcd", + "abcde", + "abcdef", + "abcdefg", + "abcdefgh", + + "/", + "//", + "/a", + "/a/", + "/ab", + "/ab/", + "/abc", + "/abc/", + "/abcd", + "/abcd/", + "/abcde", + "/abcde/", + "/abcdef", + "/abcdef/", + "/abcdefg", + "/abcdefg/", + "/abcdefgh", + "/abcdefgh/", + + "a/", + "a//", + "a/a", + "a/a/", + "a/ab", + "a/ab/", + "a/abc", + "a/abc/", + "a/abcd", + "a/abcd/", + "a/abcde", + "a/abcde/", + "a/abcdef", + "a/abcdef/", + "a/abcdefg", + "a/abcdefg/", + "a/abcdefgh", + "a/abcdefgh/", + + "ab/", + "ab//", + "ab/a", + "ab/a/", + "ab/ab", + "ab/ab/", + "ab/abc", + "ab/abc/", + "ab/abcd", + "ab/abcd/", + "ab/abcde", + "ab/abcde/", + "ab/abcdef", + "ab/abcdef/", + "ab/abcdefg", + "ab/abcdefg/", + "ab/abcdefgh", + "ab/abcdefgh/", + + "abc/", + "abc//", + "abc/a", + "abc/a/", + "abc/ab", + "abc/ab/", + "abc/abc", + "abc/abc/", + "abc/abcd", + "abc/abcd/", + "abc/abcde", + "abc/abcde/", + "abc/abcdef", + "abc/abcdef/", + "abc/abcdefg", + "abc/abcdefg/", + "abc/abcdefgh", + "abc/abcdefgh/", + + "abcd/", + "abcd//", + "abcd/a", + "abcd/a/", + "abcd/ab", + "abcd/ab/", + "abcd/abc", + "abcd/abc/", + "abcd/abcd", + "abcd/abcd/", + "abcd/abcde", + "abcd/abcde/", + "abcd/abcdef", + "abcd/abcdef/", + "abcd/abcdefg", + "abcd/abcdefg/", + "abcd/abcdefgh", + "abcd/abcdefgh/", + + "abcde/", + "abcde//", + "abcde/a", + "abcde/a/", + "abcde/ab", + "abcde/ab/", + "abcde/abc", + "abcde/abc/", + "abcde/abcd", + "abcde/abcd/", + "abcde/abcde", + "abcde/abcde/", + "abcde/abcdef", + "abcde/abcdef/", + "abcde/abcdefg", + "abcde/abcdefg/", + "abcde/abcdefgh", + "abcde/abcdefgh/", + + "abcdef/", + "abcdef//", + "abcdef/a", + "abcdef/a/", + "abcdef/ab", + "abcdef/ab/", + "abcdef/abc", + "abcdef/abc/", + "abcdef/abcd", + "abcdef/abcd/", + "abcdef/abcde", + "abcdef/abcde/", + "abcdef/abcdef", + "abcdef/abcdef/", + "abcdef/abcdefg", + "abcdef/abcdefg/", + "abcdef/abcdefgh", + "abcdef/abcdefgh/", + + "abcdefg/", + "abcdefg//", + "abcdefg/a", + "abcdefg/a/", + "abcdefg/ab", + "abcdefg/ab/", + "abcdefg/abc", + "abcdefg/abc/", + "abcdefg/abcd", + "abcdefg/abcd/", + "abcdefg/abcde", + "abcdefg/abcde/", + "abcdefg/abcdef", + "abcdefg/abcdef/", + "abcdefg/abcdefg", + "abcdefg/abcdefg/", + "abcdefg/abcdefgh", + "abcdefg/abcdefgh/", + + "abcdefgh/", + "abcdefgh//", + "abcdefgh/a", + "abcdefgh/a/", + "abcdefgh/ab", + "abcdefgh/ab/", + "abcdefgh/abc", + "abcdefgh/abc/", + "abcdefgh/abcd", + "abcdefgh/abcd/", + "abcdefgh/abcde", + "abcdefgh/abcde/", + "abcdefgh/abcdef", + "abcdefgh/abcdef/", + "abcdefgh/abcdefg", + "abcdefgh/abcdefg/", + "abcdefgh/abcdefgh", + "abcdefgh/abcdefgh/", + }; + + dl_handle = dlopen(NULL, RTLD_LAZY); + strchr_fn = dlsym(dl_handle, "test_strlen"); + if (!strchr_fn) + strchr_fn = strchr; + + for (a = 3; a < 3 + sizeof(long); ++a) { + /* Put char and a \0 before the buffer */ + buf[a-1] = '/'; + buf[a-2] = '0'; + buf[a-3] = 0xff; + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + int len = strlen(tab[t]) + 1; + memcpy(&buf[a], tab[t], len); + + /* Put the char we are looking for after the \0 */ + buf[a + len] = '/'; + + /* Check search for NUL at end of string */ + verify_strchr(buf + a, 0, t, a); + + /* Then for the '/' in the strings */ + verify_strchr(buf + a, '/', t, a); + + /* check zero extension of char arg */ + verify_strchr(buf + a, 0xffffff00 | '/', t, a); + + /* Replace all the '/' with 0xff */ + while ((off = slow_strchr(buf + a, '/')) != NULL) + *off = 0xff; + + buf[a + len] = 0xff; + + /* Check we can search for 0xff as well as '/' */ + verify_strchr(buf + a, 0xff, t, a); + } + } + (void)dlclose(dl_handle); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strchr_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcmp.c b/contrib/netbsd-tests/lib/libc/string/t_strcmp.c new file mode 100644 index 0000000..14e2e9c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strcmp.c @@ -0,0 +1,136 @@ +/* $NetBSD: t_strcmp.c,v 1.4 2012/03/25 08:17:54 joerg Exp $ */ + +/* + * Written by J.T. Conklin + * Public domain. + */ + +#include +#include +#include +#include +#include + +ATF_TC(strcmp_basic); +ATF_TC_HEAD(strcmp_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcmp(3) results, #1"); +} + +ATF_TC_BODY(strcmp_basic, tc) +{ + /* try to trick the compiler */ + int (*f)(const char *, const char *s) = strcmp; + + unsigned int a0, a1, t; + char buf0[64]; + char buf1[64]; + int ret; + + struct tab { + const char* val0; + const char* val1; + int ret; + }; + + const struct tab tab[] = { + { "", "", 0 }, + + { "a", "a", 0 }, + { "a", "b", -1 }, + { "b", "a", +1 }, + { "", "a", -1 }, + { "a", "", +1 }, + + { "aa", "aa", 0 }, + { "aa", "ab", -1 }, + { "ab", "aa", +1 }, + { "a", "aa", -1 }, + { "aa", "a", +1 }, + + { "aaa", "aaa", 0 }, + { "aaa", "aab", -1 }, + { "aab", "aaa", +1 }, + { "aa", "aaa", -1 }, + { "aaa", "aa", +1 }, + + { "aaaa", "aaaa", 0 }, + { "aaaa", "aaab", -1 }, + { "aaab", "aaaa", +1 }, + { "aaa", "aaaa", -1 }, + { "aaaa", "aaa", +1 }, + + { "aaaaa", "aaaaa", 0 }, + { "aaaaa", "aaaab", -1 }, + { "aaaab", "aaaaa", +1 }, + { "aaaa", "aaaaa", -1 }, + { "aaaaa", "aaaa", +1 }, + + { "aaaaaa", "aaaaaa", 0 }, + { "aaaaaa", "aaaaab", -1 }, + { "aaaaab", "aaaaaa", +1 }, + { "aaaaa", "aaaaaa", -1 }, + { "aaaaaa", "aaaaa", +1 }, + }; + + for (a0 = 0; a0 < sizeof(long); ++a0) { + for (a1 = 0; a1 < sizeof(long); ++a1) { + for (t = 0; t < __arraycount(tab); ++t) { + memcpy(&buf0[a0], tab[t].val0, + strlen(tab[t].val0) + 1); + memcpy(&buf1[a1], tab[t].val1, + strlen(tab[t].val1) + 1); + + ret = f(&buf0[a0], &buf1[a1]); + + if ((ret == 0 && tab[t].ret != 0) || + (ret < 0 && tab[t].ret >= 0) || + (ret > 0 && tab[t].ret <= 0)) { + fprintf(stderr, "a0 %d, a1 %d, t %d\n", + a0, a1, t); + fprintf(stderr, "\"%s\" \"%s\" %d\n", + &buf0[a0], &buf1[a1], ret); + atf_tc_fail("Check stderr for details"); + } + } + } + } +} + +ATF_TC(strcmp_simple); +ATF_TC_HEAD(strcmp_simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcmp(3) results, #2"); +} + +ATF_TC_BODY(strcmp_simple, tc) +{ + char buf1[10] = "xxx"; + char buf2[10] = "xxy"; + + ATF_CHECK(strcmp(buf1, buf1) == 0); + ATF_CHECK(strcmp(buf2, buf2) == 0); + + ATF_CHECK(strcmp("x\xf6x", "xox") > 0); + ATF_CHECK(strcmp("xxx", "xxxyyy") < 0); + ATF_CHECK(strcmp("xxxyyy", "xxx") > 0); + + ATF_CHECK(strcmp(buf1 + 0, buf2 + 0) < 0); + ATF_CHECK(strcmp(buf1 + 1, buf2 + 1) < 0); + ATF_CHECK(strcmp(buf1 + 2, buf2 + 2) < 0); + ATF_CHECK(strcmp(buf1 + 3, buf2 + 3) == 0); + + ATF_CHECK(strcmp(buf2 + 0, buf1 + 0) > 0); + ATF_CHECK(strcmp(buf2 + 1, buf1 + 1) > 0); + ATF_CHECK(strcmp(buf2 + 2, buf1 + 2) > 0); + ATF_CHECK(strcmp(buf2 + 3, buf1 + 3) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strcmp_basic); + ATF_TP_ADD_TC(tp, strcmp_simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcpy.c b/contrib/netbsd-tests/lib/libc/string/t_strcpy.c new file mode 100644 index 0000000..285371e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strcpy.c @@ -0,0 +1,124 @@ +/* $NetBSD: t_strcpy.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */ + +/* + * Written by J.T. Conklin + * Public domain. + */ + +#include +#include +#include +#include +#include + +ATF_TC(strcpy_basic); +ATF_TC_HEAD(strcpy_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcpy(3) results"); +} + +ATF_TC_BODY(strcpy_basic, tc) +{ + /* try to trick the compiler */ + char * (*f)(char *, const char *s) = strcpy; + + unsigned int a0, a1, t; + char buf0[64]; + char buf1[64]; + char *ret; + + struct tab { + const char* val; + size_t len; + }; + + const struct tab tab[] = { + /* + * patterns that check for all combinations of leading and + * trailing unaligned characters (on a 64 bit processor) + */ + + { "", 0 }, + { "a", 1 }, + { "ab", 2 }, + { "abc", 3 }, + { "abcd", 4 }, + { "abcde", 5 }, + { "abcdef", 6 }, + { "abcdefg", 7 }, + { "abcdefgh", 8 }, + { "abcdefghi", 9 }, + { "abcdefghij", 10 }, + { "abcdefghijk", 11 }, + { "abcdefghijkl", 12 }, + { "abcdefghijklm", 13 }, + { "abcdefghijklmn", 14 }, + { "abcdefghijklmno", 15 }, + { "abcdefghijklmnop", 16 }, + { "abcdefghijklmnopq", 17 }, + { "abcdefghijklmnopqr", 18 }, + { "abcdefghijklmnopqrs", 19 }, + { "abcdefghijklmnopqrst", 20 }, + { "abcdefghijklmnopqrstu", 21 }, + { "abcdefghijklmnopqrstuv", 22 }, + { "abcdefghijklmnopqrstuvw", 23 }, + + /* + * patterns that check for the cases where the expression: + * + * ((word - 0x7f7f..7f) & 0x8080..80) + * + * returns non-zero even though there are no zero bytes in + * the word. + */ + + { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 }, + { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 }, + { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 }, + { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 }, + { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 }, + { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 }, + { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 }, + { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 }, + { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 }, + }; + + for (a0 = 0; a0 < sizeof(long); ++a0) { + for (a1 = 0; a1 < sizeof(long); ++a1) { + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + + memcpy(&buf1[a1], tab[t].val, tab[t].len + 1); + ret = f(&buf0[a0], &buf1[a1]); + + /* + * verify strcpy returns address of + * first parameter + */ + if (&buf0[a0] != ret) { + fprintf(stderr, "a0 %d, a1 %d, t %d\n", + a0, a1, t); + atf_tc_fail("strcpy did not return " + "its first arg"); + } + + /* + * verify string was copied correctly + */ + if (memcmp(&buf0[a0], &buf1[a1], + tab[t].len + 1) != 0) { + fprintf(stderr, "a0 %d, a1 %d, t %d\n", + a0, a1, t); + atf_tc_fail("not correctly copied"); + } + } + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strcpy_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcspn.c b/contrib/netbsd-tests/lib/libc/string/t_strcspn.c new file mode 100644 index 0000000..d38cdb4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strcspn.c @@ -0,0 +1,58 @@ +/* $NetBSD: t_strcspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_strcspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include +#include + +ATF_TC(strcspn); +ATF_TC_HEAD(strcspn, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strcspn(3)"); +} + +ATF_TC_BODY(strcspn, tc) +{ + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", ""), 16); + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "a"), 0); + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "b"), 1); + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "cd"), 2); + ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "qrstuvwxyz"), 16); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strcspn); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strerror.c b/contrib/netbsd-tests/lib/libc/string/t_strerror.c new file mode 100644 index 0000000..99b95b4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strerror.c @@ -0,0 +1,136 @@ +/* $NetBSD: t_strerror.c,v 1.4 2017/01/10 20:35:49 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_strerror.c,v 1.4 2017/01/10 20:35:49 christos Exp $"); + +#include +#include +#include /* Needed for sys_nerr on FreeBSD */ +#include +#include +#include + +ATF_TC(strerror_basic); +ATF_TC_HEAD(strerror_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strerror(3)"); +} + +ATF_TC_BODY(strerror_basic, tc) +{ + int i; + + for (i = 1; i < sys_nerr; i++) + ATF_REQUIRE(strstr(strerror(i), "Unknown error:") == NULL); + + for (; i < sys_nerr + 10; i++) + ATF_REQUIRE(strstr(strerror(i), "Unknown error:") != NULL); +} + +ATF_TC(strerror_err); +ATF_TC_HEAD(strerror_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from strerror(3)"); +} + +ATF_TC_BODY(strerror_err, tc) +{ + + errno = 0; + + ATF_REQUIRE(strstr(strerror(INT_MAX), "Unknown error:") != NULL); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + + ATF_REQUIRE(strstr(strerror(INT_MIN), "Unknown error:") != NULL); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC(strerror_r_basic); +ATF_TC_HEAD(strerror_r_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of strerror_r(3)"); +} + +ATF_TC_BODY(strerror_r_basic, tc) +{ + char buf[512]; + int i; + + for (i = 1; i < sys_nerr; i++) { + ATF_REQUIRE(strerror_r(i, buf, sizeof(buf)) == 0); + ATF_REQUIRE(strstr(buf, "Unknown error:") == NULL); + } + + for (; i < sys_nerr + 10; i++) { + ATF_REQUIRE(strerror_r(i, buf, sizeof(buf)) == EINVAL); + ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL); + } +} + +ATF_TC(strerror_r_err); +ATF_TC_HEAD(strerror_r_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from strerror_r(3)"); +} + +ATF_TC_BODY(strerror_r_err, tc) +{ + char buf[512]; + int rv; + + rv = strerror_r(EPERM, buf, 1); + ATF_REQUIRE(rv == ERANGE); + + rv = strerror_r(INT_MAX, buf, sizeof(buf)); + + ATF_REQUIRE(rv == EINVAL); + ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL); + + rv = strerror_r(INT_MIN, buf, sizeof(buf)); + + ATF_REQUIRE(rv == EINVAL); + ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + (void)setlocale(LC_ALL, "C"); + + ATF_TP_ADD_TC(tp, strerror_basic); + ATF_TP_ADD_TC(tp, strerror_err); + ATF_TP_ADD_TC(tp, strerror_r_basic); + ATF_TP_ADD_TC(tp, strerror_r_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_stresep.c b/contrib/netbsd-tests/lib/libc/string/t_stresep.c new file mode 100644 index 0000000..4678e55 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_stresep.c @@ -0,0 +1,72 @@ +/* $NetBSD: t_stresep.c,v 1.3 2013/02/15 23:56:32 christos Exp $ */ + +/*- + * Copyright (c) 2005 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include + +#define expect(a) \ + if ((p = stresep(&q, " ", '\\')) == NULL || strcmp(p, a)) { \ + fprintf(stderr, "failed on line %d: %s != %s\n", \ + __LINE__, p, a); \ + atf_tc_fail("Check stderr for test id/line"); \ + } + +ATF_TC(stresep_basic); +ATF_TC_HEAD(stresep_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test stresep results"); +} + +ATF_TC_BODY(stresep_basic, tc) +{ + char brkstr[] = "foo\\ \\ bar baz bar\\ foo\\ bar\\ \\ foo \\ \\ \\ " + "baz bar\\ \\ "; + char *p, *q = brkstr; + + expect("foo bar"); + expect("baz"); + expect("bar foo "); + expect("bar foo"); + expect(" baz"); + expect("bar "); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, stresep_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strlen.c b/contrib/netbsd-tests/lib/libc/string/t_strlen.c new file mode 100644 index 0000000..9899e6d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strlen.c @@ -0,0 +1,202 @@ +/* $NetBSD: t_strlen.c,v 1.6 2017/01/14 20:49:24 christos Exp $ */ + +/* + * Written by J.T. Conklin + * Public domain. + */ + +#include +#include +#include +#include +#include +#include +#include + +static void write_num(int); + +static void +write_num(int val) +{ + char buf[20]; + int i; + + for (i = sizeof buf; --i >= 0;) { + buf[i] = '0' + val % 10; + val /= 10; + if (val == 0) { + write(2, buf + i, sizeof buf - i); + return; + } + } + write(2, "overflow", 8); +} + +ATF_TC(strlen_basic); +ATF_TC_HEAD(strlen_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strlen(3) results"); +} + +ATF_TC_BODY(strlen_basic, tc) +{ + void *dl_handle; + /* try to trick the compiler */ + size_t (*strlen_fn)(const char *); + + unsigned int a, t; + size_t len; + char buf[64]; + + struct tab { + const char* val; + size_t len; + }; + + const struct tab tab[] = { + /* + * patterns that check for all combinations of leading and + * trailing unaligned characters (on a 64 bit processor) + */ + + { "", 0 }, + { "a", 1 }, + { "ab", 2 }, + { "abc", 3 }, + { "abcd", 4 }, + { "abcde", 5 }, + { "abcdef", 6 }, + { "abcdefg", 7 }, + { "abcdefgh", 8 }, + { "abcdefghi", 9 }, + { "abcdefghij", 10 }, + { "abcdefghijk", 11 }, + { "abcdefghijkl", 12 }, + { "abcdefghijklm", 13 }, + { "abcdefghijklmn", 14 }, + { "abcdefghijklmno", 15 }, + { "abcdefghijklmnop", 16 }, + { "abcdefghijklmnopq", 17 }, + { "abcdefghijklmnopqr", 18 }, + { "abcdefghijklmnopqrs", 19 }, + { "abcdefghijklmnopqrst", 20 }, + { "abcdefghijklmnopqrstu", 21 }, + { "abcdefghijklmnopqrstuv", 22 }, + { "abcdefghijklmnopqrstuvw", 23 }, + + /* + * patterns that check for the cases where the expression: + * + * ((word - 0x7f7f..7f) & 0x8080..80) + * + * returns non-zero even though there are no zero bytes in + * the word. + */ + + { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 }, + { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 }, + { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 }, + { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 }, + { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 }, + { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 }, + { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 }, + { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 }, + { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 }, + }; + + /* + * During testing it is useful have the rest of the program + * use a known good version! + */ + dl_handle = dlopen(NULL, RTLD_LAZY); + strlen_fn = dlsym(dl_handle, "test_strlen"); + if (!strlen_fn) + strlen_fn = strlen; + + for (a = 0; a < sizeof(long); ++a) { + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + + memcpy(&buf[a], tab[t].val, tab[t].len + 1); + len = strlen_fn(&buf[a]); + + if (len != tab[t].len) { + /* Write error without using printf / strlen */ + write(2, "alignment ", 10); + write_num(a); + write(2, ", test ", 7); + write_num(t); + write(2, ", got len ", 10); + write_num(len); + write(2, ", not ", 6); + write_num(tab[t].len); + write(2, ", for '", 7); + write(2, tab[t].val, tab[t].len); + write(2, "'\n", 2); + atf_tc_fail("See stderr for details"); + } + } + } + (void)dlclose(dl_handle); +} + +ATF_TC(strlen_huge); +ATF_TC_HEAD(strlen_huge, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strlen(3) with huge strings"); +} + +ATF_TC_BODY(strlen_huge, tc) +{ + long page; + char *str; + size_t i; + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + for (i = 1; i < 1000; i = i + 100) { + + str = malloc(i * page + 1); + + if (str == NULL) + continue; + + (void)memset(str, 'x', i * page); + str[i * page] = '\0'; + + ATF_REQUIRE(strlen(str) == i * page); + free(str); + } +} + +ATF_TC(strnlen_basic); +ATF_TC_HEAD(strnlen_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A naive test of strnlen(3)"); +} + +ATF_TC_BODY(strnlen_basic, tc) +{ + char buf[1]; + + buf[0] = '\0'; + + ATF_CHECK(strnlen(buf, 000) == 0); + ATF_CHECK(strnlen(buf, 111) == 0); + + ATF_CHECK(strnlen("xxx", 0) == 0); + ATF_CHECK(strnlen("xxx", 1) == 1); + ATF_CHECK(strnlen("xxx", 2) == 2); + ATF_CHECK(strnlen("xxx", 3) == 3); + ATF_CHECK(strnlen("xxx", 9) == 3); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strlen_basic); + ATF_TP_ADD_TC(tp, strlen_huge); + ATF_TP_ADD_TC(tp, strnlen_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strpbrk.c b/contrib/netbsd-tests/lib/libc/string/t_strpbrk.c new file mode 100644 index 0000000..d0f2d9b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strpbrk.c @@ -0,0 +1,62 @@ +/* $NetBSD: t_strpbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_strpbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include +#include + +ATF_TC(strpbrk); +ATF_TC_HEAD(strpbrk, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strpbrk(3)"); +} + +ATF_TC_BODY(strpbrk, tc) +{ + static const char s[] = "abcdefghijklmnop"; + + ATF_CHECK_EQ(strpbrk(s, ""), NULL); + ATF_CHECK_EQ(strpbrk(s, "qrst"), NULL); + ATF_CHECK_EQ(strpbrk(s, "a"), s); + ATF_CHECK_EQ(strpbrk(s, "b"), s + 1); + ATF_CHECK_EQ(strpbrk(s, "ab"), s); + ATF_CHECK_EQ(strpbrk(s, "cdef"), s + 2); + ATF_CHECK_EQ(strpbrk(s, "fedc"), s + 2); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strpbrk); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strrchr.c b/contrib/netbsd-tests/lib/libc/string/t_strrchr.c new file mode 100644 index 0000000..038daff --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strrchr.c @@ -0,0 +1,257 @@ +/* $NetBSD: t_strrchr.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */ + +/* + * Written by J.T. Conklin + * Public domain. + */ + +#include +#include +#include +#include +#include + +ATF_TC(strrchr_basic); +ATF_TC_HEAD(strrchr_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strrchr(3) results"); +} + +ATF_TC_BODY(strrchr_basic, tc) +{ + /* try to trick the compiler */ + char * (*f)(const char *, int) = strrchr; + + unsigned int a, t; + char *off, *off2; + char buf[32]; + + struct tab { + const char* val; + char match; + ssize_t f_off; /* offset of first match */ + ssize_t l_off; /* offset of last match */ + }; + + const struct tab tab[] = { + { "", 0, 0, 0 }, + { "a", 0, 0, 0 }, + { "aa", 0, 0, 0 }, + { "abc", 0, 0, 0 }, + { "abcd", 0, 0, 0 }, + { "abcde", 0, 0, 0 }, + { "abcdef", 0, 0, 0 }, + { "abcdefg", 0, 0, 0 }, + { "abcdefgh", 0, 0, 0 }, + + { "/", 1, 0, 0 }, + { "//", 1, 0, 1 }, + { "/a", 1, 0, 0 }, + { "/a/", 1, 0, 2 }, + { "/ab", 1, 0, 0 }, + { "/ab/", 1, 0, 3 }, + { "/abc", 1, 0, 0 }, + { "/abc/", 1, 0, 4 }, + { "/abcd", 1, 0, 0 }, + { "/abcd/", 1, 0, 5 }, + { "/abcde", 1, 0, 0 }, + { "/abcde/", 1, 0, 6 }, + { "/abcdef", 1, 0, 0 }, + { "/abcdef/", 1, 0, 7 }, + { "/abcdefg", 1, 0, 0 }, + { "/abcdefg/", 1, 0, 8 }, + { "/abcdefgh", 1, 0, 0 }, + { "/abcdefgh/", 1, 0, 9 }, + + { "a/", 1, 1, 1 }, + { "a//", 1, 1, 2 }, + { "a/a", 1, 1, 1 }, + { "a/a/", 1, 1, 3 }, + { "a/ab", 1, 1, 1 }, + { "a/ab/", 1, 1, 4 }, + { "a/abc", 1, 1, 1 }, + { "a/abc/", 1, 1, 5 }, + { "a/abcd", 1, 1, 1 }, + { "a/abcd/", 1, 1, 6 }, + { "a/abcde", 1, 1, 1 }, + { "a/abcde/", 1, 1, 7 }, + { "a/abcdef", 1, 1, 1 }, + { "a/abcdef/", 1, 1, 8 }, + { "a/abcdefg", 1, 1, 1 }, + { "a/abcdefg/", 1, 1, 9 }, + { "a/abcdefgh", 1, 1, 1 }, + { "a/abcdefgh/", 1, 1, 10 }, + + { "ab/", 1, 2, 2 }, + { "ab//", 1, 2, 3 }, + { "ab/a", 1, 2, 2 }, + { "ab/a/", 1, 2, 4 }, + { "ab/ab", 1, 2, 2 }, + { "ab/ab/", 1, 2, 5 }, + { "ab/abc", 1, 2, 2 }, + { "ab/abc/", 1, 2, 6 }, + { "ab/abcd", 1, 2, 2 }, + { "ab/abcd/", 1, 2, 7 }, + { "ab/abcde", 1, 2, 2 }, + { "ab/abcde/", 1, 2, 8 }, + { "ab/abcdef", 1, 2, 2 }, + { "ab/abcdef/", 1, 2, 9 }, + { "ab/abcdefg", 1, 2, 2 }, + { "ab/abcdefg/", 1, 2, 10 }, + { "ab/abcdefgh", 1, 2, 2 }, + { "ab/abcdefgh/", 1, 2, 11 }, + + { "abc/", 1, 3, 3 }, + { "abc//", 1, 3, 4 }, + { "abc/a", 1, 3, 3 }, + { "abc/a/", 1, 3, 5 }, + { "abc/ab", 1, 3, 3 }, + { "abc/ab/", 1, 3, 6 }, + { "abc/abc", 1, 3, 3 }, + { "abc/abc/", 1, 3, 7 }, + { "abc/abcd", 1, 3, 3 }, + { "abc/abcd/", 1, 3, 8 }, + { "abc/abcde", 1, 3, 3 }, + { "abc/abcde/", 1, 3, 9 }, + { "abc/abcdef", 1, 3, 3 }, + { "abc/abcdef/", 1, 3, 10 }, + { "abc/abcdefg", 1, 3, 3 }, + { "abc/abcdefg/", 1, 3, 11 }, + { "abc/abcdefgh", 1, 3, 3 }, + { "abc/abcdefgh/", 1, 3, 12 }, + + { "abcd/", 1, 4, 4 }, + { "abcd//", 1, 4, 5 }, + { "abcd/a", 1, 4, 4 }, + { "abcd/a/", 1, 4, 6 }, + { "abcd/ab", 1, 4, 4 }, + { "abcd/ab/", 1, 4, 7 }, + { "abcd/abc", 1, 4, 4 }, + { "abcd/abc/", 1, 4, 8 }, + { "abcd/abcd", 1, 4, 4 }, + { "abcd/abcd/", 1, 4, 9 }, + { "abcd/abcde", 1, 4, 4 }, + { "abcd/abcde/", 1, 4, 10 }, + { "abcd/abcdef", 1, 4, 4 }, + { "abcd/abcdef/", 1, 4, 11 }, + { "abcd/abcdefg", 1, 4, 4 }, + { "abcd/abcdefg/", 1, 4, 12 }, + { "abcd/abcdefgh", 1, 4, 4 }, + { "abcd/abcdefgh/", 1, 4, 13 }, + + { "abcde/", 1, 5, 5 }, + { "abcde//", 1, 5, 6 }, + { "abcde/a", 1, 5, 5 }, + { "abcde/a/", 1, 5, 7 }, + { "abcde/ab", 1, 5, 5 }, + { "abcde/ab/", 1, 5, 8 }, + { "abcde/abc", 1, 5, 5 }, + { "abcde/abc/", 1, 5, 9 }, + { "abcde/abcd", 1, 5, 5 }, + { "abcde/abcd/", 1, 5, 10 }, + { "abcde/abcde", 1, 5, 5 }, + { "abcde/abcde/", 1, 5, 11 }, + { "abcde/abcdef", 1, 5, 5 }, + { "abcde/abcdef/", 1, 5, 12 }, + { "abcde/abcdefg", 1, 5, 5 }, + { "abcde/abcdefg/", 1, 5, 13 }, + { "abcde/abcdefgh", 1, 5, 5 }, + { "abcde/abcdefgh/", 1, 5, 14 }, + + { "abcdef/", 1, 6, 6 }, + { "abcdef//", 1, 6, 7 }, + { "abcdef/a", 1, 6, 6 }, + { "abcdef/a/", 1, 6, 8 }, + { "abcdef/ab", 1, 6, 6 }, + { "abcdef/ab/", 1, 6, 9 }, + { "abcdef/abc", 1, 6, 6 }, + { "abcdef/abc/", 1, 6, 10 }, + { "abcdef/abcd", 1, 6, 6 }, + { "abcdef/abcd/", 1, 6, 11 }, + { "abcdef/abcde", 1, 6, 6 }, + { "abcdef/abcde/", 1, 6, 12 }, + { "abcdef/abcdef", 1, 6, 6 }, + { "abcdef/abcdef/", 1, 6, 13 }, + { "abcdef/abcdefg", 1, 6, 6 }, + { "abcdef/abcdefg/", 1, 6, 14 }, + { "abcdef/abcdefgh", 1, 6, 6 }, + { "abcdef/abcdefgh/", 1, 6, 15 }, + + { "abcdefg/", 1, 7, 7 }, + { "abcdefg//", 1, 7, 8 }, + { "abcdefg/a", 1, 7, 7 }, + { "abcdefg/a/", 1, 7, 9 }, + { "abcdefg/ab", 1, 7, 7 }, + { "abcdefg/ab/", 1, 7, 10 }, + { "abcdefg/abc", 1, 7, 7 }, + { "abcdefg/abc/", 1, 7, 11 }, + { "abcdefg/abcd", 1, 7, 7 }, + { "abcdefg/abcd/", 1, 7, 12 }, + { "abcdefg/abcde", 1, 7, 7 }, + { "abcdefg/abcde/", 1, 7, 13 }, + { "abcdefg/abcdef", 1, 7, 7 }, + { "abcdefg/abcdef/", 1, 7, 14 }, + { "abcdefg/abcdefg", 1, 7, 7 }, + { "abcdefg/abcdefg/", 1, 7, 15 }, + { "abcdefg/abcdefgh", 1, 7, 7 }, + { "abcdefg/abcdefgh/", 1, 7, 16 }, + + { "abcdefgh/", 1, 8, 8 }, + { "abcdefgh//", 1, 8, 9 }, + { "abcdefgh/a", 1, 8, 8 }, + { "abcdefgh/a/", 1, 8, 10 }, + { "abcdefgh/ab", 1, 8, 8 }, + { "abcdefgh/ab/", 1, 8, 11 }, + { "abcdefgh/abc", 1, 8, 8 }, + { "abcdefgh/abc/", 1, 8, 12 }, + { "abcdefgh/abcd", 1, 8, 8 }, + { "abcdefgh/abcd/", 1, 8, 13 }, + { "abcdefgh/abcde", 1, 8, 8 }, + { "abcdefgh/abcde/", 1, 8, 14 }, + { "abcdefgh/abcdef", 1, 8, 8 }, + { "abcdefgh/abcdef/", 1, 8, 15 }, + { "abcdefgh/abcdefg", 1, 8, 8 }, + { "abcdefgh/abcdefg/", 1, 8, 16 }, + { "abcdefgh/abcdefgh", 1, 8, 8 }, + { "abcdefgh/abcdefgh/", 1, 8, 17 }, + }; + + for (a = 0; a < sizeof(long); ++a) { + for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) { + strcpy(&buf[a], tab[t].val); + + off = f(&buf[a], '/'); + if (tab[t].match == 0) { + if (off != 0) { + fprintf(stderr, "a %d, t %d\n", a, t); + atf_tc_fail("strrchr should not have " + "found the character"); + } + } else if (tab[t].match == 1) { + if (tab[t].l_off != (off - &buf[a])) { + fprintf(stderr, "a %d, t %d\n", a, t); + atf_tc_fail("strrchr returns wrong " + "offset"); + } + } else { + fprintf(stderr, "a %d, t %d\n", a, t); + atf_tc_fail("bad test case data"); + } + + /* check zero extension of char arg */ + off2 = f(&buf[a], 0xffffff00 | '/'); + if (off != off2) { + fprintf(stderr, "a %d, t %d\n", a, t); + atf_tc_fail("zero extension of char arg fails"); + } + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strrchr_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_strspn.c b/contrib/netbsd-tests/lib/libc/string/t_strspn.c new file mode 100644 index 0000000..6782181 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_strspn.c @@ -0,0 +1,60 @@ +/* $NetBSD: t_strspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_strspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $"); + +#include +#include + +ATF_TC(strspn); +ATF_TC_HEAD(strspn, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test strspn(3)"); +} + +ATF_TC_BODY(strspn, tc) +{ + ATF_CHECK_EQ(strspn("abcdefghijklmnop", ""), 0); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "a"), 1); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "b"), 0); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "ab"), 2); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "abc"), 3); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "abce"), 3); + ATF_CHECK_EQ(strspn("abcdefghijklmnop", "abcdefghijklmnop"), 16); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, strspn); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/string/t_swab.c b/contrib/netbsd-tests/lib/libc/string/t_swab.c new file mode 100644 index 0000000..797397a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/string/t_swab.c @@ -0,0 +1,95 @@ +/* $NetBSD: t_swab.c,v 1.2 2011/07/07 08:27:36 jruoho Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include +#include + +#include + +#define MAXCHK 100 + +static void +build(char *a, char *b, size_t n) { + size_t i; + + n >>= 1; + for (i = 0; i < n; i += 2) { + b[i+1] = a[i] = (char)i; + b[i] = a[i+1] = (char)(i+1); + } + for (n <<= 1; n < MAXCHK; n++) + a[n] = b[n] = (char)~0; +} + +static void +dump(const char *f, char *b, size_t l) +{ + + printf("%s ", f); + while (l--) + printf("%.2x ", (unsigned char)*b++); + printf("\n"); +} + +ATF_TC(swab_basic); +ATF_TC_HEAD(swab_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test swab results"); +} + +ATF_TC_BODY(swab_basic, tc) +{ + char a[MAXCHK], b[MAXCHK], r[MAXCHK]; + size_t i; + + for (i = 0; i < MAXCHK; i += 2) { + build(a, b, i); + (void)memset(r, ~0, MAXCHK); + swab(a, r, i); + if (memcmp(b, r, MAXCHK) != 0) { + fprintf(stderr, "pattern mismatch at %lu bytes", + (unsigned long)i); + dump("expect:", b, MAXCHK); + dump("result:", r, MAXCHK); + atf_tc_fail("Check stderr for details"); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, swab_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c b/contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c new file mode 100644 index 0000000..0f2068a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c @@ -0,0 +1,168 @@ +/* $NetBSD: all_sync_ops_linkable.c,v 1.4 2014/02/21 10:26:25 martin Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann . + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * This is a simple link-time test to verify all builtin atomic sync + * operations are available. Depending on the exact cpu/arch code generator + * options, some of these need support functions (which on NetBSD we + * typically provide in src/common/lib/libc/atomic). + * + * The list of operations has been extracted from sync-builtins.def file + * in the gcc distribution (as of gcc 4.8.2). + */ + +#include +#include + +volatile uint8_t u8 = 0; +volatile uint16_t u16 = 0; +volatile uint32_t u32 = 0; + +#ifdef __HAVE_ATOMIC64_OPS +volatile uint64_t u64 = 0; +#endif + +int +main(int argc, char **argv) +{ + __sync_synchronize(); + __sync_add_and_fetch(&u8, 1); + __sync_add_and_fetch_1(&u8, 1); + __sync_add_and_fetch_2(&u16, 1); + __sync_add_and_fetch_4(&u32, 1); +#ifdef __HAVE_ATOMIC64_OPS + __sync_add_and_fetch_8(&u64, 1); +#endif + __sync_bool_compare_and_swap(&u8, 1, 2); + __sync_bool_compare_and_swap_1(&u8, 1, 2); + __sync_bool_compare_and_swap_2(&u16, 1, 2); + __sync_bool_compare_and_swap_4(&u32, 1, 2); +#ifdef __HAVE_ATOMIC64_OPS + __sync_bool_compare_and_swap_8(&u64, 1, 2); +#endif + __sync_fetch_and_add(&u8, 1); + __sync_fetch_and_add_1(&u8, 1); + __sync_fetch_and_add_2(&u16, 1); + __sync_fetch_and_add_4(&u32, 1); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_add_8(&u64, 1); +#endif + __sync_fetch_and_and(&u8, 0x80); + __sync_fetch_and_and_1(&u8, 0x80); + __sync_fetch_and_and_2(&u16, 0x80); + __sync_fetch_and_and_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_and_8(&u64, 0x80); +#endif +#ifndef __clang__ + __sync_fetch_and_nand(&u8, 0x80); + __sync_fetch_and_nand_1(&u8, 0x80); + __sync_fetch_and_nand_2(&u16, 0x80); + __sync_fetch_and_nand_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_nand_8(&u64, 0x80); +#endif +#endif + __sync_fetch_and_or(&u8, 0x80); + __sync_fetch_and_or_1(&u8, 0x80); + __sync_fetch_and_or_2(&u16, 0x80); + __sync_fetch_and_or_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_or_8(&u64, 0x80); +#endif + __sync_fetch_and_sub(&u8, 0x80); + __sync_fetch_and_sub_1(&u8, 0x80); + __sync_fetch_and_sub_2(&u16, 0x80); + __sync_fetch_and_sub_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_sub_8(&u64, 0x80); +#endif + __sync_fetch_and_xor(&u8, 0x80); + __sync_fetch_and_xor_1(&u8, 0x80); + __sync_fetch_and_xor_2(&u16, 0x80); + __sync_fetch_and_xor_4(&u32, 0x80); +#ifdef __HAVE_ATOMIC64_OPS + __sync_fetch_and_xor_8(&u64, 0x80); +#endif + __sync_lock_release(&u8); + __sync_lock_release_1(&u8); + __sync_lock_release_2(&u16); + __sync_lock_release_4(&u32); +#ifdef __HAVE_ATOMIC64_OPS + __sync_lock_release_8(&u64); +#endif + __sync_lock_test_and_set(&u8, 5); + __sync_lock_test_and_set_1(&u8, 5); + __sync_lock_test_and_set_2(&u16, 5); + __sync_lock_test_and_set_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_lock_test_and_set_8(&u64, 5); +#endif +#ifndef __clang__ + __sync_nand_and_fetch(&u8, 5); + __sync_nand_and_fetch_1(&u8, 5); + __sync_nand_and_fetch_2(&u16, 5); + __sync_nand_and_fetch_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_nand_and_fetch_8(&u64, 5); +#endif +#endif + __sync_or_and_fetch(&u8, 5); + __sync_or_and_fetch_1(&u8, 5); + __sync_or_and_fetch_2(&u16, 5); + __sync_or_and_fetch_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_or_and_fetch_8(&u64, 5); +#endif + __sync_sub_and_fetch(&u8, 5); + __sync_sub_and_fetch_1(&u8, 5); + __sync_sub_and_fetch_2(&u16, 5); + __sync_sub_and_fetch_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_sub_and_fetch_8(&u64, 5); +#endif + __sync_val_compare_and_swap(&u8, 5, 9); + __sync_val_compare_and_swap_1(&u8, 5, 9); + __sync_val_compare_and_swap_2(&u16, 5, 9); + __sync_val_compare_and_swap_4(&u32, 5, 9); +#ifdef __HAVE_ATOMIC64_OPS + __sync_val_compare_and_swap_8(&u64, 5, 9); +#endif + __sync_xor_and_fetch(&u8, 5); + __sync_xor_and_fetch_1(&u8, 5); + __sync_xor_and_fetch_2(&u16, 5); + __sync_xor_and_fetch_4(&u32, 5); +#ifdef __HAVE_ATOMIC64_OPS + __sync_xor_and_fetch_8(&u64, 5); +#endif + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/sync/cpp_atomic_ops_linkable.cc b/contrib/netbsd-tests/lib/libc/sync/cpp_atomic_ops_linkable.cc new file mode 100644 index 0000000..e7822b7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sync/cpp_atomic_ops_linkable.cc @@ -0,0 +1,107 @@ +/* $NetBSD: cpp_atomic_ops_linkable.cc,v 1.5 2017/01/11 12:10:26 joerg Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann . + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * This is a simple link-time test to verify all builtin atomic sync + * operations for C++ are available. + */ + +#include +#include // for __HAVE_ATOMIC64_OPS + +template +class ATest { +public: + ATest() : m_val(0) + { + m_val.exchange(std::atomic(8)); + m_val--; + m_val++; + m_val ^= 0x0f; + m_val &= 0x0f; + m_val |= 2; + + T tval(1), other(42); + m_val.compare_exchange_weak(tval, other, + std::memory_order_release, std::memory_order_relaxed); + } + +private: + volatile std::atomic m_val; +}; + +int main(int argc, char **argv) +{ + ATest(); + ATest(); + ATest(); + ATest(); + ATest(); + ATest(); + ATest(); + ATest(); + ATest(); +#ifdef __HAVE_ATOMIC64_OPS + ATest(); + ATest(); +#endif + ATest(); + ATest(); + ATest(); + ATest(); + ATest(); + ATest(); + ATest(); + ATest(); + ATest(); +#ifdef __HAVE_ATOMIC64_OPS + ATest(); + ATest(); +#endif + ATest(); + ATest(); + ATest(); + ATest(); + ATest(); + ATest(); +#ifdef __HAVE_ATOMIC64_OPS + ATest(); + ATest(); +#endif + ATest(); + ATest(); + ATest(); + ATest(); +#ifdef __HAVE_ATOMIC64_OPS + ATest(); + ATest(); +#endif +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_access.c b/contrib/netbsd-tests/lib/libc/sys/t_access.c new file mode 100644 index 0000000..c537eca --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_access.c @@ -0,0 +1,220 @@ +/* $NetBSD: t_access.c,v 2.2 2017/01/10 22:36:29 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_access.c,v 1.2 2017/01/10 22:36:29 christos Exp $"); + +#ifdef __FreeBSD__ +#include /* For __FreeBSD_version */ +#endif + +#include + +#include + +#include +#include +#include +#include +#include +#include + +static const char path[] = "access"; +static const int mode[4] = { R_OK, W_OK, X_OK, F_OK }; + +ATF_TC_WITH_CLEANUP(access_access); +ATF_TC_HEAD(access_access, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for EACCES"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(access_access, tc) +{ + const int perm[3] = { 0200, 0400, 0000 }; + size_t i; + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + + if (fd < 0) + return; + + for (i = 0; i < __arraycount(mode) - 1; i++) { + + ATF_REQUIRE(fchmod(fd, perm[i]) == 0); + + errno = 0; + + ATF_REQUIRE(access(path, mode[i]) != 0); + ATF_REQUIRE(errno == EACCES); + } + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(access_access, tc) +{ + (void)unlink(path); +} + +ATF_TC(access_fault); +ATF_TC_HEAD(access_fault, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for EFAULT"); +} + +ATF_TC_BODY(access_fault, tc) +{ + size_t i; + + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + + ATF_REQUIRE(access(NULL, mode[i]) != 0); + ATF_REQUIRE(errno == EFAULT); + + errno = 0; + + ATF_REQUIRE(access((char *)-1, mode[i]) != 0); + ATF_REQUIRE(errno == EFAULT); + } +} + +ATF_TC(access_inval); +ATF_TC_HEAD(access_inval, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for EINVAL"); +} + +ATF_TC_BODY(access_inval, tc) +{ + +#if defined(__FreeBSD__) && __FreeBSD_version < 1100033 + atf_tc_expect_fail("arguments to access aren't validated; see " + "bug # 181155 for more details"); +#endif + errno = 0; + + ATF_REQUIRE(access("/usr", -1) != 0); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC(access_notdir); +ATF_TC_HEAD(access_notdir, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOTDIR"); +} + +ATF_TC_BODY(access_notdir, tc) +{ + size_t i; + + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + + /* + * IEEE Std 1003.1-2008 about ENOTDIR: + * + * "A component of the path prefix is not a directory, + * or the path argument contains at least one non- + * character and ends with one or more trailing + * characters and the last pathname component names an + * existing file that is neither a directory nor a symbolic + * link to a directory." + */ + ATF_REQUIRE(access("/etc/passwd//", mode[i]) != 0); + ATF_REQUIRE(errno == ENOTDIR); + } +} + +ATF_TC(access_notexist); +ATF_TC_HEAD(access_notexist, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOENT"); +} + +ATF_TC_BODY(access_notexist, tc) +{ + size_t i; + + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + + ATF_REQUIRE(access("", mode[i]) != 0); + ATF_REQUIRE(errno == ENOENT); + } +} + +ATF_TC(access_toolong); +ATF_TC_HEAD(access_toolong, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test access(2) for ENAMETOOLONG"); +} + +ATF_TC_BODY(access_toolong, tc) +{ + char *buf; + size_t i; + + buf = malloc(PATH_MAX); + + if (buf == NULL) + return; + + for (i = 0; i < PATH_MAX; i++) + buf[i] = 'x'; + + for (i = 0; i < __arraycount(mode); i++) { + + errno = 0; + + ATF_REQUIRE(access(buf, mode[i]) != 0); + ATF_REQUIRE(errno == ENAMETOOLONG); + } + + free(buf); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, access_access); + ATF_TP_ADD_TC(tp, access_fault); + ATF_TP_ADD_TC(tp, access_inval); + ATF_TP_ADD_TC(tp, access_notdir); + ATF_TP_ADD_TC(tp, access_notexist); + ATF_TP_ADD_TC(tp, access_toolong); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_bind.c b/contrib/netbsd-tests/lib/libc/sys/t_bind.c new file mode 100644 index 0000000..0c6027c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_bind.c @@ -0,0 +1,78 @@ +/* $NetBSD: t_bind.c,v 1.3 2015/04/05 23:28:10 rtr Exp $ */ +/* + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include + +#include +#include +#include + +#include + +ATF_TC(bind_foreign_family); + +ATF_TC_HEAD(bind_foreign_family, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that binding a socket " + "with a different address family fails"); +} + +ATF_TC_BODY(bind_foreign_family, tc) +{ + struct sockaddr_in addr; + + /* addr.sin_family = AF_UNSPEC = 0 */ + memset(&addr, 0, sizeof(addr)); + + /* + * it is not necessary to initialize sin_{addr,port} since + * those structure members shall not be accessed if bind + * fails correctly. + */ + + int sock = socket(AF_LOCAL, SOCK_STREAM, 0); + ATF_REQUIRE(sock != -1); + + /* should fail but currently doesn't */ + ATF_REQUIRE(-1 == bind(sock, (struct sockaddr *)&addr, sizeof(addr))); + ATF_REQUIRE(EAFNOSUPPORT == errno); + + close(sock); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, bind_foreign_family); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_chroot.c b/contrib/netbsd-tests/lib/libc/sys/t_chroot.c new file mode 100644 index 0000000..1f1c49b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_chroot.c @@ -0,0 +1,318 @@ +/* $NetBSD: t_chroot.c,v 1.2 2017/01/10 22:36:29 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_chroot.c,v 1.2 2017/01/10 22:36:29 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +ATF_TC(chroot_basic); +ATF_TC_HEAD(chroot_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of chroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(chroot_basic, tc) +{ + char buf[PATH_MAX]; + int fd, sta; + pid_t pid; + + (void)memset(buf, '\0', sizeof(buf)); + (void)getcwd(buf, sizeof(buf)); + (void)strlcat(buf, "/dir", sizeof(buf)); + + ATF_REQUIRE(mkdir(buf, 0500) == 0); + ATF_REQUIRE(chdir(buf) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (chroot(buf) != 0) + _exit(EXIT_FAILURE); + + errno = 0; + + if (chroot("/root") != -1) + _exit(EXIT_FAILURE); + + if (errno != ENOENT) + _exit(EXIT_FAILURE); + + fd = open("file", O_RDONLY | O_CREAT, 0600); + + if (fd < 0) + _exit(EXIT_FAILURE); + + if (close(fd) != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("chroot(2) failed"); + + (void)chdir("/"); + (void)strlcat(buf, "/file", sizeof(buf)); + + fd = open(buf, O_RDONLY); + + if (fd < 0) + atf_tc_fail("chroot(2) did not change the root directory"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(buf) == 0); +} + +ATF_TC(chroot_err); +ATF_TC_HEAD(chroot_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of chroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(chroot_err, tc) +{ + char buf[PATH_MAX + 1]; + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, chroot(buf) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, chroot((void *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, chroot("/a/b/c/d/e/f/g/h/i/j") == -1); +} + +ATF_TC(chroot_perm); +ATF_TC_HEAD(chroot_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with chroot(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(chroot_perm, tc) +{ + static char buf[LINE_MAX]; + pid_t pid; + int sta; + + (void)memset(buf, '\0', sizeof(buf)); + ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + errno = 0; + + if (chroot(buf) != -1) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("chroot(2) succeeded as unprivileged user"); +} + +#ifdef __NetBSD__ +ATF_TC(fchroot_basic); +ATF_TC_HEAD(fchroot_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fchroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(fchroot_basic, tc) +{ + char buf[PATH_MAX]; + int fd, sta; + pid_t pid; + + (void)memset(buf, '\0', sizeof(buf)); + (void)getcwd(buf, sizeof(buf)); + (void)strlcat(buf, "/dir", sizeof(buf)); + + ATF_REQUIRE(mkdir(buf, 0500) == 0); + ATF_REQUIRE(chdir(buf) == 0); + + fd = open(buf, O_RDONLY); + ATF_REQUIRE(fd >= 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (fchroot(fd) != 0) + _exit(EXIT_FAILURE); + + if (close(fd) != 0) + _exit(EXIT_FAILURE); + + fd = open("file", O_RDONLY | O_CREAT, 0600); + + if (fd < 0) + _exit(EXIT_FAILURE); + + if (close(fd) != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("fchroot(2) failed"); + + (void)chdir("/"); + (void)strlcat(buf, "/file", sizeof(buf)); + + fd = open(buf, O_RDONLY); + + if (fd < 0) + atf_tc_fail("fchroot(2) did not change the root directory"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(buf) == 0); +} + +ATF_TC(fchroot_err); +ATF_TC_HEAD(fchroot_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of fchroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(fchroot_err, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fchroot(-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOTDIR, fchroot(fd) == -1); + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC(fchroot_perm); +ATF_TC_HEAD(fchroot_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with fchroot(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(fchroot_perm, tc) +{ + static char buf[LINE_MAX]; + struct passwd *pw; + int fd, sta; + pid_t pid; + + (void)memset(buf, '\0', sizeof(buf)); + ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL); + + pw = getpwnam("nobody"); + fd = open(buf, O_RDONLY); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pw != NULL); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)setuid(pw->pw_uid); + + errno = 0; + + if (fchroot(fd) != -1) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("fchroot(2) succeeded as unprivileged user"); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, chroot_basic); + ATF_TP_ADD_TC(tp, chroot_err); + ATF_TP_ADD_TC(tp, chroot_perm); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, fchroot_basic); + ATF_TP_ADD_TC(tp, fchroot_err); + ATF_TP_ADD_TC(tp, fchroot_perm); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c new file mode 100644 index 0000000..a319b09 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c @@ -0,0 +1,213 @@ +/* $NetBSD: t_clock_gettime.c,v 1.3 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Frank Kardel. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c) 2006 Frank Kardel + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_clock_gettime.c,v 1.3 2017/01/13 21:30:41 christos Exp $"); + +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "h_macros.h" + +#define MINPOSDIFF 15000000 /* 15 ms for now */ +#define TIMEOUT 5 + +#define TC_HARDWARE "kern.timecounter.hardware" +#define TC_CHOICE "kern.timecounter.choice" + +static void +check_timecounter(void) +{ + struct timespec tsa, tsb, tsl, res; + long long mindiff = INTMAX_MAX; + time_t endlimit; + +#define CL(x) \ + do { \ + if ((x) != -1) \ + break; \ + atf_tc_fail_nonfatal("%s: %s", #x, strerror(errno)); \ + return; \ + } while (0) + + CL(clock_gettime(CLOCK_REALTIME, &tsa)); + tsl = tsa; + + CL(time(&endlimit)); + endlimit += TIMEOUT + 1; + + while ((time_t)tsa.tv_sec < endlimit) { + long long diff; + + CL(clock_gettime(CLOCK_REALTIME, &tsb)); + diff = 1000000000LL * (tsb.tv_sec - tsa.tv_sec) + + tsb.tv_nsec - tsa.tv_nsec; + + if (diff > 0 && mindiff > diff) + mindiff = diff; + + if (diff < 0 || diff > MINPOSDIFF) { + long long elapsed; + (void)printf("%stime TSA: 0x%jx.%08jx, TSB: 0x%jx.%08jx, " + "diff = %lld nsec, ", (diff < 0) ? "BAD " : "", + (uintmax_t)tsa.tv_sec, (uintmax_t)tsa.tv_nsec, + (uintmax_t)tsb.tv_sec, (uintmax_t)tsb.tv_nsec, diff); + + elapsed = 1000000000LL * (tsb.tv_sec - tsl.tv_sec) + + tsb.tv_nsec - tsl.tv_nsec; + + + (void)printf("%lld nsec\n", elapsed); + tsl = tsb; + + ATF_CHECK(diff >= 0); + if (diff < 0) + return; + } + + tsa.tv_sec = tsb.tv_sec; + tsa.tv_nsec = tsb.tv_nsec; + } + + if (clock_getres(CLOCK_REALTIME, &res) == 0) { + long long r = res.tv_sec * 1000000000 + res.tv_nsec; + + (void)printf("Claimed resolution: %lld nsec (%f Hz) or " + "better\n", r, 1.0 / r * 1e9); + (void)printf("Observed minimum non zero delta: %lld " + "nsec\n", mindiff); + } + +#undef CL +} + +ATF_TC(clock_gettime_real); +ATF_TC_HEAD(clock_gettime_real, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); + atf_tc_set_md_var(tc, "descr", + "Checks the monotonicity of the CLOCK_REALTIME implementation"); + atf_tc_set_md_var(tc, "timeout", "300"); +} + +ATF_TC_BODY(clock_gettime_real, tc) +{ + char name[128], cbuf[512], ctrbuf[10240]; + size_t cbufsiz = sizeof(cbuf); + size_t ctrbufsiz = sizeof(ctrbuf); + const char *p; + char *save; + int quality, n; + + if (sysctlbyname(TC_HARDWARE, cbuf, &cbufsiz, NULL, 0) != 0) { + (void)printf("\nChecking legacy time implementation " + "for %d seconds\n", TIMEOUT); + check_timecounter(); + return; + /* NOTREACHED */ + } + (void)printf("%s = %s\n", TC_HARDWARE, cbuf); + REQUIRE_LIBC(save = strdup(cbuf), NULL); + + RL(sysctlbyname(TC_CHOICE, ctrbuf, &ctrbufsiz, NULL, 0)); + (void)printf("%s = %s\n", TC_CHOICE, ctrbuf); + + for (p = ctrbuf, n = 0; sscanf(p, "%127[^(](q=%d, f=%*u Hz)%*[ ]%n", + name, &quality, &n) == 2; p += n) { + struct timespec ts; + int ret; + + if (quality < 0) + continue; + + (void)printf("\nChecking %s for %d seconds\n", name, TIMEOUT); + CHECK_LIBC(ret = sysctlbyname(TC_HARDWARE, NULL, 0, + name, strlen(name)), -1); + if (ret == -1) + continue; + + /* wait a bit to select new counter in clockinterrupt */ + ts.tv_sec = 0; + ts.tv_nsec = 100000000; + (void)nanosleep(&ts, NULL); + + check_timecounter(); + } + + RL(sysctlbyname(TC_HARDWARE, NULL, 0, save, strlen(save))); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clock_gettime_real); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clock_nanosleep.c b/contrib/netbsd-tests/lib/libc/sys/t_clock_nanosleep.c new file mode 100644 index 0000000..7437778 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_clock_nanosleep.c @@ -0,0 +1,67 @@ +/* $NetBSD: t_clock_nanosleep.c,v 1.1 2016/11/11 15:30:44 njoly Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_clock_nanosleep.c,v 1.1 2016/11/11 15:30:44 njoly Exp $"); + +#include +#include + +ATF_TC(clock_nanosleep_remain); +ATF_TC_HEAD(clock_nanosleep_remain, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Check clock_nanosleep(2) remaining time"); +} + +ATF_TC_BODY(clock_nanosleep_remain, tc) +{ + struct timespec rqtp, rmtp; + + rqtp.tv_sec = 0; rqtp.tv_nsec = 0; + rmtp.tv_sec = -1; rmtp.tv_nsec = -1; + ATF_REQUIRE(clock_nanosleep(CLOCK_REALTIME, 0, &rqtp, &rmtp) == 0); +#ifdef __FreeBSD__ + ATF_CHECK(rmtp.tv_sec == -1 && rmtp.tv_nsec == -1); +#else + ATF_CHECK(rmtp.tv_sec == 0 && rmtp.tv_nsec == 0); +#endif + + ATF_REQUIRE(clock_gettime(CLOCK_REALTIME, &rqtp) == 0); + rmtp.tv_sec = -1; rmtp.tv_nsec = -1; + ATF_REQUIRE(clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &rqtp, &rmtp) == 0); + ATF_CHECK(rmtp.tv_sec == -1 && rmtp.tv_nsec == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clock_nanosleep_remain); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clone.c b/contrib/netbsd-tests/lib/libc/sys/t_clone.c new file mode 100644 index 0000000..ea33f32 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_clone.c @@ -0,0 +1,252 @@ +/* $NetBSD: t_clone.c,v 1.3 2011/12/12 20:55:44 joerg Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_clone.c,v 1.3 2011/12/12 20:55:44 joerg Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define STACKSIZE (8 * 1024) +#define FROBVAL 41973 +#define CHILDEXIT 0xa5 + +static int +dummy(void *arg) +{ + + return 0; +} + +static int +clone_func(void *arg) +{ + long *frobp = arg, diff; + + printf("child: stack ~= %p, frobme = %p\n", &frobp, frobp); + fflush(stdout); + + if (frobp[0] != getppid()) + return 1; + + if (frobp[0] == getpid()) + return 2; + + diff = labs(frobp[1] - (long) &frobp); + + if (diff > 1024) + return 3; + + frobp[1] = FROBVAL; + + return (CHILDEXIT); +} + +ATF_TC(clone_basic); +ATF_TC_HEAD(clone_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks clone(2)"); +} + +ATF_TC_BODY(clone_basic, tc) +{ + sigset_t mask; + void *allocstack, *stack; + pid_t pid; + volatile long frobme[2]; + int stat; + + allocstack = mmap(NULL, STACKSIZE, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE|MAP_ANON, -1, (off_t) 0); + + ATF_REQUIRE_ERRNO(errno, allocstack != MAP_FAILED); + + stack = allocstack; +#ifndef __MACHINE_STACK_GROWS_UP + stack = (char *)stack + STACKSIZE; +#endif + + printf("parent: stack = %p, frobme = %p\n", stack, frobme); + fflush(stdout); + + frobme[0] = (long)getpid(); + frobme[1] = (long)stack; + + sigemptyset(&mask); + sigaddset(&mask, SIGUSR1); + + ATF_REQUIRE_ERRNO(errno, sigprocmask(SIG_BLOCK, &mask, NULL) != -1); + + switch (pid = __clone(clone_func, stack, + CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGUSR1, + __UNVOLATILE(frobme))) { + case 0: + atf_tc_fail("clone() returned 0"); + /*NOTREACHED*/ + case -1: + atf_tc_fail("clone() failed: %s", strerror(errno)); + /*NOTREACHED*/ + default: + while (waitpid(pid, &stat, __WCLONE) != pid) + continue; + } + + ATF_REQUIRE_MSG(WIFEXITED(stat) != 0, "child didn't exit"); + + printf("parent: childexit = 0x%x, frobme = %ld\n", + WEXITSTATUS(stat), frobme[1]); + + switch (WEXITSTATUS(stat)) { + case CHILDEXIT: + ATF_REQUIRE_EQ(frobme[1], FROBVAL); + break; + case 1: + atf_tc_fail("child: argument does not contain parent's pid"); + /*NOTREACHED*/ + case 2: + atf_tc_fail("child: called in parent's pid"); + /*NOTREACHED*/ + case 3: + atf_tc_fail("child: called with bad stack"); + /*NOTREACHED*/ + default: + atf_tc_fail("child returned unknown code: %d", + WEXITSTATUS(stat)); + /*NOTREACHED*/ + } + + ATF_REQUIRE_ERRNO(errno, munmap(allocstack, STACKSIZE) != -1); +} + +ATF_TC(clone_null_stack); +ATF_TC_HEAD(clone_null_stack, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that clone(2) fails when stack pointer is NULL"); +} + +ATF_TC_BODY(clone_null_stack, tc) +{ + int rv; + + rv = __clone(dummy, NULL, + CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD, NULL); + + ATF_REQUIRE_EQ(rv, -1); + ATF_REQUIRE_EQ(errno, EINVAL); +} + +ATF_TC(clone_null_func); +ATF_TC_HEAD(clone_null_func, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that clone(2) fails when function pointer is NULL"); +} + +ATF_TC_BODY(clone_null_func, tc) +{ + void *allocstack, *stack; + int rv; + + allocstack = mmap(NULL, STACKSIZE, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE|MAP_ANON, -1, (off_t) 0); + ATF_REQUIRE_ERRNO(errno, allocstack != MAP_FAILED); + stack = allocstack; +#ifndef __MACHINE_STACK_GROWS_UP + stack = (char *)stack + STACKSIZE; +#endif + + errno = 0; + rv = __clone(0, stack, + CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD, NULL); + + ATF_REQUIRE_EQ(rv, -1); + ATF_REQUIRE_EQ(errno, EINVAL); + + ATF_REQUIRE_ERRNO(errno, munmap(allocstack, STACKSIZE) != -1); +} + +ATF_TC(clone_out_of_proc); +ATF_TC_HEAD(clone_out_of_proc, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks that clone(2) fails when running out of processes"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(clone_out_of_proc, tc) +{ + struct rlimit rl; + int rv; + + ATF_REQUIRE_ERRNO(errno, getrlimit(RLIMIT_NPROC, &rl) != -1); + + rl.rlim_cur = 0; + rl.rlim_max = 0; + + ATF_REQUIRE_ERRNO(errno, setrlimit(RLIMIT_NPROC, &rl) != -1); + + errno = 0; + rv = __clone(dummy, malloc(10240), + CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD, (void *)&rl); + + ATF_REQUIRE_EQ(rv, -1); + ATF_REQUIRE_EQ(errno, EAGAIN); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, clone_basic); + ATF_TP_ADD_TC(tp, clone_null_stack); + ATF_TP_ADD_TC(tp, clone_null_func); + ATF_TP_ADD_TC(tp, clone_out_of_proc); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_connect.c b/contrib/netbsd-tests/lib/libc/sys/t_connect.c new file mode 100644 index 0000000..a920d3d --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_connect.c @@ -0,0 +1,133 @@ +/* $NetBSD: t_connect.c,v 1.3 2017/01/13 20:09:48 christos Exp $ */ +/* + * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include + +#include +#include + +#include + +ATF_TC(connect_low_port); +ATF_TC_HEAD(connect_low_port, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that low-port allocation " + "works"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(connect_low_port, tc) +{ + struct sockaddr_in sin, sinlist; + int sd, val, slist; + socklen_t slen; + + slist = socket(AF_INET, SOCK_STREAM, 0); + sd = socket(AF_INET, SOCK_STREAM, 0); + + ATF_REQUIRE(sd > 0); + ATF_REQUIRE(slist > 0); + + /* bind listening socket */ + memset(&sinlist, 0, sizeof(sinlist)); + sinlist.sin_family = AF_INET; + sinlist.sin_port = htons(31522); + sinlist.sin_addr.s_addr = inet_addr("127.0.0.1"); + + ATF_REQUIRE_EQ(bind(slist, + (struct sockaddr *)&sinlist, sizeof(sinlist)), 0); + ATF_REQUIRE_EQ(listen(slist, 1), 0); + + val = IP_PORTRANGE_LOW; + if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &val, + sizeof(val)) == -1) + atf_tc_fail("setsockopt failed: %s", strerror(errno)); + + memset(&sin, 0, sizeof(sin)); + + sin.sin_port = htons(31522); + sin.sin_addr.s_addr = inet_addr("127.0.0.1"); + sin.sin_family = AF_INET; + + if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { + int serrno = errno; + atf_tc_fail("connect failed: %s%s", + strerror(serrno), + serrno != EACCES ? "" : + " (see http://mail-index.netbsd.org/" + "source-changes/2007/12/16/0011.html)"); + } + + slen = sizeof(sin); + ATF_REQUIRE_EQ(getsockname(sd, (struct sockaddr *)&sin, &slen), 0); + ATF_REQUIRE_EQ(slen, sizeof(sin)); + ATF_REQUIRE(ntohs(sin.sin_port) <= IPPORT_RESERVEDMAX); + + close(sd); + close(slist); +} + +ATF_TC(connect_foreign_family); +ATF_TC_HEAD(connect_foreign_family, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that connecting a socket " + "with a different address family fails"); +} +ATF_TC_BODY(connect_foreign_family, tc) +{ + struct sockaddr_in addr; + + /* addr.sin_family = AF_UNSPEC = 0 */ + memset(&addr, 0, sizeof(addr)); + + /* + * it is not necessary to initialize sin_{addr,port} since + * those structure members shall not be accessed if connect + * fails correctly. + */ + + int sock = socket(AF_LOCAL, SOCK_STREAM, 0); + ATF_REQUIRE(sock != -1); + + ATF_REQUIRE(-1 == connect(sock, (struct sockaddr *)&addr, sizeof(addr))); + ATF_REQUIRE(EAFNOSUPPORT == errno); + + close(sock); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, connect_low_port); + ATF_TP_ADD_TC(tp, connect_foreign_family); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_dup.c b/contrib/netbsd-tests/lib/libc/sys/t_dup.c new file mode 100644 index 0000000..b1924e4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_dup.c @@ -0,0 +1,402 @@ +/* $NetBSD: t_dup.c,v 1.9 2017/01/13 20:31:53 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_dup.c,v 1.9 2017/01/13 20:31:53 christos Exp $"); + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char path[] = "dup"; +#ifdef __NetBSD__ +static void check_mode(bool, bool, bool); +#endif + +static void +check_mode(bool _dup, bool _dup2, bool _dup3) +{ + int mode[3] = { O_RDONLY, O_WRONLY, O_RDWR }; + int perm[5] = { 0700, 0400, 0600, 0444, 0666 }; + struct stat st, st1; + int fd, fd1, fd2; + size_t i, j; + + /* + * Check that a duplicated descriptor + * retains the mode of the original file. + */ + for (i = 0; i < __arraycount(mode); i++) { + + for (j = 0; j < __arraycount(perm); j++) { + + fd1 = open(path, mode[i] | O_CREAT, perm[j]); + fd2 = open("/etc/passwd", O_RDONLY); + + ATF_REQUIRE(fd1 >= 0); + ATF_REQUIRE(fd2 >= 0); + + if (_dup != false) + fd = dup(fd1); + else if (_dup2 != false) + fd = dup2(fd1, fd2); + else if (_dup3 != false) + fd = dup3(fd1, fd2, O_CLOEXEC); + else { + fd = -1; + } + + ATF_REQUIRE(fd >= 0); + + (void)memset(&st, 0, sizeof(struct stat)); + (void)memset(&st1, 0, sizeof(struct stat)); + + ATF_REQUIRE(fstat(fd, &st) == 0); + ATF_REQUIRE(fstat(fd1, &st1) == 0); + + if (st.st_mode != st1.st_mode) + atf_tc_fail("invalid mode"); + + (void)close(fd); + (void)close(fd1); + (void)close(fd2); + (void)unlink(path); + } + } +} + +ATF_TC(dup2_basic); +ATF_TC_HEAD(dup2_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)"); +} + +ATF_TC_BODY(dup2_basic, tc) +{ + int fd, fd1, fd2; + + fd1 = open("/etc/passwd", O_RDONLY); + fd2 = open("/etc/passwd", O_RDONLY); + + ATF_REQUIRE(fd1 >= 0); + ATF_REQUIRE(fd2 >= 0); + + fd = dup2(fd1, fd2); + ATF_REQUIRE(fd >= 0); + + if (fd != fd2) + atf_tc_fail("invalid descriptor"); + + (void)close(fd); + (void)close(fd1); + + ATF_REQUIRE(close(fd2) != 0); +} + +ATF_TC(dup2_err); +ATF_TC_HEAD(dup2_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of dup2(2)"); +} + +ATF_TC_BODY(dup2_err, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup2(-1, -1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup2(fd, -1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup2(-1, fd) == -1); + + /* + * Note that this should not fail with EINVAL. + */ + ATF_REQUIRE(dup2(fd, fd) != -1); + + (void)close(fd); +} + +ATF_TC(dup2_max); +ATF_TC_HEAD(dup2_max, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test dup2(2) against limits"); +} + +ATF_TC_BODY(dup2_max, tc) +{ + struct rlimit res; + + (void)memset(&res, 0, sizeof(struct rlimit)); + (void)getrlimit(RLIMIT_NOFILE, &res); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup2(STDERR_FILENO, res.rlim_cur + 1) == -1); +} + +ATF_TC_WITH_CLEANUP(dup2_mode); +ATF_TC_HEAD(dup2_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)"); +} + +ATF_TC_BODY(dup2_mode, tc) +{ + check_mode(false, true, false); +} + +ATF_TC_CLEANUP(dup2_mode, tc) +{ + (void)unlink(path); +} + + +ATF_TC(dup3_err); +ATF_TC_HEAD(dup3_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test error conditions of dup3(2) (PR lib/45148)"); +} + +ATF_TC_BODY(dup3_err, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY); + ATF_REQUIRE(fd >= 0); + + errno = 0; +#if defined(__FreeBSD__) || defined(__linux__) + /* + * FreeBSD and linux return EINVAL, because... + * + * [EINVAL] The oldd argument is equal to the newd argument. + */ + ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) == -1); +#else + ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) != -1); +#endif + + errno = 0; +#if defined(__FreeBSD__) || defined(__linux__) + ATF_REQUIRE_ERRNO(EINVAL, dup3(-1, -1, O_CLOEXEC) == -1); + ATF_REQUIRE_ERRNO(EBADF, dup3(fd, -1, O_CLOEXEC) == -1); +#else + ATF_REQUIRE_ERRNO(EBADF, dup3(-1, -1, O_CLOEXEC) == -1); +#endif + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup3(fd, -1, O_CLOEXEC) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup3(-1, fd, O_CLOEXEC) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, dup3(fd, 1, O_NOFOLLOW) == -1); + + (void)close(fd); +} + +ATF_TC(dup3_max); +ATF_TC_HEAD(dup3_max, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test dup3(2) against limits"); +} + +ATF_TC_BODY(dup3_max, tc) +{ + struct rlimit res; + + (void)memset(&res, 0, sizeof(struct rlimit)); + (void)getrlimit(RLIMIT_NOFILE, &res); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup3(STDERR_FILENO, + res.rlim_cur + 1, O_CLOEXEC) == -1); +} + +ATF_TC_WITH_CLEANUP(dup3_mode); +ATF_TC_HEAD(dup3_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of dup3(2)"); +} + +ATF_TC_BODY(dup3_mode, tc) +{ + check_mode(false, false, true); +} + +ATF_TC_CLEANUP(dup3_mode, tc) +{ + (void)unlink(path); +} + +ATF_TC(dup_err); +ATF_TC_HEAD(dup_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of dup(2)"); +} + +ATF_TC_BODY(dup_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, dup(-1) == -1); +} + +ATF_TC_WITH_CLEANUP(dup_max); +ATF_TC_HEAD(dup_max, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test dup(2) against limits"); +} + +ATF_TC_BODY(dup_max, tc) +{ + struct rlimit res; + int *buf, fd, sta; + size_t i, n; + pid_t pid; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Open a temporary file until the + * maximum number of open files is + * reached. Ater that dup(2) family + * should fail with EMFILE. + */ + (void)closefrom(0); + (void)memset(&res, 0, sizeof(struct rlimit)); + + n = 10; + res.rlim_cur = res.rlim_max = n; + if (setrlimit(RLIMIT_NOFILE, &res) != 0) + _exit(EX_OSERR); + + buf = calloc(n, sizeof(int)); + + if (buf == NULL) + _exit(EX_OSERR); + + buf[0] = mkstemp(path); + + if (buf[0] < 0) + _exit(EX_OSERR); + + for (i = 1; i < n; i++) { + + buf[i] = open(path, O_RDONLY); + + if (buf[i] < 0) + _exit(EX_OSERR); + } + + errno = 0; + fd = dup(buf[0]); + + if (fd != -1 || errno != EMFILE) + _exit(EX_DATAERR); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { + + if (WEXITSTATUS(sta) == EX_OSERR) + atf_tc_fail("system call error"); + + if (WEXITSTATUS(sta) == EX_DATAERR) + atf_tc_fail("dup(2) dupped more than RLIMIT_NOFILE"); + + atf_tc_fail("unknown error"); + } + + (void)unlink(path); +} + +ATF_TC_CLEANUP(dup_max, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(dup_mode); +ATF_TC_HEAD(dup_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of dup(2)"); +} + +ATF_TC_BODY(dup_mode, tc) +{ + check_mode(true, false, false); +} + +ATF_TC_CLEANUP(dup_mode, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, dup2_basic); + ATF_TP_ADD_TC(tp, dup2_err); + ATF_TP_ADD_TC(tp, dup2_max); + ATF_TP_ADD_TC(tp, dup2_mode); + ATF_TP_ADD_TC(tp, dup3_err); + ATF_TP_ADD_TC(tp, dup3_max); + ATF_TP_ADD_TC(tp, dup3_mode); + ATF_TP_ADD_TC(tp, dup_err); + ATF_TP_ADD_TC(tp, dup_max); + ATF_TP_ADD_TC(tp, dup_mode); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_fsync.c b/contrib/netbsd-tests/lib/libc/sys/t_fsync.c new file mode 100644 index 0000000..e61ea7e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_fsync.c @@ -0,0 +1,120 @@ +/* $NetBSD: t_fsync.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_fsync.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $"); + +#include +#include +#include +#include +#include +#include + +#include + +ATF_TC(fsync_err); +ATF_TC_HEAD(fsync_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test error conditions of fsync(2) (PR kern/30)"); +} + +ATF_TC_BODY(fsync_err, tc) +{ + int i, fd[2]; + + /* + * The fsync(2) call should fail with EBADF + * when the 'fd' is not a valid descriptor. + */ + for (i = 1; i < 1024; i = i + 128) { + + errno = 0; + + ATF_REQUIRE(fsync(-i) == -1); + ATF_REQUIRE(errno == EBADF); + } + + /* + * On the other hand, EINVAL should follow + * if the operation is not possible with + * the file descriptor. + */ + ATF_REQUIRE(pipe(fd) == 0); + + errno = 0; + + ATF_REQUIRE(fsync(fd[0]) == -1); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + + ATF_REQUIRE(fsync(fd[1]) == -1); + ATF_REQUIRE(errno == EINVAL); + + ATF_REQUIRE(close(fd[0]) == 0); + ATF_REQUIRE(close(fd[1]) == 0); +} + +ATF_TC(fsync_sync); +ATF_TC_HEAD(fsync_sync, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of fsync(2)"); +} + +ATF_TC_BODY(fsync_sync, tc) +{ + char buf[128]; + int fd, i; + + for (i = 0; i < 10; i++) { + + (void)snprintf(buf, sizeof(buf), "t_fsync-%d", i); + + fd = mkstemp(buf); + + ATF_REQUIRE(fd != -1); + ATF_REQUIRE(write(fd, "0", 1) == 1); + ATF_REQUIRE(fsync(fd) == 0); + + ATF_REQUIRE(unlink(buf) == 0); + ATF_REQUIRE(close(fd) == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fsync_err); + ATF_TP_ADD_TC(tp, fsync_sync); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c new file mode 100644 index 0000000..102c79f --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c @@ -0,0 +1,160 @@ +/* $NetBSD: t_getcontext.c,v 1.3 2011/07/14 04:59:14 jruoho Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_getcontext.c,v 1.3 2011/07/14 04:59:14 jruoho Exp $"); + +#include +#include +#include +#include +#include + +#define STACKSZ (10*1024) +#define DEPTH 3 + +static int calls; + +static void +run(int n, ...) +{ + va_list va; + int i, ia; + + ATF_REQUIRE_EQ(n, DEPTH - calls - 1); + + va_start(va, n); +#ifdef __FreeBSD__ +#if defined(__amd64__) + for (i = 0; i < 5; i++) { +#elif defined(__aarch64__) + for (i = 0; i < 7; i++) { +#elif defined(__mips__) + for (i = 0; i < 5; i++) { +#else + for (i = 0; i < 9; i++) { +#endif +#else + for (i = 0; i < 9; i++) { +#endif + ia = va_arg(va, int); + ATF_REQUIRE_EQ(i, ia); + } + va_end(va); + + calls++; +} + +ATF_TC(getcontext_err); +ATF_TC_HEAD(getcontext_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from getcontext(2)"); +} + +ATF_TC_BODY(getcontext_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, getcontext((void *)-1) == -1); +} + +ATF_TC(setcontext_err); +ATF_TC_HEAD(setcontext_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from setcontext(2)"); +} + +ATF_TC_BODY(setcontext_err, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, setcontext((void *)-1) == -1); +} + +ATF_TC(setcontext_link); +ATF_TC_HEAD(setcontext_link, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks get/make/setcontext(), context linking via uc_link(), " + "and argument passing to the new context"); +} + +ATF_TC_BODY(setcontext_link, tc) +{ + ucontext_t uc[DEPTH]; + ucontext_t save; + volatile int i = 0; /* avoid longjmp clobbering */ + + for (i = 0; i < DEPTH; ++i) { + ATF_REQUIRE_EQ(getcontext(&uc[i]), 0); + + uc[i].uc_stack.ss_sp = malloc(STACKSZ); + uc[i].uc_stack.ss_size = STACKSZ; + uc[i].uc_link = (i > 0) ? &uc[i - 1] : &save; + +#ifdef __FreeBSD__ +#if defined(__amd64__) + /* FreeBSD/amd64 only permits up to 6 arguments. */ + makecontext(&uc[i], (void *)run, 6, i, + 0, 1, 2, 3, 4); +#elif defined(__aarch64__) + /* FreeBSD/arm64 only permits up to 8 arguments. */ + makecontext(&uc[i], (void *)run, 8, i, + 0, 1, 2, 3, 4, 5, 6); +#elif defined(__mips__) + /* FreeBSD/mips only permits up to 6 arguments. */ + makecontext(&uc[i], (void *)run, 6, i, + 0, 1, 2, 3, 4); +#else + makecontext(&uc[i], (void *)run, 10, i, + 0, 1, 2, 3, 4, 5, 6, 7, 8); +#endif +#else + makecontext(&uc[i], (void *)run, 10, i, + 0, 1, 2, 3, 4, 5, 6, 7, 8); +#endif + } + + ATF_REQUIRE_EQ(getcontext(&save), 0); + + if (calls == 0) + ATF_REQUIRE_EQ(setcontext(&uc[DEPTH-1]), 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getcontext_err); + ATF_TP_ADD_TC(tp, setcontext_err); + ATF_TP_ADD_TC(tp, setcontext_link); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c b/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c new file mode 100644 index 0000000..7dedca4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c @@ -0,0 +1,174 @@ +/* $NetBSD: t_getgroups.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_getgroups.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include + +#include +#include +#include +#include +#include +#include + +ATF_TC(getgroups_err); +ATF_TC_HEAD(getgroups_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors in getgroups(2)"); +} + +ATF_TC_BODY(getgroups_err, tc) +{ + gid_t gidset[NGROUPS_MAX]; + + errno = 0; + + ATF_REQUIRE(getgroups(10, (gid_t *)-1) == -1); + ATF_REQUIRE(errno == EFAULT); + + errno = 0; + +#ifdef __FreeBSD__ + atf_tc_expect_fail("Reported as kern/189941"); +#endif + ATF_REQUIRE(getgroups(-1, gidset) == -1); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC(getgroups_getgid); +ATF_TC_HEAD(getgroups_getgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getgid(2) from getgroups(2)"); +} + +ATF_TC_BODY(getgroups_getgid, tc) +{ + gid_t gidset[NGROUPS_MAX]; + gid_t gid = getgid(); + int i, n; + + /* + * Check that getgid(2) is found from + * the GIDs returned by getgroups(2). + */ + n = getgroups(NGROUPS_MAX, gidset); + + for (i = 0; i < n; i++) { + + if (gidset[i] == gid) + return; + } + + atf_tc_fail("getgid(2) not found from getgroups(2)"); +} + +ATF_TC(getgroups_setgid); +ATF_TC_HEAD(getgroups_setgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setgid(2) from getgroups(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(getgroups_setgid, tc) +{ + gid_t gidset[NGROUPS_MAX]; + int i, n, rv, sta; + pid_t pid; + + /* + * Check that we can setgid(2) + * to the returned group IDs. + */ + n = getgroups(NGROUPS_MAX, gidset); + ATF_REQUIRE(n >= 0); + + for (i = 0; i < n; i++) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + rv = setgid(gidset[i]); + + if (rv != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("getgroups(2) is inconsistent"); + } +} + +ATF_TC(getgroups_zero); +ATF_TC_HEAD(getgroups_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getgroups(2) with zero param"); +} + +ATF_TC_BODY(getgroups_zero, tc) +{ + const gid_t val = 123456789; + gid_t gidset[NGROUPS_MAX]; + size_t i; + + /* + * If the first parameter is zero, the number + * of groups should be returned but the supplied + * buffer should remain intact. + */ + for (i = 0; i < __arraycount(gidset); i++) + gidset[i] = val; + + ATF_REQUIRE(getgroups(0, gidset) >= 0); + + for (i = 0; i < __arraycount(gidset); i++) { + + if (gidset[i] != val) + atf_tc_fail("getgroups(2) modified the buffer"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getgroups_err); + ATF_TP_ADD_TC(tp, getgroups_getgid); + ATF_TP_ADD_TC(tp, getgroups_setgid); + ATF_TP_ADD_TC(tp, getgroups_zero); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c b/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c new file mode 100644 index 0000000..0e4e7b6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c @@ -0,0 +1,216 @@ +/* $NetBSD: t_getitimer.c,v 1.2 2012/03/22 18:20:46 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_getitimer.c,v 1.2 2012/03/22 18:20:46 christos Exp $"); + +#include + +#include +#include +#include +#include +#include +#include + +static bool fail; +static void sighandler(int); + +static void +sighandler(int signo) +{ + + if (signo == SIGALRM || signo == SIGVTALRM) + fail = false; +} + +ATF_TC(getitimer_empty); +ATF_TC_HEAD(getitimer_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", "getitimer(2) before setitimer(2)"); +} + +ATF_TC_BODY(getitimer_empty, tc) +{ + struct itimerval it; + + /* + * Verify that the passed structure remains + * empty after calling getitimer(2) but before + * actually arming the timer with setitimer(2). + */ + (void)memset(&it, 0, sizeof(struct itimerval)); + + ATF_REQUIRE(getitimer(ITIMER_REAL, &it) == 0); + + if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0) + goto fail; + + ATF_REQUIRE(getitimer(ITIMER_VIRTUAL, &it) == 0); + + if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0) + goto fail; + + ATF_REQUIRE(getitimer(ITIMER_PROF, &it) == 0); + + if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0) + goto fail; + + return; + +fail: + atf_tc_fail("getitimer(2) modfied the timer before it was armed"); +} + +ATF_TC(getitimer_err); +ATF_TC_HEAD(getitimer_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from getitimer(2)"); +} + +ATF_TC_BODY(getitimer_err, tc) +{ + struct itimerval it; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, getitimer(-1, &it) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, getitimer(INT_MAX, &it) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, getitimer(ITIMER_REAL, (void *)-1) == -1); +} + +ATF_TC(setitimer_basic); +ATF_TC_HEAD(setitimer_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of setitimer(2)"); +} + +ATF_TC_BODY(setitimer_basic, tc) +{ + struct itimerval it; + + it.it_value.tv_sec = 0; + it.it_value.tv_usec = 100; + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + + fail = true; + + ATF_REQUIRE(signal(SIGALRM, sighandler) != SIG_ERR); + ATF_REQUIRE(setitimer(ITIMER_REAL, &it, NULL) == 0); + + /* + * Although the interaction between + * setitimer(2) and sleep(3) can be + * unspecified, it is assumed that one + * second suspension will be enough for + * the timer to fire. + */ + (void)sleep(1); + + if (fail != false) + atf_tc_fail("timer did not fire"); +} + +ATF_TC(setitimer_err); +ATF_TC_HEAD(setitimer_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from setitimer(2)" + " (PR standards/44927)"); +} + +ATF_TC_BODY(setitimer_err, tc) +{ + struct itimerval it, ot; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, setitimer(-1, &it, &ot) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, setitimer(INT_MAX, &it, &ot) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, setitimer(ITIMER_REAL,(void*)-1, &ot) == -1); +} + +ATF_TC(setitimer_old); +ATF_TC_HEAD(setitimer_old, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test old values from setitimer(2)"); +} + +ATF_TC_BODY(setitimer_old, tc) +{ + struct itimerval it, ot; + + /* + * Make two calls; the second one + * should store the old values. + */ + it.it_value.tv_sec = 4; + it.it_value.tv_usec = 3; + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + + ATF_REQUIRE(setitimer(ITIMER_REAL, &it, &ot) == 0); + + it.it_value.tv_sec = 2; + it.it_value.tv_usec = 1; + + it.it_interval.tv_sec = 0; + it.it_interval.tv_usec = 0; + + ATF_REQUIRE(setitimer(ITIMER_REAL, &it, &ot) == 0); + +#ifdef __FreeBSD__ + if (ot.it_value.tv_sec == 4 && ot.it_value.tv_usec == 3) + atf_tc_fail("setitimer(2) did not return remaining time"); +#else + if (ot.it_value.tv_sec != 4 || ot.it_value.tv_usec != 3) + atf_tc_fail("setitimer(2) did not store old values"); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getitimer_empty); + ATF_TP_ADD_TC(tp, getitimer_err); + ATF_TP_ADD_TC(tp, setitimer_basic); + ATF_TP_ADD_TC(tp, setitimer_err); + ATF_TP_ADD_TC(tp, setitimer_old); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c b/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c new file mode 100644 index 0000000..8c2b199 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c @@ -0,0 +1,237 @@ +/* $NetBSD: t_getlogin.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_getlogin.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include +#include + +#include +#include +#include +#include +#include + +ATF_TC(getlogin_r_err); +ATF_TC_HEAD(getlogin_r_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from getlogin_r(2)"); +} + +ATF_TC_BODY(getlogin_r_err, tc) +{ + char small[0]; + + ATF_REQUIRE(getlogin_r(small, sizeof(small)) == ERANGE); +} + +ATF_TC(getlogin_same); +ATF_TC_HEAD(getlogin_same, tc) +{ + atf_tc_set_md_var(tc, "descr", "getlogin(2) vs. getlogin_r(2)"); +} + +ATF_TC_BODY(getlogin_same, tc) +{ + char buf[MAXLOGNAME]; + char *str; + + str = getlogin(); + + if (str == NULL) + return; + + ATF_REQUIRE(getlogin_r(buf, sizeof(buf)) == 0); + + if (strcmp(str, buf) != 0) + atf_tc_fail("getlogin(2) and getlogin_r(2) differ"); +} + +ATF_TC(setlogin_basic); +ATF_TC_HEAD(setlogin_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that setlogin(2) works"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setlogin_basic, tc) +{ + char *name; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)setsid(); + + if (setlogin("foobar") != 0) + _exit(EXIT_FAILURE); + + name = getlogin(); + + if (name == NULL) + _exit(EXIT_FAILURE); + + if (strcmp(name, "foobar") != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("setlogin(2) failed to set login name"); +} + +ATF_TC(setlogin_err); +ATF_TC_HEAD(setlogin_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from setlogin(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setlogin_err, tc) +{ + char buf[MAXLOGNAME + 1]; + char *name; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + (void)memset(buf, 'x', sizeof(buf)); + + if (pid == 0) { + + (void)setsid(); + + errno = 0; + + if (setlogin(buf) != -1) + _exit(EINVAL); + + if (errno != EINVAL) + _exit(EINVAL); + + errno = 0; + + if (setlogin((void *)-1) != -1) + _exit(EFAULT); + + if (errno != EFAULT) + _exit(EFAULT); + + name = getlogin(); + + if (name == NULL) + _exit(EXIT_FAILURE); + + if (strcmp(name, "foobar") == 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { + + if (WEXITSTATUS(sta) == EFAULT) + atf_tc_fail("expected EFAULT, but the call succeeded"); + + if (WEXITSTATUS(sta) == EINVAL) + atf_tc_fail("expected EINVAL, but the call succeeded"); + + atf_tc_fail("setlogin(2) failed, but login name was set"); + } +} + +ATF_TC(setlogin_perm); +ATF_TC_HEAD(setlogin_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setlogin(2) as normal user"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setlogin_perm, tc) +{ + char *name; + pid_t pid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)setsid(); + + errno = 0; + + if (setlogin("foobar") != -1) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + name = getlogin(); + + if (name == NULL) + _exit(EXIT_FAILURE); + + if (strcmp(name, "foobar") == 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("login name was set as an unprivileged user"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getlogin_r_err); + ATF_TP_ADD_TC(tp, getlogin_same); + ATF_TP_ADD_TC(tp, setlogin_basic); + ATF_TP_ADD_TC(tp, setlogin_err); + ATF_TP_ADD_TC(tp, setlogin_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getpid.c b/contrib/netbsd-tests/lib/libc/sys/t_getpid.c new file mode 100644 index 0000000..b3ed393 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getpid.c @@ -0,0 +1,134 @@ +/* $NetBSD: t_getpid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_getpid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include + +#include +#include +#include + +#include + +static int maxiter = 10; +static void *threadfunc(void *); + +static void * +threadfunc(void *arg) +{ + *(pid_t *)arg = getpid(); + + return NULL; +} + +ATF_TC(getpid_process); +ATF_TC_HEAD(getpid_process, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getpid(2) with processes"); +} + +ATF_TC_BODY(getpid_process, tc) +{ + pid_t ppid, fpid, cpid, tpid, wpid; + int i, sta; + + for (i = 0; i < maxiter; i++) { + + tpid = getpid(); + fpid = fork(); + + ATF_REQUIRE(fpid >= 0); + + if (fpid == 0) { + + cpid = getpid(); + ppid = getppid(); + + if (tpid != ppid) + _exit(EXIT_FAILURE); + + if (cpid == ppid) + _exit(EXIT_FAILURE); + + if (tpid == fpid) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + wpid = wait(&sta); + + if (wpid != fpid) + atf_tc_fail("PID mismatch"); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + + if (WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("PID mismatch"); + } +} + +ATF_TC(getpid_thread); +ATF_TC_HEAD(getpid_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getpid(2) with threads"); +} + +ATF_TC_BODY(getpid_thread, tc) +{ + pid_t pid, tpid; + pthread_t tid; + int i, rv; + + for (i = 0; i < maxiter; i++) { + + pid = getpid(); + + rv = pthread_create(&tid, NULL, threadfunc, &tpid); + ATF_REQUIRE(rv == 0); + + rv = pthread_join(tid, NULL); + ATF_REQUIRE(rv == 0); + + if (pid != tpid) + atf_tc_fail("Unequal PIDs"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getpid_process); + ATF_TP_ADD_TC(tp, getpid_thread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c new file mode 100644 index 0000000..273fd83 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c @@ -0,0 +1,212 @@ +/* $NetBSD: t_getrusage.c,v 1.5 2017/01/13 20:31:06 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_getrusage.c,v 1.5 2017/01/13 20:31:06 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +static void work(void); +static void sighandler(int); + +static const size_t maxiter = 2000; + +static void +sighandler(int signo __unused) +{ + /* Nothing. */ +} + +#ifdef __FreeBSD__ +#define asm __asm +#endif + +static void +work(void) +{ + size_t n = UINT16_MAX * 10; + + while (n > 0) { +#ifdef __or1k__ + asm volatile("l.nop"); /* Do something. */ +#elif defined(__ia64__) + asm volatile("nop 0"); /* Do something. */ +#else + asm volatile("nop"); /* Do something. */ +#endif + n--; + } +} + +ATF_TC(getrusage_err); +ATF_TC_HEAD(getrusage_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions"); +} + +ATF_TC_BODY(getrusage_err, tc) +{ + struct rusage ru; + + errno = 0; + + ATF_REQUIRE(getrusage(INT_MAX, &ru) != 0); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + + ATF_REQUIRE(getrusage(RUSAGE_SELF, (void *)0) != 0); + ATF_REQUIRE(errno == EFAULT); +} + +ATF_TC(getrusage_sig); +ATF_TC_HEAD(getrusage_sig, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test signal count with getrusage(2)"); +} + +ATF_TC_BODY(getrusage_sig, tc) +{ + struct rusage ru; + const long n = 5; + int i; + + /* + * Test that signals are recorded. + */ + ATF_REQUIRE(signal(SIGUSR1, sighandler) != SIG_ERR); + + for (i = 0; i < n; i++) + ATF_REQUIRE(raise(SIGUSR1) == 0); + + (void)memset(&ru, 0, sizeof(struct rusage)); + ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0); + + if (n != ru.ru_nsignals) + atf_tc_fail("getrusage(2) did not record signals"); +} + +ATF_TC(getrusage_utime_back); +ATF_TC_HEAD(getrusage_utime_back, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test bogus values from getrusage(2)"); +} + +ATF_TC_BODY(getrusage_utime_back, tc) +{ + struct rusage ru1, ru2; + size_t i; + + /* + * Test that two consecutive calls are sane. + */ +#ifdef __NetBSD__ + atf_tc_expect_fail("PR kern/30115"); +#endif + + for (i = 0; i < maxiter; i++) { + + (void)memset(&ru1, 0, sizeof(struct rusage)); + (void)memset(&ru2, 0, sizeof(struct rusage)); + + work(); + + ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru1) == 0); + + work(); + + ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru2) == 0); + + if (timercmp(&ru2.ru_utime, &ru1.ru_utime, <) != 0) + atf_tc_fail("user time went backwards"); + } + +#ifdef __NetBSD__ + atf_tc_fail("anticipated error did not occur"); +#endif +} + +ATF_TC(getrusage_utime_zero); +ATF_TC_HEAD(getrusage_utime_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test zero utime from getrusage(2)"); +} + +ATF_TC_BODY(getrusage_utime_zero, tc) +{ + struct rusage ru; + size_t i; + +#ifdef __FreeBSD__ + atf_tc_skip("this testcase passes/fails sporadically on FreeBSD/i386 " + "@ r273153 (at least)"); +#endif + + /* + * Test that getrusage(2) does not return + * zero user time for the calling process. + * + * See also (duplicate) PR port-amd64/41734. + */ + atf_tc_expect_fail("PR kern/30115"); + + for (i = 0; i < maxiter; i++) { + + work(); + + (void)memset(&ru, 0, sizeof(struct rusage)); + + ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0); + + if (ru.ru_utime.tv_sec == 0 && ru.ru_utime.tv_usec == 0) + atf_tc_fail("zero user time from getrusage(2)"); + } + + atf_tc_fail("anticipated error did not occur"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getrusage_err); + ATF_TP_ADD_TC(tp, getrusage_sig); + ATF_TP_ADD_TC(tp, getrusage_utime_back); + ATF_TP_ADD_TC(tp, getrusage_utime_zero); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getsid.c b/contrib/netbsd-tests/lib/libc/sys/t_getsid.c new file mode 100644 index 0000000..76b54ab --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getsid.c @@ -0,0 +1,119 @@ +/* $NetBSD: t_getsid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_getsid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include + +#include +#include +#include + +#include + +ATF_TC(getsid_current); +ATF_TC_HEAD(getsid_current, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getsid(0)"); +} + +ATF_TC_BODY(getsid_current, tc) +{ + pid_t sid; + + sid = getsid(0); + ATF_REQUIRE(sid != -1); + + if (sid != getsid(getpid())) + atf_tc_fail("getsid(0) did not match the calling process"); +} + +ATF_TC(getsid_err); +ATF_TC_HEAD(getsid_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions in getsid(2)"); +} + +ATF_TC_BODY(getsid_err, tc) +{ + + errno = 0; + + ATF_REQUIRE(getsid(-1) == -1); + ATF_REQUIRE(errno == ESRCH); +} + +ATF_TC(getsid_process); +ATF_TC_HEAD(getsid_process, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test getsid(2) with processes"); +} + +ATF_TC_BODY(getsid_process, tc) +{ + pid_t csid, pid, ppid, sid; + int sta; + + sid = getsid(0); + pid = fork(); + + ATF_REQUIRE(pid >= 0); + ATF_REQUIRE(sid != -1); + + if (pid == 0) { + + csid = getsid(0); + ppid = getppid(); + + if (sid != csid) + _exit(EXIT_FAILURE); + + if (getsid(ppid) != csid) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("invalid session ID"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getsid_current); + ATF_TP_ADD_TC(tp, getsid_err); + ATF_TP_ADD_TC(tp, getsid_process); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getsockname.c b/contrib/netbsd-tests/lib/libc/sys/t_getsockname.c new file mode 100644 index 0000000..01b1f8a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_getsockname.c @@ -0,0 +1,82 @@ +/* $NetBSD: t_getsockname.c,v 1.1 2016/07/30 11:03:54 njoly Exp $ */ +/* + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include + +#include + +ATF_TC(getsockname_unix); + +ATF_TC_HEAD(getsockname_unix, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks getsockname with UNIX domain"); +} + +ATF_TC_BODY(getsockname_unix, tc) +{ + const char *path = "sock.unix"; + int sd; + socklen_t len; + struct sockaddr_un sun; + + sd = socket(AF_UNIX, SOCK_STREAM, 0); + ATF_REQUIRE(sd != -1); + + len = sizeof(sun); + memset(&sun, 0, sizeof(sun)); + ATF_REQUIRE(getsockname(sd, (struct sockaddr *)&sun, &len) != -1); + ATF_CHECK(sun.sun_family == AF_UNIX); + ATF_CHECK(strcmp(sun.sun_path, "") == 0); + + len = sizeof(sun); + memset(&sun, 0, sizeof(sun)); + sun.sun_family = AF_UNIX; + strcpy(sun.sun_path, path); + ATF_REQUIRE(bind(sd, (struct sockaddr *)&sun, len) != -1); + + len = sizeof(sun); + memset(&sun, 0, sizeof(sun)); + ATF_REQUIRE(getsockname(sd, (struct sockaddr *)&sun, &len) != -1); + ATF_CHECK(sun.sun_family == AF_UNIX); + ATF_CHECK(strcmp(sun.sun_path, path) == 0); + + ATF_REQUIRE(close(sd) != -1); + ATF_REQUIRE(unlink(path) != -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, getsockname_unix); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c b/contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c new file mode 100644 index 0000000..4d82a26 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c @@ -0,0 +1,88 @@ +/* $NetBSD: t_gettimeofday.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_gettimeofday.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include + +#include +#include +#include + +ATF_TC(gettimeofday_err); +ATF_TC_HEAD(gettimeofday_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from gettimeofday(2)"); +} + +ATF_TC_BODY(gettimeofday_err, tc) +{ + +#ifdef __NetBSD__ + errno = 0; + + ATF_REQUIRE_ERRNO(EFAULT, gettimeofday((void *)-1, NULL) != 0); +#endif +} + +ATF_TC(gettimeofday_mono); +ATF_TC_HEAD(gettimeofday_mono, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test monotonicity of gettimeofday(2)"); +} + +ATF_TC_BODY(gettimeofday_mono, tc) +{ + static const size_t maxiter = 100; + struct timeval tv1, tv2; + size_t i; + + for (i = 0; i < maxiter; i++) { + + (void)memset(&tv1, 0, sizeof(struct timeval)); + (void)memset(&tv2, 0, sizeof(struct timeval)); + + ATF_REQUIRE(gettimeofday(&tv1, NULL) == 0); + ATF_REQUIRE(gettimeofday(&tv2, NULL) == 0); + + if (timercmp(&tv2, &tv1, <) != 0) + atf_tc_fail("time went backwards"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, gettimeofday_err); + ATF_TP_ADD_TC(tp, gettimeofday_mono); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_issetugid.c b/contrib/netbsd-tests/lib/libc/sys/t_issetugid.c new file mode 100644 index 0000000..b76ba39 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_issetugid.c @@ -0,0 +1,148 @@ +/* $NetBSD: t_issetugid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_issetugid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include + +#include +#include +#include +#include +#include + +static bool check(int (*fuid)(uid_t), int (*fgid)(gid_t)); + +static bool +check(int (*fuid)(uid_t), int (*fgid)(gid_t)) +{ + struct passwd *pw; + pid_t pid; + int sta; + + pw = getpwnam("nobody"); + + if (pw == NULL) + return false; + + pid = fork(); + + if (pid < 0) + return false; + + if (pid == 0) { + + if (fuid != NULL && (*fuid)(pw->pw_uid) != 0) + _exit(EXIT_FAILURE); + + if (fgid != NULL && (*fgid)(pw->pw_gid) != 0) + _exit(EXIT_FAILURE); + + if (issetugid() != 1) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + return false; + + return true; +} + +ATF_TC(issetugid_egid); +ATF_TC_HEAD(issetugid_egid, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), eff. GID"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(issetugid_egid, tc) +{ + + if (check(NULL, setegid) != true) + atf_tc_fail("issetugid(2) failed with effective GID"); +} + +ATF_TC(issetugid_euid); +ATF_TC_HEAD(issetugid_euid, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), eff. UID"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(issetugid_euid, tc) +{ + + if (check(seteuid, NULL) != true) + atf_tc_fail("issetugid(2) failed with effective UID"); +} + +ATF_TC(issetugid_rgid); +ATF_TC_HEAD(issetugid_rgid, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), real GID"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(issetugid_rgid, tc) +{ + + if (check(NULL, setgid) != true) + atf_tc_fail("issetugid(2) failed with real GID"); +} + +ATF_TC(issetugid_ruid); +ATF_TC_HEAD(issetugid_ruid, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), real UID"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(issetugid_ruid, tc) +{ + + if (check(setuid, NULL) != true) + atf_tc_fail("issetugid(2) failed with real UID"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, issetugid_egid); + ATF_TP_ADD_TC(tp, issetugid_euid); + ATF_TP_ADD_TC(tp, issetugid_rgid); + ATF_TP_ADD_TC(tp, issetugid_ruid); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_kevent.c b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c new file mode 100644 index 0000000..5bddea5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c @@ -0,0 +1,198 @@ +/* $NetBSD: t_kevent.c,v 1.7 2015/02/05 13:55:37 isaki Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundatiom + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_kevent.c,v 1.7 2015/02/05 13:55:37 isaki Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __NetBSD__ +#include +#else +#define DRVCTLDEV "/nonexistent" +#endif +#include +#include +#include +#include + +ATF_TC(kevent_zerotimer); +ATF_TC_HEAD(kevent_zerotimer, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that kevent with a 0 timer " + "does not crash the system (PR lib/45618)"); +} + +ATF_TC_BODY(kevent_zerotimer, tc) +{ + struct kevent ev; + int kq; + + ATF_REQUIRE((kq = kqueue()) != -1); + EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 1, 0); + ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) != -1); + ATF_REQUIRE(kevent(kq, NULL, 0, &ev, 1, NULL) == 1); +} + +ATF_TC(kqueue_desc_passing); +ATF_TC_HEAD(kqueue_desc_passing, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that passing a kqueue to " + "another process does not crash the kernel (PR 46463)"); +} + +ATF_TC_BODY(kqueue_desc_passing, tc) +{ + pid_t child; + int s[2], storage, status, kq; + struct cmsghdr *msg; + struct iovec iov; + struct msghdr m; + struct kevent ev; + + ATF_REQUIRE((kq = kqueue()) != -1); + + // atf_tc_skip("crashes kernel (PR 46463)"); + + ATF_REQUIRE(socketpair(AF_LOCAL, SOCK_STREAM, 0, s) != -1); + msg = malloc(CMSG_SPACE(sizeof(int))); + m.msg_iov = &iov; + m.msg_iovlen = 1; + m.msg_name = NULL; + m.msg_namelen = 0; + m.msg_control = msg; + m.msg_controllen = CMSG_SPACE(sizeof(int)); +#ifdef __FreeBSD__ + m.msg_flags = 0; +#endif + + child = fork(); + if (child == 0) { + close(s[0]); + + iov.iov_base = &storage; + iov.iov_len = sizeof(int); + m.msg_iov = &iov; + m.msg_iovlen = 1; + + if (recvmsg(s[1], &m, 0) == -1) + err(1, "child: could not recvmsg"); + + kq = *(int *)CMSG_DATA(msg); + printf("child (pid %d): received kq fd %d\n", getpid(), kq); + exit(0); + } + + close(s[1]); + + iov.iov_base = &storage; + iov.iov_len = sizeof(int); + +#ifdef __FreeBSD__ + msg = CMSG_FIRSTHDR(&m); +#endif + msg->cmsg_level = SOL_SOCKET; + msg->cmsg_type = SCM_RIGHTS; + msg->cmsg_len = CMSG_LEN(sizeof(int)); + +#ifdef __NetBSD__ + *(int *)CMSG_DATA(msg) = kq; +#endif + + EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 1, 0); + ATF_CHECK(kevent(kq, &ev, 1, NULL, 0, NULL) != -1); + + printf("parent (pid %d): sending kq fd %d\n", getpid(), kq); + if (sendmsg(s[0], &m, 0) == -1) { + ATF_REQUIRE_EQ_MSG(errno, EBADF, "errno is %d", errno); + atf_tc_skip("PR kern/46523"); + } + + close(kq); + + waitpid(child, &status, 0); + ATF_CHECK(WIFEXITED(status) && WEXITSTATUS(status)==0); +} + +ATF_TC(kqueue_unsupported_fd); +ATF_TC_HEAD(kqueue_unsupported_fd, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that watching an fd whose" + " type is not supported does not crash the kernel"); +} + +ATF_TC_BODY(kqueue_unsupported_fd, tc) +{ + /* mqueue and semaphore use fnullop_kqueue also */ + int fd, kq; + struct kevent ev; + + fd = open(DRVCTLDEV, O_RDONLY); + if (fd == -1) { + switch (errno) { + case ENOENT: + case ENXIO: + atf_tc_skip("no " DRVCTLDEV " available for testing"); + break; + } + } + ATF_REQUIRE(fd != -1); + ATF_REQUIRE((kq = kqueue()) != -1); + + EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, + NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK| + NOTE_RENAME|NOTE_REVOKE, 0, 0); + + ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) == -1); + ATF_REQUIRE_ERRNO(EOPNOTSUPP, true); + + (void)close(fd); +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, kevent_zerotimer); + ATF_TP_ADD_TC(tp, kqueue_desc_passing); + ATF_TP_ADD_TC(tp, kqueue_unsupported_fd); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_kill.c b/contrib/netbsd-tests/lib/libc/sys/t_kill.c new file mode 100644 index 0000000..2f42862 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_kill.c @@ -0,0 +1,312 @@ +/* $NetBSD: t_kill.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_kill.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); + +#include + +#include +#include +#include +#include +#include +#include + +#include + +ATF_TC(kill_basic); +ATF_TC_HEAD(kill_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that kill(2) works"); +} + +ATF_TC_BODY(kill_basic, tc) +{ + const int sig[] = { SIGHUP, SIGINT, SIGKILL, SIGTERM }; + pid_t pid; + size_t i; + int sta; + + for (i = 0; i < __arraycount(sig); i++) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + switch (pid) { + + case 0: + pause(); + break; + + default: + ATF_REQUIRE(kill(pid, sig[i]) == 0); + } + + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != sig[i]) + atf_tc_fail("kill(2) failed to kill child"); + } +} + +ATF_TC(kill_err); +ATF_TC_HEAD(kill_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of kill(2)"); +} + +ATF_TC_BODY(kill_err, tc) +{ + int rv, sta; + pid_t pid; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + errno = 0; + rv = kill(getpid(), -1); + + if (rv == 0 || errno != EINVAL) + _exit(EINVAL); + + errno = 0; + rv = kill(INT_MAX, SIGUSR1); + + if (rv == 0 || errno != ESRCH) + _exit(ESRCH); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { + + if (WEXITSTATUS(sta) == EINVAL) + atf_tc_fail("expected EINVAL, but kill(2) succeeded"); + + if (WEXITSTATUS(sta) == ESRCH) + atf_tc_fail("expected ESRCH, but kill(2) succeeded"); + + atf_tc_fail("unknown error from kill(2)"); + } +} + +ATF_TC(kill_perm); +ATF_TC_HEAD(kill_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test kill(2) permissions"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(kill_perm, tc) +{ + struct passwd *pw; + pid_t cpid, ppid; + uid_t cuid = 0; + uid_t puid = 0; + int sta; + + /* + * Test that kill(2) fails when called + * for a PID owned by another user. + */ + pw = getpwnam("operator"); + + if (pw != NULL) + cuid = pw->pw_uid; + + pw = getpwnam("nobody"); + + if (pw != NULL) + puid = pw->pw_uid; + + if (cuid == 0 || puid == 0 || cuid == puid) + atf_tc_fail("getpwnam(3) failed"); + + ppid = fork(); + + if (ppid < 0) + _exit(EXIT_FAILURE); + + if (ppid == 0) { + + cpid = fork(); + + if (cpid < 0) + _exit(EXIT_FAILURE); + + if (cpid == 0) { + + if (setuid(cuid) < 0) + _exit(EXIT_FAILURE); + else { + (void)sleep(1); + } + + _exit(EXIT_SUCCESS); + } + + /* + * Try to kill the child after having + * set the real and effective UID. + */ + if (setuid(puid) != 0) + _exit(EXIT_FAILURE); + + errno = 0; + + if (kill(cpid, SIGKILL) == 0) + _exit(EPERM); + + if (errno != EPERM) + _exit(EPERM); + + (void)waitpid(cpid, &sta, 0); + + _exit(EXIT_SUCCESS); + } + + (void)waitpid(ppid, &sta, 0); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) == EPERM) + atf_tc_fail("killed a process of another user"); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("unknown error from kill(2)"); +} + +ATF_TC(kill_pgrp_neg); +ATF_TC_HEAD(kill_pgrp_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test kill(2) with process group, #2"); +} + +ATF_TC_BODY(kill_pgrp_neg, tc) +{ + const int maxiter = 3; + pid_t cpid, ppid; + int i, sta; + + ppid = fork(); + ATF_REQUIRE(ppid >= 0); + + if (ppid == 0) { + + ATF_REQUIRE(setpgid(0, 0) == 0); + + for (i = 0; i < maxiter; i++) { + + cpid = fork(); + ATF_REQUIRE(cpid >= 0); + + if (cpid == 0) + pause(); + } + + /* + * Test the variant of killpg(3); if the process number + * is negative but not -1, the signal should be sent to + * all processes whose process group ID is equal to the + * absolute value of the process number. + */ + ATF_REQUIRE(kill(-getpgrp(), SIGKILL) == 0); + + (void)sleep(1); + + _exit(EXIT_SUCCESS); + } + + (void)waitpid(ppid, &sta, 0); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("failed to kill(2) a process group"); +} + +ATF_TC(kill_pgrp_zero); +ATF_TC_HEAD(kill_pgrp_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test kill(2) with process group, #1"); +} + +ATF_TC_BODY(kill_pgrp_zero, tc) +{ + const int maxiter = 3; + pid_t cpid, ppid; + int i, sta; + + ppid = fork(); + ATF_REQUIRE(ppid >= 0); + + if (ppid == 0) { + + ATF_REQUIRE(setpgid(0, 0) == 0); + + for (i = 0; i < maxiter; i++) { + + cpid = fork(); + ATF_REQUIRE(cpid >= 0); + + if (cpid == 0) + pause(); + } + + /* + * If the supplied process number is zero, + * the signal should be sent to all processes + * under the current process group. + */ + ATF_REQUIRE(kill(0, SIGKILL) == 0); + + (void)sleep(1); + + _exit(EXIT_SUCCESS); + } + + (void)waitpid(ppid, &sta, 0); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("failed to kill(2) a process group"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, kill_basic); + ATF_TP_ADD_TC(tp, kill_err); + ATF_TP_ADD_TC(tp, kill_perm); + ATF_TP_ADD_TC(tp, kill_pgrp_neg); + ATF_TP_ADD_TC(tp, kill_pgrp_zero); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_link.c b/contrib/netbsd-tests/lib/libc/sys/t_link.c new file mode 100644 index 0000000..a6d894c --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_link.c @@ -0,0 +1,230 @@ +/* $NetBSD: t_link.c,v 1.3 2017/01/13 20:42:36 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_link.c,v 1.3 2017/01/13 20:42:36 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static const char *getpath(void); +static char path[] = "link"; +static const char *pathl; + +static const char * +getpath(void) +{ + static char buf[LINE_MAX]; + + (void)memset(buf, '\0', sizeof(buf)); + + if (getcwd(buf, sizeof(buf)) == NULL) + return NULL; + + (void)strlcat(buf, path, sizeof(buf)); + (void)strlcat(buf, ".link", sizeof(buf)); + + return buf; +} + +ATF_TC_WITH_CLEANUP(link_count); +ATF_TC_HEAD(link_count, tc) +{ + atf_tc_set_md_var(tc, "descr", "link(2) counts are incremented?"); +} + +ATF_TC_BODY(link_count, tc) +{ + struct stat sa, sb; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + pathl = getpath(); + fd = open(path, O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pathl != NULL); + + ATF_REQUIRE(stat(path, &sa) == 0); + ATF_REQUIRE(link(path, pathl) == 0); + ATF_REQUIRE(stat(path, &sb) == 0); + + if (sa.st_nlink != sb.st_nlink - 1) + atf_tc_fail("incorrect link(2) count"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(pathl) == 0); +} + +ATF_TC_CLEANUP(link_count, tc) +{ + (void)unlink(path); + (void)unlink(pathl); +} + +ATF_TC_WITH_CLEANUP(link_err); +ATF_TC_HEAD(link_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of link(2)"); +} + +ATF_TC_BODY(link_err, tc) +{ + char buf[MAXPATHLEN + 1]; + int fd; + + (void)memset(buf, 'x', sizeof(buf)); + + pathl = getpath(); + fd = open(path, O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pathl != NULL); + + errno = 0; + ATF_REQUIRE(link(path, pathl) == 0); + ATF_REQUIRE_ERRNO(EEXIST, link(path, pathl) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, link(buf, "xxx") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, link(path, "/d/c/b/a") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, link("/a/b/c/d", path) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, link("/a/b/c/d", "/d/c/b/a") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, link(path, (const char *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, link((const char *)-1, "xxx") == -1); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(pathl) == 0); +} + +ATF_TC_CLEANUP(link_err, tc) +{ + (void)unlink(path); + (void)unlink(pathl); +} + +ATF_TC(link_perm); +ATF_TC_HEAD(link_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with link(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(link_perm, tc) +{ + int rv; + + errno = 0; + rv = link("/root", "/root.link"); + ATF_REQUIRE_MSG(rv == -1 && (errno == EACCES || errno == EPERM), + "link to a directory did not fail with EPERM or EACCESS; link() " + "returned %d, errno %d", rv, errno); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, + link("/root/.profile", "/root/.profile.link") == -1); +} + +ATF_TC_WITH_CLEANUP(link_stat); +ATF_TC_HEAD(link_stat, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check stat(2) of a linked file"); +} + +ATF_TC_BODY(link_stat, tc) +{ + struct stat sa, sb; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + pathl = getpath(); + fd = open(path, O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pathl != NULL); + + ATF_REQUIRE(link(path, pathl) == 0); + ATF_REQUIRE(stat(path, &sa) == 0); + ATF_REQUIRE(lstat(pathl, &sb) == 0); + + if (sa.st_uid != sb.st_uid) + atf_tc_fail("unequal UIDs"); + + if (sa.st_mode != sb.st_mode) + atf_tc_fail("unequal modes"); + + if (sa.st_ino != sb.st_ino) + atf_tc_fail("unequal inodes"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(pathl) == 0); +} + +ATF_TC_CLEANUP(link_stat, tc) +{ + (void)unlink(path); + (void)unlink(pathl); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, link_count); + ATF_TP_ADD_TC(tp, link_err); + ATF_TP_ADD_TC(tp, link_perm); + ATF_TP_ADD_TC(tp, link_stat); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_listen.c b/contrib/netbsd-tests/lib/libc/sys/t_listen.c new file mode 100644 index 0000000..9f3f9b8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_listen.c @@ -0,0 +1,136 @@ +/* $NetBSD: t_listen.c,v 1.5 2017/01/13 20:41:50 christos Exp $ */ +/* + * Copyright (c) 2007 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include + +#include +#include + +static const char *path = "listen"; + +ATF_TC_WITH_CLEANUP(listen_err); +ATF_TC_HEAD(listen_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks errors from listen(2) (PR standards/46150)"); +} + +ATF_TC_BODY(listen_err, tc) +{ + static const size_t siz = sizeof(struct sockaddr_in); + struct sockaddr_in sina, sinb; + int fda, fdb, fdc; + + (void)memset(&sina, 0, sizeof(struct sockaddr_in)); + (void)memset(&sinb, 0, sizeof(struct sockaddr_in)); + + sina.sin_family = AF_INET; + sina.sin_port = htons(31522); + sina.sin_addr.s_addr = inet_addr("127.0.0.1"); + + sinb.sin_family = AF_INET; + sinb.sin_port = htons(31522); + sinb.sin_addr.s_addr = inet_addr("127.0.0.1"); + + fda = socket(AF_INET, SOCK_STREAM, 0); + fdb = socket(AF_INET, SOCK_STREAM, 0); + fdc = open("listen", O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fda >= 0 && fdb >= 0 && fdc >= 0); + ATF_REQUIRE_ERRNO(ENOTSOCK, listen(fdc, 1) == -1); + + (void)close(fdc); + (void)unlink(path); + + ATF_REQUIRE(bind(fda, (struct sockaddr *)&sina, siz) == 0); + ATF_REQUIRE(listen(fda, 1) == 0); + + /* + * According to IEEE Std 1003.1-2008: if the socket is + * already connected, the call should fail with EINVAL. + */ + ATF_REQUIRE(connect(fdb, (struct sockaddr *)&sinb, siz) == 0); + ATF_REQUIRE_ERRNO(EINVAL, listen(fdb, 1) == -1); + + (void)close(fda); + (void)close(fdb); + + ATF_REQUIRE_ERRNO(EBADF, connect(fdb, + (struct sockaddr *)&sinb, siz) == -1); +} + +ATF_TC_CLEANUP(listen_err, tc) +{ + (void)unlink(path); +} + +ATF_TC(listen_low_port); +ATF_TC_HEAD(listen_low_port, tc) +{ + atf_tc_set_md_var(tc, "descr", "Does low-port allocation work?"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(listen_low_port, tc) +{ + int sd, val; + + sd = socket(AF_INET, SOCK_STREAM, 0); + ATF_REQUIRE_MSG(sd != -1, "socket failed: %s", strerror(errno)); + + val = IP_PORTRANGE_LOW; + if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &val, + sizeof(val)) == -1) + atf_tc_fail("setsockopt failed: %s", strerror(errno)); + + if (listen(sd, 5) == -1) { + int serrno = errno; + atf_tc_fail("listen failed: %s%s", + strerror(serrno), + serrno != EACCES ? "" : + " (see http://mail-index.netbsd.org/" + "source-changes/2007/12/16/0011.html)"); + } + + close(sd); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, listen_err); + ATF_TP_ADD_TC(tp, listen_low_port); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c b/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c new file mode 100644 index 0000000..02545fe --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c @@ -0,0 +1,247 @@ +/* $NetBSD: t_lwp_create.c,v 1.2 2012/05/22 09:23:39 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * This code is partly based on code by Joel Sing + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __alpha__ +#include +#endif +#ifdef __amd64__ +#include +#include +#endif +#ifdef __hppa__ +#include +#endif +#ifdef __i386__ +#include +#include +#endif +#if defined(__m68k__) || defined(__sh3__) || defined __vax__ +#include +#endif + +volatile lwpid_t the_lwp_id = 0; + +static void lwp_main_func(void* arg) +{ + the_lwp_id = _lwp_self(); + _lwp_exit(); +} + +/* + * Hard to document - see usage examples below. + */ +#define INVALID_UCONTEXT(ARCH,NAME,DESC) \ +static void ARCH##_##NAME(ucontext_t *); \ +ATF_TC(lwp_create_##ARCH##_fail_##NAME); \ +ATF_TC_HEAD(lwp_create_##ARCH##_fail_##NAME, tc) \ +{ \ + atf_tc_set_md_var(tc, "descr", "verify rejection of invalid ucontext " \ + "on " #ARCH " due to " DESC); \ +} \ + \ +ATF_TC_BODY(lwp_create_##ARCH##_fail_##NAME, tc) \ +{ \ + ucontext_t uc; \ + lwpid_t lid; \ + int error; \ + \ + getcontext(&uc); \ + uc.uc_flags = _UC_CPU; \ + ARCH##_##NAME(&uc); \ + \ + error = _lwp_create(&uc, 0, &lid); \ + ATF_REQUIRE(error != 0 && errno == EINVAL); \ +} \ +static void ARCH##_##NAME(ucontext_t *uc) \ +{ + + +ATF_TC(lwp_create_works); +ATF_TC_HEAD(lwp_create_works, tc) +{ + atf_tc_set_md_var(tc, "descr", "Verify creation of a lwp and waiting" + " for it to finish"); +} + +ATF_TC_BODY(lwp_create_works, tc) +{ + ucontext_t uc; + lwpid_t lid; + int error; + void *stack; + static const size_t ssize = 16*1024; + + stack = malloc(ssize); + _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); + + error = _lwp_create(&uc, 0, &lid); + ATF_REQUIRE(error == 0); + + error = _lwp_wait(lid, NULL); + ATF_REQUIRE(error == 0); + ATF_REQUIRE(lid == the_lwp_id); +} + +INVALID_UCONTEXT(generic, no_uc_cpu, "not setting cpu registers") + uc->uc_flags &= ~_UC_CPU; +} + +#ifdef __alpha__ +INVALID_UCONTEXT(alpha, pslset, "trying to clear the USERMODE flag") + uc->uc_mcontext.__gregs[_REG_PS] &= ~ALPHA_PSL_USERMODE; +} +INVALID_UCONTEXT(alpha, pslclr, "trying to set a 'must be zero' flag") + uc->uc_mcontext.__gregs[_REG_PS] |= ALPHA_PSL_IPL_HIGH; +} +#endif +#ifdef __amd64__ +INVALID_UCONTEXT(amd64, untouchable_rflags, "forbidden rflags changed") + uc->uc_mcontext.__gregs[_REG_RFLAGS] |= PSL_MBZ; +} +/* + * XXX: add invalid GS/DS selector tests + */ +INVALID_UCONTEXT(amd64, pc_too_high, + "instruction pointer outside userland address space") + uc->uc_mcontext.__gregs[_REG_RIP] = VM_MAXUSER_ADDRESS; +} +#endif +#ifdef __arm__ +INVALID_UCONTEXT(arm, invalid_mode, "psr or r15 set to non-user-mode") + uc->uc_mcontext.__gregs[_REG_PC] |= 0x1f /*PSR_SYS32_MODE*/; + uc->uc_mcontext.__gregs[_REG_CPSR] |= 0x03 /*R15_MODE_SVC*/; +} +#endif +#ifdef __hppa__ +INVALID_UCONTEXT(hppa, invalid_1, "set illegal bits in psw") + uc->uc_mcontext.__gregs[_REG_PSW] |= PSW_MBZ; +} +INVALID_UCONTEXT(hppa, invalid_0, "clear illegal bits in psw") + uc->uc_mcontext.__gregs[_REG_PSW] &= ~PSW_MBS; +} +#endif +#ifdef __i386__ +INVALID_UCONTEXT(i386, untouchable_eflags, "changing forbidden eflags") + uc->uc_mcontext.__gregs[_REG_EFL] |= PSL_IOPL; +} +INVALID_UCONTEXT(i386, priv_escalation, "modifying priviledge level") + uc->uc_mcontext.__gregs[_REG_CS] &= ~SEL_RPL; +} +#endif +#ifdef __m68k__ +INVALID_UCONTEXT(m68k, invalid_ps_bits, + "setting forbidden bits in the ps register") + uc->uc_mcontext.__gregs[_REG_PS] |= (PSL_MBZ|PSL_IPL|PSL_S); +} +#endif +#ifdef __sh3__ +INVALID_UCONTEXT(sh3, modify_userstatic, + "modifying illegal bits in the status register") + uc->uc_mcontext.__gregs[_REG_SR] |= PSL_MD; +} +#endif +#ifdef __sparc__ +INVALID_UCONTEXT(sparc, pc_odd, "mis-aligned instruction pointer") + uc->uc_mcontext.__gregs[_REG_PC] = 0x100002; +} +INVALID_UCONTEXT(sparc, npc_odd, "mis-aligned next instruction pointer") + uc->uc_mcontext.__gregs[_REG_nPC] = 0x100002; +} +INVALID_UCONTEXT(sparc, pc_null, "NULL instruction pointer") + uc->uc_mcontext.__gregs[_REG_PC] = 0; +} +INVALID_UCONTEXT(sparc, npc_null, "NULL next instruction pointer") + uc->uc_mcontext.__gregs[_REG_nPC] = 0; +} +#endif +#ifdef __vax__ +INVALID_UCONTEXT(vax, psl_0, "clearing forbidden bits in psl") + uc->uc_mcontext.__gregs[_REG_PSL] &= ~(PSL_U | PSL_PREVU); +} +INVALID_UCONTEXT(vax, psl_1, "setting forbidden bits in psl") + uc->uc_mcontext.__gregs[_REG_PSL] |= PSL_IPL | PSL_IS; +} +INVALID_UCONTEXT(vax, psl_cm, "setting CM bit in psl") + uc->uc_mcontext.__gregs[_REG_PSL] |= PSL_CM; +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, lwp_create_works); + ATF_TP_ADD_TC(tp, lwp_create_generic_fail_no_uc_cpu); +#ifdef __alpha__ + ATF_TP_ADD_TC(tp, lwp_create_alpha_fail_pslset); + ATF_TP_ADD_TC(tp, lwp_create_alpha_fail_pslclr); +#endif +#ifdef __amd64__ + ATF_TP_ADD_TC(tp, lwp_create_amd64_fail_untouchable_rflags); + ATF_TP_ADD_TC(tp, lwp_create_amd64_fail_pc_too_high); +#endif +#ifdef __arm__ + ATF_TP_ADD_TC(tp, lwp_create_arm_fail_invalid_mode); +#endif +#ifdef __hppa__ + ATF_TP_ADD_TC(tp, lwp_create_hppa_fail_invalid_1); + ATF_TP_ADD_TC(tp, lwp_create_hppa_fail_invalid_0); +#endif +#ifdef __i386__ + ATF_TP_ADD_TC(tp, lwp_create_i386_fail_untouchable_eflags); + ATF_TP_ADD_TC(tp, lwp_create_i386_fail_priv_escalation); +#endif +#ifdef __m68k__ + ATF_TP_ADD_TC(tp, lwp_create_m68k_fail_invalid_ps_bits); +#endif +#ifdef __sh3__ + ATF_TP_ADD_TC(tp, lwp_create_sh3_fail_modify_userstatic); +#endif +#ifdef __sparc__ + ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_pc_odd); + ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_npc_odd); + ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_pc_null); + ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_npc_null); +#endif +#ifdef __vax__ + ATF_TP_ADD_TC(tp, lwp_create_vax_fail_psl_0); + ATF_TP_ADD_TC(tp, lwp_create_vax_fail_psl_1); + ATF_TP_ADD_TC(tp, lwp_create_vax_fail_psl_cm); +#endif + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c b/contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c new file mode 100644 index 0000000..1b28f75 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c @@ -0,0 +1,74 @@ +/* $NetBSD: t_lwp_ctl.c,v 1.2 2012/03/18 06:20:51 jruoho Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_lwp_ctl.c,v 1.2 2012/03/18 06:20:51 jruoho Exp $"); + +#include + +#include +#include +#include +#include + +ATF_TC(lwpctl_counter); +ATF_TC_HEAD(lwpctl_counter, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks lwpctl preemption counter"); +} + +ATF_TC_BODY(lwpctl_counter, tc) +{ + lwpctl_t *lc; + struct timespec ts; + int ctr1, ctr2; + + ATF_REQUIRE(_lwp_ctl(LWPCTL_FEATURE_PCTR, &lc) == 0); + + /* Ensure that preemption is reported. */ + ctr1 = lc->lc_pctr; + (void)printf("pctr = %d\n", ctr1); + ts.tv_nsec = 10*1000000; + ts.tv_sec = 0; + + ATF_REQUIRE(nanosleep(&ts, 0) != -1); + + ctr2 = lc->lc_pctr; + (void)printf("pctr = %d\n", ctr2); + + ATF_REQUIRE_MSG(ctr1 != ctr2, "counters match"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, lwpctl_counter); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mincore.c b/contrib/netbsd-tests/lib/libc/sys/t_mincore.c new file mode 100644 index 0000000..da6cafe --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mincore.c @@ -0,0 +1,342 @@ +/* $NetBSD: t_mincore.c,v 1.10 2017/01/14 20:51:13 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_mincore.c,v 1.10 2017/01/14 20:51:13 christos Exp $"); + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static long page = 0; +static const char path[] = "mincore"; +static size_t check_residency(void *, size_t); + +static size_t +check_residency(void *addr, size_t npgs) +{ + size_t i, resident; + char *vec; + + vec = malloc(npgs); + + ATF_REQUIRE(vec != NULL); + ATF_REQUIRE(mincore(addr, npgs * page, vec) == 0); + + for (i = resident = 0; i < npgs; i++) { + + if (vec[i] != 0) + resident++; + +#if 0 + (void)fprintf(stderr, "page 0x%p is %sresident\n", + (char *)addr + (i * page), vec[i] ? "" : "not "); +#endif + } + + free(vec); + + return resident; +} + +ATF_TC(mincore_err); +ATF_TC_HEAD(mincore_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from mincore(2)"); +} + +ATF_TC_BODY(mincore_err, tc) +{ + char *map, *vec; + + map = mmap(NULL, page, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + vec = malloc(page); + + ATF_REQUIRE(vec != NULL); + ATF_REQUIRE(map != MAP_FAILED); + +#ifdef __NetBSD__ + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, mincore(map, 0, vec) == -1); +#endif + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, mincore(0, page, vec) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, mincore(map, page, (void *)-1) == -1); + + free(vec); + ATF_REQUIRE(munmap(map, page) == 0); +} + +ATF_TC_WITH_CLEANUP(mincore_resid); +ATF_TC_HEAD(mincore_resid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test page residency with mincore(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mincore_resid, tc) +{ + void *addr, *addr2, *addr3, *buf; + size_t npgs = 0, resident; + struct stat st; + int fd, rv; + struct rlimit rlim; + + ATF_REQUIRE(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0); + /* + * Bump the mlock limit to unlimited so the rest of the testcase + * passes instead of failing on the mlock call. + */ + rlim.rlim_max = RLIM_INFINITY; + rlim.rlim_cur = rlim.rlim_max; + ATF_REQUIRE(setrlimit(RLIMIT_MEMLOCK, &rlim) == 0); + + (void)memset(&st, 0, sizeof(struct stat)); + + fd = open(path, O_RDWR | O_CREAT, 0700); + buf = malloc(page * 5); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(buf != NULL); + + rv = write(fd, buf, page * 5); + ATF_REQUIRE(rv >= 0); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(fstat(fd, &st) == 0); + + addr = mmap(NULL, (size_t)st.st_size, PROT_READ, + MAP_FILE | MAP_SHARED, fd, (off_t) 0); + + ATF_REQUIRE(addr != MAP_FAILED); + + (void)close(fd); + + npgs = st.st_size / page; + + if (st.st_size % page != 0) + npgs++; + + (void)check_residency(addr, npgs); + + rv = mlock(addr, npgs * page); + if (rv == -1 && errno == EAGAIN) + atf_tc_skip("hit process resource limits"); + ATF_REQUIRE(munmap(addr, st.st_size) == 0); + + npgs = 128; + +#ifdef __FreeBSD__ + addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, (off_t)0); +#else + addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_WIRED, -1, (off_t)0); +#endif + + if (addr == MAP_FAILED) + atf_tc_skip("could not mmap wired anonymous test area, system " + "might be low on memory"); + +#ifdef __FreeBSD__ + if (mlock(addr, npgs * page) == -1 && errno != ENOMEM) + atf_tc_skip("could not wire anonymous test area, system might " + "be low on memory"); +#endif + ATF_REQUIRE(check_residency(addr, npgs) == npgs); + ATF_REQUIRE(munmap(addr, npgs * page) == 0); + + npgs = 128; + + addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, (off_t)0); + + ATF_REQUIRE(addr != MAP_FAILED); + + /* + * Check that the in-core pages match the locked pages. + */ + ATF_REQUIRE(check_residency(addr, npgs) == 0); + + errno = 0; + if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0 && errno != ENOMEM) + atf_tc_fail("mlockall(2) failed"); + if (errno == ENOMEM) + atf_tc_skip("mlockall() exceeded process resource limits"); + + resident = check_residency(addr, npgs); + if (resident < npgs) + atf_tc_fail("mlockall(MCL_FUTURE) succeeded, still only " + "%zu pages of the newly mapped %zu pages are resident", + resident, npgs); + + addr2 = mmap(NULL, npgs * page, PROT_READ, MAP_ANON, -1, (off_t)0); + addr3 = mmap(NULL, npgs * page, PROT_NONE, MAP_ANON, -1, (off_t)0); + + if (addr2 == MAP_FAILED || addr3 == MAP_FAILED) + atf_tc_skip("could not mmap more anonymous test pages with " + "mlockall(MCL_FUTURE) in effect, system " + "might be low on memory"); + + ATF_REQUIRE(check_residency(addr2, npgs) == npgs); + ATF_REQUIRE(check_residency(addr3, npgs) == 0); + ATF_REQUIRE(mprotect(addr3, npgs * page, PROT_READ) == 0); + ATF_REQUIRE(check_residency(addr, npgs) == npgs); + ATF_REQUIRE(check_residency(addr2, npgs) == npgs); + + (void)munlockall(); + + ATF_REQUIRE(madvise(addr2, npgs * page, MADV_FREE) == 0); +#ifdef __NetBSD__ + ATF_REQUIRE(check_residency(addr2, npgs) == 0); +#endif + + (void)memset(addr, 0, npgs * page); + + ATF_REQUIRE(madvise(addr, npgs * page, MADV_FREE) == 0); +#ifdef __NetBSD__ + ATF_REQUIRE(check_residency(addr, npgs) == 0); +#endif + + (void)munmap(addr, npgs * page); + (void)munmap(addr2, npgs * page); + (void)munmap(addr3, npgs * page); + (void)unlink(path); + free(buf); +} + +ATF_TC_CLEANUP(mincore_resid, tc) +{ + (void)unlink(path); +} + +ATF_TC(mincore_shmseg); +ATF_TC_HEAD(mincore_shmseg, tc) +{ + atf_tc_set_md_var(tc, "descr", "residency of shared memory"); +} + +ATF_TC_BODY(mincore_shmseg, tc) +{ + size_t npgs = 128; + void *addr = NULL; + int shmid; + + shmid = shmget(IPC_PRIVATE, npgs * page, + IPC_CREAT | S_IRUSR | S_IWUSR); + + ATF_REQUIRE(shmid != -1); + + addr = shmat(shmid, NULL, 0); + + ATF_REQUIRE(addr != NULL); + ATF_REQUIRE(check_residency(addr, npgs) == 0); + + (void)memset(addr, 0xff, npgs * page); + + ATF_REQUIRE(check_residency(addr, npgs) == npgs); + ATF_REQUIRE(madvise(addr, npgs * page, MADV_FREE) == 0); + + /* + * NOTE! Even though we have MADV_FREE'd the range, + * there is another reference (the kernel's) to the + * object which owns the pages. In this case, the + * kernel does not simply free the pages, as haphazardly + * freeing pages when there are still references to + * an object can cause data corruption (say, the other + * referencer doesn't expect the pages to be freed, + * and is surprised by the subsequent ZFOD). + * + * Because of this, we simply report the number of + * pages still resident, for information only. + */ + npgs = check_residency(addr, npgs); + + (void)fprintf(stderr, "%zu pages still resident\n", npgs); + + ATF_REQUIRE(shmdt(addr) == 0); + ATF_REQUIRE(shmctl(shmid, IPC_RMID, NULL) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, mincore_err); + ATF_TP_ADD_TC(tp, mincore_resid); + ATF_TP_ADD_TC(tp, mincore_shmseg); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_minherit.c b/contrib/netbsd-tests/lib/libc/sys/t_minherit.c new file mode 100644 index 0000000..0bdf6bc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_minherit.c @@ -0,0 +1,200 @@ +/* $NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +static long page; + +static void * +makemap(int v, int f) { + void *map = mmap(NULL, page, PROT_READ|PROT_WRITE, + MAP_SHARED|MAP_ANON, -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + memset(map, v, page); + if (f != 666) + ATF_REQUIRE(minherit(map, page, f) == 0); + else + ATF_REQUIRE(minherit(map, page, f) == -1); + return map; +} + +ATF_TC(minherit_copy); +ATF_TC_HEAD(minherit_copy, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for MAP_INHERIT_COPY from minherit(2)"); +} + +ATF_TC_BODY(minherit_copy, tc) +{ + void *map1 = makemap(1, MAP_INHERIT_COPY); + void *map2 = makemap(1, MAP_INHERIT_COPY); + switch (fork()) { + default: + ATF_REQUIRE(wait(NULL) != -1); + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + break; + case -1: + ATF_REQUIRE(0); + break; + case 0: + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + memset(map1, 0, page); + exit(0); + } +} + +ATF_TC(minherit_share); +ATF_TC_HEAD(minherit_share, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for MAP_INHERIT_SHARE from minherit(2)"); +} + +ATF_TC_BODY(minherit_share, tc) +{ + void *map1 = makemap(1, MAP_INHERIT_SHARE); + void *map2 = makemap(1, MAP_INHERIT_SHARE); + + switch (fork()) { + default: + ATF_REQUIRE(wait(NULL) != -1); + memset(map2, 0, page); + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + break; + case -1: + ATF_REQUIRE(0); + break; + case 0: + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + memset(map1, 0, page); + exit(0); + } +} + +static void +segv(int n) { + _exit(n); +} + +ATF_TC(minherit_none); +ATF_TC_HEAD(minherit_none, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for MAP_INHERIT_NONE from minherit(2)"); +} + +ATF_TC_BODY(minherit_none, tc) +{ + void *map1 = makemap(0, MAP_INHERIT_NONE); + int status; + + switch (fork()) { + default: + ATF_REQUIRE(wait(&status) != -1); + ATF_REQUIRE(WEXITSTATUS(status) == SIGSEGV); + break; + case -1: + ATF_REQUIRE(0); + break; + case 0: + ATF_REQUIRE(signal(SIGSEGV, segv) != SIG_ERR); + memset(map1, 0, page); + exit(0); + } +} + +ATF_TC(minherit_zero); +ATF_TC_HEAD(minherit_zero, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for MAP_INHERIT_ZERO from minherit(2)"); +} + +ATF_TC_BODY(minherit_zero, tc) +{ + void *map1 = makemap(1, MAP_INHERIT_ZERO); + void *map2 = makemap(0, MAP_INHERIT_SHARE); + + switch (fork()) { + default: + ATF_REQUIRE(wait(NULL) != -1); + memset(map2, 1, page); + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + break; + case -1: + ATF_REQUIRE(0); + break; + case 0: + ATF_REQUIRE(memcmp(map1, map2, page) == 0); + memset(map1, 2, page); + exit(0); + } +} + +ATF_TC(minherit_bad); +ATF_TC_HEAD(minherit_bad, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test for bad minherit(2)"); +} + +ATF_TC_BODY(minherit_bad, tc) +{ + (void)makemap(0, 666); +} + +ATF_TP_ADD_TCS(tp) +{ + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, minherit_copy); + ATF_TP_ADD_TC(tp, minherit_share); + ATF_TP_ADD_TC(tp, minherit_none); + ATF_TP_ADD_TC(tp, minherit_zero); + ATF_TP_ADD_TC(tp, minherit_bad); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mkdir.c b/contrib/netbsd-tests/lib/libc/sys/t_mkdir.c new file mode 100644 index 0000000..d97a20b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mkdir.c @@ -0,0 +1,210 @@ +/* $NetBSD: t_mkdir.c,v 1.2 2011/10/15 07:38:31 jruoho Exp $ */ + +/*- + * Copyright (c) 2008, 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe and Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mkdir.c,v 1.2 2011/10/15 07:38:31 jruoho Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ATF_TC(mkdir_err); +ATF_TC_HEAD(mkdir_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks errors from mkdir(2)"); +} + +ATF_TC_BODY(mkdir_err, tc) +{ + char buf[PATH_MAX + 1]; + int fd; + + (void)memset(buf, 'x', sizeof(buf)); + + fd = open("/etc", O_RDONLY); + + if (fd >= 0) { + + (void)close(fd); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, mkdir("/etc", 0500) == -1); + } + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, mkdir((void *)-1, 0500) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, mkdir(buf, 0500) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, mkdir("/a/b/c/d/e/f/g/h/i/j/k", 0500) == -1); +} + +ATF_TC_WITH_CLEANUP(mkdir_perm); +ATF_TC_HEAD(mkdir_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks permissions with mkdir(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(mkdir_perm, tc) +{ + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, mkdir("/usr/__nonexistent__", 0500) == -1); +} + +ATF_TC_CLEANUP(mkdir_perm, tc) +{ + (void)rmdir("/usr/__nonexistent__"); +} + +ATF_TC_WITH_CLEANUP(mkdir_mode); +ATF_TC_HEAD(mkdir_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that UIDs and GIDs are right " + "for a directory created with mkdir(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mkdir_mode, tc) +{ + static const char *path = "/tmp/mkdir"; + struct stat st_a, st_b; + struct passwd *pw; + pid_t pid; + int sta; + + (void)memset(&st_a, 0, sizeof(struct stat)); + (void)memset(&st_b, 0, sizeof(struct stat)); + + pw = getpwnam("nobody"); + + ATF_REQUIRE(pw != NULL); + ATF_REQUIRE(stat("/tmp", &st_a) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (setuid(pw->pw_uid) != 0) + _exit(EXIT_FAILURE); + + if (mkdir(path, 0500) != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("failed to create '%s'", path); + + ATF_REQUIRE(stat(path, &st_b) == 0); + ATF_REQUIRE(rmdir(path) == 0); + + /* + * The directory's owner ID should be set to the + * effective UID, whereas the group ID should be + * set to that of the parent directory. + */ + if (st_b.st_uid != pw->pw_uid) + atf_tc_fail("invalid UID for '%s'", path); + + if (st_b.st_gid != st_a.st_gid) + atf_tc_fail("GID did not follow the parent directory"); +} + +ATF_TC_CLEANUP(mkdir_mode, tc) +{ + (void)rmdir("/tmp/mkdir"); +} + +ATF_TC(mkdir_trail); +ATF_TC_HEAD(mkdir_trail, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mkdir(2) for trailing slashes"); +} + +ATF_TC_BODY(mkdir_trail, tc) +{ + const char *tests[] = { + /* + * IEEE 1003.1 second ed. 2.2.2.78: + * + * If the pathname refers to a directory, it may also have + * one or more trailing slashes. Multiple successive slashes + * are considered to be the same as one slash. + */ + "dir1/", + "dir2//", + + NULL, + }; + + const char **test; + + for (test = &tests[0]; *test != NULL; ++test) { + + (void)printf("Checking \"%s\"\n", *test); + (void)rmdir(*test); + + ATF_REQUIRE(mkdir(*test, 0777) == 0); + ATF_REQUIRE(rename(*test, "foo") == 0); + ATF_REQUIRE(rename("foo/", *test) == 0); + ATF_REQUIRE(rmdir(*test) == 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mkdir_err); + ATF_TP_ADD_TC(tp, mkdir_perm); + ATF_TP_ADD_TC(tp, mkdir_mode); + ATF_TP_ADD_TC(tp, mkdir_trail); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c b/contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c new file mode 100644 index 0000000..56bc4c8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c @@ -0,0 +1,276 @@ +/* $NetBSD: t_mkfifo.c,v 1.2 2011/11/02 06:04:48 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_mkfifo.c,v 1.2 2011/11/02 06:04:48 jruoho Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char path[] = "fifo"; +static void support(void); + +static void +support(void) +{ + + errno = 0; + + if (mkfifo(path, 0600) == 0) { + ATF_REQUIRE(unlink(path) == 0); + return; + } + + if (errno == EOPNOTSUPP) + atf_tc_skip("the kernel does not support FIFOs"); + else { + atf_tc_fail("mkfifo(2) failed"); + } +} + +ATF_TC_WITH_CLEANUP(mkfifo_block); +ATF_TC_HEAD(mkfifo_block, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that FIFOs block"); +} + +ATF_TC_BODY(mkfifo_block, tc) +{ + int sta, fd = -1; + pid_t pid; + + support(); + + ATF_REQUIRE(mkfifo(path, 0600) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * If we open the FIFO as read-only (write-only), + * the call should block until another process + * opens the FIFO for writing (reading). + */ + fd = open(path, O_RDONLY); + + _exit(EXIT_FAILURE); /* NOTREACHED */ + } + + (void)sleep(1); + + ATF_REQUIRE(kill(pid, SIGKILL) == 0); + + (void)wait(&sta); + + if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL) + atf_tc_fail("FIFO did not block"); + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(mkfifo_block, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mkfifo_err); +ATF_TC_HEAD(mkfifo_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erros from mkfifo(2)"); +} + +ATF_TC_BODY(mkfifo_err, tc) +{ + char buf[PATH_MAX + 1]; + + support(); + + (void)memset(buf, 'x', sizeof(buf)); + ATF_REQUIRE(mkfifo(path, 0600) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, mkfifo((char *)-1, 0600) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, mkfifo("/etc/passwd", 0600) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, mkfifo(path, 0600) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, mkfifo(buf, 0600) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, mkfifo("/a/b/c/d/e/f/g", 0600) == -1); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mkfifo_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mkfifo_nonblock); +ATF_TC_HEAD(mkfifo_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test O_NONBLOCK with FIFOs"); +} + +ATF_TC_BODY(mkfifo_nonblock, tc) +{ + int fd, sta; + pid_t pid; + + support(); + + fd = -1; + ATF_REQUIRE(mkfifo(path, 0600) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * If we open the FIFO as O_NONBLOCK, the O_RDONLY + * call should return immediately, whereas the call + * for write-only should fail with ENXIO. + */ + fd = open(path, O_RDONLY | O_NONBLOCK); + + if (fd >= 0) + _exit(EXIT_SUCCESS); + + (void)pause(); /* NOTREACHED */ + } + + (void)sleep(1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENXIO, open(path, O_WRONLY | O_NONBLOCK) == -1); + + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFSIGNALED(sta) != 0 || WTERMSIG(sta) == SIGKILL) + atf_tc_fail("FIFO blocked for O_NONBLOCK open(2)"); + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(mkfifo_nonblock, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mkfifo_perm); +ATF_TC_HEAD(mkfifo_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with mkfifo(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(mkfifo_perm, tc) +{ + + support(); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, mkfifo("/root/fifo", 0600) == -1); + + ATF_REQUIRE(mkfifo(path, 0600) == 0); + + /* + * For some reason this fails with EFTYPE... + */ + errno = 0; + ATF_REQUIRE_ERRNO(EFTYPE, chmod(path, 1777) == -1); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mkfifo_perm, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mkfifo_stat); +ATF_TC_HEAD(mkfifo_stat, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mkfifo(2) with stat"); +} + +ATF_TC_BODY(mkfifo_stat, tc) +{ + struct stat st; + + support(); + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(mkfifo(path, 0600) == 0); + ATF_REQUIRE(stat(path, &st) == 0); + + if (S_ISFIFO(st.st_mode) == 0) + atf_tc_fail("invalid mode from mkfifo(2)"); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mkfifo_stat, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mkfifo_block); + ATF_TP_ADD_TC(tp, mkfifo_err); + ATF_TP_ADD_TC(tp, mkfifo_nonblock); + ATF_TP_ADD_TC(tp, mkfifo_perm); + ATF_TP_ADD_TC(tp, mkfifo_stat); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mknod.c b/contrib/netbsd-tests/lib/libc/sys/t_mknod.c new file mode 100644 index 0000000..1c5cd9b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mknod.c @@ -0,0 +1,202 @@ +/* $NetBSD: t_mknod.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_mknod.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $"); + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static char path[] = "node"; + +ATF_TC_WITH_CLEANUP(mknod_err); +ATF_TC_HEAD(mknod_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test error conditions of mknod(2) (PR kern/45111)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mknod_err, tc) +{ + char buf[PATH_MAX + 1]; + + (void)memset(buf, 'x', sizeof(buf)); + +#ifndef __FreeBSD__ + /* + * As of FreeBSD 6.0 device nodes may be created in regular file systems but + * such nodes cannot be used to access devices. As a result an invalid dev + * argument is unchecked. + */ + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, mknod(path, S_IFCHR, -1) == -1); +#endif + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, mknod(buf, S_IFCHR, 0) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, mknod((char *)-1, S_IFCHR, 0) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, mknod("/a/b/c/d/e/f/g", S_IFCHR, 0) == -1); +} + +ATF_TC_CLEANUP(mknod_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mknod_exist); +ATF_TC_HEAD(mknod_exist, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test EEXIST from mknod(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mknod_exist, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0) { + + (void)close(fd); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, + mknod("/etc/passwd", S_IFCHR, 0) == -1); + } + + ATF_REQUIRE(mknod(path, S_IFCHR, 0) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EEXIST, mknod(path, S_IFCHR, 0) == -1); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mknod_exist, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mknod_perm); +ATF_TC_HEAD(mknod_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions of mknod(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(mknod_perm, tc) +{ + + errno = 0; + ATF_REQUIRE_ERRNO(EPERM, mknod(path, S_IFCHR, 0) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EPERM, mknod(path, S_IFBLK, 0) == -1); +} + +ATF_TC_CLEANUP(mknod_perm, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mknod_stat); +ATF_TC_HEAD(mknod_stat, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of mknod(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mknod_stat, tc) +{ + struct stat st; + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(mknod(path, S_IFCHR, 0) == 0); + ATF_REQUIRE(stat(path, &st) == 0); + + if (S_ISCHR(st.st_mode) == 0) + atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFCHR)"); + + ATF_REQUIRE(unlink(path) == 0); + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(mknod(path, S_IFBLK, 0) == 0); + ATF_REQUIRE(stat(path, &st) == 0); + + if (S_ISBLK(st.st_mode) == 0) + atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFBLK)"); + + ATF_REQUIRE(unlink(path) == 0); + + (void)memset(&st, 0, sizeof(struct stat)); + +#ifdef __FreeBSD__ + atf_tc_expect_fail("mknod does not allow S_IFREG"); +#endif + ATF_REQUIRE(mknod(path, S_IFREG, 0) == 0); + ATF_REQUIRE(stat(path, &st) == 0); + + if (S_ISREG(st.st_mode) == 0) + atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFREG)"); + + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(mknod_stat, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, mknod_err); + ATF_TP_ADD_TC(tp, mknod_exist); + ATF_TP_ADD_TC(tp, mknod_perm); + ATF_TP_ADD_TC(tp, mknod_stat); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mlock.c b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c new file mode 100644 index 0000000..cd9ad55 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c @@ -0,0 +1,449 @@ +/* $NetBSD: t_mlock.c,v 1.6 2016/08/09 12:02:44 kre Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_mlock.c,v 1.6 2016/08/09 12:02:44 kre Exp $"); + +#ifdef __FreeBSD__ +#include /* NetBSD requires sys/param.h for sysctl(3), unlike FreeBSD */ +#endif +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef __FreeBSD__ +#include +#define _KMEMUSER +#include +#endif + +static long page = 0; + +#ifdef __FreeBSD__ +#define VM_MAX_WIRED "vm.max_wired" + +static void +vm_max_wired_sysctl(int *old_value, int *new_value) +{ + size_t old_len; + size_t new_len = (new_value == NULL ? 0 : sizeof(int)); + + if (old_value == NULL) + printf("Setting the new value to %d\n", *new_value); + else { + ATF_REQUIRE_MSG(sysctlbyname(VM_MAX_WIRED, NULL, &old_len, + new_value, new_len) == 0, + "sysctlbyname(%s) failed: %s", VM_MAX_WIRED, strerror(errno)); + } + + ATF_REQUIRE_MSG(sysctlbyname(VM_MAX_WIRED, old_value, &old_len, + new_value, new_len) == 0, + "sysctlbyname(%s) failed: %s", VM_MAX_WIRED, strerror(errno)); + + if (old_value != NULL) + printf("Saved the old value (%d)\n", *old_value); +} + +static void +set_vm_max_wired(int new_value) +{ + FILE *fp; + int old_value; + + fp = fopen(VM_MAX_WIRED, "w"); + if (fp == NULL) { + atf_tc_skip("could not open %s for writing: %s", + VM_MAX_WIRED, strerror(errno)); + return; + } + + vm_max_wired_sysctl(&old_value, NULL); + + ATF_REQUIRE_MSG(fprintf(fp, "%d", old_value) > 0, + "saving %s failed", VM_MAX_WIRED); + + fclose(fp); + + vm_max_wired_sysctl(NULL, &new_value); +} + +static void +restore_vm_max_wired(void) +{ + FILE *fp; + int saved_max_wired; + + fp = fopen(VM_MAX_WIRED, "r"); + if (fp == NULL) { + perror("fopen failed\n"); + return; + } + + if (fscanf(fp, "%d", &saved_max_wired) != 1) { + perror("fscanf failed\n"); + fclose(fp); + return; + } + + fclose(fp); + printf("old value in %s: %d\n", VM_MAX_WIRED, saved_max_wired); + + if (saved_max_wired == 0) /* This will cripple the test host */ + return; + + vm_max_wired_sysctl(NULL, &saved_max_wired); +} +#endif + +ATF_TC(mlock_clip); +ATF_TC_HEAD(mlock_clip, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test with mlock(2) that UVM only " + "clips if the clip address is within the entry (PR kern/44788)"); +} + +ATF_TC_BODY(mlock_clip, tc) +{ + void *buf; + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + if (page < 1024) + atf_tc_skip("page size too small"); + + for (size_t i = page; i >= 1; i = i - 1024) { + (void)mlock(buf, page - i); + (void)munlock(buf, page - i); + } + + free(buf); +} + +#ifdef __FreeBSD__ +ATF_TC_WITH_CLEANUP(mlock_err); +#else +ATF_TC(mlock_err); +#endif +ATF_TC_HEAD(mlock_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test error conditions in mlock(2) and munlock(2)"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.config", "allow_sysctl_side_effects"); + atf_tc_set_md_var(tc, "require.user", "root"); +#endif +} + +ATF_TC_BODY(mlock_err, tc) +{ +#ifdef __NetBSD__ + unsigned long vmin = 0; + size_t len = sizeof(vmin); +#endif +#if !defined(__aarch64__) && !defined(__riscv__) + void *invalid_ptr; +#endif + int null_errno = ENOMEM; /* error expected for NULL */ + void *buf; + +#ifdef __FreeBSD__ +#ifdef VM_MIN_ADDRESS + if ((uintptr_t)VM_MIN_ADDRESS > 0) + null_errno = EINVAL; /* NULL is not inside user VM */ +#endif + /* Set max_wired really really high to avoid EAGAIN */ + set_vm_max_wired(INT_MAX); +#else + if (sysctlbyname("vm.minaddress", &vmin, &len, NULL, 0) != 0) + atf_tc_fail("failed to read vm.minaddress"); + /* + * Any bad address must return ENOMEM (for lock & unlock) + */ + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, mlock(NULL, page) == -1); + + if (vmin > 0) + null_errno = EINVAL; /* NULL is not inside user VM */ +#endif + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, mlock((char *)0, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, mlock((char *)-1, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, munlock(NULL, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, munlock((char *)0, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, munlock((char *)-1, page) == -1); + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + /* + * unlocking memory that is not locked is an error... + */ + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, munlock(buf, page) == -1); + +/* There is no sbrk on AArch64 and RISC-V */ +#if !defined(__aarch64__) && !defined(__riscv__) + /* + * These are permitted to fail (EINVAL) but do not on NetBSD + */ + ATF_REQUIRE(mlock((void *)(((uintptr_t)buf) + page/3), page/5) == 0); + ATF_REQUIRE(munlock((void *)(((uintptr_t)buf) + page/3), page/5) == 0); + + (void)free(buf); + + /* + * Try to create a pointer to an unmapped page - first after current + * brk will likely do. + */ + invalid_ptr = (void*)(((uintptr_t)sbrk(0)+page) & ~(page-1)); + printf("testing with (hopefully) invalid pointer %p\n", invalid_ptr); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, mlock(invalid_ptr, page) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOMEM, munlock(invalid_ptr, page) == -1); +#endif +} + +#ifdef __FreeBSD__ +ATF_TC_CLEANUP(mlock_err, tc) +{ + + restore_vm_max_wired(); +} +#endif + +ATF_TC(mlock_limits); +ATF_TC_HEAD(mlock_limits, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test system limits with mlock(2)"); +} + +ATF_TC_BODY(mlock_limits, tc) +{ + struct rlimit res; + void *buf; + pid_t pid; + int sta; + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + for (ssize_t i = page; i >= 2; i -= 100) { + + res.rlim_cur = i - 1; + res.rlim_max = i - 1; + + (void)fprintf(stderr, "trying to lock %zd bytes " + "with %zu byte limit\n", i, (size_t)res.rlim_cur); + + if (setrlimit(RLIMIT_MEMLOCK, &res) != 0) + _exit(EXIT_FAILURE); + + errno = 0; + +#ifdef __FreeBSD__ + /* + * NetBSD doesn't conform to POSIX with ENOMEM requirement; + * FreeBSD does. + * + * See: NetBSD PR # kern/48962 for more details. + */ + if (mlock(buf, i) != -1 || errno != ENOMEM) { +#else + if (mlock(buf, i) != -1 || errno != EAGAIN) { +#endif + (void)munlock(buf, i); + _exit(EXIT_FAILURE); + } + } + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("mlock(2) locked beyond system limits"); + + free(buf); +} + +#ifdef __FreeBSD__ +ATF_TC_WITH_CLEANUP(mlock_mmap); +#else +ATF_TC(mlock_mmap); +#endif +ATF_TC_HEAD(mlock_mmap, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mlock(2)-mmap(2) interaction"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.config", "allow_sysctl_side_effects"); + atf_tc_set_md_var(tc, "require.user", "root"); +#endif +} + +ATF_TC_BODY(mlock_mmap, tc) +{ +#ifdef __NetBSD__ + static const int flags = MAP_ANON | MAP_PRIVATE | MAP_WIRED; +#else + static const int flags = MAP_ANON | MAP_PRIVATE; +#endif + void *buf; + +#ifdef __FreeBSD__ + /* Set max_wired really really high to avoid EAGAIN */ + set_vm_max_wired(INT_MAX); +#endif + + /* + * Make a wired RW mapping and check that mlock(2) + * does not fail for the (already locked) mapping. + */ + buf = mmap(NULL, page, PROT_READ | PROT_WRITE, flags, -1, 0); + + ATF_REQUIRE(buf != MAP_FAILED); +#ifdef __FreeBSD__ + /* + * The duplicate mlock call is added to ensure that the call works + * as described above without MAP_WIRED support. + */ + ATF_REQUIRE(mlock(buf, page) == 0); +#endif + ATF_REQUIRE(mlock(buf, page) == 0); + ATF_REQUIRE(munlock(buf, page) == 0); + ATF_REQUIRE(munmap(buf, page) == 0); + ATF_REQUIRE(munlock(buf, page) != 0); + + /* + * But it should be impossible to mlock(2) a PROT_NONE mapping. + */ + buf = mmap(NULL, page, PROT_NONE, flags, -1, 0); + + ATF_REQUIRE(buf != MAP_FAILED); +#ifdef __FreeBSD__ + ATF_REQUIRE_ERRNO(ENOMEM, mlock(buf, page) != 0); +#else + ATF_REQUIRE(mlock(buf, page) != 0); +#endif + ATF_REQUIRE(munmap(buf, page) == 0); +} + +#ifdef __FreeBSD__ +ATF_TC_CLEANUP(mlock_mmap, tc) +{ + + restore_vm_max_wired(); +} +#endif + +#ifdef __FreeBSD__ +ATF_TC_WITH_CLEANUP(mlock_nested); +#else +ATF_TC(mlock_nested); +#endif +ATF_TC_HEAD(mlock_nested, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that consecutive mlock(2) calls succeed"); +#ifdef __FreeBSD__ + atf_tc_set_md_var(tc, "require.config", "allow_sysctl_side_effects"); + atf_tc_set_md_var(tc, "require.user", "root"); +#endif +} + +ATF_TC_BODY(mlock_nested, tc) +{ + const size_t maxiter = 100; + void *buf; + +#ifdef __FreeBSD__ + /* Set max_wired really really high to avoid EAGAIN */ + set_vm_max_wired(INT_MAX); +#endif + + buf = malloc(page); + ATF_REQUIRE(buf != NULL); + + for (size_t i = 0; i < maxiter; i++) + ATF_REQUIRE(mlock(buf, page) == 0); + + ATF_REQUIRE(munlock(buf, page) == 0); + free(buf); +} + +#ifdef __FreeBSD__ +ATF_TC_CLEANUP(mlock_nested, tc) +{ + + restore_vm_max_wired(); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, mlock_clip); + ATF_TP_ADD_TC(tp, mlock_err); + ATF_TP_ADD_TC(tp, mlock_limits); + ATF_TP_ADD_TC(tp, mlock_mmap); + ATF_TP_ADD_TC(tp, mlock_nested); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mmap.c b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c new file mode 100644 index 0000000..8839aea --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c @@ -0,0 +1,590 @@ +/* $NetBSD: t_mmap.c,v 1.12 2017/01/16 16:31:05 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c)2004 YAMAMOTO Takashi, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__RCSID("$NetBSD: t_mmap.c,v 1.12 2017/01/16 16:31:05 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#endif + +static long page = 0; +static char path[] = "mmap"; +static void map_check(void *, int); +static void map_sighandler(int); +static void testloan(void *, void *, char, int); + +#define BUFSIZE (32 * 1024) /* enough size to trigger sosend_loan */ + +static void +map_check(void *map, int flag) +{ + + if (flag != 0) { + ATF_REQUIRE(map == MAP_FAILED); + return; + } + + ATF_REQUIRE(map != MAP_FAILED); + ATF_REQUIRE(munmap(map, page) == 0); +} + +void +testloan(void *vp, void *vp2, char pat, int docheck) +{ + char buf[BUFSIZE]; + char backup[BUFSIZE]; + ssize_t nwritten; + ssize_t nread; + int fds[2]; + int val; + + val = BUFSIZE; + + if (docheck != 0) + (void)memcpy(backup, vp, BUFSIZE); + + if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, fds) != 0) + atf_tc_fail("socketpair() failed"); + + val = BUFSIZE; + + if (setsockopt(fds[1], SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) != 0) + atf_tc_fail("setsockopt() failed, SO_RCVBUF"); + + val = BUFSIZE; + + if (setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)) != 0) + atf_tc_fail("setsockopt() failed, SO_SNDBUF"); + + if (fcntl(fds[0], F_SETFL, O_NONBLOCK) != 0) + atf_tc_fail("fcntl() failed"); + + nwritten = write(fds[0], (char *)vp + page, BUFSIZE - page); + + if (nwritten == -1) + atf_tc_fail("write() failed"); + + /* Break loan. */ + (void)memset(vp2, pat, BUFSIZE); + + nread = read(fds[1], buf + page, BUFSIZE - page); + + if (nread == -1) + atf_tc_fail("read() failed"); + + if (nread != nwritten) + atf_tc_fail("too short read"); + + if (docheck != 0 && memcmp(backup, buf + page, nread) != 0) + atf_tc_fail("data mismatch"); + + ATF_REQUIRE(close(fds[0]) == 0); + ATF_REQUIRE(close(fds[1]) == 0); +} + +static void +map_sighandler(int signo) +{ + _exit(signo); +} + +#ifdef __NetBSD__ +ATF_TC(mmap_block); +ATF_TC_HEAD(mmap_block, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) with a block device"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mmap_block, tc) +{ + static const int mib[] = { CTL_HW, HW_DISKNAMES }; + static const unsigned int miblen = __arraycount(mib); + char *map, *dk, *drives, dev[PATH_MAX]; + size_t len; + int fd = -1; + + atf_tc_skip("The test case causes a panic (PR kern/38889, kern/46592)"); + + ATF_REQUIRE(sysctl(mib, miblen, NULL, &len, NULL, 0) == 0); + drives = malloc(len); + ATF_REQUIRE(drives != NULL); + ATF_REQUIRE(sysctl(mib, miblen, drives, &len, NULL, 0) == 0); + for (dk = strtok(drives, " "); dk != NULL; dk = strtok(NULL, " ")) { + sprintf(dev, _PATH_DEV "%s%c", dk, 'a'+RAW_PART); + fprintf(stderr, "trying: %s\n", dev); + + if ((fd = open(dev, O_RDONLY)) >= 0) { + (void)fprintf(stderr, "using %s\n", dev); + break; + } + } + free(drives); + + if (fd < 0) + atf_tc_skip("failed to find suitable block device"); + + map = mmap(NULL, 4096, PROT_READ, MAP_FILE, fd, 0); + ATF_REQUIRE(map != MAP_FAILED); + + (void)fprintf(stderr, "first byte %x\n", *map); + ATF_REQUIRE(close(fd) == 0); + (void)fprintf(stderr, "first byte %x\n", *map); + + ATF_REQUIRE(munmap(map, 4096) == 0); +} +#endif + +ATF_TC(mmap_err); +ATF_TC_HEAD(mmap_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of mmap(2)"); +} + +ATF_TC_BODY(mmap_err, tc) +{ + size_t addr = SIZE_MAX; + void *map; + + errno = 0; + map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, -1, 0); + + ATF_REQUIRE(map == MAP_FAILED); + ATF_REQUIRE(errno == EBADF); + + errno = 0; + map = mmap(&addr, page, PROT_READ, MAP_FIXED|MAP_PRIVATE, -1, 0); + + ATF_REQUIRE(map == MAP_FAILED); + ATF_REQUIRE(errno == EINVAL); + + errno = 0; + map = mmap(NULL, page, PROT_READ, MAP_ANON|MAP_PRIVATE, INT_MAX, 0); + + ATF_REQUIRE(map == MAP_FAILED); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC_WITH_CLEANUP(mmap_loan); +ATF_TC_HEAD(mmap_loan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test uvm page loanout with mmap(2)"); +} + +ATF_TC_BODY(mmap_loan, tc) +{ + char buf[BUFSIZE]; + char *vp, *vp2; + int fd; + + fd = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(fd >= 0); + + (void)memset(buf, 'x', sizeof(buf)); + (void)write(fd, buf, sizeof(buf)); + + vp = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_PRIVATE, fd, 0); + + ATF_REQUIRE(vp != MAP_FAILED); + + vp2 = vp; + + testloan(vp, vp2, 'A', 0); + testloan(vp, vp2, 'B', 1); + + ATF_REQUIRE(munmap(vp, BUFSIZE) == 0); + + vp = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, fd, 0); + + vp2 = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, fd, 0); + + ATF_REQUIRE(vp != MAP_FAILED); + ATF_REQUIRE(vp2 != MAP_FAILED); + + testloan(vp, vp2, 'E', 1); + + ATF_REQUIRE(munmap(vp, BUFSIZE) == 0); + ATF_REQUIRE(munmap(vp2, BUFSIZE) == 0); +} + +ATF_TC_CLEANUP(mmap_loan, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mmap_prot_1); +ATF_TC_HEAD(mmap_prot_1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #1"); +} + +ATF_TC_BODY(mmap_prot_1, tc) +{ + void *map; + int fd; + + /* + * Open a file write-only and try to + * map it read-only. This should fail. + */ + fd = open(path, O_WRONLY | O_CREAT, 0700); + + if (fd < 0) + return; + + ATF_REQUIRE(write(fd, "XXX", 3) == 3); + + map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0); + map_check(map, 1); + + map = mmap(NULL, 3, PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0); + map_check(map, 0); + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(mmap_prot_1, tc) +{ + (void)unlink(path); +} + +ATF_TC(mmap_prot_2); +ATF_TC_HEAD(mmap_prot_2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #2"); +} + +ATF_TC_BODY(mmap_prot_2, tc) +{ + char buf[2]; + void *map; + pid_t pid; + int sta; + + /* + * Make a PROT_NONE mapping and try to access it. + * If we catch a SIGSEGV, all works as expected. + */ + map = mmap(NULL, page, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR); + ATF_REQUIRE(strlcpy(buf, map, sizeof(buf)) != 0); + } + + (void)wait(&sta); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); + ATF_REQUIRE(munmap(map, page) == 0); +} + +ATF_TC_WITH_CLEANUP(mmap_prot_3); +ATF_TC_HEAD(mmap_prot_3, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #3"); +} + +ATF_TC_BODY(mmap_prot_3, tc) +{ + char buf[2]; + int fd, sta; + void *map; + pid_t pid; + + /* + * Open a file, change the permissions + * to read-only, and try to map it as + * PROT_NONE. This should succeed, but + * the access should generate SIGSEGV. + */ + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) + return; + + ATF_REQUIRE(write(fd, "XXX", 3) == 3); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(chmod(path, 0444) == 0); + + fd = open(path, O_RDONLY); + ATF_REQUIRE(fd != -1); + + map = mmap(NULL, 3, PROT_NONE, MAP_FILE | MAP_SHARED, fd, 0); + ATF_REQUIRE(map != MAP_FAILED); + + pid = fork(); + + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR); + ATF_REQUIRE(strlcpy(buf, map, sizeof(buf)) != 0); + } + + (void)wait(&sta); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); + ATF_REQUIRE(munmap(map, 3) == 0); +} + +ATF_TC_CLEANUP(mmap_prot_3, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mmap_truncate); +ATF_TC_HEAD(mmap_truncate, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) and ftruncate(2)"); +} + +ATF_TC_BODY(mmap_truncate, tc) +{ + char *map; + long i; + int fd; + + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) + return; + + /* + * See that ftruncate(2) works + * while the file is mapped. + */ + ATF_REQUIRE(ftruncate(fd, page) == 0); + + map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_FILE|MAP_PRIVATE, + fd, 0); + ATF_REQUIRE(map != MAP_FAILED); + + for (i = 0; i < page; i++) + map[i] = 'x'; + + ATF_REQUIRE(ftruncate(fd, 0) == 0); + ATF_REQUIRE(ftruncate(fd, page / 8) == 0); + ATF_REQUIRE(ftruncate(fd, page / 4) == 0); + ATF_REQUIRE(ftruncate(fd, page / 2) == 0); + ATF_REQUIRE(ftruncate(fd, page / 12) == 0); + ATF_REQUIRE(ftruncate(fd, page / 64) == 0); + + (void)munmap(map, page); + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(mmap_truncate, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(mmap_truncate_signal); +ATF_TC_HEAD(mmap_truncate_signal, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test mmap(2) ftruncate(2) causing signal"); +} + +ATF_TC_BODY(mmap_truncate_signal, tc) +{ + char *map; + long i; + int fd, sta; + pid_t pid; + +#ifdef __FreeBSD__ + atf_tc_expect_fail("testcase fails with SIGSEGV on FreeBSD; bug # 211924"); +#endif + + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) + return; + + ATF_REQUIRE(write(fd, "foo\n", 5) == 5); + + map = mmap(NULL, page, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0); + ATF_REQUIRE(map != MAP_FAILED); + + sta = 0; + for (i = 0; i < 5; i++) + sta += map[i]; + ATF_REQUIRE(sta == 334); + + ATF_REQUIRE(ftruncate(fd, 0) == 0); + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGBUS, map_sighandler) != SIG_ERR); + ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR); + sta = 0; + for (i = 0; i < page; i++) + sta += map[i]; + /* child never will get this far, but the compiler will + not know, so better use the values calculated to + prevent the access to be optimized out */ + ATF_REQUIRE(i == 0); + ATF_REQUIRE(sta == 0); + (void)munmap(map, page); + (void)close(fd); + return; + } + + (void)wait(&sta); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + if (WEXITSTATUS(sta) == SIGSEGV) + atf_tc_fail("child process got SIGSEGV instead of SIGBUS"); + ATF_REQUIRE(WEXITSTATUS(sta) == SIGBUS); + ATF_REQUIRE(munmap(map, page) == 0); + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(mmap_truncate_signal, tc) +{ + (void)unlink(path); +} + +ATF_TC(mmap_va0); +ATF_TC_HEAD(mmap_va0, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mmap(2) and vm.user_va0_disable"); +} + +ATF_TC_BODY(mmap_va0, tc) +{ + int flags = MAP_ANON | MAP_FIXED | MAP_PRIVATE; + size_t len = sizeof(int); + void *map; + int val; + + /* + * Make an anonymous fixed mapping at zero address. If the address + * is restricted as noted in security(7), the syscall should fail. + */ +#ifdef __FreeBSD__ + if (sysctlbyname("security.bsd.map_at_zero", &val, &len, NULL, 0) != 0) + atf_tc_fail("failed to read security.bsd.map_at_zero"); + val = !val; /* 1 == enable map at zero */ +#endif +#ifdef __NetBSD__ + if (sysctlbyname("vm.user_va0_disable", &val, &len, NULL, 0) != 0) + atf_tc_fail("failed to read vm.user_va0_disable"); +#endif + + map = mmap(NULL, page, PROT_EXEC, flags, -1, 0); + map_check(map, val); + + map = mmap(NULL, page, PROT_READ, flags, -1, 0); + map_check(map, val); + + map = mmap(NULL, page, PROT_WRITE, flags, -1, 0); + map_check(map, val); + + map = mmap(NULL, page, PROT_READ|PROT_WRITE, flags, -1, 0); + map_check(map, val); + + map = mmap(NULL, page, PROT_EXEC|PROT_READ|PROT_WRITE, flags, -1, 0); + map_check(map, val); +} + +ATF_TP_ADD_TCS(tp) +{ + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, mmap_block); +#endif + ATF_TP_ADD_TC(tp, mmap_err); + ATF_TP_ADD_TC(tp, mmap_loan); + ATF_TP_ADD_TC(tp, mmap_prot_1); + ATF_TP_ADD_TC(tp, mmap_prot_2); + ATF_TP_ADD_TC(tp, mmap_prot_3); + ATF_TP_ADD_TC(tp, mmap_truncate); + ATF_TP_ADD_TC(tp, mmap_truncate_signal); + ATF_TP_ADD_TC(tp, mmap_va0); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c new file mode 100644 index 0000000..5dc3eae --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c @@ -0,0 +1,368 @@ +/* $NetBSD: t_mprotect.c,v 1.4 2016/05/28 14:34:49 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_mprotect.c,v 1.4 2016/05/28 14:34:49 christos Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#ifdef __NetBSD__ +#include "../common/exec_prot.h" +#endif + +static long page = 0; +static int pax_global = -1; +static int pax_enabled = -1; +static char path[] = "mmap"; + +static void sighandler(int); +static bool paxinit(void); +static bool paxset(int, int); + +static void +sighandler(int signo) +{ + _exit(signo); +} + +static bool +paxinit(void) +{ + size_t len = sizeof(int); + int rv; + + rv = sysctlbyname("security.pax.mprotect.global", + &pax_global, &len, NULL, 0); + + if (rv != 0) + return false; + + rv = sysctlbyname("security.pax.mprotect.enabled", + &pax_enabled, &len, NULL, 0); + + return rv == 0; +} + +static bool +paxset(int global, int enabled) +{ + size_t len = sizeof(int); + int rv; + + rv = sysctlbyname("security.pax.mprotect.global", + NULL, NULL, &global, len); + + if (rv != 0) + return false; + + rv = sysctlbyname("security.pax.mprotect.enabled", + NULL, NULL, &enabled, len); + + if (rv != 0) + return false; + + return true; +} + + +ATF_TC_WITH_CLEANUP(mprotect_access); +ATF_TC_HEAD(mprotect_access, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test for EACCES from mprotect(2)"); +} + +ATF_TC_BODY(mprotect_access, tc) +{ + int prot[2] = { PROT_NONE, PROT_READ }; + void *map; + size_t i; + int fd; + + fd = open(path, O_RDONLY | O_CREAT); + ATF_REQUIRE(fd >= 0); + + /* + * The call should fail with EACCES if we try to mark + * a PROT_NONE or PROT_READ file/section as PROT_WRITE. + */ + for (i = 0; i < __arraycount(prot); i++) { + + map = mmap(NULL, page, prot[i], MAP_SHARED, fd, 0); + + if (map == MAP_FAILED) + continue; + + errno = 0; + + ATF_REQUIRE(mprotect(map, page, PROT_WRITE) != 0); + ATF_REQUIRE(errno == EACCES); + ATF_REQUIRE(munmap(map, page) == 0); + } + + ATF_REQUIRE(close(fd) == 0); +} + +ATF_TC_CLEANUP(mprotect_access, tc) +{ + (void)unlink(path); +} + +ATF_TC(mprotect_err); +ATF_TC_HEAD(mprotect_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of mprotect(2)"); +} + +ATF_TC_BODY(mprotect_err, tc) +{ + errno = 0; + + ATF_REQUIRE(mprotect((char *)-1, 1, PROT_READ) != 0); + ATF_REQUIRE(errno == EINVAL); +} + +#ifdef __NetBSD__ +ATF_TC(mprotect_exec); +ATF_TC_HEAD(mprotect_exec, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test mprotect(2) executable space protections"); +} + +/* + * Trivial function -- should fit into a page + */ +ATF_TC_BODY(mprotect_exec, tc) +{ + pid_t pid; + void *map; + int sta, xp_support; + + xp_support = exec_prot_support(); + + switch (xp_support) { + case NOTIMPL: + atf_tc_skip( + "Execute protection callback check not implemented"); + break; + case NO_XP: + atf_tc_skip( + "Host does not support executable space protection"); + break; + case PARTIAL_XP: case PERPAGE_XP: default: + break; + } + + if (!paxinit()) + return; + if (pax_enabled == 1 && pax_global == 1) + atf_tc_skip("PaX MPROTECT restrictions enabled"); + + + /* + * Map a page read/write and copy a trivial assembly function inside. + * We will then change the mapping rights: + * - first by setting the execution right, and check that we can + * call the code found in the allocated page. + * - second by removing the execution right. This should generate + * a SIGSEGV on architectures that can enforce --x permissions. + */ + + map = mmap(NULL, page, PROT_WRITE|PROT_READ, MAP_ANON, -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + + memcpy(map, (void *)return_one, + (uintptr_t)return_one_end - (uintptr_t)return_one); + + /* give r-x rights then call code in page */ + ATF_REQUIRE(mprotect(map, page, PROT_EXEC|PROT_READ) == 0); + ATF_REQUIRE(((int (*)(void))map)() == 1); + + /* remove --x right */ + ATF_REQUIRE(mprotect(map, page, PROT_READ) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGSEGV, sighandler) != SIG_ERR); + ATF_CHECK(((int (*)(void))map)() == 1); + _exit(0); + } + + (void)wait(&sta); + + ATF_REQUIRE(munmap(map, page) == 0); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + + switch (xp_support) { + case PARTIAL_XP: + /* Partial protection might fail; skip the test when it does */ + if (WEXITSTATUS(sta) != SIGSEGV) { + atf_tc_skip("Host only supports " + "partial executable space protection"); + } + break; + case PERPAGE_XP: default: + /* Per-page --x protection should not fail */ + ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); + break; + } +} +#endif + +ATF_TC(mprotect_pax); +ATF_TC_HEAD(mprotect_pax, tc) +{ + atf_tc_set_md_var(tc, "descr", "PaX restrictions and mprotect(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mprotect_pax, tc) +{ + const int prot[4] = { PROT_NONE, PROT_READ, PROT_WRITE }; + const char *str = NULL; + void *map; + size_t i; + int rv; + + if (!paxinit() || !paxset(1, 1)) + return; + + /* + * As noted in the original PaX documentation [1], + * the following restrictions should apply: + * + * (1) creating executable anonymous mappings + * + * (2) creating executable/writable file mappings + * + * (3) making a non-executable mapping executable + * + * (4) making an executable/read-only file mapping + * writable except for performing relocations + * on an ET_DYN ELF file (non-PIC shared library) + * + * The following will test only the case (3). + * + * [1] http://pax.grsecurity.net/docs/mprotect.txt + * + * (Sun Apr 3 11:06:53 EEST 2011.) + */ + for (i = 0; i < __arraycount(prot); i++) { + + map = mmap(NULL, page, prot[i], MAP_ANON, -1, 0); + + if (map == MAP_FAILED) + continue; + + rv = mprotect(map, 1, prot[i] | PROT_EXEC); + + (void)munmap(map, page); + + if (rv == 0) { + str = "non-executable mapping made executable"; + goto out; + } + } + +out: + if (pax_global != -1 && pax_enabled != -1) + (void)paxset(pax_global, pax_enabled); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TC(mprotect_write); +ATF_TC_HEAD(mprotect_write, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mprotect(2) write protections"); +} + +ATF_TC_BODY(mprotect_write, tc) +{ + pid_t pid; + void *map; + int sta; + + /* + * Map a page read/write, change the protection + * to read-only with mprotect(2), and try to write + * to the page. This should generate a SIGSEGV. + */ + map = mmap(NULL, page, PROT_WRITE|PROT_READ, MAP_ANON, -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + + ATF_REQUIRE(strlcpy(map, "XXX", 3) == 3); + ATF_REQUIRE(mprotect(map, page, PROT_READ) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + ATF_REQUIRE(signal(SIGSEGV, sighandler) != SIG_ERR); + ATF_REQUIRE(strlcpy(map, "XXX", 3) == 0); + } + + (void)wait(&sta); + + ATF_REQUIRE(WIFEXITED(sta) != 0); + ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV); + ATF_REQUIRE(munmap(map, page) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + ATF_TP_ADD_TC(tp, mprotect_access); + ATF_TP_ADD_TC(tp, mprotect_err); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, mprotect_exec); +#endif + ATF_TP_ADD_TC(tp, mprotect_pax); + ATF_TP_ADD_TC(tp, mprotect_write); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c b/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c new file mode 100644 index 0000000..4c145cc --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c @@ -0,0 +1,367 @@ +/* $NetBSD: t_msgctl.c,v 1.5 2017/01/13 20:44:45 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_msgctl.c,v 1.5 2017/01/13 20:44:45 christos Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MSG_KEY 12345689 +#define MSG_MTYPE_1 0x41 + +struct msg { + long mtype; + char buf[3]; +}; + +static void clean(void); + +static void +clean(void) +{ + int id; + + if ((id = msgget(MSG_KEY, 0)) != -1) + (void)msgctl(id, IPC_RMID, 0); +} + +ATF_TC_WITH_CLEANUP(msgctl_err); +ATF_TC_HEAD(msgctl_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from msgctl(2)"); +} + +ATF_TC_BODY(msgctl_err, tc) +{ + const int cmd[] = { IPC_STAT, IPC_SET, IPC_RMID }; + struct msqid_ds msgds; + size_t i; + int id; + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, msgctl(id, INT_MAX, &msgds) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, msgctl(id, IPC_STAT, (void *)-1) == -1); + + for (i = 0; i < __arraycount(cmd); i++) { + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, msgctl(-1, cmd[i], &msgds) == -1); + } + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_err, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgctl_perm); +ATF_TC_HEAD(msgctl_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with msgctl(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(msgctl_perm, tc) +{ + struct msqid_ds msgds; + struct passwd *pw; + pid_t pid; + int sta; + int id; + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + pw = getpwnam("nobody"); + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + ATF_REQUIRE(id != -1); + ATF_REQUIRE(pw != NULL); + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (setuid(pw->pw_uid) != 0) + _exit(EX_OSERR); + + msgds.msg_perm.uid = getuid(); + msgds.msg_perm.gid = getgid(); + + errno = 0; + + if (msgctl(id, IPC_SET, &msgds) == 0) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + if (msgctl(id, IPC_STAT, &msgds) != 0) + _exit(EX_OSERR); + + msgds.msg_qbytes = 1; + + if (msgctl(id, IPC_SET, &msgds) == 0) + _exit(EXIT_FAILURE); + + if (errno != EPERM) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0) { + + if (WEXITSTATUS(sta) == EX_OSERR) + atf_tc_fail("system call failed"); + + if (WEXITSTATUS(sta) == EXIT_FAILURE) + atf_tc_fail("UID %u manipulated root's " + "message queue", pw->pw_uid); + } + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_perm, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgctl_pid); +ATF_TC_HEAD(msgctl_pid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that PIDs are updated"); +} + +ATF_TC_BODY(msgctl_pid, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msqid_ds msgds; + int id, sta; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + +#ifdef __FreeBSD__ + (void)msgsnd(id, &msg, sizeof(msg.buf), IPC_NOWAIT); +#else + (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT); +#endif + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + (void)wait(&sta); + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + if (pid != msgds.msg_lspid) + atf_tc_fail("the PID of last msgsnd(2) was not updated"); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + (void)msgrcv(id, &msg, + sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + (void)wait(&sta); + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + if (pid != msgds.msg_lrpid) + atf_tc_fail("the PID of last msgrcv(2) was not updated"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_pid, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgctl_set); +ATF_TC_HEAD(msgctl_set, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgctl(2) with IPC_SET"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(msgctl_set, tc) +{ + struct msqid_ds msgds; + struct passwd *pw; + int id; + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + pw = getpwnam("nobody"); + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + ATF_REQUIRE(id != -1); + ATF_REQUIRE(pw != NULL); + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + msgds.msg_perm.uid = pw->pw_uid; + + if (msgctl(id, IPC_SET, &msgds) != 0) + atf_tc_fail("root failed to change the UID of message queue"); + + msgds.msg_perm.uid = getuid(); + msgds.msg_perm.gid = pw->pw_gid; + + if (msgctl(id, IPC_SET, &msgds) != 0) + atf_tc_fail("root failed to change the GID of message queue"); + + /* + * Note: setting the qbytes to zero fails even as root. + */ + msgds.msg_qbytes = 1; + msgds.msg_perm.gid = getgid(); + + if (msgctl(id, IPC_SET, &msgds) != 0) + atf_tc_fail("root failed to change qbytes of message queue"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_set, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgctl_time); +ATF_TC_HEAD(msgctl_time, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that access times are updated"); +} + +ATF_TC_BODY(msgctl_time, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msqid_ds msgds; + time_t t; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + t = time(NULL); + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); +#ifdef __FreeBSD__ + (void)msgsnd(id, &msg, sizeof(msg.buf), IPC_NOWAIT); +#else + (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT); +#endif + (void)msgctl(id, IPC_STAT, &msgds); + + if (llabs(t - msgds.msg_stime) > 1) + atf_tc_fail("time of last msgsnd(2) was not updated"); + + if (msgds.msg_rtime != 0) + atf_tc_fail("time of last msgrcv(2) was updated incorrectly"); + + t = time(NULL); + + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + (void)msgrcv(id, &msg, sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT); + (void)msgctl(id, IPC_STAT, &msgds); + + if (llabs(t - msgds.msg_rtime) > 1) + atf_tc_fail("time of last msgrcv(2) was not updated"); + + /* + * Note: this is non-zero even after the memset(3). + */ + if (msgds.msg_stime == 0) + atf_tc_fail("time of last msgsnd(2) was updated incorrectly"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgctl_time, tc) +{ + clean(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msgctl_err); + ATF_TP_ADD_TC(tp, msgctl_perm); + ATF_TP_ADD_TC(tp, msgctl_pid); + ATF_TP_ADD_TC(tp, msgctl_set); + ATF_TP_ADD_TC(tp, msgctl_time); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgget.c b/contrib/netbsd-tests/lib/libc/sys/t_msgget.c new file mode 100644 index 0000000..e26cde2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgget.c @@ -0,0 +1,292 @@ +/* $NetBSD: t_msgget.c,v 1.2 2014/02/27 00:59:50 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_msgget.c,v 1.2 2014/02/27 00:59:50 joerg Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MSG_KEY 12345689 + +static void clean(void); + +static void +clean(void) +{ + int id; + + if ((id = msgget(MSG_KEY, 0)) != -1) + (void)msgctl(id, IPC_RMID, 0); +} + +ATF_TC_WITH_CLEANUP(msgget_excl); +ATF_TC_HEAD(msgget_excl, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgget(2) with IPC_EXCL"); +} + +ATF_TC_BODY(msgget_excl, tc) +{ + int id; + + /* + * Create a message queue and re-open it with + * O_CREAT and IPC_EXCL set. This should fail. + */ + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + if (id < 0) + atf_tc_fail("failed to create message queue"); + + errno = 0; + + if (msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | 0600) != -1) + atf_tc_fail("msgget(2) failed for IPC_EXCL"); + + ATF_REQUIRE(errno == EEXIST); + + /* + * However, the same call should succeed + * when IPC_EXCL is not set in the flags. + */ + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + if (id < 0) + atf_tc_fail("msgget(2) failed to re-open"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgget_excl, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgget_exit); +ATF_TC_HEAD(msgget_exit, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that XSI message queues are " + "not removed when the process exits"); +} + +ATF_TC_BODY(msgget_exit, tc) +{ + int id, sta; + pid_t pid; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | 0600) == -1) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("failed to create message queue"); + + id = msgget(MSG_KEY, 0); + + if (id == -1) + atf_tc_fail("message queue was removed on process exit"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgget_exit, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgget_init); +ATF_TC_HEAD(msgget_init, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that msgget(2) initializes data structures properly"); +} + +ATF_TC_BODY(msgget_init, tc) +{ + const uid_t uid = geteuid(); + const gid_t gid = getegid(); + struct msqid_ds msgds; + time_t t; + int id; + + (void)memset(&msgds, 0x9, sizeof(struct msqid_ds)); + + t = time(NULL); + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + ATF_REQUIRE(id !=-1); + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + + ATF_CHECK(msgds.msg_qnum == 0); + ATF_CHECK(msgds.msg_lspid == 0); + ATF_CHECK(msgds.msg_lrpid == 0); + ATF_CHECK(msgds.msg_rtime == 0); + ATF_CHECK(msgds.msg_stime == 0); + ATF_CHECK(msgds.msg_perm.uid == uid); + ATF_CHECK(msgds.msg_perm.gid == gid); + ATF_CHECK(msgds.msg_perm.cuid == uid); + ATF_CHECK(msgds.msg_perm.cgid == gid); + ATF_CHECK(msgds.msg_perm.mode == 0600); + + if (llabs(t - msgds.msg_ctime) > 5) + atf_tc_fail("msgget(2) initialized current time incorrectly"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgget_init, tc) +{ + clean(); +} + +ATF_TC(msgget_limit); +ATF_TC_HEAD(msgget_limit, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgget(2) against system limits"); +} + +ATF_TC_BODY(msgget_limit, tc) +{ + size_t len = sizeof(int); + bool fail = false; + int i, lim = 0; + int *buf; + + if (sysctlbyname("kern.ipc.msgmni", &lim, &len, NULL, 0) != 0) + atf_tc_skip("failed to read kern.ipc.msgmni sysctl"); + + buf = calloc(lim + 1, sizeof(*buf)); + ATF_REQUIRE(buf != NULL); + + for (i = 0; i < lim; i++) { + + buf[i] = msgget(MSG_KEY + i, IPC_CREAT | IPC_EXCL | 0600); + + (void)fprintf(stderr, "key[%d] = %d\n", i, buf[i]); + + /* + * This test only works when there are zero existing + * message queues. Thus, bypass the unit test when + * this precondition is not met, for reason or another. + */ + if (buf[i] == -1) + goto out; + } + + i++; + errno = 0; + + buf[i] = msgget(MSG_KEY + i, IPC_CREAT | IPC_EXCL | 0600); + + if (buf[i] != -1 || errno != ENOSPC) + fail = true; + +out: /* Remember to clean-up. */ + for (i = 0; i < lim; i++) + (void)msgctl(buf[i], IPC_RMID, 0); + + free(buf); + + if (fail != false) + atf_tc_fail("msgget(2) opened more than %d queues", lim); +} + +ATF_TC_WITH_CLEANUP(msgget_mode); +ATF_TC_HEAD(msgget_mode, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test different modes with msgget(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(msgget_mode, tc) +{ + static const mode_t mode[] = { + S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR, S_IRWXG, S_IRGRP, + S_IWGRP, S_IXGRP, S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH + }; + + struct msqid_ds msgds; + size_t i; + int id; + + for (i = 0; i < __arraycount(mode); i++) { + + (void)fprintf(stderr, "testing mode %d\n", mode[i]); + (void)memset(&msgds, 0, sizeof(struct msqid_ds)); + + id = msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | (int)mode[i]); + + ATF_REQUIRE(id != -1); + ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0); + ATF_REQUIRE(msgds.msg_perm.mode == mode[i]); + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); + } +} + +ATF_TC_CLEANUP(msgget_mode, tc) +{ + clean(); +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msgget_excl); + ATF_TP_ADD_TC(tp, msgget_exit); + ATF_TP_ADD_TC(tp, msgget_init); + ATF_TP_ADD_TC(tp, msgget_limit); + ATF_TP_ADD_TC(tp, msgget_mode); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c b/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c new file mode 100644 index 0000000..522ceb8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c @@ -0,0 +1,343 @@ +/* $NetBSD: t_msgrcv.c,v 1.4 2017/01/13 20:44:45 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_msgrcv.c,v 1.4 2017/01/13 20:44:45 christos Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MSG_KEY 1234 +#define MSG_MTYPE_1 0x41 +#define MSG_MTYPE_2 0x42 +#define MSG_MTYPE_3 0x43 +#define MSG_LEN 3 + +struct msg { + long mtype; + char buf[MSG_LEN]; +}; + +static void clean(void); + +static void +clean(void) +{ + int id; + + if ((id = msgget(MSG_KEY, 0)) != -1) + (void)msgctl(id, IPC_RMID, 0); +} + +ATF_TC_WITH_CLEANUP(msgrcv_basic); +ATF_TC_HEAD(msgrcv_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of msgrcv(2)"); +} + +ATF_TC_BODY(msgrcv_basic, tc) +{ + struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msg msg2 = { MSG_MTYPE_1, { 'x', 'y', 'z' } }; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT); + (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT); + + ATF_CHECK(msg1.buf[0] == msg2.buf[0]); + ATF_CHECK(msg1.buf[1] == msg2.buf[1]); + ATF_CHECK(msg1.buf[2] == msg2.buf[2]); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_basic, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgrcv_block); +ATF_TC_HEAD(msgrcv_block, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that msgrcv(2) blocks"); +} + +ATF_TC_BODY(msgrcv_block, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id, sta; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (msgrcv(id, &msg, MSG_LEN, MSG_MTYPE_1, 0) < 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + /* + * Below msgsnd(2) should unblock the child, + * and hence kill(2) should fail with ESRCH. + */ + (void)sleep(1); + (void)msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT); + (void)sleep(1); + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WIFSIGNALED(sta) != 0) + atf_tc_fail("msgrcv(2) did not block"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_block, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgrcv_err); +ATF_TC_HEAD(msgrcv_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from msgrcv(2)"); +} + +ATF_TC_BODY(msgrcv_err, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id, r = 0; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(ENOMSG, msgrcv(id, &msg, + MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0); + + errno = 0; + + ATF_REQUIRE_ERRNO(EFAULT, msgrcv(id, (void *)-1, + MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgrcv(-1, &msg, + MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgrcv(-1, &msg, + SSIZE_MAX, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0); + + errno = 0; + + ATF_REQUIRE_ERRNO(E2BIG, msgrcv(id, &r, + MSG_LEN - 1, MSG_MTYPE_1, IPC_NOWAIT) == -1); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_err, tc) +{ + clean(); +} + + +ATF_TC_WITH_CLEANUP(msgrcv_mtype); +ATF_TC_HEAD(msgrcv_mtype, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test message types with msgrcv(2)"); +} + +ATF_TC_BODY(msgrcv_mtype, tc) +{ + struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msg msg2 = { MSG_MTYPE_3, { 'x', 'y', 'z' } }; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT); + (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_2, IPC_NOWAIT); + + ATF_CHECK(msg1.buf[0] != msg2.buf[0]); /* Different mtype. */ + ATF_CHECK(msg1.buf[1] != msg2.buf[1]); + ATF_CHECK(msg1.buf[2] != msg2.buf[2]); + + (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT); + + ATF_CHECK(msg1.buf[0] == msg2.buf[0]); /* Same mtype. */ + ATF_CHECK(msg1.buf[1] == msg2.buf[1]); + ATF_CHECK(msg1.buf[2] == msg2.buf[2]); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_mtype, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgrcv_nonblock); +ATF_TC_HEAD(msgrcv_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgrcv(2) with IPC_NOWAIT"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(msgrcv_nonblock, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + const ssize_t n = 10; + int id, sta; + ssize_t i; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + for (i = 0; i < n; i++) { + + ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0); + } + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + while (i != 0) { + + if (msgrcv(id, &msg, MSG_LEN, MSG_MTYPE_1, + IPC_NOWAIT) == -1) + _exit(EXIT_FAILURE); + + i--; + } + + _exit(EXIT_SUCCESS); + } + + (void)sleep(2); + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFSIGNALED(sta) != 0 || WTERMSIG(sta) == SIGKILL) + atf_tc_fail("msgrcv(2) blocked with IPC_NOWAIT"); + + if (WIFEXITED(sta) == 0 && WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("msgrcv(2) failed"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_nonblock, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgrcv_truncate); +ATF_TC_HEAD(msgrcv_truncate, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgrcv(2) with MSG_NOERROR"); +} + +ATF_TC_BODY(msgrcv_truncate, tc) +{ +#define MSG_SMALLLEN 2 + struct msgsmall { + long mtype; + char buf[MSG_SMALLLEN]; + }; + + struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msgsmall msg2 = { MSG_MTYPE_1, { 'x', 'y' } }; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT); + (void)msgrcv(id, &msg2, MSG_SMALLLEN, + MSG_MTYPE_1, IPC_NOWAIT | MSG_NOERROR); + + ATF_CHECK(msg1.buf[0] == msg2.buf[0]); + ATF_CHECK(msg1.buf[1] == msg2.buf[1]); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgrcv_truncate, tc) +{ + clean(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msgrcv_basic); + ATF_TP_ADD_TC(tp, msgrcv_block); + ATF_TP_ADD_TC(tp, msgrcv_err); + ATF_TP_ADD_TC(tp, msgrcv_mtype); + ATF_TP_ADD_TC(tp, msgrcv_nonblock); + ATF_TP_ADD_TC(tp, msgrcv_truncate); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c new file mode 100644 index 0000000..562602a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c @@ -0,0 +1,367 @@ +/* $NetBSD: t_msgsnd.c,v 1.3 2017/01/13 20:44:45 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_msgsnd.c,v 1.3 2017/01/13 20:44:45 christos Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MSG_KEY 1234 +#define MSG_MTYPE_1 0x41 +#define MSG_MTYPE_2 0x42 +#define MSG_MTYPE_3 0x43 + +struct msg { + long mtype; + char buf[3]; +}; + +static void clean(void); + +static void +clean(void) +{ + int id; + + if ((id = msgget(MSG_KEY, 0)) != -1) + (void)msgctl(id, IPC_RMID, 0); +} + +ATF_TC_WITH_CLEANUP(msgsnd_block); +ATF_TC_HEAD(msgsnd_block, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that msgsnd(2) blocks"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(msgsnd_block, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id, sta; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Enqueue messages until some limit (e.g. the maximum + * number of messages in the queue or the maximum number + * of bytes in the queue) is reached. After this the call + * should block when the IPC_NOWAIT is not set. + */ + for (;;) { + +#ifdef __FreeBSD__ + if (msgsnd(id, &msg, sizeof(msg.buf), 0) < 0) +#else + if (msgsnd(id, &msg, sizeof(struct msg), 0) < 0) +#endif + _exit(EXIT_FAILURE); + } + } + + (void)sleep(2); + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFEXITED(sta) != 0 || WIFSIGNALED(sta) == 0) + atf_tc_fail("msgsnd(2) did not block"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_block, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgsnd_count); +ATF_TC_HEAD(msgsnd_count, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that msgsnd(2) increments the amount of " + "message in the queue, as given by msgctl(2)"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(msgsnd_count, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct msqid_ds ds; + size_t i = 0; + int id, rv; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + for (;;) { + + errno = 0; +#ifdef __FreeBSD__ + rv = msgsnd(id, &msg, sizeof(msg.buf), IPC_NOWAIT); +#else + rv = msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT); +#endif + + if (rv == 0) { + i++; + continue; + } + + if (rv == -1 && errno == EAGAIN) + break; + + atf_tc_fail("failed to enqueue a message"); + } + + (void)memset(&ds, 0, sizeof(struct msqid_ds)); + (void)msgctl(id, IPC_STAT, &ds); + + if (ds.msg_qnum != i) + atf_tc_fail("incorrect message count"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_count, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgsnd_err); +ATF_TC_HEAD(msgsnd_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from msgsnd(2)"); +} + +ATF_TC_BODY(msgsnd_err, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + errno = 0; + + ATF_REQUIRE_ERRNO(EFAULT, msgsnd(id, (void *)-1, +#ifdef __FreeBSD__ + sizeof(msg.buf), IPC_NOWAIT) == -1); +#else + sizeof(struct msg), IPC_NOWAIT) == -1); +#endif + + errno = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgsnd(-1, &msg, +#ifdef __FreeBSD__ + sizeof(msg.buf), IPC_NOWAIT) == -1); +#else + sizeof(struct msg), IPC_NOWAIT) == -1); +#endif + + errno = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgsnd(-1, &msg, + SSIZE_MAX, IPC_NOWAIT) == -1); + + errno = 0; + msg.mtype = 0; + + ATF_REQUIRE_ERRNO(EINVAL, msgsnd(id, &msg, +#ifdef __FreeBSD__ + sizeof(msg.buf), IPC_NOWAIT) == -1); +#else + sizeof(struct msg), IPC_NOWAIT) == -1); +#endif + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_err, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgsnd_nonblock); +ATF_TC_HEAD(msgsnd_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test msgsnd(2) with IPC_NOWAIT"); + atf_tc_set_md_var(tc, "timeout", "10"); +} + +ATF_TC_BODY(msgsnd_nonblock, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + int id, rv, sta; + pid_t pid; + + id = msgget(MSG_KEY, IPC_CREAT | 0600); + ATF_REQUIRE(id != -1); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + for (;;) { + + errno = 0; +#ifdef __FreeBSD__ + rv = msgsnd(id, &msg, sizeof(msg.buf), IPC_NOWAIT); +#else + rv = msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT); +#endif + + if (rv == -1 && errno == EAGAIN) + _exit(EXIT_SUCCESS); + } + } + + (void)sleep(2); + (void)kill(pid, SIGKILL); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WIFSIGNALED(sta) != 0) + atf_tc_fail("msgsnd(2) blocked with IPC_NOWAIT"); + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_nonblock, tc) +{ + clean(); +} + +ATF_TC_WITH_CLEANUP(msgsnd_perm); +ATF_TC_HEAD(msgsnd_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with msgsnd(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(msgsnd_perm, tc) +{ + struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } }; + struct passwd *pw; + int id, sta; + pid_t pid; + uid_t uid; + + pw = getpwnam("nobody"); + id = msgget(MSG_KEY, IPC_CREAT | 0600); + + ATF_REQUIRE(id != -1); + ATF_REQUIRE(pw != NULL); + + uid = pw->pw_uid; + ATF_REQUIRE(uid != 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Try to enqueue a message to the queue + * created by root as RW for owner only. + */ + if (setuid(uid) != 0) + _exit(EX_OSERR); + + id = msgget(MSG_KEY, 0); + + if (id == -1) + _exit(EX_OSERR); + + errno = 0; + +#ifdef __FreeBSD__ + if (msgsnd(id, &msg, sizeof(msg.buf), IPC_NOWAIT) == 0) +#else + if (msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT) == 0) +#endif + _exit(EXIT_FAILURE); + + if (errno != EACCES) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) { + + if (errno == EX_OSERR) + atf_tc_fail("system call failed"); + + atf_tc_fail("UID %u enqueued message to root's queue", uid); + } + + ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0); +} + +ATF_TC_CLEANUP(msgsnd_perm, tc) +{ + clean(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, msgsnd_block); + ATF_TP_ADD_TC(tp, msgsnd_count); + ATF_TP_ADD_TC(tp, msgsnd_err); + ATF_TP_ADD_TC(tp, msgsnd_nonblock); + ATF_TP_ADD_TC(tp, msgsnd_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msync.c b/contrib/netbsd-tests/lib/libc/sys/t_msync.c new file mode 100644 index 0000000..d1fdbe0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_msync.c @@ -0,0 +1,235 @@ +/* $NetBSD: t_msync.c,v 1.3 2017/01/14 20:52:42 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_msync.c,v 1.3 2017/01/14 20:52:42 christos Exp $"); + +#include + +#include +#include +#include +#include +#include +#include +#include + +static long page = 0; +static const off_t off = 512; +static const char path[] = "msync"; + +static const char *msync_sync(const char *, int); + +static const char * +msync_sync(const char *garbage, int flags) +{ + char *buf, *map = MAP_FAILED; + const char *str = NULL; + size_t len; + int fd, rv; + + /* + * Create a temporary file, write + * one page to it, and map the file. + */ + buf = malloc(page); + + if (buf == NULL) + return NULL; + + memset(buf, 'x', page); + + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) { + free(buf); + return "failed to open"; + } + + ATF_REQUIRE_MSG(write(fd, buf, page) != -1, "write(2) failed: %s", + strerror(errno)); + + map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_FILE|MAP_PRIVATE, + fd, 0); + + if (map == MAP_FAILED) { + str = "failed to map"; + goto out; + } + + /* + * Seek to an arbitrary offset and + * write garbage to this position. + */ + if (lseek(fd, off, SEEK_SET) != off) { + str = "failed to seek"; + goto out; + } + + len = strlen(garbage); + rv = write(fd, garbage, len); + + if (rv != (ssize_t)len) { + str = "failed to write garbage"; + goto out; + } + + /* + * Synchronize the mapping and verify + * that garbage is at the given offset. + */ + if (msync(map, page, flags) != 0) { + str = "failed to msync"; + goto out; + } + + if (memcmp(map + off, garbage, len) != 0) { + str = "msync did not synchronize"; + goto out; + } + +out: + free(buf); + + (void)close(fd); + (void)unlink(path); + + if (map != MAP_FAILED) + (void)munmap(map, page); + + return str; +} + +ATF_TC(msync_async); +ATF_TC_HEAD(msync_async, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_ASYNC"); +} + +ATF_TC_BODY(msync_async, tc) +{ + const char *str; + + str = msync_sync("garbage", MS_ASYNC); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TC(msync_err); +ATF_TC_HEAD(msync_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions in msync(2)"); +} + +ATF_TC_BODY(msync_err, tc) +{ + + char *map = MAP_FAILED; + + /* + * Test that invalid flags error out. + */ +#ifdef __FreeBSD__ + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, msync_sync("error", -1) != NULL); + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, msync_sync("error", INT_MAX) != NULL); +#else + ATF_REQUIRE(msync_sync("error", -1) != NULL); + ATF_REQUIRE(msync_sync("error", INT_MAX) != NULL); +#endif + + errno = 0; + + /* + * Map a page and then unmap to get an unmapped address. + */ + map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, + -1, 0); + ATF_REQUIRE(map != MAP_FAILED); + + (void)munmap(map, page); + + ATF_REQUIRE(msync(map, page, MS_SYNC) != 0); +#ifdef __FreeBSD__ + ATF_REQUIRE(errno == ENOMEM); +#else + ATF_REQUIRE(errno == EFAULT); +#endif +} + +ATF_TC(msync_invalidate); +ATF_TC_HEAD(msync_invalidate, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_INVALIDATE"); +} + +ATF_TC_BODY(msync_invalidate, tc) +{ + const char *str; + + str = msync_sync("garbage", MS_INVALIDATE); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TC(msync_sync); +ATF_TC_HEAD(msync_sync, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_SYNC"); +} + +ATF_TC_BODY(msync_sync, tc) +{ + const char *str; + + str = msync_sync("garbage", MS_SYNC); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TP_ADD_TCS(tp) +{ + + page = sysconf(_SC_PAGESIZE); + + ATF_REQUIRE(page >= 0); + ATF_REQUIRE(page > off); + + ATF_TP_ADD_TC(tp, msync_async); + ATF_TP_ADD_TC(tp, msync_err); + ATF_TP_ADD_TC(tp, msync_invalidate); + ATF_TP_ADD_TC(tp, msync_sync); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c new file mode 100644 index 0000000..1ad6661 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c @@ -0,0 +1,187 @@ +/* $NetBSD: t_nanosleep.c,v 1.4 2017/01/13 21:15:14 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_nanosleep.c,v 1.4 2017/01/13 21:15:14 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void +handler(int signo __unused) +{ + /* Nothing. */ +} + +ATF_TC(nanosleep_basic); +ATF_TC_HEAD(nanosleep_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that nanosleep(2) works"); +} + +ATF_TC_BODY(nanosleep_basic, tc) +{ + static const size_t maxiter = 10; + struct timespec ts1, ts2, tsn; + size_t i; + + for (i = 1; i < maxiter; i++) { + + tsn.tv_sec = 0; + tsn.tv_nsec = i; + + (void)memset(&ts1, 0, sizeof(struct timespec)); + (void)memset(&ts2, 0, sizeof(struct timespec)); + + ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts1) == 0); + ATF_REQUIRE(nanosleep(&tsn, NULL) == 0); + ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts2) == 0); + + /* + * Verify that we slept at least one nanosecond. + */ + if (timespeccmp(&ts2, &ts1, <=) != 0) { + + (void)fprintf(stderr, + "sleep time:: sec %llu, nsec %lu\n\t\t" + "ts1: sec %llu, nsec %lu\n\t\t" + "ts2: sec %llu, nsec %lu\n", + (unsigned long long)tsn.tv_sec, tsn.tv_nsec, + (unsigned long long)ts1.tv_sec, ts1.tv_nsec, + (unsigned long long)ts2.tv_sec, ts2.tv_nsec); + + atf_tc_fail_nonfatal("inaccuracies in sleep time " + "(resolution = %lu nsec)", tsn.tv_nsec); + } + } +} + +ATF_TC(nanosleep_err); +ATF_TC_HEAD(nanosleep_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test errors from nanosleep(2) (PR bin/14558)"); +} + +ATF_TC_BODY(nanosleep_err, tc) +{ + struct timespec ts; + + ts.tv_sec = 1; + ts.tv_nsec = -1; + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, nanosleep(&ts, NULL) == -1); + + ts.tv_sec = 1; + ts.tv_nsec = 1000000000; + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, nanosleep(&ts, NULL) == -1); + + ts.tv_sec = -1; + ts.tv_nsec = 0; + errno = 0; + ATF_REQUIRE_ERRNO(0, nanosleep(&ts, NULL) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, nanosleep((void *)-1, NULL) == -1); +} + +ATF_TC(nanosleep_sig); +ATF_TC_HEAD(nanosleep_sig, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test signal for nanosleep(2)"); +} + +ATF_TC_BODY(nanosleep_sig, tc) +{ + struct timespec tsn, tsr; + pid_t pid; + int sta; + + /* + * Test that a signal interrupts nanosleep(2). + * + * (In which case the return value should be -1 and the + * second parameter should contain the unslept time.) + */ + pid = fork(); + + ATF_REQUIRE(pid >= 0); + ATF_REQUIRE(signal(SIGINT, handler) == 0); + + if (pid == 0) { + + tsn.tv_sec = 10; + tsn.tv_nsec = 0; + + tsr.tv_sec = 0; + tsr.tv_nsec = 0; + + errno = 0; + + if (nanosleep(&tsn, &tsr) != -1) + _exit(EXIT_FAILURE); + + if (errno != EINTR) + _exit(EXIT_FAILURE); + + if (tsr.tv_sec == 0 && tsr.tv_nsec == 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)sleep(1); + (void)kill(pid, SIGINT); + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("signal did not interrupt nanosleep(2)"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, nanosleep_basic); + ATF_TP_ADD_TC(tp, nanosleep_err); + ATF_TP_ADD_TC(tp, nanosleep_sig); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_pipe.c b/contrib/netbsd-tests/lib/libc/sys/t_pipe.c new file mode 100644 index 0000000..df8f1ed --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_pipe.c @@ -0,0 +1,164 @@ +/* $NetBSD: t_pipe.c,v 1.5 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_pipe.c,v 1.5 2017/01/13 21:30:41 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +static pid_t pid; +static int nsiginfo = 0; + +/* + * This is used for both parent and child. Handle parent's SIGALRM, + * the childs SIGINFO doesn't need anything. + */ +static void +sighand(int sig) +{ + if (sig == SIGALRM) { + kill(pid, SIGINFO); + } + if (sig == SIGINFO) { + nsiginfo++; + } +} + +ATF_TC(pipe_restart); +ATF_TC_HEAD(pipe_restart, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that writing to pipe " + "works correctly after being interrupted and restarted " + "(kern/14087)"); +} + +ATF_TC_BODY(pipe_restart, tc) +{ + int pp[2], st; + ssize_t sz, todo, done; + char *f; + sigset_t asigset, osigset, emptysigset; + + /* Initialise signal masks */ + RL(sigemptyset(&emptysigset)); + RL(sigemptyset(&asigset)); + RL(sigaddset(&asigset, SIGINFO)); + + /* Register signal handlers for both read and writer */ + REQUIRE_LIBC(signal(SIGINFO, sighand), SIG_ERR); + REQUIRE_LIBC(signal(SIGALRM, sighand), SIG_ERR); + + todo = 2 * 1024 * 1024; + REQUIRE_LIBC(f = malloc(todo), NULL); + + RL(pipe(pp)); + + RL(pid = fork()); + if (pid == 0) { + /* child */ + RL(close(pp[1])); + + /* Do inital write. This should succeed, make + * the other side do partial write and wait for us to pick + * rest up. + */ + RL(done = read(pp[0], f, 128 * 1024)); + + /* Wait until parent is alarmed and awakens us */ + RL(sigprocmask(SIG_BLOCK, &asigset, &osigset)); + while (nsiginfo == 0) { + if (sigsuspend(&emptysigset) != -1 || errno != EINTR) + atf_tc_fail("sigsuspend(&emptysigset): %s", + strerror(errno)); + } + RL(sigprocmask(SIG_SETMASK, &osigset, NULL)); + + /* Read all what parent wants to give us */ + while((sz = read(pp[0], f, 1024 * 1024)) > 0) + done += sz; + + /* + * Exit with 1 if number of bytes read doesn't match + * number of expected bytes + */ + printf("Read: %#zx\n", (size_t)done); + printf("Expected: %#zx\n", (size_t)todo); + + exit(done != todo); + + /* NOTREACHED */ + } else { + RL(close(pp[0])); + + /* + * Arrange for alarm after two seconds. Since we have + * handler setup for SIGARLM, the write(2) call should + * be restarted internally by kernel. + */ + (void)alarm(2); + + /* We write exactly 'todo' bytes. The very first write(2) + * should partially succeed, block and eventually + * be restarted by kernel + */ + while(todo > 0 && ((sz = write(pp[1], f, todo)) > 0)) + todo -= sz; + + /* Close the pipe, so that child would stop reading */ + RL(close(pp[1])); + + /* And pickup child's exit status */ + RL(waitpid(pid, &st, 0)); + + ATF_REQUIRE_EQ(WEXITSTATUS(st), 0); + } + free(f); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pipe_restart); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c b/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c new file mode 100644 index 0000000..48f9734 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c @@ -0,0 +1,207 @@ +/* $NetBSD: t_pipe2.c,v 1.9 2017/01/13 21:19:45 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_pipe2.c,v 1.9 2017/01/13 21:19:45 christos Exp $"); + +#include +#include +#include +#include +#include +#include + +static void +run(int flags) +{ + int fd[2], i; + + while ((i = open("/", O_RDONLY)) < 3) + ATF_REQUIRE(i != -1); + +#ifdef __FreeBSD__ + closefrom(3); +#else + ATF_REQUIRE_MSG(closefrom(3) != -1, "closefrom failed: %s", + strerror(errno)); +#endif + + ATF_REQUIRE(pipe2(fd, flags) == 0); + + ATF_REQUIRE(fd[0] == 3); + ATF_REQUIRE(fd[1] == 4); + + if (flags & O_CLOEXEC) { + ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) != 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) != 0); + } else { + ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) == 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) == 0); + } + + if (flags & O_NONBLOCK) { + ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) != 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) != 0); + } else { + ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) == 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0); + } + +#ifndef __FreeBSD__ + if (flags & O_NOSIGPIPE) { + ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) != 0); + ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) != 0); + } else { + ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) == 0); + ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) == 0); + } +#endif + + ATF_REQUIRE(close(fd[0]) != -1); + ATF_REQUIRE(close(fd[1]) != -1); +} + +ATF_TC(pipe2_basic); +ATF_TC_HEAD(pipe2_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_basic, tc) +{ + run(0); +} + +ATF_TC(pipe2_consume); +ATF_TC_HEAD(pipe2_consume, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that consuming file descriptors " + "with pipe2(2) does not crash the system (PR kern/46457)"); +} + +ATF_TC_BODY(pipe2_consume, tc) +{ + struct rlimit rl; + int err, filedes[2]; + int old; + +#ifdef __FreeBSD__ + closefrom(4); +#else + ATF_REQUIRE_MSG(closefrom(4) != -1, "closefrom failed: %s", + strerror(errno)); +#endif + + err = getrlimit(RLIMIT_NOFILE, &rl); + ATF_REQUIRE(err == 0); + /* + * The heart of this test is to run against the number of open + * file descriptor limit in the middle of a pipe2() call - i.e. + * before the call only a single descriptor may be openend. + */ + old = rl.rlim_cur; + rl.rlim_cur = 4; + err = setrlimit(RLIMIT_NOFILE, &rl); + ATF_REQUIRE(err == 0); + + err = pipe2(filedes, O_CLOEXEC); + ATF_REQUIRE(err == -1); + rl.rlim_cur = old; + err = setrlimit(RLIMIT_NOFILE, &rl); +} + +ATF_TC(pipe2_nonblock); +ATF_TC_HEAD(pipe2_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "A non-blocking test of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_nonblock, tc) +{ + run(O_NONBLOCK); +} + +ATF_TC(pipe2_cloexec); +ATF_TC_HEAD(pipe2_cloexec, tc) +{ + atf_tc_set_md_var(tc, "descr", "A close-on-exec test of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_cloexec, tc) +{ + run(O_CLOEXEC); +} + +#ifdef __NetBSD__ +ATF_TC(pipe2_nosigpipe); +ATF_TC_HEAD(pipe2_nosigpipe, tc) +{ + atf_tc_set_md_var(tc, "descr", "A no sigpipe test of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_nosigpipe, tc) +{ + run(O_NOSIGPIPE); +} +#endif + +ATF_TC(pipe2_einval); +ATF_TC_HEAD(pipe2_einval, tc) +{ + atf_tc_set_md_var(tc, "descr", "A error check of pipe2(2)"); +} + +ATF_TC_BODY(pipe2_einval, tc) +{ + int fd[2]; + ATF_REQUIRE_ERRNO(EINVAL, pipe2(fd, O_ASYNC) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pipe2_basic); + ATF_TP_ADD_TC(tp, pipe2_consume); + ATF_TP_ADD_TC(tp, pipe2_nonblock); + ATF_TP_ADD_TC(tp, pipe2_cloexec); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, pipe2_nosigpipe); +#endif + ATF_TP_ADD_TC(tp, pipe2_einval); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_poll.c b/contrib/netbsd-tests/lib/libc/sys/t_poll.c new file mode 100644 index 0000000..6214486 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_poll.c @@ -0,0 +1,396 @@ +/* $NetBSD: t_poll.c,v 1.3 2012/03/18 07:00:52 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matthias Scheler. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static int desc; + +static void +child1(void) +{ + struct pollfd pfd; + + pfd.fd = desc; + pfd.events = POLLIN | POLLHUP | POLLOUT; + + (void)poll(&pfd, 1, 2000); + (void)printf("child1 exit\n"); +} + +static void +child2(void) +{ + struct pollfd pfd; + + pfd.fd = desc; + pfd.events = POLLIN | POLLHUP | POLLOUT; + + (void)sleep(1); + (void)poll(&pfd, 1, INFTIM); + (void)printf("child2 exit\n"); +} + +static void +child3(void) +{ + struct pollfd pfd; + + (void)sleep(5); + + pfd.fd = desc; + pfd.events = POLLIN | POLLHUP | POLLOUT; + + (void)poll(&pfd, 1, INFTIM); + (void)printf("child3 exit\n"); +} + +ATF_TC(poll_3way); +ATF_TC_HEAD(poll_3way, tc) +{ + atf_tc_set_md_var(tc, "timeout", "15"); + atf_tc_set_md_var(tc, "descr", + "Check for 3-way collision for descriptor. First child comes " + "and polls on descriptor, second child comes and polls, first " + "child times out and exits, third child comes and polls. When " + "the wakeup event happens, the two remaining children should " + "both be awaken. (kern/17517)"); +} + +ATF_TC_BODY(poll_3way, tc) +{ + int pf[2]; + int status, i; + pid_t pid; + + pipe(pf); + desc = pf[0]; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + (void)close(pf[1]); + child1(); + _exit(0); + /* NOTREACHED */ + } + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + (void)close(pf[1]); + child2(); + _exit(0); + /* NOTREACHED */ + } + + pid = fork(); + ATF_REQUIRE( pid >= 0); + + if (pid == 0) { + (void)close(pf[1]); + child3(); + _exit(0); + /* NOTREACHED */ + } + + (void)sleep(10); + + (void)printf("parent write\n"); + + ATF_REQUIRE(write(pf[1], "konec\n", 6) == 6); + + for(i = 0; i < 3; ++i) + (void)wait(&status); + + (void)printf("parent terminated\n"); +} + +ATF_TC(poll_basic); +ATF_TC_HEAD(poll_basic, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Basis functionality test for poll(2)"); +} + +ATF_TC_BODY(poll_basic, tc) +{ + int fds[2]; + struct pollfd pfds[2]; + int ret; + + ATF_REQUIRE_EQ(pipe(fds), 0); + + pfds[0].fd = fds[0]; + pfds[0].events = POLLIN; + pfds[1].fd = fds[1]; + pfds[1].events = POLLOUT; + + /* + * Check that we get a timeout waiting for data on the read end + * of our pipe. + */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[0], 1, 1), 0, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents); + + /* Check that the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[1], 1, 1), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\ + pfds[1].revents); + + /* Check that only the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + /* Write data to our pipe. */ + ATF_REQUIRE_EQ(write(fds[1], "", 1), 1); + + /* Check that both ends of our pipe are reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 2, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d", + pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + ATF_REQUIRE_EQ(close(fds[0]), 0); + ATF_REQUIRE_EQ(close(fds[1]), 0); +} + +ATF_TC(poll_err); +ATF_TC_HEAD(poll_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check errors from poll(2)"); +} + +ATF_TC_BODY(poll_err, tc) +{ + struct pollfd pfd; + int fd = 0; + + pfd.fd = fd; + pfd.events = POLLIN; + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, poll((struct pollfd *)-1, 1, -1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, poll(&pfd, 1, -2) == -1); +} + +#ifndef __FreeBSD__ +ATF_TC(pollts_basic); +ATF_TC_HEAD(pollts_basic, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Basis functionality test for pollts(2)"); +} + +ATF_TC_BODY(pollts_basic, tc) +{ + int fds[2]; + struct pollfd pfds[2]; + struct timespec timeout; + int ret; + + ATF_REQUIRE_EQ(pipe(fds), 0); + + pfds[0].fd = fds[0]; + pfds[0].events = POLLIN; + pfds[1].fd = fds[1]; + pfds[1].events = POLLOUT; + + /* Use a timeout of 1 second. */ + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + /* + * Check that we get a timeout waiting for data on the read end + * of our pipe. + */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[0], 1, &timeout, NULL), 0, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents); + + /* Check that the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[1], 1, &timeout, NULL), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\ + pfds[1].revents); + + /* Check that only the write end of the pipe as reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 1, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + /* Write data to our pipe. */ + ATF_REQUIRE_EQ(write(fds[1], "", 1), 1); + + /* Check that both ends of our pipe are reported as ready. */ + pfds[0].revents = -1; + pfds[1].revents = -1; + ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 2, + "got: %d", ret); + ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d", + pfds[0].revents); + ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", + pfds[1].revents); + + ATF_REQUIRE_EQ(close(fds[0]), 0); + ATF_REQUIRE_EQ(close(fds[1]), 0); +} + +ATF_TC(pollts_err); +ATF_TC_HEAD(pollts_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check errors from pollts(2)"); +} + +ATF_TC_BODY(pollts_err, tc) +{ + struct timespec timeout; + struct pollfd pfd; + int fd = 0; + + pfd.fd = fd; + pfd.events = POLLIN; + + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, pollts((void *)-1, 1, &timeout, NULL) == -1); + + timeout.tv_sec = -1; + timeout.tv_nsec = -1; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, pollts(&pfd, 1, &timeout, NULL) == -1); +} + +ATF_TC(pollts_sigmask); +ATF_TC_HEAD(pollts_sigmask, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Check that pollts(2) restores the signal mask (PR kern/44986)"); +} + +ATF_TC_BODY(pollts_sigmask, tc) +{ + int fd; + struct pollfd pfd; + struct timespec timeout; + sigset_t mask; + int ret; + + fd = open(_PATH_DEVNULL, O_RDONLY); + ATF_REQUIRE(fd >= 0); + + pfd.fd = fd; + pfd.events = POLLIN; + + /* Use a timeout of 1 second. */ + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + /* Unblock all signals. */ + ATF_REQUIRE_EQ(sigfillset(&mask), 0); + ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &mask, NULL), 0); + + /* + * Check that pollts(2) immediately returns. We block *all* + * signals during pollts(2). + */ + ATF_REQUIRE_EQ_MSG(ret = pollts(&pfd, 1, &timeout, &mask), 1, + "got: %d", ret); + + /* Check that signals are now longer blocked. */ + ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK, NULL, &mask), 0); + ATF_REQUIRE_EQ_MSG(sigismember(&mask, SIGUSR1), 0, + "signal mask was changed."); + + ATF_REQUIRE_EQ(close(fd), 0); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, poll_3way); + ATF_TP_ADD_TC(tp, poll_basic); + ATF_TP_ADD_TC(tp, poll_err); +#ifndef __FreeBSD__ + ATF_TP_ADD_TC(tp, pollts_basic); + ATF_TP_ADD_TC(tp, pollts_err); + ATF_TP_ADD_TC(tp, pollts_sigmask); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c b/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c new file mode 100644 index 0000000..813bfb8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c @@ -0,0 +1,165 @@ +/* $NetBSD: t_posix_fadvise.c,v 1.2 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by YAMAMOTO Takashi. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c)2005 YAMAMOTO Takashi, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_posix_fadvise.c,v 1.2 2017/01/13 21:30:41 christos Exp $"); + +#include + +#include +#include +#include + +#include + +#include "h_macros.h" + +#include +#include + +ATF_TC(posix_fadvise); +ATF_TC_HEAD(posix_fadvise, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks posix_fadvise(2)"); +} + +ATF_TC(posix_fadvise_reg); +ATF_TC_HEAD(posix_fadvise_reg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks posix_fadvise(2) " + "for regular files"); +} + +ATF_TC_BODY(posix_fadvise, tc) +{ + int fd; + int pipe_fds[2]; + int badfd = 10; + int ret; + + RL(fd = open("/dev/null", O_RDWR)); + + (void)close(badfd); + RL(pipe(pipe_fds)); + + /* + * it's hard to check if posix_fadvise is working properly. + * only check return values here. + */ + + /* posix_fadvise shouldn't affect errno. */ + +#define CE(x, exp) \ + do { \ + int save = errno; \ + errno = 999; \ + ATF_CHECK_EQ_MSG(ret = (x), exp, "got: %d", ret); \ + ATF_CHECK_EQ_MSG(errno, 999, "got: %s", strerror(errno)); \ + errno = save; \ + } while (0); + + CE(posix_fadvise(fd, 0, 0, -1), EINVAL); + CE(posix_fadvise(pipe_fds[0], 0, 0, POSIX_FADV_NORMAL), ESPIPE); + CE(posix_fadvise(badfd, 0, 0, POSIX_FADV_NORMAL), EBADF); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_NORMAL), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_WILLNEED), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED), 0); + CE(posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE), 0); +} + +ATF_TC_BODY(posix_fadvise_reg, tc) +{ + int rfd, ret; + + rump_init(); + RL(rfd = rump_sys_open("/a_file", O_CREAT, 0666)); + + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_NORMAL), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_SEQUENTIAL), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_RANDOM), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_WILLNEED), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_NOREUSE), 0); + + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_NORMAL), 0); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_SEQUENTIAL), 0); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_RANDOM), 0); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_WILLNEED), 0); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_NOREUSE), 0); + + //atf_tc_expect_signal(-1, "http://mail-index.netbsd.org/source-changes-d/2010/11/11/msg002508.html"); + CE(rump_sys_posix_fadvise(rfd, + INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_DONTNEED), 0); + CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_DONTNEED), 0); +#undef CE +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, posix_fadvise); + ATF_TP_ADD_TC(tp, posix_fadvise_reg); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_posix_fallocate.c b/contrib/netbsd-tests/lib/libc/sys/t_posix_fallocate.c new file mode 100644 index 0000000..b931ebd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_posix_fallocate.c @@ -0,0 +1,63 @@ +/* $NetBSD: t_posix_fallocate.c,v 1.1 2015/01/31 23:06:57 christos Exp $ */ + +/*- + * Copyright 2015, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 +__RCSID("$NetBSD: t_posix_fallocate.c,v 1.1 2015/01/31 23:06:57 christos Exp $"); + +#include +#include +#include +#include + +ATF_TC_WITHOUT_HEAD(ebadf); +ATF_TC_BODY(ebadf, tc) +{ + int rc, saved; + + errno = 1111; + rc = posix_fallocate(-1, 0, 4096); + saved = errno; + if (rc == -1 && saved != 1111) + atf_tc_fail("Should return error %s without setting errno.", + strerror(saved)); + if (rc != EBADF) + atf_tc_fail("returned %s but expected %s.", + strerror(saved), strerror(EBADF)); + if (saved != 1111) + atf_tc_fail("errno should be %d but got changed to %d.", + 1111, saved); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, ebadf); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c b/contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c new file mode 100644 index 0000000..76bc7dd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c @@ -0,0 +1,161 @@ +/* $NetBSD: t_recvmmsg.c,v 1.1 2012/06/22 18:45:23 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jared McNeill and Christos Zoulas. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_recvmmsg.c,v 1.1 2012/06/22 18:45:23 christos Exp $"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 65536 +#define NPKTS 50 + +#define min(a, b) ((a) < (b) ? (a) : (b)) +static int debug; + + +ATF_TC(recvmmsg_basic); +ATF_TC_HEAD(recvmmsg_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of recvmmsg(2)"); +} + +ATF_TC_BODY(recvmmsg_basic, tc) +{ + int fd[2], error, i, cnt; + uint8_t *buf; + struct mmsghdr *mmsghdr; + struct iovec *iov; + unsigned int mmsgcnt, n; + int status; + off_t off; + uint8_t DGRAM[1316] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, }; + + error = socketpair(AF_UNIX, SOCK_DGRAM, 0, fd); + ATF_REQUIRE_MSG(error != -1, "socketpair failed (%s)", strerror(errno)); + + buf = malloc(BUFSIZE); + ATF_REQUIRE_MSG(buf != NULL, "malloc failed (%s)", strerror(errno)); + + mmsgcnt = BUFSIZE / sizeof(DGRAM); + mmsghdr = malloc(sizeof(*mmsghdr) * mmsgcnt); + ATF_REQUIRE_MSG(mmsghdr != NULL, "malloc failed (%s)", strerror(errno)); + iov = malloc(sizeof(*iov) * mmsgcnt); + ATF_REQUIRE_MSG(iov != NULL, "malloc failed (%s)", strerror(errno)); + + for (off = 0, n = 0; n < mmsgcnt; n++) { + iov[n].iov_base = buf + off; + iov[n].iov_len = sizeof(DGRAM); + off += iov[n].iov_len; + mmsghdr[n].msg_hdr.msg_iov = &iov[n]; + mmsghdr[n].msg_hdr.msg_iovlen = 1; + mmsghdr[n].msg_hdr.msg_name = NULL; + mmsghdr[n].msg_hdr.msg_namelen = 0; + } + + switch (fork()) { + case -1: + ATF_REQUIRE_MSG(0, "fork failed (%s)", strerror(errno)); + break; + + case 0: + n = NPKTS; + if (debug) + printf("waiting for %u messages (max %u per syscall)\n", n, + mmsgcnt); + while (n > 0) { + struct timespec ts = { 1, 0 }; + cnt = recvmmsg(fd[1], mmsghdr, min(mmsgcnt, n), + MSG_WAITALL, &ts); + ATF_REQUIRE_MSG(cnt != -1, "recvmmsg failed (%s)", + strerror(errno)); + ATF_REQUIRE_MSG(cnt != 0, "recvmmsg timeout"); + if (debug) + printf("recvmmsg: got %u messages\n", cnt); + for (i = 0; i < cnt; i++) { + ATF_CHECK_EQ_MSG(mmsghdr[i].msg_len, + sizeof(DGRAM), "packet length"); + ATF_CHECK_EQ_MSG( + ((uint8_t *)iov[i].iov_base)[0], + NPKTS - n + i, "packet contents"); + } + n -= cnt; + } + if (debug) + printf("done!\n"); + exit(0); + /*NOTREACHED*/ + default: + sched_yield(); + + for (n = 0; n < NPKTS; n++) { + if (debug) + printf("sending packet %u/%u...\n", (n+1), + NPKTS); + do { + DGRAM[0] = n; + error = send(fd[0], DGRAM, sizeof(DGRAM), 0); + } while (error == -1 && errno == ENOBUFS); + if (error == -1) + ATF_REQUIRE_MSG(error != -1, "send failed (%s)", + strerror(errno)); + } + error = wait(&status); + ATF_REQUIRE_MSG(error != -1, "wait failed (%s)", + strerror(errno)); + break; + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, recvmmsg_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_revoke.c b/contrib/netbsd-tests/lib/libc/sys/t_revoke.c new file mode 100644 index 0000000..ec225b9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_revoke.c @@ -0,0 +1,196 @@ +/* $NetBSD: t_revoke.c,v 1.2 2017/01/13 21:15:57 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_revoke.c,v 1.2 2017/01/13 21:15:57 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char path[] = "revoke"; + +ATF_TC_WITH_CLEANUP(revoke_basic); +ATF_TC_HEAD(revoke_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of revoke(2)"); +} + +ATF_TC_BODY(revoke_basic, tc) +{ + struct rlimit res; + char tmp[10]; + size_t i, n; + int *buf; + +#ifdef __FreeBSD__ + atf_tc_skip("revoke(2) is only implemented for devfs(5)."); +#endif + (void)memset(&res, 0, sizeof(struct rlimit)); + (void)getrlimit(RLIMIT_NOFILE, &res); + + if ((n = res.rlim_cur / 10) == 0) + n = 10; + + buf = calloc(n, sizeof(int)); + ATF_REQUIRE(buf != NULL); + + buf[0] = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(buf[0] >= 0); + + for (i = 1; i < n; i++) { + buf[i] = open(path, O_RDWR); + ATF_REQUIRE(buf[i] >= 0); + } + + ATF_REQUIRE(revoke(path) == 0); + + for (i = 0; i < n; i++) { + + ATF_REQUIRE(read(buf[i], tmp, sizeof(tmp)) == -1); + + (void)close(buf[i]); + } + + free(buf); + + (void)unlink(path); +} + +ATF_TC_CLEANUP(revoke_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC(revoke_err); +ATF_TC_HEAD(revoke_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from revoke(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(revoke_err, tc) +{ + char buf[1024 + 1]; /* XXX: From the manual page... */ + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, revoke((char *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, revoke(buf) == -1); + +#ifdef __FreeBSD__ + atf_tc_skip("revoke(2) is only implemented for devfs(5)."); +#endif + errno = 0; + ATF_REQUIRE_ERRNO(EPERM, revoke("/etc/passwd") == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, revoke("/etc/xxx/yyy") == -1); +} + +ATF_TC_WITH_CLEANUP(revoke_perm); +ATF_TC_HEAD(revoke_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions revoke(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(revoke_perm, tc) +{ + struct passwd *pw; + int fd, sta; + pid_t pid; + +#ifdef __FreeBSD__ + atf_tc_skip("revoke(2) is only implemented for devfs(5)."); +#endif + pw = getpwnam("nobody"); + fd = open(path, O_RDWR | O_CREAT, 0600); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(pw != NULL); + ATF_REQUIRE(revoke(path) == 0); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + if (setuid(pw->pw_uid) != 0) + _exit(EXIT_FAILURE); + + errno = 0; + + if (revoke(path) == 0) + _exit(EXIT_FAILURE); + + if (errno != EACCES) + _exit(EXIT_FAILURE); + + if (close(fd) != 0) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("revoke(2) did not obey permissions"); + + (void)close(fd); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(revoke_perm, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, revoke_basic); + ATF_TP_ADD_TC(tp, revoke_err); + ATF_TP_ADD_TC(tp, revoke_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_select.c b/contrib/netbsd-tests/lib/libc/sys/t_select.c new file mode 100644 index 0000000..04a684a --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_select.c @@ -0,0 +1,217 @@ +/* $NetBSD: t_select.c,v 1.4 2017/01/13 21:18:33 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundatiom + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static sig_atomic_t keep_going = 1; + +static void +sig_handler(int signum __unused) +{ + keep_going = 0; +} + +static void +sigchld(int signum __unused) +{ +} + +static char +xtoa(uint8_t n) +{ + static const char xarray[] = "0123456789abcdef"; + assert(n < sizeof(xarray)); + return xarray[n]; +} + +static const char * +prmask(const sigset_t *m, char *buf, size_t len) +{ + size_t j = 2; + assert(len >= 3 + sizeof(*m)); + buf[0] = '0'; + buf[1] = 'x'; +#define N(p, a) (((p) >> ((a) * 4)) & 0xf) + for (size_t i = __arraycount(m->__bits); i > 0; i--) { + uint32_t p = m->__bits[i - 1]; + for (size_t k = sizeof(p); k > 0; k--) + buf[j++] = xtoa(N(p, k - 1)); + } + buf[j] = '\0'; + return buf; +} + +static __dead void +child(const struct timespec *ts) +{ + struct sigaction sa; + sigset_t set, oset, nset; + char obuf[sizeof(oset) + 3], nbuf[sizeof(nset) + 3]; + int fd; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = sig_handler; + if ((fd = open("/dev/null", O_RDONLY)) == -1) + err(1, "open"); + + if (sigaction(SIGTERM, &sa, NULL) == -1) + err(1, "sigaction"); + + sigfillset(&set); + if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) + err(1, "sigprocmask"); + + if (sigprocmask(SIG_BLOCK, NULL, &oset) == -1) + err(1, "sigprocmask"); + + sigemptyset(&set); + + for (;;) { + fd_set rset; + FD_ZERO(&rset); + FD_SET(fd, &rset); + if (pselect(1, &rset, NULL, NULL, ts, &set) == -1) { + if(errno == EINTR) { + if (!keep_going) + break; + } + } + if (ts) + break; + } + if (sigprocmask(SIG_BLOCK, NULL, &nset) == -1) + err(1, "sigprocmask"); + if (memcmp(&oset, &nset, sizeof(oset)) != 0) + atf_tc_fail("pselect() masks don't match " + "after timeout %s != %s", + prmask(&nset, nbuf, sizeof(nbuf)), + prmask(&oset, obuf, sizeof(obuf))); + _exit(0); +} + +ATF_TC(pselect_sigmask); +ATF_TC_HEAD(pselect_sigmask, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask " + "setting when a signal is received (PR lib/43625)"); +} + +ATF_TC_BODY(pselect_sigmask, tc) +{ + pid_t pid; + int status; + + signal(SIGCHLD, sigchld); + + switch (pid = fork()) { + case 0: + child(NULL); + /*NOTREACHED*/ + case -1: + err(1, "fork"); + default: + sleep(1); + if (kill(pid, SIGTERM) == -1) + err(1, "kill"); + sleep(1); + switch (waitpid(pid, &status, WNOHANG)) { + case -1: + err(1, "wait"); + case 0: + if (kill(pid, SIGKILL) == -1) + err(1, "kill"); + atf_tc_fail("pselect() did not receive signal"); + break; + default: + break; + } + } +} + +ATF_TC(pselect_timeout); +ATF_TC_HEAD(pselect_timeout, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask " + "setting when a timeout occurs"); +} + +ATF_TC_BODY(pselect_timeout, tc) +{ + pid_t pid; + int status; + static const struct timespec zero = { 0, 0 }; + + signal(SIGCHLD, sigchld); + + switch (pid = fork()) { + case 0: + child(&zero); + break; + case -1: + err(1, "fork"); + default: + sleep(1); + switch (waitpid(pid, &status, WNOHANG)) { + case -1: + err(1, "wait"); + case 0: + if (kill(pid, SIGKILL) == -1) + err(1, "kill"); + atf_tc_fail("pselect() did not receive signal"); + break; + default: + break; + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pselect_sigmask); + ATF_TP_ADD_TC(tp, pselect_timeout); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c new file mode 100644 index 0000000..7bef590 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c @@ -0,0 +1,553 @@ +/* $NetBSD: t_setrlimit.c,v 1.6 2017/01/13 21:16:38 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_setrlimit.c,v 1.6 2017/01/13 21:16:38 christos Exp $"); + +#include +#include +#include + +#include +#include +#include +#include +#ifdef __NetBSD__ +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +static void sighandler(int); +static const char path[] = "setrlimit"; + +static const int rlimit[] = { + RLIMIT_AS, + RLIMIT_CORE, + RLIMIT_CPU, + RLIMIT_DATA, + RLIMIT_FSIZE, + RLIMIT_MEMLOCK, + RLIMIT_NOFILE, + RLIMIT_NPROC, + RLIMIT_RSS, + RLIMIT_SBSIZE, + RLIMIT_STACK +}; + +ATF_TC(setrlimit_basic); +ATF_TC_HEAD(setrlimit_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic soft limit test"); +} + +ATF_TC_BODY(setrlimit_basic, tc) +{ + struct rlimit res; + int *buf, lim; + size_t i; + + buf = calloc(__arraycount(rlimit), sizeof(int)); + + if (buf == NULL) + atf_tc_fail("initialization failed"); + + for (i = lim = 0; i < __arraycount(rlimit); i++) { + + (void)memset(&res, 0, sizeof(struct rlimit)); + + if (getrlimit(rlimit[i], &res) != 0) + continue; + + if (res.rlim_cur == RLIM_INFINITY || res.rlim_cur == 0) + continue; + + if (res.rlim_cur == res.rlim_max) /* An unprivileged run. */ + continue; + + buf[i] = res.rlim_cur; + res.rlim_cur = res.rlim_cur - 1; + + if (setrlimit(rlimit[i], &res) != 0) { + lim = rlimit[i]; + goto out; + } + } + +out: + for (i = 0; i < __arraycount(rlimit); i++) { + + (void)memset(&res, 0, sizeof(struct rlimit)); + + if (buf[i] == 0) + continue; + + if (getrlimit(rlimit[i], &res) != 0) + continue; + + res.rlim_cur = buf[i]; + + (void)setrlimit(rlimit[i], &res); + } + + if (lim != 0) + atf_tc_fail("failed to set limit (%d)", lim); + free(buf); +} + +ATF_TC(setrlimit_current); +ATF_TC_HEAD(setrlimit_current, tc) +{ + atf_tc_set_md_var(tc, "descr", "setrlimit(3) with current limits"); +} + +ATF_TC_BODY(setrlimit_current, tc) +{ + struct rlimit res; + size_t i; + + for (i = 0; i < __arraycount(rlimit); i++) { + + (void)memset(&res, 0, sizeof(struct rlimit)); + + ATF_REQUIRE(getrlimit(rlimit[i], &res) == 0); + ATF_REQUIRE(setrlimit(rlimit[i], &res) == 0); + } +} + +ATF_TC(setrlimit_err); +ATF_TC_HEAD(setrlimit_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions"); +} + +ATF_TC_BODY(setrlimit_err, tc) +{ + struct rlimit res; + size_t i; + + for (i = 0; i < __arraycount(rlimit); i++) { + + errno = 0; + + ATF_REQUIRE(getrlimit(rlimit[i], (void *)0) != 0); + ATF_REQUIRE(errno == EFAULT); + } + + errno = 0; + + ATF_REQUIRE(getrlimit(INT_MAX, &res) != 0); + ATF_REQUIRE(errno == EINVAL); +} + +ATF_TC_WITH_CLEANUP(setrlimit_fsize); +ATF_TC_HEAD(setrlimit_fsize, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_FSIZE"); +} + +ATF_TC_BODY(setrlimit_fsize, tc) +{ + struct rlimit res; + int fd, sta; + pid_t pid; + + fd = open(path, O_RDWR | O_CREAT, 0700); + + if (fd < 0) + atf_tc_fail("initialization failed"); + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + res.rlim_cur = 2; + res.rlim_max = 2; + + if (setrlimit(RLIMIT_FSIZE, &res) != 0) + _exit(EXIT_FAILURE); + + if (signal(SIGXFSZ, sighandler) == SIG_ERR) + _exit(EXIT_FAILURE); + + /* + * The third call should generate a SIGXFSZ. + */ + (void)write(fd, "X", 1); + (void)write(fd, "X", 1); + (void)write(fd, "X", 1); + + _exit(EXIT_FAILURE); + } + + (void)close(fd); + (void)wait(&sta); + (void)unlink(path); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_FSIZE not enforced"); +} + +ATF_TC_CLEANUP(setrlimit_fsize, tc) +{ + (void)unlink(path); +} + +static void +sighandler(int signo) +{ + + if (signo != SIGXFSZ) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); +} + +ATF_TC(setrlimit_memlock); +ATF_TC_HEAD(setrlimit_memlock, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_MEMLOCK"); +} + +ATF_TC_BODY(setrlimit_memlock, tc) +{ + struct rlimit res; + void *buf; + long page; + pid_t pid; + int sta; + + page = sysconf(_SC_PAGESIZE); + ATF_REQUIRE(page >= 0); + + buf = malloc(page); + pid = fork(); + + if (buf == NULL || pid < 0) + atf_tc_fail("initialization failed"); + + if (pid == 0) { + + /* + * Try to lock a page while + * RLIMIT_MEMLOCK is zero. + */ + if (mlock(buf, page) != 0) + _exit(EXIT_FAILURE); + + if (munlock(buf, page) != 0) + _exit(EXIT_FAILURE); + + res.rlim_cur = 0; + res.rlim_max = 0; + + if (setrlimit(RLIMIT_MEMLOCK, &res) != 0) + _exit(EXIT_FAILURE); + + if (mlock(buf, page) != 0) + _exit(EXIT_SUCCESS); + + (void)munlock(buf, page); + + _exit(EXIT_FAILURE); + } + + free(buf); + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_MEMLOCK not enforced"); +} + +ATF_TC(setrlimit_nofile_1); +ATF_TC_HEAD(setrlimit_nofile_1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #1"); +} + +ATF_TC_BODY(setrlimit_nofile_1, tc) +{ + struct rlimit res; + int fd, i, rv, sta; + pid_t pid; + + res.rlim_cur = 0; + res.rlim_max = 0; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Close all descriptors, set RLIMIT_NOFILE + * to zero, and try to open a random file. + * This should fail with EMFILE. + */ + for (i = 0; i < 1024; i++) + (void)close(i); + + rv = setrlimit(RLIMIT_NOFILE, &res); + + if (rv != 0) + _exit(EXIT_FAILURE); + + errno = 0; + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0 || errno != EMFILE) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_NOFILE not enforced"); +} + +ATF_TC(setrlimit_nofile_2); +ATF_TC_HEAD(setrlimit_nofile_2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #2"); +} + +ATF_TC_BODY(setrlimit_nofile_2, tc) +{ + static const rlim_t lim = 12; + struct rlimit res; + int fd, i, rv, sta; + pid_t pid; + + /* + * See that an arbitrary limit on + * open files is being enforced. + */ + res.rlim_cur = lim; + res.rlim_max = lim; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + for (i = 0; i < 1024; i++) + (void)close(i); + + rv = setrlimit(RLIMIT_NOFILE, &res); + + if (rv != 0) + _exit(EXIT_FAILURE); + + for (i = 0; i < (int)lim; i++) { + + fd = open("/etc/passwd", O_RDONLY); + + if (fd < 0) + _exit(EXIT_FAILURE); + } + + /* + * After the limit has been reached, + * EMFILE should again follow. + */ + fd = open("/etc/passwd", O_RDONLY); + + if (fd >= 0 || errno != EMFILE) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_NOFILE not enforced"); +} + +ATF_TC(setrlimit_nproc); +ATF_TC_HEAD(setrlimit_nproc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NPROC"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setrlimit_nproc, tc) +{ + struct rlimit res; + pid_t pid, cpid; + int sta; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * Set RLIMIT_NPROC to zero and try to fork. + */ + res.rlim_cur = 0; + res.rlim_max = 0; + + if (setrlimit(RLIMIT_NPROC, &res) != 0) + _exit(EXIT_FAILURE); + + cpid = fork(); + + if (cpid < 0) + _exit(EXIT_SUCCESS); + + _exit(EXIT_FAILURE); + } + + (void)waitpid(pid, &sta, 0); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("RLIMIT_NPROC not enforced"); +} + +#ifdef __NetBSD__ +ATF_TC(setrlimit_nthr); +ATF_TC_HEAD(setrlimit_nthr, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NTHR"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +static void +func(lwpid_t *id) +{ + printf("thread %d\n", *id); + fflush(stdout); + _lwp_exit(); +} + +ATF_TC_BODY(setrlimit_nthr, tc) +{ + struct rlimit res; + lwpid_t lwpid; + ucontext_t c; + + /* + * Set RLIMIT_NTHR to zero and try to create a thread. + */ + res.rlim_cur = 0; + res.rlim_max = 0; + ATF_REQUIRE(setrlimit(RLIMIT_NTHR, &res) == 0); + ATF_REQUIRE(getcontext(&c) == 0); + c.uc_link = NULL; + sigemptyset(&c.uc_sigmask); + c.uc_stack.ss_flags = 0; + c.uc_stack.ss_size = 4096; + ATF_REQUIRE((c.uc_stack.ss_sp = malloc(c.uc_stack.ss_size)) != NULL); + makecontext(&c, func, 1, &lwpid); + ATF_CHECK_ERRNO(EAGAIN, _lwp_create(&c, 0, &lwpid) == -1); +} +#endif + +ATF_TC(setrlimit_perm); +ATF_TC_HEAD(setrlimit_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2) for EPERM"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setrlimit_perm, tc) +{ + struct rlimit res; + size_t i; + + /* + * Try to raise the maximum limits as an user. + */ + for (i = 0; i < __arraycount(rlimit); i++) { + + ATF_REQUIRE(getrlimit(rlimit[i], &res) == 0); + +#ifdef __FreeBSD__ + if (res.rlim_max == INT64_MAX) /* Overflow. */ +#else + if (res.rlim_max == UINT64_MAX) /* Overflow. */ +#endif + continue; + + errno = 0; + res.rlim_max = res.rlim_max + 1; + + ATF_CHECK_ERRNO(EPERM, setrlimit(rlimit[i], &res) != 0); + } +} + +ATF_TC(setrlimit_stack); +ATF_TC_HEAD(setrlimit_stack, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_STACK"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setrlimit_stack, tc) +{ + struct rlimit res; + + /* Ensure soft limit is not bigger than hard limit */ + res.rlim_cur = res.rlim_max = 4192256; + ATF_REQUIRE(setrlimit(RLIMIT_STACK, &res) == 0); + ATF_REQUIRE(getrlimit(RLIMIT_STACK, &res) == 0); + ATF_CHECK(res.rlim_cur <= res.rlim_max); + +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, setrlimit_basic); + ATF_TP_ADD_TC(tp, setrlimit_current); + ATF_TP_ADD_TC(tp, setrlimit_err); + ATF_TP_ADD_TC(tp, setrlimit_fsize); + ATF_TP_ADD_TC(tp, setrlimit_memlock); + ATF_TP_ADD_TC(tp, setrlimit_nofile_1); + ATF_TP_ADD_TC(tp, setrlimit_nofile_2); + ATF_TP_ADD_TC(tp, setrlimit_nproc); + ATF_TP_ADD_TC(tp, setrlimit_perm); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, setrlimit_nthr); +#endif + ATF_TP_ADD_TC(tp, setrlimit_stack); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_setuid.c b/contrib/netbsd-tests/lib/libc/sys/t_setuid.c new file mode 100644 index 0000000..d2bf523 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_setuid.c @@ -0,0 +1,122 @@ +/* $NetBSD: t_setuid.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_setuid.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $"); + +#include + +#include +#include +#include +#include +#include + +ATF_TC(setuid_perm); +ATF_TC_HEAD(setuid_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setuid(0) as normal user"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(setuid_perm, tc) +{ + errno = 0; + + ATF_REQUIRE(setuid(0) == -1); + ATF_REQUIRE(errno == EPERM); +} + +ATF_TC(setuid_real); +ATF_TC_HEAD(setuid_real, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setuid(2) with real UID"); +} + +ATF_TC_BODY(setuid_real, tc) +{ + uid_t uid = getuid(); + + ATF_REQUIRE(setuid(uid) == 0); + + ATF_REQUIRE(getuid() == uid); + ATF_REQUIRE(geteuid() == uid); +} + +ATF_TC(setuid_root); +ATF_TC_HEAD(setuid_root, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of setuid(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(setuid_root, tc) +{ + struct passwd *pw; + int rv, sta; + pid_t pid; + uid_t uid; + + while ((pw = getpwent()) != NULL) { + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + rv = setuid(pw->pw_uid); + + if (rv != 0) + _exit(EXIT_FAILURE); + + uid = getuid(); + + if (uid != pw->pw_uid) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("failed to change UID to %u", pw->pw_uid); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, setuid_perm); + ATF_TP_ADD_TC(tp, setuid_real); + ATF_TP_ADD_TC(tp, setuid_root); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c b/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c new file mode 100644 index 0000000..4bbf421 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c @@ -0,0 +1,153 @@ +/* $NetBSD: t_sigaction.c,v 1.5 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sigaction.c,v 1.5 2017/01/13 21:30:41 christos Exp $"); + +#include + +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +static bool handler_called = false; + +static void +handler(int signo __unused) +{ + handler_called = true; +} + +static void +sa_resethand_child(const int flags) +{ + struct sigaction sa; + + sa.sa_flags = flags; + sa.sa_handler = &handler; + sigemptyset(&sa.sa_mask); + + sigaction(SIGUSR1, &sa, NULL); + kill(getpid(), SIGUSR1); + exit(handler_called ? EXIT_SUCCESS : EXIT_FAILURE); +} + +static void +wait_and_check_child(const pid_t pid, const char *fail_message) +{ + int status; + + (void)waitpid(pid, &status, 0); + + if (WIFEXITED(status)) + ATF_CHECK_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); + else + atf_tc_fail("%s; raw exit status was %d", fail_message, status); +} + +static void +catch(int sig __unused) +{ + return; +} + +ATF_TC(sigaction_basic); +ATF_TC_HEAD(sigaction_basic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks for correct I&D cache" + "synchronization after copying out the trampoline code."); +} + +ATF_TC_BODY(sigaction_basic, tc) +{ + static struct sigaction sa; + + sa.sa_handler = catch; + + sigaction(SIGUSR1, &sa, 0); + kill(getpid(), SIGUSR1); + atf_tc_pass(); +} + +ATF_TC(sigaction_noflags); +ATF_TC_HEAD(sigaction_noflags, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks programming a signal with " + "sigaction(2) but without any flags"); +} + +ATF_TC_BODY(sigaction_noflags, tc) +{ + const pid_t pid = fork(); + if (pid == -1) + atf_tc_fail_errno("fork(2) failed"); + else if (pid == 0) + sa_resethand_child(0); + else + wait_and_check_child(pid, "Child process did not exit cleanly;" + " it failed to process the signal"); +} + +ATF_TC(sigaction_resethand); +ATF_TC_HEAD(sigaction_resethand, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that SA_RESETHAND works"); +} + +ATF_TC_BODY(sigaction_resethand, tc) +{ + const pid_t pid = fork(); + if (pid == -1) + atf_tc_fail_errno("fork(2) failed"); + else if (pid == 0) + sa_resethand_child(SA_RESETHAND); + else { + wait_and_check_child(pid, "Child process did not exit cleanly;" + " it either failed to process the signal or SA_RESETHAND" + " is broken"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sigaction_basic); + ATF_TP_ADD_TC(tp, sigaction_noflags); + ATF_TP_ADD_TC(tp, sigaction_resethand); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c new file mode 100644 index 0000000..af560f8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c @@ -0,0 +1,240 @@ +/* $NetBSD: t_sigqueue.c,v 1.7 2017/01/13 20:44:10 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_sigqueue.c,v 1.7 2017/01/13 20:44:10 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +static void handler(int, siginfo_t *, void *); + +#define VALUE (int)0xc001dad1 +static int value; + +static void +handler(int signo __unused, siginfo_t *info, void *data __unused) +{ + value = info->si_value.sival_int; + kill(0, SIGINFO); +} + +ATF_TC(sigqueue_basic); +ATF_TC_HEAD(sigqueue_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks sigqueue(3) sigval delivery"); +} + +ATF_TC_BODY(sigqueue_basic, tc) +{ + struct sigaction sa; + union sigval sv; + + sa.sa_sigaction = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + + if (sigaction(SIGUSR1, &sa, NULL) != 0) + atf_tc_fail("sigaction failed"); + + sv.sival_int = VALUE; + +#ifdef __FreeBSD__ + /* + * From kern_sig.c: + * Specification says sigqueue can only send signal to single process. + */ + if (sigqueue(getpid(), SIGUSR1, sv) != 0) +#else + if (sigqueue(0, SIGUSR1, sv) != 0) +#endif + atf_tc_fail("sigqueue failed"); + + sched_yield(); + ATF_REQUIRE_EQ(sv.sival_int, value); +} + +ATF_TC(sigqueue_err); +ATF_TC_HEAD(sigqueue_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from sigqueue(3)"); +} + +ATF_TC_BODY(sigqueue_err, tc) +{ + static union sigval sv; + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, sigqueue(getpid(), -1, sv) == -1); +} + +static int signals[] = { + SIGINT, SIGRTMIN + 1, SIGINT, SIGRTMIN + 0, SIGRTMIN + 2, + SIGQUIT, SIGRTMIN + 1 +}; +#ifdef __arraycount +#define CNT __arraycount(signals) +#else +#define CNT (sizeof(signals) / sizeof(signals[0])) +#endif + +static sig_atomic_t count = 0; +static int delivered[CNT]; + +static void +myhandler(int signo, siginfo_t *info, void *context __unused) +{ + delivered[count++] = signo; + printf("Signal #%zu: signo: %d\n", (size_t)count, signo); +} + +static int +asc(const void *a, const void *b) +{ + const int *ia = a, *ib = b; + return *ib - *ia; +} + +/* + * given a array of signals to be delivered in tosend of size len + * place in ordered the signals to be delivered in delivery order + * and return the number of signals that should be delivered + */ +static size_t +sigorder(int *ordered, const int *tosend, size_t len) +{ + memcpy(ordered, tosend, len * sizeof(*tosend)); + qsort(ordered, len, sizeof(*ordered), asc); + if (len == 1) + return len; + +#ifdef __FreeBSD__ + /* + * Don't dedupe signal numbers (bug 212173) + * + * Per kib's comment.. + * + * " + * OTOH, FreeBSD behaviour is to treat all signals as realtime while + * there is no mem shortage and siginfo can be allocated. In + * particular, signals < SIGRTMIN are not collapsed when queued more + * than once. + * " + */ + + return len; +#else + + size_t i, j; + for (i = 0, j = 0; i < len - 1; i++) { + if (ordered[i] >= SIGRTMIN) + continue; + if (j == 0) + j = i + 1; + while (ordered[i] == ordered[j] && j < len) + j++; + if (j == len) + break; + ordered[i + 1] = ordered[j]; + } + return i + 1; +#endif +} + +ATF_TC(sigqueue_rt); +ATF_TC_HEAD(sigqueue_rt, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test queuing of real-time signals"); +} + +ATF_TC_BODY(sigqueue_rt, tc) +{ + pid_t pid; + union sigval val; + struct sigaction act; + int ordered[CNT]; + struct sigaction oact[CNT]; + size_t ndelivered; + + ndelivered = sigorder(ordered, signals, CNT); + + act.sa_flags = SA_SIGINFO; + act.sa_sigaction = myhandler; + sigemptyset(&act.sa_mask); + for (size_t i = 0; i < ndelivered; i++) + ATF_REQUIRE(sigaction(ordered[i], &act, &oact[i]) != -1); + + val.sival_int = 0; + pid = getpid(); + + sigset_t mask, orig; + sigemptyset(&mask); + for (size_t i = 0; i < CNT; i++) + if (sigaddset(&mask, signals[i]) == -1) + warn("sigaddset"); + + ATF_REQUIRE(sigprocmask(SIG_BLOCK, &mask, &orig) != -1); + + for (size_t i = 0; i < CNT; i++) + ATF_REQUIRE(sigqueue(pid, signals[i], val) != -1); + + ATF_REQUIRE(sigprocmask(SIG_UNBLOCK, &mask, &orig) != -1); + sleep(1); + ATF_CHECK_MSG((size_t)count == ndelivered, + "count %zu != ndelivered %zu", (size_t)count, ndelivered); + for (size_t i = 0; i < ndelivered; i++) + ATF_REQUIRE_MSG(ordered[i] == delivered[i], + "%zu: ordered %d != delivered %d", + i, ordered[i], delivered[i]); + + if ((size_t)count > ndelivered) + for (size_t i = ndelivered; i < (size_t)count; i++) + printf("Undelivered signal #%zu: %d\n", i, ordered[i]); + + for (size_t i = 0; i < ndelivered; i++) + ATF_REQUIRE(sigaction(signals[i], &oact[i], NULL) != -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sigqueue_basic); + ATF_TP_ADD_TC(tp, sigqueue_err); + ATF_TP_ADD_TC(tp, sigqueue_rt); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c b/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c new file mode 100644 index 0000000..64b68d9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c @@ -0,0 +1,126 @@ +/* $NetBSD: t_sigtimedwait.c,v 1.2 2013/03/08 23:18:00 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_sigtimedwait.c,v 1.2 2013/03/08 23:18:00 martin Exp $"); + +#include +#include +#include +#include +#include +#include + + +ATF_TC(sigtimedwait_all0timeout); + +ATF_TC_HEAD(sigtimedwait_all0timeout, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", "Test for PR kern/47625: sigtimedwait" + " with a timeout value of all zero should return imediately"); +} + +ATF_TC_BODY(sigtimedwait_all0timeout, tc) +{ + sigset_t block; + struct timespec ts, before, after, len; + siginfo_t info; + int r; + + sigemptyset(&block); + ts.tv_sec = 0; + ts.tv_nsec = 0; + clock_gettime(CLOCK_MONOTONIC, &before); + r = sigtimedwait(&block, &info, &ts); + clock_gettime(CLOCK_MONOTONIC, &after); + ATF_REQUIRE(r == -1); + ATF_REQUIRE_ERRNO(EAGAIN, errno); + timespecsub(&after, &before, &len); + ATF_REQUIRE(len.tv_sec < 1); +} + +ATF_TC(sigtimedwait_NULL_timeout); + +ATF_TC_HEAD(sigtimedwait_NULL_timeout, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", "Test sigtimedwait() without timeout"); +} + +ATF_TC_BODY(sigtimedwait_NULL_timeout, tc) +{ + sigset_t sig; + siginfo_t info; + struct itimerval it; + int r; + + /* arrange for a SIGALRM signal in a few seconds */ + memset(&it, 0, sizeof it); + it.it_value.tv_sec = 5; + ATF_REQUIRE(setitimer(ITIMER_REAL, &it, NULL) == 0); + + /* wait without timeout */ + sigemptyset(&sig); + sigaddset(&sig, SIGALRM); + r = sigtimedwait(&sig, &info, NULL); + ATF_REQUIRE(r == SIGALRM); +} + +ATF_TC(sigtimedwait_small_timeout); + +ATF_TC_HEAD(sigtimedwait_small_timeout, tc) +{ + atf_tc_set_md_var(tc, "timeout", "15"); + atf_tc_set_md_var(tc, "descr", "Test sigtimedwait with a small " + "timeout"); +} + +ATF_TC_BODY(sigtimedwait_small_timeout, tc) +{ + sigset_t block; + struct timespec ts; + siginfo_t info; + int r; + + sigemptyset(&block); + ts.tv_sec = 5; + ts.tv_nsec = 0; + r = sigtimedwait(&block, &info, &ts); + ATF_REQUIRE(r == -1); + ATF_REQUIRE_ERRNO(EAGAIN, errno); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, sigtimedwait_all0timeout); + ATF_TP_ADD_TC(tp, sigtimedwait_NULL_timeout); + ATF_TP_ADD_TC(tp, sigtimedwait_small_timeout); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c b/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c new file mode 100644 index 0000000..7a0cc20 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c @@ -0,0 +1,141 @@ +/* $NetBSD: t_socketpair.c,v 1.2 2017/01/13 20:04:52 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_socketpair.c,v 1.2 2017/01/13 20:04:52 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +static void +connected(int fd) +{ + struct sockaddr_un addr; + socklen_t len = (socklen_t)sizeof(addr); + ATF_REQUIRE(getpeername(fd, (struct sockaddr*)(void *)&addr, + &len) == 0); +} + +static void +run(int flags) +{ + int fd[2], i; + + while ((i = open("/", O_RDONLY)) < 3) + ATF_REQUIRE(i != -1); + +#ifdef __FreeBSD__ + closefrom(3); +#else + ATF_REQUIRE(closefrom(3) != -1); +#endif + + ATF_REQUIRE(socketpair(AF_UNIX, SOCK_DGRAM | flags, 0, fd) == 0); + + ATF_REQUIRE(fd[0] == 3); + ATF_REQUIRE(fd[1] == 4); + + connected(fd[0]); + connected(fd[1]); + + if (flags & SOCK_CLOEXEC) { + ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) != 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) != 0); + } else { + ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) == 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) == 0); + } + + if (flags & SOCK_NONBLOCK) { + ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) != 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) != 0); + } else { + ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) == 0); + ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0); + } + + ATF_REQUIRE(close(fd[0]) != -1); + ATF_REQUIRE(close(fd[1]) != -1); +} + +ATF_TC(socketpair_basic); +ATF_TC_HEAD(socketpair_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of socketpair(2)"); +} + +ATF_TC_BODY(socketpair_basic, tc) +{ + run(0); +} + +ATF_TC(socketpair_nonblock); +ATF_TC_HEAD(socketpair_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", "A non-blocking test of socketpair(2)"); +} + +ATF_TC_BODY(socketpair_nonblock, tc) +{ + run(SOCK_NONBLOCK); +} + +ATF_TC(socketpair_cloexec); +ATF_TC_HEAD(socketpair_cloexec, tc) +{ + atf_tc_set_md_var(tc, "descr", "A close-on-exec of socketpair(2)"); +} + +ATF_TC_BODY(socketpair_cloexec, tc) +{ + run(SOCK_CLOEXEC); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, socketpair_basic); + ATF_TP_ADD_TC(tp, socketpair_nonblock); + ATF_TP_ADD_TC(tp, socketpair_cloexec); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_stat.c b/contrib/netbsd-tests/lib/libc/sys/t_stat.c new file mode 100644 index 0000000..adb32bb --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_stat.c @@ -0,0 +1,419 @@ +/* $NetBSD: t_stat.c,v 1.5 2017/01/13 20:06:50 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_stat.c,v 1.5 2017/01/13 20:06:50 christos Exp $"); + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +static const char *path = "stat"; + +ATF_TC_WITH_CLEANUP(stat_chflags); +ATF_TC_HEAD(stat_chflags, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test chflags(2) with stat(2)"); +} + +ATF_TC_BODY(stat_chflags, tc) +{ + struct stat sa, sb; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + fd = open(path, O_RDONLY | O_CREAT); + + ATF_REQUIRE(fd != -1); + ATF_REQUIRE(stat(path, &sa) == 0); + ATF_REQUIRE(chflags(path, UF_NODUMP) == 0); + ATF_REQUIRE(stat(path, &sb) == 0); + + if (sa.st_flags == sb.st_flags) + atf_tc_fail("stat(2) did not detect chflags(2)"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(stat_chflags, tc) +{ + (void)unlink(path); +} + +ATF_TC(stat_dir); +ATF_TC_HEAD(stat_dir, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test stat(2) with directories"); +} + +ATF_TC_BODY(stat_dir, tc) +{ + const short depth = 2; + struct stat sa, sb; + char *argv[2]; + FTSENT *ftse; + FTS *fts; + int ops; + + argv[1] = NULL; + argv[0] = __UNCONST("/"); + + ops = FTS_NOCHDIR; + ops |= FTS_PHYSICAL; + + fts = fts_open(argv, ops, NULL); + ATF_REQUIRE(fts != NULL); + + while ((ftse = fts_read(fts)) != NULL) { + + if (ftse->fts_level < 1) + continue; + + if (ftse->fts_level > depth) { + (void)fts_set(fts, ftse, FTS_SKIP); + continue; + } + + switch(ftse->fts_info) { + + case FTS_DP: + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + ATF_REQUIRE(stat(ftse->fts_parent->fts_path,&sa) == 0); + ATF_REQUIRE(chdir(ftse->fts_path) == 0); + ATF_REQUIRE(stat(".", &sb) == 0); + + /* + * The previous two stat(2) calls + * should be for the same directory. + */ + if (sa.st_dev != sb.st_dev || sa.st_ino != sb.st_ino) + atf_tc_fail("inconsistent stat(2)"); + + /* + * Check that fts(3)'s stat(2) + * call equals the manual one. + */ + if (sb.st_ino != ftse->fts_statp->st_ino) + atf_tc_fail("stat(2) and fts(3) differ"); + + break; + + default: + break; + } + } + + (void)fts_close(fts); +} + +ATF_TC(stat_err); +ATF_TC_HEAD(stat_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from the stat(2) family"); +} + +ATF_TC_BODY(stat_err, tc) +{ + char buf[NAME_MAX + 1]; + struct stat st; + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, fstat(-1, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, stat(buf, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, lstat(buf, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, stat((void *)-1, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, lstat((void *)-1, &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, stat("/etc/passwd", (void *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, lstat("/etc/passwd", (void *)-1) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, stat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, lstat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1); +} + +ATF_TC_WITH_CLEANUP(stat_mtime); +ATF_TC_HEAD(stat_mtime, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test modification times with stat(2)"); +} + +ATF_TC_BODY(stat_mtime, tc) +{ + struct stat sa, sb; + int fd[3]; + size_t i; + + for (i = 0; i < __arraycount(fd); i++) { + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + fd[i] = open(path, O_WRONLY | O_CREAT); + + ATF_REQUIRE(fd[i] != -1); + ATF_REQUIRE(write(fd[i], "X", 1) == 1); + ATF_REQUIRE(stat(path, &sa) == 0); + + (void)sleep(1); + + ATF_REQUIRE(write(fd[i], "X", 1) == 1); + ATF_REQUIRE(stat(path, &sb) == 0); + + ATF_REQUIRE(close(fd[i]) == 0); + ATF_REQUIRE(unlink(path) == 0); + + if (sa.st_mtime == sb.st_mtime) + atf_tc_fail("mtimes did not change"); + } +} + +ATF_TC_CLEANUP(stat_mtime, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(stat_perm); +ATF_TC_HEAD(stat_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with stat(2)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(stat_perm, tc) +{ + struct stat sa, sb; + gid_t gid; + uid_t uid; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + uid = getuid(); + gid = getgid(); + + fd = open(path, O_RDONLY | O_CREAT); + + ATF_REQUIRE(fd != -1); + ATF_REQUIRE(fstat(fd, &sa) == 0); + ATF_REQUIRE(stat(path, &sb) == 0); + + if (gid != sa.st_gid || sa.st_gid != sb.st_gid) + atf_tc_fail("invalid GID"); + + if (uid != sa.st_uid || sa.st_uid != sb.st_uid) + atf_tc_fail("invalid UID"); + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(stat_perm, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(stat_size); +ATF_TC_HEAD(stat_size, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test file sizes with stat(2)"); +} + +ATF_TC_BODY(stat_size, tc) +{ + struct stat sa, sb, sc; + const size_t n = 10; + size_t i; + int fd; + + fd = open(path, O_WRONLY | O_CREAT); + ATF_REQUIRE(fd >= 0); + + for (i = 0; i < n; i++) { + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + (void)memset(&sc, 0, sizeof(struct stat)); + + ATF_REQUIRE(fstat(fd, &sa) == 0); + ATF_REQUIRE(write(fd, "X", 1) == 1); + ATF_REQUIRE(fstat(fd, &sb) == 0); + ATF_REQUIRE(stat(path, &sc) == 0); + + if (sa.st_size + 1 != sb.st_size) + atf_tc_fail("invalid file size"); + + if (sb.st_size != sc.st_size) + atf_tc_fail("stat(2) and fstat(2) mismatch"); + } + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(stat_size, tc) +{ + (void)unlink(path); +} + +ATF_TC(stat_socket); +ATF_TC_HEAD(stat_socket, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test fstat(2) with " + "a socket (PR kern/46077)"); +} + +ATF_TC_BODY(stat_socket, tc) +{ + struct sockaddr_in addr; + struct stat st; + uint32_t iaddr; + int fd, flags; + + (void)memset(&st, 0, sizeof(struct stat)); + (void)memset(&addr, 0, sizeof(struct sockaddr_in)); + + fd = socket(AF_INET, SOCK_STREAM, 0); + ATF_REQUIRE(fd >= 0); + + flags = fcntl(fd, F_GETFL); + + ATF_REQUIRE(flags != -1); + ATF_REQUIRE(fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1); + ATF_REQUIRE(inet_pton(AF_INET, "127.0.0.1", &iaddr) == 1); + + addr.sin_port = htons(42); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = iaddr; + + errno = 0; + + ATF_REQUIRE_ERRNO(EINPROGRESS, + connect(fd, (struct sockaddr *)&addr, + sizeof(struct sockaddr_in)) == -1); + + errno = 0; + + if (fstat(fd, &st) != 0 || errno != 0) + atf_tc_fail("fstat(2) failed for a EINPROGRESS socket"); + + (void)close(fd); +} + +ATF_TC_WITH_CLEANUP(stat_symlink); +ATF_TC_HEAD(stat_symlink, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test symbolic links with stat(2)"); +} + +ATF_TC_BODY(stat_symlink, tc) +{ + const char *pathlink = "pathlink"; + struct stat sa, sb; + int fd; + + (void)memset(&sa, 0, sizeof(struct stat)); + (void)memset(&sb, 0, sizeof(struct stat)); + + fd = open(path, O_WRONLY | O_CREAT); + + ATF_REQUIRE(fd >= 0); + ATF_REQUIRE(symlink(path, pathlink) == 0); + ATF_REQUIRE(stat(pathlink, &sa) == 0); + ATF_REQUIRE(lstat(pathlink, &sb) == 0); + + if (S_ISLNK(sa.st_mode) != 0) + atf_tc_fail("stat(2) detected symbolic link"); + + if (S_ISLNK(sb.st_mode) == 0) + atf_tc_fail("lstat(2) did not detect symbolic link"); + + if (sa.st_mode == sb.st_mode) + atf_tc_fail("inconsistencies between stat(2) and lstat(2)"); + + (void)close(fd); + ATF_REQUIRE(unlink(path) == 0); + ATF_REQUIRE(unlink(pathlink) == 0); +} + +ATF_TC_CLEANUP(stat_symlink, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, stat_chflags); + ATF_TP_ADD_TC(tp, stat_dir); + ATF_TP_ADD_TC(tp, stat_err); + ATF_TP_ADD_TC(tp, stat_mtime); + ATF_TP_ADD_TC(tp, stat_perm); + ATF_TP_ADD_TC(tp, stat_size); + ATF_TP_ADD_TC(tp, stat_socket); + ATF_TP_ADD_TC(tp, stat_symlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c b/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c new file mode 100644 index 0000000..de36c88 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c @@ -0,0 +1,133 @@ +/* $NetBSD: t_swapcontext.c,v 1.3 2013/05/05 10:28:11 skrll Exp $ */ + +/* + * Copyright (c) 2012 Emmanuel Dreyfus. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD"); + +#include +#include +#include +#include + +#include + +#define STACKSIZE 65536 + +char stack[STACKSIZE]; +ucontext_t nctx; +ucontext_t octx; +void *otls; +void *ntls; +int val1, val2; +int alter_tlsbase; + +/* ARGSUSED0 */ +static void +swapfunc(void *arg) +{ + ntls = _lwp_getprivate(); + printf("after swapcontext TLS pointer = %p\n", ntls); + + if (alter_tlsbase) { + ATF_REQUIRE_EQ(ntls, &val1); + printf("TLS pointer modified by swapcontext()\n"); + } else { + ATF_REQUIRE_EQ(ntls, &val2); + printf("TLS pointer left untouched by swapcontext()\n"); + } + + /* Go back in main */ + ATF_REQUIRE(swapcontext(&nctx, &octx)); + + /* NOTREACHED */ + return; +} + +static void +mainfunc(void) +{ + printf("Testing if swapcontext() alters TLS pointer if _UC_TLSBASE " + "is %s\n", (alter_tlsbase) ? "left set" : "cleared"); + + _lwp_setprivate(&val1); + printf("before swapcontext TLS pointer = %p\n", &val1); + + ATF_REQUIRE(getcontext(&nctx) == 0); + + nctx.uc_stack.ss_sp = stack; + nctx.uc_stack.ss_size = sizeof(stack); + +#ifndef _UC_TLSBASE + ATF_REQUIRE_MSG(0, "_UC_TLSBASE is not defined"); +#else /* _UC_TLSBASE */ + ATF_REQUIRE(nctx.uc_flags & _UC_TLSBASE); + if (!alter_tlsbase) + nctx.uc_flags &= ~_UC_TLSBASE; +#endif /* _UC_TLSBASE */ + + makecontext(&nctx, swapfunc, 0); + + _lwp_setprivate(&val2); + otls = _lwp_getprivate(); + printf("before swapcontext TLS pointer = %p\n", otls); + ATF_REQUIRE(swapcontext(&octx, &nctx) == 0); + + printf("Test completed\n"); +} + + +ATF_TC(swapcontext1); +ATF_TC_HEAD(swapcontext1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can let " + "TLS pointer untouched"); +} +ATF_TC_BODY(swapcontext1, tc) +{ + alter_tlsbase = 0; + mainfunc(); +} + +ATF_TC(swapcontext2); +ATF_TC_HEAD(swapcontext2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can " + "modify TLS pointer"); +} +ATF_TC_BODY(swapcontext2, tc) +{ + alter_tlsbase = 1; + mainfunc(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, swapcontext1); + ATF_TP_ADD_TC(tp, swapcontext2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c new file mode 100644 index 0000000..e8a6acd --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c @@ -0,0 +1,207 @@ +/* $NetBSD: t_timer_create.c,v 1.5 2017/01/16 16:32:13 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include + +static timer_t t; +static bool fail = true; + +static void +timer_signal_handler(int signo, siginfo_t *si, void *osi __unused) +{ + timer_t *tp; + + tp = si->si_value.sival_ptr; + + if (*tp == t && signo == SIGALRM) + fail = false; + + (void)fprintf(stderr, "%s: %s\n", __func__, strsignal(signo)); +} + +static void +timer_signal_create(clockid_t cid, bool expire) +{ + struct itimerspec tim; + struct sigaction act; + struct sigevent evt; + sigset_t set; + + t = 0; + fail = true; + + (void)memset(&evt, 0, sizeof(struct sigevent)); + (void)memset(&act, 0, sizeof(struct sigaction)); + (void)memset(&tim, 0, sizeof(struct itimerspec)); + + /* + * Set handler. + */ + act.sa_flags = SA_SIGINFO; + act.sa_sigaction = timer_signal_handler; + + ATF_REQUIRE(sigemptyset(&set) == 0); + ATF_REQUIRE(sigemptyset(&act.sa_mask) == 0); + + /* + * Block SIGALRM while configuring the timer. + */ + ATF_REQUIRE(sigaction(SIGALRM, &act, NULL) == 0); + ATF_REQUIRE(sigaddset(&set, SIGALRM) == 0); + ATF_REQUIRE(sigprocmask(SIG_SETMASK, &set, NULL) == 0); + + /* + * Create the timer (SIGEV_SIGNAL). + */ + evt.sigev_signo = SIGALRM; + evt.sigev_value.sival_ptr = &t; + evt.sigev_notify = SIGEV_SIGNAL; + + ATF_REQUIRE(timer_create(cid, &evt, &t) == 0); + + /* + * Start the timer. After this, unblock the signal. + */ + tim.it_value.tv_sec = expire ? 5 : 1; + tim.it_value.tv_nsec = 0; + + ATF_REQUIRE(timer_settime(t, 0, &tim, NULL) == 0); + + (void)sigprocmask(SIG_UNBLOCK, &set, NULL); + (void)sleep(2); + + if (expire) { + if (!fail) + atf_tc_fail("timer fired too soon"); + } else { + if (fail) + atf_tc_fail("timer failed to fire"); + } + + ATF_REQUIRE(timer_delete(t) == 0); +} + +ATF_TC(timer_create_err); +ATF_TC_HEAD(timer_create_err, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Check errors from timer_create(2) (PR lib/42434"); +} + +ATF_TC_BODY(timer_create_err, tc) +{ + struct sigevent ev; + + (void)memset(&ev, 0, sizeof(struct sigevent)); + + errno = 0; + ev.sigev_signo = -1; + ev.sigev_notify = SIGEV_SIGNAL; + + ATF_REQUIRE_ERRNO(EINVAL, timer_create(CLOCK_REALTIME, &ev, &t) == -1); + + errno = 0; + ev.sigev_signo = SIGUSR1; + ev.sigev_notify = SIGEV_THREAD + 100; + + ATF_REQUIRE_ERRNO(EINVAL, timer_create(CLOCK_REALTIME, &ev, &t) == -1); +} + +ATF_TC(timer_create_real); +ATF_TC_HEAD(timer_create_real, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), " + "SIGEV_SIGNAL"); +} + +ATF_TC_BODY(timer_create_real, tc) +{ + timer_signal_create(CLOCK_REALTIME, false); +} + +ATF_TC(timer_create_mono); +ATF_TC_HEAD(timer_create_mono, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), " + "SIGEV_SIGNAL"); +} + +ATF_TC_BODY(timer_create_mono, tc) +{ + timer_signal_create(CLOCK_MONOTONIC, false); +} + +ATF_TC(timer_create_real_expire); +ATF_TC_HEAD(timer_create_real_expire, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), " + "SIGEV_SIGNAL, with expiration"); +} + +ATF_TC_BODY(timer_create_real_expire, tc) +{ + timer_signal_create(CLOCK_REALTIME, true); +} + +ATF_TC(timer_create_mono_expire); +ATF_TC_HEAD(timer_create_mono_expire, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), " + "SIGEV_SIGNAL, with expiration"); +} + +ATF_TC_BODY(timer_create_mono_expire, tc) +{ + timer_signal_create(CLOCK_MONOTONIC, true); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, timer_create_err); + ATF_TP_ADD_TC(tp, timer_create_real); + ATF_TP_ADD_TC(tp, timer_create_mono); + ATF_TP_ADD_TC(tp, timer_create_real_expire); + ATF_TP_ADD_TC(tp, timer_create_mono_expire); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_truncate.c b/contrib/netbsd-tests/lib/libc/sys/t_truncate.c new file mode 100644 index 0000000..5b96a20 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_truncate.c @@ -0,0 +1,179 @@ +/* $NetBSD: t_truncate.c,v 1.3 2017/01/13 20:03:51 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_truncate.c,v 1.3 2017/01/13 20:03:51 christos Exp $"); + +#include + +#include +#include +#include +#include +#include +#include +#include + +static const char path[] = "truncate"; +static const size_t sizes[] = { 8, 16, 512, 1024, 2048, 4094, 3000, 30 }; + +ATF_TC_WITH_CLEANUP(ftruncate_basic); +ATF_TC_HEAD(ftruncate_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of ftruncate(2)"); +} + +ATF_TC_BODY(ftruncate_basic, tc) +{ + struct stat st; + size_t i; + int fd; + + fd = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(fd >= 0); + + for (i = 0; i < __arraycount(sizes); i++) { + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(ftruncate(fd, sizes[i]) == 0); + ATF_REQUIRE(fstat(fd, &st) == 0); + + (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]); + + if (sizes[i] != (size_t)st.st_size) + atf_tc_fail("ftruncate(2) did not truncate"); + } + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(ftruncate_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC(ftruncate_err); +ATF_TC_HEAD(ftruncate_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from ftruncate(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(ftruncate_err, tc) +{ + int fd; + + fd = open("/etc/passwd", O_RDONLY, 0400); + ATF_REQUIRE(fd >= 0); + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, ftruncate(-1, 999) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, ftruncate(fd, 999) == -1); + + (void)close(fd); +} + +ATF_TC_WITH_CLEANUP(truncate_basic); +ATF_TC_HEAD(truncate_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of truncate(2)"); +} + +ATF_TC_BODY(truncate_basic, tc) +{ + struct stat st; + size_t i; + int fd; + + fd = open(path, O_RDWR | O_CREAT, 0600); + ATF_REQUIRE(fd >= 0); + + for (i = 0; i < __arraycount(sizes); i++) { + + (void)memset(&st, 0, sizeof(struct stat)); + + ATF_REQUIRE(truncate(path, sizes[i]) == 0); + ATF_REQUIRE(fstat(fd, &st) == 0); + + (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]); + + if (sizes[i] != (size_t)st.st_size) + atf_tc_fail("truncate(2) did not truncate"); + } + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(truncate_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC(truncate_err); +ATF_TC_HEAD(truncate_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from truncate(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(truncate_err, tc) +{ + char buf[PATH_MAX]; + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, truncate((void *)-1, 999) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EISDIR, truncate("/etc", 999) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, truncate("/a/b/c/d/e/f/g", 999) == -1); + + errno = 0; + snprintf(buf, sizeof(buf), "%s/truncate_test.root_owned", + atf_tc_get_config_var(tc, "srcdir")); + ATF_REQUIRE_ERRNO(EACCES, truncate(buf, 999) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ftruncate_basic); + ATF_TP_ADD_TC(tp, ftruncate_err); + ATF_TP_ADD_TC(tp, truncate_basic); + ATF_TP_ADD_TC(tp, truncate_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c b/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c new file mode 100644 index 0000000..27d6740 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c @@ -0,0 +1,76 @@ +/* $NetBSD: t_ucontext.c,v 1.1 2011/10/15 06:54:52 jruoho Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ucontext.c,v 1.1 2011/10/15 06:54:52 jruoho Exp $"); + +#include +#include +#include + +ATF_TC(ucontext_basic); +ATF_TC_HEAD(ucontext_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks {get,set}context(2)"); +} + +ATF_TC_BODY(ucontext_basic, tc) +{ + ucontext_t u, v, w; + volatile int x, y; + + x = 0; + y = 0; + + printf("Start\n"); + + getcontext(&u); + y++; + + printf("x == %d\n", x); + + getcontext(&v); + + if ( x < 20 ) { + x++; + getcontext(&w); + setcontext(&u); + } + + printf("End, y = %d\n", y); + ATF_REQUIRE_EQ(y, 21); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, ucontext_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_umask.c b/contrib/netbsd-tests/lib/libc/sys/t_umask.c new file mode 100644 index 0000000..fb3e405 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_umask.c @@ -0,0 +1,206 @@ +/* $NetBSD: t_umask.c,v 1.2 2017/01/13 19:34:19 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_umask.c,v 1.2 2017/01/13 19:34:19 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include + +static const char path[] = "umask"; +static const mode_t mask[] = { + S_IRWXU, + S_IRUSR, + S_IWUSR, + S_IXUSR, + S_IRWXG, + S_IRGRP, + S_IWGRP, + S_IXGRP, + S_IRWXO, + S_IROTH, + S_IWOTH, + S_IXOTH +}; + +ATF_TC_WITH_CLEANUP(umask_fork); +ATF_TC_HEAD(umask_fork, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that umask(2) is inherited"); +} + +ATF_TC_BODY(umask_fork, tc) +{ + mode_t mode; + pid_t pid; + size_t i; + int sta; + + for (i = 0; i < __arraycount(mask) - 1; i++) { + + (void)umask(mask[i] | mask[i + 1]); + + pid = fork(); + + if (pid < 0) + continue; + + if (pid == 0) { + + mode = umask(mask[i]); + + if (mode != (mask[i] | mask[i + 1])) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + goto fail; + } + + return; + +fail: + (void)umask(S_IWGRP | S_IWOTH); + + atf_tc_fail("umask(2) was not inherited"); +} + +ATF_TC_CLEANUP(umask_fork, tc) +{ + (void)umask(S_IWGRP | S_IWOTH); +} + +ATF_TC_WITH_CLEANUP(umask_open); +ATF_TC_HEAD(umask_open, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of open(2) and umask(2)"); +} + +ATF_TC_BODY(umask_open, tc) +{ + const char *str = NULL; + struct stat st; + size_t i; + int fd; + + for (i = 0; i < __arraycount(mask); i++) { + + (void)umask(mask[i]); + + fd = open(path, O_RDWR | O_CREAT, 0777); + + if (fd < 0) + continue; + + (void)close(fd); + (void)memset(&st, 0, sizeof(struct stat)); + + if (stat(path, &st) != 0) { + str = "failed to stat(2)"; + goto out; + } + + if ((st.st_mode & mask[i]) != 0) { + str = "invalid umask(2)"; + goto out; + } + + if (unlink(path) != 0) { + str = "failed to unlink(2)"; + goto out; + } + + } + +out: + (void)umask(S_IWGRP | S_IWOTH); + + if (str != NULL) + atf_tc_fail("%s", str); +} + +ATF_TC_CLEANUP(umask_open, tc) +{ + (void)umask(S_IWGRP | S_IWOTH); + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(umask_previous); +ATF_TC_HEAD(umask_previous, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test the return value from umask(2)"); +} + +ATF_TC_BODY(umask_previous, tc) +{ + mode_t mode; + size_t i; + + for (i = 0; i < __arraycount(mask); i++) { + + mode = umask(mask[i]); + mode = umask(mask[i]); + + if (mode != mask[i]) + goto fail; + } + + return; + +fail: + (void)umask(S_IWGRP | S_IWOTH); + + atf_tc_fail("umask(2) did not return the previous mask"); +} + +ATF_TC_CLEANUP(umask_previous, tc) +{ + (void)umask(S_IWGRP | S_IWOTH); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, umask_fork); + ATF_TP_ADD_TC(tp, umask_open); + ATF_TP_ADD_TC(tp, umask_previous); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_unlink.c b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c new file mode 100644 index 0000000..cda9c16 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c @@ -0,0 +1,162 @@ +/* $NetBSD: t_unlink.c,v 1.4 2017/01/14 20:55:26 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_unlink.c,v 1.4 2017/01/14 20:55:26 christos Exp $"); + +#include + +#include +#include +#include +#include +#include +#include + +static char path[] = "unlink"; + +ATF_TC_WITH_CLEANUP(unlink_basic); +ATF_TC_HEAD(unlink_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of unlink(2)"); +} + +ATF_TC_BODY(unlink_basic, tc) +{ + const size_t n = 512; + size_t i; + int fd; + + for (i = 0; i < n; i++) { + + fd = open(path, O_RDWR | O_CREAT, 0666); + + ATF_REQUIRE(fd != -1); + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, open(path, O_RDONLY) == -1); + } +} + +ATF_TC_CLEANUP(unlink_basic, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(unlink_err); +ATF_TC_HEAD(unlink_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test error conditions of unlink(2)"); +} + +ATF_TC_BODY(unlink_err, tc) +{ + char buf[PATH_MAX + 1]; + + (void)memset(buf, 'x', sizeof(buf)); + + errno = 0; +#ifdef __FreeBSD__ + ATF_REQUIRE_ERRNO(EISDIR, unlink("/") == -1); +#else + ATF_REQUIRE_ERRNO(EBUSY, unlink("/") == -1); +#endif + + errno = 0; + ATF_REQUIRE_ERRNO(ENAMETOOLONG, unlink(buf) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, unlink("/a/b/c/d/e/f/g/h/i/j/k/l/m") == -1); +} + +ATF_TC_CLEANUP(unlink_err, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(unlink_fifo); +ATF_TC_HEAD(unlink_fifo, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test unlink(2) for a FIFO"); +} + +ATF_TC_BODY(unlink_fifo, tc) +{ + + ATF_REQUIRE(mkfifo(path, 0666) == 0); + ATF_REQUIRE(unlink(path) == 0); + + errno = 0; + ATF_REQUIRE_ERRNO(ENOENT, open(path, O_RDONLY) == -1); +} + +ATF_TC_CLEANUP(unlink_fifo, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(unlink_perm); +ATF_TC_HEAD(unlink_perm, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test permissions with unlink(2)"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(unlink_perm, tc) +{ + int rv; + + errno = 0; + rv = unlink("/etc"); + ATF_REQUIRE_MSG(rv == -1 && (errno == EACCES || errno == EPERM), + "unlinking a directory did not fail with EPERM or EACCESS; " + "unlink() returned %d, errno %d", rv, errno); + + errno = 0; + ATF_REQUIRE_ERRNO(EACCES, unlink("/root/.profile") == -1); +} + +ATF_TC_CLEANUP(unlink_perm, tc) +{ + (void)unlink(path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, unlink_basic); + ATF_TP_ADD_TC(tp, unlink_err); + ATF_TP_ADD_TC(tp, unlink_fifo); + ATF_TP_ADD_TC(tp, unlink_perm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_wait.c b/contrib/netbsd-tests/lib/libc/sys/t_wait.c new file mode 100644 index 0000000..91bbaf1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_wait.c @@ -0,0 +1,320 @@ +/* $NetBSD: t_wait.c,v 1.8 2017/01/13 19:28:55 christos Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_wait.c,v 1.8 2017/01/13 19:28:55 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +ATF_TC(wait6_invalid); +ATF_TC_HEAD(wait6_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) returns EINVAL with 0 options"); +} + +ATF_TC_BODY(wait6_invalid, tc) +{ + siginfo_t si; + struct wrusage wru; + int st; + ATF_REQUIRE(wait6(P_ALL, 0, &st, 0, &wru, &si) == -1 + && errno == EINVAL); +} + +ATF_TC(wait6_exited); +ATF_TC_HEAD(wait6_exited, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) handled exiting process and code"); +} + +ATF_TC_BODY(wait6_exited, tc) +{ + siginfo_t si; + struct wrusage wru; + int st; + pid_t pid; + + switch (pid = fork()) { + case -1: + ATF_REQUIRE(pid > 0); + case 0: + exit(0x5a5a5a5a); + /*NOTREACHED*/ + default: + ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); + ATF_REQUIRE(WIFEXITED(st) && WEXITSTATUS(st) == 0x5a); + ATF_REQUIRE(si.si_status = 0x5a5a5a5a); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_EXITED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif + break; + } +} + +ATF_TC(wait6_terminated); +ATF_TC_HEAD(wait6_terminated, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) handled terminated process and code"); +} + +ATF_TC_BODY(wait6_terminated, tc) +{ + siginfo_t si; + struct wrusage wru; + int st; + pid_t pid; + + switch (pid = fork()) { + case 0: + sleep(100); + /*FALLTHROUGH*/ + case -1: + ATF_REQUIRE(pid > 0); + default: + ATF_REQUIRE(kill(pid, SIGTERM) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); + ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGTERM); + ATF_REQUIRE(si.si_status == SIGTERM); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_KILLED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif + break; + } +} + +ATF_TC(wait6_coredumped); +ATF_TC_HEAD(wait6_coredumped, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) handled coredumped process and code"); +} + +ATF_TC_BODY(wait6_coredumped, tc) +{ + siginfo_t si; + struct wrusage wru; + int st; + pid_t pid; + static const struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; + + switch (pid = fork()) { + case 0: + ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); + *(char *)8 = 0; + /*FALLTHROUGH*/ + case -1: + ATF_REQUIRE(pid > 0); + default: + ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); + ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGSEGV + && WCOREDUMP(st)); + ATF_REQUIRE(si.si_status == SIGSEGV); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_DUMPED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif + break; + } +} + +ATF_TC(wait6_stop_and_go); +ATF_TC_HEAD(wait6_stop_and_go, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) handled stopped/continued process and code"); +} + +ATF_TC_BODY(wait6_stop_and_go, tc) +{ + siginfo_t si; + struct wrusage wru; + int st; + pid_t pid; + static const struct rlimit rl = { 0, 0 }; + + ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); + switch (pid = fork()) { + case 0: + sleep(100); + /*FALLTHROUGH*/ + case -1: + ATF_REQUIRE(pid > 0); + default: + ATF_REQUIRE(kill(pid, SIGSTOP) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WSTOPPED, &wru, &si) == pid); + ATF_REQUIRE(!WIFEXITED(st)); + ATF_REQUIRE(!WIFSIGNALED(st)); + ATF_REQUIRE(WIFSTOPPED(st) && WSTOPSIG(st) == SIGSTOP); + ATF_REQUIRE(!WIFCONTINUED(st)); + ATF_REQUIRE(si.si_status == SIGSTOP); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_STOPPED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif + + ATF_REQUIRE(kill(pid, SIGCONT) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WCONTINUED, &wru, &si) == pid); + ATF_REQUIRE(!WIFEXITED(st)); + ATF_REQUIRE(!WIFSIGNALED(st)); + ATF_REQUIRE(WIFCONTINUED(st)); + ATF_REQUIRE(!WIFSTOPPED(st)); + ATF_REQUIRE(si.si_status == SIGCONT); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_CONTINUED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif + + ATF_REQUIRE(kill(pid, SIGQUIT) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); + ATF_REQUIRE(!WIFEXITED(st)); + ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGQUIT); + ATF_REQUIRE(!WIFSTOPPED(st)); + ATF_REQUIRE(!WIFCONTINUED(st)); + ATF_REQUIRE(si.si_status == SIGQUIT); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_KILLED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif + break; + } +} + +ATF_TC(wait6_stopgo_loop); +ATF_TC_HEAD(wait6_stopgo_loop, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) handled stopped/continued process loop"); +} + +ATF_TC_BODY(wait6_stopgo_loop, tc) +{ + siginfo_t si; + struct wrusage wru; + int st; + pid_t pid; + static const struct rlimit rl = { 0, 0 }; + size_t N = 100; + + ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0); + switch (pid = fork()) { + case 0: + sleep(100); + /*FALLTHROUGH*/ + case -1: + ATF_REQUIRE(pid > 0); + } + + printf("Before loop of SIGSTOP/SIGCONT sequence %zu times\n", N); + while (N --> 0) { + ATF_REQUIRE(kill(pid, SIGSTOP) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WSTOPPED, &wru, &si) == pid); + ATF_REQUIRE(!WIFEXITED(st)); + ATF_REQUIRE(!WIFSIGNALED(st)); + ATF_REQUIRE(WIFSTOPPED(st) && WSTOPSIG(st) == SIGSTOP); + ATF_REQUIRE(!WIFCONTINUED(st)); + ATF_REQUIRE(si.si_status == SIGSTOP); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_STOPPED); + + ATF_REQUIRE(kill(pid, SIGCONT) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WCONTINUED, &wru, &si) == pid); + ATF_REQUIRE(!WIFEXITED(st)); + ATF_REQUIRE(!WIFSIGNALED(st)); + ATF_REQUIRE(WIFCONTINUED(st)); + ATF_REQUIRE(!WIFSTOPPED(st)); + ATF_REQUIRE(si.si_status == SIGCONT); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_CONTINUED); + } + ATF_REQUIRE(kill(pid, SIGQUIT) == 0); + ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid); + ATF_REQUIRE(!WIFEXITED(st)); + ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGQUIT); + ATF_REQUIRE(!WIFSTOPPED(st)); + ATF_REQUIRE(!WIFCONTINUED(st)); + ATF_REQUIRE(si.si_status == SIGQUIT); + ATF_REQUIRE(si.si_pid == pid); + ATF_REQUIRE(si.si_uid == getuid()); + ATF_REQUIRE(si.si_code == CLD_KILLED); +#ifdef __NetBSD__ + printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime, + (uintmax_t)si.si_utime); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, wait6_invalid); + ATF_TP_ADD_TC(tp, wait6_exited); + ATF_TP_ADD_TC(tp, wait6_terminated); + ATF_TP_ADD_TC(tp, wait6_coredumped); + ATF_TP_ADD_TC(tp, wait6_stop_and_go); + ATF_TP_ADD_TC(tp, wait6_stopgo_loop); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_wait_noproc.c b/contrib/netbsd-tests/lib/libc/sys/t_wait_noproc.c new file mode 100644 index 0000000..c529f17 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_wait_noproc.c @@ -0,0 +1,342 @@ +/* $NetBSD: t_wait_noproc.c,v 1.5 2016/11/09 17:50:19 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_wait_noproc.c,v 1.5 2016/11/09 17:50:19 kamil Exp $"); + +#include +#include + +#include +#include + +#include + +#ifndef TWAIT_OPTION +#define TWAIT_OPTION 0 +#endif + +#if TWAIT_OPTION == 0 +ATF_TC(wait); +ATF_TC_HEAD(wait, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait(2) returns ECHILD for no child"); +} + +ATF_TC_BODY(wait, tc) +{ + ATF_REQUIRE_ERRNO(ECHILD, wait(NULL) == -1); +} +#endif + +ATF_TC(waitpid); +ATF_TC_HEAD(waitpid, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that waitpid(2) returns ECHILD for WAIT_ANY and option %s", + ___STRING(TWAIT_OPTION)); +} + +ATF_TC_BODY(waitpid, tc) +{ + ATF_REQUIRE_ERRNO(ECHILD, waitpid(WAIT_ANY, NULL, TWAIT_OPTION) == -1); +} + +ATF_TC(waitid); +ATF_TC_HEAD(waitid, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that waitid(2) returns ECHILD for P_ALL and option %s", + ___STRING(TWAIT_OPTION)); +} + +ATF_TC_BODY(waitid, tc) +{ + ATF_REQUIRE_ERRNO(ECHILD, + waitid(P_ALL, 0, NULL, + WTRAPPED | WEXITED | TWAIT_OPTION) == -1); +} + +ATF_TC(wait3); +ATF_TC_HEAD(wait3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait3(2) returns ECHILD for no child"); +} + +ATF_TC_BODY(wait3, tc) +{ + ATF_REQUIRE_ERRNO(ECHILD, wait3(NULL, TWAIT_OPTION, NULL) == -1); +} + +ATF_TC(wait4); +ATF_TC_HEAD(wait4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait4(2) returns ECHILD for WAIT_ANY and option %s", + ___STRING(TWAIT_OPTION)); +} + +ATF_TC_BODY(wait4, tc) +{ + ATF_REQUIRE_ERRNO(ECHILD, + wait4(WAIT_ANY, NULL, TWAIT_OPTION, NULL) == -1); +} + +ATF_TC(wait6); +ATF_TC_HEAD(wait6, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) returns ECHILD for P_ALL and option %s", + ___STRING(TWAIT_OPTION)); +} + +ATF_TC_BODY(wait6, tc) +{ + ATF_REQUIRE_ERRNO(ECHILD, + wait6(P_ALL, 0, NULL, + WTRAPPED | WEXITED | TWAIT_OPTION, NULL, NULL) == -1); +} + +/* + * Generator of valid combinations of options + * Usage: i = 0; while ((o = get_options_wait6(i++)) != -1) {} + */ +static int +get_options6(size_t pos) +{ + int rv = 0; + size_t n; + + /* + * waitid(2) must specify at least one of WEXITED, WUNTRACED, + * WSTOPPED, WTRAPPED or WCONTINUED. Single option WNOWAIT + * isn't valid. + */ + + const int matrix[] = { + WNOWAIT, /* First in order to blacklist it easily */ + WEXITED, + WUNTRACED, + WSTOPPED, /* SUS compatibility, equal to WUNTRACED */ + WTRAPPED, + WCONTINUED + }; + + const size_t M = (1 << __arraycount(matrix)) - 1; + + /* Skip empty and sole WNOWAIT option */ + pos+=2; + + if (pos > M) + return -1; + + for (n = 0; n < __arraycount(matrix); n++) { + if (pos & __BIT(n)) + rv |= matrix[n]; + } + + return rv; +} + +/* + * Generator of valid combinations of options + * Usage: i = 0; while ((o = get_options_wait4(i++)) != -1) {} + */ +static int +get_options4(size_t pos) +{ + int rv = 0; + size_t n; + + const int special[] = { + 0, +#ifdef __NetBSD__ + WALLSIG, + WALTSIG, + __WALL, /* Linux compatibility, equal to WALLSIG */ + __WCLONE /* Linux compatibility, equal to WALTSIG */ +#endif + }; + + const int matrix[] = { + WNOWAIT, + WEXITED, + WUNTRACED, + WSTOPPED, /* SUS compatibility, equal to WUNTRACED */ + WTRAPPED, + WCONTINUED + }; + + const size_t M = (1 << __arraycount(special)) - 1; + + if (pos < __arraycount(special)) + return special[pos]; + + pos -= __arraycount(special); + + ++pos; /* Don't start with empty mask */ + + if (pos > M) + return -1; + + for (n = 0; n < __arraycount(special); n++) { + if (pos & __BIT(n)) + rv |= matrix[n]; + } + + return rv; +} + +ATF_TC(waitpid_options); +ATF_TC_HEAD(waitpid_options, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that waitpid(2) returns ECHILD for WAIT_ANY and valid " + "combination of options with%s WNOHANG", + TWAIT_OPTION == 0 ? "out" : ""); +} + +ATF_TC_BODY(waitpid_options, tc) +{ + size_t i = 0; + int o; + + while((o = get_options4(i++)) != -1) { + printf("Testing waitpid(2) with options %x\n", o); + + ATF_REQUIRE_ERRNO(ECHILD, + waitpid(WAIT_ANY, NULL, o | TWAIT_OPTION) == -1); + } +} + +ATF_TC(waitid_options); +ATF_TC_HEAD(waitid_options, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that waitid(2) returns ECHILD for P_ALL and valid " + "combination of options with%s WNOHANG", + TWAIT_OPTION == 0 ? "out" : ""); +} + +ATF_TC_BODY(waitid_options, tc) +{ + size_t i = 0; + int o; + + while((o = get_options6(i++)) != -1) { + printf("Testing waitid(2) with options %x\n", o); + + ATF_REQUIRE_ERRNO(ECHILD, + waitid(P_ALL, 0, NULL, o | TWAIT_OPTION) == -1); + } +} + +ATF_TC(wait3_options); +ATF_TC_HEAD(wait3_options, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait3(2) returns ECHILD for no child"); +} + +ATF_TC_BODY(wait3_options, tc) +{ + size_t i = 0; + int o; + + while((o = get_options4(i++)) != -1) { + printf("Testing wait3(2) with options %x\n", o); + + ATF_REQUIRE_ERRNO(ECHILD, + wait3(NULL, o | TWAIT_OPTION, NULL) == -1); + } +} + +ATF_TC(wait4_options); +ATF_TC_HEAD(wait4_options, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait4(2) returns ECHILD for WAIT_ANY and option %s", + ___STRING(TWAIT_OPTION)); +} + +ATF_TC_BODY(wait4_options, tc) +{ + size_t i = 0; + int o; + + while((o = get_options4(i++)) != -1) { + printf("Testing wait4(2) with options %x\n", o); + + ATF_REQUIRE_ERRNO(ECHILD, + wait4(WAIT_ANY, NULL, o | TWAIT_OPTION, NULL) == -1); + } +} + +ATF_TC(wait6_options); +ATF_TC_HEAD(wait6_options, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that wait6(2) returns ECHILD for P_ALL and option %s", + ___STRING(TWAIT_OPTION)); +} + +ATF_TC_BODY(wait6_options, tc) +{ + size_t i = 0; + int o; + + while((o = get_options6(i++)) != -1) { + printf("Testing wait6(2) with options %x\n", o); + + ATF_REQUIRE_ERRNO(ECHILD, + wait6(P_ALL, 0, NULL, o | TWAIT_OPTION, NULL, NULL) == -1); + } +} + +ATF_TP_ADD_TCS(tp) +{ + +#if TWAIT_OPTION == 0 + ATF_TP_ADD_TC(tp, wait); +#endif + ATF_TP_ADD_TC(tp, waitpid); + ATF_TP_ADD_TC(tp, waitid); + ATF_TP_ADD_TC(tp, wait3); + ATF_TP_ADD_TC(tp, wait4); + ATF_TP_ADD_TC(tp, wait6); + + ATF_TP_ADD_TC(tp, waitpid_options); + ATF_TP_ADD_TC(tp, waitid_options); + ATF_TP_ADD_TC(tp, wait3_options); + ATF_TP_ADD_TC(tp, wait4_options); + ATF_TP_ADD_TC(tp, wait6_options); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/sys/t_wait_noproc_wnohang.c b/contrib/netbsd-tests/lib/libc/sys/t_wait_noproc_wnohang.c new file mode 100644 index 0000000..45a9998 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_wait_noproc_wnohang.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_wait_noproc_wnohang.c,v 1.1 2016/11/06 15:03:30 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TWAIT_OPTION WNOHANG +#include "t_wait_noproc.c" diff --git a/contrib/netbsd-tests/lib/libc/sys/t_write.c b/contrib/netbsd-tests/lib/libc/sys/t_write.c new file mode 100644 index 0000000..576ce7e --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/sys/t_write.c @@ -0,0 +1,226 @@ +/* $NetBSD: t_write.c,v 1.3 2017/01/13 19:27:23 christos Exp $ */ + +/*- + * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_write.c,v 1.3 2017/01/13 19:27:23 christos Exp $"); + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void sighandler(int); + +static bool fail = false; +static const char *path = "write"; + +static void +sighandler(int signo __unused) +{ + fail = false; +} + +ATF_TC_WITH_CLEANUP(write_err); +ATF_TC_HEAD(write_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks errors from write(2)"); +} + +ATF_TC_BODY(write_err, tc) +{ + char rbuf[3] = { 'a', 'b', 'c' }; + char wbuf[3] = { 'x', 'y', 'z' }; + int fd; + + errno = 0; + ATF_REQUIRE_ERRNO(EBADF, write(-1, wbuf, sizeof(wbuf)) == -1); + + fd = open(path, O_RDWR | O_CREAT); + + if (fd >= 0) { + + errno = 0; + ATF_REQUIRE_ERRNO(0, write(fd, wbuf, 3) == 3); + + errno = 0; + ATF_REQUIRE_ERRNO(EINVAL, write(fd, wbuf, SIZE_MAX) == -1); + + errno = 0; + ATF_REQUIRE_ERRNO(EFAULT, write(fd, (void *)-1, 1) == -1); + + /* + * Check that the above bogus write(2) + * calls did not corrupt the file. + */ + ATF_REQUIRE(lseek(fd, 0, SEEK_SET) == 0); + ATF_REQUIRE(read(fd, rbuf, 3) == 3); + ATF_REQUIRE(memcmp(rbuf, wbuf, 3) == 0); + + (void)close(fd); + (void)unlink(path); + } +} + +ATF_TC_CLEANUP(write_err, tc) +{ + (void)unlink(path); +} + +ATF_TC(write_pipe); +ATF_TC_HEAD(write_pipe, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks for EPIPE from write(2)"); +} + +ATF_TC_BODY(write_pipe, tc) +{ + int fds[2]; + + ATF_REQUIRE(pipe(fds) == 0); + ATF_REQUIRE(signal(SIGPIPE, sighandler) == 0); + + ATF_REQUIRE(write(fds[1], "x", 1) != -1); + ATF_REQUIRE(close(fds[0]) == 0); + + errno = 0; + fail = true; + + if (write(fds[1], "x", 1) != -1 || errno != EPIPE) + atf_tc_fail_nonfatal("expected EPIPE but write(2) succeeded"); + + ATF_REQUIRE(close(fds[1]) == 0); + + if (fail != false) + atf_tc_fail_nonfatal("SIGPIPE was not raised"); +} + +ATF_TC_WITH_CLEANUP(write_pos); +ATF_TC_HEAD(write_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that write(2) " + "updates the file position"); +} + +ATF_TC_BODY(write_pos, tc) +{ + const size_t n = 123; + size_t i; + int fd; + + fd = open(path, O_RDWR | O_CREAT); + ATF_REQUIRE(fd >= 0); + + for (i = 0; i < n; i++) { + ATF_REQUIRE(write(fd, "x", 1) == 1); + ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == (off_t)(i + 1)); + } + + ATF_REQUIRE(close(fd) == 0); + ATF_REQUIRE(unlink(path) == 0); +} + +ATF_TC_CLEANUP(write_pos, tc) +{ + (void)unlink(path); +} + +ATF_TC_WITH_CLEANUP(write_ret); +ATF_TC_HEAD(write_ret, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks return values from write(2)"); +} + +ATF_TC_BODY(write_ret, tc) +{ + const size_t n = 99; + char buf[123]; + size_t i, j; + int fd; + + fd = open(path, O_WRONLY | O_CREAT); + ATF_REQUIRE(fd >= 0); + + (void)memset(buf, 'x', sizeof(buf)); + + for (i = j = 0; i < n; i++) + j += write(fd, buf, sizeof(buf)); + + if (j != n * 123) + atf_tc_fail("inconsistent return values from write(2)"); + + (void)close(fd); + (void)unlink(path); +} + +ATF_TC_CLEANUP(write_ret, tc) +{ + (void)unlink(path); +} + +ATF_TC(writev_iovmax); +ATF_TC_HEAD(writev_iovmax, tc) +{ + atf_tc_set_md_var(tc, "timeout", "10"); + atf_tc_set_md_var(tc, "descr", + "Checks that file descriptor is properly FILE_UNUSE()d " + "when iovcnt is greater than IOV_MAX"); +} + +ATF_TC_BODY(writev_iovmax, tc) +{ + ssize_t retval; + + (void)printf("Calling writev(2, NULL, IOV_MAX + 1)...\n"); + + errno = 0; + retval = writev(2, NULL, IOV_MAX + 1); + + ATF_REQUIRE_EQ_MSG(retval, -1, "got: %zd", retval); + ATF_REQUIRE_EQ_MSG(errno, EINVAL, "got: %s", strerror(errno)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, write_err); + ATF_TP_ADD_TC(tp, write_pipe); + ATF_TP_ADD_TC(tp, write_pos); + ATF_TP_ADD_TC(tp, write_ret); + ATF_TP_ADD_TC(tp, writev_iovmax); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/t_cdb.c b/contrib/netbsd-tests/lib/libc/t_cdb.c new file mode 100644 index 0000000..97da4a3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/t_cdb.c @@ -0,0 +1,161 @@ +/* $NetBSD: t_cdb.c,v 1.2 2017/01/10 22:24:29 christos Exp $ */ +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_cdb.c,v 1.2 2017/01/10 22:24:29 christos Exp $"); + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MAXKEYS 16384 + +static const char database_name[] = "test.cdb"; + +uint32_t keys[MAXKEYS]; + +static int +cmp_keys(const void *a_, const void *b_) +{ + uint32_t a = *(const uint32_t *)a_; + uint32_t b = *(const uint32_t *)b_; + + return a > b ? 1 : (a < b ? 1 : 0); +} + +static void +init_keys(size_t len) +{ + uint32_t sorted_keys[MAXKEYS]; + size_t i; + + assert(len <= MAXKEYS); + + if (len == 0) + return; + + do { + for (i = 0; i < len; ++i) + sorted_keys[i] = keys[i] = arc4random(); + + qsort(sorted_keys, len, sizeof(*sorted_keys), cmp_keys); + for (i = 1; i < len; ++i) { + if (sorted_keys[i - 1] == sorted_keys[i]) + break; + } + } while (i != len); +} + +static void +write_database(size_t len) +{ + struct cdbw *db; + int fd; + size_t i; + uint32_t buf[2]; + + ATF_REQUIRE((db = cdbw_open()) != NULL); + ATF_REQUIRE((fd = creat(database_name, S_IRUSR|S_IWUSR)) != -1); + for (i = 0; i < len; ++i) { + buf[0] = i; + buf[1] = keys[i]; + ATF_REQUIRE(cdbw_put(db, &keys[i], sizeof(keys[i]), + buf, sizeof(buf)) == 0); + } + ATF_REQUIRE(cdbw_output(db, fd, "test database", arc4random) == 0); + cdbw_close(db); + ATF_REQUIRE(close(fd) == 0); +} + +static void +check_database(size_t len) +{ + struct cdbr *db; + size_t i, data_len; + const void *data; + uint32_t buf[2]; + + ATF_REQUIRE((db = cdbr_open(database_name, CDBR_DEFAULT)) != NULL); + ATF_REQUIRE_EQ(cdbr_entries(db), len); + for (i = 0; i < len; ++i) { + ATF_REQUIRE(cdbr_find(db, &keys[i], sizeof(keys[i]), + &data, &data_len) != -1); + ATF_REQUIRE_EQ(data_len, sizeof(buf)); + memcpy(buf, data, sizeof(buf)); + ATF_REQUIRE_EQ(buf[0], i); + ATF_REQUIRE_EQ(buf[1], keys[i]); + } + cdbr_close(db); +} + +ATF_TC_WITH_CLEANUP(cdb); + +ATF_TC_HEAD(cdb, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test cdb(5) reading and writing"); +} + +ATF_TC_BODY(cdb, tc) +{ + size_t i, sizes[] = { 0, 16, 64, 1024, 2048 }; + for (i = 0; i < __arraycount(sizes); ++i) { + init_keys(sizes[i]); + write_database(sizes[i]); + check_database(sizes[i]); + unlink(database_name); + } +} + +ATF_TC_CLEANUP(cdb, tc) +{ + + unlink(database_name); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cdb); + + return atf_no_error(); +} + diff --git a/contrib/netbsd-tests/lib/libc/t_convfp.c b/contrib/netbsd-tests/lib/libc/t_convfp.c new file mode 100644 index 0000000..de68690 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/t_convfp.c @@ -0,0 +1,155 @@ +/* $NetBSD: t_convfp.c,v 1.7 2011/06/14 11:58:22 njoly Exp $ */ + +/*- + * Copyright (c) 2003 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include + +/* + * This value is representable as an unsigned int, but not as an int. + * According to ISO C it must survive the convsion back from a double + * to an unsigned int (everything > -1 and < UINT_MAX+1 has to) + */ +#define UINT_TESTVALUE (INT_MAX+42U) + +/* The same for unsigned long */ +#define ULONG_TESTVALUE (LONG_MAX+42UL) + + +ATF_TC(conv_uint); +ATF_TC_HEAD(conv_uint, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test conversions to unsigned int"); +} + +ATF_TC_BODY(conv_uint, tc) +{ + unsigned int ui; + double d; + + /* unsigned int test */ + d = UINT_TESTVALUE; + ui = (unsigned int)d; + + if (ui != UINT_TESTVALUE) + atf_tc_fail("FAILED: unsigned int %u (0x%x) != %u (0x%x)", + ui, ui, UINT_TESTVALUE, UINT_TESTVALUE); +} + +ATF_TC(conv_ulong); + +ATF_TC_HEAD(conv_ulong, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test conversions to unsigned long"); +} + +ATF_TC_BODY(conv_ulong, tc) +{ + unsigned long ul; + long double dt; + double d; + + /* unsigned long vs. {long} double test */ + if (sizeof(d) > sizeof(ul)) { + d = ULONG_TESTVALUE; + ul = (unsigned long)d; + printf("testing double vs. long\n"); + } else if (sizeof(dt) > sizeof(ul)) { + dt = ULONG_TESTVALUE; + ul = (unsigned long)dt; + printf("testing long double vs. long\n"); + } else { + printf("sizeof(long) = %zu, sizeof(double) = %zu, " + "sizeof(long double) = %zu\n", + sizeof(ul), sizeof(d), sizeof(dt)); + atf_tc_skip("no suitable {long} double type found"); + } + + if (ul != ULONG_TESTVALUE) + atf_tc_fail("unsigned long %lu (0x%lx) != %lu (0x%lx)", + ul, ul, ULONG_TESTVALUE, ULONG_TESTVALUE); +} + +ATF_TC(cast_ulong); + +ATF_TC_HEAD(cast_ulong, tc) +{ + + atf_tc_set_md_var(tc, "descr", "test double to unsigned long cast"); +} + +ATF_TC_BODY(cast_ulong, tc) +{ + double nv; + unsigned long uv; + + nv = 5.6; + uv = (unsigned long)nv; + + ATF_CHECK_EQ_MSG(uv, 5, + "%.3f casted to unsigned long is %lu", nv, uv); +} + +ATF_TC(cast_ulong2); + +ATF_TC_HEAD(cast_ulong2, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "test double/long double casts to unsigned long"); +} + +ATF_TC_BODY(cast_ulong2, tc) +{ + double dv = 1.9; + long double ldv = dv; + unsigned long l1 = dv; + unsigned long l2 = ldv; + + ATF_CHECK_EQ_MSG(l1, 1, + "double 1.9 casted to unsigned long should be 1, but is %lu", l1); + + ATF_CHECK_EQ_MSG(l2, 1, + "long double 1.9 casted to unsigned long should be 1, but is %lu", + l2); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, conv_uint); + ATF_TP_ADD_TC(tp, conv_ulong); + ATF_TP_ADD_TC(tp, cast_ulong); + ATF_TP_ADD_TC(tp, cast_ulong2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/t_gdtoa.c b/contrib/netbsd-tests/lib/libc/t_gdtoa.c new file mode 100644 index 0000000..e040603 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/t_gdtoa.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_gdtoa.c,v 1.4 2012/09/27 08:19:18 martin Exp $"); + +#include + +#include +#include + +/* reported by Maksymilian Arciemowicz */ + +ATF_TC(long_format); + +ATF_TC_HEAD(long_format, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test printf with %%1.262159f format"); +} + +ATF_TC_BODY(long_format, tc) +{ + char *buf; + ATF_REQUIRE_EQ(262161, asprintf(&buf, "%1.262159f", 1.1)); + free(buf); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, long_format); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c b/contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c new file mode 100644 index 0000000..66b1735 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c @@ -0,0 +1,87 @@ +/* $NetBSD: t_tcsetpgrp.c,v 1.3 2012/03/18 07:14:08 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_tcsetpgrp.c,v 1.3 2012/03/18 07:14:08 jruoho Exp $"); + +#include + +#include +#include +#include +#include + +ATF_TC(tcsetpgrp_err); +ATF_TC_HEAD(tcsetpgrp_err, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test errors from tcsetpgrp(3)" + " (PR lib/41673)"); +} + +ATF_TC_BODY(tcsetpgrp_err, tc) +{ + int rv, sta; + pid_t pid; + + if (isatty(STDIN_FILENO) == 0) + return; + + pid = fork(); + ATF_REQUIRE(pid >= 0); + + if (pid == 0) { + + /* + * The child process ID doesn't match any active + * process group ID, so the following call should + * fail with EPERM (and not EINVAL). + */ + errno = 0; + rv = tcsetpgrp(STDIN_FILENO, getpid()); + + if (rv == 0 || errno != EPERM) + _exit(EXIT_FAILURE); + + _exit(EXIT_SUCCESS); + } + + (void)wait(&sta); + + if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) + atf_tc_fail("wrong errno"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, tcsetpgrp_err); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/time/t_mktime.c b/contrib/netbsd-tests/lib/libc/time/t_mktime.c new file mode 100644 index 0000000..8092361 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/time/t_mktime.c @@ -0,0 +1,155 @@ +/* $NetBSD: t_mktime.c,v 1.5 2012/03/18 07:33:58 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include +#include + +ATF_TC(localtime_r_gmt); +ATF_TC_HEAD(localtime_r_gmt, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that localtime_r(3) " + "returns localtime, not GMT (PR lib/28324)"); +} + +ATF_TC_BODY(localtime_r_gmt, tc) +{ + struct tm *t; + struct tm tt; + time_t x; + + x = time(NULL); + localtime_r(&x, &tt); + t = localtime(&x); + + if (t->tm_sec != tt.tm_sec || t->tm_min != tt.tm_min || + t->tm_hour != tt.tm_hour || t->tm_mday != tt.tm_mday) + atf_tc_fail("inconsistencies between " + "localtime(3) and localtime_r(3)"); +} + +ATF_TC(mktime_negyear); +ATF_TC_HEAD(mktime_negyear, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mktime(3) with negative year"); +} + +ATF_TC_BODY(mktime_negyear, tc) +{ + struct tm tms; + time_t t; + + (void)memset(&tms, 0, sizeof(tms)); + tms.tm_year = ~0; + + errno = 0; + t = mktime(&tms); + ATF_REQUIRE_ERRNO(0, t != (time_t)-1); +} + +ATF_TC(timegm_epoch); +ATF_TC_HEAD(timegm_epoch, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test timegm(3) close to the epoch"); +} + +ATF_TC_BODY(timegm_epoch, tc) +{ + struct tm tms; + time_t t; + + /* midnight on 1 Jan 1970 */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1970 - 1900; + tms.tm_mday = 1; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)0); + + /* one second after midnight on 1 Jan 1970 */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1970 - 1900; + tms.tm_mday = 1; + tms.tm_sec = 1; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)1); + + /* + * 1969-12-31 23:59:59 = one second before the epoch. + * Result should be -1 with errno = 0. + */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1969 - 1900; + tms.tm_mon = 12 - 1; + tms.tm_mday = 31; + tms.tm_hour = 23; + tms.tm_min = 59; + tms.tm_sec = 59; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)-1); + + /* + * Another way of getting one second before the epoch: + * Set date to 1 Jan 1970, and time to -1 second. + */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1970 - 1900; + tms.tm_mday = 1; + tms.tm_sec = -1; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)-1); + + /* + * Two seconds before the epoch. + */ + (void)memset(&tms, 0, sizeof(tms)); + errno = 0; + tms.tm_year = 1970 - 1900; + tms.tm_mday = 1; + tms.tm_sec = -2; + t = timegm(&tms); + ATF_REQUIRE_ERRNO(0, t == (time_t)-2); + +} + + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, localtime_r_gmt); + ATF_TP_ADD_TC(tp, mktime_negyear); + ATF_TP_ADD_TC(tp, timegm_epoch); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/time/t_strptime.c b/contrib/netbsd-tests/lib/libc/time/t_strptime.c new file mode 100644 index 0000000..863df36 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/time/t_strptime.c @@ -0,0 +1,486 @@ +/* $NetBSD: t_strptime.c,v 1.12 2015/10/31 02:25:11 christos Exp $ */ + +/*- + * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David Laight. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_strptime.c,v 1.12 2015/10/31 02:25:11 christos Exp $"); + +#include +#include +#include + +#include + +static void +h_pass(const char *buf, const char *fmt, int len, + int tm_sec, int tm_min, int tm_hour, int tm_mday, + int tm_mon, int tm_year, int tm_wday, int tm_yday) +{ + struct tm tm = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL }; + const char *ret, *exp; + + exp = buf + len; + ret = strptime(buf, fmt, &tm); + +#ifdef __FreeBSD__ + ATF_CHECK_MSG(ret == exp, + "strptime(\"%s\", \"%s\", tm): incorrect return code: " + "expected: %p, got: %p", buf, fmt, exp, ret); + +#define H_REQUIRE_FIELD(field) \ + ATF_CHECK_MSG(tm.field == field, \ + "strptime(\"%s\", \"%s\", tm): incorrect %s: " \ + "expected: %d, but got: %d", buf, fmt, \ + ___STRING(field), field, tm.field) +#else + ATF_REQUIRE_MSG(ret == exp, + "strptime(\"%s\", \"%s\", tm): incorrect return code: " + "expected: %p, got: %p", buf, fmt, exp, ret); + +#define H_REQUIRE_FIELD(field) \ + ATF_REQUIRE_MSG(tm.field == field, \ + "strptime(\"%s\", \"%s\", tm): incorrect %s: " \ + "expected: %d, but got: %d", buf, fmt, \ + ___STRING(field), field, tm.field) +#endif + + H_REQUIRE_FIELD(tm_sec); + H_REQUIRE_FIELD(tm_min); + H_REQUIRE_FIELD(tm_hour); + H_REQUIRE_FIELD(tm_mday); + H_REQUIRE_FIELD(tm_mon); + H_REQUIRE_FIELD(tm_year); + H_REQUIRE_FIELD(tm_wday); + H_REQUIRE_FIELD(tm_yday); + +#undef H_REQUIRE_FIELD +} + +static void +h_fail(const char *buf, const char *fmt) +{ + struct tm tm = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL }; + +#ifdef __FreeBSD__ + ATF_CHECK_MSG(strptime(buf, fmt, &tm) == NULL, "strptime(\"%s\", " + "\"%s\", &tm) should fail, but it didn't", buf, fmt); +#else + ATF_REQUIRE_MSG(strptime(buf, fmt, &tm) == NULL, "strptime(\"%s\", " + "\"%s\", &tm) should fail, but it didn't", buf, fmt); +#endif +} + +static struct { + const char *name; + long offs; +} zt[] = { + { "Z", 0 }, + { "UT", 0 }, + { "UTC", 0 }, + { "GMT", 0 }, + { "EST", -18000 }, + { "EDT", -14400 }, + { "CST", -21600 }, + { "CDT", -18000 }, + { "MST", -25200 }, + { "MDT", -21600 }, + { "PST", -28800 }, + { "PDT", -25200 }, + + { "VST", -1 }, + { "VDT", -1 }, + + { "+03", 10800 }, + { "-03", -10800 }, + { "+0403", 14580 }, + { "-0403", -14580 }, + { "+04:03", 14580 }, + { "-04:03", -14580 }, + { "+14:00", 50400 }, + { "-14:00", -50400 }, + { "+23:59", 86340 }, + { "-23:59", -86340 }, + + { "1", -1 }, + { "03", -1 }, + { "0304", -1 }, + { "+1", -1 }, + { "-203", -1 }, + { "+12345", -1 }, + { "+12:345", -1 }, + { "+123:45", -1 }, + { "+2400", -1 }, + { "-2400", -1 }, + { "+1060", -1 }, + { "-1060", -1 }, + + { "A", -3600 }, + { "B", -7200 }, + { "C", -10800 }, + { "D", -14400 }, + { "E", -18000 }, + { "F", -21600 }, + { "G", -25200 }, + { "H", -28800 }, + { "I", -32400 }, + { "L", -39600 }, + { "M", -43200 }, + { "N", 3600 }, + { "O", 7200 }, + { "P", 10800 }, + { "Q", 14400 }, + { "R", 18000 }, + { "T", 25200 }, + { "U", 28800 }, + { "V", 32400 }, + { "W", 36000 }, + { "X", 39600 }, + { "Y", 43200 }, + + { "J", -2 }, + + { "America/Los_Angeles", -28800 }, + { "America/New_York", -18000 }, + { "EST4EDT", -14400 }, + + { "Bogus", -1 }, +}; + +static void +ztest1(const char *name, const char *fmt, long value) +{ + struct tm tm; + char *rv; + + memset(&tm, 0, sizeof(tm)); + if ((rv = strptime(name, fmt, &tm)) == NULL) + tm.tm_gmtoff = -1; + else if (rv == name && fmt[1] == 'Z') + value = 0; + + switch (value) { + case -2: + value = -timezone; + break; + case -1: + if (fmt[1] == 'Z') + value = 0; + break; + default: + break; + } + + ATF_REQUIRE_MSG(tm.tm_gmtoff == value, + "strptime(\"%s\", \"%s\", &tm): " + "expected: tm.tm_gmtoff=%ld, got: tm.tm_gmtoff=%ld", + name, fmt, value, tm.tm_gmtoff); + printf("%s %s %ld\n", name, fmt, tm.tm_gmtoff); +} + +static void +ztest(const char *fmt) +{ + setenv("TZ", "US/Eastern", 1); + ztest1("GMT", fmt, 0); + ztest1("UTC", fmt, 0); + ztest1("US/Eastern", fmt, -18000); + for (size_t i = 0; i < __arraycount(zt); i++) + ztest1(zt[i].name, fmt, zt[i].offs); +} + +ATF_TC(common); + +ATF_TC_HEAD(common, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks strptime(3): various checks"); +} + +ATF_TC_BODY(common, tc) +{ + +#ifdef __FreeBSD__ + atf_tc_expect_fail("There are various issues with strptime on FreeBSD"); +#endif + + h_pass("Tue Jan 20 23:27:46 1998", "%a %b %d %T %Y", + 24, 46, 27, 23, 20, 0, 98, 2, 19); + h_pass("Tue Jan 20 23:27:46 1998", "%a %b %d %H:%M:%S %Y", + 24, 46, 27, 23, 20, 0, 98, 2, 19); + h_pass("Tue Jan 20 23:27:46 1998", "%c", + 24, 46, 27, 23, 20, 0, 98, 2, 19); + h_pass("Fri Mar 4 20:05:34 2005", "%a %b %e %H:%M:%S %Y", + 24, 34, 5, 20, 4, 2, 105, 5, 62); + h_pass("5\t3 4 8pm:05:34 2005", "%w%n%m%t%d%n%k%p:%M:%S %Y", + 21, 34, 5, 20, 4, 2, 105, 5, 62); + h_pass("Fri Mar 4 20:05:34 2005", "%c", + 24, 34, 5, 20, 4, 2, 105, 5, 62); +} + +ATF_TC(day); + +ATF_TC_HEAD(day, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks strptime(3) day name conversions [aA]"); +} + +ATF_TC_BODY(day, tc) +{ + + h_pass("Sun", "%a", 3, -1, -1, -1, -1, -1, -1, 0, -1); + h_pass("Sunday", "%a", 6, -1, -1, -1, -1, -1, -1, 0, -1); + h_pass("Mon", "%a", 3, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("Monday", "%a", 6, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("Tue", "%a", 3, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("Tuesday", "%a", 7, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("Wed", "%a", 3, -1, -1, -1, -1, -1, -1, 3, -1); + h_pass("Wednesday", "%a", 9, -1, -1, -1, -1, -1, -1, 3, -1); + h_pass("Thu", "%a", 3, -1, -1, -1, -1, -1, -1, 4, -1); + h_pass("Thursday", "%a", 8, -1, -1, -1, -1, -1, -1, 4, -1); + h_pass("Fri", "%a", 3, -1, -1, -1, -1, -1, -1, 5, -1); + h_pass("Friday", "%a", 6, -1, -1, -1, -1, -1, -1, 5, -1); + h_pass("Sat", "%a", 3, -1, -1, -1, -1, -1, -1, 6, -1); + h_pass("Saturday", "%a", 8, -1, -1, -1, -1, -1, -1, 6, -1); + h_pass("Saturn", "%a", 3, -1, -1, -1, -1, -1, -1, 6, -1); + h_fail("Moon", "%a"); + h_pass("Sun", "%A", 3, -1, -1, -1, -1, -1, -1, 0, -1); + h_pass("Sunday", "%A", 6, -1, -1, -1, -1, -1, -1, 0, -1); + h_pass("Mon", "%A", 3, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("Monday", "%A", 6, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("Tue", "%A", 3, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("Tuesday", "%A", 7, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("Wed", "%A", 3, -1, -1, -1, -1, -1, -1, 3, -1); + h_pass("Wednesday", "%A", 9, -1, -1, -1, -1, -1, -1, 3, -1); + h_pass("Thu", "%A", 3, -1, -1, -1, -1, -1, -1, 4, -1); + h_pass("Thursday", "%A", 8, -1, -1, -1, -1, -1, -1, 4, -1); + h_pass("Fri", "%A", 3, -1, -1, -1, -1, -1, -1, 5, -1); + h_pass("Friday", "%A", 6, -1, -1, -1, -1, -1, -1, 5, -1); + h_pass("Sat", "%A", 3, -1, -1, -1, -1, -1, -1, 6, -1); + h_pass("Saturday", "%A", 8, -1, -1, -1, -1, -1, -1, 6, -1); + h_pass("Saturn", "%A", 3, -1, -1, -1, -1, -1, -1, 6, -1); + h_fail("Moon", "%A"); + + h_pass("mon", "%a", 3, -1, -1, -1, -1, -1, -1, 1, -1); + h_pass("tueSDay", "%A", 7, -1, -1, -1, -1, -1, -1, 2, -1); + h_pass("sunday", "%A", 6, -1, -1, -1, -1, -1, -1, 0, -1); +#ifdef __NetBSD__ + h_fail("sunday", "%EA"); +#else + h_pass("Sunday", "%EA", 6, -1, -1, -1, -1, -1, -1, 0, -1); +#endif + h_pass("SaturDay", "%A", 8, -1, -1, -1, -1, -1, -1, 6, -1); +#ifdef __NetBSD__ + h_fail("SaturDay", "%OA"); +#else + h_pass("SaturDay", "%OA", 8, -1, -1, -1, -1, -1, -1, 6, -1); +#endif +} + +ATF_TC(hour); + +ATF_TC_HEAD(hour, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks strptime(3) hour conversions [IH]"); +} + +ATF_TC_BODY(hour, tc) +{ + + h_fail("00", "%I"); + h_fail("13", "%I"); + + h_pass("00", "%H", 2, -1, -1, 0, -1, -1, -1, -1, -1); + h_pass("12", "%H", 2, -1, -1, 12, -1, -1, -1, -1, -1); + h_pass("23", "%H", 2, -1, -1, 23, -1, -1, -1, -1, -1); + h_fail("24", "%H"); +} + + +ATF_TC(month); + +ATF_TC_HEAD(month, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks strptime(3) month name conversions [bB]"); +} + +ATF_TC_BODY(month, tc) +{ + + h_pass("Jan", "%b", 3, -1, -1, -1, -1, 0, -1, -1, -1); + h_pass("January", "%b", 7, -1, -1, -1, -1, 0, -1, -1, -1); + h_pass("Feb", "%b", 3, -1, -1, -1, -1, 1, -1, -1, -1); + h_pass("February", "%b", 8, -1, -1, -1, -1, 1, -1, -1, -1); + h_pass("Mar", "%b", 3, -1, -1, -1, -1, 2, -1, -1, -1); + h_pass("March", "%b", 5, -1, -1, -1, -1, 2, -1, -1, -1); + h_pass("Apr", "%b", 3, -1, -1, -1, -1, 3, -1, -1, -1); + h_pass("April", "%b", 5, -1, -1, -1, -1, 3, -1, -1, -1); + h_pass("May", "%b", 3, -1, -1, -1, -1, 4, -1, -1, -1); + h_pass("Jun", "%b", 3, -1, -1, -1, -1, 5, -1, -1, -1); + h_pass("June", "%b", 4, -1, -1, -1, -1, 5, -1, -1, -1); + h_pass("Jul", "%b", 3, -1, -1, -1, -1, 6, -1, -1, -1); + h_pass("July", "%b", 4, -1, -1, -1, -1, 6, -1, -1, -1); + h_pass("Aug", "%b", 3, -1, -1, -1, -1, 7, -1, -1, -1); + h_pass("August", "%b", 6, -1, -1, -1, -1, 7, -1, -1, -1); + h_pass("Sep", "%b", 3, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("September", "%b", 9, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("Oct", "%b", 3, -1, -1, -1, -1, 9, -1, -1, -1); + h_pass("October", "%b", 7, -1, -1, -1, -1, 9, -1, -1, -1); + h_pass("Nov", "%b", 3, -1, -1, -1, -1, 10, -1, -1, -1); + h_pass("November", "%b", 8, -1, -1, -1, -1, 10, -1, -1, -1); + h_pass("Dec", "%b", 3, -1, -1, -1, -1, 11, -1, -1, -1); + h_pass("December", "%b", 8, -1, -1, -1, -1, 11, -1, -1, -1); + h_pass("Mayor", "%b", 3, -1, -1, -1, -1, 4, -1, -1, -1); + h_pass("Mars", "%b", 3, -1, -1, -1, -1, 2, -1, -1, -1); + h_fail("Rover", "%b"); + h_pass("Jan", "%B", 3, -1, -1, -1, -1, 0, -1, -1, -1); + h_pass("January", "%B", 7, -1, -1, -1, -1, 0, -1, -1, -1); + h_pass("Feb", "%B", 3, -1, -1, -1, -1, 1, -1, -1, -1); + h_pass("February", "%B", 8, -1, -1, -1, -1, 1, -1, -1, -1); + h_pass("Mar", "%B", 3, -1, -1, -1, -1, 2, -1, -1, -1); + h_pass("March", "%B", 5, -1, -1, -1, -1, 2, -1, -1, -1); + h_pass("Apr", "%B", 3, -1, -1, -1, -1, 3, -1, -1, -1); + h_pass("April", "%B", 5, -1, -1, -1, -1, 3, -1, -1, -1); + h_pass("May", "%B", 3, -1, -1, -1, -1, 4, -1, -1, -1); + h_pass("Jun", "%B", 3, -1, -1, -1, -1, 5, -1, -1, -1); + h_pass("June", "%B", 4, -1, -1, -1, -1, 5, -1, -1, -1); + h_pass("Jul", "%B", 3, -1, -1, -1, -1, 6, -1, -1, -1); + h_pass("July", "%B", 4, -1, -1, -1, -1, 6, -1, -1, -1); + h_pass("Aug", "%B", 3, -1, -1, -1, -1, 7, -1, -1, -1); + h_pass("August", "%B", 6, -1, -1, -1, -1, 7, -1, -1, -1); + h_pass("Sep", "%B", 3, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("September", "%B", 9, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("Oct", "%B", 3, -1, -1, -1, -1, 9, -1, -1, -1); + h_pass("October", "%B", 7, -1, -1, -1, -1, 9, -1, -1, -1); + h_pass("Nov", "%B", 3, -1, -1, -1, -1, 10, -1, -1, -1); + h_pass("November", "%B", 8, -1, -1, -1, -1, 10, -1, -1, -1); + h_pass("Dec", "%B", 3, -1, -1, -1, -1, 11, -1, -1, -1); + h_pass("December", "%B", 8, -1, -1, -1, -1, 11, -1, -1, -1); + h_pass("Mayor", "%B", 3, -1, -1, -1, -1, 4, -1, -1, -1); + h_pass("Mars", "%B", 3, -1, -1, -1, -1, 2, -1, -1, -1); + h_fail("Rover", "%B"); + + h_pass("september", "%b", 9, -1, -1, -1, -1, 8, -1, -1, -1); + h_pass("septembe", "%B", 3, -1, -1, -1, -1, 8, -1, -1, -1); +} + +ATF_TC(seconds); + +ATF_TC_HEAD(seconds, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks strptime(3) seconds conversions [S]"); +} + +ATF_TC_BODY(seconds, tc) +{ + + h_pass("0", "%S", 1, 0, -1, -1, -1, -1, -1, -1, -1); + h_pass("59", "%S", 2, 59, -1, -1, -1, -1, -1, -1, -1); + h_pass("60", "%S", 2, 60, -1, -1, -1, -1, -1, -1, -1); + h_pass("61", "%S", 2, 61, -1, -1, -1, -1, -1, -1, -1); + h_fail("62", "%S"); +} + +ATF_TC(year); + +ATF_TC_HEAD(year, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks strptime(3) century/year conversions [CyY]"); +} + +ATF_TC_BODY(year, tc) +{ + + h_pass("x20y", "x%Cy", 4, -1, -1, -1, -1, -1, 100, -1, -1); + h_pass("x84y", "x%yy", 4, -1, -1, -1, -1, -1, 84, -1, -1); + h_pass("x2084y", "x%C%yy", 6, -1, -1, -1, -1, -1, 184, -1, -1); + h_pass("x8420y", "x%y%Cy", 6, -1, -1, -1, -1, -1, 184, -1, -1); + h_pass("%20845", "%%%C%y5", 6, -1, -1, -1, -1, -1, 184, -1, -1); + h_fail("%", "%E%"); + + h_pass("1980", "%Y", 4, -1, -1, -1, -1, -1, 80, -1, -1); + h_pass("1980", "%EY", 4, -1, -1, -1, -1, -1, 80, -1, -1); +} + +ATF_TC(zone); + +ATF_TC_HEAD(zone, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks strptime(3) timezone conversion [z]"); +} + + +ATF_TC_BODY(zone, tc) +{ + ztest("%z"); +} + +ATF_TC(Zone); + +ATF_TC_HEAD(Zone, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks strptime(3) timezone conversion [Z]"); +} + + +ATF_TC_BODY(Zone, tc) +{ + ztest("%z"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, common); + ATF_TP_ADD_TC(tp, day); + ATF_TP_ADD_TC(tp, hour); + ATF_TP_ADD_TC(tp, month); + ATF_TP_ADD_TC(tp, seconds); + ATF_TP_ADD_TC(tp, year); + ATF_TP_ADD_TC(tp, zone); + ATF_TP_ADD_TC(tp, Zone); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c new file mode 100644 index 0000000..6c913a4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c @@ -0,0 +1,62 @@ +/* $NetBSD: h_tls_dlopen.c,v 1.5 2013/10/21 19:14:16 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: h_tls_dlopen.c,v 1.5 2013/10/21 19:14:16 joerg Exp $"); + +#include +#include +#ifdef __NetBSD__ +#include +#endif + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +extern __thread int var1; +extern __thread int var2; +extern __thread int *var3; +__thread int var5 = 1; +static __thread pid_t (*local_var)(void) = getpid; + +void testf_dso_helper(int x, int y); + +void +testf_dso_helper(int x, int y) +{ + var1 = x; + var2 = y; + var3 = &optind; + ATF_CHECK_EQ(local_var, getpid); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c new file mode 100644 index 0000000..a268068 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c @@ -0,0 +1,115 @@ +/* $NetBSD: t_tls_dlopen.c,v 1.3 2012/01/17 20:34:57 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_tls_dlopen.c,v 1.3 2012/01/17 20:34:57 joerg Exp $"); + +#include +#include +#include +#include + +#ifdef __NetBSD__ +#include +#endif + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +ATF_TC(t_tls_dlopen); + +ATF_TC_HEAD(t_tls_dlopen, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test (un)initialized TLS variables and dlopen"); +} + +void (*testf_helper)(int, int); + +__thread int var1 = 1; +__thread int var2; +__thread int *var3 = &optind; +int var4_helper; +__thread int *var4 = &var4_helper; + +static void * +testf(void *dummy) +{ + ATF_CHECK_EQ(var1, 1); + ATF_CHECK_EQ(var2, 0); + ATF_CHECK_EQ(var3, &optind); + ATF_CHECK_EQ(var4, &var4_helper); + testf_helper(2, 2); + ATF_CHECK_EQ(var1, 2); + ATF_CHECK_EQ(var2, 2); + testf_helper(3, 3); + ATF_CHECK_EQ(var1, 3); + ATF_CHECK_EQ(var2, 3); + ATF_CHECK_EQ(var3, &optind); + + return NULL; +} + +ATF_TC_BODY(t_tls_dlopen, tc) +{ + void *handle; + pthread_t t; + +#ifdef __HAVE_NO___THREAD + atf_tc_skip("no TLS support on this platform"); +#endif + + handle = dlopen("h_tls_dlopen.so", RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE(handle != NULL); + + testf_helper = dlsym(handle, "testf_dso_helper"); + ATF_REQUIRE(testf_helper != NULL); + + testf(NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); + + dlclose(handle); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_tls_dlopen); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c new file mode 100644 index 0000000..1982a9b --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c @@ -0,0 +1,107 @@ +/* $NetBSD: t_tls_dynamic.c,v 1.3 2012/01/17 20:34:57 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_tls_dynamic.c,v 1.3 2012/01/17 20:34:57 joerg Exp $"); + +#include +#include +#include + +#ifdef __NetBSD__ +#include +#endif + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +ATF_TC(t_tls_dynamic); + +ATF_TC_HEAD(t_tls_dynamic, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test (un)initialized TLS variables in dynamic binaries"); +} + +void testf_dso_helper(int, int); + +extern __thread int var1; +extern __thread int var2; +extern __thread pid_t (*dso_var1)(void); + +__thread int *var3 = &optind; +int var4_helper; +__thread int *var4 = &var4_helper; + +static void * +testf(void *dummy) +{ + ATF_CHECK_EQ(var1, 1); + ATF_CHECK_EQ(var2, 0); + testf_dso_helper(2, 2); + ATF_CHECK_EQ(var1, 2); + ATF_CHECK_EQ(var2, 2); + testf_dso_helper(3, 3); + ATF_CHECK_EQ(var1, 3); + ATF_CHECK_EQ(var2, 3); + ATF_CHECK_EQ(var3, &optind); + ATF_CHECK_EQ(var4, &var4_helper); + ATF_CHECK_EQ(dso_var1, getpid); + + return NULL; +} + +ATF_TC_BODY(t_tls_dynamic, tc) +{ + pthread_t t; + +#ifdef __HAVE_NO___THREAD + atf_tc_skip("no TLS support on this platform"); +#endif + + testf(NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_tls_dynamic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c new file mode 100644 index 0000000..db0ff16 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c @@ -0,0 +1,95 @@ +/* $NetBSD: t_tls_static.c,v 1.2 2012/01/17 20:34:57 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_tls_static.c,v 1.2 2012/01/17 20:34:57 joerg Exp $"); + +#include +#include + +#ifdef __NetBSD__ +#include +#endif + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +ATF_TC(t_tls_static); + +ATF_TC_HEAD(t_tls_static, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test (un)initialized TLS variables in static binaries"); +} + +void testf_helper(void); + +__thread int var1 = 1; +__thread int var2; + +static void * +testf(void *dummy) +{ + ATF_CHECK_EQ(var1, 1); + ATF_CHECK_EQ(var2, 0); + testf_helper(); + ATF_CHECK_EQ(var1, -1); + ATF_CHECK_EQ(var2, -1); + + return NULL; +} + +ATF_TC_BODY(t_tls_static, tc) +{ + pthread_t t; + +#ifdef __HAVE_NO___THREAD + atf_tc_skip("no TLS support on this platform"); +#endif + + testf(NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); + + pthread_create(&t, 0, testf, 0); + pthread_join(t, NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_tls_static); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c new file mode 100644 index 0000000..841b2bf --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c @@ -0,0 +1,55 @@ +/* $NetBSD: t_tls_static_helper.c,v 1.2 2012/01/17 20:34:57 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_tls_static_helper.c,v 1.2 2012/01/17 20:34:57 joerg Exp $"); + +#ifdef __NetBSD__ +#include +#endif + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +extern __thread int var1; +extern __thread int var2; + +void testf_helper(void); + +void +testf_helper(void) +{ + var1 = -1; + var2 = -1; +} diff --git a/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c new file mode 100644 index 0000000..a5e78ff --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c @@ -0,0 +1,58 @@ +/* $NetBSD: h_tls_dynamic.c,v 1.5 2013/10/21 19:11:17 joerg Exp $ */ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: h_tls_dynamic.c,v 1.5 2013/10/21 19:11:17 joerg Exp $"); + +#include +#ifdef __NetBSD__ +#include +#endif + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +__thread int var1 = 1; +__thread int var2; + +__thread pid_t (*dso_var1)(void) = getpid; + +void testf_dso_helper(int x, int y); + +void +testf_dso_helper(int x, int y) +{ + var1 = x; + var2 = y; +} diff --git a/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c b/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c new file mode 100644 index 0000000..5346898 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c @@ -0,0 +1,174 @@ +/* $NetBSD: t_ptm.c,v 1.1 2011/01/13 03:19:57 pgoyette Exp $ */ + +/* + * Copyright (c) 2004, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ptm.c,v 1.1 2011/01/13 03:19:57 pgoyette Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#define REQUIRE_ERRNO(x, v) \ + ATF_REQUIRE_MSG(x != v, "%s: %s", #x, strerror(errno)) + +ATF_TC(ptm); + +ATF_TC_HEAD(ptm, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks /dev/ptm device"); +} + +ATF_TC_BODY(ptm, tc) +{ + struct stat stm, sts; + struct ptmget ptm; + int fdm; + struct group *gp; + + if ((fdm = open("/dev/ptm", O_RDWR)) == -1) { + if (errno == ENOENT || errno == ENODEV) + atf_tc_skip("/dev/ptm: %s", strerror(errno)); + atf_tc_fail("/dev/ptm: %s", strerror(errno)); + } + + REQUIRE_ERRNO(fstat(fdm, &stm), -1); + ATF_REQUIRE_EQ(major(stm.st_rdev), 165); + REQUIRE_ERRNO(ioctl(fdm, TIOCPTMGET, &ptm), -1); + + ATF_REQUIRE_MSG(strncmp(ptm.cn, "/dev/pty", 8) == 0 + || strncmp(ptm.cn, "/dev/null", 9) == 0, + "bad master name: %s", ptm.cn); + + ATF_REQUIRE_MSG(strncmp(ptm.sn, "/dev/tty", 8) == 0 + || strncmp(ptm.sn, "/dev/pts/", 9) == 0, + "bad slave name: %s", ptm.sn); + + if (strncmp(ptm.cn, "/dev/null", 9) != 0) { + REQUIRE_ERRNO(fstat(ptm.cfd, &stm), -1); + REQUIRE_ERRNO(stat(ptm.cn, &sts), -1); + ATF_REQUIRE_EQ(stm.st_rdev, sts.st_rdev); + } + + REQUIRE_ERRNO(fstat(ptm.sfd, &stm), -1); + REQUIRE_ERRNO(stat(ptm.sn, &sts), -1); + ATF_REQUIRE_EQ(stm.st_rdev, sts.st_rdev); + + ATF_REQUIRE_EQ_MSG(sts.st_uid, getuid(), "bad slave uid"); + + ATF_REQUIRE_MSG((gp = getgrnam("tty")) != NULL, + "cannot find `tty' group"); + ATF_REQUIRE_EQ_MSG(sts.st_gid, gp->gr_gid, "bad slave grid"); + + (void)close(ptm.sfd); + (void)close(ptm.cfd); + (void)close(fdm); +} + +/* + * On NetBSD /dev/ptyp0 == /dev/pts/0 so we can check for major + * and minor device numbers. This check is non-portable. This + * check is now disabled because we might not have /dev/ptyp0 + * at all. + */ + +/* + * #define PTY_DEVNO_CHECK + */ + +ATF_TC(ptmx); + +ATF_TC_HEAD(ptmx, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks /dev/ptmx device"); +} + +ATF_TC_BODY(ptmx, tc) +{ + struct stat stm, sts; + char *pty; + int fdm, fds; + struct group *gp; + + if ((fdm = posix_openpt(O_RDWR|O_NOCTTY)) == -1) { + if (errno == ENOENT || errno == ENODEV) + atf_tc_skip("/dev/ptmx: %s", strerror(errno)); + + atf_tc_fail("/dev/ptmx: %s", strerror(errno)); + } + + REQUIRE_ERRNO(fstat(fdm, &stm), -1); + +#ifdef PTY_DEVNO_CHECK + REQUIRE_ERRNO(stat("/dev/ptyp0", &sts), -1); + + ATF_REQUIRE_EQ_MSG(major(stm.st_rdev), major(sts.st_rdev), + "bad master major number"); +#endif + + REQUIRE_ERRNO(grantpt(fdm), -1); + REQUIRE_ERRNO(unlockpt(fdm), -1); + REQUIRE_ERRNO((pty = ptsname(fdm)), NULL); + + REQUIRE_ERRNO((fds = open(pty, O_RDWR|O_NOCTTY)), -1); + REQUIRE_ERRNO(fstat(fds, &sts), -1); + +#ifdef PTY_DEVNO_CHECK + ATF_REQUIRE_EQ_MSG(minor(stm.st_rdev), minor(sts.st_rdev), + "bad slave minor number"); +#endif + + ATF_REQUIRE_EQ_MSG(sts.st_uid, getuid(), "bad slave uid"); + ATF_REQUIRE_MSG((gp = getgrnam("tty")) != NULL, + "cannot find `tty' group"); + + ATF_REQUIRE_EQ_MSG(sts.st_gid, gp->gr_gid, "bad slave gid"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ptm); + ATF_TP_ADD_TC(tp, ptmx); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c b/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c new file mode 100644 index 0000000..7f60d78 --- /dev/null +++ b/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c @@ -0,0 +1,164 @@ +/* $NetBSD: t_ttyio.c,v 1.3 2017/01/10 01:31:40 christos Exp $ */ + +/* + * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Brown. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_ttyio.c,v 1.3 2017/01/10 01:31:40 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__NetBSD__) +#include +#elif defined(__bsdi__) +int openpty(int *, int *, char *, struct termios *, struct winsize *); +#elif defined(__FreeBSD__) +#include +#else +#error where openpty? +#endif + +#include + +#define REQUIRE_ERRNO(x, v) ATF_REQUIRE_MSG(x != v, "%s: %s", #x, strerror(errno)) + +ATF_TC(ioctl); +ATF_TC_HEAD(ioctl, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that ioctl calls are restarted " + "properly after being interrupted"); +} + +/* ARGSUSED */ +static void +sigchld(int nsig) +{ + REQUIRE_ERRNO(wait(NULL), -1); +} + +ATF_TC_BODY(ioctl, tc) +{ + int m, s, rc; + char name[128], buf[128]; + struct termios term; + struct sigaction sa; + + /* unbuffer stdout */ + setbuf(stdout, NULL); + + /* + * Create default termios settings for later use + */ + memset(&term, 0, sizeof(term)); + term.c_iflag = TTYDEF_IFLAG; + term.c_oflag = TTYDEF_OFLAG; + term.c_cflag = TTYDEF_CFLAG; + term.c_lflag = TTYDEF_LFLAG; + cfsetspeed(&term, TTYDEF_SPEED); + + /* get a tty */ + REQUIRE_ERRNO(openpty(&m, &s, name, &term, NULL), -1); + + switch (fork()) { + case -1: + atf_tc_fail("fork(): %s", strerror(errno)); + /* NOTREACHED */ + case 0: + /* wait for parent to get set up */ + (void)sleep(1); + (void)printf("child1: exiting\n"); + exit(0); + /* NOTREACHED */ + default: + (void)printf("parent: spawned child1\n"); + break; + } + + switch (fork()) { + case -1: + atf_tc_fail("fork(): %s", strerror(errno)); + /* NOTREACHED */ + case 0: + /* wait for parent to get upset */ + (void)sleep(2); + /* drain the tty q */ + if (read(m, buf, sizeof(buf)) == -1) + err(1, "read"); + (void)printf("child2: exiting\n"); + exit(0); + /* NOTREACHED */ + default: + (void)printf("parent: spawned child2\n"); + break; + } + + /* set up a restarting signal handler */ + (void)sigemptyset(&sa.sa_mask); + sa.sa_handler = sigchld; + sa.sa_flags = SA_RESTART; + REQUIRE_ERRNO(sigaction(SIGCHLD, &sa, NULL), -1); + + /* put something in the output q */ + REQUIRE_ERRNO(write(s, "Hello world\n", 12), -1); + + /* ask for output to drain but don't drain it */ + rc = 0; + if (tcsetattr(s, TCSADRAIN, &term) == -1) { + (void)printf("parent: tcsetattr: %s\n", strerror(errno)); + rc = 1; + } + + /* wait for last child */ + sa.sa_handler = SIG_DFL; + REQUIRE_ERRNO(sigaction(SIGCHLD, &sa, NULL), -1); + (void)wait(NULL); + + (void)close(s); + ATF_REQUIRE_EQ(rc, 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, ioctl); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libcrypt/t_crypt.c b/contrib/netbsd-tests/lib/libcrypt/t_crypt.c new file mode 100644 index 0000000..9b47692 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcrypt/t_crypt.c @@ -0,0 +1,151 @@ +/* $NetBSD: t_crypt.c,v 1.3 2011/12/28 22:07:40 christos Exp $ */ + +/* + * This version is derived from the original implementation of FreeSec + * (release 1.1) by David Burren. I've reviewed the changes made in + * OpenBSD (as of 2.7) and modified the original code in a similar way + * where applicable. I've also made it reentrant and made a number of + * other changes. + * - Solar Designer + */ + +/* + * FreeSec: libcrypt for NetBSD + * + * Copyright (c) 1994 David Burren + * 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 author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $Owl: Owl/packages/glibc/crypt_freesec.c,v 1.6 2010/02/20 14:45:06 solar Exp $ + * Id: crypt.c,v 1.15 1994/09/13 04:58:49 davidb Exp + * + * This is an original implementation of the DES and the crypt(3) interfaces + * by David Burren . + * + * An excellent reference on the underlying algorithm (and related + * algorithms) is: + * + * B. Schneier, Applied Cryptography: protocols, algorithms, + * and source code in C, John Wiley & Sons, 1994. + * + * Note that in that book's description of DES the lookups for the initial, + * pbox, and final permutations are inverted (this has been brought to the + * attention of the author). A list of errata for this book has been + * posted to the sci.crypt newsgroup by the author and is available for FTP. + * + * ARCHITECTURE ASSUMPTIONS: + * This code used to have some nasty ones, but these have been removed + * by now. The code requires a 32-bit integer type, though. + */ +#include +__RCSID("$NetBSD: t_crypt.c,v 1.3 2011/12/28 22:07:40 christos Exp $"); + +#include +#include +#include +#include +#include + +static const struct { + const char *hash; + const char *pw; +} tests[] = { +/* "new"-style */ +/* 0 */ { "_J9..CCCCXBrJUJV154M", "U*U*U*U*" }, +/* 1 */ { "_J9..CCCCXUhOBTXzaiE", "U*U***U" }, +/* 2 */ { "_J9..CCCC4gQ.mB/PffM", "U*U***U*" }, +/* 3 */ { "_J9..XXXXvlzQGqpPPdk", "*U*U*U*U" }, +/* 4 */ { "_J9..XXXXsqM/YSSP..Y", "*U*U*U*U*" }, +/* 5 */ { "_J9..XXXXVL7qJCnku0I", "*U*U*U*U*U*U*U*U" }, +/* 6 */ { "_J9..XXXXAj8cFbP5scI", "*U*U*U*U*U*U*U*U*" }, +/* 7 */ { "_J9..SDizh.vll5VED9g", "ab1234567" }, +/* 8 */ { "_J9..SDizRjWQ/zePPHc", "cr1234567" }, +/* 9 */ { "_J9..SDizxmRI1GjnQuE", "zxyDPWgydbQjgq" }, +/* 10 */ { "_K9..SaltNrQgIYUAeoY", "726 even" }, +/* 11 */ { "_J9..SDSD5YGyRCr4W4c", "" }, +/* "old"-style, valid salts */ +/* 12 */ { "CCNf8Sbh3HDfQ", "U*U*U*U*" }, +/* 13 */ { "CCX.K.MFy4Ois", "U*U***U" }, +/* 14 */ { "CC4rMpbg9AMZ.", "U*U***U*" }, +/* 15 */ { "XXxzOu6maQKqQ", "*U*U*U*U" }, +/* 16 */ { "SDbsugeBiC58A", "" }, +/* 17 */ { "./xZjzHv5vzVE", "password" }, +/* 18 */ { "0A2hXM1rXbYgo", "password" }, +/* 19 */ { "A9RXdR23Y.cY6", "password" }, +/* 20 */ { "ZziFATVXHo2.6", "password" }, +/* 21 */ { "zZDDIZ0NOlPzw", "password" }, +/* "old"-style, "reasonable" invalid salts, UFC-crypt behavior expected */ +/* 22 */ { "\001\002wyd0KZo65Jo", "password" }, +/* 23 */ { "a_C10Dk/ExaG.", "password" }, +/* 24 */ { "~\377.5OTsRVjwLo", "password" }, +/* The below are erroneous inputs, so NULL return is expected/required */ +/* 25 */ { "", "" }, /* no salt */ +/* 26 */ { " ", "" }, /* setting string is too short */ +/* 27 */ { "a:", "" }, /* unsafe character */ +/* 28 */ { "\na", "" }, /* unsafe character */ +/* 29 */ { "_/......", "" }, /* setting string is too short for its type */ +/* 30 */ { "_........", "" }, /* zero iteration count */ +/* 31 */ { "_/!......", "" }, /* invalid character in count */ +/* 32 */ { "_/......!", "" }, /* invalid character in salt */ +/* 33 */ { NULL, NULL } +}; + +ATF_TC(crypt_salts); + +ATF_TC_HEAD(crypt_salts, tc) +{ + + atf_tc_set_md_var(tc, "descr", "crypt(3) salt consistency checks"); +} + +ATF_TC_BODY(crypt_salts, tc) +{ + for (size_t i = 0; tests[i].hash; i++) { + char *hash = crypt(tests[i].pw, tests[i].hash); +#if defined(__FreeBSD__) + if (i >= 22 && i != 24 && i != 25) + atf_tc_expect_fail("Old-style/bad inputs fail on FreeBSD"); + else + atf_tc_expect_pass(); +#endif + if (!hash) { + ATF_CHECK_MSG(0, "Test %zu NULL\n", i); + continue; + } + if (strcmp(hash, "*0") == 0 && strlen(tests[i].hash) < 13) + continue; /* expected failure */ + if (strcmp(hash, tests[i].hash)) + ATF_CHECK_MSG(0, "Test %zu %s != %s\n", + i, hash, tests[i].hash); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, crypt_salts); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libcurses/atf.terminfo b/contrib/netbsd-tests/lib/libcurses/atf.terminfo new file mode 100644 index 0000000..fcd34b6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/atf.terminfo @@ -0,0 +1,44 @@ +# Based on xterm capabilities +atf|atf automatic test frame pseudo terminal, + am, bce, ccc, km, mc5i, mir, msgr, npc, xenl, + colors#8, cols#80, it#8, lines#24, pairs#64, + acsc=++\,\,--..00``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, + bel=bel, blink=blink, bold=bold, cbt=cbt, civis=civis, clear=clear, + cnorm=cnorm, cr=^M, csr=csr%i%p1%d;%p2%dX, cub=cub%p1%dX, + cub1=^H, cud=cud%p1%dX, cud1=^J, cuf=cuf%p1%dX, cuf1=, + cup=cup%i%p1%d;%p2%dX, cuu=cuu%p1%dX, cuu1=, cvvis=cvvis, + dch=dch%p1%dX, dch1=, dl=dl%p1%dX, dl1= , dim=dim, ech=ech%p1%dX, + ed=ed, el=el, el1=el1, enacs=enacs, flash=flash, home=home, + hpa=hpa%i%p1%dX, ht=^I, hts=hts, ich=ich%p1%dX, il=il%p1%dX, + il1=il1, ind=^M, indn=indn%p1%dX, invis=invis, + is2=is2, kDC=\E[3;2~, kEND=\E[1;2F, kHOM=\E[1;2H, + kIC=\E[2;2~, kLFT=\E[1;2D, kNXT=\E[6;2~, kPRV=\E[5;2~, + kRIT=\E[1;2C, kb2=\EOE, kbs=^H, kcbt=\E[Z, kcub1=\EOD, kcud1=\EOB, + kcuf1=\EOC, kcuu1=\EOA, kdch1=\E[3~, kend=\EOF, kent=\EOM, + kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[1;2P, + kf14=\E[1;2Q, kf15=\E[1;2R, kf16=\E[1;2S, kf17=\E[15;2~, + kf18=\E[17;2~, kf19=\E[18;2~, kf2=\EOQ, kf20=\E[19;2~, + kf21=\E[20;2~, kf22=\E[21;2~, kf23=\E[23;2~, kf24=\E[24;2~, + kf25=\E[1;5P, kf26=\E[1;5Q, kf27=\E[1;5R, kf28=\E[1;5S, + kf29=\E[15;5~, kf3=\EOR, kf30=\E[17;5~, kf31=\E[18;5~, + kf32=\E[19;5~, kf33=\E[20;5~, kf34=\E[21;5~, kf35=\E[23;5~, + kf36=\E[24;5~, kf37=\E[1;6P, kf38=\E[1;6Q, kf39=\E[1;6R, kf4=\EOS, + kf40=\E[1;6S, kf41=\E[15;6~, kf42=\E[17;6~, kf43=\E[18;6~, + kf44=\E[19;6~, kf45=\E[20;6~, kf46=\E[21;6~, kf47=\E[23;6~, + kf48=\E[24;6~, kf49=\E[1;3P, kf5=\E[15~, kf50=\E[1;3Q, + kf51=\E[1;3R, kf52=\E[1;3S, kf53=\E[15;3~, kf54=\E[17;3~, + kf55=\E[18;3~, kf56=\E[19;3~, kf57=\E[20;3~, kf58=\E[21;3~, + kf59=\E[23;3~, kf6=\E[17~, kf60=\E[24;3~, kf61=\E[1;4P, + kf62=\E[1;4Q, kf63=\E[1;4R, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, + khome=\EOH, kich1=\E[2~, kind=\E[1;2B, kmous=\E[M, knp=\E[6~, + kpp=\E[5~, kri=\E[1;2A, mc0=mc0, mc4=mc4, mc5=mc5, + op=op, rc=rc, rev=rev, ri=ri, rin=rin%p1%dX, rmacs=rmacs, + rmam=rmam, rmcup=rmcup, rmir=rmir, rmkx=rmkx, + rmm=rmm, rmso=rmso, rmul=rmul, rs1=rs1, + rs2=rs2, sc=sc, setab=setab%p1%dX, + setaf=setaf%p1%dX, setb=setb%p1%dX, setf=setf%p1%dX, + sgr=sgr%p1%d;%p2%d;%p3%d;%p4%d;%p5%d;%p6%d;%p7%d;%p8;%d;%p9%dX, + sgr0=sgr0, smacs=smacs, smam=smam, smcup=smcup, + smir=smir, smkx=smkx, smm=smm, smso=smso, smul=smul, + tbc=tbc, u6=u6%d;%dX, u7=u7, u8=u8, u9=u9, + vpa=vpa%p1%dX diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/addch.chk b/contrib/netbsd-tests/lib/libcurses/check_files/addch.chk new file mode 100644 index 0000000..3e2c6bb --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/addch.chk @@ -0,0 +1 @@ +smsotrmso \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/addchstr.chk b/contrib/netbsd-tests/lib/libcurses/check_files/addchstr.chk new file mode 100644 index 0000000..42286d0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/addchstr.chk @@ -0,0 +1 @@ +revabcdehomesgr0 \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/addstr.chk b/contrib/netbsd-tests/lib/libcurses/check_files/addstr.chk new file mode 100644 index 0000000..6a81654 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/addstr.chk @@ -0,0 +1 @@ +abcde \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/attributes.chk b/contrib/netbsd-tests/lib/libcurses/check_files/attributes.chk new file mode 100644 index 0000000..be35b56 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/attributes.chk @@ -0,0 +1 @@ +smsoblinkhellormsosgr0 \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background1.chk new file mode 100644 index 0000000..e52e439 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/background1.chk @@ -0,0 +1 @@ +smulAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup2;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup3;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup4;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup5;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup6;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup7;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup8;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup9;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup10;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup11;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup12;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup13;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup14;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup15;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup16;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup17;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup18;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup19;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup20;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup21;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup22;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup23;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup24;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup1;1Xrmul \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background2.chk new file mode 100644 index 0000000..55a2163 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/background2.chk @@ -0,0 +1 @@ +smula test stringrmul \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background3.chk new file mode 100644 index 0000000..732f4cc --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/background3.chk @@ -0,0 +1 @@ +cup3;6X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background4.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background4.chk new file mode 100644 index 0000000..05698e2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/background4.chk @@ -0,0 +1,6 @@ +cup1;14Xcup3;6Xrevwindow +B1BBBB +BBBBBB +BBBBBB +BBBBBB +BBBBBBcup4;8Xsgr0 \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background5.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background5.chk new file mode 100644 index 0000000..6c37975 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/background5.chk @@ -0,0 +1,3 @@ +cup1;14Xcup4;8Xrevhell +o worl +dsgr0 \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/bell.chk b/contrib/netbsd-tests/lib/libcurses/check_files/bell.chk new file mode 100644 index 0000000..f4d3c21 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/bell.chk @@ -0,0 +1 @@ +bel \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/box_standout.chk b/contrib/netbsd-tests/lib/libcurses/check_files/box_standout.chk new file mode 100644 index 0000000..5bd91e1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/box_standout.chk @@ -0,0 +1,5 @@ +revsmacsqqqqrmacs +sgr0smsosmacsxrmacssmacsxrmacs +smacsxrmacssmacsxrmacs +smacsxrmacssmacsxrmacs +smacsxrmacssmacsxrmacscup8;7Xrmsorevsmacsqqqqrmacscup3;6Xsgr0 \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/chgat1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/chgat1.chk new file mode 100644 index 0000000..e9b8b58 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/chgat1.chk @@ -0,0 +1 @@ +setaf7Xsetab0Xdsetaf3Xsetab6Xrev homesgr0 \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/chgat2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/chgat2.chk new file mode 100644 index 0000000..cadfb37 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/chgat2.chk @@ -0,0 +1 @@ +setaf7Xsetab0Xeop \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/chgat3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/chgat3.chk new file mode 100644 index 0000000..7d57a90 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/chgat3.chk @@ -0,0 +1 @@ +homesetaf3Xsetab6Xsmulde cup1;1Xrmulop \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear1.chk new file mode 100644 index 0000000..9c7d34f --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear1.chk @@ -0,0 +1 @@ +clear \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear10.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear10.chk new file mode 100644 index 0000000..1baa2a5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear10.chk @@ -0,0 +1 @@ +cup7;7X EEEEE \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear2.chk new file mode 100644 index 0000000..f25000b --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear2.chk @@ -0,0 +1 @@ +cup6;6Xabcdecup21;6Xfghijcup11;6X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear3.chk new file mode 100644 index 0000000..dfdd90d --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear3.chk @@ -0,0 +1 @@ +cup21;6Xelcup11;6X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear4.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear4.chk new file mode 100644 index 0000000..abe5be8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear4.chk @@ -0,0 +1 @@ +elhome \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear5.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear5.chk new file mode 100644 index 0000000..d9df62d --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear5.chk @@ -0,0 +1,23 @@ +homeel +el +el +el +el +el +el +el +el +el +el +el +el +el +el +el +el +el +el +el +el +el +elhome \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear6.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear6.chk new file mode 100644 index 0000000..ff815d3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear6.chk @@ -0,0 +1 @@ +abccup7;7Xefgcup4;6X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear7.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear7.chk new file mode 100644 index 0000000..8b392c3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear7.chk @@ -0,0 +1 @@ +cup7;7Xelcup4;6X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear8.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear8.chk new file mode 100644 index 0000000..9c9354e --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear8.chk @@ -0,0 +1,6 @@ +cup4;6X +EEEEE +EEEEE +EEEEE +EEEEE +EEEEE cup3;6X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear9.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear9.chk new file mode 100644 index 0000000..c5834a1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear9.chk @@ -0,0 +1,6 @@ +cup3;6X +EEEEE +EEEEE +EEEEE +EEEEE +EEEEE cup3;6X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_blank_draw.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_blank_draw.chk new file mode 100644 index 0000000..42ad0e2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_blank_draw.chk @@ -0,0 +1,24 @@ +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xel +opsetaf7Xsetab0Xelhomeop \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_blue_back.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_blue_back.chk new file mode 100644 index 0000000..5c02e4d --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_blue_back.chk @@ -0,0 +1,24 @@ +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xel +opopsetab4Xelhome \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_default.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_default.chk new file mode 100644 index 0000000..d23ddaf --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_default.chk @@ -0,0 +1,24 @@ +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopel +opopelhomeop \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_red_fore.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_red_fore.chk new file mode 100644 index 0000000..3ad4513 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_red_fore.chk @@ -0,0 +1,24 @@ +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xel +opopsetaf1Xelhomeop \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_set.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_set.chk new file mode 100644 index 0000000..d8363b7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_set.chk @@ -0,0 +1 @@ +setaf1Xsetab2Xtestingop \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_start.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_start.chk new file mode 100644 index 0000000..d314d07 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_start.chk @@ -0,0 +1 @@ +op \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin1.chk new file mode 100644 index 0000000..826062a --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin1.chk @@ -0,0 +1 @@ +cup11;15X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin10.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin10.chk new file mode 100644 index 0000000..d5c8ea5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin10.chk @@ -0,0 +1 @@ +cup11;15Xt s i cup12;15Xg e t cup13;15Xn t s cup14;15X n t scup15;15Xt n t cup16;15X t n t \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin11.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin11.chk new file mode 100644 index 0000000..9315b76 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin11.chk @@ -0,0 +1,4 @@ +cup3;6Xel + el + elcup6;7Xel + elcup8;7Xelcup3;6Xcup11;15Xelcup12;15Xelcup13;15Xelcup14;16Xelcup15;15Xelcup16;16Xelcup11;15X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin12.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin12.chk new file mode 100644 index 0000000..bc1a526 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin12.chk @@ -0,0 +1,4 @@ +cup3;6Xt s i + g e t + n t scup6;7Xn t s + t n tcup8;7Xt n tcup8;11X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin13.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin13.chk new file mode 100644 index 0000000..f2a8913 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin13.chk @@ -0,0 +1 @@ +cup11;16Xe t ncup12;16Xt s icup13;16Xg e tcup14;15Xi g ecup15;16Xi g ecup16;15Xs i g \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin14.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin14.chk new file mode 100644 index 0000000..e7fd505 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin14.chk @@ -0,0 +1 @@ +cup11;15Xtesticup12;15Xgtestcup13;15Xngtescup14;16Xngtescup15;15Xtingtcup16;16Xtingt \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin2.chk new file mode 100644 index 0000000..aac0671 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin2.chk @@ -0,0 +1,6 @@ +cup3;6Xtestin + gtesti + ngtest + ingtes + tingte + stingtcup8;11X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin3.chk new file mode 100644 index 0000000..317cd93 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin3.chk @@ -0,0 +1 @@ +cup12;16Xtestincup13;16Xgtesticup14;16Xngtestcup15;16Xingtescup16;16Xtingtecup17;16Xstingt \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin4.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin4.chk new file mode 100644 index 0000000..4fa78a9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin4.chk @@ -0,0 +1,6 @@ +cup3;6Xel + el + el + el + el + elcup12;16Xelcup13;16Xelcup14;16Xelcup15;16Xelcup16;16Xelcup17;16Xelcup11;15X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin5.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin5.chk new file mode 100644 index 0000000..4f0d7da --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin5.chk @@ -0,0 +1 @@ +testingtecup12;15Xstingtestcup13;15Xingtestincup14;15Xgtestingtcup15;15Xestingtescup16;15Xtingtesticup16;23X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin6.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin6.chk new file mode 100644 index 0000000..314dac8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin6.chk @@ -0,0 +1,6 @@ +cup3;6Xtestin + stingt + ingtes + gtesti + esting + tingtecup8;11X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin7.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin7.chk new file mode 100644 index 0000000..d10a7c2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin7.chk @@ -0,0 +1,6 @@ +cup3;6Xel + el + el + el + el + elcup11;15Xelcup12;15Xelcup13;15Xelcup14;15Xelcup15;15Xelcup16;15Xel \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin8.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin8.chk new file mode 100644 index 0000000..bc1a526 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin8.chk @@ -0,0 +1,4 @@ +cup3;6Xt s i + g e t + n t scup6;7Xn t s + t n tcup8;7Xt n tcup8;11X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin9.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin9.chk new file mode 100644 index 0000000..f2a8913 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin9.chk @@ -0,0 +1 @@ +cup11;16Xe t ncup12;16Xt s icup13;16Xg e tcup14;15Xi g ecup15;16Xi g ecup16;15Xs i g \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/curs_set1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set1.chk new file mode 100644 index 0000000..81a818c --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set1.chk @@ -0,0 +1 @@ +civis \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/curs_set2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set2.chk new file mode 100644 index 0000000..7682463 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set2.chk @@ -0,0 +1 @@ +cnorm \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/curs_set3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set3.chk new file mode 100644 index 0000000..0f3e744 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set3.chk @@ -0,0 +1 @@ +cvvis \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/curses_start.chk b/contrib/netbsd-tests/lib/libcurses/check_files/curses_start.chk new file mode 100644 index 0000000..7c4f92c --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/curses_start.chk @@ -0,0 +1 @@ +enacsenacssmcupcnormclearclear \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/fill.chk b/contrib/netbsd-tests/lib/libcurses/check_files/fill.chk new file mode 100644 index 0000000..2d89374 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/fill.chk @@ -0,0 +1,23 @@ +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEhome +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/home.chk b/contrib/netbsd-tests/lib/libcurses/check_files/home.chk new file mode 100644 index 0000000..0247178 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/home.chk @@ -0,0 +1 @@ +home \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/timeout.chk b/contrib/netbsd-tests/lib/libcurses/check_files/timeout.chk new file mode 100644 index 0000000..6463b1e --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/timeout.chk @@ -0,0 +1 @@ +asmkx diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wborder.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wborder.chk new file mode 100644 index 0000000..50857fa --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wborder.chk @@ -0,0 +1,6 @@ +smacslqqqqkrmacs + smacsxrmacs smacsxrmacs + smacsxrmacs smacsxrmacs + smacsxrmacs smacsxrmacs + smacsxrmacs smacsxrmacs + smacsmqqqqjrmacscup3;6X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wborder_refresh.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wborder_refresh.chk new file mode 100644 index 0000000..0247178 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wborder_refresh.chk @@ -0,0 +1 @@ +home \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr.chk new file mode 100644 index 0000000..770eab4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr.chk @@ -0,0 +1 @@ +input \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr_refresh.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr_refresh.chk new file mode 100644 index 0000000..e8bbed5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr_refresh.chk @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/window.chk b/contrib/netbsd-tests/lib/libcurses/check_files/window.chk new file mode 100644 index 0000000..732f4cc --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/window.chk @@ -0,0 +1 @@ +cup3;6X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wprintw_refresh.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wprintw_refresh.chk new file mode 100644 index 0000000..53794ad --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wprintw_refresh.chk @@ -0,0 +1 @@ +cup3;6Xhellocup3;10X \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wscrl1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wscrl1.chk new file mode 100644 index 0000000..627141d --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wscrl1.chk @@ -0,0 +1 @@ +cup4;7Xxxxxhome \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wscrl2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wscrl2.chk new file mode 100644 index 0000000..ee36e55 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/check_files/wscrl2.chk @@ -0,0 +1 @@ +cup4;7Xelcup6;7Xxxxxhome \ No newline at end of file diff --git a/contrib/netbsd-tests/lib/libcurses/director/director.c b/contrib/netbsd-tests/lib/libcurses/director/director.c new file mode 100644 index 0000000..c73ddae --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/director/director.c @@ -0,0 +1,279 @@ +/* $NetBSD: director.c,v 1.10 2012/06/03 23:19:11 joerg Exp $ */ + +/*- + * Copyright 2009 Brett Lymn + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "returns.h" + +void yyparse(void); +#define DEF_TERMPATH "." +#define DEF_TERM "atf" +#define DEF_SLAVE "./slave" + +const char *def_check_path = "./"; /* default check path */ +const char *def_include_path = "./"; /* default include path */ + +extern size_t nvars; /* In testlang_conf.y */ +saved_data_t saved_output; /* In testlang_conf.y */ +int cmdpipe[2]; /* command pipe between director and slave */ +int slvpipe[2]; /* reply pipe back from slave */ +int master; /* pty to the slave */ +int verbose; /* control verbosity of tests */ +const char *check_path; /* path to prepend to check files for output + validation */ +const char *include_path; /* path to prepend to include files */ +char *cur_file; /* name of file currently being read */ + +void init_parse_variables(int); /* in testlang_parse.y */ + +/* + * Handle the slave exiting unexpectedly, try to recover the exit message + * and print it out. + */ +static void +slave_died(int param) +{ + char last_words[256]; + size_t count; + + fprintf(stderr, "ERROR: Slave has exited\n"); + if (saved_output.count > 0) { + fprintf(stderr, "output from slave: "); + for (count = 0; count < saved_output.count; count ++) { + if (isprint((unsigned char)saved_output.data[count])) + fprintf(stderr, "%c", saved_output.data[count]); + } + fprintf(stderr, "\n"); + } + + if ((count = read(master, &last_words, 255)) > 0) { + last_words[count] = '\0'; + fprintf(stderr, "slave exited with message \"%s\"\n", + last_words); + } + + exit(2); +} + + +static void +usage(void) +{ + fprintf(stderr, "Usage: %s [-v] [-I include-path] [-C check-path] " + "[-T terminfo-file] [-s pathtoslave] [-t term] " + "commandfile\n", getprogname()); + fprintf(stderr, " where:\n"); + fprintf(stderr, " -v enables verbose test output\n"); + fprintf(stderr, " -T is a directory containing the terminfo.cdb " + "file, or a file holding the terminfo description n"); + fprintf(stderr, " -s is the path to the slave executable\n"); + fprintf(stderr, " -t is value to set TERM to for the test\n"); + fprintf(stderr, " -I is the directory to include files\n"); + fprintf(stderr, " -C is the directory for config files\n"); + fprintf(stderr, " commandfile is a file of test directives\n"); + exit(1); +} + + +int +main(int argc, char *argv[]) +{ + extern char *optarg; + extern int optind; + const char *termpath, *term, *slave; + int ch; + pid_t slave_pid; + extern FILE *yyin; + char *arg1, *arg2, *arg3, *arg4; + struct termios term_attr; + struct stat st; + + termpath = term = slave = NULL; + verbose = 0; + + while ((ch = getopt(argc, argv, "vC:I:p:s:t:T:")) != -1) { + switch(ch) { + case 'I': + include_path = optarg; + break; + case 'C': + check_path = optarg; + break; + case 'T': + termpath = optarg; + break; + case 'p': + termpath = optarg; + break; + case 's': + slave = optarg; + break; + case 't': + term = optarg; + break; + case 'v': + verbose = 1; + break; + case '?': + default: + usage(); + break; + } + } + + argc -= optind; + argv += optind; + if (argc < 1) + usage(); + + if (termpath == NULL) + termpath = DEF_TERMPATH; + + if (slave == NULL) + slave = DEF_SLAVE; + + if (term == NULL) + term = DEF_TERM; + + if (check_path == NULL) + check_path = getenv("CHECK_PATH"); + if ((check_path == NULL) || (check_path[0] == '\0')) { + warn("$CHECK_PATH not set, defaulting to %s", def_check_path); + check_path = def_check_path; + } + + if (include_path == NULL) + include_path = getenv("INCLUDE_PATH"); + if ((include_path == NULL) || (include_path[0] == '\0')) { + warn("$INCLUDE_PATH not set, defaulting to %s", + def_include_path); + include_path = def_include_path; + } + + signal(SIGCHLD, slave_died); + + if (setenv("TERM", term, 1) != 0) + err(2, "Failed to set TERM variable"); + + if (stat(termpath, &st) == -1) + err(1, "Cannot stat %s", termpath); + + if (S_ISDIR(st.st_mode)) { + char tinfo[MAXPATHLEN]; + int l = snprintf(tinfo, sizeof(tinfo), "%s/%s", termpath, + "terminfo.cdb"); + if (stat(tinfo, &st) == -1) + err(1, "Cannot stat `%s'", tinfo); + if (l >= 4) + tinfo[l - 4] = '\0'; + if (setenv("TERMINFO", tinfo, 1) != 0) + err(1, "Failed to set TERMINFO variable"); + } else { + int fd; + char *tinfo; + if ((fd = open(termpath, O_RDONLY)) == -1) + err(1, "Cannot open `%s'", termpath); + if ((tinfo = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_FILE, + fd, 0)) == MAP_FAILED) + err(1, "Cannot map `%s'", termpath); + if (setenv("TERMINFO", tinfo, 1) != 0) + err(1, "Failed to set TERMINFO variable"); + close(fd); + munmap(tinfo, (size_t)st.st_size); + } + + if (pipe(cmdpipe) < 0) + err(1, "Command pipe creation failed"); + + if (pipe(slvpipe) < 0) + err(1, "Slave pipe creation failed"); + + /* + * Create default termios settings for later use + */ + memset(&term_attr, 0, sizeof(term_attr)); + term_attr.c_iflag = TTYDEF_IFLAG; + term_attr.c_oflag = TTYDEF_OFLAG; + term_attr.c_cflag = TTYDEF_CFLAG; + term_attr.c_lflag = TTYDEF_LFLAG; + cfsetspeed(&term_attr, TTYDEF_SPEED); + term_attr.c_cc[VERASE] = '\b'; + term_attr.c_cc[VKILL] = '\025'; /* ^U */ + + if ((slave_pid = forkpty(&master, NULL, &term_attr, NULL)) < 0) + err(1, "Fork of pty for slave failed\n"); + + if (slave_pid == 0) { + /* slave side, just exec the slave process */ + if (asprintf(&arg1, "%d", cmdpipe[0]) < 0) + err(1, "arg1 conversion failed"); + + if (asprintf(&arg2, "%d", cmdpipe[1]) < 0) + err(1, "arg2 conversion failed"); + + if (asprintf(&arg3, "%d", slvpipe[0]) < 0) + err(1, "arg3 conversion failed"); + + if (asprintf(&arg4, "%d", slvpipe[1]) < 0) + err(1, "arg4 conversion failed"); + + if (execl(slave, slave, arg1, arg2, arg3, arg4, NULL) < 0) + err(1, "Exec of slave %s failed", slave); + + /* NOT REACHED */ + } + + fcntl(master, F_SETFL, O_NONBLOCK); + + if ((yyin = fopen(argv[0], "r")) == NULL) + err(1, "Cannot open command file %s", argv[0]); + + if ((cur_file = strdup(argv[0])) == NULL) + err(2, "Failed to alloc memory for test file name"); + + init_parse_variables(1); + + yyparse(); + fclose(yyin); + + exit(0); +} diff --git a/contrib/netbsd-tests/lib/libcurses/director/returns.h b/contrib/netbsd-tests/lib/libcurses/director/returns.h new file mode 100644 index 0000000..150e358 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/director/returns.h @@ -0,0 +1,66 @@ +/* $NetBSD: returns.h,v 1.1 2011/04/10 09:55:09 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * + */ +#ifndef CTF_RETURNS_H +#define CTF_RETURNS_H 1 + + +typedef enum { + ret_number = 1, + ret_string, + ret_byte, + ret_err, + ret_ok, + ret_null, + ret_nonnull, + ret_var, + ret_ref, + ret_count, + ret_slave_error +} returns_enum_t; + +typedef struct { + returns_enum_t return_type; + void *return_value; /* used if return_type is ret_num or + or ret_byte or ret_string */ + size_t return_len; /* number of bytes in return_value iff + return_type is ret_byte */ + int return_index; /* index into var array for return + if return_type is ret_var */ +} returns_t; + +typedef struct { + size_t count; + size_t allocated; + size_t readp; + char *data; +} saved_data_t; + +#endif /* CTF_RETURNS_H */ diff --git a/contrib/netbsd-tests/lib/libcurses/director/testlang_conf.l b/contrib/netbsd-tests/lib/libcurses/director/testlang_conf.l new file mode 100644 index 0000000..a732afc --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/director/testlang_conf.l @@ -0,0 +1,437 @@ +%{ +/* $NetBSD: testlang_conf.l,v 1.7 2013/11/21 11:06:04 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include +#include +#include +#include +#include +#include +#include "returns.h" +#include "testlang_parse.h" + +#define MAX_INCLUDES 32 /* limit for the number of nested includes */ + +int yylex(void); + +extern size_t line; +extern char *include_path; /* from director.c */ +extern char *cur_file; /* from director.c */ + +static int include_stack[MAX_INCLUDES]; +static char *include_files[MAX_INCLUDES]; +static int include_ptr = 0; + +static char * +dequote(const char *s, size_t *len) +{ + const unsigned char *p; + char *buf, *q; + + *len = 0; + p = (const unsigned char *)s; + while (*p) { + if (*p == '\\' && *(p+1)) { + if (isdigit(*(p+1)) && *(p+2) && isdigit(*(p+2)) && + *(p+3) && isdigit(*(p+3))) + p += 3; + else + ++p; + } + ++(*len); + ++p; + } + + buf = malloc(*len + 1); + if (buf == NULL) + return NULL; + + p = (const unsigned char *)s; + q = buf; + while (*p) { + if (*p == '\\' && *(p+1)) { + ++p; + if (isdigit(*p)) { + if (*(p+1) && isdigit(*(p+1)) && *(p+2) && + isdigit(*(p+2))) { + *q++ = ((*p - '0') * 8 + (*(p+1) - '0')) * 8 + (*(p+2) - '0'); + p += 3; + } else { + *q++ = *p++; + } + } else { + switch (*p) { + case 'e': + /* escape */ + *q++ = '\e'; + p++; + break; + + case 'n': + /* newline */ + *q++ = '\n'; + p++; + break; + + case 'r': + /* carriage return */ + *q++ = '\r'; + p++; + break; + + case 't': + /* tab */ + *q++ = '\t'; + p++; + break; + + case '\\': + /* backslash */ + *q++ = '\\'; + p++; + break; + + default: + *q++ = *p++; + } + } + } else + *q++ = *p++; + } + *q++ = '\0'; + + return buf; +} +%} + +HEX 0[xX][0-9a-zA-Z]+ +STRING [0-9a-z!#-&(-^ \t%._\\]+ +numeric [-0-9]+ +PCHAR (\\.|[^ \t\n]) +ASSIGN [aA][sS][sS][iI][gG][nN] +CALL2 [cC][aA][lL][lL]2 +CALL3 [cC][aA][lL][lL]3 +CALL4 [cC][aA][lL][lL]4 +CALL [cC][aA][lL][lL] +CHECK [cC][hH][eE][cC][kK] +DELAY [dD][eE][lL][aA][yY] +INPUT [iI][nN][pP][uU][tT] +NOINPUT [nN][oO][iI][nN][pP][uU][tT] +OK_RET [oO][kK] +ERR_RET [eE][rR][rR] +COMPARE [cC][oO][mM][pP][aA][rR][eE] +COMPAREND [cC][oO][mM][pP][aA][rR][eE][Nn][Dd] +FILENAME [A-Za-z0-9.][A-Za-z0-9./_-]+ +VARNAME [A-Za-z][A-Za-z0-9_-]+ +NULL_RET NULL +NON_NULL NON_NULL +BYTE BYTE +OR \| +LHB \( +RHB \) + +%x incl +%option noinput nounput + +%% + +include BEGIN(incl); + +[ \t]* /* eat the whitespace */ +[^ \t\n]+ { /* got the include file name */ + char inc_file[MAXPATHLEN]; + + if (include_ptr > MAX_INCLUDES) { + fprintf(stderr, + "Maximum number of nested includes exceeded " + "at line %zu of file %s\n", line, cur_file); + exit(2); + } + + if (yytext[0] != '/') { + if (strlcpy(inc_file, include_path, sizeof(inc_file)) + >= sizeof(inc_file)) + err(2, "CHECK_PATH too long"); + if ((include_path[strlen(include_path) - 1] != '/') && + ((strlcat(inc_file, "/", sizeof(inc_file)) + >= sizeof(inc_file)))) + err(2, "Could not append / to include file path"); + } else { + inc_file[0] = '\0'; + } + + if (strlcat(inc_file, yytext, sizeof(inc_file)) + >= sizeof(inc_file)) + err(2, "Path to include file path overflowed"); + + yyin = fopen(inc_file, "r" ); + + if (!yyin) + err(1, "Error opening %s", inc_file); + + yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); + + include_stack[include_ptr] = line; + include_files[include_ptr++] = cur_file; + cur_file = strdup(inc_file); + if (cur_file == NULL) + err(2, "Cannot allocate new include file string"); + line = 0; + BEGIN(INITIAL); + } + +<> { + yypop_buffer_state(); + + if ( !YY_CURRENT_BUFFER ) + { + yyterminate(); + } + + if (--include_ptr < 0) + err(2, "Include stack underflow"); + + free(cur_file); + cur_file = include_files[include_ptr]; + line = include_stack[include_ptr]; + } + +{ASSIGN} { + return ASSIGN; + } + +{CALL2} { + return CALL2; + } + +{CALL3} { + return CALL3; + } + +{CALL4} { + return CALL4; + } + +{CALL} { + return CALL; + } + +{CHECK} { + return CHECK; + } + +{DELAY} { + return DELAY; + } + +{INPUT} { + return INPUT; + } + +{NOINPUT} { + return NOINPUT; + } + +{COMPARE} { + return COMPARE; + } + +{COMPAREND} { + return COMPAREND; + } + +{NON_NULL} { + return NON_NULL; + } + +{NULL_RET} { + return NULL_RET; + } + +{OK_RET} { + return OK_RET; + } + +{ERR_RET} { + return ERR_RET; + } + +{OR} { + return OR; + } + +{LHB} { + return LHB; + } + +{RHB} { + return RHB; + } + +{HEX} { + /* Hex value, convert to decimal and return numeric */ + unsigned long val; + + if (sscanf(yytext, "%lx", &val) != 1) + err(1, "Bad hex conversion"); + + asprintf(&yylval.string, "%ld", val); + return numeric; + } + + +{numeric} { + if ((yylval.string = strdup(yytext)) == NULL) + err(1, "Cannot allocate numeric string"); + return numeric; +} + +{VARNAME} { + if ((yylval.string = strdup(yytext)) == NULL) + err(1, "Cannot allocate string for varname"); + return VARNAME; + } + +{FILENAME} { + size_t len; + + if ((yylval.string = dequote(yytext, &len)) == NULL) + err(1, "Cannot allocate filename string"); + return FILENAME; + } + + /* path */ +\/{PCHAR}+ { + size_t len; + if ((yylval.string = dequote(yytext, &len)) == NULL) + err(1, "Cannot allocate string"); + return PATH; + } + +\'{STRING}\' { + char *p; + size_t len; + + if ((yylval.retval = malloc(sizeof(returns_t))) == NULL) + err(1, "Cannot allocate return struct"); + p = yytext; + p++; /* skip the leading ' */ + if ((yylval.retval->return_value = dequote(p, &len)) + == NULL) + err(1, "Cannot allocate string"); + + yylval.retval->return_type = ret_byte; + /* trim trailing ' */ + yylval.retval->return_len = len - 1; + return BYTE; + } + +\`{STRING}\` { + char *p, *str; + size_t len, chlen; + size_t i; + chtype *rv; + + if ((yylval.retval = malloc(sizeof(returns_t))) == NULL) + err(1, "Cannot allocate return struct"); + p = yytext; + p++; /* skip the leading ' */ + if ((str = dequote(p, &len)) == NULL) + err(1, "Cannot allocate string"); + len--; /* trim trailing ` */ + if ((len % 2) != 0) + len--; + + chlen = ((len / 2) + 1) * sizeof(chtype); + if ((yylval.retval->return_value = malloc(chlen)) + == NULL) + err(1, "Cannot allocate chtype array"); + + rv = yylval.retval->return_value; + for (i = 0; i < len; i += 2) + *rv++ = (str[i] << 8) | str[i+1]; + *rv = __NORMAL | '\0'; /* terminates chtype array */ + yylval.retval->return_type = ret_byte; + yylval.retval->return_len = chlen; + return BYTE; + } + +\"{STRING}\" { + char *p; + size_t len; + + p = yytext; + p++; /* skip the leading " */ + if ((yylval.string = dequote(p, &len)) == NULL) + err(1, "Cannot allocate string"); + + /* remove trailing " */ + yylval.string[len - 1] = '\0'; + return STRING; + } + +\${VARNAME} { + char *p; + + p = yytext; + p++; /* skip $ before var name */ + if ((yylval.string = strdup(p)) == NULL) + err(1, "Cannot allocate string for varname"); + return VARIABLE; + } + + /* comments, white-outs */ +[ \t\r] | +#.* ; +^#.*\n | +#.*\n | +\\\n | +^\n { +line++; } + + /* eol on a line with data. need to process, return eol */ +\n { + line++; + return EOL; + } + +. { + } + +%% + +int +yywrap(void) +{ + return 1; +} diff --git a/contrib/netbsd-tests/lib/libcurses/director/testlang_parse.y b/contrib/netbsd-tests/lib/libcurses/director/testlang_parse.y new file mode 100644 index 0000000..75aaf62 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/director/testlang_parse.y @@ -0,0 +1,1618 @@ +%{ +/* $NetBSD: testlang_parse.y,v 1.14 2015/01/04 20:19:46 christos Exp $ */ + +/*- + * Copyright 2009 Brett Lymn + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "returns.h" + +#define YYDEBUG 1 + +extern int verbose; +extern int cmdpipe[2]; +extern int slvpipe[2]; +extern int master; +extern struct pollfd readfd; +extern char *check_path; +extern char *cur_file; /* from director.c */ + +int yylex(void); + +size_t line; + +static int input_delay; + +/* time delay between inputs chars - default to 0.1ms minimum to prevent + * problems with input tests + */ +#define DELAY_MIN 0.1 + +/* time delay after a function call - allows the slave time to + * run the function and output data before we do other actions. + * Set this to 50ms. + */ +#define POST_CALL_DELAY 50 + +static struct timespec delay_spec = {0, 1000 * DELAY_MIN}; +static struct timespec delay_post_call = {0, 1000 * POST_CALL_DELAY}; + +static char *input_str; /* string to feed in as input */ +static bool no_input; /* don't need more input */ + +#define READ_PIPE 0 +#define WRITE_PIPE 1 + +const char *returns_enum_names[] = { + "unused", "numeric", "string", "byte", "ERR", "OK", "NULL", "not NULL", + "variable", "reference", "returns count", "slave error" +}; + +typedef enum { + arg_static, + arg_byte, + arg_var, + arg_null +} args_state_t; + +static const char *args_enum_names[] = { + "static", "byte", "var", "NULL" +}; + +typedef struct { + args_state_t arg_type; + size_t arg_len; + char *arg_string; + int var_index; +} args_t; + +typedef struct { + char *function; + int nrets; /* number of returns */ + returns_t *returns; /* array of expected returns */ + int nargs; /* number of arguments */ + args_t *args; /* arguments for the call */ +} cmd_line_t; + +static cmd_line_t command; + +typedef struct { + char *name; + size_t len; + returns_enum_t type; + void *value; +} var_t; + +static size_t nvars; /* Number of declared variables */ +static var_t *vars; /* Variables defined during the test. */ + +static int check_function_table(char *, const char *[], int); +static int find_var_index(const char *); +static void assign_arg(args_state_t, void *); +static int assign_var(char *); +void init_parse_variables(int); +static void validate(int, void *); +static void validate_return(const char *, const char *, int); +static void validate_variable(int, returns_enum_t, const void *, int, int); +static void validate_byte(returns_t *, returns_t *, int); +static void write_cmd_pipe(char *); +static void write_cmd_pipe_args(args_state_t, void *); +static void read_cmd_pipe(returns_t *); +static void write_func_and_args(void); +static void compare_streams(char *, bool); +static void do_function_call(size_t); +static void save_slave_output(bool); +static void validate_type(returns_enum_t, returns_t *, int); +static void set_var(returns_enum_t, char *, void *); +static void validate_reference(int, void *); +static char *numeric_or(char *, char *); +static char *get_numeric_var(const char *); +static void perform_delay(struct timespec *); + +static const char *input_functions[] = { + "getch", "getnstr", "getstr", "mvgetnstr", "mvgetstr", "mvgetnstr", + "mvgetstr", "mvscanw", "mvwscanw", "scanw", "wgetch", "wgetnstr", + "wgetstr" +}; + +static const unsigned ninput_functions = + sizeof(input_functions) / sizeof(char *); + +saved_data_t saved_output; + +%} + +%union { + char *string; + returns_t *retval; +} + +%token PATH +%token STRING +%token BYTE +%token VARNAME +%token FILENAME +%token VARIABLE +%token REFERENCE +%token NULL_RET +%token NON_NULL +%token ERR_RET +%token OK_RET +%token numeric +%token DELAY +%token INPUT +%token COMPARE +%token COMPAREND +%token ASSIGN +%token EOL CALL CHECK NOINPUT OR LHB RHB +%token CALL2 CALL3 CALL4 DRAIN + +%nonassoc OR + +%% + +statement : /* empty */ + | assign statement + | call statement + | call2 statement + | call3 statement + | call4 statement + | check statement + | delay statement + | input statement + | noinput statement + | compare statement + | comparend statement + | eol statement + ; + +assign : ASSIGN VARNAME numeric {set_var(ret_number, $2, $3);} eol + | ASSIGN VARNAME LHB expr RHB {set_var(ret_number, $2, $4);} eol + | ASSIGN VARNAME STRING {set_var(ret_string, $2, $3);} eol + | ASSIGN VARNAME BYTE {set_var(ret_byte, $2, $3);} eol + ; + +call : CALL result fn_name args eol { + do_function_call(1); +} + ; + +call2 : CALL2 result result fn_name args eol { + do_function_call(2); +} + ; + +call3 : CALL3 result result result fn_name args eol { + do_function_call(3); +} + ; + +call4 : CALL4 result result result result fn_name args eol { + do_function_call(4); + } + ; + +check : CHECK var returns eol { + returns_t retvar; + var_t *vptr; + if (command.returns[0].return_index == -1) + err(1, "Undefined variable in check statement, line %zu" + " of file %s", line, cur_file); + + if (verbose) { + fprintf(stderr, "Checking contents of variable %s for %s\n", + vars[command.returns[0].return_index].name, + returns_enum_names[command.returns[1].return_type]); + } + + if (((command.returns[1].return_type == ret_byte) && + (vars[command.returns[0].return_index].type != ret_byte)) || + vars[command.returns[0].return_index].type != ret_string) + err(1, "Var type %s (%d) does not match return type %s (%d)", + returns_enum_names[ + vars[command.returns[0].return_index].type], + vars[command.returns[0].return_index].type, + returns_enum_names[command.returns[1].return_type], + command.returns[1].return_type); + + switch (command.returns[1].return_type) { + case ret_err: + validate_variable(0, ret_string, "ERR", + command.returns[0].return_index, 0); + break; + + case ret_ok: + validate_variable(0, ret_string, "OK", + command.returns[0].return_index, 0); + break; + + case ret_null: + validate_variable(0, ret_string, "NULL", + command.returns[0].return_index, 0); + break; + + case ret_nonnull: + validate_variable(0, ret_string, "NULL", + command.returns[0].return_index, 1); + break; + + case ret_string: + case ret_number: + if (verbose) { + fprintf(stderr, " %s == returned %s\n", + (const char *)command.returns[1].return_value, + (const char *) + vars[command.returns[0].return_index].value); + } + validate_variable(0, ret_string, + command.returns[1].return_value, + command.returns[0].return_index, 0); + break; + + case ret_byte: + vptr = &vars[command.returns[0].return_index]; + retvar.return_len = vptr->len; + retvar.return_type = vptr->type; + retvar.return_value = vptr->value; + validate_byte(&retvar, &command.returns[1], 0); + break; + + default: + err(1, "Malformed check statement at line %zu " + "of file %s", line, cur_file); + break; + } + + init_parse_variables(0); + } + ; + +delay : DELAY numeric eol { + /* set the inter-character delay */ + if (sscanf($2, "%d", &input_delay) == 0) + err(1, "delay specification %s could not be converted to " + "numeric at line %zu of file %s", $2, line, cur_file); + if (verbose) { + fprintf(stderr, "Set input delay to %d ms\n", input_delay); + } + + if (input_delay < DELAY_MIN) + input_delay = DELAY_MIN; + /* + * Fill in the timespec structure now ready for use later. + * The delay is specified in milliseconds so convert to timespec + * values + */ + delay_spec.tv_sec = input_delay / 1000; + delay_spec.tv_nsec = (input_delay - 1000 * delay_spec.tv_sec) * 1000; + if (verbose) { + fprintf(stderr, "set delay to %jd.%jd\n", + (intmax_t)delay_spec.tv_sec, + (intmax_t)delay_spec.tv_nsec); + } + + init_parse_variables(0); + } + ; + +input : INPUT STRING eol { + if (input_str != NULL) { + warnx("%s, %zu: Discarding unused input string", + cur_file, line); + free(input_str); + } + + if ((input_str = malloc(strlen($2) + 1)) == NULL) + err(2, "Cannot allocate memory for input string"); + + strlcpy(input_str, $2, strlen($2) + 1); +} + ; + + +noinput : NOINPUT eol { + if (input_str != NULL) { + warnx("%s, %zu: Discarding unused input string", + cur_file, line); + free(input_str); + } + + no_input = true; + } + +compare : COMPARE PATH eol + | COMPARE FILENAME eol +{ + compare_streams($2, true); +} + ; + + +comparend : COMPAREND PATH eol + | COMPAREND FILENAME eol +{ + compare_streams($2, false); +} + ; + + +result : returns + | var + | reference + ; + +returns : numeric { assign_rets(ret_number, $1); } + | LHB expr RHB { assign_rets(ret_number, $2); } + | STRING { assign_rets(ret_string, $1); } + | BYTE { assign_rets(ret_byte, (void *) $1); } + | ERR_RET { assign_rets(ret_err, NULL); } + | OK_RET { assign_rets(ret_ok, NULL); } + | NULL_RET { assign_rets(ret_null, NULL); } + | NON_NULL { assign_rets(ret_nonnull, NULL); } + ; + +var : VARNAME { + assign_rets(ret_var, $1); + } + ; + +reference : VARIABLE { + assign_rets(ret_ref, $1); + } + +fn_name : VARNAME { + if (command.function != NULL) + free(command.function); + + command.function = malloc(strlen($1) + 1); + if (command.function == NULL) + err(1, "Could not allocate memory for function name"); + strcpy(command.function, $1); + } + ; + +expr : numeric + | VARIABLE + { $$ = get_numeric_var($1); } + | expr OR expr + { $$ = numeric_or($1, $3); } + ; + +args : /* empty */ + | LHB expr RHB { assign_arg(arg_static, $2); } args + | numeric { assign_arg(arg_static, $1); } args + | STRING { assign_arg(arg_static, $1); } args + | BYTE { assign_arg(arg_byte, $1); } args + | PATH { assign_arg(arg_static, $1); } args + | FILENAME { assign_arg(arg_static, $1); } args + | VARNAME { assign_arg(arg_static, $1); } args + | VARIABLE { assign_arg(arg_var, $1); } args + | NULL_RET { assign_arg(arg_null, $1); } args + ; + +eol : EOL + ; + +%% + +static void +excess(const char *fname, size_t lineno, const char *func, const char *comment, + const void *data, size_t datalen) +{ + size_t dstlen = datalen * 4 + 1; + char *dst = malloc(dstlen); + + if (dst == NULL) + err(1, "malloc"); + + if (strnvisx(dst, dstlen, data, datalen, VIS_WHITE | VIS_OCTAL) == -1) + err(1, "strnvisx"); + + warnx("%s, %zu: [%s] Excess %zu bytes%s [%s]", + fname, lineno, func, datalen, comment, dst); + free(dst); +} + +/* + * Get the value of a variable, error if the variable has not been set or + * is not a numeric type. + */ +static char * +get_numeric_var(const char *var) +{ + int i; + + if ((i = find_var_index(var)) < 0) + err(1, "Variable %s is undefined", var); + + if (vars[i].type != ret_number) + err(1, "Variable %s is not a numeric type", var); + + return vars[i].value; +} + +/* + * Perform a bitwise OR on two numbers and return the result. + */ +static char * +numeric_or(char *n1, char *n2) +{ + unsigned long i1, i2, result; + char *ret; + + i1 = strtoul(n1, NULL, 10); + i2 = strtoul(n2, NULL, 10); + + result = i1 | i2; + asprintf(&ret, "%lu", result); + + if (verbose) { + fprintf(stderr, "numeric or of 0x%lx (%s) and 0x%lx (%s)" + " results in 0x%lx (%s)\n", + i1, n1, i2, n2, result, ret); + } + + return ret; +} + +/* + * Sleep for the specified time, handle the sleep getting interrupted + * by a signal. + */ +static void +perform_delay(struct timespec *ts) +{ + struct timespec delay_copy, delay_remainder; + + delay_copy = *ts; + while (nanosleep(&delay_copy, &delay_remainder) < 0) { + if (errno != EINTR) + err(2, "nanosleep returned error"); + delay_copy = delay_remainder; + } +} + +/* + * Assign the value given to the named variable. + */ +static void +set_var(returns_enum_t type, char *name, void *value) +{ + int i; + char *number; + returns_t *ret; + + i = find_var_index(name); + if (i < 0) + i = assign_var(name); + + vars[i].type = type; + if ((type == ret_number) || (type == ret_string)) { + number = value; + vars[i].len = strlen(number) + 1; + vars[i].value = malloc(vars[i].len + 1); + if (vars[i].value == NULL) + err(1, "Could not malloc memory for assign string"); + strcpy(vars[i].value, number); + } else { + /* can only be a byte value */ + ret = value; + vars[i].len = ret->return_len; + vars[i].value = malloc(vars[i].len); + if (vars[i].value == NULL) + err(1, "Could not malloc memory to assign byte string"); + memcpy(vars[i].value, ret->return_value, vars[i].len); + } +} + +/* + * Add a new variable to the vars array, the value will be assigned later, + * when a test function call returns. + */ +static int +assign_var(char *varname) +{ + var_t *temp; + char *name; + + if ((name = malloc(strlen(varname) + 1)) == NULL) + err(1, "Alloc of varname failed"); + + if ((temp = realloc(vars, sizeof(*temp) * (nvars + 1))) == NULL) { + free(name); + err(1, "Realloc of vars array failed"); + } + + strcpy(name, varname); + vars = temp; + vars[nvars].name = name; + vars[nvars].len = 0; + vars[nvars].value = NULL; + nvars++; + + return (nvars - 1); +} + +/* + * Allocate and assign a new argument of the given type. + */ +static void +assign_arg(args_state_t arg_type, void *arg) +{ + args_t *temp, cur; + char *str = arg; + returns_t *ret; + + if (verbose) { + fprintf(stderr, "function is >%s<, adding arg >%s< type %s\n", + command.function, str, args_enum_names[arg_type]); + } + + cur.arg_type = arg_type; + switch (arg_type) { + case arg_var: + cur.var_index = find_var_index(arg); + if (cur.var_index < 0) + err(1, "Invalid variable %s at line %zu of file %s", + str, line, cur_file); + cur.arg_type = ret_string; + break; + + case arg_byte: + ret = arg; + cur.arg_len = ret->return_len; + cur.arg_string = malloc(cur.arg_len); + if (cur.arg_string == NULL) + err(1, "Could not malloc memory for arg bytes"); + memcpy(cur.arg_string, ret->return_value, cur.arg_len); + break; + + case arg_null: + cur.arg_len = 0; + cur.arg_string = NULL; + break; + + default: + cur.arg_len = strlen(str); + cur.arg_string = malloc(cur.arg_len + 1); + if (cur.arg_string == NULL) + err(1, "Could not malloc memory for arg string"); + strcpy(cur.arg_string, arg); + } + + temp = realloc(command.args, sizeof(*temp) * (command.nargs + 1)); + if (temp == NULL) + err(1, "Failed to reallocate args"); + command.args = temp; + memcpy(&command.args[command.nargs], &cur, sizeof(args_t)); + command.nargs++; +} + +/* + * Allocate and assign a new return. + */ +static void +assign_rets(returns_enum_t ret_type, void *ret) +{ + returns_t *temp, cur; + char *ret_str; + returns_t *ret_ret; + + cur.return_type = ret_type; + if (ret_type != ret_var) { + if ((ret_type == ret_number) || (ret_type == ret_string)) { + ret_str = ret; + cur.return_len = strlen(ret_str) + 1; + cur.return_value = malloc(cur.return_len + 1); + if (cur.return_value == NULL) + err(1, + "Could not malloc memory for arg string"); + strcpy(cur.return_value, ret_str); + } else if (ret_type == ret_byte) { + ret_ret = ret; + cur.return_len = ret_ret->return_len; + cur.return_value = malloc(cur.return_len); + if (cur.return_value == NULL) + err(1, + "Could not malloc memory for byte string"); + memcpy(cur.return_value, ret_ret->return_value, + cur.return_len); + } else if (ret_type == ret_ref) { + if ((cur.return_index = find_var_index(ret)) < 0) + err(1, "Undefined variable reference"); + } + } else { + cur.return_index = find_var_index(ret); + if (cur.return_index < 0) + cur.return_index = assign_var(ret); + } + + temp = realloc(command.returns, sizeof(*temp) * (command.nrets + 1)); + if (temp == NULL) + err(1, "Failed to reallocate returns"); + command.returns = temp; + memcpy(&command.returns[command.nrets], &cur, sizeof(returns_t)); + command.nrets++; +} + +/* + * Find the given variable name in the var array and return the i + * return -1 if var is not found. + */ +static int +find_var_index(const char *var_name) +{ + int result; + size_t i; + + result = -1; + + for (i = 0; i < nvars; i++) { + if (strcmp(var_name, vars[i].name) == 0) { + result = i; + break; + } + } + + return result; +} + +/* + * Check the given function name in the given table of names, return 1 if + * there is a match. + */ +static int check_function_table(char *function, const char *table[], + int nfunctions) +{ + int i; + + for (i = 0; i < nfunctions; i++) { + if ((strlen(function) == strlen(table[i])) && + (strcmp(function, table[i]) == 0)) + return 1; + } + + return 0; +} + +/* + * Compare the output from the slave against the given file and report + * any differences. + */ +static void +compare_streams(char *filename, bool discard) +{ + char check_file[PATH_MAX], drain[100], ref, data; + struct pollfd fds[2]; + int nfd, check_fd; + ssize_t result; + size_t offs; + + /* + * Don't prepend check path iff check file has an absolute + * path. + */ + if (filename[0] != '/') { + if (strlcpy(check_file, check_path, sizeof(check_file)) + >= sizeof(check_file)) + err(2, "CHECK_PATH too long"); + + if (strlcat(check_file, "/", sizeof(check_file)) + >= sizeof(check_file)) + err(2, "Could not append / to check file path"); + } else { + check_file[0] = '\0'; + } + + if (strlcat(check_file, filename, sizeof(check_file)) + >= sizeof(check_file)) + err(2, "Path to check file path overflowed"); + + if ((check_fd = open(check_file, O_RDONLY, 0)) < 0) + err(2, "failed to open file %s line %zu of file %s", + check_file, line, cur_file); + + fds[0].fd = check_fd; + fds[0].events = POLLIN; + fds[1].fd = master; + fds[1].events = POLLIN; + + nfd = 2; + /* + * if we have saved output then only check for data in the + * reference file since the slave data may already be drained. + */ + if (saved_output.count > 0) + nfd = 1; + + offs = 0; + while (poll(fds, nfd, 500) == nfd) { + if (fds[0].revents & POLLIN) { + if ((result = read(check_fd, &ref, 1)) < 1) { + if (result != 0) { + err(2, + "Bad read on file %s", check_file); + } else { + break; + } + } + } + + if (saved_output.count > 0) { + data = saved_output.data[saved_output.readp]; + saved_output.count--; + saved_output.readp++; + /* run out of saved data, switch to file */ + if (saved_output.count == 0) + nfd = 2; + } else { + if (fds[0].revents & POLLIN) { + if (read(master, &data, 1) < 1) + err(2, "Bad read on slave pty"); + } else + continue; + } + + if (verbose) { + fprintf(stderr, "Comparing reference byte 0x%x (%c)" + " against slave byte 0x%x (%c)\n", + ref, (ref >= ' ') ? ref : '-', + data, (data >= ' ' )? data : '-'); + } + + if (ref != data) { + errx(2, "%s, %zu: refresh data from slave does " + "not match expected from file %s offs %zu " + "[reference 0x%x (%c) != slave 0x%x (%c)]", + cur_file, line, check_file, offs, + ref, (ref >= ' ') ? ref : '-', + data, (data >= ' ') ? data : '-'); + } + + offs++; + } + + + if (saved_output.count > 0) + excess(cur_file, line, __func__, " from slave", + &saved_output.data[saved_output.readp], saved_output.count); + + /* discard any excess saved output if required */ + if (discard) { + saved_output.count = 0; + saved_output.readp = 0; + } + + if ((result = poll(&fds[0], 2, 0)) != 0) { + if (result == -1) + err(2, "poll of file descriptors failed"); + + if ((fds[1].revents & POLLIN) == POLLIN) { + save_slave_output(true); + } else if ((fds[0].revents & POLLIN) == POLLIN) { + /* + * handle excess in file if it exists. Poll + * says there is data until EOF is read. + * Check next read is EOF, if it is not then + * the file really has more data than the + * slave produced so flag this as a warning. + */ + result = read(check_fd, drain, sizeof(drain)); + if (result == -1) + err(1, "read of data file failed"); + + if (result > 0) { + excess(check_file, 0, __func__, "", drain, + result); + } + } + } + + close(check_fd); +} + +/* + * Pass a function call and arguments to the slave and wait for the + * results. The variable nresults determines how many returns we expect + * back from the slave. These results will be validated against the + * expected returns or assigned to variables. + */ +static void +do_function_call(size_t nresults) +{ +#define MAX_RESULTS 4 + char *p; + int do_input; + size_t i; + struct pollfd fds[3]; + returns_t response[MAX_RESULTS], returns_count; + assert(nresults <= MAX_RESULTS); + + do_input = check_function_table(command.function, input_functions, + ninput_functions); + + write_func_and_args(); + + /* + * We should get the number of returns back here, grab it before + * doing input otherwise it will confuse the input poll + */ + read_cmd_pipe(&returns_count); + if (returns_count.return_type != ret_count) + err(2, "expected return type of ret_count but received %s", + returns_enum_names[returns_count.return_type]); + + perform_delay(&delay_post_call); /* let slave catch up */ + + if (verbose) { + fprintf(stderr, "Expect %zu results from slave, slave " + "reported %zu\n", nresults, returns_count.return_len); + } + + if ((no_input == false) && (do_input == 1)) { + if (verbose) { + fprintf(stderr, "doing input with inputstr >%s<\n", + input_str); + } + + if (input_str == NULL) + errx(2, "%s, %zu: Call to input function " + "but no input defined", cur_file, line); + + fds[0].fd = slvpipe[READ_PIPE]; + fds[0].events = POLLIN; + fds[1].fd = master; + fds[1].events = POLLOUT; + p = input_str; + save_slave_output(false); + while(*p != '\0') { + perform_delay(&delay_spec); + + if (poll(fds, 2, 0) < 0) + err(2, "poll failed"); + if (fds[0].revents & POLLIN) { + warnx("%s, %zu: Slave function " + "returned before end of input string", + cur_file, line); + break; + } + if ((fds[1].revents & POLLOUT) == 0) + continue; + if (verbose) { + fprintf(stderr, "Writing char >%c< to slave\n", + *p); + } + if (write(master, p, 1) != 1) { + warn("%s, %zu: Slave function write error", + cur_file, line); + break; + } + p++; + + } + save_slave_output(false); + + if (verbose) { + fprintf(stderr, "Input done.\n"); + } + + /* done with the input string, free the resources */ + free(input_str); + input_str = NULL; + } + + if (verbose) { + fds[0].fd = slvpipe[READ_PIPE]; + fds[0].events = POLLIN; + + fds[1].fd = slvpipe[WRITE_PIPE]; + fds[1].events = POLLOUT; + + fds[2].fd = master; + fds[2].events = POLLIN | POLLOUT; + + i = poll(&fds[0], 3, 1000); + fprintf(stderr, "Poll returned %zu\n", i); + for (i = 0; i < 3; i++) { + fprintf(stderr, "revents for fd[%zu] = 0x%x\n", + i, fds[i].revents); + } + } + + /* drain any trailing output */ + save_slave_output(false); + + for (i = 0; i < returns_count.return_len; i++) { + read_cmd_pipe(&response[i]); + } + + /* + * Check for a slave error in the first return slot, if the + * slave errored then we may not have the number of returns we + * expect but in this case we should report the slave error + * instead of a return count mismatch. + */ + if ((returns_count.return_len > 0) && + (response[0].return_type == ret_slave_error)) + err(2, "Slave returned error: %s", + (const char *)response[0].return_value); + + if (returns_count.return_len != nresults) + err(2, "Incorrect number of returns from slave, expected %zu " + "but received %zu", nresults, returns_count.return_len); + + if (verbose) { + for (i = 0; i < nresults; i++) { + if ((response[i].return_type != ret_byte) && + (response[i].return_type != ret_err) && + (response[i].return_type != ret_ok)) + fprintf(stderr, + "received response >%s< " + "expected", + (const char *)response[i].return_value); + else + fprintf(stderr, "received"); + + fprintf(stderr, " return_type %s\n", + returns_enum_names[command.returns[i].return_type]); + } + } + + for (i = 0; i < nresults; i++) { + if (command.returns[i].return_type != ret_var) { + validate(i, &response[i]); + } else { + vars[command.returns[i].return_index].len = + response[i].return_len; + vars[command.returns[i].return_index].value = + response[i].return_value; + vars[command.returns[i].return_index].type = + response[i].return_type; + } + } + + if (verbose && (saved_output.count > 0)) + excess(cur_file, line, __func__, " from slave", + &saved_output.data[saved_output.readp], saved_output.count); + + init_parse_variables(0); +} + +/* + * Write the function and command arguments to the command pipe. + */ +static void +write_func_and_args(void) +{ + int i; + + if (verbose) { + fprintf(stderr, "calling function >%s<\n", command.function); + } + + write_cmd_pipe(command.function); + for (i = 0; i < command.nargs; i++) { + if (command.args[i].arg_type == arg_var) + write_cmd_pipe_args(command.args[i].arg_type, + &vars[command.args[i].var_index]); + else + write_cmd_pipe_args(command.args[i].arg_type, + &command.args[i]); + } + + write_cmd_pipe(NULL); /* signal end of arguments */ +} + +/* + * Initialise the command structure - if initial is non-zero then just set + * everything to sane values otherwise free any memory that was allocated + * when building the structure. + */ +void +init_parse_variables(int initial) +{ + int i, result; + struct pollfd slave_pty; + + if (initial == 0) { + free(command.function); + for (i = 0; i < command.nrets; i++) { + if (command.returns[i].return_type == ret_number) + free(command.returns[i].return_value); + } + free(command.returns); + + for (i = 0; i < command.nargs; i++) { + if (command.args[i].arg_type != arg_var) + free(command.args[i].arg_string); + } + free(command.args); + } else { + line = 0; + input_delay = 0; + vars = NULL; + nvars = 0; + input_str = NULL; + saved_output.allocated = 0; + saved_output.count = 0; + saved_output.readp = 0; + saved_output.data = NULL; + } + + no_input = false; + command.function = NULL; + command.nargs = 0; + command.args = NULL; + command.nrets = 0; + command.returns = NULL; + + /* + * Check the slave pty for stray output from the slave, at this + * point we should not see any data as it should have been + * consumed by the test functions. If we see data then we have + * either a bug or are not handling an output generating function + * correctly. + */ + slave_pty.fd = master; + slave_pty.events = POLLIN; + result = poll(&slave_pty, 1, 0); + + if (result < 0) + err(2, "Poll of slave pty failed"); + else if (result > 0) + warnx("%s, %zu: Unexpected data from slave", cur_file, line); +} + +/* + * Validate the response against the expected return. The variable + * i is the i into the rets array in command. + */ +static void +validate(int i, void *data) +{ + char *response; + returns_t *byte_response; + + byte_response = data; + if ((command.returns[i].return_type != ret_byte) && + (command.returns[i].return_type != ret_err) && + (command.returns[i].return_type != ret_ok)) { + if ((byte_response->return_type == ret_byte) || + (byte_response->return_type == ret_err) || + (byte_response->return_type == ret_ok)) + err(1, "%s: expecting type %s, received type %s" + " at line %zu of file %s", __func__, + returns_enum_names[command.returns[i].return_type], + returns_enum_names[byte_response->return_type], + line, cur_file); + + response = byte_response->return_value; + } + + switch (command.returns[i].return_type) { + case ret_err: + validate_type(ret_err, byte_response, 0); + break; + + case ret_ok: + validate_type(ret_ok, byte_response, 0); + break; + + case ret_null: + validate_return("NULL", response, 0); + break; + + case ret_nonnull: + validate_return("NULL", response, 1); + break; + + case ret_string: + case ret_number: + validate_return(command.returns[i].return_value, + response, 0); + break; + + case ret_ref: + validate_reference(i, response); + break; + + case ret_byte: + validate_byte(&command.returns[i], byte_response, 0); + break; + + default: + err(1, "Malformed statement at line %zu of file %s", + line, cur_file); + break; + } +} + +/* + * Validate the return against the contents of a variable. + */ +static void +validate_reference(int i, void *data) +{ + char *response; + returns_t *byte_response; + var_t *varp; + + varp = &vars[command.returns[i].return_index]; + + byte_response = data; + if (command.returns[i].return_type != ret_byte) + response = data; + + if (verbose) { + fprintf(stderr, + "%s: return type of %s, value %s \n", __func__, + returns_enum_names[varp->type], + (const char *)varp->value); + } + + switch (varp->type) { + case ret_string: + case ret_number: + validate_return(varp->value, response, 0); + break; + + case ret_byte: + validate_byte(varp->value, byte_response, 0); + break; + + default: + err(1, + "Invalid return type for reference at line %zu of file %s", + line, cur_file); + break; + } +} + +/* + * Validate the return type against the expected type, throw an error + * if they don't match. + */ +static void +validate_type(returns_enum_t expected, returns_t *value, int check) +{ + if (((check == 0) && (expected != value->return_type)) || + ((check == 1) && (expected == value->return_type))) + err(1, "Validate expected type %s %s %s line %zu of file %s", + returns_enum_names[expected], + (check == 0)? "matching" : "not matching", + returns_enum_names[value->return_type], line, cur_file); + + if (verbose) { + fprintf(stderr, "Validate expected type %s %s %s line %zu" + " of file %s\n", + returns_enum_names[expected], + (check == 0)? "matching" : "not matching", + returns_enum_names[value->return_type], line, cur_file); + } +} + +/* + * Validate the return value against the expected value, throw an error + * if they don't match. + */ +static void +validate_return(const char *expected, const char *value, int check) +{ + if (((check == 0) && strcmp(expected, value) != 0) || + ((check == 1) && strcmp(expected, value) == 0)) + errx(1, "Validate expected %s %s %s line %zu of file %s", + expected, + (check == 0)? "matching" : "not matching", value, + line, cur_file); + if (verbose) { + fprintf(stderr, "Validated expected value %s %s %s " + "at line %zu of file %s\n", expected, + (check == 0)? "matches" : "does not match", + value, line, cur_file); + } +} + +/* + * Validate the return value against the expected value, throw an error + * if they don't match expectations. + */ +static void +validate_byte(returns_t *expected, returns_t *value, int check) +{ + char *ch; + size_t i; + + if (verbose) { + ch = value->return_value; + fprintf(stderr, "checking returned byte stream: "); + for (i = 0; i < value->return_len; i++) + fprintf(stderr, "%s0x%x", (i != 0)? ", " : "", ch[i]); + fprintf(stderr, "\n"); + + fprintf(stderr, "%s byte stream: ", + (check == 0)? "matches" : "does not match"); + ch = (char *) expected->return_value; + for (i = 0; i < expected->return_len; i++) + fprintf(stderr, "%s0x%x", (i != 0)? ", " : "", ch[i]); + fprintf(stderr, "\n"); + } + + /* + * No chance of a match if lengths differ... + */ + if ((check == 0) && (expected->return_len != value->return_len)) + errx(1, "Byte validation failed, length mismatch, expected %zu," + "received %zu", expected->return_len, value->return_len); + + /* + * If check is 0 then we want to throw an error IFF the byte streams + * do not match, if check is 1 then throw an error if the byte + * streams match. + */ + if (((check == 0) && memcmp(expected->return_value, value->return_value, + value->return_len) != 0) || + ((check == 1) && (expected->return_len == value->return_len) && + memcmp(expected->return_value, value->return_value, + value->return_len) == 0)) + errx(1, "Validate expected %s byte stream at line %zu" + "of file %s", + (check == 0)? "matching" : "not matching", line, cur_file); + if (verbose) { + fprintf(stderr, "Validated expected %s byte stream " + "at line %zu of file %s\n", + (check == 0)? "matching" : "not matching", + line, cur_file); + } +} + +/* + * Validate the variable at i against the expected value, throw an + * error if they don't match, if check is non-zero then the match is + * negated. + */ +static void +validate_variable(int ret, returns_enum_t type, const void *value, int i, + int check) +{ + returns_t *retval; + var_t *varptr; + + retval = &command.returns[ret]; + varptr = &vars[command.returns[ret].return_index]; + + if (varptr->value == NULL) + err(1, "Variable %s has no value assigned to it", varptr->name); + + + if (varptr->type != type) + err(1, "Variable %s is not the expected type", varptr->name); + + if (type != ret_byte) { + if ((((check == 0) && strcmp(value, varptr->value) != 0)) + || ((check == 1) && strcmp(value, varptr->value) == 0)) + err(1, "Variable %s contains %s instead of %s" + " value %s at line %zu of file %s", + varptr->name, (const char *)varptr->value, + (check == 0)? "expected" : "not matching", + (const char *)value, + line, cur_file); + if (verbose) { + fprintf(stderr, "Variable %s contains %s value " + "%s at line %zu of file %s\n", + varptr->name, + (check == 0)? "expected" : "not matching", + (const char *)varptr->value, line, cur_file); + } + } else { + if ((check == 0) && (retval->return_len != varptr->len)) + err(1, "Byte validation failed, length mismatch"); + + /* + * If check is 0 then we want to throw an error IFF + * the byte streams do not match, if check is 1 then + * throw an error if the byte streams match. + */ + if (((check == 0) && memcmp(retval->return_value, varptr->value, + varptr->len) != 0) || + ((check == 1) && (retval->return_len == varptr->len) && + memcmp(retval->return_value, varptr->value, + varptr->len) == 0)) + err(1, "Validate expected %s byte stream at line %zu" + " of file %s", + (check == 0)? "matching" : "not matching", + line, cur_file); + if (verbose) { + fprintf(stderr, "Validated expected %s byte stream " + "at line %zu of file %s\n", + (check == 0)? "matching" : "not matching", + line, cur_file); + } + } +} + +/* + * Write a string to the command pipe - we feed the number of bytes coming + * down first to allow storage allocation and then follow up with the data. + * If cmd is NULL then feed a -1 down the pipe to say the end of the args. + */ +static void +write_cmd_pipe(char *cmd) +{ + args_t arg; + size_t len; + + if (cmd == NULL) + len = 0; + else + len = strlen(cmd); + + arg.arg_type = arg_static; + arg.arg_len = len; + arg.arg_string = cmd; + write_cmd_pipe_args(arg.arg_type, &arg); + +} + +static void +write_cmd_pipe_args(args_state_t type, void *data) +{ + var_t *var_data; + args_t *arg_data; + int len, send_type; + void *cmd; + + arg_data = data; + switch (type) { + case arg_var: + var_data = data; + len = var_data->len; + cmd = var_data->value; + if (type == arg_byte) + send_type = ret_byte; + else + send_type = ret_string; + break; + + case arg_null: + send_type = ret_null; + len = 0; + break; + + default: + if ((arg_data->arg_len == 0) && (arg_data->arg_string == NULL)) + len = -1; + else + len = arg_data->arg_len; + cmd = arg_data->arg_string; + if (type == arg_byte) + send_type = ret_byte; + else + send_type = ret_string; + } + + if (verbose) { + fprintf(stderr, "Writing type %s to command pipe\n", + returns_enum_names[send_type]); + } + + if (write(cmdpipe[WRITE_PIPE], &send_type, sizeof(int)) < 0) + err(1, "command pipe write for type failed"); + + if (verbose) { + fprintf(stderr, "Writing length %d to command pipe\n", len); + } + + if (write(cmdpipe[WRITE_PIPE], &len, sizeof(int)) < 0) + err(1, "command pipe write for length failed"); + + if (len > 0) { + if (verbose) { + fprintf(stderr, "Writing data >%s< to command pipe\n", + (const char *)cmd); + } + if (write(cmdpipe[WRITE_PIPE], cmd, len) < 0) + err(1, "command pipe write of data failed"); + } +} + +/* + * Read a response from the command pipe, first we will receive the + * length of the response then the actual data. + */ +static void +read_cmd_pipe(returns_t *response) +{ + int len, type; + struct pollfd rfd[2]; + char *str; + + /* + * Check if there is data to read - just in case slave has died, we + * don't want to block on the read and just hang. We also check + * output from the slave because the slave may be blocked waiting + * for a flush on its stdout. + */ + rfd[0].fd = slvpipe[READ_PIPE]; + rfd[0].events = POLLIN; + rfd[1].fd = master; + rfd[1].events = POLLIN; + + do { + if (poll(rfd, 2, 4000) == 0) + errx(2, "%s, %zu: Command pipe read timeout", + cur_file, line); + + if ((rfd[1].revents & POLLIN) == POLLIN) { + if (verbose) { + fprintf(stderr, + "draining output from slave\n"); + } + save_slave_output(false); + } + } + while((rfd[1].revents & POLLIN) == POLLIN); + + if (read(slvpipe[READ_PIPE], &type, sizeof(int)) < 0) + err(1, "command pipe read for type failed"); + response->return_type = type; + + if ((type != ret_ok) && (type != ret_err) && (type != ret_count)) { + if (read(slvpipe[READ_PIPE], &len, sizeof(int)) < 0) + err(1, "command pipe read for length failed"); + response->return_len = len; + + if (verbose) { + fprintf(stderr, + "Reading %d bytes from command pipe\n", len); + } + + if ((response->return_value = malloc(len + 1)) == NULL) + err(1, "Failed to alloc memory for cmd pipe read"); + + if (read(slvpipe[READ_PIPE], response->return_value, len) < 0) + err(1, "command pipe read of data failed"); + + if (response->return_type != ret_byte) { + str = response->return_value; + str[len] = '\0'; + + if (verbose) { + fprintf(stderr, "Read data >%s< from pipe\n", + (const char *)response->return_value); + } + } + } else { + response->return_value = NULL; + if (type == ret_count) { + if (read(slvpipe[READ_PIPE], &len, sizeof(int)) < 0) + err(1, "command pipe read for number of " + "returns failed"); + response->return_len = len; + } + + if (verbose) { + fprintf(stderr, "Read type %s from pipe\n", + returns_enum_names[type]); + } + } +} + +/* + * Check for writes from the slave on the pty, save the output into a + * buffer for later checking if discard is false. + */ +#define MAX_DRAIN 256 + +static void +save_slave_output(bool discard) +{ + char *new_data, drain[MAX_DRAIN]; + size_t to_allocate; + ssize_t result; + size_t i; + + result = 0; + for (;;) { + if (result == -1) + err(2, "poll of slave pty failed"); + result = MAX_DRAIN; + if ((result = read(master, drain, result)) < 0) { + if (errno == EAGAIN) + break; + else + err(2, "draining slave pty failed"); + } + if (result == 0) + abort(); + + if (!discard) { + if ((size_t)result > + (saved_output.allocated - saved_output.count)) { + to_allocate = 1024 * ((result / 1024) + 1); + + if ((new_data = realloc(saved_output.data, + saved_output.allocated + to_allocate)) + == NULL) + err(2, "Realloc of saved_output failed"); + saved_output.data = new_data; + saved_output.allocated += to_allocate; + } + + if (verbose) { + fprintf(stderr, "count = %zu, " + "allocated = %zu\n", saved_output.count, + saved_output.allocated); + for (i = 0; i < (size_t)result; i++) { + fprintf(stderr, "Saving slave output " + "at %zu: 0x%x (%c)\n", + saved_output.count + i, drain[i], + (drain[i] >= ' ')? drain[i] : '-'); + } + } + + memcpy(&saved_output.data[saved_output.count], drain, + result); + saved_output.count += result; + + if (verbose) { + fprintf(stderr, "count = %zu, " + "allocated = %zu\n", saved_output.count, + saved_output.allocated); + } + } else { + if (verbose) { + for (i = 0; i < (size_t)result; i++) { + fprintf(stderr, "Discarding slave " + "output 0x%x (%c)\n", + drain[i], + (drain[i] >= ' ')? drain[i] : '-'); + } + } + } + } +} + +static void +yyerror(const char *msg) +{ + warnx("%s in line %zu of file %s", msg, line, cur_file); +} diff --git a/contrib/netbsd-tests/lib/libcurses/slave/command_table.h b/contrib/netbsd-tests/lib/libcurses/slave/command_table.h new file mode 100644 index 0000000..ef57a00 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/slave/command_table.h @@ -0,0 +1,397 @@ +/* $NetBSD: command_table.h,v 1.3 2011/09/15 11:46:19 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * + */ + +#ifndef _COMMAND_TABLE_H_ +#define _COMMAND_TABLE_H_ + +#include "curses_commands.h" + +/* + * Curses commands + */ +struct command_def commands[] = { + {"DRAIN", cmd_DRAIN}, + {"addbytes", cmd_addbytes}, + {"addch", cmd_addch}, + {"addchnstr", cmd_addchnstr}, + {"addchstr", cmd_addchstr}, + {"addnstr", cmd_addnstr}, + {"addstr", cmd_addstr}, + {"attr_get", cmd_attr_get}, + {"attr_off", cmd_attr_off}, + {"attr_on", cmd_attr_on}, + {"attr_set", cmd_attr_set}, + {"attroff", cmd_attroff}, + {"attron", cmd_attron}, + {"attrset", cmd_attrset}, + {"bkgd", cmd_bkgd}, + {"bkgdset", cmd_bkgdset}, + {"border", cmd_border}, + {"clear", cmd_clear}, + {"clrtobot", cmd_clrtobot}, + {"clrtoeol", cmd_clrtoeol}, + {"color_set", cmd_color_set}, + {"delch", cmd_delch}, + {"deleteln", cmd_deleteln}, + {"echochar", cmd_echochar}, + {"erase", cmd_erase}, + {"getch", cmd_getch}, + {"getnstr", cmd_getnstr}, + {"getstr", cmd_getstr}, + {"inch", cmd_inch}, + {"inchnstr", cmd_inchnstr}, + {"inchstr", cmd_inchstr}, + {"innstr", cmd_innstr}, + {"insch", cmd_insch}, + {"insdelln", cmd_insdelln}, + {"insertln", cmd_insertln}, + {"instr", cmd_instr}, + {"move", cmd_move}, + {"refresh", cmd_refresh}, + {"scrl", cmd_scrl}, + {"setscrreg", cmd_setscrreg}, + {"standend", cmd_standend}, + {"standout", cmd_standout}, + {"timeout", cmd_timeout}, + {"underscore", cmd_underscore}, + {"underend", cmd_underend}, + {"waddbytes", cmd_waddbytes}, + {"waddstr", cmd_waddstr}, + {"mvaddbytes", cmd_mvaddbytes}, + {"mvaddch", cmd_mvaddch}, + {"mvaddchnstr", cmd_mvaddchnstr}, + {"mvaddchstr", cmd_mvaddchstr}, + {"mvaddnstr", cmd_mvaddnstr}, + {"mvaddstr", cmd_mvaddstr}, + {"mvdelch", cmd_mvdelch}, + {"mvgetch", cmd_mvgetch}, + {"mvgetnstr", cmd_mvgetnstr}, + {"mvgetstr", cmd_mvgetstr}, + {"mvinch", cmd_mvinch}, + {"mvinchnstr", cmd_mvinchnstr}, + {"mvinchstr", cmd_mvinchstr}, + {"mvinnstr", cmd_mvinnstr}, + {"mvinsch", cmd_mvinsch}, + {"mvinstr", cmd_mvinstr}, + {"mvwaddbytes", cmd_mvwaddbytes}, + {"mvwaddch", cmd_mvwaddch}, + {"mvwaddchnstr", cmd_mvwaddchnstr}, + {"mvwaddchstr", cmd_mvwaddchstr}, + {"mvwaddnstr", cmd_mvwaddnstr}, + {"mvwaddstr", cmd_mvwaddstr}, + {"mvwdelch", cmd_mvwdelch}, + {"mvwgetch", cmd_mvwgetch}, + {"mvwgetnstr", cmd_mvwgetnstr}, + {"mvwgetstr", cmd_mvwgetstr}, + {"mvwinch", cmd_mvwinch}, + {"mvwinsch", cmd_mvwinsch}, + {"assume_default_colors", cmd_assume_default_colors}, + {"baudrate", cmd_baudrate}, + {"beep", cmd_beep}, + {"box", cmd_box}, + {"can_change_color", cmd_can_change_color}, + {"cbreak", cmd_cbreak}, + {"clearok", cmd_clearok}, + {"color_content", cmd_color_content}, + {"copywin", cmd_copywin}, + {"curs_set", cmd_curs_set}, + {"def_prog_mode", cmd_def_prog_mode}, + {"def_shell_mode", cmd_def_shell_mode}, + {"define_key", cmd_define_key}, + {"delay_output", cmd_delay_output}, + {"delscreen", cmd_delscreen}, + {"delwin", cmd_delwin}, + {"derwin", cmd_derwin}, + {"dupwin", cmd_dupwin}, + {"doupdate", cmd_doupdate}, + {"echo", cmd_echo}, + {"endwin", cmd_endwin}, + {"erasechar", cmd_erasechar}, + {"flash", cmd_flash}, + {"flushinp", cmd_flushinp}, + {"flushok", cmd_flushok}, + {"fullname", cmd_fullname}, + {"getattrs", cmd_getattrs}, + {"getbkgd", cmd_getbkgd}, + {"getcury", cmd_getcury}, + {"getcurx", cmd_getcurx}, + {"getyx", cmd_getyx}, + {"getbegy", cmd_getbegy}, + {"getbegx", cmd_getbegx}, + {"getmaxy", cmd_getmaxy}, + {"getmaxx", cmd_getmaxx}, + {"getpary", cmd_getpary}, + {"getparx", cmd_getparx}, + {"getparyx", cmd_getparyx}, + {"gettmode", cmd_gettmode}, + {"getwin", cmd_getwin}, + {"halfdelay", cmd_halfdelay}, + {"has_colors", cmd_has_colors}, + {"has_ic", cmd_has_ic}, + {"has_il", cmd_has_il}, + {"hline", cmd_hline}, + {"idcok", cmd_idcok}, + {"idlok", cmd_idlok}, + {"init_color", cmd_init_color}, + {"init_pair", cmd_init_pair}, + {"initscr", cmd_initscr}, + {"intrflush", cmd_intrflush}, + {"isendwin", cmd_isendwin}, + {"is_linetouched", cmd_is_linetouched}, + {"is_wintouched", cmd_is_wintouched}, + {"keyok", cmd_keyok}, + {"keypad", cmd_keypad}, + {"keyname", cmd_keyname}, + {"killchar", cmd_killchar}, + {"leaveok", cmd_leaveok}, + {"meta", cmd_meta}, + {"mvcur", cmd_mvcur}, + {"mvderwin", cmd_mvderwin}, + {"mvhline", cmd_mvhline}, + {"mvprintw", cmd_mvprintw}, + {"mvscanw", cmd_mvscanw}, + {"mvvline", cmd_mvvline}, + {"mvwhline", cmd_mvwhline}, + {"mvwvline", cmd_mvwvline}, + {"mvwin", cmd_mvwin}, + {"mvwinchnstr", cmd_mvwinchnstr}, + {"mvwinchstr", cmd_mvwinchstr}, + {"mvwinnstr", cmd_mvwinnstr}, + {"mvwinstr", cmd_mvwinstr}, + {"mvwprintw", cmd_mvwprintw}, + {"mvwscanw", cmd_mvwscanw}, + {"napms", cmd_napms}, + {"newpad", cmd_newpad}, + {"newterm", cmd_newterm}, + {"newwin", cmd_newwin}, + {"nl", cmd_nl}, + {"no_color_attributes", cmd_no_color_attributes}, + {"nocbreak", cmd_nocbreak}, + {"nodelay", cmd_nodelay}, + {"noecho", cmd_noecho}, + {"nonl", cmd_nonl}, + {"noqiflush", cmd_noqiflush}, + {"noraw", cmd_noraw}, + {"notimeout", cmd_notimeout}, + {"overlay", cmd_overlay}, + {"overwrite", cmd_overwrite}, + {"pair_content", cmd_pair_content}, + {"pechochar", cmd_pechochar}, + {"pnoutrefresh", cmd_pnoutrefresh}, + {"prefresh", cmd_prefresh}, + {"printw", cmd_printw}, + {"putwin", cmd_putwin}, + {"qiflush", cmd_qiflush}, + {"raw", cmd_raw}, + {"redrawwin", cmd_redrawwin}, + {"reset_prog_mode", cmd_reset_prog_mode}, + {"reset_shell_mode", cmd_reset_shell_mode}, + {"resetty", cmd_resetty}, + {"resizeterm", cmd_resizeterm}, + {"savetty", cmd_savetty}, + {"scanw", cmd_scanw}, + {"scroll", cmd_scroll}, + {"scrollok", cmd_scrollok}, + {"setterm", cmd_setterm}, + {"set_term", cmd_set_term}, + {"start_color", cmd_start_color}, + {"subpad", cmd_subpad}, + {"subwin", cmd_subwin}, + {"termattrs", cmd_termattrs}, + {"term_attrs", cmd_term_attrs}, + {"touchline", cmd_touchline}, + {"touchoverlap", cmd_touchoverlap}, + {"touchwin", cmd_touchwin}, + {"ungetch", cmd_ungetch}, + {"untouchwin", cmd_untouchwin}, + {"use_default_colors", cmd_use_default_colors}, + {"vline", cmd_vline}, + {"vw_printw", cmd_vw_printw}, + {"vw_scanw", cmd_vw_scanw}, + {"vwprintw", cmd_vwprintw}, + {"vwscanw", cmd_vwscanw}, + {"waddch", cmd_waddch}, + {"waddchnstr", cmd_waddchnstr}, + {"waddchstr", cmd_waddchstr}, + {"waddnstr", cmd_waddnstr}, + {"wattr_get", cmd_wattr_get}, + {"wattr_off", cmd_wattr_off}, + {"wattr_on", cmd_wattr_on}, + {"wattr_set", cmd_wattr_set}, + {"wattroff", cmd_wattroff}, + {"wattron", cmd_wattron}, + {"wattrset", cmd_wattrset}, + {"wbkgd", cmd_wbkgd}, + {"wbkgdset", cmd_wbkgdset}, + {"wborder", cmd_wborder}, + {"wclear", cmd_wclear}, + {"wclrtobot", cmd_wclrtobot}, + {"wclrtoeol", cmd_wclrtoeol}, + {"wcolor_set", cmd_wcolor_set}, + {"wdelch", cmd_wdelch}, + {"wdeleteln", cmd_wdeleteln}, + {"wechochar", cmd_wechochar}, + {"werase", cmd_werase}, + {"wgetch", cmd_wgetch}, + {"wgetnstr", cmd_wgetnstr}, + {"wgetstr", cmd_wgetstr}, + {"whline", cmd_whline}, + {"winch", cmd_winch}, + {"winchnstr", cmd_winchnstr}, + {"winchstr", cmd_winchstr}, + {"winnstr", cmd_winnstr}, + {"winsch", cmd_winsch}, + {"winsdelln", cmd_winsdelln}, + {"winsertln", cmd_winsertln}, + {"winstr", cmd_winstr}, + {"wmove", cmd_wmove}, + {"wnoutrefresh", cmd_wnoutrefresh}, + {"wprintw", cmd_wprintw}, + {"wredrawln", cmd_wredrawln}, + {"wrefresh", cmd_wrefresh}, + {"wresize", cmd_wresize}, + {"wscanw", cmd_wscanw}, + {"wscrl", cmd_wscrl}, + {"wsetscrreg", cmd_wsetscrreg}, + {"wstandend", cmd_wstandend}, + {"wstandout", cmd_wstandout}, + {"wtimeout", cmd_wtimeout}, + {"wtouchln", cmd_wtouchln}, + {"wunderend", cmd_wunderend}, + {"wunderscore", cmd_wunderscore}, + {"wvline", cmd_wvline}, + {"insnstr", cmd_insnstr}, + {"insstr", cmd_insstr}, + {"mvinsnstr", cmd_mvinsnstr}, + {"mvinsstr", cmd_mvinsstr}, + {"mvwinsnstr", cmd_mvwinsnstr}, + {"mvwinsstr", cmd_mvwinsstr}, + {"winsnstr", cmd_winsnstr}, + {"winsstr", cmd_winsstr}, + {"chgat", cmd_chgat}, + {"wchgat", cmd_wchgat}, + {"mvchgat", cmd_mvchgat}, + {"mvwchgat", cmd_mvwchgat}, + {"add_wch", cmd_add_wch}, + {"wadd_wch", cmd_wadd_wch}, + {"mvadd_wch", cmd_mvadd_wch}, + {"mvwadd_wch", cmd_mvwadd_wch}, + {"add_wchnstr", cmd_add_wchnstr}, + {"add_wchstr", cmd_add_wchstr}, + {"wadd_wchnstr", cmd_wadd_wchnstr}, + {"wadd_wchstr", cmd_wadd_wchstr}, + {"mvadd_wchnstr", cmd_mvadd_wchnstr}, + {"mvadd_wchstr", cmd_mvadd_wchstr}, + {"mvwadd_wchnstr", cmd_mvwadd_wchnstr}, + {"mvwadd_wchstr", cmd_mvwadd_wchstr}, + {"addnwstr", cmd_addnwstr}, + {"addwstr", cmd_addwstr}, + {"mvaddnwstr", cmd_mvaddnwstr}, + {"mvaddwstr", cmd_mvaddwstr}, + {"mvwaddnwstr", cmd_mvwaddnwstr}, + {"mvwaddwstr", cmd_mvwaddwstr}, + {"waddnwstr", cmd_waddnwstr}, + {"waddwstr", cmd_waddwstr}, + {"echo_wchar", cmd_echo_wchar}, + {"wecho_wchar", cmd_wecho_wchar}, + {"pecho_wchar", cmd_pecho_wchar}, + {"ins_wch", cmd_ins_wch}, + {"wins_wch", cmd_wins_wch}, + {"mvins_wch", cmd_mvins_wch}, + {"mvwins_wch", cmd_mvwins_wch}, + {"ins_nwstr", cmd_ins_nwstr}, + {"ins_wstr", cmd_ins_wstr}, + {"mvins_nwstr", cmd_mvins_nwstr}, + {"mvins_wstr", cmd_mvins_wstr}, + {"mvwins_nwstr", cmd_mvwins_nwstr}, + {"mvwins_wstr", cmd_mvwins_wstr}, + {"wins_nwstr", cmd_wins_nwstr}, + {"wins_wstr", cmd_wins_wstr}, + {"get_wch", cmd_get_wch}, + {"unget_wch", cmd_unget_wch}, + {"mvget_wch", cmd_mvget_wch}, + {"mvwget_wch", cmd_mvwget_wch}, + {"wget_wch", cmd_wget_wch}, + {"getn_wstr", cmd_getn_wstr}, + {"get_wstr", cmd_get_wstr}, + {"mvgetn_wstr", cmd_mvgetn_wstr}, + {"mvget_wstr", cmd_mvget_wstr}, + {"mvwgetn_wstr", cmd_mvwgetn_wstr}, + {"mvwget_wstr", cmd_mvwget_wstr}, + {"wgetn_wstr", cmd_wgetn_wstr}, + {"wget_wstr", cmd_wget_wstr}, + {"in_wch", cmd_in_wch}, + {"mvin_wch", cmd_mvin_wch}, + {"mvwin_wch", cmd_mvwin_wch}, + {"win_wch", cmd_win_wch}, + {"in_wchnstr", cmd_in_wchnstr}, + {"in_wchstr", cmd_in_wchstr}, + {"mvin_wchnstr", cmd_mvin_wchnstr}, + {"mvin_wchstr", cmd_mvin_wchstr}, + {"mvwin_wchnstr", cmd_mvwin_wchnstr}, + {"mvwin_wchstr", cmd_mvwin_wchstr}, + {"win_wchnstr", cmd_win_wchnstr}, + {"win_wchstr", cmd_win_wchstr}, + {"innwstr", cmd_innwstr}, + {"inwstr", cmd_inwstr}, + {"mvinnwstr", cmd_mvinnwstr}, + {"mvinwstr", cmd_mvinwstr}, + {"mvwinnwstr", cmd_mvwinnwstr}, + {"mvwinwstr", cmd_mvwinwstr}, + {"winnwstr", cmd_winnwstr}, + {"winwstr", cmd_winwstr}, + {"setcchar", cmd_setcchar}, + {"getcchar", cmd_getcchar}, + {"key_name", cmd_key_name}, + {"border_set", cmd_border_set}, + {"wborder_set", cmd_wborder_set}, + {"box_set", cmd_box_set}, + {"erasewchar", cmd_erasewchar}, + {"killwchar", cmd_killwchar}, + {"hline_set", cmd_hline_set}, + {"mvhline_set", cmd_mvhline_set}, + {"mvvline_set", cmd_mvvline_set}, + {"mvwhline_set", cmd_mvwhline_set}, + {"mvwvline_set", cmd_mvwvline_set}, + {"vline_set", cmd_vline_set}, + {"whline_set", cmd_whline_set}, + {"wvline_set", cmd_wvline_set}, + {"bkgrnd", cmd_bkgrnd}, + {"bkgrndset", cmd_bkgrndset}, + {"getbkgrnd", cmd_getbkgrnd}, + {"wbkgrnd", cmd_wbkgrnd}, + {"wbkgrndset", cmd_wbkgrndset}, + {"wgetbkgrnd", cmd_wgetbkgrnd}, +}; + +size_t ncmds = sizeof(commands) / sizeof(struct command_def); + +#endif /* _COMMAND_TABLE_H */ diff --git a/contrib/netbsd-tests/lib/libcurses/slave/commands.c b/contrib/netbsd-tests/lib/libcurses/slave/commands.c new file mode 100644 index 0000000..2f26024 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/slave/commands.c @@ -0,0 +1,243 @@ +/* $NetBSD: commands.c,v 1.4 2011/09/15 11:46:19 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include +#include +#include +#include +#include +#include +#include "returns.h" +#include "slave.h" +#include "command_table.h" + +extern int cmdpipe[2]; +extern int slvpipe[2]; + +static void report_type(returns_enum_t); +static void report_message(int, const char *); + +/* + * Match the passed command string and execute the associated test + * function. + */ +void +command_execute(char *func, int nargs, char **args) +{ + size_t i; + + i = 0; + while (i < ncmds) { + if (strcasecmp(func, commands[i].name) == 0) { + /* matched function */ + commands[i].func(nargs, args); + return; + } + i++; + } + + report_status("UNKNOWN_FUNCTION"); +} + +/* + * Report an pointer value back to the director + */ +void +report_ptr(void *ptr) +{ + char *string; + + if (ptr == NULL) + asprintf(&string, "NULL"); + else + asprintf(&string, "%p", ptr); + report_status(string); + free(string); +} + +/* + * Report an integer value back to the director + */ +void +report_int(int value) +{ + char *string; + + asprintf(&string, "%d", value); + report_status(string); + free(string); +} + +/* + * Report either an ERR or OK back to the director + */ +void +report_return(int status) +{ + if (status == ERR) + report_type(ret_err); + else if (status == OK) + report_type(ret_ok); + else + report_status("INVALID_RETURN"); +} + +/* + * Report the type back to the director via the command pipe + */ +static void +report_type(returns_enum_t return_type) +{ + int type; + + type = return_type; + if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) + err(1, "command pipe write for status type failed"); + +} + +/* + * Report the number of returns back to the director via the command pipe + */ +void +report_count(int count) +{ + int type; + + type = ret_count; + if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) + err(1, "command pipe write for count type failed"); + + if (write(slvpipe[WRITE_PIPE], &count, sizeof(int)) < 0) + err(1, "command pipe write for count"); +} + +/* + * Report the status back to the director via the command pipe + */ +void +report_status(const char *status) +{ + report_message(ret_string, status); +} + +/* + * Report an error message back to the director via the command pipe. + */ +void +report_error(const char *status) +{ + report_message(ret_slave_error, status); +} + +/* + * Report the message with the given type back to the director via the + * command pipe. + */ +static void +report_message(int type, const char *status) +{ + int len; + + len = strlen(status); + + if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) + err(1, "command pipe write for message type failed"); + + if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0) + err(1, "command pipe write for message length failed"); + + if (write(slvpipe[WRITE_PIPE], status, len) < 0) + err(1, "command pipe write of message data failed"); +} + +/* + * Report a string of chtype back to the director via the command pipe. + */ +void +report_byte(chtype c) +{ + chtype string[2]; + + string[0] = c; + string[1] = A_NORMAL | '\0'; + report_nstr(string); +} + +/* + * Report a string of chtype back to the director via the command pipe. + */ +void +report_nstr(chtype *string) +{ + int len, type; + chtype *p; + + len = 0; + p = string; + + while ((*p++ & __CHARTEXT) != 0) { + len++; + } + + len++; /* add in the termination chtype */ + len *= sizeof(chtype); + + type = ret_byte; + if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) + err(1, "%s: command pipe write for status type failed", + __func__); + + if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0) + err(1, "%s: command pipe write for status length failed", + __func__); + + if (write(slvpipe[WRITE_PIPE], string, len) < 0) + err(1, "%s: command pipe write of status data failed", + __func__); +} + +/* + * Check the number of args we received are what we expect. Return an + * error if they do not match. + */ +int +check_arg_count(int nargs, int expected) +{ + if (nargs != expected) { + report_count(1); + report_error("INCORRECT_ARGUMENT_NUMBER"); + return(1); + } + + return(0); +} diff --git a/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.c b/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.c new file mode 100644 index 0000000..9a6679a --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.c @@ -0,0 +1,7165 @@ +/* $NetBSD: curses_commands.c,v 1.7 2012/09/19 11:51:08 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include +#include +#include +#include +#include + +#include "slave.h" +#include "curses_commands.h" + +void +cmd_DRAIN(int nargs, char **args) +{ + while (getch() != ERR); + report_count(1); + report_return(OK); +} + +void +cmd_addbytes(int nargs, char **args) +{ + int count; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(addbytes(args[0], count)); +} + + +void +cmd_addch(int nargs, char **args) +{ + chtype *ch; + + if (check_arg_count(nargs, 1) == 1) + return; + + ch = (chtype *) args[0]; + report_count(1); + report_return(addch(ch[0])); +} + + +void +cmd_addchnstr(int nargs, char **args) +{ + int count; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(addchnstr((chtype *) args[0], count)); +} + + +void +cmd_addchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_return(addchstr((chtype *) args[0])); +} + + +void +cmd_addnstr(int nargs, char **args) +{ + int count; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(addnstr(args[0], count)); +} + + +void +cmd_addstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_return(addstr(args[0])); +} + + +void +cmd_attr_get(int nargs, char **args) +{ + attr_t attrs; + short colours; + int retval; + + if (check_arg_count(nargs, 0) == 1) + return; + + retval = attr_get(&attrs, &colours, NULL); + + /* XXXX - call3 */ + report_count(3); + report_return(retval); + report_int(attrs); + report_int(colours); +} + + +void +cmd_attr_off(int nargs, char **args) +{ + int attrib; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &attrib) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(attr_off(attrib, NULL)); +} + + +void +cmd_attr_on(int nargs, char **args) +{ + int attrib; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &attrib) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(attr_on(attrib, NULL)); +} + + +void +cmd_attr_set(int nargs, char **args) +{ + int attrib; + short pair; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &attrib) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%hd", &pair) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(attr_set(attrib, pair, NULL)); +} + + +void +cmd_attroff(int nargs, char **args) +{ + int attrib; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &attrib) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(attroff(attrib)); +} + + +void +cmd_attron(int nargs, char **args) +{ + int attrib; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &attrib) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(attron(attrib)); +} + + +void +cmd_attrset(int nargs, char **args) +{ + int attrib; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &attrib) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(attrset(attrib)); +} + + +void +cmd_bkgd(int nargs, char **args) +{ + chtype *ch; + + if (check_arg_count(nargs, 1) == 1) + return; + + ch = (chtype *) args[0]; + report_count(1); + report_return(bkgd(ch[0])); +} + + +void +cmd_bkgdset(int nargs, char **args) +{ + chtype *ch; + + if (check_arg_count(nargs, 1) == 1) + return; + + ch = (chtype *) args[0]; + bkgdset(ch[0]); /* returns void */ + report_count(1); + report_return(OK); +} + + +void +cmd_border(int nargs, char **args) +{ + int ls, rs, ts, bs, tl, tr, bl, br; + + if (check_arg_count(nargs, 8) == 1) + return; + + if (sscanf(args[0], "%d", &ls) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[1], "%d", &rs) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[2], "%d", &ts) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[3], "%d", &bs) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[4], "%d", &tl) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[5], "%d", &tr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[6], "%d", &bl) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + if (sscanf(args[7], "%d", &br) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(border(ls, rs, ts, bs, tl, tr, bl, br)); +} + + +void +cmd_clear(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(clear()); +} + + +void +cmd_clrtobot(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(clrtobot()); +} + + +void +cmd_clrtoeol(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(clrtoeol()); +} + + +void +cmd_color_set(int nargs, char **args) +{ + short colour_pair; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%hd", &colour_pair) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(color_set(colour_pair, NULL)); +} + + +void +cmd_delch(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(delch()); +} + + +void +cmd_deleteln(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(deleteln()); +} + + +void +cmd_echochar(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + /* XXX causes refresh */ + report_count(1); + report_return(echochar(args[0][0])); +} + + +void +cmd_erase(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(erase()); +} + + +void +cmd_getch(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX causes refresh */ + report_count(1); + report_int(getch()); +} + + +void +cmd_getnstr(int nargs, char **args) +{ + int limit; + char *string; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &limit) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc(limit + 1)) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(getnstr(string, limit)); + report_status(string); + free(string); +} + + +void +cmd_getstr(int nargs, char **args) +{ + char string[256]; + + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX call2 */ + report_count(2); + report_return(getstr(string)); + report_status(string); +} + + +void +cmd_inch(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + + report_count(1); + report_byte(inch()); +} + + +void +cmd_inchnstr(int nargs, char **args) +{ + int limit; + chtype *string; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &limit) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc((limit + 1) * sizeof(chtype))) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(inchnstr(string, limit)); + report_nstr(string); + free(string); +} + + +void +cmd_inchstr(int nargs, char **args) +{ + chtype string[256]; + + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX call2 */ + report_count(2); + report_return(inchstr(string)); + report_nstr(string); +} + + +void +cmd_innstr(int nargs, char **args) +{ + int limit; + char *string; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &limit) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc(limit + 1)) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_int(innstr(string, limit)); + report_status(string); + free(string); +} + + +void +cmd_insch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_return(insch(args[0][0])); +} + + +void +cmd_insdelln(int nargs, char **args) +{ + int nlines; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &nlines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(insdelln(nlines)); +} + + +void +cmd_insertln(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(insertln()); +} + + +void +cmd_instr(int nargs, char **args) +{ + char string[256]; + + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX call2 */ + report_count(2); + report_return(instr(string)); + report_status(string); +} + + +void +cmd_move(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(move(y, x)); +} + + +void +cmd_refresh(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(refresh()); +} + + +void +cmd_scrl(int nargs, char **args) +{ + int nlines; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &nlines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(scrl(nlines)); +} + + +void +cmd_setscrreg(int nargs, char **args) +{ + int top, bottom; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &top) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &bottom) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(setscrreg(top, bottom)); +} + + +void +cmd_standend(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(standend()); +} + + +void +cmd_standout(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(standout()); +} + + +void +cmd_timeout(int nargs, char **args) +{ + int tval; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &tval) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + timeout(tval); /* void return */ + report_count(1); + report_return(OK); +} + + +void +cmd_underscore(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(underscore()); +} + + +void +cmd_underend(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(underend()); +} + + +void +cmd_waddbytes(int nargs, char **args) +{ + WINDOW *win; + int count; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(waddbytes(win, args[1], count)); +} + + +void +cmd_waddstr(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(waddstr(win, args[1])); +} + + +void +cmd_mvaddbytes(int nargs, char **args) +{ + int y, x, count; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvaddbytes(y, x, args[2], count)); +} + + +void +cmd_mvaddch(int nargs, char **args) +{ + int y, x; + chtype *ch; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[2]; + report_count(1); + report_return(mvaddch(y, x, ch[0])); +} + + +void +cmd_mvaddchnstr(int nargs, char **args) +{ + int y, x, count; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvaddchnstr(y, x, (chtype *) args[2], count)); +} + + +void +cmd_mvaddchstr(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvaddchstr(y, x, (chtype *) args[2])); +} + + +void +cmd_mvaddnstr(int nargs, char **args) +{ + int y, x, count; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvaddnstr(y, x, args[2], count)); +} + + +void +cmd_mvaddstr(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvaddstr(y, x, args[2])); +} + + +void +cmd_mvdelch(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvdelch(y, x)); +} + + +void +cmd_mvgetch(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(mvgetch(y, x)); +} + + +void +cmd_mvgetnstr(int nargs, char **args) +{ + int y, x, count; + char *string; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc(count + 1)) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvgetnstr(y, x, string, count)); + report_status(string); + free(string); +} + + +void +cmd_mvgetstr(int nargs, char **args) +{ + int y, x; + char string[256]; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvgetstr(y, x, string)); + report_status(string); +} + + +void +cmd_mvinch(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(mvinch(y, x)); +} + + +void +cmd_mvinchnstr(int nargs, char **args) +{ + int y, x, count; + chtype *string; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc((count + 1) * sizeof(chtype))) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvinchnstr(y, x, string, count)); + report_nstr(string); + free(string); +} + + +void +cmd_mvinchstr(int nargs, char **args) +{ + int y, x; + chtype string[256]; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvinchstr(y, x, string)); + report_nstr(string); +} + + +void +cmd_mvinnstr(int nargs, char **args) +{ + int y, x, count; + char *string; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc(count + 1)) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvinnstr(y, x, string, count)); + report_status(string); + free(string); +} + + +void +cmd_mvinsch(int nargs, char **args) +{ + int y, x, ch; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvinsch(y, x, ch)); +} + + +void +cmd_mvinstr(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvinstr(y, x, args[2])); +} + + + +void +cmd_mvwaddbytes(int nargs, char **args) +{ + int y, x, count; + WINDOW *win; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwaddbytes(win, y, x, args[3], count)); +} + + +void +cmd_mvwaddch(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwaddch(win, y, x, args[3][0])); +} + + +void +cmd_mvwaddchnstr(int nargs, char **args) +{ + int y, x, count; + WINDOW *win; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwaddchnstr(win, y, x, (chtype *) args[3], count)); +} + + +void +cmd_mvwaddchstr(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwaddchstr(win, y, x, (chtype *) args[3])); +} + + +void +cmd_mvwaddnstr(int nargs, char **args) +{ + int y, x, count; + WINDOW *win; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwaddnstr(win, y, x, args[3], count)); +} + + +void +cmd_mvwaddstr(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwaddstr(win, y, x, args[3])); +} + + +void +cmd_mvwdelch(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwdelch(win, y, x)); +} + + +void +cmd_mvwgetch(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - implicit refresh */ + report_count(1); + report_int(mvwgetch(win, y, x)); +} + + +void +cmd_mvwgetnstr(int nargs, char **args) +{ + int y, x, count; + char *string; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc(count + 1)) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvwgetnstr(win, y, x, string, count)); + report_status(string); + free(string); +} + + +void +cmd_mvwgetstr(int nargs, char **args) +{ + int y, x; + WINDOW *win; + char string[256]; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(mvwgetstr(win, y, x, string)); + report_status(string); +} + + +void +cmd_mvwinch(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(mvwinch(win, y, x)); +} + + +void +cmd_mvwinsch(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(mvwinsch(win, y, x, args[3][0])); +} + + +void +cmd_assume_default_colors(int nargs, char **args) +{ + short fore, back; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%hd", &fore) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%hd", &back) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(assume_default_colors(fore, back)); +} + + +void +cmd_baudrate(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(baudrate()); +} + + +void +cmd_beep(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(beep()); +} + + +void +cmd_box(int nargs, char **args) +{ + WINDOW *win; + chtype *vertical, *horizontal; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + vertical = (chtype *) args[1]; + horizontal = (chtype *) args[2]; + report_count(1); + report_return(box(win, vertical[0], horizontal[0])); +} + + +void +cmd_can_change_color(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(can_change_color()); +} + + +void +cmd_cbreak(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(cbreak()); +} + + +void +cmd_clearok(int nargs, char **args) +{ + WINDOW *win; + int flag; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(clearok(win, flag)); +} + + +void +cmd_color_content(int nargs, char **args) +{ + short colour, red, green, blue; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%hd", &colour) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call4 */ + report_count(4); + report_return(color_content(colour, &red, &green, &blue)); + report_int(red); + report_int(green); + report_int(blue); +} + + +void +cmd_copywin(int nargs, char **args) +{ + int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, ovlay; + WINDOW *source, *destination; + + if (check_arg_count(nargs, 9) == 1) + return; + + if (sscanf(args[0], "%p", &source) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%p", &destination) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &sminrow) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &smincol) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &dminrow) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[5], "%d", &dmincol) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[6], "%d", &dmaxrow) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[7], "%d", &dmaxcol) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[8], "%d", &ovlay) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(copywin(source, destination, sminrow, smincol, dminrow, + dmincol, dmaxrow, dmaxcol, ovlay)); +} + + +void +cmd_curs_set(int nargs, char **args) +{ + int vis; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &vis) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(curs_set(vis)); +} + + +void +cmd_def_prog_mode(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(def_prog_mode()); +} + + +void +cmd_def_shell_mode(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(def_shell_mode()); +} + + +void +cmd_define_key(int nargs, char **args) +{ + int symbol; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[1], "%d", &symbol) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(define_key(args[0], symbol)); +} + + +void +cmd_delay_output(int nargs, char **args) +{ + int dtime; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &dtime) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(delay_output(dtime)); +} + + +void +cmd_delscreen(int nargs, char **args) +{ + SCREEN *scrn; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &scrn) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + delscreen(scrn); /* void return */ + report_count(1); + report_return(OK); +} + + +void +cmd_delwin(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(delwin(win)); +} + + +void +cmd_derwin(int nargs, char **args) +{ + int lines, cols, y, x; + WINDOW *win; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &lines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &cols) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(derwin(win, lines, cols, y, x)); +} + + +void +cmd_dupwin(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(dupwin(win)); +} + + +void +cmd_doupdate(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX - implicit refresh */ + report_count(1); + report_return(doupdate()); +} + + +void +cmd_echo(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(echo()); +} + + +void +cmd_endwin(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(endwin()); +} + + +void +cmd_erasechar(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(erasechar()); +} + + +void +cmd_flash(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(flash()); +} + + +void +cmd_flushinp(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(flushinp()); +} + + +void +cmd_flushok(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(flushok(win, flag)); +} + + +void +cmd_fullname(int nargs, char **args) +{ + char string[256]; + + if (check_arg_count(nargs, 1) == 1) + return; + + /* XXX - call2 */ + report_count(2); + report_status(fullname(args[0], string)); + report_status(string); +} + + +void +cmd_getattrs(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getattrs(win)); +} + + +void +cmd_getbkgd(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_byte(getbkgd(win)); +} + + +void +cmd_getcury(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getcury(win)); +} + + +void +cmd_getcurx(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getcurx(win)); +} + + +void +cmd_getyx(int nargs, char **args) +{ + WINDOW *win; + int y, x; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + getyx(win, y, x); + report_count(2); + report_int(y); + report_int(x); +} + + +void +cmd_getbegy(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getbegy(win)); +} + + +void +cmd_getbegx(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getbegx(win)); +} + + +void +cmd_getmaxy(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getmaxy(win)); +} + + +void +cmd_getmaxx(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getmaxx(win)); +} + + +void +cmd_getpary(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getpary(win)); +} + + +void +cmd_getparx(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(getparx(win)); +} + + +void +cmd_getparyx(int nargs, char **args) +{ + WINDOW *win; + int y, x; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(2); + getparyx(win, y, x); + report_int(y); + report_int(x); +} + + +void +cmd_gettmode(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(gettmode()); +} + + +void +cmd_getwin(int nargs, char **args) +{ + FILE *fp; + + if (check_arg_count(nargs, 1) == 1) + return; + + if ((fp = fopen(args[0], "r")) == NULL) { + report_count(1); + report_error("BAD FILE_ARGUMENT"); + return; + } + + report_count(1); + report_ptr(getwin(fp)); + fclose(fp); +} + + +void +cmd_halfdelay(int nargs, char **args) +{ + int ms; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &ms) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(halfdelay(ms)); +} + + +void +cmd_has_colors(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(has_colors()); +} + + +void +cmd_has_ic(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(has_ic()); +} + + +void +cmd_has_il(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(has_il()); +} + + +void +cmd_hline(int nargs, char **args) +{ + int count; + chtype *ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + ch = (chtype *) args[0]; + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(hline(ch[0], count)); +} + + +void +cmd_idcok(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(idcok(win, flag)); +} + + +void +cmd_idlok(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(idlok(win, flag)); +} + + +void +cmd_init_color(int nargs, char **args) +{ + short colour, red, green, blue; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%hd", &colour) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%hd", &red) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%hd", &green) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%hd", &blue) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(init_color(colour, red, green, blue)); +} + + +void +cmd_init_pair(int nargs, char **args) +{ + short pair, fore, back; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%hd", &pair) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%hd", &fore) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%hd", &back) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(init_pair(pair, fore, back)); +} + + +void +cmd_initscr(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_ptr(initscr()); +} + + +void +cmd_intrflush(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(intrflush(win, flag)); +} + + +void +cmd_isendwin(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(isendwin()); +} + + +void +cmd_is_linetouched(int nargs, char **args) +{ + int line; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &line) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(is_linetouched(win, line)); +} + + +void +cmd_is_wintouched(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(is_wintouched(win)); +} + + +void +cmd_keyok(int nargs, char **args) +{ + int keysym, flag; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &keysym) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(keyok(keysym, flag)); +} + + +void +cmd_keypad(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(keypad(win, flag)); +} + + +void +cmd_keyname(int nargs, char **args) +{ + unsigned int key; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &key) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_status(keyname(key)); +} + + +void +cmd_killchar(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(killchar()); +} + + +void +cmd_leaveok(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(leaveok(win, flag)); +} + + +void +cmd_meta(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(meta(win, flag)); +} + + +void +cmd_mvcur(int nargs, char **args) +{ + int oldy, oldx, y, x; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &oldy) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &oldx) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvcur(oldy, oldx, y, x)); +} + + +void +cmd_mvderwin(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvderwin(win, y, x)); +} + + +void +cmd_mvhline(int nargs, char **args) +{ + int y, x, n; + chtype *ch; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[2]; + + if (sscanf(args[3], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvhline(y, x, ch[0], n)); +} + + +void +cmd_mvprintw(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvprintw(y, x, args[2], args[3])); +} + + +void +cmd_mvscanw(int nargs, char **args) +{ + int y, x; + char string[256]; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(mvscanw(y, x, args[2], &string)); + report_status(string); +} + + +void +cmd_mvvline(int nargs, char **args) +{ + int y, x, n; + chtype *ch; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[2]; + + if (sscanf(args[3], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvvline(y, x, ch[0], n)); +} + + +void +cmd_mvwhline(int nargs, char **args) +{ + int y, x, ch, n; + WINDOW *win; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwhline(win, y, x, ch, n)); +} + + +void +cmd_mvwvline(int nargs, char **args) +{ + int y, x, n; + WINDOW *win; + chtype *ch; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[3]; + + if (sscanf(args[4], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwvline(win, y, x, ch[0], n)); +} + + +void +cmd_mvwin(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwin(win, y, x)); +} + + +void +cmd_mvwinchnstr(int nargs, char **args) +{ + int y, x, count; + chtype *string; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc((count + 1) * sizeof(chtype))) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvwinchnstr(win, y, x, string, count)); + report_nstr(string); + free(string); +} + + +void +cmd_mvwinchstr(int nargs, char **args) +{ + int y, x; + chtype string[256]; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvwinchstr(win, y, x, string)); + report_nstr(string); +} + + +void +cmd_mvwinnstr(int nargs, char **args) +{ + int y, x, count; + char *string; + WINDOW *win; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((string = malloc(count + 1)) == NULL) { + report_count(1); + report_error("MALLOC_FAILED"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvwinnstr(win, y, x, string, count)); + report_status(string); + free(string); +} + + +void +cmd_mvwinstr(int nargs, char **args) +{ + int y, x; + char string[256]; + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX call2 */ + report_count(2); + report_return(mvwinstr(win, y, x, string)); + report_status(string); +} + + +void +cmd_mvwprintw(int nargs, char **args) +{ + int y, x; + WINDOW *win; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwprintw(win, y, x, args[3], args[4])); +} + + +void +cmd_mvwscanw(int nargs, char **args) +{ + int y, x; + WINDOW *win; + char string[256]; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_int(mvwscanw(win, y, x, args[3], &string)); + report_status(string); +} + + +void +cmd_napms(int nargs, char **args) +{ + int naptime; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &naptime) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(napms(naptime)); +} + + +void +cmd_newpad(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(newpad(y, x)); +} + + +void +cmd_newterm(int nargs, char **args) +{ + FILE *in, *out; + + if (check_arg_count(nargs, 3) == 1) + return; + + if ((in = fopen(args[1], "rw")) == NULL) { + report_count(1); + report_error("BAD FILE_ARGUMENT"); + return; + } + + + if ((out = fopen(args[2], "rw")) == NULL) { + report_count(1); + report_error("BAD FILE_ARGUMENT"); + return; + } + + report_count(1); + report_ptr(newterm(args[0], out, in)); +} + + +void +cmd_newwin(int nargs, char **args) +{ + int lines, cols, begin_y, begin_x; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &lines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &cols) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &begin_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &begin_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(newwin(lines, cols, begin_y, begin_x)); +} + + +void +cmd_nl(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(nl()); +} + + +void +cmd_no_color_attributes(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(no_color_attributes()); +} + + +void +cmd_nocbreak(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(nocbreak()); +} + + +void +cmd_nodelay(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(nodelay(win, flag)); +} + + +void +cmd_noecho(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(noecho()); +} + + +void +cmd_nonl(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(nonl()); +} + + +void +cmd_noqiflush(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + noqiflush(); + report_count(1); + report_return(OK); /* fake a return, the call returns void */ +} + + +void +cmd_noraw(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(noraw()); +} + + +void +cmd_notimeout(int nargs, char **args) +{ + int flag; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(notimeout(win, flag)); +} + + +void +cmd_overlay(int nargs, char **args) +{ + WINDOW *source, *dest; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &source) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%p", &dest) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(overlay(source, dest)); +} + + +void +cmd_overwrite(int nargs, char **args) +{ + WINDOW *source, *dest; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &source) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%p", &dest) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(overwrite(source, dest)); +} + + +void +cmd_pair_content(int nargs, char **args) +{ + short pair, fore, back; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%hd", &pair) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call3 */ + report_count(3); + report_return(pair_content(pair, &fore, &back)); + report_int(fore); + report_int(back); +} + + +void +cmd_pechochar(int nargs, char **args) +{ + int ch; + WINDOW *pad; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &pad) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(pechochar(pad, ch)); +} + + +void +cmd_pnoutrefresh(int nargs, char **args) +{ + int pbeg_y, pbeg_x, sbeg_y, sbeg_x, smax_y, smax_x; + WINDOW *pad; + + if (check_arg_count(nargs, 7) == 1) + return; + + if (sscanf(args[0], "%p", &pad) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &pbeg_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &pbeg_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &sbeg_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &sbeg_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[5], "%d", &smax_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[6], "%d", &smax_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(pnoutrefresh(pad, pbeg_y, pbeg_x, sbeg_y, sbeg_x, smax_y, + smax_x)); +} + + +void +cmd_prefresh(int nargs, char **args) +{ + int pbeg_y, pbeg_x, sbeg_y, sbeg_x, smax_y, smax_x; + WINDOW *pad; + + if (check_arg_count(nargs, 7) == 1) + return; + + if (sscanf(args[0], "%p", &pad) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &pbeg_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &pbeg_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &sbeg_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &sbeg_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[5], "%d", &smax_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[6], "%d", &smax_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX causes refresh */ + report_count(1); + report_return(prefresh(pad, pbeg_y, pbeg_x, sbeg_y, sbeg_x, smax_y, + smax_x)); + +} + + +void +cmd_printw(int nargs, char **args) +{ + if (check_arg_count(nargs, 2) == 1) + return; + + + report_count(1); + report_return(printw(args[0], args[1])); +} + + +void +cmd_putwin(int nargs, char **args) +{ + FILE *fp; + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if ((fp = fopen(args[1], "rw")) == NULL) { + report_count(1); + report_error("BAD FILE_ARGUMENT"); + return; + } + + report_count(1); + report_return(putwin(win, fp)); +} + + +void +cmd_qiflush(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + qiflush(); + report_count(1); + report_return(OK); /* fake a return because call returns void */ +} + + +void +cmd_raw(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(raw()); +} + + +void +cmd_redrawwin(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(redrawwin(win)); +} + + +void +cmd_reset_prog_mode(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(reset_prog_mode()); +} + + +void +cmd_reset_shell_mode(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(reset_shell_mode()); +} + + +void +cmd_resetty(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(resetty()); +} + + +void +cmd_resizeterm(int nargs, char **args) +{ + int rows, cols; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%d", &rows) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &cols) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(resizeterm(rows, cols)); +} + + +void +cmd_savetty(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(savetty()); +} + + +void +cmd_scanw(int nargs, char **args) +{ + char string[256]; + + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX call2 */ + report_count(2); + report_return(scanw("%s", string)); + report_status(string); +} + + +void +cmd_scroll(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(scroll(win)); +} + + +void +cmd_scrollok(int nargs, char **args) +{ + WINDOW *win; + int flag; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &flag) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(scrollok(win, flag)); +} + + +void +cmd_setterm(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_return(setterm(args[0])); +} + + +void +cmd_set_term(int nargs, char **args) +{ + SCREEN *scrn; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &scrn) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(set_term(scrn)); +} + + +void +cmd_start_color(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(start_color()); +} + + +void +cmd_subpad(int nargs, char **args) +{ + WINDOW *pad; + int lines, cols, begin_y, begin_x; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &pad) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &lines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &cols) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &begin_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &begin_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(subpad(pad, lines, cols, begin_y, begin_x)); +} + + +void +cmd_subwin(int nargs, char **args) +{ + WINDOW *win; + int lines, cols, begin_y, begin_x; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &lines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &cols) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &begin_y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &begin_x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_ptr(subwin(win, lines, cols, begin_y, begin_x)); +} + + +void +cmd_termattrs(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(termattrs()); +} + + +void +cmd_term_attrs(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_int(term_attrs()); +} + + +void +cmd_touchline(int nargs, char **args) +{ + WINDOW *win; + int start, count; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &start) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(touchline(win, start, count)); +} + + +void +cmd_touchoverlap(int nargs, char **args) +{ + WINDOW *win1, *win2; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win1) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%p", &win2) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(touchoverlap(win1, win2)); +} + + +void +cmd_touchwin(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(touchwin(win)); +} + + +void +cmd_ungetch(int nargs, char **args) +{ + int ch; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(ungetch(ch)); +} + + +void +cmd_untouchwin(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(untouchwin(win)); +} + + +void +cmd_use_default_colors(int nargs, char **args) +{ + if (check_arg_count(nargs, 0) == 1) + return; + + report_count(1); + report_return(use_default_colors()); +} + + +void +cmd_vline(int nargs, char **args) +{ + int count; + chtype *ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + ch = (chtype *) args[0]; + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(vline(ch[0], count)); +} + + +static int +internal_vw_printw(WINDOW *win, char *arg1, ...) +{ + va_list va; + int rv; + + va_start(va, arg1); + rv = vw_printw(win, arg1, va); + va_end(va); + + return rv; +} + +void +cmd_vw_printw(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(internal_vw_printw(win, args[1], args[2])); +} + + +static int +internal_vw_scanw(WINDOW *win, char *arg1, ...) +{ + va_list va; + int rv; + + va_start(va, arg1); + rv = vw_scanw(win, arg1, va); + va_end(va); + + return rv; +} + +void +cmd_vw_scanw(int nargs, char **args) +{ + WINDOW *win; + char string[256]; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_int(internal_vw_scanw(win, args[1], string)); + report_status(string); +} + + +void +cmd_vwprintw(int nargs, char **args) +{ + cmd_vw_printw(nargs, args); +} + + +void +cmd_vwscanw(int nargs, char **args) +{ + cmd_vw_scanw(nargs, args); +} + + +void +cmd_waddch(int nargs, char **args) +{ + WINDOW *win; + chtype *ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[1]; + + report_count(1); + report_return(waddch(win, ch[0])); +} + + +void +cmd_waddchnstr(int nargs, char **args) +{ + WINDOW *win; + int count; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(waddchnstr(win, (chtype *) args[1], count)); +} + + +void +cmd_waddchstr(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(waddchstr(win, (chtype *) args[1])); +} + + +void +cmd_waddnstr(int nargs, char **args) +{ + WINDOW *win; + int count; + + if (check_arg_count(nargs, 1) == 3) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(waddnstr(win, args[1], count)); + +} + + +void +cmd_wattr_get(int nargs, char **args) +{ + WINDOW *win; + int attr; + short pair; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call3 */ + report_count(3); + report_return(wattr_get(win, &attr, &pair, NULL)); + report_int(attr); + report_int(pair); +} + + +void +cmd_wattr_off(int nargs, char **args) +{ + WINDOW *win; + int attr; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wattr_off(win, attr, NULL)); +} + + +void +cmd_wattr_on(int nargs, char **args) +{ + WINDOW *win; + int attr; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wattr_on(win, attr, NULL)); +} + + +void +cmd_wattr_set(int nargs, char **args) +{ + WINDOW *win; + int attr; + short pair; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%hd", &pair) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wattr_set(win, attr, pair, NULL)); +} + + +void +cmd_wattroff(int nargs, char **args) +{ + WINDOW *win; + int attr; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wattroff(win, attr)); +} + + +void +cmd_wattron(int nargs, char **args) +{ + WINDOW *win; + int attr; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wattron(win, attr)); +} + + +void +cmd_wattrset(int nargs, char **args) +{ + WINDOW *win; + int attr; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wattrset(win, attr)); +} + + +void +cmd_wbkgd(int nargs, char **args) +{ + WINDOW *win; + chtype *ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[1]; + report_count(1); + report_return(wbkgd(win, ch[0])); +} + + +void +cmd_wbkgdset(int nargs, char **args) +{ + WINDOW *win; + int ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + wbkgdset(win, ch); /* void return */ + report_count(1); + report_return(OK); +} + + +void +cmd_wborder(int nargs, char **args) +{ + WINDOW *win; + int ls, rs, ts, bs, tl, tr, bl, br; + + if (check_arg_count(nargs, 9) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &ls) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &rs) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &ts) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &bs) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[5], "%d", &tl) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[6], "%d", &tr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[7], "%d", &bl) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[8], "%d", &br) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wborder(win, ls, rs, ts, bs, tl, tr, bl, br)); +} + + +void +cmd_wclear(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wclear(win)); +} + + +void +cmd_wclrtobot(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wclrtobot(win)); +} + + +void +cmd_wclrtoeol(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wclrtoeol(win)); + +} + + +void +cmd_wcolor_set(int nargs, char **args) +{ + WINDOW *win; + short pair; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%hd", &pair) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wcolor_set(win, pair, NULL)); +} + + +void +cmd_wdelch(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wdelch(win)); +} + + +void +cmd_wdeleteln(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wdeleteln(win)); + +} + + +void +cmd_wechochar(int nargs, char **args) +{ + WINDOW *win; + int ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wechochar(win, ch)); +} + + +void +cmd_werase(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(werase(win)); +} + + +void +cmd_wgetch(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(wgetch(win)); +} + + +void +cmd_wgetnstr(int nargs, char **args) +{ + WINDOW *win; + int count; + char string[256]; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(wgetnstr(win, string, count)); + report_status(string); +} + + +void +cmd_wgetstr(int nargs, char **args) +{ + WINDOW *win; + char string[256]; + + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + string[0] = '\0'; + + report_count(2); + report_return(wgetstr(win, string)); + report_status(string); +} + + +void +cmd_whline(int nargs, char **args) +{ + WINDOW *win; + int ch, count; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(whline(win, ch, count)); +} + + +void +cmd_winch(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_int(winch(win)); +} + + +void +cmd_winchnstr(int nargs, char **args) +{ + WINDOW *win; + chtype string[256]; + int count; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(winchnstr(win, string, count)); + report_nstr(string); +} + + +void +cmd_winchstr(int nargs, char **args) +{ + WINDOW *win; + chtype string[256]; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(winchstr(win, string)); + report_nstr(string); +} + + +void +cmd_winnstr(int nargs, char **args) +{ + WINDOW *win; + char string[256]; + int count; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(winnstr(win, string, count)); + report_status(string); +} + + +void +cmd_winsch(int nargs, char **args) +{ + WINDOW *win; + int ch; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &ch) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(winsch(win, ch)); +} + + +void +cmd_winsdelln(int nargs, char **args) +{ + WINDOW *win; + int count; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &count) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(winsdelln(win, count)); +} + + +void +cmd_winsertln(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(winsertln(win)); +} + + +void +cmd_winstr(int nargs, char **args) +{ + WINDOW *win; + char string[256]; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - call2 */ + report_count(2); + report_return(winstr(win, string)); + report_status(string); +} + + +void +cmd_wmove(int nargs, char **args) +{ + WINDOW *win; + int y, x; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wmove(win, y, x)); +} + + +void +cmd_wnoutrefresh(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wnoutrefresh(win)); +} + + +void +cmd_wprintw(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wprintw(win, args[1], args[2])); +} + + +void +cmd_wredrawln(int nargs, char **args) +{ + WINDOW *win; + int beg_line, num_lines; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &beg_line) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &num_lines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wredrawln(win, beg_line, num_lines)); +} + + +void +cmd_wrefresh(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* XXX - generates output */ + report_count(1); + report_return(wrefresh(win)); +} + + +void +cmd_wresize(int nargs, char **args) +{ + WINDOW *win; + int lines, cols; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &lines) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &cols) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wresize(win, lines, cols)); +} + + +void +cmd_wscanw(int nargs, char **args) +{ + WINDOW *win; + char string[256]; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wscanw(win, args[1], &string)); +} + + +void +cmd_wscrl(int nargs, char **args) +{ + WINDOW *win; + int n; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wscrl(win, n)); +} + + +void +cmd_wsetscrreg(int nargs, char **args) +{ + WINDOW *win; + int top, bottom; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &top) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &bottom) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wsetscrreg(win, top, bottom)); +} + + +void +cmd_wstandend(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wstandend(win)); +} + + +void +cmd_wstandout(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wstandout(win)); +} + + +void +cmd_wtimeout(int nargs, char **args) +{ + WINDOW *win; + int tval; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &tval) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + wtimeout(win, tval); /* void return */ + report_count(1); + report_return(OK); +} + + +void +cmd_wtouchln(int nargs, char **args) +{ + WINDOW *win; + int line, n, changed; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &line) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &changed) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wtouchln(win, line, n, changed)); +} + + +void +cmd_wunderend(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wunderend(win)); +} + + +void +cmd_wunderscore(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wunderscore(win)); +} + + +void +cmd_wvline(int nargs, char **args) +{ + WINDOW *win; + int n; + chtype *ch; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + ch = (chtype *) args[1]; + + if (sscanf(args[2], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wvline(win, ch[0], n)); +} + + +void +cmd_insnstr(int nargs, char **args) +{ + int n; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[1], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(insnstr(args[0], n)); +} + + +void +cmd_insstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_return(insstr(args[0])); +} + + +void +cmd_mvinsnstr(int nargs, char **args) +{ + int y, x, n; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvinsnstr(y, x, args[2], n)); +} + + +void +cmd_mvinsstr(int nargs, char **args) +{ + int y, x; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvinsstr(y, x, args[2])); +} + + +void +cmd_mvwinsnstr(int nargs, char **args) +{ + WINDOW *win; + int y, x, n; + + if (check_arg_count(nargs, 5) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwinsnstr(win, y, x, args[3], n)); + +} + + +void +cmd_mvwinsstr(int nargs, char **args) +{ + WINDOW *win; + int y, x; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwinsstr(win, y, x, args[3])); +} + + +void +cmd_winsnstr(int nargs, char **args) +{ + WINDOW *win; + int n; + + if (check_arg_count(nargs, 3) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(winsnstr(win, args[1], n)); +} + + +void +cmd_winsstr(int nargs, char **args) +{ + WINDOW *win; + + if (check_arg_count(nargs, 2) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(winsstr(win, args[1])); +} + + + +void +cmd_chgat(int nargs, char **args) +{ + int n, attr, colour; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &colour) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + /* Note: 4th argument unused in current curses implementation */ + report_count(1); + report_return(chgat(n, attr, colour, NULL)); +} + + +void +cmd_wchgat(int nargs, char **args) +{ + WINDOW *win; + int n, attr; + short colour; + + if (check_arg_count(nargs, 4) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%hd", &colour) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(wchgat(win, n, attr, colour, NULL)); +} + + +void +cmd_mvchgat(int nargs, char **args) +{ + int y, x, n, attr; + short colour; + + if (check_arg_count(nargs, 6) == 1) + return; + + if (sscanf(args[0], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%hd", &colour) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvchgat(y, x, n, attr, colour, NULL)); +} + + +void +cmd_mvwchgat(int nargs, char **args) +{ + WINDOW *win; + int y, x, n, attr, colour; + + if (check_arg_count(nargs, 6) == 1) + return; + + if (sscanf(args[0], "%p", &win) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[1], "%d", &y) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[2], "%d", &x) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[3], "%d", &n) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[4], "%d", &attr) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + if (sscanf(args[5], "%d", &colour) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_return(mvwchgat(win, y, x, n, attr, colour, NULL)); +} + + +void +cmd_add_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wadd_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvadd_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwadd_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_add_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_add_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wadd_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wadd_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvadd_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvadd_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwadd_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwadd_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_addnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_addwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvaddnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvaddwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwaddnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwaddwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_waddnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_waddwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_echo_wchar(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wecho_wchar(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_pecho_wchar(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +/* insert */ +void +cmd_ins_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wins_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvins_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwins_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_ins_nwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_ins_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvins_nwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvins_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwins_nwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwins_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wins_nwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wins_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +/* input */ +void +cmd_get_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_unget_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvget_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwget_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wget_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_getn_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_get_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvgetn_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvget_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwgetn_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwget_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wgetn_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wget_wstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_in_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvin_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwin_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_win_wch(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_in_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_in_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvin_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvin_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwin_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwin_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_win_wchnstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_win_wchstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +void +cmd_innwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_inwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvinnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvinwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwinnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwinwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_winnwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_winwstr(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +/* cchar handlgin */ +void +cmd_setcchar(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_getcchar(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + + +/* misc */ +void +cmd_key_name(int nargs, char **args) +{ + int w; + + if (check_arg_count(nargs, 1) == 1) + return; + + if (sscanf(args[0], "%d", &w) == 0) { + report_count(1); + report_error("BAD ARGUMENT"); + return; + } + + report_count(1); + report_status(key_name(w)); +} + + +void +cmd_border_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wborder_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_box_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_erasewchar(int nargs, char **args) +{ + wchar_t ch; + + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX - call2 */ + report_count(2); + report_return(erasewchar(&ch)); + report_int(ch); +} + + +void +cmd_killwchar(int nargs, char **args) +{ + wchar_t ch; + + if (check_arg_count(nargs, 0) == 1) + return; + + /* XXX - call2 */ + report_count(2); + report_return(erasewchar(&ch)); + report_int(ch); +} + + +void +cmd_hline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvhline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvvline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwhline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_mvwvline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_vline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_whline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wvline_set(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_bkgrnd(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_bkgrndset(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_getbkgrnd(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wbkgrnd(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wbkgrndset(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} + + +void +cmd_wgetbkgrnd(int nargs, char **args) +{ + if (check_arg_count(nargs, 1) == 1) + return; + + report_count(1); + report_error("UNSUPPORTED"); +} diff --git a/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.h b/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.h new file mode 100644 index 0000000..d7f2ad7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.h @@ -0,0 +1,422 @@ +/* $NetBSD: curses_commands.h,v 1.3 2011/09/15 11:46:19 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * + */ + +#ifndef _CURSES_COMMANDS_H_ +#define _CURSES_COMMANDS_H_ + +struct command_def { + const char *name; + void (*func)(int, char **); +}; + +/* + * prototypes for test commands + */ +void cmd_DRAIN(int, char **); /* not a curses function */ + +void cmd_addbytes(int, char **); +void cmd_addch(int, char **); +void cmd_addchnstr(int, char **); +void cmd_addchstr(int, char **); +void cmd_addnstr(int, char **); +void cmd_addstr(int, char **); +void cmd_attr_get(int, char **); +void cmd_attr_off(int, char **); +void cmd_attr_on(int, char **); +void cmd_attr_set(int, char **); +void cmd_attroff(int, char **); +void cmd_attron(int, char **); +void cmd_attrset(int, char **); +void cmd_bkgd(int, char **); +void cmd_bkgdset(int, char **); +void cmd_border(int, char **); +void cmd_clear(int, char **); +void cmd_clrtobot(int, char **); +void cmd_clrtoeol(int, char **); +void cmd_color_set(int, char **); +void cmd_delch(int, char **); +void cmd_deleteln(int, char **); +void cmd_echochar(int, char **); +void cmd_erase(int, char **); +void cmd_getch(int, char **); +void cmd_getnstr(int, char **); +void cmd_getstr(int, char **); +void cmd_inch(int, char **); +void cmd_inchnstr(int, char **); +void cmd_inchstr(int, char **); +void cmd_innstr(int, char **); +void cmd_insch(int, char **); +void cmd_insdelln(int, char **); +void cmd_insertln(int, char **); +void cmd_instr(int, char **); +void cmd_move(int, char **); +void cmd_refresh(int, char **); +void cmd_scrl(int, char **); +void cmd_setscrreg(int, char **); +void cmd_standend(int, char **); +void cmd_standout(int, char **); +void cmd_timeout(int, char **); +void cmd_underscore(int, char **); +void cmd_underend(int, char **); +void cmd_waddbytes(int, char **); +void cmd_waddstr(int, char **); +void cmd_mvaddbytes(int, char **); +void cmd_mvaddch(int, char **); +void cmd_mvaddchnstr(int, char **); +void cmd_mvaddchstr(int, char **); +void cmd_mvaddnstr(int, char **); +void cmd_mvaddstr(int, char **); +void cmd_mvdelch(int, char **); +void cmd_mvgetch(int, char **); +void cmd_mvgetnstr(int, char **); +void cmd_mvgetstr(int, char **); +void cmd_mvinch(int, char **); +void cmd_mvinchnstr(int, char **); +void cmd_mvinchstr(int, char **); +void cmd_mvinnstr(int, char **); +void cmd_mvinsch(int, char **); +void cmd_mvinstr(int, char **); + +void cmd_mvwaddbytes(int, char **); +void cmd_mvwaddch(int, char **); +void cmd_mvwaddchnstr(int, char **); +void cmd_mvwaddchstr(int, char **); +void cmd_mvwaddnstr(int, char **); +void cmd_mvwaddstr(int, char **); +void cmd_mvwdelch(int, char **); +void cmd_mvwgetch(int, char **); +void cmd_mvwgetnstr(int, char **); +void cmd_mvwgetstr(int, char **); +void cmd_mvwinch(int, char **); +void cmd_mvwinsch(int, char **); +void cmd_assume_default_colors(int, char **); +void cmd_baudrate(int, char **); +void cmd_beep(int, char **); +void cmd_box(int, char **); +void cmd_can_change_color(int, char **); +void cmd_cbreak(int, char **); +void cmd_chgat(int, char **); +void cmd_clearok(int, char **); +void cmd_color_content(int, char **); +void cmd_copywin(int, char **); +void cmd_curs_set(int, char **); +void cmd_def_prog_mode(int, char **); +void cmd_def_shell_mode(int, char **); +void cmd_define_key(int, char **); +void cmd_delay_output(int, char **); +void cmd_delscreen(int, char **); +void cmd_delwin(int, char **); +void cmd_derwin(int, char **); +void cmd_dupwin(int, char **); +void cmd_doupdate(int, char **); +void cmd_echo(int, char **); +void cmd_endwin(int, char **); +void cmd_erasechar(int, char **); +void cmd_flash(int, char **); +void cmd_flushinp(int, char **); +void cmd_flushok(int, char **); +void cmd_fullname(int, char **); +void cmd_getattrs(int, char **); +void cmd_getbkgd(int, char **); +void cmd_getcury(int, char **); +void cmd_getcurx(int, char **); +void cmd_getyx(int, char **); +void cmd_getbegy(int, char **); +void cmd_getbegx(int, char **); +void cmd_getmaxy(int, char **); +void cmd_getmaxx(int, char **); +void cmd_getpary(int, char **); +void cmd_getparx(int, char **); +void cmd_getparyx(int, char **); +void cmd_gettmode(int, char **); +void cmd_getwin(int, char **); +void cmd_halfdelay(int, char **); +void cmd_has_colors(int, char **); +void cmd_has_ic(int, char **); +void cmd_has_il(int, char **); +void cmd_hline(int, char **); +void cmd_idcok(int, char **); +void cmd_idlok(int, char **); +void cmd_init_color(int, char **); +void cmd_init_pair(int, char **); +void cmd_initscr(int, char **); +void cmd_intrflush(int, char **); +void cmd_isendwin(int, char **); +void cmd_is_linetouched(int, char **); +void cmd_is_wintouched(int, char **); +void cmd_keyok(int, char **); +void cmd_keypad(int, char **); +void cmd_keyname(int, char **); +void cmd_killchar(int, char **); +void cmd_leaveok(int, char **); +void cmd_meta(int, char **); +void cmd_mvchgat(int, char **); +void cmd_mvcur(int, char **); +void cmd_mvderwin(int, char **); +void cmd_mvhline(int, char **); +void cmd_mvprintw(int, char **); +void cmd_mvscanw(int, char **); +void cmd_mvvline(int, char **); +void cmd_mvwchgat(int, char **); +void cmd_mvwhline(int, char **); +void cmd_mvwvline(int, char **); +void cmd_mvwin(int, char **); +void cmd_mvwinchnstr(int, char **); +void cmd_mvwinchstr(int, char **); +void cmd_mvwinnstr(int, char **); +void cmd_mvwinstr(int, char **); +void cmd_mvwprintw(int, char **); +void cmd_mvwscanw(int, char **); +void cmd_napms(int, char **); +void cmd_newpad(int, char **); +void cmd_newterm(int, char **); +void cmd_newwin(int, char **); +void cmd_nl(int, char **); +void cmd_no_color_attributes(int, char **); +void cmd_nocbreak(int, char **); +void cmd_nodelay(int, char **); +void cmd_noecho(int, char **); +void cmd_nonl(int, char **); +void cmd_noqiflush(int, char **); +void cmd_noraw(int, char **); +void cmd_notimeout(int, char **); +void cmd_overlay(int, char **); +void cmd_overwrite(int, char **); +void cmd_pair_content(int, char **); +void cmd_pechochar(int, char **); +void cmd_pnoutrefresh(int, char **); +void cmd_prefresh(int, char **); +void cmd_printw(int, char **); +void cmd_putwin(int, char **); +void cmd_qiflush(int, char **); +void cmd_raw(int, char **); +void cmd_redrawwin(int, char **); +void cmd_reset_prog_mode(int, char **); +void cmd_reset_shell_mode(int, char **); +void cmd_resetty(int, char **); +void cmd_resizeterm(int, char **); +void cmd_savetty(int, char **); +void cmd_scanw(int, char **); +void cmd_scroll(int, char **); +void cmd_scrollok(int, char **); +void cmd_setterm(int, char **); +void cmd_set_term(int, char **); +void cmd_start_color(int, char **); +void cmd_subpad(int, char **); +void cmd_subwin(int, char **); +void cmd_termattrs(int, char **); +void cmd_term_attrs(int, char **); +void cmd_touchline(int, char **); +void cmd_touchoverlap(int, char **); +void cmd_touchwin(int, char **); +void cmd_ungetch(int, char **); +void cmd_untouchwin(int, char **); +void cmd_use_default_colors(int, char **); +void cmd_vline(int, char **); +void cmd_vw_printw(int, char **); +void cmd_vw_scanw(int, char **); +void cmd_vwprintw(int, char **); +void cmd_vwscanw(int, char **); +void cmd_waddch(int, char **); +void cmd_waddchnstr(int, char **); +void cmd_waddchstr(int, char **); +void cmd_waddnstr(int, char **); +void cmd_wattr_get(int, char **); +void cmd_wattr_off(int, char **); +void cmd_wattr_on(int, char **); +void cmd_wattr_set(int, char **); +void cmd_wattroff(int, char **); +void cmd_wattron(int, char **); +void cmd_wattrset(int, char **); +void cmd_wbkgd(int, char **); +void cmd_wbkgdset(int, char **); +void cmd_wborder(int, char **); +void cmd_wchgat(int, char **); +void cmd_wclear(int, char **); +void cmd_wclrtobot(int, char **); +void cmd_wclrtoeol(int, char **); +void cmd_wcolor_set(int, char **); +void cmd_wdelch(int, char **); +void cmd_wdeleteln(int, char **); +void cmd_wechochar(int, char **); +void cmd_werase(int, char **); +void cmd_wgetch(int, char **); +void cmd_wgetnstr(int, char **); +void cmd_wgetstr(int, char **); +void cmd_whline(int, char **); +void cmd_winch(int, char **); +void cmd_winchnstr(int, char **); +void cmd_winchstr(int, char **); +void cmd_winnstr(int, char **); +void cmd_winsch(int, char **); +void cmd_winsdelln(int, char **); +void cmd_winsertln(int, char **); +void cmd_winstr(int, char **); +void cmd_wmove(int, char **); +void cmd_wnoutrefresh(int, char **); +void cmd_wprintw(int, char **); +void cmd_wredrawln(int, char **); +void cmd_wrefresh(int, char **); +void cmd_wresize(int, char **); +void cmd_wscanw(int, char **); +void cmd_wscrl(int, char **); +void cmd_wsetscrreg(int, char **); +void cmd_wstandend(int, char **); +void cmd_wstandout(int, char **); +void cmd_wtimeout(int, char **); +void cmd_wtouchln(int, char **); +void cmd_wunderend(int, char **); +void cmd_wunderscore(int, char **); +void cmd_wvline(int, char **); +void cmd_insnstr(int, char **); +void cmd_insstr(int, char **); +void cmd_mvinsnstr(int, char **); +void cmd_mvinsstr(int, char **); +void cmd_mvwinsnstr(int, char **); +void cmd_mvwinsstr(int, char **); +void cmd_winsnstr(int, char **); +void cmd_winsstr(int, char **); + +void cmd_chgat(int, char **); +void cmd_wchgat(int, char **); +void cmd_mvchgat(int, char **); +void cmd_mvwchgat(int, char **); +void cmd_add_wch(int, char **); +void cmd_wadd_wch(int, char **); +void cmd_mvadd_wch(int, char **); +void cmd_mvwadd_wch(int, char **); + +void cmd_add_wchnstr(int, char **); +void cmd_add_wchstr(int, char **); +void cmd_wadd_wchnstr(int, char **); +void cmd_wadd_wchstr(int, char **); +void cmd_mvadd_wchnstr(int, char **); +void cmd_mvadd_wchstr(int, char **); +void cmd_mvwadd_wchnstr(int, char **); +void cmd_mvwadd_wchstr(int, char **); + +void cmd_addnwstr(int, char **); +void cmd_addwstr(int, char **); +void cmd_mvaddnwstr(int, char **); +void cmd_mvaddwstr(int, char **); +void cmd_mvwaddnwstr(int, char **); +void cmd_mvwaddwstr(int, char **); +void cmd_waddnwstr(int, char **); +void cmd_waddwstr(int, char **); + +void cmd_echo_wchar(int, char **); +void cmd_wecho_wchar(int, char **); +void cmd_pecho_wchar(int, char **); + +/* insert */ +void cmd_ins_wch(int, char **); +void cmd_wins_wch(int, char **); +void cmd_mvins_wch(int, char **); +void cmd_mvwins_wch(int, char **); + +void cmd_ins_nwstr(int, char **); +void cmd_ins_wstr(int, char **); +void cmd_mvins_nwstr(int, char **); +void cmd_mvins_wstr(int, char **); +void cmd_mvwins_nwstr(int, char **); +void cmd_mvwins_wstr(int, char **); +void cmd_wins_nwstr(int, char **); +void cmd_wins_wstr(int, char **); + +/* input */ +void cmd_get_wch(int, char **); +void cmd_unget_wch(int, char **); +void cmd_mvget_wch(int, char **); +void cmd_mvwget_wch(int, char **); +void cmd_wget_wch(int, char **); + +void cmd_getn_wstr(int, char **); +void cmd_get_wstr(int, char **); +void cmd_mvgetn_wstr(int, char **); +void cmd_mvget_wstr(int, char **); +void cmd_mvwgetn_wstr(int, char **); +void cmd_mvwget_wstr(int, char **); +void cmd_wgetn_wstr(int, char **); +void cmd_wget_wstr(int, char **); + +void cmd_in_wch(int, char **); +void cmd_mvin_wch(int, char **); +void cmd_mvwin_wch(int, char **); +void cmd_win_wch(int, char **); + +void cmd_in_wchnstr(int, char **); +void cmd_in_wchstr(int, char **); +void cmd_mvin_wchnstr(int, char **); +void cmd_mvin_wchstr(int, char **); +void cmd_mvwin_wchnstr(int, char **); +void cmd_mvwin_wchstr(int, char **); +void cmd_win_wchnstr(int, char **); +void cmd_win_wchstr(int, char **); + +void cmd_innwstr(int, char **); +void cmd_inwstr(int, char **); +void cmd_mvinnwstr(int, char **); +void cmd_mvinwstr(int, char **); +void cmd_mvwinnwstr(int, char **); +void cmd_mvwinwstr(int, char **); +void cmd_winnwstr(int, char **); +void cmd_winwstr(int, char **); + +/* cchar handlgin */ +void cmd_setcchar(int, char **); +void cmd_getcchar(int, char **); + +/* misc */ +void cmd_key_name(int, char **); +void cmd_border_set(int, char **); +void cmd_wborder_set(int, char **); +void cmd_box_set(int, char **); +void cmd_erasewchar(int, char **); +void cmd_killwchar(int, char **); +void cmd_hline_set(int, char **); +void cmd_mvhline_set(int, char **); +void cmd_mvvline_set(int, char **); +void cmd_mvwhline_set(int, char **); +void cmd_mvwvline_set(int, char **); +void cmd_vline_set(int, char **); +void cmd_whline_set(int, char **); +void cmd_wvline_set(int, char **); +void cmd_bkgrnd(int, char **); +void cmd_bkgrndset(int, char **); +void cmd_getbkgrnd(int, char **); +void cmd_wbkgrnd(int, char **); +void cmd_wbkgrndset(int, char **); +void cmd_wgetbkgrnd(int, char **); + + + + +#endif /* !_CURSES_COMMAND_H_ */ diff --git a/contrib/netbsd-tests/lib/libcurses/slave/slave.c b/contrib/netbsd-tests/lib/libcurses/slave/slave.c new file mode 100644 index 0000000..b05a1da --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/slave/slave.c @@ -0,0 +1,177 @@ +/* $NetBSD: slave.c,v 1.6 2011/09/15 11:46:19 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include +#include +#include +#include +#include +#include +#include +#include "returns.h" +#include "slave.h" + +int cmdpipe[2]; +int slvpipe[2]; + +#if 0 +static const char *returns_enum_names[] = { + "unused", "numeric", "string", "byte", "ERR", "OK", "NULL", "not NULL", + "variable" +}; +#endif + +/* + * Read the command pipe for the function to execute, gather the args + * and then process the command. + */ +static void +process_commands(WINDOW *mainscr) +{ + int len, maxlen, argslen, i, ret, type; + char *cmdbuf, *tmpbuf, **args, **tmpargs; + + len = maxlen = 30; + if ((cmdbuf = malloc(maxlen)) == NULL) + err(1, "slave cmdbuf malloc failed"); + + while(1) { + if (read(cmdpipe[READ_PIPE], &type, sizeof(int)) < 0) + err(1, "slave command type read failed"); + + if (type != ret_string) + errx(1, "Unexpected type for command, got %d", type); + + if (read(cmdpipe[READ_PIPE], &len, sizeof(int)) < 0) + err(1, "slave command len read failed"); + + if ((len + 1) > maxlen) { + maxlen = len + 1; + if ((tmpbuf = realloc(cmdbuf, maxlen)) == NULL) + err(1, "slave cmdbuf realloc to %d " + "bytes failed", maxlen); + cmdbuf = tmpbuf; + } + + if (read(cmdpipe[READ_PIPE], cmdbuf, len) < 0) + err(1, "slave command read failed"); + cmdbuf[len] = '\0'; + argslen = 0; + args = NULL; + + do { + if (read(cmdpipe[READ_PIPE], &type, sizeof(int)) < 0) + err(1, "slave arg type read failed"); + + if (read(cmdpipe[READ_PIPE], &len, sizeof(int)) < 0) + err(1, "slave arg len read failed"); + + if (len >= 0) { + tmpargs = realloc(args, + (argslen + 1) * sizeof(char *)); + if (tmpargs == NULL) + err(1, "slave realloc of args array " + "failed"); + + args = tmpargs; + if (type != ret_null) { + args[argslen] = malloc(len + 1); + + if (args[argslen] == NULL) + err(1, "slave alloc of %d bytes" + " for args failed", len); + } + + if (len == 0) { + if (type == ret_null) + args[argslen] = NULL; + else + args[argslen][0] = '\0'; + } else { + read(cmdpipe[READ_PIPE], args[argslen], + len); + if (type != ret_byte) + args[argslen][len] = '\0'; + + if (len == 6) { + if (strcmp(args[argslen], + "STDSCR") == 0) { + ret = asprintf(&tmpbuf, + "%p", + stdscr); + if (ret < 0) + err(2, + "asprintf of stdscr failed"); + free(args[argslen]); + args[argslen] = tmpbuf; + } + } + } + + argslen++; + } + } + while(len >= 0); + + command_execute(cmdbuf, argslen, args); + + if (args != NULL) { + for (i = 0; i < argslen; i++) + free(args[i]); + + free(args); + } + } +} + +int +main(int argc, char *argv[]) +{ + WINDOW *mainscr; + + if (argc != 5) { + fprintf(stderr, "Usage: %s slvout>\n", + getprogname()); + return 0; + } + sscanf(argv[1], "%d", &cmdpipe[0]); + sscanf(argv[2], "%d", &cmdpipe[1]); + sscanf(argv[3], "%d", &slvpipe[0]); + sscanf(argv[4], "%d", &slvpipe[1]); + + mainscr = initscr(); + if (mainscr == NULL) + err(1, "initscr failed"); + + process_commands(mainscr); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libcurses/slave/slave.h b/contrib/netbsd-tests/lib/libcurses/slave/slave.h new file mode 100644 index 0000000..98e9971 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/slave/slave.h @@ -0,0 +1,50 @@ +/* $NetBSD: slave.h,v 1.3 2011/09/15 11:46:19 blymn Exp $ */ + +/*- + * Copyright 2009 Brett Lymn + * + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * + */ +#ifndef CURTEST_SLAVE_H +#define CURTEST_SLAVE_H + +#include + +#define READ_PIPE 0 +#define WRITE_PIPE 1 + +void command_execute(char *, int, char **); +void report_count(int); +void report_error(const char *); +void report_int(int); +void report_byte(chtype); +void report_return(int); +void report_nstr(chtype *); +void report_status(const char *); +void report_ptr(void *); +int check_arg_count(int, int); + +#endif diff --git a/contrib/netbsd-tests/lib/libcurses/t_curses.sh b/contrib/netbsd-tests/lib/libcurses/t_curses.sh new file mode 100755 index 0000000..5ff9474 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/t_curses.sh @@ -0,0 +1,294 @@ + +h_run() +{ + file="$(atf_get_srcdir)/tests/${1}" + + export COLUMNS=80 + export LINES=24 + $(atf_get_srcdir)/director \ + -T $(atf_get_srcdir) \ + -t atf \ + -I $(atf_get_srcdir)/tests \ + -C $(atf_get_srcdir)/check_files \ + -s $(atf_get_srcdir)/slave $file || atf_fail "test ${file} failed" +} + +atf_test_case startup +startup_head() +{ + atf_set "descr" "Checks curses initialisation sequence" +} +startup_body() +{ + h_run start +} + +atf_test_case addch +addch_head() +{ + atf_set "descr" "Tests adding a chtype to stdscr" +} +addch_body() +{ + h_run addch +} + +atf_test_case addchstr +addchstr_head() +{ + atf_set "descr" "Tests adding a chtype string to stdscr" +} +addchstr_body() +{ + h_run addchstr +} + +atf_test_case addchnstr +addchnstr_head() +{ + atf_set "descr" "Tests adding bytes from a chtype string to stdscr" +} +addchnstr_body() +{ + h_run addchnstr +} + +atf_test_case addstr +addstr_head() +{ + atf_set "descr" "Tests adding bytes from a string to stdscr" +} +addstr_body() +{ + h_run addstr +} + +atf_test_case addnstr +addnstr_head() +{ + atf_set "descr" "Tests adding bytes from a string to stdscr" +} +addnstr_body() +{ + h_run addnstr +} + +atf_test_case getch +getch_head() +{ + atf_set "descr" "Checks reading a character input" +} +getch_body() +{ + h_run getch +} + +atf_test_case timeout +timeout_head() +{ + atf_set "descr" "Checks timeout when reading a character" +} +timeout_body() +{ + h_run timeout +} + +atf_test_case window +window_head() +{ + atf_set "descr" "Checks window creation" +} +window_body() +{ + h_run window +} + +atf_test_case wborder +wborder_head() +{ + atf_set "descr" "Checks drawing a border around a window" +} +wborder_body() +{ + h_run wborder +} + +atf_test_case box +box_head() +{ + atf_set "descr" "Checks drawing a box around a window" +} +box_body() +{ + h_run box +} + +atf_test_case wprintw +wprintw_head() +{ + atf_set "descr" "Checks printing to a window" +} +wprintw_body() +{ + h_run wprintw +} + +atf_test_case wscrl +wscrl_head() +{ + atf_set "descr" "Check window scrolling" +} +wscrl_body() +{ + h_run wscrl +} + +atf_test_case mvwin +mvwin_head() +{ + atf_set "descr" "Check moving a window" +} +mvwin_body() +{ + h_run mvwin +} + +atf_test_case getstr +getstr_head() +{ + atf_set "descr" "Check getting a string from input" +} +getstr_body() +{ + h_run getstr +} + +atf_test_case termattrs +termattrs_head() +{ + atf_set "descr" "Check the terminal attributes" +} +termattrs_body() +{ + h_run termattrs +} + +atf_test_case assume_default_colors +assume_default_colors_head() +{ + atf_set "descr" "Check setting the default color pair" +} +assume_default_colors_body() +{ + h_run assume_default_colors +} + +atf_test_case attributes +attributes_head() +{ + atf_set "descr" "Check setting, clearing and getting of attributes" +} +attributes_body() +{ + h_run attributes +} + +atf_test_case beep +beep_head() +{ + atf_set "descr" "Check sending a beep" +} +beep_body() +{ + h_run beep +} + +atf_test_case background +background_head() +{ + atf_set "descr" "Check setting background character and attributes for both stdscr and a window." +} +background_body() +{ + h_run background +} + +atf_test_case can_change_color +can_change_color_head() +{ + atf_set "descr" "Check if the terminal can change colours" +} +can_change_color_body() +{ + h_run can_change_color +} + +atf_test_case cbreak +cbreak_head() +{ + atf_set "descr" "Check cbreak mode works" +} +cbreak_body() +{ + h_run cbreak +} + +atf_test_case clear +clear_head() +{ + atf_set "descr" "Check clear and erase work" +} +clear_body() +{ + h_run clear +} + +atf_test_case copywin +copywin_head() +{ + atf_set "descr" "Check all the modes of copying a window work" +} +copywin_body() +{ + h_run copywin +} + +atf_test_case curs_set +curs_set_head() +{ + atf_set "descr" "Check setting the cursor visibility works" +} +curs_set_body() +{ + h_run curs_set +} + +atf_init_test_cases() +{ + atf_add_test_case startup + atf_add_test_case addch + atf_add_test_case addchstr + atf_add_test_case addchnstr + atf_add_test_case addstr + atf_add_test_case addnstr + atf_add_test_case getch + atf_add_test_case timeout + atf_add_test_case window + atf_add_test_case wborder + atf_add_test_case box + atf_add_test_case wprintw + atf_add_test_case wscrl + atf_add_test_case mvwin + atf_add_test_case getstr + atf_add_test_case termattrs + atf_add_test_case can_change_color + atf_add_test_case assume_default_colors + atf_add_test_case attributes +# atf_add_test_case beep # comment out for now - return is wrong + atf_add_test_case background + atf_add_test_case cbreak + atf_add_test_case clear + atf_add_test_case copywin + atf_add_test_case curs_set +} + diff --git a/contrib/netbsd-tests/lib/libcurses/testframe.txt b/contrib/netbsd-tests/lib/libcurses/testframe.txt new file mode 100644 index 0000000..19884d7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/testframe.txt @@ -0,0 +1,241 @@ + +CURSES TESTFRAME +---------------- + +1. Introduction + +The curses library is a complex piece of software and, often, changes +made to the library may introduce subtle bugs that are hidden by other +actions so a visual check of the curses output may look correct in +some circumstances and the bug only show itself after a certain +sequence of actions. To assist with validating that changes made to +the curses library have no undesired effects an automated test is +needed to detect and highlight any changes in the curses application +output stream. The programmer can then analyse the output changes and +either correct a bug or update the automated test to accept the new +output as valid. + +2. Architecture + +The curses testframe consists of two separate programs connected by a +number of pipes and a pseudo-tty (pty). The programs are called the +director and the slave. The director reads a configuration file of +tests to perform, passes these commands to the slave over a pipe and +reads the pty for any output from the slave. Data from the slave is +compared against expected output held in a file and any differences +are highlighted to the tester. The slave is a curses application that +is forked by the director on start up. It reads commands from the +director over a pipe, these commands are calls to curses routines +along with the parameters required for the call. The slave takes the +parameters and uses them as arguments for the requested curses routine +call. The return value from the curses routine is passed back to the +director over another pipe, if the curses routine updates any passed +by reference arguments then these are also passed back to the director +for analysis. + +3. Director + +The director has the following optional command line options: + + -v enables verbose output to assist debugging + -s slave_path the director will execute slave_path as the slave + process. The default is ./slave + -t term Sets the TERM environment variable to term when + executing the slave. The default is atf + +There is one mandatory command line parameter, that is a file name +that contains the test command file. The test command file holds the +calls required to exercise a particular curses routine and validate +both the return codes from the routines and the output from the +slave. The test language has a small number of commands, they are: + +assign: + Assign a value to a variable. The syntax is: + + assign var_name value + + Where var_name is the name of the variable. Variable names are + an arbitrary sequence of alphanumeric characters, the variable + name must start with an alphabetic character. Value is the value + to be assigned. The value can either be a numeric or a string + type. Variables are created on first use and will be + overwritten on each subsequent use. + +call, call2, call3, call4: + All these are used to call curses routines, the only difference + between then is the number of expected return values. Call + expects one return value, call2 expects 2, call3 expects 3 and + call4 expects four. Any parameters that are passed by reference + and updated by the call are treated like returns. So, for + example, calling the function getyx() which has three + parameters, the window, a pointer to storage for y and a pointer + to storage for x would be called like this: + + call3 OK 4 5 getyx $win1 + + Which calls getyx, the first (and possibly only) return is the + return status of the function call, in this case we expect "OK" + indicating that the call succeeded. The next two returns are + the values of y and x respectively, the parameter $win1 is a + variable that was assigned by a previous call. Any return can + be assigned to a variable by including the variable name in a + call return list. Variables are referenced in a call parameter + list by prefixing the name with a $ character. All returns are + validated against the expected values and an error raised if + there is a mismatch. The only exception to this is when the + return is assigned to a variable. Valid values for the returns + list are: + + variable - assign the return to the given variable + name. + numeric - the value of the return must match the + number given. + string - an arbitrary sequence of characters + enclosed in double quotes. + ERR - expect an ERR return + OK - expect an OK return + NULL - expect a NULL pointer return + NON_NULL - expect a pointer that is not NULL valued + + There is one special parameter that can be passed to a call, + that is the label STDSCR. This parameter will be substituted by + the value of stdscr when the function call is made. + +check: + Validate the value of a variable. This allows a variable to be + checked for an expected return after it has been assigned in a + previous call. The syntax is: + + check var_name expected_result + + Where var_name is a variable previously assigned and + expected_result is one of the valid return values listed in the + above call section. + +compare: + Compares the output stream from the slave against the contents + of a file that contains the expected + output. The syntax is: + + compare filename + + Where filename is the name of the file containing the expected + output. The file can either be an absolute path or relative + path. In the latter case the value of the environment variable + CHECK_PATH will be prepended to the argument to provide the path + to the file. The contents of this file will be compared byte by + byte against the output from the slave, any differences in the + output will be flagged. If the director is not in verbose mode + then the first mismatch in the byte stream will cause the + director to exit. + +comparend: + Performs the same function as the above compare except that + excess output from the slave is not discarded if there is more + data from the slave than there is in the check file. This + allows chaining of multiple check files. + +delay: + Defines an inter-character delay to be inserted between + characters being fed into the input of the slave. The syntax + is: + + delay time + + Where time is the amount of time to delay in milliseconds. + +include: + Include the contents of another test file, the parser will + suspend reading the current file and read commands from the + include file until the end of file of the include file is + reached at which point it will continue reading the original + file. Include files may be nested. The syntax is: + + include filename + + Where filename is the name of the file to include. If the + filename is not an absolute path then the contents of the + environment variable INCLUDE_PATH are prepended to the file + name. + +input: + Defines a string of characters that will be fed to the slave + when a call requires input. Any unused input will be discarded + after the call that required the input is called. The syntax + is: + + input "string to pass" + +noinput: + Normally the director will error if an input function is called + without input being previously defined, this is to prevent input + functions causing the test to hang waiting for input that never + comes. If it is known that there is pending input for the slave + then the noinput keyword can be used to flag that the input + function has data available for it to read. The noinput command + only applies to the next function call then behaviour reverts to + the default. + +The testframe can define different types of strings, the type of string +depends on the type of enclosing quotes. A null terminated string is +indicated by enclosing double (") quotes. A byte string, one that is +not null terminated and may contain the nul character within it is +indicated by enclosing single (') quotes. A string of chtype +character which are a combined attribute and character value is +indicated by enclosing backticks (`), for this type of string pairs of +bytes between the backticks are converted to an array of chtype, the +first byte is the attribute and the second is the character. + +All strings defined will have a simple set of character substitutions +performed on them when they are parsed. This allows the tester to +embed some control characters into the string. Valid substitutions +are: + + \e escape + \n new line + \r carriage return + \t tab + \\ \ character + \nnn Where nnn is three octal digits, the character + represented by the octal number will be inserted into + the string. + +Any other invalid conversions will have the \ stripped and the +subsequent characters inserted into the string. + +Integers may be specified by either a plain numeric (e.g. 12345) or by +hexadecimal notation by prefixing the number with 0x (e.g. 0x3039). +Internally, no distinction is made between the two formats and they +can be freely intermixed. + +Integers and variables containing integers can have operations +performed on them. Currently only bitwise ORing numbers together is +supported. This can be done by separating a list of integers and +variables with the pipe (|) symbol and enclosing the entire list in +round brackets "()" like this: + + ( $var1 | 0x0100 | $var2 | 512 ) + +Variables and integer constants may be freely intermixed. The result +of the operation can either be used as an argument for a call or can +be used as an expected result for a call. + +In addition to all the curses calls being supported by the slave, +there is one more special call called "drain". This call repeatedly +called getch() until there are no more characters in stdin. The call +assumes that the curses input is either in no delay or timed input +mode otherwise the test will time out and fail. This call can be used +to clear any pending input when testing testing a timed read to +prevent the input being used in a later test. + +4. Slave + +The user has no direct interaction with the slave process. The slave +is forked off by the director communicates to the director over a set +of pipes and a pseudo-tty connected to its standard i/o file +descriptors. The slave executes the passed curses calls and passes +back return values to the director. The slave automatically calls +initscr() on start up. + + + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addch b/contrib/netbsd-tests/lib/libcurses/tests/addch new file mode 100644 index 0000000..a67e385 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/addch @@ -0,0 +1,4 @@ +include start +call OK addch `\001t` +call OK refresh +compare addch.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addchnstr b/contrib/netbsd-tests/lib/libcurses/tests/addchnstr new file mode 100644 index 0000000..661bf74 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/addchnstr @@ -0,0 +1,5 @@ +include start +# note that there are more characters in the array, check we only get 5 out +call OK addchnstr `\004a\004b\004c\004d\004e\004f\004g` 5 +call OK refresh +compare addchstr.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addchstr b/contrib/netbsd-tests/lib/libcurses/tests/addchstr new file mode 100644 index 0000000..4ccf7b8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/addchstr @@ -0,0 +1,4 @@ +include start +call OK addchstr `\004a\004b\004c\004d\004e` +call OK refresh +compare addchstr.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addnstr b/contrib/netbsd-tests/lib/libcurses/tests/addnstr new file mode 100644 index 0000000..9c40801 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/addnstr @@ -0,0 +1,5 @@ +include start +call OK addnstr "abcdefg" 5 +call OK refresh +# should be the same as addstr +compare addstr.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addstr b/contrib/netbsd-tests/lib/libcurses/tests/addstr new file mode 100644 index 0000000..8c1d24f --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/addstr @@ -0,0 +1,4 @@ +include start +call OK addstr "abcde" +call OK refresh +compare addstr.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/assume_default_colors b/contrib/netbsd-tests/lib/libcurses/tests/assume_default_colors new file mode 100644 index 0000000..b6ccb09 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/assume_default_colors @@ -0,0 +1,19 @@ +include start +call OK start_color +call OK assume_default_colors -1 -1 +call OK refresh +compare color_start.chk +# This should be the same as the default +compare color_default.chk +# default foreground, blue background +call OK assume_default_colors -1 $COLOR_BLUE +call OK refresh +compare color_blue_back.chk +# red foreground, default background +call OK assume_default_colors $COLOR_RED -1 +call OK refresh +compare color_red_fore.chk +# back to default +call OK assume_default_colors -1 -1 +call OK refresh +compare color_default.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/attributes b/contrib/netbsd-tests/lib/libcurses/tests/attributes new file mode 100644 index 0000000..b75d7d1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/attributes @@ -0,0 +1,23 @@ +include start +# no attributes, no color +call3 OK 0 0 attr_get +# set reverse and bold +call OK attr_set ($BOLD | $REVERSE) 2 +# returned attributes includes color information +call3 OK ($ACS_IS_WACS | $BOLD | $REVERSE) 2 attr_get +# turn off reverse +call OK attr_off $REVERSE +call3 OK ($ACS_IS_WACS | $BOLD) 2 attr_get +# turn on standout +call OK attr_on $STANDOUT +call3 OK ($ACS_IS_WACS | $BOLD | $STANDOUT) 2 attr_get +# turn on blink +call OK attron $BLINK +call3 OK ($ACS_IS_WACS | $BOLD | $STANDOUT | $BLINK) 2 attr_get +# turn off bold +call OK attroff $BOLD +call3 OK ($ACS_IS_WACS | $STANDOUT | $BLINK) 2 attr_get +# print out something to check our attributes are there, standout and blink +call OK printw "%s" "hello" +call OK refresh +compare attributes.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/background b/contrib/netbsd-tests/lib/libcurses/tests/background new file mode 100644 index 0000000..2c4a575 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/background @@ -0,0 +1,23 @@ +include start +call OK bkgd `\002A` +call OK refresh +# looks like a bug - bottom right char not filled +compare background1.chk +call OK printw "%s" "a test string" +call OK refresh +compare background2.chk +call win1 newwin 6 6 2 5 +check win1 NON_NULL +call OK wprintw $win1 "%s" "window 1" +# call OK refresh +call OK wrefresh $win1 +compare background3.chk +call OK wbkgd $win1 `\004B` +call OK refresh +call OK wrefresh $win1 +compare background4.chk +call OK wprintw $win1 "%s" "hello world" +call OK refresh +call OK wrefresh $win1 +compare background5.chk + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/beep b/contrib/netbsd-tests/lib/libcurses/tests/beep new file mode 100644 index 0000000..832e87f --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/beep @@ -0,0 +1,5 @@ +include start +# SUSv2 says this should return OK but we return 1 +call 1 beep +call OK refresh +compare bell.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/box b/contrib/netbsd-tests/lib/libcurses/tests/box new file mode 100644 index 0000000..bfd2e12 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/box @@ -0,0 +1,8 @@ +include window +call OK box $win1 `\000` `\000` +call OK wrefresh $win1 +# default settings of box will output same as wborder +compare wborder.chk +call OK box $win1 `\001\000` `\004\000` +call OK wrefresh $win1 +compare box_standout.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/can_change_color b/contrib/netbsd-tests/lib/libcurses/tests/can_change_color new file mode 100644 index 0000000..aed622a --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/can_change_color @@ -0,0 +1,3 @@ +include start +# our test terminal can change colors so expect true. +call 1 can_change_color diff --git a/contrib/netbsd-tests/lib/libcurses/tests/cbreak b/contrib/netbsd-tests/lib/libcurses/tests/cbreak new file mode 100644 index 0000000..b8bf60e --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/cbreak @@ -0,0 +1,18 @@ +include start +# setting noecho stops getch setting cbreak itself so we should need +# a newline before getch returns, check this works first. +call OK noecho +input "abcd\n" +call 0x61 getch +noinput +call 0x62 getch +noinput +call 0x63 getch +noinput +call 0x64 getch +noinput +call 0x0a getch +# set cbreak, getch should return without needing a newline +input "ef" +call OK cbreak +call 0x65 getch diff --git a/contrib/netbsd-tests/lib/libcurses/tests/chgat b/contrib/netbsd-tests/lib/libcurses/tests/chgat new file mode 100644 index 0000000..863ab11 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/chgat @@ -0,0 +1,15 @@ +include start_color +call OK init_pair 3 $COLOR_YELLOW $COLOR_CYAN +call OK addch `\000d` +call OK chgat 5 $REVERSE 3 0 +call OK refresh +compare chgat1.chk +call OK addch `\000e` +call OK refresh +compare chgat2.chk +call OK move 0 0 +# The following should apply the attribute and colour to the whole line +call OK chgat -1 $UNDERSCORE 3 0 +call OK refresh +compare chgat3.chk + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/clear b/contrib/netbsd-tests/lib/libcurses/tests/clear new file mode 100644 index 0000000..5aad934 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/clear @@ -0,0 +1,57 @@ +include addstr +call OK clear +call OK refresh +compare clear1.chk +call OK move 5 5 +call OK addstr "abcde" +call OK move 20 5 +call OK addstr "fghij" +call OK move 10 5 +call OK refresh +compare clear2.chk +call OK clrtobot +call OK refresh +compare clear3.chk +call OK erase +call OK refresh +compare clear4.chk +include fill_screen +compare fill.chk +call OK erase +call OK refresh +compare clear5.chk +# create a window to play with, defines win1 var +include window_create +call OK waddstr $win1 "abc" +call OK mvwaddstr $win1 4 1 "efg" +call OK wmove $win1 1 0 +call OK wrefresh $win1 +compare clear6.chk +call OK wclrtobot $win1 +call OK wrefresh $win1 +compare clear7.chk +include fill_screen +comparend home.chk +compare fill.chk +call OK wrefresh $win1 +call OK wclear $win1 +call OK wrefresh $win1 +compare clear8.chk +call OK clear +call OK refresh +compare clear1.chk +include fill_screen +compare fill.chk +call OK werase $win1 +call OK wrefresh $win1 +compare clear9.chk +call OK waddstr $win1 "abc" +call OK mvwaddstr $win1 4 1 "efg" +call OK wmove $win1 1 0 +call OK wrefresh $win1 +compare clear6.chk +call OK wmove $win1 4 0 +call OK wclrtoeol $win1 +call OK wrefresh $win1 +compare clear10.chk + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/color_content b/contrib/netbsd-tests/lib/libcurses/tests/color_content new file mode 100644 index 0000000..0db66e5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/color_content @@ -0,0 +1,12 @@ +include start +call OK start_color +call4 OK 0 0 0 color_content $COLOR_BLACK +call4 OK 1000 0 0 color_content $COLOR_RED +call4 OK 0 1000 0 color_content $COLOR_GREEN +call4 OK 1000 1000 0 color_content $COLOR_YELLOW +call4 OK 0 0 1000 color_content $COLOR_BLUE +call4 OK 1000 0 1000 color_content $COLOR_MAGENTA +call4 OK 0 1000 1000 color_content $COLOR_CYAN +call4 OK 1000 1000 1000 color_content $COLOR_WHITE + + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/color_set b/contrib/netbsd-tests/lib/libcurses/tests/color_set new file mode 100644 index 0000000..07cd1c5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/color_set @@ -0,0 +1,11 @@ +include start +call OK start_color +call OK refresh +comparend color_start.chk +compare color_blank_draw.chk +call OK init_pair 4 $COLOR_RED $COLOR_GREEN +call OK color_set 4 0 +call OK printw "%s" "testing" +call OK refresh +compare color_set.chk + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/copywin b/contrib/netbsd-tests/lib/libcurses/tests/copywin new file mode 100644 index 0000000..2dbec40 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/copywin @@ -0,0 +1,81 @@ +include start +include window_create +call win2 newwin 7 9 10 14 +check win2 NON_NULL +call OK wrefresh $win2 +compare copywin1.chk +call OK mvwprintw $win1 0 0 "%s" "testin" +call OK mvwprintw $win1 1 0 "%s" "gtesti" +call OK mvwprintw $win1 2 0 "%s" "ngtest" +call OK mvwprintw $win1 3 0 "%s" "ingtes" +call OK mvwprintw $win1 4 0 "%s" "tingte" +call OK mvwprintw $win1 5 0 "%s" "stingt" +call OK wrefresh $win1 +compare copywin2.chk +call OK copywin $win1 $win2 0 0 1 1 7 7 0 +call OK wrefresh $win2 +compare copywin3.chk +call OK wclear $win1 +call OK wclear $win2 +call OK wrefresh $win1 +call OK wrefresh $win2 +compare copywin4.chk +call OK mvwprintw $win2 0 0 "%s" "testingte" +call OK mvwprintw $win2 1 0 "%s" "stingtest" +call OK mvwprintw $win2 2 0 "%s" "ingtestin" +call OK mvwprintw $win2 3 0 "%s" "gtestingt" +call OK mvwprintw $win2 4 0 "%s" "estingtes" +call OK mvwprintw $win2 5 0 "%s" "tingtesti" +call OK wrefresh $win2 +compare copywin5.chk +call OK copywin $win2 $win1 0 0 0 0 7 9 0 +call OK wrefresh $win1 +compare copywin6.chk +call OK wclear $win1 +call OK wclear $win2 +call OK wrefresh $win1 +call OK wrefresh $win2 +compare copywin7.chk +call OK mvwprintw $win1 0 0 "%s" "t s i " +call OK mvwprintw $win1 1 0 "%s" "g e t " +call OK mvwprintw $win1 2 0 "%s" "n t s " +call OK mvwprintw $win1 3 0 "%s" " n t s" +call OK mvwprintw $win1 4 0 "%s" "t n t " +call OK mvwprintw $win1 5 0 "%s" " t n t" +call OK wrefresh $win1 +compare copywin8.chk +call OK mvwprintw $win2 0 0 "%s" " e t n" +call OK mvwprintw $win2 1 0 "%s" " t s i" +call OK mvwprintw $win2 2 0 "%s" " g e t" +call OK mvwprintw $win2 3 0 "%s" "i g e " +call OK mvwprintw $win2 4 0 "%s" " i g e" +call OK mvwprintw $win2 5 0 "%s" "s i g " +call OK wrefresh $win2 +compare copywin9.chk +call OK copywin $win1 $win2 0 0 0 0 6 6 0 +call OK wrefresh $win2 +compare copywin10.chk +call OK wclear $win1 +call OK wclear $win2 +call OK wrefresh $win1 +call OK wrefresh $win2 +compare copywin11.chk +call OK mvwprintw $win1 0 0 "%s" "t s i " +call OK mvwprintw $win1 1 0 "%s" "g e t " +call OK mvwprintw $win1 2 0 "%s" "n t s " +call OK mvwprintw $win1 3 0 "%s" " n t s" +call OK mvwprintw $win1 4 0 "%s" "t n t " +call OK mvwprintw $win1 5 0 "%s" " t n t" +call OK wrefresh $win1 +compare copywin12.chk +call OK mvwprintw $win2 0 0 "%s" " e t n" +call OK mvwprintw $win2 1 0 "%s" " t s i" +call OK mvwprintw $win2 2 0 "%s" " g e t" +call OK mvwprintw $win2 3 0 "%s" "i g e " +call OK mvwprintw $win2 4 0 "%s" " i g e" +call OK mvwprintw $win2 5 0 "%s" "s i g " +call OK wrefresh $win2 +compare copywin13.chk +call OK copywin $win1 $win2 0 0 0 0 6 6 1 +call OK wrefresh $win2 +compare copywin14.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/curs_set b/contrib/netbsd-tests/lib/libcurses/tests/curs_set new file mode 100644 index 0000000..5d7cb54 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/curs_set @@ -0,0 +1,7 @@ +include start +call 2 curs_set 0 +compare curs_set1.chk +call 0 curs_set 1 +compare curs_set2.chk +call 1 curs_set 2 +compare curs_set3.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/fill_screen b/contrib/netbsd-tests/lib/libcurses/tests/fill_screen new file mode 100644 index 0000000..b9e2942 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/fill_screen @@ -0,0 +1,29 @@ +# +# Fill the screen with characters. We don't do a compare in here because +# this is meant to be included from other tests which could result in random +# cursor motions before the fill is done. +# +call OK mvaddstr 0 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 1 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 2 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 3 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 4 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 5 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 6 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 7 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 8 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 9 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 10 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 11 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 12 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 13 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 14 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 15 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 16 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 17 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 18 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 19 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 20 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 21 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK mvaddstr 22 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" +call OK refresh diff --git a/contrib/netbsd-tests/lib/libcurses/tests/getch b/contrib/netbsd-tests/lib/libcurses/tests/getch new file mode 100644 index 0000000..9f437f5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/getch @@ -0,0 +1,3 @@ +include start +input "i" +call 105 getch diff --git a/contrib/netbsd-tests/lib/libcurses/tests/getstr b/contrib/netbsd-tests/lib/libcurses/tests/getstr new file mode 100644 index 0000000..320325f --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/getstr @@ -0,0 +1,6 @@ +include window +input "input\n" +call2 OK "input" wgetstr $win1 +compare wgetstr.chk +call OK wrefresh $win1 +compare wgetstr_refresh.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/mvwin b/contrib/netbsd-tests/lib/libcurses/tests/mvwin new file mode 100644 index 0000000..86d9bd6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/mvwin @@ -0,0 +1,12 @@ +include window +call OK wmove $win1 1 1 +call OK wprintw $win1 "%s" "xxxx" +call OK wrefresh $win1 +compare /dev/zero +call OK refresh +compare /dev/zero +call OK mvwin $win1 4 7 +call OK wrefresh $win1 +compare /dev/zero +call OK refresh +compare /dev/zero diff --git a/contrib/netbsd-tests/lib/libcurses/tests/start b/contrib/netbsd-tests/lib/libcurses/tests/start new file mode 100644 index 0000000..963f2f4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/start @@ -0,0 +1,3 @@ +include std_defines +call OK refresh +compare curses_start.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/start_color b/contrib/netbsd-tests/lib/libcurses/tests/start_color new file mode 100644 index 0000000..6d3f133 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/start_color @@ -0,0 +1,5 @@ +include start +call OK start_color +call OK refresh +comparend color_start.chk +compare color_blank_draw.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/std_defines b/contrib/netbsd-tests/lib/libcurses/tests/std_defines new file mode 100644 index 0000000..9c986df --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/std_defines @@ -0,0 +1,138 @@ +# +# Define some standard symbols for curses so tests can reference things +# symbolically instead of using magic numbers. +# +# +# boolean +# +assign TRUE 0x01 +assign FALSE 0x00 +# +# colours +# +assign COLOR_BLACK 0x00 +assign COLOR_RED 0x01 +assign COLOR_GREEN 0x02 +assign COLOR_YELLOW 0x03 +assign COLOR_BLUE 0x04 +assign COLOR_MAGENTA 0x05 +assign COLOR_CYAN 0x06 +assign COLOR_WHITE 0x07 +# +# Attributes +# +assign NORMAL 0x00000000 +assign STANDOUT 0x00000100 +assign UNDERSCORE 0x00000200 +assign REVERSE 0x00000400 +assign BLINK 0x00000800 +assign DIM 0x00001000 +assign BOLD 0x00002000 +assign BLANK 0x00004000 +assign PROTECT 0x00008000 +assign ALTCHARSET 0x00010000 +assign ACS_IS_WACS 0x00040000 +# +# Keys +# +assign KEY_BREAK 0x101 +assign KEY_DOWN 0x102 +assign KEY_UP 0x103 +assign KEY_LEFT 0x104 +assign KEY_RIGHT 0x105 +assign KEY_HOME 0x106 +assign KEY_BACKSPACE 0x107 +assign KEY_F0 0x108 +assign KEY_F1 0x109 +assign KEY_F2 0x10a +assign KEY_F3 0x10b +assign KEY_F4 0x10c +assign KEY_F5 0x10d +assign KEY_F6 0x10e +assign KEY_F7 0x10f +assign KEY_F8 0x110 +assign KEY_F9 0x111 +assign KEY_DL 0x148 +assign KEY_IL 0x149 +assign KEY_DC 0x14A +assign KEY_IC 0x14B +assign KEY_EIC 0x14C +assign KEY_CLEAR 0x14D +assign KEY_EOS 0x14E +assign KEY_EOL 0x14F +assign KEY_SF 0x150 +assign KEY_SR 0x151 +assign KEY_NPAGE 0x152 +assign KEY_PPAGE 0x153 +assign KEY_STAB 0x154 +assign KEY_CTAB 0x155 +assign KEY_CATAB 0x156 +assign KEY_ENTER 0x157 +assign KEY_SRESET 0x158 +assign KEY_RESET 0x159 +assign KEY_PRINT 0x15A +assign KEY_LL 0x15B +assign KEY_A1 0x15C +assign KEY_A3 0x15D +assign KEY_B2 0x15E +assign KEY_C1 0x15F +assign KEY_C3 0x160 +assign KEY_BTAB 0x161 +assign KEY_BEG 0x162 +assign KEY_CANCEL 0x163 +assign KEY_CLOSE 0x164 +assign KEY_COMMAND 0x165 +assign KEY_COPY 0x166 +assign KEY_CREATE 0x167 +assign KEY_END 0x168 +assign KEY_EXIT 0x169 +assign KEY_FIND 0x16A +assign KEY_HELP 0x16B +assign KEY_MARK 0x16C +assign KEY_MESSAGE 0x16D +assign KEY_MOVE 0x16E +assign KEY_NEXT 0x16F +assign KEY_OPEN 0x170 +assign KEY_OPTIONS 0x171 +assign KEY_PREVIOUS 0x172 +assign KEY_REDO 0x173 +assign KEY_REFERENCE 0x174 +assign KEY_REFRESH 0x175 +assign KEY_REPLACE 0x176 +assign KEY_RESTART 0x177 +assign KEY_RESUME 0x178 +assign KEY_SAVE 0x179 +assign KEY_SBEG 0x17A +assign KEY_SCANCEL 0x17B +assign KEY_SCOMMAND 0x17C +assign KEY_SCOPY 0x17D +assign KEY_SCREATE 0x17E +assign KEY_SDC 0x17F +assign KEY_SDL 0x180 +assign KEY_SELECT 0x181 +assign KEY_SEND 0x182 +assign KEY_SEOL 0x183 +assign KEY_SEXIT 0x184 +assign KEY_SFIND 0x185 +assign KEY_SHELP 0x186 +assign KEY_SHOME 0x187 +assign KEY_SIC 0x188 +assign KEY_SLEFT 0x189 +assign KEY_SMESSAGE 0x18A +assign KEY_SMOVE 0x18B +assign KEY_SNEXT 0x18C +assign KEY_SOPTIONS 0x18D +assign KEY_SPREVIOUS 0x18E +assign KEY_SPRINT 0x18F +assign KEY_SREDO 0x190 +assign KEY_SREPLACE 0x191 +assign KEY_SRIGHT 0x192 +assign KEY_SRSUME 0x193 +assign KEY_SSAVE 0x194 +assign KEY_SSUSPEND 0x195 +assign KEY_SUNDO 0x196 +assign KEY_SUSPEND 0x197 +assign KEY_UNDO 0x198 +assign KEY_MOUSE 0x199 +assign KEY_RESIZE 0x200 + diff --git a/contrib/netbsd-tests/lib/libcurses/tests/termattrs b/contrib/netbsd-tests/lib/libcurses/tests/termattrs new file mode 100644 index 0000000..1025301 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/termattrs @@ -0,0 +1,3 @@ +include start +# the atf terminal can do all attributes except PROTECT +call 0x17f00 termattrs diff --git a/contrib/netbsd-tests/lib/libcurses/tests/timeout b/contrib/netbsd-tests/lib/libcurses/tests/timeout new file mode 100644 index 0000000..1adf057 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/timeout @@ -0,0 +1,21 @@ +# +# Validate the timeout works. +# +include start +delay 2000 +input "a" +call 97 getch +call OK timeout 100 +input "b" +# since delay is in effect and we set timeout the following getch should +# return ERR not the character b. +call -1 getch +# drain input.... +call OK drain +call OK timeout -1 +call OK keypad STDSCR 1 +delay 0 +input "\eOA" +call $KEY_UP getch +call OK refresh +compare timeout.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/wborder b/contrib/netbsd-tests/lib/libcurses/tests/wborder new file mode 100644 index 0000000..7a8e78f --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/wborder @@ -0,0 +1,6 @@ +include window +call OK wborder $win1 0 0 0 0 0 0 0 0 +call OK wrefresh $win1 +compare wborder.chk +call OK refresh +compare wborder_refresh.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/window b/contrib/netbsd-tests/lib/libcurses/tests/window new file mode 100644 index 0000000..52b2d0a --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/window @@ -0,0 +1,2 @@ +include start +include window_create diff --git a/contrib/netbsd-tests/lib/libcurses/tests/window_create b/contrib/netbsd-tests/lib/libcurses/tests/window_create new file mode 100644 index 0000000..8c96134 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/window_create @@ -0,0 +1,4 @@ +call win1 newwin 6 6 2 5 +check win1 NON_NULL +call OK wrefresh $win1 +compare window.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/wprintw b/contrib/netbsd-tests/lib/libcurses/tests/wprintw new file mode 100644 index 0000000..a30fcc0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/wprintw @@ -0,0 +1,6 @@ +include start +call win1 newwin 2 5 2 5 +check win1 NON_NULL +call OK wprintw $win1 "%s" "hello" +call OK wrefresh $win1 +compare wprintw_refresh.chk diff --git a/contrib/netbsd-tests/lib/libcurses/tests/wscrl b/contrib/netbsd-tests/lib/libcurses/tests/wscrl new file mode 100644 index 0000000..51be531 --- /dev/null +++ b/contrib/netbsd-tests/lib/libcurses/tests/wscrl @@ -0,0 +1,11 @@ +include window +call OK wmove $win1 1 1 +call OK wprintw $win1 "%s" "xxxx" +call OK wrefresh $win1 +call OK refresh +compare wscrl1.chk +call OK scrollok $win1 1 +call OK wscrl $win1 -2 +call OK wrefresh $win1 +call OK refresh +compare wscrl2.chk diff --git a/contrib/netbsd-tests/lib/libdes/t_des.c b/contrib/netbsd-tests/lib/libdes/t_des.c new file mode 100644 index 0000000..abf2e54 --- /dev/null +++ b/contrib/netbsd-tests/lib/libdes/t_des.c @@ -0,0 +1,989 @@ +/* $NetBSD: t_des.c,v 1.1 2010/08/25 16:46:36 jmmv Exp $ */ + +/* + * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) All rights + * reserved. + * + * This package is an SSL implementation written by Eric Young + * (eay@cryptsoft.com). The implementation was written so as to conform with + * Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as the + * following conditions are aheared to. The following conditions apply to + * all code found in this distribution, be it the RC4, RSA, lhash, DES, etc., + * code; not just the SSL code. The SSL documentation included with this + * distribution is covered by the same copyright terms except that the holder + * is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in the code + * are not to be removed. If this package is used in a product, Eric Young + * should be given attribution as the author of the parts of the library + * used. This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * 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 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 cryptographic software written by + * Eric Young (eay@cryptsoft.com)" The word 'cryptographic' can be left out + * if the rouines from the library being used are not cryptographic related + * :-). 4. If you include any Windows specific code (or a derivative thereof) + * from the apps directory (application code) you must include an + * acknowledgement: "This product includes software written by Tim Hudson + * (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply + * be copied and put under another distribution licence [including the GNU + * Public Licence.] + */ + +#include +#include +#include +#include +#include +#include + +#define crypt(c,s) (des_crypt((c),(s))) + +/* tisk tisk - the test keys don't all have odd parity :-( */ +/* test data */ +#define NUM_TESTS 34 +static unsigned char key_data[NUM_TESTS][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}, + {0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57}, + {0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E}, + {0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86}, + {0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E}, + {0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6}, + {0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE}, + {0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6}, + {0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE}, + {0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16}, + {0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F}, + {0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46}, + {0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E}, + {0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76}, + {0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07}, + {0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F}, + {0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7}, + {0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF}, + {0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6}, + {0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF}, + {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E}, + {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10} +}; + +static unsigned char plain_data[NUM_TESTS][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42}, + {0x5C, 0xD5, 0x4C, 0xA8, 0x3D, 0xEF, 0x57, 0xDA}, + {0x02, 0x48, 0xD4, 0x38, 0x06, 0xF6, 0x71, 0x72}, + {0x51, 0x45, 0x4B, 0x58, 0x2D, 0xDF, 0x44, 0x0A}, + {0x42, 0xFD, 0x44, 0x30, 0x59, 0x57, 0x7F, 0xA2}, + {0x05, 0x9B, 0x5E, 0x08, 0x51, 0xCF, 0x14, 0x3A}, + {0x07, 0x56, 0xD8, 0xE0, 0x77, 0x47, 0x61, 0xD2}, + {0x76, 0x25, 0x14, 0xB8, 0x29, 0xBF, 0x48, 0x6A}, + {0x3B, 0xDD, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02}, + {0x26, 0x95, 0x5F, 0x68, 0x35, 0xAF, 0x60, 0x9A}, + {0x16, 0x4D, 0x5E, 0x40, 0x4F, 0x27, 0x52, 0x32}, + {0x6B, 0x05, 0x6E, 0x18, 0x75, 0x9F, 0x5C, 0xCA}, + {0x00, 0x4B, 0xD6, 0xEF, 0x09, 0x17, 0x60, 0x62}, + {0x48, 0x0D, 0x39, 0x00, 0x6E, 0xE7, 0x62, 0xF2}, + {0x43, 0x75, 0x40, 0xC8, 0x69, 0x8F, 0x3C, 0xFA}, + {0x07, 0x2D, 0x43, 0xA0, 0x77, 0x07, 0x52, 0x92}, + {0x02, 0xFE, 0x55, 0x77, 0x81, 0x17, 0xF1, 0x2A}, + {0x1D, 0x9D, 0x5C, 0x50, 0x18, 0xF7, 0x28, 0xC2}, + {0x30, 0x55, 0x32, 0x28, 0x6D, 0x6F, 0x29, 0x5A}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} +}; + +static unsigned char cipher_data[NUM_TESTS][8] = { + {0x8C, 0xA6, 0x4D, 0xE9, 0xC1, 0xB1, 0x23, 0xA7}, + {0x73, 0x59, 0xB2, 0x16, 0x3E, 0x4E, 0xDC, 0x58}, + {0x95, 0x8E, 0x6E, 0x62, 0x7A, 0x05, 0x55, 0x7B}, + {0xF4, 0x03, 0x79, 0xAB, 0x9E, 0x0E, 0xC5, 0x33}, + {0x17, 0x66, 0x8D, 0xFC, 0x72, 0x92, 0x53, 0x2D}, + {0x8A, 0x5A, 0xE1, 0xF8, 0x1A, 0xB8, 0xF2, 0xDD}, + {0x8C, 0xA6, 0x4D, 0xE9, 0xC1, 0xB1, 0x23, 0xA7}, + {0xED, 0x39, 0xD9, 0x50, 0xFA, 0x74, 0xBC, 0xC4}, + {0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B}, + {0x7A, 0x38, 0x9D, 0x10, 0x35, 0x4B, 0xD2, 0x71}, + {0x86, 0x8E, 0xBB, 0x51, 0xCA, 0xB4, 0x59, 0x9A}, + {0x71, 0x78, 0x87, 0x6E, 0x01, 0xF1, 0x9B, 0x2A}, + {0xAF, 0x37, 0xFB, 0x42, 0x1F, 0x8C, 0x40, 0x95}, + {0x86, 0xA5, 0x60, 0xF1, 0x0E, 0xC6, 0xD8, 0x5B}, + {0x0C, 0xD3, 0xDA, 0x02, 0x00, 0x21, 0xDC, 0x09}, + {0xEA, 0x67, 0x6B, 0x2C, 0xB7, 0xDB, 0x2B, 0x7A}, + {0xDF, 0xD6, 0x4A, 0x81, 0x5C, 0xAF, 0x1A, 0x0F}, + {0x5C, 0x51, 0x3C, 0x9C, 0x48, 0x86, 0xC0, 0x88}, + {0x0A, 0x2A, 0xEE, 0xAE, 0x3F, 0xF4, 0xAB, 0x77}, + {0xEF, 0x1B, 0xF0, 0x3E, 0x5D, 0xFA, 0x57, 0x5A}, + {0x88, 0xBF, 0x0D, 0xB6, 0xD7, 0x0D, 0xEE, 0x56}, + {0xA1, 0xF9, 0x91, 0x55, 0x41, 0x02, 0x0B, 0x56}, + {0x6F, 0xBF, 0x1C, 0xAF, 0xCF, 0xFD, 0x05, 0x56}, + {0x2F, 0x22, 0xE4, 0x9B, 0xAB, 0x7C, 0xA1, 0xAC}, + {0x5A, 0x6B, 0x61, 0x2C, 0xC2, 0x6C, 0xCE, 0x4A}, + {0x5F, 0x4C, 0x03, 0x8E, 0xD1, 0x2B, 0x2E, 0x41}, + {0x63, 0xFA, 0xC0, 0xD0, 0x34, 0xD9, 0xF7, 0x93}, + {0x61, 0x7B, 0x3A, 0x0C, 0xE8, 0xF0, 0x71, 0x00}, + {0xDB, 0x95, 0x86, 0x05, 0xF8, 0xC8, 0xC6, 0x06}, + {0xED, 0xBF, 0xD1, 0xC6, 0x6C, 0x29, 0xCC, 0xC7}, + {0x35, 0x55, 0x50, 0xB2, 0x15, 0x0E, 0x24, 0x51}, + {0xCA, 0xAA, 0xAF, 0x4D, 0xEA, 0xF1, 0xDB, 0xAE}, + {0xD5, 0xD4, 0x4F, 0xF7, 0x20, 0x68, 0x3D, 0x0D}, + {0x2A, 0x2B, 0xB0, 0x08, 0xDF, 0x97, 0xC2, 0xF2} +}; + +static unsigned char cipher_ecb2[NUM_TESTS - 1][8] = { + {0x92, 0x95, 0xB5, 0x9B, 0xB3, 0x84, 0x73, 0x6E}, + {0x19, 0x9E, 0x9D, 0x6D, 0xF3, 0x9A, 0xA8, 0x16}, + {0x2A, 0x4B, 0x4D, 0x24, 0x52, 0x43, 0x84, 0x27}, + {0x35, 0x84, 0x3C, 0x01, 0x9D, 0x18, 0xC5, 0xB6}, + {0x4A, 0x5B, 0x2F, 0x42, 0xAA, 0x77, 0x19, 0x25}, + {0xA0, 0x6B, 0xA9, 0xB8, 0xCA, 0x5B, 0x17, 0x8A}, + {0xAB, 0x9D, 0xB7, 0xFB, 0xED, 0x95, 0xF2, 0x74}, + {0x3D, 0x25, 0x6C, 0x23, 0xA7, 0x25, 0x2F, 0xD6}, + {0xB7, 0x6F, 0xAB, 0x4F, 0xBD, 0xBD, 0xB7, 0x67}, + {0x8F, 0x68, 0x27, 0xD6, 0x9C, 0xF4, 0x1A, 0x10}, + {0x82, 0x57, 0xA1, 0xD6, 0x50, 0x5E, 0x81, 0x85}, + {0xA2, 0x0F, 0x0A, 0xCD, 0x80, 0x89, 0x7D, 0xFA}, + {0xCD, 0x2A, 0x53, 0x3A, 0xDB, 0x0D, 0x7E, 0xF3}, + {0xD2, 0xC2, 0xBE, 0x27, 0xE8, 0x1B, 0x68, 0xE3}, + {0xE9, 0x24, 0xCF, 0x4F, 0x89, 0x3C, 0x5B, 0x0A}, + {0xA7, 0x18, 0xC3, 0x9F, 0xFA, 0x9F, 0xD7, 0x69}, + {0x77, 0x2C, 0x79, 0xB1, 0xD2, 0x31, 0x7E, 0xB1}, + {0x49, 0xAB, 0x92, 0x7F, 0xD0, 0x22, 0x00, 0xB7}, + {0xCE, 0x1C, 0x6C, 0x7D, 0x85, 0xE3, 0x4A, 0x6F}, + {0xBE, 0x91, 0xD6, 0xE1, 0x27, 0xB2, 0xE9, 0x87}, + {0x70, 0x28, 0xAE, 0x8F, 0xD1, 0xF5, 0x74, 0x1A}, + {0xAA, 0x37, 0x80, 0xBB, 0xF3, 0x22, 0x1D, 0xDE}, + {0xA6, 0xC4, 0xD2, 0x5E, 0x28, 0x93, 0xAC, 0xB3}, + {0x22, 0x07, 0x81, 0x5A, 0xE4, 0xB7, 0x1A, 0xAD}, + {0xDC, 0xCE, 0x05, 0xE7, 0x07, 0xBD, 0xF5, 0x84}, + {0x26, 0x1D, 0x39, 0x2C, 0xB3, 0xBA, 0xA5, 0x85}, + {0xB4, 0xF7, 0x0F, 0x72, 0xFB, 0x04, 0xF0, 0xDC}, + {0x95, 0xBA, 0xA9, 0x4E, 0x87, 0x36, 0xF2, 0x89}, + {0xD4, 0x07, 0x3A, 0xF1, 0x5A, 0x17, 0x82, 0x0E}, + {0xEF, 0x6F, 0xAF, 0xA7, 0x66, 0x1A, 0x7E, 0x89}, + {0xC1, 0x97, 0xF5, 0x58, 0x74, 0x8A, 0x20, 0xE7}, + {0x43, 0x34, 0xCF, 0xDA, 0x22, 0xC4, 0x86, 0xC8}, + {0x08, 0xD7, 0xB4, 0xFB, 0x62, 0x9D, 0x08, 0x85} +}; + +static unsigned char cbc_key[8] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, +}; +static unsigned char cbc2_key[8] = { + 0xf1, 0xe0, 0xd3, 0xc2, 0xb5, 0xa4, 0x97, 0x86, +}; +static unsigned char cbc3_key[8] = { + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, +}; +static unsigned char cbc_iv[8] = { + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, +}; +/* + * Changed the following text constant to binary so it will work on ebcdic + * machines :-) + */ +/* static char cbc_data[40]="7654321 Now is the time for \0001"; */ +static unsigned char cbc_data[40] = { + 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, + 0x66, 0x6F, 0x72, 0x20, 0x00, 0x31, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char cbc_ok[32] = { + 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, + 0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, + 0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68, + 0x1d, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4, +}; + +#ifdef SCREW_THE_PARITY +#error "SCREW_THE_PARITY is not ment to be defined." +#error "Original vectors are preserved for reference only." +static unsigned char cbc2_key[8] = { + 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, +}; +static unsigned char xcbc_ok[32] = { + 0x86, 0x74, 0x81, 0x0D, 0x61, 0xA4, 0xA5, 0x48, + 0xB9, 0x93, 0x03, 0xE1, 0xB8, 0xBB, 0xBD, 0xBD, + 0x64, 0x30, 0x0B, 0xB9, 0x06, 0x65, 0x81, 0x76, + 0x04, 0x1D, 0x77, 0x62, 0x17, 0xCA, 0x2B, 0xD2, +}; +#else +static unsigned char xcbc_ok[32] = { + 0x84, 0x6B, 0x29, 0x14, 0x85, 0x1E, 0x9A, 0x29, + 0x54, 0x73, 0x2F, 0x8A, 0xA0, 0xA6, 0x11, 0xC1, + 0x15, 0xCD, 0xC2, 0xD7, 0x95, 0x1B, 0x10, 0x53, + 0xA6, 0x3C, 0x5E, 0x03, 0xB2, 0x1A, 0xA3, 0xC4, +}; +#endif + +static unsigned char cbc3_ok[32] = { + 0x3F, 0xE3, 0x01, 0xC9, 0x62, 0xAC, 0x01, 0xD0, + 0x22, 0x13, 0x76, 0x3C, 0x1C, 0xBD, 0x4C, 0xDC, + 0x79, 0x96, 0x57, 0xC0, 0x64, 0xEC, 0xF5, 0xD4, + 0x1C, 0x67, 0x38, 0x12, 0xCF, 0xDE, 0x96, 0x75 +}; + +static unsigned char pcbc_ok[32] = { + 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, + 0x6d, 0xec, 0xb4, 0x70, 0xa0, 0xe5, 0x6b, 0x15, + 0xae, 0xa6, 0xbf, 0x61, 0xed, 0x7d, 0x9c, 0x9f, + 0xf7, 0x17, 0x46, 0x3b, 0x8a, 0xb3, 0xcc, 0x88 +}; + +static unsigned char cfb_key[8] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, +}; +static unsigned char cfb_iv[8] = { + 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, +}; +static unsigned char cfb_buf1[40], cfb_buf2[40], cfb_tmp[8]; +static unsigned char plain[24] = +{ + 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, + 0x69, 0x6d, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, +}; +static unsigned char cfb_cipher8[24] = { + 0xf3, 0x1f, 0xda, 0x07, 0x01, 0x14, + 0x62, 0xee, 0x18, 0x7f, 0x43, 0xd8, + 0x0a, 0x7c, 0xd9, 0xb5, 0xb0, 0xd2, + 0x90, 0xda, 0x6e, 0x5b, 0x9a, 0x87, +}; +static unsigned char cfb_cipher16[24] = { + 0xF3, 0x09, 0x87, 0x87, 0x7F, 0x57, + 0xF7, 0x3C, 0x36, 0xB6, 0xDB, 0x70, + 0xD8, 0xD5, 0x34, 0x19, 0xD3, 0x86, + 0xB2, 0x23, 0xB7, 0xB2, 0xAD, 0x1B, +}; +static unsigned char cfb_cipher32[24] = { + 0xF3, 0x09, 0x62, 0x49, 0xA4, 0xDF, + 0xA4, 0x9F, 0x33, 0xDC, 0x7B, 0xAD, + 0x4C, 0xC8, 0x9F, 0x64, 0xE4, 0x53, + 0xE5, 0xEC, 0x67, 0x20, 0xDA, 0xB6, +}; +static unsigned char cfb_cipher48[24] = { + 0xF3, 0x09, 0x62, 0x49, 0xC7, 0xF4, + 0x30, 0xB5, 0x15, 0xEC, 0xBB, 0x85, + 0x97, 0x5A, 0x13, 0x8C, 0x68, 0x60, + 0xE2, 0x38, 0x34, 0x3C, 0xDC, 0x1F, +}; +static unsigned char cfb_cipher64[24] = { + 0xF3, 0x09, 0x62, 0x49, 0xC7, 0xF4, + 0x6E, 0x51, 0xA6, 0x9E, 0x83, 0x9B, + 0x1A, 0x92, 0xF7, 0x84, 0x03, 0x46, + 0x71, 0x33, 0x89, 0x8E, 0xA6, 0x22, +}; + +static unsigned char ofb_key[8] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, +}; +static unsigned char ofb_iv[8] = { + 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, +}; +static unsigned char ofb_buf1[24], ofb_buf2[24], ofb_tmp[8]; +static unsigned char ofb_cipher[24] = +{ + 0xf3, 0x09, 0x62, 0x49, 0xc7, 0xf4, 0x6e, 0x51, + 0x35, 0xf2, 0x4a, 0x24, 0x2e, 0xeb, 0x3d, 0x3f, + 0x3d, 0x6d, 0x5b, 0xe3, 0x25, 0x5a, 0xf8, 0xc3 +}; + +static DES_LONG cbc_cksum_ret = 0xB462FEF7L; +static unsigned char cbc_cksum_data[8] = { + 0x1D, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4, +}; + +static char * +pt(unsigned char *p) +{ + static char bufs[10][20]; + static int bnum = 0; + char *ret; + int i; + static const char *f = "0123456789ABCDEF"; + + ret = &(bufs[bnum++][0]); + bnum %= 10; + for (i = 0; i < 8; i++) { + ret[i * 2] = f[(p[i] >> 4) & 0xf]; + ret[i * 2 + 1] = f[p[i] & 0xf]; + } + ret[16] = '\0'; + return (ret); +} + +static void +fail_cfb_buf(const char *msg, unsigned char *ptr) +{ + char buf[1024]; + int i; + + *buf = '\0'; + for (i = 0; i < 24; i += 8) { + char buf2[128]; + snprintf(buf2, sizeof(buf2), "%s /", pt(&(cfb_buf1[i]))); + strlcat(buf, buf2, sizeof(buf)); + } + + atf_tc_fail_nonfatal("%s: %s", msg, buf); +} + +#if !defined(LIBDES_LIT) +static void +cfb_test(int bits, unsigned char *cfb_cipher) +{ + des_key_schedule ks; + + des_set_key_checked(&cfb_key, ks); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + des_cfb_encrypt(plain, cfb_buf1, bits, sizeof(plain), ks, &cfb_tmp, + DES_ENCRYPT); + if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0) + fail_cfb_buf("cfb_encrypt encrypt error", cfb_buf1); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + des_cfb_encrypt(cfb_buf1, cfb_buf2, bits, sizeof(plain), ks, &cfb_tmp, + DES_DECRYPT); + if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) + fail_cfb_buf("cfb_encrypt decrypt error", cfb_buf2); +} +#endif /* !defined(LIBDES_LIT) */ + +#if !defined(LIBDES_LIT) +static void +cfb64_test(unsigned char *cfb_cipher) +{ + int n; + des_key_schedule ks; + + des_set_key_checked(&cfb_key, ks); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + n = 0; + des_cfb64_encrypt(plain, cfb_buf1, 12, ks, &cfb_tmp, &n, DES_ENCRYPT); + des_cfb64_encrypt(&(plain[12]), &(cfb_buf1[12]), sizeof(plain) - 12, ks, + &cfb_tmp, &n, DES_ENCRYPT); + if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0) + fail_cfb_buf("cfb_encrypt encrypt error", cfb_buf1); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + n = 0; + des_cfb64_encrypt(cfb_buf1, cfb_buf2, 17, ks, &cfb_tmp, &n, DES_DECRYPT); + des_cfb64_encrypt(&(cfb_buf1[17]), &(cfb_buf2[17]), + sizeof(plain) - 17, ks, &cfb_tmp, &n, DES_DECRYPT); + if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) + fail_cfb_buf("cfb_encrypt decrypt error", cfb_buf2); +} +#endif /* !defined(LIBDES_LIT) */ + +#if !defined(LIBDES_LIT) +static void +ede_cfb64_test(unsigned char *cfb_cipher) +{ + int n; + des_key_schedule ks; + + des_set_key_checked(&cfb_key, ks); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + n = 0; + des_ede3_cfb64_encrypt(plain, cfb_buf1, 12, ks, ks, ks, &cfb_tmp, &n, + DES_ENCRYPT); + des_ede3_cfb64_encrypt(&(plain[12]), &(cfb_buf1[12]), + sizeof(plain) - 12, ks, ks, ks, + &cfb_tmp, &n, DES_ENCRYPT); + if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0) + fail_cfb_buf("ede_cfb_encrypt encrypt error", cfb_buf1); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + n = 0; + des_ede3_cfb64_encrypt(cfb_buf1, cfb_buf2, (long) 17, ks, ks, ks, + &cfb_tmp, &n, DES_DECRYPT); + des_ede3_cfb64_encrypt(&(cfb_buf1[17]), &(cfb_buf2[17]), + sizeof(plain) - 17, ks, ks, ks, + &cfb_tmp, &n, DES_DECRYPT); + if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) + fail_cfb_buf("ede_cfb_encrypt decrypt error", cfb_buf2); +} +#endif /* !defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(cbcm); +#if defined(NO_DESCBCM) +ATF_TC_BODY(cbcm, tc) +{ + atf_tc_skip("Test program built with NO_DESCBCM"); +} +#else /* defined(NO_DESCBM) */ +ATF_TC_BODY(cbcm, tc) +{ + int i, j; + des_cblock iv3, iv2; + unsigned char cbc_in[40], cbc_out[40]; + des_key_schedule ks, ks2, ks3; + + if ((j = des_set_key_checked(&cbc_key, ks)) != 0) { + atf_tc_fail_nonfatal("Key error %d\n", j); + } + if ((j = des_set_key_checked(&cbc2_key, ks2)) != 0) { + atf_tc_fail_nonfatal("Key error %d\n", j); + } + if ((j = des_set_key_checked(&cbc3_key, ks3)) != 0) { + atf_tc_fail_nonfatal("Key error %d\n", j); + } + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + i = strlen((char *) cbc_data) + 1; + /* i=((i+7)/8)*8; */ + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + memset(iv2, '\0', sizeof iv2); + + des_ede3_cbcm_encrypt(cbc_data, cbc_out, 16L, ks, ks2, ks3, &iv3, &iv2, + DES_ENCRYPT); + des_ede3_cbcm_encrypt(&cbc_data[16], &cbc_out[16], i - 16, ks, ks2, ks3, + &iv3, &iv2, DES_ENCRYPT); + /* + * if (memcmp(cbc_out,cbc3_ok, (unsigned int)(strlen((char + * *)cbc_data)+1+7)/8*8) != 0) { printf("des_ede3_cbc_encrypt encrypt + * error\n"); err=1; } + */ + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + memset(iv2, '\0', sizeof iv2); + des_ede3_cbcm_encrypt(cbc_out, cbc_in, i, ks, ks2, ks3, &iv3, &iv2, + DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0) { + char buf[1024]; + int n; + + *buf = '\0'; + for (n = 0; n < i; ++n) { + char buf2[16]; + snprintf(buf2, sizeof(buf2), " %02x", cbc_data[n]); + strlcat(buf, buf2, sizeof(buf)); + } + strlcat(buf, ", ", sizeof(buf)); + for (n = 0; n < i; ++n) { + char buf2[16]; + snprintf(buf2, sizeof(buf2), " %02x", cbc_in[n]); + strlcat(buf, buf2, sizeof(buf)); + } + + atf_tc_fail_nonfatal("des_ede3_cbcm_encrypt decrypt error: %s", + buf); + } +} +#endif /* defined(NO_DESCBM) */ + +ATF_TC_WITHOUT_HEAD(ecb); +ATF_TC_BODY(ecb, tc) +{ + int i; + des_cblock in, out, outin; + des_key_schedule ks; + + for (i = 0; i < NUM_TESTS; i++) { + des_set_key_unchecked(&key_data[i], ks); + memcpy(in, plain_data[i], 8); + memset(out, 0, 8); + memset(outin, 0, 8); + des_ecb_encrypt(&in, &out, ks, DES_ENCRYPT); + des_ecb_encrypt(&out, &outin, ks, DES_DECRYPT); + + if (memcmp(out, cipher_data[i], 8) != 0) { + atf_tc_fail_nonfatal("Encryption error %2d\nk=%s p=%s " + "o=%s act=%s\n", i + 1, + pt(key_data[i]), pt(in), + pt(cipher_data[i]), pt(out)); + } + if (memcmp(in, outin, 8) != 0) { + atf_tc_fail_nonfatal("Decryption error %2d\nk=%s p=%s " + "o=%s act=%s\n", i + 1, + pt(key_data[i]), pt(out), pt(in), + pt(outin)); + } + } +} + +ATF_TC_WITHOUT_HEAD(ede_ecb); +#if defined(LIBDES_LIT) +ATF_TC_BODY(ede_ecb, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(ede_ecb, tc) +{ + int i; + des_cblock in, out, outin; + des_key_schedule ks, ks2, ks3; + + for (i = 0; i < (NUM_TESTS - 1); i++) { + des_set_key_unchecked(&key_data[i], ks); + des_set_key_unchecked(&key_data[i + 1], ks2); + des_set_key_unchecked(&key_data[i + 2], ks3); + memcpy(in, plain_data[i], 8); + memset(out, 0, 8); + memset(outin, 0, 8); + des_ecb2_encrypt(&in, &out, ks, ks2, DES_ENCRYPT); + des_ecb2_encrypt(&out, &outin, ks, ks2, DES_DECRYPT); + + if (memcmp(out, cipher_ecb2[i], 8) != 0) { + atf_tc_fail_nonfatal("Encryption error %2d\nk=%s p=%s o=%s act=%s\n", + i + 1, pt(key_data[i]), pt(in), pt(cipher_ecb2[i]), + pt(out)); + } + if (memcmp(in, outin, 8) != 0) { + atf_tc_fail_nonfatal("Decryption error %2d\nk=%s p=%s o=%s act=%s\n", + i + 1, pt(key_data[i]), pt(out), pt(in), pt(outin)); + } + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(cbc); +ATF_TC_BODY(cbc, tc) +{ + int j; + des_cblock iv3; + des_key_schedule ks; + unsigned char cbc_in[40], cbc_out[40]; + + if ((j = des_set_key_checked(&cbc_key, ks)) != 0) + atf_tc_fail_nonfatal("Key error %d\n", j); + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_ncbc_encrypt(cbc_data, cbc_out, strlen((char *) cbc_data) + 1, ks, + &iv3, DES_ENCRYPT); + if (memcmp(cbc_out, cbc_ok, 32) != 0) + atf_tc_fail_nonfatal("cbc_encrypt encrypt error\n"); + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_ncbc_encrypt(cbc_out, cbc_in, strlen((char *) cbc_data) + 1, ks, + &iv3, DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data)) != 0) + atf_tc_fail_nonfatal("cbc_encrypt decrypt error\n"); +} + +ATF_TC_WITHOUT_HEAD(desx_cbc); +#if defined(LIBDES_LIT) +ATF_TC_BODY(desx_cbc, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(desx_cbc, tc) +{ + int j; + des_cblock iv3; + des_key_schedule ks; + unsigned char cbc_in[40], cbc_out[40]; + + if ((j = des_set_key_checked(&cbc_key, ks)) != 0) { + atf_tc_fail_nonfatal("Key error %d\n", j); + } + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_xcbc_encrypt(cbc_data, cbc_out, strlen((char *) cbc_data) + 1, ks, + &iv3, &cbc2_key, &cbc3_key, DES_ENCRYPT); + if (memcmp(cbc_out, xcbc_ok, 32) != 0) { + atf_tc_fail_nonfatal("des_xcbc_encrypt encrypt error\n"); + } + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_xcbc_encrypt(cbc_out, cbc_in, strlen((char *) cbc_data) + 1, ks, + &iv3, &cbc2_key, &cbc3_key, DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0) { + atf_tc_fail_nonfatal("des_xcbc_encrypt decrypt error\n"); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(ede_cbc); +ATF_TC_BODY(ede_cbc, tc) +{ + int i, j; + des_cblock iv3; + des_key_schedule ks, ks2, ks3; + unsigned char cbc_in[40], cbc_out[40]; + + if ((j = des_set_key_checked(&cbc_key, ks)) != 0) + atf_tc_fail_nonfatal("Key error %d\n", j); + if ((j = des_set_key_checked(&cbc2_key, ks2)) != 0) + atf_tc_fail_nonfatal("Key error %d\n", j); + if ((j = des_set_key_checked(&cbc3_key, ks3)) != 0) + atf_tc_fail_nonfatal("Key error %d\n", j); + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + i = strlen((char *) cbc_data) + 1; + /* i=((i+7)/8)*8; */ + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + + des_ede3_cbc_encrypt(cbc_data, cbc_out, 16L, ks, ks2, ks3, &iv3, + DES_ENCRYPT); + des_ede3_cbc_encrypt(&(cbc_data[16]), &(cbc_out[16]), i - 16, ks, ks2, + ks3, &iv3, DES_ENCRYPT); + if (memcmp(cbc_out, cbc3_ok, (unsigned int) + (strlen((char *) cbc_data) + 1 + 7) / 8 * 8) != 0) + atf_tc_fail_nonfatal("des_ede3_cbc_encrypt encrypt error\n"); + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_ede3_cbc_encrypt(cbc_out, cbc_in, i, ks, ks2, ks3, &iv3, + DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0) + atf_tc_fail_nonfatal("des_ede3_cbc_encrypt decrypt error\n"); +} + +ATF_TC_WITHOUT_HEAD(pcbc); +#if defined(LIBDES_LIT) +ATF_TC_BODY(pcbc, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(pcbc, tc) +{ + int j; + unsigned char cbc_in[40], cbc_out[40]; + des_key_schedule ks; + + if ((j = des_set_key_checked(&cbc_key, ks)) != 0) { + atf_tc_fail_nonfatal("Key error %d\n", j); + } + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + des_pcbc_encrypt(cbc_data, cbc_out, strlen((char *) cbc_data) + 1, ks, + &cbc_iv, DES_ENCRYPT); + if (memcmp(cbc_out, pcbc_ok, 32) != 0) { + atf_tc_fail_nonfatal("pcbc_encrypt encrypt error\n"); + } + des_pcbc_encrypt(cbc_out, cbc_in, strlen((char *) cbc_data) + 1, ks, &cbc_iv, + DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0) { + atf_tc_fail_nonfatal("pcbc_encrypt decrypt error\n"); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(cfb); +#if defined(LIBDES_LIT) +ATF_TC_BODY(cfb, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(cfb, tc) +{ + size_t i; + des_key_schedule ks; + + printf("cfb8\n"); + cfb_test(8, cfb_cipher8); + printf("cfb16\n"); + cfb_test(16, cfb_cipher16); + printf("cfb32\n"); + cfb_test(32, cfb_cipher32); + printf("cfb48\n"); + cfb_test(48, cfb_cipher48); + printf("cfb64\n"); + cfb_test(64, cfb_cipher64); + + printf("cfb64()\n"); + cfb64_test(cfb_cipher64); + + des_set_key_checked(&cfb_key, ks); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + for (i = 0; i < sizeof(plain); i++) + des_cfb_encrypt(&(plain[i]), &(cfb_buf1[i]), + 8, 1, ks, &cfb_tmp, DES_ENCRYPT); + if (memcmp(cfb_cipher8, cfb_buf1, sizeof(plain)) != 0) + atf_tc_fail_nonfatal("cfb_encrypt small encrypt error\n"); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + for (i = 0; i < sizeof(plain); i++) + des_cfb_encrypt(&(cfb_buf1[i]), &(cfb_buf2[i]), + 8, 1, ks, &cfb_tmp, DES_DECRYPT); + if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) + atf_tc_fail_nonfatal("cfb_encrypt small decrypt error\n"); + printf("ede_cfb64()\n"); + ede_cfb64_test(cfb_cipher64); +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(ofb); +#if defined(LIBDES_LIT) +ATF_TC_BODY(ofb, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(ofb, tc) +{ + des_key_schedule ks; + + des_set_key_checked(&ofb_key, ks); + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + des_ofb_encrypt(plain, ofb_buf1, 64, sizeof(plain) / 8, ks, &ofb_tmp); + if (memcmp(ofb_cipher, ofb_buf1, sizeof(ofb_buf1)) != 0) { + atf_tc_fail_nonfatal("ofb_encrypt encrypt error: " + "%02X %02X %02X %02X %02X %02X %02X %02X, " + "%02X %02X %02X %02X %02X %02X %02X %02X", + ofb_buf1[8 + 0], ofb_buf1[8 + 1], + ofb_buf1[8 + 2], ofb_buf1[8 + 3], + ofb_buf1[8 + 4], ofb_buf1[8 + 5], + ofb_buf1[8 + 6], ofb_buf1[8 + 7], + ofb_buf1[8 + 0], ofb_cipher[8 + 1], + ofb_cipher[8 + 2], ofb_cipher[8 + 3], + ofb_buf1[8 + 4], ofb_cipher[8 + 5], + ofb_cipher[8 + 6], ofb_cipher[8 + 7]); + } + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + des_ofb_encrypt(ofb_buf1, ofb_buf2, 64, sizeof(ofb_buf1) / 8, ks, + &ofb_tmp); + if (memcmp(plain, ofb_buf2, sizeof(ofb_buf2)) != 0) { + atf_tc_fail_nonfatal("ofb_encrypt decrypt error: " + "%02X %02X %02X %02X %02X %02X %02X %02X, " + "%02X %02X %02X %02X %02X %02X %02X %02X", + ofb_buf2[8 + 0], ofb_buf2[8 + 1], + ofb_buf2[8 + 2], ofb_buf2[8 + 3], + ofb_buf2[8 + 4], ofb_buf2[8 + 5], + ofb_buf2[8 + 6], ofb_buf2[8 + 7], + plain[8 + 0], plain[8 + 1], + plain[8 + 2], plain[8 + 3], + plain[8 + 4], plain[8 + 5], + plain[8 + 6], plain[8 + 7]); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(ofb64); +#if defined(LIBDES_LIT) +ATF_TC_BODY(ofb64, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(ofb64, tc) +{ + int num; + size_t i; + des_key_schedule ks; + + des_set_key_checked(&ofb_key, ks); + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + memset(ofb_buf1, 0, sizeof(ofb_buf1)); + memset(ofb_buf2, 0, sizeof(ofb_buf1)); + num = 0; + for (i = 0; i < sizeof(plain); i++) { + des_ofb64_encrypt(&(plain[i]), &(ofb_buf1[i]), 1, ks, &ofb_tmp, + &num); + } + if (memcmp(ofb_cipher, ofb_buf1, sizeof(ofb_buf1)) != 0) { + atf_tc_fail_nonfatal("ofb64_encrypt encrypt error\n"); + } + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + num = 0; + des_ofb64_encrypt(ofb_buf1, ofb_buf2, sizeof(ofb_buf1), ks, &ofb_tmp, &num); + if (memcmp(plain, ofb_buf2, sizeof(ofb_buf2)) != 0) { + atf_tc_fail_nonfatal("ofb64_encrypt decrypt error\n"); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(ede_ofb64); +#if defined(LIBDES_LIT) +ATF_TC_BODY(ede_ofb64, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(ede_ofb64, tc) +{ + int num; + size_t i; + des_key_schedule ks; + + des_set_key_checked(&ofb_key, ks); + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + memset(ofb_buf1, 0, sizeof(ofb_buf1)); + memset(ofb_buf2, 0, sizeof(ofb_buf1)); + num = 0; + for (i = 0; i < sizeof(plain); i++) { + des_ede3_ofb64_encrypt(&(plain[i]), &(ofb_buf1[i]), 1, ks, ks, ks, + &ofb_tmp, &num); + } + if (memcmp(ofb_cipher, ofb_buf1, sizeof(ofb_buf1)) != 0) { + atf_tc_fail_nonfatal("ede_ofb64_encrypt encrypt error\n"); + } + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + num = 0; + des_ede3_ofb64_encrypt(ofb_buf1, ofb_buf2, sizeof(ofb_buf1), ks, + ks, ks, &ofb_tmp, &num); + if (memcmp(plain, ofb_buf2, sizeof(ofb_buf2)) != 0) { + atf_tc_fail_nonfatal("ede_ofb64_encrypt decrypt error\n"); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(cbc_cksum); +#if defined(LIBDES_LIT) +ATF_TC_BODY(cbc_cksum, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(cbc_cksum, tc) +{ + unsigned char cret[8]; + des_key_schedule ks; + DES_LONG cs; + + des_set_key_checked(&cbc_key, ks); + cs = des_cbc_cksum(cbc_data, &cret, strlen((char *) cbc_data), ks, &cbc_iv); + if (cs != cbc_cksum_ret) { + atf_tc_fail_nonfatal("bad return value (%08lX), should be %08lX\n", + (unsigned long) cs, (unsigned long) cbc_cksum_ret); + } + if (memcmp(cret, cbc_cksum_data, 8) != 0) { + atf_tc_fail_nonfatal("bad cbc_cksum block returned\n"); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(quad_cksum); +#if defined(LIBDES_LIT) +ATF_TC_BODY(quad_cksum, tc) +{ + atf_tc_skip("Test program built with LIBDES_LIT"); +} +#else /* defined(LIBDES_LIT) */ +ATF_TC_BODY(quad_cksum, tc) +{ + DES_LONG cs, lqret[4]; + + cs = quad_cksum(cbc_data, (des_cblock *) lqret, + (long) strlen((char *) cbc_data), 2, (des_cblock *) cbc_iv); + if (cs != 0x70d7a63aL) { + atf_tc_fail_nonfatal("quad_cksum error, ret %08lx should be 70d7a63a\n", + (unsigned long) cs); + } + if (lqret[0] != 0x327eba8dL) { + atf_tc_fail_nonfatal("quad_cksum error, out[0] %08lx is not %08lx\n", + (unsigned long) lqret[0], 0x327eba8dUL); + } + if (lqret[1] != 0x201a49ccL) { + atf_tc_fail_nonfatal("quad_cksum error, out[1] %08lx is not %08lx\n", + (unsigned long) lqret[1], 0x201a49ccUL); + } + if (lqret[2] != 0x70d7a63aL) { + atf_tc_fail_nonfatal("quad_cksum error, out[2] %08lx is not %08lx\n", + (unsigned long) lqret[2], 0x70d7a63aUL); + } + if (lqret[3] != 0x501c2c26L) { + atf_tc_fail_nonfatal("quad_cksum error, out[3] %08lx is not %08lx\n", + (unsigned long) lqret[3], 0x501c2c26UL); + } +} +#endif /* defined(LIBDES_LIT) */ + +ATF_TC_WITHOUT_HEAD(align); +ATF_TC_BODY(align, tc) +{ + int i; + unsigned char cbc_in[40], cbc_out[40]; + des_key_schedule ks; + + printf("input word alignment test"); + for (i = 0; i < 4; i++) { + printf(" %d", i); + des_ncbc_encrypt(&(cbc_out[i]), cbc_in, + strlen((char *) cbc_data) + 1, ks, + &cbc_iv, DES_ENCRYPT); + } + + printf("\noutput word alignment test"); + for (i = 0; i < 4; i++) { + printf(" %d", i); + des_ncbc_encrypt(cbc_out, &(cbc_in[i]), + strlen((char *) cbc_data) + 1, ks, + &cbc_iv, DES_ENCRYPT); + } +} + +ATF_TC_WITHOUT_HEAD(fast_crypt); +ATF_TC_BODY(fast_crypt, tc) +{ + char *str; + + str = crypt("testing", "ef"); + if (strcmp("efGnQx2725bI2", str) != 0) + atf_tc_fail_nonfatal("fast crypt error, %s should be efGnQx2725bI2\n", str); + str = crypt("bca76;23", "yA"); + if (strcmp("yA1Rp/1hZXIJk", str) != 0) + atf_tc_fail_nonfatal("fast crypt error, %s should be yA1Rp/1hZXIJk\n", str); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cbcm); + ATF_TP_ADD_TC(tp, ecb); + ATF_TP_ADD_TC(tp, ede_ecb); + ATF_TP_ADD_TC(tp, cbc); + ATF_TP_ADD_TC(tp, desx_cbc); + ATF_TP_ADD_TC(tp, ede_cbc); + ATF_TP_ADD_TC(tp, pcbc); + ATF_TP_ADD_TC(tp, cfb); + ATF_TP_ADD_TC(tp, ofb); + ATF_TP_ADD_TC(tp, ofb64); + ATF_TP_ADD_TC(tp, ede_ofb64); + ATF_TP_ADD_TC(tp, cbc_cksum); + ATF_TP_ADD_TC(tp, quad_cksum); + ATF_TP_ADD_TC(tp, align); + ATF_TP_ADD_TC(tp, fast_crypt); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libevent/t_event.sh b/contrib/netbsd-tests/lib/libevent/t_event.sh new file mode 100755 index 0000000..1e4c9bc --- /dev/null +++ b/contrib/netbsd-tests/lib/libevent/t_event.sh @@ -0,0 +1,67 @@ +# $NetBSD: t_event.sh,v 1.3 2010/11/29 18:21:15 pgoyette Exp $ +# +# Copyright (c) 2009 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# This is not great but rather than reimplementing the libevent +# provided regression tests, we use an ATF wrapper around the test +# program which carries out all the tests and prints an extensive +# report. +# + +atf_test_case kqueue +kqueue_head() { + atf_set "descr" "Test libevent with kqueue backend" +} +kqueue_body() { + EVENT_NOPOLL=1 EVENT_NOSELECT=1 \ + $(atf_get_srcdir)/h_event 2>&1 || atf_fail "check report" +} + +atf_test_case poll +poll_head() { + atf_set "descr" "Test libevent with poll backend" +} +poll_body() { + EVENT_NOKQUEUE=1 EVENT_NOSELECT=1 \ + $(atf_get_srcdir)/h_event 2>&1 || atf_fail "check report" +} + +atf_test_case select +select_head() { + atf_set "descr" "Test libevent with select backend" +} +select_body() { + EVENT_NOKQUEUE=1 EVENT_NOPOLL=1 \ + $(atf_get_srcdir)/h_event 2>&1 || atf_fail "check report" +} + +atf_init_test_cases() +{ + atf_add_test_case kqueue + atf_add_test_case poll + atf_add_test_case select +} diff --git a/contrib/netbsd-tests/lib/libexecinfo/t_backtrace.c b/contrib/netbsd-tests/lib/libexecinfo/t_backtrace.c new file mode 100644 index 0000000..00f716e --- /dev/null +++ b/contrib/netbsd-tests/lib/libexecinfo/t_backtrace.c @@ -0,0 +1,167 @@ +/* $NetBSD: t_backtrace.c,v 1.16 2014/11/04 00:20:19 justin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_backtrace.c,v 1.16 2014/11/04 00:20:19 justin Exp $"); + +#include +#include +#include +#include +#include +#include + +#ifndef __arraycount +#define __arraycount(a) (sizeof(a) / sizeof(a[0])) +#endif + +void myfunc3(size_t ncalls); +void myfunc2(size_t ncalls); +void myfunc1(size_t origcalls, volatile size_t ncalls); +void myfunc(size_t ncalls); + +volatile int prevent_inline; + +void +myfunc3(size_t ncalls) +{ + static const struct { + const char *name; + bool is_optional; + } frames[] = { + { "myfunc", false }, + { "atfu_backtrace_fmt_basic_body", false }, + { "atf_tc_run", false }, + { "atf_tp_run", true }, + { "run_tc", true }, + { "controlled_main", true }, + { "atf_tp_main", false }, + { "main", true }, + { "___start", true }, + }; + size_t j, nptrs, min_frames, max_frames; + void *buffer[ncalls + 10]; + char **strings; + + min_frames = 0; + max_frames = 0; + for (j = 0; j < __arraycount(frames); ++j) { + if (!frames[j].is_optional) + ++min_frames; + ++max_frames; + } + nptrs = backtrace(buffer, __arraycount(buffer)); + ATF_REQUIRE(nptrs != (size_t)-1); + strings = backtrace_symbols_fmt(buffer, nptrs, "%n"); + + ATF_CHECK(strings != NULL); + + printf("got nptrs=%zu ncalls=%zu (min_frames: %zu, max_frames: %zu)\n", + nptrs, ncalls, min_frames, max_frames); + printf("backtrace is:\n"); + for (j = 0; j < nptrs; j++) { + printf("#%zu: %s\n", j, strings[j]); + } + + ATF_REQUIRE(nptrs >= ncalls + 2 + min_frames); + ATF_REQUIRE(nptrs <= ncalls + 2 + max_frames); + ATF_CHECK_STREQ(strings[0], "myfunc3"); + ATF_CHECK_STREQ(strings[1], "myfunc2"); + + for (j = 2; j < ncalls + 2; j++) + ATF_CHECK_STREQ(strings[j], "myfunc1"); + + for (size_t i = 0; j < nptrs; i++, j++) { + if (frames[i].is_optional && + strcmp(strings[j], frames[i].name)) { + --i; + continue; + } + ATF_CHECK_STREQ(strings[j], frames[i].name); + } + + free(strings); + + if (prevent_inline) + vfork(); +} + +void +myfunc2(size_t ncalls) +{ + myfunc3(ncalls); + + if (prevent_inline) + vfork(); +} + +void +myfunc1(size_t origcalls, volatile size_t ncalls) +{ + if (ncalls > 1) + myfunc1(origcalls, ncalls - 1); + else + myfunc2(origcalls); + + if (prevent_inline) + vfork(); +} + +void +myfunc(size_t ncalls) +{ + myfunc1(ncalls, ncalls); + + if (prevent_inline) + vfork(); +} + +ATF_TC(backtrace_fmt_basic); +ATF_TC_HEAD(backtrace_fmt_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test backtrace_fmt(3)"); + atf_tc_set_md_var(tc, "require.files", "/proc/self"); +} + +ATF_TC_BODY(backtrace_fmt_basic, tc) +{ + myfunc(12); + + if (prevent_inline) + vfork(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, backtrace_fmt_basic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_acos.c b/contrib/netbsd-tests/lib/libm/t_acos.c new file mode 100644 index 0000000..f051fb6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_acos.c @@ -0,0 +1,105 @@ +/* $NetBSD: t_acos.c,v 1.10 2014/03/05 20:14:46 dsl Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include "t_libm.h" + +/* + * acos(3) and acosf(3) + */ + +ATF_LIBM_TEST(acos_is_nan, "Test acos/acosf(x) == NaN, x = NaN, +/-Inf, ![-1..1]") +{ + static const double x[] = { + -1.000000001, 1.000000001, + -1.0000001, 1.0000001, + -1.1, 1.1, +#ifndef __vax__ + T_LIBM_NAN, + T_LIBM_MINUS_INF, T_LIBM_PLUS_INF, +#endif + }; + unsigned int i; + + for (i = 0; i < __arraycount(x); i++) { + T_LIBM_CHECK_NAN(i, acos, x[i]); + if (i < 2) + /* Values are too small for float */ + continue; + T_LIBM_CHECK_NAN(i, acosf, x[i]); + } +} + +ATF_LIBM_TEST(acos_inrange, "Test acos/acosf(x) for some valid values") +{ + static const struct { + double x; + double y; + } values[] = { + { -1, M_PI, }, + { -0.99, 3.000053180265366, }, + { -0.5, 2.094395102393195, }, + { -0.1, 1.670963747956456, }, + { 0, M_PI / 2, }, + { 0.1, 1.470628905633337, }, + { 0.5, 1.047197551196598, }, + { 0.99, 0.141539473324427, }, + }; + unsigned int i; + + /* + * Note that acos(x) might be calculated as atan2(sqrt(1-x*x),x). + * This means that acos(-1) is atan2(+0,-1), if the sign is wrong + * the value will be -M_PI (atan2(-0,-1)) not M_PI. + */ + + for (i = 0; i < __arraycount(values); i++) { + T_LIBM_CHECK(i, acos, values[i].x, values[i].y, 1.0e-15); + T_LIBM_CHECK(i, acosf, values[i].x, values[i].y, 1.0e-5); + } +} + +ATF_LIBM_TEST(acos_is_plus_zero, "Test acosf(1.0) == +0.0") +{ + T_LIBM_CHECK_PLUS_ZERO(0, acos, 1.0); + T_LIBM_CHECK_PLUS_ZERO(0, acosf, 1.0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, acos_inrange); + ATF_TP_ADD_TC(tp, acos_is_nan); + ATF_TP_ADD_TC(tp, acos_is_plus_zero); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_asin.c b/contrib/netbsd-tests/lib/libm/t_asin.c new file mode 100644 index 0000000..06de852 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_asin.c @@ -0,0 +1,296 @@ +/* $NetBSD: t_asin.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +static const struct { + double x; + double y; +} values[] = { + { -1.0, -M_PI / 2, }, + { -0.9, -1.119769514998634, }, + { -0.5, -M_PI / 6, }, + { -0.1, -0.1001674211615598, }, + { 0.1, 0.1001674211615598, }, + { 0.5, M_PI / 6, }, + { 0.9, 1.119769514998634, }, + { 1.0, M_PI / 2, }, +}; + +/* + * asin(3) + */ +ATF_TC(asin_nan); +ATF_TC_HEAD(asin_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(NaN) == NaN"); +} + +ATF_TC_BODY(asin_nan, tc) +{ + const double x = 0.0L / 0.0L; + + if (isnan(asin(x)) == 0) + atf_tc_fail_nonfatal("asin(NaN) != NaN"); +} + +ATF_TC(asin_inf_neg); +ATF_TC_HEAD(asin_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(-Inf) == NaN"); +} + +ATF_TC_BODY(asin_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + if (isnan(asin(x)) == 0) + atf_tc_fail_nonfatal("asin(-Inf) != NaN"); +} + +ATF_TC(asin_inf_pos); +ATF_TC_HEAD(asin_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(+Inf) == NaN"); +} + +ATF_TC_BODY(asin_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + if (isnan(asin(x)) == 0) + atf_tc_fail_nonfatal("asin(+Inf) != NaN"); +} + +ATF_TC(asin_range); +ATF_TC_HEAD(asin_range, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(x) == NaN, x < -1, x > 1"); +} + +ATF_TC_BODY(asin_range, tc) +{ + const double x[] = { -1.1, -1.000000001, 1.1, 1.000000001 }; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + if (isnan(asin(x[i])) == 0) + atf_tc_fail_nonfatal("asin(%f) != NaN", x[i]); + } +} + +ATF_TC(asin_inrange); +ATF_TC_HEAD(asin_inrange, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(x) for some values"); +} + +ATF_TC_BODY(asin_inrange, tc) +{ + const double eps = 1.0e-15; + double y; + size_t i; + + for (i = 0; i < __arraycount(values); i++) { + y = asin(values[i].x); + if (fabs(y - values[i].y) > eps) + atf_tc_fail_nonfatal("asin(%g) != %g", + values[i].x, values[i].y); + } +} + +ATF_TC(asin_zero_neg); +ATF_TC_HEAD(asin_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(-0.0) == -0.0"); +} + +ATF_TC_BODY(asin_zero_neg, tc) +{ + const double x = -0.0L; + double y = asin(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("asin(-0.0) != -0.0"); +} + +ATF_TC(asin_zero_pos); +ATF_TC_HEAD(asin_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asin(+0.0) == +0.0"); +} + +ATF_TC_BODY(asin_zero_pos, tc) +{ + const double x = 0.0L; + double y = asin(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("asin(+0.0) != +0.0"); +} + +/* + * asinf(3) + */ +ATF_TC(asinf_nan); +ATF_TC_HEAD(asinf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(NaN) == NaN"); +} + +ATF_TC_BODY(asinf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + if (isnan(asinf(x)) == 0) + atf_tc_fail_nonfatal("asinf(NaN) != NaN"); +} + +ATF_TC(asinf_inf_neg); +ATF_TC_HEAD(asinf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(-Inf) == NaN"); +} + +ATF_TC_BODY(asinf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (isnan(asinf(x)) == 0) + atf_tc_fail_nonfatal("asinf(-Inf) != NaN"); +} + +ATF_TC(asinf_inf_pos); +ATF_TC_HEAD(asinf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(+Inf) == NaN"); +} + +ATF_TC_BODY(asinf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + if (isnan(asinf(x)) == 0) + atf_tc_fail_nonfatal("asinf(+Inf) != NaN"); +} + +ATF_TC(asinf_range); +ATF_TC_HEAD(asinf_range, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(x) == NaN, x < -1, x > 1"); +} + +ATF_TC_BODY(asinf_range, tc) +{ + const float x[] = { -1.1, -1.0000001, 1.1, 1.0000001 }; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + if (isnan(asinf(x[i])) == 0) + atf_tc_fail_nonfatal("asinf(%f) != NaN", x[i]); + } +} + +ATF_TC(asinf_inrange); +ATF_TC_HEAD(asinf_inrange, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(x) for some values"); +} + +ATF_TC_BODY(asinf_inrange, tc) +{ + const float eps = 1.0e-6; + float x; + float y; + size_t i; + + for (i = 0; i < __arraycount(values); i++) { + x = values[i].x; + y = values[i].y; + if (fabs(asinf(x) - y) > eps) + atf_tc_fail_nonfatal("asinf(%g) != %g", x, y); + } +} + +ATF_TC(asinf_zero_neg); +ATF_TC_HEAD(asinf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(-0.0) == -0.0"); +} + +ATF_TC_BODY(asinf_zero_neg, tc) +{ + const float x = -0.0L; + float y = asinf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("asinf(-0.0) != -0.0"); +} + +ATF_TC(asinf_zero_pos); +ATF_TC_HEAD(asinf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test asinf(+0.0) == +0.0"); +} + +ATF_TC_BODY(asinf_zero_pos, tc) +{ + const float x = 0.0L; + float y = asinf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("asinf(+0.0) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, asin_nan); + ATF_TP_ADD_TC(tp, asin_inf_neg); + ATF_TP_ADD_TC(tp, asin_inf_pos); + ATF_TP_ADD_TC(tp, asin_range); + ATF_TP_ADD_TC(tp, asin_inrange); + ATF_TP_ADD_TC(tp, asin_zero_neg); + ATF_TP_ADD_TC(tp, asin_zero_pos); + + ATF_TP_ADD_TC(tp, asinf_nan); + ATF_TP_ADD_TC(tp, asinf_inf_neg); + ATF_TP_ADD_TC(tp, asinf_inf_pos); + ATF_TP_ADD_TC(tp, asinf_range); + ATF_TP_ADD_TC(tp, asinf_inrange); + ATF_TP_ADD_TC(tp, asinf_zero_neg); + ATF_TP_ADD_TC(tp, asinf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_atan.c b/contrib/netbsd-tests/lib/libm/t_atan.c new file mode 100644 index 0000000..c3aa15f --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_atan.c @@ -0,0 +1,101 @@ +/* $NetBSD: t_atan.c,v 1.15 2014/03/17 11:08:11 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include "t_libm.h" + +static const struct { + double x; + double y; +} values[] = { +#ifndef __vax__ + /* vax has no +/- INF */ + { T_LIBM_MINUS_INF, -M_PI / 2 }, + { T_LIBM_PLUS_INF, M_PI / 2 }, +#endif + { -100, -1.560796660108231, }, + { -10, -1.471127674303735, }, + { -1, -M_PI / 4, }, + { -0.1, -0.09966865249116204, }, + { 0.1, 0.09966865249116204, }, + { 1, M_PI / 4, }, + { 10, 1.471127674303735, }, + { 100, 1.560796660108231, }, +}; + +/* + * atan(3) + */ +ATF_LIBM_TEST(atan_nan, "Test atan/atanf(NaN) == NaN") +{ +#ifdef T_LIBM_NAN + T_LIBM_CHECK_NAN(0, atan, T_LIBM_NAN); + T_LIBM_CHECK_NAN(0, atanf, T_LIBM_NAN); +#else + atf_tc_skip("no NaN on this machine"); +#endif +} + +ATF_LIBM_TEST(atan_inrange, "Test atan/atanf(x) for some values") +{ + unsigned int i; + + for (i = 0; i < __arraycount(values); i++) { + T_LIBM_CHECK(i, atan, values[i].x, values[i].y, 1.0e-15); + T_LIBM_CHECK(i, atanf, values[i].x, values[i].y, 1.0e-7); + } +} + +ATF_LIBM_TEST(atan_zero_neg, "Test atan/atanf(-0.0) == -0.0") +{ + + T_LIBM_CHECK_MINUS_ZERO(0, atan, -0.0); + T_LIBM_CHECK_MINUS_ZERO(0, atanf, -0.0); +} + +ATF_LIBM_TEST(atan_zero_pos, "Test atan/atanf(+0.0) == +0.0") +{ + + T_LIBM_CHECK_PLUS_ZERO(0, atan, +0.0); + T_LIBM_CHECK_PLUS_ZERO(0, atanf, +0.0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, atan_nan); + ATF_TP_ADD_TC(tp, atan_inrange); + ATF_TP_ADD_TC(tp, atan_zero_neg); + ATF_TP_ADD_TC(tp, atan_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_casinh.c b/contrib/netbsd-tests/lib/libm/t_casinh.c new file mode 100644 index 0000000..f9f93c3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_casinh.c @@ -0,0 +1,81 @@ +/* $NetBSD: t_casinh.c,v 1.2 2016/09/20 17:19:28 christos Exp $ */ + +/* + * Written by Maya Rashish + * Public domain. + * + * Testing special values of casinh + * Values from ISO/IEC 9899:201x G.6.2.2 + */ + +#include +#include +#include + +#define RE(z) (((double *)(&z))[0]) +#define IM(z) (((double *)(&z))[1]) + +static const struct { + double input_re; + double input_im; + double result_re; + double result_im; +} values[] = { + { +0, +0, +0, +0}, + { +5.032E3, +INFINITY, +INFINITY, +M_PI/2}, + { +INFINITY, +5.023E3, +INFINITY, +0}, + { +INFINITY, +INFINITY, +INFINITY, +M_PI/4}, +#ifdef __HAVE_NANF + { +INFINITY, +NAN, +INFINITY, +NAN}, + { +5.032E3, +NAN, +NAN, +NAN}, /* + FE_INVALID optionally raised */ + { +NAN, +0, +NAN, +0}, + { +NAN, -5.023E3, +NAN, +NAN}, /* + FE_INVALID optionally raised */ + { +NAN, +INFINITY, +INFINITY, +NAN}, /* sign of real part of result unspecified */ + { +NAN, +NAN, +NAN, +NAN}, +#endif +}; + +#ifdef __HAVE_NANF +#define both_nan(a,b) (isnan(a) && isnan(b)) +#else +#define both_nan(a,b) 0 +#endif + +#define crude_equality(a,b) ((a == b) || both_nan(a,b)) + +#define ATF_COMPLEX_EQUAL(a,b) do { \ + complex double ci = casinh(a); \ + ATF_CHECK_MSG(crude_equality(creal(ci),creal(b)) && \ + crude_equality(cimag(ci), cimag(b)), \ + "for casinh([%g,%g]) = [%g,%g] != [%g,%g]", \ + creal(a), cimag(a), creal(ci), cimag(ci), creal(b), cimag(b)); \ +} while (0/*CONSTCOND*/) + + +ATF_TC(casinh); +ATF_TC_HEAD(casinh, tc) +{ + atf_tc_set_md_var(tc, "descr","Check casinh family - special values"); +} + +ATF_TC_BODY(casinh, tc) +{ + complex double input; + complex double result; + unsigned int i; + for (i = 0; i < __arraycount(values); i++) { + RE(input) = values[i].input_re; + IM(input) = values[i].input_im; + RE(result) = values[i].result_re; + IM(result) = values[i].result_im; + ATF_COMPLEX_EQUAL(input, result); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, casinh); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_cbrt.c b/contrib/netbsd-tests/lib/libm/t_cbrt.c new file mode 100644 index 0000000..b19413a --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_cbrt.c @@ -0,0 +1,374 @@ +/* $NetBSD: t_cbrt.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_cbrt.c,v 1.3 2014/03/03 10:39:08 martin Exp $"); + +#include +#include +#include + +/* + * cbrt(3) + */ +ATF_TC(cbrt_nan); +ATF_TC_HEAD(cbrt_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrt(NaN) == NaN"); +} + +ATF_TC_BODY(cbrt_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cbrt(x)) != 0); +} + +ATF_TC(cbrt_pow); +ATF_TC_HEAD(cbrt_pow, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrt(3) vs. pow(3)"); +} + +ATF_TC_BODY(cbrt_pow, tc) +{ + const double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 }; + const double eps = 1.0e-14; + double y, z; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + y = cbrt(x[i]); + z = pow(x[i], 1.0 / 3.0); + + if (fabs(y - z) > eps) + atf_tc_fail_nonfatal("cbrt(%0.03f) != " + "pow(%0.03f, 1/3)\n", x[i], x[i]); + } +} + +ATF_TC(cbrt_inf_neg); +ATF_TC_HEAD(cbrt_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrt(-Inf) == -Inf"); +} + +ATF_TC_BODY(cbrt_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = cbrt(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) != 0); +} + +ATF_TC(cbrt_inf_pos); +ATF_TC_HEAD(cbrt_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrt(+Inf) == +Inf"); +} + +ATF_TC_BODY(cbrt_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = cbrt(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(cbrt_zero_neg); +ATF_TC_HEAD(cbrt_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrt(-0.0) == -0.0"); +} + +ATF_TC_BODY(cbrt_zero_neg, tc) +{ + const double x = -0.0L; + double y = cbrt(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("cbrt(-0.0) != -0.0"); +} + +ATF_TC(cbrt_zero_pos); +ATF_TC_HEAD(cbrt_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrt(+0.0) == +0.0"); +} + +ATF_TC_BODY(cbrt_zero_pos, tc) +{ + const double x = 0.0L; + double y = cbrt(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("cbrt(+0.0) != +0.0"); +} + +/* + * cbrtf(3) + */ +ATF_TC(cbrtf_nan); +ATF_TC_HEAD(cbrtf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtf(NaN) == NaN"); +} + +ATF_TC_BODY(cbrtf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cbrtf(x)) != 0); +} + +ATF_TC(cbrtf_powf); +ATF_TC_HEAD(cbrtf_powf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtf(3) vs. powf(3)"); +} + +ATF_TC_BODY(cbrtf_powf, tc) +{ + const float x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 }; + const float eps = 1.0e-5; + float y, z; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + y = cbrtf(x[i]); + z = powf(x[i], 1.0 / 3.0); + + if (fabsf(y - z) > eps) + atf_tc_fail_nonfatal("cbrtf(%0.03f) != " + "powf(%0.03f, 1/3)\n", x[i], x[i]); + } +} + +ATF_TC(cbrtf_inf_neg); +ATF_TC_HEAD(cbrtf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtf(-Inf) == -Inf"); +} + +ATF_TC_BODY(cbrtf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = cbrtf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) != 0); +} + +ATF_TC(cbrtf_inf_pos); +ATF_TC_HEAD(cbrtf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtf(+Inf) == +Inf"); +} + +ATF_TC_BODY(cbrtf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = cbrtf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(cbrtf_zero_neg); +ATF_TC_HEAD(cbrtf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtf(-0.0) == -0.0"); +} + +ATF_TC_BODY(cbrtf_zero_neg, tc) +{ + const float x = -0.0L; + float y = cbrtf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("cbrtf(-0.0) != -0.0"); +} + +ATF_TC(cbrtf_zero_pos); +ATF_TC_HEAD(cbrtf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtf(+0.0) == +0.0"); +} + +ATF_TC_BODY(cbrtf_zero_pos, tc) +{ + const float x = 0.0L; + float y = cbrtf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("cbrtf(+0.0) != +0.0"); +} + +#if !defined(__FreeBSD__) || LDBL_PREC != 53 +/* + * cbrtl(3) + */ +ATF_TC(cbrtl_nan); +ATF_TC_HEAD(cbrtl_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtl(NaN) == NaN"); +} + +ATF_TC_BODY(cbrtl_nan, tc) +{ + const long double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cbrtl(x)) != 0); +} + +ATF_TC(cbrtl_powl); +ATF_TC_HEAD(cbrtl_powl, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtl(3) vs. powl(3)"); +} + +ATF_TC_BODY(cbrtl_powl, tc) +{ + const long double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 }; + const long double eps = 1.0e-15; + long double y, z; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + y = cbrtl(x[i]); +#ifdef __FreeBSD__ + z = powl(x[i], (long double)1.0 / 3.0); +#else + z = powl(x[i], 1.0 / 3.0); +#endif + + if (fabsl(y - z) > eps * fabsl(1 + x[i])) + atf_tc_fail_nonfatal("cbrtl(%0.03Lf) != " + "powl(%0.03Lf, 1/3)\n", x[i], x[i]); + } +} + +ATF_TC(cbrtl_inf_neg); +ATF_TC_HEAD(cbrtl_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtl(-Inf) == -Inf"); +} + +ATF_TC_BODY(cbrtl_inf_neg, tc) +{ + const long double x = -1.0L / 0.0L; + long double y = cbrtl(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) != 0); +} + +ATF_TC(cbrtl_inf_pos); +ATF_TC_HEAD(cbrtl_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtl(+Inf) == +Inf"); +} + +ATF_TC_BODY(cbrtl_inf_pos, tc) +{ + const long double x = 1.0L / 0.0L; + long double y = cbrtl(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(cbrtl_zero_neg); +ATF_TC_HEAD(cbrtl_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtl(-0.0) == -0.0"); +} + +ATF_TC_BODY(cbrtl_zero_neg, tc) +{ + const long double x = -0.0L; + long double y = cbrtl(x); + + if (fabsl(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("cbrtl(-0.0) != -0.0"); +} + +ATF_TC(cbrtl_zero_pos); +ATF_TC_HEAD(cbrtl_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cbrtl(+0.0) == +0.0"); +} + +ATF_TC_BODY(cbrtl_zero_pos, tc) +{ + const long double x = 0.0L; + long double y = cbrtl(x); + + if (fabsl(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("cbrtl(+0.0) != +0.0"); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cbrt_nan); + ATF_TP_ADD_TC(tp, cbrt_pow); + ATF_TP_ADD_TC(tp, cbrt_inf_neg); + ATF_TP_ADD_TC(tp, cbrt_inf_pos); + ATF_TP_ADD_TC(tp, cbrt_zero_neg); + ATF_TP_ADD_TC(tp, cbrt_zero_pos); + + ATF_TP_ADD_TC(tp, cbrtf_nan); + ATF_TP_ADD_TC(tp, cbrtf_powf); + ATF_TP_ADD_TC(tp, cbrtf_inf_neg); + ATF_TP_ADD_TC(tp, cbrtf_inf_pos); + ATF_TP_ADD_TC(tp, cbrtf_zero_neg); + ATF_TP_ADD_TC(tp, cbrtf_zero_pos); + +#if !defined(__FreeBSD__) || LDBL_PREC != 53 + ATF_TP_ADD_TC(tp, cbrtl_nan); + ATF_TP_ADD_TC(tp, cbrtl_powl); + ATF_TP_ADD_TC(tp, cbrtl_inf_neg); + ATF_TP_ADD_TC(tp, cbrtl_inf_pos); + ATF_TP_ADD_TC(tp, cbrtl_zero_neg); + ATF_TP_ADD_TC(tp, cbrtl_zero_pos); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_ceil.c b/contrib/netbsd-tests/lib/libm/t_ceil.c new file mode 100644 index 0000000..b57f30e --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_ceil.c @@ -0,0 +1,931 @@ +/* $NetBSD: t_ceil.c,v 1.10 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_ceil.c,v 1.10 2014/03/03 10:39:08 martin Exp $"); + +#include +#include +#include +#include + +#ifdef __vax__ +#define SMALL_NUM 1.0e-38 +#else +#define SMALL_NUM 1.0e-40 +#endif + +/* + * ceil(3) + */ +ATF_TC(ceil_basic); +ATF_TC_HEAD(ceil_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of ceil(3)"); +} + +ATF_TC_BODY(ceil_basic, tc) +{ + const double x = 0.999999999999999; + const double y = 0.000000000000001; + + ATF_CHECK(fabs(ceil(x) - 1) < SMALL_NUM); + ATF_CHECK(fabs(ceil(y) - 1) < SMALL_NUM); +} + +ATF_TC(ceil_nan); +ATF_TC_HEAD(ceil_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceil(NaN) == NaN"); +} + +ATF_TC_BODY(ceil_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(ceil(x)) != 0); +} + +ATF_TC(ceil_inf_neg); +ATF_TC_HEAD(ceil_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceil(-Inf) == -Inf"); +} + +ATF_TC_BODY(ceil_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = ceil(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("ceil(-Inf) != -Inf"); +} + +ATF_TC(ceil_inf_pos); +ATF_TC_HEAD(ceil_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceil(+Inf) == +Inf"); +} + +ATF_TC_BODY(ceil_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = ceil(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("ceil(+Inf) != +Inf"); +} + +ATF_TC(ceil_zero_neg); +ATF_TC_HEAD(ceil_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceil(-0.0) == -0.0"); +} + +ATF_TC_BODY(ceil_zero_neg, tc) +{ + const double x = -0.0L; + double y = ceil(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("ceil(-0.0) != -0.0"); +} + +ATF_TC(ceil_zero_pos); +ATF_TC_HEAD(ceil_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceil(+0.0) == +0.0"); +} + +ATF_TC_BODY(ceil_zero_pos, tc) +{ + const double x = 0.0L; + double y = ceil(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("ceil(+0.0) != +0.0"); +} + +/* + * ceilf(3) + */ +ATF_TC(ceilf_basic); +ATF_TC_HEAD(ceilf_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of ceilf(3)"); +} + +ATF_TC_BODY(ceilf_basic, tc) +{ + const float x = 0.9999999; + const float y = 0.0000001; + + ATF_CHECK(fabsf(ceilf(x) - 1) < SMALL_NUM); + ATF_CHECK(fabsf(ceilf(y) - 1) < SMALL_NUM); +} + +ATF_TC(ceilf_nan); +ATF_TC_HEAD(ceilf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceilf(NaN) == NaN"); +} + +ATF_TC_BODY(ceilf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(ceilf(x)) != 0); +} + +ATF_TC(ceilf_inf_neg); +ATF_TC_HEAD(ceilf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceilf(-Inf) == -Inf"); +} + +ATF_TC_BODY(ceilf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = ceilf(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("ceilf(-Inf) != -Inf"); +} + +ATF_TC(ceilf_inf_pos); +ATF_TC_HEAD(ceilf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceilf(+Inf) == +Inf"); +} + +ATF_TC_BODY(ceilf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = ceilf(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("ceilf(+Inf) != +Inf"); +} + +ATF_TC(ceilf_zero_neg); +ATF_TC_HEAD(ceilf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceilf(-0.0) == -0.0"); +} + +ATF_TC_BODY(ceilf_zero_neg, tc) +{ + const float x = -0.0L; + float y = ceilf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("ceilf(-0.0) != -0.0"); +} + +ATF_TC(ceilf_zero_pos); +ATF_TC_HEAD(ceilf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceilf(+0.0) == +0.0"); +} + +ATF_TC_BODY(ceilf_zero_pos, tc) +{ + const float x = 0.0L; + float y = ceilf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("ceilf(+0.0) != +0.0"); +} + +/* + * ceill(3) + */ +ATF_TC(ceill_basic); +ATF_TC_HEAD(ceill_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of ceill(3)"); +} + +ATF_TC_BODY(ceill_basic, tc) +{ + const long double x = 0.9999999; + const long double y = 0.0000001; + + ATF_CHECK(fabsl(ceill(x) - 1) < SMALL_NUM); + ATF_CHECK(fabsl(ceill(y) - 1) < SMALL_NUM); +} + +ATF_TC(ceill_nan); +ATF_TC_HEAD(ceill_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceill(NaN) == NaN"); +} + +ATF_TC_BODY(ceill_nan, tc) +{ + const long double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(ceill(x)) != 0); +} + +ATF_TC(ceill_inf_neg); +ATF_TC_HEAD(ceill_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceill(-Inf) == -Inf"); +} + +ATF_TC_BODY(ceill_inf_neg, tc) +{ + const long double x = -1.0L / 0.0L; + long double y = ceill(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("ceill(-Inf) != -Inf"); +} + +ATF_TC(ceill_inf_pos); +ATF_TC_HEAD(ceill_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceill(+Inf) == +Inf"); +} + +ATF_TC_BODY(ceill_inf_pos, tc) +{ + const long double x = 1.0L / 0.0L; + long double y = ceill(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("ceill(+Inf) != +Inf"); +} + +ATF_TC(ceill_zero_neg); +ATF_TC_HEAD(ceill_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceill(-0.0) == -0.0"); +} + +ATF_TC_BODY(ceill_zero_neg, tc) +{ + const long double x = -0.0L; + long double y = ceill(x); + + if (fabsl(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("ceill(-0.0) != -0.0"); +} + +ATF_TC(ceill_zero_pos); +ATF_TC_HEAD(ceill_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ceill(+0.0) == +0.0"); +} + +ATF_TC_BODY(ceill_zero_pos, tc) +{ + const long double x = 0.0L; + long double y = ceill(x); + + if (fabsl(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("ceill(+0.0) != +0.0"); +} + +/* + * floor(3) + */ +ATF_TC(floor_basic); +ATF_TC_HEAD(floor_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of floor(3)"); +} + +ATF_TC_BODY(floor_basic, tc) +{ + const double x = 0.999999999999999; + const double y = 0.000000000000001; + + ATF_CHECK(floor(x) < SMALL_NUM); + ATF_CHECK(floor(y) < SMALL_NUM); +} + +ATF_TC(floor_nan); +ATF_TC_HEAD(floor_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floor(NaN) == NaN"); +} + +ATF_TC_BODY(floor_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(floor(x)) != 0); +} + +ATF_TC(floor_inf_neg); +ATF_TC_HEAD(floor_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floor(-Inf) == -Inf"); +} + +ATF_TC_BODY(floor_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = floor(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("floor(-Inf) != -Inf"); +} + +ATF_TC(floor_inf_pos); +ATF_TC_HEAD(floor_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floor(+Inf) == +Inf"); +} + +ATF_TC_BODY(floor_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = floor(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("floor(+Inf) != +Inf"); +} + +ATF_TC(floor_zero_neg); +ATF_TC_HEAD(floor_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floor(-0.0) == -0.0"); +} + +ATF_TC_BODY(floor_zero_neg, tc) +{ + const double x = -0.0L; + double y = floor(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("floor(-0.0) != -0.0"); +} + +ATF_TC(floor_zero_pos); +ATF_TC_HEAD(floor_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floor(+0.0) == +0.0"); +} + +ATF_TC_BODY(floor_zero_pos, tc) +{ + const double x = 0.0L; + double y = floor(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("floor(+0.0) != +0.0"); +} + +/* + * floorf(3) + */ +ATF_TC(floorf_basic); +ATF_TC_HEAD(floorf_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of floorf(3)"); +} + +ATF_TC_BODY(floorf_basic, tc) +{ + const float x = 0.9999999; + const float y = 0.0000001; + + ATF_CHECK(floorf(x) < SMALL_NUM); + ATF_CHECK(floorf(y) < SMALL_NUM); +} + +ATF_TC(floorf_nan); +ATF_TC_HEAD(floorf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorf(NaN) == NaN"); +} + +ATF_TC_BODY(floorf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(floorf(x)) != 0); +} + +ATF_TC(floorf_inf_neg); +ATF_TC_HEAD(floorf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorf(-Inf) == -Inf"); +} + +ATF_TC_BODY(floorf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = floorf(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("floorf(-Inf) != -Inf"); +} + +ATF_TC(floorf_inf_pos); +ATF_TC_HEAD(floorf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorf(+Inf) == +Inf"); +} + +ATF_TC_BODY(floorf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = floorf(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("floorf(+Inf) != +Inf"); +} + +ATF_TC(floorf_zero_neg); +ATF_TC_HEAD(floorf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorf(-0.0) == -0.0"); +} + +ATF_TC_BODY(floorf_zero_neg, tc) +{ + const float x = -0.0L; + float y = floorf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("floorf(-0.0) != -0.0"); +} + +ATF_TC(floorf_zero_pos); +ATF_TC_HEAD(floorf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorf(+0.0) == +0.0"); +} + +ATF_TC_BODY(floorf_zero_pos, tc) +{ + const float x = 0.0L; + float y = floorf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("floorf(+0.0) != +0.0"); +} + +/* + * floorl(3) + */ +ATF_TC(floorl_basic); +ATF_TC_HEAD(floorl_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of floorl(3)"); +} + +ATF_TC_BODY(floorl_basic, tc) +{ + const long double x = 0.9999999; + const long double y = 0.0000001; + + ATF_CHECK(floorl(x) < SMALL_NUM); + ATF_CHECK(floorl(y) < SMALL_NUM); +} + +ATF_TC(floorl_nan); +ATF_TC_HEAD(floorl_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorl(NaN) == NaN"); +} + +ATF_TC_BODY(floorl_nan, tc) +{ + const long double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(floorl(x)) != 0); +} + +ATF_TC(floorl_inf_neg); +ATF_TC_HEAD(floorl_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorl(-Inf) == -Inf"); +} + +ATF_TC_BODY(floorl_inf_neg, tc) +{ + const long double x = -1.0L / 0.0L; + long double y = floorl(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("floorl(-Inf) != -Inf"); +} + +ATF_TC(floorl_inf_pos); +ATF_TC_HEAD(floorl_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorl(+Inf) == +Inf"); +} + +ATF_TC_BODY(floorl_inf_pos, tc) +{ + const long double x = 1.0L / 0.0L; + long double y = floorl(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("floorl(+Inf) != +Inf"); +} + +ATF_TC(floorl_zero_neg); +ATF_TC_HEAD(floorl_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorl(-0.0) == -0.0"); +} + +ATF_TC_BODY(floorl_zero_neg, tc) +{ + const long double x = -0.0L; + long double y = floorl(x); + + if (fabsl(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("floorl(-0.0) != -0.0"); +} + +ATF_TC(floorl_zero_pos); +ATF_TC_HEAD(floorl_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test floorl(+0.0) == +0.0"); +} + +ATF_TC_BODY(floorl_zero_pos, tc) +{ + const long double x = 0.0L; + long double y = floorl(x); + + if (fabsl(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("floorl(+0.0) != +0.0"); +} + +/* + * trunc(3) + */ +ATF_TC(trunc_basic); +ATF_TC_HEAD(trunc_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of trunc(3)"); +} + +ATF_TC_BODY(trunc_basic, tc) +{ + const double x = 0.999999999999999; + const double y = 0.000000000000001; + + ATF_CHECK(trunc(x) < SMALL_NUM); + ATF_CHECK(trunc(y) < SMALL_NUM); +} + +ATF_TC(trunc_nan); +ATF_TC_HEAD(trunc_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test trunc(NaN) == NaN"); +} + +ATF_TC_BODY(trunc_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(trunc(x)) != 0); +} + +ATF_TC(trunc_inf_neg); +ATF_TC_HEAD(trunc_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test trunc(-Inf) == -Inf"); +} + +ATF_TC_BODY(trunc_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = trunc(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("trunc(-Inf) != -Inf"); +} + +ATF_TC(trunc_inf_pos); +ATF_TC_HEAD(trunc_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test trunc(+Inf) == +Inf"); +} + +ATF_TC_BODY(trunc_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = trunc(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("trunc(+Inf) != +Inf"); +} + +ATF_TC(trunc_zero_neg); +ATF_TC_HEAD(trunc_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test trunc(-0.0) == -0.0"); +} + +ATF_TC_BODY(trunc_zero_neg, tc) +{ + const double x = -0.0L; + double y = trunc(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("trunc(-0.0) != -0.0"); +} + +ATF_TC(trunc_zero_pos); +ATF_TC_HEAD(trunc_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test trunc(+0.0) == +0.0"); +} + +ATF_TC_BODY(trunc_zero_pos, tc) +{ + const double x = 0.0L; + double y = trunc(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("trunc(+0.0) != +0.0"); +} + +/* + * truncf(3) + */ +ATF_TC(truncf_basic); +ATF_TC_HEAD(truncf_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of truncf(3)"); +} + +ATF_TC_BODY(truncf_basic, tc) +{ + const float x = 0.9999999; + const float y = 0.0000001; + + ATF_CHECK(truncf(x) < SMALL_NUM); + ATF_CHECK(truncf(y) < SMALL_NUM); +} + +ATF_TC(truncf_nan); +ATF_TC_HEAD(truncf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncf(NaN) == NaN"); +} + +ATF_TC_BODY(truncf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(truncf(x)) != 0); +} + +ATF_TC(truncf_inf_neg); +ATF_TC_HEAD(truncf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncf(-Inf) == -Inf"); +} + +ATF_TC_BODY(truncf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = truncf(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("truncf(-Inf) != -Inf"); +} + +ATF_TC(truncf_inf_pos); +ATF_TC_HEAD(truncf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncf(+Inf) == +Inf"); +} + +ATF_TC_BODY(truncf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = truncf(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("truncf(+Inf) != +Inf"); +} + +ATF_TC(truncf_zero_neg); +ATF_TC_HEAD(truncf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncf(-0.0) == -0.0"); +} + +ATF_TC_BODY(truncf_zero_neg, tc) +{ + const float x = -0.0L; + float y = truncf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("truncf(-0.0) != -0.0"); +} + +ATF_TC(truncf_zero_pos); +ATF_TC_HEAD(truncf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncf(+0.0) == +0.0"); +} + +ATF_TC_BODY(truncf_zero_pos, tc) +{ + const float x = 0.0L; + float y = truncf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("truncf(+0.0) != +0.0"); +} + +/* + * truncl(3) + */ +ATF_TC(truncl_basic); +ATF_TC_HEAD(truncl_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of truncl(3)"); +} + +ATF_TC_BODY(truncl_basic, tc) +{ + const long double x = 0.9999999; + const long double y = 0.0000001; + + ATF_CHECK(truncl(x) < SMALL_NUM); + ATF_CHECK(truncl(y) < SMALL_NUM); +} + +ATF_TC(truncl_nan); +ATF_TC_HEAD(truncl_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncl(NaN) == NaN"); +} + +ATF_TC_BODY(truncl_nan, tc) +{ + const long double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(truncl(x)) != 0); +} + +ATF_TC(truncl_inf_neg); +ATF_TC_HEAD(truncl_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncl(-Inf) == -Inf"); +} + +ATF_TC_BODY(truncl_inf_neg, tc) +{ + const long double x = -1.0L / 0.0L; + long double y = truncl(x); + + if (isinf(y) == 0 || signbit(y) == 0) + atf_tc_fail_nonfatal("truncl(-Inf) != -Inf"); +} + +ATF_TC(truncl_inf_pos); +ATF_TC_HEAD(truncl_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncl(+Inf) == +Inf"); +} + +ATF_TC_BODY(truncl_inf_pos, tc) +{ + const long double x = 1.0L / 0.0L; + long double y = truncl(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("truncl(+Inf) != +Inf"); +} + +ATF_TC(truncl_zero_neg); +ATF_TC_HEAD(truncl_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncl(-0.0) == -0.0"); +} + +ATF_TC_BODY(truncl_zero_neg, tc) +{ + const long double x = -0.0L; + long double y = truncl(x); + + if (fabsl(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("truncl(-0.0) != -0.0"); +} + +ATF_TC(truncl_zero_pos); +ATF_TC_HEAD(truncl_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test truncl(+0.0) == +0.0"); +} + +ATF_TC_BODY(truncl_zero_pos, tc) +{ + const long double x = 0.0L; + long double y = truncl(x); + + if (fabsl(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("truncl(+0.0) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ceil_basic); + ATF_TP_ADD_TC(tp, ceil_nan); + ATF_TP_ADD_TC(tp, ceil_inf_neg); + ATF_TP_ADD_TC(tp, ceil_inf_pos); + ATF_TP_ADD_TC(tp, ceil_zero_neg); + ATF_TP_ADD_TC(tp, ceil_zero_pos); + + ATF_TP_ADD_TC(tp, ceilf_basic); + ATF_TP_ADD_TC(tp, ceilf_nan); + ATF_TP_ADD_TC(tp, ceilf_inf_neg); + ATF_TP_ADD_TC(tp, ceilf_inf_pos); + ATF_TP_ADD_TC(tp, ceilf_zero_neg); + ATF_TP_ADD_TC(tp, ceilf_zero_pos); + + ATF_TP_ADD_TC(tp, ceill_basic); + ATF_TP_ADD_TC(tp, ceill_nan); + ATF_TP_ADD_TC(tp, ceill_inf_neg); + ATF_TP_ADD_TC(tp, ceill_inf_pos); + ATF_TP_ADD_TC(tp, ceill_zero_neg); + ATF_TP_ADD_TC(tp, ceill_zero_pos); + + ATF_TP_ADD_TC(tp, floor_basic); + ATF_TP_ADD_TC(tp, floor_nan); + ATF_TP_ADD_TC(tp, floor_inf_neg); + ATF_TP_ADD_TC(tp, floor_inf_pos); + ATF_TP_ADD_TC(tp, floor_zero_neg); + ATF_TP_ADD_TC(tp, floor_zero_pos); + + ATF_TP_ADD_TC(tp, floorf_basic); + ATF_TP_ADD_TC(tp, floorf_nan); + ATF_TP_ADD_TC(tp, floorf_inf_neg); + ATF_TP_ADD_TC(tp, floorf_inf_pos); + ATF_TP_ADD_TC(tp, floorf_zero_neg); + ATF_TP_ADD_TC(tp, floorf_zero_pos); + + ATF_TP_ADD_TC(tp, floorl_basic); + ATF_TP_ADD_TC(tp, floorl_nan); + ATF_TP_ADD_TC(tp, floorl_inf_neg); + ATF_TP_ADD_TC(tp, floorl_inf_pos); + ATF_TP_ADD_TC(tp, floorl_zero_neg); + ATF_TP_ADD_TC(tp, floorl_zero_pos); + + ATF_TP_ADD_TC(tp, trunc_basic); + ATF_TP_ADD_TC(tp, trunc_nan); + ATF_TP_ADD_TC(tp, trunc_inf_neg); + ATF_TP_ADD_TC(tp, trunc_inf_pos); + ATF_TP_ADD_TC(tp, trunc_zero_neg); + ATF_TP_ADD_TC(tp, trunc_zero_pos); + + ATF_TP_ADD_TC(tp, truncf_basic); + ATF_TP_ADD_TC(tp, truncf_nan); + ATF_TP_ADD_TC(tp, truncf_inf_neg); + ATF_TP_ADD_TC(tp, truncf_inf_pos); + ATF_TP_ADD_TC(tp, truncf_zero_neg); + ATF_TP_ADD_TC(tp, truncf_zero_pos); + + ATF_TP_ADD_TC(tp, truncl_basic); + ATF_TP_ADD_TC(tp, truncl_nan); + ATF_TP_ADD_TC(tp, truncl_inf_neg); + ATF_TP_ADD_TC(tp, truncl_inf_pos); + ATF_TP_ADD_TC(tp, truncl_zero_neg); + ATF_TP_ADD_TC(tp, truncl_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_cos.c b/contrib/netbsd-tests/lib/libm/t_cos.c new file mode 100644 index 0000000..d99d608 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_cos.c @@ -0,0 +1,263 @@ +/* $NetBSD: t_cos.c,v 1.4 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +static const struct { + int angle; + double x; + double y; +} angles[] = { + { -180, -3.141592653589793, -1.0000000000000000 }, + { -135, -2.356194490192345, -0.7071067811865476 }, + { -90, -1.570796326794897, 0.0000000000000000 }, + { -45, -0.785398163397448, 0.7071067811865476 }, + { 0, 0.000000000000000, 1.0000000000000000 }, + { 30, 0.523598775598299, 0.8660254037844386 }, + { 45, 0.785398163397448, 0.7071067811865476 }, + { 60, 1.047197551196598, 0.5000000000000000 }, + { 90, 1.570796326794897, 0.0000000000000000 }, + { 120, 2.094395102393195, -0.5000000000000000 }, + { 135, 2.356194490192345, -0.7071067811865476 }, + { 150, 2.617993877991494, -0.8660254037844386 }, + { 180, 3.141592653589793, -1.0000000000000000 }, + { 270, 4.712388980384690, 0.0000000000000000 }, + { 360, 6.283185307179586, 1.0000000000000000 } +}; + +/* + * cos(3) + */ +ATF_TC(cos_angles); +ATF_TC_HEAD(cos_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(cos_angles, tc) +{ + const double eps = 1.0e-15; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + + if (fabs(cos(angles[i].x) - angles[i].y) > eps) + atf_tc_fail_nonfatal("cos(%d deg) != %0.01f", + angles[i].angle, angles[i].y); + } +} + +ATF_TC(cos_nan); +ATF_TC_HEAD(cos_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cos(NaN) == NaN"); +} + +ATF_TC_BODY(cos_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cos(x)) != 0); +} + +ATF_TC(cos_inf_neg); +ATF_TC_HEAD(cos_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cos(-Inf) == NaN"); +} + +ATF_TC_BODY(cos_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + ATF_CHECK(isnan(cos(x)) != 0); +} + +ATF_TC(cos_inf_pos); +ATF_TC_HEAD(cos_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cos(+Inf) == NaN"); +} + +ATF_TC_BODY(cos_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(isnan(cos(x)) != 0); +} + + +ATF_TC(cos_zero_neg); +ATF_TC_HEAD(cos_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cos(-0.0) == 1.0"); +} + +ATF_TC_BODY(cos_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(cos(x) == 1.0); +} + +ATF_TC(cos_zero_pos); +ATF_TC_HEAD(cos_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cos(+0.0) == 1.0"); +} + +ATF_TC_BODY(cos_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(cos(x) == 1.0); +} + +/* + * cosf(3) + */ +ATF_TC(cosf_angles); +ATF_TC_HEAD(cosf_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(cosf_angles, tc) +{ + const float eps = 1.0e-7; + float x, y; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + + x = angles[i].x; + y = angles[i].y; + + if (fabsf(cosf(x) - y) > eps) + atf_tc_fail_nonfatal("cosf(%d deg) != %0.01f", + angles[i].angle, angles[i].y); + } +} + +ATF_TC(cosf_nan); +ATF_TC_HEAD(cosf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosf(NaN) == NaN"); +} + +ATF_TC_BODY(cosf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cosf(x)) != 0); +} + +ATF_TC(cosf_inf_neg); +ATF_TC_HEAD(cosf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosf(-Inf) == NaN"); +} + +ATF_TC_BODY(cosf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (isnan(cosf(x)) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("cosf(-Inf) != NaN"); + } +} + +ATF_TC(cosf_inf_pos); +ATF_TC_HEAD(cosf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosf(+Inf) == NaN"); +} + +ATF_TC_BODY(cosf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + if (isnan(cosf(x)) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("cosf(+Inf) != NaN"); + } +} + + +ATF_TC(cosf_zero_neg); +ATF_TC_HEAD(cosf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosf(-0.0) == 1.0"); +} + +ATF_TC_BODY(cosf_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(cosf(x) == 1.0); +} + +ATF_TC(cosf_zero_pos); +ATF_TC_HEAD(cosf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosf(+0.0) == 1.0"); +} + +ATF_TC_BODY(cosf_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(cosf(x) == 1.0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cos_angles); + ATF_TP_ADD_TC(tp, cos_nan); + ATF_TP_ADD_TC(tp, cos_inf_neg); + ATF_TP_ADD_TC(tp, cos_inf_pos); + ATF_TP_ADD_TC(tp, cos_zero_neg); + ATF_TP_ADD_TC(tp, cos_zero_pos); + + ATF_TP_ADD_TC(tp, cosf_angles); + ATF_TP_ADD_TC(tp, cosf_nan); + ATF_TP_ADD_TC(tp, cosf_inf_neg); + ATF_TP_ADD_TC(tp, cosf_inf_pos); + ATF_TP_ADD_TC(tp, cosf_zero_neg); + ATF_TP_ADD_TC(tp, cosf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_cosh.c b/contrib/netbsd-tests/lib/libm/t_cosh.c new file mode 100644 index 0000000..3f998de --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_cosh.c @@ -0,0 +1,270 @@ +/* $NetBSD: t_cosh.c,v 1.6 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_cosh.c,v 1.6 2014/03/03 10:39:08 martin Exp $"); + +#include +#include +#include + +static const struct { + double x; + double y; + double e; +} values[] = { + { -10, 11013.23292010332, 1e4, }, + { -2, 3.762195691083631, 1, }, + { -1, 1.543080634815244, 1, }, + { -0.05, 1.001250260438369, 1, }, + { -0.001, 1.000000500000042, 1, }, + { 0, 1, 1, }, + { 0.001, 1.000000500000042, 1, }, + { 0.05, 1.001250260438369, 1, }, + { 1, 1.543080634815244, 1, }, + { 2, 3.762195691083631, 1, }, + { 10, 11013.23292010332, 1e4, }, +}; + +/* + * cosh(3) + */ +ATF_TC(cosh_inrange); +ATF_TC_HEAD(cosh_inrange, tc) +{ + atf_tc_set_md_var(tc, "descr", "cosh(x) for some values"); +} + +ATF_TC_BODY(cosh_inrange, tc) +{ + double eps; + double x; + double y; + size_t i; + + for (i = 0; i < __arraycount(values); i++) { + x = values[i].x; + y = values[i].y; + eps = 1e-15 * values[i].e; + + if (fabs(cosh(x) - y) > eps) + atf_tc_fail_nonfatal("cosh(%g) != %g\n", x, y); + } +} + +ATF_TC(cosh_nan); +ATF_TC_HEAD(cosh_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosh(NaN) == NaN"); +} + +ATF_TC_BODY(cosh_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cosh(x)) != 0); +} + +ATF_TC(cosh_inf_neg); +ATF_TC_HEAD(cosh_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosh(-Inf) == +Inf"); +} + +ATF_TC_BODY(cosh_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = cosh(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(cosh_inf_pos); +ATF_TC_HEAD(cosh_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosh(+Inf) == +Inf"); +} + +ATF_TC_BODY(cosh_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = cosh(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(cosh_zero_neg); +ATF_TC_HEAD(cosh_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosh(-0.0) == 1.0"); +} + +ATF_TC_BODY(cosh_zero_neg, tc) +{ + const double x = -0.0L; + + if (cosh(x) != 1.0) + atf_tc_fail_nonfatal("cosh(-0.0) != 1.0"); +} + +ATF_TC(cosh_zero_pos); +ATF_TC_HEAD(cosh_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosh(+0.0) == 1.0"); +} + +ATF_TC_BODY(cosh_zero_pos, tc) +{ + const double x = 0.0L; + + if (cosh(x) != 1.0) + atf_tc_fail_nonfatal("cosh(+0.0) != 1.0"); +} + +/* + * coshf(3) + */ +ATF_TC(coshf_inrange); +ATF_TC_HEAD(coshf_inrange, tc) +{ + atf_tc_set_md_var(tc, "descr", "coshf(x) for some values"); +} + +ATF_TC_BODY(coshf_inrange, tc) +{ + float eps; + float x; + float y; + size_t i; + + for (i = 0; i < __arraycount(values); i++) { + x = values[i].x; + y = values[i].y; + eps = 1e-6 * values[i].e; + + if (fabsf(coshf(x) - y) > eps) + atf_tc_fail_nonfatal("coshf(%g) != %g\n", x, y); + } +} + +ATF_TC(coshf_nan); +ATF_TC_HEAD(coshf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coshf(NaN) == NaN"); +} + +ATF_TC_BODY(coshf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(coshf(x)) != 0); +} + +ATF_TC(coshf_inf_neg); +ATF_TC_HEAD(coshf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coshf(-Inf) == +Inf"); +} + +ATF_TC_BODY(coshf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = coshf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(coshf_inf_pos); +ATF_TC_HEAD(coshf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coshf(+Inf) == +Inf"); +} + +ATF_TC_BODY(coshf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = coshf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(coshf_zero_neg); +ATF_TC_HEAD(coshf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coshf(-0.0) == 1.0"); +} + +ATF_TC_BODY(coshf_zero_neg, tc) +{ + const float x = -0.0L; + + if (coshf(x) != 1.0) + atf_tc_fail_nonfatal("coshf(-0.0) != 1.0"); +} + +ATF_TC(coshf_zero_pos); +ATF_TC_HEAD(coshf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coshf(+0.0) == 1.0"); +} + +ATF_TC_BODY(coshf_zero_pos, tc) +{ + const float x = 0.0L; + + if (coshf(x) != 1.0) + atf_tc_fail_nonfatal("coshf(+0.0) != 1.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cosh_inrange); + ATF_TP_ADD_TC(tp, cosh_nan); + ATF_TP_ADD_TC(tp, cosh_inf_neg); + ATF_TP_ADD_TC(tp, cosh_inf_pos); + ATF_TP_ADD_TC(tp, cosh_zero_neg); + ATF_TP_ADD_TC(tp, cosh_zero_pos); + + ATF_TP_ADD_TC(tp, coshf_inrange); + ATF_TP_ADD_TC(tp, coshf_nan); + ATF_TP_ADD_TC(tp, coshf_inf_neg); + ATF_TP_ADD_TC(tp, coshf_inf_pos); + ATF_TP_ADD_TC(tp, coshf_zero_neg); + ATF_TP_ADD_TC(tp, coshf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_erf.c b/contrib/netbsd-tests/lib/libm/t_erf.c new file mode 100644 index 0000000..25bbae7 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_erf.c @@ -0,0 +1,299 @@ +/* $NetBSD: t_erf.c,v 1.2 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_erf.c,v 1.2 2014/03/03 10:39:08 martin Exp $"); + +#include +#include + +/* + * erf(3) + */ +ATF_TC(erf_nan); +ATF_TC_HEAD(erf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erf(NaN) == NaN"); +} + +ATF_TC_BODY(erf_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(erf(x)) != 0); +} + +ATF_TC(erf_inf_neg); +ATF_TC_HEAD(erf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erf(-Inf) == -1.0"); +} + +ATF_TC_BODY(erf_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + if (erf(x) != -1.0) + atf_tc_fail_nonfatal("erf(-Inf) != -1.0"); +} + +ATF_TC(erf_inf_pos); +ATF_TC_HEAD(erf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erf(+Inf) == 1.0"); +} + +ATF_TC_BODY(erf_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + if (erf(x) != 1.0) + atf_tc_fail_nonfatal("erf(+Inf) != 1.0"); +} + +ATF_TC(erf_zero_neg); +ATF_TC_HEAD(erf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erf(-0.0) == -0.0"); +} + +ATF_TC_BODY(erf_zero_neg, tc) +{ + const double x = -0.0L; + double y = erf(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("erf(-0.0) != -0.0"); +} + +ATF_TC(erf_zero_pos); +ATF_TC_HEAD(erf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erf(+0.0) == +0.0"); +} + +ATF_TC_BODY(erf_zero_pos, tc) +{ + const double x = 0.0L; + double y = erf(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("erf(+0.0) != +0.0"); +} + +/* + * erff(3) + */ +ATF_TC(erff_nan); +ATF_TC_HEAD(erff_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erff(NaN) == NaN"); +} + +ATF_TC_BODY(erff_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(erff(x)) != 0); +} + +ATF_TC(erff_inf_neg); +ATF_TC_HEAD(erff_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erff(-Inf) == -1.0"); +} + +ATF_TC_BODY(erff_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (erff(x) != -1.0) + atf_tc_fail_nonfatal("erff(-Inf) != -1.0"); +} + +ATF_TC(erff_inf_pos); +ATF_TC_HEAD(erff_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erff(+Inf) == 1.0"); +} + +ATF_TC_BODY(erff_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + if (erff(x) != 1.0) + atf_tc_fail_nonfatal("erff(+Inf) != 1.0"); +} + +ATF_TC(erff_zero_neg); +ATF_TC_HEAD(erff_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erff(-0.0) == -0.0"); +} + +ATF_TC_BODY(erff_zero_neg, tc) +{ + const float x = -0.0L; + float y = erff(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("erff(-0.0) != -0.0"); +} + +ATF_TC(erff_zero_pos); +ATF_TC_HEAD(erff_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erff(+0.0) == +0.0"); +} + +ATF_TC_BODY(erff_zero_pos, tc) +{ + const float x = 0.0L; + float y = erff(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("erff(+0.0) != +0.0"); +} + +/* + * erfc(3) + */ +ATF_TC(erfc_nan); +ATF_TC_HEAD(erfc_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erfc(NaN) == NaN"); +} + +ATF_TC_BODY(erfc_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(erfc(x)) != 0); +} + +ATF_TC(erfc_inf_neg); +ATF_TC_HEAD(erfc_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erfc(-Inf) == 2.0"); +} + +ATF_TC_BODY(erfc_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + if (erfc(x) != 2.0) + atf_tc_fail_nonfatal("erfc(-Inf) != 2.0"); +} + +ATF_TC(erfc_inf_pos); +ATF_TC_HEAD(erfc_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erfc(+Inf) == +0.0"); +} + +ATF_TC_BODY(erfc_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = erfc(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("erfc(+Inf) != +0.0"); +} + +/* + * erfcf(3) + */ +ATF_TC(erfcf_nan); +ATF_TC_HEAD(erfcf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erfcf(NaN) == NaN"); +} + +ATF_TC_BODY(erfcf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(erfcf(x)) != 0); +} + +ATF_TC(erfcf_inf_neg); +ATF_TC_HEAD(erfcf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erfcf(-Inf) == 2.0"); +} + +ATF_TC_BODY(erfcf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (erfcf(x) != 2.0) + atf_tc_fail_nonfatal("erfcf(-Inf) != 2.0"); +} + +ATF_TC(erfcf_inf_pos); +ATF_TC_HEAD(erfcf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test erfcf(+Inf) == +0.0"); +} + +ATF_TC_BODY(erfcf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = erfcf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("erfcf(+Inf) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, erf_nan); + ATF_TP_ADD_TC(tp, erf_inf_neg); + ATF_TP_ADD_TC(tp, erf_inf_pos); + ATF_TP_ADD_TC(tp, erf_zero_neg); + ATF_TP_ADD_TC(tp, erf_zero_pos); + + ATF_TP_ADD_TC(tp, erff_nan); + ATF_TP_ADD_TC(tp, erff_inf_neg); + ATF_TP_ADD_TC(tp, erff_inf_pos); + ATF_TP_ADD_TC(tp, erff_zero_neg); + ATF_TP_ADD_TC(tp, erff_zero_pos); + + ATF_TP_ADD_TC(tp, erfc_nan); + ATF_TP_ADD_TC(tp, erfc_inf_neg); + ATF_TP_ADD_TC(tp, erfc_inf_pos); + + ATF_TP_ADD_TC(tp, erfcf_nan); + ATF_TP_ADD_TC(tp, erfcf_inf_neg); + ATF_TP_ADD_TC(tp, erfcf_inf_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_exp.c b/contrib/netbsd-tests/lib/libm/t_exp.c new file mode 100644 index 0000000..0eb6412 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_exp.c @@ -0,0 +1,569 @@ +/* $NetBSD: t_exp.c,v 1.8 2014/10/07 16:53:44 gson Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include "t_libm.h" + +/* y = exp(x) */ +static const struct { + double x; + double y; + double e; +} exp_values[] = { + { -10, 0.4539992976248485e-4, 1e-4, }, + { -5, 0.6737946999085467e-2, 1e-2, }, + { -1, 0.3678794411714423, 1e-1, }, + { -0.1, 0.9048374180359595, 1e-1, }, + { 0, 1.0000000000000000, 1, }, + { 0.1, 1.1051709180756477, 1, }, + { 1, 2.7182818284590452, 1, }, + { 5, 148.41315910257660, 1e2, }, + { 10, 22026.465794806718, 1e4, }, +}; + +/* + * exp2/exp2f(3) + */ +ATF_LIBM_TEST(exp2_is_nan, "Test exp2(x) == NaN") +{ +#ifdef T_LIBM_NAN + T_LIBM_CHECK_NAN(0, exp2, T_LIBM_NAN); + T_LIBM_CHECK_NAN(0, exp2f, T_LIBM_NAN); +#else + atf_tc_skip("no NaN on this machine"); +#endif +} + +ATF_LIBM_TEST(exp2_is_plus_zero, "Test exp2(x) == +0.0") +{ +#ifdef T_LIBM_MINUS_INF + T_LIBM_CHECK_PLUS_ZERO(0, exp2, T_LIBM_MINUS_INF); + T_LIBM_CHECK_PLUS_ZERO(0, exp2f, T_LIBM_MINUS_INF); +#else + atf_tc_skip("no +/-Inf on this machine"); +#endif +} + +ATF_LIBM_TEST(exp2_powers, "Test exp2(x) is correct for some integer x") +{ + static const struct { + double x; + double d_y; + double f_y; + } v[] = { + { +0.0, 1.0, 1.0 }, + { -0.0, 1.0, 1.0 }, + { 1, 0x1p1, 0x1p1 }, + { 2, 0x1p2, 0x1p2 }, + { 100, 0x1p100, 0x1p100 }, + { 125, 0x1p125, 0x1p125 }, + { 126, 0x1p126, 0x1p126 }, +#if __DBL_MAX_EXP__ > 129 + { 127, 0x1p127, 0x1p127 }, +#endif +#ifdef T_LIBM_PLUS_INF + { 128, 0x1p128, T_LIBM_PLUS_INF }, + { 129, 0x1p129, T_LIBM_PLUS_INF }, + { 1000, 0x1p1000, T_LIBM_PLUS_INF }, + { 1020, 0x1p1020, T_LIBM_PLUS_INF }, + { 1023, 0x1p1023, T_LIBM_PLUS_INF }, + { 1024, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, + { 1030, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, + { 1050, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, + { 2000, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, + { 16383, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, + { 16384, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, + { 16385, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF }, +#endif + { -1, 0x1p-1, 0x1p-1 }, + { -2, 0x1p-2, 0x1p-2 }, + { -100, 0x1p-100, 0x1p-100 }, + { -127, 0x1p-127, 0x1p-127 }, + { -128, 0x1p-128, 0x1p-128 }, +#if __LDBL_MIN_EXP__ < -129 + { -300, 0x1p-300, 0.0}, + { -400, 0x1p-400, 0.0}, + {-1000, 0x1p-1000, 0.0}, + {-1022, 0x1p-1022, 0.0}, + /* These should be denormal numbers */ + {-1023, 0x1p-1023, 0.0}, + {-1024, 0x1p-1024, 0.0}, + {-1040, 0x1p-1040, 0.0}, + {-1060, 0x1p-1060, 0.0}, + /* This is the smallest result gcc will allow */ + {-1074, 0x1p-1074, 0.0}, +#endif + {-1075, 0x0, 0.0}, + {-1080, 0x0, 0.0}, + {-2000, 0x0, 0.0}, + {-16382, 0x0, 0.0}, + {-16383, 0x0, 0.0}, + {-16384, 0x0, 0.0}, + }; + unsigned int i; + +#if defined(__FreeBSD__) && defined(__i386__) + atf_tc_expect_fail("a number of the assertions fail on i386"); +#endif + + for (i = 0; i < __arraycount(v); i++) { + T_LIBM_CHECK(i, exp2, v[i].x, v[i].d_y, 0.0); + T_LIBM_CHECK(i, exp2f, v[i].x, v[i].f_y, 0.0); + } +} + +ATF_LIBM_TEST(exp2_values, "Test exp2(x) is correct for some x") +{ + static const struct { + double x; + double d_y; + float f_y; + double d_eps; + double f_eps; + } v[] = { +#if __DBL_MAX_EXP__ > 128 + /* The largest double constant */ + { 0x1.fffffffffffffp9, 0x1.ffffffffffd3ap1023, 0.00, + 0x1p969, 0.0 }, + /* The largest float constant */ + { 0x1.fffffep6, 0x1.ffff4ep+127, 0x1.ffff4ep+127, 6e30, 0.0 }, +#endif +#ifdef T_LIBM_PLUS_INF + { T_LIBM_PLUS_INF, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF, 0.0, 0.0 }, +#endif + + /* The few values from the old tests */ + /* Results from i386/amd64, d_eps needed on i386 */ + /* f_y values calculated using py-mpmath */ + { 1.1, 0x1.125fbee250664p+1, 0x1.125fc0p+1, 0x1p-52, 0x1.8p-22 }, + { 2.2, 0x1.2611186bae675p+2, 0x1.26111ap+2, 0x1p-51, 0x1.8p-21 }, + { 3.3, 0x1.3b2c47bff8328p+3, 0x1.3b2c48p+3, 0x1p-50, 0x1.8p-20 }, + { 4.4, 0x1.51cb453b9536ep+4, 0x1.51cb46p+4, 0x1p-49, 0x1.8p-19 }, + { 5.5, 0x1.6a09e667f3bcdp+5, 0x1.6a09e6p+5, 0x1p-48, 0x1.8p-18 }, + { 6.6, 0x1.8406003b2ae5bp+6, 0x1.8405fep+6, 0x1p-47, 0x1.8p-17 }, + { 7.7, 0x1.9fdf8bcce533ep+7, 0x1.9fdf88p+7, 0x1p-46, 0x1.8p-16 }, + { 8.8, 0x1.bdb8cdadbe124p+8, 0x1.bdb8d2p+8, 0x1p-45, 0x1.8p-15 }, + }; + unsigned int i; + + for (i = 0; i < __arraycount(v); i++) { + T_LIBM_CHECK(i, exp2, v[i].x, v[i].d_y, v[i].d_eps); + if (i > 1) + T_LIBM_CHECK(i, exp2f, v[i].x, v[i].f_y, v[i].f_eps); + } +} + + +/* + * exp(3) + */ +ATF_TC(exp_nan); +ATF_TC_HEAD(exp_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exp(NaN) == NaN"); +} + +ATF_TC_BODY(exp_nan, tc) +{ + const double x = 0.0L / 0.0L; + + if (isnan(exp(x)) == 0) + atf_tc_fail_nonfatal("exp(NaN) != NaN"); +} + +ATF_TC(exp_inf_neg); +ATF_TC_HEAD(exp_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exp(-Inf) == +0.0"); +} + +ATF_TC_BODY(exp_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = exp(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("exp(-Inf) != +0.0"); +} + +ATF_TC(exp_inf_pos); +ATF_TC_HEAD(exp_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exp(+Inf) == +Inf"); +} + +ATF_TC_BODY(exp_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = exp(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("exp(+Inf) != +Inf"); +} + +ATF_TC(exp_product); +ATF_TC_HEAD(exp_product, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected exp(x)"); +} + +ATF_TC_BODY(exp_product, tc) +{ + double eps; + double x; + double y; + size_t i; + + for (i = 0; i < __arraycount(exp_values); i++) { + x = exp_values[i].x; + y = exp_values[i].y; + eps = 1e-15 * exp_values[i].e; + + if (fabs(exp(x) - y) > eps) + atf_tc_fail_nonfatal("exp(%0.01f) != %18.18e", x, y); + } +} + +ATF_TC(exp_zero_neg); +ATF_TC_HEAD(exp_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exp(-0.0) == 1.0"); +} + +ATF_TC_BODY(exp_zero_neg, tc) +{ + const double x = -0.0L; + + if (fabs(exp(x) - 1.0) > 0.0) + atf_tc_fail_nonfatal("exp(-0.0) != 1.0"); +} + +ATF_TC(exp_zero_pos); +ATF_TC_HEAD(exp_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test exp(+0.0) == 1.0"); +} + +ATF_TC_BODY(exp_zero_pos, tc) +{ + const double x = 0.0L; + + if (fabs(exp(x) - 1.0) > 0.0) + atf_tc_fail_nonfatal("exp(+0.0) != 1.0"); +} + +/* + * expf(3) + */ +ATF_TC(expf_nan); +ATF_TC_HEAD(expf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expf(NaN) == NaN"); +} + +ATF_TC_BODY(expf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + if (isnan(expf(x)) == 0) + atf_tc_fail_nonfatal("expf(NaN) != NaN"); +} + +ATF_TC(expf_inf_neg); +ATF_TC_HEAD(expf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expf(-Inf) == +0.0"); +} + +ATF_TC_BODY(expf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = expf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("expf(-Inf) != +0.0"); +} + +ATF_TC(expf_inf_pos); +ATF_TC_HEAD(expf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expf(+Inf) == +Inf"); +} + +ATF_TC_BODY(expf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = expf(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("expf(+Inf) != +Inf"); +} + +ATF_TC(expf_product); +ATF_TC_HEAD(expf_product, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected expf(x)"); +} + +ATF_TC_BODY(expf_product, tc) +{ + float eps; + float x; + float y; + size_t i; + + for (i = 0; i < __arraycount(exp_values); i++) { + x = exp_values[i].x; + y = exp_values[i].y; + eps = 1e-6 * exp_values[i].e; + + if (fabsf(expf(x) - y) > eps) + atf_tc_fail_nonfatal("expf(%0.01f) != %18.18e", x, y); + } +} + +ATF_TC(expf_zero_neg); +ATF_TC_HEAD(expf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expf(-0.0) == 1.0"); +} + +ATF_TC_BODY(expf_zero_neg, tc) +{ + const float x = -0.0L; + + if (fabsf(expf(x) - 1.0f) > 0.0) + atf_tc_fail_nonfatal("expf(-0.0) != 1.0"); +} + +ATF_TC(expf_zero_pos); +ATF_TC_HEAD(expf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expf(+0.0) == 1.0"); +} + +ATF_TC_BODY(expf_zero_pos, tc) +{ + const float x = 0.0L; + + if (fabsf(expf(x) - 1.0f) > 0.0) + atf_tc_fail_nonfatal("expf(+0.0) != 1.0"); +} + +/* + * expm1(3) + */ +ATF_TC(expm1_nan); +ATF_TC_HEAD(expm1_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1(NaN) == NaN"); +} + +ATF_TC_BODY(expm1_nan, tc) +{ + const double x = 0.0L / 0.0L; + + if (isnan(expm1(x)) == 0) + atf_tc_fail_nonfatal("expm1(NaN) != NaN"); +} + +ATF_TC(expm1_inf_neg); +ATF_TC_HEAD(expm1_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1(-Inf) == -1"); +} + +ATF_TC_BODY(expm1_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + if (expm1(x) != -1.0) + atf_tc_fail_nonfatal("expm1(-Inf) != -1.0"); +} + +ATF_TC(expm1_inf_pos); +ATF_TC_HEAD(expm1_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1(+Inf) == +Inf"); +} + +ATF_TC_BODY(expm1_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = expm1(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("expm1(+Inf) != +Inf"); +} + +ATF_TC(expm1_zero_neg); +ATF_TC_HEAD(expm1_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1(-0.0) == -0.0"); +} + +ATF_TC_BODY(expm1_zero_neg, tc) +{ + const double x = -0.0L; + double y = expm1(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("expm1(-0.0) != -0.0"); +} + +ATF_TC(expm1_zero_pos); +ATF_TC_HEAD(expm1_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1(+0.0) == 1.0"); +} + +ATF_TC_BODY(expm1_zero_pos, tc) +{ + const double x = 0.0L; + double y = expm1(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("expm1(+0.0) != +0.0"); +} + +/* + * expm1f(3) + */ +ATF_TC(expm1f_nan); +ATF_TC_HEAD(expm1f_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1f(NaN) == NaN"); +} + +ATF_TC_BODY(expm1f_nan, tc) +{ + const float x = 0.0L / 0.0L; + + if (isnan(expm1f(x)) == 0) + atf_tc_fail_nonfatal("expm1f(NaN) != NaN"); +} + +ATF_TC(expm1f_inf_neg); +ATF_TC_HEAD(expm1f_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1f(-Inf) == -1"); +} + +ATF_TC_BODY(expm1f_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (expm1f(x) != -1.0) + atf_tc_fail_nonfatal("expm1f(-Inf) != -1.0"); +} + +ATF_TC(expm1f_inf_pos); +ATF_TC_HEAD(expm1f_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1f(+Inf) == +Inf"); +} + +ATF_TC_BODY(expm1f_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = expm1f(x); + + if (isinf(y) == 0 || signbit(y) != 0) + atf_tc_fail_nonfatal("expm1f(+Inf) != +Inf"); +} + +ATF_TC(expm1f_zero_neg); +ATF_TC_HEAD(expm1f_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1f(-0.0) == -0.0"); +} + +ATF_TC_BODY(expm1f_zero_neg, tc) +{ + const float x = -0.0L; + float y = expm1f(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("expm1f(-0.0) != -0.0"); +} + +ATF_TC(expm1f_zero_pos); +ATF_TC_HEAD(expm1f_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test expm1f(+0.0) == 1.0"); +} + +ATF_TC_BODY(expm1f_zero_pos, tc) +{ + const float x = 0.0L; + float y = expm1f(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("expm1f(+0.0) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, exp2_is_nan); + ATF_TP_ADD_TC(tp, exp2_is_plus_zero); + ATF_TP_ADD_TC(tp, exp2_values); + ATF_TP_ADD_TC(tp, exp2_powers); + + ATF_TP_ADD_TC(tp, exp_nan); + ATF_TP_ADD_TC(tp, exp_inf_neg); + ATF_TP_ADD_TC(tp, exp_inf_pos); + ATF_TP_ADD_TC(tp, exp_product); + ATF_TP_ADD_TC(tp, exp_zero_neg); + ATF_TP_ADD_TC(tp, exp_zero_pos); + + ATF_TP_ADD_TC(tp, expf_nan); + ATF_TP_ADD_TC(tp, expf_inf_neg); + ATF_TP_ADD_TC(tp, expf_inf_pos); + ATF_TP_ADD_TC(tp, expf_product); + ATF_TP_ADD_TC(tp, expf_zero_neg); + ATF_TP_ADD_TC(tp, expf_zero_pos); + + ATF_TP_ADD_TC(tp, expm1_nan); + ATF_TP_ADD_TC(tp, expm1_inf_neg); + ATF_TP_ADD_TC(tp, expm1_inf_pos); + ATF_TP_ADD_TC(tp, expm1_zero_neg); + ATF_TP_ADD_TC(tp, expm1_zero_pos); + + ATF_TP_ADD_TC(tp, expm1f_nan); + ATF_TP_ADD_TC(tp, expm1f_inf_neg); + ATF_TP_ADD_TC(tp, expm1f_inf_pos); + ATF_TP_ADD_TC(tp, expm1f_zero_neg); + ATF_TP_ADD_TC(tp, expm1f_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_fe_round.c b/contrib/netbsd-tests/lib/libm/t_fe_round.c new file mode 100644 index 0000000..fe805b4 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_fe_round.c @@ -0,0 +1,124 @@ +/* + * Written by Maya Rashish + * Public domain. + * + * Testing IEEE-754 rounding modes (and lrint) + */ + +#include +#include +#ifdef __HAVE_FENV +#include +#include +#include + +/*#pragma STDC FENV_ACCESS ON gcc?? */ + +#define INT 9223L + +#define EPSILON 0.001 + +static const struct { + int round_mode; + double input; + long int expected; +} values[] = { + { FE_DOWNWARD, 3.7, 3}, + { FE_DOWNWARD, -3.7, -4}, + { FE_DOWNWARD, +0, 0}, + { FE_DOWNWARD, -INT-0.01, -INT-1}, + { FE_DOWNWARD, +INT-0.01, INT-1}, + { FE_DOWNWARD, -INT+0.01, -INT}, + { FE_DOWNWARD, +INT+0.01, INT}, +#if 0 /* cpu bugs? */ + { FE_DOWNWARD, -0, -1}, + + { FE_UPWARD, +0, 1}, +#endif + { FE_UPWARD, -0, 0}, + { FE_UPWARD, -123.7, -123}, + { FE_UPWARD, 123.999, 124}, + { FE_UPWARD, -INT-0.01, -INT}, + { FE_UPWARD, +INT-0.01, INT}, + { FE_UPWARD, -INT+0.01, -INT+1}, + { FE_UPWARD, +INT+0.01, INT+1}, + + { FE_TOWARDZERO, 1.99, 1}, + { FE_TOWARDZERO, -1.99, -1}, + { FE_TOWARDZERO, 0.2, 0}, + { FE_TOWARDZERO, INT+0.01, INT}, + { FE_TOWARDZERO, INT-0.01, INT - 1}, + { FE_TOWARDZERO, -INT+0.01, -INT + 1}, + { FE_TOWARDZERO, +0, 0}, + { FE_TOWARDZERO, -0, 0}, + + { FE_TONEAREST, -INT-0.01, -INT}, + { FE_TONEAREST, +INT-0.01, INT}, + { FE_TONEAREST, -INT+0.01, -INT}, + { FE_TONEAREST, +INT+0.01, INT}, + { FE_TONEAREST, -INT-0.501, -INT-1}, + { FE_TONEAREST, +INT-0.501, INT-1}, + { FE_TONEAREST, -INT+0.501, -INT+1}, + { FE_TONEAREST, +INT+0.501, INT+1}, + { FE_TONEAREST, +0, 0}, + { FE_TONEAREST, -0, 0}, +}; + +ATF_TC(fe_round); +ATF_TC_HEAD(fe_round, tc) +{ + atf_tc_set_md_var(tc, "descr","Checking IEEE 754 rounding modes using lrint"); +} + +ATF_TC_BODY(fe_round, tc) +{ + long int received; + + for (unsigned int i = 0; i < __arraycount(values); i++) { + fesetround(values[i].round_mode); + + received = lrint(values[i].input); + ATF_CHECK_MSG( + (labs(received - values[i].expected) < EPSILON), + "lrint rounding wrong, difference too large\n" + "input: %f (index %d): got %ld, expected %ld\n", + values[i].input, i, received, values[i].expected); + + /* Do we get the same rounding mode out? */ + ATF_CHECK_MSG( + (fegetround() == values[i].round_mode), + "Didn't get the same rounding mode out!\n" + "(index %d) fed in %d rounding mode, got %d out\n", + i, fegetround(), values[i].round_mode); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fe_round); + + return atf_no_error(); +} +#else +ATF_TC(t_nofe_round); + +ATF_TC_HEAD(t_nofe_round, tc) +{ + atf_tc_set_md_var(tc, "descr", + "dummy test case - no fenv.h support"); +} + + +ATF_TC_BODY(t_nofe_round, tc) +{ + atf_tc_skip("no fenv.h support on this architecture"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_nofe_round); + return atf_no_error(); +} + +#endif diff --git a/contrib/netbsd-tests/lib/libm/t_fenv.c b/contrib/netbsd-tests/lib/libm/t_fenv.c new file mode 100644 index 0000000..5445036 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_fenv.c @@ -0,0 +1,220 @@ +/* $NetBSD: t_fenv.c,v 1.3 2015/12/22 14:20:59 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_fenv.c,v 1.3 2015/12/22 14:20:59 christos Exp $"); + +#include + +#include +#ifdef __HAVE_FENV + +#include +#include + + +#if __arm__ && !__SOFTFP__ + /* + * Some NEON fpus do not implement IEEE exception handling, + * skip these tests if running on them and compiled for + * hard float. + */ +#define FPU_EXC_PREREQ() \ + if (0 == fpsetmask(fpsetmask(FP_X_INV))) \ + atf_tc_skip("FPU does not implement exception handling"); + + /* + * Same as above: some don't allow configuring the rounding mode. + */ +#define FPU_RND_PREREQ() \ + if (0 == fpsetround(fpsetround(FP_RZ))) \ + atf_tc_skip("FPU does not implement configurable " \ + "rounding modes"); +#endif + +#ifndef FPU_EXC_PREREQ +#define FPU_EXC_PREREQ() /* nothing */ +#endif +#ifndef FPU_RND_PREREQ +#define FPU_RND_PREREQ() /* nothing */ +#endif + + +ATF_TC(fegetround); + +ATF_TC_HEAD(fegetround, tc) +{ + atf_tc_set_md_var(tc, "descr", + "verify the fegetround() function agrees with the legacy " + "fpsetround"); +} + +ATF_TC_BODY(fegetround, tc) +{ + FPU_RND_PREREQ(); + + fpsetround(FP_RZ); + ATF_CHECK(fegetround() == FE_TOWARDZERO); + fpsetround(FP_RM); + ATF_CHECK(fegetround() == FE_DOWNWARD); + fpsetround(FP_RN); + ATF_CHECK(fegetround() == FE_TONEAREST); + fpsetround(FP_RP); + ATF_CHECK(fegetround() == FE_UPWARD); +} + +ATF_TC(fesetround); + +ATF_TC_HEAD(fesetround, tc) +{ + atf_tc_set_md_var(tc, "descr", + "verify the fesetround() function agrees with the legacy " + "fpgetround"); +} + +ATF_TC_BODY(fesetround, tc) +{ + FPU_RND_PREREQ(); + + fesetround(FE_TOWARDZERO); + ATF_CHECK(fpgetround() == FP_RZ); + fesetround(FE_DOWNWARD); + ATF_CHECK(fpgetround() == FP_RM); + fesetround(FE_TONEAREST); + ATF_CHECK(fpgetround() == FP_RN); + fesetround(FE_UPWARD); + ATF_CHECK(fpgetround() == FP_RP); +} + +ATF_TC(fegetexcept); + +ATF_TC_HEAD(fegetexcept, tc) +{ + atf_tc_set_md_var(tc, "descr", + "verify the fegetexcept() function agrees with the legacy " + "fpsetmask()"); +} + +ATF_TC_BODY(fegetexcept, tc) +{ + FPU_EXC_PREREQ(); + + fpsetmask(0); + ATF_CHECK(fegetexcept() == 0); + + fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); + ATF_CHECK(fegetexcept() == (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW + |FE_UNDERFLOW|FE_INEXACT)); + + fpsetmask(FP_X_INV); + ATF_CHECK(fegetexcept() == FE_INVALID); + + fpsetmask(FP_X_DZ); + ATF_CHECK(fegetexcept() == FE_DIVBYZERO); + + fpsetmask(FP_X_OFL); + ATF_CHECK(fegetexcept() == FE_OVERFLOW); + + fpsetmask(FP_X_UFL); + ATF_CHECK(fegetexcept() == FE_UNDERFLOW); + + fpsetmask(FP_X_IMP); + ATF_CHECK(fegetexcept() == FE_INEXACT); +} + +ATF_TC(feenableexcept); + +ATF_TC_HEAD(feenableexcept, tc) +{ + atf_tc_set_md_var(tc, "descr", + "verify the feenableexcept() function agrees with the legacy " + "fpgetmask()"); +} + +ATF_TC_BODY(feenableexcept, tc) +{ + FPU_EXC_PREREQ(); + + fedisableexcept(FE_ALL_EXCEPT); + ATF_CHECK(fpgetmask() == 0); + + feenableexcept(FE_UNDERFLOW); + ATF_CHECK(fpgetmask() == FP_X_UFL); + + fedisableexcept(FE_ALL_EXCEPT); + feenableexcept(FE_OVERFLOW); + ATF_CHECK(fpgetmask() == FP_X_OFL); + + fedisableexcept(FE_ALL_EXCEPT); + feenableexcept(FE_DIVBYZERO); + ATF_CHECK(fpgetmask() == FP_X_DZ); + + fedisableexcept(FE_ALL_EXCEPT); + feenableexcept(FE_INEXACT); + ATF_CHECK(fpgetmask() == FP_X_IMP); + + fedisableexcept(FE_ALL_EXCEPT); + feenableexcept(FE_INVALID); + ATF_CHECK(fpgetmask() == FP_X_INV); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, fegetround); + ATF_TP_ADD_TC(tp, fesetround); + ATF_TP_ADD_TC(tp, fegetexcept); + ATF_TP_ADD_TC(tp, feenableexcept); + + return atf_no_error(); +} + +#else /* no fenv.h support */ + +ATF_TC(t_nofenv); + +ATF_TC_HEAD(t_nofenv, tc) +{ + atf_tc_set_md_var(tc, "descr", + "dummy test case - no fenv.h support"); +} + + +ATF_TC_BODY(t_nofenv, tc) +{ + atf_tc_skip("no fenv.h support on this architecture"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_nofenv); + return atf_no_error(); +} + +#endif diff --git a/contrib/netbsd-tests/lib/libm/t_fmod.c b/contrib/netbsd-tests/lib/libm/t_fmod.c new file mode 100644 index 0000000..2a221f5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_fmod.c @@ -0,0 +1,76 @@ +/* $NetBSD: t_fmod.c,v 1.3 2015/01/03 14:23:53 gson Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include "isqemu.h" + +ATF_TC(fmod); +ATF_TC_HEAD(fmod, tc) +{ + atf_tc_set_md_var(tc, "descr","Check fmod family"); +} + +ATF_TC_BODY(fmod, tc) +{ +#ifdef __NetBSD__ + if (isQEMU()) + atf_tc_expect_fail("PR misc/44767"); +#endif + + ATF_CHECK(fmodf(2.0, 1.0) == 0); + ATF_CHECK(fmod(2.0, 1.0) == 0); +#if !defined(__FreeBSD__) || LDBL_PREC != 53 + ATF_CHECK(fmodl(2.0, 1.0) == 0); +#endif + + ATF_CHECK(fmodf(2.0, 0.5) == 0); + ATF_CHECK(fmod(2.0, 0.5) == 0); +#if !defined(__FreeBSD__) || LDBL_PREC != 53 + ATF_CHECK(fmodl(2.0, 0.5) == 0); +#endif + + ATF_CHECK(fabsf(fmodf(1.0, 0.1) - 0.1f) <= 55 * FLT_EPSILON); + ATF_CHECK(fabs(fmod(1.0, 0.1) - 0.1) <= 55 * DBL_EPSILON); +#if !defined(__FreeBSD__) || LDBL_PREC != 53 + ATF_CHECK(fabsl(fmodl(1.0, 0.1L) - 0.1L) <= 55 * LDBL_EPSILON); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, fmod); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_hypot.c b/contrib/netbsd-tests/lib/libm/t_hypot.c new file mode 100644 index 0000000..deb7e86 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_hypot.c @@ -0,0 +1,81 @@ +/* $NetBSD: t_hypot.c,v 1.1 2016/01/24 20:26:47 gson Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +ATF_TC(hypot_integer); +ATF_TC_HEAD(hypot_integer, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test hypot with integer args"); +} + +ATF_TC_BODY(hypot_integer, tc) +{ + /* volatile so hypotf() won't be evaluated at compile time */ + volatile double a = 5; + volatile double b = 12; + ATF_CHECK(hypot(a, b) == 13.0); +} + +ATF_TC(hypotf_integer); +ATF_TC_HEAD(hypotf_integer, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test hypotf with integer args"); +} + +ATF_TC_BODY(hypotf_integer, tc) +{ + volatile float a = 5; + volatile float b = 12; + ATF_CHECK(hypotf(a, b) == 13.0f); +} + +ATF_TC(pr50698); +ATF_TC_HEAD(pr50698, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check for the bug of PR 50698"); +} + +ATF_TC_BODY(pr50698, tc) +{ + volatile float a = 1e-18f; + float val = hypotf(a, a); + ATF_CHECK(!isinf(val)); + ATF_CHECK(!isnan(val)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, hypot_integer); + ATF_TP_ADD_TC(tp, hypotf_integer); + ATF_TP_ADD_TC(tp, pr50698); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_ilogb.c b/contrib/netbsd-tests/lib/libm/t_ilogb.c new file mode 100644 index 0000000..1d35cb6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_ilogb.c @@ -0,0 +1,130 @@ +/* $NetBSD: t_ilogb.c,v 1.7 2017/01/13 19:23:40 christos Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Maya Rashish. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_ilogb.c,v 1.7 2017/01/13 19:23:40 christos Exp $"); + +#include +#include +#include +#include + +#ifndef __HAVE_FENV + +# define ATF_CHECK_RAISED_INVALID +# define ATF_CHECK_RAISED_NOTHING + +#else +# define ATF_CHECK_RAISED_INVALID do { \ + int r = fetestexcept(FE_ALL_EXCEPT); \ + ATF_CHECK_MSG(r == FE_INVALID, "r=%#x != %#x\n", r, FE_INVALID); \ + (void)feclearexcept(FE_ALL_EXCEPT); \ +} while (/*CONSTCOND*/0) + +# define ATF_CHECK_RAISED_NOTHING do { \ + int r = fetestexcept(FE_ALL_EXCEPT); \ + ATF_CHECK_MSG(r == 0, "r=%#x != 0\n", r); \ + (void)feclearexcept(FE_ALL_EXCEPT); \ +} while (/*CONSTCOND*/0) +#endif + +ATF_TC(ilogb); +ATF_TC_HEAD(ilogb, tc) +{ + atf_tc_set_md_var(tc, "descr","Check ilogb family"); +} + +ATF_TC_BODY(ilogb, tc) +{ + + ATF_CHECK(ilogbf(0) == FP_ILOGB0); + ATF_CHECK_RAISED_INVALID; + ATF_CHECK(ilogb(0) == FP_ILOGB0); + ATF_CHECK_RAISED_INVALID; +#ifdef __HAVE_LONG_DOUBLE + ATF_CHECK(ilogbl(0) == FP_ILOGB0); + ATF_CHECK_RAISED_INVALID; +#endif + + ATF_CHECK(ilogbf(-0) == FP_ILOGB0); + ATF_CHECK_RAISED_INVALID; + ATF_CHECK(ilogb(-0) == FP_ILOGB0); + ATF_CHECK_RAISED_INVALID; +#ifdef __HAVE_LONG_DOUBLE + ATF_CHECK(ilogbl(-0) == FP_ILOGB0); + ATF_CHECK_RAISED_INVALID; +#endif + + ATF_CHECK(ilogbf(INFINITY) == INT_MAX); + ATF_CHECK_RAISED_INVALID; + ATF_CHECK(ilogb(INFINITY) == INT_MAX); + ATF_CHECK_RAISED_INVALID; +#ifdef __HAVE_LONG_DOUBLE + ATF_CHECK(ilogbl(INFINITY) == INT_MAX); + ATF_CHECK_RAISED_INVALID; +#endif + + ATF_CHECK(ilogbf(-INFINITY) == INT_MAX); + ATF_CHECK_RAISED_INVALID; + ATF_CHECK(ilogb(-INFINITY) == INT_MAX); + ATF_CHECK_RAISED_INVALID; +#ifdef __HAVE_LONG_DOUBLE + ATF_CHECK(ilogbl(-INFINITY) == INT_MAX); + ATF_CHECK_RAISED_INVALID; +#endif + + ATF_CHECK(ilogbf(1024) == 10); + ATF_CHECK_RAISED_NOTHING; + ATF_CHECK(ilogb(1024) == 10); + ATF_CHECK_RAISED_NOTHING; +#ifdef __HAVE_LONG_DOUBLE + ATF_CHECK(ilogbl(1024) == 10); + ATF_CHECK_RAISED_NOTHING; +#endif + +#ifndef __vax__ + ATF_CHECK(ilogbf(NAN) == FP_ILOGBNAN); + ATF_CHECK_RAISED_INVALID; + ATF_CHECK(ilogb(NAN) == FP_ILOGBNAN); + ATF_CHECK_RAISED_INVALID; +#ifdef __HAVE_LONG_DOUBLE + ATF_CHECK(ilogbl(NAN) == FP_ILOGBNAN); + ATF_CHECK_RAISED_INVALID; +#endif +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ilogb); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_infinity.c b/contrib/netbsd-tests/lib/libm/t_infinity.c new file mode 100644 index 0000000..7ac1737 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_infinity.c @@ -0,0 +1,119 @@ +/* $NetBSD: t_infinity.c,v 1.6 2012/09/26 07:24:38 jruoho Exp $ */ + +/*- + * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann . + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_infinity.c,v 1.6 2012/09/26 07:24:38 jruoho Exp $"); + +#include +#include +#include +#include + +ATF_TC(infinity_float); +ATF_TC_HEAD(infinity_float, tc) +{ + atf_tc_set_md_var(tc, "descr", + "check FPU generated infinite float values"); +} + +ATF_TC_BODY(infinity_float, tc) +{ + float v; + + v = FLT_MAX; + v *= v; + ATF_REQUIRE(isinf(v)); + ATF_REQUIRE(fpclassify(v) == FP_INFINITE); + + v = -FLT_MAX; + v *= v; + ATF_REQUIRE(isinf(v)); + ATF_REQUIRE(fpclassify(v) == FP_INFINITE); +} + +ATF_TC(infinity_double); +ATF_TC_HEAD(infinity_double, tc) +{ + atf_tc_set_md_var(tc, "descr", + "check FPU generated infinite double values"); +} + +ATF_TC_BODY(infinity_double, tc) +{ + double v; + + v = DBL_MAX; + v *= v; + ATF_REQUIRE(isinf(v)); + ATF_REQUIRE(fpclassify(v) == FP_INFINITE); + + v = -DBL_MAX; + v *= v; + ATF_REQUIRE(isinf(v)); + ATF_REQUIRE(fpclassify(v) == FP_INFINITE); +} + +ATF_TC(infinity_long_double); +ATF_TC_HEAD(infinity_long_double, tc) +{ + atf_tc_set_md_var(tc, "descr", + "check FPU generated infinite long double values"); +} + +ATF_TC_BODY(infinity_long_double, tc) +{ + +#ifndef LDBL_MAX + atf_tc_skip("no long double support on this architecture"); + return; +#else + long double v; + + v = LDBL_MAX; + v *= v; + ATF_REQUIRE(isinf(v)); + ATF_REQUIRE(fpclassify(v) == FP_INFINITE); + + v = -LDBL_MAX; + v *= v; + ATF_REQUIRE(isinf(v)); + ATF_REQUIRE(fpclassify(v) == FP_INFINITE); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, infinity_float); + ATF_TP_ADD_TC(tp, infinity_double); + ATF_TP_ADD_TC(tp, infinity_long_double); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_ldexp.c b/contrib/netbsd-tests/lib/libm/t_ldexp.c new file mode 100644 index 0000000..251f2ae --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_ldexp.c @@ -0,0 +1,480 @@ +/* $NetBSD: t_ldexp.c,v 1.16 2016/08/25 00:32:31 maya Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_ldexp.c,v 1.16 2016/08/25 00:32:31 maya Exp $"); + +#include + +#include + +#include +#include +#include +#include + +#define SKIP 9999 +#define FORMAT "%23.23lg" + +static const int exps[] = { 0, 1, -1, 100, -100 }; + +struct ldexp_test { + double x; + int exp1; + int exp2; + const char *result; +}; + +struct ldexp_test ldexp_basic[] = { + { 1.0, 5, SKIP, " 32" }, + { 1.0, 1022, SKIP, "4.4942328371557897693233e+307" }, + { 1.0, 1023, -1, "4.4942328371557897693233e+307" }, + { 1.0, 1023, SKIP, "8.9884656743115795386465e+307" }, + { 1.0, 1022, 1, "8.9884656743115795386465e+307" }, + { 1.0, -1022, 2045, "8.9884656743115795386465e+307" }, + { 1.0, -5, SKIP, " 0.03125" }, + { 1.0, -1021, SKIP, "4.4501477170144027661805e-308" }, + { 1.0, -1022, 1, "4.4501477170144027661805e-308" }, + { 1.0, -1022, SKIP, "2.2250738585072013830902e-308" }, + { 1.0, -1021, -1, "2.2250738585072013830902e-308" }, + { 1.0, 1023, -2045, "2.2250738585072013830902e-308" }, + { 1.0, 1023, -1023, " 1" }, + { 1.0, -1022, 1022, " 1" }, + { 0, 0, 0, NULL } +}; + +struct ldexp_test ldexp_zero[] = { + { 0.0, -1, SKIP, " 0" }, + { 0.0, 0, SKIP, " 0" }, + { 0.0, 1, SKIP, " 0" }, + { 0.0, 1024, SKIP, " 0" }, + { 0.0, 1025, SKIP, " 0" }, + { 0.0, -1023, SKIP, " 0" }, + { 0.0, -1024, SKIP, " 0" }, + { 0, 0, 0, NULL } +}; + +struct ldexp_test ldexp_infinity[] = { + { 1.0, 1024, -1, " inf" }, + { 1.0, 1024, 0, " inf" }, + { 1.0, 1024, 1, " inf" }, + { -1.0, 1024, -1, " -inf" }, + { -1.0, 1024, 0, " -inf" }, + { -1.0, 1024, 1, " -inf" }, + { 0, 0, 0, NULL } +}; + +struct ldexp_test ldexp_overflow[] = { + { 1.0, 1024, SKIP, " inf" }, + { 1.0, 1023, 1, " inf" }, + { 1.0, -1022, 2046, " inf" }, + { 1.0, 1025, SKIP, " inf" }, + { 2.0, INT_MAX,SKIP, " inf" }, + { -1.0, 1024, SKIP, " -inf" }, + { -1.0, 1023, 1, " -inf" }, + { -1.0, -1022, 2046, " -inf" }, + { -1.0, 1025, SKIP, " -inf" }, + { -2.0, INT_MAX,SKIP, " -inf" }, + { 0, 0, 0, NULL } +}; + +struct ldexp_test ldexp_denormal[] = { + { 1.0, -1023, SKIP, "1.1125369292536006915451e-308" }, + { 1.0, -1022, -1, "1.1125369292536006915451e-308" }, + { 1.0, 1023, -2046, "1.1125369292536006915451e-308" }, + { 1.0, -1024, SKIP, "5.5626846462680034577256e-309" }, + { 1.0, -1074, SKIP, "4.9406564584124654417657e-324" }, + { -1.0, -1023, SKIP, "-1.1125369292536006915451e-308" }, + { -1.0, -1022, -1, "-1.1125369292536006915451e-308" }, + { -1.0, 1023, -2046, "-1.1125369292536006915451e-308" }, + { -1.0, -1024, SKIP, "-5.5626846462680034577256e-309" }, + { -1.0, -1074, SKIP, "-4.9406564584124654417657e-324" }, + { 0, 0, 0, NULL } +}; + +struct ldexp_test ldexp_underflow[] = { + { 1.0, -1075, SKIP, " 0" }, + { 1.0, -1074, -1, " 0" }, + { 1.0, 1023, -2098, " 0" }, + { 1.0, -1076, SKIP, " 0" }, + { -1.0, -1075, SKIP, " -0" }, + { -1.0, -1074, -1, " -0" }, + { -1.0, 1023, -2098, " -0" }, + { -1.0, -1076, SKIP, " -0" }, + { 0, 0, 0, NULL } +}; + +struct ldexp_test ldexp_denormal_large[] = { + { 1.0, -1028, 1024, " 0.0625" }, + { 1.0, -1028, 1025, " 0.125" }, + { 1.0, -1028, 1026, " 0.25" }, + { 1.0, -1028, 1027, " 0.5" }, + { 1.0, -1028, 1028, " 1" }, + { 1.0, -1028, 1029, " 2" }, + { 1.0, -1028, 1030, " 4" }, + { 1.0, -1028, 1040, " 4096" }, + { 1.0, -1028, 1050, " 4194304" }, + { 1.0, -1028, 1060, " 4294967296" }, + { 1.0, -1028, 1100, " 4722366482869645213696" }, + { 1.0, -1028, 1200, "5.9863107065073783529623e+51" }, + { 1.0, -1028, 1300, "7.5885503602567541832791e+81" }, + { 1.0, -1028, 1400, "9.6196304190416209014353e+111" }, + { 1.0, -1028, 1500, "1.2194330274671844653834e+142" }, + { 1.0, -1028, 1600, "1.5458150092069033378781e+172" }, + { 1.0, -1028, 1700, "1.9595533242629369747791e+202" }, + { 1.0, -1028, 1800, "2.4840289476811342962384e+232" }, + { 1.0, -1028, 1900, "3.1488807865122869393369e+262" }, + { 1.0, -1028, 2000, "3.9916806190694396233127e+292" }, + { 1.0, -1028, 2046, "2.808895523222368605827e+306" }, + { 1.0, -1028, 2047, "5.6177910464447372116541e+306" }, + { 1.0, -1028, 2048, "1.1235582092889474423308e+307" }, + { 1.0, -1028, 2049, "2.2471164185778948846616e+307" }, + { 1.0, -1028, 2050, "4.4942328371557897693233e+307" }, + { 1.0, -1028, 2051, "8.9884656743115795386465e+307" }, + { 0, 0, 0, NULL } +}; + +static void +run_test(struct ldexp_test *table) +{ + char outbuf[64]; + size_t i; + double v; + + for (i = 0; table->result != NULL; table++, i++) { + + v = ldexp(table->x, table->exp1); + + if (table->exp2 != SKIP) + v = ldexp(v, table->exp2); + + (void)snprintf(outbuf, sizeof(outbuf), FORMAT, v); + + ATF_CHECK_STREQ_MSG(table->result, outbuf, + "Entry %zu:\n\tExp: \"%s\"\n\tAct: \"%s\"", + i, table->result, outbuf); + } +} + +/* + * ldexp(3) + */ +ATF_TC(ldexp_exp2); +ATF_TC_HEAD(ldexp_exp2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexp(x, n) == x * exp2(n)"); +} + +ATF_TC_BODY(ldexp_exp2, tc) +{ + const double n[] = { 1, 2, 3, 10, 50, 100 }; +#if __DBL_MIN_10_EXP__ <= -40 + const double eps = 1.0e-40; +#else + const double eps = __DBL_MIN__*4.0; +#endif + const double x = 12.0; + double y; + size_t i; + + for (i = 0; i < __arraycount(n); i++) { + + y = ldexp(x, n[i]); + + if (fabs(y - (x * exp2(n[i]))) > eps) { + atf_tc_fail_nonfatal("ldexp(%0.01f, %0.01f) " + "!= %0.01f * exp2(%0.01f)", x, n[i], x, n[i]); + } + } +} + +ATF_TC(ldexp_nan); +ATF_TC_HEAD(ldexp_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexp(NaN) == NaN"); +} + +ATF_TC_BODY(ldexp_nan, tc) +{ + const double x = 0.0L / 0.0L; + double y; + size_t i; + + ATF_REQUIRE(isnan(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = ldexp(x, exps[i]); + ATF_CHECK(isnan(y) != 0); + } +} + +ATF_TC(ldexp_inf_neg); +ATF_TC_HEAD(ldexp_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexp(-Inf) == -Inf"); +} + +ATF_TC_BODY(ldexp_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(ldexp(x, exps[i]) == x); +} + +ATF_TC(ldexp_inf_pos); +ATF_TC_HEAD(ldexp_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexp(+Inf) == +Inf"); +} + +ATF_TC_BODY(ldexp_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(ldexp(x, exps[i]) == x); +} + +ATF_TC(ldexp_zero_neg); +ATF_TC_HEAD(ldexp_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexp(-0.0) == -0.0"); +} + +ATF_TC_BODY(ldexp_zero_neg, tc) +{ + const double x = -0.0L; + double y; + size_t i; + + ATF_REQUIRE(signbit(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = ldexp(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) != 0); + } +} + +ATF_TC(ldexp_zero_pos); +ATF_TC_HEAD(ldexp_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexp(+0.0) == +0.0"); +} + +ATF_TC_BODY(ldexp_zero_pos, tc) +{ + const double x = 0.0L; + double y; + size_t i; + + ATF_REQUIRE(signbit(x) == 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = ldexp(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) == 0); + } +} + +/* + * ldexpf(3) + */ + +ATF_TC(ldexpf_exp2f); +ATF_TC_HEAD(ldexpf_exp2f, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexpf(x, n) == x * exp2f(n)"); +} + +ATF_TC_BODY(ldexpf_exp2f, tc) +{ + const float n[] = { 1, 2, 3, 10, 50, 100 }; + const float eps = 1.0e-9; + const float x = 12.0; + float y; + size_t i; + + for (i = 0; i < __arraycount(n); i++) { + + y = ldexpf(x, n[i]); + + if (fabsf(y - (x * exp2f(n[i]))) > eps) { + atf_tc_fail_nonfatal("ldexpf(%0.01f, %0.01f) " + "!= %0.01f * exp2f(%0.01f)", x, n[i], x, n[i]); + } + } +} + +ATF_TC(ldexpf_nan); +ATF_TC_HEAD(ldexpf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexpf(NaN) == NaN"); +} + +ATF_TC_BODY(ldexpf_nan, tc) +{ + const float x = 0.0L / 0.0L; + float y; + size_t i; + + ATF_REQUIRE(isnan(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = ldexpf(x, exps[i]); + ATF_CHECK(isnan(y) != 0); + } +} + +ATF_TC(ldexpf_inf_neg); +ATF_TC_HEAD(ldexpf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexpf(-Inf) == -Inf"); +} + +ATF_TC_BODY(ldexpf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(ldexpf(x, exps[i]) == x); +} + +ATF_TC(ldexpf_inf_pos); +ATF_TC_HEAD(ldexpf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexpf(+Inf) == +Inf"); +} + +ATF_TC_BODY(ldexpf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(ldexpf(x, exps[i]) == x); +} + +ATF_TC(ldexpf_zero_neg); +ATF_TC_HEAD(ldexpf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexpf(-0.0) == -0.0"); +} + +ATF_TC_BODY(ldexpf_zero_neg, tc) +{ + const float x = -0.0L; + float y; + size_t i; + + ATF_REQUIRE(signbit(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = ldexpf(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) != 0); + } +} + +ATF_TC(ldexpf_zero_pos); +ATF_TC_HEAD(ldexpf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test ldexpf(+0.0) == +0.0"); +} + +ATF_TC_BODY(ldexpf_zero_pos, tc) +{ + const float x = 0.0L; + float y; + size_t i; + + ATF_REQUIRE(signbit(x) == 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = ldexpf(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) == 0); + } +} + +#define TEST(name, desc) \ + ATF_TC(name); \ + ATF_TC_HEAD(name, tc) \ + { \ + \ + atf_tc_set_md_var(tc, "descr", \ + "Test ldexp(3) for " ___STRING(desc)); \ + } \ + ATF_TC_BODY(name, tc) \ + { \ + if (strcmp("vax", MACHINE_ARCH) == 0) \ + atf_tc_skip("Test not valid for " MACHINE_ARCH); \ + run_test(name); \ + } + +TEST(ldexp_basic, basics) +TEST(ldexp_zero, zero) +TEST(ldexp_infinity, infinity) +TEST(ldexp_overflow, overflow) +TEST(ldexp_denormal, denormal) +TEST(ldexp_denormal_large, large) +TEST(ldexp_underflow, underflow) + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, ldexp_basic); + ATF_TP_ADD_TC(tp, ldexp_zero); + ATF_TP_ADD_TC(tp, ldexp_infinity); + ATF_TP_ADD_TC(tp, ldexp_overflow); + ATF_TP_ADD_TC(tp, ldexp_denormal); + ATF_TP_ADD_TC(tp, ldexp_underflow); + ATF_TP_ADD_TC(tp, ldexp_denormal_large); + + ATF_TP_ADD_TC(tp, ldexp_exp2); + ATF_TP_ADD_TC(tp, ldexp_nan); + ATF_TP_ADD_TC(tp, ldexp_inf_neg); + ATF_TP_ADD_TC(tp, ldexp_inf_pos); + ATF_TP_ADD_TC(tp, ldexp_zero_neg); + ATF_TP_ADD_TC(tp, ldexp_zero_pos); + + ATF_TP_ADD_TC(tp, ldexpf_exp2f); + ATF_TP_ADD_TC(tp, ldexpf_nan); + ATF_TP_ADD_TC(tp, ldexpf_inf_neg); + ATF_TP_ADD_TC(tp, ldexpf_inf_pos); + ATF_TP_ADD_TC(tp, ldexpf_zero_neg); + ATF_TP_ADD_TC(tp, ldexpf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_libm.h b/contrib/netbsd-tests/lib/libm/t_libm.h new file mode 100644 index 0000000..34e3cb2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_libm.h @@ -0,0 +1,62 @@ +/* $NetBSD: t_libm.h,v 1.6 2014/03/25 17:30:14 joerg Exp $ */ + +/* + * Check result of fn(arg) is correct within the bounds. + * Should be ok to do the checks using 'double' for 'float' functions. + * On i386 float and double values are returned on the x87 stack and might + * be out of range for the function - so save and print as 'long double'. + * (otherwise you can get 'inf != inf' reported!) + */ +#define T_LIBM_CHECK(subtest, fn, arg, expect_, epsilon_) do { \ + long double epsilon = epsilon_; \ + long double expect = expect_; \ + long double r = fn(arg); \ + long double e = fabsl(r - expect); \ + if (r != expect && e > epsilon) \ + atf_tc_fail_nonfatal( \ + "subtest %u: " #fn "(%g) is %Lg (%.14La) " \ + "not %Lg (%.13La), error %Lg (%.6La) > %Lg", \ + subtest, arg, r, r, expect, expect, e, e, epsilon); \ + } while (0) + +/* Check that the result of fn(arg) is NaN */ +#ifndef __vax__ +#define T_LIBM_CHECK_NAN(subtest, fn, arg) do { \ + double r = fn(arg); \ + if (!isnan(r)) \ + atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not NaN", \ + subtest, arg, r); \ + } while (0) +#else +/* vax doesn't support NaN */ +#define T_LIBM_CHECK_NAN(subtest, fn, arg) (void)(arg) +#endif + +/* Check that the result of fn(arg) is +0.0 */ +#define T_LIBM_CHECK_PLUS_ZERO(subtest, fn, arg) do { \ + double r = fn(arg); \ + if (fabs(r) > 0.0 || signbit(r) != 0) \ + atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not +0.0", \ + subtest, arg, r); \ + } while (0) + +/* Check that the result of fn(arg) is -0.0 */ +#define T_LIBM_CHECK_MINUS_ZERO(subtest, fn, arg) do { \ + double r = fn(arg); \ + if (fabs(r) > 0.0 || signbit(r) == 0) \ + atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not -0.0", \ + subtest, arg, r); \ + } while (0) + +/* Some useful constants (for test vectors) */ +#ifndef __vax__ /* no NAN nor +/- INF on vax */ +#define T_LIBM_NAN (0.0 / 0.0) +#define T_LIBM_PLUS_INF (+1.0 / 0.0) +#define T_LIBM_MINUS_INF (-1.0 / 0.0) +#endif + +/* One line definition of a simple test */ +#define ATF_LIBM_TEST(name, description) \ +ATF_TC(name); \ +ATF_TC_HEAD(name, tc) { atf_tc_set_md_var(tc, "descr", description); } \ +ATF_TC_BODY(name, tc) diff --git a/contrib/netbsd-tests/lib/libm/t_log.c b/contrib/netbsd-tests/lib/libm/t_log.c new file mode 100644 index 0000000..756efcf --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_log.c @@ -0,0 +1,872 @@ +/* $NetBSD: t_log.c,v 1.13 2015/02/09 19:39:48 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_log.c,v 1.13 2015/02/09 19:39:48 martin Exp $"); + +#include + +#include +#include +#include + +/* + * log10(3) + */ +ATF_TC(log10_base); +ATF_TC_HEAD(log10_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(10) == 1"); +} + +ATF_TC_BODY(log10_base, tc) +{ + ATF_CHECK(log10(10.0) == 1.0); +} + +ATF_TC(log10_nan); +ATF_TC_HEAD(log10_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(NaN) == NaN"); +} + +ATF_TC_BODY(log10_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log10(x)) != 0); +} + +ATF_TC(log10_inf_neg); +ATF_TC_HEAD(log10_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(-Inf) == NaN"); +} + +ATF_TC_BODY(log10_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + const double y = log10(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(log10_inf_pos); +ATF_TC_HEAD(log10_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(+Inf) == +Inf"); +} + +ATF_TC_BODY(log10_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(log10(x) == x); +} + +ATF_TC(log10_one_pos); +ATF_TC_HEAD(log10_one_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(1.0) == +0.0"); +} + +ATF_TC_BODY(log10_one_pos, tc) +{ + const double x = log10(1.0); + const double y = 0.0L; + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(log10_zero_neg); +ATF_TC_HEAD(log10_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(-0.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log10_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(log10(x) == -HUGE_VAL); +} + +ATF_TC(log10_zero_pos); +ATF_TC_HEAD(log10_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10(+0.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log10_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(log10(x) == -HUGE_VAL); +} + +/* + * log10f(3) + */ +ATF_TC(log10f_base); +ATF_TC_HEAD(log10f_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(10) == 1"); +} + +ATF_TC_BODY(log10f_base, tc) +{ + ATF_CHECK(log10f(10.0) == 1.0); +} + +ATF_TC(log10f_nan); +ATF_TC_HEAD(log10f_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(NaN) == NaN"); +} + +ATF_TC_BODY(log10f_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log10f(x)) != 0); +} + +ATF_TC(log10f_inf_neg); +ATF_TC_HEAD(log10f_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(-Inf) == NaN"); +} + +ATF_TC_BODY(log10f_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + const float y = log10f(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(log10f_inf_pos); +ATF_TC_HEAD(log10f_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(+Inf) == +Inf"); +} + +ATF_TC_BODY(log10f_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + ATF_CHECK(log10f(x) == x); +} + +ATF_TC(log10f_one_pos); +ATF_TC_HEAD(log10f_one_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(1.0) == +0.0"); +} + +ATF_TC_BODY(log10f_one_pos, tc) +{ + const float x = log10f(1.0); + const float y = 0.0L; + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(log10f_zero_neg); +ATF_TC_HEAD(log10f_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(-0.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(log10f_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(log10f(x) == -HUGE_VALF); +} + +ATF_TC(log10f_zero_pos); +ATF_TC_HEAD(log10f_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log10f(+0.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(log10f_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(log10f(x) == -HUGE_VALF); +} + +/* + * log1p(3) + */ +ATF_TC(log1p_nan); +ATF_TC_HEAD(log1p_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1p(NaN) == NaN"); +} + +ATF_TC_BODY(log1p_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log1p(x)) != 0); +} + +ATF_TC(log1p_inf_neg); +ATF_TC_HEAD(log1p_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1p(-Inf) == NaN"); +} + +ATF_TC_BODY(log1p_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + const double y = log1p(x); + + if (isnan(y) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("log1p(-Inf) != NaN"); + } +} + +ATF_TC(log1p_inf_pos); +ATF_TC_HEAD(log1p_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1p(+Inf) == +Inf"); +} + +ATF_TC_BODY(log1p_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(log1p(x) == x); +} + +ATF_TC(log1p_one_neg); +ATF_TC_HEAD(log1p_one_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1p(-1.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log1p_one_neg, tc) +{ + const double x = log1p(-1.0); + + if (x != -HUGE_VAL) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("log1p(-1.0) != -HUGE_VAL"); + } +} + +ATF_TC(log1p_zero_neg); +ATF_TC_HEAD(log1p_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1p(-0.0) == -0.0"); +} + +ATF_TC_BODY(log1p_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(log1p(x) == x); +} + +ATF_TC(log1p_zero_pos); +ATF_TC_HEAD(log1p_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1p(+0.0) == +0.0"); +} + +ATF_TC_BODY(log1p_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(log1p(x) == x); +} + +/* + * log1pf(3) + */ +ATF_TC(log1pf_nan); +ATF_TC_HEAD(log1pf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1pf(NaN) == NaN"); +} + +ATF_TC_BODY(log1pf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log1pf(x)) != 0); +} + +ATF_TC(log1pf_inf_neg); +ATF_TC_HEAD(log1pf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1pf(-Inf) == NaN"); +} + +ATF_TC_BODY(log1pf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + const float y = log1pf(x); + + if (isnan(y) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("log1pf(-Inf) != NaN"); + } +} + +ATF_TC(log1pf_inf_pos); +ATF_TC_HEAD(log1pf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1pf(+Inf) == +Inf"); +} + +ATF_TC_BODY(log1pf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + ATF_CHECK(log1pf(x) == x); +} + +ATF_TC(log1pf_one_neg); +ATF_TC_HEAD(log1pf_one_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1pf(-1.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(log1pf_one_neg, tc) +{ + const float x = log1pf(-1.0); + + if (x != -HUGE_VALF) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("log1pf(-1.0) != -HUGE_VALF"); + } +} + +ATF_TC(log1pf_zero_neg); +ATF_TC_HEAD(log1pf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1pf(-0.0) == -0.0"); +} + +ATF_TC_BODY(log1pf_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(log1pf(x) == x); +} + +ATF_TC(log1pf_zero_pos); +ATF_TC_HEAD(log1pf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log1pf(+0.0) == +0.0"); +} + +ATF_TC_BODY(log1pf_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(log1pf(x) == x); +} + +/* + * log2(3) + */ +ATF_TC(log2_base); +ATF_TC_HEAD(log2_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(2) == 1"); +} + +ATF_TC_BODY(log2_base, tc) +{ + ATF_CHECK(log2(2.0) == 1.0); +} + +ATF_TC(log2_nan); +ATF_TC_HEAD(log2_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(NaN) == NaN"); +} + +ATF_TC_BODY(log2_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log2(x)) != 0); +} + +ATF_TC(log2_inf_neg); +ATF_TC_HEAD(log2_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(-Inf) == NaN"); +} + +ATF_TC_BODY(log2_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + const double y = log2(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(log2_inf_pos); +ATF_TC_HEAD(log2_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(+Inf) == +Inf"); +} + +ATF_TC_BODY(log2_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(log2(x) == x); +} + +ATF_TC(log2_one_pos); +ATF_TC_HEAD(log2_one_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(1.0) == +0.0"); +} + +ATF_TC_BODY(log2_one_pos, tc) +{ + const double x = log2(1.0); + const double y = 0.0L; + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(log2_zero_neg); +ATF_TC_HEAD(log2_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(-0.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log2_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(log2(x) == -HUGE_VAL); +} + +ATF_TC(log2_zero_pos); +ATF_TC_HEAD(log2_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2(+0.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log2_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(log2(x) == -HUGE_VAL); +} + +/* + * log2f(3) + */ +ATF_TC(log2f_base); +ATF_TC_HEAD(log2f_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(2) == 1"); +} + +ATF_TC_BODY(log2f_base, tc) +{ + ATF_CHECK(log2f(2.0) == 1.0); +} + +ATF_TC(log2f_nan); +ATF_TC_HEAD(log2f_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(NaN) == NaN"); +} + +ATF_TC_BODY(log2f_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log2f(x)) != 0); +} + +ATF_TC(log2f_inf_neg); +ATF_TC_HEAD(log2f_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(-Inf) == NaN"); +} + +ATF_TC_BODY(log2f_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + const float y = log2f(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(log2f_inf_pos); +ATF_TC_HEAD(log2f_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(+Inf) == +Inf"); +} + +ATF_TC_BODY(log2f_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + ATF_CHECK(log2f(x) == x); +} + +ATF_TC(log2f_one_pos); +ATF_TC_HEAD(log2f_one_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(1.0) == +0.0"); +} + +ATF_TC_BODY(log2f_one_pos, tc) +{ + const float x = log2f(1.0); + const float y = 0.0L; + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(log2f_zero_neg); +ATF_TC_HEAD(log2f_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(-0.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(log2f_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(log2f(x) == -HUGE_VALF); +} + +ATF_TC(log2f_zero_pos); +ATF_TC_HEAD(log2f_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log2f(+0.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(log2f_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(log2f(x) == -HUGE_VALF); +} + +/* + * log(3) + */ +ATF_TC(log_base); +ATF_TC_HEAD(log_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(e) == 1"); +} + +ATF_TC_BODY(log_base, tc) +{ + const double eps = 1.0e-38; + + if (fabs(log(M_E) - 1.0) > eps) + atf_tc_fail_nonfatal("log(e) != 1"); +} + +ATF_TC(log_nan); +ATF_TC_HEAD(log_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(NaN) == NaN"); +} + +ATF_TC_BODY(log_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(log(x)) != 0); +} + +ATF_TC(log_inf_neg); +ATF_TC_HEAD(log_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(-Inf) == NaN"); +} + +ATF_TC_BODY(log_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + const double y = log(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(log_inf_pos); +ATF_TC_HEAD(log_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(+Inf) == +Inf"); +} + +ATF_TC_BODY(log_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(log(x) == x); +} + +ATF_TC(log_one_pos); +ATF_TC_HEAD(log_one_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(1.0) == +0.0"); +} + +ATF_TC_BODY(log_one_pos, tc) +{ + const double x = log(1.0); + const double y = 0.0L; + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(log_zero_neg); +ATF_TC_HEAD(log_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(-0.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(log(x) == -HUGE_VAL); +} + +ATF_TC(log_zero_pos); +ATF_TC_HEAD(log_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test log(+0.0) == -HUGE_VAL"); +} + +ATF_TC_BODY(log_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(log(x) == -HUGE_VAL); +} + +/* + * logf(3) + */ +ATF_TC(logf_base); +ATF_TC_HEAD(logf_base, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(e) == 1"); +} + +ATF_TC_BODY(logf_base, tc) +{ + const float eps = 1.0e-7; + + if (fabsf(logf(M_E) - 1.0f) > eps) + atf_tc_fail_nonfatal("logf(e) != 1"); +} + +ATF_TC(logf_nan); +ATF_TC_HEAD(logf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(NaN) == NaN"); +} + +ATF_TC_BODY(logf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(logf(x)) != 0); +} + +ATF_TC(logf_inf_neg); +ATF_TC_HEAD(logf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(-Inf) == NaN"); +} + +ATF_TC_BODY(logf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + const float y = logf(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(logf_inf_pos); +ATF_TC_HEAD(logf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(+Inf) == +Inf"); +} + +ATF_TC_BODY(logf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + ATF_CHECK(logf(x) == x); +} + +ATF_TC(logf_one_pos); +ATF_TC_HEAD(logf_one_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(1.0) == +0.0"); +} + +ATF_TC_BODY(logf_one_pos, tc) +{ + const float x = logf(1.0); + const float y = 0.0L; + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(logf_zero_neg); +ATF_TC_HEAD(logf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(-0.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(logf_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(logf(x) == -HUGE_VALF); +} + +ATF_TC(logf_zero_pos); +ATF_TC_HEAD(logf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test logf(+0.0) == -HUGE_VALF"); +} + +ATF_TC_BODY(logf_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(logf(x) == -HUGE_VALF); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, log10_base); + ATF_TP_ADD_TC(tp, log10_nan); + ATF_TP_ADD_TC(tp, log10_inf_neg); + ATF_TP_ADD_TC(tp, log10_inf_pos); + ATF_TP_ADD_TC(tp, log10_one_pos); + ATF_TP_ADD_TC(tp, log10_zero_neg); + ATF_TP_ADD_TC(tp, log10_zero_pos); + + ATF_TP_ADD_TC(tp, log10f_base); + ATF_TP_ADD_TC(tp, log10f_nan); + ATF_TP_ADD_TC(tp, log10f_inf_neg); + ATF_TP_ADD_TC(tp, log10f_inf_pos); + ATF_TP_ADD_TC(tp, log10f_one_pos); + ATF_TP_ADD_TC(tp, log10f_zero_neg); + ATF_TP_ADD_TC(tp, log10f_zero_pos); + + ATF_TP_ADD_TC(tp, log1p_nan); + ATF_TP_ADD_TC(tp, log1p_inf_neg); + ATF_TP_ADD_TC(tp, log1p_inf_pos); + ATF_TP_ADD_TC(tp, log1p_one_neg); + ATF_TP_ADD_TC(tp, log1p_zero_neg); + ATF_TP_ADD_TC(tp, log1p_zero_pos); + + ATF_TP_ADD_TC(tp, log1pf_nan); + ATF_TP_ADD_TC(tp, log1pf_inf_neg); + ATF_TP_ADD_TC(tp, log1pf_inf_pos); + ATF_TP_ADD_TC(tp, log1pf_one_neg); + ATF_TP_ADD_TC(tp, log1pf_zero_neg); + ATF_TP_ADD_TC(tp, log1pf_zero_pos); + + ATF_TP_ADD_TC(tp, log2_base); + ATF_TP_ADD_TC(tp, log2_nan); + ATF_TP_ADD_TC(tp, log2_inf_neg); + ATF_TP_ADD_TC(tp, log2_inf_pos); + ATF_TP_ADD_TC(tp, log2_one_pos); + ATF_TP_ADD_TC(tp, log2_zero_neg); + ATF_TP_ADD_TC(tp, log2_zero_pos); + + ATF_TP_ADD_TC(tp, log2f_base); + ATF_TP_ADD_TC(tp, log2f_nan); + ATF_TP_ADD_TC(tp, log2f_inf_neg); + ATF_TP_ADD_TC(tp, log2f_inf_pos); + ATF_TP_ADD_TC(tp, log2f_one_pos); + ATF_TP_ADD_TC(tp, log2f_zero_neg); + ATF_TP_ADD_TC(tp, log2f_zero_pos); + + ATF_TP_ADD_TC(tp, log_base); + ATF_TP_ADD_TC(tp, log_nan); + ATF_TP_ADD_TC(tp, log_inf_neg); + ATF_TP_ADD_TC(tp, log_inf_pos); + ATF_TP_ADD_TC(tp, log_one_pos); + ATF_TP_ADD_TC(tp, log_zero_neg); + ATF_TP_ADD_TC(tp, log_zero_pos); + + ATF_TP_ADD_TC(tp, logf_base); + ATF_TP_ADD_TC(tp, logf_nan); + ATF_TP_ADD_TC(tp, logf_inf_neg); + ATF_TP_ADD_TC(tp, logf_inf_pos); + ATF_TP_ADD_TC(tp, logf_one_pos); + ATF_TP_ADD_TC(tp, logf_zero_neg); + ATF_TP_ADD_TC(tp, logf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_modf.c b/contrib/netbsd-tests/lib/libm/t_modf.c new file mode 100644 index 0000000..a856b15 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_modf.c @@ -0,0 +1,68 @@ +/* $NetBSD: t_modf.c,v 1.1 2014/06/16 12:54:43 joerg Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +ATF_TC(modf); +ATF_TC_HEAD(modf, tc) +{ + atf_tc_set_md_var(tc, "descr","Check modf family"); +} + +ATF_TC_BODY(modf, tc) +{ + float basef; + double base; + long double basel; + ATF_CHECK(modff(1.0, &basef) == 0.0); + ATF_CHECK(basef == 1.0); + ATF_CHECK(modf(1.0, &base) == 0.0); + ATF_CHECK(base == 1.0); + ATF_CHECK(modfl(1.0, &basel) == 0.0); + ATF_CHECK(basel == 1.0); + + ATF_CHECK(modff(-1 - FLT_EPSILON, &basef) == -FLT_EPSILON); + ATF_CHECK(basef == -1.0); + ATF_CHECK(modf(-1 - DBL_EPSILON, &base) == -DBL_EPSILON); + ATF_CHECK(base == -1.0); + ATF_CHECK(modfl(-1 - LDBL_EPSILON, &basel) == -LDBL_EPSILON); + ATF_CHECK(basel == -1.0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, modf); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_pow.c b/contrib/netbsd-tests/lib/libm/t_pow.c new file mode 100644 index 0000000..7afee9f --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_pow.c @@ -0,0 +1,666 @@ +/* $NetBSD: t_pow.c,v 1.5 2017/01/20 21:15:56 maya Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_pow.c,v 1.5 2017/01/20 21:15:56 maya Exp $"); + +#include +#include + +/* + * pow(3) + */ +ATF_TC(pow_nan_x); +ATF_TC_HEAD(pow_nan_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(NaN, y) == NaN"); +} + +ATF_TC_BODY(pow_nan_x, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(pow(x, 2.0)) != 0); +} + +ATF_TC(pow_nan_y); +ATF_TC_HEAD(pow_nan_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(x, NaN) == NaN"); +} + +ATF_TC_BODY(pow_nan_y, tc) +{ + const double y = 0.0L / 0.0L; + + ATF_CHECK(isnan(pow(2.0, y)) != 0); +} + +ATF_TC(pow_inf_neg_x); +ATF_TC_HEAD(pow_inf_neg_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(-Inf, y) == +-Inf || +-0.0"); +} + +ATF_TC_BODY(pow_inf_neg_x, tc) +{ + const double x = -1.0L / 0.0L; + double z; + + /* + * If y is odd, y > 0, and x is -Inf, -Inf is returned. + * If y is even, y > 0, and x is -Inf, +Inf is returned. + */ + z = pow(x, 3.0); + + if (isinf(z) == 0 || signbit(z) == 0) + atf_tc_fail_nonfatal("pow(-Inf, 3.0) != -Inf"); + + z = pow(x, 4.0); + + if (isinf(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(-Inf, 4.0) != +Inf"); + + /* + * If y is odd, y < 0, and x is -Inf, -0.0 is returned. + * If y is even, y < 0, and x is -Inf, +0.0 is returned. + */ + z = pow(x, -3.0); + + if (fabs(z) > 0.0 || signbit(z) == 0) + atf_tc_fail_nonfatal("pow(-Inf, -3.0) != -0.0"); + + z = pow(x, -4.0); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(-Inf -4.0) != +0.0"); +} + +ATF_TC(pow_inf_neg_y); +ATF_TC_HEAD(pow_inf_neg_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(x, -Inf) == +Inf || +0.0"); +} + +ATF_TC_BODY(pow_inf_neg_y, tc) +{ + const double y = -1.0L / 0.0L; + double z; + + /* + * If |x| < 1 and y is -Inf, +Inf is returned. + * If |x| > 1 and y is -Inf, +0.0 is returned. + */ + z = pow(0.1, y); + + if (isinf(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(0.1, -Inf) != +Inf"); + + z = pow(1.1, y); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(1.1, -Inf) != +0.0"); +} + +ATF_TC(pow_inf_pos_x); +ATF_TC_HEAD(pow_inf_pos_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(+Inf, y) == +Inf || +0.0"); +} + +ATF_TC_BODY(pow_inf_pos_x, tc) +{ + const double x = 1.0L / 0.0L; + double z; + + /* + * For y < 0, if x is +Inf, +0.0 is returned. + * For y > 0, if x is +Inf, +Inf is returned. + */ + z = pow(x, -2.0); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(+Inf, -2.0) != +0.0"); + + z = pow(x, 2.0); + + if (isinf(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(+Inf, 2.0) != +Inf"); +} + +ATF_TC(pow_inf_pos_y); +ATF_TC_HEAD(pow_inf_pos_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(x, +Inf) == +Inf || +0.0"); +} + +ATF_TC_BODY(pow_inf_pos_y, tc) +{ + const double y = 1.0L / 0.0L; + double z; + + /* + * If |x| < 1 and y is +Inf, +0.0 is returned. + * If |x| > 1 and y is +Inf, +Inf is returned. + */ + z = pow(0.1, y); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(0.1, +Inf) != +0.0"); + + z = pow(1.1, y); + + if (isinf(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(1.1, +Inf) != +Inf"); +} + +ATF_TC(pow_one_neg_x); +ATF_TC_HEAD(pow_one_neg_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(-1.0, +-Inf) == 1.0"); +} + +ATF_TC_BODY(pow_one_neg_x, tc) +{ + const double infp = 1.0L / 0.0L; + const double infn = -1.0L / 0.0L; + + /* + * If x is -1.0, and y is +-Inf, 1.0 shall be returned. + */ + ATF_REQUIRE(isinf(infp) != 0); + ATF_REQUIRE(isinf(infn) != 0); + + if (pow(-1.0, infp) != 1.0) { + atf_tc_expect_fail("PR lib/45372"); + atf_tc_fail_nonfatal("pow(-1.0, +Inf) != 1.0"); + } + + if (pow(-1.0, infn) != 1.0) { + atf_tc_expect_fail("PR lib/45372"); + atf_tc_fail_nonfatal("pow(-1.0, -Inf) != 1.0"); + } +} + +ATF_TC(pow_one_pos_x); +ATF_TC_HEAD(pow_one_pos_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(1.0, y) == 1.0"); +} + +ATF_TC_BODY(pow_one_pos_x, tc) +{ + const double y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 }; + const double z = 0.0L / 0.0L; + size_t i; + + /* + * For any value of y (including NaN), + * if x is 1.0, 1.0 shall be returned. + */ + if (pow(1.0, z) != 1.0) + atf_tc_fail_nonfatal("pow(1.0, NaN) != 1.0"); + + for (i = 0; i < __arraycount(y); i++) { + + if (pow(1.0, y[i]) != 1.0) + atf_tc_fail_nonfatal("pow(1.0, %0.01f) != 1.0", y[i]); + } +} + +ATF_TC(pow_zero_x); +ATF_TC_HEAD(pow_zero_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(+-0.0, y) == +-0.0 || HUGE"); +} + +ATF_TC_BODY(pow_zero_x, tc) +{ + double z; + + /* + * If x is +0.0 or -0.0, y > 0, and y + * is an odd integer, x is returned. + */ + z = pow(+0.0, 3.0); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(+0.0, 3.0) != +0.0"); + + z = pow(-0.0, 3.0); + + if (fabs(z) > 0.0 || signbit(z) == 0) + atf_tc_fail_nonfatal("pow(-0.0, 3.0) != -0.0"); + + /* + * If y > 0 and not an odd integer, + * if x is +0.0 or -0.0, +0.0 is returned. + */ + z = pow(+0.0, 4.0); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(+0.0, 4.0) != +0.0"); + + z = pow(-0.0, 4.0); + + if (fabs(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("pow(-0.0, 4.0) != +0.0"); + + /* + * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL, + * +-HUGE_VALF, or +-HUGE_VALL shall be returned. + */ + z = pow(+0.0, -4.0); + + if (z != HUGE_VAL) { + atf_tc_fail_nonfatal("pow(+0.0, -4.0) != HUGE_VAL"); + } + + z = pow(-0.0, -4.0); + + if (z != HUGE_VAL) { + atf_tc_fail_nonfatal("pow(-0.0, -4.0) != HUGE_VAL"); + } + + z = pow(+0.0, -5.0); + + if (z != HUGE_VAL) { + atf_tc_fail_nonfatal("pow(+0.0, -5.0) != HUGE_VAL"); + } + + z = pow(-0.0, -5.0); + + if (z != -HUGE_VAL) + atf_tc_fail_nonfatal("pow(-0.0, -5.0) != -HUGE_VAL"); +} + +ATF_TC(pow_zero_y); +ATF_TC_HEAD(pow_zero_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pow(x, +-0.0) == 1.0"); +} + +ATF_TC_BODY(pow_zero_y, tc) +{ + const double x[] = { 0.1, -3.0, 77.0, 99.99, 101.0000001 }; + const double z = 0.0L / 0.0L; + size_t i; + + /* + * For any value of x (including NaN), + * if y is +0.0 or -0.0, 1.0 is returned. + */ + if (pow(z, +0.0) != 1.0) + atf_tc_fail_nonfatal("pow(NaN, +0.0) != 1.0"); + + if (pow(z, -0.0) != 1.0) + atf_tc_fail_nonfatal("pow(NaN, -0.0) != 1.0"); + + for (i = 0; i < __arraycount(x); i++) { + + if (pow(x[i], +0.0) != 1.0) + atf_tc_fail_nonfatal("pow(%0.01f, +0.0) != 1.0", x[i]); + + if (pow(x[i], -0.0) != 1.0) + atf_tc_fail_nonfatal("pow(%0.01f, -0.0) != 1.0", x[i]); + } +} + +/* + * powf(3) + */ +ATF_TC(powf_nan_x); +ATF_TC_HEAD(powf_nan_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(NaN, y) == NaN"); +} + +ATF_TC_BODY(powf_nan_x, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnanf(powf(x, 2.0)) != 0); +} + +ATF_TC(powf_nan_y); +ATF_TC_HEAD(powf_nan_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(x, NaN) == NaN"); +} + +ATF_TC_BODY(powf_nan_y, tc) +{ + const float y = 0.0L / 0.0L; + + ATF_CHECK(isnanf(powf(2.0, y)) != 0); +} + +ATF_TC(powf_inf_neg_x); +ATF_TC_HEAD(powf_inf_neg_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(-Inf, y) == +-Inf || +-0.0"); +} + +ATF_TC_BODY(powf_inf_neg_x, tc) +{ + const float x = -1.0L / 0.0L; + float z; + + /* + * If y is odd, y > 0, and x is -Inf, -Inf is returned. + * If y is even, y > 0, and x is -Inf, +Inf is returned. + */ + z = powf(x, 3.0); + + if (isinf(z) == 0 || signbit(z) == 0) + atf_tc_fail_nonfatal("powf(-Inf, 3.0) != -Inf"); + + z = powf(x, 4.0); + + if (isinf(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(-Inf, 4.0) != +Inf"); + + /* + * If y is odd, y < 0, and x is -Inf, -0.0 is returned. + * If y is even, y < 0, and x is -Inf, +0.0 is returned. + */ + z = powf(x, -3.0); + + if (fabsf(z) > 0.0 || signbit(z) == 0) { + atf_tc_expect_fail("PR lib/45372"); + atf_tc_fail_nonfatal("powf(-Inf, -3.0) != -0.0"); + } + + z = powf(x, -4.0); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(-Inf -4.0) != +0.0"); +} + +ATF_TC(powf_inf_neg_y); +ATF_TC_HEAD(powf_inf_neg_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(x, -Inf) == +Inf || +0.0"); +} + +ATF_TC_BODY(powf_inf_neg_y, tc) +{ + const float y = -1.0L / 0.0L; + float z; + + /* + * If |x| < 1 and y is -Inf, +Inf is returned. + * If |x| > 1 and y is -Inf, +0.0 is returned. + */ + z = powf(0.1, y); + + if (isinf(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(0.1, -Inf) != +Inf"); + + z = powf(1.1, y); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(1.1, -Inf) != +0.0"); +} + +ATF_TC(powf_inf_pos_x); +ATF_TC_HEAD(powf_inf_pos_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(+Inf, y) == +Inf || +0.0"); +} + +ATF_TC_BODY(powf_inf_pos_x, tc) +{ + const float x = 1.0L / 0.0L; + float z; + + /* + * For y < 0, if x is +Inf, +0.0 is returned. + * For y > 0, if x is +Inf, +Inf is returned. + */ + z = powf(x, -2.0); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(+Inf, -2.0) != +0.0"); + + z = powf(x, 2.0); + + if (isinf(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(+Inf, 2.0) != +Inf"); +} + +ATF_TC(powf_inf_pos_y); +ATF_TC_HEAD(powf_inf_pos_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(x, +Inf) == +Inf || +0.0"); +} + +ATF_TC_BODY(powf_inf_pos_y, tc) +{ + const float y = 1.0L / 0.0L; + float z; + + /* + * If |x| < 1 and y is +Inf, +0.0 is returned. + * If |x| > 1 and y is +Inf, +Inf is returned. + */ + z = powf(0.1, y); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(0.1, +Inf) != +0.0"); + + z = powf(1.1, y); + + if (isinf(z) == 0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(1.1, +Inf) != +Inf"); +} + +ATF_TC(powf_one_neg_x); +ATF_TC_HEAD(powf_one_neg_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(-1.0, +-Inf) == 1.0"); +} + +ATF_TC_BODY(powf_one_neg_x, tc) +{ + const float infp = 1.0L / 0.0L; + const float infn = -1.0L / 0.0L; + + /* + * If x is -1.0, and y is +-Inf, 1.0 shall be returned. + */ + ATF_REQUIRE(isinf(infp) != 0); + ATF_REQUIRE(isinf(infn) != 0); + + if (powf(-1.0, infp) != 1.0) { + atf_tc_expect_fail("PR lib/45372"); + atf_tc_fail_nonfatal("powf(-1.0, +Inf) != 1.0"); + } + + if (powf(-1.0, infn) != 1.0) { + atf_tc_expect_fail("PR lib/45372"); + atf_tc_fail_nonfatal("powf(-1.0, -Inf) != 1.0"); + } +} + +ATF_TC(powf_one_pos_x); +ATF_TC_HEAD(powf_one_pos_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(1.0, y) == 1.0"); +} + +ATF_TC_BODY(powf_one_pos_x, tc) +{ + const float y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 }; + const float z = 0.0L / 0.0L; + size_t i; + + /* + * For any value of y (including NaN), + * if x is 1.0, 1.0 shall be returned. + */ + if (powf(1.0, z) != 1.0) + atf_tc_fail_nonfatal("powf(1.0, NaN) != 1.0"); + + for (i = 0; i < __arraycount(y); i++) { + + if (powf(1.0, y[i]) != 1.0) + atf_tc_fail_nonfatal("powf(1.0, %0.01f) != 1.0", y[i]); + } +} + +ATF_TC(powf_zero_x); +ATF_TC_HEAD(powf_zero_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(+-0.0, y) == +-0.0 || HUGE"); +} + +ATF_TC_BODY(powf_zero_x, tc) +{ + float z; + + /* + * If x is +0.0 or -0.0, y > 0, and y + * is an odd integer, x is returned. + */ + z = powf(+0.0, 3.0); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(+0.0, 3.0) != +0.0"); + + z = powf(-0.0, 3.0); + + if (fabsf(z) > 0.0 || signbit(z) == 0) + atf_tc_fail_nonfatal("powf(-0.0, 3.0) != -0.0"); + + /* + * If y > 0 and not an odd integer, + * if x is +0.0 or -0.0, +0.0 is returned. + */ + z = powf(+0.0, 4.0); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(+0.0, 4.0) != +0.0"); + + z = powf(-0.0, 4.0); + + if (fabsf(z) > 0.0 || signbit(z) != 0) + atf_tc_fail_nonfatal("powf(-0.0, 4.0) != +0.0"); + + /* + * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL, + * +-HUGE_VALF, or +-HUGE_VALL shall be returned. + */ + z = powf(+0.0, -4.0); + + if (z != HUGE_VALF) { + atf_tc_expect_fail("PR port-amd64/45391"); + atf_tc_fail_nonfatal("powf(+0.0, -4.0) != HUGE_VALF"); + } + + z = powf(-0.0, -4.0); + + if (z != HUGE_VALF) { + atf_tc_expect_fail("PR port-amd64/45391"); + atf_tc_fail_nonfatal("powf(-0.0, -4.0) != HUGE_VALF"); + } + + z = powf(+0.0, -5.0); + + if (z != HUGE_VALF) { + atf_tc_expect_fail("PR port-amd64/45391"); + atf_tc_fail_nonfatal("powf(+0.0, -5.0) != HUGE_VALF"); + } + + z = powf(-0.0, -5.0); + + if (z != -HUGE_VALF) + atf_tc_fail_nonfatal("powf(-0.0, -5.0) != -HUGE_VALF"); +} + +ATF_TC(powf_zero_y); +ATF_TC_HEAD(powf_zero_y, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test powf(x, +-0.0) == 1.0"); +} + +ATF_TC_BODY(powf_zero_y, tc) +{ + const float x[] = { 0.1, -3.0, 77.0, 99.99, 101.0000001 }; + const float z = 0.0L / 0.0L; + size_t i; + + /* + * For any value of x (including NaN), + * if y is +0.0 or -0.0, 1.0 is returned. + */ + if (powf(z, +0.0) != 1.0) + atf_tc_fail_nonfatal("powf(NaN, +0.0) != 1.0"); + + if (powf(z, -0.0) != 1.0) + atf_tc_fail_nonfatal("powf(NaN, -0.0) != 1.0"); + + for (i = 0; i < __arraycount(x); i++) { + + if (powf(x[i], +0.0) != 1.0) + atf_tc_fail_nonfatal("powf(%0.01f, +0.0) != 1.0",x[i]); + + if (powf(x[i], -0.0) != 1.0) + atf_tc_fail_nonfatal("powf(%0.01f, -0.0) != 1.0",x[i]); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pow_nan_x); + ATF_TP_ADD_TC(tp, pow_nan_y); + ATF_TP_ADD_TC(tp, pow_inf_neg_x); + ATF_TP_ADD_TC(tp, pow_inf_neg_y); + ATF_TP_ADD_TC(tp, pow_inf_pos_x); + ATF_TP_ADD_TC(tp, pow_inf_pos_y); + ATF_TP_ADD_TC(tp, pow_one_neg_x); + ATF_TP_ADD_TC(tp, pow_one_pos_x); + ATF_TP_ADD_TC(tp, pow_zero_x); + ATF_TP_ADD_TC(tp, pow_zero_y); + + ATF_TP_ADD_TC(tp, powf_nan_x); + ATF_TP_ADD_TC(tp, powf_nan_y); + ATF_TP_ADD_TC(tp, powf_inf_neg_x); + ATF_TP_ADD_TC(tp, powf_inf_neg_y); + ATF_TP_ADD_TC(tp, powf_inf_pos_x); + ATF_TP_ADD_TC(tp, powf_inf_pos_y); + ATF_TP_ADD_TC(tp, powf_one_neg_x); + ATF_TP_ADD_TC(tp, powf_one_pos_x); + ATF_TP_ADD_TC(tp, powf_zero_x); + ATF_TP_ADD_TC(tp, powf_zero_y); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_precision.c b/contrib/netbsd-tests/lib/libm/t_precision.c new file mode 100644 index 0000000..eb8e295 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_precision.c @@ -0,0 +1,84 @@ +/* $NetBSD: t_precision.c,v 1.3 2016/08/27 10:07:05 christos Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_precision.c,v 1.3 2016/08/27 10:07:05 christos Exp $"); + +#include + +#include +#include + +ATF_TC(t_precision); + +ATF_TC_HEAD(t_precision, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Basic precision test for double and long double"); +} + +volatile double x = 1; +#if __HAVE_LONG_DOUBLE +volatile long double y = 1; +#endif + +ATF_TC_BODY(t_precision, tc) +{ +#ifdef __FreeBSD__ +#ifdef __i386__ + atf_tc_expect_fail("the __HAVE_LONG_DOUBLE checks fail on i386"); +#endif +#endif + x += DBL_EPSILON; + ATF_CHECK(x != 1.0); + x -= 1; + ATF_CHECK(x == DBL_EPSILON); + + x = 2; + x += DBL_EPSILON; + ATF_CHECK(x == 2.0); + +#if __HAVE_LONG_DOUBLE + y += LDBL_EPSILON; + ATF_CHECK(y != 1.0L); + y -= 1; + ATF_CHECK(y == LDBL_EPSILON); + y = 2; + y += LDBL_EPSILON; + ATF_CHECK(y == 2.0L); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_precision); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_round.c b/contrib/netbsd-tests/lib/libm/t_round.c new file mode 100644 index 0000000..f47e1a0 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_round.c @@ -0,0 +1,85 @@ +/* $NetBSD: t_round.c,v 1.4 2013/11/11 23:57:34 joerg Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +/* + * This tests for a bug in the initial implementation where + * precision was lost in an internal substraction, leading to + * rounding into the wrong direction. + */ + +/* 0.5 - EPSILON */ +#define VAL 0x0.7ffffffffffffcp0 +#define VALF 0x0.7fffff8p0 +#define VALL (0.5 - LDBL_EPSILON) + +#ifdef __vax__ +#define SMALL_NUM 1.0e-38 +#else +#define SMALL_NUM 1.0e-40 +#endif + +ATF_TC(round_dir); +ATF_TC_HEAD(round_dir, tc) +{ + atf_tc_set_md_var(tc, "descr","Check for rounding in wrong direction"); +} + +ATF_TC_BODY(round_dir, tc) +{ + double a = VAL, b, c; + float af = VALF, bf, cf; + long double al = VALL, bl, cl; + + b = round(a); + bf = roundf(af); + bl = roundl(al); + + ATF_CHECK(fabs(b) < SMALL_NUM); + ATF_CHECK(fabsf(bf) < SMALL_NUM); + ATF_CHECK(fabsl(bl) < SMALL_NUM); + + c = round(-a); + cf = roundf(-af); + cl = roundl(-al); + + ATF_CHECK(fabs(c) < SMALL_NUM); + ATF_CHECK(fabsf(cf) < SMALL_NUM); + ATF_CHECK(fabsl(cl) < SMALL_NUM); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, round_dir); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_scalbn.c b/contrib/netbsd-tests/lib/libm/t_scalbn.c new file mode 100644 index 0000000..4bf00c3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_scalbn.c @@ -0,0 +1,526 @@ +/* $NetBSD: t_scalbn.c,v 1.14 2017/01/13 21:09:12 agc Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_scalbn.c,v 1.14 2017/01/13 21:09:12 agc Exp $"); + +#include +#include +#include +#include + +#include + +static const int exps[] = { 0, 1, -1, 100, -100 }; + +/* tests here do not require specific precision, so we just use double */ +struct testcase { + int exp; + double inval; + double result; + int error; +}; +struct testcase test_vals[] = { + { 0, 1.00085, 1.00085, 0 }, + { 0, 0.99755, 0.99755, 0 }, + { 0, -1.00085, -1.00085, 0 }, + { 0, -0.99755, -0.99755, 0 }, + { 1, 1.00085, 2.0* 1.00085, 0 }, + { 1, 0.99755, 2.0* 0.99755, 0 }, + { 1, -1.00085, 2.0* -1.00085, 0 }, + { 1, -0.99755, 2.0* -0.99755, 0 }, + + /* + * We could add more corner test cases here, but we would have to + * add some ifdefs for the exact format and use a reliable + * generator program - bail for now and only do trivial stuff above. + */ +}; + +/* + * scalbn(3) + */ +ATF_TC(scalbn_val); +ATF_TC_HEAD(scalbn_val, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn() for a few values"); +} + +ATF_TC_BODY(scalbn_val, tc) +{ + const struct testcase *tests = test_vals; + const size_t tcnt = __arraycount(test_vals); + size_t i; + double rv; + + for (i = 0; i < tcnt; i++) { + errno = 0; + rv = scalbn(tests[i].inval, tests[i].exp); + ATF_CHECK_EQ_MSG(errno, tests[i].error, + "test %zu: errno %d instead of %d", i, errno, + tests[i].error); + ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*DBL_EPSILON, + "test %zu: return value %g instead of %g (difference %g)", + i, rv, tests[i].result, tests[i].result-rv); + } +} + +ATF_TC(scalbn_nan); +ATF_TC_HEAD(scalbn_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn(NaN, n) == NaN"); +} + +ATF_TC_BODY(scalbn_nan, tc) +{ + const double x = 0.0L / 0.0L; + double y; + size_t i; + + ATF_REQUIRE(isnan(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbn(x, exps[i]); + ATF_CHECK(isnan(y) != 0); + } +} + +ATF_TC(scalbn_inf_neg); +ATF_TC_HEAD(scalbn_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn(-Inf, n) == -Inf"); +} + +ATF_TC_BODY(scalbn_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(scalbn(x, exps[i]) == x); +} + +ATF_TC(scalbn_inf_pos); +ATF_TC_HEAD(scalbn_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn(+Inf, n) == +Inf"); +} + +ATF_TC_BODY(scalbn_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(scalbn(x, exps[i]) == x); +} + +ATF_TC(scalbn_ldexp); +ATF_TC_HEAD(scalbn_ldexp, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn(x, n) == ldexp(x, n)"); +} + +ATF_TC_BODY(scalbn_ldexp, tc) +{ +#if FLT_RADIX == 2 + const double x = 2.91288191221812821; + double y; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbn(x, exps[i]); + ATF_CHECK_MSG(y == ldexp(x, exps[i]), "test %zu: exponent=%d, " + "y=%g, expected %g (diff: %g)", i, exps[i], y, + ldexp(x, exps[i]), y - ldexp(x, exps[i])); + } +#endif +} + +ATF_TC(scalbn_zero_neg); +ATF_TC_HEAD(scalbn_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn(-0.0, n) == -0.0"); +} + +ATF_TC_BODY(scalbn_zero_neg, tc) +{ + const double x = -0.0L; + double y; + size_t i; + + ATF_REQUIRE(signbit(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbn(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) != 0); + } +} + +ATF_TC(scalbn_zero_pos); +ATF_TC_HEAD(scalbn_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn(+0.0, n) == +0.0"); +} + +ATF_TC_BODY(scalbn_zero_pos, tc) +{ + const double x = 0.0L; + double y; + size_t i; + + ATF_REQUIRE(signbit(x) == 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbn(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) == 0); + } +} + +/* + * scalbnf(3) + */ +ATF_TC(scalbnf_val); +ATF_TC_HEAD(scalbnf_val, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf() for a few values"); +} + +ATF_TC_BODY(scalbnf_val, tc) +{ + const struct testcase *tests = test_vals; + const size_t tcnt = __arraycount(test_vals); + size_t i; + double rv; + + for (i = 0; i < tcnt; i++) { + errno = 0; + rv = scalbnf(tests[i].inval, tests[i].exp); + ATF_CHECK_EQ_MSG(errno, tests[i].error, + "test %zu: errno %d instead of %d", i, errno, + tests[i].error); + ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*FLT_EPSILON, + "test %zu: return value %g instead of %g (difference %g)", + i, rv, tests[i].result, tests[i].result-rv); + } +} + +ATF_TC(scalbnf_nan); +ATF_TC_HEAD(scalbnf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf(NaN, n) == NaN"); +} + +ATF_TC_BODY(scalbnf_nan, tc) +{ + const float x = 0.0L / 0.0L; + float y; + size_t i; + + ATF_REQUIRE(isnan(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnf(x, exps[i]); + ATF_CHECK(isnan(y) != 0); + } +} + +ATF_TC(scalbnf_inf_neg); +ATF_TC_HEAD(scalbnf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf(-Inf, n) == -Inf"); +} + +ATF_TC_BODY(scalbnf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(scalbnf(x, exps[i]) == x); +} + +ATF_TC(scalbnf_inf_pos); +ATF_TC_HEAD(scalbnf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf(+Inf, n) == +Inf"); +} + +ATF_TC_BODY(scalbnf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(scalbnf(x, exps[i]) == x); +} + +ATF_TC(scalbnf_ldexpf); +ATF_TC_HEAD(scalbnf_ldexpf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf(x, n) == ldexpf(x, n)"); +} + +ATF_TC_BODY(scalbnf_ldexpf, tc) +{ +#if FLT_RADIX == 2 + const float x = 2.91288191221812821; + float y; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnf(x, exps[i]); + ATF_CHECK_MSG(y == ldexpf(x, exps[i]), + "test %zu: exponent=%d, y=%g ldexpf returns %g (diff: %g)", + i, exps[i], y, ldexpf(x, exps[i]), y-ldexpf(x, exps[i])); + } +#endif +} + +ATF_TC(scalbnf_zero_neg); +ATF_TC_HEAD(scalbnf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf(-0.0, n) == -0.0"); +} + +ATF_TC_BODY(scalbnf_zero_neg, tc) +{ + const float x = -0.0L; + float y; + size_t i; + + ATF_REQUIRE(signbit(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnf(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) != 0); + } +} + +ATF_TC(scalbnf_zero_pos); +ATF_TC_HEAD(scalbnf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf(+0.0, n) == +0.0"); +} + +ATF_TC_BODY(scalbnf_zero_pos, tc) +{ + const float x = 0.0L; + float y; + size_t i; + + ATF_REQUIRE(signbit(x) == 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnf(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) == 0); + } +} + +/* + * scalbnl(3) + */ +ATF_TC(scalbnl_val); +ATF_TC_HEAD(scalbnl_val, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl() for a few values"); +} + +ATF_TC_BODY(scalbnl_val, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const struct testcase *tests = test_vals; + const size_t tcnt = __arraycount(test_vals); + size_t i; + long double rv; + + for (i = 0; i < tcnt; i++) { + errno = 0; + rv = scalbnl(tests[i].inval, tests[i].exp); + ATF_CHECK_EQ_MSG(errno, tests[i].error, + "test %zu: errno %d instead of %d", i, errno, + tests[i].error); + ATF_CHECK_MSG(fabsl(rv-(long double)tests[i].result)<2.0*LDBL_EPSILON, + "test %zu: return value %Lg instead of %Lg (difference %Lg)", + i, rv, (long double)tests[i].result, (long double)tests[i].result-rv); + } +#endif +} + +ATF_TC(scalbnl_nan); +ATF_TC_HEAD(scalbnl_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl(NaN, n) == NaN"); +} + +ATF_TC_BODY(scalbnl_nan, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const long double x = 0.0L / 0.0L; + long double y; + size_t i; + + if (isnan(x) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("(0.0L / 0.0L) != NaN"); + } + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnl(x, exps[i]); + ATF_CHECK(isnan(y) != 0); + } +#endif +} + +ATF_TC(scalbnl_inf_neg); +ATF_TC_HEAD(scalbnl_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl(-Inf, n) == -Inf"); +} + +ATF_TC_BODY(scalbnl_inf_neg, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const long double x = -1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(scalbnl(x, exps[i]) == x); +#endif +} + +ATF_TC(scalbnl_inf_pos); +ATF_TC_HEAD(scalbnl_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl(+Inf, n) == +Inf"); +} + +ATF_TC_BODY(scalbnl_inf_pos, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const long double x = 1.0L / 0.0L; + size_t i; + + for (i = 0; i < __arraycount(exps); i++) + ATF_CHECK(scalbnl(x, exps[i]) == x); +#endif +} + +ATF_TC(scalbnl_zero_neg); +ATF_TC_HEAD(scalbnl_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl(-0.0, n) == -0.0"); +} + +ATF_TC_BODY(scalbnl_zero_neg, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const long double x = -0.0L; + long double y; + size_t i; + + ATF_REQUIRE(signbit(x) != 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnl(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) != 0); + } +#endif +} + +ATF_TC(scalbnl_zero_pos); +ATF_TC_HEAD(scalbnl_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl(+0.0, n) == +0.0"); +} + +ATF_TC_BODY(scalbnl_zero_pos, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const long double x = 0.0L; + long double y; + size_t i; + + ATF_REQUIRE(signbit(x) == 0); + + for (i = 0; i < __arraycount(exps); i++) { + y = scalbnl(x, exps[i]); + ATF_CHECK(x == y); + ATF_CHECK(signbit(y) == 0); + } +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, scalbn_val); + ATF_TP_ADD_TC(tp, scalbn_nan); + ATF_TP_ADD_TC(tp, scalbn_inf_neg); + ATF_TP_ADD_TC(tp, scalbn_inf_pos); + ATF_TP_ADD_TC(tp, scalbn_ldexp); + ATF_TP_ADD_TC(tp, scalbn_zero_neg); + ATF_TP_ADD_TC(tp, scalbn_zero_pos); + + ATF_TP_ADD_TC(tp, scalbnf_val); + ATF_TP_ADD_TC(tp, scalbnf_nan); + ATF_TP_ADD_TC(tp, scalbnf_inf_neg); + ATF_TP_ADD_TC(tp, scalbnf_inf_pos); + ATF_TP_ADD_TC(tp, scalbnf_ldexpf); + ATF_TP_ADD_TC(tp, scalbnf_zero_neg); + ATF_TP_ADD_TC(tp, scalbnf_zero_pos); + + ATF_TP_ADD_TC(tp, scalbnl_val); + ATF_TP_ADD_TC(tp, scalbnl_nan); + ATF_TP_ADD_TC(tp, scalbnl_inf_neg); + ATF_TP_ADD_TC(tp, scalbnl_inf_pos); +/* ATF_TP_ADD_TC(tp, scalbnl_ldexp); */ + ATF_TP_ADD_TC(tp, scalbnl_zero_neg); + ATF_TP_ADD_TC(tp, scalbnl_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_sin.c b/contrib/netbsd-tests/lib/libm/t_sin.c new file mode 100644 index 0000000..a82f49d --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_sin.c @@ -0,0 +1,263 @@ +/* $NetBSD: t_sin.c,v 1.4 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +static const struct { + int angle; + double x; + double y; +} angles[] = { + { -180, -3.141592653589793, 0.0000000000000000 }, + { -135, -2.356194490192345, -0.7071067811865476 }, + { -90, -1.570796326794897, -1.0000000000000000 }, + { -45, -0.785398163397448, -0.7071067811865476 }, + { 0, 0.000000000000000, 0.0000000000000000 }, + { 30, 0.523598775598299, 0.5000000000000000 }, + { 45, 0.785398163397448, 0.7071067811865476 }, + { 60, 1.047197551196598, 0.8660254037844386 }, + { 90, 1.570796326794897, 1.0000000000000000 }, + { 120, 2.094395102393195, 0.8660254037844386 }, + { 135, 2.356194490192345, 0.7071067811865476 }, + { 150, 2.617993877991494, 0.5000000000000000 }, + { 180, 3.141592653589793, 0.0000000000000000 }, + { 270, 4.712388980384690, -1.0000000000000000 }, + { 360, 6.283185307179586, 0.0000000000000000 } +}; + +/* + * sin(3) + */ +ATF_TC(sin_angles); +ATF_TC_HEAD(sin_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(sin_angles, tc) +{ + const double eps = 1.0e-15; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + + if (fabs(sin(angles[i].x) - angles[i].y) > eps) + atf_tc_fail_nonfatal("sin(%d deg) != %0.01f", + angles[i].angle, angles[i].y); + } +} + +ATF_TC(sin_nan); +ATF_TC_HEAD(sin_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sin(NaN) == NaN"); +} + +ATF_TC_BODY(sin_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sin(x)) != 0); +} + +ATF_TC(sin_inf_neg); +ATF_TC_HEAD(sin_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sin(-Inf) == NaN"); +} + +ATF_TC_BODY(sin_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + ATF_CHECK(isnan(sin(x)) != 0); +} + +ATF_TC(sin_inf_pos); +ATF_TC_HEAD(sin_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sin(+Inf) == NaN"); +} + +ATF_TC_BODY(sin_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(isnan(sin(x)) != 0); +} + + +ATF_TC(sin_zero_neg); +ATF_TC_HEAD(sin_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sin(-0.0) == -0.0"); +} + +ATF_TC_BODY(sin_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(sin(x) == x); +} + +ATF_TC(sin_zero_pos); +ATF_TC_HEAD(sin_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sin(+0.0) == +0.0"); +} + +ATF_TC_BODY(sin_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(sin(x) == x); +} + +/* + * sinf(3) + */ +ATF_TC(sinf_angles); +ATF_TC_HEAD(sinf_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(sinf_angles, tc) +{ + const float eps = 1.0e-6; + float x, y; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + + x = angles[i].x; + y = angles[i].y; + + if (fabsf(sinf(x) - y) > eps) + atf_tc_fail_nonfatal("sinf(%d deg) != %0.01f", + angles[i].angle, angles[i].y); + } +} + +ATF_TC(sinf_nan); +ATF_TC_HEAD(sinf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinf(NaN) == NaN"); +} + +ATF_TC_BODY(sinf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sinf(x)) != 0); +} + +ATF_TC(sinf_inf_neg); +ATF_TC_HEAD(sinf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinf(-Inf) == NaN"); +} + +ATF_TC_BODY(sinf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (isnan(sinf(x)) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("sinf(-Inf) != NaN"); + } +} + +ATF_TC(sinf_inf_pos); +ATF_TC_HEAD(sinf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinf(+Inf) == NaN"); +} + +ATF_TC_BODY(sinf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + if (isnan(sinf(x)) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("sinf(+Inf) != NaN"); + } +} + + +ATF_TC(sinf_zero_neg); +ATF_TC_HEAD(sinf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinf(-0.0) == -0.0"); +} + +ATF_TC_BODY(sinf_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(sinf(x) == x); +} + +ATF_TC(sinf_zero_pos); +ATF_TC_HEAD(sinf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinf(+0.0) == +0.0"); +} + +ATF_TC_BODY(sinf_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(sinf(x) == x); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sin_angles); + ATF_TP_ADD_TC(tp, sin_nan); + ATF_TP_ADD_TC(tp, sin_inf_neg); + ATF_TP_ADD_TC(tp, sin_inf_pos); + ATF_TP_ADD_TC(tp, sin_zero_neg); + ATF_TP_ADD_TC(tp, sin_zero_pos); + + ATF_TP_ADD_TC(tp, sinf_angles); + ATF_TP_ADD_TC(tp, sinf_nan); + ATF_TP_ADD_TC(tp, sinf_inf_neg); + ATF_TP_ADD_TC(tp, sinf_inf_pos); + ATF_TP_ADD_TC(tp, sinf_zero_neg); + ATF_TP_ADD_TC(tp, sinf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_sinh.c b/contrib/netbsd-tests/lib/libm/t_sinh.c new file mode 100644 index 0000000..d935f0e --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_sinh.c @@ -0,0 +1,273 @@ +/* $NetBSD: t_sinh.c,v 1.6 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_sinh.c,v 1.6 2014/03/03 10:39:08 martin Exp $"); + +#include +#include +#include + +static const struct { + double x; + double y; + double e; +} values[] = { + { -10, -11013.23287470339, 1e4, }, + { -2, -3.626860407847019, 1, }, + { -1, -1.175201193643801, 1, }, + { -0.05, -0.050020835937655, 1, }, + { -0.001,-0.001000000166667, 1, }, + { 0.001, 0.001000000166667, 1, }, + { 0.05, 0.050020835937655, 1, }, + { 1, 1.175201193643801, 1, }, + { 2, 3.626860407847019, 1, }, + { 10, 11013.23287470339, 1e4, }, +}; + +/* + * sinh(3) + */ +ATF_TC(sinh_inrange); +ATF_TC_HEAD(sinh_inrange, tc) +{ + atf_tc_set_md_var(tc, "descr", "sinh(x) for some values"); +} + +ATF_TC_BODY(sinh_inrange, tc) +{ + double eps; + double x; + double y; + size_t i; + + for (i = 0; i < __arraycount(values); i++) { + x = values[i].x; + y = values[i].y; + eps = 1e-15 * values[i].e; + + if (fabs(sinh(x) - y) > eps) + atf_tc_fail_nonfatal("sinh(%g) != %g\n", x, y); + } +} + +ATF_TC(sinh_nan); +ATF_TC_HEAD(sinh_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinh(NaN) == NaN"); +} + +ATF_TC_BODY(sinh_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sinh(x)) != 0); +} + +ATF_TC(sinh_inf_neg); +ATF_TC_HEAD(sinh_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinh(-Inf) == -Inf"); +} + +ATF_TC_BODY(sinh_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = sinh(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) != 0); +} + +ATF_TC(sinh_inf_pos); +ATF_TC_HEAD(sinh_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinh(+Inf) == +Inf"); +} + +ATF_TC_BODY(sinh_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = sinh(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(sinh_zero_neg); +ATF_TC_HEAD(sinh_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinh(-0.0) == -0.0"); +} + +ATF_TC_BODY(sinh_zero_neg, tc) +{ + const double x = -0.0L; + double y = sinh(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("sinh(-0.0) != -0.0"); +} + +ATF_TC(sinh_zero_pos); +ATF_TC_HEAD(sinh_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinh(+0.0) == +0.0"); +} + +ATF_TC_BODY(sinh_zero_pos, tc) +{ + const double x = 0.0L; + double y = sinh(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("sinh(+0.0) != +0.0"); +} + +/* + * sinhf(3) + */ +ATF_TC(sinhf_inrange); +ATF_TC_HEAD(sinhf_inrange, tc) +{ + atf_tc_set_md_var(tc, "descr", "sinhf(x) for some values"); +} + +ATF_TC_BODY(sinhf_inrange, tc) +{ + float eps; + float x; + float y; + size_t i; + + for (i = 0; i < __arraycount(values); i++) { + x = values[i].x; + y = values[i].y; + eps = 1e-6 * values[i].e; + + if (fabsf(sinhf(x) - y) > eps) + atf_tc_fail_nonfatal("sinhf(%g) != %g\n", x, y); + } +} + +ATF_TC(sinhf_nan); +ATF_TC_HEAD(sinhf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinhf(NaN) == NaN"); +} + +ATF_TC_BODY(sinhf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sinhf(x)) != 0); +} + +ATF_TC(sinhf_inf_neg); +ATF_TC_HEAD(sinhf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinhf(-Inf) == -Inf"); +} + +ATF_TC_BODY(sinhf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = sinhf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) != 0); +} + +ATF_TC(sinhf_inf_pos); +ATF_TC_HEAD(sinhf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinhf(+Inf) == +Inf"); +} + +ATF_TC_BODY(sinhf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = sinhf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(sinhf_zero_neg); +ATF_TC_HEAD(sinhf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinhf(-0.0) == -0.0"); +} + +ATF_TC_BODY(sinhf_zero_neg, tc) +{ + const float x = -0.0L; + float y = sinhf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("sinhf(-0.0) != -0.0"); +} + +ATF_TC(sinhf_zero_pos); +ATF_TC_HEAD(sinhf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sinhf(+0.0) == +0.0"); +} + +ATF_TC_BODY(sinhf_zero_pos, tc) +{ + const float x = 0.0L; + float y = sinhf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("sinhf(+0.0) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sinh_inrange); + ATF_TP_ADD_TC(tp, sinh_nan); + ATF_TP_ADD_TC(tp, sinh_inf_neg); + ATF_TP_ADD_TC(tp, sinh_inf_pos); + ATF_TP_ADD_TC(tp, sinh_zero_neg); + ATF_TP_ADD_TC(tp, sinh_zero_pos); + + ATF_TP_ADD_TC(tp, sinhf_inrange); + ATF_TP_ADD_TC(tp, sinhf_nan); + ATF_TP_ADD_TC(tp, sinhf_inf_neg); + ATF_TP_ADD_TC(tp, sinhf_inf_pos); + ATF_TP_ADD_TC(tp, sinhf_zero_neg); + ATF_TP_ADD_TC(tp, sinhf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_sqrt.c b/contrib/netbsd-tests/lib/libm/t_sqrt.c new file mode 100644 index 0000000..1d551ec --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_sqrt.c @@ -0,0 +1,368 @@ +/* $NetBSD: t_sqrt.c,v 1.7 2014/03/12 21:40:07 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_sqrt.c,v 1.7 2014/03/12 21:40:07 martin Exp $"); + +#include +#include +#include +#include + +/* + * sqrt(3) + */ +ATF_TC(sqrt_nan); +ATF_TC_HEAD(sqrt_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrt(NaN) == NaN"); +} + +ATF_TC_BODY(sqrt_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sqrt(x)) != 0); +} + +ATF_TC(sqrt_pow); +ATF_TC_HEAD(sqrt_pow, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrt(3) vs. pow(3)"); +} + +ATF_TC_BODY(sqrt_pow, tc) +{ + const double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 }; +#if __DBL_MIN_10_EXP__ <= -40 + const double eps = 1.0e-40; +#else + const double eps = __DBL_MIN__*4.0; +#endif + double y, z; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + y = sqrt(x[i]); + z = pow(x[i], 1.0 / 2.0); + + if (fabs(y - z) > eps) + atf_tc_fail_nonfatal("sqrt(%0.03f) != " + "pow(%0.03f, 1/2)\n", x[i], x[i]); + } +} + +ATF_TC(sqrt_inf_neg); +ATF_TC_HEAD(sqrt_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrt(-Inf) == NaN"); +} + +ATF_TC_BODY(sqrt_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + double y = sqrt(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(sqrt_inf_pos); +ATF_TC_HEAD(sqrt_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrt(+Inf) == +Inf"); +} + +ATF_TC_BODY(sqrt_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + double y = sqrt(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(sqrt_zero_neg); +ATF_TC_HEAD(sqrt_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrt(-0.0) == -0.0"); +} + +ATF_TC_BODY(sqrt_zero_neg, tc) +{ + const double x = -0.0L; + double y = sqrt(x); + + if (fabs(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("sqrt(-0.0) != -0.0"); +} + +ATF_TC(sqrt_zero_pos); +ATF_TC_HEAD(sqrt_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrt(+0.0) == +0.0"); +} + +ATF_TC_BODY(sqrt_zero_pos, tc) +{ + const double x = 0.0L; + double y = sqrt(x); + + if (fabs(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("sqrt(+0.0) != +0.0"); +} + +/* + * sqrtf(3) + */ +ATF_TC(sqrtf_nan); +ATF_TC_HEAD(sqrtf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtf(NaN) == NaN"); +} + +ATF_TC_BODY(sqrtf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sqrtf(x)) != 0); +} + +ATF_TC(sqrtf_powf); +ATF_TC_HEAD(sqrtf_powf, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtf(3) vs. powf(3)"); +} + +ATF_TC_BODY(sqrtf_powf, tc) +{ + const float x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 }; + const float eps = 1.0e-30; + volatile float y, z; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + y = sqrtf(x[i]); + z = powf(x[i], 1.0 / 2.0); + + if (fabsf(y - z) > eps) + atf_tc_fail_nonfatal("sqrtf(%0.03f) != " + "powf(%0.03f, 1/2)\n", x[i], x[i]); + } +} + +ATF_TC(sqrtf_inf_neg); +ATF_TC_HEAD(sqrtf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtf(-Inf) == NaN"); +} + +ATF_TC_BODY(sqrtf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + float y = sqrtf(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(sqrtf_inf_pos); +ATF_TC_HEAD(sqrtf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtf(+Inf) == +Inf"); +} + +ATF_TC_BODY(sqrtf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + float y = sqrtf(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(sqrtf_zero_neg); +ATF_TC_HEAD(sqrtf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtf(-0.0) == -0.0"); +} + +ATF_TC_BODY(sqrtf_zero_neg, tc) +{ + const float x = -0.0L; + float y = sqrtf(x); + + if (fabsf(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("sqrtf(-0.0) != -0.0"); +} + +ATF_TC(sqrtf_zero_pos); +ATF_TC_HEAD(sqrtf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtf(+0.0) == +0.0"); +} + +ATF_TC_BODY(sqrtf_zero_pos, tc) +{ + const float x = 0.0L; + float y = sqrtf(x); + + if (fabsf(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("sqrtf(+0.0) != +0.0"); +} + +/* + * sqrtl(3) + */ +ATF_TC(sqrtl_nan); +ATF_TC_HEAD(sqrtl_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtl(NaN) == NaN"); +} + +ATF_TC_BODY(sqrtl_nan, tc) +{ + const long double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(sqrtl(x)) != 0); +} + +ATF_TC(sqrtl_powl); +ATF_TC_HEAD(sqrtl_powl, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtl(3) vs. powl(3)"); +} + +ATF_TC_BODY(sqrtl_powl, tc) +{ + const long double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 }; + const long double eps = 5.0*DBL_EPSILON; /* XXX powl == pow for now */ + volatile long double y, z; + size_t i; + + for (i = 0; i < __arraycount(x); i++) { + + y = sqrtl(x[i]); + z = powl(x[i], 1.0 / 2.0); + + if (fabsl(y - z) > eps) + atf_tc_fail_nonfatal("sqrtl(%0.03Lf) != " + "powl(%0.03Lf, 1/2)\n", x[i], x[i]); + } +} + +ATF_TC(sqrtl_inf_neg); +ATF_TC_HEAD(sqrtl_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtl(-Inf) == NaN"); +} + +ATF_TC_BODY(sqrtl_inf_neg, tc) +{ + const long double x = -1.0L / 0.0L; + long double y = sqrtl(x); + + ATF_CHECK(isnan(y) != 0); +} + +ATF_TC(sqrtl_inf_pos); +ATF_TC_HEAD(sqrtl_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtl(+Inf) == +Inf"); +} + +ATF_TC_BODY(sqrtl_inf_pos, tc) +{ + const long double x = 1.0L / 0.0L; + long double y = sqrtl(x); + + ATF_CHECK(isinf(y) != 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TC(sqrtl_zero_neg); +ATF_TC_HEAD(sqrtl_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtl(-0.0) == -0.0"); +} + +ATF_TC_BODY(sqrtl_zero_neg, tc) +{ + const long double x = -0.0L; + long double y = sqrtl(x); + + if (fabsl(y) > 0.0 || signbit(y) == 0) + atf_tc_fail_nonfatal("sqrtl(-0.0) != -0.0"); +} + +ATF_TC(sqrtl_zero_pos); +ATF_TC_HEAD(sqrtl_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sqrtl(+0.0) == +0.0"); +} + +ATF_TC_BODY(sqrtl_zero_pos, tc) +{ + const long double x = 0.0L; + long double y = sqrtl(x); + + if (fabsl(y) > 0.0 || signbit(y) != 0) + atf_tc_fail_nonfatal("sqrtl(+0.0) != +0.0"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sqrt_nan); + ATF_TP_ADD_TC(tp, sqrt_pow); + ATF_TP_ADD_TC(tp, sqrt_inf_neg); + ATF_TP_ADD_TC(tp, sqrt_inf_pos); + ATF_TP_ADD_TC(tp, sqrt_zero_neg); + ATF_TP_ADD_TC(tp, sqrt_zero_pos); + + ATF_TP_ADD_TC(tp, sqrtf_nan); + ATF_TP_ADD_TC(tp, sqrtf_powf); + ATF_TP_ADD_TC(tp, sqrtf_inf_neg); + ATF_TP_ADD_TC(tp, sqrtf_inf_pos); + ATF_TP_ADD_TC(tp, sqrtf_zero_neg); + ATF_TP_ADD_TC(tp, sqrtf_zero_pos); + + ATF_TP_ADD_TC(tp, sqrtl_nan); + ATF_TP_ADD_TC(tp, sqrtl_powl); + ATF_TP_ADD_TC(tp, sqrtl_inf_neg); + ATF_TP_ADD_TC(tp, sqrtl_inf_pos); + ATF_TP_ADD_TC(tp, sqrtl_zero_neg); + ATF_TP_ADD_TC(tp, sqrtl_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_tan.c b/contrib/netbsd-tests/lib/libm/t_tan.c new file mode 100644 index 0000000..807e3d1 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_tan.c @@ -0,0 +1,260 @@ +/* $NetBSD: t_tan.c,v 1.5 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +static const struct { + int angle; + double x; + double y; +} angles[] = { + { -180, -3.141592653589793, 0.0000000000000000 }, + { -135, -2.356194490192345, 1.0000000000000000 }, + { -45, -0.785398163397448, -1.0000000000000000 }, + { 0, 0.000000000000000, 0.0000000000000000 }, + { 30, 0.523598775598299, 0.5773502691896258 }, + { 45, 0.785398163397448, 1.0000000000000000 }, + { 60, 1.047197551196598, 1.7320508075688773 }, + { 120, 2.094395102393195, -1.7320508075688773 }, + { 135, 2.356194490192345, -1.0000000000000000 }, + { 150, 2.617993877991494, -0.5773502691896258 }, + { 180, 3.141592653589793, 0.0000000000000000 }, + { 360, 6.283185307179586, 0.0000000000000000 } +}; + +/* + * tan(3) + */ +ATF_TC(tan_angles); +ATF_TC_HEAD(tan_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(tan_angles, tc) +{ + const double eps = 1.0e-14; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + + if (fabs(tan(angles[i].x) - angles[i].y) > eps) + atf_tc_fail_nonfatal("tan(%d deg) != %0.01f", + angles[i].angle, angles[i].y); + } +} + +ATF_TC(tan_nan); +ATF_TC_HEAD(tan_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tan(NaN) == NaN"); +} + +ATF_TC_BODY(tan_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(tan(x)) != 0); +} + +ATF_TC(tan_inf_neg); +ATF_TC_HEAD(tan_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tan(-Inf) == NaN"); +} + +ATF_TC_BODY(tan_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + ATF_CHECK(isnan(tan(x)) != 0); +} + +ATF_TC(tan_inf_pos); +ATF_TC_HEAD(tan_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tan(+Inf) == NaN"); +} + +ATF_TC_BODY(tan_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(isnan(tan(x)) != 0); +} + + +ATF_TC(tan_zero_neg); +ATF_TC_HEAD(tan_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tan(-0.0) == -0.0"); +} + +ATF_TC_BODY(tan_zero_neg, tc) +{ + const double x = -0.0L; + + ATF_CHECK(tan(x) == x); +} + +ATF_TC(tan_zero_pos); +ATF_TC_HEAD(tan_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tan(+0.0) == +0.0"); +} + +ATF_TC_BODY(tan_zero_pos, tc) +{ + const double x = 0.0L; + + ATF_CHECK(tan(x) == x); +} + +/* + * tanf(3) + */ +ATF_TC(tanf_angles); +ATF_TC_HEAD(tanf_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(tanf_angles, tc) +{ + const float eps = 1.0e-6; + float x, y; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + + x = angles[i].x; + y = angles[i].y; + + if (fabsf(tanf(x) - y) > eps) + atf_tc_fail_nonfatal("tanf(%d deg) != %0.01f", + angles[i].angle, angles[i].y); + } +} + +ATF_TC(tanf_nan); +ATF_TC_HEAD(tanf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanf(NaN) == NaN"); +} + +ATF_TC_BODY(tanf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(tanf(x)) != 0); +} + +ATF_TC(tanf_inf_neg); +ATF_TC_HEAD(tanf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanf(-Inf) == NaN"); +} + +ATF_TC_BODY(tanf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + if (isnan(tanf(x)) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("tanf(-Inf) != NaN"); + } +} + +ATF_TC(tanf_inf_pos); +ATF_TC_HEAD(tanf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanf(+Inf) == NaN"); +} + +ATF_TC_BODY(tanf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + if (isnan(tanf(x)) == 0) { + atf_tc_expect_fail("PR lib/45362"); + atf_tc_fail("tanf(+Inf) != NaN"); + } +} + + +ATF_TC(tanf_zero_neg); +ATF_TC_HEAD(tanf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanf(-0.0) == -0.0"); +} + +ATF_TC_BODY(tanf_zero_neg, tc) +{ + const float x = -0.0L; + + ATF_CHECK(tanf(x) == x); +} + +ATF_TC(tanf_zero_pos); +ATF_TC_HEAD(tanf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanf(+0.0) == +0.0"); +} + +ATF_TC_BODY(tanf_zero_pos, tc) +{ + const float x = 0.0L; + + ATF_CHECK(tanf(x) == x); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, tan_angles); + ATF_TP_ADD_TC(tp, tan_nan); + ATF_TP_ADD_TC(tp, tan_inf_neg); + ATF_TP_ADD_TC(tp, tan_inf_pos); + ATF_TP_ADD_TC(tp, tan_zero_neg); + ATF_TP_ADD_TC(tp, tan_zero_pos); + + ATF_TP_ADD_TC(tp, tanf_angles); + ATF_TP_ADD_TC(tp, tanf_nan); + ATF_TP_ADD_TC(tp, tanf_inf_neg); + ATF_TP_ADD_TC(tp, tanf_inf_pos); + ATF_TP_ADD_TC(tp, tanf_zero_neg); + ATF_TP_ADD_TC(tp, tanf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_tanh.c b/contrib/netbsd-tests/lib/libm/t_tanh.c new file mode 100644 index 0000000..4cc4551 --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_tanh.c @@ -0,0 +1,207 @@ +/* $NetBSD: t_tanh.c,v 1.7 2014/03/03 10:39:08 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_tanh.c,v 1.7 2014/03/03 10:39:08 martin Exp $"); + +#include +#include + +/* + * tanh(3) + */ +ATF_TC(tanh_nan); +ATF_TC_HEAD(tanh_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanh(NaN) == NaN"); +} + +ATF_TC_BODY(tanh_nan, tc) +{ + const double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(tanh(x)) != 0); +} + +ATF_TC(tanh_inf_neg); +ATF_TC_HEAD(tanh_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanh(-Inf) == -1.0"); +} + +ATF_TC_BODY(tanh_inf_neg, tc) +{ + const double x = -1.0L / 0.0L; + + ATF_CHECK(tanh(x) == -1.0); +} + +ATF_TC(tanh_inf_pos); +ATF_TC_HEAD(tanh_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanh(+Inf) == +1.0"); +} + +ATF_TC_BODY(tanh_inf_pos, tc) +{ + const double x = 1.0L / 0.0L; + + ATF_CHECK(tanh(x) == 1.0); +} + +ATF_TC(tanh_zero_neg); +ATF_TC_HEAD(tanh_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanh(-0.0) == -0.0"); +} + +ATF_TC_BODY(tanh_zero_neg, tc) +{ + const double x = -0.0L; + double y = tanh(x); + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) != 0); + + ATF_REQUIRE_MSG(signbit(y) != 0, + "compiler bug, waiting for newer gcc import, see PR lib/44057"); +} + +ATF_TC(tanh_zero_pos); +ATF_TC_HEAD(tanh_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanh(+0.0) == +0.0"); +} + +ATF_TC_BODY(tanh_zero_pos, tc) +{ + const double x = 0.0L; + double y = tanh(x); + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +/* + * tanhf(3) + */ +ATF_TC(tanhf_nan); +ATF_TC_HEAD(tanhf_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanhf(NaN) == NaN"); +} + +ATF_TC_BODY(tanhf_nan, tc) +{ + const float x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(tanhf(x)) != 0); +} + +ATF_TC(tanhf_inf_neg); +ATF_TC_HEAD(tanhf_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanhf(-Inf) == -1.0"); +} + +ATF_TC_BODY(tanhf_inf_neg, tc) +{ + const float x = -1.0L / 0.0L; + + ATF_CHECK(tanhf(x) == -1.0); +} + +ATF_TC(tanhf_inf_pos); +ATF_TC_HEAD(tanhf_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanhf(+Inf) == +1.0"); +} + +ATF_TC_BODY(tanhf_inf_pos, tc) +{ + const float x = 1.0L / 0.0L; + + ATF_CHECK(tanhf(x) == 1.0); +} + +ATF_TC(tanhf_zero_neg); +ATF_TC_HEAD(tanhf_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanhf(-0.0) == -0.0"); +} + +ATF_TC_BODY(tanhf_zero_neg, tc) +{ + const float x = -0.0L; + float y = tanh(x); + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) != 0); + + ATF_REQUIRE_MSG(signbit(y) != 0, + "compiler bug, waiting for newer gcc import, see PR lib/44057"); +} + +ATF_TC(tanhf_zero_pos); +ATF_TC_HEAD(tanhf_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test tanhf(+0.0) == +0.0"); +} + +ATF_TC_BODY(tanhf_zero_pos, tc) +{ + const float x = 0.0L; + float y = tanhf(x); + + ATF_CHECK(x == y); + ATF_CHECK(signbit(x) == 0); + ATF_CHECK(signbit(y) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, tanh_nan); + ATF_TP_ADD_TC(tp, tanh_inf_neg); + ATF_TP_ADD_TC(tp, tanh_inf_pos); + ATF_TP_ADD_TC(tp, tanh_zero_neg); + ATF_TP_ADD_TC(tp, tanh_zero_pos); + + ATF_TP_ADD_TC(tp, tanhf_nan); + ATF_TP_ADD_TC(tp, tanhf_inf_neg); + ATF_TP_ADD_TC(tp, tanhf_inf_pos); + ATF_TP_ADD_TC(tp, tanhf_zero_neg); + ATF_TP_ADD_TC(tp, tanhf_zero_pos); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libobjc/t_threads.m b/contrib/netbsd-tests/lib/libobjc/t_threads.m new file mode 100644 index 0000000..a6bd720 --- /dev/null +++ b/contrib/netbsd-tests/lib/libobjc/t_threads.m @@ -0,0 +1,136 @@ +/* $NetBSD: t_threads.m,v 1.2 2013/10/31 21:02:11 christos Exp $ */ + +/* + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* Originally written by David Wetzel */ + +#include +#include +#include + +#include + +#include +#include +#include +#if __GNUC_PREREQ__(4,8) +#include +#endif + +static int IsMultithreaded = 0; +static objc_mutex_t Mutex; +static objc_condition_t Condition; + +@interface MyClass : Object +{ +} +-(void)start; +#if __GNUC_PREREQ__(4,8) +-init; ++new; ++alloc; +-free; +#endif +@end + +@implementation MyClass +-(void)start +{ + printf("detached thread started!\n"); + + objc_condition_signal(Condition); +} +#if __GNUC_PREREQ__(4,8) +-init +{ + return self; +} + ++new +{ + return [[self alloc] init]; +} + ++alloc +{ + return class_createInstance(self, 0); +} + +-free +{ + return object_dispose(self); +} +#endif +@end + +static void +becomeMultiThreaded(void) +{ + printf("becoming multithreaded!\n"); + IsMultithreaded++; +} + +ATF_TC(thread_callback); +ATF_TC_HEAD(thread_callback, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that the thread callback is only" + "called once"); +} +ATF_TC_BODY(thread_callback, tc) +{ + id o = [MyClass new]; + objc_thread_callback cb; + objc_thread_t rv; + + cb = objc_set_thread_callback(becomeMultiThreaded); + printf("Old Callback: %p\n", cb); + ATF_CHECK(cb == 0); + + Mutex = objc_mutex_allocate(); + Condition = objc_condition_allocate(); + + ATF_CHECK_EQ(0, IsMultithreaded); + + rv = objc_thread_detach(@selector(start), o, nil); + printf("detach value: %p\n", rv); + assert(rv != NULL); + + objc_mutex_lock(Mutex); + objc_condition_wait(Condition, Mutex); + objc_mutex_unlock(Mutex); + + ATF_CHECK_EQ(1, IsMultithreaded); + printf("Shutting down\n"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, thread_callback); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libposix/t_rename.c b/contrib/netbsd-tests/lib/libposix/t_rename.c new file mode 100644 index 0000000..8c18ec5 --- /dev/null +++ b/contrib/netbsd-tests/lib/libposix/t_rename.c @@ -0,0 +1,89 @@ +/* $NetBSD: t_rename.c,v 1.3 2017/01/13 21:30:41 christos Exp $ */ + +/* + * Copyright (c) 2001, 2008, 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ +#define _NETBSD_SOURCE /* strlcat/random */ +#include +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_rename.c,v 1.3 2017/01/13 21:30:41 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(rename); +ATF_TC_HEAD(rename, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks rename(2)"); +} +ATF_TC_BODY(rename, tc) +{ + struct stat sb; + + REQUIRE_LIBC(open("t1", O_CREAT | O_TRUNC | O_WRONLY, 0600), -1); + REQUIRE_LIBC(link("t1", "t2"), -1); + + /* Check if rename to same name works as expected */ + REQUIRE_LIBC(rename("t1", "t1"), -1); + + /* Rename removed file? */ + REQUIRE_LIBC(stat("t1", &sb), -1); + + REQUIRE_LIBC(rename("t1", "t2"), -1); + +#if BSD_RENAME + /* check if rename of hardlinked file works the BSD way */ + ATF_REQUIRE_MSG(stat("t1", &sb) != 0, "BSD rename should remove file t1"); + ATF_REQUIRE_EQ(errno, ENOENT); +#else + /* check if rename of hardlinked file works as the standard says */ + REQUIRE_LIBC(stat("t1", &sb), -1); +#endif + /* check if we get the expected error */ + /* this also exercises icky shared libraries goo */ + ATF_REQUIRE_MSG(rename("no/such/file/or/dir", "no/such/file/or/dir") != 0, + "No error renaming nonexistent file"); + ATF_REQUIRE_EQ(errno, ENOENT); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, rename); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libppath/personnel.plist b/contrib/netbsd-tests/lib/libppath/personnel.plist new file mode 100644 index 0000000..daec88c --- /dev/null +++ b/contrib/netbsd-tests/lib/libppath/personnel.plist @@ -0,0 +1,26 @@ + + + + + John Doe + + children + + Jane Doe + John Doe, Jr. + + + pets + + Fido + Spot + + + job title + computer programmer + + u.s. citizen + + + + diff --git a/contrib/netbsd-tests/lib/libppath/plist_to_c b/contrib/netbsd-tests/lib/libppath/plist_to_c new file mode 100755 index 0000000..f471b4e --- /dev/null +++ b/contrib/netbsd-tests/lib/libppath/plist_to_c @@ -0,0 +1,20 @@ +#!/bin/sh + +prog=$(basename $0) +usage() +{ + echo "usage: ${prog} symbol" 1>&2 + exit 1 +} + +if [ $# -ne 1 ]; then + usage +fi + +sed 's/\(["\]\)/\\\1/g' | \ +${AWK:-awk} -v sym=$1 ' +BEGIN { printf "const char " sym "[] = \""; } + { printf $0 "\\n"; } +END { print "\";"; }' + +exit 0 diff --git a/contrib/netbsd-tests/lib/libppath/t_ppath.c b/contrib/netbsd-tests/lib/libppath/t_ppath.c new file mode 100644 index 0000000..7330763 --- /dev/null +++ b/contrib/netbsd-tests/lib/libppath/t_ppath.c @@ -0,0 +1,1548 @@ +/* $Id: t_ppath.c,v 1.1 2011/08/25 19:09:46 dyoung Exp $ */ + +/* Copyright (c) 2010 David Young. All rights reserved. */ + +#include +__RCSID("$Id: t_ppath.c,v 1.1 2011/08/25 19:09:46 dyoung Exp $"); + +#include +#include +#include +#include +#include + +#include +#include "personnel.h" + +void test_ppath_extant_inc(void); +void test_ppath_extant_dec(void); +void test_ppath_component_extant_inc(void); +void test_ppath_component_extant_dec(void); + +__strong_alias(ppath_extant_inc, test_ppath_extant_inc); +__strong_alias(ppath_extant_dec, test_ppath_extant_dec); +__strong_alias(ppath_component_extant_inc, test_ppath_component_extant_inc); +__strong_alias(ppath_component_extant_dec, test_ppath_component_extant_dec); + +static uint64_t nppath = 0, nppath_component = 0; + +static bool +dictionary_equals(prop_dictionary_t ld, prop_dictionary_t rd) +{ + bool eq; + char *lt, *rt; + + lt = prop_dictionary_externalize(ld); + rt = prop_dictionary_externalize(rd); + + assert(lt != NULL && rt != NULL); + + eq = (strcmp(lt, rt) == 0); + + free(lt); + free(rt); + + return eq; +} + +static void +assert_no_ppath_extant(void) +{ + ATF_CHECK_EQ(nppath, 0); +} + +static void +assert_no_ppath_component_extant(void) +{ + ATF_CHECK_EQ(nppath_component, 0); +} + +void +test_ppath_extant_inc(void) +{ + if (++nppath == 0) + atf_tc_fail("count of extant paths overflowed"); +} + +void +test_ppath_extant_dec(void) +{ + if (nppath-- == 0) + atf_tc_fail("count of extant path underflowed"); +} + +void +test_ppath_component_extant_inc(void) +{ + if (++nppath_component == 0) + atf_tc_fail("count of extant path components overflowed"); +} + +void +test_ppath_component_extant_dec(void) +{ + if (nppath_component-- == 0) + atf_tc_fail("count of extant path components underflowed"); +} + +ATF_TC(push_until_full); + +ATF_TC_HEAD(push_until_full, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_push() returns error " + "after ppath_t reaches maximum length"); +} + +ATF_TC_BODY(push_until_full, tc) +{ + ppath_t *p, *rp; + ppath_component_t *pc; + int i; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if ((pc = ppath_idx(0)) == NULL) + atf_tc_fail("ppath_idx failed"); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + rp = ppath_push(p, pc); + ATF_CHECK_EQ(rp, p); + } + + rp = ppath_push(p, pc); + ATF_CHECK_EQ(rp, NULL); + + rp = ppath_push(p, pc); + ATF_CHECK_EQ(rp, NULL); + + ppath_component_release(pc); + ppath_release(p); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(pop_until_empty); +ATF_TC_HEAD(pop_until_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_pop() returns error " + "after ppath_t is empty"); +} + +ATF_TC_BODY(pop_until_empty, tc) +{ + ppath_t *p, *rp; + ppath_component_t *pc, *rpc; + int i; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if ((pc = ppath_idx(0)) == NULL) + atf_tc_fail("ppath_idx failed"); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + rp = ppath_push(p, pc); + ATF_CHECK_EQ(rp, p); + } + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + rp = ppath_pop(p, &rpc); + ATF_CHECK_EQ(rp, p); + ATF_CHECK_EQ(rpc, pc); + ppath_component_release(rpc); + } + + rp = ppath_pop(p, &rpc); + ATF_CHECK_EQ(rp, NULL); + rp = ppath_pop(p, &rpc); + ATF_CHECK_EQ(rp, NULL); + + ppath_component_release(pc); + ppath_release(p); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(length); + +ATF_TC_HEAD(length, tc) +{ + atf_tc_set_md_var(tc, "descr", "check that ppath_push() " + "and ppath_pop() affect ppath_length() correctly"); +} + +ATF_TC_BODY(length, tc) +{ + ppath_t *p, *rp; + ppath_component_t *pc; + unsigned int i, len; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if ((pc = ppath_idx(0)) == NULL) + atf_tc_fail("ppath_idx failed"); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + len = ppath_length(p); + ATF_CHECK_EQ(len, i); + rp = ppath_push(p, pc); + ATF_CHECK_EQ(rp, p); + } + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + len = ppath_length(p); + ATF_CHECK_EQ(len, PPATH_MAX_COMPONENTS - i); + rp = ppath_pop(p, NULL); + ATF_CHECK_EQ(rp, p); + } + ppath_component_release(pc); + ppath_release(p); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(component_at); + +ATF_TC_HEAD(component_at, tc) +{ + atf_tc_set_md_var(tc, "descr", "check that ppath_component_at() " + "returns the expected component"); +} + +ATF_TC_BODY(component_at, tc) +{ + ppath_t *p, *rp; + ppath_component_t *pc; + unsigned int i; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + if ((pc = ppath_idx(i)) == NULL) + atf_tc_fail("ppath_idx failed"); + rp = ppath_push(p, pc); + ppath_component_release(pc); + ATF_CHECK_EQ(rp, p); + } + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + pc = ppath_component_at(p, i); + ATF_CHECK_EQ(ppath_component_idx(pc), (int)i); + ppath_component_release(pc); + } + ppath_release(p); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_idx_key); + +ATF_TC_HEAD(get_idx_key, tc) +{ + atf_tc_set_md_var(tc, "descr", "check that ppath_component_idx() " + "and ppath_component_key() return -1 and NULL, respectively, if " + "the component is a key or an index, respectively."); +} + +ATF_TC_BODY(get_idx_key, tc) +{ + ppath_component_t *idx, *key; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((idx = ppath_idx(0)) == NULL) + atf_tc_fail("ppath_idx failed"); + if ((key = ppath_key("key")) == NULL) + atf_tc_fail("ppath_idx failed"); + + ATF_CHECK_EQ(ppath_component_key(idx), NULL); + ATF_CHECK_EQ(ppath_component_idx(key), -1); + + ppath_component_release(idx); + ppath_component_release(key); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(ppath_copy); + +ATF_TC_HEAD(ppath_copy, tc) +{ + atf_tc_set_md_var(tc, "descr", "check that ppath_copy() " + "creates an exact replica of a path, and that no " + "resources are leaked."); +} + +ATF_TC_BODY(ppath_copy, tc) +{ + ppath_component_t *pc, *cpc; + ppath_t *p, *cp, *rp; + unsigned int i; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + if ((pc = ppath_idx(i)) == NULL) + atf_tc_fail("ppath_idx failed"); + rp = ppath_push(p, pc); + ppath_component_release(pc); + ATF_CHECK_EQ(rp, p); + } + + if ((cp = ppath_copy(p)) == NULL) + atf_tc_fail("ppath_copy failed"); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + pc = ppath_component_at(p, i); + cpc = ppath_component_at(cp, i); + ATF_CHECK_EQ(pc, cpc); + ppath_component_release(pc); + ppath_component_release(cpc); + } + + ppath_release(cp); + ppath_release(p); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(replace); + +ATF_TC_HEAD(replace, tc) +{ + atf_tc_set_md_var(tc, "descr", "check that ppath_replace_idx() " + "and ppath_replace_key() produce the paths we expect without " + "leaking resources."); +} + +ATF_TC_BODY(replace, tc) +{ + ppath_component_t *pc; + ppath_t *p, *cp, *rp; + unsigned int i; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + /* index replacement fails on an empty path */ + rp = ppath_replace_idx(p, 0); + ATF_CHECK_EQ(rp, NULL); + + /* key replacement fails on an empty path */ + rp = ppath_replace_key(p, "key"); + ATF_CHECK_EQ(rp, NULL); + + for (i = 0; i < PPATH_MAX_COMPONENTS; i++) { + if ((pc = ppath_idx(i)) == NULL) + atf_tc_fail("ppath_idx failed"); + rp = ppath_push(p, pc); + ppath_component_release(pc); + ATF_CHECK_EQ(rp, p); + } + + if ((cp = ppath_copy(p)) == NULL) + atf_tc_fail("ppath_copy failed"); + + rp = ppath_pop(cp, NULL); + ATF_CHECK_EQ(rp, cp); + rp = ppath_push_key(cp, "key"); + ATF_CHECK_EQ(rp, cp); + + ppath_replace_idx(p, 0); + + if ((pc = ppath_component_at(p, PPATH_MAX_COMPONENTS - 1)) == NULL) + atf_tc_fail("ppath_idx failed"); + ATF_CHECK_EQ(ppath_component_idx(pc), 0); + ppath_component_release(pc); + + for (i = 0; i < PPATH_MAX_COMPONENTS - 1; i++) { + if ((pc = ppath_component_at(p, i)) == NULL) + atf_tc_fail("ppath_idx failed"); + ATF_CHECK_EQ(ppath_component_idx(pc), (int)i); + ppath_component_release(pc); + } + + for (i = 0; i < PPATH_MAX_COMPONENTS - 1; i++) { + if ((pc = ppath_component_at(cp, i)) == NULL) + atf_tc_fail("ppath_idx failed"); + ATF_CHECK_EQ(ppath_component_idx(pc), (int)i); + ppath_component_release(pc); + } + + if ((pc = ppath_component_at(cp, PPATH_MAX_COMPONENTS - 1)) == NULL) + atf_tc_fail("ppath_idx failed"); + if (ppath_component_key(pc) == NULL || + strcmp(ppath_component_key(pc), "key") != 0) + atf_tc_fail("last path component expected to be \"key\""); + ppath_component_release(pc); + ppath_release(p); + ppath_release(cp); + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(copyset_object_twice_success); + +ATF_TC_HEAD(copyset_object_twice_success, tc) +{ + atf_tc_set_md_var(tc, "descr", + "check that after back-to-back ppath_copyset_object() calls, " + "changing the \"u.s. citizen\" property and the first property " + "in \"children\" in the \"John Doe\" record in the " + "\"personnel\" property list, the properties are changed " + "in the new dictionary and unchanged in the old dictionary"); +} + +ATF_TC_BODY(copyset_object_twice_success, tc) +{ + const char *s; + char *oext, *next; + int rc; + bool v = false; + prop_dictionary_t d, od; + prop_object_t nd = NULL, ond; + prop_object_t r, or; + ppath_t *p, *p2, *p3; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + od = prop_dictionary_copy(d); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("dictionaries are unequal from the outset, argh! " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if ((p = ppath_create()) == NULL || (p2 = ppath_create()) == NULL || + (p3 = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + if (ppath_push_key(p2, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p2, "children") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_idx(p2, 0) == NULL) + atf_tc_fail("ppath_push_idx failed"); + + if (ppath_push_key(p3, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + s = ""; + rc = ppath_get_string(d, p2, &s); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_STREQ(s, "Jane Doe"); + + rc = ppath_copyset_bool(d, &nd, p, false); + ATF_CHECK_EQ(rc, 0); + + rc = ppath_get_object(nd, p3, &r); + ATF_CHECK_EQ(rc, 0); + + ond = nd; + + rc = ppath_copyset_string(d, &nd, p2, "Martha Doe"); + ATF_CHECK_EQ(rc, 0); + + ATF_CHECK_EQ(nd, ond); + + rc = ppath_get_object(nd, p3, &or); + ATF_CHECK_EQ(rc, 0); + + ATF_CHECK_EQ(r, or); + + v = true; + rc = ppath_get_bool(nd, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, false); + + s = ""; + rc = ppath_get_string(nd, p2, &s); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_STREQ(s, "Martha Doe"); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("copydel modified original dictionary, " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if (dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copydel made no change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + rc = ppath_set_bool(od, p, false); + ATF_CHECK_EQ(rc, 0); + + rc = ppath_set_string(od, p2, "Martha Doe"); + ATF_CHECK_EQ(rc, 0); + + if (!dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copydel made an out-of-bounds change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + ppath_release(p); + ppath_release(p2); + ppath_release(p3); + prop_object_release(d); + prop_object_release(od); + prop_object_release(nd); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(copydel_object_twice_success); + +ATF_TC_HEAD(copydel_object_twice_success, tc) +{ + atf_tc_set_md_var(tc, "descr", + "check that after back-to-back ppath_copydel_object() calls, " + "removing the \"u.s. citizen\" property and the first property " + "in \"children\" from the \"John Doe\" record in the " + "\"personnel\" property list, the properties are missing " + "from the new dictionary and unchanged in the old dictionary"); +} + +ATF_TC_BODY(copydel_object_twice_success, tc) +{ + const char *s; + char *oext, *next; + int rc; + bool v = false; + prop_dictionary_t d, od; + prop_object_t nd = NULL, ond; + prop_object_t r, or; + ppath_t *p, *p2, *p3; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + od = prop_dictionary_copy(d); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("dictionaries are unequal from the outset, argh! " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if ((p = ppath_create()) == NULL || (p2 = ppath_create()) == NULL || + (p3 = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + if (ppath_push_key(p2, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p2, "children") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_idx(p2, 0) == NULL) + atf_tc_fail("ppath_push_idx failed"); + + if (ppath_push_key(p3, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + s = ""; + rc = ppath_get_string(d, p2, &s); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_STREQ(s, "Jane Doe"); + + rc = ppath_copydel_bool(d, &nd, p); + ATF_CHECK_EQ(rc, 0); + + ond = nd; + + rc = ppath_get_object(nd, p3, &r); + ATF_CHECK_EQ(rc, 0); + + rc = ppath_copydel_string(d, &nd, p2); + ATF_CHECK_EQ(rc, 0); + + ATF_CHECK_EQ(nd, ond); + + rc = ppath_get_object(nd, p3, &or); + ATF_CHECK_EQ(rc, 0); + + ATF_CHECK_EQ(r, or); + + v = true; + rc = ppath_get_bool(nd, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, true); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("copydel modified original dictionary, " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if (dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copydel made no change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + rc = ppath_delete_bool(od, p); + ATF_CHECK_EQ(rc, 0); + + rc = ppath_delete_string(od, p2); + ATF_CHECK_EQ(rc, 0); + + if (!dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copydel made an out-of-bounds change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + ppath_release(p); + ppath_release(p2); + ppath_release(p3); + prop_object_release(d); + prop_object_release(od); + prop_object_release(nd); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(copydel_bool_success); + +ATF_TC_HEAD(copydel_bool_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_copydel_bool() deletes " + "the \"u.s. citizen\" property in the \"John Doe\" record in the " + "\"personnel\" property list and verifies the value is missing " + "from the new dictionary and unchanged in the old dictionary"); +} + +ATF_TC_BODY(copydel_bool_success, tc) +{ + char *oext, *next; + int rc; + bool v = false; + prop_dictionary_t d, od; + prop_object_t nd = NULL; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + od = prop_dictionary_copy(d); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("dictionaries are unequal from the outset, argh! " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + rc = ppath_copydel_bool(d, &nd, p); + ATF_CHECK_EQ(rc, 0); + + v = true; + rc = ppath_get_bool(nd, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, true); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("copydel modified original dictionary, " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if (dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copydel made no change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + rc = ppath_delete_bool(od, p); + ATF_CHECK_EQ(rc, 0); + + if (!dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copydel made an out-of-bounds change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + ppath_release(p); + prop_object_release(d); + prop_object_release(od); + prop_object_release(nd); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(copyset_bool_success); + +ATF_TC_HEAD(copyset_bool_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_copyset_bool() sets " + "the \"u.s. citizen\" property in the \"John Doe\" record in the " + "\"personnel\" property list to false and verifies the new value " + "in the new dictionary and that the old dictionary is unchanged"); +} + +ATF_TC_BODY(copyset_bool_success, tc) +{ + char *oext, *next; + int rc; + bool v = false; + prop_dictionary_t d, od; + prop_object_t nd = NULL; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + od = prop_dictionary_copy(d); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("dictionaries are unequal from the outset, argh! " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + rc = ppath_copyset_bool(d, &nd, p, false); + ATF_CHECK_EQ(rc, 0); + + v = true; + rc = ppath_get_bool(nd, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, false); + + if (!dictionary_equals(od, d)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(d); + atf_tc_fail("copyset modified original dictionary, " + "original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + if (dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copyset made no change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + rc = ppath_set_bool(nd, p, true); + ATF_CHECK_EQ(rc, 0); + + if (!dictionary_equals(od, nd)) { + oext = prop_dictionary_externalize(od); + next = prop_dictionary_externalize(nd); + atf_tc_fail("copyset made an out-of-bounds change to the new " + "dictionary, original\n%s\nnew\n%s", oext, next); + free(oext); + free(next); + } + + ppath_release(p); + prop_object_release(d); + prop_object_release(od); + prop_object_release(nd); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(set_bool_eftype); + +ATF_TC_HEAD(set_bool_eftype, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_set_bool() does not " + "overwrite with a bool " + "the \"job title\" property in the \"John Doe\" record in " + "the " + "\"personnel\" property list"); +} + +ATF_TC_BODY(set_bool_eftype, tc) +{ + int rc; + bool v = false; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "job title") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, EFTYPE); + ATF_CHECK_EQ(v, false); + + rc = ppath_set_bool(d, p, false); + ATF_CHECK_EQ(rc, EFTYPE); + + v = true; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, EFTYPE); + ATF_CHECK_EQ(v, true); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(set_bool_enoent); + +ATF_TC_HEAD(set_bool_enoent, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_set_bool() does not create " + "the \"russian citizen\" property in the \"John Doe\" record in " + "the " + "\"personnel\" property list"); +} + +ATF_TC_BODY(set_bool_enoent, tc) +{ + int rc; + bool v = false; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "russian citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, false); + + rc = ppath_set_bool(d, p, false); + ATF_CHECK_EQ(rc, ENOENT); + + v = true; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, true); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(create_bool_eexist); + +ATF_TC_HEAD(create_bool_eexist, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_create_bool() returns " + "EEXIST because the \"u.s. citizen\" property in the " + "\"John Doe\" record in the \"personnel\" property list " + "already exists"); +} + +ATF_TC_BODY(create_bool_eexist, tc) +{ + int rc; + bool v = false; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + rc = ppath_create_bool(d, p, false); + ATF_CHECK_EQ(rc, EEXIST); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(create_bool_success); + +ATF_TC_HEAD(create_bool_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_create_bool() creates " + "the \"russian citizen\" property in the \"John Doe\" record in " + "the \"personnel\" property list and sets it to false"); +} + +ATF_TC_BODY(create_bool_success, tc) +{ + int rc; + bool v = false; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "russian citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, false); + + rc = ppath_create_bool(d, p, false); + ATF_CHECK_EQ(rc, 0); + + v = true; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, false); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(set_bool_success); + +ATF_TC_HEAD(set_bool_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_set_bool() sets " + "the \"u.s. citizen\" property in the \"John Doe\" record in the " + "\"personnel\" property list to false and verifies the new value"); +} + +ATF_TC_BODY(set_bool_success, tc) +{ + int rc; + bool v = false; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + rc = ppath_set_bool(d, p, v); + ATF_CHECK_EQ(rc, 0); + + v = true; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_bool_success); + +ATF_TC_HEAD(get_bool_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_get_bool() fetches " + "the \"u.s. citizen\" property from the \"John Doe\" record in the " + "\"personnel\" property list, and compares it with the expected " + "value, true"); +} + +ATF_TC_BODY(get_bool_success, tc) +{ + int rc; + bool v = false; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_EQ(v, true); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(delete_bool_success); + +ATF_TC_HEAD(delete_bool_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_delete_bool() succeeds " + "for the path (\"John Doe\", \"u.s. citizen\") in the " + "\"personnel\" property list"); +} + +ATF_TC_BODY(delete_bool_success, tc) +{ + int rc; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + rc = ppath_delete_bool(d, p); + ATF_CHECK_EQ(rc, 0); + + rc = ppath_get_bool(d, p, NULL); + ATF_CHECK_EQ(rc, ENOENT); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(delete_bool_eftype); + +ATF_TC_HEAD(delete_bool_eftype, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_delete_bool() returns " + "EFTYPE for the path (\"John Doe\", \"job title\") in the " + "\"personnel\" property list and does not delete the path"); +} + +ATF_TC_BODY(delete_bool_eftype, tc) +{ + int rc; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "job title") == NULL) + atf_tc_fail("ppath_push_key failed"); + + rc = ppath_delete_bool(d, p); + ATF_CHECK_EQ(rc, EFTYPE); + + rc = ppath_get_object(d, p, NULL); + ATF_CHECK_EQ(rc, 0); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(delete_bool_enoent); + +ATF_TC_HEAD(delete_bool_enoent, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_delete_bool() returns " + "ENOENT for the path (\"John Doe\", \"citizen\") in the " + "\"personnel\" property list"); +} + +ATF_TC_BODY(delete_bool_enoent, tc) +{ + int rc; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + rc = ppath_delete_bool(d, p); + ATF_CHECK_EQ(rc, ENOENT); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_bool_enoent); + +ATF_TC_HEAD(get_bool_enoent, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_get_bool() returns " + "ENOENT for the path (\"John Doe\", \"citizen\") in the " + "\"personnel\" property list, and the bool * argument is " + "unchanged"); +} + +ATF_TC_BODY(get_bool_enoent, tc) +{ + int rc; + bool v; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = true; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, true); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, false); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_bool_eftype); + +ATF_TC_HEAD(get_bool_eftype, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_get_bool() returns " + "EFTYPE for the path (\"John Doe\", \"job title\") in the " + "\"personnel\" property list, and the bool * argument is " + "unchanged"); +} + +ATF_TC_BODY(get_bool_eftype, tc) +{ + int rc; + bool v; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "job title") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = true; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, EFTYPE); + ATF_CHECK_EQ(v, true); + + v = false; + rc = ppath_get_bool(d, p, &v); + ATF_CHECK_EQ(rc, EFTYPE); + ATF_CHECK_EQ(v, false); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_string_eftype); + +ATF_TC_HEAD(get_string_eftype, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_get_string() returns " + "EFTYPE for the path (\"John Doe\", \"u.s. citizen\") in the " + "\"personnel\" property list, and the const char ** argument is " + "unchanged"); +} + +ATF_TC_BODY(get_string_eftype, tc) +{ + int rc; + const char *v; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "u.s. citizen") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = NULL; + rc = ppath_get_string(d, p, &v); + ATF_CHECK_EQ(rc, EFTYPE); + ATF_CHECK_EQ(v, NULL); + + v = "xyz"; + rc = ppath_get_string(d, p, &v); + ATF_CHECK_EQ(rc, EFTYPE); + ATF_CHECK_STREQ(v, "xyz"); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_string_enoent); + +ATF_TC_HEAD(get_string_enoent, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_get_string() returns " + "ENOENT for the path (\"John Doe\", \"title\") in the " + "\"personnel\" property list, and the const char ** argument is " + "unchanged"); +} + +ATF_TC_BODY(get_string_enoent, tc) +{ + int rc; + const char *v; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "title") == NULL) + atf_tc_fail("ppath_push_key failed"); + + v = NULL; + rc = ppath_get_string(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_EQ(v, NULL); + + v = "xyz"; + rc = ppath_get_string(d, p, &v); + ATF_CHECK_EQ(rc, ENOENT); + ATF_CHECK_STREQ(v, "xyz"); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TC(get_string_success); + +ATF_TC_HEAD(get_string_success, tc) +{ + atf_tc_set_md_var(tc, "descr", "check ppath_get_string() fetches " + "the \"job title\" property from the \"John Doe\" record in the " + "\"personnel\" property list and compares it with the expected " + "value, \"computer programmer\""); +} + +ATF_TC_BODY(get_string_success, tc) +{ + int rc; + const char *v = NULL;; + prop_dictionary_t d; + ppath_t *p; + + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); + + if ((d = prop_dictionary_internalize(personnel)) == NULL) + atf_tc_fail("prop_dictionary_internalize failed"); + + if ((p = ppath_create()) == NULL) + atf_tc_fail("ppath_create failed"); + + if (ppath_push_key(p, "John Doe") == NULL) + atf_tc_fail("ppath_push_key failed"); + if (ppath_push_key(p, "job title") == NULL) + atf_tc_fail("ppath_push_key failed"); + + rc = ppath_get_string(d, p, &v); + ATF_CHECK_EQ(rc, 0); + ATF_CHECK_STREQ(v, "computer programmer"); + + ppath_release(p); + prop_object_release(d); + assert_no_ppath_extant(); + assert_no_ppath_component_extant(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, push_until_full); + ATF_TP_ADD_TC(tp, pop_until_empty); + ATF_TP_ADD_TC(tp, length); + ATF_TP_ADD_TC(tp, component_at); + ATF_TP_ADD_TC(tp, get_idx_key); + ATF_TP_ADD_TC(tp, ppath_copy); + ATF_TP_ADD_TC(tp, replace); + + ATF_TP_ADD_TC(tp, delete_bool_eftype); + ATF_TP_ADD_TC(tp, delete_bool_enoent); + ATF_TP_ADD_TC(tp, delete_bool_success); + + ATF_TP_ADD_TC(tp, get_bool_eftype); + ATF_TP_ADD_TC(tp, get_bool_enoent); + ATF_TP_ADD_TC(tp, get_bool_success); + + ATF_TP_ADD_TC(tp, copydel_bool_success); + ATF_TP_ADD_TC(tp, copydel_object_twice_success); + ATF_TP_ADD_TC(tp, copyset_object_twice_success); + ATF_TP_ADD_TC(tp, copyset_bool_success); + ATF_TP_ADD_TC(tp, create_bool_eexist); + ATF_TP_ADD_TC(tp, create_bool_success); + ATF_TP_ADD_TC(tp, set_bool_enoent); + ATF_TP_ADD_TC(tp, set_bool_eftype); + ATF_TP_ADD_TC(tp, set_bool_success); + + ATF_TP_ADD_TC(tp, get_string_eftype); + ATF_TP_ADD_TC(tp, get_string_enoent); + ATF_TP_ADD_TC(tp, get_string_success); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libprop/t_basic.c b/contrib/netbsd-tests/lib/libprop/t_basic.c new file mode 100644 index 0000000..febf29d --- /dev/null +++ b/contrib/netbsd-tests/lib/libprop/t_basic.c @@ -0,0 +1,203 @@ +/* $NetBSD: t_basic.c,v 1.4 2011/04/20 20:02:58 martin Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Written by Jason Thorpe 5/26/2006. + * Public domain. + */ + +#include +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_basic.c,v 1.4 2011/04/20 20:02:58 martin Exp $"); + +#include +#include +#include + +#include + +static const char compare1[] = +"\n" +"\n" +"\n" +"\n" +" false-val\n" +" \n" +" one\n" +" 1\n" +" three\n" +" \n" +" \n" +" one\n" +" 1\n" +" two\n" +" number-two\n" +" \n" +" \n" +" one\n" +" 1\n" +" two\n" +" number-two\n" +" \n" +" \n" +" one\n" +" 1\n" +" two\n" +" number-two\n" +" \n" +" \n" +" true-val\n" +" \n" +" two\n" +" number-two\n" +"\n" +"\n"; + +ATF_TC(prop_basic); +ATF_TC_HEAD(prop_basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of proplib(3)"); +} + +ATF_TC_BODY(prop_basic, tc) +{ + prop_dictionary_t dict; + char *ext1; + + dict = prop_dictionary_create(); + ATF_REQUIRE(dict != NULL); + + { + prop_number_t num = prop_number_create_integer(1); + ATF_REQUIRE(num != NULL); + + ATF_REQUIRE_EQ(prop_dictionary_set(dict, "one", num), true); + prop_object_release(num); + } + + { + prop_string_t str = prop_string_create_cstring("number-two"); + ATF_REQUIRE(str != NULL); + + ATF_REQUIRE_EQ(prop_dictionary_set(dict, "two", str), true); + prop_object_release(str); + } + + { + prop_array_t arr; + prop_dictionary_t dict_copy; + int i; + + arr = prop_array_create(); + ATF_REQUIRE(arr != NULL); + + for (i = 0; i < 3; ++i) { + dict_copy = prop_dictionary_copy(dict); + ATF_REQUIRE(dict_copy != NULL); + ATF_REQUIRE_EQ(prop_array_add(arr, dict_copy), true); + prop_object_release(dict_copy); + } + + ATF_REQUIRE_EQ(prop_dictionary_set(dict, "three", arr), true); + prop_object_release(arr); + } + + { + prop_bool_t val = prop_bool_create(true); + ATF_REQUIRE(val != NULL); + ATF_REQUIRE_EQ(prop_dictionary_set(dict, "true-val", val), true); + prop_object_release(val); + + val = prop_bool_create(false); + ATF_REQUIRE(val != NULL); + ATF_REQUIRE_EQ(prop_dictionary_set(dict, "false-val", val), true); + prop_object_release(val); + } + + ext1 = prop_dictionary_externalize(dict); + ATF_REQUIRE(ext1 != NULL); + ATF_REQUIRE_STREQ(compare1, ext1); + + { + prop_dictionary_t dict2; + char *ext2; + + dict2 = prop_dictionary_internalize(ext1); + ATF_REQUIRE(dict2 != NULL); + ext2 = prop_dictionary_externalize(dict2); + ATF_REQUIRE(ext2 != NULL); + ATF_REQUIRE_STREQ(ext1, ext2); + prop_object_release(dict2); + free(ext2); + } + + prop_object_release(dict); + free(ext1); +} + +ATF_TC(prop_dictionary_equals); +ATF_TC_HEAD(prop_dictionary_equals, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test prop_dictionary_equals(3)"); +} + +ATF_TC_BODY(prop_dictionary_equals, tc) +{ + prop_dictionary_t c, d; + + /* + * Fixed, should not fail any more... + * + atf_tc_expect_death("PR lib/43964"); + * + */ + + d = prop_dictionary_internalize(compare1); + + ATF_REQUIRE(d != NULL); + + c = prop_dictionary_copy(d); + + ATF_REQUIRE(c != NULL); + + if (prop_dictionary_equals(c, d) != true) + atf_tc_fail("dictionaries are not equal"); + + prop_object_release(c); + prop_object_release(d); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, prop_basic); + ATF_TP_ADD_TC(tp, prop_dictionary_equals); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/d_mach b/contrib/netbsd-tests/lib/libpthread/d_mach new file mode 100644 index 0000000..f3c3981 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/d_mach @@ -0,0 +1,92 @@ +above.warped.net +anoncvs.cirr.com +anoncvs.isc.netbsd.org +anoncvs.leo.org +anoncvs.netbsd.lt +anoncvs.netbsd.ro +anoncvs.netbsd.se +antioche.antioche.eu.org +boulder.tele.dk +centaurus.4web.cz +chur.math.ntnu.no +cnftp.bjpu.edu.cn +console.netbsd.org +cvs.fi.netbsd.org +cvs.mikrolahti.fi +cvs.netbsd.org +cvsup-netbsd.leo.org +cvsup.netbsd.se +cvsup.pasta.cs.uit.no +ftp.bitcon.no +ftp.chg.ru +ftp.duth.gr +ftp.estpak.ee +ftp.fsn.hu +ftp.funet.fi +ftp.grondar.za +ftp.leo.org +ftp.netbsd.lt +ftp.netbsd.org +ftp.nluug.nl +ftp.plig.org +ftp.uni-erlangen.de +ftp.xgate.co.kr +gd.tuwien.ac.at +gort.ludd.luth.se +grappa.unix-ag.uni-kl.de +info.wins.uva.nl +irc.warped.net +knug.youn.co.kr +lala.iri.co.jp +mail.jp.netbsd.org +mail.kr.netbsd.org +mail.netbsd.org +melanoma.cs.rmit.edu.au +mirror.aarnet.edu.au +mirror.netbsd.com.br +mirror03.inet.tele.dk +moon.vub.ac.be +nbwww.sergei.cc +net.bsd.cz +netbsd.3miasto.net +netbsd.4ka.mipt.ru +netbsd.apk.od.ua +netbsd.csie.nctu.edu.tw +netbsd.enderunix.org +netbsd.ftp.fu-berlin.de +netbsd.netlead.com.au +netbsd.nsysu.edu.tw +netbsd.pair.com +netbsd.stevens-tech.edu +netbsd.triada.bg +netbsd.unix.net.nz +netbsd.unixtech.be +netbsd.vejas.lt +netbsd.wagener-consulting.lu +netbsd.zarco.org +netbsdiso.interoute.net.uk +netbsdwww.bitcon.no +netbsdwww.cordef.com.pl +netbsdwww.cs.rmit.edu.au +netbsdwww.interoute.net.uk +news.gw.com +ns.netbsd.org +pigu.iri.co.jp +pluto.cdpa.nsysu.edu.tw +projects.slowass.net +server6.pasta.cs.uit.no +skeleton.phys.spbu.ru +snoopy.allbsd.org +spike.allbsd.org +sundry.netbsd.org +tanya.sergei.cc +web-a.fi.gw.com +web-a.us.gw.com +web.netbsd.mirror.arhea.net +www.en.netbsd.de +www.netbsd.cl +www.netbsd.nl +www.netbsd.org +www.netbsd.ro +zathras.netbsd.org +zeppo.rediris.es diff --git a/contrib/netbsd-tests/lib/libpthread/dlopen/dso/h_pthread_dlopen.c b/contrib/netbsd-tests/lib/libpthread/dlopen/dso/h_pthread_dlopen.c new file mode 100644 index 0000000..63bf6a3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/dlopen/dso/h_pthread_dlopen.c @@ -0,0 +1,86 @@ +/* $NetBSD: h_pthread_dlopen.c,v 1.1 2013/03/21 16:50:22 christos Exp $ */ +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: h_pthread_dlopen.c,v 1.1 2013/03/21 16:50:22 christos Exp $"); + +#if 0 +#include +#else +#include +#define ATF_REQUIRE(a) assert(a) +#endif +#include +#include + +int testf_dso_null(void); +int testf_dso_mutex_lock(pthread_mutex_t *); +int testf_dso_mutex_unlock(pthread_mutex_t *); +int testf_dso_pthread_create(pthread_t *, const pthread_attr_t *, + void *(*)(void *), void *); + +int +testf_dso_null(void) +{ + return 0xcafe; +} + +int +testf_dso_mutex_lock(pthread_mutex_t *mtx) +{ + ATF_REQUIRE(mtx != NULL); + ATF_REQUIRE(pthread_mutex_lock(mtx) == 0); + + return 0xcafe; +} + +int +testf_dso_mutex_unlock(pthread_mutex_t *mtx) +{ + ATF_REQUIRE(mtx != NULL); + ATF_REQUIRE(pthread_mutex_unlock(mtx) == 0); + + return 0xcafe; +} + +int +testf_dso_pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*routine)(void *), void *arg) +{ + int ret; + + ret = pthread_create(thread, attr, routine, arg); + ATF_REQUIRE(ret == 0); + + return 0; +} diff --git a/contrib/netbsd-tests/lib/libpthread/dlopen/t_dlopen.c b/contrib/netbsd-tests/lib/libpthread/dlopen/t_dlopen.c new file mode 100644 index 0000000..68e9835 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/dlopen/t_dlopen.c @@ -0,0 +1,171 @@ +/* $NetBSD: t_dlopen.c,v 1.1 2013/03/21 16:50:21 christos Exp $ */ +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_dlopen.c,v 1.1 2013/03/21 16:50:21 christos Exp $"); + +#include +#include +#include +#include + +ATF_TC(dlopen); + +ATF_TC_HEAD(dlopen, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if dlopen can load -lpthread DSO"); +} + +#define DSO TESTDIR "/h_pthread_dlopen.so" + +ATF_TC_BODY(dlopen, tc) +{ + void *handle; + int (*testf_dso_null)(void); + handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror()); + + testf_dso_null = dlsym(handle, "testf_dso_null"); + ATF_REQUIRE_MSG(testf_dso_null != NULL, "dlsym fails: %s", dlerror()); + + ATF_REQUIRE(testf_dso_null() == 0xcafe); + + ATF_REQUIRE(dlclose(handle) == 0); +} + +ATF_TC(dlopen_mutex); + +ATF_TC_HEAD(dlopen_mutex, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if dlopen can load -lpthread DSO without breaking mutex"); +} + +ATF_TC_BODY(dlopen_mutex, tc) +{ + pthread_mutex_t mtx; + void *handle; + int (*testf_dso_null)(void); + + ATF_REQUIRE(pthread_mutex_init(&mtx, NULL) == 0); + ATF_REQUIRE(pthread_mutex_lock(&mtx) == 0); + + handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror()); + + testf_dso_null = dlsym(handle, "testf_dso_null"); + ATF_REQUIRE_MSG(testf_dso_null != NULL, "dlsym fails: %s", dlerror()); + + ATF_REQUIRE(testf_dso_null() == 0xcafe); + + ATF_REQUIRE(pthread_mutex_unlock(&mtx) == 0); + + ATF_REQUIRE(dlclose(handle) == 0); + + pthread_mutex_destroy(&mtx); +} + +ATF_TC(dlopen_mutex_libc); + +ATF_TC_HEAD(dlopen_mutex_libc, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if dlopen can load -lpthread DSO and use libc locked mutex"); +} + +ATF_TC_BODY(dlopen_mutex_libc, tc) +{ + pthread_mutex_t mtx; + void *handle; + int (*testf_dso_mutex_unlock)(pthread_mutex_t *); + + ATF_REQUIRE(pthread_mutex_init(&mtx, NULL) == 0); + ATF_REQUIRE(pthread_mutex_lock(&mtx) == 0); + + handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror()); + + testf_dso_mutex_unlock = dlsym(handle, "testf_dso_mutex_unlock"); + ATF_REQUIRE_MSG(testf_dso_mutex_unlock != NULL, + "dlsym fails: %s", dlerror()); + + ATF_REQUIRE(testf_dso_mutex_unlock(&mtx) == 0xcafe); + + dlclose(handle); + + pthread_mutex_destroy(&mtx); +} + +ATF_TC(dlopen_mutex_libpthread); + +ATF_TC_HEAD(dlopen_mutex_libpthread, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if dlopen can load -lpthread DSO and use " + "libpthread locked mutex"); +} + +ATF_TC_BODY(dlopen_mutex_libpthread, tc) +{ + pthread_mutex_t mtx; + void *handle; + int (*testf_dso_mutex_lock)(pthread_mutex_t *); + + ATF_REQUIRE(pthread_mutex_init(&mtx, NULL) == 0); + + handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror()); + + testf_dso_mutex_lock = dlsym(handle, "testf_dso_mutex_lock"); + ATF_REQUIRE_MSG(testf_dso_mutex_lock != NULL, + "dlsym fails: %s", dlerror()); + + ATF_REQUIRE(testf_dso_mutex_lock(&mtx) == 0xcafe); + + ATF_REQUIRE(pthread_mutex_unlock(&mtx) == 0); + + dlclose(handle); + + pthread_mutex_destroy(&mtx); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, dlopen); + ATF_TP_ADD_TC(tp, dlopen_mutex); + ATF_TP_ADD_TC(tp, dlopen_mutex_libc); + ATF_TP_ADD_TC(tp, dlopen_mutex_libpthread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/dlopen/t_dso_pthread_create.c b/contrib/netbsd-tests/lib/libpthread/dlopen/t_dso_pthread_create.c new file mode 100644 index 0000000..ab8bec3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/dlopen/t_dso_pthread_create.c @@ -0,0 +1,96 @@ +/* $NetBSD: t_dso_pthread_create.c,v 1.1 2013/03/21 16:50:21 christos Exp $ */ +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_dso_pthread_create.c,v 1.1 2013/03/21 16:50:21 christos Exp $"); + +#include +#include +#include +#include +#include + +#define DSO TESTDIR "/h_pthread_dlopen.so" + +void * +routine(void *arg) +{ + ATF_REQUIRE((intptr_t)arg == 0xcafe); + return NULL; +} + +ATF_TC(dso_pthread_create_dso); + +ATF_TC_HEAD(dso_pthread_create_dso, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if non -lpthread main can call pthread_create() " + "in -lpthread DSO"); +} + +ATF_TC_BODY(dso_pthread_create_dso, tc) +{ + int ret; + pthread_t thread; + void *arg = (void *)0xcafe; + void *handle; + int (*testf_dso_pthread_create)(pthread_t *, pthread_attr_t *, + void *(*)(void *), void *); + struct rlimit rl; + + atf_tc_expect_signal(6, + "calling pthread_create() requires -lpthread main"); + + rl.rlim_max = rl.rlim_cur = 0; + ATF_REQUIRE_EQ(setrlimit(RLIMIT_CORE, &rl), 0); + + handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror()); + + testf_dso_pthread_create = dlsym(handle, "testf_dso_pthread_create"); + ATF_REQUIRE_MSG(testf_dso_pthread_create != NULL, + "dlsym fails: %s", dlerror()); + + ret = testf_dso_pthread_create(&thread, NULL, routine, arg); + ATF_REQUIRE(ret == 0); + + ATF_REQUIRE(dlclose(handle) == 0); + +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, dso_pthread_create_dso); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/dlopen/t_main_pthread_create.c b/contrib/netbsd-tests/lib/libpthread/dlopen/t_main_pthread_create.c new file mode 100644 index 0000000..7ba89b3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/dlopen/t_main_pthread_create.c @@ -0,0 +1,106 @@ +/* $NetBSD: t_main_pthread_create.c,v 1.1 2013/03/21 16:50:21 christos Exp $ */ +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_main_pthread_create.c,v 1.1 2013/03/21 16:50:21 christos Exp $"); + +#include +#include +#include +#include + +#define DSO TESTDIR "/h_pthread_dlopen.so" + +void * +routine(void *arg) +{ + ATF_REQUIRE((intptr_t)arg == 0xcafe); + return NULL; +} + +ATF_TC(main_pthread_create_main); + +ATF_TC_HEAD(main_pthread_create_main, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if -lpthread main can call pthread_create() in main()"); +} + +ATF_TC_BODY(main_pthread_create_main, tc) +{ + int ret; + pthread_t thread; + void *arg = (void *)0xcafe; + + ret = pthread_create(&thread, NULL, routine, arg); + ATF_REQUIRE(ret == 0); +} + +ATF_TC(main_pthread_create_dso); + +ATF_TC_HEAD(main_pthread_create_dso, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test if -lpthread main can call pthread_create() in DSO"); +} + +ATF_TC_BODY(main_pthread_create_dso, tc) +{ + int ret; + pthread_t thread; + void *arg = (void *)0xcafe; + void *handle; + int (*testf_dso_pthread_create)(pthread_t *, pthread_attr_t *, + void *(*)(void *), void *); + + handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL); + ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror()); + + testf_dso_pthread_create = dlsym(handle, "testf_dso_pthread_create"); + ATF_REQUIRE_MSG(testf_dso_pthread_create != NULL, + "dlsym fails: %s", dlerror()); + + ret = testf_dso_pthread_create(&thread, NULL, routine, arg); + ATF_REQUIRE(ret == 0); + + ATF_REQUIRE(dlclose(handle) == 0); + +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, main_pthread_create_main); + ATF_TP_ADD_TC(tp, main_pthread_create_dso); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/h_atexit.c b/contrib/netbsd-tests/lib/libpthread/h_atexit.c new file mode 100644 index 0000000..29b8775 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/h_atexit.c @@ -0,0 +1,203 @@ +/* $NetBSD: h_atexit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Program to test atexit(3) and __cxa_atexit()/__cxa_finalize(). + * + * Written by Jason R. Thorpe, February 2003. + * Public domain. + */ + +#include +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_atexit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include +#include +#include +#include +#include + +extern int __cxa_atexit(void (*func)(void *), void *, void *); +extern void __cxa_finalize(void *); + +#ifdef __FreeBSD__ +/* + * See comments in ../../lib/libc/stdlib/h_atexit.c about the deviation + * between FreeBSD and NetBSD with this helper program + */ +static void *dso_handle_1 = (void *)1; +static void *dso_handle_2 = (void *)2; +static void *dso_handle_3 = (void *)3; +#else +static int dso_handle_1; +static int dso_handle_2; +static int dso_handle_3; +#endif + +static int arg_1; +static int arg_2; +static int arg_3; + +static int exiting_state; + +#define ASSERT(expr) \ +do { \ + if ((expr) == 0) { \ + write(STDERR_FILENO, __func__, strlen(__func__)); \ + write(STDERR_FILENO, ": ", 2); \ + write(STDERR_FILENO, __STRING(expr), \ + strlen(__STRING(expr))); \ + write(STDERR_FILENO, "\n", 1); \ + my_abort(); \ + } \ +} while (/*CONSTCOND*/0) + +#define SUCCESS() \ +do { \ + write(STDOUT_FILENO, __func__, strlen(__func__)); \ + write(STDOUT_FILENO, "\n", 1); \ +} while (/*CONSTCOND*/0) + +static void +my_abort(void) +{ + + kill(getpid(), SIGABRT); + /* NOTREACHED */ +} + +static void +cxa_handler_5(void *arg) +{ + static int cxa_handler_5_called; + + ASSERT(arg == (void *)&arg_1); + ASSERT(cxa_handler_5_called == 0); + ASSERT(exiting_state == 5); + + exiting_state--; + cxa_handler_5_called = 1; + SUCCESS(); +} + +static void +cxa_handler_4(void *arg) +{ + static int cxa_handler_4_called; + + ASSERT(arg == (void *)&arg_1); + ASSERT(cxa_handler_4_called == 0); + ASSERT(exiting_state == 4); + + exiting_state--; + cxa_handler_4_called = 1; + SUCCESS(); +} + +static void +cxa_handler_3(void *arg) +{ + static int cxa_handler_3_called; + + ASSERT(arg == (void *)&arg_2); + ASSERT(cxa_handler_3_called == 0); + ASSERT(exiting_state == 3); + + exiting_state--; + cxa_handler_3_called = 1; + SUCCESS(); +} + +static void +cxa_handler_2(void *arg) +{ + static int cxa_handler_2_called; + + ASSERT(arg == (void *)&arg_3); + ASSERT(cxa_handler_2_called == 0); + ASSERT(exiting_state == 2); + + exiting_state--; + cxa_handler_2_called = 1; + SUCCESS(); +} + +static void +normal_handler_1(void) +{ + static int normal_handler_1_called; + + ASSERT(normal_handler_1_called == 0); + ASSERT(exiting_state == 1); + + exiting_state--; + normal_handler_1_called = 1; + SUCCESS(); +} + +static void +normal_handler_0(void) +{ + static int normal_handler_0_called; + + ASSERT(normal_handler_0_called == 0); + ASSERT(exiting_state == 0); + + normal_handler_0_called = 1; + SUCCESS(); +} + +int +main(int argc, char *argv[]) +{ + + exiting_state = 5; + +#ifdef __FreeBSD__ + ASSERT(0 == atexit(normal_handler_0)); + ASSERT(0 == atexit(normal_handler_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, dso_handle_2)); + ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, dso_handle_3)); + + __cxa_finalize(dso_handle_1); + __cxa_finalize(dso_handle_2); +#else + ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, &dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, &dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, &dso_handle_2)); + ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, &dso_handle_3)); + + __cxa_finalize(&dso_handle_1); + __cxa_finalize(&dso_handle_2); +#endif + exit(0); +} diff --git a/contrib/netbsd-tests/lib/libpthread/h_cancel.c b/contrib/netbsd-tests/lib/libpthread/h_cancel.c new file mode 100644 index 0000000..b7a9363 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/h_cancel.c @@ -0,0 +1,60 @@ +/* $NetBSD: h_cancel.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_cancel.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include +#include +#include +#include + +int +main(void) +{ + char str1[] = "You should see this.\n"; + char str2[] = "You should not see this.\n"; + +#ifdef __NetBSD__ + printf("Cancellation test: Self-cancellation and disabling.\n"); +#endif + + pthread_cancel(pthread_self()); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + + write(STDOUT_FILENO, str1, sizeof(str1)-1); + + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + write(STDOUT_FILENO, str2, sizeof(str2)-1); + + exit(1); +} diff --git a/contrib/netbsd-tests/lib/libpthread/h_common.h b/contrib/netbsd-tests/lib/libpthread/h_common.h new file mode 100644 index 0000000..261b07f --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/h_common.h @@ -0,0 +1,18 @@ +#ifndef H_COMMON_H +#define H_COMMON_H + +#include + +#define PTHREAD_REQUIRE(x) \ + do { \ + int _ret = (x); \ + ATF_REQUIRE_MSG(_ret == 0, "%s: %s", #x, strerror(_ret)); \ + } while (0) + +#define PTHREAD_REQUIRE_STATUS(x, v) \ + do { \ + int _ret = (x); \ + ATF_REQUIRE_MSG(_ret == (v), "%s: %s", #x, strerror(_ret)); \ + } while (0) + +#endif // H_COMMON_H diff --git a/contrib/netbsd-tests/lib/libpthread/h_exit.c b/contrib/netbsd-tests/lib/libpthread/h_exit.c new file mode 100644 index 0000000..a37f88f --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/h_exit.c @@ -0,0 +1,47 @@ +/* $NetBSD: h_exit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_exit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include +#include +#include + +int +main(void) +{ + printf("Test of pthread_exit() in main thread only.\n"); + + pthread_exit(NULL); + + printf("You shouldn't see this."); + exit(1); +} diff --git a/contrib/netbsd-tests/lib/libpthread/h_resolv.c b/contrib/netbsd-tests/lib/libpthread/h_resolv.c new file mode 100644 index 0000000..9c5fedc --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/h_resolv.c @@ -0,0 +1,208 @@ +/* $NetBSD: h_resolv.c,v 1.2 2010/11/03 16:10:22 christos Exp $ */ + +/*- + * Copyright (c) 2004, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: h_resolv.c,v 1.2 2010/11/03 16:10:22 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#define NTHREADS 10 +#define NHOSTS 100 +#define WS " \t\n\r" + +static StringList *hosts = NULL; +static int debug = 0; +static int *ask = NULL; +static int *got = NULL; + +static void usage(void) __attribute__((__noreturn__)); +static void load(const char *); +static void resolvone(int); +static void *resolvloop(void *); +static void run(int *); + +static pthread_mutex_t stats = PTHREAD_MUTEX_INITIALIZER; + +static void +usage(void) +{ + (void)fprintf(stderr, + "Usage: %s [-d] [-h ] [-n ] ...\n", + getprogname()); + exit(1); +} + +static void +load(const char *fname) +{ + FILE *fp; + size_t len; + char *line; + + if ((fp = fopen(fname, "r")) == NULL) + err(1, "Cannot open `%s'", fname); + while ((line = fgetln(fp, &len)) != NULL) { + char c = line[len]; + char *ptr; + line[len] = '\0'; + for (ptr = strtok(line, WS); ptr; ptr = strtok(NULL, WS)) + sl_add(hosts, strdup(ptr)); + line[len] = c; + } + + (void)fclose(fp); +} + +static void +resolvone(int n) +{ + char buf[1024]; + pthread_t self = pthread_self(); + size_t i = (random() & 0x0fffffff) % hosts->sl_cur; + char *host = hosts->sl_str[i]; + struct addrinfo *res; + int error, len; + if (debug) { + len = snprintf(buf, sizeof(buf), "%p: %d resolving %s %d\n", + self, n, host, (int)i); + (void)write(STDOUT_FILENO, buf, len); + } + error = getaddrinfo(host, NULL, NULL, &res); + if (debug) { + len = snprintf(buf, sizeof(buf), "%p: host %s %s\n", + self, host, error ? "not found" : "ok"); + (void)write(STDOUT_FILENO, buf, len); + } + pthread_mutex_lock(&stats); + ask[i]++; + got[i] += error == 0; + pthread_mutex_unlock(&stats); + if (error == 0) + freeaddrinfo(res); +} + +static void * +resolvloop(void *p) +{ + int *nhosts = (int *)p; + if (*nhosts == 0) + return NULL; + do + resolvone(*nhosts); + while (--(*nhosts)); + return NULL; +} + +static void +run(int *nhosts) +{ + pthread_t self = pthread_self(); + if (pthread_create(&self, NULL, resolvloop, nhosts) != 0) + err(1, "pthread_create"); +} + +int +main(int argc, char *argv[]) +{ + int nthreads = NTHREADS; + int nhosts = NHOSTS; + int i, c, done, *nleft; + hosts = sl_init(); + + srandom(1234); + + while ((c = getopt(argc, argv, "dh:n:")) != -1) + switch (c) { + case 'd': + debug++; + break; + case 'h': + nhosts = atoi(optarg); + break; + case 'n': + nthreads = atoi(optarg); + break; + default: + usage(); + } + + for (i = optind; i < argc; i++) + load(argv[i]); + + if (hosts->sl_cur == 0) + usage(); + + if ((nleft = malloc(nthreads * sizeof(int))) == NULL) + err(1, "malloc"); + if ((ask = calloc(hosts->sl_cur, sizeof(int))) == NULL) + err(1, "calloc"); + if ((got = calloc(hosts->sl_cur, sizeof(int))) == NULL) + err(1, "calloc"); + + + for (i = 0; i < nthreads; i++) { + nleft[i] = nhosts; + run(&nleft[i]); + } + + for (done = 0; !done;) { + done = 1; + for (i = 0; i < nthreads; i++) { + if (nleft[i] != 0) { + done = 0; + break; + } + } + sleep(1); + } + c = 0; + for (i = 0; i < (int)hosts->sl_cur; i++) { + if (ask[i] != got[i] && got[i] != 0) { + warnx("Error: host %s ask %d got %d\n", + hosts->sl_str[i], ask[i], got[i]); + c++; + } + } + free(nleft); + free(ask); + free(got); + sl_free(hosts, 1); + return c; +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_atexit.sh b/contrib/netbsd-tests/lib/libpthread/t_atexit.sh new file mode 100755 index 0000000..7b99618 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_atexit.sh @@ -0,0 +1,49 @@ +# $NetBSD: t_atexit.sh,v 1.2 2010/11/07 17:51:20 jmmv Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case atexit +atexit_head() +{ + atf_set "descr" "Checks atexit functionality" +} +atexit_body() +{ + cat >expout < +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_barrier.c,v 1.2 2010/11/03 16:10:22 christos Exp $"); + +#include +#include +#include + +#include + +#include "h_common.h" + +#define COUNT 5 + +pthread_barrier_t barrier; +pthread_mutex_t mutex; +int serial_count; +int after_barrier_count; + +static void * +threadfunc(void *arg) +{ + int which = (int)(long)arg; + int rv; + + printf("thread %d entering barrier\n", which); + rv = pthread_barrier_wait(&barrier); + printf("thread %d leaving barrier -> %d\n", which, rv); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + after_barrier_count++; + if (rv == PTHREAD_BARRIER_SERIAL_THREAD) + serial_count++; + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + return NULL; +} + +ATF_TC(barrier); +ATF_TC_HEAD(barrier, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks barriers"); +} +ATF_TC_BODY(barrier, tc) +{ + int i; + pthread_t new[COUNT]; + void *joinval; + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + PTHREAD_REQUIRE(pthread_barrier_init(&barrier, NULL, COUNT)); + + for (i = 0; i < COUNT; i++) { + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + ATF_REQUIRE_EQ(after_barrier_count, 0); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + PTHREAD_REQUIRE(pthread_create(&new[i], NULL, threadfunc, + (void *)(long)i)); + sleep(2); + } + + for (i = 0; i < COUNT; i++) { + PTHREAD_REQUIRE(pthread_join(new[i], &joinval)); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + ATF_REQUIRE(after_barrier_count > i); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + printf("main joined with thread %d\n", i); + } + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + ATF_REQUIRE_EQ(after_barrier_count, COUNT); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + ATF_REQUIRE_EQ(serial_count, 1); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, barrier); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_cancel.sh b/contrib/netbsd-tests/lib/libpthread/t_cancel.sh new file mode 100755 index 0000000..4a0701e --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_cancel.sh @@ -0,0 +1,44 @@ +# $NetBSD: t_cancel.sh,v 1.1 2010/07/16 15:42:53 jmmv Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case register_while_disabled +register_while_disabled_head() +{ + atf_set "descr" "Checks that a cancellation registered while" \ + "cancellation is enabled is not honored while cancellation is" \ + "disabled" +} +register_while_disabled_body() +{ + atf_check -o inline:"You should see this.\n" \ + "$(atf_get_srcdir)/h_cancel" +} + +atf_init_test_cases() +{ + atf_add_test_case register_while_disabled +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_cond.c b/contrib/netbsd-tests/lib/libpthread/t_cond.c new file mode 100644 index 0000000..83a3833 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_cond.c @@ -0,0 +1,584 @@ +/* $NetBSD: t_cond.c,v 1.7 2016/07/03 14:24:59 christos Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_cond.c,v 1.7 2016/07/03 14:24:59 christos Exp $"); + +#include + +#include +#include +#include +#include + +#include + +#include "h_common.h" + +static pthread_mutex_t mutex; +static pthread_cond_t cond; +static pthread_mutex_t static_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t static_cond = PTHREAD_COND_INITIALIZER; +static int count, share, toggle, total; + +static void * +signal_delay_wait_threadfunc(void *arg) +{ + int *shared = (int *) arg; + + printf("2: Second thread.\n"); + + printf("2: Locking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + printf("2: Got mutex.\n"); + printf("Shared value: %d. Changing to 0.\n", *shared); + *shared = 0; + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + PTHREAD_REQUIRE(pthread_cond_signal(&cond)); + + return NULL; +} + +ATF_TC(signal_delay_wait); +ATF_TC_HEAD(signal_delay_wait, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks condition variables"); +} +ATF_TC_BODY(signal_delay_wait, tc) +{ + pthread_t new; + void *joinval; + int sharedval; + + printf("1: condition variable test 1\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL)); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + sharedval = 1; + + PTHREAD_REQUIRE(pthread_create(&new, NULL, signal_delay_wait_threadfunc, + &sharedval)); + + printf("1: Before waiting.\n"); + do { + sleep(2); + PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex)); + printf("1: After waiting, in loop.\n"); + } while (sharedval != 0); + + printf("1: After the loop.\n"); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + printf("1: After releasing the mutex.\n"); + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + printf("1: Thread joined.\n"); +} + +static void * +signal_before_unlock_threadfunc(void *arg) +{ + int *shared = (int *) arg; + + printf("2: Second thread.\n"); + + printf("2: Locking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + printf("2: Got mutex.\n"); + printf("Shared value: %d. Changing to 0.\n", *shared); + *shared = 0; + + /* Signal first, then unlock, for a different test than #1. */ + PTHREAD_REQUIRE(pthread_cond_signal(&cond)); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + return NULL; +} + +ATF_TC(signal_before_unlock); +ATF_TC_HEAD(signal_before_unlock, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks condition variables: signal before unlocking mutex"); +} +ATF_TC_BODY(signal_before_unlock, tc) +{ + pthread_t new; + void *joinval; + int sharedval; + + printf("1: condition variable test 2\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL)); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + sharedval = 1; + + PTHREAD_REQUIRE(pthread_create(&new, NULL, + signal_before_unlock_threadfunc, &sharedval)); + + printf("1: Before waiting.\n"); + do { + sleep(2); + PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex)); + printf("1: After waiting, in loop.\n"); + } while (sharedval != 0); + + printf("1: After the loop.\n"); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + printf("1: After releasing the mutex.\n"); + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + printf("1: Thread joined.\n"); +} + +static void * +signal_before_unlock_static_init_threadfunc(void *arg) +{ + int *shared = (int *) arg; + + printf("2: Second thread.\n"); + + printf("2: Locking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + printf("2: Got mutex.\n"); + printf("Shared value: %d. Changing to 0.\n", *shared); + *shared = 0; + + /* Signal first, then unlock, for a different test than #1. */ + PTHREAD_REQUIRE(pthread_cond_signal(&static_cond)); + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + + return NULL; +} + +ATF_TC(signal_before_unlock_static_init); +ATF_TC_HEAD(signal_before_unlock_static_init, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks condition variables: signal before unlocking " + "mutex, use static initializers"); +} +ATF_TC_BODY(signal_before_unlock_static_init, tc) +{ + pthread_t new; + void *joinval; + int sharedval; + + printf("1: condition variable test 3\n"); + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + + sharedval = 1; + + PTHREAD_REQUIRE(pthread_create(&new, NULL, + signal_before_unlock_static_init_threadfunc, &sharedval)); + + printf("1: Before waiting.\n"); + do { + sleep(2); + PTHREAD_REQUIRE(pthread_cond_wait(&static_cond, &static_mutex)); + printf("1: After waiting, in loop.\n"); + } while (sharedval != 0); + + printf("1: After the loop.\n"); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + + printf("1: After releasing the mutex.\n"); + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + printf("1: Thread joined.\n"); +} + +static void * +signal_wait_race_threadfunc(void *arg) +{ + printf("2: Second thread.\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + printf("2: Before the loop.\n"); + while (count>0) { + count--; + total++; + toggle = 0; + /* printf("2: Before signal %d.\n", count); */ + PTHREAD_REQUIRE(pthread_cond_signal(&static_cond)); + do { + PTHREAD_REQUIRE(pthread_cond_wait(&static_cond, + &static_mutex)); + } while (toggle != 1); + } + printf("2: After the loop.\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + + return NULL; +} + +ATF_TC(signal_wait_race); +ATF_TC_HEAD(signal_wait_race, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks condition variables"); +} +ATF_TC_BODY(signal_wait_race, tc) +{ + pthread_t new; + void *joinval; + int sharedval; + + printf("1: condition variable test 4\n"); + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + + count = 50000; + toggle = 0; + + PTHREAD_REQUIRE(pthread_create(&new, NULL, signal_wait_race_threadfunc, + &sharedval)); + + printf("1: Before waiting.\n"); + while (count>0) { + count--; + total++; + toggle = 1; + /* printf("1: Before signal %d.\n", count); */ + PTHREAD_REQUIRE(pthread_cond_signal(&static_cond)); + do { + PTHREAD_REQUIRE(pthread_cond_wait(&static_cond, + &static_mutex)); + } while (toggle != 0); + } + printf("1: After the loop.\n"); + + toggle = 1; + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + PTHREAD_REQUIRE(pthread_cond_signal(&static_cond)); + + printf("1: After releasing the mutex.\n"); + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + printf("1: Thread joined. Final count = %d, total = %d\n", + count, total); + + ATF_REQUIRE_EQ(count, 0); + ATF_REQUIRE_EQ(total, 50000); +} + +static void * +pthread_cond_timedwait_func(void *arg) +{ + struct timespec ts; + size_t i = 0; + int rv; + + for (;;) { + + if (i++ >= 10000) + pthread_exit(NULL); + + (void)memset(&ts, 0, sizeof(struct timespec)); + + ATF_REQUIRE(clock_gettime(CLOCK_REALTIME, &ts) == 0); + + /* + * Set to one second in the past: + * pthread_cond_timedwait(3) should + * return ETIMEDOUT immediately. + */ + ts.tv_sec = ts.tv_sec - 1; + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + rv = pthread_cond_timedwait(&static_cond, &static_mutex, &ts); + + /* + * Sometimes we catch ESRCH. + * This should never happen. + */ + ATF_REQUIRE(rv == ETIMEDOUT); + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + } +} + +ATF_TC(cond_timedwait_race); +ATF_TC_HEAD(cond_timedwait_race, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test pthread_cond_timedwait(3)"); + +} +ATF_TC_BODY(cond_timedwait_race, tc) +{ + pthread_t tid[64]; + size_t i; + + for (i = 0; i < __arraycount(tid); i++) { + + PTHREAD_REQUIRE(pthread_create(&tid[i], NULL, + pthread_cond_timedwait_func, NULL)); + } + + for (i = 0; i < __arraycount(tid); i++) { + + PTHREAD_REQUIRE(pthread_join(tid[i], NULL)); + } +} + +static void * +broadcast_threadfunc(void *arg) +{ + printf("2: Second thread.\n"); + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + while (count>0) { + count--; + total++; + toggle = 0; + PTHREAD_REQUIRE(pthread_cond_signal(&static_cond)); + do { + PTHREAD_REQUIRE(pthread_cond_wait(&static_cond, + &static_mutex)); + } while (toggle != 1); + } + printf("2: After the loop.\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + + return NULL; +} + + +ATF_TC(broadcast); +ATF_TC_HEAD(broadcast, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks condition variables: use pthread_cond_broadcast()"); +} +ATF_TC_BODY(broadcast, tc) +{ + pthread_t new; + void *joinval; + int sharedval; + + printf("1: condition variable test 5\n"); + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + + count = 50000; + toggle = 0; + + PTHREAD_REQUIRE(pthread_create(&new, NULL, broadcast_threadfunc, + &sharedval)); + + printf("1: Before waiting.\n"); + while (count>0) { + count--; + total++; + toggle = 1; + PTHREAD_REQUIRE(pthread_cond_broadcast(&static_cond)); + do { + PTHREAD_REQUIRE(pthread_cond_wait(&static_cond, + &static_mutex)); + } while (toggle != 0); + } + printf("1: After the loop.\n"); + + toggle = 1; + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + PTHREAD_REQUIRE(pthread_cond_signal(&static_cond)); + + printf("1: After releasing the mutex.\n"); + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + printf("1: Thread joined. Final count = %d, total = %d\n", count, + total); + + ATF_REQUIRE_EQ(count, 0); + ATF_REQUIRE_EQ(total, 50000); +} + +static void * +bogus_timedwaits_threadfunc(void *arg) +{ + return NULL; +} + +ATF_TC(bogus_timedwaits); +ATF_TC_HEAD(bogus_timedwaits, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks condition variables: bogus timedwaits"); +} +ATF_TC_BODY(bogus_timedwaits, tc) +{ + pthread_t new; + struct timespec ts; + struct timeval tv; + + printf("condition variable test 6: bogus timedwaits\n"); + + PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex)); + + printf("unthreaded test (past)\n"); + gettimeofday(&tv, NULL); + tv.tv_sec -= 2; /* Place the time in the past */ + TIMEVAL_TO_TIMESPEC(&tv, &ts); + + ATF_REQUIRE_EQ_MSG(pthread_cond_timedwait(&static_cond, &static_mutex, + &ts), ETIMEDOUT, "pthread_cond_timedwait() (unthreaded) in the " + "past"); + + printf("unthreaded test (zero time)\n"); + tv.tv_sec = 0; + tv.tv_usec = 0; + TIMEVAL_TO_TIMESPEC(&tv, &ts); + + ATF_REQUIRE_EQ_MSG(pthread_cond_timedwait(&static_cond, &static_mutex, + &ts), ETIMEDOUT, "pthread_cond_timedwait() (unthreaded) with zero " + "time"); + + PTHREAD_REQUIRE(pthread_create(&new, NULL, bogus_timedwaits_threadfunc, + NULL)); + PTHREAD_REQUIRE(pthread_join(new, NULL)); + + printf("threaded test\n"); + gettimeofday(&tv, NULL); + tv.tv_sec -= 2; /* Place the time in the past */ + TIMEVAL_TO_TIMESPEC(&tv, &ts); + + ATF_REQUIRE_EQ_MSG(pthread_cond_timedwait(&static_cond, &static_mutex, + &ts), ETIMEDOUT, "pthread_cond_timedwait() (threaded) in the past"); + + printf("threaded test (zero time)\n"); + tv.tv_sec = 0; + tv.tv_usec = 0; + TIMEVAL_TO_TIMESPEC(&tv, &ts); + + ATF_REQUIRE_EQ_MSG(pthread_cond_timedwait(&static_cond, &static_mutex, + &ts), ETIMEDOUT, "pthread_cond_timedwait() (threaded) with zero " + "time"); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); +} + +static void +unlock(void *arg) +{ + pthread_mutex_unlock((pthread_mutex_t *)arg); +} + +static void * +destroy_after_cancel_threadfunc(void *arg) +{ + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + pthread_cleanup_push(unlock, &mutex); + + while (1) { + share = 1; + PTHREAD_REQUIRE(pthread_cond_broadcast(&cond)); + PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex)); + } + + pthread_cleanup_pop(0); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + return NULL; +} + +ATF_TC(destroy_after_cancel); +ATF_TC_HEAD(destroy_after_cancel, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks destroying a condition variable " + "after cancelling a wait"); +} +ATF_TC_BODY(destroy_after_cancel, tc) +{ + pthread_t thread; + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL)); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(pthread_create(&thread, NULL, + destroy_after_cancel_threadfunc, NULL)); + + while (share == 0) { + PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex)); + } + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + PTHREAD_REQUIRE(pthread_cancel(thread)); + + PTHREAD_REQUIRE(pthread_join(thread, NULL)); + PTHREAD_REQUIRE(pthread_cond_destroy(&cond)); + + PTHREAD_REQUIRE(pthread_mutex_destroy(&mutex)); +} + +ATF_TC(condattr); +ATF_TC_HEAD(condattr, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks Condattr"); +} +ATF_TC_BODY(condattr, tc) +{ + pthread_condattr_t condattr; + clockid_t clockid; + + PTHREAD_REQUIRE(pthread_condattr_init(&condattr)); + PTHREAD_REQUIRE(pthread_condattr_setclock(&condattr, CLOCK_REALTIME)); + PTHREAD_REQUIRE(pthread_condattr_getclock(&condattr, &clockid)); + ATF_REQUIRE_EQ(clockid, CLOCK_REALTIME); + + PTHREAD_REQUIRE(pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC)); + PTHREAD_REQUIRE(pthread_condattr_getclock(&condattr, &clockid)); + ATF_REQUIRE_EQ(clockid, CLOCK_MONOTONIC); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, signal_delay_wait); + ATF_TP_ADD_TC(tp, signal_before_unlock); + ATF_TP_ADD_TC(tp, signal_before_unlock_static_init); + ATF_TP_ADD_TC(tp, signal_wait_race); + ATF_TP_ADD_TC(tp, cond_timedwait_race); + ATF_TP_ADD_TC(tp, broadcast); + ATF_TP_ADD_TC(tp, bogus_timedwaits); + ATF_TP_ADD_TC(tp, destroy_after_cancel); + ATF_TP_ADD_TC(tp, condattr); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_condwait.c b/contrib/netbsd-tests/lib/libpthread/t_condwait.c new file mode 100644 index 0000000..58b4a8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_condwait.c @@ -0,0 +1,145 @@ +/* $NetBSD: t_condwait.c,v 1.5 2017/01/16 16:29:19 christos Exp $ */ + +/* + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_condwait.c,v 1.5 2017/01/16 16:29:19 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "isqemu.h" + +#include "h_common.h" + +#define WAITTIME 2 /* Timeout wait secound */ + +static const int debug = 1; + +static void * +run(void *param) +{ + struct timespec ts, to, te; + clockid_t clck; + pthread_condattr_t attr; + pthread_cond_t cond; + pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; + int ret = 0; + + + clck = *(clockid_t *)param; + PTHREAD_REQUIRE(pthread_condattr_init(&attr)); + PTHREAD_REQUIRE(pthread_condattr_setclock(&attr, clck)); + pthread_cond_init(&cond, &attr); + + ATF_REQUIRE_EQ((ret = pthread_mutex_lock(&m)), 0); + + ATF_REQUIRE_EQ(clock_gettime(clck, &ts), 0); + to = ts; + + if (debug) + printf("started: %lld.%09ld sec\n", (long long)to.tv_sec, + to.tv_nsec); + + ts.tv_sec += WAITTIME; /* Timeout wait */ + + switch (ret = pthread_cond_timedwait(&cond, &m, &ts)) { + case ETIMEDOUT: + /* Timeout */ + ATF_REQUIRE_EQ(clock_gettime(clck, &te), 0); + timespecsub(&te, &to, &to); + if (debug) { + printf("timeout: %lld.%09ld sec\n", + (long long)te.tv_sec, te.tv_nsec); + printf("elapsed: %lld.%09ld sec\n", + (long long)to.tv_sec, to.tv_nsec); + } + if (isQEMU()) { + double to_seconds = to.tv_sec + 1e-9 * to.tv_nsec; + ATF_REQUIRE(to_seconds >= WAITTIME * 0.9); + /* Loose upper limit because of qemu timing bugs */ + ATF_REQUIRE(to_seconds < WAITTIME * 2.5); + } else { + ATF_REQUIRE_EQ(to.tv_sec, WAITTIME); + } + break; + default: + ATF_REQUIRE_MSG(0, "pthread_cond_timedwait: %s", strerror(ret)); + } + + ATF_REQUIRE_MSG(!(ret = pthread_mutex_unlock(&m)), + "pthread_mutex_unlock: %s", strerror(ret)); + pthread_exit(&ret); +} + +static void +cond_wait(clockid_t clck, const char *msg) { + pthread_t child; + + if (debug) + printf( "**** %s clock wait starting\n", msg); + ATF_REQUIRE_EQ(pthread_create(&child, NULL, run, &clck), 0); + ATF_REQUIRE_EQ(pthread_join(child, NULL), 0); /* wait for terminate */ + if (debug) + printf( "**** %s clock wait ended\n", msg); +} + +ATF_TC(cond_wait_real); +ATF_TC_HEAD(cond_wait_real, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_cond_timedwait " + "with CLOCK_REALTIME"); +} + +ATF_TC_BODY(cond_wait_real, tc) { + cond_wait(CLOCK_REALTIME, "CLOCK_REALTIME"); +} + +ATF_TC(cond_wait_mono); +ATF_TC_HEAD(cond_wait_mono, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_cond_timedwait " + "with CLOCK_MONOTONIC"); +} + +ATF_TC_BODY(cond_wait_mono, tc) { + cond_wait(CLOCK_MONOTONIC, "CLOCK_MONOTONIC"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, cond_wait_real); + ATF_TP_ADD_TC(tp, cond_wait_mono); + return 0; +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_detach.c b/contrib/netbsd-tests/lib/libpthread/t_detach.c new file mode 100644 index 0000000..b30cb02 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_detach.c @@ -0,0 +1,96 @@ +/* $NetBSD: t_detach.c,v 1.2 2017/01/16 16:29:54 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_detach.c,v 1.2 2017/01/16 16:29:54 christos Exp $"); + +#include +#include +#include + +#include + +#include "h_common.h" + +static void *func(void *); + +static void * +func(void *arg) +{ + sleep(2); + return NULL; +} + +ATF_TC(pthread_detach); +ATF_TC_HEAD(pthread_detach, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of pthread_detach(3)"); +} + +ATF_TC_BODY(pthread_detach, tc) +{ + const int state = PTHREAD_CREATE_JOINABLE; + pthread_attr_t attr; + pthread_t t; + int rv; + + /* + * Create a joinable thread. + */ + PTHREAD_REQUIRE(pthread_attr_init(&attr)); + PTHREAD_REQUIRE(pthread_attr_setdetachstate(&attr, state)); + PTHREAD_REQUIRE(pthread_create(&t, &attr, func, NULL)); + + /* + * Detach the thread and try to + * join it; EINVAL should follow. + */ + PTHREAD_REQUIRE(pthread_detach(t)); + + sleep(1); + rv = pthread_join(t, NULL); + ATF_REQUIRE(rv == EINVAL); + + sleep(3); + + /* + * As usual, ESRCH should follow if + * we try to detach an invalid thread. + */ + rv = pthread_cancel(t); + ATF_REQUIRE(rv == ESRCH); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pthread_detach); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_equal.c b/contrib/netbsd-tests/lib/libpthread/t_equal.c new file mode 100644 index 0000000..bcda996 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_equal.c @@ -0,0 +1,74 @@ +/* $NetBSD: t_equal.c,v 1.1 2011/03/24 12:40:59 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_equal.c,v 1.1 2011/03/24 12:40:59 jruoho Exp $"); + +#include + +#include + +#include "h_common.h" + +static void *func(void *); + +static void * +func(void *arg) +{ + return NULL; +} + +ATF_TC(pthread_equal); +ATF_TC_HEAD(pthread_equal, tc) +{ + atf_tc_set_md_var(tc, "descr", "A test of pthread_equal(3)"); +} + +ATF_TC_BODY(pthread_equal, tc) +{ + pthread_t t1, t2; + + ATF_REQUIRE(pthread_create(&t1, NULL, func, NULL) == 0); + ATF_REQUIRE(pthread_create(&t2, NULL, func, NULL) == 0); + + ATF_REQUIRE(pthread_equal(t1, t1) != 0); + ATF_REQUIRE(pthread_equal(t2, t2) != 0); + ATF_REQUIRE(pthread_equal(t1, t2) == 0); + + ATF_REQUIRE(pthread_join(t1, NULL) == 0); + ATF_REQUIRE(pthread_join(t2, NULL) == 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, pthread_equal); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_exit.sh b/contrib/netbsd-tests/lib/libpthread/t_exit.sh new file mode 100755 index 0000000..7fbd689 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_exit.sh @@ -0,0 +1,41 @@ +# $NetBSD: t_exit.sh,v 1.1 2010/07/16 15:42:53 jmmv Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case main_thread +main_thread_head() +{ + atf_set "descr" "Checks calling pthread_exit() in the main thread" +} +main_thread_body() +{ + atf_check -o ignore "$(atf_get_srcdir)/h_exit" +} + +atf_init_test_cases() +{ + atf_add_test_case main_thread +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_fork.c b/contrib/netbsd-tests/lib/libpthread/t_fork.c new file mode 100644 index 0000000..936c7de --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_fork.c @@ -0,0 +1,107 @@ +/* $NetBSD: t_fork.c,v 1.2 2017/01/16 16:28:27 christos Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_fork.c,v 1.2 2017/01/16 16:28:27 christos Exp $"); + +/* + * Written by Love H�rnquist �strand , March 2003. + * Public domain. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_common.h" + +static pid_t parent; +static int thread_survived = 0; + +static void * +print_pid(void *arg) +{ + sleep(3); + + thread_survived = 1; + if (parent != getpid()) { + _exit(1); + } + return NULL; +} + +ATF_TC(fork); +ATF_TC_HEAD(fork, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that child process doesn't get threads"); +} +ATF_TC_BODY(fork, tc) +{ + pthread_t p; + pid_t fork_pid; + + parent = getpid(); + + PTHREAD_REQUIRE(pthread_create(&p, NULL, print_pid, NULL)); + + fork_pid = fork(); + ATF_REQUIRE(fork_pid != -1); + + if (fork_pid) { + int status; + + PTHREAD_REQUIRE(pthread_join(p, NULL)); + ATF_REQUIRE_MSG(thread_survived, "thread did not survive in parent"); + + waitpid(fork_pid, &status, 0); + ATF_REQUIRE_MSG(WIFEXITED(status), "child died wrongly"); + ATF_REQUIRE_EQ_MSG(WEXITSTATUS(status), 0, "thread survived in child"); + } else { + sleep(5); + _exit(thread_survived ? 1 : 0); + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, fork); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_fpu.c b/contrib/netbsd-tests/lib/libpthread/t_fpu.c new file mode 100644 index 0000000..dd47fb8 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_fpu.c @@ -0,0 +1,152 @@ +/* $NetBSD: t_fpu.c,v 1.3 2017/01/16 16:27:43 christos Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_fpu.c,v 1.3 2017/01/16 16:27:43 christos Exp $"); + +/* + * This is adapted from part of csw/cstest of the MPD implementation by + * the University of Arizona CS department (http://www.cs.arizona.edu/sr/) + * which is in the public domain: + * + * "The MPD system is in the public domain and you may use and distribute it + * as you wish. We ask that you retain credits referencing the University + * of Arizona and that you identify any changes you make. + * + * We can't provide a warranty with MPD; it's up to you to determine its + * suitability and reliability for your needs. We would like to hear of + * any problems you encounter but we cannot promise a timely correction." + * + * It was changed to use pthread_create() and sched_yield() instead of + * the internal MPD context switching primitives by Ignatios Souvatzis + * . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_common.h" + +#define N_RECURSE 10 + +static void recurse(void); + +int recursion_depth = 0; +pthread_mutex_t recursion_depth_lock; + +static void * +stir(void *p) +{ + double *q = (double *)p; + double x = *q++; + double y = *q++; + double z = *q++; + + for (;;) { + x = sin ((y = cos (x + y + .4)) - (z = cos (x + z + .6))); + ATF_REQUIRE_MSG(sched_yield() == 0, + "sched_yield failed: %s", strerror(errno)); + } +} + +static double +mul3(double x, double y, double z) +{ + ATF_REQUIRE_MSG(sched_yield() == 0, + "sched_yield failed: %s", strerror(errno)); + + return x * y * z; +} + +static void * +bar(void *p) +{ + double d; + int rc; + + d = mul3(mul3(2., 3., 5.), mul3(7., 11., 13.), mul3(17., 19., 23.)); + ATF_REQUIRE_EQ(d, 223092870.); + + PTHREAD_REQUIRE(pthread_mutex_lock(&recursion_depth_lock)); + rc = recursion_depth++; + PTHREAD_REQUIRE(pthread_mutex_unlock(&recursion_depth_lock)); + + if (rc < N_RECURSE) + recurse(); + else + atf_tc_pass(); + + /* NOTREACHED */ + return NULL; +} + +static void +recurse(void) { + pthread_t s2; + PTHREAD_REQUIRE(pthread_create(&s2, 0, bar, 0)); + sleep(20); /* XXX must be long enough for our slowest machine */ +} + +ATF_TC(fpu); +ATF_TC_HEAD(fpu, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks that thread context switches will leave the " + "floating point computations unharmed"); +} +ATF_TC_BODY(fpu, tc) +{ + double stirseed[] = { 1.7, 3.2, 2.4 }; + pthread_t s5; + + printf("Testing threaded floating point computations...\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&recursion_depth_lock, 0)); + + PTHREAD_REQUIRE(pthread_create(&s5, 0, stir, stirseed)); + recurse(); + + atf_tc_fail("exiting from main"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, fpu); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_join.c b/contrib/netbsd-tests/lib/libpthread/t_join.c new file mode 100644 index 0000000..1c57910 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_join.c @@ -0,0 +1,177 @@ +/* $NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $"); + +#include +#include +#include + +#include + +#include "h_common.h" + +#ifdef CHECK_STACK_ALIGNMENT +extern int check_stack_alignment(void); +#endif + +#define STACKSIZE 65536 + +static bool error; + +static void *threadfunc1(void *); +static void *threadfunc2(void *); + +ATF_TC(pthread_join); +ATF_TC_HEAD(pthread_join, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Checks basic error conditions in pthread_join(3)"); +} + +ATF_TC_BODY(pthread_join, tc) +{ + pthread_t thread; + + PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc1, NULL)); + PTHREAD_REQUIRE(pthread_join(thread, NULL)); +} + +static void * +threadfunc1(void *arg) +{ + pthread_t thread[25]; + pthread_t caller; + void *val = NULL; + uintptr_t i; + int rv; + pthread_attr_t attr; + + caller = pthread_self(); + +#ifdef CHECK_STACK_ALIGNMENT + /* + * Check alignment of thread stack, if supported. + */ + ATF_REQUIRE(check_stack_alignment()); +#endif + + /* + * The behavior is undefined, but should error + * out, if we try to join the calling thread. + */ + rv = pthread_join(caller, NULL); + + /* + * The specification recommends EDEADLK. + */ + ATF_REQUIRE(rv != 0); + ATF_REQUIRE_EQ(rv, EDEADLK); + + ATF_REQUIRE(pthread_attr_init(&attr) == 0); + + for (i = 0; i < __arraycount(thread); i++) { + + error = true; + + ATF_REQUIRE(pthread_attr_setstacksize(&attr, STACKSIZE * (i + 1)) == 0); + + rv = pthread_create(&thread[i], &attr, threadfunc2, (void *)i); + + ATF_REQUIRE_EQ(rv, 0); + + /* + * Check join and exit condition. + */ + PTHREAD_REQUIRE(pthread_join(thread[i], &val)); + + ATF_REQUIRE_EQ(error, false); + + ATF_REQUIRE(val != NULL); + ATF_REQUIRE(val == (void *)(i + 1)); + + /* + * Once the thread has returned, ESRCH should + * again follow if we try to join it again. + */ + rv = pthread_join(thread[i], NULL); + + ATF_REQUIRE_EQ(rv, ESRCH); + + /* + * Try to detach the exited thread. + */ + rv = pthread_detach(thread[i]); + + ATF_REQUIRE(rv != 0); + } + + ATF_REQUIRE(pthread_attr_destroy(&attr) == 0); + + pthread_exit(NULL); + + return NULL; +} + +static void * +threadfunc2(void *arg) +{ + static uintptr_t i = 0; + uintptr_t j; + pthread_attr_t attr; + size_t stacksize; + + j = (uintptr_t)arg; + +#ifdef __FreeBSD__ + pthread_attr_init(&attr); +#endif + ATF_REQUIRE(pthread_attr_get_np(pthread_self(), &attr) == 0); + ATF_REQUIRE(pthread_attr_getstacksize(&attr, &stacksize) == 0); + ATF_REQUIRE(stacksize == STACKSIZE * (j + 1)); + ATF_REQUIRE(pthread_attr_destroy(&attr) == 0); + + if (i++ == j) + error = false; + + pthread_exit((void *)i); + + return NULL; +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pthread_join); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_kill.c b/contrib/netbsd-tests/lib/libpthread/t_kill.c new file mode 100644 index 0000000..2fcdd99 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_kill.c @@ -0,0 +1,147 @@ +/* $NetBSD: t_kill.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c)2004 YAMAMOTO Takashi, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_kill.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include +#include +#include +#include +#include + +#include + +#include "h_common.h" + +#define NTHREAD 2 + +struct threadinfo { + pthread_t id; + sig_atomic_t gotsignal; +} th[NTHREAD]; + +pthread_t mainthread; + +static void +sighandler(int signo) +{ + pthread_t self; + int i; + + self = pthread_self(); + ATF_REQUIRE_MSG((self != mainthread) && (signo == SIGUSR1), + "unexpected signal"); + + for (i = 0; i < NTHREAD; i++) + if (self == th[i].id) + break; + + ATF_REQUIRE_MSG(i != NTHREAD, "unknown thread"); + + th[i].gotsignal++; +} + +static void * +f(void *arg) +{ + struct threadinfo volatile *t = arg; + + while (t->gotsignal < 1) { + /* busy loop */ + } + + return NULL; +} + +ATF_TC(simple); +ATF_TC_HEAD(simple, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_kill()"); +} +ATF_TC_BODY(simple, tc) +{ + int i; + pthread_t self; + + mainthread = pthread_self(); + + ATF_REQUIRE(signal(SIGUSR1, sighandler) != SIG_ERR); + + for (i = 0; i < NTHREAD; i++) { + PTHREAD_REQUIRE(pthread_create(&th[i].id, NULL, f, &th[i])); + } + + sched_yield(); + + self = pthread_self(); + ATF_REQUIRE_EQ_MSG(self, mainthread, "thread id changed"); + + for (i = 0; i < NTHREAD; i++) { + PTHREAD_REQUIRE(pthread_kill(th[i].id, SIGUSR1)); + } + + for (i = 0; i < NTHREAD; i++) { + PTHREAD_REQUIRE(pthread_join(th[i].id, NULL)); + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, simple); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_mutex.c b/contrib/netbsd-tests/lib/libpthread/t_mutex.c new file mode 100644 index 0000000..bcb8540 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_mutex.c @@ -0,0 +1,747 @@ +/* $NetBSD: t_mutex.c,v 1.15 2017/01/16 16:23:41 christos Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_mutex.c,v 1.15 2017/01/16 16:23:41 christos Exp $"); + +#include /* For timespecadd */ +#include /* For UINT16_MAX */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_common.h" + +static pthread_mutex_t mutex; +static pthread_mutex_t static_mutex = PTHREAD_MUTEX_INITIALIZER; +static int global_x; + +#ifdef TIMEDMUTEX +/* This code is used for verifying non-timed specific code */ +static struct timespec ts_lengthy = { + .tv_sec = UINT16_MAX, + .tv_nsec = 0 +}; +/* This code is used for verifying timed-only specific code */ +static struct timespec ts_shortlived = { + .tv_sec = 0, + .tv_nsec = 120 +}; + +static int +mutex_lock(pthread_mutex_t *m, const struct timespec *ts) +{ + struct timespec ts_wait; + ATF_REQUIRE(clock_gettime(CLOCK_REALTIME, &ts_wait) != -1); + timespecadd(&ts_wait, ts, &ts_wait); + + return pthread_mutex_timedlock(m, &ts_wait); +} +#else +#define mutex_lock(a, b) pthread_mutex_lock(a) +#endif + +static void * +mutex1_threadfunc(void *arg) +{ + int *param; + + printf("2: Second thread.\n"); + + param = arg; + printf("2: Locking mutex\n"); + mutex_lock(&mutex, &ts_lengthy); + printf("2: Got mutex. *param = %d\n", *param); + ATF_REQUIRE_EQ(*param, 20); + (*param)++; + + pthread_mutex_unlock(&mutex); + + return param; +} + +ATF_TC(mutex1); +ATF_TC_HEAD(mutex1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mutexes"); +} +ATF_TC_BODY(mutex1, tc) +{ + int x; + pthread_t new; + void *joinval; + + printf("1: Mutex-test 1\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + x = 1; + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex1_threadfunc, &x)); + printf("1: Before changing the value.\n"); + sleep(2); + x = 20; + printf("1: Before releasing the mutex.\n"); + sleep(2); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + printf("1: After releasing the mutex.\n"); + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + printf("1: Thread joined. X was %d. Return value (int) was %d\n", + x, *(int *)joinval); + ATF_REQUIRE_EQ(x, 21); + ATF_REQUIRE_EQ(*(int *)joinval, 21); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); +} + +static void * +mutex2_threadfunc(void *arg) +{ + long count = *(int *)arg; + + printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count); + + while (count--) { + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + global_x++; + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + } + + return (void *)count; +} + +ATF_TC(mutex2); +ATF_TC_HEAD(mutex2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mutexes"); +#ifdef __NetBSD__ +#if defined(__powerpc__) + atf_tc_set_md_var(tc, "timeout", "40"); +#endif +#endif +} +ATF_TC_BODY(mutex2, tc) +{ + int count, count2; + pthread_t new; + void *joinval; + + printf("1: Mutex-test 2\n"); + +#ifdef __NetBSD__ +#if defined(__powerpc__) + atf_tc_expect_timeout("PR port-powerpc/44387"); +#endif +#endif + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + + global_x = 0; + count = count2 = 10000000; + + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex2_threadfunc, &count2)); + + printf("1: Thread %p\n", pthread_self()); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + while (count--) { + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + global_x++; + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + } + + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + printf("1: Thread joined. X was %d. Return value (long) was %ld\n", + global_x, (long)joinval); + ATF_REQUIRE_EQ(global_x, 20000000); + +#ifdef __NetBSD__ +#if defined(__powerpc__) + /* XXX force a timeout in ppc case since an un-triggered race + otherwise looks like a "failure" */ + /* We sleep for longer than the timeout to make ATF not + complain about unexpected success */ + sleep(41); +#endif +#endif +} + +static void * +mutex3_threadfunc(void *arg) +{ + long count = *(int *)arg; + + printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count); + + while (count--) { + PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy)); + global_x++; + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + } + + return (void *)count; +} + +ATF_TC(mutex3); +ATF_TC_HEAD(mutex3, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mutexes using a static " + "initializer"); +#ifdef __NetBSD__ +#if defined(__powerpc__) + atf_tc_set_md_var(tc, "timeout", "40"); +#endif +#endif +} +ATF_TC_BODY(mutex3, tc) +{ + int count, count2; + pthread_t new; + void *joinval; + + printf("1: Mutex-test 3\n"); + +#ifdef __NetBSD__ +#if defined(__powerpc__) + atf_tc_expect_timeout("PR port-powerpc/44387"); +#endif +#endif + + global_x = 0; + count = count2 = 10000000; + + PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy)); + PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex3_threadfunc, &count2)); + + printf("1: Thread %p\n", pthread_self()); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + + while (count--) { + PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy)); + global_x++; + PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex)); + } + + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + PTHREAD_REQUIRE(mutex_lock(&static_mutex, &ts_lengthy)); + printf("1: Thread joined. X was %d. Return value (long) was %ld\n", + global_x, (long)joinval); + ATF_REQUIRE_EQ(global_x, 20000000); + +#ifdef __NetBSD__ +#if defined(__powerpc__) + /* XXX force a timeout in ppc case since an un-triggered race + otherwise looks like a "failure" */ + /* We sleep for longer than the timeout to make ATF not + complain about unexpected success */ + sleep(41); +#endif +#endif +} + +static void * +mutex4_threadfunc(void *arg) +{ + int *param; + + printf("2: Second thread.\n"); + + param = arg; + printf("2: Locking mutex\n"); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + printf("2: Got mutex. *param = %d\n", *param); + (*param)++; + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + + return param; +} + +ATF_TC(mutex4); +ATF_TC_HEAD(mutex4, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mutexes"); +} +ATF_TC_BODY(mutex4, tc) +{ + int x; + pthread_t new; + pthread_mutexattr_t mattr; + void *joinval; + + printf("1: Mutex-test 4\n"); + + PTHREAD_REQUIRE(pthread_mutexattr_init(&mattr)); + PTHREAD_REQUIRE(pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE)); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, &mattr)); + + PTHREAD_REQUIRE(pthread_mutexattr_destroy(&mattr)); + + x = 1; + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex4_threadfunc, &x)); + + printf("1: Before recursively acquiring the mutex.\n"); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + + printf("1: Before releasing the mutex once.\n"); + sleep(2); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + printf("1: After releasing the mutex once.\n"); + + x = 20; + + printf("1: Before releasing the mutex twice.\n"); + sleep(2); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + printf("1: After releasing the mutex twice.\n"); + + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + printf("1: Thread joined. X was %d. Return value (int) was %d\n", + x, *(int *)joinval); + ATF_REQUIRE_EQ(x, 21); + ATF_REQUIRE_EQ(*(int *)joinval, 21); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); +} + +#ifdef __NetBSD__ +static pthread_mutexattr_t attr5; +static pthread_mutex_t mutex5; +static int min_fifo_prio, max_fifo_prio; + +static void * +child_func(void* arg) +{ + int res; + + printf("child is waiting\n"); + res = _sched_protect(-2); + ATF_REQUIRE_EQ_MSG(res, -1, "sched_protect returned %d", res); + ATF_REQUIRE_EQ(errno, ENOENT); + PTHREAD_REQUIRE(mutex_lock(&mutex5, &ts_lengthy)); + printf("child is owning resource\n"); + res = _sched_protect(-2); + ATF_REQUIRE_EQ(res, max_fifo_prio); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex5)); + printf("child is done\n"); + + return 0; +} + +ATF_TC(mutex5); +ATF_TC_HEAD(mutex5, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mutexes for priority setting"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(mutex5, tc) +{ + int res; + struct sched_param param; + pthread_t child; + + min_fifo_prio = sched_get_priority_min(SCHED_FIFO); + max_fifo_prio = sched_get_priority_max(SCHED_FIFO); + printf("min prio for FIFO = %d\n", min_fifo_prio); + param.sched_priority = min_fifo_prio; + + /* = 0 OTHER, 1 FIFO, 2 RR, -1 NONE */ + res = sched_setscheduler(getpid(), SCHED_FIFO, ¶m); + printf("previous policy used = %d\n", res); + + res = sched_getscheduler(getpid()); + ATF_REQUIRE_EQ_MSG(res, SCHED_FIFO, "sched %d != FIFO %d", res, + SCHED_FIFO); + + PTHREAD_REQUIRE(pthread_mutexattr_init(&attr5)); + PTHREAD_REQUIRE(pthread_mutexattr_setprotocol(&attr5, + PTHREAD_PRIO_PROTECT)); + PTHREAD_REQUIRE(pthread_mutexattr_setprioceiling(&attr5, + max_fifo_prio)); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex5, &attr5)); + PTHREAD_REQUIRE(mutex_lock(&mutex5, &ts_lengthy)); + printf("enter critical section for main\n"); + PTHREAD_REQUIRE(pthread_create(&child, NULL, child_func, NULL)); + printf("main starts to sleep\n"); + sleep(10); + printf("main completes\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex5)); + PTHREAD_REQUIRE(pthread_join(child, NULL)); +} + +static pthread_mutex_t mutex6; +static int start = 0; +static uintmax_t high_cnt = 0, low_cnt = 0, MAX_LOOP = 100000000; + +static void * +high_prio(void* arg) +{ + struct sched_param param; + int policy; + param.sched_priority = min_fifo_prio + 10; + pthread_t childid = pthread_self(); + + PTHREAD_REQUIRE(pthread_setschedparam(childid, 1, ¶m)); + PTHREAD_REQUIRE(pthread_getschedparam(childid, &policy, ¶m)); + printf("high protect = %d, prio = %d\n", + _sched_protect(-2), param.sched_priority); + ATF_REQUIRE_EQ(policy, 1); + printf("high prio = %d\n", param.sched_priority); + sleep(1); + long tmp = 0; + for (int i = 0; i < 20; i++) { + while (high_cnt < MAX_LOOP) { + tmp += (123456789 % 1234) * (987654321 % 54321); + high_cnt += 1; + } + high_cnt = 0; + sleep(1); + } + PTHREAD_REQUIRE(mutex_lock(&mutex6, &ts_lengthy)); + if (start == 0) start = 2; + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex6)); + + return 0; +} + +static void * +low_prio(void* arg) +{ + struct sched_param param; + int policy; + param.sched_priority = min_fifo_prio; + pthread_t childid = pthread_self(); + int res = _sched_protect(max_fifo_prio); + ATF_REQUIRE_EQ(res, 0); + PTHREAD_REQUIRE(pthread_setschedparam(childid, 1, ¶m)); + PTHREAD_REQUIRE(pthread_getschedparam(childid, &policy, ¶m)); + printf("low protect = %d, prio = %d\n", _sched_protect(-2), + param.sched_priority); + ATF_REQUIRE_EQ(policy, 1); + printf("low prio = %d\n", param.sched_priority); + sleep(1); + long tmp = 0; + for (int i = 0; i < 20; i++) { + while (low_cnt < MAX_LOOP) { + tmp += (123456789 % 1234) * (987654321 % 54321); + low_cnt += 1; + } + low_cnt = 0; + sleep(1); + } + PTHREAD_REQUIRE(mutex_lock(&mutex6, &ts_lengthy)); + if (start == 0) + start = 1; + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex6)); + + return 0; +} + +ATF_TC(mutex6); +ATF_TC_HEAD(mutex6, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks scheduling for priority ceiling"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +/* + * 1. main thread sets itself to be a realtime task and launched two tasks, + * one has higher priority and the other has lower priority. + * 2. each child thread(low and high priority thread) sets its scheduler and + * priority. + * 3. each child thread did several rounds of computation, after each round it + * sleep 1 second. + * 4. the child thread with low priority will call _sched_protect to increase + * its protect priority. + * 5. We verify the thread with low priority runs first. + * + * Why does it work? From the main thread, we launched the high + * priority thread first. This gives this thread the benefit of + * starting first. The low priority thread did not call _sched_protect(2). + * The high priority thread should finish the task first. After each + * round of computation, we call sleep, to put the task into the + * sleep queue, and wake up again after the timer expires. This + * gives the scheduler the chance to decide which task to run. So, + * the thread with real high priority will always block the thread + * with real low priority. + * + */ +ATF_TC_BODY(mutex6, tc) +{ + struct sched_param param; + int res; + pthread_t high, low; + + min_fifo_prio = sched_get_priority_min(SCHED_FIFO); + max_fifo_prio = sched_get_priority_max(SCHED_FIFO); + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + printf("min_fifo_prio = %d, max_fifo_info = %d\n", min_fifo_prio, + max_fifo_prio); + + param.sched_priority = min_fifo_prio; + res = sched_setscheduler(getpid(), SCHED_FIFO, ¶m); + printf("previous policy used = %d\n", res); + + res = sched_getscheduler(getpid()); + ATF_REQUIRE_EQ(res, 1); + PTHREAD_REQUIRE(pthread_create(&high, NULL, high_prio, NULL)); + PTHREAD_REQUIRE(pthread_create(&low, NULL, low_prio, NULL)); + sleep(5); + PTHREAD_REQUIRE(pthread_join(low, NULL)); + PTHREAD_REQUIRE(pthread_join(high, NULL)); + + ATF_REQUIRE_EQ(start, 1); +} +#endif + +ATF_TC(mutexattr1); +ATF_TC_HEAD(mutexattr1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mutexattr"); +} + +ATF_TC_BODY(mutexattr1, tc) +{ + pthread_mutexattr_t mattr; + int protocol, target; + + PTHREAD_REQUIRE(pthread_mutexattr_init(&mattr)); + + target = PTHREAD_PRIO_NONE; + PTHREAD_REQUIRE(pthread_mutexattr_setprotocol(&mattr, target)); + PTHREAD_REQUIRE(pthread_mutexattr_getprotocol(&mattr, &protocol)); + ATF_REQUIRE_EQ(protocol, target); + + /* + target = PTHREAD_PRIO_INHERIT; + PTHREAD_REQUIRE(pthread_mutexattr_setprotocol(&mattr, target)); + PTHREAD_REQUIRE(pthread_mutexattr_getprotocol(&mattr, &protocol)); + ATF_REQUIRE_EQ(protocol, target); + */ + + target = PTHREAD_PRIO_PROTECT; + PTHREAD_REQUIRE(pthread_mutexattr_setprotocol(&mattr, target)); + PTHREAD_REQUIRE(pthread_mutexattr_getprotocol(&mattr, &protocol)); + ATF_REQUIRE_EQ(protocol, target); +} + +ATF_TC(mutexattr2); +ATF_TC_HEAD(mutexattr2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks mutexattr"); +} + +ATF_TC_BODY(mutexattr2, tc) +{ + pthread_mutexattr_t mattr; + +#ifdef __FreeBSD__ + atf_tc_expect_fail("fails on i == 0 with: " + "pthread_mutexattr_setprioceiling(&mattr, i): Invalid argument " + "-- PR # 211802"); +#endif + + PTHREAD_REQUIRE(pthread_mutexattr_init(&mattr)); + int max_prio = sched_get_priority_max(SCHED_FIFO); + int min_prio = sched_get_priority_min(SCHED_FIFO); + for (int i = min_prio; i <= max_prio; i++) { + int prioceiling; + int protocol; + + PTHREAD_REQUIRE(pthread_mutexattr_getprotocol(&mattr, + &protocol)); + + printf("priority: %d\nprotocol: %d\n", i, protocol); + PTHREAD_REQUIRE(pthread_mutexattr_setprioceiling(&mattr, i)); + PTHREAD_REQUIRE(pthread_mutexattr_getprioceiling(&mattr, + &prioceiling)); + printf("prioceiling: %d\n", prioceiling); + ATF_REQUIRE_EQ(i, prioceiling); + } +} + +#ifdef TIMEDMUTEX +ATF_TC(timedmutex1); +ATF_TC_HEAD(timedmutex1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks timeout on selflock"); +} + +ATF_TC_BODY(timedmutex1, tc) +{ + + printf("Timed mutex-test 1\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + + printf("Before acquiring mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + printf("Before endeavor to reacquire timed-mutex (timeout expected)\n"); + PTHREAD_REQUIRE_STATUS(mutex_lock(&mutex, &ts_shortlived), + ETIMEDOUT); + + printf("Unlocking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); +} + +ATF_TC(timedmutex2); +ATF_TC_HEAD(timedmutex2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks timeout on selflock with timedlock"); +} + +ATF_TC_BODY(timedmutex2, tc) +{ + + printf("Timed mutex-test 2\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + + printf("Before acquiring mutex with timedlock\n"); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + + printf("Before endeavor to reacquire timed-mutex (timeout expected)\n"); + PTHREAD_REQUIRE_STATUS(mutex_lock(&mutex, &ts_shortlived), + ETIMEDOUT); + + printf("Unlocking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); +} + +ATF_TC(timedmutex3); +ATF_TC_HEAD(timedmutex3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks timeout on selflock in a new thread"); +} + +static void * +timedmtx_thrdfunc(void *arg) +{ + printf("Before endeavor to reacquire timed-mutex (timeout expected)\n"); + PTHREAD_REQUIRE_STATUS(mutex_lock(&mutex, &ts_shortlived), + ETIMEDOUT); + + return NULL; +} + +ATF_TC_BODY(timedmutex3, tc) +{ + pthread_t new; + + printf("Timed mutex-test 3\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + + printf("Before acquiring mutex with timedlock\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + printf("Before creating new thread\n"); + PTHREAD_REQUIRE(pthread_create(&new, NULL, timedmtx_thrdfunc, NULL)); + + printf("Before joining the mutex\n"); + PTHREAD_REQUIRE(pthread_join(new, NULL)); + + printf("Unlocking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); +} + +ATF_TC(timedmutex4); +ATF_TC_HEAD(timedmutex4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks timeout on selflock with timedlock in a new thread"); +} + +ATF_TC_BODY(timedmutex4, tc) +{ + pthread_t new; + + printf("Timed mutex-test 4\n"); + + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + + printf("Before acquiring mutex with timedlock\n"); + PTHREAD_REQUIRE(mutex_lock(&mutex, &ts_lengthy)); + + printf("Before creating new thread\n"); + PTHREAD_REQUIRE(pthread_create(&new, NULL, timedmtx_thrdfunc, NULL)); + + printf("Before joining the mutex\n"); + PTHREAD_REQUIRE(pthread_join(new, NULL)); + + printf("Unlocking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mutex1); + ATF_TP_ADD_TC(tp, mutex2); + ATF_TP_ADD_TC(tp, mutex3); + ATF_TP_ADD_TC(tp, mutex4); +#ifdef __NetBSD__ + ATF_TP_ADD_TC(tp, mutex5); + ATF_TP_ADD_TC(tp, mutex6); +#endif + ATF_TP_ADD_TC(tp, mutexattr1); + ATF_TP_ADD_TC(tp, mutexattr2); + +#ifdef TIMEDMUTEX + ATF_TP_ADD_TC(tp, timedmutex1); + ATF_TP_ADD_TC(tp, timedmutex2); + ATF_TP_ADD_TC(tp, timedmutex3); + ATF_TP_ADD_TC(tp, timedmutex4); +#endif + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_name.c b/contrib/netbsd-tests/lib/libpthread/t_name.c new file mode 100644 index 0000000..d17895e --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_name.c @@ -0,0 +1,103 @@ +/* $NetBSD: t_name.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_name.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include +#include +#include +#include +#include +#include + +#include + +#include "h_common.h" + +#define NAME_TOO_LONG "12345678901234567890123456789012" /* 32 chars */ +#define NAME_JUST_RIGHT "1234567890123456789012345678901" /* 31 chars */ + +#define CONST_NAME "xyzzy" +char non_const_name[] = CONST_NAME; + +static void * +threadfunc(void *arg) +{ + pthread_t self = pthread_self(); + char retname[32]; + + PTHREAD_REQUIRE(pthread_getname_np(self, retname, sizeof(retname))); + ATF_REQUIRE_STREQ(retname, NAME_JUST_RIGHT); + + PTHREAD_REQUIRE(pthread_setname_np(self, non_const_name, NULL)); + (void) memset(non_const_name, 0, sizeof(non_const_name)); + PTHREAD_REQUIRE(pthread_getname_np(self, retname, sizeof(retname))); + ATF_REQUIRE_STREQ(retname, CONST_NAME); + + return NULL; +} + +ATF_TC(name); +ATF_TC_HEAD(name, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks pthread_{,attr}_{get,set}name_np() API"); +} +ATF_TC_BODY(name, tc) +{ + pthread_t thr, self = pthread_self(); + pthread_attr_t attr; + char retname[32]; + + PTHREAD_REQUIRE(pthread_attr_init(&attr)); + PTHREAD_REQUIRE(pthread_attr_getname_np(&attr, retname, + sizeof(retname), NULL)); + ATF_REQUIRE_EQ(retname[0], '\0'); + ATF_REQUIRE_EQ(pthread_attr_setname_np(&attr, NAME_TOO_LONG, NULL), EINVAL); + PTHREAD_REQUIRE(pthread_attr_setname_np(&attr, "%s", + __UNCONST(NAME_JUST_RIGHT))); + + (void) strcpy(retname, "foo"); + PTHREAD_REQUIRE(pthread_getname_np(self, retname, sizeof(retname))); + ATF_REQUIRE_EQ(retname[0], '\0'); + + PTHREAD_REQUIRE(pthread_create(&thr, &attr, threadfunc, NULL)); + PTHREAD_REQUIRE(pthread_join(thr, NULL)); + + ATF_REQUIRE_EQ(pthread_getname_np(thr, retname, sizeof(retname)), ESRCH); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, name); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_once.c b/contrib/netbsd-tests/lib/libpthread/t_once.c new file mode 100644 index 0000000..e2f209b --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_once.c @@ -0,0 +1,199 @@ +/* $NetBSD: t_once.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_once.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#ifdef __FreeBSD__ +#include /* For itimer*, etc. */ +#endif +#include +#include +#include +#include + +#include + +#include "h_common.h" + +static pthread_once_t once = PTHREAD_ONCE_INIT; +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +static int x; + +#define NTHREADS 25 + +static void +ofunc(void) +{ + printf("Variable x has value %d\n", x); + x++; +} + +ATF_TC(once1); +ATF_TC_HEAD(once1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_once()"); +} +ATF_TC_BODY(once1, tc) +{ + + printf("1: Test 1 of pthread_once()\n"); + + PTHREAD_REQUIRE(pthread_once(&once, ofunc)); + PTHREAD_REQUIRE(pthread_once(&once, ofunc)); + + printf("1: X has value %d\n",x ); + ATF_REQUIRE_EQ(x, 1); +} + +static void +once2_ofunc(void) +{ + x++; + printf("ofunc: Variable x has value %d\n", x); + x++; +} + +static void * +once2_threadfunc(void *arg) +{ + int num; + + PTHREAD_REQUIRE(pthread_once(&once, once2_ofunc)); + + num = *(int *)arg; + printf("Thread %d sees x with value %d\n", num, x); + ATF_REQUIRE_EQ(x, 2); + + return NULL; +} + +ATF_TC(once2); +ATF_TC_HEAD(once2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_once()"); +} +ATF_TC_BODY(once2, tc) +{ + pthread_t threads[NTHREADS]; + int id[NTHREADS]; + int i; + + printf("1: Test 2 of pthread_once()\n"); + + for (i=0; i < NTHREADS; i++) { + id[i] = i; + PTHREAD_REQUIRE(pthread_create(&threads[i], NULL, once2_threadfunc, &id[i])); + } + + for (i=0; i < NTHREADS; i++) + PTHREAD_REQUIRE(pthread_join(threads[i], NULL)); + + printf("1: X has value %d\n",x ); + ATF_REQUIRE_EQ(x, 2); +} + +static void +once3_cleanup(void *m) +{ + pthread_mutex_t *mu = m; + + PTHREAD_REQUIRE(pthread_mutex_unlock(mu)); +} + +static void +once3_ofunc(void) +{ + pthread_testcancel(); +} + +static void * +once3_threadfunc(void *arg) +{ + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + pthread_cleanup_push(once3_cleanup, &mutex); + PTHREAD_REQUIRE(pthread_once(&once, once3_ofunc)); + pthread_cleanup_pop(1); + + return NULL; +} + +static void +handler(int sig, siginfo_t *info, void *ctx) +{ + atf_tc_fail("Signal handler was called; " + "main thread deadlocked in pthread_once()"); +} + +ATF_TC(once3); +ATF_TC_HEAD(once3, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_once()"); +} +ATF_TC_BODY(once3, tc) +{ + pthread_t thread; + struct sigaction act; + struct itimerval it; + printf("Test 3 of pthread_once() (test versus cancellation)\n"); + + act.sa_sigaction = handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + sigaction(SIGALRM, &act, NULL); + + timerclear(&it.it_value); + it.it_value.tv_usec = 500000; + timerclear(&it.it_interval); + setitimer(ITIMER_REAL, &it, NULL); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + PTHREAD_REQUIRE(pthread_create(&thread, NULL, once3_threadfunc, NULL)); + PTHREAD_REQUIRE(pthread_cancel(thread)); + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + PTHREAD_REQUIRE(pthread_join(thread, NULL)); + + PTHREAD_REQUIRE(pthread_once(&once, ofunc)); + + /* Cancel timer */ + timerclear(&it.it_value); + setitimer(ITIMER_REAL, &it, NULL); + + printf("Test succeeded\n"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, once1); + ATF_TP_ADD_TC(tp, once2); + ATF_TP_ADD_TC(tp, once3); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_preempt.c b/contrib/netbsd-tests/lib/libpthread/t_preempt.c new file mode 100644 index 0000000..7ec43b6 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_preempt.c @@ -0,0 +1,128 @@ +/* $NetBSD: t_preempt.c,v 1.2 2010/11/03 16:10:22 christos Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_preempt.c,v 1.2 2010/11/03 16:10:22 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_common.h" + +pthread_mutex_t mutex; +pthread_cond_t cond; +int started; + +#define HUGE_BUFFER 1<<20 +#define NTHREADS 1 + +static void * +threadfunc(void *arg) +{ + printf("2: Second thread.\n"); + + printf("2: Locking mutex\n"); + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + printf("2: Got mutex.\n"); + started++; + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + PTHREAD_REQUIRE(pthread_cond_signal(&cond)); + sleep(1); + + return NULL; +} + +ATF_TC(preempt1); +ATF_TC_HEAD(preempt1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks kernel preemption during a large uiomove"); +} +ATF_TC_BODY(preempt1, tc) +{ + int i; + ssize_t rv; + pthread_t new; + void *joinval; + + char *mem; + int fd; + + mem = malloc(HUGE_BUFFER); + ATF_REQUIRE_MSG(mem != NULL, "%s", strerror(errno)); + + fd = open("/dev/urandom", O_RDONLY, 0); + ATF_REQUIRE_MSG(fd != -1, "%s", strerror(errno)); + + printf("1: preempt test\n"); + + PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL)); + PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); + + PTHREAD_REQUIRE(pthread_mutex_lock(&mutex)); + + started = 0; + + for (i = 0; i < NTHREADS; i++) { + PTHREAD_REQUIRE(pthread_create(&new, NULL, threadfunc, NULL)); + } + + while (started < NTHREADS) { + PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex)); + } + + printf("1: Thread has started.\n"); + + PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex)); + printf("1: After releasing the mutex.\n"); + + rv = read(fd, mem, HUGE_BUFFER); + close(fd); + ATF_REQUIRE_EQ(rv, HUGE_BUFFER); + + PTHREAD_REQUIRE(pthread_join(new, &joinval)); + + printf("1: Thread joined.\n"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, preempt1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_resolv.sh b/contrib/netbsd-tests/lib/libpthread/t_resolv.sh new file mode 100755 index 0000000..847eadc --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_resolv.sh @@ -0,0 +1,42 @@ +# $NetBSD: t_resolv.sh,v 1.1 2010/07/16 15:42:53 jmmv Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case resolv +resolv_head() +{ + atf_set "descr" "Checks parallel name resolution" +} +resolv_body() +{ + "$(atf_get_srcdir)"/h_resolv -d -n 5 -h 5 \ + "$(atf_get_srcdir)"/d_mach || atf_fail "test failed" +} + +atf_init_test_cases() +{ + atf_add_test_case resolv +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_rwlock.c b/contrib/netbsd-tests/lib/libpthread/t_rwlock.c new file mode 100644 index 0000000..81f8c58 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_rwlock.c @@ -0,0 +1,141 @@ +/* $NetBSD: t_rwlock.c,v 1.2 2015/06/26 11:07:20 pooka Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c)2004 YAMAMOTO Takashi, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_rwlock.c,v 1.2 2015/06/26 11:07:20 pooka Exp $"); + +#include +#include +#include +#include + +#include + +#include "h_common.h" + +pthread_rwlock_t lk; + +struct timespec to; + +static pthread_rwlock_t static_rwlock = PTHREAD_RWLOCK_INITIALIZER; + +/* ARGSUSED */ +static void * +do_nothing(void *dummy) +{ + return NULL; +} + +ATF_TC(rwlock1); +ATF_TC_HEAD(rwlock1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks read/write locks"); +} +ATF_TC_BODY(rwlock1, tc) +{ + int error; + pthread_t t; + + PTHREAD_REQUIRE(pthread_create(&t, NULL, do_nothing, NULL)); + PTHREAD_REQUIRE(pthread_rwlock_init(&lk, NULL)); + PTHREAD_REQUIRE(pthread_rwlock_rdlock(&lk)); + PTHREAD_REQUIRE(pthread_rwlock_rdlock(&lk)); + PTHREAD_REQUIRE(pthread_rwlock_unlock(&lk)); + + ATF_REQUIRE_EQ(pthread_rwlock_trywrlock(&lk), EBUSY); + + ATF_REQUIRE_EQ_MSG(clock_gettime(CLOCK_REALTIME, &to), 0, + "%s", strerror(errno)); + to.tv_sec++; + error = pthread_rwlock_timedwrlock(&lk, &to); + ATF_REQUIRE_MSG(error == ETIMEDOUT || error == EDEADLK, + "%s", strerror(error)); + + PTHREAD_REQUIRE(pthread_rwlock_unlock(&lk)); + + ATF_REQUIRE_EQ_MSG(clock_gettime(CLOCK_REALTIME, &to), 0, + "%s", strerror(errno)); + to.tv_sec++; + PTHREAD_REQUIRE(pthread_rwlock_timedwrlock(&lk, &to)); + + ATF_REQUIRE_EQ_MSG(clock_gettime(CLOCK_REALTIME, &to), 0, + "%s", strerror(errno)); + to.tv_sec++; + error = pthread_rwlock_timedwrlock(&lk, &to); + ATF_REQUIRE_MSG(error == ETIMEDOUT || error == EDEADLK, + "%s", strerror(error)); +} + +ATF_TC(rwlock_static); +ATF_TC_HEAD(rwlock_static, tc) +{ + atf_tc_set_md_var(tc, "descr", "rwlock w/ static initializer"); +} +ATF_TC_BODY(rwlock_static, tc) +{ + + PTHREAD_REQUIRE(pthread_rwlock_rdlock(&static_rwlock)); + PTHREAD_REQUIRE(pthread_rwlock_unlock(&static_rwlock)); + PTHREAD_REQUIRE(pthread_rwlock_destroy(&static_rwlock)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, rwlock1); + ATF_TP_ADD_TC(tp, rwlock_static); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_sem.c b/contrib/netbsd-tests/lib/libpthread/t_sem.c new file mode 100644 index 0000000..3d15edd --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_sem.c @@ -0,0 +1,307 @@ +/* $NetBSD: t_sem.c,v 1.9 2017/01/16 16:22:22 christos Exp $ */ + +/* + * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c)2004 YAMAMOTO Takashi, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +/**************************************************************************** + * + * Copyright (C) 2000 Jason Evans . + * 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(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sem.c,v 1.9 2017/01/16 16:22:22 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_common.h" + +#define NTHREADS 10 + +#define _LIBC_R_ + +#define SEM_REQUIRE(x) \ + ATF_REQUIRE_EQ_MSG(x, 0, "%s", strerror(errno)) + +static sem_t sem; + +ATF_TC(named); +ATF_TC_HEAD(named, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks named semaphores"); +} +ATF_TC_BODY(named, tc) +{ + sem_t *semp; + + ATF_REQUIRE_MSG(-1 != sysconf(_SC_SEMAPHORES), "%s", strerror(errno)); + + printf("Test begin\n"); + + (void) sem_unlink("/foo"); + semp = sem_open("/foo", O_CREAT | O_EXCL, 0644, 0); + ATF_REQUIRE_MSG(semp != SEM_FAILED, "%s", strerror(errno)); + SEM_REQUIRE(sem_close(semp)); + SEM_REQUIRE(sem_unlink("/foo")); + + printf("Test end\n"); +} + +ATF_TC(unnamed); +ATF_TC_HEAD(unnamed, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks unnamed semaphores"); +} + +static void * +entry(void * a_arg) +{ + pthread_t self = pthread_self(); + sem_t *semp = (sem_t *) a_arg; + + printf("Thread %p waiting for semaphore...\n", self); + sem_wait(semp); + printf("Thread %p got semaphore\n", self); + + return NULL; +} + +ATF_TC_BODY(unnamed, tc) +{ + sem_t sem_a, sem_b; + pthread_t threads[NTHREADS]; + unsigned i, j; + int val; + + ATF_REQUIRE_MSG(-1 != sysconf(_SC_SEMAPHORES), "%s", strerror(errno)); + + printf("Test begin\n"); + + SEM_REQUIRE(sem_init(&sem_b, 0, 0)); + SEM_REQUIRE(sem_getvalue(&sem_b, &val)); + ATF_REQUIRE_EQ(0, val); + + SEM_REQUIRE(sem_post(&sem_b)); + SEM_REQUIRE(sem_getvalue(&sem_b, &val)); + ATF_REQUIRE_EQ(1, val); + + SEM_REQUIRE(sem_wait(&sem_b)); + ATF_REQUIRE_EQ(sem_trywait(&sem_b), -1); + ATF_REQUIRE_EQ(errno, EAGAIN); + SEM_REQUIRE(sem_post(&sem_b)); + SEM_REQUIRE(sem_trywait(&sem_b)); + SEM_REQUIRE(sem_post(&sem_b)); + SEM_REQUIRE(sem_wait(&sem_b)); + SEM_REQUIRE(sem_post(&sem_b)); + + SEM_REQUIRE(sem_destroy(&sem_b)); + + SEM_REQUIRE(sem_init(&sem_a, 0, 0)); + + for (j = 0; j < 2; j++) { + for (i = 0; i < NTHREADS; i++) { + PTHREAD_REQUIRE(pthread_create(&threads[i], NULL, + entry, (void *) &sem_a)); + } + + for (i = 0; i < NTHREADS; i++) { + usleep(10000); + printf("main loop %u: posting...\n", j+1); + SEM_REQUIRE(sem_post(&sem_a)); + } + + for (i = 0; i < NTHREADS; i++) { + PTHREAD_REQUIRE(pthread_join(threads[i], NULL)); + } + } + + SEM_REQUIRE(sem_destroy(&sem_a)); + + printf("Test end\n"); +} + +static void +sighandler(int signo) +{ + /* printf("signal %d\n", signo); */ + + ATF_REQUIRE_EQ_MSG(signo, SIGALRM, "unexpected signal"); + SEM_REQUIRE(sem_post(&sem)); +} + +static void +alarm_ms(const int ms) +{ + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = ms * 1000; + ATF_REQUIRE(setitimer(ITIMER_REAL, &timer, NULL) == 0); +} + +static void * +threadfunc(void *arg) +{ + int i, ret; + + printf("Entering loop\n"); + for (i = 0; i < 500; ) { + if ((i & 1) != 0) { + do { + ret = sem_wait(&sem); + } while (ret == -1 && errno == EINTR); + ATF_REQUIRE(ret == 0); + } else { + ret = sem_trywait(&sem); + if (ret == -1) { + ATF_REQUIRE(errno == EAGAIN); + continue; + } + } + printf("%s: %d\n", __func__, i); + alarm_ms(5); + i++; + } + + return NULL; +} + +static void +before_start_test(const bool use_pthread) +{ + pthread_t t; + + SEM_REQUIRE(sem_init(&sem, 0, 0)); + ATF_REQUIRE(SIG_ERR != signal(SIGALRM, sighandler)); + + alarm_ms(5); + + if (use_pthread) { + PTHREAD_REQUIRE(pthread_create(&t, NULL, threadfunc, NULL)); + PTHREAD_REQUIRE(pthread_join(t, NULL)); + } else { + threadfunc(NULL); + } +} + +ATF_TC(before_start_no_threads); +ATF_TC_HEAD(before_start_no_threads, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks using semaphores without any " + "thread running"); + atf_tc_set_md_var(tc, "timeout", "40"); +} +ATF_TC_BODY(before_start_no_threads, tc) +{ + before_start_test(false); +} + +ATF_TC(before_start_one_thread); +ATF_TC_HEAD(before_start_one_thread, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks using semaphores before " + "starting one thread"); + atf_tc_set_md_var(tc, "timeout", "40"); +} +ATF_TC_BODY(before_start_one_thread, tc) +{ + before_start_test(true); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, named); + ATF_TP_ADD_TC(tp, unnamed); + ATF_TP_ADD_TC(tp, before_start_no_threads); + ATF_TP_ADD_TC(tp, before_start_one_thread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_sigalarm.c b/contrib/netbsd-tests/lib/libpthread/t_sigalarm.c new file mode 100644 index 0000000..0a58c4e --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_sigalarm.c @@ -0,0 +1,107 @@ +/* $NetBSD: t_sigalarm.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sigalarm.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include +#include +#include +#include + +#include + +#include "h_common.h" + +int alarm_set; + +#ifdef SA_SIGINFO +static void +alarm_handler(int signo, siginfo_t *si, void *ctx) +{ + ATF_REQUIRE_EQ_MSG(si->si_signo, signo, "Received unexpected signal"); + alarm_set = 1; +} +#else +static void +alarm_handler(int signo) +{ + ATF_REQUIRE_EQ_MSG(SIGALRM, signo, "Received unexpected signal"); + alarm_set = 1; +} +#endif + +static void * +setup(void *dummy) +{ + struct sigaction sa; + sigset_t ss; +#ifdef SA_SIGINFO + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = alarm_handler; +#else + sa.sa_flags = 0; + sa.sa_handler = alarm_handler; +#endif + sigfillset(&ss); + sigprocmask(SIG_SETMASK, &ss, NULL); + sigemptyset(&sa.sa_mask); + sigaction(SIGALRM, &sa, NULL); + alarm(1); + + return NULL; +} + +ATF_TC(sigalarm); +ATF_TC_HEAD(sigalarm, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sigsuspend in libpthread when pthread lib is initialized"); +} +ATF_TC_BODY(sigalarm, tc) +{ + sigset_t set; + pthread_t self = pthread_self(); + + PTHREAD_REQUIRE(pthread_create(&self, NULL, setup, NULL)); + + sigemptyset(&set); + sigsuspend(&set); + alarm(0); + + ATF_REQUIRE(alarm_set); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, sigalarm); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_siglongjmp.c b/contrib/netbsd-tests/lib/libpthread/t_siglongjmp.c new file mode 100644 index 0000000..298879c --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_siglongjmp.c @@ -0,0 +1,109 @@ +/* $NetBSD: t_siglongjmp.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_siglongjmp.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +/* + * Regression test for siglongjmp out of a signal handler back into + * its thread. + * + * Written by Christian Limpach , December 2003. + * Public domain. + */ + +#include + +#include +#include +#include +#include + +#include + +#include "h_common.h" + +static sigjmp_buf env; + +static void * +thread(void *arg) +{ + return NULL; +} + +static void +handler(int sig, siginfo_t *info, void *ctx) +{ + siglongjmp(env, 1); +} + +ATF_TC(siglongjmp1); +ATF_TC_HEAD(siglongjmp1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks siglongjmp() out of a signal handler back into its thread"); +} +ATF_TC_BODY(siglongjmp1, tc) +{ + pthread_t t; + sigset_t nset; + struct rlimit rlim; + struct sigaction act; + + rlim.rlim_cur = rlim.rlim_max = 0; + (void)setrlimit(RLIMIT_CORE, &rlim); + + PTHREAD_REQUIRE(pthread_create(&t, NULL, thread, NULL)); + + sigemptyset(&nset); + sigaddset(&nset, SIGUSR1); + PTHREAD_REQUIRE(pthread_sigmask(SIG_SETMASK, &nset, NULL)); + + act.sa_sigaction = handler; + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask, SIGUSR2); + act.sa_flags = 0; + sigaction(SIGSEGV, &act, NULL); + + ATF_REQUIRE_EQ(sigsetjmp(env, 1), 0); + + PTHREAD_REQUIRE(pthread_sigmask(0, NULL, &nset)); + + ATF_REQUIRE_EQ_MSG(sigismember(&nset, SIGSEGV), 0, "SIGSEGV set"); + ATF_REQUIRE_EQ_MSG(sigismember(&nset, SIGUSR2), 0, "SIGUSR2 set"); + ATF_REQUIRE_MSG(sigismember(&nset, SIGUSR1), "SIGUSR1 not set"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, siglongjmp1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_sigmask.c b/contrib/netbsd-tests/lib/libpthread/t_sigmask.c new file mode 100644 index 0000000..69e0577 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_sigmask.c @@ -0,0 +1,261 @@ +/* $NetBSD: t_sigmask.c,v 1.3 2013/10/19 17:45:01 christos Exp $ */ + +/* + * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sigmask.c,v 1.3 2013/10/19 17:45:01 christos Exp $"); + +/* + * Regression test for pthread_sigmask when SA upcalls aren't started yet. + * + * Written by Christian Limpach , December 2003. + * Public domain. + */ + +#include +#include +#include +#include +#include + +#include + +#include + +#include "h_common.h" + +static volatile sig_atomic_t flag; +static volatile sig_atomic_t flag2; + +static volatile pthread_t thr_usr1; +static volatile pthread_t thr_usr2; + +static sig_atomic_t count = 0; + +ATF_TC(upcalls_not_started); +ATF_TC_HEAD(upcalls_not_started, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks pthread_sigmask when SA upcalls " + "aren't started yet"); +} +ATF_TC_BODY(upcalls_not_started, tc) +{ + sigset_t nset; + struct rlimit rlim; + + rlim.rlim_cur = rlim.rlim_max = 0; + (void) setrlimit(RLIMIT_CORE, &rlim); + + sigemptyset(&nset); + sigaddset(&nset, SIGFPE); + pthread_sigmask(SIG_BLOCK, &nset, NULL); + + kill(getpid(), SIGFPE); +} + +static void +upcalls_not_started_handler1(int sig, siginfo_t *info, void *ctx) +{ + + kill(getpid(), SIGUSR2); + /* + * If the mask is properly set, SIGUSR2 will not be handled + * until this handler returns. + */ + flag = 1; +} + +static void +upcalls_not_started_handler2(int sig, siginfo_t *info, void *ctx) +{ + if (flag == 1) + flag = 2; +} + +ATF_TC(before_threads); +ATF_TC_HEAD(before_threads, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that signal masks are respected " + "before threads are started"); +} +ATF_TC_BODY(before_threads, tc) +{ + struct sigaction act; + + act.sa_sigaction = upcalls_not_started_handler1; + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask, SIGUSR2); + act.sa_flags = SA_SIGINFO; + + ATF_REQUIRE_EQ(sigaction(SIGUSR1, &act, NULL), 0); + + act.sa_sigaction = upcalls_not_started_handler2; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + (void)sigaction(SIGUSR2, &act, NULL); + + kill(getpid(), SIGUSR1); + + ATF_REQUIRE_EQ(flag, 2); + printf("Success: Both handlers ran in order\n"); +} + +static void +respected_while_running_handler1(int sig, siginfo_t *info, void *ctx) +{ + + kill(getpid(), SIGUSR2); + /* + * If the mask is properly set, SIGUSR2 will not be handled + * by the current thread until this handler returns. + */ + flag = 1; + thr_usr1 = pthread_self(); +} + +static void +respected_while_running_handler2(int sig, siginfo_t *info, void *ctx) +{ + if (flag == 1) + flag = 2; + flag2 = 1; + thr_usr2 = pthread_self(); +} + +static void * +respected_while_running_threadroutine(void *arg) +{ + + kill(getpid(), SIGUSR1); + sleep(1); + + if (flag == 2) + printf("Success: Both handlers ran in order\n"); + else if (flag == 1 && flag2 == 1 && thr_usr1 != thr_usr2) + printf("Success: Handlers were invoked by different threads\n"); + else { + printf("Failure: flag=%d, flag2=%d, thr1=%p, thr2=%p\n", + (int)flag, (int)flag2, (void *)thr_usr1, (void *)thr_usr2); + atf_tc_fail("failure"); + } + + return NULL; +} + +ATF_TC(respected_while_running); +ATF_TC_HEAD(respected_while_running, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that signal masks are respected " + "while threads are running"); +} +ATF_TC_BODY(respected_while_running, tc) +{ + struct sigaction act; + pthread_t thread; + + act.sa_sigaction = respected_while_running_handler1; + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask, SIGUSR2); + act.sa_flags = SA_SIGINFO; + + ATF_REQUIRE_EQ(sigaction(SIGUSR1, &act, NULL), 0); + + act.sa_sigaction = respected_while_running_handler2; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + (void)sigaction(SIGUSR2, &act, NULL); + + PTHREAD_REQUIRE(pthread_create(&thread, NULL, + respected_while_running_threadroutine, NULL)); + PTHREAD_REQUIRE(pthread_join(thread, NULL)); +} + +static void +incorrect_mask_bug_handler(int sig) +{ + count++; +} + +static void * +incorrect_mask_bug_sleeper(void* arg) +{ + int i; + for (i = 0; i < 10; i++) + sleep(1); + + atf_tc_fail("sleeper"); +} + +ATF_TC(incorrect_mask_bug); +ATF_TC_HEAD(incorrect_mask_bug, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks for bug in libpthread where " + "incorrect signal mask was used"); +} +ATF_TC_BODY(incorrect_mask_bug, tc) +{ + pthread_t id; + struct sigaction act; + + act.sa_sigaction = NULL; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = incorrect_mask_bug_handler; + + ATF_REQUIRE_EQ_MSG(sigaction(SIGALRM, &act, NULL), 0, "%s", + strerror(errno)); + + sigaddset(&act.sa_mask, SIGALRM); + PTHREAD_REQUIRE(pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL)); + + PTHREAD_REQUIRE(pthread_create(&id, NULL, incorrect_mask_bug_sleeper, + NULL)); + sleep(1); + + sigemptyset(&act.sa_mask); + PTHREAD_REQUIRE(pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL)); + + for (;;) { + alarm(1); + if (select(1, NULL, NULL, NULL, NULL) == -1 && errno == EINTR) + if (count == 2) + return; + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, upcalls_not_started); + ATF_TP_ADD_TC(tp, before_threads); + ATF_TP_ADD_TC(tp, respected_while_running); + ATF_TP_ADD_TC(tp, incorrect_mask_bug); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_sigsuspend.c b/contrib/netbsd-tests/lib/libpthread/t_sigsuspend.c new file mode 100644 index 0000000..1179657 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_sigsuspend.c @@ -0,0 +1,90 @@ +/* $NetBSD: t_sigsuspend.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sigsuspend.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +/* + * Regression test for sigsuspend in libpthread when pthread lib isn't + * initialized. + * + * Written by Love FIXME strand , March 2003. + * Public domain. + */ + +#include +#include +#include + +#include + +int alarm_set; + +static void +alarm_handler(int signo) +{ + alarm_set = 1; +} + +ATF_TC(sigsuspend); +ATF_TC_HEAD(sigsuspend, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sigsuspend in libpthread when pthread lib isn't initialized"); +} +ATF_TC_BODY(sigsuspend, tc) +{ + struct sigaction sa; + sigset_t set; + + sa.sa_flags = 0; + sa.sa_handler = alarm_handler; + sigemptyset(&sa.sa_mask); + + sigaction(SIGALRM, &sa, NULL); + + alarm(1); + + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + + sigsuspend(&set); + + alarm(0); + + ATF_REQUIRE(alarm_set); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, sigsuspend); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_sleep.c b/contrib/netbsd-tests/lib/libpthread/t_sleep.c new file mode 100644 index 0000000..93a30e3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_sleep.c @@ -0,0 +1,104 @@ +/* $NetBSD: t_sleep.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sleep.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); + +#include + +#include +#include +#include +#include + +#include + +#include "h_common.h" + +#define LONGTIME 2000000000 + +static void * +threadfunc(void *arg) +{ + sleep(LONGTIME); + + return NULL; +} + +static void +handler(int sig) +{ + /* + * Nothing to do; invoking the handler is enough to interrupt + * the sleep. + */ +} + +ATF_TC(sleep1); +ATF_TC_HEAD(sleep1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks sleeping past the time when " + "time_t wraps"); +} +ATF_TC_BODY(sleep1, tc) +{ + pthread_t thread; + struct itimerval it; + struct sigaction act; + sigset_t mtsm; + + printf("Testing sleeps unreasonably far into the future.\n"); + + act.sa_handler = handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGALRM, &act, NULL); + + PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc, NULL)); + + /* make sure the signal is delivered to the child thread */ + sigemptyset(&mtsm); + sigaddset(&mtsm, SIGALRM); + PTHREAD_REQUIRE(pthread_sigmask(SIG_BLOCK, &mtsm, 0)); + + timerclear(&it.it_interval); + timerclear(&it.it_value); + it.it_value.tv_sec = 1; + setitimer(ITIMER_REAL, &it, NULL); + + PTHREAD_REQUIRE(pthread_join(thread, NULL)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, sleep1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c b/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c new file mode 100644 index 0000000..677c51f --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c @@ -0,0 +1,117 @@ +/* $NetBSD: t_swapcontext.c,v 1.3 2017/01/16 16:27:06 christos Exp $ */ + +/* + * Copyright (c) 2012 Emmanuel Dreyfus. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "h_common.h" + +#define STACKSIZE 65536 + +char stack[STACKSIZE]; +ucontext_t nctx; +ucontext_t octx; +void *oself; +void *nself; +int val1, val2; + +/* ARGSUSED0 */ +static void +swapfunc(void *arg) +{ + /* + * If the test fails, we are very likely to crash + * without the opportunity to report + */ + nself = (void *)pthread_self(); + printf("after swapcontext self = %p\n", nself); + + ATF_REQUIRE_EQ(oself, nself); + printf("Test succeeded\n"); + /* Go back in main */ + ATF_REQUIRE(swapcontext(&nctx, &octx)); + + /* NOTREACHED */ + return; +} + +/* ARGSUSED0 */ +static void * +threadfunc(void *arg) +{ + nctx.uc_stack.ss_sp = stack; + nctx.uc_stack.ss_size = sizeof(stack); + + makecontext(&nctx, (void *)*swapfunc, 0); + + oself = (void *)pthread_self(); + printf("before swapcontext self = %p\n", oself); + ATF_REQUIRE_MSG(swapcontext(&octx, &nctx) != -1, "swapcontext failed: %s", + strerror(errno)); + + /* NOTREACHED */ + return NULL; +} + + +ATF_TC(swapcontext1); +ATF_TC_HEAD(swapcontext1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() " + "alters pthread_self()"); +} +ATF_TC_BODY(swapcontext1, tc) +{ + pthread_t thread; + + oself = (void *)&val1; + nself = (void *)&val2; + + printf("Testing if swapcontext() alters pthread_self()\n"); + + ATF_REQUIRE_MSG(getcontext(&nctx) != -1, "getcontext failed: %s", + strerror(errno)); + PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc, NULL)); + PTHREAD_REQUIRE(pthread_join(thread, NULL)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, swapcontext1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread/t_timedmutex.c b/contrib/netbsd-tests/lib/libpthread/t_timedmutex.c new file mode 100644 index 0000000..4f71acd --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread/t_timedmutex.c @@ -0,0 +1,30 @@ +/* $NetBSD: t_timedmutex.c,v 1.2 2016/10/31 16:21:23 christos Exp $ */ + +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#define TIMEDMUTEX +#include "t_mutex.c" diff --git a/contrib/netbsd-tests/lib/libpthread_dbg/h_common.h b/contrib/netbsd-tests/lib/libpthread_dbg/h_common.h new file mode 100644 index 0000000..0a02b96 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread_dbg/h_common.h @@ -0,0 +1,128 @@ +/* $NetBSD: h_common.h,v 1.2 2016/11/19 02:30:54 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + + +#ifndef H_COMMON_H +#define H_COMMON_H + +#include +#include +#include +#include + +#include + +#define PTHREAD_REQUIRE(x) \ + do { \ + int ret = (x); \ + ATF_REQUIRE_MSG(ret == 0, "%s: %s", #x, strerror(ret)); \ + } while (0) + +#define PTHREAD_REQUIRE_STATUS(x, v) \ + do { \ + int ret = (x); \ + ATF_REQUIRE_MSG(ret == (v), "%s: %s", #x, strerror(ret)); \ + } while (0) + +static int __used +dummy_proc_read(void *arg, caddr_t addr, void *buf, size_t size) +{ + return TD_ERR_ERR; +} + +static int __used +dummy_proc_write(void *arg, caddr_t addr, void *buf, size_t size) +{ + return TD_ERR_ERR; +} + +static int __used +dummy_proc_lookup(void *arg, const char *sym, caddr_t *addr) +{ + return TD_ERR_ERR; +} + +static int __used +dummy_proc_regsize(void *arg, int regset, size_t *size) +{ + return TD_ERR_ERR; +} + +static int __used +dummy_proc_getregs(void *arg, int regset, int lwp, void *buf) +{ + return TD_ERR_ERR; +} + +static int __used +dummy_proc_setregs(void *arg, int regset, int lwp, void *buf) +{ + return TD_ERR_ERR; +} + +/* Minimalistic basic implementation */ + +static int __used +basic_proc_read(void *arg, caddr_t addr, void *buf, size_t size) +{ + memcpy(buf, addr, size); + + return TD_ERR_OK; +} + +static int __used +basic_proc_write(void *arg, caddr_t addr, void *buf, size_t size) +{ + memcpy(addr, buf, size); + + return TD_ERR_OK; +} + +static int __used +basic_proc_lookup(void *arg, const char *sym, caddr_t *addr) +{ + void *handle; + void *symbol; + + ATF_REQUIRE_MSG((handle = dlopen(NULL, RTLD_LOCAL | RTLD_LAZY)) + != NULL, "dlopen(3) failed: %s", dlerror()); + + symbol = dlsym(handle, sym); + + ATF_REQUIRE_MSG(dlclose(handle) == 0, "dlclose(3) failed: %s", + dlerror()); + + if (!symbol) + return TD_ERR_NOSYM; + + *addr = (caddr_t)(uintptr_t)symbol; + + return TD_ERR_OK; +} + +#endif // H_COMMON_H diff --git a/contrib/netbsd-tests/lib/libpthread_dbg/t_dummy.c b/contrib/netbsd-tests/lib/libpthread_dbg/t_dummy.c new file mode 100644 index 0000000..367443c --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread_dbg/t_dummy.c @@ -0,0 +1,131 @@ +/* $NetBSD: t_dummy.c,v 1.6 2016/11/19 15:13:46 kamil Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_dummy.c,v 1.6 2016/11/19 15:13:46 kamil Exp $"); + +#include "h_common.h" +#include +#include + +#include + + +ATF_TC(dummy1); +ATF_TC_HEAD(dummy1, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Asserts that dummy lookup functions stop td_open() with failure"); +} + +ATF_TC_BODY(dummy1, tc) +{ + + struct td_proc_callbacks_t dummy_callbacks; + td_proc_t *main_ta; + + dummy_callbacks.proc_read = dummy_proc_read; + dummy_callbacks.proc_write = dummy_proc_write; + dummy_callbacks.proc_lookup = dummy_proc_lookup; + dummy_callbacks.proc_regsize = dummy_proc_regsize; + dummy_callbacks.proc_getregs = dummy_proc_getregs; + dummy_callbacks.proc_setregs = dummy_proc_setregs; + + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_ERR); +} + +ATF_TC(dummy2); +ATF_TC_HEAD(dummy2, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Asserts that td_open() for basic proc_{read,write,lookup} works"); +} + +ATF_TC_BODY(dummy2, tc) +{ + struct td_proc_callbacks_t dummy_callbacks; + td_proc_t *main_ta; + + dummy_callbacks.proc_read = basic_proc_read; + dummy_callbacks.proc_write = basic_proc_write; + dummy_callbacks.proc_lookup = basic_proc_lookup; + dummy_callbacks.proc_regsize = dummy_proc_regsize; + dummy_callbacks.proc_getregs = dummy_proc_getregs; + dummy_callbacks.proc_setregs = dummy_proc_setregs; + + printf("Calling td_open(3)\n"); + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); + + printf("Calling td_close(3)\n"); + ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); +} + +ATF_TC(dummy3); +ATF_TC_HEAD(dummy3, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Asserts that calling twice td_open() for the same process fails"); +} + +ATF_TC_BODY(dummy3, tc) +{ + struct td_proc_callbacks_t dummy_callbacks; + td_proc_t *main_ta1; + td_proc_t *main_ta2; + + dummy_callbacks.proc_read = basic_proc_read; + dummy_callbacks.proc_write = basic_proc_write; + dummy_callbacks.proc_lookup = basic_proc_lookup; + dummy_callbacks.proc_regsize = dummy_proc_regsize; + dummy_callbacks.proc_getregs = dummy_proc_getregs; + dummy_callbacks.proc_setregs = dummy_proc_setregs; + + printf("Calling td_open(3) for the first time - expecting success\n"); + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta1) == TD_ERR_OK); + + printf("Calling td_open(3) for the first time - expecting in-use\n"); + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta2) == + TD_ERR_INUSE); + + printf("Calling td_close(3) for the first successful call\n"); + ATF_REQUIRE(td_close(main_ta1) == TD_ERR_OK); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, dummy1); + ATF_TP_ADD_TC(tp, dummy2); + ATF_TP_ADD_TC(tp, dummy3); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libpthread_dbg/t_threads.c b/contrib/netbsd-tests/lib/libpthread_dbg/t_threads.c new file mode 100644 index 0000000..f22bbc9 --- /dev/null +++ b/contrib/netbsd-tests/lib/libpthread_dbg/t_threads.c @@ -0,0 +1,719 @@ +/* $NetBSD: t_threads.c,v 1.9 2017/01/13 05:18:22 christos Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_threads.c,v 1.9 2017/01/13 05:18:22 christos Exp $"); + +#include +#include +#include +#include +#include +#include + +#include + +#include "h_common.h" + +#define MAX_THREADS (size_t)10 + +ATF_TC(threads1); +ATF_TC_HEAD(threads1, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Asserts that td_thr_iter() call without extra logic works"); +} + +static volatile int exiting1; + +static void * +busyFunction1(void *arg) +{ + + while (exiting1 == 0) + usleep(50000); + + return NULL; +} + +static int +iterateThreads1(td_thread_t *thread, void *arg) +{ + + return TD_ERR_OK; +} + +ATF_TC_BODY(threads1, tc) +{ + struct td_proc_callbacks_t dummy_callbacks; + td_proc_t *main_ta; + size_t i; + pthread_t threads[MAX_THREADS]; + + dummy_callbacks.proc_read = basic_proc_read; + dummy_callbacks.proc_write = basic_proc_write; + dummy_callbacks.proc_lookup = basic_proc_lookup; + dummy_callbacks.proc_regsize = dummy_proc_regsize; + dummy_callbacks.proc_getregs = dummy_proc_getregs; + dummy_callbacks.proc_setregs = dummy_proc_setregs; + + for (i = 0; i < MAX_THREADS; i++) { + printf("Creating thread %zu\n", i); + PTHREAD_REQUIRE + (pthread_create(&threads[i], NULL, busyFunction1, NULL)); + } + + printf("Calling td_open(3)\n"); + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); + + ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads1, NULL) == TD_ERR_OK); + + exiting1 = 1; + + printf("Calling td_close(3)\n"); + ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); +} + +ATF_TC(threads2); +ATF_TC_HEAD(threads2, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Asserts that td_thr_iter() call is executed for each thread once"); +} + +static volatile int exiting2; + +static void * +busyFunction2(void *arg) +{ + + while (exiting2 == 0) + usleep(50000); + + return NULL; +} + +static int +iterateThreads2(td_thread_t *thread, void *arg) +{ + int *counter = (int *)arg; + + ++(*counter); + + return TD_ERR_OK; +} + +ATF_TC_BODY(threads2, tc) +{ + struct td_proc_callbacks_t dummy_callbacks; + td_proc_t *main_ta; + size_t i; + pthread_t threads[MAX_THREADS]; + int count = 0; + + dummy_callbacks.proc_read = basic_proc_read; + dummy_callbacks.proc_write = basic_proc_write; + dummy_callbacks.proc_lookup = basic_proc_lookup; + dummy_callbacks.proc_regsize = dummy_proc_regsize; + dummy_callbacks.proc_getregs = dummy_proc_getregs; + dummy_callbacks.proc_setregs = dummy_proc_setregs; + + + for (i = 0; i < MAX_THREADS; i++) { + printf("Creating thread %zu\n", i); + PTHREAD_REQUIRE + (pthread_create(&threads[i], NULL, busyFunction2, NULL)); + } + + printf("Calling td_open(3)\n"); + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); + + ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads2, &count) == TD_ERR_OK); + + exiting2 = 1; + + printf("Calling td_close(3)\n"); + ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); + + ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, + "counted threads (%d) != expected threads (%zu)", + count, MAX_THREADS + 1); +} + +ATF_TC(threads3); +ATF_TC_HEAD(threads3, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Asserts that for each td_thr_iter() call td_thr_info() is valid"); +} + +static volatile int exiting3; + +static void * +busyFunction3(void *arg) +{ + + while (exiting3 == 0) + usleep(50000); + + return NULL; +} + +static int +iterateThreads3(td_thread_t *thread, void *arg) +{ + int *counter = (int *)arg; + td_thread_info_t info; + + ATF_REQUIRE(td_thr_info(thread, &info) == TD_ERR_OK); + + ++(*counter); + + return TD_ERR_OK; +} + +ATF_TC_BODY(threads3, tc) +{ + struct td_proc_callbacks_t dummy_callbacks; + td_proc_t *main_ta; + size_t i; + pthread_t threads[MAX_THREADS]; + int count = 0; + + dummy_callbacks.proc_read = basic_proc_read; + dummy_callbacks.proc_write = basic_proc_write; + dummy_callbacks.proc_lookup = basic_proc_lookup; + dummy_callbacks.proc_regsize = dummy_proc_regsize; + dummy_callbacks.proc_getregs = dummy_proc_getregs; + dummy_callbacks.proc_setregs = dummy_proc_setregs; + + + for (i = 0; i < MAX_THREADS; i++) { + printf("Creating thread %zu\n", i); + PTHREAD_REQUIRE + (pthread_create(&threads[i], NULL, busyFunction3, NULL)); + } + + printf("Calling td_open(3)\n"); + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); + + ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads3, &count) == TD_ERR_OK); + + exiting3 = 1; + + printf("Calling td_close(3)\n"); + ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); + + ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, + "counted threads (%d) != expected threads (%zu)", + count, MAX_THREADS + 1); +} + +ATF_TC(threads4); +ATF_TC_HEAD(threads4, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Asserts that for each td_thr_iter() call td_thr_getname() is " + "valid"); +} + +static volatile int exiting4; + +static void * +busyFunction4(void *arg) +{ + + while (exiting4 == 0) + usleep(50000); + + return NULL; +} + +static int +iterateThreads4(td_thread_t *thread, void *arg) +{ + int *counter = (int *)arg; + char name[PTHREAD_MAX_NAMELEN_NP]; + + ATF_REQUIRE(td_thr_getname(thread, name, sizeof(name)) == TD_ERR_OK); + + printf("Thread name: %s\n", name); + + ++(*counter); + + return TD_ERR_OK; +} + +ATF_TC_BODY(threads4, tc) +{ + struct td_proc_callbacks_t dummy_callbacks; + td_proc_t *main_ta; + size_t i; + pthread_t threads[MAX_THREADS]; + int count = 0; + + dummy_callbacks.proc_read = basic_proc_read; + dummy_callbacks.proc_write = basic_proc_write; + dummy_callbacks.proc_lookup = basic_proc_lookup; + dummy_callbacks.proc_regsize = dummy_proc_regsize; + dummy_callbacks.proc_getregs = dummy_proc_getregs; + dummy_callbacks.proc_setregs = dummy_proc_setregs; + + for (i = 0; i < MAX_THREADS; i++) { + printf("Creating thread %zu\n", i); + PTHREAD_REQUIRE + (pthread_create(&threads[i], NULL, busyFunction4, NULL)); + } + + for (i = 0; i < MAX_THREADS; i++) { + PTHREAD_REQUIRE + (pthread_setname_np(threads[i], "test_%d", (void*)i)); + } + + printf("Calling td_open(3)\n"); + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); + + ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads4, &count) == TD_ERR_OK); + + exiting4 = 1; + + printf("Calling td_close(3)\n"); + ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); + + ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, + "counted threads (%d) != expected threads (%zu)", + count, MAX_THREADS + 1); +} + +ATF_TC(threads5); +ATF_TC_HEAD(threads5, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Asserts that td_thr_getname() handles shorter buffer parameter " + "and the result is properly truncated"); +} + +static volatile int exiting5; + +static void * +busyFunction5(void *arg) +{ + + while (exiting5 == 0) + usleep(50000); + + return NULL; +} + +static int +iterateThreads5(td_thread_t *thread, void *arg) +{ + int *counter = (int *)arg; + /* Arbitrarily short string buffer */ + char name[3]; + + ATF_REQUIRE(td_thr_getname(thread, name, sizeof(name)) == TD_ERR_OK); + + printf("Thread name: %s\n", name); + + /* strlen(3) does not count including a '\0' character */ + ATF_REQUIRE(strlen(name) < sizeof(name)); + + ++(*counter); + + return TD_ERR_OK; +} + +ATF_TC_BODY(threads5, tc) +{ + struct td_proc_callbacks_t dummy_callbacks; + td_proc_t *main_ta; + size_t i; + pthread_t threads[MAX_THREADS]; + int count = 0; + + dummy_callbacks.proc_read = basic_proc_read; + dummy_callbacks.proc_write = basic_proc_write; + dummy_callbacks.proc_lookup = basic_proc_lookup; + dummy_callbacks.proc_regsize = dummy_proc_regsize; + dummy_callbacks.proc_getregs = dummy_proc_getregs; + dummy_callbacks.proc_setregs = dummy_proc_setregs; + + for (i = 0; i < MAX_THREADS; i++) { + printf("Creating thread %zu\n", i); + PTHREAD_REQUIRE + (pthread_create(&threads[i], NULL, busyFunction5, NULL)); + } + + for (i = 0; i < MAX_THREADS; i++) { + PTHREAD_REQUIRE + (pthread_setname_np(threads[i], "test_%d", (void*)i)); + } + + printf("Calling td_open(3)\n"); + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); + + ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads5, &count) == TD_ERR_OK); + + exiting5 = 1; + + printf("Calling td_close(3)\n"); + ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); + + ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, + "counted threads (%d) != expected threads (%zu)", + count, MAX_THREADS + 1); +} + +ATF_TC(threads6); +ATF_TC_HEAD(threads6, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Asserts that pthread_t can be translated with td_map_pth2thr() " + "to td_thread_t -- and assert earlier that td_thr_iter() call is " + "valid"); +} + +static volatile int exiting6; + +static void * +busyFunction6(void *arg) +{ + + while (exiting6 == 0) + usleep(50000); + + return NULL; +} + +static int +iterateThreads6(td_thread_t *thread, void *arg) +{ + int *counter = (int *)arg; + + ++(*counter); + + return TD_ERR_OK; +} + +ATF_TC_BODY(threads6, tc) +{ + struct td_proc_callbacks_t dummy_callbacks; + td_proc_t *main_ta; + size_t i; + pthread_t threads[MAX_THREADS]; + int count = 0; + + dummy_callbacks.proc_read = basic_proc_read; + dummy_callbacks.proc_write = basic_proc_write; + dummy_callbacks.proc_lookup = basic_proc_lookup; + dummy_callbacks.proc_regsize = dummy_proc_regsize; + dummy_callbacks.proc_getregs = dummy_proc_getregs; + dummy_callbacks.proc_setregs = dummy_proc_setregs; + + for (i = 0; i < MAX_THREADS; i++) { + printf("Creating thread %zu\n", i); + PTHREAD_REQUIRE + (pthread_create(&threads[i], NULL, busyFunction6, NULL)); + } + + printf("Calling td_open(3)\n"); + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); + + ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads6, &count) == TD_ERR_OK); + + for (i = 0; i < MAX_THREADS; i++) { + td_thread_t *td_thread; + ATF_REQUIRE(td_map_pth2thr(main_ta, threads[i], &td_thread) + == TD_ERR_OK); + } + + exiting6 = 1; + + printf("Calling td_close(3)\n"); + ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); + + ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, + "counted threads (%d) != expected threads (%zu)", + count, MAX_THREADS + 1); +} + +ATF_TC(threads7); +ATF_TC_HEAD(threads7, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Asserts that pthread_t can be translated with td_map_pth2thr() " + "to td_thread_t -- and assert later that td_thr_iter() call is " + "valid"); +} + +static volatile int exiting7; + +static void * +busyFunction7(void *arg) +{ + + while (exiting7 == 0) + usleep(50000); + + return NULL; +} + +static int +iterateThreads7(td_thread_t *thread, void *arg) +{ + int *counter = (int *)arg; + + ++(*counter); + + return TD_ERR_OK; +} + +ATF_TC_BODY(threads7, tc) +{ + struct td_proc_callbacks_t dummy_callbacks; + td_proc_t *main_ta; + size_t i; + pthread_t threads[MAX_THREADS]; + int count = 0; + + dummy_callbacks.proc_read = basic_proc_read; + dummy_callbacks.proc_write = basic_proc_write; + dummy_callbacks.proc_lookup = basic_proc_lookup; + dummy_callbacks.proc_regsize = dummy_proc_regsize; + dummy_callbacks.proc_getregs = dummy_proc_getregs; + dummy_callbacks.proc_setregs = dummy_proc_setregs; + + for (i = 0; i < MAX_THREADS; i++) { + printf("Creating thread %zu\n", i); + PTHREAD_REQUIRE + (pthread_create(&threads[i], NULL, busyFunction7, NULL)); + } + + printf("Calling td_open(3)\n"); + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); + + for (i = 0; i < MAX_THREADS; i++) { + td_thread_t *td_thread; + ATF_REQUIRE(td_map_pth2thr(main_ta, threads[i], &td_thread) + == TD_ERR_OK); + } + + ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads7, &count) == TD_ERR_OK); + + exiting7 = 1; + + printf("Calling td_close(3)\n"); + ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); + + ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, + "counted threads (%d) != expected threads (%zu)", + count, MAX_THREADS + 1); +} + +ATF_TC(threads8); +ATF_TC_HEAD(threads8, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Asserts that pthread_t can be translated with td_map_pth2thr() " + "to td_thread_t -- compare thread's name of pthread_t and " + "td_thread_t"); +} + +static volatile int exiting8; + +static void * +busyFunction8(void *arg) +{ + + while (exiting8 == 0) + usleep(50000); + + return NULL; +} + +static int +iterateThreads8(td_thread_t *thread, void *arg) +{ + int *counter = (int *)arg; + + ++(*counter); + + return TD_ERR_OK; +} + +ATF_TC_BODY(threads8, tc) +{ + struct td_proc_callbacks_t dummy_callbacks; + td_proc_t *main_ta; + size_t i; + pthread_t threads[MAX_THREADS]; + int count = 0; + + dummy_callbacks.proc_read = basic_proc_read; + dummy_callbacks.proc_write = basic_proc_write; + dummy_callbacks.proc_lookup = basic_proc_lookup; + dummy_callbacks.proc_regsize = dummy_proc_regsize; + dummy_callbacks.proc_getregs = dummy_proc_getregs; + dummy_callbacks.proc_setregs = dummy_proc_setregs; + + for (i = 0; i < MAX_THREADS; i++) { + printf("Creating thread %zu\n", i); + PTHREAD_REQUIRE + (pthread_create(&threads[i], NULL, busyFunction8, NULL)); + } + + printf("Calling td_open(3)\n"); + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); + + ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads8, &count) == TD_ERR_OK); + + for (i = 0; i < MAX_THREADS; i++) { + td_thread_t *td_thread; + char td_threadname[PTHREAD_MAX_NAMELEN_NP]; + char pth_threadname[PTHREAD_MAX_NAMELEN_NP]; + ATF_REQUIRE(td_map_pth2thr(main_ta, threads[i], &td_thread) + == TD_ERR_OK); + ATF_REQUIRE(td_thr_getname(td_thread, td_threadname, + sizeof(td_threadname)) == TD_ERR_OK); + PTHREAD_REQUIRE(pthread_getname_np(threads[i], pth_threadname, + sizeof(pth_threadname))); + ATF_REQUIRE(strcmp(td_threadname, pth_threadname) == 0); + } + + exiting8 = 1; + + printf("Calling td_close(3)\n"); + ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); + + ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, + "counted threads (%d) != expected threads (%zu)", + count, MAX_THREADS + 1); +} + +ATF_TC(threads9); +ATF_TC_HEAD(threads9, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Asserts that pthread_t can be translated with td_map_pth2thr() " + "to td_thread_t -- assert that thread is in the TD_STATE_RUNNING " + "state"); +} + +static volatile int exiting9; + +static void * +busyFunction9(void *arg) +{ + + while (exiting9 == 0) + usleep(50000); + + return NULL; +} + +static int +iterateThreads9(td_thread_t *thread, void *arg) +{ + int *counter = (int *)arg; + + ++(*counter); + + return TD_ERR_OK; +} + +ATF_TC_BODY(threads9, tc) +{ + struct td_proc_callbacks_t dummy_callbacks; + td_proc_t *main_ta; + size_t i; + pthread_t threads[MAX_THREADS]; + int count = 0; + + dummy_callbacks.proc_read = basic_proc_read; + dummy_callbacks.proc_write = basic_proc_write; + dummy_callbacks.proc_lookup = basic_proc_lookup; + dummy_callbacks.proc_regsize = dummy_proc_regsize; + dummy_callbacks.proc_getregs = dummy_proc_getregs; + dummy_callbacks.proc_setregs = dummy_proc_setregs; + + for (i = 0; i < MAX_THREADS; i++) { + printf("Creating thread %zu\n", i); + PTHREAD_REQUIRE + (pthread_create(&threads[i], NULL, busyFunction9, NULL)); + } + + printf("Calling td_open(3)\n"); + ATF_REQUIRE(td_open(&dummy_callbacks, NULL, &main_ta) == TD_ERR_OK); + + for (i = 0; i < MAX_THREADS; i++) { + td_thread_t *td_thread; + td_thread_info_t info; + ATF_REQUIRE(td_map_pth2thr(main_ta, threads[i], &td_thread) + == TD_ERR_OK); + ATF_REQUIRE(td_thr_info(td_thread, &info) == TD_ERR_OK); + ATF_REQUIRE_EQ(info.thread_state, TD_STATE_RUNNING); + } + + ATF_REQUIRE(td_thr_iter(main_ta, iterateThreads9, &count) == TD_ERR_OK); + + exiting9 = 1; + + printf("Calling td_close(3)\n"); + ATF_REQUIRE(td_close(main_ta) == TD_ERR_OK); + + ATF_REQUIRE_EQ_MSG(count, MAX_THREADS + 1, + "counted threads (%d) != expected threads (%zu)", + count, MAX_THREADS + 1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, threads1); + ATF_TP_ADD_TC(tp, threads2); + ATF_TP_ADD_TC(tp, threads3); + ATF_TP_ADD_TC(tp, threads4); + ATF_TP_ADD_TC(tp, threads5); + ATF_TP_ADD_TC(tp, threads6); + ATF_TP_ADD_TC(tp, threads7); + ATF_TP_ADD_TC(tp, threads8); + ATF_TP_ADD_TC(tp, threads9); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/librefuse/t_refuse_opt.c b/contrib/netbsd-tests/lib/librefuse/t_refuse_opt.c new file mode 100644 index 0000000..23c2803 --- /dev/null +++ b/contrib/netbsd-tests/lib/librefuse/t_refuse_opt.c @@ -0,0 +1,418 @@ +/* $NetBSD: t_refuse_opt.c,v 1.8 2017/01/13 21:30:41 christos Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_refuse_opt.c,v 1.8 2017/01/13 21:30:41 christos Exp $"); + +#define _KERNTYPES +#include + +#include + +#include + +#include "h_macros.h" + +ATF_TC(t_fuse_opt_add_arg); +ATF_TC_HEAD(t_fuse_opt_add_arg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_add_arg(3) works"); +} + +ATF_TC_BODY(t_fuse_opt_add_arg, tc) +{ + struct fuse_args args = FUSE_ARGS_INIT(0, NULL); + + RZ(fuse_opt_add_arg(&args, "foo")); + RZ(fuse_opt_add_arg(&args, "bar")); + + ATF_REQUIRE_EQ(args.argc, 2); + ATF_CHECK_STREQ(args.argv[0], "foo"); + ATF_CHECK_STREQ(args.argv[1], "bar"); + ATF_CHECK(args.allocated != 0); +} + +ATF_TC(t_fuse_opt_insert_arg); +ATF_TC_HEAD(t_fuse_opt_insert_arg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_insert_arg(3) works"); +} + +ATF_TC_BODY(t_fuse_opt_insert_arg, tc) +{ + struct fuse_args args = FUSE_ARGS_INIT(0, NULL); + + RZ(fuse_opt_insert_arg(&args, 0, "foo")); + RZ(fuse_opt_insert_arg(&args, 0, "bar")); + + ATF_REQUIRE_EQ(args.argc, 2); + ATF_CHECK_STREQ(args.argv[0], "bar"); + ATF_CHECK_STREQ(args.argv[1], "foo"); + ATF_CHECK(args.allocated != 0); +} + +ATF_TC(t_fuse_opt_add_opt); +ATF_TC_HEAD(t_fuse_opt_add_opt, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_add_opt(3) works"); +} + +ATF_TC_BODY(t_fuse_opt_add_opt, tc) +{ + char* opt = NULL; + + RZ(fuse_opt_add_opt(&opt, "fo\\o")); + ATF_CHECK_STREQ(opt, "fo\\o"); + + RZ(fuse_opt_add_opt(&opt, "ba,r")); + ATF_CHECK_STREQ(opt, "fo\\o,ba,r"); +} + +ATF_TC(t_fuse_opt_add_opt_escaped); +ATF_TC_HEAD(t_fuse_opt_add_opt_escaped, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_add_opt_escaped(3) works"); +} + +ATF_TC_BODY(t_fuse_opt_add_opt_escaped, tc) +{ + char* opt = NULL; + + RZ(fuse_opt_add_opt_escaped(&opt, "fo\\o")); + ATF_CHECK_STREQ(opt, "fo\\\\o"); + + RZ(fuse_opt_add_opt_escaped(&opt, "ba,r")); + ATF_CHECK_STREQ(opt, "fo\\\\o,ba\\,r"); +} + +ATF_TC(t_fuse_opt_match); +ATF_TC_HEAD(t_fuse_opt_match, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_match(3) works" + " for every form of templates"); +} + +ATF_TC_BODY(t_fuse_opt_match, tc) +{ + struct fuse_opt o1[] = { FUSE_OPT_KEY("-x" , 0), FUSE_OPT_END }; + struct fuse_opt o2[] = { FUSE_OPT_KEY("foo" , 0), FUSE_OPT_END }; + struct fuse_opt o3[] = { FUSE_OPT_KEY("foo=" , 0), FUSE_OPT_END }; + struct fuse_opt o4[] = { FUSE_OPT_KEY("foo=%s", 0), FUSE_OPT_END }; + struct fuse_opt o5[] = { FUSE_OPT_KEY("-x " , 0), FUSE_OPT_END }; + struct fuse_opt o6[] = { FUSE_OPT_KEY("-x %s" , 0), FUSE_OPT_END }; + + ATF_CHECK(fuse_opt_match(o1, "-x") == 1); + ATF_CHECK(fuse_opt_match(o1, "x") == 0); + + ATF_CHECK(fuse_opt_match(o2, "foo") == 1); + ATF_CHECK(fuse_opt_match(o2, "-foo") == 0); + + ATF_CHECK(fuse_opt_match(o3, "foo=bar") == 1); + ATF_CHECK(fuse_opt_match(o3, "foo" ) == 0); + + ATF_CHECK(fuse_opt_match(o4, "foo=bar") == 1); + ATF_CHECK(fuse_opt_match(o4, "foo" ) == 0); + + ATF_CHECK(fuse_opt_match(o5, "-xbar" ) == 1); + ATF_CHECK(fuse_opt_match(o5, "-x" ) == 1); + ATF_CHECK(fuse_opt_match(o5, "-x=bar") == 1); + ATF_CHECK(fuse_opt_match(o5, "bar" ) == 0); + + ATF_CHECK(fuse_opt_match(o6, "-xbar" ) == 1); + ATF_CHECK(fuse_opt_match(o6, "-x" ) == 1); + ATF_CHECK(fuse_opt_match(o6, "-x=bar") == 1); + ATF_CHECK(fuse_opt_match(o6, "bar" ) == 0); +} + +struct foofs_config { + int number; + char *string; + char* nonopt; +}; + +#define FOOFS_OPT(t, p, v) { t, offsetof(struct foofs_config, p), v } + +static struct fuse_opt foofs_opts[] = { + FOOFS_OPT("number=%i" , number, 0), + FOOFS_OPT("-n %i" , number, 0), + FOOFS_OPT("string=%s" , string, 0), + FOOFS_OPT("number1" , number, 1), + FOOFS_OPT("number2" , number, 2), + FOOFS_OPT("--number=three", number, 3), + FOOFS_OPT("--number=four" , number, 4), + FUSE_OPT_END +}; + +static int foo_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs) { + struct foofs_config *config = data; + + if (key == FUSE_OPT_KEY_NONOPT && config->nonopt == NULL) { + config->nonopt = strdup(arg); + return 0; + } + else { + return 1; + } +} + +ATF_TC(t_fuse_opt_parse_null_args); +ATF_TC_HEAD(t_fuse_opt_parse_null_args, tc) +{ + atf_tc_set_md_var(tc, "descr", "NULL args means an empty arguments vector"); +} + +ATF_TC_BODY(t_fuse_opt_parse_null_args, tc) +{ + struct foofs_config config; + + memset(&config, 0, sizeof(config)); + ATF_CHECK(fuse_opt_parse(NULL, &config, NULL, NULL) == 0); + ATF_CHECK_EQ(config.number, 0); + ATF_CHECK_EQ(config.string, NULL); + ATF_CHECK_EQ(config.nonopt, NULL); +} + +ATF_TC(t_fuse_opt_parse_null_opts); +ATF_TC_HEAD(t_fuse_opt_parse_null_opts, tc) +{ + atf_tc_set_md_var(tc, "descr", "NULL opts means an opts array which only has FUSE_OPT_END"); +} + +ATF_TC_BODY(t_fuse_opt_parse_null_opts, tc) +{ + struct fuse_args args = FUSE_ARGS_INIT(0, NULL); + struct foofs_config config; + + RZ(fuse_opt_add_arg(&args, "foofs")); + RZ(fuse_opt_add_arg(&args, "-o")); + RZ(fuse_opt_add_arg(&args, "number=1,string=foo")); + RZ(fuse_opt_add_arg(&args, "bar")); + + memset(&config, 0, sizeof(config)); + ATF_CHECK(fuse_opt_parse(&args, &config, NULL, NULL) == 0); + ATF_CHECK_EQ(config.number, 0); + ATF_CHECK_EQ(config.string, NULL); + ATF_CHECK_EQ(config.nonopt, NULL); + ATF_CHECK_EQ(args.argc, 4); + ATF_CHECK_STREQ(args.argv[0], "foofs"); + ATF_CHECK_STREQ(args.argv[1], "-o"); + ATF_CHECK_STREQ(args.argv[2], "number=1,string=foo"); + ATF_CHECK_STREQ(args.argv[3], "bar"); +} + +ATF_TC(t_fuse_opt_parse_null_proc); +ATF_TC_HEAD(t_fuse_opt_parse_null_proc, tc) +{ + atf_tc_set_md_var(tc, "descr", "NULL proc means a processor function always returning 1," + " i.e. keep the argument"); +} + +ATF_TC_BODY(t_fuse_opt_parse_null_proc, tc) +{ + struct fuse_args args = FUSE_ARGS_INIT(0, NULL); + struct foofs_config config; + + RZ(fuse_opt_add_arg(&args, "foofs")); + RZ(fuse_opt_add_arg(&args, "-o")); + RZ(fuse_opt_add_arg(&args, "number=1,string=foo")); + RZ(fuse_opt_add_arg(&args, "bar")); + + memset(&config, 0, sizeof(config)); + ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, NULL) == 0); + ATF_CHECK_EQ(config.number, 1); + ATF_CHECK_STREQ(config.string, "foo"); + ATF_CHECK_EQ(config.nonopt, NULL); + ATF_CHECK_EQ(args.argc, 2); + ATF_CHECK_STREQ(args.argv[0], "foofs"); + ATF_CHECK_STREQ(args.argv[1], "bar"); +} + +ATF_TC(t_fuse_opt_parse); +ATF_TC_HEAD(t_fuse_opt_parse, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_parse(3) fully works"); +} + +ATF_TC_BODY(t_fuse_opt_parse, tc) +{ + struct fuse_args args = FUSE_ARGS_INIT(0, NULL); + struct foofs_config config; + + /* Standard form */ + fuse_opt_free_args(&args); + RZ(fuse_opt_add_arg(&args, "foofs")); + RZ(fuse_opt_add_arg(&args, "-o")); + RZ(fuse_opt_add_arg(&args, "number=1,string=foo")); + RZ(fuse_opt_add_arg(&args, "bar")); + + memset(&config, 0, sizeof(config)); + ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0); + ATF_CHECK_EQ(config.number, 1); + ATF_CHECK_STREQ(config.string, "foo"); + ATF_CHECK_STREQ(config.nonopt, "bar"); + ATF_CHECK_EQ(args.argc, 1); + ATF_CHECK_STREQ(args.argv[0], "foofs"); + + /* Concatenated -o */ + fuse_opt_free_args(&args); + RZ(fuse_opt_add_arg(&args, "foofs")); + RZ(fuse_opt_add_arg(&args, "-onumber=1,unknown,string=foo")); + RZ(fuse_opt_add_arg(&args, "bar")); + + memset(&config, 0, sizeof(config)); + ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0); + ATF_CHECK_EQ(config.number, 1); + ATF_CHECK_STREQ(config.string, "foo"); + ATF_CHECK_STREQ(config.nonopt, "bar"); + ATF_CHECK_EQ(args.argc, 3); + ATF_CHECK_STREQ(args.argv[0], "foofs"); + ATF_CHECK_STREQ(args.argv[1], "-o"); + ATF_CHECK_STREQ(args.argv[2], "unknown"); + + /* Sparse -o */ + fuse_opt_free_args(&args); + RZ(fuse_opt_add_arg(&args, "foofs")); + RZ(fuse_opt_add_arg(&args, "bar")); + RZ(fuse_opt_add_arg(&args, "baz")); + RZ(fuse_opt_add_arg(&args, "-o")); + RZ(fuse_opt_add_arg(&args, "number=1")); + RZ(fuse_opt_add_arg(&args, "-o")); + RZ(fuse_opt_add_arg(&args, "unknown")); + RZ(fuse_opt_add_arg(&args, "-o")); + RZ(fuse_opt_add_arg(&args, "string=foo")); + + memset(&config, 0, sizeof(config)); + ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0); + ATF_CHECK_EQ(config.number, 1); + ATF_CHECK_STREQ(config.string, "foo"); + ATF_CHECK_STREQ(config.nonopt, "bar"); + ATF_CHECK_EQ(args.argc, 4); + ATF_CHECK_STREQ(args.argv[0], "foofs"); + ATF_CHECK_STREQ(args.argv[1], "-o"); + ATF_CHECK_STREQ(args.argv[2], "unknown"); + ATF_CHECK_STREQ(args.argv[3], "baz"); + + /* Separate -n %i */ + fuse_opt_free_args(&args); + RZ(fuse_opt_add_arg(&args, "foofs")); + RZ(fuse_opt_add_arg(&args, "-n")); + RZ(fuse_opt_add_arg(&args, "3")); + + memset(&config, 0, sizeof(config)); + ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0); + ATF_CHECK_EQ(config.number, 3); + ATF_CHECK_EQ(config.string, NULL); + ATF_CHECK_EQ(config.nonopt, NULL); + ATF_CHECK_EQ(args.argc, 1); + ATF_CHECK_STREQ(args.argv[0], "foofs"); + + /* Concatenated -n %i */ + fuse_opt_free_args(&args); + RZ(fuse_opt_add_arg(&args, "foofs")); + RZ(fuse_opt_add_arg(&args, "-n3")); + + memset(&config, 0, sizeof(config)); + ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0); + ATF_CHECK_EQ(config.number, 3); + ATF_CHECK_EQ(config.string, NULL); + ATF_CHECK_EQ(config.nonopt, NULL); + ATF_CHECK_EQ(args.argc, 1); + ATF_CHECK_STREQ(args.argv[0], "foofs"); + + /* -o constant */ + fuse_opt_free_args(&args); + RZ(fuse_opt_add_arg(&args, "foofs")); + RZ(fuse_opt_add_arg(&args, "-o")); + RZ(fuse_opt_add_arg(&args, "number2")); + + memset(&config, 0, sizeof(config)); + ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0); + ATF_CHECK_EQ(config.number, 2); + ATF_CHECK_EQ(config.string, NULL); + ATF_CHECK_EQ(config.nonopt, NULL); + ATF_CHECK_EQ(args.argc, 1); + ATF_CHECK_STREQ(args.argv[0], "foofs"); + + /* -x constant */ + fuse_opt_free_args(&args); + RZ(fuse_opt_add_arg(&args, "foofs")); + RZ(fuse_opt_add_arg(&args, "--number=four")); + + memset(&config, 0, sizeof(config)); + ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0); + ATF_CHECK_EQ(config.number, 4); + ATF_CHECK_EQ(config.string, NULL); + ATF_CHECK_EQ(config.nonopt, NULL); + ATF_CHECK_EQ(args.argc, 1); + ATF_CHECK_STREQ(args.argv[0], "foofs"); + + /* end-of-options "--" marker */ + fuse_opt_free_args(&args); + RZ(fuse_opt_add_arg(&args, "foofs")); + RZ(fuse_opt_add_arg(&args, "--")); + RZ(fuse_opt_add_arg(&args, "-onumber=1")); + RZ(fuse_opt_add_arg(&args, "-ostring=foo")); + + memset(&config, 0, sizeof(config)); + ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0); + ATF_CHECK_EQ(config.number, 0); + ATF_CHECK_EQ(config.string, NULL); + ATF_CHECK_STREQ(config.nonopt, "-onumber=1"); + ATF_CHECK_EQ(args.argc, 3); + ATF_CHECK_STREQ(args.argv[0], "foofs"); + ATF_CHECK_STREQ(args.argv[1], "--"); + ATF_CHECK_STREQ(args.argv[2], "-ostring=foo"); + + /* The "--" marker at the last of outargs should be removed */ + fuse_opt_free_args(&args); + RZ(fuse_opt_add_arg(&args, "foofs")); + RZ(fuse_opt_add_arg(&args, "--")); + RZ(fuse_opt_add_arg(&args, "-onumber=1")); + + memset(&config, 0, sizeof(config)); + ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0); + ATF_CHECK_EQ(config.number, 0); + ATF_CHECK_EQ(config.string, NULL); + ATF_CHECK_STREQ(config.nonopt, "-onumber=1"); + ATF_CHECK_EQ(args.argc, 1); + ATF_CHECK_STREQ(args.argv[0], "foofs"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_fuse_opt_add_arg); + ATF_TP_ADD_TC(tp, t_fuse_opt_insert_arg); + ATF_TP_ADD_TC(tp, t_fuse_opt_add_opt); + ATF_TP_ADD_TC(tp, t_fuse_opt_add_opt_escaped); + ATF_TP_ADD_TC(tp, t_fuse_opt_match); + ATF_TP_ADD_TC(tp, t_fuse_opt_parse_null_args); + ATF_TP_ADD_TC(tp, t_fuse_opt_parse_null_opts); + ATF_TP_ADD_TC(tp, t_fuse_opt_parse_null_proc); + ATF_TP_ADD_TC(tp, t_fuse_opt_parse); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/librt/t_sched.c b/contrib/netbsd-tests/lib/librt/t_sched.c new file mode 100644 index 0000000..8796043 --- /dev/null +++ b/contrib/netbsd-tests/lib/librt/t_sched.c @@ -0,0 +1,256 @@ +/* $NetBSD: t_sched.c,v 1.5 2012/03/25 04:11:42 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_sched.c,v 1.5 2012/03/25 04:11:42 christos Exp $"); + +#include +#include +#include + +#include + +static void sched_priority_set(int, int); + +ATF_TC(sched_getparam); +ATF_TC_HEAD(sched_getparam, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of sched_getparam(3)"); +} + +ATF_TC_BODY(sched_getparam, tc) +{ + struct sched_param s1, s2; + pid_t p = getpid(); + + /* + * IEEE Std 1003.1-2008: if the supplied pid is zero, + * the parameters for the calling process are returned. + */ + ATF_REQUIRE(sched_getparam(0, &s1) == 0); + ATF_REQUIRE(sched_getparam(p, &s2) == 0); + + ATF_CHECK_EQ(s1.sched_priority, s2.sched_priority); + + /* + * The behavior is undefined but should error + * out in case the supplied PID is negative. + */ + ATF_REQUIRE(sched_getparam(-1, &s1) != 0); +} + +ATF_TC(sched_priority); +ATF_TC_HEAD(sched_priority, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sched(3) priority ranges"); +} + +ATF_TC_BODY(sched_priority, tc) +{ + static const int pol[3] = { SCHED_OTHER, SCHED_FIFO, SCHED_RR }; + int pmax, pmin; + size_t i; + + /* + * Test that bogus values error out. + */ + if (INT_MAX > SCHED_RR) + ATF_REQUIRE(sched_get_priority_max(INT_MAX) != 0); + + if (-INT_MAX < SCHED_OTHER) + ATF_REQUIRE(sched_get_priority_max(-INT_MAX) != 0); + + /* + * Test that we have a valid range. + */ + for (i = 0; i < __arraycount(pol); i++) { + + pmax = sched_get_priority_max(pol[i]); + pmin = sched_get_priority_min(pol[i]); + + ATF_REQUIRE(pmax != -1); + ATF_REQUIRE(pmin != -1); + ATF_REQUIRE(pmax > pmin); + } +} + +static void +sched_priority_set(int pri, int pol) +{ + struct sched_param sched; + + sched.sched_priority = pri; + + ATF_REQUIRE(pri >= 0); + ATF_REQUIRE(sched_setscheduler(0, pol, &sched) == 0); + + /* + * Test that the policy was changed. + */ + ATF_CHECK_EQ(sched_getscheduler(0), pol); + + /* + * And that sched_getparam(3) returns the new priority. + */ + sched.sched_priority = -1; + + ATF_REQUIRE(sched_getparam(0, &sched) == 0); + ATF_CHECK_EQ(sched.sched_priority, pri); +} + +ATF_TC(sched_setscheduler_1); +ATF_TC_HEAD(sched_setscheduler_1, tc) +{ + atf_tc_set_md_var(tc, "descr", "sched_setscheduler(3), max, RR"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sched_setscheduler_1, tc) +{ + int pri; + + pri = sched_get_priority_max(SCHED_RR); + sched_priority_set(pri, SCHED_RR); +} + +ATF_TC(sched_setscheduler_2); +ATF_TC_HEAD(sched_setscheduler_2, tc) +{ + atf_tc_set_md_var(tc, "descr", "sched_setscheduler(3), min, RR"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sched_setscheduler_2, tc) +{ + int pri; + + pri = sched_get_priority_min(SCHED_RR); + sched_priority_set(pri, SCHED_RR); +} + +ATF_TC(sched_setscheduler_3); +ATF_TC_HEAD(sched_setscheduler_3, tc) +{ + atf_tc_set_md_var(tc, "descr", "sched_setscheduler(3), max, FIFO"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sched_setscheduler_3, tc) +{ + int pri; + + pri = sched_get_priority_max(SCHED_FIFO); + sched_priority_set(pri, SCHED_FIFO); +} + +ATF_TC(sched_setscheduler_4); +ATF_TC_HEAD(sched_setscheduler_4, tc) +{ + atf_tc_set_md_var(tc, "descr", "sched_setscheduler(3), min, FIFO"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sched_setscheduler_4, tc) +{ + int pri; + + pri = sched_get_priority_min(SCHED_FIFO); + sched_priority_set(pri, SCHED_FIFO); +} + +ATF_TC(sched_rr_get_interval_1); +ATF_TC_HEAD(sched_rr_get_interval_1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sched_rr_get_interval(3), #1" + " (PR lib/44768)"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sched_rr_get_interval_1, tc) +{ + struct timespec tv; + int pri; + + pri = sched_get_priority_min(SCHED_RR); + sched_priority_set(pri, SCHED_RR); + + /* + * This should fail with ESRCH for invalid PID. + */ + ATF_REQUIRE(sched_rr_get_interval(-INT_MAX, &tv) != 0); +} + +ATF_TC(sched_rr_get_interval_2); +ATF_TC_HEAD(sched_rr_get_interval_2, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test sched_rr_get_interval(3), #2"); + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(sched_rr_get_interval_2, tc) +{ + struct timespec tv1, tv2; + int pri; + + pri = sched_get_priority_min(SCHED_RR); + sched_priority_set(pri, SCHED_RR); + + tv1.tv_sec = tv2.tv_sec = -1; + tv1.tv_nsec = tv2.tv_nsec = -1; + + ATF_REQUIRE(sched_rr_get_interval(0, &tv1) == 0); + ATF_REQUIRE(sched_rr_get_interval(getpid(), &tv2) == 0); + + ATF_REQUIRE(tv1.tv_sec != -1); + ATF_REQUIRE(tv2.tv_sec != -1); + + ATF_REQUIRE(tv1.tv_nsec != -1); + ATF_REQUIRE(tv2.tv_nsec != -1); + + ATF_REQUIRE(tv1.tv_sec == tv2.tv_sec); + ATF_REQUIRE(tv1.tv_nsec == tv2.tv_nsec); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sched_getparam); + ATF_TP_ADD_TC(tp, sched_priority); + + ATF_TP_ADD_TC(tp, sched_setscheduler_1); + ATF_TP_ADD_TC(tp, sched_setscheduler_2); + ATF_TP_ADD_TC(tp, sched_setscheduler_3); + ATF_TP_ADD_TC(tp, sched_setscheduler_4); + + ATF_TP_ADD_TC(tp, sched_rr_get_interval_1); + ATF_TP_ADD_TC(tp, sched_rr_get_interval_2); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/librt/t_sem.c b/contrib/netbsd-tests/lib/librt/t_sem.c new file mode 100644 index 0000000..4bf379b --- /dev/null +++ b/contrib/netbsd-tests/lib/librt/t_sem.c @@ -0,0 +1,330 @@ +/* $NetBSD: t_sem.c,v 1.3 2017/01/14 20:58:20 christos Exp $ */ + +/* + * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Copyright (C) 2000 Jason Evans . + * 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(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sem.c,v 1.3 2017/01/14 20:58:20 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define NCHILDREN 10 + +#define SEM_REQUIRE(x) \ + ATF_REQUIRE_EQ_MSG(x, 0, "%s", strerror(errno)) + +ATF_TC_WITH_CLEANUP(basic); +ATF_TC_HEAD(basic, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks basic functionality of POSIX " + "semaphores"); +} +ATF_TC_BODY(basic, tc) +{ + int val; + sem_t *sem_b; + + if (sysconf(_SC_SEMAPHORES) == -1) + atf_tc_skip("POSIX semaphores not supported"); + + sem_b = sem_open("/sem_b", O_CREAT | O_EXCL, 0644, 0); + ATF_REQUIRE(sem_b != SEM_FAILED); + + ATF_REQUIRE_EQ(sem_getvalue(sem_b, &val), 0); + ATF_REQUIRE_EQ(val, 0); + + ATF_REQUIRE_EQ(sem_post(sem_b), 0); + ATF_REQUIRE_EQ(sem_getvalue(sem_b, &val), 0); + ATF_REQUIRE_EQ(val, 1); + + ATF_REQUIRE_EQ(sem_wait(sem_b), 0); + ATF_REQUIRE_EQ(sem_trywait(sem_b), -1); + ATF_REQUIRE_EQ(errno, EAGAIN); + ATF_REQUIRE_EQ(sem_post(sem_b), 0); + ATF_REQUIRE_EQ(sem_trywait(sem_b), 0); + ATF_REQUIRE_EQ(sem_post(sem_b), 0); + ATF_REQUIRE_EQ(sem_wait(sem_b), 0); + ATF_REQUIRE_EQ(sem_post(sem_b), 0); + + ATF_REQUIRE_EQ(sem_close(sem_b), 0); + ATF_REQUIRE_EQ(sem_unlink("/sem_b"), 0); +} +ATF_TC_CLEANUP(basic, tc) +{ + (void)sem_unlink("/sem_b"); +} + +ATF_TC_WITH_CLEANUP(child); +ATF_TC_HEAD(child, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks using semaphores to synchronize " + "parent with multiple child processes"); + atf_tc_set_md_var(tc, "timeout", "5"); +} +ATF_TC_BODY(child, tc) +{ + pid_t children[NCHILDREN]; + unsigned i, j; + sem_t *sem_a; + int status; + + pid_t pid; + + if (sysconf(_SC_SEMAPHORES) == -1) + atf_tc_skip("POSIX semaphores not supported"); + + sem_a = sem_open("/sem_a", O_CREAT | O_EXCL, 0644, 0); + ATF_REQUIRE(sem_a != SEM_FAILED); + + for (j = 1; j <= 2; j++) { + for (i = 0; i < NCHILDREN; i++) { + switch ((pid = fork())) { + case -1: + atf_tc_fail("fork() returned -1"); + case 0: + printf("PID %d waiting for semaphore...\n", + getpid()); + ATF_REQUIRE_MSG(sem_wait(sem_a) == 0, + "sem_wait failed; iteration %d", j); + printf("PID %d got semaphore\n", getpid()); + _exit(0); + default: + children[i] = pid; + break; + } + } + + for (i = 0; i < NCHILDREN; i++) { + usleep(100000); + printf("main loop %d: posting...\n", j); + ATF_REQUIRE_EQ(sem_post(sem_a), 0); + } + + for (i = 0; i < NCHILDREN; i++) { + ATF_REQUIRE_EQ(waitpid(children[i], &status, 0), children[i]); + ATF_REQUIRE(WIFEXITED(status)); + ATF_REQUIRE_EQ(WEXITSTATUS(status), 0); + } + } + + ATF_REQUIRE_EQ(sem_close(sem_a), 0); + ATF_REQUIRE_EQ(sem_unlink("/sem_a"), 0); +} +ATF_TC_CLEANUP(child, tc) +{ + (void)sem_unlink("/sem_a"); +} + +static inline void +timespec_add_ms(struct timespec *ts, int ms) +{ + ts->tv_nsec += ms * 1000*1000; + if (ts->tv_nsec > 1000*1000*1000) { + ts->tv_sec++; + ts->tv_nsec -= 1000*1000*1000; + } +} + +volatile sig_atomic_t got_sigalrm = 0; + +static void +sigalrm_handler(int sig __unused) +{ + got_sigalrm = 1; +} + +ATF_TC(timedwait); +ATF_TC_HEAD(timedwait, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests sem_timedwait(3)" +#ifdef __FreeBSD__ + " and sem_clockwait_np(3)" +#endif + ); + atf_tc_set_md_var(tc, "timeout", "20"); +} +ATF_TC_BODY(timedwait, tc) +{ + struct timespec ts; + sem_t sem; + int result; + + SEM_REQUIRE(sem_init(&sem, 0, 0)); + SEM_REQUIRE(sem_post(&sem)); + ATF_REQUIRE_MSG(clock_gettime(CLOCK_REALTIME, &ts) == 0, + "%s", strerror(errno)); + timespec_add_ms(&ts, 100); + SEM_REQUIRE(sem_timedwait(&sem, &ts)); + ATF_REQUIRE_ERRNO(ETIMEDOUT, sem_timedwait(&sem, &ts)); + ts.tv_sec--; + ATF_REQUIRE_ERRNO(ETIMEDOUT, sem_timedwait(&sem, &ts)); + SEM_REQUIRE(sem_post(&sem)); + SEM_REQUIRE(sem_timedwait(&sem, &ts)); + + /* timespec validation, in the past */ + ts.tv_nsec += 1000*1000*1000; + ATF_REQUIRE_ERRNO(EINVAL, sem_timedwait(&sem, &ts)); + ts.tv_nsec = -1; + ATF_REQUIRE_ERRNO(EINVAL, sem_timedwait(&sem, &ts)); + /* timespec validation, in the future */ + ATF_REQUIRE_MSG(clock_gettime(CLOCK_REALTIME, &ts) == 0, + "%s", strerror(errno)); + ts.tv_sec++; + ts.tv_nsec = 1000*1000*1000; + ATF_REQUIRE_ERRNO(EINVAL, sem_timedwait(&sem, &ts)); + ts.tv_nsec = -1; + ATF_REQUIRE_ERRNO(EINVAL, sem_timedwait(&sem, &ts)); + + /* EINTR */ + struct sigaction act = { + .sa_handler = sigalrm_handler, + .sa_flags = 0 /* not SA_RESTART */ + }; + ATF_REQUIRE_MSG(sigemptyset(&act.sa_mask) == 0, + "%s", strerror(errno)); + ATF_REQUIRE_MSG(sigaction(SIGALRM, &act, NULL) == 0, + "%s", strerror(errno)); + struct itimerval it = { + .it_value.tv_usec = 50*1000 + }; + ATF_REQUIRE_MSG(setitimer(ITIMER_REAL, &it, NULL) == 0, + "%s", strerror(errno)); + ATF_REQUIRE_MSG(clock_gettime(CLOCK_REALTIME, &ts) == 0, + "%s", strerror(errno)); + timespec_add_ms(&ts, 100); + ATF_REQUIRE_ERRNO(EINTR, sem_timedwait(&sem, &ts)); + ATF_REQUIRE_MSG(got_sigalrm, "did not get SIGALRM"); + +#ifdef __FreeBSD__ + /* CLOCK_MONOTONIC, absolute */ + SEM_REQUIRE(sem_post(&sem)); + ATF_REQUIRE_MSG(clock_gettime(CLOCK_MONOTONIC, &ts) == 0, + "%s", strerror(errno)); + timespec_add_ms(&ts, 100); + SEM_REQUIRE(sem_clockwait_np(&sem, CLOCK_MONOTONIC, TIMER_ABSTIME, + &ts, NULL)); + ATF_REQUIRE_ERRNO(ETIMEDOUT, + sem_clockwait_np(&sem, CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL)); + + /* CLOCK_MONOTONIC, relative */ + SEM_REQUIRE(sem_post(&sem)); + ts.tv_sec = 0; + ts.tv_nsec = 100*1000*1000; + SEM_REQUIRE(sem_clockwait_np(&sem, CLOCK_MONOTONIC, 0, + &ts, NULL)); + ATF_REQUIRE_ERRNO(ETIMEDOUT, + sem_clockwait_np(&sem, CLOCK_MONOTONIC, 0, &ts, NULL)); + + /* absolute does not update remaining time on EINTR */ + struct timespec remain = {42, 1000*1000*1000}; + got_sigalrm = 0; + it.it_value.tv_usec = 50*1000; + ATF_REQUIRE_MSG(setitimer(ITIMER_REAL, &it, NULL) == 0, + "%s", strerror(errno)); + ATF_REQUIRE_MSG(clock_gettime(CLOCK_MONOTONIC, &ts) == 0, + "%s", strerror(errno)); + timespec_add_ms(&ts, 100); + ATF_REQUIRE_ERRNO(EINTR, sem_clockwait_np(&sem, CLOCK_MONOTONIC, + TIMER_ABSTIME, &ts, &remain)); + ATF_REQUIRE_MSG(got_sigalrm, "did not get SIGALRM"); + ATF_REQUIRE_MSG(remain.tv_sec == 42 && remain.tv_nsec == 1000*1000*1000, + "an absolute clockwait modified the remaining time on EINTR"); + + /* relative updates remaining time on EINTR */ + remain.tv_sec = 42; + remain.tv_nsec = 1000*1000*1000; + got_sigalrm = 0; + it.it_value.tv_usec = 50*1000; + ATF_REQUIRE_MSG(setitimer(ITIMER_REAL, &it, NULL) == 0, + "%s", strerror(errno)); + ts.tv_sec = 0; + ts.tv_nsec = 100*1000*1000; + ATF_REQUIRE_ERRNO(EINTR, sem_clockwait_np(&sem, CLOCK_MONOTONIC, 0, &ts, + &remain)); + ATF_REQUIRE_MSG(got_sigalrm, "did not get SIGALRM"); + /* + * If this nsec comparison turns out to be unreliable due to timing, + * it could simply check that nsec < 100 ms. + */ + ATF_REQUIRE_MSG(remain.tv_sec == 0 && + remain.tv_nsec >= 25*1000*1000 && + remain.tv_nsec <= 75*1000*1000, + "the remaining time was not as expected when a relative clockwait" + " got EINTR" ); +#endif +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, basic); + ATF_TP_ADD_TC(tp, child); + ATF_TP_ADD_TC(tp, timedwait); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/librumpclient/h_exec.c b/contrib/netbsd-tests/lib/librumpclient/h_exec.c new file mode 100644 index 0000000..cf2526c --- /dev/null +++ b/contrib/netbsd-tests/lib/librumpclient/h_exec.c @@ -0,0 +1,132 @@ +/* $NetBSD: h_exec.c,v 1.6 2011/02/16 17:57:44 pooka Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +int +main(int argc, char *argv[]) +{ + struct sockaddr_in sin; + socklen_t slen; + int s1, s2; + char buf[12]; + char *eargv[4]; + char *ename; + extern char **environ; + + if (rumpclient_init() == -1) + err(1, "init"); + + if (argc > 1) { + if (strcmp(argv[1], "_didexec") == 0) { + rumpclient_daemon(0, 0); /* detach-me-notnot */ + s2 = atoi(argv[2]); + slen = sizeof(sin); + /* see below */ + rump_sys_accept(s2, (struct sockaddr *)&sin, &slen); + } + } + + /* open and listenize two TCP4 suckets */ + if ((s1 = rump_sys_socket(PF_INET, SOCK_STREAM, 0)) == -1) + err(1, "socket 1"); + if ((s2 = rump_sys_socket(PF_INET, SOCK_STREAM, 0)) == -1) + err(1, "socket 2"); + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + + if (rump_sys_bind(s1, (struct sockaddr *)&sin, sizeof(sin)) == -1) + err(1, "bind1"); + sin.sin_port = htons(2345); + if (rump_sys_bind(s2, (struct sockaddr *)&sin, sizeof(sin)) == -1) + err(1, "bind2"); + + if (rump_sys_listen(s1, 1) == -1) + err(1, "listen1"); + if (rump_sys_listen(s2, 1) == -1) + err(1, "listen2"); + + if (argc == 1) { + rumpclient_daemon(0, 0); + slen = sizeof(sin); + /* + * "pause()", but conveniently gets rid of this helper + * since we were called with RUMPCLIENT_RETRYCONN_DIE set + */ + rump_sys_accept(s2, (struct sockaddr *)&sin, &slen); + } + + if (argc == 3 && strcmp(argv[2], "cloexec1") == 0) { + if (rump_sys_fcntl(s1, F_SETFD, FD_CLOEXEC) == -1) { + err(1, "cloexec failed"); + } + } + + sprintf(buf, "%d", s2); + + if (argc == 3 && strcmp(argv[2], "vfork_please") == 0) { + switch (rumpclient_vfork()) { + case 0: + ename = __UNCONST("fourchette"); + break; + case -1: + err(1, "vfork"); + default: + ename = __UNCONST("h_ution"); + break; + } + } else { + ename = __UNCONST("h_ution"); + } + + /* omstart! */ + eargv[0] = ename; + eargv[1] = __UNCONST("_didexec"); + eargv[2] = buf; + eargv[3] = NULL; + if (rumpclient_exec(argv[1], __UNCONST(eargv), environ) == -1) + err(1, "exec"); +} diff --git a/contrib/netbsd-tests/lib/librumpclient/h_execthr.c b/contrib/netbsd-tests/lib/librumpclient/h_execthr.c new file mode 100644 index 0000000..c209375 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumpclient/h_execthr.c @@ -0,0 +1,221 @@ +/* $NetBSD: h_execthr.c,v 1.7 2016/11/24 00:37:29 dholland Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +//#define VERBOSE + +#ifdef VERBOSE +#define SAY(...) printf(__VA_ARGS__) +#else +#define SAY(...) +#endif + +static int canreturn = 0; + +/* + * Use a fairly large number of threads so that we have + * a better chance catching races. XXX: this is rumpuser's + * MAXWORKER-1. + */ +#define NTHR 63 + +#define P1_0 3 +#define P1_1 4 +#define P2_0 5 +#define P2_1 6 + +static void * +wrk(void *arg) +{ + int fd = (uintptr_t)arg; + + rump_sys_read(fd, &fd, sizeof(fd)); + if (!canreturn) + errx(1, "should not have returned"); + if (fd != 37) + errx(1, "got invalid magic"); + + return NULL; +} + +static int +getproc(pid_t mypid, struct kinfo_proc2 *p) +{ + int name[6]; + size_t len = sizeof(*p); + + name[0] = CTL_KERN; + name[1] = KERN_PROC2; + name[2] = KERN_PROC_PID; + name[3] = mypid; + name[4] = len; + name[5] = 1; + + return rump_sys___sysctl(name, __arraycount(name), p, &len, NULL, 0); +} + +int +main(int argc, char *argv[], char *envp[]) +{ + struct kinfo_proc2 p; + char *execarg[3]; + int p1[2], p2[2]; + pid_t mypid; + pthread_t pt; + ssize_t n; + int i, execd; + char nexec[16]; + + if (argc > 1) + execd = atoi(argv[1]); + else + execd = 0; + sprintf(nexec, "%d", execd+1); + SAY("execd: %d\n", execd); + + if (rumpclient_init() == -1) { + if (execd) + err(1, "init execd"); + else + err(1, "init"); + } + mypid = rump_sys_getpid(); + SAY("rumpclient_init finished.\n"); + + if (execd) { + canreturn = 1; + errno = pthread_create(&pt, NULL, + wrk, (void *)(uintptr_t)P2_0); + if (errno != 0) + err(1, "exec pthread_create"); + SAY("startup pthread_create finished.\n"); + + i = 37; + rump_sys_write(P2_1, &i, sizeof(i)); + pthread_join(pt, NULL); + SAY("startup pthread_join finished.\n"); + + n = rump_sys_read(P1_0, &i, sizeof(i)); + if (n != -1 || errno != EBADF) + errx(1, "post-exec cloexec works"); + SAY("startup rump_sys_read finished.\n"); + + getproc(mypid, &p); + SAY("startup getproc finished.\n"); + if (p.p_nlwps != 2) + errx(1, "invalid nlwps: %lld", (long long)p.p_nlwps); + + /* we passed? */ + if (execd > 10) { + SAY("done.\n"); + exit(0); + } + + rump_sys_close(P2_0); + rump_sys_close(P2_1); + } + + SAY("making pipes...\n"); + + if (rump_sys_pipe(p1) == -1) + err(1, "pipe1"); + if (p1[0] != P1_0 || p1[1] != P1_1) + errx(1, "p1 assumptions failed %d %d", p1[0], p1[1]); + if (rump_sys_pipe(p2) == -1) + err(1, "pipe1"); + if (p2[0] != P2_0 || p2[1] != P2_1) + errx(1, "p2 assumptions failed"); + if (rump_sys_fcntl(p1[0], F_SETFD, FD_CLOEXEC) == -1) + err(1, "cloexec"); + if (rump_sys_fcntl(p1[1], F_SETFD, FD_CLOEXEC) == -1) + err(1, "cloexec"); + + SAY("making threads...\n"); + + for (i = 0; i < NTHR; i++) { + errno = pthread_create(&pt, NULL, + wrk, (void *)(uintptr_t)p1[0]); + if (errno != 0) + err(1, "pthread_create 1 %d", i); + } + + for (i = 0; i < NTHR; i++) { + errno = pthread_create(&pt, NULL, + wrk, (void *)(uintptr_t)p2[0]); + if (errno != 0) + err(1, "pthread_create 2 %d", i); + } + + SAY("waiting for threads to start...\n"); + + /* wait for all the threads to be enjoying themselves */ + for (;;) { + getproc(mypid, &p); + SAY("getproc finished.\n"); + if (p.p_nlwps == 2*NTHR + 2) + break; + usleep(10000); + } + + SAY("making some more threads start...\n"); + + /* + * load up one more (big) set. these won't start executing, though, + * but we're interested in if they create blockage + */ + for (i = 0; i < 3*NTHR; i++) { + errno = pthread_create(&pt, NULL, + wrk, (void *)(uintptr_t)p1[0]); + if (errno != 0) + err(1, "pthread_create 3 %d", i); + } + + SAY("calling exec...\n"); + + /* then, we exec! */ + execarg[0] = argv[0]; + execarg[1] = nexec; + execarg[2] = NULL; + if (rumpclient_exec(argv[0], execarg, envp) == -1) + err(1, "exec"); +} diff --git a/contrib/netbsd-tests/lib/librumpclient/t_exec.sh b/contrib/netbsd-tests/lib/librumpclient/t_exec.sh new file mode 100755 index 0000000..a07af0c --- /dev/null +++ b/contrib/netbsd-tests/lib/librumpclient/t_exec.sh @@ -0,0 +1,154 @@ +# $NetBSD: t_exec.sh,v 1.9 2016/08/10 21:10:18 kre Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +rumpsrv='rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpdev -lrumpvfs' +export RUMP_SERVER=unix://csock +export RUMPHIJACK_RETRYCONNECT='die' + +atf_test_case noexec cleanup +noexec_head() +{ + atf_set "descr" "check that we see what we expect without exec" +} + +noexec_body() +{ + + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + atf_check -s exit:0 env $(atf_get_srcdir)/h_exec + atf_check -s exit:0 -o save:sstat.out rump.sockstat -n + atf_check -s exit:0 -o match:'^root.*h_exec.*tcp.*\*\.1234' \ + sed -n 2p sstat.out + atf_check -s exit:0 -o match:'^root.*h_exec.*tcp.*\*\.2345' \ + sed -n 3p sstat.out +} + +noexec_cleanup() +{ + rump.halt +} + +atf_test_case exec cleanup +exec_head() +{ + atf_set "descr" "check that client names changes after exec" +} + +exec_body() +{ + + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + atf_check -s exit:0 $(atf_get_srcdir)/h_exec $(atf_get_srcdir)/h_exec + atf_check -s exit:0 -o save:sstat.out rump.sockstat -n + atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.1234' \ + sed -n 2p sstat.out + atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.2345' \ + sed -n 3p sstat.out +} + +exec_cleanup() +{ + rump.halt +} + +atf_test_case cloexec cleanup +cloexec_head() +{ + atf_set "descr" "check that FD_CLOEXEC works" +} + +cloexec_body() +{ + + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + atf_check -s exit:0 \ + $(atf_get_srcdir)/h_exec $(atf_get_srcdir)/h_exec cloexec1 + atf_check -s exit:0 -o save:sstat.out rump.sockstat -n + atf_check -s exit:0 -o inline:'2\n' sed -n '$=' sstat.out + atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.2345' \ + sed -n 2p sstat.out +} + +cloexec_cleanup() +{ + rump.halt +} + +atf_test_case vfork cleanup +vfork_head() +{ + atf_set "descr" "test rumpclient_vfork()" +} + +vfork_body() +{ + + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + atf_check -s exit:0 \ + $(atf_get_srcdir)/h_exec $(atf_get_srcdir)/h_exec vfork_please + atf_check -s exit:0 -o save:sstat.out rump.sockstat -n + atf_check -s exit:0 -o inline:'5\n' sed -n '$=' sstat.out + atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.1234' \ + cat sstat.out + atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.2345' \ + cat sstat.out + atf_check -s exit:0 -o match:'^root.*fourchette.*tcp.*\*\.1234' \ + cat sstat.out + atf_check -s exit:0 -o match:'^root.*fourchette.*tcp.*\*\.2345' \ + cat sstat.out +} + +vfork_cleanup() +{ + rump.halt +} + +atf_test_case threxec cleanup +threxec_head() +{ + atf_set "descr" "check that threads are killed before exec continues" +} + +threxec_body() +{ + atf_check -s exit:0 rump_server ${RUMP_SERVER} + atf_check -s exit:0 $(atf_get_srcdir)/h_execthr +} + +threxec_cleanup() +{ + rump.halt +} + +atf_init_test_cases() +{ + atf_add_test_case noexec + atf_add_test_case exec + atf_add_test_case cloexec + atf_add_test_case vfork + atf_add_test_case threxec +} diff --git a/contrib/netbsd-tests/lib/librumpclient/t_fd.c b/contrib/netbsd-tests/lib/librumpclient/t_fd.c new file mode 100644 index 0000000..70182ab --- /dev/null +++ b/contrib/netbsd-tests/lib/librumpclient/t_fd.c @@ -0,0 +1,146 @@ +/* $NetBSD: t_fd.c,v 1.6 2017/01/13 21:30:41 christos Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "h_macros.h" + +ATF_TC_WITH_CLEANUP(bigenough); +ATF_TC_HEAD(bigenough, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that rumpclient uses " + "fd > 2"); +} +ATF_TC_WITH_CLEANUP(sigio); +ATF_TC_HEAD(sigio, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that rump client receives " + "SIGIO"); +} + +#define RUMPSERV "unix://sucket" + +ATF_TC_CLEANUP(bigenough, tc){system("env RUMP_SERVER=" RUMPSERV " rump.halt");} +ATF_TC_CLEANUP(sigio, tc) { system("env RUMP_SERVER=" RUMPSERV " rump.halt"); } + +ATF_TC_BODY(bigenough, tc) +{ + struct stat sb; + + RZ(system("rump_server " RUMPSERV)); + RL(setenv("RUMP_SERVER", RUMPSERV, 1)); + + RL(dup2(0, 10)); + RL(dup2(1, 11)); + RL(dup2(2, 12)); + + RL(close(0)); + RL(close(1)); + RL(close(2)); + + RL(rumpclient_init()); + RL(rump_sys_getpid()); + + ATF_REQUIRE_ERRNO(EBADF, fstat(0, &sb) == -1); + ATF_REQUIRE_ERRNO(EBADF, fstat(1, &sb) == -1); + ATF_REQUIRE_ERRNO(EBADF, fstat(2, &sb) == -1); + + RL(rump_sys_getpid()); + + /* restore these. does it help? */ + dup2(10, 0); + dup2(11, 1); + dup2(12, 2); +} + +static volatile sig_atomic_t sigcnt; +static void +gotsig(int sig) +{ + + sigcnt++; +} + +ATF_TC_BODY(sigio, tc) +{ + struct sockaddr_in sin; + int ls; + int cs; + int fl; + int sc; + + signal(SIGIO, gotsig); + RZ(system("rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet " + "-lrumpdev -lrumpvfs " RUMPSERV)); + RL(setenv("RUMP_SERVER", RUMPSERV, 1)); + + RL(rumpclient_init()); + RL(ls = rump_sys_socket(PF_INET, SOCK_STREAM, 0)); + + RL(rump_sys_fcntl(ls, F_SETOWN, rump_sys_getpid())); + RL(fl = rump_sys_fcntl(ls, F_GETFL)); + RL(rump_sys_fcntl(ls, F_SETFL, fl | O_ASYNC)); + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(12345); + RL(rump_sys_bind(ls, (struct sockaddr *)&sin, sizeof(sin))); + RL(rump_sys_listen(ls, 5)); + + RL(cs = rump_sys_socket(PF_INET, SOCK_STREAM, 0)); + sin.sin_addr.s_addr = inet_addr("127.0.0.1"); + + ATF_REQUIRE_EQ(sigcnt, 0); + RL(rump_sys_connect(cs, (struct sockaddr *)&sin, sizeof(sin))); + sc = sigcnt; + printf("sigcnt after connect: %d\n", sc); + ATF_REQUIRE(sc >= 1); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, bigenough); + ATF_TP_ADD_TC(tp, sigio); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/librumphijack/h_client.c b/contrib/netbsd-tests/lib/librumphijack/h_client.c new file mode 100644 index 0000000..20add73 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/h_client.c @@ -0,0 +1,138 @@ +/* $NetBSD: h_client.c,v 1.8 2012/04/20 05:15:11 jruoho Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + + if (argc != 2) { + errx(1, "need testname as param"); + } + + if (strcmp(argv[1], "select_timeout") == 0) { + fd_set rfds; + struct timeval tv; + int pipefd[2]; + int rv; + + tv.tv_sec = 0; + tv.tv_usec = 1; + + if (pipe(pipefd) == -1) + err(EXIT_FAILURE, "pipe"); + FD_ZERO(&rfds); + FD_SET(pipefd[0], &rfds); + + rv = select(pipefd[0]+1, &rfds, NULL, NULL, &tv); + if (rv == -1) + err(EXIT_FAILURE, "select"); + if (rv != 0) + errx(EXIT_FAILURE, "select succesful"); + + if (FD_ISSET(pipefd[0], &rfds)) + errx(EXIT_FAILURE, "stdin fileno is still set"); + return EXIT_SUCCESS; + } else if (strcmp(argv[1], "select_allunset") == 0) { + fd_set fds; + struct timeval tv; + int rv; + + tv.tv_sec = 0; + tv.tv_usec = 1; + + FD_ZERO(&fds); + + rv = select(100, &fds, &fds, &fds, &tv); + if (rv == -1) + err(EXIT_FAILURE, "select"); + if (rv != 0) + errx(EXIT_FAILURE, "select succesful"); + + rv = select(0, NULL, NULL, NULL, &tv); + if (rv == -1) + err(EXIT_FAILURE, "select2"); + if (rv != 0) + errx(EXIT_FAILURE, "select2 succesful"); + + return EXIT_SUCCESS; + } else if (strcmp(argv[1], "invafd") == 0) { + struct pollfd pfd[2]; + int fd, rv; + + fd = open("/rump/dev/null", O_RDWR); + if (fd == -1) + err(EXIT_FAILURE, "open"); + close(fd); + + pfd[0].fd = STDIN_FILENO; + pfd[0].events = POLLIN; + pfd[1].fd = fd; + pfd[1].events = POLLIN; + + if ((rv = poll(pfd, 2, INFTIM)) != 1) + errx(EXIT_FAILURE, "poll unexpected rv %d (%d)", + rv, errno); + if (pfd[1].revents != POLLNVAL || pfd[0].revents != 0) + errx(EXIT_FAILURE, "poll unexpected revents"); + + return EXIT_SUCCESS; + } else if (strcmp(argv[1], "fdoff8") == 0) { + + (void)closefrom(0); + + int fd; + + do { + if ((fd = open("/dev/null", O_RDWR)) == -1) + err(EXIT_FAILURE, "open1"); + } while (fd < 7); + fd = open("/dev/null", O_RDWR); + if (fd != -1 || errno != ENFILE) + errx(EXIT_FAILURE, "unexpected fd8 %d %d", fd, errno); + if (fcntl(0, F_MAXFD) != 7) + errx(EXIT_FAILURE, "fd leak?"); + if ((fd = open("/rump/dev/null", O_RDWR)) != 8) + errx(EXIT_FAILURE, "rump open %d %d", fd, errno); + return EXIT_SUCCESS; + } else { + return ENOTSUP; + } +} diff --git a/contrib/netbsd-tests/lib/librumphijack/h_cwd.c b/contrib/netbsd-tests/lib/librumphijack/h_cwd.c new file mode 100644 index 0000000..dfc509d --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/h_cwd.c @@ -0,0 +1,168 @@ +/* $NetBSD: h_cwd.c,v 1.3 2012/04/17 09:23:21 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include +#include + +static const char *prefix; +static size_t prefixlen; +static char buf[1024]; +static char pwd[1024]; + +static const char * +makepath(const char *tail) +{ + + strcpy(buf, prefix); + if (prefix[prefixlen-1] != '/') + strcat(buf, "/"); + strcat(buf, tail); + + return buf; +} + +static void +dochdir(const char *path, const char *errmsg) +{ + + if (chdir(path) == -1) + err(EXIT_FAILURE, "%s", errmsg); +} + +static void +dofchdir(const char *path, const char *errmsg) +{ + int fd; + + fd = open(path, O_RDONLY); + if (fd == -1) + err(EXIT_FAILURE, "open %s", errmsg); + if (fchdir(fd) == -1) + err(EXIT_FAILURE, "fchdir %s", errmsg); + close(fd); +} +static void (*thechdir)(const char *, const char *); + +static void +simple(void) +{ + + thechdir(prefix, "chdir1"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd1"); + if (strcmp(pwd, prefix) != 0) + errx(EXIT_FAILURE, "strcmp1"); + + if (mkdir("dir", 0777) == -1) + err(EXIT_FAILURE, "mkdir2"); + thechdir("dir", "chdir2"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd2"); + if (strcmp(pwd, makepath("dir")) != 0) + errx(EXIT_FAILURE, "strcmp2"); + + if (mkdir("dir", 0777) == -1) + err(EXIT_FAILURE, "mkdir3"); + thechdir("dir", "chdir3"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd3"); + if (strcmp(pwd, makepath("dir/dir")) != 0) + errx(EXIT_FAILURE, "strcmp3"); + + thechdir("..", "chdir4"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd4"); + if (strcmp(pwd, makepath("dir")) != 0) + errx(EXIT_FAILURE, "strcmp4"); + + + thechdir("../../../../../../..", "chdir5"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd5"); + if (strcmp(pwd, prefix) != 0) + errx(EXIT_FAILURE, "strcmp5"); + + thechdir("/", "chdir6"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd6"); + if (strcmp(pwd, "/") != 0) + errx(EXIT_FAILURE, "strcmp6"); +} + +static void +symlinktest(void) +{ + + thechdir(prefix, "chdir1"); + if (mkdir("adir", 0777) == -1) + err(EXIT_FAILURE, "mkdir1"); + if (mkdir("anotherdir", 0777) == -1) + err(EXIT_FAILURE, "mkdir2"); + + if (symlink("/adir", "anotherdir/lincthesink") == -1) + err(EXIT_FAILURE, "symlink"); + + thechdir("anotherdir/lincthesink", "chdir2"); + if (getcwd(pwd, sizeof(pwd)) == NULL) + err(EXIT_FAILURE, "getcwd"); + if (strcmp(pwd, makepath("adir")) != 0) + errx(EXIT_FAILURE, "strcmp"); +} + +int +main(int argc, char *argv[]) +{ + + if (argc != 4) + errx(1, "usage"); + + prefix = argv[1]; + prefixlen = strlen(argv[1]); + + if (strcmp(argv[3], "chdir") == 0) + thechdir = dochdir; + else if (strcmp(argv[3], "fchdir") == 0) + thechdir = dofchdir; + else + errx(EXIT_FAILURE, "invalid chdir type"); + + if (strcmp(argv[2], "simple") == 0) + simple(); + if (strcmp(argv[2], "symlink") == 0) + symlinktest(); + + return EXIT_SUCCESS; +} diff --git a/contrib/netbsd-tests/lib/librumphijack/h_netget.c b/contrib/netbsd-tests/lib/librumphijack/h_netget.c new file mode 100644 index 0000000..4d8b408 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/h_netget.c @@ -0,0 +1,101 @@ +/* $NetBSD: h_netget.c,v 1.2 2012/04/17 09:23:21 jruoho Exp $ */ + +/*- + * Copyright (c) 2011 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/* + * simple utility to fetch a webpage. we wouldn't need this + * if we had something like netcat in base + */ + +#include +__RCSID("$NetBSD: h_netget.c,v 1.2 2012/04/17 09:23:21 jruoho Exp $"); + +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define GETSTR "GET / HTTP/1.0\n\n" + +int +main(int argc, char *argv[]) +{ + char buf[8192]; + struct sockaddr_in sin; + ssize_t n; + int s, fd; + + setprogname(argv[0]); + if (argc != 4) { + fprintf(stderr, "usage: %s address port savefile\n", + getprogname()); + return EXIT_FAILURE; + } + + s = socket(PF_INET, SOCK_STREAM, 0); + if (s == -1) + err(EXIT_FAILURE, "socket"); + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(atoi(argv[2])); + sin.sin_addr.s_addr = inet_addr(argv[1]); + + fd = open(argv[3], O_CREAT | O_RDWR, 0644); + if (fd == -1) + err(EXIT_FAILURE, "open"); + if (ftruncate(fd, 0) == -1) + err(EXIT_FAILURE, "ftruncate savefile"); + + if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) + err(EXIT_FAILURE, "connect"); + + if (write(s, GETSTR, strlen(GETSTR)) != strlen(GETSTR)) + err(EXIT_FAILURE, "socket write"); + + for (;;) { + n = read(s, buf, sizeof(buf)); + if (n == 0) + break; + if (n == -1) + err(EXIT_FAILURE, "socket read"); + + if (write(fd, buf, n) != n) + err(EXIT_FAILURE, "write file"); + } + + return EXIT_SUCCESS; +} diff --git a/contrib/netbsd-tests/lib/librumphijack/index.html b/contrib/netbsd-tests/lib/librumphijack/index.html new file mode 100644 index 0000000..1d8679c --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/index.html @@ -0,0 +1,5 @@ + +test page + +i am a test, how do you do? + diff --git a/contrib/netbsd-tests/lib/librumphijack/netstat.expout b/contrib/netbsd-tests/lib/librumphijack/netstat.expout new file mode 100644 index 0000000..1a9a2a1 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/netstat.expout @@ -0,0 +1,6 @@ +Active Internet connections (including servers) +Proto Recv-Q Send-Q Local Address Foreign Address State +tcp 0 0 *.http *.* LISTEN +Active Internet6 connections (including servers) +Proto Recv-Q Send-Q Local Address Foreign Address (state) +tcp6 0 0 *.http *.* LISTEN diff --git a/contrib/netbsd-tests/lib/librumphijack/ssh_config.in b/contrib/netbsd-tests/lib/librumphijack/ssh_config.in new file mode 100644 index 0000000..73b83c8 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/ssh_config.in @@ -0,0 +1,14 @@ +# $NetBSD: ssh_config.in,v 1.1 2011/02/14 15:14:00 pooka Exp $ + +# Basic settings. +Port 22 +Protocol 2 + +# The temporary key used for login. +IdentityFile @WORKDIR@/ssh_user_key + +# Prevent the client from complaining about unknown host keys. +GlobalKnownHostsFile @WORKDIR@/known_hosts + +# Do not attempt password authentication in case keys fail. +IdentitiesOnly yes diff --git a/contrib/netbsd-tests/lib/librumphijack/ssh_host_key b/contrib/netbsd-tests/lib/librumphijack/ssh_host_key new file mode 100644 index 0000000..ebdbc8b --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/ssh_host_key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQDJnMpSG1lGmApk8F7ZH7TGtjjP/WUs+vqHyFsyS2lilJzereen +a/ME6S0d0HTOeCdKldjbtDpfNXbh+XnJMlJMEgEs4Mg1jluuEV0GOJoMt7cGzku2 +gAYGx++2+wqYw6Y+M8Tb1M4AO+PcxD/3BkdUyIKO63v6STl2VQn1BzsTQwIBIwKB +gAuFTWPHDGpvFols0jhK9GMgWwSSIwnidLdNRwowMehgQ3pwVmFWoCwqlN0h2sn4 +PMJu9nL0WxtiJAzprzARgQuPI25t9LiKTF7scC/cNUiHPplUjvoDXA9ccY1eIf4R +e6wwZz1jfCWen0eRsvMyoYvFmEH8hILAk1bY9heymOGLAkEA/WhC49n+gtloVMow +iKQOO6+u3ouxTOTQ3sV2wCaLaO2pEbHP2//5SlUJLp6QrjC7bg9Kr+f56+zT2he9 +f6GCwwJBAMus3XizmZdJyJLnkCJRiT0/3Kf57fhWKRdnFkuRLyjET9MEWavRdJmr +bx/lxmILi1iKwXiFEDM6MqYfmNImJYECQQCtw9YYlXtSaTGZOi/oqwJyEhGCqO6b +II85q/moVPHhjQY4BOZNttbT4on0FPV+wlSjPa+OkHDcSp/mAaaDZ2+bAkEAujel +6rLVkaKLfv+ZuPoXE22WivMityo0Mqdk12ArHfVQS+a4YpOdzlOYzLTSosi56o19 +sAShGOTAl+Jf1hQ/iwJAKpPviX5w292H/m5T0m4l0NRdQ3pRujOLMSVmY+/HFZTW +GJMYLr1eBKNfLsKzJgB88GzuF2O/O8hNi3XSiOP+9w== +-----END RSA PRIVATE KEY----- diff --git a/contrib/netbsd-tests/lib/librumphijack/ssh_host_key.pub b/contrib/netbsd-tests/lib/librumphijack/ssh_host_key.pub new file mode 100644 index 0000000..8d08795 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/ssh_host_key.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAyZzKUhtZRpgKZPBe2R+0xrY4z/1lLPr6h8hbMktpYpSc3q3np2vzBOktHdB0zngnSpXY27Q6XzV24fl5yTJSTBIBLODINY5brhFdBjiaDLe3Bs5LtoAGBsfvtvsKmMOmPjPE29TOADvj3MQ/9wZHVMiCjut7+kk5dlUJ9Qc7E0M= test@test.example.net diff --git a/contrib/netbsd-tests/lib/librumphijack/sshd_config.in b/contrib/netbsd-tests/lib/librumphijack/sshd_config.in new file mode 100644 index 0000000..9ffc47f --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/sshd_config.in @@ -0,0 +1,39 @@ +# $NetBSD: sshd_config.in,v 1.1 2011/02/14 15:14:00 pooka Exp $ + +# Basic settings. +Port 22 +Protocol 2 + +# Provide information to the user in case something goes wrong. +LogLevel DEBUG1 + +# The host key. It lives in the work directory because we need to set +# very strict permissions on it and cannot modify the copy on the source +# directory. +HostKey @WORKDIR@/ssh_host_key + +# The authorized keys file we set up during the test to allow the client +# to safely log in. We need to disable strict modes because ATF_WORKDIR +# usually lives in /tmp, which has 1777 permissions and are not liked by +# sshd. +AuthorizedKeysFile @WORKDIR@/authorized_keys +StrictModes no + +# Some settings to allow user runs of sshd. +PidFile @WORKDIR@/sshd.pid +UsePam no +UsePrivilegeSeparation no + +# The root user should also be able to run the tests. +PermitRootLogin yes + +# Be restrictive about access to the temporary server. Only allow key-based +# authentication. +ChallengeResponseAuthentication no +GSSAPIAuthentication no +HostbasedAuthentication no +KerberosAuthentication no +MaxAuthTries 1 +MaxStartups 1 +PasswordAuthentication no +PubkeyAuthentication yes diff --git a/contrib/netbsd-tests/lib/librumphijack/t_asyncio.sh b/contrib/netbsd-tests/lib/librumphijack/t_asyncio.sh new file mode 100755 index 0000000..d5d703c --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/t_asyncio.sh @@ -0,0 +1,94 @@ +# $NetBSD: t_asyncio.sh,v 1.4 2014/08/27 13:32:16 gson Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +rumpsrv='rump_server' +export RUMP_SERVER=unix://csock + +atf_test_case select_timeout cleanup +select_timeout_head() +{ + atf_set "descr" "select() with timeout returns no fds set" +} + +select_timeout_body() +{ + + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + $(atf_get_srcdir)/h_client select_timeout +} + +select_timeout_cleanup() +{ + rump.halt +} + +atf_test_case select_allunset cleanup +select_allunset_head() +{ + atf_set "descr" "select() with no set fds in fd_set should not crash" +} + +select_allunset_body() +{ + + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + $(atf_get_srcdir)/h_client select_allunset +} + +select_allunset_cleanup() +{ + rump.halt +} + +atf_test_case invafd cleanup +invafd_head() +{ + atf_set "descr" "poll on invalid rump fd" + atf_set "timeout" "10" +} + +invafd_body() +{ + + atf_check -s exit:0 rump_server -lrumpvfs ${RUMP_SERVER} + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + $(atf_get_srcdir)/h_client invafd +} + +invafd_cleanup() +{ + rump.halt +} + +atf_init_test_cases() +{ + atf_add_test_case select_timeout + atf_add_test_case select_allunset + atf_add_test_case invafd +} diff --git a/contrib/netbsd-tests/lib/librumphijack/t_config.sh b/contrib/netbsd-tests/lib/librumphijack/t_config.sh new file mode 100755 index 0000000..014bb0f --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/t_config.sh @@ -0,0 +1,54 @@ +# $NetBSD: t_config.sh,v 1.1 2011/03/14 15:56:40 pooka Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +rumpsrv='rump_server -lrumpvfs' +export RUMP_SERVER=unix://csock + +atf_test_case fdoff cleanup +fdoff_head() +{ + atf_set "descr" "RUMPHIJACK fdoff=8" +} + +fdoff_body() +{ + + atf_check -s exit:0 rump_server -lrumpvfs ${RUMP_SERVER} + export RUMPHIJACK=path=/rump,fdoff=8 + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + $(atf_get_srcdir)/h_client fdoff8 +} + +fdoff_cleanup() +{ + rump.halt +} + +atf_init_test_cases() +{ + atf_add_test_case fdoff +} diff --git a/contrib/netbsd-tests/lib/librumphijack/t_cwd.sh b/contrib/netbsd-tests/lib/librumphijack/t_cwd.sh new file mode 100755 index 0000000..3f2a50b --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/t_cwd.sh @@ -0,0 +1,72 @@ +# $NetBSD: t_cwd.sh,v 1.2 2011/02/19 19:57:28 pooka Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +rumpsrv='rump_server -lrumpvfs' +export RUMP_SERVER=unix://csock + +test_case() +{ + local name="${1}"; shift + + atf_test_case "${name}" cleanup + eval "${name}_head() { }" + eval "${name}_body() { \ + export RUMPHIJACK="path=${1}" ; \ + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} ; \ + testbody " "${@}" "; \ + }" + eval "${name}_cleanup() { \ + rump.halt + }" +} + +test_case basic_chdir /rump simple chdir +test_case basic_fchdir /rump simple fchdir +test_case slash_chdir // simple chdir +test_case slash_fchdir // simple fchdir +test_case symlink_chdir /rump symlink chdir +test_case symlink_fchdir /rump symlink fchdir +test_case symlink_slash_chdir // symlink chdir +test_case symlink_slash_fchdir // symlink fchdir + +testbody() +{ + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + $(atf_get_srcdir)/h_cwd $* +} + +atf_init_test_cases() +{ + atf_add_test_case basic_chdir + atf_add_test_case basic_fchdir + atf_add_test_case slash_chdir + atf_add_test_case slash_fchdir + atf_add_test_case symlink_chdir + atf_add_test_case symlink_fchdir + atf_add_test_case symlink_slash_chdir + atf_add_test_case symlink_slash_fchdir +} diff --git a/contrib/netbsd-tests/lib/librumphijack/t_sh.sh b/contrib/netbsd-tests/lib/librumphijack/t_sh.sh new file mode 100755 index 0000000..c01c729 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/t_sh.sh @@ -0,0 +1,91 @@ +# $NetBSD: t_sh.sh,v 1.1 2011/03/03 11:54:12 pooka Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Test various /bin/sh descriptor games. +# +# Note that there is an extra level of trickery here, since +# we need to run an extra level of shell to "catch" LD_PRELOAD. +# + +rumpsrv='rump_server -lrumpvfs' +export RUMP_SERVER=unix://csock +exout="this is the output you are looking for" + +atf_test_case runscript cleanup +runscript_head() +{ + atf_set "descr" "can run /bin/sh scripts from rumpfs" +} + +runscript_body() +{ + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + + export LD_PRELOAD=/usr/lib/librumphijack.so + echo "echo $exout" > thescript + atf_check -s exit:0 mv thescript /rump + atf_check -s exit:0 -o inline:"${exout}\n" -x sh /rump/thescript +} + +runscript_cleanup() +{ + rump.halt +} + +atf_test_case redirect cleanup +redirect_head() +{ + atf_set "descr" "input/output redirection works with rumphijack" +} + +redirect_body() +{ + atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} + export LD_PRELOAD=/usr/lib/librumphijack.so + + echo "echo $exout > /rump/thefile" > thescript + atf_check -s exit:0 -x sh thescript + + # read it without input redirection + atf_check -s exit:0 -o inline:"${exout}\n" cat /rump/thefile + + # read it with input redirection (note, need an exec'd shell again) + echo "cat < /rump/thefile" > thescript + atf_check -s exit:0 -o inline:"${exout}\n" -x sh thescript +} + +redirect_cleanup() +{ + rump.halt +} + +atf_init_test_cases() +{ + atf_add_test_case runscript + atf_add_test_case redirect +} diff --git a/contrib/netbsd-tests/lib/librumphijack/t_tcpip.sh b/contrib/netbsd-tests/lib/librumphijack/t_tcpip.sh new file mode 100755 index 0000000..411be33 --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/t_tcpip.sh @@ -0,0 +1,273 @@ +# $NetBSD: t_tcpip.sh,v 1.18 2016/08/13 11:22:11 christos Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +rumpnetlibs="-lrumpnet -lrumpnet_net -lrumpnet_netinet6 -lrumpnet_netinet" +rumpnetsrv="rump_server $rumpnetlibs -lrumpdev" +export RUMP_SERVER=unix://csock + +atf_test_case http cleanup +http_head() +{ + atf_set "descr" "Start hijacked httpd and get webpage from it" +} + +http_body() +{ + + atf_check -s exit:0 ${rumpnetsrv} ${RUMP_SERVER} + + # start bozo in daemon mode + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + /usr/libexec/httpd -P ./httpd.pid -b -s $(atf_get_srcdir) + + atf_check -s exit:0 -o file:"$(atf_get_srcdir)/netstat.expout" \ + rump.netstat -a + + # get the webpage + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + $(atf_get_srcdir)/h_netget 127.0.0.1 80 webfile + + # check that we got what we wanted + atf_check -o match:'HTTP/1.0 200 OK' cat webfile + atf_check -o match:'Content-Length: 95' cat webfile + blank_line_re="$(printf '^\r$')" # matches a line with only + atf_check -o file:"$(atf_get_srcdir)/index.html" \ + sed -n "1,/${blank_line_re}/!p" webfile +} + +http_cleanup() +{ + if [ -f httpd.pid ]; then + kill -9 "$(cat httpd.pid)" + rm -f httpd.pid + fi + + rump.halt +} + +# +# Starts a SSH server and sets up the client to access it. +# Authentication is allowed and done using an RSA key exclusively, which +# is generated on the fly as part of the test case. +# XXX: Ideally, all the tests in this test program should be able to share +# the generated key, because creating it can be a very slow process on some +# machines. +# +# XXX2: copypasted from jmmv's sshd thingamob in the psshfs test. +# ideally code (and keys, like jmmv notes above) could be shared +# +start_sshd() { + echo "Setting up SSH server configuration" + sed -e "s,@SRCDIR@,$(atf_get_srcdir),g" -e "s,@WORKDIR@,$(pwd),g" \ + $(atf_get_srcdir)/sshd_config.in >sshd_config || \ + atf_fail "Failed to create sshd_config" + atf_check -s ignore -o empty -e ignore \ + cp $(atf_get_srcdir)/ssh_host_key . + atf_check -s ignore -o empty -e ignore \ + cp $(atf_get_srcdir)/ssh_host_key.pub . + atf_check -s eq:0 -o empty -e empty chmod 400 ssh_host_key + atf_check -s eq:0 -o empty -e empty chmod 444 ssh_host_key.pub + + env LD_PRELOAD=/usr/lib/librumphijack.so \ + /usr/sbin/sshd -e -f ./sshd_config + while [ ! -f sshd.pid ]; do + sleep 0.01 + done + echo "SSH server started (pid $(cat sshd.pid))" + + echo "Setting up SSH client configuration" + atf_check -s eq:0 -o empty -e empty \ + ssh-keygen -f ssh_user_key -t rsa -b 1024 -N "" -q + atf_check -s eq:0 -o empty -e empty \ + cp ssh_user_key.pub authorized_keys + echo "127.0.0.1,localhost,::1 " \ + "$(cat $(atf_get_srcdir)/ssh_host_key.pub)" >known_hosts || \ + atf_fail "Failed to create known_hosts" + atf_check -s eq:0 -o empty -e empty chmod 600 authorized_keys + sed -e "s,@SRCDIR@,$(atf_get_srcdir),g" -e "s,@WORKDIR@,$(pwd),g" \ + $(atf_get_srcdir)/ssh_config.in >ssh_config || \ + atf_fail "Failed to create ssh_config" + + echo "sshd running" +} + +atf_test_case ssh cleanup +ssh_head() +{ + atf_set "descr" "Test that hijacked ssh/sshd works" +} + +ssh_body() +{ + atf_expect_fail "PR lib/50174" + + atf_check -s exit:0 ${rumpnetsrv} ${RUMP_SERVER} + # make sure clients die after we nuke the server + export RUMPHIJACK_RETRYCONNECT='die' + + start_sshd + + # create some sort of directory for us to "ls" + mkdir testdir + cd testdir + jot 11 | xargs touch + jot 11 12 | xargs mkdir + cd .. + + atf_check -s exit:0 -o save:ssh.out \ + env LD_PRELOAD=/usr/lib/librumphijack.so \ + ssh -T -F ssh_config 127.0.0.1 env BLOCKSIZE=512 \ + ls -li $(pwd)/testdir + atf_check -s exit:0 -o file:ssh.out env BLOCKSIZE=512 \ + ls -li $(pwd)/testdir +} + +ssh_cleanup() +{ + rump.halt + # sshd dies due to RUMPHIJACK_RETRYCONNECT=1d6 +} + +test_nfs() +{ + + magicstr='wind in my hair' + # create ffs file system we'll be serving from + atf_check -s exit:0 -o ignore newfs -F -s 10000 ffs.img + + # start nfs kernel server. this is a mouthful + export RUMP_SERVER=unix://serversock + atf_check -s exit:0 rump_server $* ${RUMP_SERVER} + + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.1.1.1 + + export RUMPHIJACK_RETRYCONNECT=die + export LD_PRELOAD=/usr/lib/librumphijack.so + + atf_check -s exit:0 mkdir -p /rump/var/run + atf_check -s exit:0 mkdir -p /rump/var/db + atf_check -s exit:0 touch /rump/var/db/mountdtab + atf_check -s exit:0 mkdir /rump/etc + atf_check -s exit:0 mkdir /rump/export + + atf_check -s exit:0 -x \ + 'echo "/export -noresvport -noresvmnt 10.1.1.100" | \ + dd of=/rump/etc/exports 2> /dev/null' + + atf_check -s exit:0 rump.sysctl -q -w kern.module.autoload=1 + + atf_check -s exit:0 -e ignore mount_ffs /dk /rump/export + atf_check -s exit:0 -x "echo ${magicstr} > /rump/export/im_alive" + + # start rpcbind. we want /var/run/rpcbind.sock + export RUMPHIJACK='blanket=/var/run,socket=all' + atf_check -s exit:0 rpcbind + + # ok, then we want mountd in the similar fashion + export RUMPHIJACK='blanket=/var/run:/var/db:/export,socket=all,path=/rump,vfs=all' + atf_check -s exit:0 mountd /rump/etc/exports + + # finally, le nfschuck + export RUMPHIJACK='blanket=/var/run,socket=all,vfs=all' + atf_check -s exit:0 nfsd + + # + # now, time for the client server and associated madness. + # + + export RUMP_SERVER=unix://clientsock + unset RUMPHIJACK + unset LD_PRELOAD + + # at least the kernel server is easier + atf_check -s exit:0 rump_server -lrumpvfs -lrumpnet -lrumpdev \ + -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpfs_nfs\ + ${RUMP_SERVER} + + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.1.1.100 + + export LD_PRELOAD=/usr/lib/librumphijack.so + + atf_check -s exit:0 mkdir /rump/mnt + atf_check -s exit:0 mount_nfs 10.1.1.1:/export /rump/mnt + + atf_check -s exit:0 -o inline:"${magicstr}\n" cat /rump/mnt/im_alive + atf_check -s exit:0 -o match:'.*im_alive$' ls -l /rump/mnt/im_alive +} + + +atf_test_case nfs cleanup +nfs_head() +{ + atf_set "descr" "Test hijacked nfsd and mount_nfs" +} + +nfs_body() +{ + test_nfs -lrumpvfs -lrumpdev -lrumpnet -lrumpnet_net \ + -lrumpnet_netinet -lrumpnet_local -lrumpnet_shmif -lrumpdev \ + -lrumpdev_disk -lrumpfs_ffs -lrumpfs_nfs -lrumpfs_nfsserver \ + -d key=/dk,hostpath=ffs.img,size=host +} + +nfs_cleanup() +{ + RUMP_SERVER=unix://serversock rump.halt 2> /dev/null + RUMP_SERVER=unix://clientsock rump.halt 2> /dev/null + : +} + +atf_test_case nfs_autoload cleanup +nfs_autoload_head() +{ + atf_set "descr" "Test hijacked nfsd with autoload from /stand" +} + +nfs_autoload_body() +{ + [ `uname -m` = "i386" ] || atf_skip "test currently valid only on i386" + test_nfs -lrumpvfs -lrumpdev -lrumpnet -lrumpnet_net \ + -lrumpnet_netinet -lrumpnet_local -lrumpnet_shmif -lrumpdev \ + -lrumpdev_disk -d key=/dk,hostpath=ffs.img,size=host +} + +nfs_autoload_cleanup() +{ + nfs_cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case http + atf_add_test_case ssh + atf_add_test_case nfs + atf_add_test_case nfs_autoload +} diff --git a/contrib/netbsd-tests/lib/librumphijack/t_vfs.sh b/contrib/netbsd-tests/lib/librumphijack/t_vfs.sh new file mode 100755 index 0000000..c803e2a --- /dev/null +++ b/contrib/netbsd-tests/lib/librumphijack/t_vfs.sh @@ -0,0 +1,223 @@ +# $NetBSD: t_vfs.sh,v 1.6 2012/08/04 03:56:47 riastradh Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +img=ffs.img +rumpsrv_ffs=\ +"rump_server -lrumpvfs -lrumpfs_ffs -lrumpdev_disk -d key=/img,hostpath=${img},size=host" +export RUMP_SERVER=unix://csock + +domount() +{ + + mntdir=$1 + [ $# -eq 0 ] && mntdir=/rump/mnt + atf_check -s exit:0 -e ignore mount_ffs /img ${mntdir} +} + +dounmount() +{ + + atf_check -s exit:0 umount -R ${mntdir} +} + +remount() +{ + + dounmount + domount /rump/mnt2 +} + +simpletest() +{ + local name="${1}"; shift + + atf_test_case "${name}" cleanup + eval "${name}_head() { }" + eval "${name}_body() { \ + atf_check -s exit:0 rump_server -lrumpvfs ${RUMP_SERVER} ; \ + export LD_PRELOAD=/usr/lib/librumphijack.so ; \ + ${name} " "${@}" "; \ + }" + eval "${name}_cleanup() { \ + rump.halt + }" +} + +test_case() +{ + local name="${1}"; shift + + atf_test_case "${name}" cleanup + eval "${name}_head() { }" + eval "${name}_body() { \ + atf_check -s exit:0 -o ignore newfs -F -s 20000 ${img} ; \ + atf_check -s exit:0 ${rumpsrv_ffs} ${RUMP_SERVER} ; \ + export LD_PRELOAD=/usr/lib/librumphijack.so ; \ + mkdir /rump/mnt /rump/mnt2 ; \ + domount ; \ + ${name} " "${@}" "; \ + dounmount ${mntdir} + }" + eval "${name}_cleanup() { \ + rump.halt + }" +} + +test_case paxcopy +test_case cpcopy +test_case mv_nox +test_case ln_nox + +# +# use rumphijack to cp/pax stuff onto an image, unmount it, remount it +# at a different location, and check that we have an identical copy +# (we make a local copy to avoid the minor possibility that someone +# modifies the source dir data while the test is running) +# +paxcopy() +{ + parent=$(dirname $(atf_get_srcdir)) + thedir=$(basename $(atf_get_srcdir)) + atf_check -s exit:0 pax -rw -s,${parent},, $(atf_get_srcdir) . + atf_check -s exit:0 pax -rw ${thedir} /rump/mnt + remount + atf_check -s exit:0 diff -ru ${thedir} /rump/mnt2/${thedir} +} + +cpcopy() +{ + thedir=$(basename $(atf_get_srcdir)) + atf_check -s exit:0 cp -Rp $(atf_get_srcdir) . + atf_check -s exit:0 cp -Rp ${thedir} /rump/mnt + remount + atf_check -s exit:0 diff -ru ${thedir} /rump/mnt2/${thedir} +} + +# +# non-crosskernel mv (non-simple test since this uses rename(2) +# which is not supported by rumpfs) +# + +mv_nox() +{ + # stat default format sans changetime and filename + statstr='%d %i %Sp %l %Su %Sg %r %z \"%Sa\" \"%Sm\" \"%SB\" %k %b %#Xf' + + atf_check -s exit:0 touch /rump/mnt/filename + atf_check -s exit:0 -o save:stat.out \ + stat -f "${statstr}" /rump/mnt/filename + atf_check -s exit:0 mkdir /rump/mnt/dir + atf_check -s exit:0 mv /rump/mnt/filename /rump/mnt/dir/same + atf_check -s exit:0 -o file:stat.out \ + stat -f "${statstr}" /rump/mnt/dir/same +} + +ln_nox() +{ + # Omit st_nlink too, since it will increase. + statstr='%d %i %Sp %Su %Sg %r %z \"%Sa\" \"%Sm\" \"%SB\" %k %b %#Xf' + + atf_check -s exit:0 touch /rump/mnt/filename + atf_check -s exit:0 -o save:stat.out \ + stat -f "${statstr}" /rump/mnt/filename + atf_check -s exit:0 mkdir /rump/mnt/dir + atf_check -s exit:0 ln /rump/mnt/filename /rump/mnt/dir/same + atf_check -s exit:0 -o file:stat.out \ + stat -f "${statstr}" /rump/mnt/filename + atf_check -s exit:0 -o file:stat.out \ + stat -f "${statstr}" /rump/mnt/dir/same +} + +simpletest mv_x +simpletest ln_x +simpletest runonprefix +simpletest blanket +simpletest doubleblanket + +# +# do a cross-kernel mv +# +mv_x() +{ + thedir=$(basename $(atf_get_srcdir)) + atf_check -s exit:0 cp -Rp $(atf_get_srcdir) . + atf_check -s exit:0 cp -Rp ${thedir} ${thedir}.2 + atf_check -s exit:0 mv ${thedir} /rump + atf_check -s exit:0 diff -ru ${thedir}.2 /rump/${thedir} +} + +# +# Fail to make a cross-kernel hard link. +# +ln_x() +{ + atf_check -s exit:0 touch ./loser + atf_check -s not-exit:0 -e ignore ln ./loser /rump/. +} + +runonprefix() +{ + atf_check -s exit:0 -o ignore stat /rump/dev + atf_check -s exit:1 -e ignore stat /rumpdev +} + +blanket() +{ + export RUMPHIJACK='blanket=/dev,path=/rump' + atf_check -s exit:0 -o save:stat.out \ + stat -f "${statstr}" /rump/dev/null + atf_check -s exit:0 -o file:stat.out \ + stat -f "${statstr}" /dev/null +} + +doubleblanket() +{ + atf_check -s exit:0 mkdir /rump/dir + atf_check -s exit:0 ln -s dir /rump/dirtoo + + export RUMPHIJACK='blanket=/dirtoo:/dir' + atf_check -s exit:0 touch /dir/file + + atf_check -s exit:0 -o save:stat.out \ + stat -f "${statstr}" /dir/file + atf_check -s exit:0 -o file:stat.out \ + stat -f "${statstr}" /dirtoo/file +} + +atf_init_test_cases() +{ + + atf_add_test_case paxcopy + atf_add_test_case cpcopy + atf_add_test_case mv_x + atf_add_test_case ln_x + atf_add_test_case mv_nox + atf_add_test_case ln_nox + atf_add_test_case runonprefix + atf_add_test_case blanket + atf_add_test_case doubleblanket +} diff --git a/contrib/netbsd-tests/lib/libskey/t_algorithms.c b/contrib/netbsd-tests/lib/libskey/t_algorithms.c new file mode 100644 index 0000000..2eec278 --- /dev/null +++ b/contrib/netbsd-tests/lib/libskey/t_algorithms.c @@ -0,0 +1,121 @@ +/* $NetBSD: t_algorithms.c,v 1.1 2010/07/16 13:56:32 jmmv Exp $ */ + +/* + * Copyright (c) 2000, 2008, 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_algorithms.c,v 1.1 2010/07/16 13:56:32 jmmv Exp $"); + +#include +#include +#include + +#include + +#define H_REQUIRE(x, y) \ + ATF_REQUIRE_MSG(strcasecmp((x), (y)) == 0, "\"%s\" != \"%s\"", (x), (y)) + +static void +h_check(const char *pass, const char *seed, + const char *algo, const char *zero, + const char *one, const char *nine) +{ + char prn[64]; + char data[16]; + int i; + + skey_set_algorithm(algo); + + keycrunch(data, seed, pass); + btoa8(prn, data); + H_REQUIRE(prn, zero); + + f(data); + btoa8(prn, data); + H_REQUIRE(prn, one); + + for(i = 1; i < 99; ++i) + f(data); + btoa8(prn, data); + H_REQUIRE(prn, nine); +} + +ATF_TC(md4); +ATF_TC_HEAD(md4, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks MD4 algorithm"); +} +ATF_TC_BODY(md4, tc) +{ + h_check("This is a test.", "TeSt", "md4", "D1854218EBBB0B51", + "63473EF01CD0B444", "C5E612776E6C237A"); + h_check("AbCdEfGhIjK", "alpha1", "md4", "50076F47EB1ADE4E", + "65D20D1949B5F7AB", "D150C82CCE6F62D1"); + h_check("OTP's are good", "correct", "md4", "849C79D4F6F55388", + "8C0992FB250847B1", "3F3BF4B4145FD74B"); +} + +ATF_TC(md5); +ATF_TC_HEAD(md5, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks MD5 algorithm"); +} +ATF_TC_BODY(md5, tc) +{ + h_check("This is a test.", "TeSt", "md5", "9E876134D90499DD", + "7965E05436F5029F", "50FE1962C4965880"); + h_check("AbCdEfGhIjK", "alpha1", "md5", "87066DD9644BF206", + "7CD34C1040ADD14B", "5AA37A81F212146C"); + h_check("OTP's are good", "correct", "md5", "F205753943DE4CF9", + "DDCDAC956F234937", "B203E28FA525BE47"); +} + +ATF_TC(sha1); +ATF_TC_HEAD(sha1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks SHA1 algorithm"); +} +ATF_TC_BODY(sha1, tc) +{ + h_check("This is a test.", "TeSt", "sha1","BB9E6AE1979D8FF4", + "63D936639734385B", "87FEC7768B73CCF9"); + h_check("AbCdEfGhIjK", "alpha1", "sha1","AD85F658EBE383C9", + "D07CE229B5CF119B", "27BC71035AAF3DC6"); + h_check("OTP's are good", "correct", "sha1","D51F3E99BF8E6F0B", + "82AEB52D943774E4", "4F296A74FE1567EC"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, md4); + ATF_TP_ADD_TC(tp, md5); + ATF_TP_ADD_TC(tp, sha1); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libsljit/t_sljit.sh b/contrib/netbsd-tests/lib/libsljit/t_sljit.sh new file mode 100755 index 0000000..50fb860 --- /dev/null +++ b/contrib/netbsd-tests/lib/libsljit/t_sljit.sh @@ -0,0 +1,45 @@ +# $NetBSD: t_sljit.sh,v 1.1 2012/11/05 00:34:28 alnsn Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Alexander Nasonov. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case sljit +sljit_head() { + + atf_set "descr" "Run sljit unit tests." +} + +sljit_body() { + + $(atf_get_srcdir)/h_sljit 2>&1 || atf_fail "check report" +} + +atf_init_test_cases() { + + atf_add_test_case sljit +} diff --git a/contrib/netbsd-tests/lib/libusbhid/hid_test_data.c b/contrib/netbsd-tests/lib/libusbhid/hid_test_data.c new file mode 100644 index 0000000..dedcb11 --- /dev/null +++ b/contrib/netbsd-tests/lib/libusbhid/hid_test_data.c @@ -0,0 +1,137 @@ +/* $NetBSD: hid_test_data.c,v 1.2 2016/01/07 15:58:23 jakllsch Exp $ */ + +/* + * Copyright (c) 2016 Jonathan A. Kollasch + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ + +static const uint8_t range_test_report_descriptor[] = { + 0x0b, 0x03, 0x00, 0x00, 0xff, // Usage + 0x75, 0x20, // Report Size + 0x95, 0x01, // Report Count + 0x17, 0x00, 0x00, 0x00, 0x80, // Logical Minimum + 0x27, 0xff, 0xff, 0xff, 0x7f, // Logical Maximum + 0x37, 0x00, 0x00, 0x00, 0x80, // Physical Minimum + 0x47, 0xff, 0xff, 0xff, 0x7f, // Physical Maximum + 0x81, 0x00, // Input + + 0x0b, 0x02, 0x00, 0x00, 0xff, // Usage + 0x75, 0x10, // Report Size + 0x95, 0x01, // Report Count + 0x16, 0x00, 0x80, // Logical Minimum + 0x26, 0xff, 0x7f, // Logical Maximum + 0x36, 0x00, 0x80, // Physical Minimum + 0x46, 0xff, 0x7f, // Physical Maximum + 0x81, 0x00, // Input + + 0x0b, 0x01, 0x00, 0x00, 0xff, // Usage + 0x75, 0x08, // Report Size + 0x95, 0x01, // Report Count + 0x15, 0x80, // Logical Minimum + 0x25, 0x7f, // Logical Maximum + 0x35, 0x80, // Physical Minimum + 0x45, 0x7f, // Physical Maximum + 0x81, 0x00, // Input +}; + +static const uint8_t range_test_minimum_report[7] = { + 0x00, 0x00, 0x00, 0x80, + 0x00, 0x80, + 0x80, +}; + +static const uint8_t range_test_negative_one_report[7] = { + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, + 0xff, +}; + +static const uint8_t range_test_positive_one_report[7] = { + 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, + 0x01, +}; + +static const uint8_t range_test_maximum_report[7] = { + 0xff, 0xff, 0xff, 0x7f, + 0xff, 0x7f, + 0x7f, +}; + +static const uint8_t unsigned_range_test_report_descriptor[] = { + 0x0b, 0x13, 0x00, 0x00, 0xff, // Usage + 0x75, 0x20, // Report Size + 0x95, 0x01, // Report Count + 0x17, 0x00, 0x00, 0x00, 0x00, // Logical Minimum + 0x27, 0xff, 0xff, 0xff, 0xff, // Logical Maximum + 0x37, 0x00, 0x00, 0x00, 0x00, // Physical Minimum + 0x47, 0xff, 0xff, 0xff, 0xff, // Physical Maximum + 0x81, 0x00, // Input + + 0x0b, 0x12, 0x00, 0x00, 0xff, // Usage + 0x75, 0x10, // Report Size + 0x95, 0x01, // Report Count + 0x16, 0x00, 0x00, // Logical Minimum + 0x26, 0xff, 0xff, // Logical Maximum + 0x36, 0x00, 0x00, // Physical Minimum + 0x46, 0xff, 0xff, // Physical Maximum + 0x81, 0x00, // Input + + 0x0b, 0x11, 0x00, 0x00, 0xff, // Usage + 0x75, 0x08, // Report Size + 0x95, 0x01, // Report Count + 0x15, 0x00, // Logical Minimum + 0x25, 0xff, // Logical Maximum + 0x35, 0x00, // Physical Minimum + 0x45, 0xff, // Physical Maximum + 0x81, 0x00, // Input +}; + +static const uint8_t unsigned_range_test_minimum_report[7] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + 0x00, +}; + +static const uint8_t unsigned_range_test_positive_one_report[7] = { + 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, + 0x01, +}; + +static const uint8_t unsigned_range_test_negative_one_report[7] = { + 0xfe, 0xff, 0xff, 0xff, + 0xfe, 0xff, + 0xfe, +}; + +static const uint8_t unsigned_range_test_maximum_report[7] = { + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, + 0xff, +}; + +static const uint8_t just_pop_report_descriptor[] = { + 0xb4, +}; diff --git a/contrib/netbsd-tests/lib/libusbhid/t_usbhid.c b/contrib/netbsd-tests/lib/libusbhid/t_usbhid.c new file mode 100644 index 0000000..2766da2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libusbhid/t_usbhid.c @@ -0,0 +1,452 @@ +/* $NetBSD: t_usbhid.c,v 1.12 2016/08/17 12:10:42 jakllsch Exp $ */ + +/* + * Copyright (c) 2016 Jonathan A. Kollasch + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 +__RCSID("$NetBSD: t_usbhid.c,v 1.12 2016/08/17 12:10:42 jakllsch Exp $"); + +#include + +#include +#include +#include + +#include +#include + +#include + +ATF_TC(check_hid_logical_range); +ATF_TC(check_hid_physical_range); +ATF_TC(check_hid_usage); +ATF_TC(check_hid_get_data); +ATF_TC(check_hid_set_data); +ATF_TC(check_parse_just_pop); + +#define MYd_ATF_CHECK_EQ(d, v) \ + ATF_CHECK_EQ_MSG(d, v, "== %d", (d)) + +#define MYu_ATF_CHECK_EQ(d, v) \ + ATF_CHECK_EQ_MSG(d, v, "== %u", (d)) + +#define MYx_ATF_CHECK_EQ(d, v) \ + ATF_CHECK_EQ_MSG(d, v, "== 0x%x", (d)) + +#include "hid_test_data.c" + +ATF_TC_HEAD(check_hid_usage, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test libusbhid usage.c"); +} + +ATF_TC_BODY(check_hid_usage, tc) +{ + char usages_path[PATH_MAX]; + + (void)strlcpy(usages_path, atf_tc_get_config_var(tc, "srcdir"), + sizeof(usages_path)); + (void)strlcat(usages_path, "/test_usb_hid_usages", + sizeof(usages_path)); + + hid_init(usages_path); + + ATF_CHECK_STREQ("t_usbhid_page", hid_usage_page(0xff1b)); + ATF_CHECK_EQ((uint32_t)hid_parse_usage_page("t_usbhid_page"), 0xff1b); + + ATF_CHECK_STREQ("t_usbhid_usage", hid_usage_in_page(0xff1bff2a)); + ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page( + "t_usbhid_page:t_usbhid_usage"), 0xff1bff2a); + + ATF_CHECK_STREQ("Quick_zephyrs_blow_vexing_daft_Jim_", + hid_usage_page(0xff2a)); + ATF_CHECK_EQ((uint32_t)hid_parse_usage_page( + "Quick_zephyrs_blow_vexing_daft_Jim_"), 0xff2a); + + ATF_CHECK_STREQ("Usage_ID_Zero_%", hid_usage_in_page(0xff2a0000)); + ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page( + "Quick_zephyrs_blow_vexing_daft_Jim_:Usage_ID_Zero_%"), + 0xff2a0000); + + //ATF_CHECK_STREQ("Usage_ID_0_%", hid_usage_in_page(0xff2a0000)); + ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page( + "Quick_zephyrs_blow_vexing_daft_Jim_:Usage_ID_0_%"), 0xff2a0000); + + ATF_CHECK_STREQ("Usage_ID_65535_%", hid_usage_in_page(0xff2affff)); + ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page( + "Quick_zephyrs_blow_vexing_daft_Jim_:Usage_ID_65535_%"), + 0xff2affff); + + MYx_ATF_CHECK_EQ((uint32_t)hid_parse_usage_in_page("0xff2a:0xff1b"), + 0xff2aff1b); +} + +ATF_TC_HEAD(check_hid_logical_range, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test hid_get_item " + "Logical Minimum/Maximum results"); +} + +ATF_TC_BODY(check_hid_logical_range, tc) +{ + report_desc_t hrd; + hid_item_t hi; + uint32_t minimum, maximum; + + atf_tc_expect_fail("only the 32-bit opcode works, " + "8 and 16-bit is broken"); + + ATF_REQUIRE((hrd = hid_use_report_desc(range_test_report_descriptor, + __arraycount(range_test_report_descriptor))) != NULL); + ATF_REQUIRE(hid_locate(hrd, 0xff000001U, hid_input, &hi, + NO_REPORT_ID) > 0); + MYd_ATF_CHECK_EQ(hi.logical_minimum, -128); + MYd_ATF_CHECK_EQ(hi.logical_maximum, 127); + ATF_REQUIRE(hid_locate(hrd, 0xff000002U, hid_input, &hi, + NO_REPORT_ID) > 0); + MYd_ATF_CHECK_EQ(hi.logical_minimum, -32768); + MYd_ATF_CHECK_EQ(hi.logical_maximum, 32767); + ATF_REQUIRE(hid_locate(hrd, 0xff000003U, hid_input, &hi, + NO_REPORT_ID) > 0); + MYd_ATF_CHECK_EQ(hi.logical_minimum, -2147483648); + MYd_ATF_CHECK_EQ(hi.logical_maximum, 2147483647); + + hid_dispose_report_desc(hrd); + hrd = NULL; + + ATF_REQUIRE((hrd = hid_use_report_desc( + unsigned_range_test_report_descriptor, + __arraycount(unsigned_range_test_report_descriptor))) != NULL); + ATF_REQUIRE(hid_locate(hrd, 0xff000011U, hid_input, &hi, + NO_REPORT_ID) > 0); + ATF_CHECK(hi.logical_minimum > hi.logical_maximum); + minimum = (uint32_t)hi.logical_minimum & ((1ULL< 0); + ATF_CHECK(hi.logical_minimum > hi.logical_maximum); + minimum = hi.logical_minimum & ((1ULL< 0); + ATF_CHECK(hi.logical_minimum > hi.logical_maximum); + minimum = hi.logical_minimum & ((1ULL< 0); + MYd_ATF_CHECK_EQ(hi.physical_minimum, -128); + MYd_ATF_CHECK_EQ(hi.physical_maximum, 127); + ATF_REQUIRE(hid_locate(hrd, 0xff000002U, hid_input, &hi, + NO_REPORT_ID) > 0); + MYd_ATF_CHECK_EQ(hi.physical_minimum, -32768); + MYd_ATF_CHECK_EQ(hi.physical_maximum, 32767); + ATF_REQUIRE(hid_locate(hrd, 0xff000003U, hid_input, &hi, + NO_REPORT_ID) > 0); + MYd_ATF_CHECK_EQ(hi.physical_minimum, -2147483648); + MYd_ATF_CHECK_EQ(hi.physical_maximum, 2147483647); + + hid_dispose_report_desc(hrd); + hrd = NULL; + + ATF_REQUIRE((hrd = hid_use_report_desc( + unsigned_range_test_report_descriptor, + __arraycount(unsigned_range_test_report_descriptor))) != NULL); + ATF_REQUIRE(hid_locate(hrd, 0xff000011U, hid_input, &hi, + NO_REPORT_ID) > 0); + ATF_CHECK(hi.physical_minimum > hi.physical_maximum); + minimum = (uint32_t)hi.physical_minimum & ((1ULL< 0); + ATF_CHECK(hi.physical_minimum > hi.physical_maximum); + minimum = hi.physical_minimum & ((1ULL< 0); + ATF_CHECK(hi.physical_minimum > hi.physical_maximum); + minimum = hi.physical_minimum & ((1ULL< 0); + data = hid_get_data(range_test_minimum_report, &hi); + MYd_ATF_CHECK_EQ(data, -128); + data = hid_get_data(range_test_negative_one_report, &hi); + MYd_ATF_CHECK_EQ(data, -1); + data = hid_get_data(range_test_positive_one_report, &hi); + MYd_ATF_CHECK_EQ(data, 1); + data = hid_get_data(range_test_maximum_report, &hi); + MYd_ATF_CHECK_EQ(data, 127); + + ATF_REQUIRE(hid_locate(hrd, 0xff000002U, hid_input, &hi, + NO_REPORT_ID) > 0); + data = hid_get_data(range_test_minimum_report, &hi); + MYd_ATF_CHECK_EQ(data, -32768); + data = hid_get_data(range_test_negative_one_report, &hi); + MYd_ATF_CHECK_EQ(data, -1); + data = hid_get_data(range_test_positive_one_report, &hi); + MYd_ATF_CHECK_EQ(data, 1); + data = hid_get_data(range_test_maximum_report, &hi); + MYd_ATF_CHECK_EQ(data, 32767); + + ATF_REQUIRE(hid_locate(hrd, 0xff000003U, hid_input, &hi, + NO_REPORT_ID) > 0); + data = hid_get_data(range_test_minimum_report, &hi); + MYd_ATF_CHECK_EQ(data, -2147483648); + data = hid_get_data(range_test_negative_one_report, &hi); + MYd_ATF_CHECK_EQ(data, -1); + data = hid_get_data(range_test_positive_one_report, &hi); + MYd_ATF_CHECK_EQ(data, 1); + data = hid_get_data(range_test_maximum_report, &hi); + MYd_ATF_CHECK_EQ(data, 2147483647); + + hid_dispose_report_desc(hrd); + hrd = NULL; + + ATF_REQUIRE((hrd = hid_use_report_desc( + unsigned_range_test_report_descriptor, + __arraycount(unsigned_range_test_report_descriptor))) != NULL); + ATF_REQUIRE(hid_locate(hrd, 0xff000011U, hid_input, &hi, + NO_REPORT_ID) > 0); + udat = hid_get_data(unsigned_range_test_minimum_report, &hi); + MYu_ATF_CHECK_EQ(udat, 0); + udat = hid_get_data(unsigned_range_test_positive_one_report, &hi); + MYu_ATF_CHECK_EQ(udat, 1); + udat = hid_get_data(unsigned_range_test_negative_one_report, &hi); + MYu_ATF_CHECK_EQ(udat, 254); + udat = hid_get_data(unsigned_range_test_maximum_report, &hi); + MYu_ATF_CHECK_EQ(udat, 255); + + ATF_REQUIRE(hid_locate(hrd, 0xff000012U, hid_input, &hi, + NO_REPORT_ID) > 0); + udat = hid_get_data(unsigned_range_test_minimum_report, &hi); + MYu_ATF_CHECK_EQ(udat, 0); + udat = hid_get_data(unsigned_range_test_positive_one_report, &hi); + MYu_ATF_CHECK_EQ(udat, 1); + udat = hid_get_data(unsigned_range_test_negative_one_report, &hi); + MYu_ATF_CHECK_EQ(udat, 65534); + udat = hid_get_data(unsigned_range_test_maximum_report, &hi); + MYu_ATF_CHECK_EQ(udat, 65535); + + ATF_REQUIRE(hid_locate(hrd, 0xff000013U, hid_input, &hi, + NO_REPORT_ID) > 0); + udat = hid_get_data(unsigned_range_test_minimum_report, &hi); + MYu_ATF_CHECK_EQ(udat, 0); + udat = hid_get_data(unsigned_range_test_positive_one_report, &hi); + MYu_ATF_CHECK_EQ(udat, 1); + udat = hid_get_data(unsigned_range_test_negative_one_report, &hi); + MYu_ATF_CHECK_EQ(udat, 4294967294); + udat = hid_get_data(unsigned_range_test_maximum_report, &hi); + MYu_ATF_CHECK_EQ(udat, 4294967295); + + hid_dispose_report_desc(hrd); + hrd = NULL; +} + +ATF_TC_HEAD(check_hid_set_data, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test hid_set_data results"); +} + +ATF_TC_BODY(check_hid_set_data, tc) +{ + report_desc_t hrd; + hid_item_t hi; + uint8_t test_data_minimum[7]; + uint8_t test_data_negative_one[7]; + uint8_t test_data_positive_one[7]; + uint8_t test_data_maximum[7]; + + ATF_REQUIRE((hrd = hid_use_report_desc( + range_test_report_descriptor, + __arraycount(range_test_report_descriptor))) != NULL); + ATF_REQUIRE(hid_locate(hrd, 0xff000001U, hid_input, &hi, + NO_REPORT_ID) > 0); + hid_set_data(test_data_minimum, &hi, -128); + hid_set_data(test_data_negative_one, &hi, -1); + hid_set_data(test_data_positive_one, &hi, 1); + hid_set_data(test_data_maximum, &hi, 127); + ATF_REQUIRE(hid_locate(hrd, 0xff000002U, hid_input, &hi, + NO_REPORT_ID) > 0); + hid_set_data(test_data_minimum, &hi, -32768); + hid_set_data(test_data_negative_one, &hi, -1); + hid_set_data(test_data_positive_one, &hi, 1); + hid_set_data(test_data_maximum, &hi, 32767); + ATF_REQUIRE(hid_locate(hrd, 0xff000003U, hid_input, &hi, + NO_REPORT_ID) > 0); + hid_set_data(test_data_minimum, &hi, -2147483648); + hid_set_data(test_data_negative_one, &hi, -1); + hid_set_data(test_data_positive_one, &hi, 1); + hid_set_data(test_data_maximum, &hi, 2147483647); + ATF_CHECK(memcmp(test_data_minimum, range_test_minimum_report, + sizeof test_data_minimum) == 0); + ATF_CHECK(memcmp(test_data_negative_one, + range_test_negative_one_report, + sizeof test_data_negative_one) == 0); + ATF_CHECK(memcmp(test_data_positive_one, + range_test_positive_one_report, + sizeof test_data_positive_one) == 0); + ATF_CHECK(memcmp(test_data_maximum, range_test_maximum_report, + sizeof test_data_maximum) == 0); + + hid_dispose_report_desc(hrd); + hrd = NULL; + + ATF_REQUIRE((hrd = hid_use_report_desc( + unsigned_range_test_report_descriptor, + __arraycount(range_test_report_descriptor))) != NULL); + ATF_REQUIRE(hid_locate(hrd, 0xff000011U, hid_input, &hi, + NO_REPORT_ID) > 0); + hid_set_data(test_data_minimum, &hi, 0); + hid_set_data(test_data_positive_one, &hi, 1); + hid_set_data(test_data_negative_one, &hi, 0xfffffffe); + hid_set_data(test_data_maximum, &hi, 0xffffffff); + ATF_REQUIRE(hid_locate(hrd, 0xff000012U, hid_input, &hi, + NO_REPORT_ID) > 0); + hid_set_data(test_data_minimum, &hi, 0); + hid_set_data(test_data_positive_one, &hi, 1); + hid_set_data(test_data_negative_one, &hi, 0xfffe); + hid_set_data(test_data_maximum, &hi, 0xffff); + ATF_REQUIRE(hid_locate(hrd, 0xff000013U, hid_input, &hi, + NO_REPORT_ID) > 0); + hid_set_data(test_data_minimum, &hi, 0); + hid_set_data(test_data_positive_one, &hi, 1); + hid_set_data(test_data_negative_one, &hi, 0xfffffffe); + hid_set_data(test_data_maximum, &hi, 0xffffffff); + ATF_CHECK(memcmp(test_data_minimum, + unsigned_range_test_minimum_report, + sizeof test_data_minimum) == 0); + ATF_CHECK(memcmp(test_data_negative_one, + unsigned_range_test_negative_one_report, + sizeof test_data_negative_one) == 0); + ATF_CHECK(memcmp(test_data_positive_one, + unsigned_range_test_positive_one_report, + sizeof test_data_positive_one) == 0); + ATF_CHECK(memcmp(test_data_maximum, + unsigned_range_test_maximum_report, + sizeof test_data_maximum) == 0); + + hid_dispose_report_desc(hrd); + hrd = NULL; +} + +ATF_TC_HEAD(check_parse_just_pop, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check Pop on empty stack bug"); +} + +ATF_TC_BODY(check_parse_just_pop, tc) +{ + report_desc_t hrd; + hid_data_t hd; + hid_item_t hi; + + ATF_REQUIRE((hrd = hid_use_report_desc( + just_pop_report_descriptor, + sizeof just_pop_report_descriptor)) != NULL); + hd = hid_start_parse(hrd, 0, NO_REPORT_ID); + while (hid_get_item(hd, &hi) > 0) { + } + hid_end_parse(hd); + hid_dispose_report_desc(hrd); + hrd = NULL; +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, check_hid_logical_range); + ATF_TP_ADD_TC(tp, check_hid_physical_range); + ATF_TP_ADD_TC(tp, check_hid_usage); + ATF_TP_ADD_TC(tp, check_hid_get_data); + ATF_TP_ADD_TC(tp, check_hid_set_data); + ATF_TP_ADD_TC(tp, check_parse_just_pop); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libusbhid/test_usb_hid_usages b/contrib/netbsd-tests/lib/libusbhid/test_usb_hid_usages new file mode 100644 index 0000000..2444ef2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libusbhid/test_usb_hid_usages @@ -0,0 +1,17 @@ +# $NetBSD: test_usb_hid_usages,v 1.1 2016/01/01 21:38:54 jakllsch Exp $ +# +# USB HID usage table (for t_usbhid) +# Syntax: +# - lines that do not start with a white space give the number and name of +# a usage page. +# - lines that start with a white space give the number and name of +# a usage with the last given page. +# If the number is * then the line matches all usages and the name +# is a printf formatting string that will be given the usage number. +# +0xff1b t_usbhid page + 0xff2a t_usbhid usage + +0xff2a Quick zephyrs blow vexing daft Jim. + 0 Usage ID Zero % + * Usage ID %u %% diff --git a/contrib/netbsd-tests/lib/libutil/t_efun.c b/contrib/netbsd-tests/lib/libutil/t_efun.c new file mode 100644 index 0000000..f5187f2 --- /dev/null +++ b/contrib/netbsd-tests/lib/libutil/t_efun.c @@ -0,0 +1,135 @@ +/* $NetBSD: t_efun.c,v 1.3 2012/11/04 23:37:02 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_efun.c,v 1.3 2012/11/04 23:37:02 christos Exp $"); + +#include + +#include +#include +#include +#include + +static bool fail; +static void handler(int, const char *, ...); + +static void +handler(int ef, const char *fmt, ...) +{ + fail = false; +} + +ATF_TC(ecalloc); +ATF_TC_HEAD(ecalloc, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of ecalloc(3)"); +} + +ATF_TC_BODY(ecalloc, tc) +{ + char *x; + + fail = true; + x = ecalloc(-1, 1); + + ATF_REQUIRE(x == NULL); + ATF_REQUIRE(fail != true); + + fail = true; + x = ecalloc(SIZE_MAX, 2); + + ATF_REQUIRE(x == NULL); + ATF_REQUIRE(fail != true); +} + +ATF_TC(efopen); +ATF_TC_HEAD(efopen, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of efopen(3)"); +} + +ATF_TC_BODY(efopen, tc) +{ + FILE *f; + + fail = true; + f = efopen("XXX", "XXX"); + + ATF_REQUIRE(f == NULL); + ATF_REQUIRE(fail != true); +} + +ATF_TC(emalloc); +ATF_TC_HEAD(emalloc, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of emalloc(3)"); +} + +ATF_TC_BODY(emalloc, tc) +{ + char *x; + + fail = true; + x = emalloc(-1); + + ATF_REQUIRE(x == NULL); + ATF_REQUIRE(fail != true); +} + +ATF_TC(erealloc); +ATF_TC_HEAD(erealloc, tc) +{ + atf_tc_set_md_var(tc, "descr", "A basic test of erealloc(3)"); +} + +ATF_TC_BODY(erealloc, tc) +{ + char *x; + + fail = true; + x = erealloc(NULL, -1); + + ATF_REQUIRE(x == NULL); + ATF_REQUIRE(fail != true); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_REQUIRE(esetfunc(handler) != NULL); + + ATF_TP_ADD_TC(tp, ecalloc); + ATF_TP_ADD_TC(tp, efopen); + ATF_TP_ADD_TC(tp, emalloc); + ATF_TP_ADD_TC(tp, erealloc); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libutil/t_parsedate.c b/contrib/netbsd-tests/lib/libutil/t_parsedate.c new file mode 100644 index 0000000..c78df58 --- /dev/null +++ b/contrib/netbsd-tests/lib/libutil/t_parsedate.c @@ -0,0 +1,583 @@ +/* $NetBSD: t_parsedate.c,v 1.25 2016/06/22 15:01:38 kre Exp $ */ +/*- + * Copyright (c) 2010, 2015 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_parsedate.c,v 1.25 2016/06/22 15:01:38 kre Exp $"); + +#include +#include +#include +#include +#include +#include + +/* + * ANY is used as a placeholder for values that do not need to be + * checked. The actual value is arbitrary. We don't use -1 + * because some tests might want to use -1 as a literal value. + */ +#define ANY -30215 + +/* parsecheck -- + * call parsedate(), then call time_to_tm() on the result, + * and check that year/month/day/hour/minute/second are as expected. + * + * time_to_tm should usually be localtime_r or gmtime_r. + * + * Don't check values specified as ANY. + */ +static void +parsecheck(const char *datestr, const time_t *reftime, const int *zoff, + struct tm * time_to_tm(const time_t *, struct tm *), + int year, int month, int day, int hour, int minute, int second) +{ + time_t t; + struct tm tm; + char argstr[128]; + + /* + * printable version of the args. + * + * Note that printf("%.*d", 0, 0)) prints nothing at all, + * while printf("%.*d", 1, val) prints the value as usual. + */ + snprintf(argstr, sizeof(argstr), "%s%s%s, %s%.*jd, %s%.*d", + /* NULL or \"\" */ + (datestr ? "\"" : ""), + (datestr ? datestr : "NULL"), + (datestr ? "\"" : ""), + /* NULL or *reftime */ + (reftime ? "" : "NULL"), + (reftime ? 1 : 0), + (reftime ? (intmax_t)*reftime : (intmax_t)0), + /* NULL or *zoff */ + (zoff ? "" : "NULL"), + (zoff ? 1 : 0), + (zoff ? *zoff : 0)); + + ATF_CHECK_MSG((t = parsedate(datestr, reftime, zoff)) != -1, + "parsedate(%s) returned -1\n", argstr); + ATF_CHECK(time_to_tm(&t, &tm) != NULL); + if (year != ANY) + ATF_CHECK_MSG(tm.tm_year + 1900 == year, + "parsedate(%s) expected year %d got %d (+1900)\n", + argstr, year, (int)tm.tm_year); + if (month != ANY) + ATF_CHECK_MSG(tm.tm_mon + 1 == month, + "parsedate(%s) expected month %d got %d (+1)\n", + argstr, month, (int)tm.tm_mon); + if (day != ANY) + ATF_CHECK_MSG(tm.tm_mday == day, + "parsedate(%s) expected day %d got %d\n", + argstr, day, (int)tm.tm_mday); + if (hour != ANY) + ATF_CHECK_MSG(tm.tm_hour == hour, + "parsedate(%s) expected hour %d got %d\n", + argstr, hour, (int)tm.tm_hour); + if (minute != ANY) + ATF_CHECK_MSG(tm.tm_min == minute, + "parsedate(%s) expected minute %d got %d\n", + argstr, minute, (int)tm.tm_min); + if (second != ANY) + ATF_CHECK_MSG(tm.tm_sec == second, + "parsedate(%s) expected second %d got %d\n", + argstr, second, (int)tm.tm_sec); +} + +ATF_TC(dates); + +ATF_TC_HEAD(dates, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test unambiguous dates" + " (PR lib/44255)"); +} + +ATF_TC_BODY(dates, tc) +{ + + parsecheck("9/10/69", NULL, NULL, localtime_r, + 2069, 9, 10, 0, 0, 0); /* year < 70: add 2000 */ + parsecheck("9/10/70", NULL, NULL, localtime_r, + 1970, 9, 10, 0, 0, 0); /* 70 <= year < 100: add 1900 */ + parsecheck("69-09-10", NULL, NULL, localtime_r, + 69, 9, 10, 0, 0, 0); /* ISO8601 year remains unchanged */ + parsecheck("70-09-10", NULL, NULL, localtime_r, + 70, 9, 10, 0, 0, 0); /* ISO8601 year remains unchanged */ + parsecheck("2006-11-17", NULL, NULL, localtime_r, + 2006, 11, 17, 0, 0, 0); + parsecheck("10/1/2000", NULL, NULL, localtime_r, + 2000, 10, 1, 0, 0, 0); /* month/day/year */ + parsecheck("20 Jun 1994", NULL, NULL, localtime_r, + 1994, 6, 20, 0, 0, 0); + parsecheck("97 September 2", NULL, NULL, localtime_r, + 1997, 9, 2, 0, 0, 0); + parsecheck("23jun2001", NULL, NULL, localtime_r, + 2001, 6, 23, 0, 0, 0); + parsecheck("1-sep-06", NULL, NULL, localtime_r, + 2006, 9, 1, 0, 0, 0); + parsecheck("1/11", NULL, NULL, localtime_r, + ANY, 1, 11, 0, 0, 0); /* month/day */ + parsecheck("1500-01-02", NULL, NULL, localtime_r, + 1500, 1, 2, 0, 0, 0); + parsecheck("9999-12-21", NULL, NULL, localtime_r, + 9999, 12, 21, 0, 0, 0); + parsecheck("2015.12.07.08.07.35", NULL, NULL, localtime_r, + 2015, 12, 7, 8, 7, 35); +} + +ATF_TC(times); + +ATF_TC_HEAD(times, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test times" + " (PR lib/44255)"); +} + +ATF_TC_BODY(times, tc) +{ + + parsecheck("10:01", NULL, NULL, localtime_r, + ANY, ANY, ANY, 10, 1, 0); + parsecheck("10:12pm", NULL, NULL, localtime_r, + ANY, ANY, ANY, 22, 12, 0); + parsecheck("12:11:01.000012", NULL, NULL, localtime_r, + ANY, ANY, ANY, 12, 11, 1); + parsecheck("12:21-0500", NULL, NULL, gmtime_r, + ANY, ANY, ANY, 12+5, 21, 0); + /* numeric zones not permitted with am/pm ... */ + parsecheck("7 a.m. ICT", NULL, NULL, gmtime_r, + ANY, ANY, ANY, 7-7, 0, 0); + parsecheck("midnight", NULL, NULL, localtime_r, + ANY, ANY, ANY, 0, 0, 0); + parsecheck("mn", NULL, NULL, localtime_r, + ANY, ANY, ANY, 0, 0, 0); + parsecheck("noon", NULL, NULL, localtime_r, + ANY, ANY, ANY, 12, 0, 0); +} + +ATF_TC(dsttimes); + +ATF_TC_HEAD(dsttimes, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test DST transition times" + " (PR lib/47916)"); +} + +ATF_TC_BODY(dsttimes, tc) +{ + struct tm tm; + time_t t; + int tzoff; + + putenv(__UNCONST("TZ=EST")); + tzset(); + parsecheck("12:0", NULL, NULL, localtime_r, + ANY, ANY, ANY, 12, 0, 0); + + putenv(__UNCONST("TZ=Asia/Tokyo")); + tzset(); + parsecheck("12:0", NULL, NULL, localtime_r, + ANY, ANY, ANY, 12, 0, 0); + + /* + * When the effective local time is Tue Jul 9 13:21:53 BST 2013, + * check mktime("14:00") + */ + putenv(__UNCONST("TZ=Europe/London")); + tzset(); + tm = (struct tm){ + .tm_year = 2013-1900, .tm_mon = 7-1, .tm_mday = 9, + .tm_hour = 13, .tm_min = 21, .tm_sec = 53, + .tm_isdst = 0 }; + t = mktime(&tm); + ATF_CHECK(t != (time_t)-1); + parsecheck("14:00", &t, NULL, localtime_r, + 2013, 7, 9, 14, 0, 0); + tzoff = -60; /* British Summer Time */ + parsecheck("14:00", &t, &tzoff, localtime_r, + 2013, 7, 9, 14, 0, 0); +} + +ATF_TC(relative); + +ATF_TC_HEAD(relative, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test relative items" + " (PR lib/44255)"); +} + +ATF_TC_BODY(relative, tc) +{ + struct tm tm; + time_t now; + +#define REL_CHECK(s, now, tm) do { \ + time_t p, q; \ + char nb[30], pb[30], qb[30]; \ + p = parsedate(s, &now, NULL); \ + q = mktime(&tm); \ + ATF_CHECK_EQ_MSG(p, q, \ + "From %jd (%24.24s) using \"%s\", obtained %jd (%24.24s); expected %jd (%24.24s)", \ + (uintmax_t)now, ctime_r(&now, nb), \ + s, (uintmax_t)p, ctime_r(&p, pb), (uintmax_t)q, \ + ctime_r(&q, qb)); \ + } while (/*CONSTCOND*/0) + +#define isleap(yr) (((yr) & 3) == 0 && (((yr) % 100) != 0 || \ + ((1900+(yr)) % 400) == 0)) + + ATF_CHECK(parsedate("-1 month", NULL, NULL) != -1); + ATF_CHECK(parsedate("last friday", NULL, NULL) != -1); + ATF_CHECK(parsedate("one week ago", NULL, NULL) != -1); + ATF_CHECK(parsedate("this thursday", NULL, NULL) != -1); + ATF_CHECK(parsedate("next sunday", NULL, NULL) != -1); + ATF_CHECK(parsedate("+2 years", NULL, NULL) != -1); + + /* + * Test relative to a number of fixed dates. Avoid the + * edges of the time_t range to avert under- or overflow + * of the relative date, and use a prime step for maximum + * coverage of different times of day/week/month/year. + */ + for (now = 0x00FFFFFF; now < 0xFF000000; now += 3777779) { + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_mday--; + /* "yesterday" leaves time untouched */ + tm.tm_isdst = -1; + REL_CHECK("yesterday", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_mday++; + /* as does "tomorrow" */ + tm.tm_isdst = -1; + REL_CHECK("tomorrow", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + if (tm.tm_wday > 4) + tm.tm_mday += 7; + tm.tm_mday += 4 - tm.tm_wday; + /* if a day name is mentioned, it means midnight (by default) */ + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + tm.tm_isdst = -1; + REL_CHECK("this thursday", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_mday += 14 - (tm.tm_wday ? tm.tm_wday : 7); + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + tm.tm_isdst = -1; + REL_CHECK("next sunday", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + if (tm.tm_wday <= 5) + tm.tm_mday -= 7; + tm.tm_mday += 5 - tm.tm_wday; + tm.tm_sec = tm.tm_min = 0; + tm.tm_hour = 16; + tm.tm_isdst = -1; + REL_CHECK("last friday 4 p.m.", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_mday += 14; + if (tm.tm_wday > 3) + tm.tm_mday += 7; + tm.tm_mday += 3 - tm.tm_wday; + tm.tm_sec = tm.tm_min = 0; + tm.tm_hour = 3; + tm.tm_isdst = -1; + REL_CHECK("we fortnight 3 a.m.", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_min -= 5; + tm.tm_isdst = -1; + REL_CHECK("5 minutes ago", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_hour++; + tm.tm_min += 37; + tm.tm_isdst = -1; + REL_CHECK("97 minutes", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_mon++; + if (tm.tm_mon == 1 && + tm.tm_mday > 28 + isleap(tm.tm_year)) + tm.tm_mday = 28 + isleap(tm.tm_year); + else if ((tm.tm_mon == 3 || tm.tm_mon == 5 || + tm.tm_mon == 8 || tm.tm_mon == 10) && tm.tm_mday == 31) + tm.tm_mday = 30; + tm.tm_isdst = -1; + REL_CHECK("month", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_mon += 2; /* "next" means add 2 ... */ + if (tm.tm_mon == 13 && + tm.tm_mday > 28 + isleap(tm.tm_year + 1)) + tm.tm_mday = 28 + isleap(tm.tm_year + 1); + else if (tm.tm_mon == 8 && tm.tm_mday == 31) + tm.tm_mday = 30; + tm.tm_isdst = -1; + REL_CHECK("next month", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_mon--; + if (tm.tm_mon == 1 && + tm.tm_mday > 28 + isleap(tm.tm_year)) + tm.tm_mday = 28 + isleap(tm.tm_year); + else if ((tm.tm_mon == 3 || tm.tm_mon == 5 || + tm.tm_mon == 8 || tm.tm_mon == 10) && tm.tm_mday == 31) + tm.tm_mday = 30; + tm.tm_isdst = -1; + REL_CHECK("last month", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_mon += 6; + if (tm.tm_mon == 13 && + tm.tm_mday > 28 + isleap(tm.tm_year + 1)) + tm.tm_mday = 28 + isleap(tm.tm_year + 1); + else if ((tm.tm_mon == 15 || tm.tm_mon == 17 || + tm.tm_mon == 8 || tm.tm_mon == 10) && tm.tm_mday == 31) + tm.tm_mday = 30; + tm.tm_mday += 2; + tm.tm_isdst = -1; + REL_CHECK("+6 months 2 days", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_mon -= 9; + if (tm.tm_mon == 1 && tm.tm_mday > 28 + isleap(tm.tm_year)) + tm.tm_mday = 28 + isleap(tm.tm_year); + else if ((tm.tm_mon == -9 || tm.tm_mon == -7 || + tm.tm_mon == -2) && tm.tm_mday == 31) + tm.tm_mday = 30; + tm.tm_isdst = -1; + REL_CHECK("9 months ago", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + if (tm.tm_wday <= 2) + tm.tm_mday -= 7; + tm.tm_mday += 2 - tm.tm_wday; + tm.tm_isdst = -1; + tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + REL_CHECK("1 week ago Tu", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_isdst = -1; + tm.tm_mday++; + tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + REL_CHECK("midnight tomorrow", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_isdst = -1; + tm.tm_mday++; + tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + REL_CHECK("tomorrow midnight", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + tm.tm_isdst = -1; + tm.tm_mday++; + tm.tm_hour = 12; + tm.tm_min = tm.tm_sec = 0; + REL_CHECK("noon tomorrow", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + if (tm.tm_wday > 2) + tm.tm_mday += 7; + tm.tm_mday += 2 - tm.tm_wday; + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + tm.tm_isdst = -1; + REL_CHECK("midnight Tuesday", now, tm); + + ATF_CHECK(localtime_r(&now, &tm) != NULL); + if (tm.tm_wday > 2 + 1) + tm.tm_mday += 7; + tm.tm_mday += 2 - tm.tm_wday; + tm.tm_mday++; /* xxx midnight --> the next day */ + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + tm.tm_isdst = -1; + REL_CHECK("Tuesday midnight", now, tm); + } +} + +ATF_TC(atsecs); + +ATF_TC_HEAD(atsecs, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test seconds past the epoch"); +} + +ATF_TC_BODY(atsecs, tc) +{ + int tzoff; + + /* "@0" -> (time_t)0, regardless of timezone */ + ATF_CHECK(parsedate("@0", NULL, NULL) == (time_t)0); + putenv(__UNCONST("TZ=Europe/Berlin")); + tzset(); + ATF_CHECK(parsedate("@0", NULL, NULL) == (time_t)0); + putenv(__UNCONST("TZ=America/New_York")); + tzset(); + ATF_CHECK(parsedate("@0", NULL, NULL) == (time_t)0); + tzoff = 0; + ATF_CHECK(parsedate("@0", NULL, &tzoff) == (time_t)0); + tzoff = 3600; + ATF_CHECK(parsedate("@0", NULL, &tzoff) == (time_t)0); + tzoff = -3600; + ATF_CHECK(parsedate("@0", NULL, &tzoff) == (time_t)0); + + /* -1 or other negative numbers are not errors */ + errno = 0; + ATF_CHECK(parsedate("@-1", NULL, &tzoff) == (time_t)-1 && errno == 0); + ATF_CHECK(parsedate("@-2", NULL, &tzoff) == (time_t)-2 && errno == 0); + + /* junk is an error */ + errno = 0; + ATF_CHECK(parsedate("@junk", NULL, NULL) == (time_t)-1 && errno != 0); +} + +ATF_TC(zones); + +ATF_TC_HEAD(zones, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test parsing dates with zones"); +} + +ATF_TC_BODY(zones, tc) +{ + parsecheck("2015-12-06 16:11:48 UTC", NULL, NULL, gmtime_r, + 2015, 12, 6, 16, 11, 48); + parsecheck("2015-12-06 16:11:48 UT", NULL, NULL, gmtime_r, + 2015, 12, 6, 16, 11, 48); + parsecheck("2015-12-06 16:11:48 GMT", NULL, NULL, gmtime_r, + 2015, 12, 6, 16, 11, 48); + parsecheck("2015-12-06 16:11:48 +0000", NULL, NULL, gmtime_r, + 2015, 12, 6, 16, 11, 48); + + parsecheck("2015-12-06 16:11:48 -0500", NULL, NULL, gmtime_r, + 2015, 12, 6, 21, 11, 48); + parsecheck("2015-12-06 16:11:48 EST", NULL, NULL, gmtime_r, + 2015, 12, 6, 21, 11, 48); + parsecheck("2015-12-06 16:11:48 EDT", NULL, NULL, gmtime_r, + 2015, 12, 6, 20, 11, 48); + parsecheck("2015-12-06 16:11:48 +0500", NULL, NULL, gmtime_r, + 2015, 12, 6, 11, 11, 48); + + parsecheck("2015-12-06 16:11:48 +1000", NULL, NULL, gmtime_r, + 2015, 12, 6, 6, 11, 48); + parsecheck("2015-12-06 16:11:48 AEST", NULL, NULL, gmtime_r, + 2015, 12, 6, 6, 11, 48); + parsecheck("2015-12-06 16:11:48 -1000", NULL, NULL, gmtime_r, + 2015, 12, 7, 2, 11, 48); + parsecheck("2015-12-06 16:11:48 HST", NULL, NULL, gmtime_r, + 2015, 12, 7, 2, 11, 48); + + parsecheck("2015-12-06 16:11:48 AWST", NULL, NULL, gmtime_r, + 2015, 12, 6, 8, 11, 48); + parsecheck("2015-12-06 16:11:48 NZDT", NULL, NULL, gmtime_r, + 2015, 12, 6, 3, 11, 48); + + parsecheck("Sun, 6 Dec 2015 09:43:16 -0500", NULL, NULL, gmtime_r, + 2015, 12, 6, 14, 43, 16); + parsecheck("Mon Dec 7 03:13:31 ICT 2015", NULL, NULL, gmtime_r, + 2015, 12, 6, 20, 13, 31); + /* the day name is ignored when a day of month (etc) is given... */ + parsecheck("Sat Dec 7 03:13:31 ICT 2015", NULL, NULL, gmtime_r, + 2015, 12, 6, 20, 13, 31); + + + parsecheck("2015-12-06 12:00:00 IDLW", NULL, NULL, gmtime_r, + 2015, 12, 7, 0, 0, 0); + parsecheck("2015-12-06 12:00:00 IDLE", NULL, NULL, gmtime_r, + 2015, 12, 6, 0, 0, 0); + + parsecheck("2015-12-06 21:17:33 NFT", NULL, NULL, gmtime_r, + 2015, 12, 7, 0, 47, 33); + parsecheck("2015-12-06 21:17:33 ACST", NULL, NULL, gmtime_r, + 2015, 12, 6, 11, 47, 33); + parsecheck("2015-12-06 21:17:33 +0717", NULL, NULL, gmtime_r, + 2015, 12, 6, 14, 0, 33); + + parsecheck("2015-12-06 21:21:21 Z", NULL, NULL, gmtime_r, + 2015, 12, 6, 21, 21, 21); + parsecheck("2015-12-06 21:21:21 A", NULL, NULL, gmtime_r, + 2015, 12, 6, 22, 21, 21); + parsecheck("2015-12-06 21:21:21 G", NULL, NULL, gmtime_r, + 2015, 12, 7, 4, 21, 21); + parsecheck("2015-12-06 21:21:21 M", NULL, NULL, gmtime_r, + 2015, 12, 7, 9, 21, 21); + parsecheck("2015-12-06 21:21:21 N", NULL, NULL, gmtime_r, + 2015, 12, 6, 20, 21, 21); + parsecheck("2015-12-06 21:21:21 T", NULL, NULL, gmtime_r, + 2015, 12, 6, 14, 21, 21); + parsecheck("2015-12-06 21:21:21 Y", NULL, NULL, gmtime_r, + 2015, 12, 6, 9, 21, 21); + +} + +ATF_TC(gibberish); + +ATF_TC_HEAD(gibberish, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test (not) parsing nonsense"); +} + +ATF_TC_BODY(gibberish, tc) +{ + errno = 0; + ATF_CHECK(parsedate("invalid nonsense", NULL, NULL) == (time_t)-1 + && errno != 0); + errno = 0; + ATF_CHECK(parsedate("12th day of Christmas", NULL, NULL) == (time_t)-1 + && errno != 0); + errno = 0; + ATF_CHECK(parsedate("2015-31-07 15:00", NULL, NULL) == (time_t)-1 + && errno != 0); + errno = 0; + ATF_CHECK(parsedate("2015-02-29 10:01", NULL, NULL) == (time_t)-1 + && errno != 0); + errno = 0; + ATF_CHECK(parsedate("2015-12-06 24:01", NULL, NULL) == (time_t)-1 + && errno != 0); + errno = 0; + ATF_CHECK(parsedate("2015-12-06 14:61", NULL, NULL) == (time_t)-1 + && errno != 0); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, dates); + ATF_TP_ADD_TC(tp, times); + ATF_TP_ADD_TC(tp, dsttimes); + ATF_TP_ADD_TC(tp, relative); + ATF_TP_ADD_TC(tp, atsecs); + ATF_TP_ADD_TC(tp, zones); + ATF_TP_ADD_TC(tp, gibberish); + + return atf_no_error(); +} + diff --git a/contrib/netbsd-tests/lib/libutil/t_pidfile.c b/contrib/netbsd-tests/lib/libutil/t_pidfile.c new file mode 100644 index 0000000..a2aff83 --- /dev/null +++ b/contrib/netbsd-tests/lib/libutil/t_pidfile.c @@ -0,0 +1,363 @@ +/* $NetBSD: t_pidfile.c,v 1.3 2011/03/29 13:55:37 jmmv Exp $ */ + +/* + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * This file implements tests for the pidfile(3) functions. + * + * The tests here are tricky because we need to validate that the atexit(3) + * handler registered by pidfile(3) correctly deletes the generated pidfile. + * To do so: + * 1) We spawn a subprocess in every test case, + * 2) Run our test code in such subprocesses. We cannot call any of the ATF + * primitives from inside these. + * 3) Wait for the subprocess to terminate and ensure it exited successfully. + * 4) Check that the pidfile(s) created in the subprocess are gone. + * + * Additionally, pidfile(3) hardcodes a path to a directory writable only by + * root (/var/run). This makes us require root privileges to execute these + * tests. + */ + +#include +__COPYRIGHT("@(#) Copyright (c) 2011\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_pidfile.c,v 1.3 2011/03/29 13:55:37 jmmv Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Used by routines that can be called both from the parent and the child + * code to implement proper error reporting. */ +static bool in_child = false; + +/* Callable from the test case child code. */ +static void +check_pidfile(const char *path) +{ + FILE *file; + int pid; + + printf("Validating contents of pidfile '%s'\n", path); + + if ((file = fopen(path, "r")) == NULL) + errx(EXIT_FAILURE, "Cannot open expected pidfile '%s'", path); + + if (fscanf(file, "%d", &pid) == -1) + errx(EXIT_FAILURE, "Failed to read pid from pidfile '%s'", + path); + + printf("Read pid %d, current pid %d\n", pid, getpid()); + if (pid != getpid()) + errx(EXIT_FAILURE, "Pid in pidfile (%d) does not match " + "current pid (%d)", pid, getpid()); +} + +/* Callable from the test case parent/child code. */ +static void +ensure_deleted(const char *path) +{ + printf("Ensuring pidfile %s does not exist any more\n", path); + if (access(path, R_OK) != -1) { + unlink(path); + if (in_child) + errx(EXIT_FAILURE, "The pidfile %s was not deleted", + path); + else + atf_tc_fail("The pidfile %s was not deleted", path); + } +} + +/* Callable from the test case parent code. */ +static void +run_child(void (*child)(const char *), const char *cookie) +{ + pid_t pid; + + pid = fork(); + ATF_REQUIRE(pid != -1); + if (pid == 0) { + in_child = true; + child(cookie); + assert(false); + /* UNREACHABLE */ + } else { + int status; + + ATF_REQUIRE(waitpid(pid, &status, 0) != -1); + if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS) + atf_tc_fail("See stderr for details"); + } +} + +/* Callable from the test case parent/child code. */ +static char * +generate_varrun_pidfile(const char *basename) +{ + char *path; + + if (asprintf(&path, "%s%s.pid", _PATH_VARRUN, + basename == NULL ? getprogname() : basename) == -1) { + if (in_child) + errx(EXIT_FAILURE, "Cannot allocate memory for path"); + else + atf_tc_fail("Cannot allocate memory for path"); + } + + return path; +} + +static void +helper_default_path(const char *path) +{ + + if (pidfile(NULL) == -1) + errx(EXIT_FAILURE, "Failed to create pidfile with default " + "basename"); + + check_pidfile(path); + exit(EXIT_SUCCESS); +} + +ATF_TC(default_path); +ATF_TC_HEAD(default_path, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(default_path, tc) +{ + char *path; + + path = generate_varrun_pidfile(NULL); + run_child(helper_default_path, path); + ensure_deleted(path); + free(path); +} + +static void +helper_custom_basename(const char *path) +{ + + if (pidfile("custom-basename") == -1) + errx(EXIT_FAILURE, "Failed to create pidfile with custom " + "basename"); + + check_pidfile(path); + exit(EXIT_SUCCESS); +} + +ATF_TC(custom_basename); +ATF_TC_HEAD(custom_basename, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(custom_basename, tc) +{ + char *path; + + path = generate_varrun_pidfile("custom-basename"); + run_child(helper_custom_basename, path); + ensure_deleted(path); + free(path); +} + +static void +helper_custom_path(const char *path) +{ + + if (pidfile(path) == -1) + errx(EXIT_FAILURE, "Failed to create pidfile '%s'", path); + check_pidfile(path); + exit(EXIT_SUCCESS); +} + +ATF_TC_WITHOUT_HEAD(custom_path); +ATF_TC_BODY(custom_path, tc) +{ + + ATF_REQUIRE(mkdir("var", 0777) != -1); + ATF_REQUIRE(mkdir("var/run", 0777) != -1); + + run_child(helper_custom_path, "./var/run/my-pidfile.pid"); + + ensure_deleted("./var/run/my-pidfile.pid"); +} + +static void +helper_change_basenames(const char *unused_cookie) +{ + char *default_path; + char *custom_path; + + default_path = generate_varrun_pidfile(NULL); + if (pidfile(NULL) == -1) + errx(EXIT_FAILURE, "Failed to create pidfile with default " + "basename"); + check_pidfile(default_path); + if (pidfile(NULL) == -1) + errx(EXIT_FAILURE, "Failed to recreate pidfile with default " + "basename"); + check_pidfile(default_path); + + custom_path = generate_varrun_pidfile("custom-basename"); + if (pidfile("custom-basename") == -1) + errx(EXIT_FAILURE, "Failed to create pidfile with custom " + "basename"); + ensure_deleted(default_path); + check_pidfile(custom_path); + if (pidfile("custom-basename") == -1) + errx(EXIT_FAILURE, "Failed to recreate pidfile with custom " + "basename"); + check_pidfile(custom_path); + + free(custom_path); + free(default_path); + exit(EXIT_SUCCESS); +} + +ATF_TC(change_basenames); +ATF_TC_HEAD(change_basenames, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(change_basenames, tc) +{ + char *default_path; + char *custom_path; + + run_child(helper_change_basenames, NULL); + + default_path = generate_varrun_pidfile(NULL); + custom_path = generate_varrun_pidfile("custom-basename"); + + ensure_deleted(default_path); + ensure_deleted(custom_path); + + free(custom_path); + free(default_path); +} + +static void +helper_change_paths(const char *unused_cookie) +{ + + if (pidfile("./var/run/first.pid") == -1) + errx(EXIT_FAILURE, "Failed to create pidfile " + "'./var/run/first.pid'"); + check_pidfile("./var/run/first.pid"); + + if (pidfile("./second.pid") == -1) + errx(EXIT_FAILURE, "Failed to create pidfile 'second.pid'"); + ensure_deleted("./var/run/first.pid"); + check_pidfile("./second.pid"); + + exit(EXIT_SUCCESS); +} + +ATF_TC_WITHOUT_HEAD(change_paths); +ATF_TC_BODY(change_paths, tc) +{ + + ATF_REQUIRE(mkdir("var", 0777) != -1); + ATF_REQUIRE(mkdir("var/run", 0777) != -1); + + run_child(helper_change_paths, NULL); + + ensure_deleted("./var/run/my-pidfile.pid"); + ensure_deleted("second.pid"); +} + +static void +helper_mix(const char *unused_cookie) +{ + char *default_path; + char *custom_path; + + default_path = generate_varrun_pidfile(NULL); + custom_path = generate_varrun_pidfile("custom-basename"); + + if (pidfile(NULL) == -1) + errx(EXIT_FAILURE, "Failed to create default pidfile"); + check_pidfile(default_path); + + if (pidfile("./second.pid") == -1) + errx(EXIT_FAILURE, "Failed to create pidfile 'second.pid'"); + ensure_deleted(default_path); + check_pidfile("./second.pid"); + + if (pidfile("custom-basename") == -1) + errx(EXIT_FAILURE, "Failed to create pidfile 'second.pid'"); + ensure_deleted(default_path); + ensure_deleted("./second.pid"); + ensure_deleted("./custom-basename"); + check_pidfile(custom_path); + + free(custom_path); + free(default_path); + exit(EXIT_SUCCESS); +} + +ATF_TC(change_mix); +ATF_TC_HEAD(change_mix, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(change_mix, tc) +{ + char *default_path; + + run_child(helper_mix, NULL); + + default_path = generate_varrun_pidfile(NULL); + ensure_deleted(default_path); + ensure_deleted("second.pid"); + free(default_path); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, default_path); + ATF_TP_ADD_TC(tp, custom_basename); + ATF_TP_ADD_TC(tp, custom_path); + ATF_TP_ADD_TC(tp, change_basenames); + ATF_TP_ADD_TC(tp, change_paths); + ATF_TP_ADD_TC(tp, change_mix); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libutil/t_snprintb.c b/contrib/netbsd-tests/lib/libutil/t_snprintb.c new file mode 100644 index 0000000..8863e8b --- /dev/null +++ b/contrib/netbsd-tests/lib/libutil/t_snprintb.c @@ -0,0 +1,117 @@ +/* $NetBSD: t_snprintb.c,v 1.4 2014/06/06 06:59:21 shm Exp $ */ + +/* + * Copyright (c) 2002, 2004, 2008, 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_snprintb.c,v 1.4 2014/06/06 06:59:21 shm Exp $"); + +#include +#include + +#include + +static void +h_snprintb(const char *fmt, uint64_t val, const char *res) +{ + char buf[1024]; + int len, slen; + + len = snprintb(buf, sizeof(buf), fmt, val); + slen = (int) strlen(res); + + ATF_REQUIRE_STREQ(res, buf); + ATF_REQUIRE_EQ(len, slen); +} + +ATF_TC(snprintb); +ATF_TC_HEAD(snprintb, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks snprintb(3)"); +} +ATF_TC_BODY(snprintb, tc) +{ + h_snprintb("\10\2BITTWO\1BITONE", 3, "03"); + h_snprintb("\177\20b\0A\0\0", 0, "0x0"); + + h_snprintb("\177\20b\05NOTBOOT\0b\06FPP\0b\013SDVMA\0b\015VIDEO\0" + "b\020LORES\0b\021FPA\0b\022DIAG\0b\016CACHE\0" + "b\017IOCACHE\0b\022LOOPBACK\0b\04DBGCACHE\0", + 0xe860, "0xe860"); +} + +static void +h_snprintb_m(const char *fmt, uint64_t val, int line_max, const char *res, + int res_len) +{ + char buf[1024]; + int len; + + len = snprintb_m(buf, sizeof(buf), fmt, val, line_max); + + ATF_REQUIRE_EQ(len, res_len); + ATF_REQUIRE_EQ(0, memcmp(res, buf, res_len + 1)); +} + +ATF_TC(snprintb_m); +ATF_TC_HEAD(snprintb_m, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks snprintb_m(3)"); +} +ATF_TC_BODY(snprintb_m, tc) +{ + h_snprintb_m("\177\020b\0LSB\0b\1_BITONE\0f\4\4NIBBLE2\0" + "f\x10\4BURST\0=\4FOUR\0=\xfSIXTEEN\0" + "b\x1fMSB\0\0", + 0x800f0701, + 33, + "0x800f0701\0" + "0x800f0701\0\0", + 62); + + h_snprintb_m("\177\020b\0LSB\0b\1_BITONE\0f\4\4NIBBLE2\0" + "f\x10\4BURST\0=\4FOUR\0=\xfSIXTEEN\0" + "b\x1fMSB\0\0", + 0x800f0701, + 32, + "0x800f0701\0" + "0x800f0701\0" + "0x800f0701\0\0", + 74); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, snprintb); + ATF_TP_ADD_TC(tp, snprintb_m); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libutil/t_sockaddr_snprintf.c b/contrib/netbsd-tests/lib/libutil/t_sockaddr_snprintf.c new file mode 100644 index 0000000..b4e8cb3 --- /dev/null +++ b/contrib/netbsd-tests/lib/libutil/t_sockaddr_snprintf.c @@ -0,0 +1,185 @@ +/* $NetBSD: t_sockaddr_snprintf.c,v 1.1 2010/07/16 13:56:32 jmmv Exp $ */ + +/* + * Copyright (c) 2002, 2004, 2008, 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code was contributed to The NetBSD Foundation by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ + The NetBSD Foundation, inc. All rights reserved."); +__RCSID("$NetBSD: t_sockaddr_snprintf.c,v 1.1 2010/07/16 13:56:32 jmmv Exp $"); + +#include /* AF_ */ +#include /* sun */ + +#include /* sdl */ +#include /* sat */ +#include /* sin/sin6 */ + +#include +#include + +#include + +ATF_TC(sockaddr_snprintf_in); +ATF_TC_HEAD(sockaddr_snprintf_in, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sockaddr_snprintf(3) with sockaddr_in"); +} +ATF_TC_BODY(sockaddr_snprintf_in, tc) +{ + char buf[1024]; + struct sockaddr_in sin4; + int i; + + memset(&sin4, 0, sizeof(sin4)); + sin4.sin_len = sizeof(sin4); + sin4.sin_family = AF_INET; + sin4.sin_port = ntohs(80); + sin4.sin_addr.s_addr = ntohl(INADDR_LOOPBACK); + i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %p %a", + (struct sockaddr *)&sin4); + + ATF_REQUIRE_EQ_MSG(i, 17, "bad length for sin4"); + ATF_REQUIRE_STREQ(buf, "2 16 80 127.0.0.1"); +} + +ATF_TC(sockaddr_snprintf_in6); +ATF_TC_HEAD(sockaddr_snprintf_in6, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sockaddr_snprintf(3) with sockaddr_in6"); +} +ATF_TC_BODY(sockaddr_snprintf_in6, tc) +{ +#ifdef INET6 + char buf[1024]; + struct sockaddr_in6 sin6; + int i; + + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_len = sizeof(sin6); + sin6.sin6_family = AF_INET6; + sin6.sin6_port = ntohs(80); + sin6.sin6_addr = in6addr_nodelocal_allnodes; + i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %p %a", + (struct sockaddr *)&sin6); + + ATF_REQUIRE_EQ_MSG(i, 16, "bad length for sin6"); + ATF_REQUIRE_STREQ(buf, "24 28 80 ff01::1"); +#else + atf_tc_skip("Tests built with USE_INET6=no"); +#endif /* INET6 */ +} + +ATF_TC(sockaddr_snprintf_un); +ATF_TC_HEAD(sockaddr_snprintf_un, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sockaddr_snprintf(3) with sockaddr_un"); +} +ATF_TC_BODY(sockaddr_snprintf_un, tc) +{ + char buf[1024]; + struct sockaddr_un sun; + int i; + + memset(&sun, 0, sizeof(sun)); + sun.sun_len = sizeof(sun); + sun.sun_family = AF_UNIX; + strncpy(sun.sun_path, "/tmp/sock", sizeof(sun.sun_path)); + i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %a", + (struct sockaddr *)&sun); + + ATF_REQUIRE_EQ_MSG(i, 15, "bad length for sun"); + ATF_REQUIRE_STREQ(buf, "1 106 /tmp/sock"); +} + +ATF_TC(sockaddr_snprintf_at); +ATF_TC_HEAD(sockaddr_snprintf_at, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sockaddr_snprintf(3) with sockaddr_at"); +} +ATF_TC_BODY(sockaddr_snprintf_at, tc) +{ + char buf[1024]; + struct sockaddr_at sat; + int i; + + memset(&sat, 0, sizeof(sat)); + sat.sat_len = sizeof(sat); + sat.sat_family = AF_APPLETALK; + sat.sat_addr.s_net = ntohs(101); + sat.sat_addr.s_node = 3; + i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %a", + (struct sockaddr *)&sat); + + ATF_REQUIRE_EQ_MSG(i, 11, "bad length for sat"); + ATF_REQUIRE_STREQ(buf, "16 16 101.3"); +} + +ATF_TC(sockaddr_snprintf_dl); +ATF_TC_HEAD(sockaddr_snprintf_dl, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Checks sockaddr_snprintf(3) with sockaddr_dl"); +} +ATF_TC_BODY(sockaddr_snprintf_dl, tc) +{ + char buf[1024]; + struct sockaddr_dl sdl; + int i; + + memset(&sdl, 0, sizeof(sdl)); + sdl.sdl_len = sizeof(sdl); + sdl.sdl_family = AF_LINK; + sdl.sdl_index = 0; + sdl.sdl_type = 0; + sdl.sdl_nlen = 0; + sdl.sdl_alen = 6; + sdl.sdl_slen = 0; + memcpy(sdl.sdl_data, "\01\02\03\04\05\06", 6); + i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %a", + (struct sockaddr *)&sdl); + + ATF_REQUIRE_EQ_MSG(i, 17, "bad length for sdl"); + ATF_REQUIRE_STREQ(buf, "18 20 1.2.3.4.5.6"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sockaddr_snprintf_in); + ATF_TP_ADD_TC(tp, sockaddr_snprintf_in6); + ATF_TP_ADD_TC(tp, sockaddr_snprintf_un); + ATF_TP_ADD_TC(tp, sockaddr_snprintf_at); + ATF_TP_ADD_TC(tp, sockaddr_snprintf_dl); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/semaphore/pthread/t_sem_pth.c b/contrib/netbsd-tests/lib/semaphore/pthread/t_sem_pth.c new file mode 100644 index 0000000..b32d954 --- /dev/null +++ b/contrib/netbsd-tests/lib/semaphore/pthread/t_sem_pth.c @@ -0,0 +1,17 @@ +#define LIBNAME "pthread" +#include "sem.c" + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, postwait); + ATF_TP_ADD_TC(tp, initvalue); + ATF_TP_ADD_TC(tp, destroy); + ATF_TP_ADD_TC(tp, busydestroy); + ATF_TP_ADD_TC(tp, blockwait); + ATF_TP_ADD_TC(tp, blocktimedwait); + ATF_TP_ADD_TC(tp, named); + ATF_TP_ADD_TC(tp, unlink); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/semaphore/sem.c b/contrib/netbsd-tests/lib/semaphore/sem.c new file mode 100644 index 0000000..6af9b0d --- /dev/null +++ b/contrib/netbsd-tests/lib/semaphore/sem.c @@ -0,0 +1,332 @@ +/* $NetBSD: sem.c,v 1.11 2017/01/13 21:30:42 christos Exp $ */ + +/* + * Common code for semaphore tests. This can be included both into + * programs using librt and libpthread. + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "h_macros.h" + +ATF_TC(postwait); +ATF_TC_HEAD(postwait, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests post and wait from a " + "single thread (%s)", LIBNAME); +} + +ATF_TC_BODY(postwait, tc) +{ + sem_t sem; + int rv; + + rump_init(); + + ATF_REQUIRE_EQ(sem_init(&sem, 1, 0), 0); + + sem_post(&sem); + sem_post(&sem); + + sem_wait(&sem); + sem_wait(&sem); + rv = sem_trywait(&sem); + ATF_REQUIRE(errno == EAGAIN); + ATF_REQUIRE(rv == -1); +} + +ATF_TC(initvalue); +ATF_TC_HEAD(initvalue, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests initialization with a non-zero " + "value (%s)", LIBNAME); +} + +ATF_TC_BODY(initvalue, tc) +{ + sem_t sem; + + rump_init(); + sem_init(&sem, 1, 4); + + ATF_REQUIRE_EQ(sem_trywait(&sem), 0); + ATF_REQUIRE_EQ(sem_trywait(&sem), 0); + ATF_REQUIRE_EQ(sem_trywait(&sem), 0); + ATF_REQUIRE_EQ(sem_trywait(&sem), 0); + ATF_REQUIRE_EQ(sem_trywait(&sem), -1); +} + +ATF_TC(destroy); +ATF_TC_HEAD(destroy, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests sem_destroy works (%s)", LIBNAME); +} + +ATF_TC_BODY(destroy, tc) +{ + sem_t sem; + int rv, i; + + rump_init(); + for (i = 0; i < 2; i++) { + sem_init(&sem, 1, 1); + + ATF_REQUIRE_EQ(sem_trywait(&sem), 0); + ATF_REQUIRE_EQ(sem_trywait(&sem), -1); + ATF_REQUIRE_EQ(sem_destroy(&sem), 0); + rv = sem_trywait(&sem); + ATF_REQUIRE_EQ(errno, EINVAL); + ATF_REQUIRE_EQ(rv, -1); + } +} + +ATF_TC(busydestroy); +ATF_TC_HEAD(busydestroy, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests sem_destroy report EBUSY for " + "a busy semaphore (%s)", LIBNAME); +} + +static void * +hthread(void *arg) +{ + sem_t *semmarit = arg; + + for (;;) { + sem_post(&semmarit[2]); + sem_wait(&semmarit[1]); + sem_wait(&semmarit[0]); + } + + return NULL; +} + +ATF_TC_BODY(busydestroy, tc) +{ + sem_t semmarit[3]; + pthread_t pt; + int i; + + /* use a unicpu rump kernel. this means less chance for race */ + setenv("RUMP_NCPU", "1", 1); + + rump_init(); + sem_init(&semmarit[0], 1, 0); + sem_init(&semmarit[1], 1, 0); + sem_init(&semmarit[2], 1, 0); + + pthread_create(&pt, NULL, hthread, semmarit); + + /* + * Make a best-effort to catch the other thread with its pants down. + * We can't do this for sure, can we? Although, we could reach + * inside the rump kernel and inquire about the thread's sleep + * status. + */ + for (i = 0; i < 1000; i++) { + sem_wait(&semmarit[2]); + usleep(1); + if (sem_destroy(&semmarit[1]) == -1) + if (errno == EBUSY) + break; + + /* + * Didn't catch it? ok, recreate and post to make the + * other thread run + */ + sem_init(&semmarit[1], 1, 0); + sem_post(&semmarit[0]); + sem_post(&semmarit[1]); + + } + if (i == 1000) + atf_tc_fail("sem destroy not reporting EBUSY"); + + pthread_cancel(pt); + pthread_join(pt, NULL); +} + +ATF_TC(blockwait); +ATF_TC_HEAD(blockwait, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests sem_wait can handle blocking " + "(%s)", LIBNAME); + atf_tc_set_md_var(tc, "timeout", "2"); +} + +ATF_TC_BODY(blockwait, tc) +{ + sem_t semmarit[3]; + pthread_t pt; + int i; + + rump_init(); + sem_init(&semmarit[0], 1, 0); + sem_init(&semmarit[1], 1, 0); + sem_init(&semmarit[2], 1, 0); + + pthread_create(&pt, NULL, hthread, semmarit); + + /* + * Make a best-effort. Unless we're extremely unlucky, we should + * at least one blocking wait. + */ + for (i = 0; i < 10; i++) { + sem_wait(&semmarit[2]); + usleep(1); + sem_post(&semmarit[0]); + sem_post(&semmarit[1]); + + } + + pthread_cancel(pt); + pthread_join(pt, NULL); +} + +ATF_TC(blocktimedwait); +ATF_TC_HEAD(blocktimedwait, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests sem_timedwait can handle blocking" + " (%s)", LIBNAME); + atf_tc_set_md_var(tc, "timeout", "2"); +} + +ATF_TC_BODY(blocktimedwait, tc) +{ + sem_t semid; + struct timespec tp; + + rump_init(); + + clock_gettime(CLOCK_REALTIME, &tp); + tp.tv_nsec += 50000000; + tp.tv_sec += tp.tv_nsec / 1000000000; + tp.tv_nsec %= 1000000000; + + ATF_REQUIRE_EQ(sem_init(&semid, 1, 0), 0); + ATF_REQUIRE_ERRNO(ETIMEDOUT, sem_timedwait(&semid, &tp) == -1); +} + +ATF_TC(named); +ATF_TC_HEAD(named, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests named semaphores (%s)", LIBNAME); +} + +/* + * Wow, easy naming rules. it's these times i'm really happy i can + * single-step into the kernel. + */ +#define SEM1 "/precious_sem" +#define SEM2 "/justsem" +ATF_TC_BODY(named, tc) +{ + sem_t *sem1, *sem2; + void *rv; + + rump_init(); + sem1 = sem_open(SEM1, 0); + ATF_REQUIRE_EQ(errno, ENOENT); + ATF_REQUIRE_EQ(sem1, NULL); + + sem1 = sem_open(SEM1, O_CREAT, 0444, 1); + if (sem1 == NULL) + atf_tc_fail_errno("sem_open O_CREAT"); + + rv = sem_open(SEM1, O_CREAT | O_EXCL); + ATF_REQUIRE_EQ(errno, EEXIST); + ATF_REQUIRE_EQ(rv, NULL); + + sem2 = sem_open(SEM2, O_CREAT, 0444, 0); + if (sem2 == NULL) + atf_tc_fail_errno("sem_open O_CREAT"); + + /* check that semaphores are independent */ + ATF_REQUIRE_EQ(sem_trywait(sem2), -1); + ATF_REQUIRE_EQ(sem_trywait(sem1), 0); + ATF_REQUIRE_EQ(sem_trywait(sem1), -1); + + /* check that unlinked remains valid */ + sem_unlink(SEM2); + ATF_REQUIRE_EQ(sem_post(sem2), 0); + ATF_REQUIRE_EQ(sem_trywait(sem2), 0); + ATF_REQUIRE_EQ(sem_trywait(sem2), -1); + ATF_REQUIRE_EQ(errno, EAGAIN); + +#if 0 /* see unlink */ + /* close it and check that it's gone */ + if (sem_close(sem2) != 0) + atf_tc_fail_errno("sem close"); + ATF_REQUIRE_EQ(sem_trywait(sem2), -1); + ATF_REQUIRE_EQ(errno, EINVAL); +#endif + + /* check that we still have sem1 */ + sem_post(sem1); + ATF_REQUIRE_EQ(sem_trywait(sem1), 0); + ATF_REQUIRE_EQ(sem_trywait(sem1), -1); + ATF_REQUIRE_EQ(errno, EAGAIN); +} + +ATF_TC(unlink); +ATF_TC_HEAD(unlink, tc) +{ + + /* this is currently broken. i'll append the PR number soon */ + atf_tc_set_md_var(tc, "descr", "tests unlinked semaphores can be " + "closed (%s)", LIBNAME); +} + +#define SEM "/thesem" +ATF_TC_BODY(unlink, tc) +{ + sem_t *sem; + + rump_init(); + sem = sem_open(SEM, O_CREAT, 0444, 0); + ATF_REQUIRE(sem); + + if (sem_unlink(SEM) == -1) + atf_tc_fail_errno("unlink"); + if (sem_close(sem) == -1) + atf_tc_fail_errno("close unlinked semaphore"); +} + +/* use rump calls for libpthread _ksem_foo() calls */ +#define F1(name, a) int _ksem_##name(a); \ +int _ksem_##name(a v1) {return rump_sys__ksem_##name(v1);} +#define F2(name, a, b) int _ksem_##name(a, b); \ +int _ksem_##name(a v1, b v2) {return rump_sys__ksem_##name(v1, v2);} +F2(init, unsigned int, intptr_t *); +F1(close, intptr_t); +F1(destroy, intptr_t); +F1(post, intptr_t); +F1(unlink, const char *); +F1(trywait, intptr_t); +F1(wait, intptr_t); +F2(getvalue, intptr_t, unsigned int *); +F2(timedwait, intptr_t, const struct timespec *); +int _ksem_open(const char *, int, mode_t, unsigned int, intptr_t *); +int _ksem_open(const char *a, int b, mode_t c, unsigned int d, intptr_t *e) + {return rump_sys__ksem_open(a,b,c,d,e);} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v0-v0 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v0-v0 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v0-v0 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v0-v1 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v0-v1 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v0-v1 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v0-v2 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v0-v2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v0-v2 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v1-v0 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v1-v0 new file mode 100644 index 0000000..8cfcf27 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v1-v0 @@ -0,0 +1 @@ +/usr/tests/libexec/ld.elf_so/h_helper_symver_dso0/libh_helper_symver_dso.so.1: version V_1 required by /usr/tests/libexec/ld.elf_so/h_dl_symver_v1 not defined diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v1-v1 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v1-v1 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v1-v1 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v1-v2 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v1-v2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v1-v2 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v2-v0 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v2-v0 new file mode 100644 index 0000000..e43fc56 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v2-v0 @@ -0,0 +1 @@ +/usr/tests/libexec/ld.elf_so/h_helper_symver_dso0/libh_helper_symver_dso.so.1: version V_3 required by /usr/tests/libexec/ld.elf_so/h_dl_symver_v2 not defined diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v2-v1 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v2-v1 new file mode 100644 index 0000000..494c321 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v2-v1 @@ -0,0 +1 @@ +/usr/tests/libexec/ld.elf_so/h_helper_symver_dso1/libh_helper_symver_dso.so.1: version V_3 required by /usr/tests/libexec/ld.elf_so/h_dl_symver_v2 not found diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v2-v2 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v2-v2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stderr.v2-v2 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v0-v0 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v0-v0 new file mode 100644 index 0000000..573541a --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v0-v0 @@ -0,0 +1 @@ +0 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v0-v1 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v0-v1 new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v0-v1 @@ -0,0 +1 @@ +1 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v0-v2 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v0-v2 new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v0-v2 @@ -0,0 +1 @@ +1 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v1-v0 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v1-v0 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v1-v0 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v1-v1 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v1-v1 new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v1-v1 @@ -0,0 +1 @@ +1 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v1-v2 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v1-v2 new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v1-v2 @@ -0,0 +1 @@ +1 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v2-v0 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v2-v0 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v2-v0 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v2-v1 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v2-v1 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v2-v1 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v2-v2 b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v2-v2 new file mode 100644 index 0000000..00750ed --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/data/symver-output-ref-stdout.v2-v2 @@ -0,0 +1 @@ +3 diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/h_df_1_noopen.c b/contrib/netbsd-tests/libexec/ld.elf_so/h_df_1_noopen.c new file mode 100644 index 0000000..518f39b --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/h_df_1_noopen.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include + +int +main(void) +{ + void *handle; + + handle = dlopen("libpthread.so", RTLD_NOLOAD); + if (handle == NULL) + errx(1, "%s", dlerror()); + + printf("libpthread loaded successfully\n"); + return 0; +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/h_dl_symver.c b/contrib/netbsd-tests/libexec/ld.elf_so/h_dl_symver.c new file mode 100644 index 0000000..71e4dc1 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/h_dl_symver.c @@ -0,0 +1,42 @@ +/* $NetBSD: h_dl_symver.c,v 1.1 2011/06/25 05:45:13 nonaka Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by NONAKA Kimihiro. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +extern int testfunc(void); + +int +main(void) +{ + + printf("%d\n", testfunc()); + return 0; +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/h_ifunc.c b/contrib/netbsd-tests/libexec/ld.elf_so/h_ifunc.c new file mode 100644 index 0000000..ac446fa --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/h_ifunc.c @@ -0,0 +1,43 @@ +/* $NetBSD: h_ifunc.c,v 1.1 2014/08/25 20:40:53 joerg Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +extern int ifunc(void); + +int +main(int argc, char **argv) +{ + + if (argc != 2) + return 1; + return ifunc() != atoi(argv[1]); +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/h_locking.c b/contrib/netbsd-tests/libexec/ld.elf_so/h_locking.c new file mode 100644 index 0000000..4ff3fc4 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/h_locking.c @@ -0,0 +1,149 @@ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include +#include +#include +#include +#include + +int sleep_init; +int sleep_fini; +int dlopen_cookie; +int dlclose_cookie; + +void (*tls_callback_sym)(void); + +static int +dl_iterate_phdr_cb(struct dl_phdr_info *info, size_t size, void *data) +{ + (*tls_callback_sym)(); + return 0; +} + +static void * +test_dl_iterate_phdr_helper(void *dummy) +{ + sleep(10); + _exit(1); +} + +static void +test_dl_iterate_phdr(void) +{ + pthread_t t; + void *dso; + sleep_init = 0; + sleep_fini = 0; + if ((dso = dlopen("libh_helper_dso2.so", RTLD_LAZY)) == NULL) { + fprintf(stderr, "opening helper failed\n"); + _exit(1); + } + tls_callback_sym = dlsym(dso, "tls_callback"); + if (tls_callback_sym == NULL) { + fprintf(stderr, "bad helper\n"); + _exit(1); + } + pthread_create(&t, NULL, test_dl_iterate_phdr_helper, NULL); + if (dl_iterate_phdr(dl_iterate_phdr_cb, NULL)) + _exit(1); + _exit(0); +} + +static void * +init_fini_helper(void *arg) +{ + void *dso; + if ((dso = dlopen(arg, RTLD_LAZY)) == NULL) { + fprintf(stderr, "opening %s failed\n", (char *)arg); + exit(1); + } + dlclose(dso); + return NULL; +} + +static void +test_dlopen(void) +{ + pthread_t t1, t2; + sleep_init = 1; + sleep_fini = 0; + printf("%d\n", dlopen_cookie); + pthread_create(&t1, NULL, init_fini_helper, + __UNCONST("libh_helper_dso2.so")); + sleep(1); + printf("%d\n", dlopen_cookie); + if (dlopen_cookie != 1) + _exit(1); + sleep(1); + pthread_create(&t2, NULL, init_fini_helper, + __UNCONST("libutil.so")); + printf("%d\n", dlopen_cookie); + if (dlopen_cookie != 1) + _exit(1); + _exit(0); +} + +static void +test_dlclose(void) +{ + pthread_t t1, t2; + sleep_init = 0; + sleep_fini = 1; + printf("%d\n", dlclose_cookie); + pthread_create(&t1, NULL, init_fini_helper, + __UNCONST("libh_helper_dso2.so")); + sleep(1); + printf("%d\n", dlclose_cookie); + if (dlclose_cookie != 2) + _exit(1); + pthread_create(&t2, NULL, init_fini_helper, + __UNCONST("libutil.so")); + sleep(1); + printf("%d\n", dlclose_cookie); + if (dlclose_cookie != 2) + _exit(1); + _exit(0); +} + +int +main(int argc, char **argv) +{ + if (argc != 2) + return 1; + if (strcmp(argv[1], "dl_iterate_phdr") == 0) + test_dl_iterate_phdr(); + if (strcmp(argv[1], "dlopen") == 0) + test_dlopen(); + if (strcmp(argv[1], "dlclose") == 0) + test_dlclose(); + return 1; +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/helper_dso1/h_helper_dso1.c b/contrib/netbsd-tests/libexec/ld.elf_so/helper_dso1/h_helper_dso1.c new file mode 100644 index 0000000..e89e3ff --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/helper_dso1/h_helper_dso1.c @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#ifdef __HAVE_NO___THREAD +#define __thread +#endif + +extern int sleep_init; +extern int sleep_fini; +extern int dlopen_cookie; + +static void __attribute__((__constructor__)) +init1(void) +{ + dlopen_cookie = 1; + if (!sleep_init) + return; + for (;;) + poll(NULL, 0, -1); +} + +extern int dlclose_cookie; + +static void __attribute__((__destructor__)) +fini1(void) +{ + dlclose_cookie = 1; + if (!sleep_fini) + return; + for (;;) + poll(NULL, 0, -1); +} + +static __thread int tls_callback_var; + +static void __attribute__((__used__)) +tls_callback(void) +{ + tls_callback_var = 1; +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/helper_dso2/h_helper_dso2.c b/contrib/netbsd-tests/libexec/ld.elf_so/helper_dso2/h_helper_dso2.c new file mode 100644 index 0000000..adeef6b --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/helper_dso2/h_helper_dso2.c @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +extern int sleep_init; +extern int sleep_fini; +extern int dlopen_cookie; + +static void __attribute__((__constructor__)) +init2(void) +{ + dlopen_cookie = 2; + if (!sleep_init) + return; + for (;;) + poll(NULL, 0, -1); +} + +extern int dlclose_cookie; + +static void __attribute__((__destructor__)) +fini2(void) +{ + dlclose_cookie = 2; + if (!sleep_fini) + return; + for (;;) + poll(NULL, 0, -1); +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/helper_ifunc_dso/h_helper_ifunc.c b/contrib/netbsd-tests/libexec/ld.elf_so/helper_ifunc_dso/h_helper_ifunc.c new file mode 100644 index 0000000..c04f775 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/helper_ifunc_dso/h_helper_ifunc.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +static int +ifunc1(void) +{ + return 0xdeadbeef; +} + +static int +ifunc2(void) +{ + return 0xbeefdead; +} + +static __attribute__((used)) +int (*resolve_ifunc(void))(void) +{ + const char *e = getenv("USE_IFUNC2"); + return e && strcmp(e, "1") == 0 ? ifunc2 : ifunc1; +} + +__ifunc(ifunc, resolve_ifunc); diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso0/h_helper_symver_dso0.c b/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso0/h_helper_symver_dso0.c new file mode 100644 index 0000000..a34bf31 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso0/h_helper_symver_dso0.c @@ -0,0 +1,39 @@ +/* $NetBSD: h_helper_symver_dso0.c,v 1.1 2011/06/25 05:45:13 nonaka Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by NONAKA Kimihiro. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +int testfunc(void); + +int +testfunc(void) +{ + + return 0; +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso1/h_helper_symver_dso1.c b/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso1/h_helper_symver_dso1.c new file mode 100644 index 0000000..615816b --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso1/h_helper_symver_dso1.c @@ -0,0 +1,41 @@ +/* $NetBSD: h_helper_symver_dso1.c,v 1.1 2011/06/25 05:45:13 nonaka Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by NONAKA Kimihiro. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +__asm(".symver testfunc_new, testfunc@@V_1"); + +int testfunc_new(void); + +int +testfunc_new(void) +{ + + return 1; +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso1/h_helper_symver_dso1.map b/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso1/h_helper_symver_dso1.map new file mode 100644 index 0000000..c813f5d --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso1/h_helper_symver_dso1.map @@ -0,0 +1,5 @@ +# $NetBSD: h_helper_symver_dso1.map,v 1.1 2011/06/25 05:45:13 nonaka Exp $ + +V_1 { + testfunc; +}; diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso2/h_helper_symver_dso2.c b/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso2/h_helper_symver_dso2.c new file mode 100644 index 0000000..f5ae4c8 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso2/h_helper_symver_dso2.c @@ -0,0 +1,59 @@ +/* $NetBSD: h_helper_symver_dso2.c,v 1.1 2011/06/25 05:45:13 nonaka Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by NONAKA Kimihiro. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +__asm(".symver testfunc_new, testfunc@@V_3"); +__asm(".symver testfunc_compat1, testfunc@V_1"); +__asm(".symver testfunc_compat2, testfunc@V_2"); + +int testfunc_new(void); +int testfunc_compat1(void); +int testfunc_compat2(void); + +int +testfunc_new(void) +{ + + return 3; +} + +int +testfunc_compat1(void) +{ + + return 1; +} + +int +testfunc_compat2(void) +{ + + return 2; +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso2/h_helper_symver_dso2.map b/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso2/h_helper_symver_dso2.map new file mode 100644 index 0000000..518c76b --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/helper_symver_dso2/h_helper_symver_dso2.map @@ -0,0 +1,13 @@ +# $NetBSD: h_helper_symver_dso2.map,v 1.1 2011/06/25 05:45:13 nonaka Exp $ + +V_1 { + testfunc; +}; + +V_2 { + testfunc; +}; + +V_3 { + testfunc; +}; diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/t_df_1_noopen.sh b/contrib/netbsd-tests/libexec/ld.elf_so/t_df_1_noopen.sh new file mode 100755 index 0000000..31851f4 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/t_df_1_noopen.sh @@ -0,0 +1,63 @@ +# $NetBSD: t_df_1_noopen.sh,v 1.3 2011/03/17 15:59:32 skrll Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Nick Hudson. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case df_1_noopen1 +df_1_noopen1_head() +{ + atf_set "descr" "Checks DF_1_NOOPEN prevents dlopening of library" +} +df_1_noopen1_body() +{ + cat >expout <expout < + +#include +#include +#include + +#include "h_macros.h" + +ATF_TC(rtld_dlerror_cleared); +ATF_TC_HEAD(rtld_dlerror_cleared, tc) +{ + atf_tc_set_md_var(tc, "descr", + "error set by dlopen persists past a successful dlopen call"); +} + +ATF_TC_BODY(rtld_dlerror_cleared, tc) +{ + void *handle; + char *error; + + /* + * Test that an error set by dlopen() persists past a successful + * dlopen() call. + */ + handle = dlopen("libnonexistent.so", RTLD_LAZY); + ATF_CHECK(handle == NULL); + handle = dlopen("libm.so", RTLD_NOW); + ATF_CHECK(handle); + error = dlerror(); + ATF_CHECK(error); + +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, rtld_dlerror_cleared); + return 0; +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/t_dlerror-false.c b/contrib/netbsd-tests/libexec/ld.elf_so/t_dlerror-false.c new file mode 100644 index 0000000..31b96e8 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/t_dlerror-false.c @@ -0,0 +1,79 @@ +/* $NetBSD: t_dlerror-false.c,v 1.2 2017/01/13 21:30:42 christos Exp $ */ + +/* + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include + +#include "h_macros.h" + +ATF_TC(rtld_dlerror_false); +ATF_TC_HEAD(rtld_dlerror_false, tc) +{ + atf_tc_set_md_var(tc, "descr", + "error set by dlopen persists past a successful dlopen call"); +} + +ATF_TC_BODY(rtld_dlerror_false, tc) +{ + void *handle, *sym; + char *error; + + /* + * + * Test for dlerror() being set by a successful library open. + * Requires that the rpath be set to something that does not + * include libm.so. + */ + + handle = dlopen("libm.so", RTLD_LAZY); + error = dlerror(); + ATF_CHECK(error == NULL); + ATF_CHECK(handle != NULL); + + sym = dlsym(handle, "sin"); + error = dlerror(); + ATF_CHECK(sym != NULL); + ATF_CHECK(error == NULL); + + dlclose(handle); + error = dlerror(); + + ATF_CHECK(error == NULL); + +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, rtld_dlerror_false); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/t_dlinfo.c b/contrib/netbsd-tests/libexec/ld.elf_so/t_dlinfo.c new file mode 100644 index 0000000..7b12528 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/t_dlinfo.c @@ -0,0 +1,120 @@ +/* $NetBSD: t_dlinfo.c,v 1.5 2017/01/13 21:30:42 christos Exp $ */ + +/* + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include + +#include "h_macros.h" + +ATF_TC(rtld_dlinfo_linkmap_self); +ATF_TC_HEAD(rtld_dlinfo_linkmap_self, tc) +{ + atf_tc_set_md_var(tc, "descr", "dlinfo with RTLD_SELF handle works"); +} +ATF_TC_BODY(rtld_dlinfo_linkmap_self, tc) +{ + struct link_map *map; + int rv; + + rv = dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &map); + ATF_CHECK_EQ(rv, 0); + ATF_CHECK((strstr(map->l_name, "t_dlinfo") != NULL)); +} + +ATF_TC(rtld_dlinfo_linkmap_inval); +ATF_TC_HEAD(rtld_dlinfo_linkmap_inval, tc) +{ + atf_tc_set_md_var(tc, "descr", "dlinfo with invalid handle fails"); +} +ATF_TC_BODY(rtld_dlinfo_linkmap_inval, tc) +{ + void *v; + int rv; + + rv = dlinfo(NULL, RTLD_DI_LINKMAP, &v); + ATF_CHECK_EQ(rv, -1); +} + +ATF_TC(rtld_dlinfo_linkmap_dlopen); +ATF_TC_HEAD(rtld_dlinfo_linkmap_dlopen, tc) +{ + atf_tc_set_md_var(tc, "descr", "dlinfo dlopen'd handle works"); +} +ATF_TC_BODY(rtld_dlinfo_linkmap_dlopen, tc) +{ + struct link_map *map; + void *handle; + int rv; + + handle = dlopen("libutil.so", RTLD_LAZY); + ATF_CHECK(handle); + + rv = dlinfo(handle, RTLD_DI_LINKMAP, &map); + ATF_CHECK_EQ(rv, 0); + ATF_CHECK((strstr(map->l_name, "libutil.so") != NULL)); + dlclose(handle); +} + +ATF_TC(rtld_dlinfo_linkmap_dlopen_iter); +ATF_TC_HEAD(rtld_dlinfo_linkmap_dlopen_iter, tc) +{ + atf_tc_set_md_var(tc, "descr", "dlopen'd dso's show up in the list"); +} +ATF_TC_BODY(rtld_dlinfo_linkmap_dlopen_iter, tc) +{ + struct link_map *map; + void *handle; + + handle = dlopen("libutil.so", RTLD_LAZY); + ATF_CHECK(handle); + + RZ(dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &map)); + + for (; map->l_next; map = map->l_next) + continue; + for (; map; map = map->l_prev) + if (strstr(map->l_name, "libutil.so") != NULL) + break; + + ATF_REQUIRE_MSG(map, "dlopen()d object not found from linkmap"); + ATF_REQUIRE_MSG(dlopen(map->l_name, RTLD_LAZY) != NULL, + "could not dlopen() name in linkmap"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, rtld_dlinfo_linkmap_self); + ATF_TP_ADD_TC(tp, rtld_dlinfo_linkmap_inval); + ATF_TP_ADD_TC(tp, rtld_dlinfo_linkmap_dlopen); + ATF_TP_ADD_TC(tp, rtld_dlinfo_linkmap_dlopen_iter); + return 0; +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/t_dlvsym.c b/contrib/netbsd-tests/libexec/ld.elf_so/t_dlvsym.c new file mode 100644 index 0000000..ce437d4 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/t_dlvsym.c @@ -0,0 +1,203 @@ +/* $NetBSD: t_dlvsym.c,v 1.1 2011/06/25 05:45:13 nonaka Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by NONAKA Kimihiro. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include + +ATF_TC(rtld_dlvsym_v1); +ATF_TC_HEAD(rtld_dlvsym_v1, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check dlvsym() function (V_1)"); +} +ATF_TC_BODY(rtld_dlvsym_v1, tc) +{ + void *handle; + char *error; + int (*sym)(void); + int result; + + /* Clear previous error */ + (void) dlerror(); + + handle = dlopen("libh_helper_symver_dso.so", RTLD_LAZY); + error = dlerror(); + ATF_CHECK(error == NULL); + ATF_CHECK(handle != NULL); + + sym = dlvsym(handle, "testfunc", "V_1"); + error = dlerror(); + ATF_CHECK(error == NULL); + + result = (*sym)(); + ATF_CHECK(result == 1); + + dlclose(handle); + error = dlerror(); + ATF_CHECK(error == NULL); +} + +ATF_TC(rtld_dlvsym_v3); +ATF_TC_HEAD(rtld_dlvsym_v3, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check dlvsym() function (V_3)"); +} +ATF_TC_BODY(rtld_dlvsym_v3, tc) +{ + void *handle; + char *error; + int (*sym)(void); + int result; + + /* Clear previous error */ + (void) dlerror(); + + handle = dlopen("libh_helper_symver_dso.so", RTLD_LAZY); + error = dlerror(); + ATF_CHECK(error == NULL); + ATF_CHECK(handle != NULL); + + sym = dlvsym(handle, "testfunc", "V_3"); + error = dlerror(); + ATF_CHECK(error == NULL); + + result = (*sym)(); + ATF_CHECK(result == 3); + + dlclose(handle); + error = dlerror(); + ATF_CHECK(error == NULL); +} + +ATF_TC(rtld_dlvsym_symbol_nonexistent); +ATF_TC_HEAD(rtld_dlvsym_symbol_nonexistent, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Check dlvsym() function (symbol is nonexistent)"); +} +ATF_TC_BODY(rtld_dlvsym_symbol_nonexistent, tc) +{ + void *handle; + char *error; + int (*sym)(void); + + /* Clear previous error */ + (void) dlerror(); + + handle = dlopen("libh_helper_symver_dso.so", RTLD_LAZY); + error = dlerror(); + ATF_CHECK(error == NULL); + ATF_CHECK(handle != NULL); + + sym = dlvsym(handle, "symbol_nonexistent", "V_3"); + error = dlerror(); + ATF_CHECK(sym == NULL); + ATF_CHECK(error != NULL); + + dlclose(handle); + error = dlerror(); + ATF_CHECK(error == NULL); +} + +ATF_TC(rtld_dlvsym_version_nonexistent); +ATF_TC_HEAD(rtld_dlvsym_version_nonexistent, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Check dlvsym() function (version is nonexistent)"); +} +ATF_TC_BODY(rtld_dlvsym_version_nonexistent, tc) +{ + void *handle; + char *error; + int (*sym)(void); + + /* Clear previous error */ + (void) dlerror(); + + handle = dlopen("libh_helper_symver_dso.so", RTLD_LAZY); + error = dlerror(); + ATF_CHECK(error == NULL); + ATF_CHECK(handle != NULL); + + sym = dlvsym(handle, "testfunc", ""); + error = dlerror(); + ATF_CHECK(sym == NULL); + ATF_CHECK(error != NULL); + + dlclose(handle); + error = dlerror(); + ATF_CHECK(error == NULL); +} + +ATF_TC(rtld_dlvsym_version_null); +ATF_TC_HEAD(rtld_dlvsym_version_null, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Check dlvsym() function (version is NULL)"); +} +ATF_TC_BODY(rtld_dlvsym_version_null, tc) +{ + void *handle; + char *error; + int (*sym)(void); + int result; + + /* Clear previous error */ + (void) dlerror(); + + handle = dlopen("libh_helper_symver_dso.so", RTLD_LAZY); + error = dlerror(); + ATF_CHECK(error == NULL); + ATF_CHECK(handle != NULL); + + sym = dlvsym(handle, "testfunc", NULL); + error = dlerror(); + ATF_CHECK(error == NULL); + + result = (*sym)(); + ATF_CHECK(result == 3); + + dlclose(handle); + error = dlerror(); + ATF_CHECK(error == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, rtld_dlvsym_v1); + ATF_TP_ADD_TC(tp, rtld_dlvsym_v3); + ATF_TP_ADD_TC(tp, rtld_dlvsym_symbol_nonexistent); + ATF_TP_ADD_TC(tp, rtld_dlvsym_version_nonexistent); + ATF_TP_ADD_TC(tp, rtld_dlvsym_version_null); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/libexec/ld.elf_so/t_ifunc.c b/contrib/netbsd-tests/libexec/ld.elf_so/t_ifunc.c new file mode 100644 index 0000000..68468d4 --- /dev/null +++ b/contrib/netbsd-tests/libexec/ld.elf_so/t_ifunc.c @@ -0,0 +1,92 @@ +/* $NetBSD: t_ifunc.c,v 1.2 2017/01/13 21:30:42 christos Exp $ */ + +/* + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include + +#include "h_macros.h" + +ATF_TC(rtld_ifunc); + +ATF_TC_HEAD(rtld_ifunc, tc) +{ + atf_tc_set_md_var(tc, "descr", "ifunc functions are resolved"); +} + +ATF_TC_BODY(rtld_ifunc, tc) +{ + const char *envstr[] = { + "0", "1" + }; + int expected_result[] = { + 0xdeadbeef, 0xbeefdead + }; + void *handle; + int (*sym)(void); + int result; + const char *error; + size_t i; + + for (i = 0; i < __arraycount(envstr); ++i) { + setenv("USE_IFUNC2", envstr[i], 1); + + handle = dlopen("libh_helper_ifunc_dso.so", RTLD_LAZY); + error = dlerror(); + ATF_CHECK(error == NULL); + ATF_CHECK(handle != NULL); + + sym = dlsym(handle, "ifunc"); + error = dlerror(); + ATF_CHECK(error == NULL); + ATF_CHECK(sym != NULL); + + result = (*sym)(); + ATF_CHECK(result == expected_result[i]); + + dlclose(handle); + error = dlerror(); + ATF_CHECK(error == NULL); + + char *command; + easprintf(&command, "%s/h_ifunc %d", + atf_tc_get_config_var(tc, "srcdir"), expected_result[i]); + if (system(command) != EXIT_SUCCESS) + atf_tc_fail("Test failed; see output for details"); + free(command); + } +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, rtld_ifunc); + return 0; +} diff --git a/contrib/netbsd-tests/modules/k_helper/k_helper.c b/contrib/netbsd-tests/modules/k_helper/k_helper.c new file mode 100644 index 0000000..6a54ccd --- /dev/null +++ b/contrib/netbsd-tests/modules/k_helper/k_helper.c @@ -0,0 +1,202 @@ +/* $NetBSD: k_helper.c,v 1.6 2012/06/03 10:59:44 dsl Exp $ */ +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__KERNEL_RCSID(0, "$NetBSD: k_helper.c,v 1.6 2012/06/03 10:59:44 dsl Exp $"); + +#include +#include +#include +#include + +#include + +MODULE(MODULE_CLASS_MISC, k_helper, NULL); + +/* --------------------------------------------------------------------- */ +/* Sysctl interface to query information about the module. */ +/* --------------------------------------------------------------------- */ + +/* TODO: Change the integer variables below that represent booleans to + * bools, once sysctl(8) supports CTLTYPE_BOOL nodes. */ + +static struct sysctllog *clogp; +static int present = 1; +static int prop_str_ok; +static char prop_str_val[128]; +static int prop_int_ok; +static int64_t prop_int_val; +static int prop_int_load; + +#define K_HELPER 0x12345678 +#define K_HELPER_PRESENT 0 +#define K_HELPER_PROP_STR_OK 1 +#define K_HELPER_PROP_STR_VAL 2 +#define K_HELPER_PROP_INT_OK 3 +#define K_HELPER_PROP_INT_VAL 4 +#define K_HELPER_PROP_INT_LOAD 5 + +SYSCTL_SETUP(sysctl_k_helper_setup, "sysctl k_helper subtree setup") +{ + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_NODE, "k_helper", NULL, + NULL, 0, NULL, 0, + CTL_VENDOR, K_HELPER, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_INT, "present", + SYSCTL_DESCR("Whether the module was loaded or not"), + NULL, 0, &present, 0, + CTL_VENDOR, K_HELPER, K_HELPER_PRESENT, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_INT, "prop_str_ok", + SYSCTL_DESCR("String property's validity"), + NULL, 0, &prop_str_ok, 0, + CTL_VENDOR, K_HELPER, K_HELPER_PROP_STR_OK, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_STRING, "prop_str_val", + SYSCTL_DESCR("String property's value"), + NULL, 0, prop_str_val, 0, + CTL_VENDOR, K_HELPER, K_HELPER_PROP_STR_VAL, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_INT, "prop_int_ok", + SYSCTL_DESCR("String property's validity"), + NULL, 0, &prop_int_ok, 0, + CTL_VENDOR, K_HELPER, K_HELPER_PROP_INT_OK, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_QUAD, "prop_int_val", + SYSCTL_DESCR("String property's value"), + NULL, 0, &prop_int_val, 0, + CTL_VENDOR, K_HELPER, K_HELPER_PROP_INT_VAL, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_INT, "prop_int_load", + SYSCTL_DESCR("Status of recursive modload"), + NULL, 0, &prop_int_load, 0, + CTL_VENDOR, K_HELPER, K_HELPER_PROP_INT_LOAD, CTL_EOL); +} + +/* --------------------------------------------------------------------- */ +/* Module management. */ +/* --------------------------------------------------------------------- */ + +static +int +k_helper_init(prop_dictionary_t props) +{ + prop_object_t p; + + p = prop_dictionary_get(props, "prop_str"); + if (p == NULL) + prop_str_ok = 0; + else if (prop_object_type(p) != PROP_TYPE_STRING) + prop_str_ok = 0; + else { + const char *msg = prop_string_cstring_nocopy(p); + if (msg == NULL) + prop_str_ok = 0; + else { + strlcpy(prop_str_val, msg, sizeof(prop_str_val)); + prop_str_ok = 1; + } + } + if (!prop_str_ok) + strlcpy(prop_str_val, "", sizeof(prop_str_val)); + + p = prop_dictionary_get(props, "prop_int"); + if (p == NULL) + prop_int_ok = 0; + else if (prop_object_type(p) != PROP_TYPE_NUMBER) + prop_int_ok = 0; + else { + prop_int_val = prop_number_integer_value(p); + prop_int_ok = 1; + } + if (!prop_int_ok) + prop_int_val = -1; + + p = prop_dictionary_get(props, "prop_recurse"); + if (p != NULL && prop_object_type(p) == PROP_TYPE_STRING) { + const char *recurse_name = prop_string_cstring_nocopy(p); + if (recurse_name != NULL) + prop_int_load = module_load(recurse_name, + MODCTL_NO_PROP, NULL, MODULE_CLASS_ANY); + else + prop_int_load = -1; + } else + prop_int_load = -2; + + sysctl_k_helper_setup(&clogp); + + return 0; +} + +static +int +k_helper_fini(void *arg) +{ + + sysctl_teardown(&clogp); + + return 0; +} + +static +int +k_helper_modcmd(modcmd_t cmd, void *arg) +{ + int ret; + + switch (cmd) { + case MODULE_CMD_INIT: + ret = k_helper_init(arg); + break; + + case MODULE_CMD_FINI: + ret = k_helper_fini(arg); + break; + + case MODULE_CMD_STAT: + default: + ret = ENOTTY; + } + + return ret; +} diff --git a/contrib/netbsd-tests/modules/k_helper2/k_helper2.c b/contrib/netbsd-tests/modules/k_helper2/k_helper2.c new file mode 100644 index 0000000..286b25a --- /dev/null +++ b/contrib/netbsd-tests/modules/k_helper2/k_helper2.c @@ -0,0 +1,115 @@ +/* $NetBSD: k_helper2.c,v 1.2 2010/11/03 16:10:23 christos Exp $ */ +/* + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__KERNEL_RCSID(0, "$NetBSD: k_helper2.c,v 1.2 2010/11/03 16:10:23 christos Exp $"); + +#include +#include +#include +#include + +#include + +MODULE(MODULE_CLASS_MISC, k_helper2, NULL); + +/* --------------------------------------------------------------------- */ +/* Sysctl interface to query information about the module. */ +/* --------------------------------------------------------------------- */ + +/* TODO: Change the integer variables below that represent booleans to + * bools, once sysctl(8) supports CTLTYPE_BOOL nodes. */ + +static struct sysctllog *clogp; +static int present = 1; + +#define K_HELPER2 0x23456781 +#define K_HELPER_PRESENT 0 + +SYSCTL_SETUP(sysctl_k_helper2_setup, "sysctl k_helper subtree setup") +{ + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_NODE, "k_helper2", NULL, + NULL, 0, NULL, 0, + CTL_VENDOR, K_HELPER2, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_INT, "present", + SYSCTL_DESCR("Whether the module was loaded or not"), + NULL, 0, &present, 0, + CTL_VENDOR, K_HELPER2, K_HELPER_PRESENT, CTL_EOL); +} + +/* --------------------------------------------------------------------- */ +/* Module management. */ +/* --------------------------------------------------------------------- */ + +static +int +k_helper2_init(prop_dictionary_t props) +{ + sysctl_k_helper2_setup(&clogp); + + return 0; +} + +static +int +k_helper2_fini(void *arg) +{ + + sysctl_teardown(&clogp); + + return 0; +} + +static +int +k_helper2_modcmd(modcmd_t cmd, void *arg) +{ + int ret; + + switch (cmd) { + case MODULE_CMD_INIT: + ret = k_helper2_init(arg); + break; + + case MODULE_CMD_FINI: + ret = k_helper2_fini(arg); + break; + + case MODULE_CMD_STAT: + default: + ret = ENOTTY; + } + + return ret; +} diff --git a/contrib/netbsd-tests/modules/k_helper3/k_helper3.c b/contrib/netbsd-tests/modules/k_helper3/k_helper3.c new file mode 100644 index 0000000..4e0984d --- /dev/null +++ b/contrib/netbsd-tests/modules/k_helper3/k_helper3.c @@ -0,0 +1,102 @@ +/* $NetBSD: k_helper3.c,v 1.3 2012/04/17 21:39:19 martin Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: k_helper3.c,v 1.3 2012/04/17 21:39:19 martin Exp $"); + +#include + +#include +#include +#include +#include +#include +#include + +#include + +static int load(const char *, ...); + +/* + * A program that loads a module and returns the errno(2) from modctl(8). + */ +int +main(int argc, char *argv[]) +{ + assert(argc == 3); + + return load(argv[1], argv[2]); +} + +static __printflike(1, 2) int +load(const char *fmt, ...) +{ + char filename[MAXPATHLEN], *propsstr, *shortname, *dot; + prop_dictionary_t props; + modctl_load_t ml; + int serrno, rv; + va_list ap; + + props = prop_dictionary_create(); + propsstr = prop_dictionary_externalize(props); + assert(propsstr != NULL); + prop_object_release(props); + + va_start(ap, fmt); + (void)vsnprintf(filename, sizeof(filename), fmt, ap); + va_end(ap); + + ml.ml_filename = filename; + ml.ml_flags = 0; + ml.ml_props = propsstr; + ml.ml_propslen = strlen(propsstr); + + printf("Loading module %s\n", filename); + errno = serrno = 0; + + rv = modctl(MODCTL_LOAD, &ml); + + if (rv != 0) + serrno = errno; + + shortname = strrchr(filename, '/'); + if (shortname != NULL) + shortname++; + else + shortname = filename; + dot = strrchr(shortname, '.'); + if (dot) + *dot = 0; + (void)modctl(MODCTL_UNLOAD, shortname); + + free(propsstr); + + return serrno; +} diff --git a/contrib/netbsd-tests/modules/k_uvm/k_uvm.c b/contrib/netbsd-tests/modules/k_uvm/k_uvm.c new file mode 100644 index 0000000..7f8d3b0 --- /dev/null +++ b/contrib/netbsd-tests/modules/k_uvm/k_uvm.c @@ -0,0 +1,113 @@ +/* $NetBSD: k_uvm.c,v 1.1 2012/02/17 22:36:50 jmmv Exp $ */ +/* + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__KERNEL_RCSID(0, "$NetBSD: k_uvm.c,v 1.1 2012/02/17 22:36:50 jmmv Exp $"); + +#include +#include +#include +#include + +MODULE(MODULE_CLASS_MISC, k_uvm, NULL); + +/* --------------------------------------------------------------------- */ +/* Sysctl interface to query information about the module. */ +/* --------------------------------------------------------------------- */ + +static struct sysctllog *clogp; +static int page_size; + +#define K_UVM 0x12345678 +#define K_UVM_VALUE 0 + +SYSCTL_SETUP(sysctl_k_uvm_setup, "sysctl k_uvm subtree setup") +{ + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_NODE, "k_uvm", NULL, + NULL, 0, NULL, 0, + CTL_VENDOR, K_UVM, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_INT, "page_size", + SYSCTL_DESCR("Value of PAGE_SIZE"), + NULL, 0, &page_size, 0, + CTL_VENDOR, K_UVM, K_UVM_VALUE, CTL_EOL); +} + +/* --------------------------------------------------------------------- */ +/* Module management. */ +/* --------------------------------------------------------------------- */ + +static +int +k_uvm_init(prop_dictionary_t props) +{ + + page_size = PAGE_SIZE; + + sysctl_k_uvm_setup(&clogp); + + return 0; +} + +static +int +k_uvm_fini(void *arg) +{ + + sysctl_teardown(&clogp); + + return 0; +} + +static +int +k_uvm_modcmd(modcmd_t cmd, void *arg) +{ + int ret; + + switch (cmd) { + case MODULE_CMD_INIT: + ret = k_uvm_init(arg); + break; + + case MODULE_CMD_FINI: + ret = k_uvm_fini(arg); + break; + + case MODULE_CMD_STAT: + default: + ret = ENOTTY; + } + + return ret; +} diff --git a/contrib/netbsd-tests/modules/t_abi_uvm.sh b/contrib/netbsd-tests/modules/t_abi_uvm.sh new file mode 100755 index 0000000..b855bc8 --- /dev/null +++ b/contrib/netbsd-tests/modules/t_abi_uvm.sh @@ -0,0 +1,70 @@ +# $NetBSD: t_abi_uvm.sh,v 1.3 2012/04/20 05:41:25 jruoho Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case PAGE_SIZE cleanup +PAGE_SIZE_head() { + atf_set "descr" "Ensures that modules have access to PAGE_SIZE" + atf_set "require.user" "root" +} +PAGE_SIZE_body() { + + # XXX: Adjust when modctl(8) fails consistently. + # + $(atf_get_srcdir)/k_helper3 \ + "%s/k_helper/k_helper.kmod" $(atf_get_srcdir) + + if [ $? -eq 1 ] || [ $? -eq 78 ]; then + atf_skip "host does not support modules" + fi + + if modload $(atf_get_srcdir)/k_uvm/k_uvm.kmod; then + : + else + case "$(uname -m)" in + macppc) + atf_expect_fail "PR port-macppc/46041" + ;; + esac + atf_fail "Failed to load k_uvm; missing uvmexp_pagesize?" + fi + + kernel_pagesize="$(sysctl -n hw.pagesize || echo fail1)" + module_pagesize="$(sysctl -n vendor.k_uvm.page_size || echo fail2)" + echo "Kernel PAGE_SIZE: ${kernel_pagesize}" + echo "Module PAGE_SIZE: ${module_pagesize}" + atf_check_equal "${kernel_pagesize}" "${module_pagesize}" + + atf_check -s eq:0 -o empty -e empty modunload k_uvm +} +PAGE_SIZE_cleanup() { + modunload k_uvm >/dev/null 2>&1 || true +} + +atf_init_test_cases() +{ + atf_add_test_case PAGE_SIZE +} diff --git a/contrib/netbsd-tests/modules/t_builtin.c b/contrib/netbsd-tests/modules/t_builtin.c new file mode 100644 index 0000000..79845b8 --- /dev/null +++ b/contrib/netbsd-tests/modules/t_builtin.c @@ -0,0 +1,194 @@ +/* $NetBSD: t_builtin.c,v 1.3 2017/01/13 21:30:42 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include "h_macros.h" + +#define MYMP "/mnt" +#define HZFILE MYMP "/hz" + +static char kernfs[] = "kernfs"; + +static bool +check_kernfs(void) +{ + char buf[16]; + bool rv = true; + int fd; + + fd = rump_sys_open(HZFILE, O_RDONLY); + if (fd == -1) + return false; + if (rump_sys_read(fd, buf, sizeof(buf)) < 1) + rv = false; + RL(rump_sys_close(fd)); + + return rv; +} + +ATF_TC(disable); +ATF_TC_HEAD(disable, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Tests that builtin modules can " + "be disabled"); +} + +ATF_TC_BODY(disable, tc) +{ + + rump_init(); + RL(rump_sys_mkdir(MYMP, 0777)); + RL(rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0)); + ATF_REQUIRE(check_kernfs()); + RL(rump_sys_unmount(MYMP, 0)); + RL(rump_sys_modctl(MODCTL_UNLOAD, kernfs)); +} + +ATF_TC(noauto); +ATF_TC_HEAD(noauto, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests that disabled builtin modules " + "will not autoload"); +} + +ATF_TC_BODY(noauto, tc) +{ + + rump_init(); + RL(rump_sys_mkdir(MYMP, 0777)); + + RL(rump_sys_modctl(MODCTL_UNLOAD, kernfs)); + + ATF_REQUIRE_ERRNO(ENODEV, + rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0) == -1); +} + +ATF_TC(forcereload); +ATF_TC_HEAD(forcereload, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests that disabled builtin modules " + "can be force-reloaded"); +} + +ATF_TC_BODY(forcereload, tc) +{ + struct modctl_load mod; + + rump_init(); + RL(rump_sys_mkdir(MYMP, 0777)); + + RL(rump_sys_modctl(MODCTL_UNLOAD, kernfs)); + ATF_REQUIRE_ERRNO(ENODEV, + rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0) == -1); + + memset(&mod, 0, sizeof(mod)); + mod.ml_filename = kernfs; + mod.ml_flags = MODCTL_LOAD_FORCE; + + RL(rump_sys_modctl(MODCTL_LOAD, &mod)); + + RL(rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0)); + ATF_REQUIRE(check_kernfs()); + RL(rump_sys_unmount(MYMP, 0)); +} + +ATF_TC(disabledstat); +ATF_TC_HEAD(disabledstat, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests that disabled builtin modules " + "show up in modstat with refcount -1"); +} + +ATF_TC_BODY(disabledstat, tc) +{ + struct modstat ms[128]; + struct iovec iov; + size_t i; + bool found = false; + + rump_init(); + RL(rump_sys_mkdir(MYMP, 0777)); + + RL(rump_sys_modctl(MODCTL_UNLOAD, kernfs)); + + iov.iov_base = ms; + iov.iov_len = sizeof(ms); + RL(rump_sys_modctl(MODCTL_STAT, &iov)); + + for (i = 0; i < __arraycount(ms); i++) { + if (strcmp(ms[i].ms_name, kernfs) == 0) { + ATF_REQUIRE_EQ(ms[i].ms_refcnt, (u_int)-1); + found = 1; + break; + } + } + ATF_REQUIRE(found); +} + +ATF_TC(busydisable); +ATF_TC_HEAD(busydisable, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests that busy builtin modules " + "cannot be disabled"); +} + +ATF_TC_BODY(busydisable, tc) +{ + + rump_init(); + RL(rump_sys_mkdir(MYMP, 0777)); + RL(rump_sys_mount(MOUNT_KERNFS, MYMP, 0, NULL, 0)); + ATF_REQUIRE(check_kernfs()); + ATF_REQUIRE_ERRNO(EBUSY, + rump_sys_modctl(MODCTL_UNLOAD, kernfs) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, disable); + ATF_TP_ADD_TC(tp, noauto); + ATF_TP_ADD_TC(tp, forcereload); + ATF_TP_ADD_TC(tp, disabledstat); + ATF_TP_ADD_TC(tp, busydisable); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/modules/t_modctl.c b/contrib/netbsd-tests/modules/t_modctl.c new file mode 100644 index 0000000..50cd907 --- /dev/null +++ b/contrib/netbsd-tests/modules/t_modctl.c @@ -0,0 +1,493 @@ +/* $NetBSD: t_modctl.c,v 1.12 2012/08/20 08:07:52 martin Exp $ */ +/* + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__KERNEL_RCSID(0, "$NetBSD: t_modctl.c,v 1.12 2012/08/20 08:07:52 martin Exp $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +enum presence_check { both_checks, stat_check, sysctl_check }; + +static void check_permission(void); +static bool get_modstat_info(const char *, modstat_t *); +static bool get_sysctl(const char *, void *buf, const size_t); +static bool k_helper_is_present_stat(void); +static bool k_helper_is_present_sysctl(void); +static bool k_helper_is_present(enum presence_check); +static int load(prop_dictionary_t, bool, const char *, ...); +static int unload(const char *, bool); +static void unload_cleanup(const char *); + +/* --------------------------------------------------------------------- */ +/* Auxiliary functions */ +/* --------------------------------------------------------------------- */ + +/* + * A function checking wether we are allowed to load modules currently + * (either the kernel is not modular, or securelevel may prevent it) + */ +static void +check_permission(void) +{ + int err; + + err = modctl(MODCTL_EXISTS, 0); + if (err == 0) return; + if (errno == ENOSYS) + atf_tc_skip("Kernel does not have 'options MODULAR'."); + else if (errno == EPERM) + atf_tc_skip("Module loading administratively forbidden"); + ATF_REQUIRE_EQ_MSG(errno, 0, "unexpected error %d from " + "modctl(MODCTL_EXISTS, 0)", errno); +} + +static bool +get_modstat_info(const char *name, modstat_t *msdest) +{ + bool found; + size_t len; + struct iovec iov; + modstat_t *ms; + + check_permission(); + for (len = 4096; ;) { + iov.iov_base = malloc(len); + iov.iov_len = len; + + errno = 0; + + if (modctl(MODCTL_STAT, &iov) != 0) { + int err = errno; + fprintf(stderr, "modctl(MODCTL_STAT) failed: %s\n", + strerror(err)); + atf_tc_fail("Failed to query module status"); + } + if (len >= iov.iov_len) + break; + free(iov.iov_base); + len = iov.iov_len; + } + + found = false; + len = iov.iov_len / sizeof(modstat_t); + for (ms = (modstat_t *)iov.iov_base; len != 0 && !found; + ms++, len--) { + if (strcmp(ms->ms_name, name) == 0) { + if (msdest != NULL) + *msdest = *ms; + found = true; + } + } + + free(iov.iov_base); + + return found; +} + +/* + * Queries a sysctl property. + */ +static bool +get_sysctl(const char *name, void *buf, const size_t len) +{ + size_t len2 = len; + printf("Querying sysctl variable: %s\n", name); + int ret = sysctlbyname(name, buf, &len2, NULL, 0); + if (ret == -1 && errno != ENOENT) { + fprintf(stderr, "sysctlbyname(2) failed: %s\n", + strerror(errno)); + atf_tc_fail("Failed to query %s", name); + } + return ret != -1; +} + +/* + * Returns a boolean indicating if the k_helper module was loaded + * successfully. This implementation uses modctl(2)'s MODCTL_STAT + * subcommand to do the check. + */ +static bool +k_helper_is_present_stat(void) +{ + + return get_modstat_info("k_helper", NULL); +} + +/* + * Returns a boolean indicating if the k_helper module was loaded + * successfully. This implementation uses the module's sysctl + * installed node to do the check. + */ +static bool +k_helper_is_present_sysctl(void) +{ + size_t present; + + return get_sysctl("vendor.k_helper.present", &present, + sizeof(present)); +} + +/* + * Returns a boolean indicating if the k_helper module was loaded + * successfully. The 'how' parameter specifies the implementation to + * use to do the check. + */ +static bool +k_helper_is_present(enum presence_check how) +{ + bool found; + + switch (how) { + case both_checks: + found = k_helper_is_present_stat(); + ATF_CHECK(k_helper_is_present_sysctl() == found); + break; + + case stat_check: + found = k_helper_is_present_stat(); + break; + + case sysctl_check: + found = k_helper_is_present_sysctl(); + break; + + default: + found = false; + assert(found); + } + + return found; +} + +/* + * Loads the specified module from a file. If fatal is set and an error + * occurs when loading the module, an error message is printed and the + * test case is aborted. + */ +static __printflike(3, 4) int +load(prop_dictionary_t props, bool fatal, const char *fmt, ...) +{ + int err; + va_list ap; + char filename[MAXPATHLEN], *propsstr; + modctl_load_t ml; + + check_permission(); + if (props == NULL) { + props = prop_dictionary_create(); + propsstr = prop_dictionary_externalize(props); + ATF_CHECK(propsstr != NULL); + prop_object_release(props); + } else { + propsstr = prop_dictionary_externalize(props); + ATF_CHECK(propsstr != NULL); + } + + va_start(ap, fmt); + vsnprintf(filename, sizeof(filename), fmt, ap); + va_end(ap); + + ml.ml_filename = filename; + ml.ml_flags = 0; + ml.ml_props = propsstr; + ml.ml_propslen = strlen(propsstr); + + printf("Loading module %s\n", filename); + errno = err = 0; + + if (modctl(MODCTL_LOAD, &ml) == -1) { + err = errno; + fprintf(stderr, "modctl(MODCTL_LOAD, %s), failed: %s\n", + filename, strerror(err)); + if (fatal) + atf_tc_fail("Module load failed"); + } + + free(propsstr); + + return err; +} + +/* + * Unloads the specified module. If silent is true, nothing will be + * printed and no errors will be raised if the unload was unsuccessful. + */ +static int +unload(const char *name, bool fatal) +{ + int err; + + check_permission(); + printf("Unloading module %s\n", name); + errno = err = 0; + + if (modctl(MODCTL_UNLOAD, __UNCONST(name)) == -1) { + err = errno; + fprintf(stderr, "modctl(MODCTL_UNLOAD, %s) failed: %s\n", + name, strerror(err)); + if (fatal) + atf_tc_fail("Module unload failed"); + } + return err; +} + +/* + * A silent version of unload, to be called as part of the cleanup + * process only. + */ +static void +unload_cleanup(const char *name) +{ + + (void)modctl(MODCTL_UNLOAD, __UNCONST(name)); +} + +/* --------------------------------------------------------------------- */ +/* Test cases */ +/* --------------------------------------------------------------------- */ + +ATF_TC_WITH_CLEANUP(cmd_load); +ATF_TC_HEAD(cmd_load, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests for the MODCTL_LOAD command"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(cmd_load, tc) +{ + char longname[MAXPATHLEN]; + size_t i; + + ATF_CHECK(load(NULL, false, " ") == ENOENT); + ATF_CHECK(load(NULL, false, "non-existent.o") == ENOENT); + + for (i = 0; i < MAXPATHLEN - 1; i++) + longname[i] = 'a'; + longname[MAXPATHLEN - 1] = '\0'; + ATF_CHECK(load(NULL, false, "%s", longname) == ENAMETOOLONG); + + ATF_CHECK(!k_helper_is_present(stat_check)); + load(NULL, true, "%s/k_helper/k_helper.kmod", + atf_tc_get_config_var(tc, "srcdir")); + printf("Checking if load was successful\n"); + ATF_CHECK(k_helper_is_present(stat_check)); +} +ATF_TC_CLEANUP(cmd_load, tc) +{ + unload_cleanup("k_helper"); +} + +ATF_TC_WITH_CLEANUP(cmd_load_props); +ATF_TC_HEAD(cmd_load_props, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests for the MODCTL_LOAD command, " + "providing extra load-time properties"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(cmd_load_props, tc) +{ + prop_dictionary_t props; + + printf("Loading module without properties\n"); + props = prop_dictionary_create(); + load(props, true, "%s/k_helper/k_helper.kmod", + atf_tc_get_config_var(tc, "srcdir")); + prop_object_release(props); + { + int ok; + ATF_CHECK(get_sysctl("vendor.k_helper.prop_str_ok", + &ok, sizeof(ok))); + ATF_CHECK(!ok); + } + unload("k_helper", true); + + printf("Loading module with a string property\n"); + props = prop_dictionary_create(); + prop_dictionary_set(props, "prop_str", + prop_string_create_cstring("1st string")); + load(props, true, "%s/k_helper/k_helper.kmod", + atf_tc_get_config_var(tc, "srcdir")); + prop_object_release(props); + { + int ok; + ATF_CHECK(get_sysctl("vendor.k_helper.prop_str_ok", + &ok, sizeof(ok))); + ATF_CHECK(ok); + + char val[128]; + ATF_CHECK(get_sysctl("vendor.k_helper.prop_str_val", + &val, sizeof(val))); + ATF_CHECK(strcmp(val, "1st string") == 0); + } + unload("k_helper", true); + + printf("Loading module with a different string property\n"); + props = prop_dictionary_create(); + prop_dictionary_set(props, "prop_str", + prop_string_create_cstring("2nd string")); + load(props, true, "%s/k_helper/k_helper.kmod", + atf_tc_get_config_var(tc, "srcdir")); + prop_object_release(props); + { + int ok; + ATF_CHECK(get_sysctl("vendor.k_helper.prop_str_ok", + &ok, sizeof(ok))); + ATF_CHECK(ok); + + char val[128]; + ATF_CHECK(get_sysctl("vendor.k_helper.prop_str_val", + &val, sizeof(val))); + ATF_CHECK(strcmp(val, "2nd string") == 0); + } + unload("k_helper", true); +} +ATF_TC_CLEANUP(cmd_load_props, tc) +{ + unload_cleanup("k_helper"); +} + +ATF_TC_WITH_CLEANUP(cmd_load_recurse); +ATF_TC_HEAD(cmd_load_recurse, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests for the MODCTL_LOAD command, " + "with recursive module_load()"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(cmd_load_recurse, tc) +{ + prop_dictionary_t props; + char filename[MAXPATHLEN]; + + printf("Loading module with request to load another module\n"); + props = prop_dictionary_create(); + snprintf(filename, sizeof(filename), "%s/k_helper2/k_helper2.kmod", + atf_tc_get_config_var(tc, "srcdir")); + prop_dictionary_set(props, "prop_recurse", + prop_string_create_cstring(filename)); + load(props, true, "%s/k_helper/k_helper.kmod", + atf_tc_get_config_var(tc, "srcdir")); + { + int ok; + ATF_CHECK(get_sysctl("vendor.k_helper.prop_int_load", + &ok, sizeof(ok))); + ATF_CHECK(ok == 0); + ATF_CHECK(get_sysctl("vendor.k_helper2.present", + &ok, sizeof(ok))); + ATF_CHECK(ok); + } + unload("k_helper", true); + unload("k_helper2", true); +} +ATF_TC_CLEANUP(cmd_load_recurse, tc) +{ + unload_cleanup("k_helper"); + unload_cleanup("k_helper2"); +} + +ATF_TC_WITH_CLEANUP(cmd_stat); +ATF_TC_HEAD(cmd_stat, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests for the MODCTL_STAT command"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(cmd_stat, tc) +{ + ATF_CHECK(!k_helper_is_present(both_checks)); + + load(NULL, true, "%s/k_helper/k_helper.kmod", + atf_tc_get_config_var(tc, "srcdir")); + ATF_CHECK(k_helper_is_present(both_checks)); + { + modstat_t ms; + ATF_CHECK(get_modstat_info("k_helper", &ms)); + + ATF_CHECK(ms.ms_class == MODULE_CLASS_MISC); + ATF_CHECK(ms.ms_source == MODULE_SOURCE_FILESYS); + ATF_CHECK(ms.ms_refcnt == 0); + } + unload("k_helper", true); + + ATF_CHECK(!k_helper_is_present(both_checks)); +} +ATF_TC_CLEANUP(cmd_stat, tc) +{ + unload_cleanup("k_helper"); +} + +ATF_TC_WITH_CLEANUP(cmd_unload); +ATF_TC_HEAD(cmd_unload, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests for the MODCTL_UNLOAD command"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(cmd_unload, tc) +{ + load(NULL, true, "%s/k_helper/k_helper.kmod", + atf_tc_get_config_var(tc, "srcdir")); + + ATF_CHECK(unload("", false) == ENOENT); + ATF_CHECK(unload("non-existent.kmod", false) == ENOENT); + ATF_CHECK(unload("k_helper.kmod", false) == ENOENT); + + ATF_CHECK(k_helper_is_present(stat_check)); + unload("k_helper", true); + printf("Checking if unload was successful\n"); + ATF_CHECK(!k_helper_is_present(stat_check)); +} +ATF_TC_CLEANUP(cmd_unload, tc) +{ + unload_cleanup("k_helper"); +} + +/* --------------------------------------------------------------------- */ +/* Main */ +/* --------------------------------------------------------------------- */ + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, cmd_load); + ATF_TP_ADD_TC(tp, cmd_load_props); + ATF_TP_ADD_TC(tp, cmd_stat); + ATF_TP_ADD_TC(tp, cmd_load_recurse); + ATF_TP_ADD_TC(tp, cmd_unload); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/modules/t_modload.sh b/contrib/netbsd-tests/modules/t_modload.sh new file mode 100755 index 0000000..561bb6f --- /dev/null +++ b/contrib/netbsd-tests/modules/t_modload.sh @@ -0,0 +1,205 @@ +# $NetBSD: t_modload.sh,v 1.13 2012/04/20 05:41:25 jruoho Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +check_sysctl() { + echo "${1} = ${2}" >expout + atf_check -s eq:0 -o file:expout -e empty sysctl ${1} +} + +atf_test_case plain cleanup +plain_head() { + atf_set "descr" "Test load without arguments" + atf_set "require.user" "root" +} +plain_body() { + + # XXX: Adjust when modctl(8) fails consistently. + # + $(atf_get_srcdir)/k_helper3 \ + "%s/k_helper/k_helper.kmod" $(atf_get_srcdir) + + if [ $? -eq 1 ] || [ $? -eq 78 ]; then + atf_skip "host does not support modules" + fi + + cat >experr </dev/null 2>&1 +} + +atf_test_case bflag cleanup +bflag_head() { + atf_set "descr" "Test the -b flag" + atf_set "require.user" "root" +} +bflag_body() { + echo "Checking error conditions" + + atf_check -s eq:1 -o empty -e save:stderr \ + modload -b foo k_helper.kmod + atf_check -s eq:0 -o ignore -e empty \ + grep 'Invalid parameter.*foo' stderr + + atf_check -s eq:1 -o empty -e save:stderr \ + modload -b foo= k_helper.kmod + atf_check -s eq:0 -o ignore -e empty \ + grep 'Invalid boolean value' stderr + + atf_check -s eq:1 -o empty -e save:stderr \ + modload -b foo=bar k_helper.kmod + atf_check -s eq:0 -o ignore -e empty \ + grep 'Invalid boolean value.*bar' stderr + + atf_check -s eq:1 -o empty -e save:stderr \ + modload -b foo=falsea k_helper.kmod + atf_check -s eq:0 -o ignore -e empty \ + grep 'Invalid boolean value.*falsea' stderr + + atf_check -s eq:1 -o empty -e save:stderr \ + modload -b foo=truea k_helper.kmod + atf_check -s eq:0 -o ignore -e empty \ + grep 'Invalid boolean value.*truea' stderr + + # TODO Once sysctl(8) supports CTLTYPE_BOOL nodes. + #echo "Checking valid values" +} +bflag_cleanup() { + modunload k_helper >/dev/null 2>&1 || true +} + +atf_test_case iflag cleanup +iflag_head() { + atf_set "descr" "Test the -i flag" + atf_set "require.user" "root" +} +iflag_body() { + + # XXX: Adjust when modctl(8) fails consistently. + # + $(atf_get_srcdir)/k_helper3 \ + "%s/k_helper/k_helper.kmod" $(atf_get_srcdir) + + if [ $? -eq 1 ] || [ $? -eq 78 ]; then + atf_skip "host does not support modules" + fi + + echo "Checking error conditions" + + atf_check -s eq:1 -o empty -e save:stderr modload -i foo \ + k_helper/k_helper.kmod + atf_check -s eq:0 -o ignore -e empty \ + grep 'Invalid parameter.*foo' stderr + + atf_check -s eq:1 -o empty -e save:stderr modload -i foo= \ + k_helper/k_helper.kmod + atf_check -s eq:0 -o ignore -e empty \ + grep 'Invalid integer value' stderr + + atf_check -s eq:1 -o empty -e save:stderr \ + modload -i foo=bar k_helper/k_helper.kmod + atf_check -s eq:0 -o ignore -e empty \ + grep 'Invalid integer value.*bar' stderr + + atf_check -s eq:1 -o empty -e save:stderr \ + modload -i foo=123a k_helper/k_helper.kmod + atf_check -s eq:0 -o ignore -e empty \ + grep 'Invalid integer value.*123a' stderr + + echo "Checking valid values" + + for v in 5 10; do + atf_check -s eq:0 -o empty -e empty \ + modload -i prop_int="${v}" \ + $(atf_get_srcdir)/k_helper/k_helper.kmod + check_sysctl vendor.k_helper.prop_int_ok 1 + check_sysctl vendor.k_helper.prop_int_val "${v}" + atf_check -s eq:0 -o empty -e empty modunload k_helper + done + touch done +} +iflag_cleanup() { + test -f done || modunload k_helper >/dev/null 2>&1 +} + +atf_test_case sflag cleanup +sflag_head() { + atf_set "descr" "Test the -s flag" + atf_set "require.user" "root" +} +sflag_body() { + + # XXX: Adjust when modctl(8) fails consistently. + # + $(atf_get_srcdir)/k_helper3 \ + "%s/k_helper/k_helper.kmod" $(atf_get_srcdir) + + if [ $? -eq 1 ] || [ $? -eq 78 ]; then + atf_skip "host does not support modules" + fi + + echo "Checking error conditions" + + atf_check -s eq:1 -o empty -e save:stderr modload -s foo \ + k_helper/k_helper.kmod + atf_check -s eq:0 -o ignore -e empty \ + grep 'Invalid parameter.*foo' stderr + + echo "Checking valid values" + + for v in '1st string' '2nd string'; do + atf_check -s eq:0 -o empty -e empty \ + modload -s prop_str="${v}" \ + $(atf_get_srcdir)/k_helper/k_helper.kmod + check_sysctl vendor.k_helper.prop_str_ok 1 + check_sysctl vendor.k_helper.prop_str_val "${v}" + atf_check -s eq:0 -o empty -e empty modunload k_helper + done + touch done +} +sflag_cleanup() { + test -f done || modunload k_helper >/dev/null 2>&1 +} + +atf_init_test_cases() +{ + atf_add_test_case plain + atf_add_test_case bflag + atf_add_test_case iflag + atf_add_test_case sflag +} diff --git a/contrib/netbsd-tests/net/arp/t_arp.sh b/contrib/netbsd-tests/net/arp/t_arp.sh new file mode 100755 index 0000000..04e2f70 --- /dev/null +++ b/contrib/netbsd-tests/net/arp/t_arp.sh @@ -0,0 +1,612 @@ +# $NetBSD: t_arp.sh,v 1.22 2016/11/25 08:51:16 ozaki-r Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCKSRC=unix://commsock1 +SOCKDST=unix://commsock2 +IP4SRC=10.0.1.1 +IP4DST=10.0.1.2 +IP4DST_PROXYARP1=10.0.1.3 +IP4DST_PROXYARP2=10.0.1.4 + +DEBUG=${DEBUG:-false} +TIMEOUT=1 + +atf_test_case arp_cache_expiration_5s cleanup +atf_test_case arp_cache_expiration_10s cleanup +atf_test_case arp_command cleanup +atf_test_case arp_garp cleanup +atf_test_case arp_cache_overwriting cleanup +atf_test_case arp_proxy_arp_pub cleanup +atf_test_case arp_proxy_arp_pubproxy cleanup +atf_test_case arp_link_activation cleanup +atf_test_case arp_static cleanup + +arp_cache_expiration_5s_head() +{ + atf_set "descr" "Tests for ARP cache expiration (5s)" + atf_set "require.progs" "rump_server" +} + +arp_cache_expiration_10s_head() +{ + atf_set "descr" "Tests for ARP cache expiration (10s)" + atf_set "require.progs" "rump_server" +} + +arp_command_head() +{ + atf_set "descr" "Tests for arp_commands of arp(8)" + atf_set "require.progs" "rump_server" +} + +arp_garp_head() +{ + atf_set "descr" "Tests for GARP" + atf_set "require.progs" "rump_server" +} + +arp_cache_overwriting_head() +{ + atf_set "descr" "Tests for behavior of overwriting ARP caches" + atf_set "require.progs" "rump_server" +} + +arp_proxy_arp_pub_head() +{ + atf_set "descr" "Tests for Proxy ARP (pub)" + atf_set "require.progs" "rump_server" +} + +arp_proxy_arp_pubproxy_head() +{ + atf_set "descr" "Tests for Proxy ARP (pub proxy)" + atf_set "require.progs" "rump_server" +} + +arp_link_activation_head() +{ + atf_set "descr" "Tests for activating a new MAC address" + atf_set "require.progs" "rump_server" +} + +arp_static_head() +{ + + atf_set "descr" "Tests for static ARP entries" + atf_set "require.progs" "rump_server" +} + +setup_dst_server() +{ + + rump_server_add_iface $SOCKDST shmif0 bus1 + export RUMP_SERVER=$SOCKDST + atf_check -s exit:0 rump.ifconfig shmif0 inet $IP4DST/24 + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig shmif0 + $DEBUG && rump.arp -n -a +} + +setup_src_server() +{ + local keep=$1 + + export RUMP_SERVER=$SOCKSRC + + # Adjust ARP parameters + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.arp.keep=$keep + + # Setup an interface + rump_server_add_iface $SOCKSRC shmif0 bus1 + atf_check -s exit:0 rump.ifconfig shmif0 inet $IP4SRC/24 + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + # Sanity check + $DEBUG && rump.ifconfig shmif0 + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o ignore rump.arp -n $IP4SRC + atf_check -s not-exit:0 -e ignore rump.arp -n $IP4DST +} + +test_cache_expiration() +{ + local arp_keep=$1 + local bonus=2 + + rump_server_start $SOCKSRC + rump_server_start $SOCKDST + + setup_dst_server + setup_src_server $arp_keep + + # + # Check if a cache is expired expectedly + # + export RUMP_SERVER=$SOCKSRC + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST + + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o ignore rump.arp -n $IP4SRC + # Should be cached + atf_check -s exit:0 -o ignore rump.arp -n $IP4DST + + atf_check -s exit:0 sleep $(($arp_keep + $bonus)) + + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o ignore rump.arp -n $IP4SRC + # Should be expired + atf_check -s not-exit:0 -e ignore rump.arp -n $IP4DST +} + +arp_cache_expiration_5s_body() +{ + + test_cache_expiration 5 + rump_server_destroy_ifaces +} + +arp_cache_expiration_10s_body() +{ + + test_cache_expiration 10 + rump_server_destroy_ifaces +} + +arp_command_body() +{ + local arp_keep=5 + local bonus=2 + + rump_server_start $SOCKSRC + rump_server_start $SOCKDST + + setup_dst_server + setup_src_server $arp_keep + + export RUMP_SERVER=$SOCKSRC + + # We can delete the entry for the interface's IP address + atf_check -s exit:0 -o ignore rump.arp -d $IP4SRC + + # Add and delete a static entry + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10 + atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.10 + atf_check -s exit:0 -o ignore rump.arp -d 10.0.1.10 + $DEBUG && rump.arp -n -a + atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.10 + + # Add multiple entries via a file + cat - > ./list <<-EOF + 10.0.1.11 b2:a0:20:00:00:11 + 10.0.1.12 b2:a0:20:00:00:12 + 10.0.1.13 b2:a0:20:00:00:13 + 10.0.1.14 b2:a0:20:00:00:14 + 10.0.1.15 b2:a0:20:00:00:15 + EOF + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o ignore rump.arp -f ./list + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o match:'b2:a0:20:00:00:11' rump.arp -n 10.0.1.11 + atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.11 + atf_check -s exit:0 -o match:'b2:a0:20:00:00:12' rump.arp -n 10.0.1.12 + atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.12 + atf_check -s exit:0 -o match:'b2:a0:20:00:00:13' rump.arp -n 10.0.1.13 + atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.13 + atf_check -s exit:0 -o match:'b2:a0:20:00:00:14' rump.arp -n 10.0.1.14 + atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.14 + atf_check -s exit:0 -o match:'b2:a0:20:00:00:15' rump.arp -n 10.0.1.15 + atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.15 + + # Test arp -a + atf_check -s exit:0 -o match:'10.0.1.11' rump.arp -n -a + atf_check -s exit:0 -o match:'10.0.1.12' rump.arp -n -a + atf_check -s exit:0 -o match:'10.0.1.13' rump.arp -n -a + atf_check -s exit:0 -o match:'10.0.1.14' rump.arp -n -a + atf_check -s exit:0 -o match:'10.0.1.15' rump.arp -n -a + + # Flush all entries + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o ignore rump.arp -d -a + atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.11 + atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.12 + atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.13 + atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.14 + atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.15 + atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.1 + + # Test temp option + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 temp + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10 + atf_check -s exit:0 -o not-match:'permanent' rump.arp -n 10.0.1.10 + + # Hm? the cache doesn't expire... + atf_check -s exit:0 sleep $(($arp_keep + $bonus)) + $DEBUG && rump.arp -n -a + #atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.10 + + rump_server_destroy_ifaces +} + +make_pkt_str_arpreq() +{ + local target=$1 + local sender=$2 + pkt="> ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42:" + pkt="$pkt Request who-has $target tell $sender, length 28" + echo $pkt +} + +arp_garp_body() +{ + local pkt= + + rump_server_start $SOCKSRC + + export RUMP_SERVER=$SOCKSRC + + # Setup an interface + rump_server_add_iface $SOCKSRC shmif0 bus1 + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.1/24 + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.2/24 alias + atf_check -s exit:0 rump.ifconfig shmif0 up + $DEBUG && rump.ifconfig shmif0 + + atf_check -s exit:0 sleep 1 + shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r - > ./out + + # A GARP packet is sent for the primary address + pkt=$(make_pkt_str_arpreq 10.0.0.1 10.0.0.1) + atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" + # No GARP packet is sent for the alias address + pkt=$(make_pkt_str_arpreq 10.0.0.2 10.0.0.2) + atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" + + atf_check -s exit:0 rump.ifconfig -w 10 + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.3/24 + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.4/24 alias + + # No GARP packets are sent during IFF_UP + shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r - > ./out + pkt=$(make_pkt_str_arpreq 10.0.0.3 10.0.0.3) + atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" + pkt=$(make_pkt_str_arpreq 10.0.0.4 10.0.0.4) + atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" + + rump_server_destroy_ifaces +} + +arp_cache_overwriting_body() +{ + local arp_keep=5 + local bonus=2 + + rump_server_start $SOCKSRC + rump_server_start $SOCKDST + + setup_dst_server + setup_src_server $arp_keep + + export RUMP_SERVER=$SOCKSRC + + # Cannot overwrite a permanent cache + atf_check -s not-exit:0 -e match:'File exists' \ + rump.arp -s $IP4SRC b2:a0:20:00:00:ff + $DEBUG && rump.arp -n -a + + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST + $DEBUG && rump.arp -n -a + # Can overwrite a dynamic cache + atf_check -s exit:0 -o ignore rump.arp -s $IP4DST b2:a0:20:00:00:00 + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o match:'b2:a0:20:00:00:00' rump.arp -n $IP4DST + atf_check -s exit:0 -o match:'permanent' rump.arp -n $IP4DST + + atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 temp + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10 + atf_check -s exit:0 -o not-match:'permanent' rump.arp -n 10.0.1.10 + # Can overwrite a temp cache + atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:ff + atf_check -s exit:0 -o match:'b2:a0:20:00:00:ff' rump.arp -n 10.0.1.10 + $DEBUG && rump.arp -n -a + + rump_server_destroy_ifaces +} + +make_pkt_str_arprep() +{ + local ip=$1 + local mac=$2 + pkt="ethertype ARP (0x0806), length 42: " + pkt="Reply $ip is-at $mac, length 28" + echo $pkt +} + +make_pkt_str_garp() +{ + local ip=$1 + local mac=$2 + local pkt= + pkt="$mac > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806)," + pkt="$pkt length 42: Request who-has $ip tell $ip, length 28" + echo $pkt +} + +test_proxy_arp() +{ + local arp_keep=5 + local opts= title= flags= + local type=$1 + + rump_server_start $SOCKSRC + rump_server_start $SOCKDST tap + + setup_dst_server + setup_src_server $arp_keep + + export RUMP_SERVER=$SOCKDST + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.forwarding=1 + macaddr_dst=$(get_macaddr $SOCKDST shmif0) + + if [ "$type" = "pub" ]; then + opts="pub" + title="permanent published" + else + opts="pub proxy" + title='permanent published \(proxy only\)' + fi + + # + # Test#1: First setup an endpoint then create proxy arp entry + # + export RUMP_SERVER=$SOCKDST + atf_check -s exit:0 rump.ifconfig tap1 create + atf_check -s exit:0 rump.ifconfig tap1 $IP4DST_PROXYARP1/24 up + atf_check -s exit:0 rump.ifconfig -w 10 + + # Try to ping (should fail w/o proxy arp) + export RUMP_SERVER=$SOCKSRC + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1 + + # Flushing + extract_new_packets bus1 > ./out + + # Set up proxy ARP entry + export RUMP_SERVER=$SOCKDST + atf_check -s exit:0 -o ignore \ + rump.arp -s $IP4DST_PROXYARP1 $macaddr_dst $opts + atf_check -s exit:0 -o match:"$title" rump.arp -n $IP4DST_PROXYARP1 + + # Try to ping + export RUMP_SERVER=$SOCKSRC + if [ "$type" = "pub" ]; then + # XXX fails + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1 + else + atf_check -s exit:0 -o ignore \ + rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1 + fi + + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + pkt1=$(make_pkt_str_arprep $IP4DST_PROXYARP1 $macaddr_dst) + pkt2=$(make_pkt_str_garp $IP4DST_PROXYARP1 $macaddr_dst) + if [ "$type" = "pub" ]; then + atf_check -s not-exit:0 -x \ + "cat ./out |grep -q -e '$pkt1' -e '$pkt2'" + else + atf_check -s exit:0 -x "cat ./out |grep -q -e '$pkt1' -e '$pkt2'" + fi + + # + # Test#2: Create proxy arp entry then set up an endpoint + # + export RUMP_SERVER=$SOCKDST + atf_check -s exit:0 -o ignore \ + rump.arp -s $IP4DST_PROXYARP2 $macaddr_dst $opts + atf_check -s exit:0 -o match:"$title" rump.arp -n $IP4DST_PROXYARP2 + $DEBUG && rump.netstat -nr -f inet + + # Try to ping (should fail because no endpoint exists) + export RUMP_SERVER=$SOCKSRC + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP2 + + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + # ARP reply should be sent + pkt=$(make_pkt_str_arprep $IP4DST_PROXYARP2 $macaddr_dst) + atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" + + export RUMP_SERVER=$SOCKDST + atf_check -s exit:0 rump.ifconfig tap2 create + atf_check -s exit:0 rump.ifconfig tap2 $IP4DST_PROXYARP2/24 up + atf_check -s exit:0 rump.ifconfig -w 10 + + # Try to ping + export RUMP_SERVER=$SOCKSRC + atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP2 +} + +arp_proxy_arp_pub_body() +{ + + test_proxy_arp pub + rump_server_destroy_ifaces +} + +arp_proxy_arp_pubproxy_body() +{ + + test_proxy_arp pubproxy + rump_server_destroy_ifaces +} + +arp_link_activation_body() +{ + local arp_keep=5 + local bonus=2 + + rump_server_start $SOCKSRC + rump_server_start $SOCKDST + + setup_dst_server + setup_src_server $arp_keep + + # flush old packets + extract_new_packets bus1 > ./out + + export RUMP_SERVER=$SOCKSRC + + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \ + b2:a1:00:00:00:01 + + atf_check -s exit:0 sleep 1 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + pkt=$(make_pkt_str_arpreq $IP4SRC $IP4SRC) + atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" + + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \ + b2:a1:00:00:00:02 active + + atf_check -s exit:0 sleep 1 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + pkt=$(make_pkt_str_arpreq $IP4SRC $IP4SRC) + atf_check -s exit:0 -x \ + "cat ./out |grep '$pkt' |grep -q 'b2:a1:00:00:00:02'" + + rump_server_destroy_ifaces +} + +arp_static_body() +{ + local arp_keep=5 + local macaddr_src= + + rump_server_start $SOCKSRC + rump_server_start $SOCKDST + + setup_dst_server + setup_src_server $arp_keep + + macaddr_src=$(get_macaddr $SOCKSRC shmif0) + + # Set a (valid) static ARP entry for the src server + export RUMP_SERVER=$SOCKDST + $DEBUG && rump.arp -n -a + atf_check -s exit:0 -o ignore rump.arp -s $IP4SRC $macaddr_src + $DEBUG && rump.arp -n -a + + # Test receiving an ARP request with the static ARP entry (as spa/sha) + export RUMP_SERVER=$SOCKSRC + atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST + + rump_server_destroy_ifaces +} + +arp_cache_expiration_5s_cleanup() +{ + $DEBUG && dump + cleanup +} + +arp_cache_expiration_10s_cleanup() +{ + $DEBUG && dump + cleanup +} + +arp_command_cleanup() +{ + $DEBUG && dump + cleanup +} + +arp_garp_cleanup() +{ + $DEBUG && dump + cleanup +} + +arp_cache_overwriting_cleanup() +{ + $DEBUG && dump + cleanup +} + +arp_proxy_arp_pub_cleanup() +{ + $DEBUG && dump + cleanup +} + +arp_proxy_arp_pubproxy_cleanup() +{ + $DEBUG && dump + cleanup +} + +arp_link_activation_cleanup() +{ + $DEBUG && dump + cleanup +} + +arp_static_cleanup() +{ + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case arp_cache_expiration_5s + atf_add_test_case arp_cache_expiration_10s + atf_add_test_case arp_command + atf_add_test_case arp_garp + atf_add_test_case arp_cache_overwriting + atf_add_test_case arp_proxy_arp_pub + atf_add_test_case arp_proxy_arp_pubproxy + atf_add_test_case arp_link_activation + atf_add_test_case arp_static +} diff --git a/contrib/netbsd-tests/net/arp/t_dad.sh b/contrib/netbsd-tests/net/arp/t_dad.sh new file mode 100755 index 0000000..57a7d4b --- /dev/null +++ b/contrib/netbsd-tests/net/arp/t_dad.sh @@ -0,0 +1,201 @@ +# $NetBSD: t_dad.sh,v 1.13 2016/11/25 08:51:16 ozaki-r Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCKLOCAL=unix://commsock1 +SOCKPEER=unix://commsock2 + +DEBUG=${DEBUG:-false} + +atf_test_case dad_basic cleanup +atf_test_case dad_duplicated cleanup + +dad_basic_head() +{ + atf_set "descr" "Tests for IPv4 DAD basic behavior" + atf_set "require.progs" "rump_server" +} + +dad_duplicated_head() +{ + atf_set "descr" "Tests for IPv4 DAD duplicated state" + atf_set "require.progs" "rump_server" +} + +setup_server() +{ + local sock=$1 + local ip=$2 + + rump_server_add_iface $sock shmif0 bus1 + + export RUMP_SERVER=$sock + atf_check -s exit:0 rump.ifconfig shmif0 inet $ip/24 + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig shmif0 +} + +make_pkt_str() +{ + local target=$1 + local sender=$2 + pkt="> ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42:" + pkt="$pkt Request who-has $target tell $sender, length 28" + echo $pkt +} + +dad_basic_body() +{ + local pkt= + + rump_server_start $SOCKLOCAL + rump_server_add_iface $SOCKLOCAL shmif0 bus1 + + export RUMP_SERVER=$SOCKLOCAL + + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.1/24 + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.2/24 alias + $DEBUG && rump.ifconfig shmif0 + + atf_check -s exit:0 rump.ifconfig shmif0 up + rump.ifconfig shmif0 > ./out + $DEBUG && cat ./out + + # The primary address doesn't start with tentative state + atf_check -s not-exit:0 -x "cat ./out |grep 10.0.0.1 |grep -iq tentative" + # The alias address starts with tentative state + # XXX we have no stable way to check this, so skip for now + #atf_check -s exit:0 -x "cat ./out |grep 10.0.0.2 |grep -iq tentative" + + atf_check -s exit:0 sleep 2 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + # Check DAD probe packets + pkt=$(make_pkt_str 10.0.0.2 0.0.0.0) + atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" + # No DAD for the primary address + pkt=$(make_pkt_str 10.0.0.1 0.0.0.0) + atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" + + # Waiting for DAD complete + atf_check -s exit:0 rump.ifconfig -w 10 + # Give a chance to send a DAD announce packet + atf_check -s exit:0 sleep 1 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + # Check the DAD announce packet + pkt=$(make_pkt_str 10.0.0.2 10.0.0.2) + atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" + # The alias address left tentative + atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep 10.0.0.2 |grep -iq tentative" + + # + # Add a new address on the fly + # + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.3/24 alias + + # The new address starts with tentative state + # XXX we have no stable way to check this, so skip for now + #atf_check -s exit:0 -x "rump.ifconfig shmif0 |grep 10.0.0.3 |grep -iq tentative" + + # Check DAD probe packets + atf_check -s exit:0 sleep 2 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + pkt=$(make_pkt_str 10.0.0.3 0.0.0.0) + atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" + + # Waiting for DAD complete + atf_check -s exit:0 rump.ifconfig -w 10 + # Give a chance to send a DAD announce packet + atf_check -s exit:0 sleep 1 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + # Check the DAD announce packet + pkt=$(make_pkt_str 10.0.0.3 10.0.0.3) + atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" + # The new address left tentative + atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep 10.0.0.3 |grep -iq tentative" + + rump_server_destroy_ifaces +} + +dad_duplicated_body() +{ + local localip1=10.0.1.1 + local localip2=10.0.1.11 + local peerip=10.0.1.2 + + rump_server_start $SOCKLOCAL + rump_server_start $SOCKPEER + + setup_server $SOCKLOCAL $localip1 + setup_server $SOCKPEER $peerip + + export RUMP_SERVER=$SOCKLOCAL + + # The primary address isn't marked as duplicated + atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep $localip1 |grep -iq duplicated" + + # + # Add a new address duplicated with the peer server + # + atf_check -s exit:0 rump.ifconfig shmif0 inet $peerip alias + atf_check -s exit:0 sleep 1 + + # The new address is marked as duplicated + atf_check -s exit:0 -x "rump.ifconfig shmif0 |grep $peerip |grep -iq duplicated" + + # A unique address isn't marked as duplicated + atf_check -s exit:0 rump.ifconfig shmif0 inet $localip2 alias + atf_check -s exit:0 sleep 1 + atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep $localip2 |grep -iq duplicated" + + rump_server_destroy_ifaces +} + +dad_basic_cleanup() +{ + $DEBUG && dump + cleanup +} + +dad_duplicated_cleanup() +{ + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case dad_basic + atf_add_test_case dad_duplicated +} diff --git a/contrib/netbsd-tests/net/bpf/h_bpf.h b/contrib/netbsd-tests/net/bpf/h_bpf.h new file mode 100644 index 0000000..307bc50 --- /dev/null +++ b/contrib/netbsd-tests/net/bpf/h_bpf.h @@ -0,0 +1,171 @@ +/* $NetBSD: h_bpf.h,v 1.2 2014/07/08 21:44:26 alnsn Exp $ */ + +/*- + * Copyright (c) 2014 Alexander Nasonov. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#ifndef _TESTS_NET_BPF_H_BPF_H_ +#define _TESTS_NET_BPF_H_BPF_H_ + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +/* XXX These declarations don't look kosher. */ +int rumpns_bpf_validate(const struct bpf_insn *, int); +unsigned int rumpns_bpf_filter_ext(const bpf_ctx_t *, + const struct bpf_insn *, bpf_args_t *); +bpfjit_func_t rumpns_bpfjit_generate_code(const bpf_ctx_t *, + const struct bpf_insn *, size_t); +void rumpns_bpfjit_free_code(bpfjit_func_t); + +/* + * Init mbuf chain with one or two chunks. The first chunk holds + * [pkt, pkt + split] bytes, the second chunk (if it's not empty) + * holds (pkt + split, pkt + pktsize) bytes. + * The function returns (const uint8_t *)mb1. + */ +static inline const uint8_t * +init_mchain2(struct mbuf *mb1, struct mbuf *mb2, + unsigned char pkt[], size_t pktsize, size_t split) +{ + + (void)memset(mb1, 0, sizeof(*mb1)); + mb1->m_data = (char *)pkt; + mb1->m_next = (split < pktsize) ? mb2 : NULL; + mb1->m_len = (split < pktsize) ? split : pktsize; + + if (split < pktsize) { + (void)memset(mb2, 0, sizeof(*mb2)); + mb2->m_next = NULL; + mb2->m_data = (char *)&pkt[split]; + mb2->m_len = pktsize - split; + } + + return (const uint8_t*)mb1; +} + +/* + * Compile and run a filter program. + */ +static inline unsigned int +exec_prog(struct bpf_insn *insns, size_t insn_count, + unsigned char pkt[], size_t pktsize) +{ + bpfjit_func_t fn; + bpf_args_t args; + unsigned int res; + + args.pkt = (const uint8_t *)pkt; + args.buflen = pktsize; + args.wirelen = pktsize; + + rump_schedule(); + fn = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + + res = fn(NULL, &args); + + rump_schedule(); + rumpns_bpfjit_free_code(fn); + rump_unschedule(); + + return res; +} + +/* + * Interpret a filter program with mbuf chain passed to bpf_filter_ext(). + */ +static inline unsigned int +interp_prog_mchain2(struct bpf_insn *insns, + unsigned char pkt[], size_t pktsize, size_t split) +{ + uint32_t mem[BPF_MEMWORDS]; + struct mbuf mb1, mb2; + bpf_args_t args; + unsigned int res; + + args.pkt = init_mchain2(&mb1, &mb2, pkt, pktsize, split); + args.buflen = 0; + args.wirelen = pktsize; + args.mem = mem; + + rump_schedule(); + res = rumpns_bpf_filter_ext(NULL, insns, &args); + rump_unschedule(); + + return res; +} + +/* + * Compile and run a filter program with mbuf chain passed to compiled function. + */ +static inline unsigned int +exec_prog_mchain2(struct bpf_insn *insns, size_t insn_count, + unsigned char pkt[], size_t pktsize, size_t split) +{ + bpfjit_func_t fn; + struct mbuf mb1, mb2; + bpf_args_t args; + unsigned int res; + + args.pkt = init_mchain2(&mb1, &mb2, pkt, pktsize, split); + args.buflen = 0; + args.wirelen = pktsize; + + rump_schedule(); + fn = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + + res = fn(NULL, &args); + + rump_schedule(); + rumpns_bpfjit_free_code(fn); + rump_unschedule(); + + return res; +} + +static inline bool +prog_validate(struct bpf_insn *insns, size_t insn_count) +{ + bool res; + + rump_schedule(); + res = rumpns_bpf_validate(insns, insn_count); + rump_unschedule(); + + return res; +} + +#endif /* _TESTS_NET_BPF_H_BPF_H_ */ diff --git a/contrib/netbsd-tests/net/bpf/t_bpf.c b/contrib/netbsd-tests/net/bpf/t_bpf.c new file mode 100644 index 0000000..cf8aa82 --- /dev/null +++ b/contrib/netbsd-tests/net/bpf/t_bpf.c @@ -0,0 +1,211 @@ +/* $NetBSD: t_bpf.c,v 1.7 2017/02/01 08:04:49 ozaki-r Exp $ */ + +/*- + * Copyright (c) 2010 Antti Kantee. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__RCSID("$NetBSD: t_bpf.c,v 1.7 2017/02/01 08:04:49 ozaki-r Exp $"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +/* XXX: atf-c.h has collisions with mbuf */ +#undef m_type +#undef m_data +#include + +#include "h_macros.h" +#include "../config/netconfig.c" + +ATF_TC(bpfwriteleak); +ATF_TC_HEAD(bpfwriteleak, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that writing to /dev/bpf " + "does not leak mbufs"); +} + +static int +getmtdata(void) +{ + struct mbstat mbstat; + size_t mbstatlen = sizeof(mbstat); + const int mbstat_mib[] = { CTL_KERN, KERN_MBUF, MBUF_STATS }; + + RL(rump_sys___sysctl(mbstat_mib, __arraycount(mbstat_mib), + &mbstat, &mbstatlen, NULL, 0)); + return mbstat.m_mtypes[MT_DATA]; +} + +ATF_TC_BODY(bpfwriteleak, tc) +{ + char buf[28]; /* sizeof(garbage) > etherhdrlen */ + struct ifreq ifr; + int ifnum, bpfd; + + RZ(rump_init()); + RZ(rump_pub_shmif_create(NULL, &ifnum)); + sprintf(ifr.ifr_name, "shmif%d", ifnum); + + RL(bpfd = rump_sys_open("/dev/bpf", O_RDWR)); + RL(rump_sys_ioctl(bpfd, BIOCSETIF, &ifr)); + RL(rump_sys_ioctl(bpfd, BIOCSFEEDBACK, &ifr)); + + if (getmtdata() != 0) + atf_tc_fail("test precondition failed: MT_DATA mbufs != 0"); + + ATF_REQUIRE_ERRNO(ENETDOWN, rump_sys_write(bpfd, buf, sizeof(buf))==-1); + + ATF_REQUIRE_EQ(getmtdata(), 0); +} + +#if (SIZE_MAX > UINT_MAX) +ATF_TC(bpfwritetrunc); +ATF_TC_HEAD(bpfwritetrunc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that write to /dev/bpf " + "does not truncate size_t to int"); +} + +ATF_TC_BODY(bpfwritetrunc, tc) +{ + int bpfd; + struct ifreq ifr; + struct iovec *iov; + size_t iovlen, sz; + const size_t extra_bytes = 28; + const size_t total = extra_bytes + UINT_MAX + 1; + long iov_max, vm_page_size; /* round_page wants vm_page_size variable */ + + memset(&ifr, 0, sizeof(ifr)); + + iov_max = sysconf(_SC_IOV_MAX); + vm_page_size = sysconf(_SC_PAGE_SIZE); + ATF_REQUIRE(iov_max > 1 && vm_page_size > 1); + + /* + * Minimize memory consumption by using many iovecs + * all pointing to one memory region. + */ + iov = calloc(iov_max, sizeof(struct iovec)); + ATF_REQUIRE(iov != NULL); + + sz = round_page((total + (iov_max - 1)) / iov_max); + + iov[0].iov_len = sz; + iov[0].iov_base = mmap(NULL, sz, PROT_READ, MAP_ANON, -1, 0); + ATF_REQUIRE(iov[0].iov_base != MAP_FAILED); + + iovlen = 1; + while (sz + iov[0].iov_len <= total) + { + iov[iovlen].iov_len = iov[0].iov_len; + iov[iovlen].iov_base = iov[0].iov_base; + sz += iov[0].iov_len; + iovlen++; + } + + if (sz < total) + { + iov[iovlen].iov_len = total - sz; + iov[iovlen].iov_base = iov[0].iov_base; + iovlen++; + } + + /* Sanity checks */ + ATF_REQUIRE(iovlen >= 1 && iovlen <= (size_t)iov_max); + ATF_REQUIRE_EQ(iov[iovlen-1].iov_len, total % iov[0].iov_len); + + RZ(rump_init()); + netcfg_rump_makeshmif("bpfwritetrunc", ifr.ifr_name); + netcfg_rump_if(ifr.ifr_name, "10.1.1.1", "255.0.0.0"); + + RL(bpfd = rump_sys_open("/dev/bpf", O_RDWR)); + RL(rump_sys_ioctl(bpfd, BIOCSETIF, &ifr)); + + ATF_CHECK_ERRNO(EMSGSIZE, rump_sys_writev(bpfd, iov, iovlen) == -1); + + munmap(iov[0].iov_base, iov[0].iov_len); + free(iov); +} +#endif /* #if (SIZE_MAX > UINT_MAX) */ + +ATF_TC(bpf_ioctl_BLEN); +ATF_TC_HEAD(bpf_ioctl_BLEN, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks behaviors of BIOCGBLEN and " + "BIOCSBLEN"); +} + +ATF_TC_BODY(bpf_ioctl_BLEN, tc) +{ + struct ifreq ifr; + int ifnum, bpfd; + u_int blen = 0; + + RZ(rump_init()); + RZ(rump_pub_shmif_create(NULL, &ifnum)); + sprintf(ifr.ifr_name, "shmif%d", ifnum); + + RL(bpfd = rump_sys_open("/dev/bpf", O_RDWR)); + + RL(rump_sys_ioctl(bpfd, BIOCGBLEN, &blen)); + ATF_REQUIRE(blen != 0); + blen = 100; + RL(rump_sys_ioctl(bpfd, BIOCSBLEN, &blen)); + RL(rump_sys_ioctl(bpfd, BIOCGBLEN, &blen)); + ATF_REQUIRE_EQ(blen, 100); + + RL(rump_sys_ioctl(bpfd, BIOCSETIF, &ifr)); + + ATF_REQUIRE_EQ_MSG(rump_sys_ioctl(bpfd, BIOCSBLEN, &blen), -1, + "Don't allow to change buflen after binding bpf to an interface"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, bpfwriteleak); +#if (SIZE_MAX > UINT_MAX) + ATF_TP_ADD_TC(tp, bpfwritetrunc); +#endif + ATF_TP_ADD_TC(tp, bpf_ioctl_BLEN); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/bpf/t_div-by-zero.c b/contrib/netbsd-tests/net/bpf/t_div-by-zero.c new file mode 100644 index 0000000..542d08a --- /dev/null +++ b/contrib/netbsd-tests/net/bpf/t_div-by-zero.c @@ -0,0 +1,52 @@ +#include +#include + +#include + +#include +#include + +#include +#include + +ATF_TC(div_by_zero); +ATF_TC_HEAD(div_by_zero, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF rejects a filter " + "which divides by 0"); +} + +ATF_TC_BODY(div_by_zero, tc) +{ + struct bpf_program bp; + int fd; + + /* + * Source code for following program: + * link[0:4]/0 = 2 + */ + struct bpf_insn bins[] = { + { 0x20, 0, 0, 0x00000000 }, + { 0x34, 0, 0, 0x00000000 }, + { 0x15, 0, 1, 0x00000002 }, + { 0x6, 0, 0, 0x00000060 }, + { 0x6, 0, 0, 0x00000000 }, + }; + + bp.bf_len = __arraycount(bins); + bp.bf_insns = bins; + + rump_init(); + fd = rump_sys_open("/dev/bpf", O_RDWR); + ATF_CHECK(fd != -1); + ATF_REQUIRE_EQ_MSG(rump_sys_ioctl(fd, BIOCSETF, &bp), -1, + "bpf accepted program with division by zero"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, div_by_zero); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/bpf/t_mbuf.c b/contrib/netbsd-tests/net/bpf/t_mbuf.c new file mode 100644 index 0000000..2076dc2 --- /dev/null +++ b/contrib/netbsd-tests/net/bpf/t_mbuf.c @@ -0,0 +1,961 @@ +/* $NetBSD: t_mbuf.c,v 1.3 2017/01/13 21:30:42 christos Exp $ */ + +/*- + * Copyright (c) 2014 Alexander Nasonov. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__RCSID("$NetBSD: t_mbuf.c,v 1.3 2017/01/13 21:30:42 christos Exp $"); + +#include +#include + +#include + +#include +#include + +#include +#include + +#include "../../net/bpf/h_bpf.h" + +/* XXX: atf-c.h has collisions with mbuf */ +#undef m_type +#undef m_data +#include + +#include "h_macros.h" + +static bool +test_ldb_abs(size_t split) +{ + /* Return a product of all packet bytes. */ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A <- P[0] */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 1), /* A <- P[1] */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 2), /* A <- P[2] */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* A <- P[3] */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4), /* A <- P[4] */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 120; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == res; +} + +static bool +test_ldh_abs(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 0), /* A <- P[0:2] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 1), /* A <- P[1:2] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 2), /* A <- P[2:2] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 3), /* A <- P[3:2] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 0x0a0e; /* 10 14 */ + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == res; +} + +static bool +test_ldw_abs(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 0), /* A <- P[0:4] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 1), /* A <- P[1:4] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 0x03050709; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == res; +} + +static bool +test_ldb_ind(size_t split) +{ + /* Return a sum of all packet bytes. */ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0), /* A <- P[0+X] */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1), /* A <- P[1+X] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1), /* A <- P[1+X] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2), /* A <- P[2+X] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 3), /* A <- P[3+X] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 15; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == res; +} + +static bool +test_ldw_ind(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0), /* A <- P[X+0:4] */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0), /* A <- P[X+0:4] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), /* X <- 0 */ + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 1), /* A <- P[X+1:4] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 0x05080b0e; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == res; +} + +static bool +test_ldh_ind(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0), /* A <- P[X+0:2] */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1), /* A <- P[X+1:2] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1), /* A <- P[X+1:2] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2), /* A <- P[X+2:2] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 0x0a0e; /* 10 14 */ + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == res; +} + +static bool +test_msh(size_t split) +{ + /* Return a product of all packet bytes. */ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), /* A <- 1 */ + + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 0), /* X <- 4*(P[0]&0xf) */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4 */ + + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 1), /* X <- 4*(P[1]&0xf) */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4 */ + + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 2), /* X <- 4*(P[2]&0xf) */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4 */ + + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 3), /* X <- 4*(P[3]&0xf) */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4 */ + + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 4), /* X <- 4*(P[4]&0xf) */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4 */ + + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 120; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == res; +} + +static bool +test_ldb_abs_overflow(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +static bool +test_ldh_abs_overflow(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +static bool +test_ldw_abs_overflow(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 2), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +static bool +test_ldb_ind_overflow1(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +static bool +test_ldb_ind_overflow2(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +static bool +test_ldb_ind_overflow3(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +static bool +test_ldh_ind_overflow1(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 4), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +static bool +test_ldh_ind_overflow2(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +static bool +test_ldh_ind_overflow3(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +static bool +test_ldw_ind_overflow1(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 2), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +static bool +test_ldw_ind_overflow2(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +static bool +test_ldw_ind_overflow3(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +static bool +test_msh_overflow(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 5), + BPF_STMT(BPF_MISC+BPF_TXA, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + + if (!prog_validate(insns, sizeof(insns) / sizeof(insns[0]))) + return false; + + return interp_prog_mchain2(insns, P, sizeof(P), split) == 0; +} + +ATF_TC(bpf_mbuf_ldb_abs); +ATF_TC_HEAD(bpf_mbuf_ldb_abs, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_ABS " + "loads bytes from mbuf correctly"); +} + +ATF_TC_BODY(bpf_mbuf_ldb_abs, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldb_abs(0)); + ATF_CHECK(test_ldb_abs(1)); + ATF_CHECK(test_ldb_abs(2)); + ATF_CHECK(test_ldb_abs(3)); + ATF_CHECK(test_ldb_abs(4)); + ATF_CHECK(test_ldb_abs(5)); +} + +ATF_TC(bpf_mbuf_ldh_abs); +ATF_TC_HEAD(bpf_mbuf_ldh_abs, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_ABS " + "loads halfwords from mbuf correctly"); +} + +ATF_TC_BODY(bpf_mbuf_ldh_abs, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldh_abs(0)); + ATF_CHECK(test_ldh_abs(1)); + ATF_CHECK(test_ldh_abs(2)); + ATF_CHECK(test_ldh_abs(3)); + ATF_CHECK(test_ldh_abs(4)); + ATF_CHECK(test_ldh_abs(5)); +} + +ATF_TC(bpf_mbuf_ldw_abs); +ATF_TC_HEAD(bpf_mbuf_ldw_abs, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_ABS " + "loads words from mbuf correctly"); +} + +ATF_TC_BODY(bpf_mbuf_ldw_abs, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldw_abs(0)); + ATF_CHECK(test_ldw_abs(1)); + ATF_CHECK(test_ldw_abs(2)); + ATF_CHECK(test_ldw_abs(3)); + ATF_CHECK(test_ldw_abs(4)); + ATF_CHECK(test_ldw_abs(5)); +} + +ATF_TC(bpf_mbuf_ldb_ind); +ATF_TC_HEAD(bpf_mbuf_ldb_ind, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND " + "loads bytes from mbuf correctly"); +} + +ATF_TC_BODY(bpf_mbuf_ldb_ind, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldb_ind(0)); + ATF_CHECK(test_ldb_ind(1)); + ATF_CHECK(test_ldb_ind(2)); + ATF_CHECK(test_ldb_ind(3)); + ATF_CHECK(test_ldb_ind(4)); + ATF_CHECK(test_ldb_ind(5)); +} + +ATF_TC(bpf_mbuf_ldh_ind); +ATF_TC_HEAD(bpf_mbuf_ldh_ind, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND " + "loads halfwords from mbuf correctly"); +} + +ATF_TC_BODY(bpf_mbuf_ldh_ind, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldh_ind(0)); + ATF_CHECK(test_ldh_ind(1)); + ATF_CHECK(test_ldh_ind(2)); + ATF_CHECK(test_ldh_ind(3)); + ATF_CHECK(test_ldh_ind(4)); + ATF_CHECK(test_ldh_ind(5)); +} + +ATF_TC(bpf_mbuf_ldw_ind); +ATF_TC_HEAD(bpf_mbuf_ldw_ind, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND " + "loads words from mbuf correctly"); +} + +ATF_TC_BODY(bpf_mbuf_ldw_ind, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldw_ind(0)); + ATF_CHECK(test_ldw_ind(1)); + ATF_CHECK(test_ldw_ind(2)); + ATF_CHECK(test_ldw_ind(3)); + ATF_CHECK(test_ldw_ind(4)); + ATF_CHECK(test_ldw_ind(5)); +} + +ATF_TC(bpf_mbuf_msh); +ATF_TC_HEAD(bpf_mbuf_msh, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LDX+BPF_B+BPF_MSH " + "loads bytes from mbuf correctly"); +} + +ATF_TC_BODY(bpf_mbuf_msh, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_msh(0)); + ATF_CHECK(test_msh(1)); + ATF_CHECK(test_msh(2)); + ATF_CHECK(test_msh(3)); + ATF_CHECK(test_msh(4)); + ATF_CHECK(test_msh(5)); +} + +ATF_TC(bpf_mbuf_ldb_abs_overflow); +ATF_TC_HEAD(bpf_mbuf_ldb_abs_overflow, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_ABS " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_ldb_abs_overflow, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldb_abs_overflow(0)); + ATF_CHECK(test_ldb_abs_overflow(1)); + ATF_CHECK(test_ldb_abs_overflow(2)); + ATF_CHECK(test_ldb_abs_overflow(3)); + ATF_CHECK(test_ldb_abs_overflow(4)); + ATF_CHECK(test_ldb_abs_overflow(5)); +} + +ATF_TC(bpf_mbuf_ldh_abs_overflow); +ATF_TC_HEAD(bpf_mbuf_ldh_abs_overflow, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_ABS " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_ldh_abs_overflow, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldh_abs_overflow(0)); + ATF_CHECK(test_ldh_abs_overflow(1)); + ATF_CHECK(test_ldh_abs_overflow(2)); + ATF_CHECK(test_ldh_abs_overflow(3)); + ATF_CHECK(test_ldh_abs_overflow(4)); + ATF_CHECK(test_ldh_abs_overflow(5)); +} + +ATF_TC(bpf_mbuf_ldw_abs_overflow); +ATF_TC_HEAD(bpf_mbuf_ldw_abs_overflow, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_ABS " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_ldw_abs_overflow, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldw_abs_overflow(0)); + ATF_CHECK(test_ldw_abs_overflow(1)); + ATF_CHECK(test_ldw_abs_overflow(2)); + ATF_CHECK(test_ldw_abs_overflow(3)); + ATF_CHECK(test_ldw_abs_overflow(4)); + ATF_CHECK(test_ldw_abs_overflow(5)); +} + +ATF_TC(bpf_mbuf_ldb_ind_overflow1); +ATF_TC_HEAD(bpf_mbuf_ldb_ind_overflow1, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_ldb_ind_overflow1, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldb_ind_overflow1(0)); + ATF_CHECK(test_ldb_ind_overflow1(1)); + ATF_CHECK(test_ldb_ind_overflow1(2)); + ATF_CHECK(test_ldb_ind_overflow1(3)); + ATF_CHECK(test_ldb_ind_overflow1(4)); + ATF_CHECK(test_ldb_ind_overflow1(5)); +} + +ATF_TC(bpf_mbuf_ldb_ind_overflow2); +ATF_TC_HEAD(bpf_mbuf_ldb_ind_overflow2, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_ldb_ind_overflow2, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldb_ind_overflow2(0)); + ATF_CHECK(test_ldb_ind_overflow2(1)); + ATF_CHECK(test_ldb_ind_overflow2(2)); + ATF_CHECK(test_ldb_ind_overflow2(3)); + ATF_CHECK(test_ldb_ind_overflow2(4)); + ATF_CHECK(test_ldb_ind_overflow2(5)); +} + +ATF_TC(bpf_mbuf_ldb_ind_overflow3); +ATF_TC_HEAD(bpf_mbuf_ldb_ind_overflow3, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_ldb_ind_overflow3, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldb_ind_overflow3(0)); + ATF_CHECK(test_ldb_ind_overflow3(1)); + ATF_CHECK(test_ldb_ind_overflow3(2)); + ATF_CHECK(test_ldb_ind_overflow3(3)); + ATF_CHECK(test_ldb_ind_overflow3(4)); + ATF_CHECK(test_ldb_ind_overflow3(5)); +} + +ATF_TC(bpf_mbuf_ldh_ind_overflow1); +ATF_TC_HEAD(bpf_mbuf_ldh_ind_overflow1, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_ldh_ind_overflow1, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldh_ind_overflow1(0)); + ATF_CHECK(test_ldh_ind_overflow1(1)); + ATF_CHECK(test_ldh_ind_overflow1(2)); + ATF_CHECK(test_ldh_ind_overflow1(3)); + ATF_CHECK(test_ldh_ind_overflow1(4)); + ATF_CHECK(test_ldh_ind_overflow1(5)); +} + +ATF_TC(bpf_mbuf_ldh_ind_overflow2); +ATF_TC_HEAD(bpf_mbuf_ldh_ind_overflow2, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_ldh_ind_overflow2, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldh_ind_overflow2(0)); + ATF_CHECK(test_ldh_ind_overflow2(1)); + ATF_CHECK(test_ldh_ind_overflow2(2)); + ATF_CHECK(test_ldh_ind_overflow2(3)); + ATF_CHECK(test_ldh_ind_overflow2(4)); + ATF_CHECK(test_ldh_ind_overflow2(5)); +} + +ATF_TC(bpf_mbuf_ldh_ind_overflow3); +ATF_TC_HEAD(bpf_mbuf_ldh_ind_overflow3, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_ldh_ind_overflow3, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldh_ind_overflow3(0)); + ATF_CHECK(test_ldh_ind_overflow3(1)); + ATF_CHECK(test_ldh_ind_overflow3(2)); + ATF_CHECK(test_ldh_ind_overflow3(3)); + ATF_CHECK(test_ldh_ind_overflow3(4)); + ATF_CHECK(test_ldh_ind_overflow3(5)); +} + +ATF_TC(bpf_mbuf_ldw_ind_overflow1); +ATF_TC_HEAD(bpf_mbuf_ldw_ind_overflow1, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_ldw_ind_overflow1, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldw_ind_overflow1(0)); + ATF_CHECK(test_ldw_ind_overflow1(1)); + ATF_CHECK(test_ldw_ind_overflow1(2)); + ATF_CHECK(test_ldw_ind_overflow1(3)); + ATF_CHECK(test_ldw_ind_overflow1(4)); + ATF_CHECK(test_ldw_ind_overflow1(5)); +} + +ATF_TC(bpf_mbuf_ldw_ind_overflow2); +ATF_TC_HEAD(bpf_mbuf_ldw_ind_overflow2, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_ldw_ind_overflow2, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldw_ind_overflow2(0)); + ATF_CHECK(test_ldw_ind_overflow2(1)); + ATF_CHECK(test_ldw_ind_overflow2(2)); + ATF_CHECK(test_ldw_ind_overflow2(3)); + ATF_CHECK(test_ldw_ind_overflow2(4)); + ATF_CHECK(test_ldw_ind_overflow2(5)); +} + +ATF_TC(bpf_mbuf_ldw_ind_overflow3); +ATF_TC_HEAD(bpf_mbuf_ldw_ind_overflow3, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_ldw_ind_overflow3, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldw_ind_overflow3(0)); + ATF_CHECK(test_ldw_ind_overflow3(1)); + ATF_CHECK(test_ldw_ind_overflow3(2)); + ATF_CHECK(test_ldw_ind_overflow3(3)); + ATF_CHECK(test_ldw_ind_overflow3(4)); + ATF_CHECK(test_ldw_ind_overflow3(5)); +} + +ATF_TC(bpf_mbuf_msh_overflow); +ATF_TC_HEAD(bpf_mbuf_msh_overflow, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LDX+BPF_B+BPF_MSH " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpf_mbuf_msh_overflow, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_msh_overflow(0)); + ATF_CHECK(test_msh_overflow(1)); + ATF_CHECK(test_msh_overflow(2)); + ATF_CHECK(test_msh_overflow(3)); + ATF_CHECK(test_msh_overflow(4)); + ATF_CHECK(test_msh_overflow(5)); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * For every new test please also add a similar test + * to ../../net/bpfjit/t_mbuf.c + */ + ATF_TP_ADD_TC(tp, bpf_mbuf_ldb_abs); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldh_abs); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldw_abs); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldb_ind); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldh_ind); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldw_ind); + ATF_TP_ADD_TC(tp, bpf_mbuf_msh); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldb_abs_overflow); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldh_abs_overflow); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldw_abs_overflow); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldb_ind_overflow1); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldb_ind_overflow2); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldb_ind_overflow3); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldh_ind_overflow1); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldh_ind_overflow2); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldh_ind_overflow3); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldw_ind_overflow1); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldw_ind_overflow2); + ATF_TP_ADD_TC(tp, bpf_mbuf_ldw_ind_overflow3); + ATF_TP_ADD_TC(tp, bpf_mbuf_msh_overflow); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/bpfilter/t_bpfilter.c b/contrib/netbsd-tests/net/bpfilter/t_bpfilter.c new file mode 100644 index 0000000..15a9ab6 --- /dev/null +++ b/contrib/netbsd-tests/net/bpfilter/t_bpfilter.c @@ -0,0 +1,482 @@ +/* $NetBSD: t_bpfilter.c,v 1.11 2017/01/13 21:30:42 christos Exp $ */ + +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__RCSID("$NetBSD: t_bpfilter.c,v 1.11 2017/01/13 21:30:42 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +/* XXX: atf-c.h has collisions with mbuf */ +#undef m_type +#undef m_data +#include + +#include "h_macros.h" +#include "../config/netconfig.c" + + +#define SNAPLEN UINT32_MAX + +#define BMAGIC UINT32_C(0x37) +#define HMAGIC UINT32_C(0xc2c2) +#define WMAGIC UINT32_C(0x7d7d7d7d) + +static const char magic_echo_reply_tail[7] = { + BMAGIC, + HMAGIC & 0xff, + HMAGIC & 0xff, + WMAGIC & 0xff, + WMAGIC & 0xff, + WMAGIC & 0xff, + WMAGIC & 0xff +}; + +/* + * Match ICMP_ECHOREPLY packet with 7 magic bytes at the end. + */ +static struct bpf_insn magic_echo_reply_prog[] = { + BPF_STMT(BPF_LD+BPF_ABS+BPF_B, + sizeof(struct ip) + offsetof(struct icmp, icmp_type)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ICMP_ECHOREPLY, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 0), + + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), /* A <- len */ + BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, 7), /* A <- A - 7 */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_IND+BPF_B, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, BMAGIC, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 0), + + BPF_STMT(BPF_LD+BPF_IND+BPF_H, 1), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, HMAGIC, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 0), + + BPF_STMT(BPF_LD+BPF_IND+BPF_W, 3), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, WMAGIC, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 0), + + BPF_STMT(BPF_RET+BPF_K, SNAPLEN) +}; + +static struct bpf_insn badmem_prog[] = { + BPF_STMT(BPF_LD+BPF_MEM, 5), + BPF_STMT(BPF_RET+BPF_A, 0), +}; + +static struct bpf_insn noinitA_prog[] = { + BPF_STMT(BPF_RET+BPF_A, 0), +}; + +static struct bpf_insn noinitX_prog[] = { + BPF_STMT(BPF_MISC+BPF_TXA, 0), + BPF_STMT(BPF_RET+BPF_A, 0), +}; + +static struct bpf_insn badjmp_prog[] = { + BPF_STMT(BPF_JMP+BPF_JA, 5), + BPF_STMT(BPF_RET+BPF_A, 0), +}; + +static struct bpf_insn negjmp_prog[] = { + BPF_STMT(BPF_JMP+BPF_JA, 0), + BPF_STMT(BPF_JMP+BPF_JA, UINT32_MAX - 1), // -2 + BPF_STMT(BPF_RET+BPF_A, 0), +}; + +static struct bpf_insn badret_prog[] = { + BPF_STMT(BPF_RET+BPF_A+0x8000, 0), +}; + +static uint16_t +in_cksum(void *data, size_t len) +{ + uint16_t *buf = data; + unsigned sum; + + for (sum = 0; len > 1; len -= 2) + sum += *buf++; + if (len) + sum += *(uint8_t *)buf; + + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + + return ~sum; +} + +/* + * Based on netcfg_rump_pingtest(). + */ +static bool __unused +pingtest(const char *dst, unsigned int wirelen, const char tail[7]) +{ + struct timeval tv; + struct sockaddr_in sin; + struct icmp *icmp; + char *pkt; + unsigned int pktsize; + socklen_t slen; + int s; + bool rv = false; + + if (wirelen < ETHER_HDR_LEN + sizeof(struct ip)) + return false; + + pktsize = wirelen - ETHER_HDR_LEN - sizeof(struct ip); + if (pktsize < sizeof(struct icmp) + 7) + return false; + + s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); + if (s == -1) + return false; + + pkt = NULL; + + tv.tv_sec = 1; + tv.tv_usec = 0; + if (rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, + &tv, sizeof(tv)) == -1) + goto out; + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = inet_addr(dst); + + pkt = calloc(1, pktsize); + icmp = (struct icmp *)pkt; + if (pkt == NULL) + goto out; + + memcpy(pkt + pktsize - 7, tail, 7); + icmp->icmp_type = ICMP_ECHO; + icmp->icmp_id = htons(37); + icmp->icmp_seq = htons(1); + icmp->icmp_cksum = in_cksum(pkt, pktsize); + + slen = sizeof(sin); + if (rump_sys_sendto(s, pkt, pktsize, 0, + (struct sockaddr *)&sin, slen) == -1) { + goto out; + } + + if (rump_sys_recvfrom(s, pkt, pktsize, 0, + (struct sockaddr *)&sin, &slen) == -1) + goto out; + + rv = true; + out: + if (pkt != NULL) + free(pkt); + rump_sys_close(s); + return rv; +} + +static void +magic_ping_test(const char *name, unsigned int wirelen) +{ + struct bpf_program prog; + struct bpf_stat bstat; + struct ifreq ifr; + struct timeval tv; + unsigned int bufsize; + bool pinged; + ssize_t n; + char *buf; + pid_t child; + int bpfd; + char token; + int channel[2]; + + struct bpf_hdr *hdr; + + RL(pipe(channel)); + + prog.bf_len = __arraycount(magic_echo_reply_prog); + prog.bf_insns = magic_echo_reply_prog; + + child = fork(); + RZ(rump_init()); + netcfg_rump_makeshmif(name, ifr.ifr_name); + + switch (child) { + case -1: + atf_tc_fail_errno("fork failed"); + case 0: + netcfg_rump_if(ifr.ifr_name, "10.1.1.10", "255.0.0.0"); + close(channel[0]); + ATF_CHECK(write(channel[1], "U", 1) == 1); + close(channel[1]); + pause(); + return; + default: + break; + } + + netcfg_rump_if(ifr.ifr_name, "10.1.1.20", "255.0.0.0"); + + RL(bpfd = rump_sys_open("/dev/bpf", O_RDONLY)); + + tv.tv_sec = 0; + tv.tv_usec = 500; + RL(rump_sys_ioctl(bpfd, BIOCSRTIMEOUT, &tv)); + + RL(rump_sys_ioctl(bpfd, BIOCGBLEN, &bufsize)); + RL(rump_sys_ioctl(bpfd, BIOCSETF, &prog)); + RL(rump_sys_ioctl(bpfd, BIOCSETIF, &ifr)); + + close(channel[1]); + ATF_CHECK(read(channel[0], &token, 1) == 1 && token == 'U'); + + pinged = pingtest("10.1.1.10", wirelen, magic_echo_reply_tail); + ATF_CHECK(pinged); + + buf = malloc(bufsize); + hdr = (struct bpf_hdr *)buf; + ATF_REQUIRE(buf != NULL); + ATF_REQUIRE(bufsize > sizeof(struct bpf_hdr)); + + n = rump_sys_read(bpfd, buf, bufsize); + + ATF_CHECK(n > (int)sizeof(struct bpf_hdr)); + ATF_CHECK(hdr->bh_caplen == MIN(SNAPLEN, wirelen)); + + RL(rump_sys_ioctl(bpfd, BIOCGSTATS, &bstat)); + ATF_CHECK(bstat.bs_capt >= 1); /* XXX == 1 */ + + rump_sys_close(bpfd); + free(buf); + + close(channel[0]); + + kill(child, SIGKILL); +} + +static int +send_bpf_prog(const char *ifname, struct bpf_program *prog) +{ + struct ifreq ifr; + int bpfd, e, rv; + + RZ(rump_init()); + netcfg_rump_makeshmif(ifname, ifr.ifr_name); + netcfg_rump_if(ifr.ifr_name, "10.1.1.20", "255.0.0.0"); + + RL(bpfd = rump_sys_open("/dev/bpf", O_RDONLY)); + + rv = rump_sys_ioctl(bpfd, BIOCSETF, prog); + e = errno; + + rump_sys_close(bpfd); + errno = e; + + return rv; +} + +ATF_TC(bpfiltercontig); +ATF_TC_HEAD(bpfiltercontig, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that bpf program " + "can read bytes from contiguous buffer."); + atf_tc_set_md_var(tc, "timeout", "30"); +} + +ATF_TC_BODY(bpfiltercontig, tc) +{ + + magic_ping_test("bpfiltercontig", 128); +} + + +ATF_TC(bpfiltermchain); +ATF_TC_HEAD(bpfiltermchain, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that bpf program " + "can read bytes from mbuf chain."); + atf_tc_set_md_var(tc, "timeout", "30"); +} + +ATF_TC_BODY(bpfiltermchain, tc) +{ + + magic_ping_test("bpfiltermchain", MINCLSIZE + 1); +} + + +ATF_TC(bpfilterbadmem); +ATF_TC_HEAD(bpfilterbadmem, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that bpf program that " + "doesn't initialize memomy store is rejected by the kernel"); + atf_tc_set_md_var(tc, "timeout", "30"); +} + +ATF_TC_BODY(bpfilterbadmem, tc) +{ + struct bpf_program prog; + + prog.bf_len = __arraycount(badmem_prog); + prog.bf_insns = badmem_prog; + ATF_CHECK_ERRNO(EINVAL, send_bpf_prog("bpfilterbadmem", &prog) == -1); +} + +ATF_TC(bpfilternoinitA); +ATF_TC_HEAD(bpfilternoinitA, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that bpf program that " + "doesn't initialize the A register is accepted by the kernel"); + atf_tc_set_md_var(tc, "timeout", "30"); +} + +ATF_TC_BODY(bpfilternoinitA, tc) +{ + struct bpf_program prog; + + prog.bf_len = __arraycount(noinitA_prog); + prog.bf_insns = noinitA_prog; + RL(send_bpf_prog("bpfilternoinitA", &prog)); +} + +ATF_TC(bpfilternoinitX); +ATF_TC_HEAD(bpfilternoinitX, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that bpf program that " + "doesn't initialize the X register is accepted by the kernel"); + atf_tc_set_md_var(tc, "timeout", "30"); +} + +ATF_TC_BODY(bpfilternoinitX, tc) +{ + struct bpf_program prog; + + prog.bf_len = __arraycount(noinitX_prog); + prog.bf_insns = noinitX_prog; + RL(send_bpf_prog("bpfilternoinitX", &prog)); +} + +ATF_TC(bpfilterbadjmp); +ATF_TC_HEAD(bpfilterbadjmp, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that bpf program that " + "jumps to invalid destination is rejected by the kernel"); + atf_tc_set_md_var(tc, "timeout", "30"); +} + +ATF_TC_BODY(bpfilterbadjmp, tc) +{ + struct bpf_program prog; + + prog.bf_len = __arraycount(badjmp_prog); + prog.bf_insns = badjmp_prog; + ATF_CHECK_ERRNO(EINVAL, send_bpf_prog("bpfilterbadjmp", &prog) == -1); +} + +ATF_TC(bpfilternegjmp); +ATF_TC_HEAD(bpfilternegjmp, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that bpf program that " + "jumps backwards is rejected by the kernel"); + atf_tc_set_md_var(tc, "timeout", "30"); +} + +ATF_TC_BODY(bpfilternegjmp, tc) +{ + struct bpf_program prog; + + prog.bf_len = __arraycount(negjmp_prog); + prog.bf_insns = negjmp_prog; + ATF_CHECK_ERRNO(EINVAL, send_bpf_prog("bpfilternegjmp", &prog) == -1); +} + +ATF_TC(bpfilterbadret); +ATF_TC_HEAD(bpfilterbadret, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that bpf program that " + "ends with invalid BPF_RET instruction is rejected by the kernel"); + atf_tc_set_md_var(tc, "timeout", "30"); +} + +ATF_TC_BODY(bpfilterbadret, tc) +{ + struct bpf_program prog; + struct bpf_insn *last; + + prog.bf_len = __arraycount(badret_prog); + prog.bf_insns = badret_prog; + + /* + * The point of this test is checking a bad instruction of + * a valid class and with a valid BPF_RVAL data. + */ + last = &prog.bf_insns[prog.bf_len - 1]; + ATF_CHECK(BPF_CLASS(last->code) == BPF_RET && + (BPF_RVAL(last->code) == BPF_K || BPF_RVAL(last->code) == BPF_A)); + + ATF_CHECK_ERRNO(EINVAL, send_bpf_prog("bpfilterbadret", &prog) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, bpfiltercontig); + ATF_TP_ADD_TC(tp, bpfiltermchain); + ATF_TP_ADD_TC(tp, bpfilterbadmem); + ATF_TP_ADD_TC(tp, bpfilternoinitA); + ATF_TP_ADD_TC(tp, bpfilternoinitX); + ATF_TP_ADD_TC(tp, bpfilterbadjmp); + ATF_TP_ADD_TC(tp, bpfilternegjmp); + ATF_TP_ADD_TC(tp, bpfilterbadret); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/bpfjit/t_bpfjit.c b/contrib/netbsd-tests/net/bpfjit/t_bpfjit.c new file mode 100644 index 0000000..06c3d97 --- /dev/null +++ b/contrib/netbsd-tests/net/bpfjit/t_bpfjit.c @@ -0,0 +1,4689 @@ +/* $NetBSD: t_bpfjit.c,v 1.12 2017/01/13 21:30:42 christos Exp $ */ + +/*- + * Copyright (c) 2011-2012, 2014-2015 Alexander Nasonov. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__RCSID("$NetBSD: t_bpfjit.c,v 1.12 2017/01/13 21:30:42 christos Exp $"); + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include "../../net/bpf/h_bpf.h" + +/* XXX: atf-c.h has collisions with mbuf */ +#undef m_type +#undef m_data +#include + +#include "h_macros.h" + + +static uint8_t deadbeef_at_5[16] = { + 0, 0xf1, 2, 0xf3, 4, 0xde, 0xad, 0xbe, 0xef, 0xff +}; + +static inline +unsigned int jitcall(bpfjit_func_t fn, + const uint8_t *pkt, unsigned int wirelen, unsigned int buflen) +{ + bpf_args_t args; + + args.pkt = pkt; + args.wirelen = wirelen; + args.buflen = buflen; + + return fn(NULL, &args); +} + +ATF_TC(bpfjit_empty); +ATF_TC_HEAD(bpfjit_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that JIT compilation of an empty bpf program fails"); +} + +ATF_TC_BODY(bpfjit_empty, tc) +{ + struct bpf_insn dummy; + bpfjit_func_t code; + + RZ(rump_init()); + + ATF_CHECK(!prog_validate(&dummy, 0)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, &dummy, 0); + rump_unschedule(); + + ATF_CHECK(code == NULL); +} + +ATF_TC(bpfjit_ret_k); +ATF_TC_HEAD(bpfjit_ret_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of a trivial bpf program"); +} + +ATF_TC_BODY(bpfjit_ret_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_RET+BPF_K, 17) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 17); +} + +ATF_TC(bpfjit_bad_ret_k); +ATF_TC_HEAD(bpfjit_bad_ret_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that JIT compilation of a program with bad BPF_RET fails"); +} + +ATF_TC_BODY(bpfjit_bad_ret_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_RET+BPF_K+0x8000, 13) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + uint8_t pkt[1]; /* the program doesn't read any data */ + + /* + * The point of this test is checking a bad instruction of + * a valid class and with a valid BPF_RVAL data. + */ + const uint16_t rcode = insns[0].code; + ATF_CHECK(BPF_CLASS(rcode) == BPF_RET && + (BPF_RVAL(rcode) == BPF_K || BPF_RVAL(rcode) == BPF_A)); + + RZ(rump_init()); + + ATF_CHECK(!prog_validate(insns, insn_count)); + + /* Current implementation generates code. */ + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 13); +} + +ATF_TC(bpfjit_alu_add_k); +ATF_TC_HEAD(bpfjit_alu_add_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_ADD+BPF_K"); +} + +ATF_TC_BODY(bpfjit_alu_add_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 3), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 5); +} + +ATF_TC(bpfjit_alu_sub_k); +ATF_TC_HEAD(bpfjit_alu_sub_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_SUB+BPF_K"); +} + +ATF_TC_BODY(bpfjit_alu_sub_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), + BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX); +} + +ATF_TC(bpfjit_alu_mul_k); +ATF_TC_HEAD(bpfjit_alu_mul_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MUL+BPF_K"); +} + +ATF_TC_BODY(bpfjit_alu_mul_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xfffffffd); +} + +ATF_TC(bpfjit_alu_div0_k); +ATF_TC_HEAD(bpfjit_alu_div0_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=0"); +} + +ATF_TC_BODY(bpfjit_alu_div0_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + //ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0); +} + +ATF_TC(bpfjit_alu_div1_k); +ATF_TC_HEAD(bpfjit_alu_div1_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=1"); +} + +ATF_TC_BODY(bpfjit_alu_div1_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 7); +} + +ATF_TC(bpfjit_alu_div2_k); +ATF_TC_HEAD(bpfjit_alu_div2_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=2"); +} + +ATF_TC_BODY(bpfjit_alu_div2_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3); +} + +ATF_TC(bpfjit_alu_div4_k); +ATF_TC_HEAD(bpfjit_alu_div4_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=4"); +} + +ATF_TC_BODY(bpfjit_alu_div4_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0x3fffffff); +} + +ATF_TC(bpfjit_alu_div10_k); +ATF_TC_HEAD(bpfjit_alu_div10_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=10"); +} + +ATF_TC_BODY(bpfjit_alu_div10_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 10), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 429484384); +} + +ATF_TC(bpfjit_alu_div10000_k); +ATF_TC_HEAD(bpfjit_alu_div10000_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=10000"); +} + +ATF_TC_BODY(bpfjit_alu_div10000_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 10000), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 429484); +} + +ATF_TC(bpfjit_alu_div7609801_k); +ATF_TC_HEAD(bpfjit_alu_div7609801_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=7609801"); +} + +ATF_TC_BODY(bpfjit_alu_div7609801_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(7609801)), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 564); +} + +ATF_TC(bpfjit_alu_div80000000_k); +ATF_TC_HEAD(bpfjit_alu_div80000000_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=0x80000000"); +} + +ATF_TC_BODY(bpfjit_alu_div80000000_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(0x80000000)), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 1); +} + +ATF_TC(bpfjit_alu_mod0_k); +ATF_TC_HEAD(bpfjit_alu_mod0_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=0"); +} + +ATF_TC_BODY(bpfjit_alu_mod0_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + //ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0); +} + +ATF_TC(bpfjit_alu_mod1_k); +ATF_TC_HEAD(bpfjit_alu_mod1_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=1"); +} + +ATF_TC_BODY(bpfjit_alu_mod1_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0); +} + +ATF_TC(bpfjit_alu_mod2_k); +ATF_TC_HEAD(bpfjit_alu_mod2_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=2"); +} + +ATF_TC_BODY(bpfjit_alu_mod2_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 1); +} + +ATF_TC(bpfjit_alu_mod4_k); +ATF_TC_HEAD(bpfjit_alu_mod4_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=4"); +} + +ATF_TC_BODY(bpfjit_alu_mod4_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3); +} + +ATF_TC(bpfjit_alu_mod10_k); +ATF_TC_HEAD(bpfjit_alu_mod10_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=10"); +} + +ATF_TC_BODY(bpfjit_alu_mod10_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 10), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 9); +} + +ATF_TC(bpfjit_alu_mod10000_k); +ATF_TC_HEAD(bpfjit_alu_mod10000_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=10000"); +} + +ATF_TC_BODY(bpfjit_alu_mod10000_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 10000), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3849); +} + +ATF_TC(bpfjit_alu_mod7609801_k); +ATF_TC_HEAD(bpfjit_alu_mod7609801_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=7609801"); +} + +ATF_TC_BODY(bpfjit_alu_mod7609801_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, UINT32_C(7609801)), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3039531); +} + +ATF_TC(bpfjit_alu_mod80000000_k); +ATF_TC_HEAD(bpfjit_alu_mod80000000_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=0x80000000"); +} + +ATF_TC_BODY(bpfjit_alu_mod80000000_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, UINT32_C(0x80000000)), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_C(0x7fffffde)); +} + +ATF_TC(bpfjit_alu_and_k); +ATF_TC_HEAD(bpfjit_alu_and_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_AND+BPF_K"); +} + +ATF_TC_BODY(bpfjit_alu_and_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead), + BPF_STMT(BPF_ALU+BPF_AND+BPF_K, 0xbeef), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == (0xdead&0xbeef)); +} + +ATF_TC(bpfjit_alu_or_k); +ATF_TC_HEAD(bpfjit_alu_or_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_OR+BPF_K"); +} + +ATF_TC_BODY(bpfjit_alu_or_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead0000), + BPF_STMT(BPF_ALU+BPF_OR+BPF_K, 0x0000beef), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef); +} + +ATF_TC(bpfjit_alu_xor_k); +ATF_TC_HEAD(bpfjit_alu_xor_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_XOR+BPF_K"); +} + +ATF_TC_BODY(bpfjit_alu_xor_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead0f0f), + BPF_STMT(BPF_ALU+BPF_XOR+BPF_K, 0x0000b1e0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef); +} + +ATF_TC(bpfjit_alu_lsh_k); +ATF_TC_HEAD(bpfjit_alu_lsh_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_K"); +} + +ATF_TC_BODY(bpfjit_alu_lsh_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 16), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xbeef0000); +} + +ATF_TC(bpfjit_alu_lsh0_k); +ATF_TC_HEAD(bpfjit_alu_lsh0_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_K with k=0"); +} + +ATF_TC_BODY(bpfjit_alu_lsh0_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef); +} + +ATF_TC(bpfjit_alu_rsh_k); +ATF_TC_HEAD(bpfjit_alu_rsh_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_K"); +} + +ATF_TC_BODY(bpfjit_alu_rsh_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 16), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0x0000dead); +} + +ATF_TC(bpfjit_alu_rsh0_k); +ATF_TC_HEAD(bpfjit_alu_rsh0_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_K with k=0"); +} + +ATF_TC_BODY(bpfjit_alu_rsh0_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef); +} + +ATF_TC(bpfjit_alu_modulo_k); +ATF_TC_HEAD(bpfjit_alu_modulo_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of modulo logic of BPF_ALU+BPF_K operations"); +} + +ATF_TC_BODY(bpfjit_alu_modulo_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)), + + /* (7FFFFF77 * 0FFFFF77) = 07FFFFB2,F0004951 */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, UINT32_C(0x0fffff77)), + + /* 07FFFFB2,F0004951 << 1 = 0FFFFF65,E00092A2 */ + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 1), + + /* 0FFFFF65,E00092A2 + DDDDDDDD = 0FFFFF66,BDDE707F */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xdddddddd)), + + /* 0FFFFF66,BDDE707F - FFFFFFFF = 0FFFFF65,BDDE7080 */ + BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, UINT32_C(0xffffffff)), + + /* 0FFFFF65,BDDE7080 | 0000030C = 0FFFFF65,BDDE738C */ + BPF_STMT(BPF_ALU+BPF_OR+BPF_K, UINT32_C(0x0000030c)), + + /* -0FFFFF65,BDDE738C mod(2^64) = F000009A,42218C74 */ + BPF_STMT(BPF_ALU+BPF_NEG, 0), + + /* F000009A,42218C74 & FFFFFF0F = F000009A,42218C04 */ + BPF_STMT(BPF_ALU+BPF_AND+BPF_K, UINT32_C(0xffffff0f)), + + /* F000009A,42218C74 >> 3 = 1E000013,48443180 */ + /* 00000000,42218C74 >> 3 = 00000000,08443180 */ + BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 3), + + /* 00000000,08443180 * 7FFFFF77 = 042218BB,93818280 */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, UINT32_C(0x7fffff77)), + + /* 042218BB,93818280 / DEAD = 000004C0,71CBBBC3 */ + /* 00000000,93818280 / DEAD = 00000000,0000A994 */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(0xdead)), + + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) != UINT32_C(0x71cbbbc3)); + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x0000a994)); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_alu_add_x); +ATF_TC_HEAD(bpfjit_alu_add_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_ADD+BPF_X"); +} + +ATF_TC_BODY(bpfjit_alu_add_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 3), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 5); +} + +ATF_TC(bpfjit_alu_sub_x); +ATF_TC_HEAD(bpfjit_alu_sub_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_SUB+BPF_X"); +} + +ATF_TC_BODY(bpfjit_alu_sub_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_STMT(BPF_ALU+BPF_SUB+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX); +} + +ATF_TC(bpfjit_alu_mul_x); +ATF_TC_HEAD(bpfjit_alu_mul_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MUL+BPF_X"); +} + +ATF_TC_BODY(bpfjit_alu_mul_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xfffffffd); +} + +ATF_TC(bpfjit_alu_div0_x); +ATF_TC_HEAD(bpfjit_alu_div0_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=0"); +} + +ATF_TC_BODY(bpfjit_alu_div0_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0); +} + +ATF_TC(bpfjit_alu_div1_x); +ATF_TC_HEAD(bpfjit_alu_div1_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=1"); +} + +ATF_TC_BODY(bpfjit_alu_div1_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 7); +} + +ATF_TC(bpfjit_alu_div2_x); +ATF_TC_HEAD(bpfjit_alu_div2_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=2"); +} + +ATF_TC_BODY(bpfjit_alu_div2_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3); +} + +ATF_TC(bpfjit_alu_div4_x); +ATF_TC_HEAD(bpfjit_alu_div4_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=4"); +} + +ATF_TC_BODY(bpfjit_alu_div4_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0x3fffffff); +} + +ATF_TC(bpfjit_alu_div10_x); +ATF_TC_HEAD(bpfjit_alu_div10_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=10"); +} + +ATF_TC_BODY(bpfjit_alu_div10_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 429484384); +} + +ATF_TC(bpfjit_alu_div10000_x); +ATF_TC_HEAD(bpfjit_alu_div10000_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=10000"); +} + +ATF_TC_BODY(bpfjit_alu_div10000_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10000), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 429484); +} + +ATF_TC(bpfjit_alu_div7609801_x); +ATF_TC_HEAD(bpfjit_alu_div7609801_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=7609801"); +} + +ATF_TC_BODY(bpfjit_alu_div7609801_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(7609801)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 564); +} + +ATF_TC(bpfjit_alu_div80000000_x); +ATF_TC_HEAD(bpfjit_alu_div80000000_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=0x80000000"); +} + +ATF_TC_BODY(bpfjit_alu_div80000000_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0x80000000)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 1); +} + +ATF_TC(bpfjit_alu_mod0_x); +ATF_TC_HEAD(bpfjit_alu_mod0_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=0"); +} + +ATF_TC_BODY(bpfjit_alu_mod0_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0); +} + +ATF_TC(bpfjit_alu_mod1_x); +ATF_TC_HEAD(bpfjit_alu_mod1_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=1"); +} + +ATF_TC_BODY(bpfjit_alu_mod1_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0); +} + +ATF_TC(bpfjit_alu_mod2_x); +ATF_TC_HEAD(bpfjit_alu_mod2_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=2"); +} + +ATF_TC_BODY(bpfjit_alu_mod2_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 7), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 1); +} + +ATF_TC(bpfjit_alu_mod4_x); +ATF_TC_HEAD(bpfjit_alu_mod4_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=4"); +} + +ATF_TC_BODY(bpfjit_alu_mod4_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3); +} + +ATF_TC(bpfjit_alu_mod10_x); +ATF_TC_HEAD(bpfjit_alu_mod10_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=10"); +} + +ATF_TC_BODY(bpfjit_alu_mod10_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 9); +} + +ATF_TC(bpfjit_alu_mod10000_x); +ATF_TC_HEAD(bpfjit_alu_mod10000_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=10000"); +} + +ATF_TC_BODY(bpfjit_alu_mod10000_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10000), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3849); +} + +ATF_TC(bpfjit_alu_mod7609801_x); +ATF_TC_HEAD(bpfjit_alu_mod7609801_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=7609801"); +} + +ATF_TC_BODY(bpfjit_alu_mod7609801_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(7609801)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3039531); +} + +ATF_TC(bpfjit_alu_mod80000000_x); +ATF_TC_HEAD(bpfjit_alu_mod80000000_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=0x80000000"); +} + +ATF_TC_BODY(bpfjit_alu_mod80000000_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0x80000000)), + BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_C(0x7fffffde)); +} + +ATF_TC(bpfjit_alu_and_x); +ATF_TC_HEAD(bpfjit_alu_and_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_AND+BPF_X"); +} + +ATF_TC_BODY(bpfjit_alu_and_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0xbeef), + BPF_STMT(BPF_ALU+BPF_AND+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == (0xdead&0xbeef)); +} + +ATF_TC(bpfjit_alu_or_x); +ATF_TC_HEAD(bpfjit_alu_or_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_OR+BPF_X"); +} + +ATF_TC_BODY(bpfjit_alu_or_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead0000), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0x0000beef), + BPF_STMT(BPF_ALU+BPF_OR+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef); +} + +ATF_TC(bpfjit_alu_xor_x); +ATF_TC_HEAD(bpfjit_alu_xor_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_XOR+BPF_X"); +} + +ATF_TC_BODY(bpfjit_alu_xor_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdead0f0f), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0x0000b1e0), + BPF_STMT(BPF_ALU+BPF_XOR+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef); +} + +ATF_TC(bpfjit_alu_lsh_x); +ATF_TC_HEAD(bpfjit_alu_lsh_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_X"); +} + +ATF_TC_BODY(bpfjit_alu_lsh_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 16), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xbeef0000); +} + +ATF_TC(bpfjit_alu_lsh0_x); +ATF_TC_HEAD(bpfjit_alu_lsh0_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_X with k=0"); +} + +ATF_TC_BODY(bpfjit_alu_lsh0_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef); +} + +ATF_TC(bpfjit_alu_rsh_x); +ATF_TC_HEAD(bpfjit_alu_rsh_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_X"); +} + +ATF_TC_BODY(bpfjit_alu_rsh_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 16), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0x0000dead); +} + +ATF_TC(bpfjit_alu_rsh0_x); +ATF_TC_HEAD(bpfjit_alu_rsh0_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_X with k=0"); +} + +ATF_TC_BODY(bpfjit_alu_rsh0_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef); +} + +ATF_TC(bpfjit_alu_modulo_x); +ATF_TC_HEAD(bpfjit_alu_modulo_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of modulo logic of BPF_ALU+BPF_X operations"); +} + +ATF_TC_BODY(bpfjit_alu_modulo_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)), + + /* (7FFFFF77 * 0FFFFF77) = 07FFFFB2,F0004951 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x0fffff77)), + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), + + /* 07FFFFB2,F0004951 << 1 = 0FFFFF65,E00092A2 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, 1), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0), + + /* 0FFFFF65,E00092A2 + DDDDDDDD = 0FFFFF66,BDDE707F */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xdddddddd)), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + + /* 0FFFFF66,BDDE707F - FFFFFFFF = 0FFFFF65,BDDE7080 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ALU+BPF_SUB+BPF_X, 0), + + /* 0FFFFF65,BDDE7080 | 0000030C = 0FFFFF65,BDDE738C */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x0000030c)), + BPF_STMT(BPF_ALU+BPF_OR+BPF_X, 0), + + /* -0FFFFF65,BDDE738C mod(2^64) = F000009A,42218C74 */ + BPF_STMT(BPF_ALU+BPF_NEG, 0), + + /* F000009A,42218C74 & FFFFFF0F = F000009A,42218C04 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xffffff0f)), + BPF_STMT(BPF_ALU+BPF_AND+BPF_X, 0), + + /* F000009A,42218C74 >> 3 = 1E000013,48443180 */ + /* 00000000,42218C74 >> 3 = 00000000,08443180 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, 3), + BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0), + + /* 00000000,08443180 * 7FFFFF77 = 042218BB,93818280 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x7fffff77)), + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), + + /* 042218BB,93818280 / DEAD = 000004C0,71CBBBC3 */ + /* 00000000,93818280 / DEAD = 00000000,0000A994 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xdead)), + BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0), + + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) != UINT32_C(0x71cbbbc3)); + ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x0000a994)); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_alu_neg); +ATF_TC_HEAD(bpfjit_alu_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ALU+BPF_NEG"); +} + +ATF_TC_BODY(bpfjit_alu_neg, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 777), + BPF_STMT(BPF_ALU+BPF_NEG, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0u-777u); +} + +ATF_TC(bpfjit_jmp_ja); +ATF_TC_HEAD(bpfjit_jmp_ja, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JA"); +} + +ATF_TC_BODY(bpfjit_jmp_ja, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_JMP+BPF_JA, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_K, 3), + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX); +} + +ATF_TC(bpfjit_jmp_ja_invalid); +ATF_TC_HEAD(bpfjit_jmp_ja_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test BPF_JMP+BPF_JA to invalid destination"); +} + +ATF_TC_BODY(bpfjit_jmp_ja_invalid, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_JMP+BPF_JA, 4), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_RET+BPF_K, 3), + }; + + bpfjit_func_t code; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(!prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_CHECK(code == NULL); +} + +ATF_TC(bpfjit_jmp_ja_overflow); +ATF_TC_HEAD(bpfjit_jmp_ja_overflow, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test BPF_JMP+BPF_JA with negative offset"); +} + +ATF_TC_BODY(bpfjit_jmp_ja_overflow, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_JMP+BPF_JA, 1), + BPF_STMT(BPF_RET+BPF_K, 777), + BPF_STMT(BPF_JMP+BPF_JA, UINT32_MAX - 1), // -2 + BPF_STMT(BPF_RET+BPF_K, 0) + }; + + bpfjit_func_t code; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + /* Jumps with negative offsets work only in userspace. */ + ATF_CHECK(!prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_CHECK(code == NULL); +} + +ATF_TC(bpfjit_jmp_jgt_k); +ATF_TC_HEAD(bpfjit_jmp_jgt_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_K"); +} + +ATF_TC_BODY(bpfjit_jmp_jgt_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 7, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 2, 2, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 9, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 4, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 5, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 7); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_jmp_jge_k); +ATF_TC_HEAD(bpfjit_jmp_jge_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_K"); +} + +ATF_TC_BODY(bpfjit_jmp_jge_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 8, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 3, 2, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 9, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 5, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 6, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 1, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 7); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_jmp_jeq_k); +ATF_TC_HEAD(bpfjit_jmp_jeq_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_K"); +} + +ATF_TC_BODY(bpfjit_jmp_jeq_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 1, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 9, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 5, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 7, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 1, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 7); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 7); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 1); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_jmp_jset_k); +ATF_TC_HEAD(bpfjit_jmp_jset_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_K"); +} + +ATF_TC_BODY(bpfjit_jmp_jset_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 8, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 4, 2, 0), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 3, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 1, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 7, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 1); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 5); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_jmp_modulo_k); +ATF_TC_HEAD(bpfjit_jmp_modulo_k, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of modulo logic of BPF_JMP+BPF_K operations"); +} + +ATF_TC_BODY(bpfjit_jmp_modulo_k, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)), + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 1, 0), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 0, 1), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 0, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 0, 3), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 2, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 1, 0), + BPF_STMT(BPF_JMP+BPF_JA, 1), + BPF_STMT(BPF_RET+BPF_K, 3), + + /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)), + + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 1, 0), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 0, 1), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 0, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 0, 3), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 2, 0), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 1, 0), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX); +} + +ATF_TC(bpfjit_jmp_jgt_x); +ATF_TC_HEAD(bpfjit_jmp_jgt_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_X"); +} + +ATF_TC_BODY(bpfjit_jmp_jgt_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 4, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 7); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_jmp_jge_x); +ATF_TC_HEAD(bpfjit_jmp_jge_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_X"); +} + +ATF_TC_BODY(bpfjit_jmp_jge_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 3, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 4, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 7); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 7); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_jmp_jeq_x); +ATF_TC_HEAD(bpfjit_jmp_jeq_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_X"); +} + +ATF_TC_BODY(bpfjit_jmp_jeq_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 3, 1), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 8), + BPF_STMT(BPF_RET+BPF_K, 9) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 8); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 8); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 2); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 8); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 3); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 9); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 6); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 1); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_jmp_jset_x); +ATF_TC_HEAD(bpfjit_jmp_jset_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_X"); +} + +ATF_TC_BODY(bpfjit_jmp_jset_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 0), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 3, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 1, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 3), + BPF_STMT(BPF_RET+BPF_K, 3), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 4, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, 8) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 1); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 1); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 7); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 5); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 8); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 5); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_jmp_jeq_x_noinit_ax); +ATF_TC_HEAD(bpfjit_jmp_jeq_x_noinit_ax, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test JIT compilation " + "of BPF_JMP+BPF_EQ+BPF_X with uninitialised A and X"); +} + +ATF_TC_BODY(bpfjit_jmp_jeq_x_noinit_ax, tc) +{ + static struct bpf_insn insns[] = { + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 10), + BPF_STMT(BPF_RET+BPF_K, 11) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 10); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_jmp_jeq_x_noinit_a); +ATF_TC_HEAD(bpfjit_jmp_jeq_x_noinit_a, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test JIT compilation " + "of BPF_JMP+BPF_EQ+BPF_X with uninitialised A"); +} + +ATF_TC_BODY(bpfjit_jmp_jeq_x_noinit_a, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), /* X > 0 */ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 10), + BPF_STMT(BPF_RET+BPF_K, 11) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 11); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_jmp_jeq_x_noinit_x); +ATF_TC_HEAD(bpfjit_jmp_jeq_x_noinit_x, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test JIT compilation " + "of BPF_JMP+BPF_EQ+BPF_X with uninitialised X"); +} + +ATF_TC_BODY(bpfjit_jmp_jeq_x_noinit_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_LEN, 0), /* A > 0 */ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 10), + BPF_STMT(BPF_RET+BPF_K, 11) + }; + + bpfjit_func_t code; + uint8_t pkt[8]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 11); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_jmp_modulo_x); +ATF_TC_HEAD(bpfjit_jmp_modulo_x, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of modulo logic of BPF_JMP+BPF_X operations"); +} + +ATF_TC_BODY(bpfjit_jmp_modulo_x, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)), + /* FFFFF770 << 4 = FFFFF770 */ + BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4), + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0), + BPF_STMT(BPF_JMP+BPF_JA, 1), + BPF_STMT(BPF_RET+BPF_K, 3), + + /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)), + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 5), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 6), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4), + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)), + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX); +} + +ATF_TC(bpfjit_ld_abs); +ATF_TC_HEAD(bpfjit_ld_abs, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_ABS"); +} + +ATF_TC_BODY(bpfjit_ld_abs, tc) +{ + static struct bpf_insn insns[3][2] = { + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 5), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 5), + BPF_STMT(BPF_RET+BPF_A, 0) + } + }; + + static size_t lengths[3] = { 1, 2, 4 }; + static unsigned int expected[3] = { 0xde, 0xdead, 0xdeadbeef }; + + size_t i, l; + uint8_t *pkt = deadbeef_at_5; + size_t pktsize = sizeof(deadbeef_at_5); + + size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]); + + RZ(rump_init()); + + for (i = 0; i < 3; i++) { + bpfjit_func_t code; + + ATF_CHECK(prog_validate(insns[i], insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns[i], insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (l = 1; l < 5 + lengths[i]; l++) { + ATF_CHECK(jitcall(code, pkt, l, l) == 0); + ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0); + } + + l = 5 + lengths[i]; + ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]); + ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]); + + l = pktsize; + ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); + } +} + +ATF_TC(bpfjit_ld_abs_k_overflow); +ATF_TC_HEAD(bpfjit_ld_abs_k_overflow, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_ABS with overflow in k+4"); +} + +ATF_TC_BODY(bpfjit_ld_abs_k_overflow, tc) +{ + static struct bpf_insn insns[12][3] = { + { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3), + BPF_STMT(BPF_RET+BPF_K, 1) + } + }; + + int i; + uint8_t pkt[8] = { 0 }; + + size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]); + + RZ(rump_init()); + + for (i = 0; i < 3; i++) { + ATF_CHECK(prog_validate(insns[i], insn_count)); + ATF_CHECK(exec_prog(insns[i], insn_count, pkt, 8) == 0); + } +} + +ATF_TC(bpfjit_ld_ind); +ATF_TC_HEAD(bpfjit_ld_ind, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(bpfjit_ld_ind, tc) +{ + static struct bpf_insn insns[6][3] = { + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }, + { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + } + }; + + static size_t lengths[6] = { 1, 2, 4, 1, 2, 4 }; + + static unsigned int expected[6] = { + 0xde, 0xdead, 0xdeadbeef, + 0xde, 0xdead, 0xdeadbeef + }; + + size_t i, l; + uint8_t *pkt = deadbeef_at_5; + size_t pktsize = sizeof(deadbeef_at_5); + + size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]); + + RZ(rump_init()); + + for (i = 0; i < 3; i++) { + bpfjit_func_t code; + + ATF_CHECK(prog_validate(insns[i], insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns[i], insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (l = 1; l < 5 + lengths[i]; l++) { + ATF_CHECK(jitcall(code, pkt, l, l) == 0); + ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0); + } + + l = 5 + lengths[i]; + ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]); + ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]); + + l = pktsize; + ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); + } +} + +ATF_TC(bpfjit_ld_ind_k_overflow); +ATF_TC_HEAD(bpfjit_ld_ind_k_overflow, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IND with overflow in k+4"); +} + +ATF_TC_BODY(bpfjit_ld_ind_k_overflow, tc) +{ + static struct bpf_insn insns[12][3] = { + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2), + BPF_STMT(BPF_RET+BPF_K, 1) + }, + { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3), + BPF_STMT(BPF_RET+BPF_K, 1) + } + }; + + int i; + uint8_t pkt[8] = { 0 }; + + size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]); + + RZ(rump_init()); + + for (i = 0; i < 3; i++) { + + ATF_CHECK(prog_validate(insns[i], insn_count)); + ATF_CHECK(exec_prog(insns[i], insn_count, pkt, 8) == 0); + } +} + +ATF_TC(bpfjit_ld_ind_x_overflow1); +ATF_TC_HEAD(bpfjit_ld_ind_x_overflow1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4"); +} + +ATF_TC_BODY(bpfjit_ld_ind_x_overflow1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_LEN, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)), + BPF_STMT(BPF_MISC+BPF_TAX, 0), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) { + //ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i); + ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i); + } + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_ld_ind_x_overflow2); +ATF_TC_HEAD(bpfjit_ld_ind_x_overflow2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4"); +} + +ATF_TC_BODY(bpfjit_ld_ind_x_overflow2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_LEN, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)), + BPF_STMT(BPF_ST, 3), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) { + //ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i); + ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i); + } + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_ld_len); +ATF_TC_HEAD(bpfjit_ld_len, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_W+BPF_LEN"); +} + +ATF_TC_BODY(bpfjit_ld_len, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[32]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < sizeof(pkt); i++) + ATF_CHECK(jitcall(code, pkt, i, 1) == i); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_ld_imm); +ATF_TC_HEAD(bpfjit_ld_imm, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LD+BPF_IMM"); +} + +ATF_TC_BODY(bpfjit_ld_imm, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX); +} + +ATF_TC(bpfjit_ldx_imm1); +ATF_TC_HEAD(bpfjit_ldx_imm1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_IMM"); +} + +ATF_TC_BODY(bpfjit_ldx_imm1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX - 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX - 5); +} + +ATF_TC(bpfjit_ldx_imm2); +ATF_TC_HEAD(bpfjit_ldx_imm2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_IMM"); +} + +ATF_TC_BODY(bpfjit_ldx_imm2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5), + BPF_STMT(BPF_LD+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX); +} + +ATF_TC(bpfjit_ldx_len1); +ATF_TC_HEAD(bpfjit_ldx_len1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_LEN"); +} + +ATF_TC_BODY(bpfjit_ldx_len1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[5]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 1; i < sizeof(pkt); i++) { + ATF_CHECK(jitcall(code, pkt, i, 1) == i); + ATF_CHECK(jitcall(code, pkt, i + 1, i) == i + 1); + } + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_ldx_len2); +ATF_TC_HEAD(bpfjit_ldx_len2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_LEN"); +} + +ATF_TC_BODY(bpfjit_ldx_len2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_LD+BPF_IMM, 5), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 7), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX) + }; + + bpfjit_func_t code; + uint8_t pkt[5]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 5, 1) == UINT32_MAX); + ATF_CHECK(jitcall(code, pkt, 6, 5) == 7); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_ldx_msh); +ATF_TC_HEAD(bpfjit_ldx_msh, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_LDX+BPF_MSH"); +} + +ATF_TC_BODY(bpfjit_ldx_msh, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[2] = { 0, 0x7a }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 2) == 40); +} + +ATF_TC(bpfjit_misc_tax); +ATF_TC_HEAD(bpfjit_misc_tax, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_MISC+BPF_TAX"); +} + +ATF_TC_BODY(bpfjit_misc_tax, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 3), + BPF_STMT(BPF_MISC+BPF_TAX, 0), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[6] = { 0, 11, 22, 33, 44, 55 }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 6) == 55); +} + +ATF_TC(bpfjit_misc_txa); +ATF_TC_HEAD(bpfjit_misc_txa, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_MISC+BPF_TXA"); +} + +ATF_TC_BODY(bpfjit_misc_txa, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 391), + BPF_STMT(BPF_MISC+BPF_TXA, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 391); +} + +ATF_TC(bpfjit_st1); +ATF_TC_HEAD(bpfjit_st1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(bpfjit_st1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ST, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_LD+BPF_MEM, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[16]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) + ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_st2); +ATF_TC_HEAD(bpfjit_st2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(bpfjit_st2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_ST, 0), + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ST, BPF_MEMWORDS-1), + BPF_STMT(BPF_LD+BPF_MEM, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0); +} + +ATF_TC(bpfjit_st3); +ATF_TC_HEAD(bpfjit_st3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(bpfjit_st3, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ST, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100), + BPF_STMT(BPF_ST, BPF_MEMWORDS-1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0), + BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1), + BPF_STMT(BPF_RET+BPF_A, 0), + BPF_STMT(BPF_LD+BPF_MEM, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[2]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_REQUIRE(BPF_MEMWORDS > 1); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 102); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_st4); +ATF_TC_HEAD(bpfjit_st4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(bpfjit_st4, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_ST, 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100), + BPF_STMT(BPF_ST, BPF_MEMWORDS-1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0), + BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1), + BPF_STMT(BPF_RET+BPF_A, 0), + BPF_STMT(BPF_LD+BPF_MEM, 5), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[2]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + ATF_REQUIRE(BPF_MEMWORDS > 6); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 1); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 102); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_st5); +ATF_TC_HEAD(bpfjit_st5, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_ST"); +} + +ATF_TC_BODY(bpfjit_st5, tc) +{ + struct bpf_insn insns[5*BPF_MEMWORDS+2]; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + size_t k; + bpfjit_func_t code; + uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */ + + memset(insns, 0, sizeof(insns)); + + /* for each k do M[k] = k */ + for (k = 0; k < BPF_MEMWORDS; k++) { + insns[2*k].code = BPF_LD+BPF_IMM; + insns[2*k].k = 3*k; + insns[2*k+1].code = BPF_ST; + insns[2*k+1].k = k; + } + + /* load wirelen into A */ + insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN; + + /* for each k, if (A == k + 1) return M[k] */ + for (k = 0; k < BPF_MEMWORDS; k++) { + insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K; + insns[2*BPF_MEMWORDS+3*k+1].k = k+1; + insns[2*BPF_MEMWORDS+3*k+1].jt = 0; + insns[2*BPF_MEMWORDS+3*k+1].jf = 2; + insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM; + insns[2*BPF_MEMWORDS+3*k+2].k = k; + insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A; + insns[2*BPF_MEMWORDS+3*k+3].k = 0; + } + + insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K; + insns[5*BPF_MEMWORDS+1].k = UINT32_MAX; + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (k = 1; k <= sizeof(pkt); k++) + ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1)); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_stx1); +ATF_TC_HEAD(bpfjit_stx1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_STX"); +} + +ATF_TC_BODY(bpfjit_stx1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_STX, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[16]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) + ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_stx2); +ATF_TC_HEAD(bpfjit_stx2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_STX"); +} + +ATF_TC_BODY(bpfjit_stx2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_ST, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_STX, BPF_MEMWORDS-1), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), + BPF_STMT(BPF_MISC+BPF_TXA, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0); +} + +ATF_TC(bpfjit_stx3); +ATF_TC_HEAD(bpfjit_stx3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_STX"); +} + +ATF_TC_BODY(bpfjit_stx3, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_STX, 6), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_STX, 5), + BPF_STMT(BPF_STX, 2), + BPF_STMT(BPF_STX, 3), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 2), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 6), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + size_t i; + bpfjit_func_t code; + uint8_t pkt[16]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 1; i <= sizeof(pkt); i++) + ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == 3 * i); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_stx4); +ATF_TC_HEAD(bpfjit_stx4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation of BPF_STX"); +} + +ATF_TC_BODY(bpfjit_stx4, tc) +{ + struct bpf_insn insns[5*BPF_MEMWORDS+2]; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + size_t k; + bpfjit_func_t code; + uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */ + + memset(insns, 0, sizeof(insns)); + + /* for each k do M[k] = k */ + for (k = 0; k < BPF_MEMWORDS; k++) { + insns[2*k].code = BPF_LDX+BPF_W+BPF_IMM; + insns[2*k].k = 3*k; + insns[2*k+1].code = BPF_STX; + insns[2*k+1].k = k; + } + + /* load wirelen into A */ + insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN; + + /* for each k, if (A == k + 1) return M[k] */ + for (k = 0; k < BPF_MEMWORDS; k++) { + insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K; + insns[2*BPF_MEMWORDS+3*k+1].k = k+1; + insns[2*BPF_MEMWORDS+3*k+1].jt = 0; + insns[2*BPF_MEMWORDS+3*k+1].jf = 2; + insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM; + insns[2*BPF_MEMWORDS+3*k+2].k = k; + insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A; + insns[2*BPF_MEMWORDS+3*k+3].k = 0; + } + + insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K; + insns[5*BPF_MEMWORDS+1].k = UINT32_MAX; + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (k = 1; k <= sizeof(pkt); k++) + ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1)); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_opt_ld_abs_1); +ATF_TC_HEAD(bpfjit_opt_ld_abs_1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_ABS"); +} + +ATF_TC_BODY(bpfjit_opt_ld_abs_1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_opt_ld_abs_2); +ATF_TC_HEAD(bpfjit_opt_ld_abs_2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_ABS"); +} + +ATF_TC_BODY(bpfjit_opt_ld_abs_2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_opt_ld_abs_3); +ATF_TC_HEAD(bpfjit_opt_ld_abs_3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_ABS"); +} + +ATF_TC_BODY(bpfjit_opt_ld_abs_3, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 5), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_opt_ld_ind_1); +ATF_TC_HEAD(bpfjit_opt_ld_ind_1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(bpfjit_opt_ld_ind_1, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 12), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 14), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_opt_ld_ind_2); +ATF_TC_HEAD(bpfjit_opt_ld_ind_2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(bpfjit_opt_ld_ind_2, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_opt_ld_ind_3); +ATF_TC_HEAD(bpfjit_opt_ld_ind_3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(bpfjit_opt_ld_ind_3, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 15), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_opt_ld_ind_4); +ATF_TC_HEAD(bpfjit_opt_ld_ind_4, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test JIT compilation with length optimization " + "applied to BPF_LD+BPF_IND"); +} + +ATF_TC_BODY(bpfjit_opt_ld_ind_4, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 11), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 19), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4), + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + size_t i, j; + bpfjit_func_t code; + uint8_t pkt[2][34] = { + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x0f, + 0x80, 0x03, 0x70, 0x23 + }, + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0x80, 0x03, 0x70, 0x23, + 0x80, 0x03, 0x70, 0x0f + } + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + for (i = 0; i < 2; i++) { + for (j = 1; j < sizeof(pkt[i]); j++) + ATF_CHECK(jitcall(code, pkt[i], j, j) == 0); + ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX); + } + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_abc_ja); +ATF_TC_HEAD(bpfjit_abc_ja, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test ABC optimization with a single BPF_JMP+BPF_JA"); +} + +ATF_TC_BODY(bpfjit_abc_ja, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */ + BPF_STMT(BPF_JMP+BPF_JA, 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, UINT32_MAX - 1), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 2), /* min. length 6 */ + BPF_STMT(BPF_RET+BPF_A, 0), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7), + BPF_STMT(BPF_RET+BPF_K, 3), + }; + + bpfjit_func_t code; + uint8_t pkt[6] = {0, 0, /* UINT32_MAX: */ 255, 255, 255, 255}; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == UINT32_MAX); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_abc_ja_over); +ATF_TC_HEAD(bpfjit_abc_ja_over, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test ABC optimization when BPF_JMP+BPF_JA jumps over all loads"); +} + +ATF_TC_BODY(bpfjit_abc_ja_over, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_JMP+BPF_JA, 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4), + BPF_STMT(BPF_RET+BPF_K, 1), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5), + BPF_STMT(BPF_RET+BPF_K, 2), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6), + BPF_STMT(BPF_RET+BPF_K, 3), + }; + + uint8_t pkt[1]; /* the program doesn't read any data */ + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX); +} + +ATF_TC(bpfjit_abc_ld_chain); +ATF_TC_HEAD(bpfjit_abc_ld_chain, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test ABC optimization of a chain of BPF_LD instructions " + "with exits leading to a single BPF_RET"); +} + +ATF_TC_BODY(bpfjit_abc_ld_chain, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 4), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4), /* min. length 6 */ + BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 6), /* min. length 10 */ + BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 123456789), + BPF_STMT(BPF_RET+BPF_K, 987654321), + }; + + bpfjit_func_t code; + uint8_t pkt[10] = {}; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + + /* !(pkt[3] == 8) => return 123456789 */ + ATF_CHECK(jitcall(code, pkt, 4, 4) == 123456789); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 123456789); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 123456789); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 123456789); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789); + + /* !(pkt[4:2] >= 7) => too short or return 123456789 */ + pkt[3] = 8; + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789); + + /* !(pkt[6:4] > 6) => too short or return 987654321 */ + pkt[4] = pkt[5] = 1; + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 987654321); + + /* (pkt[6:4] > 6) => too short or return 123456789 */ + pkt[6] = pkt[7] = pkt[8] = pkt[9] = 1; + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 123456789); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_examples_1); +ATF_TC_HEAD(bpfjit_examples_1, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the first example from bpf(4) - " + "accept Reverse ARP requests"); +} + +ATF_TC_BODY(bpfjit_examples_1, tc) +{ + /* + * The following filter is taken from the Reverse ARP + * Daemon. It accepts only Reverse ARP requests. + */ + struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8035, 0, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 0, 1), + BPF_STMT(BPF_RET+BPF_K, 42), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + bpfjit_func_t code; + uint8_t pkt[22] = {}; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + + /* The packet doesn't match. */ + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + + /* Still no match after setting the protocol field. */ + pkt[12] = 0x80; pkt[13] = 0x35; + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + + /* Set RARP message type. */ + pkt[21] = 3; + ATF_CHECK(jitcall(code, pkt, 22, 22) == 42); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + + /* Change RARP message type. */ + pkt[20] = 3; + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_examples_2); +ATF_TC_HEAD(bpfjit_examples_2, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the second example from bpf(4) - " + "accept IP packets between two specified hosts"); +} + +ATF_TC_BODY(bpfjit_examples_2, tc) +{ + /* + * This filter accepts only IP packets between host 128.3.112.15 + * and 128.3.112.35. + */ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 8), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3), + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + bpfjit_func_t code; + uint8_t pkt[34] = {}; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + ATF_CHECK(jitcall(code, pkt, 23, 23) == 0); + ATF_CHECK(jitcall(code, pkt, 24, 24) == 0); + ATF_CHECK(jitcall(code, pkt, 25, 25) == 0); + ATF_CHECK(jitcall(code, pkt, 26, 26) == 0); + ATF_CHECK(jitcall(code, pkt, 27, 27) == 0); + ATF_CHECK(jitcall(code, pkt, 28, 28) == 0); + ATF_CHECK(jitcall(code, pkt, 29, 29) == 0); + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + ATF_CHECK(jitcall(code, pkt, 31, 31) == 0); + ATF_CHECK(jitcall(code, pkt, 32, 32) == 0); + ATF_CHECK(jitcall(code, pkt, 33, 33) == 0); + + /* The packet doesn't match. */ + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + /* Still no match after setting the protocol field. */ + pkt[12] = 8; + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 15; + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 35; + ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX); + + /* Swap the ip addresses. */ + pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 35; + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 15; + ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + ATF_CHECK(jitcall(code, pkt, 23, 23) == 0); + ATF_CHECK(jitcall(code, pkt, 24, 24) == 0); + ATF_CHECK(jitcall(code, pkt, 25, 25) == 0); + ATF_CHECK(jitcall(code, pkt, 26, 26) == 0); + ATF_CHECK(jitcall(code, pkt, 27, 27) == 0); + ATF_CHECK(jitcall(code, pkt, 28, 28) == 0); + ATF_CHECK(jitcall(code, pkt, 29, 29) == 0); + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + ATF_CHECK(jitcall(code, pkt, 31, 31) == 0); + ATF_CHECK(jitcall(code, pkt, 32, 32) == 0); + ATF_CHECK(jitcall(code, pkt, 33, 33) == 0); + + /* Change the protocol field. */ + pkt[13] = 8; + ATF_CHECK(jitcall(code, pkt, 34, 34) == 0); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_examples_3); +ATF_TC_HEAD(bpfjit_examples_3, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test the third example from bpf(4) - " + "accept TCP finger packets"); +} + +ATF_TC_BODY(bpfjit_examples_3, tc) +{ + /* + * This filter returns only TCP finger packets. + */ + struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 10), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 0, 8), + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20), + BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0), + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1), + BPF_STMT(BPF_RET+BPF_K, UINT32_MAX), + BPF_STMT(BPF_RET+BPF_K, 0), + }; + + bpfjit_func_t code; + uint8_t pkt[30] = {}; + + /* Set IP fragment offset to non-zero. */ + pkt[20] = 1; pkt[21] = 1; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + ATF_CHECK(jitcall(code, pkt, 23, 23) == 0); + ATF_CHECK(jitcall(code, pkt, 24, 24) == 0); + ATF_CHECK(jitcall(code, pkt, 25, 25) == 0); + ATF_CHECK(jitcall(code, pkt, 26, 26) == 0); + ATF_CHECK(jitcall(code, pkt, 27, 27) == 0); + ATF_CHECK(jitcall(code, pkt, 28, 28) == 0); + ATF_CHECK(jitcall(code, pkt, 29, 29) == 0); + + /* The packet doesn't match. */ + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Still no match after setting the protocol field. */ + pkt[12] = 8; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Get one step closer to the match. */ + pkt[23] = 6; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Set IP fragment offset to zero. */ + pkt[20] = 0x20; pkt[21] = 0; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Set IP header length to 12. */ + pkt[14] = 0xd3; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + /* Match one branch of the program. */ + pkt[27] = 79; + ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX); + + /* Match the other branch of the program. */ + pkt[29] = 79; pkt[27] = 0; + ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX); + + /* Packet is too short. */ + ATF_CHECK(jitcall(code, pkt, 1, 1) == 0); + ATF_CHECK(jitcall(code, pkt, 2, 2) == 0); + ATF_CHECK(jitcall(code, pkt, 3, 3) == 0); + ATF_CHECK(jitcall(code, pkt, 4, 4) == 0); + ATF_CHECK(jitcall(code, pkt, 5, 5) == 0); + ATF_CHECK(jitcall(code, pkt, 6, 6) == 0); + ATF_CHECK(jitcall(code, pkt, 7, 7) == 0); + ATF_CHECK(jitcall(code, pkt, 8, 8) == 0); + ATF_CHECK(jitcall(code, pkt, 9, 9) == 0); + ATF_CHECK(jitcall(code, pkt, 10, 10) == 0); + ATF_CHECK(jitcall(code, pkt, 11, 11) == 0); + ATF_CHECK(jitcall(code, pkt, 12, 12) == 0); + ATF_CHECK(jitcall(code, pkt, 13, 13) == 0); + ATF_CHECK(jitcall(code, pkt, 14, 14) == 0); + ATF_CHECK(jitcall(code, pkt, 15, 15) == 0); + ATF_CHECK(jitcall(code, pkt, 16, 16) == 0); + ATF_CHECK(jitcall(code, pkt, 17, 17) == 0); + ATF_CHECK(jitcall(code, pkt, 18, 18) == 0); + ATF_CHECK(jitcall(code, pkt, 19, 19) == 0); + ATF_CHECK(jitcall(code, pkt, 20, 20) == 0); + ATF_CHECK(jitcall(code, pkt, 21, 21) == 0); + ATF_CHECK(jitcall(code, pkt, 22, 22) == 0); + ATF_CHECK(jitcall(code, pkt, 23, 23) == 0); + ATF_CHECK(jitcall(code, pkt, 24, 24) == 0); + ATF_CHECK(jitcall(code, pkt, 25, 25) == 0); + ATF_CHECK(jitcall(code, pkt, 26, 26) == 0); + ATF_CHECK(jitcall(code, pkt, 27, 27) == 0); + ATF_CHECK(jitcall(code, pkt, 28, 28) == 0); + ATF_CHECK(jitcall(code, pkt, 29, 29) == 0); + + /* Set IP header length to 16. Packet is too short. */ + pkt[14] = 4; + ATF_CHECK(jitcall(code, pkt, 30, 30) == 0); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_cop_no_ctx); +ATF_TC_HEAD(bpfjit_cop_no_ctx, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COP " + "instruction can't be accepted without a context"); +} + +ATF_TC_BODY(bpfjit_cop_no_ctx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_MISC+BPF_COP, 0), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + bpfjit_func_t code; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(!prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_CHECK(code == NULL); +} + +ATF_TC(bpfjit_copx_no_ctx); +ATF_TC_HEAD(bpfjit_copx_no_ctx, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COPX " + "instruction can't be accepted without a context"); +} + +ATF_TC_BODY(bpfjit_copx_no_ctx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + bpfjit_func_t code; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(!prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_CHECK(code == NULL); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * For every new test please also add a similar test + * to ../../lib/libbpfjit/t_bpfjit.c + */ + ATF_TP_ADD_TC(tp, bpfjit_empty); + ATF_TP_ADD_TC(tp, bpfjit_ret_k); + ATF_TP_ADD_TC(tp, bpfjit_bad_ret_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_add_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_sub_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_mul_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_div0_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_div1_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_div2_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_div4_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_div10_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_div10000_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_div7609801_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_div80000000_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod0_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod1_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod2_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod4_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod10_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod10000_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod7609801_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod80000000_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_and_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_or_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_xor_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_lsh_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_lsh0_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_rsh_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_rsh0_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_modulo_k); + ATF_TP_ADD_TC(tp, bpfjit_alu_add_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_sub_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_mul_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_div0_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_div1_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_div2_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_div4_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_div10_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_div10000_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_div7609801_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_div80000000_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod0_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod1_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod2_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod4_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod10_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod10000_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod7609801_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_mod80000000_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_and_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_or_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_xor_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_lsh_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_lsh0_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_rsh_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_rsh0_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_modulo_x); + ATF_TP_ADD_TC(tp, bpfjit_alu_neg); + ATF_TP_ADD_TC(tp, bpfjit_jmp_ja); + ATF_TP_ADD_TC(tp, bpfjit_jmp_ja_invalid); + ATF_TP_ADD_TC(tp, bpfjit_jmp_ja_overflow); + ATF_TP_ADD_TC(tp, bpfjit_jmp_jgt_k); + ATF_TP_ADD_TC(tp, bpfjit_jmp_jge_k); + ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_k); + ATF_TP_ADD_TC(tp, bpfjit_jmp_jset_k); + ATF_TP_ADD_TC(tp, bpfjit_jmp_modulo_k); + ATF_TP_ADD_TC(tp, bpfjit_jmp_jgt_x); + ATF_TP_ADD_TC(tp, bpfjit_jmp_jge_x); + ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x); + ATF_TP_ADD_TC(tp, bpfjit_jmp_jset_x); + ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x_noinit_ax); + ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x_noinit_a); + ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x_noinit_x); + ATF_TP_ADD_TC(tp, bpfjit_jmp_modulo_x); + ATF_TP_ADD_TC(tp, bpfjit_ld_abs); + ATF_TP_ADD_TC(tp, bpfjit_ld_abs_k_overflow); + ATF_TP_ADD_TC(tp, bpfjit_ld_ind); + ATF_TP_ADD_TC(tp, bpfjit_ld_ind_k_overflow); + ATF_TP_ADD_TC(tp, bpfjit_ld_ind_x_overflow1); + ATF_TP_ADD_TC(tp, bpfjit_ld_ind_x_overflow2); + ATF_TP_ADD_TC(tp, bpfjit_ld_len); + ATF_TP_ADD_TC(tp, bpfjit_ld_imm); + ATF_TP_ADD_TC(tp, bpfjit_ldx_imm1); + ATF_TP_ADD_TC(tp, bpfjit_ldx_imm2); + ATF_TP_ADD_TC(tp, bpfjit_ldx_len1); + ATF_TP_ADD_TC(tp, bpfjit_ldx_len2); + ATF_TP_ADD_TC(tp, bpfjit_ldx_msh); + ATF_TP_ADD_TC(tp, bpfjit_misc_tax); + ATF_TP_ADD_TC(tp, bpfjit_misc_txa); + ATF_TP_ADD_TC(tp, bpfjit_st1); + ATF_TP_ADD_TC(tp, bpfjit_st2); + ATF_TP_ADD_TC(tp, bpfjit_st3); + ATF_TP_ADD_TC(tp, bpfjit_st4); + ATF_TP_ADD_TC(tp, bpfjit_st5); + ATF_TP_ADD_TC(tp, bpfjit_stx1); + ATF_TP_ADD_TC(tp, bpfjit_stx2); + ATF_TP_ADD_TC(tp, bpfjit_stx3); + ATF_TP_ADD_TC(tp, bpfjit_stx4); + ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_1); + ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_2); + ATF_TP_ADD_TC(tp, bpfjit_opt_ld_abs_3); + ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_1); + ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_2); + ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_3); + ATF_TP_ADD_TC(tp, bpfjit_opt_ld_ind_4); + ATF_TP_ADD_TC(tp, bpfjit_abc_ja); + ATF_TP_ADD_TC(tp, bpfjit_abc_ja_over); + ATF_TP_ADD_TC(tp, bpfjit_abc_ld_chain); + ATF_TP_ADD_TC(tp, bpfjit_examples_1); + ATF_TP_ADD_TC(tp, bpfjit_examples_2); + ATF_TP_ADD_TC(tp, bpfjit_examples_3); + ATF_TP_ADD_TC(tp, bpfjit_cop_no_ctx); + ATF_TP_ADD_TC(tp, bpfjit_copx_no_ctx); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/bpfjit/t_cop.c b/contrib/netbsd-tests/net/bpfjit/t_cop.c new file mode 100644 index 0000000..502c588 --- /dev/null +++ b/contrib/netbsd-tests/net/bpfjit/t_cop.c @@ -0,0 +1,757 @@ +/* $NetBSD: t_cop.c,v 1.4 2017/01/13 21:30:42 christos Exp $ */ + +/*- + * Copyright (c) 2014 Alexander Nasonov. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_cop.c,v 1.4 2017/01/13 21:30:42 christos Exp $"); + +#include +#include + +#define __BPF_PRIVATE +#include +#include + +#include "../../net/bpf/h_bpf.h" + +/* XXX: atf-c.h has collisions with mbuf */ +#undef m_type +#undef m_data +#include + +#include "h_macros.h" + +static uint32_t retA(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); +static uint32_t retBL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); +static uint32_t retWL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); +static uint32_t retNF(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); +static uint32_t setARG(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); + +static const bpf_copfunc_t copfuncs[] = { + &retA, + &retBL, + &retWL, + &retNF, + &setARG +}; + +static const bpf_ctx_t ctx = { + .copfuncs = copfuncs, + .nfuncs = sizeof(copfuncs) / sizeof(copfuncs[0]), + .extwords = 0 +}; + +static uint32_t +retA(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return A; +} + +static uint32_t +retBL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return args->buflen; +} + +static uint32_t +retWL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return args->wirelen; +} + +static uint32_t +retNF(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return bc->nfuncs; +} + +/* + * COP function with a side effect. + */ +static uint32_t +setARG(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + bool *arg = (bool *)args->arg; + bool old = *arg; + + *arg = true; + return old; +} + +ATF_TC(bpfjit_cop_no_ctx); +ATF_TC_HEAD(bpfjit_cop_no_ctx, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that bpf program with BPF_COP " + "instruction isn't valid without a context"); +} + +ATF_TC_BODY(bpfjit_cop_no_ctx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_MISC+BPF_COP, 0), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + bpfjit_func_t code; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(!prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_CHECK(code == NULL); +} + +ATF_TC(bpfjit_cop_ret_A); +ATF_TC_HEAD(bpfjit_cop_ret_A, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns a content of the A register"); +} + +ATF_TC_BODY(bpfjit_cop_ret_A, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 0), // retA + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 13); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_cop_ret_buflen); +ATF_TC_HEAD(bpfjit_cop_ret_buflen, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns the buflen argument"); +} + +ATF_TC_BODY(bpfjit_cop_ret_buflen, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 1), // retBL + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == sizeof(pkt)); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_cop_ret_wirelen); +ATF_TC_HEAD(bpfjit_cop_ret_wirelen, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns the wirelen argument"); +} + +ATF_TC_BODY(bpfjit_cop_ret_wirelen, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 2), // retWL + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == sizeof(pkt)); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_cop_ret_nfuncs); +ATF_TC_HEAD(bpfjit_cop_ret_nfuncs, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns nfuncs member of the context argument"); +} + +ATF_TC_BODY(bpfjit_cop_ret_nfuncs, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 3), // retNF + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == ctx.nfuncs); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_cop_side_effect); +ATF_TC_HEAD(bpfjit_cop_side_effect, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that ABC optimization doesn't skip BPF_COP call"); +} + +ATF_TC_BODY(bpfjit_cop_side_effect, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), + BPF_STMT(BPF_MISC+BPF_COP, 4), // setARG + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99999), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + bool arg = false; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = NULL, + .arg = &arg + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + ATF_CHECK(arg == true); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_cop_copx); +ATF_TC_HEAD(bpfjit_cop_copx, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test BPF_COP call followed by BPF_COPX call"); +} + +ATF_TC_BODY(bpfjit_cop_copx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), /* A <- 1 */ + BPF_STMT(BPF_MISC+BPF_COP, 0), /* retA */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A = P[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_MISC+BPF_COPX, 0), /* retNF */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 2 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3 + ctx.nfuncs); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_cop_invalid_index); +ATF_TC_HEAD(bpfjit_cop_invalid_index, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that out-of-range coprocessor function fails validation"); +} + +ATF_TC_BODY(bpfjit_cop_invalid_index, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COP, 6), // invalid index + BPF_STMT(BPF_RET+BPF_K, 27) + }; + + bpfjit_func_t code; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_CHECK(code == NULL); +} + +ATF_TC(bpfjit_copx_no_ctx); +ATF_TC_HEAD(bpfjit_copx_no_ctx, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that bpf program with BPF_COPX " + "instruction isn't valid without a context"); +} + +ATF_TC_BODY(bpfjit_copx_no_ctx, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_MISC+BPF_COP, 0), + BPF_STMT(BPF_RET+BPF_K, 7) + }; + + bpfjit_func_t code; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + ATF_CHECK(!prog_validate(insns, insn_count)); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(NULL, insns, insn_count); + rump_unschedule(); + ATF_CHECK(code == NULL); +} + +ATF_TC(bpfjit_copx_ret_A); +ATF_TC_HEAD(bpfjit_copx_ret_A, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns a content of the A register"); +} + +ATF_TC_BODY(bpfjit_copx_ret_A, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LDX+BPF_IMM, 0), // retA + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 13); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_copx_ret_buflen); +ATF_TC_HEAD(bpfjit_copx_ret_buflen, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns the buflen argument"); +} + +ATF_TC_BODY(bpfjit_copx_ret_buflen, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LDX+BPF_IMM, 1), // retBL + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == sizeof(pkt)); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_copx_ret_wirelen); +ATF_TC_HEAD(bpfjit_copx_ret_wirelen, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns the wirelen argument"); +} + +ATF_TC_BODY(bpfjit_copx_ret_wirelen, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_IMM, 2), // retWL + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == sizeof(pkt)); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_copx_ret_nfuncs); +ATF_TC_HEAD(bpfjit_copx_ret_nfuncs, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns nfuncs member of the context argument"); +} + +ATF_TC_BODY(bpfjit_copx_ret_nfuncs, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LDX+BPF_IMM, 3), // retNF + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == ctx.nfuncs); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_copx_side_effect); +ATF_TC_HEAD(bpfjit_copx_side_effect, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that ABC optimization doesn't skip BPF_COPX call"); +} + +ATF_TC_BODY(bpfjit_copx_side_effect, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), + BPF_STMT(BPF_LDX+BPF_IMM, 4), // setARG + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99999), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + bool arg = false; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = NULL, + .arg = &arg + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + ATF_CHECK(arg == true); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_copx_cop); +ATF_TC_HEAD(bpfjit_copx_cop, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test BPF_COPX call followed by BPF_COP call"); +} + +ATF_TC_BODY(bpfjit_copx_cop, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_IMM, 2), /* X <- 2 */ + BPF_STMT(BPF_MISC+BPF_COPX, 0), /* retWL */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A = P[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + BPF_STMT(BPF_MISC+BPF_COP, 3), /* retNF */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */ + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 2 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 5 + ctx.nfuncs); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_copx_invalid_index); +ATF_TC_HEAD(bpfjit_copx_invalid_index, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that out-of-range BPF_COPX call fails at runtime"); +} + +ATF_TC_BODY(bpfjit_copx_invalid_index, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_IMM, 5), // invalid index + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_K, 27) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt) + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * For every new test please also add a similar test + * to ../../lib/libbpfjit/t_cop.c + */ + ATF_TP_ADD_TC(tp, bpfjit_cop_no_ctx); + ATF_TP_ADD_TC(tp, bpfjit_cop_ret_A); + ATF_TP_ADD_TC(tp, bpfjit_cop_ret_buflen); + ATF_TP_ADD_TC(tp, bpfjit_cop_ret_wirelen); + ATF_TP_ADD_TC(tp, bpfjit_cop_ret_nfuncs); + ATF_TP_ADD_TC(tp, bpfjit_cop_side_effect); + ATF_TP_ADD_TC(tp, bpfjit_cop_copx); + ATF_TP_ADD_TC(tp, bpfjit_cop_invalid_index); + + ATF_TP_ADD_TC(tp, bpfjit_copx_no_ctx); + ATF_TP_ADD_TC(tp, bpfjit_copx_ret_A); + ATF_TP_ADD_TC(tp, bpfjit_copx_ret_buflen); + ATF_TP_ADD_TC(tp, bpfjit_copx_ret_wirelen); + ATF_TP_ADD_TC(tp, bpfjit_copx_ret_nfuncs); + ATF_TP_ADD_TC(tp, bpfjit_copx_side_effect); + ATF_TP_ADD_TC(tp, bpfjit_copx_cop); + ATF_TP_ADD_TC(tp, bpfjit_copx_invalid_index); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/bpfjit/t_extmem.c b/contrib/netbsd-tests/net/bpfjit/t_extmem.c new file mode 100644 index 0000000..51761ec --- /dev/null +++ b/contrib/netbsd-tests/net/bpfjit/t_extmem.c @@ -0,0 +1,506 @@ +/* $NetBSD: t_extmem.c,v 1.2 2017/01/13 21:30:42 christos Exp $ */ + +/*- + * Copyright (c) 2014 Alexander Nasonov. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__RCSID("$NetBSD: t_extmem.c,v 1.2 2017/01/13 21:30:42 christos Exp $"); + +#include +#include + +#define __BPF_PRIVATE +#include +#include + +#include "../../net/bpf/h_bpf.h" + +/* XXX: atf-c.h has collisions with mbuf */ +#undef m_type +#undef m_data +#include + +#include "h_macros.h" + +static uint32_t retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A); + +static const bpf_copfunc_t copfuncs[] = { + &retM +}; + +static const bpf_ctx_t ctx = { + .copfuncs = copfuncs, + .nfuncs = sizeof(copfuncs) / sizeof(copfuncs[0]), + .extwords = 4, + .preinited = BPF_MEMWORD_INIT(0) | BPF_MEMWORD_INIT(3), +}; + +static uint32_t +retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A) +{ + + return args->mem[(uintptr_t)args->arg]; +} + + +ATF_TC(bpfjit_extmem_load_preinited); +ATF_TC_HEAD(bpfjit_extmem_load_preinited, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test a load of external " + "pre-initialized memory"); +} + +ATF_TC_BODY(bpfjit_extmem_load_preinited, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_MEM, 3), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_extmem_invalid_load); +ATF_TC_HEAD(bpfjit_extmem_invalid_load, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that out-of-range load " + "fails validation"); +} + +ATF_TC_BODY(bpfjit_extmem_invalid_load, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_MEM, 4), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_CHECK(code == NULL); +} + +ATF_TC(bpfjit_extmem_store); +ATF_TC_HEAD(bpfjit_extmem_store, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test stores to external memory"); +} + +ATF_TC_BODY(bpfjit_extmem_store, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), /* A <- 1 */ + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2 */ + BPF_STMT(BPF_ST, 1), /* M[1] <- A */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_STX, 2), /* M[2] <- X */ + BPF_STMT(BPF_ST, 3), /* M[3] <- A */ + BPF_STMT(BPF_RET+BPF_A, 0) /* ret A */ + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 7; + + mem[1] = mem[2] = 0xdeadbeef; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); + + ATF_CHECK(mem[0] == 0); + ATF_CHECK(mem[1] == 1); + ATF_CHECK(mem[2] == 2); + ATF_CHECK(mem[3] == 3); +} + +ATF_TC(bpfjit_extmem_side_effect); +ATF_TC_HEAD(bpfjit_extmem_side_effect, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that ABC optimization doesn\'t " + "skip stores to external memory"); +} + +ATF_TC_BODY(bpfjit_extmem_side_effect, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A <- P[0] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2 */ + BPF_STMT(BPF_ST, 1), /* M[1] <- A */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_STX, 2), /* M[2] <- X */ + BPF_STMT(BPF_ST, 3), /* M[3] <- A */ + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99), /* A <- P[99] */ + BPF_STMT(BPF_RET+BPF_A, 0) /* ret A */ + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 1 }; + uint32_t mem[ctx.extwords]; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 7; + + mem[1] = mem[2] = 0xdeadbeef; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 0); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); + + ATF_CHECK(mem[0] == 0); + ATF_CHECK(mem[1] == 1); + ATF_CHECK(mem[2] == 2); + ATF_CHECK(mem[3] == 3); +} + +ATF_TC(bpfjit_extmem_invalid_store); +ATF_TC_HEAD(bpfjit_extmem_invalid_store, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test that out-of-range store " + "fails validation"); +} + +ATF_TC_BODY(bpfjit_extmem_invalid_store, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_ST, 4), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_CHECK(code == NULL); +} + +ATF_TC(bpfjit_cop_ret_mem); +ATF_TC_HEAD(bpfjit_cop_ret_mem, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns a content of external memory word"); +} + +ATF_TC_BODY(bpfjit_cop_ret_mem, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_ST, 2), + BPF_STMT(BPF_LD+BPF_IMM, 137), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_MISC+BPF_COP, 0), // retM + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + void *arg = (void*)(uintptr_t)2; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .arg = arg, + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 13); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_cop_ret_preinited_mem); +ATF_TC_HEAD(bpfjit_cop_ret_preinited_mem, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function that " + "returns a content of external pre-initialized memory word"); +} + +ATF_TC_BODY(bpfjit_cop_ret_preinited_mem, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_ST, 2), + BPF_STMT(BPF_LD+BPF_IMM, 137), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_MISC+BPF_COP, 0), // retM + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + void *arg = (void*)(uintptr_t)3; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .arg = arg, + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_copx_ret_mem); +ATF_TC_HEAD(bpfjit_copx_ret_mem, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function " + "that returns a content of external memory word"); +} + +ATF_TC_BODY(bpfjit_copx_ret_mem, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_ST, 2), + BPF_STMT(BPF_LD+BPF_IMM, 137), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + void *arg = (void*)(uintptr_t)2; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .arg = arg, + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 13); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TC(bpfjit_copx_ret_preinited_mem); +ATF_TC_HEAD(bpfjit_copx_ret_preinited_mem, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test coprocessor function that " + "returns a content of external pre-initialized memory word"); +} + +ATF_TC_BODY(bpfjit_copx_ret_preinited_mem, tc) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 13), + BPF_STMT(BPF_ST, 2), + BPF_STMT(BPF_LD+BPF_IMM, 137), + BPF_STMT(BPF_ST, 1), + BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM + BPF_STMT(BPF_MISC+BPF_COPX, 0), + BPF_STMT(BPF_RET+BPF_A, 0) + }; + + bpfjit_func_t code; + uint8_t pkt[1] = { 0 }; + uint32_t mem[ctx.extwords]; + void *arg = (void*)(uintptr_t)3; + + /* Pre-inited words. */ + mem[0] = 0; + mem[3] = 3; + + bpf_args_t args = { + .pkt = pkt, + .buflen = sizeof(pkt), + .wirelen = sizeof(pkt), + .arg = arg, + .mem = mem, + }; + + size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + RZ(rump_init()); + + rump_schedule(); + code = rumpns_bpfjit_generate_code(&ctx, insns, insn_count); + rump_unschedule(); + ATF_REQUIRE(code != NULL); + + ATF_CHECK(code(&ctx, &args) == 3); + + rump_schedule(); + rumpns_bpfjit_free_code(code); + rump_unschedule(); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * For every new test please also add a similar test + * to ../../lib/libbpfjit/t_extmem.c + */ + //ATF_TP_ADD_TC(tp, bpfjit_extmem_load_default); + ATF_TP_ADD_TC(tp, bpfjit_extmem_load_preinited); + ATF_TP_ADD_TC(tp, bpfjit_extmem_invalid_load); + ATF_TP_ADD_TC(tp, bpfjit_extmem_store); + ATF_TP_ADD_TC(tp, bpfjit_extmem_side_effect); + ATF_TP_ADD_TC(tp, bpfjit_extmem_invalid_store); + ATF_TP_ADD_TC(tp, bpfjit_cop_ret_mem); + ATF_TP_ADD_TC(tp, bpfjit_cop_ret_preinited_mem); + ATF_TP_ADD_TC(tp, bpfjit_copx_ret_mem); + ATF_TP_ADD_TC(tp, bpfjit_copx_ret_preinited_mem); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/bpfjit/t_mbuf.c b/contrib/netbsd-tests/net/bpfjit/t_mbuf.c new file mode 100644 index 0000000..d3a2b99 --- /dev/null +++ b/contrib/netbsd-tests/net/bpfjit/t_mbuf.c @@ -0,0 +1,982 @@ +/* $NetBSD: t_mbuf.c,v 1.2 2017/01/13 21:30:42 christos Exp $ */ + +/*- + * Copyright (c) 2014 Alexander Nasonov. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__RCSID("$NetBSD: t_mbuf.c,v 1.2 2017/01/13 21:30:42 christos Exp $"); + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include "../../net/bpf/h_bpf.h" + +/* XXX: atf-c.h has collisions with mbuf */ +#undef m_type +#undef m_data +#include + +#include "h_macros.h" + +static bool +test_ldb_abs(size_t split) +{ + /* Return a product of all packet bytes. */ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A <- P[0] */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 1), /* A <- P[1] */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 2), /* A <- P[2] */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* A <- P[3] */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4), /* A <- P[4] */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 120; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res; +} + +static bool +test_ldh_abs(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 0), /* A <- P[0:2] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 1), /* A <- P[1:2] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 2), /* A <- P[2:2] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 3), /* A <- P[3:2] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 0x0a0e; /* 10 14 */ + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res; +} + +static bool +test_ldw_abs(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 0), /* A <- P[0:4] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */ + + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 1), /* A <- P[1:4] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 0x03050709; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res; +} + +static bool +test_ldb_ind(size_t split) +{ + /* Return a sum of all packet bytes. */ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0), /* A <- P[0+X] */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1), /* A <- P[1+X] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1), /* A <- P[1+X] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2), /* A <- P[2+X] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 3), /* A <- P[3+X] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 15; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res; +} + +static bool +test_ldw_ind(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0), /* A <- P[X+0:4] */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0), /* A <- P[X+0:4] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0), /* X <- 0 */ + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 1), /* A <- P[X+1:4] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 0x05080b0e; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res; +} + +static bool +test_ldh_ind(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0), /* A <- P[X+0:2] */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1), /* A <- P[X+1:2] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1), /* A <- P[X+1:2] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_ST, 0), /* M[0] <- A */ + + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), /* X <- 1 */ + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2), /* A <- P[X+2:2] */ + BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0), /* X <- M[0] */ + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */ + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 0x0a0e; /* 10 14 */ + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res; +} + +static bool +test_msh(size_t split) +{ + /* Return a product of all packet bytes. */ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_IMM, 1), /* A <- 1 */ + + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 0), /* X <- 4*(P[0]&0xf) */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4 */ + + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 1), /* X <- 4*(P[1]&0xf) */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4 */ + + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 2), /* X <- 4*(P[2]&0xf) */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4 */ + + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 3), /* X <- 4*(P[3]&0xf) */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4 */ + + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 4), /* X <- 4*(P[4]&0xf) */ + BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0), /* A <- A * X */ + BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4), /* A <- A / 4 */ + + BPF_STMT(BPF_RET+BPF_A, 0), /* ret A */ + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const unsigned int res = 120; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == res; +} + +static bool +test_ldb_abs_overflow(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +static bool +test_ldh_abs_overflow(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +static bool +test_ldw_abs_overflow(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 2), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +static bool +test_ldb_ind_overflow1(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 5), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +static bool +test_ldb_ind_overflow2(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +static bool +test_ldb_ind_overflow3(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_B+BPF_IND, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +static bool +test_ldh_ind_overflow1(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 4), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +static bool +test_ldh_ind_overflow2(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +static bool +test_ldh_ind_overflow3(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_H+BPF_IND, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +static bool +test_ldw_ind_overflow1(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 2), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +static bool +test_ldw_ind_overflow2(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +static bool +test_ldw_ind_overflow3(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX), + BPF_STMT(BPF_LD+BPF_W+BPF_IND, 1), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +static bool +test_msh_overflow(size_t split) +{ + static struct bpf_insn insns[] = { + BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 5), + BPF_STMT(BPF_MISC+BPF_TXA, 0), + BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + + static unsigned char P[] = { 1, 2, 3, 4, 5 }; + const size_t insn_count = sizeof(insns) / sizeof(insns[0]); + + if (!prog_validate(insns, insn_count)) + return false; + + return exec_prog_mchain2(insns, insn_count, P, sizeof(P), split) == 0; +} + +ATF_TC(bpfjit_mbuf_ldb_abs); +ATF_TC_HEAD(bpfjit_mbuf_ldb_abs, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_ABS " + "loads bytes from mbuf correctly"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldb_abs, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldb_abs(0)); + ATF_CHECK(test_ldb_abs(1)); + ATF_CHECK(test_ldb_abs(2)); + ATF_CHECK(test_ldb_abs(3)); + ATF_CHECK(test_ldb_abs(4)); + ATF_CHECK(test_ldb_abs(5)); +} + +ATF_TC(bpfjit_mbuf_ldh_abs); +ATF_TC_HEAD(bpfjit_mbuf_ldh_abs, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_ABS " + "loads halfwords from mbuf correctly"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldh_abs, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldh_abs(0)); + ATF_CHECK(test_ldh_abs(1)); + ATF_CHECK(test_ldh_abs(2)); + ATF_CHECK(test_ldh_abs(3)); + ATF_CHECK(test_ldh_abs(4)); + ATF_CHECK(test_ldh_abs(5)); +} + +ATF_TC(bpfjit_mbuf_ldw_abs); +ATF_TC_HEAD(bpfjit_mbuf_ldw_abs, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_ABS " + "loads words from mbuf correctly"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldw_abs, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldw_abs(0)); + ATF_CHECK(test_ldw_abs(1)); + ATF_CHECK(test_ldw_abs(2)); + ATF_CHECK(test_ldw_abs(3)); + ATF_CHECK(test_ldw_abs(4)); + ATF_CHECK(test_ldw_abs(5)); +} + +ATF_TC(bpfjit_mbuf_ldb_ind); +ATF_TC_HEAD(bpfjit_mbuf_ldb_ind, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND " + "loads bytes from mbuf correctly"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldb_ind, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldb_ind(0)); + ATF_CHECK(test_ldb_ind(1)); + ATF_CHECK(test_ldb_ind(2)); + ATF_CHECK(test_ldb_ind(3)); + ATF_CHECK(test_ldb_ind(4)); + ATF_CHECK(test_ldb_ind(5)); +} + +ATF_TC(bpfjit_mbuf_ldh_ind); +ATF_TC_HEAD(bpfjit_mbuf_ldh_ind, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND " + "loads halfwords from mbuf correctly"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldh_ind, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldh_ind(0)); + ATF_CHECK(test_ldh_ind(1)); + ATF_CHECK(test_ldh_ind(2)); + ATF_CHECK(test_ldh_ind(3)); + ATF_CHECK(test_ldh_ind(4)); + ATF_CHECK(test_ldh_ind(5)); +} + +ATF_TC(bpfjit_mbuf_ldw_ind); +ATF_TC_HEAD(bpfjit_mbuf_ldw_ind, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND " + "loads words from mbuf correctly"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldw_ind, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldw_ind(0)); + ATF_CHECK(test_ldw_ind(1)); + ATF_CHECK(test_ldw_ind(2)); + ATF_CHECK(test_ldw_ind(3)); + ATF_CHECK(test_ldw_ind(4)); + ATF_CHECK(test_ldw_ind(5)); +} + +ATF_TC(bpfjit_mbuf_msh); +ATF_TC_HEAD(bpfjit_mbuf_msh, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LDX+BPF_B+BPF_MSH " + "loads bytes from mbuf correctly"); +} + +ATF_TC_BODY(bpfjit_mbuf_msh, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_msh(0)); + ATF_CHECK(test_msh(1)); + ATF_CHECK(test_msh(2)); + ATF_CHECK(test_msh(3)); + ATF_CHECK(test_msh(4)); + ATF_CHECK(test_msh(5)); +} + +ATF_TC(bpfjit_mbuf_ldb_abs_overflow); +ATF_TC_HEAD(bpfjit_mbuf_ldb_abs_overflow, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_ABS " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldb_abs_overflow, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldb_abs_overflow(0)); + ATF_CHECK(test_ldb_abs_overflow(1)); + ATF_CHECK(test_ldb_abs_overflow(2)); + ATF_CHECK(test_ldb_abs_overflow(3)); + ATF_CHECK(test_ldb_abs_overflow(4)); + ATF_CHECK(test_ldb_abs_overflow(5)); +} + +ATF_TC(bpfjit_mbuf_ldh_abs_overflow); +ATF_TC_HEAD(bpfjit_mbuf_ldh_abs_overflow, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_ABS " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldh_abs_overflow, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldh_abs_overflow(0)); + ATF_CHECK(test_ldh_abs_overflow(1)); + ATF_CHECK(test_ldh_abs_overflow(2)); + ATF_CHECK(test_ldh_abs_overflow(3)); + ATF_CHECK(test_ldh_abs_overflow(4)); + ATF_CHECK(test_ldh_abs_overflow(5)); +} + +ATF_TC(bpfjit_mbuf_ldw_abs_overflow); +ATF_TC_HEAD(bpfjit_mbuf_ldw_abs_overflow, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_ABS " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldw_abs_overflow, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldw_abs_overflow(0)); + ATF_CHECK(test_ldw_abs_overflow(1)); + ATF_CHECK(test_ldw_abs_overflow(2)); + ATF_CHECK(test_ldw_abs_overflow(3)); + ATF_CHECK(test_ldw_abs_overflow(4)); + ATF_CHECK(test_ldw_abs_overflow(5)); +} + +ATF_TC(bpfjit_mbuf_ldb_ind_overflow1); +ATF_TC_HEAD(bpfjit_mbuf_ldb_ind_overflow1, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldb_ind_overflow1, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldb_ind_overflow1(0)); + ATF_CHECK(test_ldb_ind_overflow1(1)); + ATF_CHECK(test_ldb_ind_overflow1(2)); + ATF_CHECK(test_ldb_ind_overflow1(3)); + ATF_CHECK(test_ldb_ind_overflow1(4)); + ATF_CHECK(test_ldb_ind_overflow1(5)); +} + +ATF_TC(bpfjit_mbuf_ldb_ind_overflow2); +ATF_TC_HEAD(bpfjit_mbuf_ldb_ind_overflow2, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldb_ind_overflow2, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldb_ind_overflow2(0)); + ATF_CHECK(test_ldb_ind_overflow2(1)); + ATF_CHECK(test_ldb_ind_overflow2(2)); + ATF_CHECK(test_ldb_ind_overflow2(3)); + ATF_CHECK(test_ldb_ind_overflow2(4)); + ATF_CHECK(test_ldb_ind_overflow2(5)); +} + +ATF_TC(bpfjit_mbuf_ldb_ind_overflow3); +ATF_TC_HEAD(bpfjit_mbuf_ldb_ind_overflow3, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_B+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldb_ind_overflow3, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldb_ind_overflow3(0)); + ATF_CHECK(test_ldb_ind_overflow3(1)); + ATF_CHECK(test_ldb_ind_overflow3(2)); + ATF_CHECK(test_ldb_ind_overflow3(3)); + ATF_CHECK(test_ldb_ind_overflow3(4)); + ATF_CHECK(test_ldb_ind_overflow3(5)); +} + +ATF_TC(bpfjit_mbuf_ldh_ind_overflow1); +ATF_TC_HEAD(bpfjit_mbuf_ldh_ind_overflow1, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldh_ind_overflow1, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldh_ind_overflow1(0)); + ATF_CHECK(test_ldh_ind_overflow1(1)); + ATF_CHECK(test_ldh_ind_overflow1(2)); + ATF_CHECK(test_ldh_ind_overflow1(3)); + ATF_CHECK(test_ldh_ind_overflow1(4)); + ATF_CHECK(test_ldh_ind_overflow1(5)); +} + +ATF_TC(bpfjit_mbuf_ldh_ind_overflow2); +ATF_TC_HEAD(bpfjit_mbuf_ldh_ind_overflow2, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldh_ind_overflow2, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldh_ind_overflow2(0)); + ATF_CHECK(test_ldh_ind_overflow2(1)); + ATF_CHECK(test_ldh_ind_overflow2(2)); + ATF_CHECK(test_ldh_ind_overflow2(3)); + ATF_CHECK(test_ldh_ind_overflow2(4)); + ATF_CHECK(test_ldh_ind_overflow2(5)); +} + +ATF_TC(bpfjit_mbuf_ldh_ind_overflow3); +ATF_TC_HEAD(bpfjit_mbuf_ldh_ind_overflow3, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_H+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldh_ind_overflow3, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldh_ind_overflow3(0)); + ATF_CHECK(test_ldh_ind_overflow3(1)); + ATF_CHECK(test_ldh_ind_overflow3(2)); + ATF_CHECK(test_ldh_ind_overflow3(3)); + ATF_CHECK(test_ldh_ind_overflow3(4)); + ATF_CHECK(test_ldh_ind_overflow3(5)); +} + +ATF_TC(bpfjit_mbuf_ldw_ind_overflow1); +ATF_TC_HEAD(bpfjit_mbuf_ldw_ind_overflow1, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldw_ind_overflow1, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldw_ind_overflow1(0)); + ATF_CHECK(test_ldw_ind_overflow1(1)); + ATF_CHECK(test_ldw_ind_overflow1(2)); + ATF_CHECK(test_ldw_ind_overflow1(3)); + ATF_CHECK(test_ldw_ind_overflow1(4)); + ATF_CHECK(test_ldw_ind_overflow1(5)); +} + +ATF_TC(bpfjit_mbuf_ldw_ind_overflow2); +ATF_TC_HEAD(bpfjit_mbuf_ldw_ind_overflow2, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldw_ind_overflow2, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldw_ind_overflow2(0)); + ATF_CHECK(test_ldw_ind_overflow2(1)); + ATF_CHECK(test_ldw_ind_overflow2(2)); + ATF_CHECK(test_ldw_ind_overflow2(3)); + ATF_CHECK(test_ldw_ind_overflow2(4)); + ATF_CHECK(test_ldw_ind_overflow2(5)); +} + +ATF_TC(bpfjit_mbuf_ldw_ind_overflow3); +ATF_TC_HEAD(bpfjit_mbuf_ldw_ind_overflow3, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LD+BPF_W+BPF_IND " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_ldw_ind_overflow3, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_ldw_ind_overflow3(0)); + ATF_CHECK(test_ldw_ind_overflow3(1)); + ATF_CHECK(test_ldw_ind_overflow3(2)); + ATF_CHECK(test_ldw_ind_overflow3(3)); + ATF_CHECK(test_ldw_ind_overflow3(4)); + ATF_CHECK(test_ldw_ind_overflow3(5)); +} + +ATF_TC(bpfjit_mbuf_msh_overflow); +ATF_TC_HEAD(bpfjit_mbuf_msh_overflow, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that BPF_LDX+BPF_B+BPF_MSH " + "with out-of-bounds index aborts a filter program"); +} + +ATF_TC_BODY(bpfjit_mbuf_msh_overflow, tc) +{ + + RZ(rump_init()); + + ATF_CHECK(test_msh_overflow(0)); + ATF_CHECK(test_msh_overflow(1)); + ATF_CHECK(test_msh_overflow(2)); + ATF_CHECK(test_msh_overflow(3)); + ATF_CHECK(test_msh_overflow(4)); + ATF_CHECK(test_msh_overflow(5)); +} + +ATF_TP_ADD_TCS(tp) +{ + + /* + * For every new test please also add a similar test + * to ../../net/bpf/t_mbuf.c + */ + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldb_abs); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldh_abs); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldw_abs); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldb_ind); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldh_ind); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldw_ind); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_msh); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldb_abs_overflow); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldh_abs_overflow); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldw_abs_overflow); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldb_ind_overflow1); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldb_ind_overflow2); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldb_ind_overflow3); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldh_ind_overflow1); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldh_ind_overflow2); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldh_ind_overflow3); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldw_ind_overflow1); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldw_ind_overflow2); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_ldw_ind_overflow3); + ATF_TP_ADD_TC(tp, bpfjit_mbuf_msh_overflow); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/carp/t_basic.sh b/contrib/netbsd-tests/net/carp/t_basic.sh new file mode 100755 index 0000000..94ada1c --- /dev/null +++ b/contrib/netbsd-tests/net/carp/t_basic.sh @@ -0,0 +1,165 @@ +# $NetBSD: t_basic.sh,v 1.1 2017/01/16 08:18:11 ozaki-r Exp $ +# +# Copyright (c) 2017 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCK_CLIENT=unix://carp_client +SOCK_MASTER=unix://carp_master +SOCK_BACKUP=unix://carp_backup +BUS=bus_carp +IP_CLIENT=10.1.1.240 +IP_MASTER=10.1.1.1 +IP_BACKUP=10.1.1.2 +IP_CARP=10.1.1.100 +TIMEOUT=3 + +atf_test_case carp_handover cleanup + +carp_handover_head() +{ + + atf_set "descr" "Tests for CARP handover" + atf_set "require.progs" "rump_server" +} + +setup_carp() +{ + local sock=$1 + local master=$2 + local carpif= ip= advskew= + + if $master; then + carpif=carp0 + ip=$IP_MASTER + advskew=0 + else + carpif=carp1 + ip=$IP_BACKUP + advskew=200 + fi + + export RUMP_SERVER=$sock + atf_check -s exit:0 rump.ifconfig $carpif create + atf_check -s exit:0 rump.ifconfig shmif0 $ip/24 up + atf_check -s exit:0 rump.ifconfig $carpif \ + vhid 175 advskew $advskew advbase 1 pass s3cret \ + $IP_CARP netmask 255.255.255.0 + atf_check -s exit:0 rump.ifconfig -w 10 +} + +wait_handover() +{ + local i=0 + + export RUMP_SERVER=$SOCK_CLIENT + + while [ $i -ne 5 ]; do + $DEBUG && echo "Trying ping $IP_CARP" + rump.ping -n -w 1 -c 1 $IP_CARP >/dev/null + if [ $? = 0 ]; then + $DEBUG && echo "Passed ping $IP_CARP" + break; + fi + $DEBUG && echo "Failed ping $IP_CARP" + i=$((i + 1)) + done + + if [ $i -eq 5 ]; then + atf_fail "Failed to failover (5 sec)" + fi +} + +carp_handover_body() +{ + + rump_server_start $SOCK_CLIENT + rump_server_start $SOCK_MASTER + rump_server_start $SOCK_BACKUP + + rump_server_add_iface $SOCK_CLIENT shmif0 $BUS + rump_server_add_iface $SOCK_MASTER shmif0 $BUS + rump_server_add_iface $SOCK_BACKUP shmif0 $BUS + + setup_carp $SOCK_MASTER true + setup_carp $SOCK_BACKUP false + + export RUMP_SERVER=$SOCK_CLIENT + atf_check -s exit:0 rump.ifconfig shmif0 $IP_CLIENT/24 up + atf_check -s exit:0 rump.ifconfig -w 10 + + # Check that the primary addresses are up + atf_check -s exit:0 -o ignore \ + rump.ping -n -w $TIMEOUT -c 1 $IP_MASTER + atf_check -s exit:0 -o ignore \ + rump.ping -n -w $TIMEOUT -c 1 $IP_BACKUP + + # Give carp a while to croak + sleep 4 + + # Check state + export RUMP_SERVER=$SOCK_MASTER + $DEBUG && rump.ifconfig + atf_check -s exit:0 -o match:'carp: MASTER carpdev shmif0' \ + rump.ifconfig carp0 + export RUMP_SERVER=$SOCK_BACKUP + $DEBUG && rump.ifconfig + atf_check -s exit:0 -o match:'carp: BACKUP carpdev shmif0' \ + rump.ifconfig carp1 + export RUMP_SERVER=$SOCK_CLIENT + + # Check that the shared IP works + atf_check -s exit:0 -o ignore \ + rump.ping -n -w $TIMEOUT -c 1 $IP_CARP + + # KILLING SPREE + env RUMP_SERVER=$SOCK_MASTER rump.halt + sleep 1 + + # Check that primary is now dead + atf_check -s not-exit:0 -o ignore \ + rump.ping -n -w $TIMEOUT -c 1 $IP_MASTER + + # Do it in installments. carp will cluck meanwhile + wait_handover + + # Check state + export RUMP_SERVER=$SOCK_BACKUP + $DEBUG && rump.ifconfig + atf_check -s exit:0 -o match:'carp: MASTER carpdev shmif0' \ + rump.ifconfig carp1 +} + +carp_handover_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case carp_handover +} diff --git a/contrib/netbsd-tests/net/config/netconfig.c b/contrib/netbsd-tests/net/config/netconfig.c new file mode 100644 index 0000000..6fe37cc --- /dev/null +++ b/contrib/netbsd-tests/net/config/netconfig.c @@ -0,0 +1,231 @@ +/* $NetBSD: netconfig.c,v 1.9 2017/01/13 21:30:42 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#ifndef lint +__RCSID("$NetBSD: netconfig.c,v 1.9 2017/01/13 21:30:42 christos Exp $"); +#endif /* not lint */ + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "h_macros.h" + +int noatf; + +static void __unused +netcfg_rump_makeshmif(const char *busname, char *ifname) +{ + int rv, ifnum; + + if ((rv = rump_pub_shmif_create(busname, &ifnum)) != 0) { + if (noatf) + err(1, "makeshmif: rump_pub_shmif_create %d", rv); + else + atf_tc_fail("makeshmif: rump_pub_shmif_create %d", rv); + } + sprintf(ifname, "shmif%d", ifnum); +} + +static void __unused +netcfg_rump_if(const char *ifname, const char *addr, const char *mask) +{ + struct ifaliasreq ia; + struct sockaddr_in *sin; + in_addr_t inaddr, inmask; + int s, rv; + + s = -1; + if ((s = rump_sys_socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + if (noatf) + err(1, "if config socket"); + else + atf_tc_fail_errno("if config socket"); + } + + inaddr = inet_addr(addr); + inmask = inet_addr(mask); + + /* Address */ + memset(&ia, 0, sizeof(ia)); + strcpy(ia.ifra_name, ifname); + sin = (struct sockaddr_in *)&ia.ifra_addr; + sin->sin_family = AF_INET; + sin->sin_len = sizeof(struct sockaddr_in); + sin->sin_addr.s_addr = inaddr; + + /* Netmask */ + sin = (struct sockaddr_in *)&ia.ifra_mask; + sin->sin_family = AF_INET; + sin->sin_len = sizeof(struct sockaddr_in); + sin->sin_addr.s_addr = inmask; + + /* Broadcast address */ + sin = (struct sockaddr_in *)&ia.ifra_broadaddr; + sin->sin_family = AF_INET; + sin->sin_len = sizeof(struct sockaddr_in); + sin->sin_addr.s_addr = inaddr | ~inmask; + + rv = rump_sys_ioctl(s, SIOCAIFADDR, &ia); + if (rv == -1) { + if (noatf) + err(1, "SIOCAIFADDR"); + else + atf_tc_fail_errno("SIOCAIFADDR"); + } + rump_sys_close(s); +} + +static void __unused +netcfg_rump_route(const char *dst, const char *mask, const char *gw) +{ + size_t len; + struct { + struct rt_msghdr m_rtm; + uint8_t m_space[512]; + } m_rtmsg; +#define rtm m_rtmsg.m_rtm + uint8_t *bp = m_rtmsg.m_space; + struct sockaddr_in sinstore; + int s, rv; + + s = rump_sys_socket(PF_ROUTE, SOCK_RAW, 0); + if (s == -1) { + if (noatf) + err(1, "routing socket"); + else + atf_tc_fail_errno("routing socket"); + } + + memset(&m_rtmsg, 0, sizeof(m_rtmsg)); + rtm.rtm_type = RTM_ADD; + rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; + rtm.rtm_version = RTM_VERSION; + rtm.rtm_seq = 2; + rtm.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; + + /* dst */ + memset(&sinstore, 0, sizeof(sinstore)); + sinstore.sin_family = AF_INET; + sinstore.sin_len = sizeof(sinstore); + sinstore.sin_addr.s_addr = inet_addr(dst); + memcpy(bp, &sinstore, sizeof(sinstore)); + bp += sizeof(sinstore); + + /* gw */ + memset(&sinstore, 0, sizeof(sinstore)); + sinstore.sin_family = AF_INET; + sinstore.sin_len = sizeof(sinstore); + sinstore.sin_addr.s_addr = inet_addr(gw); + memcpy(bp, &sinstore, sizeof(sinstore)); + bp += sizeof(sinstore); + + /* netmask */ + memset(&sinstore, 0, sizeof(sinstore)); + sinstore.sin_family = AF_INET; + sinstore.sin_len = sizeof(sinstore); + sinstore.sin_addr.s_addr = inet_addr(mask); + memcpy(bp, &sinstore, sizeof(sinstore)); + bp += sizeof(sinstore); + + len = bp - (uint8_t *)&m_rtmsg; + rtm.rtm_msglen = len; + + rv = rump_sys_write(s, &m_rtmsg, len); + if (rv != (int)len) { + if (noatf) + err(1, "write routing message"); + else + atf_tc_fail_errno("write routing message"); + } + rump_sys_close(s); +} + +static bool __unused +netcfg_rump_pingtest(const char *dst, int ms_timo) +{ + struct timeval tv; + struct sockaddr_in sin; + struct icmp icmp; + socklen_t slen; + int s; + bool rv = false; + + s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); + if (s == -1) + return false; + tv.tv_sec = ms_timo / 1000; + tv.tv_usec = 1000 * (ms_timo % 1000); + if (rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, + &tv, sizeof(tv)) == -1) + goto out; + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = inet_addr(dst); + + memset(&icmp, 0, sizeof(icmp)); + icmp.icmp_type = ICMP_ECHO; + icmp.icmp_id = htons(37); + icmp.icmp_cksum = htons(0xf7da); /* precalc */ + + slen = sizeof(sin); + if (rump_sys_sendto(s, &icmp, sizeof(icmp), 0, + (struct sockaddr *)&sin, slen) == -1) { + goto out; + } + + if (rump_sys_recvfrom(s, &icmp, sizeof(icmp), 0, + (struct sockaddr *)&sin, &slen) == -1) + goto out; + + rv = true; + out: + rump_sys_close(s); + return rv; +} diff --git a/contrib/netbsd-tests/net/fdpass/fdpass.c b/contrib/netbsd-tests/net/fdpass/fdpass.c new file mode 100644 index 0000000..17b0a1d --- /dev/null +++ b/contrib/netbsd-tests/net/fdpass/fdpass.c @@ -0,0 +1,231 @@ +/* $NetBSD: fdpass.c,v 1.1 2012/08/13 11:15:05 christos Exp $ */ +/* $OpenBSD: monitor_fdpass.c,v 1.19 2010/01/12 00:58:25 djm Exp $ */ +/* + * Copyright 2001 Niels Provos + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__RCSID("$NetBSD: fdpass.c,v 1.1 2012/08/13 11:15:05 christos Exp $"); +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static int debug; + +static int +send_fd(int sock, int fd) +{ + struct msghdr msg; + union { + struct cmsghdr hdr; + char buf[1024]; + } cmsgbuf; + struct cmsghdr *cmsg; + struct iovec vec; + char ch = '\0'; + ssize_t n; + struct pollfd pfd; + + if (sizeof(cmsgbuf.buf) < CMSG_SPACE(sizeof(int))) + errx(1, "%s: %zu < %zu, recompile", __func__, + sizeof(cmsgbuf.buf), CMSG_SPACE(sizeof(int))); + + memset(&msg, 0, sizeof(msg)); + msg.msg_control = &cmsgbuf.buf; + msg.msg_controllen = CMSG_SPACE(sizeof(int)); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = fd; + msg.msg_controllen = cmsg->cmsg_len; + + vec.iov_base = &ch; + vec.iov_len = 1; + msg.msg_iov = &vec; + msg.msg_iovlen = 1; + + pfd.fd = sock; + pfd.events = POLLOUT; + while ((n = sendmsg(sock, &msg, 0)) == -1 && + (errno == EAGAIN || errno == EINTR)) { + (void)poll(&pfd, 1, -1); + } + switch (n) { + case -1: + err(1, "%s: sendmsg(%d)", __func__, fd); + case 1: + if (debug) + fprintf(stderr, "%d: send fd %d\n", getpid(), fd); + return 0; + default: + errx(1, "%s: sendmsg: expected sent 1 got %ld", + __func__, (long)n); + } +} + +static int +recv_fd(int sock) +{ + struct msghdr msg; + union { + struct cmsghdr hdr; + char buf[1024]; + } cmsgbuf; + struct cmsghdr *cmsg; + struct iovec vec; + ssize_t n; + char ch; + int fd; + struct pollfd pfd; + + if (sizeof(cmsgbuf.buf) < CMSG_SPACE(sizeof(int))) + errx(1, "%s: %zu < %zu, recompile", __func__, + sizeof(cmsgbuf.buf), CMSG_SPACE(sizeof(int))); + + memset(&msg, 0, sizeof(msg)); + vec.iov_base = &ch; + vec.iov_len = 1; + msg.msg_iov = &vec; + msg.msg_iovlen = 1; + msg.msg_control = &cmsgbuf.buf; + msg.msg_controllen = CMSG_SPACE(sizeof(int)); + + pfd.fd = sock; + pfd.events = POLLIN; + while ((n = recvmsg(sock, &msg, 0)) == -1 && + (errno == EAGAIN || errno == EINTR)) { + (void)poll(&pfd, 1, -1); + } + switch (n) { + case -1: + err(1, "%s: recvmsg", __func__); + case 1: + break; + default: + errx(1, "%s: recvmsg: expected received 1 got %ld", + __func__, (long)n); + } + + cmsg = CMSG_FIRSTHDR(&msg); + if (cmsg == NULL) + errx(1, "%s: no message header", __func__); + + if (cmsg->cmsg_type != SCM_RIGHTS) + err(1, "%s: expected type %d got %d", __func__, + SCM_RIGHTS, cmsg->cmsg_type); + fd = (*(int *)CMSG_DATA(cmsg)); + if (debug) + fprintf(stderr, "%d: recv fd %d\n", getpid(), fd); + return fd; +} + +static void usage(void) __attribute__((__noreturn__)); + +static void +usage(void) +{ + fprintf(stderr, "Usage: %s [-vd] -i -o \n" + "\t %s [-v] -p \n", getprogname(), getprogname()); + exit(EXIT_FAILURE); +} + +int +main(int argc, char *argv[]) +{ + int s[2], fd, status, c, verbose; + char buf[1024], *prog; + + prog = NULL; + s[0] = s[1] = -1; + verbose = 0; + + while ((c = getopt(argc, argv, "di:o:p:")) != -1) + switch (c) { + case 'd': + debug++; + break; + case 'i': + s[0] = atoi(optarg); + break; + case 'o': + s[1] = atoi(optarg); + break; + case 'p': + prog = optarg; + break; + default: + usage(); + } + + if ((s[0] == -1 && s[1] != -1) || (s[0] != -1 && s[1] == -1)) + usage(); + + if (s[0] == -1) { + if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, s) == -1) + err(1, "socketpair"); + } else + goto recv; + + switch (fork()) { + case -1: + err(1, "fork"); + default: + fd = open("foo", O_RDWR|O_CREAT|O_TRUNC, 0666); + if (fd == -1) + err(1, "open"); + send_fd(s[0], fd); + wait(&status); + return 0; + case 0: + if (prog != NULL) { + char i[64], o[64]; + snprintf(i, sizeof(i), "%d", s[0]); + snprintf(o, sizeof(o), "%d", s[1]); + execlp(prog, prog, "-i", i, "-o", o, NULL); + err(1, "execlp"); + } + recv: + fd = recv_fd(s[1]); + if (verbose) { + snprintf(buf, sizeof(buf), "ls -l /proc/%d/fd", + getpid()); + system(buf); + } + if (write(fd, "foo\n", 4) == -1) + err(1, "write"); + close(fd); + return 0; + } +} diff --git a/contrib/netbsd-tests/net/fdpass/t_fdpass.sh b/contrib/netbsd-tests/net/fdpass/t_fdpass.sh new file mode 100755 index 0000000..4e4ac04 --- /dev/null +++ b/contrib/netbsd-tests/net/fdpass/t_fdpass.sh @@ -0,0 +1,99 @@ +# $NetBSD: t_fdpass.sh,v 1.2 2012/08/16 08:39:43 martin Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Christos Zoulas +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +have32() { + local src="$(atf_get_srcdir)" + if cmp "${src}/fdpass64" "${src}/fdpass32" > /dev/null + then + # echo "no -m32 support" + return 1 + else + return 0 + fi +} + +atf_test_case fdpass_normal + +fdpass_normal_head() { + atf_set "descr" "Test file descriptor passing (default)" +} + +fdpass_normal_body() { + local src="$(atf_get_srcdir)" + atf_check "${src}/fdpass64" +} + + +atf_test_case fdpass_compat + +fdpass_compat_head() { + atf_set "descr" "Test file descriptor passing (compat)" +} + +fdpass_compat_body() { + local src="$(atf_get_srcdir)" + have32 && atf_check "${src}/fdpass32" +} + + +atf_test_case fdpass_normal_compat + +fdpass_normal_compat_head() { + atf_set "descr" "Test file descriptor passing (normal->compat)" +} + +fdpass_normal_compat_body() { + local src="$(atf_get_srcdir)" + have32 && atf_check "${src}/fdpass64" -p "${src}/fdpass32" +} + + +atf_test_case fdpass_compat_normal + +fdpass_compat_normal_head() { + atf_set "descr" "Test file descriptor passing (normal->compat)" +} + +fdpass_compat_normal_body() { + local src="$(atf_get_srcdir)" + have32 && atf_check "${src}/fdpass32" -p "${src}/fdpass64" +} + + +atf_init_test_cases() +{ + atf_add_test_case fdpass_normal + if have32 + then + atf_add_test_case fdpass_compat + atf_add_test_case fdpass_compat_normal + atf_add_test_case fdpass_normal_compat + fi +} diff --git a/contrib/netbsd-tests/net/icmp/t_forward.c b/contrib/netbsd-tests/net/icmp/t_forward.c new file mode 100644 index 0000000..346614c --- /dev/null +++ b/contrib/netbsd-tests/net/icmp/t_forward.c @@ -0,0 +1,169 @@ +/* $NetBSD: t_forward.c,v 1.10 2017/01/13 21:30:42 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#ifndef lint +__RCSID("$NetBSD: t_forward.c,v 1.10 2017/01/13 21:30:42 christos Exp $"); +#endif /* not lint */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "h_macros.h" +#include "../config/netconfig.c" + +/* + * Since our maxttl is in our private namespace, we don't need raw packet + * construction like traceroute(8) -- we can just use the global maxttl. + */ +static void +sendttl(void) +{ + struct sockaddr_in sin; + char payload[1024]; + char ifname[IFNAMSIZ]; + int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL }; + int nv; + int s; + + netcfg_rump_makeshmif("bus1", ifname); + netcfg_rump_if(ifname, "1.0.0.1", "255.255.255.0"); + netcfg_rump_route("0.0.0.0", "0.0.0.0", "1.0.0.2"); /* default router */ + + /* set global ttl to 1 */ + nv = 1; + if (rump_sys___sysctl(mib, 4, NULL, NULL, &nv, sizeof(nv)) == -1) + atf_tc_fail_errno("set ttl"); + + s = rump_sys_socket(PF_INET, SOCK_DGRAM, 0); + if (s == -1) + atf_tc_fail_errno("create send socket"); + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(33434); + sin.sin_addr.s_addr = inet_addr("9.9.9.9"); + + /* send udp datagram with ttl == 1 */ + if (rump_sys_sendto(s, payload, sizeof(payload), 0, + (struct sockaddr *)&sin, sizeof(sin)) == -1) + atf_tc_fail_errno("sendto"); +} + +static void +router(void) +{ + int mib[4] = { CTL_NET, PF_INET, IPPROTO_ICMP, + ICMPCTL_RETURNDATABYTES }; + char ifname[IFNAMSIZ]; + int nv; + + /* set returndatabytes to 200 */ + nv = 200; + if (rump_sys___sysctl(mib, 4, NULL, NULL, &nv, sizeof(nv)) == -1) + atf_tc_fail_errno("sysctl returndatabytes"); + + netcfg_rump_makeshmif("bus1", ifname); + netcfg_rump_if(ifname, "1.0.0.2", "255.255.255.0"); + + /* + * Wait for parent to send us the data and for us to have + * a chance to process it. + */ + sleep(1); + exit(0); +} + +ATF_TC(returndatabytes); +ATF_TC_HEAD(returndatabytes, tc) +{ + + atf_tc_set_md_var(tc, "descr", "icmp.returndatabytes with certain " + "packets can cause kernel panic (PR kern/43548)"); + atf_tc_set_md_var(tc, "timeout", "20"); /* just in case */ +} + +ATF_TC_BODY(returndatabytes, tc) +{ + pid_t cpid; + int status; + + cpid = fork(); + rump_init(); + + switch (cpid) { + case -1: + atf_tc_fail_errno("fork failed"); + case 0: + router(); + break; + default: + sendttl(); + if (wait(&status) == -1) + atf_tc_fail_errno("wait"); + if (WIFEXITED(status)) { + if (WEXITSTATUS(status)) + atf_tc_fail("child exited with status %d", + WEXITSTATUS(status)); + } else { + atf_tc_fail("child died"); + } + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, returndatabytes); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/icmp/t_icmp6_redirect.sh b/contrib/netbsd-tests/net/icmp/t_icmp6_redirect.sh new file mode 100755 index 0000000..5dcdc9c --- /dev/null +++ b/contrib/netbsd-tests/net/icmp/t_icmp6_redirect.sh @@ -0,0 +1,152 @@ +# $NetBSD: t_icmp6_redirect.sh,v 1.7 2016/11/25 08:51:16 ozaki-r Exp $ +# +# Copyright (c) 2015 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCK_LOCAL=unix://commsock1 +SOCK_PEER=unix://commsock2 +SOCK_GW1=unix://commsock3 +SOCK_GW2=unix://commsock4 + +BUS1=bus1 +BUS2=bus2 +IP6BUS1=fc00:1::/64 +IP6BUS2=fc00:2::/64 +IP6IF0_LOCAL=fc00:1::2 +IP6IF0_PEER=fc00:2::2 +IP6IF0_GW1=fc00:1::1 +IP6IF1_GW1=fc00:2::1 +IP6IF0_GW2=fc00:1::3 + +REDIRECT_TIMEOUT=5 + +DEBUG=${DEBUG:-true} + +atf_test_case icmp6_redirect_basic cleanup + +icmp6_redirect_basic_head() +{ + + atf_set "descr" "Test for the basically function of the ICMP6 redirect" + atf_set "require.progs" "rump_server rump.route rump.ping rump.ifconfig" +} + +icmp6_redirect_basic_body() +{ + local gw1_lladdr0= + local gw1_lladdr1= + local gw2_lladdr0= + + rump_server_start $SOCK_LOCAL netinet6 + rump_server_start $SOCK_PEER netinet6 + rump_server_start $SOCK_GW1 netinet6 + rump_server_start $SOCK_GW2 netinet6 + + # + # Setup + # + # Setup gateway #1 (real gateway) + export RUMP_SERVER=${SOCK_GW1} + rump_server_add_iface $SOCK_GW1 shmif0 $BUS1 + rump_server_add_iface $SOCK_GW1 shmif1 $BUS2 + + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6IF0_GW1} + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${IP6IF1_GW1} + atf_check -s exit:0 rump.ifconfig shmif1 up + + atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w \ + net.inet6.ip6.forwarding=1 + unset RUMP_SERVER + + gw1_lladdr0=`get_linklocal_addr ${SOCK_GW1} shmif0` + gw1_lladdr1=`get_linklocal_addr ${SOCK_GW1} shmif1` + + # Setup a peer behind gateway #1 + export RUMP_SERVER=${SOCK_PEER} + rump_server_add_iface $SOCK_PEER shmif0 $BUS2 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6IF0_PEER} + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 -o ignore rump.route add \ + -inet6 default ${gw1_lladdr1}%shmif0 + unset RUMP_SERVER + + # Setup gateway #2 (fake gateway) + export RUMP_SERVER=${SOCK_GW2} + rump_server_add_iface $SOCK_GW2 shmif0 $BUS1 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6IF0_GW2} + atf_check -s exit:0 rump.ifconfig shmif0 up + + atf_check -s exit:0 -o ignore rump.route add \ + -inet6 ${IP6BUS2} ${gw1_lladdr0}%shmif0 + atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w \ + net.inet6.ip6.forwarding=1 + unset RUMP_SERVER + + gw2_lladdr0=`get_linklocal_addr ${SOCK_GW2} shmif0` + + export RUMP_SERVER=${SOCK_LOCAL} + rump_server_add_iface $SOCK_LOCAL shmif0 $BUS1 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6IF0_LOCAL} + atf_check -s exit:0 rump.ifconfig shmif0 up + + # Teach the fake gateway as the default gateway + atf_check -s exit:0 -o ignore rump.route add \ + -inet6 default ${gw2_lladdr0}%shmif0 + $DEBUG && rump.route get -inet6 ${IP6IF0_PEER} + + atf_check -s exit:0 -o ignore rump.sysctl -w \ + net.inet6.icmp6.redirtimeout=$REDIRECT_TIMEOUT + + # + # Tests + # + atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n ${IP6IF0_PEER} + $DEBUG && rump.route show -inet6 + # Check if a created route is correctly redirected to gateway #1 + atf_check -s exit:0 -o match:"gateway: ${gw1_lladdr0}" rump.route get \ + -inet6 ${IP6IF0_PEER} + + atf_check -s exit:0 sleep $((REDIRECT_TIMEOUT + 2)) + $DEBUG && rump.route show -inet6 + # Check if the created route is expired + atf_check -s exit:0 -o not-match:"gateway: ${gw1_lladdr0}" rump.route get \ + -inet6 ${IP6IF0_PEER} + + rump_server_destroy_ifaces +} + +icmp6_redirect_basic_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case icmp6_redirect_basic +} diff --git a/contrib/netbsd-tests/net/icmp/t_icmp_redirect.sh b/contrib/netbsd-tests/net/icmp/t_icmp_redirect.sh new file mode 100755 index 0000000..6697216 --- /dev/null +++ b/contrib/netbsd-tests/net/icmp/t_icmp_redirect.sh @@ -0,0 +1,285 @@ +# $NetBSD: t_icmp_redirect.sh,v 1.6 2016/11/25 08:51:16 ozaki-r Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# Most codes are derived from tests/net/route/t_flags.sh + +SOCK_LOCAL=unix://commsock1 +SOCK_PEER=unix://commsock2 +SOCK_GW=unix://commsock3 +BUS=bus1 +BUS2=bus2 +REDIRECT_TIMEOUT=5 + +DEBUG=${DEBUG:-false} + +atf_test_case icmp_redirect_timeout cleanup + +icmp_redirect_timeout_head() +{ + + atf_set "descr" "Tests for ICMP redirect timeout"; + atf_set "require.progs" "rump_server"; +} + +setup_local() +{ + + rump_server_start $SOCK_LOCAL + rump_server_add_iface $SOCK_LOCAL shmif0 $BUS + + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 10.0.0.2/24 + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + + atf_check -s exit:0 -o ignore rump.sysctl -w \ + net.inet.icmp.redirtimeout=$REDIRECT_TIMEOUT + + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -rn -f inet +} + +setup_peer() +{ + + rump_server_start $SOCK_PEER + rump_server_add_iface $SOCK_PEER shmif0 $BUS + + export RUMP_SERVER=$SOCK_PEER + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 10.0.0.1/24 + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -rn -f inet +} + +setup_gw() +{ + + rump_server_start $SOCK_GW + rump_server_add_iface $SOCK_GW shmif0 $BUS + rump_server_add_iface $SOCK_GW shmif1 $BUS2 + + export RUMP_SERVER=$SOCK_GW + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 10.0.0.254/24 + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + + atf_check -s exit:0 -o ignore rump.ifconfig shmif1 10.0.2.1/24 + atf_check -s exit:0 -o ignore rump.ifconfig shmif1 alias 10.0.2.2/24 + atf_check -s exit:0 -o ignore rump.ifconfig shmif1 up + + # Wait until DAD completes (10 sec at most) + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + atf_check -s not-exit:0 -x "rump.ifconfig shmif1 |grep -q tentative" + + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -rn -f inet +} + +icmp_redirect_timeout_body() +{ + + $DEBUG && ulimit -c unlimited + + setup_local + setup_peer + + ### Testing Dynamic flag ### + + # + # Setup a gateway 10.0.0.254. 10.0.2.1 is behind it. + # + setup_gw + + # + # Teach the peer that 10.0.2.* is behind 10.0.0.254 + # + export RUMP_SERVER=$SOCK_PEER + atf_check -s exit:0 -o ignore rump.route add -net 10.0.2.0/24 10.0.0.254 + # Up, Gateway, Static + check_route_flags 10.0.2/24 UGS + + # + # Setup the default gateway to the peer, 10.0.0.1 + # + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 -o ignore rump.route add default 10.0.0.1 + # Up, Gateway, Static + check_route_flags default UGS + + # Try ping 10.0.2.1 + atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.2.1 + $DEBUG && rump.netstat -rn -f inet + + # Up, Gateway, Host, Dynamic + check_route_flags 10.0.2.1 UGHD + check_route_gw 10.0.2.1 10.0.0.254 + + atf_check -s exit:0 sleep $((REDIRECT_TIMEOUT + 2)) + + # The dynamic entry should be expired and removed + check_route_no_entry 10.0.2.1 + + export RUMP_SERVER=$SOCK_PEER + $DEBUG && rump.netstat -rn -f inet + + rump_server_destroy_ifaces +} + +icmp_redirect_timeout_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_test_case icmp_redirect cleanup + +icmp_redirect_head() +{ + + atf_set "descr" "Tests for icmp redirect"; + atf_set "require.progs" "rump_server"; +} + +setup_redirect() +{ + atf_check -s exit:0 -o ignore rump.sysctl -w \ + net.inet.ip.redirect=1 +} + +teardown_redirect() +{ + atf_check -s exit:0 -o ignore rump.sysctl -w \ + net.inet.ip.redirect=0 +} + +icmp_redirect_body() +{ + + $DEBUG && ulimit -c unlimited + + setup_local + setup_peer + + # + # Setup a gateway 10.0.0.254. 10.0.2.1 is behind it. + # + setup_gw + + # + # Teach the peer that 10.0.2.* is behind 10.0.0.254 + # + export RUMP_SERVER=$SOCK_PEER + atf_check -s exit:0 -o ignore rump.route add -net 10.0.2.0/24 10.0.0.254 + # Up, Gateway, Static + check_route_flags 10.0.2/24 UGS + + # + # Setup the default gateway to the peer, 10.0.0.1 + # + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 -o ignore rump.route add default 10.0.0.1 + # Up, Gateway, Static + check_route_flags default UGS + + + ### ICMP redirects are NOT sent by the peer ### + + # + # Disable net.inet.ip.redirect + # + export RUMP_SERVER=$SOCK_PEER + teardown_redirect + + # Try ping 10.0.2.1 + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.2.1 + $DEBUG && rump.netstat -rn -f inet + + # A direct route shouldn't be created + check_route_no_entry 10.0.2.1 + + + ### ICMP redirects are sent by the peer ### + + # + # Enable net.inet.ip.redirect + # + export RUMP_SERVER=$SOCK_PEER + setup_redirect + + # Try ping 10.0.2.1 + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.2.1 + $DEBUG && rump.netstat -rn -f inet + + # Up, Gateway, Host, Dynamic + check_route_flags 10.0.2.1 UGHD + check_route_gw 10.0.2.1 10.0.0.254 + + export RUMP_SERVER=$SOCK_PEER + $DEBUG && rump.netstat -rn -f inet + + + # cleanup + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 -o ignore rump.route delete 10.0.2.1 + check_route_no_entry 10.0.2.1 + + + ### ICMP redirects are NOT sent by the peer (again) ### + + # + # Disable net.inet.ip.redirect + # + export RUMP_SERVER=$SOCK_PEER + teardown_redirect + + # Try ping 10.0.2.1 + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.2.1 + $DEBUG && rump.netstat -rn -f inet + + # A direct route shouldn't be created + check_route_no_entry 10.0.2.1 + + rump_server_destroy_ifaces +} + +icmp_redirect_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case icmp_redirect + atf_add_test_case icmp_redirect_timeout +} diff --git a/contrib/netbsd-tests/net/icmp/t_ping.c b/contrib/netbsd-tests/net/icmp/t_ping.c new file mode 100644 index 0000000..b3327e1 --- /dev/null +++ b/contrib/netbsd-tests/net/icmp/t_ping.c @@ -0,0 +1,438 @@ +/* $NetBSD: t_ping.c,v 1.17 2017/01/13 21:30:42 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#ifndef lint +__RCSID("$NetBSD: t_ping.c,v 1.17 2017/01/13 21:30:42 christos Exp $"); +#endif /* not lint */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "h_macros.h" +#include "../config/netconfig.c" + +ATF_TC(simpleping); +ATF_TC_HEAD(simpleping, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check that kernel responds to ping"); + atf_tc_set_md_var(tc, "timeout", "20"); +} + +ATF_TC_BODY(simpleping, tc) +{ + char ifname[IFNAMSIZ]; + pid_t cpid; + bool win, win2; + char token; + int channel[2]; + + RL(pipe(channel)); + + cpid = fork(); + rump_init(); + netcfg_rump_makeshmif("but-can-i-buy-your-ether-bus", ifname); + + switch (cpid) { + case -1: + atf_tc_fail_errno("fork failed"); + case 0: + netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); + close(channel[0]); + ATF_CHECK(write(channel[1], "U", 1) == 1); + close(channel[1]); + pause(); + break; + default: + break; + } + + close(channel[1]); + ATF_CHECK(read(channel[0], &token, 1) == 1 && token == 'U'); + close(channel[0]); + + netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); + + /* + * The beauty of shmif is that we don't have races here. + */ + win = netcfg_rump_pingtest("1.1.1.10", 500); + win2 = netcfg_rump_pingtest("1.1.1.30", 500); + + kill(cpid, SIGKILL); + + if (!win) + atf_tc_fail("ping failed"); + if (win2) + atf_tc_fail("non-existent host responded"); +} + +ATF_TC(floodping); +ATF_TC_HEAD(floodping, tc) +{ + + atf_tc_set_md_var(tc, "descr", "see how kernel responds to floodping"); +} + +/* why the hell isn't this available in userspace??? */ +static uint16_t +in_cksum(void *data, size_t len) +{ + uint16_t *buf = data; + unsigned sum; + + for (sum = 0; len > 1; len -= 2) + sum += *buf++; + if (len) + sum += *(uint8_t *)buf; + + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + + return ~sum; +} + +static int +doping(const char *target, int loops, u_int pktsize) +{ + union { + char buf[IP_MAXPACKET - sizeof(struct ip)]; + struct icmp i; /* ensure proper alignment */ + } sndbuf; + char recvbuf[IP_MAXPACKET]; + struct sockaddr_in dst, pingee; + struct icmp *icmp; + socklen_t slen; + ssize_t n; + int loop, succ; + int x, xnon, s; + + RL(s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)); + RL(x = rump_sys_fcntl(s, F_GETFL, 0)); + xnon = x | O_NONBLOCK; + + memset(&dst, 0, sizeof(dst)); + dst.sin_len = sizeof(dst); + dst.sin_family = AF_INET; + dst.sin_addr.s_addr = inet_addr(target); + + icmp = (struct icmp *)&sndbuf; + memset(icmp, 0, sizeof(*icmp)); + icmp->icmp_type = ICMP_ECHO; + icmp->icmp_id = htons(37); + + if (pktsize < sizeof(*icmp)) + pktsize = sizeof(*icmp); + if (pktsize > sizeof(sndbuf.buf)) + pktsize = sizeof(sndbuf.buf); + + RL(rump_sys_setsockopt(s, SOL_SOCKET, SO_SNDBUF, + &pktsize, sizeof(pktsize))); + RL(rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVBUF, + &pktsize, sizeof(pktsize))); + + slen = sizeof(pingee); + succ = 0; + for (loop = 0; loop < loops; loop++) { + RL(rump_sys_fcntl(s, F_SETFL, x)); + icmp->icmp_seq = htons(loop); + icmp->icmp_cksum = 0; + icmp->icmp_cksum = in_cksum(icmp, pktsize); + RL(rump_sys_sendto(s, icmp, pktsize, 0, + (struct sockaddr *)&dst, sizeof(dst))); + + RL(rump_sys_fcntl(s, F_SETFL, xnon)); + while ((n = rump_sys_recvfrom(s, recvbuf, sizeof(recvbuf), 0, + (struct sockaddr *)&pingee, &slen)) > 0) { + succ++; + } + if (n == -1 && errno == EAGAIN) + continue; + atf_tc_fail_errno("recv failed"); + } + + rump_sys_close(s); + return succ; +} + +#define LOOPS 10000 + +ATF_TC_BODY(floodping, tc) +{ + char ifname[IFNAMSIZ]; + pid_t cpid; + int succ; + + cpid = fork(); + rump_init(); + netcfg_rump_makeshmif("thank-you-driver-for-getting-me-here", ifname); + + switch (cpid) { + case -1: + atf_tc_fail_errno("fork failed"); + case 0: + netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); + pause(); + break; + default: + break; + } + + netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); + + succ = doping("1.1.1.10", LOOPS, 56); + printf("got %d/%d\n", succ, LOOPS); + + kill(cpid, SIGKILL); +} + +ATF_TC(floodping2); +ATF_TC_HEAD(floodping2, tc) +{ + + atf_tc_set_md_var(tc, "descr", "two hosts floodpinging each other"); +} + +ATF_TC_BODY(floodping2, tc) +{ + char ifname[IFNAMSIZ]; + pid_t cpid; + int succ; + + cpid = fork(); + rump_init(); + netcfg_rump_makeshmif("floodping2", ifname); + + switch (cpid) { + case -1: + atf_tc_fail_errno("fork failed"); + case 0: + netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); + succ = doping("1.1.1.20", LOOPS, 56); + break; + default: + netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); + succ = doping("1.1.1.10", LOOPS, 56); + break; + } + + printf("got %d/%d\n", succ, LOOPS); +} + +ATF_TC(pingsize); +ATF_TC_HEAD(pingsize, tc) +{ + + atf_tc_set_md_var(tc, "descr", "ping with packets min <= size <= max"); +} + +ATF_TC_BODY(pingsize, tc) +{ + char ifname[IFNAMSIZ]; + pid_t cpid; + int succ, i; + + cpid = fork(); + rump_init(); + netcfg_rump_makeshmif("jippikaiee", ifname); + + switch (cpid) { + case -1: + atf_tc_fail_errno("fork failed"); + case 0: + netcfg_rump_if(ifname, "1.1.1.10", "255.255.255.0"); + pause(); + break; + default: + break; + } + + netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); + + succ = 0; + + /* small sizes */ + for (i = 0 ; i < IP_MAXPACKET - 60000; i++) + succ += doping("1.1.1.10", 1, i); + + /* medium sizes */ + for (i = IP_MAXPACKET - 60000; i < IP_MAXPACKET - 100; i += 1000) + succ += doping("1.1.1.10", 1, i); + + /* big sizes */ + for (i = IP_MAXPACKET - 100; i < IP_MAXPACKET; i += 10) + succ += doping("1.1.1.10", 1, i); + + printf("got %d/%d\n", succ, IP_MAXPACKET); + kill(cpid, SIGKILL); +} + +ATF_TC(ping_of_death); +ATF_TC_HEAD(ping_of_death, tc) +{ + + atf_tc_set_md_var(tc, "descr", "send a \"ping of death\""); + atf_tc_set_md_var(tc, "timeout", "20"); +} + +ATF_TC_BODY(ping_of_death, tc) +{ + char data[1500]; + struct sockaddr_in dst; + struct ip *ip; + struct icmp *icmp; + char ifname[IFNAMSIZ]; + pid_t cpid; + size_t tot, frag; + int s, x, loop; + + cpid = fork(); + rump_init(); + netcfg_rump_makeshmif("jippikaiee", ifname); + + switch (cpid) { + case -1: + atf_tc_fail_errno("fork failed"); + case 0: + /* wait until we receive a too long IP packet */ + for (loop = 0;; loop++) { + uint64_t ipstat[IP_NSTATS]; + size_t arglen; + int mib[4]; + + if (loop == 1) + netcfg_rump_if(ifname, + "1.1.1.10", "255.255.255.0"); + + mib[0] = CTL_NET; + mib[1] = PF_INET; + mib[2] = IPPROTO_IP; + mib[3] = IPCTL_STATS; + + arglen = sizeof(ipstat); + RL(rump_sys___sysctl(mib, 4, &ipstat, &arglen, + NULL, 0)); + if (loop == 0 && ipstat[IP_STAT_TOOLONG] != 0) + _exit(1); + if (ipstat[IP_STAT_TOOLONG]) + break; + usleep(10000); + } + + _exit(0); + break; + default: + break; + } + + netcfg_rump_if(ifname, "1.1.1.20", "255.255.255.0"); + + RL(s = rump_sys_socket(PF_INET, SOCK_RAW, 0)); + x = 1; + RL(rump_sys_setsockopt(s, IPPROTO_IP, IP_HDRINCL, &x, sizeof(x))); + + memset(&dst, 0, sizeof(dst)); + dst.sin_len = sizeof(dst); + dst.sin_family = AF_INET; + dst.sin_addr.s_addr = inet_addr("1.1.1.10"); + + /* construct packet */ + memset(data, 0, sizeof(data)); + ip = (struct ip *)data; + ip->ip_v = 4; + ip->ip_hl = sizeof(*ip) >> 2; + ip->ip_p = IPPROTO_ICMP; + ip->ip_ttl = IPDEFTTL; + ip->ip_dst = dst.sin_addr; + ip->ip_id = 1234; + + icmp = (struct icmp *)(ip + 1); + icmp->icmp_type = ICMP_ECHO; + icmp->icmp_cksum = in_cksum(icmp, sizeof(*icmp)); + + for (;;) { + int status; + + /* resolve arp before sending raw stuff */ + netcfg_rump_pingtest("1.1.1.10", 1); + + for (tot = 0; + tot < 65538 - sizeof(*ip); + tot += (frag - sizeof(*ip))) { + frag = MIN(65538 - tot, sizeof(data)); + ip->ip_off = tot >> 3; + assert((size_t)ip->ip_off << 3 == tot); + ip->ip_len = frag; + + if (frag == sizeof(data)) { + ip->ip_off |= IP_MF; + } + + RL(rump_sys_sendto(s, data, frag, 0, + (struct sockaddr *)&dst, sizeof(dst))); + } + if (waitpid(-1, &status, WNOHANG) > 0) { + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) + break; + atf_tc_fail("child did not exit clean"); + } + + usleep(10000); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, simpleping); + ATF_TP_ADD_TC(tp, floodping); + ATF_TP_ADD_TC(tp, floodping2); + ATF_TP_ADD_TC(tp, pingsize); + ATF_TP_ADD_TC(tp, ping_of_death); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/icmp/t_ping2.sh b/contrib/netbsd-tests/net/icmp/t_ping2.sh new file mode 100755 index 0000000..fc75196 --- /dev/null +++ b/contrib/netbsd-tests/net/icmp/t_ping2.sh @@ -0,0 +1,78 @@ +# $NetBSD: t_ping2.sh,v 1.5 2016/08/10 22:17:44 kre Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +netserver=\ +"rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpdev" + +atf_test_case basic cleanup +basic_head() +{ + + atf_set "descr" "Checks that a simple ping works" +} + +docfg () +{ + + sock=${1} + addr=${2} + + atf_check -s exit:0 \ + env RUMP_SERVER=${sock} rump.ifconfig shmif0 create + atf_check -s exit:0 \ + env RUMP_SERVER=${sock} rump.ifconfig shmif0 linkstr bus + atf_check -s exit:0 \ + env RUMP_SERVER=${sock} rump.ifconfig shmif0 inet ${addr} +} + +basic_body() +{ + + atf_check -s exit:0 ${netserver} unix://commsock1 + atf_check -s exit:0 ${netserver} unix://commsock2 + + docfg unix://commsock1 1.2.3.4 + docfg unix://commsock2 1.2.3.5 + + atf_check -s exit:0 -o ignore \ + env RUMP_SERVER=unix://commsock1 rump.ping -n -c 1 1.2.3.5 + atf_check -s exit:0 -o ignore \ + env RUMP_SERVER=unix://commsock2 rump.ping -n -c 1 1.2.3.5 +} + +basic_cleanup() +{ + + env RUMP_SERVER=unix://commsock1 rump.halt + env RUMP_SERVER=unix://commsock2 rump.halt +} + +atf_init_test_cases() +{ + + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/net/if/ifconf.c b/contrib/netbsd-tests/net/if/ifconf.c new file mode 100644 index 0000000..424c5e8 --- /dev/null +++ b/contrib/netbsd-tests/net/if/ifconf.c @@ -0,0 +1,134 @@ +/* $NetBSD: ifconf.c,v 1.1 2014/12/08 04:23:03 ozaki-r Exp $ */ +/* + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__RCSID("$NetBSD: ifconf.c,v 1.1 2014/12/08 04:23:03 ozaki-r Exp $"); +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +static void +help(void) +{ + fprintf(stderr, "usage:\n\t%s total\n\t%s list []\n", + getprogname(), getprogname()); + exit(EXIT_FAILURE); +} + +static int +get_number_of_entries(void) +{ + int fd, r; + struct ifconf ifc; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd == -1) + err(EXIT_FAILURE, "socket"); + + ifc.ifc_len = 0; + ifc.ifc_buf = NULL; + + r = ioctl(fd, SIOCGIFCONF, &ifc); + if (r == -1) + err(EXIT_FAILURE, "ioctl"); + + close(fd); + + return ifc.ifc_len / sizeof(struct ifreq); +} + +static void +show_number_of_entries(void) +{ + printf("%d\n", get_number_of_entries()); +} + +static void +show_interfaces(int nifreqs) +{ + int i, fd, r; + struct ifconf ifc; + struct ifreq *ifreqs; + + if (nifreqs == 0) + nifreqs = get_number_of_entries(); + + if (nifreqs <= 0) + errx(EXIT_FAILURE, "nifreqs=%d", nifreqs); + + ifreqs = malloc(sizeof(struct ifreq) * nifreqs); + if (ifreqs == NULL) + err(EXIT_FAILURE, "malloc(sizeof(ifreq) * %d)", nifreqs); + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd == -1) + err(EXIT_FAILURE, "socket"); + + ifc.ifc_len = sizeof(struct ifreq) * nifreqs; + ifc.ifc_req = ifreqs; + + r = ioctl(fd, SIOCGIFCONF, &ifc); + if (r == -1) + err(EXIT_FAILURE, "ioctl"); + close(fd); + + for (i=0; i < (int)(ifc.ifc_len / sizeof(struct ifreq)); i++) { + printf("%s: af=%hhu socklen=%hhu\n", ifreqs[i].ifr_name, + ifreqs[i].ifr_addr.sa_family, ifreqs[i].ifr_addr.sa_len); + } + + free(ifreqs); +} + +int +main(int argc, char *argv[]) +{ + if (argc < 2) + help(); + + if (strcmp(argv[1], "total") == 0) { + show_number_of_entries(); + } else if (strcmp(argv[1], "list") == 0) { + if (argc == 2) + show_interfaces(0); + else if (argc == 3) + show_interfaces(atoi(argv[2])); + else + help(); + } else + help(); + + return EXIT_SUCCESS; +} diff --git a/contrib/netbsd-tests/net/if/t_compat.c b/contrib/netbsd-tests/net/if/t_compat.c new file mode 100644 index 0000000..9eb84a3 --- /dev/null +++ b/contrib/netbsd-tests/net/if/t_compat.c @@ -0,0 +1,85 @@ +/* $NetBSD: t_compat.c,v 1.4 2016/11/12 15:12:59 kre Exp $ */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "../config/netconfig.c" + +/* + * Test for stack smashing in compat ioctl handling. Adapted as an + * atf test from code provided by Onno van der Linden in PR kern/44054 + */ + +struct oifreq { + char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + union { + struct sockaddr ifru_addr; + struct sockaddr ifru_dstaddr; + struct sockaddr ifru_broadaddr; + short ifru_flags; + int ifru_metric; + int ifru_mtu; + int ifru_dlt; + u_int ifru_value; + void * ifru_data; + struct { + uint32_t b_buflen; + void *b_buf; + } ifru_b; + } ifr_ifru; +}; +#define OOSIOCGIFBRDADDR _IOWR('i', 18, struct oifreq) + +ATF_TC(OOSIOCGIFBRDADDR); +ATF_TC_HEAD(OOSIOCGIFBRDADDR, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks that OOSIOCGIFBRDADDR works " + "(PR kern/44054)"); +} + +ATF_TC_BODY(OOSIOCGIFBRDADDR, tc) +{ + int fd, ifnum; + struct oifreq ifreq; + struct sockaddr_in *sin; + int rv; + + memset(&ifreq,'\0',sizeof ifreq); + + rump_init(); + + /* create an interface and give it netmask 0xffff0000 */ + rv = rump_pub_shmif_create("bus", &ifnum); + if (rv) + atf_tc_fail("failed to create shmif: %s", strerror(rv)); + sprintf(ifreq.ifr_name, "shmif%d", ifnum); + netcfg_rump_if(ifreq.ifr_name, "1.7.64.10", "255.255.0.0"); + + atf_tc_expect_fail("PR kern/51610: rump does not include COMPAT_43"); + + /* query kernel for iface bcast */ + RL(fd = rump_sys_socket(AF_INET, SOCK_DGRAM, 0)); + RL(rump_sys_ioctl(fd, OOSIOCGIFBRDADDR, &ifreq)); + + /* make sure we got what we deserve */ + sin = (struct sockaddr_in *)&ifreq.ifr_broadaddr; + ATF_REQUIRE_EQ(sin->sin_addr.s_addr, htonl(0x0107ffff)); + rump_sys_close(fd); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, OOSIOCGIFBRDADDR); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/if/t_ifconf.sh b/contrib/netbsd-tests/net/if/t_ifconf.sh new file mode 100755 index 0000000..f56e9e3 --- /dev/null +++ b/contrib/netbsd-tests/net/if/t_ifconf.sh @@ -0,0 +1,100 @@ +# $NetBSD: t_ifconf.sh,v 1.3 2016/08/10 22:30:02 kre Exp $ +# +# Copyright (c) 2014 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +RUMP_SERVER1=unix://./r1 + +RUMP_FLAGS=\ +"-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpdev" + +atf_test_case basic cleanup +basic_head() +{ + + atf_set "descr" "basic ifconf (SIOCGIFCONF) test" + atf_set "require.progs" "rump_server" +} + +basic_body() +{ + local ifconf="$(atf_get_srcdir)/ifconf" + + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER1} + + export RUMP_SERVER=${RUMP_SERVER1} + export LD_PRELOAD=/usr/lib/librumphijack.so + + # lo0 (127.0.0.1 and link local) + atf_check -s exit:0 -o match:'^2$' "$ifconf" total + atf_check -s exit:0 -o match:'lo0' "$ifconf" list + + # Add shmif0 (no address) + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 -o match:'^3$' "$ifconf" total + atf_check -s exit:0 -o match:'shmif0' "$ifconf" list + + # Add shmif1 (no address) + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 -o match:'^4$' "$ifconf" total + atf_check -s exit:0 -o match:'shmif1' "$ifconf" list + + # Add an address to shmif0 + atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus + atf_check -s exit:0 rump.ifconfig shmif0 192.168.0.1/24 + atf_check -s exit:0 -o match:'^5$' "$ifconf" total + + # Vary the number of requesting interfaces + atf_check -s exit:0 -o match:1 -x "$ifconf list 1 | wc -l" + atf_check -s exit:0 -o match:2 -x "$ifconf list 2 | wc -l" + atf_check -s exit:0 -o match:3 -x "$ifconf list 3 | wc -l" + atf_check -s exit:0 -o match:4 -x "$ifconf list 4 | wc -l" + atf_check -s exit:0 -o match:5 -x "$ifconf list 5 | wc -l" + atf_check -s exit:0 -o match:5 -x "$ifconf list 6 | wc -l" + + # Check if removing an interface is reflected + atf_check -s exit:0 rump.ifconfig shmif0 destroy + atf_check -s exit:0 -o match:'^3$' "$ifconf" total + atf_check -s exit:0 -o not-match:'shmif0' "$ifconf" list + atf_check -s exit:0 -o match:1 -x "$ifconf list 1 | wc -l" + atf_check -s exit:0 -o match:2 -x "$ifconf list 2 | wc -l" + atf_check -s exit:0 -o match:3 -x "$ifconf list 3 | wc -l" + atf_check -s exit:0 -o match:3 -x "$ifconf list 4 | wc -l" + + unset LD_PRELOAD + unset RUMP_SERVER +} + +basic_cleanup() +{ + + RUMP_SERVER=${RUMP_SERVER1} rump.halt +} + +atf_init_test_cases() +{ + + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/net/if/t_ifconfig.sh b/contrib/netbsd-tests/net/if/t_ifconfig.sh new file mode 100755 index 0000000..21c877c --- /dev/null +++ b/contrib/netbsd-tests/net/if/t_ifconfig.sh @@ -0,0 +1,333 @@ +# $NetBSD: t_ifconfig.sh,v 1.15 2017/01/20 08:35:33 ozaki-r Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +RUMP_SERVER1=unix://./r1 +RUMP_SERVER2=unix://./r2 + +RUMP_FLAGS=\ +"-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_netinet6 -lrumpnet_shmif" +RUMP_FLAGS="${RUMP_FLAGS} -lrumpdev" + +TIMEOUT=3 + +anycast="[Aa][Nn][Yy][Cc][Aa][Ss][Tt]" +deprecated="[Dd][Ee][Pp][Rr][Ee][Cc][Aa][Tt][Ee][Dd]" + +atf_test_case ifconfig_create_destroy cleanup +ifconfig_create_destroy_head() +{ + + atf_set "descr" "tests of ifconfig create and destroy" + atf_set "require.progs" "rump_server" +} + +ifconfig_create_destroy_body() +{ + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER1} + + export RUMP_SERVER=${RUMP_SERVER1} + + # Create and destroy (no address) + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 destroy + + # Create and destroy (with an IPv4 address) + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus + atf_check -s exit:0 rump.ifconfig shmif0 192.168.0.1/24 + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig shmif0 destroy + + # Create and destroy (with an IPv6 address) + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::1 + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig shmif0 destroy + + unset RUMP_SERVER +} + +ifconfig_create_destroy_cleanup() +{ + + RUMP_SERVER=${RUMP_SERVER1} rump.halt +} + +atf_test_case ifconfig_options cleanup +ifconfig_options_head() +{ + + atf_set "descr" "tests of ifconfig options" + atf_set "require.progs" "rump_server" +} + +ifconfig_options_body() +{ + + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 rump_server $RUMP_FLAGS $RUMP_SERVER1 + + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 create + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 linkstr bus1 + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet 10.0.0.1/24 + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 fc00::1/64 + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + $DEBUG && rump.ifconfig shmif0 + + # ifconfig [-N] interface address_family + # -N resolves hostnames + atf_check -s exit:0 -o match:'inet 127.0.0.1' rump.ifconfig lo0 inet + atf_check -s exit:0 -o match:'inet localhost' rump.ifconfig -N lo0 inet + atf_check -s exit:0 -o match:'inet6 ::1' rump.ifconfig lo0 inet6 + atf_check -s exit:0 -o match:'inet6 localhost' rump.ifconfig -N lo0 inet6 + atf_check -s not-exit:0 -e match:'not supported' rump.ifconfig lo0 atalk + atf_check -s not-exit:0 -e match:'not supported' rump.ifconfig -N lo0 atalk + atf_check -s exit:0 -o ignore rump.ifconfig lo0 link + atf_check -s exit:0 -o ignore rump.ifconfig -N lo0 link + + # ifconfig [-hLmNvz] interface + # -h -v shows statistics in human readable format + atf_check -s exit:0 -o ignore rump.ifconfig -h -v lo0 + # -L shows IPv6 lifetime + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 fc00::2 \ + pltime 100 + $DEBUG && rump.ifconfig -L shmif0 + atf_check -s exit:0 -o match:'pltime' rump.ifconfig -L shmif0 + atf_check -s exit:0 -o match:'vltime' rump.ifconfig -L shmif0 + # -m shows all of the supported media (not supported in shmif) + $DEBUG && rump.ifconfig -m shmif0 + atf_check -s exit:0 -o ignore rump.ifconfig -m shmif0 + atf_check -s exit:0 -o match:'localhost' rump.ifconfig -N lo0 + atf_check -s exit:0 -o match:'0 packets' rump.ifconfig -v lo0 + atf_check -s exit:0 -o ignore rump.ping -c 1 -w $TIMEOUT localhost + # -z clears and shows statistics at that point + atf_check -s exit:0 -o match:'2 packets' rump.ifconfig -z lo0 + atf_check -s exit:0 -o match:'0 packets' rump.ifconfig -v lo0 + + # ifconfig -a [-bdhLNmsuvz] + # -a shows all interfaces in the system + $DEBUG && rump.ifconfig -a + atf_check -s exit:0 -o match:'shmif0' -o match:'lo0' rump.ifconfig -a + # -a -b shows only broadcast interfaces + atf_check -s exit:0 -o match:'shmif0' -o not-match:'lo0' rump.ifconfig -a -b + # -a -d shows only down interfaces + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 down + atf_check -s exit:0 -o match:'shmif0' rump.ifconfig -a -d + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + atf_check -s exit:0 -o not-match:'shmif0' rump.ifconfig -a -d + atf_check -s exit:0 -o match:'pltime' rump.ifconfig -a -L + atf_check -s exit:0 -o match:'vltime' rump.ifconfig -a -L + atf_check -s exit:0 -o match:'localhost' rump.ifconfig -a -N + atf_check -s exit:0 -o ignore rump.ifconfig -a -m + # -a -s shows only interfaces connected to a network + # (shmif is always connected) + $DEBUG && rump.ifconfig -a -s + atf_check -s exit:0 -o ignore rump.ifconfig -a -s + # -a -u shows only up interfaces + atf_check -s exit:0 -o match:'shmif0' rump.ifconfig -a -u + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 down + atf_check -s exit:0 -o not-match:'shmif0' rump.ifconfig -a -u + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + atf_check -s exit:0 -o match:'0 packets' rump.ifconfig -a -v + atf_check -s exit:0 -o ignore rump.ping -c 1 -w $TIMEOUT localhost + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 down + atf_check -s exit:0 -o match:'2 packets' rump.ifconfig -a -z + atf_check -s exit:0 -o not-match:'2 packets' rump.ifconfig -a -v + atf_check -s exit:0 -o match:'0 packets' rump.ifconfig -a -v + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + + # ifconfig -l [-bdsu] + # -l shows only inteface names + atf_check -s exit:0 -o match:'lo0' rump.ifconfig -l + atf_check -s exit:0 -o match:'shmif0' rump.ifconfig -l + atf_check -s exit:0 -o match:'shmif0' rump.ifconfig -l -b + atf_check -s exit:0 -o not-match:'lo0' rump.ifconfig -l -b + atf_check -s exit:0 -o ignore rump.ifconfig -l -d + atf_check -s exit:0 -o match:'lo0' rump.ifconfig -l -s + atf_check -s exit:0 -o match:'shmif0' rump.ifconfig -l -s + atf_check -s exit:0 -o match:'lo0' rump.ifconfig -l -u + atf_check -s exit:0 -o match:'shmif0' rump.ifconfig -l -u + + # ifconfig -s interface + # -s interface exists with 0 / 1 if connected / disconnected + atf_check -s exit:0 -o empty rump.ifconfig -s lo0 + atf_check -s exit:0 -o empty rump.ifconfig -s shmif0 + + # ifconfig -C + # -C shows all of the interface cloners available on the system + atf_check -s exit:0 -o match:'shmif carp lo' rump.ifconfig -C + + unset RUMP_SERVER +} + +ifconfig_options_cleanup() +{ + + env RUMP_SERVER=${RUMP_SERVER1} rump.halt +} + + +atf_test_case ifconfig_parameters cleanup +ifconfig_parameters_head() +{ + atf_set "descr" "tests of interface parameters" + atf_set "require.progs" "rump_server" +} + +ifconfig_parameters_body() +{ + local interval= + + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER1} + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER2} + + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus + atf_check -s exit:0 rump.ifconfig shmif0 192.168.0.1/24 + atf_check -s exit:0 rump.ifconfig shmif0 up + unset RUMP_SERVER + + export RUMP_SERVER=${RUMP_SERVER2} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus + atf_check -s exit:0 rump.ifconfig shmif0 192.168.0.2/24 + atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.0.3/24 alias + atf_check -s exit:0 rump.ifconfig shmif0 up + unset RUMP_SERVER + + export RUMP_SERVER=${RUMP_SERVER1} + + # active + atf_check -s exit:0 rump.ifconfig shmif0 link b2:a0:75:00:00:01 active + atf_check -s exit:0 -o match:'address:.b2:a0:75:00:00:01' \ + rump.ifconfig shmif0 + # down, up + atf_check -s exit:0 rump.ifconfig shmif0 down + atf_check -s not-exit:0 -o ignore -e ignore rump.ping -c 1 \ + -w $TIMEOUT -n 192.168.0.2 + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + atf_check -s exit:0 -o ignore rump.ping -c 1 -w $TIMEOUT -n 192.168.0.2 + + # alias + atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.1.1/24 alias + atf_check -s exit:0 -o match:'192.168.1.1/24' rump.ifconfig shmif0 + atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.1.1/24 -alias + atf_check -s exit:0 -o not-match:'192.168.1.1/24' rump.ifconfig shmif0 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::1 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::2 + atf_check -s exit:0 -o match:'fc00::1' rump.ifconfig shmif0 inet6 + atf_check -s exit:0 -o match:'fc00::2' rump.ifconfig shmif0 inet6 + + # delete + atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.1.1 alias + atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.1.1 delete + atf_check -s exit:0 -o not-match:'192.168.1.1' rump.ifconfig shmif0 inet + atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.0.1 delete + atf_check -s exit:0 -o not-match:'192.168.0.1' rump.ifconfig shmif0 inet + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::1 delete + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::2 delete + atf_check -s exit:0 -o not-match:'fc00::1' rump.ifconfig shmif0 inet6 + atf_check -s exit:0 -o not-match:'fc00::2' rump.ifconfig shmif0 inet6 + # can delete inactive link + atf_check -s exit:0 rump.ifconfig shmif0 link b2:a0:75:00:00:02 + atf_check -s exit:0 rump.ifconfig shmif0 link b2:a0:75:00:00:02 delete + # cannot delete active link + atf_check -s not-exit:0 -e match:'SIOCDLIFADDR: Device busy' \ + rump.ifconfig shmif0 link b2:a0:75:00:00:01 delete + + atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.0.1/24 + + # arp + atf_check -s exit:0 rump.ifconfig shmif0 -arp + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping -c 1 -w $TIMEOUT -n 192.168.0.3 + atf_check -s exit:0 -o not-match:'192.168.0.3' rump.arp -an + # The entry shouldn't appear in the routing table anymore + atf_check -s exit:0 -o not-match:'192.168.0.3' rump.netstat -nr + + # netmask + atf_check -s exit:0 rump.ifconfig shmif0 inet 172.16.0.1 netmask 255.255.255.0 alias + atf_check -s exit:0 -o match:'172.16.0/24' rump.netstat -rn -f inet + atf_check -s exit:0 rump.ifconfig shmif0 inet 172.16.0.1 delete + + # broadcast (does it not work?) + atf_check -s exit:0 rump.ifconfig shmif0 inet 172.16.0.1 \ + broadcast 255.255.255.255 alias + atf_check -s exit:0 -o match:'broadcast 255.255.255.255' \ + rump.ifconfig shmif0 inet + + # metric (external only) + atf_check -s exit:0 rump.ifconfig shmif0 metric 10 + atf_check -s exit:0 rump.ifconfig shmif0 metric 0 + + # prefixlen + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::1 prefixlen 70 + atf_check -s exit:0 -o match:'fc00::/70' rump.netstat -rn -f inet6 + + # anycast + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::2 anycast + atf_check -s exit:0 -o match:"fc00::2.+$anycast" rump.ifconfig shmif0 inet6 + + # deprecated + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::3 deprecated + # Not deprecated immediately. Need to wait nd6_timer that does it is scheduled. + interval=$(sysctl -n net.inet6.icmp6.nd6_prune) + atf_check -s exit:0 sleep $((interval + 1)) + atf_check -s exit:0 -o match:"fc00::3.+$deprecated" rump.ifconfig shmif0 inet6 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::3 -deprecated + atf_check -s exit:0 -o not-match:"fc00::3.+$deprecated" rump.ifconfig shmif0 inet6 + + # pltime + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::3 pltime 3 + atf_check -s exit:0 -o not-match:"fc00::3.+$deprecated" rump.ifconfig shmif0 inet6 + atf_check -s exit:0 sleep 5 + atf_check -s exit:0 -o match:"fc00::3.+$deprecated" rump.ifconfig shmif0 inet6 + + # eui64 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00:1::0 eui64 + atf_check -s exit:0 -o match:'fc00:1::' rump.ifconfig shmif0 inet6 + + unset RUMP_SERVER +} + +ifconfig_parameters_cleanup() +{ + env RUMP_SERVER=${RUMP_SERVER1} rump.halt + env RUMP_SERVER=${RUMP_SERVER2} rump.halt +} + +atf_init_test_cases() +{ + + atf_add_test_case ifconfig_create_destroy + atf_add_test_case ifconfig_options + atf_add_test_case ifconfig_parameters +} diff --git a/contrib/netbsd-tests/net/if_bridge/t_bridge.sh b/contrib/netbsd-tests/net/if_bridge/t_bridge.sh new file mode 100755 index 0000000..25edb35 --- /dev/null +++ b/contrib/netbsd-tests/net/if_bridge/t_bridge.sh @@ -0,0 +1,573 @@ +# $NetBSD: t_bridge.sh,v 1.16 2016/11/25 08:51:16 ozaki-r Exp $ +# +# Copyright (c) 2014 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCK1=unix://commsock1 +SOCK2=unix://commsock2 +SOCK3=unix://commsock3 +IP1=10.0.0.1 +IP2=10.0.0.2 +IP61=fc00::1 +IP62=fc00::2 +IPBR1=10.0.0.11 +IPBR2=10.0.0.12 +IP6BR1=fc00::11 +IP6BR2=fc00::12 + +DEBUG=${DEBUG:-false} +TIMEOUT=5 + +atf_test_case bridge_ipv4 cleanup +atf_test_case bridge_ipv6 cleanup +atf_test_case bridge_rtable cleanup +atf_test_case bridge_member_ipv4 cleanup +atf_test_case bridge_member_ipv6 cleanup + +bridge_ipv4_head() +{ + atf_set "descr" "Does simple if_bridge tests" + atf_set "require.progs" "rump_server" +} + +bridge_ipv6_head() +{ + atf_set "descr" "Does simple if_bridge tests (IPv6)" + atf_set "require.progs" "rump_server" +} + +bridge_rtable_head() +{ + atf_set "descr" "Tests route table operations of if_bridge" + atf_set "require.progs" "rump_server" +} + +bridge_member_ipv4_head() +{ + atf_set "descr" "Tests if_bridge with members with an IP address" + atf_set "require.progs" "rump_server" +} + +bridge_member_ipv6_head() +{ + atf_set "descr" "Tests if_bridge with members with an IP address (IPv6)" + atf_set "require.progs" "rump_server" +} + +setup_endpoint() +{ + sock=${1} + addr=${2} + bus=${3} + mode=${4} + + rump_server_add_iface $sock shmif0 $bus + export RUMP_SERVER=${sock} + if [ $mode = "ipv6" ]; then + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${addr} + else + atf_check -s exit:0 rump.ifconfig shmif0 inet ${addr} netmask 0xffffff00 + fi + + atf_check -s exit:0 rump.ifconfig shmif0 up + $DEBUG && rump.ifconfig shmif0 +} + +test_endpoint() +{ + sock=${1} + addr=${2} + bus=${3} + mode=${4} + + export RUMP_SERVER=${sock} + atf_check -s exit:0 -o match:shmif0 rump.ifconfig + if [ $mode = "ipv6" ]; then + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${addr} + else + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 ${addr} + fi +} + +test_setup() +{ + test_endpoint $SOCK1 $IP1 bus1 ipv4 + test_endpoint $SOCK3 $IP2 bus2 ipv4 + + export RUMP_SERVER=$SOCK2 + atf_check -s exit:0 -o match:shmif0 rump.ifconfig + atf_check -s exit:0 -o match:shmif1 rump.ifconfig +} + +test_setup6() +{ + test_endpoint $SOCK1 $IP61 bus1 ipv6 + test_endpoint $SOCK3 $IP62 bus2 ipv6 + + export RUMP_SERVER=$SOCK2 + atf_check -s exit:0 -o match:shmif0 rump.ifconfig + atf_check -s exit:0 -o match:shmif1 rump.ifconfig +} + +setup_bridge_server() +{ + + rump_server_add_iface $SOCK2 shmif0 bus1 + rump_server_add_iface $SOCK2 shmif1 bus2 + export RUMP_SERVER=$SOCK2 + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig shmif1 up +} + +setup() +{ + + rump_server_start $SOCK1 bridge + rump_server_start $SOCK2 bridge + rump_server_start $SOCK3 bridge + + setup_endpoint $SOCK1 $IP1 bus1 ipv4 + setup_endpoint $SOCK3 $IP2 bus2 ipv4 + setup_bridge_server +} + +setup6() +{ + + rump_server_start $SOCK1 netinet6 bridge + rump_server_start $SOCK2 netinet6 bridge + rump_server_start $SOCK3 netinet6 bridge + + setup_endpoint $SOCK1 $IP61 bus1 ipv6 + setup_endpoint $SOCK3 $IP62 bus2 ipv6 + setup_bridge_server +} + +setup_bridge() +{ + export RUMP_SERVER=$SOCK2 + atf_check -s exit:0 rump.ifconfig bridge0 create + atf_check -s exit:0 rump.ifconfig bridge0 up + + export LD_PRELOAD=/usr/lib/librumphijack.so + atf_check -s exit:0 /sbin/brconfig bridge0 add shmif0 + atf_check -s exit:0 /sbin/brconfig bridge0 add shmif1 + /sbin/brconfig bridge0 + unset LD_PRELOAD + rump.ifconfig shmif0 + rump.ifconfig shmif1 +} + +setup_member_ip() +{ + export RUMP_SERVER=$SOCK2 + export LD_PRELOAD=/usr/lib/librumphijack.so + atf_check -s exit:0 rump.ifconfig shmif0 $IPBR1/24 + atf_check -s exit:0 rump.ifconfig shmif1 $IPBR2/24 + atf_check -s exit:0 rump.ifconfig -w 10 + /sbin/brconfig bridge0 + unset LD_PRELOAD + rump.ifconfig shmif0 + rump.ifconfig shmif1 +} + +setup_member_ip6() +{ + export RUMP_SERVER=$SOCK2 + export LD_PRELOAD=/usr/lib/librumphijack.so + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6BR1 + atf_check -s exit:0 rump.ifconfig shmif1 inet6 $IP6BR2 + atf_check -s exit:0 rump.ifconfig -w 10 + /sbin/brconfig bridge0 + unset LD_PRELOAD + rump.ifconfig shmif0 + rump.ifconfig shmif1 +} + +teardown_bridge() +{ + export RUMP_SERVER=$SOCK2 + export LD_PRELOAD=/usr/lib/librumphijack.so + /sbin/brconfig bridge0 + atf_check -s exit:0 /sbin/brconfig bridge0 delete shmif0 + atf_check -s exit:0 /sbin/brconfig bridge0 delete shmif1 + /sbin/brconfig bridge0 + unset LD_PRELOAD + rump.ifconfig shmif0 + rump.ifconfig shmif1 +} + +test_setup_bridge() +{ + export RUMP_SERVER=$SOCK2 + export LD_PRELOAD=/usr/lib/librumphijack.so + atf_check -s exit:0 -o match:shmif0 /sbin/brconfig bridge0 + atf_check -s exit:0 -o match:shmif1 /sbin/brconfig bridge0 + /sbin/brconfig bridge0 + unset LD_PRELOAD +} + +down_up_interfaces() +{ + export RUMP_SERVER=$SOCK1 + rump.ifconfig shmif0 down + rump.ifconfig shmif0 up + export RUMP_SERVER=$SOCK3 + rump.ifconfig shmif0 down + rump.ifconfig shmif0 up +} + +test_ping_failure() +{ + export RUMP_SERVER=$SOCK1 + atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP2 + export RUMP_SERVER=$SOCK3 + atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP1 +} + +test_ping_success() +{ + export RUMP_SERVER=$SOCK1 + rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP2 + rump.ifconfig -v shmif0 + + export RUMP_SERVER=$SOCK3 + rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP1 + rump.ifconfig -v shmif0 +} + +test_ping6_failure() +{ + export RUMP_SERVER=$SOCK1 + atf_check -s not-exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP62 + export RUMP_SERVER=$SOCK3 + atf_check -s not-exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP61 +} + +test_ping6_success() +{ + export RUMP_SERVER=$SOCK1 + rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP62 + rump.ifconfig -v shmif0 + + export RUMP_SERVER=$SOCK3 + rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP61 + rump.ifconfig -v shmif0 +} + +test_ping_member() +{ + export RUMP_SERVER=$SOCK1 + rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR1 + rump.ifconfig -v shmif0 + # Test for PR#48104 + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR2 + rump.ifconfig -v shmif0 + + export RUMP_SERVER=$SOCK3 + rump.ifconfig -v shmif0 + # Test for PR#48104 + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR1 + rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR2 + rump.ifconfig -v shmif0 +} + +test_ping6_member() +{ + export RUMP_SERVER=$SOCK1 + rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR1 + rump.ifconfig -v shmif0 + # Test for PR#48104 + atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR2 + rump.ifconfig -v shmif0 + + export RUMP_SERVER=$SOCK3 + rump.ifconfig -v shmif0 + # Test for PR#48104 + atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR1 + rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR2 + rump.ifconfig -v shmif0 +} + +get_number_of_caches() +{ + export RUMP_SERVER=$SOCK2 + export LD_PRELOAD=/usr/lib/librumphijack.so + echo $(($(/sbin/brconfig bridge0 |grep -A 100 "Address cache" |wc -l) - 1)) + unset LD_PRELOAD +} + +test_brconfig_maxaddr() +{ + addr1= addr3= n= + + # Get MAC addresses of the endpoints. + addr1=$(get_macaddr $SOCK1 shmif0) + addr3=$(get_macaddr $SOCK3 shmif0) + + # Refill the MAC addresses of the endpoints. + export RUMP_SERVER=$SOCK1 + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP2 + export RUMP_SERVER=$SOCK2 + export LD_PRELOAD=/usr/lib/librumphijack.so + /sbin/brconfig bridge0 + atf_check -s exit:0 -o match:"$addr1 shmif0" /sbin/brconfig bridge0 + atf_check -s exit:0 -o match:"$addr3 shmif1" /sbin/brconfig bridge0 + + # Check the default # of caches is 100 + atf_check -s exit:0 -o match:"max cache: 100" /sbin/brconfig bridge0 + + # Test two MAC addresses are cached + n=$(get_number_of_caches) + atf_check_equal $n 2 + + # Limit # of caches to one + atf_check -s exit:0 -o ignore /sbin/brconfig bridge0 maxaddr 1 + atf_check -s exit:0 -o match:"max cache: 1" /sbin/brconfig bridge0 + /sbin/brconfig bridge0 + + # Test just one address is cached + n=$(get_number_of_caches) + atf_check_equal $n 1 + + # Increase # of caches to two + atf_check -s exit:0 -o ignore /sbin/brconfig bridge0 maxaddr 2 + atf_check -s exit:0 -o match:"max cache: 2" /sbin/brconfig bridge0 + unset LD_PRELOAD + + # Test we can cache two addresses again + export RUMP_SERVER=$SOCK1 + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP2 + export RUMP_SERVER=$SOCK2 + export LD_PRELOAD=/usr/lib/librumphijack.so + /sbin/brconfig bridge0 + atf_check -s exit:0 -o match:"$addr1 shmif0" /sbin/brconfig bridge0 + atf_check -s exit:0 -o match:"$addr3 shmif1" /sbin/brconfig bridge0 + unset LD_PRELOAD +} + +bridge_ipv4_body() +{ + setup + test_setup + + # Enable once PR kern/49219 is fixed + #test_ping_failure + + setup_bridge + sleep 1 + test_setup_bridge + test_ping_success + + teardown_bridge + test_ping_failure + + rump_server_destroy_ifaces +} + +bridge_ipv6_body() +{ + setup6 + test_setup6 + + test_ping6_failure + + setup_bridge + sleep 1 + test_setup_bridge + test_ping6_success + + teardown_bridge + test_ping6_failure + + rump_server_destroy_ifaces +} + +bridge_rtable_body() +{ + addr1= addr3= + + setup + setup_bridge + + # Get MAC addresses of the endpoints. + addr1=$(get_macaddr $SOCK1 shmif0) + addr3=$(get_macaddr $SOCK3 shmif0) + + # Confirm there is no MAC address caches. + export RUMP_SERVER=$SOCK2 + export LD_PRELOAD=/usr/lib/librumphijack.so + $DEBUG && /sbin/brconfig bridge0 + atf_check -s exit:0 -o not-match:"$addr1" /sbin/brconfig bridge0 + atf_check -s exit:0 -o not-match:"$addr3" /sbin/brconfig bridge0 + unset LD_PRELOAD + + # Make the bridge learn the MAC addresses of the endpoints. + export RUMP_SERVER=$SOCK1 + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP2 + unset RUMP_SERVER + + # Tests the addresses are in the cache. + export RUMP_SERVER=$SOCK2 + export LD_PRELOAD=/usr/lib/librumphijack.so + $DEBUG && /sbin/brconfig bridge0 + atf_check -s exit:0 -o match:"$addr1 shmif0" /sbin/brconfig bridge0 + atf_check -s exit:0 -o match:"$addr3 shmif1" /sbin/brconfig bridge0 + + # Tests brconfig deladdr + atf_check -s exit:0 -o ignore /sbin/brconfig bridge0 deladdr "$addr1" + atf_check -s exit:0 -o not-match:"$addr1 shmif0" /sbin/brconfig bridge0 + atf_check -s exit:0 -o ignore /sbin/brconfig bridge0 deladdr "$addr3" + atf_check -s exit:0 -o not-match:"$addr3 shmif1" /sbin/brconfig bridge0 + unset LD_PRELOAD + + # Refill the MAC addresses of the endpoints. + export RUMP_SERVER=$SOCK1 + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP2 + unset RUMP_SERVER + export RUMP_SERVER=$SOCK2 + export LD_PRELOAD=/usr/lib/librumphijack.so + $DEBUG && /sbin/brconfig bridge0 + atf_check -s exit:0 -o match:"$addr1 shmif0" /sbin/brconfig bridge0 + atf_check -s exit:0 -o match:"$addr3 shmif1" /sbin/brconfig bridge0 + + # Tests brconfig flush. + atf_check -s exit:0 -o ignore /sbin/brconfig bridge0 flush + atf_check -s exit:0 -o not-match:"$addr1 shmif0" /sbin/brconfig bridge0 + atf_check -s exit:0 -o not-match:"$addr3 shmif1" /sbin/brconfig bridge0 + unset LD_PRELOAD + + # Tests brconfig timeout. + export RUMP_SERVER=$SOCK2 + export LD_PRELOAD=/usr/lib/librumphijack.so + atf_check -s exit:0 -o match:"timeout: 1200" /sbin/brconfig bridge0 + atf_check -s exit:0 -o ignore /sbin/brconfig bridge0 timeout 10 + atf_check -s exit:0 -o match:"timeout: 10" /sbin/brconfig bridge0 + unset LD_PRELOAD + + # Tests brconfig maxaddr. + test_brconfig_maxaddr + + # TODO: brconfig static/flushall/discover/learn + # TODO: cache expiration; it takes 5 minutes at least and we want to + # wait here so long. Should we have a sysctl to change the period? + + rump_server_destroy_ifaces +} + +bridge_member_ipv4_body() +{ + setup + test_setup + + # Enable once PR kern/49219 is fixed + #test_ping_failure + + setup_bridge + sleep 1 + test_setup_bridge + test_ping_success + + setup_member_ip + test_ping_member + + teardown_bridge + test_ping_failure + + rump_server_destroy_ifaces +} + +bridge_member_ipv6_body() +{ + setup6 + test_setup6 + + test_ping6_failure + + setup_bridge + sleep 1 + test_setup_bridge + test_ping6_success + + setup_member_ip6 + test_ping6_member + + teardown_bridge + test_ping6_failure + + rump_server_destroy_ifaces +} + +bridge_ipv4_cleanup() +{ + + $DEBUG && dump + cleanup +} + +bridge_ipv6_cleanup() +{ + + $DEBUG && dump + cleanup +} + +bridge_rtable_cleanup() +{ + + $DEBUG && dump + cleanup +} + +bridge_member_ipv4_cleanup() +{ + + $DEBUG && dump + cleanup +} + +bridge_member_ipv6_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case bridge_ipv4 + atf_add_test_case bridge_ipv6 + atf_add_test_case bridge_rtable + atf_add_test_case bridge_member_ipv4 + atf_add_test_case bridge_member_ipv6 +} diff --git a/contrib/netbsd-tests/net/if_gif/t_gif.sh b/contrib/netbsd-tests/net/if_gif/t_gif.sh new file mode 100755 index 0000000..8690d78 --- /dev/null +++ b/contrib/netbsd-tests/net/if_gif/t_gif.sh @@ -0,0 +1,763 @@ +# $NetBSD: t_gif.sh,v 1.9 2016/12/21 09:46:39 ozaki-r Exp $ +# +# Copyright (c) 2015 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCK1=unix://commsock1 # for ROUTER1 +SOCK2=unix://commsock2 # for ROUTER2 +ROUTER1_LANIP=192.168.1.1 +ROUTER1_LANNET=192.168.1.0/24 +ROUTER1_WANIP=10.0.0.1 +ROUTER1_GIFIP=172.16.1.1 +ROUTER1_WANIP_DUMMY=10.0.0.11 +ROUTER1_GIFIP_DUMMY=172.16.11.1 +ROUTER1_GIFIP_RECURSIVE1=172.16.101.1 +ROUTER1_GIFIP_RECURSIVE2=172.16.201.1 +ROUTER2_LANIP=192.168.2.1 +ROUTER2_LANNET=192.168.2.0/24 +ROUTER2_WANIP=10.0.0.2 +ROUTER2_GIFIP=172.16.2.1 +ROUTER2_WANIP_DUMMY=10.0.0.12 +ROUTER2_GIFIP_DUMMY=172.16.12.1 +ROUTER2_GIFIP_RECURSIVE1=172.16.102.1 +ROUTER2_GIFIP_RECURSIVE2=172.16.202.1 + +ROUTER1_LANIP6=fc00:1::1 +ROUTER1_LANNET6=fc00:1::/64 +ROUTER1_WANIP6=fc00::1 +ROUTER1_GIFIP6=fc00:3::1 +ROUTER1_WANIP6_DUMMY=fc00::11 +ROUTER1_GIFIP6_DUMMY=fc00:13::1 +ROUTER1_GIFIP6_RECURSIVE1=fc00:103::1 +ROUTER1_GIFIP6_RECURSIVE2=fc00:203::1 +ROUTER2_LANIP6=fc00:2::1 +ROUTER2_LANNET6=fc00:2::/64 +ROUTER2_WANIP6=fc00::2 +ROUTER2_GIFIP6=fc00:4::1 +ROUTER2_WANIP6_DUMMY=fc00::12 +ROUTER2_GIFIP6_DUMMY=fc00:14::1 +ROUTER2_GIFIP6_RECURSIVE1=fc00:104::1 +ROUTER2_GIFIP6_RECURSIVE2=fc00:204::1 + +DEBUG=${DEBUG:-true} +TIMEOUT=5 + +setup_router() +{ + sock=${1} + lan=${2} + lan_mode=${3} + wan=${4} + wan_mode=${5} + + rump_server_add_iface $sock shmif0 bus0 + rump_server_add_iface $sock shmif1 bus1 + + export RUMP_SERVER=${sock} + if [ ${lan_mode} = "ipv6" ]; then + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${lan} + else + atf_check -s exit:0 rump.ifconfig shmif0 inet ${lan} netmask 0xffffff00 + fi + atf_check -s exit:0 rump.ifconfig shmif0 up + rump.ifconfig shmif0 + + if [ ${wan_mode} = "ipv6" ]; then + atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${wan} + else + atf_check -s exit:0 rump.ifconfig shmif1 inet ${wan} netmask 0xff000000 + fi + atf_check -s exit:0 rump.ifconfig shmif1 up + rump.ifconfig shmif1 +} + +test_router() +{ + sock=${1} + lan=${2} + lan_mode=${3} + wan=${4} + wan_mode=${5} + + export RUMP_SERVER=${sock} + atf_check -s exit:0 -o match:shmif0 rump.ifconfig + if [ ${lan_mode} = "ipv6" ]; then + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${lan} + else + atf_check -s exit:0 -o ignore rump.ping -n -c 1 -w $TIMEOUT ${lan} + fi + + atf_check -s exit:0 -o match:shmif1 rump.ifconfig + if [ ${wan_mode} = "ipv6" ]; then + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${wan} + else + atf_check -s exit:0 -o ignore rump.ping -n -c 1 -w $TIMEOUT ${wan} + fi +} + +setup() +{ + inner=${1} + outer=${2} + + rump_server_start $SOCK1 netinet6 gif + rump_server_start $SOCK2 netinet6 gif + + router1_lan="" + router1_lan_mode="" + router2_lan="" + router2_lan_mode="" + if [ ${inner} = "ipv6" ]; then + router1_lan=$ROUTER1_LANIP6 + router1_lan_mode="ipv6" + router2_lan=$ROUTER2_LANIP6 + router2_lan_mode="ipv6" + else + router1_lan=$ROUTER1_LANIP + router1_lan_mode="ipv4" + router2_lan=$ROUTER2_LANIP + router2_lan_mode="ipv4" + fi + + if [ ${outer} = "ipv6" ]; then + setup_router $SOCK1 ${router1_lan} ${router1_lan_mode} \ + $ROUTER1_WANIP6 ipv6 + setup_router $SOCK2 ${router2_lan} ${router2_lan_mode} \ + $ROUTER2_WANIP6 ipv6 + else + setup_router $SOCK1 ${router1_lan} ${router1_lan_mode} \ + $ROUTER1_WANIP ipv4 + setup_router $SOCK2 ${router2_lan} ${router2_lan_mode} \ + $ROUTER2_WANIP ipv4 + fi +} + +test_setup() +{ + inner=${1} + outer=${2} + + router1_lan="" + router1_lan_mode="" + router2_lan="" + router2_lan_mode="" + if [ ${inner} = "ipv6" ]; then + router1_lan=$ROUTER1_LANIP6 + router1_lan_mode="ipv6" + router2_lan=$ROUTER2_LANIP6 + router2_lan_mode="ipv6" + else + router1_lan=$ROUTER1_LANIP + router1_lan_mode="ipv4" + router2_lan=$ROUTER2_LANIP + router2_lan_mode="ipv4" + fi + if [ ${outer} = "ipv6" ]; then + test_router $SOCK1 ${router1_lan} ${router1_lan_mode} \ + $ROUTER1_WANIP6 ipv6 + test_router $SOCK2 ${router2_lan} ${router2_lan_mode} \ + $ROUTER2_WANIP6 ipv6 + else + test_router $SOCK1 ${router1_lan} ${router1_lan_mode} \ + $ROUTER1_WANIP ipv4 + test_router $SOCK2 ${router2_lan} ${router2_lan_mode} \ + $ROUTER2_WANIP ipv4 + fi +} + +setup_if_gif() +{ + sock=${1} + addr=${2} + remote=${3} + inner=${4} + src=${5} + dst=${6} + peernet=${7} + + export RUMP_SERVER=${sock} + atf_check -s exit:0 rump.ifconfig gif0 create + atf_check -s exit:0 rump.ifconfig gif0 tunnel ${src} ${dst} + if [ ${inner} = "ipv6" ]; then + atf_check -s exit:0 rump.ifconfig gif0 inet6 ${addr}/128 ${remote} + atf_check -s exit:0 -o ignore rump.route add -inet6 ${peernet} ${addr} + else + atf_check -s exit:0 rump.ifconfig gif0 inet ${addr}/32 ${remote} + atf_check -s exit:0 -o ignore rump.route add -inet ${peernet} ${addr} + fi + + rump.ifconfig gif0 + rump.route -nL show +} + +setup_tunnel() +{ + inner=${1} + outer=${2} + + addr="" + remote="" + src="" + dst="" + peernet="" + + if [ ${inner} = "ipv6" ]; then + addr=$ROUTER1_GIFIP6 + remote=$ROUTER2_GIFIP6 + peernet=$ROUTER2_LANNET6 + else + addr=$ROUTER1_GIFIP + remote=$ROUTER2_GIFIP + peernet=$ROUTER2_LANNET + fi + if [ ${outer} = "ipv6" ]; then + src=$ROUTER1_WANIP6 + dst=$ROUTER2_WANIP6 + else + src=$ROUTER1_WANIP + dst=$ROUTER2_WANIP + fi + setup_if_gif $SOCK1 ${addr} ${remote} ${inner} \ + ${src} ${dst} ${peernet} + + if [ $inner = "ipv6" ]; then + addr=$ROUTER2_GIFIP6 + remote=$ROUTER1_GIFIP6 + peernet=$ROUTER1_LANNET6 + else + addr=$ROUTER2_GIFIP + remote=$ROUTER1_GIFIP + peernet=$ROUTER1_LANNET + fi + if [ $outer = "ipv6" ]; then + src=$ROUTER2_WANIP6 + dst=$ROUTER1_WANIP6 + else + src=$ROUTER2_WANIP + dst=$ROUTER1_WANIP + fi + setup_if_gif $SOCK2 ${addr} ${remote} ${inner} \ + ${src} ${dst} ${peernet} +} + +test_setup_tunnel() +{ + mode=${1} + + peernet="" + opt="" + if [ ${mode} = "ipv6" ]; then + peernet=$ROUTER2_LANNET6 + opt="-inet6" + else + peernet=$ROUTER2_LANNET + opt="-inet" + fi + export RUMP_SERVER=$SOCK1 + atf_check -s exit:0 -o match:gif0 rump.ifconfig + atf_check -s exit:0 -o match:gif0 rump.route -nL get ${opt} ${peernet} + + if [ ${mode} = "ipv6" ]; then + peernet=$ROUTER1_LANNET6 + opt="-inet6" + else + peernet=$ROUTER1_LANNET + opt="-inet" + fi + export RUMP_SERVER=$SOCK2 + atf_check -s exit:0 -o match:gif0 rump.ifconfig + atf_check -s exit:0 -o match:gif0 rump.route -nL get ${opt} ${peernet} +} + +teardown_tunnel() +{ + export RUMP_SERVER=$SOCK1 + atf_check -s exit:0 rump.ifconfig gif0 deletetunnel + atf_check -s exit:0 rump.ifconfig gif0 destroy + + export RUMP_SERVER=$SOCK2 + atf_check -s exit:0 rump.ifconfig gif0 deletetunnel + atf_check -s exit:0 rump.ifconfig gif0 destroy +} + +setup_dummy_if_gif() +{ + sock=${1} + addr=${2} + remote=${3} + inner=${4} + src=${5} + dst=${6} + + export RUMP_SERVER=${sock} + atf_check -s exit:0 rump.ifconfig gif1 create + atf_check -s exit:0 rump.ifconfig gif1 tunnel ${src} ${dst} + if [ ${inner} = "ipv6" ]; then + atf_check -s exit:0 rump.ifconfig gif1 inet6 ${addr}/128 ${remote} + else + atf_check -s exit:0 rump.ifconfig gif1 inet ${addr}/32 ${remote} + fi + + rump.ifconfig gif1 +} + +setup_dummy_tunnel() +{ + inner=${1} + outer=${2} + + addr="" + remote="" + src="" + dst="" + + if [ ${inner} = "ipv6" ]; then + addr=$ROUTER1_GIFIP6_DUMMY + remote=$ROUTER2_GIFIP6_DUMMY + else + addr=$ROUTER1_GIFIP_DUMMY + remote=$ROUTER2_GIFIP_DUMMY + fi + if [ ${outer} = "ipv6" ]; then + src=$ROUTER1_WANIP6_DUMMY + dst=$ROUTER2_WANIP6_DUMMY + else + src=$ROUTER1_WANIP_DUMMY + dst=$ROUTER2_WANIP_DUMMY + fi + setup_dummy_if_gif $SOCK1 ${addr} ${remote} ${inner} \ + ${src} ${dst} + + if [ $inner = "ipv6" ]; then + addr=$ROUTER2_GIFIP6_DUMMY + remote=$ROUTER1_GIFIP6_DUMMY + else + addr=$ROUTER2_GIFIP_DUMMY + remote=$ROUTER1_GIFIP_DUMMY + fi + if [ $outer = "ipv6" ]; then + src=$ROUTER2_WANIP6_DUMMY + dst=$ROUTER1_WANIP6_DUMMY + else + src=$ROUTER2_WANIP_DUMMY + dst=$ROUTER1_WANIP_DUMMY + fi + setup_dummy_if_gif $SOCK2 ${addr} ${remote} ${inner} \ + ${src} ${dst} +} + +test_setup_dummy_tunnel() +{ + export RUMP_SERVER=$SOCK1 + atf_check -s exit:0 -o match:gif1 rump.ifconfig + + export RUMP_SERVER=$SOCK2 + atf_check -s exit:0 -o match:gif1 rump.ifconfig +} + +teardown_dummy_tunnel() +{ + export RUMP_SERVER=$SOCK1 + atf_check -s exit:0 rump.ifconfig gif1 deletetunnel + atf_check -s exit:0 rump.ifconfig gif1 destroy + + export RUMP_SERVER=$SOCK2 + atf_check -s exit:0 rump.ifconfig gif1 deletetunnel + atf_check -s exit:0 rump.ifconfig gif1 destroy +} + +setup_recursive_if_gif() +{ + sock=${1} + gif=${2} + addr=${3} + remote=${4} + inner=${5} + src=${6} + dst=${7} + + export RUMP_SERVER=${sock} + atf_check -s exit:0 rump.ifconfig ${gif} create + atf_check -s exit:0 rump.ifconfig ${gif} tunnel ${src} ${dst} + if [ ${inner} = "ipv6" ]; then + atf_check -s exit:0 rump.ifconfig ${gif} inet6 ${addr}/128 ${remote} + else + atf_check -s exit:0 rump.ifconfig ${gif} inet ${addr}/32 ${remote} + fi + + rump.ifconfig ${gif} +} + +# test in ROUTER1 only +setup_recursive_tunnels() +{ + mode=${1} + + addr="" + remote="" + src="" + dst="" + + if [ ${mode} = "ipv6" ]; then + addr=$ROUTER1_GIFIP6_RECURSIVE1 + remote=$ROUTER2_GIFIP6_RECURSIVE1 + src=$ROUTER1_GIFIP6 + dst=$ROUTER2_GIFIP6 + else + addr=$ROUTER1_GIFIP_RECURSIVE1 + remote=$ROUTER2_GIFIP_RECURSIVE1 + src=$ROUTER1_GIFIP + dst=$ROUTER2_GIFIP + fi + setup_recursive_if_gif $SOCK1 gif1 ${addr} ${remote} ${mode} \ + ${src} ${dst} + + if [ ${mode} = "ipv6" ]; then + addr=$ROUTER1_GIFIP6_RECURSIVE2 + remote=$ROUTER2_GIFIP6_RECURSIVE2 + src=$ROUTER1_GIFIP6_RECURSIVE1 + dst=$ROUTER2_GIFIP6_RECURSIVE1 + else + addr=$ROUTER1_GIFIP_RECURSIVE2 + remote=$ROUTER2_GIFIP_RECURSIVE2 + src=$ROUTER1_GIFIP_RECURSIVE1 + dst=$ROUTER2_GIFIP_RECURSIVE1 + fi + setup_recursive_if_gif $SOCK1 gif2 ${addr} ${remote} ${mode} \ + ${src} ${dst} +} + +# test in router1 only +test_recursive_check() +{ + mode=$1 + + export RUMP_SERVER=$SOCK1 + if [ ${mode} = "ipv6" ]; then + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping6 -n -X $TIMEOUT -c 1 $ROUTER2_GIFIP6_RECURSIVE2 + else + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping -n -w $TIMEOUT -c 1 $ROUTER2_GIFIP_RECURSIVE2 + fi + + atf_check -o match:'gif0: recursively called too many times' \ + -x "$HIJACKING dmesg" + + $HIJACKING dmesg +} + +teardown_recursive_tunnels() +{ + export RUMP_SERVER=$SOCK1 + atf_check -s exit:0 rump.ifconfig gif1 deletetunnel + atf_check -s exit:0 rump.ifconfig gif1 destroy + atf_check -s exit:0 rump.ifconfig gif2 deletetunnel + atf_check -s exit:0 rump.ifconfig gif2 destroy +} + +test_ping_failure() +{ + mode=$1 + + export RUMP_SERVER=$SOCK1 + if [ ${mode} = "ipv6" ]; then + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping6 -n -X $TIMEOUT -c 1 -S $ROUTER1_LANIP6 \ + $ROUTER2_LANIP6 + else + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER1_LANIP \ + $ROUTER2_LANIP + fi + + export RUMP_SERVER=$SOCK2 + if [ ${mode} = "ipv6" ]; then + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping6 -n -X $TIMEOUT -c 1 -S $ROUTER2_LANIP6 \ + $ROUTER1_LANIP6 + else + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER1_LANIP \ + $ROUTER2_LANIP + fi +} + +test_ping_success() +{ + mode=$1 + + export RUMP_SERVER=$SOCK1 + rump.ifconfig -v gif0 + if [ ${mode} = "ipv6" ]; then + # XXX + # rump.ping6 rarely fails with the message that + # "failed to get receiving hop limit". + # This is a known issue being analyzed. + atf_check -s exit:0 -o ignore \ + rump.ping6 -n -X $TIMEOUT -c 1 -S $ROUTER1_LANIP6 \ + $ROUTER2_LANIP6 + else + atf_check -s exit:0 -o ignore \ + rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER1_LANIP \ + $ROUTER2_LANIP + fi + rump.ifconfig -v gif0 + + export RUMP_SERVER=$SOCK2 + rump.ifconfig -v gif0 + if [ ${mode} = "ipv6" ]; then + atf_check -s exit:0 -o ignore \ + rump.ping6 -n -X $TIMEOUT -c 1 -S $ROUTER2_LANIP6 \ + $ROUTER1_LANIP6 + else + atf_check -s exit:0 -o ignore \ + rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER2_LANIP \ + $ROUTER1_LANIP + fi + rump.ifconfig -v gif0 +} + +test_change_tunnel_duplicate() +{ + mode=$1 + + newsrc="" + newdst="" + if [ ${mode} = "ipv6" ]; then + newsrc=$ROUTER1_WANIP6_DUMMY + newdst=$ROUTER2_WANIP6_DUMMY + else + newsrc=$ROUTER1_WANIP_DUMMY + newdst=$ROUTER2_WANIP_DUMMY + fi + export RUMP_SERVER=$SOCK1 + rump.ifconfig -v gif0 + rump.ifconfig -v gif1 + atf_check -s exit:0 -e match:SIOCSLIFPHYADDR \ + rump.ifconfig gif0 tunnel ${newsrc} ${newdst} + rump.ifconfig -v gif0 + rump.ifconfig -v gif1 + + if [ ${mode} = "ipv6" ]; then + newsrc=$ROUTER2_WANIP6_DUMMY + newdst=$ROUTER1_WANIP6_DUMMY + else + newsrc=$ROUTER2_WANIP_DUMMY + newdst=$ROUTER1_WANIP_DUMMY + fi + export RUMP_SERVER=$SOCK2 + rump.ifconfig -v gif0 + rump.ifconfig -v gif1 + atf_check -s exit:0 -e match:SIOCSLIFPHYADDR \ + rump.ifconfig gif0 tunnel ${newsrc} ${newdst} + rump.ifconfig -v gif0 + rump.ifconfig -v gif1 +} + +test_change_tunnel_success() +{ + mode=$1 + + newsrc="" + newdst="" + if [ ${mode} = "ipv6" ]; then + newsrc=$ROUTER1_WANIP6_DUMMY + newdst=$ROUTER2_WANIP6_DUMMY + else + newsrc=$ROUTER1_WANIP_DUMMY + newdst=$ROUTER2_WANIP_DUMMY + fi + export RUMP_SERVER=$SOCK1 + rump.ifconfig -v gif0 + atf_check -s exit:0 \ + rump.ifconfig gif0 tunnel ${newsrc} ${newdst} + rump.ifconfig -v gif0 + + if [ ${mode} = "ipv6" ]; then + newsrc=$ROUTER2_WANIP6_DUMMY + newdst=$ROUTER1_WANIP6_DUMMY + else + newsrc=$ROUTER2_WANIP_DUMMY + newdst=$ROUTER1_WANIP_DUMMY + fi + export RUMP_SERVER=$SOCK2 + rump.ifconfig -v gif0 + atf_check -s exit:0 \ + rump.ifconfig gif0 tunnel ${newsrc} ${newdst} + rump.ifconfig -v gif0 +} + +basic_setup() +{ + inner=$1 + outer=$2 + + setup ${inner} ${outer} + test_setup ${inner} ${outer} + + # Enable once PR kern/49219 is fixed + #test_ping_failure + + setup_tunnel ${inner} ${outer} + sleep 1 + test_setup_tunnel ${inner} +} + +basic_test() +{ + inner=$1 + outer=$2 # not use + + test_ping_success ${inner} +} + +basic_teardown() +{ + inner=$1 + outer=$2 # not use + + teardown_tunnel + test_ping_failure ${inner} +} + +ioctl_setup() +{ + inner=$1 + outer=$2 + + setup ${inner} ${outer} + test_setup ${inner} ${outer} + + # Enable once PR kern/49219 is fixed + #test_ping_failure + + setup_tunnel ${inner} ${outer} + setup_dummy_tunnel ${inner} ${outer} + sleep 1 + test_setup_tunnel ${inner} +} + +ioctl_test() +{ + inner=$1 + outer=$2 + + test_ping_success ${inner} + + test_change_tunnel_duplicate ${outer} + + teardown_dummy_tunnel + test_change_tunnel_success ${outer} +} + +ioctl_teardown() +{ + inner=$1 + outer=$2 # not use + + teardown_tunnel + test_ping_failure ${inner} +} + +recursive_setup() +{ + inner=$1 + outer=$2 + + setup ${inner} ${outer} + test_setup ${inner} ${outer} + + # Enable once PR kern/49219 is fixed + #test_ping_failure + + setup_tunnel ${inner} ${outer} + setup_recursive_tunnels ${inner} + sleep 1 + test_setup_tunnel ${inner} +} + +recursive_test() +{ + inner=$1 + outer=$2 # not use + + test_recursive_check ${inner} +} + +recursive_teardown() +{ + inner=$1 # not use + outer=$2 # not use + + teardown_recursive_tunnels + teardown_tunnel +} + +add_test() +{ + category=$1 + desc=$2 + inner=$3 + outer=$4 + + name="gif_${category}_${inner}over${outer}" + fulldesc="Does ${inner} over ${outer} if_gif ${desc}" + + atf_test_case ${name} cleanup + eval "${name}_head() { \ + atf_set \"descr\" \"${fulldesc}\"; \ + atf_set \"require.progs\" \"rump_server\"; \ + }; \ + ${name}_body() { \ + ${category}_setup ${inner} ${outer}; \ + ${category}_test ${inner} ${outer}; \ + ${category}_teardown ${inner} ${outer}; \ + rump_server_destroy_ifaces; \ + }; \ + ${name}_cleanup() { \ + $DEBUG && dump; \ + cleanup; \ + }" + atf_add_test_case ${name} +} + +add_test_allproto() +{ + category=$1 + desc=$2 + + add_test ${category} "${desc}" ipv4 ipv4 + add_test ${category} "${desc}" ipv4 ipv6 + add_test ${category} "${desc}" ipv6 ipv4 + add_test ${category} "${desc}" ipv6 ipv6 +} + +atf_init_test_cases() +{ + add_test_allproto basic "basic tests" + add_test_allproto ioctl "ioctl tests" + add_test_allproto recursive "recursive check tests" +} diff --git a/contrib/netbsd-tests/net/if_loop/t_pr.c b/contrib/netbsd-tests/net/if_loop/t_pr.c new file mode 100644 index 0000000..ee4f684 --- /dev/null +++ b/contrib/netbsd-tests/net/if_loop/t_pr.c @@ -0,0 +1,229 @@ +/* $NetBSD: t_pr.c,v 1.8 2017/01/13 21:30:42 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#ifndef lint +__RCSID("$NetBSD: t_pr.c,v 1.8 2017/01/13 21:30:42 christos Exp $"); +#endif /* not lint */ + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "../config/netconfig.c" +#include "h_macros.h" + +/* + * Prepare rump, configure interface and route to cause fragmentation + */ +static void +setup(void) +{ + char ifname[IFNAMSIZ]; + struct { + struct rt_msghdr m_rtm; + struct sockaddr_in m_sin; + } m_rtmsg; +#define rtm m_rtmsg.m_rtm +#define rsin m_rtmsg.m_sin + struct ifreq ifr; + int s; + + rump_init(); + + /* first, config lo0 & route */ + strcpy(ifname, "lo0"); + netcfg_rump_if(ifname, "127.0.0.1", "255.0.0.0"); + netcfg_rump_route("127.0.0.1", "255.0.0.0", "127.0.0.1"); + + if ((s = rump_sys_socket(PF_ROUTE, SOCK_RAW, 0)) == -1) + atf_tc_fail_errno("routing socket"); + + /* + * set MTU for interface so that route MTU doesn't + * get overridden by it. + */ + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, "lo0"); + ifr.ifr_mtu = 1300; + if (rump_sys_ioctl(s, SIOCSIFMTU, &ifr) == -1) + atf_tc_fail_errno("set mtu"); + + /* change route MTU to 100 */ + memset(&m_rtmsg, 0, sizeof(m_rtmsg)); + rtm.rtm_type = RTM_CHANGE; + rtm.rtm_flags = RTF_STATIC; + rtm.rtm_version = RTM_VERSION; + rtm.rtm_seq = 3; + rtm.rtm_inits = RTV_MTU; + rtm.rtm_addrs = RTA_DST; + rtm.rtm_rmx.rmx_mtu = 100; + rtm.rtm_msglen = sizeof(m_rtmsg); + + memset(&rsin, 0, sizeof(rsin)); + rsin.sin_family = AF_INET; + rsin.sin_len = sizeof(rsin); + rsin.sin_addr.s_addr = inet_addr("127.0.0.1"); + + if (rump_sys_write(s, &m_rtmsg, sizeof(m_rtmsg)) != sizeof(m_rtmsg)) + atf_tc_fail_errno("set route mtu"); + rump_sys_close(s); +} + +/* + * Turn on checksums on loopback interfaces + */ +static int +enable_locsums(void) +{ + struct sysctlnode q, ans[256]; + int mib[5], enable; + size_t alen; + unsigned i; + + mib[0] = CTL_NET; + mib[1] = PF_INET; + mib[2] = IPPROTO_IP; + mib[3] = CTL_QUERY; + alen = sizeof(ans); + + memset(&q, 0, sizeof(q)); + q.sysctl_flags = SYSCTL_VERSION; + + if (rump_sys___sysctl(mib, 4, ans, &alen, &q, sizeof(q)) == -1) + return -1; + + for (i = 0; i < __arraycount(ans); i++) + if (strcmp("do_loopback_cksum", ans[i].sysctl_name) == 0) + break; + if (i == __arraycount(ans)) { + errno = ENOENT; + return -1; + } + + mib[3] = ans[i].sysctl_num; + + enable = 1; + if (rump_sys___sysctl(mib, 4, NULL, NULL, &enable, + sizeof(enable)) == -1) + return errno; + + return 0; +} + +ATF_TC(loopmtu); +ATF_TC_HEAD(loopmtu, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "test lo0 fragmentation (PR kern/43664)"); +} + +ATF_TC_BODY(loopmtu, tc) +{ + struct sockaddr_in sin; + char data[2000]; + int s; + + setup(); + + /* open raw socket */ + s = rump_sys_socket(PF_INET, SOCK_RAW, 0); + if (s == -1) + atf_tc_fail_errno("raw socket"); + + /* then, send data */ + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_len = sizeof(sin); + sin.sin_port = htons(12345); + sin.sin_addr.s_addr = inet_addr("127.0.0.1"); + + if (rump_sys_sendto(s, data, sizeof(data), 0, + (struct sockaddr *)&sin, sizeof(sin)) == -1) + atf_tc_fail_errno("sendto failed"); +} + +ATF_TC(loopmtu_csum); +ATF_TC_HEAD(loopmtu_csum, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "test lo0 fragmentation with checksums (PR kern/43664)"); +} + +ATF_TC_BODY(loopmtu_csum, tc) +{ + struct sockaddr_in sin; + char data[2000]; + int s; + + setup(); + + ATF_CHECK(enable_locsums() == 0); + + /* open raw socket */ + s = rump_sys_socket(PF_INET, SOCK_RAW, 0); + if (s == -1) + atf_tc_fail_errno("raw socket"); + + /* then, send data */ + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_len = sizeof(sin); + sin.sin_port = htons(12345); + sin.sin_addr.s_addr = inet_addr("127.0.0.1"); + + if (rump_sys_sendto(s, data, sizeof(data), 0, + (struct sockaddr *)&sin, sizeof(sin)) == -1) + atf_tc_fail_errno("sendto failed"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, loopmtu); + ATF_TP_ADD_TC(tp, loopmtu_csum); + + return atf_no_error(); +} + diff --git a/contrib/netbsd-tests/net/if_pppoe/t_pppoe.sh b/contrib/netbsd-tests/net/if_pppoe/t_pppoe.sh new file mode 100755 index 0000000..8d9d5c2 --- /dev/null +++ b/contrib/netbsd-tests/net/if_pppoe/t_pppoe.sh @@ -0,0 +1,416 @@ +# $NetBSD: t_pppoe.sh,v 1.16 2016/12/14 03:30:30 knakahara Exp $ +# +# Copyright (c) 2016 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +server="rump_server -lrump -lrumpnet -lrumpnet_net -lrumpnet_netinet \ + -lrumpnet_netinet6 -lrumpnet_shmif -lrumpdev \ + -lrumpnet_pppoe" +# pppoectl doesn't work with RUMPHIJACK=sysctl=yes +HIJACKING="env LD_PRELOAD=/usr/lib/librumphijack.so" + +SERVER=unix://commsock1 +CLIENT=unix://commsock2 + +SERVER_IP=10.3.3.1 +CLIENT_IP=10.3.3.3 +SERVER_IP6=fc00::1 +CLIENT_IP6=fc00::3 +AUTHNAME=foobar@baz.com +SECRET=oink +BUS=bus0 +TIMEOUT=3 +WAITTIME=10 +DEBUG=${DEBUG:-false} + +setup() +{ + inet=true + + if [ $# -ne 0 ]; then + eval $@ + fi + + atf_check -s exit:0 ${server} $SERVER + atf_check -s exit:0 ${server} $CLIENT + + export RUMP_SERVER=$SERVER + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr $BUS + atf_check -s exit:0 rump.ifconfig shmif0 up + + atf_check -s exit:0 rump.ifconfig pppoe0 create + $inet && atf_check -s exit:0 rump.ifconfig pppoe0 \ + inet $SERVER_IP $CLIENT_IP down + atf_check -s exit:0 rump.ifconfig pppoe0 link0 + + $DEBUG && rump.ifconfig + $DEBUG && $HIJACKING pppoectl -d pppoe0 + + atf_check -s exit:0 -x "$HIJACKING pppoectl -e shmif0 pppoe0" + unset RUMP_SERVER + + export RUMP_SERVER=$CLIENT + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr $BUS + atf_check -s exit:0 rump.ifconfig shmif0 up + + atf_check -s exit:0 rump.ifconfig pppoe0 create + $inet && atf_check -s exit:0 rump.ifconfig pppoe0 \ + inet 0.0.0.0 0.0.0.1 down + + atf_check -s exit:0 -x "$HIJACKING pppoectl -e shmif0 pppoe0" + unset RUMP_SERVER +} + +cleanup() +{ + env RUMP_SERVER=$SERVER rump.halt + env RUMP_SERVER=$CLIENT rump.halt +} + + +wait_for_session_established() +{ + local dontfail=$1 + local n=$WAITTIME + + for i in $(seq $n); do + $HIJACKING pppoectl -d pppoe0 |grep -q "state = session" + [ $? = 0 ] && return + sleep 1 + done + + if [ "$dontfail" != "dontfail" ]; then + atf_fail "Couldn't connect to the server for $n seconds." + fi +} + +wait_for_disconnected() +{ + local dontfail=$1 + local n=$WAITTIME + + for i in $(seq $n); do + $HIJACKING pppoectl -d pppoe0 | grep -q "state = initial" + [ $? = 0 ] && return + # If PPPoE client is disconnected by PPPoE server and then + # the client kicks callout of pppoe_timeout(), the client + # state is changed to PPPOE_STATE_PADI_SENT while padi retrying. + $HIJACKING pppoectl -d pppoe0 | grep -q "state = PADI sent" + [ $? = 0 ] && return + + sleep 1 + done + + if [ "$dontfail" != "dontfail" ]; then + atf_fail "Couldn't disconnect for $n seconds." + fi +} + +run_test() +{ + local auth=$1 + setup + + # As pppoe client doesn't support rechallenge yet. + local server_optparam="" + if [ $auth = "chap" ]; then + server_optparam="norechallenge" + fi + + export RUMP_SERVER=$SERVER + local setup_serverparam="pppoectl pppoe0 hisauthproto=$auth \ + 'hisauthname=$AUTHNAME' \ + 'hisauthsecret=$SECRET' \ + 'myauthproto=none' \ + $server_optparam" + atf_check -s exit:0 -x "$HIJACKING $setup_serverparam" + atf_check -s exit:0 rump.ifconfig pppoe0 up + unset RUMP_SERVER + + export RUMP_SERVER=$CLIENT + local setup_clientparam="pppoectl pppoe0 myauthproto=$auth \ + 'myauthname=$AUTHNAME' \ + 'myauthsecret=$SECRET' \ + 'hisauthproto=none'" + atf_check -s exit:0 -x "$HIJACKING $setup_clientparam" + atf_check -s exit:0 rump.ifconfig pppoe0 up + $DEBUG && rump.ifconfig + wait_for_session_established + atf_check -s exit:0 -o ignore rump.ping -c 1 -w $TIMEOUT $SERVER_IP + unset RUMP_SERVER + + # test for disconnection from server + export RUMP_SERVER=$SERVER + atf_check -s exit:0 rump.ifconfig pppoe0 down + wait_for_disconnected + export RUMP_SERVER=$CLIENT + wait_for_disconnected + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping -c 1 -w $TIMEOUT $SERVER_IP + atf_check -s exit:0 -o match:'PADI sent' -x "$HIJACKING pppoectl -d pppoe0" + unset RUMP_SERVER + + # test for recoonecting + atf_check -s exit:0 -x "env RUMP_SERVER=$SERVER rump.ifconfig pppoe0 up" + export RUMP_SERVER=$CLIENT + wait_for_session_established + atf_check -s exit:0 -o ignore rump.ping -c 1 -w $TIMEOUT $SERVER_IP + unset RUMP_SERVER + + # test for disconnection from client + export RUMP_SERVER=$CLIENT + atf_check -s exit:0 -x rump.ifconfig pppoe0 down + wait_for_disconnected + export RUMP_SERVER=$SERVER + wait_for_disconnected + $DEBUG && $HIJACKING pppoectl -d pppoe0 + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping -c 1 -w $TIMEOUT $CLIENT_IP + atf_check -s exit:0 -o match:'initial' -x "$HIJACKING pppoectl -d pppoe0" + unset RUMP_SERVER + + # test for reconnecting + export RUMP_SERVER=$CLIENT + atf_check -s exit:0 -x rump.ifconfig pppoe0 up + wait_for_session_established + $DEBUG && rump.ifconfig pppoe0 + $DEBUG && $HIJACKING pppoectl -d pppoe0 + unset RUMP_SERVER + + export RUMP_SERVER=$SERVER + atf_check -s exit:0 rump.ifconfig -w 10 + atf_check -s exit:0 -o ignore rump.ping -c 1 -w $TIMEOUT $CLIENT_IP + atf_check -s exit:0 -o match:'session' -x "$HIJACKING pppoectl -d pppoe0" + $DEBUG && HIJACKING pppoectl -d pppoe0 + unset RUMP_SERVER + + # test for invalid password + export RUMP_SERVER=$CLIENT + atf_check -s exit:0 rump.ifconfig pppoe0 down + wait_for_disconnected + local setup_clientparam="pppoectl pppoe0 myauthproto=$auth \ + 'myauthname=$AUTHNAME' \ + 'myauthsecret=invalidsecret' \ + 'hisauthproto=none'" + atf_check -s exit:0 -x "$HIJACKING $setup_clientparam" + atf_check -s exit:0 rump.ifconfig pppoe0 up + wait_for_session_established dontfail + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping -c 1 -w $TIMEOUT $SERVER_IP + atf_check -s exit:0 -o match:'DETACHED' rump.ifconfig pppoe0 + unset RUMP_SERVER +} + +atf_test_case pppoe_pap cleanup + +pppoe_pap_head() +{ + atf_set "descr" "Does simple pap tests" + atf_set "require.progs" "rump_server pppoectl" +} + +pppoe_pap_body() +{ + run_test pap +} + +pppoe_pap_cleanup() +{ + cleanup +} + +atf_test_case pppoe_chap cleanup + +pppoe_chap_head() +{ + atf_set "descr" "Does simple chap tests" + atf_set "require.progs" "rump_server pppoectl" +} + +pppoe_chap_body() +{ + run_test chap +} + +pppoe_chap_cleanup() +{ + cleanup +} + +run_test6() +{ + local auth=$1 + setup "inet=false" + + # As pppoe client doesn't support rechallenge yet. + local server_optparam="" + if [ $auth = "chap" ]; then + server_optparam="norechallenge" + fi + + export RUMP_SERVER=$SERVER + local setup_serverparam="pppoectl pppoe0 hisauthproto=$auth \ + 'hisauthname=$AUTHNAME' \ + 'hisauthsecret=$SECRET' \ + 'myauthproto=none' \ + $server_optparam" + atf_check -s exit:0 -x "$HIJACKING $setup_serverparam" + atf_check -s exit:0 rump.ifconfig pppoe0 inet6 $SERVER_IP6/64 down + atf_check -s exit:0 rump.ifconfig pppoe0 up + unset RUMP_SERVER + + export RUMP_SERVER=$CLIENT + local setup_clientparam="pppoectl pppoe0 myauthproto=$auth \ + 'myauthname=$AUTHNAME' \ + 'myauthsecret=$SECRET' \ + 'hisauthproto=none'" + atf_check -s exit:0 -x "$HIJACKING $setup_clientparam" + atf_check -s exit:0 rump.ifconfig pppoe0 inet6 $CLIENT_IP6/64 down + atf_check -s exit:0 rump.ifconfig pppoe0 up + $DEBUG && rump.ifconfig + wait_for_session_established + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + export RUMP_SERVER=$SERVER + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + export RUMP_SERVER=$CLIENT + atf_check -s exit:0 -o ignore rump.ping6 -c 1 -X $TIMEOUT $SERVER_IP6 + unset RUMP_SERVER + + # test for disconnection from server + export RUMP_SERVER=$SERVER + session_id=`$HIJACKING pppoectl -d pppoe0 | grep state` + atf_check -s exit:0 rump.ifconfig pppoe0 down + wait_for_disconnected + export RUMP_SERVER=$CLIENT + wait_for_disconnected + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping6 -c 1 -X $TIMEOUT $SERVER_IP6 + atf_check -s exit:0 -o not-match:"$session_id" -x "$HIJACKING pppoectl -d pppoe0" + unset RUMP_SERVER + + # test for recoonecting + export RUMP_SERVER=$SERVER + atf_check -s exit:0 rump.ifconfig pppoe0 up + wait_for_session_established + atf_check -s exit:0 rump.ifconfig -w 10 + $DEBUG && $HIJACKING pppoectl -d pppoe0 + $DEBUG && rump.ifconfig pppoe0 + export RUMP_SERVER=$CLIENT + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + atf_check -s exit:0 -o ignore rump.ping6 -c 1 -X $TIMEOUT $SERVER_IP6 + unset RUMP_SERVER + + # test for disconnection from client + export RUMP_SERVER=$CLIENT + atf_check -s exit:0 rump.ifconfig pppoe0 down + wait_for_disconnected + + export RUMP_SERVER=$SERVER + wait_for_disconnected + $DEBUG && $HIJACKING pppoectl -d pppoe0 + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping6 -c 1 -X $TIMEOUT $CLIENT_IP6 + atf_check -s exit:0 -o match:'initial' -x "$HIJACKING pppoectl -d pppoe0" + unset RUMP_SERVER + + # test for reconnecting + export RUMP_SERVER=$CLIENT + atf_check -s exit:0 rump.ifconfig pppoe0 up + wait_for_session_established + atf_check -s exit:0 rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig pppoe0 + $DEBUG && $HIJACKING pppoectl -d pppoe0 + unset RUMP_SERVER + + export RUMP_SERVER=$SERVER + atf_check -s exit:0 rump.ifconfig -w 10 + atf_check -s exit:0 -o ignore rump.ping6 -c 1 -X $TIMEOUT $CLIENT_IP6 + atf_check -s exit:0 -o match:'session' -x "$HIJACKING pppoectl -d pppoe0" + $DEBUG && HIJACKING pppoectl -d pppoe0 + unset RUMP_SERVER + + # test for invalid password + export RUMP_SERVER=$CLIENT + atf_check -s exit:0 rump.ifconfig pppoe0 down + wait_for_disconnected + local setup_clientparam="pppoectl pppoe0 myauthproto=$auth \ + 'myauthname=$AUTHNAME' \ + 'myauthsecret=invalidsecret' \ + 'hisauthproto=none'" + atf_check -s exit:0 -x "$HIJACKING $setup_clientparam" + atf_check -s exit:0 rump.ifconfig pppoe0 up + wait_for_session_established dontfail + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping6 -c 1 -X $TIMEOUT $SERVER_IP6 + atf_check -s exit:0 -o match:'DETACHED' rump.ifconfig pppoe0 + unset RUMP_SERVER +} + +atf_test_case pppoe6_pap cleanup + +pppoe6_pap_head() +{ + atf_set "descr" "Does simple pap using IPv6 tests" + atf_set "require.progs" "rump_server pppoectl" +} + +pppoe6_pap_body() +{ + run_test6 pap +} + +pppoe6_pap_cleanup() +{ + cleanup +} + +atf_test_case pppoe6_chap cleanup + +pppoe6_chap_head() +{ + atf_set "descr" "Does simple chap using IPv6 tests" + atf_set "require.progs" "rump_server pppoectl" +} + +pppoe6_chap_body() +{ + run_test6 chap +} + +pppoe6_chap_cleanup() +{ + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case pppoe_pap + atf_add_test_case pppoe_chap + atf_add_test_case pppoe6_pap + atf_add_test_case pppoe6_chap +} diff --git a/contrib/netbsd-tests/net/if_tap/t_tap.sh b/contrib/netbsd-tests/net/if_tap/t_tap.sh new file mode 100755 index 0000000..4b1ce25 --- /dev/null +++ b/contrib/netbsd-tests/net/if_tap/t_tap.sh @@ -0,0 +1,198 @@ +# $NetBSD: t_tap.sh,v 1.6 2016/11/25 08:51:16 ozaki-r Exp $ +# +# Copyright (c) 2016 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCK_LOCAL=unix://commsock1 +SOCK_REMOTE=unix://commsock2 +BUS=bus1 +IP4_LOCAL=10.0.0.1 +IP4_TAP=10.0.0.2 +IP4_REMOTE=10.0.0.3 +IP6_LOCAL=fc00::1 +IP6_TAP=fc00::2 +IP6_REMOTE=fc00::3 + +DEBUG=${DEBUG:-false} +TIMEOUT=1 + +atf_test_case tap_create_destroy cleanup +tap_create_destroy_head() +{ + + atf_set "descr" "tests of creation and deletion of tap interface" + atf_set "require.progs" "rump_server" +} + +tap_create_destroy_body() +{ + + rump_server_start $SOCK_LOCAL netinet6 tap + + export RUMP_SERVER=${SOCK_LOCAL} + + # Create and destroy (no address) + atf_check -s exit:0 rump.ifconfig tap0 create + atf_check -s exit:0 rump.ifconfig tap0 destroy + + # Create and destroy (with an IPv4 address) + atf_check -s exit:0 rump.ifconfig tap0 create + atf_check -s exit:0 rump.ifconfig tap0 $IP4_TAP + atf_check -s exit:0 rump.ifconfig tap0 up + atf_check -s exit:0 rump.ifconfig tap0 destroy + + # Create and destroy (with an IPv6 address) + atf_check -s exit:0 rump.ifconfig tap0 create + atf_check -s exit:0 rump.ifconfig tap0 inet6 $IP6_TAP + atf_check -s exit:0 rump.ifconfig tap0 up + atf_check -s exit:0 rump.ifconfig tap0 destroy +} + +tap_create_destroy_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_test_case tap_stand_alone cleanup +tap_create_destroy_head() +{ + + atf_set "descr" "tests of alone tap interface" + atf_set "require.progs" "rump_server" +} + +tap_stand_alone_body() +{ + + rump_server_start $SOCK_LOCAL netinet6 tap + rump_server_start $SOCK_REMOTE netinet6 tap + + rump_server_add_iface $SOCK_LOCAL shmif0 $BUS + rump_server_add_iface $SOCK_REMOTE shmif0 $BUS + + export RUMP_SERVER=${SOCK_LOCAL} + atf_check -s exit:0 rump.ifconfig shmif0 $IP4_LOCAL + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6_LOCAL + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig tap0 create + atf_check -s exit:0 rump.ifconfig tap0 $IP4_TAP + atf_check -s exit:0 rump.ifconfig tap0 inet6 $IP6_TAP + atf_check -s exit:0 rump.ifconfig tap0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + export RUMP_SERVER=${SOCK_REMOTE} + + atf_check -s exit:0 rump.ifconfig shmif0 $IP4_REMOTE + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6_REMOTE + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4_LOCAL + # Cannot reach to an alone tap + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping -n -w $TIMEOUT -c 1 $IP4_TAP + + atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6_LOCAL + # Cannot reach to an alone tap + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping6 -n -X $TIMEOUT -c 1 $IP6_TAP + + rump_server_destroy_ifaces +} + +tap_stand_alone_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_test_case tap_bridged cleanup +tap_bridged_head() +{ + + atf_set "descr" "tests of alone tap interface" + atf_set "require.progs" "rump_server" +} + +tap_bridged_body() +{ + + rump_server_start $SOCK_LOCAL netinet6 tap bridge + rump_server_start $SOCK_REMOTE netinet6 tap + + rump_server_add_iface $SOCK_LOCAL shmif0 $BUS + rump_server_add_iface $SOCK_REMOTE shmif0 $BUS + + export RUMP_SERVER=${SOCK_LOCAL} + + atf_check -s exit:0 rump.ifconfig shmif0 $IP4_LOCAL + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6_LOCAL + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig tap0 create + atf_check -s exit:0 rump.ifconfig tap0 $IP4_TAP + atf_check -s exit:0 rump.ifconfig tap0 inet6 $IP6_TAP + atf_check -s exit:0 rump.ifconfig tap0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + atf_check -s exit:0 rump.ifconfig bridge0 create + atf_check -s exit:0 rump.ifconfig bridge0 up + export LD_PRELOAD=/usr/lib/librumphijack.so + atf_check -s exit:0 brconfig bridge0 add shmif0 + atf_check -s exit:0 brconfig bridge0 add tap0 + unset LD_PRELOAD + + export RUMP_SERVER=${SOCK_REMOTE} + + atf_check -s exit:0 rump.ifconfig shmif0 $IP4_REMOTE + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6_REMOTE + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4_LOCAL + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4_TAP + + atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6_LOCAL + atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6_TAP + + rump_server_destroy_ifaces +} + +tap_bridged_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case tap_create_destroy + atf_add_test_case tap_stand_alone + atf_add_test_case tap_bridged +} diff --git a/contrib/netbsd-tests/net/if_tun/t_tun.sh b/contrib/netbsd-tests/net/if_tun/t_tun.sh new file mode 100755 index 0000000..87df39a --- /dev/null +++ b/contrib/netbsd-tests/net/if_tun/t_tun.sh @@ -0,0 +1,138 @@ +# $NetBSD: t_tun.sh,v 1.4 2016/11/07 05:25:37 ozaki-r Exp $ +# +# Copyright (c) 2016 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +RUMP_FLAGS="-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_netinet6" +RUMP_FLAGS="$RUMP_FLAGS -lrumpnet_shmif -lrumpnet_tun -lrumpdev" + +BUS=bus +SOCK_LOCAL=unix://commsock1 +SOCK_REMOTE=unix://commsock2 +IP_LOCAL=10.0.0.1 +IP_REMOTE=10.0.0.2 + +DEBUG=${DEBUG:-true} + +atf_test_case tun_create_destroy cleanup +tun_create_destroy_head() +{ + + atf_set "descr" "tests of creation and deletion of tun interface" + atf_set "require.progs" "rump_server" +} + +tun_create_destroy_body() +{ + + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${SOCK_LOCAL} + + export RUMP_SERVER=${SOCK_LOCAL} + + atf_check -s exit:0 rump.ifconfig tun0 create + atf_check -s exit:0 rump.ifconfig tun0 up + atf_check -s exit:0 rump.ifconfig tun0 down + atf_check -s exit:0 rump.ifconfig tun0 destroy +} + +tun_create_destroy_cleanup() +{ + + RUMP_SERVER=${SOCK_LOCAL} rump.halt +} + +atf_test_case tun_setup cleanup +tun_setup_head() +{ + + atf_set "descr" "tests of setting up a tunnel" + atf_set "require.progs" "rump_server" +} + +check_route_entry() +{ + local ip=$(echo $1 |sed 's/\./\\./g') + local gw=$2 + local flags=$3 + local iface=$4 + + atf_check -s exit:0 -o match:" $flags " -e ignore -x \ + "rump.netstat -rn -f inet | grep ^'$ip'" + atf_check -s exit:0 -o match:" $gw " -e ignore -x \ + "rump.netstat -rn -f inet | grep ^'$ip'" + atf_check -s exit:0 -o match:" $iface" -e ignore -x \ + "rump.netstat -rn -f inet | grep ^'$ip'" +} + +tun_setup_body() +{ + + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${SOCK_LOCAL} + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${SOCK_REMOTE} + + export RUMP_SERVER=${SOCK_LOCAL} + + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr $BUS + atf_check -s exit:0 rump.ifconfig shmif0 ${IP_LOCAL}/24 up + atf_check -s exit:0 rump.ifconfig -w 10 + + export RUMP_SERVER=${SOCK_REMOTE} + + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr $BUS + atf_check -s exit:0 rump.ifconfig shmif0 ${IP_REMOTE}/24 up + atf_check -s exit:0 rump.ifconfig -w 10 + + export RUMP_SERVER=${SOCK_LOCAL} + atf_check -s exit:0 rump.ifconfig tun0 create + atf_check -s exit:0 rump.ifconfig tun0 ${IP_LOCAL} ${IP_REMOTE} up + atf_check -s exit:0 \ + -o match:"inet ${IP_LOCAL}/32 -> ${IP_REMOTE}" rump.ifconfig tun0 + $DEBUG && rump.netstat -nr -f inet + check_route_entry ${IP_REMOTE} ${IP_LOCAL} UH tun0 + + export RUMP_SERVER=${SOCK_REMOTE} + atf_check -s exit:0 rump.ifconfig tun0 create + atf_check -s exit:0 rump.ifconfig tun0 ${IP_REMOTE} ${IP_LOCAL} up + atf_check -s exit:0 \ + -o match:"inet ${IP_REMOTE}/32 -> ${IP_LOCAL}" rump.ifconfig tun0 + $DEBUG && rump.netstat -nr -f inet + check_route_entry ${IP_LOCAL} ${IP_REMOTE} UH tun0 +} + +tun_setup_cleanup() +{ + + RUMP_SERVER=${SOCK_LOCAL} rump.halt + RUMP_SERVER=${SOCK_REMOTE} rump.halt +} + +atf_init_test_cases() +{ + + atf_add_test_case tun_create_destroy + atf_add_test_case tun_setup +} diff --git a/contrib/netbsd-tests/net/if_vlan/t_vlan.sh b/contrib/netbsd-tests/net/if_vlan/t_vlan.sh new file mode 100755 index 0000000..a6902fb --- /dev/null +++ b/contrib/netbsd-tests/net/if_vlan/t_vlan.sh @@ -0,0 +1,115 @@ +# $NetBSD: t_vlan.sh,v 1.1 2016/11/26 03:19:49 ozaki-r Exp $ +# +# Copyright (c) 2016 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +BUS=bus +SOCK_LOCAL=unix://commsock1 +SOCK_REMOTE=unix://commsock2 +IP_LOCAL=10.0.0.1 +IP_REMOTE=10.0.0.2 + +DEBUG=${DEBUG:-false} + +atf_test_case vlan_create_destroy cleanup +vlan_create_destroy_head() +{ + + atf_set "descr" "tests of creation and deletion of vlan interface" + atf_set "require.progs" "rump_server" +} + +vlan_create_destroy_body() +{ + + rump_server_start $SOCK_LOCAL vlan + + export RUMP_SERVER=${SOCK_LOCAL} + + atf_check -s exit:0 rump.ifconfig vlan0 create + atf_check -s exit:0 rump.ifconfig vlan0 up + atf_check -s exit:0 rump.ifconfig vlan0 down + atf_check -s exit:0 rump.ifconfig vlan0 destroy +} + +vlan_create_destroy_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_test_case vlan_basic cleanup +vlan_basic_head() +{ + + atf_set "descr" "tests of communications over vlan interfaces" + atf_set "require.progs" "rump_server" +} + +vlan_basic_body() +{ + + rump_server_start $SOCK_LOCAL vlan + rump_server_add_iface $SOCK_LOCAL shmif0 $BUS + rump_server_start $SOCK_REMOTE vlan + rump_server_add_iface $SOCK_REMOTE shmif0 $BUS + + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 rump.ifconfig shmif0 up + export RUMP_SERVER=$SOCK_REMOTE + atf_check -s exit:0 rump.ifconfig shmif0 up + + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 rump.ifconfig vlan0 create + atf_check -s exit:0 rump.ifconfig vlan0 vlan 10 vlanif shmif0 + atf_check -s exit:0 rump.ifconfig vlan0 $IP_LOCAL/24 + atf_check -s exit:0 rump.ifconfig vlan0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + export RUMP_SERVER=$SOCK_REMOTE + atf_check -s exit:0 rump.ifconfig vlan0 create + atf_check -s exit:0 rump.ifconfig vlan0 vlan 10 vlanif shmif0 + atf_check -s exit:0 rump.ifconfig vlan0 $IP_REMOTE/24 + atf_check -s exit:0 rump.ifconfig vlan0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP_REMOTE +} + +vlan_basic_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case vlan_create_destroy + atf_add_test_case vlan_basic +} diff --git a/contrib/netbsd-tests/net/in_cksum/assym.h b/contrib/netbsd-tests/net/in_cksum/assym.h new file mode 100644 index 0000000..60aa41f --- /dev/null +++ b/contrib/netbsd-tests/net/in_cksum/assym.h @@ -0,0 +1,10 @@ +/* XXX: Depends on m_hdr */ +#ifdef _LP64 +#define M_NEXT 0 +#define M_DATA 16 +#define M_LEN 32 +#else +#define M_NEXT 0 +#define M_DATA 8 +#define M_LEN 16 +#endif diff --git a/contrib/netbsd-tests/net/in_cksum/in_cksum.c b/contrib/netbsd-tests/net/in_cksum/in_cksum.c new file mode 100644 index 0000000..4bdaf5b --- /dev/null +++ b/contrib/netbsd-tests/net/in_cksum/in_cksum.c @@ -0,0 +1,270 @@ +/* $NetBSD: in_cksum.c,v 1.5 2015/10/18 18:27:25 christos Exp $ */ +/*- + * Copyright (c) 2008 Joerg Sonnenberger . + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +__KERNEL_RCSID(0, "$NetBSD: in_cksum.c,v 1.5 2015/10/18 18:27:25 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define cpu_in_cksum portable_cpu_in_cksum +#include "cpu_in_cksum.c" + +#ifdef HAVE_CPU_IN_CKSUM +#undef cpu_in_cksum +int cpu_in_cksum(struct mbuf*, int, int, uint32_t); +#endif + +static bool random_aligned; + +void panic(const char *, ...) __printflike(1, 2); +void +panic(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrx(1, fmt, ap); + va_end(ap); +} + +static void +free_mbuf_chain(struct mbuf *m) +{ + struct mbuf *next; + + if (m == NULL) + return; + + next = m->m_next; + free(m); + free_mbuf_chain(next); +} + +static struct mbuf * +allocate_mbuf_chain(char **lens) +{ + int len, off; + struct mbuf *m; + + if (*lens == NULL) + return NULL; + + len = atoi(*lens); + off = random_aligned ? rand() % 64 : 0; + + m = malloc(sizeof(struct m_hdr) + len + off); + if (m == NULL) + err(EXIT_FAILURE, "malloc failed"); + + m->m_data = (char *)m + sizeof(struct m_hdr) + off; + m->m_len = len; + + m->m_next = allocate_mbuf_chain(lens + 1); + + return m; +} + +#ifdef MBUFDUMP +static void +dump_mbuf(const struct mbuf *m, int len, int off) +{ + int x = 0; + if (len <= 0) + return; + + printf("Starting len=%d off=%d:\n", len, off); + if (off > 0) { + for (; m; m = m->m_next) + if (off > m->m_len) + off -= m->m_len; + else + break; + if (m == NULL || off > m->m_len) + errx(1, "out of data"); + } + + unsigned char *ptr = mtod(m, unsigned char *) + off; + unsigned char *eptr = ptr + m->m_len; + printf("["); + for (;;) { + if (ptr == eptr) { + m = m->m_next; + if (m == NULL) + errx(1, "out of data"); + ptr = mtod(m, unsigned char *); + eptr = ptr + m->m_len; + printf("]\n["); + x = 0; + } + printf("%.2x ", *ptr++); + if (++x % 16 == 0) + printf("\n"); + if (--len == 0) + break; + } + printf("]\n"); + fflush(stdout); +} +#endif + +static void +randomise_mbuf_chain(struct mbuf *m) +{ + int i, data, len; + + for (i = 0; i < m->m_len; i += sizeof(int)) { + data = rand(); + if (i + sizeof(int) < (size_t)m->m_len) + len = sizeof(int); + else + len = m->m_len - i; + memcpy(m->m_data + i, &data, len); + } + if (m->m_next) + randomise_mbuf_chain(m->m_next); +} + +static int +mbuf_len(struct mbuf *m) +{ + return m == NULL ? 0 : m->m_len + mbuf_len(m->m_next); +} + +int in_cksum_portable(struct mbuf *, int); +int in_cksum(struct mbuf *, int); + +int +main(int argc, char **argv) +{ + struct rusage res; + struct timeval tv, old_tv; + int loops, old_sum, off, len; +#ifdef HAVE_CPU_IN_CKSUM + int new_sum; +#endif + long i, iterations; + uint32_t init_sum; + struct mbuf *m; + bool verbose; + int c; + + loops = 16; + verbose = false; + random_aligned = 0; + iterations = 100000; + + while ((c = getopt(argc, argv, "i:l:u:v")) != -1) { + switch (c) { + case 'i': + iterations = atoi(optarg); + break; + case 'l': + loops = atoi(optarg); + break; + case 'u': + random_aligned = atoi(optarg); + break; + case 'v': + verbose = true; + break; + default: + errx(1, "%s [-l ] [-u [-i " + "[ ...]", getprogname()); + } + } + + for (; loops; --loops) { + if ((m = allocate_mbuf_chain(argv + 4)) == NULL) + continue; + randomise_mbuf_chain(m); + init_sum = rand(); + len = mbuf_len(m); + + /* force one loop over all data */ + if (loops == 1) + off = 0; + else + off = len ? rand() % len : 0; + + len -= off; + old_sum = portable_cpu_in_cksum(m, len, off, init_sum); +#ifdef HAVE_CPU_IN_CKSUM +#ifdef MBUFDUMP + printf("m->m_len=%d len=%d off=%d\n", m->m_len, len, off); + dump_mbuf(m, len, off); +#endif + new_sum = cpu_in_cksum(m, len, off, init_sum); + if (old_sum != new_sum) + errx(1, "comparison failed: %x %x", old_sum, new_sum); +#else + __USE(old_sum); +#endif + + if (iterations == 0) + continue; + + getrusage(RUSAGE_SELF, &res); + tv = res.ru_utime; + for (i = iterations; i; --i) + (void)portable_cpu_in_cksum(m, len, off, init_sum); + getrusage(RUSAGE_SELF, &res); + timersub(&res.ru_utime, &tv, &old_tv); + if (verbose) + printf("portable version: %jd.%06jd\n", + (intmax_t)old_tv.tv_sec, (intmax_t)old_tv.tv_usec); + +#ifdef HAVE_CPU_IN_CKSUM + getrusage(RUSAGE_SELF, &res); + tv = res.ru_utime; + for (i = iterations; i; --i) + (void)cpu_in_cksum(m, len, off, init_sum); + getrusage(RUSAGE_SELF, &res); + timersub(&res.ru_utime, &tv, &tv); + if (verbose) { + printf("test version: %jd.%06jd\n", + (intmax_t)tv.tv_sec, (intmax_t)tv.tv_usec); + printf("relative time: %3.g%%\n", + 100 * ((double)tv.tv_sec * 1e6 + tv.tv_usec) / + ((double)old_tv.tv_sec * 1e6 + old_tv.tv_usec + 1)); + } +#endif + free_mbuf_chain(m); + } + + return 0; +} diff --git a/contrib/netbsd-tests/net/in_cksum/t_in_cksum.sh b/contrib/netbsd-tests/net/in_cksum/t_in_cksum.sh new file mode 100755 index 0000000..a342403 --- /dev/null +++ b/contrib/netbsd-tests/net/in_cksum/t_in_cksum.sh @@ -0,0 +1,78 @@ +#! /usr/bin/atf-sh +# $NetBSD: t_in_cksum.sh,v 1.2 2015/01/06 15:13:16 martin Exp $ +# + +TIMING_LOOPS=10000 +incksum="$(atf_get_srcdir)/in_cksum" + +fail() { + atf_fail "see output for details" +} + +mbufs() { + ${incksum} -l 16 -u $0 -i ${TIMING_LOOPS} \ + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 \ + || fail + ${incksum} -l 16 -u $0 -i ${TIMING_LOOPS} \ + 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \ + 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \ + || fail + ${incksum} -l 64 -u $0 -i ${TIMING_LOOPS} \ + 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \ + 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \ + || fail + ${incksum} -l 16 -u $0 -i ${TIMING_LOOPS} \ + 1 3 1 3 1 3 1 \ + || fail +} + +sizes() { + ${incksum} -l 16 -u $1 -i ${TIMING_LOOPS} 2048 || fail + ${incksum} -l 16 -u $1 -i ${TIMING_LOOPS} 40 || fail + ${incksum} -l 16 -u $1 -i ${TIMING_LOOPS} 1536 || fail + ${incksum} -l 16 -u $1 -i ${TIMING_LOOPS} 576 || fail + ${incksum} -l 16 -u $1 -i ${TIMING_LOOPS} 1536 1536 1536 1536 1536 640 \ + || fail +} + +atf_test_case mbufs_aligned + +mbufs_aligned_head() { + atf_set "descr" "Test in_cksum mbuf chains aligned" +} + +mbufs_aligned_body() { + mbufs 0 +} + +mbufs_unaligned_head() { + atf_set "descr" "Test in_cksum mbuf chains unaligned" +} + +mbufs_unaligned_body() { + mbufs 1 +} + +sizes_aligned_head() { + atf_set "descr" "Test in_cksum sizes aligned" +} + +sizes_aligned_body() { + sizes 0 +} + +sizes_unaligned_head() { + atf_set "descr" "Test in_cksum sizes unaligned" +} + +sizes_unaligned_body() { + sizes 1 +} + +atf_init_test_cases() +{ + atf_add_test_case mbufs_aligned + atf_add_test_case mbufs_unaligned + atf_add_test_case sizes_aligned + atf_add_test_case sizes_unaligned +} diff --git a/contrib/netbsd-tests/net/mcast/mcast.c b/contrib/netbsd-tests/net/mcast/mcast.c new file mode 100644 index 0000000..ad2c9b3 --- /dev/null +++ b/contrib/netbsd-tests/net/mcast/mcast.c @@ -0,0 +1,559 @@ +/* $NetBSD: mcast.c,v 1.3 2015/05/28 10:19:17 ozaki-r Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#ifdef __RCSID +__RCSID("$NetBSD: mcast.c,v 1.3 2015/05/28 10:19:17 ozaki-r Exp $"); +#else +extern const char *__progname; +#define getprogname() __progname +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef ATF +#include + +#define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__) +#define ERRX0(ev, msg) ATF_REQUIRE_MSG(0, msg) + +#define SKIPX(ev, msg, ...) do { \ + atf_tc_skip(msg, __VA_ARGS__); \ + return; \ +} while(/*CONSTCOND*/0) + +#else +#define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) +#define ERRX0(ev, msg) errx(ev, msg) +#define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__) +#endif + +static int debug; + +#define TOTAL 10 +#define PORT_V4MAPPED "6666" +#define HOST_V4MAPPED "::FFFF:239.1.1.1" +#define PORT_V4 "6666" +#define HOST_V4 "239.1.1.1" +#define PORT_V6 "6666" +#define HOST_V6 "FF05:1:0:0:0:0:0:1" + +struct message { + size_t seq; + struct timespec ts; +}; + +static int +addmc(int s, struct addrinfo *ai, bool bug) +{ + struct ip_mreq m4; + struct ipv6_mreq m6; + struct sockaddr_in *s4; + struct sockaddr_in6 *s6; + unsigned int ifc; + + switch (ai->ai_family) { + case AF_INET: + s4 = (void *)ai->ai_addr; + assert(sizeof(*s4) == ai->ai_addrlen); + m4.imr_multiaddr = s4->sin_addr; + m4.imr_interface.s_addr = htonl(INADDR_ANY); + return setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, + &m4, sizeof(m4)); + case AF_INET6: + s6 = (void *)ai->ai_addr; + /* + * Linux: Does not support the v6 ioctls on v4 mapped + * sockets but it does support the v4 ones and + * it works. + * MacOS/X: Supports the v6 ioctls on v4 mapped sockets, + * but does not work and also does not support + * the v4 ioctls. So no way to make multicasting + * work with mapped addresses. + * NetBSD: Supports both and works for both. + */ + if (bug && IN6_IS_ADDR_V4MAPPED(&s6->sin6_addr)) { + memcpy(&m4.imr_multiaddr, &s6->sin6_addr.s6_addr[12], + sizeof(m4.imr_multiaddr)); + m4.imr_interface.s_addr = htonl(INADDR_ANY); + return setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, + &m4, sizeof(m4)); + } + assert(sizeof(*s6) == ai->ai_addrlen); + memset(&m6, 0, sizeof(m6)); +#if 0 + ifc = 1; + if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, + &ifc, sizeof(ifc)) == -1) + return -1; + ifc = 224; + if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, + &ifc, sizeof(ifc)) == -1) + return -1; + ifc = 1; /* XXX should pick a proper interface */ + if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifc, + sizeof(ifc)) == -1) + return -1; +#else + ifc = 0; /* Let pick an appropriate interface */ +#endif + m6.ipv6mr_interface = ifc; + m6.ipv6mr_multiaddr = s6->sin6_addr; + return setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, + &m6, sizeof(m6)); + default: + errno = EOPNOTSUPP; + return -1; + } +} + +static int +allowv4mapped(int s, struct addrinfo *ai) +{ + struct sockaddr_in6 *s6; + int zero = 0; + + if (ai->ai_family != AF_INET6) + return 0; + + s6 = (void *)ai->ai_addr; + + if (!IN6_IS_ADDR_V4MAPPED(&s6->sin6_addr)) + return 0; + return setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)); +} + +static struct sockaddr_storage ss; +static int +connector(int fd, const struct sockaddr *sa, socklen_t slen) +{ + assert(sizeof(ss) > slen); + memcpy(&ss, sa, slen); + return 0; +} + +static void +show(const char *prefix, const struct message *msg) +{ + printf("%10.10s: %zu [%jd.%ld]\n", prefix, msg->seq, (intmax_t) + msg->ts.tv_sec, msg->ts.tv_nsec); +} + +static int +getsocket(const char *host, const char *port, + int (*f)(int, const struct sockaddr *, socklen_t), socklen_t *slen, + bool bug) +{ + int e, s, lasterrno = 0; + struct addrinfo hints, *ai0, *ai; + const char *cause = "?"; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + e = getaddrinfo(host, port, &hints, &ai0); + if (e) + ERRX(EXIT_FAILURE, "Can't resolve %s:%s (%s)", host, port, + gai_strerror(e)); + + s = -1; + for (ai = ai0; ai; ai = ai->ai_next) { + s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (s == -1) { + lasterrno = errno; + cause = "socket"; + continue; + } + if (allowv4mapped(s, ai) == -1) { + cause = "allow v4 mapped"; + goto out; + } + if ((*f)(s, ai->ai_addr, ai->ai_addrlen) == -1) { + cause = f == bind ? "bind" : "connect"; + goto out; + } + if ((f == bind || f == connector) && addmc(s, ai, bug) == -1) { + cause = "join group"; + goto out; + } + *slen = ai->ai_addrlen; + break; +out: + lasterrno = errno; + close(s); + s = -1; + continue; + } + freeaddrinfo(ai0); + if (s == -1) + ERRX(EXIT_FAILURE, "%s (%s)", cause, strerror(lasterrno)); + return s; +} + +static int +synchronize(const int fd, bool waiter) +{ + int syncmsg = 0; + int r; + struct pollfd pfd; + + if (waiter) { + pfd.fd = fd; + pfd.events = POLLIN; + + /* We use poll to avoid lock up when the peer died unexpectedly */ + r = poll(&pfd, 1, 10000); + if (r == -1) + ERRX(EXIT_FAILURE, "poll (%s)", strerror(errno)); + if (r == 0) + /* Timed out */ + return -1; + + if (read(fd, &syncmsg, sizeof(syncmsg)) == -1) + ERRX(EXIT_FAILURE, "read (%s)", strerror(errno)); + } else { + if (write(fd, &syncmsg, sizeof(syncmsg)) == -1) + ERRX(EXIT_FAILURE, "write (%s)", strerror(errno)); + } + + return 0; +} + +static int +sender(const int fd, const char *host, const char *port, size_t n, bool conn, + bool bug) +{ + int s; + ssize_t l; + struct message msg; + + socklen_t slen; + + s = getsocket(host, port, conn ? connect : connector, &slen, bug); + + /* Wait until receiver gets ready. */ + if (synchronize(fd, true) == -1) + return -1; + + for (msg.seq = 0; msg.seq < n; msg.seq++) { +#ifdef CLOCK_MONOTONIC + if (clock_gettime(CLOCK_MONOTONIC, &msg.ts) == -1) + ERRX(EXIT_FAILURE, "clock (%s)", strerror(errno)); +#else + struct timeval tv; + if (gettimeofday(&tv, NULL) == -1) + ERRX(EXIT_FAILURE, "clock (%s)", strerror(errno)); + msg.ts.tv_sec = tv.tv_sec; + msg.ts.tv_nsec = tv.tv_usec * 1000; +#endif + if (debug) + show("sending", &msg); + l = conn ? send(s, &msg, sizeof(msg), 0) : + sendto(s, &msg, sizeof(msg), 0, (void *)&ss, slen); + if (l == -1) + ERRX(EXIT_FAILURE, "send (%s)", strerror(errno)); + usleep(100); + } + + /* Wait until receiver finishes its work. */ + if (synchronize(fd, true) == -1) + return -1; + + return 0; +} + +static void +receiver(const int fd, const char *host, const char *port, size_t n, bool conn, + bool bug) +{ + int s; + ssize_t l; + size_t seq; + struct message msg; + struct pollfd pfd; + socklen_t slen; + + s = getsocket(host, port, bind, &slen, bug); + pfd.fd = s; + pfd.events = POLLIN; + + /* Tell I'm ready */ + synchronize(fd, false); + + for (seq = 0; seq < n; seq++) { + if (poll(&pfd, 1, 10000) == -1) + ERRX(EXIT_FAILURE, "poll (%s)", strerror(errno)); + l = conn ? recv(s, &msg, sizeof(msg), 0) : + recvfrom(s, &msg, sizeof(msg), 0, (void *)&ss, &slen); + if (l == -1) + ERRX(EXIT_FAILURE, "recv (%s)", strerror(errno)); + if (debug) + show("got", &msg); + if (seq != msg.seq) + ERRX(EXIT_FAILURE, "seq: expect=%zu actual=%zu", + seq, msg.seq); + } + + /* Tell I'm finished */ + synchronize(fd, false); +} + +static void +run(const char *host, const char *port, size_t n, bool conn, bool bug) +{ + pid_t pid; + int status; + int syncfds[2]; + int error; + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, syncfds) == -1) + ERRX(EXIT_FAILURE, "socketpair (%s)", strerror(errno)); + + switch ((pid = fork())) { + case 0: + receiver(syncfds[0], host, port, n, conn, bug); + return; + case -1: + ERRX(EXIT_FAILURE, "fork (%s)", strerror(errno)); + default: + error = sender(syncfds[1], host, port, n, conn, bug); + again: + switch (waitpid(pid, &status, WNOHANG)) { + case -1: + ERRX(EXIT_FAILURE, "wait (%s)", strerror(errno)); + case 0: + if (error == 0) + /* + * Receiver is still alive, but we know + * it will exit soon. + */ + goto again; + + if (kill(pid, SIGTERM) == -1) + ERRX(EXIT_FAILURE, "kill (%s)", + strerror(errno)); + goto again; + default: + if (WIFSIGNALED(status)) { + if (WTERMSIG(status) == SIGTERM) + ERRX0(EXIT_FAILURE, + "receiver failed and was killed" \ + "by sender"); + else + ERRX(EXIT_FAILURE, + "receiver got signaled (%s)", + strsignal(WTERMSIG(status))); + } else if (WIFEXITED(status)) { + if (WEXITSTATUS(status) != 0) + ERRX(EXIT_FAILURE, + "receiver exited with status %d", + WEXITSTATUS(status)); + } else { + ERRX(EXIT_FAILURE, + "receiver exited with unexpected status %d", + status); + } + break; + } + return; + } +} + +#ifndef ATF +int +main(int argc, char *argv[]) +{ + const char *host, *port; + int c; + size_t n; + bool conn, bug; + + host = HOST_V4; + port = PORT_V4; + n = TOTAL; + bug = conn = false; + + while ((c = getopt(argc, argv, "46bcdmn:")) != -1) + switch (c) { + case '4': + host = HOST_V4; + port = PORT_V4; + break; + case '6': + host = HOST_V6; + port = PORT_V6; + break; + case 'b': + bug = true; + break; + case 'c': + conn = true; + break; + case 'd': + debug++; + break; + case 'm': + host = HOST_V4MAPPED; + port = PORT_V4MAPPED; + break; + case 'n': + n = atoi(optarg); + break; + default: + fprintf(stderr, "Usage: %s [-cdm46] [-n ]", + getprogname()); + return 1; + } + + run(host, port, n, conn, bug); + return 0; +} +#else + +ATF_TC(conninet4); +ATF_TC_HEAD(conninet4, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks connected multicast for ipv4"); +} + +ATF_TC_BODY(conninet4, tc) +{ + run(HOST_V4, PORT_V4, TOTAL, true, false); +} + +ATF_TC(connmappedinet4); +ATF_TC_HEAD(connmappedinet4, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks connected multicast for mapped ipv4"); +} + +ATF_TC_BODY(connmappedinet4, tc) +{ + run(HOST_V4MAPPED, PORT_V4MAPPED, TOTAL, true, false); +} + +ATF_TC(connmappedbuginet4); +ATF_TC_HEAD(connmappedbuginet4, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks connected multicast for mapped ipv4 using the v4 ioctls"); +} + +ATF_TC_BODY(connmappedbuginet4, tc) +{ + run(HOST_V4MAPPED, PORT_V4MAPPED, TOTAL, true, true); +} + +ATF_TC(conninet6); +ATF_TC_HEAD(conninet6, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks connected multicast for ipv6"); +} + +ATF_TC_BODY(conninet6, tc) +{ + run(HOST_V6, PORT_V6, TOTAL, true, false); +} + +ATF_TC(unconninet4); +ATF_TC_HEAD(unconninet4, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks unconnected multicast for ipv4"); +} + +ATF_TC_BODY(unconninet4, tc) +{ + run(HOST_V4, PORT_V4, TOTAL, false, false); +} + +ATF_TC(unconnmappedinet4); +ATF_TC_HEAD(unconnmappedinet4, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks unconnected multicast for mapped ipv4"); +} + +ATF_TC_BODY(unconnmappedinet4, tc) +{ + run(HOST_V4MAPPED, PORT_V4MAPPED, TOTAL, false, false); +} + +ATF_TC(unconnmappedbuginet4); +ATF_TC_HEAD(unconnmappedbuginet4, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks unconnected multicast for mapped ipv4 using the v4 ioctls"); +} + +ATF_TC_BODY(unconnmappedbuginet4, tc) +{ + run(HOST_V4MAPPED, PORT_V4MAPPED, TOTAL, false, true); +} + +ATF_TC(unconninet6); +ATF_TC_HEAD(unconninet6, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks unconnected multicast for ipv6"); +} + +ATF_TC_BODY(unconninet6, tc) +{ + run(HOST_V6, PORT_V6, TOTAL, false, false); +} + +ATF_TP_ADD_TCS(tp) +{ + debug++; + ATF_TP_ADD_TC(tp, conninet4); + ATF_TP_ADD_TC(tp, connmappedinet4); + ATF_TP_ADD_TC(tp, connmappedbuginet4); + ATF_TP_ADD_TC(tp, conninet6); + ATF_TP_ADD_TC(tp, unconninet4); + ATF_TP_ADD_TC(tp, unconnmappedinet4); + ATF_TP_ADD_TC(tp, unconnmappedbuginet4); + ATF_TP_ADD_TC(tp, unconninet6); + + return atf_no_error(); +} +#endif diff --git a/contrib/netbsd-tests/net/mcast/t_mcast.sh b/contrib/netbsd-tests/net/mcast/t_mcast.sh new file mode 100755 index 0000000..aeb7000 --- /dev/null +++ b/contrib/netbsd-tests/net/mcast/t_mcast.sh @@ -0,0 +1,106 @@ +# $NetBSD: t_mcast.sh,v 1.4 2016/11/25 08:51:16 ozaki-r Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +export RUMP_SERVER=unix://commsock + +DEBUG=${DEBUG:-false} + +run_test() +{ + local name="$1" + local opts="$2" + local mcast="$(atf_get_srcdir)/mcast" + + rump_server_start $RUMP_SERVER netinet6 + rump_server_add_iface $RUMP_SERVER shmif0 bus1 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.0.2/24 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::2/64 + atf_check -s exit:0 rump.ifconfig shmif0 up + + atf_check -s exit:0 rump.ifconfig -w 10 + atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep -q tentative" + + # A route to the mcast address is required to join the mcast group + atf_check -s exit:0 -o ignore rump.route add default 10.0.0.1 + atf_check -s exit:0 -o ignore rump.route add -inet6 default fc00::1 + + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -nr + + export LD_PRELOAD=/usr/lib/librumphijack.so + #$DEBUG && /usr/sbin/ifmcstat # Not yet run on rump kernel + if $DEBUG; then + atf_check -s exit:0 -o ignore $mcast -d ${opts} + else + atf_check -s exit:0 $mcast ${opts} + fi + #$DEBUG && /usr/sbin/ifmcstat # Not yet run on rump kernel + unset LD_PRELOAD +} + +add_test() +{ + local name=$1 + local opts="$2" + local desc="$3" + + atf_test_case "mcast_${name}" cleanup + eval "mcast_${name}_head() { \ + atf_set \"descr\" \"${desc}\"; \ + atf_set \"require.progs\" \"rump_server\"; \ + }; \ + mcast_${name}_body() { \ + run_test \"${name}\" \"${opts}\"; \ + rump_server_destroy_ifaces; \ + }; \ + mcast_${name}_cleanup() { \ + ${DEBUG} && dump; \ + cleanup; \ + }" + atf_add_test_case "mcast_${name}" +} + +atf_init_test_cases() +{ + + add_test conninet4 "-c -4" \ + "Checks connected multicast for ipv4" + add_test connmappedinet4 "-c -m -4" \ + "Checks connected multicast for mapped ipv4" + add_test connmappedbuginet4 "-c -m -b -4" \ + "Checks connected multicast for mapped ipv4 using the v4 ioctls" + add_test conninet6 "-c -6" \ + "Checks connected multicast for ipv6" + add_test unconninet4 "-4" \ + "Checks unconnected multicast for ipv4" + add_test unconnmappedinet4 "-m -4" \ + "Checks unconnected multicast for mapped ipv4" + add_test unconnmappedbuginet4 "-m -b -4" \ + "Checks unconnected multicast for mapped ipv4 using the v4 ioctls" + add_test unconninet6 "-6" \ + "Checks unconnected multicast for ipv6" +} diff --git a/contrib/netbsd-tests/net/mpls/t_ldp_regen.sh b/contrib/netbsd-tests/net/mpls/t_ldp_regen.sh new file mode 100755 index 0000000..964b9ef --- /dev/null +++ b/contrib/netbsd-tests/net/mpls/t_ldp_regen.sh @@ -0,0 +1,183 @@ +# $NetBSD: t_ldp_regen.sh,v 1.7 2016/08/10 07:50:37 ozaki-r Exp $ +# +# Copyright (c) 2013 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# IP/MPLS & LDP label reallocation test +# Create 4 routers connected like this: R1--R2--R3--R4-- +# The goal is to push packets from R1 to the R4 shmif1 (the right one) interface +# Enable MPLS forwarding on R2 +# Disable IP forwarding and enable MPLS forwarding on R3 +# Start ldpd and wait for adjancencies to come up +# Add an alias on shmif1 on R4 for which we already have a route on R3 +# Now: * R4 should install label IMPLNULL for that prefix +# * R3 should realloc the target label from IMPLNULL to something else + + +RUMP_SERVER1=unix://./r1 +RUMP_SERVER2=unix://./r2 +RUMP_SERVER3=unix://./r3 +RUMP_SERVER4=unix://./r4 + +RUMP_LIBS="-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_netinet6 \ + -lrumpdev -lrumpnet_netmpls -lrumpnet_shmif" +LDP_FLAGS="" + +atf_test_case ldp_regen cleanup +ldp_regen_head() { + + atf_set "descr" "IP/MPLS and LDP label regeneration test" + atf_set "require.progs" "rump_server" + atf_set "use.fs" "true" +} + +newaddr_and_ping() { + + # Add new address on R4 + RUMP_SERVER=${RUMP_SERVER4} atf_check -s exit:0 \ + rump.ifconfig shmif1 10.0.5.1/24 alias + RUMP_SERVER=${RUMP_SERVER4} atf_check -s exit:0 \ + rump.ifconfig -w 60 + + # Now ldpd on R5 should take notice of the new route and announce it + # to R4's ldpd. ldpd on R4 should verify that the next hop + # corresponds to its routing table and change its tag entry + RUMP_SERVER=${RUMP_SERVER1} atf_check -s exit:0 -o ignore -e ignore \ + rump.ping -n -o -w 5 10.0.5.1 +} + +create_servers() { + + # allows us to run as normal user + ulimit -r 400 + + atf_check -s exit:0 rump_server ${RUMP_LIBS} ${RUMP_SERVER1} + atf_check -s exit:0 rump_server ${RUMP_LIBS} ${RUMP_SERVER2} + atf_check -s exit:0 rump_server ${RUMP_LIBS} ${RUMP_SERVER3} + atf_check -s exit:0 rump_server ${RUMP_LIBS} ${RUMP_SERVER4} + + # LDP HIJACK + export RUMPHIJACK=path=/rump,socket=all,sysctl=yes + export LD_PRELOAD=/usr/lib/librumphijack.so + + # Setup first server + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.1.1/24 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.route -q add 10.0.4.0/24 10.0.1.2 + atf_check -s exit:0 rump.route -q add 10.0.5.0/24 10.0.1.2 + atf_check -s exit:0 /usr/sbin/ldpd ${LDP_FLAGS} + + # Setup second server + export RUMP_SERVER=${RUMP_SERVER2} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.1.2/24 + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom2 + atf_check -s exit:0 rump.ifconfig shmif1 10.0.2.1/24 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1 + # This one should still do ip forwarding because it announces IMPLNULL + # for the 10.0.1.0/24 subnet + atf_check -s exit:0 rump.route -q add 10.0.4.0/24 10.0.2.2 + atf_check -s exit:0 rump.route -q add 10.0.5.0/24 10.0.2.2 + atf_check -s exit:0 /usr/sbin/ldpd ${LDP_FLAGS} + + # Setup third server + export RUMP_SERVER=${RUMP_SERVER3} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom2 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.2.2/24 + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom3 + atf_check -s exit:0 rump.ifconfig shmif1 10.0.3.1/24 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.route -q add 10.0.1.0/24 10.0.2.1 + atf_check -s exit:0 rump.route -q add 10.0.4.0/24 10.0.3.2 + atf_check -s exit:0 rump.route -q add 10.0.5.0/24 10.0.3.2 + atf_check -s exit:0 /usr/sbin/ldpd ${LDP_FLAGS} + + # Setup fourth server + export RUMP_SERVER=${RUMP_SERVER4} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom3 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.3.2/24 + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom4 + atf_check -s exit:0 rump.ifconfig shmif1 10.0.4.1/24 + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.route -q add 10.0.1.0/24 10.0.3.1 + atf_check -s exit:0 /usr/sbin/ldpd ${LDP_FLAGS} + + unset RUMP_SERVER + unset LD_PRELOAD + unset RUMPHIJACK +} + +wait_ldp_ok() { + + RUMP_SERVER=${RUMP_SERVER1} atf_check -s exit:0 -o ignore -e ignore \ + rump.ifconfig -w 60 + RUMP_SERVER=${RUMP_SERVER1} atf_check -s exit:0 -o ignore -e ignore \ + rump.ping -o -w 60 10.0.4.1 +} + +docleanup() { + + RUMP_SERVER=${RUMP_SERVER1} rump.halt + RUMP_SERVER=${RUMP_SERVER2} rump.halt + RUMP_SERVER=${RUMP_SERVER3} rump.halt + RUMP_SERVER=${RUMP_SERVER4} rump.halt +} + +ldp_regen_body() { + + if sysctl machdep.cpu_brand 2>/dev/null | grep QEMU >/dev/null 2>&1 + then + atf_skip "unreliable under qemu, skip until PR kern/43997 fixed" + fi + create_servers + wait_ldp_ok + newaddr_and_ping +} + +ldp_regen_cleanup() { + + docleanup +} + +atf_init_test_cases() { + + atf_add_test_case ldp_regen +} diff --git a/contrib/netbsd-tests/net/mpls/t_mpls_fw.sh b/contrib/netbsd-tests/net/mpls/t_mpls_fw.sh new file mode 100755 index 0000000..f974b44 --- /dev/null +++ b/contrib/netbsd-tests/net/mpls/t_mpls_fw.sh @@ -0,0 +1,188 @@ +# $NetBSD: t_mpls_fw.sh,v 1.5 2016/08/10 07:50:37 ozaki-r Exp $ +# +# Copyright (c) 2013 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# TEST MPLS encap/decap and forwarding using INET as encapsulated protocol +# Setup four routers connected like this: R1---R2---R3---R4-- +# Goal is to be able to ping from R1 the outermost interface of R4 +# Disable net.inet.ip.forwarding, enable net.mpls.forwarding +# Add route on R1 in order to encapsulate into MPLS the IP packets with +# destination equal to R4 right hand side interface +# Add MPLS routes on R2 in order to forward frames belonging to that FEC to R3 +# Add MPLS "POP" route on R3 for that FEC, pointing to R4 +# Do the same for the reverse direction (R4 to R1) +# ping from R1 to R4 right hand side interface + + +RUMP_SERVER1=unix://./r1 +RUMP_SERVER2=unix://./r2 +RUMP_SERVER3=unix://./r3 +RUMP_SERVER4=unix://./r4 + +RUMP_FLAGS="-lrumpnet -lrumpnet_net -lrumpnet_netinet \ + -lrumpdev -lrumpnet_netmpls -lrumpnet_shmif" + +atf_test_case mplsfw4 cleanup +mplsfw4_head() +{ + + atf_set "descr" "IP/MPLS forwarding test using PHP" + atf_set "require.progs" "rump_server" +} + +startservers() +{ + + ulimit -r 300 + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER1} + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER2} + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER3} + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER4} +} + +configservers() +{ + + # Setup the first server + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.1.1/24 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.route -q add 10.0.4.0/24 -ifa 10.0.1.1 \ + -ifp mpls0 -tag 25 -inet 10.0.1.2 + + # Setup the second server + export RUMP_SERVER=${RUMP_SERVER2} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.1.2/24 + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom2 + atf_check -s exit:0 rump.ifconfig shmif1 10.0.2.1/24 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.route -q add -mpls 25 -tag 30 -inet 10.0.2.2 + atf_check -s exit:0 rump.route -q add -mpls 27 -tag ${1} -inet 10.0.1.1 + + # Setup the third server + export RUMP_SERVER=${RUMP_SERVER3} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom2 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.2.2/24 + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom3 + atf_check -s exit:0 rump.ifconfig shmif1 10.0.3.1/24 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.route -q add -mpls 30 -tag ${1} -inet 10.0.3.2 + atf_check -s exit:0 rump.route -q add -mpls 26 -tag 27 -inet 10.0.2.1 + + # Setup the fourth server + export RUMP_SERVER=${RUMP_SERVER4} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom3 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.3.2/24 + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom4 + atf_check -s exit:0 rump.ifconfig shmif1 10.0.4.1/24 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.route -q add 10.0.1.0/24 -ifa 10.0.3.2 \ + -ifp mpls0 -tag 26 -inet 10.0.3.1 + + unset RUMP_SERVER +} + +doping() +{ + + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 -o match:"64 bytes from 10.0.4.1: icmp_seq=" \ + rump.ping -n -o -w 5 10.0.4.1 + unset RUMP_SERVER +} + +docleanup() +{ + + RUMP_SERVER=${RUMP_SERVER1} rump.halt + RUMP_SERVER=${RUMP_SERVER2} rump.halt + RUMP_SERVER=${RUMP_SERVER3} rump.halt + RUMP_SERVER=${RUMP_SERVER4} rump.halt +} + +mplsfw4_body() +{ + + startservers + configservers 3 + doping +} + +mplsfw4_cleanup() +{ + + docleanup +} + + +atf_test_case mplsfw4_expl cleanup +mplsfw4_expl_head() +{ + + atf_set "descr" "IP/MPLS forwarding test using explicit NULL labels" + atf_set "require.progs" "rump_server" +} + +mplsfw4_expl_body() +{ + + startservers + configservers 0 + doping +} + +mplsfw4_expl_cleanup() +{ + + docleanup +} + + +atf_init_test_cases() +{ + + atf_add_test_case mplsfw4 + atf_add_test_case mplsfw4_expl +} diff --git a/contrib/netbsd-tests/net/mpls/t_mpls_fw6.sh b/contrib/netbsd-tests/net/mpls/t_mpls_fw6.sh new file mode 100755 index 0000000..b9ac6cd --- /dev/null +++ b/contrib/netbsd-tests/net/mpls/t_mpls_fw6.sh @@ -0,0 +1,220 @@ +# $NetBSD: t_mpls_fw6.sh,v 1.3 2016/08/10 07:50:37 ozaki-r Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# Test MPLS encap/decap and forwarding using INET6 as encapsulated protocol +# Setup four routers connected like this: R1---R2---R3---R4-- +# Goal is to be able to ping from R1 the outermost interface of R4 +# Disable net.inet6.ip6.forwarding, enable net.mpls.forwarding +# Add route on R1 in order to encapsulate into MPLS the IP6 packets with +# destination equal to R4 right hand side interface +# Add MPLS routes on R2 in order to forward frames belonging to that FEC to R3 +# Add MPLS "POP" route on R3 for that FEC, pointing to R4 +# Do the same for the reverse direction (R4 to R1) +# ping6 from R1 to R4 right hand side interface +# +# redo the test using IPv6 explicit null label + +RUMP_SERVER1=unix://./r1 +RUMP_SERVER2=unix://./r2 +RUMP_SERVER3=unix://./r3 +RUMP_SERVER4=unix://./r4 + +RUMP_FLAGS6="-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_netinet6 \ + -lrumpdev -lrumpnet_shmif -lrumpnet_netmpls" + +atf_test_case mplsfw6 cleanup +mplsfw6_head() +{ + + atf_set "descr" "IP6/MPLS forwarding test using PHP" + atf_set "require.progs" "rump_server" +} + +startservers() +{ + + ulimit -r 300 + atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER1} + atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER2} + atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER3} + atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER4} +} + +configservers() +{ + + # Setup the first server + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234::1/64 alias + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0 + atf_check -s exit:0 rump.route -q add -inet6 fd00:1234:0:3::/64 \ + -ifa fd00:1234::1 \ + -ifp mpls0 -tag 25 -inet6 fd00:1234::2 + + # Setup the second server + export RUMP_SERVER=${RUMP_SERVER2} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234::2/64 alias + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom2 + atf_check -s exit:0 rump.ifconfig shmif1 inet6 fd00:1234:0:1::1/64 alias + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0 + atf_check -s exit:0 rump.route -q add -mpls 25 -tag 30 \ + -inet6 fd00:1234:0:1::2 + atf_check -s exit:0 rump.route -q add -mpls 27 -tag ${1} -inet6 \ + fd00:1234::1 + + # Setup the third server + export RUMP_SERVER=${RUMP_SERVER3} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom2 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234:0:1::2/64 alias + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom3 + atf_check -s exit:0 rump.ifconfig shmif1 inet6 fd00:1234:0:2::1/64 alias + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0 + atf_check -s exit:0 rump.route -q add -mpls 30 -tag ${1} \ + -inet6 fd00:1234:0:2::2 + atf_check -s exit:0 rump.route -q add -mpls 26 -tag 27 \ + -inet6 fd00:1234:0:1::1 + + # Setup the fourth server + export RUMP_SERVER=${RUMP_SERVER4} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom3 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234:0:2::2/64 alias + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom4 + atf_check -s exit:0 rump.ifconfig shmif1 inet6 fd00:1234:0:3::1/64 alias + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0 + atf_check -s exit:0 rump.route -q add -inet6 fd00:1234::/64 \ + -ifa fd00:1234:0:2::2 \ + -ifp mpls0 -tag 26 -inet6 fd00:1234:0:2::1 + + unset RUMP_SERVER +} + +doping() +{ + + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 \ + -o match:" bytes from fd00:1234::2, icmp_seq=" \ + rump.ping6 -n -o -X 2 fd00:1234::2 + export RUMP_SERVER=${RUMP_SERVER2} + atf_check -s exit:0 \ + -o match:" bytes from fd00:1234:0:1::2, icmp_seq=" \ + rump.ping6 -n -o -X 2 fd00:1234:0:1::2 + export RUMP_SERVER=${RUMP_SERVER3} + atf_check -s exit:0 \ + -o match:" bytes from fd00:1234:0:2::2, icmp_seq=" \ + rump.ping6 -n -o -X 2 fd00:1234:0:2::2 + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 \ + -o match:" bytes from fd00:1234:0:3::1, icmp_seq=" \ + rump.ping6 -n -o -X 2 fd00:1234:0:3::1 + unset RUMP_SERVER +} + +do_check_route() +{ + + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 \ + -o match:"^fd00:1234:0:3::/64.+fd00:1234::2.+25.+mpls0" \ + rump.netstat -nrT + unset RUMP_SERVER +} + +docleanup() +{ + + RUMP_SERVER=${RUMP_SERVER1} rump.halt + RUMP_SERVER=${RUMP_SERVER2} rump.halt + RUMP_SERVER=${RUMP_SERVER3} rump.halt + RUMP_SERVER=${RUMP_SERVER4} rump.halt +} + +mplsfw6_body() +{ + + startservers + configservers 3 + do_check_route + doping +} + +mplsfw6_cleanup() +{ + + docleanup +} + + +atf_test_case mplsfw6_expl cleanup +mplsfw4_expl_head() +{ + + atf_set "descr" "IP6/MPLS forwarding test using explicit NULL labels" + atf_set "require.progs" "rump_server" +} + +mplsfw6_expl_body() +{ + + startservers + configservers 2 + do_check_route + doping +} + +mplsfw6_expl_cleanup() +{ + + docleanup +} + + +atf_init_test_cases() +{ + + atf_add_test_case mplsfw6 + atf_add_test_case mplsfw6_expl +} diff --git a/contrib/netbsd-tests/net/mpls/t_mpls_fw64.sh b/contrib/netbsd-tests/net/mpls/t_mpls_fw64.sh new file mode 100755 index 0000000..9df3aa7 --- /dev/null +++ b/contrib/netbsd-tests/net/mpls/t_mpls_fw64.sh @@ -0,0 +1,226 @@ +# $NetBSD: t_mpls_fw64.sh,v 1.3 2016/08/10 07:50:37 ozaki-r Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# Test MPLS encap/decap and forwarding using INET6 as encapsulated protocol +# Setup four routers connected like this: R1---R2---R3---R4-- +# Goal is to be able to ping from R1 the outermost interface of R4 +# Disable net.inet[6].ip[6].forwarding, enable net.mpls.forwarding +# Use IPv6 between R1-R2-R3 and IPv4 between R3-R4 +# As we use IPv4 on last link we should use only expl.null there +# because implicit null will assume IPv4 (as the next-hop) +# But we can use impl null on R2-R1 link because stack will correctly +# guess IPv6 (from next-hop) +# Add route on R1 in order to encapsulate into MPLS the IP6 packets with +# destination equal to R4 right hand side interface +# Add MPLS routes on R2 in order to forward frames belonging to that FEC to R3 +# Add MPLS expl.null route on R3 for that FEC, pointing to R4 +# Do the same for the reverse direction (R4 to R1) +# ping6 from R1 to R4 right hand side interface + + +RUMP_SERVER1=unix://./r1 +RUMP_SERVER2=unix://./r2 +RUMP_SERVER3=unix://./r3 +RUMP_SERVER4=unix://./r4 + +RUMP_FLAGS6="-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_netinet6 \ + -lrumpdev -lrumpnet_shmif -lrumpnet_netmpls" + +startservers() +{ + + ulimit -r 300 + atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER1} + atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER2} + atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER3} + atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER4} +} + +configservers() +{ + + # Setup the first server + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234::1/64 alias + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0 + atf_check -s exit:0 rump.route -q add -inet6 fd00:1234:0:3::/64 \ + -ifa fd00:1234::1 \ + -ifp mpls0 -tag 25 -inet6 fd00:1234::2 + + # Setup the second server + export RUMP_SERVER=${RUMP_SERVER2} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234::2/64 alias + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom2 + atf_check -s exit:0 rump.ifconfig shmif1 inet6 fd00:1234:0:1::1/64 alias + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0 + atf_check -s exit:0 rump.route -q add -mpls 25 -tag 30 \ + -inet6 fd00:1234:0:1::2 + atf_check -s exit:0 rump.route -q add -mpls 27 -tag ${1} -inet6 \ + fd00:1234::1 + + # Setup the third server + export RUMP_SERVER=${RUMP_SERVER3} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom2 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234:0:1::2/64 alias + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom3 + atf_check -s exit:0 rump.ifconfig shmif1 inet 10.0.3.1/24 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0 + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.route -q add -mpls 30 -tag 2 \ + -inet 10.0.3.2 + atf_check -s exit:0 rump.route -q add -mpls 26 -tag 27 \ + -inet6 fd00:1234:0:1::1 + + # Setup the fourth server + export RUMP_SERVER=${RUMP_SERVER4} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom3 + atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.3.2 + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom4 + atf_check -s exit:0 rump.ifconfig shmif1 inet6 fd00:1234:0:3::1/64 alias + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0 + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.route -q add -inet6 fd00:1234::/64 \ + -ifa fd00:1234:0:3::1 \ + -ifp mpls0 -tag 26 -inet 10.0.3.1 + + unset RUMP_SERVER +} + +doping() +{ + + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 \ + -o match:" bytes from fd00:1234::2, icmp_seq=" \ + rump.ping6 -n -o -X 2 fd00:1234::2 + export RUMP_SERVER=${RUMP_SERVER2} + atf_check -s exit:0 \ + -o match:" bytes from fd00:1234:0:1::2, icmp_seq=" \ + rump.ping6 -n -o -X 2 fd00:1234:0:1::2 + export RUMP_SERVER=${RUMP_SERVER3} + atf_check -s exit:0 \ + -o match:" bytes from 10.0.3.2: icmp_seq" \ + rump.ping -n -o -w 2 10.0.3.2 + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 \ + -o match:" bytes from fd00:1234:0:3::1, icmp_seq=" \ + rump.ping6 -n -o -X 2 fd00:1234:0:3::1 + unset RUMP_SERVER +} + +do_check_route() +{ + + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 \ + -o match:"^fd00:1234:0:3::/64.+fd00:1234::2.+25.+mpls0" \ + rump.netstat -nrT + unset RUMP_SERVER +} + +docleanup() +{ + + RUMP_SERVER=${RUMP_SERVER1} rump.halt + RUMP_SERVER=${RUMP_SERVER2} rump.halt + RUMP_SERVER=${RUMP_SERVER3} rump.halt + RUMP_SERVER=${RUMP_SERVER4} rump.halt +} + +atf_test_case mplsfw64_impl cleanup +mplsfw64_impl_head() +{ + + atf_set "descr" "IP6/MPLS test using impl. NULL labels in mixed env." + atf_set "require.progs" "rump_server" +} + +mplsfw64_impl_body() +{ + + startservers + configservers 3 + do_check_route + doping +} + +mplsfw64_impl_cleanup() +{ + + docleanup +} + + +atf_test_case mplsfw64_expl cleanup +mplsfw64_expl_head() +{ + + atf_set "descr" "IP6/MPLS test using explicit NULL labels in mixed env." + atf_set "require.progs" "rump_server" +} + +mplsfw64_expl_body() +{ + + startservers + configservers 2 + do_check_route + doping +} + +mplsfw64_expl_cleanup() +{ + + docleanup +} + + +atf_init_test_cases() +{ + + atf_add_test_case mplsfw64_impl + atf_add_test_case mplsfw64_expl +} diff --git a/contrib/netbsd-tests/net/mpls/t_rfc4182.sh b/contrib/netbsd-tests/net/mpls/t_rfc4182.sh new file mode 100755 index 0000000..558f7fd --- /dev/null +++ b/contrib/netbsd-tests/net/mpls/t_rfc4182.sh @@ -0,0 +1,165 @@ +# $NetBSD: t_rfc4182.sh,v 1.4 2016/08/10 07:50:37 ozaki-r Exp $ +# +# Copyright (c) 2013 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# TEST RFC 4182 +# Setup four routers connected like this: R1---R2---R3---R4-- +# Goal is to be able to ping from R1 the outermost interface of R4 +# Disable net.inet.ip.forwarding, enable net.mpls.forwarding +# Add route on R1 in order to encapsulate into MPLS the IP packets with +# destination equal to R4 right hand side interface. Use two labels here: +# 25 and IPv6 Explicit NULL +# Add a double tagged MPLS route on R2 in order to forward frames belonging to +# that FEC to R3, with IPv4 NULL being the most outermost one +# Add MPLS "POP" route on R3 for that FEC, pointing to R4 +# Do the same for the reverse direction (R4 to R1) +# ping from R1 to R4 right hand side interface + + +RUMP_SERVER1=unix://./r1 +RUMP_SERVER2=unix://./r2 +RUMP_SERVER3=unix://./r3 +RUMP_SERVER4=unix://./r4 + +RUMP_FLAGS="-lrumpnet -lrumpnet_net -lrumpnet_netinet \ + -lrumpdev -lrumpnet_netmpls -lrumpnet_shmif" + +atf_test_case rfc4182 cleanup +rfc4182_head() +{ + + atf_set "descr" "RFC 4182 conformance test" + atf_set "require.progs" "rump_server" +} + +startservers() +{ + + ulimit -r 300 + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER1} + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER2} + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER3} + atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER4} +} + +configservers() +{ + + # Setup the first server + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.1.1/24 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.route -q add 10.0.4.0/24 -ifa 10.0.1.1 \ + -ifp mpls0 -tag 25,2 -inet 10.0.1.2 + + # Setup the second server + export RUMP_SERVER=${RUMP_SERVER2} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.1.2/24 + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom2 + atf_check -s exit:0 rump.ifconfig shmif1 10.0.2.1/24 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.route -q add -mpls 25 -tag 30,0 -inet 10.0.2.2 + atf_check -s exit:0 rump.route -q add -mpls 27 -tag 3 -inet 10.0.1.1 + + # Setup the third server + export RUMP_SERVER=${RUMP_SERVER3} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom2 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.2.2/24 + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom3 + atf_check -s exit:0 rump.ifconfig shmif1 10.0.3.1/24 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.route -q add -mpls 30 -tag 3 -inet 10.0.3.2 + atf_check -s exit:0 rump.route -q add -mpls 26 -tag 27,0 -inet 10.0.2.1 + + # Setup the fourth server + export RUMP_SERVER=${RUMP_SERVER4} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom3 + atf_check -s exit:0 rump.ifconfig shmif0 10.0.3.2/24 + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom4 + atf_check -s exit:0 rump.ifconfig shmif1 10.0.4.1/24 + atf_check -s exit:0 rump.ifconfig mpls0 create up + atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1 + atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0 + atf_check -s exit:0 rump.route -q add 10.0.1.0/24 -ifa 10.0.3.2 \ + -ifp mpls0 -tag 26 -inet 10.0.3.1 + + unset RUMP_SERVER +} + +doping() +{ + + export RUMP_SERVER=${RUMP_SERVER1} + atf_check -s exit:0 -o match:"64 bytes from 10.0.4.1: icmp_seq=" \ + rump.ping -n -o -w 5 10.0.4.1 + unset RUMP_SERVER +} + +docleanup() +{ + + RUMP_SERVER=${RUMP_SERVER1} rump.halt + RUMP_SERVER=${RUMP_SERVER2} rump.halt + RUMP_SERVER=${RUMP_SERVER3} rump.halt + RUMP_SERVER=${RUMP_SERVER4} rump.halt +} + +rfc4182_body() +{ + + startservers + configservers + doping +} + +rfc4182_cleanup() +{ + + docleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case rfc4182 +} diff --git a/contrib/netbsd-tests/net/ndp/t_dad.sh b/contrib/netbsd-tests/net/ndp/t_dad.sh new file mode 100755 index 0000000..50ec933 --- /dev/null +++ b/contrib/netbsd-tests/net/ndp/t_dad.sh @@ -0,0 +1,276 @@ +# $NetBSD: t_dad.sh,v 1.12 2016/11/25 08:51:17 ozaki-r Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCKLOCAL=unix://commsock1 +SOCKPEER=unix://commsock2 + +DEBUG=${DEBUG:-false} + +duplicated="[Dd][Uu][Pp][Ll][Ii][Cc][Aa][Tt][Ee][Dd]" + +atf_test_case dad_basic cleanup +atf_test_case dad_duplicated cleanup +atf_test_case dad_count cleanup + +dad_basic_head() +{ + atf_set "descr" "Tests for IPv6 DAD basic behavior" + atf_set "require.progs" "rump_server" +} + +dad_duplicated_head() +{ + atf_set "descr" "Tests for IPv6 DAD duplicated state" + atf_set "require.progs" "rump_server" +} + +dad_count_head() +{ + atf_set "descr" "Tests for IPv6 DAD count behavior" + atf_set "require.progs" "rump_server" +} + +setup_server() +{ + local sock=$1 + local ip=$2 + + rump_server_add_iface $sock shmif0 bus1 + + export RUMP_SERVER=$sock + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig shmif0 +} + +make_ns_pkt_str() +{ + local id=$1 + local target=$2 + pkt="33:33:ff:00:00:0${id}, ethertype IPv6 (0x86dd), length 78: ::" + pkt="$pkt > ff02::1:ff00:${id}: ICMP6, neighbor solicitation," + pkt="$pkt who has $target, length 24" + echo $pkt +} + +dad_basic_body() +{ + local pkt= + local localip1=fc00::1 + local localip2=fc00::2 + local localip3=fc00::3 + + rump_server_start $SOCKLOCAL netinet6 + rump_server_add_iface $SOCKLOCAL shmif0 bus1 + + export RUMP_SERVER=$SOCKLOCAL + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $localip1 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $localip2 + $DEBUG && rump.ifconfig shmif0 + + atf_check -s exit:0 rump.ifconfig shmif0 up + rump.ifconfig shmif0 > ./out + $DEBUG && cat ./out + + # The primary address doesn't start with tentative state + atf_check -s not-exit:0 -x "cat ./out |grep $localip1 |grep -q tentative" + # The alias address starts with tentative state + # XXX we have no stable way to check this, so skip for now + #atf_check -s exit:0 -x "cat ./out |grep $localip2 |grep -q tentative" + + atf_check -s exit:0 sleep 2 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + # Check DAD probe packets (Neighbor Solicitation Message) + pkt=$(make_ns_pkt_str 2 $localip2) + atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" + # No DAD for the primary address + pkt=$(make_ns_pkt_str 1 $localip1) + atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" + + # Waiting for DAD complete + atf_check -s exit:0 rump.ifconfig -w 10 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + # IPv6 DAD doesn't announce (Neighbor Advertisement Message) + + # The alias address left tentative + atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep $localip2 |grep -q tentative" + + # + # Add a new address on the fly + # + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $localip3 + + # The new address starts with tentative state + # XXX we have no stable way to check this, so skip for now + #atf_check -s exit:0 -x "rump.ifconfig shmif0 |grep $localip3 |grep -q tentative" + + # Check DAD probe packets (Neighbor Solicitation Message) + atf_check -s exit:0 sleep 2 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + pkt=$(make_ns_pkt_str 3 $localip3) + atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" + + # Waiting for DAD complete + atf_check -s exit:0 rump.ifconfig -w 10 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + # IPv6 DAD doesn't announce (Neighbor Advertisement Message) + + # The new address left tentative + atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep $localip3 |grep -q tentative" + + rump_server_destroy_ifaces +} + +dad_duplicated_body() +{ + local localip1=fc00::1 + local localip2=fc00::11 + local peerip=fc00::2 + + rump_server_start $SOCKLOCAL netinet6 + rump_server_start $SOCKPEER netinet6 + + setup_server $SOCKLOCAL $localip1 + setup_server $SOCKPEER $peerip + + export RUMP_SERVER=$SOCKLOCAL + + # The primary address isn't marked as duplicated + atf_check -s exit:0 -o not-match:"$localip1.+$duplicated" \ + rump.ifconfig shmif0 + + # + # Add a new address duplicated with the peer server + # + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $peerip + atf_check -s exit:0 sleep 1 + + # The new address is marked as duplicated + atf_check -s exit:0 -o match:"$peerip.+$duplicated" \ + rump.ifconfig shmif0 + + # A unique address isn't marked as duplicated + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $localip2 + atf_check -s exit:0 sleep 1 + atf_check -s exit:0 -o not-match:"$localip2.+$duplicated" \ + rump.ifconfig shmif0 + + rump_server_destroy_ifaces +} + +dad_count_test() +{ + local pkt= + local count=$1 + local id=$2 + local target=$3 + + # + # Set DAD count to $count + # + atf_check -s exit:0 rump.sysctl -w -q net.inet6.ip6.dad_count=$count + + # Add a new address + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $target + + # Waiting for DAD complete + atf_check -s exit:0 rump.ifconfig -w 20 + + # Check the number of DAD probe packets (Neighbor Solicitation Message) + atf_check -s exit:0 sleep 2 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + pkt=$(make_ns_pkt_str $id $target) + atf_check -s exit:0 -o match:"$count" \ + -x "cat ./out |grep '$pkt' | wc -l | tr -d ' '" +} + +dad_count_body() +{ + local localip1=fc00::1 + local localip2=fc00::2 + + rump_server_start $SOCKLOCAL netinet6 + rump_server_add_iface $SOCKLOCAL shmif0 bus1 + + export RUMP_SERVER=$SOCKLOCAL + + # Check default value + atf_check -s exit:0 -o match:"1" rump.sysctl -n net.inet6.ip6.dad_count + + # Setup interface + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 sleep 2 + rump.ifconfig shmif0 > ./out + $DEBUG && cat ./out + + # + # Set and test DAD count (count=1) + # + dad_count_test 1 1 $localip1 + + # + # Set and test DAD count (count=8) + # + dad_count_test 8 2 $localip2 + + rump_server_destroy_ifaces +} + +dad_basic_cleanup() +{ + $DEBUG && dump + cleanup +} + +dad_duplicated_cleanup() +{ + $DEBUG && dump + cleanup +} + +dad_count_cleanup() +{ + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case dad_basic + atf_add_test_case dad_duplicated + atf_add_test_case dad_count +} diff --git a/contrib/netbsd-tests/net/ndp/t_ndp.sh b/contrib/netbsd-tests/net/ndp/t_ndp.sh new file mode 100755 index 0000000..aa96390 --- /dev/null +++ b/contrib/netbsd-tests/net/ndp/t_ndp.sh @@ -0,0 +1,406 @@ +# $NetBSD: t_ndp.sh,v 1.17 2016/11/25 08:51:17 ozaki-r Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCKSRC=unix://commsock1 +SOCKDST=unix://commsock2 +IP6SRC=fc00::1 +IP6DST=fc00::2 + +DEBUG=${DEBUG:-true} +TIMEOUT=1 + +atf_test_case ndp_cache_expiration cleanup +atf_test_case ndp_commands cleanup +atf_test_case ndp_cache_overwriting cleanup +atf_test_case ndp_neighborgcthresh cleanup +atf_test_case ndp_link_activation cleanup + +ndp_cache_expiration_head() +{ + atf_set "descr" "Tests for NDP cache expiration" + atf_set "require.progs" "rump_server" +} + +ndp_commands_head() +{ + atf_set "descr" "Tests for commands of ndp(8)" + atf_set "require.progs" "rump_server" +} + +ndp_cache_overwriting_head() +{ + atf_set "descr" "Tests for behavior of overwriting NDP caches" + atf_set "require.progs" "rump_server" +} + +ndp_neighborgcthresh_head() +{ + atf_set "descr" "Tests for GC of neighbor caches" + atf_set "require.progs" "rump_server" +} + +ndp_link_activation_head() +{ + atf_set "descr" "Tests for activating a new MAC address" + atf_set "require.progs" "rump_server" +} + +setup_dst_server() +{ + local assign_ip=$1 + + rump_server_add_iface $SOCKDST shmif0 bus1 + export RUMP_SERVER=$SOCKDST + if [ "$assign_ip" != no ]; then + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6DST + fi + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig shmif0 + $DEBUG && rump.ndp -n -a +} + +setup_src_server() +{ + $DEBUG && ulimit -c unlimited + export RUMP_SERVER=$SOCKSRC + + # Setup an interface + rump_server_add_iface $SOCKSRC shmif0 bus1 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6SRC + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + # Sanity check + $DEBUG && rump.ifconfig shmif0 + $DEBUG && rump.ndp -n -a + atf_check -s exit:0 -o ignore rump.ndp -n $IP6SRC + atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST +} + +get_timeout() +{ + local timeout=$(env RUMP_SERVER=$SOCKSRC rump.ndp -n $IP6DST |grep $IP6DST|awk '{print $4;}') + timeout=${timeout%s} + echo $timeout +} + +ndp_cache_expiration_body() +{ + + rump_server_start $SOCKSRC netinet6 + rump_server_start $SOCKDST netinet6 + + setup_dst_server + setup_src_server + + # + # Check if a cache is expired expectedly + # + export RUMP_SERVER=$SOCKSRC + atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST + + $DEBUG && rump.ndp -n -a + atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6SRC + # Should be cached + atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST + + timeout=$(get_timeout $IP6DST) + + atf_check -s exit:0 sleep $(($timeout + 1)) + + $DEBUG && rump.ndp -n -a + atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6SRC + # Expired but remains until GC sweaps it (1 day) + atf_check -s exit:0 -o match:'(1d0h0m|23h59m)' rump.ndp -n $IP6DST + + rump_server_destroy_ifaces +} + +ifdown_dst_server() +{ + export RUMP_SERVER=$SOCKDST + atf_check -s exit:0 rump.ifconfig shmif0 down + export RUMP_SERVER=$SOCKSRC +} + +ndp_commands_body() +{ + + rump_server_start $SOCKSRC netinet6 + rump_server_start $SOCKDST netinet6 + + setup_dst_server + setup_src_server + + export RUMP_SERVER=$SOCKSRC + + # We can delete the entry for the interface's IP address + atf_check -s exit:0 -o match:"$IP6SRC" rump.ndp -d $IP6SRC + + # Add and delete a static entry + $DEBUG && rump.ndp -n -a + atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 + $DEBUG && rump.ndp -n -a + atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::10 + atf_check -s exit:0 -o match:'deleted' rump.ndp -d fc00::10 + $DEBUG && rump.ndp -n -a + atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n fc00::10 + + # Add multiple entries via a file (XXX not implemented) + #cat - > ./list <<-EOF + #fc00::11 b2:a0:20:00:00:11 + #fc00::12 b2:a0:20:00:00:12 + #fc00::13 b2:a0:20:00:00:13 + #fc00::14 b2:a0:20:00:00:14 + #fc00::15 b2:a0:20:00:00:15 + #EOF + #$DEBUG && rump.ndp -n -a + #atf_check -s exit:0 -o ignore rump.ndp -f ./list + #$DEBUG && rump.ndp -n -a + + atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST + atf_check -s exit:0 -o ignore rump.ndp -s fc00::11 b2:a0:20:00:00:11 + atf_check -s exit:0 -o ignore rump.ndp -s fc00::12 b2:a0:20:00:00:12 + + atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST + atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::11 + atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::12 + + # Test ndp -a + atf_check -s exit:0 -o match:'fc00::11' rump.ndp -n -a + atf_check -s exit:0 -o match:'fc00::12' rump.ndp -n -a + + # Ensure no packet upsets the src server + ifdown_dst_server + + # Flush all entries (-c) + $DEBUG && rump.ndp -n -a + atf_check -s exit:0 -o ignore rump.ndp -c + atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6SRC + atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST + # Only the static caches are not deleted + atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::11 + atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::12 + + $DEBUG && rump.ndp -n -a + atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp + rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp + $DEBUG && rump.ndp -n -a + atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10 + + rump_server_destroy_ifaces +} + +ndp_cache_overwriting_body() +{ + + rump_server_start $SOCKSRC netinet6 + rump_server_start $SOCKDST netinet6 + + setup_dst_server + setup_src_server + + export RUMP_SERVER=$SOCKSRC + + # Cannot overwrite a permanent cache + atf_check -s not-exit:0 -e ignore rump.ndp -s $IP6SRC b2:a0:20:00:00:ff + $DEBUG && rump.ndp -n -a + + atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST + $DEBUG && rump.ndp -n -a + # Can overwrite a dynamic cache + atf_check -s exit:0 -o ignore rump.ndp -s $IP6DST b2:a0:20:00:00:00 + $DEBUG && rump.ndp -n -a + atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6DST + + # Test temp option (XXX it doesn't work; expire time isn't set) + #atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp + #$DEBUG && rump.ndp -n -a + #atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10 + # Cannot overwrite a temp cache + #atf_check -s not-exit:0 -e ignore rump.ndp -s fc00::10 b2:a0:20:00:00:ff + #$DEBUG && rump.ndp -n -a + + rump_server_destroy_ifaces +} + +get_n_caches() +{ + + echo $(rump.ndp -a -n |grep -v -e Neighbor -e permanent |wc -l) +} + +ndp_neighborgcthresh_body() +{ + + rump_server_start $SOCKSRC netinet6 + rump_server_start $SOCKDST netinet6 + + setup_dst_server no + setup_src_server + + export RUMP_SERVER=$SOCKDST + for i in $(seq 0 9); do + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6DST}$i + done + + export RUMP_SERVER=$SOCKSRC + + # ping to 3 destinations + $DEBUG && rump.ndp -n -a + for i in $(seq 0 2); do + atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \ + ${IP6DST}$i + done + $DEBUG && rump.ndp -n -a + + # 3 caches should be created + atf_check_equal $(get_n_caches) 3 + + # ping to additional 3 destinations + for i in $(seq 3 5); do + atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \ + ${IP6DST}$i + done + $DEBUG && rump.ndp -n -a + + # 6 caches should be created in total + atf_check_equal $(get_n_caches) 6 + + # Limit the number of neighbor caches to 5 + atf_check -s exit:0 -o ignore rump.sysctl -w \ + net.inet6.ip6.neighborgcthresh=5 + + # ping to additional 4 destinations + for i in $(seq 6 9); do + atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \ + ${IP6DST}$i + done + + # More than 5 caches should be created in total, but exceeded caches + # should be GC-ed + if [ "$(get_n_caches)" -gt 5 ]; then + atf_fail "Neighbor caches are not GC-ed" + fi + + rump_server_destroy_ifaces +} + +make_pkt_str_na() +{ + local ip=$1 + local mac=$2 + local pkt= + pkt="$mac > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86:" + pkt="$pkt $ip > ff02::1: ICMP6, neighbor advertisement" + echo $pkt +} + +ndp_link_activation_body() +{ + local linklocal= + + rump_server_start $SOCKSRC netinet6 + rump_server_start $SOCKDST netinet6 + + setup_dst_server + setup_src_server + + # flush old packets + extract_new_packets bus1 > ./out + + export RUMP_SERVER=$SOCKSRC + + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \ + b2:a1:00:00:00:01 + + atf_check -s exit:0 sleep 1 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}') + $DEBUG && echo $linklocal + + pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:01) + atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'" + + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \ + b2:a1:00:00:00:02 active + + atf_check -s exit:0 sleep 1 + extract_new_packets bus1 > ./out + $DEBUG && cat ./out + + linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}') + $DEBUG && echo $linklocal + + pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:02) + atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'" + + rump_server_destroy_ifaces +} + +ndp_cache_expiration_cleanup() +{ + $DEBUG && dump + cleanup +} + +ndp_commands_cleanup() +{ + $DEBUG && dump + cleanup +} + +ndp_cache_overwriting_cleanup() +{ + $DEBUG && dump + cleanup +} + +ndp_neighborgcthresh_cleanup() +{ + $DEBUG && dump + cleanup +} + +ndp_link_activation_cleanup() +{ + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case ndp_cache_expiration + atf_add_test_case ndp_commands + atf_add_test_case ndp_cache_overwriting + atf_add_test_case ndp_neighborgcthresh + atf_add_test_case ndp_link_activation +} diff --git a/contrib/netbsd-tests/net/ndp/t_ra.sh b/contrib/netbsd-tests/net/ndp/t_ra.sh new file mode 100755 index 0000000..69f227a --- /dev/null +++ b/contrib/netbsd-tests/net/ndp/t_ra.sh @@ -0,0 +1,703 @@ +# $NetBSD: t_ra.sh,v 1.24 2017/01/13 08:11:01 ozaki-r Exp $ +# +# Copyright (c) 2015 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +RUMPSRV=unix://r1 +RUMPSRV1_2=unix://r12 +RUMPCLI=unix://r2 +RUMPSRV3=unix://r3 +RUMPSRV4=unix://r4 +IP6SRV=fc00:1::1 +IP6SRV1_2=fc00:1::2 +IP6SRV_PREFIX=fc00:1: +IP6CLI=fc00:2::2 +IP6SRV3=fc00:3::1 +IP6SRV3_PREFIX=fc00:3: +IP6SRV4=fc00:4::1 +IP6SRV4_PREFIX=fc00:4: +PIDFILE=./rump.rtadvd.pid +PIDFILE1_2=./rump.rtadvd.pid12 +PIDFILE3=./rump.rtadvd.pid3 +PIDFILE4=./rump.rtadvd.pid4 +CONFIG=./rtadvd.conf +WAITTIME=2 +DEBUG=${DEBUG:-true} + +init_server() +{ + + export RUMP_SERVER=$1 + atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.forwarding=1 + export LD_PRELOAD=/usr/lib/librumphijack.so + atf_check -s exit:0 mkdir -p /rump/var/chroot/rtadvd + unset LD_PRELOAD + unset RUMP_SERVER +} + +setup_shmif0() +{ + local sock=$1 + local IP6ADDR=$2 + + rump_server_add_iface $sock shmif0 bus1 + + export RUMP_SERVER=$sock + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6ADDR} + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig +} + +wait_term() +{ + local PIDFILE=${1} + shift + + while [ -f ${PIDFILE} ] + do + sleep 0.2 + done + + return 0 +} + +create_rtadvdconfig() +{ + + cat << _EOF > ${CONFIG} +shmif0:\ + :mtu#1300:maxinterval#4:mininterval#3: +_EOF +} + +start_rtadvd() +{ + local sock=$1 + local pidfile=$2 + + export RUMP_SERVER=$sock + atf_check -s exit:0 rump.rtadvd -c ${CONFIG} -p $pidfile shmif0 + while [ ! -f $pidfile ]; do + sleep 0.2 + done + unset RUMP_SERVER +} + +check_entries() +{ + local cli=$1 + local srv=$2 + local addr_prefix=$3 + local mac_srv= ll_srv= + + ll_srv=$(get_linklocal_addr $srv shmif0) + mac_srv=$(get_macaddr $srv shmif0) + + export RUMP_SERVER=$cli + $DEBUG && dump_entries + atf_check -s exit:0 -o match:'if=shmif0' rump.ndp -r + atf_check -s exit:0 -o match:'advertised' rump.ndp -p + atf_check -s exit:0 -o match:"${ll_srv}%shmif0 \(reachable\)" rump.ndp -p + atf_check -s exit:0 -o match:'linkmtu=1300' rump.ndp -n -i shmif0 + atf_check -s exit:0 \ + -o match:"$ll_srv%shmif0 +$mac_srv +shmif0 +(23h59m|1d0h0m)..s S R" \ + rump.ndp -n -a + atf_check -s exit:0 -o match:$addr_prefix rump.ndp -n -a + atf_check -s exit:0 \ + -o match:"$addr_prefix.+<(TENTATIVE,)?AUTOCONF>" \ + rump.ifconfig shmif0 inet6 + unset RUMP_SERVER +} + +dump_entries() +{ + + echo ndp -n -a + rump.ndp -n -a + echo ndp -p + rump.ndp -p + echo ndp -r + rump.ndp -r +} + +atf_test_case ra_basic cleanup +ra_basic_head() +{ + + atf_set "descr" "Tests for basic functions of router advaertisement(RA)" + atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig" +} + +ra_basic_body() +{ + + rump_server_fs_start $RUMPSRV netinet6 + rump_server_start $RUMPCLI netinet6 + + setup_shmif0 ${RUMPSRV} ${IP6SRV} + init_server $RUMPSRV + + setup_shmif0 ${RUMPCLI} ${IP6CLI} + export RUMP_SERVER=${RUMPCLI} + $DEBUG && rump.ndp -n -a + atf_check -s exit:0 -o match:'= 0' rump.sysctl net.inet6.ip6.accept_rtadv + unset RUMP_SERVER + + create_rtadvdconfig + start_rtadvd $RUMPSRV $PIDFILE + sleep $WAITTIME + + export RUMP_SERVER=${RUMPCLI} + atf_check -s exit:0 -o empty rump.ndp -r + atf_check -s exit:0 -o not-match:'advertised' rump.ndp -p + atf_check -s exit:0 -o match:'linkmtu=0' rump.ndp -n -i shmif0 + atf_check -s exit:0 -o not-match:'S R' rump.ndp -n -a + atf_check -s exit:0 -o not-match:'fc00:1:' rump.ndp -n -a + atf_check -s exit:0 -o not-match:'fc00:1:' rump.ifconfig shmif0 inet6 + unset RUMP_SERVER + + atf_check -s exit:0 kill -TERM `cat ${PIDFILE}` + wait_term ${PIDFILE} + + export RUMP_SERVER=${RUMPCLI} + atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1 + unset RUMP_SERVER + + start_rtadvd $RUMPSRV $PIDFILE + sleep $WAITTIME + + check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX + + atf_check -s exit:0 kill -TERM `cat ${PIDFILE}` + wait_term ${PIDFILE} + + rump_server_destroy_ifaces +} + +ra_basic_cleanup() +{ + + if [ -f ${PIDFILE} ]; then + kill -TERM `cat ${PIDFILE}` + wait_term ${PIDFILE} + fi + + $DEBUG && dump + cleanup +} + +atf_test_case ra_flush_prefix_entries cleanup +ra_flush_prefix_entries_head() +{ + + atf_set "descr" "Tests for flushing prefixes (ndp -P)" + atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig" +} + +ra_flush_prefix_entries_body() +{ + + rump_server_fs_start $RUMPSRV netinet6 + rump_server_start $RUMPCLI netinet6 + + setup_shmif0 ${RUMPSRV} ${IP6SRV} + setup_shmif0 ${RUMPCLI} ${IP6CLI} + + init_server $RUMPSRV + + create_rtadvdconfig + + export RUMP_SERVER=${RUMPCLI} + atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1 + unset RUMP_SERVER + + start_rtadvd $RUMPSRV $PIDFILE + sleep $WAITTIME + + check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX + + export RUMP_SERVER=${RUMPCLI} + + # Terminate rtadvd to prevent new RA messages from coming + # Note that ifconfig down; kill -TERM doesn't work + kill -KILL `cat ${PIDFILE}` + + # Flush all the entries in the prefix list + atf_check -s exit:0 rump.ndp -P + + $DEBUG && dump_entries + atf_check -s exit:0 -o match:'if=shmif0' rump.ndp -r + atf_check -s exit:0 -o empty rump.ndp -p + atf_check -s exit:0 -o match:'linkmtu=1300' rump.ndp -n -i shmif0 + atf_check -s exit:0 -o match:'(23h59m|1d0h0m)..s S R' rump.ndp -n -a + atf_check -s exit:0 -o match:'fc00:1:' rump.ndp -n -a + atf_check -s exit:0 -o not-match:'fc00:1:' rump.ifconfig shmif0 inet6 + unset RUMP_SERVER + + rump_server_destroy_ifaces +} + +ra_flush_prefix_entries_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_test_case ra_flush_defrouter_entries cleanup +ra_flush_defrouter_entries_head() +{ + + atf_set "descr" "Tests for flushing default routers (ndp -R)" + atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig" +} + +ra_flush_defrouter_entries_body() +{ + + rump_server_fs_start $RUMPSRV netinet6 + rump_server_start $RUMPCLI netinet6 + + setup_shmif0 ${RUMPSRV} ${IP6SRV} + setup_shmif0 ${RUMPCLI} ${IP6CLI} + + init_server $RUMPSRV + + create_rtadvdconfig + + export RUMP_SERVER=${RUMPCLI} + atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1 + unset RUMP_SERVER + + start_rtadvd $RUMPSRV $PIDFILE + sleep $WAITTIME + + check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX + + export RUMP_SERVER=${RUMPCLI} + + # Terminate rtadvd to prevent new RA messages from coming + # Note that ifconfig down; kill -TERM doesn't work + kill -KILL `cat ${PIDFILE}` + + # Flush all the entries in the default router list + atf_check -s exit:0 rump.ndp -R + + $DEBUG && dump_entries + atf_check -s exit:0 -o empty rump.ndp -r + atf_check -s exit:0 -o match:'No advertising router' rump.ndp -p + atf_check -s exit:0 -o match:'linkmtu=1300' rump.ndp -n -i shmif0 + atf_check -s exit:0 -o match:'(23h59m|1d0h0m)..s S R' rump.ndp -n -a + atf_check -s exit:0 -o match:'fc00:1:' rump.ndp -n -a + atf_check -s exit:0 -o match:'fc00:1:' rump.ifconfig shmif0 inet6 + unset RUMP_SERVER + + rump_server_destroy_ifaces +} + +ra_flush_defrouter_entries_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_test_case ra_delete_address cleanup +ra_delete_address_head() +{ + + atf_set "descr" "Tests for deleting auto-configured address" + atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig" +} + +ra_delete_address_body() +{ + + rump_server_fs_start $RUMPSRV netinet6 + rump_server_start $RUMPCLI netinet6 + + setup_shmif0 ${RUMPSRV} ${IP6SRV} + setup_shmif0 ${RUMPCLI} ${IP6CLI} + + init_server $RUMPSRV + + create_rtadvdconfig + + export RUMP_SERVER=${RUMPCLI} + atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1 + unset RUMP_SERVER + + start_rtadvd $RUMPSRV $PIDFILE + sleep $WAITTIME + + check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX + + export RUMP_SERVER=${RUMPCLI} + $DEBUG && rump.ifconfig shmif0 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 \ + $(rump.ifconfig shmif0 |awk '/AUTOCONF/ {print $2}') delete + unset RUMP_SERVER + + atf_check -s exit:0 kill -TERM `cat ${PIDFILE}` + wait_term ${PIDFILE} + + rump_server_destroy_ifaces +} + +ra_delete_address_cleanup() +{ + + if [ -f ${PIDFILE} ]; then + kill -TERM `cat ${PIDFILE}` + wait_term ${PIDFILE} + fi + + $DEBUG && dump + cleanup +} + +atf_test_case ra_multiple_routers cleanup +ra_multiple_routers_head() +{ + + atf_set "descr" "Tests for multiple routers" + atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig" +} + +ra_multiple_routers_body() +{ + local n= + + rump_server_fs_start $RUMPSRV netinet6 + rump_server_fs_start $RUMPSRV3 netinet6 + rump_server_start $RUMPCLI netinet6 + + setup_shmif0 ${RUMPSRV} ${IP6SRV} + setup_shmif0 ${RUMPSRV3} ${IP6SRV3} + setup_shmif0 ${RUMPCLI} ${IP6CLI} + + init_server $RUMPSRV + init_server $RUMPSRV3 + + create_rtadvdconfig + + export RUMP_SERVER=${RUMPCLI} + atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1 + unset RUMP_SERVER + + start_rtadvd $RUMPSRV $PIDFILE + start_rtadvd $RUMPSRV3 $PIDFILE3 + sleep $WAITTIME + + check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX + check_entries $RUMPCLI $RUMPSRV3 $IP6SRV3_PREFIX + + export RUMP_SERVER=$RUMPCLI + # Two prefixes are advertised by differnt two routers + n=$(rump.ndp -p |grep 'advertised by' |wc -l) + atf_check_equal $n 2 + unset RUMP_SERVER + + atf_check -s exit:0 kill -TERM `cat ${PIDFILE}` + wait_term ${PIDFILE} + atf_check -s exit:0 kill -TERM `cat ${PIDFILE3}` + wait_term ${PIDFILE3} + + rump_server_destroy_ifaces +} + +ra_multiple_routers_cleanup() +{ + + if [ -f ${PIDFILE} ]; then + kill -TERM `cat ${PIDFILE}` + wait_term ${PIDFILE} + fi + if [ -f ${PIDFILE3} ]; then + kill -TERM `cat ${PIDFILE3}` + wait_term ${PIDFILE3} + fi + + $DEBUG && dump + cleanup +} + +atf_test_case ra_multiple_routers_single_prefix cleanup +ra_multiple_routers_single_prefix_head() +{ + + atf_set "descr" "Tests for multiple routers with a single prefix" + atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig" +} + +ra_multiple_routers_single_prefix_body() +{ + local n= + + rump_server_fs_start $RUMPSRV netinet6 + rump_server_fs_start $RUMPSRV1_2 netinet6 + rump_server_start $RUMPCLI netinet6 + + setup_shmif0 ${RUMPSRV} ${IP6SRV} + setup_shmif0 ${RUMPSRV1_2} ${IP6SRV1_2} + setup_shmif0 ${RUMPCLI} ${IP6CLI} + + init_server $RUMPSRV + init_server $RUMPSRV1_2 + + create_rtadvdconfig + + export RUMP_SERVER=${RUMPCLI} + atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1 + unset RUMP_SERVER + + start_rtadvd $RUMPSRV $PIDFILE + start_rtadvd $RUMPSRV1_2 $PIDFILE1_2 + sleep $WAITTIME + + check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX + check_entries $RUMPCLI $RUMPSRV1_2 $IP6SRV_PREFIX + + export RUMP_SERVER=$RUMPCLI + # One prefix is advertised by differnt two routers + n=$(rump.ndp -p |grep 'advertised by' |wc -l) + atf_check_equal $n 1 + unset RUMP_SERVER + + atf_check -s exit:0 kill -TERM `cat ${PIDFILE}` + wait_term ${PIDFILE} + atf_check -s exit:0 kill -TERM `cat ${PIDFILE1_2}` + wait_term ${PIDFILE1_2} + + rump_server_destroy_ifaces +} + +ra_multiple_routers_single_prefix_cleanup() +{ + + if [ -f ${PIDFILE} ]; then + kill -TERM `cat ${PIDFILE}` + wait_term ${PIDFILE} + fi + if [ -f ${PIDFILE1_2} ]; then + kill -TERM `cat ${PIDFILE1_2}` + wait_term ${PIDFILE1_2} + fi + + $DEBUG && dump + cleanup +} + +atf_test_case ra_multiple_routers_maxifprefixes cleanup +ra_multiple_routers_maxifprefixes_head() +{ + + atf_set "descr" "Tests for exceeding the number of maximum prefixes" + atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig" +} + +ra_multiple_routers_maxifprefixes_body() +{ + local n= + + rump_server_fs_start $RUMPSRV netinet6 + rump_server_fs_start $RUMPSRV3 netinet6 + rump_server_fs_start $RUMPSRV4 netinet6 + rump_server_start $RUMPCLI netinet6 + + setup_shmif0 ${RUMPSRV} ${IP6SRV} + setup_shmif0 ${RUMPSRV3} ${IP6SRV3} + setup_shmif0 ${RUMPSRV4} ${IP6SRV4} + setup_shmif0 ${RUMPCLI} ${IP6CLI} + + init_server $RUMPSRV + init_server $RUMPSRV3 + init_server $RUMPSRV4 + + create_rtadvdconfig + + export RUMP_SERVER=${RUMPCLI} + atf_check -s exit:0 -o match:'0.->.1' \ + rump.sysctl -w net.inet6.ip6.accept_rtadv=1 + # Limit the maximum number of prefix entries to 2 + atf_check -s exit:0 -o match:'16.->.2' \ + rump.sysctl -w net.inet6.ip6.maxifprefixes=2 + unset RUMP_SERVER + + start_rtadvd $RUMPSRV $PIDFILE + start_rtadvd $RUMPSRV3 $PIDFILE3 + sleep $WAITTIME + + check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX + check_entries $RUMPCLI $RUMPSRV3 $IP6SRV3_PREFIX + + start_rtadvd $RUMPSRV4 $PIDFILE4 + sleep $WAITTIME + + export RUMP_SERVER=${RUMPCLI} + $DEBUG && dump_entries + # There should remain two prefixes + n=$(rump.ndp -p |grep 'advertised by' |wc -l) + atf_check_equal $n 2 + # TODO check other conditions + unset RUMP_SERVER + + atf_check -s exit:0 kill -TERM `cat ${PIDFILE}` + wait_term ${PIDFILE} + atf_check -s exit:0 kill -TERM `cat ${PIDFILE3}` + wait_term ${PIDFILE3} + atf_check -s exit:0 kill -TERM `cat ${PIDFILE4}` + wait_term ${PIDFILE4} + + rump_server_destroy_ifaces +} + +ra_multiple_routers_maxifprefixes_cleanup() +{ + + if [ -f ${PIDFILE} ]; then + kill -TERM `cat ${PIDFILE}` + wait_term ${PIDFILE} + fi + if [ -f ${PIDFILE3} ]; then + kill -TERM `cat ${PIDFILE3}` + wait_term ${PIDFILE3} + fi + if [ -f ${PIDFILE4} ]; then + kill -TERM `cat ${PIDFILE4}` + wait_term ${PIDFILE4} + fi + + $DEBUG && dump + cleanup +} + +atf_test_case ra_temporary_address cleanup +ra_temporary_address_head() +{ + + atf_set "descr" "Tests for IPv6 temporary address" + atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig" +} + +check_echo_request_pkt() +{ + local pkt="$2 > $3: .+ echo request" + + extract_new_packets $1 > ./out + $DEBUG && echo $pkt + $DEBUG && cat ./out + atf_check -s exit:0 -o match:"$pkt" cat ./out +} + +ra_temporary_address_body() +{ + local ip_auto= ip_temp= + + rump_server_fs_start $RUMPSRV netinet6 + rump_server_start $RUMPCLI netinet6 + + setup_shmif0 $RUMPSRV $IP6SRV + init_server $RUMPSRV + setup_shmif0 $RUMPCLI $IP6CLI + + export RUMP_SERVER=$RUMPCLI + atf_check -s exit:0 -o match:'0.->.1' \ + rump.sysctl -w net.inet6.ip6.accept_rtadv=1 + atf_check -s exit:0 -o match:'0.->.1' \ + rump.sysctl -w net.inet6.ip6.use_tempaddr=1 + unset RUMP_SERVER + + create_rtadvdconfig + start_rtadvd $RUMPSRV $PIDFILE + sleep $WAITTIME + + check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX + + export RUMP_SERVER=$RUMPCLI + + # Check temporary address + atf_check -s exit:0 \ + -o match:"$IP6SRV_PREFIX.+<(TENTATIVE,)?AUTOCONF,TEMPORARY>" \ + rump.ifconfig shmif0 inet6 + + # + # Testing net.inet6.ip6.prefer_tempaddr + # + atf_check -s exit:0 rump.ifconfig -w 10 + $DEBUG && rump.ifconfig shmif0 + ip_auto=$(rump.ifconfig shmif0 |awk '// {sub(/\/[0-9]*/, ""); print $2;}') + ip_temp=$(rump.ifconfig shmif0 |awk '// {sub(/\/[0-9]*/, ""); print $2;}') + $DEBUG && echo $ip_auto $ip_temp + + # Ignore old packets + extract_new_packets bus1 > /dev/null + + atf_check -s exit:0 -o ignore rump.ping6 -n -X 2 -c 1 $IP6SRV + # autoconf (non-temporal) address should be used as the source address + check_echo_request_pkt bus1 $ip_auto $IP6SRV + + # Enable net.inet6.ip6.prefer_tempaddr + atf_check -s exit:0 -o match:'0.->.1' \ + rump.sysctl -w net.inet6.ip6.prefer_tempaddr=1 + + atf_check -s exit:0 -o ignore rump.ping6 -n -X 2 -c 1 $IP6SRV + # autoconf, temporal address should be used as the source address + check_echo_request_pkt bus1 $ip_temp $IP6SRV + + unset RUMP_SERVER + + atf_check -s exit:0 kill -TERM `cat ${PIDFILE}` + wait_term $PIDFILE + + rump_server_destroy_ifaces +} + +ra_temporary_address_cleanup() +{ + + if [ -f ${PIDFILE} ]; then + kill -TERM `cat ${PIDFILE}` + wait_term ${PIDFILE} + fi + + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case ra_basic + atf_add_test_case ra_flush_prefix_entries + atf_add_test_case ra_flush_defrouter_entries + atf_add_test_case ra_delete_address + atf_add_test_case ra_multiple_routers + atf_add_test_case ra_multiple_routers_single_prefix + atf_add_test_case ra_multiple_routers_maxifprefixes + atf_add_test_case ra_temporary_address +} diff --git a/contrib/netbsd-tests/net/net/t_forwarding.sh b/contrib/netbsd-tests/net/net/t_forwarding.sh new file mode 100755 index 0000000..fc30530 --- /dev/null +++ b/contrib/netbsd-tests/net/net/t_forwarding.sh @@ -0,0 +1,530 @@ +# $NetBSD: t_forwarding.sh,v 1.19 2016/11/25 08:51:17 ozaki-r Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCKSRC=unix://commsock1 +SOCKFWD=unix://commsock2 +SOCKDST=unix://commsock3 +IP4SRC=10.0.1.2 +IP4SRCGW=10.0.1.1 +IP4DSTGW=10.0.2.1 +IP4DST=10.0.2.2 +IP4DST_BCAST=10.0.2.255 +IP6SRC=fc00:0:0:1::2 +IP6SRCGW=fc00:0:0:1::1 +IP6DSTGW=fc00:0:0:2::1 +IP6DST=fc00:0:0:2::2 +HTML_FILE=index.html + +DEBUG=${DEBUG:-false} +TIMEOUT=5 + +atf_test_case ipforwarding_v4 cleanup +atf_test_case ipforwarding_v6 cleanup +atf_test_case ipforwarding_fastforward_v4 cleanup +atf_test_case ipforwarding_fastforward_v6 cleanup +atf_test_case ipforwarding_misc cleanup + +ipforwarding_v4_head() +{ + atf_set "descr" "Does IPv4 forwarding tests" + atf_set "require.progs" "rump_server" +} + +ipforwarding_v6_head() +{ + atf_set "descr" "Does IPv6 forwarding tests" + atf_set "require.progs" "rump_server" +} + +ipforwarding_fastforward_v4_head() +{ + atf_set "descr" "Tests for IPv4 fastforward" + atf_set "require.progs" "rump_server" +} + +ipforwarding_fastforward_v6_head() +{ + atf_set "descr" "Tests for IPv6 fastfoward" + atf_set "require.progs" "rump_server" +} + +ipforwarding_misc_head() +{ + atf_set "descr" "Does IPv4 forwarding tests" + atf_set "require.progs" "rump_server" +} + +setup_endpoint() +{ + sock=${1} + addr=${2} + bus=${3} + mode=${4} + gw=${5} + + rump_server_add_iface $sock shmif0 $bus + + export RUMP_SERVER=${sock} + if [ $mode = "ipv6" ]; then + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${addr} + atf_check -s exit:0 -o ignore rump.route add -inet6 default ${gw} + else + atf_check -s exit:0 rump.ifconfig shmif0 inet ${addr} netmask 0xffffff00 + atf_check -s exit:0 -o ignore rump.route add default ${gw} + fi + atf_check -s exit:0 rump.ifconfig shmif0 up + + if $DEBUG; then + rump.ifconfig shmif0 + rump.netstat -nr + fi +} + +test_endpoint() +{ + sock=${1} + addr=${2} + bus=${3} + mode=${4} + + export RUMP_SERVER=${sock} + atf_check -s exit:0 -o match:shmif0 rump.ifconfig + if [ $mode = "ipv6" ]; then + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${addr} + else + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 ${addr} + fi +} + +setup_forwarder() +{ + mode=${1} + + rump_server_add_iface $SOCKFWD shmif0 bus1 + rump_server_add_iface $SOCKFWD shmif1 bus2 + + export RUMP_SERVER=$SOCKFWD + + if [ $mode = "ipv6" ]; then + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6SRCGW} + atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${IP6DSTGW} + else + atf_check -s exit:0 rump.ifconfig shmif0 inet ${IP4SRCGW} netmask 0xffffff00 + atf_check -s exit:0 rump.ifconfig shmif1 inet ${IP4DSTGW} netmask 0xffffff00 + fi + + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig shmif1 up + + if $DEBUG; then + rump.netstat -nr + if [ $mode = "ipv6" ]; then + rump.sysctl net.inet6.ip6.forwarding + else + rump.sysctl net.inet.ip.forwarding + fi + fi +} + +setup() +{ + rump_server_start $SOCKSRC + rump_server_start $SOCKFWD + rump_server_start $SOCKDST + + setup_endpoint $SOCKSRC $IP4SRC bus1 ipv4 $IP4SRCGW + setup_endpoint $SOCKDST $IP4DST bus2 ipv4 $IP4DSTGW + setup_forwarder ipv4 +} + +setup6() +{ + rump_server_start $SOCKSRC netinet6 + rump_server_start $SOCKFWD netinet6 + rump_server_start $SOCKDST netinet6 + + setup_endpoint $SOCKSRC $IP6SRC bus1 ipv6 $IP6SRCGW + setup_endpoint $SOCKDST $IP6DST bus2 ipv6 $IP6DSTGW + setup_forwarder ipv6 +} + +test_http_get() +{ + local ip=$1 + + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 rump.arp -d -a + + export RUMP_SERVER=$SOCKSRC + + # get the webpage + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + ftp -q $TIMEOUT -o out http://$ip/$HTML_FILE +} + +test_setup() +{ + test_endpoint $SOCKSRC $IP4SRC bus1 ipv4 + test_endpoint $SOCKDST $IP4DST bus2 ipv4 + + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o match:shmif0 rump.ifconfig + atf_check -s exit:0 -o match:shmif1 rump.ifconfig + + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 ${IP4SRCGW} + atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 ${IP4DSTGW} +} + +test_setup6() +{ + test_endpoint $SOCKSRC $IP6SRC bus1 ipv6 + test_endpoint $SOCKDST $IP6DST bus2 ipv6 + + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o match:shmif0 rump.ifconfig + atf_check -s exit:0 -o match:shmif1 rump.ifconfig + + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${IP6SRCGW} + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${IP6DSTGW} +} + +setup_forwarding() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.forwarding=1 +} + +setup_forwarding6() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet6.ip6.forwarding=1 +} + +setup_directed_broadcast() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.directed-broadcast=1 +} + +setup_icmp_bmcastecho() +{ + export RUMP_SERVER=$SOCKDST + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.icmp.bmcastecho=1 +} + +teardown_forwarding() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.forwarding=0 +} + +teardown_forwarding6() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet6.ip6.forwarding=0 +} + +teardown_directed_broadcast() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.directed-broadcast=0 +} + +teardown_icmp_bmcastecho() +{ + export RUMP_SERVER=$SOCKDST + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.icmp.bmcastecho=0 +} + +teardown_interfaces() +{ + + rump_server_destroy_ifaces +} + +test_setup_forwarding() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o match:"net.inet.ip.forwarding = 1" \ + rump.sysctl net.inet.ip.forwarding +} +test_setup_forwarding6() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o match:"net.inet6.ip6.forwarding = 1" \ + rump.sysctl net.inet6.ip6.forwarding +} + +test_teardown_forwarding() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o match:"net.inet.ip.forwarding = 0" \ + rump.sysctl net.inet.ip.forwarding +} +test_teardown_forwarding6() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o match:"net.inet6.ip6.forwarding = 0" \ + rump.sysctl net.inet6.ip6.forwarding +} + +test_ping_failure() +{ + export RUMP_SERVER=$SOCKSRC + atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4DST + export RUMP_SERVER=$SOCKDST + atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4SRC +} + +test_ping_success() +{ + export RUMP_SERVER=$SOCKSRC + $DEBUG && rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4SRCGW + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4DST + $DEBUG && rump.ifconfig -v shmif0 + + export RUMP_SERVER=$SOCKDST + $DEBUG && rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4DSTGW + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4SRC + $DEBUG && rump.ifconfig -v shmif0 +} + +test_ping_ttl() +{ + export RUMP_SERVER=$SOCKSRC + $DEBUG && rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 -T 1 $IP4SRCGW + atf_check -s not-exit:0 -o match:'Time To Live exceeded' \ + rump.ping -v -n -w $TIMEOUT -c 1 -T 1 $IP4DST + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 -T 2 $IP4DST + $DEBUG && rump.ifconfig -v shmif0 +} + +test_sysctl_ttl() +{ + local ip=$1 + + export RUMP_SERVER=$SOCKSRC + $DEBUG && rump.ifconfig -v shmif0 + + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.ttl=1 + # get the webpage + atf_check -s not-exit:0 -e match:'timed out' \ + env LD_PRELOAD=/usr/lib/librumphijack.so \ + ftp -q $TIMEOUT -o out http://$ip/$HTML_FILE + + + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.ttl=2 + # get the webpage + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + ftp -q $TIMEOUT -o out http://$ip/$HTML_FILE + + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.ttl=64 + $DEBUG && rump.ifconfig -v shmif0 +} + +test_directed_broadcast() +{ + setup_icmp_bmcastecho + + setup_directed_broadcast + export RUMP_SERVER=$SOCKSRC + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4DST_BCAST + + teardown_directed_broadcast + export RUMP_SERVER=$SOCKSRC + atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4DST_BCAST + + teardown_icmp_bmcastecho +} + +test_ping6_failure() +{ + export RUMP_SERVER=$SOCKSRC + atf_check -s not-exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP6DST + export RUMP_SERVER=$SOCKDST + atf_check -s not-exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP6SRC +} + +test_ping6_success() +{ + export RUMP_SERVER=$SOCKSRC + $DEBUG && rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP6SRCGW + atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP6DST + $DEBUG && rump.ifconfig -v shmif0 + + export RUMP_SERVER=$SOCKDST + $DEBUG && rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP6DSTGW + atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP6SRC + $DEBUG && rump.ifconfig -v shmif0 +} + +test_hoplimit() +{ + export RUMP_SERVER=$SOCKSRC + $DEBUG && rump.ifconfig -v shmif0 + atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -h 1 -X $TIMEOUT $IP6SRCGW + atf_check -s not-exit:0 -o match:'Time to live exceeded' \ + rump.ping6 -v -n -c 1 -h 1 -X $TIMEOUT $IP6DST + atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -h 2 -X $TIMEOUT $IP6DST + $DEBUG && rump.ifconfig -v shmif0 +} + +ipforwarding_v4_body() +{ + setup + test_setup + + setup_forwarding + test_setup_forwarding + test_ping_success + + teardown_forwarding + test_teardown_forwarding + test_ping_failure + + teardown_interfaces +} + +ipforwarding_v6_body() +{ + setup6 + test_setup6 + + setup_forwarding6 + test_setup_forwarding6 + test_ping6_success + test_hoplimit + + teardown_forwarding6 + test_teardown_forwarding6 + test_ping6_failure + + teardown_interfaces +} + +ipforwarding_fastforward_v4_body() +{ + setup + test_setup + + setup_forwarding + test_setup_forwarding + + touch $HTML_FILE + start_httpd $SOCKDST $IP4DST + $DEBUG && rump.netstat -a + + test_http_get $IP4DST + + teardown_interfaces +} + +ipforwarding_fastforward_v6_body() +{ + setup6 + test_setup6 + + setup_forwarding6 + test_setup_forwarding6 + + touch $HTML_FILE + start_httpd $SOCKDST $IP6DST + $DEBUG && rump.netstat -a + + test_http_get "[$IP6DST]" + + teardown_interfaces +} + +ipforwarding_misc_body() +{ + setup + test_setup + + setup_forwarding + test_setup_forwarding + + test_ping_ttl + + test_directed_broadcast + + touch $HTML_FILE + start_httpd $SOCKDST $IP4DST + $DEBUG && rump.netstat -a + + test_sysctl_ttl $IP4DST + + teardown_interfaces + return 0 +} + +ipforwarding_v4_cleanup() +{ + $DEBUG && dump + cleanup +} + +ipforwarding_v6_cleanup() +{ + $DEBUG && dump + cleanup +} + +ipforwarding_fastforward_v4_cleanup() +{ + $DEBUG && dump + stop_httpd + cleanup +} + +ipforwarding_fastforward_v6_cleanup() +{ + $DEBUG && dump + stop_httpd + cleanup +} + +ipforwarding_misc_cleanup() +{ + $DEBUG && dump + stop_httpd + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case ipforwarding_v4 + atf_add_test_case ipforwarding_v6 + atf_add_test_case ipforwarding_fastforward_v4 + atf_add_test_case ipforwarding_fastforward_v6 + atf_add_test_case ipforwarding_misc +} diff --git a/contrib/netbsd-tests/net/net/t_ipaddress.sh b/contrib/netbsd-tests/net/net/t_ipaddress.sh new file mode 100755 index 0000000..4cdd954 --- /dev/null +++ b/contrib/netbsd-tests/net/net/t_ipaddress.sh @@ -0,0 +1,193 @@ +# $NetBSD: t_ipaddress.sh,v 1.9 2016/12/15 02:43:56 ozaki-r Exp $ +# +# Copyright (c) 2015 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCK_LOCAL=unix://commsock1 +BUS=bus + +DEBUG=${DEBUG:-false} + +test_same_address() +{ + local ip=10.0.0.1 + local net=10.0.0/24 + + rump_server_start $SOCK_LOCAL + rump_server_add_iface $SOCK_LOCAL shmif0 $BUS + + export RUMP_SERVER=$SOCK_LOCAL + + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 $ip/24 + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + + $DEBUG && rump.netstat -nr -f inet + + check_route $ip 'link#2' UHl lo0 + check_route $net 'link#2' UC shmif0 + + # Delete the address + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 $ip delete + + $DEBUG && rump.netstat -nr -f inet + + check_route_no_entry $ip + check_route_no_entry $net + + # Assign the same address again + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 $ip/24 + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + + $DEBUG && rump.netstat -nr -f inet + + check_route $ip 'link#2' UHl lo0 + check_route $net 'link#2' UC shmif0 + + # Delete the address again + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 $ip delete + + $DEBUG && rump.netstat -nr -f inet + + check_route_no_entry $ip + check_route_no_entry $net + + rump_server_destroy_ifaces +} + +test_same_address6() +{ + local ip=fc00::1 + local net=fc00::/64 + + rump_server_start $SOCK_LOCAL netinet6 + rump_server_add_iface $SOCK_LOCAL shmif0 $BUS + + export RUMP_SERVER=$SOCK_LOCAL + + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 $ip + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + + $DEBUG && rump.netstat -nr -f inet6 + + check_route $ip 'link#2' UHl lo0 + check_route $net 'link#2' UC shmif0 + + # Delete the address + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 $ip delete + + $DEBUG && rump.netstat -nr -f inet6 + + check_route_no_entry $ip + check_route_no_entry $net + + # Assign the same address again + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 $ip + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + + $DEBUG && rump.netstat -nr -f inet6 + + check_route $ip 'link#2' UHl lo0 + check_route $net 'link#2' UC shmif0 + + # Delete the address again + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 $ip delete + + $DEBUG && rump.netstat -nr -f inet6 + + check_route_no_entry $ip + check_route_no_entry $net + + rump_server_destroy_ifaces +} + +test_auto_linklocal() +{ + + rump_server_start $SOCK_LOCAL netinet6 + rump_server_add_iface $SOCK_LOCAL shmif0 $BUS + + export RUMP_SERVER=$SOCK_LOCAL + + # + # Test enabled auto linklocal + # + + # Check default value + atf_check -s exit:0 -o match:"1" rump.sysctl -n net.inet6.ip6.auto_linklocal + + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + + $DEBUG && rump.netstat -nr -f inet + + # IPv6 link-local address is set + atf_check -s exit:0 -o match:"inet6 fe80::" rump.ifconfig shmif0 + + # + # Test disabled auto linklocal + # + atf_check -s exit:0 -o ignore rump.sysctl -w -q net.inet6.ip6.auto_linklocal=0 + + rump_server_add_iface $SOCK_LOCAL shmif1 $BUS + atf_check -s exit:0 -o ignore rump.ifconfig shmif1 up + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + + $DEBUG && rump.netstat -nr -f inet + + # IPv6 link-local address is not set + atf_check -s exit:0 -o not-match:"inet6 fe80::" rump.ifconfig shmif1 + + rump_server_destroy_ifaces +} + +add_test() +{ + local name=$1 + local desc="$2" + + atf_test_case "ipaddr_${name}" cleanup + eval "ipaddr_${name}_head() { \ + atf_set \"descr\" \"${desc}\"; \ + atf_set \"require.progs\" \"rump_server\"; \ + }; \ + ipaddr_${name}_body() { \ + test_${name}; \ + }; \ + ipaddr_${name}_cleanup() { \ + $DEBUG && dump; \ + cleanup; \ + }" + atf_add_test_case "ipaddr_${name}" +} + +atf_init_test_cases() +{ + + add_test same_address "Assigning/deleting an IP address twice" + add_test same_address6 "Assigning/deleting an IPv6 address twice" + add_test auto_linklocal "Assigning an IPv6 link-local address automatically" +} diff --git a/contrib/netbsd-tests/net/net/t_ipv6_lifetime.sh b/contrib/netbsd-tests/net/net/t_ipv6_lifetime.sh new file mode 100755 index 0000000..10e50fd --- /dev/null +++ b/contrib/netbsd-tests/net/net/t_ipv6_lifetime.sh @@ -0,0 +1,127 @@ +# $NetBSD: t_ipv6_lifetime.sh,v 1.6 2016/11/25 08:51:17 ozaki-r Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCK=unix://sock +BUS=./bus + +DEBUG=${DEBUG:-false} + +deprecated="[Dd][Ee][Pp][Rr][Ee][Cc][Aa][Tt][Ee][Dd]" + +atf_test_case basic cleanup + +basic_head() +{ + atf_set "descr" "Tests for IPv6 address lifetime" + atf_set "require.progs" "rump_server" +} + +basic_body() +{ + local time=5 + local bonus=2 + local ip="fc00::1" + + rump_server_start $SOCK netinet6 + rump_server_add_iface $SOCK shmif0 $BUS + + export RUMP_SERVER=$SOCK + + atf_check -s exit:0 rump.ifconfig shmif0 up + + # A normal IP address doesn't contain preferred/valid lifetime + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip + $DEBUG && rump.ifconfig -L shmif0 + atf_check -s exit:0 -o not-match:'pltime' rump.ifconfig -L shmif0 + atf_check -s exit:0 -o not-match:'vltime' rump.ifconfig -L shmif0 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip delete + + # Setting only a preferred lifetime + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip pltime $time + $DEBUG && rump.ifconfig -L shmif0 + atf_check -s exit:0 -o match:'pltime' rump.ifconfig -L shmif0 + atf_check -s exit:0 -o match:'vltime infty' rump.ifconfig -L shmif0 + atf_check -s exit:0 sleep $(($time + $bonus)) + $DEBUG && rump.ifconfig -L shmif0 + # Should remain but marked as deprecated + atf_check -s exit:0 -o match:"$ip.+$deprecated" rump.ifconfig -L shmif0 + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip delete + + # Setting only a valid lifetime (invalid) + atf_check -s not-exit:0 -e match:'Invalid argument' \ + rump.ifconfig shmif0 inet6 $ip vltime $time + + # Setting both preferred and valid lifetimes (same value) + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip \ + pltime $time vltime $time + $DEBUG && rump.ifconfig -L shmif0 + atf_check -s exit:0 -o match:'pltime' rump.ifconfig -L shmif0 + atf_check -s exit:0 -o match:'vltime' rump.ifconfig -L shmif0 + atf_check -s exit:0 sleep $(($time + $bonus)) + $DEBUG && rump.ifconfig -L shmif0 + # Shouldn't remain anymore + atf_check -s exit:0 -o not-match:"$ip" rump.ifconfig -L shmif0 + + # Setting both preferred and valid lifetimes (pltime > vltime) + atf_check -s not-exit:0 -e match:'Invalid argument' rump.ifconfig \ + shmif0 inet6 $ip pltime $(($time * 2)) vltime $time + + # Setting both preferred and valid lifetimes (pltime < vltime) + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip \ + pltime $time vltime $((time * 2)) + $DEBUG && rump.ifconfig -L shmif0 + atf_check -s exit:0 -o match:'pltime' rump.ifconfig -L shmif0 + atf_check -s exit:0 -o match:'vltime' rump.ifconfig -L shmif0 + + if sysctl machdep.cpu_brand 2>/dev/null | grep QEMU >/dev/null 2>&1 + then + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip delete + atf_skip "unreliable under qemu, skip until PR kern/43997 fixed" + fi + + atf_check -s exit:0 sleep $(($time + $bonus)) + $DEBUG && rump.ifconfig -L shmif0 + # Should remain but marked as deprecated + atf_check -s exit:0 -o match:"$ip.+$deprecated" rump.ifconfig -L shmif0 + atf_check -s exit:0 sleep $(($time + $bonus)) + $DEBUG && rump.ifconfig -L shmif0 + # Shouldn't remain anymore + atf_check -s exit:0 -o not-match:"$ip" rump.ifconfig -L shmif0 + + rump_server_destroy_ifaces +} + +basic_cleanup() +{ + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/net/net/t_ipv6address.sh b/contrib/netbsd-tests/net/net/t_ipv6address.sh new file mode 100755 index 0000000..539a16d --- /dev/null +++ b/contrib/netbsd-tests/net/net/t_ipv6address.sh @@ -0,0 +1,387 @@ +# $NetBSD: t_ipv6address.sh,v 1.12 2016/12/14 02:50:42 ozaki-r Exp $ +# +# Copyright (c) 2015 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + +SERVER="rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet" +SERVER="${SERVER} -lrumpnet_shmif -lrumpdev" +SERVER6="${SERVER} -lrumpnet_netinet6" + +SOCKSRC=unix://commsock1 +SOCKFWD=unix://commsock2 +SOCKDST=unix://commsock3 +IP6SRCNW=fc00:1::0/64 +IP6SRC=fc00:1::1 +IP6DSTNW=fc00:2::0/64 +IP6DST=fc00:2::1 +IP6FWD0=fc00:3::1 +BUS1=bus1 +BUS2=bus2 +BUSSRC=bus_src +BUSDST=bus_dst + +DEBUG=${DEBUG:-true} +TIMEOUT=3 + +atf_test_case linklocal cleanup +atf_test_case linklocal_ops cleanup + +setup() +{ + atf_check -s exit:0 ${SERVER6} ${SOCKSRC} + atf_check -s exit:0 ${SERVER6} ${SOCKFWD} + atf_check -s exit:0 ${SERVER6} ${SOCKDST} + + export RUMP_SERVER=${SOCKSRC} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif1 create + unset RUMP_SERVER + + export RUMP_SERVER=${SOCKDST} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif1 create + unset RUMP_SERVER + + export RUMP_SERVER=${SOCKFWD} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 -o match:"0 -> 1" rump.sysctl \ + -w net.inet6.ip6.forwarding=1 + unset RUMP_SERVER + + setup_ifcfg + + export RUMP_SERVER=${SOCKSRC} + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -rn -f inet6 + unset RUMP_SERVER + + export RUMP_SERVER=${SOCKDST} + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -rn -f inet6 + unset RUMP_SERVER + + export RUMP_SERVER=${SOCKFWD} + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -rn -f inet6 + unset RUMP_SERVER +} +setup_ifcfg() +{ + export RUMP_SERVER=${SOCKSRC} + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ${BUS1} + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ${BUSSRC} + atf_check -s exit:0 rump.ifconfig shmif1 up + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + unset RUMP_SERVER + + export RUMP_SERVER=${SOCKDST} + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ${BUS2} + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ${BUSDST} + atf_check -s exit:0 rump.ifconfig shmif1 up + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + unset RUMP_SERVER + + export RUMP_SERVER=${SOCKFWD} + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ${BUS1} + atf_check -s exit:0 rump.ifconfig shmif0 up + + atf_check -s exit:0 rump.ifconfig shmif1 linkstr ${BUS2} + atf_check -s exit:0 rump.ifconfig shmif1 up + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + unset RUMP_SERVER +} + +setup_route() +{ + local tmp_rump_server=$RUMP_SERVER + + local src_if0_lladdr=`get_linklocal_addr ${SOCKSRC} shmif0` + local dst_if0_lladdr=`get_linklocal_addr ${SOCKDST} shmif0` + local fwd_if0_lladdr=`get_linklocal_addr ${SOCKFWD} shmif0` + local fwd_if1_lladdr=`get_linklocal_addr ${SOCKFWD} shmif1` + + export RUMP_SERVER=${SOCKSRC} + atf_check -s ignore -o ignore -e ignore \ + rump.route delete -inet6 default ${fwd_if0_lladdr}%shmif0 + atf_check -s exit:0 -o match:"add net default:" \ + rump.route add -inet6 default ${fwd_if0_lladdr}%shmif0 + atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${IP6SRC} + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + $DEBUG && rump.netstat -rn -f inet6 + unset RUMP_SERVER + + export RUMP_SERVER=${SOCKDST} + atf_check -s ignore -o ignore -e ignore \ + rump.route delete -inet6 default ${fwd_if1_lladdr}%shmif0 + atf_check -s exit:0 -o match:"add net default:" \ + rump.route add -inet6 default ${fwd_if1_lladdr}%shmif0 + atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${IP6DST} + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + $DEBUG && rump.netstat -rn -f inet6 + unset RUMP_SERVER + + export RUMP_SERVER=${SOCKFWD} + atf_check -s ignore -o ignore -e ignore \ + rump.route delete -inet6 ${IP6SRCNW} ${src_if0_lladdr}%shmif0 + atf_check -s exit:0 -o match:"add net" \ + rump.route add -inet6 ${IP6SRCNW} ${src_if0_lladdr}%shmif0 + + atf_check -s ignore -o ignore -e ignore \ + rump.route delete -inet6 ${IP6DSTNW} ${dst_if0_lladdr}%shmif1 + atf_check -s exit:0 -o match:"add net" \ + rump.route add -inet6 ${IP6DSTNW} ${dst_if0_lladdr}%shmif1 + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + $DEBUG && rump.netstat -rn -f inet6 + unset RUMP_SERVER + + export RUMP_SERVER=$tmp_rump_server +} + +cleanup_bus() +{ + local tmp_rump_server=$RUMP_SERVER + + $DEBUG && dump_bus + + export RUMP_SERVER=${SOCKSRC} + atf_check -s exit:0 rump.ifconfig shmif0 down + atf_check -s exit:0 rump.ifconfig shmif0 -linkstr + atf_check -s exit:0 rump.ifconfig shmif1 down + atf_check -s exit:0 rump.ifconfig shmif1 -linkstr + unset RUMP_SERVER + + export RUMP_SERVER=${SOCKDST} + atf_check -s exit:0 rump.ifconfig shmif0 down + atf_check -s exit:0 rump.ifconfig shmif0 -linkstr + atf_check -s exit:0 rump.ifconfig shmif1 down + atf_check -s exit:0 rump.ifconfig shmif1 -linkstr + unset RUMP_SERVER + + export RUMP_SERVER=${SOCKFWD} + atf_check -s exit:0 rump.ifconfig shmif0 down + atf_check -s exit:0 rump.ifconfig shmif0 -linkstr + atf_check -s exit:0 rump.ifconfig shmif1 down + atf_check -s exit:0 rump.ifconfig shmif1 -linkstr + unset RUMP_SERVER + + atf_check -s exit:0 rm ${BUSSRC} + atf_check -s exit:0 rm ${BUSDST} + atf_check -s exit:0 rm ${BUS1} + atf_check -s exit:0 rm ${BUS2} + + setup_ifcfg + + export RUMP_SERVER=$tmp_rump_server +} + +cleanup_rump_servers() +{ + + env RUMP_SERVER=${SOCKSRC} rump.halt + env RUMP_SERVER=${SOCKDST} rump.halt + env RUMP_SERVER=${SOCKFWD} rump.halt +} + +dump_bus() +{ + + shmif_dumpbus -p - ${BUSSRC} 2>/dev/null| tcpdump -n -e -r - + shmif_dumpbus -p - ${BUSDST} 2>/dev/null| tcpdump -n -e -r - + shmif_dumpbus -p - ${BUS1} 2>/dev/null| tcpdump -n -e -r - + shmif_dumpbus -p - ${BUS2} 2>/dev/null| tcpdump -n -e -r - +} + +_dump() +{ + + export RUMP_SERVER=${SOCKSRC} + rump.ndp -n -a + rump.netstat -nr -f inet6 + export RUMP_SERVER=${SOCKDST} + rump.ndp -n -a + rump.netstat -nr -f inet6 + export RUMP_SERVER=${SOCKFWD} + rump.ndp -n -a + rump.netstat -nr -f inet6 + unset RUMP_SERVER +} + +linklocal_head() +{ + atf_set "descr" \ + "Test for bassically function of the IPv6 linklocal address" + atf_set "require.progs" \ + "rump_server rump.route rump.ifconfig rump.ping6" +} + +linklocal_body() +{ + setup + + local src_if0_lladdr=`get_linklocal_addr ${SOCKSRC} shmif0` + local src_if1_lladdr=`get_linklocal_addr ${SOCKSRC} shmif1` + local dst_if0_lladdr=`get_linklocal_addr ${SOCKDST} shmif0` + local fwd_if0_lladdr=`get_linklocal_addr ${SOCKFWD} shmif0` + local fwd_if1_lladdr=`get_linklocal_addr ${SOCKFWD} shmif1` + + export RUMP_SERVER=${SOCKSRC} + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -rn -f inet6 + + # link local address to link local address + + atf_check -s not-exit:0 -e match:"No route to host" \ + rump.ping6 -c 1 -X $TIMEOUT -n ${fwd_if0_lladdr} + + atf_check -s exit:0 -o match:"0.0% packet loss" \ + rump.ping6 -c 1 -X $TIMEOUT -n ${fwd_if0_lladdr}%shmif0 + + atf_check -s ignore -o empty -e ignore \ + -x "shmif_dumpbus -p - ${BUSSRC} | tcpdump -r - -n -p icmp6" + atf_check -s ignore -o not-empty -e ignore \ + -x "shmif_dumpbus -p - ${BUS1} | tcpdump -r - -n -p icmp6" + + cleanup_bus + + atf_check -s not-exit:0 -o ignore -e ignore \ + rump.ping6 -c 1 -X $TIMEOUT -n -S ${src_if1_lladdr}%shmif1 \ + ${fwd_if0_lladdr}%shmif0 + atf_check -s ignore -o not-match:"${src_if1_lladdr}" -e ignore \ + -x "shmif_dumpbus -p - ${BUS1} | tcpdump -r - -n -p icmp6" + $DEBUG && shmif_dumpbus -p - ${BUS1} | tcpdump -r - -n -p icmp6 + unset RUMP_SERVER + + # link local address to host address + export RUMP_SERVER=${SOCKFWD} + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6FWD0} + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + unset RUMP_SERVER + + export RUMP_SERVER=${SOCKSRC} + atf_check -s exit:0 -o match:"add net default:" \ + rump.route add -inet6 default ${fwd_if0_lladdr}%shmif0 + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig shmif0 + $DEBUG && _dump + + export RUMP_SERVER=${SOCKSRC} + atf_check -s exit:0 -o match:"0.0% packet loss" \ + rump.ping6 -c 1 -X $TIMEOUT -n -S ${src_if0_lladdr}%shmif0 ${IP6FWD0} + unset RUMP_SERVER + + export RUMP_SERVER=${SOCKFWD} + # host address to link local address + atf_check -s exit:0 -o match:"0.0% packet loss" \ + rump.ping6 -c 1 -X $TIMEOUT -n ${src_if0_lladdr}%shmif0 + atf_check -s not-exit:0 -o match:"100.0% packet loss" \ + rump.ping6 -c 1 -X $TIMEOUT -n ${src_if1_lladdr}%shmif0 + + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6FWD0} delete + + unset RUMP_SERVER + + # forwarding with link local address + setup_route + + export RUMP_SERVER=${SOCKSRC} + atf_check -s exit:0 -o match:"0.0% packet loss" rump.ping6 -c 1 \ + -X $TIMEOUT -n -S ${IP6SRC} ${IP6DST} + + cleanup_bus + $DEBUG && rump.ifconfig shmif0 + atf_check -s not-exit:0 -o match:"100.0% packet loss" rump.ping6 -c 1 \ + -X $TIMEOUT -n -S ${src_if0_lladdr}%shmif0 ${IP6DST} + atf_check -s ignore -o not-match:"${src_if0_lladdr}" -e ignore \ + -x "shmif_dumpbus -p - ${BUS2} | tcpdump -r - -n -p icmp6" + + cleanup_bus + atf_check -s not-exit:0 -o match:"100.0% packet loss" rump.ping6 -c 1 \ + -X $TIMEOUT -n -S ${IP6SRC} ${dst_if0_lladdr}%shmif0 + atf_check -s ignore -o not-empty -e ignore \ + -x "shmif_dumpbus -p - ${BUS2} | tcpdump -r - -n -p icmp6" + + unset RUMP_SERVER + +} + +linklocal_cleanup() +{ + + $DEBUG && _dump + $DEBUG && dump_bus + cleanup_rump_servers +} + +linklocal_ops_head() +{ + + atf_set "descr" \ + "Test for various operations to IPv6 linklocal addresses" + atf_set "require.progs" "rump_server rump.route rump.ndp" +} + +linklocal_ops_body() +{ + local src_if0_lladdr= + + setup + + src_if0_lladdr=`get_linklocal_addr ${SOCKSRC} shmif0` + + export RUMP_SERVER=${SOCKSRC} + + # route get + atf_check -s exit:0 -o match:"${src_if0_lladdr}" \ + rump.route get -inet6 ${src_if0_lladdr}%shmif0 + + # route get without an interface name (zone index) + atf_check -s not-exit:0 -e match:"not in table" \ + rump.route get -inet6 ${src_if0_lladdr} + + # ndp + atf_check -s exit:0 -o match:"${src_if0_lladdr}" \ + rump.ndp -n ${src_if0_lladdr}%shmif0 + + # ndp without an interface name (zone index) + atf_check -s not-exit:0 -o ignore -e match:"no entry" \ + rump.ndp -n ${src_if0_lladdr} +} + + +linklocal_ops_cleanup() +{ + + cleanup_rump_servers +} + +atf_init_test_cases() +{ + + atf_add_test_case linklocal + atf_add_test_case linklocal_ops +} diff --git a/contrib/netbsd-tests/net/net/t_mtudisc.sh b/contrib/netbsd-tests/net/net/t_mtudisc.sh new file mode 100755 index 0000000..a99d652 --- /dev/null +++ b/contrib/netbsd-tests/net/net/t_mtudisc.sh @@ -0,0 +1,192 @@ +# $NetBSD: t_mtudisc.sh,v 1.8 2016/12/21 01:16:18 ozaki-r Exp $ +# +# Copyright (c) 2016 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCKLOCAL=unix://commsock1 +SOCKGATEWAY=unix://commsock2 +SOCKREMOTE=unix://commsock3 +HTML_FILE=index.html + +DEBUG=${DEBUG:-false} + +atf_test_case mtudisc_basic cleanup + +mtudisc_basic_head() +{ + atf_set "descr" "Tests for IPv4 Path MTU Dicorvery basic behavior" + atf_set "require.progs" "rump_server" +} + +setup_server() +{ + local sock=$1 + local if=$2 + local bus=$3 + local ip=$4 + + rump_server_add_iface $sock $if $bus + + export RUMP_SERVER=$sock + atf_check -s exit:0 rump.ifconfig $if $ip + atf_check -s exit:0 rump.ifconfig $if up + atf_check -s exit:0 rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig $if +} + +prepare_download_file() +{ + local file=$1 + local data="0123456789" + + touch $file + for i in `seq 1 512` + do + echo $data >> $file + done +} + +do_http_get() +{ + local ip=$1 + local ret=$2 + local timeout=5 + + # get the webpage + atf_check -s exit:$ret env LD_PRELOAD=/usr/lib/librumphijack.so \ + ftp -q $timeout -o ./out http://$ip/$HTML_FILE +} + +mtudisc_basic_body() +{ + local pkt= + local local_ip=10.0.0.2 + local gateway_local_ip=10.0.0.1 + local gateway_remote_ip=10.0.1.1 + local remote_ip=10.0.1.2 + local prefixlen=24 + + rump_server_start $SOCKLOCAL + rump_server_start $SOCKGATEWAY + rump_server_start $SOCKREMOTE + + # + # Setup servers + # + # [local server] [gateway server] [remote server with httpd] + # | 10.0.0.2 10.0.0.1 | | 10.0.1.1 10.0.1.2 | + # shmif0(mtu=1500) ----- shmif1(mtu=1280) shmif0(mtu=1500) ----- shmif0(mtu=1500) + # + + # Assign IP addresses + setup_server $SOCKLOCAL shmif0 bus1 $local_ip/$prefixlen + setup_server $SOCKGATEWAY shmif0 bus1 $gateway_local_ip/$prefixlen + setup_server $SOCKGATEWAY shmif1 bus2 $gateway_remote_ip/$prefixlen + setup_server $SOCKREMOTE shmif0 bus2 $remote_ip/$prefixlen + + ### Setup gateway server + export RUMP_SERVER=$SOCKGATEWAY + + # Set mtu of shmif0 to 1280 + export RUMP_SERVER=$SOCKGATEWAY + atf_check -s exit:0 rump.ifconfig shmif0 mtu 1280 + + # Enable IPv4 forwarding + atf_check -s exit:0 rump.sysctl -w -q net.inet.ip.forwarding=1 + + ### Setup remote server + export RUMP_SERVER=$SOCKREMOTE + + # Check default value + atf_check -s exit:0 -o match:"1" rump.sysctl -n net.inet.ip.mtudisc + + # Start httpd daemon + prepare_download_file $HTML_FILE + start_httpd $SOCKREMOTE $remote_ip + $DEBUG && rump.netstat -a -f inet + + # Teach the peer thar 10.0.0.2(local serer) is behind 10.0.1.1(gateway server) + atf_check -s exit:0 -o ignore rump.route add $local_ip/32 $gateway_remote_ip + + ### Setup local server + export RUMP_SERVER=$SOCKLOCAL + + # Teach the peer thar 10.0.1.2(remote serer) is behind 10.0.0.1(gateway server) + atf_check -s exit:0 -o ignore rump.route add $remote_ip/32 $gateway_local_ip + + # Don't accept fragmented packets + atf_check -s exit:0 -o ignore rump.sysctl -w -q net.inet.ip.maxfragpackets=0 + + # + # Test disabled path mtu discorvery + # + export RUMP_SERVER=$SOCKREMOTE + atf_check -s exit:0 -o ignore rump.sysctl -w -q net.inet.ip.mtudisc=0 + + # Get the webpage (expect: failed) + export RUMP_SERVER=$SOCKLOCAL + do_http_get $remote_ip 1 + $DEBUG && extract_new_packets bus2 > ./out + $DEBUG && cat ./out + + # Check path mtu size on remote server + export RUMP_SERVER=$SOCKREMOTE + atf_check -s exit:0 \ + -o match:"^10.0.0.2 +10.0.1.1 +UGHS +- +- +- +shmif0" \ + rump.netstat -nr -f inet + + # + # Test enabled path mtu discorvery + # + export RUMP_SERVER=$SOCKREMOTE + atf_check -s exit:0 -o ignore rump.sysctl -w -q net.inet.ip.mtudisc=1 + + # Get the webpage (expect: success) + export RUMP_SERVER=$SOCKLOCAL + do_http_get $remote_ip 0 + $DEBUG && extract_new_packets bus2 > ./out + $DEBUG && cat ./out + + # Check path mtu size on remote server + export RUMP_SERVER=$SOCKREMOTE + atf_check -s exit:0 \ + -o match:"^10.0.0.2 +10.0.1.1 +UGHS +- +- +1280 +shmif0" \ + rump.netstat -nr -f inet + + rump_server_destroy_ifaces +} + +mtudisc_basic_cleanup() +{ + $DEBUG && dump + stop_httpd + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case mtudisc_basic +} diff --git a/contrib/netbsd-tests/net/net/t_mtudisc6.sh b/contrib/netbsd-tests/net/net/t_mtudisc6.sh new file mode 100755 index 0000000..93bc12e --- /dev/null +++ b/contrib/netbsd-tests/net/net/t_mtudisc6.sh @@ -0,0 +1,179 @@ +# $NetBSD: t_mtudisc6.sh,v 1.5 2016/11/25 08:51:17 ozaki-r Exp $ +# +# Copyright (c) 2016 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCKLOCAL=unix://commsock1 +SOCKGATEWAY=unix://commsock2 +SOCKREMOTE=unix://commsock3 +HTML_FILE=index.html + +DEBUG=${DEBUG:-false} + +atf_test_case mtudisc6_basic cleanup + +mtudisc6_basic_head() +{ + + atf_set "descr" "Tests for IPv6 Path MTU Dicorvery basic behavior" + atf_set "require.progs" "rump_server" +} + +setup_server() +{ + local sock=$1 + local if=$2 + local bus=$3 + local ip=$4 + + rump_server_add_iface $sock $if $bus + + export RUMP_SERVER=$sock + atf_check -s exit:0 rump.ifconfig $if inet6 $ip + atf_check -s exit:0 rump.ifconfig $if up + atf_check -s exit:0 rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig $if +} + +prepare_download_file() +{ + local file=$1 + local data="0123456789" + + touch $file + for i in `seq 1 512` + do + echo $data >> $file + done +} + +do_http_get() +{ + local ip=$1 + local ret=$2 + local timeout=5 + + # get the webpage + atf_check -s exit:$ret env LD_PRELOAD=/usr/lib/librumphijack.so \ + ftp -q $timeout -o ./out "http://[$ip]/$HTML_FILE" +} + +mtudisc6_basic_body() +{ + local pkt= + local local_ip=fc00:0:0:1::2 + local gateway_local_ip=fc00:0:0:1::1 + local gateway_remote_ip=fc00:0:0:2::1 + local remote_ip=fc00:0:0:2::2 + local prefixlen=64 + + rump_server_start $SOCKLOCAL netinet6 + rump_server_start $SOCKGATEWAY netinet6 + rump_server_start $SOCKREMOTE netinet6 + + # + # Setup servers + # + # [local server] [gateway server] [remote server] + # | | | | + # shmif0(1500) -- shmif1(1280) shmif0(1500) -- shmif0(1500) + # + + # Assign IP addresses + setup_server $SOCKLOCAL shmif0 bus1 $local_ip/$prefixlen + setup_server $SOCKGATEWAY shmif0 bus1 $gateway_local_ip/$prefixlen + setup_server $SOCKGATEWAY shmif1 bus2 $gateway_remote_ip/$prefixlen + setup_server $SOCKREMOTE shmif0 bus2 $remote_ip/$prefixlen + + ### Setup gateway server + export RUMP_SERVER=$SOCKGATEWAY + + # Set MTU of shmif0 to 1280 + export RUMP_SERVER=$SOCKGATEWAY + atf_check -s exit:0 rump.ifconfig shmif0 mtu 1280 + + # Enable IPv6 forwarding + atf_check -s exit:0 rump.sysctl -w -q net.inet6.ip6.forwarding=1 + + ### Setup remote server + export RUMP_SERVER=$SOCKREMOTE + + # Start httpd daemon + prepare_download_file $HTML_FILE + start_httpd $SOCKREMOTE $remote_ip + $DEBUG && rump.netstat -a + + # Teach the peer that local serer is behind gateway server + atf_check -s exit:0 -o ignore \ + rump.route add -inet6 $local_ip/128 $gateway_remote_ip + + # Check path MTU size on remote server + atf_check -s exit:0 \ + -o match:"^$local_ip +$gateway_remote_ip +UGHS +- +- +- +shmif0" \ + rump.netstat -nr -f inet6 + + ### Setup local server + export RUMP_SERVER=$SOCKLOCAL + + # Teach the peer that remote serer is behind gateway server + atf_check -s exit:0 -o ignore \ + rump.route add -inet6 $remote_ip/128 $gateway_local_ip + + # Don't accept fragmented packets + atf_check -s exit:0 -o ignore \ + rump.sysctl -w -q net.inet6.ip6.maxfragpackets=0 + + # + # Test enabled path MTU discorvery + # + # Get the webpage (expect: success) + export RUMP_SERVER=$SOCKLOCAL + do_http_get $remote_ip 0 + $DEBUG && extract_new_packets bus2 > ./out + $DEBUG && cat ./out + + # Check path MTU size on remote server + export RUMP_SERVER=$SOCKREMOTE + atf_check -s exit:0 \ + -o match:"^$local_ip +$gateway_remote_ip +UGHS +- +- +1280 +shmif0" \ + rump.netstat -nr -f inet6 + + rump_server_destroy_ifaces +} + +mtudisc6_basic_cleanup() +{ + + $DEBUG && dump + stop_httpd + cleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case mtudisc6_basic +} diff --git a/contrib/netbsd-tests/net/net/t_ping6_opts.sh b/contrib/netbsd-tests/net/net/t_ping6_opts.sh new file mode 100755 index 0000000..e2e774e --- /dev/null +++ b/contrib/netbsd-tests/net/net/t_ping6_opts.sh @@ -0,0 +1,380 @@ +# $NetBSD: t_ping6_opts.sh,v 1.8 2016/11/25 08:51:17 ozaki-r Exp $ +# +# Copyright (c) 2016 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCKSRC=unix://commsock1 +SOCKFWD=unix://commsock2 +SOCKDST=unix://commsock3 +IP6SRC=fc00:0:0:1::2 +IP6SRCGW=fc00:0:0:1::1 +IP6DSTGW=fc00:0:0:2::1 +IP6DST=fc00:0:0:2::2 +BUS_SRCGW=bus1 +BUS_DSTGW=bus2 + +IP6SRC2=fc00:0:0:1::3 +IP6SRCGW2=fc00:0:0:1::254 + +DEBUG=${DEBUG:-false} +TIMEOUT=1 + +# +# Utility functions +# +setup_endpoint() +{ + local sock=${1} + local addr=${2} + local bus=${3} + local gw=${4} + + rump_server_add_iface $sock shmif0 $bus + + export RUMP_SERVER=${sock} + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${addr} + atf_check -s exit:0 -o ignore rump.route add -inet6 default ${gw} + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + if $DEBUG; then + rump.ifconfig shmif0 + rump.netstat -nr + fi +} + +setup_forwarder() +{ + + rump_server_add_iface $SOCKFWD shmif0 $BUS_SRCGW + rump_server_add_iface $SOCKFWD shmif1 $BUS_DSTGW + + export RUMP_SERVER=$SOCKFWD + + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6SRCGW} + atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${IP6DSTGW} + + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig shmif1 up + atf_check -s exit:0 rump.ifconfig -w 10 + + if $DEBUG; then + rump.netstat -nr + rump.sysctl net.inet6.ip6.forwarding + fi +} + +setup_forwarding6() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet6.ip6.forwarding=1 +} + +setup6() +{ + + rump_server_start $SOCKSRC netinet6 + rump_server_start $SOCKFWD netinet6 + rump_server_start $SOCKDST netinet6 + + setup_endpoint $SOCKSRC $IP6SRC $BUS_SRCGW $IP6SRCGW + setup_endpoint $SOCKDST $IP6DST $BUS_DSTGW $IP6DSTGW + setup_forwarder +} + +check_echo_request_pkt() +{ + local pkt="$1 > $2: .+ echo request" + + extract_new_packets $BUS_SRCGW > ./out + $DEBUG && echo $pkt + $DEBUG && cat ./out + atf_check -s exit:0 -o match:"$pkt" cat ./out +} + +check_echo_request_pkt_with_macaddr() +{ + local pkt="$1 > $2, .+ $3 > $4: .+ echo request" + + extract_new_packets $BUS_SRCGW > ./out + $DEBUG && echo $pkt + $DEBUG && cat ./out + atf_check -s exit:0 -o match:"$pkt" cat ./out +} + +check_echo_request_pkt_with_macaddr_and_rthdr0() +{ + local pkt= + + pkt="$1 > $2, .+ $3 > $4:" + pkt="$pkt srcrt \\(len=2, type=0, segleft=1, \\[0\\]$5\\)" + pkt="$pkt .+ echo request" + + extract_new_packets $BUS_SRCGW > ./out + $DEBUG && echo $pkt + $DEBUG && cat ./out + atf_check -s exit:0 -o match:"$pkt" cat ./out +} + +# +# Tests +# +atf_test_case ping6_opts_sourceaddr cleanup +ping6_opts_sourceaddr_head() +{ + + atf_set "descr" "tests of ping6 -S option" + atf_set "require.progs" "rump_server" +} + +ping6_opts_sourceaddr_body() +{ + + setup6 + setup_forwarding6 + + export RUMP_SERVER=$SOCKSRC + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6DST + check_echo_request_pkt $IP6SRC $IP6DST + + atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6SRC2 + atf_check -s exit:0 rump.ifconfig -w 10 + + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6DST + check_echo_request_pkt $IP6SRC $IP6DST + + # ping6 -S + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \ + -S $IP6SRC $IP6DST + check_echo_request_pkt $IP6SRC $IP6DST + + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \ + -S $IP6SRC2 $IP6DST + check_echo_request_pkt $IP6SRC2 $IP6DST + + rump_server_destroy_ifaces +} + +ping6_opts_sourceaddr_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_test_case ping6_opts_interface cleanup +ping6_opts_interface_head() +{ + + atf_set "descr" "tests of ping6 -I option" + atf_set "require.progs" "rump_server" +} + +ping6_opts_interface_body() +{ + local shmif0_lladdr= + local shmif1_lladdr= + local gw_lladdr= + + setup6 + setup_forwarding6 + + shmif0_lladdr=$(get_linklocal_addr ${SOCKSRC} shmif0) + gw_lladdr=$(get_linklocal_addr ${SOCKFWD} shmif0) + + export RUMP_SERVER=$SOCKSRC + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $gw_lladdr + check_echo_request_pkt $shmif0_lladdr $gw_lladdr + + rump_server_add_iface $SOCKSRC shmif1 $BUS_SRCGW + atf_check -s exit:0 rump.ifconfig shmif1 up + atf_check -s exit:0 rump.ifconfig -w 10 + shmif1_lladdr=$(get_linklocal_addr ${SOCKSRC} shmif1) + + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $gw_lladdr + check_echo_request_pkt $shmif0_lladdr $gw_lladdr + + # ping6 -I + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \ + -I shmif0 $gw_lladdr + check_echo_request_pkt $shmif0_lladdr $gw_lladdr + + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \ + -I shmif1 $gw_lladdr + check_echo_request_pkt $shmif1_lladdr $gw_lladdr + + rump_server_destroy_ifaces +} + +ping6_opts_interface_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_test_case ping6_opts_gateway cleanup +ping6_opts_gateway_head() +{ + + atf_set "descr" "tests of ping6 -g option" + atf_set "require.progs" "rump_server" +} + +ping6_opts_gateway_body() +{ + local my_macaddr= + local gw_shmif0_macaddr= + local gw_shmif2_macaddr= + + setup6 + setup_forwarding6 + + my_macaddr=$(get_macaddr ${SOCKSRC} shmif0) + gw_shmif0_macaddr=$(get_macaddr ${SOCKFWD} shmif0) + + export RUMP_SERVER=$SOCKSRC + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6DST + check_echo_request_pkt_with_macaddr \ + $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6DST + + rump_server_add_iface $SOCKFWD shmif2 $BUS_SRCGW + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 rump.ifconfig shmif2 inet6 $IP6SRCGW2 + atf_check -s exit:0 rump.ifconfig -w 10 + gw_shmif2_macaddr=$(get_macaddr ${SOCKFWD} shmif2) + + export RUMP_SERVER=$SOCKSRC + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6DST + check_echo_request_pkt_with_macaddr \ + $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6DST + + # ping6 -g + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \ + -g $IP6SRCGW $IP6DST + check_echo_request_pkt_with_macaddr \ + $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6DST + + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \ + -g $IP6SRCGW2 $IP6DST + check_echo_request_pkt_with_macaddr \ + $my_macaddr $gw_shmif2_macaddr $IP6SRC $IP6DST + + rump_server_destroy_ifaces +} + +ping6_opts_gateway_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_test_case ping6_opts_hops cleanup +ping6_opts_hops_head() +{ + + atf_set "descr" "tests of ping6 hops (Type 0 Routing Header)" + atf_set "require.progs" "rump_server" +} + +ping6_opts_hops_body() +{ + local my_macaddr= + local gw_shmif0_macaddr= + local gw_shmif2_macaddr= + + setup6 + setup_forwarding6 + + my_macaddr=$(get_macaddr ${SOCKSRC} shmif0) + gw_shmif0_macaddr=$(get_macaddr ${SOCKFWD} shmif0) + + export RUMP_SERVER=$SOCKSRC + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6DST + check_echo_request_pkt_with_macaddr \ + $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6DST + + rump_server_add_iface $SOCKFWD shmif2 $BUS_SRCGW + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 rump.ifconfig shmif2 inet6 $IP6SRCGW2 + atf_check -s exit:0 rump.ifconfig -w 10 + gw_shmif2_macaddr=$(get_macaddr ${SOCKFWD} shmif2) + + export RUMP_SERVER=$SOCKSRC + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6DST + check_echo_request_pkt_with_macaddr \ + $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6DST + + # ping6 hops + + # ping6 fails expectedly because the kernel doesn't support + # to receive packets with type 0 routing headers, but we can + # check whether a sent packet is correct. + atf_check -s not-exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \ + $IP6SRCGW $IP6DST + check_echo_request_pkt_with_macaddr_and_rthdr0 \ + $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6SRCGW $IP6DST + + atf_check -s not-exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \ + $IP6SRCGW2 $IP6DST + check_echo_request_pkt_with_macaddr_and_rthdr0 \ + $my_macaddr $gw_shmif2_macaddr $IP6SRC $IP6SRCGW2 $IP6DST + + # ping6 -g hops + atf_check -s not-exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \ + -g $IP6SRCGW $IP6SRCGW $IP6DST + check_echo_request_pkt_with_macaddr_and_rthdr0 \ + $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6SRCGW $IP6DST + + atf_check -s not-exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \ + -g $IP6SRCGW2 $IP6SRCGW2 $IP6DST + check_echo_request_pkt_with_macaddr_and_rthdr0 \ + $my_macaddr $gw_shmif2_macaddr $IP6SRC $IP6SRCGW2 $IP6DST + + # ping6 -g hops, but different nexthops (is it valid?) + atf_check -s not-exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \ + -g $IP6SRCGW $IP6SRCGW2 $IP6DST + check_echo_request_pkt_with_macaddr_and_rthdr0 \ + $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6SRCGW2 $IP6DST + + rump_server_destroy_ifaces +} + +ping6_opts_hops_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case ping6_opts_sourceaddr + atf_add_test_case ping6_opts_interface + atf_add_test_case ping6_opts_gateway + atf_add_test_case ping6_opts_hops +} diff --git a/contrib/netbsd-tests/net/net/t_pktinfo.c b/contrib/netbsd-tests/net/net/t_pktinfo.c new file mode 100644 index 0000000..326f9f6 --- /dev/null +++ b/contrib/netbsd-tests/net/net/t_pktinfo.c @@ -0,0 +1,194 @@ +/* $NetBSD: t_pktinfo.c,v 1.2 2013/10/19 17:45:01 christos Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_pktinfo.c,v 1.2 2013/10/19 17:45:01 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char traffic[] = "foo"; + +#ifdef TEST +#include +#define ERR(msg) err(EXIT_FAILURE, msg) +#define ERRX(msg, a) errx(EXIT_FAILURE, msg, a) +#define ERRX2(msg, a1, a2) errx(EXIT_FAILURE, msg, a1, a2) +#else +#include +#define ERR(msg) ATF_REQUIRE_MSG(0, "%s: %s", msg, strerror(errno)) +#define ERRX(msg, a) ATF_REQUIRE_MSG(0, msg, a) +#define ERRX2(msg, a1, a2) ATF_REQUIRE_MSG(0, msg, a1, a2) +#endif + +static int +server(struct sockaddr_in *sin) { + int s, one; + socklen_t len = sizeof(*sin); + + if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + ERR("socket"); + + memset(sin, 0, len); + sin->sin_family = AF_INET; + sin->sin_len = len; + sin->sin_port = 0; + sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + if (bind(s, (const struct sockaddr *)sin, len) == -1) + ERR("bind"); + + if (getsockname(s, (struct sockaddr *)sin, &len) == -1) + ERR("getsockname"); + + one = 1; + if (setsockopt(s, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one)) == -1) + ERR("setsockopt"); + if (setsockopt(s, IPPROTO_IP, IP_RECVPKTINFO, &one, sizeof(one)) == -1) + ERR("setsockopt"); + + return s; +} + +static int +client(struct sockaddr_in *sin) { + int s; + + if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + ERR("socket"); + if (sendto(s, traffic, sizeof(traffic), 0, + (const struct sockaddr *)sin, sizeof(*sin)) == -1) + ERR("sendto"); + return s; +} + +static void +receive(int s) { + struct msghdr msg; + struct cmsghdr *cmsg; + struct iovec iov; + char buf[sizeof(traffic)]; + struct in_pktinfo *ipi; + char control[CMSG_SPACE(sizeof(*ipi)) * 2]; + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + memset(&iov, 0, sizeof(iov)); + iov.iov_base = buf; + iov.iov_len = sizeof(buf); + msg.msg_iovlen = 1; + msg.msg_control = control; + msg.msg_controllen = sizeof(control); + msg.msg_flags = 0; + + if (recvmsg(s, &msg, 0) == -1) + ERR("recvmsg"); + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level != IPPROTO_IP) + ERRX("bad level %d", cmsg->cmsg_level); + const char *m; + switch (cmsg->cmsg_type) { + case IP_PKTINFO: + m = "pktinfo"; + break; + case IP_RECVPKTINFO: + m = "recvpktinfo"; + break; + default: + m = NULL; + ERRX("bad type %d", cmsg->cmsg_type); + } + ipi = (void *)CMSG_DATA(cmsg); +#ifdef TEST + printf("%s message received on address %s at interface %d\n", + m, inet_ntoa(ipi->ipi_addr), ipi->ipi_ifindex); +#else + __USE(m); + ATF_REQUIRE_MSG(ipi->ipi_addr.s_addr == htonl(INADDR_LOOPBACK), + "address 0x%x != 0x%x", ipi->ipi_addr.s_addr, + htonl(INADDR_LOOPBACK)); +#endif + } + + if (strcmp(traffic, buf) != 0) + ERRX2("Bad message '%s' != '%s'", buf, traffic); +} + +static void +doit(void) +{ + struct sockaddr_in sin; + int s, c; + s = server(&sin); + c = client(&sin); + receive(s); + close(s); + close(c); +} + +#ifndef TEST +ATF_TC(pktinfo); +ATF_TC_HEAD(pktinfo, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that IP_PKTINFO and " + "IP_RECVPKTINFO work"); +} + +ATF_TC_BODY(pktinfo, tc) +{ + doit(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, pktinfo); + return atf_no_error(); +} +#else + +int +main(int argc, char *argv[]) { + doit(); + return 0; +} +#endif diff --git a/contrib/netbsd-tests/net/net/t_raw.c b/contrib/netbsd-tests/net/net/t_raw.c new file mode 100644 index 0000000..5c483a1 --- /dev/null +++ b/contrib/netbsd-tests/net/net/t_raw.c @@ -0,0 +1,41 @@ +/* $NetBSD: t_raw.c,v 1.2 2017/01/13 21:30:42 christos Exp $ */ + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(PRU_SENSE); +ATF_TC_HEAD(PRU_SENSE, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Biglock leak with PRU_SENSE on " + "raw sockets (PR kern/44369)"); +} + +ATF_TC_BODY(PRU_SENSE, tc) +{ + struct stat sb; + int s; + + rump_init(); + RL(s = rump_sys_socket(PF_ROUTE, SOCK_RAW, 0)); + /* call PRU_SENSE. unfixed bug causes panic in rump_unschedule() */ + RL(rump_sys_fstat(s, &sb)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, PRU_SENSE); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/net/t_tcp.c b/contrib/netbsd-tests/net/net/t_tcp.c new file mode 100644 index 0000000..fd1f1e9 --- /dev/null +++ b/contrib/netbsd-tests/net/net/t_tcp.c @@ -0,0 +1,227 @@ +/* $NetBSD: t_tcp.c,v 1.4 2016/03/04 18:52:01 christos Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#ifdef __RCSID +__RCSID("$Id: t_tcp.c,v 1.4 2016/03/04 18:52:01 christos Exp $"); +#endif + +/* Example code. Should block; does with accept not paccept. */ +/* Original by: Justin Cormack */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef TEST +#define FAIL(msg, ...) err(EXIT_FAILURE, msg, ## __VA_ARGS__) +#else +#include +#define FAIL(msg, ...) ATF_CHECK_MSG(0, msg, ## __VA_ARGS__); goto fail +#endif + +#ifdef __linux__ +#define paccept(a, b, c, d, e) accept4((a), (b), (c), (e)) +#endif + +static void +ding(int al) +{ +} + +static void +paccept_block(bool pacceptblock, bool fcntlblock) +{ + int srvr = -1, clnt = -1, as = -1; + int ok, fl; + ssize_t n; + char buf[10]; + struct sockaddr_in sin, ba; + struct sigaction sa; + + srvr = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); + if (srvr == -1) + FAIL("socket"); + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; +#ifdef BSD4_4 + sin.sin_len = sizeof(sin); +#endif + sin.sin_port = htons(0); + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + ok = bind(srvr, (const struct sockaddr *)&sin, (socklen_t)sizeof(sin)); + if (ok == -1) + FAIL("bind"); + + socklen_t addrlen = sizeof(struct sockaddr_in); + ok = getsockname(srvr, (struct sockaddr *)&ba, &addrlen); + if (ok == -1) + FAIL("getsockname"); + + ok = listen(srvr, SOMAXCONN); + if (ok == -1) + FAIL("listen"); + + clnt = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); + if (clnt == -1) + FAIL("socket"); + + /* may not connect first time */ + ok = connect(clnt, (struct sockaddr *) &ba, addrlen); + if (ok != -1 || errno != EINPROGRESS) + FAIL("expected connect to fail"); + as = paccept(srvr, NULL, NULL, NULL, pacceptblock ? 0 : SOCK_NONBLOCK); + ok = connect(clnt, (struct sockaddr *) &ba, addrlen); + if (ok == -1 && errno != EISCONN) + FAIL("connect failed"); + +#if 0 + fl = fcntl(srvr, F_GETFL, 0); + if (fl == -1) + FAIL("fnctl getfl"); + + ok = fcntl(srvr, F_SETFL, fl & ~O_NONBLOCK); + if (ok == -1) + FAIL("fnctl setfl"); +#endif + + if (as == -1) { /* not true under NetBSD */ + as = paccept(srvr, NULL, NULL, NULL, pacceptblock ? 0 : SOCK_NONBLOCK); + if (as == -1) + FAIL("paccept"); + } + if (fcntlblock) { + fl = fcntl(as, F_GETFL, 0); + if (fl == -1) + FAIL("fnctl"); + if (fl != (O_RDWR|O_NONBLOCK)) + FAIL("fl 0x%x != 0x%x\n", fl, O_RDWR|O_NONBLOCK); + ok = fcntl(as, F_SETFL, fl & ~O_NONBLOCK); + if (ok == -1) + FAIL("fnctl setfl"); + + fl = fcntl(as, F_GETFL, 0); + if (fl & O_NONBLOCK) + FAIL("fl non blocking after reset"); + } + sa.sa_handler = ding; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(SIGALRM, &sa, NULL); + alarm(1); + n = read(as, buf, 10); + + if (pacceptblock || fcntlblock) { + if (n == -1 && errno != EINTR) + FAIL("read"); + } else { + if (n != -1 || errno != EWOULDBLOCK) + FAIL("read"); + } + return; +fail: + close(srvr); + close(clnt); + close(as); +} + +#ifndef TEST + +ATF_TC(paccept_reset_nonblock); +ATF_TC_HEAD(paccept_reset_nonblock, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that paccept(2) resets " + "the non-blocking flag on non-blocking sockets"); +} + +ATF_TC_BODY(paccept_reset_nonblock, tc) +{ + paccept_block(true, false); +} + +ATF_TC(fcntl_reset_nonblock); +ATF_TC_HEAD(fcntl_reset_nonblock, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that fcntl(2) resets " + "the non-blocking flag on non-blocking sockets"); +} + +ATF_TC_BODY(fcntl_reset_nonblock, tc) +{ + paccept_block(false, true); +} + +ATF_TC(paccept_nonblock); +ATF_TC_HEAD(paccept_nonblock, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that fcntl(2) resets " + "the non-blocking flag on non-blocking sockets"); +} + +ATF_TC_BODY(paccept_nonblock, tc) +{ + paccept_block(false, false); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, paccept_reset_nonblock); + ATF_TP_ADD_TC(tp, fcntl_reset_nonblock); + ATF_TP_ADD_TC(tp, paccept_nonblock); + return atf_no_error(); +} +#else +int +main(int argc, char *argv[]) +{ + paccept_block(false); + paccept_block(true); + return 0; +} +#endif diff --git a/contrib/netbsd-tests/net/net/t_udp.c b/contrib/netbsd-tests/net/net/t_udp.c new file mode 100644 index 0000000..db59342 --- /dev/null +++ b/contrib/netbsd-tests/net/net/t_udp.c @@ -0,0 +1,110 @@ +#include +__RCSID("$NetBSD: t_udp.c,v 1.2 2013/01/06 02:22:50 christos Exp $"); + +#include +#include + +#include +#include +#include +#include + +#include + +static const char msg[] = "sendto test"; + +static void +sendit(int family) +{ + struct addrinfo hints; + struct addrinfo *res; + int S, s; + int e; + + /* lookup localhost addr, depending on argv[1] */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + hints.ai_flags = 0; + + e = getaddrinfo("localhost", "9999", &hints, &res); + ATF_REQUIRE_MSG(e == 0, "getaddrinfo AF=%d: %s", family, + gai_strerror(e)); + + /* server socket */ + S = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + ATF_REQUIRE_MSG(S >= 0, "server-socket AF=%d: %s", family, + strerror(errno)); + + e = bind(S, res->ai_addr, res->ai_addrlen); + ATF_REQUIRE_MSG(e == 0, "bind AF=%d: %s", family, + strerror(errno)); + + /* client socket */ + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + ATF_REQUIRE_MSG(s >= 0, "client-socket AF=%d: %s", family, + strerror(errno)); + + /* sendto */ + e = sendto(s, msg, sizeof(msg), 0, res->ai_addr, res->ai_addrlen); + ATF_REQUIRE_MSG(e == sizeof(msg), "sendto(1) AF=%d: %s", family, + strerror(errno)); + + e = sendto(s, msg, sizeof(msg), 0, res->ai_addr, res->ai_addrlen); + ATF_REQUIRE_MSG(e == sizeof(msg), "sendto(2) AF=%d: %s", family, + strerror(errno)); + + /* connect + send */ + e = connect(s, res->ai_addr, res->ai_addrlen); + ATF_REQUIRE_MSG(e == 0, "connect(1) AF=%d: %s", family, + strerror(errno)); + + e = send(s, msg, sizeof(msg), 0); + ATF_REQUIRE_MSG(e == sizeof(msg), "send(1) AF=%d: %s", family, + strerror(errno)); + + e = connect(s, res->ai_addr, res->ai_addrlen); + ATF_REQUIRE_MSG(e == 0, "connect(2) AF=%d: %s", family, + strerror(errno)); + + e = send(s, msg, sizeof(msg), 0); + ATF_REQUIRE_MSG(e == sizeof(msg), "send(2) AF=%d: %s", family, + strerror(errno)); + + close(s); +} + +ATF_TC(udp4_send); +ATF_TC_HEAD(udp4_send, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that inet4 udp send works both" + " for connected and unconnected sockets"); +} + +ATF_TC_BODY(udp4_send, tc) +{ + sendit(AF_INET); +} + +ATF_TC(udp6_send); +ATF_TC_HEAD(udp6_send, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that inet6 udp send works both" + " for connected and unconnected sockets"); +} + +ATF_TC_BODY(udp6_send, tc) +{ + sendit(AF_INET6); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, udp4_send); + ATF_TP_ADD_TC(tp, udp6_send); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/net/net/t_unix.c b/contrib/netbsd-tests/net/net/t_unix.c new file mode 100644 index 0000000..30759f1 --- /dev/null +++ b/contrib/netbsd-tests/net/net/t_unix.c @@ -0,0 +1,328 @@ +/* $NetBSD: t_unix.c,v 1.11 2013/11/13 21:41:23 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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 NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#ifdef __RCSID +__RCSID("$Id: t_unix.c,v 1.11 2013/11/13 21:41:23 christos Exp $"); +#else +#define getprogname() argv[0] +#endif + +#ifdef __linux__ +#define LX -1 +#else +#define LX +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef TEST +#define FAIL(msg, ...) err(EXIT_FAILURE, msg, ## __VA_ARGS__) +#else + +#include +#define FAIL(msg, ...) \ + do { \ + ATF_CHECK_MSG(0, msg, ## __VA_ARGS__); \ + goto fail; \ + } while (/*CONSTCOND*/0) + +#endif + +#define OF offsetof(struct sockaddr_un, sun_path) + +static void +print(const char *msg, struct sockaddr_un *addr, socklen_t len) +{ + size_t i; + + printf("%s: client socket length: %zu\n", msg, (size_t)len); + printf("%s: client family %d\n", msg, addr->sun_family); +#ifdef BSD4_4 + printf("%s: client len %d\n", msg, addr->sun_len); +#endif + printf("%s: socket name: ", msg); + for (i = 0; i < len - OF; i++) { + int ch = addr->sun_path[i]; + if (ch < ' ' || '~' < ch) + printf("\\x%02x", ch); + else + printf("%c", ch); + } + printf("\n"); +} + +static int +acc(int s) +{ + char guard1; + struct sockaddr_un sun; + char guard2; + socklen_t len; + + guard1 = guard2 = 's'; + + memset(&sun, 0, sizeof(sun)); + len = sizeof(sun); + if ((s = accept(s, (struct sockaddr *)&sun, &len)) == -1) + FAIL("accept"); + if (guard1 != 's') + FAIL("guard1 = '%c'", guard1); + if (guard2 != 's') + FAIL("guard2 = '%c'", guard2); +#ifdef DEBUG + print("accept", &sun, len); +#endif + if (len != 2) + FAIL("len %d != 2", len); + if (sun.sun_family != AF_UNIX) + FAIL("sun->sun_family %d != AF_UNIX", sun.sun_family); +#ifdef BSD4_4 + if (sun.sun_len != 2) + FAIL("sun->sun_len %d != 2", sun.sun_len); +#endif + for (size_t i = 0; i < sizeof(sun.sun_path); i++) + if (sun.sun_path[i]) + FAIL("sun.sun_path[%zu] %d != NULL", i, + sun.sun_path[i]); + return s; +fail: + if (s != -1) + close(s); + return -1; +} + +static int +test(bool closeit, size_t len) +{ + size_t slen; + socklen_t sl; + int srvr = -1, clnt = -1, acpt = -1; + struct sockaddr_un *sock_addr = NULL, *sun = NULL; + socklen_t sock_addrlen; + + srvr = socket(AF_UNIX, SOCK_STREAM, 0); + if (srvr == -1) + FAIL("socket(srvrer)"); + + slen = len + OF + 1; + + if ((sun = calloc(1, slen)) == NULL) + FAIL("calloc"); + + srvr = socket(AF_UNIX, SOCK_STREAM, 0); + if (srvr == -1) + FAIL("socket"); + + memset(sun->sun_path, 'a', len); + sun->sun_path[len] = '\0'; + (void)unlink(sun->sun_path); + + sl = SUN_LEN(sun); +#ifdef BSD4_4 + sun->sun_len = sl; +#endif + sun->sun_family = AF_UNIX; + + if (bind(srvr, (struct sockaddr *)sun, sl) == -1) { + if (errno == EINVAL && sl >= 256) { + close(srvr); + return -1; + } + FAIL("bind"); + } + + if (listen(srvr, SOMAXCONN) == -1) + FAIL("listen"); + + clnt = socket(AF_UNIX, SOCK_STREAM, 0); + if (clnt == -1) + FAIL("socket(client)"); + + if (connect(clnt, (const struct sockaddr *)sun, sl) == -1) + FAIL("connect"); + + if (closeit) { + if (close(clnt) == -1) + FAIL("close"); + clnt = -1; + } + + acpt = acc(srvr); +#if 0 + /* + * Both linux and NetBSD return ENOTCONN, why? + */ + if (!closeit) { + socklen_t peer_addrlen; + sockaddr_un peer_addr; + + peer_addrlen = sizeof(peer_addr); + memset(&peer_addr, 0, sizeof(peer_addr)); + if (getpeername(srvr, (struct sockaddr *)&peer_addr, + &peer_addrlen) == -1) + FAIL("getpeername"); + print("peer", &peer_addr, peer_addrlen); + } +#endif + + if ((sock_addr = calloc(1, slen)) == NULL) + FAIL("calloc"); + sock_addrlen = slen; + if (getsockname(srvr, (struct sockaddr *)sock_addr, &sock_addrlen) + == -1) + FAIL("getsockname"); + print("sock", sock_addr, sock_addrlen); + + if (sock_addr->sun_family != AF_UNIX) + FAIL("sock_addr->sun_family %d != AF_UNIX", + sock_addr->sun_family); + + len += OF; + if (sock_addrlen LX != len) + FAIL("sock_addr_len %zu != %zu", (size_t)sock_addrlen, len); +#ifdef BSD4_4 + if (sock_addr->sun_len != sl) + FAIL("sock_addr.sun_len %d != %zu", sock_addr->sun_len, + (size_t)sl); +#endif + for (size_t i = 0; i < slen - OF; i++) + if (sock_addr->sun_path[i] != sun->sun_path[i]) + FAIL("sock_addr.sun_path[%zu] %d != " + "sun->sun_path[%zu] %d\n", i, + sock_addr->sun_path[i], i, sun->sun_path[i]); + + if (acpt != -1) + (void)close(acpt); + if (srvr != -1) + (void)close(srvr); + if (clnt != -1 && !closeit) + (void)close(clnt); + + free(sock_addr); + free(sun); + return 0; +fail: + if (acpt != -1) + (void)close(acpt); + if (srvr != -1) + (void)close(srvr); + if (clnt != -1 && !closeit) + (void)close(clnt); + free(sock_addr); + free(sun); + return -1; +} + +#ifndef TEST + +ATF_TC(sockaddr_un_len_exceed); +ATF_TC_HEAD(sockaddr_un_len_exceed, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that exceeding the size of " + "unix domain sockets does not trash memory or kernel when " + "exceeding the size of the fixed sun_path"); +} + +ATF_TC_BODY(sockaddr_un_len_exceed, tc) +{ + ATF_REQUIRE_MSG(test(false, 254) == -1, "test(false, 254): %s", + strerror(errno)); +} + +ATF_TC(sockaddr_un_len_max); +ATF_TC_HEAD(sockaddr_un_len_max, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that we can use the maximum " + "unix domain socket pathlen (253): 255 - sizeof(sun_len) - " + "sizeof(sun_family)"); +} + +ATF_TC_BODY(sockaddr_un_len_max, tc) +{ + ATF_REQUIRE_MSG(test(false, 253) == 0, "test(false, 253): %s", + strerror(errno)); +} + +ATF_TC(sockaddr_un_closed); +ATF_TC_HEAD(sockaddr_un_closed, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check that we can use the accepted " + "address of unix domain socket when closed"); +} + +ATF_TC_BODY(sockaddr_un_closed, tc) +{ + ATF_REQUIRE_MSG(test(true, 100) == 0, "test(true, 100): %s", + strerror(errno)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sockaddr_un_len_exceed); + ATF_TP_ADD_TC(tp, sockaddr_un_len_max); + ATF_TP_ADD_TC(tp, sockaddr_un_closed); + return atf_no_error(); +} +#else +int +main(int argc, char *argv[]) +{ + size_t len; + + if (argc == 1) { + fprintf(stderr, "Usage: %s \n", getprogname()); + return EXIT_FAILURE; + } + test(false, atoi(argv[1])); + test(true, atoi(argv[1])); +} +#endif diff --git a/contrib/netbsd-tests/net/net_common.sh b/contrib/netbsd-tests/net/net_common.sh new file mode 100755 index 0000000..df21a88 --- /dev/null +++ b/contrib/netbsd-tests/net/net_common.sh @@ -0,0 +1,314 @@ +# $NetBSD: net_common.sh,v 1.11 2017/01/10 05:55:34 ozaki-r Exp $ +# +# Copyright (c) 2016 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# Common utility functions for tests/net +# + +HIJACKING="env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=sysctl=yes" + +extract_new_packets() +{ + local bus=$1 + local old=./.__old + + if [ ! -f $old ]; then + old=/dev/null + fi + + shmif_dumpbus -p - $bus 2>/dev/null| \ + tcpdump -n -e -r - 2>/dev/null > ./.__new + diff -u $old ./.__new |grep '^+' |cut -d '+' -f 2 > ./.__diff + mv -f ./.__new ./.__old + cat ./.__diff +} + +check_route() +{ + local target=$1 + local gw=$2 + local flags=${3:-\.\+} + local ifname=${4:-\.\+} + + target=$(echo $target |sed 's/\./\\./g') + if [ "$gw" = "" ]; then + gw=".+" + else + gw=$(echo $gw |sed 's/\./\\./g') + fi + + atf_check -s exit:0 -e ignore \ + -o match:"^$target +$gw +$flags +- +- +.+ +$ifname" \ + rump.netstat -rn +} + +check_route_flags() +{ + + check_route "$1" "" "$2" "" +} + +check_route_gw() +{ + + check_route "$1" "$2" "" "" +} + +check_route_no_entry() +{ + local target=$(echo $1 |sed 's/\./\\./g') + + atf_check -s exit:0 -e ignore -o not-match:"^$target" \ + rump.netstat -rn +} + +get_linklocal_addr() +{ + + export RUMP_SERVER=${1} + rump.ifconfig ${2} inet6 | + awk "/fe80/ {sub(/%$2/, \"\"); sub(/\\/[0-9]*/, \"\"); print \$2;}" + unset RUMP_SERVER + + return 0 +} + +get_macaddr() +{ + + env RUMP_SERVER=${1} \ + rump.ifconfig ${2} |awk '/address/ {print $2;}' +} + +HTTPD_PID=./.__httpd.pid +start_httpd() +{ + local sock=$1 + local ip=$2 + local backup=$RUMP_SERVER + + export RUMP_SERVER=$sock + + # start httpd in daemon mode + atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \ + /usr/libexec/httpd -P $HTTPD_PID -i $ip -b -s $(pwd) + + export RUMP_SERVER=$backup + + sleep 3 +} + +stop_httpd() +{ + + if [ -f $HTTPD_PID ]; then + kill -9 $(cat $HTTPD_PID) + rm -f $HTTPD_PID + sleep 1 + fi +} + +BASIC_LIBS="-lrumpnet -lrumpnet_net -lrumpnet_netinet \ + -lrumpnet_shmif -lrumpdev" +FS_LIBS="$BASIC_LIBS -lrumpvfs -lrumpfs_ffs" + +# We cannot keep variables between test phases, so need to store in files +_rump_server_socks=./.__socks +_rump_server_ifaces=./.__ifaces +_rump_server_buses=./.__buses + +_rump_server_start_common() +{ + local sock=$1 + local libs= + + shift 1 + libs="$*" + + atf_check -s exit:0 rump_server $libs $sock + + echo $sock >> $_rump_server_socks + $DEBUG && cat $_rump_server_socks +} + +rump_server_start() +{ + local sock=$1 + local _libs= + local libs="$BASIC_LIBS" + + shift 1 + _libs="$*" + + for lib in $_libs; do + libs="$libs -lrumpnet_$lib" + done + + _rump_server_start_common $sock $libs + + return 0 +} + +rump_server_fs_start() +{ + local sock=$1 + local _libs= + local libs="$FS_LIBS" + + shift 1 + _libs="$*" + + for lib in $_libs; do + libs="$libs -lrumpnet_$lib" + done + + _rump_server_start_common $sock $libs + + return 0 +} + +rump_server_add_iface() +{ + local sock=$1 + local ifname=$2 + local bus=$3 + local backup=$RUMP_SERVER + + export RUMP_SERVER=$sock + atf_check -s exit:0 rump.ifconfig $ifname create + atf_check -s exit:0 rump.ifconfig $ifname linkstr $bus + export RUMP_SERVER=$backup + + echo $sock $ifname >> $_rump_server_ifaces + $DEBUG && cat $_rump_server_ifaces + + echo $bus >> $_rump_server_buses + cat $_rump_server_buses |sort -u >./.__tmp + mv -f ./.__tmp $_rump_server_buses + $DEBUG && cat $_rump_server_buses + + return 0 +} + +rump_server_destroy_ifaces() +{ + local backup=$RUMP_SERVER + + $DEBUG && cat $_rump_server_ifaces + + # Try to dump states before destroying interfaces + for sock in $(cat $_rump_server_socks); do + export RUMP_SERVER=$sock + atf_check -s exit:0 -o ignore rump.ifconfig + atf_check -s exit:0 -o ignore rump.netstat -nr + # XXX still need hijacking + atf_check -s exit:0 -o ignore $HIJACKING rump.netstat -i -a + atf_check -s exit:0 -o ignore rump.arp -na + atf_check -s exit:0 -o ignore rump.ndp -na + atf_check -s exit:0 -o ignore $HIJACKING ifmcstat + done + + # XXX using pipe doesn't work. See PR bin/51667 + #cat $_rump_server_ifaces | while read sock ifname; do + while read sock ifname; do + export RUMP_SERVER=$sock + if rump.ifconfig -l |grep -q $ifname; then + atf_check -s exit:0 rump.ifconfig $ifname destroy + fi + atf_check -s exit:0 -o ignore rump.ifconfig + done < $_rump_server_ifaces + export RUMP_SERVER=$backup + + return 0 +} + +rump_server_halt_servers() +{ + local backup=$RUMP_SERVER + + $DEBUG && cat $_rump_server_socks + for sock in $(cat $_rump_server_socks); do + env RUMP_SERVER=$sock rump.halt + done + export RUMP_SERVER=$backup + + return 0 +} + +rump_server_dump_servers() +{ + local backup=$RUMP_SERVER + + $DEBUG && cat $_rump_server_socks + for sock in $(cat $_rump_server_socks); do + echo "### Dumping $sock" + export RUMP_SERVER=$sock + rump.ifconfig + rump.netstat -nr + # XXX still need hijacking + $HIJACKING rump.netstat -i -a + rump.arp -na + rump.ndp -na + $HIJACKING ifmcstat + $HIJACKING dmesg + done + export RUMP_SERVER=$backup + + if [ -f rump_server.core ]; then + gdb -ex bt /usr/bin/rump_server rump_server.core + strings rump_server.core |grep panic + fi + return 0 +} + +rump_server_dump_buses() +{ + + if [ ! -f $_rump_server_buses ]; then + return 0 + fi + + $DEBUG && cat $_rump_server_buses + for bus in $(cat $_rump_server_buses); do + echo "### Dumping $bus" + shmif_dumpbus -p - $bus 2>/dev/null| tcpdump -n -e -r - + done + return 0 +} + +cleanup() +{ + + rump_server_halt_servers +} + +dump() +{ + + rump_server_dump_servers + rump_server_dump_buses +} diff --git a/contrib/netbsd-tests/net/npf/t_npf.sh b/contrib/netbsd-tests/net/npf/t_npf.sh new file mode 100755 index 0000000..bf247fc --- /dev/null +++ b/contrib/netbsd-tests/net/npf/t_npf.sh @@ -0,0 +1,63 @@ +# $NetBSD: t_npf.sh,v 1.2 2012/09/18 08:28:15 martin Exp $ +# +# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +run_test() +{ + local name="${1}" + + atf_check -o ignore -e ignore npfctl debug "$(atf_get_srcdir)/npftest.conf" ./npf.plist + atf_check -o ignore npftest -c npf.plist -T "${name}" +} + +add_test() +{ + local name="${1}"; shift + local desc="${*}"; + + atf_test_case "npf_${name}" + eval "npf_${name}_head() { \ + atf_set \"descr\" \"${desc}\"; \ + atf_set \"require.progs\" \"npfctl npftest\"; \ + }; \ + npf_${name}_body() { \ + run_test \"${name}\"; \ + }" + atf_add_test_case "npf_${name}" +} + +atf_init_test_cases() +{ + LIST=/tmp/t_npf.$$ + trap "rm -f $LIST" EXIT + + sh -ec 'npftest -L || printf "dummy\tnone\n"' > $LIST 2>/dev/null + + while read tag desc + do + add_test "${tag}" "${desc}" + done < $LIST +} diff --git a/contrib/netbsd-tests/net/route/t_change.sh b/contrib/netbsd-tests/net/route/t_change.sh new file mode 100755 index 0000000..260cad0 --- /dev/null +++ b/contrib/netbsd-tests/net/route/t_change.sh @@ -0,0 +1,304 @@ +# $NetBSD: t_change.sh,v 1.9 2016/11/07 05:25:37 ozaki-r Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +netserver=\ +"rump_server -lrumpdev -lrumpnet -lrumpnet_net \ + -lrumpnet_netinet -lrumpnet_shmif" +export RUMP_SERVER=unix://commsock + +DEBUG=${DEBUG:-false} + +atf_test_case route_change_reject2blackhole cleanup +route_change_reject2blackhole_head() +{ + + atf_set "descr" "Change a reject route to blackhole" + atf_set "require.progs" "rump_server" +} + +route_change_reject2blackhole_body() +{ + + atf_check -s exit:0 ${netserver} ${RUMP_SERVER} + + atf_check -s exit:0 -o ignore \ + rump.route add 207.46.197.32 127.0.0.1 -reject + atf_check -s exit:0 -o match:UGHR -x \ + "rump.route -n show -inet | grep ^207.46" + atf_check -s exit:0 -o ignore \ + rump.route change 207.46.197.32 127.0.0.1 -blackhole + atf_check -s exit:0 -o match:' UGHBS ' -e ignore -x \ + "rump.netstat -rn -f inet | grep ^207.46" +} + +route_change_reject2blackhole_cleanup() +{ + + env RUMP_SERVER=unix://commsock rump.halt +} + +atf_test_case route_change_gateway cleanup +route_change_gateway_head() +{ + + atf_set "descr" "Change the gateway of a route" + atf_set "require.progs" "rump_server" +} + +route_change_gateway_body() +{ + + atf_check -s exit:0 ${netserver} ${RUMP_SERVER} + + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus + atf_check -s exit:0 rump.ifconfig shmif0 10.0.0.10/24 up + + atf_check -s exit:0 -o ignore \ + rump.route add -net 192.168.0.0/24 10.0.0.1 + atf_check -s exit:0 -o match:'10.0.0.1' -x \ + "rump.route -n show -inet | grep ^192.168" + atf_check -s exit:0 -o ignore \ + rump.route change -net 192.168.0.0/24 10.0.0.254 + atf_check -s exit:0 -o match:'10.0.0.254' -x \ + "rump.route -n show -inet | grep ^192.168" +} + +route_change_gateway_cleanup() +{ + + env RUMP_SERVER=unix://commsock rump.halt +} + +atf_test_case route_change_ifa cleanup +route_change_ifa_head() +{ + + atf_set "descr" "Change the ifa (local address) of a route" + atf_set "require.progs" "rump_server" +} + +route_change_ifa_body() +{ + + atf_check -s exit:0 ${netserver} ${RUMP_SERVER} + + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus + atf_check -s exit:0 rump.ifconfig shmif0 10.0.0.10/24 + atf_check -s exit:0 rump.ifconfig shmif0 alias 10.0.0.11/24 + atf_check -s exit:0 rump.ifconfig shmif0 up + + atf_check -s exit:0 -o ignore \ + rump.route add -net 192.168.0.0/24 10.0.0.1 + atf_check -s exit:0 -o match:'10.0.0.1' -x \ + "rump.route -n show -inet | grep ^192.168" + $DEBUG && rump.route -n show -inet + cat >./expect <<-EOF + route to: 192.168.0.1 +destination: 192.168.0.0 + mask: 255.255.255.0 + gateway: 10.0.0.1 + local addr: 10.0.0.10 + interface: shmif0 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get 192.168.0.1 > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output + + # Change the local address of the route + atf_check -s exit:0 -o ignore \ + rump.route change -net 192.168.0.0/24 10.0.0.1 -ifa 10.0.0.11 + $DEBUG && rump.route -n show -inet + cat >./expect <<-EOF + route to: 192.168.0.1 +destination: 192.168.0.0 + mask: 255.255.255.0 + gateway: 10.0.0.1 + local addr: 10.0.0.11 + interface: shmif0 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get 192.168.0.1 > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output +} + +route_change_ifa_cleanup() +{ + + env RUMP_SERVER=unix://commsock rump.halt +} + +atf_test_case route_change_ifp cleanup +route_change_ifp_head() +{ + + atf_set "descr" "Change a route based on an interface (ifp)" + atf_set "require.progs" "rump_server" +} + +route_change_ifp_body() +{ + + atf_check -s exit:0 ${netserver} ${RUMP_SERVER} + + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus + atf_check -s exit:0 rump.ifconfig shmif0 10.0.0.10/24 up + + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr bus + atf_check -s exit:0 rump.ifconfig shmif1 10.0.0.11/24 up + + atf_check -s exit:0 -o ignore \ + rump.route add -net 192.168.0.0/24 10.0.0.1 + atf_check -s exit:0 -o match:'10.0.0.1' -x \ + "rump.route -n show -inet | grep ^192.168" + $DEBUG && rump.route -n show -inet + cat >./expect <<-EOF + route to: 192.168.0.1 +destination: 192.168.0.0 + mask: 255.255.255.0 + gateway: 10.0.0.1 + local addr: 10.0.0.10 + interface: shmif0 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get 192.168.0.1 > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output + + # Change a route based on an interface + atf_check -s exit:0 -o ignore \ + rump.route change -net 192.168.0.0/24 10.0.0.1 -ifp shmif1 + $DEBUG && rump.route -n show -inet + cat >./expect <<-EOF + route to: 192.168.0.1 +destination: 192.168.0.0 + mask: 255.255.255.0 + gateway: 10.0.0.1 + local addr: 10.0.0.11 + interface: shmif1 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get 192.168.0.1 > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output +} + +route_change_ifp_cleanup() +{ + + env RUMP_SERVER=unix://commsock rump.halt +} + +atf_test_case route_change_ifp_ifa cleanup +route_change_ifp_head() +{ + + atf_set "descr" "Change a route with -ifp and -ifa" + atf_set "require.progs" "rump_server" +} + +route_change_ifp_ifa_body() +{ + + atf_check -s exit:0 ${netserver} ${RUMP_SERVER} + + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus + atf_check -s exit:0 rump.ifconfig shmif0 10.0.0.10/24 up + + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr bus + atf_check -s exit:0 rump.ifconfig shmif1 10.0.0.11/24 up + + atf_check -s exit:0 -o ignore \ + rump.route add -net 192.168.0.0/24 10.0.0.1 + atf_check -s exit:0 -o match:'10.0.0.1' -x \ + "rump.route -n show -inet | grep ^192.168" + $DEBUG && rump.route -n show -inet + cat >./expect <<-EOF + route to: 192.168.0.1 +destination: 192.168.0.0 + mask: 255.255.255.0 + gateway: 10.0.0.1 + local addr: 10.0.0.10 + interface: shmif0 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get 192.168.0.1 > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output + + # Change a route with -ifa and -ifp + atf_check -s exit:0 -o ignore \ + rump.route change -net 192.168.0.0/24 -ifa 10.0.0.1 -ifp shmif1 + $DEBUG && rump.route -n show -inet + cat >./expect <<-EOF + route to: 192.168.0.1 +destination: 192.168.0.0 + mask: 255.255.255.0 + gateway: 10.0.0.1 + local addr: 10.0.0.11 + interface: shmif1 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get 192.168.0.1 > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output +} + +route_change_ifp_ifa_cleanup() +{ + + env RUMP_SERVER=unix://commsock rump.halt +} + +atf_init_test_cases() +{ + + atf_add_test_case route_change_reject2blackhole + atf_add_test_case route_change_gateway + atf_add_test_case route_change_ifa + atf_add_test_case route_change_ifp + atf_add_test_case route_change_ifp_ifa +} diff --git a/contrib/netbsd-tests/net/route/t_flags.sh b/contrib/netbsd-tests/net/route/t_flags.sh new file mode 100755 index 0000000..457e3f5 --- /dev/null +++ b/contrib/netbsd-tests/net/route/t_flags.sh @@ -0,0 +1,334 @@ +# $NetBSD: t_flags.sh,v 1.15 2016/12/21 02:46:08 ozaki-r Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCK_LOCAL=unix://commsock1 +SOCK_PEER=unix://commsock2 +SOCK_GW=unix://commsock3 +BUS=bus1 +BUS2=bus2 + +DEBUG=${DEBUG:-false} + +setup_local() +{ + + rump_server_start $SOCK_LOCAL + rump_server_add_iface $SOCK_LOCAL shmif0 $BUS + + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 10.0.0.2/24 + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -rn -f inet +} + +setup_peer() +{ + + rump_server_start $SOCK_PEER + rump_server_add_iface $SOCK_PEER shmif0 $BUS + + export RUMP_SERVER=$SOCK_PEER + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 10.0.0.1/24 + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -rn -f inet +} + +setup_gw() +{ + + rump_server_start $SOCK_GW + rump_server_add_iface $SOCK_GW shmif0 $BUS + rump_server_add_iface $SOCK_GW shmif1 $BUS2 + + export RUMP_SERVER=$SOCK_GW + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 10.0.0.254/24 + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + + atf_check -s exit:0 -o ignore rump.ifconfig shmif1 10.0.2.1/24 + atf_check -s exit:0 -o ignore rump.ifconfig shmif1 alias 10.0.2.2/24 + atf_check -s exit:0 -o ignore rump.ifconfig shmif1 up + + # Wait until DAD completes (10 sec at most) + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + atf_check -s not-exit:0 -x "rump.ifconfig shmif1 |grep -q tentative" + + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -rn -f inet +} + +test_lo() +{ + + export RUMP_SERVER=$SOCK_LOCAL + + # Up, Host, local + check_route_flags 127.0.0.1 UHl +} + +test_connected() +{ + + export RUMP_SERVER=$SOCK_LOCAL + + # Up, Host, LLINFO, local + check_route_flags 10.0.0.2 UHl + + # Up, Cloning + check_route_flags 10.0.0/24 UC +} + +test_default_gateway() +{ + + export RUMP_SERVER=$SOCK_LOCAL + + atf_check -s exit:0 -o ignore rump.route add default 10.0.0.1 + $DEBUG && rump.netstat -rn -f inet + + # Up, Gateway, Static + check_route_flags default UGS +} + +test_static() +{ + + export RUMP_SERVER=$SOCK_LOCAL + + # Static route to host + atf_check -s exit:0 -o ignore rump.route add 10.0.1.1 10.0.0.1 + $DEBUG && rump.netstat -rn -f inet + + # Up, Gateway, Host, Static + check_route_flags 10.0.1.1 UGHS + + # Static route to network + atf_check -s exit:0 -o ignore rump.route add -net 10.0.2.0/24 10.0.0.1 + $DEBUG && rump.netstat -rn -f inet + + # Up, Gateway, Static + check_route_flags 10.0.2/24 UGS +} + +test_blackhole() +{ + + export RUMP_SERVER=$SOCK_LOCAL + + atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.0.1 + + # Delete an existing route first + atf_check -s exit:0 -o ignore rump.route delete -net 10.0.0.0/24 + + # Gateway must be lo0 + atf_check -s exit:0 -o ignore \ + rump.route add -net 10.0.0.0/24 127.0.0.1 -blackhole + $DEBUG && rump.netstat -rn -f inet + + # Up, Gateway, Blackhole, Static + check_route_flags 10.0.0/24 UGBS + + atf_check -s not-exit:0 -o match:'100.0% packet loss' \ + rump.ping -n -w 1 -c 1 10.0.0.1 + $DEBUG && rump.netstat -rn -f inet + + # Shouldn't be created + check_route_no_entry 10.0.0.1 +} + +test_reject() +{ + + export RUMP_SERVER=$SOCK_LOCAL + + # Delete an existing route first + atf_check -s exit:0 -o ignore rump.route delete -net 10.0.0.0/24 + + atf_check -s exit:0 -o ignore rump.route add -net 10.0.0.0/24 10.0.0.1 -reject + $DEBUG && rump.netstat -rn -f inet + + # Up, Gateway, Reject, Static + check_route_flags 10.0.0/24 UGRS + + atf_check -s not-exit:0 -o ignore -e match:'No route to host' \ + rump.ping -n -w 1 -c 1 10.0.0.1 + $DEBUG && rump.netstat -rn -f inet + + # Shouldn't be created + check_route_no_entry 10.0.0.1 + + # Gateway is lo0 (RTF_GATEWAY) + + # Delete an existing route first + atf_check -s exit:0 -o ignore rump.route delete -net 10.0.0.0/24 + + atf_check -s exit:0 -o ignore \ + rump.route add -net 10.0.0.0/24 127.0.0.1 -reject + $DEBUG && rump.netstat -rn -f inet + + # Up, Gateway, Reject, Static + check_route_flags 10.0.0/24 UGRS + + atf_check -s not-exit:0 -o ignore -e match:'Network is unreachable' \ + rump.ping -n -w 1 -c 1 10.0.0.1 + $DEBUG && rump.netstat -rn -f inet + + # Shouldn't be created + check_route_no_entry 10.0.0.1 + + # Gateway is lo0 (RTF_HOST) + + # Delete an existing route first + atf_check -s exit:0 -o ignore rump.route delete -net 10.0.0.0/24 + + atf_check -s exit:0 -o ignore \ + rump.route add -host 10.0.0.1/24 127.0.0.1 -iface -reject + $DEBUG && rump.netstat -rn -f inet + + # Up, Host, Reject, Static + check_route_flags 10.0.0.1 UHRS + + atf_check -s not-exit:0 -o ignore -e match:'No route to host' \ + rump.ping -n -w 1 -c 1 10.0.0.1 + $DEBUG && rump.netstat -rn -f inet + + return 0 +} + +test_icmp_redirect() +{ + + ### Testing Dynamic flag ### + + # + # Setup a gateway 10.0.0.254. 10.0.2.1 is behind it. + # + setup_gw + + # + # Teach the peer that 10.0.2.* is behind 10.0.0.254 + # + export RUMP_SERVER=$SOCK_PEER + atf_check -s exit:0 -o ignore rump.route add -net 10.0.2.0/24 10.0.0.254 + # Up, Gateway, Static + check_route_flags 10.0.2/24 UGS + + # + # Setup the default gateway to the peer, 10.0.0.1 + # + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 -o ignore rump.route add default 10.0.0.1 + # Up, Gateway, Static + check_route_flags default UGS + + # Try ping 10.0.2.1 + atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.2.1 + $DEBUG && rump.netstat -rn -f inet + + # Up, Gateway, Host, Dynamic + check_route_flags 10.0.2.1 UGHD + check_route_gw 10.0.2.1 10.0.0.254 + + export RUMP_SERVER=$SOCK_PEER + $DEBUG && rump.netstat -rn -f inet + + ### Testing Modified flag ### + + # + # Teach a wrong route to 10.0.2.2 + # + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 -o ignore rump.route add 10.0.2.2 10.0.0.1 + # Up, Gateway, Host, Static + check_route_flags 10.0.2.2 UGHS + check_route_gw 10.0.2.2 10.0.0.1 + + # Try ping 10.0.2.2 + atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.2.2 + $DEBUG && rump.netstat -rn -f inet + + # Up, Gateway, Host, Modified, Static + check_route_flags 10.0.2.2 UGHMS + check_route_gw 10.0.2.2 10.0.0.254 +} + +test_announce() +{ + export RUMP_SERVER=$SOCK_LOCAL + + # Delete an existing route first + atf_check -s exit:0 -o ignore rump.route delete -net 10.0.0.0/24 + + atf_check -s exit:0 -o ignore rump.route add -net 10.0.0.0/24 10.0.0.1 -proxy + $DEBUG && rump.netstat -rn -f inet + + # Up, Gateway, Static, proxy + check_route_flags 10.0.0/24 UGSp + + # TODO test its behavior +} + +add_test() +{ + local name=$1 + local desc="$2" + + atf_test_case "route_flags_${name}" cleanup + eval "route_flags_${name}_head() { \ + atf_set \"descr\" \"${desc}\"; \ + atf_set \"require.progs\" \"rump_server\"; \ + }; \ + route_flags_${name}_body() { \ + setup_local; \ + setup_peer; \ + test_${name}; \ + rump_server_destroy_ifaces; \ + }; \ + route_flags_${name}_cleanup() { \ + $DEBUG && dump; \ + cleanup; \ + }" + atf_add_test_case "route_flags_${name}" +} + +atf_init_test_cases() +{ + + add_test lo "Tests route flags: loop back interface" + add_test connected "Tests route flags: connected route" + add_test default_gateway "Tests route flags: default gateway" + add_test static "Tests route flags: static route" + add_test blackhole "Tests route flags: blackhole route" + add_test reject "Tests route flags: reject route" + add_test icmp_redirect "Tests route flags: icmp redirect" + add_test announce "Tests route flags: announce flag" +} diff --git a/contrib/netbsd-tests/net/route/t_flags6.sh b/contrib/netbsd-tests/net/route/t_flags6.sh new file mode 100755 index 0000000..e570829 --- /dev/null +++ b/contrib/netbsd-tests/net/route/t_flags6.sh @@ -0,0 +1,268 @@ +# $NetBSD: t_flags6.sh,v 1.12 2016/12/21 02:46:08 ozaki-r Exp $ +# +# Copyright (c) 2016 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +SOCK_LOCAL=unix://commsock1 +SOCK_PEER=unix://commsock2 +SOCK_GW=unix://commsock3 +BUS=bus1 +BUS2=bus2 + +IP6_LOCAL=fc00::2 +IP6_PEER=fc00::1 + +DEBUG=${DEBUG:-false} + +setup_local() +{ + + rump_server_start $SOCK_LOCAL netinet6 + rump_server_add_iface $SOCK_LOCAL shmif0 $BUS + + export RUMP_SERVER=$SOCK_LOCAL + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 $IP6_LOCAL + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -rn -f inet6 +} + +setup_peer() +{ + + rump_server_start $SOCK_PEER netinet6 + rump_server_add_iface $SOCK_PEER shmif0 $BUS + + export RUMP_SERVER=$SOCK_PEER + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 $IP6_PEER + atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up + atf_check -s exit:0 -o ignore rump.ifconfig -w 10 + + $DEBUG && rump.ifconfig + $DEBUG && rump.netstat -rn -f inet6 +} + +test_lo6() +{ + + export RUMP_SERVER=$SOCK_LOCAL + + # Up, Host, local + check_route_flags fe80::1 UHl + + # Up, Host, local + check_route_flags ::1 UHl +} + +test_connected6() +{ + + export RUMP_SERVER=$SOCK_LOCAL + + # Up, Host, local + check_route_flags $IP6_LOCAL UHl + + # Up, Connected + check_route_flags fc00::/64 UC +} + +test_default_gateway6() +{ + + export RUMP_SERVER=$SOCK_LOCAL + + atf_check -s exit:0 -o ignore rump.route add -inet6 default $IP6_PEER + $DEBUG && rump.netstat -rn -f inet6 + + # Up, Gateway, Static + check_route_flags default UGS +} + +test_static6() +{ + + export RUMP_SERVER=$SOCK_LOCAL + + # Static route to host + atf_check -s exit:0 -o ignore \ + rump.route add -inet6 fc00::1:1 $IP6_PEER + $DEBUG && rump.netstat -rn -f inet6 + + # Up, Gateway, Host, Static + check_route_flags fc00::1:1 UGHS + + # Static route to network + atf_check -s exit:0 -o ignore \ + rump.route add -inet6 -net fc00::/24 $IP6_PEER + $DEBUG && rump.netstat -rn -f inet6 + + # Up, Gateway, Static + check_route_flags fc00::/24 UGS +} + +test_blackhole6() +{ + + export RUMP_SERVER=$SOCK_LOCAL + + atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6_PEER + + # Delete an existing route first + atf_check -s exit:0 -o ignore \ + rump.route delete -inet6 -net fc00::/64 + + # Gateway must be lo0 + atf_check -s exit:0 -o ignore \ + rump.route add -inet6 -net fc00::/64 ::1 -blackhole + $DEBUG && rump.netstat -rn -f inet6 + + # Up, Gateway, Blackhole, Static + check_route_flags fc00::/64 UGBS + + atf_check -s not-exit:0 -o match:'100.0% packet loss' \ + rump.ping6 -n -X 1 -c 1 $IP6_PEER + $DEBUG && rump.netstat -rn -f inet6 + + # Shouldn't be created + check_route_no_entry $IP6_PEER +} + +test_reject6() +{ + + export RUMP_SERVER=$SOCK_LOCAL + + # Delete an existing route first + atf_check -s exit:0 -o ignore \ + rump.route delete -inet6 -net fc00::/64 + + atf_check -s exit:0 -o ignore \ + rump.route add -inet6 -net fc00::/64 $IP6_PEER -reject + $DEBUG && rump.netstat -rn -f inet6 + + # Up, Gateway, Reject, Static + check_route_flags fc00::/64 UGRS + + atf_check -s not-exit:0 -o ignore -e match:'No route to host' \ + rump.ping6 -n -X 1 -c 1 $IP6_PEER + $DEBUG && rump.netstat -rn -f inet6 + + # Shouldn't be created + check_route_no_entry $IP6_PEER + + # Gateway is lo0 (RTF_GATEWAY) + + # Delete an existing route first + atf_check -s exit:0 -o ignore \ + rump.route delete -inet6 -net fc00::/64 + + atf_check -s exit:0 -o ignore \ + rump.route add -inet6 -net fc00::/64 ::1 -reject + $DEBUG && rump.netstat -rn -f inet6 + + # Up, Gateway, Reject, Static + check_route_flags fc00::/64 UGRS + + atf_check -s not-exit:0 -o ignore -e match:'Network is unreachable' \ + rump.ping6 -n -X 1 -c 1 $IP6_PEER + $DEBUG && rump.netstat -rn -f inet6 + + # Shouldn't be created + check_route_no_entry $IP6_PEER + + # Gateway is lo0 (RTF_HOST) + + # Delete an existing route first + atf_check -s exit:0 -o ignore \ + rump.route delete -inet6 -net fc00::/64 + + atf_check -s exit:0 -o ignore \ + rump.route add -inet6 -host fc00::/64 ::1 -iface -reject + $DEBUG && rump.netstat -rn -f inet6 + + # Up, Host, Reject, Static + check_route_flags fc00:: UHRS + + atf_check -s not-exit:0 -o ignore -e match:'No route to host' \ + rump.ping6 -n -X 1 -c 1 $IP6_PEER + $DEBUG && rump.netstat -rn -f inet6 + + return 0 +} + +test_announce6() +{ + export RUMP_SERVER=$SOCK_LOCAL + + # Delete an existing route first + atf_check -s exit:0 -o ignore \ + rump.route delete -inet6 -net fc00::/64 + + atf_check -s exit:0 -o ignore \ + rump.route add -inet6 -net fc00::/64 $IP6_PEER -proxy + $DEBUG && rump.netstat -rn -f inet6 + + # Up, Gateway, Static, proxy + check_route_flags fc00::/64 UGSp + + # TODO test its behavior +} + +add_test() +{ + local name=$1 + local desc="$2" + + atf_test_case "route_flags_${name}" cleanup + eval "route_flags_${name}_head() { \ + atf_set \"descr\" \"${desc}\"; \ + atf_set \"require.progs\" \"rump_server\"; \ + }; \ + route_flags_${name}_body() { \ + setup_local; \ + setup_peer; \ + test_${name}; \ + rump_server_destroy_ifaces; \ + }; \ + route_flags_${name}_cleanup() { \ + $DEBUG && dump; \ + cleanup; \ + }" + atf_add_test_case "route_flags_${name}" +} + +atf_init_test_cases() +{ + + add_test lo6 "Tests route flags: loop back interface" + add_test connected6 "Tests route flags: connected route" + add_test default_gateway6 "Tests route flags: default gateway" + add_test static6 "Tests route flags: static route" + add_test blackhole6 "Tests route flags: blackhole route" + add_test reject6 "Tests route flags: reject route" + add_test announce6 "Tests route flags: announce flag" +} diff --git a/contrib/netbsd-tests/net/route/t_route.sh b/contrib/netbsd-tests/net/route/t_route.sh new file mode 100755 index 0000000..053f48f --- /dev/null +++ b/contrib/netbsd-tests/net/route/t_route.sh @@ -0,0 +1,406 @@ +# $NetBSD: t_route.sh,v 1.10 2016/12/21 02:46:08 ozaki-r Exp $ +# +# Copyright (c) 2016 Internet Initiative Japan Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# non_subnet_gateway +SOCK_CLIENT=unix://commsock1 +SOCK_GW=unix://commsock2 +BUS=bus1 + +# command_get +SOCKSRC=unix://commsock1 +SOCKFWD=unix://commsock2 +SOCKDST=unix://commsock3 +IP4SRC=10.0.1.2 +IP4SRCGW=10.0.1.1 +IP4DSTGW=10.0.2.1 +IP4DST=10.0.2.2 +IP4DST_BCAST=10.0.2.255 +IP6SRC=fc00:0:0:1::2 +IP6SRCGW=fc00:0:0:1::1 +IP6DSTGW=fc00:0:0:2::1 +IP6DST=fc00:0:0:2::2 +BUS_SRCGW=bus1 +BUS_DSTGW=bus2 + +DEBUG=${DEBUG:-false} +TIMEOUT=1 +PING_OPTS="-n -c 1 -w $TIMEOUT" + +atf_test_case route_non_subnet_gateway cleanup +route_non_subnet_gateway_head() +{ + + atf_set "descr" "tests of a gateway not on the local subnet" + atf_set "require.progs" "rump_server" +} + +route_non_subnet_gateway_body() +{ + + rump_server_start $SOCK_CLIENT + rump_server_start $SOCK_GW + + export RUMP_SERVER=${SOCK_GW} + rump_server_add_iface $SOCK_GW shmif0 $BUS + atf_check -s exit:0 rump.ifconfig shmif0 192.168.0.1 + atf_check -s exit:0 rump.ifconfig shmif0 up + + # The gateway knows the client + atf_check -s exit:0 -o match:'add net 10.0.0.1: gateway shmif0' \ + rump.route add -net 10.0.0.1/32 -link -cloning -iface shmif0 + + $DEBUG && rump.netstat -nr -f inet + + export RUMP_SERVER=${SOCK_CLIENT} + rump_server_add_iface $SOCK_CLIENT shmif0 $BUS + atf_check -s exit:0 rump.ifconfig shmif0 10.0.0.1/32 + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + $DEBUG && rump.netstat -nr -f inet + + # Don't know a route to the gateway yet + atf_check -s not-exit:0 -o match:'100.0% packet loss' \ + -e match:'No route to host' rump.ping $PING_OPTS 192.168.0.1 + + # Teach a route to the gateway + atf_check -s exit:0 -o match:'add net 192.168.0.1: gateway shmif0' \ + rump.route add -net 192.168.0.1/32 -link -cloning -iface shmif0 + atf_check -s exit:0 -o match:'add net default: gateway 192.168.0.1' \ + rump.route add default -ifa 10.0.0.1 192.168.0.1 + + $DEBUG && rump.netstat -nr -f inet + + # Be reachable to the gateway + atf_check -s exit:0 -o ignore rump.ping $PING_OPTS 192.168.0.1 + + rump_server_destroy_ifaces +} + +route_non_subnet_gateway_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_test_case route_command_get cleanup +atf_test_case route_command_get6 cleanup +route_command_get_head() +{ + + atf_set "descr" "tests of route get command" + atf_set "require.progs" "rump_server" +} + +route_command_get6_head() +{ + + atf_set "descr" "tests of route get command (IPv6)" + atf_set "require.progs" "rump_server" +} + +setup_endpoint() +{ + local sock=${1} + local addr=${2} + local bus=${3} + local mode=${4} + local gw=${5} + + export RUMP_SERVER=${sock} + rump_server_add_iface $sock shmif0 $bus + if [ $mode = "ipv6" ]; then + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${addr} + atf_check -s exit:0 -o ignore rump.route add -inet6 default ${gw} + else + atf_check -s exit:0 rump.ifconfig shmif0 inet ${addr} netmask 0xffffff00 + atf_check -s exit:0 -o ignore rump.route add default ${gw} + fi + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig -w 10 + + if $DEBUG; then + rump.ifconfig shmif0 + rump.netstat -nr + fi +} + +setup_forwarder() +{ + mode=${1} + + rump_server_add_iface $SOCKFWD shmif0 $BUS_SRCGW + rump_server_add_iface $SOCKFWD shmif1 $BUS_DSTGW + + export RUMP_SERVER=$SOCKFWD + if [ $mode = "ipv6" ]; then + atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6SRCGW} + atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${IP6DSTGW} + else + atf_check -s exit:0 rump.ifconfig shmif0 inet ${IP4SRCGW} netmask 0xffffff00 + atf_check -s exit:0 rump.ifconfig shmif1 inet ${IP4DSTGW} netmask 0xffffff00 + fi + + atf_check -s exit:0 rump.ifconfig shmif0 up + atf_check -s exit:0 rump.ifconfig shmif1 up + atf_check -s exit:0 rump.ifconfig -w 10 + + if $DEBUG; then + rump.netstat -nr + if [ $mode = "ipv6" ]; then + rump.sysctl net.inet6.ip6.forwarding + else + rump.sysctl net.inet.ip.forwarding + fi + fi +} + +setup_forwarding() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.forwarding=1 +} + +setup_forwarding6() +{ + export RUMP_SERVER=$SOCKFWD + atf_check -s exit:0 -o ignore rump.sysctl -w net.inet6.ip6.forwarding=1 +} + +setup() +{ + + rump_server_start $SOCKSRC + rump_server_start $SOCKFWD + rump_server_start $SOCKDST + + setup_endpoint $SOCKSRC $IP4SRC $BUS_SRCGW ipv4 $IP4SRCGW + setup_endpoint $SOCKDST $IP4DST $BUS_DSTGW ipv4 $IP4DSTGW + setup_forwarder ipv4 +} + +setup6() +{ + + rump_server_start $SOCKSRC netinet6 + rump_server_start $SOCKFWD netinet6 + rump_server_start $SOCKDST netinet6 + + setup_endpoint $SOCKSRC $IP6SRC $BUS_SRCGW ipv6 $IP6SRCGW + setup_endpoint $SOCKDST $IP6DST $BUS_DSTGW ipv6 $IP6DSTGW + setup_forwarder ipv6 +} + +test_route_get() +{ + + export RUMP_SERVER=$SOCKSRC + $DEBUG && rump.netstat -nr -f inet + $DEBUG && rump.arp -n -a + + # Make sure an ARP cache to the gateway doesn't exist + rump.arp -d $IP4SRCGW + + # Local + cat >./expect <<-EOF + route to: 10.0.1.2 +destination: 10.0.1.2 + local addr: 10.0.1.2 + interface: lo0 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get $IP4SRC > ./output + $DEBUG && cat ./expect ./output + # XXX: omit the last line because expire is unstable on rump kernel. + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output + + # Neighbor + cat >./expect <<-EOF + route to: 10.0.1.1 +destination: 10.0.1.0 + mask: 255.255.255.0 + local addr: 10.0.1.2 + interface: shmif0 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get $IP4SRCGW > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output + + # Remote host + cat >./expect <<-EOF + route to: 10.0.2.2 +destination: default + mask: default + gateway: 10.0.1.1 + local addr: 10.0.1.2 + interface: shmif0 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get $IP4DST > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output + + # Create a ARP cache + atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4SRCGW + + # Neighbor with a cache (no different from w/o cache) + cat >./expect <<-EOF + route to: 10.0.1.1 +destination: 10.0.1.0 + mask: 255.255.255.0 + local addr: 10.0.1.2 + interface: shmif0 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get $IP4SRCGW > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output +} + +test_route_get6() +{ + + export RUMP_SERVER=$SOCKSRC + $DEBUG && rump.netstat -nr -f inet + $DEBUG && rump.ndp -n -a + + # Make sure an ARP cache to the gateway doesn't exist + rump.ndp -d $IP6SRCGW + + # Local + cat >./expect <<-EOF + route to: fc00:0:0:1::2 +destination: fc00:0:0:1::2 + local addr: fc00:0:0:1::2 + interface: lo0 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get -inet6 $IP6SRC > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output + + # Neighbor + cat >./expect <<-EOF + route to: fc00:0:0:1::1 +destination: fc00:0:0:1:: + mask: ffff:ffff:ffff:ffff:: + local addr: fc00:0:0:1::2 + interface: shmif0 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get -inet6 $IP6SRCGW > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output + + # Remote host + cat >./expect <<-EOF + route to: fc00:0:0:2::2 +destination: :: + mask: default + gateway: fc00:0:0:1::1 + local addr: fc00:0:0:1::2 + interface: shmif0 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get -inet6 $IP6DST > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output + + # Create a NDP cache + atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6SRCGW + + # Neighbor with a cache (no different from w/o cache) + cat >./expect <<-EOF + route to: fc00:0:0:1::1 +destination: fc00:0:0:1:: + mask: ffff:ffff:ffff:ffff:: + local addr: fc00:0:0:1::2 + interface: shmif0 + flags: + recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire + EOF + rump.route -n get -inet6 $IP6SRCGW > ./output + $DEBUG && cat ./expect ./output + sed -i '$d' ./output + atf_check -s exit:0 diff ./expect ./output +} + +route_command_get_body() +{ + + setup + setup_forwarding + test_route_get + rump_server_destroy_ifaces +} + +route_command_get6_body() +{ + + setup6 + setup_forwarding6 + test_route_get6 + rump_server_destroy_ifaces +} + +route_command_get_cleanup() +{ + + $DEBUG && dump + cleanup +} + +route_command_get6_cleanup() +{ + + $DEBUG && dump + cleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case route_non_subnet_gateway + atf_add_test_case route_command_get + atf_add_test_case route_command_get6 +} diff --git a/contrib/netbsd-tests/net/sys/t_rfc6056.c b/contrib/netbsd-tests/net/sys/t_rfc6056.c new file mode 100644 index 0000000..944521b --- /dev/null +++ b/contrib/netbsd-tests/net/sys/t_rfc6056.c @@ -0,0 +1,152 @@ +/* $NetBSD: t_rfc6056.c,v 1.3 2012/06/22 14:54:35 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_rfc6056.c,v 1.3 2012/06/22 14:54:35 christos Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static void +test(const char *hostname, const char *service, int family, int al) +{ + static const char hello[] = "hello\n"; + int s, error, proto, option; + struct sockaddr_storage ss; + struct addrinfo hints, *res; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_socktype = SOCK_DGRAM; + + switch (family) { + case AF_INET: + proto = IPPROTO_IP; + option = IP_PORTALGO; + break; + case AF_INET6: + proto = IPPROTO_IPV6; + option = IPV6_PORTALGO; + break; + default: + abort(); + } + + error = getaddrinfo(hostname, service, &hints, &res); + if (error) + errx(EXIT_FAILURE, "Cannot get address for %s (%s)", + hostname, gai_strerror(error)); + + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s == -1) + err(EXIT_FAILURE, "socket"); + + if (setsockopt(s, proto, option, &al, sizeof(al)) == -1) + err(EXIT_FAILURE, "setsockopt"); + + memset(&ss, 0, sizeof(ss)); + ss.ss_len = res->ai_addrlen; + ss.ss_family = res->ai_family; + + if (bind(s, (struct sockaddr *)&ss, ss.ss_len) == -1) + err(EXIT_FAILURE, "bind"); + + if (sendto(s, hello, sizeof(hello) - 1, 0, + res->ai_addr, res->ai_addrlen) == -1) + err(EXIT_FAILURE, "sendto"); + + if (close(s) == -1) + err(EXIT_FAILURE, "close"); + + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s == -1) + err(EXIT_FAILURE, "socket"); + + if (setsockopt(s, proto, option, &al, sizeof(al)) == -1) + err(EXIT_FAILURE, "setsockopt"); + + if (connect(s, res->ai_addr, res->ai_addrlen) == -1) + err(EXIT_FAILURE, "connect"); + + if (send(s, hello, sizeof(hello) - 1, 0) == -1) + err(EXIT_FAILURE, "send"); + + if (close(s) == -1) + err(EXIT_FAILURE, "close"); + + freeaddrinfo(res); +} + +ATF_TC(inet4); +ATF_TC_HEAD(inet4, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks random port allocation " + "for ipv4"); +} + +ATF_TC_BODY(inet4, tc) +{ + for (int i = 0; i < 6; i++) + test("localhost", "http", AF_INET, i); +} + +ATF_TC(inet6); +ATF_TC_HEAD(inet6, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks random port allocation " + "for ipv6"); +} + +ATF_TC_BODY(inet6, tc) +{ + for (int i = 0; i < 6; i++) + test("localhost", "http", AF_INET6, i); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, inet4); + ATF_TP_ADD_TC(tp, inet6); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/kernspace/alloc.c b/contrib/netbsd-tests/rump/kernspace/alloc.c new file mode 100644 index 0000000..5cbcfb6 --- /dev/null +++ b/contrib/netbsd-tests/rump/kernspace/alloc.c @@ -0,0 +1,122 @@ +/* $NetBSD: alloc.c,v 1.1 2010/06/14 21:06:09 pooka Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#if !defined(lint) +__RCSID("$NetBSD: alloc.c,v 1.1 2010/06/14 21:06:09 pooka Exp $"); +#endif /* !lint */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "kernspace.h" + +static void *store[32]; +static struct pool pp1, pp2; + +static kmutex_t mtx; +static kcondvar_t kcv; +static int curstat; + +static void +hthr(void *arg) +{ + int i; + + mutex_enter(&mtx); + curstat++; + cv_signal(&kcv); + + while (curstat < 2) + cv_wait(&kcv, &mtx); + mutex_exit(&mtx); + + /* try to guarantee that the sleep is triggered in PR_WAITOK */ + while ((kernel_map->flags & VM_MAP_WANTVA) == 0) + kpause("take5", false, 1, NULL); + + for (i = 0; i < __arraycount(store); i++) { + pool_put(&pp1, store[i]); + } + + kthread_exit(0); +} + +void +rumptest_alloc(size_t thelimit) +{ + char *c; + int succ, i; + + mutex_init(&mtx, MUTEX_DEFAULT, IPL_NONE); + cv_init(&kcv, "venailu"); + + kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, hthr, NULL, NULL, "h"); + + pool_init(&pp1, 1024, 0, 0, 0, "vara-allas", + &pool_allocator_nointr, IPL_NONE); + pool_init(&pp2, 1024, 0, 0, 0, "allas", + &pool_allocator_nointr, IPL_NONE); + + for (i = 0; i < __arraycount(store); i++) { + store[i] = pool_get(&pp1, PR_NOWAIT); + if (store[i] == NULL) { + panic("pool_get store failed"); + } + } + + /* wait until other thread runs */ + mutex_enter(&mtx); + while (curstat == 0) + cv_wait(&kcv, &mtx); + mutex_exit(&mtx); + + for (succ = 0;; succ++) { + if (succ * 1024 > thelimit) + panic("managed to allocate over limit"); + if ((c = pool_get(&pp2, PR_NOWAIT)) == NULL) { + mutex_enter(&mtx); + curstat++; + cv_signal(&kcv); + mutex_exit(&mtx); + if (pool_get(&pp2, PR_WAITOK) == NULL) + panic("pool get PR_WAITOK failed"); + break; + } + *c = 'a'; + } +} diff --git a/contrib/netbsd-tests/rump/kernspace/busypage.c b/contrib/netbsd-tests/rump/kernspace/busypage.c new file mode 100644 index 0000000..e0142b7 --- /dev/null +++ b/contrib/netbsd-tests/rump/kernspace/busypage.c @@ -0,0 +1,94 @@ +/* $NetBSD: busypage.c,v 1.5 2011/08/07 14:03:15 rmind Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#if !defined(lint) +__RCSID("$NetBSD: busypage.c,v 1.5 2011/08/07 14:03:15 rmind Exp $"); +#endif /* !lint */ + +#include +#include +#include +#include +#include + +#include + +#include "kernspace.h" + +static struct uvm_object *uobj; +static struct vm_page *testpg; +static kcondvar_t tcv; + +static bool threadrun = false; + +static void +thread(void *arg) +{ + + mutex_enter(uobj->vmobjlock); + threadrun = true; + cv_signal(&tcv); + testpg->flags |= PG_WANTED; + UVM_UNLOCK_AND_WAIT(testpg, uobj->vmobjlock, false, "tw", 0); + kthread_exit(0); +} + +void +rumptest_busypage() +{ + struct lwp *newl; + int rv; + + cv_init(&tcv, "napina"); + + uobj = uao_create(1, 0); + mutex_enter(uobj->vmobjlock); + testpg = uvm_pagealloc(uobj, 0, NULL, 0); + mutex_exit(uobj->vmobjlock); + if (testpg == NULL) + panic("couldn't create vm page"); + + rv = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN | KTHREAD_MPSAFE, NULL, + thread, NULL, &newl, "jointest"); + if (rv) + panic("thread creation failed: %d", rv); + + mutex_enter(uobj->vmobjlock); + while (!threadrun) + cv_wait(&tcv, uobj->vmobjlock); + + uvm_page_unbusy(&testpg, 1); + mutex_exit(uobj->vmobjlock); + + rv = kthread_join(newl); + if (rv) + panic("thread join failed: %d", rv); + +} diff --git a/contrib/netbsd-tests/rump/kernspace/kernspace.h b/contrib/netbsd-tests/rump/kernspace/kernspace.h new file mode 100644 index 0000000..248f62f --- /dev/null +++ b/contrib/netbsd-tests/rump/kernspace/kernspace.h @@ -0,0 +1,47 @@ +/* $NetBSD: kernspace.h,v 1.4 2011/01/14 13:08:00 pooka Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _TESTS_RUMP_KERNSPACE_KERNSPACE_H_ +#define _TESTS_RUMP_KERNSPACE_KERNSPACE_H_ + +enum locktest { LOCKME_MTX, LOCKME_RWDOUBLEX, LOCKME_RWRX, LOCKME_RWXR, + LOCKME_DESTROYHELD, LOCKME_DOUBLEINIT, LOCKME_DOUBLEFREE, + LOCKME_MEMFREE }; + +void rumptest_busypage(void); +void rumptest_threadjoin(void); +void rumptest_thread(void); +void rumptest_tsleep(void); +void rumptest_alloc(size_t); +void rumptest_lockme(enum locktest); + +void rumptest_sendsig(char *); +void rumptest_localsig(int); + +#endif /* _TESTS_RUMP_KERNSPACE_KERNSPACE_H_ */ diff --git a/contrib/netbsd-tests/rump/kernspace/lockme.c b/contrib/netbsd-tests/rump/kernspace/lockme.c new file mode 100644 index 0000000..6f9bd58 --- /dev/null +++ b/contrib/netbsd-tests/rump/kernspace/lockme.c @@ -0,0 +1,92 @@ +/* $NetBSD: lockme.c,v 1.1 2011/01/06 13:12:52 pooka Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#if !defined(lint) +__RCSID("$NetBSD: lockme.c,v 1.1 2011/01/06 13:12:52 pooka Exp $"); +#endif /* !lint */ + +#include +#include +#include +#include + +#include "kernspace.h" + +struct somemem { + char foo; + kmutex_t mutexetum; + char oof; +}; + +void +rumptest_lockme(enum locktest what) +{ + struct somemem *some; + kmutex_t mtx; + krwlock_t rw; + + rw_init(&rw); + mutex_init(&mtx, MUTEX_DEFAULT, IPL_NONE); + + switch (what) { + case LOCKME_MTX: + mutex_enter(&mtx); + mutex_enter(&mtx); + break; + case LOCKME_RWDOUBLEX: + rw_enter(&rw, RW_WRITER); + rw_enter(&rw, RW_WRITER); + break; + case LOCKME_RWRX: + rw_enter(&rw, RW_READER); + rw_enter(&rw, RW_WRITER); + break; + case LOCKME_RWXR: + rw_enter(&rw, RW_WRITER); + rw_enter(&rw, RW_READER); + break; + case LOCKME_DOUBLEINIT: + mutex_init(&mtx, MUTEX_DEFAULT, IPL_NONE); + break; + case LOCKME_DOUBLEFREE: + mutex_destroy(&mtx); + mutex_destroy(&mtx); + break; + case LOCKME_DESTROYHELD: + mutex_enter(&mtx); + mutex_destroy(&mtx); + break; + case LOCKME_MEMFREE: + some = kmem_alloc(sizeof(*some), KM_SLEEP); + mutex_init(&some->mutexetum, MUTEX_DEFAULT, IPL_NONE); + kmem_free(some, sizeof(*some)); + break; + } +} diff --git a/contrib/netbsd-tests/rump/kernspace/sendsig.c b/contrib/netbsd-tests/rump/kernspace/sendsig.c new file mode 100644 index 0000000..f0b17a8 --- /dev/null +++ b/contrib/netbsd-tests/rump/kernspace/sendsig.c @@ -0,0 +1,82 @@ +/* $NetBSD: sendsig.c,v 1.1 2011/01/14 13:08:00 pooka Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#if !defined(lint) +__RCSID("$NetBSD: sendsig.c,v 1.1 2011/01/14 13:08:00 pooka Exp $"); +#endif /* !lint */ + +#include +#include + +#include + +#include "kernspace.h" + +/* + * loop until a non-system process appears and we can send it a signal + */ +void +rumptest_sendsig(char *signo) +{ + struct proc *p; + bool sent = false; + int sig; + + sig = strtoull(signo, NULL, 10); + rump_boot_setsigmodel(RUMP_SIGMODEL_RAISE); + + mutex_enter(proc_lock); + while (!sent) { + PROCLIST_FOREACH(p, &allproc) { + if (p->p_pid > 1) { + mutex_enter(p->p_lock); + psignal(p, sig); + mutex_exit(p->p_lock); + sent = true; + break; + } + } + kpause("w8", false, 1, proc_lock); + } + mutex_exit(proc_lock); + + /* restore default */ + rump_boot_setsigmodel(RUMP_SIGMODEL_PANIC); +} + +void +rumptest_localsig(int signo) +{ + struct proc *p = curproc; + + mutex_enter(p->p_lock); + psignal(p, signo); + mutex_exit(p->p_lock); +} diff --git a/contrib/netbsd-tests/rump/kernspace/thread.c b/contrib/netbsd-tests/rump/kernspace/thread.c new file mode 100644 index 0000000..5c24f12 --- /dev/null +++ b/contrib/netbsd-tests/rump/kernspace/thread.c @@ -0,0 +1,108 @@ +/* $NetBSD: thread.c,v 1.2 2011/08/07 14:03:15 rmind Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#if !defined(lint) +__RCSID("$NetBSD: thread.c,v 1.2 2011/08/07 14:03:15 rmind Exp $"); +#endif /* !lint */ + +#include +#include +#include +#include +#include + +#include "kernspace.h" + +static volatile int testit; + +static void +jointhread(void *arg) +{ + + kpause("take5", false, 1, NULL); + testit = 1; + kthread_exit(0); +} + +void +rumptest_threadjoin() +{ + struct lwp *newl; + int rv; + + rv = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN | KTHREAD_MPSAFE, NULL, + jointhread, NULL, &newl, "jointest"); + if (rv) + panic("thread creation failed: %d", rv); + rv = kthread_join(newl); + if (rv) + panic("thread join failed: %d", rv); + + if (testit != 1) + panic("new thread did not run"); +} + +static kmutex_t mtx; +static kcondvar_t cv; +static int value; + +static void +thethread(void *arg) +{ + + mutex_enter(&mtx); + value = 1; + cv_signal(&cv); + mutex_exit(&mtx); + + kthread_exit(0); +} + +void +rumptest_thread() +{ + struct lwp *newl; + int rv; + + mutex_init(&mtx, MUTEX_DEFAULT, IPL_NONE); + cv_init(&cv, "jooei"); + rv = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, + thethread, NULL, &newl, "ktest"); + if (rv) + panic("thread creation failed: %d", rv); + + mutex_enter(&mtx); + while (value == 0) + cv_wait(&cv, &mtx); + mutex_exit(&mtx); + + /* try to verify thread really exists and we don't crash */ + kpause("take1", false, 1, NULL); +} diff --git a/contrib/netbsd-tests/rump/kernspace/tsleep.c b/contrib/netbsd-tests/rump/kernspace/tsleep.c new file mode 100644 index 0000000..4d08e0a --- /dev/null +++ b/contrib/netbsd-tests/rump/kernspace/tsleep.c @@ -0,0 +1,100 @@ +/* $NetBSD: tsleep.c,v 1.4 2014/03/21 22:18:57 dholland Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#if !defined(lint) +__RCSID("$NetBSD: tsleep.c,v 1.4 2014/03/21 22:18:57 dholland Exp $"); +#endif /* !lint */ + +#include +#include +#include +#include + +#include "kernspace.h" + +#define NTHREADS 10 + +/* + * mpsafe thread. need dedicated interlock + */ +static kmutex_t mymtx; + +static void +tinythread(void *arg) +{ + static int wakeups; + int i, rv; + bool relock = ((uintptr_t)arg % 2) == 0; + + for (i = 0; i < 1000; i++) { + mutex_enter(&mymtx); + wakeup(tinythread); + if (wakeups >= NTHREADS-1) { + mutex_exit(&mymtx); + break; + } + rv = mtsleep(tinythread, relock ? 0 : PNORELOCK, + "haa", 0, &mymtx); + if (relock) + mutex_exit(&mymtx); + if (rv != 0) + panic("mtsleep failed"); + } + + mutex_enter(&mymtx); + wakeups++; + wakeup(tinythread); + + rv = mtsleep(rumptest_tsleep, PNORELOCK, "kepuli", 1, &mymtx); + if (rv != EWOULDBLOCK) + panic("mtsleep unexpected return value %d", rv); + + kthread_exit(0); +} + +void +rumptest_tsleep() +{ + struct lwp *notbigl[NTHREADS]; + int rv, i; + + mutex_init(&mymtx, MUTEX_DEFAULT, IPL_NONE); + + for (i = 0; i < NTHREADS; i++) { + rv = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN| KTHREAD_MPSAFE, + NULL, tinythread, (void *)(uintptr_t)i, ¬bigl[i], "nb"); + if (rv) + panic("thread create failed: %d", rv); + } + + for (i = 0; i < NTHREADS; i++) { + kthread_join(notbigl[i]); + } +} diff --git a/contrib/netbsd-tests/rump/modautoload/t_modautoload.c b/contrib/netbsd-tests/rump/modautoload/t_modautoload.c new file mode 100644 index 0000000..b45dae5 --- /dev/null +++ b/contrib/netbsd-tests/rump/modautoload/t_modautoload.c @@ -0,0 +1,88 @@ +/* $NetBSD: t_modautoload.c,v 1.6 2017/01/13 21:30:42 christos Exp $ */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "h_macros.h" + +ATF_TC(modautoload); +ATF_TC_HEAD(modautoload, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests that kernel module " + "autoload works in rump"); +} + +static void +mountkernfs(void) +{ + bool old_autoload, new_autoload; + size_t old_len, new_len; + int error; + + if (!rump_nativeabi_p()) + atf_tc_skip("host kernel modules not supported"); + + rump_init(); + + if (rump_sys_mkdir("/kern", 0777) == -1) + atf_tc_fail_errno("mkdir /kern"); + + new_autoload = true; + old_len = sizeof(old_autoload); + new_len = sizeof(new_autoload); + error = sysctlbyname("kern.module.autoload", + &old_autoload, &old_len, + &new_autoload, new_len); + if (error != 0) + atf_tc_fail_errno("could not enable module autoload"); + + if (rump_sys_mount(MOUNT_KERNFS, "/kern", 0, NULL, 0) == -1) + atf_tc_fail_errno("could not mount kernfs"); +} + +/* + * Why use kernfs here? It talks to plenty of other parts with the + * kernel (e.g. vfs_attach() in modcmd), but is still easy to verify + * it's working correctly. + */ + +#define MAGICNUM 1323 +ATF_TC_BODY(modautoload, tc) +{ + extern int rumpns_hz; + char buf[64]; + int fd; + + mountkernfs(); + rumpns_hz = MAGICNUM; + if ((fd = rump_sys_open("/kern/hz", O_RDONLY)) == -1) + atf_tc_fail_errno("open /kern/hz"); + if (rump_sys_read(fd, buf, sizeof(buf)) <= 0) + atf_tc_fail_errno("read"); + ATF_REQUIRE(atoi(buf) == MAGICNUM); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, modautoload); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/rumpkern/h_client/h_forkcli.c b/contrib/netbsd-tests/rump/rumpkern/h_client/h_forkcli.c new file mode 100644 index 0000000..3b89727 --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/h_client/h_forkcli.c @@ -0,0 +1,169 @@ +/* $NetBSD: h_forkcli.c,v 1.1 2011/01/05 17:19:09 pooka Exp $ */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static void +simple(void) +{ + struct rumpclient_fork *rf; + pid_t pid1, pid2; + int fd, status; + + if ((pid1 = rump_sys_getpid()) < 2) + errx(1, "unexpected pid %d", pid1); + + fd = rump_sys_open("/dev/null", O_CREAT | O_RDWR); + if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd)) + errx(1, "write newlyopened /dev/null"); + + if ((rf = rumpclient_prefork()) == NULL) + err(1, "prefork"); + + switch (fork()) { + case -1: + err(1, "fork"); + break; + case 0: + if (rumpclient_fork_init(rf) == -1) + err(1, "postfork init failed"); + + if ((pid2 = rump_sys_getpid()) < 2) + errx(1, "unexpected pid %d", pid2); + if (pid1 == pid2) + errx(1, "child and parent pids are equal"); + + /* check that we can access the fd, the close it and exit */ + if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd)) + errx(1, "write child /dev/null"); + rump_sys_close(fd); + break; + default: + /* + * check that we can access the fd, wait for the child, and + * check we can still access the fd + */ + if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd)) + errx(1, "write parent /dev/null"); + if (wait(&status) == -1) + err(1, "wait failed"); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + errx(1, "child exited with status %d", status); + if (rump_sys_write(fd, &fd, sizeof(fd)) != sizeof(fd)) + errx(1, "write parent /dev/null"); + break; + } +} + +static void +cancel(void) +{ + + /* XXX: not implemented in client / server !!! */ +} + +#define TESTSTR "i am your fatherrrrrrr" +#define TESTSLEN (sizeof(TESTSTR)-1) +static void +pipecomm(void) +{ + struct rumpclient_fork *rf; + char buf[TESTSLEN+1]; + int pipetti[2]; + int status; + + if (rump_sys_pipe(pipetti) == -1) + errx(1, "pipe"); + + if ((rf = rumpclient_prefork()) == NULL) + err(1, "prefork"); + + switch (fork()) { + case -1: + err(1, "fork"); + break; + case 0: + if (rumpclient_fork_init(rf) == -1) + err(1, "postfork init failed"); + + memset(buf, 0, sizeof(buf)); + if (rump_sys_read(pipetti[0], buf, TESTSLEN) != TESTSLEN) + err(1, "pipe read"); + if (strcmp(TESTSTR, buf) != 0) + errx(1, "teststring doesn't match, got %s", buf); + break; + default: + if (rump_sys_write(pipetti[1], TESTSTR, TESTSLEN) != TESTSLEN) + err(1, "pipe write"); + if (wait(&status) == -1) + err(1, "wait failed"); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + errx(1, "child exited with status %d", status); + break; + } +} + +static void +fakeauth(void) +{ + struct rumpclient_fork *rf; + uint32_t *auth; + int rv; + + if ((rf = rumpclient_prefork()) == NULL) + err(1, "prefork"); + + /* XXX: we know the internal structure of rf */ + auth = (void *)rf; + *(auth+3) = *(auth+3) ^ 0x1; + + rv = rumpclient_fork_init(rf); + if (!(rv == -1 && errno == ESRCH)) + exit(1); +} + +struct parsa { + const char *arg; /* sp arg, el */ + void (*spring)(void); /* spring into action */ +} paragus[] = { + { "simple", simple }, + { "cancel", cancel }, + { "pipecomm", pipecomm }, + { "fakeauth", fakeauth }, +}; + +int +main(int argc, char *argv[]) +{ + unsigned i; + + if (argc != 2) + errx(1, "invalid usage"); + + if (rumpclient_init() == -1) + err(1, "rumpclient init"); + + for (i = 0; i < __arraycount(paragus); i++) { + if (strcmp(argv[1], paragus[i].arg) == 0) { + paragus[i].spring(); + break; + } + } + if (i == __arraycount(paragus)) { + printf("invalid test %s\n", argv[1]); + exit(1); + } + + exit(0); +} diff --git a/contrib/netbsd-tests/rump/rumpkern/h_client/h_reconcli.c b/contrib/netbsd-tests/rump/rumpkern/h_client/h_reconcli.c new file mode 100644 index 0000000..c594bbf --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/h_client/h_reconcli.c @@ -0,0 +1,121 @@ +/* $NetBSD: h_reconcli.c,v 1.2 2011/02/19 09:56:45 pooka Exp $ */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +static volatile int quit, riseandwhine; + +static pthread_mutex_t closermtx; +static pthread_cond_t closercv; + +static void * +closer(void *arg) +{ + + pthread_mutex_lock(&closermtx); + while (!quit) { + while (!riseandwhine) + pthread_cond_wait(&closercv, &closermtx); + riseandwhine = 0; + pthread_mutex_unlock(&closermtx); + + /* try to catch a random slot */ + usleep(random() % 100000); + + /* + * wide-angle disintegration beam, but takes care + * of the client rumpkernel communication socket. + */ + closefrom(3); + + pthread_mutex_lock(&closermtx); + } + pthread_mutex_unlock(&closermtx); + + return NULL; +} + +static const int hostnamemib[] = { CTL_KERN, KERN_HOSTNAME }; +static char goodhostname[128]; + +static void * +worker(void *arg) +{ + char hostnamebuf[128]; + size_t blen; + + pthread_mutex_lock(&closermtx); + while (!quit) { + pthread_mutex_unlock(&closermtx); + if (rump_sys_getpid() == -1) + err(1, "getpid"); + + blen = sizeof(hostnamebuf); + memset(hostnamebuf, 0, sizeof(hostnamebuf)); + if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib), + hostnamebuf, &blen, NULL, 0) == -1) + err(1, "sysctl"); + if (strcmp(hostnamebuf, goodhostname) != 0) + exit(1); + pthread_mutex_lock(&closermtx); + riseandwhine = 1; + pthread_cond_signal(&closercv); + } + riseandwhine = 1; + pthread_cond_signal(&closercv); + pthread_mutex_unlock(&closermtx); + + return NULL; +} + +int +main(int argc, char *argv[]) +{ + pthread_t pt, w1, w2, w3, w4; + size_t blen; + int timecount; + + if (argc != 2) + errx(1, "need timecount"); + timecount = atoi(argv[1]); + if (timecount <= 0) + errx(1, "invalid timecount %d\n", timecount); + + srandom(time(NULL)); + + rumpclient_setconnretry(RUMPCLIENT_RETRYCONN_INFTIME); + if (rumpclient_init() == -1) + err(1, "init"); + + blen = sizeof(goodhostname); + if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib), + goodhostname, &blen, NULL, 0) == -1) + err(1, "sysctl"); + + pthread_create(&pt, NULL, closer, NULL); + pthread_create(&w1, NULL, worker, NULL); + pthread_create(&w2, NULL, worker, NULL); + pthread_create(&w3, NULL, worker, NULL); + pthread_create(&w4, NULL, worker, NULL); + + sleep(timecount); + quit = 1; + + pthread_join(pt, NULL); + pthread_join(w1, NULL); + pthread_join(w2, NULL); + pthread_join(w3, NULL); + pthread_join(w4, NULL); + + exit(0); +} diff --git a/contrib/netbsd-tests/rump/rumpkern/h_client/h_sigcli.c b/contrib/netbsd-tests/rump/rumpkern/h_client/h_sigcli.c new file mode 100644 index 0000000..9134f98 --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/h_client/h_sigcli.c @@ -0,0 +1,84 @@ +/* $NetBSD: h_sigcli.c,v 1.3 2011/02/07 20:05:09 pooka Exp $ */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +static const int hostnamemib[] = { CTL_KERN, KERN_HOSTNAME }; +static char hostnamebuf[128]; + +static volatile sig_atomic_t sigexecs; + +static void +sighand(int sig) +{ + char buf[128]; + size_t blen = sizeof(buf); + + if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib), + buf, &blen, NULL, 0) == -1) + err(1, "sighand sysctl"); + if (strcmp(buf, hostnamebuf) != 0) + errx(1, "sighandler hostname"); + sigexecs++; +} + +int +main(void) +{ + char buf[128]; + time_t tstart; + struct itimerval itv; + size_t hnbsize; + int i; + size_t blen; + + if (rumpclient_init() == -1) + err(1, "rumpclient init"); + + hnbsize = sizeof(hostnamebuf); + if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib), + hostnamebuf, &hnbsize, NULL, 0) == -1) + err(1, "sysctl"); + + if (signal(SIGALRM, sighand) == SIG_ERR) + err(1, "signal"); + + itv.it_interval.tv_sec = itv.it_value.tv_sec = 0; + itv.it_interval.tv_usec = itv.it_value.tv_usec = 10000; /* 10ms */ + + if (setitimer(ITIMER_REAL, &itv, NULL) == -1) + err(1, "itimer"); + + tstart = time(NULL); + for (i = 0;; i++) { + blen = sizeof(buf); + if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib), + buf, &blen, NULL, 0) == -1) + err(1, "sysctl"); + if (strcmp(buf, hostnamebuf) != 0) + errx(1, "main hostname"); + + /* + * check every 100 cycles to avoid doing + * nothing but gettimeofday() + */ + if (i == 100) { + if (time(NULL) - tstart > 5) + break; + i = 0; + } + } + + if (!sigexecs) { + printf("no signal handlers run. test busted?\n"); + } +} diff --git a/contrib/netbsd-tests/rump/rumpkern/h_client/h_simplecli.c b/contrib/netbsd-tests/rump/rumpkern/h_client/h_simplecli.c new file mode 100644 index 0000000..11f432c --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/h_client/h_simplecli.c @@ -0,0 +1,30 @@ +/* $NetBSD: h_simplecli.c,v 1.2 2011/01/14 13:23:15 pooka Exp $ */ + +#include + +#include +#include +#include +#include + +#include +#include + +int +main(int argc, char *argv[]) +{ + + if (rumpclient_init() == -1) + err(1, "rumpclient init"); + + if (argc > 1) { + for (;;) { + rump_sys_getpid(); + usleep(10000); + } + } else { + if (rump_sys_getpid() > 0) + exit(0); + err(1, "getpid"); + } +} diff --git a/contrib/netbsd-tests/rump/rumpkern/h_client/h_stresscli.c b/contrib/netbsd-tests/rump/rumpkern/h_client/h_stresscli.c new file mode 100644 index 0000000..d49edeb --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/h_client/h_stresscli.c @@ -0,0 +1,219 @@ +/* $NetBSD: h_stresscli.c,v 1.9 2011/06/26 13:17:36 christos Exp $ */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static unsigned int syscalls, bindcalls; +static pid_t mypid; +static volatile sig_atomic_t doquit; + +static void +signaali(int sig) +{ + + doquit = 1; +} + +static const int hostnamemib[] = { CTL_KERN, KERN_HOSTNAME }; +static char hostnamebuf[128]; +#define HOSTNAMEBASE "rumpclient" + +static int iskiller; + +static void * +client(void *arg) +{ + char buf[256]; + struct sockaddr_in sin; + size_t blen; + int port = (int)(uintptr_t)arg; + int s, fd, x; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_len = sizeof(sin); + sin.sin_port = htons(port); + + while (!doquit) { + pid_t pidi; + blen = sizeof(buf); + s = rump_sys_socket(PF_INET, SOCK_STREAM, 0); + if (s == -1) + err(1, "socket"); + atomic_inc_uint(&syscalls); + + fd = rump_sys_open("/dev/null", O_RDWR); + atomic_inc_uint(&syscalls); + + if (doquit) + goto out; + + x = 1; + if (rump_sys_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, + &x, sizeof(x)) == -1) + err(1, "reuseaddr"); + + /* + * we don't really know when the kernel handles our disconnect, + * so be soft about about the failure in case of a killer client + */ + if (rump_sys_bind(s, (struct sockaddr*)&sin, sizeof(sin))==-1) { + if (!iskiller) + err(1, "bind to port %d failed", + ntohs(sin.sin_port)); + } else { + atomic_inc_uint(&bindcalls); + } + atomic_inc_uint(&syscalls); + + if (doquit) + goto out; + + if (rump_sys___sysctl(hostnamemib, __arraycount(hostnamemib), + buf, &blen, NULL, 0) == -1) + err(1, "sysctl"); + if (strncmp(buf, hostnamebuf, sizeof(HOSTNAMEBASE)-1) != 0) + errx(1, "hostname (%s/%s) mismatch", buf, hostnamebuf); + atomic_inc_uint(&syscalls); + + if (doquit) + goto out; + + pidi = rump_sys_getpid(); + if (pidi == -1) + err(1, "getpid"); + if (pidi != mypid) + errx(1, "mypid mismatch"); + atomic_inc_uint(&syscalls); + + if (doquit) + goto out; + + if (rump_sys_write(fd, buf, 16) != 16) + err(1, "write /dev/null"); + atomic_inc_uint(&syscalls); + + out: + rump_sys_close(fd); + atomic_inc_uint(&syscalls); + rump_sys_close(s); + atomic_inc_uint(&syscalls); + } + + return NULL; +} + +/* Stress with max 32 clients, 8 threads each (256 concurrent threads) */ +#define NCLI 32 +#define NTHR 8 + +int +main(int argc, char *argv[]) +{ + pthread_t pt[NTHR-1]; + pid_t clis[NCLI]; + pid_t apid; + int ncli = 0; + int i = 0, j; + int status, thesig; + int rounds, myport; + + if (argc != 2 && argc != 3) + errx(1, "need roundcount"); + + if (argc == 3) { + if (strcmp(argv[2], "kill") != 0) + errx(1, "optional 3rd param must be kill"); + thesig = SIGKILL; + iskiller = 1; + } else { + thesig = SIGUSR1; + } + + signal(SIGUSR1, signaali); + + memset(clis, 0, sizeof(clis)); + for (rounds = 1; rounds < atoi(argv[1])*10; rounds++) { + while (ncli < NCLI) { + switch ((apid = fork())) { + case -1: + err(1, "fork failed"); + case 0: + if (rumpclient_init() == -1) + err(1, "rumpclient init"); + + mypid = rump_sys_getpid(); + sprintf(hostnamebuf, HOSTNAMEBASE "%d", mypid); + if (rump_sys___sysctl(hostnamemib, + __arraycount(hostnamemib), NULL, NULL, + hostnamebuf, strlen(hostnamebuf)+1) == -1) + err(1, "sethostname"); + + for (j = 0; j < NTHR-1; j++) { + myport = i*NCLI + j+2; + if (pthread_create(&pt[j], NULL, + client, + (void*)(uintptr_t)myport) !=0 ) + err(1, "pthread create"); + } + myport = i*NCLI+1; + client((void *)(uintptr_t)myport); + for (j = 0; j < NTHR-1; j++) + pthread_join(pt[j], NULL); + membar_consumer(); + fprintf(stderr, "done %d\n", syscalls); + exit(0); + /* NOTREACHED */ + default: + ncli++; + clis[i] = apid; + break; + } + + i = (i + 1) % NCLI; + } + + usleep(100000); + kill(clis[i], thesig); + + apid = wait(&status); + if (apid != clis[i]) + errx(1, "wanted pid %d, got %d\n", clis[i], apid); + clis[i] = 0; + ncli--; + if (thesig == SIGUSR1) { + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + fprintf(stderr, "child died with 0x%x\n", + status); + exit(1); + } + } else { + if (!WIFSIGNALED(status) || WTERMSIG(status) != thesig){ + fprintf(stderr, "child died with 0x%x\n", + status); + exit(1); + } + } + } + + for (i = 0; i < NCLI; i++) + if (clis[i]) + kill(clis[i], SIGKILL); +} diff --git a/contrib/netbsd-tests/rump/rumpkern/h_server/h_simpleserver.c b/contrib/netbsd-tests/rump/rumpkern/h_server/h_simpleserver.c new file mode 100644 index 0000000..0ab3958 --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/h_server/h_simpleserver.c @@ -0,0 +1,64 @@ +/* $NetBSD: h_simpleserver.c,v 1.4 2016/01/25 12:21:42 pooka Exp $ */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "../../kernspace/kernspace.h" + +#define NOFAIL(e) do { int rv = e; if (rv) err(1, #e); } while (/*CONSTCOND*/0) + +struct { + const char *str; + void (*dofun)(char *); +} actions[] = { + { "sendsig", rumptest_sendsig }, +}; + +int +main(int argc, char *argv[]) +{ + unsigned i; + bool match; + + if (argc < 2) + exit(1); + + NOFAIL(rump_daemonize_begin()); + NOFAIL(rump_init()); + NOFAIL(rump_init_server(argv[1])); + NOFAIL(rump_daemonize_done(RUMP_DAEMONIZE_SUCCESS)); + + if (argc > 2) { + char *arg = NULL; + + if (argc == 4) + arg = argv[3]; + + for (i = 0; i < __arraycount(actions); i++) { + if (strcmp(actions[i].str, argv[2]) == 0) { + rump_schedule(); + actions[i].dofun(arg); + rump_unschedule(); + match = true; + } + } + + if (!match) { + exit(1); + } + pause(); + } else { + for (;;) + pause(); + } + + return 0; +} diff --git a/contrib/netbsd-tests/rump/rumpkern/t_copy.c b/contrib/netbsd-tests/rump/rumpkern/t_copy.c new file mode 100644 index 0000000..a31e58c --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/t_copy.c @@ -0,0 +1,139 @@ +/* $NetBSD: t_copy.c,v 1.2 2013/07/26 16:09:48 njoly Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include +#include +#include + +#include + +ATF_TC(copystr); +ATF_TC_HEAD(copystr, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Tests copystr()"); +} + +ATF_TC(copyinstr); +ATF_TC_HEAD(copyinstr, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Tests copyinstr()"); +} + +ATF_TC(copyoutstr); +ATF_TC_HEAD(copyoutstr, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Tests copyoutstr()"); +} + +typedef int (copystr_fn)(const void *, void *, size_t, size_t *); +typedef int (copy_fn)(const void *, void *, size_t); + +extern copystr_fn rumpns_copystr, rumpns_copyinstr, rumpns_copyoutstr; +extern copy_fn rumpns_copyin, rumpns_copyout; + +#define TESTSTR "jippii, lisaa puuroa" + +static void +dotest(copystr_fn *thefun) +{ + char buf[sizeof(TESTSTR)+1]; + size_t len; + + rump_init(); + rump_schedule(); + + /* larger buffer */ + memset(buf, 0xaa, sizeof(buf)); + ATF_REQUIRE_EQ(thefun(TESTSTR, buf, sizeof(buf), &len), 0); + ATF_REQUIRE_EQ(len, sizeof(TESTSTR)); + ATF_REQUIRE_STREQ(TESTSTR, buf); + + /* just large enough */ + memset(buf, 0xaa, sizeof(buf)); + ATF_REQUIRE_EQ(thefun(TESTSTR, buf, sizeof(buf)-1, &len), 0); + ATF_REQUIRE_EQ(len, sizeof(TESTSTR)); + ATF_REQUIRE_STREQ(TESTSTR, buf); + + /* one too small */ + memset(buf, 0xaa, sizeof(buf)); + ATF_REQUIRE_EQ(thefun(TESTSTR, buf, sizeof(buf)-2, NULL), ENAMETOOLONG); + + rump_unschedule(); +} + +ATF_TC_BODY(copystr, tc) +{ + + dotest(rumpns_copystr); +} + +ATF_TC_BODY(copyinstr, tc) +{ + + dotest(rumpns_copyinstr); +} + +ATF_TC_BODY(copyoutstr, tc) +{ + + dotest(rumpns_copyoutstr); +} + +ATF_TC(copy_efault); +ATF_TC_HEAD(copy_efault, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Tests that copy(9) functions can return EFAULT"); +} +ATF_TC_BODY(copy_efault, tc) +{ + char buf[1024]; + + ATF_REQUIRE_EQ(rumpns_copyin(NULL, buf, sizeof(buf)), EFAULT); + ATF_REQUIRE_EQ(rumpns_copyout(buf, NULL, sizeof(buf)), EFAULT); + + ATF_REQUIRE_EQ(rumpns_copyinstr(NULL, buf, sizeof(buf), NULL), EFAULT); + ATF_REQUIRE_EQ(rumpns_copyoutstr(buf, NULL, sizeof(buf), NULL), EFAULT); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, copystr); + ATF_TP_ADD_TC(tp, copyinstr); + ATF_TP_ADD_TC(tp, copyoutstr); + ATF_TP_ADD_TC(tp, copy_efault); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/rumpkern/t_kern.c b/contrib/netbsd-tests/rump/rumpkern/t_kern.c new file mode 100644 index 0000000..15b2586 --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/t_kern.c @@ -0,0 +1,119 @@ +/* $NetBSD: t_kern.c,v 1.4 2017/01/13 21:30:43 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include + +#include +#include +#include +#include + +#include "h_macros.h" +#include "../kernspace/kernspace.h" + +#define LOCKFUN(_name_, _descr_,_needld_, _expect_) \ + ATF_TC(lockme_##_name_); \ + ATF_TC_HEAD(lockme_##_name_, tc) { \ + atf_tc_set_md_var(tc, "descr", _descr_); \ + } \ + ATF_TC_BODY(lockme_##_name_, tc) { \ + locktest(tc, LOCKME_##_name_, _needld_, _expect_); \ + } + +static void +locktest(const atf_tc_t *tc, enum locktest lt, int needld, const char *expect) +{ + extern const int rump_lockdebug; + int pipetti[2]; + int status; + + if (needld && !rump_lockdebug) + atf_tc_skip("test requires LOCKDEBUG kernel"); + RL(pipe(pipetti)); + + switch (fork()) { + case 0: + RL(dup2(pipetti[1], STDOUT_FILENO)); + RL(dup2(pipetti[1], STDOUT_FILENO)); + rump_init(); + rump_schedule(); + rumptest_lockme(lt); + rump_unschedule(); + break; + default: + RL(wait(&status)); + ATF_REQUIRE(WIFSIGNALED(status) && WTERMSIG(status) == SIGABRT); + if (rump_lockdebug) { + char buf[8192]; + + ATF_REQUIRE(read(pipetti[0], buf, sizeof(buf)) > 0); + if (strncmp(buf, expect, strlen(expect)) != 0) + atf_tc_fail("unexpected output"); + } + break; + case -1: + atf_tc_fail("fork"); + } +} + +LOCKFUN(DESTROYHELD, "destroy lock while held", 0, + "mutex error: lockdebug_free: is locked or in use"); +LOCKFUN(DOUBLEFREE, "free lock twice", 0, + "panic: lockdebug_lookup: uninitialized lock"); +LOCKFUN(DOUBLEINIT, "init lock twice", 1, + "mutex error: lockdebug_alloc: already initialized"); +LOCKFUN(MEMFREE, "free memory active lock is in", 1, + "mutex error: kmem_intr_free: allocation contains active lock"); +LOCKFUN(MTX, "locking-against-self mutex", 0, + "mutex error: lockdebug_wantlock: locking against myself"); +LOCKFUN(RWDOUBLEX, "locking-against-self exclusive rwlock", 0, + "rwlock error: lockdebug_wantlock: locking against myself"); +LOCKFUN(RWRX, "rw: first shared, then exclusive", 1, + "rwlock error: lockdebug_wantlock: locking against myself"); +LOCKFUN(RWXR, "rw: first execusive, then shared", 0, + "rwlock error: lockdebug_wantlock: locking against myself"); + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, lockme_MTX); + ATF_TP_ADD_TC(tp, lockme_RWDOUBLEX); + ATF_TP_ADD_TC(tp, lockme_RWRX); + ATF_TP_ADD_TC(tp, lockme_RWXR); + ATF_TP_ADD_TC(tp, lockme_DOUBLEINIT); + ATF_TP_ADD_TC(tp, lockme_DOUBLEFREE); + ATF_TP_ADD_TC(tp, lockme_DESTROYHELD); + ATF_TP_ADD_TC(tp, lockme_MEMFREE); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/rumpkern/t_lwproc.c b/contrib/netbsd-tests/rump/rumpkern/t_lwproc.c new file mode 100644 index 0000000..f319979 --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/t_lwproc.c @@ -0,0 +1,318 @@ +/* $NetBSD: t_lwproc.c,v 1.9 2017/01/13 21:30:43 christos Exp $ */ + +/* + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "h_macros.h" + +ATF_TC(makelwp); +ATF_TC_HEAD(makelwp, tc) +{ + + atf_tc_set_md_var(tc, "descr", "tests that lwps can be attached to " + "processes"); +} + +ATF_TC_BODY(makelwp, tc) +{ + struct lwp *l; + pid_t pid; + + rump_init(); + RZ(rump_pub_lwproc_newlwp(0)); + ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(37), ESRCH); + l = rump_pub_lwproc_curlwp(); + + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + ATF_REQUIRE(rump_pub_lwproc_curlwp() != l); + l = rump_pub_lwproc_curlwp(); + + RZ(rump_pub_lwproc_newlwp(rump_sys_getpid())); + ATF_REQUIRE(rump_pub_lwproc_curlwp() != l); + + pid = rump_sys_getpid(); + ATF_REQUIRE(pid != -1 && pid != 0); +} + +ATF_TC(proccreds); +ATF_TC_HEAD(proccreds, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check that procs have different creds"); +} + +ATF_TC_BODY(proccreds, tc) +{ + struct lwp *l1, *l2; + + rump_init(); + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + l1 = rump_pub_lwproc_curlwp(); + RZ(rump_pub_lwproc_newlwp(rump_sys_getpid())); + + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + l2 = rump_pub_lwproc_curlwp(); + + RL(rump_sys_setuid(22)); + ATF_REQUIRE_EQ(rump_sys_getuid(), 22); + + rump_pub_lwproc_switch(l1); + ATF_REQUIRE_EQ(rump_sys_getuid(), 0); /* from parent, proc0 */ + RL(rump_sys_setuid(11)); + ATF_REQUIRE_EQ(rump_sys_getuid(), 11); + + rump_pub_lwproc_switch(l2); + ATF_REQUIRE_EQ(rump_sys_getuid(), 22); + rump_pub_lwproc_newlwp(rump_sys_getpid()); + ATF_REQUIRE_EQ(rump_sys_getuid(), 22); +} + + +ATF_TC(inherit); +ATF_TC_HEAD(inherit, tc) +{ + + atf_tc_set_md_var(tc, "descr", "new processes inherit creds from " + "parents"); +} + +ATF_TC_BODY(inherit, tc) +{ + + rump_init(); + + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + RL(rump_sys_setuid(66)); + ATF_REQUIRE_EQ(rump_sys_getuid(), 66); + + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + ATF_REQUIRE_EQ(rump_sys_getuid(), 66); + + /* release lwp and proc */ + rump_pub_lwproc_releaselwp(); + ATF_REQUIRE_EQ(rump_sys_getuid(), 0); +} + +ATF_TC(lwps); +ATF_TC_HEAD(lwps, tc) +{ + + atf_tc_set_md_var(tc, "descr", "proc can hold many lwps and is " + "automatically g/c'd when the last one exits"); +} + +#define LOOPS 128 +ATF_TC_BODY(lwps, tc) +{ + struct lwp *l[LOOPS]; + pid_t mypid; + struct lwp *l_orig; + int i; + + rump_init(); + + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + mypid = rump_sys_getpid(); + RL(rump_sys_setuid(375)); + + l_orig = rump_pub_lwproc_curlwp(); + for (i = 0; i < LOOPS; i++) { + mypid = rump_sys_getpid(); + ATF_REQUIRE(mypid != -1 && mypid != 0); + RZ(rump_pub_lwproc_newlwp(mypid)); + l[i] = rump_pub_lwproc_curlwp(); + ATF_REQUIRE_EQ(rump_sys_getuid(), 375); + } + + rump_pub_lwproc_switch(l_orig); + rump_pub_lwproc_releaselwp(); + for (i = 0; i < LOOPS; i++) { + rump_pub_lwproc_switch(l[i]); + ATF_REQUIRE_EQ(rump_sys_getpid(), mypid); + ATF_REQUIRE_EQ(rump_sys_getuid(), 375); + rump_pub_lwproc_releaselwp(); + ATF_REQUIRE_EQ(rump_sys_getpid(), 1); + ATF_REQUIRE_EQ(rump_sys_getuid(), 0); + } + + ATF_REQUIRE_EQ(rump_pub_lwproc_newlwp(mypid), ESRCH); +} + +ATF_TC(nolwprelease); +ATF_TC_HEAD(nolwprelease, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check that lwp context is required " + "for lwproc_releaselwp()"); +} + +ATF_TC_BODY(nolwprelease, tc) +{ + int status; + + switch (fork()) { + case 0: + rump_init(); + rump_pub_lwproc_releaselwp(); + atf_tc_fail("survived"); + break; + case -1: + atf_tc_fail_errno("fork"); + break; + default: + wait(&status); + ATF_REQUIRE(WIFSIGNALED(status)); + ATF_REQUIRE_EQ(WTERMSIG(status), SIGABRT); + + } +} + +ATF_TC(nolwp); +ATF_TC_HEAD(nolwp, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check that curlwp for an implicit " + "context is NULL"); +} + +ATF_TC_BODY(nolwp, tc) +{ + + rump_init(); + ATF_REQUIRE_EQ(rump_pub_lwproc_curlwp(), NULL); +} + +ATF_TC(nullswitch); +ATF_TC_HEAD(nullswitch, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check that switching to NULL marks " + "current lwp as not running"); +} + +ATF_TC_BODY(nullswitch, tc) +{ + struct lwp *l; + + rump_init(); + RZ(rump_pub_lwproc_newlwp(0)); + l = rump_pub_lwproc_curlwp(); + rump_pub_lwproc_switch(NULL); + /* if remains LP_RUNNING, next call will panic */ + rump_pub_lwproc_switch(l); +} + +ATF_TC(rfork); +ATF_TC_HEAD(rfork, tc) +{ + + atf_tc_set_md_var(tc, "descr", "check that fork shares fd's"); +} + +ATF_TC_BODY(rfork, tc) +{ + struct stat sb; + struct lwp *l, *l2; + int fd; + + RZ(rump_init()); + + ATF_REQUIRE_EQ(rump_pub_lwproc_rfork(RUMP_RFFDG|RUMP_RFCFDG), EINVAL); + + RZ(rump_pub_lwproc_rfork(0)); + l = rump_pub_lwproc_curlwp(); + + RL(fd = rump_sys_open("/file", O_RDWR | O_CREAT, 0777)); + + /* ok, first check rfork(RUMP_RFCFDG) does *not* preserve fd's */ + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + ATF_REQUIRE_ERRNO(EBADF, rump_sys_write(fd, &fd, sizeof(fd)) == -1); + + /* then check that rfork(0) does */ + rump_pub_lwproc_switch(l); + RZ(rump_pub_lwproc_rfork(0)); + ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd)); + RL(rump_sys_fstat(fd, &sb)); + l2 = rump_pub_lwproc_curlwp(); + + /* + * check that the shared fd table is really shared by + * closing fd in parent + */ + rump_pub_lwproc_switch(l); + RL(rump_sys_close(fd)); + rump_pub_lwproc_switch(l2); + ATF_REQUIRE_ERRNO(EBADF, rump_sys_fstat(fd, &sb) == -1); + + /* redo, this time copying the fd table instead of sharing it */ + rump_pub_lwproc_releaselwp(); + rump_pub_lwproc_switch(l); + RL(fd = rump_sys_open("/file", O_RDWR, 0777)); + RZ(rump_pub_lwproc_rfork(RUMP_RFFDG)); + ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd)); + RL(rump_sys_fstat(fd, &sb)); + l2 = rump_pub_lwproc_curlwp(); + + /* check that the fd table is copied */ + rump_pub_lwproc_switch(l); + RL(rump_sys_close(fd)); + rump_pub_lwproc_switch(l2); + RL(rump_sys_fstat(fd, &sb)); + ATF_REQUIRE_EQ(sb.st_size, sizeof(fd)); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, makelwp); + ATF_TP_ADD_TC(tp, proccreds); + ATF_TP_ADD_TC(tp, inherit); + ATF_TP_ADD_TC(tp, lwps); + ATF_TP_ADD_TC(tp, nolwprelease); + ATF_TP_ADD_TC(tp, nolwp); + ATF_TP_ADD_TC(tp, nullswitch); + ATF_TP_ADD_TC(tp, rfork); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/rumpkern/t_modcmd.c b/contrib/netbsd-tests/rump/rumpkern/t_modcmd.c new file mode 100644 index 0000000..e48bcb5 --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/t_modcmd.c @@ -0,0 +1,182 @@ +/* $NetBSD: t_modcmd.c,v 1.10 2017/01/13 21:30:43 christos Exp $ */ + +/* + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "h_macros.h" +/* + * We verify that modules can be loaded and unloaded. + * tmpfs was chosen because it does not depend on an image. + */ + +ATF_TC(cmsg_modcmd); +ATF_TC_HEAD(cmsg_modcmd, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that loading and unloading " + "a module (vfs/tmpfs) is possible"); +} + +static int +disable_autoload(void) +{ + struct sysctlnode q, ans[256]; + int mib[3]; + size_t alen; + unsigned i; + bool no; + + mib[0] = CTL_KERN; + mib[1] = CTL_QUERY; + alen = sizeof(ans); + + memset(&q, 0, sizeof(q)); + q.sysctl_flags = SYSCTL_VERSION; + + if (rump_sys___sysctl(mib, 2, ans, &alen, &q, sizeof(q)) == -1) + return -1; + + for (i = 0; i < __arraycount(ans); i++) + if (strcmp("module", ans[i].sysctl_name) == 0) + break; + if (i == __arraycount(ans)) { + errno = ENOENT; + return -1; + } + + mib[1] = ans[i].sysctl_num; + mib[2] = CTL_QUERY; + + if (rump_sys___sysctl(mib, 3, ans, &alen, &q, sizeof(q)) == -1) + return errno; + + for (i = 0; i < __arraycount(ans); i++) + if (strcmp("autoload", ans[i].sysctl_name) == 0) + break; + if (i == __arraycount(ans)) { + errno = ENOENT; + return -1; + } + + mib[2] = ans[i].sysctl_num; + + no = false; + alen = 0; + if (rump_sys___sysctl(mib, 3, NULL, &alen, &no, sizeof(no)) == -1) + return errno; + + return 0; + +} + +#define TMPFSMODULE "librumpfs_tmpfs.so" +ATF_TC_BODY(cmsg_modcmd, tc) +{ + struct tmpfs_args args; + const struct modinfo *const *mi_start, *const *mi_end; + void *handle; + int i, rv, loop = 0; + + rump_init(); + + if (disable_autoload() == -1) + atf_tc_fail_errno("count not disable module autoload"); + + memset(&args, 0, sizeof(args)); + args.ta_version = TMPFS_ARGS_VERSION; + args.ta_root_mode = 0777; + + if (rump_sys_mkdir("/mp", 0777) == -1) + atf_tc_fail_errno("mkdir mountpoint"); + if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) != -1) + atf_tc_fail("mount unexpectedly succeeded"); + + handle = dlopen(TMPFSMODULE, RTLD_GLOBAL); + if (handle == NULL) { + const char *dlmsg = dlerror(); + atf_tc_fail("cannot open %s: %s", TMPFSMODULE, dlmsg); + } + + again: + mi_start = dlsym(handle, "__start_link_set_modules"); + mi_end = dlsym(handle, "__stop_link_set_modules"); + if (mi_start == NULL || mi_end == NULL) + atf_tc_fail("cannot find module info"); + if ((rv = rump_pub_module_init(mi_start, (size_t)(mi_end-mi_start)))!=0) + atf_tc_fail("module init failed: %d (%s)", rv, strerror(rv)); + if ((rv = rump_pub_module_init(mi_start, (size_t)(mi_end-mi_start)))==0) + atf_tc_fail("module double init succeeded"); + + if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) == -1) + atf_tc_fail_errno("still cannot mount"); + if (rump_sys_unmount("/mp", 0) == -1) + atf_tc_fail("cannot unmount"); + for (i = 0; i < (int)(mi_end-mi_start); i++) { + if ((rv = rump_pub_module_fini(mi_start[i])) != 0) + atf_tc_fail("module fini failed: %d (%s)", + rv, strerror(rv)); + } + for (i = 0; i < (int)(mi_end-mi_start); i++) { + if ((rv = rump_pub_module_fini(mi_start[i])) == 0) + atf_tc_fail("module double fini succeeded"); + } + if (loop++ == 0) + goto again; + + if (dlclose(handle)) { + const char *dlmsg = dlerror(); + atf_tc_fail("cannot close %s: %s", TMPFSMODULE, dlmsg); + } + + if (rump_sys_mount(MOUNT_TMPFS, "/mp", 0, &args, sizeof(args)) != -1) + atf_tc_fail("mount unexpectedly succeeded"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, cmsg_modcmd); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/rumpkern/t_modlinkset.c b/contrib/netbsd-tests/rump/rumpkern/t_modlinkset.c new file mode 100644 index 0000000..7d725dc --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/t_modlinkset.c @@ -0,0 +1,73 @@ +/* $NetBSD: t_modlinkset.c,v 1.3 2017/01/13 21:30:43 christos Exp $ */ + +/* + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "h_macros.h" + +ATF_TC(modlinkset); +ATF_TC_HEAD(modlinkset, tc) +{ + atf_tc_set_md_var(tc, "descr", "Check that module linkset bootstrap " + "works"); +} + +/* + * We link against cd9660 and msdosfs (both chosed because the names + * are unlikely to ever be a substring of a another file system). + * Without proper linkset handling at most one will be reported. + */ +ATF_TC_BODY(modlinkset, tc) +{ + char buf[1024]; + + rump_init(); + if (ukfs_vfstypes(buf, sizeof(buf)) == -1) + atf_tc_fail_errno("ukfs_vfstypes"); + + ATF_CHECK((strstr(buf, "msdos") != NULL)); + ATF_CHECK((strstr(buf, "cd9660") != NULL)); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, modlinkset); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/rumpkern/t_signals.c b/contrib/netbsd-tests/rump/rumpkern/t_signals.c new file mode 100644 index 0000000..ba0c0ea --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/t_signals.c @@ -0,0 +1,127 @@ +/* $NetBSD: t_signals.c,v 1.3 2017/01/13 21:30:43 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include + +#include +#include +#include +#include +#include + +#include + +#include "../kernspace/kernspace.h" +#include "h_macros.h" + +ATF_TC(sigraise); +ATF_TC_HEAD(sigraise, tc) +{ + + atf_tc_set_md_var(tc, "descr", "RUMP_SIGMODEL_RAISE"); +} + +ATF_TC(sigignore); +ATF_TC_HEAD(sigignore, tc) +{ + + atf_tc_set_md_var(tc, "descr", "RUMP_SIGMODEL_IGNORE"); +} + +ATF_TC(sigpanic); +ATF_TC_HEAD(sigpanic, tc) +{ + + atf_tc_set_md_var(tc, "descr", "RUMP_SIGMODEL_PANIC"); +} + +static volatile sig_atomic_t sigcnt; +static void +thehand(int sig) +{ + + sigcnt++; +} + +ATF_TC_BODY(sigraise, tc) +{ + + signal(SIGUSR2, thehand); + rump_boot_setsigmodel(RUMP_SIGMODEL_RAISE); + + rump_init(); + rump_schedule(); + rumptest_localsig(SIGUSR2); + rump_unschedule(); + ATF_REQUIRE_EQ(sigcnt, 1); +} + +ATF_TC_BODY(sigignore, tc) +{ + + rump_boot_setsigmodel(RUMP_SIGMODEL_IGNORE); + + rump_init(); + rump_schedule(); + rumptest_localsig(SIGKILL); + rump_unschedule(); +} + +ATF_TC_BODY(sigpanic, tc) +{ + int status; + + rump_boot_setsigmodel(RUMP_SIGMODEL_PANIC); + + switch (fork()) { + case 0: + rump_init(); + rump_schedule(); + rumptest_localsig(SIGCONT); + /* NOTREACHED */ + exit(1); + default: + wait(&status); + ATF_REQUIRE(WIFSIGNALED(status) && WTERMSIG(status) == SIGABRT); + break; + case -1: + atf_tc_fail_errno("fork"); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, sigraise); + ATF_TP_ADD_TC(tp, sigignore); + ATF_TP_ADD_TC(tp, sigpanic); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/rumpkern/t_sp.sh b/contrib/netbsd-tests/rump/rumpkern/t_sp.sh new file mode 100755 index 0000000..2c4404a --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/t_sp.sh @@ -0,0 +1,129 @@ +# $NetBSD: t_sp.sh,v 1.13 2016/08/10 23:47:14 kre Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +test_case() +{ + local name="${1}"; shift + local check_function="${1}"; shift + + atf_test_case "${name}" cleanup + eval "${name}_head() { }" + eval "${name}_body() { \ + ${check_function} " "${@}" "; \ + }" + eval "${name}_cleanup() { \ + RUMP_SERVER=unix://commsock rump.halt + }" +} + +test_case basic basic +test_case stress_short stress 1 +test_case stress_long stress 2 +test_case stress_killer stress 5 kill +test_case fork_simple fork simple +test_case fork_pipecomm fork pipecomm +test_case fork_fakeauth fork fakeauth +test_case sigsafe sigsafe sigsafe +test_case signal signal +test_case reconnect reconnect + +basic() +{ + export RUMP_SERVER=unix://commsock + atf_check -s exit:0 rump_server ${RUMP_SERVER} + atf_check -s exit:0 $(atf_get_srcdir)/h_client/h_simplecli +} + +stress_short_head() +{ + atf_set "require.memory" "64M" +} + +stress_long_head() +{ + atf_set "require.memory" "64M" +} + +stress() +{ + + export RUMP_SERVER=unix://commsock + atf_check -s exit:0 rump_server \ + -lrumpvfs -lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpdev \ + ${RUMP_SERVER} + atf_check -s exit:0 -e ignore $(atf_get_srcdir)/h_client/h_stresscli $@ +} + +fork() +{ + + export RUMP_SERVER=unix://commsock + atf_check -s exit:0 rump_server -lrumpvfs -lrumpdev ${RUMP_SERVER} + atf_check -s exit:0 $(atf_get_srcdir)/h_client/h_forkcli ${1} +} + +sigsafe() +{ + + export RUMP_SERVER=unix://commsock + atf_check -s exit:0 rump_server ${RUMP_SERVER} + atf_check -s exit:0 $(atf_get_srcdir)/h_client/h_sigcli + +} + +signal() +{ + + export RUMP_SERVER=unix://commsock + atf_check -s exit:0 $(atf_get_srcdir)/h_server/h_simpleserver \ + ${RUMP_SERVER} sendsig 27 + atf_check -s signal:27 $(atf_get_srcdir)/h_client/h_simplecli block +} + +reconnect() +{ + + + export RUMP_SERVER=unix://commsock + atf_check -s exit:0 rump_server ${RUMP_SERVER} + atf_check -s exit:0 -e ignore $(atf_get_srcdir)/h_client/h_reconcli 2 +} + +atf_init_test_cases() +{ + + atf_add_test_case basic + atf_add_test_case stress_short + atf_add_test_case stress_long + atf_add_test_case stress_killer + atf_add_test_case fork_simple + atf_add_test_case fork_pipecomm + atf_add_test_case fork_fakeauth + atf_add_test_case sigsafe + atf_add_test_case signal + atf_add_test_case reconnect +} diff --git a/contrib/netbsd-tests/rump/rumpkern/t_threads.c b/contrib/netbsd-tests/rump/rumpkern/t_threads.c new file mode 100644 index 0000000..2931fa6 --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/t_threads.c @@ -0,0 +1,81 @@ +/* $NetBSD: t_threads.c,v 1.2 2017/01/13 21:30:43 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include + +#include + +#include "h_macros.h" +#include "../kernspace/kernspace.h" + +ATF_TC(threadjoin); +ATF_TC_HEAD(threadjoin, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks joinable threads work"); +} + +ATF_TC_BODY(threadjoin, tc) +{ + + rump_init(); + + rump_schedule(); + rumptest_threadjoin(); /* panics if fails */ + rump_unschedule(); +} + +ATF_TC(kthread); +ATF_TC_HEAD(kthread, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks kthread_create/exit works"); +} + +ATF_TC_BODY(kthread, tc) +{ + + rump_init(); + + rump_schedule(); + rumptest_threadjoin(); /* panics if fails */ + rump_unschedule(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, threadjoin); + ATF_TP_ADD_TC(tp, kthread); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/rumpkern/t_tsleep.c b/contrib/netbsd-tests/rump/rumpkern/t_tsleep.c new file mode 100644 index 0000000..126a89d --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/t_tsleep.c @@ -0,0 +1,63 @@ +/* $NetBSD: t_tsleep.c,v 1.2 2017/01/13 21:30:43 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include + +#include + +#include "h_macros.h" +#include "../kernspace/kernspace.h" + +ATF_TC(tsleep); +ATF_TC_HEAD(tsleep, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check tsleep variants"); +} + +ATF_TC_BODY(tsleep, tc) +{ + + rump_init(); + + rump_schedule(); + rumptest_tsleep(); /* panics if fails */ + rump_unschedule(); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, tsleep); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/rumpkern/t_vm.c b/contrib/netbsd-tests/rump/rumpkern/t_vm.c new file mode 100644 index 0000000..ddb005c --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpkern/t_vm.c @@ -0,0 +1,91 @@ +/* $NetBSD: t_vm.c,v 1.4 2017/01/13 21:30:43 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include + +#include +#include +#include + +#include "h_macros.h" +#include "../kernspace/kernspace.h" + +ATF_TC(busypage); +ATF_TC_HEAD(busypage, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks VM pagewaits work"); +} + +ATF_TC_BODY(busypage, tc) +{ + + rump_init(); + + rump_schedule(); + rumptest_busypage(); + rump_unschedule(); +} + +ATF_TC(uvmwait); +ATF_TC_HEAD(uvmwait, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Tests that uvm_wait works"); + atf_tc_set_md_var(tc, "timeout", "30"); +} + +#define UVMWAIT_LIMIT 1024*1024 +ATF_TC_BODY(uvmwait, tc) +{ + char buf[64]; + + /* limit rump kernel memory */ + snprintf(buf, sizeof(buf), "%d", UVMWAIT_LIMIT); + setenv("RUMP_MEMLIMIT", buf, 1); + + rump_init(); + + rump_schedule(); + rumptest_alloc(UVMWAIT_LIMIT); + rump_unschedule(); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, busypage); + ATF_TP_ADD_TC(tp, uvmwait); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/rumpnet/t_shmif.sh b/contrib/netbsd-tests/rump/rumpnet/t_shmif.sh new file mode 100755 index 0000000..4de8b4f --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpnet/t_shmif.sh @@ -0,0 +1,80 @@ +# $NetBSD: t_shmif.sh,v 1.3 2016/08/10 23:49:03 kre Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case crossping cleanup + +NKERN=8 + +crossping_head() +{ + atf_set "descr" "run $NKERN rump kernels on one shmif bus and crossping" +} + +startserver() +{ + + export RUMP_SERVER=unix://sock${1} + atf_check -s exit:0 rump_server -lrumpnet -lrumpnet_net \ + -lrumpnet_netinet -lrumpnet_shmif -lrumpdev ${RUMP_SERVER} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus + atf_check -s exit:0 rump.ifconfig shmif0 inet 1.1.1.${1} +} + +pingothers() +{ + +} + +crossping_body() +{ + + for x in `jot ${NKERN}` ; do startserver $x ; done + for x in `jot ${NKERN}` + do + export RUMP_SERVER=unix://sock${x} + for y in `jot ${NKERN}` + do + [ ${y} -eq ${x} ] && continue + atf_check -s exit:0 -o ignore -e ignore \ + rump.ping -c 1 1.1.1.${y} + done + done +} + +crossping_cleanup() +{ + + for x in `jot ${NKERN}` ; do RUMP_SERVER=unix://sock${x} rump.halt ;done + : +} + +atf_init_test_cases() +{ + + atf_add_test_case crossping +} diff --git a/contrib/netbsd-tests/rump/rumpvfs/t_basic.c b/contrib/netbsd-tests/rump/rumpvfs/t_basic.c new file mode 100644 index 0000000..278d99e --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpvfs/t_basic.c @@ -0,0 +1,81 @@ +/* $NetBSD: t_basic.c,v 1.3 2017/01/13 21:30:43 christos Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "h_macros.h" + +ATF_TC(lseekrv); +ATF_TC_HEAD(lseekrv, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Test lseek return values"); +} + +#define TESTFILE "testi" + +#define FIVE_MEGS (5*1024*1024) +#define FIVE_GIGS (5*1024*1024*1024LL) + +ATF_TC_BODY(lseekrv, tc) +{ + off_t rv; + int fd; + + RZ(rump_init()); + RL(fd = rump_sys_open(TESTFILE, O_RDWR | O_CREAT, 0777)); + + rv = rump_sys_lseek(37, FIVE_MEGS, SEEK_SET); + ATF_REQUIRE_ERRNO(EBADF, rv == -1); + + rv = rump_sys_lseek(fd, FIVE_MEGS, SEEK_SET); + ATF_REQUIRE_EQ(rv, FIVE_MEGS); + + rv = rump_sys_lseek(fd, FIVE_GIGS, SEEK_SET); + ATF_REQUIRE_EQ(rv, FIVE_GIGS); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, lseekrv); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/rumpvfs/t_etfs.c b/contrib/netbsd-tests/rump/rumpvfs/t_etfs.c new file mode 100644 index 0000000..5935bea --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpvfs/t_etfs.c @@ -0,0 +1,302 @@ +/* $NetBSD: t_etfs.c,v 1.11 2017/01/13 21:30:43 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "h_macros.h" + +ATF_TC(reregister_reg); +ATF_TC_HEAD(reregister_reg, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Tests register/unregister/register " + "for a regular file"); +} + +#define TESTSTR1 "hi, it's me again!" +#define TESTSTR1SZ (sizeof(TESTSTR1)-1) + +#define TESTSTR2 "what about the old vulcan proverb?" +#define TESTSTR2SZ (sizeof(TESTSTR2)-1) + +#define TESTPATH1 "/trip/to/the/moon" +#define TESTPATH2 "/but/not/the/dark/size" +ATF_TC_BODY(reregister_reg, tc) +{ + char buf[1024]; + int localfd, etcfd; + ssize_t n; + int tfd; + + etcfd = open("/etc/passwd", O_RDONLY); + ATF_REQUIRE(etcfd != -1); + + localfd = open("./testfile", O_RDWR | O_CREAT, 0666); + ATF_REQUIRE(localfd != -1); + + ATF_REQUIRE_EQ(write(localfd, TESTSTR1, TESTSTR1SZ), TESTSTR1SZ); + /* testfile now contains test string */ + + rump_init(); + + ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH1, "/etc/passwd", + RUMP_ETFS_REG), 0); + tfd = rump_sys_open(TESTPATH1, O_RDONLY); + ATF_REQUIRE(tfd != -1); + ATF_REQUIRE(rump_sys_read(tfd, buf, sizeof(buf)) > 0); + rump_sys_close(tfd); + rump_pub_etfs_remove(TESTPATH1); + + ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH2, "./testfile", + RUMP_ETFS_REG), 0); + tfd = rump_sys_open(TESTPATH2, O_RDWR); + ATF_REQUIRE(tfd != -1); + memset(buf, 0, sizeof(buf)); + ATF_REQUIRE((n = rump_sys_read(tfd, buf, sizeof(buf))) > 0); + + /* check that we have what we expected */ + ATF_REQUIRE_STREQ(buf, TESTSTR1); + + /* ... while here, check that writing works too */ + ATF_REQUIRE_EQ(rump_sys_lseek(tfd, 0, SEEK_SET), 0); + ATF_REQUIRE(TESTSTR1SZ <= TESTSTR2SZ); + ATF_REQUIRE_EQ(rump_sys_write(tfd, TESTSTR2, TESTSTR2SZ), TESTSTR2SZ); + + memset(buf, 0, sizeof(buf)); + ATF_REQUIRE_EQ(lseek(localfd, 0, SEEK_SET), 0); + ATF_REQUIRE(read(localfd, buf, sizeof(buf)) > 0); + ATF_REQUIRE_STREQ(buf, TESTSTR2); + close(etcfd); + close(localfd); +} + +ATF_TC(reregister_blk); +ATF_TC_HEAD(reregister_blk, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Tests register/unregister/register " + "for a block device"); +} + +ATF_TC_BODY(reregister_blk, tc) +{ + char buf[512 * 128]; + char cmpbuf[512 * 128]; + int rv, tfd; + + /* first, create some image files */ + rv = system("dd if=/dev/zero bs=512 count=64 " + "| tr '\\0' '\\1' > disk1.img"); + ATF_REQUIRE_EQ(rv, 0); + + rv = system("dd if=/dev/zero bs=512 count=128 " + "| tr '\\0' '\\2' > disk2.img"); + ATF_REQUIRE_EQ(rv, 0); + + rump_init(); + + ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH1, "./disk1.img", + RUMP_ETFS_BLK), 0); + tfd = rump_sys_open(TESTPATH1, O_RDONLY); + ATF_REQUIRE(tfd != -1); + ATF_REQUIRE_EQ(rump_sys_read(tfd, buf, sizeof(buf)), 64*512); + memset(cmpbuf, 1, sizeof(cmpbuf)); + ATF_REQUIRE_EQ(memcmp(buf, cmpbuf, 64*512), 0); + ATF_REQUIRE_EQ(rump_sys_close(tfd), 0); + ATF_REQUIRE_EQ(rump_pub_etfs_remove(TESTPATH1), 0); + + ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH2, "./disk2.img", + RUMP_ETFS_BLK), 0); + tfd = rump_sys_open(TESTPATH2, O_RDONLY); + ATF_REQUIRE(tfd != -1); + ATF_REQUIRE_EQ(rump_sys_read(tfd, buf, sizeof(buf)), 128*512); + memset(cmpbuf, 2, sizeof(cmpbuf)); + ATF_REQUIRE_EQ(memcmp(buf, cmpbuf, 128*512), 0); + ATF_REQUIRE_EQ(rump_sys_close(tfd), 0); + ATF_REQUIRE_EQ(rump_pub_etfs_remove(TESTPATH2), 0); +} + +ATF_TC_WITH_CLEANUP(large_blk); +ATF_TC_HEAD(large_blk, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Check etfs block devices work for " + ">2TB images"); +} + +#define IMG_ON_MFS "mfsdir/disk.img" +ATF_TC_BODY(large_blk, tc) +{ + char buf[128]; + char cmpbuf[128]; + ssize_t n; + int rv, tfd; + + /* + * mount mfs. it would be nice if this would not be required, + * but a) tmpfs doesn't "support" sparse files b) we don't really + * know what fs atf workdir is on anyway. + */ + if (mkdir("mfsdir", 0777) == -1) + atf_tc_fail_errno("mkdir failed"); + if (system("mount_mfs -s 64m -o nosuid,nodev mfs mfsdir") != 0) + atf_tc_skip("could not mount mfs"); + + /* create a 8TB sparse file */ + rv = system("dd if=/dev/zero of=" IMG_ON_MFS " bs=1 count=1 seek=8t"); + ATF_REQUIRE_EQ(rv, 0); + + /* + * map it and issue write at 6TB, then unmap+remap and check + * we get the same stuff back + */ + + rump_init(); + ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH1, IMG_ON_MFS, + RUMP_ETFS_BLK), 0); + tfd = rump_sys_open(TESTPATH1, O_RDWR); + ATF_REQUIRE(tfd != -1); + memset(buf, 12, sizeof(buf)); + n = rump_sys_pwrite(tfd, buf, sizeof(buf), 6*1024*1024*1024ULL*1024ULL); + ATF_REQUIRE_EQ(n, sizeof(buf)); + ATF_REQUIRE_EQ(rump_sys_close(tfd), 0); + ATF_REQUIRE_EQ(rump_pub_etfs_remove(TESTPATH1), 0); + + ATF_REQUIRE_EQ(rump_pub_etfs_register(TESTPATH2, IMG_ON_MFS, + RUMP_ETFS_BLK), 0); + tfd = rump_sys_open(TESTPATH2, O_RDWR); + ATF_REQUIRE(tfd != -1); + memset(buf, 0, sizeof(buf)); + n = rump_sys_pread(tfd, buf, sizeof(buf), 6*1024*1024*1024ULL*1024ULL); + ATF_REQUIRE_EQ(n, sizeof(buf)); + + memset(cmpbuf, 12, sizeof(cmpbuf)); + ATF_REQUIRE_EQ(memcmp(cmpbuf, buf, 128), 0); +} + +ATF_TC_CLEANUP(large_blk, tc) +{ + + system("umount mfsdir"); +} + +ATF_TC(range_blk); +ATF_TC_HEAD(range_blk, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks ranged (offset,size) mappings"); +} + +ATF_TC_BODY(range_blk, tc) +{ + char buf[32000]; + char cmpbuf[32000]; + ssize_t n; + int rv, tfd; + + /* create a 64000 byte file with 16 1's at offset = 32000 */ + rv = system("dd if=/dev/zero of=disk.img bs=1000 count=64"); + ATF_REQUIRE_EQ(rv, 0); + rv = system("yes | tr '\\ny' '\\1' " + "| dd of=disk.img conv=notrunc bs=1 count=16 seek=32000"); + ATF_REQUIRE_EQ(rv, 0); + + /* map the file at [16000,48000]. this puts our 1's at offset 16000 */ + rump_init(); + ATF_REQUIRE_EQ(rump_pub_etfs_register_withsize(TESTPATH1, "disk.img", + RUMP_ETFS_BLK, 16000, 32000), 0); + tfd = rump_sys_open(TESTPATH1, O_RDWR); + ATF_REQUIRE(tfd != -1); + n = rump_sys_read(tfd, buf, sizeof(buf)); + ATF_REQUIRE_EQ(n, sizeof(buf)); + ATF_REQUIRE_EQ(rump_sys_close(tfd), 0); + ATF_REQUIRE_EQ(rump_pub_etfs_remove(TESTPATH1), 0); + + /* check that we got what is expected */ + memset(cmpbuf, 0, sizeof(cmpbuf)); + memset(cmpbuf+16000, 1, 16); + ATF_REQUIRE_EQ(memcmp(buf, cmpbuf, sizeof(buf)), 0); +} + +ATF_TC(key); +ATF_TC_HEAD(key, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Checks key format"); +} + +ATF_TC_BODY(key, tc) +{ + + RZ(rump_init()); + + RL(open("hostfile", O_RDWR | O_CREAT, 0777)); + + RZ(rump_pub_etfs_register("/key", "hostfile", RUMP_ETFS_REG)); + ATF_REQUIRE_EQ(rump_pub_etfs_register("key", "hostfile", RUMP_ETFS_REG), + EINVAL); + + RL(rump_sys_open("/key", O_RDONLY)); + RL(rump_sys_open("////////key", O_RDONLY)); + + RZ(rump_pub_etfs_register("////key//with/slashes", "hostfile", + RUMP_ETFS_REG)); + + RL(rump_sys_open("/key//with/slashes", O_RDONLY)); + RL(rump_sys_open("key//with/slashes", O_RDONLY)); + ATF_REQUIRE_ERRNO(ENOENT, + rump_sys_open("/key/with/slashes", O_RDONLY) == -1); + + RL(rump_sys_mkdir("/a", 0777)); + ATF_REQUIRE_ERRNO(ENOENT, + rump_sys_open("/a/key//with/slashes", O_RDONLY) == -1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, reregister_reg); + ATF_TP_ADD_TC(tp, reregister_blk); + ATF_TP_ADD_TC(tp, large_blk); + ATF_TP_ADD_TC(tp, range_blk); + ATF_TP_ADD_TC(tp, key); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/rump/rumpvfs/t_p2kifs.c b/contrib/netbsd-tests/rump/rumpvfs/t_p2kifs.c new file mode 100644 index 0000000..ec2423c --- /dev/null +++ b/contrib/netbsd-tests/rump/rumpvfs/t_p2kifs.c @@ -0,0 +1,93 @@ +/* $NetBSD: t_p2kifs.c,v 1.6 2017/01/13 21:30:43 christos Exp $ */ + +/*- + * Copyright (c) 2010 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "h_macros.h" + +ATF_TC(makecn); +ATF_TC_HEAD(makecn, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Tests makecn/LOOKUP/freecn"); +} + +#define TESTFILE "testi" + +ATF_TC_BODY(makecn, tc) +{ + struct componentname *cn; + char pathstr[MAXPATHLEN] = TESTFILE; + struct vnode *vp; + extern struct vnode *rumpns_rootvnode; + + rump_init(); + + /* + * Strategy is to create a componentname, edit the passed + * string, and then do a lookup with the componentname. + */ + RL(rump_sys_mkdir("/" TESTFILE, 0777)); + + /* need stable lwp for componentname */ + RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); + + /* try it once with the right path */ + cn = rump_pub_makecn(RUMP_NAMEI_LOOKUP, 0, pathstr, strlen(pathstr), + rump_pub_cred_create(0, 0, 0, NULL), rump_pub_lwproc_curlwp()); + RZ(RUMP_VOP_LOOKUP(rumpns_rootvnode, &vp, cn)); + rump_pub_freecn(cn, RUMPCN_FREECRED); + + /* and then with modification-in-the-middle */ + cn = rump_pub_makecn(RUMP_NAMEI_LOOKUP, 0, pathstr, strlen(pathstr), + rump_pub_cred_create(0, 0, 0, NULL), rump_pub_lwproc_curlwp()); + strcpy(pathstr, "/muuta"); + RZ(RUMP_VOP_LOOKUP(rumpns_rootvnode, &vp, cn)); + rump_pub_freecn(cn, RUMPCN_FREECRED); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, makecn); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/sbin/fsck_ffs/quotas_common.sh b/contrib/netbsd-tests/sbin/fsck_ffs/quotas_common.sh new file mode 100755 index 0000000..7d4ab58 --- /dev/null +++ b/contrib/netbsd-tests/sbin/fsck_ffs/quotas_common.sh @@ -0,0 +1,44 @@ +# $NetBSD: quotas_common.sh,v 1.2 2011/03/06 17:08:41 bouyer Exp $ + +create_with_quotas() +{ + local endian=$1; shift + local vers=$1; shift + local uid=$(id -u) + local gid=$(id -g) + + atf_check -o ignore -e ignore newfs -B ${endian} -O ${vers} \ + -s 4000 -F ${IMG} + atf_check -o ignore -e ignore tunefs -q user -q group -F ${IMG} + atf_check -s exit:0 -o 'match:NO USER QUOTA INODE \(CREATED\)' \ + -o 'match:USER QUOTA MISMATCH FOR ID '${uid}': 0/0 SHOULD BE 1/1' \ + -o 'match:GROUP QUOTA MISMATCH FOR ID '${gid}': 0/0 SHOULD BE 1/1' \ + fsck_ffs -p -F ${IMG} +} + +# from tests/ipf/h_common.sh via tests/sbin/resize_ffs +test_case() +{ + local name="${1}"; shift + local check_function="${1}"; shift + local descr="${1}"; shift + + atf_test_case "${name}" + + eval "${name}_head() { \ + atf_set "descr" "Checks ${descr} quotas inodes" + }" + eval "${name}_body() { \ + ${check_function} " "${@}" "; \ + }" + tests="${tests} ${name}" +} + +atf_init_test_cases() +{ + IMG=fsimage + DIR=target + for i in ${tests}; do + atf_add_test_case $i + done +} diff --git a/contrib/netbsd-tests/sbin/fsck_ffs/t_check_quotas.sh b/contrib/netbsd-tests/sbin/fsck_ffs/t_check_quotas.sh new file mode 100755 index 0000000..804c5b5 --- /dev/null +++ b/contrib/netbsd-tests/sbin/fsck_ffs/t_check_quotas.sh @@ -0,0 +1,73 @@ +# $NetBSD: t_check_quotas.sh,v 1.2 2011/03/06 17:08:41 bouyer Exp $ +# +# Copyright (c) 2011 Manuel Bouyer +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +for e in le be; do + for v in 1 2; do + test_case corrupt_list_${e}_${v} corrupt_list \ + "recovery of corrupted free list in" ${e} ${v} + test_case expand1_list_${e}_${v} expand_list \ + "allocation of direct block in" 40 ${e} ${v} + test_case expand2_list_${e}_${v} expand_list \ + "allocation of indirect block in" 1000 ${e} ${v} + done +done + +corrupt_list() +{ + create_with_quotas $* + local blkno=$(printf "inode 3\nblks\n" | /sbin/fsdb -nF -f ${IMG} | awk '$1 == "0:" {print $2}') + blkno=$(($blkno * 512 + 104)) + #clear the free list + atf_check -o ignore -e ignore dd if=/dev/zero of=${IMG} bs=1 \ + count=8 seek=${blkno} conv=notrunc + atf_check -s exit:0 \ + -o "match:QUOTA ENTRY NOT IN LIST \(FIXED\)" \ + fsck_ffs -fp -F ${IMG} + atf_check -s exit:0 -o "match:3 files" fsck_ffs -nf -F ${IMG} +} + +expand_list() +{ + local nuid=$1; shift + local expected_files=$((nuid + 2)) + echo "/set uid=0 gid=0" > spec + echo ". type=dir mode=0755" >> spec + mkdir ${DIR} + for i in $(seq ${nuid}); do + touch ${DIR}/f${i} + echo "./f$i type=file mode=0600 uid=$i gid=$i" >> spec + done + + atf_check -o ignore -e ignore makefs -B $1 -o version=$2 \ + -F spec -s 4000b ${IMG} ${DIR} + atf_check -o ignore -e ignore tunefs -q user -F ${IMG} + atf_check -s exit:0 -o 'match:NO USER QUOTA INODE \(CREATED\)' \ + -o 'match:USER QUOTA MISMATCH FOR ID 10: 0/0 SHOULD BE 0/1' \ + fsck_ffs -p -F ${IMG} + atf_check -s exit:0 -o "match:${expected_files} files" \ + fsck_ffs -nf -F ${IMG} +} diff --git a/contrib/netbsd-tests/sbin/fsck_ffs/t_enable_quotas.sh b/contrib/netbsd-tests/sbin/fsck_ffs/t_enable_quotas.sh new file mode 100755 index 0000000..3148911 --- /dev/null +++ b/contrib/netbsd-tests/sbin/fsck_ffs/t_enable_quotas.sh @@ -0,0 +1,105 @@ +# $NetBSD: t_enable_quotas.sh,v 1.2 2011/03/06 17:08:41 bouyer Exp $ +# +# Copyright (c) 2011 Manuel Bouyer +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +for e in le be; do + for v in 1 2; do + test_case disable_${e}_${v} disable_quotas "creation/removal of" ${e} ${v} + test_case corrupt_${e}_${v} corrupt_quotas "repair of corrupted" ${e} ${v} + test_case unallocated_${e}_${v} unallocated_quotas \ + "recovery of unallocated" ${e} ${v} + test_case dir1_${e}_${v} dir1_quotas \ + "successfull clear of wrong type of" ${e} ${v} + test_case notreg_${e}_${v} notreg_quotas \ + "successfull clear of wrong type of" ${e} ${v} + done +done + +disable_quotas() +{ + create_with_quotas $* + +# check that the quota inode creation didn't corrupt the filesystem + atf_check -s exit:0 -o "match:already clean" -o "match:3 files" \ + fsck_ffs -nf -F ${IMG} +#now check fsck can properly clear the quota inode when quota flags are +# cleared + atf_check -o ignore -e ignore tunefs -q nouser -q nogroup -F ${IMG} + atf_check -s exit:0 -o "match:SUPERBLOCK QUOTA FLAG CLEARED" \ + fsck_ffs -fp -F ${IMG} + atf_check -s exit:0 -o "match:1 files, 1 used" fsck_ffs -nf -F ${IMG} +} + +corrupt_quotas() +{ + create_with_quotas $* + + local blkno=$(printf "inode 3\nblks\n" | /sbin/fsdb -nF -f ${IMG} | awk '$1 == "0:" {print $2}') + atf_check -o ignore -e ignore dd if=/dev/zero of=${IMG} bs=512 \ + count=1 seek=${blkno} conv=notrunc + atf_check -s exit:0 \ + -o "match:CORRUPTED USER QUOTA INODE 3 \(CLEARED\)" \ + -o "match:NO USER QUOTA INODE \(CREATED\)" \ + fsck_ffs -fp -F ${IMG} + atf_check -s exit:0 -o "match:3 files" fsck_ffs -nf -F ${IMG} +} + +unallocated_quotas() +{ + create_with_quotas $* + + atf_check -o ignore -e ignore clri ${IMG} 3 + atf_check -s exit:0 \ + -o "match:UNALLOCATED USER QUOTA INODE 3 \(CLEARED\)" \ + -o "match:NO USER QUOTA INODE \(CREATED\)" \ + fsck_ffs -fp -F ${IMG} + atf_check -s exit:0 -o "match:3 files" fsck_ffs -nf -F ${IMG} +} + +dir1_quotas() +{ + create_with_quotas $* + + atf_check -s exit:255 -o ignore -e ignore -x \ + "printf 'inode 3\nchtype dir\nexit\n' | fsdb -F -f ${IMG}" + atf_check -s exit:0 \ + -o "match:DIR I=3 CONNECTED. PARENT WAS I=0" \ + -o "match:USER QUOTA INODE 3 IS A DIRECTORY" \ + fsck_ffs -y -F ${IMG} +} + +notreg_quotas() +{ + create_with_quotas $* + + atf_check -s exit:255 -o ignore -e ignore -x \ + "printf 'inode 3\nchtype fifo\nexit\n' | fsdb -F -f ${IMG}" + atf_check -s exit:0 \ + -o "match:WRONG TYPE 4096 for USER QUOTA INODE 3 \(CLEARED\)" \ + -o "match:NO USER QUOTA INODE \(CREATED\)" \ + fsck_ffs -p -F ${IMG} + atf_check -s exit:0 -o "match:3 files" fsck_ffs -nf -F ${IMG} +} diff --git a/contrib/netbsd-tests/sbin/gpt/gpt.2part.show.label b/contrib/netbsd-tests/sbin/gpt/gpt.2part.show.label new file mode 100644 index 0000000..dfb2b99 --- /dev/null +++ b/contrib/netbsd-tests/sbin/gpt/gpt.2part.show.label @@ -0,0 +1,8 @@ + start size index contents + 0 1 PMBR + 1 1 Pri GPT header + 2 32 Pri GPT table + 34 1024 1 GPT part - potato + 1058 9150 2 GPT part - tomato + 10208 32 Sec GPT table + 10240 1 Sec GPT header diff --git a/contrib/netbsd-tests/sbin/gpt/gpt.2part.show.normal b/contrib/netbsd-tests/sbin/gpt/gpt.2part.show.normal new file mode 100644 index 0000000..667c4d8 --- /dev/null +++ b/contrib/netbsd-tests/sbin/gpt/gpt.2part.show.normal @@ -0,0 +1,8 @@ + start size index contents + 0 1 PMBR + 1 1 Pri GPT header + 2 32 Pri GPT table + 34 1024 1 GPT part - EFI System + 1058 9150 2 GPT part - NetBSD FFSv1/FFSv2 + 10208 32 Sec GPT table + 10240 1 Sec GPT header diff --git a/contrib/netbsd-tests/sbin/gpt/gpt.2part.show.uuid b/contrib/netbsd-tests/sbin/gpt/gpt.2part.show.uuid new file mode 100644 index 0000000..77c41cc --- /dev/null +++ b/contrib/netbsd-tests/sbin/gpt/gpt.2part.show.uuid @@ -0,0 +1,8 @@ + start size index contents + 0 1 PMBR + 1 1 Pri GPT header + 2 32 Pri GPT table + 34 1024 1 GPT part - c12a7328-f81f-11d2-ba4b-00a0c93ec93b + 1058 9150 2 GPT part - 49f48d5a-b10e-11dc-b99b-0019d1879648 + 10208 32 Sec GPT table + 10240 1 Sec GPT header diff --git a/contrib/netbsd-tests/sbin/gpt/gpt.backup b/contrib/netbsd-tests/sbin/gpt/gpt.backup new file mode 100644 index 0000000..8c57949 --- /dev/null +++ b/contrib/netbsd-tests/sbin/gpt/gpt.backup @@ -0,0 +1,1851 @@ + + + + + GPT_HDR + + entries + 128 + guid + 00000000-0000-0000-0000-000000000000 + revision + 0x10000 + + GPT_TBL + + gpt_array + + + attributes + 0x0 + end + 0x421 + guid + 00000000-0000-0000-0000-000000000000 + index + 1 + start + 0x22 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x27df + guid + 00000000-0000-0000-0000-000000000000 + index + 2 + start + 0x422 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 3 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 4 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 5 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 6 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 7 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 8 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 9 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 10 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 11 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 12 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 13 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 14 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 15 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 16 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 17 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 18 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 19 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 20 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 21 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 22 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 23 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 24 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 25 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 26 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 27 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 28 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 29 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 30 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 31 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 32 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 33 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 34 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 35 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 36 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 37 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 38 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 39 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 40 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 41 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 42 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 43 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 44 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 45 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 46 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 47 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 48 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 49 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 50 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 51 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 52 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 53 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 54 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 55 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 56 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 57 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 58 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 59 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 60 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 61 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 62 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 63 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 64 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 65 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 66 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 67 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 68 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 69 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 70 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 71 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 72 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 73 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 74 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 75 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 76 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 77 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 78 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 79 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 80 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 81 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 82 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 83 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 84 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 85 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 86 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 87 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 88 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 89 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 90 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 91 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 92 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 93 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 94 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 95 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 96 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 97 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 98 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 99 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 100 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 101 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 102 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 103 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 104 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 105 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 106 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 107 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 108 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 109 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 110 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 111 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 112 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 113 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 114 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 115 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 116 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 117 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 118 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 119 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 120 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 121 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 122 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 123 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 124 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 125 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 126 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 127 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + attributes + 0x0 + end + 0x0 + guid + 00000000-0000-0000-0000-000000000000 + index + 128 + start + 0x0 + type + 00000000-0000-0000-0000-000000000000 + + + + MBR + + code + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + mbr_array + + + end_cylinder + 0xff + end_head + 0xfe + end_sector + 0xff + flag + 0x0 + index + 0 + lba_size_high + 0x0 + lba_size_low + 0x2800 + lba_start_high + 0x0 + lba_start_low + 0x1 + start_cylinder + 0x0 + start_head + 0x0 + start_sector + 0x2 + type + 0xee + + + + sector_size + 512 + + diff --git a/contrib/netbsd-tests/sbin/gpt/gpt.disklabel b/contrib/netbsd-tests/sbin/gpt/gpt.disklabel new file mode 100644 index 0000000..4a598ee --- /dev/null +++ b/contrib/netbsd-tests/sbin/gpt/gpt.disklabel @@ -0,0 +1,27 @@ +# gpt.disk: +type: ESDI +disk: WDC WD2500SD-01K +label: fictitious +flags: +bytes/sector: 512 +sectors/track: 63 +tracks/cylinder: 16 +sectors/cylinder: 1000 +cylinders: 10 +total sectors: 10000 +rpm: 3600 +interleave: 1 +trackskew: 0 +cylinderskew: 0 +headswitch: 0 # microseconds +track-to-track seek: 0 # microseconds +drivedata: 0 + +6 partitions: +# size offset fstype [fsize bsize cpg/sgs] + a: 500 63 4.2BSD 1024 8192 0 # (Cyl. 0*- 0*) + b: 1000 563 swap # (Cyl. 0*- 1*) + c: 1000 63 unused 0 0 # (Cyl. 0*- 1*) + d: 1063 0 unused 0 0 # (Cyl. 0 - 1*) + e: 1000 1563 4.2BSD 1024 8192 0 # (Cyl. 1*- 2*) + f: 400 2563 MSDOS # (Cyl. 2*- 2*) diff --git a/contrib/netbsd-tests/sbin/gpt/gpt.disklabel.show.normal b/contrib/netbsd-tests/sbin/gpt/gpt.disklabel.show.normal new file mode 100644 index 0000000..5d93707 --- /dev/null +++ b/contrib/netbsd-tests/sbin/gpt/gpt.disklabel.show.normal @@ -0,0 +1,12 @@ + start size index contents + 0 1 PMBR + 1 1 Pri GPT header + 2 32 Pri GPT table + 34 29 Unused + 63 500 1 GPT part - NetBSD FFSv1/FFSv2 + 563 1000 2 GPT part - NetBSD swap + 1563 1000 3 GPT part - NetBSD FFSv1/FFSv2 + 2563 400 4 GPT part - Windows basic data + 2963 7245 Unused + 10208 32 Sec GPT table + 10240 1 Sec GPT header diff --git a/contrib/netbsd-tests/sbin/gpt/gpt.empty.show.normal b/contrib/netbsd-tests/sbin/gpt/gpt.empty.show.normal new file mode 100644 index 0000000..e55c5a9 --- /dev/null +++ b/contrib/netbsd-tests/sbin/gpt/gpt.empty.show.normal @@ -0,0 +1,7 @@ + start size index contents + 0 1 PMBR + 1 1 Pri GPT header + 2 32 Pri GPT table + 34 10174 Unused + 10208 32 Sec GPT table + 10240 1 Sec GPT header diff --git a/contrib/netbsd-tests/sbin/gpt/gpt.removepart.show.normal b/contrib/netbsd-tests/sbin/gpt/gpt.removepart.show.normal new file mode 100644 index 0000000..bf89431 --- /dev/null +++ b/contrib/netbsd-tests/sbin/gpt/gpt.removepart.show.normal @@ -0,0 +1,8 @@ + start size index contents + 0 1 PMBR + 1 1 Pri GPT header + 2 32 Pri GPT table + 34 1024 Unused + 1058 9150 2 GPT part - NetBSD FFSv1/FFSv2 + 10208 32 Sec GPT table + 10240 1 Sec GPT header diff --git a/contrib/netbsd-tests/sbin/gpt/gpt.resizedisk.show.normal b/contrib/netbsd-tests/sbin/gpt/gpt.resizedisk.show.normal new file mode 100644 index 0000000..a328028 --- /dev/null +++ b/contrib/netbsd-tests/sbin/gpt/gpt.resizedisk.show.normal @@ -0,0 +1,9 @@ + start size index contents + 0 1 PMBR + 1 1 Pri GPT header + 2 32 Pri GPT table + 34 1024 1 GPT part - EFI System + 1058 9150 2 GPT part - NetBSD FFSv1/FFSv2 + 10208 10240 Unused + 20448 32 Sec GPT table + 20480 1 Sec GPT header diff --git a/contrib/netbsd-tests/sbin/gpt/gpt.resizepart.show.normal b/contrib/netbsd-tests/sbin/gpt/gpt.resizepart.show.normal new file mode 100644 index 0000000..6228a63 --- /dev/null +++ b/contrib/netbsd-tests/sbin/gpt/gpt.resizepart.show.normal @@ -0,0 +1,8 @@ + start size index contents + 0 1 PMBR + 1 1 Pri GPT header + 2 32 Pri GPT table + 34 1024 1 GPT part - EFI System + 1058 19390 2 GPT part - NetBSD FFSv1/FFSv2 + 20448 32 Sec GPT table + 20480 1 Sec GPT header diff --git a/contrib/netbsd-tests/sbin/gpt/t_gpt.sh b/contrib/netbsd-tests/sbin/gpt/t_gpt.sh new file mode 100755 index 0000000..0381313 --- /dev/null +++ b/contrib/netbsd-tests/sbin/gpt/t_gpt.sh @@ -0,0 +1,318 @@ +# $NetBSD: t_gpt.sh,v 1.15 2016/03/08 08:04:48 joerg Exp $ +# +# Copyright (c) 2015 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Christos Zoulas +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +bootblk=/usr/mdec/gptmbr.bin +size=10240 +newsize=20480 +shdr=34 +disk=gpt.disk +uuid="........-....-....-....-............" +zero="00000000-0000-0000-0000-000000000000" +src=$(atf_get_srcdir) + +silence() { + atf_check -s exit:0 -o empty -e empty "$@" +} + +inline() { + local inline="$1" + shift + atf_check -s exit:0 -e empty -o inline:"$inline" "$@" +} + +match() { + local match="$1" + shift + atf_check -s exit:0 -e empty -o match:"$match" "$@" +} + +matcherr() { + local match="$1" + shift + atf_check -s exit:0 -o empty -e match:"$match" "$@" +} + +file() { + local file="$1" + shift + atf_check -s exit:0 -e empty -o file:"$file" "$@" +} + +save() { + local save="$1" + shift + atf_check -s exit:0 -e empty -o save:"$save" "$@" +} + +zerodd() { + silence dd conv=notrunc msgfmt=quiet if=/dev/zero of="$disk" "$@" +} + +prepare() { + rm -f "$disk" + zerodd seek="$size" count=1 +} + +prepare_2part() { + prepare + silence gpt create "$disk" + match "$(partaddmsg 1 34 1024)" gpt add -t efi -s 1024 "$disk" + match "$(partaddmsg 2 1058 9150)" gpt add "$disk" +} + +# Calling this from tests does not work. BUG! +check_2part() { + file "$src/gpt.2part.show.normal" gpt show "$disk" + file "$src/gpt.2part.show.uuid" gpt show -u "$disk" +} + +partaddmsg() { + echo "^$disk: Partition $1 added: $uuid $2 $3\$" +} + +partresmsg() { + echo "^$disk: Partition $1 resized: $2 $3\$" +} + +partremmsg() { + echo "^$disk: Partition $1 removed\$" +} + +partlblmsg() { + echo "^$disk: Partition $1 label changed\$" +} + +partbootmsg() { + echo "^$disk: Partition $1 marked as bootable\$" +} + +recovermsg() { + echo "^$disk: Recovered $1 GPT [a-z]* from $2\$" +} + +migratemsg() { + echo -n "^gpt: $disk: Partition $1 unknown type MSDOS, " + echo 'using "Microsoft Basic Data"$' +} + +attrmsg() { + echo "^$disk: Partition $1 attributes updated\$" +} + +typemsg() { + echo "^$disk: Partition $1 type changed\$" +} + +atf_test_case create_empty +create_empty_head() { + atf_set "descr" "Create empty disk" +} + +create_empty_body() { + prepare + silence gpt create "$disk" + file "$src/gpt.empty.show.normal" gpt show "$disk" +} + +atf_test_case create_2part +create_2part_head() { + atf_set "descr" "Create 2 partition disk" +} + +create_2part_body() { + prepare_2part + check_2part +} + +atf_test_case change_attr_2part +change_attr_2part_head() { + atf_set "descr" "Change the attribute of 2 partition disk" +} + +change_attr_2part_body() { + prepare_2part + match "$(attrmsg 1)" gpt set -i 1 -a biosboot,bootme "$disk" + save attr gpt show -i 1 "$disk" + match "^Attributes: biosboot, bootme\$" tail -1 attr + match "$(attrmsg 1)" gpt unset -i 1 -a biosboot,bootme "$disk" + save attr gpt show -i 1 "$disk" + match "^Attributes: None\$" tail -1 attr +} + +atf_test_case change_type_2part +change_type_2part_head() { + atf_set "descr" "Change the partition type type of 2 partition disk" +} + +change_type_2part_body() { + prepare_2part + match "$(typemsg 1)" gpt type -i 1 -T apple "$disk" + save type gpt show -i 1 "$disk" + inline "Type: apple (48465300-0000-11aa-aa11-00306543ecac)\n" \ + grep "^Type:" type + match "$(typemsg 1)" gpt type -i 1 -T efi "$disk" + save type gpt show -i 1 "$disk" + inline "Type: efi (c12a7328-f81f-11d2-ba4b-00a0c93ec93b)\n" \ + grep "^Type:" type +} + +atf_test_case backup_2part +backup_2part_head() { + atf_set "descr" "Backup 2 partition disk" +} + +backup_2part_body() { + prepare_2part + save test.backup gpt backup "$disk" + file "$src/gpt.backup" sed -e "s/$uuid/$zero/g" "test.backup" +} + +atf_test_case restore_2part +restore_2part_head() { + atf_set "descr" "Restore 2 partition disk" +} + +restore_2part_body() { + prepare_2part + save test.backup gpt backup "$disk" + prepare + silence gpt restore -i test.backup "$disk" + check_2part +} + +atf_test_case recover_backup +recover_backup_head() { + atf_set "descr" "Recover the backup GPT header and table" +} + +recover_backup_body() { + prepare_2part + zerodd seek="$((size - shdr))" count="$shdr" + match "$(recovermsg secondary primary)" gpt recover "$disk" + check_2part +} + +atf_test_case recover_primary +recover_primary_head() { + atf_set "descr" "Recover the primary GPT header and table" +} + +recover_primary_body() { + prepare_2part + zerodd seek=1 count="$shdr" + match "$(recovermsg primary secondary)" gpt recover "$disk" + check_2part +} + +atf_test_case resize_2part +resize_2part_head() { + atf_set "descr" "Resize a 2 partition disk and partition" +} + +resize_2part_body() { + prepare_2part + zerodd seek="$newsize" count=1 + silence gpt resizedisk "$disk" + file "$src/gpt.resizedisk.show.normal" gpt show "$disk" + match "$(partresmsg 2 1058 19390)" gpt resize -i 2 "$disk" + file "$src/gpt.resizepart.show.normal" gpt show "$disk" +} + +atf_test_case remove_2part +remove_2part_head() { + atf_set "descr" "Remove a partition from a 2 partition disk" +} + +remove_2part_body() { + prepare_2part + match "$(partremmsg 1)" -e empty gpt remove \ + -i 1 "$disk" + file "$src/gpt.removepart.show.normal" \ + gpt show "$disk" +} + +atf_test_case label_2part +label_2part_head() { + atf_set "descr" "Label partitions in a 2 partition disk" +} + +label_2part_body() { + prepare_2part + match "$(partlblmsg 1)" gpt label -i 1 -l potato "$disk" + match "$(partlblmsg 2)" gpt label -i 2 -l tomato "$disk" + file "$src/gpt.2part.show.label" \ + gpt show -l "$disk" +} + +atf_test_case bootable_2part +bootable_2part_head() { + atf_set "descr" "Make partition 2 bootable in a 2 partition disk" + atf_set "require.files" "$bootblk" +} + +bootable_2part_body() { + prepare_2part + match "$(partbootmsg 2)" gpt biosboot -i 2 "$disk" + local bootsz="$(ls -l "$bootblk" | awk '{ print $5 }')" + silence dd msgfmt=quiet if="$disk" of=bootblk bs=1 count="$bootsz" + silence cmp "$bootblk" bootblk + save bootattr gpt show -i 2 "$disk" + match "^Attributes: biosboot\$" tail -1 bootattr +} + +atf_test_case migrate_disklabel +migrate_disklabel_head() { + atf_set "descr" "Migrate an MBR+disklabel disk to GPT" +} + +migrate_disklabel_body() { + prepare + silence fdisk -fi "$disk" + silence fdisk -fu0s "169/63/$((size / 10))" "$disk" + silence disklabel -R "$disk" "$src/gpt.disklabel" + matcherr "$(migratemsg 5)" gpt migrate "$disk" + file "$src/gpt.disklabel.show.normal" gpt show "$disk" +} + +atf_init_test_cases() { + atf_add_test_case create_empty + atf_add_test_case create_2part + atf_add_test_case change_attr_2part + atf_add_test_case change_type_2part + atf_add_test_case backup_2part + atf_add_test_case remove_2part + atf_add_test_case restore_2part + atf_add_test_case recover_backup + atf_add_test_case recover_primary + atf_add_test_case resize_2part + atf_add_test_case label_2part + atf_add_test_case bootable_2part + atf_add_test_case migrate_disklabel +} diff --git a/contrib/netbsd-tests/sbin/ifconfig/t_nonexistent.sh b/contrib/netbsd-tests/sbin/ifconfig/t_nonexistent.sh new file mode 100755 index 0000000..8670323 --- /dev/null +++ b/contrib/netbsd-tests/sbin/ifconfig/t_nonexistent.sh @@ -0,0 +1,45 @@ +# $NetBSD: t_nonexistent.sh,v 1.4 2012/03/18 09:46:50 jruoho Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case nonexistent +nonexistent_head() { + atf_set "descr" "Check ifconfig(8) with " \ + "a nonexistent interface (PR bin/43141)" +} + +nonexistent_body() { + + atf_check -s not-exit:0 -e ignore \ + ifconfig nonexistent0 1.2.3.4/24 +} + +atf_init_test_cases() { + atf_add_test_case nonexistent +} diff --git a/contrib/netbsd-tests/sbin/newfs/quotas_common.sh b/contrib/netbsd-tests/sbin/newfs/quotas_common.sh new file mode 100755 index 0000000..3ea89a2 --- /dev/null +++ b/contrib/netbsd-tests/sbin/newfs/quotas_common.sh @@ -0,0 +1,68 @@ +# $NetBSD: quotas_common.sh,v 1.3 2012/03/18 09:31:50 jruoho Exp $ + +# Copyright (c) 2011 Manuel Bouyer +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +create_with_quotas() +{ + local endian=$1; shift + local vers=$1; shift + local type=$1; shift + local op; + if [ ${type} = "both" ]; then + op="-q user -q group" + else + op="-q ${type}" + fi + atf_check -o ignore -e ignore newfs ${op} \ + -B ${endian} -O ${vers} -s 4000 -F ${IMG} +} + +# from tests/ipf/h_common.sh via tests/sbin/resize_ffs +test_case() +{ + local name="${1}"; shift + local check_function="${1}"; shift + local descr="${1}"; shift + + atf_test_case "${name}" + + eval "${name}_head() { \ + atf_set "descr" "Checks ${descr} quotas inodes" + }" + eval "${name}_body() { \ + ${check_function} " "${@}" "; \ + }" + tests="${tests} ${name}" +} + +atf_init_test_cases() +{ + IMG=fsimage + DIR=target + for i in ${tests}; do + atf_add_test_case $i + done +} diff --git a/contrib/netbsd-tests/sbin/newfs/t_enable_quotas.sh b/contrib/netbsd-tests/sbin/newfs/t_enable_quotas.sh new file mode 100755 index 0000000..62218e9 --- /dev/null +++ b/contrib/netbsd-tests/sbin/newfs/t_enable_quotas.sh @@ -0,0 +1,57 @@ +# $NetBSD: t_enable_quotas.sh,v 1.3 2012/03/18 09:31:50 jruoho Exp $ +# +# Copyright (c) 2011 Manuel Bouyer +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +for e in le be; do + for v in 1 2; do + for q in "user" "group"; do + test_case enabled_${e}_${v}_${q} quota_enabled_single \ + "creation of" ${e} ${v} ${q} + done + test_case enabled_${e}_${v}_"both" quota_enabled_both \ + "creation of" ${e} ${v} "both" + done +done + +quota_enabled_single() +{ + create_with_quotas $* + +# check that the quota inode creation didn't corrupt the filesystem + atf_check -s exit:0 -o "match:already clean" -o "match:2 files" \ + -o "match:Phase 6 - Check Quotas" \ + fsck_ffs -nf -F ${IMG} +} + +quota_enabled_both() +{ + create_with_quotas $* + +# check that the quota inode creation didn't corrupt the filesystem + atf_check -s exit:0 -o "match:already clean" -o "match:3 files" \ + -o "match:Phase 6 - Check Quotas" \ + fsck_ffs -nf -F ${IMG} +} diff --git a/contrib/netbsd-tests/sbin/newfs_msdos/t_create.sh b/contrib/netbsd-tests/sbin/newfs_msdos/t_create.sh new file mode 100755 index 0000000..dc43116 --- /dev/null +++ b/contrib/netbsd-tests/sbin/newfs_msdos/t_create.sh @@ -0,0 +1,45 @@ +# $NetBSD: t_create.sh,v 1.3 2014/01/05 12:59:03 martin Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case validfat32 +validfat32_head() { + atf_set "descr" "Verifies that fat32 created filesystems are valid" +} +validfat32_body() { + + atf_check -s eq:0 -o ignore -e ignore \ + newfs_msdos -b 512 -C 33m -F 32 msdos.img +# fsck_msdos/newfs_msdos have been fixed +# atf_expect_fail "PR bin/46743" + atf_check -s eq:0 -o not-match:FIXED -e empty fsck_msdos -p msdos.img + atf_expect_pass +} + + +atf_init_test_cases() { + atf_add_test_case validfat32 +} diff --git a/contrib/netbsd-tests/sbin/resize_ffs/common.sh b/contrib/netbsd-tests/sbin/resize_ffs/common.sh new file mode 100755 index 0000000..80ebc65 --- /dev/null +++ b/contrib/netbsd-tests/sbin/resize_ffs/common.sh @@ -0,0 +1,163 @@ + +# Common settings and functions for the various resize_ffs tests. +# + +# called from atf_init_test_cases +setupvars() +{ + IMG=fsimage + TDBASE64=$(atf_get_srcdir)/testdata.tar.gz.base64 + GOODMD5=$(atf_get_srcdir)/testdata.md5 + # set BYTESWAP to opposite-endian. + if [ $(sysctl -n hw.byteorder) = "1234" ]; then + BYTESWAP=be + else + BYTESWAP=le + fi +} + +# test_case() taken from the tests/ipf/h_common.sh +# Used to declare the atf goop for a test. +test_case() +{ + local name="${1}"; shift + local check_function="${1}"; shift + + atf_test_case "${name}" cleanup + eval "${name}_head() { \ + atf_set "require.user" "root" ; \ + atf_set "require.progs" "rump_ffs" ; \ + }" + eval "${name}_body() { \ + ${check_function} " "${@}" "; \ + }" + eval "${name}_cleanup() { \ + umount -f mnt ; \ + : reset error ; \ + }" +} + +# Used to declare the atf goop for a test expected to fail. +test_case_xfail() +{ + local name="${1}"; shift + local reason="${1}"; shift + local check_function="${1}"; shift + + atf_test_case "${name}" cleanup + eval "${name}_head() { \ + atf_set "require.user" "root" ; \ + }" + eval "${name}_body() { \ + atf_expect_fail "${reason}" ; \ + ${check_function} " "${@}" "; \ + }" + eval "${name}_cleanup() { \ + umount -f mnt ; \ + : reset error ; \ + }" +} + +# copy_data requires the mount already done; makes one copy of the test data +copy_data () +{ + uudecode -p ${TDBASE64} | (cd mnt; tar xzf - -s/testdata/TD$1/) +} + +copy_multiple () +{ + local i + for i in $(seq $1); do + copy_data $i + done +} + +# remove_data removes one directory worth of test data; the purpose +# is to ensure data exists near the end of the fs under test. +remove_data () +{ + rm -rf mnt/TD$1 +} + +remove_multiple () +{ + local i + for i in $(seq $1); do + remove_data $i + done +} + +# verify that the data in a particular directory is still OK +# generated md5 file doesn't need explicit cleanup thanks to ATF +check_data () +{ + (cd mnt/TD$1 && md5 *) > TD$1.md5 + atf_check diff -u ${GOODMD5} TD$1.md5 +} + +# supply begin and end arguments +check_data_range () +{ + local i + for i in $(seq $1 $2); do + check_data $i + done +} + + +resize_ffs() +{ + echo "in resize_ffs:" ${@} + local bs=$1 + local fragsz=$2 + local osize=$3 + local nsize=$4 + local fslevel=$5 + local numdata=$6 + local swap=$7 + mkdir -p mnt + echo "bs is ${bs} numdata is ${numdata}" + echo "****resizing fs with blocksize ${bs}" + + # we want no more than 16K/inode to allow test files to copy. + local fpi=$((fragsz * 4)) + local i + if [ $fpi -gt 16384 ]; then + i="-i 16384" + fi + if [ x$swap != x ]; then + newfs -B ${BYTESWAP} -O${fslevel} -b ${bs} -f ${fragsz} \ + -s ${osize} ${i} -F ${IMG} + else + newfs -O${fslevel} -b ${bs} -f ${fragsz} -s ${osize} ${i} \ + -F ${IMG} + fi + + # we're specifying relative paths, so rump_ffs warns - ignore. + atf_check -s exit:0 -e ignore rump_ffs ${IMG} mnt + copy_multiple ${numdata} + + if [ ${nsize} -lt ${osize} ]; then + # how much data to remove so fs can be shrunk + local remove=$((numdata-numdata*nsize/osize)) + local dataleft=$((numdata-remove)) + echo remove is $remove dataleft is $dataleft + remove_multiple ${remove} + fi + + umount mnt + # Check that resize needed + atf_check -s exit:0 -o ignore resize_ffs -c -y -s ${nsize} ${IMG} + atf_check -s exit:0 -o ignore resize_ffs -y -s ${nsize} ${IMG} + atf_check -s exit:0 -o ignore fsck_ffs -f -n -F ${IMG} + atf_check -s exit:0 -e ignore rump_ffs ${IMG} mnt + if [ ${nsize} -lt ${osize} ]; then + check_data_range $((remove + 1)) ${numdata} + else + # checking everything because we don't delete on grow + check_data_range 1 ${numdata} + fi + # Check that no resize needed + atf_check -s exit:1 -o ignore resize_ffs -c -y -s ${nsize} ${IMG} + umount mnt +} diff --git a/contrib/netbsd-tests/sbin/resize_ffs/t_check.sh b/contrib/netbsd-tests/sbin/resize_ffs/t_check.sh new file mode 100755 index 0000000..5b92292 --- /dev/null +++ b/contrib/netbsd-tests/sbin/resize_ffs/t_check.sh @@ -0,0 +1,56 @@ +# $NetBSD: t_check.sh,v 1.1 2015/03/29 19:37:02 chopps Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Christian E. Hopps +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case check_grow + +check_grow_head() { + atf_set "descr" "Tests check for room to grow in image" + atf_set "require.user" "root" +} + +check_grow_body() { + echo "***resize_ffs check grow test" + + atf_check -o ignore -e ignore newfs -V1 -s 6144 -F ${IMG} + dd if=/dev/zero count=2048 >> ${IMG} + + # test room to grow, grow then check that we did. + atf_check -s exit:0 -o match:"newsize: 8192 oldsize: 6144" resize_ffs -v -c -y ${IMG} + atf_check -s exit:0 -o ignore resize_ffs -y ${IMG} + atf_check -s exit:0 -o ignore fsck_ffs -f -n -F ${IMG} + atf_check -s exit:1 -o match:"already 8192 blocks" \ + resize_ffs -v -c -y ${IMG} +} + +atf_init_test_cases() +{ + setupvars + atf_add_test_case check_grow +} diff --git a/contrib/netbsd-tests/sbin/resize_ffs/t_grow.sh b/contrib/netbsd-tests/sbin/resize_ffs/t_grow.sh new file mode 100755 index 0000000..08512d1 --- /dev/null +++ b/contrib/netbsd-tests/sbin/resize_ffs/t_grow.sh @@ -0,0 +1,223 @@ +# $NetBSD: t_grow.sh,v 1.9 2015/03/29 19:37:02 chopps Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jeffrey C. Rizzo. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + + +# resize_ffs params as follows: +# resize_ffs blocksize fragsize fssize newfssize level numdata swap +# where 'numdata' is the number of data directories to copy - this is +# determined manually based on the maximum number that will fit in the +# created fs. 'level' is the fs-level (-O 0,1,2) passed to newfs. +# If 'swap' is included, byteswap the fs + +# v0 == newfs -O0 (4.3BSD layout, ffsv1 superblock) +test_case grow_16M_v0_4096 resize_ffs 4096 512 32768 131072 0 28 +test_case grow_16M_v0_8192 resize_ffs 8192 1024 32768 131072 0 28 +test_case grow_16M_v0_16384 resize_ffs 16384 2048 32768 131072 0 29 +test_case grow_16M_v0_32768 resize_ffs 32768 4096 32768 131072 0 28 +test_case grow_16M_v0_65536 resize_ffs 65536 8192 32768 131072 0 26 +# these grow_24M grow a smaller amount; sometimes there's different issues +test_case grow_24M_v0_4096 resize_ffs 4096 512 49152 65536 0 41 +test_case grow_24M_v0_8192 resize_ffs 8192 1024 49152 65536 0 42 +test_case grow_24M_v0_16384 resize_ffs 16384 2048 49152 65536 0 43 +test_case grow_24M_v0_32768 resize_ffs 32768 4096 49152 65536 0 42 +test_case grow_24M_v0_65536 resize_ffs 65536 8192 49152 65536 0 38 +test_case grow_32M_v0_4096 resize_ffs 4096 512 65536 131072 0 55 +test_case grow_32M_v0_8192 resize_ffs 8192 1024 65536 131072 0 56 +test_case grow_32M_v0_16384 resize_ffs 16384 2048 65536 131072 0 58 +test_case grow_32M_v0_32768 resize_ffs 32768 4096 65536 131072 0 56 +test_case grow_32M_v0_65536 resize_ffs 65536 8192 65536 131072 0 51 +test_case grow_48M_v0_4096 resize_ffs 4096 512 98304 131072 0 82 +test_case grow_48M_v0_8192 resize_ffs 8192 1024 98304 131072 0 84 +test_case grow_48M_v0_16384 resize_ffs 16384 2048 98304 131072 0 87 +test_case grow_48M_v0_32768 resize_ffs 32768 4096 98304 131072 0 83 +test_case grow_48M_v0_65536 resize_ffs 65536 8192 98304 131072 0 76 +test_case grow_64M_v0_4096 resize_ffs 4096 512 131072 262144 0 109 +test_case grow_64M_v0_8192 resize_ffs 8192 1024 131072 262144 0 111 +test_case grow_64M_v0_16384 resize_ffs 16384 2048 131072 262144 0 115 +test_case grow_64M_v0_32768 resize_ffs 32768 4096 131072 262144 0 111 +test_case grow_64M_v0_65536 resize_ffs 65536 8192 131072 262144 0 101 + +# v1 == newfs -O1 (FFSv1, v2 superblock layout) +test_case grow_16M_v1_4096 resize_ffs 4096 512 32768 131072 1 28 +test_case grow_16M_v1_8192 resize_ffs 8192 1024 32768 131072 1 28 +test_case grow_16M_v1_16384 resize_ffs 16384 2048 32768 131072 1 29 +test_case grow_16M_v1_32768 resize_ffs 32768 4096 32768 131072 1 28 +test_case grow_16M_v1_65536 resize_ffs 65536 8192 32768 131072 1 26 +# these grow_24M grow a smaller amount; sometimes there's different issues +test_case grow_24M_v1_4096 resize_ffs 4096 512 49152 65536 1 41 +test_case grow_24M_v1_8192 resize_ffs 8192 1024 49152 65536 1 42 +test_case grow_24M_v1_16384 resize_ffs 16384 2048 49152 65536 1 43 +test_case grow_24M_v1_32768 resize_ffs 32768 4096 49152 65536 1 42 +test_case grow_24M_v1_65536 resize_ffs 65536 8192 49152 65536 1 38 +test_case grow_32M_v1_4096 resize_ffs 4096 512 65536 131072 1 55 +test_case grow_32M_v1_8192 resize_ffs 8192 1024 65536 131072 1 56 +test_case grow_32M_v1_16384 resize_ffs 16384 2048 65536 131072 1 58 +test_case grow_32M_v1_32768 resize_ffs 32768 4096 65536 131072 1 56 +test_case grow_32M_v1_65536 resize_ffs 65536 8192 65536 131072 1 51 +test_case grow_48M_v1_4096 resize_ffs 4096 512 98304 131072 1 82 +test_case grow_48M_v1_8192 resize_ffs 8192 1024 98304 131072 1 84 +test_case grow_48M_v1_16384 resize_ffs 16384 2048 98304 131072 1 87 +test_case grow_48M_v1_32768 resize_ffs 32768 4096 98304 131072 1 83 +test_case grow_48M_v1_65536 resize_ffs 65536 8192 98304 131072 1 76 +test_case grow_64M_v1_4096 resize_ffs 4096 512 131072 262144 1 109 +test_case grow_64M_v1_8192 resize_ffs 8192 1024 131072 262144 1 111 +test_case grow_64M_v1_16384 resize_ffs 16384 2048 131072 262144 1 115 +test_case grow_64M_v1_32768 resize_ffs 32768 4096 131072 262144 1 111 +test_case grow_64M_v1_65536 resize_ffs 65536 8192 131072 262144 1 101 +test_case grow_16M_v2_4096 resize_ffs 4096 512 32768 131072 2 26 +test_case grow_16M_v2_8192 resize_ffs 8192 1024 32768 131072 2 28 +test_case grow_16M_v2_16384 resize_ffs 16384 2048 32768 131072 2 29 +test_case grow_16M_v2_32768 resize_ffs 32768 4096 32768 131072 2 28 +test_case grow_16M_v2_65536 resize_ffs 65536 8192 32768 131072 2 25 +test_case grow_24M_v2_4096 resize_ffs 4096 512 49152 65536 2 40 +test_case grow_24M_v2_8192 resize_ffs 8192 1024 49152 65536 2 42 +test_case grow_24M_v2_16384 resize_ffs 16384 2048 49152 65536 2 43 +test_case grow_24M_v2_32768 resize_ffs 32768 4096 49152 65536 2 42 +test_case grow_24M_v2_65536 resize_ffs 65536 8192 49152 65536 2 38 +test_case grow_32M_v2_4096 resize_ffs 4096 512 65536 131072 2 53 +test_case grow_32M_v2_8192 resize_ffs 8192 1024 65536 131072 2 56 +test_case grow_32M_v2_16384 resize_ffs 16384 2048 65536 131072 2 58 +test_case grow_32M_v2_32768 resize_ffs 32768 4096 65536 131072 2 56 +test_case grow_32M_v2_65536 resize_ffs 65536 8192 65536 131072 2 51 +test_case grow_48M_v2_4096 resize_ffs 4096 512 98304 131072 2 80 +test_case grow_48M_v2_8192 resize_ffs 8192 1024 98304 131072 2 84 +test_case grow_48M_v2_16384 resize_ffs 16384 2048 98304 131072 2 87 +test_case grow_48M_v2_32768 resize_ffs 32768 4096 98304 131072 2 83 +test_case grow_48M_v2_65536 resize_ffs 65536 8192 98304 131072 2 76 +test_case grow_64M_v2_4096 resize_ffs 4096 512 131072 262144 2 107 +test_case grow_64M_v2_8192 resize_ffs 8192 1024 131072 262144 2 111 +test_case grow_64M_v2_16384 resize_ffs 16384 2048 131072 262144 2 115 +test_case grow_64M_v2_32768 resize_ffs 32768 4096 131072 262144 2 111 +test_case grow_64M_v2_65536 resize_ffs 65536 8192 131072 262144 2 101 + +atf_test_case grow_ffsv1_partial_cg +grow_ffsv1_partial_cg_head() +{ + atf_set "descr" "Checks successful ffsv1 growth by less" \ + "than a cylinder group" +} +grow_ffsv1_partial_cg_body() +{ + echo "***resize_ffs grow test" + + # resize_ffs only supports ffsv1 at the moment + atf_check -o ignore -e ignore newfs -V1 -s 4000 -F ${IMG} + + # size to grow to is chosen to cause partial cg + atf_check -s exit:0 -o ignore resize_ffs -c -y -s 5760 ${IMG} + atf_check -s exit:0 -o ignore resize_ffs -y -s 5760 ${IMG} + atf_check -s exit:0 -o ignore fsck_ffs -f -n -F ${IMG} + atf_check -s exit:1 -o ignore resize_ffs -c -y -s 5760 ${IMG} +} + +atf_init_test_cases() +{ + setupvars + atf_add_test_case grow_16M_v0_8192 + atf_add_test_case grow_16M_v1_16384 + atf_add_test_case grow_16M_v2_32768 +if [ "${RESIZE_FFS_ALL_TESTS-X}" != "X" ]; then + atf_add_test_case grow_16M_v0_4096 + atf_add_test_case grow_16M_v0_16384 + atf_add_test_case grow_16M_v0_32768 + atf_add_test_case grow_16M_v0_65536 + atf_add_test_case grow_16M_v1_4096 + atf_add_test_case grow_16M_v1_8192 + atf_add_test_case grow_16M_v1_32768 + atf_add_test_case grow_16M_v1_65536 + atf_add_test_case grow_16M_v2_4096 + atf_add_test_case grow_16M_v2_8192 + atf_add_test_case grow_16M_v2_16384 + atf_add_test_case grow_16M_v2_65536 + atf_add_test_case grow_24M_v0_4096 + atf_add_test_case grow_24M_v0_8192 + atf_add_test_case grow_24M_v0_16384 + atf_add_test_case grow_24M_v0_32768 + atf_add_test_case grow_24M_v0_65536 + atf_add_test_case grow_32M_v0_4096 + atf_add_test_case grow_32M_v0_8192 + atf_add_test_case grow_32M_v0_16384 + atf_add_test_case grow_32M_v0_32768 + atf_add_test_case grow_32M_v0_65536 + atf_add_test_case grow_48M_v0_4096 + atf_add_test_case grow_48M_v0_8192 + atf_add_test_case grow_48M_v0_16384 + atf_add_test_case grow_48M_v0_32768 + atf_add_test_case grow_48M_v0_65536 + atf_add_test_case grow_64M_v0_4096 + atf_add_test_case grow_64M_v0_8192 + atf_add_test_case grow_64M_v0_16384 + atf_add_test_case grow_64M_v0_32768 + atf_add_test_case grow_64M_v0_65536 + + atf_add_test_case grow_24M_v1_4096 + atf_add_test_case grow_24M_v1_8192 + atf_add_test_case grow_24M_v1_16384 + atf_add_test_case grow_24M_v1_32768 + atf_add_test_case grow_24M_v1_65536 + atf_add_test_case grow_32M_v1_4096 + atf_add_test_case grow_32M_v1_8192 + atf_add_test_case grow_32M_v1_16384 + atf_add_test_case grow_32M_v1_32768 + atf_add_test_case grow_32M_v1_65536 + atf_add_test_case grow_48M_v1_4096 + atf_add_test_case grow_48M_v1_8192 + atf_add_test_case grow_48M_v1_16384 + atf_add_test_case grow_48M_v1_32768 + atf_add_test_case grow_48M_v1_65536 + atf_add_test_case grow_64M_v1_4096 + atf_add_test_case grow_64M_v1_8192 + atf_add_test_case grow_64M_v1_16384 + atf_add_test_case grow_64M_v1_32768 + atf_add_test_case grow_64M_v1_65536 + + atf_add_test_case grow_24M_v2_4096 + atf_add_test_case grow_24M_v2_8192 + atf_add_test_case grow_24M_v2_16384 + atf_add_test_case grow_24M_v2_32768 + atf_add_test_case grow_24M_v2_65536 + atf_add_test_case grow_32M_v2_4096 + atf_add_test_case grow_32M_v2_8192 + atf_add_test_case grow_32M_v2_16384 + atf_add_test_case grow_32M_v2_32768 + atf_add_test_case grow_32M_v2_65536 + atf_add_test_case grow_48M_v2_4096 + atf_add_test_case grow_48M_v2_8192 + atf_add_test_case grow_48M_v2_16384 + atf_add_test_case grow_48M_v2_32768 + atf_add_test_case grow_48M_v2_65536 + atf_add_test_case grow_64M_v2_4096 + atf_add_test_case grow_64M_v2_8192 + atf_add_test_case grow_64M_v2_16384 + atf_add_test_case grow_64M_v2_32768 + atf_add_test_case grow_64M_v2_65536 +fi + atf_add_test_case grow_ffsv1_partial_cg +} diff --git a/contrib/netbsd-tests/sbin/resize_ffs/t_grow_swapped.sh b/contrib/netbsd-tests/sbin/resize_ffs/t_grow_swapped.sh new file mode 100755 index 0000000..3dba236 --- /dev/null +++ b/contrib/netbsd-tests/sbin/resize_ffs/t_grow_swapped.sh @@ -0,0 +1,222 @@ +# $NetBSD: t_grow_swapped.sh,v 1.3 2015/03/29 19:37:02 chopps Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jeffrey C. Rizzo. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + + +# resize_ffs params as follows: +# resize_ffs blocksize fragsize fssize newfssize level numdata swap +# where 'numdata' is the number of data directories to copy - this is +# determined manually based on the maximum number that will fit in the +# created fs. 'level' is the fs-level (-O 0,1,2) passed to newfs. +# If 'swap' is included, byteswap the fs + +# v0 == newfs -O0 (4.3BSD layout, ffsv1 superblock) +test_case grow_16M_v0_4096 resize_ffs 4096 512 32768 131072 0 28 swap +test_case grow_16M_v0_8192 resize_ffs 8192 1024 32768 131072 0 28 swap +test_case grow_16M_v0_16384 resize_ffs 16384 2048 32768 131072 0 29 swap +test_case grow_16M_v0_32768 resize_ffs 32768 4096 32768 131072 0 28 swap +test_case grow_16M_v0_65536 resize_ffs 65536 8192 32768 131072 0 26 swap +# these grow_24M grow a smaller amount; sometimes there's different issues +test_case grow_24M_v0_4096 resize_ffs 4096 512 49152 65536 0 41 swap +test_case grow_24M_v0_8192 resize_ffs 8192 1024 49152 65536 0 42 swap +test_case grow_24M_v0_16384 resize_ffs 16384 2048 49152 65536 0 43 swap +test_case grow_24M_v0_32768 resize_ffs 32768 4096 49152 65536 0 42 swap +test_case grow_24M_v0_65536 resize_ffs 65536 8192 49152 65536 0 38 swap +test_case grow_32M_v0_4096 resize_ffs 4096 512 65536 131072 0 55 swap +test_case grow_32M_v0_8192 resize_ffs 8192 1024 65536 131072 0 56 swap +test_case grow_32M_v0_16384 resize_ffs 16384 2048 65536 131072 0 58 swap +test_case grow_32M_v0_32768 resize_ffs 32768 4096 65536 131072 0 56 swap +test_case grow_32M_v0_65536 resize_ffs 65536 8192 65536 131072 0 51 swap +test_case grow_48M_v0_4096 resize_ffs 4096 512 98304 131072 0 82 swap +test_case grow_48M_v0_8192 resize_ffs 8192 1024 98304 131072 0 84 swap +test_case grow_48M_v0_16384 resize_ffs 16384 2048 98304 131072 0 87 swap +test_case grow_48M_v0_32768 resize_ffs 32768 4096 98304 131072 0 83 swap +test_case grow_48M_v0_65536 resize_ffs 65536 8192 98304 131072 0 76 swap +test_case grow_64M_v0_4096 resize_ffs 4096 512 131072 262144 0 109 swap +test_case grow_64M_v0_8192 resize_ffs 8192 1024 131072 262144 0 111 swap +test_case grow_64M_v0_16384 resize_ffs 16384 2048 131072 262144 0 115 swap +test_case grow_64M_v0_32768 resize_ffs 32768 4096 131072 262144 0 111 swap +test_case grow_64M_v0_65536 resize_ffs 65536 8192 131072 262144 0 101 swap + +# v1 == newfs -O1 (FFSv1, v2 superblock layout) +test_case grow_16M_v1_4096 resize_ffs 4096 512 32768 131072 1 28 swap +test_case grow_16M_v1_8192 resize_ffs 8192 1024 32768 131072 1 28 swap +test_case grow_16M_v1_16384 resize_ffs 16384 2048 32768 131072 1 29 swap +test_case grow_16M_v1_32768 resize_ffs 32768 4096 32768 131072 1 28 swap +test_case grow_16M_v1_65536 resize_ffs 65536 8192 32768 131072 1 26 swap +# these grow_24M grow a smaller amount; sometimes there's different issues +test_case grow_24M_v1_4096 resize_ffs 4096 512 49152 65536 1 41 swap +test_case grow_24M_v1_8192 resize_ffs 8192 1024 49152 65536 1 42 swap +test_case grow_24M_v1_16384 resize_ffs 16384 2048 49152 65536 1 43 swap +test_case grow_24M_v1_32768 resize_ffs 32768 4096 49152 65536 1 42 swap +test_case grow_24M_v1_65536 resize_ffs 65536 8192 49152 65536 1 38 swap +test_case grow_32M_v1_4096 resize_ffs 4096 512 65536 131072 1 55 swap +test_case grow_32M_v1_8192 resize_ffs 8192 1024 65536 131072 1 56 swap +test_case grow_32M_v1_16384 resize_ffs 16384 2048 65536 131072 1 58 swap +test_case grow_32M_v1_32768 resize_ffs 32768 4096 65536 131072 1 56 swap +test_case grow_32M_v1_65536 resize_ffs 65536 8192 65536 131072 1 51 swap +test_case grow_48M_v1_4096 resize_ffs 4096 512 98304 131072 1 82 swap +test_case grow_48M_v1_8192 resize_ffs 8192 1024 98304 131072 1 84 swap +test_case grow_48M_v1_16384 resize_ffs 16384 2048 98304 131072 1 87 swap +test_case grow_48M_v1_32768 resize_ffs 32768 4096 98304 131072 1 83 swap +test_case grow_48M_v1_65536 resize_ffs 65536 8192 98304 131072 1 76 swap +test_case grow_64M_v1_4096 resize_ffs 4096 512 131072 262144 1 109 swap +test_case grow_64M_v1_8192 resize_ffs 8192 1024 131072 262144 1 111 swap +test_case grow_64M_v1_16384 resize_ffs 16384 2048 131072 262144 1 115 swap +test_case grow_64M_v1_32768 resize_ffs 32768 4096 131072 262144 1 111 swap +test_case grow_64M_v1_65536 resize_ffs 65536 8192 131072 262144 1 101 swap +test_case grow_16M_v2_4096 resize_ffs 4096 512 32768 131072 2 26 swap +test_case grow_16M_v2_8192 resize_ffs 8192 1024 32768 131072 2 28 swap +test_case grow_16M_v2_16384 resize_ffs 16384 2048 32768 131072 2 29 swap +test_case grow_16M_v2_32768 resize_ffs 32768 4096 32768 131072 2 28 swap +test_case grow_16M_v2_65536 resize_ffs 65536 8192 32768 131072 2 25 swap +test_case grow_24M_v2_4096 resize_ffs 4096 512 49152 65536 2 40 swap +test_case grow_24M_v2_8192 resize_ffs 8192 1024 49152 65536 2 42 swap +test_case grow_24M_v2_16384 resize_ffs 16384 2048 49152 65536 2 43 swap +test_case grow_24M_v2_32768 resize_ffs 32768 4096 49152 65536 2 42 swap +test_case grow_24M_v2_65536 resize_ffs 65536 8192 49152 65536 2 38 swap +test_case grow_32M_v2_4096 resize_ffs 4096 512 65536 131072 2 53 swap +test_case grow_32M_v2_8192 resize_ffs 8192 1024 65536 131072 2 56 swap +test_case grow_32M_v2_16384 resize_ffs 16384 2048 65536 131072 2 58 swap +test_case grow_32M_v2_32768 resize_ffs 32768 4096 65536 131072 2 56 swap +test_case grow_32M_v2_65536 resize_ffs 65536 8192 65536 131072 2 51 swap +test_case grow_48M_v2_4096 resize_ffs 4096 512 98304 131072 2 80 swap +test_case grow_48M_v2_8192 resize_ffs 8192 1024 98304 131072 2 84 swap +test_case grow_48M_v2_16384 resize_ffs 16384 2048 98304 131072 2 87 swap +test_case grow_48M_v2_32768 resize_ffs 32768 4096 98304 131072 2 83 swap +test_case grow_48M_v2_65536 resize_ffs 65536 8192 98304 131072 2 76 swap +test_case grow_64M_v2_4096 resize_ffs 4096 512 131072 262144 2 107 swap +test_case grow_64M_v2_8192 resize_ffs 8192 1024 131072 262144 2 111 swap +test_case grow_64M_v2_16384 resize_ffs 16384 2048 131072 262144 2 115 swap +test_case grow_64M_v2_32768 resize_ffs 32768 4096 131072 262144 2 111 swap +test_case grow_64M_v2_65536 resize_ffs 65536 8192 131072 262144 2 101 swap + +atf_test_case grow_ffsv1_partial_cg +grow_ffsv1_partial_cg_head() +{ + atf_set "descr" "Checks successful ffsv1 growth by less" \ + "than a cylinder group" +} +grow_ffsv1_partial_cg_body() +{ + echo "***resize_ffs grow test" + + atf_check -o ignore -e ignore newfs -B be -V1 -s 4000 -F ${IMG} + + # size to grow to is chosen to cause partial cg + atf_check -s exit:0 -o ignore resize_ffs -c -y -s 5760 ${IMG} + atf_check -s exit:0 -o ignore resize_ffs -y -s 5760 ${IMG} + atf_check -s exit:0 -o ignore fsck_ffs -f -n -F ${IMG} + atf_check -s exit:1 -o ignore resize_ffs -c -y -s 5760 ${IMG} +} + +atf_init_test_cases() +{ + setupvars + atf_add_test_case grow_16M_v0_65536 + atf_add_test_case grow_16M_v1_4096 + atf_add_test_case grow_16M_v2_8192 +if [ "${RESIZE_FFS_ALL_TESTS-X}" != "X" ]; then + atf_add_test_case grow_16M_v0_4096 + atf_add_test_case grow_16M_v0_8192 + atf_add_test_case grow_16M_v0_16384 + atf_add_test_case grow_16M_v0_32768 + atf_add_test_case grow_16M_v1_8192 + atf_add_test_case grow_16M_v1_16384 + atf_add_test_case grow_16M_v1_32768 + atf_add_test_case grow_16M_v1_65536 + atf_add_test_case grow_16M_v2_4096 + atf_add_test_case grow_16M_v2_16384 + atf_add_test_case grow_16M_v2_32768 + atf_add_test_case grow_16M_v2_65536 + atf_add_test_case grow_24M_v0_4096 + atf_add_test_case grow_24M_v0_8192 + atf_add_test_case grow_24M_v0_16384 + atf_add_test_case grow_24M_v0_32768 + atf_add_test_case grow_24M_v0_65536 + atf_add_test_case grow_32M_v0_4096 + atf_add_test_case grow_32M_v0_8192 + atf_add_test_case grow_32M_v0_16384 + atf_add_test_case grow_32M_v0_32768 + atf_add_test_case grow_32M_v0_65536 + atf_add_test_case grow_48M_v0_4096 + atf_add_test_case grow_48M_v0_8192 + atf_add_test_case grow_48M_v0_16384 + atf_add_test_case grow_48M_v0_32768 + atf_add_test_case grow_48M_v0_65536 + atf_add_test_case grow_64M_v0_4096 + atf_add_test_case grow_64M_v0_8192 + atf_add_test_case grow_64M_v0_16384 + atf_add_test_case grow_64M_v0_32768 + atf_add_test_case grow_64M_v0_65536 + + atf_add_test_case grow_24M_v1_4096 + atf_add_test_case grow_24M_v1_8192 + atf_add_test_case grow_24M_v1_16384 + atf_add_test_case grow_24M_v1_32768 + atf_add_test_case grow_24M_v1_65536 + atf_add_test_case grow_32M_v1_4096 + atf_add_test_case grow_32M_v1_8192 + atf_add_test_case grow_32M_v1_16384 + atf_add_test_case grow_32M_v1_32768 + atf_add_test_case grow_32M_v1_65536 + atf_add_test_case grow_48M_v1_4096 + atf_add_test_case grow_48M_v1_8192 + atf_add_test_case grow_48M_v1_16384 + atf_add_test_case grow_48M_v1_32768 + atf_add_test_case grow_48M_v1_65536 + atf_add_test_case grow_64M_v1_4096 + atf_add_test_case grow_64M_v1_8192 + atf_add_test_case grow_64M_v1_16384 + atf_add_test_case grow_64M_v1_32768 + atf_add_test_case grow_64M_v1_65536 + + atf_add_test_case grow_24M_v2_4096 + atf_add_test_case grow_24M_v2_8192 + atf_add_test_case grow_24M_v2_16384 + atf_add_test_case grow_24M_v2_32768 + atf_add_test_case grow_24M_v2_65536 + atf_add_test_case grow_32M_v2_4096 + atf_add_test_case grow_32M_v2_8192 + atf_add_test_case grow_32M_v2_16384 + atf_add_test_case grow_32M_v2_32768 + atf_add_test_case grow_32M_v2_65536 + atf_add_test_case grow_48M_v2_4096 + atf_add_test_case grow_48M_v2_8192 + atf_add_test_case grow_48M_v2_16384 + atf_add_test_case grow_48M_v2_32768 + atf_add_test_case grow_48M_v2_65536 + atf_add_test_case grow_64M_v2_4096 + atf_add_test_case grow_64M_v2_8192 + atf_add_test_case grow_64M_v2_16384 + atf_add_test_case grow_64M_v2_32768 + atf_add_test_case grow_64M_v2_65536 +fi + atf_add_test_case grow_ffsv1_partial_cg +} diff --git a/contrib/netbsd-tests/sbin/resize_ffs/t_shrink.sh b/contrib/netbsd-tests/sbin/resize_ffs/t_shrink.sh new file mode 100755 index 0000000..8a9cf19 --- /dev/null +++ b/contrib/netbsd-tests/sbin/resize_ffs/t_shrink.sh @@ -0,0 +1,187 @@ +# $NetBSD: t_shrink.sh,v 1.8 2015/03/29 19:37:02 chopps Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jeffrey C. Rizzo. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + + +# resize_ffs params as follows: +# resize_ffs blocksize fragsize fssize newfssize level numdata swap +# where 'numdata' is the number of data directories to copy - this is +# determined manually based on the maximum number that will fit in the +# created fs. 'level' is the fs-level (-O 0,1,2) passed to newfs. +# If 'swap' is included, byteswap the fs +test_case shrink_24M_16M_v0_4096 resize_ffs 4096 512 49152 32768 0 41 +test_case shrink_24M_16M_v0_8192 resize_ffs 8192 1024 49152 32768 0 42 +test_case shrink_24M_16M_v0_16384 resize_ffs 16384 2048 49152 32768 0 43 +test_case shrink_24M_16M_v0_32768 resize_ffs 32768 4096 49152 32768 0 42 +test_case shrink_24M_16M_v0_65536 resize_ffs 65536 8192 49152 32768 0 38 +test_case shrink_32M_24M_v0_4096 resize_ffs 4096 512 65536 49152 0 55 +test_case shrink_32M_24M_v0_8192 resize_ffs 8192 1024 65536 49152 0 56 +test_case shrink_32M_24M_v0_16384 resize_ffs 16384 2048 65536 49152 0 58 +test_case shrink_32M_24M_v0_32768 resize_ffs 32768 4096 65536 49152 0 56 +test_case_xfail shrink_32M_24M_v0_65536 "PR bin/44204" resize_ffs 65536 8192 65536 49152 0 51 +test_case shrink_48M_16M_v0_4096 resize_ffs 4096 512 98304 32768 0 82 +test_case shrink_48M_16M_v0_8192 resize_ffs 8192 1024 98304 32768 0 84 +test_case shrink_48M_16M_v0_16384 resize_ffs 16384 2048 98304 32768 0 87 +test_case shrink_48M_16M_v0_32768 resize_ffs 32768 4096 98304 32768 0 83 +test_case shrink_48M_16M_v0_65536 resize_ffs 65536 8192 98304 32768 0 76 +test_case shrink_64M_48M_v0_4096 resize_ffs 4096 512 131072 98304 0 109 +test_case shrink_64M_48M_v0_8192 resize_ffs 8192 1024 131072 98304 0 111 +test_case shrink_64M_48M_v0_16384 resize_ffs 16384 2048 131072 98304 0 115 +test_case shrink_64M_48M_v0_32768 resize_ffs 32768 4096 131072 98304 0 111 +test_case shrink_64M_48M_v0_65536 resize_ffs 65536 8192 131072 98304 0 101 + +test_case shrink_24M_16M_v1_4096 resize_ffs 4096 512 49152 32768 1 41 +test_case shrink_24M_16M_v1_8192 resize_ffs 8192 1024 49152 32768 1 42 +test_case shrink_24M_16M_v1_16384 resize_ffs 16384 2048 49152 32768 1 43 +test_case shrink_24M_16M_v1_32768 resize_ffs 32768 4096 49152 32768 1 42 +test_case shrink_24M_16M_v1_65536 resize_ffs 65536 8192 49152 32768 1 38 +test_case shrink_32M_24M_v1_4096 resize_ffs 4096 512 65536 49152 1 55 +test_case shrink_32M_24M_v1_8192 resize_ffs 8192 1024 65536 49152 1 56 +test_case shrink_32M_24M_v1_16384 resize_ffs 16384 2048 65536 49152 1 58 +test_case shrink_32M_24M_v1_32768 resize_ffs 32768 4096 65536 49152 1 56 +test_case_xfail shrink_32M_24M_v1_65536 "PR bin/44204" resize_ffs 65536 8192 65536 49152 1 51 +test_case shrink_48M_16M_v1_4096 resize_ffs 4096 512 98304 32768 1 82 +test_case shrink_48M_16M_v1_8192 resize_ffs 8192 1024 98304 32768 1 84 +test_case shrink_48M_16M_v1_16384 resize_ffs 16384 2048 98304 32768 1 87 +test_case shrink_48M_16M_v1_32768 resize_ffs 32768 4096 98304 32768 1 83 +test_case shrink_48M_16M_v1_65536 resize_ffs 65536 8192 98304 32768 1 76 +test_case shrink_64M_48M_v1_4096 resize_ffs 4096 512 131072 98304 1 109 +test_case shrink_64M_48M_v1_8192 resize_ffs 8192 1024 131072 98304 1 111 +test_case shrink_64M_48M_v1_16384 resize_ffs 16384 2048 131072 98304 1 115 +test_case shrink_64M_48M_v1_32768 resize_ffs 32768 4096 131072 98304 1 111 +test_case shrink_64M_48M_v1_65536 resize_ffs 65536 8192 131072 98304 1 101 + +test_case_xfail shrink_24M_16M_v2_4096 "PR bin/44205" resize_ffs 4096 512 49152 32768 2 41 +test_case_xfail shrink_24M_16M_v2_8192 "PR bin/44205" resize_ffs 8192 1024 49152 32768 2 42 +test_case_xfail shrink_24M_16M_v2_16384 "PR bin/44205" resize_ffs 16384 2048 49152 32768 2 43 +test_case_xfail shrink_24M_16M_v2_32768 "PR bin/44205" resize_ffs 32768 4096 49152 32768 2 42 +test_case_xfail shrink_24M_16M_v2_65536 "PR bin/44205" resize_ffs 65536 8192 49152 32768 2 38 +test_case_xfail shrink_32M_24M_v2_4096 "PR bin/44205" resize_ffs 4096 512 65536 49152 2 55 +test_case_xfail shrink_32M_24M_v2_8192 "PR bin/44205" resize_ffs 8192 1024 65536 49152 2 56 +test_case_xfail shrink_32M_24M_v2_16384 "PR bin/44205" resize_ffs 16384 2048 65536 49152 2 58 +test_case_xfail shrink_32M_24M_v2_32768 "PR bin/44205" resize_ffs 32768 4096 65536 49152 2 56 +test_case_xfail shrink_32M_24M_v2_65536 "PR bin/44204" resize_ffs 65536 8192 65536 49152 2 51 +test_case_xfail shrink_48M_16M_v2_4096 "PR bin/44205" resize_ffs 4096 512 98304 32768 2 82 +test_case_xfail shrink_48M_16M_v2_8192 "PR bin/44205" resize_ffs 8192 1024 98304 32768 2 84 +test_case_xfail shrink_48M_16M_v2_16384 "PR bin/44205" resize_ffs 16384 2048 98304 32768 2 87 +test_case_xfail shrink_48M_16M_v2_32768 "PR bin/44205" resize_ffs 32768 4096 98304 32768 2 83 +test_case_xfail shrink_48M_16M_v2_65536 "PR bin/44205" resize_ffs 65536 8192 98304 32768 2 76 +test_case_xfail shrink_64M_48M_v2_4096 "PR bin/44205" resize_ffs 4096 512 131072 98304 2 109 +test_case_xfail shrink_64M_48M_v2_8192 "PR bin/44205" resize_ffs 8192 1024 131072 98304 2 111 +test_case_xfail shrink_64M_48M_v2_16384 "PR bin/44205" resize_ffs 16384 2048 131072 98304 2 115 +test_case_xfail shrink_64M_48M_v2_32768 "PR bin/44205" resize_ffs 32768 4096 131072 98304 2 111 +test_case_xfail shrink_64M_48M_v2_65536 "PR bin/44205" resize_ffs 65536 8192 131072 98304 2 101 + + +atf_test_case shrink_ffsv1_partial_cg +shrink_ffsv1_partial_cg_head() +{ + atf_set "descr" "Checks successful shrinkage of ffsv1 by" \ + "less than a cylinder group" +} +shrink_ffsv1_partial_cg_body() +{ + echo "*** resize_ffs shrinkage partial cg test" + + atf_check -o ignore -e ignore newfs -V1 -F -s 5760 ${IMG} + + # shrink so there's a partial cg at the end + atf_check -s exit:0 resize_ffs -c -s 4000 -y ${IMG} + atf_check -s exit:0 resize_ffs -s 4000 -y ${IMG} + atf_check -s exit:0 -o ignore fsck_ffs -f -n -F ${IMG} + atf_check -s exit:1 resize_ffs -c -s 4000 -y ${IMG} +} + +atf_init_test_cases() +{ + setupvars + atf_add_test_case shrink_24M_16M_v0_32768 + atf_add_test_case shrink_24M_16M_v1_65536 + atf_add_test_case shrink_24M_16M_v2_4096 +if [ "${RESIZE_FFS_ALL_TESTS-X}" != "X" ]; then + atf_add_test_case shrink_24M_16M_v0_4096 + atf_add_test_case shrink_24M_16M_v0_8192 + atf_add_test_case shrink_24M_16M_v0_16384 + atf_add_test_case shrink_24M_16M_v0_65536 + atf_add_test_case shrink_24M_16M_v1_4096 + atf_add_test_case shrink_24M_16M_v1_8192 + atf_add_test_case shrink_24M_16M_v1_16384 + atf_add_test_case shrink_24M_16M_v1_32768 + atf_add_test_case shrink_24M_16M_v2_8192 + atf_add_test_case shrink_24M_16M_v2_16384 + atf_add_test_case shrink_24M_16M_v2_32768 + atf_add_test_case shrink_24M_16M_v2_65536 + atf_add_test_case shrink_32M_24M_v0_4096 + atf_add_test_case shrink_32M_24M_v0_8192 + atf_add_test_case shrink_32M_24M_v0_16384 + atf_add_test_case shrink_32M_24M_v0_32768 + atf_add_test_case shrink_32M_24M_v0_65536 + atf_add_test_case shrink_48M_16M_v0_4096 + atf_add_test_case shrink_48M_16M_v0_8192 + atf_add_test_case shrink_48M_16M_v0_16384 + atf_add_test_case shrink_48M_16M_v0_32768 + atf_add_test_case shrink_48M_16M_v0_65536 + atf_add_test_case shrink_64M_48M_v0_4096 + atf_add_test_case shrink_64M_48M_v0_8192 + atf_add_test_case shrink_64M_48M_v0_16384 + atf_add_test_case shrink_64M_48M_v0_32768 + atf_add_test_case shrink_64M_48M_v0_65536 + atf_add_test_case shrink_32M_24M_v1_4096 + atf_add_test_case shrink_32M_24M_v1_8192 + atf_add_test_case shrink_32M_24M_v1_16384 + atf_add_test_case shrink_32M_24M_v1_32768 + atf_add_test_case shrink_32M_24M_v1_65536 + atf_add_test_case shrink_48M_16M_v1_4096 + atf_add_test_case shrink_48M_16M_v1_8192 + atf_add_test_case shrink_48M_16M_v1_16384 + atf_add_test_case shrink_48M_16M_v1_32768 + atf_add_test_case shrink_48M_16M_v1_65536 + atf_add_test_case shrink_64M_48M_v1_4096 + atf_add_test_case shrink_64M_48M_v1_8192 + atf_add_test_case shrink_64M_48M_v1_16384 + atf_add_test_case shrink_64M_48M_v1_32768 + atf_add_test_case shrink_64M_48M_v1_65536 + atf_add_test_case shrink_32M_24M_v2_4096 + atf_add_test_case shrink_32M_24M_v2_8192 + atf_add_test_case shrink_32M_24M_v2_16384 + atf_add_test_case shrink_32M_24M_v2_32768 + atf_add_test_case shrink_32M_24M_v2_65536 + atf_add_test_case shrink_48M_16M_v2_4096 + atf_add_test_case shrink_48M_16M_v2_8192 + atf_add_test_case shrink_48M_16M_v2_16384 + atf_add_test_case shrink_48M_16M_v2_32768 + atf_add_test_case shrink_48M_16M_v2_65536 + atf_add_test_case shrink_64M_48M_v2_4096 + atf_add_test_case shrink_64M_48M_v2_8192 + atf_add_test_case shrink_64M_48M_v2_16384 + atf_add_test_case shrink_64M_48M_v2_32768 + atf_add_test_case shrink_64M_48M_v2_65536 +fi + atf_add_test_case shrink_ffsv1_partial_cg +} diff --git a/contrib/netbsd-tests/sbin/resize_ffs/t_shrink_swapped.sh b/contrib/netbsd-tests/sbin/resize_ffs/t_shrink_swapped.sh new file mode 100755 index 0000000..50dc436 --- /dev/null +++ b/contrib/netbsd-tests/sbin/resize_ffs/t_shrink_swapped.sh @@ -0,0 +1,187 @@ +# $NetBSD: t_shrink_swapped.sh,v 1.2 2015/03/29 19:37:02 chopps Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jeffrey C. Rizzo. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + + +# resize_ffs params as follows: +# resize_ffs blocksize fragsize fssize newfssize level numdata swap +# where 'numdata' is the number of data directories to copy - this is +# determined manually based on the maximum number that will fit in the +# created fs. 'level' is the fs-level (-O 0,1,2) passed to newfs. +# If 'swap' is included, byteswap the fs +test_case shrink_24M_16M_v0_4096 resize_ffs 4096 512 49152 32768 0 41 swap +test_case shrink_24M_16M_v0_8192 resize_ffs 8192 1024 49152 32768 0 42 swap +test_case shrink_24M_16M_v0_16384 resize_ffs 16384 2048 49152 32768 0 43 swap +test_case shrink_24M_16M_v0_32768 resize_ffs 32768 4096 49152 32768 0 42 swap +test_case shrink_24M_16M_v0_65536 resize_ffs 65536 8192 49152 32768 0 38 swap +test_case shrink_32M_24M_v0_4096 resize_ffs 4096 512 65536 49152 0 55 swap +test_case shrink_32M_24M_v0_8192 resize_ffs 8192 1024 65536 49152 0 56 swap +test_case shrink_32M_24M_v0_16384 resize_ffs 16384 2048 65536 49152 0 58 swap +test_case shrink_32M_24M_v0_32768 resize_ffs 32768 4096 65536 49152 0 56 swap +test_case_xfail shrink_32M_24M_v0_65536 "PR bin/44204" resize_ffs 65536 8192 65536 49152 0 51 swap +test_case shrink_48M_16M_v0_4096 resize_ffs 4096 512 98304 32768 0 82 swap +test_case shrink_48M_16M_v0_8192 resize_ffs 8192 1024 98304 32768 0 84 swap +test_case shrink_48M_16M_v0_16384 resize_ffs 16384 2048 98304 32768 0 87 swap +test_case shrink_48M_16M_v0_32768 resize_ffs 32768 4096 98304 32768 0 83 swap +test_case shrink_48M_16M_v0_65536 resize_ffs 65536 8192 98304 32768 0 76 swap +test_case shrink_64M_48M_v0_4096 resize_ffs 4096 512 131072 98304 0 109 swap +test_case shrink_64M_48M_v0_8192 resize_ffs 8192 1024 131072 98304 0 111 swap +test_case shrink_64M_48M_v0_16384 resize_ffs 16384 2048 131072 98304 0 115 swap +test_case shrink_64M_48M_v0_32768 resize_ffs 32768 4096 131072 98304 0 111 swap +test_case shrink_64M_48M_v0_65536 resize_ffs 65536 8192 131072 98304 0 101 swap + +test_case shrink_24M_16M_v1_4096 resize_ffs 4096 512 49152 32768 1 41 swap +test_case shrink_24M_16M_v1_8192 resize_ffs 8192 1024 49152 32768 1 42 swap +test_case shrink_24M_16M_v1_16384 resize_ffs 16384 2048 49152 32768 1 43 swap +test_case shrink_24M_16M_v1_32768 resize_ffs 32768 4096 49152 32768 1 42 swap +test_case shrink_24M_16M_v1_65536 resize_ffs 65536 8192 49152 32768 1 38 swap +test_case shrink_32M_24M_v1_4096 resize_ffs 4096 512 65536 49152 1 55 swap +test_case shrink_32M_24M_v1_8192 resize_ffs 8192 1024 65536 49152 1 56 swap +test_case shrink_32M_24M_v1_16384 resize_ffs 16384 2048 65536 49152 1 58 swap +test_case shrink_32M_24M_v1_32768 resize_ffs 32768 4096 65536 49152 1 56 swap +test_case_xfail shrink_32M_24M_v1_65536 "PR bin/44204" resize_ffs 65536 8192 65536 49152 1 51 swap +test_case shrink_48M_16M_v1_4096 resize_ffs 4096 512 98304 32768 1 82 swap +test_case shrink_48M_16M_v1_8192 resize_ffs 8192 1024 98304 32768 1 84 swap +test_case shrink_48M_16M_v1_16384 resize_ffs 16384 2048 98304 32768 1 87 swap +test_case shrink_48M_16M_v1_32768 resize_ffs 32768 4096 98304 32768 1 83 swap +test_case shrink_48M_16M_v1_65536 resize_ffs 65536 8192 98304 32768 1 76 swap +test_case shrink_64M_48M_v1_4096 resize_ffs 4096 512 131072 98304 1 109 swap +test_case shrink_64M_48M_v1_8192 resize_ffs 8192 1024 131072 98304 1 111 swap +test_case shrink_64M_48M_v1_16384 resize_ffs 16384 2048 131072 98304 1 115 swap +test_case shrink_64M_48M_v1_32768 resize_ffs 32768 4096 131072 98304 1 111 swap +test_case shrink_64M_48M_v1_65536 resize_ffs 65536 8192 131072 98304 1 101 swap + +test_case_xfail shrink_24M_16M_v2_4096 "PR bin/44205" resize_ffs 4096 512 49152 32768 2 41 swap +test_case_xfail shrink_24M_16M_v2_8192 "PR bin/44205" resize_ffs 8192 1024 49152 32768 2 42 swap +test_case_xfail shrink_24M_16M_v2_16384 "PR bin/44205" resize_ffs 16384 2048 49152 32768 2 43 swap +test_case_xfail shrink_24M_16M_v2_32768 "PR bin/44205" resize_ffs 32768 4096 49152 32768 2 42 swap +test_case_xfail shrink_24M_16M_v2_65536 "PR bin/44205" resize_ffs 65536 8192 49152 32768 2 38 swap +test_case_xfail shrink_32M_24M_v2_4096 "PR bin/44205" resize_ffs 4096 512 65536 49152 2 55 swap +test_case_xfail shrink_32M_24M_v2_8192 "PR bin/44205" resize_ffs 8192 1024 65536 49152 2 56 swap +test_case_xfail shrink_32M_24M_v2_16384 "PR bin/44205" resize_ffs 16384 2048 65536 49152 2 58 swap +test_case_xfail shrink_32M_24M_v2_32768 "PR bin/44205" resize_ffs 32768 4096 65536 49152 2 56 swap +test_case_xfail shrink_32M_24M_v2_65536 "PR bin/44204" resize_ffs 65536 8192 65536 49152 2 51 swap +test_case_xfail shrink_48M_16M_v2_4096 "PR bin/44205" resize_ffs 4096 512 98304 32768 2 82 swap +test_case_xfail shrink_48M_16M_v2_8192 "PR bin/44205" resize_ffs 8192 1024 98304 32768 2 84 swap +test_case_xfail shrink_48M_16M_v2_16384 "PR bin/44205" resize_ffs 16384 2048 98304 32768 2 87 swap +test_case_xfail shrink_48M_16M_v2_32768 "PR bin/44205" resize_ffs 32768 4096 98304 32768 2 83 swap +test_case_xfail shrink_48M_16M_v2_65536 "PR bin/44205" resize_ffs 65536 8192 98304 32768 2 76 swap +test_case_xfail shrink_64M_48M_v2_4096 "PR bin/44205" resize_ffs 4096 512 131072 98304 2 109 swap +test_case_xfail shrink_64M_48M_v2_8192 "PR bin/44205" resize_ffs 8192 1024 131072 98304 2 111 swap +test_case_xfail shrink_64M_48M_v2_16384 "PR bin/44205" resize_ffs 16384 2048 131072 98304 2 115 swap +test_case_xfail shrink_64M_48M_v2_32768 "PR bin/44205" resize_ffs 32768 4096 131072 98304 2 111 swap +test_case_xfail shrink_64M_48M_v2_65536 "PR bin/44205" resize_ffs 65536 8192 131072 98304 2 101 swap + + +atf_test_case shrink_ffsv1_partial_cg +shrink_ffsv1_partial_cg_head() +{ + atf_set "descr" "Checks successful shrinkage of ffsv1 by" \ + "less than a cylinder group" +} +shrink_ffsv1_partial_cg_body() +{ + echo "*** resize_ffs shrinkage partial cg test" + + atf_check -o ignore -e ignore newfs -V1 -F -s 5760 ${IMG} + + # shrink so there's a partial cg at the end + atf_check -s exit:0 resize_ffs -c -s 4000 -y ${IMG} + atf_check -s exit:0 resize_ffs -s 4000 -y ${IMG} + atf_check -s exit:0 -o ignore fsck_ffs -f -n -F ${IMG} + atf_check -s exit:1 resize_ffs -c -s 4000 -y ${IMG} +} + +atf_init_test_cases() +{ + setupvars + atf_add_test_case shrink_24M_16M_v0_4096 + atf_add_test_case shrink_24M_16M_v1_8192 + atf_add_test_case shrink_24M_16M_v2_16384 +if [ "${RESIZE_FFS_ALL_TESTS-X}" != "X" ]; then + atf_add_test_case shrink_24M_16M_v0_8192 + atf_add_test_case shrink_24M_16M_v0_16384 + atf_add_test_case shrink_24M_16M_v0_32768 + atf_add_test_case shrink_24M_16M_v0_65536 + atf_add_test_case shrink_24M_16M_v1_4096 + atf_add_test_case shrink_24M_16M_v1_16384 + atf_add_test_case shrink_24M_16M_v1_32768 + atf_add_test_case shrink_24M_16M_v1_65536 + atf_add_test_case shrink_24M_16M_v2_4096 + atf_add_test_case shrink_24M_16M_v2_8192 + atf_add_test_case shrink_24M_16M_v2_32768 + atf_add_test_case shrink_24M_16M_v2_65536 + atf_add_test_case shrink_32M_24M_v0_4096 + atf_add_test_case shrink_32M_24M_v0_8192 + atf_add_test_case shrink_32M_24M_v0_16384 + atf_add_test_case shrink_32M_24M_v0_32768 + atf_add_test_case shrink_32M_24M_v0_65536 + atf_add_test_case shrink_48M_16M_v0_4096 + atf_add_test_case shrink_48M_16M_v0_8192 + atf_add_test_case shrink_48M_16M_v0_16384 + atf_add_test_case shrink_48M_16M_v0_32768 + atf_add_test_case shrink_48M_16M_v0_65536 + atf_add_test_case shrink_64M_48M_v0_4096 + atf_add_test_case shrink_64M_48M_v0_8192 + atf_add_test_case shrink_64M_48M_v0_16384 + atf_add_test_case shrink_64M_48M_v0_32768 + atf_add_test_case shrink_64M_48M_v0_65536 + atf_add_test_case shrink_32M_24M_v1_4096 + atf_add_test_case shrink_32M_24M_v1_8192 + atf_add_test_case shrink_32M_24M_v1_16384 + atf_add_test_case shrink_32M_24M_v1_32768 + atf_add_test_case shrink_32M_24M_v1_65536 + atf_add_test_case shrink_48M_16M_v1_4096 + atf_add_test_case shrink_48M_16M_v1_8192 + atf_add_test_case shrink_48M_16M_v1_16384 + atf_add_test_case shrink_48M_16M_v1_32768 + atf_add_test_case shrink_48M_16M_v1_65536 + atf_add_test_case shrink_64M_48M_v1_4096 + atf_add_test_case shrink_64M_48M_v1_8192 + atf_add_test_case shrink_64M_48M_v1_16384 + atf_add_test_case shrink_64M_48M_v1_32768 + atf_add_test_case shrink_64M_48M_v1_65536 + atf_add_test_case shrink_32M_24M_v2_4096 + atf_add_test_case shrink_32M_24M_v2_8192 + atf_add_test_case shrink_32M_24M_v2_16384 + atf_add_test_case shrink_32M_24M_v2_32768 + atf_add_test_case shrink_32M_24M_v2_65536 + atf_add_test_case shrink_48M_16M_v2_4096 + atf_add_test_case shrink_48M_16M_v2_8192 + atf_add_test_case shrink_48M_16M_v2_16384 + atf_add_test_case shrink_48M_16M_v2_32768 + atf_add_test_case shrink_48M_16M_v2_65536 + atf_add_test_case shrink_64M_48M_v2_4096 + atf_add_test_case shrink_64M_48M_v2_8192 + atf_add_test_case shrink_64M_48M_v2_16384 + atf_add_test_case shrink_64M_48M_v2_32768 + atf_add_test_case shrink_64M_48M_v2_65536 +fi + atf_add_test_case shrink_ffsv1_partial_cg +} diff --git a/contrib/netbsd-tests/sbin/resize_ffs/testdata.md5 b/contrib/netbsd-tests/sbin/resize_ffs/testdata.md5 new file mode 100644 index 0000000..9a3f76f --- /dev/null +++ b/contrib/netbsd-tests/sbin/resize_ffs/testdata.md5 @@ -0,0 +1,18 @@ +MD5 (1024) = eadce85bc513cc7b9b46c027ce07ccdb +MD5 (1025) = 3cf2a95b3af7377ca81ff08265534334 +MD5 (131072) = 3bf5f82ad5e1f8878caa699548cc0955 +MD5 (131073) = 3423d2f10e3abb20e1ceae4b055f5071 +MD5 (16384) = 933f03c66d4e2da32089ed994c9b34bd +MD5 (16385) = d0b296920f44ef298880a2d963066026 +MD5 (2048) = fb03fb8916dd57f9648f89a06bb46f06 +MD5 (2049) = f2e489640fc3af5f09352d27717d832e +MD5 (32768) = d940d6ccf83aeb00e71b9bbeaf860962 +MD5 (32769) = 760e060cefd844c082a10b3bef1408f7 +MD5 (4096) = a04926ee9302f93a322e784a6b044577 +MD5 (4097) = bf13de3963f43a0ffaadb1c782b71372 +MD5 (512) = 991ad794ac386e8ba71d9bb64ab4c979 +MD5 (513) = ede1dc964fe2460dd74c3c87942162ad +MD5 (65536) = 1ee304df7275d8f88c5c0650536c842c +MD5 (65537) = 964632a8f1a323e31af6cf1297f88041 +MD5 (8192) = 51ce7789ae9662b2c13195573a447206 +MD5 (8193) = 35d478bc5fba0d96ffb318748d1035c7 diff --git a/contrib/netbsd-tests/sbin/resize_ffs/testdata.tar.gz.base64 b/contrib/netbsd-tests/sbin/resize_ffs/testdata.tar.gz.base64 new file mode 100644 index 0000000..d8fe840 --- /dev/null +++ b/contrib/netbsd-tests/sbin/resize_ffs/testdata.tar.gz.base64 @@ -0,0 +1,10938 @@ +begin-base64 644 testdata.tar.gz +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 +BYj5GMUVET4FSnC6zauv7ZhiE9U17V6WFnmIBwZ3zhWkL8eb2TzvTOfZw4L4ZCSK +cIKEs8jOM49qBE+6P+x6jbp2GNtOuFp/WxCyQIQXG7XDE9YeaUu4/S5aegmdM0S2 +tnDHEHrk2s6EkH89wbEXwccsZ9PgafhhorasAQoZOdKzAMmt0MEDB3b7BrlNGFCr +wS6KSfX8vrIVGNSMqGyxUfLYggRNtWxE7x4tN8JAbXQ6gspaRMjprpuvGieqYPgT +V52s3D4jneWAyy+XhUQHWxCLUbiCG4PQmAF0RVj9tJZwSMjW/PpUlL1bFjiYdCl5 +YEekzVs4YDjkG8MKJH1B3lOgqmKYm/4MRr0rq9eMOKU1dnfHuAuCG1txYRwCPbWg +XRwT2BNm1cmQh6/0teqJ2L/iZLOEsSckj6W5mP/OWSAtEEK15zahOU6rmICfQD1H +q9Z3D/qdG9q7+q+beRhOG8zSq9ykOm6N3NhnInjQbOZ5keGsLd9Cvdh3u+4pNU8m +hopfl5xK3tu1z1x+f8dSdqPPoQgiclOr3oErSjL0sJYyUlsXGttjmZ1CX+qlqdP5 +21bFA46l90h5lCEb1deme5wEn7sVkL22sfNO/ZgN49TpUn21jVGs/GlzTsDlApAP +0LQnh/tyE10vhL0eS2zyr8NX/fLPMfasOuvhm/LZiKoe8TQNYaLkEt04ozbKD4eM +2YiRtBVuaTAgj4FS/tn0ZOOoevcNVST1lxrjrZ6q25Quj/YB7jwUdOsNPdF8NR1H +eHASk1IuFqiYj9he2A0lJU0QcYqFUbWtE6tkySrAshSfmgRohskjvDtnXIJn2DA5 +7bODLbkoJws5nUjM1vkeuprzI6aC12rfkhr6X/bonNnyEKKDeQKJ509JmQM2JQLo +yLdred1IXifjIzIDVYgQTbvgnw3d1720RWNLJhAgnqrCfqZC6R3ebCT0zwnQqNJg +P52OqBqHuim6yrgGyNEg6dJLJE64Ipjk//a+En0xQsXHqvwsYdCHebu3auiZqrUx +EYV2cVGW7H/iW6psFjGW2jAoYjb06zm08upWuuGkxli6dqBORKWUakecTh7NGKXr +wGTur8a31lvkzlCkycZp3MkYW2RjyMeVkqLSwT7fWqmm6Mjldb8BziOELUvgP5XE +XuOVXwKmPyeZDvJ2/K6g+KFM6euWYWqP31e7/2yq2uvbffL+p46h83/SQtDe3JYz +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 +1M+q804BKH73FL8J+w1SXX3tvkdMy2z82pyD3xsOfnrjoOQyYxucPyZn8hcwL32c +6r5+xqss+XXcpc8+hc/J3mW7VImdKDkvR+8bM5a9Kc8Khmi15NdSQtd4yGjuyEAM +ibFGTK4JRr5IzO5H5H/SgmQzoBEV9eDgYqtm+4t3YOOgcGAqvZJXvUkwKwrLj1QR +TAhA7WXl3BpueZCwN9sFiXSLyuRm2O8S8MAJ6kPwqiGdGAjjkdecM2POiJ7LxAgp +sCCkJKsLIK7G/SHaYWnkmKZROdcohPE85CI9hgdS+IZlKMFS3ja9OYVEYytyYPiQ +UXZ1S/4QGVkNAxMCv2Reymir+FQGpy5BeITgr0gQ3RYNVcs8lJVvp409Lr6gpekt +WBT3V4E/mx0yY4W9FVcA1R2ZJoRKTpZLkoyxsXFZaZk0X76zeCR2O3mMOa4uNHEH +dpImS6fiXFUpfkwJ+wDxGS02WEFtbk2c1M0PdjRdZ0CwKDj5om06XXHLjpi2MY7x +3sqGMGe7nwPwJRE1guKv27xCuwZzryfktEA3trycM8rNmyfWZ86wAAahS8bw30se +GgtG/d1E7DRO2vxvigyL05FnDA9niWAP84VVPTfkakDTdGqspgJwjCJxM+C+AxlF +z4aTAgvKJux9ISmDM2x0zk+mON/3/ySwCOvmnZJWnFgYD+CtJyYUwJYSwgqWPUlf +Yvj/AhuojfJfk7o+HKRdE5vow1qlRCbOHDmKbR3Fh+Rd0NnXKIQzz4mfVReHfebl +3pfolvW1Dhse4Uixbk98MQnN7wyVRY2KNK7yHkG4DPGi/e5UgVMLDM0o054sRgdL +6nu8Co+BrDAXjusqeLzajyyijzrOpmFl6UqyaDW9mNYpjuS9gGkrfv4QOXREeJkN +SarPWgEU/dArOOQTcH7sH158JIW8OtCJbQRYORll6DDHyR2NFYt4sgu4InLjSgzs +Qmf4q57yan2TpjloCvyiSPJAwAmGdM10WkTOvpF8a/36N1Sm01jdochVQjSQrQ3e +HvVHhy+wUU0sfbDaUbpMWBp2Uph4GMbwP0oAJXRObfU2aGL85nYm9Z5DKBIqzR7l +LQDJLrgcQAwH4xUCJLEVnKpGHsEqcGs50cO7BM4Gmuk3/9LqtMBLyai+g/HjSn2W +2G3iAhNVXh6y+GFLV+Rc4n9bafGPoB7SBSLN7eubkXF5wAGjztz6Tm+09keUSIMh +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 +//znP//5z3/+85//L/0vxuXHSABICAA= +==== diff --git a/contrib/netbsd-tests/sbin/route/t_missing.sh b/contrib/netbsd-tests/sbin/route/t_missing.sh new file mode 100755 index 0000000..cd9387e --- /dev/null +++ b/contrib/netbsd-tests/sbin/route/t_missing.sh @@ -0,0 +1,45 @@ +# $NetBSD: t_missing.sh,v 1.3 2012/03/17 08:34:55 jruoho Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case missing +missing_head() { + atf_set "descr" "Check route(8) with a missing argument (PR bin/42179)" +} + +missing_body() { + + atf_check -s exit:1 \ + -e not-inline:"route: writing to routing socket: Invalid argument\n" \ + route -n get +} + +atf_init_test_cases() { + atf_add_test_case missing +} diff --git a/contrib/netbsd-tests/sbin/sysctl/t_perm.sh b/contrib/netbsd-tests/sbin/sysctl/t_perm.sh new file mode 100755 index 0000000..25b2975 --- /dev/null +++ b/contrib/netbsd-tests/sbin/sysctl/t_perm.sh @@ -0,0 +1,210 @@ +# $NetBSD: t_perm.sh,v 1.7 2016/06/17 03:55:35 pgoyette Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +file="/tmp/d_sysctl.out" + +clean() { + + if [ -f $file ]; then + rm $file + fi +} + +sysctl_write() { + + deadbeef="3735928559" + deadbeef_signed="-559038737" + + sysctl $1 | cut -d= -f1 > $file + + if [ ! -f $file ]; then + atf_fail "sysctl failed" + fi + + while read line; do + + node=$(echo $line) + + case $node in + + "$1."*) + atf_check -s not-exit:0 -e ignore \ + -x sysctl -w $node=$deadbeef + ;; + esac + + done < $file + + # A functional verification that $deadbeef + # was not actually written to the node. + # + if [ ! -z $(sysctl $1 | grep -e $deadbeef -e $deadbeef_signed) ]; then + atf_fail "value was written" + fi +} + +# ddb. +# +atf_test_case sysctl_ddb cleanup +sysctl_ddb_head() { + atf_set "require.user" "unprivileged" + atf_set "descr" "Test writing to 'ddb' sysctl node as an user" +} + +sysctl_ddb_body() { + sysctl_write "ddb" +} + +sysctl_ddb_cleanup() { + clean +} + +# hw. +# +atf_test_case sysctl_hw cleanup +sysctl_hw_head() { + atf_set "require.user" "unprivileged" + atf_set "descr" "Test writing to 'hw' sysctl node as an user" +} + +sysctl_hw_body() { + sysctl_write "hw" +} + +sysctl_hw_cleanup() { + clean +} + +# kern. +# +atf_test_case sysctl_kern cleanup +sysctl_kern_head() { + atf_set "require.user" "unprivileged" + atf_set "descr" "Test writing to 'kern' " \ + "sysctl node as an user (PR kern/44946)" +} + +sysctl_kern_body() { + sysctl_write "kern" +} + +sysctl_kern_cleanup() { + clean +} + +# machdep. +# +atf_test_case sysctl_machdep cleanup +sysctl_machdep_head() { + atf_set "require.user" "unprivileged" + atf_set "descr" "Test writing to 'machdep' sysctl node as an user" +} + +sysctl_machdep_body() { + sysctl_write "machdep" +} + +sysctl_machdep_cleanup() { + clean +} + +# net. +# +atf_test_case sysctl_net cleanup +sysctl_net_head() { + atf_set "require.user" "unprivileged" + atf_set "descr" "Test writing to 'net' sysctl node as an user" +} + +sysctl_net_body() { + sysctl_write "net" +} + +sysctl_net_cleanup() { + clean +} + +# security. +# +atf_test_case sysctl_security cleanup +sysctl_security_head() { + atf_set "require.user" "unprivileged" + atf_set "descr" "Test writing to 'security' sysctl node as an user" +} + +sysctl_security_body() { + sysctl_write "security" +} + +sysctl_security_cleanup() { + clean +} + +# vfs. +# +atf_test_case sysctl_vfs cleanup +sysctl_vfs_head() { + atf_set "require.user" "unprivileged" + atf_set "descr" "Test writing to 'vfs' sysctl node as an user" +} + +sysctl_vfs_body() { + sysctl_write "vfs" +} + +sysctl_vfs_cleanup() { + clean +} + +# vm. +# +atf_test_case sysctl_vm cleanup +sysctl_vm_head() { + atf_set "require.user" "unprivileged" + atf_set "descr" "Test writing to 'vm' sysctl node as an user" +} + +sysctl_vm_body() { + sysctl_write "vm" +} + +sysctl_vm_cleanup() { + clean +} + +atf_init_test_cases() { + atf_add_test_case sysctl_ddb + atf_add_test_case sysctl_hw + atf_add_test_case sysctl_kern + atf_add_test_case sysctl_machdep + atf_add_test_case sysctl_net + atf_add_test_case sysctl_security + atf_add_test_case sysctl_vfs + atf_add_test_case sysctl_vm +} diff --git a/contrib/netbsd-tests/sbin/sysctl/t_sysctl.sh b/contrib/netbsd-tests/sbin/sysctl/t_sysctl.sh new file mode 100755 index 0000000..6573d8d --- /dev/null +++ b/contrib/netbsd-tests/sbin/sysctl/t_sysctl.sh @@ -0,0 +1,45 @@ +# $NetBSD: t_sysctl.sh,v 1.2 2014/05/16 18:50:28 palle Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() { + atf_set "descr" "Test that sysctl(8) works" +} + +basic_body() { + + atf_check -s exit:0 -o ignore -e empty -x "sysctl -a" + atf_check -s exit:0 -o ignore -e empty -x "sysctl -d" +} + +atf_init_test_cases() { + + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/share/examples/t_asm.sh b/contrib/netbsd-tests/share/examples/t_asm.sh new file mode 100755 index 0000000..f615935 --- /dev/null +++ b/contrib/netbsd-tests/share/examples/t_asm.sh @@ -0,0 +1,74 @@ +# $NetBSD: t_asm.sh,v 1.1 2013/02/16 12:44:26 jmmv Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# check_implemented +# +# Verifies if a particular asm example is implemented for the current +# platform. The example_name argument is the name of the subdirectory +# of the examples/asm/ subtree that includes the code for the example +# under test. +# +# If the example is not implemented, the calling test is skipped. If the +# check for implementation fails, the calling test is failed. +check_implemented() { + local name="${1}"; shift + + local implemented=$(cd /usr/share/examples/asm/${name}/ && \ + make check-implemented) + [ $? -eq 0 ] || atf_fail "Failed to determine if the sample" \ + "program is supported" + [ "${implemented}" = yes ] || atf_skip "Example program not" \ + "implemented on this platform" +} + +# copy_example +# +# Copies the example code and supporting Makefiles into the current +# directory. +copy_example() { + local name="${1}"; shift + + cp /usr/share/examples/asm/${name}/* . +} + +atf_test_case hello +hello_head() { + atf_set "descr" "Builds, runs and validates the 'hello' asm example" + atf_set "require.files" "/usr/share/examples/asm/hello/" + atf_set "require.progs" "make" +} +hello_body() { + check_implemented hello + copy_example hello + atf_check -s exit:0 -o ignore -e ignore make + atf_check -s exit:0 -o inline:'Hello, world!\n' -e empty ./hello +} + +atf_init_test_cases() { + atf_add_test_case hello +} diff --git a/contrib/netbsd-tests/share/mk/common.subr b/contrib/netbsd-tests/share/mk/common.subr new file mode 100644 index 0000000..0b542fe --- /dev/null +++ b/contrib/netbsd-tests/share/mk/common.subr @@ -0,0 +1,132 @@ +# Copyright 2012 Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT +# OWNER 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. + +# Dumps a file to the test's stdout for debugging purposes. +dump_file() { + local file="${1}"; shift + + echo "==== BEGIN ${file}" + cat "${file}" + echo "==== END ${file}" +} + +# Creates a C source file with a single symbol in it. +# +# The file parameter specifies the path to the file to create, WITHOUT the +# C extension. Both a source file and a header file are created. Any +# intermediate directories are created too. +# +# The symbol parameter specifies the name of the symbol to place in the +# module, which is defined as a string holding the name of the module. +create_c_module() { + local file="${1}"; shift + local symbol="${1}"; shift + + mkdir -p "$(dirname ${file})" + echo "extern const char *${symbol};" >"${file}.h" + echo "const char *${symbol} = \"${file}\";" >"${file}.c" + + dump_file "${file}.h" + dump_file "${file}.c" +} + +# Creates a main C source file that references a set of modules. +# +# The modules to be referenced should have been created with +# create_c_module. The generated source file ensures that all the modules +# are referenced in some way, which helps in testing that the generated +# binary holds all the necessary objects. +# +# The file parameter specifies the name of the file to create. +# +# The rest of the parameters are module:symbol pairs that specify the +# module to include and the symbol within them to reference. +create_main_using_modules() { + local file="${1}"; shift + + local modules= + local symbols= + for spec in "${@}"; do + modules="${modules} $(echo ${spec} | cut -d : -f 1)" + symbols="${symbols} $(echo ${spec} | cut -d : -f 2)" + done + + echo '#include ' >"${file}" + for module in ${modules}; do + echo "#include \"${module}\"" >>"${file}" + done + echo 'int main(void) {' >>"${file}" + for symbol in ${symbols}; do + echo "printf(\"%s\n\", ${symbol});" >>"${file}" + done + echo 'return 0; }' >>"${file}" + + dump_file "${file}" +} + +# Creates a mk.conf file and points MAKECONF to it. +# +# The first argument specifies the name of the configuration file to +# create. +# +# The rest of the arguments include a collection of modifiers for the +# generated configuration file and/or a collection of explicit variable +# names and their values to set. +# +# The qualifiers can be one of: +# - owngrp: Override the *OWN and *GRP variables to point to the current +# user. +create_make_conf() { + local file="${1}"; shift + + echo "# Test configuration file" >"${file}" + for arg in "${@}"; do + case "${arg}" in + *=*) + echo "${arg}" >>"${file}" + ;; + owngrp) + for class in BIN DOC LIB LINKS MAN; do + echo "${class}OWN=$(id -un)" >>"${file}" + echo "${class}GRP=$(id -gn)" >>"${file}" + done + ;; + esac + done + + case "${file}" in + /*) + MAKECONF="${file}"; export MAKECONF + ;; + *) + MAKECONF="$(pwd)/${file}"; export MAKECONF + ;; + esac + + dump_file "${file}" +} diff --git a/contrib/netbsd-tests/share/mk/t_lib.sh b/contrib/netbsd-tests/share/mk/t_lib.sh new file mode 100755 index 0000000..0187aa2 --- /dev/null +++ b/contrib/netbsd-tests/share/mk/t_lib.sh @@ -0,0 +1,60 @@ +# Copyright 2012 Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT +# OWNER 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. + +atf_test_case defaults__build_and_install +defaults__build_and_install_body() { + create_c_module module1 first + create_c_module module2 second + + CC=gcc + if [ ! -e /usr/bin/gcc -a -e /usr/bin/clang ]; then + export HAVE_LLVM=yes + CC=clang + fi + + cat >Makefile < +EOF + + atf_check -o ignore make + mkdir -p root/usr/lib + mkdir -p root/usr/libdata/lint + create_make_conf mk.conf owngrp DESTDIR="$(pwd)/root" + atf_check -o ignore make install + + create_main_using_modules main.c module1.h:first module2.h:second + atf_check -o ignore ${CC} -I. -Lroot/usr/lib -o main main.c -ltwo-modules + + atf_check -o inline:'module1\nmodule2\n' ./main +} + +atf_init_test_cases() { + atf_add_test_case defaults__build_and_install +} diff --git a/contrib/netbsd-tests/share/mk/t_own.sh b/contrib/netbsd-tests/share/mk/t_own.sh new file mode 100755 index 0000000..7372dd2 --- /dev/null +++ b/contrib/netbsd-tests/share/mk/t_own.sh @@ -0,0 +1,72 @@ +# Copyright 2012 Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT +# OWNER 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. + +atf_test_case makeconf__ok +makeconf__ok_body() { + cat >Makefile < +EOF + + echo >empty.conf + cat >custom.conf <Makefile < +EOF + + echo >empty.conf + cat >custom.conf <hello.c < +int main(void) { printf("Hello, test!\n"); return 0; } +EOF + cat >hello.1 <Makefile < +EOF + + atf_check -o ignore make + mkdir -p root/the/bin/dir + mkdir -p root/usr/share/man/man1 + mkdir -p root/usr/share/man/html1 + create_make_conf mk.conf owngrp DESTDIR="$(pwd)/root" + atf_check -o ignore make install + + atf_check -o inline:'Hello, test!\n' ./root/the/bin/dir/hello + atf_check -o inline:'Manpage of hello(1).\n' \ + cat root/usr/share/man/man1/hello.1 + atf_check -o match:'Manpage of hello' \ + cat root/usr/share/man/html1/hello.html +} + +atf_test_case without_man__build_and_install +without_man__build_and_install_body() { + if [ ! -e /usr/bin/gcc -a -e /usr/bin/clang ]; then + export HAVE_LLVM=yes + fi + + cat >hello.c < +int main(void) { printf("Hello, test!\n"); return 0; } +EOF + + cat >Makefile < +EOF + + atf_check -o ignore make + mkdir -p root/the/bin/dir + create_make_conf mk.conf owngrp DESTDIR="$(pwd)/root" + atf_check -o ignore make install + + atf_check -o inline:'Hello, test!\n' ./root/the/bin/dir/hello +} + +atf_init_test_cases() { + atf_add_test_case defaults__build_and_install + atf_add_test_case without_man__build_and_install +} diff --git a/contrib/netbsd-tests/share/mk/t_test.sh b/contrib/netbsd-tests/share/mk/t_test.sh new file mode 100755 index 0000000..08681d8 --- /dev/null +++ b/contrib/netbsd-tests/share/mk/t_test.sh @@ -0,0 +1,115 @@ +# Copyright 2012 Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * 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. +# * Neither the name of Google Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT +# OWNER 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. + +# Helper function for the various one_* test cases. +# +# The first argument must be one of C, CXX or SH, and this indicates the +# language of the test program. +# +# The second argument is the name of the test program, without an extension. +# The corresponding source file must exist in the current directory. +one_test() { + + if [ ! -e /usr/bin/gcc -a -e /usr/bin/clang ]; then + export HAVE_LLVM=yes + fi + local lang="${1}"; shift + local name="${1}"; shift + + cat >Makefile < +TESTSDIR = \${TESTSBASE}/fake +TESTS_${lang} = ${name} +.include +EOF + + atf_check -o ignore make + mkdir -p root/usr/tests/fake + create_make_conf mk.conf owngrp DESTDIR="$(pwd)/root" + atf_check -o ignore make install + + atf_check -o match:'ident: one_tc' "./root/usr/tests/fake/${name}" -l +} + +atf_test_case one_c +one_c_body() { + cat >t_fake.c < +ATF_TC_WITHOUT_HEAD(one_tc); +ATF_TC_BODY(one_tc, tc) +{ + atf_tc_fail("Failing explicitly"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, one_tc); + return atf_no_error(); +} +EOF + one_test C t_fake +} + +atf_test_case one_cxx +one_cxx_body() { + cat >t_fake.cpp < +ATF_TEST_CASE_WITHOUT_HEAD(one_tc); +ATF_TEST_CASE_BODY(one_tc) +{ + fail("Failing explicitly"); +} + +ATF_INIT_TEST_CASES(tcs) +{ + ATF_ADD_TEST_CASE(tcs, one_tc); +} +EOF + one_test CXX t_fake +} + +atf_test_case one_sh +one_sh_body() { + cat >t_fake.sh < +__RCSID("$NetBSD: t_print.c,v 1.2 2016/08/27 11:30:49 christos Exp $"); + +#include "net/dl_print.c" + +#include + +static const struct { + struct dl_addr ia; + const char *str; + int len; +} tst[] = { + { + { + .dl_type = 6, + .dl_nlen = 0, + .dl_alen = 6, + .dl_slen = 0, + .dl_data = { + (char)0x01, (char)0xa2, (char)0x03, + (char)0xc4, (char)0x05, (char)0xf6, + }, + }, + "/6#01:a2:03:c4:05:f6", + 20, + }, + { + { + .dl_type = 24, + .dl_nlen = 3, + .dl_alen = 6, + .dl_slen = 0, + .dl_data = { + 'l', 'o', '0', + (char)0x11, (char)0x22, (char)0x33, + (char)0x44, (char)0x55, (char)0x66, + }, + }, + "lo0/24#11:22:33:44:55:66", + 24, + }, + { + { + .dl_type = 24, + .dl_nlen = 7, + .dl_alen = 1, + .dl_slen = 0, + .dl_data = { + 'n', 'p', 'f', 'l', 'o', 'g', '0', (char)0xa5, + }, + }, + "npflog0/24#a5", + 13, + }, + { + { + .dl_type = 0, + .dl_nlen = 0, + .dl_alen = 0, + .dl_slen = 0, + .dl_data = { + '\0' + }, + }, + "/0#", + 3, + }, +}; + + +ATF_TC(dl_print); +ATF_TC_HEAD(dl_print, tc) +{ + + atf_tc_set_md_var(tc, "descr", "printing of link address"); +} + +ATF_TC_BODY(dl_print, tc) +{ + char buf[LINK_ADDRSTRLEN]; + int r; + size_t l = sizeof(buf); + + for (size_t i = 0; i < __arraycount(tst); i++) { + r = dl_print(buf, l, &tst[i].ia); + ATF_REQUIRE_STREQ(buf, tst[i].str); + ATF_REQUIRE_EQ(r, tst[i].len); + } + + l = 4; + for (size_t i = 0; i < __arraycount(tst); i++) { + r = dl_print(buf, l, &tst[i].ia); + ATF_CHECK(strncmp(buf, tst[i].str, l - 1) == 0); + if (r > (int)l) + ATF_REQUIRE_EQ(buf[l - 1], '\0'); + ATF_REQUIRE_EQ(r, tst[i].len); + } +} + +ATF_TC(sdl_print); +ATF_TC_HEAD(sdl_print, tc) +{ + + atf_tc_set_md_var(tc, "descr", "printing of sockaddr_dl"); +} + +ATF_TC_BODY(sdl_print, tc) +{ + char buf[1024]; + char res[1024]; + int r, e; + size_t l = sizeof(buf); + struct sockaddr_dl sdl; + + memset(&sdl, 0, sizeof(sdl)); + for (size_t i = 0; i < __arraycount(tst); i++) { + memcpy(&sdl.sdl_addr, &tst[i].ia, sizeof(sdl.sdl_addr)); + sdl.sdl_index = (uint16_t)i; + r = sdl_print(buf, l, &sdl); + if (i == 3) + e = snprintf(res, l, "link#%zu", i); + else + e = snprintf(res, l, "[%s]:%zu", tst[i].str, i); + ATF_REQUIRE_STREQ(buf, res); + ATF_REQUIRE_EQ(r, e); + } + + l = 8; + for (size_t i = 0; i < __arraycount(tst); i++) { + memcpy(&sdl.sdl_addr, &tst[i].ia, sizeof(sdl.sdl_addr)); + sdl.sdl_index = (uint16_t)i; + r = sdl_print(buf, l, &sdl); + if (i == 3) + e = snprintf(res, l, "link#%zu", i); + else + e = snprintf(res, l, "[%s]:%zu", tst[i].str, i); + ATF_REQUIRE_STREQ(buf, res); + ATF_REQUIRE_EQ(r, e); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, dl_print); + ATF_TP_ADD_TC(tp, sdl_print); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/sys/netatalk/t_print.c b/contrib/netbsd-tests/sys/netatalk/t_print.c new file mode 100644 index 0000000..2e506c6 --- /dev/null +++ b/contrib/netbsd-tests/sys/netatalk/t_print.c @@ -0,0 +1,135 @@ +/* $NetBSD: t_print.c,v 1.1 2014/12/02 19:48:21 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_print.c,v 1.1 2014/12/02 19:48:21 christos Exp $"); + +#include "netatalk/at_print.c" + +#include + +static const struct { + struct at_addr ia; + const char *str; + int len; +} tst[] = { + { + { 0, 0 }, + "0.0", + 3, + }, + { + { htons(3), 255 }, + "3.255", + 5, + }, +}; + + +ATF_TC(at_print); +ATF_TC_HEAD(at_print, tc) +{ + + atf_tc_set_md_var(tc, "descr", "printing of struct at_addr"); +} + +ATF_TC_BODY(at_print, tc) +{ + char buf[ATALK_ADDRSTRLEN]; + int r; + size_t l = sizeof(buf); + + for (size_t i = 0; i < __arraycount(tst); i++) { + r = at_print(buf, l, &tst[i].ia); + ATF_REQUIRE_STREQ(buf, tst[i].str); + ATF_REQUIRE_EQ(r, tst[i].len); + } + + l = 4; + for (size_t i = 0; i < __arraycount(tst); i++) { + r = at_print(buf, l, &tst[i].ia); + ATF_CHECK(strncmp(buf, tst[i].str, l - 1) == 0); + if (r > (int)l) + ATF_REQUIRE_EQ(buf[l - 1], '\0'); + ATF_REQUIRE_EQ(r, tst[i].len); + } +} + +ATF_TC(sat_print); +ATF_TC_HEAD(sat_print, tc) +{ + + atf_tc_set_md_var(tc, "descr", "printing of sockaddr_at"); +} + +ATF_TC_BODY(sat_print, tc) +{ + char buf[1024]; + char res[1024]; + int r, e; + size_t l = sizeof(buf); + struct sockaddr_at sat; + + memset(&sat, 0, sizeof(sat)); + for (size_t i = 0; i < __arraycount(tst); i++) { + sat.sat_addr = tst[i].ia; + sat.sat_port = (uint8_t)i; + r = sat_print(buf, l, &sat); + if (i == 0) + e = snprintf(res, sizeof(res), "%s", tst[i].str); + else + e = snprintf(res, sizeof(res), "%s:%zu", tst[i].str, i); + + ATF_REQUIRE_STREQ(buf, res); + ATF_REQUIRE_EQ(r, e); + } + + l = 8; + for (size_t i = 0; i < __arraycount(tst); i++) { + sat.sat_addr = tst[i].ia; + sat.sat_port = (uint8_t)i; + r = sat_print(buf, l, &sat); + if (i == 0) + e = snprintf(res, l, "%s", tst[i].str); + else + e = snprintf(res, l, "%s:%zu", tst[i].str, i); + + ATF_REQUIRE_STREQ(buf, res); + ATF_REQUIRE_EQ(r, e); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, at_print); + ATF_TP_ADD_TC(tp, sat_print); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/sys/netinet/t_print.c b/contrib/netbsd-tests/sys/netinet/t_print.c new file mode 100644 index 0000000..6a0d913 --- /dev/null +++ b/contrib/netbsd-tests/sys/netinet/t_print.c @@ -0,0 +1,144 @@ +/* $NetBSD: t_print.c,v 1.2 2014/12/03 13:10:49 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_print.c,v 1.2 2014/12/03 13:10:49 christos Exp $"); + +#include "netinet/in_print.c" + +#include + +static const struct { + struct in_addr ia; + const char *str; + int len; +} tst[] = { + { + { .s_addr = ntohl(INADDR_LOOPBACK) }, + "127.0.0.1", + 9, + }, + { + { .s_addr = ntohl(INADDR_ANY) }, + "0.0.0.0", + 7, + }, + { + { .s_addr = ntohl(IN_CLASSC_NET) }, + "255.255.255.0", + 13, + }, + { + { .s_addr = ntohl(INADDR_ALLHOSTS_GROUP) }, + "224.0.0.1", + 9, + }, +}; + + +ATF_TC(in_print); +ATF_TC_HEAD(in_print, tc) +{ + + atf_tc_set_md_var(tc, "descr", "printing of struct in_addr"); +} + +ATF_TC_BODY(in_print, tc) +{ + char buf[INET_ADDRSTRLEN]; + int r; + size_t l = sizeof(buf); + + for (size_t i = 0; i < __arraycount(tst); i++) { + r = in_print(buf, l, &tst[i].ia); + ATF_REQUIRE_STREQ(buf, tst[i].str); + ATF_REQUIRE_EQ(r, tst[i].len); + } + + l = 8; + for (size_t i = 0; i < __arraycount(tst); i++) { + r = in_print(buf, l, &tst[i].ia); + ATF_CHECK(strncmp(buf, tst[i].str, l - 1) == 0); + ATF_REQUIRE_EQ(buf[l - 1], '\0'); + ATF_REQUIRE_EQ(r, tst[i].len); + } +} + +ATF_TC(sin_print); +ATF_TC_HEAD(sin_print, tc) +{ + + atf_tc_set_md_var(tc, "descr", "printing of sockaddr_in"); +} + +ATF_TC_BODY(sin_print, tc) +{ + char buf[1024]; + char res[1024]; + int r, e; + size_t l = sizeof(buf); + struct sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); + + for (size_t i = 0; i < __arraycount(tst); i++) { + sin.sin_addr = tst[i].ia; + sin.sin_port = (in_port_t)htons(i); + r = sin_print(buf, l, &sin); + if (i == 0) + e = snprintf(res, sizeof(res), "%s", tst[i].str); + else + e = snprintf(res, sizeof(res), "%s:%zu", tst[i].str, i); + + ATF_REQUIRE_STREQ(buf, res); + ATF_REQUIRE_EQ(r, e); + } + + l = 14; + for (size_t i = 0; i < __arraycount(tst); i++) { + sin.sin_addr = tst[i].ia; + sin.sin_port = (in_port_t)htons(i); + r = sin_print(buf, l, &sin); + if (i == 0) + e = snprintf(res, l, "%s", tst[i].str); + else + e = snprintf(res, l, "%s:%zu", tst[i].str, i); + + ATF_REQUIRE_STREQ(buf, res); + ATF_REQUIRE_EQ(r, e); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, in_print); + ATF_TP_ADD_TC(tp, sin_print); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/sys/netinet6/t_print.c b/contrib/netbsd-tests/sys/netinet6/t_print.c new file mode 100644 index 0000000..629c23f --- /dev/null +++ b/contrib/netbsd-tests/sys/netinet6/t_print.c @@ -0,0 +1,154 @@ +/* $NetBSD: t_print.c,v 1.2 2014/12/03 13:10:49 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_print.c,v 1.2 2014/12/03 13:10:49 christos Exp $"); + +#include "netinet6/in6_print.c" +#include "netinet/in_print.c" + +#include + +static const struct { + struct in6_addr ia; + const char *str; + int len; +} tst[] = { + { + IN6ADDR_ANY_INIT, + "::", + 2, + }, + { + IN6ADDR_LOOPBACK_INIT, + "::1", + 3, + }, + { + IN6ADDR_NODELOCAL_ALLNODES_INIT, + "ff01::1", + 7, + }, + { + {{{ 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }}}, + "1020:3040:5060:7080:102:304:506:708", + 35, + }, + { + {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x88, 0x44, 0x22, 0x11 }}}, + "::ffff:136.68.34.17", + 19, + }, +}; + + +ATF_TC(in6_print); +ATF_TC_HEAD(in6_print, tc) +{ + + atf_tc_set_md_var(tc, "descr", "printing of struct in6_addr"); +} + +ATF_TC_BODY(in6_print, tc) +{ + char buf[INET6_ADDRSTRLEN]; + int r; + size_t l = sizeof(buf); + + for (size_t i = 0; i < __arraycount(tst); i++) { + r = in6_print(buf, l, &tst[i].ia); + ATF_REQUIRE_STREQ(buf, tst[i].str); + ATF_REQUIRE_EQ(r, tst[i].len); + } + + l = 12; + for (size_t i = 0; i < __arraycount(tst); i++) { + r = in6_print(buf, l, &tst[i].ia); + ATF_CHECK(strncmp(buf, tst[i].str, l - 1) == 0); + if (r > (int)l) + ATF_REQUIRE_EQ(buf[l - 1], '\0'); + ATF_REQUIRE_EQ(r, tst[i].len); + } +} + +ATF_TC(sin6_print); +ATF_TC_HEAD(sin6_print, tc) +{ + + atf_tc_set_md_var(tc, "descr", "printing of sockaddr_in6"); +} + +ATF_TC_BODY(sin6_print, tc) +{ + char buf[1024]; + char res[1024]; + int r, e; + size_t l = sizeof(buf); + struct sockaddr_in6 sin6; + memset(&sin6, 0, sizeof(sin6)); + + for (size_t i = 0; i < __arraycount(tst); i++) { + sin6.sin6_addr = tst[i].ia; + sin6.sin6_port = (in_port_t)htons(i); + r = sin6_print(buf, l, &sin6); + if (i == 0) + e = snprintf(res, sizeof(res), "%s", tst[i].str); + else + e = snprintf(res, sizeof(res), "[%s]:%zu", + tst[i].str, i); + + ATF_REQUIRE_STREQ(buf, res); + ATF_REQUIRE_EQ(r, e); + } + + l = 14; + for (size_t i = 0; i < __arraycount(tst); i++) { + sin6.sin6_addr = tst[i].ia; + sin6.sin6_port = (in_port_t)htons(i); + r = sin6_print(buf, l, &sin6); + if (i == 0) + e = snprintf(res, l, "%s", tst[i].str); + else + e = snprintf(res, l, "[%s]:%zu", tst[i].str, i); + + ATF_REQUIRE_STREQ(buf, res); + ATF_REQUIRE_EQ(r, e); + } +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, in6_print); + ATF_TP_ADD_TC(tp, sin6_print); + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/sys/rc/h_args.sh b/contrib/netbsd-tests/sys/rc/h_args.sh new file mode 100755 index 0000000..2b03f29 --- /dev/null +++ b/contrib/netbsd-tests/sys/rc/h_args.sh @@ -0,0 +1,64 @@ +#! /bin/sh +# +# $NetBSD: h_args.sh,v 1.1 2010/03/15 19:03:08 jmmv Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Julio Merino. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# An rc.d script that overrides all standard comands and adds a non-standard +# command. All of them print the set of arguments passed to them and take no +# further action. +# + +${_rc_subr_loaded} . /etc/rc.subr + +name="h_args" +rcvar="${name}" +command="/usr/bin/true" +extra_commands="custom" + +for command in start stop restart custom; do + eval ${command}_precmd=\'print_args pre${command}\' + eval ${command}_cmd=\'print_args ${command}\' + eval ${command}_postcmd=\'print_args post${command}\' +done + +print_args() { + local command="${1}"; shift + + printf "${command}:" + while [ ${#} -gt 0 ]; do + printf " >%s<" "${1}" + shift + done + printf ".\n" +} + +load_rc_config "${name}" +run_rc_command "${@}" diff --git a/contrib/netbsd-tests/sys/rc/h_simple.sh b/contrib/netbsd-tests/sys/rc/h_simple.sh new file mode 100755 index 0000000..4ed62a7 --- /dev/null +++ b/contrib/netbsd-tests/sys/rc/h_simple.sh @@ -0,0 +1,45 @@ +#! /bin/sh +# +# $NetBSD: h_simple.sh,v 1.1 2010/03/15 19:03:08 jmmv Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Julio Merino. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# A very simple rc.d script that defines the minimum variables to be functional. +# + +${_rc_subr_loaded} . /etc/rc.subr + +name="h_simple" +rcvar="${name}" +command="/bin/sleep" +command_args="300 &" + +load_rc_config "${name}" +run_rc_command "${@}" diff --git a/contrib/netbsd-tests/sys/rc/t_rc_d_cli.sh b/contrib/netbsd-tests/sys/rc/t_rc_d_cli.sh new file mode 100755 index 0000000..d97f8cc --- /dev/null +++ b/contrib/netbsd-tests/sys/rc/t_rc_d_cli.sh @@ -0,0 +1,250 @@ +# $NetBSD: t_rc_d_cli.sh,v 1.4 2010/11/07 17:51:21 jmmv Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Julio Merino. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case no_command +no_command_head() { + atf_set "descr" "Tests that the lack of a command errors out" +} +no_command_body() { + export h_simple=YES + rc_helper=$(atf_get_srcdir)/h_simple + + atf_check -s eq:1 -o empty -e ignore ${rc_helper} +} + +atf_test_case default_start_no_args +default_start_no_args_head() { + atf_set "descr" "Tests that running the default 'start' without" \ + "arguments does not error out" +} +default_start_no_args_body() { + export h_simple=YES + rc_helper=$(atf_get_srcdir)/h_simple + + atf_check -s eq:0 -o ignore -e empty ${rc_helper} start + ${rc_helper} forcestop +} + +atf_test_case default_start_with_args +default_start_with_args_head() { + atf_set "descr" "Tests that running the default 'start' with" \ + "arguments errors out" +} +default_start_with_args_body() { + export h_simple=YES + rc_helper=$(atf_get_srcdir)/h_simple + + atf_check -s eq:1 -o ignore -e ignore ${rc_helper} start foo + if ${rc_helper} status >/dev/null; then + ${rc_helper} forcestop + atf_fail 'extra argument to start did not error out' + fi +} + +atf_test_case default_stop_no_args +default_stop_no_args_head() { + atf_set "descr" "Tests that running the default 'stop' without" \ + "arguments does not error out" +} +default_stop_no_args_body() { + export h_simple=YES + rc_helper=$(atf_get_srcdir)/h_simple + + ${rc_helper} start + atf_check -s eq:0 -o ignore -e empty ${rc_helper} stop +} + +atf_test_case default_stop_with_args +default_stop_with_args_head() { + atf_set "descr" "Tests that running the default 'stop' with" \ + "arguments errors out" +} +default_stop_with_args_body() { + export h_simple=YES + rc_helper=$(atf_get_srcdir)/h_simple + + ${rc_helper} start + atf_check -s eq:1 -o ignore -e ignore ${rc_helper} stop foo + if ${rc_helper} status >/dev/null; then + ${rc_helper} forcestop + else + atf_fail 'extra argument to stop did not error out' + fi +} + +atf_test_case default_restart_no_args +default_restart_no_args_head() { + atf_set "descr" "Tests that running the default 'restart' without" \ + "arguments does not error out" +} +default_restart_no_args_body() { + export h_simple=YES + rc_helper=$(atf_get_srcdir)/h_simple + + ${rc_helper} start + atf_check -s eq:0 -o ignore -e empty ${rc_helper} restart + ${rc_helper} forcestop +} + +atf_test_case default_restart_with_args +default_restart_with_args_head() { + atf_set "descr" "Tests that running the default 'restart' with" \ + "arguments errors out" +} +default_restart_with_args_body() { + export h_simple=YES + rc_helper=$(atf_get_srcdir)/h_simple + + ${rc_helper} start + atf_check -s eq:1 -o ignore -e ignore ${rc_helper} restart foo + ${rc_helper} forcestop +} + +do_overriden_no_args() { + local command="${1}"; shift + + export h_args=YES + rc_helper=$(atf_get_srcdir)/h_args + + cat >expout <expout <arg1< > arg 2 < >arg3< >*<. +post${command}:. +EOF + atf_check -s eq:0 -o file:expout -e empty ${rc_helper} ${command} \ + 'arg1' ' arg 2 ' 'arg3' '*' +} + +atf_test_case overriden_start_no_args +overriden_start_no_args_head() { + atf_set "descr" "Tests that running a custom 'start' without" \ + "arguments does not pass any parameters to the command" +} +overriden_start_no_args_body() { + do_overriden_no_args start +} + +atf_test_case overriden_start_with_args +overriden_start_with_args_head() { + atf_set "descr" "Tests that running a custom 'start' with" \ + "arguments passes those arguments as parameters to the command" +} +overriden_start_with_args_body() { + do_overriden_with_args start +} + +atf_test_case overriden_stop_no_args +overriden_stop_no_args_head() { + atf_set "descr" "Tests that running a custom 'stop' without" \ + "arguments does not pass any parameters to the command" +} +overriden_stop_no_args_body() { + do_overriden_no_args stop +} + +atf_test_case overriden_stop_with_args +overriden_stop_with_args_head() { + atf_set "descr" "Tests that running a custom 'stop' with" \ + "arguments passes those arguments as parameters to the command" +} +overriden_stop_with_args_body() { + do_overriden_with_args stop +} + +atf_test_case overriden_restart_no_args +overriden_restart_no_args_head() { + atf_set "descr" "Tests that running a custom 'restart' without" \ + "arguments does not pass any parameters to the command" +} +overriden_restart_no_args_body() { + do_overriden_no_args restart +} + +atf_test_case overriden_restart_with_args +overriden_restart_with_args_head() { + atf_set "descr" "Tests that running a custom 'restart' with" \ + "arguments passes those arguments as parameters to the command" +} +overriden_restart_with_args_body() { + do_overriden_with_args restart +} + +atf_test_case overriden_custom_no_args +overriden_custom_no_args_head() { + atf_set "descr" "Tests that running a custom command without" \ + "arguments does not pass any parameters to the command" +} +overriden_custom_no_args_body() { + do_overriden_no_args custom +} + +atf_test_case overriden_custom_with_args +overriden_custom_with_args_head() { + atf_set "descr" "Tests that running a custom command with" \ + "arguments passes those arguments as parameters to the command" +} +overriden_custom_with_args_body() { + do_overriden_with_args custom +} + +atf_init_test_cases() +{ + atf_add_test_case no_command + + atf_add_test_case default_start_no_args + atf_add_test_case default_start_with_args + atf_add_test_case default_stop_no_args + atf_add_test_case default_stop_with_args + atf_add_test_case default_restart_no_args + atf_add_test_case default_restart_with_args + + atf_add_test_case overriden_start_no_args + atf_add_test_case overriden_start_with_args + atf_add_test_case overriden_stop_no_args + atf_add_test_case overriden_stop_with_args + atf_add_test_case overriden_restart_no_args + atf_add_test_case overriden_restart_with_args + atf_add_test_case overriden_custom_no_args + atf_add_test_case overriden_custom_with_args +} diff --git a/contrib/netbsd-tests/sys/uvm/t_uvm_physseg.c b/contrib/netbsd-tests/sys/uvm/t_uvm_physseg.c new file mode 100644 index 0000000..a5f2fa9 --- /dev/null +++ b/contrib/netbsd-tests/sys/uvm/t_uvm_physseg.c @@ -0,0 +1,2377 @@ +/* $NetBSD: t_uvm_physseg.c,v 1.2 2016/12/22 08:15:20 cherry Exp $ */ + +/*- + * Copyright (c) 2015, 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Santhosh N. Raju and + * by Cherry G. Mathew + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_uvm_physseg.c,v 1.2 2016/12/22 08:15:20 cherry Exp $"); + +/* + * If this line is commented out tests related to uvm_physseg_get_pmseg() + * wont run. + * + * Have a look at machine/uvm_physseg.h for more details. + */ +#define __HAVE_PMAP_PHYSSEG + +/* + * This is a dummy struct used for testing purposes + * + * In reality this struct would exist in the MD part of the code residing in + * machines/vmparam.h + */ + +#ifdef __HAVE_PMAP_PHYSSEG +struct pmap_physseg { + int dummy_variable; /* Dummy variable use for testing */ +}; +#endif + +/* Testing API - assumes userland */ +/* Provide Kernel API equivalents */ +#include +#include +#include +#include /* memset(3) et. al */ +#include /* printf(3) */ +#include /* malloc(3) */ +#include +#include + +#define PRIxPADDR "lx" +#define PRIxPSIZE "lx" +#define PRIuPSIZE "lu" +#define PRIxVADDR "lx" +#define PRIxVSIZE "lx" +#define PRIuVSIZE "lu" + +#define UVM_HOTPLUG /* Enable hotplug with rbtree. */ +#define PMAP_STEAL_MEMORY +#define DEBUG /* Enable debug functionality. */ + +typedef unsigned long vaddr_t; +typedef unsigned long paddr_t; +typedef unsigned long psize_t; +typedef unsigned long vsize_t; + +#include +#include + +#ifndef DIAGNOSTIC +#define KASSERTMSG(e, msg, ...) /* NOTHING */ +#define KASSERT(e) /* NOTHING */ +#else +#define KASSERT(a) assert(a) +#define KASSERTMSG(exp, ...) printf(__VA_ARGS__); assert((exp)) +#endif + +#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH + +#define VM_NFREELIST 4 +#define VM_FREELIST_DEFAULT 0 +#define VM_FREELIST_FIRST16 3 +#define VM_FREELIST_FIRST1G 2 +#define VM_FREELIST_FIRST4G 1 + +/* + * Used in tests when Array implementation is tested + */ +#if !defined(VM_PHYSSEG_MAX) +#define VM_PHYSSEG_MAX 1 +#endif + +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1 << PAGE_SHIFT) +#define PAGE_MASK (PAGE_SIZE - 1) +#define atop(x) (((paddr_t)(x)) >> PAGE_SHIFT) +#define ptoa(x) (((paddr_t)(x)) << PAGE_SHIFT) + +#define mutex_enter(l) +#define mutex_exit(l) + +psize_t physmem; + +struct uvmexp uvmexp; /* decl */ + +/* + * uvm structure borrowed from uvm.h + * + * Remember this is a dummy structure used within the ATF Tests and + * uses only necessary fields from the original uvm struct. + * See uvm/uvm.h for the full struct. + */ + +struct uvm { + /* vm_page related parameters */ + + bool page_init_done; /* TRUE if uvm_page_init() finished */ +} uvm; + +#include + +void * +kmem_alloc(size_t size, km_flag_t flags) +{ + return malloc(size); +} + +void * +kmem_zalloc(size_t size, km_flag_t flags) +{ + void *ptr; + ptr = malloc(size); + + memset(ptr, 0, size); + + return ptr; +} + +void +kmem_free(void *mem, size_t size) +{ + free(mem); +} + +static void +panic(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vprintf(fmt, ap); + printf("\n"); + va_end(ap); + KASSERT(false); + + /*NOTREACHED*/ +} + +static void +uvm_pagefree(struct vm_page *pg) +{ + return; +} + +#if defined(UVM_HOTPLUG) +static void +uvmpdpol_reinit(void) +{ + return; +} +#endif /* UVM_HOTPLUG */ + +/* end - Provide Kernel API equivalents */ + + +#include "uvm/uvm_physseg.c" + +#include + +#define SIXTYFOUR_KILO (64 * 1024) +#define ONETWENTYEIGHT_KILO (128 * 1024) +#define TWOFIFTYSIX_KILO (256 * 1024) +#define FIVEONETWO_KILO (512 * 1024) +#define ONE_MEGABYTE (1024 * 1024) +#define TWO_MEGABYTE (2 * 1024 * 1024) + +/* Sample Page Frame Numbers */ +#define VALID_START_PFN_1 atop(0) +#define VALID_END_PFN_1 atop(ONE_MEGABYTE) +#define VALID_AVAIL_START_PFN_1 atop(0) +#define VALID_AVAIL_END_PFN_1 atop(ONE_MEGABYTE) + +#define VALID_START_PFN_2 atop(ONE_MEGABYTE + 1) +#define VALID_END_PFN_2 atop(ONE_MEGABYTE * 2) +#define VALID_AVAIL_START_PFN_2 atop(ONE_MEGABYTE + 1) +#define VALID_AVAIL_END_PFN_2 atop(ONE_MEGABYTE * 2) + +#define VALID_START_PFN_3 atop((ONE_MEGABYTE * 2) + 1) +#define VALID_END_PFN_3 atop(ONE_MEGABYTE * 3) +#define VALID_AVAIL_START_PFN_3 atop((ONE_MEGABYTE * 2) + 1) +#define VALID_AVAIL_END_PFN_3 atop(ONE_MEGABYTE * 3) + +#define VALID_START_PFN_4 atop((ONE_MEGABYTE * 3) + 1) +#define VALID_END_PFN_4 atop(ONE_MEGABYTE * 4) +#define VALID_AVAIL_START_PFN_4 atop((ONE_MEGABYTE * 3) + 1) +#define VALID_AVAIL_END_PFN_4 atop(ONE_MEGABYTE * 4) + +/* + * Total number of pages (of 4K size each) should be 256 for 1MB of memory. + */ +#define PAGE_COUNT_1M 256 + +/* + * A debug fucntion to print the content of upm. + */ + static inline void + uvm_physseg_dump_seg(uvm_physseg_t upm) + { +#if defined(DEBUG) + printf("%s: seg->start == %ld\n", __func__, + uvm_physseg_get_start(upm)); + printf("%s: seg->end == %ld\n", __func__, + uvm_physseg_get_end(upm)); + printf("%s: seg->avail_start == %ld\n", __func__, + uvm_physseg_get_avail_start(upm)); + printf("%s: seg->avail_end == %ld\n", __func__, + uvm_physseg_get_avail_end(upm)); + + printf("====\n\n"); +#else + return; +#endif /* DEBUG */ + } + +/* + * Private accessor that gets the value of uvm_physseg_graph.nentries + */ +static int +uvm_physseg_get_entries(void) +{ +#if defined(UVM_HOTPLUG) + return uvm_physseg_graph.nentries; +#else + return vm_nphysmem; +#endif /* UVM_HOTPLUG */ +} + +#if !defined(UVM_HOTPLUG) +static void * +uvm_physseg_alloc(size_t sz) +{ + return &vm_physmem[vm_nphysseg++]; +} +#endif + +/* + * Test Fixture SetUp(). + */ +static void +setup(void) +{ + /* Prerequisites for running certain calls in uvm_physseg */ + uvmexp.pagesize = PAGE_SIZE; + uvmexp.npages = 0; + uvm.page_init_done = false; + uvm_physseg_init(); +} + + +/* <---- Tests for Internal functions ----> */ +#if defined(UVM_HOTPLUG) +ATF_TC(uvm_physseg_alloc_atboot_mismatch); +ATF_TC_HEAD(uvm_physseg_alloc_atboot_mismatch, tc) +{ + atf_tc_set_md_var(tc, "descr", "boot time uvm_physseg_alloc() sanity" + "size mismatch alloc() test."); +} + +ATF_TC_BODY(uvm_physseg_alloc_atboot_mismatch, tc) +{ + uvm.page_init_done = false; + + atf_tc_expect_signal(SIGABRT, "size mismatch alloc()"); + + uvm_physseg_alloc(sizeof(struct uvm_physseg) - 1); +} + +ATF_TC(uvm_physseg_alloc_atboot_overrun); +ATF_TC_HEAD(uvm_physseg_alloc_atboot_overrun, tc) +{ + atf_tc_set_md_var(tc, "descr", "boot time uvm_physseg_alloc() sanity" + "array overrun alloc() test."); +} + +ATF_TC_BODY(uvm_physseg_alloc_atboot_overrun, tc) +{ + uvm.page_init_done = false; + + atf_tc_expect_signal(SIGABRT, "array overrun alloc()"); + + uvm_physseg_alloc((VM_PHYSSEG_MAX + 1) * sizeof(struct uvm_physseg)); + +} + +ATF_TC(uvm_physseg_alloc_sanity); +ATF_TC_HEAD(uvm_physseg_alloc_sanity, tc) +{ + atf_tc_set_md_var(tc, "descr", "further uvm_physseg_alloc() sanity checks"); +} + +ATF_TC_BODY(uvm_physseg_alloc_sanity, tc) +{ + + /* At boot time */ + uvm.page_init_done = false; + + /* Correct alloc */ + ATF_REQUIRE(uvm_physseg_alloc(VM_PHYSSEG_MAX * sizeof(struct uvm_physseg))); + + /* Retry static alloc()s as dynamic - we expect them to pass */ + uvm.page_init_done = true; + ATF_REQUIRE(uvm_physseg_alloc(sizeof(struct uvm_physseg) - 1)); + ATF_REQUIRE(uvm_physseg_alloc(2 * VM_PHYSSEG_MAX * sizeof(struct uvm_physseg))); +} + +ATF_TC(uvm_physseg_free_atboot_mismatch); +ATF_TC_HEAD(uvm_physseg_free_atboot_mismatch, tc) +{ + atf_tc_set_md_var(tc, "descr", "boot time uvm_physseg_free() sanity" + "size mismatch free() test."); +} + +ATF_TC_BODY(uvm_physseg_free_atboot_mismatch, tc) +{ + uvm.page_init_done = false; + + atf_tc_expect_signal(SIGABRT, "size mismatch free()"); + + uvm_physseg_free(&uvm_physseg[0], sizeof(struct uvm_physseg) - 1); +} + +ATF_TC(uvm_physseg_free_sanity); +ATF_TC_HEAD(uvm_physseg_free_sanity, tc) +{ + atf_tc_set_md_var(tc, "descr", "further uvm_physseg_free() sanity checks"); +} + +ATF_TC_BODY(uvm_physseg_free_sanity, tc) +{ + + /* At boot time */ + uvm.page_init_done = false; + + struct uvm_physseg *seg; + +#if VM_PHYSSEG_MAX > 1 + /* + * Note: free()ing the entire array is considered to be an + * error. Thus VM_PHYSSEG_MAX - 1. + */ + + seg = uvm_physseg_alloc((VM_PHYSSEG_MAX - 1) * sizeof(*seg)); + uvm_physseg_free(seg, (VM_PHYSSEG_MAX - 1) * sizeof(struct uvm_physseg)); +#endif + + /* Retry static alloc()s as dynamic - we expect them to pass */ + uvm.page_init_done = true; + + seg = uvm_physseg_alloc(sizeof(struct uvm_physseg) - 1); + uvm_physseg_free(seg, sizeof(struct uvm_physseg) - 1); + + seg = uvm_physseg_alloc(2 * VM_PHYSSEG_MAX * sizeof(struct uvm_physseg)); + + uvm_physseg_free(seg, 2 * VM_PHYSSEG_MAX * sizeof(struct uvm_physseg)); +} + +#if VM_PHYSSEG_MAX > 1 +ATF_TC(uvm_physseg_atboot_free_leak); +ATF_TC_HEAD(uvm_physseg_atboot_free_leak, tc) +{ + atf_tc_set_md_var(tc, "descr", + "does free() leak at boot ?\n" + "This test needs VM_PHYSSEG_MAX > 1)"); +} + +ATF_TC_BODY(uvm_physseg_atboot_free_leak, tc) +{ + + /* At boot time */ + uvm.page_init_done = false; + + /* alloc to array size */ + struct uvm_physseg *seg; + seg = uvm_physseg_alloc(VM_PHYSSEG_MAX * sizeof(*seg)); + + uvm_physseg_free(seg, sizeof(*seg)); + + atf_tc_expect_signal(SIGABRT, "array overrun on alloc() after leak"); + + ATF_REQUIRE(uvm_physseg_alloc(sizeof(struct uvm_physseg))); +} +#endif /* VM_PHYSSEG_MAX */ +#endif /* UVM_HOTPLUG */ + +/* + * Note: This function replicates verbatim what happens in + * uvm_page.c:uvm_page_init(). + * + * Please track any changes that happen there. + */ +static void +uvm_page_init_fake(struct vm_page *pagearray, psize_t pagecount) +{ + uvm_physseg_t bank; + size_t n; + + for (bank = uvm_physseg_get_first(), + uvm_physseg_seg_chomp_slab(bank, pagearray, pagecount); + uvm_physseg_valid_p(bank); + bank = uvm_physseg_get_next(bank)) { + + n = uvm_physseg_get_end(bank) - uvm_physseg_get_start(bank); + uvm_physseg_seg_alloc_from_slab(bank, n); + uvm_physseg_init_seg(bank, pagearray); + + /* set up page array pointers */ + pagearray += n; + pagecount -= n; + } + + uvm.page_init_done = true; +} + +ATF_TC(uvm_physseg_plug); +ATF_TC_HEAD(uvm_physseg_plug, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test plug functionality."); +} +/* Note: We only do the second boot time plug if VM_PHYSSEG_MAX > 1 */ +ATF_TC_BODY(uvm_physseg_plug, tc) +{ + int nentries = 0; /* Count of entries via plug done so far */ + uvm_physseg_t upm1; +#if VM_PHYSSEG_MAX > 2 + uvm_physseg_t upm2; +#endif + +#if VM_PHYSSEG_MAX > 1 + uvm_physseg_t upm3; +#endif + uvm_physseg_t upm4; + psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); + psize_t npages2 = (VALID_END_PFN_2 - VALID_START_PFN_2); + psize_t npages3 = (VALID_END_PFN_3 - VALID_START_PFN_3); + psize_t npages4 = (VALID_END_PFN_4 - VALID_START_PFN_4); + struct vm_page *pgs, *slab = malloc(sizeof(struct vm_page) * (npages1 +#if VM_PHYSSEG_MAX > 2 + + npages2 +#endif + + npages3)); + + /* Fake early boot */ + + setup(); + + /* Vanilla plug x 2 */ + ATF_REQUIRE_EQ(uvm_physseg_plug(VALID_START_PFN_1, npages1, &upm1), true); + ATF_REQUIRE_EQ(++nentries, uvm_physseg_get_entries()); + ATF_REQUIRE_EQ(0, uvmexp.npages); + +#if VM_PHYSSEG_MAX > 2 + ATF_REQUIRE_EQ(uvm_physseg_plug(VALID_START_PFN_2, npages2, &upm2), true); + ATF_REQUIRE_EQ(++nentries, uvm_physseg_get_entries()); + ATF_REQUIRE_EQ(0, uvmexp.npages); +#endif + /* Post boot: Fake all segments and pages accounted for. */ + uvm_page_init_fake(slab, npages1 + npages2 + npages3); + + ATF_CHECK_EQ(npages1 +#if VM_PHYSSEG_MAX > 2 + + npages2 +#endif + , uvmexp.npages); +#if VM_PHYSSEG_MAX > 1 + /* Scavenge plug - goes into the same slab */ + ATF_REQUIRE_EQ(uvm_physseg_plug(VALID_START_PFN_3, npages3, &upm3), true); + ATF_REQUIRE_EQ(++nentries, uvm_physseg_get_entries()); + ATF_REQUIRE_EQ(npages1 +#if VM_PHYSSEG_MAX > 2 + + npages2 +#endif + + npages3, uvmexp.npages); + + /* Scavenge plug should fit right in the slab */ + pgs = uvm_physseg_get_pg(upm3, 0); + ATF_REQUIRE(pgs > slab && pgs < (slab + npages1 + npages2 + npages3)); +#endif + /* Hot plug - goes into a brand new slab */ + ATF_REQUIRE_EQ(uvm_physseg_plug(VALID_START_PFN_4, npages4, &upm4), true); + /* The hot plug slab should have nothing to do with the original slab */ + pgs = uvm_physseg_get_pg(upm4, 0); + ATF_REQUIRE(pgs < slab || pgs > (slab + npages1 +#if VM_PHYSSEG_MAX > 2 + + npages2 +#endif + + npages3)); + +} +ATF_TC(uvm_physseg_unplug); +ATF_TC_HEAD(uvm_physseg_unplug, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test unplug functionality."); +} +ATF_TC_BODY(uvm_physseg_unplug, tc) +{ + paddr_t pa = 0; + + psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); + psize_t npages2 = (VALID_END_PFN_2 - VALID_START_PFN_2); + psize_t npages3 = (VALID_END_PFN_3 - VALID_START_PFN_3); + + struct vm_page *slab = malloc(sizeof(struct vm_page) * (npages1 + npages2 + npages3)); + + uvm_physseg_t upm; + + /* Boot time */ + setup(); + + /* We start with zero segments */ + ATF_REQUIRE_EQ(true, uvm_physseg_plug(atop(0), atop(ONE_MEGABYTE), NULL)); + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + /* Do we have an arbitrary offset in there ? */ + uvm_physseg_find(atop(TWOFIFTYSIX_KILO), &pa); + ATF_REQUIRE_EQ(pa, atop(TWOFIFTYSIX_KILO)); + ATF_REQUIRE_EQ(0, uvmexp.npages); /* Boot time sanity */ + +#if VM_PHYSSEG_MAX == 1 + /* + * This is the curious case at boot time, of having one + * extent(9) static entry per segment, which means that a + * fragmenting unplug will fail. + */ + atf_tc_expect_signal(SIGABRT, "fragmenting unplug for single segment"); + + /* + * In order to test the fragmenting cases, please set + * VM_PHYSSEG_MAX > 1 + */ +#endif + /* Now let's unplug from the middle */ + ATF_REQUIRE_EQ(true, uvm_physseg_unplug(atop(TWOFIFTYSIX_KILO), atop(FIVEONETWO_KILO))); + /* verify that a gap exists at TWOFIFTYSIX_KILO */ + pa = 0; /* reset */ + uvm_physseg_find(atop(TWOFIFTYSIX_KILO), &pa); + ATF_REQUIRE_EQ(pa, 0); + + /* Post boot: Fake all segments and pages accounted for. */ + uvm_page_init_fake(slab, npages1 + npages2 + npages3); + /* Account for the unplug */ + ATF_CHECK_EQ(atop(FIVEONETWO_KILO), uvmexp.npages); + + /* Original entry should fragment into two */ + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + upm = uvm_physseg_find(atop(TWOFIFTYSIX_KILO + FIVEONETWO_KILO), NULL); + + ATF_REQUIRE(uvm_physseg_valid_p(upm)); + + /* Now unplug the tail fragment - should swallow the complete entry */ + ATF_REQUIRE_EQ(true, uvm_physseg_unplug(atop(TWOFIFTYSIX_KILO + FIVEONETWO_KILO), atop(TWOFIFTYSIX_KILO))); + + /* The "swallow" above should have invalidated the handle */ + ATF_REQUIRE_EQ(false, uvm_physseg_valid_p(upm)); + + /* Only the first one is left now */ + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + /* Unplug from the back */ + ATF_REQUIRE_EQ(true, uvm_physseg_unplug(atop(ONETWENTYEIGHT_KILO), atop(ONETWENTYEIGHT_KILO))); + /* Shouldn't change the number of segments */ + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + /* Unplug from the front */ + ATF_REQUIRE_EQ(true, uvm_physseg_unplug(0, atop(SIXTYFOUR_KILO))); + /* Shouldn't change the number of segments */ + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + /* Unplugging the final fragment should fail */ + atf_tc_expect_signal(SIGABRT, "Unplugging the last segment"); + ATF_REQUIRE_EQ(true, uvm_physseg_unplug(atop(SIXTYFOUR_KILO), atop(SIXTYFOUR_KILO))); +} + + +/* <---- end Tests for Internal functions ----> */ + +/* Tests for functions exported via uvm_physseg.h */ +ATF_TC(uvm_physseg_init); +ATF_TC_HEAD(uvm_physseg_init, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_init() call\ + initializes the vm_physmem struct which holds the rb_tree."); +} +ATF_TC_BODY(uvm_physseg_init, tc) +{ + uvm_physseg_init(); + + ATF_REQUIRE_EQ(0, uvm_physseg_get_entries()); +} + +ATF_TC(uvm_page_physload_preload); +ATF_TC_HEAD(uvm_page_physload_preload, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physload() \ + call works without a panic() in a preload scenario."); +} +ATF_TC_BODY(uvm_page_physload_preload, tc) +{ + uvm_physseg_t upm; + + setup(); + + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + /* Should return a valid handle */ + ATF_REQUIRE(uvm_physseg_valid_p(upm)); + + /* No pages should be allocated yet */ + ATF_REQUIRE_EQ(0, uvmexp.npages); + + /* After the first call one segment should exist */ + ATF_CHECK_EQ(1, uvm_physseg_get_entries()); + + /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */ +#if VM_PHYSSEG_MAX > 1 + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + /* Should return a valid handle */ + ATF_REQUIRE(uvm_physseg_valid_p(upm)); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + /* After the second call two segments should exist */ + ATF_CHECK_EQ(2, uvm_physseg_get_entries()); +#endif +} + +ATF_TC(uvm_page_physload_postboot); +ATF_TC_HEAD(uvm_page_physload_postboot, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physload() \ + panic()s in a post boot scenario."); +} +ATF_TC_BODY(uvm_page_physload_postboot, tc) +{ + uvm_physseg_t upm; + + psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); + psize_t npages2 = (VALID_END_PFN_2 - VALID_START_PFN_2); + + struct vm_page *slab = malloc(sizeof(struct vm_page) * (npages1 + npages2)); + + setup(); + + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + /* Should return a valid handle */ + ATF_REQUIRE(uvm_physseg_valid_p(upm)); + + /* No pages should be allocated yet */ + ATF_REQUIRE_EQ(0, uvmexp.npages); + + /* After the first call one segment should exist */ + ATF_CHECK_EQ(1, uvm_physseg_get_entries()); + + /* Post boot: Fake all segments and pages accounted for. */ + uvm_page_init_fake(slab, npages1 + npages2); + + atf_tc_expect_signal(SIGABRT, + "uvm_page_physload() called post boot"); + + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + /* Should return a valid handle */ + ATF_REQUIRE(uvm_physseg_valid_p(upm)); + + ATF_REQUIRE_EQ(npages1 + npages2, uvmexp.npages); + + /* After the second call two segments should exist */ + ATF_CHECK_EQ(2, uvm_physseg_get_entries()); +} + +ATF_TC(uvm_physseg_handle_immutable); +ATF_TC_HEAD(uvm_physseg_handle_immutable, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the uvm_physseg_t handle is \ + immutable."); +} +ATF_TC_BODY(uvm_physseg_handle_immutable, tc) +{ + uvm_physseg_t upm; + + /* We insert the segments in out of order */ + + setup(); + + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID_EMPTY, uvm_physseg_get_prev(upm)); + + /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */ +#if VM_PHYSSEG_MAX > 1 + uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + /* Fetch Previous, we inserted a lower value */ + upm = uvm_physseg_get_prev(upm); + +#if !defined(UVM_HOTPLUG) + /* + * This test is going to fail for the Array Implementation but is + * expected to pass in the RB Tree implementation. + */ + /* Failure can be expected iff there are more than one handles */ + atf_tc_expect_fail("Mutable handle in static array impl."); +#endif + ATF_CHECK(UVM_PHYSSEG_TYPE_INVALID_EMPTY != upm); + ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm)); +#endif +} + +ATF_TC(uvm_physseg_seg_chomp_slab); +ATF_TC_HEAD(uvm_physseg_seg_chomp_slab, tc) +{ + atf_tc_set_md_var(tc, "descr", "The slab import code.()"); + +} +ATF_TC_BODY(uvm_physseg_seg_chomp_slab, tc) +{ + int err; + size_t i; + struct uvm_physseg *seg; + struct vm_page *slab, *pgs; + const size_t npages = UVM_PHYSSEG_BOOT_UNPLUG_MAX; /* Number of pages */ + + setup(); + + /* This is boot time */ + slab = malloc(sizeof(struct vm_page) * npages * 2); + + seg = uvm_physseg_alloc(sizeof(struct uvm_physseg)); + + uvm_physseg_seg_chomp_slab(PHYSSEG_NODE_TO_HANDLE(seg), slab, npages * 2); + + /* Should be able to allocate two 128 * sizeof(*slab) */ + ATF_REQUIRE_EQ(0, extent_alloc(seg->ext, sizeof(*slab), 1, 0, EX_BOUNDZERO, (void *)&pgs)); + err = extent_free(seg->ext, (u_long) pgs, sizeof(*slab), EX_BOUNDZERO); + +#if VM_PHYSSEG_MAX == 1 + /* + * free() needs an extra region descriptor, but we only have + * one! The classic alloc() at free() problem + */ + + ATF_REQUIRE_EQ(ENOMEM, err); +#else + /* Try alloc/free at static time */ + for (i = 0; i < npages; i++) { + ATF_REQUIRE_EQ(0, extent_alloc(seg->ext, sizeof(*slab), 1, 0, EX_BOUNDZERO, (void *)&pgs)); + err = extent_free(seg->ext, (u_long) pgs, sizeof(*slab), EX_BOUNDZERO); + ATF_REQUIRE_EQ(0, err); + } +#endif + + /* Now setup post boot */ + uvm.page_init_done = true; + + uvm_physseg_seg_chomp_slab(PHYSSEG_NODE_TO_HANDLE(seg), slab, npages * 2); + + /* Try alloc/free after uvm_page.c:uvm_page_init() as well */ + for (i = 0; i < npages; i++) { + ATF_REQUIRE_EQ(0, extent_alloc(seg->ext, sizeof(*slab), 1, 0, EX_BOUNDZERO, (void *)&pgs)); + err = extent_free(seg->ext, (u_long) pgs, sizeof(*slab), EX_BOUNDZERO); + ATF_REQUIRE_EQ(0, err); + } + +} + +ATF_TC(uvm_physseg_alloc_from_slab); +ATF_TC_HEAD(uvm_physseg_alloc_from_slab, tc) +{ + atf_tc_set_md_var(tc, "descr", "The slab alloc code.()"); + +} +ATF_TC_BODY(uvm_physseg_alloc_from_slab, tc) +{ + struct uvm_physseg *seg; + struct vm_page *slab, *pgs; + const size_t npages = UVM_PHYSSEG_BOOT_UNPLUG_MAX; /* Number of pages */ + + setup(); + + /* This is boot time */ + slab = malloc(sizeof(struct vm_page) * npages * 2); + + seg = uvm_physseg_alloc(sizeof(struct uvm_physseg)); + + uvm_physseg_seg_chomp_slab(PHYSSEG_NODE_TO_HANDLE(seg), slab, npages * 2); + + pgs = uvm_physseg_seg_alloc_from_slab(PHYSSEG_NODE_TO_HANDLE(seg), npages); + + ATF_REQUIRE(pgs != NULL); + + /* Now setup post boot */ + uvm.page_init_done = true; + +#if VM_PHYSSEG_MAX > 1 + pgs = uvm_physseg_seg_alloc_from_slab(PHYSSEG_NODE_TO_HANDLE(seg), npages); + ATF_REQUIRE(pgs != NULL); +#endif + atf_tc_expect_fail("alloc beyond extent"); + + pgs = uvm_physseg_seg_alloc_from_slab(PHYSSEG_NODE_TO_HANDLE(seg), npages); + ATF_REQUIRE(pgs != NULL); +} + +ATF_TC(uvm_physseg_init_seg); +ATF_TC_HEAD(uvm_physseg_init_seg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if uvm_physseg_init_seg adds pages to" + "uvmexp.npages"); +} +ATF_TC_BODY(uvm_physseg_init_seg, tc) +{ + struct uvm_physseg *seg; + struct vm_page *slab, *pgs; + const size_t npages = UVM_PHYSSEG_BOOT_UNPLUG_MAX; /* Number of pages */ + + setup(); + + /* This is boot time */ + slab = malloc(sizeof(struct vm_page) * npages * 2); + + seg = uvm_physseg_alloc(sizeof(struct uvm_physseg)); + + uvm_physseg_seg_chomp_slab(PHYSSEG_NODE_TO_HANDLE(seg), slab, npages * 2); + + pgs = uvm_physseg_seg_alloc_from_slab(PHYSSEG_NODE_TO_HANDLE(seg), npages); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + seg->start = 0; + seg->end = npages; + + seg->avail_start = 0; + seg->avail_end = npages; + + uvm_physseg_init_seg(PHYSSEG_NODE_TO_HANDLE(seg), pgs); + + ATF_REQUIRE_EQ(npages, uvmexp.npages); +} + +#if 0 +ATF_TC(uvm_physseg_init_seg); +ATF_TC_HEAD(uvm_physseg_init_seg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physload() \ + call works without a panic() after Segment is inited."); +} +ATF_TC_BODY(uvm_physseg_init_seg, tc) +{ + uvm_physseg_t upm; + psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1); + struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_CHECK_EQ(0, uvmexp.npages); + + /* + * Boot time physplug needs explicit external init, + * Duplicate what uvm_page.c:uvm_page_init() does. + * Note: not everything uvm_page_init() does gets done here. + * Read the source. + */ + /* suck in backing slab, initialise extent. */ + uvm_physseg_seg_chomp_slab(upm, pgs, npages); + + /* + * Actual pgs[] allocation, from extent. + */ + uvm_physseg_alloc_from_slab(upm, npages); + + /* Now we initialize the segment */ + uvm_physseg_init_seg(upm, pgs); + + /* Done with boot simulation */ + extent_init(); + uvm.page_init_done = true; + + /* We have total memory of 1MB */ + ATF_CHECK_EQ(PAGE_COUNT_1M, uvmexp.npages); + + upm =uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + /* We added another 1MB so PAGE_COUNT_1M + PAGE_COUNT_1M */ + ATF_CHECK_EQ(PAGE_COUNT_1M + PAGE_COUNT_1M, uvmexp.npages); + +} +#endif + +ATF_TC(uvm_physseg_get_start); +ATF_TC_HEAD(uvm_physseg_get_start, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the start PFN is returned \ + correctly from a segment created via uvm_page_physload()."); +} +ATF_TC_BODY(uvm_physseg_get_start, tc) +{ + uvm_physseg_t upm; + + /* Fake early boot */ + setup(); + + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm)); + + /* This test will be triggered only if there are 2 or more segments. */ +#if VM_PHYSSEG_MAX > 1 + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); +#endif +} + +ATF_TC(uvm_physseg_get_start_invalid); +ATF_TC_HEAD(uvm_physseg_get_start_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \ + correctly when uvm_physseg_get_start() is called with invalid \ + parameter values."); +} +ATF_TC_BODY(uvm_physseg_get_start_invalid, tc) +{ + /* Check for pgs == NULL */ + setup(); + uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + /* Force other check conditions */ + uvm.page_init_done = true; + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(true, uvm.page_init_done); + + /* Invalid uvm_physseg_t */ + ATF_CHECK_EQ((paddr_t) -1, + uvm_physseg_get_start(UVM_PHYSSEG_TYPE_INVALID)); +} + +ATF_TC(uvm_physseg_get_end); +ATF_TC_HEAD(uvm_physseg_get_end, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the end PFN is returned \ + correctly from a segment created via uvm_page_physload()."); +} +ATF_TC_BODY(uvm_physseg_get_end, tc) +{ + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm)); + + /* This test will be triggered only if there are 2 or more segments. */ +#if VM_PHYSSEG_MAX > 1 + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); +#endif +} + +ATF_TC(uvm_physseg_get_end_invalid); +ATF_TC_HEAD(uvm_physseg_get_end_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \ + correctly when uvm_physseg_get_end() is called with invalid \ + parameter values."); +} +ATF_TC_BODY(uvm_physseg_get_end_invalid, tc) +{ + /* Check for pgs == NULL */ + setup(); + uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + /* Force other check conditions */ + uvm.page_init_done = true; + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(true, uvm.page_init_done); + + /* Invalid uvm_physseg_t */ + ATF_CHECK_EQ((paddr_t) -1, + uvm_physseg_get_end(UVM_PHYSSEG_TYPE_INVALID)); +} + +ATF_TC(uvm_physseg_get_avail_start); +ATF_TC_HEAD(uvm_physseg_get_avail_start, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the avail_start PFN is \ + returned correctly from a segment created via uvm_page_physload()."); +} +ATF_TC_BODY(uvm_physseg_get_avail_start, tc) +{ + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_1, uvm_physseg_get_avail_start(upm)); + + /* This test will be triggered only if there are 2 or more segments. */ +#if VM_PHYSSEG_MAX > 1 + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm)); +#endif +} + +ATF_TC(uvm_physseg_get_avail_start_invalid); +ATF_TC_HEAD(uvm_physseg_get_avail_start_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \ + correctly when uvm_physseg_get_avail_start() is called with invalid\ + parameter values."); +} +ATF_TC_BODY(uvm_physseg_get_avail_start_invalid, tc) +{ + /* Check for pgs == NULL */ + setup(); + uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + /* Force other check conditions */ + uvm.page_init_done = true; + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(true, uvm.page_init_done); + + /* Invalid uvm_physseg_t */ + ATF_CHECK_EQ((paddr_t) -1, + uvm_physseg_get_avail_start(UVM_PHYSSEG_TYPE_INVALID)); +} + +ATF_TC(uvm_physseg_get_avail_end); +ATF_TC_HEAD(uvm_physseg_get_avail_end, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the avail_end PFN is \ + returned correctly from a segment created via uvm_page_physload()."); +} +ATF_TC_BODY(uvm_physseg_get_avail_end, tc) +{ + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1, uvm_physseg_get_avail_end(upm)); + + /* This test will be triggered only if there are 2 or more segments. */ +#if VM_PHYSSEG_MAX > 1 + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm)); +#endif +} + +ATF_TC(uvm_physseg_get_avail_end_invalid); +ATF_TC_HEAD(uvm_physseg_get_avail_end_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \ + correctly when uvm_physseg_get_avail_end() is called with invalid\ + parameter values."); +} +ATF_TC_BODY(uvm_physseg_get_avail_end_invalid, tc) +{ + /* Check for pgs == NULL */ + setup(); + uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + /* Force other check conditions */ + uvm.page_init_done = true; + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(true, uvm.page_init_done); + + /* Invalid uvm_physseg_t */ + ATF_CHECK_EQ((paddr_t) -1, + uvm_physseg_get_avail_end(UVM_PHYSSEG_TYPE_INVALID)); +} + +ATF_TC(uvm_physseg_get_next); +ATF_TC_HEAD(uvm_physseg_get_next, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the pointer values for next \ + segment using the uvm_physseg_get_next() call."); +} +ATF_TC_BODY(uvm_physseg_get_next, tc) +{ + uvm_physseg_t upm; +#if VM_PHYSSEG_MAX > 1 + uvm_physseg_t upm_next; +#endif + + /* We insert the segments in ascending order */ + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID_OVERFLOW, + uvm_physseg_get_next(upm)); + + /* This test will be triggered only if there are 2 or more segments. */ +#if VM_PHYSSEG_MAX > 1 + upm_next = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + upm = uvm_physseg_get_next(upm); /* Fetch Next */ + + ATF_CHECK_EQ(upm_next, upm); + ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); +#endif + + /* This test will be triggered only if there are 3 or more segments. */ +#if VM_PHYSSEG_MAX > 2 + upm_next = uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3, + VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(3, uvm_physseg_get_entries()); + + upm = uvm_physseg_get_next(upm); /* Fetch Next */ + + ATF_CHECK_EQ(upm_next, upm); + ATF_CHECK_EQ(VALID_START_PFN_3, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_3, uvm_physseg_get_end(upm)); +#endif +} + +ATF_TC(uvm_physseg_get_next_invalid); +ATF_TC_HEAD(uvm_physseg_get_next_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \ + correctly when uvm_physseg_get_next() is called with invalid \ + parameter values."); +} +ATF_TC_BODY(uvm_physseg_get_next_invalid, tc) +{ + uvm_physseg_t upm = UVM_PHYSSEG_TYPE_INVALID; + + ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID, uvm_physseg_get_next(upm)); +} + +ATF_TC(uvm_physseg_get_prev); +ATF_TC_HEAD(uvm_physseg_get_prev, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the pointer values for previous \ + segment using the uvm_physseg_get_prev() call."); +} +ATF_TC_BODY(uvm_physseg_get_prev, tc) +{ +#if VM_PHYSSEG_MAX > 1 + uvm_physseg_t upm; +#endif + uvm_physseg_t upm_prev; + + + setup(); + upm_prev = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID_EMPTY, + uvm_physseg_get_prev(upm_prev)); + + /* This test will be triggered only if there are 2 or more segments. */ +#if VM_PHYSSEG_MAX > 1 + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + /* Fetch Previous, we inserted a lower value */ + upm = uvm_physseg_get_prev(upm); + + ATF_CHECK_EQ(upm_prev, upm); + ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm)); +#endif + + /* This test will be triggered only if there are 3 or more segments. */ +#if VM_PHYSSEG_MAX > 2 + uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3, + VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(3, uvm_physseg_get_entries()); + + /* + * This will return a UVM_PHYSSEG_TYPE_INVALID_EMPTY we are at the + * lowest + */ + upm = uvm_physseg_get_prev(upm); + + ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID_EMPTY, upm); +#endif +} + +ATF_TC(uvm_physseg_get_prev_invalid); +ATF_TC_HEAD(uvm_physseg_get_prev_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the invalid / error conditions \ + correctly when uvm_physseg_get_prev() is called with invalid \ + parameter values."); +} +ATF_TC_BODY(uvm_physseg_get_prev_invalid, tc) +{ + uvm_physseg_t upm = UVM_PHYSSEG_TYPE_INVALID; + + ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID, uvm_physseg_get_prev(upm)); +} + +ATF_TC(uvm_physseg_get_first); +ATF_TC_HEAD(uvm_physseg_get_first, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the pointer values for first \ + segment (lowest node) using the uvm_physseg_get_first() call."); +} +ATF_TC_BODY(uvm_physseg_get_first, tc) +{ + uvm_physseg_t upm = UVM_PHYSSEG_TYPE_INVALID_EMPTY; + uvm_physseg_t upm_first; + + /* Fake early boot */ + setup(); + + /* No nodes exist */ + ATF_CHECK_EQ(upm, uvm_physseg_get_first()); + + upm_first = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + /* Pointer to first should be the least valued node */ + upm = uvm_physseg_get_first(); + ATF_CHECK_EQ(upm_first, upm); + ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm)); + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm)); + + /* This test will be triggered only if there are 2 or more segments. */ +#if VM_PHYSSEG_MAX > 1 + /* Insert a node of lesser value */ + upm_first = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_CHECK_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + /* Pointer to first should be the least valued node */ + upm = uvm_physseg_get_first(); + ATF_CHECK_EQ(upm_first, upm); + ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm)); + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_1, uvm_physseg_get_avail_start(upm)); + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1, uvm_physseg_get_avail_end(upm)); +#endif + + /* This test will be triggered only if there are 3 or more segments. */ +#if VM_PHYSSEG_MAX > 2 + /* Insert a node of higher value */ + upm_first =uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3, + VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT); + + ATF_CHECK_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(3, uvm_physseg_get_entries()); + + /* Pointer to first should be the least valued node */ + upm = uvm_physseg_get_first(); + ATF_CHECK(upm_first != upm); + ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm)); + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_1, uvm_physseg_get_avail_start(upm)); + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1, uvm_physseg_get_avail_end(upm)); +#endif +} + +ATF_TC(uvm_physseg_get_last); +ATF_TC_HEAD(uvm_physseg_get_last, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the pointer values for last \ + segment using the uvm_physseg_get_last() call."); +} +ATF_TC_BODY(uvm_physseg_get_last, tc) +{ + uvm_physseg_t upm = UVM_PHYSSEG_TYPE_INVALID_EMPTY; + uvm_physseg_t upm_last; + + setup(); + + /* No nodes exist */ + ATF_CHECK_EQ(upm, uvm_physseg_get_last()); + + upm_last = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + /* Pointer to last should be the most valued node */ + upm = uvm_physseg_get_last(); + ATF_CHECK_EQ(upm_last, upm); + ATF_CHECK_EQ(VALID_START_PFN_1, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_1, uvm_physseg_get_end(upm)); + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_1, uvm_physseg_get_avail_start(upm)); + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1, uvm_physseg_get_avail_end(upm)); + + /* This test will be triggered only if there are 2 or more segments. */ +#if VM_PHYSSEG_MAX > 1 + /* Insert node of greater value */ + upm_last = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + /* Pointer to last should be the most valued node */ + upm = uvm_physseg_get_last(); + ATF_CHECK_EQ(upm_last, upm); + ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm)); + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm)); +#endif + + /* This test will be triggered only if there are 3 or more segments. */ +#if VM_PHYSSEG_MAX > 2 + /* Insert node of greater value */ + upm_last = uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3, + VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(3, uvm_physseg_get_entries()); + + /* Pointer to last should be the most valued node */ + upm = uvm_physseg_get_last(); + ATF_CHECK_EQ(upm_last, upm); + ATF_CHECK_EQ(VALID_START_PFN_3, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_3, uvm_physseg_get_end(upm)); + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_3, uvm_physseg_get_avail_start(upm)); + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_3, uvm_physseg_get_avail_end(upm)); +#endif +} + +ATF_TC(uvm_physseg_valid); +ATF_TC_HEAD(uvm_physseg_valid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the pointer value for current \ + segment is valid using the uvm_physseg_valid_p() call."); +} +ATF_TC_BODY(uvm_physseg_valid, tc) +{ + psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1); + + struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); + + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + uvm_physseg_init_seg(upm, pgs); + + ATF_REQUIRE_EQ(PAGE_COUNT_1M, uvmexp.npages); + + ATF_CHECK_EQ(true, uvm_physseg_valid_p(upm)); +} + +ATF_TC(uvm_physseg_valid_invalid); +ATF_TC_HEAD(uvm_physseg_valid_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests the pointer value for current \ + segment is invalid using the uvm_physseg_valid_p() call."); +} +ATF_TC_BODY(uvm_physseg_valid_invalid, tc) +{ + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + /* Force other check conditions */ + uvm.page_init_done = true; + + ATF_REQUIRE_EQ(true, uvm.page_init_done); + + /* Invalid uvm_physseg_t */ + ATF_CHECK_EQ(false, uvm_physseg_valid_p(UVM_PHYSSEG_TYPE_INVALID)); + + /* + * Without any pages initialized for segment, it is considered + * invalid + */ + ATF_CHECK_EQ(false, uvm_physseg_valid_p(upm)); +} + +ATF_TC(uvm_physseg_get_highest); +ATF_TC_HEAD(uvm_physseg_get_highest, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the returned PFN matches \ + the highest PFN in use by the system."); +} +ATF_TC_BODY(uvm_physseg_get_highest, tc) +{ + setup(); + uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + /* Only one segment so highest is the current */ + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_1 - 1, uvm_physseg_get_highest_frame()); + + /* This test will be triggered only if there are 2 or more segments. */ +#if VM_PHYSSEG_MAX > 1 + uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3, + VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_DEFAULT); + + /* PFN_3 > PFN_1 */ + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_3 - 1, uvm_physseg_get_highest_frame()); +#endif + + /* This test will be triggered only if there are 3 or more segments. */ +#if VM_PHYSSEG_MAX > 2 + uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + /* PFN_3 > PFN_2 */ + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_3 - 1, uvm_physseg_get_highest_frame()); +#endif +} + +ATF_TC(uvm_physseg_get_free_list); +ATF_TC_HEAD(uvm_physseg_get_free_list, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the returned Free List type \ + of a segment matches the one returned from \ + uvm_physseg_get_free_list() call."); +} +ATF_TC_BODY(uvm_physseg_get_free_list, tc) +{ + uvm_physseg_t upm; + + /* Fake early boot */ + setup(); + + /* Insertions are made in ascending order */ + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_CHECK_EQ(VM_FREELIST_DEFAULT, uvm_physseg_get_free_list(upm)); + + /* This test will be triggered only if there are 2 or more segments. */ +#if VM_PHYSSEG_MAX > 1 + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_FIRST16); + + ATF_CHECK_EQ(VM_FREELIST_FIRST16, uvm_physseg_get_free_list(upm)); +#endif + + /* This test will be triggered only if there are 3 or more segments. */ +#if VM_PHYSSEG_MAX > 2 + upm = uvm_page_physload(VALID_START_PFN_3, VALID_END_PFN_3, + VALID_AVAIL_START_PFN_3, VALID_AVAIL_END_PFN_3, VM_FREELIST_FIRST1G); + + ATF_CHECK_EQ(VM_FREELIST_FIRST1G, uvm_physseg_get_free_list(upm)); +#endif +} + +ATF_TC(uvm_physseg_get_start_hint); +ATF_TC_HEAD(uvm_physseg_get_start_hint, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the returned start_hint value \ + of a segment matches the one returned from \ + uvm_physseg_get_start_hint() call."); +} +ATF_TC_BODY(uvm_physseg_get_start_hint, tc) +{ + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + /* Will be Zero since no specific value is set during init */ + ATF_CHECK_EQ(0, uvm_physseg_get_start_hint(upm)); +} + +ATF_TC(uvm_physseg_set_start_hint); +ATF_TC_HEAD(uvm_physseg_set_start_hint, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the returned start_hint value \ + of a segment matches the one set by the \ + uvm_physseg_set_start_hint() call."); +} +ATF_TC_BODY(uvm_physseg_set_start_hint, tc) +{ + psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1); + + struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); + + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + uvm_physseg_init_seg(upm, pgs); + + ATF_CHECK_EQ(true, uvm_physseg_set_start_hint(upm, atop(128))); + + /* Will be atop(128) since no specific value is set above */ + ATF_CHECK_EQ(atop(128), uvm_physseg_get_start_hint(upm)); +} + +ATF_TC(uvm_physseg_set_start_hint_invalid); +ATF_TC_HEAD(uvm_physseg_set_start_hint_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the returned value is false \ + when an invalid segment matches the one trying to set by the \ + uvm_physseg_set_start_hint() call."); +} +ATF_TC_BODY(uvm_physseg_set_start_hint_invalid, tc) +{ + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + /* Force other check conditions */ + uvm.page_init_done = true; + + ATF_REQUIRE_EQ(true, uvm.page_init_done); + + ATF_CHECK_EQ(false, uvm_physseg_set_start_hint(upm, atop(128))); + + /* + * Will be Zero since no specific value is set after the init + * due to failure + */ + atf_tc_expect_signal(SIGABRT, "invalid uvm_physseg_t handle"); + + ATF_CHECK_EQ(0, uvm_physseg_get_start_hint(upm)); +} + +ATF_TC(uvm_physseg_get_pg); +ATF_TC_HEAD(uvm_physseg_get_pg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the returned vm_page struct \ + is correct when fetched by uvm_physseg_get_pg() call."); +} +ATF_TC_BODY(uvm_physseg_get_pg, tc) +{ + psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1); + + struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); + + struct vm_page *extracted_pg = NULL; + + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + /* Now we initialize the segment */ + uvm_physseg_init_seg(upm, pgs); + + ATF_REQUIRE_EQ(PAGE_COUNT_1M, uvmexp.npages); + + ATF_REQUIRE_EQ(NULL, extracted_pg); + + /* Try fetching the 5th Page in the Segment */ + extracted_pg = uvm_physseg_get_pg(upm, 5); + + /* Values of phys_addr is n * PAGE_SIZE where n is the page number */ + ATF_CHECK_EQ(5 * PAGE_SIZE, extracted_pg->phys_addr); + + /* Try fetching the 113th Page in the Segment */ + extracted_pg = uvm_physseg_get_pg(upm, 113); + + ATF_CHECK_EQ(113 * PAGE_SIZE, extracted_pg->phys_addr); +} + +#ifdef __HAVE_PMAP_PHYSSEG +ATF_TC(uvm_physseg_get_pmseg); +ATF_TC_HEAD(uvm_physseg_get_pmseg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the returned pmap_physseg \ + struct is correct when fetched by uvm_physseg_get_pmseg() call."); +} +ATF_TC_BODY(uvm_physseg_get_pmseg, tc) +{ + psize_t npages = (VALID_END_PFN_1 - VALID_START_PFN_1); + + struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); + + struct pmap_physseg pmseg = { true }; + + struct pmap_physseg *extracted_pmseg = NULL; + + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + /* Now we initialize the segment */ + uvm_physseg_init_seg(upm, pgs); + + ATF_REQUIRE_EQ(PAGE_COUNT_1M, uvmexp.npages); + + ATF_REQUIRE_EQ(NULL, extracted_pmseg); + + ATF_REQUIRE_EQ(true, pmseg.dummy_variable); + + /* Extract the current pmseg */ + extracted_pmseg = uvm_physseg_get_pmseg(upm); + + /* + * We can only check if it is not NULL + * We do not know the value it contains + */ + ATF_CHECK(NULL != extracted_pmseg); + + extracted_pmseg->dummy_variable = pmseg.dummy_variable; + + /* Invert value to ensure test integrity */ + pmseg.dummy_variable = false; + + ATF_REQUIRE_EQ(false, pmseg.dummy_variable); + + extracted_pmseg = uvm_physseg_get_pmseg(upm); + + ATF_CHECK(NULL != extracted_pmseg); + + ATF_CHECK_EQ(true, extracted_pmseg->dummy_variable); +} +#endif + +ATF_TC(vm_physseg_find); +ATF_TC_HEAD(vm_physseg_find, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the returned segment number \ + is correct when an PFN is passed into uvm_physseg_find() call. \ + In addition to this the offset of the PFN from the start of \ + segment is also set if the parameter is passed in as not NULL."); +} +ATF_TC_BODY(vm_physseg_find, tc) +{ + psize_t offset = (psize_t) -1; + + uvm_physseg_t upm_first, result; +#if VM_PHYSSEG_MAX > 1 + uvm_physseg_t upm_second; +#endif + + setup(); + + upm_first = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + /* This test will be triggered only if there are 2 or more segments. */ +#if VM_PHYSSEG_MAX > 1 + upm_second = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); +#endif + + /* Under ONE_MEGABYTE is segment upm_first */ + result = uvm_physseg_find(atop(ONE_MEGABYTE - 1024), NULL); + ATF_CHECK_EQ(upm_first, result); + ATF_CHECK_EQ(uvm_physseg_get_start(upm_first), + uvm_physseg_get_start(result)); + ATF_CHECK_EQ(uvm_physseg_get_end(upm_first), + uvm_physseg_get_end(result)); + ATF_CHECK_EQ(uvm_physseg_get_avail_start(upm_first), + uvm_physseg_get_avail_start(result)); + ATF_CHECK_EQ(uvm_physseg_get_avail_end(upm_first), + uvm_physseg_get_avail_end(result)); + + ATF_REQUIRE_EQ((psize_t) -1, offset); + + /* This test will be triggered only if there are 2 or more segments. */ +#if VM_PHYSSEG_MAX > 1 + /* Over ONE_MEGABYTE is segment upm_second */ + result = uvm_physseg_find(atop(ONE_MEGABYTE + 8192), &offset); + ATF_CHECK_EQ(upm_second, result); + ATF_CHECK_EQ(uvm_physseg_get_start(upm_second), + uvm_physseg_get_start(result)); + ATF_CHECK_EQ(uvm_physseg_get_end(upm_second), + uvm_physseg_get_end(result)); + ATF_CHECK_EQ(uvm_physseg_get_avail_start(upm_second), + uvm_physseg_get_avail_start(result)); + ATF_CHECK_EQ(uvm_physseg_get_avail_end(upm_second), + uvm_physseg_get_avail_end(result)); + + /* Offset is calculated based on PAGE_SIZE */ + /* atop(ONE_MEGABYTE + (2 * PAGE_SIZE)) - VALID_START_PFN1 = 2 */ + ATF_CHECK_EQ(2, offset); +#else + /* Under ONE_MEGABYTE is segment upm_first */ + result = uvm_physseg_find(atop(ONE_MEGABYTE - 12288), &offset); + ATF_CHECK_EQ(upm_first, result); + ATF_CHECK_EQ(uvm_physseg_get_start(upm_first), + uvm_physseg_get_start(result)); + ATF_CHECK_EQ(uvm_physseg_get_end(upm_first), + uvm_physseg_get_end(result)); + ATF_CHECK_EQ(uvm_physseg_get_avail_start(upm_first), + uvm_physseg_get_avail_start(result)); + ATF_CHECK_EQ(uvm_physseg_get_avail_end(upm_first), + uvm_physseg_get_avail_end(result)); + + /* Offset is calculated based on PAGE_SIZE */ + /* atop(ONE_MEGABYTE - (3 * PAGE_SIZE)) - VALID_START_PFN1 = 253 */ + ATF_CHECK_EQ(253, offset); +#endif +} + +ATF_TC(vm_physseg_find_invalid); +ATF_TC_HEAD(vm_physseg_find_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the returned segment number \ + is (paddr_t) -1 when a non existant PFN is passed into \ + uvm_physseg_find() call."); +} +ATF_TC_BODY(vm_physseg_find_invalid, tc) +{ + psize_t offset = (psize_t) -1; + + setup(); + uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + /* No segments over 3 MB exists at the moment */ + ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID, + uvm_physseg_find(atop(ONE_MEGABYTE * 3), NULL)); + + ATF_REQUIRE_EQ((psize_t) -1, offset); + + /* No segments over 3 MB exists at the moment */ + ATF_CHECK_EQ(UVM_PHYSSEG_TYPE_INVALID, + uvm_physseg_find(atop(ONE_MEGABYTE * 3), &offset)); + + ATF_CHECK_EQ((psize_t) -1, offset); +} + +ATF_TC(uvm_page_physunload_start); +ATF_TC_HEAD(uvm_page_physunload_start, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physunload()\ + call works without a panic(). Unloads from Start of the segment."); +} +ATF_TC_BODY(uvm_page_physunload_start, tc) +{ + /* + * Would uvmexp.npages reduce everytime an uvm_page_physunload is called? + */ + psize_t npages = (VALID_END_PFN_2 - VALID_START_PFN_2); + + struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); + + paddr_t p = 0; + + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + uvm_physseg_init_seg(upm, pgs); + + ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p)); + + /* + * When called for first time, uvm_page_physload() removes the first PFN + * + * New avail start will be VALID_AVAIL_START_PFN_2 + 1 + */ + ATF_CHECK_EQ(VALID_START_PFN_2, atop(p)); + + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2 + 1, + uvm_physseg_get_avail_start(upm)); + + ATF_CHECK_EQ(VALID_START_PFN_2 + 1, uvm_physseg_get_start(upm)); + + /* Rest of the stuff should remain the same */ + ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm)); +} + +ATF_TC(uvm_page_physunload_end); +ATF_TC_HEAD(uvm_page_physunload_end, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physunload()\ + call works without a panic(). Unloads from End of the segment."); +} +ATF_TC_BODY(uvm_page_physunload_end, tc) +{ + /* + * Would uvmexp.npages reduce everytime an uvm_page_physunload is called? + */ + paddr_t p = 0; + + uvm_physseg_t upm; + + setup(); + /* Note: start != avail_start to remove from end. */ + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2 + 1, VALID_AVAIL_END_PFN_2, + VM_FREELIST_DEFAULT); + + p = 0; + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE( + uvm_physseg_get_avail_start(upm) != uvm_physseg_get_start(upm)); + + ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p)); + + /* + * Remember if X is the upper limit the actual valid pointer is X - 1 + * + * For example if 256 is the upper limit for 1MB memory, last valid + * pointer is 256 - 1 = 255 + */ + + ATF_CHECK_EQ(VALID_END_PFN_2 - 1, atop(p)); + + /* + * When called for second time, uvm_page_physload() removes the last PFN + * + * New avail end will be VALID_AVAIL_END_PFN_2 - 1 + * New end will be VALID_AVAIL_PFN_2 - 1 + */ + + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2 - 1, uvm_physseg_get_avail_end(upm)); + + ATF_CHECK_EQ(VALID_END_PFN_2 - 1, uvm_physseg_get_end(upm)); + + /* Rest of the stuff should remain the same */ + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2 + 1, + uvm_physseg_get_avail_start(upm)); + ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); +} + +ATF_TC(uvm_page_physunload_none); +ATF_TC_HEAD(uvm_page_physunload_none, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the basic uvm_page_physunload()\ + call works without a panic(). Does not unload from start or end \ + because of non-aligned start / avail_start and end / avail_end \ + respectively."); +} +ATF_TC_BODY(uvm_page_physunload_none, tc) +{ + psize_t npages = (VALID_END_PFN_2 - VALID_START_PFN_2); + + struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); + + paddr_t p = 0; + + uvm_physseg_t upm; + + setup(); + /* + * Note: start != avail_start and end != avail_end. + * + * This prevents any unload from occuring. + */ + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2 + 1, VALID_AVAIL_END_PFN_2 - 1, + VM_FREELIST_DEFAULT); + + p = 0; + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_REQUIRE( + uvm_physseg_get_avail_start(upm) != uvm_physseg_get_start(upm)); + + uvm_physseg_init_seg(upm, pgs); + + ATF_CHECK_EQ(false, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p)); + + /* uvm_page_physload() will no longer unload memory */ + ATF_CHECK_EQ(0, p); + + /* Rest of the stuff should remain the same */ + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2 + 1, + uvm_physseg_get_avail_start(upm)); + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2 - 1, + uvm_physseg_get_avail_end(upm)); + ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); +} + +ATF_TC(uvm_page_physunload_delete_start); +ATF_TC_HEAD(uvm_page_physunload_delete_start, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the uvm_page_physunload() \ + works when the segment gets small enough to be deleted scenario. \ + NOTE: This one works deletes from start."); +} +ATF_TC_BODY(uvm_page_physunload_delete_start, tc) +{ + /* + * Would uvmexp.npages reduce everytime an uvm_page_physunload is called? + */ + paddr_t p = 0; + + uvm_physseg_t upm; + + setup(); + + /* + * Setup the Nuke from Starting point + */ + + upm = uvm_page_physload(VALID_END_PFN_1 - 1, VALID_END_PFN_1, + VALID_AVAIL_END_PFN_1 - 1, VALID_AVAIL_END_PFN_1, + VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */ +#if VM_PHYSSEG_MAX > 1 + uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); +#endif + +#if VM_PHYSSEG_MAX == 1 + atf_tc_expect_signal(SIGABRT, + "cannot uvm_page_physunload() the last segment"); +#endif + + ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p)); + + ATF_CHECK_EQ(VALID_END_PFN_1 - 1, atop(p)); + + ATF_CHECK_EQ(1, uvm_physseg_get_entries()); + + /* The only node now is the one we inserted second. */ + upm = uvm_physseg_get_first(); + + ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm)); + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm)); +} + +ATF_TC(uvm_page_physunload_delete_end); +ATF_TC_HEAD(uvm_page_physunload_delete_end, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the uvm_page_physunload() \ + works when the segment gets small enough to be deleted scenario. \ + NOTE: This one works deletes from end."); +} +ATF_TC_BODY(uvm_page_physunload_delete_end, tc) +{ + /* + * Would uvmexp.npages reduce everytime an uvm_page_physunload is called? + */ + + paddr_t p = 0; + + uvm_physseg_t upm; + + setup(); + + /* + * Setup the Nuke from Ending point + */ + + upm = uvm_page_physload(VALID_START_PFN_1, VALID_START_PFN_1 + 2, + VALID_AVAIL_START_PFN_1 + 1, VALID_AVAIL_START_PFN_1 + 2, + VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */ +#if VM_PHYSSEG_MAX > 1 + uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); +#endif + +#if VM_PHYSSEG_MAX == 1 + atf_tc_expect_signal(SIGABRT, + "cannot uvm_page_physunload() the last segment"); +#endif + + ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p)); + + p = 0; + + ATF_CHECK_EQ(true, uvm_page_physunload(upm, VM_FREELIST_DEFAULT, &p)); + + ATF_CHECK_EQ(VALID_START_PFN_1 + 2, atop(p)); + + ATF_CHECK_EQ(1, uvm_physseg_get_entries()); + + /* The only node now is the one we inserted second. */ + upm = uvm_physseg_get_first(); + + ATF_CHECK_EQ(VALID_START_PFN_2, uvm_physseg_get_start(upm)); + ATF_CHECK_EQ(VALID_END_PFN_2, uvm_physseg_get_end(upm)); + ATF_CHECK_EQ(VALID_AVAIL_START_PFN_2, uvm_physseg_get_avail_start(upm)); + ATF_CHECK_EQ(VALID_AVAIL_END_PFN_2, uvm_physseg_get_avail_end(upm)); +} + +ATF_TC(uvm_page_physunload_invalid); +ATF_TC_HEAD(uvm_page_physunload_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the uvm_page_physunload() \ + fails when then Free list does not match."); +} +ATF_TC_BODY(uvm_page_physunload_invalid, tc) +{ + psize_t npages = (VALID_END_PFN_2 - VALID_START_PFN_2); + + struct vm_page *pgs = malloc(sizeof(struct vm_page) * npages); + + paddr_t p = 0; + + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + uvm_physseg_init_seg(upm, pgs); + + ATF_CHECK_EQ(false, uvm_page_physunload(upm, VM_FREELIST_FIRST4G, &p)); +} + +ATF_TC(uvm_page_physunload_force); +ATF_TC_HEAD(uvm_page_physunload_force, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the basic \ + uvm_page_physunload_force() including delete works without."); +} +ATF_TC_BODY(uvm_page_physunload_force, tc) +{ + /* + * Would uvmexp.npages reduce everytime an uvm_page_physunload is called? + */ + paddr_t p = 0; + + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_1, VALID_END_PFN_1, + VALID_AVAIL_START_PFN_1, VALID_AVAIL_END_PFN_1, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + /* Insert more than one segment iff VM_PHYSSEG_MAX > 1 */ +#if VM_PHYSSEG_MAX > 1 + /* + * We have couple of physloads done this is bacause of the fact that if + * we physunload all the PFs from a given range and we have only one + * segment in total a panic() is called + */ + uvm_page_physload(VALID_START_PFN_2, VALID_END_PFN_2, + VALID_AVAIL_START_PFN_2, VALID_AVAIL_END_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); +#endif + +#if VM_PHYSSEG_MAX == 1 + atf_tc_expect_signal(SIGABRT, + "cannot uvm_page_physunload() the last segment"); +#endif + + ATF_REQUIRE_EQ(VALID_AVAIL_START_PFN_1, + uvm_physseg_get_avail_start(upm)); + + for(paddr_t i = VALID_AVAIL_START_PFN_1; + i < VALID_AVAIL_END_PFN_1; i++) { + ATF_CHECK_EQ(true, + uvm_page_physunload_force(upm, VM_FREELIST_DEFAULT, &p)); + ATF_CHECK_EQ(i, atop(p)); + + if(i + 1 < VALID_AVAIL_END_PFN_1) + ATF_CHECK_EQ(i + 1, uvm_physseg_get_avail_start(upm)); + } + + /* + * Now we try to retrieve the segment, which has been removed + * from the system through force unloading all the pages inside it. + */ + upm = uvm_physseg_find(VALID_AVAIL_END_PFN_1 - 1, NULL); + + /* It should no longer exist */ + ATF_CHECK_EQ(NULL, upm); + + ATF_CHECK_EQ(1, uvm_physseg_get_entries()); +} + +ATF_TC(uvm_page_physunload_force_invalid); +ATF_TC_HEAD(uvm_page_physunload_force_invalid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Tests if the invalid conditions for \ + uvm_page_physunload_force_invalid()."); +} +ATF_TC_BODY(uvm_page_physunload_force_invalid, tc) +{ + paddr_t p = 0; + + uvm_physseg_t upm; + + setup(); + upm = uvm_page_physload(VALID_START_PFN_2, VALID_START_PFN_2+ 1, + VALID_START_PFN_2, VALID_START_PFN_2, VM_FREELIST_DEFAULT); + + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + ATF_REQUIRE_EQ(0, uvmexp.npages); + + ATF_CHECK_EQ(false, + uvm_page_physunload_force(upm, VM_FREELIST_DEFAULT, &p)); + + ATF_CHECK_EQ(0, p); +} + +ATF_TP_ADD_TCS(tp) +{ +#if defined(UVM_HOTPLUG) + /* Internal */ + ATF_TP_ADD_TC(tp, uvm_physseg_alloc_atboot_mismatch); + ATF_TP_ADD_TC(tp, uvm_physseg_alloc_atboot_overrun); + ATF_TP_ADD_TC(tp, uvm_physseg_alloc_sanity); + ATF_TP_ADD_TC(tp, uvm_physseg_free_atboot_mismatch); + ATF_TP_ADD_TC(tp, uvm_physseg_free_sanity); +#if VM_PHYSSEG_MAX > 1 + ATF_TP_ADD_TC(tp, uvm_physseg_atboot_free_leak); +#endif +#endif /* UVM_HOTPLUG */ + + ATF_TP_ADD_TC(tp, uvm_physseg_plug); + ATF_TP_ADD_TC(tp, uvm_physseg_unplug); + + /* Exported */ + ATF_TP_ADD_TC(tp, uvm_physseg_init); + ATF_TP_ADD_TC(tp, uvm_page_physload_preload); + ATF_TP_ADD_TC(tp, uvm_page_physload_postboot); + ATF_TP_ADD_TC(tp, uvm_physseg_handle_immutable); + ATF_TP_ADD_TC(tp, uvm_physseg_seg_chomp_slab); + ATF_TP_ADD_TC(tp, uvm_physseg_alloc_from_slab); + ATF_TP_ADD_TC(tp, uvm_physseg_init_seg); + ATF_TP_ADD_TC(tp, uvm_physseg_get_start); + ATF_TP_ADD_TC(tp, uvm_physseg_get_start_invalid); + ATF_TP_ADD_TC(tp, uvm_physseg_get_end); + ATF_TP_ADD_TC(tp, uvm_physseg_get_end_invalid); + ATF_TP_ADD_TC(tp, uvm_physseg_get_avail_start); + ATF_TP_ADD_TC(tp, uvm_physseg_get_avail_start_invalid); + ATF_TP_ADD_TC(tp, uvm_physseg_get_avail_end); + ATF_TP_ADD_TC(tp, uvm_physseg_get_avail_end_invalid); + ATF_TP_ADD_TC(tp, uvm_physseg_get_next); + ATF_TP_ADD_TC(tp, uvm_physseg_get_next_invalid); + ATF_TP_ADD_TC(tp, uvm_physseg_get_prev); + ATF_TP_ADD_TC(tp, uvm_physseg_get_prev_invalid); + ATF_TP_ADD_TC(tp, uvm_physseg_get_first); + ATF_TP_ADD_TC(tp, uvm_physseg_get_last); + ATF_TP_ADD_TC(tp, uvm_physseg_valid); + ATF_TP_ADD_TC(tp, uvm_physseg_valid_invalid); + ATF_TP_ADD_TC(tp, uvm_physseg_get_highest); + ATF_TP_ADD_TC(tp, uvm_physseg_get_free_list); + ATF_TP_ADD_TC(tp, uvm_physseg_get_start_hint); + ATF_TP_ADD_TC(tp, uvm_physseg_set_start_hint); + ATF_TP_ADD_TC(tp, uvm_physseg_set_start_hint_invalid); + ATF_TP_ADD_TC(tp, uvm_physseg_get_pg); + +#ifdef __HAVE_PMAP_PHYSSEG + ATF_TP_ADD_TC(tp, uvm_physseg_get_pmseg); +#endif + ATF_TP_ADD_TC(tp, vm_physseg_find); + ATF_TP_ADD_TC(tp, vm_physseg_find_invalid); + + ATF_TP_ADD_TC(tp, uvm_page_physunload_start); + ATF_TP_ADD_TC(tp, uvm_page_physunload_end); + ATF_TP_ADD_TC(tp, uvm_page_physunload_none); + ATF_TP_ADD_TC(tp, uvm_page_physunload_delete_start); + ATF_TP_ADD_TC(tp, uvm_page_physunload_delete_end); + ATF_TP_ADD_TC(tp, uvm_page_physunload_invalid); + ATF_TP_ADD_TC(tp, uvm_page_physunload_force); + ATF_TP_ADD_TC(tp, uvm_page_physunload_force_invalid); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/sys/uvm/t_uvm_physseg_load.c b/contrib/netbsd-tests/sys/uvm/t_uvm_physseg_load.c new file mode 100644 index 0000000..a150f69 --- /dev/null +++ b/contrib/netbsd-tests/sys/uvm/t_uvm_physseg_load.c @@ -0,0 +1,740 @@ +/* $NetBSD: t_uvm_physseg_load.c,v 1.2 2016/12/22 08:15:20 cherry Exp $ */ + +/*- + * Copyright (c) 2015, 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Santhosh N. Raju and + * by Cherry G. Mathew + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__RCSID("$NetBSD: t_uvm_physseg_load.c,v 1.2 2016/12/22 08:15:20 cherry Exp $"); + +/* + * If this line is commented out tests related touvm_physseg_get_pmseg() + * wont run. + * + * Have a look at machine/uvm_physseg.h for more details. + */ +#define __HAVE_PMAP_PHYSSEG + +/* + * This is a dummy struct used for testing purposes + * + * In reality this struct would exist in the MD part of the code residing in + * machines/vmparam.h + */ + +#ifdef __HAVE_PMAP_PHYSSEG +struct pmap_physseg { + int dummy_variable; /* Dummy variable use for testing */ +}; +#endif + +/* Testing API - assumes userland */ +/* Provide Kernel API equivalents */ +#include +#include +#include /* memset(3) et. al */ +#include /* printf(3) */ +#include /* malloc(3) */ +#include +#include +#include + +#define PRIxPADDR "lx" +#define PRIxPSIZE "lx" +#define PRIuPSIZE "lu" +#define PRIxVADDR "lx" +#define PRIxVSIZE "lx" +#define PRIuVSIZE "lu" + +#define UVM_HOTPLUG /* Enable hotplug with rbtree. */ +#define PMAP_STEAL_MEMORY +#define DEBUG /* Enable debug functionality. */ + +typedef unsigned long vaddr_t; +typedef unsigned long paddr_t; +typedef unsigned long psize_t; +typedef unsigned long vsize_t; + +#include +#include + +#ifndef DIAGNOSTIC +#define KASSERTMSG(e, msg, ...) /* NOTHING */ +#define KASSERT(e) /* NOTHING */ +#else +#define KASSERT(a) assert(a) +#define KASSERTMSG(exp, ...) printf(__VA_ARGS__); assert((exp)) +#endif + +#define VM_PHYSSEG_STRAT VM_PSTRAT_BSEARCH + +#define VM_NFREELIST 4 +#define VM_FREELIST_DEFAULT 0 +#define VM_FREELIST_FIRST16 3 +#define VM_FREELIST_FIRST1G 2 +#define VM_FREELIST_FIRST4G 1 + +/* + * Used in tests when Array implementation is tested + */ +#if !defined(VM_PHYSSEG_MAX) +#define VM_PHYSSEG_MAX 32 +#endif + +#define PAGE_SIZE 4096 +#define PAGE_SHIFT 12 +#define atop(x) (((paddr_t)(x)) >> PAGE_SHIFT) + +#define mutex_enter(l) +#define mutex_exit(l) + +#define _SYS_KMEM_H_ /* Disallow the real kmem API (see below) */ +/* free(p) XXX: pgs management need more thought */ +#define kmem_alloc(size, flags) malloc(size) +#define kmem_zalloc(size, flags) malloc(size) +#define kmem_free(p, size) free(p) + +psize_t physmem; + +struct uvmexp uvmexp; /* decl */ + +/* + * uvm structure borrowed from uvm.h + * + * Remember this is a dummy structure used within the ATF Tests and + * uses only necessary fields from the original uvm struct. + * See uvm/uvm.h for the full struct. + */ + +struct uvm { + /* vm_page related parameters */ + + bool page_init_done; /* TRUE if uvm_page_init() finished */ +} uvm; + +static void +panic(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vprintf(fmt, ap); + printf("\n"); + va_end(ap); + KASSERT(false); + + /*NOTREACHED*/ +} + +static void +uvm_pagefree(struct vm_page *pg) +{ + return; +} + +#if defined(UVM_HOTPLUG) +static void +uvmpdpol_reinit(void) +{ + return; +} +#endif /* UVM_HOTPLUG */ + +/* end - Provide Kernel API equivalents */ + +#include "uvm/uvm_physseg.c" + +#include + +#define ONE_MEGABYTE 1024 * 1024 + +/* Sample Page Frame Numbers */ +#define VALID_START_PFN_1 atop(0) +#define VALID_END_PFN_1 atop(ONE_MEGABYTE) +#define VALID_AVAIL_START_PFN_1 atop(0) +#define VALID_AVAIL_END_PFN_1 atop(ONE_MEGABYTE) + +#define VALID_START_PFN_2 atop(ONE_MEGABYTE + 1) +#define VALID_END_PFN_2 atop(ONE_MEGABYTE * 2) +#define VALID_AVAIL_START_PFN_2 atop(ONE_MEGABYTE + 1) +#define VALID_AVAIL_END_PFN_2 atop(ONE_MEGABYTE * 2) + +#define VALID_START_PFN_3 atop((ONE_MEGABYTE * 2) + 1) +#define VALID_END_PFN_3 atop(ONE_MEGABYTE * 3) +#define VALID_AVAIL_START_PFN_3 atop((ONE_MEGABYTE * 2) + 1) +#define VALID_AVAIL_END_PFN_3 atop(ONE_MEGABYTE * 3) + +#define VALID_START_PFN_4 atop(ONE_MEGABYTE + 1) +#define VALID_END_PFN_4 atop(ONE_MEGABYTE * 128) +#define VALID_AVAIL_START_PFN_4 atop(ONE_MEGABYTE + 1) +#define VALID_AVAIL_END_PFN_4 atop(ONE_MEGABYTE * 128) + +#define VALID_START_PFN_5 atop(ONE_MEGABYTE + 1) +#define VALID_END_PFN_5 atop(ONE_MEGABYTE * 256) +#define VALID_AVAIL_START_PFN_5 atop(ONE_MEGABYTE + 1) +#define VALID_AVAIL_END_PFN_5 atop(ONE_MEGABYTE * 256) + +/* + * Total number of pages (of 4K size each) should be 256 for 1MB of memory. + */ +#define PAGE_COUNT_1M 256 + +/* + * The number of Page Frames to allot per segment + */ +#define PF_STEP 8 + +/* + * A debug fucntion to print the content of upm. + */ + static inline void + uvm_physseg_dump_seg(uvm_physseg_t upm) + { +#if defined(DEBUG) + printf("%s: seg->start == %ld\n", __func__, + uvm_physseg_get_start(upm)); + printf("%s: seg->end == %ld\n", __func__, + uvm_physseg_get_end(upm)); + printf("%s: seg->avail_start == %ld\n", __func__, + uvm_physseg_get_avail_start(upm)); + printf("%s: seg->avail_end == %ld\n", __func__, + uvm_physseg_get_avail_end(upm)); + + printf("====\n\n"); +#else + return; +#endif /* DEBUG */ + } + +/* + * Private accessor that gets the value of vm_physmem.nentries + */ +static int +uvm_physseg_get_entries(void) +{ +#if defined(UVM_HOTPLUG) + return uvm_physseg_graph.nentries; +#else + return vm_nphysmem; +#endif /* UVM_HOTPLUG */ +} + +/* + * Note: This function replicates verbatim what happens in + * uvm_page.c:uvm_page_init(). + * + * Please track any changes that happen there. + */ +static void +uvm_page_init_fake(struct vm_page *pagearray, psize_t pagecount) +{ + uvm_physseg_t bank; + size_t n; + + for (bank = uvm_physseg_get_first(), + uvm_physseg_seg_chomp_slab(bank, pagearray, pagecount); + uvm_physseg_valid_p(bank); + bank = uvm_physseg_get_next(bank)) { + + n = uvm_physseg_get_end(bank) - uvm_physseg_get_start(bank); + uvm_physseg_seg_alloc_from_slab(bank, n); + uvm_physseg_init_seg(bank, pagearray); + + /* set up page array pointers */ + pagearray += n; + pagecount -= n; + } + + uvm.page_init_done = true; +} + +/* + * PHYS_TO_VM_PAGE: find vm_page for a PA. used by MI code to get vm_pages + * back from an I/O mapping (ugh!). used in some MD code as well. + */ +static struct vm_page * +uvm_phys_to_vm_page(paddr_t pa) +{ + paddr_t pf = atop(pa); + paddr_t off; + uvm_physseg_t psi; + + psi = uvm_physseg_find(pf, &off); + if (psi != UVM_PHYSSEG_TYPE_INVALID) + return uvm_physseg_get_pg(psi, off); + return(NULL); +} + +//static paddr_t +//uvm_vm_page_to_phys(const struct vm_page *pg) +//{ +// +// return pg->phys_addr; +//} + +/* + * XXX: To do, write control test cases for uvm_vm_page_to_phys(). + */ + +/* #define VM_PAGE_TO_PHYS(entry) uvm_vm_page_to_phys(entry) */ + +#define PHYS_TO_VM_PAGE(pa) uvm_phys_to_vm_page(pa) + +/* + * Test Fixture SetUp(). + */ +static void +setup(void) +{ + /* Prerequisites for running certain calls in uvm_physseg */ + uvmexp.pagesize = PAGE_SIZE; + uvmexp.npages = 0; + uvm.page_init_done = false; + uvm_physseg_init(); +} + +ATF_TC(uvm_physseg_100); +ATF_TC_HEAD(uvm_physseg_100, tc) +{ + atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ + 100 calls, VM_PHYSSEG_MAX is 32."); +} +ATF_TC_BODY(uvm_physseg_100, tc) +{ + paddr_t pa; + + setup(); + + for(paddr_t i = VALID_START_PFN_1; + i < VALID_END_PFN_1; i += PF_STEP) { + uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, + VM_FREELIST_DEFAULT); + } + + ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); + + srandom((unsigned)time(NULL)); + for(int i = 0; i < 100; i++) { + pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); + PHYS_TO_VM_PAGE(pa); + } + + ATF_CHECK_EQ(true, true); +} + +ATF_TC(uvm_physseg_1K); +ATF_TC_HEAD(uvm_physseg_1K, tc) +{ + atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ + 1000 calls, VM_PHYSSEG_MAX is 32."); +} +ATF_TC_BODY(uvm_physseg_1K, tc) +{ + paddr_t pa; + + setup(); + + for(paddr_t i = VALID_START_PFN_1; + i < VALID_END_PFN_1; i += PF_STEP) { + uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, + VM_FREELIST_DEFAULT); + } + + ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); + + srandom((unsigned)time(NULL)); + for(int i = 0; i < 1000; i++) { + pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); + PHYS_TO_VM_PAGE(pa); + } + + ATF_CHECK_EQ(true, true); +} + +ATF_TC(uvm_physseg_10K); +ATF_TC_HEAD(uvm_physseg_10K, tc) +{ + atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ + 10,000 calls, VM_PHYSSEG_MAX is 32."); +} +ATF_TC_BODY(uvm_physseg_10K, tc) +{ + paddr_t pa; + + setup(); + + for(paddr_t i = VALID_START_PFN_1; + i < VALID_END_PFN_1; i += PF_STEP) { + uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, + VM_FREELIST_DEFAULT); + } + + ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); + + srandom((unsigned)time(NULL)); + for(int i = 0; i < 10000; i++) { + pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); + PHYS_TO_VM_PAGE(pa); + } + + ATF_CHECK_EQ(true, true); +} + +ATF_TC(uvm_physseg_100K); +ATF_TC_HEAD(uvm_physseg_100K, tc) +{ + atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ + 100,000 calls, VM_PHYSSEG_MAX is 32."); +} +ATF_TC_BODY(uvm_physseg_100K, tc) +{ + paddr_t pa; + + setup(); + + for(paddr_t i = VALID_START_PFN_1; + i < VALID_END_PFN_1; i += PF_STEP) { + uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, + VM_FREELIST_DEFAULT); + } + + ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); + + srandom((unsigned)time(NULL)); + for(int i = 0; i < 100000; i++) { + pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); + PHYS_TO_VM_PAGE(pa); + } + + ATF_CHECK_EQ(true, true); +} + +ATF_TC(uvm_physseg_1M); +ATF_TC_HEAD(uvm_physseg_1M, tc) +{ + atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ + 1,000,000 calls, VM_PHYSSEG_MAX is 32."); +} +ATF_TC_BODY(uvm_physseg_1M, tc) +{ + paddr_t pa; + + setup(); + + for(paddr_t i = VALID_START_PFN_1; + i < VALID_END_PFN_1; i += PF_STEP) { + uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, + VM_FREELIST_DEFAULT); + } + + ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); + + srandom((unsigned)time(NULL)); + for(int i = 0; i < 1000000; i++) { + pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); + PHYS_TO_VM_PAGE(pa); + } + + ATF_CHECK_EQ(true, true); +} + +ATF_TC(uvm_physseg_10M); +ATF_TC_HEAD(uvm_physseg_10M, tc) +{ + atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ + 10,000,000 calls, VM_PHYSSEG_MAX is 32."); +} +ATF_TC_BODY(uvm_physseg_10M, tc) +{ + paddr_t pa; + + setup(); + + for(paddr_t i = VALID_START_PFN_1; + i < VALID_END_PFN_1; i += PF_STEP) { + uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, + VM_FREELIST_DEFAULT); + } + + ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); + + srandom((unsigned)time(NULL)); + for(int i = 0; i < 10000000; i++) { + pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); + PHYS_TO_VM_PAGE(pa); + } + + ATF_CHECK_EQ(true, true); +} + +ATF_TC(uvm_physseg_100M); +ATF_TC_HEAD(uvm_physseg_100M, tc) +{ + atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ + 100,000,000 calls, VM_PHYSSEG_MAX is 32."); +} +ATF_TC_BODY(uvm_physseg_100M, tc) +{ + paddr_t pa; + + setup(); + + for(paddr_t i = VALID_START_PFN_1; + i < VALID_END_PFN_1; i += PF_STEP) { + uvm_page_physload(i, i + PF_STEP, i, i + PF_STEP, + VM_FREELIST_DEFAULT); + } + + ATF_REQUIRE_EQ(VM_PHYSSEG_MAX, uvm_physseg_get_entries()); + + srandom((unsigned)time(NULL)); + for(int i = 0; i < 100000000; i++) { + pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_1); + PHYS_TO_VM_PAGE(pa); + } + + ATF_CHECK_EQ(true, true); +} + +ATF_TC(uvm_physseg_1MB); +ATF_TC_HEAD(uvm_physseg_1MB, tc) +{ + atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ + 10,000,000 calls, VM_PHYSSEG_MAX is 32 on 1 MB Segment."); +} +ATF_TC_BODY(uvm_physseg_1MB, t) +{ + paddr_t pa = 0; + + paddr_t pf = 0; + + psize_t pf_chunk_size = 0; + + psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); + + psize_t npages2 = (VALID_END_PFN_2 - VALID_START_PFN_2); + + struct vm_page *slab = malloc(sizeof(struct vm_page) * + (npages1 + npages2)); + + setup(); + + /* We start with zero segments */ + ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_1, npages1, NULL)); + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + /* Post boot: Fake all segments and pages accounted for. */ + uvm_page_init_fake(slab, npages1 + npages2); + + ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_2, npages2, NULL)); + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + srandom((unsigned)time(NULL)); + for(pf = VALID_START_PFN_2; pf < VALID_END_PFN_2; pf += PF_STEP) { + pf_chunk_size = (psize_t) random() % (psize_t) (PF_STEP - 1) + 1; + uvm_physseg_unplug(pf, pf_chunk_size); + } + + for(int i = 0; i < 10000000; i++) { + pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_2); + if(pa < ctob(VALID_START_PFN_2)) + pa += ctob(VALID_START_PFN_2); + PHYS_TO_VM_PAGE(pa); + } + + ATF_CHECK_EQ(true, true); +} + +ATF_TC(uvm_physseg_64MB); +ATF_TC_HEAD(uvm_physseg_64MB, tc) +{ + atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ + 10,000,000 calls, VM_PHYSSEG_MAX is 32 on 64 MB Segment."); +} +ATF_TC_BODY(uvm_physseg_64MB, t) +{ + paddr_t pa = 0; + + paddr_t pf = 0; + + psize_t pf_chunk_size = 0; + + psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); + + psize_t npages2 = (VALID_END_PFN_3 - VALID_START_PFN_3); + + struct vm_page *slab = malloc(sizeof(struct vm_page) * + (npages1 + npages2)); + + setup(); + + /* We start with zero segments */ + ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_1, npages1, NULL)); + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + /* Post boot: Fake all segments and pages accounted for. */ + uvm_page_init_fake(slab, npages1 + npages2); + + ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_3, npages2, NULL)); + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + srandom((unsigned)time(NULL)); + for(pf = VALID_START_PFN_3; pf < VALID_END_PFN_3; pf += PF_STEP) { + pf_chunk_size = (psize_t) random() % (psize_t) (PF_STEP - 1) + 1; + uvm_physseg_unplug(pf, pf_chunk_size); + } + + for(int i = 0; i < 10000000; i++) { + pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_3); + if(pa < ctob(VALID_START_PFN_3)) + pa += ctob(VALID_START_PFN_3); + PHYS_TO_VM_PAGE(pa); + } + + ATF_CHECK_EQ(true, true); +} + +ATF_TC(uvm_physseg_128MB); +ATF_TC_HEAD(uvm_physseg_128MB, tc) +{ + atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ + 10,000,000 calls, VM_PHYSSEG_MAX is 32 on 128 MB Segment."); +} +ATF_TC_BODY(uvm_physseg_128MB, t) +{ + paddr_t pa = 0; + + paddr_t pf = 0; + + psize_t pf_chunk_size = 0; + + psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); + + psize_t npages2 = (VALID_END_PFN_4 - VALID_START_PFN_4); + + struct vm_page *slab = malloc(sizeof(struct vm_page) + * (npages1 + npages2)); + + setup(); + + /* We start with zero segments */ + ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_1, npages1, NULL)); + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + /* Post boot: Fake all segments and pages accounted for. */ + uvm_page_init_fake(slab, npages1 + npages2); + + ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_2, npages2, NULL)); + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + srandom((unsigned)time(NULL)); + for(pf = VALID_START_PFN_4; pf < VALID_END_PFN_4; pf += PF_STEP) { + pf_chunk_size = (psize_t) random() % (psize_t) (PF_STEP - 1) + 1; + uvm_physseg_unplug(pf, pf_chunk_size); + } + + for(int i = 0; i < 10000000; i++) { + pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_4); + if(pa < ctob(VALID_START_PFN_4)) + pa += ctob(VALID_START_PFN_4); + PHYS_TO_VM_PAGE(pa); + } + + ATF_CHECK_EQ(true, true); +} + +ATF_TC(uvm_physseg_256MB); +ATF_TC_HEAD(uvm_physseg_256MB, tc) +{ + atf_tc_set_md_var(tc, "descr", "Load test uvm_phys_to_vm_page() with \ + 10,000,000 calls, VM_PHYSSEG_MAX is 32 on 256 MB Segment."); +} +ATF_TC_BODY(uvm_physseg_256MB, t) +{ + paddr_t pa = 0; + + paddr_t pf = 0; + + psize_t pf_chunk_size = 0; + + psize_t npages1 = (VALID_END_PFN_1 - VALID_START_PFN_1); + + psize_t npages2 = (VALID_END_PFN_5 - VALID_START_PFN_5); + + struct vm_page *slab = malloc(sizeof(struct vm_page) * (npages1 + npages2)); + + setup(); + + /* We start with zero segments */ + ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_1, npages1, NULL)); + ATF_REQUIRE_EQ(1, uvm_physseg_get_entries()); + + /* Post boot: Fake all segments and pages accounted for. */ + uvm_page_init_fake(slab, npages1 + npages2); + + ATF_REQUIRE_EQ(true, uvm_physseg_plug(VALID_START_PFN_2, npages2, NULL)); + ATF_REQUIRE_EQ(2, uvm_physseg_get_entries()); + + srandom((unsigned)time(NULL)); + for(pf = VALID_START_PFN_5; pf < VALID_END_PFN_5; pf += PF_STEP) { + pf_chunk_size = (psize_t) random() % (psize_t) (PF_STEP - 1) + 1; + uvm_physseg_unplug(pf, pf_chunk_size); + } + + for(int i = 0; i < 10000000; i++) { + pa = (paddr_t) random() % (paddr_t) ctob(VALID_END_PFN_5); + if(pa < ctob(VALID_END_PFN_5)) + pa += ctob(VALID_START_PFN_5); + PHYS_TO_VM_PAGE(pa); + } + + ATF_CHECK_EQ(true, true); +} + +ATF_TP_ADD_TCS(tp) +{ + /* Fixed memory size tests. */ + ATF_TP_ADD_TC(tp, uvm_physseg_100); + ATF_TP_ADD_TC(tp, uvm_physseg_1K); + ATF_TP_ADD_TC(tp, uvm_physseg_10K); + ATF_TP_ADD_TC(tp, uvm_physseg_100K); + ATF_TP_ADD_TC(tp, uvm_physseg_1M); + ATF_TP_ADD_TC(tp, uvm_physseg_10M); + ATF_TP_ADD_TC(tp, uvm_physseg_100M); + +#if defined(UVM_HOTPLUG) + /* Variable memory size tests. */ + ATF_TP_ADD_TC(tp, uvm_physseg_1MB); + ATF_TP_ADD_TC(tp, uvm_physseg_64MB); + ATF_TP_ADD_TC(tp, uvm_physseg_128MB); + ATF_TP_ADD_TC(tp, uvm_physseg_256MB); +#endif /* UVM_HOTPLUG */ + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/usr.bin/awk/d_assign_NF.awk b/contrib/netbsd-tests/usr.bin/awk/d_assign_NF.awk new file mode 100644 index 0000000..52c3912 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_assign_NF.awk @@ -0,0 +1,16 @@ +# $NetBSD: d_assign_NF.awk,v 1.1 2012/03/11 18:35:59 jruoho Exp $ + +{ + NF = 2 + print "$0=`" $0 "`" + print "$3=`" $3 "`" + print "$4=`" $4 "`" + NF = 3 + print "$0=`" $0 "`" + print "$3=`" $3 "`" + print "$4=`" $4 "`" + NF = 4 + print "$0=`" $0 "`" + print "$3=`" $3 "`" + print "$4=`" $4 "`" +} diff --git a/contrib/netbsd-tests/usr.bin/awk/d_assign_NF.in b/contrib/netbsd-tests/usr.bin/awk/d_assign_NF.in new file mode 100644 index 0000000..1245b92 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_assign_NF.in @@ -0,0 +1 @@ + 1 2 3 diff --git a/contrib/netbsd-tests/usr.bin/awk/d_assign_NF.out b/contrib/netbsd-tests/usr.bin/awk/d_assign_NF.out new file mode 100644 index 0000000..2631a7a --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_assign_NF.out @@ -0,0 +1,9 @@ +$0=`1 2` +$3=`` +$4=`` +$0=`1 2 ` +$3=`` +$4=`` +$0=`1 2 ` +$3=`` +$4=`` diff --git a/contrib/netbsd-tests/usr.bin/awk/d_big_regexp.awk b/contrib/netbsd-tests/usr.bin/awk/d_big_regexp.awk new file mode 100644 index 0000000..1502b5e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_big_regexp.awk @@ -0,0 +1,3 @@ +# $NetBSD: d_big_regexp.awk,v 1.1 2012/03/11 18:36:00 jruoho Exp $ + +/^[^_][^ ]*_NNIFO([ ]+[^_]+[^ ]*_(CC|INR|JJFO|JJMA|JJPG|NNIFG|NNIFO|NNIMPG|NNIMR|NNING|PP3FD|PQINO|PQMO|PSFR|RQ|TC|VIIR3|VPIPN|VPLIPF|NOTAG|RQR))*$/ diff --git a/contrib/netbsd-tests/usr.bin/awk/d_big_regexp.in b/contrib/netbsd-tests/usr.bin/awk/d_big_regexp.in new file mode 100644 index 0000000..ad82078 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_big_regexp.in @@ -0,0 +1 @@ +1_NNIFO 1_PSFR 1_JJFO 1_NNIFO 1_INR 1_NNIMR 1_CC 1_NNING 1_RQ 1_VPLIPF 1_NNIFG 1_JJPG 1_NNIMPG 1_PQINO 1_VPIPN 1_PP3FD 1_JJMA 1_PQMO 1_TC 1_VIIR3 diff --git a/contrib/netbsd-tests/usr.bin/awk/d_big_regexp.out b/contrib/netbsd-tests/usr.bin/awk/d_big_regexp.out new file mode 100644 index 0000000..ad82078 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_big_regexp.out @@ -0,0 +1 @@ +1_NNIFO 1_PSFR 1_JJFO 1_NNIFO 1_INR 1_NNIMR 1_CC 1_NNING 1_RQ 1_VPLIPF 1_NNIFG 1_JJPG 1_NNIMPG 1_PQINO 1_VPIPN 1_PP3FD 1_JJMA 1_PQMO 1_TC 1_VIIR3 diff --git a/contrib/netbsd-tests/usr.bin/awk/d_end1.awk b/contrib/netbsd-tests/usr.bin/awk/d_end1.awk new file mode 100644 index 0000000..cb8b0d0 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_end1.awk @@ -0,0 +1,5 @@ +# $NetBSD: d_end1.awk,v 1.1 2012/03/11 18:36:00 jruoho Exp $ + +END { + print NF; +} diff --git a/contrib/netbsd-tests/usr.bin/awk/d_end1.in b/contrib/netbsd-tests/usr.bin/awk/d_end1.in new file mode 100644 index 0000000..8e13e46 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_end1.in @@ -0,0 +1 @@ +a b c d diff --git a/contrib/netbsd-tests/usr.bin/awk/d_end1.out b/contrib/netbsd-tests/usr.bin/awk/d_end1.out new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_end1.out @@ -0,0 +1 @@ +4 diff --git a/contrib/netbsd-tests/usr.bin/awk/d_end2.awk b/contrib/netbsd-tests/usr.bin/awk/d_end2.awk new file mode 100644 index 0000000..8b10b82 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_end2.awk @@ -0,0 +1,5 @@ +# $NetBSD: d_end2.awk,v 1.1 2012/03/11 18:36:00 jruoho Exp $ + +END { + print $0; +} diff --git a/contrib/netbsd-tests/usr.bin/awk/d_end2.in b/contrib/netbsd-tests/usr.bin/awk/d_end2.in new file mode 100644 index 0000000..8e13e46 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_end2.in @@ -0,0 +1 @@ +a b c d diff --git a/contrib/netbsd-tests/usr.bin/awk/d_end2.out b/contrib/netbsd-tests/usr.bin/awk/d_end2.out new file mode 100644 index 0000000..8e13e46 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_end2.out @@ -0,0 +1 @@ +a b c d diff --git a/contrib/netbsd-tests/usr.bin/awk/d_period.awk b/contrib/netbsd-tests/usr.bin/awk/d_period.awk new file mode 100644 index 0000000..d1dabf7 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_period.awk @@ -0,0 +1 @@ +{print x + $1 + 0.125} diff --git a/contrib/netbsd-tests/usr.bin/awk/d_period.in b/contrib/netbsd-tests/usr.bin/awk/d_period.in new file mode 100644 index 0000000..d10c0e2 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_period.in @@ -0,0 +1 @@ +0,25 diff --git a/contrib/netbsd-tests/usr.bin/awk/d_period.out b/contrib/netbsd-tests/usr.bin/awk/d_period.out new file mode 100644 index 0000000..3382aa6 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_period.out @@ -0,0 +1 @@ +0.625 diff --git a/contrib/netbsd-tests/usr.bin/awk/d_string1.awk b/contrib/netbsd-tests/usr.bin/awk/d_string1.awk new file mode 100644 index 0000000..d690240 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_string1.awk @@ -0,0 +1,7 @@ +# $NetBSD: d_string1.awk,v 1.1 2012/03/11 18:36:00 jruoho Exp $ + +BEGIN { + print "A\ +B"; + print "CD" +} diff --git a/contrib/netbsd-tests/usr.bin/awk/d_string1.out b/contrib/netbsd-tests/usr.bin/awk/d_string1.out new file mode 100644 index 0000000..96c017b --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_string1.out @@ -0,0 +1,2 @@ +AB +CD diff --git a/contrib/netbsd-tests/usr.bin/awk/d_tolower.awk b/contrib/netbsd-tests/usr.bin/awk/d_tolower.awk new file mode 100644 index 0000000..258d181 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_tolower.awk @@ -0,0 +1,5 @@ +# $NetBSD: d_tolower.awk,v 1.1 2012/03/11 18:36:00 jruoho Exp $ + +END { + print tolower($0); +} diff --git a/contrib/netbsd-tests/usr.bin/awk/d_tolower.in b/contrib/netbsd-tests/usr.bin/awk/d_tolower.in new file mode 100644 index 0000000..66ed03c --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_tolower.in @@ -0,0 +1 @@ +ABCÆØÅ diff --git a/contrib/netbsd-tests/usr.bin/awk/d_tolower.out b/contrib/netbsd-tests/usr.bin/awk/d_tolower.out new file mode 100644 index 0000000..83b2bf5 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_tolower.out @@ -0,0 +1 @@ +abcæøå diff --git a/contrib/netbsd-tests/usr.bin/awk/d_toupper.awk b/contrib/netbsd-tests/usr.bin/awk/d_toupper.awk new file mode 100644 index 0000000..0719aa9 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_toupper.awk @@ -0,0 +1,5 @@ +# $NetBSD: d_toupper.awk,v 1.1 2012/03/11 18:36:01 jruoho Exp $ + +END { + print toupper($0); +} diff --git a/contrib/netbsd-tests/usr.bin/awk/d_toupper.in b/contrib/netbsd-tests/usr.bin/awk/d_toupper.in new file mode 100644 index 0000000..83b2bf5 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_toupper.in @@ -0,0 +1 @@ +abcæøå diff --git a/contrib/netbsd-tests/usr.bin/awk/d_toupper.out b/contrib/netbsd-tests/usr.bin/awk/d_toupper.out new file mode 100644 index 0000000..66ed03c --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/d_toupper.out @@ -0,0 +1 @@ +ABCÆØÅ diff --git a/contrib/netbsd-tests/usr.bin/awk/t_awk.sh b/contrib/netbsd-tests/usr.bin/awk/t_awk.sh new file mode 100755 index 0000000..77cb5f8 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/awk/t_awk.sh @@ -0,0 +1,378 @@ +# $NetBSD: t_awk.sh,v 1.5 2012/12/10 20:30:06 christos Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Christos Zoulas +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +awk=awk + +h_check() +{ + local fname=d_$1 + for sfx in in out awk; do + cp -r $(atf_get_srcdir)/$fname.$sfx . + done + shift 1 + atf_check -o file:$fname.out -x "awk $@ -f $fname.awk < $fname.in" +} + +atf_test_case big_regexp + +big_regexp_head() { + atf_set "descr" "Checks matching long regular expressions (PR/33392)" +} + +big_regexp_body() { + h_check big_regexp +} + +atf_test_case end + +end_head() { + atf_set "descr" "Checks that the last line of the input" \ + "is available under END pattern (PR/29659)" +} + +end_body() { + h_check end1 + h_check end2 +} + +atf_test_case string1 + +string1_head() { + atf_set "descr" "Checks escaping newlines in string literals" +} + +string1_body() { + for sfx in out awk; do + cp -r $(atf_get_srcdir)/d_string1.$sfx . + done + atf_check -o file:d_string1.out awk -f d_string1.awk +} + +atf_test_case multibyte + +multibyte_head() { + atf_set "descr" "Checks multibyte charsets support" \ + "in tolower and toupper (PR/36394)" +} + +multibyte_body() { + export LANG=en_US.UTF-8 + + h_check tolower + h_check toupper +} + +atf_test_case period + +period_head() { + atf_set "descr" "Checks that the period character is recognised" \ + "in awk program regardless of locale (bin/42320)" +} + +period_body() { + export LANG=ru_RU.KOI8-R + + h_check period -v x=0.5 +} + +atf_test_case assign_NF + +assign_NF_head() { + atf_set "descr" 'Checks that assign to NF changes $0 and $n (PR/44063)' +} + +assign_NF_body() { + h_check assign_NF +} + +atf_test_case single_char_rs + +single_char_rs_head() { + atf_set "descr" "Test awk(1) with single character RS" +} + +single_char_rs_body() { + atf_check \ + -o "inline:1\n2\n\n3\n\n\n4\n\n" \ + -x "echo 1a2aa3aaa4 | $awk 1 RS=a" +} + +atf_test_case two_char_rs + +two_char_rs_head() { + atf_set "descr" "Test awk(1) with two characters RS" +} + +two_char_rs_body() { + atf_check \ + -o "inline:1\n2\n3\n4\n\n" \ + -x "echo 1ab2ab3ab4 | $awk 1 RS=ab" +} + +atf_test_case single_char_regex_group_rs + +single_char_regex_group_rs_head() { + atf_set "descr" "Test awk(1) with single character regex group RS" +} + +single_char_regex_group_rs_body() { + atf_check \ + -o "inline:1\n2\n\n3\n\n\n4\n\n" \ + -x "echo 1a2aa3aaa4 | $awk 1 RS='[a]'" +} + +atf_test_case two_char_regex_group_rs + +two_char_regex_group_rs_head() { + atf_set "descr" "Test awk(1) with two characters regex group RS" +} + +two_char_regex_group_rs_body() { + atf_check \ + -o "inline:1\n2\n\n3\n\n\n4\n\n" \ + -x "echo 1a2ab3aba4 | $awk 1 RS='[ab]'" +} + +atf_test_case single_char_regex_star_rs + +single_char_regex_star_rs_head() { + atf_set "descr" "Test awk(1) with single character regex star RS" +} + +single_char_regex_star_rs_body() { + atf_check \ + -o "inline:1\n2\n3\n4\n\n" \ + -x "echo 1a2aa3aaa4 | $awk 1 RS='a*'" +} + +atf_test_case two_char_regex_star_rs + +two_char_regex_star_rs_head() { + atf_set "descr" "Test awk(1) with two characters regex star RS" +} + +two_char_regex_star_rs_body() { + atf_check \ + -o "inline:1\n2\n3\n4\n\n" \ + -x "echo 1a2aa3aaa4 | $awk 1 RS='aa*'" +} + +atf_test_case regex_two_star_rs + +regex_two_star_rs_head() { + atf_set "descr" "Test awk(1) with regex two star RS" +} + +regex_two_star_rs_body() { + atf_check \ + -o "inline:1\n2\n3\n4\n\n" \ + -x "echo 1a2ab3aab4 | $awk 1 RS='aa*b*'" +} + +atf_test_case regex_or_1_rs + +regex_or_1_rs_head() { + atf_set "descr" "Test awk(1) with regex | case 1 RS" +} + +regex_or_1_rs_body() { + atf_check \ + -o "inline:1a\nc\n\n" \ + -x "echo 1abc | $awk 1 RS='abcde|b'" +} + +atf_test_case regex_or_2_rs + +regex_or_2_rs_head() { + atf_set "descr" "Test awk(1) with regex | case 2 RS" +} + +regex_or_2_rs_body() { + atf_check \ + -o "inline:1a\ncdf2\n\n" \ + -x "echo 1abcdf2 | $awk 1 RS='abcde|b'" +} + +atf_test_case regex_or_3_rs + +regex_or_3_rs_head() { + atf_set "descr" "Test awk(1) with regex | case 3 RS" +} + +regex_or_3_rs_body() { + atf_check \ + -o "inline:1\n\nf2\n\n" \ + -x "echo 1abcdebf2 | $awk 1 RS='abcde|b'" +} + +atf_test_case regex_or_4_rs + +regex_or_4_rs_head() { + atf_set "descr" "Test awk(1) with regex | case 4 RS" +} + +regex_or_4_rs_body() { + atf_check \ + -o "inline:1\nbcdf2\n\n" \ + -x "echo 1abcdf2 | $awk 1 RS='abcde|a'" + +} + +atf_test_case regex_caret_1_rs + +regex_caret_1_rs_head() { + atf_set "descr" "Test awk(1) with regex ^ case 1 RS" +} + +regex_caret_1_rs_body() { + atf_check \ + -o "inline:\n1a2a3a\n\n" \ + -x "echo a1a2a3a | $awk 1 RS='^a'" + +} + +atf_test_case regex_caret_2_rs + +regex_caret_2_rs_head() { + atf_set "descr" "Test awk(1) with regex ^ case 2 RS" +} + +regex_caret_2_rs_body() { + atf_check \ + -o "inline:\naa1a2a\n\n" \ + -x "echo aaa1a2a | $awk 1 RS='^a'" + +} + +atf_test_case regex_dollar_1_rs + +regex_dollar_1_rs_head() { + atf_set "descr" "Test awk(1) with regex $ case 1 RS" +} + +regex_dollar_1_rs_body() { + atf_check \ + -o "inline:a1a2a3a\n\n" \ + -x "echo a1a2a3a | $awk 1 RS='a$'" + +} + +atf_test_case regex_dollar_2_rs + +regex_dollar_2_rs_head() { + atf_set "descr" "Test awk(1) with regex $ case 2 RS" +} + +regex_dollar_2_rs_body() { + atf_check \ + -o "inline:a1a2aaa\n\n" \ + -x "echo a1a2aaa | $awk 1 RS='a$'" + +} + +atf_test_case regex_reallocation_rs + +regex_reallocation_rs_head() { + atf_set "descr" "Test awk(1) with regex reallocation RS" +} + +regex_reallocation_rs_body() { + atf_check \ + -o "inline:a\na\na\na\na\na\na\na\na\na10000\n\n" \ + -x "jot -s a 10000 | $awk 'NR>1' RS='999[0-9]'" + +} + +atf_test_case empty_rs + +empty_rs_head() { + atf_set "descr" "Test awk(1) with empty RS" +} + +empty_rs_body() { + atf_check \ + -o "inline:foo\n" \ + -x "echo foo | $awk 1 RS=''" + +} + +atf_test_case newline_rs + +newline_rs_head() { + atf_set "descr" "Test awk(1) with newline RS" +} + +newline_rs_body() { + atf_check \ + -o "inline:r1f1:r1f2\nr2f1:r2f2\n" \ + -x "printf '\n\n\nr1f1\nr1f2\n\nr2f1\nr2f2\n\n\n' | $awk '{\$1=\$1}1' RS= OFS=:" +} + +atf_test_case modify_subsep + +modify_subsep_head() { + atf_set "descr" "Test awk(1) SUPSEP modification (PR/47306)" +} + +modify_subsep_body() { + atf_check \ + -o "inline:1\n1\n1\n" \ + -x "printf '1\n1 2\n' | \ + $awk '1{ arr[\$1 SUBSEP \$2 SUBSEP ++cnt[\$1]]=1} {for (f in arr) print arr[f];}'" +} + +atf_init_test_cases() { + + atf_add_test_case big_regexp + atf_add_test_case end + atf_add_test_case string1 + atf_add_test_case multibyte + atf_add_test_case period + atf_add_test_case assign_NF + + atf_add_test_case single_char_rs + atf_add_test_case two_char_rs + atf_add_test_case single_char_regex_group_rs + atf_add_test_case two_char_regex_group_rs + atf_add_test_case two_char_regex_star_rs + atf_add_test_case single_char_regex_star_rs + atf_add_test_case regex_two_star_rs + atf_add_test_case regex_or_1_rs + atf_add_test_case regex_or_2_rs + atf_add_test_case regex_or_3_rs + atf_add_test_case regex_caret_1_rs + atf_add_test_case regex_caret_2_rs + atf_add_test_case regex_dollar_1_rs + atf_add_test_case regex_dollar_2_rs + atf_add_test_case regex_reallocation_rs + atf_add_test_case empty_rs + atf_add_test_case newline_rs + atf_add_test_case modify_subsep +} diff --git a/contrib/netbsd-tests/usr.bin/basename/t_basename.sh b/contrib/netbsd-tests/usr.bin/basename/t_basename.sh new file mode 100755 index 0000000..d22b7a9 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/basename/t_basename.sh @@ -0,0 +1,62 @@ +# $NetBSD: t_basename.sh,v 1.1 2012/03/17 16:33:12 jruoho Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() +{ + atf_set "descr" "Checks basic functionality" +} +basic_body() +{ + atf_check -o inline:"bin\n" basename /usr/bin + atf_check -o inline:"usr\n" basename /usr + atf_check -o inline:"/\n" basename / + atf_check -o inline:"/\n" basename /// + atf_check -o inline:"usr\n" basename /usr// + atf_check -o inline:"bin\n" basename //usr//bin + atf_check -o inline:"usr\n" basename usr + atf_check -o inline:"bin\n" basename usr/bin +} + +atf_test_case suffix +suffix_head() +{ + atf_set "descr" "Checks removing of provided suffix" +} +suffix_body() +{ + atf_check -o inline:"bi\n" basename /usr/bin n + atf_check -o inline:"bin\n" basename /usr/bin bin + atf_check -o inline:"/\n" basename / / + atf_check -o inline:"g\n" basename /usr/bin/gcc cc +} + +atf_init_test_cases() +{ + atf_add_test_case basic + atf_add_test_case suffix +} diff --git a/contrib/netbsd-tests/usr.bin/bzip2/t_bzip2.sh b/contrib/netbsd-tests/usr.bin/bzip2/t_bzip2.sh new file mode 100755 index 0000000..447fea9 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/bzip2/t_bzip2.sh @@ -0,0 +1,52 @@ +# $NetBSD: t_bzip2.sh,v 1.1 2012/03/17 16:33:12 jruoho Exp $ +# +# Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() +{ + atf_set "descr" "Checks basic functionality" +} +basic_body() +{ + atf_check -o file:$(atf_get_srcdir)/d_sample1.bz2 \ + bzip2 -1c $(atf_get_srcdir)/d_sample1.ref + atf_check -o file:$(atf_get_srcdir)/d_sample2.bz2 \ + bzip2 -2c $(atf_get_srcdir)/d_sample2.ref + atf_check -o file:$(atf_get_srcdir)/d_sample3.bz2 \ + bzip2 -3c $(atf_get_srcdir)/d_sample3.ref + atf_check -o file:$(atf_get_srcdir)/d_sample1.ref \ + bzip2 -dc $(atf_get_srcdir)/d_sample1.bz2 + atf_check -o file:$(atf_get_srcdir)/d_sample2.ref \ + bzip2 -dc $(atf_get_srcdir)/d_sample2.bz2 + atf_check -o file:$(atf_get_srcdir)/d_sample3.ref \ + bzip2 -dsc $(atf_get_srcdir)/d_sample3.bz2 +} + +atf_init_test_cases() +{ + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/usr.bin/cc/t_hello.sh b/contrib/netbsd-tests/usr.bin/cc/t_hello.sh new file mode 100755 index 0000000..6edc58b --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/cc/t_hello.sh @@ -0,0 +1,144 @@ +# $NetBSD: t_hello.sh,v 1.3 2016/04/03 14:41:30 gson Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case hello +hello_head() { + atf_set "descr" "compile and run \"hello world\"" + atf_set "require.progs" "cc" +} + +atf_test_case hello_pic +hello_pic_head() { + atf_set "descr" "compile and run PIC \"hello world\"" + atf_set "require.progs" "cc" +} + +atf_test_case hello_pie +hello_pie_head() { + atf_set "descr" "compile and run position independent (PIE) \"hello world\"" + atf_set "require.progs" "cc" +} + +atf_test_case hello32 +hello32_head() { + atf_set "descr" "compile and run \"hello world\" for/in netbsd32 emulation" + atf_set "require.progs" "cc file diff cat" +} + +hello_body() { + cat > test.c << EOF +#include +#include +int main(void) {printf("hello world\n");exit(0);} +EOF + atf_check -s exit:0 -o ignore -e ignore cc -o hello test.c + atf_check -s exit:0 -o inline:"hello world\n" ./hello +} + +hello_pic_body() { + cat > test.c << EOF +#include +int main(void) {callpic();exit(0);} +EOF + cat > pic.c << EOF +#include +int callpic(void) {printf("hello world\n");} +EOF + + atf_check -s exit:0 -o ignore -e ignore \ + cc -fPIC -dPIC -shared -o libtest.so pic.c + atf_check -s exit:0 -o ignore -e ignore \ + cc -o hello test.c -L. -ltest + + export LD_LIBRARY_PATH=. + atf_check -s exit:0 -o inline:"hello world\n" ./hello +} + +hello_pie_body() { + # check whether this arch supports -pie + if ! cc -pie -dM -E - < /dev/null 2>/dev/null >/dev/null; then + atf_skip "cc -pie not supported on this architecture" + fi + cat > test.c << EOF +#include +#include +int main(void) {printf("hello world\n");exit(0);} +EOF + atf_check -s exit:0 -o ignore -e ignore cc -fpie -pie -o hello test.c + atf_check -s exit:0 -o inline:"hello world\n" ./hello +} + +hello32_body() { + # check whether this arch is 64bit + if ! cc -dM -E - < /dev/null | fgrep -q _LP64; then + atf_skip "this is not a 64 bit architecture" + fi + if ! cc -m32 -dM -E - < /dev/null 2>/dev/null > ./def32; then + atf_skip "cc -m32 not supported on this architecture" + else + if fgrep -q _LP64 ./def32; then + atf_fail "cc -m32 does not generate netbsd32 binaries" + fi + fi + + cat > test.c << EOF +#include +#include +int main(void) {printf("hello world\n");exit(0);} +EOF + atf_check -s exit:0 -o ignore -e ignore cc -o hello32 -m32 test.c + atf_check -s exit:0 -o ignore -e ignore cc -o hello64 test.c + file -b ./hello32 > ./ftype32 + file -b ./hello64 > ./ftype64 + if diff ./ftype32 ./ftype64 >/dev/null; then + atf_fail "generated binaries do not differ" + fi + echo "32bit binaries on this platform are:" + cat ./ftype32 + echo "While native (64bit) binaries are:" + cat ./ftype64 + atf_check -s exit:0 -o inline:"hello world\n" ./hello32 + + # do another test with static 32bit binaries + cat > test.c << EOF +#include +#include +int main(void) {printf("hello static world\n");exit(0);} +EOF + atf_check -s exit:0 -o ignore -e ignore cc -o hello -m32 \ + -static test.c + atf_check -s exit:0 -o inline:"hello static world\n" ./hello +} + +atf_init_test_cases() +{ + + atf_add_test_case hello + atf_add_test_case hello_pic + atf_add_test_case hello_pie + atf_add_test_case hello32 +} diff --git a/contrib/netbsd-tests/usr.bin/cmp/t_cmp.sh b/contrib/netbsd-tests/usr.bin/cmp/t_cmp.sh new file mode 100755 index 0000000..341047f --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/cmp/t_cmp.sh @@ -0,0 +1,67 @@ +# $NetBSD: t_cmp.sh,v 1.1 2012/03/19 07:05:18 jruoho Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case missing +missing_head() { + atf_set "descr" "Test that cmp(1) with '-s' is silent " \ + "when files are missing (PR bin/2642)" +} + +missing_body() { + + echo a > a + + atf_check -s not-exit:0 -o empty -e empty -x "cmp -s a x" + atf_check -s not-exit:0 -o empty -e empty -x "cmp -s x a" + atf_check -s not-exit:0 -o empty -e empty -x "cmp -s x y" + atf_check -s not-exit:0 -o empty -e empty -x "cmp -s y x" +} + +atf_test_case skip +skip_head() { + atf_set "descr" "Test that cmp(1) handles skip " \ + "parameters correctly (PR bin/23836)" +} + +skip_body() { + + echo 0123456789abcdef > a + echo abcdef > b + + atf_check -s exit:0 -o empty -e empty -x "cmp a b '10'" + atf_check -s exit:0 -o empty -e empty -x "cmp a b '0xa'" + atf_check -s exit:1 -o not-empty -e empty -x "cmp a b '9'" +} + +atf_init_test_cases() +{ + atf_add_test_case missing + atf_add_test_case skip +} diff --git a/contrib/netbsd-tests/usr.bin/config/d_deffs_redef b/contrib/netbsd-tests/usr.bin/config/d_deffs_redef new file mode 100644 index 0000000..d84d1f7 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/config/d_deffs_redef @@ -0,0 +1,10 @@ +include "arch/regress/conf/std.regress" +maxusers 4 +file-system REGRESSFS + +master0 at root + +defflag NOT_A_FS +deffs NOT_A_FS + +config regress root on ? diff --git a/contrib/netbsd-tests/usr.bin/config/d_loop b/contrib/netbsd-tests/usr.bin/config/d_loop new file mode 100644 index 0000000..674a209 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/config/d_loop @@ -0,0 +1,23 @@ +include "arch/regress/conf/std.regress" +maxusers 4 +file-system REGRESSFS + +master0 at root + +# The following definitions build a loop of 'looper' devices. +# This tests how well the code that look for orphans handle loops. +# +# In that case, while the loopchild devices will always be seen in +# time, the code has to make sure it reaches all the loopbaby +# devices. + +looper0 at master0 +looper1 at looper0 + +loopchild0 at looper0 +loopchild1 at looper1 + +loopbaby0 at loopchild0 +loopbaby1 at loopchild1 + +config regress root on ? diff --git a/contrib/netbsd-tests/usr.bin/config/d_loop2 b/contrib/netbsd-tests/usr.bin/config/d_loop2 new file mode 100644 index 0000000..8e7238d --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/config/d_loop2 @@ -0,0 +1,16 @@ +include "arch/regress/conf/std.regress" +maxusers 4 +file-system REGRESSFS + +master0 at root + +# Devices that are their own parent must be handled properly +# when the instance is negated. + +looper* at master0 +looper* at looper? +looper1 at looper0 + +no looper* at looper? + +config regress root on ? diff --git a/contrib/netbsd-tests/usr.bin/config/d_min b/contrib/netbsd-tests/usr.bin/config/d_min new file mode 100644 index 0000000..4ccdbfc --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/config/d_min @@ -0,0 +1,6 @@ +include "arch/regress/conf/std.regress" +maxusers 4 + +master0 at root + +config regress root on ? diff --git a/contrib/netbsd-tests/usr.bin/config/d_no_pseudo b/contrib/netbsd-tests/usr.bin/config/d_no_pseudo new file mode 100644 index 0000000..9ee8564 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/config/d_no_pseudo @@ -0,0 +1,14 @@ +include "arch/regress/conf/std.regress" + +maxusers 4 + +file-system REGRESSFS + +master0 at root + +# Simply negating a pseudo-device should yield an error. + +pseudo-device pseudodev +no pseudodev + +config regress root on ? diff --git a/contrib/netbsd-tests/usr.bin/config/d_postponed_orphan b/contrib/netbsd-tests/usr.bin/config/d_postponed_orphan new file mode 100644 index 0000000..bb5ec04 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/config/d_postponed_orphan @@ -0,0 +1,21 @@ +include "arch/regress/conf/std.regress" + +maxusers 4 + +file-system REGRESSFS + +master0 at root + +parenti* at master? + +# Here, parenti is negated before the child* instance is declared. That +# means the child* instance does not qualify as an explicit orphan and +# therefore should _not_ be ignored. +# +# config(1) should error out on that config file. + +no parenti + +child* at parenti? + +config regress root on ? diff --git a/contrib/netbsd-tests/usr.bin/config/d_pseudo_parent b/contrib/netbsd-tests/usr.bin/config/d_pseudo_parent new file mode 100644 index 0000000..aebad8b --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/config/d_pseudo_parent @@ -0,0 +1,13 @@ +include "arch/regress/conf/std.regress" +maxusers 4 +file-system REGRESSFS + +# Pseudo-devices can have children on interface attributes, +# which means they don't necessarily have to explicitly +# define locators (see pseudodev definition). + +pseudo-device pseudodev + +child* at pseudodev? + +config regress root on ? diff --git a/contrib/netbsd-tests/usr.bin/config/d_shadow_instance b/contrib/netbsd-tests/usr.bin/config/d_shadow_instance new file mode 100644 index 0000000..6022821 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/config/d_shadow_instance @@ -0,0 +1,25 @@ +include "arch/regress/conf/std.regress" + +maxusers 4 + +file-system REGRESSFS + +master0 at root + +parenti* at master? +parentii* at master? + +# The second child* instance (attaching at parentii) is useless: it will be +# shadowed by the first one, which is semantically the same, from a parentii +# device's point of view. +# +# The two child* instances are aliases, and at some point the orphan-checking +# code skipped some aliases, in the shadowing situation and some others. +# +# This test should pass, the lines are valid, even though the second one is +# useless. + +child* at hook? +child* at parentii? + +config regress root on ? diff --git a/contrib/netbsd-tests/usr.bin/config/support/arch/regress/conf/files.regress b/contrib/netbsd-tests/usr.bin/config/support/arch/regress/conf/files.regress new file mode 100644 index 0000000..e9488d6 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/config/support/arch/regress/conf/files.regress @@ -0,0 +1,2 @@ +maxpartitions 8 +maxusers 2 4 8 diff --git a/contrib/netbsd-tests/usr.bin/config/support/arch/regress/conf/std.regress b/contrib/netbsd-tests/usr.bin/config/support/arch/regress/conf/std.regress new file mode 100644 index 0000000..f92baaf --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/config/support/arch/regress/conf/std.regress @@ -0,0 +1 @@ +machine regress diff --git a/contrib/netbsd-tests/usr.bin/config/support/conf/files b/contrib/netbsd-tests/usr.bin/config/support/conf/files new file mode 100644 index 0000000..01022ee --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/config/support/conf/files @@ -0,0 +1,41 @@ +deffs REGRESSFS + +device master { } +attach master at root + +define hook { } + +device parentii: hook +attach parentii at master +device parenti: hook +attach parenti at master + +device child +attach child at hook + +device looper { } +attach looper at master with looper_master +attach looper at looper with looper_looper + +device loopchild { } +attach loopchild at looper + +device loopbaby +attach loopbaby at loopchild + +defpseudo pseudodev: hook + +define a +file a.c a + +define b: a +file b.c b + +define c: b +file c.c c + +define i {} + +device d: i +attach d at root +file d.c d diff --git a/contrib/netbsd-tests/usr.bin/config/t_config.sh b/contrib/netbsd-tests/usr.bin/config/t_config.sh new file mode 100755 index 0000000..55af069 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/config/t_config.sh @@ -0,0 +1,278 @@ +# $NetBSD: t_config.sh,v 1.8 2016/08/27 12:08:14 christos Exp $ +# +# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +srcdir=.. +merge_backslash() +{ + sed ' +: again +/\\$/ { + N + s/\\\n// + t again +} +' "$1" +} +run_and_check_prep() +{ + local name="${1}"; shift + + mkdir -p compile + srcdir="$(atf_get_srcdir)" + if [ ! -d "${srcdir}/support" ]; then + srcdir="$(dirname "${srcdir}")" + if [ ! -d "${srcdir}/support" ]; then + atf_fail "bad source directory ${srcdir}" + exit 1 + fi + fi + supportdir="${srcdir}/support" + + local config_str + eval config_str=\$${name}_config_str + if [ -n "$config_str" ]; then + config="d_${name}" + printf "$config_str" >"${config}" + else + config="${srcdir}/d_${name}" + fi +} + +run_and_check_pass() +{ + local name="${1}"; shift + + run_and_check_prep "${name}" + + atf_check -o ignore -s eq:0 \ + config -s "${supportdir}" -b "compile/${name}" "${config}" +} + +run_and_check_warn() +{ + local name="${1}"; shift + + run_and_check_prep "${name}" + + local stderr + eval stderr=\$${name}_stderr + atf_check -o ignore -e "${stderr}" -s eq:0 \ + config -s "${supportdir}" -b "compile/${name}" "${config}" +} + +run_and_check_fail() +{ + local name="${1}"; shift + + run_and_check_prep "${name}" + + atf_check -o ignore -e ignore -s ne:0 \ + config -s "${supportdir}" -b "compile/${name}" "${config}" +} + +test_output() +{ + local name="${1}"; shift + local res=1 + + run_and_check_prep "${name}" + + config -s "${supportdir}" -b compile/"${name}" "${config}" >/dev/null && + cd compile/"${name}" && + check_${name} && + cd $OLDPWD && + res=0 + + atf_check test $res -eq 0 +} + +# Defines a test case for config(1). +test_case() +{ + local name="${1}"; shift + local type="${1}"; shift + local descr="${*}" + + atf_test_case "${name}" + eval "${name}_head() { \ + atf_set descr \"${descr}\"; \ + atf_set require.progs \"config\"; \ + }" + eval "${name}_body() { \ + run_and_check_${type} '${name}'; \ + }" +} + +test_case shadow_instance pass "Checks correct handling of shadowed instances" +test_case loop pass "Checks correct handling of loops" +test_case loop2 pass "Checks correct handling of devices that can be their" \ + "own parents" +test_case pseudo_parent pass "Checks correct handling of children of pseudo" \ + "devices (PR/32329)" +test_case postponed_orphan fail "Checks that config catches adding an" \ + "instance of a child of a negated instance as error" +test_case no_pseudo fail "Checks that config catches ommited 'pseudo-device'" \ + "as error (PR/34111)" +test_case deffs_redef fail "Checks that config doesn't allow a deffs to use" \ + "the same name as a previous defflag/defparam" + +# Selecting an undefined option. +undefined_opt_config_str=" +include \"${srcdir}/d_min\" +options UNDEFINED +" +test_case undefined_opt pass \ + "Checks that config allows a selection for an undefined options" + +# Negating an undefined option. +no_undefined_opt_config_str=" +include \"${srcdir}/d_min\" +no options UNDEFINED +" +no_undefined_opt_stderr='match:UNDEFINED' +test_case no_undefined_opt warn \ + "Checks that config allows a negation for an undefined options" + +# Attribute selection +test_case select pass "Attribute selection" +select_config_str=" +include \"${srcdir}/d_min\" +select c +" +check_select() +{ + local f=Makefile + + grep -q '^ a\.c ' $f && + grep -q '^ b\.c ' $f && + grep -q '^ c\.c ' $f && + : +} +select_body() { + test_output select +} + +# Attribute negation +test_case no_select pass "Attribute negation" +no_select_config_str=" +include \"${srcdir}/d_min\" +select c +no select a +" +check_no_select() +{ + local f=Makefile + + : >tmp + grep -q '^a\.o:' $f >>tmp + grep -q '^b\.o:' $f >>tmp + grep -q '^c\.o:' $f >>tmp + + [ ! -s tmp ] && + : +} +no_select_body() { + test_output no_select +} + +# Device instance +test_case devi pass "Device instance" +devi_config_str=" +include \"${srcdir}/d_min\" +d0 at root +" +check_devi() +{ + local f=ioconf.c + + sed -ne '/^struct cfdriver \* const cfdriver_list_initial\[\]/,/^};/p' $f >tmp.cfdriver + sed -ne '/^struct cfdata cfdata\[\]/,/^};/p' $f >tmp.cfdata + + grep -q '^CFDRIVER_DECL(d, ' $f && + grep -q '&d_cd,' tmp.cfdriver && + grep -q '^extern struct cfattach d_ca;$' $f && + grep -q '^static const struct cfiattrdata \* const d_attrs\[\]' $f && + grep -q '^static const struct cfiattrdata icf_iattrdata' $f && + grep -q '{ "d",' tmp.cfdata && + : +} +devi_body() { + test_output devi +} + +# Check minimal kernel config(1) output +test_case min pass "Minimal config" +check_min_files() +{ + test -e Makefile && + test -e config_file.h && + test -e config_time.src && + test -e ioconf.c && + test -e ioconf.h && + test -e locators.h && + test -e swapregress.c && + test -h machine && + test -h regress && + : +} +check_min_makefile() +{ + local f=Makefile + + grep -q '^%' $f >tmp.template + + grep -q '^MACHINE=regress$' $f && + (merge_backslash $f | grep -q '^IDENT=[ ]*-DMAXUSERS="4"') && + [ ! -s tmp.template ] && + : +} +check_min() +{ + check_min_files && + check_min_makefile && + : +} +min_body() { + test_output min +} + +atf_init_test_cases() +{ + atf_add_test_case shadow_instance + atf_add_test_case loop + atf_add_test_case loop2 + atf_add_test_case pseudo_parent + atf_add_test_case postponed_orphan + atf_add_test_case no_pseudo + atf_add_test_case deffs_redef + atf_add_test_case undefined_opt + atf_add_test_case no_undefined_opt + atf_add_test_case select + atf_add_test_case no_select + atf_add_test_case devi + atf_add_test_case min +} diff --git a/contrib/netbsd-tests/usr.bin/cut/d_basic.out b/contrib/netbsd-tests/usr.bin/cut/d_basic.out new file mode 100644 index 0000000..f704cdf --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/cut/d_basic.out @@ -0,0 +1,88 @@ +----- test: cut -f 1 d_cut.in ----- +1 + +12 + +qwe +1 + +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl:zxc:vbn:nm +:qwe:::rty:uio::p[]:asd:fgh:jkl:zxc:vbn:nm +----- test: cut -f 2 d_cut.in ----- +1 + +34 +12 + +1 + +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl:zxc:vbn:nm +:qwe:::rty:uio::p[]:asd:fgh:jkl:zxc:vbn:nm +----- test: cut -f 3 d_cut.in ----- +1 + +56 + +rty +1 + +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl:zxc:vbn:nm +:qwe:::rty:uio::p[]:asd:fgh:jkl:zxc:vbn:nm +----- test: cut -f 1-2 d_cut.in ----- +1 + +12 34 + 12 +qwe +1 + +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl:zxc:vbn:nm +:qwe:::rty:uio::p[]:asd:fgh:jkl:zxc:vbn:nm +----- test: cut -f 2,3 d_cut.in ----- +1 + +34 56 +12 + rty +1 + +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl:zxc:vbn:nm +:qwe:::rty:uio::p[]:asd:fgh:jkl:zxc:vbn:nm +----- test: cut -f 4 d_cut.in ----- +1 + + +34 +uio +1 + +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl:zxc:vbn:nm +:qwe:::rty:uio::p[]:asd:fgh:jkl:zxc:vbn:nm +----- test: cut -f 1-3,4-7 d_cut.in ----- +1 + +12 34 56 + 12 34 56 +qwe rty uio p[] asd +1 + +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl:zxc:vbn:nm +:qwe:::rty:uio::p[]:asd:fgh:jkl:zxc:vbn:nm +----- test: cut -f 1,2-7 d_cut.in ----- +1 + +12 34 56 + 12 34 56 +qwe rty uio p[] asd +1 + +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl:zxc:vbn:nm +:qwe:::rty:uio::p[]:asd:fgh:jkl:zxc:vbn:nm diff --git a/contrib/netbsd-tests/usr.bin/cut/d_cut.in b/contrib/netbsd-tests/usr.bin/cut/d_cut.in new file mode 100644 index 0000000..85b4184 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/cut/d_cut.in @@ -0,0 +1,10 @@ +1 + +12 34 56 + 12 34 56 +qwe rty uio p[] asd fgh jkl zxc vbn nm +1 + +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl:zxc:vbn:nm +:qwe:::rty:uio::p[]:asd:fgh:jkl:zxc:vbn:nm diff --git a/contrib/netbsd-tests/usr.bin/cut/d_dflag.out b/contrib/netbsd-tests/usr.bin/cut/d_dflag.out new file mode 100644 index 0000000..63b814f --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/cut/d_dflag.out @@ -0,0 +1,88 @@ +----- test: cut -f 1 -d : d_cut.in ----- +1 + +12 34 56 + 12 34 56 +qwe rty uio p[] asd fgh jkl zxc vbn nm +1 + +12 +qwe + +----- test: cut -f 2 -d : d_cut.in ----- +1 + +12 34 56 + 12 34 56 +qwe rty uio p[] asd fgh jkl zxc vbn nm +1 + +34 +rty +qwe +----- test: cut -f 3 -d : d_cut.in ----- +1 + +12 34 56 + 12 34 56 +qwe rty uio p[] asd fgh jkl zxc vbn nm +1 + +56 +uio + +----- test: cut -f 1-2 -d : d_cut.in ----- +1 + +12 34 56 + 12 34 56 +qwe rty uio p[] asd fgh jkl zxc vbn nm +1 + +12:34 +qwe:rty +:qwe +----- test: cut -f 2,3 -d : d_cut.in ----- +1 + +12 34 56 + 12 34 56 +qwe rty uio p[] asd fgh jkl zxc vbn nm +1 + +34:56 +rty:uio +qwe: +----- test: cut -f 4 -d : d_cut.in ----- +1 + +12 34 56 + 12 34 56 +qwe rty uio p[] asd fgh jkl zxc vbn nm +1 + + +p[] + +----- test: cut -f 1-3,4-7 -d : d_cut.in ----- +1 + +12 34 56 + 12 34 56 +qwe rty uio p[] asd fgh jkl zxc vbn nm +1 + +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl +:qwe:::rty:uio: +----- test: cut -f 1,2-7 -d : d_cut.in ----- +1 + +12 34 56 + 12 34 56 +qwe rty uio p[] asd fgh jkl zxc vbn nm +1 + +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl +:qwe:::rty:uio: diff --git a/contrib/netbsd-tests/usr.bin/cut/d_dsflag.out b/contrib/netbsd-tests/usr.bin/cut/d_dsflag.out new file mode 100644 index 0000000..e3d1beb --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/cut/d_dsflag.out @@ -0,0 +1,32 @@ +----- test: cut -f 1 -d : -s d_cut.in ----- +12 +qwe + +----- test: cut -f 2 -d : -s d_cut.in ----- +34 +rty +qwe +----- test: cut -f 3 -d : -s d_cut.in ----- +56 +uio + +----- test: cut -f 1-2 -d : -s d_cut.in ----- +12:34 +qwe:rty +:qwe +----- test: cut -f 2,3 -d : -s d_cut.in ----- +34:56 +rty:uio +qwe: +----- test: cut -f 4 -d : -s d_cut.in ----- + +p[] + +----- test: cut -f 1-3,4-7 -d : -s d_cut.in ----- +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl +:qwe:::rty:uio: +----- test: cut -f 1,2-7 -d : -s d_cut.in ----- +12:34:56 +qwe:rty:uio:p[]:asd:fgh:jkl +:qwe:::rty:uio: diff --git a/contrib/netbsd-tests/usr.bin/cut/d_latin1.in b/contrib/netbsd-tests/usr.bin/cut/d_latin1.in new file mode 100644 index 0000000..00255b1 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/cut/d_latin1.in @@ -0,0 +1,4 @@ +foo�:bar:�baz +Foo�:Bar:�Baz +FOo�:BAr:�BAz +FOO�:BAR:�BAZ diff --git a/contrib/netbsd-tests/usr.bin/cut/d_sflag.out b/contrib/netbsd-tests/usr.bin/cut/d_sflag.out new file mode 100644 index 0000000..88c2b3e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/cut/d_sflag.out @@ -0,0 +1,32 @@ +----- test: cut -f 1 -s d_cut.in ----- +12 + +qwe +----- test: cut -f 2 -s d_cut.in ----- +34 +12 + +----- test: cut -f 3 -s d_cut.in ----- +56 + +rty +----- test: cut -f 1-2 -s d_cut.in ----- +12 34 + 12 +qwe +----- test: cut -f 2,3 -s d_cut.in ----- +34 56 +12 + rty +----- test: cut -f 4 -s d_cut.in ----- + +34 +uio +----- test: cut -f 1-3,4-7 -s d_cut.in ----- +12 34 56 + 12 34 56 +qwe rty uio p[] asd +----- test: cut -f 1,2-7 -s d_cut.in ----- +12 34 56 + 12 34 56 +qwe rty uio p[] asd diff --git a/contrib/netbsd-tests/usr.bin/cut/d_utf8.in b/contrib/netbsd-tests/usr.bin/cut/d_utf8.in new file mode 100644 index 0000000..320a063 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/cut/d_utf8.in @@ -0,0 +1,4 @@ +fooÄ:bar:Äbaz +FooÄ:Bar:ÄBaz +FOoÄ:BAr:ÄBAz +FOOÄ:BAR:ÄBAZ diff --git a/contrib/netbsd-tests/usr.bin/cut/t_cut.sh b/contrib/netbsd-tests/usr.bin/cut/t_cut.sh new file mode 100755 index 0000000..3c3793f --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/cut/t_cut.sh @@ -0,0 +1,130 @@ +# $NetBSD: t_cut.sh,v 1.1 2012/03/17 16:33:13 jruoho Exp $ +# +# Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +h_run() +{ + file="${1}"; shift + opts="${*}" + + for fields in 1 2 3 1-2 2,3 4 1-3,4-7 1,2-7 + do + opts="-f ${fields} $@" + echo "----- test: cut ${opts} $(basename $file) -----" + cut $opts "$file" || atf_fail "command failed: cut ${opts} $file" + done +} + +h_check() +{ + diff -Nru "$1" "$2" || atf_fail "files $1 and $2 differ" +} + +atf_test_case basic +basic_head() +{ + atf_set "descr" "Checks basic functionality" +} +basic_body() +{ + h_run "$(atf_get_srcdir)/d_cut.in" > out + h_check out "$(atf_get_srcdir)/d_basic.out" +} + +atf_test_case sflag +sflag_head() +{ + atf_set "descr" "Checks -s flag" +} +sflag_body() +{ + h_run "$(atf_get_srcdir)/d_cut.in" -s > out + h_check out "$(atf_get_srcdir)/d_sflag.out" +} + +atf_test_case dflag +dflag_head() +{ + atf_set "descr" "Checks -d flag" +} +dflag_body() +{ + h_run "$(atf_get_srcdir)/d_cut.in" -d ":" > out + h_check out "$(atf_get_srcdir)/d_dflag.out" +} + +atf_test_case dsflag +dsflag_head() +{ + atf_set "descr" "Checks -s and -d flags combined" +} +dsflag_body() +{ + h_run "$(atf_get_srcdir)/d_cut.in" -d ":" -s > out + h_check out "$(atf_get_srcdir)/d_dsflag.out" +} + +atf_test_case latin1 +latin1_head() +{ + atf_set "descr" "Checks support for non-ascii characters" +} +latin1_body() +{ + export LC_ALL=C + + atf_check -o inline:"bar\nBar\nBAr\nBAR\n" \ + cut -b 6,7,8 "$(atf_get_srcdir)/d_latin1.in" + + atf_check -o inline:"bar\nBar\nBAr\nBAR\n" \ + cut -c 6,7,8 "$(atf_get_srcdir)/d_latin1.in" +} + +atf_test_case utf8 +utf8_head() +{ + atf_set "descr" "Checks support for multibyte characters" +} +utf8_body() +{ + export LC_ALL=en_US.UTF-8 + + atf_check -o inline:":ba\n:Ba\n:BA\n:BA\n" \ + cut -b 6,7,8 "$(atf_get_srcdir)/d_utf8.in" + + atf_check -o inline:"bar\nBar\nBAr\nBAR\n" \ + cut -c 6,7,8 "$(atf_get_srcdir)/d_utf8.in" +} + +atf_init_test_cases() +{ + atf_add_test_case basic + atf_add_test_case sflag + atf_add_test_case dflag + atf_add_test_case dsflag + atf_add_test_case latin1 + atf_add_test_case utf8 +} diff --git a/contrib/netbsd-tests/usr.bin/diff/d_mallocv1.in b/contrib/netbsd-tests/usr.bin/diff/d_mallocv1.in new file mode 100644 index 0000000..27ab503 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/diff/d_mallocv1.in @@ -0,0 +1,5 @@ +18086b1e91f730facb2d6e1b +c562653b24814eb3651b1e68301a3c14b96302bb +6d017f7aef74662ed8dd51eef14281eaad223298db370bfaca +30c04231cb3de404e4b8a5359a74066fd963291d7986be835834ab07870c097682a953bfff38784780eef844de47fb36c34f8e034c96cfa64d9cb5decee472138236e9fb79e9fe1fba6b7757b970f22477d167832206900473f09f3e8c822db6d9a8273340ed6743d99638d6cf192d821b6f33d23278b1a929f303a80865c426d01add11b2f2416babd13e70b44d8eeb731c09c7163af9d1a23cbe20ddb08b0f67ecaa2eed511263a67e9c12e59ef113f0b9e4e4e140b43896078a7571c61826ba099b3dd8c4b096a9785b4434e97ea99e662ba6fdb60a41547ccae4c67d3e1f3ef515198e91f009c75c9e80fda90d13ee29d8aad5d87cc2437ce60e6ce55700837fb0815bfd2495f8aa1a33fe67c1ae28a885506a78ca6257f5a5f2a8042e28680acc83b1aecb3a9cb51911126f2f0deaf14fcfa5f165e9a5c3f8f2d1c3f4683b2d75927a7bc802d63b680a5e22768cc0439854ccd49e58a002794f541bddd6ef6fbd4f9869843a72d0ae9d438c90353a46c0c9863a16b1de206c717ab7ce6ea6f648a38efa12b70bbe3388b35adec7a789ea98de217520d7d6ce699841e17e5946bf5a8b3c7a2c3e2d6767422baf3159ff08d913ec78011ab7d34bc24af26c24a8d46f7261c7705a7b270e27590c29583c659a0df8dada4e7a0532f115040165d18f74a55a4f39bb1dcfd865e94a + 488ca910cc447e121b2a19450239e75d24 diff --git a/contrib/netbsd-tests/usr.bin/diff/d_mallocv2.in b/contrib/netbsd-tests/usr.bin/diff/d_mallocv2.in new file mode 100644 index 0000000..27ab503 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/diff/d_mallocv2.in @@ -0,0 +1,5 @@ +18086b1e91f730facb2d6e1b +c562653b24814eb3651b1e68301a3c14b96302bb +6d017f7aef74662ed8dd51eef14281eaad223298db370bfaca +30c04231cb3de404e4b8a5359a74066fd963291d7986be835834ab07870c097682a953bfff38784780eef844de47fb36c34f8e034c96cfa64d9cb5decee472138236e9fb79e9fe1fba6b7757b970f22477d167832206900473f09f3e8c822db6d9a8273340ed6743d99638d6cf192d821b6f33d23278b1a929f303a80865c426d01add11b2f2416babd13e70b44d8eeb731c09c7163af9d1a23cbe20ddb08b0f67ecaa2eed511263a67e9c12e59ef113f0b9e4e4e140b43896078a7571c61826ba099b3dd8c4b096a9785b4434e97ea99e662ba6fdb60a41547ccae4c67d3e1f3ef515198e91f009c75c9e80fda90d13ee29d8aad5d87cc2437ce60e6ce55700837fb0815bfd2495f8aa1a33fe67c1ae28a885506a78ca6257f5a5f2a8042e28680acc83b1aecb3a9cb51911126f2f0deaf14fcfa5f165e9a5c3f8f2d1c3f4683b2d75927a7bc802d63b680a5e22768cc0439854ccd49e58a002794f541bddd6ef6fbd4f9869843a72d0ae9d438c90353a46c0c9863a16b1de206c717ab7ce6ea6f648a38efa12b70bbe3388b35adec7a789ea98de217520d7d6ce699841e17e5946bf5a8b3c7a2c3e2d6767422baf3159ff08d913ec78011ab7d34bc24af26c24a8d46f7261c7705a7b270e27590c29583c659a0df8dada4e7a0532f115040165d18f74a55a4f39bb1dcfd865e94a + 488ca910cc447e121b2a19450239e75d24 diff --git a/contrib/netbsd-tests/usr.bin/diff/t_diff.sh b/contrib/netbsd-tests/usr.bin/diff/t_diff.sh new file mode 100755 index 0000000..e33edee --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/diff/t_diff.sh @@ -0,0 +1,75 @@ +# $NetBSD: t_diff.sh,v 1.3 2012/03/13 05:40:00 jruoho Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case mallocv +mallocv_head() { + atf_set "descr" "Test diff(1) with MALLOC_OPTIONS=V (cf. PR bin/26453)" +} + +mallocv_body() { + + atf_check -s ignore \ + -e not-inline:"diff: memory exhausted\n" \ + -x "env MALLOC_OPTIONS=V diff " \ + "$(atf_get_srcdir)/d_mallocv1.in" \ + "$(atf_get_srcdir)/d_mallocv2.in" +} + +atf_test_case nomallocv +nomallocv_head() { + atf_set "descr" "Test diff(1) with no MALLOC_OPTIONS=V" +} + +nomallocv_body() { + + atf_check -s exit:0 \ + -e inline:"" \ + -x "diff " \ + "$(atf_get_srcdir)/d_mallocv1.in" \ + "$(atf_get_srcdir)/d_mallocv2.in" +} + +atf_test_case same +same_head() { + atf_set "descr" "Test diff(1) with identical files" +} + +same_body() { + + atf_check -s exit:0 \ + -e inline:"" \ + -x "diff $(atf_get_srcdir)/t_diff $(atf_get_srcdir)/t_diff" +} + +atf_init_test_cases() { + atf_add_test_case mallocv + atf_add_test_case nomallocv + atf_add_test_case same +} diff --git a/contrib/netbsd-tests/usr.bin/dirname/t_dirname.sh b/contrib/netbsd-tests/usr.bin/dirname/t_dirname.sh new file mode 100755 index 0000000..a393524 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/dirname/t_dirname.sh @@ -0,0 +1,49 @@ +# $NetBSD: t_dirname.sh,v 1.1 2012/03/17 16:33:13 jruoho Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() +{ + atf_set "descr" "Checks basic functionality" +} +basic_body() +{ + atf_check -o inline:"/\n" dirname / + atf_check -o inline:"/\n" dirname // + atf_check -o inline:"/usr\n" dirname /usr/bin/ + atf_check -o inline:"//usr\n" dirname //usr//bin// + atf_check -o inline:".\n" dirname usr + atf_check -o inline:".\n" dirname "" + atf_check -o inline:"/\n" dirname /usr + atf_check -o inline:"/usr\n" dirname /usr/bin + atf_check -o inline:"usr\n" dirname usr/bin +} + +atf_init_test_cases() +{ + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/usr.bin/find/t_find.sh b/contrib/netbsd-tests/usr.bin/find/t_find.sh new file mode 100755 index 0000000..b30de5e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/find/t_find.sh @@ -0,0 +1,73 @@ +# $NetBSD: t_find.sh,v 1.6 2012/03/19 12:58:41 jruoho Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case emptyperm +emptyperm_head() { + atf_set "descr" "Test that 'find -empty' does not error out " \ + "when directory access is denied (PR bin/44179)" + atf_set "require.user" "unprivileged" +} + +emptyperm_body() { + + # The case assumes that at least some directories + # in /var are unavailable for the user '_tests'. + # + # TODO: Parse the output.file for actual verification. + # + atf_check -s exit:1 -o save:output.file \ + -e not-empty -x "find /var -empty -type d" +} + +atf_test_case exit +exit_head() { + atf_set "descr" "Test that find(1) with -exit works (PR bin/44973)" +} + +exit_body() { + atf_check -o ignore \ + -s exit:0 -x "find /etc -type f -exit" +} + +atf_test_case exit_status +exit_status_head() { + atf_set "descr" "Test exit status from 'find -exit'" +} + +exit_status_body() { + num=$(jot -r 1 0 99) + atf_check -o ignore -e ignore -s exit:$num -x "find / -exit $num" +} + +atf_init_test_cases() { + atf_add_test_case emptyperm + atf_add_test_case exit + atf_add_test_case exit_status +} diff --git a/contrib/netbsd-tests/usr.bin/gdb/t_regress.sh b/contrib/netbsd-tests/usr.bin/gdb/t_regress.sh new file mode 100755 index 0000000..5ea8713 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/gdb/t_regress.sh @@ -0,0 +1,77 @@ +# $NetBSD: t_regress.sh,v 1.1 2016/04/08 10:09:16 gson Exp $ +# +# Copyright (c) 2016 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# Regression tests for some GDB PRs + +# PR 47430 + +atf_test_case threads +threads_head() { + atf_set "descr" "Test that gdb works with threaded programs" + atf_set "require.progs" "gdb" +} +threads_body() { + # Dig at an unused IP address so that dig fails the + # same way on machines with Internet connectivity + # as on those without. + cat <test.gdb +run +time=1 +tries=1 @127.0.0.177 +cont +cont +cont +cont +cont +EOF + gdb --batch -x test.gdb dig >gdb.out + atf_check -s exit:1 -o ignore -e ignore grep "Program received signal SIGTRAP" gdb.out +} + +# PR 48250 + +atf_test_case pie +pie_head() { + atf_set "descr" "Test that gdb works with PIE executables" + atf_set "require.progs" "cc gdb" +} +pie_body() { + cat <<\EOF >test.c +#include +int main(int argc, char **argv) { printf ("hello\n"); return 0; } +EOF + cc -fpie -pie -g test.c -o test + cat <test.gdb +break main +run +EOF + gdb --batch -x test.gdb ./test >gdb.out 2>&1 + atf_check -s exit:1 -o ignore -e ignore grep "annot access memory" gdb.out +} + +atf_init_test_cases() { + atf_add_test_case threads + atf_add_test_case pie +} diff --git a/contrib/netbsd-tests/usr.bin/grep/d_basic.out b/contrib/netbsd-tests/usr.bin/grep/d_basic.out new file mode 100644 index 0000000..ccefccb --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_basic.out @@ -0,0 +1,20 @@ +123 +1123 +1230 +1231 +1232 +1233 +1234 +1235 +1236 +1237 +1238 +1239 +2123 +3123 +4123 +5123 +6123 +7123 +8123 +9123 diff --git a/contrib/netbsd-tests/usr.bin/grep/d_begin_end_a.out b/contrib/netbsd-tests/usr.bin/grep/d_begin_end_a.out new file mode 100644 index 0000000..3288aec --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_begin_end_a.out @@ -0,0 +1 @@ +Front of the line diff --git a/contrib/netbsd-tests/usr.bin/grep/d_begin_end_b.out b/contrib/netbsd-tests/usr.bin/grep/d_begin_end_b.out new file mode 100644 index 0000000..dd09e02 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_begin_end_b.out @@ -0,0 +1 @@ +This is a another line with a Front and an ending diff --git a/contrib/netbsd-tests/usr.bin/grep/d_binary.out b/contrib/netbsd-tests/usr.bin/grep/d_binary.out new file mode 100644 index 0000000..f0ef988 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_binary.out @@ -0,0 +1 @@ +Binary file test.file matches diff --git a/contrib/netbsd-tests/usr.bin/grep/d_context2_a.out b/contrib/netbsd-tests/usr.bin/grep/d_context2_a.out new file mode 100644 index 0000000..384d280 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_context2_a.out Binary files differ diff --git a/contrib/netbsd-tests/usr.bin/grep/d_context2_b.out b/contrib/netbsd-tests/usr.bin/grep/d_context2_b.out new file mode 100644 index 0000000..c1d1222 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_context2_b.out Binary files differ diff --git a/contrib/netbsd-tests/usr.bin/grep/d_context2_c.out b/contrib/netbsd-tests/usr.bin/grep/d_context2_c.out new file mode 100644 index 0000000..1692c2a --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_context2_c.out Binary files differ diff --git a/contrib/netbsd-tests/usr.bin/grep/d_context_a.in b/contrib/netbsd-tests/usr.bin/grep/d_context_a.in new file mode 100644 index 0000000..670e4ce --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_context_a.in @@ -0,0 +1,10 @@ +A pig is a jolly companion, +Boar, sow, barrow, or gilt -- +A pig is a pal, who'll boost your morale, +Though mountains may topple and tilt. +When they've blackballed, bamboozled, and burned you, +When they've turned on you, Tory and Whig, +Though you may be thrown over by Tabby and Rover, +You'll never go wrong with a pig, a pig, +You'll never go wrong with a pig! + -- Thomas Pynchon, "Gravity's Rainbow" diff --git a/contrib/netbsd-tests/usr.bin/grep/d_context_a.out b/contrib/netbsd-tests/usr.bin/grep/d_context_a.out new file mode 100644 index 0000000..5788aa5 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_context_a.out @@ -0,0 +1,5 @@ +A pig is a pal, who'll boost your morale, +Though mountains may topple and tilt. +When they've blackballed, bamboozled, and burned you, +When they've turned on you, Tory and Whig, +Though you may be thrown over by Tabby and Rover, diff --git a/contrib/netbsd-tests/usr.bin/grep/d_context_b.in b/contrib/netbsd-tests/usr.bin/grep/d_context_b.in new file mode 100644 index 0000000..663c992 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_context_b.in @@ -0,0 +1,3 @@ +This is to test output of context from multiple files. +Dave was a happy pig who wandered around the orchard eating +apples all day long. diff --git a/contrib/netbsd-tests/usr.bin/grep/d_context_b.out b/contrib/netbsd-tests/usr.bin/grep/d_context_b.out new file mode 100644 index 0000000..aa18352 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_context_b.out @@ -0,0 +1,4 @@ +Though mountains may topple and tilt. +When they've blackballed, bamboozled, and burned you, +When they've turned on you, Tory and Whig, +Though you may be thrown over by Tabby and Rover, diff --git a/contrib/netbsd-tests/usr.bin/grep/d_context_c.out b/contrib/netbsd-tests/usr.bin/grep/d_context_c.out new file mode 100644 index 0000000..f91b712 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_context_c.out @@ -0,0 +1,5 @@ +Boar, sow, barrow, or gilt -- +A pig is a pal, who'll boost your morale, +Though mountains may topple and tilt. +When they've blackballed, bamboozled, and burned you, +When they've turned on you, Tory and Whig, diff --git a/contrib/netbsd-tests/usr.bin/grep/d_context_d.out b/contrib/netbsd-tests/usr.bin/grep/d_context_d.out new file mode 100644 index 0000000..225df69 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_context_d.out @@ -0,0 +1,13 @@ +d_context_a.in:A pig is a jolly companion, +d_context_a.in-Boar, sow, barrow, or gilt -- +d_context_a.in:A pig is a pal, who'll boost your morale, +d_context_a.in-Though mountains may topple and tilt. +-- +d_context_a.in-Though you may be thrown over by Tabby and Rover, +d_context_a.in:You'll never go wrong with a pig, a pig, +d_context_a.in:You'll never go wrong with a pig! +d_context_a.in- -- Thomas Pynchon, "Gravity's Rainbow" +-- +d_context_b.in-This is to test output of context from multiple files. +d_context_b.in:Dave was a happy pig who wandered around the orchard eating +d_context_b.in-apples all day long. diff --git a/contrib/netbsd-tests/usr.bin/grep/d_egrep.out b/contrib/netbsd-tests/usr.bin/grep/d_egrep.out new file mode 100644 index 0000000..2cc0277 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_egrep.out @@ -0,0 +1 @@ +Special characters [, $, ^, * diff --git a/contrib/netbsd-tests/usr.bin/grep/d_file_exp.in b/contrib/netbsd-tests/usr.bin/grep/d_file_exp.in new file mode 100644 index 0000000..9faee93 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_file_exp.in @@ -0,0 +1,2 @@ +-0.[24]0 +0.[35]0 diff --git a/contrib/netbsd-tests/usr.bin/grep/d_file_exp.out b/contrib/netbsd-tests/usr.bin/grep/d_file_exp.out new file mode 100644 index 0000000..7d97522 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_file_exp.out @@ -0,0 +1,6 @@ +-0.50 +-0.40 +-0.30 +-0.20 +0.30 +0.50 diff --git a/contrib/netbsd-tests/usr.bin/grep/d_ignore_case.out b/contrib/netbsd-tests/usr.bin/grep/d_ignore_case.out new file mode 100644 index 0000000..c14d8dd --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_ignore_case.out @@ -0,0 +1,2 @@ +Mostly I prefer lower case to upper case, +but UpPeR cAsE has its merits too. diff --git a/contrib/netbsd-tests/usr.bin/grep/d_input b/contrib/netbsd-tests/usr.bin/grep/d_input new file mode 100644 index 0000000..5e38c39 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_input @@ -0,0 +1,12 @@ +dot.separated@words +kkseparatedkk +Front of the line +This is a another line with a Front and an ending +Special characters [, $, ^, * +Here is another ending. + +Mostly I prefer lower case to upper case, +but UpPeR cAsE has its merits too. + +matchme + diff --git a/contrib/netbsd-tests/usr.bin/grep/d_invert.in b/contrib/netbsd-tests/usr.bin/grep/d_invert.in new file mode 100644 index 0000000..631cf83 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_invert.in @@ -0,0 +1,10 @@ + +fish +fish +dog +cat +fish +fish + +poodle +fish diff --git a/contrib/netbsd-tests/usr.bin/grep/d_invert.out b/contrib/netbsd-tests/usr.bin/grep/d_invert.out new file mode 100644 index 0000000..7d7c54a --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_invert.out @@ -0,0 +1,5 @@ + +dog +cat + +poodle diff --git a/contrib/netbsd-tests/usr.bin/grep/d_recurse.out b/contrib/netbsd-tests/usr.bin/grep/d_recurse.out new file mode 100644 index 0000000..0ba61c8 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_recurse.out @@ -0,0 +1,2 @@ +recurse/a/f/favourite-fish:haddock +recurse/d/fish:haddock diff --git a/contrib/netbsd-tests/usr.bin/grep/d_recurse_symlink.err b/contrib/netbsd-tests/usr.bin/grep/d_recurse_symlink.err new file mode 100644 index 0000000..b4bff98 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_recurse_symlink.err @@ -0,0 +1 @@ +grep: warning: test/c/d/d: recursive directory loop diff --git a/contrib/netbsd-tests/usr.bin/grep/d_recurse_symlink.out b/contrib/netbsd-tests/usr.bin/grep/d_recurse_symlink.out new file mode 100644 index 0000000..2849239 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_recurse_symlink.out @@ -0,0 +1 @@ +test/c/match:Test string diff --git a/contrib/netbsd-tests/usr.bin/grep/d_whole_line.out b/contrib/netbsd-tests/usr.bin/grep/d_whole_line.out new file mode 100644 index 0000000..16febeb --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_whole_line.out @@ -0,0 +1 @@ +matchme diff --git a/contrib/netbsd-tests/usr.bin/grep/d_word_regexps.out b/contrib/netbsd-tests/usr.bin/grep/d_word_regexps.out new file mode 100644 index 0000000..e6c4af4 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_word_regexps.out @@ -0,0 +1 @@ +dot.separated@words diff --git a/contrib/netbsd-tests/usr.bin/grep/d_zgrep.out b/contrib/netbsd-tests/usr.bin/grep/d_zgrep.out new file mode 100644 index 0000000..c5fe9b8 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/d_zgrep.out @@ -0,0 +1,2 @@ +Front of the line +This is a another line with a Front and an ending diff --git a/contrib/netbsd-tests/usr.bin/grep/t_grep.sh b/contrib/netbsd-tests/usr.bin/grep/t_grep.sh new file mode 100755 index 0000000..558b074 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/grep/t_grep.sh @@ -0,0 +1,248 @@ +# $NetBSD: t_grep.sh,v 1.3 2017/01/14 20:43:52 christos Exp $ +# +# Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() +{ + atf_set "descr" "Checks basic functionality" +} +basic_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_basic.out" -x \ + 'jot 10000 | grep 123' +} + +atf_test_case binary +binary_head() +{ + atf_set "descr" "Checks handling of binary files" +} +binary_body() +{ + dd if=/dev/zero count=1 of=test.file + echo -n "foobar" >> test.file + atf_check -o file:"$(atf_get_srcdir)/d_binary.out" grep foobar test.file +} + +atf_test_case recurse +recurse_head() +{ + atf_set "descr" "Checks recursive searching" +} +recurse_body() +{ + mkdir -p recurse/a/f recurse/d + echo -e "cod\ndover sole\nhaddock\nhalibut\npilchard" > recurse/d/fish + echo -e "cod\nhaddock\nplaice" > recurse/a/f/favourite-fish + + atf_check -o file:"$(atf_get_srcdir)/d_recurse.out" -x "grep -r haddock recurse | sort" +} + +atf_test_case recurse_symlink +recurse_symlink_head() +{ + atf_set "descr" "Checks symbolic link recursion" +} +recurse_symlink_body() +{ + mkdir -p test/c/d + (cd test/c/d && ln -s ../d .) + echo "Test string" > test/c/match + + atf_check -o file:"$(atf_get_srcdir)/d_recurse_symlink.out" \ + -e file:"$(atf_get_srcdir)/d_recurse_symlink.err" \ + grep -r string test +} + +atf_test_case word_regexps +word_regexps_head() +{ + atf_set "descr" "Checks word-regexps" +} +word_regexps_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_word_regexps.out" \ + grep -w separated $(atf_get_srcdir)/d_input +} + +atf_test_case begin_end +begin_end_head() +{ + atf_set "descr" "Checks handling of line beginnings and ends" +} +begin_end_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_begin_end_a.out" \ + grep ^Front "$(atf_get_srcdir)/d_input" + + atf_check -o file:"$(atf_get_srcdir)/d_begin_end_b.out" \ + grep ending$ "$(atf_get_srcdir)/d_input" +} + +atf_test_case ignore_case +ignore_case_head() +{ + atf_set "descr" "Checks ignore-case option" +} +ignore_case_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_ignore_case.out" \ + grep -i Upper "$(atf_get_srcdir)/d_input" +} + +atf_test_case invert +invert_head() +{ + atf_set "descr" "Checks selecting non-matching lines with -v option" +} +invert_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_invert.out" \ + grep -v fish "$(atf_get_srcdir)/d_invert.in" +} + +atf_test_case whole_line +whole_line_head() +{ + atf_set "descr" "Checks whole-line matching with -x flag" +} +whole_line_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_whole_line.out" \ + grep -x matchme "$(atf_get_srcdir)/d_input" +} + +atf_test_case negative +negative_head() +{ + atf_set "descr" "Checks handling of files with no matches" +} +negative_body() +{ + atf_check -s ne:0 grep "not a hope in hell" "$(atf_get_srcdir)/d_input" +} + +atf_test_case context +context_head() +{ + atf_set "descr" "Checks displaying context with -A, -B and -C flags" +} +context_body() +{ + cp $(atf_get_srcdir)/d_context_*.* . + + atf_check -o file:d_context_a.out grep -C2 bamboo d_context_a.in + atf_check -o file:d_context_b.out grep -A3 tilt d_context_a.in + atf_check -o file:d_context_c.out grep -B4 Whig d_context_a.in + atf_check -o file:d_context_d.out grep -C1 pig d_context_a.in d_context_b.in +} + +atf_test_case file_exp +file_exp_head() +{ + atf_set "descr" "Checks reading expressions from file" +} +file_exp_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_file_exp.out" -x \ + 'jot 21 -1 1.00 | grep -f '"$(atf_get_srcdir)"'/d_file_exp.in' +} + +atf_test_case egrep +egrep_head() +{ + atf_set "descr" "Checks matching special characters with egrep" +} +egrep_body() +{ + atf_check -o file:"$(atf_get_srcdir)/d_egrep.out" \ + egrep '\?|\*$$' "$(atf_get_srcdir)/d_input" +} + +atf_test_case zgrep +zgrep_head() +{ + atf_set "descr" "Checks handling of gzipped files with zgrep" +} +zgrep_body() +{ + cp "$(atf_get_srcdir)/d_input" . + gzip d_input || atf_fail "gzip failed" + + atf_check -o file:"$(atf_get_srcdir)/d_zgrep.out" zgrep -h line d_input.gz +} + +atf_test_case nonexistent +nonexistent_head() +{ + atf_set "descr" "Checks that -s flag suppresses error" \ + "messages about nonexistent files" +} +nonexistent_body() +{ + atf_check -s ne:0 grep -s foobar nonexistent +} + +atf_test_case context2 +context2_head() +{ + atf_set "descr" "Checks displaying context with -z flag" +} +context2_body() +{ + printf "haddock\000cod\000plaice\000" > test1 + printf "mackeral\000cod\000crab\000" > test2 + + atf_check -o file:"$(atf_get_srcdir)/d_context2_a.out" \ + grep -z -A1 cod test1 test2 + + atf_check -o file:"$(atf_get_srcdir)/d_context2_b.out" \ + grep -z -B1 cod test1 test2 + + atf_check -o file:"$(atf_get_srcdir)/d_context2_c.out" \ + grep -z -C1 cod test1 test2 +} + +atf_init_test_cases() +{ + atf_add_test_case basic + atf_add_test_case binary + atf_add_test_case recurse + atf_add_test_case recurse_symlink + atf_add_test_case word_regexps + atf_add_test_case begin_end + atf_add_test_case ignore_case + atf_add_test_case invert + atf_add_test_case whole_line + atf_add_test_case negative + atf_add_test_case context + atf_add_test_case file_exp + atf_add_test_case egrep + atf_add_test_case zgrep + atf_add_test_case nonexistent + atf_add_test_case context2 +} diff --git a/contrib/netbsd-tests/usr.bin/gzip/t_gzip.sh b/contrib/netbsd-tests/usr.bin/gzip/t_gzip.sh new file mode 100755 index 0000000..bee6655 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/gzip/t_gzip.sh @@ -0,0 +1,110 @@ +# $NetBSD: t_gzip.sh,v 1.1 2012/03/17 16:33:13 jruoho Exp $ +# +# Copyright (c) 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case concatenated +concatenated_head() +{ + atf_set "descr" "Checks concatenated gzipped data" +} +concatenated_body() +{ + echo -n "aaaa" | gzip > tmp.gz + echo -n "bbbb" | gzip >> tmp.gz + + atf_check -o inline:"aaaabbbb" gzip -d tmp.gz -c +} + +atf_test_case pipe +pipe_head() +{ + atf_set "descr" "Checks input from pipe" +} +pipe_body() +{ + atf_check -x "dd if=/dev/zero count=102400 2>/dev/null \ +| gzip -c | dd bs=1 2>/dev/null | gzip -tc" +} + +atf_test_case truncated +truncated_head() +{ + atf_set "descr" "Checks that gzip fails on truncated data" +} +truncated_body() +{ + cat >truncated.gz.uue <crcerror.gz.uue <good.gz.uue < + +#include +#include +#include +#include +#include +#include + +char Login[16]; +struct group GrEntry; +struct passwd PwEntry; + +gid_t +getgid(void) +{ + return 100; +} + +gid_t +getegid(void) +{ + if (getenv("LIBFAKE_EGID_ROOT") != NULL) + return 0; + else + return 100; +} + +uid_t +getuid(void) +{ + return 100; +} + +uid_t +geteuid(void) +{ + if (getenv("LIBFAKE_EUID_ROOT") != NULL) + return 0; + else + return 100; +} + +char * +getlogin(void) +{ + strcpy(Login, "test"); + return Login; +} + +struct group * +getgrgid(gid_t gid) +{ + struct group *g = &GrEntry; + + memset(g, 0, sizeof(*g)); + if (gid == 0) { + g->gr_name = __UNCONST("wheel"); + g->gr_gid = 0; + } else if (gid == 100) { + g->gr_name = __UNCONST("users"); + g->gr_gid = 100; + } else + g = NULL; + + return g; +} + +int +getgrouplist(const char *name, gid_t basegid, gid_t *groups, int *ngroups) +{ + int cnt, ret; + + if (strcmp(name, "root") == 0) { + if (*ngroups >= 1) { + groups[0] = basegid; + cnt = 1; + } + + ret = (*ngroups >= cnt) ? 0 : -1; + *ngroups = cnt; + } else if (strcmp(name, "test") == 0) { + if (*ngroups >= 1) { + groups[0] = basegid; + cnt = 1; + } + + if (*ngroups >= 2) { + groups[1] = 0; + cnt = 2; + } + + ret = (*ngroups >= cnt) ? 0 : -1; + *ngroups = cnt; + } else + ret = -1; + + return ret; +} + +int +getgroups(int gidsetlen, gid_t *gidset) +{ + if (gidsetlen < 2) { + errno = EINVAL; + return -1; + } + + gidset[0] = 100; + gidset[1] = 0; + return 2; +} + +struct passwd * +getpwnam(const char *login) +{ + struct passwd *p = &PwEntry; + + memset(p, 0, sizeof(*p)); + if (strcmp(login, "root") == 0) { + p->pw_name = __UNCONST("root"); + p->pw_uid = 0; + p->pw_gid = 0; + } else if (strcmp(login, "test") == 0) { + p->pw_name = __UNCONST("test"); + p->pw_uid = 100; + p->pw_gid = 100; + } else + p = NULL; + + return p; +} + +struct passwd * +getpwuid(uid_t uid) +{ + struct passwd *p = &PwEntry; + + memset(p, 0, sizeof(*p)); + if (uid == 0) { + p->pw_name = __UNCONST("root"); + p->pw_uid = 0; + p->pw_gid = 0; + } else if (uid == 100) { + p->pw_name = __UNCONST("test"); + p->pw_uid = 100; + p->pw_gid = 100; + } else + p = NULL; + + return p; +} diff --git a/contrib/netbsd-tests/usr.bin/id/t_groups.sh b/contrib/netbsd-tests/usr.bin/id/t_groups.sh new file mode 100755 index 0000000..71121ab --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/id/t_groups.sh @@ -0,0 +1,71 @@ +# $NetBSD: t_groups.sh,v 1.1 2012/03/17 16:33:14 jruoho Exp $ +# +# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +create_run_groups() { + cat >run_groups.sh <expout + atf_check -s eq:0 -o file:expout -e empty ./run_groups.sh + atf_check -s eq:0 -o file:expout -e empty ./run_groups.sh 100 + atf_check -s eq:0 -o file:expout -e empty ./run_groups.sh test + + echo "wheel" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_groups.sh 0 + atf_check -s eq:0 -o file:expout -e empty ./run_groups.sh root +} + +atf_test_case syntax +syntax_head() { + atf_set "descr" "Checks the command's syntax" +} +syntax_body() { + create_run_groups + + # Give an invalid flag but which is allowed by id (with which + # groups shares code) when using the -Gn options. + atf_check -s eq:1 -o empty -e save:stderr ./run_groups.sh -r + atf_check -s eq:0 -o ignore -e empty grep '^usage:' stderr +} + +atf_init_test_cases() +{ + atf_add_test_case correct + atf_add_test_case syntax +} diff --git a/contrib/netbsd-tests/usr.bin/id/t_id.sh b/contrib/netbsd-tests/usr.bin/id/t_id.sh new file mode 100755 index 0000000..9c877a6 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/id/t_id.sh @@ -0,0 +1,305 @@ +# $NetBSD: t_id.sh,v 1.1 2012/03/17 16:33:14 jruoho Exp $ +# +# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +create_run_id() { + cat >run_id.sh <expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh test + + echo "uid=0(root) gid=0(wheel) groups=0(wheel)" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh 0 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh root + + export LIBFAKE_EGID_ROOT=1 LIBFAKE_EUID_ROOT=1 + echo "uid=100(test) gid=100(users) euid=0(root) egid=0(wheel) groups=100(users),0(wheel)" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh + unset LIBFAKE_EGID_ROOT LIBFAKE_EUID_ROOT + + echo 'id: nonexistent: No such user' >experr + atf_check -s eq:1 -o empty -e file:experr ./run_id.sh nonexistent + + atf_check -s eq:1 -o empty -e save:stderr ./run_id.sh root nonexistent + atf_check -s eq:0 -o ignore -e empty grep ^usage: stderr +} + +atf_test_case primaries +primaries_head() { + atf_set "descr" "Checks that giving multiple primaries" \ + "simultaneously provides an error" +} +primaries_body() { + create_run_id + + for p1 in -G -g -p -u; do + for p2 in -G -g -p -u; do + if [ ${p1} != ${p2} ]; then + atf_check -s eq:1 -o empty -e save:stderr \ + ./run_id.sh ${p1} ${p2} + atf_check -s eq:0 -o ignore -e empty \ + grep ^usage: stderr + fi + done + done +} + +atf_test_case Gflag +Gflag_head() { + atf_set "descr" "Checks that the -G primary flag works" +} +Gflag_body() { + create_run_id + + echo "100 0" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -G + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -G 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -G test + + echo "users wheel" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -G -n + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -G -n 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -G -n test + + echo "0" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -G 0 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -G root + + echo "wheel" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -G -n 0 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -G -n root + + echo 'id: nonexistent: No such user' >experr + atf_check -s eq:1 -o empty -e file:experr ./run_id.sh -G nonexistent + + atf_check -s eq:1 -o empty -e save:stderr ./run_id.sh -G root nonexistent + atf_check -s eq:0 -o ignore -e empty grep ^usage: stderr +} + +atf_test_case gflag +gflag_head() { + atf_set "descr" "Checks that the -g primary flag works" +} +gflag_body() { + create_run_id + + echo "100" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g test + + echo "users" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -n + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -n 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -n test + + echo "0" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g 0 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g root + + echo "wheel" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -n 0 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -n root + + echo "100" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -r + + echo "users" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -r -n + + echo "100" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -r 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -r test + + echo "users" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -r -n 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -r -n test + + export LIBFAKE_EGID_ROOT=1 LIBFAKE_EUID_ROOT=1 + + echo "0" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g + + echo "wheel" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -n + + echo "100" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -r + + echo "users" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -r -n + + echo "100" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -r 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -r test + + echo "users" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -r -n 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -g -r -n test + + unset LIBFAKE_EGID_ROOT LIBFAKE_EUID_ROOT + + echo 'id: nonexistent: No such user' >experr + atf_check -s eq:1 -o empty -e file:experr ./run_id.sh -g nonexistent + + atf_check -s eq:1 -o empty -e save:stderr ./run_id.sh -g root nonexistent + atf_check -s eq:0 -o ignore -e empty grep ^usage: stderr +} + +atf_test_case pflag +pflag_head() { + atf_set "descr" "Checks that the -p primary flag works" +} +pflag_body() { + create_run_id + + cat >expout <expout <expout <experr + atf_check -s eq:1 -o empty -e file:experr ./run_id.sh -p nonexistent + + atf_check -s eq:1 -o empty -e save:stderr ./run_id.sh -p root nonexistent + atf_check -s eq:0 -o ignore -e empty grep ^usage: stderr +} + +atf_test_case uflag +uflag_head() { + atf_set "descr" "Checks that the -u primary flag works" +} +uflag_body() { + create_run_id + + echo "100" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u test + + echo "test" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -n + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -n 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -n test + + echo "0" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u 0 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u root + + echo "root" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -n 0 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -n root + + echo "100" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -r + + echo "test" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -r -n + + echo "100" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -r 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -r test + + echo "test" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -r -n 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -r -n test + + export LIBFAKE_EGID_ROOT=1 LIBFAKE_EUID_ROOT=1 + + echo "0" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u + + echo "root" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -n + + echo "100" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -r + + echo "test" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -r -n + + echo "100" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -r 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -r test + + echo "test" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -r -n 100 + atf_check -s eq:0 -o file:expout -e empty ./run_id.sh -u -r -n test + + unset LIBFAKE_EGID_ROOT LIBFAKE_EUID_ROOT + + echo 'id: nonexistent: No such user' >experr + atf_check -s eq:1 -o empty -e file:experr ./run_id.sh -u nonexistent + + atf_check -s eq:1 -o empty -e save:stderr \ + ./run_id.sh -u root nonexistent + atf_check -s eq:0 -o ignore -e empty grep ^usage: stderr +} + +atf_init_test_cases() +{ + atf_add_test_case default + atf_add_test_case primaries + atf_add_test_case Gflag + atf_add_test_case gflag + atf_add_test_case pflag + atf_add_test_case uflag +} diff --git a/contrib/netbsd-tests/usr.bin/id/t_whoami.sh b/contrib/netbsd-tests/usr.bin/id/t_whoami.sh new file mode 100755 index 0000000..c8df745 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/id/t_whoami.sh @@ -0,0 +1,75 @@ +# $NetBSD: t_whoami.sh,v 1.1 2012/03/17 16:33:14 jruoho Exp $ +# +# Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +create_run_whoami() { + cat >run_whoami.sh <expout + atf_check -s eq:0 -o file:expout -e empty ./run_whoami.sh + + echo "Checking with EUID=0" + export LIBFAKE_EUID_ROOT=1 + echo "root" >expout + atf_check -s eq:0 -o file:expout -e empty ./run_whoami.sh +} + +atf_test_case syntax +syntax_head() { + atf_set "descr" "Checks the command's syntax" +} +syntax_body() { + create_run_whoami + + # Give a user to the command. + echo 'usage: whoami' >experr + atf_check -s eq:1 -o empty -e file:experr ./run_whoami.sh root + + # Give an invalid flag but which is allowed by id (with which + # whoami shares code) when using the -un options. + echo 'usage: whoami' >experr + atf_check -s eq:1 -o empty -e file:experr ./run_whoami.sh -r +} + +atf_init_test_cases() +{ + atf_add_test_case correct + atf_add_test_case syntax +} diff --git a/contrib/netbsd-tests/usr.bin/infocmp/t_terminfo.sh b/contrib/netbsd-tests/usr.bin/infocmp/t_terminfo.sh new file mode 100755 index 0000000..8ede240 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/infocmp/t_terminfo.sh @@ -0,0 +1,62 @@ +# $NetBSD: t_terminfo.sh,v 1.1 2012/06/06 21:23:10 martin Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() { + atf_set "descr" "infocmp can decode one of some existing term types" + atf_set "require.progs" "infocmp env" +} + +basic_body() { + for term in ansi vt100 wsvt25 sun-ss5 ibcs2 vt52 386at h19k h19kermit + do + atf_check -s exit:0 -e empty -o not-empty \ + env TERM="${term}" infocmp + done +} + +atf_test_case missing +missing_head() { + atf_set "descr" "infocmp fails to decode non existent entries" + atf_set "require.progs" "infocmp env" +} + +missing_body() { + for term in this-is-no-term nonexistent + do + atf_check -s not-exit:0 -e not-empty -o empty \ + env TERM="${term}" infocmp + done +} + +atf_init_test_cases() +{ + + atf_add_test_case basic + atf_add_test_case missing +} + diff --git a/contrib/netbsd-tests/usr.bin/jot/d_basic.out b/contrib/netbsd-tests/usr.bin/jot/d_basic.out new file mode 100644 index 0000000..89b0879 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/jot/d_basic.out @@ -0,0 +1,21 @@ +-1.00 +-0.90 +-0.80 +-0.70 +-0.60 +-0.50 +-0.40 +-0.30 +-0.20 +-0.10 +-0.00 +0.10 +0.20 +0.30 +0.40 +0.50 +0.60 +0.70 +0.80 +0.90 +1.00 diff --git a/contrib/netbsd-tests/usr.bin/jot/t_jot.sh b/contrib/netbsd-tests/usr.bin/jot/t_jot.sh new file mode 100755 index 0000000..bcdae32 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/jot/t_jot.sh @@ -0,0 +1,56 @@ +# $NetBSD: t_jot.sh,v 1.1 2012/03/20 06:18:34 jruoho Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() { + atf_set "descr" "Test that jot(1)'s output is sane (PR bin/12424)" +} + +basic_body() { + atf_check -o file:"$(atf_get_srcdir)/d_basic.out" jot 21 -1 1.00 +} + +atf_test_case format +format_head() { + atf_set "descr" "Test that jot(1) handles format strings " \ + "correctly (PR bin/12316, PR bin/14253)" +} + +format_body() { + atf_check -s exit:0 -o ignore jot -w xa%c 26 a + atf_check -s not-exit:0 -e not-empty jot -w %2 12 + atf_check -s not-exit:0 -e not-empty jot -w %0 10 1 10 +} + +atf_init_test_cases() +{ + atf_add_test_case basic + atf_add_test_case format +} diff --git a/contrib/netbsd-tests/usr.bin/ld/t_script.sh b/contrib/netbsd-tests/usr.bin/ld/t_script.sh new file mode 100755 index 0000000..6262dac --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/ld/t_script.sh @@ -0,0 +1,230 @@ +# $NetBSD: t_script.sh,v 1.7 2014/11/16 04:47:18 uebayasi Exp $ +# +# Copyright (c) 2014 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +################################################################################ + +atf_test_case order_default +order_default_head() { + atf_set "descr" "check if default object ordering works" + atf_set "require.progs" "cc" "ld" "readelf" "nm" "sed" "grep" +} + +order_default_body() { + cat > test.x << EOF +SECTIONS { + /* do nothing; but ld has implicit scripts internally */ + /* which usually do: *(.data) *(.data.*) */ +} +EOF + order_assert_descending +} + +################################################################################ + +atf_test_case order_merge +order_merge_head() { + atf_set "descr" "check if glob merge keeps object ordering" + atf_set "require.progs" ${order_require_progs} +} + +order_merge_body() { + cat > test.x << EOF +SECTIONS { + .data : { + *(.data .data.*) + } +} +EOF + order_assert_descending +} + +################################################################################ + +atf_test_case order_reorder +order_reorder_head() { + atf_set "descr" "check if object reordering works" + atf_set "require.progs" ${order_require_progs} +} + +order_reorder_body() { + cat > test.x << EOF +SECTIONS { + .data : { + *(.data) + *(.data.a) + *(.data.b) + *(.data.c) + } +} +EOF + order_assert_ascending +} + +################################################################################ + +atf_test_case order_sort +order_sort_head() { + atf_set "descr" "check if object sort works" + atf_set "require.progs" ${order_require_progs} +} + +order_sort_body() { + cat > test.x << EOF +SECTIONS { + .data : { + *(.data) + /* SORT_BY_NAME */ + SORT(*)(.data.*) + } +} +EOF + order_assert_ascending +} + +################################################################################ + +atf_test_case multisec +multisec_head() { + atf_set "descr" "check if multiple SECTIONS commands work" + atf_set "require.progs" ${order_require_progs} +} + +multisec_body() { + cat > test.c << EOF +#include +char a __section(".data.a") = 'a'; +char b __section(".data.b") = 'b'; +char c __section(".data.c") = 'c'; +EOF + atf_check -s exit:0 -o ignore -e ignore cc -c test.c + + cat > test.x << EOF +SECTIONS { + .data : { + *(.data) + *(.data.a) + } +} +SECTIONS { + .data : { + *(.data) + *(.data.b) + } +} +EOF + atf_check -s exit:0 -o ignore -e ignore \ + ld -r -T test.x -Map test.map -o test.ro test.o + extract_section_names test.ro >test.secs + extract_symbol_names test.ro >test.syms + assert_nosec '\.data\.a' + assert_nosec '\.data\.b' + assert_sec '\.data\.c' +} + +################################################################################ + +order_require_progs="cc ld readelf nm sed grep" + +order_assert_ascending() { + order_assert_order a b c +} + +order_assert_descending() { + order_assert_order c b a +} + +order_assert_order() { + order_compile + order_link + { + match $1 && match $2 && match $3 + } $i.c << EOF +#include +char $i __section(".data.$i") = '$i'; +EOF + atf_check -s exit:0 -o ignore -e ignore cc -c $i.c + done + cat > test.c << EOF +int main(void) { return 0; } +EOF + atf_check -s exit:0 -o ignore -e ignore cc -c test.c +} + +order_link() { + # c -> b -> a + atf_check -s exit:0 -o ignore -e ignore \ + ld -r -T test.x -Map test.map -o x.o c.o b.o a.o + atf_check -s exit:0 -o ignore -e ignore \ + cc -o test test.o x.o + extract_symbol_names test | + grep '^[abc]$' >test.syms +} + +extract_section_names() { + readelf -S "$1" | + sed -ne '/\] \./ { s/^.*\] //; s/ .*$//; p }' +} + +extract_symbol_names() { + nm -n "$1" | + sed -e 's/^.* //' +} + +match() { + read line + case "$line" in + *"$1"*) return 0; + esac + return 1 +} + +assert_sec() { + atf_check -s exit:0 -o ignore -e ignore \ + grep "^$1\$" test.secs +} + +assert_nosec() { + atf_check -s exit:1 -o ignore -e ignore \ + grep "^$1\$" test.secs +} + +################################################################################ + +atf_init_test_cases() +{ + atf_add_test_case order_default + atf_add_test_case order_merge + atf_add_test_case order_reorder + atf_add_test_case order_sort + atf_add_test_case multisec +} diff --git a/contrib/netbsd-tests/usr.bin/ld/t_section.sh b/contrib/netbsd-tests/usr.bin/ld/t_section.sh new file mode 100755 index 0000000..03c12e4 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/ld/t_section.sh @@ -0,0 +1,100 @@ +# $NetBSD: t_section.sh,v 1.4 2015/02/17 11:51:04 martin Exp $ +# +# Copyright (c) 2014 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +################################################################################ + +atf_test_case startstop +startstop_head() { + atf_set "descr" "check if __start_*/__stop_* symbols are generated" + atf_set "require.progs" "cc" +} + +startstop_body() { + cat > test.c << EOF +#include +int i __section("hoge"); +extern int __start_hoge[], __stop_hoge[]; +int main(void) { return __start_hoge[0] + __stop_hoge[0]; } +EOF + atf_check -s exit:0 -o ignore -e ignore cc -o test test.c +} + +################################################################################ + +atf_test_case orphan +orphan_head() { + atf_set "descr" "check orphan section placement" + atf_set "require.progs" "cc" "readelf" "grep" +} + +orphan_body() { + cat > test.c << EOF +#include +/* read-only orphan */ +const char a[] __section("hoge") = "hoge"; +/* read-write orphan */ +char b[] __section("fuga") = { 'f', 'u', 'g', 'a', '\0' }; +/* .data */ +int c[1024] = { 123, 20, 1, 0 }; +/* .bss */ +int d = 0; +/* .text */ +int main(void) { return 0; } +EOF + atf_check -s exit:0 -o ignore -e ignore cc -o test test.c + readelf -S test | + grep ' \.text\| hoge\| \.data\| fuga\| \.bss' >test.secs + { + # Read-only orphan sections are placed after well-known + # read-only sections (.text, .rodata) but before .data. + match ".text" && + match "hoge" && + # Read-write orphan sections are placed after well-known + # read-write sections (.data) but before .bss. + match ".data" && + match "fuga" && + match ".bss" && + : + } < test.secs + atf_check test "$?" -eq 0 +} + +match() { + read line + case "$line" in + *"$1"*) return 0; + esac + return 1 +} + +################################################################################ + +atf_init_test_cases() +{ + atf_add_test_case startstop + atf_add_test_case orphan +} diff --git a/contrib/netbsd-tests/usr.bin/m4/d_ff_after_dnl.m4.uue b/contrib/netbsd-tests/usr.bin/m4/d_ff_after_dnl.m4.uue new file mode 100644 index 0000000..8b90044 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/m4/d_ff_after_dnl.m4.uue @@ -0,0 +1,9 @@ +$NetBSD: d_ff_after_dnl.m4.uue,v 1.1 2012/03/17 16:33:14 jruoho Exp $ + +begin 644 d_ff_after_dnl.m4 +M"0E42$E3(%-(3U5,1"!32$]7(%50("A,24Y%(#$I"F1N;`D)5$A)4R!32$]5 +M3$0@3D]4(%-(3U<@55`@*$Q)3D4@,BD*9&YL_PD)5$A)4R!32$]53$0@3D]4 +M(%-(3U<@55`@*$Q)3D4@,RD*9&YL"?\)5$A)4R!32$]53$0@3D]4(%-(3U<@ +K55`@*$Q)3D4@-"D*"0E42$E3(%-(3U5,1"!32$]7(%50("A,24Y%(#4I"E<@ +` +end diff --git a/contrib/netbsd-tests/usr.bin/m4/d_ff_after_dnl.out b/contrib/netbsd-tests/usr.bin/m4/d_ff_after_dnl.out new file mode 100644 index 0000000..8e51f1e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/m4/d_ff_after_dnl.out @@ -0,0 +1,2 @@ + THIS SHOULD SHOW UP (LINE 1) + THIS SHOULD SHOW UP (LINE 5) diff --git a/contrib/netbsd-tests/usr.bin/m4/d_m4wrap-P.m4 b/contrib/netbsd-tests/usr.bin/m4/d_m4wrap-P.m4 new file mode 100644 index 0000000..e029858 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/m4/d_m4wrap-P.m4 @@ -0,0 +1,5 @@ +m4_dnl $NetBSD: d_m4wrap-P.m4,v 1.1 2012/03/17 16:33:14 jruoho Exp $ +m4_define(`ateof', `TEXT AT EOF +')m4_dnl +m4_m4wrap(`ateof()')m4_dnl +TEXT IN BODY diff --git a/contrib/netbsd-tests/usr.bin/m4/d_m4wrap-P.out b/contrib/netbsd-tests/usr.bin/m4/d_m4wrap-P.out new file mode 100644 index 0000000..a1bc22a --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/m4/d_m4wrap-P.out @@ -0,0 +1,2 @@ +TEXT IN BODY +TEXT AT EOF diff --git a/contrib/netbsd-tests/usr.bin/m4/d_m4wrap.m4 b/contrib/netbsd-tests/usr.bin/m4/d_m4wrap.m4 new file mode 100644 index 0000000..b74db96 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/m4/d_m4wrap.m4 @@ -0,0 +1,5 @@ +dnl $NetBSD: d_m4wrap.m4,v 1.1 2012/03/17 16:33:14 jruoho Exp $ +define(`ateof', `TEXT AT EOF +')dnl +m4wrap(`ateof()')dnl +TEXT IN BODY diff --git a/contrib/netbsd-tests/usr.bin/m4/d_m4wrap.out b/contrib/netbsd-tests/usr.bin/m4/d_m4wrap.out new file mode 100644 index 0000000..a1bc22a --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/m4/d_m4wrap.out @@ -0,0 +1,2 @@ +TEXT IN BODY +TEXT AT EOF diff --git a/contrib/netbsd-tests/usr.bin/m4/t_m4.sh b/contrib/netbsd-tests/usr.bin/m4/t_m4.sh new file mode 100755 index 0000000..a0e1e70 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/m4/t_m4.sh @@ -0,0 +1,50 @@ +# $NetBSD: t_m4.sh,v 1.1 2012/03/17 16:33:14 jruoho Exp $ +# +# Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case eof +eof_head() +{ + atf_set "descr" "Checks that m4 doesn't confuse 0xFF with EOF" +} +eof_body() +{ + cp "$(atf_get_srcdir)/d_ff_after_dnl.m4.uue" . + uudecode d_ff_after_dnl.m4.uue + atf_check -o file:"$(atf_get_srcdir)/d_ff_after_dnl.out" \ + m4 d_ff_after_dnl.m4 + + atf_check -o file:"$(atf_get_srcdir)/d_m4wrap.out" \ + m4 "$(atf_get_srcdir)/d_m4wrap.m4" + + atf_check -o file:"$(atf_get_srcdir)/d_m4wrap-P.out" \ + m4 -P "$(atf_get_srcdir)/d_m4wrap-P.m4" +} + +atf_init_test_cases() +{ + atf_add_test_case eof +} diff --git a/contrib/netbsd-tests/usr.bin/make/t_make.sh b/contrib/netbsd-tests/usr.bin/make/t_make.sh new file mode 100755 index 0000000..42fd795 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/make/t_make.sh @@ -0,0 +1,85 @@ +# $NetBSD: t_make.sh,v 1.7 2015/01/27 12:57:14 martin Exp $ +# +# Copyright (c) 2008, 2010, 2014 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# Executes make and compares the output to a golden file. +run_and_check() +{ + local atfname="${1}"; shift + local makename="${1}"; shift + + # these tests fail since the backout of the patch in PR + # 49085 - adjust for more concrete PR if there is one + case ${makename} in + escape) atf_expect_fail "see PR toolchain/49085";; + impsrc) atf_expect_fail "see PR toolchain/49085";; + phony*) atf_expect_fail "see PR toolchain/49085";; + posix1) atf_expect_fail "see PR toolchain/49085";; + suffixes) atf_expect_fail "see PR toolchain/49085" + atf_fail "this uses up all memory and then fails";; + esac + + local srcdir="$(atf_get_srcdir)" + + local testdir="$(atf_get_srcdir)/unit-tests" + + atf_check -s exit:0 -o ignore -e ignore \ + make -f "${testdir}/Makefile" "${makename}.out" + atf_check -o file:"${testdir}/${makename}.exp" cat "${makename}.out" +} + +# Defines a test case for make(1), parsing a given file and comparing the +# output to prerecorded results. +test_case() +{ + local atfname="${1}"; shift # e.g. foo_bar + local makename="${1}"; shift # e.g. foo-bar + local descr="${1}"; shift + + atf_test_case "${atfname}" + eval "${atfname}_head() { \ + if [ -n '${descr}' ]; then \ + atf_set descr '${descr}'; \ + fi \ + }" + eval "${atfname}_body() { \ + run_and_check '${atfname}' '${makename}'; \ + }" +} + +atf_init_test_cases() +{ + local filename basename atfname descr + + for filename in "$(atf_get_srcdir)"/unit-tests/*.mk ; do + basename="${filename##*/}" + basename="${basename%.mk}" + atfname="$(echo "${basename}" | tr "x-" "x_")" + descr='' # XXX + test_case "${atfname}" "${basename}" "${descr}" + atf_add_test_case "${atfname}" + done +} diff --git a/contrib/netbsd-tests/usr.bin/mixerctl/t_mixerctl.sh b/contrib/netbsd-tests/usr.bin/mixerctl/t_mixerctl.sh new file mode 100755 index 0000000..94c0bdf --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/mixerctl/t_mixerctl.sh @@ -0,0 +1,51 @@ +# $NetBSD: t_mixerctl.sh,v 1.1 2017/01/02 15:40:09 christos Exp $ + +atf_test_case noargs_usage +noargs_usage_head() { + atf_set "descr" "Ensure mixerctl(1) with no args prints a usage message" +} +noargs_usage_body() { + atf_check -s exit:0 -o not-empty -e ignore \ + mixerctl +} + +atf_test_case showvalue +showvalue_head() { + atf_set "descr" "Ensure mixerctl(1) can print the value for all variables" +} +showvalue_body() { + for var in $(mixerctl -a | awk -F= '{print $1}'); do + atf_check -s exit:0 -e ignore -o match:"^${var}=" \ + mixerctl ${var} + done +} + +atf_test_case nflag +nflag_head() { + atf_set "descr" "Ensure 'mixerctl -n' actually suppresses some output" +} +nflag_body() { + varname="$(mixerctl -a | head -1 | awk -F= '{print $1}')" + + atf_check -s exit:0 -o match:"${varname}" -e ignore \ + mixerctl ${varname} + + atf_check -s exit:0 -o not-match:"${varname}" -e ignore \ + mixerctl -n ${varname} +} + +atf_test_case nonexistant_device +nonexistant_device_head() { + atf_set "descr" "Ensure mixerctl(1) complains if provided a nonexistant mixer device" +} +nonexistant_device_body() { + atf_check -s not-exit:0 -o ignore -e match:"No such file" \ + mixerctl -d /a/b/c/d/e +} + +atf_init_test_cases() { + atf_add_test_case noargs_usage + atf_add_test_case showvalue + atf_add_test_case nflag + atf_add_test_case nonexistant_device +} diff --git a/contrib/netbsd-tests/usr.bin/mkdep/t_mkdep.sh b/contrib/netbsd-tests/usr.bin/mkdep/t_mkdep.sh new file mode 100755 index 0000000..7ad6fd9 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/mkdep/t_mkdep.sh @@ -0,0 +1,83 @@ +# $NetBSD: t_mkdep.sh,v 1.4 2012/08/26 22:37:19 jmmv Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Nicolas Joly. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case prefix +prefix_head() { + atf_set "descr" "Test adding a prefix to a single target" + atf_set "require.progs" "mkdep cc" +} +prefix_body() { + + atf_check touch sample.c + + atf_check mkdep -f sample.d -P some/path/ sample.c + atf_check -o ignore grep '^some/path/sample.o:' sample.d +} + +atf_test_case suffixes +suffixes_head() { + atf_set "descr" "Test suffixes list" + atf_set "require.progs" "mkdep cc" +} +suffixes_body() { + + atf_check touch sample.c + + # No list + atf_check mkdep -f sample.d sample.c + atf_check -o ignore grep '^sample.o:' sample.d + + # Suffix list + atf_check mkdep -f sample.d -s '.a .b' sample.c + atf_check -o ignore grep '^sample.b sample.a:' sample.d + + # Empty list + atf_check mkdep -f sample.d -s '' sample.c + atf_check -o ignore grep '^sample:' sample.d +} + +atf_test_case prefix_and_suffixes +prefix_and_suffixes_head() { + atf_set "descr" "Test the combination of a prefix and suffixes" + atf_set "require.progs" "mkdep cc" +} +prefix_and_suffixes_body() { + + atf_check touch sample.c + + atf_check mkdep -f sample.d -s '.a .b' -P c/d sample.c + atf_check -o ignore grep '^c/dsample.b c/dsample.a:' sample.d +} + +atf_init_test_cases() { + atf_add_test_case prefix + atf_add_test_case suffixes + atf_add_test_case prefix_and_suffixes +} diff --git a/contrib/netbsd-tests/usr.bin/nbperf/h_nbperf.sh b/contrib/netbsd-tests/usr.bin/nbperf/h_nbperf.sh new file mode 100755 index 0000000..2587ed0 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/nbperf/h_nbperf.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# $NetBSD: h_nbperf.sh,v 1.2 2012/09/25 20:53:46 joerg Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +set -e +head -n $4 $1 | nbperf -m hash.map -o hash.c -a $2 2> /dev/null +cc -o testprog -I. $5 +head -n $4 $1 | ./testprog | $3 diff --git a/contrib/netbsd-tests/usr.bin/nbperf/hash_driver.c b/contrib/netbsd-tests/usr.bin/nbperf/hash_driver.c new file mode 100644 index 0000000..e4195d9 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/nbperf/hash_driver.c @@ -0,0 +1,53 @@ +/* $NetBSD: hash_driver.c,v 1.3 2014/02/06 14:57:16 joerg Exp $ */ +/*- + * Copyright (c) 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Joerg Sonnenberger. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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 +#include + +#include "hash.c" + +int +main(void) +{ + char *line = NULL; + size_t buflen; + ssize_t len; + + while ((len = getline(&line, &buflen, stdin)) > 0) { + if (len && line[len - 1] == '\n') + --len; + printf("%" PRId32 "\n", hash(line, len)); + } + free(line); + return 0; +} diff --git a/contrib/netbsd-tests/usr.bin/nbperf/t_nbperf.sh b/contrib/netbsd-tests/usr.bin/nbperf/t_nbperf.sh new file mode 100755 index 0000000..37b7d90 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/nbperf/t_nbperf.sh @@ -0,0 +1,110 @@ +# $NetBSD: t_nbperf.sh,v 1.3 2014/04/30 21:04:21 joerg Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +cleanup() +{ + rm -f reference.txt hash.c hash.map testprog +} + +atf_test_case chm +chm_head() +{ + atf_set "descr" "Checks chm algorithm" + atf_set "require.files" "/usr/share/dict/web2" + atf_set "require.progs" "cc" +} +chm_body() +{ + for n in 4 32 128 1024 65536; do + seq 0 $(($n - 1)) > reference.txt + atf_check -o file:reference.txt \ + $(atf_get_srcdir)/h_nbperf /usr/share/dict/web2 chm cat \ + $n $(atf_get_srcdir)/hash_driver.c + atf_check -o file:hash.map \ + $(atf_get_srcdir)/h_nbperf /usr/share/dict/web2 chm cat \ + $n $(atf_get_srcdir)/hash_driver.c + done +} +chm_clean() +{ + cleanup +} + +atf_test_case chm3 +chm3_head() +{ + atf_set "descr" "Checks chm3 algorithm" + atf_set "require.files" "/usr/share/dict/web2" + atf_set "require.progs" "cc" +} +chm3_body() +{ + for n in 4 32 128 1024 65536; do + seq 0 $(($n - 1)) > reference.txt + atf_check -o file:reference.txt \ + $(atf_get_srcdir)/h_nbperf /usr/share/dict/web2 chm3 cat \ + $n $(atf_get_srcdir)/hash_driver.c + atf_check -o file:hash.map \ + $(atf_get_srcdir)/h_nbperf /usr/share/dict/web2 chm3 cat \ + $n $(atf_get_srcdir)/hash_driver.c + done +} +chm3_clean() +{ + cleanup +} + +atf_test_case bdz +bdz_head() +{ + atf_set "descr" "Checks bdz algorithm" + atf_set "require.files" "/usr/share/dict/web2" + atf_set "require.progs" "cc" +} +bdz_body() +{ + for n in 4 32 128 1024 65536 131072; do + seq 0 $(($n - 1)) > reference.txt + atf_check -o file:reference.txt \ + $(atf_get_srcdir)/h_nbperf /usr/share/dict/web2 bdz "sort -n" \ + $n $(atf_get_srcdir)/hash_driver.c + atf_check -o file:hash.map \ + $(atf_get_srcdir)/h_nbperf /usr/share/dict/web2 bdz cat \ + $n $(atf_get_srcdir)/hash_driver.c + done +} +bdz_clean() +{ + cleanup +} + +atf_init_test_cases() +{ + atf_add_test_case chm + atf_add_test_case chm3 + atf_add_test_case bdz +} diff --git a/contrib/netbsd-tests/usr.bin/netpgpverify/Testspec b/contrib/netbsd-tests/usr.bin/netpgpverify/Testspec new file mode 100644 index 0000000..d04f4ad --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/netpgpverify/Testspec @@ -0,0 +1,114 @@ +#! /bin/sh + +# $NetBSD: Testspec,v 1.2 2016/06/01 14:52:56 agc Exp $ + +# Copyright (c) 2016 Alistair Crooks +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +# + +TESTNAME=netpgpverify + +TESTSET_1_NAME=rsa_signatures +TESTSET_1_FILES=' +a.gpg +b.gpg +det +det.sig +jj.asc +pubring.gpg +NetBSD-6.0_hashes.asc:gzip +expected16 +expected17 +expected18 +expected19 +expected20 +expected21 +expected22 +expected23 +expected24 +expected25 +expected26 +expected27 +expected28 +expected29 +expected30 +expected31 +expected32 +expected33 +expected34 +expected35 +' +TESTSET_1_CASE_1="-s eq:0 -o file:1.expected -e empty b2e < 1.in" +TESTSET_1_CASE_2="-s eq:0 -o file:2.expected -e empty b2e < 2.in" + +TESTSET_1_CASE_1="-s eq:0 -o file:expected16 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg -c verify b.gpg" +DISABLE_TESTSET_1_CASE_2="-s eq:0 -o file:expected17 -e empty netpgpverify -c verify a.gpg" +TESTSET_1_CASE_3="-s eq:0 -o file:expected18 -e empty env TZ=US/Pacific netpgpverify -c verify a.gpg" +TESTSET_1_CASE_4="-s eq:0 -o file:expected19 -e empty env TZ=US/Pacific netpgpverify -c verify NetBSD-6.0_RC2_hashes.asc" +TESTSET_1_CASE_5="-s eq:0 -o file:expected20 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg -c cat jj.asc" +TESTSET_1_CASE_6="-s eq:0 -o file:expected21 -e empty env TZ=US/Pacific netpgpverify < a.gpg" +TESTSET_1_CASE_7="-s eq:0 -o file:expected22 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg < jj.asc" +TESTSET_1_CASE_8="-s eq:0 -o file:expected23 -e empty env TZ=US/Pacific netpgpverify < NetBSD-6.0_RC2_hashes.asc" +TESTSET_1_CASE_9="-s eq:0 -o file:expected24 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg < b.gpg" +DISABLE_TESTSET_1_CASE_10="-s eq:0 -o file:expected25 -e empty netpgpverify NetBSD-6.0_RC1_hashes.gpg" +DISABLE_TESTSET_1_CASE_11="-s eq:0 -o file:expected26 -e empty netpgpverify < NetBSD-6.0_RC1_hashes.gpg" +TESTSET_1_CASE_12="-s eq:0 -o file:expected27 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg < NetBSD-6.0_hashes.asc" +TESTSET_1_CASE_13="-s eq:0 -o file:expected28 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg NetBSD-6.0_hashes.asc" +DISABLE_TESTSET_1_CASE_14="-s eq:0 -o file:expected29 -e empty netpgpverify NetBSD-6.0_RC1_hashes_ascii.gpg" +DISABLE_TESTSET_1_CASE_15="-s eq:0 -o file:expected30 -e empty netpgpverify < NetBSD-6.0_RC1_hashes_ascii.gpg" +TESTSET_1_CASE_16="-s eq:0 -o file:expected31 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg -c cat b.gpg b.gpg b.gpg" +TESTSET_1_CASE_17="-s eq:0 -o file:expected32 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg b.gpg b.gpg b.gpg" +TESTSET_1_CASE_18="-s eq:0 -o file:expected33 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg -c cat b.gpg jj.asc b.gpg" +TESTSET_1_CASE_19="-s eq:0 -o file:expected34 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg det.sig" +TESTSET_1_CASE_20="-s eq:0 -o file:expected35 -e empty env TZ=US/Pacific netpgpverify -c cat -k pubring.gpg det.sig" +DISABLE_TESTSET_1_CASE_21="-s eq:0 -o file:expected46 -e empty netpgpverify -k problem-pubring.gpg NetBSD-6.0_hashes.asc" + +TESTSET_2_NAME=dsa_signatures +TESTSET_2_FILES=' +dsa-pubring.gpg +in1.gpg +in1.asc +in2.gpg +in2.asc +expected36 +expected37 +expected38 +expected39 +expected40 +expected41 +expected42 +expected43 +expected44 +expected45 +expected46 +' +TESTSET_2_CASE_1="-s eq:0 -o file:expected36 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg in1.gpg" +TESTSET_2_CASE_2="-s eq:0 -o file:expected37 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg < in1.gpg" +TESTSET_2_CASE_3="-s eq:0 -o file:expected38 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg in1.asc" +TESTSET_2_CASE_4="-s eq:0 -o file:expected39 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg < in1.asc" +TESTSET_2_CASE_5="-s eq:0 -o file:expected40 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg -c cat in1.gpg" +TESTSET_2_CASE_6="-s eq:0 -o file:expected41 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg -c cat < in1.gpg" +TESTSET_2_CASE_7="-s eq:0 -o file:expected42 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg -c cat in1.asc" +TESTSET_2_CASE_8="-s eq:0 -o file:expected43 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg -c cat < in1.asc" +TESTSET_2_CASE_9="-s eq:0 -o file:expected44 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg in2.gpg" +TESTSET_2_CASE_10="-s eq:0 -o file:expected45 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg in2.asc" diff --git a/contrib/netbsd-tests/usr.bin/netpgpverify/t_netpgpverify.sh b/contrib/netbsd-tests/usr.bin/netpgpverify/t_netpgpverify.sh new file mode 100755 index 0000000..2d532c0 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/netpgpverify/t_netpgpverify.sh @@ -0,0 +1,7427 @@ +#! /bin/sh + +# $NetBSD: t_netpgpverify.sh,v 1.4 2016/08/28 15:59:15 christos Exp $ + +# +# Copyright (c) 2016 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Alistair Crooks (agc@NetBSD.org) +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# Define test sets with atf_test_case +# There may well be only one test set - these are tests for different +# functionality, so netpgpverify has 2 sets, 1 for RSA and 1 for DSA +# each test set has a +# + *_head() function, to define the set, and +# + *_body(), to set up the supporting input and expected output files +# and some atf_check calls, which actually carry out the tests + +# any binary files should be uuencoded +# we need to give the input and expected output files like this as tests +# take place in a clean directory, so we need to be able to set them up +# from the shell script + +# Test set 1 (rsa_signatures) for netpgpverify +atf_test_case netpgpverify_testset_1_rsa_signatures + +netpgpverify_testset_1_rsa_signatures_head() { + atf_set "descr" "Test set 1 (rsa_signatures) for netpgpverify" +} +netpgpverify_testset_1_rsa_signatures_body() { + uudecode << EOF +begin-base64 644 a.gpg +owGbwMvMwMQonXHnz4HIDGXGNduSGBPD/Rq2KSuo+KWWOAW7WCn4JmanpmXmpOqU +KRjqGSoYGRga6Rsa6hsZKBiYW5maWpmaKCSmJyu4VhQoqHBx6WXmJeeUpqQq2CQV +p+jll+fp5WbbcXGFuAaHBLt4BtkqqFSD2U6Owa61+qXFRXpJmXn6eaklBekFZalF +mWmVUMXxwR7atgol8ahSqMaXpBaXgM3vZJRhYWBkYmBjZQK5noGLUwDmp2X32f/X +n4pynyaz+0jbeluli8/NgkI2bK65Ud+ecUelqkvNaXlNVo3TKyX9TuNUpmX3l7l2 +t2xy4e8veH8/OpurgK9V4EXAB98rbddTgtpzTxhuWH5x0Qf3O0xOzL5MR5SfLH7/ +zJMl72uqUExspt5UJuXIEw+LTj2JKfA7Mcl219+lKebOVlfqpA20HzSeXmaatynY +NrX2BWfpS++vxxJiWL/wtLvzSVk/uZVunlXBsfDV/rbUxFDGPdMuNT/98f6cQ1Fz +/+nLOY84rsk7K/NnulZuvNzb9jw3Qv58qPvep1saRDy6XhcUxhwOmZvh1DvLz/HG +HNZMdVcl/iahoFURvHryU72zzz5eKXgoSc0SAA== +==== +EOF + uudecode << EOF +begin-base64 644 b.gpg +xA0DAAgBG2jc/MBZaCMBy4tiAAAAAABQUk9HPXAKU1JDUz1wYXJzZS5jCldBUk5T +PTUKTUtNQU49bm8KQ1BQRkxBR1MrPS1nIC1PMApMREZMQUdTKz0tZyAtTzAKCi5p +bmNsdWRlIDxic2QucHJvZy5taz4KCnQ6ICR7UFJPR30KCS4vJHtQUk9HfSBncGdz +aWduZWQtYS5ncGcKwsBiBAABCAAWBQJQTZOaBQMAAAAACRAbaNz8wFloIwAABTcH +/RhxktWLH3Cw6YkC/4Wcm9yq6flgiKQsB0VUaVgmmOfWnLxcowyH5ISENo/J6qhT +S8Z0B2lAkRzBhXbfSe8GoESc/NsXTuOIvdjZEy7FBkl9Lumuqp1IlmoXh3RgPv5Z +gcJ+uDCV958uXAxLn017xN/CVKi5yBiNWWk/mOJuI8FCiQCyFVQ3dOXcFU/gf4iZ +YkH6OMX6eNpLQXp+s1ar6ZqpFE09QEoiFuIiDas+V6g0IG1c+PgP+TOlO5ztaKjx +XxejP0Thtft0T+AKTANVrtx+aTseVt4CR3jBt0n4CJjTTRQwnIYxGML3ddgMXSPT +0c4J/4dwyMqdDuhby//52Nw= +==== +EOF + uudecode << EOF +begin-base64 644 det +VG8gRG8KPT09PT0KdGVzdHMgd2l0aCAtayBzaWcKZGV0YWNoZWQgc2lncwpEU0EK +CkRvbmUKPT09PQpiYXNpY3MKbG9jYWxpc2UgcGdwX3JlYWRfcGFja2V0cwpmaXgg +bGludApXQVJOUz01CmxpYiBtYW4gcGFnZQpwcm9nIG1hbiBwYWdlCmRvIHdlIGRv +IGl0IHN0YXRpY2FsbHkgbGlua2VkIGFzIHdlbGw/Cm11bHRpcGxlIGZpbGVzIGlu +IG5ldHBncHZlcmlmeQo= +==== +EOF + uudecode << EOF +begin-base64 644 det.sig +iQEcBAABAgAGBQJQf8gBAAoJEBto3PzAWWgjbLoH/i9MZSv2l9lJ5O+bfGmRSUxe +rGeAM0dq//xi+AABByDEWNYORq2I6CO6k2eVPv7YbNE2Whn7qXA6U7LotM7Lt61l +MCLRhuTv9RViV1qzsy+Z8VAQmhERAcG/qA5JSQbzjuVYhg5FexpiVmxgG9L8Z/Oj +4pU9zIId1vH7CvAcy/mfSyM8Ih8bmsrgs9b1wzMPLQKl0v0jtcrEcnwMtscXa9Mw +X66bHxCHtRyGcWsHU8Ab2fJCvsCbBBMtg3JjZ7+VgDoZqPqBgIkhmppqC05vU5QR +leNo8g9OwiJ6fMtdwTMsFkxqjjVKk5//X/6jQd/mf55XcxLOw4UK4ev5ADExnOU= +==== +EOF + uudecode << EOF +begin-base64 644 jj.asc +LS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UtLS0tLQpIYXNoOiBTSEExCgox +LiB0YWcgJiAweDNmCjIuIGxlbgoKb25lIHBhc3MgKHRhZyA0KQo9PT09PT09PQpi +IHZlcnNpb246MwpiIHNpZyB0eXBlCmIgaGFzaCBhbGcKYiBwdWJrZXkgYWxnCjhi +IGtleWlkCgpsaXRlcmFsIGRhdGEgKHRhZyAxMSkKPT09PT09PT09PT09PQpiIGJp +bmFyeS90ZXh0CmIgbGVuZ3RoCmMgc3RyaW5nCkwgbXRpbWUKdGV4dAotLS0tLUJF +R0lOIFBHUCBTSUdOQVRVUkUtLS0tLQpWZXJzaW9uOiBHbnVQRyB2MS40LjExIChO +ZXRCU0QpCgppUUVjQkFFQkFnQUdCUUpRYUlaY0FBb0pFQnRvM1B6QVdXZ2o2NzhJ +QUxiREhvbjNSbTZxVWhuN2sxVEZUNkQzCnlpL2p6ZjNwaVNKR3NnVWcyd0VnaHMx +NzVlZEMvY0pLM2xHOUd4LzMvdVFxMDZSOWczN25WUlg4STBzSzd5VDIKWGdSK1JI +b0doL2IrQ1F4ZFJOQyt1YjVRb05iOExjbUNiL01RR3EyS0s5b3RTRXhpeTRXTVVQ +NEsxRGJsYUs1TAorSGc0VlRvb01vdDFOVnF5RlNvQjJhWmF1WGMyRjRaVmg1cTBm +bjh3NUdFdzQ1UCtBVVVibXpwZ2JMd1hibCtJCnRNc1g1NFYxZHh5RGNDWVVzMHhV +SC9WeEpVUUVlSWxEYkNPWFlNYkNWdGdnWVJxS2tzVHIrdS9yaXcvTGxucWwKalFk +cTVyQlJXMVNsRDdMbDZ6L0xGMldCSk9XdEh6cDRxYm5CR1NxNXVCMXEzN0gzbVdM +MjhmMXRMLy9UVWpNPQo9RVg4VwotLS0tLUVORCBQR1AgU0lHTkFUVVJFLS0tLS0K +==== +EOF + uudecode << EOF +begin-base64 644 pubring.gpg +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 +StZtC+VbuN66pfHwsAIAAw== +==== +EOF + uudecode << EOF +begin-base64 644 NetBSD-6.0_hashes.asc.gz +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 +tyqIlNwhRRNj3K46lymZxdG+jMqP50E7d6omJEqsrdBOyVztIJMqO/9/5t6tx7Yk +OdL7R6O4X171KggDSBhAb0RcBw2J7AKbwHD+vT5bJ7MrV56duSOzzgCHZLOq67L2 +3ssj3M0i3M2s++Cg6l//9sc/vtSrtkwTM3Qyk6AGQ+aMWiFFRLXou1pMamkfxeyr +n2fZCtKCy7oWrxoZIH5d22OrM6LHLbNldhokyjUoysV+qNVr1wjVt45tCBU3BF4S +jUFmKlOKv5RPCP8lUalm0wmwBEBkzWiQZbI0l6P9kJV99XcoxNEngr7rJXftdHNl +NlVWHcPsyi4lafsw2l8O0iyiFU4tWK4V+cP2JMCutgTf3FeXwr1rdfJ+glPCLH5m +zV/olkui+2woGRQNnVOM/fUlcP8cE6d6rQFMQhyztySti8v6RDPj3Wd2MYQRFGLm +VJOXTu63fOs0WeY1FN5tzLwM6Hoi3Q+1xJCotRrUXNM04TcmHFllFFbQdtM8q+yd +R/166N/JWkmyNy19ZBu6RQ6XI42Am1U+F131fc4vhvydqlXXGQ1fswQTryZSiLCT +IryRUlT77q5/nbSEMjRe9ZyS48qAD11l1ibFgB78AGHM6Pb3d/sLFQYuOskoOFA3 +u9LIlBNaFwC2/BjZGqQIOpe7xLDXQJ2TAab8EsnGidUIHU8D7JkoZFs3hH56WeQ6 +L0kWSbX7rK4o4APpSX1aUqwrXtPr+/u7/JVxU1hWUmtIANUak9jtQAOeGSflSB6O +VKH0zd39KpOm06VcItzEF5lCtxVlGNuMDp/z81A/8PVRCmczgeF94FuyoeWzNrr0 +G6FdQiNtf0wlPn8673ZDvJsV/CXVkcsBH7rDbbDlbeTpQArsgc/LItFAPPaLug67 +JlhBBJr69l3zieRyNnYXopWDh24QG5gQ2OGCTAZ03HhdtO0AyJGPgD0J64MWUk3i +sqs0dkSloeZc7tbqJJAQXQtBLm9xPw3mI2G0qU7ZoTGvreEgp3bnMrwm1ZwphyH8 +hU2knz37d+0i/ew7/6U20s8e/L0+0p+f+AsbST99+O/aSfr5G/krraSfPvl7vaQ/ +PfJhl11X58rmlbbRt9zbqmwRdRI/pbCpsaVVPu57OvoQyohOV7rEXoRuqSYuFXXS +QOaq0l2lIEi3THd+YYyise4kwRLJmhkFLm6AumUHs4/DJo9JfyVCYclEUrRK0jQu +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 +0EbuVRbNvuqeIyzPHtaZBRUy5fhekE8fJfe2bSQElczwIC5wY3ckJtlshwUhHc0V +6dixqqqkB03uzdpOuSp16zjYs1iCISPbEs1iJ2mgNxaygRW7D+WQpJfeURNJlaKT +teyFzVbo74X69BOWDqel4WZj8i2RnsZh9dS9BfBuJ01RlYw3An76HL2l5rxvRleH +uqYHo+RQu+6j4Mnvhf2f/nv4p7/7tUNE1kawvVo7gIoSNuAB0jCAiQ+d0MnVJb0b +9puPgkcKtkhuIAcdkxAK0OrWnMjoY5ETy2pqsJONyMhNfguHsOXSob/MKrSbvXPh +uD5coU+pvrajLZxUkewxbX+g29UKPGOyFX2lQq+VzLthv/kJMRXJSHRxlwywWyCv +47oidguz9TY1D+mcb4X95nMyK7noaESKmuqy7pI1A07lxNv41A3j/gf81//5T//w +j18fDB2AeYriiHeyp5qOEyW+oOlgUmrr5pvi/Avhvv0Iy0bQyRUwF8rbu5WqvwCd +/BIPsdd9EH/pKFvHRzqZ29SSi5WrSWyHCxq5SM25OS6Ac5yasxQHTw3cJg2jCES3 +JQ8y6xS/tFFiakZ3nK+F+farS6dBLbGFfNLlrZx1YJtWYxmyE0qXwW6Z6ZXw3j4f +2laUrCWrs2WIO5p0nyOPXG0V+1JY/9v//E//4+///j//519vLFgYvKWkQ6plvJfd +JXxd4gHZ7hbVQEDpfDGyHz7FfvEOS5qRmmxVAFklWoQXGt+XIpUkFT+tukrc1vWJ +Lor3MaEaR9vgnjyDhC7VEwZzXxp7Am57ie0VFgD/XtrkVM1ueV6/Y4FIMko9fy8G +98O37+QIvq92LCSlSe9vFl7SlPI26FqOVeCa/Ep8P3yEJM2dm8blEPhxuoANZGrZ +HVPKSnsrxP/8P/7+//kWgCI/vuGmVXsx5MPqzYUGxhfnz8doNlvlzTDffFIiD1MX +dGs657JykipqqZ1xQ4hSLUkld0JsReODJrShJk7uhXX7YKTRA7rdzslDIEsWiARe +mpFPNxyPPwNvWP4BG3jKIQ+u3NUj2ADlY70Z6ptfsFvXKSN7YpbSJC4qffgaHWsP +yt+0usZ8DXd/8jFy92MJFXErCalQOouASUkCOp/6Ddw+/w8d3Hr04B9ycOvRF35/ +cOvRU98Y3Pr94/6owa2HT/4hB7cev4u3B7cePvaNwa3fPe800wBr/tXTi4erTX7z ++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 +U/o9Sm1r56e/gN/ulLvyMsZPONUwbMCMlre0xtm1YsKkim4T2i5Ukq9uO2yLM4Zt +UCkR2CFepQt0dPlIcGhhe6F/FTJ9SKJB/gfz499IgnNIEunP6gU293Twf/sFC1jD +LIwxA+H0TqbvifEXgdVEixlKck/G/bfbOL2EiZ8Lw2dpKbOnWGgZmUFvwaRvhvxl +xW+EwQuKG4p4R0VFOC+Ka1llFUUhF/pz3Lfj/come/IDm3QtVEEaFeFER5Bgq2f2 +pymOKBnXmJSm8XlbGd0zRb1gkVD1Pu1lmuDyWKIG2IW5jftcwlssm23EgZuCjQS9 +mH+IU5cvMSOEur8d7NceYpFUfaWMRS3PLCS+mIJVTpwsuGBUZpnN/V6kX7a8w0w7 +CSS4EvJKO2LNhXHfyFlwZn4zwb+Qyb2UTumxEUkyWC2AWgTDo9abwUbWqaTv8e3E +/rKmmersfY6NRhrz1AMpRz1/7UkcKjXf0XtnWBJbheV3NK4LovWrX7YpbALhZrPq +tdz32F7cC1iPztFe9MDo46/oji7BMd1N5Hu65JUCW/h2Qn/Z4kYaCimMKUiytKSt +KaoVwo6T42p9Sq1bP/L3EvnravY7Ny24yXlfS9EzFiuWNZL+x65fhvkPV/b5+NJ/ +tto+Hz/y/566z8fX/aa+z9sL/pEKP59c+89W4+ez9/G/pfLzyYW/qfPz5oq3wd6/ ++3e/ZvD80quKWy8klShUdilL6PvXDYfKApZF8ZOewLPbOEbYVQ61vAp1v2nR4Uy7 +xZVX5HSyqWpcJwk4QgcMneqEZwanou4nJ6kelVfT/aA/Hj3liA+b6mRr+jiSvvBW +LWPFeuGqzXpF7I8EnENPA/rB4/uMT+Fm0mLYrOx9zUxYfXeKjNZoV4JX0jpblR/c +I5uZ7ArIQxS9KvJhStOgia/fZNdZmB+btcWBOKQXac3CmWEWn9zqYuwisioRU8Gg ++pjT2N4azPH/SPR3gVCwfsZsnYOTLELLPsBiTL7pntfs4mzbF6PirX8SYxuYKaKQ +U/RfWnjVrCsbCZ13fQhpLIU7bfwvMNSdGbata64LZXhznFpvOkU+GubLPO1m6Ogg +bm9aqVE3Skxg6HmTj0dRvL9oDNH1jsfI+lExhcuBeXcXWm4fylu8ueLj7La+c3h8 +pC3eeKPKuui5a0ooClyqkQErVcXT0N1UhThajN4IG8SOXlUbNSmbGNWXNe0aPQQf +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 +63c/sI/ST4/uP3o073xx/8aDm+HLr38bX5V47dcHz2u62b6zz0f+/vY/3/vxYf/P +90+fPPzllzvzw/FjdD9c/+fNx/Gbn6//+lX7/BMfvjS3W3ny4vdP7z/76scv71xL +dz+5+8v9B789/+H6jY++8f/qD5/867tvf/v1vbvP4/Wv8r3nn62n//zhy2dPzZ1b +X//7s0dPv8wf/+fn8u+b8fntj3+pz679+HG4ux798uv2y7f3y70Pknn69cOfPv3h +obt/68EHd776bdz843n/6ZPtm4fzwW/XP37+6fNfvvnm2b343c/Xn4YX9vtrX3zz +2U+Pv3/85fxo3rz/9ffX/xjLfPPi92d/rJ8+eXr39+/urC/y9+/d/c+PH7XH1/+1 +nt6+c/uLfHM9fHAvXQ9ffPjztce3bt2xjx494P6s3Pn27vXfb/vb7bv1zdMb9vH2 +5Na/f/rnJy/K7x8+/+TO/burfPX8n/67B5+37x+/mA+++/Wzm9f+Yz//9tvf/C/x +0U3/6ON79Yu7f3ypiPC5+f7bh09vvBf79a/uvffVk5+efGDufdp+/fDZD7999/TO +i7r9/uzzX839G9duf5TN3X/a+3cf3Lz707I37j364vtfPv3xt3+t35W6Xe/6bfnx +/V/e++3x7Yc/fPHj7Wc3Xnx076MH6+GjP8rPX975+doH//7i+bOP/p3vv7jR4s9P +zQfun59tN756+tuzm7d+/DLdjvX6oxg+/Ohbc7/Gr/8I9cUq929/9MX12+3FXD9+ +cu36XXvj0zuPXPz9h9/6oz8++LLceTpvP/sgmE8e/7g9efLRk5u/vLiRf/rsl/DA +3X04f/vpAz9/efrTN0/lc9972q+ZB1/f//zZjU9a/P73p4+/IF15+OT2rVuf3r31 +3Yzxu/7Tg3L/0xeP37t+3z76z40H9sObn3//6EF58Um7/ezu7XvX4h/3fnh+45O7 +5fP5xwfmgf3mvV8/uvZ/H33yXT/ZJLc+v3neFvn/qZKFEe79DQA= +==== +EOF + gunzip NetBSD-6.0_hashes.asc.gz + uudecode << EOF +begin-base64 644 expected16 +R29vZCBzaWduYXR1cmUgZm9yIGIuZ3BnIG1hZGUgTW9uIFNlcCAxMCAwMDoxNToz +OCAyMDEyCnNpZ25hdHVyZSAgICAgMjA0OC9SU0EgKEVuY3J5cHQgb3IgU2lnbikg +MWI2OGRjZmNjMDU5NjgyMyAyMDA0LTAxLTEyCmZpbmdlcnByaW50ICAgZDQxNSA5 +ZGViIDMzNmQgZTRjYyBjZGZhIDAwY2QgMWI2OCBkY2ZjIGMwNTkgNjgyMyAKdWlk +ICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0BhbGlzdGFpcmNyb29rcy5j +b20+CnVpZCAgICAgICAgICAgQWxpc3RhaXIgQ3Jvb2tzIDxhZ2NAcGtnc3JjLm9y +Zz4KdWlkICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0BuZXRic2Qub3Jn +Pgp1aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQG5ldGZsaXguY29t +PgoK +==== +EOF + uudecode << EOF +begin-base64 644 expected17 +R29vZCBzaWduYXR1cmUgZm9yIGEuZ3BnIG1hZGUgU3VuIFNlcCAgOSAxNzo0NDox +MSAyMDEyCnNpZ25hdHVyZSAgMjA0OC9SU0EgKEVuY3J5cHQgb3IgU2lnbikgMWI2 +OGRjZmNjMDU5NjgyMyAyMDA0LTAxLTEyCmZpbmdlcnByaW50OiAgZDQxNSA5ZGVi +IDMzNmQgZTRjYyBjZGZhIDAwY2QgMWI2OCBkY2ZjIGMwNTkgNjgyMyAKdWlkICAg +ICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0BhbGlzdGFpcmNyb29rcy5j +b20+CnVpZCAgICAgICAgICAgICAgQWxpc3RhaXIgQ3Jvb2tzIDxhZ2NAcGtnc3Jj +Lm9yZz4KdWlkICAgICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0BuZXRi +c2Qub3JnPgp1aWQgICAgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQG5l +dGZsaXguY29tPgplbmNyeXB0aW9uIDIwNDgvUlNBIChFbmNyeXB0IG9yIFNpZ24p +IDc5ZGViNjFlNDg4ZWVlNzQgMjAwNC0wMS0xMgpmaW5nZXJwcmludDogIDU3YzAg +YzFlNiBiZjcxIDg4NDUgNDE2YiA5NTIyIDc5ZGUgYjYxZSA0ODhlIGVlNzQgCgo= +==== +EOF + uudecode << EOF +begin-base64 644 expected18 +R29vZCBzaWduYXR1cmUgZm9yIGEuZ3BnIG1hZGUgVHVlIE1heSAzMSAyMzoyOTox +MCAyMDE2CnNpZ25hdHVyZSAgICAgMjA0OC9SU0EgKEVuY3J5cHQgb3IgU2lnbikg +MWI2OGRjZmNjMDU5NjgyMyAyMDA0LTAxLTEyCmZpbmdlcnByaW50ICAgZDQxNSA5 +ZGViIDMzNmQgZTRjYyBjZGZhIDAwY2QgMWI2OCBkY2ZjIGMwNTkgNjgyMyAKdWlk +ICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0BhbGlzdGFpcmNyb29rcy5j +b20+CnVpZCAgICAgICAgICAgQWxpc3RhaXIgQ3Jvb2tzIDxhZ2NAcGtnc3JjLm9y +Zz4KdWlkICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0BuZXRic2Qub3Jn +Pgp1aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQG5ldGZsaXguY29t +PgoK +==== +EOF + uudecode << EOF +begin-base64 644 expected19 +R29vZCBzaWduYXR1cmUgZm9yIE5ldEJTRC02LjBfUkMyX2hhc2hlcy5hc2MgbWFk +ZSBXZWQgU2VwIDE5IDA3OjUzOjE4IDIwMTIKc2lnbmF0dXJlICA0MDk2L1JTQSAo +RW5jcnlwdCBvciBTaWduKSAwNjQ5NzNhYzRjNGE3MDZlIDIwMDktMDYtMjMKZmlu +Z2VycHJpbnQ6ICBkZGVlIDJiZGIgOWM5OCBhMGQxIGQ0ZmIgZGJmNyAwNjQ5IDcz +YWMgNGM0YSA3MDZlIAp1aWQgICAgICAgICAgICAgIE5ldEJTRCBTZWN1cml0eSBP +ZmZpY2VyIDxzZWN1cml0eS1vZmZpY2VyQE5ldEJTRC5vcmc+CmVuY3J5cHRpb24g +NDA5Ni9SU0EgKEVuY3J5cHQgb3IgU2lnbikgOWZmMmMyNGZkZjJjZTYyMCAyMDA5 +LTA2LTIzIFtFeHBpcnkgMjAxOS0wNi0yMV0KZmluZ2VycHJpbnQ6ICAxOTE1IDA4 +MDEgZmJkOCBmNDVkIDg5ZjIgMDIwNSA5ZmYyIGMyNGYgZGYyYyBlNjIwIAoK +==== +EOF + uudecode << EOF +begin-base64 644 expected20 +MS4gdGFnICYgMHgzZgoyLiBsZW4KCm9uZSBwYXNzICh0YWcgNCkKPT09PT09PT0K +YiB2ZXJzaW9uOjMKYiBzaWcgdHlwZQpiIGhhc2ggYWxnCmIgcHVia2V5IGFsZwo4 +YiBrZXlpZAoKbGl0ZXJhbCBkYXRhICh0YWcgMTEpCj09PT09PT09PT09PT0KYiBi +aW5hcnkvdGV4dApiIGxlbmd0aApjIHN0cmluZwpMIG10aW1lCnRleHQK +==== +EOF + uudecode << EOF +begin-base64 644 expected21 +R29vZCBzaWduYXR1cmUgZm9yIFtzdGRpbl0gbWFkZSBUdWUgTWF5IDMxIDIzOjI5 +OjEwIDIwMTYKc2lnbmF0dXJlICAgICAyMDQ4L1JTQSAoRW5jcnlwdCBvciBTaWdu +KSAxYjY4ZGNmY2MwNTk2ODIzIDIwMDQtMDEtMTIKZmluZ2VycHJpbnQgICBkNDE1 +IDlkZWIgMzM2ZCBlNGNjIGNkZmEgMDBjZCAxYjY4IGRjZmMgYzA1OSA2ODIzIAp1 +aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQGFsaXN0YWlyY3Jvb2tz +LmNvbT4KdWlkICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0Bwa2dzcmMu +b3JnPgp1aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQG5ldGJzZC5v +cmc+CnVpZCAgICAgICAgICAgQWxpc3RhaXIgQ3Jvb2tzIDxhZ2NAbmV0ZmxpeC5j +b20+Cgo= +==== +EOF + uudecode << EOF +begin-base64 644 expected22 +R29vZCBzaWduYXR1cmUgZm9yIFtzdGRpbl0gbWFkZSBTdW4gU2VwIDMwIDEwOjUw +OjIwIDIwMTIKc2lnbmF0dXJlICAgICAyMDQ4L1JTQSAoRW5jcnlwdCBvciBTaWdu +KSAxYjY4ZGNmY2MwNTk2ODIzIDIwMDQtMDEtMTIKZmluZ2VycHJpbnQgICBkNDE1 +IDlkZWIgMzM2ZCBlNGNjIGNkZmEgMDBjZCAxYjY4IGRjZmMgYzA1OSA2ODIzIAp1 +aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQGFsaXN0YWlyY3Jvb2tz +LmNvbT4KdWlkICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0Bwa2dzcmMu +b3JnPgp1aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQG5ldGJzZC5v +cmc+CnVpZCAgICAgICAgICAgQWxpc3RhaXIgQ3Jvb2tzIDxhZ2NAbmV0ZmxpeC5j +b20+Cgo= +==== +EOF + uudecode << EOF +begin-base64 644 expected23 +R29vZCBzaWduYXR1cmUgZm9yIFtzdGRpbl0gbWFkZSBXZWQgU2VwIDE5IDA3OjUz +OjE4IDIwMTIKc2lnbmF0dXJlICA0MDk2L1JTQSAoRW5jcnlwdCBvciBTaWduKSAw +NjQ5NzNhYzRjNGE3MDZlIDIwMDktMDYtMjMKZmluZ2VycHJpbnQ6ICBkZGVlIDJi +ZGIgOWM5OCBhMGQxIGQ0ZmIgZGJmNyAwNjQ5IDczYWMgNGM0YSA3MDZlIAp1aWQg +ICAgICAgICAgICAgIE5ldEJTRCBTZWN1cml0eSBPZmZpY2VyIDxzZWN1cml0eS1v +ZmZpY2VyQE5ldEJTRC5vcmc+CmVuY3J5cHRpb24gNDA5Ni9SU0EgKEVuY3J5cHQg +b3IgU2lnbikgOWZmMmMyNGZkZjJjZTYyMCAyMDA5LTA2LTIzIFtFeHBpcnkgMjAx +OS0wNi0yMV0KZmluZ2VycHJpbnQ6ICAxOTE1IDA4MDEgZmJkOCBmNDVkIDg5ZjIg +MDIwNSA5ZmYyIGMyNGYgZGYyYyBlNjIwIAoK +==== +EOF + uudecode << EOF +begin-base64 644 expected24 +R29vZCBzaWduYXR1cmUgZm9yIFtzdGRpbl0gbWFkZSBNb24gU2VwIDEwIDAwOjE1 +OjM4IDIwMTIKc2lnbmF0dXJlICAgICAyMDQ4L1JTQSAoRW5jcnlwdCBvciBTaWdu +KSAxYjY4ZGNmY2MwNTk2ODIzIDIwMDQtMDEtMTIKZmluZ2VycHJpbnQgICBkNDE1 +IDlkZWIgMzM2ZCBlNGNjIGNkZmEgMDBjZCAxYjY4IGRjZmMgYzA1OSA2ODIzIAp1 +aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQGFsaXN0YWlyY3Jvb2tz +LmNvbT4KdWlkICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0Bwa2dzcmMu +b3JnPgp1aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQG5ldGJzZC5v +cmc+CnVpZCAgICAgICAgICAgQWxpc3RhaXIgQ3Jvb2tzIDxhZ2NAbmV0ZmxpeC5j +b20+Cgo= +==== +EOF + uudecode << EOF +begin-base64 644 expected25 +R29vZCBzaWduYXR1cmUgZm9yIE5ldEJTRC02LjBfUkMxX2hhc2hlcy5ncGcgbWFk +ZSBUdWUgT2N0IDE2IDA4OjEyOjE2IDIwMTIKc2lnbmF0dXJlICA0MDk2L1JTQSAo +RW5jcnlwdCBvciBTaWduKSAwNjQ5NzNhYzRjNGE3MDZlIDIwMDktMDYtMjMKZmlu +Z2VycHJpbnQ6ICBkZGVlIDJiZGIgOWM5OCBhMGQxIGQ0ZmIgZGJmNyAwNjQ5IDcz +YWMgNGM0YSA3MDZlIAp1aWQgICAgICAgICAgICAgIE5ldEJTRCBTZWN1cml0eSBP +ZmZpY2VyIDxzZWN1cml0eS1vZmZpY2VyQE5ldEJTRC5vcmc+CmVuY3J5cHRpb24g +NDA5Ni9SU0EgKEVuY3J5cHQgb3IgU2lnbikgOWZmMmMyNGZkZjJjZTYyMCAyMDA5 +LTA2LTIzIFtFeHBpcnkgMjAxOS0wNi0yMV0KZmluZ2VycHJpbnQ6ICAxOTE1IDA4 +MDEgZmJkOCBmNDVkIDg5ZjIgMDIwNSA5ZmYyIGMyNGYgZGYyYyBlNjIwIAoK +==== +EOF + uudecode << EOF +begin-base64 644 expected26 +R29vZCBzaWduYXR1cmUgZm9yIFtzdGRpbl0gbWFkZSBUdWUgT2N0IDE2IDA4OjEy +OjE2IDIwMTIKc2lnbmF0dXJlICA0MDk2L1JTQSAoRW5jcnlwdCBvciBTaWduKSAw +NjQ5NzNhYzRjNGE3MDZlIDIwMDktMDYtMjMKZmluZ2VycHJpbnQ6ICBkZGVlIDJi +ZGIgOWM5OCBhMGQxIGQ0ZmIgZGJmNyAwNjQ5IDczYWMgNGM0YSA3MDZlIAp1aWQg +ICAgICAgICAgICAgIE5ldEJTRCBTZWN1cml0eSBPZmZpY2VyIDxzZWN1cml0eS1v +ZmZpY2VyQE5ldEJTRC5vcmc+CmVuY3J5cHRpb24gNDA5Ni9SU0EgKEVuY3J5cHQg +b3IgU2lnbikgOWZmMmMyNGZkZjJjZTYyMCAyMDA5LTA2LTIzIFtFeHBpcnkgMjAx +OS0wNi0yMV0KZmluZ2VycHJpbnQ6ICAxOTE1IDA4MDEgZmJkOCBmNDVkIDg5ZjIg +MDIwNSA5ZmYyIGMyNGYgZGYyYyBlNjIwIAoK +==== +EOF + uudecode << EOF +begin-base64 644 expected27 +R29vZCBzaWduYXR1cmUgZm9yIFtzdGRpbl0gbWFkZSBNb24gT2N0IDE1IDA5OjI4 +OjU0IDIwMTIKc2lnbmF0dXJlICAgICA0MDk2L1JTQSAoRW5jcnlwdCBvciBTaWdu +KSAwNjQ5NzNhYzRjNGE3MDZlIDIwMDktMDYtMjMKZmluZ2VycHJpbnQgICBkZGVl +IDJiZGIgOWM5OCBhMGQxIGQ0ZmIgZGJmNyAwNjQ5IDczYWMgNGM0YSA3MDZlIAp1 +aWQgICAgICAgICAgIE5ldEJTRCBTZWN1cml0eSBPZmZpY2VyIDxzZWN1cml0eS1v +ZmZpY2VyQE5ldEJTRC5vcmc+Cgo= +==== +EOF + uudecode << EOF +begin-base64 644 expected28 +R29vZCBzaWduYXR1cmUgZm9yIE5ldEJTRC02LjBfaGFzaGVzLmFzYyBtYWRlIE1v +biBPY3QgMTUgMDk6Mjg6NTQgMjAxMgpzaWduYXR1cmUgICAgIDQwOTYvUlNBIChF +bmNyeXB0IG9yIFNpZ24pIDA2NDk3M2FjNGM0YTcwNmUgMjAwOS0wNi0yMwpmaW5n +ZXJwcmludCAgIGRkZWUgMmJkYiA5Yzk4IGEwZDEgZDRmYiBkYmY3IDA2NDkgNzNh +YyA0YzRhIDcwNmUgCnVpZCAgICAgICAgICAgTmV0QlNEIFNlY3VyaXR5IE9mZmlj +ZXIgPHNlY3VyaXR5LW9mZmljZXJATmV0QlNELm9yZz4KCg== +==== +EOF + uudecode << EOF +begin-base64 644 expected29 +R29vZCBzaWduYXR1cmUgZm9yIE5ldEJTRC02LjBfUkMxX2hhc2hlc19hc2NpaS5n +cGcgbWFkZSBTdW4gU2VwICA5IDE3OjQxOjI0IDIwMTIKc2lnbmF0dXJlICA0MDk2 +L1JTQSAoRW5jcnlwdCBvciBTaWduKSAwNjQ5NzNhYzRjNGE3MDZlIDIwMDktMDYt +MjMKZmluZ2VycHJpbnQ6ICBkZGVlIDJiZGIgOWM5OCBhMGQxIGQ0ZmIgZGJmNyAw +NjQ5IDczYWMgNGM0YSA3MDZlIAp1aWQgICAgICAgICAgICAgIE5ldEJTRCBTZWN1 +cml0eSBPZmZpY2VyIDxzZWN1cml0eS1vZmZpY2VyQE5ldEJTRC5vcmc+CmVuY3J5 +cHRpb24gNDA5Ni9SU0EgKEVuY3J5cHQgb3IgU2lnbikgOWZmMmMyNGZkZjJjZTYy +MCAyMDA5LTA2LTIzIFtFeHBpcnkgMjAxOS0wNi0yMV0KZmluZ2VycHJpbnQ6ICAx +OTE1IDA4MDEgZmJkOCBmNDVkIDg5ZjIgMDIwNSA5ZmYyIGMyNGYgZGYyYyBlNjIw +IAoK +==== +EOF + uudecode << EOF +begin-base64 644 expected30 +R29vZCBzaWduYXR1cmUgZm9yIFtzdGRpbl0gbWFkZSBTdW4gU2VwICA5IDE3OjQx +OjI0IDIwMTIKc2lnbmF0dXJlICA0MDk2L1JTQSAoRW5jcnlwdCBvciBTaWduKSAw +NjQ5NzNhYzRjNGE3MDZlIDIwMDktMDYtMjMKZmluZ2VycHJpbnQ6ICBkZGVlIDJi +ZGIgOWM5OCBhMGQxIGQ0ZmIgZGJmNyAwNjQ5IDczYWMgNGM0YSA3MDZlIAp1aWQg +ICAgICAgICAgICAgIE5ldEJTRCBTZWN1cml0eSBPZmZpY2VyIDxzZWN1cml0eS1v +ZmZpY2VyQE5ldEJTRC5vcmc+CmVuY3J5cHRpb24gNDA5Ni9SU0EgKEVuY3J5cHQg +b3IgU2lnbikgOWZmMmMyNGZkZjJjZTYyMCAyMDA5LTA2LTIzIFtFeHBpcnkgMjAx +OS0wNi0yMV0KZmluZ2VycHJpbnQ6ICAxOTE1IDA4MDEgZmJkOCBmNDVkIDg5ZjIg +MDIwNSA5ZmYyIGMyNGYgZGYyYyBlNjIwIAoK +==== +EOF + uudecode << EOF +begin-base64 644 expected31 +UFJPRz1wClNSQ1M9cGFyc2UuYwpXQVJOUz01Ck1LTUFOPW5vCkNQUEZMQUdTKz0t +ZyAtTzAKTERGTEFHUys9LWcgLU8wCgouaW5jbHVkZSA8YnNkLnByb2cubWs+Cgp0 +OiAke1BST0d9CgkuLyR7UFJPR30gZ3Bnc2lnbmVkLWEuZ3BnClBST0c9cApTUkNT +PXBhcnNlLmMKV0FSTlM9NQpNS01BTj1ubwpDUFBGTEFHUys9LWcgLU8wCkxERkxB +R1MrPS1nIC1PMAoKLmluY2x1ZGUgPGJzZC5wcm9nLm1rPgoKdDogJHtQUk9HfQoJ +Li8ke1BST0d9IGdwZ3NpZ25lZC1hLmdwZwpQUk9HPXAKU1JDUz1wYXJzZS5jCldB +Uk5TPTUKTUtNQU49bm8KQ1BQRkxBR1MrPS1nIC1PMApMREZMQUdTKz0tZyAtTzAK +Ci5pbmNsdWRlIDxic2QucHJvZy5taz4KCnQ6ICR7UFJPR30KCS4vJHtQUk9HfSBn +cGdzaWduZWQtYS5ncGcK +==== +EOF + uudecode << EOF +begin-base64 644 expected32 +R29vZCBzaWduYXR1cmUgZm9yIGIuZ3BnIG1hZGUgTW9uIFNlcCAxMCAwMDoxNToz +OCAyMDEyCnNpZ25hdHVyZSAgICAgMjA0OC9SU0EgKEVuY3J5cHQgb3IgU2lnbikg +MWI2OGRjZmNjMDU5NjgyMyAyMDA0LTAxLTEyCmZpbmdlcnByaW50ICAgZDQxNSA5 +ZGViIDMzNmQgZTRjYyBjZGZhIDAwY2QgMWI2OCBkY2ZjIGMwNTkgNjgyMyAKdWlk +ICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0BhbGlzdGFpcmNyb29rcy5j +b20+CnVpZCAgICAgICAgICAgQWxpc3RhaXIgQ3Jvb2tzIDxhZ2NAcGtnc3JjLm9y +Zz4KdWlkICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0BuZXRic2Qub3Jn +Pgp1aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQG5ldGZsaXguY29t +PgoKR29vZCBzaWduYXR1cmUgZm9yIGIuZ3BnIG1hZGUgTW9uIFNlcCAxMCAwMDox +NTozOCAyMDEyCnNpZ25hdHVyZSAgICAgMjA0OC9SU0EgKEVuY3J5cHQgb3IgU2ln +bikgMWI2OGRjZmNjMDU5NjgyMyAyMDA0LTAxLTEyCmZpbmdlcnByaW50ICAgZDQx +NSA5ZGViIDMzNmQgZTRjYyBjZGZhIDAwY2QgMWI2OCBkY2ZjIGMwNTkgNjgyMyAK +dWlkICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0BhbGlzdGFpcmNyb29r +cy5jb20+CnVpZCAgICAgICAgICAgQWxpc3RhaXIgQ3Jvb2tzIDxhZ2NAcGtnc3Jj +Lm9yZz4KdWlkICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0BuZXRic2Qu +b3JnPgp1aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQG5ldGZsaXgu +Y29tPgoKR29vZCBzaWduYXR1cmUgZm9yIGIuZ3BnIG1hZGUgTW9uIFNlcCAxMCAw +MDoxNTozOCAyMDEyCnNpZ25hdHVyZSAgICAgMjA0OC9SU0EgKEVuY3J5cHQgb3Ig +U2lnbikgMWI2OGRjZmNjMDU5NjgyMyAyMDA0LTAxLTEyCmZpbmdlcnByaW50ICAg +ZDQxNSA5ZGViIDMzNmQgZTRjYyBjZGZhIDAwY2QgMWI2OCBkY2ZjIGMwNTkgNjgy +MyAKdWlkICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0BhbGlzdGFpcmNy +b29rcy5jb20+CnVpZCAgICAgICAgICAgQWxpc3RhaXIgQ3Jvb2tzIDxhZ2NAcGtn +c3JjLm9yZz4KdWlkICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0BuZXRi +c2Qub3JnPgp1aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQG5ldGZs +aXguY29tPgoK +==== +EOF + uudecode << EOF +begin-base64 644 expected33 +UFJPRz1wClNSQ1M9cGFyc2UuYwpXQVJOUz01Ck1LTUFOPW5vCkNQUEZMQUdTKz0t +ZyAtTzAKTERGTEFHUys9LWcgLU8wCgouaW5jbHVkZSA8YnNkLnByb2cubWs+Cgp0 +OiAke1BST0d9CgkuLyR7UFJPR30gZ3Bnc2lnbmVkLWEuZ3BnCjEuIHRhZyAmIDB4 +M2YKMi4gbGVuCgpvbmUgcGFzcyAodGFnIDQpCj09PT09PT09CmIgdmVyc2lvbjoz +CmIgc2lnIHR5cGUKYiBoYXNoIGFsZwpiIHB1YmtleSBhbGcKOGIga2V5aWQKCmxp +dGVyYWwgZGF0YSAodGFnIDExKQo9PT09PT09PT09PT09CmIgYmluYXJ5L3RleHQK +YiBsZW5ndGgKYyBzdHJpbmcKTCBtdGltZQp0ZXh0ClBST0c9cApTUkNTPXBhcnNl +LmMKV0FSTlM9NQpNS01BTj1ubwpDUFBGTEFHUys9LWcgLU8wCkxERkxBR1MrPS1n +IC1PMAoKLmluY2x1ZGUgPGJzZC5wcm9nLm1rPgoKdDogJHtQUk9HfQoJLi8ke1BS +T0d9IGdwZ3NpZ25lZC1hLmdwZwo= +==== +EOF + uudecode << EOF +begin-base64 644 expected34 +R29vZCBzaWduYXR1cmUgZm9yIGRldC5zaWcgbWFkZSBUaHUgT2N0IDE4IDAyOjEy +OjMzIDIwMTIKc2lnbmF0dXJlICAgICAyMDQ4L1JTQSAoRW5jcnlwdCBvciBTaWdu +KSAxYjY4ZGNmY2MwNTk2ODIzIDIwMDQtMDEtMTIKZmluZ2VycHJpbnQgICBkNDE1 +IDlkZWIgMzM2ZCBlNGNjIGNkZmEgMDBjZCAxYjY4IGRjZmMgYzA1OSA2ODIzIAp1 +aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQGFsaXN0YWlyY3Jvb2tz +LmNvbT4KdWlkICAgICAgICAgICBBbGlzdGFpciBDcm9va3MgPGFnY0Bwa2dzcmMu +b3JnPgp1aWQgICAgICAgICAgIEFsaXN0YWlyIENyb29rcyA8YWdjQG5ldGJzZC5v +cmc+CnVpZCAgICAgICAgICAgQWxpc3RhaXIgQ3Jvb2tzIDxhZ2NAbmV0ZmxpeC5j +b20+Cgo= +==== +EOF + uudecode << EOF +begin-base64 644 expected35 +VG8gRG8KPT09PT0KdGVzdHMgd2l0aCAtayBzaWcKZGV0YWNoZWQgc2lncwpEU0EK +CkRvbmUKPT09PQpiYXNpY3MKbG9jYWxpc2UgcGdwX3JlYWRfcGFja2V0cwpmaXgg +bGludApXQVJOUz01CmxpYiBtYW4gcGFnZQpwcm9nIG1hbiBwYWdlCmRvIHdlIGRv +IGl0IHN0YXRpY2FsbHkgbGlua2VkIGFzIHdlbGw/Cm11bHRpcGxlIGZpbGVzIGlu +IG5ldHBncHZlcmlmeQo= +==== +EOF + atf_check -s eq:0 -o file:expected16 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg -c verify b.gpg + atf_check -s eq:0 -o file:expected18 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg -c verify a.gpg +# atf_check -s eq:0 -o file:expected19 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg -c verify NetBSD-6.0_RC2_hashes.asc + atf_check -s eq:0 -o file:expected20 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg -c cat jj.asc + atf_check -s eq:0 -o file:expected21 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg < a.gpg + atf_check -s eq:0 -o file:expected22 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg < jj.asc +# atf_check -s eq:0 -o file:expected23 -e empty env TZ=US/Pacific netpgpverify < NetBSD-6.0_RC2_hashes.asc + atf_check -s eq:0 -o file:expected24 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg < b.gpg + #atf_check -s eq:0 -o file:expected25 -e empty netpgpverify NetBSD-6.0_RC1_hashes.gpg + #atf_check -s eq:0 -o file:expected26 -e empty netpgpverify < NetBSD-6.0_RC1_hashes.gpg + atf_check -s eq:0 -o file:expected27 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg < NetBSD-6.0_hashes.asc + atf_check -s eq:0 -o file:expected28 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg NetBSD-6.0_hashes.asc + #atf_check -s eq:0 -o file:expected29 -e empty netpgpverify NetBSD-6.0_RC1_hashes_ascii.gpg + #atf_check -s eq:0 -o file:expected30 -e empty netpgpverify < NetBSD-6.0_RC1_hashes_ascii.gpg + atf_check -s eq:0 -o file:expected31 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg -c cat b.gpg b.gpg b.gpg + atf_check -s eq:0 -o file:expected32 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg b.gpg b.gpg b.gpg + atf_check -s eq:0 -o file:expected33 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg -c cat b.gpg jj.asc b.gpg + atf_check -s eq:0 -o file:expected34 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg det.sig + atf_check -s eq:0 -o file:expected35 -e empty env TZ=US/Pacific netpgpverify -k pubring.gpg -c cat det.sig + #atf_check -s eq:0 -o file:expected46 -e empty netpgpverify -k problem-pubring.gpg NetBSD-6.0_hashes.asc +} + +# Test set 2 (dsa_signatures) for netpgpverify +atf_test_case netpgpverify_testset_2_dsa_signatures + +netpgpverify_testset_2_dsa_signatures_head() { + atf_set "descr" "Test set 2 (dsa_signatures) for netpgpverify" +} +netpgpverify_testset_2_dsa_signatures_body() { + uudecode << EOF +begin-base64 644 dsa-pubring.gpg +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 +OTZKjAvuLXkOVnawAgAD +==== +EOF + uudecode << EOF +begin-base64 644 in1.gpg +owGbwMvMwCGoZv+8NenRnzrGNY1JzJl5hgGthk+VOfX8Ukucgl2sFHwTs1PTMnNS +dcoUDPVM9QwN9AwVjAwMjfQNTPUNzBQMLawMTawMzRQS05MVXCsKFPS4uIJDnVw8 +g7RtOXMykxT0wh09QxBCSZl5XFx6mXnJOaUpqQo2ScUpesWlSSmZRXq52XZcHXEs +DIIcDGysTCBXMHBxCsBct0iSkWHa0k9iZ5i+mtQ43zvsb7nA9sWeSrvwubEbQw0P +MNe3Vuky/C+59v/fFbGv5ofnzRSY/ld6vkfIxCtxoVEnvHZVrZeeb60BAA== +==== +EOF + uudecode << EOF +begin-base64 644 in1.asc +LS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UtLS0tLQpIYXNoOiBTSEEyNTYK +CiMJLk5ldEJTRDogTWFrZWZpbGUsdiAxLjUuMTAuMSAyMDEyLzA1LzA2IDE4OjE0 +OjE2IGFnYyBFeHAgLgoKU1VCRElSKz0JbGliIC5XQUlUClNVQkRJUis9CWJpbgoK +LmluY2x1ZGUgPGJzZC5zdWJkaXIubWs+Ci0tLS0tQkVHSU4gUEdQIFNJR05BVFVS +RS0tLS0tClZlcnNpb246IEdudVBHIHYxLjQuMTEgKE5ldEJTRCkKCmlGNEVBUkVJ +QUFZRkFsQ0ZNZFlBQ2drUUpqL25oV0xpL0g3Q2tRRUFnRFFyRndQRDc2SkMrNkZu +T0tFei85RFAKSDdXalJSTW9JUU5UR0MzWlhSc0EvMXhhaDhlRmVQUURtVE8xc1FH +bklOYmdYOXZaN0dBRk9nVGpXNyt0VmI3SAo9d3RLYgotLS0tLUVORCBQR1AgU0lH +TkFUVVJFLS0tLS0K +==== +EOF + uudecode << EOF +begin-base64 644 in2.gpg +owGbwMvMwCGoZv+8NenRnzrGNU1JzJl5RgGtHj+VOfX8Ukucgl2sFHwTs1PTMnNS +dcoUDPVM9QwN9AwVjAwMjfQNTPUNzBQMLawMTawMzRQS05MVXCsKFPQUuLiCQ51c +PIO0bTlzMpMU9MIdPUMQQkmZeVxcepl5yTmlKakKNknFKXrFpUkpmUV6udl2XB1x +LAyCHAxsrEwgZzBwcQrAnFfzjeGv9GtuvQj7X/Kv5IQ8f2s9n/36yaOmu9HPs8/V +8pg+SdfaxMhwdEOjtLVOGtuaizmXnJ8oa4fN/bfL0WfP1smOn38vsLFlBQA= +==== +EOF + uudecode << EOF +begin-base64 644 in2.asc +LS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UtLS0tLQpIYXNoOiBTSEEyNTYK +CiMJLk5ldEJTRDogTWFrZWZpbGUsdiAxLjUuMTAuMSAyMDEyLzA1LzA2IDE4OjE0 +OjE2IGFnYyBFeHAgLiAKClNVQkRJUis9CWxpYiAuV0FJVApTVUJESVIrPQliaW4K +Ci5pbmNsdWRlIDxic2Quc3ViZGlyLm1rPgotLS0tLUJFR0lOIFBHUCBTSUdOQVRV +UkUtLS0tLQpWZXJzaW9uOiBHbnVQRyB2MS40LjExIChOZXRCU0QpCgppRjRFQVJF +SUFBWUZBbENGU1FvQUNna1FKai9uaFdMaS9INmFLQUQ5SENMVHdZOEN3aXFUWHJ6 +S3hIWjVsSFFuCnFFWmJjYlhqa0N4bGsrbS9QSFVBLzJXaGxjMHQ1WnRtSTIyMUxR +eTVpblRuenB1MVU3NUU1bEp2dzBZTVRkWEoKPXY3ODgKLS0tLS1FTkQgUEdQIFNJ +R05BVFVSRS0tLS0tCg== +==== +EOF + uudecode << EOF +begin-base64 644 expected36 +R29vZCBzaWduYXR1cmUgZm9yIGluMS5ncGcgbWFkZSBNb24gT2N0IDIyIDA0OjQ1 +OjQxIDIwMTIKc2lnbmF0dXJlICAgICAyMDQ4L0RTQSAyNjNmZTc4NTYyZTJmYzdl +IDIwMTItMTAtMjEKZmluZ2VycHJpbnQgICBkMmU1IDA3YjYgNWQ1OSAzM2QzIDlj +OGQgYTYxOCAyNjNmIGU3ODUgNjJlMiBmYzdlIAp1aWQgICAgICAgICAgIERhdmlk +IEFybXN0cm9uZyAoVGVzdCBEU0Ega2V5IC0gZG8gbm90IHVzZSkgPGRzYUBkc2Eu +Y29tPgoK +==== +EOF + uudecode << EOF +begin-base64 644 expected37 +R29vZCBzaWduYXR1cmUgZm9yIFtzdGRpbl0gbWFkZSBNb24gT2N0IDIyIDA0OjQ1 +OjQxIDIwMTIKc2lnbmF0dXJlICAgICAyMDQ4L0RTQSAyNjNmZTc4NTYyZTJmYzdl +IDIwMTItMTAtMjEKZmluZ2VycHJpbnQgICBkMmU1IDA3YjYgNWQ1OSAzM2QzIDlj +OGQgYTYxOCAyNjNmIGU3ODUgNjJlMiBmYzdlIAp1aWQgICAgICAgICAgIERhdmlk +IEFybXN0cm9uZyAoVGVzdCBEU0Ega2V5IC0gZG8gbm90IHVzZSkgPGRzYUBkc2Eu +Y29tPgoK +==== +EOF + uudecode << EOF +begin-base64 644 expected38 +R29vZCBzaWduYXR1cmUgZm9yIGluMS5hc2MgbWFkZSBNb24gT2N0IDIyIDA0OjQ1 +OjI2IDIwMTIKc2lnbmF0dXJlICAgICAyMDQ4L0RTQSAyNjNmZTc4NTYyZTJmYzdl +IDIwMTItMTAtMjEKZmluZ2VycHJpbnQgICBkMmU1IDA3YjYgNWQ1OSAzM2QzIDlj +OGQgYTYxOCAyNjNmIGU3ODUgNjJlMiBmYzdlIAp1aWQgICAgICAgICAgIERhdmlk +IEFybXN0cm9uZyAoVGVzdCBEU0Ega2V5IC0gZG8gbm90IHVzZSkgPGRzYUBkc2Eu +Y29tPgoK +==== +EOF + uudecode << EOF +begin-base64 644 expected39 +R29vZCBzaWduYXR1cmUgZm9yIFtzdGRpbl0gbWFkZSBNb24gT2N0IDIyIDA0OjQ1 +OjI2IDIwMTIKc2lnbmF0dXJlICAgICAyMDQ4L0RTQSAyNjNmZTc4NTYyZTJmYzdl +IDIwMTItMTAtMjEKZmluZ2VycHJpbnQgICBkMmU1IDA3YjYgNWQ1OSAzM2QzIDlj +OGQgYTYxOCAyNjNmIGU3ODUgNjJlMiBmYzdlIAp1aWQgICAgICAgICAgIERhdmlk +IEFybXN0cm9uZyAoVGVzdCBEU0Ega2V5IC0gZG8gbm90IHVzZSkgPGRzYUBkc2Eu +Y29tPgoK +==== +EOF + uudecode << EOF +begin-base64 644 expected40 +IwkuTmV0QlNEOiBNYWtlZmlsZSx2IDEuNS4xMC4xIDIwMTIvMDUvMDYgMTg6MTQ6 +MTYgYWdjIEV4cCAuCgpTVUJESVIrPQlsaWIgLldBSVQKU1VCRElSKz0JYmluCgou +aW5jbHVkZSA8YnNkLnN1YmRpci5taz4K +==== +EOF + uudecode << EOF +begin-base64 644 expected41 +IwkuTmV0QlNEOiBNYWtlZmlsZSx2IDEuNS4xMC4xIDIwMTIvMDUvMDYgMTg6MTQ6 +MTYgYWdjIEV4cCAuCgpTVUJESVIrPQlsaWIgLldBSVQKU1VCRElSKz0JYmluCgou +aW5jbHVkZSA8YnNkLnN1YmRpci5taz4K +==== +EOF + uudecode << EOF +begin-base64 644 expected42 +IwkuTmV0QlNEOiBNYWtlZmlsZSx2IDEuNS4xMC4xIDIwMTIvMDUvMDYgMTg6MTQ6 +MTYgYWdjIEV4cCAuCgpTVUJESVIrPQlsaWIgLldBSVQKU1VCRElSKz0JYmluCgou +aW5jbHVkZSA8YnNkLnN1YmRpci5taz4K +==== +EOF + uudecode << EOF +begin-base64 644 expected43 +IwkuTmV0QlNEOiBNYWtlZmlsZSx2IDEuNS4xMC4xIDIwMTIvMDUvMDYgMTg6MTQ6 +MTYgYWdjIEV4cCAuCgpTVUJESVIrPQlsaWIgLldBSVQKU1VCRElSKz0JYmluCgou +aW5jbHVkZSA8YnNkLnN1YmRpci5taz4K +==== +EOF + uudecode << EOF +begin-base64 644 expected44 +R29vZCBzaWduYXR1cmUgZm9yIGluMi5ncGcgbWFkZSBNb24gT2N0IDIyIDA2OjI0 +OjA5IDIwMTIKc2lnbmF0dXJlICAgICAyMDQ4L0RTQSAyNjNmZTc4NTYyZTJmYzdl +IDIwMTItMTAtMjEKZmluZ2VycHJpbnQgICBkMmU1IDA3YjYgNWQ1OSAzM2QzIDlj +OGQgYTYxOCAyNjNmIGU3ODUgNjJlMiBmYzdlIAp1aWQgICAgICAgICAgIERhdmlk +IEFybXN0cm9uZyAoVGVzdCBEU0Ega2V5IC0gZG8gbm90IHVzZSkgPGRzYUBkc2Eu +Y29tPgoK +==== +EOF + uudecode << EOF +begin-base64 644 expected45 +R29vZCBzaWduYXR1cmUgZm9yIGluMi5hc2MgbWFkZSBNb24gT2N0IDIyIDA2OjI0 +OjI2IDIwMTIKc2lnbmF0dXJlICAgICAyMDQ4L0RTQSAyNjNmZTc4NTYyZTJmYzdl +IDIwMTItMTAtMjEKZmluZ2VycHJpbnQgICBkMmU1IDA3YjYgNWQ1OSAzM2QzIDlj +OGQgYTYxOCAyNjNmIGU3ODUgNjJlMiBmYzdlIAp1aWQgICAgICAgICAgIERhdmlk +IEFybXN0cm9uZyAoVGVzdCBEU0Ega2V5IC0gZG8gbm90IHVzZSkgPGRzYUBkc2Eu +Y29tPgoK +==== +EOF + uudecode << EOF +begin-base64 644 expected46 +SWdub3JpbmcgdW51c3VhbC9yZXNlcnZlZCBzaWduYXR1cmUgc3VicGFja2V0IDE4 +Ckdvb2Qgc2lnbmF0dXJlIGZvciBOZXRCU0QtNi4wX2hhc2hlcy5hc2MgbWFkZSBN +b24gT2N0IDE1IDA5OjI4OjU0IDIwMTIKc2lnbmF0dXJlICA0MDk2L1JTQSAoRW5j +cnlwdCBvciBTaWduKSAwNjQ5NzNhYzRjNGE3MDZlIDIwMDktMDYtMjMKZmluZ2Vy +cHJpbnQ6ICBkZGVlIDJiZGIgOWM5OCBhMGQxIGQ0ZmIgZGJmNyAwNjQ5IDczYWMg +NGM0YSA3MDZlIAp1aWQgICAgICAgICAgICAgIE5ldEJTRCBTZWN1cml0eSBPZmZp +Y2VyIDxzZWN1cml0eS1vZmZpY2VyQE5ldEJTRC5vcmc+CmVuY3J5cHRpb24gNDA5 +Ni9SU0EgKEVuY3J5cHQgb3IgU2lnbikgOWZmMmMyNGZkZjJjZTYyMCAyMDA5LTA2 +LTIzIFtFeHBpcnkgMjAxOS0wNi0yMV0KZmluZ2VycHJpbnQ6ICAxOTE1IDA4MDEg +ZmJkOCBmNDVkIDg5ZjIgMDIwNSA5ZmYyIGMyNGYgZGYyYyBlNjIwIAoK +==== +EOF + atf_check -s eq:0 -o file:expected36 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg in1.gpg + atf_check -s eq:0 -o file:expected37 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg < in1.gpg + atf_check -s eq:0 -o file:expected38 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg in1.asc + atf_check -s eq:0 -o file:expected39 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg < in1.asc + atf_check -s eq:0 -o file:expected40 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg -c cat in1.gpg + atf_check -s eq:0 -o file:expected41 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg -c cat < in1.gpg + atf_check -s eq:0 -o file:expected42 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg -c cat in1.asc + atf_check -s eq:0 -o file:expected43 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg -c cat < in1.asc + atf_check -s eq:0 -o file:expected44 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg in2.gpg + atf_check -s eq:0 -o file:expected45 -e empty env TZ=US/Pacific netpgpverify -k dsa-pubring.gpg in2.asc +} + +# all test sets +atf_init_test_cases() { + atf_add_test_case netpgpverify_testset_1_rsa_signatures + atf_add_test_case netpgpverify_testset_2_dsa_signatures +} + diff --git a/contrib/netbsd-tests/usr.bin/pr/d_basic.in b/contrib/netbsd-tests/usr.bin/pr/d_basic.in new file mode 100644 index 0000000..4e36f6e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/pr/d_basic.in @@ -0,0 +1,2 @@ +123 456 789 +abc def ghi diff --git a/contrib/netbsd-tests/usr.bin/pr/d_basic.out b/contrib/netbsd-tests/usr.bin/pr/d_basic.out new file mode 100644 index 0000000..e187104 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/pr/d_basic.out @@ -0,0 +1 @@ +123 456 789 abc def ghi diff --git a/contrib/netbsd-tests/usr.bin/pr/t_basic.sh b/contrib/netbsd-tests/usr.bin/pr/t_basic.sh new file mode 100755 index 0000000..6bd80dd --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/pr/t_basic.sh @@ -0,0 +1,46 @@ +# $NetBSD: t_basic.sh,v 1.4 2012/03/13 05:40:00 jruoho Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() { + atf_set "descr" "A basic test of pr(1) (cf. PR bin/41880)" +} + +basic_body() { + + # The output file was generated with "pr (GNU coreutils) 6.10". + # + atf_check -s ignore -o file:$(atf_get_srcdir)/d_basic.out \ + -x "pr -t -2 $(atf_get_srcdir)/d_basic.in" +} + +atf_init_test_cases() { + atf_add_test_case basic +} diff --git a/contrib/netbsd-tests/usr.bin/rump_server/t_disk.sh b/contrib/netbsd-tests/usr.bin/rump_server/t_disk.sh new file mode 100755 index 0000000..bf1e7e1 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/rump_server/t_disk.sh @@ -0,0 +1,130 @@ +# $NetBSD: t_disk.sh,v 1.5 2013/02/19 21:08:25 joerg Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +server='rump_server -lrumpvfs' +export RUMP_SERVER='unix://commsock' + +startsrv() +{ + + atf_check -s exit:0 ${server} $@ ${RUMP_SERVER} +} + +test_case() +{ + local name="${1}"; shift + + atf_test_case "${name}" cleanup + eval "${name}_head() { \ + atf_set "require.progs" "rump_server" ; \ + }" + eval "${name}_body() { \ + ${name}_prefun ; \ + startsrv $@ ; \ + ${name} ; \ + }" + eval "${name}_cleanup() { \ + [ -f halted ] && return 0 ; rump.halt ; + }" +} + +test_case size -d key=/img,hostpath=the.img,size=32k +size() +{ + atf_check -s exit:0 -o inline:'32768\n' stat -f %z the.img +} + +test_case offset -d key=/img,hostpath=the.img,size=32k,offset=16k +offset() +{ + atf_check -s exit:0 -o inline:'49152\n' stat -f %z the.img +} + +test_case notrunc -d key=/img,hostpath=the.img,size=8k,offset=16k +notrunc_prefun() +{ + dd if=/dev/zero of=the.img bs=1 oseek=65535 count=1 +} +notrunc() +{ + atf_check -s exit:0 -o inline:'65536\n' stat -f %z the.img +} + +test_case data -d key=/img,hostpath=the.img,size=8k,offset=16k +data() +{ + echo 'test string' | dd of=testfile ibs=512 count=1 conv=sync + atf_check -s exit:0 -e ignore -x \ + "dd if=testfile | rump.dd of=/img bs=512 count=1" + + # cheap fsync + atf_check -s exit:0 rump.halt + touch halted + atf_check -s exit:0 -e ignore -o file:testfile \ + dd if=the.img iseek=16k bs=1 count=512 +} + +test_case type_chr -d key=/img,hostpath=the.img,size=32k,type=chr +type_chr() +{ + atf_check -s exit:0 -o inline:'Character Device\n' \ + env LD_PRELOAD=/usr/lib/librumphijack.so stat -f %HT /rump/img +} + +test_case type_reg -d key=/img,hostpath=the.img,size=32k,type=reg +type_reg() +{ + atf_check -s exit:0 -o inline:'Regular File\n' \ + env LD_PRELOAD=/usr/lib/librumphijack.so stat -f %HT /rump/img +} + +test_case type_blk -d key=/img,hostpath=the.img,size=32k,type=blk +type_blk() +{ + atf_check -s exit:0 -o inline:'Block Device\n' \ + env LD_PRELOAD=/usr/lib/librumphijack.so stat -f %HT /rump/img +} + +test_case type_blk_default -d key=/img,hostpath=the.img,size=32k +type_blk_default() +{ + atf_check -s exit:0 -o inline:'Block Device\n' \ + env LD_PRELOAD=/usr/lib/librumphijack.so stat -f %HT /rump/img +} + +atf_init_test_cases() +{ + + atf_add_test_case size + atf_add_test_case offset + atf_add_test_case notrunc + atf_add_test_case data + atf_add_test_case type_chr + atf_add_test_case type_reg + atf_add_test_case type_blk + atf_add_test_case type_blk_default +} diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_dot.in b/contrib/netbsd-tests/usr.bin/sdiff/d_dot.in new file mode 100644 index 0000000..9c558e3 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_dot.in @@ -0,0 +1 @@ +. diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_flags_l.out b/contrib/netbsd-tests/usr.bin/sdiff/d_flags_l.out new file mode 100644 index 0000000..c7afce0 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_flags_l.out @@ -0,0 +1,102 @@ +Policy: /usr/bin/lynx, Emulation: native + > native-issetugid: permit + > native-mprotect: permit + > native-mmap: permit + native-__sysctl: permit + > native-fsread: filename eq "/var/run/ld.so.hints" then perm + > native-fstat: permit + native-close: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then perm | native-fsread: filename match "/usr/lib/libssl.so.*" then p + native-connect: sockaddr match "inet-\\\[*\\\]:80" then per | native-read: permit + native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" the + native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*" th + native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then per + native-fsread: filename match "/: *" | native-munmap: permit + native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit + native-fsread: filename eq "/etc/malloc.conf" then permit + native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit + native-fsread: filename eq "/etc/utmp" then permit < + native-fsread: filename eq "/home" then permit < + native-fsread: filename eq "$HOME" then permit < + native-fsread: filename eq "$HOME/.lynx-keymaps" then permi < + native-fsread: filename eq "$HOME/.lynxrc" then permit < + native-fsread: filename eq "$HOME/.mailcap" then permit < + native-fsread: filename eq "$HOME/.mime.types" then permit < + native-fsread: filename eq "$HOME/.terminfo" then permit < + native-fsread: filename eq "$HOME/.terminfo.db" then permit < + native-fsread: filename eq "/obj" then permit < + native-fsread: filename eq "/tmp" then permit + > native-fswrite: filename match "/tmp/lynx-*" then permit + native-fsread: filename match "/tmp/lynx-*/." then permit + > native-fsread: filename eq "$HOME" then permit + > native-fsread: filename eq "/etc/lynx.cfg" then permit + > native-fsread: filename eq "/" then permit + > native-fsread: filename eq "/usr/obj/bin/systrace/." then p + > native-fsread: filename eq "/usr/obj/bin" then permit + > native-fcntl: permit + > native-getdirentries: permit + > native-lseek: permit + > native-fsread: filename eq "/usr/obj" then permit + native-fsread: filename eq "/usr" then permit + native-fsread: filename eq "/usr/bin" then permit + native-fsread: filename eq "/usr/games" then permit + native-fsread: filename eq "/usr/include" then permit + native-fsread: filename eq "/usr/lib" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then per < + native-fsread: filename match "/usr/lib/libcrypto.so.*" the < + native-fsread: filename match "/usr/lib/libncurses.so.*" th < + native-fsread: filename match "/usr/lib/libssl.so.*" then p < + native-fsread: filename eq "/usr/libdata" then permit + native-fsread: filename eq "/usr/libexec" then permit + native-fsread: filename eq "/usr/lkm" then permit + native-fsread: filename eq "/usr/local" then permit + native-fsread: filename eq "/usr/mdec" then permit + native-fsread: filename eq "/usr/obj" then permit | native-fsread: filename eq "/home" then permit + native-fsread: filename eq "/usr/obj/bin" then permit | native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/." then p | native-fsread: filename eq "$HOME/.lynxrc" then permit + > native-fsread: filename match "/: *" + native-fsread: filename eq "/usr/obj/bin/systrace/.mailcap" + > native-fsread: filename eq "$HOME/.mailcap" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mime.typ + > native-fsread: filename eq "$HOME/.mime.types" then permit + > native-sigaction: permit + > native-ioctl: permit + > native-fsread: filename eq "$HOME/.terminfo.db" then permit + > native-fsread: filename eq "$HOME/.terminfo" then permit + native-fsread: filename eq "/usr/share/misc/terminfo.db" th + > native-pread: permit + > native-write: permit + > native-fsread: filename eq "$HOME/.lynx-keymaps" then permi + native-fsread: filename eq "/var/run/dev.db" then permit + native-fsread: filename eq "/var/run/ld.so.hints" then perm | native-fsread: filename eq "/etc/utmp" then permit + native-fstat: permit < + native-fswrite: filename match "/tmp/lynx-*" then permit < + native-getdirentries: permit < + native-getpid: permit < + native-gettimeofday: permit < + native-ioctl: permit < + native-issetugid: permit < + native-lseek: permit < + native-mmap: permit < + native-mprotect: prot eq "PROT_READ" then permit < + native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permit < + native-mprotect: prot eq "PROT_READ|PROT_WRITE" then permit < + native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" t < + native-munmap: permit < + native-nanosleep: permit < + native-poll: permit + native-pread: permit | native-nanosleep: permit + native-read: permit | native-gettimeofday: permit + native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit + native-select: permit < + native-sendto: true then permit < + native-sigaction: permit < + native-sigprocmask: permit < + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_D + > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then perm + > native-sendto: true then permit + > native-select: permit + > native-recvfrom: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_S + native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then per + > native-exit: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_flags_s.out b/contrib/netbsd-tests/usr.bin/sdiff/d_flags_s.out new file mode 100644 index 0000000..19179fe --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_flags_s.out @@ -0,0 +1,79 @@ + > native-issetugid: permit + > native-mprotect: permit + > native-mmap: permit + > native-fsread: filename eq "/var/run/ld.so.hints" then perm + > native-fstat: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then perm | native-fsread: filename match "/usr/lib/libssl.so.*" then p + native-connect: sockaddr match "inet-\\\[*\\\]:80" then per | native-read: permit + native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" the + native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*" th + native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then per + native-fsread: filename match "/: *" | native-munmap: permit + native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit + native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit + native-fsread: filename eq "/etc/utmp" then permit < + native-fsread: filename eq "/home" then permit < + native-fsread: filename eq "$HOME" then permit < + native-fsread: filename eq "$HOME/.lynx-keymaps" then permi < + native-fsread: filename eq "$HOME/.lynxrc" then permit < + native-fsread: filename eq "$HOME/.mailcap" then permit < + native-fsread: filename eq "$HOME/.mime.types" then permit < + native-fsread: filename eq "$HOME/.terminfo" then permit < + native-fsread: filename eq "$HOME/.terminfo.db" then permit < + native-fsread: filename eq "/obj" then permit < + > native-fswrite: filename match "/tmp/lynx-*" then permit + > native-fsread: filename eq "$HOME" then permit + > native-fsread: filename eq "/etc/lynx.cfg" then permit + > native-fsread: filename eq "/" then permit + > native-fsread: filename eq "/usr/obj/bin/systrace/." then p + > native-fsread: filename eq "/usr/obj/bin" then permit + > native-fcntl: permit + > native-getdirentries: permit + > native-lseek: permit + > native-fsread: filename eq "/usr/obj" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then per < + native-fsread: filename match "/usr/lib/libcrypto.so.*" the < + native-fsread: filename match "/usr/lib/libncurses.so.*" th < + native-fsread: filename match "/usr/lib/libssl.so.*" then p < + native-fsread: filename eq "/usr/obj" then permit | native-fsread: filename eq "/home" then permit + native-fsread: filename eq "/usr/obj/bin" then permit | native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/." then p | native-fsread: filename eq "$HOME/.lynxrc" then permit + > native-fsread: filename match "/: *" + > native-fsread: filename eq "$HOME/.mailcap" then permit + > native-fsread: filename eq "$HOME/.mime.types" then permit + > native-sigaction: permit + > native-ioctl: permit + > native-fsread: filename eq "$HOME/.terminfo.db" then permit + > native-fsread: filename eq "$HOME/.terminfo" then permit + > native-pread: permit + > native-write: permit + > native-fsread: filename eq "$HOME/.lynx-keymaps" then permi + native-fsread: filename eq "/var/run/ld.so.hints" then perm | native-fsread: filename eq "/etc/utmp" then permit + native-fstat: permit < + native-fswrite: filename match "/tmp/lynx-*" then permit < + native-getdirentries: permit < + native-getpid: permit < + native-gettimeofday: permit < + native-ioctl: permit < + native-issetugid: permit < + native-lseek: permit < + native-mmap: permit < + native-mprotect: prot eq "PROT_READ" then permit < + native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permit < + native-mprotect: prot eq "PROT_READ|PROT_WRITE" then permit < + native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" t < + native-munmap: permit < + native-nanosleep: permit < + native-pread: permit | native-nanosleep: permit + native-read: permit | native-gettimeofday: permit + native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit + native-select: permit < + native-sendto: true then permit < + native-sigaction: permit < + native-sigprocmask: permit < + > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then perm + > native-sendto: true then permit + > native-select: permit + > native-recvfrom: permit + native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then per + > native-exit: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_flags_w.out b/contrib/netbsd-tests/usr.bin/sdiff/d_flags_w.out new file mode 100644 index 0000000..19ea79b --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_flags_w.out @@ -0,0 +1,102 @@ +Policy: /usr/bin/lynx, Emulation: native Policy: /usr/bin/lynx, Emulation: native + > native-issetugid: permit + > native-mprotect: permit + > native-mmap: permit + native-__sysctl: permit native-__sysctl: permit + > native-fsread: filename eq "/var/run/ld.so.hints" then pe + > native-fstat: permit + native-close: permit native-close: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-fsread: filename match "/usr/lib/libssl.so.*" then + native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-read: permit + native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t + native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*" + native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p + native-fsread: filename match "/: | native-munmap: permit + native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit + native-fsread: filename eq "/etc/malloc.conf" then permit native-fsread: filename eq "/etc/malloc.conf" then permit + native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit + native-fsread: filename eq "/etc/utmp" then permit < + native-fsread: filename eq "/home" then permit < + native-fsread: filename eq "$HOME" then permit < + native-fsread: filename eq "$HOME/.lynx-keymaps" then per < + native-fsread: filename eq "$HOME/.lynxrc" then permit < + native-fsread: filename eq "$HOME/.mailcap" then permit < + native-fsread: filename eq "$HOME/.mime.types" then permi < + native-fsread: filename eq "$HOME/.terminfo" then permit < + native-fsread: filename eq "$HOME/.terminfo.db" then perm < + native-fsread: filename eq "/obj" then permit < + native-fsread: filename eq "/tmp" then permit native-fsread: filename eq "/tmp" then permit + > native-fswrite: filename match "/tmp/lynx-*" then permit + native-fsread: filename match "/tmp/lynx-*/." then permit native-fsread: filename match "/tmp/lynx-*/." then permit + > native-fsread: filename eq "$HOME" then permit + > native-fsread: filename eq "/etc/lynx.cfg" then permit + > native-fsread: filename eq "/" then permit + > native-fsread: filename eq "/usr/obj/bin/systrace/." then + > native-fsread: filename eq "/usr/obj/bin" then permit + > native-fcntl: permit + > native-getdirentries: permit + > native-lseek: permit + > native-fsread: filename eq "/usr/obj" then permit + native-fsread: filename eq "/usr" then permit native-fsread: filename eq "/usr" then permit + native-fsread: filename eq "/usr/bin" then permit native-fsread: filename eq "/usr/bin" then permit + native-fsread: filename eq "/usr/games" then permit native-fsread: filename eq "/usr/games" then permit + native-fsread: filename eq "/usr/include" then permit native-fsread: filename eq "/usr/include" then permit + native-fsread: filename eq "/usr/lib" then permit native-fsread: filename eq "/usr/lib" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then p < + native-fsread: filename match "/usr/lib/libcrypto.so.*" t < + native-fsread: filename match "/usr/lib/libncurses.so.*" < + native-fsread: filename match "/usr/lib/libssl.so.*" then < + native-fsread: filename eq "/usr/libdata" then permit native-fsread: filename eq "/usr/libdata" then permit + native-fsread: filename eq "/usr/libexec" then permit native-fsread: filename eq "/usr/libexec" then permit + native-fsread: filename eq "/usr/lkm" then permit native-fsread: filename eq "/usr/lkm" then permit + native-fsread: filename eq "/usr/local" then permit native-fsread: filename eq "/usr/local" then permit + native-fsread: filename eq "/usr/mdec" then permit native-fsread: filename eq "/usr/mdec" then permit + native-fsread: filename eq "/usr/obj" then permit | native-fsread: filename eq "/home" then permit + native-fsread: filename eq "/usr/obj/bin" then permit | native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/." then | native-fsread: filename eq "$HOME/.lynxrc" then permit + > native-fsread: filename match "/: + native-fsread: filename eq "/usr/obj/bin/systrace/.mailca native-fsread: filename eq "/usr/obj/bin/systrace/.mailca + > native-fsread: filename eq "$HOME/.mailcap" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t + > native-fsread: filename eq "$HOME/.mime.types" then permi + > native-sigaction: permit + > native-ioctl: permit + > native-fsread: filename eq "$HOME/.terminfo.db" then perm + > native-fsread: filename eq "$HOME/.terminfo" then permit + native-fsread: filename eq "/usr/share/misc/terminfo.db" native-fsread: filename eq "/usr/share/misc/terminfo.db" + > native-pread: permit + > native-write: permit + > native-fsread: filename eq "$HOME/.lynx-keymaps" then per + native-fsread: filename eq "/var/run/dev.db" then permit native-fsread: filename eq "/var/run/dev.db" then permit + native-fsread: filename eq "/var/run/ld.so.hints" then pe | native-fsread: filename eq "/etc/utmp" then permit + native-fstat: permit < + native-fswrite: filename match "/tmp/lynx-*" then permit < + native-getdirentries: permit < + native-getpid: permit < + native-gettimeofday: permit < + native-ioctl: permit < + native-issetugid: permit < + native-lseek: permit < + native-mmap: permit < + native-mprotect: prot eq "PROT_READ" then permit < + native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi < + native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm < + native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" < + native-munmap: permit < + native-nanosleep: permit < + native-poll: permit native-poll: permit + native-pread: permit | native-nanosleep: permit + native-read: permit | native-gettimeofday: permit + native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit + native-select: permit < + native-sendto: true then permit < + native-sigaction: permit < + native-sigprocmask: permit < + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK native-socket: sockdom eq "AF_INET" and socktype eq "SOCK + > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe + > native-sendto: true then permit + > native-select: permit + > native-recvfrom: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK native-socket: sockdom eq "AF_INET" and socktype eq "SOCK + native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p + > native-exit: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_a1.out b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_a1.out new file mode 100644 index 0000000..2a0f532 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_a1.out @@ -0,0 +1,100 @@ +Policy: /usr/bin/lynx, Emulation: native Policy: /usr/bin/lynx, Emulation: native + > native-issetugid: permit + > native-mprotect: permit + > native-mmap: permit + native-__sysctl: permit native-__sysctl: permit + > native-fsread: filename eq "/var/run/ld.so.hints" then pe + > native-fstat: permit + native-close: permit native-close: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-fsread: filename match "/usr/lib/libssl.so.*" then + native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-read: permit + native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t + native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*" + native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p + native-fsread: filename match "/: | native-munmap: permit + native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit + native-fsread: filename eq "/etc/malloc.conf" then permit native-fsread: filename eq "/etc/malloc.conf" then permit + native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit + native-fsread: filename eq "/etc/utmp" then permit < + native-fsread: filename eq "/home" then permit < + native-fsread: filename eq "$HOME" then permit < + native-fsread: filename eq "$HOME/.lynx-keymaps" then per < + native-fsread: filename eq "$HOME/.lynxrc" then permit < + native-fsread: filename eq "$HOME/.mailcap" then permit < + native-fsread: filename eq "$HOME/.mime.types" then permi < + native-fsread: filename eq "$HOME/.terminfo" then permit < + native-fsread: filename eq "$HOME/.terminfo.db" then perm < + native-fsread: filename eq "/obj" then permit < + native-fsread: filename eq "/tmp" then permit native-fsread: filename eq "/tmp" then permit + native-fsread: filename match "/tmp/lynx-*/." then permit native-fswrite: filename match "/tmp/lynx-*" then permit + ) native-fsread: filename match "/tmp/lynx-*/." then permit + > native-fsread: filename eq "$HOME" then permit + > native-fsread: filename eq "/etc/lynx.cfg" then permit + > native-fsread: filename eq "/" then permit + > native-fsread: filename eq "/usr/obj/bin/systrace/." then + > native-fsread: filename eq "/usr/obj/bin" then permit + > native-fcntl: permit + > native-getdirentries: permit + > native-lseek: permit + > native-fsread: filename eq "/usr/obj" then permit + native-fsread: filename eq "/usr" then permit native-fsread: filename eq "/usr" then permit + native-fsread: filename eq "/usr/bin" then permit native-fsread: filename eq "/usr/bin" then permit + native-fsread: filename eq "/usr/games" then permit native-fsread: filename eq "/usr/games" then permit + native-fsread: filename eq "/usr/include" then permit native-fsread: filename eq "/usr/include" then permit + native-fsread: filename eq "/usr/lib" then permit native-fsread: filename eq "/usr/lib" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then p native-fsread: filename eq "/usr/libdata" then permit + native-fsread: filename match "/usr/lib/libcrypto.so.*" t native-fsread: filename eq "/usr/libexec" then permit + native-fsread: filename match "/usr/lib/libncurses.so.*" native-fsread: filename eq "/usr/lkm" then permit + native-fsread: filename match "/usr/lib/libssl.so.*" then native-fsread: filename eq "/usr/local" then permit + native-fsread: filename eq "/usr/libdata" then permit native-fsread: filename eq "/usr/mdec" then permit + native-fsread: filename eq "/usr/libexec" then permit native-fsread: filename eq "/home" then permit + native-fsread: filename eq "/usr/lkm" then permit native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "/usr/local" then permit native-fsread: filename eq "$HOME/.lynxrc" then permit + native-fsread: filename eq "/usr/mdec" then permit native-fsread: filename match "/: + native-fsread: filename eq "/usr/obj" then permit native-fsread: filename eq "/usr/obj/bin/systrace/.mailca + native-fsread: filename eq "/usr/obj/bin" then permit native-fsread: filename eq "$HOME/.mailcap" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/." then native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t + native-fsread: filename eq "/usr/obj/bin/systrace/.mailca ( + native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t ( + > native-fsread: filename eq "$HOME/.mime.types" then permi + > native-sigaction: permit + > native-ioctl: permit + > native-fsread: filename eq "$HOME/.terminfo.db" then perm + > native-fsread: filename eq "$HOME/.terminfo" then permit + native-fsread: filename eq "/usr/share/misc/terminfo.db" native-fsread: filename eq "/usr/share/misc/terminfo.db" + > native-pread: permit + > native-write: permit + > native-fsread: filename eq "$HOME/.lynx-keymaps" then per + native-fsread: filename eq "/var/run/dev.db" then permit native-fsread: filename eq "/var/run/dev.db" then permit + native-fsread: filename eq "/var/run/ld.so.hints" then pe | native-fsread: filename eq "/etc/utmp" then permit + native-fstat: permit < + native-fswrite: filename match "/tmp/lynx-*" then permit < + native-getdirentries: permit < + native-getpid: permit < + native-gettimeofday: permit < + native-ioctl: permit < + native-issetugid: permit < + native-lseek: permit < + native-mmap: permit < + native-mprotect: prot eq "PROT_READ" then permit < + native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi < + native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm < + native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" < + native-munmap: permit < + native-nanosleep: permit < + native-poll: permit native-poll: permit + native-pread: permit | native-nanosleep: permit + native-read: permit | native-gettimeofday: permit + native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit + native-select: permit < + native-sendto: true then permit < + native-sigaction: permit < + native-sigprocmask: permit < + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK native-socket: sockdom eq "AF_INET" and socktype eq "SOCK + > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe + > native-sendto: true then permit + > native-select: permit + > native-recvfrom: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK native-socket: sockdom eq "AF_INET" and socktype eq "SOCK + native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p + > native-exit: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_a2.out b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_a2.out new file mode 100644 index 0000000..4e0d349 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_a2.out @@ -0,0 +1,96 @@ +Policy: /usr/bin/lynx, Emulation: native Policy: /usr/bin/lynx, Emulation: native + native-issetugid: permit < + native-mprotect: permit < + native-mmap: permit < + native-__sysctl: permit native-__sysctl: permit + native-fsread: filename eq "/var/run/ld.so.hints" then pe < + native-fstat: permit < + native-close: permit native-close: permit + native-fsread: filename match "/usr/lib/libssl.so.*" then | native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe + native-read: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p + native-fsread: filename match "/usr/lib/libcrypto.so.*" t | native-exit: permit + native-fsread: filename match "/usr/lib/libncurses.so.*" | native-fcntl: cmd eq "F_SETFD" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then p | native-fsread: filename eq "/" then permit + native-munmap: permit | native-fsread: filename match "/: + native-sigprocmask: permit | native-fsread: filename eq "/etc/lynx.cfg" then permit + native-fsread: filename eq "/etc/malloc.conf" then permit native-fsread: filename eq "/etc/malloc.conf" then permit + native-getpid: permit | native-fsread: filename eq "/etc/resolv.conf" then permit + > native-fsread: filename eq "/etc/utmp" then permit + > native-fsread: filename eq "/home" then permit + > native-fsread: filename eq "$HOME" then permit + > native-fsread: filename eq "$HOME/.lynx-keymaps" then per + > native-fsread: filename eq "$HOME/.lynxrc" then permit + > native-fsread: filename eq "$HOME/.mailcap" then permit + > native-fsread: filename eq "$HOME/.mime.types" then permi + > native-fsread: filename eq "$HOME/.terminfo" then permit + > native-fsread: filename eq "$HOME/.terminfo.db" then perm + > native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "/tmp" then permit native-fsread: filename eq "/tmp" then permit + native-fswrite: filename match "/tmp/lynx-*" then permit native-fsread: filename match "/tmp/lynx-*/." then permit + native-fsread: filename match "/tmp/lynx-*/." then permit ( + native-fsread: filename eq "$HOME" then permit < + native-fsread: filename eq "/etc/lynx.cfg" then permit < + native-fsread: filename eq "/" then permit < + native-fsread: filename eq "/usr/obj/bin/systrace/." then < + native-fsread: filename eq "/usr/obj/bin" then permit < + native-fcntl: permit < + native-getdirentries: permit < + native-lseek: permit < + native-fsread: filename eq "/usr/obj" then permit < + native-fsread: filename eq "/usr" then permit native-fsread: filename eq "/usr" then permit + native-fsread: filename eq "/usr/bin" then permit native-fsread: filename eq "/usr/bin" then permit + native-fsread: filename eq "/usr/games" then permit native-fsread: filename eq "/usr/games" then permit + native-fsread: filename eq "/usr/include" then permit native-fsread: filename eq "/usr/include" then permit + native-fsread: filename eq "/usr/lib" then permit native-fsread: filename eq "/usr/lib" then permit + native-fsread: filename eq "/usr/libdata" then permit native-fsread: filename match "/usr/lib/libc.so.*" then p + native-fsread: filename eq "/usr/libexec" then permit native-fsread: filename match "/usr/lib/libcrypto.so.*" t + native-fsread: filename eq "/usr/lkm" then permit native-fsread: filename match "/usr/lib/libncurses.so.*" + native-fsread: filename eq "/usr/local" then permit native-fsread: filename match "/usr/lib/libssl.so.*" then + native-fsread: filename eq "/usr/mdec" then permit native-fsread: filename eq "/usr/libdata" then permit + native-fsread: filename eq "/home" then permit native-fsread: filename eq "/usr/libexec" then permit + native-fsread: filename eq "/obj" then permit native-fsread: filename eq "/usr/lkm" then permit + native-fsread: filename eq "$HOME/.lynxrc" then permit native-fsread: filename eq "/usr/local" then permit + native-fsread: filename match "/: native-fsread: filename eq "/usr/mdec" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mailca native-fsread: filename eq "/usr/obj" then permit + native-fsread: filename eq "$HOME/.mailcap" then permit native-fsread: filename eq "/usr/obj/bin" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t native-fsread: filename eq "/usr/obj/bin/systrace/." then + ) native-fsread: filename eq "/usr/obj/bin/systrace/.mailca + ) native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t + native-fsread: filename eq "$HOME/.mime.types" then permi < + native-sigaction: permit < + native-ioctl: permit < + native-fsread: filename eq "$HOME/.terminfo.db" then perm < + native-fsread: filename eq "$HOME/.terminfo" then permit < + native-fsread: filename eq "/usr/share/misc/terminfo.db" native-fsread: filename eq "/usr/share/misc/terminfo.db" + native-pread: permit < + native-write: permit < + native-fsread: filename eq "$HOME/.lynx-keymaps" then per < + native-fsread: filename eq "/var/run/dev.db" then permit native-fsread: filename eq "/var/run/dev.db" then permit + native-fsread: filename eq "/etc/utmp" then permit | native-fsread: filename eq "/var/run/ld.so.hints" then pe + native-poll: permit | native-fstat: permit + native-nanosleep: permit | native-fswrite: filename match "/tmp/lynx-*" then permit + > native-getdirentries: permit + > native-getpid: permit + native-gettimeofday: permit native-gettimeofday: permit + native-fsread: filename eq "/etc/resolv.conf" then permit | native-ioctl: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK | native-issetugid: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-lseek: permit + native-sendto: true then permit | native-mmap: permit + native-select: permit | native-mprotect: prot eq "PROT_READ" then permit + > native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi + > native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm + > native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" + > native-munmap: permit + > native-nanosleep: permit + > native-poll: permit + > native-pread: permit + > native-read: permit + native-recvfrom: permit native-recvfrom: permit + > native-select: permit + > native-sendto: true then permit + > native-sigaction: permit + > native-sigprocmask: permit + > native-socket: sockdom eq "AF_INET" and socktype eq "SOCK + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK native-socket: sockdom eq "AF_INET" and socktype eq "SOCK + native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-write: permit + native-exit: permit < diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_b1.out b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_b1.out new file mode 100644 index 0000000..3e548b6 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_b1.out @@ -0,0 +1,69 @@ + > native-issetugid: permit + > native-mprotect: permit + > native-mmap: permit + > native-fsread: filename eq "/var/run/ld.so.hints" then pe + > native-fstat: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-fsread: filename match "/usr/lib/libssl.so.*" then + native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-read: permit + native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t + native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*" + native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p + native-fsread: filename match "/: | native-munmap: permit + native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit + native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit + native-fsread: filename eq "/etc/utmp" then permit < + native-fsread: filename eq "/home" then permit < + native-fsread: filename eq "$HOME" then permit < + native-fsread: filename eq "$HOME/.lynx-keymaps" then per < + native-fsread: filename eq "$HOME/.lynxrc" then permit < + native-fsread: filename eq "$HOME/.mailcap" then permit < + native-fsread: filename eq "$HOME/.mime.types" then permi < + native-fsread: filename eq "$HOME/.terminfo" then permit < + native-fsread: filename eq "$HOME/.terminfo.db" then perm < + native-fsread: filename eq "/obj" then permit < + > native-fsread: filename eq "$HOME" then permit + > native-fsread: filename eq "/etc/lynx.cfg" then permit + > native-fsread: filename eq "/" then permit + > native-fsread: filename eq "/usr/obj/bin/systrace/." then + > native-fsread: filename eq "/usr/obj/bin" then permit + > native-fcntl: permit + > native-getdirentries: permit + > native-lseek: permit + > native-fsread: filename eq "/usr/obj" then permit + > native-fsread: filename eq "$HOME/.mime.types" then permi + > native-sigaction: permit + > native-ioctl: permit + > native-fsread: filename eq "$HOME/.terminfo.db" then perm + > native-fsread: filename eq "$HOME/.terminfo" then permit + > native-pread: permit + > native-write: permit + > native-fsread: filename eq "$HOME/.lynx-keymaps" then per + native-fsread: filename eq "/var/run/ld.so.hints" then pe | native-fsread: filename eq "/etc/utmp" then permit + native-fstat: permit < + native-fswrite: filename match "/tmp/lynx-*" then permit < + native-getdirentries: permit < + native-getpid: permit < + native-gettimeofday: permit < + native-ioctl: permit < + native-issetugid: permit < + native-lseek: permit < + native-mmap: permit < + native-mprotect: prot eq "PROT_READ" then permit < + native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi < + native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm < + native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" < + native-munmap: permit < + native-nanosleep: permit < + native-pread: permit | native-nanosleep: permit + native-read: permit | native-gettimeofday: permit + native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit + native-select: permit < + native-sendto: true then permit < + native-sigaction: permit < + native-sigprocmask: permit < + > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe + > native-sendto: true then permit + > native-select: permit + > native-recvfrom: permit + native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p + > native-exit: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_b2.out b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_b2.out new file mode 100644 index 0000000..4504c36 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_b2.out @@ -0,0 +1,65 @@ + native-issetugid: permit < + native-mprotect: permit < + native-mmap: permit < + native-fsread: filename eq "/var/run/ld.so.hints" then pe < + native-fstat: permit < + native-fsread: filename match "/usr/lib/libssl.so.*" then | native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe + native-read: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p + native-fsread: filename match "/usr/lib/libcrypto.so.*" t | native-exit: permit + native-fsread: filename match "/usr/lib/libncurses.so.*" | native-fcntl: cmd eq "F_SETFD" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then p | native-fsread: filename eq "/" then permit + native-munmap: permit | native-fsread: filename match "/: + native-sigprocmask: permit | native-fsread: filename eq "/etc/lynx.cfg" then permit + native-getpid: permit | native-fsread: filename eq "/etc/resolv.conf" then permit + > native-fsread: filename eq "/etc/utmp" then permit + > native-fsread: filename eq "/home" then permit + > native-fsread: filename eq "$HOME" then permit + > native-fsread: filename eq "$HOME/.lynx-keymaps" then per + > native-fsread: filename eq "$HOME/.lynxrc" then permit + > native-fsread: filename eq "$HOME/.mailcap" then permit + > native-fsread: filename eq "$HOME/.mime.types" then permi + > native-fsread: filename eq "$HOME/.terminfo" then permit + > native-fsread: filename eq "$HOME/.terminfo.db" then perm + > native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "$HOME" then permit < + native-fsread: filename eq "/etc/lynx.cfg" then permit < + native-fsread: filename eq "/" then permit < + native-fsread: filename eq "/usr/obj/bin/systrace/." then < + native-fsread: filename eq "/usr/obj/bin" then permit < + native-fcntl: permit < + native-getdirentries: permit < + native-lseek: permit < + native-fsread: filename eq "/usr/obj" then permit < + native-fsread: filename eq "$HOME/.mime.types" then permi < + native-sigaction: permit < + native-ioctl: permit < + native-fsread: filename eq "$HOME/.terminfo.db" then perm < + native-fsread: filename eq "$HOME/.terminfo" then permit < + native-pread: permit < + native-write: permit < + native-fsread: filename eq "$HOME/.lynx-keymaps" then per < + native-fsread: filename eq "/etc/utmp" then permit | native-fsread: filename eq "/var/run/ld.so.hints" then pe + native-poll: permit | native-fstat: permit + native-nanosleep: permit | native-fswrite: filename match "/tmp/lynx-*" then permit + > native-getdirentries: permit + > native-getpid: permit + native-fsread: filename eq "/etc/resolv.conf" then permit | native-ioctl: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK | native-issetugid: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-lseek: permit + native-sendto: true then permit | native-mmap: permit + native-select: permit | native-mprotect: prot eq "PROT_READ" then permit + > native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi + > native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm + > native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" + > native-munmap: permit + > native-nanosleep: permit + > native-poll: permit + > native-pread: permit + > native-read: permit + > native-select: permit + > native-sendto: true then permit + > native-sigaction: permit + > native-sigprocmask: permit + > native-socket: sockdom eq "AF_INET" and socktype eq "SOCK + native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-write: permit + native-exit: permit < diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_c1.out b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_c1.out new file mode 100644 index 0000000..e9ac88e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_c1.out @@ -0,0 +1,99 @@ +Policy: /usr/bin/lynx, Emulation: native ( + > native-issetugid: permit + > native-mprotect: permit + > native-mmap: permit + native-__sysctl: permit ( + > native-fsread: filename eq "/var/run/ld.so.hints" then pe + > native-fstat: permit + native-close: permit ( + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-fsread: filename match "/usr/lib/libssl.so.*" then + native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-read: permit + native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t + native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*" + native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p + native-fsread: filename match "/: | native-munmap: permit + native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit + native-fsread: filename eq "/etc/malloc.conf" then permit ( + native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit + native-fsread: filename eq "/etc/utmp" then permit < + native-fsread: filename eq "/home" then permit < + native-fsread: filename eq "$HOME" then permit < + native-fsread: filename eq "$HOME/.lynx-keymaps" then per < + native-fsread: filename eq "$HOME/.lynxrc" then permit < + native-fsread: filename eq "$HOME/.mailcap" then permit < + native-fsread: filename eq "$HOME/.mime.types" then permi < + native-fsread: filename eq "$HOME/.terminfo" then permit < + native-fsread: filename eq "$HOME/.terminfo.db" then perm < + native-fsread: filename eq "/obj" then permit < + native-fsread: filename eq "/tmp" then permit ( + native-fsread: filename match "/tmp/lynx-*/." then permit ( + > native-fsread: filename eq "$HOME" then permit + > native-fsread: filename eq "/etc/lynx.cfg" then permit + > native-fsread: filename eq "/" then permit + > native-fsread: filename eq "/usr/obj/bin/systrace/." then + > native-fsread: filename eq "/usr/obj/bin" then permit + > native-fcntl: permit + > native-getdirentries: permit + > native-lseek: permit + > native-fsread: filename eq "/usr/obj" then permit + native-fsread: filename eq "/usr" then permit ( + native-fsread: filename eq "/usr/bin" then permit ( + native-fsread: filename eq "/usr/games" then permit ( + native-fsread: filename eq "/usr/include" then permit ( + native-fsread: filename eq "/usr/lib" then permit ( + native-fsread: filename match "/usr/lib/libc.so.*" then p ( + native-fsread: filename match "/usr/lib/libcrypto.so.*" t ( + native-fsread: filename match "/usr/lib/libncurses.so.*" ( + native-fsread: filename match "/usr/lib/libssl.so.*" then ( + native-fsread: filename eq "/usr/libdata" then permit ( + native-fsread: filename eq "/usr/libexec" then permit ( + native-fsread: filename eq "/usr/lkm" then permit ( + native-fsread: filename eq "/usr/local" then permit ( + native-fsread: filename eq "/usr/mdec" then permit ( + native-fsread: filename eq "/usr/obj" then permit ( + native-fsread: filename eq "/usr/obj/bin" then permit ( + native-fsread: filename eq "/usr/obj/bin/systrace/." then ( + native-fsread: filename eq "/usr/obj/bin/systrace/.mailca ( + native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t ( + > native-fsread: filename eq "$HOME/.mime.types" then permi + > native-sigaction: permit + > native-ioctl: permit + > native-fsread: filename eq "$HOME/.terminfo.db" then perm + > native-fsread: filename eq "$HOME/.terminfo" then permit + native-fsread: filename eq "/usr/share/misc/terminfo.db" ( + > native-pread: permit + > native-write: permit + > native-fsread: filename eq "$HOME/.lynx-keymaps" then per + native-fsread: filename eq "/var/run/dev.db" then permit ( + native-fsread: filename eq "/var/run/ld.so.hints" then pe | native-fsread: filename eq "/etc/utmp" then permit + native-fstat: permit < + native-fswrite: filename match "/tmp/lynx-*" then permit < + native-getdirentries: permit < + native-getpid: permit < + native-gettimeofday: permit < + native-ioctl: permit < + native-issetugid: permit < + native-lseek: permit < + native-mmap: permit < + native-mprotect: prot eq "PROT_READ" then permit < + native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi < + native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm < + native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" < + native-munmap: permit < + native-nanosleep: permit < + native-poll: permit ( + native-pread: permit | native-nanosleep: permit + native-read: permit | native-gettimeofday: permit + native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit + native-select: permit < + native-sendto: true then permit < + native-sigaction: permit < + native-sigprocmask: permit < + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK ( + > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe + > native-sendto: true then permit + > native-select: permit + > native-recvfrom: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK ( + native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p + > native-exit: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_c2.out b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_c2.out new file mode 100644 index 0000000..fe7af0e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_c2.out @@ -0,0 +1,94 @@ +Policy: /usr/bin/lynx, Emulation: native ( + native-issetugid: permit < + native-mprotect: permit < + native-mmap: permit < + native-__sysctl: permit ( + native-fsread: filename eq "/var/run/ld.so.hints" then pe < + native-fstat: permit < + native-close: permit ( + native-fsread: filename match "/usr/lib/libssl.so.*" then | native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe + native-read: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p + native-fsread: filename match "/usr/lib/libcrypto.so.*" t | native-exit: permit + native-fsread: filename match "/usr/lib/libncurses.so.*" | native-fcntl: cmd eq "F_SETFD" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then p | native-fsread: filename eq "/" then permit + native-munmap: permit | native-fsread: filename match "/: + native-sigprocmask: permit | native-fsread: filename eq "/etc/lynx.cfg" then permit + native-fsread: filename eq "/etc/malloc.conf" then permit ( + native-getpid: permit | native-fsread: filename eq "/etc/resolv.conf" then permit + > native-fsread: filename eq "/etc/utmp" then permit + > native-fsread: filename eq "/home" then permit + > native-fsread: filename eq "$HOME" then permit + > native-fsread: filename eq "$HOME/.lynx-keymaps" then per + > native-fsread: filename eq "$HOME/.lynxrc" then permit + > native-fsread: filename eq "$HOME/.mailcap" then permit + > native-fsread: filename eq "$HOME/.mime.types" then permi + > native-fsread: filename eq "$HOME/.terminfo" then permit + > native-fsread: filename eq "$HOME/.terminfo.db" then perm + > native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "/tmp" then permit ( + native-fswrite: filename match "/tmp/lynx-*" then permit ( + native-fsread: filename match "/tmp/lynx-*/." then permit ( + native-fsread: filename eq "$HOME" then permit < + native-fsread: filename eq "/etc/lynx.cfg" then permit < + native-fsread: filename eq "/" then permit < + native-fsread: filename eq "/usr/obj/bin/systrace/." then < + native-fsread: filename eq "/usr/obj/bin" then permit < + native-fcntl: permit < + native-getdirentries: permit < + native-lseek: permit < + native-fsread: filename eq "/usr/obj" then permit < + native-fsread: filename eq "/usr" then permit ( + native-fsread: filename eq "/usr/bin" then permit ( + native-fsread: filename eq "/usr/games" then permit ( + native-fsread: filename eq "/usr/include" then permit ( + native-fsread: filename eq "/usr/lib" then permit ( + native-fsread: filename eq "/usr/libdata" then permit ( + native-fsread: filename eq "/usr/libexec" then permit ( + native-fsread: filename eq "/usr/lkm" then permit ( + native-fsread: filename eq "/usr/local" then permit ( + native-fsread: filename eq "/usr/mdec" then permit ( + native-fsread: filename eq "/home" then permit ( + native-fsread: filename eq "/obj" then permit ( + native-fsread: filename eq "$HOME/.lynxrc" then permit ( + native-fsread: filename match "/: ( + native-fsread: filename eq "/usr/obj/bin/systrace/.mailca ( + native-fsread: filename eq "$HOME/.mailcap" then permit ( + native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t ( + native-fsread: filename eq "$HOME/.mime.types" then permi < + native-sigaction: permit < + native-ioctl: permit < + native-fsread: filename eq "$HOME/.terminfo.db" then perm < + native-fsread: filename eq "$HOME/.terminfo" then permit < + native-fsread: filename eq "/usr/share/misc/terminfo.db" ( + native-pread: permit < + native-write: permit < + native-fsread: filename eq "$HOME/.lynx-keymaps" then per < + native-fsread: filename eq "/var/run/dev.db" then permit ( + native-fsread: filename eq "/etc/utmp" then permit | native-fsread: filename eq "/var/run/ld.so.hints" then pe + native-poll: permit | native-fstat: permit + native-nanosleep: permit | native-fswrite: filename match "/tmp/lynx-*" then permit + > native-getdirentries: permit + > native-getpid: permit + native-gettimeofday: permit ( + native-fsread: filename eq "/etc/resolv.conf" then permit | native-ioctl: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK | native-issetugid: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-lseek: permit + native-sendto: true then permit | native-mmap: permit + native-select: permit | native-mprotect: prot eq "PROT_READ" then permit + > native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi + > native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm + > native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" + > native-munmap: permit + > native-nanosleep: permit + > native-poll: permit + > native-pread: permit + > native-read: permit + native-recvfrom: permit ( + > native-select: permit + > native-sendto: true then permit + > native-sigaction: permit + > native-sigprocmask: permit + > native-socket: sockdom eq "AF_INET" and socktype eq "SOCK + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK ( + native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-write: permit + native-exit: permit < diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_d1.out b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_d1.out new file mode 100644 index 0000000..3e548b6 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_d1.out @@ -0,0 +1,69 @@ + > native-issetugid: permit + > native-mprotect: permit + > native-mmap: permit + > native-fsread: filename eq "/var/run/ld.so.hints" then pe + > native-fstat: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-fsread: filename match "/usr/lib/libssl.so.*" then + native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-read: permit + native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t + native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*" + native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p + native-fsread: filename match "/: | native-munmap: permit + native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit + native-fsread: filename eq "/etc/resolv.conf" then permit | native-getpid: permit + native-fsread: filename eq "/etc/utmp" then permit < + native-fsread: filename eq "/home" then permit < + native-fsread: filename eq "$HOME" then permit < + native-fsread: filename eq "$HOME/.lynx-keymaps" then per < + native-fsread: filename eq "$HOME/.lynxrc" then permit < + native-fsread: filename eq "$HOME/.mailcap" then permit < + native-fsread: filename eq "$HOME/.mime.types" then permi < + native-fsread: filename eq "$HOME/.terminfo" then permit < + native-fsread: filename eq "$HOME/.terminfo.db" then perm < + native-fsread: filename eq "/obj" then permit < + > native-fsread: filename eq "$HOME" then permit + > native-fsread: filename eq "/etc/lynx.cfg" then permit + > native-fsread: filename eq "/" then permit + > native-fsread: filename eq "/usr/obj/bin/systrace/." then + > native-fsread: filename eq "/usr/obj/bin" then permit + > native-fcntl: permit + > native-getdirentries: permit + > native-lseek: permit + > native-fsread: filename eq "/usr/obj" then permit + > native-fsread: filename eq "$HOME/.mime.types" then permi + > native-sigaction: permit + > native-ioctl: permit + > native-fsread: filename eq "$HOME/.terminfo.db" then perm + > native-fsread: filename eq "$HOME/.terminfo" then permit + > native-pread: permit + > native-write: permit + > native-fsread: filename eq "$HOME/.lynx-keymaps" then per + native-fsread: filename eq "/var/run/ld.so.hints" then pe | native-fsread: filename eq "/etc/utmp" then permit + native-fstat: permit < + native-fswrite: filename match "/tmp/lynx-*" then permit < + native-getdirentries: permit < + native-getpid: permit < + native-gettimeofday: permit < + native-ioctl: permit < + native-issetugid: permit < + native-lseek: permit < + native-mmap: permit < + native-mprotect: prot eq "PROT_READ" then permit < + native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi < + native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm < + native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" < + native-munmap: permit < + native-nanosleep: permit < + native-pread: permit | native-nanosleep: permit + native-read: permit | native-gettimeofday: permit + native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit + native-select: permit < + native-sendto: true then permit < + native-sigaction: permit < + native-sigprocmask: permit < + > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe + > native-sendto: true then permit + > native-select: permit + > native-recvfrom: permit + native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p + > native-exit: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_d2.out b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_d2.out new file mode 100644 index 0000000..4504c36 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_iflags_d2.out @@ -0,0 +1,65 @@ + native-issetugid: permit < + native-mprotect: permit < + native-mmap: permit < + native-fsread: filename eq "/var/run/ld.so.hints" then pe < + native-fstat: permit < + native-fsread: filename match "/usr/lib/libssl.so.*" then | native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe + native-read: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p + native-fsread: filename match "/usr/lib/libcrypto.so.*" t | native-exit: permit + native-fsread: filename match "/usr/lib/libncurses.so.*" | native-fcntl: cmd eq "F_SETFD" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then p | native-fsread: filename eq "/" then permit + native-munmap: permit | native-fsread: filename match "/: + native-sigprocmask: permit | native-fsread: filename eq "/etc/lynx.cfg" then permit + native-getpid: permit | native-fsread: filename eq "/etc/resolv.conf" then permit + > native-fsread: filename eq "/etc/utmp" then permit + > native-fsread: filename eq "/home" then permit + > native-fsread: filename eq "$HOME" then permit + > native-fsread: filename eq "$HOME/.lynx-keymaps" then per + > native-fsread: filename eq "$HOME/.lynxrc" then permit + > native-fsread: filename eq "$HOME/.mailcap" then permit + > native-fsread: filename eq "$HOME/.mime.types" then permi + > native-fsread: filename eq "$HOME/.terminfo" then permit + > native-fsread: filename eq "$HOME/.terminfo.db" then perm + > native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "$HOME" then permit < + native-fsread: filename eq "/etc/lynx.cfg" then permit < + native-fsread: filename eq "/" then permit < + native-fsread: filename eq "/usr/obj/bin/systrace/." then < + native-fsread: filename eq "/usr/obj/bin" then permit < + native-fcntl: permit < + native-getdirentries: permit < + native-lseek: permit < + native-fsread: filename eq "/usr/obj" then permit < + native-fsread: filename eq "$HOME/.mime.types" then permi < + native-sigaction: permit < + native-ioctl: permit < + native-fsread: filename eq "$HOME/.terminfo.db" then perm < + native-fsread: filename eq "$HOME/.terminfo" then permit < + native-pread: permit < + native-write: permit < + native-fsread: filename eq "$HOME/.lynx-keymaps" then per < + native-fsread: filename eq "/etc/utmp" then permit | native-fsread: filename eq "/var/run/ld.so.hints" then pe + native-poll: permit | native-fstat: permit + native-nanosleep: permit | native-fswrite: filename match "/tmp/lynx-*" then permit + > native-getdirentries: permit + > native-getpid: permit + native-fsread: filename eq "/etc/resolv.conf" then permit | native-ioctl: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK | native-issetugid: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe | native-lseek: permit + native-sendto: true then permit | native-mmap: permit + native-select: permit | native-mprotect: prot eq "PROT_READ" then permit + > native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permi + > native-mprotect: prot eq "PROT_READ|PROT_WRITE" then perm + > native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" + > native-munmap: permit + > native-nanosleep: permit + > native-poll: permit + > native-pread: permit + > native-read: permit + > native-select: permit + > native-sendto: true then permit + > native-sigaction: permit + > native-sigprocmask: permit + > native-socket: sockdom eq "AF_INET" and socktype eq "SOCK + native-connect: sockaddr match "inet-\\\[*\\\]:80" then p | native-write: permit + native-exit: permit < diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_input1 b/contrib/netbsd-tests/usr.bin/sdiff/d_input1 new file mode 100644 index 0000000..686e8ea --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_input1 @@ -0,0 +1,72 @@ +Policy: /usr/bin/lynx, Emulation: native + native-__sysctl: permit + native-close: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then permit + native-connect: sockaddr match "inet-\\\[*\\\]:80" then permit + native-exit: permit + native-fcntl: cmd eq "F_SETFD" then permit + native-fsread: filename eq "/" then permit + native-fsread: filename match "/: *" then permit + native-fsread: filename eq "/etc/lynx.cfg" then permit + native-fsread: filename eq "/etc/malloc.conf" then permit + native-fsread: filename eq "/etc/resolv.conf" then permit + native-fsread: filename eq "/etc/utmp" then permit + native-fsread: filename eq "/home" then permit + native-fsread: filename eq "$HOME" then permit + native-fsread: filename eq "$HOME/.lynx-keymaps" then permit + native-fsread: filename eq "$HOME/.lynxrc" then permit + native-fsread: filename eq "$HOME/.mailcap" then permit + native-fsread: filename eq "$HOME/.mime.types" then permit + native-fsread: filename eq "$HOME/.terminfo" then permit + native-fsread: filename eq "$HOME/.terminfo.db" then permit + native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "/tmp" then permit + native-fsread: filename match "/tmp/lynx-*/." then permit + native-fsread: filename eq "/usr" then permit + native-fsread: filename eq "/usr/bin" then permit + native-fsread: filename eq "/usr/games" then permit + native-fsread: filename eq "/usr/include" then permit + native-fsread: filename eq "/usr/lib" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then permit + native-fsread: filename match "/usr/lib/libcrypto.so.*" then permit + native-fsread: filename match "/usr/lib/libncurses.so.*" then permit + native-fsread: filename match "/usr/lib/libssl.so.*" then permit + native-fsread: filename eq "/usr/libdata" then permit + native-fsread: filename eq "/usr/libexec" then permit + native-fsread: filename eq "/usr/lkm" then permit + native-fsread: filename eq "/usr/local" then permit + native-fsread: filename eq "/usr/mdec" then permit + native-fsread: filename eq "/usr/obj" then permit + native-fsread: filename eq "/usr/obj/bin" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/." then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mailcap" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mime.types" then permit + native-fsread: filename eq "/usr/share/misc/terminfo.db" then permit + native-fsread: filename eq "/var/run/dev.db" then permit + native-fsread: filename eq "/var/run/ld.so.hints" then permit + native-fstat: permit + native-fswrite: filename match "/tmp/lynx-*" then permit + native-getdirentries: permit + native-getpid: permit + native-gettimeofday: permit + native-ioctl: permit + native-issetugid: permit + native-lseek: permit + native-mmap: permit + native-mprotect: prot eq "PROT_READ" then permit + native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permit + native-mprotect: prot eq "PROT_READ|PROT_WRITE" then permit + native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" then permit + native-munmap: permit + native-nanosleep: permit + native-poll: permit + native-pread: permit + native-read: permit + native-recvfrom: permit + native-select: permit + native-sendto: true then permit + native-sigaction: permit + native-sigprocmask: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_DGRAM" then permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_STREAM" then permit + native-write: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_input2 b/contrib/netbsd-tests/usr.bin/sdiff/d_input2 new file mode 100644 index 0000000..70e1b57 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_input2 @@ -0,0 +1,69 @@ +Policy: /usr/bin/lynx, Emulation: native + native-issetugid: permit + native-mprotect: permit + native-mmap: permit + native-__sysctl: permit + native-fsread: filename eq "/var/run/ld.so.hints" then permit + native-fstat: permit + native-close: permit + native-fsread: filename match "/usr/lib/libssl.so.*" then permit + native-read: permit + native-fsread: filename match "/usr/lib/libcrypto.so.*" then permit + native-fsread: filename match "/usr/lib/libncurses.so.*" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then permit + native-munmap: permit + native-sigprocmask: permit + native-fsread: filename eq "/etc/malloc.conf" then permit + native-getpid: permit + native-fsread: filename eq "/tmp" then permit + native-fswrite: filename match "/tmp/lynx-*" then permit + native-fsread: filename match "/tmp/lynx-*/." then permit + native-fsread: filename eq "$HOME" then permit + native-fsread: filename eq "/etc/lynx.cfg" then permit + native-fsread: filename eq "/" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/." then permit + native-fsread: filename eq "/usr/obj/bin" then permit + native-fcntl: permit + native-getdirentries: permit + native-lseek: permit + native-fsread: filename eq "/usr/obj" then permit + native-fsread: filename eq "/usr" then permit + native-fsread: filename eq "/usr/bin" then permit + native-fsread: filename eq "/usr/games" then permit + native-fsread: filename eq "/usr/include" then permit + native-fsread: filename eq "/usr/lib" then permit + native-fsread: filename eq "/usr/libdata" then permit + native-fsread: filename eq "/usr/libexec" then permit + native-fsread: filename eq "/usr/lkm" then permit + native-fsread: filename eq "/usr/local" then permit + native-fsread: filename eq "/usr/mdec" then permit + native-fsread: filename eq "/home" then permit + native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "$HOME/.lynxrc" then permit + native-fsread: filename match "/: *" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mailcap" then permit + native-fsread: filename eq "$HOME/.mailcap" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mime.types" then permit + native-fsread: filename eq "$HOME/.mime.types" then permit + native-sigaction: permit + native-ioctl: permit + native-fsread: filename eq "$HOME/.terminfo.db" then permit + native-fsread: filename eq "$HOME/.terminfo" then permit + native-fsread: filename eq "/usr/share/misc/terminfo.db" then permit + native-pread: permit + native-write: permit + native-fsread: filename eq "$HOME/.lynx-keymaps" then permit + native-fsread: filename eq "/var/run/dev.db" then permit + native-fsread: filename eq "/etc/utmp" then permit + native-poll: permit + native-nanosleep: permit + native-gettimeofday: permit + native-fsread: filename eq "/etc/resolv.conf" then permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_DGRAM" then permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then permit + native-sendto: true then permit + native-select: permit + native-recvfrom: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_STREAM" then permit + native-connect: sockaddr match "inet-\\\[*\\\]:80" then permit + native-exit: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_oneline.in b/contrib/netbsd-tests/usr.bin/sdiff/d_oneline.in new file mode 100644 index 0000000..acbe86c --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_oneline.in @@ -0,0 +1 @@ +abcd diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_oneline_a.out b/contrib/netbsd-tests/usr.bin/sdiff/d_oneline_a.out new file mode 100644 index 0000000..99560a6 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_oneline_a.out @@ -0,0 +1 @@ + > abcd diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_oneline_b.out b/contrib/netbsd-tests/usr.bin/sdiff/d_oneline_b.out new file mode 100644 index 0000000..7300b1d --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_oneline_b.out @@ -0,0 +1 @@ +abcd < diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_same.out b/contrib/netbsd-tests/usr.bin/sdiff/d_same.out new file mode 100644 index 0000000..bce8944 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_same.out @@ -0,0 +1,72 @@ +Policy: /usr/bin/lynx, Emulation: native Policy: /usr/bin/lynx, Emulation: native + native-__sysctl: permit native-__sysctl: permit + native-close: permit native-close: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then perm native-connect: sockaddr eq "inet-[127.0.0.1]:53" then perm + native-connect: sockaddr match "inet-\\\[*\\\]:80" then per native-connect: sockaddr match "inet-\\\[*\\\]:80" then per + native-exit: permit native-exit: permit + native-fcntl: cmd eq "F_SETFD" then permit native-fcntl: cmd eq "F_SETFD" then permit + native-fsread: filename eq "/" then permit native-fsread: filename eq "/" then permit + native-fsread: filename match "/: *" native-fsread: filename match "/: *" + native-fsread: filename eq "/etc/lynx.cfg" then permit native-fsread: filename eq "/etc/lynx.cfg" then permit + native-fsread: filename eq "/etc/malloc.conf" then permit native-fsread: filename eq "/etc/malloc.conf" then permit + native-fsread: filename eq "/etc/resolv.conf" then permit native-fsread: filename eq "/etc/resolv.conf" then permit + native-fsread: filename eq "/etc/utmp" then permit native-fsread: filename eq "/etc/utmp" then permit + native-fsread: filename eq "/home" then permit native-fsread: filename eq "/home" then permit + native-fsread: filename eq "$HOME" then permit native-fsread: filename eq "$HOME" then permit + native-fsread: filename eq "$HOME/.lynx-keymaps" then permi native-fsread: filename eq "$HOME/.lynx-keymaps" then permi + native-fsread: filename eq "$HOME/.lynxrc" then permit native-fsread: filename eq "$HOME/.lynxrc" then permit + native-fsread: filename eq "$HOME/.mailcap" then permit native-fsread: filename eq "$HOME/.mailcap" then permit + native-fsread: filename eq "$HOME/.mime.types" then permit native-fsread: filename eq "$HOME/.mime.types" then permit + native-fsread: filename eq "$HOME/.terminfo" then permit native-fsread: filename eq "$HOME/.terminfo" then permit + native-fsread: filename eq "$HOME/.terminfo.db" then permit native-fsread: filename eq "$HOME/.terminfo.db" then permit + native-fsread: filename eq "/obj" then permit native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "/tmp" then permit native-fsread: filename eq "/tmp" then permit + native-fsread: filename match "/tmp/lynx-*/." then permit native-fsread: filename match "/tmp/lynx-*/." then permit + native-fsread: filename eq "/usr" then permit native-fsread: filename eq "/usr" then permit + native-fsread: filename eq "/usr/bin" then permit native-fsread: filename eq "/usr/bin" then permit + native-fsread: filename eq "/usr/games" then permit native-fsread: filename eq "/usr/games" then permit + native-fsread: filename eq "/usr/include" then permit native-fsread: filename eq "/usr/include" then permit + native-fsread: filename eq "/usr/lib" then permit native-fsread: filename eq "/usr/lib" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then per native-fsread: filename match "/usr/lib/libc.so.*" then per + native-fsread: filename match "/usr/lib/libcrypto.so.*" the native-fsread: filename match "/usr/lib/libcrypto.so.*" the + native-fsread: filename match "/usr/lib/libncurses.so.*" th native-fsread: filename match "/usr/lib/libncurses.so.*" th + native-fsread: filename match "/usr/lib/libssl.so.*" then p native-fsread: filename match "/usr/lib/libssl.so.*" then p + native-fsread: filename eq "/usr/libdata" then permit native-fsread: filename eq "/usr/libdata" then permit + native-fsread: filename eq "/usr/libexec" then permit native-fsread: filename eq "/usr/libexec" then permit + native-fsread: filename eq "/usr/lkm" then permit native-fsread: filename eq "/usr/lkm" then permit + native-fsread: filename eq "/usr/local" then permit native-fsread: filename eq "/usr/local" then permit + native-fsread: filename eq "/usr/mdec" then permit native-fsread: filename eq "/usr/mdec" then permit + native-fsread: filename eq "/usr/obj" then permit native-fsread: filename eq "/usr/obj" then permit + native-fsread: filename eq "/usr/obj/bin" then permit native-fsread: filename eq "/usr/obj/bin" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/." then p native-fsread: filename eq "/usr/obj/bin/systrace/." then p + native-fsread: filename eq "/usr/obj/bin/systrace/.mailcap" native-fsread: filename eq "/usr/obj/bin/systrace/.mailcap" + native-fsread: filename eq "/usr/obj/bin/systrace/.mime.typ native-fsread: filename eq "/usr/obj/bin/systrace/.mime.typ + native-fsread: filename eq "/usr/share/misc/terminfo.db" th native-fsread: filename eq "/usr/share/misc/terminfo.db" th + native-fsread: filename eq "/var/run/dev.db" then permit native-fsread: filename eq "/var/run/dev.db" then permit + native-fsread: filename eq "/var/run/ld.so.hints" then perm native-fsread: filename eq "/var/run/ld.so.hints" then perm + native-fstat: permit native-fstat: permit + native-fswrite: filename match "/tmp/lynx-*" then permit native-fswrite: filename match "/tmp/lynx-*" then permit + native-getdirentries: permit native-getdirentries: permit + native-getpid: permit native-getpid: permit + native-gettimeofday: permit native-gettimeofday: permit + native-ioctl: permit native-ioctl: permit + native-issetugid: permit native-issetugid: permit + native-lseek: permit native-lseek: permit + native-mmap: permit native-mmap: permit + native-mprotect: prot eq "PROT_READ" then permit native-mprotect: prot eq "PROT_READ" then permit + native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permit native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permit + native-mprotect: prot eq "PROT_READ|PROT_WRITE" then permit native-mprotect: prot eq "PROT_READ|PROT_WRITE" then permit + native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" t native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" t + native-munmap: permit native-munmap: permit + native-nanosleep: permit native-nanosleep: permit + native-poll: permit native-poll: permit + native-pread: permit native-pread: permit + native-read: permit native-read: permit + native-recvfrom: permit native-recvfrom: permit + native-select: permit native-select: permit + native-sendto: true then permit native-sendto: true then permit + native-sigaction: permit native-sigaction: permit + native-sigprocmask: permit native-sigprocmask: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_D native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_D + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_S native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_S + native-write: permit native-write: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_short.out b/contrib/netbsd-tests/usr.bin/sdiff/d_short.out new file mode 100644 index 0000000..7a33460 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_short.out @@ -0,0 +1,15 @@ +Policy: /usr/bin/lynx, Emulation: native + native-issetugid: permit + native-mprotect: permit + native-mmap: permit + native-__sysctl: permit + native-close: permit + native-fsread: filename match "/usr/lib/libssl.so.*" then permit + native-read: permit + native-fsread: filename match "/usr/lib/libcrypto.so.*" then permit + native-fsread: filename match "/usr/lib/libncurses.so.*" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then permit + native-munmap: permit + native-sigprocmask: permit + native-fsread: filename eq "/etc/malloc.conf" then permit + native-fsread: filename eq "/etc/resolv.conf" then permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_tabends.in b/contrib/netbsd-tests/usr.bin/sdiff/d_tabends.in new file mode 100644 index 0000000..0547049 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_tabends.in @@ -0,0 +1,17 @@ + +0 +01 +012 +0123 +01234 +012345 +0123456 +01234567 +012345670 +0123456701 +01234567012 +012345670123 +0123456701234 +01234567012345 +012345670123456 +0123456701234567 diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_tabends_a.out b/contrib/netbsd-tests/usr.bin/sdiff/d_tabends_a.out new file mode 100644 index 0000000..423bd02 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_tabends_a.out @@ -0,0 +1,17 @@ + < +0 < +01 < +012 < +0123 < +01234 < +012345 < +0123456 < +01234567 < +012345670 < +0123456701 < +01234567012 < +012345670123 < +0123456701234 < +0123456701234 < +0123456701234 < +0123456701234 < diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_tabends_b.out b/contrib/netbsd-tests/usr.bin/sdiff/d_tabends_b.out new file mode 100644 index 0000000..b180705 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_tabends_b.out @@ -0,0 +1,17 @@ + > + > 0 + > 01 + > 012 + > 0123 + > 01234 + > 012345 + > 0123456 + > 01234567 + > 012345670 + > 0123456701 + > 01234567012 + > 012345670123 + > 0123456701234 + > 0123456701234 + > 0123456701234 + > 0123456701234 diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_tabends_c.out b/contrib/netbsd-tests/usr.bin/sdiff/d_tabends_c.out new file mode 100644 index 0000000..c301382 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_tabends_c.out @@ -0,0 +1,17 @@ + < +0 < +01 < +012 < +0123 < +01234 < +012345 < +0123456 < +01234567 < +01234567 < +01234567 < +01234567 < +01234567 < +01234567 < +01234567 < +01234567 < +01234567 < diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_tabs.out b/contrib/netbsd-tests/usr.bin/sdiff/d_tabs.out new file mode 100644 index 0000000..eb34bac --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_tabs.out @@ -0,0 +1,102 @@ +Policy: /usr/bin/lynx, Emulation: native Policy: /usr/bin/lynx, Emulation: native + > native-issetugid: permit + > native-mprotect: permit + > native-mmap: permit + native-__sysctl: permit native-__sysctl: permit + > native-fsread: filename eq "/var/run/ld.so.hints" then pe + > native-fstat: permit + native-close: permit native-close: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then | native-fsread: filename match "/usr/lib/libssl.so.*" then + native-connect: sockaddr match "inet-\\\[*\\\]:80" then | native-read: permit + native-exit: permit | native-fsread: filename match "/usr/lib/libcrypto.so.*" t + native-fcntl: cmd eq "F_SETFD" then permit | native-fsread: filename match "/usr/lib/libncurses.so.*" + native-fsread: filename eq "/" then permit | native-fsread: filename match "/usr/lib/libc.so.*" then p + native-fsread: filename match "/ | native-munmap: permit + native-fsread: filename eq "/etc/lynx.cfg" then permit | native-sigprocmask: permit + native-fsread: filename eq "/etc/malloc.conf" then perm native-fsread: filename eq "/etc/malloc.conf" then permit + native-fsread: filename eq "/etc/resolv.conf" then perm | native-getpid: permit + native-fsread: filename eq "/etc/utmp" then permit < + native-fsread: filename eq "/home" then permit < + native-fsread: filename eq "$HOME" then permit < + native-fsread: filename eq "$HOME/.lynx-keymaps" then p < + native-fsread: filename eq "$HOME/.lynxrc" then permit < + native-fsread: filename eq "$HOME/.mailcap" then permit < + native-fsread: filename eq "$HOME/.mime.types" then per < + native-fsread: filename eq "$HOME/.terminfo" then permi < + native-fsread: filename eq "$HOME/.terminfo.db" then pe < + native-fsread: filename eq "/obj" then permit < + native-fsread: filename eq "/tmp" then permit native-fsread: filename eq "/tmp" then permit + > native-fswrite: filename match "/tmp/lynx-*" then permit + native-fsread: filename match "/tmp/lynx-*/." then perm native-fsread: filename match "/tmp/lynx-*/." then permit + > native-fsread: filename eq "$HOME" then permit + > native-fsread: filename eq "/etc/lynx.cfg" then permit + > native-fsread: filename eq "/" then permit + > native-fsread: filename eq "/usr/obj/bin/systrace/." then + > native-fsread: filename eq "/usr/obj/bin" then permit + > native-fcntl: permit + > native-getdirentries: permit + > native-lseek: permit + > native-fsread: filename eq "/usr/obj" then permit + native-fsread: filename eq "/usr" then permit native-fsread: filename eq "/usr" then permit + native-fsread: filename eq "/usr/bin" then permit native-fsread: filename eq "/usr/bin" then permit + native-fsread: filename eq "/usr/games" then permit native-fsread: filename eq "/usr/games" then permit + native-fsread: filename eq "/usr/include" then permit native-fsread: filename eq "/usr/include" then permit + native-fsread: filename eq "/usr/lib" then permit native-fsread: filename eq "/usr/lib" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then < + native-fsread: filename match "/usr/lib/libcrypto.so.*" < + native-fsread: filename match "/usr/lib/libncurses.so.* < + native-fsread: filename match "/usr/lib/libssl.so.*" th < + native-fsread: filename eq "/usr/libdata" then permit native-fsread: filename eq "/usr/libdata" then permit + native-fsread: filename eq "/usr/libexec" then permit native-fsread: filename eq "/usr/libexec" then permit + native-fsread: filename eq "/usr/lkm" then permit native-fsread: filename eq "/usr/lkm" then permit + native-fsread: filename eq "/usr/local" then permit native-fsread: filename eq "/usr/local" then permit + native-fsread: filename eq "/usr/mdec" then permit native-fsread: filename eq "/usr/mdec" then permit + native-fsread: filename eq "/usr/obj" then permit | native-fsread: filename eq "/home" then permit + native-fsread: filename eq "/usr/obj/bin" then permit | native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/." th | native-fsread: filename eq "$HOME/.lynxrc" then permit + > native-fsread: filename match "/: + native-fsread: filename eq "/usr/obj/bin/systrace/.mail native-fsread: filename eq "/usr/obj/bin/systrace/.mailca + > native-fsread: filename eq "$HOME/.mailcap" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mime native-fsread: filename eq "/usr/obj/bin/systrace/.mime.t + > native-fsread: filename eq "$HOME/.mime.types" then permi + > native-sigaction: permit + > native-ioctl: permit + > native-fsread: filename eq "$HOME/.terminfo.db" then perm + > native-fsread: filename eq "$HOME/.terminfo" then permit + native-fsread: filename eq "/usr/share/misc/terminfo.db native-fsread: filename eq "/usr/share/misc/terminfo.db" + > native-pread: permit + > native-write: permit + > native-fsread: filename eq "$HOME/.lynx-keymaps" then per + native-fsread: filename eq "/var/run/dev.db" then permi native-fsread: filename eq "/var/run/dev.db" then permit + native-fsread: filename eq "/var/run/ld.so.hints" then | native-fsread: filename eq "/etc/utmp" then permit + native-fstat: permit < + native-fswrite: filename match "/tmp/lynx-*" then permi < + native-getdirentries: permit < + native-getpid: permit < + native-gettimeofday: permit < + native-ioctl: permit < + native-issetugid: permit < + native-lseek: permit < + native-mmap: permit < + native-mprotect: prot eq "PROT_READ" then permit < + native-mprotect: prot eq "PROT_READ|PROT_EXEC" then per < + native-mprotect: prot eq "PROT_READ|PROT_WRITE" then pe < + native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXE < + native-munmap: permit < + native-nanosleep: permit < + native-poll: permit native-poll: permit + native-pread: permit | native-nanosleep: permit + native-read: permit | native-gettimeofday: permit + native-recvfrom: permit | native-fsread: filename eq "/etc/resolv.conf" then permit + native-select: permit < + native-sendto: true then permit < + native-sigaction: permit < + native-sigprocmask: permit < + native-socket: sockdom eq "AF_INET" and socktype eq "SO native-socket: sockdom eq "AF_INET" and socktype eq "SOCK + > native-connect: sockaddr eq "inet-[127.0.0.1]:53" then pe + > native-sendto: true then permit + > native-select: permit + > native-recvfrom: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SO native-socket: sockdom eq "AF_INET" and socktype eq "SOCK + native-write: permit | native-connect: sockaddr match "inet-\\\[*\\\]:80" then p + > native-exit: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_tabs1.in b/contrib/netbsd-tests/usr.bin/sdiff/d_tabs1.in new file mode 100644 index 0000000..b5a1834 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_tabs1.in @@ -0,0 +1,72 @@ +Policy: /usr/bin/lynx, Emulation: native + native-__sysctl: permit + native-close: permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then permit + native-connect: sockaddr match "inet-\\\[*\\\]:80" then permit + native-exit: permit + native-fcntl: cmd eq "F_SETFD" then permit + native-fsread: filename eq "/" then permit + native-fsread: filename match "/: *" then permit + native-fsread: filename eq "/etc/lynx.cfg" then permit + native-fsread: filename eq "/etc/malloc.conf" then permit + native-fsread: filename eq "/etc/resolv.conf" then permit + native-fsread: filename eq "/etc/utmp" then permit + native-fsread: filename eq "/home" then permit + native-fsread: filename eq "$HOME" then permit + native-fsread: filename eq "$HOME/.lynx-keymaps" then permit + native-fsread: filename eq "$HOME/.lynxrc" then permit + native-fsread: filename eq "$HOME/.mailcap" then permit + native-fsread: filename eq "$HOME/.mime.types" then permit + native-fsread: filename eq "$HOME/.terminfo" then permit + native-fsread: filename eq "$HOME/.terminfo.db" then permit + native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "/tmp" then permit + native-fsread: filename match "/tmp/lynx-*/." then permit + native-fsread: filename eq "/usr" then permit + native-fsread: filename eq "/usr/bin" then permit + native-fsread: filename eq "/usr/games" then permit + native-fsread: filename eq "/usr/include" then permit + native-fsread: filename eq "/usr/lib" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then permit + native-fsread: filename match "/usr/lib/libcrypto.so.*" then permit + native-fsread: filename match "/usr/lib/libncurses.so.*" then permit + native-fsread: filename match "/usr/lib/libssl.so.*" then permit + native-fsread: filename eq "/usr/libdata" then permit + native-fsread: filename eq "/usr/libexec" then permit + native-fsread: filename eq "/usr/lkm" then permit + native-fsread: filename eq "/usr/local" then permit + native-fsread: filename eq "/usr/mdec" then permit + native-fsread: filename eq "/usr/obj" then permit + native-fsread: filename eq "/usr/obj/bin" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/." then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mailcap" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mime.types" then permit + native-fsread: filename eq "/usr/share/misc/terminfo.db" then permit + native-fsread: filename eq "/var/run/dev.db" then permit + native-fsread: filename eq "/var/run/ld.so.hints" then permit + native-fstat: permit + native-fswrite: filename match "/tmp/lynx-*" then permit + native-getdirentries: permit + native-getpid: permit + native-gettimeofday: permit + native-ioctl: permit + native-issetugid: permit + native-lseek: permit + native-mmap: permit + native-mprotect: prot eq "PROT_READ" then permit + native-mprotect: prot eq "PROT_READ|PROT_EXEC" then permit + native-mprotect: prot eq "PROT_READ|PROT_WRITE" then permit + native-mprotect: prot eq "PROT_READ|PROT_WRITE|PROT_EXEC" then permit + native-munmap: permit + native-nanosleep: permit + native-poll: permit + native-pread: permit + native-read: permit + native-recvfrom: permit + native-select: permit + native-sendto: true then permit + native-sigaction: permit + native-sigprocmask: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_DGRAM" then permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_STREAM" then permit + native-write: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/d_tabs2.in b/contrib/netbsd-tests/usr.bin/sdiff/d_tabs2.in new file mode 100644 index 0000000..d00f415 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/d_tabs2.in @@ -0,0 +1,69 @@ +Policy: /usr/bin/lynx, Emulation: native + native-issetugid: permit + native-mprotect: permit + native-mmap: permit + native-__sysctl: permit + native-fsread: filename eq "/var/run/ld.so.hints" then permit + native-fstat: permit + native-close: permit + native-fsread: filename match "/usr/lib/libssl.so.*" then permit + native-read: permit + native-fsread: filename match "/usr/lib/libcrypto.so.*" then permit + native-fsread: filename match "/usr/lib/libncurses.so.*" then permit + native-fsread: filename match "/usr/lib/libc.so.*" then permit + native-munmap: permit + native-sigprocmask: permit + native-fsread: filename eq "/etc/malloc.conf" then permit + native-getpid: permit + native-fsread: filename eq "/tmp" then permit + native-fswrite: filename match "/tmp/lynx-*" then permit + native-fsread: filename match "/tmp/lynx-*/." then permit + native-fsread: filename eq "$HOME" then permit + native-fsread: filename eq "/etc/lynx.cfg" then permit + native-fsread: filename eq "/" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/." then permit + native-fsread: filename eq "/usr/obj/bin" then permit + native-fcntl: permit + native-getdirentries: permit + native-lseek: permit + native-fsread: filename eq "/usr/obj" then permit + native-fsread: filename eq "/usr" then permit + native-fsread: filename eq "/usr/bin" then permit + native-fsread: filename eq "/usr/games" then permit + native-fsread: filename eq "/usr/include" then permit + native-fsread: filename eq "/usr/lib" then permit + native-fsread: filename eq "/usr/libdata" then permit + native-fsread: filename eq "/usr/libexec" then permit + native-fsread: filename eq "/usr/lkm" then permit + native-fsread: filename eq "/usr/local" then permit + native-fsread: filename eq "/usr/mdec" then permit + native-fsread: filename eq "/home" then permit + native-fsread: filename eq "/obj" then permit + native-fsread: filename eq "$HOME/.lynxrc" then permit + native-fsread: filename match "/: *" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mailcap" then permit + native-fsread: filename eq "$HOME/.mailcap" then permit + native-fsread: filename eq "/usr/obj/bin/systrace/.mime.types" then permit + native-fsread: filename eq "$HOME/.mime.types" then permit + native-sigaction: permit + native-ioctl: permit + native-fsread: filename eq "$HOME/.terminfo.db" then permit + native-fsread: filename eq "$HOME/.terminfo" then permit + native-fsread: filename eq "/usr/share/misc/terminfo.db" then permit + native-pread: permit + native-write: permit + native-fsread: filename eq "$HOME/.lynx-keymaps" then permit + native-fsread: filename eq "/var/run/dev.db" then permit + native-fsread: filename eq "/etc/utmp" then permit + native-poll: permit + native-nanosleep: permit + native-gettimeofday: permit + native-fsread: filename eq "/etc/resolv.conf" then permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_DGRAM" then permit + native-connect: sockaddr eq "inet-[127.0.0.1]:53" then permit + native-sendto: true then permit + native-select: permit + native-recvfrom: permit + native-socket: sockdom eq "AF_INET" and socktype eq "SOCK_STREAM" then permit + native-connect: sockaddr match "inet-\\\[*\\\]:80" then permit + native-exit: permit diff --git a/contrib/netbsd-tests/usr.bin/sdiff/t_sdiff.sh b/contrib/netbsd-tests/usr.bin/sdiff/t_sdiff.sh new file mode 100755 index 0000000..2d6fc2d --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sdiff/t_sdiff.sh @@ -0,0 +1,206 @@ +# $NetBSD: t_sdiff.sh,v 1.1 2012/03/17 16:33:15 jruoho Exp $ +# +# Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case flags +flags_head() +{ + atf_set "descr" "Checks -l, -s and -w flags" +} +flags_body() +{ + atf_check -o file:$(atf_get_srcdir)/d_flags_l.out -s eq:1 \ + sdiff -l "$(atf_get_srcdir)/d_input1" "$(atf_get_srcdir)/d_input2" + + atf_check -o file:$(atf_get_srcdir)/d_flags_s.out -s eq:1 \ + sdiff -s "$(atf_get_srcdir)/d_input1" "$(atf_get_srcdir)/d_input2" + + atf_check -o file:$(atf_get_srcdir)/d_flags_w.out -s eq:1 \ + sdiff -w 125 "$(atf_get_srcdir)/d_input1" "$(atf_get_srcdir)/d_input2" +} + +atf_test_case iflags +iflags_head() +{ + atf_set "descr" "Checks flags -l, -s and -w combined with -I" +} +iflags_body() +{ + tail1="-w 125 -I .*filename.* $(atf_get_srcdir)/d_input1 $(atf_get_srcdir)/d_input2" + tail2="-w 125 -I .*filename.* $(atf_get_srcdir)/d_input2 $(atf_get_srcdir)/d_input1" + + atf_check -o file:$(atf_get_srcdir)/d_iflags_a1.out -s eq:1 sdiff ${tail1} + atf_check -o file:$(atf_get_srcdir)/d_iflags_a2.out -s eq:1 sdiff ${tail2} + atf_check -o file:$(atf_get_srcdir)/d_iflags_b1.out -s eq:1 sdiff -s ${tail1} + atf_check -o file:$(atf_get_srcdir)/d_iflags_b2.out -s eq:1 sdiff -s ${tail2} + atf_check -o file:$(atf_get_srcdir)/d_iflags_c1.out -s eq:1 sdiff -l ${tail1} + atf_check -o file:$(atf_get_srcdir)/d_iflags_c2.out -s eq:1 sdiff -l ${tail2} + atf_check -o file:$(atf_get_srcdir)/d_iflags_d1.out -s eq:1 sdiff -s ${tail1} + atf_check -o file:$(atf_get_srcdir)/d_iflags_d2.out -s eq:1 sdiff -s ${tail2} +} + +atf_test_case tabs +tabs_head() +{ + atf_set "descr" "Checks comparing files containing tabs" +} +tabs_body() +{ + atf_check -o file:$(atf_get_srcdir)/d_tabs.out -s eq:1 \ + sdiff "$(atf_get_srcdir)/d_tabs1.in" "$(atf_get_srcdir)/d_tabs2.in" +} + +atf_test_case tabends +tabends_head() +{ + atf_set "descr" "Checks correct handling of lines ended with tabs" +} +tabends_body() +{ + atf_check -o file:$(atf_get_srcdir)/d_tabends_a.out -s eq:1 \ + sdiff -w30 "$(atf_get_srcdir)/d_tabends.in" /dev/null + + atf_check -o file:$(atf_get_srcdir)/d_tabends_b.out -s eq:1 \ + sdiff -w30 /dev/null "$(atf_get_srcdir)/d_tabends.in" + + atf_check -o file:$(atf_get_srcdir)/d_tabends_c.out -s eq:1 \ + sdiff -w19 "$(atf_get_srcdir)/d_tabends.in" /dev/null +} + +atf_test_case merge +merge_head() +{ + atf_set "descr" "Checks interactive merging" +} +merge_body() +{ + merge_tail="-o merge.out $(atf_get_srcdir)/d_input1 \ +$(atf_get_srcdir)/d_input2 >/dev/null ; cat merge.out" + + cp $(atf_get_srcdir)/d_input* . + + atf_check -o file:d_input1 -x "yes l | sdiff ${merge_tail}" + atf_check -o file:d_input2 -x "yes r | sdiff ${merge_tail}" + + atf_check -o file:d_input1 -x \ + "yes el | EDITOR=cat VISUAL=cat sdiff ${merge_tail}" + atf_check -o file:d_input2 -x \ + "yes er | EDITOR=cat VISUAL=cat sdiff ${merge_tail}" + + atf_check -o file:d_input1 -x "yes l | sdiff -s ${merge_tail}" + atf_check -o file:d_input2 -x "yes r | sdiff -s ${merge_tail}" + atf_check -o file:d_input1 -x "yes l | sdiff -l ${merge_tail}" + atf_check -o file:d_input2 -x "yes r | sdiff -l ${merge_tail}" + atf_check -o file:d_input1 -x "yes l | sdiff -ls ${merge_tail}" + atf_check -o file:d_input2 -x "yes r | sdiff -ls ${merge_tail}" + + atf_check -o file:d_input1 -x "{ while :; do echo s; echo l; \ +echo v; echo l; done; } | sdiff ${merge_tail}" + + atf_check -o file:d_input2 -x "{ while :; do echo s; echo r; \ +echo v; echo r; done; } | sdiff ${merge_tail}" +} + +atf_test_case same +same_head() +{ + atf_set "descr" "Checks comparing file with itself" +} +same_body() +{ + atf_check -o file:$(atf_get_srcdir)/d_same.out \ + sdiff "$(atf_get_srcdir)/d_input1" "$(atf_get_srcdir)/d_input1" +} + +atf_test_case oneline +oneline_head() +{ + atf_set "descr" "Checks comparing one-line files" +} +oneline_body() +{ + atf_check -o file:$(atf_get_srcdir)/d_oneline_a.out -s eq:1 \ + sdiff /dev/null "$(atf_get_srcdir)/d_oneline.in" + + atf_check -o file:$(atf_get_srcdir)/d_oneline_b.out -s eq:1 \ + sdiff "$(atf_get_srcdir)/d_oneline.in" /dev/null +} + +atf_test_case dot +dot_head() +{ + atf_set "descr" "Checks comparing with file containing only one character" +} +dot_body() +{ + echo ". <" > expout + atf_check -o file:expout -s eq:1 sdiff "$(atf_get_srcdir)/d_dot.in" /dev/null + + echo " > ." > expout + atf_check -o file:expout -s eq:1 sdiff /dev/null "$(atf_get_srcdir)/d_dot.in" +} + +atf_test_case stdin +stdin_head() +{ + atf_set "descr" "Checks reading data from stdin" +} +stdin_body() +{ + echo " > stdin" > expout + atf_check -o file:expout -s eq:1 -x \ + "echo stdin | sdiff /dev/null /dev/stdin" + + echo "stdin <" > expout + atf_check -o file:expout -s eq:1 -x \ + "echo stdin | sdiff /dev/stdin /dev/null" +} + +atf_test_case short +short_head() +{ + atf_set "descr" "Checks premature stop of merging" +} +short_body() +{ + atf_check -o file:$(atf_get_srcdir)/d_short.out -x \ + "printf \"r\\nl\\nr\\nl\" | sdiff -o merge.out $(atf_get_srcdir)/d_input1 \ +$(atf_get_srcdir)/d_input2 >/dev/null ; cat merge.out" +} + +atf_init_test_cases() +{ + atf_add_test_case flags + atf_add_test_case iflags + atf_add_test_case tabs + atf_add_test_case tabends + atf_add_test_case merge + atf_add_test_case same + atf_add_test_case oneline + atf_add_test_case dot + atf_add_test_case stdin + atf_add_test_case short +} diff --git a/contrib/netbsd-tests/usr.bin/sed/d_c2048.in b/contrib/netbsd-tests/usr.bin/sed/d_c2048.in new file mode 100644 index 0000000..96ea71e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sed/d_c2048.in @@ -0,0 +1 @@ +s/1/abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabc\/defghij/ diff --git a/contrib/netbsd-tests/usr.bin/sed/t_sed.sh b/contrib/netbsd-tests/usr.bin/sed/t_sed.sh new file mode 100755 index 0000000..c97a998 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sed/t_sed.sh @@ -0,0 +1,142 @@ +# $NetBSD: t_sed.sh,v 1.6 2016/04/05 00:48:53 christos Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen and David A. Holland. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case c2048 +c2048_head() { + atf_set "descr" "Test that sed(1) does not fail when the " \ + "2048'th character is a backslash (PR bin/25899)" +} + +c2048_body() { + + atf_check -s exit:0 -o inline:'foo\n' -e empty \ + -x "echo foo | sed -f $(atf_get_srcdir)/d_c2048.in" +} + +atf_test_case emptybackref +emptybackref_head() { + atf_set "descr" "Test that sed(1) handles " \ + "empty back references (PR bin/28126)" +} + +emptybackref_body() { + + atf_check -o inline:"foo1bar1\n" \ + -x "echo foo1bar1 | sed -ne '/foo\(.*\)bar\1/p'" + + atf_expect_fail "PR bin/28126" + + atf_check -o inline:"foobar\n" \ + -x "echo foobar | sed -ne '/foo\(.*\)bar\1/p'" +} + +atf_test_case longlines +longlines_head() { + atf_set "descr" "Test that sed(1) handles " \ + "long lines correctly (PR bin/42261)" +} + +longlines_body() { + + str=$(awk 'BEGIN {while(x<2043){printf "x";x++}}') + echo $str > input + + atf_check -o save:output -x "echo x | sed s,x,${str},g" + atf_check -s exit:0 -o empty -e empty -x "diff input output" +} + +atf_test_case rangeselection +rangeselection_head() { + atf_set "descr" "Test that sed(1) handles " \ + "range selection correctly" +} + +rangeselection_body() { + # basic cases + atf_check -o inline:"D\n" \ + -x "printf 'A\nB\nC\nD\n' | sed '1,3d'" + atf_check -o inline:"A\n" \ + -x "printf 'A\nB\nC\nD\n' | sed '2,4d'" + # two nonoverlapping ranges + atf_check -o inline:"C\n" \ + -x "printf 'A\nB\nC\nD\nE\n' | sed '1,2d;4,5d'" + # overlapping ranges; the first prevents the second from being entered + atf_check -o inline:"D\nE\n" \ + -x "printf 'A\nB\nC\nD\nE\n' | sed '1,3d;3,5d'" + # the 'n' command can also prevent ranges from being entered + atf_check -o inline:"B\nB\nC\nD\n" \ + -x "printf 'A\nB\nC\nD\n' | sed '1,3s/A/B/;1,3n;1,3s/B/C/'" + atf_check -o inline:"B\nC\nC\nD\n" \ + -x "printf 'A\nB\nC\nD\n' | sed '1,3s/A/B/;1,3n;2,3s/B/C/'" + + # basic cases using regexps + atf_check -o inline:"D\n" \ + -x "printf 'A\nB\nC\nD\n' | sed '/A/,/C/d'" + atf_check -o inline:"A\n" \ + -x "printf 'A\nB\nC\nD\n' | sed '/B/,/D/d'" + # two nonoverlapping ranges + atf_check -o inline:"C\n" \ + -x "printf 'A\nB\nC\nD\nE\n' | sed '/A/,/B/d;/D/,/E/d'" + # two overlapping ranges; the first blocks the second as above + atf_check -o inline:"D\nE\n" \ + -x "printf 'A\nB\nC\nD\nE\n' | sed '/A/,/C/d;/C/,/E/d'" + # the 'n' command makes some lines invisible to downstreap regexps + atf_check -o inline:"B\nC\nC\nD\n" \ + -x "printf 'A\nB\nC\nD\n' | sed '/A/,/C/s/A/B/;1,3n;/B/,/C/s/B/C/'" + + # a range ends at the *first* matching end line + atf_check -o inline:"D\nC\n" \ + -x "printf 'A\nB\nC\nD\nC\n' | sed '/A/,/C/d'" + # another matching start line within the range has no effect + atf_check -o inline:"D\nC\n" \ + -x "printf 'A\nB\nA\nC\nD\nC\n' | sed '/A/,/C/d'" +} + +atf_test_case preserve_leading_ws_ia +preserve_leading_ws_ia_head() { + atf_set "descr" "Test that sed(1) preserves leading whitespace " \ + "in insert and append (PR bin/49872)" +} + +preserve_leading_ws_ia_body() { + atf_check -o inline:" 1 2 3\n4 5 6\n 7 8 9\n\n" \ + -x 'echo | sed -e "/^$/i\\ + 1 2 3\\ +4 5 6\\ + 7 8 9"' +} + +atf_init_test_cases() { + atf_add_test_case c2048 + atf_add_test_case emptybackref + atf_add_test_case longlines + atf_add_test_case rangeselection + atf_add_test_case preserve_leading_ws_ia +} diff --git a/contrib/netbsd-tests/usr.bin/shmif_dumpbus/d_pcap.out.bz2.uue b/contrib/netbsd-tests/usr.bin/shmif_dumpbus/d_pcap.out.bz2.uue new file mode 100644 index 0000000..5bc3348 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/shmif_dumpbus/d_pcap.out.bz2.uue @@ -0,0 +1,104 @@ +begin 644 d_pcap.out.bz2 +M0EIH.3%!62936=O8'&4!%NW?@$`00`5_\0@B0``.Y_X@8"=^\@0```````!P +M```````![XY0O$\'N'"@P'!M=O2E=5*>#>[0M50X0`Q@V@,$-!@@$%T!A:`P +MNATWD`,83$T&",0R,)AE/4?O1O52E*@P`$`820U`]4JH-#(#0-`)/5*JFU,: +MAIDQ--,`("DJ$*>E&F@!B:9'J>H%0J0>BI0``:`#P[E![R+ZY%2,<&JMJ-E3 +M46V)*F;;EK75-K&QM&I2K*&T&T6+/K6_NM*C]*2HP@P@TB)E$3A/FJ+(T01D +MEE3)*^*HLJRIC"2U2*M!2L$O=47PI1'PJ+)#2".()^T@)^44*>9`3@D/Q2`G +MVD!-(%K\?\`````````````````````````````````!`D````D````````` +M`````````````````````````````)"```2$```````````````````````` +M````0``````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M````````````````]]]]]]]]]]]]]]]]\]_U>^N]_A_'^7[OYZ?8#!^`0.`X +M-W=&9F```````]]`-/L!@_`)))``````````*?;[]``````````````````` +M````````````````````````#P``!;;;;0```'./'CQX\ +M>/'CQX\]]/ODW8-=SN^=SF_;]WWM/UWKN][\SQTV<,++++++9E55"JRD964C +M*RD964C*RD964C*RD964C*RD969F4C*RF5F:2222222ZZZ2222222222ZZZ2 +M222155555569E5ZA"1F835JZZ2222222_2ZZ2222222222ZZZ2222222222Z +MZZ2222222222ZZZ22225555557)NPDA8BUYY[\["YG,W,XZ +M0ZI3(:35+77/7,ERN5RNJ#J*U!J646HJIJB32D)4$%2$(L$/23K?/G?/O?.[ +MWWI()MWWWWWWSN]]Z$D?"0.)(_CSGOG+V]`#ODDD@``!(+:M@MX%L@MX%L%M +M@MX%L@MX%L%M@MX%L@MX%L%M@MX%L%M@;NZ```=MMJ2#I))T=_.][WO3=W=U +MX\[[50XD`D),$@##G.6\;VXXX\MC-"@U#LAV@]U!V@Z0Z0\J.DV39-DV39-9 +M-O,<9-DV39-DV3:>9QDT'.R;)LFR;)LFDT','*'=!\0?$'U!V@X@X@X@X@X@ +MX@X@X@X@X@X@X@X@X@Y(.0.(Q$TEJ+46HM1]?9/LT,I35%FD1K8&)PC7A-DV +M3:U59-DV39%1*@^H/D#X@^H.(/J#B#B#B#B#B#B#B#B#B#B#B#B#B#D#B#B# +MB#D]/4GJ:,EB*DDTDQ@S1:AW$@(KX(2E50B555WWWO>-Z?'Q^>6QB11WO;[C +M>GU]?7EL8?S`2H!B2*$>]Z_9QZ?GQ^>6QAY)(H0;0D`"/>]>9MZ?GY^>6QF@ +M$"H$=[VWFGI]?7UY;&)'>]ON:>GU]?7EL9HH\D(H0>]Z]9MZ?GY^>6QFBCP) +M*A!:$@6"0`520``'O>MXWI^?GYY;&:*/"%0@][UZS;T_/S\\MC#P@*$%`EY] +M?7UYY\_/S,SY\^?*`/GDDDG0``$@MJV"W@6P6V"W@6R"W@6P6V"W@6R"W@6P +M6V"W@6R"W@6P6V!N[H``!O;;62#I))T=[WO>]'..MMNNDDD +MDDDDE022YG'MQQQY?M55&BB)(5EE%%%%%%%%%%%%%`"HH)) +M$O&U77222222225XR7,X]N../+]JJHT40$`66444444]1,S$9F(S,1F8C,Q% +M$DN9U\<NLS/U\^?%`/GDDDG +M>@``2"VK8+>!;!;8+>!;(+>!;!=XMW>6EL@MX%L%M@MX%L7=WEMI!;8&[N@` +M`&[VVLP=&9F7IWO>][WI;;:\[YTAPPYSE\SCXXXX\OVJJC11A\D`8(#NAWH> +M!7B#I#J#B%W1R\,1F8C,Q&9B,S$9F(666"+++!%EE@BB27W./CZ_/SR_:MKV +MKIX05#ITQ&4BJ15(JD52*I%4BJ16>>>;SKGKKSKSOK;GJVNW3P@J&4BJ15(J +MD52*I%4BJ15(Z>>>;SKKXXX_/+]JJT80$!0@LH$44"**$S$S$S$S$S$S$Z>G +MIZ7,Z^../SR_:JM&$!`4(+."2+!%F)F)F)F)F)F)F)F!&B27O.OCCC\\OVJK +M1A`0%""R@3,3,3,3.1)<$X8F8110!0R27,X]N./SR_:JM$!`4(,));W +MO[[[[WN^][WO>UK6M:^=[T``$@MJT6V`06V"W@6P6V"W@6R"W@6P6V"W@6R" +MW@6P6V"W@6R!N[H``!N[VUF#O3-[WWL]))))/=[WO>^)"F)<$N4`@54(21AQ +M\OF<<<WQ]<>7[55H@( +M"A!A)+F<>W'''E^U5:(D`4(,))7[55H@("A!A)+F<>W'''E^U5<0`D);(A!0@ +M9)JYG'MQQQY?M56B"`H0822YG'MQQQY?M56B"`H0822YG'MQQQY?M5NST0R, +MHB>"4O?!D49#(HT&JHM6R;)LFR;)LF!-!H49#(H]\^O///?KSZ^O//KSG+EO +MZ_7Z_0`222=[WH``,P!;!;8+>!;(+>!;!;8+>!;(+>!;!;8+>!;(+>!;!;8+ +M>!;!6[O```#=W>UF#O>LS,MO>R2223O>][WQZ%6`@3$MC-YN]9MQQSKTZYX\ +M]MNS[X,AW0[ITARAR@M"+#0DBA*B27,V]OCZX\OVJK0`H("@P!"%0E1)+F<> +MW'''E^U5:(D!0@P^^^^O[.OC^?S^>7-56CY`%"##[[Z_L^?7Q_/Y_/+FJK1\ +M(H08???7]GSZ^/Y_/YY7-56C2`$A*A!A)+F1]?'UQQY +M7-5221H$:$D"PDES(^OKZYSO/S[[/?9YY]>>^R]Z +M*!)))WO>@`!(`$%M@MX%L%M@MX%L@MX%L%M@MX%L@MX%L%M@MX%L@MX%L%;N +M\```-W=WK,'>][F9EM[WLDDDG>][WOCT*X`A"T)5RJ97'?,X^..../+FJK0( +M-"`L0%B`L0%"#"27,CZ^/KCCRYJJT)6@$J*`0*B@$"HH0@4DN9'Q\<<<>7-5 +M6BP$"IA%F$6819A%F"F`HDES(^/CCCCRYJJX`(%L1B`$A*A%$DO61\?''''E +MS55H$622YD?'QQQQYLCX^.../+F +MJKAL$822]9'Q\<<<>7-57#8!A)+UD?'QQQQY]]GON^>YF3.]Z%`DDD[WO0`` +MD`""VP6\"V"VP6\"V06\"V"VP6\"V06\"V"VP6\"V"VP""MW>```&[N[UF#O +M>]S,RV][WO>][WL[WO>]\256"2!8>0`D)=[5;*[V^9Q]W''''ES55PI"LDEZR/;CCCCRYJJX4"+))>LCVXXXX\N:J +MN%`BR27K(]N.../+FJI"*))>>_7UYYF9,^?/GP4"223YWO0``D`6\"V"VP6\"V06\"V"VP6\"V06 +M\"V"VP6\"V06\"V"VP6\!NZ```/-W=WK,'>][F9EM[WO>][))WO>][XDJK.& +M'.WQ]?S^>7-52$422 +MYD>W''''ES54A%$DN9'MQQQQY7-52$422YD>W''''ES5 +M4A%$DN9'MQQQQY][W +MM:UK6I)/>\``D`6\"V"VP6\"V06\"V"VP6\"V06\"V"VP6\"V06\"V"VP6\! +MNZ```9F9G;F6][WOR2223O>][WQ)56<.B2&=[V^YQ]<WQ]<<>7-57`$@*!%DDO61[<<<<>7-52$ +M422YD>W''''ES55P2H$622]9'MQQQQY7-57!*@19) +M+UD>W''''ES54A%$DN9'MQQQY<)JJ0BB27,CVXXX\OSJD(H][U^SSV_/S\\O +MSJDE8D@5)-XY))KWO>][WO:UK6M3WO>]X`!(+:M@$%M@MX%L%M@MX%L@MX%L +M%M@MX%L@MX%L%M@MX%L@MX#=T```[N[I(.DDF[T>][TD[WO>]Z>(0X67YU2ZJR'9#LAYB/"'2'2&1L>_7[./;X^OSR_.J0BCWO7[//;\_/SR_ +M.J0BCWO7[//;\_/SR_.J27ZT`)"5"LDES(]N../+\ZI"*/>]?L\]OS\_/+\Z +MI!`!`J"BBBBBBBBBR27,CXXXX^MWZM^I(2O%555555553IYY[N9'MQQQY?G5 +M(11[WK]GGM^?GYY?G5(@"0%!0E10E10E0%DDN9'MQQQYQY=2JZJ=2"-46J<$ +M$<=36D42T5%8M93,VIM:10-"E6)36EEEE9:T@)\9`3UD!/"J$GK0$X)#TD!/]D!/8D.$ +<@)V2`F0$]$!/:0$]4!/?0$_\7````````M5ZU2M8;`7KK33;500',-455U@\!@/ +M.T7K$JH^L!YM3K6M5L$^!>)T:*I:U*:`-HT]1ZC3GMVDMDD^>,22V26SY_K_%DLD +MED))+)(MMLMP222663_4DLE1"$6RR62?Y6VV72RVR6S5DDMEJV1))9*B$(0B +M(0A"$(LD22V2(EI+26K;^VVR6623.N_?K_&_NIK6M`;F`,8P`;[@``#8```` +M`````````````````````````````9S^O]0&Y@8DD`````N[QB;`$D@2JJ@) +M550$JJHDD```````"20````"20````"20````"20````$D@````$D@````$D +M@````&))`````)F0````&,8`````22`````22`````22`````22`````22`` +M```22`````22`````22`````22`````22`````22`````22`````22`````2 +M2`````22`````;[@```$D@````&V4,W!,R)4VMG$B0NIF[D,YDDDDDDDDDR)), +MU4WWSF7)))G.Y+8QE4J9EW)))))))))))))))))+N[N[DDD +MDDDDDDDDEW=W3.,IMOVUK6@`J#H!V*``)@(`()@`% +M`.P!9R``*@Z`!(`#D`L`03``3`0`+.0`"@'8`)``!T%0`.0"P``J#H``'8H` +M``LY```$@```3`0``*@Z``Y`+``%`.Y``````````````````"0````````` +M````````````````#L4`````````````````````````!4'0```````````` +M````````````!R`6`````````````````````````2`````````````````` +M``2``````````````````````````()@`````````````_\`%P`````````# +MH*@````````````````````````"8"`````````````````````````$@``` +M``````````````````````!9R`````````````````````````!T%0`````` +M````````````!V*``````````````````````````J#H```````````````` +M```7`%P```.0"P`````````03``*''''$I<>\2EQ*4I<2E[+B4I2XG;Q99>N +MV6V69FM26W5MMO:2U?-NK,3S;EEN[9;$LD66)+9$DM;MW;NW4LEW9+4DDJV5 +M)));9N2VZSGGSY[>>_7361`$0*K,S,VV9K(``@R`B``?[_SJ>:U_7],TKGOO +MK82220```````````````$DDD`&`````````````````````````5\\KG%-6 +MJ("[N[MD"6=1=8-^TK/9E?'6*[QA".*KS7+Z;Q]F)>_>@`.@J``#MKKKJM[Q +M>]P``````````````````````"8"`````````````M+J4N.)2E+K[YXQGV_O +MFM9SG,>UA/$[?(M$1$>^@`*2EQQ*2=][679+"6$L*O4L)82PJ6=[9)-VR2;E +MDCKKK7/`#G,`-Y@!K,`-9@!K,!LWF`&^V`&\P`YS`#MO6@#>8`:S!R&\P#NX +MS`#>8`:S`#68`:S`#68V!K>M!R-Y@``&9@``&9@`T`:S#L``-9@!K,`-9@`` +M-:S``P`@``!```"`8(`'&```9F```9F``,"`%ETEDRWN,S```,S```,S`#,L +M)WDF)863#,P`[@#68`<9@!K,```S,&P`.[G,```S,```S,`.,P;#>8'<`!K, +M```S,```S-`'.8=@;[:`)QF`&LP`UF`&LP`UF`&LP`UF`.^\P`WF`&LP`33` +M#4`&LP`0`9F`"`#,P`0`9F`"`#>M:`$-@:S`!`!F8`("XLQ9BS$N+,68LQ9B +MS%F9;"7-@$UF`&LPMT[VIM9EFDRUI+DFERW62S268DG$XWE[HDX28+IEBU;F +M6XDN+)ELQ,L``<:U+-6KB3+5KC2S5JWMV2Y:MS+M:```S,``-Z(0L;RSG68`:S-@-Y@!O,` +M-9@!K,`-9@-F\P`WS@!N9@!K,`-9@!SF`&LP8'`XS`#OF`&LP`UF`&LP`UFP#>88#C>M`"`#,P`0`9F`-H`-9FP&9 +M@!K,`-9@!-9@!K,!AK,`)@`0`0`$`$`!`P,S`*68LQ9BS%F,DG<:S`"`!F8` +M;8`-9@!%F)WNEFEF+,68LUK,`(]_O;>SS9;))+/>M))9+Z9Y]_LWM.F)^,3O +M_U9+))9*=-3O/&=5I[;W$:UY[Y$1$?:``4ZK74Y@#`##$;`#`-[R@'>2(J(( +MC-/6,HAFA[>IJ\YJQ%^\>.V/8B(BP`!UY6O]92EQQ.>JT&0"MAM`"XT(H`8: +MD6]X!].G%4S(EXM$1$?``$O:4S;7'''$JUU>E.>>YSS.>N9\IS3GI5UGU=R. +M7QY`B``!!S6NORGJ/3,YWVQM=\X\B(B/?0`%)2EQ*7'U:^SGN7''$I<=4 +MIF87(BH!+".]YM1#'U^_?M"/+RE65C?)EL.'1$2-:``12G/.O.ZUQ.>:TISS +MG%*9G.T4ISSWY#O9J>:U^U^UK0CA]5\J6B,K,NQ=JN>IPY=$2(]N``I++KK? +M'$N)?4IJU*<\WU2A2E;JUC5*1S/G4Y]]>=:IYYNM][QC&8B(C>@`%-$1>UK] +M^_4(K0C8![HCX`@`WM."/@#7=MWG+Z*=:7[\MYYY]K[61$1'OH +M`"DJ2M00(JTUK2J^]Z]R:[V]Z5=>J]R<0KO7$`0"4N)2]Q?[KWV_T1$1JX`# +MVE-2XE*6:4U.W([VX!@`O!'`!^".`';QFA6=VYC0GK:]O;B +M.KU,/;N*.3374"N<;33J2)FO2I7#>)[$5$35W?;MK&7>YW?2IQ2>]N!Y[M=Y +MU#:&PF,&Q6WEHUIQ9RJ;(NKN[2*)*CH]K&UO??O=[VV>2TZYK.-NS[S,;WSD +M^]A_@$"(`$XDOU/5OM9U/T"`""8``+TI2][WO>]`.P``````````````!:UK +M6M:U@``````!!,``````````#N4I<<2E*THYK'VKVO]GS&-:SFKZ=?+=^WTM +MJUK6LN``I\\\<9]LDG,MM_)9)Q+).)+)-2\6V67^;WDL_2SOUF]Y;%50@Z;6^LB"UE'Q`%=YKD>C'7CWWWLUS>][W/V][WO> +M][9FQ[N,+\$`!0"QL0@JEO=0@^-K*+/N,UK+9F9)/Y.O6<<9;,SOJ6=V]Y/J +M2?HB#7[0/W%AH'#?)6OIF/?>N[WS9MNW;T/BJJKVF9F9F9F9F8(B`(;][G.K +M?!`$!0#\<85$^7W^>_F^W;+9F9)M+W;WDL_FM9+#,_-6S6L'Q0=*?CC"H@55 +M'"`-=XZZ;XOK[V(WUH^WO>]_OF9F9F9F9F]SN,+\@1$0H!\;W4(-FUE"#XZU +MEG\L^_,XXRV9GG4LZ;WELS,DGM._7K7/.3X@*4%E4#XA)?NVCO.PV>[^_5UZ +M9W?Z?TS:^N*_>=[B^;6M:VM``(YO6L_W''$N.9<2I22S]]YO>2S[ +MYS>_FK9K62SYXS>_[5LUK)](`T;W4!RB6LH0_.]Y]EDBR?6]Y+/O;-[RV9F2SQWS>\MF9K4L]]\XXR?5DUK)/J7 +M6O6M:RV9F2?=Z_$D,;%\SEW@9Z_=NHB*SZ[TFKV5=3SM:JJK5,S,S,S,S-?E +M[K\`@`!0"C>ZA!]G];&%"#XUK)^I)X;W]U;-:R?4D]-[R3RMUK)9RUI0.%$M +M90GQ`416X;F\=^^F^7B)WO>]U\S,S,W777776>&L^R6VI9K62S[X\:XXR?RR +M:U[U+/;>\GU9-:R6?C6LGU9-:R3ZE_F]Y/">T\+HS#7Z-ZT]$\ESYSA`3V5F +M1$76?7Z_!$1`4`HWNH0*2OK4L_6]Y+/UK +M6?4LUK)\23LWO)/"W6LE_@$`WNH0;-K*$^('7XV\[7O?FC[Z&]^WO>]_?F;K +MKKKKKKKKKKKQO>?9+)$LUKYJ6=V]Y;,SYJ6>V]Y/JW^3>\D^I?QO>6S,R6/7 +M;6]Y+W6:T&M:^WJ^=GY/JX=2B<>VN'?[[/7=]NNC>/C@@ZM31+:9X1X[2G<7 +MB6_<@^#'.=FC>$F6.3,Z>;NJ>JS+NTAYH7F,X:]CIPB<[7--B"T* +MQ16&<5*F?*R6N(BIS,NR:1JN]$BG.A&8Q)SJMA-LVXQPU)T57D6YS,DS0<1& +MN=[:'KR>ZNCW0*JJJ@`````````````````````````````````````````` +M!UIYMFF[7``.<\9S*S\YXKYU=-7SGO3HUKKKFG.<,=_93.:ZU?3%`.P`2``! +M>E*7O>][W``!(`````````````````````````*`=@````"UK6M:UK"DN..) +M2XM*<_-/+34=>,R[N]\!=E(\K%N%55679F9F9F9F8Q[O>?;9).=;9)S +M99=PEA+"6$L)8)$6R;MDDYEF9DDVGWWG'&2>ENM9+\28UF23XNM9+/36LDG\ +MNM9+.NN^N.)RXE^YI2][]^9F9F9F;KKJ>-:S[)9(EFM9+.S6LE]K-:R3:3ZG?YSISDL^M:R6?/> +MM;S)M)/K>\EG;MF]Y+/K6@U^UQ/IC.^WL^\>ZF'?[[WKNQUO3H4>RG5558AF +M9F9F9F9J[>Z_`(`"E%$O=0GH4#YO6UI0)]76LEGK]S>\MF9DL_?.;WDL^M:R +M6>?NM;S+Q*==9]DLD6>UF]Y)/J6]Y+/#6LDGXNM9+/?] +MF]Y)]2_&]Y+/S>;WDL^M:R6??N;WELS.J2XUS*5KXOC'U.Y^]_OU_OOUK6M; +M[8`"MZUG]DLD3XOI9QQDD^IK^S-Y+/K6LEGKSF]Y;,S)^I)V[9QPR>$D^M;R +M6>LS6?=6S6LEG]Z]<^ZYPZ)\L<6GEZ^]Z[:D[6U(_7+JJJL0S,S-UUUUUUUU +MXWO/LEDBSA/Q/OG.W;)9]\YO>6S,R?M9\!$'MB/T$1.(CC$1``,W9^GC]I=5 +MB_'=V^K6M:V?P`#&O>NOTI<2E*E*8G]6==?JUK;VI%\(BB$1.(C!D1?(1$]\ +M2#5P[:%EQV(^>ZSZ[XZ"T\*^G"Y4$4+;O<"G'M>TZ]Q"6J +M[+4]S>78KIYWBQ2'SJ(EMUZ-'Q7NX0S2#RS?BV1(U]2N$MA:]R::'S+R[T:O +MJ72>XZ)R5=.@_'2'S(?E]X<X````!T%0```````````````````````#H*@`````ZEQQ:4N..+%$` +M1`2@`"#V[8W7NN]5$>_3,69_.T^>MQO>][V[LS,S,S,S-8]YF?/>][]:UK[UO9?"(_21$PB.<6>\['V#- +ME?UM;*JJM^9F9F9FUK6N/55]VV_-MMNZJOGBJKZ/8^C[=57H:E50`'WU\GHL +M7'1R5/LM7^[41][+N[UW@.OH[BJJV:``2O2G[CB4I2I2D>5K7]2E-?JUKFE* +M?N1$``/61$RD1?(WHY!=].^?+5T]>5556^9F9FUK6M:U[SZSG[MM^;;;=550 +M?1][X9SC?&^+'H?;$0^$16X[UG5X8.LE8F/=?3%7]=QVB[RH;TQ>UK6LR``B +M]:_I2XE*5*4WFM:_D1&(C]A$7PB+LBP_S<<$/U^NV^ +M>YOUVP&@0T;NQ:UK6^^``5EQ*4N.)<<3O7]Q+B4J4IO%'HS'XB+.D1``0(BH +MB/T]]SG'^(B/XJ5*%D3[]GWWW5K6M;]D``G>N_TN)2E;KKK]6M:[G2B"(WA$ +M7T$1?"(WN"(0`.KWC\5\92^YQ:^OYHC]C.\Y[\[K'5>J[[UBUK6M]\``SY6O +MZ7$I2_49GOP@(`&41$RD1>82V0`'T2)GDD10V>E;;.?T7Q?&&;6M:W[0`#N= +MZ_I<2E+5:U_9SUT?A$?MV1"``Q$1?"(LA$3"(T_7\VFL/$ZQZUAW]]?KL5$U +ME,HWKB=5FJL,YG9PJ.Y*,<[N70^<5%[2BW*RD>9R(F\NY$]JY:O.)=@A&_>'4RZET +M>=J.K-0RVC]_/KGGGGOW[]3\MLMO^RRPLL++"6PLL++"RPLL);"RPLL++"V0 +M0`0`(@`@`(`(`"`DD++"6P`"`"``@`@`(`(`MI+866%EA9866$MA9866%EA9 +M+)8$`"`!``@`4`(`$`"`!``@`0`(`$`"RVR%EA9866$MA9866%EA982V%EA9 +M866%EA+866%EA9866$MA9824"`!0"VVR2%`"`!``@`0`(`$`MMH`0`(`$`"` +M!``@!?I]29N536;GOM^_902222``>@`#T``````````"222`#``````````` +M``````````````3G,[U,;FJB``PO'?/UIY?&N^O.>/'GDU4GG75K==??=YC- +MI]G7<>_#L4``*`=@/U*4O>][WN```````!R`6``````````````````````` +M#D`L``*2E+B4N#U^_)IN9!NV9'8B\N[M]#/>5BW*JJK5,S,S-UUUUUUQ,\;_ +MVLDFI9)Q)9)YEF[;+J62?O;.U=:ZSG/0_3JMJKL255?18@\_MZSG/OF*8OWO4>Q$0Q@`!KVGN?OY^;;;?:JOOC6,8@]LYSSFI%X1'U$1>$1<1$`!5DS/PB/A:+88D^X?&7S_7RQ[[O6=YSWYYBL? +M8OG<9B(B'WP`%ISOCH>Y55R+'7=57P=COOY+N\8Q/.N;XVZYB^<;[QB\1$1] +MK8`'VI^UWNM:RG.\STI91$HB(F>MF9F9F9F:]N/A$6]!F8`%8YF8`'>D1>$1][1$0`#6LWWR +M4'9[R%!/9V+J9FL]=Z,M5T9C.I*FF/UDX;$LMG.;9,;5\Z/)ZNIMPY3B9]FZ +MGO%1)>Z/EM9SH%G(``=!4!N +ME*7O>][W``````````'8H````````````````````````$$P=2XXM;GGZT^K +M:SY[[G>,?:SGVL7E];.-?6[B(C'F@`'-Z>ZEDFY+)-2R3)9)_.-?O6][S,[? +MF][^:UKWJ:'O?&9]HB+PB,=D>QA^JREVCB(B5[S,S,S,S,U;4]#V$1P2]ES/HN:]=WQH;?)?R- +MQ$1.W;,S,VM:UK3?R]=U5?!C&.O>U570^<55:&M7G.>RE?*_46MYY[K3&/>X +MB(]SH`"DISO.*4I]HS,Z$1SEF9@`1<&9Y!$2U9F8`":<"EIGO>>3,S*=_5?K +MNQ6+?LJ<>E^(B)%VS,S,S,S,.NL>JX'S1Z^>/''>+^Q +MOGZ-XQ]U$1&][``I*T[US2E.OJUK.<_;(B'V$139$0`"(1%@B*S`9`KQN2%J +M_EY=SC&]YWG.>O>\TK[B^XCJ(B#X`"DM3\K.$1["F9N( +MCZ8OHM.S/W7Y7G\^9[+N`B@IL[$+V(-.TB=XR0:<%8GJ\F2?4PD"Y<:4YSF5 +M5=R,BJS+MJ79436'::,N3WQ$XS-&C=Y2V?F&,Q2"[X5J!Z:^MACE553;Y-Y= +MN!S>#+)IB,\[Q2J:M5&_>]?'?N/,E'ON@5555` +M`````````````!X``))))`````````````````````````8OG-]ZO&[7``/I +MC/R]\]\9>--VG==>;XIKO6>:J\>QC,N:X^=>XO@!(``!9R`W2E+WO>][@``` +M`````````D```````````````````````!0K+GB4I2XXU^_*N]JRY?4[62\3 +MF7:J/"=6/,DT1$KO69F;KKKKKKK4]^M?G%R62/R62(O5F)9(6%J6V3O))"V+ +M99N64DCUG.MZUK,SKO^>>UXO7UC1$18[UK6 +MM:UK6M:;7IYS\'/-570\CH>QH=<(B81'7DR/!/<4",>/ZIAW][WKLSU%P)'[ +M*.(B,XP`!26O:>];S6M>OJUK.<[TI2M*4M%2+&(BP="(`$H_F;R/[9D/J>%D +MD1$O/,S,S-K6M:?F_EV.=]53V.1V.^*JL8QGS55YU54.%RE(^B9XO>/C^C,S +MUV"'OM.2W[*)$1%EV9F9F9F9AT`=``#%(B``OQ>V9X(BW2(@`/57.^^U*4O? +M'6\5OJ4<^YWU[[Y6(B-[T`!26)N7A$4V(AX1'HB(`%>Y/.<[XB+U$1``)+]6 +M^Q$+SF.C7%1&9Z[L]K756_8A(B)789F9F9F9M-O&/-=CBYG.<8QMW=57L=_* +MJO(X&AUZ\^-6K76,]TUG&+TB(C.O@`-\^4G.>?*UKN@CYB(L$1X(B`!YL,S\ +M(C4/WH0\=BD*^P]3Y]?9WG/L[>8K3NG6_O:1$1CSP`#KF]/TI2XE(1'U$18( +MC]8$0``91$2B(S\G>BVZ]_7]=M3UC'WM'QT9FY400\ +M-WR*3B$,4?6+J12)WLE9\0Z5LG&A\S,N^.\MO1)E.M;0YE72J0P]P``````````````%0=````````````` +M````````=5E:6]VO'>=^XQO7WV<,S\(C\ +M>+].Y+.<.?O0D2"(B>?S,S,S,S,U;<0`/01%X1&ND1``>9C,_(1%3>/N^<`` +MOJ=@ZDVZES:O4^F:SUV`AQ"EO'3;1$1KMF9F9F9F;F^C@B-[NS,G$1];F9^$ +M16B(@`#@B)G*M9]>^Q3ZSS6M,8QJ41$9]T`!SS>>:4I:@C0B-T1$F$1,(B`! +ME09FHB+-Z$C#?J&]>NV_,_9WG.>NHZPW=]$3B/,Y(`%.;TW2E*:"C,9HB*#< +MS-A$54B+PB,"(^4B*YXPTOLGW/%$3Y$04]&,W&9F9F9EWT?"(UBG[?.``6(B +M0B*>PS,`"1$1$15%=T*C?N<\U>OW9CV9=W`5^M;O%-WUF(B*W\R=`#S4Y>U_ +M<<2EQ2E/U,4`@L1%.D11XB)E(B``Q"(OA$?ES@SV62#^^F<6^B(C[/?XH`.N +M;TW*4N)2I2F\UK7.ZUK*$Z!11`\)7J9V_%3M37(Q$)\=XYSO:2'X]'U`XDY52[W5Y +M=G&J%\/N=7CH35"G"I1&S.6&?%6$R$T\KR;@JWW7RL]WK'KUOT]V$DDD```` +M```````````!=W=W8`Q@````````````````````````.]_/-LTW:X`#$SY7 +MS$\TSSS,\8WEBY>N^<>8O&>^KL=T9I&?)^V]`"8"``$P;I2E[VO>]P`````` +M```````````2```````````````````*2M*'?N+]M?>XQC.LYG[;-<7C77WL +M1$'H<@&N?*;2ENI"6$L+,69?%)82PE@NEKJVRHLZDMF);>]EW9[+ +M;H?LE41$J(9F9F8F9F;>^A8B+"(@`9[AF>"(XQ$0`"4IF>"(E:>=-XQ6.I^_ +M6\O[N(B-[V`=!3CCCF])SG\.QW[UG.<8QQZJJT.O''K4DZ'Q?B^>Z==Z]QGS +MR^=YWO.?9Y]ZSAUO6?8B(8N`$%9<<`Z4;\(6B$5@"`"`%]\1``2`<`$1':%K +M$D,*(5T1$F\9F9F9F9E8M?OU.>4(ZWO>\@1XG),\5B+>W@1QA'E'IN-4D7># +M>.SO4>G/>NVI#I[=;SB(B(>^@`.[UC=*>SGB<\\YI/GGO%*:G.T4INHGGHB$%-_8QC +M?F_L[SG/?D2KZC&XM$1$>^>``9KY6@#U".]Y7B+P!WOB+H`P`H!I^/ +M[WIG$B(C&=@`2O/GGN<_?J4UO5:^SG]SC-:?>;K5C$?`!\29Z31S$>ZB(CWO +M>NP03L7U^_?M5Q]\>LM.,5OV>'Q^]PWQ.%U]P```````````````````!V*````````````````6E/>8OW;.O<>[WG. +M<_?>_>17W6+Q$1'E\@`=WI7CB59<2E*\K)-2WB6$L)82PEA+"6%6=["6+>)8 +ML)82PLB\2$L)82ZWK5(7O9XS``0`WOF61;VB".]RGG?RGD*<9DXU$1$;OL`# +MG.O:;G.^*4S.>+16NYS\G/=A%?>(M['EIVH8M0CVA-=W+>BZOUV^WD6.7]"( +MB(NN`!2].>?9SWFE/OJ4YYO*U*1.=K4IJ]*:I&(]VZQO>V,>Q$1&M;``M._. +MYSM&^8Q^]:S,+6)\JE``$0(GXKG]-[DXUE_TO$YMYN+-,[>^[SG><]7G*\9KUMJ(B(M]\`!KORO,M_3IS+<@._V]ZQP'>DV&])`#O7MA[A^,R`" +M1[9']G#>NMZ^^1$1'VO@`,>4^U2FYS]G/S%*;M2F\6(G`$`$`/>G"XG']TE5 +M\Q::?1'O9=@DQP^A47W=$1$:SZ`!*+TYYYE*7'$I2W:=.>>9<<:\MB$3Q4A$ +MRJDF8M;FK6S6M[J.ZQ.*G2:O>C>X1C-F7>]CR;97Q*AX3FLMN5'"N"*^]O#+7&MCKA\8X')YL]+2(LS-N\7 +MEY=TA]I%*_Q[U3`"P/B,Q%DDX+D5,612(.S?2CADI)X7.CDIXGBAN*,$5 +M2I_WL?UG]Y]Y[SO[]]]]'WT3,S,Q$1$3(``````````````````````````` +M```````````````#K3S;--VN`!6>7$WCS6G.O-_37L7;+[MUHF?:9HS&?3L) +MLA"0A(0D(2$)%)24E)24E)24E)24E)24E)24E)24E)24E)24E)24E)24E)24 +ME)1"$A#B,/C>=\:'B?3,].N1GX>/".ECDAR^U>5$O-DSE1!%Y5*=0YH[(HX( +MX;97A$E,GFSWI(7:S+..:+;]C%]$,=>5(A1!%V +M4"QR1#*&RM$"[[L&+E+[7A&CDW(Z0Q;RC)&>*DWY8QQXFB +MG"-'N9MMU!=[01DY,$8=4]E0YN[+^)ZYS'2<^NM2<[SI.OS+[3E..LG9^KV_ +M>>*BN.\//IJ973\GU*18]ZHZ=2LD8PU[X-$6*>ZHZ:(%L*+<6CO:CA39R6(X +M4Y+V&2,\5I441TV.2C/G.]S$97A&=3JS;Q\R?/F7:>4USD +MZ?G[E]^L\IW=E]/">/W)P1)3"[L-GM*A.2&.]^U[F*>NQ%553)FTS5&>/&3P +MX3\>&U]^LGEXYR3:=WXZ3TZ8YG=8JGG+JIJ_7;C59^[ONTWJQL=:?>N_,W^9RN)T]O"< +M]LOZY=)U^?FIZ$Y3GQD\.O:H]3;9$&>*FMKUE&/_?[=K_OOOI_/,S7WTSN+K +M[X?B>'9/?K)^/Q)KMVU/C];_(KWG=Y]-3..0OJ@BS*DD6ZHOE1XL0QZ>$:.9:R45-GCWDY3PO/6>WAT +MNG"=><_._;7A./?.KSQD\)X[:CCR[N]355,KK.^^KI&&Y829/"!>ZCADN1LI +MDX==$;I02^5!(PRI)#%G7)'#C2B#%*^]'0:T.TWHBR\B:B(K+S+NS:+K-1N+ +MP=:.P$&2F3)&3@MU0Y1O*,D9A4?BCA]"Z*.9+G&UZ1ZE2YO=>D3U4SGDS+>Z +M[^BJJ9/?4&+'+*GF4,>'A&_*!A@O"%A4HR;94990QHIXX(X?:5(]5NFCFE$$ +M8*>=0Y[W-Z[/HBHGTU,SY[+0&\*((]M>$.W2D24GJCID[*&LUII]YW>O54SIUC)U0V5 +M.2/:5,GEW3K]ZU>R'Q`OM0Q +M_\UQJRS3,S'OW[]V9F?>]Z2````````````````N[N[L`8P````````````` +M```````````&9UJ>;F:F[@`&,\35WQUGC:JQ4Y5O=3K6<\\XJM8EM;U\U/+2 +M5+D'.5Q'Y,,OB%/H79':5'=1HC)3W%'#RER4DCA]N[^PY"RJ9-P7(GKV2740 +M<77922.%M:CG--7:>*JIDY6\5O"BF4#QV1[JI[JC)&>*&,!/;XY3R_>^?J>N +M^>4XXR>4VGH\9/#TDUQK4V8E6(:V[^B.N]//IJ9]<>I*.S!$E)[>PP1G7?5\ +M)T]1RDY3IZ]9X3CQ\U?QP\I^^Z9RMBY$%,]4=LN3HIC:@F"Q$$D8.O +M9]MJ[7'>JJIF.;BVJV1=E3Q&2,5%DX1XOQK;(L<:71&Z7A''[DFG9/S\X\[G +MEO\R>4XG63P_%[/**FIGFN"*#'RE1@CTJG?*'/#DH\*.&= +MJ.D4ZIBV^*,THZ1TO2/%&.NJ2/%.M.9>:[$3#^J +MIF[/%"B,85)(D\."F"'/>[LQ&8F;@8+D8ZJ0\6"D7THX>U-DV>D;.BGCPCD* +M,$?VJ`(@`1!EJ73^CWFJ*FOTR?=_:([WL7%C)2YP11K2L0TJ)O?K4\L?L +M7WYR>7IW7:=/'K/*>E]]L[/"==>;)!&2&]GS>?T\AXJ:F?7O,K2;(P9JULD0 +M;:5*I:=1CR@7.B(XHX:(%LJ-GQ3UZMPC1U*\(]"HU*-$9*+B_IYR*=WJ:J9Z +M;2?&A)8](T=D.>[7I$SFR8.#TZ,]5/$;,W[9BDD=,ER-1ZK@:+D[[X&,KTA_.7V +MGXFNV3R]1/+T\)V<[SPGEX3Q^9.R?%XXHY"TZHS[U.:]Z'>O34SHYW%40YQU +M>D3*I>X44113W%'"YT4N"-FBQ$%,''%;2C?52B-$9XJ=E1TT3O?)W$] +MB)JJF;MWGO4G==]>4X]Y)K,[,>_SQJ?K2S7;)W?%]O"$<\HT1IO62 +M;*.F3DI1MY>G'L2SUZ?>]Z:J9.=]]ZI(=WLF#@P1?JIR5'C^7?CUC?GF]S?KU[L"JJJ`````````` +M`````````````````````````````````'SRN<5WFF[7``=9RNJ2'=0Q&UZ\9/#VIKYS +MJ=/SUGA.5[.72?B]=\\N>^3LRIXCAHX*8(X7I>:499EY7NO/(B*JIGI\GL^O +MDQ/#E-^\O'YDZ3?;)\3ROMX3EQUEZ=)UY49,F2F7[8=,E*.2.G6EX1[JN1CF +MEU6:[$.\^FIGJJ3Z;#QP6.B,$4>GAZ=JJ9.2Q#4J>LHP?'/%'# +MFW""+;T<6/[FS@'WI$26>IF9RLS+M('E#\O2> +MVO>=T[O*?KV_4[\Y)Q\]Z\L>-Y.6TY3.U&_*2CG!'"^EYE0]+TC.5'3DXE4S +MFIQ#=YWL355,W"Z4!`@`]%#AYQ6*8VM'AR>RHDILY/2.>5.]49(RRI1T6,G) +M'#HCAB,6Z1F,'6BV^!J2@=-OI#:6T1$5.9EWOAI6:+>F0-0]+Y>DYG*$>E>D8PH8BY3W%'#$+LIC2ABNM3N--/:>*JIF[.8GE=(T4L9+$2ZH_5& +M2,SRR21PUY=&3!WO4;X8/8:Y>&$9$+ET;=9EK>YO+L8LZ#%E+13YQ\U=>>[TG4YNCI&R,AWS,R[D=6@C2GG;1(>D@WI#Z^.:F+F&TGG978IQIZTI +MHQYWIHD0Z1DU47>7?;0ZIC[39;0!OSG;LN[?))=141Q^0:O7\M7#,J/?GSXL +MELDMG_.[);)+8_XLELDMG_RR6R2V?\-\RRV26SBV6R2V\/Z2$`TP#_____________________________________ +M________X'+^>H!`P```````#['(&C```````(@``+7@```]````%48Z``4) +M:\Y``%``/H`!U(`#O=O=L=`=V`#2`#8#*V,E&9CM@=MUNW7=F@6LP!\````( +M(0>]Z[.^O_]5-2G +MM4#]I4_*@`#U&GO_550W_^JJH````!H]3(?^__5554(HC)30PTT#`$$W@1-( +M%/>IH](>D](](R'J``&@`#$TT:--'J-^DD#0:`(V@9!HPF()A,$S0":,>H`` +M$P#0-#]4H)40A!C`"`S$TBGJ@/4C333$-#31B:9#":::`R9,F$TPC)@!`P$T +M,FF)HTR:9#1B9)^A#)IB)Z,C$8AIHGID:9,0"-3U!*?JBJFDFIHVF)A2>$(T +M_433(`/4,T3)D::9``--```&(9,",AIDT8FAB&(`::`:-&F@`&@-!@`C1D!D +MT&$P")2:*-%/3:-!-,A,U3P3TIHFTGAH_548GZHVH>H>H_0F4]1ZAXC*:#:3 +M:GIDFU'J;4>4,Q)FIZGJ/$F)ZC;U4T]33U/4/2>4T]3TGE/4\:I^E/TIZF:3 +M]$1Y0T_2&3(GBCTTU`JI)"1C3`3U&A'HF'J8DWJ!,0C#(GIIB384S(TT$]3Q +M3?ZJ3T:GD&331B!J;0FTT,4S)D">0TU3S1HT--!,&AHWZJ-3TTQ3Q,33$:8" +M83:J9V-0K45+8@O4H`HM("H,@-N/CX^/OM]OM]C"9$$$9`4O0%!I`7(@,@(4 +M666%16%49%EE85AEDC(!($@2#)N3B3DRQ&L50D1%DS(S)2RS,SP1$1$1AAAA +MAA%$41AF9F&9E1EE&%$48888888811%$9'O&6564M9M9596[AA$1AF9F&9E1 +MAAAAAAAAD11%$41D8811%$485919E11AAAAAAAAA1AAA!%$&&%)E2``D0!18 +MJ/)(C[I5(^2HE@")5`08.-!H080(08081(08Q81818141A%A!$6D%5S@+X`P +M"(#`BI`@#$8*A&"%%*4&0:+2@R#16E!D&@"@4`08!"!")""BFKJZNKJZNKJZ +MNKJZNKJZNKJZNKJZNKZ1O>][WO>][WO>][WO>][WZIO>][WO>][WO>][WO>] +M[WO>][WO>][W[WOWK>][WO>_@][WO>]^$\)SG.NW[C(Y&B]C2Z7V?:U.KBBX"L +M6Q.SL225*BGD\GD[.SS5HD-6B0I$$5+8EM&8IBF*5K)-H*@]:@V0&R`2`!2% +MQ<7%@*V@@$`)`N5(14@(W06R`-("\(=V9!?*C"#"!""EB4DDE)9GCS*I6RQ+ +M))*DL2Q*2Q*2S,S5F48QC&,6"WH`6P1*04"D!6D%I`2D!QA$"$$0("MD%`+B +MXN+`*P02Z`T@@4@(%(`!2"T@#2`H%I:6E@JML`"V"4@`4@@E("XX`@L("*P% +MLA9!`I`0+BXN+!`MMDDDM+2TK625*E2M9))4J5*E223J=3J=G8HHO5>F]-ZK +MUGJ/4:-ZS2-&(:1$0HE$HFD5`#*@JY4!6D!&D%4*4DN+BXK6222I4J5K)))4 +MJ5*UDDE2I4K625*E2I4A)*E2I4J1$"I4J5K(BK)*E2I7Q`/%>*\5WB@/%==P +M'77<.NNY!UUW"ZZZX===Q)====)===G29UUUTEUUW'77721UUUUUUW"2LJZZ +MVRS.%58NNMX)===PDZZWA.NMXZZ[IB.NNZ777<2777<)===<)===PEUUW#KK +M>PZZZXDZZZXNNNY`NNNK+,X994.NNX#KKN!UUW'76]"====!UUUT===P)UUW +M)'7788ZZWH.NNSH.NNNCKKN2.NNYB.NNX===P= +M==T%.NNY(ZZ[DG77.\B6XP39;,%MN; +M(DJLI,K,K$),`JDP"J23*PDQ"20DD))"20DD))"20DD)*LP,LJ*S*0"0"0"2 +M0#Z>;`)),K*PDD)*0DI"2D`A`D`DJBLI+,J0DA)(22$D))(20B0B0B7D9F6Y +ME999,S)9@`A22$^'U78\Q9999[0S50+XCB^+XOBMJ`#```,`5_W_'Y1_3 +M1O(7%Q(W);\.I.\WJ]WR^WZ_X#`X*2P>$PN&P\KB,3BL7C +M,;CG5OQ^0R.2R>4OV5O,M+S&6F:S3^AT6CTF +M+_5!IM/^M30ZJ=U>L\>;I[:OX_HZNY^_+U'^_CF]?\TB#U' +MHSW:_74VGI]I1=^IH]KX/ +M;N*/Q>[=;G?^^EI=]\.335E5YZG@?'TU?\5WJX'J^7L_CD_/W<6M^GPX_0^O +M-Y71^WRYE;7_3G?Y]_MT?\_'WZG7_/Y_SLH]CK]O]:%[H=#/O9^?>/9]X@]> +M(">H(/4$!">H"$]0$)Z@(3U`0GJ`A/4!">H"$]0$)Z@(3U`0GJ`A/4!">H"$ +M]0$)Z@(3U`0GJ`A/4!">H"$]0$)Z@(3U`0GJ`A/4!">H"$]0GA/4!">H"$]0 +M$)ZA/">H"$]0$)Z@)Z@(3T0A/1"$]$(3T0A/1"$]$(3T0A/1"$]$(3T0A/1" +M$]$(3T0A/1"$]$(3T0A/1"$]$(3T0A/18H3U#%"E18=Z@+#BPKU#"B%A'J&# +M$+!/4,"(6`>H7\0K\]%?1"OCV]("O(GKJSBNXI1[:128KH]M;D0KF];2(A.' +MLA;Q";O8^00MB#UJ@XM*#VS(7*,0.>H%W-"R/4(B208>%6A=$%/B@T).!0\; +M^A*6-!-Y$+N0@'<00=#SW;T"%[(S_:=H7[/6&=[*&`G;'.>5"I#*92)R/KQR&4B\9[,4\EL0 +M;[<,\P7V8C;U[WCK+6>[?!Y*6F9NOQ>71KEW/MN3RVS4C77%Y;F^8 +M^5P>-F^9M?S>?^D,U9_@\C7&;9_1X=(E3GUB7ES8YS[+GCE7.POR>05TSL!7 +MO'V3SUA^CQ-*.TM>\"\9]"O'0=3PJ\C07S/"^]@SU^G4/Q8IW`SB'Y?YS!YI +MXBGS69P[R"S'ZFL0\R\*C,XMYEE:,QC99XM1ELAE'C%'*9+)/(A'(93&1;Q' +M%965PACQ'!2U^9(S]\F(R\HS\PZNUF1GY29NMI1G[I,N6J,_<^WF)%LCH7'< +MS-QMZ+?1=W-W"XHQ^C[V!;:&J1X#;652/`MVLJD>!;]=5=.YZE]OVNG[G5[K=;S<[#<[FEW%3N=S2TB.YB6"PL0PPP5M;6UM;6UM;6UM;6UM +M;6UM;6UM;6UM;6UM;6UO-YG+X_$X-74[W=TFUV6PUFIH-$AGYW-34QE,AC)7 +M"X*_WQU*24C6UO-Y?(XW#X6_J]]3[S=4FVV?[[#6ZK44&B>3SN=YV#PV&Y^' +ME\IT,EC^%P=_5[ZHIMYN]S2;?:[/9?ML-=K-5QN1QD-#I-,^5O00T.JUK_`) +MX%1!0<)"PRE5Y-!/"0:,C>ET^I_?5_SK=?L/>SVO=W.[WO)D^+PO++\?BS/) +MX_FS/]K2=:@['6]FI[+WVZSN=OW;#O?Q[Z +M+Q_#:^?Q_&D]7GKMWR_^^5--Y#YU$YD_3\]]Z_7[_IP!37UX4_-_;AZ-V8`P +M#``6-+O>U#6*F[*Z!IWL2NJ.P9$U/7C#-]76>,JJXNSU=='-:S56]I6:R1M] +M9K;K(UE%=[K6;.^.JS:8*^5FUE<%6;;&RM9M\GC:RCRV3K-7FX%%RJ[A;;EUW#W']5W%I>9\?YI^;\.155OOY7`YWN_KC<_V\W^>A +M[.=RNCZ^AS>EZNET^C_R"'3>((=1X@AHWB"%`\00U#Q!#6O$$->\00V+Q!#] +MWB"%$\000$+7H"%0H"%MD!"HT!"W"`A;)`0MT@(5*@(6]0$*G0$*I0$*J0$* +MK0$+?H3PJY`0JY`0JY`0JY">%7("%7("%7("%7("%7"$*N$(5<(0JX0A5PA" +MKA"%7"$)$0A(B$)$0A(B$)$0JP0A<`0A<$0A<,0A<00A<40A<80A?R+%"XZ& +M*%*BP_40%AQ87DH800L'RD,$(6!Y:&`$*_\M"_"%??Z%?!"O?,O*`G0N:ZLX +MKN*4K;2*3%=.=:W(A7/GMI$0G'DD+>(3?HQ\@*V"Z343BTB1LPKE&".1$7#?YOMBF\+`YCN30L1EX7N3(L3EE/=F!2^.797O"RN08Y/OBR>3 +MB+\.)0RLJ;XL*A@I9GX[^A?)>-O/D0O$Q9Y3RH2=IRUT\R$DUF7 +M/GN2%MR\CZ+BA;F\UZ;@@V;YBUHH?^D)NSHH1KC-,T4#I$K-HQ*%S8SB*Y!R +MKSD*BA!72=@$4'V3SMA1032F>2HH!>'8D1Q.M!/(D9^^9V>1L&=OV<$C8LY@ +M9P2+_.8/-((I\UF<.A!9A&:Q"&7A49G%H996C,8V66(Y7'Y-!@CD\CD4(?\X +M_)XNR((XG*8?!EH(X'*WT]%Y>Y=FZ1>2]XE+*B\D\M=+0B\DLM<[4B\N7;FG +M%M1G[CW,Q(6]%OH>[FKA<48_1=ZO6(HOV-]O[[!%'II\G[T=ILD8261KMMLT8:91^='M4FJJ;=TU-4[V?WN]J +M-YI-YO*>EH:6EIMU]IWO>]GJ\+U=7?=C\3JZN^WTZNKL[Z=75V>QTZNK?9Z= +M75OIV.QWG3>_ONG>=YXGI]5]-]%G9V[E_.*>GWF<]&DT>@].GTVA_[54.E]6 +MNUNH]?[;'5^RBV>O]M'M_W]VZW.T]^]WE'\*FHW7QW]9O:[A9>H^7$S-5\_Y +MS?R?/[OI.X]#O>A],!%0\E`$@J(@/TN"1^F(@=J=H?(.S+1M%5[O:=YV?Q?1 +MQ,14'Z1$0!#(((@;+CK;%20`0"0$5#R3WO`D_M,&8L&XK6YKU>T=?EV"Q(#Z +M4!=4!RJ`R*`NZ`GH$JB50"J`5$"P"P"P**#1`:*E!#)5!Y_\_H/C_+]ER_)^ +MYYG&$5V,%"?45!T"FM)I&<9YK2HHC]/ANBYS8%O$]S['Q*:-:UL]GSTF8(@9 +M@A14?3`^S]GU=@`V#8-@VEJ@$#ZL52@($(H!<@M!1H"!HHCSW/^YM+5`+E&B +MKB04L!`Q%4H4!`B(Q0"=."O2?K_L>]W/ONHZGJO?_L_`UB(:Q48"!-8@A00* +M%^*#0$"%B@%!`I?`3,S,RJ`%05A:"!&"!`!(@$@C"`@0$2`@1@($4$@($("! +M%4("!`B@$5$@($+E0P8,&#!@P8,&#!@R-8HF8&?GY]@#8-@V#:"#:"!E@(4: +M"!H#2H#AH"Y`+A`N$"X0+A`N$"X0-P"*>K@"!(B*2*2*B,@*([G#APU5 +M,,$0,.'#ZK#:JJH8X:1-(PFM-`UQ:ND1ZCT.*_,Z/D>MXB[:%ZWZGS]_T=E; +M*U[;I),\1`[L5,45!]3H:%>K_*V"PT]L?>@-F@,,@/N0&=0'90">0$\@)Y`3 +MR`GD!/("KJZNKJZNKJZNKLA9T(0'BE08(.B1`-R9QGFM*BW(K"")`9^_WKO> +MUL-?KM9:]50ZC3QF*T.W>"P&?SJM8MZ]K>W>\.KS>KW(7R^WZ_X"U7R2I*1F +M`Q]R1`5W9%%#LM[TOI^)W_4=?QUX4/%A(B!(%$121$411)%$1%$E$41%%Z__ +MW\1^"[N[Y_^">1_`@@+_=Z_?Y=_Y^;-OZMH#F$![B`S\)Q`3B`G$!.(#0H#D +M$!^R`HK]?K]?KY7[]?K]?K*5V)$B(B2(B(B2(B(DB(B(DB+T;=B,2(B(B2(B +M(DB(B(DB(B(DB(B(GL+S[U-Z%X6>"(B(B"(B(B3"+U=NQ$D1$1$D1$1$D81$ +M21%ZNW8B)(B(B)(B(B2(B(DB(C")[]Y^]%ZRW8B)(B(B)(B(B)(B(B),(B(D +MC"(B)+V'X/U'K?BOE/8>O\GR8B(PDB(BS+*B2(B(B2(B(B2(B(DB(B)(B_W? +M`?%?V_=O$\7B\7A\Q^$/3>U^?Y_J_.J:>Q6.?;B`?:@/?A`?1`/WH*&JJJJJ +MJJJJJJJTT2NQ"2(B(DB(B(DB(B(DB(B)(B(B)(B(B2(B(B2(B(DB(B+S[=DB +M(GMEYMZJ\Z\*O!$F$1$21$1$D1$1$D1$1$D1$1$D1$1$D81$3V6;&$1$3XML +M1$1$D1$81)$3_?^,_#^=X7@B];;;$1$1)$1$1)$1$21$1$8D1$7K;=DB(B+^ +M?\7W21$1$21$1$21$81$D1&$1)$1$1(D2)2A*1*1*3I\/9_0=<==U"VR"[+> +M9')*^:FK>RYHO*O"KPD1$1)$1$1)$1$1)$1$7F6[)$1$D1$1$D1$1)$1 +M$1)$1$21$81$D1$1)>5^Q[HB(B"(O.MV,)(B(B)(B(B2,(B(DB(B)+SK=B_L +M?WOIO8>;^F^4_U>3Y,1$D1$1)$1$21$1$27K+=B,(DB()"0D(0D)"0D.ZZOF +M]#U-:UK6ZYV67EYN/LL_6Z%XRROVBL*BL*BL*HR,RBF1$)`)`D"0.^1`$/W@ +M0!"*@^U%5HJ01`@B!85@LBD@D9D9DI9E?'(B(B(PPPPPPBB*(PPPPPHBC### +M####"*(HC(PPPPBC"C#########(BB*(HC(PPBB*(HPHBC########"C##"" +M*(,,*3*,S*JO*]+V;TO2]+UOI>CZ7I>GO3R(B(B2(B(@PB(B)(B(B)(B,(DB +M(B(DB(B(DB(B)(B(B2(B(GI7F7FWJKPJ\)$1$1)$1$1)$JR^@]^W+*=$0P-) +M2>U.B'(Q($44'UUEVG\]HNPN^OVM1P;E1T!0Q+6B0&2#@``6`XPP7:DV/2]? +M]DDDD$DW0*=\C7VQKXV-5Q,5'V)G"1+-FS9LV;/&#S`0()E$7815D"1`D?5% +M\RC++1M$,F0A##5^4@A+10''XE!\=RN7Y;RO*AMEFE6:@ET5+35_[!"$>.@$ +M!XR$`#@(8QC&,8QF.0B0D'-X;][:'D?=[OY&Q_N]O[C_7`O////;$,FBGC9 +M+-.M:UK6M:U_O0@`]/'-CGQETO%\>$0GY-R=E$ +MHQ\!XWB^/M$_-;1D,AXU/SG''.Q]^E/&CT6E+ILGHP,A8Q:UK72"S5+I>'A$ +M`GM>7_!"$4444444447R5%!>+X^/(1R/71FOM\O +MY=F\\O_G'=[K:/I=HZZZ[_$7<7#.N:.=2E<.M:UK7";^"`1\I*`0(PHD(RLA +M(B,MB#H-CWS>N$XJV_[7?\AX?7]KP;KCKOC#-.;2F9)+,QC&,8QC&88A*%%X +MOCX\(C(AST[=(-Z_%?;]D4&GMMOGOG._2Q495U"5*E2_^`I3X=S>?-\W!Z/":G[OM< +M9UOG_9M6K5JU:_*:D44=U4L-X_I+OM^(]K^[L +M/-QFKC/3[_Z+KO,>>>>>7I7(UKFGH6M:UKQ+6N^4(^\A"!`A"`2POCY`/!O> +MOD.9YKNOA='XO7?Y[;<[R*C[0MQ;\ZY)9EK6M:UK6N`D@$J+X^0#P&T_8D(L +MNT_RP^%:M>@W?R>^XC_5JU:M/6MS%KH@H7-/0N):UK6M:_=H`%D8DA(QA`0D +M1;`]9O&V^UV7]N$V75^YYKKKKNY%,<6E'3%'JTTTTTTTTTTY(A.4O%\?'A$) +M&.!YGS>PS,^K7Q_9Z_[G,..NN]#]=*>#&3Q,D9-/0QC&,8QC&/C"Z7B^,0B, +M21$9ZO?GD;SUO0[6];_OYNO==<=R7KL5_)!#%DR9,F3)DR9,CYD+I>+Y0@Z# +MD91U$&$(&(Q/QK.+19C6UVVS7"_,ZG`*5=MTB1)NP_8"X:%7J2UJY>664666 +MH+++YH$`:XNEXOF`(C>=Y=^UWKE`DX7=.([N?\?/;-I92D^_[D]:,?M27&33 +MT5,9&QC&,9,@672\7QX(3ZV_^MW"UN^\>?\K$6C?^:[G]J5*E2]*1''B'R(4 +M1$1"0L-`4V@Z\!-^+Q1_(W?BY&>['4<>+Q;?Q4\Q>E2IGXM4TU_[*9N? +M_OWWN.\7BSUVT.MYZ^(U:M6M@:M6K5JU:M6K5JU:M6K5JUB8JR-6K5JU:M6K5JU:M +M6K5JU:M6O)OS4[J$$)2"-"$E'MI)-)6^(B)*2DI)O)24E)242G!0!X/X0`)P +MN8`$&$&#=NW;MUS=NW;MV[=NW;MV[=NW;MUBUD9R +M8`@`PGK/6ZW)>!V._^BX!UUQW>'4IO%EE%^>R6:>RRRRRRRRRRRRR0L:)$)F +M)2PC(,(0$PP!%AW**DO!.,OO2ML3!?^C*C]60)?GS)"5*E2V`#%JQ\6&*E:P +MPPPPPPPPPPPQ:8$2.,$*"08P($%`00$`$,$*"08,GCC@AU^TKINR/%?DX_+; +MM6[=NW;[,;/&V1LT]#6MO-A:UK6M:V,2(E&D)$1C1AH8!X8)=0E`,-A]XNS, +MTF,!X`PPP5?C[RU*E2I>1:1QV@%*H19"E*52N9,F3)G)S*69,F3)DR$+>$`I +MEK4:D4JS%A1+QR/D^3LM'R1D-+X>#CXWD&>>>>^T:(WR%--5*U +MAIIIIIIIJDTTTV!`V+'&''&'`#`@04!!`0`&ATIY2%/M^_:^?3R&WI)"HV<6 +M$"%']?"D2)#238)::J5K#333333333333360`,`"242$AB1L!&2$H\A&P&C8 +M/Z^VSZ[[<^[^]_U5C6/Y8MP<<"<3W_2X!U!X_1[_CY#IN1WWWOR=8]9]C>JG +M7'7?>&?#-CEAHP8<6?/GSY\\.?/GSY\^=")!\@(2(L"<2B<3.)1W.:]Q7?:T +MUP6>;T24_R[A*5P02PKCDEF6M:URK6M:\J^/"`L_JB`5$I"C4BE4R>$"P(H0 +MA!3HG:X/-=;/B`*F_7[:_^H[6B$"X>1XGA3DY.3C%_\E2I6S6 +MZQRUKZT7L&,.T:-&C1HT:-&C1HTC&`X#10)P@04!!`F`(4-OR58$!Z.[J.II +M+OVXB("PT7Y[J1(DCI@<>P0#XH**A(6&4E%%%%%%%%%%%%%00+@!(`P\!"1$ +M8\&8F*!W<.>YOL7L9S?F=(XXYO)KA=VY>D7#%'(M:UK6M:UK6M89$HD'`@(2 +M(C'D"SGO<;C]/"8RX?DXKN_G\Z\\\\]ZCT?9...;26:MEZ>R6:>CXH@1FS9L +MV;-FS9LV;-FS")A*X2(C,PJ&<<>J(J%$^9V70<)J&]Z_R/Z//]?T/R.!KLG: +M'7;_R/4=KR]MJ4@DG"?$E2FF"[%>I?@ABIIIIIIRY9]SC/$^]Q_3Z[+R>H>9VR4_,VY*?W[`E-DDF"6] +M-/1@LLLLLLLLLLL;C$B+#9!"'R`A(BX%I`2FU_N>P"?(U,)I]RE.^:>[?@]S +MSG?_=O+$D0)2C-V_X^R=<<=:9II*-7--AQ8'S5S9LV;-FS9LV;51F2A&)(." +M'+X^42C3I,9"[Y^\4ZWT]D4*N10(HB&1NWN7_Z_&YCF>U^3AP8PYYYYYYYYQYY\7`@.`/P/X0`)P(&"+&&&`\Y'8^#WCNG +MN$>PGUX?A<([UM0^<$>OJ2FNNW7>PUT8,.+5KKKKKKKKQ5Q'J-"`R&`@%')+ +MYE&65'R/1VIP.L[KS"[@KGHP8:ZZZZ\ +M'7-:UKLLLLLLLJLLLQ&*P?( +M"$B+02B2:EY#G>I\`'7'OC?327GT]@L%@L%@L%@FGP? +M4A&1BR&6J8Q>P8P\9&1D9-FS9LV;-FV:"`KR@4*B3I;40@4R*$($U8%@>SV. +MZ^-ORN>ZVDNGSMDB_*ZZZ[XFZ)3;0"`!`661QRW;*+N##J@"`"RRRRRRRRRR +MS]((`N@TOCY`0EI!8>^V.<>(/=]WA)Y-2AE,E!`Q!B#13:_PE2I4OLU8XY15 +MAL,*44M7+V!4*444P***8*DX,"\7Q\@'D&,382'!^=_+P;9<.K_O_K3\WM*4I5N54%*ZYYZY*YIZ,%==========?MA`&@C*RLG(2(C)"T$XDG$GT/BN&H<- +M[_TFU>3V?GU:9SWW>FZEU+KO4DQFS8)L,]ZC!AU,V;-FS9LV;-FS6%9&7Q\@ +M(3(@MB9B8P8PYYYYYYYYYYYZP9]"\7Q\>#7"8Q +M-0F8>)C<.9H-&]I3^TR9-33O:61^"&+)DR9,F3)DR9,G\^*!"!"$!E07Q\@( +M1X1E/,_F?:K'&:IW3KV9<9G7[/N +M:-K7:,\_)6*QL'?.\=PSS8..XKQW^7?O^MRK'&4V;V'P-TU3;OA:MFVL9E\SSFQ;5L''>V_9^+4O<2-.^=[S8/ +MU<-M&W;!(X*1QFS:AN&S;MQ6M#>#>#>#>-O_+I=+I+I)))))))))))))))))))))))))))))))) +M)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +M)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +M)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +M)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +M)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) +M)))))))%8K%8K%8K%8K%8K%8C1HT:-&C1HT:-&C1HT:-&C1HT:-&C1HT:-&C +M1HT:-&C1HT:-&C1HT:-&C1HT:-&C1HT:-&C1HT:-&C1HT:-&C1HT:-&C1HT: +M-&C1HT:-&C1HT:-&C1HT:-&C1HT:-&K%8K%8K%9))))))))))))))))))))) +M))))))))))))))))))))))))))))>+O%I$B1(D2)$B1(D2)$B1(D2)$B1+2T +MM+2TM+2TM+2TM+2TM+2TM+2TM+2TB1(D2)$B1(D2)$B1(D2)$B1(D2)$B1(D +M2)$B1(D2)$B1(D2)$B1(D2)$B1(D2)$B1(D2)$B1(D2)$B1(D2)$B1(D2)$B +M1@CN>]YDSE$5#G?9F+?X[=V\T8YS9AY??\;2REG[9]\`OJ/:8UY1B\IE9:7F +M-304%!IM-(^CT^GTZ"!!>,_A``G"!`@8%X#A-D[';9Z=[:L'PP-0<_KT7&^: +MZZZ[X'V$IQC6M;?P-HP486M;?:UK6M:V0D(Q\@($%`+AAEX#A5;WG\L@+DWJ +M=X\H-7#AV=3X4B1)>@_D"RUBRPK"U2M8ML8!"!"UVNUVNUVN\5-34U-34U*T +MK!^6YRNSFAQP<8R""[`R.2 +M69C-/3T]/3T]/3T]/3T=F>%YXR#(,@R#(,@R#()86%A86%A86%A86%@,@YYM +M`#`9AFF<7@M09$9`UQ$77$$`5@^@2'L_YS%?+[W_P:?16(;YAB+"./QMP..: +M;"0BN$-4JE:PTTTTTTTTW1HT:,F82^0$)$/!*))S.:104'C^F\7S-MU,6T_; +M^%MKKSSKVO*ZXH(X:Y9IZ*X*ZZZZZZZZZZ\B$(`8)]H"$"$("`A,LP%H6J(J +M$40SCM_Z[%`O$UQZ7\?<:'0='?]?_#\/_>DAI+,!0%!J:#8I$B0\^%L"Q\/7 +ML&,(>J///////////+&,"`!.$"$1:$=[WG?]Z\2]QA';IN6\\GQ/K_V57."V +MO4"LT&_RU\YSKSSSSVC1I:)7]&IDRTWL6C1HT:-&C1HT:)",QTD)$1DA:`D[ +MOPN/>TS;MN[7L_E:;!;R'"Q%@,,,'\5WKA4J5*EZ8&&&+;&M,6+5UC7&&&&& +M&%EEEEX+9@`P$QERE!.1DA*3%P,PD1QW'[WU+UHY;F4I4J&!4*GX(8E*4I2E +M*4I2E1F*83`0D1&/!,5&,H/($(`!`$W#MQT<$Z2'4_VP."`L86))@DGM\.(( +M((((SN%''F`--60RV&-5K%JXTTTW1HT:-&C1HT1E\?("$J03"9C0+*!1IWKA +M\>;YW31?VMZIS^OYEQQSD1C))*)&3T38&,90QC&,9CJ9D1?'R`A'@D$S"FTY)!)))-D`\]8I6J8-F.4@^`1DM@M!*M"P2.YI)>8Y=]\. +M']>UQ;7$?2^;7F]&,MXXX8/1)!TF="T6A@'R`A(BTA$I;'.0IVG_O$6OQH,8D0&,][VJ4L%*T])_25#%'(I2E +M*4I2E*4JLR+("$B(RT(^C\CG=S>1^>5PU0N7[47]^Z9P40%A&B@)T*,=MN\2 +M22223J`//L)[Z>>M7+V"@\\]<>>>>>?L.P[#*2&PF8B(R0E)4(YKI-T]EQ/` +MVS5-O^$^]V?YMT<<5Q6+X5W1U&65I$O.Y\W=HT("]<^]I$B3*>T<=F +MS9JURQFP8P\0S9LV;-FO9LV;-FS7#'@/``G"!!0!`#+&\,%I3-H^P!8P6!^> +M4MIM;OZG39:VZ?1?U82@3Y+%Z-(D240:P(R,C(9=8X5BNAXB,C(R,C(R,FS9 +MLVVW)R4*I0J)1J1/(($_BI4$!+10@.X^'\]W.SY*$"#$2^#WO;.NN.J4JY?4 +MJ.2692E*B5B4I2E0F$4/D!"1%H1C$H-]T^$X7V[-^-UUVU +M:M5UUUW:*Y9IZ(:ZZZZZZZZZZUR$9??("$B'@K$TB0V/"[^SVN^?X@TBV)/_ +M.X2G3JJCJDJBCDEJJJJJJJJJJP51&`D'R`A(BT2"<(FH2B;T?].]^[YMM&CW +MW2N..><<",8R:>.&26:><8QC&,8QC&,VY"`.2J$M%1J12J9.PL"P)4M%BI)B +M<=+@>COOG]GS7SY+N:XEP0@BK?%4X"_$$$$$5H'''*EZLY:N7L#CCCCCCCCC +MCCLFO/`<(`$X0(*`("$$A,)N$Q;_A[R:WQGO=C'0Y3G+[CCE554$,%5R&.2J +M*JJJJJJJJJJK#4)?("$B'@E$A#_.B\?D7''.+-R+ +M++(YH[*,&'%99DLLLLX;+FS9LV;06(,Q"1$9(6D$YUWIW0'P'VZR'_E++^]O +M:K_$`^Q`#\-+.I$B1D$*!99::&L1:I785A9<*6666667G7GS[4"`-<90A(B, +M=,PGD^4<]7Z5PQB3J^CX7O7C4%%O9F_?ZTR222223*W<<GWTI!!!!FG''X`1L;&Q$2QC8V)BK)&O\;&QL;K:VMK:VMK +M4A(;(.$!"1#H2B28_9R+ND)/APB$`&,?("$=!A,.!,)1./#B*O]^?TOU'GG7GNL*JJM6]>JJ@ABJJJ +MJJJJJJJJJJREE14*B4:<65$EHH:W+YCP)WT<%*LB+;<3']MH:G3YSS=I7$Q3 +M,JA`8*WF?JGDR""""&C1I8ET,T:,8>(:-&C1HT:-&C1HT:,!@?P@`3@E&:`Q +M'"82&\;SCZ)[")/K_[_C\]UQUW8C26M=_56N.25:UK6M:UK6M>244.(0A"(" +M$B'4`@%DGD?ZX'3+:,(GW7N^*XOD]?IZGT.N]OP-U`@.E\SW'&\R\\\\]_W\ +M]*?OGKCNT(0@UM;67BUM:I;*];6UM;6UM;6UM;6UM:(6B4V0A(B,M`>R7\3@ +M?0FF:?3Z2,8E'S^#2GL#P!C&1Z+[ +M%SJ=DTT:GM\S/P*2VT@<>>$!^A==(D2'''*3H,XY:N7G''''''''''''+`@P +M'`"@3D)$/$HF82!\_A_9;MXMZZ3^BI<<E.S%--.K!>TJ7X(:::::::::::::<12 +M/D!"/!*),8GWNWN&`3@$]C$>/9Z#'SD"^!JQ@&````&`CD3"KCW(DDD@DFLL +MXXYIIL(JA335JY>:::::::;"FFFFFA#C!``G"!!*$0`X$A"A%E=>D3`$M<]Z +M23P:J7EY>@L810#Q0/"QQP++30:8LM4K6%EEEEEEEEEEEEJB@'`(`$X0()0` +M@&+$L"`4@/LH/\%;&-NF"K/I8@#E(9?_,,,`XP=.TO@$`0)0A!=Y7EMM +MQEL/L_Y2E2E17(U*CDE4I2E*4I2L2E8:1,@F`A(ATF$H1M5>D;]I?+J8:1C$ +M[=Z_<'''%K7!I1K7)+"M:UK6M:U+6O8$"`QH40$)$/!*))Q.+<'$;MLSFH)^ +M1^[O/B=_^BLV53L+%DL#CX.%2D$$$.0RH,F3)6R?&3)?8V#)DR9,F3)DR9,F +M3)ZN@E,=!@_!G-EHDM< +M00E((T=VCE2I4V;-L-19)LVHLMFFS9LV;-FS9LV;-LD(0"!;5,E4*B4:8P,,,,,,8##``&`H!(,,`T@ +ME\@(1T#P^ITAT$`?M^]Y7TJ[>(N;`)1#U#$)1$7Q\@'@D$AW>Y;9[']??6[IO79='%:,AY75I2M:XK%5]_BN`G'8]1B+U!`F`.)Q./5)4J5+E&`XYAAB=_A#(18M7&&&&&&0) +MAAAECA2*\H%"G5L?6Q#=L8[-D5G99AEF8QNW;MH[)I'\%O?HQ#OFLHJV'9U:F;=6U +M*1PG+/Y+`U3%O+?W9M_1>FH7%YC*.@5IL$;2I]S[KE:7YY3MWA/<3ZM/$>NT +M[^+YUU;-\CRE4Z3&(H9//2KE)*PZ):9=HUN^R.?Y_P_VQ*NTBI#HA+2UZL&- +M@I:Z8W'%2TM+2UK:7N6EI:65`,^@_`_@E&5!!`D`L/-6I0#M^]\[^^MZG&73 +M2,A[GY?=_$====KKKN2:M=<]&"NNNNNNNNNNOYPA"#$(O%\?'48Q,@G9=9PS +M"3P^^_#Y?P;MO&736VP2M:UQ:2URWIEK6M:UK6M>`C$HO%\?'4&`2$AW/Z^" +M^ESWR?_/8[I\#5UPDW@8QDL+&,FGH8QC&,8QC&,*(A(2#Y`0CPZ'YO1] +M)#U7*=7I(.L/E;VE/\3D"RRR3#-99@PXFUM:UK<36XT`&)8F,OCY`/"&D@D# +M#)TEA`>%#H>IA\*?I6:/LD7W/4_#3\`O2)$E(>./$`667"KU99:]@Q+?2ZH< +M[<^?/@"@NEXOCR(A(9C]_U/D\1.:I<-?U?<[:\8S^'K^#<<<6M=N.^MA\M#FUX/P5P#UO?K-LE2I4NT +M#;@8888L?C#%[!B888N,,,,,,6*`'&*!^!_"``@!JS&)`]WHA@2A80]>ZNS& +M6[;N[^R5L=G",U#,N.(((((S^P''B@(..8*3CCF,/$$@6<<_G'''''60`&`` +M7#!&A!@D@`3A`@Z9Q-L_/NKJ$3G'?9^MT>S;-YWI?8\P^7?U:24^\+++*(J[ +M+,&'%999999:K5:K5A*>VHH3$1`I5"HE&G85]9$J$!=O3E0(&7Q+)HY[W6W# +MT?=@@?P?0B`F*W-\Y*E2I9L#335-A6FFK5R\TTTTTTTTTTW1#""";`U[J&27 +MS**IL2XIFDSR\*""4,GH:NHN"47#J/U<3M63K;5JU:M6M0X(4JU>5"I4DLRE +M*4K"I2E*RQ"2\7Q\="D4.!(5$QT&X;!PWIUZ>D)-43+[3_G4\LZ\\Z]S1ZGD +MTILLLDPS668<6-K6ME:UK6X\HE$1>+X^/",HTX3H'M,3,)1.8NZW7O.?]#S> +M+S/7:I^3\"4M:V##$UN'%C;"UK6M:UO.@A"$6'&H0",**Q+Y`0CH2B;@E'/< +MYKCX'$=YXER\),9D''_C:[YM.'7)DR9,F)31H:L"RRWY3`%EK%J@LLLLLLLL +MLM<$6`X/H/P/X)1J1)NW$RCND)0<7\'3^=\W]^P%RZ=GN?"HW;H=EW7V%TW8W +M#RTI^,6668'\-EF'%CLLLLLLLLLLV(PYA*(A.8E'("$B$H!P\WCNZ0%C`>Q` +M.J`?YP5U;=I1\O-/Z/(:V>)3)DR9,FP8%EEK8)<66N7TY\^?/GQY\^?.LRC" +ML=+X^0#H1B91-P2=E^#3'43B>(;[K[_-O////4TTW]1^FF*.2FFFFFFFFFG# +MZ$NGZ3DSY)XYW1M)TQV#A*)W3^+PW[-X_JRBJ=X]=W:OK,Y13K@BA;EQ2K6B +M53[?K.+^+TW3X?`WG;=Q?,@;Y^H*GS?2D_RTI/<&'#AS\.AAPZ_8;'#APX<. +MR;9MFV;9CA$W2\7QU&02@R&N')#Y_Y)SQ.VM:9 +M$^>V6+CR>FOU1ETP08-`2!9`C^WJ?TE2I4K)DR9+K"R90\1$LF3)DR9,F3)D +M>"A8N4=*VSKU.R*N,N\=E'0O/7!KFJ=2Q2SK>X+TV;8YH&G91SC2,*N[\U`] +MYA'AN^=L\%Y39/$;5W;-+:P#L58_BN"K?_,2RJ?=.\UF%X9!4K2\9FWJOH1/ +MI>$O[7JZKJ[/<<\\M_UP76,6J&R7QIGG(G(*-^+X7&8Q[:MN17EB&0=BRSUW +M_F.5B\KRWCR5M>2^%R;6L*\9:UW?`\IOW6/2>/GN2%E7N224R9,2FCP9,F3!\?&3*(A8EDR9,F3)DR +M9,EAP#OH5Y0)PJT1`I%2KZ<0'?;>N)R?[*\;776G7W_D:%$A`4$8!,&`\2$*'7.AX@RT^SW4_$K=A/^R%"! +M"X_H<>:!_`PR$*4F&+5R\PPPPPPS7:[79S`1";Q?'QTPB3HO1.(XKQCM]4>H +M$[$>1]3JML_72/FEL'.I2QEN>^QD]&!C&,8QC&,FRB2(O%\?'D4"3R-%?J=OCJ[SPP/D4`]D",#4]FZ)$B0XY,PL)QS!C#G'''''''' +M''`J&0`A`A%TO%\="(3A+9_B-XX/==W\+!_6VCTG2:O-N.NN]"55:<-4%4DL +MUHJJJJJJJJJJ\($`811(-,(]"1$8Z@F-(1C)Z,"UK6M:UKYQ"`"1`B=(A"4A$)`'$H$7B^/CQ79$4I`D$'0 +M(!2";3V%`"R(29Q&D9`)%P]]]?L?`\VX#7D$Q9D$!>DUO7?N?/[_PO^;L2[$ +MQ+L3$V8_,9\[^2?/GR9:9,^?/G>HSY\^>T"-`D!"*4@72\7QXJ.62DD!)!V) +M%2D`600Y3$[7Z/G?C]7_/BK>2A!A$H0X)2E"$I$([?ITI^_UB4J4J/44J:>6 +M^I2E/*4I2NENRR!H;(H(.S(B9)?,HN*HLD@.:0*0"17$("%((\URW3^_[SMN +MFY/ANZQ@4QX\SO__?+Z+IJVVDDD[8)0##%JDPPQ:N7J####"######$PP)P' +M7#C@.,,..`P#@.@8"&W(@&27S*+BJIN"*M(G*\&BV0D0)#/(HWB('G<'%Y3/ +MXSQ,CR>_QD3(@C[;XV+V-EEEGLRNNB3!77!AQ/URUUO5^K6UK6W$(Q)$"$I` +MB$N)0)2A,!D&0#6&27RI5S"":9!4_(VM%TR+Z2(`A\M4'%414.<5!L0!*`(! +M*(!`G(!!*0@0(.PODJ')(L_^GD>+0LUQXHO"3``HJ%?E912M8M********** +M*7C/H/P/X)0@0'&""!6#W7%`3HT]7N#V$2>*+X^.BD1-O^LI`2T7R^K7$X@+G=\!_*U3*U,=Y_[O>6G)RY\F6EWKI\O +MJ?U[5U#SSSSW$BUWY8%22S*4I2E*4I2E[@(,F@=$.2"8"$B'491*)1)Y$?<> +MF>,`EWS$IQX[5_4QWK[^/&_CQ8L6+%BP8"=P0G"7Q\@'D1B3J.GTQWC:OJI< +ML_W'V.U;7V^P[9R%Y0E'M-;Z#CB2HC6Z1(D]H'''+7TY>P8EG'''+CCCCE9P +MZ@!T@##E@_A``G`@8X$HD+8X;[OWU>BZ?=.Z]=ZQQQRFF._33%')33333333 +M33C`$`BE-\@4&99-@3)+YE%@;$CF'(>7Z?16Z':<9D'P14XT5!TNW]_T#KCK +MJ]26&=?$GGGGGGGK0.&&NK +M\#^$`!(T"`X#2RI@$*!%MLB[;7C0)1MG@8/*W)7Y[=NU:MV[;QQ`ZQ]DC)IZ +M&,OL8QC&,P#(2H<$,'R`A+@1B4%PD'^\_?TUOD>7\WW;KKKN3)JQW\D$,6V( +M`$($(RY:8VJ5*E2T'.N=W2I4J6.`LM]60Q:R`6E%%%%+)DR9,L:U1(D(DQ%,4"A42= +M5"F2EPV77;+2V^M6)8.)X%RP^(P&%F.%MXA^`(0/7YNTD2)/R!QQRV%.7L&) +MR=8<<<<<<;U?`[B_N]>92I\3YV[I'%KCN::Y9I5KC6M:UK6ND6A"81*Q\@(1Y!4)4"9C +MB/KO&40CZ'*N("XAXN^XWCG\L'U=('S3+1Z\6N)Z57O/ZC$(4-B`;BM?SK_ZI"22""2 +M?-.#CLV<(S6LV#&'9LV;-FS9LV;-FM!F.>E+?CM8!-TX+?/I?2M&42;[M"4K7:ANKCDE6M:UK6M:US"TI$)0++X^0#Q +MD$R"QSG\OV-V>]7W6OXE[(71P*?]XW=^;I$DDDDDRV+''@0+++AH`M4K6%EE +MEEEEEEEE+AAP&4`D*!_"`!.!`#,`'@P'`H+,RV6=P."//YONJ]YH=%-6_`8J +ME(((((M@''+U1QR[DZBKJZNKJZNKJZNKH%74U2*4A$4JK42C4B>@\RIE5M$2 +MVWN5/N?=<=JZP;UEW_5====4J5V>WIR2J4I5555552$7S(9$%1?'R^5#`3=" +MI-YN*7B&DD@D@)(!P_#Y&ZZ+ENN[3RM'E>P_QR!$V9`,"HI!7;$%Z/N^-I2G +MC];>I2G,FIJ:_(S]38\+LKYJ:F?J:FIJ:FI>/Q8.Y@HR$A"$A(#GSZ(B(B(B +M+[QNQ$1%N[$1$1>V6[$1>W7J;R[S+R+Q^.(B(BW=B]5;L1$1$1=NQ$1$1$1$ +M1$1$1$6[L1$1$6[L1$1$1$7OGKOD=\7BB(B(B(B(B(O9;=B(GT/^/KD1$1$1 +M$1$1$1>FW8B(B(B(B(B(BW=MW8B(B(B(B(OXWMWQ_R_IOVOPOK_+\GXWR/3] +M$1>Q[L1%Y]NQ=NQ$1;NQ$1$6[L1$1$1$1;NQ$1$"4B4B4B4B4B4F!U*76MB; +M.V]@PW34:UK6M:V34-1(1>T[L1$1%Y=NQ$1$1$1$1%[;;L1$3Q;-VW6S=MW8 +MB(B(B(B(B(B(B(B(B(B(B(B(B(B^[WE7J;R[T+Q^.W=B(B(B(BW=B(B(B(B( +MB(B+T;=B(B(B(B(B(B(O.MV(B(B(B(O%NQ$1$1$1$1%N[$1$1$6[MN[$1$1$ +M1$1$1$1$1$1%Y]NQ$1$1$1$1$1$7V7J?1^U\/"(B(B(B\C=B+=V(B(BW=B(B +M(MW8B(B+RK=B(B+MV(O8K=B)$I-ZT][<<[$1$6[L1$6[L1$1$1/%LW;=;-VW=B(B(B(B(O- +MMV(B(B(B(B(B(B+UENQ$1$1%ZZ\N\R\V\F\?CB(B(B(B(B(B(B(MW8B(BW=B +M(B(B(B(B(B(B(B(B(B(B(B(B(B(B(B(B(B(B+SK=B(B(B(B(B+MV(B(B(B(B +M+=V(B(B(MW8MW8B(B_F^F[HB(B(B(B(B(B+T+=B(B(O#=B(MW8B(B(B(B(B( +MOOE_%OC+Q:.)DX^CD:S)X0O:.CHZ.CHZ[1T<8QH2$A(2$A(9U*$@1$1$1$6[ +ML1$1$1$1$1$6[L1$1$1$1;NQ$1$1$1;;L1$1$1$1$1$7H7LEZB\J\=X_'$1$ +M1%YENQ$1$1$1$1$1$2&@4H2$0K%"3M^*H@\_S=%0SR`?A97F\=B<#UWO/H;W +M&`R8K(LD@,@@@#A8#"@8/D!"/$@GEZW$$PG8%<3$]_'NV> +MHSW%S'JLXSR^KVM:XJI][LE]PSKOV,L:QO\,J[EG6:7UD6!;QTCNWKMRK*+8] +M!L5*]=OG:MTOS-OE?4[]L678=\C_CWW-/@>PN;]6!6);%B5:Q+$]5V#L'M+$ +ML2UNN*Y5A'D/36%X+N'[FD?W>4\EB&6:-2N:4JUL:ZAIGPNH=^ +M[]FF:81B&$81SCG'-N:?8_,^I=6]8A=&(8A2.]9!LV;7-H%N6YM76,HZ-@U0UK&O96 +MY;FF:=FF:4[CO^*=Y;>J=]#^J\KRJ72/,>8GWJ+0Q*[.:=RL+N&D89>UH9%I +MEZ?@_5PW$8EVR?9A:&/9Q_)-=`TK1/4>8MS5.]=:T+M%.R;$.>6Y]#3MB^UV +M2^NA=LKKKVP<18%M8=AW6/!7EMTYMT*Y*%0O06=@W.IYK'*/"=8VK@N&SSXWYOG>XX#O6F>2Q[ +MP7-N&W3M'BN&X#O7*JA5,@_H]Y][IVK><_@K' +MGN,]5^;IF=6EW[>-JOK=+*[]977O;7EA'DK*Q+7KRS:^KPO"W/*>\]Y/M"MC +MHGNN]:)_9EDC6JA^:]/Z,8O3O%*RK[FH>`[AW#W7@M&^Y\S?NG?&R;!L6X3J +M%0J'XO89-\+]70,VS;8.@<-FFP:5I7MO:?@J'BMVX35LNWRE8)@G#:!TRH?, +M]E=FV>R[EP&P=2T#'+$QS'+HQJ\O&7E=6+3Z?8M/L:S[TFE?FP2W,:GV!;Q9 +M&A>VXR:GWQM%><%BN%>^=X6NN]_CP'BYMM&29Q5*I5,$QK_#GUJ;UU;./7=F +M_-J74,2YIN$C_#+/6?X6E:'*-.S[#.^8=G&)81Q7'<1]3;LL_JIWYO#8IX;B +MK8YAK&7?>T[T'H.B8M_-@4CANB=*Z)[KM7D,4W3?KXV+T74-,PKH70OI9%Q% +MZ7IT[M6^9A[+^CDT;<(VH>JPSI77.U<\_LYY6.>?%(X+)M +M&US,NY4B?>THV+8)E%Q7%RJYIYRSX6671=VF4;=-.WJ6LR:LS*NT=HX3T6F; +MU@VJ85@V#>4\%9W,,R\!BGQN\;9:5A;E\C"JEKU8X#R%4U*PM0L+4,8IW./+ +M;E[+[7G/YO=;A_M]KWFB9%_MXS_:U.^?$R[=OQ4_1>IR&T]RQ\3K^^Z:IZ;) +MX9AGR+F]98IBE=8Y]#'-^ +MNCT5D899%S<=SRD9=;TUK5M?*R3,KVTSC/;# +M3Q/W@[?,5%B +M&"#\]%@\[NNHA+9^;>>>>O///A?0B=B+Q? +M'QXA$AL7>2COD?4_3MCR!.Y^MA\'Q_W6[=NW;MVZ;M,%,46\\\\]\L7=GOKDEF6>6(!`QC +M&,8QC,`0BR^/D!:&$!`AWG(YI5!"Q1$"044$^/\+?;;1N\/M.??>1E$H$(0C +MIO'WG[;KKKOM/?)3=TJ(ZYZ+]8QC&4L8QE"!"$`,+I>+Y"6A@=9^F3U3.L_+ +M^_C+9J(]_N_>N..?-*JH=*J.26HJJJJJJJJJF(1-1>+X^??M!&)4)^5KWW'3J$^2?S_YT/&.NNN^[%30*5+-.H4JA2E*4J@0A\2A1>+X +M^/1"?\S?LH>"8XWAN[P?>\6XA"A)U'\.$R.NNN[F2BI(*+\T]Q0K54I2E*5, +M`3D`HOCY`6T$8GH?L?KZSA>&_CW6DC$=T;09;ST66"&+*8LN7+ERYH,(!BO*!0J-!`5JT(NKZS89[@]WR)"`VT?CZZNGU=+?Y4J5:NGBB8RB\R:>A +MC&,_1777777"4%9?'R`>C$E9_FUQ'*6O9[UTO5XBU]'K_5?0====UVNYUQQQ +MD\FJR:2=C&,8QC&,9A0PO%\?(RTB,3B,1=[P04%HS=3JOU_B/&<='+7]^]G1 +MNWSH+[I$R9,2F3)CUBP\]>P8GGGGGGGGVRV6SOJ)R4$($+(7 +MD*W"G15[P*[E?KX_GXG6=;E*&YGY)9>'8/7_A!!))).I#M`:JA5YJUUO(]7Z;A?$AZK&=IX.'GO +M4O.O//=T+N+DP+GHP+7A@6M:YUKRHB$K+X^0$1:-VW:4=1T&?K^8W+?/O]=I +M7N.[7#U3SSSSV06NB*5>K/0M>JN^M:UK7$=I0($(D(QA"1$9;M'!^_=0(`M? +M%L_IS/9[O51WS[]Y`A`=Z(0@[_STIV0T\.".9M%&!K6M:UM#6MHC*R +M^/D!:D$HXN>4X[>;7(3?W_IB+79P-YGQWGG7GJI8M."J26:J*JJJJJJJJK?0 +M0.$@@6,L2A42C2T]C,;84X]_FI5.YG]T_X?^:+.Z?35ZNWJKSRKT/0R5;HD@L@R*&?I^E[*O3\Q14Q(!ID`-QU'R:4IFM9HILTMZ72^C==;=;==UGAR;;;:.;K=MKL&CE\43;[?;[?/)GS +MY\^?/=I`0"$@A*4$PE"!`XE")A(&@U +M$IX,PN7;FEAU-6[JX1.'#APX<.'#APX<-T,"02D0($I0`!"@K"!!0$$$,%@! +MSN4@*0\&B^O%LN-QW.-O:&T1UM.G+##![P.6J284Y6L6G`<<<<<<<<<<<NY4,E2I4O$ +M`Y6G.A4ZM:N------------BP4`.!H^0$(\'X?P;\Y04%HKHY[/;[^+F>:TS +M*<31MW;?[^G_GM=AZ;3T]/3TKFGIZ>GRQ_Z:(Z*H*,F6G1HT:-&C1AT5:-%1 +M$:!\@(2T@Y3^3TD:1LW`?8U.2_MV?D\KX6JBWY7/?\=<==C&,9+&R>Y$QC&,8QC& +M,[80!&1F`*R`A(B0]]O*+%BQ8I!`1$0X( +M`PE\?(!X(A((`]@A`*H'7]?W'C\KS7UN^Q132(*F-R7I;'[%E++.0+,[.O9> +MRS,W.O@(!"E*4I2E*5J"*$"B\7Q\D)#J%:02GY^SQ[9Q?NN`BZ'E^=_>ZZZZ +MN*)<"Y9IUK6M:UK7-E@$D`HOCY`6D1D9P5GTNE3`%C#!_7&X[\T>9J.C1\W9 +MVZEQCT@DDD@F/`Q4J7PABU4"C6I"F8VKJJJPKI=+ +M[\7]?/GSDU\,8QC,!`"9R^/D!LFRR +M%Q'+I>C^"Z\\\]\D]&?1%ZFI!.N6:=:UK6N1:UKQ(@%E\?( +M"U]WH)!WU7I?"U_U>:MH]^-*::;L=,,4?SD"$(155555555555.2$@X5$!"1 +M#T@F3FO>>YZK7[#M6,T]03\A[9^IX'X;SSSW[2V(!"$"$1"4(!`#)Y[UZ272 +MFI6M:UK6M:\2(R,6/@G"!!,-!!ULSU.^3`S#[?T[=3LW>8WZ%)*RN+]6#))) +M())@P*7*"E92UPVCJ^;_7M& +MU\IM_2:_)[K&>%(E2I;N&8V0XYBM6P5&+E[`PPPPPPPLRR0`19@/P/X0`$#0 +M0#\'UPAJ:EKGA^)3NNY\*E*:7"8V5>TLF_E:6EI:6EI:6EI:7**GZ2IY*IVJ +MI\I4T53I[?SM_RWF8V0LG;RC1^[S[SB)K_V-+2UOP?!I;U_&D^.9RO!V_D<+,KG?3*>'E_2GORR+W2S?:)62U0T?LI,Q[= +M_X.CL.^P\&"R^TQOV)E_GK+%I.]]X>#TV%/Z?YTMVI)@[T>CK1,3^6$38=._ +M^_![]]??'1Z.Z71FHGI1KMM3A]$8PZDKTZBC_7,Q'H_?BKU9[9I]#?:MQ;7[9^^"*8IO!^H)]?8&_7[!;;T6=FSVLE3XNIN^G-Z.Q^W]?VAG=H +M;Z?]AWI-Y["GWVW)&[_]E4%'0_@F<%K=>I[D%';G:ZV-P-5?;957'C1MQ\WZ +MH=[(R,K>]_O]%(9R^9/"2S7]S/?QU78^4W:!;]7R^G7Y?\>NXW'T])W!SRKW +M9Y'C^KW[^LK/S?N-\+(1#8#52N$PF?XEYDX!ZUQ$KB.RVN6NA^K>CR2=-M.Q +M%<&AO=YN-5L-!Q^=2Z_B?W#=;S7^9[>(_910[90]T\;=M]V*%5U-1=*W_;A] +M,0_<__PE$=DO:7]5%_W6V)XG6]V`A]A_65VWW_!)=+OXC[=B'Z-_@9N%DNE% +M^BX4S=KQ-!@)3">/K[CW +M9+=6>D\,[F57GU>&ZEER*/!4\FF_]^KT\F][^.%Q\;K\*JEZW(X/C^;$YX7E +MR]M_/ST%-/QD9_&"Y'*R6)Q.0ONE[UOH_HN70N.A?QRK7CNQ!;[*3>UM?74H +M:QY089IP^>=A;M-:OZ\N8F'JF:_>NX>F\>*7YK0:"\]3\M\IW5=1G_G +M\IO=:E?+Q>+QY;;U/M*[S(YF5J-# +ML+7MOK%WN][.+C[QO^QJZ55];Y5J:B/ZC\F92,CLZ`[3W#D]K^9"EF#M+G9`[;S3 +MNUYOA>7R[VU^4MJ7I,*6C-0\/G28KLZS,]SKFZ]]E +M_3RN)@HJ*BGMEY<%.Q.*\'LU+B)W6ZOKJ9CNA]25GIJ[0+E_WQ=)U8Z>M)-M +M]M:ZYM\P/_NL?U3[Q_,[H/W\/QEJ+TIO[EZCJ];JW;:X_X"RG7G[CZ^%%[/[ +MZK>ZM-BF"I5'P]YK\93]AI +MPL-U>2@^_)]^?@A:+/X/+04%L:_R5\W\Y'*:Z][PFS_-E@LEVO#TL5+,,EV^ +MSD];NKFWX=]F+S0PMJL7R]+QFU[[/Y?LR)QV[QR>$N_MNFUM]=;Y65EO)75E +MWI-4JJ]7(5M7L?5CMI)[OO=RYOK7(Y7-9KQOM'%M]-14G-_KYYW.R_^V.OK^ +M+L^?P.3_'#7R4IL779?>D^OM>[W5NMV>4;F0A\]3:=OUL;]MGFO!<-=A"+7_ +MO)?M_O]1T//I?=(8>Q\WI7[E\LDQ/U:GP^W:?%\KZ[@[;N6G(2DI<92FUUXV +MSS.OU'SH*7LT%4/T-QX^/DT.='Y11S^NO4J5N`P&$Y75DF5&*"%IH*:M^7H< +M'Q^!8.98+!W?-+SXU%+&[C[676<.1^"I5[R: +M+[9OSWPRG>ZFRL4T]3G<[EN6^DU&X=3V@GMS?9#66;FEVPDF>X/=M% +M-/G]9[>?-ANQ>9Z$J$W6W$YB:9C#;S&XW?[6T]N)M/;K^4PZGP:-/WV6/IOY +M)HK)S\FPU+!A2S_8ZO0O_(7K_)]=!@.1U:11K2U'FH:',N/IA=._+GZCX-JL +M?.O%,GO.I]5D^,7.T\B3M+4YG&+SET.T^?Q)K]+4U$TUU$'$1$!=ZOF1TM]5 +M>V^&OLORXFUO:U*JOB:/2[#Z<3B1=9>W[&T9T?'^>_4.M\^0OSBOD<: +MFLWASF^B^_D>KR/Y35UW;>5WBLIAZ'@='[;'V>7^K/AM9?$W;^5Y:M2?31_MLM)?-MYL[\;)C\?F[)@=#3\&BW:K`]21;[!!5EM)Z]QO9Q154.Q +MH[V:HN\EBNCOOI_--KO+GY&1KNW(QIN@Z=/M]P]M_(Y":RN=#F\KS)B1XO(W +M=GJBL/E,CRF@MEZG^XQ[RNGRW)7K]*#(BY4$1U +M(C_>)$#V[>6E>[SO^W@=[>(2_(\J3VW$0XUIE]73:[+;^RY7-79\.D)7+T7' +M\[YSIZ_^Z\2'+\>2]OB^U]UTLGAX=1-8>C9,O72YOXX"3DYN3DY:K?]9'>#N +M/Z[T\"9SWA'F^W(_Y=L9=[>TB(3M\:U8N,A(2W=H?W\2*BA_^]^KUTK->_)_ +MC`9SP:NARGSMB$I\[D^PQIMU:RV\O-2.I=NTKMWEG;B8DY=W:[6[=N[3@79Y +MTP[QCMV[/O5J=WNR63'.W>"4.XAV[B'<1=W<0.[=NU]PM.>=CX;&0CMV[=NW +M;O*VEWG)5V[=V7`N\N^'2#N[XAWF7QV[N[O)2#MW?G>0R+MV[3P\.HP\Q,,F +M3MWFW>`DY.7DY-V[?W<<[=OZZ;=N\\['=NY'*W;&7>WM(B$=N[5BXR$A+<[' +M=S,5%#NW;MW*S3O)YK`.W;MWE'=L=RCNY/L,:;?.7_OD\!DXL$Z=CUF4CEGB +MN[;].+ZHW!7]V<(0@#_,4(``88!@YF_U7YO'#Z/SFYA5!75KVZ!J_3.(E(&^ +M8_8T&J_5IH)/B]=C'9]0QL=%K.,Z\7T^67O^ZVG7TWCAO1/S>XJ)JS3BV'U$ +MWN-0HLHLIQF?+P^]YO\_([R\^IU7"T%3ZHZIY'`MR;BU.XIG3JVK&SHUTZ=. +MG3HMTZ=.GYTZ50+I>Z=2=J=7!TZ=-G4:H8V-TZ=.G3ITZ=.KBZ=.H9TZ=.G3 +MJS.EL.Z=.G2BRNG3IFZ=.G3ITNNWF\WF\Y;DN.IB4G.I +M[<($BQ)"$)!DDDM4$`)EX#U79SU<9X/7WG99Z"QF14`LJ3,Q2K%4496*99BE*4I7W(NY(IPH2'>']) +!"$Q# +` +end diff --git a/contrib/netbsd-tests/usr.bin/shmif_dumpbus/t_basic.sh b/contrib/netbsd-tests/usr.bin/shmif_dumpbus/t_basic.sh new file mode 100755 index 0000000..10fea10 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/shmif_dumpbus/t_basic.sh @@ -0,0 +1,86 @@ +# $NetBSD: t_basic.sh,v 1.8 2013/04/07 19:14:03 christos Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +unpack_file() +{ + + atf_check -s exit:0 uudecode $(atf_get_srcdir)/${1}.bz2.uue + atf_check -s exit:0 bunzip2 -f ${1}.bz2 +} + +test_case() +{ + local name="${1}"; shift + + atf_test_case "${name}" + eval "${name}_head() { }" + eval "${name}_body() { \ + unpack_file shmbus ; \ + ${name} ; \ + }" +} + +test_case header +test_case contents +test_case pcap + +ehdr='bus version 2, lock: 0, generation: 22, firstoff: 0x9e414, lastoff: 0x9dfd0' + +header() +{ + + atf_check -s exit:0 -o inline:"${ehdr}\n" shmif_dumpbus -h shmbus +} + +contents() +{ + + unpack_file d_pkthdrs.out + atf_check -s exit:0 -o file:d_pkthdrs.out \ + shmif_dumpbus shmbus +} + +pcap() +{ + + unpack_file d_pcap.out + atf_check -s exit:0 -o ignore shmif_dumpbus -p pcap shmbus +# +# should not fail anymore... +# +# Used to fail for "PR bin/44721" + atf_check -s exit:0 -o file:d_pcap.out -e ignore \ + tcpdump -tt -r pcap +} + +atf_init_test_cases() +{ + + atf_add_test_case header + atf_add_test_case contents + atf_add_test_case pcap +} diff --git a/contrib/netbsd-tests/usr.bin/sort/d_any_char_dflag_out.txt b/contrib/netbsd-tests/usr.bin/sort/d_any_char_dflag_out.txt new file mode 100644 index 0000000..610c470 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sort/d_any_char_dflag_out.txt Binary files differ diff --git a/contrib/netbsd-tests/usr.bin/sort/d_any_char_fflag_out.txt b/contrib/netbsd-tests/usr.bin/sort/d_any_char_fflag_out.txt new file mode 100644 index 0000000..2bfbda8 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sort/d_any_char_fflag_out.txt Binary files differ diff --git a/contrib/netbsd-tests/usr.bin/sort/d_any_char_iflag_out.txt b/contrib/netbsd-tests/usr.bin/sort/d_any_char_iflag_out.txt new file mode 100644 index 0000000..99d3ae6 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sort/d_any_char_iflag_out.txt Binary files differ diff --git a/contrib/netbsd-tests/usr.bin/sort/d_any_char_in.txt b/contrib/netbsd-tests/usr.bin/sort/d_any_char_in.txt new file mode 100644 index 0000000..5963fca --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sort/d_any_char_in.txt Binary files differ diff --git a/contrib/netbsd-tests/usr.bin/sort/t_sort.sh b/contrib/netbsd-tests/usr.bin/sort/t_sort.sh new file mode 100755 index 0000000..a36457c --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/sort/t_sort.sh @@ -0,0 +1,1023 @@ +# $NetBSD: t_sort.sh,v 1.1 2012/03/17 16:33:15 jruoho Exp $ +# +# Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() +{ + atf_set "descr" "Basic functionality test" +} +basic_body() +{ + cat >in <expout <-k + atf_check -o file:-k -x "sort -S -- -k in + atf_check -o inline:'x\n' sort in +} + +atf_test_case null_bytes +null_bytes_head() +{ + atf_set "descr" "Tests the behavior of null bytes" +} +null_bytes_body() +{ + printf '\0b\n\0a\n' >in + atf_check -o inline:'\0a\n\0b\n' sort -S in +} + +atf_test_case long_records +long_records_head() +{ + atf_set "descr" "Tests long lines and keys" +} +long_records_body() +{ + awk 'BEGIN { x="x" + for(i=1; i<=12; i++) x = x x + for(i=15; i<=25; i++) print x i +}' >in + + awk 'BEGIN { x="x" + for(i=1; i<=12; i++) x = x x + for(i=25; i>=15; i--) print x i +}' >out + + atf_check -o file:out sort -r in + atf_check -o file:out sort -k 1,1r -k 1 in +} + +atf_test_case long_file +long_file_head() +{ + atf_set "descr" "Tests with a long file to try to force intermediate" \ + "files" +} +long_file_body() +{ + awk 'BEGIN { for(i=0; i<20000; i++) print rand() }' >in + sort -S -r in | awk '$0 "x" != x { print ; x = $0 "x" }' >out + atf_check -o file:out sort -u -r in +} + +atf_test_case any_char +any_char_head() +{ + atf_set "descr" "Tests with files containing non-printable/extended" \ + "characters" +} +any_char_body() +{ + atf_check -o file:$(atf_get_srcdir)/d_any_char_dflag_out.txt \ + sort -d -k 2 $(atf_get_srcdir)/d_any_char_in.txt + + atf_check -o file:$(atf_get_srcdir)/d_any_char_fflag_out.txt \ + sort -f -k 2 $(atf_get_srcdir)/d_any_char_in.txt + + atf_check -o file:$(atf_get_srcdir)/d_any_char_iflag_out.txt \ + sort -i -k 2 $(atf_get_srcdir)/d_any_char_in.txt +} + +atf_test_case bflag +bflag_head() +{ + atf_set "descr" "Tests the -b flag" +} +bflag_body() +{ + cat >in <in <in <expout <in <expout <in <out <in <in <in <out <in <xx" + atf_check -e ignore sort -c -t: -k2n xx + + atf_check -x "sort -S -k2,2.1b -k2 in >xx" + atf_check -e ignore sort -c -t: -k3n xx + + atf_check -x "sort -S -k2.3 -k2 in >xx" + atf_check -e ignore sort -c -t: -k4n xx + + atf_check -x "sort -S -k2b,2.3 -k2 in >xx" + atf_check -e ignore sort -c -t: -k5n xx + + atf_check -x "sort -S -k2.3,2.1b -k2 in >xx" + atf_check -e ignore sort -c -t: -k6n xx + + atf_check -x "sort -S -k2,2.1b -k2r in >xx" + atf_check -e ignore sort -c -t: -k7n xx + + atf_check -x "sort -S -b -k2,2 -k2 in >xx" + atf_check -e ignore sort -c -t: -k8n xx + + # XXX This test is broken. The standard is not clear on the behavior. + #atf_check -x "sort -S -b -k2,2b -k2 in >xx" + #atf_check -e ignore sort -c -t: -k3n xx +} + +atf_test_case kflag_no_end +kflag_no_end_head() +{ + atf_set "descr" "Tests the -k flag with a field without end" +} +kflag_no_end_body() +{ + cat >in <out <in1 <in2 <out <in <in <out <in <expout <in <expout <in <expout <in <expout <in <out <in1 <in2 <out <in <in <in <out <in <out <out <out <in <expout <in <expout <in <expout <in <expout <./+0 + + atf_check -o file:+0 sort -- +0 +} + +atf_test_case plus_nonmonotone +plus_nonmonotone_head() +{ + atf_set "descr" "Tests += addressing: apparently nonmonotone field" \ + "specs" +} +plus_nonmonotone_body() +{ + cat >in <./+0 + echo 'more contents' >in + cat ./+0 in >expout + + atf_check -o file:expout sort in +0 +} + +atf_test_case plus_bad_tempfile +plus_bad_tempfile_head() +{ + atf_set "descr" "Tests +- addressing: intermediate wrong behavior" \ + "that raised a '+0: No such file or directory' error" +} +plus_bad_tempfile_body() +{ + echo 'good contents' >in + atf_check -o file:in sort -T /tmp +0 in +} + +atf_test_case plus_rflag_invalid +plus_rflag_invalid_head() +{ + atf_set "descr" "Tests +- addressing: invalid record delimiter" +} +plus_rflag_invalid_body() +{ + ( + echo 'z b m f' + echo 'y c o e' + echo 'x a n h' + echo 'x a n g' + ) | tr '\n' '+' >in + + atf_check -o inline:'x a n g+x a n h+z b m f+y c o e+' \ + sort -R + -k2 in +} + +atf_test_case plus_tflag +plus_tflag_head() +{ + atf_set "descr" "Tests +- addressing: using -T caused a 'No such file" \ + "or directory' error" +} +plus_tflag_body() +{ + mkdir ./+ + yes | sed 200000q | sort -T + >/dev/null || atf_fail "program failed" +} + +atf_test_case plus_no_end +plus_no_end_head() +{ + atf_set "descr" "Tests +- addressing: field without end" +} +plus_no_end_body() +{ + cat >in <out </dev/null 2>&1" +} + +atf_test_case stdin +stdin_head() { + atf_set "descr" "Test that tmux(1) does not crash the system " \ + "when stdin(4) is closed (PR kern/46463)" +} + +stdin_body() { + stdincrash +} + +atf_init_test_cases() +{ + atf_add_test_case stdin +} diff --git a/contrib/netbsd-tests/usr.bin/tr/t_basic.sh b/contrib/netbsd-tests/usr.bin/tr/t_basic.sh new file mode 100755 index 0000000..4515d11 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/tr/t_basic.sh @@ -0,0 +1,195 @@ +# $NetBSD: t_basic.sh,v 1.3 2013/08/11 01:50:02 dholland Exp $ +# +# Copyright (c) 2013 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by David A. Holland. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# +# tr -d: delete character +# +atf_test_case dopt +dopt_head() { + atf_set "descr" "Tests for tr -d" +} + +dopt_body() { + atf_check -o inline:'abcde\n' -x 'echo abcde | tr -d x' + atf_check -o inline:'abde\n' -x 'echo abcde | tr -d c' + atf_check -o inline:'ace\n' -x 'echo abcde | tr -d bd' + atf_check -o inline:'ae\n' -x 'echo abcde | tr -d b-d' + atf_check -o inline:'b\n' -x 'echo abcde | tr -d ac-e' + atf_check -o inline:'d\n' -x 'echo abcde | tr -d a-ce' + atf_check -o inline:'aei\n' -x 'echo abcdefghi | tr -d b-df-h' + + atf_check -o inline:'' -x 'echo abcde | tr -c -d x' + atf_check -o inline:'c' -x 'echo abcde | tr -c -d c' + atf_check -o inline:'bd' -x 'echo abcde | tr -c -d bd' + atf_check -o inline:'bcd' -x 'echo abcde | tr -c -d b-d' + atf_check -o inline:'acde' -x 'echo abcde | tr -c -d ac-e' + atf_check -o inline:'abce' -x 'echo abcde | tr -c -d a-ce' + atf_check -o inline:'bcdfgh' -x 'echo abcdefghi | tr -c -d b-df-h' + + # see if escape codes work + atf_check -o inline:'splice' -x '(echo spl; echo ice) | tr -d '"'\n'" + atf_check -o inline:'splice' -x '(echo spl; echo ice) | tr -d '"'\012'" + + # see if escape codes work when followed by other things + atf_check -o inline:'slice' -x '(echo spl; echo ice) | tr -d '"'\n'p" + atf_check -o inline:'slice' -x '(echo spl; echo ice) | tr -d '"'\012'p" + + # see if the [=x=] syntax works + atf_check -o inline:'abde\n' -x 'echo abcde | tr -d '"'[=c=]'" + atf_check -o inline:'bde\n' -x 'echo abcde | tr -d '"'[=c=]'a" + + # make sure 0 works + # (ignore stderr as dd blabbers to it) + atf_check -e ignore -o inline:'ab\n' \ + -x '(echo -n a; dd if=/dev/zero bs=3 count=1; echo b) | tr -d '"'\0'" + + # test posix classes + atf_check -o inline:'.\n' -x 'echo aAzZ.123 | tr -d '"'[:alnum:]'" + atf_check -o inline:'.123\n' -x 'echo aAzZ.123 | tr -d '"'[:alpha:]'" + atf_check -o inline:'az\n' -x 'echo "a z" | tr -d '"'[:blank:]'" + atf_check -o inline:'az' -x '(echo a; echo z) | tr -d '"'[:cntrl:]'" + atf_check -o inline:'aAzZ.\n' -x 'echo aAzZ.123 | tr -d '"'[:digit:]'" + atf_check -o inline:' \n' -x 'echo "a z.123" | tr -d '"'[:graph:]'" + atf_check -o inline:'AZ.123\n' -x 'echo aAzZ.123 | tr -d '"'[:lower:]'" + atf_check -o inline:'\n' -x 'echo aAzZ.123 | tr -d '"'[:print:]'" + atf_check -o inline:'aAzZ12\n' -x 'echo aAzZ.12 | tr -d '"'[:punct:]'" + atf_check -o inline:'az' -x 'echo "a z" | tr -d '"'[:space:]'" + atf_check -o inline:'az.123\n' -x 'echo aAzZ.123 | tr -d '"'[:upper:]'" + atf_check -o inline:'zZ.\n' -x 'echo aAzZ.123 | tr -d '"'[:xdigit:]'" +} + +# +# tr -s: squeeze duplicate character runs +# +atf_test_case sopt +sopt_head() { + atf_set "descr" "Tests for tr -s" +} + +sopt_body() { + atf_check -o inline:'abcde\n' -x 'echo abcde | tr -s x' + atf_check -o inline:'abcde\n' -x 'echo abcde | tr -s c' + atf_check -o inline:'abcde\n' -x 'echo abccccde | tr -s c' + atf_check -o inline:'abcde\n' -x 'echo abbbcddde | tr -s bd' + atf_check -o inline:'abcde\n' -x 'echo abbbcccddde | tr -s b-d' + + atf_check -o inline:'acac\n' -x 'echo acac | tr -s c' + atf_check -o inline:'acac\n' -x 'echo accacc | tr -s c' + + atf_check -o inline:'abcde\n' -x 'echo abcde | tr -c -s x' + atf_check -o inline:'abcde\n' -x 'echo abcde | tr -c -s c' + atf_check -o inline:'abcccde\n' -x 'echo abcccde | tr -c -s c' + atf_check -o inline:'abbbcddde\n' -x 'echo abbbcddde | tr -c -s bd' + atf_check -o inline:'abbbccddde\n' -x 'echo abbbccddde | tr -c -s b-d' + atf_check -o inline:'abcccde\n' -x 'echo aaabcccde | tr -c -s b-d' +} + +# +# tr -ds: both -d and -s at once +# +atf_test_case dsopt +dsopt_head() { + atf_set "descr" "Tests for tr -ds" +} + +dsopt_body() { + atf_check -o inline:'abcde\n' -x 'echo abcde | tr -ds x y' + atf_check -o inline:'abde\n' -x 'echo abcde | tr -ds c x' + atf_check -o inline:'abcde\n' -x 'echo abcde | tr -ds x c' + atf_check -o inline:'abde\n' -x 'echo abcde | tr -ds c c' + atf_check -o inline:'abde\n' -x 'echo abcccde | tr -ds c x' + atf_check -o inline:'abcde\n' -x 'echo abcccde | tr -ds x c' + atf_check -o inline:'abde\n' -x 'echo abcccde | tr -ds c c' + + # -c complements only the first string + atf_check -o inline:'' -x 'echo abcde | tr -c -ds x y' + atf_check -o inline:'c' -x 'echo abcde | tr -c -ds c x' + atf_check -o inline:'' -x 'echo abcde | tr -c -ds x c' + atf_check -o inline:'c' -x 'echo abcde | tr -c -ds c c' + atf_check -o inline:'ccc' -x 'echo abcccde | tr -c -ds c x' + atf_check -o inline:'' -x 'echo abcccde | tr -c -ds x c' + atf_check -o inline:'c' -x 'echo abcccde | tr -c -ds c c' +} + +# +# test substitution +# +atf_test_case subst +subst_head() { + atf_set "descr" "Tests for tr substitution" +} + +subst_body() { + atf_check -o inline:'abcde\n' -x 'echo abcde | tr a-c a-c' + atf_check -o inline:'cbade\n' -x 'echo abcde | tr a-c cba' + atf_check -o inline:'abcde\n' -x 'echo abcde | tr a-z a-z' + atf_check -o inline:'bcdef\n' -x 'echo abcde | tr a-z b-za' + atf_check -o inline:'zabcd\n' -x 'echo abcde | tr b-za a-z' + atf_check -o inline:'bbbbb\n' -x 'echo ababa | tr a b' + atf_check -o inline:'furrfu\n' -x 'echo sheesh | tr a-z n-za-m' + atf_check -o inline:'furrfu\n' -x 'echo sheesh | tr n-za-m a-z' + + atf_check -o inline:'ABCDE\n' -x 'echo abcde | tr a-z A-Z' + atf_check -o inline:'ABC\n' \ + -x 'echo abc | tr '"'[:lower:]' '[:upper:]'" + + # If you don't give enough substitution chars the last is repeated. + atf_check -o inline:'bozoo\n' -x 'echo abcde | tr a-z bozo' + atf_check -o inline:'qaaaa\n' -x 'echo abcde | tr a-z qa' + + # You can use -s with substitution. + atf_check -o inline:'cbade\n' -x 'echo abcde | tr -s a-c cba' + atf_check -o inline:'cbaddee\n' -x 'echo aabbccddee | tr -s a-c cba' +} + +# +# test substitution with -c (does not currently work) +# +atf_test_case csubst +csubst_head() { + atf_set "descr" "Tests for tr substitution with -c" +} + +csubst_body() { + atf_check -o inline:'abcde\n' -x \ + 'echo abcde | tr -c '"'\0-ac-\377' b" + atf_check -o inline:'abcde\n' -x \ + 'echo abcde | tr -c '"'\0-ad-\377' bc" + atf_check -o inline:'QUACK\n' -x \ + 'echo ABCDE | tr -c '"'\0-@' QUACK" +} + +atf_init_test_cases() { + atf_add_test_case dopt + atf_add_test_case sopt + atf_add_test_case dsopt + atf_add_test_case subst + atf_add_test_case csubst +} diff --git a/contrib/netbsd-tests/usr.bin/unifdef/d_basic.in b/contrib/netbsd-tests/usr.bin/unifdef/d_basic.in new file mode 100644 index 0000000..9de6a94 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/unifdef/d_basic.in @@ -0,0 +1,25 @@ +#if defined(__FreeBSD__) +#include +#else +#include +#endif + +#if defined(__FreeBSD__) + #include + #include + #include + #include + #include + #include +#else +#include +#endif + +#if defined(__FreeBSD__) +#endif + +#ifdef __FreeBSD__ +#include +#else +#include +#endif diff --git a/contrib/netbsd-tests/usr.bin/unifdef/d_basic.out b/contrib/netbsd-tests/usr.bin/unifdef/d_basic.out new file mode 100644 index 0000000..2d52e9e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/unifdef/d_basic.out @@ -0,0 +1,6 @@ +#include + +#include + + +#include diff --git a/contrib/netbsd-tests/usr.bin/unifdef/t_basic.sh b/contrib/netbsd-tests/usr.bin/unifdef/t_basic.sh new file mode 100755 index 0000000..43ca280 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/unifdef/t_basic.sh @@ -0,0 +1,62 @@ +# $NetBSD: t_basic.sh,v 1.6 2012/10/15 17:49:58 njoly Exp $ +# +# Copyright (c) 2011 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() { + atf_set "descr" "A basic test of unifdef(1) (PR bin/42628)" + atf_set "require.progs" "unifdef" +} + +basic_body() { + + atf_check -s ignore -o file:$(atf_get_srcdir)/d_basic.out \ + -x "unifdef -U__FreeBSD__ $(atf_get_srcdir)/d_basic.in" +} + +atf_test_case lastline +lastline_head() { + atf_set "descr" "Checks with directive on last line (PR bin/47068)" +} + +lastline_body() { + + # With newline after cpp directive + printf '#ifdef foo\n#endif\n' >input + atf_check -o file:input unifdef -Ubar input + + # Without newline after cpp directive + printf '#ifdef foo\n#endif' >input + atf_check -o file:input unifdef -Ubar input +} + +atf_init_test_cases() { + atf_add_test_case basic + atf_add_test_case lastline +} diff --git a/contrib/netbsd-tests/usr.bin/uniq/d_basic.in b/contrib/netbsd-tests/usr.bin/uniq/d_basic.in new file mode 100644 index 0000000..52a24bc --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/uniq/d_basic.in @@ -0,0 +1,4 @@ +1 +12 +1 +1 diff --git a/contrib/netbsd-tests/usr.bin/uniq/d_basic.out b/contrib/netbsd-tests/usr.bin/uniq/d_basic.out new file mode 100644 index 0000000..d44fcba --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/uniq/d_basic.out @@ -0,0 +1,3 @@ +1 +12 +1 diff --git a/contrib/netbsd-tests/usr.bin/uniq/d_counts.out b/contrib/netbsd-tests/usr.bin/uniq/d_counts.out new file mode 100644 index 0000000..bb1c86b --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/uniq/d_counts.out @@ -0,0 +1,6 @@ + 1 #01 foo0 bar0 foo1 bar1 + 1 #02 bar0 foo1 bar1 foo1 + 1 #03 foo0 bar0 foo1 bar1 + 1 #04 + 2 #05 foo0 bar0 foo1 bar1 + 1 #07 bar0 foo1 bar1 foo0 diff --git a/contrib/netbsd-tests/usr.bin/uniq/d_input.in b/contrib/netbsd-tests/usr.bin/uniq/d_input.in new file mode 100644 index 0000000..c32c44d --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/uniq/d_input.in @@ -0,0 +1,7 @@ +#01 foo0 bar0 foo1 bar1 +#02 bar0 foo1 bar1 foo1 +#03 foo0 bar0 foo1 bar1 +#04 +#05 foo0 bar0 foo1 bar1 +#06 foo0 bar0 foo1 bar1 +#07 bar0 foo1 bar1 foo0 diff --git a/contrib/netbsd-tests/usr.bin/uniq/d_show_duplicates.out b/contrib/netbsd-tests/usr.bin/uniq/d_show_duplicates.out new file mode 100644 index 0000000..45f4be7 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/uniq/d_show_duplicates.out @@ -0,0 +1 @@ +#05 foo0 bar0 foo1 bar1 diff --git a/contrib/netbsd-tests/usr.bin/uniq/d_show_uniques.out b/contrib/netbsd-tests/usr.bin/uniq/d_show_uniques.out new file mode 100644 index 0000000..1cc2ecb --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/uniq/d_show_uniques.out @@ -0,0 +1,5 @@ +#01 foo0 bar0 foo1 bar1 +#02 bar0 foo1 bar1 foo1 +#03 foo0 bar0 foo1 bar1 +#04 +#07 bar0 foo1 bar1 foo0 diff --git a/contrib/netbsd-tests/usr.bin/uniq/t_uniq.sh b/contrib/netbsd-tests/usr.bin/uniq/t_uniq.sh new file mode 100755 index 0000000..d90a4d5 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/uniq/t_uniq.sh @@ -0,0 +1,97 @@ +# $NetBSD: t_uniq.sh,v 1.1 2016/10/22 14:13:39 abhinav Exp $ +# +# Copyright (c) 2016 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Abhinav Upadhyay +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case basic +basic_head() +{ + atf_set "descr" "Checks the basic functionality" +} +basic_body() +{ + atf_check -o file:$(atf_get_srcdir)/d_basic.out uniq \ + $(atf_get_srcdir)/d_basic.in +} + +atf_test_case test_counts +test_counts_head() +{ + atf_set "descr" "Tests the -c option, comparing each line of the input" \ + "file data starting from the second field" +} +test_counts_body() +{ + atf_check -o file:$(atf_get_srcdir)/d_counts.out uniq -c -f 1 \ + $(atf_get_srcdir)/d_input.in +} + +atf_test_case show_duplicates +show_duplicates_head() +{ + atf_set "descr" "Checks the -d option, comparing each line of the input" \ + "file data starting from the second field" +} +show_duplicates_body() +{ + atf_check -o file:$(atf_get_srcdir)/d_show_duplicates.out uniq -d -f 1 \ + $(atf_get_srcdir)/d_input.in +} + +atf_test_case show_uniques +show_uniques_head() +{ + atf_set "descr" "Checks the -u option, comparing each line of the input" \ + "file data starting from the second field" +} +show_uniques_body() +{ + atf_check -o file:$(atf_get_srcdir)/d_show_uniques.out uniq -u -f 1 \ + $(atf_get_srcdir)/d_input.in +} + +atf_test_case show_duplicates_from_third_character +show_duplicates_from_third_character_head() +{ + atf_set "descr" "Checks the -d option, comparing each line of the input" \ + "file data starting from the third character (-s option)" +} +show_duplicates_from_third_character_body() +{ + atf_check -o empty uniq -d -s 2 $(atf_get_srcdir)/d_input.in + +} + +atf_init_test_cases() +{ + atf_add_test_case basic + atf_add_test_case test_counts + atf_add_test_case show_duplicates + atf_add_test_case show_uniques + atf_add_test_case show_duplicates_from_third_character +} diff --git a/contrib/netbsd-tests/usr.bin/vmstat/t_vmstat.sh b/contrib/netbsd-tests/usr.bin/vmstat/t_vmstat.sh new file mode 100755 index 0000000..6676900 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/vmstat/t_vmstat.sh @@ -0,0 +1,48 @@ +# $NetBSD: t_vmstat.sh,v 1.1 2014/01/07 16:47:13 gson Exp $ +# +# Copyright (c) 2013 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +atf_test_case default +default_head() { + atf_set "descr" "Test that vmstat(1) returns success when run with no arguments" +} +default_body() { + atf_check -s exit:0 -o ignore -e empty vmstat +} + +atf_test_case opt_s +opt_s_head() { + atf_set "descr" "Test that vmstat(1) returns success when run with -s (PR 44518)" +} +opt_s_body() { + atf_check -s exit:0 -o ignore -e empty vmstat -s +} + +atf_init_test_cases() +{ + atf_add_test_case default + atf_add_test_case opt_s +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_alignof.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_alignof.c new file mode 100644 index 0000000..4a66134 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_alignof.c @@ -0,0 +1,6 @@ +/* __alignof__ */ +int +main(void) +{ + return __alignof__(short); +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_anon_struct.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_anon_struct.c new file mode 100644 index 0000000..367b56f --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_anon_struct.c @@ -0,0 +1,26 @@ +/* Anonymous struct test */ + +typedef int type; + +struct point { + int x; + int y; +}; + +struct bar { + struct { + struct point top_left; + struct point bottom_right; + }; + type z; +}; + + +int +main(void) +{ + struct bar b; + b.top_left.x = 1; + return 0; +} + diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_anon_union.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_anon_union.c new file mode 100644 index 0000000..508bcc9 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_anon_union.c @@ -0,0 +1,16 @@ +/* struct with only anonymous members */ + +struct foo { + union { + long loo; + double doo; + }; +}; + +int +main(void) { + + struct foo *f = 0; + printf("%p\n", &f[1]); + return 0; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_complex_num.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_complex_num.c new file mode 100644 index 0000000..c3c952e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_complex_num.c @@ -0,0 +1,7 @@ +double cabs(double _Complex); + +double cabs(double _Complex foo) +{ + double d = __real__ foo; + return d + 0.1fi; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_complex_split.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_complex_split.c new file mode 100644 index 0000000..7b3d1a1 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_complex_split.c @@ -0,0 +1,8 @@ +int b(double a) { + return a == 0; +} +void a(void) { + double _Complex z = 0; + if (b(__real__ z) && b(__imag__ z)) + return; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_compound_literal_comma.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_compound_literal_comma.c new file mode 100644 index 0000000..ca70694 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_compound_literal_comma.c @@ -0,0 +1,14 @@ +struct bintime { + unsigned long long sec; + unsigned long long frac; +}; + +struct bintime +us2bintime(unsigned long long us) +{ + + return (struct bintime) { + .sec = us / 1000000U, + .frac = (((us % 1000000U) >> 32)/1000000U) >> 32, + }; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_decls_after_stmt.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_decls_after_stmt.c new file mode 100644 index 0000000..f32a963 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_decls_after_stmt.c @@ -0,0 +1,5 @@ +void sample(void) +{ + int i = 0; i += 1; + int j = 0; j += 1; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_decls_after_stmt2.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_decls_after_stmt2.c new file mode 100644 index 0000000..960d392 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_decls_after_stmt2.c @@ -0,0 +1,6 @@ +typedef int int_t; +int main(void) { +int i = 0; i += 1; +int_t j = 0; j += 1; +return 0; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_decls_after_stmt3.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_decls_after_stmt3.c new file mode 100644 index 0000000..278fe1b --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_decls_after_stmt3.c @@ -0,0 +1,5 @@ +void sample(int i) +{ + i += 1; + int j = 0; j += 1; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_flex_array_packed.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_flex_array_packed.c new file mode 100644 index 0000000..e7b8756 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_flex_array_packed.c @@ -0,0 +1,6 @@ +/* Allow packed c99 flexible arrays */ +struct { + int x; + char y[0]; +} __packed foo; + diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_for_loops.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_for_loops.c new file mode 100644 index 0000000..48e380c --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_for_loops.c @@ -0,0 +1,15 @@ +/* c99 for loops */ +extern void foo(int); + +int +main(void) +{ + // Test the basic functionality + for (int i = 0; i < 10; i++) + foo(i); + + // Test that the scope of the iterator is correct + for (int i = 0; i < 10; i++) + continue; + return 0; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_func.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_func.c new file mode 100644 index 0000000..b827bfa --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_func.c @@ -0,0 +1,7 @@ +/* C99 __func__ */ + +void +foo(const char *p) { + p = __func__; + foo(p); +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_nested_struct.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_nested_struct.c new file mode 100644 index 0000000..15410c8 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_nested_struct.c @@ -0,0 +1,25 @@ +/* C99 nested struct init with named and non-named initializers */ +typedef struct pthread_mutex_t { + unsigned int ptm_magic; + char ptm_errorcheck; + + char ptm_pad1[3]; + + char ptm_interlock; + + char ptm_pad2[3]; + + volatile void * ptm_owner; + void * volatile ptm_waiters; + unsigned int ptm_recursed; + void *ptm_spare2; +} pthread_mutex_t; + + +struct arc4random_global { + + pthread_mutex_t lock; +} arc4random_global = { + + .lock = { 0x33330003, 0, { 0, 0, 0 }, 0, { 0, 0, 0 }, ((void *)0), ((void *)0), 0, ((void *)0) }, +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_recursive_init.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_recursive_init.c new file mode 100644 index 0000000..347644f --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_recursive_init.c @@ -0,0 +1,13 @@ +/* C99 recursive struct/union initialization */ +struct top { + int i; + char c; + union onion { + short us; + char uc; + } u; + char *s; +} c[] = { + { .s = "foo", .c = 'b', .u = { .uc = 'c' } }, + { .i = 1, .c = 'a', .u = { .us = 2 } }, +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_struct_init.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_struct_init.c new file mode 100644 index 0000000..a94cbd1 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_struct_init.c @@ -0,0 +1,10 @@ +/* C99 struct initialization */ +struct { + int i; + char *s; +} c[] = { + { .i = 2, }, + { .s = "foo" }, + { .i = 1, .s = "bar" }, + { .s = "foo", .i = -1 }, +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_cast.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_cast.c new file mode 100644 index 0000000..31628b4 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_cast.c @@ -0,0 +1,18 @@ +/* union cast */ + +struct bar { + int a; + int b; +}; + +union foo { + struct bar *a; + int b; +}; + +void +foo(void) { + struct bar *a; + + ((union foo)a).a; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_init1.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_init1.c new file mode 100644 index 0000000..0e1a1a8 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_init1.c @@ -0,0 +1,8 @@ +/* C99 union initialization */ +union { + int i; + char *s; +} c[] = { + { i: 1 }, + { s: "foo" } +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_init2.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_init2.c new file mode 100644 index 0000000..51d34d4 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_init2.c @@ -0,0 +1,8 @@ +/* C99 union initialization */ +union { + int i[10]; + short s; +} c[] = { + { s: 2 }, + { i: { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } }, +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_init3.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_init3.c new file mode 100644 index 0000000..f5e8b59 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_init3.c @@ -0,0 +1,8 @@ +/* C99 union initialization */ +struct { + int i[10]; + char *s; +} c[] = { + { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + "foo" }, +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_init4.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_init4.c new file mode 100644 index 0000000..f73b113 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c99_union_init4.c @@ -0,0 +1,15 @@ +/* test .data.l[x] */ +typedef struct { + int type; + union { + char b[20]; + short s[10]; + long l[5]; + } data; +} foo; + + +foo bar = { + .type = 3, + .data.l[0] = 4 +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c9x_array_init.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c9x_array_init.c new file mode 100644 index 0000000..66f0e9e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c9x_array_init.c @@ -0,0 +1,6 @@ +/* C9X array initializers */ +int foo[256] = { + [2] = 1, + [3] = 2, + [4 ... 5] = 3 +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c9x_recursive_init.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c9x_recursive_init.c new file mode 100644 index 0000000..df907cd --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_c9x_recursive_init.c @@ -0,0 +1,16 @@ +/* C9X struct/union member init, with nested union and trailing member */ +union node { + void *next; + char *data; +}; +struct foo { + int b; + union node n; + int c; +}; + +struct foo f = { + .b = 1, + .n = { .next = 0, }, + .c = 1 +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cast_fun_array_param.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cast_fun_array_param.c new file mode 100644 index 0000000..345c783 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cast_fun_array_param.c @@ -0,0 +1,9 @@ + +static void f(void *b[4]) { + (void)&b; +} + +void * +foo(void *fn) { + return fn == 0 ? f : (void (*)(void *[4])) fn; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cast_init.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cast_init.c new file mode 100644 index 0000000..36986e8 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cast_init.c @@ -0,0 +1,27 @@ +/* cast initialization */ +typedef unsigned char u_char; +typedef unsigned int size_t; +struct sockaddr_x25 { + u_char x25_len; + u_char x25_family; + short x25_net; + char x25_addr[16]; + struct x25opts { + char op_flags; + char op_psize; + char op_wsize; + char op_speed; + } x25_opts; + short x25_udlen; + char x25_udata[16]; +}; + +struct sockaddr_x25 x25_dgmask = { + (unsigned char)(unsigned char)(unsigned int)(unsigned long)(&((( struct sockaddr_x25 *)0)->x25_udata[1])) , + 0, + 0, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 0, 0, 0}, + -1, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cast_init2.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cast_init2.c new file mode 100644 index 0000000..9597d35 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cast_init2.c @@ -0,0 +1,7 @@ +/* cast initialization as the rhs of a - operand */ +struct sockaddr_dl { + char sdl_data[2]; +}; + +int npdl_datasize = sizeof(struct sockaddr_dl) - +((int) ((unsigned long)&((struct sockaddr_dl *) 0)->sdl_data[0])); diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cast_lhs.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cast_lhs.c new file mode 100644 index 0000000..eb86569 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cast_lhs.c @@ -0,0 +1,7 @@ +/* pointer casts are valid lhs lvalues */ +struct sockaddr { }; +void +foo() { + unsigned long p = 6; + ((struct sockaddr *)p) = 0; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_compound_literals1.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_compound_literals1.c new file mode 100644 index 0000000..cd1987a --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_compound_literals1.c @@ -0,0 +1,11 @@ +/* compound literals */ + +struct p { + short a, b, c, d; +}; + +foo() +{ + struct p me = (struct p) {1, 2, 3, 4}; + me.a = me.b; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_compound_literals2.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_compound_literals2.c new file mode 100644 index 0000000..e4ffb92 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_compound_literals2.c @@ -0,0 +1,18 @@ +/* compound literals */ + +struct p { + short a, b, c, d; +} zz = { + 1, 2, 3, 4 +}; + +struct p *bar(int i) +{ + static struct p q[10]; + return &q[i]; +} + +foo() +{ + *bar(1) = (struct p) { 1, 2, 3, 4 }; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_constant_conv1.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_constant_conv1.c new file mode 100644 index 0000000..53795c5 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_constant_conv1.c @@ -0,0 +1,9 @@ +/* Flag information-losing constant conversion in argument lists */ + +int f(unsigned int); + +void +should_fail() +{ + f(-1); +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_constant_conv2.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_constant_conv2.c new file mode 100644 index 0000000..87066c9 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_constant_conv2.c @@ -0,0 +1,9 @@ +/* Flag information-losing constant conversion in argument lists */ + +int f(unsigned int); + +void +should_fail() +{ + f(2.1); +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cvt_constant.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cvt_constant.c new file mode 100644 index 0000000..aa74509 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cvt_constant.c @@ -0,0 +1,8 @@ +/* the second assignment assumes failed before */ +int +main(void) { + double x = 1; + int foo = 0; + if (foo) + x = 1; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cvt_in_ternary.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cvt_in_ternary.c new file mode 100644 index 0000000..4a6149c --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_cvt_in_ternary.c @@ -0,0 +1,13 @@ +/* CVT node handling in ?: operator */ +typedef unsigned long int size_t; +struct filecore_direntry { + unsigned len:32; +}; +int +main(void) +{ + struct filecore_direntry dirent = { 0 }; + size_t uio_resid = 0; + size_t bytelen = (((dirent.len)<(uio_resid))?(dirent.len):(uio_resid)); + return bytelen; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_ellipsis_in_switch.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_ellipsis_in_switch.c new file mode 100644 index 0000000..ba4a338 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_ellipsis_in_switch.c @@ -0,0 +1,11 @@ +int x(void) +{ + int i = 33; + switch (i) { + case 1 ... 40: + break; + default: + break; + } + return 0; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_compound_statements1.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_compound_statements1.c new file mode 100644 index 0000000..d970be1 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_compound_statements1.c @@ -0,0 +1,7 @@ +/* GCC compound statements */ + +foo(unsigned long z) +{ + z = ({ unsigned long tmp; tmp = 1; tmp; }); + foo(z); +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c new file mode 100644 index 0000000..fa1ee67 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_compound_statements2.c @@ -0,0 +1,14 @@ +/* GCC compound statements with non-expressions */ +struct cpu_info { + int bar; +}; + +int +main(void) +{ + return ({ + struct cpu_info *__ci; + __asm__ volatile("movl %%fs:4,%0":"=r" (__ci)); + __ci; + })->bar; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_compound_statements3.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_compound_statements3.c new file mode 100644 index 0000000..29e9063 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_compound_statements3.c @@ -0,0 +1,10 @@ +/* GCC compound statements with void type */ + +void +main(void) +{ + ({ + void *v; + __asm__ volatile("noop"); + }); +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_extension.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_extension.c new file mode 100644 index 0000000..d8bd8f5 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_extension.c @@ -0,0 +1,6 @@ +/* extension */ +void a(void) { + double __logbw = 1; + if (__extension__(({ __typeof((__logbw)) x_ = (__logbw); !__builtin_isinf((x_)) && !__builtin_isnan((x_)); }))) + __logbw = 1; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_func.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_func.c new file mode 100644 index 0000000..459919d --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_func.c @@ -0,0 +1,7 @@ +/* gcc __FUNCTION__ */ + +void +foo(const char *p) { + p = __FUNCTION__; + foo(p); +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_variable_array_init.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_variable_array_init.c new file mode 100644 index 0000000..d5b01ad --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_gcc_variable_array_init.c @@ -0,0 +1,7 @@ +/* gcc: variable array initializer */ +void foo(int i) +{ + int array[i]; + while (i--) + foo(array[i] = 0); +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_incorrect_array_size.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_incorrect_array_size.c new file mode 100644 index 0000000..c86c0d6 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_incorrect_array_size.c @@ -0,0 +1,3 @@ +struct foo { + int a[-1]; +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_long_double_int.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_long_double_int.c new file mode 100644 index 0000000..a5a644e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_long_double_int.c @@ -0,0 +1,7 @@ +/* PR 39639: writing "long double" gave "long int" */ + +int +fail(long double *a, long int *b) +{ + return a == b; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_nested_structs.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_nested_structs.c new file mode 100644 index 0000000..edd3396 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_nested_structs.c @@ -0,0 +1,21 @@ +/* Nested struct */ +typedef void *EditLine; +typedef void *History; + +typedef struct { + EditLine *el; + History *hist; +} el_mode_t; + +struct el_modes_s { + el_mode_t command; + el_mode_t string; + el_mode_t filec; + el_mode_t mime_enc; +}; + +struct el_modes_s elm = { + .command = { .el = 0, .hist = 0, }, + .string = { .el = 0, .hist = 0, }, + .filec = { .el = 0, .hist = 0, }, +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_nolimit_init.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_nolimit_init.c new file mode 100644 index 0000000..68e71b4 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_nolimit_init.c @@ -0,0 +1,4 @@ +/* no limit initializers */ +char foo[][4] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_packed_structs.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_packed_structs.c new file mode 100644 index 0000000..71b4384 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_packed_structs.c @@ -0,0 +1,35 @@ +/* packed tests */ + +struct in_addr { + int x; +}; +struct ip_timestamp { + char ipt_code; + char ipt_len; + char ipt_ptr; + unsigned int ipt_flg:4, + ipt_oflw:4; + union ipt_timestamp { + int ipt_time[1]; + struct ipt_ta { + struct in_addr ipt_addr; + int ipt_time; + } ipt_ta[1] __packed; + } ipt_timestamp __packed; +} __packed; + +typedef struct __packed { + int x; +} t; + +struct x { + char c; + long l; +} __packed; + +struct y { + char c; + long l; +}; + +int a[sizeof(struct y) - sizeof(struct x) - 1]; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_shift_to_narrower_type.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_shift_to_narrower_type.c new file mode 100644 index 0000000..0208944 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_shift_to_narrower_type.c @@ -0,0 +1,24 @@ +// Test that type shifts that result to narrower types don't produce warnings. + +void +foo(void) { + unsigned long l = 100; + unsigned long long ll = 100; + unsigned int i = 100; + unsigned short s = 100; + unsigned char c = 1; + + l = ll >> 32; +// i = ll >> 31; + i = ll >> 32; + s = ll >> 48; + c = ll >> 56; + s = i >> 16; + c = i >> 24; + c = s >> 8; + (void)≪ + (void)&l; + (void)&i; + (void)&s; + (void)&c; +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_type_conv1.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_type_conv1.c new file mode 100644 index 0000000..d9e470e --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_type_conv1.c @@ -0,0 +1,11 @@ +/* Flag information-losing type conversion in argument lists */ + +int f(unsigned int); + +void +should_fail() +{ + long long x = 20; + + f(x); +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_type_conv2.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_type_conv2.c new file mode 100644 index 0000000..7c2e1f4 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_type_conv2.c @@ -0,0 +1,11 @@ +/* Flag information-losing type conversion in argument lists */ + +int f(float); + +void +should_fail() +{ + double x = 2.0; + + f(x); +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_type_conv3.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_type_conv3.c new file mode 100644 index 0000000..bc6a8e6 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_type_conv3.c @@ -0,0 +1,10 @@ +/* Flag information-losing type conversion in argument lists */ + +int f(unsigned int); + +void +should_fail() +{ + + f(0x7fffffffffffffffLL); +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_type_question_colon.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_type_question_colon.c new file mode 100644 index 0000000..00f69cd --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_type_question_colon.c @@ -0,0 +1,14 @@ +/* the type of the ?: expression should be the more specific type */ + +struct foo { + int bar; +}; + +void +test(void) { + int i; + struct foo *ptr = 0; + + for (i = (ptr ? ptr : (void *)0)->bar; i < 10; i++) + test(); +} diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_typefun.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_typefun.c new file mode 100644 index 0000000..ad69c51 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_typefun.c @@ -0,0 +1,22 @@ +/* typedef of function parameter */ + +typedef void (*free_func) (void * opaque, void* address); +typedef struct stack_st +{ + int num; + char **data; + int sorted; + + int num_alloc; + int (*comp)(const void *, const void *); +} _STACK; /* Use STACK_OF(...) instead */ + +typedef void *OPENSSL_BLOCK; +struct stack_st_OPENSSL_BLOCK { _STACK stack; }; +typedef void *d2i_of_void(void **,const unsigned char **,long); typedef int i2d_of_void(void *,unsigned char **); + +struct stack_st_OPENSSL_BLOCK *d2i_ASN1_SET(struct stack_st_OPENSSL_BLOCK **a, + const unsigned char **pp, + long length, d2i_of_void *d2i, + void (*free_func)(OPENSSL_BLOCK), int ex_tag, + int ex_class); diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_typename_as_var.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_typename_as_var.c new file mode 100644 index 0000000..248dc75 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_typename_as_var.c @@ -0,0 +1,14 @@ +typedef char h[10]; + +typedef struct { + int i; + char *c; +} fh; + +struct foo { + fh h; + struct { + int x; + int y; + } fl; +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/d_zero_sized_arrays.c b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_zero_sized_arrays.c new file mode 100644 index 0000000..9c06c6b --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/d_zero_sized_arrays.c @@ -0,0 +1,3 @@ +struct foo { +int a[0]; +}; diff --git a/contrib/netbsd-tests/usr.bin/xlint/lint1/t_integration.sh b/contrib/netbsd-tests/usr.bin/xlint/lint1/t_integration.sh new file mode 100755 index 0000000..9575f96 --- /dev/null +++ b/contrib/netbsd-tests/usr.bin/xlint/lint1/t_integration.sh @@ -0,0 +1,132 @@ +# $NetBSD: t_integration.sh,v 1.4 2014/04/21 19:10:41 christos Exp $ +# +# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +LINT1=/usr/libexec/lint1 + +Names= + +check_valid() +{ + atf_check -s exit:0 ${LINT1} -g -S "$(atf_get_srcdir)/$1" /dev/null +} + +check_invalid() +{ + atf_check -s not-exit:0 -o ignore -e ignore ${LINT1} -g -S -w \ + "$(atf_get_srcdir)/$1" /dev/null +} + +test_case() +{ + local result="${1}"; shift + local name="${1}"; shift + local descr="${*}" + + atf_test_case ${name} + eval "${name}_head() { + atf_set \"descr\" \"${descr}\"; + atf_set \"require.progs\" \"${LINT1}\"; + }" + eval "${name}_body() { + ${result} d_${name}.c; + }" + + Names="${Names} ${name}" +} + +test_case check_valid c99_struct_init "Checks C99 struct initialization" +test_case check_valid c99_union_init1 "Checks C99 union initialization" +test_case check_valid c99_union_init2 "Checks C99 union initialization" +test_case check_valid c99_union_init3 "Checks C99 union initialization" +test_case check_valid c99_recursive_init "Checks C99 recursive struct/union" \ + "initialization" +test_case check_valid c9x_recursive_init "Checks C9X struct/union member" \ + "init, with nested union and trailing member" +test_case check_valid nested_structs "Checks nested structs" +test_case check_valid packed_structs "Checks packed structs" + +test_case check_valid cast_init "Checks cast initialization" +test_case check_valid cast_init2 "Checks cast initialization as the rhs of a" \ + "- operand" +test_case check_valid cast_lhs "Checks whether pointer casts are valid lhs" \ + "lvalues" + +test_case check_valid gcc_func "Checks GCC __FUNCTION__" +test_case check_valid c99_func "Checks C99 __func__" + +test_case check_valid gcc_variable_array_init "Checks GCC variable array" \ + "initializers" +test_case check_valid c9x_array_init "Checks C9X array initializers" +test_case check_valid c99_decls_after_stmt "Checks C99 decls after statements" +test_case check_valid c99_decls_after_stmt3 "Checks C99 decls after statements" +test_case check_valid nolimit_init "Checks no limit initializers" +test_case check_valid zero_sized_arrays "Checks zero sized arrays" + +test_case check_valid compound_literals1 "Checks compound literals" +test_case check_valid compound_literals2 "Checks compound literals" +test_case check_valid gcc_compound_statements1 "Checks GCC compound statements" +test_case check_valid gcc_compound_statements2 "Checks GCC compound" \ + "statements with non-expressions" +test_case check_valid gcc_compound_statements3 "Checks GCC compound" \ + "statements with void type" +# XXX: Because of polymorphic __builtin_isnan and expression has null effect +# test_case check_valid gcc_extension "Checks GCC __extension__ and __typeof__" + +test_case check_valid cvt_in_ternary "Checks CVT nodes handling in ?" \ +test_case check_valid cvt_constant "Checks constant conversion" +test_case check_valid ellipsis_in_switch "Checks ellipsis in switch()" +test_case check_valid c99_complex_num "Checks C99 complex numbers" +test_case check_valid c99_complex_split "Checks C99 complex access" +test_case check_valid c99_for_loops "Checks C99 for loops" +test_case check_valid alignof "Checks __alignof__" +test_case check_valid shift_to_narrower_type "Checks that type shifts that" \ + "result in narrower types do not produce warnings" + +test_case check_invalid constant_conv1 "Checks failing on information-losing" \ + "constant conversion in argument lists" +test_case check_invalid constant_conv2 "Checks failing on information-losing" \ + "constant conversion in argument lists" + +test_case check_invalid type_conv1 "Checks failing on information-losing" \ + "type conversion in argument lists" +test_case check_invalid type_conv2 "Checks failing on information-losing" \ + "type conversion in argument lists" +test_case check_invalid type_conv3 "Checks failing on information-losing" \ + "type conversion in argument lists" + +test_case check_invalid incorrect_array_size "Checks failing on incorrect" \ + "array sizes" + +test_case check_invalid long_double_int "Checks for confusion of 'long" \ + "double' with 'long int'; PR 39639" + +atf_init_test_cases() +{ + for name in ${Names}; do + atf_add_test_case ${name} + done +} diff --git a/contrib/netbsd-tests/usr.sbin/mtree/d_convert.in b/contrib/netbsd-tests/usr.sbin/mtree/d_convert.in new file mode 100644 index 0000000..6a1abb0 --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/mtree/d_convert.in @@ -0,0 +1,40 @@ +# Similar to d_create.out, but a few entries have been deleted; nlink, +# size and sha256 attributes have been removed; and the order has been +# changed to test sorting. + +# . +. type=dir + a.symlink.1 type=link link=a.file.1 + top.dangling type=link link=nonexistent + top.symlink.b \ + type=link link=b + +# ./b +b type=dir + b.file.2 type=file + b.file.1 type=file +# end ./b, up to "." +.. + + top.file.1 type=file + +# ./a +a type=dir + a.file.2 type=file + +# ./a/1 +1 type=dir + a1.file.1 type=file +# end ./a/1, up to "./a" +.. + + a.file.1 type=file + +# ./a/2 +2 type=dir +# end ./a/2, up to "./a" +.. + +# end ./a, up to "." +.. + diff --git a/contrib/netbsd-tests/usr.sbin/mtree/d_convert_C.out b/contrib/netbsd-tests/usr.sbin/mtree/d_convert_C.out new file mode 100644 index 0000000..de4d9f6 --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/mtree/d_convert_C.out @@ -0,0 +1,14 @@ +. type=dir +./a.symlink.1 type=link link=a.file.1 +./top.dangling type=link link=nonexistent +./top.symlink.b type=link link=b +./b type=dir +./b/b.file.2 type=file +./b/b.file.1 type=file +./top.file.1 type=file +./a type=dir +./a/a.file.2 type=file +./a/1 type=dir +./a/1/a1.file.1 type=file +./a/a.file.1 type=file +./a/2 type=dir diff --git a/contrib/netbsd-tests/usr.sbin/mtree/d_convert_C_S.out b/contrib/netbsd-tests/usr.sbin/mtree/d_convert_C_S.out new file mode 100644 index 0000000..bd03cc4 --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/mtree/d_convert_C_S.out @@ -0,0 +1,14 @@ +. type=dir +./a.symlink.1 type=link link=a.file.1 +./top.dangling type=link link=nonexistent +./top.file.1 type=file +./top.symlink.b type=link link=b +./a type=dir +./a/a.file.1 type=file +./a/a.file.2 type=file +./a/1 type=dir +./a/1/a1.file.1 type=file +./a/2 type=dir +./b type=dir +./b/b.file.1 type=file +./b/b.file.2 type=file diff --git a/contrib/netbsd-tests/usr.sbin/mtree/d_convert_D.out b/contrib/netbsd-tests/usr.sbin/mtree/d_convert_D.out new file mode 100644 index 0000000..c059478 --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/mtree/d_convert_D.out @@ -0,0 +1,14 @@ +type=dir . +type=link link=a.file.1 ./a.symlink.1 +type=link link=nonexistent ./top.dangling +type=link link=b ./top.symlink.b +type=dir ./b +type=file ./b/b.file.2 +type=file ./b/b.file.1 +type=file ./top.file.1 +type=dir ./a +type=file ./a/a.file.2 +type=dir ./a/1 +type=file ./a/1/a1.file.1 +type=file ./a/a.file.1 +type=dir ./a/2 diff --git a/contrib/netbsd-tests/usr.sbin/mtree/d_convert_D_S.out b/contrib/netbsd-tests/usr.sbin/mtree/d_convert_D_S.out new file mode 100644 index 0000000..a777a0b --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/mtree/d_convert_D_S.out @@ -0,0 +1,14 @@ +type=dir . +type=link link=a.file.1 ./a.symlink.1 +type=link link=nonexistent ./top.dangling +type=file ./top.file.1 +type=link link=b ./top.symlink.b +type=dir ./a +type=file ./a/a.file.1 +type=file ./a/a.file.2 +type=dir ./a/1 +type=file ./a/1/a1.file.1 +type=dir ./a/2 +type=dir ./b +type=file ./b/b.file.1 +type=file ./b/b.file.2 diff --git a/contrib/netbsd-tests/usr.sbin/mtree/d_merge.in b/contrib/netbsd-tests/usr.sbin/mtree/d_merge.in new file mode 100644 index 0000000..9efd04b --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/mtree/d_merge.in @@ -0,0 +1,27 @@ +# The last entry for any duplicate node should take precedence. + +. type=dir + +# directory "a" with only one entry, changing from dir to link +./a type=dir +./a/change-dir-to-link type=dir mode=0755 +./a/change-dir-to-link type=link mode=0755 + +# directory "b" with only one entry, changing from link to dir +./b type=dir +./b/change-link-to-dir type=link mode=0755 +./b/change-link-to-dir type=dir mode=0755 + +# directory "c" with multiple entries, one changing from dir to link +./c type=dir +./c/aaa type=file +./c/zzz type=file +./c/change-dir-to-link type=dir mode=0755 +./c/change-dir-to-link type=link mode=0755 + +# directory "d" with multiple entries, one changing from link to dir +./d type=dir +./d/aaa type=file +./d/zzz type=file +./d/change-link-to-dir type=link mode=0755 +./d/change-link-to-dir type=dir mode=0755 diff --git a/contrib/netbsd-tests/usr.sbin/mtree/d_merge_C_M.out b/contrib/netbsd-tests/usr.sbin/mtree/d_merge_C_M.out new file mode 100644 index 0000000..dea9966 --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/mtree/d_merge_C_M.out @@ -0,0 +1,13 @@ +. type=dir +./a type=dir +./a/change-dir-to-link type=link mode=0755 +./b type=dir +./b/change-link-to-dir type=dir mode=0755 +./c type=dir +./c/aaa type=file +./c/zzz type=file +./c/change-dir-to-link type=link mode=0755 +./d type=dir +./d/aaa type=file +./d/zzz type=file +./d/change-link-to-dir type=dir mode=0755 diff --git a/contrib/netbsd-tests/usr.sbin/mtree/d_merge_C_M_S.out b/contrib/netbsd-tests/usr.sbin/mtree/d_merge_C_M_S.out new file mode 100644 index 0000000..9f02bea --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/mtree/d_merge_C_M_S.out @@ -0,0 +1,13 @@ +. type=dir +./a type=dir +./a/change-dir-to-link type=link mode=0755 +./b type=dir +./b/change-link-to-dir type=dir mode=0755 +./c type=dir +./c/aaa type=file +./c/change-dir-to-link type=link mode=0755 +./c/zzz type=file +./d type=dir +./d/aaa type=file +./d/zzz type=file +./d/change-link-to-dir type=dir mode=0755 diff --git a/contrib/netbsd-tests/usr.sbin/mtree/mtree_d_create.out b/contrib/netbsd-tests/usr.sbin/mtree/mtree_d_create.out new file mode 100644 index 0000000..389ec65 --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/mtree/mtree_d_create.out @@ -0,0 +1,55 @@ +# user: x +# machine: x +# tree: x +# date: x + +# . +/set type=file nlink=1 +. type=dir nlink=4 + a.symlink.1 type=link link=a.file.1 + top.dangling \ + type=link link=nonexistent + top.file.1 size=18 \ + sha256=74c53aaf0cd9543b7efad969de1058ee38859134ba467500b849811fc3513195 + top.symlink.b \ + type=link link=b + +# ./a +a type=dir nlink=4 + a.file.1 size=18 \ + sha256=bdbea62f7ccdf862f22254ea871d523845250010d5f233896e800142a859eef2 + a.file.2 size=18 \ + sha256=77876d113fe1b45a41f8d1d3e178aaad7f91fcd93d3df782690625b74ad90fe6 + a.hardlink.b2 \ + nlink=2 size=18 \ + sha256=784fd6b95fe5054d87bf268de51dea043031c5e985f668d4f51e1c759b0f9333 + +# ./a/1 +1 type=dir nlink=2 + a1.file.1 size=21 \ + sha256=a062cd272facdd38c4fdeff2a18947b28c99a28a8fe51f88468978740382e592 +# ./a/1 +.. + + +# ./a/2 +2 type=dir nlink=2 +# ./a/2 +.. + +# ./a +.. + + +# ./b +b type=dir nlink=2 + b.file.1 nlink=2 size=18 \ + sha256=5754b0d97a8238ea0e495ab871667dcab8f1d684e323290ae76f70c47de18998 + b.file.2 nlink=2 size=18 \ + sha256=784fd6b95fe5054d87bf268de51dea043031c5e985f668d4f51e1c759b0f9333 + b.hardlink.1 \ + nlink=2 size=18 \ + sha256=5754b0d97a8238ea0e495ab871667dcab8f1d684e323290ae76f70c47de18998 +# ./b +.. + diff --git a/contrib/netbsd-tests/usr.sbin/mtree/netbsd6_d_create.out b/contrib/netbsd-tests/usr.sbin/mtree/netbsd6_d_create.out new file mode 100644 index 0000000..389ec65 --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/mtree/netbsd6_d_create.out @@ -0,0 +1,55 @@ +# user: x +# machine: x +# tree: x +# date: x + +# . +/set type=file nlink=1 +. type=dir nlink=4 + a.symlink.1 type=link link=a.file.1 + top.dangling \ + type=link link=nonexistent + top.file.1 size=18 \ + sha256=74c53aaf0cd9543b7efad969de1058ee38859134ba467500b849811fc3513195 + top.symlink.b \ + type=link link=b + +# ./a +a type=dir nlink=4 + a.file.1 size=18 \ + sha256=bdbea62f7ccdf862f22254ea871d523845250010d5f233896e800142a859eef2 + a.file.2 size=18 \ + sha256=77876d113fe1b45a41f8d1d3e178aaad7f91fcd93d3df782690625b74ad90fe6 + a.hardlink.b2 \ + nlink=2 size=18 \ + sha256=784fd6b95fe5054d87bf268de51dea043031c5e985f668d4f51e1c759b0f9333 + +# ./a/1 +1 type=dir nlink=2 + a1.file.1 size=21 \ + sha256=a062cd272facdd38c4fdeff2a18947b28c99a28a8fe51f88468978740382e592 +# ./a/1 +.. + + +# ./a/2 +2 type=dir nlink=2 +# ./a/2 +.. + +# ./a +.. + + +# ./b +b type=dir nlink=2 + b.file.1 nlink=2 size=18 \ + sha256=5754b0d97a8238ea0e495ab871667dcab8f1d684e323290ae76f70c47de18998 + b.file.2 nlink=2 size=18 \ + sha256=784fd6b95fe5054d87bf268de51dea043031c5e985f668d4f51e1c759b0f9333 + b.hardlink.1 \ + nlink=2 size=18 \ + sha256=5754b0d97a8238ea0e495ab871667dcab8f1d684e323290ae76f70c47de18998 +# ./b +.. + diff --git a/contrib/netbsd-tests/usr.sbin/mtree/t_mtree.sh b/contrib/netbsd-tests/usr.sbin/mtree/t_mtree.sh new file mode 100755 index 0000000..58fc7db --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/mtree/t_mtree.sh @@ -0,0 +1,436 @@ +# $NetBSD: t_mtree.sh,v 1.7 2017/01/14 20:45:16 christos Exp $ +# +# Copyright (c) 2009, 2012 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +# Postprocess mtree output, canonicalising portions that +# are expected to differ from one run to another. +# + +h_postprocess() +{ + sed -e ' + /^# user: /s/:.*/: x/ + /^# machine: /s/:.*/: x/ + /^# tree: /s/:.*/: x/ + /^# date: /s/:.*/: x/ + ' \ + -e '/type=dir/s/ size=[0-9]*//' +} + +h_check() +{ + diff -Nru "$1" "$2" || atf_fail "files $1 and $2 differ" +} + + +atf_test_case mtree_create +atf_test_case netbsd6_create +create_head() +{ + atf_set "descr" "Create a specfile describing a directory tree" +} + +create_setup() +{ + # create some directories + rm -fr create + mkdir -p create/a/1 create/a/2 create/b + # create some files + for file in create/top.file.1 \ + create/a/a.file.1 \ + create/a/a.file.2 \ + create/a/1/a1.file.1 \ + create/b/b.file.1 \ + create/b/b.file.2 + do + echo "$file" >$file + done + # hard link to file in same dir + ln create/b/b.file.1 create/b/b.hardlink.1 + # hard link to file in another dir + ln create/b/b.file.2 create/a/a.hardlink.b2 + # symlink to file + ln -s a.file.1 create/a.symlink.1 + # symlink to dir + ln -s b create/top.symlink.b + # dangling symlink + ln -s nonexistent create/top.dangling +} + +create_body() +{ + create_setup + + # run mtree and check output + ( cd create && mtree -F ${FLAVOR} -c -k type,nlink,link,size,sha256 ) >output.raw \ + || atf_fail "mtree exit status $?" + h_postprocess output + h_check "$(atf_get_srcdir)/${FLAVOR}_d_create.out" output +} + +mtree_create_head() +{ + FLAVOR=mtree create_head +} +netbsd6_create_head() +{ + FLAVOR=netbsd6 create_head +} + +mtree_create_body() +{ + FLAVOR=mtree create_body +} +netbsd6_create_body() +{ + FLAVOR=netbsd6 create_body +} + + +atf_test_case mtree_check +atf_test_case netbsd6_check +check_head() +{ + atf_set "descr" "Check a directory tree against a specfile" +} + +check_body() +{ + # we use the same directory tree and specfile as in the "create" test + create_setup + + # run mtree and check output + ( cd create && mtree -F ${FLAVOR} ) <"$(atf_get_srcdir)/${FLAVOR}_d_create.out" >output \ + || atf_fail "mtree exit status $?" + h_check /dev/null output +} + +mtree_check_head() +{ + FLAVOR=mtree check_head +} +netbsd6_check_head() +{ + FLAVOR=netbsd6 check_head +} + +mtree_check_body() +{ + FLAVOR=mtree check_body +} +netbsd6_check_body() +{ + FLAVOR=netbsd6 check_body +} + + +atf_test_case mtree_convert_C +atf_test_case netbsd6_convert_C +convert_C_head() +{ + atf_set "descr" "Convert a specfile to mtree -C format, unsorted" +} + +convert_C_body() +{ + mtree -F ${FLAVOR} -C -K all <"$(atf_get_srcdir)/d_convert.in" >output + h_check "$(atf_get_srcdir)/d_convert_C.out" output +} + +mtree_convert_C_head() +{ + FLAVOR=mtree convert_C_head +} +netbsd6_convert_C_head() +{ + FLAVOR=netbsd6 convert_C_head +} + +mtree_convert_C_body() +{ + FLAVOR=mtree convert_C_body +} +netbsd6_convert_C_body() +{ + FLAVOR=netbsd6 convert_C_body +} + + +atf_test_case mtree_convert_C_S +atf_test_case netbsd6_convert_C_S +convert_C_S_head() +{ + atf_set "descr" "Convert a specfile to mtree -C format, sorted" +} + +convert_C_S_body() +{ + mtree -F ${FLAVOR} -C -S -K all <"$(atf_get_srcdir)/d_convert.in" >output + h_check "$(atf_get_srcdir)/d_convert_C_S.out" output +} + +mtree_convert_C_S_head() +{ + FLAVOR=mtree convert_C_S_head +} +netbsd6_convert_C_S_head() +{ + FLAVOR=netbsd6 convert_C_S_head +} + +mtree_convert_C_S_body() +{ + FLAVOR=mtree convert_C_S_body +} +netbsd6_convert_C_S_body() +{ + FLAVOR=netbsd6 convert_C_S_body +} + + +atf_test_case mtree_convert_D +atf_test_case netbsd6_convert_D +convert_D_head() +{ + atf_set "descr" "Convert a specfile to mtree -D format, unsorted" +} + +convert_D_body() +{ + mtree -F ${FLAVOR} -D -K all <"$(atf_get_srcdir)/d_convert.in" >output + h_check "$(atf_get_srcdir)/d_convert_D.out" output +} + +mtree_convert_D_head() +{ + FLAVOR=mtree convert_D_head +} +netbsd6_convert_D_head() +{ + FLAVOR=netbsd6 convert_D_head +} + +mtree_convert_D_body() +{ + FLAVOR=mtree convert_D_body +} +netbsd6_convert_D_body() +{ + FLAVOR=netbsd6 convert_D_body +} + + +atf_test_case mtree_convert_D_S +atf_test_case netbsd6_convert_D_S +convert_D_S_head() +{ + atf_set "descr" "Convert a specfile to mtree -D format, sorted" +} + +convert_D_S_body() +{ + mtree -F ${FLAVOR} -D -S -K all <"$(atf_get_srcdir)/d_convert.in" >output + h_check "$(atf_get_srcdir)/d_convert_D_S.out" output +} + +mtree_convert_D_S_head() +{ + FLAVOR=mtree convert_D_S_head +} +netbsd6_convert_D_S_head() +{ + FLAVOR=netbsd6 convert_D_S_head +} + +mtree_convert_D_S_body() +{ + FLAVOR=mtree convert_D_S_body +} +netbsd6_convert_D_S_body() +{ + FLAVOR=netbsd6 convert_D_S_body +} + + +atf_test_case mtree_ignore +atf_test_case netbs6_ignore +ignore_head() +{ + atf_set "descr" "Test that -d ignores symlinks (PR bin/41061)" +} + +ignore_body() +{ + # Kyua 0.11 and above point TMPDIR to our work directory and atf-check + # generates a temporary file, which confuses mtree. Put the mtree files + # into a subdirectory. + # + # See https://github.com/jmmv/kyua/issues/133 for details. + mkdir root && cd root + + mkdir newdir + mtree -F ${FLAVOR} -c | mtree -F ${FLAVOR} -Ck uid,gid,mode > mtree.spec + ln -s newdir otherdir + + # This yields "extra: otherdir" even with -d. + # (PR bin/41061) + atf_check -s ignore -o empty -e empty -x "mtree -F ${FLAVOR} -d < mtree.spec" + + # Delete the symlink and re-verify. + # + rm otherdir + atf_check -s ignore -o empty -e empty -x "mtree -F ${FLAVOR} -d < mtree.spec" +} + +mtree_ignore_head() +{ + FLAVOR=mtree ignore_head +} +netbsd6_ignore_head() +{ + FLAVOR=netbsd6 ignore_head +} + +mtree_ignore_body() +{ + FLAVOR=mtree ignore_body +} +netbsd6_ignore_body() +{ + # Kyua 0.11 and above point TMPDIR to our work directory and atf-check + # generates a temporary file, which confuses mtree. Put the mtree files + # into a subdirectory. + # + # See https://github.com/jmmv/kyua/issues/133 for details. + mkdir root && cd root + + FLAVOR=netbsd6 ignore_body +} + + +atf_test_case mtree_merge +atf_test_case netbsd6_merge +merge_head() +{ + atf_set "descr" "Merge records of different type" +} + +merge_body() +{ + mtree -F ${FLAVOR} -C -M -K all <"$(atf_get_srcdir)/d_merge.in" >output + h_check "$(atf_get_srcdir)/d_merge_C_M.out" output + # same again, with sorting + mtree -F ${FLAVOR} -C -M -S -K all <"$(atf_get_srcdir)/d_merge.in" >output + h_check "$(atf_get_srcdir)/d_merge_C_M_S.out" output +} + +mtree_merge_head() +{ + FLAVOR=mtree merge_head +} +netbsd6_merge_head() +{ + FLAVOR=netbsd6 merge_head +} + +mtree_merge_body() +{ + FLAVOR=mtree merge_body +} +netbsd6_merge_body() +{ + FLAVOR=netbsd6 merge_body +} + + +atf_test_case mtree_nonemptydir +atf_test_case netbsd6_nonemptydir +nonemptydir_head() +{ + atf_set "descr" "Test that new non-empty " \ + "directories are recorded (PR bin/25693)" +} + +nonemptydir_body() +{ + mkdir testdir + cd testdir + + mtree -F ${FLAVOR} -c > mtree.spec + + if [ ! -f mtree.spec ]; then + atf_fail "mtree failed" + fi + + touch bar + atf_check -s ignore -o save:output -x "mtree -F ${FLAVOR} -f mtree.spec" + + if [ ! -n "$(egrep "extra: bar" output)" ]; then + atf_fail "mtree did not record changes (PR bin/25693)" + fi +} + +mtree_nonemptydir_head() +{ + FLAVOR=mtree nonemptydir_head +} +netbsd6_nonemptydir_head() +{ + FLAVOR=netbsd6 nonemptydir_head +} + +mtree_nonemptydir_body() +{ + FLAVOR=mtree nonemptydir_body +} +netbsd6_nonemptydir_body() +{ + FLAVOR=netbsd6 nonemptydir_body +} + + +atf_init_test_cases() +{ + atf_add_test_case mtree_create + atf_add_test_case mtree_check + atf_add_test_case mtree_convert_C + atf_add_test_case mtree_convert_C_S + atf_add_test_case mtree_convert_D + atf_add_test_case mtree_convert_D_S + atf_add_test_case mtree_ignore + atf_add_test_case mtree_merge + atf_add_test_case mtree_nonemptydir + + atf_add_test_case netbsd6_create + atf_add_test_case netbsd6_check + atf_add_test_case netbsd6_convert_C + atf_add_test_case netbsd6_convert_C_S + atf_add_test_case netbsd6_convert_D + atf_add_test_case netbsd6_convert_D_S + atf_add_test_case netbsd6_ignore + atf_add_test_case netbsd6_merge + atf_add_test_case netbsd6_nonemptydir +} diff --git a/contrib/netbsd-tests/usr.sbin/tcpdump/t_tcpdump.sh b/contrib/netbsd-tests/usr.sbin/tcpdump/t_tcpdump.sh new file mode 100755 index 0000000..5cd89b4 --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/tcpdump/t_tcpdump.sh @@ -0,0 +1,59 @@ +# $NetBSD: t_tcpdump.sh,v 1.4 2014/09/20 06:08:07 ozaki-r Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +prom() { + atf_check -s ignore -o ignore -e ignore -x "tcpdump -c 1 -i $1" & + sleep 2; kill $! >/dev/null 2>&1 +} + +atf_test_case promiscuous +promiscuous_head() { + atf_set "require.user" "root" + atf_set "descr" "Test that switching an interface into and out " \ + "of promiscuous mode does not lockup (PR kern/46328)" +} + +promiscuous_body() { + + for i in $(ifconfig -l); do + case $i in + bridge*) + echo "Skipping $i" + continue + ;; + esac + + echo "Testing $i" + prom $i + done +} + +atf_init_test_cases() { + atf_add_test_case promiscuous +} diff --git a/contrib/netbsd-tests/usr.sbin/traceroute/t_traceroute.sh b/contrib/netbsd-tests/usr.sbin/traceroute/t_traceroute.sh new file mode 100755 index 0000000..7727683 --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/traceroute/t_traceroute.sh @@ -0,0 +1,128 @@ +# $NetBSD: t_traceroute.sh,v 1.6 2016/08/10 23:17:35 kre Exp $ +# +# Copyright (c) 2010 The NetBSD Foundation, Inc. +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# + +netserver=\ +"rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpdev" + +atf_test_case basic cleanup +basic_head() +{ + + atf_set "descr" "Does a simple three-hop traceroute" + atf_set "require.progs" "rump_server" +} + +cfgendpt () +{ + + sock=${1} + addr=${2} + route=${3} + bus=${4} + + export RUMP_SERVER=${sock} + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr ${bus} + atf_check -s exit:0 rump.ifconfig shmif0 inet ${addr} netmask 0xffffff00 + atf_check -s exit:0 -o ignore rump.route add default ${route} +} + +threeservers() +{ + + atf_check -s exit:0 ${netserver} unix://commsock1 + atf_check -s exit:0 ${netserver} unix://commsock2 + atf_check -s exit:0 ${netserver} unix://commsock3 + + # configure endpoints + cfgendpt unix://commsock1 1.2.3.4 1.2.3.1 bus1 + cfgendpt unix://commsock3 2.3.4.5 2.3.4.1 bus2 + + # configure the router + export RUMP_SERVER=unix://commsock2 + atf_check -s exit:0 rump.ifconfig shmif0 create + atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1 + atf_check -s exit:0 rump.ifconfig shmif0 inet 1.2.3.1 netmask 0xffffff00 + + atf_check -s exit:0 rump.ifconfig shmif1 create + atf_check -s exit:0 rump.ifconfig shmif1 linkstr bus2 + atf_check -s exit:0 rump.ifconfig shmif1 inet 2.3.4.1 netmask 0xffffff00 +} + +threecleanup() +{ + env RUMP_SERVER=unix://commsock1 rump.halt + env RUMP_SERVER=unix://commsock2 rump.halt + env RUMP_SERVER=unix://commsock3 rump.halt +} + +threetests() +{ + + threeservers + export RUMP_SERVER=unix://commsock1 + atf_check -s exit:0 -o inline:'1.2.3.1\n2.3.4.5\n' -e ignore -x \ + "rump.traceroute ${1} -n 2.3.4.5 | awk '{print \$2}'" + export RUMP_SERVER=unix://commsock3 + atf_check -s exit:0 -o inline:'2.3.4.1\n1.2.3.4\n' -e ignore -x \ + "rump.traceroute ${1} -n 1.2.3.4 | awk '{print \$2}'" +} + +basic_body() +{ + threetests +} + +basic_cleanup() +{ + threecleanup +} + +atf_test_case basic_icmp cleanup +basic_icmp_head() +{ + + atf_set "descr" "Does an ICMP-based three-hop traceroute" + atf_set "require.progs" "rump_server" +} + +basic_icmp_body() +{ + threetests -I +} + +basic_icmp_cleanup() +{ + threecleanup +} + +atf_init_test_cases() +{ + + atf_add_test_case basic + atf_add_test_case basic_icmp +} diff --git a/contrib/netbsd-tests/usr.sbin/useradd/t_useradd.sh b/contrib/netbsd-tests/usr.sbin/useradd/t_useradd.sh new file mode 100755 index 0000000..c55818e --- /dev/null +++ b/contrib/netbsd-tests/usr.sbin/useradd/t_useradd.sh @@ -0,0 +1,50 @@ +# $NetBSD: t_useradd.sh,v 1.1 2012/04/19 18:51:36 jruoho Exp $ +# +# Copyright (c) 2012 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Jukka Ruohonen. +# +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +# +username="test5678901234567" + +atf_test_case longname cleanup +longname_head() { + atf_set "require.user" "root" + atf_set "descr" "Test that usernames longer than 16 " \ + "characters are allowed (PR bin/39546)" +} + +longname_body() { + atf_expect_fail "PR bin/39546" + atf_check -s exit:0 -o ignore -e ignore -x "useradd $username" +} + +longname_cleanup() { + atf_check -s ignore -o ignore -e ignore -x "userdel $username" +} + +atf_init_test_cases() { + atf_add_test_case longname +} diff --git a/contrib/tzcode/stdtime/asctime.c b/contrib/tzcode/stdtime/asctime.c new file mode 100644 index 0000000..ed315f6 --- /dev/null +++ b/contrib/tzcode/stdtime/asctime.c @@ -0,0 +1,145 @@ +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +*/ + +/* +** Avoid the temptation to punt entirely to strftime; +** the output of strftime is supposed to be locale specific +** whereas the output of asctime is supposed to be constant. +*/ + +#include +#ifndef lint +#ifndef NOID +static char elsieid[] __unused = "@(#)asctime.c 8.5"; +#endif /* !defined NOID */ +#endif /* !defined lint */ +__FBSDID("$FreeBSD: releng/11.1/contrib/tzcode/stdtime/asctime.c 214411 2010-10-27 07:14:46Z edwin $"); + +/*LINTLIBRARY*/ + +#include "namespace.h" +#include "private.h" +#include "un-namespace.h" +#include "tzfile.h" + +/* +** Some systems only handle "%.2d"; others only handle "%02d"; +** "%02.2d" makes (most) everybody happy. +** At least some versions of gcc warn about the %02.2d; +** we conditionalize below to avoid the warning. +*/ +/* +** All years associated with 32-bit time_t values are exactly four digits long; +** some years associated with 64-bit time_t values are not. +** Vintage programs are coded for years that are always four digits long +** and may assume that the newline always lands in the same place. +** For years that are less than four digits, we pad the output with +** leading zeroes to get the newline in the traditional place. +** The -4 ensures that we get four characters of output even if +** we call a strftime variant that produces fewer characters for some years. +** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year, +** but many implementations pad anyway; most likely the standards are buggy. +*/ +#ifdef __GNUC__ +#define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n" +#else /* !defined __GNUC__ */ +#define ASCTIME_FMT "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n" +#endif /* !defined __GNUC__ */ +/* +** For years that are more than four digits we put extra spaces before the year +** so that code trying to overwrite the newline won't end up overwriting +** a digit within a year and truncating the year (operating on the assumption +** that no output is better than wrong output). +*/ +#ifdef __GNUC__ +#define ASCTIME_FMT_B "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %s\n" +#else /* !defined __GNUC__ */ +#define ASCTIME_FMT_B "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %s\n" +#endif /* !defined __GNUC__ */ + +#define STD_ASCTIME_BUF_SIZE 26 +/* +** Big enough for something such as +** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n +** (two three-character abbreviations, five strings denoting integers, +** seven explicit spaces, two explicit colons, a newline, +** and a trailing ASCII nul). +** The values above are for systems where an int is 32 bits and are provided +** as an example; the define below calculates the maximum for the system at +** hand. +*/ +#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1) + +static char buf_asctime[MAX_ASCTIME_BUF_SIZE]; + +/* +** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition. +*/ + +char * +asctime_r(timeptr, buf) +const struct tm * timeptr; +char * buf; +{ + static const char wday_name[][3] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + static const char mon_name[][3] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + const char * wn; + const char * mn; + char year[INT_STRLEN_MAXIMUM(int) + 2]; + char result[MAX_ASCTIME_BUF_SIZE]; + + if (timeptr == NULL) { + errno = EINVAL; + return strcpy(buf, "??? ??? ?? ??:??:?? ????\n"); + } + if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) + wn = "???"; + else wn = wday_name[timeptr->tm_wday]; + if (timeptr->tm_mon < 0 || timeptr->tm_mon >= MONSPERYEAR) + mn = "???"; + else mn = mon_name[timeptr->tm_mon]; + /* + ** Use strftime's %Y to generate the year, to avoid overflow problems + ** when computing timeptr->tm_year + TM_YEAR_BASE. + ** Assume that strftime is unaffected by other out-of-range members + ** (e.g., timeptr->tm_mday) when processing "%Y". + */ + (void) strftime(year, sizeof year, "%Y", timeptr); + /* + ** We avoid using snprintf since it's not available on all systems. + */ + (void) sprintf(result, + ((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B), + wn, mn, + timeptr->tm_mday, timeptr->tm_hour, + timeptr->tm_min, timeptr->tm_sec, + year); + if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) + return strcpy(buf, result); + else { +#ifdef EOVERFLOW + errno = EOVERFLOW; +#else /* !defined EOVERFLOW */ + errno = EINVAL; +#endif /* !defined EOVERFLOW */ + return NULL; + } +} + +/* +** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition. +*/ + +char * +asctime(timeptr) +const struct tm * timeptr; +{ + return asctime_r(timeptr, buf_asctime); +} diff --git a/contrib/tzcode/stdtime/ctime.3 b/contrib/tzcode/stdtime/ctime.3 new file mode 100644 index 0000000..abf4ade --- /dev/null +++ b/contrib/tzcode/stdtime/ctime.3 @@ -0,0 +1,374 @@ +.\" 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 +.\" Arthur Olson. +.\" 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. +.\" 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. +.\" +.\" From: @(#)ctime.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/contrib/tzcode/stdtime/ctime.3 266111 2014-05-15 03:08:20Z gavin $ +.\" +.Dd January 2, 1999 +.Dt CTIME 3 +.Os +.Sh NAME +.Nm asctime , +.Nm asctime_r , +.Nm ctime , +.Nm ctime_r , +.Nm difftime , +.Nm gmtime , +.Nm gmtime_r , +.Nm localtime , +.Nm localtime_r , +.Nm mktime , +.Nm timegm +.Nd transform binary date and time values +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In time.h +.Vt extern char *tzname[2] ; +.Ft char * +.Fn ctime "const time_t *clock" +.Ft double +.Fn difftime "time_t time1" "time_t time0" +.Ft char * +.Fn asctime "const struct tm *tm" +.Ft struct tm * +.Fn localtime "const time_t *clock" +.Ft struct tm * +.Fn gmtime "const time_t *clock" +.Ft time_t +.Fn mktime "struct tm *tm" +.Ft time_t +.Fn timegm "struct tm *tm" +.Ft char * +.Fn ctime_r "const time_t *clock" "char *buf" +.Ft struct tm * +.Fn localtime_r "const time_t *clock" "struct tm *result" +.Ft struct tm * +.Fn gmtime_r "const time_t *clock" "struct tm *result" +.Ft char * +.Fn asctime_r "const struct tm *tm" "char *buf" +.Sh DESCRIPTION +The functions +.Fn ctime , +.Fn gmtime +and +.Fn localtime +all take as an argument a time value representing the time in seconds since +the Epoch (00:00:00 +.Tn UTC , +January 1, 1970; see +.Xr time 3 ) . +.Pp +The function +.Fn localtime +converts the time value pointed at by +.Fa clock , +and returns a pointer to a +.Dq Fa struct tm +(described below) which contains +the broken-out time information for the value after adjusting for the current +time zone (and any other factors such as Daylight Saving Time). +Time zone adjustments are performed as specified by the +.Ev TZ +environment variable (see +.Xr tzset 3 ) . +The function +.Fn localtime +uses +.Xr tzset 3 +to initialize time conversion information if +.Xr tzset 3 +has not already been called by the process. +.Pp +After filling in the tm structure, +.Fn localtime +sets the +.Fa tm_isdst Ns 'th +element of +.Fa tzname +to a pointer to an +.Tn ASCII +string that is the time zone abbreviation to be +used with +.Fn localtime Ns 's +return value. +.Pp +The function +.Fn gmtime +similarly converts the time value, but without any time zone adjustment, +and returns a pointer to a tm structure (described below). +.Pp +The +.Fn ctime +function +adjusts the time value for the current time zone in the same manner as +.Fn localtime , +and returns a pointer to a 26-character string of the form: +.Bd -literal -offset indent +Thu Nov 24 18:22:48 1986\en\e0 +.Ed +.Pp +All the fields have constant width. +.Pp +The +.Fn ctime_r +function +provides the same functionality as +.Fn ctime +except the caller must provide the output buffer +.Fa buf +to store the result, which must be at least 26 characters long. +The +.Fn localtime_r +and +.Fn gmtime_r +functions +provide the same functionality as +.Fn localtime +and +.Fn gmtime +respectively, except the caller must provide the output buffer +.Fa result . +.Pp +The +.Fn asctime +function +converts the broken down time in the structure +.Fa tm +pointed at by +.Fa *tm +to the form +shown in the example above. +.Pp +The +.Fn asctime_r +function +provides the same functionality as +.Fn asctime +except the caller provide the output buffer +.Fa buf +to store the result, which must be at least 26 characters long. +.Pp +The functions +.Fn mktime +and +.Fn timegm +convert the broken-down time in the structure +pointed to by tm into a time value with the same encoding as that of the +values returned by the +.Xr time 3 +function (that is, seconds from the Epoch, +.Tn UTC ) . +The +.Fn mktime +function +interprets the input structure according to the current timezone setting +(see +.Xr tzset 3 ) . +The +.Fn timegm +function +interprets the input structure as representing Universal Coordinated Time +.Pq Tn UTC . +.Pp +The original values of the +.Fa tm_wday +and +.Fa tm_yday +components of the structure are ignored, and the original values of the +other components are not restricted to their normal ranges, and will be +normalized if needed. +For example, +October 40 is changed into November 9, +a +.Fa tm_hour +of \-1 means 1 hour before midnight, +.Fa tm_mday +of 0 means the day preceding the current month, and +.Fa tm_mon +of \-2 means 2 months before January of +.Fa tm_year . +(A positive or zero value for +.Fa tm_isdst +causes +.Fn mktime +to presume initially that summer time (for example, Daylight Saving Time) +is or is not in effect for the specified time, respectively. +A negative value for +.Fa tm_isdst +causes the +.Fn mktime +function to attempt to divine whether summer time is in effect for the +specified time. +The +.Fa tm_isdst +and +.Fa tm_gmtoff +members are forced to zero by +.Fn timegm . ) +.Pp +On successful completion, the values of the +.Fa tm_wday +and +.Fa tm_yday +components of the structure are set appropriately, and the other components +are set to represent the specified calendar time, but with their values +forced to their normal ranges; the final value of +.Fa tm_mday +is not set until +.Fa tm_mon +and +.Fa tm_year +are determined. +The +.Fn mktime +function +returns the specified calendar time; if the calendar time cannot be +represented, it returns \-1; +.Pp +The +.Fn difftime +function +returns the difference between two calendar times, +.Pf ( Fa time1 +- +.Fa time0 ) , +expressed in seconds. +.Pp +External declarations as well as the tm structure definition are in the +.In time.h +include file. +The tm structure includes at least the following fields: +.Bd -literal -offset indent +int tm_sec; /\(** seconds (0 - 60) \(**/ +int tm_min; /\(** minutes (0 - 59) \(**/ +int tm_hour; /\(** hours (0 - 23) \(**/ +int tm_mday; /\(** day of month (1 - 31) \(**/ +int tm_mon; /\(** month of year (0 - 11) \(**/ +int tm_year; /\(** year \- 1900 \(**/ +int tm_wday; /\(** day of week (Sunday = 0) \(**/ +int tm_yday; /\(** day of year (0 - 365) \(**/ +int tm_isdst; /\(** is summer time in effect? \(**/ +char \(**tm_zone; /\(** abbreviation of timezone name \(**/ +long tm_gmtoff; /\(** offset from UTC in seconds \(**/ +.Ed +.Pp +The +field +.Fa tm_isdst +is non-zero if summer time is in effect. +.Pp +The field +.Fa tm_gmtoff +is the offset (in seconds) of the time represented from +.Tn UTC , +with positive +values indicating east of the Prime Meridian. +.Sh SEE ALSO +.Xr date 1 , +.Xr gettimeofday 2 , +.Xr getenv 3 , +.Xr time 3 , +.Xr tzset 3 , +.Xr tzfile 5 +.Sh STANDARDS +The +.Fn asctime , +.Fn ctime , +.Fn difftime , +.Fn gmtime , +.Fn localtime , +and +.Fn mktime +functions conform to +.St -isoC , +and conform to +.St -p1003.1-96 +provided the selected local timezone does not contain a leap-second table +(see +.Xr zic 8 ) . +.Pp +The +.Fn asctime_r , +.Fn ctime_r , +.Fn gmtime_r , +and +.Fn localtime_r +functions are expected to conform to +.St -p1003.1-96 +(again provided the selected local timezone does not contain a leap-second +table). +.Pp +The +.Fn timegm +function is not specified by any standard; its function cannot be +completely emulated using the standard functions described above. +.Sh HISTORY +This manual page is derived from +the time package contributed to Berkeley by +.An Arthur Olson +and which appeared in +.Bx 4.3 . +.Sh BUGS +Except for +.Fn difftime , +.Fn mktime , +and the +.Fn \&_r +variants of the other functions, +these functions leave their result in an internal static object and return +a pointer to that object. +Subsequent calls to these +function will modify the same object. +.Pp +The C Standard provides no mechanism for a program to modify its current +local timezone setting, and the +.Tn POSIX Ns No \&-standard +method is not reentrant. +(However, thread-safe implementations are provided +in the +.Tn POSIX +threaded environment.) +.Pp +The +.Va tm_zone +field of a returned +.Vt tm +structure points to a static array of characters, +which will also be overwritten by any subsequent calls (as well as by +subsequent calls to +.Xr tzset 3 +and +.Xr tzsetwall 3 ) . +.Pp +Use of the external variable +.Fa tzname +is discouraged; the +.Fa tm_zone +entry in the tm structure is preferred. diff --git a/contrib/tzcode/stdtime/difftime.c b/contrib/tzcode/stdtime/difftime.c new file mode 100644 index 0000000..fe062e7 --- /dev/null +++ b/contrib/tzcode/stdtime/difftime.c @@ -0,0 +1,67 @@ +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +*/ + +#include +#ifndef lint +#ifndef NOID +static char elsieid[] __unused = "@(#)difftime.c 8.1"; +#endif /* !defined NOID */ +#endif /* !defined lint */ +__FBSDID("$FreeBSD: releng/11.1/contrib/tzcode/stdtime/difftime.c 289027 2015-10-08 11:42:15Z rodrigc $"); + +/*LINTLIBRARY*/ + +#include "namespace.h" +#include "private.h" /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */ +#include "un-namespace.h" + +double +difftime(const time_t time1, const time_t time0) +{ + /* + ** If (sizeof (double) > sizeof (time_t)) simply convert and subtract + ** (assuming that the larger type has more precision). + ** This is the common real-world case circa 2004. + */ + if (sizeof (double) > sizeof (time_t)) + return (double) time1 - (double) time0; + if (!TYPE_INTEGRAL(time_t)) { + /* + ** time_t is floating. + */ + return time1 - time0; + } + if (!TYPE_SIGNED(time_t)) { + /* + ** time_t is integral and unsigned. + ** The difference of two unsigned values can't overflow + ** if the minuend is greater than or equal to the subtrahend. + */ + if (time1 >= time0) + return time1 - time0; + else return -((double) (time0 - time1)); + } + /* + ** time_t is integral and signed. + ** Handle cases where both time1 and time0 have the same sign + ** (meaning that their difference cannot overflow). + */ + if ((time1 < 0) == (time0 < 0)) + return time1 - time0; + /* + ** time1 and time0 have opposite signs. + ** Punt if unsigned long is too narrow. + */ + if (sizeof (unsigned long) < sizeof (time_t)) + return (double) time1 - (double) time0; + /* + ** Stay calm...decent optimizers will eliminate the complexity below. + */ + if (time1 >= 0 /* && time0 < 0 */) + return (unsigned long) time1 + + (unsigned long) (-(time0 + 1)) + 1; + return -(double) ((unsigned long) time0 + + (unsigned long) (-(time1 + 1)) + 1); +} diff --git a/contrib/tzcode/stdtime/localtime.c b/contrib/tzcode/stdtime/localtime.c new file mode 100644 index 0000000..0332328 --- /dev/null +++ b/contrib/tzcode/stdtime/localtime.c @@ -0,0 +1,2242 @@ +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +*/ + +#include +#ifndef lint +#ifndef NOID +static char elsieid[] __unused = "@(#)localtime.c 8.14"; +#endif /* !defined NOID */ +#endif /* !defined lint */ +__FBSDID("$FreeBSD: releng/11.1/contrib/tzcode/stdtime/localtime.c 314447 2017-03-01 01:45:52Z emaste $"); + +/* +** Leap second handling from Bradley White. +** POSIX-style TZ environment variable handling from Guy Harris. +*/ + +/*LINTLIBRARY*/ + +#include "namespace.h" +#include +#include +#include +#include +#include +#include "private.h" +#include "un-namespace.h" + +#include "tzfile.h" +#include "float.h" /* for FLT_MAX and DBL_MAX */ + +#ifndef TZ_ABBR_MAX_LEN +#define TZ_ABBR_MAX_LEN 16 +#endif /* !defined TZ_ABBR_MAX_LEN */ + +#ifndef TZ_ABBR_CHAR_SET +#define TZ_ABBR_CHAR_SET \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" +#endif /* !defined TZ_ABBR_CHAR_SET */ + +#ifndef TZ_ABBR_ERR_CHAR +#define TZ_ABBR_ERR_CHAR '_' +#endif /* !defined TZ_ABBR_ERR_CHAR */ + +#include "libc_private.h" + +#define _MUTEX_LOCK(x) if (__isthreaded) _pthread_mutex_lock(x) +#define _MUTEX_UNLOCK(x) if (__isthreaded) _pthread_mutex_unlock(x) + +#define _RWLOCK_RDLOCK(x) \ + do { \ + if (__isthreaded) _pthread_rwlock_rdlock(x); \ + } while (0) + +#define _RWLOCK_WRLOCK(x) \ + do { \ + if (__isthreaded) _pthread_rwlock_wrlock(x); \ + } while (0) + +#define _RWLOCK_UNLOCK(x) \ + do { \ + if (__isthreaded) _pthread_rwlock_unlock(x); \ + } while (0) + +/* +** SunOS 4.1.1 headers lack O_BINARY. +*/ + +#ifdef O_BINARY +#define OPEN_MODE (O_RDONLY | O_BINARY) +#endif /* defined O_BINARY */ +#ifndef O_BINARY +#define OPEN_MODE O_RDONLY +#endif /* !defined O_BINARY */ + +#ifndef WILDABBR +/* +** Someone might make incorrect use of a time zone abbreviation: +** 1. They might reference tzname[0] before calling tzset (explicitly +** or implicitly). +** 2. They might reference tzname[1] before calling tzset (explicitly +** or implicitly). +** 3. They might reference tzname[1] after setting to a time zone +** in which Daylight Saving Time is never observed. +** 4. They might reference tzname[0] after setting to a time zone +** in which Standard Time is never observed. +** 5. They might reference tm.TM_ZONE after calling offtime. +** What's best to do in the above cases is open to debate; +** for now, we just set things up so that in any of the five cases +** WILDABBR is used. Another possibility: initialize tzname[0] to the +** string "tzname[0] used before set", and similarly for the other cases. +** And another: initialize tzname[0] to "ERA", with an explanation in the +** manual page of what this "time zone abbreviation" means (doing this so +** that tzname[0] has the "normal" length of three characters). +*/ +#define WILDABBR " " +#endif /* !defined WILDABBR */ + +static char wildabbr[] = WILDABBR; + +/* + * In June 2004 it was decided UTC was a more appropriate default time + * zone than GMT. + */ + +static const char gmt[] = "UTC"; + +/* +** The DST rules to use if TZ has no rules and we can't load TZDEFRULES. +** We default to US rules as of 1999-08-17. +** POSIX 1003.1 section 8.1.1 says that the default DST rules are +** implementation dependent; for historical reasons, US rules are a +** common default. +*/ +#ifndef TZDEFRULESTRING +#define TZDEFRULESTRING ",M4.1.0,M10.5.0" +#endif /* !defined TZDEFDST */ + +struct ttinfo { /* time type information */ + long tt_gmtoff; /* UTC offset in seconds */ + int tt_isdst; /* used to set tm_isdst */ + int tt_abbrind; /* abbreviation list index */ + int tt_ttisstd; /* TRUE if transition is std time */ + int tt_ttisgmt; /* TRUE if transition is UTC */ +}; + +struct lsinfo { /* leap second information */ + time_t ls_trans; /* transition time */ + long ls_corr; /* correction to apply */ +}; + +#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b)) + +#ifdef TZNAME_MAX +#define MY_TZNAME_MAX TZNAME_MAX +#endif /* defined TZNAME_MAX */ +#ifndef TZNAME_MAX +#define MY_TZNAME_MAX 255 +#endif /* !defined TZNAME_MAX */ + +struct state { + int leapcnt; + int timecnt; + int typecnt; + int charcnt; + int goback; + int goahead; + time_t ats[TZ_MAX_TIMES]; + unsigned char types[TZ_MAX_TIMES]; + struct ttinfo ttis[TZ_MAX_TYPES]; + char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), + (2 * (MY_TZNAME_MAX + 1)))]; + struct lsinfo lsis[TZ_MAX_LEAPS]; +}; + +struct rule { + int r_type; /* type of rule--see below */ + int r_day; /* day number of rule */ + int r_week; /* week number of rule */ + int r_mon; /* month number of rule */ + long r_time; /* transition time of rule */ +}; + +#define JULIAN_DAY 0 /* Jn - Julian day */ +#define DAY_OF_YEAR 1 /* n - day of year */ +#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ + +/* +** Prototypes for static functions. +*/ + +static long detzcode(const char * codep); +static time_t detzcode64(const char * codep); +static int differ_by_repeat(time_t t1, time_t t0); +static const char * getzname(const char * strp) ATTRIBUTE_PURE; +static const char * getqzname(const char * strp, const int delim) + ATTRIBUTE_PURE; +static const char * getnum(const char * strp, int * nump, int min, + int max); +static const char * getsecs(const char * strp, long * secsp); +static const char * getoffset(const char * strp, long * offsetp); +static const char * getrule(const char * strp, struct rule * rulep); +static void gmtload(struct state * sp); +static struct tm * gmtsub(const time_t * timep, long offset, + struct tm * tmp); +static struct tm * localsub(const time_t * timep, long offset, + struct tm * tmp); +static int increment_overflow(int * number, int delta); +static int leaps_thru_end_of(int y) ATTRIBUTE_PURE; +static int long_increment_overflow(long * number, int delta); +static int long_normalize_overflow(long * tensptr, + int * unitsptr, int base); +static int normalize_overflow(int * tensptr, int * unitsptr, + int base); +static void settzname(void); +static time_t time1(struct tm * tmp, + struct tm * (*funcp)(const time_t *, + long, struct tm *), + long offset); +static time_t time2(struct tm *tmp, + struct tm * (*funcp)(const time_t *, + long, struct tm*), + long offset, int * okayp); +static time_t time2sub(struct tm *tmp, + struct tm * (*funcp)(const time_t *, + long, struct tm*), + long offset, int * okayp, int do_norm_secs); +static struct tm * timesub(const time_t * timep, long offset, + const struct state * sp, struct tm * tmp); +static int tmcomp(const struct tm * atmp, + const struct tm * btmp); +static time_t transtime(time_t janfirst, int year, + const struct rule * rulep, long offset) + ATTRIBUTE_PURE; +static int typesequiv(const struct state * sp, int a, int b); +static int tzload(const char * name, struct state * sp, + int doextend); +static int tzparse(const char * name, struct state * sp, + int lastditch); + +#ifdef ALL_STATE +static struct state * lclptr; +static struct state * gmtptr; +#endif /* defined ALL_STATE */ + +#ifndef ALL_STATE +static struct state lclmem; +static struct state gmtmem; +#define lclptr (&lclmem) +#define gmtptr (&gmtmem) +#endif /* State Farm */ + +#ifndef TZ_STRLEN_MAX +#define TZ_STRLEN_MAX 255 +#endif /* !defined TZ_STRLEN_MAX */ + +static char lcl_TZname[TZ_STRLEN_MAX + 1]; +static int lcl_is_set; +static pthread_once_t gmt_once = PTHREAD_ONCE_INIT; +static pthread_rwlock_t lcl_rwlock = PTHREAD_RWLOCK_INITIALIZER; +static pthread_once_t gmtime_once = PTHREAD_ONCE_INIT; +static pthread_key_t gmtime_key; +static int gmtime_key_error; +static pthread_once_t localtime_once = PTHREAD_ONCE_INIT; +static pthread_key_t localtime_key; +static int localtime_key_error; + +char * tzname[2] = { + wildabbr, + wildabbr +}; + +/* +** Section 4.12.3 of X3.159-1989 requires that +** Except for the strftime function, these functions [asctime, +** ctime, gmtime, localtime] return values in one of two static +** objects: a broken-down time structure and an array of char. +** Thanks to Paul Eggert for noting this. +*/ + +static struct tm tm; + +#ifdef USG_COMPAT +time_t timezone = 0; +int daylight = 0; +#endif /* defined USG_COMPAT */ + +#ifdef ALTZONE +time_t altzone = 0; +#endif /* defined ALTZONE */ + +static long +detzcode(const char *const codep) +{ + long result; + int i; + + result = (codep[0] & 0x80) ? ~0L : 0; + for (i = 0; i < 4; ++i) + result = (result << 8) | (codep[i] & 0xff); + return result; +} + +static time_t +detzcode64(const char *const codep) +{ + register time_t result; + register int i; + + result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0; + for (i = 0; i < 8; ++i) + result = result * 256 + (codep[i] & 0xff); + return result; +} + +static void +settzname(void) +{ + struct state * sp = lclptr; + int i; + + tzname[0] = wildabbr; + tzname[1] = wildabbr; +#ifdef USG_COMPAT + daylight = 0; + timezone = 0; +#endif /* defined USG_COMPAT */ +#ifdef ALTZONE + altzone = 0; +#endif /* defined ALTZONE */ +#ifdef ALL_STATE + if (sp == NULL) { + tzname[0] = tzname[1] = gmt; + return; + } +#endif /* defined ALL_STATE */ + /* + ** And to get the latest zone names into tzname. . . + */ + for (i = 0; i < sp->typecnt; ++i) { + const struct ttinfo * const ttisp = &sp->ttis[sp->types[i]]; + + tzname[ttisp->tt_isdst] = + &sp->chars[ttisp->tt_abbrind]; +#ifdef USG_COMPAT + if (ttisp->tt_isdst) + daylight = 1; + if (!ttisp->tt_isdst) + timezone = -(ttisp->tt_gmtoff); +#endif /* defined USG_COMPAT */ +#ifdef ALTZONE + if (ttisp->tt_isdst) + altzone = -(ttisp->tt_gmtoff); +#endif /* defined ALTZONE */ + } + /* + ** Finally, scrub the abbreviations. + ** First, replace bogus characters. + */ + for (i = 0; i < sp->charcnt; ++i) + if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL) + sp->chars[i] = TZ_ABBR_ERR_CHAR; + /* + ** Second, truncate long abbreviations. + */ + for (i = 0; i < sp->typecnt; ++i) { + register const struct ttinfo * const ttisp = &sp->ttis[i]; + register char * cp = &sp->chars[ttisp->tt_abbrind]; + + if (strlen(cp) > TZ_ABBR_MAX_LEN && + strcmp(cp, GRANDPARENTED) != 0) + *(cp + TZ_ABBR_MAX_LEN) = '\0'; + } +} + +static int +differ_by_repeat(const time_t t1, const time_t t0) +{ + int_fast64_t _t0 = t0; + int_fast64_t _t1 = t1; + + if (TYPE_INTEGRAL(time_t) && + TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS) + return 0; + //turn ((int_fast64_t)(t1 - t0) == SECSPERREPEAT); + return _t1 - _t0 == SECSPERREPEAT; +} + +static int +tzload(name, sp, doextend) +const char * name; +struct state * const sp; +register const int doextend; +{ + const char * p; + int i; + int fid; + int stored; + int nread; + int res; + union { + struct tzhead tzhead; + char buf[2 * sizeof(struct tzhead) + + 2 * sizeof *sp + + 4 * TZ_MAX_TIMES]; + } *u; + + u = NULL; + res = -1; + sp->goback = sp->goahead = FALSE; + + /* XXX The following is from OpenBSD, and I'm not sure it is correct */ + if (name != NULL && issetugid() != 0) + if ((name[0] == ':' && name[1] == '/') || + name[0] == '/' || strchr(name, '.')) + name = NULL; + if (name == NULL && (name = TZDEFAULT) == NULL) + return -1; + { + int doaccess; + struct stat stab; + /* + ** Section 4.9.1 of the C standard says that + ** "FILENAME_MAX expands to an integral constant expression + ** that is the size needed for an array of char large enough + ** to hold the longest file name string that the implementation + ** guarantees can be opened." + */ + char *fullname; + + fullname = malloc(FILENAME_MAX + 1); + if (fullname == NULL) + goto out; + + if (name[0] == ':') + ++name; + doaccess = name[0] == '/'; + if (!doaccess) { + if ((p = TZDIR) == NULL) { + free(fullname); + return -1; + } + if (strlen(p) + 1 + strlen(name) >= FILENAME_MAX) { + free(fullname); + return -1; + } + (void) strcpy(fullname, p); + (void) strcat(fullname, "/"); + (void) strcat(fullname, name); + /* + ** Set doaccess if '.' (as in "../") shows up in name. + */ + if (strchr(name, '.') != NULL) + doaccess = TRUE; + name = fullname; + } + if (doaccess && access(name, R_OK) != 0) { + free(fullname); + return -1; + } + if ((fid = _open(name, OPEN_MODE)) == -1) { + free(fullname); + return -1; + } + if ((_fstat(fid, &stab) < 0) || !S_ISREG(stab.st_mode)) { + free(fullname); + _close(fid); + return -1; + } + free(fullname); + } + u = malloc(sizeof(*u)); + if (u == NULL) + goto out; + nread = _read(fid, u->buf, sizeof u->buf); + if (_close(fid) < 0 || nread <= 0) + goto out; + for (stored = 4; stored <= 8; stored *= 2) { + int ttisstdcnt; + int ttisgmtcnt; + + ttisstdcnt = (int) detzcode(u->tzhead.tzh_ttisstdcnt); + ttisgmtcnt = (int) detzcode(u->tzhead.tzh_ttisgmtcnt); + sp->leapcnt = (int) detzcode(u->tzhead.tzh_leapcnt); + sp->timecnt = (int) detzcode(u->tzhead.tzh_timecnt); + sp->typecnt = (int) detzcode(u->tzhead.tzh_typecnt); + sp->charcnt = (int) detzcode(u->tzhead.tzh_charcnt); + p = u->tzhead.tzh_charcnt + sizeof u->tzhead.tzh_charcnt; + if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS || + sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES || + sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES || + sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS || + (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) || + (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0)) + goto out; + if (nread - (p - u->buf) < + sp->timecnt * stored + /* ats */ + sp->timecnt + /* types */ + sp->typecnt * 6 + /* ttinfos */ + sp->charcnt + /* chars */ + sp->leapcnt * (stored + 4) + /* lsinfos */ + ttisstdcnt + /* ttisstds */ + ttisgmtcnt) /* ttisgmts */ + goto out; + for (i = 0; i < sp->timecnt; ++i) { + sp->ats[i] = (stored == 4) ? + detzcode(p) : detzcode64(p); + p += stored; + } + for (i = 0; i < sp->timecnt; ++i) { + sp->types[i] = (unsigned char) *p++; + if (sp->types[i] >= sp->typecnt) + goto out; + } + for (i = 0; i < sp->typecnt; ++i) { + struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + ttisp->tt_gmtoff = detzcode(p); + p += 4; + ttisp->tt_isdst = (unsigned char) *p++; + if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1) + goto out; + ttisp->tt_abbrind = (unsigned char) *p++; + if (ttisp->tt_abbrind < 0 || + ttisp->tt_abbrind > sp->charcnt) + goto out; + } + for (i = 0; i < sp->charcnt; ++i) + sp->chars[i] = *p++; + sp->chars[i] = '\0'; /* ensure '\0' at end */ + for (i = 0; i < sp->leapcnt; ++i) { + struct lsinfo * lsisp; + + lsisp = &sp->lsis[i]; + lsisp->ls_trans = (stored == 4) ? + detzcode(p) : detzcode64(p); + p += stored; + lsisp->ls_corr = detzcode(p); + p += 4; + } + for (i = 0; i < sp->typecnt; ++i) { + struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + if (ttisstdcnt == 0) + ttisp->tt_ttisstd = FALSE; + else { + ttisp->tt_ttisstd = *p++; + if (ttisp->tt_ttisstd != TRUE && + ttisp->tt_ttisstd != FALSE) + goto out; + } + } + for (i = 0; i < sp->typecnt; ++i) { + struct ttinfo * ttisp; + + ttisp = &sp->ttis[i]; + if (ttisgmtcnt == 0) + ttisp->tt_ttisgmt = FALSE; + else { + ttisp->tt_ttisgmt = *p++; + if (ttisp->tt_ttisgmt != TRUE && + ttisp->tt_ttisgmt != FALSE) + goto out; + } + } + /* + ** Out-of-sort ats should mean we're running on a + ** signed time_t system but using a data file with + ** unsigned values (or vice versa). + */ + for (i = 0; i < sp->timecnt - 2; ++i) + if (sp->ats[i] > sp->ats[i + 1]) { + ++i; + if (TYPE_SIGNED(time_t)) { + /* + ** Ignore the end (easy). + */ + sp->timecnt = i; + } else { + /* + ** Ignore the beginning (harder). + */ + register int j; + + for (j = 0; j + i < sp->timecnt; ++j) { + sp->ats[j] = sp->ats[j + i]; + sp->types[j] = sp->types[j + i]; + } + sp->timecnt = j; + } + break; + } + /* + ** If this is an old file, we're done. + */ + if (u->tzhead.tzh_version[0] == '\0') + break; + nread -= p - u->buf; + for (i = 0; i < nread; ++i) + u->buf[i] = p[i]; + /* + ** If this is a narrow integer time_t system, we're done. + */ + if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t)) + break; + } + if (doextend && nread > 2 && + u->buf[0] == '\n' && u->buf[nread - 1] == '\n' && + sp->typecnt + 2 <= TZ_MAX_TYPES) { + struct state *ts; + register int result; + + ts = malloc(sizeof(*ts)); + if (ts == NULL) + goto out; + u->buf[nread - 1] = '\0'; + result = tzparse(&u->buf[1], ts, FALSE); + if (result == 0 && ts->typecnt == 2 && + sp->charcnt + ts->charcnt <= TZ_MAX_CHARS) { + for (i = 0; i < 2; ++i) + ts->ttis[i].tt_abbrind += + sp->charcnt; + for (i = 0; i < ts->charcnt; ++i) + sp->chars[sp->charcnt++] = + ts->chars[i]; + i = 0; + while (i < ts->timecnt && + ts->ats[i] <= + sp->ats[sp->timecnt - 1]) + ++i; + while (i < ts->timecnt && + sp->timecnt < TZ_MAX_TIMES) { + sp->ats[sp->timecnt] = + ts->ats[i]; + sp->types[sp->timecnt] = + sp->typecnt + + ts->types[i]; + ++sp->timecnt; + ++i; + } + sp->ttis[sp->typecnt++] = ts->ttis[0]; + sp->ttis[sp->typecnt++] = ts->ttis[1]; + } + free(ts); + } + if (sp->timecnt > 1) { + for (i = 1; i < sp->timecnt; ++i) + if (typesequiv(sp, sp->types[i], sp->types[0]) && + differ_by_repeat(sp->ats[i], sp->ats[0])) { + sp->goback = TRUE; + break; + } + for (i = sp->timecnt - 2; i >= 0; --i) + if (typesequiv(sp, sp->types[sp->timecnt - 1], + sp->types[i]) && + differ_by_repeat(sp->ats[sp->timecnt - 1], + sp->ats[i])) { + sp->goahead = TRUE; + break; + } + } + res = 0; +out: + free(u); + return (res); +} + +static int +typesequiv(sp, a, b) +const struct state * const sp; +const int a; +const int b; +{ + register int result; + + if (sp == NULL || + a < 0 || a >= sp->typecnt || + b < 0 || b >= sp->typecnt) + result = FALSE; + else { + register const struct ttinfo * ap = &sp->ttis[a]; + register const struct ttinfo * bp = &sp->ttis[b]; + result = ap->tt_gmtoff == bp->tt_gmtoff && + ap->tt_isdst == bp->tt_isdst && + ap->tt_ttisstd == bp->tt_ttisstd && + ap->tt_ttisgmt == bp->tt_ttisgmt && + strcmp(&sp->chars[ap->tt_abbrind], + &sp->chars[bp->tt_abbrind]) == 0; + } + return result; +} + +static const int mon_lengths[2][MONSPERYEAR] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +static const int year_lengths[2] = { + DAYSPERNYEAR, DAYSPERLYEAR +}; + +/* +** Given a pointer into a time zone string, scan until a character that is not +** a valid character in a zone name is found. Return a pointer to that +** character. +*/ + +static const char * +getzname(strp) +const char * strp; +{ + char c; + + while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && + c != '+') + ++strp; + return strp; +} + +/* +** Given a pointer into an extended time zone string, scan until the ending +** delimiter of the zone name is located. Return a pointer to the delimiter. +** +** As with getzname above, the legal character set is actually quite +** restricted, with other characters producing undefined results. +** We don't do any checking here; checking is done later in common-case code. +*/ + +static const char * +getqzname(register const char *strp, const int delim) +{ + register int c; + + while ((c = *strp) != '\0' && c != delim) + ++strp; + return strp; +} + +/* +** Given a pointer into a time zone string, extract a number from that string. +** Check that the number is within a specified range; if it is not, return +** NULL. +** Otherwise, return a pointer to the first character not part of the number. +*/ + +static const char * +getnum(strp, nump, min, max) +const char * strp; +int * const nump; +const int min; +const int max; +{ + char c; + int num; + + if (strp == NULL || !is_digit(c = *strp)) + return NULL; + num = 0; + do { + num = num * 10 + (c - '0'); + if (num > max) + return NULL; /* illegal value */ + c = *++strp; + } while (is_digit(c)); + if (num < min) + return NULL; /* illegal value */ + *nump = num; + return strp; +} + +/* +** Given a pointer into a time zone string, extract a number of seconds, +** in hh[:mm[:ss]] form, from the string. +** If any error occurs, return NULL. +** Otherwise, return a pointer to the first character not part of the number +** of seconds. +*/ + +static const char * +getsecs(strp, secsp) +const char * strp; +long * const secsp; +{ + int num; + + /* + ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like + ** "M10.4.6/26", which does not conform to Posix, + ** but which specifies the equivalent of + ** ``02:00 on the first Sunday on or after 23 Oct''. + */ + strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); + if (strp == NULL) + return NULL; + *secsp = num * (long) SECSPERHOUR; + if (*strp == ':') { + ++strp; + strp = getnum(strp, &num, 0, MINSPERHOUR - 1); + if (strp == NULL) + return NULL; + *secsp += num * SECSPERMIN; + if (*strp == ':') { + ++strp; + /* `SECSPERMIN' allows for leap seconds. */ + strp = getnum(strp, &num, 0, SECSPERMIN); + if (strp == NULL) + return NULL; + *secsp += num; + } + } + return strp; +} + +/* +** Given a pointer into a time zone string, extract an offset, in +** [+-]hh[:mm[:ss]] form, from the string. +** If any error occurs, return NULL. +** Otherwise, return a pointer to the first character not part of the time. +*/ + +static const char * +getoffset(strp, offsetp) +const char * strp; +long * const offsetp; +{ + int neg = 0; + + if (*strp == '-') { + neg = 1; + ++strp; + } else if (*strp == '+') + ++strp; + strp = getsecs(strp, offsetp); + if (strp == NULL) + return NULL; /* illegal time */ + if (neg) + *offsetp = -*offsetp; + return strp; +} + +/* +** Given a pointer into a time zone string, extract a rule in the form +** date[/time]. See POSIX section 8 for the format of "date" and "time". +** If a valid rule is not found, return NULL. +** Otherwise, return a pointer to the first character not part of the rule. +*/ + +static const char * +getrule(strp, rulep) +const char * strp; +struct rule * const rulep; +{ + if (*strp == 'J') { + /* + ** Julian day. + */ + rulep->r_type = JULIAN_DAY; + ++strp; + strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); + } else if (*strp == 'M') { + /* + ** Month, week, day. + */ + rulep->r_type = MONTH_NTH_DAY_OF_WEEK; + ++strp; + strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); + if (strp == NULL) + return NULL; + if (*strp++ != '.') + return NULL; + strp = getnum(strp, &rulep->r_week, 1, 5); + if (strp == NULL) + return NULL; + if (*strp++ != '.') + return NULL; + strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); + } else if (is_digit(*strp)) { + /* + ** Day of year. + */ + rulep->r_type = DAY_OF_YEAR; + strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); + } else return NULL; /* invalid format */ + if (strp == NULL) + return NULL; + if (*strp == '/') { + /* + ** Time specified. + */ + ++strp; + strp = getsecs(strp, &rulep->r_time); + } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ + return strp; +} + +/* +** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the +** year, a rule, and the offset from UTC at the time that rule takes effect, +** calculate the Epoch-relative time that rule takes effect. +*/ + +static time_t +transtime(janfirst, year, rulep, offset) +const time_t janfirst; +const int year; +const struct rule * const rulep; +const long offset; +{ + int leapyear; + time_t value; + int i; + int d, m1, yy0, yy1, yy2, dow; + + INITIALIZE(value); + leapyear = isleap(year); + switch (rulep->r_type) { + + case JULIAN_DAY: + /* + ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap + ** years. + ** In non-leap years, or if the day number is 59 or less, just + ** add SECSPERDAY times the day number-1 to the time of + ** January 1, midnight, to get the day. + */ + value = janfirst + (rulep->r_day - 1) * SECSPERDAY; + if (leapyear && rulep->r_day >= 60) + value += SECSPERDAY; + break; + + case DAY_OF_YEAR: + /* + ** n - day of year. + ** Just add SECSPERDAY times the day number to the time of + ** January 1, midnight, to get the day. + */ + value = janfirst + rulep->r_day * SECSPERDAY; + break; + + case MONTH_NTH_DAY_OF_WEEK: + /* + ** Mm.n.d - nth "dth day" of month m. + */ + value = janfirst; + for (i = 0; i < rulep->r_mon - 1; ++i) + value += mon_lengths[leapyear][i] * SECSPERDAY; + + /* + ** Use Zeller's Congruence to get day-of-week of first day of + ** month. + */ + m1 = (rulep->r_mon + 9) % 12 + 1; + yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; + yy1 = yy0 / 100; + yy2 = yy0 % 100; + dow = ((26 * m1 - 2) / 10 + + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; + if (dow < 0) + dow += DAYSPERWEEK; + + /* + ** "dow" is the day-of-week of the first day of the month. Get + ** the day-of-month (zero-origin) of the first "dow" day of the + ** month. + */ + d = rulep->r_day - dow; + if (d < 0) + d += DAYSPERWEEK; + for (i = 1; i < rulep->r_week; ++i) { + if (d + DAYSPERWEEK >= + mon_lengths[leapyear][rulep->r_mon - 1]) + break; + d += DAYSPERWEEK; + } + + /* + ** "d" is the day-of-month (zero-origin) of the day we want. + */ + value += d * SECSPERDAY; + break; + } + + /* + ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in + ** question. To get the Epoch-relative time of the specified local + ** time on that day, add the transition time and the current offset + ** from UTC. + */ + return value + rulep->r_time + offset; +} + +/* +** Given a POSIX section 8-style TZ string, fill in the rule tables as +** appropriate. +*/ + +static int +tzparse(name, sp, lastditch) +const char * name; +struct state * const sp; +const int lastditch; +{ + const char * stdname; + const char * dstname; + size_t stdlen; + size_t dstlen; + long stdoffset; + long dstoffset; + time_t * atp; + unsigned char * typep; + char * cp; + int load_result; + + INITIALIZE(dstname); + stdname = name; + if (lastditch) { + stdlen = strlen(name); /* length of standard zone name */ + name += stdlen; + if (stdlen >= sizeof sp->chars) + stdlen = (sizeof sp->chars) - 1; + stdoffset = 0; + } else { + if (*name == '<') { + name++; + stdname = name; + name = getqzname(name, '>'); + if (*name != '>') + return (-1); + stdlen = name - stdname; + name++; + } else { + name = getzname(name); + stdlen = name - stdname; + } + if (*name == '\0') + return -1; /* was "stdoffset = 0;" */ + else { + name = getoffset(name, &stdoffset); + if (name == NULL) + return -1; + } + } + load_result = tzload(TZDEFRULES, sp, FALSE); + if (load_result != 0) + sp->leapcnt = 0; /* so, we're off a little */ + if (*name != '\0') { + if (*name == '<') { + dstname = ++name; + name = getqzname(name, '>'); + if (*name != '>') + return -1; + dstlen = name - dstname; + name++; + } else { + dstname = name; + name = getzname(name); + dstlen = name - dstname; /* length of DST zone name */ + } + if (*name != '\0' && *name != ',' && *name != ';') { + name = getoffset(name, &dstoffset); + if (name == NULL) + return -1; + } else dstoffset = stdoffset - SECSPERHOUR; + if (*name == '\0' && load_result != 0) + name = TZDEFRULESTRING; + if (*name == ',' || *name == ';') { + struct rule start; + struct rule end; + int year; + time_t janfirst; + time_t starttime; + time_t endtime; + + ++name; + if ((name = getrule(name, &start)) == NULL) + return -1; + if (*name++ != ',') + return -1; + if ((name = getrule(name, &end)) == NULL) + return -1; + if (*name != '\0') + return -1; + sp->typecnt = 2; /* standard time and DST */ + /* + ** Two transitions per year, from EPOCH_YEAR forward. + */ + sp->ttis[0].tt_gmtoff = -dstoffset; + sp->ttis[0].tt_isdst = 1; + sp->ttis[0].tt_abbrind = stdlen + 1; + sp->ttis[1].tt_gmtoff = -stdoffset; + sp->ttis[1].tt_isdst = 0; + sp->ttis[1].tt_abbrind = 0; + atp = sp->ats; + typep = sp->types; + janfirst = 0; + sp->timecnt = 0; + for (year = EPOCH_YEAR; + sp->timecnt + 2 <= TZ_MAX_TIMES; + ++year) { + time_t newfirst; + + starttime = transtime(janfirst, year, &start, + stdoffset); + endtime = transtime(janfirst, year, &end, + dstoffset); + if (starttime > endtime) { + *atp++ = endtime; + *typep++ = 1; /* DST ends */ + *atp++ = starttime; + *typep++ = 0; /* DST begins */ + } else { + *atp++ = starttime; + *typep++ = 0; /* DST begins */ + *atp++ = endtime; + *typep++ = 1; /* DST ends */ + } + sp->timecnt += 2; + newfirst = janfirst; + newfirst += year_lengths[isleap(year)] * + SECSPERDAY; + if (newfirst <= janfirst) + break; + janfirst = newfirst; + } + } else { + long theirstdoffset; + long theirdstoffset; + long theiroffset; + int isdst; + int i; + int j; + + if (*name != '\0') + return -1; + /* + ** Initial values of theirstdoffset and theirdstoffset. + */ + theirstdoffset = 0; + for (i = 0; i < sp->timecnt; ++i) { + j = sp->types[i]; + if (!sp->ttis[j].tt_isdst) { + theirstdoffset = + -sp->ttis[j].tt_gmtoff; + break; + } + } + theirdstoffset = 0; + for (i = 0; i < sp->timecnt; ++i) { + j = sp->types[i]; + if (sp->ttis[j].tt_isdst) { + theirdstoffset = + -sp->ttis[j].tt_gmtoff; + break; + } + } + /* + ** Initially we're assumed to be in standard time. + */ + isdst = FALSE; + theiroffset = theirstdoffset; + /* + ** Now juggle transition times and types + ** tracking offsets as you do. + */ + for (i = 0; i < sp->timecnt; ++i) { + j = sp->types[i]; + sp->types[i] = sp->ttis[j].tt_isdst; + if (sp->ttis[j].tt_ttisgmt) { + /* No adjustment to transition time */ + } else { + /* + ** If summer time is in effect, and the + ** transition time was not specified as + ** standard time, add the summer time + ** offset to the transition time; + ** otherwise, add the standard time + ** offset to the transition time. + */ + /* + ** Transitions from DST to DDST + ** will effectively disappear since + ** POSIX provides for only one DST + ** offset. + */ + if (isdst && !sp->ttis[j].tt_ttisstd) { + sp->ats[i] += dstoffset - + theirdstoffset; + } else { + sp->ats[i] += stdoffset - + theirstdoffset; + } + } + theiroffset = -sp->ttis[j].tt_gmtoff; + if (sp->ttis[j].tt_isdst) + theirdstoffset = theiroffset; + else theirstdoffset = theiroffset; + } + /* + ** Finally, fill in ttis. + ** ttisstd and ttisgmt need not be handled. + */ + sp->ttis[0].tt_gmtoff = -stdoffset; + sp->ttis[0].tt_isdst = FALSE; + sp->ttis[0].tt_abbrind = 0; + sp->ttis[1].tt_gmtoff = -dstoffset; + sp->ttis[1].tt_isdst = TRUE; + sp->ttis[1].tt_abbrind = stdlen + 1; + sp->typecnt = 2; + } + } else { + dstlen = 0; + sp->typecnt = 1; /* only standard time */ + sp->timecnt = 0; + sp->ttis[0].tt_gmtoff = -stdoffset; + sp->ttis[0].tt_isdst = 0; + sp->ttis[0].tt_abbrind = 0; + } + sp->charcnt = stdlen + 1; + if (dstlen != 0) + sp->charcnt += dstlen + 1; + if ((size_t) sp->charcnt > sizeof sp->chars) + return -1; + cp = sp->chars; + (void) strncpy(cp, stdname, stdlen); + cp += stdlen; + *cp++ = '\0'; + if (dstlen != 0) { + (void) strncpy(cp, dstname, dstlen); + *(cp + dstlen) = '\0'; + } + return 0; +} + +static void +gmtload(struct state *const sp) +{ + if (tzload(gmt, sp, TRUE) != 0) + (void) tzparse(gmt, sp, TRUE); +} + +static void +tzsetwall_basic(int rdlocked) +{ + if (!rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); + if (lcl_is_set < 0) { + if (!rdlocked) + _RWLOCK_UNLOCK(&lcl_rwlock); + return; + } + _RWLOCK_UNLOCK(&lcl_rwlock); + + _RWLOCK_WRLOCK(&lcl_rwlock); + lcl_is_set = -1; + +#ifdef ALL_STATE + if (lclptr == NULL) { + lclptr = calloc(1, sizeof *lclptr); + if (lclptr == NULL) { + settzname(); /* all we can do */ + _RWLOCK_UNLOCK(&lcl_rwlock); + if (rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); + return; + } + } +#endif /* defined ALL_STATE */ + if (tzload((char *) NULL, lclptr, TRUE) != 0) + gmtload(lclptr); + settzname(); + _RWLOCK_UNLOCK(&lcl_rwlock); + + if (rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); +} + +void +tzsetwall(void) +{ + tzsetwall_basic(0); +} + +static void +tzset_basic(int rdlocked) +{ + const char * name; + + name = getenv("TZ"); + if (name == NULL) { + tzsetwall_basic(rdlocked); + return; + } + + if (!rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); + if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0) { + if (!rdlocked) + _RWLOCK_UNLOCK(&lcl_rwlock); + return; + } + _RWLOCK_UNLOCK(&lcl_rwlock); + + _RWLOCK_WRLOCK(&lcl_rwlock); + lcl_is_set = strlen(name) < sizeof lcl_TZname; + if (lcl_is_set) + (void) strcpy(lcl_TZname, name); + +#ifdef ALL_STATE + if (lclptr == NULL) { + lclptr = (struct state *) calloc(1, sizeof *lclptr); + if (lclptr == NULL) { + settzname(); /* all we can do */ + _RWLOCK_UNLOCK(&lcl_rwlock); + if (rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); + return; + } + } +#endif /* defined ALL_STATE */ + if (*name == '\0') { + /* + ** User wants it fast rather than right. + */ + lclptr->leapcnt = 0; /* so, we're off a little */ + lclptr->timecnt = 0; + lclptr->typecnt = 0; + lclptr->ttis[0].tt_isdst = 0; + lclptr->ttis[0].tt_gmtoff = 0; + lclptr->ttis[0].tt_abbrind = 0; + (void) strcpy(lclptr->chars, gmt); + } else if (tzload(name, lclptr, TRUE) != 0) + if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0) + (void) gmtload(lclptr); + settzname(); + _RWLOCK_UNLOCK(&lcl_rwlock); + + if (rdlocked) + _RWLOCK_RDLOCK(&lcl_rwlock); +} + +void +tzset(void) +{ + tzset_basic(0); +} + +/* +** The easy way to behave "as if no library function calls" localtime +** is to not call it--so we drop its guts into "localsub", which can be +** freely called. (And no, the PANS doesn't require the above behavior-- +** but it *is* desirable.) +** +** The unused offset argument is for the benefit of mktime variants. +*/ + +/*ARGSUSED*/ +static struct tm * +localsub(const time_t *const timep, const long offset, struct tm *const tmp) +{ + struct state * sp; + const struct ttinfo * ttisp; + int i; + struct tm * result; + const time_t t = *timep; + + sp = lclptr; +#ifdef ALL_STATE + if (sp == NULL) + return gmtsub(timep, offset, tmp); +#endif /* defined ALL_STATE */ + if ((sp->goback && t < sp->ats[0]) || + (sp->goahead && t > sp->ats[sp->timecnt - 1])) { + time_t newt = t; + register time_t seconds; + register time_t tcycles; + register int_fast64_t icycles; + + if (t < sp->ats[0]) + seconds = sp->ats[0] - t; + else seconds = t - sp->ats[sp->timecnt - 1]; + --seconds; + tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR; + ++tcycles; + icycles = tcycles; + if (tcycles - icycles >= 1 || icycles - tcycles >= 1) + return NULL; + seconds = icycles; + seconds *= YEARSPERREPEAT; + seconds *= AVGSECSPERYEAR; + if (t < sp->ats[0]) + newt += seconds; + else newt -= seconds; + if (newt < sp->ats[0] || + newt > sp->ats[sp->timecnt - 1]) + return NULL; /* "cannot happen" */ + result = localsub(&newt, offset, tmp); + if (result == tmp) { + register time_t newy; + + newy = tmp->tm_year; + if (t < sp->ats[0]) + newy -= icycles * YEARSPERREPEAT; + else newy += icycles * YEARSPERREPEAT; + tmp->tm_year = newy; + if (tmp->tm_year != newy) + return NULL; + } + return result; + } + if (sp->timecnt == 0 || t < sp->ats[0]) { + i = 0; + while (sp->ttis[i].tt_isdst) + if (++i >= sp->typecnt) { + i = 0; + break; + } + } else { + register int lo = 1; + register int hi = sp->timecnt; + + while (lo < hi) { + register int mid = (lo + hi) >> 1; + + if (t < sp->ats[mid]) + hi = mid; + else lo = mid + 1; + } + i = (int) sp->types[lo - 1]; + } + ttisp = &sp->ttis[i]; + /* + ** To get (wrong) behavior that's compatible with System V Release 2.0 + ** you'd replace the statement below with + ** t += ttisp->tt_gmtoff; + ** timesub(&t, 0L, sp, tmp); + */ + result = timesub(&t, ttisp->tt_gmtoff, sp, tmp); + tmp->tm_isdst = ttisp->tt_isdst; + tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind]; +#ifdef TM_ZONE + tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; +#endif /* defined TM_ZONE */ + return result; +} + +static void +localtime_key_init(void) +{ + + localtime_key_error = _pthread_key_create(&localtime_key, free); +} + +struct tm * +localtime(const time_t *const timep) +{ + struct tm *p_tm; + + if (__isthreaded != 0) { + _pthread_once(&localtime_once, localtime_key_init); + if (localtime_key_error != 0) { + errno = localtime_key_error; + return(NULL); + } + p_tm = _pthread_getspecific(localtime_key); + if (p_tm == NULL) { + if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) + == NULL) + return(NULL); + _pthread_setspecific(localtime_key, p_tm); + } + _RWLOCK_RDLOCK(&lcl_rwlock); + tzset_basic(1); + p_tm = localsub(timep, 0L, p_tm); + _RWLOCK_UNLOCK(&lcl_rwlock); + } else { + tzset_basic(0); + p_tm = localsub(timep, 0L, &tm); + } + return(p_tm); +} + +/* +** Re-entrant version of localtime. +*/ + +struct tm * +localtime_r(const time_t *const timep, struct tm *tmp) +{ + _RWLOCK_RDLOCK(&lcl_rwlock); + tzset_basic(1); + tmp = localsub(timep, 0L, tmp); + _RWLOCK_UNLOCK(&lcl_rwlock); + return tmp; +} + +static void +gmt_init(void) +{ + +#ifdef ALL_STATE + gmtptr = (struct state *) calloc(1, sizeof *gmtptr); + if (gmtptr != NULL) +#endif /* defined ALL_STATE */ + gmtload(gmtptr); +} + +/* +** gmtsub is to gmtime as localsub is to localtime. +*/ + +static struct tm * +gmtsub(timep, offset, tmp) +const time_t * const timep; +const long offset; +struct tm * const tmp; +{ + register struct tm * result; + + _once(&gmt_once, gmt_init); + result = timesub(timep, offset, gmtptr, tmp); +#ifdef TM_ZONE + /* + ** Could get fancy here and deliver something such as + ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero, + ** but this is no time for a treasure hunt. + */ + if (offset != 0) + tmp->TM_ZONE = wildabbr; + else { +#ifdef ALL_STATE + if (gmtptr == NULL) + tmp->TM_ZONE = gmt; + else tmp->TM_ZONE = gmtptr->chars; +#endif /* defined ALL_STATE */ +#ifndef ALL_STATE + tmp->TM_ZONE = gmtptr->chars; +#endif /* State Farm */ + } +#endif /* defined TM_ZONE */ + return result; +} + +static void +gmtime_key_init(void) +{ + + gmtime_key_error = _pthread_key_create(&gmtime_key, free); +} + +struct tm * +gmtime(const time_t *const timep) +{ + struct tm *p_tm; + + if (__isthreaded != 0) { + _pthread_once(&gmtime_once, gmtime_key_init); + if (gmtime_key_error != 0) { + errno = gmtime_key_error; + return(NULL); + } + /* + * Changed to follow POSIX.1 threads standard, which + * is what BSD currently has. + */ + if ((p_tm = _pthread_getspecific(gmtime_key)) == NULL) { + if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) + == NULL) { + return(NULL); + } + _pthread_setspecific(gmtime_key, p_tm); + } + gmtsub(timep, 0L, p_tm); + return(p_tm); + } + else { + gmtsub(timep, 0L, &tm); + return(&tm); + } +} + +/* +* Re-entrant version of gmtime. +*/ + +struct tm * +gmtime_r(const time_t *const timep, struct tm *tmp) +{ + return gmtsub(timep, 0L, tmp); +} + +#ifdef STD_INSPIRED + +struct tm * +offtime(const time_t *const timep, const long offset) +{ + return gmtsub(timep, offset, &tm); +} + +#endif /* defined STD_INSPIRED */ + +/* +** Return the number of leap years through the end of the given year +** where, to make the math easy, the answer for year zero is defined as zero. +*/ + +static int +leaps_thru_end_of(y) +register const int y; +{ + return (y >= 0) ? (y / 4 - y / 100 + y / 400) : + -(leaps_thru_end_of(-(y + 1)) + 1); +} + +static struct tm * +timesub(timep, offset, sp, tmp) +const time_t * const timep; +const long offset; +const struct state * const sp; +struct tm * const tmp; +{ + const struct lsinfo * lp; + time_t tdays; + int idays; /* unsigned would be so 2003 */ + long rem; + int y; + const int * ip; + long corr; + int hit; + int i; + + corr = 0; + hit = 0; +#ifdef ALL_STATE + i = (sp == NULL) ? 0 : sp->leapcnt; +#endif /* defined ALL_STATE */ +#ifndef ALL_STATE + i = sp->leapcnt; +#endif /* State Farm */ + while (--i >= 0) { + lp = &sp->lsis[i]; + if (*timep >= lp->ls_trans) { + if (*timep == lp->ls_trans) { + hit = ((i == 0 && lp->ls_corr > 0) || + lp->ls_corr > sp->lsis[i - 1].ls_corr); + if (hit) + while (i > 0 && + sp->lsis[i].ls_trans == + sp->lsis[i - 1].ls_trans + 1 && + sp->lsis[i].ls_corr == + sp->lsis[i - 1].ls_corr + 1) { + ++hit; + --i; + } + } + corr = lp->ls_corr; + break; + } + } + y = EPOCH_YEAR; + tdays = *timep / SECSPERDAY; + rem = *timep - tdays * SECSPERDAY; + while (tdays < 0 || tdays >= year_lengths[isleap(y)]) { + int newy; + register time_t tdelta; + register int idelta; + register int leapdays; + + tdelta = tdays / DAYSPERLYEAR; + idelta = tdelta; + if (tdelta - idelta >= 1 || idelta - tdelta >= 1) + return NULL; + if (idelta == 0) + idelta = (tdays < 0) ? -1 : 1; + newy = y; + if (increment_overflow(&newy, idelta)) + return NULL; + leapdays = leaps_thru_end_of(newy - 1) - + leaps_thru_end_of(y - 1); + tdays -= ((time_t) newy - y) * DAYSPERNYEAR; + tdays -= leapdays; + y = newy; + } + { + register long seconds; + + seconds = tdays * SECSPERDAY + 0.5; + tdays = seconds / SECSPERDAY; + rem += seconds - tdays * SECSPERDAY; + } + /* + ** Given the range, we can now fearlessly cast... + */ + idays = tdays; + rem += offset - corr; + while (rem < 0) { + rem += SECSPERDAY; + --idays; + } + while (rem >= SECSPERDAY) { + rem -= SECSPERDAY; + ++idays; + } + while (idays < 0) { + if (increment_overflow(&y, -1)) + return NULL; + idays += year_lengths[isleap(y)]; + } + while (idays >= year_lengths[isleap(y)]) { + idays -= year_lengths[isleap(y)]; + if (increment_overflow(&y, 1)) + return NULL; + } + tmp->tm_year = y; + if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) + return NULL; + tmp->tm_yday = idays; + /* + ** The "extra" mods below avoid overflow problems. + */ + tmp->tm_wday = EPOCH_WDAY + + ((y - EPOCH_YEAR) % DAYSPERWEEK) * + (DAYSPERNYEAR % DAYSPERWEEK) + + leaps_thru_end_of(y - 1) - + leaps_thru_end_of(EPOCH_YEAR - 1) + + idays; + tmp->tm_wday %= DAYSPERWEEK; + if (tmp->tm_wday < 0) + tmp->tm_wday += DAYSPERWEEK; + tmp->tm_hour = (int) (rem / SECSPERHOUR); + rem %= SECSPERHOUR; + tmp->tm_min = (int) (rem / SECSPERMIN); + /* + ** A positive leap second requires a special + ** representation. This uses "... ??:59:60" et seq. + */ + tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; + ip = mon_lengths[isleap(y)]; + for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) + idays -= ip[tmp->tm_mon]; + tmp->tm_mday = (int) (idays + 1); + tmp->tm_isdst = 0; +#ifdef TM_GMTOFF + tmp->TM_GMTOFF = offset; +#endif /* defined TM_GMTOFF */ + return tmp; +} + +char * +ctime(const time_t *const timep) +{ +/* +** Section 4.12.3.2 of X3.159-1989 requires that +** The ctime function converts the calendar time pointed to by timer +** to local time in the form of a string. It is equivalent to +** asctime(localtime(timer)) +*/ + return asctime(localtime(timep)); +} + +char * +ctime_r(const time_t *const timep, char *buf) +{ + struct tm mytm; + + return asctime_r(localtime_r(timep, &mytm), buf); +} + +/* +** Adapted from code provided by Robert Elz, who writes: +** The "best" way to do mktime I think is based on an idea of Bob +** Kridle's (so its said...) from a long time ago. +** It does a binary search of the time_t space. Since time_t's are +** just 32 bits, its a max of 32 iterations (even at 64 bits it +** would still be very reasonable). +*/ + +#ifndef WRONG +#define WRONG (-1) +#endif /* !defined WRONG */ + +/* +** Simplified normalize logic courtesy Paul Eggert. +*/ + +static int +increment_overflow(number, delta) +int * number; +int delta; +{ + int number0; + + number0 = *number; + *number += delta; + return (*number < number0) != (delta < 0); +} + +static int +long_increment_overflow(number, delta) +long * number; +int delta; +{ + long number0; + + number0 = *number; + *number += delta; + return (*number < number0) != (delta < 0); +} + +static int +normalize_overflow(int *const tensptr, int *const unitsptr, const int base) +{ + int tensdelta; + + tensdelta = (*unitsptr >= 0) ? + (*unitsptr / base) : + (-1 - (-1 - *unitsptr) / base); + *unitsptr -= tensdelta * base; + return increment_overflow(tensptr, tensdelta); +} + +static int +long_normalize_overflow(long *const tensptr, int *const unitsptr, const int base) +{ + register int tensdelta; + + tensdelta = (*unitsptr >= 0) ? + (*unitsptr / base) : + (-1 - (-1 - *unitsptr) / base); + *unitsptr -= tensdelta * base; + return long_increment_overflow(tensptr, tensdelta); +} + +static int +tmcomp(atmp, btmp) +const struct tm * const atmp; +const struct tm * const btmp; +{ + int result; + + if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && + (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && + (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && + (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && + (result = (atmp->tm_min - btmp->tm_min)) == 0) + result = atmp->tm_sec - btmp->tm_sec; + return result; +} + +static time_t +time2sub(struct tm *const tmp, + struct tm *(*const funcp)(const time_t *, long, struct tm *), + const long offset, + int *const okayp, + const int do_norm_secs) +{ + const struct state * sp; + int dir; + int i, j; + int saved_seconds; + long li; + time_t lo; + time_t hi; + long y; + time_t newt; + time_t t; + struct tm yourtm, mytm; + + *okayp = FALSE; + yourtm = *tmp; + if (do_norm_secs) { + if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, + SECSPERMIN)) + return WRONG; + } + if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) + return WRONG; + if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) + return WRONG; + y = yourtm.tm_year; + if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR)) + return WRONG; + /* + ** Turn y into an actual year number for now. + ** It is converted back to an offset from TM_YEAR_BASE later. + */ + if (long_increment_overflow(&y, TM_YEAR_BASE)) + return WRONG; + while (yourtm.tm_mday <= 0) { + if (long_increment_overflow(&y, -1)) + return WRONG; + li = y + (1 < yourtm.tm_mon); + yourtm.tm_mday += year_lengths[isleap(li)]; + } + while (yourtm.tm_mday > DAYSPERLYEAR) { + li = y + (1 < yourtm.tm_mon); + yourtm.tm_mday -= year_lengths[isleap(li)]; + if (long_increment_overflow(&y, 1)) + return WRONG; + } + for ( ; ; ) { + i = mon_lengths[isleap(y)][yourtm.tm_mon]; + if (yourtm.tm_mday <= i) + break; + yourtm.tm_mday -= i; + if (++yourtm.tm_mon >= MONSPERYEAR) { + yourtm.tm_mon = 0; + if (long_increment_overflow(&y, 1)) + return WRONG; + } + } + if (long_increment_overflow(&y, -TM_YEAR_BASE)) + return WRONG; + yourtm.tm_year = y; + if (yourtm.tm_year != y) + return WRONG; + /* Don't go below 1900 for POLA */ + if (yourtm.tm_year < 0) + return WRONG; + if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) + saved_seconds = 0; + else if (y + TM_YEAR_BASE < EPOCH_YEAR) { + /* + ** We can't set tm_sec to 0, because that might push the + ** time below the minimum representable time. + ** Set tm_sec to 59 instead. + ** This assumes that the minimum representable time is + ** not in the same minute that a leap second was deleted from, + ** which is a safer assumption than using 58 would be. + */ + if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) + return WRONG; + saved_seconds = yourtm.tm_sec; + yourtm.tm_sec = SECSPERMIN - 1; + } else { + saved_seconds = yourtm.tm_sec; + yourtm.tm_sec = 0; + } + /* + ** Do a binary search (this works whatever time_t's type is). + */ + if (!TYPE_SIGNED(time_t)) { + lo = 0; + hi = lo - 1; + } else if (!TYPE_INTEGRAL(time_t)) { + if (sizeof(time_t) > sizeof(float)) + hi = (time_t) DBL_MAX; + else hi = (time_t) FLT_MAX; + lo = -hi; + } else { + lo = 1; + for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i) + lo *= 2; + hi = -(lo + 1); + } + for ( ; ; ) { + t = lo / 2 + hi / 2; + if (t < lo) + t = lo; + else if (t > hi) + t = hi; + if ((*funcp)(&t, offset, &mytm) == NULL) { + /* + ** Assume that t is too extreme to be represented in + ** a struct tm; arrange things so that it is less + ** extreme on the next pass. + */ + dir = (t > 0) ? 1 : -1; + } else dir = tmcomp(&mytm, &yourtm); + if (dir != 0) { + if (t == lo) { + ++t; + if (t <= lo) + return WRONG; + ++lo; + } else if (t == hi) { + --t; + if (t >= hi) + return WRONG; + --hi; + } + if (lo > hi) + return WRONG; + if (dir > 0) + hi = t; + else lo = t; + continue; + } + if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) + break; + /* + ** Right time, wrong type. + ** Hunt for right time, right type. + ** It's okay to guess wrong since the guess + ** gets checked. + */ + sp = (const struct state *) + ((funcp == localsub) ? lclptr : gmtptr); +#ifdef ALL_STATE + if (sp == NULL) + return WRONG; +#endif /* defined ALL_STATE */ + for (i = sp->typecnt - 1; i >= 0; --i) { + if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) + continue; + for (j = sp->typecnt - 1; j >= 0; --j) { + if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) + continue; + newt = t + sp->ttis[j].tt_gmtoff - + sp->ttis[i].tt_gmtoff; + if ((*funcp)(&newt, offset, &mytm) == NULL) + continue; + if (tmcomp(&mytm, &yourtm) != 0) + continue; + if (mytm.tm_isdst != yourtm.tm_isdst) + continue; + /* + ** We have a match. + */ + t = newt; + goto label; + } + } + return WRONG; + } +label: + newt = t + saved_seconds; + if ((newt < t) != (saved_seconds < 0)) + return WRONG; + t = newt; + if ((*funcp)(&t, offset, tmp)) + *okayp = TRUE; + return t; +} + +static time_t +time2(struct tm * const tmp, + struct tm * (*const funcp)(const time_t *, long, struct tm *), + const long offset, + int *const okayp) +{ + time_t t; + + /* + ** First try without normalization of seconds + ** (in case tm_sec contains a value associated with a leap second). + ** If that fails, try with normalization of seconds. + */ + t = time2sub(tmp, funcp, offset, okayp, FALSE); + return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE); +} + +static time_t +time1(tmp, funcp, offset) +struct tm * const tmp; +struct tm * (* const funcp)(const time_t *, long, struct tm *); +const long offset; +{ + time_t t; + const struct state * sp; + int samei, otheri; + int sameind, otherind; + int i; + int nseen; + int seen[TZ_MAX_TYPES]; + int types[TZ_MAX_TYPES]; + int okay; + + if (tmp == NULL) { + errno = EINVAL; + return WRONG; + } + + if (tmp->tm_isdst > 1) + tmp->tm_isdst = 1; + t = time2(tmp, funcp, offset, &okay); +#ifdef PCTS + /* + ** PCTS code courtesy Grant Sullivan. + */ + if (okay) + return t; + if (tmp->tm_isdst < 0) + tmp->tm_isdst = 0; /* reset to std and try again */ +#endif /* defined PCTS */ +#ifndef PCTS + if (okay || tmp->tm_isdst < 0) + return t; +#endif /* !defined PCTS */ + /* + ** We're supposed to assume that somebody took a time of one type + ** and did some math on it that yielded a "struct tm" that's bad. + ** We try to divine the type they started from and adjust to the + ** type they need. + */ + sp = (const struct state *) ((funcp == localsub) ? lclptr : gmtptr); +#ifdef ALL_STATE + if (sp == NULL) + return WRONG; +#endif /* defined ALL_STATE */ + for (i = 0; i < sp->typecnt; ++i) + seen[i] = FALSE; + nseen = 0; + for (i = sp->timecnt - 1; i >= 0; --i) + if (!seen[sp->types[i]]) { + seen[sp->types[i]] = TRUE; + types[nseen++] = sp->types[i]; + } + for (sameind = 0; sameind < nseen; ++sameind) { + samei = types[sameind]; + if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) + continue; + for (otherind = 0; otherind < nseen; ++otherind) { + otheri = types[otherind]; + if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) + continue; + tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - + sp->ttis[samei].tt_gmtoff; + tmp->tm_isdst = !tmp->tm_isdst; + t = time2(tmp, funcp, offset, &okay); + if (okay) + return t; + tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - + sp->ttis[samei].tt_gmtoff; + tmp->tm_isdst = !tmp->tm_isdst; + } + } + return WRONG; +} + +time_t +mktime(struct tm *const tmp) +{ + time_t mktime_return_value; + _RWLOCK_RDLOCK(&lcl_rwlock); + tzset_basic(1); + mktime_return_value = time1(tmp, localsub, 0L); + _RWLOCK_UNLOCK(&lcl_rwlock); + return(mktime_return_value); +} + +#ifdef STD_INSPIRED + +time_t +timelocal(struct tm *const tmp) +{ + if (tmp != NULL) + tmp->tm_isdst = -1; /* in case it wasn't initialized */ + return mktime(tmp); +} + +time_t +timegm(struct tm *const tmp) +{ + if (tmp != NULL) + tmp->tm_isdst = 0; + return time1(tmp, gmtsub, 0L); +} + +time_t +timeoff(struct tm *const tmp, const long offset) +{ + if (tmp != NULL) + tmp->tm_isdst = 0; + return time1(tmp, gmtsub, offset); +} + +#endif /* defined STD_INSPIRED */ + +#ifdef CMUCS + +/* +** The following is supplied for compatibility with +** previous versions of the CMUCS runtime library. +*/ + +long +gtime(struct tm *const tmp) +{ + const time_t t = mktime(tmp); + + if (t == WRONG) + return -1; + return t; +} + +#endif /* defined CMUCS */ + +/* +** XXX--is the below the right way to conditionalize?? +*/ + +#ifdef STD_INSPIRED + +/* +** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599 +** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which +** is not the case if we are accounting for leap seconds. +** So, we provide the following conversion routines for use +** when exchanging timestamps with POSIX conforming systems. +*/ + +static long +leapcorr(time_t *timep) +{ + struct state * sp; + struct lsinfo * lp; + int i; + + sp = lclptr; + i = sp->leapcnt; + while (--i >= 0) { + lp = &sp->lsis[i]; + if (*timep >= lp->ls_trans) + return lp->ls_corr; + } + return 0; +} + +time_t +time2posix(time_t t) +{ + tzset(); + return t - leapcorr(&t); +} + +time_t +posix2time(time_t t) +{ + time_t x; + time_t y; + + tzset(); + /* + ** For a positive leap second hit, the result + ** is not unique. For a negative leap second + ** hit, the corresponding time doesn't exist, + ** so we return an adjacent second. + */ + x = t + leapcorr(&t); + y = x - leapcorr(&x); + if (y < t) { + do { + x++; + y = x - leapcorr(&x); + } while (y < t); + if (t != y) + return x - 1; + } else if (y > t) { + do { + --x; + y = x - leapcorr(&x); + } while (y > t); + if (t != y) + return x + 1; + } + return x; +} + +#endif /* defined STD_INSPIRED */ diff --git a/contrib/tzcode/stdtime/private.h b/contrib/tzcode/stdtime/private.h new file mode 100644 index 0000000..5b60cd1 --- /dev/null +++ b/contrib/tzcode/stdtime/private.h @@ -0,0 +1,327 @@ +#ifndef PRIVATE_H + +#define PRIVATE_H + +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +** +** $FreeBSD: releng/11.1/contrib/tzcode/stdtime/private.h 289027 2015-10-08 11:42:15Z rodrigc $ +*/ + +/* Stuff moved from Makefile.inc to reduce clutter */ +#ifndef TM_GMTOFF +#define TM_GMTOFF tm_gmtoff +#define TM_ZONE tm_zone +#define STD_INSPIRED 1 +#define PCTS 1 +#define HAVE_LONG_DOUBLE 1 +#define HAVE_STRERROR 1 +#define HAVE_UNISTD_H 1 +#define LOCALE_HOME _PATH_LOCALE +#define TZDIR "/usr/share/zoneinfo" +#endif /* ndef TM_GMTOFF */ + +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + +/* +** ID +*/ + +#ifndef lint +#ifndef NOID +/* +static char privatehid[] = "@(#)private.h 8.6"; +*/ +#endif /* !defined NOID */ +#endif /* !defined lint */ + +#define GRANDPARENTED "Local time zone must be set--see zic manual page" + +/* +** Defaults for preprocessor symbols. +** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'. +*/ + +#ifndef HAVE_ADJTIME +#define HAVE_ADJTIME 1 +#endif /* !defined HAVE_ADJTIME */ + +#ifndef HAVE_GETTEXT +#define HAVE_GETTEXT 0 +#endif /* !defined HAVE_GETTEXT */ + +#ifndef HAVE_INCOMPATIBLE_CTIME_R +#define HAVE_INCOMPATIBLE_CTIME_R 0 +#endif /* !defined INCOMPATIBLE_CTIME_R */ + +#ifndef HAVE_SETTIMEOFDAY +#define HAVE_SETTIMEOFDAY 3 +#endif /* !defined HAVE_SETTIMEOFDAY */ + +#ifndef HAVE_SYMLINK +#define HAVE_SYMLINK 1 +#endif /* !defined HAVE_SYMLINK */ + +#ifndef HAVE_SYS_STAT_H +#define HAVE_SYS_STAT_H 1 +#endif /* !defined HAVE_SYS_STAT_H */ + +#ifndef HAVE_SYS_WAIT_H +#define HAVE_SYS_WAIT_H 1 +#endif /* !defined HAVE_SYS_WAIT_H */ + +#ifndef HAVE_UNISTD_H +#define HAVE_UNISTD_H 1 +#endif /* !defined HAVE_UNISTD_H */ + +#ifndef HAVE_UTMPX_H +#define HAVE_UTMPX_H 0 +#endif /* !defined HAVE_UTMPX_H */ + +#ifndef LOCALE_HOME +#define LOCALE_HOME "/usr/lib/locale" +#endif /* !defined LOCALE_HOME */ + +#if HAVE_INCOMPATIBLE_CTIME_R +#define asctime_r _incompatible_asctime_r +#define ctime_r _incompatible_ctime_r +#endif /* HAVE_INCOMPATIBLE_CTIME_R */ + +/* +** Nested includes +*/ + +#include "sys/types.h" /* for time_t */ +#include "stdio.h" +#include "errno.h" +#include "string.h" +#include "limits.h" /* for CHAR_BIT et al. */ +#include "time.h" +#include "stdlib.h" + +#if HAVE_GETTEXT +#include "libintl.h" +#endif /* HAVE_GETTEXT */ + +#if HAVE_SYS_WAIT_H +#include /* for WIFEXITED and WEXITSTATUS */ +#endif /* HAVE_SYS_WAIT_H */ + +#ifndef WIFEXITED +#define WIFEXITED(status) (((status) & 0xff) == 0) +#endif /* !defined WIFEXITED */ +#ifndef WEXITSTATUS +#define WEXITSTATUS(status) (((status) >> 8) & 0xff) +#endif /* !defined WEXITSTATUS */ + +#if HAVE_UNISTD_H +#include "unistd.h" /* for F_OK, R_OK, and other POSIX goodness */ +#endif /* HAVE_UNISTD_H */ + +#if !(HAVE_UNISTD_H) +#ifndef F_OK +#define F_OK 0 +#endif /* !defined F_OK */ +#ifndef R_OK +#define R_OK 4 +#endif /* !defined R_OK */ +#endif /* !(HAVE_UNISTD_H) */ + +/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ +#define is_digit(c) ((unsigned)(c) - '0' <= 9) + +/* +** Define HAVE_STDINT_H's default value here, rather than at the +** start, since __GLIBC__'s value depends on previously-included +** files. +** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.) +*/ +#ifndef HAVE_STDINT_H +#define HAVE_STDINT_H \ + (199901 <= __STDC_VERSION__ || \ + 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__))) +#endif /* !defined HAVE_STDINT_H */ + +#if HAVE_STDINT_H +#include "stdint.h" +#endif /* !HAVE_STDINT_H */ + +#ifndef INT_FAST64_MAX +/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */ +#if defined LLONG_MAX || defined __LONG_LONG_MAX__ +typedef long long int_fast64_t; +#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#if (LONG_MAX >> 31) < 0xffffffff +Please use a compiler that supports a 64-bit integer type (or wider); +you may need to compile with "-DHAVE_STDINT_H". +#endif /* (LONG_MAX >> 31) < 0xffffffff */ +typedef long int_fast64_t; +#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#endif /* !defined INT_FAST64_MAX */ + +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff +#endif /* !defined INT32_MAX */ +#ifndef INT32_MIN +#define INT32_MIN (-1 - INT32_MAX) +#endif /* !defined INT32_MIN */ + +#if 2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__) +# define ATTRIBUTE_PURE __attribute__ ((__pure__)) +#else +# define ATTRIBUTE_PURE /* empty */ +#endif + +/* +** Workarounds for compilers/systems. +*/ + +/* +** Some time.h implementations don't declare asctime_r. +** Others might define it as a macro. +** Fix the former without affecting the latter. +*/ + +#ifndef asctime_r +extern char * asctime_r(struct tm const *, char *); +#endif + +/* +** Private function declarations. +*/ + +char * icatalloc(char * old, const char * new); +char * icpyalloc(const char * string); +const char * scheck(const char * string, const char * format); + +/* +** Finally, some convenience items. +*/ + +#ifndef TRUE +#define TRUE 1 +#endif /* !defined TRUE */ + +#ifndef FALSE +#define FALSE 0 +#endif /* !defined FALSE */ + +#ifndef TYPE_BIT +#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT) +#endif /* !defined TYPE_BIT */ + +#ifndef TYPE_SIGNED +#define TYPE_SIGNED(type) (((type) -1) < 0) +#endif /* !defined TYPE_SIGNED */ + +/* +** Since the definition of TYPE_INTEGRAL contains floating point numbers, +** it cannot be used in preprocessor directives. +*/ + +#ifndef TYPE_INTEGRAL +#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5) +#endif /* !defined TYPE_INTEGRAL */ + +/* +** Since the definition of TYPE_INTEGRAL contains floating point numbers, +** it cannot be used in preprocessor directives. +*/ + +#ifndef TYPE_INTEGRAL +#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5) +#endif /* !defined TYPE_INTEGRAL */ + +#ifndef INT_STRLEN_MAXIMUM +/* +** 302 / 1000 is log10(2.0) rounded up. +** Subtract one for the sign bit if the type is signed; +** add one for integer division truncation; +** add one more for a minus sign if the type is signed. +*/ +#define INT_STRLEN_MAXIMUM(type) \ + ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \ + 1 + TYPE_SIGNED(type)) +#endif /* !defined INT_STRLEN_MAXIMUM */ + +/* +** INITIALIZE(x) +*/ + +#ifndef GNUC_or_lint +#ifdef lint +#define GNUC_or_lint +#endif /* defined lint */ +#ifndef lint +#ifdef __GNUC__ +#define GNUC_or_lint +#endif /* defined __GNUC__ */ +#endif /* !defined lint */ +#endif /* !defined GNUC_or_lint */ + +#ifndef INITIALIZE +#ifdef GNUC_or_lint +#define INITIALIZE(x) ((x) = 0) +#endif /* defined GNUC_or_lint */ +#ifndef GNUC_or_lint +#define INITIALIZE(x) +#endif /* !defined GNUC_or_lint */ +#endif /* !defined INITIALIZE */ + +/* +** For the benefit of GNU folk... +** `_(MSGID)' uses the current locale's message library string for MSGID. +** The default is to use gettext if available, and use MSGID otherwise. +*/ + +#ifndef _ +#if HAVE_GETTEXT +#define _(msgid) gettext(msgid) +#else /* !HAVE_GETTEXT */ +#define _(msgid) msgid +#endif /* !HAVE_GETTEXT */ +#endif /* !defined _ */ + +#ifndef TZ_DOMAIN +#define TZ_DOMAIN "tz" +#endif /* !defined TZ_DOMAIN */ + +#if HAVE_INCOMPATIBLE_CTIME_R +#undef asctime_r +#undef ctime_r +char *asctime_r(struct tm const *, char *); +char *ctime_r(time_t const *, char *); +#endif /* HAVE_INCOMPATIBLE_CTIME_R */ + +#ifndef YEARSPERREPEAT +#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */ +#endif /* !defined YEARSPERREPEAT */ + +/* +** The Gregorian year averages 365.2425 days, which is 31556952 seconds. +*/ + +#ifndef AVGSECSPERYEAR +#define AVGSECSPERYEAR 31556952L +#endif /* !defined AVGSECSPERYEAR */ + +#ifndef SECSPERREPEAT +#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR) +#endif /* !defined SECSPERREPEAT */ + +#ifndef SECSPERREPEAT_BITS +#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */ +#endif /* !defined SECSPERREPEAT_BITS */ + +/* +** UNIX was a registered trademark of The Open Group in 2003. +*/ + +#endif /* !defined PRIVATE_H */ diff --git a/contrib/tzcode/stdtime/time2posix.3 b/contrib/tzcode/stdtime/time2posix.3 new file mode 100644 index 0000000..2d435ee --- /dev/null +++ b/contrib/tzcode/stdtime/time2posix.3 @@ -0,0 +1,123 @@ +.\" $FreeBSD: releng/11.1/contrib/tzcode/stdtime/time2posix.3 192890 2009-05-27 12:18:39Z edwin $ +.\" +.Dd September 11, 2005 +.Dt TIME2POSIX 3 +.Os +.Sh NAME +.Nm time2posix , +.Nm posix2time +.Nd convert seconds since the Epoch +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In time.h +.Ft time_t +.Fn time2posix "time_t t" +.Ft time_t +.Fn posix2time "time_t t" +.Sh DESCRIPTION +.St -p1003.1-88 +legislates that a time_t value of +536457599 shall correspond to "Wed Dec 31 23:59:59 GMT 1986." +This effectively implies that POSIX time_t's cannot include leap +seconds and, +therefore, +that the system time must be adjusted as each leap occurs. +.Pp +If the time package is configured with leap-second support +enabled, +however, +no such adjustment is needed and +time_t values continue to increase over leap events +(as a true `seconds since...' value). +This means that these values will differ from those required by POSIX +by the net number of leap seconds inserted since the Epoch. +.Pp +Typically this is not a problem as the type time_t is intended +to be +(mostly) +opaque\(emtime_t values should only be obtained-from and +passed-to functions such as +.Xr time 3 , +.Xr localtime 3 , +.Xr mktime 3 +and +.Xr difftime 3 . +However, +.St -p1003.1-88 +gives an arithmetic +expression for directly computing a time_t value from a given date/time, +and the same relationship is assumed by some +(usually older) +applications. +Any programs creating/dissecting time_t's +using such a relationship will typically not handle intervals +over leap seconds correctly. +.Pp +The +.Fn time2posix +and +.Fn posix2time +functions are provided to address this time_t mismatch by converting +between local time_t values and their POSIX equivalents. +This is done by accounting for the number of time-base changes that +would have taken place on a POSIX system as leap seconds were inserted +or deleted. +These converted values can then be used in lieu of correcting the older +applications, +or when communicating with POSIX-compliant systems. +.Pp +The +.Fn time2posix +function is single-valued. +That is, +every local time_t +corresponds to a single POSIX time_t. +The +.Fn posix2time +function is less well-behaved: +for a positive leap second hit the result is not unique, +and for a negative leap second hit the corresponding +POSIX time_t does not exist so an adjacent value is returned. +Both of these are good indicators of the inferiority of the +POSIX representation. +.Pp +The following table summarizes the relationship between time_t +and its conversion to, +and back from, +the POSIX representation over the leap second inserted at the end of June, +1993. +.Bl -column "93/06/30" "23:59:59" "A+0" "X=time2posix(T)" +.It Sy "DATE TIME T X=time2posix(T) posix2time(X)" +.It "93/06/30 23:59:59 A+0 B+0 A+0" +.It "93/06/30 23:59:60 A+1 B+1 A+1 or A+2" +.It "93/07/01 00:00:00 A+2 B+1 A+1 or A+2" +.It "93/07/01 00:00:01 A+3 B+2 A+3" +.El +.Pp +A leap second deletion would look like... +.Bl -column "??/06/30" "23:59:58" "A+0" "X=time2posix(T)" +.It Sy "DATE TIME T X=time2posix(T) posix2time(X)" +.It "??/06/30 23:59:58 A+0 B+0 A+0" +.It "??/07/01 00:00:00 A+1 B+2 A+1" +.It "??/07/01 00:00:01 A+2 B+3 A+2" +.El +.Pp +.D1 No "[Note: posix2time(B+1) => A+0 or A+1]" +.Pp +If leap-second support is not enabled, +local time_t's and +POSIX time_t's are equivalent, +and both +.Fn time2posix +and +.Fn posix2time +degenerate to the identity function. +.Sh "SEE ALSO" +.Xr difftime 3 , +.Xr localtime 3 , +.Xr mktime 3 , +.Xr time 3 +.\" @(#)time2posix.3 8.2 +.\" This file is in the public domain, so clarified as of +.\" 1996-06-05 by Arthur David Olson. diff --git a/contrib/tzcode/stdtime/tzfile.5 b/contrib/tzcode/stdtime/tzfile.5 new file mode 100644 index 0000000..9e00d77 --- /dev/null +++ b/contrib/tzcode/stdtime/tzfile.5 @@ -0,0 +1,152 @@ +.\" $FreeBSD: releng/11.1/contrib/tzcode/stdtime/tzfile.5 259446 2013-12-16 01:58:12Z bjk $ +.Dd September 13, 1994 +.Dt TZFILE 5 +.Os +.Sh NAME +.Nm tzfile +.Nd timezone information +.Sh SYNOPSIS +.Fd #include \&"/usr/src/contrib/tzcode/stdtime/tzfile.h\&" +.Sh DESCRIPTION +The time zone information files used by +.Xr tzset 3 +begin with the magic characters +.Dq Li TZif +to identify them as +time zone information files, +followed by a character identifying the version of the file's format +(as of 2005, either an ASCII NUL or a '2') +followed by fifteen bytes containing zeroes reserved for future use, +followed by four four-byte values +written in a ``standard'' byte order +(the high-order byte of the value is written first). +These values are, +in order: +.Pp +.Bl -tag -compact -width tzh_ttisstdcnt +.It Va tzh_ttisgmtcnt +The number of UTC/local indicators stored in the file. +.It Va tzh_ttisstdcnt +The number of standard/wall indicators stored in the file. +.It Va tzh_leapcnt +The number of leap seconds for which data is stored in the file. +.It Va tzh_timecnt +The number of ``transition times'' for which data is stored +in the file. +.It Va tzh_typecnt +The number of ``local time types'' for which data is stored +in the file (must not be zero). +.It Va tzh_charcnt +The number of characters of ``time zone abbreviation strings'' +stored in the file. +.El +.Pp +The above header is followed by +.Va tzh_timecnt +four-byte values of type +.Fa long , +sorted in ascending order. +These values are written in ``standard'' byte order. +Each is used as a transition time (as returned by +.Xr time 3 ) +at which the rules for computing local time change. +Next come +.Va tzh_timecnt +one-byte values of type +.Fa "unsigned char" ; +each one tells which of the different types of ``local time'' types +described in the file is associated with the same-indexed transition time. +These values serve as indices into an array of +.Fa ttinfo +structures (with +.Fa tzh_typecnt +entries) that appears next in the file; +these structures are defined as follows: +.Pp +.Bd -literal -offset indent +struct ttinfo { + long tt_gmtoff; + int tt_isdst; + unsigned int tt_abbrind; +}; +.Ed +.Pp +Each structure is written as a four-byte value for +.Va tt_gmtoff +of type +.Fa long , +in a standard byte order, followed by a one-byte value for +.Va tt_isdst +and a one-byte value for +.Va tt_abbrind . +In each structure, +.Va tt_gmtoff +gives the number of seconds to be added to UTC, +.Li tt_isdst +tells whether +.Li tm_isdst +should be set by +.Xr localtime 3 +and +.Va tt_abbrind +serves as an index into the array of time zone abbreviation characters +that follow the +.Li ttinfo +structure(s) in the file. +.Pp +Then there are +.Va tzh_leapcnt +pairs of four-byte values, written in standard byte order; +the first value of each pair gives the time +(as returned by +.Xr time 3 ) +at which a leap second occurs; +the second gives the +.Em total +number of leap seconds to be applied after the given time. +The pairs of values are sorted in ascending order by time. +.Pp +Then there are +.Va tzh_ttisstdcnt +standard/wall indicators, each stored as a one-byte value; +they tell whether the transition times associated with local time types +were specified as standard time or wall clock time, +and are used when a time zone file is used in handling POSIX-style +time zone environment variables. +.Pp +Finally there are +.Va tzh_ttisgmtcnt +UTC/local indicators, each stored as a one-byte value; +they tell whether the transition times associated with local time types +were specified as UTC or local time, +and are used when a time zone file is used in handling POSIX-style +time zone environment variables. +.Pp +.Nm localtime +uses the first standard-time +.Li ttinfo +structure in the file +(or simply the first +.Li ttinfo +structure in the absence of a standard-time structure) +if either +.Li tzh_timecnt +is zero or the time argument is less than the first transition time recorded +in the file. +.Pp +For version-2-format time zone files, +the above header and data is followed by a second header and data, +identical in format except that eight bytes are used for each +transition time or leap second time. +After the second header and data comes a newline-enclosed, +POSIX-TZ-environment-variable-style string for use in handling instants +after the last transition time stored in the file +(with nothing between the newlines if there is no POSIX representation for +such instants). +.Sh SEE ALSO +.Xr ctime 3 , +.Xr time2posix 3 , +.Xr zic 8 +.\" @(#)tzfile.5 8.3 +.\" This file is in the public domain, so clarified as of +.\" 1996-06-05 by Arthur David Olson. diff --git a/contrib/tzcode/stdtime/tzfile.h b/contrib/tzcode/stdtime/tzfile.h new file mode 100644 index 0000000..f24d2bd --- /dev/null +++ b/contrib/tzcode/stdtime/tzfile.h @@ -0,0 +1,184 @@ +#ifndef TZFILE_H +#define TZFILE_H + + +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +** +** $FreeBSD: releng/11.1/contrib/tzcode/stdtime/tzfile.h 192625 2009-05-23 06:31:50Z edwin $ +*/ + +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + +/* +** ID +*/ + +#ifndef lint +#ifndef NOID +/* +static char tzfilehid[] = "@(#)tzfile.h 8.1"; +*/ +#endif /* !defined NOID */ +#endif /* !defined lint */ + +/* +** Information about time zone files. +*/ + +#ifndef TZDIR +#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */ +#endif /* !defined TZDIR */ + +#ifndef TZDEFAULT +#define TZDEFAULT "/etc/localtime" +#endif /* !defined TZDEFAULT */ + +#ifndef TZDEFRULES +#define TZDEFRULES "posixrules" +#endif /* !defined TZDEFRULES */ + +/* +** Each file begins with. . . +*/ + +#define TZ_MAGIC "TZif" + +struct tzhead { + char tzh_magic[4]; /* TZ_MAGIC */ + char tzh_version[1]; /* '\0' or '2' as of 2005 */ + char tzh_reserved[15]; /* reserved--must be zero */ + char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ + char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ + char tzh_leapcnt[4]; /* coded number of leap seconds */ + char tzh_timecnt[4]; /* coded number of transition times */ + char tzh_typecnt[4]; /* coded number of local time types */ + char tzh_charcnt[4]; /* coded number of abbr. chars */ +}; + +/* +** . . .followed by. . . +** +** tzh_timecnt (char [4])s coded transition times a la time(2) +** tzh_timecnt (unsigned char)s types of local time starting at above +** tzh_typecnt repetitions of +** one (char [4]) coded UTC offset in seconds +** one (unsigned char) used to set tm_isdst +** one (unsigned char) that's an abbreviation list index +** tzh_charcnt (char)s '\0'-terminated zone abbreviations +** tzh_leapcnt repetitions of +** one (char [4]) coded leap second transition times +** one (char [4]) total correction after above +** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition +** time is standard time, if FALSE, +** transition time is wall clock time +** if absent, transition times are +** assumed to be wall clock time +** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition +** time is UTC, if FALSE, +** transition time is local time +** if absent, transition times are +** assumed to be local time +*/ + +/* +** If tzh_version is '2' or greater, the above is followed by a second instance +** of tzhead and a second instance of the data in which each coded transition +** time uses 8 rather than 4 chars, +** then a POSIX-TZ-environment-variable-style string for use in handling +** instants after the last transition time stored in the file +** (with nothing between the newlines if there is no POSIX representation for +** such instants). +*/ + +/* +** In the current implementation, "tzset()" refuses to deal with files that +** exceed any of the limits below. +*/ + +#ifndef TZ_MAX_TIMES +#define TZ_MAX_TIMES 1200 +#endif /* !defined TZ_MAX_TIMES */ + +#ifndef TZ_MAX_TYPES +#ifndef NOSOLAR +#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ +#endif /* !defined NOSOLAR */ +#ifdef NOSOLAR +/* +** Must be at least 14 for Europe/Riga as of Jan 12 1995, +** as noted by Earl Chew. +*/ +#define TZ_MAX_TYPES 20 /* Maximum number of local time types */ +#endif /* !defined NOSOLAR */ +#endif /* !defined TZ_MAX_TYPES */ + +#ifndef TZ_MAX_CHARS +#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ + /* (limited by what unsigned chars can hold) */ +#endif /* !defined TZ_MAX_CHARS */ + +#ifndef TZ_MAX_LEAPS +#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ +#endif /* !defined TZ_MAX_LEAPS */ + +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define HOURSPERDAY 24 +#define DAYSPERWEEK 7 +#define DAYSPERNYEAR 365 +#define DAYSPERLYEAR 366 +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY) +#define MONSPERYEAR 12 + +#define TM_SUNDAY 0 +#define TM_MONDAY 1 +#define TM_TUESDAY 2 +#define TM_WEDNESDAY 3 +#define TM_THURSDAY 4 +#define TM_FRIDAY 5 +#define TM_SATURDAY 6 + +#define TM_JANUARY 0 +#define TM_FEBRUARY 1 +#define TM_MARCH 2 +#define TM_APRIL 3 +#define TM_MAY 4 +#define TM_JUNE 5 +#define TM_JULY 6 +#define TM_AUGUST 7 +#define TM_SEPTEMBER 8 +#define TM_OCTOBER 9 +#define TM_NOVEMBER 10 +#define TM_DECEMBER 11 + +#define TM_YEAR_BASE 1900 + +#define EPOCH_YEAR 1970 +#define EPOCH_WDAY TM_THURSDAY + +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) + +/* +** Since everything in isleap is modulo 400 (or a factor of 400), we know that +** isleap(y) == isleap(y % 400) +** and so +** isleap(a + b) == isleap((a + b) % 400) +** or +** isleap(a + b) == isleap(a % 400 + b % 400) +** This is true even if % means modulo rather than Fortran remainder +** (which is allowed by C89 but not C99). +** We use this to avoid addition overflow problems. +*/ + +#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) + +#endif /* !defined TZFILE_H */ diff --git a/contrib/tzcode/zic/README b/contrib/tzcode/zic/README new file mode 100644 index 0000000..9259227 --- /dev/null +++ b/contrib/tzcode/zic/README @@ -0,0 +1,88 @@ +@(#)README 8.3 +This file is in the public domain, so clarified as of +2009-05-17 by Arthur David Olson. + +$FreeBSD: releng/11.1/contrib/tzcode/zic/README 192890 2009-05-27 12:18:39Z edwin $ + +"What time is it?" -- Richard Deacon as The King +"Any time you want it to be." -- Frank Baxter as The Scientist + (from the Bell System film "About Time") + +The 1989 update of the time zone package featured + +* POSIXization (including interpretation of POSIX-style TZ environment + variables, provided by Guy Harris), +* ANSIfication (including versions of "mktime" and "difftime"), +* SVIDulation (an "altzone" variable) +* MACHination (the "gtime" function) +* corrections to some time zone data (including corrections to the rules + for Great Britain and New Zealand) +* reference data from the United States Naval Observatory for folks who + want to do additional time zones +* and the 1989 data for Saudi Arabia. + +(Since this code will be treated as "part of the implementation" in some places +and as "part of the application" in others, there's no good way to name +functions, such as timegm, that are not part of the proposed ANSI C standard; +such functions have kept their old, underscore-free names in this update.) + +And the "dysize" function has disappeared; it was present to allow compilation +of the "date" command on old BSD systems, and a version of "date" is now +provided in the package. The "date" command is not created when you "make all" +since it may lack options provided by the version distributed with your +operating system, or may not interact with the system in the same way the +native version does. + +Since POSIX frowns on correct leap second handling, the default behavior of +the "zic" command (in the absence of a "-L" option) has been changed to omit +leap second information from its output files. + +Here is a recipe for acquiring, building, installing, and testing the +tz distribution on a GNU/Linux or similar host. + + mkdir tz + cd tz + wget 'ftp://elsie.nci.nih.gov/pub/tz*.tar.gz' + gzip -dc tzcode*.tar.gz | tar -xf - + gzip -dc tzdata*.tar.gz | tar -xf - + +Be sure to read the comments in "Makefile" and make any changes needed +to make things right for your system, especially if you are using some +platform other than GNU/Linux. Then run the following commands, +substituting your desired installation directory for "$HOME/tzdir": + + make TOPDIR=$HOME/tzdir install + $HOME/tzdir/etc/zdump -v America/Los_Angeles + +To use the new functions, use a "-ltz" option when compiling or linking. + +Historical local time information has been included here to: + +* provide a compendium of data about the history of civil time + that is useful even if the data are not 100% accurate; + +* give an idea of the variety of local time rules that have + existed in the past and thus an idea of the variety that may be + expected in the future; + +* provide a test of the generality of the local time rule description + system. + +The information in the time zone data files is by no means authoritative; +the files currently do not even attempt to cover all time stamps before +1970, and there are undoubtedly errors even for time stamps since 1970. +If you know that the rules are different from those in a file, by all means +feel free to change file (and please send the changed version to +tz@elsie.nci.nih.gov for use in the future). Europeans take note! + +Thanks to these Timezone Caballeros who've made major contributions to the +time conversion package: Keith Bostic; Bob Devine; Paul Eggert; Robert Elz; +Guy Harris; Mark Horton; John Mackin; and Bradley White. Thanks also to +Michael Bloom, Art Neilson, Stephen Prince, John Sovereign, and Frank Wales +for testing work, and to Gwillim Law for checking local mean time data. +None of them are responsible for remaining errors. + +Look in the ~ftp/pub directory of elsie.nci.nih.gov +for updated versions of these files. + +Please send comments or information to tz@elsie.nci.nih.gov. diff --git a/contrib/tzcode/zic/Theory b/contrib/tzcode/zic/Theory new file mode 100644 index 0000000..a7fdbf5 --- /dev/null +++ b/contrib/tzcode/zic/Theory @@ -0,0 +1,570 @@ +@(#)Theory 8.4 +This file is in the public domain, so clarified as of +2009-05-17 by Arthur David Olson. +$FreeBSD: releng/11.1/contrib/tzcode/zic/Theory 200832 2009-12-22 11:17:10Z edwin $ + +----- Outline ----- + + Time and date functions + Names of time zone regions + Time zone abbreviations + Calendrical issues + Time and time zones on Mars + +----- Time and date functions ----- + +These time and date functions are upwards compatible with POSIX, +an international standard for UNIX-like systems. +As of this writing, the current edition of POSIX is: + + Standard for Information technology + -- Portable Operating System Interface (POSIX (R)) + -- System Interfaces + IEEE Std 1003.1, 2004 Edition + + + +POSIX has the following properties and limitations. + +* In POSIX, time display in a process is controlled by the + environment variable TZ. Unfortunately, the POSIX TZ string takes + a form that is hard to describe and is error-prone in practice. + Also, POSIX TZ strings can't deal with other (for example, Israeli) + daylight saving time rules, or situations where more than two + time zone abbreviations are used in an area. + + The POSIX TZ string takes the following form: + + stdoffset[dst[offset],date[/time],date[/time]] + + where: + + std and dst + are 3 or more characters specifying the standard + and daylight saving time (DST) zone names. + Starting with POSIX.1-2001, std and dst may also be + in a quoted form like ""; this allows + "+" and "-" in the names. + offset + is of the form `[-]hh:[mm[:ss]]' and specifies the + offset west of UTC. The default DST offset is one hour + ahead of standard time. + date[/time],date[/time] + specifies the beginning and end of DST. If this is absent, + the system supplies its own rules for DST, and these can + differ from year to year; typically US DST rules are used. + time + takes the form `hh:[mm[:ss]]' and defaults to 02:00. + date + takes one of the following forms: + Jn (1<=n<=365) + origin-1 day number not counting February 29 + n (0<=n<=365) + origin-0 day number counting February 29 if present + Mm.n.d (0[Sunday]<=d<=6[Saturday], 1<=n<=5, 1<=m<=12) + for the dth day of week n of month m of the year, + where week 1 is the first week in which day d appears, + and `5' stands for the last week in which day d appears + (which may be either the 4th or 5th week). + + Here is an example POSIX TZ string, for US Pacific time using rules + appropriate from 1987 through 2006: + + TZ='PST8PDT,M4.1.0/02:00,M10.5.0/02:00' + + This POSIX TZ string is hard to remember, and mishandles time stamps + before 1987 and after 2006. With this package you can use this + instead: + + TZ='America/Los_Angeles' + +* POSIX does not define the exact meaning of TZ values like "EST5EDT". + Typically the current US DST rules are used to interpret such values, + but this means that the US DST rules are compiled into each program + that does time conversion. This means that when US time conversion + rules change (as in the United States in 1987), all programs that + do time conversion must be recompiled to ensure proper results. + +* In POSIX, there's no tamper-proof way for a process to learn the + system's best idea of local wall clock. (This is important for + applications that an administrator wants used only at certain times-- + without regard to whether the user has fiddled the "TZ" environment + variable. While an administrator can "do everything in UTC" to get + around the problem, doing so is inconvenient and precludes handling + daylight saving time shifts--as might be required to limit phone + calls to off-peak hours.) + +* POSIX requires that systems ignore leap seconds. + +These are the extensions that have been made to the POSIX functions: + +* The "TZ" environment variable is used in generating the name of a file + from which time zone information is read (or is interpreted a la + POSIX); "TZ" is no longer constrained to be a three-letter time zone + name followed by a number of hours and an optional three-letter + daylight time zone name. The daylight saving time rules to be used + for a particular time zone are encoded in the time zone file; + the format of the file allows U.S., Australian, and other rules to be + encoded, and allows for situations where more than two time zone + abbreviations are used. + + It was recognized that allowing the "TZ" environment variable to + take on values such as "America/New_York" might cause "old" programs + (that expect "TZ" to have a certain form) to operate incorrectly; + consideration was given to using some other environment variable + (for example, "TIMEZONE") to hold the string used to generate the + time zone information file name. In the end, however, it was decided + to continue using "TZ": it is widely used for time zone purposes; + separately maintaining both "TZ" and "TIMEZONE" seemed a nuisance; + and systems where "new" forms of "TZ" might cause problems can simply + use TZ values such as "EST5EDT" which can be used both by + "new" programs (a la POSIX) and "old" programs (as zone names and + offsets). + +* To handle places where more than two time zone abbreviations are used, + the functions "localtime" and "gmtime" set tzname[tmp->tm_isdst] + (where "tmp" is the value the function returns) to the time zone + abbreviation to be used. This differs from POSIX, where the elements + of tzname are only changed as a result of calls to tzset. + +* Since the "TZ" environment variable can now be used to control time + conversion, the "daylight" and "timezone" variables are no longer + needed. (These variables are defined and set by "tzset"; however, their + values will not be used by "localtime.") + +* The "localtime" function has been set up to deliver correct results + for near-minimum or near-maximum time_t values. (A comment in the + source code tells how to get compatibly wrong results). + +* A function "tzsetwall" has been added to arrange for the system's + best approximation to local wall clock time to be delivered by + subsequent calls to "localtime." Source code for portable + applications that "must" run on local wall clock time should call + "tzsetwall();" if such code is moved to "old" systems that don't + provide tzsetwall, you won't be able to generate an executable program. + (These time zone functions also arrange for local wall clock time to be + used if tzset is called--directly or indirectly--and there's no "TZ" + environment variable; portable applications should not, however, rely + on this behavior since it's not the way SVR2 systems behave.) + +* These functions can account for leap seconds, thanks to Bradley White. + +Points of interest to folks with other systems: + +* This package is already part of many POSIX-compliant hosts, + including BSD, HP, Linux, Network Appliance, SCO, SGI, and Sun. + On such hosts, the primary use of this package + is to update obsolete time zone rule tables. + To do this, you may need to compile the time zone compiler + `zic' supplied with this package instead of using the system `zic', + since the format of zic's input changed slightly in late 1994, + and many vendors still do not support the new input format. + +* The UNIX Version 7 "timezone" function is not present in this package; + it's impossible to reliably map timezone's arguments (a "minutes west + of GMT" value and a "daylight saving time in effect" flag) to a + time zone abbreviation, and we refuse to guess. + Programs that in the past used the timezone function may now examine + tzname[localtime(&clock)->tm_isdst] to learn the correct time + zone abbreviation to use. Alternatively, use + localtime(&clock)->tm_zone if this has been enabled. + +* The 4.2BSD gettimeofday function is not used in this package. + This formerly let users obtain the current UTC offset and DST flag, + but this functionality was removed in later versions of BSD. + +* In SVR2, time conversion fails for near-minimum or near-maximum + time_t values when doing conversions for places that don't use UTC. + This package takes care to do these conversions correctly. + +The functions that are conditionally compiled if STD_INSPIRED is defined +should, at this point, be looked on primarily as food for thought. They are +not in any sense "standard compatible"--some are not, in fact, specified in +*any* standard. They do, however, represent responses of various authors to +standardization proposals. + +Other time conversion proposals, in particular the one developed by folks at +Hewlett Packard, offer a wider selection of functions that provide capabilities +beyond those provided here. The absence of such functions from this package +is not meant to discourage the development, standardization, or use of such +functions. Rather, their absence reflects the decision to make this package +contain valid extensions to POSIX, to ensure its broad acceptability. If +more powerful time conversion functions can be standardized, so much the +better. + + +----- Names of time zone rule files ----- + +The time zone rule file naming conventions attempt to strike a balance +among the following goals: + + * Uniquely identify every national region where clocks have all + agreed since 1970. This is essential for the intended use: static + clocks keeping local civil time. + + * Indicate to humans as to where that region is. This simplifes use. + + * Be robust in the presence of political changes. This reduces the + number of updates and backward-compatibility hacks. For example, + names of countries are ordinarily not used, to avoid + incompatibilities when countries change their name + (e.g. Zaire->Congo) or when locations change countries + (e.g. Hong Kong from UK colony to China). + + * Be portable to a wide variety of implementations. + This promotes use of the technology. + + * Use a consistent naming convention over the entire world. + This simplifies both use and maintenance. + +This naming convention is not intended for use by inexperienced users +to select TZ values by themselves (though they can of course examine +and reuse existing settings). Distributors should provide +documentation and/or a simple selection interface that explains the +names; see the 'tzselect' program supplied with this distribution for +one example. + +Names normally have the form AREA/LOCATION, where AREA is the name +of a continent or ocean, and LOCATION is the name of a specific +location within that region. North and South America share the same +area, `America'. Typical names are `Africa/Cairo', `America/New_York', +and `Pacific/Honolulu'. + +Here are the general rules used for choosing location names, +in decreasing order of importance: + + Use only valid POSIX file name components (i.e., the parts of + names other than `/'). Within a file name component, + use only ASCII letters, `.', `-' and `_'. Do not use + digits, as that might create an ambiguity with POSIX + TZ strings. A file name component must not exceed 14 + characters or start with `-'. E.g., prefer `Brunei' + to `Bandar_Seri_Begawan'. + Include at least one location per time zone rule set per country. + One such location is enough. Use ISO 3166 (see the file + iso3166.tab) to help decide whether something is a country. + However, uninhabited ISO 3166 regions like Bouvet Island + do not need locations, since local time is not defined there. + If all the clocks in a country's region have agreed since 1970, + don't bother to include more than one location + even if subregions' clocks disagreed before 1970. + Otherwise these tables would become annoyingly large. + If a name is ambiguous, use a less ambiguous alternative; + e.g. many cities are named San Jose and Georgetown, so + prefer `Costa_Rica' to `San_Jose' and `Guyana' to `Georgetown'. + Keep locations compact. Use cities or small islands, not countries + or regions, so that any future time zone changes do not split + locations into different time zones. E.g. prefer `Paris' + to `France', since France has had multiple time zones. + Use mainstream English spelling, e.g. prefer `Rome' to `Roma', and + prefer `Athens' to the true name (which uses Greek letters). + The POSIX file name restrictions encourage this rule. + Use the most populous among locations in a country's time zone, + e.g. prefer `Shanghai' to `Beijing'. Among locations with + similar populations, pick the best-known location, + e.g. prefer `Rome' to `Milan'. + Use the singular form, e.g. prefer `Canary' to `Canaries'. + Omit common suffixes like `_Islands' and `_City', unless that + would lead to ambiguity. E.g. prefer `Cayman' to + `Cayman_Islands' and `Guatemala' to `Guatemala_City', + but prefer `Mexico_City' to `Mexico' because the country + of Mexico has several time zones. + Use `_' to represent a space. + Omit `.' from abbreviations in names, e.g. prefer `St_Helena' + to `St._Helena'. + Do not change established names if they only marginally + violate the above rules. For example, don't change + the existing name `Rome' to `Milan' merely because + Milan's population has grown to be somewhat greater + than Rome's. + If a name is changed, put its old spelling in the `backward' file. + +The file `zone.tab' lists the geographical locations used to name +time zone rule files. It is intended to be an exhaustive list +of canonical names for geographic regions. + +Older versions of this package used a different naming scheme, +and these older names are still supported. +See the file `backward' for most of these older names +(e.g. `US/Eastern' instead of `America/New_York'). +The other old-fashioned names still supported are +`WET', `CET', `MET', `EET' (see the file `europe'), +and `Factory' (see the file `factory'). + + +----- Time zone abbreviations ----- + +When this package is installed, it generates time zone abbreviations +like `EST' to be compatible with human tradition and POSIX. +Here are the general rules used for choosing time zone abbreviations, +in decreasing order of importance: + + Use abbreviations that consist of three or more ASCII letters. + Previous editions of this database also used characters like + ' ' and '?', but these characters have a special meaning to + the shell and cause commands like + set `date` + to have unexpected effects. + Previous editions of this rule required upper-case letters, + but the Congressman who introduced Chamorro Standard Time + preferred "ChST", so the rule has been relaxed. + + This rule guarantees that all abbreviations could have + been specified by a POSIX TZ string. POSIX + requires at least three characters for an + abbreviation. POSIX through 2000 says that an abbreviation + cannot start with ':', and cannot contain ',', '-', + '+', NUL, or a digit. POSIX from 2001 on changes this + rule to say that an abbreviation can contain only '-', '+', + and alphanumeric characters from the portable character set + in the current locale. To be portable to both sets of + rules, an abbreviation must therefore use only ASCII + letters. + + Use abbreviations that are in common use among English-speakers, + e.g. `EST' for Eastern Standard Time in North America. + We assume that applications translate them to other languages + as part of the normal localization process; for example, + a French application might translate `EST' to `HNE'. + + For zones whose times are taken from a city's longitude, use the + traditional xMT notation, e.g. `PMT' for Paris Mean Time. + The only name like this in current use is `GMT'. + + If there is no common English abbreviation, abbreviate the English + translation of the usual phrase used by native speakers. + If this is not available or is a phrase mentioning the country + (e.g. ``Cape Verde Time''), then: + + When a country has a single or principal time zone region, + append `T' to the country's ISO code, e.g. `CVT' for + Cape Verde Time. For summer time append `ST'; + for double summer time append `DST'; etc. + When a country has multiple time zones, take the first three + letters of an English place name identifying each zone + and then append `T', `ST', etc. as before; + e.g. `VLAST' for VLAdivostok Summer Time. + + Use UTC (with time zone abbreviation "zzz") for locations while + uninhabited. The "zzz" mnemonic is that these locations are, + in some sense, asleep. + +Application writers should note that these abbreviations are ambiguous +in practice: e.g. `EST' has a different meaning in Australia than +it does in the United States. In new applications, it's often better +to use numeric UTC offsets like `-0500' instead of time zone +abbreviations like `EST'; this avoids the ambiguity. + + +----- Calendrical issues ----- + +Calendrical issues are a bit out of scope for a time zone database, +but they indicate the sort of problems that we would run into if we +extended the time zone database further into the past. An excellent +resource in this area is Nachum Dershowitz and Edward M. Reingold, + +Calendrical Calculations: Third Edition +, Cambridge University Press (2008). Other information and +sources are given below. They sometimes disagree. + + +France + +Gregorian calendar adopted 1582-12-20. +French Revolutionary calendar used 1793-11-24 through 1805-12-31, +and (in Paris only) 1871-05-06 through 1871-05-23. + + +Russia + +From Chris Carrier (1996-12-02): +On 1929-10-01 the Soviet Union instituted an ``Eternal Calendar'' +with 30-day months plus 5 holidays, with a 5-day week. +On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the +Gregorian calendar while retaining the 6-day week; on 1940-06-27 it +reverted to the 7-day week. With the 6-day week the usual days +off were the 6th, 12th, 18th, 24th and 30th of the month. +(Source: Evitiar Zerubavel, _The Seven Day Circle_) + + +Mark Brader reported a similar story in "The Book of Calendars", edited +by Frank Parise (1982, Facts on File, ISBN 0-8719-6467-8), page 377. But: + +From: Petteri Sulonen (via Usenet) +Date: 14 Jan 1999 00:00:00 GMT +... + +If your source is correct, how come documents between 1929 -- 1940 were +still dated using the conventional, Gregorian calendar? + +I can post a scan of a document dated December 1, 1934, signed by +Yenukidze, the secretary, on behalf of Kalinin, the President of the +Executive Committee of the Supreme Soviet, if you like. + + + +Sweden (and Finland) + +From: Mark Brader + +Subject: Re: Gregorian reform -- a part of locale? + +Date: 1996-07-06 + +In 1700, Denmark made the transition from Julian to Gregorian. Sweden +decided to *start* a transition in 1700 as well, but rather than have one of +those unsightly calendar gaps :-), they simply decreed that the next leap +year after 1696 would be in 1744 -- putting the whole country on a calendar +different from both Julian and Gregorian for a period of 40 years. + +However, in 1704 something went wrong and the plan was not carried through; +they did, after all, have a leap year that year. And one in 1708. In 1712 +they gave it up and went back to Julian, putting 30 days in February that +year!... + +Then in 1753, Sweden made the transition to Gregorian in the usual manner, +getting there only 13 years behind the original schedule. + +(A previous posting of this story was challenged, and Swedish readers +produced the following references to support it: "Tiderakning och historia" +by Natanael Beckman (1924) and "Tid, en bok om tiderakning och +kalendervasen" by Lars-Olof Lode'n (no date was given).) + + +Grotefend's data + +From: "Michael Palmer" [with one obvious typo fixed] +Subject: Re: Gregorian Calendar (was Re: Another FHC related question +Newsgroups: soc.genealogy.german +Date: Tue, 9 Feb 1999 02:32:48 -800 +... + +The following is a(n incomplete) listing, arranged chronologically, of +European states, with the date they converted from the Julian to the +Gregorian calendar: + +04/15 Oct 1582 - Italy (with exceptions), Spain, Portugal, Poland (Roman + Catholics and Danzig only) +09/20 Dec 1582 - France, Lorraine + +21 Dec 1582/ + 01 Jan 1583 - Holland, Brabant, Flanders, Hennegau +10/21 Feb 1583 - bishopric of Liege (L"uttich) +13/24 Feb 1583 - bishopric of Augsburg +04/15 Oct 1583 - electorate of Trier +05/16 Oct 1583 - Bavaria, bishoprics of Freising, Eichstedt, Regensburg, + Salzburg, Brixen +13/24 Oct 1583 - Austrian Oberelsass and Breisgau +20/31 Oct 1583 - bishopric of Basel +02/13 Nov 1583 - duchy of J"ulich-Berg +02/13 Nov 1583 - electorate and city of K"oln +04/15 Nov 1583 - bishopric of W"urzburg +11/22 Nov 1583 - electorate of Mainz +16/27 Nov 1583 - bishopric of Strassburg and the margraviate of Baden +17/28 Nov 1583 - bishopric of M"unster and duchy of Cleve +14/25 Dec 1583 - Steiermark + +06/17 Jan 1584 - Austria and Bohemia +11/22 Jan 1584 - Luzern, Uri, Schwyz, Zug, Freiburg, Solothurn +12/23 Jan 1584 - Silesia and the Lausitz +22 Jan/ + 02 Feb 1584 - Hungary (legally on 21 Oct 1587) + Jun 1584 - Unterwalden +01/12 Jul 1584 - duchy of Westfalen + +16/27 Jun 1585 - bishopric of Paderborn + +14/25 Dec 1590 - Transylvania + +22 Aug/ + 02 Sep 1612 - duchy of Prussia + +13/24 Dec 1614 - Pfalz-Neuburg + + 1617 - duchy of Kurland (reverted to the Julian calendar in + 1796) + + 1624 - bishopric of Osnabr"uck + + 1630 - bishopric of Minden + +15/26 Mar 1631 - bishopric of Hildesheim + + 1655 - Kanton Wallis + +05/16 Feb 1682 - city of Strassburg + +18 Feb/ + 01 Mar 1700 - Protestant Germany (including Swedish possessions in + Germany), Denmark, Norway +30 Jun/ + 12 Jul 1700 - Gelderland, Zutphen +10 Nov/ + 12 Dec 1700 - Utrecht, Overijssel + +31 Dec 1700/ + 12 Jan 1701 - Friesland, Groningen, Z"urich, Bern, Basel, Geneva, + Turgau, and Schaffhausen + + 1724 - Glarus, Appenzell, and the city of St. Gallen + +01 Jan 1750 - Pisa and Florence + +02/14 Sep 1752 - Great Britain + +17 Feb/ + 01 Mar 1753 - Sweden + +1760-1812 - Graub"unden + +The Russian empire (including Finland and the Baltic states) did not +convert to the Gregorian calendar until the Soviet revolution of 1917. + +Source: H. Grotefend, _Taschenbuch der Zeitrechnung des deutschen +Mittelalters und der Neuzeit_, herausgegeben von Dr. O. Grotefend +(Hannover: Hahnsche Buchhandlung, 1941), pp. 26-28. + + +----- Time and time zones on Mars ----- + +Some people have adjusted their work schedules to fit Mars time. +Dozens of special Mars watches were built for Jet Propulsion +Laboratory workers who kept Mars time during the Mars Exploration +Rovers mission (2004). These timepieces look like normal Seikos and +Citizens but use Mars seconds rather than terrestrial seconds. + +A Mars solar day is called a "sol" and has a mean period equal to +about 24 hours 39 minutes 35.244 seconds in terrestrial time. It is +divided into a conventional 24-hour clock, so each Mars second equals +about 1.02749125 terrestrial seconds. + +The prime meridian of Mars goes through the center of the crater +Airy-0, named in honor of the British astronomer who built the +Greenwich telescope that defines Earth's prime meridian. Mean solar +time on the Mars prime meridian is called Mars Coordinated Time (MTC). + +Each landed mission on Mars has adopted a different reference for +solar time keeping, so there is no real standard for Mars time zones. +For example, the Mars Exploration Rover project (2004) defined two +time zones "Local Solar Time A" and "Local Solar Time B" for its two +missions, each zone designed so that its time equals local true solar +time at approximately the middle of the nominal mission. Such a "time +zone" is not particularly suited for any application other than the +mission itself. + +Many calendars have been proposed for Mars, but none have achieved +wide acceptance. Astronomers often use Mars Sol Date (MSD) which is a +sequential count of Mars solar days elapsed since about 1873-12-29 +12:00 GMT. + +The tz database does not currently support Mars time, but it is +documented here in the hopes that support will be added eventually. + +Sources: + +Michael Allison and Robert Schmunk, +"Technical Notes on Mars Solar Time as Adopted by the Mars24 Sunclock" + (2004-07-30). + +Jia-Rui Chong, "Workdays Fit for a Martian", Los Angeles Times +(2004-01-14), pp A1, A20-A21. diff --git a/contrib/tzcode/zic/ialloc.c b/contrib/tzcode/zic/ialloc.c new file mode 100644 index 0000000..73ee035 --- /dev/null +++ b/contrib/tzcode/zic/ialloc.c @@ -0,0 +1,91 @@ +/* +** This file is in the public domain, so clarified as of +** 2006-07-17 by Arthur David Olson. +*/ + +#ifndef lint +#ifndef NOID +static const char elsieid[] = "@(#)ialloc.c 8.30"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD: releng/11.1/contrib/tzcode/zic/ialloc.c 192625 2009-05-23 06:31:50Z edwin $"; +#endif /* not lint */ + +/*LINTLIBRARY*/ + +#include "private.h" + +#define nonzero(n) (((n) == 0) ? 1 : (n)) + +char * +imalloc(n) +const int n; +{ + return malloc((size_t) nonzero(n)); +} + +char * +icalloc(nelem, elsize) +int nelem; +int elsize; +{ + if (nelem == 0 || elsize == 0) + nelem = elsize = 1; + return calloc((size_t) nelem, (size_t) elsize); +} + +void * +irealloc(pointer, size) +void * const pointer; +const int size; +{ + if (pointer == NULL) + return imalloc(size); + return realloc((void *) pointer, (size_t) nonzero(size)); +} + +char * +icatalloc(old, new) +char * const old; +const char * const new; +{ + register char * result; + register int oldsize, newsize; + + newsize = (new == NULL) ? 0 : strlen(new); + if (old == NULL) + oldsize = 0; + else if (newsize == 0) + return old; + else oldsize = strlen(old); + if ((result = irealloc(old, oldsize + newsize + 1)) != NULL) + if (new != NULL) + (void) strcpy(result + oldsize, new); + return result; +} + +char * +icpyalloc(string) +const char * const string; +{ + return icatalloc((char *) NULL, string); +} + +void +ifree(p) +char * const p; +{ + if (p != NULL) + (void) free(p); +} + +void +icfree(p) +char * const p; +{ + if (p != NULL) + (void) free(p); +} diff --git a/contrib/tzcode/zic/private.h b/contrib/tzcode/zic/private.h new file mode 100644 index 0000000..7f615b2 --- /dev/null +++ b/contrib/tzcode/zic/private.h @@ -0,0 +1,272 @@ +#ifndef PRIVATE_H + +#define PRIVATE_H + +/* +** This file is in the public domain, so clarified as of +** 1996-06-05 by Arthur David Olson. +*/ + +/* + * FreeBSD modifications: separate libc's privates from zic's. + * This makes it easier when we need to update one but not the other. + * I have removed all of the ifdef spaghetti which is not relevant to + * zic from this file. + * + * $FreeBSD: releng/11.1/contrib/tzcode/zic/private.h 207590 2010-05-03 22:32:26Z emaste $ + */ + +/* +** This header is for use ONLY with the time conversion code. +** There is no guarantee that it will remain unchanged, +** or that it will remain at all. +** Do NOT copy it to any system include directory. +** Thank you! +*/ + +/* +** ID +*/ + +#ifndef lint +#ifndef NOID +static const char privatehid[] = "@(#)private.h 8.6"; +#endif /* !defined NOID */ +#endif /* !defined lint */ + +#define GRANDPARENTED "Local time zone must be set--use tzsetup" + +/* +** Defaults for preprocessor symbols. +** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'. +*/ + +#ifndef HAVE_GETTEXT +#define HAVE_GETTEXT 0 +#endif /* !defined HAVE_GETTEXT */ + +#ifndef HAVE_SYMLINK +#define HAVE_SYMLINK 1 +#endif /* !defined HAVE_SYMLINK */ + +#ifndef HAVE_SYS_STAT_H +#define HAVE_SYS_STAT_H 1 +#endif /* !defined HAVE_SYS_STAT_H */ + +#ifndef HAVE_SYS_WAIT_H +#define HAVE_SYS_WAIT_H 1 +#endif /* !defined HAVE_SYS_WAIT_H */ + +#ifndef HAVE_UNISTD_H +#define HAVE_UNISTD_H 1 +#endif /* !defined HAVE_UNISTD_H */ + +/* +** Nested includes +*/ + +#include "sys/types.h" /* for time_t */ +#include "stdio.h" +#include "errno.h" +#include "string.h" +#include "limits.h" /* for CHAR_BIT et al. */ +#include "time.h" +#include "stdlib.h" + +#if HAVE_GETTEXT +#include "libintl.h" +#endif /* HAVE_GETTEXT */ + +#if HAVE_SYS_WAIT_H +#include /* for WIFEXITED and WEXITSTATUS */ +#endif /* HAVE_SYS_WAIT_H */ + +#if HAVE_UNISTD_H +#include "unistd.h" /* for F_OK and R_OK, and other POSIX goodness */ +#endif /* HAVE_UNISTD_H */ + +#ifndef F_OK +#define F_OK 0 +#endif /* !defined F_OK */ +#ifndef R_OK +#define R_OK 4 +#endif /* !defined R_OK */ + +/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ +#define is_digit(c) ((unsigned)(c) - '0' <= 9) + +/* +** Define HAVE_STDINT_H's default value here, rather than at the +** start, since __GLIBC__'s value depends on previously-included +** files. +** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.) +*/ +#ifndef HAVE_STDINT_H +#define HAVE_STDINT_H \ + (199901 <= __STDC_VERSION__ || \ + 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__))) +#endif /* !defined HAVE_STDINT_H */ + +#if HAVE_STDINT_H +#include "stdint.h" +#endif /* !HAVE_STDINT_H */ + +#ifndef INT_FAST64_MAX +/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */ +#if defined LLONG_MAX || defined __LONG_LONG_MAX__ +typedef long long int_fast64_t; +#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#if (LONG_MAX >> 31) < 0xffffffff +Please use a compiler that supports a 64-bit integer type (or wider); +you may need to compile with "-DHAVE_STDINT_H". +#endif /* (LONG_MAX >> 31) < 0xffffffff */ +typedef long int_fast64_t; +#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#endif /* !defined INT_FAST64_MAX */ + +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff +#endif /* !defined INT32_MAX */ +#ifndef INT32_MIN +#define INT32_MIN (-1 - INT32_MAX) +#endif /* !defined INT32_MIN */ + +/* +** Workarounds for compilers/systems. + */ + +/* +** Some time.h implementations don't declare asctime_r. +** Others might define it as a macro. +** Fix the former without affecting the latter. + */ +#ifndef asctime_r +extern char * asctime_r(struct tm const *, char *); +#endif + + + +/* +** Private function declarations. +*/ +char * icalloc (int nelem, int elsize); +char * icatalloc (char * old, const char * new); +char * icpyalloc (const char * string); +char * imalloc (int n); +void * irealloc (void * pointer, int size); +void icfree (char * pointer); +void ifree (char * pointer); +const char * scheck (const char *string, const char *format); + +/* +** Finally, some convenience items. +*/ + +#ifndef TRUE +#define TRUE 1 +#endif /* !defined TRUE */ + +#ifndef FALSE +#define FALSE 0 +#endif /* !defined FALSE */ + +#ifndef TYPE_BIT +#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT) +#endif /* !defined TYPE_BIT */ + +#ifndef TYPE_SIGNED +#define TYPE_SIGNED(type) (((type) -1) < 0) +#endif /* !defined TYPE_SIGNED */ + +/* +** Since the definition of TYPE_INTEGRAL contains floating point numbers, +** it cannot be used in preprocessor directives. +*/ + +#ifndef TYPE_INTEGRAL +#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5) +#endif /* !defined TYPE_INTEGRAL */ + +#ifndef INT_STRLEN_MAXIMUM +/* +** 302 / 1000 is log10(2.0) rounded up. +** Subtract one for the sign bit if the type is signed; +** add one for integer division truncation; +** add one more for a minus sign if the type is signed. +*/ +#define INT_STRLEN_MAXIMUM(type) \ + ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \ + 1 + TYPE_SIGNED(type)) +#endif /* !defined INT_STRLEN_MAXIMUM */ + +/* +** INITIALIZE(x) +*/ + +#ifndef GNUC_or_lint +#ifdef lint +#define GNUC_or_lint +#endif /* defined lint */ +#ifndef lint +#ifdef __GNUC__ +#define GNUC_or_lint +#endif /* defined __GNUC__ */ +#endif /* !defined lint */ +#endif /* !defined GNUC_or_lint */ + +#ifndef INITIALIZE +#ifdef GNUC_or_lint +#define INITIALIZE(x) ((x) = 0) +#endif /* defined GNUC_or_lint */ +#ifndef GNUC_or_lint +#define INITIALIZE(x) +#endif /* !defined GNUC_or_lint */ +#endif /* !defined INITIALIZE */ + +/* +** For the benefit of GNU folk... +** `_(MSGID)' uses the current locale's message library string for MSGID. +** The default is to use gettext if available, and use MSGID otherwise. +*/ + +#ifndef _ +#if HAVE_GETTEXT +#define _(msgid) gettext(msgid) +#else /* !HAVE_GETTEXT */ +#define _(msgid) msgid +#endif /* !HAVE_GETTEXT */ +#endif /* !defined _ */ + +#ifndef TZ_DOMAIN +#define TZ_DOMAIN "tz" +#endif /* !defined TZ_DOMAIN */ + +/* +** UNIX was a registered trademark of The Open Group in 2003. +*/ + +#ifndef YEARSPERREPEAT +#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */ +#endif /* !defined YEARSPERREPEAT */ + +/* +** The Gregorian year averages 365.2425 days, which is 31556952 seconds. +*/ + +#ifndef AVGSECSPERYEAR +#define AVGSECSPERYEAR 31556952L +#endif /* !defined AVGSECSPERYEAR */ + +#ifndef SECSPERREPEAT +#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR) +#endif /* !defined SECSPERREPEAT */ + +#ifndef SECSPERREPEAT_BITS +#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */ +#endif /* !defined SECSPERREPEAT_BITS */ + + /* + ** UNIX was a registered trademark of The Open Group in 2003. + */ + +#endif /* !defined PRIVATE_H */ diff --git a/contrib/tzcode/zic/scheck.c b/contrib/tzcode/zic/scheck.c new file mode 100644 index 0000000..e09a048 --- /dev/null +++ b/contrib/tzcode/zic/scheck.c @@ -0,0 +1,68 @@ +/* +** This file is in the public domain, so clarified as of +** 2006-07-17 by Arthur David Olson. +*/ + +#ifndef lint +#ifndef NOID +static const char elsieid[] = "@(#)scheck.c 8.19"; +#endif /* !defined lint */ +#endif /* !defined NOID */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD: releng/11.1/contrib/tzcode/zic/scheck.c 192625 2009-05-23 06:31:50Z edwin $"; +#endif /* not lint */ + +/*LINTLIBRARY*/ + +#include "private.h" + +const char * +scheck(string, format) +const char * const string; +const char * const format; +{ + register char * fbuf; + register const char * fp; + register char * tp; + register int c; + register const char * result; + char dummy; + + result = ""; + if (string == NULL || format == NULL) + return result; + fbuf = imalloc((int) (2 * strlen(format) + 4)); + if (fbuf == NULL) + return result; + fp = format; + tp = fbuf; + while ((*tp++ = c = *fp++) != '\0') { + if (c != '%') + continue; + if (*fp == '%') { + *tp++ = *fp++; + continue; + } + *tp++ = '*'; + if (*fp == '*') + ++fp; + while (is_digit(*fp)) + *tp++ = *fp++; + if (*fp == 'l' || *fp == 'h') + *tp++ = *fp++; + else if (*fp == '[') + do *tp++ = *fp++; + while (*fp != '\0' && *fp != ']'); + if ((*tp++ = *fp++) == '\0') + break; + } + *(tp - 1) = '%'; + *tp++ = 'c'; + *tp = '\0'; + if (sscanf(string, fbuf, &dummy) != 1) + result = (char *) format; + ifree(fbuf); + return result; +} diff --git a/contrib/tzcode/zic/zdump.8 b/contrib/tzcode/zic/zdump.8 new file mode 100644 index 0000000..82009ee --- /dev/null +++ b/contrib/tzcode/zic/zdump.8 @@ -0,0 +1,63 @@ +.\" +.\" @(#)zdump.8 8.2 +.\" This file is in the public domain, so clarified as of +.\" 2009-05-17 by Arthur David Olson. +.\" $FreeBSD: releng/11.1/contrib/tzcode/zic/zdump.8 192890 2009-05-27 12:18:39Z edwin $ +.\" +.Dd June 20, 2004 +.Dt ZDUMP 8 +.Os +.Sh NAME +.Nm zdump +.Nd timezone dumper +.Sh SYNOPSIS +.Nm +.Op Fl -version +.Op Fl v +.Op Fl c Ar [loyear,]hiyear +.Op Ar zonename ... +.Sh DESCRIPTION +The +.Nm +utility prints the current time in each +.Ar zonename +named on the command line. +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl -version +Output version information and exit. +.It Fl v +For each +.Ar zonename +on the command line, +print the time at the lowest possible time value, +the time one day after the lowest possible time value, +the times both one second before and exactly at +each detected time discontinuity, +the time at one day less than the highest possible time value, +and the time at the highest possible time value, +Each line ends with +.Em isdst=1 +if the given time is Daylight Saving Time or +.Em isdst=0 +otherwise. +.It Fl c Ar loyear,hiyear +Cut off verbose output near the start of the given year(s). +By default, +the program cuts off verbose output near the starts of the years -500 and 2500. +.El +.Sh LIMITATIONS +The +.Fl v +option may not be used on systems with floating-point time_t values +that are neither float nor double. +.Pp +Time discontinuities are found by sampling the results returned by localtime +at twelve-hour intervals. +This works in all real-world cases; +one can construct artificial time zones for which this fails. +.Sh "SEE ALSO" +.Xr ctime 3 , +.Xr tzfile 5 , +.Xr zic 8 diff --git a/contrib/tzcode/zic/zdump.c b/contrib/tzcode/zic/zdump.c new file mode 100644 index 0000000..d78c0b3 --- /dev/null +++ b/contrib/tzcode/zic/zdump.c @@ -0,0 +1,668 @@ +/* +** This file is in the public domain, so clarified as of +** 2009-05-17 by Arthur David Olson. +*/ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD: releng/11.1/contrib/tzcode/zic/zdump.c 307358 2016-10-15 12:37:57Z bapt $"; +static char elsieid[] = "@(#)zdump.c 8.10"; +#endif /* not lint */ + +/* +** This code has been made independent of the rest of the time +** conversion package to increase confidence in the verification it provides. +** You can use this code to help in verifying other implementations. +*/ + +#include +#include /* for stdout, stderr */ +#include /* for exit, malloc, atoi */ +#include /* for strcpy */ +#include /* for time_t */ +#include /* for struct tm */ +#include +#include /* for FLT_MAX and DBL_MAX */ +#include /* for isalpha et al. */ +#ifndef isascii +#define isascii(x) 1 +#endif /* !defined isascii */ + +#ifndef ZDUMP_LO_YEAR +#define ZDUMP_LO_YEAR (-500) +#endif /* !defined ZDUMP_LO_YEAR */ + +#ifndef ZDUMP_HI_YEAR +#define ZDUMP_HI_YEAR 2500 +#endif /* !defined ZDUMP_HI_YEAR */ + +#ifndef MAX_STRING_LENGTH +#define MAX_STRING_LENGTH 1024 +#endif /* !defined MAX_STRING_LENGTH */ + +#ifndef TRUE +#define TRUE 1 +#endif /* !defined TRUE */ + +#ifndef FALSE +#define FALSE 0 +#endif /* !defined FALSE */ + +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif /* !defined EXIT_SUCCESS */ + +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif /* !defined EXIT_FAILURE */ + +#ifndef SECSPERMIN +#define SECSPERMIN 60 +#endif /* !defined SECSPERMIN */ + +#ifndef MINSPERHOUR +#define MINSPERHOUR 60 +#endif /* !defined MINSPERHOUR */ + +#ifndef SECSPERHOUR +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#endif /* !defined SECSPERHOUR */ + +#ifndef HOURSPERDAY +#define HOURSPERDAY 24 +#endif /* !defined HOURSPERDAY */ + +#ifndef EPOCH_YEAR +#define EPOCH_YEAR 1970 +#endif /* !defined EPOCH_YEAR */ + +#ifndef TM_YEAR_BASE +#define TM_YEAR_BASE 1900 +#endif /* !defined TM_YEAR_BASE */ + +#ifndef DAYSPERNYEAR +#define DAYSPERNYEAR 365 +#endif /* !defined DAYSPERNYEAR */ + +#ifndef isleap +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) +#endif /* !defined isleap */ + +#ifndef isleap_sum +/* +** See tzfile.h for details on isleap_sum. +*/ +#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) +#endif /* !defined isleap_sum */ + +#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY) +#define SECSPERNYEAR (SECSPERDAY * DAYSPERNYEAR) +#define SECSPERLYEAR (SECSPERNYEAR + SECSPERDAY) + +#ifndef HAVE_GETTEXT +#define HAVE_GETTEXT 0 +#endif +#if HAVE_GETTEXT +#include "locale.h" /* for setlocale */ +#include "libintl.h" +#endif /* HAVE_GETTEXT */ + +#ifndef GNUC_or_lint +#ifdef lint +#define GNUC_or_lint +#else /* !defined lint */ +#ifdef __GNUC__ +#define GNUC_or_lint +#endif /* defined __GNUC__ */ +#endif /* !defined lint */ +#endif /* !defined GNUC_or_lint */ + +#ifndef INITIALIZE +#ifdef GNUC_or_lint +#define INITIALIZE(x) ((x) = 0) +#else /* !defined GNUC_or_lint */ +#define INITIALIZE(x) +#endif /* !defined GNUC_or_lint */ +#endif /* !defined INITIALIZE */ + +/* +** For the benefit of GNU folk... +** `_(MSGID)' uses the current locale's message library string for MSGID. +** The default is to use gettext if available, and use MSGID otherwise. +*/ + +#ifndef _ +#if HAVE_GETTEXT +#define _(msgid) gettext(msgid) +#else /* !(HAVE_GETTEXT) */ +#define _(msgid) msgid +#endif /* !(HAVE_GETTEXT) */ +#endif /* !defined _ */ + +#ifndef TZ_DOMAIN +#define TZ_DOMAIN "tz" +#endif /* !defined TZ_DOMAIN */ + +extern char ** environ; +extern char * tzname[2]; + +static time_t absolute_min_time; +static time_t absolute_max_time; +static size_t longest; +static char * progname; +static int warned; + +static void usage(FILE *stream, int status); +static char * abbr(struct tm * tmp); +static void abbrok(const char * abbrp, const char * zone); +static long delta(struct tm * newp, struct tm * oldp); +static void dumptime(const struct tm * tmp); +static time_t hunt(char * name, time_t lot, time_t hit); +static void setabsolutes(void); +static void show(char * zone, time_t t, int v); +static const char * tformat(void); +static time_t yeartot(long y); + +#ifndef TYPECHECK +#define my_localtime localtime +#else /* !defined TYPECHECK */ +static struct tm * +my_localtime(tp) +time_t * tp; +{ + register struct tm * tmp; + + tmp = localtime(tp); + if (tp != NULL && tmp != NULL) { + struct tm tm; + register time_t t; + + tm = *tmp; + t = mktime(&tm); + if (t - *tp >= 1 || *tp - t >= 1) { + (void) fflush(stdout); + (void) fprintf(stderr, "\n%s: ", progname); + (void) fprintf(stderr, tformat(), *tp); + (void) fprintf(stderr, " ->"); + (void) fprintf(stderr, " year=%d", tmp->tm_year); + (void) fprintf(stderr, " mon=%d", tmp->tm_mon); + (void) fprintf(stderr, " mday=%d", tmp->tm_mday); + (void) fprintf(stderr, " hour=%d", tmp->tm_hour); + (void) fprintf(stderr, " min=%d", tmp->tm_min); + (void) fprintf(stderr, " sec=%d", tmp->tm_sec); + (void) fprintf(stderr, " isdst=%d", tmp->tm_isdst); + (void) fprintf(stderr, " -> "); + (void) fprintf(stderr, tformat(), t); + (void) fprintf(stderr, "\n"); + } + } + return tmp; +} +#endif /* !defined TYPECHECK */ + +static void +abbrok(abbrp, zone) +const char * const abbrp; +const char * const zone; +{ + register const char * cp; + register char * wp; + + if (warned) + return; + cp = abbrp; + wp = NULL; + while (isascii((unsigned char) *cp) && + (isalnum((unsigned char)*cp) || *cp == '-' || *cp == '+')) + ++cp; + if (cp - abbrp < 3) + wp = _("has fewer than 3 characters"); + else if (cp - abbrp > 6) + wp = _("has more than 6 characters"); + else if (*cp) + wp = "has characters other than ASCII alphanumerics, '-' or '+'"; + else + return; + (void) fflush(stdout); + (void) fprintf(stderr, + _("%s: warning: zone \"%s\" abbreviation \"%s\" %s\n"), + progname, zone, abbrp, wp); + warned = TRUE; +} + +int +main(argc, argv) +int argc; +char * argv[]; +{ + register int i; + register int c; + register int vflag; + register char * cutarg; + register long cutloyear = ZDUMP_LO_YEAR; + register long cuthiyear = ZDUMP_HI_YEAR; + register time_t cutlotime; + register time_t cuthitime; + register char ** fakeenv; + time_t now; + time_t t; + time_t newt; + struct tm tm; + struct tm newtm; + register struct tm * tmp; + register struct tm * newtmp; + + progname=argv[0]; + INITIALIZE(cutlotime); + INITIALIZE(cuthitime); +#if HAVE_GETTEXT + (void) setlocale(LC_MESSAGES, ""); +#ifdef TZ_DOMAINDIR + (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); +#endif /* TEXTDOMAINDIR */ + (void) textdomain(TZ_DOMAIN); +#endif /* HAVE_GETTEXT */ + for (i = 1; i < argc; ++i) + if (strcmp(argv[i], "--version") == 0) { + errx(EXIT_SUCCESS, "%s", elsieid); + } else if (strcmp(argv[i], "--help") == 0) { + usage(stdout, EXIT_SUCCESS); + } + vflag = 0; + cutarg = NULL; + while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v') + if (c == 'v') + vflag = 1; + else cutarg = optarg; + if ((c != -1) || + (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) { + usage(stderr, EXIT_FAILURE); + } + if (vflag) { + if (cutarg != NULL) { + long lo; + long hi; + char dummy; + + if (sscanf(cutarg, "%ld%c", &hi, &dummy) == 1) { + cuthiyear = hi; + } else if (sscanf(cutarg, "%ld,%ld%c", + &lo, &hi, &dummy) == 2) { + cutloyear = lo; + cuthiyear = hi; + } else { +(void) fprintf(stderr, _("%s: wild -c argument %s\n"), + progname, cutarg); + exit(EXIT_FAILURE); + } + } + setabsolutes(); + cutlotime = yeartot(cutloyear); + cuthitime = yeartot(cuthiyear); + } + (void) time(&now); + longest = 0; + for (i = optind; i < argc; ++i) + if (strlen(argv[i]) > longest) + longest = strlen(argv[i]); + { + register int from; + register int to; + + for (i = 0; environ[i] != NULL; ++i) + continue; + fakeenv = (char **) malloc((size_t) ((i + 2) * + sizeof *fakeenv)); + if (fakeenv == NULL || + (fakeenv[0] = (char *) malloc((size_t) (longest + + 4))) == NULL) + errx(EXIT_FAILURE, + _("malloc() failed")); + to = 0; + (void) strcpy(fakeenv[to++], "TZ="); + for (from = 0; environ[from] != NULL; ++from) + if (strncmp(environ[from], "TZ=", 3) != 0) + fakeenv[to++] = environ[from]; + fakeenv[to] = NULL; + environ = fakeenv; + } + for (i = optind; i < argc; ++i) { + static char buf[MAX_STRING_LENGTH]; + + (void) strcpy(&fakeenv[0][3], argv[i]); + if (!vflag) { + show(argv[i], now, FALSE); + continue; + } + warned = FALSE; + t = absolute_min_time; + show(argv[i], t, TRUE); + t += SECSPERHOUR * HOURSPERDAY; + show(argv[i], t, TRUE); + if (t < cutlotime) + t = cutlotime; + tmp = my_localtime(&t); + if (tmp != NULL) { + tm = *tmp; + (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1); + } + for ( ; ; ) { + if (t >= cuthitime || t >= cuthitime - SECSPERHOUR * 12) + break; + newt = t + SECSPERHOUR * 12; + newtmp = localtime(&newt); + if (newtmp != NULL) + newtm = *newtmp; + if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) : + (delta(&newtm, &tm) != (newt - t) || + newtm.tm_isdst != tm.tm_isdst || + strcmp(abbr(&newtm), buf) != 0)) { + newt = hunt(argv[i], t, newt); + newtmp = localtime(&newt); + if (newtmp != NULL) { + newtm = *newtmp; + (void) strncpy(buf, + abbr(&newtm), + (sizeof buf) - 1); + } + } + t = newt; + tm = newtm; + tmp = newtmp; + } + t = absolute_max_time; + t -= SECSPERHOUR * HOURSPERDAY; + show(argv[i], t, TRUE); + t += SECSPERHOUR * HOURSPERDAY; + show(argv[i], t, TRUE); + } + if (fflush(stdout) || ferror(stdout)) + errx(EXIT_FAILURE, _("error writing standard output")); + exit(EXIT_SUCCESS); + /* If exit fails to exit... */ + return(EXIT_FAILURE); +} + +static void +setabsolutes(void) +{ + if (0.5 == (time_t) 0.5) { + /* + ** time_t is floating. + */ + if (sizeof (time_t) == sizeof (float)) { + absolute_min_time = (time_t) -FLT_MAX; + absolute_max_time = (time_t) FLT_MAX; + } else if (sizeof (time_t) == sizeof (double)) { + absolute_min_time = (time_t) -DBL_MAX; + absolute_max_time = (time_t) DBL_MAX; + } else { + (void) fprintf(stderr, +_("%s: use of -v on system with floating time_t other than float or double\n"), + progname); + exit(EXIT_FAILURE); + } + } else if (0 > (time_t) -1) { + /* + ** time_t is signed. Assume overflow wraps around. + */ + time_t t = 0; + time_t t1 = 1; + + while (t < t1) { + t = t1; + t1 = 2 * t1 + 1; + } + + absolute_max_time = t; + t = -t; + absolute_min_time = t - 1; + if (t < absolute_min_time) + absolute_min_time = t; + } else { + /* + ** time_t is unsigned. + */ + absolute_min_time = 0; + absolute_max_time = absolute_min_time - 1; + } +} + +static time_t +yeartot(y) +const long y; +{ + register long myy; + register long seconds; + register time_t t; + + myy = EPOCH_YEAR; + t = 0; + while (myy != y) { + if (myy < y) { + seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR; + ++myy; + if (t > absolute_max_time - seconds) { + t = absolute_max_time; + break; + } + t += seconds; + } else { + --myy; + seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR; + if (t < absolute_min_time + seconds) { + t = absolute_min_time; + break; + } + t -= seconds; + } + } + return t; +} + +static void +usage(FILE *stream, int status) +{ + fprintf(stream, +_("usage: %s [--version] [-v] [--help] [-c [loyear,]hiyear] zonename ...\n\ +\n\ +Report bugs to tz@elsie.nci.nih.gov.\n"), progname); + exit(status); +} + +static time_t +hunt(char *name, time_t lot, time_t hit) +{ + time_t t; + long diff; + struct tm lotm; + register struct tm * lotmp; + struct tm tm; + register struct tm * tmp; + char loab[MAX_STRING_LENGTH]; + + lotmp = my_localtime(&lot); + if (lotmp != NULL) { + lotm = *lotmp; + (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1); + } + for ( ; ; ) { + diff = (long) (hit - lot); + if (diff < 2) + break; + t = lot; + t += diff / 2; + if (t <= lot) + ++t; + else if (t >= hit) + --t; + tmp = my_localtime(&t); + if (tmp != NULL) + tm = *tmp; + if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) : + (delta(&tm, &lotm) == (t - lot) && + tm.tm_isdst == lotm.tm_isdst && + strcmp(abbr(&tm), loab) == 0)) { + lot = t; + lotm = tm; + lotmp = tmp; + } else hit = t; + } + show(name, lot, TRUE); + show(name, hit, TRUE); + return hit; +} + +/* +** Thanks to Paul Eggert for logic used in delta. +*/ + +static long +delta(newp, oldp) +struct tm * newp; +struct tm * oldp; +{ + register long result; + register int tmy; + + if (newp->tm_year < oldp->tm_year) + return -delta(oldp, newp); + result = 0; + for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy) + result += DAYSPERNYEAR + isleap_sum(tmy, TM_YEAR_BASE); + result += newp->tm_yday - oldp->tm_yday; + result *= HOURSPERDAY; + result += newp->tm_hour - oldp->tm_hour; + result *= MINSPERHOUR; + result += newp->tm_min - oldp->tm_min; + result *= SECSPERMIN; + result += newp->tm_sec - oldp->tm_sec; + return result; +} + +static void +show(char *zone, time_t t, int v) +{ + register struct tm * tmp; + + (void) printf("%-*s ", (int) longest, zone); + if (v) { + tmp = gmtime(&t); + if (tmp == NULL) { + (void) printf(tformat(), t); + } else { + dumptime(tmp); + (void) printf(" UTC"); + } + (void) printf(" = "); + } + tmp = my_localtime(&t); + dumptime(tmp); + if (tmp != NULL) { + if (*abbr(tmp) != '\0') + (void) printf(" %s", abbr(tmp)); + if (v) { + (void) printf(" isdst=%d", tmp->tm_isdst); +#ifdef TM_GMTOFF + (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF); +#endif /* defined TM_GMTOFF */ + } + } + (void) printf("\n"); + if (tmp != NULL && *abbr(tmp) != '\0') + abbrok(abbr(tmp), zone); +} + +static char * +abbr(tmp) +struct tm * tmp; +{ + register char * result; + static char nada; + + if (tmp->tm_isdst != 0 && tmp->tm_isdst != 1) + return &nada; + result = tzname[tmp->tm_isdst]; + return (result == NULL) ? &nada : result; +} + +/* +** The code below can fail on certain theoretical systems; +** it works on all known real-world systems as of 2004-12-30. +*/ + +static const char * +tformat(void) +{ + if (0.5 == (time_t) 0.5) { /* floating */ + if (sizeof (time_t) > sizeof (double)) + return "%Lg"; + return "%g"; + } + if (0 > (time_t) -1) { /* signed */ + if (sizeof (time_t) > sizeof (long)) + return "%lld"; + if (sizeof (time_t) > sizeof (int)) + return "%ld"; + return "%d"; + } + if (sizeof (time_t) > sizeof (unsigned long)) + return "%llu"; + if (sizeof (time_t) > sizeof (unsigned int)) + return "%lu"; + return "%u"; +} + +static void +dumptime(timeptr) +register const struct tm * timeptr; +{ + static const char wday_name[][3] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + static const char mon_name[][3] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + register const char * wn; + register const char * mn; + register int lead; + register int trail; + + if (timeptr == NULL) { + (void) printf("NULL"); + return; + } + /* + ** The packaged versions of localtime and gmtime never put out-of-range + ** values in tm_wday or tm_mon, but since this code might be compiled + ** with other (perhaps experimental) versions, paranoia is in order. + */ + if (timeptr->tm_wday < 0 || timeptr->tm_wday >= + (int) (sizeof wday_name / sizeof wday_name[0])) + wn = "???"; + else wn = wday_name[timeptr->tm_wday]; + if (timeptr->tm_mon < 0 || timeptr->tm_mon >= + (int) (sizeof mon_name / sizeof mon_name[0])) + mn = "???"; + else mn = mon_name[timeptr->tm_mon]; + (void) printf("%.3s %.3s%3d %.2d:%.2d:%.2d ", + wn, mn, + timeptr->tm_mday, timeptr->tm_hour, + timeptr->tm_min, timeptr->tm_sec); +#define DIVISOR 10 + trail = timeptr->tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR; + lead = timeptr->tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR + + trail / DIVISOR; + trail %= DIVISOR; + if (trail < 0 && lead > 0) { + trail += DIVISOR; + --lead; + } else if (lead < 0 && trail > 0) { + trail -= DIVISOR; + ++lead; + } + if (lead == 0) + (void) printf("%d", trail); + else (void) printf("%d%d", lead, ((trail < 0) ? -trail : trail)); +} diff --git a/contrib/tzcode/zic/zdump/Makefile b/contrib/tzcode/zic/zdump/Makefile new file mode 100644 index 0000000..4470b3b --- /dev/null +++ b/contrib/tzcode/zic/zdump/Makefile @@ -0,0 +1,15 @@ +# $FreeBSD: releng/11.1/contrib/tzcode/zic/zdump/Makefile 201390 2010-01-02 11:07:44Z ed $ + +.PATH: ${.CURDIR}/.. + +PROG= zdump +MAN= zdump.8 +SRCS= zdump.c ialloc.c scheck.c + +CFLAGS+= -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DSTD_INSPIRED -DPCTS +CFLAGS+= -DHAVE_LONG_DOUBLE -DTZDIR=\"/usr/share/zoneinfo\" -Demkdir=mkdir +CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../lib/libc/stdtime + +WARNS?= 2 + +.include diff --git a/contrib/tzcode/zic/zic.8 b/contrib/tzcode/zic/zic.8 new file mode 100644 index 0000000..c71eb62 --- /dev/null +++ b/contrib/tzcode/zic/zic.8 @@ -0,0 +1,468 @@ +.\" $FreeBSD: releng/11.1/contrib/tzcode/zic/zic.8 214411 2010-10-27 07:14:46Z edwin $ +.Dd June 20, 2004 +.Dt ZIC 8 +.Os +.Sh NAME +.Nm zic +.Nd timezone compiler +.Sh SYNOPSIS +.Nm +.Op Fl -version +.Op Fl Dsv +.Op Fl d Ar directory +.Op Fl g Ar group +.Op Fl L Ar leapsecondfilename +.Op Fl l Ar localtime +.Op Fl m Ar mode +.Op Fl p Ar posixrules +.Op Fl u Ar user +.Op Fl y Ar command +.Op Ar filename ... +.Sh DESCRIPTION +The +.Nm +utility reads text from the file(s) named on the command line +and creates the time conversion information files specified in this input. +If a +.Ar filename +is +.Em - , +the standard input is read. +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl -version +Output version information and exit. +.It Fl D +Do not automatically create directories. +If the input file(s) specify +an output file in a directory which does not already exist, the +default behavior is to attempt to create the directory. +If +.Fl D +is specified, +.Nm +will instead error out immediately. +.It Fl d Ar directory +Create time conversion information files in the named directory rather than +in the standard directory named below. +.It Fl g Ar group +After creating each output file, change its group ownership to the +specified +.Ar group +(which can be either a name or a numeric group ID). +.It Fl L Ar leapsecondfilename +Read leap second information from the file with the given name. +If this option is not used, +no leap second information appears in output files. +.It Fl l Ar timezone +Use the given +.Ar time zone +as local time. +The +.Nm +utility will act as if the input contained a link line of the form +.Pp +.D1 No "Link timezone localtime" +.Pp +(Note that this action has no effect on +.Fx , +since the local time zone is specified in +.Pa /etc/localtime +and not +.Pa /usr/share/zoneinfo/localtime . ) +.It Fl m Ar mode +After creating each output file, change its access mode to +.Ar mode . +Both numeric and alphabetic modes are accepted +(see +.Xr chmod 1 ) . +.It Fl p Ar timezone +Use the given +.Ar "time zone" Ns 's +rules when handling POSIX-format +time zone environment variables. +The +.Nm +utility will act as if the input contained a link line of the form +.Pp +.D1 No "Link timezone posixrules" +.It Fl u Ar user +After creating each output file, change its owner to +.Ar user +(which can be either a name or a numeric user ID). +.It Fl v +Complain if a year that appears in a data file is outside the range +of years representable by +.Xr time 3 +values. +.It Fl s +Limit time values stored in output files to values that are the same +whether they are taken to be signed or unsigned. +You can use this option to generate SVVS-compatible files. +.It Fl y Ar command +Use the given +.Ar command +rather than +.Em yearistype +when checking year types (see below). +.El +.Pp +Input lines are made up of fields. +Fields are separated from one another by any number of white space characters. +Leading and trailing white space on input lines is ignored. +An unquoted sharp character (#) in the input introduces a comment which extends +to the end of the line the sharp character appears on. +White space characters and sharp characters may be enclosed in double quotes +(") if they are to be used as part of a field. +Any line that is blank (after comment stripping) is ignored. +Non-blank lines are expected to be of one of three types: +rule lines, zone lines, and link lines. +.Pp +Names (such as month names) must be in English and are case insensitive. +Abbreviations, if used, must be unambiguous in context. +.Pp +A rule line has the form: +.Dl "Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S" +For example: +.Dl "Rule US 1967 1973 \- Apr lastSun 2:00 1:00 D" +.Pp +The fields that make up a rule line are: +.Bl -tag -width "LETTER/S" -offset indent +.It NAME +Give the (arbitrary) name of the set of rules this rule is part of. +.It FROM +Give the first year in which the rule applies. +Any integer year can be supplied; the Gregorian calendar is assumed. +The word +.Em minimum +(or an abbreviation) means the minimum year representable as an integer. +The word +.Em maximum +(or an abbreviation) means the maximum year representable as an integer. +Rules can describe times that are not representable as time values, +with the unrepresentable times ignored; this allows rules to be portable +among hosts with differing time value types. +.It TO +Give the final year in which the rule applies. +In addition to +.Em minimum +and +.Em maximum +(as above), +the word +.Em only +(or an abbreviation) +may be used to repeat the value of the +.Em FROM +field. +.It TYPE +Give the type of year in which the rule applies. +If +.Em TYPE +is +.Em \- +then the rule applies in all years between +.Em FROM +and +.Em TO +inclusive. +If +.Em TYPE +is something else, then +.Nm +executes the command +.Li yearistype Ar year Ar type +to check the type of a year: +an exit status of zero is taken to mean that the year is of the given type; +an exit status of one is taken to mean that the year is not of the given type. +.It IN +Name the month in which the rule takes effect. +Month names may be abbreviated. +.It ON +Give the day on which the rule takes effect. +Recognized forms include: +.Pp +.Bl -tag -width lastSun -compact -offset indent +.It \&5 +the fifth of the month +.It lastSun +the last Sunday in the month +.It lastMon +the last Monday in the month +.It Sun>=8 +first Sunday on or after the eighth +.It Sun<=25 +last Sunday on or before the 25th +.El +.Pp +Names of days of the week may be abbreviated or spelled out in full. +Note that there must be no spaces within the +.Em ON +field. +.It AT +Give the time of day at which the rule takes effect. +Recognized forms include: +.Pp +.Bl -tag -width "\&1:28:14" -offset indent -compact +.It 2 +time in hours +.It 2:00 +time in hours and minutes +.It 15:00 +24-hour format time (for times after noon) +.It 1:28:14 +time in hours, minutes, and seconds +.El +.Pp +where hour 0 is midnight at the start of the day, +and hour 24 is midnight at the end of the day. +Any of these forms may be followed by the letter +.Sq Li w +if the given time is local +.Dq "wall clock" +time, +.Sq Li s +if the given time is local +.Dq standard +time, or +.Sq Li u +(or +.Sq Li g +or +.Sq Li z ) +if the given time is universal time; +in the absence of an indicator, +wall clock time is assumed. +.It SAVE +Give the amount of time to be added to local standard time when the rule is in +effect. +This field has the same format as the +.Em AT +field +(although, of course, the +.Sq Li w +and +.Sq Li s +suffixes are not used). +.It LETTER/S +Give the +.Dq "variable part" +(for example, the +.Dq S +or +.Dq D +in +.Dq EST +or +.Dq EDT ) +of time zone abbreviations to be used when this rule is in effect. +If this field is +.Em \- , +the variable part is null. +.El +.Pp +A zone line has the form: +.Dl "Zone NAME GMTOFF RULES/SAVE FORMAT [UNTILYEAR [MONTH [DAY [TIME]]]]" +For example: +.Dl "Zone Australia/Adelaide 9:30 Aus CST 1971 Oct 31 2:00" +The fields that make up a zone line are: +.Bl -tag -width indent +.It NAME +The name of the time zone. +This is the name used in creating the time conversion information file for the +zone. +.It GMTOFF +The amount of time to add to UTC to get standard time in this zone. +This field has the same format as the +.Em AT +and +.Em SAVE +fields of rule lines; +begin the field with a minus sign if time must be subtracted from UTC. +.It RULES/SAVE +The name of the rule(s) that apply in the time zone or, +alternately, an amount of time to add to local standard time. +If this field is +.Em \- +then standard time always applies in the time zone. +.It FORMAT +The format for time zone abbreviations in this time zone. +The pair of characters +.Em %s +is used to show where the +.Dq "variable part" +of the time zone abbreviation goes. +Alternately, +a slash (/) +separates standard and daylight abbreviations. +.It UNTILYEAR [MONTH [DAY [TIME]]] +The time at which the UTC offset or the rule(s) change for a location. +It is specified as a year, a month, a day, and a time of day. +If this is specified, +the time zone information is generated from the given UTC offset +and rule change until the time specified. +The month, day, and time of day have the same format as the IN, ON, and AT +fields of a rule; trailing fields can be omitted, and default to the +earliest possible value for the missing fields. +.Pp +The next line must be a +.Dq continuation +line; this has the same form as a zone line except that the +string +.Dq Zone +and the name are omitted, as the continuation line will +place information starting at the time specified as the +.Em until +information in the previous line in the file used by the previous line. +Continuation lines may contain +.Em until +information, just as zone lines do, indicating that the next line is a further +continuation. +.El +.Pp +A link line has the form +.Dl "Link LINK-FROM LINK-TO" +For example: +.Dl "Link Europe/Istanbul Asia/Istanbul" +The +.Em LINK-FROM +field should appear as the +.Em NAME +field in some zone line; +the +.Em LINK-TO +field is used as an alternate name for that zone. +.Pp +Except for continuation lines, +lines may appear in any order in the input. +.Pp +Lines in the file that describes leap seconds have the following form: +.Dl "Leap YEAR MONTH DAY HH:MM:SS CORR R/S" +For example: +.Dl "Leap 1974 Dec 31 23:59:60 + S" +The +.Em YEAR , +.Em MONTH , +.Em DAY , +and +.Em HH:MM:SS +fields tell when the leap second happened. +The +.Em CORR +field +should be +.Dq + +if a second was added +or +.Dq - +if a second was skipped. +.\" There's no need to document the following, since it's impossible for more +.\" than one leap second to be inserted or deleted at a time. +.\" The C Standard is in error in suggesting the possibility. +.\" See Terry J Quinn, The BIPM and the accurate measure of time, +.\" Proc IEEE 79, 7 (July 1991), 894-905. +.\" or +.\" .q ++ +.\" if two seconds were added +.\" or +.\" .q -- +.\" if two seconds were skipped. +The +.Em R/S +field +should be (an abbreviation of) +.Dq Stationary +if the leap second time given by the other fields should be interpreted as UTC +or +(an abbreviation of) +.Dq Rolling +if the leap second time given by the other fields should be interpreted as +local wall clock time. +.Sh "EXTENDED EXAMPLE" +Here is an extended example of +.Nm +input, intended to illustrate many of its features. +.br +.ne 22 +.nf +.in +2m +.ta \w'# Rule\0\0'u +\w'NAME\0\0'u +\w'FROM\0\0'u +\w'1973\0\0'u +\w'TYPE\0\0'u +\w'Apr\0\0'u +\w'lastSun\0\0'u +\w'2:00\0\0'u +\w'SAVE\0\0'u +.sp +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Swiss 1940 only - Nov 2 0:00 1:00 S +Rule Swiss 1940 only - Dec 31 0:00 0 - +Rule Swiss 1941 1942 - May Sun>=1 2:00 1:00 S +Rule Swiss 1941 1942 - Oct Sun>=1 0:00 0 +.sp .5 +Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S +Rule EU 1977 only - Sep lastSun 1:00u 0 - +Rule EU 1978 only - Oct 1 1:00u 0 - +Rule EU 1979 1995 - Sep lastSun 1:00u 0 - +Rule EU 1981 max - Mar lastSun 1:00u 1:00 S +Rule EU 1996 max - Oct lastSun 1:00u 0 - +.sp +.ta \w'# Zone\0\0'u +\w'Europe/Zurich\0\0'u +\w'0:34:08\0\0'u +\w'RULES/SAVE\0\0'u +\w'FORMAT\0\0'u +# Zone NAME GMTOFF RULES FORMAT UNTIL +Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12 + 0:29:44 - BMT 1894 Jun + 1:00 Swiss CE%sT 1981 + 1:00 EU CE%sT +.sp +Link Europe/Zurich Switzerland +.sp +.in +.fi +In this example, the zone is named Europe/Zurich but it has an alias +as Switzerland. +Zurich was 34 minutes and 8 seconds west of GMT until 1848-09-12 +at 00:00, when the offset changed to 29 minutes and 44 seconds. +After 1894-06-01 at 00:00 Swiss daylight saving rules (defined with +lines beginning with "Rule Swiss") apply, and the GMT offset became +one hour. +From 1981 to the present, EU daylight saving rules have applied, +and the UTC offset has remained at one hour. +.Pp +In 1940, daylight saving time applied from November 2 at 00:00 to +December 31 at 00:00. +In 1941 and 1942, daylight saving time applied from the first Sunday +in May at 02:00 to the first Sunday in October at 00:00. +The pre-1981 EU daylight-saving rules have no effect here, but are +included for completeness. +Since 1981, daylight saving has begun on the last Sunday in March +at 01:00 UTC. +Until 1995 it ended the last Sunday in September at 01:00 UTC, but +this changed to the last Sunday in October starting in 1996. +.Pp +For purposes of display, "LMT" and "BMT" were initially used, +respectively. +Since Swiss rules and later EU rules were applied, the display name +for the timezone has been CET for standard time and CEST for daylight +saving time. +.Sh NOTES +For areas with more than two types of local time, +you may need to use local standard time in the +.Em AT +field of the earliest transition time's rule to ensure that +the earliest transition time recorded in the compiled file is correct. +.Pp +If, for a particular zone, a clock advance caused by the start of +daylight saving coincides with and is equal to a clock retreat +caused by a change in UTC offset, +.Nm +produces a single transition to daylight saving at the new UTC offset +(without any change in wall clock time). +To get separate transitions use multiple zone continuation lines +specifying transition instants using universal time. +.Sh FILES +.Bl -tag -width /usr/share/zoneinfo -compact +.It /usr/share/zoneinfo +standard directory used for created files +.El +.Sh "SEE ALSO" +.Xr ctime 3 , +.Xr tzfile 5 , +.Xr zdump 8 +.\" @(#)zic.8 8.6 +.\" This file is in the public domain, so clarified as of +.\" 2009-05-17 by Arthur David Olson. diff --git a/contrib/tzcode/zic/zic.c b/contrib/tzcode/zic/zic.c new file mode 100644 index 0000000..a7a22e4 --- /dev/null +++ b/contrib/tzcode/zic/zic.c @@ -0,0 +1,2756 @@ +/* +** This file is in the public domain, so clarified as of +** 2006-07-17 by Arthur David Olson. +*/ + +static const char elsieid[] = "@(#)zic.c 8.22"; + +#ifndef lint +static const char rcsid[] = + "$FreeBSD: releng/11.1/contrib/tzcode/zic/zic.c 307358 2016-10-15 12:37:57Z bapt $"; +#endif /* not lint */ + +#include "private.h" +#include "tzfile.h" +#include +#include +#include /* for umask manifest constants */ +#include +#include + +#define ZIC_VERSION '2' + +typedef int_fast64_t zic_t; + +#ifndef ZIC_MAX_ABBR_LEN_WO_WARN +#define ZIC_MAX_ABBR_LEN_WO_WARN 6 +#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */ + +#define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) + +/* +** On some ancient hosts, predicates like `isspace(C)' are defined +** only if isascii(C) || C == EOF. Modern hosts obey the C Standard, +** which says they are defined only if C == ((unsigned char) C) || C == EOF. +** Neither the C Standard nor POSIX require that `isascii' exist. +** For portability, we check both ancient and modern requirements. +** If isascii is not defined, the isascii check succeeds trivially. +*/ +#include "ctype.h" +#ifndef isascii +#define isascii(x) 1 +#endif + +#define OFFSET_STRLEN_MAXIMUM (7 + INT_STRLEN_MAXIMUM(long)) +#define RULE_STRLEN_MAXIMUM 8 /* "Mdd.dd.d" */ + +#define end(cp) (strchr((cp), '\0')) + +struct rule { + const char * r_filename; + int r_linenum; + const char * r_name; + + int r_loyear; /* for example, 1986 */ + int r_hiyear; /* for example, 1986 */ + const char * r_yrtype; + int r_lowasnum; + int r_hiwasnum; + + int r_month; /* 0..11 */ + + int r_dycode; /* see below */ + int r_dayofmonth; + int r_wday; + + long r_tod; /* time from midnight */ + int r_todisstd; /* above is standard time if TRUE */ + /* or wall clock time if FALSE */ + int r_todisgmt; /* above is GMT if TRUE */ + /* or local time if FALSE */ + long r_stdoff; /* offset from standard time */ + const char * r_abbrvar; /* variable part of abbreviation */ + + int r_todo; /* a rule to do (used in outzone) */ + zic_t r_temp; /* used in outzone */ +}; + +/* +** r_dycode r_dayofmonth r_wday +*/ + +#define DC_DOM 0 /* 1..31 */ /* unused */ +#define DC_DOWGEQ 1 /* 1..31 */ /* 0..6 (Sun..Sat) */ +#define DC_DOWLEQ 2 /* 1..31 */ /* 0..6 (Sun..Sat) */ + +struct zone { + const char * z_filename; + int z_linenum; + + const char * z_name; + long z_gmtoff; + const char * z_rule; + const char * z_format; + + long z_stdoff; + + struct rule * z_rules; + int z_nrules; + + struct rule z_untilrule; + zic_t z_untiltime; +}; + +static void addtt(zic_t starttime, int type); +static int addtype(long gmtoff, const char * abbr, int isdst, + int ttisstd, int ttisgmt); +static void leapadd(zic_t t, int positive, int rolling, int count); +static void adjleap(void); +static void associate(void); +static int ciequal(const char * ap, const char * bp); +static void convert(long val, char * buf); +static void convert64(zic_t val, char * buf); +static void dolink(const char * fromfield, const char * tofield); +static void doabbr(char * abbr, const char * format, + const char * letters, int isdst, int doquotes); +static void eat(const char * name, int num); +static void eats(const char * name, int num, + const char * rname, int rnum); +static long eitol(int i); +static void error(const char * message); +static char ** getfields(char * buf); +static long gethms(const char * string, const char * errstrng, + int signable); +static void infile(const char * filename); +static void inleap(char ** fields, int nfields); +static void inlink(char ** fields, int nfields); +static void inrule(char ** fields, int nfields); +static int inzcont(char ** fields, int nfields); +static int inzone(char ** fields, int nfields); +static int inzsub(char ** fields, int nfields, int iscont); +static int is32(zic_t x); +static int itsabbr(const char * abbr, const char * word); +static int itsdir(const char * name); +static int lowerit(int c); +static char * memcheck(char * tocheck); +static int mkdirs(char * filename); +static void newabbr(const char * abbr); +static long oadd(long t1, long t2); +static void outzone(const struct zone * zp, int ntzones); +static void puttzcode(long code, FILE * fp); +static void puttzcode64(zic_t code, FILE * fp); +static int rcomp(const void * leftp, const void * rightp); +static zic_t rpytime(const struct rule * rp, int wantedy); +static void rulesub(struct rule * rp, + const char * loyearp, const char * hiyearp, + const char * typep, const char * monthp, + const char * dayp, const char * timep); +static int stringoffset(char * result, long offset); +static int stringrule(char * result, const struct rule * rp, + long dstoff, long gmtoff); +static void stringzone(char * result, + const struct zone * zp, int ntzones); +static void setboundaries(void); +static void setgroup(gid_t *flag, const char *name); +static void setuser(uid_t *flag, const char *name); +static zic_t tadd(zic_t t1, long t2); +static void usage(FILE *stream, int status); +static void writezone(const char * name, const char * string); +static int yearistype(int year, const char * type); + +static int charcnt; +static int errors; +static const char * filename; +static int leapcnt; +static int leapseen; +static int leapminyear; +static int leapmaxyear; +static int linenum; +static int max_abbrvar_len; +static int max_format_len; +static zic_t max_time; +static int max_year; +static zic_t min_time; +static int min_year; +static zic_t min_time; +static int noise; +static const char * rfilename; +static int rlinenum; +static int timecnt; +static int typecnt; + +/* +** Line codes. +*/ + +#define LC_RULE 0 +#define LC_ZONE 1 +#define LC_LINK 2 +#define LC_LEAP 3 + +/* +** Which fields are which on a Zone line. +*/ + +#define ZF_NAME 1 +#define ZF_GMTOFF 2 +#define ZF_RULE 3 +#define ZF_FORMAT 4 +#define ZF_TILYEAR 5 +#define ZF_TILMONTH 6 +#define ZF_TILDAY 7 +#define ZF_TILTIME 8 +#define ZONE_MINFIELDS 5 +#define ZONE_MAXFIELDS 9 + +/* +** Which fields are which on a Zone continuation line. +*/ + +#define ZFC_GMTOFF 0 +#define ZFC_RULE 1 +#define ZFC_FORMAT 2 +#define ZFC_TILYEAR 3 +#define ZFC_TILMONTH 4 +#define ZFC_TILDAY 5 +#define ZFC_TILTIME 6 +#define ZONEC_MINFIELDS 3 +#define ZONEC_MAXFIELDS 7 + +/* +** Which files are which on a Rule line. +*/ + +#define RF_NAME 1 +#define RF_LOYEAR 2 +#define RF_HIYEAR 3 +#define RF_COMMAND 4 +#define RF_MONTH 5 +#define RF_DAY 6 +#define RF_TOD 7 +#define RF_STDOFF 8 +#define RF_ABBRVAR 9 +#define RULE_FIELDS 10 + +/* +** Which fields are which on a Link line. +*/ + +#define LF_FROM 1 +#define LF_TO 2 +#define LINK_FIELDS 3 + +/* +** Which fields are which on a Leap line. +*/ + +#define LP_YEAR 1 +#define LP_MONTH 2 +#define LP_DAY 3 +#define LP_TIME 4 +#define LP_CORR 5 +#define LP_ROLL 6 +#define LEAP_FIELDS 7 + +/* +** Year synonyms. +*/ + +#define YR_MINIMUM 0 +#define YR_MAXIMUM 1 +#define YR_ONLY 2 + +static struct rule * rules; +static int nrules; /* number of rules */ + +static struct zone * zones; +static int nzones; /* number of zones */ + +struct link { + const char * l_filename; + int l_linenum; + const char * l_from; + const char * l_to; +}; + +static struct link * links; +static int nlinks; + +struct lookup { + const char * l_word; + const int l_value; +}; + +static struct lookup const * byword(const char * string, + const struct lookup * lp); + +static struct lookup const line_codes[] = { + { "Rule", LC_RULE }, + { "Zone", LC_ZONE }, + { "Link", LC_LINK }, + { "Leap", LC_LEAP }, + { NULL, 0} +}; + +static struct lookup const mon_names[] = { + { "January", TM_JANUARY }, + { "February", TM_FEBRUARY }, + { "March", TM_MARCH }, + { "April", TM_APRIL }, + { "May", TM_MAY }, + { "June", TM_JUNE }, + { "July", TM_JULY }, + { "August", TM_AUGUST }, + { "September", TM_SEPTEMBER }, + { "October", TM_OCTOBER }, + { "November", TM_NOVEMBER }, + { "December", TM_DECEMBER }, + { NULL, 0 } +}; + +static struct lookup const wday_names[] = { + { "Sunday", TM_SUNDAY }, + { "Monday", TM_MONDAY }, + { "Tuesday", TM_TUESDAY }, + { "Wednesday", TM_WEDNESDAY }, + { "Thursday", TM_THURSDAY }, + { "Friday", TM_FRIDAY }, + { "Saturday", TM_SATURDAY }, + { NULL, 0 } +}; + +static struct lookup const lasts[] = { + { "last-Sunday", TM_SUNDAY }, + { "last-Monday", TM_MONDAY }, + { "last-Tuesday", TM_TUESDAY }, + { "last-Wednesday", TM_WEDNESDAY }, + { "last-Thursday", TM_THURSDAY }, + { "last-Friday", TM_FRIDAY }, + { "last-Saturday", TM_SATURDAY }, + { NULL, 0 } +}; + +static struct lookup const begin_years[] = { + { "minimum", YR_MINIMUM }, + { "maximum", YR_MAXIMUM }, + { NULL, 0 } +}; + +static struct lookup const end_years[] = { + { "minimum", YR_MINIMUM }, + { "maximum", YR_MAXIMUM }, + { "only", YR_ONLY }, + { NULL, 0 } +}; + +static struct lookup const leap_types[] = { + { "Rolling", TRUE }, + { "Stationary", FALSE }, + { NULL, 0 } +}; + +static const int len_months[2][MONSPERYEAR] = { + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +static const int len_years[2] = { + DAYSPERNYEAR, DAYSPERLYEAR +}; + +static struct attype { + zic_t at; + unsigned char type; +} attypes[TZ_MAX_TIMES]; +static long gmtoffs[TZ_MAX_TYPES]; +static char isdsts[TZ_MAX_TYPES]; +static unsigned char abbrinds[TZ_MAX_TYPES]; +static char ttisstds[TZ_MAX_TYPES]; +static char ttisgmts[TZ_MAX_TYPES]; +static char chars[TZ_MAX_CHARS]; +static zic_t trans[TZ_MAX_LEAPS]; +static long corr[TZ_MAX_LEAPS]; +static char roll[TZ_MAX_LEAPS]; + +/* +** Memory allocation. +*/ + +static char * +memcheck(ptr) +char * const ptr; +{ + if (ptr == NULL) + errx(EXIT_FAILURE, _("memory exhausted")); + return ptr; +} + +#define emalloc(size) memcheck(imalloc(size)) +#define erealloc(ptr, size) memcheck(irealloc((ptr), (size))) +#define ecpyalloc(ptr) memcheck(icpyalloc(ptr)) +#define ecatalloc(oldp, newp) memcheck(icatalloc((oldp), (newp))) + +/* +** Error handling. +*/ + +static void +eats(name, num, rname, rnum) +const char * const name; +const int num; +const char * const rname; +const int rnum; +{ + filename = name; + linenum = num; + rfilename = rname; + rlinenum = rnum; +} + +static void +eat(name, num) +const char * const name; +const int num; +{ + eats(name, num, (char *) NULL, -1); +} + +static void +error(string) +const char * const string; +{ + /* + ** Match the format of "cc" to allow sh users to + ** zic ... 2>&1 | error -t "*" -v + ** on BSD systems. + */ + (void) fprintf(stderr, _("\"%s\", line %d: %s"), + filename, linenum, string); + if (rfilename != NULL) + (void) fprintf(stderr, _(" (rule from \"%s\", line %d)"), + rfilename, rlinenum); + (void) fprintf(stderr, "\n"); + ++errors; +} + +static void +warning(string) +const char * const string; +{ + char * cp; + + cp = ecpyalloc(_("warning: ")); + cp = ecatalloc(cp, string); + error(cp); + ifree(cp); + --errors; +} + +static void +usage(FILE *stream, int status) + { + (void) fprintf(stream, _("usage is zic \ +[ --version ] [--help] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\ +\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n\ +\n\ +Report bugs to tz@elsie.nci.nih.gov.\n")); + exit(status); +} + +static const char * psxrules; +static const char * lcltime; +static const char * directory; +static const char * leapsec; +static const char * yitcommand; +static int Dflag; +static uid_t uflag = (uid_t)-1; +static gid_t gflag = (gid_t)-1; +static mode_t mflag = (S_IRUSR | S_IRGRP | S_IROTH + | S_IWUSR); + +int +main(argc, argv) +int argc; +char * argv[]; +{ + register int i; + register int j; + register int c; + +#ifdef unix + (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH)); +#endif /* defined unix */ +#if HAVE_GETTEXT + (void) setlocale(LC_ALL, ""); +#ifdef TZ_DOMAINDIR + (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); +#endif /* defined TEXTDOMAINDIR */ + (void) textdomain(TZ_DOMAIN); +#endif /* HAVE_GETTEXT */ + if (TYPE_BIT(zic_t) < 64) { + (void) fprintf(stderr, "zic: %s\n", + _("wild compilation-time specification of zic_t")); + exit(EXIT_FAILURE); + } + for (i = 1; i < argc; ++i) + if (strcmp(argv[i], "--version") == 0) { + errx(EXIT_SUCCESS, "%s", elsieid); + } else if (strcmp(argv[i], "--help") == 0) { + usage(stdout, EXIT_SUCCESS); + } + while ((c = getopt(argc, argv, "Dd:g:l:m:p:L:u:vsy:")) != -1) + switch (c) { + default: + usage(stderr, EXIT_FAILURE); + case 'D': + Dflag = 1; + break; + case 'd': + if (directory == NULL) + directory = optarg; + else + errx(EXIT_FAILURE, +_("more than one -d option specified")); + break; + case 'g': + setgroup(&gflag, optarg); + break; + case 'l': + if (lcltime == NULL) + lcltime = optarg; + else + errx(EXIT_FAILURE, +_("more than one -l option specified")); + break; + case 'm': + { + void *set = setmode(optarg); + if (set == NULL) + errx(EXIT_FAILURE, +_("invalid file mode")); + mflag = getmode(set, mflag); + free(set); + break; + } + case 'p': + if (psxrules == NULL) + psxrules = optarg; + else + errx(EXIT_FAILURE, +_("more than one -p option specified")); + break; + case 'u': + setuser(&uflag, optarg); + break; + case 'y': + if (yitcommand == NULL) + yitcommand = optarg; + else + errx(EXIT_FAILURE, +_("more than one -y option specified")); + break; + case 'L': + if (leapsec == NULL) + leapsec = optarg; + else + errx(EXIT_FAILURE, +_("more than one -L option specified")); + break; + case 'v': + noise = TRUE; + break; + case 's': + (void) printf("zic: -s ignored\n"); + break; + } + if (optind == argc - 1 && strcmp(argv[optind], "=") == 0) + usage(stderr, EXIT_FAILURE); /* usage message by request */ + if (directory == NULL) + directory = TZDIR; + if (yitcommand == NULL) + yitcommand = "yearistype"; + + setboundaries(); + + if (optind < argc && leapsec != NULL) { + infile(leapsec); + adjleap(); + } + + for (i = optind; i < argc; ++i) + infile(argv[i]); + if (errors) + exit(EXIT_FAILURE); + associate(); + for (i = 0; i < nzones; i = j) { + /* + ** Find the next non-continuation zone entry. + */ + for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j) + continue; + outzone(&zones[i], j - i); + } + /* + ** Make links. + */ + for (i = 0; i < nlinks; ++i) { + eat(links[i].l_filename, links[i].l_linenum); + dolink(links[i].l_from, links[i].l_to); + if (noise) + for (j = 0; j < nlinks; ++j) + if (strcmp(links[i].l_to, + links[j].l_from) == 0) + warning(_("link to link")); + } + if (lcltime != NULL) { + eat("command line", 1); + dolink(lcltime, TZDEFAULT); + } + if (psxrules != NULL) { + eat("command line", 1); + dolink(psxrules, TZDEFRULES); + } + return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} + +static void +dolink(fromfield, tofield) +const char * const fromfield; +const char * const tofield; +{ + register char * fromname; + register char * toname; + + if (fromfield[0] == '/') + fromname = ecpyalloc(fromfield); + else { + fromname = ecpyalloc(directory); + fromname = ecatalloc(fromname, "/"); + fromname = ecatalloc(fromname, fromfield); + } + if (tofield[0] == '/') + toname = ecpyalloc(tofield); + else { + toname = ecpyalloc(directory); + toname = ecatalloc(toname, "/"); + toname = ecatalloc(toname, tofield); + } + /* + ** We get to be careful here since + ** there's a fair chance of root running us. + */ + if (!itsdir(toname)) + (void) remove(toname); + if (link(fromname, toname) != 0) { + int result; + + if (mkdirs(toname) != 0) + exit(EXIT_FAILURE); + + result = link(fromname, toname); +#if HAVE_SYMLINK + if (result != 0 && + access(fromname, F_OK) == 0 && + !itsdir(fromname)) { + const char *s = tofield; + register char * symlinkcontents = NULL; + while ((s = strchr(s+1, '/')) != NULL) + symlinkcontents = + ecatalloc(symlinkcontents, + "../"); + symlinkcontents = + ecatalloc(symlinkcontents, + fromname); + result = + symlink(symlinkcontents, + toname); + if (result == 0) +warning(_("hard link failed, symbolic link used")); + ifree(symlinkcontents); + } +#endif /* HAVE_SYMLINK */ + if (result != 0) { + err(EXIT_FAILURE, _("can't link from %s to %s"), + fromname, toname); + } + } + ifree(fromname); + ifree(toname); +} + +#define TIME_T_BITS_IN_FILE 64 + +static void +setboundaries (void) +{ + register int i; + + min_time = -1; + for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i) + min_time *= 2; + max_time = -(min_time + 1); +} + +static int +itsdir(name) +const char * const name; +{ + register char * myname; + register int accres; + + myname = ecpyalloc(name); + myname = ecatalloc(myname, "/."); + accres = access(myname, F_OK); + ifree(myname); + return accres == 0; +} + +/* +** Associate sets of rules with zones. +*/ + +/* +** Sort by rule name. +*/ + +static int +rcomp(cp1, cp2) +const void * cp1; +const void * cp2; +{ + return strcmp(((const struct rule *) cp1)->r_name, + ((const struct rule *) cp2)->r_name); +} + +static void +associate(void) +{ + register struct zone * zp; + register struct rule * rp; + register int base, out; + register int i, j; + + if (nrules != 0) { + (void) qsort((void *) rules, (size_t) nrules, + (size_t) sizeof *rules, rcomp); + for (i = 0; i < nrules - 1; ++i) { + if (strcmp(rules[i].r_name, + rules[i + 1].r_name) != 0) + continue; + if (strcmp(rules[i].r_filename, + rules[i + 1].r_filename) == 0) + continue; + eat(rules[i].r_filename, rules[i].r_linenum); + warning(_("same rule name in multiple files")); + eat(rules[i + 1].r_filename, rules[i + 1].r_linenum); + warning(_("same rule name in multiple files")); + for (j = i + 2; j < nrules; ++j) { + if (strcmp(rules[i].r_name, + rules[j].r_name) != 0) + break; + if (strcmp(rules[i].r_filename, + rules[j].r_filename) == 0) + continue; + if (strcmp(rules[i + 1].r_filename, + rules[j].r_filename) == 0) + continue; + break; + } + i = j - 1; + } + } + for (i = 0; i < nzones; ++i) { + zp = &zones[i]; + zp->z_rules = NULL; + zp->z_nrules = 0; + } + for (base = 0; base < nrules; base = out) { + rp = &rules[base]; + for (out = base + 1; out < nrules; ++out) + if (strcmp(rp->r_name, rules[out].r_name) != 0) + break; + for (i = 0; i < nzones; ++i) { + zp = &zones[i]; + if (strcmp(zp->z_rule, rp->r_name) != 0) + continue; + zp->z_rules = rp; + zp->z_nrules = out - base; + } + } + for (i = 0; i < nzones; ++i) { + zp = &zones[i]; + if (zp->z_nrules == 0) { + /* + ** Maybe we have a local standard time offset. + */ + eat(zp->z_filename, zp->z_linenum); + zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"), + TRUE); + /* + ** Note, though, that if there's no rule, + ** a '%s' in the format is a bad thing. + */ + if (strchr(zp->z_format, '%') != 0) + error(_("%s in ruleless zone")); + } + } + if (errors) + exit(EXIT_FAILURE); +} + +static void +infile(name) +const char * name; +{ + register FILE * fp; + register char ** fields; + register char * cp; + register const struct lookup * lp; + register int nfields; + register int wantcont; + register int num; + char buf[BUFSIZ]; + + if (strcmp(name, "-") == 0) { + name = _("standard input"); + fp = stdin; + } else if ((fp = fopen(name, "r")) == NULL) + err(EXIT_FAILURE, _("can't open %s"), name); + wantcont = FALSE; + for (num = 1; ; ++num) { + eat(name, num); + if (fgets(buf, (int) sizeof buf, fp) != buf) + break; + cp = strchr(buf, '\n'); + if (cp == NULL) { + error(_("line too long")); + exit(EXIT_FAILURE); + } + *cp = '\0'; + fields = getfields(buf); + nfields = 0; + while (fields[nfields] != NULL) { + static char nada; + + if (strcmp(fields[nfields], "-") == 0) + fields[nfields] = &nada; + ++nfields; + } + if (nfields == 0) { + /* nothing to do */ + } else if (wantcont) { + wantcont = inzcont(fields, nfields); + } else { + lp = byword(fields[0], line_codes); + if (lp == NULL) + error(_("input line of unknown type")); + else switch ((int) (lp->l_value)) { + case LC_RULE: + inrule(fields, nfields); + wantcont = FALSE; + break; + case LC_ZONE: + wantcont = inzone(fields, nfields); + break; + case LC_LINK: + inlink(fields, nfields); + wantcont = FALSE; + break; + case LC_LEAP: + if (name != leapsec) + warnx( +_("leap line in non leap seconds file %s"), name); + else inleap(fields, nfields); + wantcont = FALSE; + break; + default: /* "cannot happen" */ + errx(EXIT_FAILURE, +_("panic: invalid l_value %d"), lp->l_value); + } + } + ifree((char *) fields); + } + if (ferror(fp)) + errx(EXIT_FAILURE, _("error reading %s"), filename); + if (fp != stdin && fclose(fp)) + err(EXIT_FAILURE, _("error closing %s"), filename); + if (wantcont) + error(_("expected continuation line not found")); +} + +/* +** Convert a string of one of the forms +** h -h hh:mm -hh:mm hh:mm:ss -hh:mm:ss +** into a number of seconds. +** A null string maps to zero. +** Call error with errstring and return zero on errors. +*/ + +static long +gethms(string, errstring, signable) +const char * string; +const char * const errstring; +const int signable; +{ + long hh; + int mm, ss, sign; + + if (string == NULL || *string == '\0') + return 0; + if (!signable) + sign = 1; + else if (*string == '-') { + sign = -1; + ++string; + } else sign = 1; + if (sscanf(string, scheck(string, "%ld"), &hh) == 1) + mm = ss = 0; + else if (sscanf(string, scheck(string, "%ld:%d"), &hh, &mm) == 2) + ss = 0; + else if (sscanf(string, scheck(string, "%ld:%d:%d"), + &hh, &mm, &ss) != 3) { + error(errstring); + return 0; + } + if (hh < 0 || + mm < 0 || mm >= MINSPERHOUR || + ss < 0 || ss > SECSPERMIN) { + error(errstring); + return 0; + } + if (LONG_MAX / SECSPERHOUR < hh) { + error(_("time overflow")); + return 0; + } + if (noise && hh == HOURSPERDAY && mm == 0 && ss == 0) + warning(_("24:00 not handled by pre-1998 versions of zic")); + if (noise && (hh > HOURSPERDAY || + (hh == HOURSPERDAY && (mm != 0 || ss != 0)))) +warning(_("values over 24 hours not handled by pre-2007 versions of zic")); + return oadd(eitol(sign) * hh * eitol(SECSPERHOUR), + eitol(sign) * (eitol(mm) * eitol(SECSPERMIN) + eitol(ss))); +} + +static void +inrule(fields, nfields) +register char ** const fields; +const int nfields; +{ + static struct rule r; + + if (nfields != RULE_FIELDS) { + error(_("wrong number of fields on Rule line")); + return; + } + if (*fields[RF_NAME] == '\0') { + error(_("nameless rule")); + return; + } + r.r_filename = filename; + r.r_linenum = linenum; + r.r_stdoff = gethms(fields[RF_STDOFF], _("invalid saved time"), TRUE); + rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND], + fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]); + r.r_name = ecpyalloc(fields[RF_NAME]); + r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]); + if (max_abbrvar_len < strlen(r.r_abbrvar)) + max_abbrvar_len = strlen(r.r_abbrvar); + rules = (struct rule *) (void *) erealloc((char *) rules, + (int) ((nrules + 1) * sizeof *rules)); + rules[nrules++] = r; +} + +static int +inzone(fields, nfields) +register char ** const fields; +const int nfields; +{ + register int i; + static char * buf; + + if (nfields < ZONE_MINFIELDS || nfields > ZONE_MAXFIELDS) { + error(_("wrong number of fields on Zone line")); + return FALSE; + } + if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) { + buf = erealloc(buf, (int) (132 + strlen(TZDEFAULT))); + (void) sprintf(buf, +_("\"Zone %s\" line and -l option are mutually exclusive"), + TZDEFAULT); + error(buf); + return FALSE; + } + if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) { + buf = erealloc(buf, (int) (132 + strlen(TZDEFRULES))); + (void) sprintf(buf, +_("\"Zone %s\" line and -p option are mutually exclusive"), + TZDEFRULES); + error(buf); + return FALSE; + } + for (i = 0; i < nzones; ++i) + if (zones[i].z_name != NULL && + strcmp(zones[i].z_name, fields[ZF_NAME]) == 0) { + buf = erealloc(buf, (int) (132 + + strlen(fields[ZF_NAME]) + + strlen(zones[i].z_filename))); + (void) sprintf(buf, +_("duplicate zone name %s (file \"%s\", line %d)"), + fields[ZF_NAME], + zones[i].z_filename, + zones[i].z_linenum); + error(buf); + return FALSE; + } + return inzsub(fields, nfields, FALSE); +} + +static int +inzcont(fields, nfields) +register char ** const fields; +const int nfields; +{ + if (nfields < ZONEC_MINFIELDS || nfields > ZONEC_MAXFIELDS) { + error(_("wrong number of fields on Zone continuation line")); + return FALSE; + } + return inzsub(fields, nfields, TRUE); +} + +static int +inzsub(fields, nfields, iscont) +register char ** const fields; +const int nfields; +const int iscont; +{ + register char * cp; + static struct zone z; + register int i_gmtoff, i_rule, i_format; + register int i_untilyear, i_untilmonth; + register int i_untilday, i_untiltime; + register int hasuntil; + + if (iscont) { + i_gmtoff = ZFC_GMTOFF; + i_rule = ZFC_RULE; + i_format = ZFC_FORMAT; + i_untilyear = ZFC_TILYEAR; + i_untilmonth = ZFC_TILMONTH; + i_untilday = ZFC_TILDAY; + i_untiltime = ZFC_TILTIME; + z.z_name = NULL; + } else { + i_gmtoff = ZF_GMTOFF; + i_rule = ZF_RULE; + i_format = ZF_FORMAT; + i_untilyear = ZF_TILYEAR; + i_untilmonth = ZF_TILMONTH; + i_untilday = ZF_TILDAY; + i_untiltime = ZF_TILTIME; + z.z_name = ecpyalloc(fields[ZF_NAME]); + } + z.z_filename = filename; + z.z_linenum = linenum; + z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UTC offset"), TRUE); + if ((cp = strchr(fields[i_format], '%')) != 0) { + if (*++cp != 's' || strchr(cp, '%') != 0) { + error(_("invalid abbreviation format")); + return FALSE; + } + } + z.z_rule = ecpyalloc(fields[i_rule]); + z.z_format = ecpyalloc(fields[i_format]); + if (max_format_len < strlen(z.z_format)) + max_format_len = strlen(z.z_format); + hasuntil = nfields > i_untilyear; + if (hasuntil) { + z.z_untilrule.r_filename = filename; + z.z_untilrule.r_linenum = linenum; + rulesub(&z.z_untilrule, + fields[i_untilyear], + "only", + "", + (nfields > i_untilmonth) ? + fields[i_untilmonth] : "Jan", + (nfields > i_untilday) ? fields[i_untilday] : "1", + (nfields > i_untiltime) ? fields[i_untiltime] : "0"); + z.z_untiltime = rpytime(&z.z_untilrule, + z.z_untilrule.r_loyear); + if (iscont && nzones > 0 && + z.z_untiltime > min_time && + z.z_untiltime < max_time && + zones[nzones - 1].z_untiltime > min_time && + zones[nzones - 1].z_untiltime < max_time && + zones[nzones - 1].z_untiltime >= z.z_untiltime) { + error(_( +"Zone continuation line end time is not after end time of previous line" + )); + return FALSE; + } + } + zones = (struct zone *) (void *) erealloc((char *) zones, + (int) ((nzones + 1) * sizeof *zones)); + zones[nzones++] = z; + /* + ** If there was an UNTIL field on this line, + ** there's more information about the zone on the next line. + */ + return hasuntil; +} + +static void +inleap(fields, nfields) +register char ** const fields; +const int nfields; +{ + register const char * cp; + register const struct lookup * lp; + register int i, j; + int year, month, day; + long dayoff, tod; + zic_t t; + + if (nfields != LEAP_FIELDS) { + error(_("wrong number of fields on Leap line")); + return; + } + dayoff = 0; + cp = fields[LP_YEAR]; + if (sscanf(cp, scheck(cp, "%d"), &year) != 1) { + /* + ** Leapin' Lizards! + */ + error(_("invalid leaping year")); + return; + } + if (!leapseen || leapmaxyear < year) + leapmaxyear = year; + if (!leapseen || leapminyear > year) + leapminyear = year; + leapseen = TRUE; + j = EPOCH_YEAR; + while (j != year) { + if (year > j) { + i = len_years[isleap(j)]; + ++j; + } else { + --j; + i = -len_years[isleap(j)]; + } + dayoff = oadd(dayoff, eitol(i)); + } + if ((lp = byword(fields[LP_MONTH], mon_names)) == NULL) { + error(_("invalid month name")); + return; + } + month = lp->l_value; + j = TM_JANUARY; + while (j != month) { + i = len_months[isleap(year)][j]; + dayoff = oadd(dayoff, eitol(i)); + ++j; + } + cp = fields[LP_DAY]; + if (sscanf(cp, scheck(cp, "%d"), &day) != 1 || + day <= 0 || day > len_months[isleap(year)][month]) { + error(_("invalid day of month")); + return; + } + dayoff = oadd(dayoff, eitol(day - 1)); + if (dayoff < 0 && !TYPE_SIGNED(zic_t)) { + error(_("time before zero")); + return; + } + if (dayoff < min_time / SECSPERDAY) { + error(_("time too small")); + return; + } + if (dayoff > max_time / SECSPERDAY) { + error(_("time too large")); + return; + } + t = (zic_t) dayoff * SECSPERDAY; + tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE); + cp = fields[LP_CORR]; + { + register int positive; + int count; + + if (strcmp(cp, "") == 0) { /* infile() turns "-" into "" */ + positive = FALSE; + count = 1; + } else if (strcmp(cp, "--") == 0) { + positive = FALSE; + count = 2; + } else if (strcmp(cp, "+") == 0) { + positive = TRUE; + count = 1; + } else if (strcmp(cp, "++") == 0) { + positive = TRUE; + count = 2; + } else { + error(_("illegal CORRECTION field on Leap line")); + return; + } + if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) { + error(_( + "illegal Rolling/Stationary field on Leap line" + )); + return; + } + leapadd(tadd(t, tod), positive, lp->l_value, count); + } +} + +static void +inlink(fields, nfields) +register char ** const fields; +const int nfields; +{ + struct link l; + + if (nfields != LINK_FIELDS) { + error(_("wrong number of fields on Link line")); + return; + } + if (*fields[LF_FROM] == '\0') { + error(_("blank FROM field on Link line")); + return; + } + if (*fields[LF_TO] == '\0') { + error(_("blank TO field on Link line")); + return; + } + l.l_filename = filename; + l.l_linenum = linenum; + l.l_from = ecpyalloc(fields[LF_FROM]); + l.l_to = ecpyalloc(fields[LF_TO]); + links = (struct link *) (void *) erealloc((char *) links, + (int) ((nlinks + 1) * sizeof *links)); + links[nlinks++] = l; +} + +static void +rulesub(rp, loyearp, hiyearp, typep, monthp, dayp, timep) +register struct rule * const rp; +const char * const loyearp; +const char * const hiyearp; +const char * const typep; +const char * const monthp; +const char * const dayp; +const char * const timep; +{ + register const struct lookup * lp; + register const char * cp; + register char * dp; + register char * ep; + + if ((lp = byword(monthp, mon_names)) == NULL) { + error(_("invalid month name")); + return; + } + rp->r_month = lp->l_value; + rp->r_todisstd = FALSE; + rp->r_todisgmt = FALSE; + dp = ecpyalloc(timep); + if (*dp != '\0') { + ep = dp + strlen(dp) - 1; + switch (lowerit(*ep)) { + case 's': /* Standard */ + rp->r_todisstd = TRUE; + rp->r_todisgmt = FALSE; + *ep = '\0'; + break; + case 'w': /* Wall */ + rp->r_todisstd = FALSE; + rp->r_todisgmt = FALSE; + *ep = '\0'; + break; + case 'g': /* Greenwich */ + case 'u': /* Universal */ + case 'z': /* Zulu */ + rp->r_todisstd = TRUE; + rp->r_todisgmt = TRUE; + *ep = '\0'; + break; + } + } + rp->r_tod = gethms(dp, _("invalid time of day"), FALSE); + ifree(dp); + /* + ** Year work. + */ + cp = loyearp; + lp = byword(cp, begin_years); + rp->r_lowasnum = lp == NULL; + if (!rp->r_lowasnum) switch ((int) lp->l_value) { + case YR_MINIMUM: + rp->r_loyear = INT_MIN; + break; + case YR_MAXIMUM: + rp->r_loyear = INT_MAX; + break; + default: /* "cannot happen" */ + errx(EXIT_FAILURE, + _("panic: invalid l_value %d"), lp->l_value); + } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) { + error(_("invalid starting year")); + return; + } + cp = hiyearp; + lp = byword(cp, end_years); + rp->r_hiwasnum = lp == NULL; + if (!rp->r_hiwasnum) switch ((int) lp->l_value) { + case YR_MINIMUM: + rp->r_hiyear = INT_MIN; + break; + case YR_MAXIMUM: + rp->r_hiyear = INT_MAX; + break; + case YR_ONLY: + rp->r_hiyear = rp->r_loyear; + break; + default: /* "cannot happen" */ + errx(EXIT_FAILURE, + _("panic: invalid l_value %d"), lp->l_value); + } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) { + error(_("invalid ending year")); + return; + } + if (rp->r_loyear > rp->r_hiyear) { + error(_("starting year greater than ending year")); + return; + } + if (*typep == '\0') + rp->r_yrtype = NULL; + else { + if (rp->r_loyear == rp->r_hiyear) { + error(_("typed single year")); + return; + } + rp->r_yrtype = ecpyalloc(typep); + } + /* + ** Day work. + ** Accept things such as: + ** 1 + ** last-Sunday + ** Sun<=20 + ** Sun>=7 + */ + dp = ecpyalloc(dayp); + if ((lp = byword(dp, lasts)) != NULL) { + rp->r_dycode = DC_DOWLEQ; + rp->r_wday = lp->l_value; + rp->r_dayofmonth = len_months[1][rp->r_month]; + } else { + if ((ep = strchr(dp, '<')) != 0) + rp->r_dycode = DC_DOWLEQ; + else if ((ep = strchr(dp, '>')) != 0) + rp->r_dycode = DC_DOWGEQ; + else { + ep = dp; + rp->r_dycode = DC_DOM; + } + if (rp->r_dycode != DC_DOM) { + *ep++ = 0; + if (*ep++ != '=') { + error(_("invalid day of month")); + ifree(dp); + return; + } + if ((lp = byword(dp, wday_names)) == NULL) { + error(_("invalid weekday name")); + ifree(dp); + return; + } + rp->r_wday = lp->l_value; + } + if (sscanf(ep, scheck(ep, "%d"), &rp->r_dayofmonth) != 1 || + rp->r_dayofmonth <= 0 || + (rp->r_dayofmonth > len_months[1][rp->r_month])) { + error(_("invalid day of month")); + ifree(dp); + return; + } + } + ifree(dp); +} + +static void +convert(val, buf) +const long val; +char * const buf; +{ + register int i; + register int shift; + + for (i = 0, shift = 24; i < 4; ++i, shift -= 8) + buf[i] = val >> shift; +} + +static void +convert64(val, buf) +const zic_t val; +char * const buf; +{ + register int i; + register int shift; + + for (i = 0, shift = 56; i < 8; ++i, shift -= 8) + buf[i] = val >> shift; +} + +static void +puttzcode(val, fp) +const long val; +FILE * const fp; +{ + char buf[4]; + + convert(val, buf); + (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); +} + +static void +puttzcode64(val, fp) +const zic_t val; +FILE * const fp; +{ + char buf[8]; + + convert64(val, buf); + (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); +} + +static int +atcomp(avp, bvp) +const void * avp; +const void * bvp; +{ + const zic_t a = ((const struct attype *) avp)->at; + const zic_t b = ((const struct attype *) bvp)->at; + + return (a < b) ? -1 : (a > b); +} + +static int +is32(x) +const zic_t x; +{ + return INT32_MIN <= x && x <= INT32_MAX; +} + +static void +writezone(name, string) +const char * const name; +const char * const string; +{ + register FILE * fp; + register int i, j; + register int leapcnt32, leapi32; + register int timecnt32, timei32; + register int pass; + static char * fullname; + static const struct tzhead tzh0; + static struct tzhead tzh; + zic_t ats[TZ_MAX_TIMES]; + unsigned char types[TZ_MAX_TIMES]; + + /* + ** Sort. + */ + if (timecnt > 1) + (void) qsort((void *) attypes, (size_t) timecnt, + (size_t) sizeof *attypes, atcomp); + /* + ** Optimize. + */ + { + int fromi; + int toi; + + toi = 0; + fromi = 0; + while (fromi < timecnt && attypes[fromi].at < min_time) + ++fromi; + if (isdsts[0] == 0) + while (fromi < timecnt && attypes[fromi].type == 0) + ++fromi; /* handled by default rule */ + for ( ; fromi < timecnt; ++fromi) { + if (toi != 0 && ((attypes[fromi].at + + gmtoffs[attypes[toi - 1].type]) <= + (attypes[toi - 1].at + gmtoffs[toi == 1 ? 0 + : attypes[toi - 2].type]))) { + attypes[toi - 1].type = + attypes[fromi].type; + continue; + } + if (toi == 0 || + attypes[toi - 1].type != attypes[fromi].type) + attypes[toi++] = attypes[fromi]; + } + timecnt = toi; + } + /* + ** Transfer. + */ + for (i = 0; i < timecnt; ++i) { + ats[i] = attypes[i].at; + types[i] = attypes[i].type; + } + /* + ** Correct for leap seconds. + */ + for (i = 0; i < timecnt; ++i) { + j = leapcnt; + while (--j >= 0) + if (ats[i] > trans[j] - corr[j]) { + ats[i] = tadd(ats[i], corr[j]); + break; + } + } + /* + ** Figure out 32-bit-limited starts and counts. + */ + timecnt32 = timecnt; + timei32 = 0; + leapcnt32 = leapcnt; + leapi32 = 0; + while (timecnt32 > 0 && !is32(ats[timecnt32 - 1])) + --timecnt32; + while (timecnt32 > 0 && !is32(ats[timei32])) { + --timecnt32; + ++timei32; + } + while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1])) + --leapcnt32; + while (leapcnt32 > 0 && !is32(trans[leapi32])) { + --leapcnt32; + ++leapi32; + } + fullname = erealloc(fullname, + (int) (strlen(directory) + 1 + strlen(name) + 1)); + (void) sprintf(fullname, "%s/%s", directory, name); + + /* + * Remove old file, if any, to snap links. + */ + if (!itsdir(fullname) && remove(fullname) != 0 && errno != ENOENT) + err(EXIT_FAILURE, _("can't remove %s"), fullname); + + if ((fp = fopen(fullname, "wb")) == NULL) { + if (mkdirs(fullname) != 0) + exit(EXIT_FAILURE); + if ((fp = fopen(fullname, "wb")) == NULL) + err(EXIT_FAILURE, _("can't create %s"), fullname); + } + for (pass = 1; pass <= 2; ++pass) { + register int thistimei, thistimecnt; + register int thisleapi, thisleapcnt; + register int thistimelim, thisleaplim; + int writetype[TZ_MAX_TIMES]; + int typemap[TZ_MAX_TYPES]; + register int thistypecnt; + char thischars[TZ_MAX_CHARS]; + char thischarcnt; + int indmap[TZ_MAX_CHARS]; + + if (pass == 1) { + thistimei = timei32; + thistimecnt = timecnt32; + thisleapi = leapi32; + thisleapcnt = leapcnt32; + } else { + thistimei = 0; + thistimecnt = timecnt; + thisleapi = 0; + thisleapcnt = leapcnt; + } + thistimelim = thistimei + thistimecnt; + thisleaplim = thisleapi + thisleapcnt; + for (i = 0; i < typecnt; ++i) + writetype[i] = thistimecnt == timecnt; + if (thistimecnt == 0) { + /* + ** No transition times fall in the current + ** (32- or 64-bit) window. + */ + if (typecnt != 0) + writetype[typecnt - 1] = TRUE; + } else { + for (i = thistimei - 1; i < thistimelim; ++i) + if (i >= 0) + writetype[types[i]] = TRUE; + /* + ** For America/Godthab and Antarctica/Palmer + */ + if (thistimei == 0) + writetype[0] = TRUE; + } +#ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH + /* + ** For some pre-2011 systems: if the last-to-be-written + ** standard (or daylight) type has an offset different from the + ** most recently used offset, + ** append an (unused) copy of the most recently used type + ** (to help get global "altzone" and "timezone" variables + ** set correctly). + */ + { + register int mrudst, mrustd, hidst, histd, type; + + hidst = histd = mrudst = mrustd = -1; + for (i = thistimei; i < thistimelim; ++i) + if (isdsts[types[i]]) + mrudst = types[i]; + else mrustd = types[i]; + for (i = 0; i < typecnt; ++i) + if (writetype[i]) { + if (isdsts[i]) + hidst = i; + else histd = i; + } + if (hidst >= 0 && mrudst >= 0 && hidst != mrudst && + gmtoffs[hidst] != gmtoffs[mrudst]) { + isdsts[mrudst] = -1; + type = addtype(gmtoffs[mrudst], + &chars[abbrinds[mrudst]], + TRUE, + ttisstds[mrudst], + ttisgmts[mrudst]); + isdsts[mrudst] = TRUE; + writetype[type] = TRUE; + } + if (histd >= 0 && mrustd >= 0 && histd != mrustd && + gmtoffs[histd] != gmtoffs[mrustd]) { + isdsts[mrustd] = -1; + type = addtype(gmtoffs[mrustd], + &chars[abbrinds[mrustd]], + FALSE, + ttisstds[mrustd], + ttisgmts[mrustd]); + isdsts[mrustd] = FALSE; + writetype[type] = TRUE; + } + } +#endif /* !defined LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH */ + thistypecnt = 0; + for (i = 0; i < typecnt; ++i) + typemap[i] = writetype[i] ? thistypecnt++ : -1; + for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i) + indmap[i] = -1; + thischarcnt = 0; + for (i = 0; i < typecnt; ++i) { + register char * thisabbr; + + if (!writetype[i]) + continue; + if (indmap[abbrinds[i]] >= 0) + continue; + thisabbr = &chars[abbrinds[i]]; + for (j = 0; j < thischarcnt; ++j) + if (strcmp(&thischars[j], thisabbr) == 0) + break; + if (j == thischarcnt) { + (void) strcpy(&thischars[(int) thischarcnt], + thisabbr); + thischarcnt += strlen(thisabbr) + 1; + } + indmap[abbrinds[i]] = j; + } +#define DO(field) (void) fwrite((void *) tzh.field, \ + (size_t) sizeof tzh.field, (size_t) 1, fp) + tzh = tzh0; + (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); + tzh.tzh_version[0] = ZIC_VERSION; + convert(eitol(thistypecnt), tzh.tzh_ttisgmtcnt); + convert(eitol(thistypecnt), tzh.tzh_ttisstdcnt); + convert(eitol(thisleapcnt), tzh.tzh_leapcnt); + convert(eitol(thistimecnt), tzh.tzh_timecnt); + convert(eitol(thistypecnt), tzh.tzh_typecnt); + convert(eitol(thischarcnt), tzh.tzh_charcnt); + DO(tzh_magic); + DO(tzh_version); + DO(tzh_reserved); + DO(tzh_ttisgmtcnt); + DO(tzh_ttisstdcnt); + DO(tzh_leapcnt); + DO(tzh_timecnt); + DO(tzh_typecnt); + DO(tzh_charcnt); +#undef DO + for (i = thistimei; i < thistimelim; ++i) + if (pass == 1) + puttzcode((long) ats[i], fp); + else puttzcode64(ats[i], fp); + for (i = thistimei; i < thistimelim; ++i) { + unsigned char uc; + + uc = typemap[types[i]]; + (void) fwrite((void *) &uc, + (size_t) sizeof uc, + (size_t) 1, + fp); + } + for (i = 0; i < typecnt; ++i) + if (writetype[i]) { + puttzcode(gmtoffs[i], fp); + (void) putc(isdsts[i], fp); + (void) putc((unsigned char) indmap[abbrinds[i]], fp); + } + if (thischarcnt != 0) + (void) fwrite((void *) thischars, + (size_t) sizeof thischars[0], + (size_t) thischarcnt, fp); + for (i = thisleapi; i < thisleaplim; ++i) { + register zic_t todo; + + if (roll[i]) { + if (timecnt == 0 || trans[i] < ats[0]) { + j = 0; + while (isdsts[j]) + if (++j >= typecnt) { + j = 0; + break; + } + } else { + j = 1; + while (j < timecnt && + trans[i] >= ats[j]) + ++j; + j = types[j - 1]; + } + todo = tadd(trans[i], -gmtoffs[j]); + } else todo = trans[i]; + if (pass == 1) + puttzcode((long) todo, fp); + else puttzcode64(todo, fp); + puttzcode(corr[i], fp); + } + for (i = 0; i < typecnt; ++i) + if (writetype[i]) + (void) putc(ttisstds[i], fp); + for (i = 0; i < typecnt; ++i) + if (writetype[i]) + (void) putc(ttisgmts[i], fp); + } + (void) fprintf(fp, "\n%s\n", string); + if (ferror(fp) || fclose(fp)) + errx(EXIT_FAILURE, _("error writing %s"), fullname); + if (chmod(fullname, mflag) < 0) + err(EXIT_FAILURE, _("cannot change mode of %s to %03o"), + fullname, (unsigned)mflag); + if ((uflag != (uid_t)-1 || gflag != (gid_t)-1) + && chown(fullname, uflag, gflag) < 0) + err(EXIT_FAILURE, _("cannot change ownership of %s"), + fullname); +} + +static void +doabbr(abbr, format, letters, isdst, doquotes) +char * const abbr; +const char * const format; +const char * const letters; +const int isdst; +const int doquotes; +{ + register char * cp; + register char * slashp; + register int len; + + slashp = strchr(format, '/'); + if (slashp == NULL) { + if (letters == NULL) + (void) strcpy(abbr, format); + else (void) sprintf(abbr, format, letters); + } else if (isdst) { + (void) strcpy(abbr, slashp + 1); + } else { + if (slashp > format) + (void) strncpy(abbr, format, + (unsigned) (slashp - format)); + abbr[slashp - format] = '\0'; + } + if (!doquotes) + return; + for (cp = abbr; *cp != '\0'; ++cp) + if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", *cp) == NULL && + strchr("abcdefghijklmnopqrstuvwxyz", *cp) == NULL) + break; + len = strlen(abbr); + if (len > 0 && *cp == '\0') + return; + abbr[len + 2] = '\0'; + abbr[len + 1] = '>'; + for ( ; len > 0; --len) + abbr[len] = abbr[len - 1]; + abbr[0] = '<'; +} + +static void +updateminmax(x) +const int x; +{ + if (min_year > x) + min_year = x; + if (max_year < x) + max_year = x; +} + +static int +stringoffset(result, offset) +char * result; +long offset; +{ + register int hours; + register int minutes; + register int seconds; + + result[0] = '\0'; + if (offset < 0) { + (void) strcpy(result, "-"); + offset = -offset; + } + seconds = offset % SECSPERMIN; + offset /= SECSPERMIN; + minutes = offset % MINSPERHOUR; + offset /= MINSPERHOUR; + hours = offset; + if (hours >= HOURSPERDAY) { + result[0] = '\0'; + return -1; + } + (void) sprintf(end(result), "%d", hours); + if (minutes != 0 || seconds != 0) { + (void) sprintf(end(result), ":%02d", minutes); + if (seconds != 0) + (void) sprintf(end(result), ":%02d", seconds); + } + return 0; +} + +static int +stringrule(result, rp, dstoff, gmtoff) +char * result; +const struct rule * const rp; +const long dstoff; +const long gmtoff; +{ + register long tod; + + result = end(result); + if (rp->r_dycode == DC_DOM) { + register int month, total; + + if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY) + return -1; + total = 0; + for (month = 0; month < rp->r_month; ++month) + total += len_months[0][month]; + (void) sprintf(result, "J%d", total + rp->r_dayofmonth); + } else { + register int week; + + if (rp->r_dycode == DC_DOWGEQ) { + week = 1 + rp->r_dayofmonth / DAYSPERWEEK; + if ((week - 1) * DAYSPERWEEK + 1 != rp->r_dayofmonth) + return -1; + } else if (rp->r_dycode == DC_DOWLEQ) { + if (rp->r_dayofmonth == len_months[1][rp->r_month]) + week = 5; + else { + week = 1 + rp->r_dayofmonth / DAYSPERWEEK; + if (week * DAYSPERWEEK - 1 != rp->r_dayofmonth) + return -1; + } + } else return -1; /* "cannot happen" */ + (void) sprintf(result, "M%d.%d.%d", + rp->r_month + 1, week, rp->r_wday); + } + tod = rp->r_tod; + if (rp->r_todisgmt) + tod += gmtoff; + if (rp->r_todisstd && rp->r_stdoff == 0) + tod += dstoff; + if (tod < 0) { + result[0] = '\0'; + return -1; + } + if (tod != 2 * SECSPERMIN * MINSPERHOUR) { + (void) strcat(result, "/"); + if (stringoffset(end(result), tod) != 0) + return -1; + } + return 0; +} + +static void +stringzone(result, zpfirst, zonecount) +char * result; +const struct zone * const zpfirst; +const int zonecount; +{ + register const struct zone * zp; + register struct rule * rp; + register struct rule * stdrp; + register struct rule * dstrp; + register int i; + register const char * abbrvar; + + result[0] = '\0'; + zp = zpfirst + zonecount - 1; + stdrp = dstrp = NULL; + for (i = 0; i < zp->z_nrules; ++i) { + rp = &zp->z_rules[i]; + if (rp->r_hiwasnum || rp->r_hiyear != INT_MAX) + continue; + if (rp->r_yrtype != NULL) + continue; + if (rp->r_stdoff == 0) { + if (stdrp == NULL) + stdrp = rp; + else return; + } else { + if (dstrp == NULL) + dstrp = rp; + else return; + } + } + if (stdrp == NULL && dstrp == NULL) { + /* + ** There are no rules running through "max". + ** Let's find the latest rule. + */ + for (i = 0; i < zp->z_nrules; ++i) { + rp = &zp->z_rules[i]; + if (stdrp == NULL || rp->r_hiyear > stdrp->r_hiyear || + (rp->r_hiyear == stdrp->r_hiyear && + rp->r_month > stdrp->r_month)) + stdrp = rp; + } + if (stdrp != NULL && stdrp->r_stdoff != 0) + return; /* We end up in DST (a POSIX no-no). */ + /* + ** Horrid special case: if year is 2037, + ** presume this is a zone handled on a year-by-year basis; + ** do not try to apply a rule to the zone. + */ + if (stdrp != NULL && stdrp->r_hiyear == 2037) + return; + } + if (stdrp == NULL && (zp->z_nrules != 0 || zp->z_stdoff != 0)) + return; + abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar; + doabbr(result, zp->z_format, abbrvar, FALSE, TRUE); + if (stringoffset(end(result), -zp->z_gmtoff) != 0) { + result[0] = '\0'; + return; + } + if (dstrp == NULL) + return; + doabbr(end(result), zp->z_format, dstrp->r_abbrvar, TRUE, TRUE); + if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR) + if (stringoffset(end(result), + -(zp->z_gmtoff + dstrp->r_stdoff)) != 0) { + result[0] = '\0'; + return; + } + (void) strcat(result, ","); + if (stringrule(result, dstrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) { + result[0] = '\0'; + return; + } + (void) strcat(result, ","); + if (stringrule(result, stdrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) { + result[0] = '\0'; + return; + } +} + +static void +outzone(zpfirst, zonecount) +const struct zone * const zpfirst; +const int zonecount; +{ + register const struct zone * zp; + register struct rule * rp; + register int i, j; + register int usestart, useuntil; + register zic_t starttime, untiltime; + register long gmtoff; + register long stdoff; + register int year; + register long startoff; + register int startttisstd; + register int startttisgmt; + register int type; + register char * startbuf; + register char * ab; + register char * envvar; + register int max_abbr_len; + register int max_envvar_len; + + max_abbr_len = 2 + max_format_len + max_abbrvar_len; + max_envvar_len = 2 * max_abbr_len + 5 * 9; + startbuf = emalloc(max_abbr_len + 1); + ab = emalloc(max_abbr_len + 1); + envvar = emalloc(max_envvar_len + 1); + INITIALIZE(untiltime); + INITIALIZE(starttime); + /* + ** Now. . .finally. . .generate some useful data! + */ + timecnt = 0; + typecnt = 0; + charcnt = 0; + /* + ** Thanks to Earl Chew + ** for noting the need to unconditionally initialize startttisstd. + */ + startttisstd = FALSE; + startttisgmt = FALSE; + min_year = max_year = EPOCH_YEAR; + if (leapseen) { + updateminmax(leapminyear); + updateminmax(leapmaxyear + (leapmaxyear < INT_MAX)); + } + for (i = 0; i < zonecount; ++i) { + zp = &zpfirst[i]; + if (i < zonecount - 1) + updateminmax(zp->z_untilrule.r_loyear); + for (j = 0; j < zp->z_nrules; ++j) { + rp = &zp->z_rules[j]; + if (rp->r_lowasnum) + updateminmax(rp->r_loyear); + if (rp->r_hiwasnum) + updateminmax(rp->r_hiyear); + } + } + /* + ** Generate lots of data if a rule can't cover all future times. + */ + stringzone(envvar, zpfirst, zonecount); + if (noise && envvar[0] == '\0') { + register char * wp; + +wp = ecpyalloc(_("no POSIX environment variable for zone")); + wp = ecatalloc(wp, " "); + wp = ecatalloc(wp, zpfirst->z_name); + warning(wp); + ifree(wp); + } + if (envvar[0] == '\0') { + if (min_year >= INT_MIN + YEARSPERREPEAT) + min_year -= YEARSPERREPEAT; + else min_year = INT_MIN; + if (max_year <= INT_MAX - YEARSPERREPEAT) + max_year += YEARSPERREPEAT; + else max_year = INT_MAX; + } + /* + ** For the benefit of older systems, + ** generate data from 1900 through 2037. + */ + if (min_year > 1900) + min_year = 1900; + if (max_year < 2037) + max_year = 2037; + for (i = 0; i < zonecount; ++i) { + /* + ** A guess that may well be corrected later. + */ + stdoff = 0; + zp = &zpfirst[i]; + usestart = i > 0 && (zp - 1)->z_untiltime > min_time; + useuntil = i < (zonecount - 1); + if (useuntil && zp->z_untiltime <= min_time) + continue; + gmtoff = zp->z_gmtoff; + eat(zp->z_filename, zp->z_linenum); + *startbuf = '\0'; + startoff = zp->z_gmtoff; + if (zp->z_nrules == 0) { + stdoff = zp->z_stdoff; + doabbr(startbuf, zp->z_format, + (char *) NULL, stdoff != 0, FALSE); + type = addtype(oadd(zp->z_gmtoff, stdoff), + startbuf, stdoff != 0, startttisstd, + startttisgmt); + if (usestart) { + addtt(starttime, type); + usestart = FALSE; + } else if (stdoff != 0) + addtt(min_time, type); + } else for (year = min_year; year <= max_year; ++year) { + if (useuntil && year > zp->z_untilrule.r_hiyear) + break; + /* + ** Mark which rules to do in the current year. + ** For those to do, calculate rpytime(rp, year); + */ + for (j = 0; j < zp->z_nrules; ++j) { + rp = &zp->z_rules[j]; + eats(zp->z_filename, zp->z_linenum, + rp->r_filename, rp->r_linenum); + rp->r_todo = year >= rp->r_loyear && + year <= rp->r_hiyear && + yearistype(year, rp->r_yrtype); + if (rp->r_todo) + rp->r_temp = rpytime(rp, year); + } + for ( ; ; ) { + register int k; + register zic_t jtime, ktime; + register long offset; + + INITIALIZE(ktime); + if (useuntil) { + /* + ** Turn untiltime into UTC + ** assuming the current gmtoff and + ** stdoff values. + */ + untiltime = zp->z_untiltime; + if (!zp->z_untilrule.r_todisgmt) + untiltime = tadd(untiltime, + -gmtoff); + if (!zp->z_untilrule.r_todisstd) + untiltime = tadd(untiltime, + -stdoff); + } + /* + ** Find the rule (of those to do, if any) + ** that takes effect earliest in the year. + */ + k = -1; + for (j = 0; j < zp->z_nrules; ++j) { + rp = &zp->z_rules[j]; + if (!rp->r_todo) + continue; + eats(zp->z_filename, zp->z_linenum, + rp->r_filename, rp->r_linenum); + offset = rp->r_todisgmt ? 0 : gmtoff; + if (!rp->r_todisstd) + offset = oadd(offset, stdoff); + jtime = rp->r_temp; + if (jtime == min_time || + jtime == max_time) + continue; + jtime = tadd(jtime, -offset); + if (k < 0 || jtime < ktime) { + k = j; + ktime = jtime; + } + } + if (k < 0) + break; /* go on to next year */ + rp = &zp->z_rules[k]; + rp->r_todo = FALSE; + if (useuntil && ktime >= untiltime) + break; + stdoff = rp->r_stdoff; + if (usestart && ktime == starttime) + usestart = FALSE; + if (usestart) { + if (ktime < starttime) { + startoff = oadd(zp->z_gmtoff, + stdoff); + doabbr(startbuf, zp->z_format, + rp->r_abbrvar, + rp->r_stdoff != 0, + FALSE); + continue; + } + if (*startbuf == '\0' && + startoff == oadd(zp->z_gmtoff, + stdoff)) { + doabbr(startbuf, + zp->z_format, + rp->r_abbrvar, + rp->r_stdoff != + 0, + FALSE); + } + } + eats(zp->z_filename, zp->z_linenum, + rp->r_filename, rp->r_linenum); + doabbr(ab, zp->z_format, rp->r_abbrvar, + rp->r_stdoff != 0, FALSE); + offset = oadd(zp->z_gmtoff, rp->r_stdoff); + type = addtype(offset, ab, rp->r_stdoff != 0, + rp->r_todisstd, rp->r_todisgmt); + addtt(ktime, type); + } + } + if (usestart) { + if (*startbuf == '\0' && + zp->z_format != NULL && + strchr(zp->z_format, '%') == NULL && + strchr(zp->z_format, '/') == NULL) + (void) strcpy(startbuf, zp->z_format); + eat(zp->z_filename, zp->z_linenum); + if (*startbuf == '\0') +error(_("can't determine time zone abbreviation to use just after until time")); + else addtt(starttime, + addtype(startoff, startbuf, + startoff != zp->z_gmtoff, + startttisstd, + startttisgmt)); + } + /* + ** Now we may get to set starttime for the next zone line. + */ + if (useuntil) { + startttisstd = zp->z_untilrule.r_todisstd; + startttisgmt = zp->z_untilrule.r_todisgmt; + starttime = zp->z_untiltime; + if (!startttisstd) + starttime = tadd(starttime, -stdoff); + if (!startttisgmt) + starttime = tadd(starttime, -gmtoff); + } + } + writezone(zpfirst->z_name, envvar); + ifree(startbuf); + ifree(ab); + ifree(envvar); +} + +static void +addtt(starttime, type) +const zic_t starttime; +int type; +{ + if (starttime <= min_time || + (timecnt == 1 && attypes[0].at < min_time)) { + gmtoffs[0] = gmtoffs[type]; + isdsts[0] = isdsts[type]; + ttisstds[0] = ttisstds[type]; + ttisgmts[0] = ttisgmts[type]; + if (abbrinds[type] != 0) + (void) strcpy(chars, &chars[abbrinds[type]]); + abbrinds[0] = 0; + charcnt = strlen(chars) + 1; + typecnt = 1; + timecnt = 0; + type = 0; + } + if (timecnt >= TZ_MAX_TIMES) { + error(_("too many transitions?!")); + exit(EXIT_FAILURE); + } + attypes[timecnt].at = starttime; + attypes[timecnt].type = type; + ++timecnt; +} + +static int +addtype(gmtoff, abbr, isdst, ttisstd, ttisgmt) +const long gmtoff; +const char * const abbr; +const int isdst; +const int ttisstd; +const int ttisgmt; +{ + register int i, j; + + if (isdst != TRUE && isdst != FALSE) { + error(_("internal error - addtype called with bad isdst")); + exit(EXIT_FAILURE); + } + if (ttisstd != TRUE && ttisstd != FALSE) { + error(_("internal error - addtype called with bad ttisstd")); + exit(EXIT_FAILURE); + } + if (ttisgmt != TRUE && ttisgmt != FALSE) { + error(_("internal error - addtype called with bad ttisgmt")); + exit(EXIT_FAILURE); + } + /* + ** See if there's already an entry for this zone type. + ** If so, just return its index. + */ + for (i = 0; i < typecnt; ++i) { + if (gmtoff == gmtoffs[i] && isdst == isdsts[i] && + strcmp(abbr, &chars[abbrinds[i]]) == 0 && + ttisstd == ttisstds[i] && + ttisgmt == ttisgmts[i]) + return i; + } + /* + ** There isn't one; add a new one, unless there are already too + ** many. + */ + if (typecnt >= TZ_MAX_TYPES) { + error(_("too many local time types")); + exit(EXIT_FAILURE); + } + if (! (-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L)) { + error(_("UTC offset out of range")); + exit(EXIT_FAILURE); + } + gmtoffs[i] = gmtoff; + isdsts[i] = isdst; + ttisstds[i] = ttisstd; + ttisgmts[i] = ttisgmt; + + for (j = 0; j < charcnt; ++j) + if (strcmp(&chars[j], abbr) == 0) + break; + if (j == charcnt) + newabbr(abbr); + abbrinds[i] = j; + ++typecnt; + return i; +} + +static void +leapadd(t, positive, rolling, count) +const zic_t t; +const int positive; +const int rolling; +int count; +{ + register int i, j; + + if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) { + error(_("too many leap seconds")); + exit(EXIT_FAILURE); + } + for (i = 0; i < leapcnt; ++i) + if (t <= trans[i]) { + if (t == trans[i]) { + error(_("repeated leap second moment")); + exit(EXIT_FAILURE); + } + break; + } + do { + for (j = leapcnt; j > i; --j) { + trans[j] = trans[j - 1]; + corr[j] = corr[j - 1]; + roll[j] = roll[j - 1]; + } + trans[i] = t; + corr[i] = positive ? 1L : eitol(-count); + roll[i] = rolling; + ++leapcnt; + } while (positive && --count != 0); +} + +static void +adjleap(void) +{ + register int i; + register long last = 0; + + /* + ** propagate leap seconds forward + */ + for (i = 0; i < leapcnt; ++i) { + trans[i] = tadd(trans[i], last); + last = corr[i] += last; + } +} + +static int +yearistype(year, type) +const int year; +const char * const type; +{ + static char * buf; + int result; + + if (type == NULL || *type == '\0') + return TRUE; + buf = erealloc(buf, (int) (132 + strlen(yitcommand) + strlen(type))); + (void) sprintf(buf, "%s %d %s", yitcommand, year, type); + result = system(buf); + if (WIFEXITED(result)) switch (WEXITSTATUS(result)) { + case 0: + return TRUE; + case 1: + return FALSE; + } + error(_("wild result from command execution")); + warnx(_("command was '%s', result was %d"), buf, result); + for ( ; ; ) + exit(EXIT_FAILURE); +} + +static int +lowerit(a) +int a; +{ + a = (unsigned char) a; + return (isascii(a) && isupper(a)) ? tolower(a) : a; +} + +static int +ciequal(ap, bp) /* case-insensitive equality */ +register const char * ap; +register const char * bp; +{ + while (lowerit(*ap) == lowerit(*bp++)) + if (*ap++ == '\0') + return TRUE; + return FALSE; +} + +static int +itsabbr(abbr, word) +register const char * abbr; +register const char * word; +{ + if (lowerit(*abbr) != lowerit(*word)) + return FALSE; + ++word; + while (*++abbr != '\0') + do { + if (*word == '\0') + return FALSE; + } while (lowerit(*word++) != lowerit(*abbr)); + return TRUE; +} + +static const struct lookup * +byword(word, table) +register const char * const word; +register const struct lookup * const table; +{ + register const struct lookup * foundlp; + register const struct lookup * lp; + + if (word == NULL || table == NULL) + return NULL; + /* + ** Look for exact match. + */ + for (lp = table; lp->l_word != NULL; ++lp) + if (ciequal(word, lp->l_word)) + return lp; + /* + ** Look for inexact match. + */ + foundlp = NULL; + for (lp = table; lp->l_word != NULL; ++lp) + if (itsabbr(word, lp->l_word)) { + if (foundlp == NULL) + foundlp = lp; + else return NULL; /* multiple inexact matches */ + } + return foundlp; +} + +static char ** +getfields(cp) +register char * cp; +{ + register char * dp; + register char ** array; + register int nsubs; + + if (cp == NULL) + return NULL; + array = (char **) (void *) + emalloc((int) ((strlen(cp) + 1) * sizeof *array)); + nsubs = 0; + for ( ; ; ) { + while (isascii((unsigned char) *cp) && + isspace((unsigned char) *cp)) + ++cp; + if (*cp == '\0' || *cp == '#') + break; + array[nsubs++] = dp = cp; + do { + if ((*dp = *cp++) != '"') + ++dp; + else while ((*dp = *cp++) != '"') + if (*dp != '\0') + ++dp; + else { + error(_("odd number of quotation marks")); + exit(EXIT_FAILURE); + } + } while (*cp != '\0' && *cp != '#' && + (!isascii(*cp) || !isspace((unsigned char) *cp))); + if (isascii(*cp) && isspace((unsigned char) *cp)) + ++cp; + *dp = '\0'; + } + array[nsubs] = NULL; + return array; +} + +static long +oadd(t1, t2) +const long t1; +const long t2; +{ + register long t; + + t = t1 + t2; + if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { + error(_("time overflow")); + exit(EXIT_FAILURE); + } + return t; +} + +static zic_t +tadd(t1, t2) +const zic_t t1; +const long t2; +{ + register zic_t t; + + if (t1 == max_time && t2 > 0) + return max_time; + if (t1 == min_time && t2 < 0) + return min_time; + t = t1 + t2; + if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { + error(_("time overflow")); + exit(EXIT_FAILURE); + } + return t; +} + +/* +** Given a rule, and a year, compute the date - in seconds since January 1, +** 1970, 00:00 LOCAL time - in that year that the rule refers to. +*/ + +static zic_t +rpytime(rp, wantedy) +register const struct rule * const rp; +register const int wantedy; +{ + register int y, m, i; + register long dayoff; /* with a nod to Margaret O. */ + register zic_t t; + + if (wantedy == INT_MIN) + return min_time; + if (wantedy == INT_MAX) + return max_time; + dayoff = 0; + m = TM_JANUARY; + y = EPOCH_YEAR; + while (wantedy != y) { + if (wantedy > y) { + i = len_years[isleap(y)]; + ++y; + } else { + --y; + i = -len_years[isleap(y)]; + } + dayoff = oadd(dayoff, eitol(i)); + } + while (m != rp->r_month) { + i = len_months[isleap(y)][m]; + dayoff = oadd(dayoff, eitol(i)); + ++m; + } + i = rp->r_dayofmonth; + if (m == TM_FEBRUARY && i == 29 && !isleap(y)) { + if (rp->r_dycode == DC_DOWLEQ) + --i; + else { + error(_("use of 2/29 in non leap-year")); + exit(EXIT_FAILURE); + } + } + --i; + dayoff = oadd(dayoff, eitol(i)); + if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) { + register long wday; + +#define LDAYSPERWEEK ((long) DAYSPERWEEK) + wday = eitol(EPOCH_WDAY); + /* + ** Don't trust mod of negative numbers. + */ + if (dayoff >= 0) + wday = (wday + dayoff) % LDAYSPERWEEK; + else { + wday -= ((-dayoff) % LDAYSPERWEEK); + if (wday < 0) + wday += LDAYSPERWEEK; + } + while (wday != eitol(rp->r_wday)) + if (rp->r_dycode == DC_DOWGEQ) { + dayoff = oadd(dayoff, (long) 1); + if (++wday >= LDAYSPERWEEK) + wday = 0; + ++i; + } else { + dayoff = oadd(dayoff, (long) -1); + if (--wday < 0) + wday = LDAYSPERWEEK - 1; + --i; + } + if (i < 0 || i >= len_months[isleap(y)][m]) { + if (noise) + warning(_("rule goes past start/end of month--\ +will not work with pre-2004 versions of zic")); + } + } + if (dayoff < min_time / SECSPERDAY) + return min_time; + if (dayoff > max_time / SECSPERDAY) + return max_time; + t = (zic_t) dayoff * SECSPERDAY; + return tadd(t, rp->r_tod); +} + +static void +newabbr(string) +const char * const string; +{ + register int i; + + if (strcmp(string, GRANDPARENTED) != 0) { + register const char * cp; + register char * wp; + + cp = string; + wp = NULL; + while (isascii((unsigned char) *cp) && + (isalnum((unsigned char)*cp) || *cp == '-' || *cp == '+')) + ++cp; + if (noise && cp - string > 3) +wp = _("time zone abbreviation has more than 3 characters"); + if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN) +wp = _("time zone abbreviation has too many characters"); + if (*cp != '\0') +wp = _("time zone abbreviation differs from POSIX standard"); + if (wp != NULL) { + wp = ecpyalloc(wp); + wp = ecatalloc(wp, " ("); + wp = ecatalloc(wp, string); + wp = ecatalloc(wp, ")"); + warning(wp); + ifree(wp); + } + } + i = strlen(string) + 1; + if (charcnt + i > TZ_MAX_CHARS) { + error(_("too many, or too long, time zone abbreviations")); + exit(EXIT_FAILURE); + } + (void) strcpy(&chars[charcnt], string); + charcnt += eitol(i); +} + +static int +mkdirs(argname) +char * argname; +{ + register char * name; + register char * cp; + + if (argname == NULL || *argname == '\0' || Dflag) + return 0; + cp = name = ecpyalloc(argname); + while ((cp = strchr(cp + 1, '/')) != 0) { + *cp = '\0'; +#ifndef unix + /* + ** DOS drive specifier? + */ + if (isalpha((unsigned char) name[0]) && + name[1] == ':' && name[2] == '\0') { + *cp = '/'; + continue; + } +#endif /* !defined unix */ + if (!itsdir(name)) { + /* + ** It doesn't seem to exist, so we try to create it. + ** Creation may fail because of the directory being + ** created by some other multiprocessor, so we get + ** to do extra checking. + */ + if (mkdir(name, MKDIR_UMASK) != 0 + && (errno != EEXIST || !itsdir(name))) { + warn(_("can't create directory %s"), name); + ifree(name); + return -1; + } + } + *cp = '/'; + } + ifree(name); + return 0; +} + +static long +eitol(i) +const int i; +{ + long l; + + l = i; + if ((i < 0 && l >= 0) || (i == 0 && l != 0) || (i > 0 && l <= 0)) + errx(EXIT_FAILURE, _("%d did not sign extend correctly"), i); + return l; +} + +#include +#include + +static void +setgroup(flag, name) + gid_t *flag; + const char *name; +{ + struct group *gr; + + if (*flag != (gid_t)-1) + errx(EXIT_FAILURE, _("multiple -g flags specified")); + + gr = getgrnam(name); + if (gr == 0) { + char *ep; + unsigned long ul; + + ul = strtoul(name, &ep, 10); + if (ul == (unsigned long)(gid_t)ul && *ep == '\0') { + *flag = ul; + return; + } + errx(EXIT_FAILURE, _("group `%s' not found"), name); + } + *flag = gr->gr_gid; +} + +static void +setuser(flag, name) + uid_t *flag; + const char *name; +{ + struct passwd *pw; + + if (*flag != (gid_t)-1) + errx(EXIT_FAILURE, _("multiple -u flags specified")); + + pw = getpwnam(name); + if (pw == 0) { + char *ep; + unsigned long ul; + + ul = strtoul(name, &ep, 10); + if (ul == (unsigned long)(gid_t)ul && *ep == '\0') { + *flag = ul; + return; + } + errx(EXIT_FAILURE, _("user `%s' not found"), name); + } + *flag = pw->pw_uid; +} + +/* +** UNIX was a registered trademark of The Open Group in 2003. +*/ diff --git a/contrib/tzcode/zic/zic/Makefile b/contrib/tzcode/zic/zic/Makefile new file mode 100644 index 0000000..2c07728 --- /dev/null +++ b/contrib/tzcode/zic/zic/Makefile @@ -0,0 +1,16 @@ +# $FreeBSD: releng/11.1/contrib/tzcode/zic/zic/Makefile 201390 2010-01-02 11:07:44Z ed $ + +.PATH: ${.CURDIR}/.. + +PROG= zic +MAN= zic.8 +SRCS= zic.c ialloc.c scheck.c + +CFLAGS+= -DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DSTD_INSPIRED -DPCTS +CFLAGS+= -DHAVE_LONG_DOUBLE -DTZDIR=\"/usr/share/zoneinfo\" -Demkdir=mkdir +CFLAGS+= -DHAVE_STRERROR -DHAVE_UNISTD_H +CFLAGS+= -I${.CURDIR}/.. -I${.CURDIR}/../../../lib/libc/stdtime + +WARNS?= 2 + +.include diff --git a/include/Makefile b/include/Makefile new file mode 100644 index 0000000..358fdfd --- /dev/null +++ b/include/Makefile @@ -0,0 +1,398 @@ +# @(#)Makefile 8.2 (Berkeley) 1/4/94 +# $FreeBSD: releng/11.1/include/Makefile 318197 2017-05-11 20:55:11Z marius $ +# +# Doing a "make install" builds /usr/include. + +.include + +PACKAGE=runtime +TAGS+= development +CLEANFILES= osreldate.h version +SUBDIR= arpa protocols rpcsvc rpc xlocale +SUBDIR_PARALLEL= +INCS= a.out.h ar.h assert.h bitstring.h complex.h cpio.h _ctype.h ctype.h \ + db.h \ + dirent.h dlfcn.h elf.h elf-hints.h err.h fmtmsg.h fnmatch.h fstab.h \ + fts.h ftw.h getopt.h glob.h grp.h \ + ieeefp.h ifaddrs.h \ + inttypes.h iso646.h kenv.h langinfo.h libgen.h limits.h link.h \ + locale.h malloc.h malloc_np.h memory.h monetary.h mpool.h mqueue.h \ + ndbm.h netconfig.h \ + netdb.h nl_types.h nlist.h nss.h nsswitch.h paths.h \ + printf.h proc_service.h pthread.h \ + pthread_np.h pwd.h ranlib.h readpassphrase.h regex.h \ + res_update.h resolv.h runetype.h search.h semaphore.h setjmp.h \ + signal.h spawn.h stab.h stdalign.h stdbool.h stddef.h \ + stdnoreturn.h stdio.h stdlib.h string.h stringlist.h \ + strings.h sysexits.h tar.h termios.h tgmath.h \ + time.h timeconv.h timers.h ttyent.h \ + uchar.h ulimit.h unistd.h utime.h utmpx.h uuid.h varargs.h \ + wchar.h wctype.h wordexp.h xlocale.h + +.PATH: ${.CURDIR}/../contrib/libc-vis +INCS+= vis.h + +MHDRS= float.h floatingpoint.h stdarg.h + +PHDRS= sched.h _semaphore.h + +LHDRS= aio.h errno.h fcntl.h linker_set.h poll.h stdatomic.h stdint.h \ + syslog.h ucontext.h + +LDIRS= bsm cam geom net net80211 netgraph netinet netinet6 \ + netipsec netnatm netsmb nfs nfsclient nfsserver sys vm + +LSUBDIRS= cam/ata cam/nvme cam/scsi \ + dev/acpica dev/agp dev/an dev/bktr dev/ciss dev/filemon dev/firewire \ + dev/hwpmc dev/hyperv \ + dev/ic dev/iicbus dev/io dev/lmc dev/mfi dev/mmc dev/nvme \ + dev/ofw dev/pbio dev/pci ${_dev_powermac_nvram} dev/ppbus dev/smbus \ + dev/speaker dev/utopia dev/vkbd dev/wi \ + fs/devfs fs/fdescfs fs/msdosfs fs/nandfs fs/nfs fs/nullfs \ + fs/procfs fs/smbfs fs/udf fs/unionfs \ + geom/cache geom/concat geom/eli geom/gate geom/journal geom/label \ + geom/mirror geom/mountver geom/multipath geom/nop \ + geom/raid geom/raid3 geom/shsec geom/stripe geom/virstor \ + net/altq \ + netgraph/atm netgraph/netflow \ + netinet/cc \ + security/audit \ + security/mac_biba security/mac_bsdextended security/mac_lomac \ + security/mac_mls security/mac_partition \ + ufs/ffs ufs/ufs + +LSUBSUBDIRS= dev/mpt/mpilib + +.if ${MK_BLUETOOTH} != "no" +LSUBSUBDIRS+= netgraph/bluetooth/include +.endif + +.if ${MK_CUSE} != "no" +LSUBDIRS+= fs/cuse +.endif + +.if ${MK_GSSAPI} != "no" +SUBDIR+= gssapi +INCS+= gssapi.h +.endif + +.if ${MK_HESIOD} != "no" +INCS+= hesiod.h +.endif + +# Handle the #define aliases for libiconv +.if ${MK_ICONV} == "yes" +INCS+= iconv.h +.endif + +.if ${MK_USB} != "no" +LSUBDIRS+= dev/usb +.endif + +.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64" +_dev_powermac_nvram= dev/powermac_nvram +.endif + +# Define SHARED to indicate whether you want symbolic links to the system +# source (``symlinks''), or a separate copy (``copies''). ``symlinks'' is +# probably only useful for developers and should be avoided if you do not +# wish to tie your /usr/include and /usr/src together. +#SHARED= symlinks +SHARED?= copies + +INCS+= osreldate.h + +SYSDIR= ${.CURDIR}/../sys +NEWVERS_SH= ${SYSDIR}/conf/newvers.sh +PARAM_H= ${SYSDIR}/sys/param.h +MK_OSRELDATE_SH= ${.CURDIR}/mk-osreldate.sh + +SYMLINKS+= ${INCLUDEDIR} ${LIBDIR}/include + +osreldate.h: ${NEWVERS_SH} ${PARAM_H} ${MK_OSRELDATE_SH} + env NEWVERS_SH=${NEWVERS_SH} PARAMFILE=${PARAM_H} SYSDIR=${SYSDIR} \ + sh ${MK_OSRELDATE_SH} + +.for i in ${LHDRS} +INCSLINKS+= sys/$i ${INCLUDEDIR}/$i +.endfor +.for i in ${MHDRS} +INCSLINKS+= machine/$i ${INCLUDEDIR}/$i +.endfor +.for i in ${PHDRS} +INCSLINKS+= sys/$i ${INCLUDEDIR}/$i +.endfor + +.if ${MACHINE} != ${MACHINE_CPUARCH} +_MARCHS= ${MACHINE_CPUARCH} +.endif +.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" +_MARCHS+= x86 +.endif + +META_TARGETS+= compat +stage_includes: ${SHARED} + +# Take care of stale directory-level symlinks. +compat: +.for i in ${LDIRS} ${LSUBDIRS} machine ${_MARCHS} crypto + if [ -L ${DESTDIR}${INCLUDEDIR}/$i ]; then \ + rm -f ${DESTDIR}${INCLUDEDIR}/$i; \ + fi +.endfor + mtree -deU ${MTREE_FOLLOWS_SYMLINKS} \ + -f ${.CURDIR}/../etc/mtree/BSD.include.dist \ + -p ${DESTDIR}${INCLUDEDIR} > /dev/null + +copies: .PHONY .META +.for i in ${LDIRS} ${LSUBDIRS} ${LSUBSUBDIRS} crypto machine machine/pc \ + ${_MARCHS} + if [ -d ${DESTDIR}${INCLUDEDIR}/$i ]; then \ + cd ${DESTDIR}${INCLUDEDIR}/$i; \ + for h in *.h; do \ + if [ -L $$h ]; then rm -f $$h; fi; \ + done; \ + fi +.endfor +.for i in ${LDIRS} ${LSUBDIRS:Ndev/agp:Ndev/acpica:Ndev/bktr:Ndev/evdev:Ndev/hyperv:Ndev/nand:Ndev/pci} ${LSUBSUBDIRS} + cd ${.CURDIR}/../sys; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 $i/*.h \ + ${DESTDIR}${INCLUDEDIR}/$i +.endfor + cd ${.CURDIR}/../sys/dev/acpica; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 acpiio.h \ + ${DESTDIR}${INCLUDEDIR}/dev/acpica; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 acpi_hpet.h \ + ${DESTDIR}${INCLUDEDIR}/dev/acpica + cd ${.CURDIR}/../sys/dev/agp; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 agpreg.h \ + ${DESTDIR}${INCLUDEDIR}/dev/agp + cd ${.CURDIR}/../sys/dev/bktr; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 ioctl_*.h \ + ${DESTDIR}${INCLUDEDIR}/dev/bktr +.if ${MK_NAND} != "no" + cd ${.CURDIR}/../sys/dev/nand; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 nandsim.h \ + ${DESTDIR}${INCLUDEDIR}/dev/nand; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 nand_dev.h \ + ${DESTDIR}${INCLUDEDIR}/dev/nand +.endif + cd ${.CURDIR}/../sys/dev/evdev; \ + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 input.h \ + ${DESTDIR}${INCLUDEDIR}/dev/evdev; \ + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 input-event-codes.h \ + ${DESTDIR}${INCLUDEDIR}/dev/evdev; \ + ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 uinput.h \ + ${DESTDIR}${INCLUDEDIR}/dev/evdev + cd ${.CURDIR}/../sys/dev/hyperv/include; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 hyperv.h \ + ${DESTDIR}${INCLUDEDIR}/dev/hyperv + cd ${.CURDIR}/../sys/dev/hyperv/utilities; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 hv_snapshot.h \ + ${DESTDIR}${INCLUDEDIR}/dev/hyperv + cd ${.CURDIR}/../sys/dev/pci; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 pcireg.h \ + ${DESTDIR}${INCLUDEDIR}/dev/pci + cd ${.CURDIR}/../sys/fs/cd9660/; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ + ${DESTDIR}${INCLUDEDIR}/isofs/cd9660 +.if ${MK_IPFILTER} != "no" + cd ${.CURDIR}/../sys/contrib/ipfilter/netinet; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ + ${DESTDIR}${INCLUDEDIR}/netinet +.endif +.if ${MK_PF} != "no" + cd ${.CURDIR}/../sys/netpfil/pf; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ + ${DESTDIR}${INCLUDEDIR}/netpfil/pf +.endif + cd ${.CURDIR}/../sys/crypto; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 rijndael/rijndael.h \ + ${DESTDIR}${INCLUDEDIR}/crypto + cd ${.CURDIR}/../sys/opencrypto; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ + ${DESTDIR}${INCLUDEDIR}/crypto + cd ${.CURDIR}/../sys/${MACHINE}/include; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ + ${DESTDIR}${INCLUDEDIR}/machine +.if exists(${.CURDIR}/../sys/${MACHINE}/include/pc) + cd ${.CURDIR}/../sys/${MACHINE}/include/pc; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ + ${DESTDIR}${INCLUDEDIR}/machine/pc +.endif +.for _MARCH in ${_MARCHS} +.if exists(${.CURDIR}/../sys/${_MARCH}/include) + ${INSTALL} -d ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 755 \ + ${DESTDIR}${INCLUDEDIR}/${_MARCH}; \ + cd ${.CURDIR}/../sys/${_MARCH}/include; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ + ${DESTDIR}${INCLUDEDIR}/${_MARCH} +.if exists(${.CURDIR}/../sys/${_MARCH}/include/pc) + ${INSTALL} -d ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 755 \ + ${DESTDIR}${INCLUDEDIR}/${_MARCH}/pc; \ + cd ${.CURDIR}/../sys/${_MARCH}/include/pc; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ + ${DESTDIR}${INCLUDEDIR}/${_MARCH}/pc +.endif +.endif +.endfor + cd ${.CURDIR}/../sys/rpc; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 types.h \ + ${DESTDIR}${INCLUDEDIR}/rpc + cd ${.CURDIR}/../sys/teken; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 teken.h \ + ${DESTDIR}${INCLUDEDIR}/teken +.if ${MK_CDDL} != "no" + cd ${.CURDIR}/../cddl/contrib/opensolaris/lib/libzfs_core/common; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 libzfs_core.h \ + ${DESTDIR}${INCLUDEDIR} + cd ${.CURDIR}/../cddl/contrib/opensolaris/lib/libnvpair; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 libnvpair.h \ + ${DESTDIR}${INCLUDEDIR} + cd ${.CURDIR}/../sys/cddl/contrib/opensolaris/uts/common/sys; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 nvpair.h \ + ${DESTDIR}${INCLUDEDIR}/sys +.endif + +symlinks: .PHONY .META + @${ECHO} "Setting up symlinks to kernel source tree..." +.for i in ${LDIRS} + cd ${.CURDIR}/../sys/$i; \ + for h in *.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/$i/$$h ${DESTDIR}${INCLUDEDIR}/$i; \ + done +.endfor +.for i in ${LSUBDIRS:Ndev/agp:Ndev/acpica:Ndev/bktr:Ndev/evdev:Ndev/hyperv:Ndev/nand:Ndev/pci} + cd ${.CURDIR}/../sys/$i; \ + for h in *.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/$i/$$h ${DESTDIR}${INCLUDEDIR}/$i; \ + done +.endfor + cd ${.CURDIR}/../sys/dev/acpica; \ + for h in acpiio.h acpi_hpet.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/acpica/$$h \ + ${DESTDIR}${INCLUDEDIR}/dev/acpica; \ + done + cd ${.CURDIR}/../sys/dev/agp; \ + for h in agpreg.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/agp/$$h \ + ${DESTDIR}${INCLUDEDIR}/dev/agp; \ + done + cd ${.CURDIR}/../sys/dev/bktr; \ + for h in ioctl_*.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/bktr/$$h \ + ${DESTDIR}${INCLUDEDIR}/dev/bktr; \ + done +.if ${MK_NAND} != "no" + cd ${.CURDIR}/../sys/dev/nand; \ + for h in nandsim.h nand_dev.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/nand/$$h \ + ${DESTDIR}${INCLUDEDIR}/dev/nand; \ + done +.endif + cd ${.CURDIR}/../sys/dev/evdev; \ + for h in input.h input-event-codes.h uinput.h; do \ + ln -fs ../../../../sys/dev/evdev/$$h \ + ${DESTDIR}${INCLUDEDIR}/dev/evdev; \ + done + cd ${.CURDIR}/../sys/dev/hyperv/include; \ + for h in hyperv.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/hyperv/include/$$h \ + ${DESTDIR}${INCLUDEDIR}/dev/hyperv; \ + done + cd ${.CURDIR}/../sys/dev/hyperv/utilities; \ + for h in hv_snapshot.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/hyperv/utilities/$$h \ + ${DESTDIR}${INCLUDEDIR}/dev/hyperv; \ + done + cd ${.CURDIR}/../sys/dev/pci; \ + for h in pcireg.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/pci/$$h \ + ${DESTDIR}${INCLUDEDIR}/dev/pci; \ + done +.for i in ${LSUBSUBDIRS} + cd ${.CURDIR}/../sys/$i; \ + for h in *.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../../sys/$i/$$h ${DESTDIR}${INCLUDEDIR}/$i; \ + done +.endfor +.if ${MK_IPFILTER} != "no" + cd ${.CURDIR}/../sys/contrib/ipfilter/netinet; \ + for h in *.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/contrib/ipfilter/netinet/$$h \ + ${DESTDIR}${INCLUDEDIR}/netinet; \ + done +.endif +.if ${MK_PF} != "no" + cd ${.CURDIR}/../sys/netpfil/pf; \ + for h in *.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/netpfil/pf/$$h \ + ${DESTDIR}${INCLUDEDIR}/netpfil/pf; \ + done +.endif + cd ${.CURDIR}/../sys/crypto; \ + for h in rijndael/rijndael.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/crypto/$$h \ + ${DESTDIR}${INCLUDEDIR}/crypto; \ + done + cd ${.CURDIR}/../sys/opencrypto; \ + for h in *.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/opencrypto/$$h \ + ${DESTDIR}${INCLUDEDIR}/crypto; \ + done + cd ${.CURDIR}/../sys/${MACHINE}/include; \ + for h in *.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/${MACHINE}/include/$$h \ + ${DESTDIR}${INCLUDEDIR}/machine; \ + done +.if exists(${.CURDIR}/../sys/${MACHINE}/include/pc) + cd ${.CURDIR}/../sys/${MACHINE}/include/pc; \ + for h in *.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/${MACHINE}/include/pc/$$h \ + ${DESTDIR}${INCLUDEDIR}/machine/pc; \ + done +.endif +.for _MARCH in ${_MARCHS} +.if exists(${.CURDIR}/../sys/${_MARCH}/include) + ${INSTALL} -d ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 755 \ + ${DESTDIR}${INCLUDEDIR}/${_MARCH}; \ + cd ${.CURDIR}/../sys/${_MARCH}/include; \ + for h in *.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/${_MARCH}/include/$$h \ + ${DESTDIR}${INCLUDEDIR}/${_MARCH}; \ + done +.if exists(${.CURDIR}/../sys/${_MARCH}/include/pc) + ${INSTALL} -d ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 755 \ + ${DESTDIR}${INCLUDEDIR}/${_MARCH}/pc; \ + cd ${.CURDIR}/../sys/${_MARCH}/include/pc; \ + for h in *.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/${_MARCH}/include/pc/$$h \ + ${DESTDIR}${INCLUDEDIR}/${_MARCH}/pc; \ + done +.endif +.endif +.endfor + cd ${.CURDIR}/../sys/fs/cd9660; \ + for h in *.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/fs/cd9660/$$h \ + ${DESTDIR}${INCLUDEDIR}/isofs/cd9660; \ + done + cd ${.CURDIR}/../sys/rpc; \ + for h in types.h; do \ + ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/rpc/$$h \ + ${DESTDIR}${INCLUDEDIR}/rpc; \ + done + +.include + +installincludes: ${SHARED} +${SHARED}: compat + +.if ${MACHINE} == "host" && !defined(_SKIP_BUILD) +# we're here because we are building a sysroot... +# we need MACHINE et al set correctly +HOST_MACHINE!= uname -m +HOST_MACHINE_ARCH!= uname -p +MACHINE:= ${HOST_MACHINE} +MACHINE_ARCH:= ${HOST_MACHINE_ARCH} +.endif diff --git a/include/Makefile.depend b/include/Makefile.depend new file mode 100644 index 0000000..c7231d1 --- /dev/null +++ b/include/Makefile.depend @@ -0,0 +1,12 @@ +# $FreeBSD: releng/11.1/include/Makefile.depend 284481 2015-06-16 23:37:19Z sjg $ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + usr.bin/xinstall.host \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/include/_ctype.h b/include/_ctype.h new file mode 100644 index 0000000..465ac7c --- /dev/null +++ b/include/_ctype.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (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. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * 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. + * + * From @(#)ctype.h 8.4 (Berkeley) 1/21/94 + * From FreeBSD: src/include/ctype.h,v 1.27 2004/06/23 07:11:39 tjr Exp + * $FreeBSD: releng/11.1/include/_ctype.h 290494 2015-11-07 12:43:35Z bapt $ + */ + +#ifndef __CTYPE_H_ +#define __CTYPE_H_ + +#include +#include + +#define _CTYPE_A 0x00000100L /* Alpha */ +#define _CTYPE_C 0x00000200L /* Control */ +#define _CTYPE_D 0x00000400L /* Digit */ +#define _CTYPE_G 0x00000800L /* Graph */ +#define _CTYPE_L 0x00001000L /* Lower */ +#define _CTYPE_P 0x00002000L /* Punct */ +#define _CTYPE_S 0x00004000L /* Space */ +#define _CTYPE_U 0x00008000L /* Upper */ +#define _CTYPE_X 0x00010000L /* X digit */ +#define _CTYPE_B 0x00020000L /* Blank */ +#define _CTYPE_R 0x00040000L /* Print */ +#define _CTYPE_I 0x00080000L /* Ideogram */ +#define _CTYPE_T 0x00100000L /* Special */ +#define _CTYPE_Q 0x00200000L /* Phonogram */ +#define _CTYPE_N 0x00400000L /* Number (superset of digit) */ +#define _CTYPE_SW0 0x20000000L /* 0 width character */ +#define _CTYPE_SW1 0x40000000L /* 1 width character */ +#define _CTYPE_SW2 0x80000000L /* 2 width character */ +#define _CTYPE_SW3 0xc0000000L /* 3 width character */ +#define _CTYPE_SWM 0xe0000000L /* Mask for screen width data */ +#define _CTYPE_SWS 30 /* Bits to shift to get width */ + +/* See comments in about __ct_rune_t. */ +__BEGIN_DECLS +unsigned long ___runetype(__ct_rune_t) __pure; +__ct_rune_t ___tolower(__ct_rune_t) __pure; +__ct_rune_t ___toupper(__ct_rune_t) __pure; +__END_DECLS + +/* + * _EXTERNALIZE_CTYPE_INLINES_ is defined in locale/nomacros.c to tell us + * to generate code for extern versions of all our inline functions. + */ +#ifdef _EXTERNALIZE_CTYPE_INLINES_ +#define _USE_CTYPE_INLINE_ +#define static +#define __inline +#endif + +extern int __mb_sb_limit; + +/* + * Use inline functions if we are allowed to and the compiler supports them. + */ +#if !defined(_DONT_USE_CTYPE_INLINE_) && \ + (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus)) + +#include + +static __inline int +__maskrune(__ct_rune_t _c, unsigned long _f) +{ + return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype(_c) : + _CurrentRuneLocale->__runetype[_c]) & _f; +} + +static __inline int +__sbmaskrune(__ct_rune_t _c, unsigned long _f) +{ + return (_c < 0 || _c >= __mb_sb_limit) ? 0 : + _CurrentRuneLocale->__runetype[_c] & _f; +} + +static __inline int +__istype(__ct_rune_t _c, unsigned long _f) +{ + return (!!__maskrune(_c, _f)); +} + +static __inline int +__sbistype(__ct_rune_t _c, unsigned long _f) +{ + return (!!__sbmaskrune(_c, _f)); +} + +static __inline int +__isctype(__ct_rune_t _c, unsigned long _f) +{ + return (_c < 0 || _c >= 128) ? 0 : + !!(_DefaultRuneLocale.__runetype[_c] & _f); +} + +static __inline __ct_rune_t +__toupper(__ct_rune_t _c) +{ + return (_c < 0 || _c >= _CACHED_RUNES) ? ___toupper(_c) : + _CurrentRuneLocale->__mapupper[_c]; +} + +static __inline __ct_rune_t +__sbtoupper(__ct_rune_t _c) +{ + return (_c < 0 || _c >= __mb_sb_limit) ? _c : + _CurrentRuneLocale->__mapupper[_c]; +} + +static __inline __ct_rune_t +__tolower(__ct_rune_t _c) +{ + return (_c < 0 || _c >= _CACHED_RUNES) ? ___tolower(_c) : + _CurrentRuneLocale->__maplower[_c]; +} + +static __inline __ct_rune_t +__sbtolower(__ct_rune_t _c) +{ + return (_c < 0 || _c >= __mb_sb_limit) ? _c : + _CurrentRuneLocale->__maplower[_c]; +} + +static __inline int +__wcwidth(__ct_rune_t _c) +{ + unsigned int _x; + + if (_c == 0) + return (0); + _x = (unsigned int)__maskrune(_c, _CTYPE_SWM|_CTYPE_R); + if ((_x & _CTYPE_SWM) != 0) + return ((_x & _CTYPE_SWM) >> _CTYPE_SWS); + return ((_x & _CTYPE_R) != 0 ? 1 : -1); +} + +#else /* not using inlines */ + +__BEGIN_DECLS +int __maskrune(__ct_rune_t, unsigned long); +int __sbmaskrune(__ct_rune_t, unsigned long); +int __istype(__ct_rune_t, unsigned long); +int __sbistype(__ct_rune_t, unsigned long); +int __isctype(__ct_rune_t, unsigned long); +__ct_rune_t __toupper(__ct_rune_t); +__ct_rune_t __sbtoupper(__ct_rune_t); +__ct_rune_t __tolower(__ct_rune_t); +__ct_rune_t __sbtolower(__ct_rune_t); +int __wcwidth(__ct_rune_t); +__END_DECLS +#endif /* using inlines */ + +#endif /* !__CTYPE_H_ */ diff --git a/include/a.out.h b/include/a.out.h new file mode 100644 index 0000000..f0095ab --- /dev/null +++ b/include/a.out.h @@ -0,0 +1,45 @@ +/*- + * 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. + * + * @(#)a.out.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: releng/11.1/include/a.out.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _AOUT_H_ +#define _AOUT_H_ + +#include +#include +#include +#include +#include + +#define _AOUT_INCLUDE_ +#include + +#endif /* !_AOUT_H_ */ diff --git a/include/ar.h b/include/ar.h new file mode 100644 index 0000000..721a05f --- /dev/null +++ b/include/ar.h @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (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. + * + * This code is derived from software contributed to Berkeley by + * Hugh Smith at The University of Guelph. + * + * 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. + * + * @(#)ar.h 8.2 (Berkeley) 1/21/94 + * + * $FreeBSD: releng/11.1/include/ar.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _AR_H_ +#define _AR_H_ + +#include + +/* Pre-4BSD archives had these magic numbers in them. */ +#define OARMAG1 0177555 +#define OARMAG2 0177545 + +#define ARMAG "!\n" /* ar "magic number" */ +#define SARMAG 8 /* strlen(ARMAG); */ + +#define AR_EFMT1 "#1/" /* extended format #1 */ + +struct ar_hdr { + char ar_name[16]; /* name */ + char ar_date[12]; /* modification time */ + char ar_uid[6]; /* user id */ + char ar_gid[6]; /* group id */ + char ar_mode[8]; /* octal file permissions */ + char ar_size[10]; /* size in bytes */ +#define ARFMAG "`\n" + char ar_fmag[2]; /* consistency check */ +} __packed; + +#endif /* !_AR_H_ */ diff --git a/include/arpa/Makefile b/include/arpa/Makefile new file mode 100644 index 0000000..ddfd040 --- /dev/null +++ b/include/arpa/Makefile @@ -0,0 +1,9 @@ +# $FreeBSD: releng/11.1/include/arpa/Makefile 284345 2015-06-13 19:20:56Z sjg $ + +.include + +INCS= ftp.h inet.h nameser.h nameser_compat.h tftp.h +INCS+= telnet.h +INCSDIR=${INCLUDEDIR}/arpa + +.include diff --git a/include/arpa/Makefile.depend b/include/arpa/Makefile.depend new file mode 100644 index 0000000..60c0897 --- /dev/null +++ b/include/arpa/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD: releng/11.1/include/arpa/Makefile.depend 284345 2015-06-13 19:20:56Z sjg $ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/include/arpa/ftp.h b/include/arpa/ftp.h new file mode 100644 index 0000000..3573d3f --- /dev/null +++ b/include/arpa/ftp.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1983, 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. + * + * @(#)ftp.h 8.1 (Berkeley) 6/2/93 + * + * $FreeBSD: releng/11.1/include/arpa/ftp.h 203965 2010-02-16 19:46:46Z imp $ + */ + +#ifndef _ARPA_FTP_H_ +#define _ARPA_FTP_H_ + +/* Definitions for FTP; see RFC-765. */ + +/* + * Reply codes. + */ +#define PRELIM 1 /* positive preliminary */ +#define COMPLETE 2 /* positive completion */ +#define CONTINUE 3 /* positive intermediate */ +#define TRANSIENT 4 /* transient negative completion */ +#define ERROR 5 /* permanent negative completion */ + +/* + * Type codes + */ +#define TYPE_A 1 /* ASCII */ +#define TYPE_E 2 /* EBCDIC */ +#define TYPE_I 3 /* image */ +#define TYPE_L 4 /* local byte size */ + +#ifdef FTP_NAMES +char *typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local" }; +#endif + +/* + * Form codes + */ +#define FORM_N 1 /* non-print */ +#define FORM_T 2 /* telnet format effectors */ +#define FORM_C 3 /* carriage control (ASA) */ +#ifdef FTP_NAMES +char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" }; +#endif + +/* + * Structure codes + */ +#define STRU_F 1 /* file (no record structure) */ +#define STRU_R 2 /* record structure */ +#define STRU_P 3 /* page structure */ +#ifdef FTP_NAMES +char *strunames[] = {"0", "File", "Record", "Page" }; +#endif + +/* + * Mode types + */ +#define MODE_S 1 /* stream */ +#define MODE_B 2 /* block */ +#define MODE_C 3 /* compressed */ +#ifdef FTP_NAMES +char *modenames[] = {"0", "Stream", "Block", "Compressed" }; +#endif + +/* + * Record Tokens + */ +#define REC_ESC '\377' /* Record-mode Escape */ +#define REC_EOR '\001' /* Record-mode End-of-Record */ +#define REC_EOF '\002' /* Record-mode End-of-File */ + +/* + * Block Header + */ +#define BLK_EOR 0x80 /* Block is End-of-Record */ +#define BLK_EOF 0x40 /* Block is End-of-File */ +#define BLK_ERRORS 0x20 /* Block is suspected of containing errors */ +#define BLK_RESTART 0x10 /* Block is Restart Marker */ + +#define BLK_BYTECOUNT 2 /* Bytes in this block */ + +#endif /* !_FTP_H_ */ diff --git a/include/arpa/inet.h b/include/arpa/inet.h new file mode 100644 index 0000000..3e32ef9 --- /dev/null +++ b/include/arpa/inet.h @@ -0,0 +1,178 @@ +/* + * ++Copyright++ 1983, 1993 + * - + * Copyright (c) 1983, 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. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * 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, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION 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. + * - + * --Copyright-- + */ + +/*% + * @(#)inet.h 8.1 (Berkeley) 6/2/93 + * $Id: inet.h,v 1.3 2005/04/27 04:56:16 sra Exp $ + * $FreeBSD: releng/11.1/include/arpa/inet.h 269867 2014-08-12 12:36:06Z ume $ + */ + +#ifndef _ARPA_INET_H_ +#define _ARPA_INET_H_ + +/* External definitions for functions in inet(3). */ + +#include +#include + +/* Required for byteorder(3) functions. */ +#include + +#define INET_ADDRSTRLEN 16 +#define INET6_ADDRSTRLEN 46 + +#ifndef _UINT16_T_DECLARED +typedef __uint16_t uint16_t; +#define _UINT16_T_DECLARED +#endif + +#ifndef _UINT32_T_DECLARED +typedef __uint32_t uint32_t; +#define _UINT32_T_DECLARED +#endif + +#ifndef _IN_ADDR_T_DECLARED +typedef uint32_t in_addr_t; +#define _IN_ADDR_T_DECLARED +#endif + +#ifndef _IN_PORT_T_DECLARED +typedef uint16_t in_port_t; +#define _IN_PORT_T_DECLARED +#endif + +#if __BSD_VISIBLE +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif +#endif + +/* + * XXX socklen_t is used by a POSIX.1-2001 interface, but not required by + * POSIX.1-2001. + */ +#ifndef _SOCKLEN_T_DECLARED +typedef __socklen_t socklen_t; +#define _SOCKLEN_T_DECLARED +#endif + +#ifndef _STRUCT_IN_ADDR_DECLARED +struct in_addr { + in_addr_t s_addr; +}; +#define _STRUCT_IN_ADDR_DECLARED +#endif + +/* XXX all new diversions!! argh!! */ +#if __BSD_VISIBLE +#define inet_addr __inet_addr +#define inet_aton __inet_aton +#define inet_lnaof __inet_lnaof +#define inet_makeaddr __inet_makeaddr +#define inet_neta __inet_neta +#define inet_netof __inet_netof +#define inet_network __inet_network +#define inet_net_ntop __inet_net_ntop +#define inet_net_pton __inet_net_pton +#define inet_cidr_ntop __inet_cidr_ntop +#define inet_cidr_pton __inet_cidr_pton +#define inet_ntoa __inet_ntoa +#define inet_ntoa_r __inet_ntoa_r +#define inet_pton __inet_pton +#define inet_ntop __inet_ntop +#define inet_nsap_addr __inet_nsap_addr +#define inet_nsap_ntoa __inet_nsap_ntoa +#endif /* __BSD_VISIBLE */ + +__BEGIN_DECLS +#ifndef _BYTEORDER_PROTOTYPED +#define _BYTEORDER_PROTOTYPED +uint32_t htonl(uint32_t); +uint16_t htons(uint16_t); +uint32_t ntohl(uint32_t); +uint16_t ntohs(uint16_t); +#endif + +in_addr_t inet_addr(const char *); +/*const*/ char *inet_ntoa(struct in_addr); +const char *inet_ntop(int, const void * __restrict, char * __restrict, + socklen_t); +int inet_pton(int, const char * __restrict, void * __restrict); + +#if __BSD_VISIBLE +int inet_aton(const char *, struct in_addr *); +in_addr_t inet_lnaof(struct in_addr); +struct in_addr inet_makeaddr(in_addr_t, in_addr_t); +char * inet_neta(in_addr_t, char *, size_t); +in_addr_t inet_netof(struct in_addr); +in_addr_t inet_network(const char *); +char *inet_net_ntop(int, const void *, int, char *, size_t); +int inet_net_pton(int, const char *, void *, size_t); +char *inet_ntoa_r(struct in_addr, char *buf, socklen_t size); +char *inet_cidr_ntop(int, const void *, int, char *, size_t); +int inet_cidr_pton(int, const char *, void *, int *); +unsigned inet_nsap_addr(const char *, unsigned char *, int); +char *inet_nsap_ntoa(int, const unsigned char *, char *); +#endif /* __BSD_VISIBLE */ +__END_DECLS + +#ifndef _BYTEORDER_FUNC_DEFINED +#define _BYTEORDER_FUNC_DEFINED +#define htonl(x) __htonl(x) +#define htons(x) __htons(x) +#define ntohl(x) __ntohl(x) +#define ntohs(x) __ntohs(x) +#endif + +#endif /* !_ARPA_INET_H_ */ + +/*! \file */ diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h new file mode 100644 index 0000000..e035677 --- /dev/null +++ b/include/arpa/nameser.h @@ -0,0 +1,680 @@ +/* + * Portions Copyright (C) 2004, 2005, 2008, 2009 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1996-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC 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. + */ + +/* + * Copyright (c) 1983, 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. + */ + +/* + * $Id: nameser.h,v 1.16 2009/03/03 01:52:48 each Exp $ + * $FreeBSD: releng/11.1/include/arpa/nameser.h 298849 2016-04-30 14:43:42Z pfg $ + */ + +#ifndef _ARPA_NAMESER_H_ +#define _ARPA_NAMESER_H_ + +/*! \file */ + +#define BIND_4_COMPAT + +#include +#include +#include + +/*% + * Revision information. This is the release date in YYYYMMDD format. + * It can change every day so the right thing to do with it is use it + * in preprocessor commands such as "#if (__NAMESER > 19931104)". Do not + * compare for equality; rather, use it to determine whether your libbind.a + * contains a new enough lib/nameser/ to support the feature you need. + */ + +#define __NAMESER 20090302 /*%< New interface version stamp. */ +/* + * Define constants based on RFC0883, RFC1034, RFC 1035 + */ +#define NS_PACKETSZ 512 /*%< default UDP packet size */ +#define NS_MAXDNAME 1025 /*%< maximum domain name (presentation format)*/ +#define NS_MAXMSG 65535 /*%< maximum message size */ +#define NS_MAXCDNAME 255 /*%< maximum compressed domain name */ +#define NS_MAXLABEL 63 /*%< maximum length of domain label */ +#define NS_MAXLABELS 128 /*%< theoretical max #/labels per domain name */ +#define NS_MAXNNAME 256 /*%< maximum uncompressed (binary) domain name*/ +#define NS_MAXPADDR (sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff") +#define NS_HFIXEDSZ 12 /*%< #/bytes of fixed data in header */ +#define NS_QFIXEDSZ 4 /*%< #/bytes of fixed data in query */ +#define NS_RRFIXEDSZ 10 /*%< #/bytes of fixed data in r record */ +#define NS_INT32SZ 4 /*%< #/bytes of data in a u_int32_t */ +#define NS_INT16SZ 2 /*%< #/bytes of data in a u_int16_t */ +#define NS_INT8SZ 1 /*%< #/bytes of data in a u_int8_t */ +#define NS_INADDRSZ 4 /*%< IPv4 T_A */ +#define NS_IN6ADDRSZ 16 /*%< IPv6 T_AAAA */ +#define NS_CMPRSFLGS 0xc0 /*%< Flag bits indicating name compression. */ +#define NS_DEFAULTPORT 53 /*%< For both TCP and UDP. */ +/* + * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord() + * in synch with it. + */ +typedef enum __ns_sect { + ns_s_qd = 0, /*%< Query: Question. */ + ns_s_zn = 0, /*%< Update: Zone. */ + ns_s_an = 1, /*%< Query: Answer. */ + ns_s_pr = 1, /*%< Update: Prerequisites. */ + ns_s_ns = 2, /*%< Query: Name servers. */ + ns_s_ud = 2, /*%< Update: Update. */ + ns_s_ar = 3, /*%< Query|Update: Additional records. */ + ns_s_max = 4 +} ns_sect; + +/*% + * Network name (compressed or not) type. Equivalent to a pointer when used + * in a function prototype. Can be const'd. + */ +typedef u_char ns_nname[NS_MAXNNAME]; +typedef const u_char *ns_nname_ct; +typedef u_char *ns_nname_t; + +struct ns_namemap { ns_nname_ct base; int len; }; +typedef struct ns_namemap *ns_namemap_t; +typedef const struct ns_namemap *ns_namemap_ct; + +/*% + * This is a message handle. It is caller allocated and has no dynamic data. + * This structure is intended to be opaque to all but ns_parse.c, thus the + * leading _'s on the member names. Use the accessor functions, not the _'s. + */ +typedef struct __ns_msg { + const u_char *_msg, *_eom; + u_int16_t _id, _flags, _counts[ns_s_max]; + const u_char *_sections[ns_s_max]; + ns_sect _sect; + int _rrnum; + const u_char *_msg_ptr; +} ns_msg; + +/* + * This is a newmsg handle, used when constructing new messages with + * ns_newmsg_init, et al. + */ +struct ns_newmsg { + ns_msg msg; + const u_char *dnptrs[25]; + const u_char **lastdnptr; +}; +typedef struct ns_newmsg ns_newmsg; + +/* Private data structure - do not use from outside library. */ +struct _ns_flagdata { int mask, shift; }; +extern struct _ns_flagdata _ns_flagdata[]; + +/* Accessor macros - this is part of the public interface. */ + +#define ns_msg_id(handle) ((handle)._id + 0) +#define ns_msg_base(handle) ((handle)._msg + 0) +#define ns_msg_end(handle) ((handle)._eom + 0) +#define ns_msg_size(handle) ((handle)._eom - (handle)._msg) +#define ns_msg_count(handle, section) ((handle)._counts[section] + 0) + +/*% + * This is a parsed record. It is caller allocated and has no dynamic data. + */ +typedef struct __ns_rr { + char name[NS_MAXDNAME]; + u_int16_t type; + u_int16_t rr_class; + u_int32_t ttl; + u_int16_t rdlength; + const u_char * rdata; +} ns_rr; + +/* + * Same thing, but using uncompressed network binary names, and real C types. + */ +typedef struct __ns_rr2 { + ns_nname nname; + size_t nnamel; + int type; + int rr_class; + u_int ttl; + int rdlength; + const u_char * rdata; +} ns_rr2; + +/* Accessor macros - this is part of the public interface. */ +#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".") +#define ns_rr_nname(rr) ((const ns_nname_t)(rr).nname) +#define ns_rr_nnamel(rr) ((rr).nnamel + 0) +#define ns_rr_type(rr) ((ns_type)((rr).type + 0)) +#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0)) +#define ns_rr_ttl(rr) ((rr).ttl + 0) +#define ns_rr_rdlen(rr) ((rr).rdlength + 0) +#define ns_rr_rdata(rr) ((rr).rdata + 0) + +/*% + * These don't have to be in the same order as in the packet flags word, + * and they can even overlap in some cases, but they will need to be kept + * in synch with ns_parse.c:ns_flagdata[]. + */ +typedef enum __ns_flag { + ns_f_qr, /*%< Question/Response. */ + ns_f_opcode, /*%< Operation code. */ + ns_f_aa, /*%< Authoritative Answer. */ + ns_f_tc, /*%< Truncation occurred. */ + ns_f_rd, /*%< Recursion Desired. */ + ns_f_ra, /*%< Recursion Available. */ + ns_f_z, /*%< MBZ. */ + ns_f_ad, /*%< Authentic Data (DNSSEC). */ + ns_f_cd, /*%< Checking Disabled (DNSSEC). */ + ns_f_rcode, /*%< Response code. */ + ns_f_max +} ns_flag; + +/*% + * Currently defined opcodes. + */ +typedef enum __ns_opcode { + ns_o_query = 0, /*%< Standard query. */ + ns_o_iquery = 1, /*%< Inverse query (deprecated/unsupported). */ + ns_o_status = 2, /*%< Name server status query (unsupported). */ + /* Opcode 3 is undefined/reserved. */ + ns_o_notify = 4, /*%< Zone change notification. */ + ns_o_update = 5, /*%< Zone update message. */ + ns_o_max = 6 +} ns_opcode; + +/*% + * Currently defined response codes. + */ +typedef enum __ns_rcode { + ns_r_noerror = 0, /*%< No error occurred. */ + ns_r_formerr = 1, /*%< Format error. */ + ns_r_servfail = 2, /*%< Server failure. */ + ns_r_nxdomain = 3, /*%< Name error. */ + ns_r_notimpl = 4, /*%< Unimplemented. */ + ns_r_refused = 5, /*%< Operation refused. */ + /* these are for BIND_UPDATE */ + ns_r_yxdomain = 6, /*%< Name exists */ + ns_r_yxrrset = 7, /*%< RRset exists */ + ns_r_nxrrset = 8, /*%< RRset does not exist */ + ns_r_notauth = 9, /*%< Not authoritative for zone */ + ns_r_notzone = 10, /*%< Zone of record different from zone section */ + ns_r_max = 11, + /* The following are EDNS extended rcodes */ + ns_r_badvers = 16, + /* The following are TSIG errors */ + ns_r_badsig = 16, + ns_r_badkey = 17, + ns_r_badtime = 18 +} ns_rcode; + +/* BIND_UPDATE */ +typedef enum __ns_update_operation { + ns_uop_delete = 0, + ns_uop_add = 1, + ns_uop_max = 2 +} ns_update_operation; + +/*% + * This structure is used for TSIG authenticated messages + */ +struct ns_tsig_key { + char name[NS_MAXDNAME], alg[NS_MAXDNAME]; + unsigned char *data; + int len; +}; +typedef struct ns_tsig_key ns_tsig_key; + +/*% + * This structure is used for TSIG authenticated TCP messages + */ +struct ns_tcp_tsig_state { + int counter; + struct dst_key *key; + void *ctx; + unsigned char sig[NS_PACKETSZ]; + int siglen; +}; +typedef struct ns_tcp_tsig_state ns_tcp_tsig_state; + +#define NS_TSIG_FUDGE 300 +#define NS_TSIG_TCP_COUNT 100 +#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT" + +#define NS_TSIG_ERROR_NO_TSIG -10 +#define NS_TSIG_ERROR_NO_SPACE -11 +#define NS_TSIG_ERROR_FORMERR -12 + +/*% + * Currently defined type values for resources and queries. + */ +typedef enum __ns_type { + ns_t_invalid = 0, /*%< Cookie. */ + ns_t_a = 1, /*%< Host address. */ + ns_t_ns = 2, /*%< Authoritative server. */ + ns_t_md = 3, /*%< Mail destination. */ + ns_t_mf = 4, /*%< Mail forwarder. */ + ns_t_cname = 5, /*%< Canonical name. */ + ns_t_soa = 6, /*%< Start of authority zone. */ + ns_t_mb = 7, /*%< Mailbox domain name. */ + ns_t_mg = 8, /*%< Mail group member. */ + ns_t_mr = 9, /*%< Mail rename name. */ + ns_t_null = 10, /*%< Null resource record. */ + ns_t_wks = 11, /*%< Well known service. */ + ns_t_ptr = 12, /*%< Domain name pointer. */ + ns_t_hinfo = 13, /*%< Host information. */ + ns_t_minfo = 14, /*%< Mailbox information. */ + ns_t_mx = 15, /*%< Mail routing information. */ + ns_t_txt = 16, /*%< Text strings. */ + ns_t_rp = 17, /*%< Responsible person. */ + ns_t_afsdb = 18, /*%< AFS cell database. */ + ns_t_x25 = 19, /*%< X_25 calling address. */ + ns_t_isdn = 20, /*%< ISDN calling address. */ + ns_t_rt = 21, /*%< Router. */ + ns_t_nsap = 22, /*%< NSAP address. */ + ns_t_nsap_ptr = 23, /*%< Reverse NSAP lookup (deprecated). */ + ns_t_sig = 24, /*%< Security signature. */ + ns_t_key = 25, /*%< Security key. */ + ns_t_px = 26, /*%< X.400 mail mapping. */ + ns_t_gpos = 27, /*%< Geographical position (withdrawn). */ + ns_t_aaaa = 28, /*%< IPv6 Address. */ + ns_t_loc = 29, /*%< Location Information. */ + ns_t_nxt = 30, /*%< Next domain (security). */ + ns_t_eid = 31, /*%< Endpoint identifier. */ + ns_t_nimloc = 32, /*%< Nimrod Locator. */ + ns_t_srv = 33, /*%< Server Selection. */ + ns_t_atma = 34, /*%< ATM Address */ + ns_t_naptr = 35, /*%< Naming Authority PoinTeR */ + ns_t_kx = 36, /*%< Key Exchange */ + ns_t_cert = 37, /*%< Certification record */ + ns_t_a6 = 38, /*%< IPv6 address (experimental) */ + ns_t_dname = 39, /*%< Non-terminal DNAME */ + ns_t_sink = 40, /*%< Kitchen sink (experimentatl) */ + ns_t_opt = 41, /*%< EDNS0 option (meta-RR) */ + ns_t_apl = 42, /*%< Address prefix list (RFC3123) */ + ns_t_ds = 43, /*%< Delegation Signer */ + ns_t_sshfp = 44, /*%< SSH Fingerprint */ + ns_t_ipseckey = 45, /*%< IPSEC Key */ + ns_t_rrsig = 46, /*%< RRset Signature */ + ns_t_nsec = 47, /*%< Negative security */ + ns_t_dnskey = 48, /*%< DNS Key */ + ns_t_dhcid = 49, /*%< Dynamic host configuratin identifier */ + ns_t_nsec3 = 50, /*%< Negative security type 3 */ + ns_t_nsec3param = 51, /*%< Negative security type 3 parameters */ + ns_t_hip = 55, /*%< Host Identity Protocol */ + ns_t_spf = 99, /*%< Sender Policy Framework */ + ns_t_tkey = 249, /*%< Transaction key */ + ns_t_tsig = 250, /*%< Transaction signature. */ + ns_t_ixfr = 251, /*%< Incremental zone transfer. */ + ns_t_axfr = 252, /*%< Transfer zone of authority. */ + ns_t_mailb = 253, /*%< Transfer mailbox records. */ + ns_t_maila = 254, /*%< Transfer mail agent records. */ + ns_t_any = 255, /*%< Wildcard match. */ + ns_t_zxfr = 256, /*%< BIND-specific, nonstandard. */ + ns_t_dlv = 32769, /*%< DNSSEC look-aside validatation. */ + ns_t_max = 65536 +} ns_type; + +/* Exclusively a QTYPE? (not also an RTYPE) */ +#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \ + (t) == ns_t_mailb || (t) == ns_t_maila) +/* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */ +#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt) +/* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */ +#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t)) +#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr) +#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \ + (t) == ns_t_zxfr) + +/*% + * Values for class field + */ +typedef enum __ns_class { + ns_c_invalid = 0, /*%< Cookie. */ + ns_c_in = 1, /*%< Internet. */ + ns_c_2 = 2, /*%< unallocated/unsupported. */ + ns_c_chaos = 3, /*%< MIT Chaos-net. */ + ns_c_hs = 4, /*%< MIT Hesiod. */ + /* Query class values which do not appear in resource records */ + ns_c_none = 254, /*%< for prereq. sections in update requests */ + ns_c_any = 255, /*%< Wildcard match. */ + ns_c_max = 65536 +} ns_class; + +/* DNSSEC constants. */ + +typedef enum __ns_key_types { + ns_kt_rsa = 1, /*%< key type RSA/MD5 */ + ns_kt_dh = 2, /*%< Diffie Hellman */ + ns_kt_dsa = 3, /*%< Digital Signature Standard (MANDATORY) */ + ns_kt_private = 254 /*%< Private key type starts with OID */ +} ns_key_types; + +typedef enum __ns_cert_types { + cert_t_pkix = 1, /*%< PKIX (X.509v3) */ + cert_t_spki = 2, /*%< SPKI */ + cert_t_pgp = 3, /*%< PGP */ + cert_t_url = 253, /*%< URL private type */ + cert_t_oid = 254 /*%< OID private type */ +} ns_cert_types; + +/* Flags field of the KEY RR rdata. */ +#define NS_KEY_TYPEMASK 0xC000 /*%< Mask for "type" bits */ +#define NS_KEY_TYPE_AUTH_CONF 0x0000 /*%< Key usable for both */ +#define NS_KEY_TYPE_CONF_ONLY 0x8000 /*%< Key usable for confidentiality */ +#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /*%< Key usable for authentication */ +#define NS_KEY_TYPE_NO_KEY 0xC000 /*%< No key usable for either; no key */ +/* The type bits can also be interpreted independently, as single bits: */ +#define NS_KEY_NO_AUTH 0x8000 /*%< Key unusable for authentication */ +#define NS_KEY_NO_CONF 0x4000 /*%< Key unusable for confidentiality */ +#define NS_KEY_RESERVED2 0x2000 /* Security is *mandatory* if bit=0 */ +#define NS_KEY_EXTENDED_FLAGS 0x1000 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED4 0x0800 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED5 0x0400 /*%< reserved - must be zero */ +#define NS_KEY_NAME_TYPE 0x0300 /*%< these bits determine the type */ +#define NS_KEY_NAME_USER 0x0000 /*%< key is assoc. with user */ +#define NS_KEY_NAME_ENTITY 0x0200 /*%< key is assoc. with entity eg host */ +#define NS_KEY_NAME_ZONE 0x0100 /*%< key is zone key */ +#define NS_KEY_NAME_RESERVED 0x0300 /*%< reserved meaning */ +#define NS_KEY_RESERVED8 0x0080 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED9 0x0040 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED10 0x0020 /*%< reserved - must be zero */ +#define NS_KEY_RESERVED11 0x0010 /*%< reserved - must be zero */ +#define NS_KEY_SIGNATORYMASK 0x000F /*%< key can sign RR's of same name */ +#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \ + NS_KEY_RESERVED4 | \ + NS_KEY_RESERVED5 | \ + NS_KEY_RESERVED8 | \ + NS_KEY_RESERVED9 | \ + NS_KEY_RESERVED10 | \ + NS_KEY_RESERVED11 ) +#define NS_KEY_RESERVED_BITMASK2 0xFFFF /*%< no bits defined here */ +/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */ +#define NS_ALG_MD5RSA 1 /*%< MD5 with RSA */ +#define NS_ALG_DH 2 /*%< Diffie Hellman KEY */ +#define NS_ALG_DSA 3 /*%< DSA KEY */ +#define NS_ALG_DSS NS_ALG_DSA +#define NS_ALG_EXPIRE_ONLY 253 /*%< No alg, no security */ +#define NS_ALG_PRIVATE_OID 254 /*%< Key begins with OID giving alg */ +/* Protocol values */ +/* value 0 is reserved */ +#define NS_KEY_PROT_TLS 1 +#define NS_KEY_PROT_EMAIL 2 +#define NS_KEY_PROT_DNSSEC 3 +#define NS_KEY_PROT_IPSEC 4 +#define NS_KEY_PROT_ANY 255 + +/* Signatures */ +#define NS_MD5RSA_MIN_BITS 512 /*%< Size of a mod or exp in bits */ +#define NS_MD5RSA_MAX_BITS 4096 + /* Total of binary mod and exp */ +#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3) + /* Max length of text sig block */ +#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4) +#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8) +#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8) + +#define NS_DSA_SIG_SIZE 41 +#define NS_DSA_MIN_SIZE 213 +#define NS_DSA_MAX_BYTES 405 + +/* Offsets into SIG record rdata to find various values */ +#define NS_SIG_TYPE 0 /*%< Type flags */ +#define NS_SIG_ALG 2 /*%< Algorithm */ +#define NS_SIG_LABELS 3 /*%< How many labels in name */ +#define NS_SIG_OTTL 4 /*%< Original TTL */ +#define NS_SIG_EXPIR 8 /*%< Expiration time */ +#define NS_SIG_SIGNED 12 /*%< Signature time */ +#define NS_SIG_FOOT 16 /*%< Key footprint */ +#define NS_SIG_SIGNER 18 /*%< Domain name of who signed it */ +/* How RR types are represented as bit-flags in NXT records */ +#define NS_NXT_BITS 8 +#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS))) +#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS))) +#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS))) +#define NS_NXT_MAX 127 + +/*% + * EDNS0 extended flags and option codes, host order. + */ +#define NS_OPT_DNSSEC_OK 0x8000U +#define NS_OPT_NSID 3 + +/*% + * Inline versions of get/put short/long. Pointer is advanced. + */ +#define NS_GET16(s, cp) do { \ + register const u_char *t_cp = (const u_char *)(cp); \ + (s) = ((u_int16_t)t_cp[0] << 8) \ + | ((u_int16_t)t_cp[1]) \ + ; \ + (cp) += NS_INT16SZ; \ +} while (0) + +#define NS_GET32(l, cp) do { \ + register const u_char *t_cp = (const u_char *)(cp); \ + (l) = ((u_int32_t)t_cp[0] << 24) \ + | ((u_int32_t)t_cp[1] << 16) \ + | ((u_int32_t)t_cp[2] << 8) \ + | ((u_int32_t)t_cp[3]) \ + ; \ + (cp) += NS_INT32SZ; \ +} while (0) + +#define NS_PUT16(s, cp) do { \ + register u_int16_t t_s = (u_int16_t)(s); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += NS_INT16SZ; \ +} while (0) + +#define NS_PUT32(l, cp) do { \ + register u_int32_t t_l = (u_int32_t)(l); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp = t_l; \ + (cp) += NS_INT32SZ; \ +} while (0) + +/*% + * ANSI C identifier hiding for bind's lib/nameser. + */ +#define ns_msg_getflag __ns_msg_getflag +#define ns_get16 __ns_get16 +#define ns_get32 __ns_get32 +#define ns_put16 __ns_put16 +#define ns_put32 __ns_put32 +#define ns_initparse __ns_initparse +#define ns_skiprr __ns_skiprr +#define ns_parserr __ns_parserr +#define ns_parserr2 __ns_parserr2 +#define ns_sprintrr __ns_sprintrr +#define ns_sprintrrf __ns_sprintrrf +#define ns_format_ttl __ns_format_ttl +#define ns_parse_ttl __ns_parse_ttl +#if 0 +#define ns_datetosecs __ns_datetosecs +#endif +#define ns_name_ntol __ns_name_ntol +#define ns_name_ntop __ns_name_ntop +#define ns_name_pton __ns_name_pton +#define ns_name_pton2 __ns_name_pton2 +#define ns_name_unpack __ns_name_unpack +#define ns_name_unpack2 __ns_name_unpack2 +#define ns_name_pack __ns_name_pack +#define ns_name_compress __ns_name_compress +#define ns_name_uncompress __ns_name_uncompress +#define ns_name_skip __ns_name_skip +#define ns_name_rollback __ns_name_rollback +#define ns_name_length __ns_name_length +#define ns_name_eq __ns_name_eq +#define ns_name_owned __ns_name_owned +#define ns_name_map __ns_name_map +#define ns_name_labels __ns_name_labels +#if 0 +#define ns_sign __ns_sign +#define ns_sign2 __ns_sign2 +#define ns_sign_tcp __ns_sign_tcp +#define ns_sign_tcp2 __ns_sign_tcp2 +#define ns_sign_tcp_init __ns_sign_tcp_init +#define ns_find_tsig __ns_find_tsig +#define ns_verify __ns_verify +#define ns_verify_tcp __ns_verify_tcp +#define ns_verify_tcp_init __ns_verify_tcp_init +#endif +#define ns_samedomain __ns_samedomain +#if 0 +#define ns_subdomain __ns_subdomain +#endif +#define ns_makecanon __ns_makecanon +#define ns_samename __ns_samename +#define ns_newmsg_init __ns_newmsg_init +#define ns_newmsg_copy __ns_newmsg_copy +#define ns_newmsg_id __ns_newmsg_id +#define ns_newmsg_flag __ns_newmsg_flag +#define ns_newmsg_q __ns_newmsg_q +#define ns_newmsg_rr __ns_newmsg_rr +#define ns_newmsg_done __ns_newmsg_done +#define ns_rdata_unpack __ns_rdata_unpack +#define ns_rdata_equal __ns_rdata_equal +#define ns_rdata_refers __ns_rdata_refers + +__BEGIN_DECLS +int ns_msg_getflag(ns_msg, int); +u_int ns_get16(const u_char *); +u_long ns_get32(const u_char *); +void ns_put16(u_int, u_char *); +void ns_put32(u_long, u_char *); +int ns_initparse(const u_char *, int, ns_msg *); +int ns_skiprr(const u_char *, const u_char *, ns_sect, int); +int ns_parserr(ns_msg *, ns_sect, int, ns_rr *); +int ns_parserr2(ns_msg *, ns_sect, int, ns_rr2 *); +int ns_sprintrr(const ns_msg *, const ns_rr *, + const char *, const char *, char *, size_t); +int ns_sprintrrf(const u_char *, size_t, const char *, + ns_class, ns_type, u_long, const u_char *, + size_t, const char *, const char *, + char *, size_t); +int ns_format_ttl(u_long, char *, size_t); +int ns_parse_ttl(const char *, u_long *); +#if 0 +u_int32_t ns_datetosecs(const char *cp, int *errp); +#endif +int ns_name_ntol(const u_char *, u_char *, size_t); +int ns_name_ntop(const u_char *, char *, size_t); +int ns_name_pton(const char *, u_char *, size_t); +int ns_name_pton2(const char *, u_char *, size_t, size_t *); +int ns_name_unpack(const u_char *, const u_char *, + const u_char *, u_char *, size_t); +int ns_name_unpack2(const u_char *, const u_char *, + const u_char *, u_char *, size_t, + size_t *); +int ns_name_pack(const u_char *, u_char *, int, + const u_char **, const u_char **); +int ns_name_uncompress(const u_char *, const u_char *, + const u_char *, char *, size_t); +int ns_name_compress(const char *, u_char *, size_t, + const u_char **, const u_char **); +int ns_name_skip(const u_char **, const u_char *); +void ns_name_rollback(const u_char *, const u_char **, + const u_char **); +ssize_t ns_name_length(ns_nname_ct, size_t); +int ns_name_eq(ns_nname_ct, size_t, ns_nname_ct, size_t); +int ns_name_owned(ns_namemap_ct, int, ns_namemap_ct, int); +int ns_name_map(ns_nname_ct, size_t, ns_namemap_t, int); +int ns_name_labels(ns_nname_ct, size_t); +#if 0 +int ns_sign(u_char *, int *, int, int, void *, + const u_char *, int, u_char *, int *, time_t); +int ns_sign2(u_char *, int *, int, int, void *, + const u_char *, int, u_char *, int *, time_t, + u_char **, u_char **); +int ns_sign_tcp(u_char *, int *, int, int, + ns_tcp_tsig_state *, int); +int ns_sign_tcp2(u_char *, int *, int, int, + ns_tcp_tsig_state *, int, + u_char **, u_char **); +int ns_sign_tcp_init(void *, const u_char *, int, + ns_tcp_tsig_state *); +u_char *ns_find_tsig(u_char *, u_char *); +int ns_verify(u_char *, int *, void *, + const u_char *, int, u_char *, int *, + time_t *, int); +int ns_verify_tcp(u_char *, int *, ns_tcp_tsig_state *, int); +int ns_verify_tcp_init(void *, const u_char *, int, + ns_tcp_tsig_state *); +#endif +int ns_samedomain(const char *, const char *); +#if 0 +int ns_subdomain(const char *, const char *); +#endif +int ns_makecanon(const char *, char *, size_t); +int ns_samename(const char *, const char *); +int ns_newmsg_init(u_char *buffer, size_t bufsiz, ns_newmsg *); +int ns_newmsg_copy(ns_newmsg *, ns_msg *); +void ns_newmsg_id(ns_newmsg *handle, u_int16_t id); +void ns_newmsg_flag(ns_newmsg *handle, ns_flag flag, u_int value); +int ns_newmsg_q(ns_newmsg *handle, ns_nname_ct qname, + ns_type qtype, ns_class qclass); +int ns_newmsg_rr(ns_newmsg *handle, ns_sect sect, + ns_nname_ct name, ns_type type, + ns_class rr_class, u_int32_t ttl, + u_int16_t rdlen, const u_char *rdata); +size_t ns_newmsg_done(ns_newmsg *handle); +ssize_t ns_rdata_unpack(const u_char *, const u_char *, ns_type, + const u_char *, size_t, u_char *, size_t); +int ns_rdata_equal(ns_type, + const u_char *, size_t, + const u_char *, size_t); +int ns_rdata_refers(ns_type, + const u_char *, size_t, + const u_char *); +__END_DECLS + +#ifdef BIND_4_COMPAT +#include +#endif + +#endif /* !_ARPA_NAMESER_H_ */ +/*! \file */ diff --git a/include/arpa/nameser_compat.h b/include/arpa/nameser_compat.h new file mode 100644 index 0000000..b2dac70 --- /dev/null +++ b/include/arpa/nameser_compat.h @@ -0,0 +1,199 @@ +/* Copyright (c) 1983, 1989 + * 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. + */ + +/*% + * from nameser.h 8.1 (Berkeley) 6/2/93 + * $Id: nameser_compat.h,v 1.8 2006/05/19 02:33:40 marka Exp $ + * $FreeBSD: releng/11.1/include/arpa/nameser_compat.h 269867 2014-08-12 12:36:06Z ume $ + */ + +#ifndef _ARPA_NAMESER_COMPAT_ +#define _ARPA_NAMESER_COMPAT_ + +#define __BIND 19950621 /*%< (DEAD) interface version stamp. */ + +#include + +#if !defined(_BYTE_ORDER) || \ + (_BYTE_ORDER != _BIG_ENDIAN && _BYTE_ORDER != _LITTLE_ENDIAN && \ + _BYTE_ORDER != _PDP_ENDIAN) + /* you must determine what the correct bit order is for + * your compiler - the next line is an intentional error + * which will force your compiles to bomb until you fix + * the above macros. + */ +#error "Undefined or invalid _BYTE_ORDER"; +#endif + +/*% + * Structure for query header. The order of the fields is machine- and + * compiler-dependent, depending on the byte/bit order and the layout + * of bit fields. We use bit fields only in int variables, as this + * is all ANSI requires. This requires a somewhat confusing rearrangement. + */ + +typedef struct { + unsigned id :16; /*%< query identification number */ +#if _BYTE_ORDER == _BIG_ENDIAN + /* fields in third byte */ + unsigned qr: 1; /*%< response flag */ + unsigned opcode: 4; /*%< purpose of message */ + unsigned aa: 1; /*%< authoritative answer */ + unsigned tc: 1; /*%< truncated message */ + unsigned rd: 1; /*%< recursion desired */ + /* fields in fourth byte */ + unsigned ra: 1; /*%< recursion available */ + unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */ + unsigned ad: 1; /*%< authentic data from named */ + unsigned cd: 1; /*%< checking disabled by resolver */ + unsigned rcode :4; /*%< response code */ +#endif +#if _BYTE_ORDER == _LITTLE_ENDIAN || _BYTE_ORDER == _PDP_ENDIAN + /* fields in third byte */ + unsigned rd :1; /*%< recursion desired */ + unsigned tc :1; /*%< truncated message */ + unsigned aa :1; /*%< authoritative answer */ + unsigned opcode :4; /*%< purpose of message */ + unsigned qr :1; /*%< response flag */ + /* fields in fourth byte */ + unsigned rcode :4; /*%< response code */ + unsigned cd: 1; /*%< checking disabled by resolver */ + unsigned ad: 1; /*%< authentic data from named */ + unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */ + unsigned ra :1; /*%< recursion available */ +#endif + /* remaining bytes */ + unsigned qdcount :16; /*%< number of question entries */ + unsigned ancount :16; /*%< number of answer entries */ + unsigned nscount :16; /*%< number of authority entries */ + unsigned arcount :16; /*%< number of resource entries */ +} HEADER; + +#define PACKETSZ NS_PACKETSZ +#define MAXDNAME NS_MAXDNAME +#define MAXCDNAME NS_MAXCDNAME +#define MAXLABEL NS_MAXLABEL +#define HFIXEDSZ NS_HFIXEDSZ +#define QFIXEDSZ NS_QFIXEDSZ +#define RRFIXEDSZ NS_RRFIXEDSZ +#define INT32SZ NS_INT32SZ +#define INT16SZ NS_INT16SZ +#define INT8SZ NS_INT8SZ +#define INADDRSZ NS_INADDRSZ +#define IN6ADDRSZ NS_IN6ADDRSZ +#define INDIR_MASK NS_CMPRSFLGS +#define NAMESERVER_PORT NS_DEFAULTPORT + +#define S_ZONE ns_s_zn +#define S_PREREQ ns_s_pr +#define S_UPDATE ns_s_ud +#define S_ADDT ns_s_ar + +#define QUERY ns_o_query +#define IQUERY ns_o_iquery +#define STATUS ns_o_status +#define NS_NOTIFY_OP ns_o_notify +#define NS_UPDATE_OP ns_o_update + +#define NOERROR ns_r_noerror +#define FORMERR ns_r_formerr +#define SERVFAIL ns_r_servfail +#define NXDOMAIN ns_r_nxdomain +#define NOTIMP ns_r_notimpl +#define REFUSED ns_r_refused +#define YXDOMAIN ns_r_yxdomain +#define YXRRSET ns_r_yxrrset +#define NXRRSET ns_r_nxrrset +#define NOTAUTH ns_r_notauth +#define NOTZONE ns_r_notzone +/*#define BADSIG ns_r_badsig*/ +/*#define BADKEY ns_r_badkey*/ +/*#define BADTIME ns_r_badtime*/ + + +#define DELETE ns_uop_delete +#define ADD ns_uop_add + +#define T_A ns_t_a +#define T_NS ns_t_ns +#define T_MD ns_t_md +#define T_MF ns_t_mf +#define T_CNAME ns_t_cname +#define T_SOA ns_t_soa +#define T_MB ns_t_mb +#define T_MG ns_t_mg +#define T_MR ns_t_mr +#define T_NULL ns_t_null +#define T_WKS ns_t_wks +#define T_PTR ns_t_ptr +#define T_HINFO ns_t_hinfo +#define T_MINFO ns_t_minfo +#define T_MX ns_t_mx +#define T_TXT ns_t_txt +#define T_RP ns_t_rp +#define T_AFSDB ns_t_afsdb +#define T_X25 ns_t_x25 +#define T_ISDN ns_t_isdn +#define T_RT ns_t_rt +#define T_NSAP ns_t_nsap +#define T_NSAP_PTR ns_t_nsap_ptr +#define T_SIG ns_t_sig +#define T_KEY ns_t_key +#define T_PX ns_t_px +#define T_GPOS ns_t_gpos +#define T_AAAA ns_t_aaaa +#define T_LOC ns_t_loc +#define T_NXT ns_t_nxt +#define T_EID ns_t_eid +#define T_NIMLOC ns_t_nimloc +#define T_SRV ns_t_srv +#define T_ATMA ns_t_atma +#define T_NAPTR ns_t_naptr +#define T_A6 ns_t_a6 +#define T_OPT ns_t_opt +#define T_TSIG ns_t_tsig +#define T_IXFR ns_t_ixfr +#define T_AXFR ns_t_axfr +#define T_MAILB ns_t_mailb +#define T_MAILA ns_t_maila +#define T_ANY ns_t_any + +#define C_IN ns_c_in +#define C_CHAOS ns_c_chaos +#define C_HS ns_c_hs +/* BIND_UPDATE */ +#define C_NONE ns_c_none +#define C_ANY ns_c_any + +#define GETSHORT NS_GET16 +#define GETLONG NS_GET32 +#define PUTSHORT NS_PUT16 +#define PUTLONG NS_PUT32 + +#endif /* _ARPA_NAMESER_COMPAT_ */ +/*! \file */ diff --git a/include/arpa/telnet.h b/include/arpa/telnet.h new file mode 100644 index 0000000..fbf03d2 --- /dev/null +++ b/include/arpa/telnet.h @@ -0,0 +1,343 @@ +/* + * Copyright (c) 1983, 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. + * + * @(#)telnet.h 8.2 (Berkeley) 12/15/93 + * $FreeBSD: releng/11.1/include/arpa/telnet.h 203965 2010-02-16 19:46:46Z imp $ + */ + +#ifndef _ARPA_TELNET_H_ +#define _ARPA_TELNET_H_ + +/* + * Definitions for the TELNET protocol. + */ +#define IAC 255 /* interpret as command: */ +#define DONT 254 /* you are not to use option */ +#define DO 253 /* please, you use option */ +#define WONT 252 /* I won't use option */ +#define WILL 251 /* I will use option */ +#define SB 250 /* interpret as subnegotiation */ +#define GA 249 /* you may reverse the line */ +#define EL 248 /* erase the current line */ +#define EC 247 /* erase the current character */ +#define AYT 246 /* are you there */ +#define AO 245 /* abort output--but let prog finish */ +#define IP 244 /* interrupt process--permanently */ +#define BREAK 243 /* break */ +#define DM 242 /* data mark--for connect. cleaning */ +#define NOP 241 /* nop */ +#define SE 240 /* end sub negotiation */ +#define EOR 239 /* end of record (transparent mode) */ +#define ABORT 238 /* Abort process */ +#define SUSP 237 /* Suspend process */ +#define xEOF 236 /* End of file: EOF is already used... */ + +#define SYNCH 242 /* for telfunc calls */ + +#ifdef TELCMDS +const char *telcmds[] = { + "EOF", "SUSP", "ABORT", "EOR", + "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", + "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", + 0 +}; +#else +extern char *telcmds[]; +#endif + +#define TELCMD_FIRST xEOF +#define TELCMD_LAST IAC +#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \ + (unsigned int)(x) >= TELCMD_FIRST) +#define TELCMD(x) telcmds[(x)-TELCMD_FIRST] + +/* telnet options */ +#define TELOPT_BINARY 0 /* 8-bit data path */ +#define TELOPT_ECHO 1 /* echo */ +#define TELOPT_RCP 2 /* prepare to reconnect */ +#define TELOPT_SGA 3 /* suppress go ahead */ +#define TELOPT_NAMS 4 /* approximate message size */ +#define TELOPT_STATUS 5 /* give status */ +#define TELOPT_TM 6 /* timing mark */ +#define TELOPT_RCTE 7 /* remote controlled transmission and echo */ +#define TELOPT_NAOL 8 /* negotiate about output line width */ +#define TELOPT_NAOP 9 /* negotiate about output page size */ +#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */ +#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */ +#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */ +#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */ +#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */ +#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */ +#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */ +#define TELOPT_XASCII 17 /* extended ascic character set */ +#define TELOPT_LOGOUT 18 /* force logout */ +#define TELOPT_BM 19 /* byte macro */ +#define TELOPT_DET 20 /* data entry terminal */ +#define TELOPT_SUPDUP 21 /* supdup protocol */ +#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */ +#define TELOPT_SNDLOC 23 /* send location */ +#define TELOPT_TTYPE 24 /* terminal type */ +#define TELOPT_EOR 25 /* end or record */ +#define TELOPT_TUID 26 /* TACACS user identification */ +#define TELOPT_OUTMRK 27 /* output marking */ +#define TELOPT_TTYLOC 28 /* terminal location number */ +#define TELOPT_3270REGIME 29 /* 3270 regime */ +#define TELOPT_X3PAD 30 /* X.3 PAD */ +#define TELOPT_NAWS 31 /* window size */ +#define TELOPT_TSPEED 32 /* terminal speed */ +#define TELOPT_LFLOW 33 /* remote flow control */ +#define TELOPT_LINEMODE 34 /* Linemode option */ +#define TELOPT_XDISPLOC 35 /* X Display Location */ +#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */ +#define TELOPT_AUTHENTICATION 37/* Authenticate */ +#define TELOPT_ENCRYPT 38 /* Encryption option */ +#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */ +#define TELOPT_TN3270E 40 /* RFC2355 - TN3270 Enhancements */ +#define TELOPT_CHARSET 42 /* RFC2066 - Charset */ +#define TELOPT_COMPORT 44 /* RFC2217 - Com Port Control */ +#define TELOPT_KERMIT 47 /* RFC2840 - Kermit */ +#define TELOPT_EXOPL 255 /* extended-options-list */ + + +#define NTELOPTS (1+TELOPT_KERMIT) +#ifdef TELOPTS +const char *telopts[NTELOPTS+1] = { + "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", + "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP", + "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS", + "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", + "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT", + "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD", + "TACACS UID", "OUTPUT MARKING", "TTYLOC", + "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW", + "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION", + "ENCRYPT", "NEW-ENVIRON", "TN3270E", "XAUTH", "CHARSET", + "RSP", "COM-PORT", "SLE", "STARTTLS", "KERMIT", + 0 +}; +#define TELOPT_FIRST TELOPT_BINARY +#define TELOPT_LAST TELOPT_KERMIT +#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST) +#define TELOPT(x) telopts[(x)-TELOPT_FIRST] +#endif + +/* sub-option qualifiers */ +#define TELQUAL_IS 0 /* option is... */ +#define TELQUAL_SEND 1 /* send option */ +#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */ +#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */ +#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */ + +#define LFLOW_OFF 0 /* Disable remote flow control */ +#define LFLOW_ON 1 /* Enable remote flow control */ +#define LFLOW_RESTART_ANY 2 /* Restart output on any char */ +#define LFLOW_RESTART_XON 3 /* Restart output only on XON */ + +/* + * LINEMODE suboptions + */ + +#define LM_MODE 1 +#define LM_FORWARDMASK 2 +#define LM_SLC 3 + +#define MODE_EDIT 0x01 +#define MODE_TRAPSIG 0x02 +#define MODE_ACK 0x04 +#define MODE_SOFT_TAB 0x08 +#define MODE_LIT_ECHO 0x10 + +#define MODE_MASK 0x1f + +/* Not part of protocol, but needed to simplify things... */ +#define MODE_FLOW 0x0100 +#define MODE_ECHO 0x0200 +#define MODE_INBIN 0x0400 +#define MODE_OUTBIN 0x0800 +#define MODE_FORCE 0x1000 + +#define SLC_SYNCH 1 +#define SLC_BRK 2 +#define SLC_IP 3 +#define SLC_AO 4 +#define SLC_AYT 5 +#define SLC_EOR 6 +#define SLC_ABORT 7 +#define SLC_EOF 8 +#define SLC_SUSP 9 +#define SLC_EC 10 +#define SLC_EL 11 +#define SLC_EW 12 +#define SLC_RP 13 +#define SLC_LNEXT 14 +#define SLC_XON 15 +#define SLC_XOFF 16 +#define SLC_FORW1 17 +#define SLC_FORW2 18 +#define SLC_MCL 19 +#define SLC_MCR 20 +#define SLC_MCWL 21 +#define SLC_MCWR 22 +#define SLC_MCBOL 23 +#define SLC_MCEOL 24 +#define SLC_INSRT 25 +#define SLC_OVER 26 +#define SLC_ECR 27 +#define SLC_EWR 28 +#define SLC_EBOL 29 +#define SLC_EEOL 30 + +#define NSLC 30 + +/* + * For backwards compatibility, we define SLC_NAMES to be the + * list of names if SLC_NAMES is not defined. + */ +#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \ + "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \ + "LNEXT", "XON", "XOFF", "FORW1", "FORW2", \ + "MCL", "MCR", "MCWL", "MCWR", "MCBOL", \ + "MCEOL", "INSRT", "OVER", "ECR", "EWR", \ + "EBOL", "EEOL", \ + 0 + +#ifdef SLC_NAMES +const char *slc_names[] = { + SLC_NAMELIST +}; +#else +extern char *slc_names[]; +#define SLC_NAMES SLC_NAMELIST +#endif + +#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC) +#define SLC_NAME(x) slc_names[x] + +#define SLC_NOSUPPORT 0 +#define SLC_CANTCHANGE 1 +#define SLC_VARIABLE 2 +#define SLC_DEFAULT 3 +#define SLC_LEVELBITS 0x03 + +#define SLC_FUNC 0 +#define SLC_FLAGS 1 +#define SLC_VALUE 2 + +#define SLC_ACK 0x80 +#define SLC_FLUSHIN 0x40 +#define SLC_FLUSHOUT 0x20 + +#define OLD_ENV_VAR 1 +#define OLD_ENV_VALUE 0 +#define NEW_ENV_VAR 0 +#define NEW_ENV_VALUE 1 +#define ENV_ESC 2 +#define ENV_USERVAR 3 + +/* + * AUTHENTICATION suboptions + */ + +/* + * Who is authenticating who ... + */ +#define AUTH_WHO_CLIENT 0 /* Client authenticating server */ +#define AUTH_WHO_SERVER 1 /* Server authenticating client */ +#define AUTH_WHO_MASK 1 + +/* + * amount of authentication done + */ +#define AUTH_HOW_ONE_WAY 0 +#define AUTH_HOW_MUTUAL 2 +#define AUTH_HOW_MASK 2 + +#define AUTHTYPE_NULL 0 +#define AUTHTYPE_KERBEROS_V4 1 +#define AUTHTYPE_KERBEROS_V5 2 +#define AUTHTYPE_SPX 3 +#define AUTHTYPE_MINK 4 +#define AUTHTYPE_SRA 6 +#define AUTHTYPE_CNT 7 + +#define AUTHTYPE_TEST 99 + +#ifdef AUTH_NAMES +const char *authtype_names[] = { + "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", NULL, "SRA", + 0 +}; +#else +extern char *authtype_names[]; +#endif + +#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT) +#define AUTHTYPE_NAME(x) authtype_names[x] + +/* + * ENCRYPTion suboptions + */ +#define ENCRYPT_IS 0 /* I pick encryption type ... */ +#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */ +#define ENCRYPT_REPLY 2 /* Initial setup response */ +#define ENCRYPT_START 3 /* Am starting to send encrypted */ +#define ENCRYPT_END 4 /* Am ending encrypted */ +#define ENCRYPT_REQSTART 5 /* Request you start encrypting */ +#define ENCRYPT_REQEND 6 /* Request you end encrypting */ +#define ENCRYPT_ENC_KEYID 7 +#define ENCRYPT_DEC_KEYID 8 +#define ENCRYPT_CNT 9 + +#define ENCTYPE_ANY 0 +#define ENCTYPE_DES_CFB64 1 +#define ENCTYPE_DES_OFB64 2 +#define ENCTYPE_CNT 3 + +#ifdef ENCRYPT_NAMES +const char *encrypt_names[] = { + "IS", "SUPPORT", "REPLY", "START", "END", + "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID", + 0 +}; +const char *enctype_names[] = { + "ANY", "DES_CFB64", "DES_OFB64", + 0 +}; +#else +extern char *encrypt_names[]; +extern char *enctype_names[]; +#endif + + +#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT) +#define ENCRYPT_NAME(x) encrypt_names[x] + +#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT) +#define ENCTYPE_NAME(x) enctype_names[x] + +#endif /* !_TELNET_H_ */ diff --git a/include/arpa/tftp.h b/include/arpa/tftp.h new file mode 100644 index 0000000..c8f36cb --- /dev/null +++ b/include/arpa/tftp.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1983, 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. + * + * @(#)tftp.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: releng/11.1/include/arpa/tftp.h 250887 2013-05-21 21:20:10Z ed $ + */ + +#ifndef _ARPA_TFTP_H_ +#define _ARPA_TFTP_H_ + +#include + +/* + * Trivial File Transfer Protocol (IEN-133) + */ +#define SEGSIZE 512 /* data segment size */ + +/* + * Packet types. + */ +#define RRQ 01 /* read request */ +#define WRQ 02 /* write request */ +#define DATA 03 /* data packet */ +#define ACK 04 /* acknowledgement */ +#define ERROR 05 /* error code */ +#define OACK 06 /* option acknowledgement */ + +struct tftphdr { + unsigned short th_opcode; /* packet type */ + union { + unsigned short tu_block; /* block # */ + unsigned short tu_code; /* error code */ + char tu_stuff[1]; /* request packet stuff */ + } __packed th_u; + char th_data[1]; /* data or error string */ +} __packed; + +#define th_block th_u.tu_block +#define th_code th_u.tu_code +#define th_stuff th_u.tu_stuff +#define th_msg th_data + +/* + * Error codes. + */ +#define EUNDEF 0 /* not defined */ +#define ENOTFOUND 1 /* file not found */ +#define EACCESS 2 /* access violation */ +#define ENOSPACE 3 /* disk full or allocation exceeded */ +#define EBADOP 4 /* illegal TFTP operation */ +#define EBADID 5 /* unknown transfer ID */ +#define EEXISTS 6 /* file already exists */ +#define ENOUSER 7 /* no such user */ +#define EOPTNEG 8 /* option negotiation failed */ + +#endif /* !_TFTP_H_ */ diff --git a/include/assert.h b/include/assert.h new file mode 100644 index 0000000..85fa576 --- /dev/null +++ b/include/assert.h @@ -0,0 +1,78 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * (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. + * + * 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. + * + * @(#)assert.h 8.2 (Berkeley) 1/21/94 + * $FreeBSD: releng/11.1/include/assert.h 228955 2011-12-29 14:41:17Z ed $ + */ + +#include + +/* + * Unlike other ANSI header files, may usefully be included + * multiple times, with and without NDEBUG defined. + */ + +#undef assert +#undef _assert + +#ifdef NDEBUG +#define assert(e) ((void)0) +#define _assert(e) ((void)0) +#else +#define _assert(e) assert(e) + +#define assert(e) ((e) ? (void)0 : __assert(__func__, __FILE__, \ + __LINE__, #e)) +#endif /* NDEBUG */ + +#ifndef _ASSERT_H_ +#define _ASSERT_H_ + +/* + * Static assertions. In principle we could define static_assert for + * C++ older than C++11, but this breaks if _Static_assert is + * implemented as a macro. + * + * C++ template parameters may contain commas, even if not enclosed in + * parentheses, causing the _Static_assert macro to be invoked with more + * than two parameters. + */ +#if __ISO_C_VISIBLE >= 2011 && !defined(__cplusplus) +#define static_assert _Static_assert +#endif + +__BEGIN_DECLS +void __assert(const char *, const char *, int, const char *) __dead2; +__END_DECLS + +#endif /* !_ASSERT_H_ */ diff --git a/include/bitstring.h b/include/bitstring.h new file mode 100644 index 0000000..15c7e39 --- /dev/null +++ b/include/bitstring.h @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2003 Poul-Henning Kamp + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/bitstring.h 299090 2016-05-04 22:34:11Z asomers $ + */ + +#ifndef _BITSTRING_H_ +#define _BITSTRING_H_ + +#include +#include +#include + +#endif /* _BITSTRING_H_ */ + diff --git a/include/complex.h b/include/complex.h new file mode 100644 index 0000000..9482651 --- /dev/null +++ b/include/complex.h @@ -0,0 +1,116 @@ +/*- + * Copyright (c) 2001-2011 The FreeBSD Project. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/complex.h 251121 2013-05-30 04:49:26Z das $ + */ + +#ifndef _COMPLEX_H +#define _COMPLEX_H + +#include + +#ifdef __GNUC__ +#if __STDC_VERSION__ < 199901 +#define _Complex __complex__ +#endif +#define _Complex_I ((float _Complex)1.0i) +#endif + +#ifdef __generic +_Static_assert(__generic(_Complex_I, float _Complex, 1, 0), + "_Complex_I must be of type float _Complex"); +#endif + +#define complex _Complex +#define I _Complex_I + +#if __ISO_C_VISIBLE >= 2011 +#ifdef __clang__ +#define CMPLX(x, y) ((double complex){ x, y }) +#define CMPLXF(x, y) ((float complex){ x, y }) +#define CMPLXL(x, y) ((long double complex){ x, y }) +#elif __GNUC_PREREQ__(4, 7) +#define CMPLX(x, y) __builtin_complex((double)(x), (double)(y)) +#define CMPLXF(x, y) __builtin_complex((float)(x), (float)(y)) +#define CMPLXL(x, y) __builtin_complex((long double)(x), (long double)(y)) +#endif +#endif /* __ISO_C_VISIBLE >= 2011 */ + +__BEGIN_DECLS + +double cabs(double complex); +float cabsf(float complex); +long double cabsl(long double complex); +double complex cacos(double complex); +float complex cacosf(float complex); +double complex cacosh(double complex); +float complex cacoshf(float complex); +double carg(double complex); +float cargf(float complex); +long double cargl(long double complex); +double complex casin(double complex); +float complex casinf(float complex); +double complex casinh(double complex); +float complex casinhf(float complex); +double complex catan(double complex); +float complex catanf(float complex); +double complex catanh(double complex); +float complex catanhf(float complex); +double complex ccos(double complex); +float complex ccosf(float complex); +double complex ccosh(double complex); +float complex ccoshf(float complex); +double complex cexp(double complex); +float complex cexpf(float complex); +double cimag(double complex) __pure2; +float cimagf(float complex) __pure2; +long double cimagl(long double complex) __pure2; +double complex conj(double complex) __pure2; +float complex conjf(float complex) __pure2; +long double complex + conjl(long double complex) __pure2; +float complex cprojf(float complex) __pure2; +double complex cproj(double complex) __pure2; +long double complex + cprojl(long double complex) __pure2; +double creal(double complex) __pure2; +float crealf(float complex) __pure2; +long double creall(long double complex) __pure2; +double complex csin(double complex); +float complex csinf(float complex); +double complex csinh(double complex); +float complex csinhf(float complex); +double complex csqrt(double complex); +float complex csqrtf(float complex); +long double complex + csqrtl(long double complex); +double complex ctan(double complex); +float complex ctanf(float complex); +double complex ctanh(double complex); +float complex ctanhf(float complex); + +__END_DECLS + +#endif /* _COMPLEX_H */ diff --git a/include/cpio.h b/include/cpio.h new file mode 100644 index 0000000..827a720 --- /dev/null +++ b/include/cpio.h @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2002 Mike Barcroft + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/cpio.h 101138 2002-08-01 07:18:38Z mike $ + */ + +#ifndef _CPIO_H_ +#define _CPIO_H_ + +#define C_ISSOCK 0140000 /* Socket. */ +#define C_ISLNK 0120000 /* Symbolic link. */ +#define C_ISCTG 0110000 /* Reserved. */ +#define C_ISREG 0100000 /* Regular file. */ +#define C_ISBLK 0060000 /* Block special. */ +#define C_ISDIR 0040000 /* Directory. */ +#define C_ISCHR 0020000 /* Character special. */ +#define C_ISFIFO 0010000 /* FIFO. */ +#define C_ISUID 0004000 /* Set user ID. */ +#define C_ISGID 0002000 /* Set group ID. */ +#define C_ISVTX 0001000 /* On directories, restricted deletion flag. */ +#define C_IRUSR 0000400 /* Read by owner. */ +#define C_IWUSR 0000200 /* Write by owner. */ +#define C_IXUSR 0000100 /* Execute by owner. */ +#define C_IRGRP 0000040 /* Read by group. */ +#define C_IWGRP 0000020 /* Write by group. */ +#define C_IXGRP 0000010 /* Execute by group. */ +#define C_IROTH 0000004 /* Read by others. */ +#define C_IWOTH 0000002 /* Write by others. */ +#define C_IXOTH 0000001 /* Execute by others. */ + +#define MAGIC "070707" + +#endif /* _CPIO_H_ */ diff --git a/include/db.h b/include/db.h new file mode 100644 index 0000000..8218560 --- /dev/null +++ b/include/db.h @@ -0,0 +1,217 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * 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. + * + * @(#)db.h 8.7 (Berkeley) 6/16/94 + * $FreeBSD: releng/11.1/include/db.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _DB_H_ +#define _DB_H_ + +#include +#include + +#include + +#define RET_ERROR -1 /* Return values. */ +#define RET_SUCCESS 0 +#define RET_SPECIAL 1 + +#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */ +typedef uint32_t pgno_t; +#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */ +typedef uint16_t indx_t; +#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */ +typedef uint32_t recno_t; + +/* Key/data structure -- a Data-Base Thang. */ +typedef struct { + void *data; /* data */ + size_t size; /* data length */ +} DBT; + +/* Routine flags. */ +#define R_CURSOR 1 /* del, put, seq */ +#define __R_UNUSED 2 /* UNUSED */ +#define R_FIRST 3 /* seq */ +#define R_IAFTER 4 /* put (RECNO) */ +#define R_IBEFORE 5 /* put (RECNO) */ +#define R_LAST 6 /* seq (BTREE, RECNO) */ +#define R_NEXT 7 /* seq */ +#define R_NOOVERWRITE 8 /* put */ +#define R_PREV 9 /* seq (BTREE, RECNO) */ +#define R_SETCURSOR 10 /* put (RECNO) */ +#define R_RECNOSYNC 11 /* sync (RECNO) */ + +typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE; + +/* + * !!! + * The following flags are included in the dbopen(3) call as part of the + * open(2) flags. In order to avoid conflicts with the open flags, start + * at the top of the 16 or 32-bit number space and work our way down. If + * the open flags were significantly expanded in the future, it could be + * a problem. Wish I'd left another flags word in the dbopen call. + * + * !!! + * None of this stuff is implemented yet. The only reason that it's here + * is so that the access methods can skip copying the key/data pair when + * the DB_LOCK flag isn't set. + */ +#if UINT_MAX > 65535 +#define DB_LOCK 0x20000000 /* Do locking. */ +#define DB_SHMEM 0x40000000 /* Use shared memory. */ +#define DB_TXN 0x80000000 /* Do transactions. */ +#else +#define DB_LOCK 0x2000 /* Do locking. */ +#define DB_SHMEM 0x4000 /* Use shared memory. */ +#define DB_TXN 0x8000 /* Do transactions. */ +#endif + +/* Access method description structure. */ +typedef struct __db { + DBTYPE type; /* Underlying db type. */ + int (*close)(struct __db *); + int (*del)(const struct __db *, const DBT *, unsigned int); + int (*get)(const struct __db *, const DBT *, DBT *, unsigned int); + int (*put)(const struct __db *, DBT *, const DBT *, unsigned int); + int (*seq)(const struct __db *, DBT *, DBT *, unsigned int); + int (*sync)(const struct __db *, unsigned int); + void *internal; /* Access method private. */ + int (*fd)(const struct __db *); +} DB; + +#define BTREEMAGIC 0x053162 +#define BTREEVERSION 3 + +/* Structure used to pass parameters to the btree routines. */ +typedef struct { +#define R_DUP 0x01 /* duplicate keys */ + unsigned long flags; + unsigned int cachesize; /* bytes to cache */ + int maxkeypage; /* maximum keys per page */ + int minkeypage; /* minimum keys per page */ + unsigned int psize; /* page size */ + int (*compare) /* comparison function */ + (const DBT *, const DBT *); + size_t (*prefix) /* prefix function */ + (const DBT *, const DBT *); + int lorder; /* byte order */ +} BTREEINFO; + +#define HASHMAGIC 0x061561 +#define HASHVERSION 2 + +/* Structure used to pass parameters to the hashing routines. */ +typedef struct { + unsigned int bsize; /* bucket size */ + unsigned int ffactor; /* fill factor */ + unsigned int nelem; /* number of elements */ + unsigned int cachesize; /* bytes to cache */ + uint32_t /* hash function */ + (*hash)(const void *, size_t); + int lorder; /* byte order */ +} HASHINFO; + +/* Structure used to pass parameters to the record routines. */ +typedef struct { +#define R_FIXEDLEN 0x01 /* fixed-length records */ +#define R_NOKEY 0x02 /* key not required */ +#define R_SNAPSHOT 0x04 /* snapshot the input */ + unsigned long flags; + unsigned int cachesize; /* bytes to cache */ + unsigned int psize; /* page size */ + int lorder; /* byte order */ + size_t reclen; /* record length (fixed-length records) */ + unsigned char bval; /* delimiting byte (variable-length records */ + char *bfname; /* btree file name */ +} RECNOINFO; + +#ifdef __DBINTERFACE_PRIVATE +/* + * Little endian <==> big endian 32-bit swap macros. + * M_32_SWAP swap a memory location + * P_32_SWAP swap a referenced memory location + * P_32_COPY swap from one location to another + */ +#define M_32_SWAP(a) { \ + uint32_t _tmp = a; \ + ((char *)&a)[0] = ((char *)&_tmp)[3]; \ + ((char *)&a)[1] = ((char *)&_tmp)[2]; \ + ((char *)&a)[2] = ((char *)&_tmp)[1]; \ + ((char *)&a)[3] = ((char *)&_tmp)[0]; \ +} +#define P_32_SWAP(a) { \ + uint32_t _tmp = *(uint32_t *)a; \ + ((char *)a)[0] = ((char *)&_tmp)[3]; \ + ((char *)a)[1] = ((char *)&_tmp)[2]; \ + ((char *)a)[2] = ((char *)&_tmp)[1]; \ + ((char *)a)[3] = ((char *)&_tmp)[0]; \ +} +#define P_32_COPY(a, b) { \ + ((char *)&(b))[0] = ((char *)&(a))[3]; \ + ((char *)&(b))[1] = ((char *)&(a))[2]; \ + ((char *)&(b))[2] = ((char *)&(a))[1]; \ + ((char *)&(b))[3] = ((char *)&(a))[0]; \ +} + +/* + * Little endian <==> big endian 16-bit swap macros. + * M_16_SWAP swap a memory location + * P_16_SWAP swap a referenced memory location + * P_16_COPY swap from one location to another + */ +#define M_16_SWAP(a) { \ + uint16_t _tmp = a; \ + ((char *)&a)[0] = ((char *)&_tmp)[1]; \ + ((char *)&a)[1] = ((char *)&_tmp)[0]; \ +} +#define P_16_SWAP(a) { \ + uint16_t _tmp = *(uint16_t *)a; \ + ((char *)a)[0] = ((char *)&_tmp)[1]; \ + ((char *)a)[1] = ((char *)&_tmp)[0]; \ +} +#define P_16_COPY(a, b) { \ + ((char *)&(b))[0] = ((char *)&(a))[1]; \ + ((char *)&(b))[1] = ((char *)&(a))[0]; \ +} +#endif + +__BEGIN_DECLS +#if __BSD_VISIBLE +DB *dbopen(const char *, int, int, DBTYPE, const void *); +#endif + +#ifdef __DBINTERFACE_PRIVATE +DB *__bt_open(const char *, int, int, const BTREEINFO *, int); +DB *__hash_open(const char *, int, int, const HASHINFO *, int); +DB *__rec_open(const char *, int, int, const RECNOINFO *, int); +void __dbpanic(DB *dbp); +#endif +__END_DECLS +#endif /* !_DB_H_ */ diff --git a/include/dirent.h b/include/dirent.h new file mode 100644 index 0000000..3ce53bb --- /dev/null +++ b/include/dirent.h @@ -0,0 +1,122 @@ +/*- + * 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. + * + * @(#)dirent.h 8.2 (Berkeley) 7/28/94 + * $FreeBSD: releng/11.1/include/dirent.h 300986 2016-05-30 07:50:57Z ed $ + */ + +#ifndef _DIRENT_H_ +#define _DIRENT_H_ + +/* + * The kernel defines the format of directory entries returned by + * the getdirentries(2) system call. + */ +#include +#include +#include + +#if __XSI_VISIBLE + +#ifndef _INO_T_DECLARED +typedef __ino_t ino_t; +#define _INO_T_DECLARED +#endif + +/* + * XXX this is probably illegal in the __XSI_VISIBLE case, but brings us closer + * to the specification. + */ +#define d_ino d_fileno /* backward and XSI compatibility */ + +#endif /* __XSI_VISIBLE */ + +#if __BSD_VISIBLE + +#include + +/* definitions for library routines operating on directories. */ +#define DIRBLKSIZ 1024 + +struct _dirdesc; +typedef struct _dirdesc DIR; + +/* flags for opendir2 */ +#define DTF_HIDEW 0x0001 /* hide whiteout entries */ +#define DTF_NODUP 0x0002 /* don't return duplicate names */ +#define DTF_REWIND 0x0004 /* rewind after reading union stack */ +#define __DTF_READALL 0x0008 /* everything has been read */ +#define __DTF_SKIPREAD 0x0010 /* assume internal buffer is populated */ + +#else /* !__BSD_VISIBLE */ + +typedef void * DIR; + +#endif /* __BSD_VISIBLE */ + +#ifndef _KERNEL + +__BEGIN_DECLS +#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE >= 700 +int alphasort(const struct dirent **, const struct dirent **); +int dirfd(DIR *); +#endif +#if __BSD_VISIBLE +DIR *__opendir2(const char *, int); +int fdclosedir(DIR *); +int getdents(int, char *, int); +int getdirentries(int, char *, int, long *); +#endif +DIR *opendir(const char *); +DIR *fdopendir(int); +struct dirent * + readdir(DIR *); +#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE >= 500 +int readdir_r(DIR *, struct dirent *, struct dirent **); +#endif +void rewinddir(DIR *); +#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE >= 700 +int scandir(const char *, struct dirent ***, + int (*)(const struct dirent *), int (*)(const struct dirent **, + const struct dirent **)); +#ifdef __BLOCKS__ +int scandir_b(const char *, struct dirent ***, + int (^)(const struct dirent *), + int (^)(const struct dirent **, const struct dirent **)); +#endif +#endif +#if __XSI_VISIBLE +void seekdir(DIR *, long); +long telldir(DIR *); +#endif +int closedir(DIR *); +__END_DECLS + +#endif /* !_KERNEL */ + +#endif /* !_DIRENT_H_ */ diff --git a/include/dlfcn.h b/include/dlfcn.h new file mode 100644 index 0000000..7ea50d6 --- /dev/null +++ b/include/dlfcn.h @@ -0,0 +1,137 @@ +/*- + * Copyright (c) 1994 + * 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. + * + * $FreeBSD: releng/11.1/include/dlfcn.h 229768 2012-01-07 10:33:01Z kib $ + */ + +#ifndef _DLFCN_H_ +#define _DLFCN_H_ + +#include + +/* + * Modes and flags for dlopen(). + */ +#define RTLD_LAZY 1 /* Bind function calls lazily. */ +#define RTLD_NOW 2 /* Bind function calls immediately. */ +#define RTLD_MODEMASK 0x3 +#define RTLD_GLOBAL 0x100 /* Make symbols globally available. */ +#define RTLD_LOCAL 0 /* Opposite of RTLD_GLOBAL, and the default. */ +#define RTLD_TRACE 0x200 /* Trace loaded objects and exit. */ +#define RTLD_NODELETE 0x01000 /* Do not remove members. */ +#define RTLD_NOLOAD 0x02000 /* Do not load if not already loaded. */ + +/* + * Request arguments for dlinfo(). + */ +#define RTLD_DI_LINKMAP 2 /* Obtain link map. */ +#define RTLD_DI_SERINFO 4 /* Obtain search path info. */ +#define RTLD_DI_SERINFOSIZE 5 /* ... query for required space. */ +#define RTLD_DI_ORIGIN 6 /* Obtain object origin */ +#define RTLD_DI_MAX RTLD_DI_ORIGIN + +/* + * Special handle arguments for dlsym()/dlinfo(). + */ +#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */ +#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */ +#define RTLD_SELF ((void *) -3) /* Search the caller itself. */ + +#if __BSD_VISIBLE + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +/* + * Structure filled in by dladdr(). + */ +typedef struct dl_info { + const char *dli_fname; /* Pathname of shared object. */ + void *dli_fbase; /* Base address of shared object. */ + const char *dli_sname; /* Name of nearest symbol. */ + void *dli_saddr; /* Address of nearest symbol. */ +} Dl_info; + +/*- + * The actual type declared by this typedef is immaterial, provided that + * it is a function pointer. Its purpose is to provide a return type for + * dlfunc() which can be cast to a function pointer type without depending + * on behavior undefined by the C standard, which might trigger a compiler + * diagnostic. We intentionally declare a unique type signature to force + * a diagnostic should the application not cast the return value of dlfunc() + * appropriately. + */ +struct __dlfunc_arg { + int __dlfunc_dummy; +}; + +typedef void (*dlfunc_t)(struct __dlfunc_arg); + +/* + * Structures, returned by the RTLD_DI_SERINFO dlinfo() request. + */ +typedef struct dl_serpath { + char * dls_name; /* single search path entry */ + unsigned int dls_flags; /* path information */ +} Dl_serpath; + +typedef struct dl_serinfo { + size_t dls_size; /* total buffer size */ + unsigned int dls_cnt; /* number of path entries */ + Dl_serpath dls_serpath[1]; /* there may be more than one */ +} Dl_serinfo; + +#endif /* __BSD_VISIBLE */ + +__BEGIN_DECLS +/* XSI functions first. */ +int dlclose(void *); +char *dlerror(void); +void *dlopen(const char *, int); +void *dlsym(void * __restrict, const char * __restrict); + +#if __BSD_VISIBLE +void *fdlopen(int, int); +int dladdr(const void * __restrict, Dl_info * __restrict); +dlfunc_t dlfunc(void * __restrict, const char * __restrict); +int dlinfo(void * __restrict, int, void * __restrict); +void dllockinit(void *_context, + void *(*_lock_create)(void *_context), + void (*_rlock_acquire)(void *_lock), + void (*_wlock_acquire)(void *_lock), + void (*_lock_release)(void *_lock), + void (*_lock_destroy)(void *_lock), + void (*_context_destroy)(void *_context)); +void *dlvsym(void * __restrict, const char * __restrict, + const char * __restrict); +#endif /* __BSD_VISIBLE */ +__END_DECLS + +#endif /* !_DLFCN_H_ */ diff --git a/include/elf-hints.h b/include/elf-hints.h new file mode 100644 index 0000000..0b2c00f --- /dev/null +++ b/include/elf-hints.h @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 1997 John D. Polstra. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/elf-hints.h 76224 2001-05-02 23:56:21Z obrien $ + */ + +#ifndef _ELF_HINTS_H_ +#define _ELF_HINTS_H_ + +/* + * Hints file produced by ldconfig. + */ +struct elfhints_hdr { + u_int32_t magic; /* Magic number */ + u_int32_t version; /* File version (1) */ + u_int32_t strtab; /* Offset of string table in file */ + u_int32_t strsize; /* Size of string table */ + u_int32_t dirlist; /* Offset of directory list in + string table */ + u_int32_t dirlistlen; /* strlen(dirlist) */ + u_int32_t spare[26]; /* Room for expansion */ +}; + +#define ELFHINTS_MAGIC 0x746e6845 + +#define _PATH_ELF_HINTS "/var/run/ld-elf.so.hints" + +#endif /* !_ELF_HINTS_H_ */ diff --git a/include/elf.h b/include/elf.h new file mode 100644 index 0000000..2ca5dbf --- /dev/null +++ b/include/elf.h @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2001 David E. O'Brien. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/elf.h 174044 2007-11-28 22:09:12Z jb $ + */ + +/* + * This is a Solaris compatibility header + */ + +#ifndef _ELF_H_ +#define _ELF_H_ + +#include +#include +#include +#include + +#endif /* !_ELF_H_ */ diff --git a/include/fmtmsg.h b/include/fmtmsg.h new file mode 100644 index 0000000..78a998c --- /dev/null +++ b/include/fmtmsg.h @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2002 Mike Barcroft + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/fmtmsg.h 236629 2012-06-05 19:42:57Z ed $ + */ + +#ifndef _FMTMSG_H_ +#define _FMTMSG_H_ + +/* Source of condition is... */ +#define MM_HARD 0x0001 /* ...hardware. */ +#define MM_SOFT 0x0002 /* ...software. */ +#define MM_FIRM 0x0004 /* ...firmware. */ + +/* Condition detected by... */ +#define MM_APPL 0x0010 /* ...application. */ +#define MM_UTIL 0x0020 /* ...utility. */ +#define MM_OPSYS 0x0040 /* ...operating system. */ + +/* Display on... */ +#define MM_PRINT 0x0100 /* ...standard error. */ +#define MM_CONSOLE 0x0200 /* ...system console. */ + +#define MM_RECOVER 0x1000 /* Recoverable error. */ +#define MM_NRECOV 0x2000 /* Non-recoverable error. */ + +/* Severity levels. */ +#define MM_NOSEV 0 /* No severity level provided. */ +#define MM_HALT 1 /* Error causing application to halt. */ +#define MM_ERROR 2 /* Non-fault fault. */ +#define MM_WARNING 3 /* Unusual non-error condition. */ +#define MM_INFO 4 /* Informative message. */ + +/* Null options. */ +#define MM_NULLLBL (char *)0 +#define MM_NULLSEV 0 +#define MM_NULLMC 0L +#define MM_NULLTXT (char *)0 +#define MM_NULLACT (char *)0 +#define MM_NULLTAG (char *)0 + +/* Return values. */ +#define MM_OK 0 /* Success. */ +#define MM_NOMSG 1 /* Failed to output to stderr. */ +#define MM_NOCON 2 /* Failed to output to console. */ +#define MM_NOTOK 3 /* Failed to output anything. */ + +int fmtmsg(long, const char *, int, const char *, const char *, + const char *); + +#endif /* !_FMTMSG_H_ */ diff --git a/include/fnmatch.h b/include/fnmatch.h new file mode 100644 index 0000000..0177f24 --- /dev/null +++ b/include/fnmatch.h @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 1992, 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. + * + * $FreeBSD: releng/11.1/include/fnmatch.h 203964 2010-02-16 19:39:50Z imp $ + * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _FNMATCH_H_ +#define _FNMATCH_H_ + +#include + +#define FNM_NOMATCH 1 /* Match failed. */ + +#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ +#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ +#define FNM_PERIOD 0x04 /* Period must be matched by period. */ + +#if __XSI_VISIBLE +#define FNM_NOSYS (-1) /* Reserved. */ +#endif + +#if __BSD_VISIBLE +#define FNM_LEADING_DIR 0x08 /* Ignore / after Imatch. */ +#define FNM_CASEFOLD 0x10 /* Case insensitive search. */ +#define FNM_IGNORECASE FNM_CASEFOLD +#define FNM_FILE_NAME FNM_PATHNAME +#endif + +__BEGIN_DECLS +int fnmatch(const char *, const char *, int); +__END_DECLS + +#endif /* !_FNMATCH_H_ */ diff --git a/include/fstab.h b/include/fstab.h new file mode 100644 index 0000000..b6c5436 --- /dev/null +++ b/include/fstab.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1980, 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. + * + * @(#)fstab.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: releng/11.1/include/fstab.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _FSTAB_H_ +#define _FSTAB_H_ + +/* + * File system table, see fstab(5). + * + * Used by dump, mount, umount, swapon, fsck, df, ... + * + * For ufs fs_spec field is the block special name. Programs that want to + * use the character special name must create that name by prepending a 'r' + * after the right most slash. Quota files are always named "quotas", so + * if type is "rq", then use concatenation of fs_file and "quotas" to locate + * quota file. + */ +#define _PATH_FSTAB "/etc/fstab" +#define FSTAB "/etc/fstab" /* deprecated */ + +#define FSTAB_RW "rw" /* read/write device */ +#define FSTAB_RQ "rq" /* read/write with quotas */ +#define FSTAB_RO "ro" /* read-only device */ +#define FSTAB_SW "sw" /* swap device */ +#define FSTAB_XX "xx" /* ignore totally */ + +struct fstab { + char *fs_spec; /* block special device name */ + char *fs_file; /* file system path prefix */ + char *fs_vfstype; /* File system type, ufs, nfs */ + char *fs_mntops; /* Mount options ala -o */ + char *fs_type; /* FSTAB_* from fs_mntops */ + int fs_freq; /* dump frequency, in days */ + int fs_passno; /* pass number on parallel fsck */ +}; + +#include + +__BEGIN_DECLS +struct fstab *getfsent(void); +struct fstab *getfsspec(const char *); +struct fstab *getfsfile(const char *); +int setfsent(void); +void endfsent(void); +void setfstab(const char *); +const char *getfstab(void); +__END_DECLS + +#endif /* !_FSTAB_H_ */ diff --git a/include/fts.h b/include/fts.h new file mode 100644 index 0000000..b41b25a --- /dev/null +++ b/include/fts.h @@ -0,0 +1,136 @@ +/* + * 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. + * + * @(#)fts.h 8.3 (Berkeley) 8/14/94 + * $FreeBSD: releng/11.1/include/fts.h 250887 2013-05-21 21:20:10Z ed $ + */ + +#ifndef _FTS_H_ +#define _FTS_H_ + +#include + +typedef struct { + struct _ftsent *fts_cur; /* current node */ + struct _ftsent *fts_child; /* linked list of children */ + struct _ftsent **fts_array; /* sort array */ + __dev_t fts_dev; /* starting device # */ + char *fts_path; /* path for this descent */ + int fts_rfd; /* fd for root */ + __size_t fts_pathlen; /* sizeof(path) */ + __size_t fts_nitems; /* elements in the sort array */ + int (*fts_compar) /* compare function */ + (const struct _ftsent * const *, const struct _ftsent * const *); + +#define FTS_COMFOLLOW 0x001 /* follow command line symlinks */ +#define FTS_LOGICAL 0x002 /* logical walk */ +#define FTS_NOCHDIR 0x004 /* don't change directories */ +#define FTS_NOSTAT 0x008 /* don't get stat info */ +#define FTS_PHYSICAL 0x010 /* physical walk */ +#define FTS_SEEDOT 0x020 /* return dot and dot-dot */ +#define FTS_XDEV 0x040 /* don't cross devices */ +#define FTS_WHITEOUT 0x080 /* return whiteout information */ +#define FTS_OPTIONMASK 0x0ff /* valid user option mask */ + +#define FTS_NAMEONLY 0x100 /* (private) child names only */ +#define FTS_STOP 0x200 /* (private) unrecoverable error */ + int fts_options; /* fts_open options, global flags */ + void *fts_clientptr; /* thunk for sort function */ +} FTS; + +typedef struct _ftsent { + struct _ftsent *fts_cycle; /* cycle node */ + struct _ftsent *fts_parent; /* parent directory */ + struct _ftsent *fts_link; /* next file in directory */ + long long fts_number; /* local numeric value */ +#define fts_bignum fts_number /* XXX non-std, should go away */ + void *fts_pointer; /* local address value */ + char *fts_accpath; /* access path */ + char *fts_path; /* root path */ + int fts_errno; /* errno for this node */ + int fts_symfd; /* fd for symlink */ + __size_t fts_pathlen; /* strlen(fts_path) */ + __size_t fts_namelen; /* strlen(fts_name) */ + + __ino_t fts_ino; /* inode */ + __dev_t fts_dev; /* device */ + __nlink_t fts_nlink; /* link count */ + +#define FTS_ROOTPARENTLEVEL -1 +#define FTS_ROOTLEVEL 0 + long fts_level; /* depth (-1 to N) */ + +#define FTS_D 1 /* preorder directory */ +#define FTS_DC 2 /* directory that causes cycles */ +#define FTS_DEFAULT 3 /* none of the above */ +#define FTS_DNR 4 /* unreadable directory */ +#define FTS_DOT 5 /* dot or dot-dot */ +#define FTS_DP 6 /* postorder directory */ +#define FTS_ERR 7 /* error; errno is set */ +#define FTS_F 8 /* regular file */ +#define FTS_INIT 9 /* initialized only */ +#define FTS_NS 10 /* stat(2) failed */ +#define FTS_NSOK 11 /* no stat(2) requested */ +#define FTS_SL 12 /* symbolic link */ +#define FTS_SLNONE 13 /* symbolic link without target */ +#define FTS_W 14 /* whiteout object */ + int fts_info; /* user status for FTSENT structure */ + +#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */ +#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */ +#define FTS_ISW 0x04 /* this is a whiteout object */ + unsigned fts_flags; /* private flags for FTSENT structure */ + +#define FTS_AGAIN 1 /* read node again */ +#define FTS_FOLLOW 2 /* follow symbolic link */ +#define FTS_NOINSTR 3 /* no instructions */ +#define FTS_SKIP 4 /* discard node */ + int fts_instr; /* fts_set() instructions */ + + struct stat *fts_statp; /* stat(2) information */ + char *fts_name; /* file name */ + FTS *fts_fts; /* back pointer to main FTS */ +} FTSENT; + +#include + +__BEGIN_DECLS +FTSENT *fts_children(FTS *, int); +int fts_close(FTS *); +void *fts_get_clientptr(FTS *); +#define fts_get_clientptr(fts) ((fts)->fts_clientptr) +FTS *fts_get_stream(FTSENT *); +#define fts_get_stream(ftsent) ((ftsent)->fts_fts) +FTS *fts_open(char * const *, int, + int (*)(const FTSENT * const *, const FTSENT * const *)); +FTSENT *fts_read(FTS *); +int fts_set(FTS *, FTSENT *, int); +void fts_set_clientptr(FTS *, void *); +__END_DECLS + +#endif /* !_FTS_H_ */ diff --git a/include/ftw.h b/include/ftw.h new file mode 100644 index 0000000..9dbdfd6 --- /dev/null +++ b/include/ftw.h @@ -0,0 +1,62 @@ +/* $OpenBSD: ftw.h,v 1.1 2003/07/21 21:13:18 millert Exp $ */ + +/* + * Copyright (c) 2003 Todd C. Miller + * + * 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. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + * + * $FreeBSD: releng/11.1/include/ftw.h 134244 2004-08-24 13:00:55Z tjr $ + */ + +#ifndef _FTW_H +#define _FTW_H + +#include +#include + +/* + * Valid flags for the 3rd argument to the function that is passed as the + * second argument to ftw(3) and nftw(3). Say it three times fast! + */ +#define FTW_F 0 /* File. */ +#define FTW_D 1 /* Directory. */ +#define FTW_DNR 2 /* Directory without read permission. */ +#define FTW_DP 3 /* Directory with subdirectories visited. */ +#define FTW_NS 4 /* Unknown type; stat() failed. */ +#define FTW_SL 5 /* Symbolic link. */ +#define FTW_SLN 6 /* Sym link that names a nonexistent file. */ + +/* + * Flags for use as the 4th argument to nftw(3). These may be ORed together. + */ +#define FTW_PHYS 0x01 /* Physical walk, don't follow sym links. */ +#define FTW_MOUNT 0x02 /* The walk does not cross a mount point. */ +#define FTW_DEPTH 0x04 /* Subdirs visited before the dir itself. */ +#define FTW_CHDIR 0x08 /* Change to a directory before reading it. */ + +struct FTW { + int base; + int level; +}; + +__BEGIN_DECLS +int ftw(const char *, int (*)(const char *, const struct stat *, int), int); +int nftw(const char *, int (*)(const char *, const struct stat *, int, + struct FTW *), int, int); +__END_DECLS + +#endif /* !_FTW_H */ diff --git a/include/getopt.h b/include/getopt.h new file mode 100644 index 0000000..7e9787c --- /dev/null +++ b/include/getopt.h @@ -0,0 +1,78 @@ +/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */ +/* $FreeBSD: releng/11.1/include/getopt.h 203963 2010-02-16 19:28:10Z imp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +#include + +/* + * GNU-like getopt_long()/getopt_long_only() with 4.4BSD optreset extension. + * getopt() is declared here too for GNU programs. + */ +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +struct option { + /* name of long option */ + const char *name; + /* + * one of no_argument, required_argument, and optional_argument: + * whether option takes an argument + */ + int has_arg; + /* if not NULL, set *flag to val when option found */ + int *flag; + /* if flag not NULL, value to set *flag to; else return value */ + int val; +}; + +__BEGIN_DECLS +int getopt_long(int, char * const *, const char *, + const struct option *, int *); +int getopt_long_only(int, char * const *, const char *, + const struct option *, int *); +#ifndef _GETOPT_DECLARED +#define _GETOPT_DECLARED +int getopt(int, char * const [], const char *); + +extern char *optarg; /* getopt(3) external variables */ +extern int optind, opterr, optopt; +#endif +#ifndef _OPTRESET_DECLARED +#define _OPTRESET_DECLARED +extern int optreset; /* getopt(3) external variable */ +#endif +__END_DECLS + +#endif /* !_GETOPT_H_ */ diff --git a/include/glob.h b/include/glob.h new file mode 100644 index 0000000..c0a0360 --- /dev/null +++ b/include/glob.h @@ -0,0 +1,106 @@ +/* + * 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. + * + * 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. + * + * @(#)glob.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: releng/11.1/include/glob.h 228754 2011-12-20 22:56:13Z eadler $ + */ + +#ifndef _GLOB_H_ +#define _GLOB_H_ + +#include +#include + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +struct stat; +typedef struct { + size_t gl_pathc; /* Count of total paths so far. */ + size_t gl_matchc; /* Count of paths matching pattern. */ + size_t gl_offs; /* Reserved at beginning of gl_pathv. */ + int gl_flags; /* Copy of flags parameter to glob. */ + char **gl_pathv; /* List of paths matching pattern. */ + /* Copy of errfunc parameter to glob. */ + int (*gl_errfunc)(const char *, int); + + /* + * Alternate filesystem access methods for glob; replacement + * versions of closedir(3), readdir(3), opendir(3), stat(2) + * and lstat(2). + */ + void (*gl_closedir)(void *); + struct dirent *(*gl_readdir)(void *); + void *(*gl_opendir)(const char *); + int (*gl_lstat)(const char *, struct stat *); + int (*gl_stat)(const char *, struct stat *); +} glob_t; + +#if __POSIX_VISIBLE >= 199209 +/* Believed to have been introduced in 1003.2-1992 */ +#define GLOB_APPEND 0x0001 /* Append to output from previous call. */ +#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ +#define GLOB_ERR 0x0004 /* Return on error. */ +#define GLOB_MARK 0x0008 /* Append / to matching directories. */ +#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ +#define GLOB_NOSORT 0x0020 /* Don't sort. */ +#define GLOB_NOESCAPE 0x2000 /* Disable backslash escaping. */ + +/* Error values returned by glob(3) */ +#define GLOB_NOSPACE (-1) /* Malloc call failed. */ +#define GLOB_ABORTED (-2) /* Unignored error. */ +#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK was not set. */ +#define GLOB_NOSYS (-4) /* Obsolete: source comptability only. */ +#endif /* __POSIX_VISIBLE >= 199209 */ + +#if __BSD_VISIBLE +#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ +#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ +#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ +#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */ +#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ +#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ +#define GLOB_LIMIT 0x1000 /* limit number of returned paths */ + +/* source compatibility, these are the old names */ +#define GLOB_MAXPATH GLOB_LIMIT +#define GLOB_ABEND GLOB_ABORTED +#endif /* __BSD_VISIBLE */ + +__BEGIN_DECLS +int glob(const char * __restrict, int, + int (*)(const char *, int), glob_t * __restrict); +void globfree(glob_t *); +__END_DECLS + +#endif /* !_GLOB_H_ */ diff --git a/include/grp.h b/include/grp.h new file mode 100644 index 0000000..0a96a84 --- /dev/null +++ b/include/grp.h @@ -0,0 +1,93 @@ +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (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. + * + * 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. + * + * @(#)grp.h 8.2 (Berkeley) 1/21/94 + * $FreeBSD: releng/11.1/include/grp.h 265878 2014-05-11 13:48:21Z jilles $ + */ + +#ifndef _GRP_H_ +#define _GRP_H_ + +#include +#include + +#define _PATH_GROUP "/etc/group" + +#ifndef _GID_T_DECLARED +typedef __gid_t gid_t; +#define _GID_T_DECLARED +#endif + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +struct group { + char *gr_name; /* group name */ + char *gr_passwd; /* group password */ + gid_t gr_gid; /* group id */ + char **gr_mem; /* group members */ +}; + +__BEGIN_DECLS +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE +void endgrent(void); +struct group *getgrent(void); +#endif +struct group *getgrgid(gid_t); +struct group *getgrnam(const char *); +#if __BSD_VISIBLE +const char *group_from_gid(gid_t, int); +int gid_from_group(const char *, gid_t *); +int pwcache_groupdb(int (*)(int), void (*)(void), + struct group * (*)(const char *), + struct group * (*)(gid_t)); +#endif +#if __XSI_VISIBLE +/* XXX IEEE Std 1003.1, 2003 specifies `void setgrent(void)' */ +int setgrent(void); +#endif +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE +int getgrgid_r(gid_t, struct group *, char *, size_t, + struct group **); +int getgrnam_r(const char *, struct group *, char *, size_t, + struct group **); +#endif +#if __BSD_VISIBLE +int getgrent_r(struct group *, char *, size_t, struct group **); +int setgroupent(int); +#endif +__END_DECLS + +#endif /* !_GRP_H_ */ diff --git a/include/gssapi.h b/include/gssapi.h new file mode 100644 index 0000000..3efac0c --- /dev/null +++ b/include/gssapi.h @@ -0,0 +1,5 @@ +/* $FreeBSD: releng/11.1/include/gssapi.h 153838 2005-12-29 14:40:22Z dfr $ */ +#ifdef __GNUC__ +#warning "this file includes which is deprecated, use instead" +#endif +#include diff --git a/include/gssapi/Makefile b/include/gssapi/Makefile new file mode 100644 index 0000000..e3e8c8b --- /dev/null +++ b/include/gssapi/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD: releng/11.1/include/gssapi/Makefile 284255 2015-06-11 04:22:17Z sjg $ + +INCS= gssapi.h +INCSDIR= ${INCLUDEDIR}/gssapi + +.include diff --git a/include/gssapi/Makefile.depend b/include/gssapi/Makefile.depend new file mode 100644 index 0000000..026e7d9 --- /dev/null +++ b/include/gssapi/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD: releng/11.1/include/gssapi/Makefile.depend 284345 2015-06-13 19:20:56Z sjg $ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/include/gssapi/gssapi.h b/include/gssapi/gssapi.h new file mode 100644 index 0000000..1764712 --- /dev/null +++ b/include/gssapi/gssapi.h @@ -0,0 +1,876 @@ +/* + * Copyright (C) The Internet Society (2000). All Rights Reserved. + * + * This document and translations of it may be copied and furnished to + * others, and derivative works that comment on or otherwise explain it + * or assist in its implementation may be prepared, copied, published + * and distributed, in whole or in part, without restriction of any + * kind, provided that the above copyright notice and this paragraph are + * included on all such copies and derivative works. However, this + * document itself may not be modified in any way, such as by removing + * the copyright notice or references to the Internet Society or other + * Internet organizations, except as needed for the purpose of + * developing Internet standards in which case the procedures for + * copyrights defined in the Internet Standards process must be + * followed, or as required to translate it into languages other than + * English. + * + * The limited permissions granted above are perpetual and will not be + * revoked by the Internet Society or its successors or assigns. + * + * This document and the information contained herein is provided on an + * "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + * TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * $FreeBSD: releng/11.1/include/gssapi/gssapi.h 252409 2013-06-30 07:46:22Z hrs $ + */ + +#ifndef _GSSAPI_GSSAPI_H_ +#define _GSSAPI_GSSAPI_H_ + +#include +#include + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +#ifndef _SSIZE_T_DECLARED +typedef __ssize_t ssize_t; +#define _SSIZE_T_DECLARED +#endif + +/* Compatibility with Heimdal 1.5.1 */ +#ifndef GSSAPI_CPP_START +#ifdef __cplusplus +#define GSSAPI_CPP_START extern "C" { +#define GSSAPI_CPP_END } +#else +#define GSSAPI_CPP_START +#define GSSAPI_CPP_END +#endif +#endif + +/* Compatibility with Heimdal 1.5.1 */ +#ifndef BUILD_GSSAPI_LIB +#define GSSAPI_LIB_FUNCTION +#define GSSAPI_LIB_CALL +#define GSSAPI_LIB_VARIABLE +#endif + +/* Compatibility with Heimdal 1.5.1 */ +#ifndef GSSAPI_DEPRECATED_FUNCTION +#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 ))) +#define GSSAPI_DEPRECATED_FUNCTION(X) __attribute__((deprecated)) +#else +#define GSSAPI_DEPRECATED_FUNCTION(X) +#endif +#endif + +#if 0 +/* + * If the platform supports the xom.h header file, it should be + * included here. + */ +#include +#endif + + +/* + * Now define the three implementation-dependent types. + */ +typedef struct _gss_ctx_id_t *gss_ctx_id_t; +typedef struct _gss_cred_id_t *gss_cred_id_t; +typedef struct _gss_name_t *gss_name_t; + +/* + * The following type must be defined as the smallest natural + * unsigned integer supported by the platform that has at least + * 32 bits of precision. + */ +typedef __uint32_t gss_uint32; + + +#ifdef OM_STRING +/* + * We have included the xom.h header file. Verify that OM_uint32 + * is defined correctly. + */ + +#if sizeof(gss_uint32) != sizeof(OM_uint32) +#error Incompatible definition of OM_uint32 from xom.h +#endif + +typedef OM_object_identifier gss_OID_desc, *gss_OID; + +#else + +/* + * We can't use X/Open definitions, so roll our own. + */ + +typedef gss_uint32 OM_uint32; +typedef __uint64_t OM_uint64; + +typedef struct gss_OID_desc_struct { + OM_uint32 length; + void *elements; +} gss_OID_desc, *gss_OID; + +#endif + +typedef struct gss_OID_set_desc_struct { + size_t count; + gss_OID elements; +} gss_OID_set_desc, *gss_OID_set; + +typedef struct gss_buffer_desc_struct { + size_t length; + void *value; +} gss_buffer_desc, *gss_buffer_t; + +typedef struct gss_channel_bindings_struct { + OM_uint32 initiator_addrtype; + gss_buffer_desc initiator_address; + OM_uint32 acceptor_addrtype; + gss_buffer_desc acceptor_address; + gss_buffer_desc application_data; +} *gss_channel_bindings_t; + +/* + * For now, define a QOP-type as an OM_uint32 + */ +typedef OM_uint32 gss_qop_t; + +typedef int gss_cred_usage_t; + +/* + * Flag bits for context-level services. + */ +#define GSS_C_DELEG_FLAG 1 +#define GSS_C_MUTUAL_FLAG 2 +#define GSS_C_REPLAY_FLAG 4 +#define GSS_C_SEQUENCE_FLAG 8 +#define GSS_C_CONF_FLAG 16 +#define GSS_C_INTEG_FLAG 32 +#define GSS_C_ANON_FLAG 64 +#define GSS_C_PROT_READY_FLAG 128 +#define GSS_C_TRANS_FLAG 256 + +/* + * Credential usage options + */ +#define GSS_C_BOTH 0 +#define GSS_C_INITIATE 1 +#define GSS_C_ACCEPT 2 + +/* + * Status code types for gss_display_status + */ +#define GSS_C_GSS_CODE 1 +#define GSS_C_MECH_CODE 2 + +/* + * The constant definitions for channel-bindings address families + */ +#define GSS_C_AF_UNSPEC 0 +#define GSS_C_AF_LOCAL 1 +#define GSS_C_AF_INET 2 +#define GSS_C_AF_IMPLINK 3 +#define GSS_C_AF_PUP 4 +#define GSS_C_AF_CHAOS 5 +#define GSS_C_AF_NS 6 +#define GSS_C_AF_NBS 7 +#define GSS_C_AF_ECMA 8 +#define GSS_C_AF_DATAKIT 9 +#define GSS_C_AF_CCITT 10 +#define GSS_C_AF_SNA 11 +#define GSS_C_AF_DECnet 12 +#define GSS_C_AF_DLI 13 +#define GSS_C_AF_LAT 14 +#define GSS_C_AF_HYLINK 15 +#define GSS_C_AF_APPLETALK 16 +#define GSS_C_AF_BSC 17 +#define GSS_C_AF_DSS 18 +#define GSS_C_AF_OSI 19 +#define GSS_C_AF_X25 21 +#define GSS_C_AF_NULLADDR 255 + +/* + * Various Null values + */ +#define GSS_C_NO_NAME ((gss_name_t) 0) +#define GSS_C_NO_BUFFER ((gss_buffer_t) 0) +#define GSS_C_NO_OID ((gss_OID) 0) +#define GSS_C_NO_OID_SET ((gss_OID_set) 0) +#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0) +#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0) +#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0) +#define GSS_C_EMPTY_BUFFER {0, NULL} + +/* + * Some alternate names for a couple of the above + * values. These are defined for V1 compatibility. + */ +#define GSS_C_NULL_OID GSS_C_NO_OID +#define GSS_C_NULL_OID_SET GSS_C_NO_OID_SET + +/* + * Define the default Quality of Protection for per-message + * services. Note that an implementation that offers multiple + * levels of QOP may define GSS_C_QOP_DEFAULT to be either zero + * (as done here) to mean "default protection", or to a specific + * explicit QOP value. However, a value of 0 should always be + * interpreted by a GSS-API implementation as a request for the + * default protection level. + */ +#define GSS_C_QOP_DEFAULT 0 + +/* + * Expiration time of 2^32-1 seconds means infinite lifetime for a + * credential or security context + */ +#define GSS_C_INDEFINITE 0xfffffffful + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" + * "\x01\x02\x01\x01"}, + * corresponding to an object-identifier value of + * {iso(1) member-body(2) United States(840) mit(113554) + * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant + * GSS_C_NT_USER_NAME should be initialized to point + * to that gss_OID_desc. + */ +extern gss_OID GSS_C_NT_USER_NAME; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" + * "\x01\x02\x01\x02"}, + * corresponding to an object-identifier value of + * {iso(1) member-body(2) United States(840) mit(113554) + * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}. + * The constant GSS_C_NT_MACHINE_UID_NAME should be + * initialized to point to that gss_OID_desc. + */ +extern gss_OID GSS_C_NT_MACHINE_UID_NAME; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" + * "\x01\x02\x01\x03"}, + * corresponding to an object-identifier value of + * {iso(1) member-body(2) United States(840) mit(113554) + * infosys(1) gssapi(2) generic(1) string_uid_name(3)}. + * The constant GSS_C_NT_STRING_UID_NAME should be + * initialized to point to that gss_OID_desc. + */ +extern gss_OID GSS_C_NT_STRING_UID_NAME; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {6, (void *)"\x2b\x06\x01\x05\x06\x02"}, + * corresponding to an object-identifier value of + * {iso(1) org(3) dod(6) internet(1) security(5) + * nametypes(6) gss-host-based-services(2)). The constant + * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point + * to that gss_OID_desc. This is a deprecated OID value, and + * implementations wishing to support hostbased-service names + * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID, + * defined below, to identify such names; + * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym + * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input + * parameter, but should not be emitted by GSS-API + * implementations + */ +extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {10, (void *)"\x2a\x86\x48\x86\xf7\x12" + * "\x01\x02\x01\x04"}, corresponding to an + * object-identifier value of {iso(1) member-body(2) + * Unites States(840) mit(113554) infosys(1) gssapi(2) + * generic(1) service_name(4)}. The constant + * GSS_C_NT_HOSTBASED_SERVICE should be initialized + * to point to that gss_OID_desc. + */ +extern gss_OID GSS_C_NT_HOSTBASED_SERVICE; + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {6, (void *)"\x2b\x06\01\x05\x06\x03"}, + * corresponding to an object identifier value of + * {1(iso), 3(org), 6(dod), 1(internet), 5(security), + * 6(nametypes), 3(gss-anonymous-name)}. The constant + * and GSS_C_NT_ANONYMOUS should be initialized to point + * to that gss_OID_desc. + */ +extern gss_OID GSS_C_NT_ANONYMOUS; + + +/* + * The implementation must reserve static storage for a + * gss_OID_desc object containing the value + * {6, (void *)"\x2b\x06\x01\x05\x06\x04"}, + * corresponding to an object-identifier value of + * {1(iso), 3(org), 6(dod), 1(internet), 5(security), + * 6(nametypes), 4(gss-api-exported-name)}. The constant + * GSS_C_NT_EXPORT_NAME should be initialized to point + * to that gss_OID_desc. + */ +extern gss_OID GSS_C_NT_EXPORT_NAME; + +/* + * This name form shall be represented by the Object Identifier {iso(1) + * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) + * krb5(2) krb5_name(1)}. The recommended symbolic name for this type + * is "GSS_KRB5_NT_PRINCIPAL_NAME". + */ +extern gss_OID GSS_KRB5_NT_PRINCIPAL_NAME; + +/* + * This name form shall be represented by the Object Identifier {iso(1) + * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) + * generic(1) user_name(1)}. The recommended symbolic name for this + * type is "GSS_KRB5_NT_USER_NAME". + */ +extern gss_OID GSS_KRB5_NT_USER_NAME; + +/* + * This name form shall be represented by the Object Identifier {iso(1) + * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) + * generic(1) machine_uid_name(2)}. The recommended symbolic name for + * this type is "GSS_KRB5_NT_MACHINE_UID_NAME". + */ +extern gss_OID GSS_KRB5_NT_MACHINE_UID_NAME; + +/* + * This name form shall be represented by the Object Identifier {iso(1) + * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) + * generic(1) string_uid_name(3)}. The recommended symbolic name for + * this type is "GSS_KRB5_NT_STRING_UID_NAME". + */ +extern gss_OID GSS_KRB5_NT_STRING_UID_NAME; + +/* Major status codes */ + +#define GSS_S_COMPLETE 0 + +/* + * Some "helper" definitions to make the status code macros obvious. + */ +#define GSS_C_CALLING_ERROR_OFFSET 24 +#define GSS_C_ROUTINE_ERROR_OFFSET 16 +#define GSS_C_SUPPLEMENTARY_OFFSET 0 +#define GSS_C_CALLING_ERROR_MASK 0377ul +#define GSS_C_ROUTINE_ERROR_MASK 0377ul +#define GSS_C_SUPPLEMENTARY_MASK 0177777ul + +/* + * The macros that test status codes for error conditions. + * Note that the GSS_ERROR() macro has changed slightly from + * the V1 GSS-API so that it now evaluates its argument + * only once. + */ +#define GSS_CALLING_ERROR(x) \ + (x & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET)) +#define GSS_ROUTINE_ERROR(x) \ + (x & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)) +#define GSS_SUPPLEMENTARY_INFO(x) \ + (x & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET)) +#define GSS_ERROR(x) \ + (x & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \ + (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))) + +/* + * Now the actual status code definitions + */ + +/* + * Calling errors: + */ +#define GSS_S_CALL_INACCESSIBLE_READ \ +(1ul << GSS_C_CALLING_ERROR_OFFSET) +#define GSS_S_CALL_INACCESSIBLE_WRITE \ +(2ul << GSS_C_CALLING_ERROR_OFFSET) +#define GSS_S_CALL_BAD_STRUCTURE \ +(3ul << GSS_C_CALLING_ERROR_OFFSET) + +/* + * Routine errors: + */ +#define GSS_S_BAD_MECH (1ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_NAME (2ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_NAMETYPE (3ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_BINDINGS (4ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_STATUS (5ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_SIG (6ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_MIC GSS_S_BAD_SIG +#define GSS_S_NO_CRED (7ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NO_CONTEXT (8ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DEFECTIVE_TOKEN (9ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DEFECTIVE_CREDENTIAL (10ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_CREDENTIALS_EXPIRED (11ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_CONTEXT_EXPIRED (12ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_FAILURE (13ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_BAD_QOP (14ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_UNAUTHORIZED (15ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_UNAVAILABLE (16ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_DUPLICATE_ELEMENT (17ul << GSS_C_ROUTINE_ERROR_OFFSET) +#define GSS_S_NAME_NOT_MN (18ul << GSS_C_ROUTINE_ERROR_OFFSET) + +/* + * Supplementary info bits: + */ +#define GSS_S_CONTINUE_NEEDED \ + (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 0)) +#define GSS_S_DUPLICATE_TOKEN \ + (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 1)) +#define GSS_S_OLD_TOKEN \ + (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 2)) +#define GSS_S_UNSEQ_TOKEN \ + (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3)) +#define GSS_S_GAP_TOKEN \ + (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 4)) + +__BEGIN_DECLS + +/* + * Finally, function prototypes for the GSS-API routines. + */ +OM_uint32 gss_acquire_cred + (OM_uint32 *, /* minor_status */ + const gss_name_t, /* desired_name */ + OM_uint32, /* time_req */ + const gss_OID_set, /* desired_mechs */ + gss_cred_usage_t, /* cred_usage */ + gss_cred_id_t *, /* output_cred_handle */ + gss_OID_set *, /* actual_mechs */ + OM_uint32 * /* time_rec */ + ); + +OM_uint32 gss_release_cred + (OM_uint32 *, /* minor_status */ + gss_cred_id_t * /* cred_handle */ + ); + +OM_uint32 gss_init_sec_context + (OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* initiator_cred_handle */ + gss_ctx_id_t *, /* context_handle */ + const gss_name_t, /* target_name */ + const gss_OID, /* mech_type */ + OM_uint32, /* req_flags */ + OM_uint32, /* time_req */ + const gss_channel_bindings_t, + /* input_chan_bindings */ + const gss_buffer_t, /* input_token */ + gss_OID *, /* actual_mech_type */ + gss_buffer_t, /* output_token */ + OM_uint32 *, /* ret_flags */ + OM_uint32 * /* time_rec */ + ); + +OM_uint32 gss_accept_sec_context + (OM_uint32 *, /* minor_status */ + gss_ctx_id_t *, /* context_handle */ + const gss_cred_id_t, /* acceptor_cred_handle */ + const gss_buffer_t, /* input_token_buffer */ + const gss_channel_bindings_t, + /* input_chan_bindings */ + gss_name_t *, /* src_name */ + gss_OID *, /* mech_type */ + gss_buffer_t, /* output_token */ + OM_uint32 *, /* ret_flags */ + OM_uint32 *, /* time_rec */ + gss_cred_id_t * /* delegated_cred_handle */ + ); + +OM_uint32 gss_process_context_token + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + const gss_buffer_t /* token_buffer */ + ); + +OM_uint32 gss_delete_sec_context + (OM_uint32 *, /* minor_status */ + gss_ctx_id_t *, /* context_handle */ + gss_buffer_t /* output_token */ + ); + +OM_uint32 gss_context_time + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + OM_uint32 * /* time_rec */ + ); + +OM_uint32 gss_get_mic + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + gss_qop_t, /* qop_req */ + const gss_buffer_t, /* message_buffer */ + gss_buffer_t /* message_token */ + ); + +OM_uint32 gss_verify_mic + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + const gss_buffer_t, /* message_buffer */ + const gss_buffer_t, /* token_buffer */ + gss_qop_t * /* qop_state */ + ); + +OM_uint32 gss_wrap + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + gss_qop_t, /* qop_req */ + const gss_buffer_t, /* input_message_buffer */ + int *, /* conf_state */ + gss_buffer_t /* output_message_buffer */ + ); + +OM_uint32 gss_unwrap + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + const gss_buffer_t, /* input_message_buffer */ + gss_buffer_t, /* output_message_buffer */ + int *, /* conf_state */ + gss_qop_t * /* qop_state */ + ); + +OM_uint32 gss_display_status + (OM_uint32 *, /* minor_status */ + OM_uint32, /* status_value */ + int, /* status_type */ + const gss_OID, /* mech_type */ + OM_uint32 *, /* message_context */ + gss_buffer_t /* status_string */ + ); + +OM_uint32 gss_indicate_mechs + (OM_uint32 *, /* minor_status */ + gss_OID_set * /* mech_set */ + ); + +OM_uint32 gss_compare_name + (OM_uint32 *, /* minor_status */ + const gss_name_t, /* name1 */ + const gss_name_t, /* name2 */ + int * /* name_equal */ + ); + +OM_uint32 gss_display_name + (OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_buffer_t, /* output_name_buffer */ + gss_OID * /* output_name_type */ + ); + +OM_uint32 gss_import_name + (OM_uint32 *, /* minor_status */ + const gss_buffer_t, /* input_name_buffer */ + const gss_OID, /* input_name_type */ + gss_name_t * /* output_name */ + ); + +OM_uint32 gss_export_name + (OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_buffer_t /* exported_name */ + ); + +OM_uint32 gss_release_name + (OM_uint32 *, /* minor_status */ + gss_name_t * /* input_name */ + ); + +OM_uint32 gss_release_buffer + (OM_uint32 *, /* minor_status */ + gss_buffer_t /* buffer */ + ); + +OM_uint32 gss_release_oid_set + (OM_uint32 *, /* minor_status */ + gss_OID_set * /* set */ + ); + +OM_uint32 gss_inquire_cred + (OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* cred_handle */ + gss_name_t *, /* name */ + OM_uint32 *, /* lifetime */ + gss_cred_usage_t *, /* cred_usage */ + gss_OID_set * /* mechanisms */ + ); + +OM_uint32 gss_inquire_context ( + OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + gss_name_t *, /* src_name */ + gss_name_t *, /* targ_name */ + OM_uint32 *, /* lifetime_rec */ + gss_OID *, /* mech_type */ + OM_uint32 *, /* ctx_flags */ + int *, /* locally_initiated */ + int * /* open */ + ); + +OM_uint32 gss_wrap_size_limit ( + OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + gss_qop_t, /* qop_req */ + OM_uint32, /* req_output_size */ + OM_uint32 * /* max_input_size */ + ); + +OM_uint32 gss_add_cred ( + OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* input_cred_handle */ + const gss_name_t, /* desired_name */ + const gss_OID, /* desired_mech */ + gss_cred_usage_t, /* cred_usage */ + OM_uint32, /* initiator_time_req */ + OM_uint32, /* acceptor_time_req */ + gss_cred_id_t *, /* output_cred_handle */ + gss_OID_set *, /* actual_mechs */ + OM_uint32 *, /* initiator_time_rec */ + OM_uint32 * /* acceptor_time_rec */ + ); + +OM_uint32 gss_inquire_cred_by_mech ( + OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* cred_handle */ + const gss_OID, /* mech_type */ + gss_name_t *, /* name */ + OM_uint32 *, /* initiator_lifetime */ + OM_uint32 *, /* acceptor_lifetime */ + gss_cred_usage_t * /* cred_usage */ + ); + +OM_uint32 gss_export_sec_context ( + OM_uint32 *, /* minor_status */ + gss_ctx_id_t *, /* context_handle */ + gss_buffer_t /* interprocess_token */ + ); + +OM_uint32 gss_import_sec_context ( + OM_uint32 *, /* minor_status */ + const gss_buffer_t, /* interprocess_token */ + gss_ctx_id_t * /* context_handle */ + ); + +OM_uint32 gss_create_empty_oid_set ( + OM_uint32 *, /* minor_status */ + gss_OID_set * /* oid_set */ + ); + +OM_uint32 gss_add_oid_set_member ( + OM_uint32 *, /* minor_status */ + const gss_OID, /* member_oid */ + gss_OID_set * /* oid_set */ + ); + +OM_uint32 gss_test_oid_set_member ( + OM_uint32 *, /* minor_status */ + const gss_OID, /* member */ + const gss_OID_set, /* set */ + int * /* present */ + ); + +OM_uint32 gss_inquire_names_for_mech ( + OM_uint32 *, /* minor_status */ + const gss_OID, /* mechanism */ + gss_OID_set * /* name_types */ + ); + +OM_uint32 gss_inquire_mechs_for_name ( + OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_OID_set * /* mech_types */ + ); + +OM_uint32 gss_canonicalize_name ( + OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + const gss_OID, /* mech_type */ + gss_name_t * /* output_name */ + ); + +OM_uint32 gss_duplicate_name ( + OM_uint32 *, /* minor_status */ + const gss_name_t, /* src_name */ + gss_name_t * /* dest_name */ + ); + +/* + * The following routines are obsolete variants of gss_get_mic, + * gss_verify_mic, gss_wrap and gss_unwrap. They should be + * provided by GSS-API V2 implementations for backwards + * compatibility with V1 applications. Distinct entrypoints + * (as opposed to #defines) should be provided, both to allow + * GSS-API V1 applications to link against GSS-API V2 implementations, + * and to retain the slight parameter type differences between the + * obsolete versions of these routines and their current forms. + */ + +OM_uint32 gss_sign + (OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* qop_req */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t /* message_token */ + ); + + +OM_uint32 gss_verify + (OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* token_buffer */ + int * /* qop_state */ + ); + +OM_uint32 gss_seal + (OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + int, /* qop_req */ + gss_buffer_t, /* input_message_buffer */ + int *, /* conf_state */ + gss_buffer_t /* output_message_buffer */ + ); + + +OM_uint32 gss_unseal + (OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* input_message_buffer */ + gss_buffer_t, /* output_message_buffer */ + int *, /* conf_state */ + int * /* qop_state */ + ); + +/* + * Other extensions and helper functions. + */ + +int gss_oid_equal + (const gss_OID, /* first OID to compare */ + const gss_OID /* second OID to compare */ + ); + +OM_uint32 gss_release_oid + (OM_uint32 *, /* minor status */ + gss_OID * /* oid to free */ + ); + +OM_uint32 gss_decapsulate_token + (const gss_buffer_t, /* mechanism independent token */ + gss_OID, /* desired mechanism */ + gss_buffer_t /* decapsulated mechanism dependent token */ + ); + +OM_uint32 gss_encapsulate_token + (const gss_buffer_t, /* mechanism dependent token */ + gss_OID, /* desired mechanism */ + gss_buffer_t /* encapsulated mechanism independent token */ + ); + +OM_uint32 gss_duplicate_oid + (OM_uint32 *, /* minor status */ + const gss_OID, /* oid to copy */ + gss_OID * /* result */ + ); + +OM_uint32 gss_oid_to_str + (OM_uint32 *, /* minor status */ + gss_OID, /* oid to convert */ + gss_buffer_t /* buffer to contain string */ + ); + +typedef struct gss_buffer_set_desc_struct { + size_t count; + gss_buffer_desc *elements; +} gss_buffer_set_desc, *gss_buffer_set_t; + +#define GSS_C_NO_BUFFER_SET ((gss_buffer_set_t) 0) + +OM_uint32 gss_create_empty_buffer_set + (OM_uint32 *, /* minor status */ + gss_buffer_set_t * /* location for new buffer set */ + ); + +OM_uint32 gss_add_buffer_set_member + (OM_uint32 *, /* minor status */ + gss_buffer_t, /* buffer to add */ + gss_buffer_set_t * /* set to add to */ + ); + +OM_uint32 gss_release_buffer_set + (OM_uint32 *, /* minor status */ + gss_buffer_set_t * /* set to release */ + ); + +OM_uint32 gss_inquire_sec_context_by_oid + (OM_uint32 *, /* minor_status */ + const gss_ctx_id_t, /* context_handle */ + const gss_OID, /* desired_object */ + gss_buffer_set_t * /* result */ + ); + +OM_uint32 gss_inquire_cred_by_oid + (OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* cred_handle */ + const gss_OID, /* desired_object */ + gss_buffer_set_t * /* result */ + ); + +OM_uint32 gss_set_sec_context_option + (OM_uint32 *, /* minor status */ + gss_ctx_id_t *, /* context */ + const gss_OID, /* option to set */ + const gss_buffer_t /* option value */ + ); + +OM_uint32 gss_set_cred_option + (OM_uint32 *, /* minor status */ + gss_cred_id_t *, /* cred */ + const gss_OID, /* option to set */ + const gss_buffer_t /* option value */ + ); + +OM_uint32 gss_pseudo_random + (OM_uint32 *, /* minor status */ + gss_ctx_id_t, /* context handle */ + int prf_key, /* XXX */ + const gss_buffer_t, /* data to seed generator */ + ssize_t, /* amount of data required */ + gss_buffer_t /* buffer for result */ + ); + +#ifdef _UID_T_DECLARED +OM_uint32 gss_pname_to_uid + (OM_uint32 *, /* minor status */ + const gss_name_t pname, /* principal name */ + const gss_OID mech, /* mechanism to query */ + uid_t *uidp /* pointer to UID for result */ + ); +#endif + +__END_DECLS + +#endif /* _GSSAPI_GSSAPI_H_ */ diff --git a/include/hesiod.h b/include/hesiod.h new file mode 100644 index 0000000..f7420ee --- /dev/null +++ b/include/hesiod.h @@ -0,0 +1,91 @@ +/* $NetBSD: hesiod.h,v 1.3 1999/01/24 23:53:18 lukem Exp $ */ +/* $FreeBSD: releng/11.1/include/hesiod.h 203963 2010-02-16 19:28:10Z imp $ */ + + +/*- + * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM 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. + */ + +#ifndef _HESIOD_H_ +#define _HESIOD_H_ + + /* Application-visible indication that we have the new interfaces */ + +#define HESIOD_INTERFACES + + /* Configuration information. */ + +#ifndef _PATH_HESIOD_CONF /* Configuration file. */ +#define _PATH_HESIOD_CONF "/etc/hesiod.conf" +#endif + +#define DEF_RHS "" /* Defaults if HESIOD_CONF */ +#define DEF_LHS "" /* file is not present. */ + + /* Error codes (for backwards compatibility) */ + +#define HES_ER_UNINIT -1 /* uninitialized */ +#define HES_ER_OK 0 /* no error */ +#define HES_ER_NOTFOUND 1 /* Hesiod name not found by server */ +#define HES_ER_CONFIG 2 /* local problem (no config file?) */ +#define HES_ER_NET 3 /* network problem */ + + /* Declaration of routines */ + +#include + +__BEGIN_DECLS +int hesiod_init(void **); +char **hesiod_resolve(void *, const char *, const char *); +void hesiod_free_list(void *, char **); +char *hesiod_to_bind(void *, const char *, const char *); +void hesiod_end(void *); + + /* backwards compatibility */ +int hes_init(void); +char *hes_to_bind(const char *, const char *); +char **hes_resolve(const char *, const char *); +int hes_error(void); +void hes_free(char **); +__END_DECLS + +#endif /* ! _HESIOD_H_ */ diff --git a/include/iconv.h b/include/iconv.h new file mode 100644 index 0000000..d246523 --- /dev/null +++ b/include/iconv.h @@ -0,0 +1,133 @@ +/* $FreeBSD: releng/11.1/include/iconv.h 281550 2015-04-15 09:09:20Z tijl $ */ +/* $NetBSD: iconv.h,v 1.6 2005/02/03 04:39:32 perry Exp $ */ + +/*- + * Copyright (c) 2003 Citrus Project, + * Copyright (c) 2009, 2010 Gabor Kovesdan + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + */ + +#ifndef _ICONV_H_ +#define _ICONV_H_ + +#include +#include + +#include + +#include +#include + +#ifdef __cplusplus +typedef bool __iconv_bool; +#elif __STDC_VERSION__ >= 199901L +typedef _Bool __iconv_bool; +#else +typedef int __iconv_bool; +#endif + +struct __tag_iconv_t; +typedef struct __tag_iconv_t *iconv_t; + +__BEGIN_DECLS +iconv_t iconv_open(const char *, const char *); +size_t iconv(iconv_t, char ** __restrict, + size_t * __restrict, char ** __restrict, + size_t * __restrict); +int iconv_close(iconv_t); +/* + * non-portable interfaces for iconv + */ +int __iconv_get_list(char ***, size_t *, __iconv_bool); +void __iconv_free_list(char **, size_t); +size_t __iconv(iconv_t, char **, size_t *, char **, + size_t *, __uint32_t, size_t *); +#define __ICONV_F_HIDE_INVALID 0x0001 + +/* + * GNU interfaces for iconv + */ +typedef struct { + void *spaceholder[64]; +} iconv_allocation_t; + +int iconv_open_into(const char *, const char *, iconv_allocation_t *); +void iconv_set_relocation_prefix(const char *, const char *); + +/* + * iconvctl() request macros + */ +#define ICONV_TRIVIALP 0 +#define ICONV_GET_TRANSLITERATE 1 +#define ICONV_SET_TRANSLITERATE 2 +#define ICONV_GET_DISCARD_ILSEQ 3 +#define ICONV_SET_DISCARD_ILSEQ 4 +#define ICONV_SET_HOOKS 5 +#define ICONV_SET_FALLBACKS 6 +#define ICONV_GET_ILSEQ_INVALID 128 +#define ICONV_SET_ILSEQ_INVALID 129 + +typedef void (*iconv_unicode_char_hook) (unsigned int mbr, void *data); +typedef void (*iconv_wide_char_hook) (wchar_t wc, void *data); + +struct iconv_hooks { + iconv_unicode_char_hook uc_hook; + iconv_wide_char_hook wc_hook; + void *data; +}; + +/* + * Fallbacks aren't supported but type definitions are provided for + * source compatibility. + */ +typedef void (*iconv_unicode_mb_to_uc_fallback) (const char*, + size_t, void (*write_replacement) (const unsigned int *, + size_t, void*), void*, void*); +typedef void (*iconv_unicode_uc_to_mb_fallback) (unsigned int, + void (*write_replacement) (const char *, size_t, void*), + void*, void*); +typedef void (*iconv_wchar_mb_to_wc_fallback) (const char*, size_t, + void (*write_replacement) (const wchar_t *, size_t, void*), + void*, void*); +typedef void (*iconv_wchar_wc_to_mb_fallback) (wchar_t, + void (*write_replacement) (const char *, size_t, void*), + void*, void*); + +struct iconv_fallbacks { + iconv_unicode_mb_to_uc_fallback mb_to_uc_fallback; + iconv_unicode_uc_to_mb_fallback uc_to_mb_fallback; + iconv_wchar_mb_to_wc_fallback mb_to_wc_fallback; + iconv_wchar_wc_to_mb_fallback wc_to_mb_fallback; + void *data; +}; + + +void iconvlist(int (*do_one) (unsigned int, const char * const *, + void *), void *); +const char *iconv_canonicalize(const char *); +int iconvctl(iconv_t, int, void *); +__END_DECLS + +#endif /* !_ICONV_H_ */ diff --git a/include/ieeefp.h b/include/ieeefp.h new file mode 100644 index 0000000..87dcca9 --- /dev/null +++ b/include/ieeefp.h @@ -0,0 +1,15 @@ +/* $NetBSD: ieeefp.h,v 1.4 1998/01/09 08:03:43 perry Exp $ */ +/* $FreeBSD: releng/11.1/include/ieeefp.h 226607 2011-10-21 06:41:46Z das $ */ + +/* + * Written by J.T. Conklin, Apr 6, 1995 + * Public domain. + */ + +#ifndef _IEEEFP_H_ +#define _IEEEFP_H_ + +#include +#include + +#endif /* _IEEEFP_H_ */ diff --git a/include/ifaddrs.h b/include/ifaddrs.h new file mode 100644 index 0000000..d728729 --- /dev/null +++ b/include/ifaddrs.h @@ -0,0 +1,65 @@ +/* $FreeBSD: releng/11.1/include/ifaddrs.h 250887 2013-05-21 21:20:10Z ed $ */ + +/* + * Copyright (c) 1995, 1999 + * Berkeley Software Design, Inc. 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. + * + * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``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 Berkeley Software Design, Inc. 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. + * + * BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp + */ + +#ifndef _IFADDRS_H_ +#define _IFADDRS_H_ + +struct ifaddrs { + struct ifaddrs *ifa_next; + char *ifa_name; + unsigned int ifa_flags; + struct sockaddr *ifa_addr; + struct sockaddr *ifa_netmask; + struct sockaddr *ifa_dstaddr; + void *ifa_data; +}; + +/* + * This may have been defined in . Note that if is + * to be included it must be included before this header file. + */ +#ifndef ifa_broadaddr +#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ +#endif + +struct ifmaddrs { + struct ifmaddrs *ifma_next; + struct sockaddr *ifma_name; + struct sockaddr *ifma_addr; + struct sockaddr *ifma_lladdr; +}; + +#include + +__BEGIN_DECLS +extern int getifaddrs(struct ifaddrs **); +extern void freeifaddrs(struct ifaddrs *); +extern int getifmaddrs(struct ifmaddrs **); +extern void freeifmaddrs(struct ifmaddrs *); +__END_DECLS + +#endif diff --git a/include/inttypes.h b/include/inttypes.h new file mode 100644 index 0000000..a2b4968 --- /dev/null +++ b/include/inttypes.h @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2001 Mike Barcroft + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/inttypes.h 263998 2014-04-01 14:46:11Z tijl $ + */ + +#ifndef _INTTYPES_H_ +#define _INTTYPES_H_ + +#include +#include + +#ifndef __cplusplus +#ifndef _WCHAR_T_DECLARED +typedef ___wchar_t wchar_t; +#define _WCHAR_T_DECLARED +#endif +#endif + +typedef struct { + intmax_t quot; /* Quotient. */ + intmax_t rem; /* Remainder. */ +} imaxdiv_t; + +__BEGIN_DECLS +#ifdef _XLOCALE_H_ +#include +#endif +intmax_t imaxabs(intmax_t) __pure2; +imaxdiv_t imaxdiv(intmax_t, intmax_t) __pure2; + +intmax_t strtoimax(const char * __restrict, char ** __restrict, int); +uintmax_t strtoumax(const char * __restrict, char ** __restrict, int); +intmax_t wcstoimax(const wchar_t * __restrict, + wchar_t ** __restrict, int); +uintmax_t wcstoumax(const wchar_t * __restrict, + wchar_t ** __restrict, int); +__END_DECLS + +#endif /* !_INTTYPES_H_ */ diff --git a/include/iso646.h b/include/iso646.h new file mode 100644 index 0000000..c4d72bd --- /dev/null +++ b/include/iso646.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 1998 Alex Nash + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/iso646.h 225801 2011-09-27 16:33:17Z jkim $ + */ + +#ifndef _ISO646_H_ +#define _ISO646_H_ + +#ifndef __cplusplus + +#define and && +#define and_eq &= +#define bitand & +#define bitor | +#define compl ~ +#define not ! +#define not_eq != +#define or || +#define or_eq |= +#define xor ^ +#define xor_eq ^= + +#endif /* !__cplusplus */ + +#endif /* !_ISO646_H_ */ diff --git a/include/kenv.h b/include/kenv.h new file mode 100644 index 0000000..569d411 --- /dev/null +++ b/include/kenv.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2002 Maxime Henrion + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/kenv.h 152750 2005-11-24 07:20:26Z ru $ + */ + +#ifndef _KENV_H_ +#define _KENV_H_ + +#include +#include + +__BEGIN_DECLS +int kenv(int, const char *, char *, int); +__END_DECLS + +#endif /* !_KENV_H_ */ diff --git a/include/langinfo.h b/include/langinfo.h new file mode 100644 index 0000000..73cd155 --- /dev/null +++ b/include/langinfo.h @@ -0,0 +1,139 @@ +/*- + * Copyright (c) 2001 Alexey Zelkin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/langinfo.h 264676 2014-04-19 12:38:01Z jilles $ + */ + +#ifndef _LANGINFO_H_ +#define _LANGINFO_H_ + +#include +#include + +#ifndef _NL_ITEM_DECLARED +typedef __nl_item nl_item; +#define _NL_ITEM_DECLARED +#endif + +#define CODESET 0 /* codeset name */ +#define D_T_FMT 1 /* string for formatting date and time */ +#define D_FMT 2 /* date format string */ +#define T_FMT 3 /* time format string */ +#define T_FMT_AMPM 4 /* a.m. or p.m. time formatting string */ +#define AM_STR 5 /* Ante Meridian affix */ +#define PM_STR 6 /* Post Meridian affix */ + +/* week day names */ +#define DAY_1 7 +#define DAY_2 8 +#define DAY_3 9 +#define DAY_4 10 +#define DAY_5 11 +#define DAY_6 12 +#define DAY_7 13 + +/* abbreviated week day names */ +#define ABDAY_1 14 +#define ABDAY_2 15 +#define ABDAY_3 16 +#define ABDAY_4 17 +#define ABDAY_5 18 +#define ABDAY_6 19 +#define ABDAY_7 20 + +/* month names */ +#define MON_1 21 +#define MON_2 22 +#define MON_3 23 +#define MON_4 24 +#define MON_5 25 +#define MON_6 26 +#define MON_7 27 +#define MON_8 28 +#define MON_9 29 +#define MON_10 30 +#define MON_11 31 +#define MON_12 32 + +/* abbreviated month names */ +#define ABMON_1 33 +#define ABMON_2 34 +#define ABMON_3 35 +#define ABMON_4 36 +#define ABMON_5 37 +#define ABMON_6 38 +#define ABMON_7 39 +#define ABMON_8 40 +#define ABMON_9 41 +#define ABMON_10 42 +#define ABMON_11 43 +#define ABMON_12 44 + +#define ERA 45 /* era description segments */ +#define ERA_D_FMT 46 /* era date format string */ +#define ERA_D_T_FMT 47 /* era date and time format string */ +#define ERA_T_FMT 48 /* era time format string */ +#define ALT_DIGITS 49 /* alternative symbols for digits */ + +#define RADIXCHAR 50 /* radix char */ +#define THOUSEP 51 /* separator for thousands */ + +#define YESEXPR 52 /* affirmative response expression */ +#define NOEXPR 53 /* negative response expression */ + +#if __BSD_VISIBLE || (__XSI_VISIBLE && __XSI_VISIBLE <= 500) +#define YESSTR 54 /* affirmative response for yes/no queries */ +#define NOSTR 55 /* negative response for yes/no queries */ +#endif + +#define CRNCYSTR 56 /* currency symbol */ + +#if __BSD_VISIBLE +#define D_MD_ORDER 57 /* month/day order (local extension) */ +#endif + +/* standalone months forms for %OB */ +#define ALTMON_1 58 +#define ALTMON_2 59 +#define ALTMON_3 60 +#define ALTMON_4 61 +#define ALTMON_5 62 +#define ALTMON_6 63 +#define ALTMON_7 64 +#define ALTMON_8 65 +#define ALTMON_9 66 +#define ALTMON_10 67 +#define ALTMON_11 68 +#define ALTMON_12 69 + +__BEGIN_DECLS +char *nl_langinfo(nl_item); + +#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) +#include +#endif +__END_DECLS + +#endif /* !_LANGINFO_H_ */ diff --git a/include/libgen.h b/include/libgen.h new file mode 100644 index 0000000..4391ae2 --- /dev/null +++ b/include/libgen.h @@ -0,0 +1,42 @@ +/* $OpenBSD: libgen.h,v 1.4 1999/05/28 22:00:22 espie Exp $ */ +/* $FreeBSD: releng/11.1/include/libgen.h 300955 2016-05-29 12:21:54Z ed $ */ + +/* + * Copyright (c) 1997 Todd C. Miller + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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. + */ + +#ifndef _LIBGEN_H_ +#define _LIBGEN_H_ + +#include + +__BEGIN_DECLS +char *basename(const char *); +char *basename_r(const char *, char *); +char *dirname(const char *); +__END_DECLS + +#endif /* !_LIBGEN_H_ */ diff --git a/include/link.h b/include/link.h new file mode 100644 index 0000000..bf649dd --- /dev/null +++ b/include/link.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 1993 Paul Kranenburg + * 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 Paul Kranenburg. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/link.h 103436 2002-09-17 01:49:00Z peter $ + */ + +#include diff --git a/include/locale.h b/include/locale.h new file mode 100644 index 0000000..6c817b5 --- /dev/null +++ b/include/locale.h @@ -0,0 +1,87 @@ +/* + * 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. + * + * @(#)locale.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: releng/11.1/include/locale.h 232498 2012-03-04 15:31:13Z theraven $ + */ + +#ifndef _LOCALE_H_ +#define _LOCALE_H_ + +#include + +struct lconv { + char *decimal_point; + char *thousands_sep; + char *grouping; + char *int_curr_symbol; + char *currency_symbol; + char *mon_decimal_point; + char *mon_thousands_sep; + char *mon_grouping; + char *positive_sign; + char *negative_sign; + char int_frac_digits; + char frac_digits; + char p_cs_precedes; + char p_sep_by_space; + char n_cs_precedes; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +}; + +#define LC_ALL 0 +#define LC_COLLATE 1 +#define LC_CTYPE 2 +#define LC_MONETARY 3 +#define LC_NUMERIC 4 +#define LC_TIME 5 +#define LC_MESSAGES 6 + +#define _LC_LAST 7 /* marks end */ + +#include + +__BEGIN_DECLS +struct lconv *localeconv(void); +char *setlocale(int, const char *); + +#if __POSIX_VISIBLE >= 200809 +#include +#endif +__END_DECLS + + +#endif /* _LOCALE_H_ */ diff --git a/include/malloc.h b/include/malloc.h new file mode 100644 index 0000000..886276f --- /dev/null +++ b/include/malloc.h @@ -0,0 +1,6 @@ +/* $FreeBSD: releng/11.1/include/malloc.h 86178 2001-11-07 23:14:31Z obrien $ */ +#if __STDC__ +#error " has been replaced by " +#else +#include +#endif diff --git a/include/malloc_np.h b/include/malloc_np.h new file mode 100644 index 0000000..4005532 --- /dev/null +++ b/include/malloc_np.h @@ -0,0 +1,105 @@ +/*- + * Copyright (C) 2006 Jason Evans . + * 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(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. + * + * $FreeBSD: releng/11.1/include/malloc_np.h 296221 2016-02-29 19:10:32Z jasone $ + */ + +#ifndef _MALLOC_NP_H_ +#define _MALLOC_NP_H_ +#include +#include +#include +#include + +__BEGIN_DECLS +typedef void *(chunk_alloc_t)(void *, size_t, size_t, bool *, bool *, unsigned); +typedef bool (chunk_dalloc_t)(void *, size_t, bool, unsigned); +typedef bool (chunk_commit_t)(void *, size_t, size_t, size_t, unsigned); +typedef bool (chunk_decommit_t)(void *, size_t, size_t, size_t, unsigned); +typedef bool (chunk_purge_t)(void *, size_t, size_t, size_t, unsigned); +typedef bool (chunk_split_t)(void *, size_t, size_t, size_t, bool, unsigned); +typedef bool (chunk_merge_t)(void *, size_t, void *, size_t, bool, unsigned); +typedef struct { + chunk_alloc_t *alloc; + chunk_dalloc_t *dalloc; + chunk_commit_t *commit; + chunk_decommit_t *decommit; + chunk_purge_t *purge; + chunk_split_t *split; + chunk_merge_t *merge; +} chunk_hooks_t; + +size_t malloc_usable_size(const void *ptr); + +void malloc_stats_print(void (*write_cb)(void *, const char *), + void *cbopaque, const char *opts); +int mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, + size_t newlen); +int mallctlnametomib(const char *name, size_t *mibp, size_t *miblenp); +int mallctlbymib(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen); + +#define MALLOCX_LG_ALIGN(la) (la) +#define MALLOCX_ALIGN(a) (ffsl(a)-1) +#define MALLOCX_ZERO ((int)0x40) +#define MALLOCX_TCACHE(tc) ((int)(((tc)+2) << 8)) +#define MALLOCX_TCACHE_NONE MALLOCX_TCACHE(-1) +#define MALLOCX_ARENA(a) ((int)(((a)+1) << 20)) + +void *mallocx(size_t size, int flags); +void *rallocx(void *ptr, size_t size, int flags); +size_t xallocx(void *ptr, size_t size, size_t extra, int flags); +size_t sallocx(const void *ptr, int flags); +void dallocx(void *ptr, int flags); +void sdallocx(void *ptr, size_t size, int flags); +size_t nallocx(size_t size, int flags); + +void * __calloc(size_t number, size_t size) __malloc_like; +void * __malloc(size_t size) __malloc_like; +void * __realloc(void *ptr, size_t size); +void __free(void *ptr); +int __posix_memalign(void **ptr, size_t alignment, size_t size); +void *__aligned_alloc(size_t alignment, size_t size); +size_t __malloc_usable_size(const void *ptr); +void __malloc_stats_print(void (*write_cb)(void *, const char *), + void *cbopaque, const char *opts); +int __mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, + size_t newlen); +int __mallctlnametomib(const char *name, size_t *mibp, size_t *miblenp); +int __mallctlbymib(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen); +void *__mallocx(size_t size, int flags); +void *__rallocx(void *ptr, size_t size, int flags); +size_t __xallocx(void *ptr, size_t size, size_t extra, int flags); +size_t __sallocx(const void *ptr, int flags); +void __dallocx(void *ptr, int flags); +void __sdallocx(void *ptr, size_t size, int flags); +size_t __nallocx(size_t size, int flags); +__END_DECLS + +#endif /* _MALLOC_NP_H_ */ diff --git a/include/memory.h b/include/memory.h new file mode 100644 index 0000000..d2cb285 --- /dev/null +++ b/include/memory.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1988, 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. + * + * @(#)memory.h 8.1 (Berkeley) 6/2/93 + * + * $FreeBSD: releng/11.1/include/memory.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#include diff --git a/include/mk-osreldate.sh b/include/mk-osreldate.sh new file mode 100755 index 0000000..3758f5a --- /dev/null +++ b/include/mk-osreldate.sh @@ -0,0 +1,52 @@ +#!/bin/sh - +# Copyright (c) 2013 Garrett Cooper +# 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. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +# +# $FreeBSD: releng/11.1/include/mk-osreldate.sh 291310 2015-11-25 19:10:59Z bdrewery $ + +set -e + +CURDIR=$(pwd) +ECHO=${ECHO:=echo} + +tmpfile=$(mktemp osreldate.XXXXXXXX) +trap "rm -f $tmpfile" EXIT + +${ECHO} creating osreldate.h from newvers.sh + +set +e +VARS_ONLY=1 +. "${NEWVERS_SH:=$CURDIR/../sys/conf/newvers.sh}" || exit 1 +set -e +cat > $tmpfile < cannot be used in the kernel, use " +#else +#undef __FreeBSD_version +#define __FreeBSD_version $RELDATE +#endif +EOF +chmod 644 $tmpfile +mv -f $tmpfile osreldate.h diff --git a/include/monetary.h b/include/monetary.h new file mode 100644 index 0000000..7021043 --- /dev/null +++ b/include/monetary.h @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2001 Alexey Zelkin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/monetary.h 301035 2016-05-31 12:29:21Z ed $ + */ + +#ifndef _MONETARY_H_ +#define _MONETARY_H_ + +#include +#include + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +#ifndef _SSIZE_T_DECLARED +typedef __ssize_t ssize_t; +#define _SSIZE_T_DECLARED +#endif + +__BEGIN_DECLS +#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) +#include +#endif +ssize_t strfmon(char * __restrict, size_t, const char * __restrict, ...); +__END_DECLS + +#endif /* !_MONETARY_H_ */ diff --git a/include/mpool.h b/include/mpool.h new file mode 100644 index 0000000..fe81349 --- /dev/null +++ b/include/mpool.h @@ -0,0 +1,109 @@ +/*- + * Copyright (c) 1991, 1993, 1994 + * 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. + * + * @(#)mpool.h 8.4 (Berkeley) 11/2/95 + * $FreeBSD: releng/11.1/include/mpool.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _MPOOL_H_ +#define _MPOOL_H_ + +#include + +/* + * The memory pool scheme is a simple one. Each in-memory page is referenced + * by a bucket which is threaded in up to two of three ways. All active pages + * are threaded on a hash chain (hashed by page number) and an lru chain. + * Inactive pages are threaded on a free chain. Each reference to a memory + * pool is handed an opaque MPOOL cookie which stores all of this information. + */ +#define HASHSIZE 128 +#define HASHKEY(pgno) ((pgno - 1 + HASHSIZE) % HASHSIZE) + +/* The BKT structures are the elements of the queues. */ +typedef struct _bkt { + TAILQ_ENTRY(_bkt) hq; /* hash queue */ + TAILQ_ENTRY(_bkt) q; /* lru queue */ + void *page; /* page */ + pgno_t pgno; /* page number */ + +#define MPOOL_DIRTY 0x01 /* page needs to be written */ +#define MPOOL_PINNED 0x02 /* page is pinned into memory */ +#define MPOOL_INUSE 0x04 /* page address is valid */ + u_int8_t flags; /* flags */ +} BKT; + +typedef struct MPOOL { + TAILQ_HEAD(_lqh, _bkt) lqh; /* lru queue head */ + /* hash queue array */ + TAILQ_HEAD(_hqh, _bkt) hqh[HASHSIZE]; + pgno_t curcache; /* current number of cached pages */ + pgno_t maxcache; /* max number of cached pages */ + pgno_t npages; /* number of pages in the file */ + unsigned long pagesize; /* file page size */ + int fd; /* file descriptor */ + /* page in conversion routine */ + void (*pgin)(void *, pgno_t, void *); + /* page out conversion routine */ + void (*pgout)(void *, pgno_t, void *); + void *pgcookie; /* cookie for page in/out routines */ +#ifdef STATISTICS + unsigned long cachehit; + unsigned long cachemiss; + unsigned long pagealloc; + unsigned long pageflush; + unsigned long pageget; + unsigned long pagenew; + unsigned long pageput; + unsigned long pageread; + unsigned long pagewrite; +#endif +} MPOOL; + +#define MPOOL_IGNOREPIN 0x01 /* Ignore if the page is pinned. */ +#define MPOOL_PAGE_REQUEST 0x01 /* Allocate a new page with a + specific page number. */ +#define MPOOL_PAGE_NEXT 0x02 /* Allocate a new page with the next + page number. */ + +__BEGIN_DECLS +MPOOL *mpool_open(void *, int, pgno_t, pgno_t); +void mpool_filter(MPOOL *, void (*)(void *, pgno_t, void *), + void (*)(void *, pgno_t, void *), void *); +void *mpool_new(MPOOL *, pgno_t *, unsigned int); +void *mpool_get(MPOOL *, pgno_t, unsigned int); +int mpool_delete(MPOOL *, void *); +int mpool_put(MPOOL *, void *, unsigned int); +int mpool_sync(MPOOL *); +int mpool_close(MPOOL *); +#ifdef STATISTICS +void mpool_stat(MPOOL *); +#endif +__END_DECLS + +#endif diff --git a/include/mqueue.h b/include/mqueue.h new file mode 100644 index 0000000..4a7eb52 --- /dev/null +++ b/include/mqueue.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2005 David Xu + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/mqueue.h 306905 2016-10-09 12:34:56Z kib $ + */ + +#ifndef _MQUEUE_H_ +#define _MQUEUE_H_ + +#include +#include +#include +#include + +struct timespec; + +__BEGIN_DECLS +int mq_close(mqd_t); +int mq_getattr(mqd_t, struct mq_attr *); +int mq_notify(mqd_t, const struct sigevent *); +mqd_t mq_open(const char *, int, ...); +ssize_t mq_receive(mqd_t, char *, size_t, unsigned *); +int mq_send(mqd_t, const char *, size_t, unsigned); +int mq_setattr(mqd_t, const struct mq_attr *__restrict, + struct mq_attr *__restrict); +ssize_t mq_timedreceive(mqd_t, char *__restrict, size_t, + unsigned *__restrict, const struct timespec *__restrict); +int mq_timedsend(mqd_t, const char *, size_t, unsigned, + const struct timespec *); +int mq_unlink(const char *); +#if __BSD_VISIBLE +int mq_getfd_np(mqd_t mqd); +#endif /* __BSD_VISIBLE */ + +__END_DECLS +#endif diff --git a/include/ndbm.h b/include/ndbm.h new file mode 100644 index 0000000..23fb6b9 --- /dev/null +++ b/include/ndbm.h @@ -0,0 +1,80 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * 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. + * + * @(#)ndbm.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: releng/11.1/include/ndbm.h 301066 2016-05-31 18:32:57Z ed $ + */ + +#ifndef _NDBM_H_ +#define _NDBM_H_ + +#include + +/* Map dbm interface onto db(3). */ +#define DBM_RDONLY O_RDONLY + +/* Flags to dbm_store(). */ +#define DBM_INSERT 0 +#define DBM_REPLACE 1 + +/* + * The db(3) support for ndbm always appends this suffix to the + * file name to avoid overwriting the user's original database. + */ +#define DBM_SUFFIX ".db" + +typedef struct { + void *dptr; + int dsize; +} datum; + +typedef DB DBM; +#define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE + +__BEGIN_DECLS +int dbm_clearerr(DBM *); +void dbm_close(DBM *); +int dbm_delete(DBM *, datum); +int dbm_error(DBM *); +datum dbm_fetch(DBM *, datum); +datum dbm_firstkey(DBM *); +#if __BSD_VISIBLE +long dbm_forder(DBM *, datum); +#endif +datum dbm_nextkey(DBM *); +DBM *dbm_open(const char *, int, mode_t); +int dbm_store(DBM *, datum, datum, int); +#if __BSD_VISIBLE +int dbm_dirfno(DBM *); +#endif +__END_DECLS + +#endif /* !_NDBM_H_ */ diff --git a/include/netconfig.h b/include/netconfig.h new file mode 100644 index 0000000..248c08b --- /dev/null +++ b/include/netconfig.h @@ -0,0 +1,96 @@ +/* $NetBSD: netconfig.h,v 1.1 2000/06/02 22:57:54 fvdl Exp $ */ +/* $FreeBSD: releng/11.1/include/netconfig.h 93032 2002-03-23 17:24:55Z imp $ */ + + +#ifndef _NETCONFIG_H_ +#define _NETCONFIG_H_ + +#include + +#define NETCONFIG "/etc/netconfig" +#define NETPATH "NETPATH" + +struct netconfig { + char *nc_netid; /* Network ID */ + unsigned long nc_semantics; /* Semantics (see below) */ + unsigned long nc_flag; /* Flags (see below) */ + char *nc_protofmly; /* Protocol family */ + char *nc_proto; /* Protocol name */ + char *nc_device; /* Network device pathname */ + unsigned long nc_nlookups; /* Number of directory lookup libs */ + char **nc_lookups; /* Names of the libraries */ + unsigned long nc_unused[9]; /* reserved */ +}; + +typedef struct { + struct netconfig **nc_head; + struct netconfig **nc_curr; +} NCONF_HANDLE; + +/* + * nc_semantics values + */ +#define NC_TPI_CLTS 1 +#define NC_TPI_COTS 2 +#define NC_TPI_COTS_ORD 3 +#define NC_TPI_RAW 4 + +/* + * nc_flag values + */ +#define NC_NOFLAG 0x00 +#define NC_VISIBLE 0x01 +#define NC_BROADCAST 0x02 + +/* + * nc_protofmly values + */ +#define NC_NOPROTOFMLY "-" +#define NC_LOOPBACK "loopback" +#define NC_INET "inet" +#define NC_INET6 "inet6" +#define NC_IMPLINK "implink" +#define NC_PUP "pup" +#define NC_CHAOS "chaos" +#define NC_NS "ns" +#define NC_NBS "nbs" +#define NC_ECMA "ecma" +#define NC_DATAKIT "datakit" +#define NC_CCITT "ccitt" +#define NC_SNA "sna" +#define NC_DECNET "decnet" +#define NC_DLI "dli" +#define NC_LAT "lat" +#define NC_HYLINK "hylink" +#define NC_APPLETALK "appletalk" +#define NC_NIT "nit" +#define NC_IEEE802 "ieee802" +#define NC_OSI "osi" +#define NC_X25 "x25" +#define NC_OSINET "osinet" +#define NC_GOSIP "gosip" + +/* + * nc_proto values + */ +#define NC_NOPROTO "-" +#define NC_TCP "tcp" +#define NC_UDP "udp" +#define NC_ICMP "icmp" + +__BEGIN_DECLS +void *setnetconfig(void); +struct netconfig *getnetconfig(void *); +struct netconfig *getnetconfigent(const char *); +void freenetconfigent(struct netconfig *); +int endnetconfig(void *); + +void *setnetpath(void); +struct netconfig *getnetpath(void *); +int endnetpath(void *); + +void nc_perror(const char *); +char *nc_sperror(void); +__END_DECLS + +#endif /* _NETCONFIG_H_ */ diff --git a/include/netdb.h b/include/netdb.h new file mode 100644 index 0000000..17fbf2d --- /dev/null +++ b/include/netdb.h @@ -0,0 +1,306 @@ +/*- + * Copyright (c) 1980, 1983, 1988, 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. + * + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * 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, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION 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. + * - + * --Copyright-- + */ + +/* + * @(#)netdb.h 8.1 (Berkeley) 6/2/93 + * From: Id: netdb.h,v 8.9 1996/11/19 08:39:29 vixie Exp $ + * $FreeBSD: releng/11.1/include/netdb.h 301711 2016-06-09 01:28:44Z markj $ + */ + +#ifndef _NETDB_H_ +#define _NETDB_H_ + +#include +#include + +#ifndef _IN_ADDR_T_DECLARED +typedef __uint32_t in_addr_t; +#define _IN_ADDR_T_DECLARED +#endif + +#ifndef _IN_PORT_T_DECLARED +typedef __uint16_t in_port_t; +#define _IN_PORT_T_DECLARED +#endif + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +#ifndef _SOCKLEN_T_DECLARED +typedef __socklen_t socklen_t; +#define _SOCKLEN_T_DECLARED +#endif + +#ifndef _UINT32_T_DECLARED +typedef __uint32_t uint32_t; +#define _UINT32_T_DECLARED +#endif + +#ifndef _PATH_HEQUIV +# define _PATH_HEQUIV "/etc/hosts.equiv" +#endif +#define _PATH_HOSTS "/etc/hosts" +#define _PATH_NETWORKS "/etc/networks" +#define _PATH_PROTOCOLS "/etc/protocols" +#define _PATH_SERVICES "/etc/services" +#define _PATH_SERVICES_DB "/var/db/services.db" + +#define h_errno (*__h_errno()) + +/* + * Structures returned by network data base library. All addresses are + * supplied in host order, and returned in network order (suitable for + * use in system calls). + */ +struct hostent { + char *h_name; /* official name of host */ + char **h_aliases; /* alias list */ + int h_addrtype; /* host address type */ + int h_length; /* length of address */ + char **h_addr_list; /* list of addresses from name server */ +#define h_addr h_addr_list[0] /* address, for backward compatibility */ +}; + +struct netent { + char *n_name; /* official name of net */ + char **n_aliases; /* alias list */ + int n_addrtype; /* net address type */ + uint32_t n_net; /* network # */ +}; + +struct servent { + char *s_name; /* official service name */ + char **s_aliases; /* alias list */ + int s_port; /* port # */ + char *s_proto; /* protocol to use */ +}; + +struct protoent { + char *p_name; /* official protocol name */ + char **p_aliases; /* alias list */ + int p_proto; /* protocol # */ +}; + +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ + int ai_family; /* AF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + socklen_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; + +#define IPPORT_RESERVED 1024 + +/* + * Error return codes from gethostbyname() and gethostbyaddr() + * (left in h_errno). + */ + +#define NETDB_INTERNAL -1 /* see errno */ +#define NETDB_SUCCESS 0 /* no problem */ +#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ +#define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL */ +#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ +#define NO_DATA 4 /* Valid name, no data record of requested type */ +#define NO_ADDRESS NO_DATA /* no address, look for MX record */ + +/* + * Error return codes from getaddrinfo() + */ +#if 0 +/* obsoleted */ +#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ +#endif +#define EAI_AGAIN 2 /* temporary failure in name resolution */ +#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ +#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ +#define EAI_FAMILY 5 /* ai_family not supported */ +#define EAI_MEMORY 6 /* memory allocation failure */ +#if 0 +/* obsoleted */ +#define EAI_NODATA 7 /* no address associated with hostname */ +#endif +#define EAI_NONAME 8 /* hostname nor servname provided, or not known */ +#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ +#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ +#define EAI_SYSTEM 11 /* system error returned in errno */ +#define EAI_BADHINTS 12 /* invalid value for hints */ +#define EAI_PROTOCOL 13 /* resolved protocol is unknown */ +#define EAI_OVERFLOW 14 /* argument buffer overflow */ +#define EAI_MAX 15 + +/* + * Flag values for getaddrinfo() + */ +#define AI_PASSIVE 0x00000001 /* get address to use bind() */ +#define AI_CANONNAME 0x00000002 /* fill ai_canonname */ +#define AI_NUMERICHOST 0x00000004 /* prevent host name resolution */ +#define AI_NUMERICSERV 0x00000008 /* prevent service name resolution */ +/* valid flags for addrinfo (not a standard def, apps should not use it) */ +#define AI_MASK \ + (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | \ + AI_ADDRCONFIG | AI_ALL | AI_V4MAPPED) + +#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ +#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ +#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ +#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ +/* special recommended flags for getipnodebyname */ +#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) + +/* + * Constants for getnameinfo() + */ +#define NI_MAXHOST 1025 +#define NI_MAXSERV 32 + +/* + * Flag values for getnameinfo() + */ +#define NI_NOFQDN 0x00000001 +#define NI_NUMERICHOST 0x00000002 +#define NI_NAMEREQD 0x00000004 +#define NI_NUMERICSERV 0x00000008 +#define NI_DGRAM 0x00000010 +#if 0 /* obsolete */ +#define NI_WITHSCOPEID 0x00000020 +#endif + +/* + * Scope delimit character + */ +#define SCOPE_DELIMITER '%' + +__BEGIN_DECLS +void endhostent(void); +void endnetent(void); +void endprotoent(void); +void endservent(void); +#if __BSD_VISIBLE || (__POSIX_VISIBLE && __POSIX_VISIBLE <= 200112) +struct hostent *gethostbyaddr(const void *, socklen_t, int); +struct hostent *gethostbyname(const char *); +#endif +struct hostent *gethostent(void); +struct netent *getnetbyaddr(uint32_t, int); +struct netent *getnetbyname(const char *); +struct netent *getnetent(void); +struct protoent *getprotobyname(const char *); +struct protoent *getprotobynumber(int); +struct protoent *getprotoent(void); +struct servent *getservbyname(const char *, const char *); +struct servent *getservbyport(int, const char *); +struct servent *getservent(void); +void sethostent(int); +/* void sethostfile(const char *); */ +void setnetent(int); +void setprotoent(int); +int getaddrinfo(const char *, const char *, + const struct addrinfo *, struct addrinfo **); +int getnameinfo(const struct sockaddr *, socklen_t, char *, + size_t, char *, size_t, int); +void freeaddrinfo(struct addrinfo *); +const char *gai_strerror(int); +void setservent(int); + +#if __BSD_VISIBLE +void endnetgrent(void); +void freehostent(struct hostent *); +int gethostbyaddr_r(const void *, socklen_t, int, struct hostent *, + char *, size_t, struct hostent **, int *); +int gethostbyname_r(const char *, struct hostent *, char *, size_t, + struct hostent **, int *); +struct hostent *gethostbyname2(const char *, int); +int gethostbyname2_r(const char *, int, struct hostent *, char *, + size_t, struct hostent **, int *); +int gethostent_r(struct hostent *, char *, size_t, + struct hostent **, int *); +struct hostent *getipnodebyaddr(const void *, size_t, int, int *); +struct hostent *getipnodebyname(const char *, int, int, int *); +int getnetbyaddr_r(uint32_t, int, struct netent *, char *, size_t, + struct netent**, int *); +int getnetbyname_r(const char *, struct netent *, char *, size_t, + struct netent **, int *); +int getnetent_r(struct netent *, char *, size_t, struct netent **, + int *); +int getnetgrent(char **, char **, char **); +int getnetgrent_r(char **, char **, char **, char *, size_t); +int getprotobyname_r(const char *, struct protoent *, char *, + size_t, struct protoent **); +int getprotobynumber_r(int, struct protoent *, char *, size_t, + struct protoent **); +int getprotoent_r(struct protoent *, char *, size_t, + struct protoent **); +int getservbyname_r(const char *, const char *, struct servent *, + char *, size_t, struct servent **); +int getservbyport_r(int, const char *, struct servent *, char *, + size_t, struct servent **); +int getservent_r(struct servent *, char *, size_t, + struct servent **); +void herror(const char *); +const char *hstrerror(int); +int innetgr(const char *, const char *, const char *, const char *); +void setnetgrent(const char *); +#endif + + +/* + * PRIVATE functions specific to the FreeBSD implementation + */ + +/* DO NOT USE THESE, THEY ARE SUBJECT TO CHANGE AND ARE NOT PORTABLE!!! */ +int * __h_errno(void); +__END_DECLS + +#endif /* !_NETDB_H_ */ diff --git a/include/nl_types.h b/include/nl_types.h new file mode 100644 index 0000000..4809409 --- /dev/null +++ b/include/nl_types.h @@ -0,0 +1,97 @@ +/* $NetBSD: nl_types.h,v 1.9 2000/10/03 19:53:32 sommerfeld Exp $ */ + +/*- + * Copyright (c) 1996 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by J.T. Conklin. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + * + * $FreeBSD: releng/11.1/include/nl_types.h 203963 2010-02-16 19:28:10Z imp $ + */ + +#ifndef _NL_TYPES_H_ +#define _NL_TYPES_H_ + +#include +#include + +#ifdef _NLS_PRIVATE +/* + * MESSAGE CATALOG FILE FORMAT. + * + * The NetBSD/FreeBSD message catalog format is similar to the format used by + * Svr4 systems. The differences are: + * * fixed byte order (big endian) + * * fixed data field sizes + * + * A message catalog contains four data types: a catalog header, one + * or more set headers, one or more message headers, and one or more + * text strings. + */ + +#define _NLS_MAGIC 0xff88ff89 + +struct _nls_cat_hdr { + int32_t __magic; + int32_t __nsets; + int32_t __mem; + int32_t __msg_hdr_offset; + int32_t __msg_txt_offset; +} ; + +struct _nls_set_hdr { + int32_t __setno; /* set number: 0 < x <= NL_SETMAX */ + int32_t __nmsgs; /* number of messages in the set */ + int32_t __index; /* index of first msg_hdr in msg_hdr table */ +} ; + +struct _nls_msg_hdr { + int32_t __msgno; /* msg number: 0 < x <= NL_MSGMAX */ + int32_t __msglen; + int32_t __offset; +} ; + +#endif /* _NLS_PRIVATE */ + +#define NL_SETD 0 +#define NL_CAT_LOCALE 1 + +typedef struct __nl_cat_d { + void *__data; + int __size; +} *nl_catd; + +#ifndef _NL_ITEM_DECLARED +typedef __nl_item nl_item; +#define _NL_ITEM_DECLARED +#endif + +__BEGIN_DECLS +nl_catd catopen(const char *, int); +char *catgets(nl_catd, int, int, const char *) __format_arg(4); +int catclose(nl_catd); +__END_DECLS + +#endif /* _NL_TYPES_H_ */ diff --git a/include/nlist.h b/include/nlist.h new file mode 100644 index 0000000..c5dd02e --- /dev/null +++ b/include/nlist.h @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (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. + * + * 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. + * + * @(#)nlist.h 8.2 (Berkeley) 1/21/94 + * + * $FreeBSD: releng/11.1/include/nlist.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _NLIST_H_ +#define _NLIST_H_ + +#include +#include + +__BEGIN_DECLS +int nlist(const char *, struct nlist *); +__END_DECLS + +#endif /* !_NLIST_H_ */ diff --git a/include/nss.h b/include/nss.h new file mode 100644 index 0000000..238ad6c --- /dev/null +++ b/include/nss.h @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2003 Networks Associates Technology, Inc. + * All rights reserved. + * + * This software was developed for the FreeBSD Project by + * Jacques A. Vidrine, Safeport Network Services, and Network + * Associates Laboratories, the Security Research Division of Network + * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 + * ("CBOSS"), as part of the DARPA CHATS research program. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/nss.h 124289 2004-01-09 13:43:49Z nectar $ + * + * Compatibility header for the GNU C Library-style nsswitch interface. + */ +#ifndef _NSS_H_ +#define _NSS_H_ + +#include + +enum nss_status { + NSS_STATUS_TRYAGAIN = -2, + NSS_STATUS_UNAVAIL, + NSS_STATUS_NOTFOUND, + NSS_STATUS_SUCCESS, + NSS_STATUS_RETURN +}; + +#define __nss_compat_result(rv, err) \ +((rv == NSS_STATUS_TRYAGAIN && err == ERANGE) ? NS_RETURN : \ + (rv == NSS_STATUS_TRYAGAIN) ? NS_TRYAGAIN : \ + (rv == NSS_STATUS_UNAVAIL) ? NS_UNAVAIL : \ + (rv == NSS_STATUS_NOTFOUND) ? NS_NOTFOUND : \ + (rv == NSS_STATUS_SUCCESS) ? NS_SUCCESS : \ + (rv == NSS_STATUS_RETURN) ? NS_RETURN : 0) + +#endif diff --git a/include/nsswitch.h b/include/nsswitch.h new file mode 100644 index 0000000..e1848c2 --- /dev/null +++ b/include/nsswitch.h @@ -0,0 +1,244 @@ +/* $NetBSD: nsswitch.h,v 1.6 1999/01/26 01:04:07 lukem Exp $ */ +/* $FreeBSD: releng/11.1/include/nsswitch.h 206155 2010-04-04 08:31:03Z ume $ */ + +/*- + * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Luke Mewburn. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _NSSWITCH_H +#define _NSSWITCH_H 1 + +#include +#include + +#define NSS_MODULE_INTERFACE_VERSION 1 + +#ifndef _PATH_NS_CONF +#define _PATH_NS_CONF "/etc/nsswitch.conf" +#endif + +/* NSS source actions */ +#define NS_ACTION_CONTINUE 0 /* try the next source */ +#define NS_ACTION_RETURN 1 /* look no further */ + +#define NS_SUCCESS (1<<0) /* entry was found */ +#define NS_UNAVAIL (1<<1) /* source not responding, or corrupt */ +#define NS_NOTFOUND (1<<2) /* source responded 'no such entry' */ +#define NS_TRYAGAIN (1<<3) /* source busy, may respond to retry */ +#define NS_RETURN (1<<4) /* stop search, e.g. for ERANGE */ +#define NS_TERMINATE (NS_SUCCESS|NS_RETURN) /* flags that end search */ +#define NS_STATUSMASK 0x000000ff /* bitmask to get the status flags */ + +/* + * currently implemented sources + */ +#define NSSRC_FILES "files" /* local files */ +#define NSSRC_DB "db" /* database */ +#define NSSRC_DNS "dns" /* DNS; IN for hosts, HS for others */ +#define NSSRC_NIS "nis" /* YP/NIS */ +#define NSSRC_COMPAT "compat" /* passwd,group in YP compat mode */ +#define NSSRC_CACHE "cache" /* nscd daemon */ +#define NSSRC_FALLBACK "__fallback" /* internal fallback source */ + +/* + * currently implemented databases + */ +#define NSDB_HOSTS "hosts" +#define NSDB_GROUP "group" +#define NSDB_GROUP_COMPAT "group_compat" +#define NSDB_NETGROUP "netgroup" +#define NSDB_NETWORKS "networks" +#define NSDB_PASSWD "passwd" +#define NSDB_PASSWD_COMPAT "passwd_compat" +#define NSDB_SHELLS "shells" +#define NSDB_SERVICES "services" +#define NSDB_SERVICES_COMPAT "services_compat" +#define NSDB_SSH_HOSTKEYS "ssh_hostkeys" +#define NSDB_PROTOCOLS "protocols" +#define NSDB_RPC "rpc" + +/* + * suggested databases to implement + */ +#define NSDB_ALIASES "aliases" +#define NSDB_AUTH "auth" +#define NSDB_AUTOMOUNT "automount" +#define NSDB_BOOTPARAMS "bootparams" +#define NSDB_ETHERS "ethers" +#define NSDB_EXPORTS "exports" +#define NSDB_NETMASKS "netmasks" +#define NSDB_PHONES "phones" +#define NSDB_PRINTCAP "printcap" +#define NSDB_REMOTE "remote" +#define NSDB_SENDMAILVARS "sendmailvars" +#define NSDB_TERMCAP "termcap" +#define NSDB_TTYS "ttys" + +/* + * ns_dtab `method' function signature. + */ +typedef int (*nss_method)(void *_retval, void *_mdata, va_list _ap); + +/* + * Macro for generating method prototypes. + */ +#define NSS_METHOD_PROTOTYPE(method) \ + int method(void *, void *, va_list) + +/* + * ns_dtab - `nsswitch dispatch table' + * Contains an entry for each source and the appropriate function to + * call. ns_dtabs are used in the nsdispatch() API in order to allow + * the application to override built-in actions. + */ +typedef struct _ns_dtab { + const char *src; /* Source this entry implements */ + nss_method method; /* Method to be called */ + void *mdata; /* Data passed to method */ +} ns_dtab; + +/* + * macros to help build an ns_dtab[] + */ +#define NS_FILES_CB(F,C) { NSSRC_FILES, F, C }, +#define NS_COMPAT_CB(F,C) { NSSRC_COMPAT, F, C }, +#define NS_FALLBACK_CB(F) { NSSRC_FALLBACK, F, NULL }, + +#ifdef HESIOD +# define NS_DNS_CB(F,C) { NSSRC_DNS, F, C }, +#else +# define NS_DNS_CB(F,C) +#endif + +#ifdef YP +# define NS_NIS_CB(F,C) { NSSRC_NIS, F, C }, +#else +# define NS_NIS_CB(F,C) +#endif + +/* + * ns_src - `nsswitch source' + * used by the nsparser routines to store a mapping between a source + * and its dispatch control flags for a given database. + */ +typedef struct _ns_src { + const char *name; + u_int32_t flags; +} ns_src; + + +/* + * default sourcelist (if nsswitch.conf is missing, corrupt, + * or the requested database doesn't have an entry. + */ +extern const ns_src __nsdefaultsrc[]; + +/* + * ns_mtab - NSS method table + * An NSS module provides a mapping from (database name, method name) + * tuples to the nss_method and associated data. + */ +typedef struct _ns_mtab { + const char *database; + const char *name; + nss_method method; + void *mdata; +} ns_mtab; + +/* + * NSS module de-registration, called at module unload. + */ +typedef void (*nss_module_unregister_fn)(ns_mtab *, unsigned int); + +/* + * NSS module registration, called at module load. + */ +typedef ns_mtab *(*nss_module_register_fn)(const char *, unsigned int *, + nss_module_unregister_fn *); + +/* + * Many NSS interfaces follow the getXXnam, getXXid, getXXent pattern. + * Developers are encouraged to use nss_lookup_type where approriate. + */ +enum nss_lookup_type { + nss_lt_name = 1, + nss_lt_id = 2, + nss_lt_all = 3 +}; + +#ifdef _NS_PRIVATE +/* + * private data structures for back-end nsswitch implementation + */ + +/* + * ns_dbt - `nsswitch database thang' + * for each database in /etc/nsswitch.conf there is a ns_dbt, with its + * name and a list of ns_src's containing the source information. + */ +typedef struct _ns_dbt { + const char *name; /* name of database */ + ns_src *srclist; /* list of sources */ + int srclistsize; /* size of srclist */ +} ns_dbt; + +/* + * ns_mod - NSS module + */ +typedef struct _ns_mod { + char *name; /* module name */ + void *handle; /* handle from dlopen */ + ns_mtab *mtab; /* method table */ + unsigned int mtabsize; /* count of entries in method table */ + nss_module_unregister_fn unregister; /* called to unload module */ +} ns_mod; + +#endif /* _NS_PRIVATE */ + + +#include + +__BEGIN_DECLS +extern int nsdispatch(void *, const ns_dtab [], const char *, + const char *, const ns_src [], ...); + +#ifdef _NS_PRIVATE +extern void _nsdbtaddsrc(ns_dbt *, const ns_src *); +extern void _nsdbtput(const ns_dbt *); +extern void _nsyyerror(const char *); +extern int _nsyylex(void); +extern int _nsyyparse(void); +extern int _nsyylineno; +#ifdef _NSS_DEBUG +extern void _nsdbtdump(const ns_dbt *); +#endif +#endif /* _NS_PRIVATE */ + +__END_DECLS + +#endif /* !_NSSWITCH_H */ diff --git a/include/printf.h b/include/printf.h new file mode 100644 index 0000000..e06c224 --- /dev/null +++ b/include/printf.h @@ -0,0 +1,164 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/printf.h 238111 2012-07-04 17:35:07Z pjd $ + */ + +#ifndef _PRINTF_H_ +#define _PRINTF_H_ + +#include +#include + +/* + * The API defined by glibc allows a renderer to take multiple arguments + * This is obviously usable for things like (ptr+len) pairs etc. + * But the do not actually provide support for it at the end of the day, + * they offer only one argument to the arginfo function, but do accept + * >1 returns, although the do not check the types of those arguments + * argument + * Be compatible for now. + */ +#define __PRINTFMAXARG 2 + +struct printf_info { + /* GLIBC compatible */ + int prec; + int width; + wchar_t spec; + unsigned is_long_double; + unsigned is_char; + unsigned is_short; + unsigned is_long; + unsigned alt; + unsigned space; + unsigned left; + unsigned showsign; + unsigned group; + unsigned extra; + unsigned wide; + wchar_t pad; + + /* FreeBSD extensions */ + + unsigned is_quad; + unsigned is_intmax; + unsigned is_ptrdiff; + unsigned is_size; + + /* private */ + int sofar; + unsigned get_width; + unsigned get_prec; + const char *begin; + const char *end; + void *arg[__PRINTFMAXARG]; +}; + +enum { + PA_INT = (1 << 0), /* int */ + PA_CHAR = (1 << 1), /* int, cast to char */ + PA_WCHAR = (1 << 2), /* wide char */ + PA_STRING = (1 << 3), /* const char * (with '\0') */ + PA_WSTRING = (1 << 4), /* const wchar_t * */ + PA_POINTER = (1 << 5), /* void * */ + PA_FLOAT = (1 << 6), /* float */ + PA_DOUBLE = (1 << 7) /* double */ +}; + +#define PA_FLAG_MASK 0xff0000 +#define PA_FLAG_LONG_LONG (1 << 16) +#define PA_FLAG_LONG (1 << 17) +#define PA_FLAG_SHORT (1 << 18) +#define PA_FLAG_PTR (1 << 19) +#define PA_FLAG_QUAD (1 << 20) +#define PA_FLAG_INTMAX (1 << 21) +#define PA_FLAG_SIZE (1 << 22) +#define PA_FLAG_PTRDIFF (1 << 23) +#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG + +typedef int printf_arginfo_function(const struct printf_info *, size_t, int *); +typedef int printf_function(FILE *, const struct printf_info *, const void *const *); + +/* FreeBSD extension */ +struct __printf_io; +typedef int printf_render(struct __printf_io *, const struct printf_info *, const void *const *); + +/* vprintf.c */ +extern const char __lowercase_hex[17]; +extern const char __uppercase_hex[17]; + +void __printf_flush(struct __printf_io *io); +int __printf_puts(struct __printf_io *io, const void *ptr, int len); +int __printf_pad(struct __printf_io *io, int n, int zero); +int __printf_out(struct __printf_io *io, const struct printf_info *pi, const void *ptr, int len); + +int __xvprintf(FILE *fp, const char *fmt0, va_list ap); +extern int __use_xprintf; + +/* GLIBC compat */ +int register_printf_function(int spec, printf_function *render, printf_arginfo_function *arginfo); + +/* FreeBSD */ +int register_printf_render(int spec, printf_render *render, printf_arginfo_function *arginfo); +int register_printf_render_std(const char *specs); + +/* vprintf_errno.c */ +printf_arginfo_function __printf_arginfo_errno; +printf_render __printf_render_errno; + +/* vprintf_float.c */ +printf_arginfo_function __printf_arginfo_float; +printf_render __printf_render_float; + +/* vprintf_hexdump.c */ +printf_arginfo_function __printf_arginfo_hexdump; +printf_render __printf_render_hexdump; + +/* vprintf_int.c */ +printf_arginfo_function __printf_arginfo_ptr; +printf_arginfo_function __printf_arginfo_int; +printf_render __printf_render_ptr; +printf_render __printf_render_int; + +/* vprintf_quoute.c */ +printf_arginfo_function __printf_arginfo_quote; +printf_render __printf_render_quote; + +/* vprintf_str.c */ +printf_arginfo_function __printf_arginfo_chr; +printf_render __printf_render_chr; +printf_arginfo_function __printf_arginfo_str; +printf_render __printf_render_str; + +/* vprintf_time.c */ +printf_arginfo_function __printf_arginfo_time; +printf_render __printf_render_time; + +/* vprintf_vis.c */ +printf_arginfo_function __printf_arginfo_vis; +printf_render __printf_render_vis; + +#endif /* !_PRINTF_H */ diff --git a/include/proc_service.h b/include/proc_service.h new file mode 100644 index 0000000..9d78666 --- /dev/null +++ b/include/proc_service.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2004 David Xu + * Copyright (c) 2004 Marcel Moolenaar + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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. + * + * $FreeBSD: releng/11.1/include/proc_service.h 155412 2006-02-07 02:29:55Z davidxu $ + */ + +#ifndef _PROC_SERVICE_H_ +#define _PROC_SERVICE_H_ + +#include +#include + +typedef enum { + PS_OK = 0, /* No errors. */ + PS_ERR, /* Generic error. */ + PS_BADADDR, /* Bad address. */ + PS_BADLID, /* Bad LWP Id. */ + PS_BADPID, /* Bad process Id. */ + PS_NOFREGS, /* FPU register set not available. */ + PS_NOSYM /* Symbol not found. */ +} ps_err_e; + +struct ps_prochandle; /* Opaque type. Defined by the implementor. */ + +__BEGIN_DECLS +ps_err_e ps_lcontinue(struct ps_prochandle *, lwpid_t); +ps_err_e ps_lgetfpregs(struct ps_prochandle *, lwpid_t, prfpregset_t *); +ps_err_e ps_lgetregs(struct ps_prochandle *, lwpid_t, prgregset_t); +ps_err_e ps_lsetfpregs(struct ps_prochandle *, lwpid_t, const prfpregset_t *); +ps_err_e ps_lsetregs(struct ps_prochandle *, lwpid_t, const prgregset_t); +#ifdef __i386__ +ps_err_e ps_lgetxmmregs (struct ps_prochandle *, lwpid_t, char *); +ps_err_e ps_lsetxmmregs (struct ps_prochandle *, lwpid_t, const char *); +#endif +ps_err_e ps_lstop(struct ps_prochandle *, lwpid_t); +ps_err_e ps_linfo(struct ps_prochandle *, lwpid_t, void *); +ps_err_e ps_pcontinue(struct ps_prochandle *); +ps_err_e ps_pdmodel(struct ps_prochandle *, int *); +ps_err_e ps_pglobal_lookup(struct ps_prochandle *, const char *, const char *, + psaddr_t *); +void ps_plog(const char *, ...); +ps_err_e ps_pread(struct ps_prochandle *, psaddr_t, void *, size_t); +ps_err_e ps_pstop(struct ps_prochandle *); +ps_err_e ps_pwrite(struct ps_prochandle *, psaddr_t, const void *, size_t); +__END_DECLS + +#endif /* _PROC_SERVICE_H_ */ diff --git a/include/protocols/Makefile b/include/protocols/Makefile new file mode 100644 index 0000000..346a5c6 --- /dev/null +++ b/include/protocols/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD: releng/11.1/include/protocols/Makefile 284255 2015-06-11 04:22:17Z sjg $ + +INCS= dumprestore.h routed.h rwhod.h talkd.h timed.h +INCSDIR=${INCLUDEDIR}/protocols + +.include diff --git a/include/protocols/Makefile.depend b/include/protocols/Makefile.depend new file mode 100644 index 0000000..2b0af55 --- /dev/null +++ b/include/protocols/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD: releng/11.1/include/protocols/Makefile.depend 284345 2015-06-13 19:20:56Z sjg $ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/include/protocols/dumprestore.h b/include/protocols/dumprestore.h new file mode 100644 index 0000000..652f348 --- /dev/null +++ b/include/protocols/dumprestore.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 1980, 1993 + * The Regents of the University of California. All rights reserved. + * (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. + * + * 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. + * + * @(#)dumprestore.h 8.2 (Berkeley) 1/21/94 + * + * $FreeBSD: releng/11.1/include/protocols/dumprestore.h 235601 2012-05-18 10:01:31Z gleb $ + */ + +#ifndef _PROTOCOLS_DUMPRESTORE_H_ +#define _PROTOCOLS_DUMPRESTORE_H_ + +/* + * TP_BSIZE is the size of file blocks on the dump tapes. + * Note that TP_BSIZE must be a multiple of DEV_BSIZE. + * + * NTREC is the number of TP_BSIZE blocks that are written + * in each tape record. HIGHDENSITYTREC is the number of + * TP_BSIZE blocks that are written in each tape record on + * 6250 BPI or higher density tapes. + * + * TP_NINDIR is the number of indirect pointers in a TS_INODE + * or TS_ADDR record. Note that it must be a power of two. + */ +#define TP_BSIZE 1024 +#define NTREC 10 +#define HIGHDENSITYTREC 32 +#define TP_NINDIR (TP_BSIZE/2) +#define LBLSIZE 16 +#define NAMELEN 64 + +#define OFS_MAGIC (int)60011 +#define NFS_MAGIC (int)60012 +#ifndef FS_UFS2_MAGIC +#define FS_UFS2_MAGIC (int)0x19540119 +#endif +#define CHECKSUM (int)84446 + +/* + * Since ino_t size is changing to 64-bits, yet we desire this structure to + * remain compatible with exiting dump formats, we do NOT use ino_t here, + * but rather define a 32-bit type in its place. At some point, it may be + * necessary to use some of the c_spare[] in order to fully support 64-bit + * inode numbers. + */ +typedef uint32_t dump_ino_t; + +union u_spcl { + char dummy[TP_BSIZE]; + struct s_spcl { + int32_t c_type; /* record type (see below) */ + int32_t c_old_date; /* date of this dump */ + int32_t c_old_ddate; /* date of previous dump */ + int32_t c_volume; /* dump volume number */ + int32_t c_old_tapea; /* logical block of this record */ + dump_ino_t c_inumber; /* number of inode */ + int32_t c_magic; /* magic number (see above) */ + int32_t c_checksum; /* record checksum */ + /* + * Start old dinode structure, expanded for binary + * compatibility with UFS1. + */ + u_int16_t c_mode; /* file mode */ + int16_t c_spare1[3]; /* old nlink, ids */ + u_int64_t c_size; /* file byte count */ + int32_t c_old_atime; /* old last access time, seconds */ + int32_t c_atimensec; /* last access time, nanoseconds */ + int32_t c_old_mtime; /* old last modified time, secs */ + int32_t c_mtimensec; /* last modified time, nanosecs */ + int32_t c_spare2[2]; /* old ctime */ + int32_t c_rdev; /* for devices, device number */ + int32_t c_birthtimensec; /* creation time, nanosecs */ + int64_t c_birthtime; /* creation time, seconds */ + int64_t c_atime; /* last access time, seconds */ + int64_t c_mtime; /* last modified time, seconds */ + int32_t c_extsize; /* external attribute size */ + int32_t c_spare4[6]; /* old block pointers */ + u_int32_t c_file_flags; /* status flags (chflags) */ + int32_t c_spare5[2]; /* old blocks, generation number */ + u_int32_t c_uid; /* file owner */ + u_int32_t c_gid; /* file group */ + int32_t c_spare6[2]; /* previously unused spares */ + /* + * End old dinode structure. + */ + int32_t c_count; /* number of valid c_addr entries */ + char c_addr[TP_NINDIR]; /* 1 => data; 0 => hole in inode */ + char c_label[LBLSIZE]; /* dump label */ + int32_t c_level; /* level of this dump */ + char c_filesys[NAMELEN]; /* name of dumpped file system */ + char c_dev[NAMELEN]; /* name of dumpped device */ + char c_host[NAMELEN]; /* name of dumpped host */ + int32_t c_flags; /* additional information */ + int32_t c_old_firstrec; /* first record on volume */ + int64_t c_date; /* date of this dump */ + int64_t c_ddate; /* date of previous dump */ + int64_t c_tapea; /* logical block of this record */ + int64_t c_firstrec; /* first record on volume */ + int32_t c_spare[24]; /* reserved for future uses */ + } s_spcl; +} u_spcl; +#define spcl u_spcl.s_spcl +/* + * special record types + */ +#define TS_TAPE 1 /* dump tape header */ +#define TS_INODE 2 /* beginning of file record */ +#define TS_ADDR 4 /* continuation of file record */ +#define TS_BITS 3 /* map of inodes on tape */ +#define TS_CLRI 6 /* map of inodes deleted since last dump */ +#define TS_END 5 /* end of volume marker */ + +#endif /* !_DUMPRESTORE_H_ */ diff --git a/include/protocols/routed.h b/include/protocols/routed.h new file mode 100644 index 0000000..11f9738 --- /dev/null +++ b/include/protocols/routed.h @@ -0,0 +1,172 @@ +/*- + * Copyright (c) 1983, 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. + * + * @(#)routed.h 8.1 (Berkeley) 6/2/93 + * + * $FreeBSD: releng/11.1/include/protocols/routed.h 203965 2010-02-16 19:46:46Z imp $ + * $Revision: 2.26 $ + */ + +#ifndef _ROUTED_H_ +#define _ROUTED_H_ +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Routing Information Protocol + * + * Derived from Xerox NS Routing Information Protocol + * by changing 32-bit net numbers to sockaddr's and + * padding stuff to 32-bit boundaries. + */ + +#define RIPv1 1 +#define RIPv2 2 +#ifndef RIPVERSION +#define RIPVERSION RIPv1 +#endif + +#define RIP_PORT 520 + +#if RIPVERSION == 1 +/* Note that this so called sockaddr has a 2-byte sa_family and no sa_len. + * It is not a UNIX sockaddr, but the shape of an address as defined + * in RIPv1. It is still defined to allow old versions of programs + * such as `gated` to use this file to define RIPv1. + */ +struct netinfo { + struct sockaddr rip_dst; /* destination net/host */ + u_int32_t rip_metric; /* cost of route */ +}; +#else +struct netinfo { + u_int16_t n_family; +#define RIP_AF_INET htons(AF_INET) +#define RIP_AF_UNSPEC 0 +#define RIP_AF_AUTH 0xffff + u_int16_t n_tag; /* optional in RIPv2 */ + u_int32_t n_dst; /* destination net or host */ +#define RIP_DEFAULT 0 + u_int32_t n_mask; /* netmask in RIPv2 */ + u_int32_t n_nhop; /* optional next hop in RIPv2 */ + u_int32_t n_metric; /* cost of route */ +}; +#endif + +/* RIPv2 authentication */ +struct netauth { + u_int16_t a_family; /* always RIP_AF_AUTH */ + u_int16_t a_type; +#define RIP_AUTH_NONE 0 +#define RIP_AUTH_PW htons(2) /* password type */ +#define RIP_AUTH_MD5 htons(3) /* Keyed MD5 */ + union { +#define RIP_AUTH_PW_LEN 16 + u_int8_t au_pw[RIP_AUTH_PW_LEN]; + struct a_md5 { + int16_t md5_pkt_len; /* RIP-II packet length */ + int8_t md5_keyid; /* key ID and auth data len */ + int8_t md5_auth_len; /* 16 */ + u_int32_t md5_seqno; /* sequence number */ + u_int32_t rsvd[2]; /* must be 0 */ +#define RIP_AUTH_MD5_KEY_LEN RIP_AUTH_PW_LEN +#define RIP_AUTH_MD5_HASH_XTRA (sizeof(struct netauth)-sizeof(struct a_md5)) +#define RIP_AUTH_MD5_HASH_LEN (RIP_AUTH_MD5_KEY_LEN+RIP_AUTH_MD5_HASH_XTRA) + } a_md5; + } au; +}; + +struct rip { + u_int8_t rip_cmd; /* request/response */ + u_int8_t rip_vers; /* protocol version # */ + u_int16_t rip_res1; /* pad to 32-bit boundary */ + union { /* variable length... */ + struct netinfo ru_nets[1]; + int8_t ru_tracefile[1]; + struct netauth ru_auth[1]; + } ripun; +#define rip_nets ripun.ru_nets +#define rip_auths ripun.ru_auth +#define rip_tracefile ripun.ru_tracefile +}; + +/* Packet types. + */ +#define RIPCMD_REQUEST 1 /* want info */ +#define RIPCMD_RESPONSE 2 /* responding to request */ +#define RIPCMD_TRACEON 3 /* turn tracing on */ +#define RIPCMD_TRACEOFF 4 /* turn it off */ + +/* Gated extended RIP to include a "poll" command instead of using + * RIPCMD_REQUEST with (RIP_AF_UNSPEC, RIP_DEFAULT). RFC 1058 says + * command 5 is used by Sun Microsystems for its own purposes. + */ +#define RIPCMD_POLL 5 + +#define RIPCMD_MAX 6 + +#ifdef RIPCMDS +const char *ripcmds[RIPCMD_MAX] = { + "#0", "REQUEST", "RESPONSE", "TRACEON", "TRACEOFF" +}; +#endif + +#define HOPCNT_INFINITY 16 +#define MAXPACKETSIZE 512 /* max broadcast size */ +#define NETS_LEN ((MAXPACKETSIZE-sizeof(struct rip)) \ + / sizeof(struct netinfo) +1) + +#define INADDR_RIP_GROUP (u_int32_t)0xe0000009 /* 224.0.0.9 */ + + +/* Timer values used in managing the routing table. + * + * Complete tables are broadcast every SUPPLY_INTERVAL seconds. + * If changes occur between updates, dynamic updates containing only changes + * may be sent. When these are sent, a timer is set for a random value + * between MIN_WAITTIME and MAX_WAITTIME, and no additional dynamic updates + * are sent until the timer expires. + * + * Every update of a routing entry forces an entry's timer to be reset. + * After EXPIRE_TIME without updates, the entry is marked invalid, + * but held onto until GARBAGE_TIME so that others may see it, to + * "poison" the bad route. + */ +#define SUPPLY_INTERVAL 30 /* time to supply tables */ +#define MIN_WAITTIME 2 /* min sec until next flash updates */ +#define MAX_WAITTIME 5 /* max sec until flash update */ + +#define STALE_TIME 90 /* switch to a new gateway */ +#define EXPIRE_TIME 180 /* time to mark entry invalid */ +#define GARBAGE_TIME 240 /* time to garbage collect */ + +#ifdef __cplusplus +} +#endif +#endif /* !_ROUTED_H_ */ diff --git a/include/protocols/rwhod.h b/include/protocols/rwhod.h new file mode 100644 index 0000000..391dbb3 --- /dev/null +++ b/include/protocols/rwhod.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 1983, 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. + * + * @(#)rwhod.h 8.1 (Berkeley) 6/2/93 + * + * $FreeBSD: releng/11.1/include/protocols/rwhod.h 250889 2013-05-21 21:50:11Z ed $ + */ + +#ifndef _PROTOCOLS_RWHOD_H_ +#define _PROTOCOLS_RWHOD_H_ + +#include + +/* + * rwho protocol packet format. + */ +struct outmp { + char out_line[8]; /* tty name */ + char out_name[8]; /* user id */ + __int32_t out_time; /* time on */ +}; + +struct whod { + char wd_vers; /* protocol version # */ + char wd_type; /* packet type, see below */ + char wd_pad[2]; + int wd_sendtime; /* time stamp by sender */ + int wd_recvtime; /* time stamp applied by receiver */ + char wd_hostname[32]; /* hosts's name */ + int wd_loadav[3]; /* load average as in uptime */ + int wd_boottime; /* time system booted */ + struct whoent { + struct outmp we_utmp; /* active tty info */ + int we_idle; /* tty idle time */ + } wd_we[1024 / sizeof (struct whoent)]; +}; + +#define WHODVERSION 1 +#define WHODTYPE_STATUS 1 /* host status */ + +#define _PATH_RWHODIR "/var/rwho" + +#endif /* !_RWHOD_H_ */ diff --git a/include/protocols/talkd.h b/include/protocols/talkd.h new file mode 100644 index 0000000..6e9e422 --- /dev/null +++ b/include/protocols/talkd.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 1983, 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. + * + * @(#)talkd.h 8.1 (Berkeley) 6/2/93 + * + * $FreeBSD: releng/11.1/include/protocols/talkd.h 203965 2010-02-16 19:46:46Z imp $ + */ + +#ifndef _PROTOCOLS_TALKD_H_ +#define _PROTOCOLS_TALKD_H_ + +/* + * This describes the protocol used by the talk server and clients. + * + * The talk server acts a repository of invitations, responding to + * requests by clients wishing to rendezvous for the purpose of + * holding a conversation. In normal operation, a client, the caller, + * initiates a rendezvous by sending a CTL_MSG to the server of + * type LOOK_UP. This causes the server to search its invitation + * tables to check if an invitation currently exists for the caller + * (to speak to the callee specified in the message). If the lookup + * fails, the caller then sends an ANNOUNCE message causing the server + * to broadcast an announcement on the callee's login ports requesting + * contact. When the callee responds, the local server uses the + * recorded invitation to respond with the appropriate rendezvous + * address and the caller and callee client programs establish a + * stream connection through which the conversation takes place. + */ + +/* + * Client->server request message format. + */ +typedef struct { + u_char vers; /* protocol version */ + u_char type; /* request type, see below */ + u_char answer; /* not used */ + u_char pad; + u_int32_t id_num; /* message id */ + struct osockaddr addr; /* old (4.3) style */ + struct osockaddr ctl_addr; /* old (4.3) style */ + int32_t pid; /* caller's process id */ +#define NAME_SIZE 12 + char l_name[NAME_SIZE];/* caller's name */ + char r_name[NAME_SIZE];/* callee's name */ +#define TTY_SIZE 16 + char r_tty[TTY_SIZE];/* callee's tty name */ +} CTL_MSG; + +/* + * Server->client response message format. + */ +typedef struct { + u_char vers; /* protocol version */ + u_char type; /* type of request message, see below */ + u_char answer; /* respose to request message, see below */ + u_char pad; + u_int32_t id_num; /* message id */ + struct osockaddr addr; /* address for establishing conversation */ +} CTL_RESPONSE; + +#define TALK_VERSION 1 /* protocol version */ + +/* message type values */ +#define LEAVE_INVITE 0 /* leave invitation with server */ +#define LOOK_UP 1 /* check for invitation by callee */ +#define DELETE 2 /* delete invitation by caller */ +#define ANNOUNCE 3 /* announce invitation by caller */ + +/* answer values */ +#define SUCCESS 0 /* operation completed properly */ +#define NOT_HERE 1 /* callee not logged in */ +#define FAILED 2 /* operation failed for unexplained reason */ +#define MACHINE_UNKNOWN 3 /* caller's machine name unknown */ +#define PERMISSION_DENIED 4 /* callee's tty doesn't permit announce */ +#define UNKNOWN_REQUEST 5 /* request has invalid type value */ +#define BADVERSION 6 /* request has invalid protocol version */ +#define BADADDR 7 /* request has invalid addr value */ +#define BADCTLADDR 8 /* request has invalid ctl_addr value */ + +/* + * Operational parameters. + */ +#define MAX_LIFE 60 /* max time daemon saves invitations */ +/* RING_WAIT should be 10's of seconds less than MAX_LIFE */ +#define RING_WAIT 30 /* time to wait before resending invitation */ + +#endif /* !_TALKD_H_ */ diff --git a/include/protocols/timed.h b/include/protocols/timed.h new file mode 100644 index 0000000..8695f7b --- /dev/null +++ b/include/protocols/timed.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1983, 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. + * + * @(#)timed.h 8.1 (Berkeley) 6/2/93 + * + * $FreeBSD: releng/11.1/include/protocols/timed.h 249311 2013-04-09 16:16:34Z ed $ + */ + +#ifndef _PROTOCOLS_TIMED_H_ +#define _PROTOCOLS_TIMED_H_ + +/* + * Time Synchronization Protocol + */ + +#define TSPVERSION 1 +#define ANYADDR NULL + +struct tsp { + u_int8_t tsp_type; + u_int8_t tsp_vers; + u_int16_t tsp_seq; + union { + struct { + int32_t tv_sec; + int32_t tv_usec; + } tspu_time; + char tspu_hopcnt; + } tsp_u; + char tsp_name[MAXHOSTNAMELEN]; +}; + +#define tsp_time tsp_u.tspu_time +#define tsp_hopcnt tsp_u.tspu_hopcnt + +/* + * Command types. + */ +#define TSP_ANY 0 /* match any types */ +#define TSP_ADJTIME 1 /* send adjtime */ +#define TSP_ACK 2 /* generic acknowledgement */ +#define TSP_MASTERREQ 3 /* ask for master's name */ +#define TSP_MASTERACK 4 /* acknowledge master request */ +#define TSP_SETTIME 5 /* send network time */ +#define TSP_MASTERUP 6 /* inform slaves that master is up */ +#define TSP_SLAVEUP 7 /* slave is up but not polled */ +#define TSP_ELECTION 8 /* advance candidature for master */ +#define TSP_ACCEPT 9 /* support candidature of master */ +#define TSP_REFUSE 10 /* reject candidature of master */ +#define TSP_CONFLICT 11 /* two or more masters present */ +#define TSP_RESOLVE 12 /* masters' conflict resolution */ +#define TSP_QUIT 13 /* reject candidature if master is up */ +#define TSP_DATE 14 /* reset the time (date command) */ +#define TSP_DATEREQ 15 /* remote request to reset the time */ +#define TSP_DATEACK 16 /* acknowledge time setting */ +#define TSP_TRACEON 17 /* turn tracing on */ +#define TSP_TRACEOFF 18 /* turn tracing off */ +#define TSP_MSITE 19 /* find out master's site */ +#define TSP_MSITEREQ 20 /* remote master's site request */ +#define TSP_TEST 21 /* for testing election algo */ +#define TSP_SETDATE 22 /* New from date command */ +#define TSP_SETDATEREQ 23 /* New remote for above */ +#define TSP_LOOP 24 /* loop detection packet */ + +#define TSPTYPENUMBER 25 + +#ifdef TSPTYPES +static char const * const tsptype[] = + { "ANY", "ADJTIME", "ACK", "MASTERREQ", "MASTERACK", "SETTIME", "MASTERUP", + "SLAVEUP", "ELECTION", "ACCEPT", "REFUSE", "CONFLICT", "RESOLVE", "QUIT", + "DATE", "DATEREQ", "DATEACK", "TRACEON", "TRACEOFF", "MSITE", "MSITEREQ", + "TEST", "SETDATE", "SETDATEREQ", "LOOP" }; +_Static_assert(sizeof(tsptype) / sizeof(const char *) == TSPTYPENUMBER, + "Size of tsptype does not match TSPTYPENUMBER"); +#endif + +#endif /* !_TIMED_H_ */ diff --git a/include/pthread.h b/include/pthread.h new file mode 100644 index 0000000..68eb560 --- /dev/null +++ b/include/pthread.h @@ -0,0 +1,350 @@ +/* + * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu + * Copyright (c) 1995-1998 by John Birrell + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * $FreeBSD: releng/11.1/include/pthread.h 315282 2017-03-14 20:14:57Z pfg $ + */ +#ifndef _PTHREAD_H_ +#define _PTHREAD_H_ + +/* + * Header files. + */ +#include +#include +#include +#include +#include +#include +#include + +__NULLABILITY_PRAGMA_PUSH + +/* + * Run-time invariant values: + */ +#define PTHREAD_DESTRUCTOR_ITERATIONS 4 +#define PTHREAD_KEYS_MAX 256 +#define PTHREAD_STACK_MIN __MINSIGSTKSZ +#define PTHREAD_THREADS_MAX __ULONG_MAX +#define PTHREAD_BARRIER_SERIAL_THREAD -1 + +/* + * Flags for threads and thread attributes. + */ +#define PTHREAD_DETACHED 0x1 +#define PTHREAD_SCOPE_SYSTEM 0x2 +#define PTHREAD_INHERIT_SCHED 0x4 +#define PTHREAD_NOFLOAT 0x8 + +#define PTHREAD_CREATE_DETACHED PTHREAD_DETACHED +#define PTHREAD_CREATE_JOINABLE 0 +#define PTHREAD_SCOPE_PROCESS 0 +#define PTHREAD_EXPLICIT_SCHED 0 + +/* + * Values for process shared/private attributes. + */ +#define PTHREAD_PROCESS_PRIVATE 0 +#define PTHREAD_PROCESS_SHARED 1 + +/* + * Flags for cancelling threads + */ +#define PTHREAD_CANCEL_ENABLE 0 +#define PTHREAD_CANCEL_DISABLE 1 +#define PTHREAD_CANCEL_DEFERRED 0 +#define PTHREAD_CANCEL_ASYNCHRONOUS 2 +#define PTHREAD_CANCELED ((void *) 1) + +/* + * Flags for once initialization. + */ +#define PTHREAD_NEEDS_INIT 0 +#define PTHREAD_DONE_INIT 1 + +/* + * Static once initialization values. + */ +#define PTHREAD_ONCE_INIT { PTHREAD_NEEDS_INIT, NULL } + +/* + * Static initialization values. + */ +#define PTHREAD_MUTEX_INITIALIZER NULL +#define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP ((pthread_mutex_t)1) +#define PTHREAD_COND_INITIALIZER NULL +#define PTHREAD_RWLOCK_INITIALIZER NULL + +/* + * Default attribute arguments (draft 4, deprecated). + */ +#ifndef PTHREAD_KERNEL +#define pthread_condattr_default NULL +#define pthread_mutexattr_default NULL +#define pthread_attr_default NULL +#endif + +#define PTHREAD_PRIO_NONE 0 +#define PTHREAD_PRIO_INHERIT 1 +#define PTHREAD_PRIO_PROTECT 2 + +/* + * Mutex types (Single UNIX Specification, Version 2, 1997). + * + * Note that a mutex attribute with one of the following types: + * + * PTHREAD_MUTEX_NORMAL + * PTHREAD_MUTEX_RECURSIVE + * + * will deviate from POSIX specified semantics. + */ +enum pthread_mutextype { + PTHREAD_MUTEX_ERRORCHECK = 1, /* Default POSIX mutex */ + PTHREAD_MUTEX_RECURSIVE = 2, /* Recursive mutex */ + PTHREAD_MUTEX_NORMAL = 3, /* No error checking */ + PTHREAD_MUTEX_ADAPTIVE_NP = 4, /* Adaptive mutex, spins briefly before blocking on lock */ + PTHREAD_MUTEX_TYPE_MAX +}; + +#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_ERRORCHECK + +#define PTHREAD_MUTEX_STALLED 0 +#define PTHREAD_MUTEX_ROBUST 1 + +struct _pthread_cleanup_info { + __uintptr_t pthread_cleanup_pad[8]; +}; + +/* + * Thread function prototype definitions: + */ +__BEGIN_DECLS +int pthread_atfork(void (*)(void), void (*)(void), void (*)(void)); +int pthread_attr_destroy(pthread_attr_t * _Nonnull); +int pthread_attr_getstack( + const pthread_attr_t * _Nonnull __restrict, + void ** _Nonnull __restrict, + size_t * _Nonnull __restrict); +int pthread_attr_getstacksize(const pthread_attr_t * _Nonnull, + size_t * _Nonnull); +int pthread_attr_getguardsize(const pthread_attr_t * _Nonnull, + size_t * _Nonnull); +int pthread_attr_getstackaddr(const pthread_attr_t *, void **); +int pthread_attr_getdetachstate(const pthread_attr_t * _Nonnull, + int * _Nonnull); +int pthread_attr_init(pthread_attr_t * _Nonnull); +int pthread_attr_setstacksize(pthread_attr_t * _Nonnull, size_t); +int pthread_attr_setguardsize(pthread_attr_t * _Nonnull, size_t); +int pthread_attr_setstack(pthread_attr_t * _Nonnull, void *, + size_t); +int pthread_attr_setstackaddr(pthread_attr_t *, void *); +int pthread_attr_setdetachstate(pthread_attr_t * _Nonnull, int); +int pthread_barrier_destroy(pthread_barrier_t * _Nonnull); +int pthread_barrier_init(pthread_barrier_t * _Nonnull, + const pthread_barrierattr_t *, unsigned); +int pthread_barrier_wait(pthread_barrier_t * _Nonnull); +int pthread_barrierattr_destroy(pthread_barrierattr_t * _Nonnull); +int pthread_barrierattr_getpshared( + const pthread_barrierattr_t * _Nonnull, int * _Nonnull); +int pthread_barrierattr_init(pthread_barrierattr_t * _Nonnull); +int pthread_barrierattr_setpshared(pthread_barrierattr_t * _Nonnull, + int); + +#define pthread_cleanup_push(cleanup_routine, cleanup_arg) \ + { \ + struct _pthread_cleanup_info __cleanup_info__; \ + __pthread_cleanup_push_imp(cleanup_routine, cleanup_arg,\ + &__cleanup_info__); \ + { + +#define pthread_cleanup_pop(execute) \ + (void)0; \ + } \ + __pthread_cleanup_pop_imp(execute); \ + } + +int pthread_condattr_destroy(pthread_condattr_t * _Nonnull); +int pthread_condattr_getclock(const pthread_condattr_t * _Nonnull, + clockid_t * _Nonnull); +int pthread_condattr_getpshared(const pthread_condattr_t * _Nonnull, + int * _Nonnull); +int pthread_condattr_init(pthread_condattr_t * _Nonnull); +int pthread_condattr_setclock(pthread_condattr_t * _Nonnull, + clockid_t); +int pthread_condattr_setpshared(pthread_condattr_t * _Nonnull, int); +int pthread_cond_broadcast(pthread_cond_t * _Nonnull); +int pthread_cond_destroy(pthread_cond_t * _Nonnull); +int pthread_cond_init(pthread_cond_t * _Nonnull, + const pthread_condattr_t *); +int pthread_cond_signal(pthread_cond_t * _Nonnull); +int pthread_cond_timedwait(pthread_cond_t * _Nonnull, + pthread_mutex_t * _Nonnull __mutex, + const struct timespec * _Nonnull) + __requires_exclusive(*__mutex); +int pthread_cond_wait(pthread_cond_t * _Nonnull, + pthread_mutex_t * _Nonnull __mutex) + __requires_exclusive(*__mutex); +int pthread_create(pthread_t * _Nonnull, const pthread_attr_t *, + void *(* _Nonnull) (void *), void *); +int pthread_detach(pthread_t); +int pthread_equal(pthread_t, pthread_t); +void pthread_exit(void *) __dead2; +void *pthread_getspecific(pthread_key_t); +int pthread_getcpuclockid(pthread_t, clockid_t * _Nonnull); +int pthread_join(pthread_t, void **); +int pthread_key_create(pthread_key_t * _Nonnull, + void (*) (void *)); +int pthread_key_delete(pthread_key_t); +int pthread_mutexattr_init(pthread_mutexattr_t * _Nonnull); +int pthread_mutexattr_destroy(pthread_mutexattr_t * _Nonnull); +int pthread_mutexattr_getpshared( + const pthread_mutexattr_t * _Nonnull, int * _Nonnull); +int pthread_mutexattr_gettype(pthread_mutexattr_t * _Nonnull, + int * _Nonnull); +int pthread_mutexattr_settype(pthread_mutexattr_t * _Nonnull, int); +int pthread_mutexattr_setpshared(pthread_mutexattr_t * _Nonnull, + int); +int pthread_mutex_consistent(pthread_mutex_t * _Nonnull __mutex) + __requires_exclusive(*__mutex); +int pthread_mutex_destroy(pthread_mutex_t * _Nonnull __mutex) + __requires_unlocked(*__mutex); +int pthread_mutex_init(pthread_mutex_t * _Nonnull __mutex, + const pthread_mutexattr_t *) + __requires_unlocked(*__mutex); +int pthread_mutex_lock(pthread_mutex_t * _Nonnull __mutex) + __locks_exclusive(*__mutex); +int pthread_mutex_trylock(pthread_mutex_t * _Nonnull __mutex) + __trylocks_exclusive(0, *__mutex); +int pthread_mutex_timedlock(pthread_mutex_t * _Nonnull __mutex, + const struct timespec * _Nonnull) + __trylocks_exclusive(0, *__mutex); +int pthread_mutex_unlock(pthread_mutex_t * _Nonnull __mutex) + __unlocks(*__mutex); +int pthread_once(pthread_once_t * _Nonnull, + void (* _Nonnull) (void)); +int pthread_rwlock_destroy(pthread_rwlock_t * _Nonnull __rwlock) + __requires_unlocked(*__rwlock); +int pthread_rwlock_init(pthread_rwlock_t * _Nonnull __rwlock, + const pthread_rwlockattr_t *) + __requires_unlocked(*__rwlock); +int pthread_rwlock_rdlock(pthread_rwlock_t * _Nonnull __rwlock) + __locks_shared(*__rwlock); +int pthread_rwlock_timedrdlock(pthread_rwlock_t * _Nonnull __rwlock, + const struct timespec * _Nonnull) + __trylocks_shared(0, *__rwlock); +int pthread_rwlock_timedwrlock(pthread_rwlock_t * _Nonnull __rwlock, + const struct timespec * _Nonnull) + __trylocks_exclusive(0, *__rwlock); +int pthread_rwlock_tryrdlock(pthread_rwlock_t * _Nonnull __rwlock) + __trylocks_shared(0, *__rwlock); +int pthread_rwlock_trywrlock(pthread_rwlock_t * _Nonnull __rwlock) + __trylocks_exclusive(0, *__rwlock); +int pthread_rwlock_unlock(pthread_rwlock_t * _Nonnull __rwlock) + __unlocks(*__rwlock); +int pthread_rwlock_wrlock(pthread_rwlock_t * _Nonnull __rwlock) + __locks_exclusive(*__rwlock); +int pthread_rwlockattr_destroy(pthread_rwlockattr_t * _Nonnull); +int pthread_rwlockattr_getkind_np( + const pthread_rwlockattr_t * _Nonnull, int *); +int pthread_rwlockattr_getpshared( + const pthread_rwlockattr_t * _Nonnull, int * _Nonnull); +int pthread_rwlockattr_init(pthread_rwlockattr_t * _Nonnull); +int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t * _Nonnull, + int); +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t * _Nonnull, + int); +pthread_t pthread_self(void); +int pthread_setspecific(pthread_key_t, const void *); + +int pthread_spin_init(pthread_spinlock_t * _Nonnull __spin, int) + __requires_unlocked(*__spin); +int pthread_spin_destroy(pthread_spinlock_t * _Nonnull __spin) + __requires_unlocked(*__spin); +int pthread_spin_lock(pthread_spinlock_t * _Nonnull __spin) + __locks_exclusive(*__spin); +int pthread_spin_trylock(pthread_spinlock_t * _Nonnull __spin) + __trylocks_exclusive(0, *__spin); +int pthread_spin_unlock(pthread_spinlock_t * _Nonnull __spin) + __unlocks(*__spin); +int pthread_cancel(pthread_t); +int pthread_setcancelstate(int, int *); +int pthread_setcanceltype(int, int *); +void pthread_testcancel(void); + +#if __BSD_VISIBLE +int pthread_getprio(pthread_t); +int pthread_setprio(pthread_t, int); +void pthread_yield(void); +#endif + +int pthread_mutexattr_getprioceiling(pthread_mutexattr_t *, int *); +int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int); +int pthread_mutex_getprioceiling(pthread_mutex_t *, int *); +int pthread_mutex_setprioceiling(pthread_mutex_t *, int, int *); + +int pthread_mutexattr_getprotocol(pthread_mutexattr_t *, int *); +int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int); + +int pthread_mutexattr_getrobust( + pthread_mutexattr_t * _Nonnull __restrict, + int * _Nonnull __restrict); +int pthread_mutexattr_setrobust(pthread_mutexattr_t * _Nonnull, + int); + +int pthread_attr_getinheritsched(const pthread_attr_t *, int *); +int pthread_attr_getschedparam(const pthread_attr_t * _Nonnull, + struct sched_param * _Nonnull); +int pthread_attr_getschedpolicy(const pthread_attr_t * _Nonnull, + int * _Nonnull); +int pthread_attr_getscope(const pthread_attr_t * _Nonnull, + int * _Nonnull); +int pthread_attr_setinheritsched(pthread_attr_t *, int); +int pthread_attr_setschedparam(pthread_attr_t * _Nonnull, + const struct sched_param * _Nonnull); +int pthread_attr_setschedpolicy(pthread_attr_t * _Nonnull, int); +int pthread_attr_setscope(pthread_attr_t * _Nonnull, int); +int pthread_getschedparam(pthread_t pthread, int * _Nonnull, + struct sched_param * _Nonnull); +int pthread_setschedparam(pthread_t, int, + const struct sched_param * _Nonnull); +#if __XSI_VISIBLE +int pthread_getconcurrency(void); +int pthread_setconcurrency(int); +#endif + +void __pthread_cleanup_push_imp(void (*)(void *), void *, + struct _pthread_cleanup_info *); +void __pthread_cleanup_pop_imp(int); +__END_DECLS +__NULLABILITY_PRAGMA_POP + +#endif /* _PTHREAD_H_ */ diff --git a/include/pthread_np.h b/include/pthread_np.h new file mode 100644 index 0000000..bb745a9 --- /dev/null +++ b/include/pthread_np.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 1996-98 John Birrell . + * 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 author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL 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. + * + * $FreeBSD: releng/11.1/include/pthread_np.h 218414 2011-02-07 21:26:46Z jkim $ + */ +#ifndef _PTHREAD_NP_H_ +#define _PTHREAD_NP_H_ + +#include +#include + +/* + * Non-POSIX type definitions: + */ +typedef void (*pthread_switch_routine_t)(pthread_t, pthread_t); + +/* + * Non-POSIX thread function prototype definitions: + */ +__BEGIN_DECLS +int pthread_attr_setcreatesuspend_np(pthread_attr_t *); +int pthread_attr_get_np(pthread_t, pthread_attr_t *); +int pthread_attr_getaffinity_np(const pthread_attr_t *, size_t, cpuset_t *); +int pthread_attr_setaffinity_np(pthread_attr_t *, size_t, const cpuset_t *); +int pthread_getaffinity_np(pthread_t, size_t, cpuset_t *); +int pthread_getthreadid_np(void); +int pthread_main_np(void); +int pthread_multi_np(void); +int pthread_mutexattr_getkind_np(pthread_mutexattr_t); +int pthread_mutexattr_setkind_np(pthread_mutexattr_t *, int); +void pthread_resume_all_np(void); +int pthread_resume_np(pthread_t); +void pthread_set_name_np(pthread_t, const char *); +int pthread_mutex_getspinloops_np(pthread_mutex_t *mutex, int *count); +int pthread_mutex_setspinloops_np(pthread_mutex_t *mutex, int count); +int pthread_mutex_getyieldloops_np(pthread_mutex_t *mutex, int *count); +int pthread_mutex_setyieldloops_np(pthread_mutex_t *mutex, int count); +int pthread_mutex_isowned_np(pthread_mutex_t *mutex); +int pthread_setaffinity_np(pthread_t, size_t, const cpuset_t *); +int pthread_single_np(void); +void pthread_suspend_all_np(void); +int pthread_suspend_np(pthread_t); +int pthread_switch_add_np(pthread_switch_routine_t); +int pthread_switch_delete_np(pthread_switch_routine_t); +int pthread_timedjoin_np(pthread_t, void **, const struct timespec *); +__END_DECLS + +#endif diff --git a/include/pwd.h b/include/pwd.h new file mode 100644 index 0000000..96329a5 --- /dev/null +++ b/include/pwd.h @@ -0,0 +1,175 @@ +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (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. + * + * 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. + * + * @(#)pwd.h 8.2 (Berkeley) 1/21/94 + * $FreeBSD: releng/11.1/include/pwd.h 241731 2012-10-19 12:44:22Z brooks $ + */ + +#ifndef _PWD_H_ +#define _PWD_H_ + +#include +#include + +#ifndef _GID_T_DECLARED +typedef __gid_t gid_t; +#define _GID_T_DECLARED +#endif + +#ifndef _TIME_T_DECLARED +typedef __time_t time_t; +#define _TIME_T_DECLARED +#endif + +#ifndef _UID_T_DECLARED +typedef __uid_t uid_t; +#define _UID_T_DECLARED +#endif + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +#define _PATH_PWD "/etc" +#define _PATH_PASSWD "/etc/passwd" +#define _PASSWD "passwd" +#define _PATH_MASTERPASSWD "/etc/master.passwd" +#define _MASTERPASSWD "master.passwd" + +#define _PATH_MP_DB "/etc/pwd.db" +#define _MP_DB "pwd.db" +#define _PATH_SMP_DB "/etc/spwd.db" +#define _SMP_DB "spwd.db" + +#define _PATH_PWD_MKDB "/usr/sbin/pwd_mkdb" + +/* Historically, the keys in _PATH_MP_DB/_PATH_SMP_DB had the format + * `1 octet tag | key', where the tag is one of the _PW_KEY* values + * listed below. These values happen to be ASCII digits. Starting + * with FreeBSD 5.1, the tag is now still a single octet, but the + * upper 4 bits are interpreted as a version. Pre-FreeBSD 5.1 format + * entries are version `3' -- this conveniently results in the same + * key values as before. The new, architecture-independent entries + * are version `4'. + * As it happens, some applications read the database directly. + * (Bad app, no cookie!) Thus, we leave the _PW_KEY* symbols at their + * old pre-FreeBSD 5.1 values so these apps still work. Consequently + * we have to muck around a bit more to get the correct, versioned + * tag, and that is what the _PW_VERSIONED macro is about. + */ + +#define _PW_VERSION_MASK '\xF0' +#define _PW_VERSIONED(x, v) ((unsigned char)(((x) & 0xCF) | ((v)<<4))) + +#define _PW_KEYBYNAME '\x31' /* stored by name */ +#define _PW_KEYBYNUM '\x32' /* stored by entry in the "file" */ +#define _PW_KEYBYUID '\x33' /* stored by uid */ +#define _PW_KEYYPENABLED '\x34' /* YP is enabled */ +#define _PW_KEYYPBYNUM '\x35' /* special +@netgroup entries */ + +/* The database also contains a key to indicate the format version of + * the entries therein. There may be other, older versioned entries + * as well. + */ +#define _PWD_VERSION_KEY "\xFF" "VERSION" +#define _PWD_CURRENT_VERSION '\x04' + +#define _PASSWORD_EFMT1 '_' /* extended encryption format */ + +#define _PASSWORD_LEN 128 /* max length, not counting NULL */ + +struct passwd { + char *pw_name; /* user name */ + char *pw_passwd; /* encrypted password */ + uid_t pw_uid; /* user uid */ + gid_t pw_gid; /* user gid */ + time_t pw_change; /* password change time */ + char *pw_class; /* user access class */ + char *pw_gecos; /* Honeywell login info */ + char *pw_dir; /* home directory */ + char *pw_shell; /* default shell */ + time_t pw_expire; /* account expiration */ + int pw_fields; /* internal: fields filled in */ +}; + +/* Mapping from fields to bits for pw_fields. */ +#define _PWF(x) (1 << x) +#define _PWF_NAME _PWF(0) +#define _PWF_PASSWD _PWF(1) +#define _PWF_UID _PWF(2) +#define _PWF_GID _PWF(3) +#define _PWF_CHANGE _PWF(4) +#define _PWF_CLASS _PWF(5) +#define _PWF_GECOS _PWF(6) +#define _PWF_DIR _PWF(7) +#define _PWF_SHELL _PWF(8) +#define _PWF_EXPIRE _PWF(9) + +/* XXX These flags are bogus. With nsswitch, there are many + * possible sources and they cannot be represented in a small integer. + */ +#define _PWF_SOURCE 0x3000 +#define _PWF_FILES 0x1000 +#define _PWF_NIS 0x2000 +#define _PWF_HESIOD 0x3000 + +__BEGIN_DECLS +struct passwd *getpwnam(const char *); +struct passwd *getpwuid(uid_t); + +#if __XSI_VISIBLE >= 500 +void endpwent(void); +struct passwd *getpwent(void); +void setpwent(void); +#endif + +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE >= 500 +int getpwnam_r(const char *, struct passwd *, char *, size_t, + struct passwd **); +int getpwuid_r(uid_t, struct passwd *, char *, size_t, + struct passwd **); +#endif + +#if __BSD_VISIBLE +int getpwent_r(struct passwd *, char *, size_t, struct passwd **); +int setpassent(int); +const char *user_from_uid(uid_t, int); +int uid_from_user(const char *, uid_t *); +int pwcache_userdb(int (*)(int), void (*)(void), + struct passwd * (*)(const char *), + struct passwd * (*)(uid_t)); +#endif +__END_DECLS + +#endif /* !_PWD_H_ */ diff --git a/include/ranlib.h b/include/ranlib.h new file mode 100644 index 0000000..90f55ac --- /dev/null +++ b/include/ranlib.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 1990, 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. + * + * @(#)ranlib.h 8.1 (Berkeley) 6/2/93 + * + * $FreeBSD: releng/11.1/include/ranlib.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _RANLIB_H_ +#define _RANLIB_H_ + +#define RANLIBMAG "__.SYMDEF" /* archive file name */ +#define RANLIBSKEW 3 /* creation time offset */ + +struct ranlib { + union { + long ran_strx; /* string table index */ + char *ran_name; /* in memory symbol name */ + } ran_un; + long ran_off; /* archive file offset */ +}; + +#endif /* !_RANLIB_H_ */ diff --git a/include/readpassphrase.h b/include/readpassphrase.h new file mode 100644 index 0000000..1d59df7 --- /dev/null +++ b/include/readpassphrase.h @@ -0,0 +1,47 @@ +/* $OpenBSD: readpassphrase.h,v 1.5 2003/06/17 21:56:23 millert Exp $ */ +/* $FreeBSD: releng/11.1/include/readpassphrase.h 215236 2010-11-13 10:38:06Z delphij $ */ + +/* + * Copyright (c) 2000, 2002 Todd C. Miller + * + * 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. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ + +#ifndef _READPASSPHRASE_H_ +#define _READPASSPHRASE_H_ + +#define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ +#define RPP_ECHO_ON 0x01 /* Leave echo on. */ +#define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ +#define RPP_FORCELOWER 0x04 /* Force input to lower case. */ +#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ +#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ +#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */ + +#include +#include + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +__BEGIN_DECLS +char * readpassphrase(const char *, char *, size_t, int); +__END_DECLS + +#endif /* !_READPASSPHRASE_H_ */ diff --git a/include/res_update.h b/include/res_update.h new file mode 100644 index 0000000..ea00941 --- /dev/null +++ b/include/res_update.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1999 by Internet Software Consortium, Inc. + * + * 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 ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. + */ + +/* + * $Id: res_update.h,v 1.3 2005/04/27 04:56:15 sra Exp $ + * $FreeBSD: releng/11.1/include/res_update.h 269867 2014-08-12 12:36:06Z ume $ + */ + +#ifndef __RES_UPDATE_H +#define __RES_UPDATE_H + +/*! \file */ + +#include +#include +#include + +/*% + * This RR-like structure is particular to UPDATE. + */ +struct ns_updrec { + struct { + struct ns_updrec *prev; + struct ns_updrec *next; + } r_link, r_glink; + ns_sect r_section; /*%< ZONE/PREREQUISITE/UPDATE */ + char * r_dname; /*%< owner of the RR */ + ns_class r_class; /*%< class number */ + ns_type r_type; /*%< type number */ + u_int32_t r_ttl; /*%< time to live */ + u_char * r_data; /*%< rdata fields as text string */ + u_int r_size; /*%< size of r_data field */ + int r_opcode; /*%< type of operation */ + /* following fields for private use by the resolver/server routines */ + struct databuf *r_dp; /*%< databuf to process */ + struct databuf *r_deldp; /*%< databuf's deleted/overwritten */ + u_int r_zone; /*%< zone number on server */ +}; +typedef struct ns_updrec ns_updrec; +typedef struct { + ns_updrec *head; + ns_updrec *tail; +} ns_updque; + +#define res_mkupdate __res_mkupdate +#define res_update __res_update +#define res_mkupdrec __res_mkupdrec +#define res_freeupdrec __res_freeupdrec +#define res_nmkupdate __res_nmkupdate +#define res_nupdate __res_nupdate + +int res_mkupdate(ns_updrec *, u_char *, int); +int res_update(ns_updrec *); +ns_updrec * res_mkupdrec(int, const char *, u_int, u_int, u_long); +void res_freeupdrec(ns_updrec *); +int res_nmkupdate(res_state, ns_updrec *, u_char *, int); +int res_nupdate(res_state, ns_updrec *, ns_tsig_key *); + +#endif /*__RES_UPDATE_H*/ + +/*! \file */ diff --git a/include/resolv.h b/include/resolv.h new file mode 100644 index 0000000..2cf01a3 --- /dev/null +++ b/include/resolv.h @@ -0,0 +1,503 @@ +/* + * Portions Copyright (C) 2004, 2005, 2008, 2009 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 1995-2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC 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. + */ + +/* + * Copyright (c) 1983, 1987, 1989 + * 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. + */ + +/*% + * @(#)resolv.h 8.1 (Berkeley) 6/2/93 + * $Id: resolv.h,v 1.30 2009/03/03 01:52:48 each Exp $ + * $FreeBSD: releng/11.1/include/resolv.h 292216 2015-12-14 17:21:06Z vangyzen $ + */ + +#ifndef _RESOLV_H_ +#define _RESOLV_H_ + +#include +#include +#include +#include +#include +#include + +/*% + * Revision information. This is the release date in YYYYMMDD format. + * It can change every day so the right thing to do with it is use it + * in preprocessor commands such as "#if (__RES > 19931104)". Do not + * compare for equality; rather, use it to determine whether your resolver + * is new enough to contain a certain feature. + */ + +#define __RES 20090302 + +/*% + * This used to be defined in res_query.c, now it's in herror.c. + * [XXX no it's not. It's in irs/irs_data.c] + * It was + * never extern'd by any *.h file before it was placed here. For thread + * aware programs, the last h_errno value set is stored in res->h_errno. + * + * XXX: There doesn't seem to be a good reason for exposing RES_SET_H_ERRNO + * (and __h_errno_set) to the public via . + * XXX: __h_errno_set is really part of IRS, not part of the resolver. + * If somebody wants to build and use a resolver that doesn't use IRS, + * what do they do? Perhaps something like + * #ifdef WANT_IRS + * # define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x) + * #else + * # define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x)) + * #endif + */ + +#define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x) +struct __res_state; /*%< forward */ +__BEGIN_DECLS +void __h_errno_set(struct __res_state *, int); +__END_DECLS + +/*% + * Resolver configuration file. + * Normally not present, but may contain the address of the + * initial name server(s) to query and the domain search list. + */ + +#ifndef _PATH_RESCONF +#define _PATH_RESCONF "/etc/resolv.conf" +#endif + +typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error } + res_sendhookact; + +typedef res_sendhookact (*res_send_qhook)(struct sockaddr * const *, + const u_char **, int *, + u_char *, int, int *); + +typedef res_sendhookact (*res_send_rhook)(const struct sockaddr *, + const u_char *, int, u_char *, + int, int *); + +struct res_sym { + int number; /*%< Identifying number, like T_MX */ + const char * name; /*%< Its symbolic name, like "MX" */ + const char * humanname; /*%< Its fun name, like "mail exchanger" */ +}; + +/*% + * Global defines and variables for resolver stub. + */ +#define MAXNS 3 /*%< max # name servers we'll track */ +#define MAXDFLSRCH 3 /*%< # default domain levels to try */ +#define MAXDNSRCH 6 /*%< max # domains in search path */ +#define LOCALDOMAINPARTS 2 /*%< min levels in name that is "local" */ +#define RES_TIMEOUT 5 /*%< min. seconds between retries */ +#define MAXRESOLVSORT 10 /*%< number of net to sort on */ +#define RES_MAXNDOTS 15 /*%< should reflect bit field size */ +#define RES_MAXRETRANS 30 /*%< only for resolv.conf/RES_OPTIONS */ +#define RES_MAXRETRY 5 /*%< only for resolv.conf/RES_OPTIONS */ +#define RES_DFLRETRY 2 /*%< Default #/tries. */ +#define RES_MAXTIME 65535 /*%< Infinity, in milliseconds. */ +struct __res_state_ext; + +struct __res_state { + int retrans; /*%< retransmission time interval */ + int retry; /*%< number of times to retransmit */ + /* + * XXX: If `sun' is defined, `options' and `pfcode' are + * defined as u_int in original BIND9 distribution. However, + * it breaks binary backward compatibility against FreeBSD's + * resolver. So, we changed not to see `sun'. + */ +#if defined(sun) && 0 + u_int options; /*%< option flags - see below. */ +#else + u_long options; /*%< option flags - see below. */ +#endif + int nscount; /*%< number of name servers */ + struct sockaddr_in + nsaddr_list[MAXNS]; /*%< address of name server */ +#define nsaddr nsaddr_list[0] /*%< for backward compatibility */ + u_short id; /*%< current message id */ + char *dnsrch[MAXDNSRCH+1]; /*%< components of domain to search */ + char defdname[256]; /*%< default domain (deprecated) */ +#if defined(sun) && 0 + u_int pfcode; /*%< RES_PRF_ flags - see below. */ +#else + u_long pfcode; /*%< RES_PRF_ flags - see below. */ +#endif + unsigned ndots:4; /*%< threshold for initial abs. query */ + unsigned nsort:4; /*%< number of elements in sort_list[] */ + char unused[3]; + struct { + struct in_addr addr; + u_int32_t mask; + } sort_list[MAXRESOLVSORT]; + res_send_qhook qhook; /*%< query hook */ + res_send_rhook rhook; /*%< response hook */ + int res_h_errno; /*%< last one set for this context */ + int _vcsock; /*%< PRIVATE: for res_send VC i/o */ + u_int _flags; /*%< PRIVATE: see below */ + u_int _pad; /*%< make _u 64 bit aligned */ + union { + /* On an 32-bit arch this means 512b total. */ + char pad[72 - 4*sizeof (int) - 3*sizeof (void *)]; + struct { + u_int16_t nscount; + u_int16_t nstimes[MAXNS]; /*%< ms. */ + int nssocks[MAXNS]; + struct __res_state_ext *ext; /*%< extension for IPv6 */ + } _ext; + } _u; + u_char *_rnd; /*%< PRIVATE: random state */ +}; + +typedef struct __res_state *res_state; + +union res_sockaddr_union { + struct sockaddr_in sin; +#ifdef IN6ADDR_ANY_INIT + struct sockaddr_in6 sin6; +#endif +#ifdef ISC_ALIGN64 + int64_t __align64; /*%< 64bit alignment */ +#else + int32_t __align32; /*%< 32bit alignment */ +#endif + char __space[128]; /*%< max size */ +}; + +/*% + * Resolver flags (used to be discrete per-module statics ints). + */ +#define RES_F_VC 0x00000001 /*%< socket is TCP */ +#define RES_F_CONN 0x00000002 /*%< socket is connected */ +#define RES_F_EDNS0ERR 0x00000004 /*%< EDNS0 caused errors */ +#define RES_F__UNUSED 0x00000008 /*%< (unused) */ +#define RES_F_LASTMASK 0x000000F0 /*%< ordinal server of last res_nsend */ +#define RES_F_LASTSHIFT 4 /*%< bit position of LASTMASK "flag" */ +#define RES_GETLAST(res) (((res)._flags & RES_F_LASTMASK) >> RES_F_LASTSHIFT) + +/* res_findzonecut2() options */ +#define RES_EXHAUSTIVE 0x00000001 /*%< always do all queries */ +#define RES_IPV4ONLY 0x00000002 /*%< IPv4 only */ +#define RES_IPV6ONLY 0x00000004 /*%< IPv6 only */ + +/*% + * Resolver options (keep these in synch with res_debug.c, please) + */ +#define RES_INIT 0x00000001 /*%< address initialized */ +#define RES_DEBUG 0x00000002 /*%< print debug messages */ +#define RES_AAONLY 0x00000004 /*%< authoritative answers only (!IMPL)*/ +#define RES_USEVC 0x00000008 /*%< use virtual circuit */ +#define RES_PRIMARY 0x00000010 /*%< query primary server only (!IMPL) */ +#define RES_IGNTC 0x00000020 /*%< ignore truncation errors */ +#define RES_RECURSE 0x00000040 /*%< recursion desired */ +#define RES_DEFNAMES 0x00000080 /*%< use default domain name */ +#define RES_STAYOPEN 0x00000100 /*%< Keep TCP socket open */ +#define RES_DNSRCH 0x00000200 /*%< search up local domain tree */ +#define RES_INSECURE1 0x00000400 /*%< type 1 security disabled */ +#define RES_INSECURE2 0x00000800 /*%< type 2 security disabled */ +#define RES_NOALIASES 0x00001000 /*%< shuts off HOSTALIASES feature */ +#define RES_USE_INET6 0x00002000 /*%< use/map IPv6 in gethostbyname() */ +#define RES_ROTATE 0x00004000 /*%< rotate ns list after each query */ +#define RES_NOCHECKNAME 0x00008000 /*%< do not check names for sanity. */ +#define RES_KEEPTSIG 0x00010000 /*%< do not strip TSIG records */ +#define RES_BLAST 0x00020000 /*%< blast all recursive servers */ +#define RES_NSID 0x00040000 /*%< request name server ID */ +#define RES_NOTLDQUERY 0x00100000 /*%< don't unqualified name as a tld */ +#define RES_USE_DNSSEC 0x00200000 /*%< use DNSSEC using OK bit in OPT */ +/* #define RES_DEBUG2 0x00400000 */ /* nslookup internal */ +/* KAME extensions: use higher bit to avoid conflict with ISC use */ +#define RES_USE_DNAME 0x10000000 /*%< use DNAME */ +#define RES_USE_EDNS0 0x40000000 /*%< use EDNS0 if configured */ +#define RES_NO_NIBBLE2 0x80000000 /*%< disable alternate nibble lookup */ + +#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | \ + RES_DNSRCH | RES_NO_NIBBLE2) + +/*% + * Resolver "pfcode" values. Used by dig. + */ +#define RES_PRF_STATS 0x00000001 +#define RES_PRF_UPDATE 0x00000002 +#define RES_PRF_CLASS 0x00000004 +#define RES_PRF_CMD 0x00000008 +#define RES_PRF_QUES 0x00000010 +#define RES_PRF_ANS 0x00000020 +#define RES_PRF_AUTH 0x00000040 +#define RES_PRF_ADD 0x00000080 +#define RES_PRF_HEAD1 0x00000100 +#define RES_PRF_HEAD2 0x00000200 +#define RES_PRF_TTLID 0x00000400 +#define RES_PRF_HEADX 0x00000800 +#define RES_PRF_QUERY 0x00001000 +#define RES_PRF_REPLY 0x00002000 +#define RES_PRF_INIT 0x00004000 +#define RES_PRF_TRUNC 0x00008000 +/* 0x00010000 */ + +/* Things involving an internal (static) resolver context. */ +__BEGIN_DECLS +extern struct __res_state *__res_state(void); +__END_DECLS +#define _res (*__res_state()) + +#ifndef __BIND_NOSTATIC +#define fp_nquery __fp_nquery +#define fp_query __fp_query +#define hostalias __hostalias +#define p_query __p_query +#define res_close __res_close +#define res_init __res_init +#define res_isourserver __res_isourserver +#define res_mkquery __res_mkquery +#define res_opt __res_opt +#define res_query __res_query +#define res_querydomain __res_querydomain +#define res_search __res_search +#define res_send __res_send +#define res_sendsigned __res_sendsigned + +__BEGIN_DECLS +void fp_nquery(const u_char *, int, FILE *); +void fp_query(const u_char *, FILE *); +const char * hostalias(const char *); +void p_query(const u_char *); +void res_close(void); +int res_init(void); +int res_isourserver(const struct sockaddr_in *); +int res_mkquery(int, const char *, int, int, const u_char *, + int, const u_char *, u_char *, int); +int res_opt(int, u_char *, int, int); +int res_query(const char *, int, int, u_char *, int); +int res_querydomain(const char *, const char *, int, int, + u_char *, int); +int res_search(const char *, int, int, u_char *, int); +int res_send(const u_char *, int, u_char *, int); +int res_sendsigned(const u_char *, int, ns_tsig_key *, + u_char *, int); +__END_DECLS +#endif + +#if !defined(SHARED_LIBBIND) || defined(LIB) +/* + * If libbind is a shared object (well, DLL anyway) + * these externs break the linker when resolv.h is + * included by a lib client (like named) + * Make them go away if a client is including this + * + */ +extern const struct res_sym __p_key_syms[]; +extern const struct res_sym __p_cert_syms[]; +extern const struct res_sym __p_class_syms[]; +extern const struct res_sym __p_type_syms[]; +extern const struct res_sym __p_rcode_syms[]; +#endif /* SHARED_LIBBIND */ + +#define b64_ntop __b64_ntop +#define b64_pton __b64_pton +#define dn_comp __dn_comp +#define dn_count_labels __dn_count_labels +#define dn_expand __dn_expand +#define dn_skipname __dn_skipname +#define fp_resstat __fp_resstat +#define loc_aton __loc_aton +#define loc_ntoa __loc_ntoa +#define p_cdname __p_cdname +#define p_cdnname __p_cdnname +#define p_class __p_class +#define p_fqname __p_fqname +#define p_fqnname __p_fqnname +#define p_option __p_option +#define p_secstodate __p_secstodate +#define p_section __p_section +#define p_time __p_time +#define p_type __p_type +#define p_rcode __p_rcode +#define p_sockun __p_sockun +#define putlong __putlong +#define putshort __putshort +#define res_dnok __res_dnok +#if 0 +#define res_findzonecut __res_findzonecut +#endif +#define res_findzonecut2 __res_findzonecut2 +#define res_hnok __res_hnok +#define res_hostalias __res_hostalias +#define res_mailok __res_mailok +#define res_nameinquery __res_nameinquery +#define res_nclose __res_nclose +#define res_ninit __res_ninit +#define res_nmkquery __res_nmkquery +#define res_pquery __res_pquery +#define res_nquery __res_nquery +#define res_nquerydomain __res_nquerydomain +#define res_nsearch __res_nsearch +#define res_nsend __res_nsend +#if 0 +#define res_nsendsigned __res_nsendsigned +#endif +#define res_nisourserver __res_nisourserver +#define res_ownok __res_ownok +#define res_queriesmatch __res_queriesmatch +#define res_rndinit __res_rndinit +#define res_randomid __res_randomid +#define res_nrandomid __res_nrandomid +#define sym_ntop __sym_ntop +#define sym_ntos __sym_ntos +#define sym_ston __sym_ston +#define res_nopt __res_nopt +#define res_nopt_rdata __res_nopt_rdata +#define res_ndestroy __res_ndestroy +#define res_nametoclass __res_nametoclass +#define res_nametotype __res_nametotype +#define res_setservers __res_setservers +#define res_getservers __res_getservers +#if 0 +#define res_buildprotolist __res_buildprotolist +#define res_destroyprotolist __res_destroyprotolist +#define res_destroyservicelist __res_destroyservicelist +#define res_get_nibblesuffix __res_get_nibblesuffix +#define res_get_nibblesuffix2 __res_get_nibblesuffix2 +#endif +#define res_ourserver_p __res_ourserver_p +#if 0 +#define res_protocolname __res_protocolname +#define res_protocolnumber __res_protocolnumber +#endif +#define res_send_setqhook __res_send_setqhook +#define res_send_setrhook __res_send_setrhook +#if 0 +#define res_servicename __res_servicename +#define res_servicenumber __res_servicenumber +#endif +__BEGIN_DECLS +int res_hnok(const char *); +int res_ownok(const char *); +int res_mailok(const char *); +int res_dnok(const char *); +int sym_ston(const struct res_sym *, const char *, int *); +const char * sym_ntos(const struct res_sym *, int, int *); +const char * sym_ntop(const struct res_sym *, int, int *); +int b64_ntop(u_char const *, size_t, char *, size_t); +int b64_pton(char const *, u_char *, size_t); +int loc_aton(const char *, u_char *); +const char * loc_ntoa(const u_char *, char *); +int dn_skipname(const u_char *, const u_char *); +void putlong(u_int32_t, u_char *); +void putshort(u_int16_t, u_char *); +#ifndef __ultrix__ +u_int16_t _getshort(const u_char *); +u_int32_t _getlong(const u_char *); +#endif +const char * p_class(int); +const char * p_time(u_int32_t); +const char * p_type(int); +const char * p_rcode(int); +const char * p_sockun(union res_sockaddr_union, char *, size_t); +const u_char * p_cdnname(const u_char *, const u_char *, int, FILE *); +const u_char * p_cdname(const u_char *, const u_char *, FILE *); +const u_char * p_fqnname(const u_char *, const u_char *, int, char *, int); +const u_char * p_fqname(const u_char *, const u_char *, FILE *); +const char * p_option(u_long); +char * p_secstodate(u_long); +int dn_count_labels(const char *); +int dn_comp(const char *, u_char *, int, u_char **, u_char **); +int dn_expand(const u_char *, const u_char *, const u_char *, + char *, int); +void res_rndinit(res_state); +u_int res_randomid(void); +u_int res_nrandomid(res_state); +int res_nameinquery(const char *, int, int, const u_char *, + const u_char *); +int res_queriesmatch(const u_char *, const u_char *, + const u_char *, const u_char *); +const char * p_section(int, int); +/* Things involving a resolver context. */ +int res_ninit(res_state); +int res_nisourserver(const res_state, const struct sockaddr_in *); +void fp_resstat(const res_state, FILE *); +void res_pquery(const res_state, const u_char *, int, FILE *); +const char * res_hostalias(const res_state, const char *, char *, size_t); +int res_nquery(res_state, const char *, int, int, u_char *, int); +int res_nsearch(res_state, const char *, int, int, u_char *, int); +int res_nquerydomain(res_state, const char *, const char *, + int, int, u_char *, int); +int res_nmkquery(res_state, int, const char *, int, int, + const u_char *, int, const u_char *, + u_char *, int); +int res_nsend(res_state, const u_char *, int, u_char *, int); +#if 0 +int res_nsendsigned(res_state, const u_char *, int, + ns_tsig_key *, u_char *, int); +int res_findzonecut(res_state, const char *, ns_class, int, + char *, size_t, struct in_addr *, int); +#endif +int res_findzonecut2(res_state, const char *, ns_class, int, + char *, size_t, + union res_sockaddr_union *, int); +void res_nclose(res_state); +int res_nopt(res_state, int, u_char *, int, int); +int res_nopt_rdata(res_state, int, u_char *, int, u_char *, + u_short, u_short, u_char *); +void res_send_setqhook(res_send_qhook); +void res_send_setrhook(res_send_rhook); +int __res_vinit(res_state, int); +#if 0 +void res_destroyservicelist(void); +const char * res_servicename(u_int16_t, const char *); +const char * res_protocolname(int); +void res_destroyprotolist(void); +void res_buildprotolist(void); +const char * res_get_nibblesuffix(res_state); +const char * res_get_nibblesuffix2(res_state); +#endif +void res_ndestroy(res_state); +u_int16_t res_nametoclass(const char *, int *); +u_int16_t res_nametotype(const char *, int *); +void res_setservers(res_state, const union res_sockaddr_union *, + int); +int res_getservers(res_state, union res_sockaddr_union *, int); +__END_DECLS + +#endif /* !_RESOLV_H_ */ +/*! \file */ diff --git a/include/rpc/Makefile b/include/rpc/Makefile new file mode 100644 index 0000000..e6bb846 --- /dev/null +++ b/include/rpc/Makefile @@ -0,0 +1,31 @@ +# from: @(#)Makefile 2.3 88/08/11 4.0 RPCSRC +# $FreeBSD: releng/11.1/include/rpc/Makefile 231118 2012-02-07 09:27:07Z dim $ + +.SUFFIXES: .x + +RPCCOM= RPCGEN_CPP=${CPP:Q} rpcgen -C + +HDRS= rpcb_prot.h + +XFILES= rpcb_prot.x + +HFILES= auth.h auth_unix.h clnt.h clnt_soc.h clnt_stat.h \ + nettype.h pmap_clnt.h pmap_prot.h pmap_rmt.h raw.h \ + rpc.h rpc_msg.h rpcb_clnt.h rpcent.h rpc_com.h rpcsec_gss.h \ + svc.h svc_auth.h svc_soc.h svc_dg.h xdr.h + +# Secure RPC +HFILES+= auth_des.h des.h des_crypt.h + +# Kerberos +HFILES+= auth_kerb.h + +CLEANFILES+= ${HDRS} + +INCS= ${HFILES} ${XFILES} ${HDRS} +INCSDIR=${INCLUDEDIR}/rpc + +.x.h: + ${RPCCOM} -h -DWANT_NFS3 ${.IMPSRC} -o ${.TARGET} + +.include diff --git a/include/rpc/Makefile.depend b/include/rpc/Makefile.depend new file mode 100644 index 0000000..3272dd6 --- /dev/null +++ b/include/rpc/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD: releng/11.1/include/rpc/Makefile.depend 284345 2015-06-13 19:20:56Z sjg $ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/include/rpc/auth.h b/include/rpc/auth.h new file mode 100644 index 0000000..ee7314f --- /dev/null +++ b/include/rpc/auth.h @@ -0,0 +1,368 @@ +/* $NetBSD: auth.h,v 1.15 2000/06/02 22:57:55 fvdl Exp $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * from: @(#)auth.h 1.17 88/02/08 SMI + * from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC + * from: @(#)auth.h 1.43 98/02/02 SMI + * $FreeBSD: releng/11.1/include/rpc/auth.h 258578 2013-11-25 19:04:36Z hrs $ + */ + +/* + * auth.h, Authentication interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The data structures are completely opaque to the client. The client + * is required to pass an AUTH * to routines that create rpc + * "sessions". + */ + +#ifndef _RPC_AUTH_H +#define _RPC_AUTH_H +#include +#include +#include +#include + +#define MAX_AUTH_BYTES 400 +#define MAXNETNAMELEN 255 /* maximum length of network user's name */ + +/* + * Client side authentication/security data + */ + +typedef struct sec_data { + u_int secmod; /* security mode number e.g. in nfssec.conf */ + u_int rpcflavor; /* rpc flavors:AUTH_UNIX,AUTH_DES,RPCSEC_GSS */ + int flags; /* AUTH_F_xxx flags */ + caddr_t data; /* opaque data per flavor */ +} sec_data_t; + +#ifdef _SYSCALL32_IMPL +struct sec_data32 { + uint32_t secmod; /* security mode number e.g. in nfssec.conf */ + uint32_t rpcflavor; /* rpc flavors:AUTH_UNIX,AUTH_DES,RPCSEC_GSS */ + int32_t flags; /* AUTH_F_xxx flags */ + caddr32_t data; /* opaque data per flavor */ +}; +#endif /* _SYSCALL32_IMPL */ + +/* + * AUTH_DES flavor specific data from sec_data opaque data field. + * AUTH_KERB has the same structure. + */ +typedef struct des_clnt_data { + struct netbuf syncaddr; /* time sync addr */ + struct knetconfig *knconf; /* knetconfig info that associated */ + /* with the syncaddr. */ + char *netname; /* server's netname */ + int netnamelen; /* server's netname len */ +} dh_k4_clntdata_t; + +#ifdef _SYSCALL32_IMPL +struct des_clnt_data32 { + struct netbuf32 syncaddr; /* time sync addr */ + caddr32_t knconf; /* knetconfig info that associated */ + /* with the syncaddr. */ + caddr32_t netname; /* server's netname */ + int32_t netnamelen; /* server's netname len */ +}; +#endif /* _SYSCALL32_IMPL */ + +#ifdef KERBEROS +/* + * flavor specific data to hold the data for AUTH_DES/AUTH_KERB(v4) + * in sec_data->data opaque field. + */ +typedef struct krb4_svc_data { + int window; /* window option value */ +} krb4_svcdata_t; + +typedef struct krb4_svc_data des_svcdata_t; +#endif /* KERBEROS */ + +/* + * authentication/security specific flags + */ +#define AUTH_F_RPCTIMESYNC 0x001 /* use RPC to do time sync */ +#define AUTH_F_TRYNONE 0x002 /* allow fall back to AUTH_NONE */ + + +/* + * Status returned from authentication check + */ +enum auth_stat { + AUTH_OK=0, + /* + * failed at remote end + */ + AUTH_BADCRED=1, /* bogus credentials (seal broken) */ + AUTH_REJECTEDCRED=2, /* client should begin new session */ + AUTH_BADVERF=3, /* bogus verifier (seal broken) */ + AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ + AUTH_TOOWEAK=5, /* rejected due to security reasons */ + /* + * failed locally + */ + AUTH_INVALIDRESP=6, /* bogus response verifier */ + AUTH_FAILED=7, /* some unknown reason */ +#ifdef KERBEROS + /* + * kerberos errors + */ + , + AUTH_KERB_GENERIC = 8, /* kerberos generic error */ + AUTH_TIMEEXPIRE = 9, /* time of credential expired */ + AUTH_TKT_FILE = 10, /* something wrong with ticket file */ + AUTH_DECODE = 11, /* can't decode authenticator */ + AUTH_NET_ADDR = 12, /* wrong net address in ticket */ +#endif /* KERBEROS */ + /* + * RPCSEC_GSS errors + */ + RPCSEC_GSS_CREDPROBLEM = 13, + RPCSEC_GSS_CTXPROBLEM = 14, + RPCSEC_GSS_NODISPATCH = 0x8000000 +}; + +union des_block { + struct { + uint32_t high; + uint32_t low; + } key; + char c[8]; +}; +typedef union des_block des_block; +__BEGIN_DECLS +extern bool_t xdr_des_block(XDR *, des_block *); +__END_DECLS + +/* + * Authentication info. Opaque to client. + */ +struct opaque_auth { + enum_t oa_flavor; /* flavor of auth */ + caddr_t oa_base; /* address of more auth stuff */ + u_int oa_length; /* not to exceed MAX_AUTH_BYTES */ +}; + + +/* + * Auth handle, interface to client side authenticators. + */ +typedef struct __auth { + struct opaque_auth ah_cred; + struct opaque_auth ah_verf; + union des_block ah_key; + struct auth_ops { + void (*ah_nextverf) (struct __auth *); + /* nextverf & serialize */ + int (*ah_marshal) (struct __auth *, XDR *); + /* validate verifier */ + int (*ah_validate) (struct __auth *, + struct opaque_auth *); + /* refresh credentials */ + int (*ah_refresh) (struct __auth *, void *); + /* destroy this structure */ + void (*ah_destroy) (struct __auth *); + } *ah_ops; + void *ah_private; +} AUTH; + + +/* + * Authentication ops. + * The ops and the auth handle provide the interface to the authenticators. + * + * AUTH *auth; + * XDR *xdrs; + * struct opaque_auth verf; + */ +#define AUTH_NEXTVERF(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) +#define auth_nextverf(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) + +#define AUTH_MARSHALL(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) +#define auth_marshall(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) + +#define AUTH_VALIDATE(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) +#define auth_validate(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) + +#define AUTH_REFRESH(auth, msg) \ + ((*((auth)->ah_ops->ah_refresh))(auth, msg)) +#define auth_refresh(auth, msg) \ + ((*((auth)->ah_ops->ah_refresh))(auth, msg)) + +#define AUTH_DESTROY(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) +#define auth_destroy(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) + + +__BEGIN_DECLS +extern struct opaque_auth _null_auth; +__END_DECLS + +/* + * These are the various implementations of client side authenticators. + */ + +/* + * System style authentication + * AUTH *authunix_create(machname, uid, gid, len, aup_gids) + * char *machname; + * u_int uid; + * u_int gid; + * int len; + * u_int *aup_gids; + */ +__BEGIN_DECLS +extern AUTH *authunix_create(char *, u_int, u_int, int, u_int *); +extern AUTH *authunix_create_default(void); /* takes no parameters */ +extern AUTH *authnone_create(void); /* takes no parameters */ +__END_DECLS +/* + * DES style authentication + * AUTH *authsecdes_create(servername, window, timehost, ckey) + * char *servername; - network name of server + * u_int window; - time to live + * const char *timehost; - optional hostname to sync with + * des_block *ckey; - optional conversation key to use + */ +__BEGIN_DECLS +extern AUTH *authdes_create (char *, u_int, struct sockaddr *, des_block *); +extern AUTH *authdes_seccreate (const char *, const u_int, const char *, + const des_block *); +__END_DECLS + +__BEGIN_DECLS +extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *); +__END_DECLS + +#define authsys_create(c,i1,i2,i3,ip) authunix_create((c),(i1),(i2),(i3),(ip)) +#define authsys_create_default() authunix_create_default() + +/* + * Netname manipulation routines. + */ +__BEGIN_DECLS +extern int getnetname(char *); +extern int host2netname(char *, const char *, const char *); +extern int user2netname(char *, const uid_t, const char *); +extern int netname2user(char *, uid_t *, gid_t *, int *, gid_t *); +extern int netname2host(char *, char *, const int); +extern void passwd2des ( char *, char * ); +__END_DECLS + +/* + * + * These routines interface to the keyserv daemon + * + */ +__BEGIN_DECLS +extern int key_decryptsession(const char *, des_block *); +extern int key_encryptsession(const char *, des_block *); +extern int key_gendes(des_block *); +extern int key_setsecret(const char *); +extern int key_secretkey_is_set(void); +__END_DECLS + +/* + * Publickey routines. + */ +__BEGIN_DECLS +extern int getpublickey (const char *, char *); +extern int getpublicandprivatekey (const char *, char *); +extern int getsecretkey (char *, char *, char *); +__END_DECLS + +#ifdef KERBEROS +/* + * Kerberos style authentication + * AUTH *authkerb_seccreate(service, srv_inst, realm, window, timehost, status) + * const char *service; - service name + * const char *srv_inst; - server instance + * const char *realm; - server realm + * const u_int window; - time to live + * const char *timehost; - optional hostname to sync with + * int *status; - kerberos status returned + */ +__BEGIN_DECLS +extern AUTH *authkerb_seccreate(const char *, const char *, const char *, + const u_int, const char *, int *); +__END_DECLS + +/* + * Map a kerberos credential into a unix cred. + * + * authkerb_getucred(rqst, uid, gid, grouplen, groups) + * const struct svc_req *rqst; - request pointer + * uid_t *uid; + * gid_t *gid; + * short *grouplen; + * int *groups; + * + */ +__BEGIN_DECLS +extern int authkerb_getucred(/* struct svc_req *, uid_t *, gid_t *, + short *, int * */); +__END_DECLS +#endif /* KERBEROS */ + +__BEGIN_DECLS +struct svc_req; +struct rpc_msg; +enum auth_stat _svcauth_null (struct svc_req *, struct rpc_msg *); +enum auth_stat _svcauth_short (struct svc_req *, struct rpc_msg *); +enum auth_stat _svcauth_unix (struct svc_req *, struct rpc_msg *); +__END_DECLS + +#define AUTH_NONE 0 /* no authentication */ +#define AUTH_NULL 0 /* backward compatibility */ +#define AUTH_SYS 1 /* unix style (uid, gids) */ +#define AUTH_UNIX AUTH_SYS +#define AUTH_SHORT 2 /* short hand unix style */ +#define AUTH_DH 3 /* for Diffie-Hellman mechanism */ +#define AUTH_DES AUTH_DH /* for backward compatibility */ +#define AUTH_KERB 4 /* kerberos style */ +#define RPCSEC_GSS 6 /* RPCSEC_GSS */ + +/* + * Pseudo auth flavors for RPCSEC_GSS. + */ +#define RPCSEC_GSS_KRB5 390003 +#define RPCSEC_GSS_KRB5I 390004 +#define RPCSEC_GSS_KRB5P 390005 + +#endif /* !_RPC_AUTH_H */ diff --git a/include/rpc/auth_des.h b/include/rpc/auth_des.h new file mode 100644 index 0000000..c6e67d3 --- /dev/null +++ b/include/rpc/auth_des.h @@ -0,0 +1,125 @@ +/* @(#)auth_des.h 2.2 88/07/29 4.0 RPCSRC; from 1.3 88/02/08 SMI */ +/* $FreeBSD: releng/11.1/include/rpc/auth_des.h 258578 2013-11-25 19:04:36Z hrs $ */ +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * from: @(#)auth_des.h 2.2 88/07/29 4.0 RPCSRC + * from: @(#)auth_des.h 1.14 94/04/25 SMI + */ + +/* + * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. + */ + +/* + * auth_des.h, Protocol for DES style authentication for RPC + */ + +#ifndef _AUTH_DES_ +#define _AUTH_DES_ + +/* + * There are two kinds of "names": fullnames and nicknames + */ +enum authdes_namekind { + ADN_FULLNAME, + ADN_NICKNAME +}; + +/* + * A fullname contains the network name of the client, + * a conversation key and the window + */ +struct authdes_fullname { + char *name; /* network name of client, up to MAXNETNAMELEN */ + des_block key; /* conversation key */ + u_long window; /* associated window */ +}; + + +/* + * A credential + */ +struct authdes_cred { + enum authdes_namekind adc_namekind; + struct authdes_fullname adc_fullname; + u_long adc_nickname; +}; + + + +/* + * A des authentication verifier + */ +struct authdes_verf { + union { + struct timeval adv_ctime; /* clear time */ + des_block adv_xtime; /* crypt time */ + } adv_time_u; + u_long adv_int_u; +}; + +/* + * des authentication verifier: client variety + * + * adv_timestamp is the current time. + * adv_winverf is the credential window + 1. + * Both are encrypted using the conversation key. + */ +#define adv_timestamp adv_time_u.adv_ctime +#define adv_xtimestamp adv_time_u.adv_xtime +#define adv_winverf adv_int_u + +/* + * des authentication verifier: server variety + * + * adv_timeverf is the client's timestamp + client's window + * adv_nickname is the server's nickname for the client. + * adv_timeverf is encrypted using the conversation key. + */ +#define adv_timeverf adv_time_u.adv_ctime +#define adv_xtimeverf adv_time_u.adv_xtime +#define adv_nickname adv_int_u + +/* + * Map a des credential into a unix cred. + * + */ +__BEGIN_DECLS +extern int authdes_getucred( struct authdes_cred *, uid_t *, gid_t *, int *, gid_t * ); +__END_DECLS + +__BEGIN_DECLS +extern bool_t xdr_authdes_cred(XDR *, struct authdes_cred *); +extern bool_t xdr_authdes_verf(XDR *, struct authdes_verf *); +extern int rtime(dev_t, struct netbuf *, int, struct timeval *, + struct timeval *); +extern void kgetnetname(char *); +extern enum auth_stat _svcauth_des(struct svc_req *, struct rpc_msg *); +__END_DECLS + +#endif /* ndef _AUTH_DES_ */ diff --git a/include/rpc/auth_kerb.h b/include/rpc/auth_kerb.h new file mode 100644 index 0000000..6088fd6 --- /dev/null +++ b/include/rpc/auth_kerb.h @@ -0,0 +1,140 @@ +/* $FreeBSD: releng/11.1/include/rpc/auth_kerb.h 258578 2013-11-25 19:04:36Z hrs $ */ +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +/* + * auth_kerb.h, Protocol for Kerberos style authentication for RPC + * + * Copyright (C) 1986, Sun Microsystems, Inc. + */ + +#ifndef _RPC_AUTH_KERB_H +#define _RPC_AUTH_KERB_H + +#ifdef KERBEROS + +#include +#include +#include +#include +#include + +/* + * There are two kinds of "names": fullnames and nicknames + */ +enum authkerb_namekind { + AKN_FULLNAME, + AKN_NICKNAME +}; +/* + * A fullname contains the ticket and the window + */ +struct authkerb_fullname { + KTEXT_ST ticket; + u_long window; /* associated window */ +}; + +/* + * cooked credential stored in rq_clntcred + */ +struct authkerb_clnt_cred { + /* start of AUTH_DAT */ + unsigned char k_flags; /* Flags from ticket */ + char pname[ANAME_SZ]; /* Principal's name */ + char pinst[INST_SZ]; /* His Instance */ + char prealm[REALM_SZ]; /* His Realm */ + unsigned long checksum; /* Data checksum (opt) */ + C_Block session; /* Session Key */ + int life; /* Life of ticket */ + unsigned long time_sec; /* Time ticket issued */ + unsigned long address; /* Address in ticket */ + /* KTEXT_ST reply; Auth reply (opt) */ + /* end of AUTH_DAT */ + unsigned long expiry; /* time the ticket is expiring */ + u_long nickname; /* Nickname into cache */ + u_long window; /* associated window */ +}; + +typedef struct authkerb_clnt_cred authkerb_clnt_cred; + +/* + * A credential + */ +struct authkerb_cred { + enum authkerb_namekind akc_namekind; + struct authkerb_fullname akc_fullname; + u_long akc_nickname; +}; + +/* + * A kerb authentication verifier + */ +struct authkerb_verf { + union { + struct timeval akv_ctime; /* clear time */ + des_block akv_xtime; /* crypt time */ + } akv_time_u; + u_long akv_int_u; +}; + +/* + * des authentication verifier: client variety + * + * akv_timestamp is the current time. + * akv_winverf is the credential window + 1. + * Both are encrypted using the conversation key. + */ +#ifndef akv_timestamp +#define akv_timestamp akv_time_u.akv_ctime +#define akv_xtimestamp akv_time_u.akv_xtime +#define akv_winverf akv_int_u +#endif +/* + * des authentication verifier: server variety + * + * akv_timeverf is the client's timestamp + client's window + * akv_nickname is the server's nickname for the client. + * akv_timeverf is encrypted using the conversation key. + */ +#ifndef akv_timeverf +#define akv_timeverf akv_time_u.akv_ctime +#define akv_xtimeverf akv_time_u.akv_xtime +#define akv_nickname akv_int_u +#endif + +/* + * Register the service name, instance and realm. + */ +extern int authkerb_create(char *, char *, char *, u_int, + struct netbuf *, int *, dev_t, int, AUTH **); +extern bool_t xdr_authkerb_cred(XDR *, struct authkerb_cred *); +extern bool_t xdr_authkerb_verf(XDR *, struct authkerb_verf *); +extern int svc_kerb_reg(SVCXPRT *, char *, char *, char *); +extern enum auth_stat _svcauth_kerb(struct svc_req *, struct rpc_msg *); + +#endif /* KERBEROS */ +#endif /* !_RPC_AUTH_KERB_H */ diff --git a/include/rpc/auth_unix.h b/include/rpc/auth_unix.h new file mode 100644 index 0000000..c8ed112 --- /dev/null +++ b/include/rpc/auth_unix.h @@ -0,0 +1,83 @@ +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * from: @(#)auth_unix.h 1.8 88/02/08 SMI + * from: @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC + * $FreeBSD: releng/11.1/include/rpc/auth_unix.h 258578 2013-11-25 19:04:36Z hrs $ + */ + +/* + * auth_unix.h, Protocol for UNIX style authentication parameters for RPC + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * The system is very weak. The client uses no encryption for it + * credentials and only sends null verifiers. The server sends backs + * null verifiers or optionally a verifier that suggests a new short hand + * for the credentials. + */ + +#ifndef _RPC_AUTH_UNIX_H +#define _RPC_AUTH_UNIX_H +#include + +/* The machine name is part of a credential; it may not exceed 255 bytes */ +#define MAX_MACHINE_NAME 255 + +/* gids compose part of a credential; there may not be more than 16 of them */ +#define NGRPS 16 + +/* + * Unix style credentials. + */ +struct authunix_parms { + u_long aup_time; + char *aup_machname; + u_int aup_uid; + u_int aup_gid; + u_int aup_len; + u_int *aup_gids; +}; + +#define authsys_parms authunix_parms + +__BEGIN_DECLS +extern bool_t xdr_authunix_parms(XDR *, struct authunix_parms *); +__END_DECLS + +/* + * If a response verifier has flavor AUTH_SHORT, + * then the body of the response verifier encapsulates the following structure; + * again it is serialized in the obvious fashion. + */ +struct short_hand_verf { + struct opaque_auth new_cred; +}; + +#endif /* !_RPC_AUTH_UNIX_H */ diff --git a/include/rpc/clnt.h b/include/rpc/clnt.h new file mode 100644 index 0000000..18e091c --- /dev/null +++ b/include/rpc/clnt.h @@ -0,0 +1,536 @@ +/* $NetBSD: clnt.h,v 1.14 2000/06/02 22:57:55 fvdl Exp $ */ + +/*- + * Copyright (c) 2010, Oracle America, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * from: @(#)clnt.h 1.31 94/04/29 SMI + * from: @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: releng/11.1/include/rpc/clnt.h 258581 2013-11-25 19:08:38Z hrs $ + */ + +/* + * clnt.h - Client side remote procedure call interface. + */ + +#ifndef _RPC_CLNT_H_ +#define _RPC_CLNT_H_ +#include +#include +#include +#include + +/* + * Well-known IPV6 RPC broadcast address. + */ +#define RPCB_MULTICAST_ADDR "ff02::202" + +/* + * the following errors are in general unrecoverable. The caller + * should give up rather than retry. + */ +#define IS_UNRECOVERABLE_RPC(s) (((s) == RPC_AUTHERROR) || \ + ((s) == RPC_CANTENCODEARGS) || \ + ((s) == RPC_CANTDECODERES) || \ + ((s) == RPC_VERSMISMATCH) || \ + ((s) == RPC_PROCUNAVAIL) || \ + ((s) == RPC_PROGUNAVAIL) || \ + ((s) == RPC_PROGVERSMISMATCH) || \ + ((s) == RPC_CANTDECODEARGS)) + +/* + * Error info. + */ +struct rpc_err { + enum clnt_stat re_status; + union { + int RE_errno; /* related system error */ + enum auth_stat RE_why; /* why the auth error occurred */ + struct { + rpcvers_t low; /* lowest version supported */ + rpcvers_t high; /* highest version supported */ + } RE_vers; + struct { /* maybe meaningful if RPC_FAILED */ + int32_t s1; + int32_t s2; + } RE_lb; /* life boot & debugging only */ + } ru; +#define re_errno ru.RE_errno +#define re_why ru.RE_why +#define re_vers ru.RE_vers +#define re_lb ru.RE_lb +}; + + +/* + * Client rpc handle. + * Created by individual implementations + * Client is responsible for initializing auth, see e.g. auth_none.c. + */ +typedef struct __rpc_client { + AUTH *cl_auth; /* authenticator */ + struct clnt_ops { + /* call remote procedure */ + enum clnt_stat (*cl_call)(struct __rpc_client *, + rpcproc_t, xdrproc_t, void *, xdrproc_t, + void *, struct timeval); + /* abort a call */ + void (*cl_abort)(struct __rpc_client *); + /* get specific error code */ + void (*cl_geterr)(struct __rpc_client *, + struct rpc_err *); + /* frees results */ + bool_t (*cl_freeres)(struct __rpc_client *, + xdrproc_t, void *); + /* destroy this structure */ + void (*cl_destroy)(struct __rpc_client *); + /* the ioctl() of rpc */ + bool_t (*cl_control)(struct __rpc_client *, u_int, + void *); + } *cl_ops; + void *cl_private; /* private stuff */ + char *cl_netid; /* network token */ + char *cl_tp; /* device name */ +} CLIENT; + + +/* + * Timers used for the pseudo-transport protocol when using datagrams + */ +struct rpc_timers { + u_short rt_srtt; /* smoothed round-trip time */ + u_short rt_deviate; /* estimated deviation */ + u_long rt_rtxcur; /* current (backed-off) rto */ +}; + +/* + * Feedback values used for possible congestion and rate control + */ +#define FEEDBACK_REXMIT1 1 /* first retransmit */ +#define FEEDBACK_OK 2 /* no retransmits */ + +/* Used to set version of portmapper used in broadcast */ + +#define CLCR_SET_LOWVERS 3 +#define CLCR_GET_LOWVERS 4 + +#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */ + +/* + * client side rpc interface ops + * + * Parameter types are: + * + */ + +/* + * enum clnt_stat + * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout) + * CLIENT *rh; + * rpcproc_t proc; + * xdrproc_t xargs; + * void *argsp; + * xdrproc_t xres; + * void *resp; + * struct timeval timeout; + */ +#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, \ + argsp, xres, resp, secs)) +#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, \ + argsp, xres, resp, secs)) + +/* + * void + * CLNT_ABORT(rh); + * CLIENT *rh; + */ +#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh)) +#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh)) + +/* + * struct rpc_err + * CLNT_GETERR(rh); + * CLIENT *rh; + */ +#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) +#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) + + +/* + * bool_t + * CLNT_FREERES(rh, xres, resp); + * CLIENT *rh; + * xdrproc_t xres; + * void *resp; + */ +#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) +#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) + +/* + * bool_t + * CLNT_CONTROL(cl, request, info) + * CLIENT *cl; + * u_int request; + * char *info; + */ +#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) +#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) + +/* + * control operations that apply to both udp and tcp transports + */ +#define CLSET_TIMEOUT 1 /* set timeout (timeval) */ +#define CLGET_TIMEOUT 2 /* get timeout (timeval) */ +#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */ +#define CLGET_FD 6 /* get connections file descriptor */ +#define CLGET_SVC_ADDR 7 /* get server's address (netbuf) */ +#define CLSET_FD_CLOSE 8 /* close fd while clnt_destroy */ +#define CLSET_FD_NCLOSE 9 /* Do not close fd while clnt_destroy */ +#define CLGET_XID 10 /* Get xid */ +#define CLSET_XID 11 /* Set xid */ +#define CLGET_VERS 12 /* Get version number */ +#define CLSET_VERS 13 /* Set version number */ +#define CLGET_PROG 14 /* Get program number */ +#define CLSET_PROG 15 /* Set program number */ +#define CLSET_SVC_ADDR 16 /* get server's address (netbuf) */ +#define CLSET_PUSH_TIMOD 17 /* push timod if not already present */ +#define CLSET_POP_TIMOD 18 /* pop timod */ +/* + * Connectionless only control operations + */ +#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */ +#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */ +#define CLSET_ASYNC 19 +#define CLSET_CONNECT 20 /* Use connect() for UDP. (int) */ + +/* + * void + * CLNT_DESTROY(rh); + * CLIENT *rh; + */ +#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) +#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) + + +/* + * RPCTEST is a test program which is accessible on every rpc + * transport/port. It is used for testing, performance evaluation, + * and network administration. + */ + +#define RPCTEST_PROGRAM ((rpcprog_t)1) +#define RPCTEST_VERSION ((rpcvers_t)1) +#define RPCTEST_NULL_PROC ((rpcproc_t)2) +#define RPCTEST_NULL_BATCH_PROC ((rpcproc_t)3) + +/* + * By convention, procedure 0 takes null arguments and returns them + */ + +#define NULLPROC ((rpcproc_t)0) + +/* + * Below are the client handle creation routines for the various + * implementations of client side rpc. They can return NULL if a + * creation failure occurs. + */ + +/* + * Generic client creation routine. Supported protocols are those that + * belong to the nettype namespace (/etc/netconfig). + */ +__BEGIN_DECLS +extern CLIENT *clnt_create(const char *, const rpcprog_t, const rpcvers_t, + const char *); +/* + * + * const char *hostname; -- hostname + * const rpcprog_t prog; -- program number + * const rpcvers_t vers; -- version number + * const char *nettype; -- network type + */ + + /* + * Generic client creation routine. Just like clnt_create(), except + * it takes an additional timeout parameter. + */ +extern CLIENT * clnt_create_timed(const char *, const rpcprog_t, + const rpcvers_t, const char *, const struct timeval *); +/* + * + * const char *hostname; -- hostname + * const rpcprog_t prog; -- program number + * const rpcvers_t vers; -- version number + * const char *nettype; -- network type + * const struct timeval *tp; -- timeout + */ + +/* + * Generic client creation routine. Supported protocols are which belong + * to the nettype name space. + */ +extern CLIENT *clnt_create_vers(const char *, const rpcprog_t, rpcvers_t *, + const rpcvers_t, const rpcvers_t, + const char *); +/* + * const char *host; -- hostname + * const rpcprog_t prog; -- program number + * rpcvers_t *vers_out; -- servers highest available version + * const rpcvers_t vers_low; -- low version number + * const rpcvers_t vers_high; -- high version number + * const char *nettype; -- network type + */ + +/* + * Generic client creation routine. Supported protocols are which belong + * to the nettype name space. + */ +extern CLIENT * clnt_create_vers_timed(const char *, const rpcprog_t, + rpcvers_t *, const rpcvers_t, const rpcvers_t, const char *, + const struct timeval *); +/* + * const char *host; -- hostname + * const rpcprog_t prog; -- program number + * rpcvers_t *vers_out; -- servers highest available version + * const rpcvers_t vers_low; -- low version number + * const rpcvers_t vers_high; -- high version number + * const char *nettype; -- network type + * const struct timeval *tp -- timeout + */ + +/* + * Generic client creation routine. It takes a netconfig structure + * instead of nettype + */ +extern CLIENT *clnt_tp_create(const char *, const rpcprog_t, + const rpcvers_t, const struct netconfig *); +/* + * const char *hostname; -- hostname + * const rpcprog_t prog; -- program number + * const rpcvers_t vers; -- version number + * const struct netconfig *netconf; -- network config structure + */ + +/* + * Generic client creation routine. Just like clnt_tp_create(), except + * it takes an additional timeout parameter. + */ +extern CLIENT * clnt_tp_create_timed(const char *, const rpcprog_t, + const rpcvers_t, const struct netconfig *, const struct timeval *); +/* + * const char *hostname; -- hostname + * const rpcprog_t prog; -- program number + * const rpcvers_t vers; -- version number + * const struct netconfig *netconf; -- network config structure + * const struct timeval *tp -- timeout + */ + +/* + * Generic TLI create routine. Only provided for compatibility. + */ + +extern CLIENT *clnt_tli_create(const int, const struct netconfig *, + struct netbuf *, const rpcprog_t, + const rpcvers_t, const u_int, const u_int); +/* + * const register int fd; -- fd + * const struct netconfig *nconf; -- netconfig structure + * struct netbuf *svcaddr; -- servers address + * const u_long prog; -- program number + * const u_long vers; -- version number + * const u_int sendsz; -- send size + * const u_int recvsz; -- recv size + */ + +/* + * Low level clnt create routine for connectionful transports, e.g. tcp. + */ +extern CLIENT *clnt_vc_create(const int, const struct netbuf *, + const rpcprog_t, const rpcvers_t, + u_int, u_int); +/* + * Added for compatibility to old rpc 4.0. Obsoleted by clnt_vc_create(). + */ +extern CLIENT *clntunix_create(struct sockaddr_un *, + u_long, u_long, int *, u_int, u_int); +/* + * const int fd; -- open file descriptor + * const struct netbuf *svcaddr; -- servers address + * const rpcprog_t prog; -- program number + * const rpcvers_t vers; -- version number + * const u_int sendsz; -- buffer recv size + * const u_int recvsz; -- buffer send size + */ + +/* + * Low level clnt create routine for connectionless transports, e.g. udp. + */ +extern CLIENT *clnt_dg_create(const int, const struct netbuf *, + const rpcprog_t, const rpcvers_t, + const u_int, const u_int); +/* + * const int fd; -- open file descriptor + * const struct netbuf *svcaddr; -- servers address + * const rpcprog_t program; -- program number + * const rpcvers_t version; -- version number + * const u_int sendsz; -- buffer recv size + * const u_int recvsz; -- buffer send size + */ + +/* + * Memory based rpc (for speed check and testing) + * CLIENT * + * clnt_raw_create(prog, vers) + * u_long prog; + * u_long vers; + */ +extern CLIENT *clnt_raw_create(rpcprog_t, rpcvers_t); + +__END_DECLS + + +/* + * Print why creation failed + */ +__BEGIN_DECLS +extern void clnt_pcreateerror(const char *); /* stderr */ +extern char *clnt_spcreateerror(const char *); /* string */ +__END_DECLS + +/* + * Like clnt_perror(), but is more verbose in its output + */ +__BEGIN_DECLS +extern void clnt_perrno(enum clnt_stat); /* stderr */ +extern char *clnt_sperrno(enum clnt_stat); /* string */ +__END_DECLS + +/* + * Print an English error message, given the client error code + */ +__BEGIN_DECLS +extern void clnt_perror(CLIENT *, const char *); /* stderr */ +extern char *clnt_sperror(CLIENT *, const char *); /* string */ +__END_DECLS + + +/* + * If a creation fails, the following allows the user to figure out why. + */ +struct rpc_createerr { + enum clnt_stat cf_stat; + struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */ +}; + +__BEGIN_DECLS +extern struct rpc_createerr *__rpc_createerr(void); +__END_DECLS +#define rpc_createerr (*(__rpc_createerr())) + +/* + * The simplified interface: + * enum clnt_stat + * rpc_call(host, prognum, versnum, procnum, inproc, in, outproc, out, nettype) + * const char *host; + * const rpcprog_t prognum; + * const rpcvers_t versnum; + * const rpcproc_t procnum; + * const xdrproc_t inproc, outproc; + * const char *in; + * char *out; + * const char *nettype; + */ +__BEGIN_DECLS +extern enum clnt_stat rpc_call(const char *, const rpcprog_t, + const rpcvers_t, const rpcproc_t, + const xdrproc_t, const char *, + const xdrproc_t, char *, const char *); +__END_DECLS + +/* + * RPC broadcast interface + * The call is broadcasted to all locally connected nets. + * + * extern enum clnt_stat + * rpc_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, + * eachresult, nettype) + * const rpcprog_t prog; -- program number + * const rpcvers_t vers; -- version number + * const rpcproc_t proc; -- procedure number + * const xdrproc_t xargs; -- xdr routine for args + * caddr_t argsp; -- pointer to args + * const xdrproc_t xresults; -- xdr routine for results + * caddr_t resultsp; -- pointer to results + * const resultproc_t eachresult; -- call with each result + * const char *nettype; -- Transport type + * + * For each valid response received, the procedure eachresult is called. + * Its form is: + * done = eachresult(resp, raddr, nconf) + * bool_t done; + * caddr_t resp; + * struct netbuf *raddr; + * struct netconfig *nconf; + * where resp points to the results of the call and raddr is the + * address if the responder to the broadcast. nconf is the transport + * on which the response was received. + * + * extern enum clnt_stat + * rpc_broadcast_exp(prog, vers, proc, xargs, argsp, xresults, resultsp, + * eachresult, inittime, waittime, nettype) + * const rpcprog_t prog; -- program number + * const rpcvers_t vers; -- version number + * const rpcproc_t proc; -- procedure number + * const xdrproc_t xargs; -- xdr routine for args + * caddr_t argsp; -- pointer to args + * const xdrproc_t xresults; -- xdr routine for results + * caddr_t resultsp; -- pointer to results + * const resultproc_t eachresult; -- call with each result + * const int inittime; -- how long to wait initially + * const int waittime; -- maximum time to wait + * const char *nettype; -- Transport type + */ + +typedef bool_t (*resultproc_t)(caddr_t, ...); + +__BEGIN_DECLS +extern enum clnt_stat rpc_broadcast(const rpcprog_t, const rpcvers_t, + const rpcproc_t, const xdrproc_t, + caddr_t, const xdrproc_t, caddr_t, + const resultproc_t, const char *); +extern enum clnt_stat rpc_broadcast_exp(const rpcprog_t, const rpcvers_t, + const rpcproc_t, const xdrproc_t, + caddr_t, const xdrproc_t, caddr_t, + const resultproc_t, const int, + const int, const char *); +__END_DECLS + +/* For backward compatibility */ +#include + +#endif /* !_RPC_CLNT_H_ */ diff --git a/include/rpc/clnt_soc.h b/include/rpc/clnt_soc.h new file mode 100644 index 0000000..7338989 --- /dev/null +++ b/include/rpc/clnt_soc.h @@ -0,0 +1,105 @@ +/* $NetBSD: clnt_soc.h,v 1.1 2000/06/02 22:57:55 fvdl Exp $ */ +/* $FreeBSD: releng/11.1/include/rpc/clnt_soc.h 258578 2013-11-25 19:04:36Z hrs $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +/* + * Copyright (c) 1984 - 1991 by Sun Microsystems, Inc. + */ + +/* + * clnt.h - Client side remote procedure call interface. + */ + +#ifndef _RPC_CLNT_SOC_H +#define _RPC_CLNT_SOC_H + +/* derived from clnt_soc.h 1.3 88/12/17 SMI */ + +/* + * All the following declarations are only for backward compatibility + * with TS-RPC. + */ + +#include + +#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */ + +/* + * TCP based rpc + * CLIENT * + * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long prog; + * u_long version; + * register int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +__BEGIN_DECLS +extern CLIENT *clnttcp_create(struct sockaddr_in *, u_long, u_long, int *, + u_int, u_int); +__END_DECLS + +/* + * Raw (memory) rpc. + */ +__BEGIN_DECLS +extern CLIENT *clntraw_create(u_long, u_long); +__END_DECLS + + +/* + * UDP based rpc. + * CLIENT * + * clntudp_create(raddr, program, version, wait, sockp) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * + * Same as above, but you specify max packet sizes. + * CLIENT * + * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +__BEGIN_DECLS +extern CLIENT *clntudp_create(struct sockaddr_in *, u_long, u_long, + struct timeval, int *); +extern CLIENT *clntudp_bufcreate(struct sockaddr_in *, u_long, u_long, + struct timeval, int *, u_int, u_int); +__END_DECLS + +#endif /* _RPC_CLNT_SOC_H */ diff --git a/include/rpc/clnt_stat.h b/include/rpc/clnt_stat.h new file mode 100644 index 0000000..fe5f98a --- /dev/null +++ b/include/rpc/clnt_stat.h @@ -0,0 +1,83 @@ +/* $FreeBSD: releng/11.1/include/rpc/clnt_stat.h 74509 2001-03-20 08:20:50Z alfred $ */ +/* + * Copyright (c) 1986 - 1991, 1994, 1996, 1997 by Sun Microsystems, Inc. + * All rights reserved. + */ + +/* + * clnt_stat.h - Client side remote procedure call enum + * + */ + +#ifndef _RPC_CLNT_STAT_H +#define _RPC_CLNT_STAT_H + +/* #pragma ident "@(#)clnt_stat.h 1.2 97/04/28 SMI" */ + +#ifdef __cplusplus +extern "C" { +#endif + +enum clnt_stat { + RPC_SUCCESS = 0, /* call succeeded */ + /* + * local errors + */ + RPC_CANTENCODEARGS = 1, /* can't encode arguments */ + RPC_CANTDECODERES = 2, /* can't decode results */ + RPC_CANTSEND = 3, /* failure in sending call */ + RPC_CANTRECV = 4, + /* failure in receiving result */ + RPC_TIMEDOUT = 5, /* call timed out */ + RPC_INTR = 18, /* call interrupted */ + RPC_UDERROR = 23, /* recv got uderr indication */ + /* + * remote errors + */ + RPC_VERSMISMATCH = 6, /* rpc versions not compatible */ + RPC_AUTHERROR = 7, /* authentication error */ + RPC_PROGUNAVAIL = 8, /* program not available */ + RPC_PROGVERSMISMATCH = 9, /* program version mismatched */ + RPC_PROCUNAVAIL = 10, /* procedure unavailable */ + RPC_CANTDECODEARGS = 11, /* decode arguments error */ + RPC_SYSTEMERROR = 12, /* generic "other problem" */ + + /* + * rpc_call & clnt_create errors + */ + RPC_UNKNOWNHOST = 13, /* unknown host name */ + RPC_UNKNOWNPROTO = 17, /* unknown protocol */ + RPC_UNKNOWNADDR = 19, /* Remote address unknown */ + RPC_NOBROADCAST = 21, /* Broadcasting not supported */ + + /* + * rpcbind errors + */ + RPC_RPCBFAILURE = 14, /* the pmapper failed in its call */ +#define RPC_PMAPFAILURE RPC_RPCBFAILURE + RPC_PROGNOTREGISTERED = 15, /* remote program is not registered */ + RPC_N2AXLATEFAILURE = 22, + /* Name to address translation failed */ + /* + * Misc error in the TLI library + */ + RPC_TLIERROR = 20, + /* + * unspecified error + */ + RPC_FAILED = 16, + /* + * asynchronous errors + */ + RPC_INPROGRESS = 24, + RPC_STALERACHANDLE = 25, + RPC_CANTCONNECT = 26, /* couldn't make connection (cots) */ + RPC_XPRTFAILED = 27, /* received discon from remote (cots) */ + RPC_CANTCREATESTREAM = 28 /* can't push rpc module (cots) */ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* !_RPC_CLNT_STAT_H */ diff --git a/include/rpc/des.h b/include/rpc/des.h new file mode 100644 index 0000000..ac36a92 --- /dev/null +++ b/include/rpc/des.h @@ -0,0 +1,82 @@ +/* @(#)des.h 2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI */ +/* $FreeBSD: releng/11.1/include/rpc/des.h 258578 2013-11-25 19:04:36Z hrs $ */ +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +/* + * Generic DES driver interface + * Keep this file hardware independent! + * Copyright (c) 1986 by Sun Microsystems, Inc. + */ + +#define DES_MAXLEN 65536 /* maximum # of bytes to encrypt */ +#define DES_QUICKLEN 16 /* maximum # of bytes to encrypt quickly */ + +enum desdir { ENCRYPT, DECRYPT }; +enum desmode { CBC, ECB }; + +/* + * parameters to ioctl call + */ +struct desparams { + u_char des_key[8]; /* key (with low bit parity) */ + enum desdir des_dir; /* direction */ + enum desmode des_mode; /* mode */ + u_char des_ivec[8]; /* input vector */ + unsigned des_len; /* number of bytes to crypt */ + union { + u_char UDES_data[DES_QUICKLEN]; + u_char *UDES_buf; + } UDES; +# define des_data UDES.UDES_data /* direct data here if quick */ +# define des_buf UDES.UDES_buf /* otherwise, pointer to data */ +}; + +#ifdef notdef + +/* + * These ioctls are only implemented in SunOS. Maybe someday + * if somebody writes a driver for DES hardware that works + * with FreeBSD, we can being that back. + */ + +/* + * Encrypt an arbitrary sized buffer + */ +#define DESIOCBLOCK _IOWR('d', 6, struct desparams) + +/* + * Encrypt of small amount of data, quickly + */ +#define DESIOCQUICK _IOWR('d', 7, struct desparams) + +#endif + +/* + * Software DES. + */ +extern int _des_crypt( char *, int, struct desparams * ); diff --git a/include/rpc/des_crypt.h b/include/rpc/des_crypt.h new file mode 100644 index 0000000..10643f1 --- /dev/null +++ b/include/rpc/des_crypt.h @@ -0,0 +1,105 @@ +/* + * @(#)des_crypt.h 2.1 88/08/11 4.0 RPCSRC; from 1.4 88/02/08 (C) 1986 SMI + * $FreeBSD: releng/11.1/include/rpc/des_crypt.h 258578 2013-11-25 19:04:36Z hrs $ + * + * des_crypt.h, des library routine interface + * Copyright (C) 1986, Sun Microsystems, Inc. + */ +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +/* + * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. + */ + +/* + * des_crypt.h, des library routine interface + */ + +#ifndef _DES_DES_CRYPT_H +#define _DES_DES_CRYPT_H + +#include +#include + +#define DES_MAXDATA 8192 /* max bytes encrypted in one call */ +#define DES_DIRMASK (1 << 0) +#define DES_ENCRYPT (0*DES_DIRMASK) /* Encrypt */ +#define DES_DECRYPT (1*DES_DIRMASK) /* Decrypt */ + + +#define DES_DEVMASK (1 << 1) +#define DES_HW (0*DES_DEVMASK) /* Use hardware device */ +#define DES_SW (1*DES_DEVMASK) /* Use software device */ + + +#define DESERR_NONE 0 /* succeeded */ +#define DESERR_NOHWDEVICE 1 /* succeeded, but hw device not available */ +#define DESERR_HWERROR 2 /* failed, hardware/driver error */ +#define DESERR_BADPARAM 3 /* failed, bad parameter to call */ + +#define DES_FAILED(err) \ + ((err) > DESERR_NOHWDEVICE) + +/* + * cbc_crypt() + * ecb_crypt() + * + * Encrypt (or decrypt) len bytes of a buffer buf. + * The length must be a multiple of eight. + * The key should have odd parity in the low bit of each byte. + * ivec is the input vector, and is updated to the new one (cbc only). + * The mode is created by oring together the appropriate parameters. + * DESERR_NOHWDEVICE is returned if DES_HW was specified but + * there was no hardware to do it on (the data will still be + * encrypted though, in software). + */ + + +/* + * Cipher Block Chaining mode + */ +__BEGIN_DECLS +int cbc_crypt( char *, char *, unsigned int, unsigned int, char *); +__END_DECLS + +/* + * Electronic Code Book mode + */ +__BEGIN_DECLS +int ecb_crypt( char *, char *, unsigned int, unsigned int ); +__END_DECLS + +/* + * Set des parity for a key. + * DES parity is odd and in the low bit of each byte + */ +__BEGIN_DECLS +void des_setparity( char *); +__END_DECLS + +#endif /* _DES_DES_CRYPT_H */ diff --git a/include/rpc/nettype.h b/include/rpc/nettype.h new file mode 100644 index 0000000..7b85a3e --- /dev/null +++ b/include/rpc/nettype.h @@ -0,0 +1,63 @@ +/* $NetBSD: nettype.h,v 1.2 2000/07/06 03:17:19 christos Exp $ */ +/* $FreeBSD: releng/11.1/include/rpc/nettype.h 258578 2013-11-25 19:04:36Z hrs $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +/* + * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. + */ + +/* + * nettype.h, Nettype definitions. + * All for the topmost layer of rpc + * + */ + +#ifndef _RPC_NETTYPE_H +#define _RPC_NETTYPE_H + +#include + +#define _RPC_NONE 0 +#define _RPC_NETPATH 1 +#define _RPC_VISIBLE 2 +#define _RPC_CIRCUIT_V 3 +#define _RPC_DATAGRAM_V 4 +#define _RPC_CIRCUIT_N 5 +#define _RPC_DATAGRAM_N 6 +#define _RPC_TCP 7 +#define _RPC_UDP 8 + +__BEGIN_DECLS +extern void *__rpc_setconf(const char *); +extern void __rpc_endconf(void *); +extern struct netconfig *__rpc_getconf(void *); +extern struct netconfig *__rpc_getconfip(const char *); +__END_DECLS + +#endif /* !_RPC_NETTYPE_H */ diff --git a/include/rpc/pmap_clnt.h b/include/rpc/pmap_clnt.h new file mode 100644 index 0000000..cf75899 --- /dev/null +++ b/include/rpc/pmap_clnt.h @@ -0,0 +1,85 @@ +/* $NetBSD: pmap_clnt.h,v 1.9 2000/06/02 22:57:55 fvdl Exp $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * from: @(#)pmap_clnt.h 1.11 88/02/08 SMI + * from: @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: releng/11.1/include/rpc/pmap_clnt.h 258578 2013-11-25 19:04:36Z hrs $ + */ + +/* + * pmap_clnt.h + * Supplies C routines to get to portmap services. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * Usage: + * success = pmap_set(program, version, protocol, port); + * success = pmap_unset(program, version); + * port = pmap_getport(address, program, version, protocol); + * head = pmap_getmaps(address); + * clnt_stat = pmap_rmtcall(address, program, version, procedure, + * xdrargs, argsp, xdrres, resp, tout, port_ptr) + * (works for udp only.) + * clnt_stat = clnt_broadcast(program, version, procedure, + * xdrargs, argsp, xdrres, resp, eachresult) + * (like pmap_rmtcall, except the call is broadcasted to all + * locally connected nets. For each valid response received, + * the procedure eachresult is called. Its form is: + * done = eachresult(resp, raddr) + * bool_t done; + * caddr_t resp; + * struct sockaddr_in raddr; + * where resp points to the results of the call and raddr is the + * address if the responder to the broadcast. + */ + +#ifndef _RPC_PMAP_CLNT_H_ +#define _RPC_PMAP_CLNT_H_ +#include + +__BEGIN_DECLS +extern bool_t pmap_set(u_long, u_long, int, int); +extern bool_t pmap_unset(u_long, u_long); +extern struct pmaplist *pmap_getmaps(struct sockaddr_in *); +extern enum clnt_stat pmap_rmtcall(struct sockaddr_in *, + u_long, u_long, u_long, + xdrproc_t, caddr_t, + xdrproc_t, caddr_t, + struct timeval, u_long *); +extern enum clnt_stat clnt_broadcast(u_long, u_long, u_long, + xdrproc_t, void *, + xdrproc_t, void *, + resultproc_t); +extern u_short pmap_getport(struct sockaddr_in *, + u_long, u_long, u_int); +__END_DECLS + +#endif /* !_RPC_PMAP_CLNT_H_ */ diff --git a/include/rpc/pmap_prot.h b/include/rpc/pmap_prot.h new file mode 100644 index 0000000..644b417 --- /dev/null +++ b/include/rpc/pmap_prot.h @@ -0,0 +1,106 @@ +/* $NetBSD: pmap_prot.h,v 1.8 2000/06/02 22:57:55 fvdl Exp $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * from: @(#)pmap_prot.h 1.14 88/02/08 SMI + * from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: releng/11.1/include/rpc/pmap_prot.h 258578 2013-11-25 19:04:36Z hrs $ + */ + +/* + * pmap_prot.h + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The following procedures are supported by the protocol: + * + * PMAPPROC_NULL() returns () + * takes nothing, returns nothing + * + * PMAPPROC_SET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Registers the tuple + * [prog, vers, prot, port]. + * + * PMAPPROC_UNSET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Un-registers pair + * [prog, vers]. prot and port are ignored. + * + * PMAPPROC_GETPORT(struct pmap) returns (long unsigned). + * 0 is failure. Otherwise returns the port number where the pair + * [prog, vers] is registered. It may lie! + * + * PMAPPROC_DUMP() RETURNS (struct pmaplist *) + * + * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>) + * RETURNS (port, string<>); + * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); + * Calls the procedure on the local machine. If it is not registered, + * this procedure is quite; ie it does not return error information!!! + * This procedure only is supported on rpc/udp and calls via + * rpc/udp. This routine only passes null authentication parameters. + * This file has no interface to xdr routines for PMAPPROC_CALLIT. + * + * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. + */ + +#ifndef _RPC_PMAP_PROT_H +#define _RPC_PMAP_PROT_H +#include + +#define PMAPPORT ((u_short)111) +#define PMAPPROG ((u_long)100000) +#define PMAPVERS ((u_long)2) +#define PMAPVERS_PROTO ((u_long)2) +#define PMAPVERS_ORIG ((u_long)1) +#define PMAPPROC_NULL ((u_long)0) +#define PMAPPROC_SET ((u_long)1) +#define PMAPPROC_UNSET ((u_long)2) +#define PMAPPROC_GETPORT ((u_long)3) +#define PMAPPROC_DUMP ((u_long)4) +#define PMAPPROC_CALLIT ((u_long)5) + +struct pmap { + long unsigned pm_prog; + long unsigned pm_vers; + long unsigned pm_prot; + long unsigned pm_port; +}; + +struct pmaplist { + struct pmap pml_map; + struct pmaplist *pml_next; +}; + +__BEGIN_DECLS +extern bool_t xdr_pmap(XDR *, struct pmap *); +extern bool_t xdr_pmaplist(XDR *, struct pmaplist **); +extern bool_t xdr_pmaplist_ptr(XDR *, struct pmaplist *); +__END_DECLS + +#endif /* !_RPC_PMAP_PROT_H */ diff --git a/include/rpc/pmap_rmt.h b/include/rpc/pmap_rmt.h new file mode 100644 index 0000000..b31cab7 --- /dev/null +++ b/include/rpc/pmap_rmt.h @@ -0,0 +1,64 @@ +/* $NetBSD: pmap_rmt.h,v 1.7 1998/02/11 23:01:23 lukem Exp $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * from: @(#)pmap_rmt.h 1.2 88/02/08 SMI + * from: @(#)pmap_rmt.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: releng/11.1/include/rpc/pmap_rmt.h 258578 2013-11-25 19:04:36Z hrs $ + */ + +/* + * Structures and XDR routines for parameters to and replies from + * the portmapper remote-call-service. + * + * Copyright (C) 1986, Sun Microsystems, Inc. + */ + +#ifndef _RPC_PMAP_RMT_H +#define _RPC_PMAP_RMT_H +#include + +struct rmtcallargs { + u_long prog, vers, proc, arglen; + caddr_t args_ptr; + xdrproc_t xdr_args; +}; + +struct rmtcallres { + u_long *port_ptr; + u_long resultslen; + caddr_t results_ptr; + xdrproc_t xdr_results; +}; + +__BEGIN_DECLS +extern bool_t xdr_rmtcall_args(XDR *, struct rmtcallargs *); +extern bool_t xdr_rmtcallres(XDR *, struct rmtcallres *); +__END_DECLS + +#endif /* !_RPC_PMAP_RMT_H */ diff --git a/include/rpc/raw.h b/include/rpc/raw.h new file mode 100644 index 0000000..22024c6 --- /dev/null +++ b/include/rpc/raw.h @@ -0,0 +1,57 @@ +/* $NetBSD: raw.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $ */ +/* $FreeBSD: releng/11.1/include/rpc/raw.h 258578 2013-11-25 19:04:36Z hrs $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +/* + * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. + */ + +#ifndef _RPC_RAW_H +#define _RPC_RAW_H + +/* from: @(#)raw.h 1.11 94/04/25 SMI */ +/* from: @(#)raw.h 1.2 88/10/25 SMI */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * raw.h + * + * Raw interface + * The common memory area over which they will communicate + */ +extern char *__rpc_rawcombuf; + +#ifdef __cplusplus +} +#endif + +#endif /* _RPC_RAW_H */ diff --git a/include/rpc/rpc.h b/include/rpc/rpc.h new file mode 100644 index 0000000..60cc95e --- /dev/null +++ b/include/rpc/rpc.h @@ -0,0 +1,107 @@ +/* $NetBSD: rpc.h,v 1.13 2000/06/02 22:57:56 fvdl Exp $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * from: @(#)rpc.h 1.9 88/02/08 SMI + * from: @(#)rpc.h 2.4 89/07/11 4.0 RPCSRC + * $FreeBSD: releng/11.1/include/rpc/rpc.h 258578 2013-11-25 19:04:36Z hrs $ + */ + +/* + * rpc.h, Just includes the billions of rpc header files necessary to + * do remote procedure calling. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ +#ifndef _RPC_RPC_H +#define _RPC_RPC_H + +#include /* some typedefs */ +#include +#include + +/* external data representation interfaces */ +#include /* generic (de)serializer */ + +/* Client side only authentication */ +#include /* generic authenticator (client side) */ + +/* Client side (mostly) remote procedure call */ +#include /* generic rpc stuff */ + +/* semi-private protocol headers */ +#include /* protocol for rpc messages */ +#include /* protocol for unix style cred */ +/* + * Uncomment-out the next line if you are building the rpc library with + * DES Authentication (see the README file in the secure_rpc/ directory). + */ +#include /* protocol for des style cred */ + +/* Server side only remote procedure callee */ +#include /* service manager and multiplexer */ +#include /* service side authenticator */ + +/* Portmapper client, server, and protocol headers */ +#include +#include + +#ifndef _KERNEL +#include /* rpcbind interface functions */ +#endif + +#include + +__BEGIN_DECLS +extern int get_myaddress(struct sockaddr_in *); +extern int bindresvport(int, struct sockaddr_in *); +extern int registerrpc(int, int, int, char *(*)(char [UDPMSGSIZE]), + xdrproc_t, xdrproc_t); +extern int callrpc(const char *, int, int, int, xdrproc_t, void *, + xdrproc_t , void *); +extern int getrpcport(char *, int, int, int); + +char *taddr2uaddr(const struct netconfig *, const struct netbuf *); +struct netbuf *uaddr2taddr(const struct netconfig *, const char *); + +struct sockaddr; +extern int bindresvport_sa(int, struct sockaddr *); +__END_DECLS + +/* + * The following are not exported interfaces, they are for internal library + * and rpcbind use only. Do not use, they may change without notice. + */ +__BEGIN_DECLS +int __rpc_nconf2fd(const struct netconfig *); +int __rpc_nconf2sockinfo(const struct netconfig *, struct __rpc_sockinfo *); +int __rpc_fd2sockinfo(int, struct __rpc_sockinfo *); +u_int __rpc_get_t_size(int, int, int); +__END_DECLS + +#endif /* !_RPC_RPC_H */ diff --git a/include/rpc/rpc_com.h b/include/rpc/rpc_com.h new file mode 100644 index 0000000..d80c6df --- /dev/null +++ b/include/rpc/rpc_com.h @@ -0,0 +1,82 @@ +/* $NetBSD: rpc_com.h,v 1.3 2000/12/10 04:10:08 christos Exp $ */ +/* $FreeBSD: releng/11.1/include/rpc/rpc_com.h 258578 2013-11-25 19:04:36Z hrs $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +/* + * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. + */ + +/* + * rpc_com.h, Common definitions for both the server and client side. + * All for the topmost layer of rpc + * + */ + +#ifndef _RPC_RPCCOM_H +#define _RPC_RPCCOM_H + +#include + +/* #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */ + +/* + * The max size of the transport, if the size cannot be determined + * by other means. + */ +#define RPC_MAXDATASIZE 9000 +#define RPC_MAXADDRSIZE 1024 + +#define __RPC_GETXID(now) ((u_int32_t)getpid() ^ (u_int32_t)(now)->tv_sec ^ \ + (u_int32_t)(now)->tv_usec) + +__BEGIN_DECLS +extern u_int __rpc_get_a_size(int); +extern int __rpc_dtbsize(void); +extern int _rpc_dtablesize(void); +extern struct netconfig * __rpcgettp(int); +extern int __rpc_get_default_domain(char **); + +char *__rpc_taddr2uaddr_af(int, const struct netbuf *); +struct netbuf *__rpc_uaddr2taddr_af(int, const char *); +int __rpc_fixup_addr(struct netbuf *, const struct netbuf *); +int __rpc_sockinfo2netid(struct __rpc_sockinfo *, const char **); +int __rpc_seman2socktype(int); +int __rpc_socktype2seman(int); +void *rpc_nullproc(CLIENT *); +int __rpc_sockisbound(int); + +struct netbuf *__rpcb_findaddr(rpcprog_t, rpcvers_t, const struct netconfig *, + const char *, CLIENT **); +bool_t rpc_control(int,void *); + +char *_get_next_token(char *, int); + +__END_DECLS + +#endif /* _RPC_RPCCOM_H */ diff --git a/include/rpc/rpc_msg.h b/include/rpc/rpc_msg.h new file mode 100644 index 0000000..cd9e9b8 --- /dev/null +++ b/include/rpc/rpc_msg.h @@ -0,0 +1,213 @@ +/* $NetBSD: rpc_msg.h,v 1.11 2000/06/02 22:57:56 fvdl Exp $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * from: @(#)rpc_msg.h 1.7 86/07/16 SMI + * from: @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: releng/11.1/include/rpc/rpc_msg.h 258578 2013-11-25 19:04:36Z hrs $ + */ + +/* + * rpc_msg.h + * rpc message definition + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_RPC_MSG_H +#define _RPC_RPC_MSG_H + +#define RPC_MSG_VERSION ((u_int32_t) 2) +#define RPC_SERVICE_PORT ((u_short) 2048) + +/* + * Bottom up definition of an rpc message. + * NOTE: call and reply use the same overall stuct but + * different parts of unions within it. + */ + +enum msg_type { + CALL=0, + REPLY=1 +}; + +enum reply_stat { + MSG_ACCEPTED=0, + MSG_DENIED=1 +}; + +enum accept_stat { + SUCCESS=0, + PROG_UNAVAIL=1, + PROG_MISMATCH=2, + PROC_UNAVAIL=3, + GARBAGE_ARGS=4, + SYSTEM_ERR=5 +}; + +enum reject_stat { + RPC_MISMATCH=0, + AUTH_ERROR=1 +}; + +/* + * Reply part of an rpc exchange + */ + +/* + * Reply to an rpc request that was accepted by the server. + * Note: there could be an error even though the request was + * accepted. + */ +struct accepted_reply { + struct opaque_auth ar_verf; + enum accept_stat ar_stat; + union { + struct { + rpcvers_t low; + rpcvers_t high; + } AR_versions; + struct { + caddr_t where; + xdrproc_t proc; + } AR_results; + /* and many other null cases */ + } ru; +#define ar_results ru.AR_results +#define ar_vers ru.AR_versions +}; + +/* + * Reply to an rpc request that was rejected by the server. + */ +struct rejected_reply { + enum reject_stat rj_stat; + union { + struct { + rpcvers_t low; + rpcvers_t high; + } RJ_versions; + enum auth_stat RJ_why; /* why authentication did not work */ + } ru; +#define rj_vers ru.RJ_versions +#define rj_why ru.RJ_why +}; + +/* + * Body of a reply to an rpc request. + */ +struct reply_body { + enum reply_stat rp_stat; + union { + struct accepted_reply RP_ar; + struct rejected_reply RP_dr; + } ru; +#define rp_acpt ru.RP_ar +#define rp_rjct ru.RP_dr +}; + +/* + * Body of an rpc request call. + */ +struct call_body { + rpcvers_t cb_rpcvers; /* must be equal to two */ + rpcprog_t cb_prog; + rpcvers_t cb_vers; + rpcproc_t cb_proc; + struct opaque_auth cb_cred; + struct opaque_auth cb_verf; /* protocol specific - provided by client */ +}; + +/* + * The rpc message + */ +struct rpc_msg { + u_int32_t rm_xid; + enum msg_type rm_direction; + union { + struct call_body RM_cmb; + struct reply_body RM_rmb; + } ru; +#define rm_call ru.RM_cmb +#define rm_reply ru.RM_rmb +}; +#define acpted_rply ru.RM_rmb.ru.RP_ar +#define rjcted_rply ru.RM_rmb.ru.RP_dr + +__BEGIN_DECLS +/* + * XDR routine to handle a rpc message. + * xdr_callmsg(xdrs, cmsg) + * XDR *xdrs; + * struct rpc_msg *cmsg; + */ +extern bool_t xdr_callmsg(XDR *, struct rpc_msg *); + +/* + * XDR routine to pre-serialize the static part of a rpc message. + * xdr_callhdr(xdrs, cmsg) + * XDR *xdrs; + * struct rpc_msg *cmsg; + */ +extern bool_t xdr_callhdr(XDR *, struct rpc_msg *); + +/* + * XDR routine to handle a rpc reply. + * xdr_replymsg(xdrs, rmsg) + * XDR *xdrs; + * struct rpc_msg *rmsg; + */ +extern bool_t xdr_replymsg(XDR *, struct rpc_msg *); + + +/* + * XDR routine to handle an accepted rpc reply. + * xdr_accepted_reply(xdrs, rej) + * XDR *xdrs; + * struct accepted_reply *rej; + */ +extern bool_t xdr_accepted_reply(XDR *, struct accepted_reply *); + +/* + * XDR routine to handle a rejected rpc reply. + * xdr_rejected_reply(xdrs, rej) + * XDR *xdrs; + * struct rejected_reply *rej; + */ +extern bool_t xdr_rejected_reply(XDR *, struct rejected_reply *); + +/* + * Fills in the error part of a reply message. + * _seterr_reply(msg, error) + * struct rpc_msg *msg; + * struct rpc_err *error; + */ +extern void _seterr_reply(struct rpc_msg *, struct rpc_err *); +__END_DECLS + +#endif /* !_RPC_RPC_MSG_H */ diff --git a/include/rpc/rpcb_clnt.h b/include/rpc/rpcb_clnt.h new file mode 100644 index 0000000..53ef5cc --- /dev/null +++ b/include/rpc/rpcb_clnt.h @@ -0,0 +1,84 @@ +/* $NetBSD: rpcb_clnt.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $ */ +/* $FreeBSD: releng/11.1/include/rpc/rpcb_clnt.h 258578 2013-11-25 19:04:36Z hrs $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +/* + * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. + */ + +/* + * rpcb_clnt.h + * Supplies C routines to get to rpcbid services. + * + */ + +/* + * Usage: + * success = rpcb_set(program, version, nconf, address); + * success = rpcb_unset(program, version, nconf); + * success = rpcb_getaddr(program, version, nconf, host); + * head = rpcb_getmaps(nconf, host); + * clnt_stat = rpcb_rmtcall(nconf, host, program, version, procedure, + * xdrargs, argsp, xdrres, resp, tout, addr_ptr) + * success = rpcb_gettime(host, timep) + * uaddr = rpcb_taddr2uaddr(nconf, taddr); + * taddr = rpcb_uaddr2uaddr(nconf, uaddr); + */ + +#ifndef _RPC_RPCB_CLNT_H +#define _RPC_RPCB_CLNT_H + +/* #pragma ident "@(#)rpcb_clnt.h 1.13 94/04/25 SMI" */ +/* rpcb_clnt.h 1.3 88/12/05 SMI */ + +#include +#include + +__BEGIN_DECLS +extern bool_t rpcb_set(const rpcprog_t, const rpcvers_t, + const struct netconfig *, const struct netbuf *); +extern bool_t rpcb_unset(const rpcprog_t, const rpcvers_t, + const struct netconfig *); +extern rpcblist *rpcb_getmaps(const struct netconfig *, const char *); +extern enum clnt_stat rpcb_rmtcall(const struct netconfig *, + const char *, const rpcprog_t, + const rpcvers_t, const rpcproc_t, + const xdrproc_t, const caddr_t, + const xdrproc_t, const caddr_t, + const struct timeval, + const struct netbuf *); +extern bool_t rpcb_getaddr(const rpcprog_t, const rpcvers_t, + const struct netconfig *, struct netbuf *, + const char *); +extern bool_t rpcb_gettime(const char *, time_t *); +extern char *rpcb_taddr2uaddr(struct netconfig *, struct netbuf *); +extern struct netbuf *rpcb_uaddr2taddr(struct netconfig *, char *); +__END_DECLS + +#endif /* !_RPC_RPCB_CLNT_H */ diff --git a/include/rpc/rpcb_prot.x b/include/rpc/rpcb_prot.x new file mode 100644 index 0000000..496f5d7 --- /dev/null +++ b/include/rpc/rpcb_prot.x @@ -0,0 +1,553 @@ +%/*- +% * $FreeBSD: releng/11.1/include/rpc/rpcb_prot.x 258578 2013-11-25 19:04:36Z hrs $ +% * +% * Copyright (c) 2009, Sun Microsystems, Inc. +% * All rights reserved. +% * +% * Redistribution and use in source and binary forms, with or without +% * modification, are permitted provided that the following conditions are met: +% * - Redistributions of source code must retain the above copyright notice, +% * this list of conditions and the following disclaimer. +% * - 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. +% * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. +% */ +%/* +% * Copyright (c) 1988 by Sun Microsystems, Inc. +% */ + +%/* from rpcb_prot.x */ + +#ifdef RPC_HDR +% +%/* #pragma ident "@(#)rpcb_prot.x 1.5 94/04/29 SMI" */ +% +%#ifndef _KERNEL +% +#endif + +/* + * rpcb_prot.x + * rpcbind protocol, versions 3 and 4, in RPC Language + */ +% +%/* +% * The following procedures are supported by the protocol in version 3: +% * +% * RPCBPROC_NULL() returns () +% * takes nothing, returns nothing +% * +% * RPCBPROC_SET(rpcb) returns (bool_t) +% * TRUE is success, FALSE is failure. Registers the tuple +% * [prog, vers, address, owner, netid]. +% * Finds out owner and netid information on its own. +% * +% * RPCBPROC_UNSET(rpcb) returns (bool_t) +% * TRUE is success, FALSE is failure. Un-registers tuple +% * [prog, vers, netid]. addresses is ignored. +% * If netid is NULL, unregister all. +% * +% * RPCBPROC_GETADDR(rpcb) returns (string). +% * 0 is failure. Otherwise returns the universal address where the +% * triple [prog, vers, netid] is registered. Ignore address and owner. +% * +% * RPCBPROC_DUMP() RETURNS (rpcblist_ptr) +% * used to dump the entire rpcbind maps +% * +% * RPCBPROC_CALLIT(rpcb_rmtcallargs) +% * RETURNS (rpcb_rmtcallres); +% * Calls the procedure on the remote machine. If it is not registered, +% * this procedure is quiet; i.e. it does not return error information!!! +% * This routine only passes null authentication parameters. +% * It has no interface to xdr routines for RPCBPROC_CALLIT. +% * +% * RPCBPROC_GETTIME() returns (int). +% * Gets the remote machines time +% * +% * RPCBPROC_UADDR2TADDR(strint) RETURNS (struct netbuf) +% * Returns the netbuf address from universal address. +% * +% * RPCBPROC_TADDR2UADDR(struct netbuf) RETURNS (string) +% * Returns the universal address from netbuf address. +% * +% * END OF RPCBIND VERSION 3 PROCEDURES +% */ +%/* +% * Except for RPCBPROC_CALLIT, the procedures above are carried over to +% * rpcbind version 4. Those below are added or modified for version 4. +% * NOTE: RPCBPROC_BCAST HAS THE SAME FUNCTIONALITY AND PROCEDURE NUMBER +% * AS RPCBPROC_CALLIT. +% * +% * RPCBPROC_BCAST(rpcb_rmtcallargs) +% * RETURNS (rpcb_rmtcallres); +% * Calls the procedure on the remote machine. If it is not registered, +% * this procedure IS quiet; i.e. it DOES NOT return error information!!! +% * This routine should be used for broadcasting and nothing else. +% * +% * RPCBPROC_GETVERSADDR(rpcb) returns (string). +% * 0 is failure. Otherwise returns the universal address where the +% * triple [prog, vers, netid] is registered. Ignore address and owner. +% * Same as RPCBPROC_GETADDR except that if the given version number +% * is not available, the address is not returned. +% * +% * RPCBPROC_INDIRECT(rpcb_rmtcallargs) +% * RETURNS (rpcb_rmtcallres); +% * Calls the procedure on the remote machine. If it is not registered, +% * this procedure is NOT quiet; i.e. it DOES return error information!!! +% * as any normal application would expect. +% * +% * RPCBPROC_GETADDRLIST(rpcb) returns (rpcb_entry_list_ptr). +% * Same as RPCBPROC_GETADDR except that it returns a list of all the +% * addresses registered for the combination (prog, vers) (for all +% * transports). +% * +% * RPCBPROC_GETSTAT(void) returns (rpcb_stat_byvers) +% * Returns the statistics about the kind of requests received by rpcbind. +% */ +% +%/* +% * A mapping of (program, version, network ID) to address +% */ +struct rpcb { + rpcprog_t r_prog; /* program number */ + rpcvers_t r_vers; /* version number */ + string r_netid<>; /* network id */ + string r_addr<>; /* universal address */ + string r_owner<>; /* owner of this service */ +}; +#ifdef RPC_HDR +% +%typedef rpcb RPCB; +% +#endif +% +%/* +% * A list of mappings +% * +% * Below are two definitions for the rpcblist structure. This is done because +% * xdr_rpcblist() is specified to take a struct rpcblist **, rather than a +% * struct rpcblist * that rpcgen would produce. One version of the rpcblist +% * structure (actually called rp__list) is used with rpcgen, and the other is +% * defined only in the header file for compatibility with the specified +% * interface. +% */ + +struct rp__list { + rpcb rpcb_map; + struct rp__list *rpcb_next; +}; + +typedef rp__list *rpcblist_ptr; /* results of RPCBPROC_DUMP */ + +#ifdef RPC_HDR +% +%typedef struct rp__list rpcblist; +%typedef struct rp__list RPCBLIST; +% +%#ifndef __cplusplus +%struct rpcblist { +% RPCB rpcb_map; +% struct rpcblist *rpcb_next; +%}; +%#endif +% +%#ifdef __cplusplus +%extern "C" { +%#endif +%extern bool_t xdr_rpcblist(XDR *, rpcblist**); +%#ifdef __cplusplus +%} +%#endif +% +#endif + +% +%/* +% * Arguments of remote calls +% */ +struct rpcb_rmtcallargs { + rpcprog_t prog; /* program number */ + rpcvers_t vers; /* version number */ + rpcproc_t proc; /* procedure number */ + opaque args<>; /* argument */ +}; +#ifdef RPC_HDR +% +%/* +% * Client-side only representation of rpcb_rmtcallargs structure. +% * +% * The routine that XDRs the rpcb_rmtcallargs structure must deal with the +% * opaque arguments in the "args" structure. xdr_rpcb_rmtcallargs() needs to +% * be passed the XDR routine that knows the args' structure. This routine +% * doesn't need to go over-the-wire (and it wouldn't make sense anyway) since +% * the application being called already knows the args structure. So we use a +% * different "XDR" structure on the client side, r_rpcb_rmtcallargs, which +% * includes the args' XDR routine. +% */ +%struct r_rpcb_rmtcallargs { +% rpcprog_t prog; +% rpcvers_t vers; +% rpcproc_t proc; +% struct { +% u_int args_len; +% char *args_val; +% } args; +% xdrproc_t xdr_args; /* encodes args */ +%}; +% +#endif /* def RPC_HDR */ +% +%/* +% * Results of the remote call +% */ +struct rpcb_rmtcallres { + string addr<>; /* remote universal address */ + opaque results<>; /* result */ +}; +#ifdef RPC_HDR +% +%/* +% * Client-side only representation of rpcb_rmtcallres structure. +% */ +%struct r_rpcb_rmtcallres { +% char *addr; +% struct { +% u_int32_t results_len; +% char *results_val; +% } results; +% xdrproc_t xdr_res; /* decodes results */ +%}; +#endif /* RPC_HDR */ +% +%/* +% * rpcb_entry contains a merged address of a service on a particular +% * transport, plus associated netconfig information. A list of rpcb_entrys +% * is returned by RPCBPROC_GETADDRLIST. See netconfig.h for values used +% * in r_nc_* fields. +% */ +struct rpcb_entry { + string r_maddr<>; /* merged address of service */ + string r_nc_netid<>; /* netid field */ + unsigned int r_nc_semantics; /* semantics of transport */ + string r_nc_protofmly<>; /* protocol family */ + string r_nc_proto<>; /* protocol name */ +}; +% +%/* +% * A list of addresses supported by a service. +% */ +struct rpcb_entry_list { + rpcb_entry rpcb_entry_map; + struct rpcb_entry_list *rpcb_entry_next; +}; + +typedef rpcb_entry_list *rpcb_entry_list_ptr; + +% +%/* +% * rpcbind statistics +% */ +% +const rpcb_highproc_2 = RPCBPROC_CALLIT; +const rpcb_highproc_3 = RPCBPROC_TADDR2UADDR; +const rpcb_highproc_4 = RPCBPROC_GETSTAT; + +const RPCBSTAT_HIGHPROC = 13; /* # of procs in rpcbind V4 plus one */ +const RPCBVERS_STAT = 3; /* provide only for rpcbind V2, V3 and V4 */ +const RPCBVERS_4_STAT = 2; +const RPCBVERS_3_STAT = 1; +const RPCBVERS_2_STAT = 0; +% +%/* Link list of all the stats about getport and getaddr */ +struct rpcbs_addrlist { + rpcprog_t prog; + rpcvers_t vers; + int success; + int failure; + string netid<>; + struct rpcbs_addrlist *next; +}; +% +%/* Link list of all the stats about rmtcall */ +struct rpcbs_rmtcalllist { + rpcprog_t prog; + rpcvers_t vers; + rpcproc_t proc; + int success; + int failure; + int indirect; /* whether callit or indirect */ + string netid<>; + struct rpcbs_rmtcalllist *next; +}; + +typedef int rpcbs_proc[RPCBSTAT_HIGHPROC]; +typedef rpcbs_addrlist *rpcbs_addrlist_ptr; +typedef rpcbs_rmtcalllist *rpcbs_rmtcalllist_ptr; + +struct rpcb_stat { + rpcbs_proc info; + int setinfo; + int unsetinfo; + rpcbs_addrlist_ptr addrinfo; + rpcbs_rmtcalllist_ptr rmtinfo; +}; +% +%/* +% * One rpcb_stat structure is returned for each version of rpcbind +% * being monitored. +% */ + +typedef rpcb_stat rpcb_stat_byvers[RPCBVERS_STAT]; + +#ifdef RPC_HDR +% +%/* +% * We don't define netbuf in RPCL, since it would contain structure member +% * names that would conflict with the definition of struct netbuf in +% * . Instead we merely declare the XDR routine xdr_netbuf() here, +% * and implement it ourselves in rpc/rpcb_prot.c. +% */ +%#ifdef __cplusplus +%extern "C" bool_t xdr_netbuf(XDR *, struct netbuf *); +% +%#else /* __STDC__ */ +%extern bool_t xdr_netbuf(XDR *, struct netbuf *); +% +%#endif +#endif /* def RPC_HDR */ + +/* + * rpcbind procedures + */ +program RPCBPROG { + version RPCBVERS { + bool + RPCBPROC_SET(rpcb) = 1; + + bool + RPCBPROC_UNSET(rpcb) = 2; + + string + RPCBPROC_GETADDR(rpcb) = 3; + + rpcblist_ptr + RPCBPROC_DUMP(void) = 4; + + rpcb_rmtcallres + RPCBPROC_CALLIT(rpcb_rmtcallargs) = 5; + + unsigned int + RPCBPROC_GETTIME(void) = 6; + + struct netbuf + RPCBPROC_UADDR2TADDR(string) = 7; + + string + RPCBPROC_TADDR2UADDR(struct netbuf) = 8; + } = 3; + + version RPCBVERS4 { + bool + RPCBPROC_SET(rpcb) = 1; + + bool + RPCBPROC_UNSET(rpcb) = 2; + + string + RPCBPROC_GETADDR(rpcb) = 3; + + rpcblist_ptr + RPCBPROC_DUMP(void) = 4; + + /* + * NOTE: RPCBPROC_BCAST has the same functionality as CALLIT; + * the new name is intended to indicate that this + * procedure should be used for broadcast RPC, and + * RPCBPROC_INDIRECT should be used for indirect calls. + */ + rpcb_rmtcallres + RPCBPROC_BCAST(rpcb_rmtcallargs) = RPCBPROC_CALLIT; + + unsigned int + RPCBPROC_GETTIME(void) = 6; + + struct netbuf + RPCBPROC_UADDR2TADDR(string) = 7; + + string + RPCBPROC_TADDR2UADDR(struct netbuf) = 8; + + string + RPCBPROC_GETVERSADDR(rpcb) = 9; + + rpcb_rmtcallres + RPCBPROC_INDIRECT(rpcb_rmtcallargs) = 10; + + rpcb_entry_list_ptr + RPCBPROC_GETADDRLIST(rpcb) = 11; + + rpcb_stat_byvers + RPCBPROC_GETSTAT(void) = 12; + } = 4; +} = 100000; +#ifdef RPC_HDR +% +%#define RPCBVERS_3 RPCBVERS +%#define RPCBVERS_4 RPCBVERS4 +% +%#define _PATH_RPCBINDSOCK "/var/run/rpcbind.sock" +% +%#else /* ndef _KERNEL */ +%#ifdef __cplusplus +%extern "C" { +%#endif +% +%/* +% * A mapping of (program, version, network ID) to address +% */ +%struct rpcb { +% rpcprog_t r_prog; /* program number */ +% rpcvers_t r_vers; /* version number */ +% char *r_netid; /* network id */ +% char *r_addr; /* universal address */ +% char *r_owner; /* owner of the mapping */ +%}; +%typedef struct rpcb RPCB; +% +%/* +% * A list of mappings +% */ +%struct rpcblist { +% RPCB rpcb_map; +% struct rpcblist *rpcb_next; +%}; +%typedef struct rpcblist RPCBLIST; +%typedef struct rpcblist *rpcblist_ptr; +% +%/* +% * Remote calls arguments +% */ +%struct rpcb_rmtcallargs { +% rpcprog_t prog; /* program number */ +% rpcvers_t vers; /* version number */ +% rpcproc_t proc; /* procedure number */ +% u_int32_t arglen; /* arg len */ +% caddr_t args_ptr; /* argument */ +% xdrproc_t xdr_args; /* XDR routine for argument */ +%}; +%typedef struct rpcb_rmtcallargs rpcb_rmtcallargs; +% +%/* +% * Remote calls results +% */ +%struct rpcb_rmtcallres { +% char *addr_ptr; /* remote universal address */ +% u_int32_t resultslen; /* results length */ +% caddr_t results_ptr; /* results */ +% xdrproc_t xdr_results; /* XDR routine for result */ +%}; +%typedef struct rpcb_rmtcallres rpcb_rmtcallres; +% +%struct rpcb_entry { +% char *r_maddr; +% char *r_nc_netid; +% unsigned int r_nc_semantics; +% char *r_nc_protofmly; +% char *r_nc_proto; +%}; +%typedef struct rpcb_entry rpcb_entry; +% +%/* +% * A list of addresses supported by a service. +% */ +% +%struct rpcb_entry_list { +% rpcb_entry rpcb_entry_map; +% struct rpcb_entry_list *rpcb_entry_next; +%}; +%typedef struct rpcb_entry_list rpcb_entry_list; +% +%typedef rpcb_entry_list *rpcb_entry_list_ptr; +% +%/* +% * rpcbind statistics +% */ +% +%#define rpcb_highproc_2 RPCBPROC_CALLIT +%#define rpcb_highproc_3 RPCBPROC_TADDR2UADDR +%#define rpcb_highproc_4 RPCBPROC_GETSTAT +%#define RPCBSTAT_HIGHPROC 13 +%#define RPCBVERS_STAT 3 +%#define RPCBVERS_4_STAT 2 +%#define RPCBVERS_3_STAT 1 +%#define RPCBVERS_2_STAT 0 +% +%/* Link list of all the stats about getport and getaddr */ +% +%struct rpcbs_addrlist { +% rpcprog_t prog; +% rpcvers_t vers; +% int success; +% int failure; +% char *netid; +% struct rpcbs_addrlist *next; +%}; +%typedef struct rpcbs_addrlist rpcbs_addrlist; +% +%/* Link list of all the stats about rmtcall */ +% +%struct rpcbs_rmtcalllist { +% rpcprog_t prog; +% rpcvers_t vers; +% rpcproc_t proc; +% int success; +% int failure; +% int indirect; +% char *netid; +% struct rpcbs_rmtcalllist *next; +%}; +%typedef struct rpcbs_rmtcalllist rpcbs_rmtcalllist; +% +%typedef int rpcbs_proc[RPCBSTAT_HIGHPROC]; +% +%typedef rpcbs_addrlist *rpcbs_addrlist_ptr; +% +%typedef rpcbs_rmtcalllist *rpcbs_rmtcalllist_ptr; +% +%struct rpcb_stat { +% rpcbs_proc info; +% int setinfo; +% int unsetinfo; +% rpcbs_addrlist_ptr addrinfo; +% rpcbs_rmtcalllist_ptr rmtinfo; +%}; +%typedef struct rpcb_stat rpcb_stat; +% +%/* +% * One rpcb_stat structure is returned for each version of rpcbind +% * being monitored. +% */ +% +%typedef rpcb_stat rpcb_stat_byvers[RPCBVERS_STAT]; +% +%#ifdef __cplusplus +%} +%#endif +% +%#endif /* ndef _KERNEL */ +#endif /* RPC_HDR */ diff --git a/include/rpc/rpcent.h b/include/rpc/rpcent.h new file mode 100644 index 0000000..600020d --- /dev/null +++ b/include/rpc/rpcent.h @@ -0,0 +1,66 @@ +/* $NetBSD: rpcent.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $ */ +/* $FreeBSD: releng/11.1/include/rpc/rpcent.h 296133 2016-02-26 23:25:21Z pfg $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +/* + * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. + */ + +/* + * rpcent.h, + * For converting rpc program numbers to names etc. + * + */ + +#ifndef _RPC_RPCENT_H +#define _RPC_RPCENT_H + +/* #pragma ident "@(#)rpcent.h 1.13 94/04/25 SMI" */ +/* @(#)rpcent.h 1.1 88/12/06 SMI */ + + +struct rpcent { + char *r_name; /* name of server for this rpc program */ + char **r_aliases; /* alias list */ + int r_number; /* rpc program number */ +}; + +__BEGIN_DECLS +/* + * These interfaces are currently implemented through nsswitch and are + * MT-safe. + */ +extern struct rpcent *getrpcbyname(const char *); +extern struct rpcent *getrpcbynumber(int); +extern struct rpcent *getrpcent(void); +extern void setrpcent(int); +extern void endrpcent(void); +__END_DECLS + +#endif /* !_RPC_CENT_H */ diff --git a/include/rpc/rpcsec_gss.h b/include/rpc/rpcsec_gss.h new file mode 100644 index 0000000..f73bd34 --- /dev/null +++ b/include/rpc/rpcsec_gss.h @@ -0,0 +1,179 @@ +/*- + * Copyright (c) 2008 Doug Rabson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/rpc/rpcsec_gss.h 240062 2012-09-02 22:23:23Z pfg $ + */ + +#ifndef _RPCSEC_GSS_H +#define _RPCSEC_GSS_H + +#include + +#ifndef MAX_GSS_MECH +#define MAX_GSS_MECH 64 +#endif + +/* + * Define the types of security service required for rpc_gss_seccreate(). + */ +typedef enum { + rpc_gss_svc_default = 0, + rpc_gss_svc_none = 1, + rpc_gss_svc_integrity = 2, + rpc_gss_svc_privacy = 3 +} rpc_gss_service_t; + +/* + * Structure containing options for rpc_gss_seccreate(). + */ +typedef struct { + int req_flags; /* GSS request bits */ + int time_req; /* requested credential lifetime */ + gss_cred_id_t my_cred; /* GSS credential */ + gss_channel_bindings_t input_channel_bindings; +} rpc_gss_options_req_t; + +/* + * Structure containing options returned by rpc_gss_seccreate(). + */ +typedef struct { + int major_status; + int minor_status; + u_int rpcsec_version; + int ret_flags; + int time_req; + gss_ctx_id_t gss_context; + char actual_mechanism[MAX_GSS_MECH]; +} rpc_gss_options_ret_t; + +/* + * Client principal type. Used as an argument to + * rpc_gss_get_principal_name(). Also referenced by the + * rpc_gss_rawcred_t structure. + */ +typedef struct { + int len; + char name[1]; +} *rpc_gss_principal_t; + +/* + * Structure for raw credentials used by rpc_gss_getcred() and + * rpc_gss_set_callback(). + */ +typedef struct { + u_int version; /* RPC version number */ + const char *mechanism; /* security mechanism */ + const char *qop; /* quality of protection */ + rpc_gss_principal_t client_principal; /* client name */ + const char *svc_principal; /* server name */ + rpc_gss_service_t service; /* service type */ +} rpc_gss_rawcred_t; + +/* + * Unix credentials derived from raw credentials. Returned by + * rpc_gss_getcred(). + */ +typedef struct { + uid_t uid; /* user ID */ + gid_t gid; /* group ID */ + short gidlen; + gid_t *gidlist; /* list of groups */ +} rpc_gss_ucred_t; + +/* + * Structure used to enforce a particular QOP and service. + */ +typedef struct { + bool_t locked; + rpc_gss_rawcred_t *raw_cred; +} rpc_gss_lock_t; + +/* + * Callback structure used by rpc_gss_set_callback(). + */ +typedef struct { + u_int program; /* RPC program number */ + u_int version; /* RPC version number */ + /* user defined callback */ + bool_t (*callback)(struct svc_req *req, + gss_cred_id_t deleg, + gss_ctx_id_t gss_context, + rpc_gss_lock_t *lock, + void **cookie); +} rpc_gss_callback_t; + +/* + * Structure used to return error information by rpc_gss_get_error() + */ +typedef struct { + int rpc_gss_error; + int system_error; /* same as errno */ +} rpc_gss_error_t; + +/* + * Values for rpc_gss_error + */ +#define RPC_GSS_ER_SUCCESS 0 /* no error */ +#define RPC_GSS_ER_SYSTEMERROR 1 /* system error */ + +__BEGIN_DECLS + +AUTH *rpc_gss_seccreate(CLIENT *clnt, const char *principal, + const char *mechanism, rpc_gss_service_t service, const char *qop, + rpc_gss_options_req_t *options_req, rpc_gss_options_ret_t *options_ret); +bool_t rpc_gss_set_defaults(AUTH *auth, rpc_gss_service_t service, + const char *qop); +int rpc_gss_max_data_length(AUTH *handle, int max_tp_unit_len); +void rpc_gss_get_error(rpc_gss_error_t *error); + +bool_t rpc_gss_mech_to_oid(const char *mech, gss_OID *oid_ret); +bool_t rpc_gss_oid_to_mech(gss_OID oid, const char **mech_ret); +bool_t rpc_gss_qop_to_num(const char *qop, const char *mech, u_int *num_ret); +const char **rpc_gss_get_mechanisms(void); +const char **rpc_gss_get_mech_info(const char *mech, rpc_gss_service_t *service); +bool_t rpc_gss_get_versions(u_int *vers_hi, u_int *vers_lo); +bool_t rpc_gss_is_installed(const char *mech); + +bool_t rpc_gss_set_svc_name(const char *principal, const char *mechanism, + u_int req_time, u_int program, u_int version); +bool_t rpc_gss_getcred(struct svc_req *req, rpc_gss_rawcred_t **rcred, + rpc_gss_ucred_t **ucred, void **cookie); +bool_t rpc_gss_set_callback(rpc_gss_callback_t *cb); +bool_t rpc_gss_get_principal_name(rpc_gss_principal_t *principal, + const char *mech, const char *name, const char *node, const char *domain); +int rpc_gss_svc_max_data_length(struct svc_req *req, int max_tp_unit_len); + +/* + * Internal interface from the RPC implementation. + */ +bool_t __rpc_gss_wrap(AUTH *auth, void *header, size_t headerlen, + XDR* xdrs, xdrproc_t xdr_args, void *args_ptr); +bool_t __rpc_gss_unwrap(AUTH *auth, XDR* xdrs, xdrproc_t xdr_args, + void *args_ptr); +bool_t __rpc_gss_set_error(int rpc_gss_error, int system_error); + +__END_DECLS + +#endif /* !_RPCSEC_GSS_H */ diff --git a/include/rpc/svc.h b/include/rpc/svc.h new file mode 100644 index 0000000..2bfd1b7 --- /dev/null +++ b/include/rpc/svc.h @@ -0,0 +1,474 @@ +/* $NetBSD: svc.h,v 1.17 2000/06/02 22:57:56 fvdl Exp $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * from: @(#)svc.h 1.35 88/12/17 SMI + * from: @(#)svc.h 1.27 94/04/25 SMI + * $FreeBSD: releng/11.1/include/rpc/svc.h 296349 2016-03-03 14:44:30Z pfg $ + */ + +/* + * svc.h, Server-side remote procedure call interface. + * + * Copyright (C) 1986-1993 by Sun Microsystems, Inc. + */ + +#ifndef _RPC_SVC_H +#define _RPC_SVC_H +#include + +/* + * This interface must manage two items concerning remote procedure calling: + * + * 1) An arbitrary number of transport connections upon which rpc requests + * are received. The two most notable transports are TCP and UDP; they are + * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; + * they in turn call xprt_register and xprt_unregister. + * + * 2) An arbitrary number of locally registered services. Services are + * described by the following four data: program number, version number, + * "service dispatch" function, a transport handle, and a boolean that + * indicates whether or not the exported program should be registered with a + * local binder service; if true the program's number and version and the + * port number from the transport handle are registered with the binder. + * These data are registered with the rpc svc system via svc_register. + * + * A service's dispatch function is called whenever an rpc request comes in + * on a transport. The request's program and version numbers must match + * those of the registered service. The dispatch function is passed two + * parameters, struct svc_req * and SVCXPRT *, defined below. + */ + +/* + * Service control requests + */ +#define SVCGET_VERSQUIET 1 +#define SVCSET_VERSQUIET 2 +#define SVCGET_CONNMAXREC 3 +#define SVCSET_CONNMAXREC 4 + +/* + * Operations for rpc_control(). + */ +#define RPC_SVC_CONNMAXREC_SET 0 /* set max rec size, enable nonblock */ +#define RPC_SVC_CONNMAXREC_GET 1 + +enum xprt_stat { + XPRT_DIED, + XPRT_MOREREQS, + XPRT_IDLE +}; + +/* + * Server side transport handle + */ +typedef struct __rpc_svcxprt { + int xp_fd; +#define xp_sock xp_fd + u_short xp_port; /* associated port number */ + const struct xp_ops { + /* receive incoming requests */ + bool_t (*xp_recv)(struct __rpc_svcxprt *, struct rpc_msg *); + /* get transport status */ + enum xprt_stat (*xp_stat)(struct __rpc_svcxprt *); + /* get arguments */ + bool_t (*xp_getargs)(struct __rpc_svcxprt *, xdrproc_t, + void *); + /* send reply */ + bool_t (*xp_reply)(struct __rpc_svcxprt *, struct rpc_msg *); + /* free mem allocated for args */ + bool_t (*xp_freeargs)(struct __rpc_svcxprt *, xdrproc_t, + void *); + /* destroy this struct */ + void (*xp_destroy)(struct __rpc_svcxprt *); + } *xp_ops; + int xp_addrlen; /* length of remote address */ + struct sockaddr_in xp_raddr; /* remote addr. (backward ABI compat) */ + /* XXX - fvdl stick this here for ABI backward compat reasons */ + const struct xp_ops2 { + /* catch-all function */ + bool_t (*xp_control)(struct __rpc_svcxprt *, const u_int, + void *); + } *xp_ops2; + char *xp_tp; /* transport provider device name */ + char *xp_netid; /* network token */ + struct netbuf xp_ltaddr; /* local transport address */ + struct netbuf xp_rtaddr; /* remote transport address */ + struct opaque_auth xp_verf; /* raw response verifier */ + void *xp_p1; /* private: for use by svc ops */ + void *xp_p2; /* private: for use by svc ops */ + void *xp_p3; /* private: for use by svc lib */ + int xp_type; /* transport type */ +} SVCXPRT; + +/* + * Interface to server-side authentication flavors. + */ +typedef struct __rpc_svcauth { + struct svc_auth_ops { + int (*svc_ah_wrap)(struct __rpc_svcauth *, XDR *, + xdrproc_t, caddr_t); + int (*svc_ah_unwrap)(struct __rpc_svcauth *, XDR *, + xdrproc_t, caddr_t); + } *svc_ah_ops; + void *svc_ah_private; +} SVCAUTH; + +/* + * Server transport extensions (accessed via xp_p3). + */ +typedef struct __rpc_svcxprt_ext { + int xp_flags; /* versquiet */ + SVCAUTH xp_auth; /* interface to auth methods */ +} SVCXPRT_EXT; + +/* + * Service request + */ +struct svc_req { + u_int32_t rq_prog; /* service program number */ + u_int32_t rq_vers; /* service protocol version */ + u_int32_t rq_proc; /* the desired procedure */ + struct opaque_auth rq_cred; /* raw creds from the wire */ + void *rq_clntcred; /* read only cooked cred */ + SVCXPRT *rq_xprt; /* associated transport */ +}; + +/* + * Approved way of getting address of caller + */ +#define svc_getrpccaller(x) (&(x)->xp_rtaddr) + +/* + * Operations defined on an SVCXPRT handle + * + * SVCXPRT *xprt; + * struct rpc_msg *msg; + * xdrproc_t xargs; + * void * argsp; + */ +#define SVC_RECV(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) +#define svc_recv(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) + +#define SVC_STAT(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) +#define svc_stat(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) + +#define SVC_GETARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) +#define svc_getargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) + +#define SVC_REPLY(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) +#define svc_reply(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) + +#define SVC_FREEARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) +#define svc_freeargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) + +#define SVC_DESTROY(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) +#define svc_destroy(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) + +#define SVC_CONTROL(xprt, rq, in) \ + (*(xprt)->xp_ops2->xp_control)((xprt), (rq), (in)) + +#define SVC_EXT(xprt) \ + ((SVCXPRT_EXT *) xprt->xp_p3) + +#define SVC_AUTH(xprt) \ + (SVC_EXT(xprt)->xp_auth) + +/* + * Operations defined on an SVCAUTH handle + */ +#define SVCAUTH_WRAP(auth, xdrs, xfunc, xwhere) \ + ((auth)->svc_ah_ops->svc_ah_wrap(auth, xdrs, xfunc, xwhere)) +#define SVCAUTH_UNWRAP(auth, xdrs, xfunc, xwhere) \ + ((auth)->svc_ah_ops->svc_ah_unwrap(auth, xdrs, xfunc, xwhere)) + +/* + * Service registration + * + * svc_reg(xprt, prog, vers, dispatch, nconf) + * const SVCXPRT *xprt; + * const rpcprog_t prog; + * const rpcvers_t vers; + * const void (*dispatch)(struct svc_req *, SVCXPRT *); + * const struct netconfig *nconf; + */ + +__BEGIN_DECLS +extern bool_t svc_reg(SVCXPRT *, const rpcprog_t, const rpcvers_t, + void (*)(struct svc_req *, SVCXPRT *), + const struct netconfig *); +__END_DECLS + +/* + * Service un-registration + * + * svc_unreg(prog, vers) + * const rpcprog_t prog; + * const rpcvers_t vers; + */ + +__BEGIN_DECLS +extern void svc_unreg(const rpcprog_t, const rpcvers_t); +__END_DECLS + +/* + * Transport registration. + * + * xprt_register(xprt) + * SVCXPRT *xprt; + */ +__BEGIN_DECLS +extern void xprt_register(SVCXPRT *); +__END_DECLS + +/* + * Transport un-register + * + * xprt_unregister(xprt) + * SVCXPRT *xprt; + */ +__BEGIN_DECLS +extern void xprt_unregister(SVCXPRT *); +__END_DECLS + + +/* + * When the service routine is called, it must first check to see if it + * knows about the procedure; if not, it should call svcerr_noproc + * and return. If so, it should deserialize its arguments via + * SVC_GETARGS (defined above). If the deserialization does not work, + * svcerr_decode should be called followed by a return. Successful + * decoding of the arguments should be followed the execution of the + * procedure's code and a call to svc_sendreply. + * + * Also, if the service refuses to execute the procedure due to too- + * weak authentication parameters, svcerr_weakauth should be called. + * Note: do not confuse access-control failure with weak authentication! + * + * NB: In pure implementations of rpc, the caller always waits for a reply + * msg. This message is sent when svc_sendreply is called. + * Therefore pure service implementations should always call + * svc_sendreply even if the function logically returns void; use + * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows + * for the abuse of pure rpc via batched calling or pipelining. In the + * case of a batched call, svc_sendreply should NOT be called since + * this would send a return message, which is what batching tries to avoid. + * It is the service/protocol writer's responsibility to know which calls are + * batched and which are not. Warning: responding to batch calls may + * deadlock the caller and server processes! + */ + +__BEGIN_DECLS +extern bool_t svc_sendreply(SVCXPRT *, xdrproc_t, void *); +extern void svcerr_decode(SVCXPRT *); +extern void svcerr_weakauth(SVCXPRT *); +extern void svcerr_noproc(SVCXPRT *); +extern void svcerr_progvers(SVCXPRT *, rpcvers_t, rpcvers_t); +extern void svcerr_auth(SVCXPRT *, enum auth_stat); +extern void svcerr_noprog(SVCXPRT *); +extern void svcerr_systemerr(SVCXPRT *); +extern int rpc_reg(rpcprog_t, rpcvers_t, rpcproc_t, + char *(*)(char *), xdrproc_t, xdrproc_t, + char *); +__END_DECLS + +/* + * Lowest level dispatching -OR- who owns this process anyway. + * Somebody has to wait for incoming requests and then call the correct + * service routine. The routine svc_run does infinite waiting; i.e., + * svc_run never returns. + * Since another (co-existent) package may wish to selectively wait for + * incoming calls or other events outside of the rpc architecture, the + * routine svc_getreq is provided. It must be passed readfds, the + * "in-place" results of a select system call (see select, section 2). + */ + +/* + * Global keeper of rpc service descriptors in use + * dynamic; must be inspected before each call to select + */ +extern int svc_maxfd; +#ifdef FD_SETSIZE +extern fd_set svc_fdset; +#define svc_fds svc_fdset.fds_bits[0] /* compatibility */ +#else +extern int svc_fds; +#endif /* def FD_SETSIZE */ + +/* + * A set of null auth methods used by any authentication protocols + * that don't need to inspect or modify the message body. + */ +extern SVCAUTH _svc_auth_null; + +/* + * a small program implemented by the svc_rpc implementation itself; + * also see clnt.h for protocol numbers. + */ +__BEGIN_DECLS +extern void rpctest_service(void); +__END_DECLS + +__BEGIN_DECLS +extern SVCXPRT *svc_xprt_alloc(void); +extern void svc_xprt_free(SVCXPRT *); +extern void svc_getreq(int); +extern void svc_getreqset(fd_set *); +extern void svc_getreq_common(int); +struct pollfd; +extern void svc_getreq_poll(struct pollfd *, int); + +extern void svc_run(void); +extern void svc_exit(void); +__END_DECLS + +/* + * Socket to use on svcxxx_create call to get default socket + */ +#define RPC_ANYSOCK -1 +#define RPC_ANYFD RPC_ANYSOCK + +/* + * These are the existing service side transport implementations + */ + +__BEGIN_DECLS +/* + * Transport independent svc_create routine. + */ +extern int svc_create(void (*)(struct svc_req *, SVCXPRT *), + const rpcprog_t, const rpcvers_t, const char *); +/* + * void (*dispatch)(struct svc_req *, SVCXPRT *); + * const rpcprog_t prognum; -- program number + * const rpcvers_t versnum; -- version number + * const char *nettype; -- network type + */ + + +/* + * Generic server creation routine. It takes a netconfig structure + * instead of a nettype. + */ + +extern SVCXPRT *svc_tp_create(void (*)(struct svc_req *, SVCXPRT *), + const rpcprog_t, const rpcvers_t, + const struct netconfig *); + /* + * void (*dispatch)(struct svc_req *, SVCXPRT *); + * const rpcprog_t prognum; -- program number + * const rpcvers_t versnum; -- version number + * const struct netconfig *nconf; -- netconfig structure + */ + + +/* + * Generic TLI create routine + */ +extern SVCXPRT *svc_tli_create(const int, const struct netconfig *, + const struct t_bind *, const u_int, + const u_int); +/* + * const int fd; -- connection end point + * const struct netconfig *nconf; -- netconfig structure for network + * const struct t_bind *bindaddr; -- local bind address + * const u_int sendsz; -- max sendsize + * const u_int recvsz; -- max recvsize + */ + +/* + * Connectionless and connectionful create routines + */ + +extern SVCXPRT *svc_vc_create(const int, const u_int, const u_int); +/* + * const int fd; -- open connection end point + * const u_int sendsize; -- max send size + * const u_int recvsize; -- max recv size + */ + +/* + * Added for compatibility to old rpc 4.0. Obsoleted by svc_vc_create(). + */ +extern SVCXPRT *svcunix_create(int, u_int, u_int, char *); + +extern SVCXPRT *svc_dg_create(const int, const u_int, const u_int); + /* + * const int fd; -- open connection + * const u_int sendsize; -- max send size + * const u_int recvsize; -- max recv size + */ + + +/* + * the routine takes any *open* connection + * descriptor as its first input and is used for open connections. + */ +extern SVCXPRT *svc_fd_create(const int, const u_int, const u_int); +/* + * const int fd; -- open connection end point + * const u_int sendsize; -- max send size + * const u_int recvsize; -- max recv size + */ + +/* + * Added for compatibility to old rpc 4.0. Obsoleted by svc_fd_create(). + */ +extern SVCXPRT *svcunixfd_create(int, u_int, u_int); + +/* + * Memory based rpc (for speed check and testing) + */ +extern SVCXPRT *svc_raw_create(void); + +/* + * svc_dg_enable_cache() enables the cache on dg transports. + */ +int svc_dg_enablecache(SVCXPRT *, const u_int); + +int __rpc_get_local_uid(SVCXPRT *_transp, uid_t *_uid); + +__END_DECLS + + +/* for backward compatibility */ +#include + +#endif /* !_RPC_SVC_H */ diff --git a/include/rpc/svc_auth.h b/include/rpc/svc_auth.h new file mode 100644 index 0000000..ef68257 --- /dev/null +++ b/include/rpc/svc_auth.h @@ -0,0 +1,56 @@ +/* $NetBSD: svc_auth.h,v 1.8 2000/06/02 22:57:57 fvdl Exp $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * from: @(#)svc_auth.h 1.6 86/07/16 SMI + * @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC + * $FreeBSD: releng/11.1/include/rpc/svc_auth.h 258578 2013-11-25 19:04:36Z hrs $ + */ + +/* + * svc_auth.h, Service side of rpc authentication. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_SVC_AUTH_H +#define _RPC_SVC_AUTH_H + +/* + * Server side authenticator + */ +__BEGIN_DECLS +extern struct svc_auth_ops svc_auth_null_ops; + +extern enum auth_stat _authenticate(struct svc_req *, struct rpc_msg *); +extern int svc_auth_reg(int, enum auth_stat (*)(struct svc_req *, + struct rpc_msg *)); + +__END_DECLS + +#endif /* !_RPC_SVC_AUTH_H */ diff --git a/include/rpc/svc_dg.h b/include/rpc/svc_dg.h new file mode 100644 index 0000000..0287c03 --- /dev/null +++ b/include/rpc/svc_dg.h @@ -0,0 +1,50 @@ +/* $NetBSD: svc_dg.h,v 1.1 2000/06/02 23:11:16 fvdl Exp $ */ +/* $FreeBSD: releng/11.1/include/rpc/svc_dg.h 258578 2013-11-25 19:04:36Z hrs $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +/* + * XXX - this file exists only so that the rpcbind code can pull it in. + * This should go away. It should only be include by svc_dg.c and + * rpcb_svc_com.c in the rpcbind code. + */ + +/* + * kept in xprt->xp_p2 + */ +struct svc_dg_data { + /* XXX: optbuf should be the first field, used by ti_opts.c code */ + size_t su_iosz; /* size of send.recv buffer */ + u_int32_t su_xid; /* transaction id */ + XDR su_xdrs; /* XDR handle */ + char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ + void *su_cache; /* cached data, NULL if none */ + struct netbuf su_srcaddr; /* dst address of last msg */ +}; + +#define __rpcb_get_dg_xidp(x) (&((struct svc_dg_data *)(x)->xp_p2)->su_xid) diff --git a/include/rpc/svc_soc.h b/include/rpc/svc_soc.h new file mode 100644 index 0000000..babf56b --- /dev/null +++ b/include/rpc/svc_soc.h @@ -0,0 +1,115 @@ +/* $NetBSD: svc_soc.h,v 1.1 2000/06/02 22:57:57 fvdl Exp $ */ +/* $FreeBSD: releng/11.1/include/rpc/svc_soc.h 258578 2013-11-25 19:04:36Z hrs $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + */ +/* + * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. + */ + +/* + * svc.h, Server-side remote procedure call interface. + */ + +#ifndef _RPC_SVC_SOC_H +#define _RPC_SVC_SOC_H +#include + +/* #pragma ident "@(#)svc_soc.h 1.11 94/04/25 SMI" */ +/* svc_soc.h 1.8 89/05/01 SMI */ + +/* + * All the following declarations are only for backward compatibility + * with TS-RPC + */ + +/* + * Approved way of getting address of caller + */ +#define svc_getcaller(x) (&(x)->xp_raddr) + +/* + * Service registration + * + * svc_register(xprt, prog, vers, dispatch, protocol) + * SVCXPRT *xprt; + * u_long prog; + * u_long vers; + * void (*dispatch)(); + * int protocol; like TCP or UDP, zero means do not register + */ +__BEGIN_DECLS +extern bool_t svc_register(SVCXPRT *, u_long, u_long, + void (*)(struct svc_req *, SVCXPRT *), int); +__END_DECLS + +/* + * Service un-registration + * + * svc_unregister(prog, vers) + * u_long prog; + * u_long vers; + */ +__BEGIN_DECLS +extern void svc_unregister(u_long, u_long); +__END_DECLS + + +/* + * Memory based rpc for testing and timing. + */ +__BEGIN_DECLS +extern SVCXPRT *svcraw_create(void); +__END_DECLS + + +/* + * Udp based rpc. + */ +__BEGIN_DECLS +extern SVCXPRT *svcudp_create(int); +extern SVCXPRT *svcudp_bufcreate(int, u_int, u_int); +extern int svcudp_enablecache(SVCXPRT *, u_long); +__END_DECLS + + +/* + * Tcp based rpc. + */ +__BEGIN_DECLS +extern SVCXPRT *svctcp_create(int, u_int, u_int); +__END_DECLS + +/* + * Fd based rpc. + */ +__BEGIN_DECLS +extern SVCXPRT *svcfd_create(int, u_int, u_int); +__END_DECLS + +#endif /* !_RPC_SVC_SOC_H */ diff --git a/include/rpc/xdr.h b/include/rpc/xdr.h new file mode 100644 index 0000000..54bc85e --- /dev/null +++ b/include/rpc/xdr.h @@ -0,0 +1,364 @@ +/* $NetBSD: xdr.h,v 1.19 2000/07/17 05:00:45 matt Exp $ */ + +/*- + * Copyright (c) 2009, Sun Microsystems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Sun Microsystems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. + * + * from: @(#)xdr.h 1.19 87/04/22 SMI + * from: @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC + * $FreeBSD: releng/11.1/include/rpc/xdr.h 296394 2016-03-04 22:03:38Z pfg $ + */ + +/* + * xdr.h, External Data Representation Serialization Routines. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_XDR_H +#define _RPC_XDR_H +#include + +/* + * XDR provides a conventional way for converting between C data + * types and an external bit-string representation. Library supplied + * routines provide for the conversion on built-in C data types. These + * routines and utility routines defined here are used to help implement + * a type encode/decode routine for each user-defined type. + * + * Each data type provides a single procedure which takes two arguments: + * + * bool_t + * xdrproc(xdrs, argresp) + * XDR *xdrs; + * *argresp; + * + * xdrs is an instance of a XDR handle, to which or from which the data + * type is to be converted. argresp is a pointer to the structure to be + * converted. The XDR handle contains an operation field which indicates + * which of the operations (ENCODE, DECODE * or FREE) is to be performed. + * + * XDR_DECODE may allocate space if the pointer argresp is null. This + * data can be freed with the XDR_FREE operation. + * + * We write only one procedure per data type to make it easy + * to keep the encode and decode procedures for a data type consistent. + * In many cases the same code performs all operations on a user defined type, + * because all the hard work is done in the component type routines. + * decode as a series of calls on the nested data types. + */ + +/* + * Xdr operations. XDR_ENCODE causes the type to be encoded into the + * stream. XDR_DECODE causes the type to be extracted from the stream. + * XDR_FREE can be used to release the space allocated by an XDR_DECODE + * request. + */ +enum xdr_op { + XDR_ENCODE=0, + XDR_DECODE=1, + XDR_FREE=2 +}; + +/* + * This is the number of bytes per unit of external data. + */ +#define BYTES_PER_XDR_UNIT (4) +#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \ + * BYTES_PER_XDR_UNIT) + +/* + * The XDR handle. + * Contains operation which is being applied to the stream, + * an operations vector for the particular implementation (e.g. see xdr_mem.c), + * and two private fields for the use of the particular implementation. + */ +typedef struct XDR { + enum xdr_op x_op; /* operation; fast additional param */ + const struct xdr_ops { + /* get a long from underlying stream */ + bool_t (*x_getlong)(struct XDR *, long *); + /* put a long to " */ + bool_t (*x_putlong)(struct XDR *, const long *); + /* get some bytes from " */ + bool_t (*x_getbytes)(struct XDR *, char *, u_int); + /* put some bytes to " */ + bool_t (*x_putbytes)(struct XDR *, const char *, u_int); + /* returns bytes off from beginning */ + u_int (*x_getpostn)(struct XDR *); + /* lets you reposition the stream */ + bool_t (*x_setpostn)(struct XDR *, u_int); + /* buf quick ptr to buffered data */ + int32_t *(*x_inline)(struct XDR *, u_int); + /* free privates of this xdr_stream */ + void (*x_destroy)(struct XDR *); + bool_t (*x_control)(struct XDR *, int, void *); + } *x_ops; + char * x_public; /* users' data */ + void * x_private; /* pointer to private data */ + char * x_base; /* private used for position info */ + u_int x_handy; /* extra private word */ +} XDR; + +/* + * A xdrproc_t exists for each data type which is to be encoded or decoded. + * + * The second argument to the xdrproc_t is a pointer to an opaque pointer. + * The opaque pointer generally points to a structure of the data type + * to be decoded. If this pointer is 0, then the type routines should + * allocate dynamic storage of the appropriate size and return it. + */ +#ifdef _KERNEL +typedef bool_t (*xdrproc_t)(XDR *, void *, u_int); +#else +/* + * XXX can't actually prototype it, because some take three args!!! + */ +typedef bool_t (*xdrproc_t)(XDR *, ...); +#endif + +/* + * Operations defined on a XDR handle + * + * XDR *xdrs; + * long *longp; + * char * addr; + * u_int len; + * u_int pos; + */ +#define XDR_GETLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) +#define xdr_getlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) + +#define XDR_PUTLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) +#define xdr_putlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) + +static __inline int +xdr_getint32(XDR *xdrs, int32_t *ip) +{ + long l; + + if (!xdr_getlong(xdrs, &l)) + return (FALSE); + *ip = (int32_t)l; + return (TRUE); +} + +static __inline int +xdr_putint32(XDR *xdrs, int32_t *ip) +{ + long l; + + l = (long)*ip; + return xdr_putlong(xdrs, &l); +} + +#define XDR_GETINT32(xdrs, int32p) xdr_getint32(xdrs, int32p) +#define XDR_PUTINT32(xdrs, int32p) xdr_putint32(xdrs, int32p) + +#define XDR_GETBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) +#define xdr_getbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) + +#define XDR_PUTBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) +#define xdr_putbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) + +#define XDR_GETPOS(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) +#define xdr_getpos(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) + +#define XDR_SETPOS(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) +#define xdr_setpos(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) + +#define XDR_INLINE(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) +#define xdr_inline(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) + +#define XDR_DESTROY(xdrs) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) +#define xdr_destroy(xdrs) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) + +#define XDR_CONTROL(xdrs, req, op) \ + if ((xdrs)->x_ops->x_control) \ + (*(xdrs)->x_ops->x_control)(xdrs, req, op) +#define xdr_control(xdrs, req, op) XDR_CONTROL(xdrs, req, op) + +#define xdr_rpcvers(xdrs, versp) xdr_u_int32_t(xdrs, versp) +#define xdr_rpcprog(xdrs, progp) xdr_u_int32_t(xdrs, progp) +#define xdr_rpcproc(xdrs, procp) xdr_u_int32_t(xdrs, procp) +#define xdr_rpcprot(xdrs, protp) xdr_u_int32_t(xdrs, protp) +#define xdr_rpcport(xdrs, portp) xdr_u_int32_t(xdrs, portp) + +/* + * Support struct for discriminated unions. + * You create an array of xdrdiscrim structures, terminated with + * an entry with a null procedure pointer. The xdr_union routine gets + * the discriminant value and then searches the array of structures + * for a matching value. If a match is found the associated xdr routine + * is called to handle that part of the union. If there is + * no match, then a default routine may be called. + * If there is no match and no default routine it is an error. + */ +#define NULL_xdrproc_t ((xdrproc_t)0) +struct xdr_discrim { + int value; + xdrproc_t proc; +}; + +/* + * In-line routines for fast encode/decode of primitive data types. + * Caveat emptor: these use single memory cycles to get the + * data from the underlying buffer, and will fail to operate + * properly if the data is not aligned. The standard way to use these + * is to say: + * if ((buf = XDR_INLINE(xdrs, count)) == NULL) + * return (FALSE); + * <<< macro calls >>> + * where ``count'' is the number of bytes of data occupied + * by the primitive data types. + * + * N.B. and frozen for all time: each data type here uses 4 bytes + * of external representation. + */ +#define IXDR_GET_INT32(buf) ((int32_t)__ntohl((u_int32_t)*(buf)++)) +#define IXDR_PUT_INT32(buf, v) (*(buf)++ =(int32_t)__htonl((u_int32_t)v)) +#define IXDR_GET_U_INT32(buf) ((u_int32_t)IXDR_GET_INT32(buf)) +#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_INT32((buf), ((int32_t)(v))) + +#define IXDR_GET_LONG(buf) ((long)__ntohl((u_int32_t)*(buf)++)) +#define IXDR_PUT_LONG(buf, v) (*(buf)++ =(int32_t)__htonl((u_int32_t)v)) + +#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) +#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf)) +#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf)) + +#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), (v)) +#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), (v)) +#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), (v)) +#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), (v)) +#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), (v)) + +/* + * These are the "generic" xdr routines. + */ +__BEGIN_DECLS +extern bool_t xdr_void(void); +extern bool_t xdr_int(XDR *, int *); +extern bool_t xdr_u_int(XDR *, u_int *); +extern bool_t xdr_long(XDR *, long *); +extern bool_t xdr_u_long(XDR *, u_long *); +extern bool_t xdr_short(XDR *, short *); +extern bool_t xdr_u_short(XDR *, u_short *); +extern bool_t xdr_int16_t(XDR *, int16_t *); +extern bool_t xdr_u_int16_t(XDR *, u_int16_t *); +extern bool_t xdr_uint16_t(XDR *, u_int16_t *); +extern bool_t xdr_int32_t(XDR *, int32_t *); +extern bool_t xdr_u_int32_t(XDR *, u_int32_t *); +extern bool_t xdr_uint32_t(XDR *, u_int32_t *); +extern bool_t xdr_int64_t(XDR *, int64_t *); +extern bool_t xdr_u_int64_t(XDR *, u_int64_t *); +extern bool_t xdr_uint64_t(XDR *, u_int64_t *); +extern bool_t xdr_bool(XDR *, bool_t *); +extern bool_t xdr_enum(XDR *, enum_t *); +extern bool_t xdr_array(XDR *, char **, u_int *, u_int, u_int, xdrproc_t); +extern bool_t xdr_bytes(XDR *, char **, u_int *, u_int); +extern bool_t xdr_opaque(XDR *, char *, u_int); +extern bool_t xdr_string(XDR *, char **, u_int); +extern bool_t xdr_union(XDR *, enum_t *, char *, const struct xdr_discrim *, xdrproc_t); +extern bool_t xdr_char(XDR *, char *); +extern bool_t xdr_u_char(XDR *, u_char *); +extern bool_t xdr_vector(XDR *, char *, u_int, u_int, xdrproc_t); +extern bool_t xdr_float(XDR *, float *); +extern bool_t xdr_double(XDR *, double *); +extern bool_t xdr_quadruple(XDR *, long double *); +extern bool_t xdr_reference(XDR *, char **, u_int, xdrproc_t); +extern bool_t xdr_pointer(XDR *, char **, u_int, xdrproc_t); +extern bool_t xdr_wrapstring(XDR *, char **); +extern void xdr_free(xdrproc_t, void *); +extern bool_t xdr_hyper(XDR *, quad_t *); +extern bool_t xdr_u_hyper(XDR *, u_quad_t *); +extern bool_t xdr_longlong_t(XDR *, quad_t *); +extern bool_t xdr_u_longlong_t(XDR *, u_quad_t *); +extern unsigned long xdr_sizeof(xdrproc_t, void *); +__END_DECLS + +/* + * Common opaque bytes objects used by many rpc protocols; + * declared here due to commonality. + */ +#define MAX_NETOBJ_SZ 1024 +struct netobj { + u_int n_len; + char *n_bytes; +}; +typedef struct netobj netobj; +extern bool_t xdr_netobj(XDR *, struct netobj *); + +/* + * These are the public routines for the various implementations of + * xdr streams. + */ +__BEGIN_DECLS +/* XDR using memory buffers */ +extern void xdrmem_create(XDR *, char *, u_int, enum xdr_op); + +/* XDR using stdio library */ +#ifdef _STDIO_H_ +extern void xdrstdio_create(XDR *, FILE *, enum xdr_op); +#endif + +/* XDR pseudo records for tcp */ +extern void xdrrec_create(XDR *, u_int, u_int, void *, + int (*)(void *, void *, int), + int (*)(void *, void *, int)); + +/* make end of xdr record */ +extern bool_t xdrrec_endofrecord(XDR *, int); + +/* move to beginning of next record */ +extern bool_t xdrrec_skiprecord(XDR *); + +/* true if no more input */ +extern bool_t xdrrec_eof(XDR *); +extern u_int xdrrec_readbytes(XDR *, caddr_t, u_int); +__END_DECLS + +#endif /* !_RPC_XDR_H */ diff --git a/include/rpcsvc/Makefile b/include/rpcsvc/Makefile new file mode 100644 index 0000000..0af728a --- /dev/null +++ b/include/rpcsvc/Makefile @@ -0,0 +1,31 @@ +# from: @(#)Makefile 2.3 88/08/11 4.0 RPCSRC +# $FreeBSD: releng/11.1/include/rpcsvc/Makefile 231118 2012-02-07 09:27:07Z dim $ + +.SUFFIXES: .x + +RPCCOM= RPCGEN_CPP=${CPP:Q} rpcgen -C + +HDRS= key_prot.h klm_prot.h mount.h nfs_prot.h nlm_prot.h rex.h rnusers.h \ + rquota.h rstat.h rwall.h sm_inter.h spray.h yppasswd.h yp.h \ + ypxfrd.h ypupdate_prot.h nis.h nis_cache.h nis_callback.h \ + bootparam_prot.h crypt.h +XFILES= bootparam_prot.x key_prot.x klm_prot.x mount.x nfs_prot.x nlm_prot.x \ + rex.x rnusers.x rquota.x rstat.x rwall.x sm_inter.x spray.x \ + yppasswd.x yp.x ypxfrd.x ypupdate_prot.x nis.x nis_cache.x nis_object.x \ + nis_callback.x crypt.x +HFILES= yp_prot.h ypclnt.h nis_db.h nis_tags.h nislib.h + +CLEANFILES+= ${HDRS} + +INCSGROUPS= INCS RPCHDRS +INCS= ${HFILES} ${XFILES} ${HDRS} +INCSDIR= ${INCLUDEDIR}/rpcsvc +RPCHDRS= key_prot.h +RPCHDRSDIR= ${INCLUDEDIR}/rpc + +.x.h: + ${RPCCOM} -h -DWANT_NFS3 ${.IMPSRC} -o ${.TARGET} + +nis.h: nis_object.x + +.include diff --git a/include/rpcsvc/Makefile.depend b/include/rpcsvc/Makefile.depend new file mode 100644 index 0000000..25bc110 --- /dev/null +++ b/include/rpcsvc/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD: releng/11.1/include/rpcsvc/Makefile.depend 284345 2015-06-13 19:20:56Z sjg $ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/include/rpcsvc/bootparam_prot.x b/include/rpcsvc/bootparam_prot.x new file mode 100644 index 0000000..f193178 --- /dev/null +++ b/include/rpcsvc/bootparam_prot.x @@ -0,0 +1,104 @@ +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/* + * RPC for bootparms service. + * There are two procedures: + * WHOAMI takes a net address and returns a client name and also a + * likely net address for routing + * GETFILE takes a client name and file identifier and returns the + * server name, server net address and pathname for the file. + * file identifiers typically include root, swap, pub and dump + */ + +#ifdef RPC_HDR +%#include +%#include +%#include +%#include +%#include +#else +%#ifndef lint +%/*static char sccsid[] = "from: @(#)bootparam_prot.x 1.2 87/06/24 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)bootparam_prot.x 2.1 88/08/01 4.0 RPCSRC";*/ +%#endif /* not lint */ +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/bootparam_prot.x 259117 2013-12-09 04:26:50Z hrs $"); +#endif + +const MAX_MACHINE_NAME = 255; +const MAX_PATH_LEN = 1024; +const MAX_FILEID = 32; +const IP_ADDR_TYPE = 1; + +typedef string bp_machine_name_t; +typedef string bp_path_t; +typedef string bp_fileid_t; + +struct ip_addr_t { + char net; + char host; + char lh; + char impno; +}; + +union bp_address switch (int address_type) { + case IP_ADDR_TYPE: + ip_addr_t ip_addr; +}; + +struct bp_whoami_arg { + bp_address client_address; +}; + +struct bp_whoami_res { + bp_machine_name_t client_name; + bp_machine_name_t domain_name; + bp_address router_address; +}; + +struct bp_getfile_arg { + bp_machine_name_t client_name; + bp_fileid_t file_id; +}; + +struct bp_getfile_res { + bp_machine_name_t server_name; + bp_address server_address; + bp_path_t server_path; +}; + +program BOOTPARAMPROG { + version BOOTPARAMVERS { + bp_whoami_res BOOTPARAMPROC_WHOAMI(bp_whoami_arg) = 1; + bp_getfile_res BOOTPARAMPROC_GETFILE(bp_getfile_arg) = 2; + } = 1; +} = 100026; diff --git a/include/rpcsvc/crypt.x b/include/rpcsvc/crypt.x new file mode 100644 index 0000000..0266924 --- /dev/null +++ b/include/rpcsvc/crypt.x @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1996 + * Bill Paul . 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 Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul 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. + */ + +#ifndef RPC_HDR +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/crypt.x 114629 2003-05-04 02:51:42Z obrien $"); +#endif + +/* + * This protocol definition exists because of the U.S. government and + * its stupid export laws. We can't export DES code from the United + * States to other countries (even though the code already exists + * outside the U.S. -- go figure that one out) but we need to make + * Secure RPC work. The normal way around this is to break the DES + * code out into a shared library; we can then provide a dummy lib + * in the base OS and provide the real lib in the secure dist, which + * the user can install later. But we need Secure RPC for NIS+, and + * there are several system programs that use NIS+ which are statically + * linked. We would have to provide replacements for these programs + * in the secure dist, but there are a lot, and this is a pain. The + * shared lib trick won't work for these programs, and we can't change + * them once they're compiled. + * + * One solution for this problem is to do the DES encryption as a system + * call; no programs need to be changed and we can even supply the DES + * support as an LKM. But this bloats the kernel. Maybe if we have + * Secure NFS one day this will be worth it, but for now we should keep + * this mess in user space. + * + * So we have this second solution: we provide a server that does the + * DES encryption for us. In this case, the server is keyserv (we need + * it to make Secure RPC work anyway) and we use this protocol to ship + * the data back and forth between keyserv and the application. + */ + +enum des_dir { ENCRYPT_DES, DECRYPT_DES }; +enum des_mode { CBC_DES, ECB_DES }; + +struct desargs { + u_char des_key[8]; /* key (with low bit parity) */ + des_dir des_dir; /* direction */ + des_mode des_mode; /* mode */ + u_char des_ivec[8]; /* input vector */ + opaque desbuf<>; +}; + +struct desresp { + opaque desbuf<>; + u_char des_ivec[8]; + int stat; +}; + +program CRYPT_PROG { + version CRYPT_VERS { + desresp + DES_CRYPT(desargs) = 1; + } = 1; +} = 600100029; diff --git a/include/rpcsvc/key_prot.x b/include/rpcsvc/key_prot.x new file mode 100644 index 0000000..66975d1 --- /dev/null +++ b/include/rpcsvc/key_prot.x @@ -0,0 +1,287 @@ +%/*- +% * Copyright (c) 2010, Oracle America, Inc. +% * +% * Redistribution and use in source and binary forms, with or without +% * modification, are permitted provided that the following conditions are +% * met: +% * +% * * Redistributions of source code must retain the above copyright +% * notice, this list of conditions and the following disclaimer. +% * * 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. +% * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 +% * COPYRIGHT HOLDER 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. +% */ +/* + * Key server protocol definition + * Copyright (C) 1990, 1991 Sun Microsystems, Inc. + * + * The keyserver is a public key storage/encryption/decryption service + * The encryption method used is based on the Diffie-Hellman exponential + * key exchange technology. + * + * The key server is local to each machine, akin to the portmapper. + * Under TI-RPC, communication with the keyserver is through the + * loopback transport. + * + * NOTE: This .x file generates the USER level headers for the keyserver. + * the KERNEL level headers are created by hand as they kernel has special + * requirements. + */ + +%/* From: #pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI" */ +%/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */ +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/key_prot.x 259117 2013-12-09 04:26:50Z hrs $"); +% +%/* +% * Compiled from key_prot.x using rpcgen. +% * DO NOT EDIT THIS FILE! +% * This is NOT source code! +% */ + +/* + * PROOT and MODULUS define the way the Diffie-Hellman key is generated. + * + * MODULUS should be chosen as a prime of the form: MODULUS == 2*p + 1, + * where p is also prime. + * + * PROOT satisfies the following two conditions: + * (1) (PROOT ** 2) % MODULUS != 1 + * (2) (PROOT ** p) % MODULUS != 1 + * + */ + +const PROOT = 3; +const HEXMODULUS = "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"; + +const HEXKEYBYTES = 48; /* HEXKEYBYTES == strlen(HEXMODULUS) */ +const KEYSIZE = 192; /* KEYSIZE == bit length of key */ +const KEYBYTES = 24; /* byte length of key */ + +/* + * The first 16 hex digits of the encrypted secret key are used as + * a checksum in the database. + */ +const KEYCHECKSUMSIZE = 16; + +/* + * status of operation + */ +enum keystatus { + KEY_SUCCESS, /* no problems */ + KEY_NOSECRET, /* no secret key stored */ + KEY_UNKNOWN, /* unknown netname */ + KEY_SYSTEMERR /* system error (out of memory, encryption failure) */ +}; + +typedef opaque keybuf[HEXKEYBYTES]; /* store key in hex */ + +typedef string netnamestr; + +/* + * Argument to ENCRYPT or DECRYPT + */ +struct cryptkeyarg { + netnamestr remotename; + des_block deskey; +}; + +/* + * Argument to ENCRYPT_PK or DECRYPT_PK + */ +struct cryptkeyarg2 { + netnamestr remotename; + netobj remotekey; /* Contains a length up to 1024 bytes */ + des_block deskey; +}; + + +/* + * Result of ENCRYPT, DECRYPT, ENCRYPT_PK, and DECRYPT_PK + */ +union cryptkeyres switch (keystatus status) { +case KEY_SUCCESS: + des_block deskey; +default: + void; +}; + +const MAXGIDS = 16; /* max number of gids in gid list */ + +/* + * Unix credential + */ +struct unixcred { + u_int uid; + u_int gid; + u_int gids; +}; + +/* + * Result returned from GETCRED + */ +union getcredres switch (keystatus status) { +case KEY_SUCCESS: + unixcred cred; +default: + void; +}; +/* + * key_netstarg; + */ + +struct key_netstarg { + keybuf st_priv_key; + keybuf st_pub_key; + netnamestr st_netname; +}; + +union key_netstres switch (keystatus status){ +case KEY_SUCCESS: + key_netstarg knet; +default: + void; +}; + +#ifdef RPC_HDR +% +%#ifndef opaque +%#define opaque char +%#endif +% +#endif +program KEY_PROG { + version KEY_VERS { + + /* + * This is my secret key. + * Store it for me. + */ + keystatus + KEY_SET(keybuf) = 1; + + /* + * I want to talk to X. + * Encrypt a conversation key for me. + */ + cryptkeyres + KEY_ENCRYPT(cryptkeyarg) = 2; + + /* + * X just sent me a message. + * Decrypt the conversation key for me. + */ + cryptkeyres + KEY_DECRYPT(cryptkeyarg) = 3; + + /* + * Generate a secure conversation key for me + */ + des_block + KEY_GEN(void) = 4; + + /* + * Get me the uid, gid and group-access-list associated + * with this netname (for kernel which cannot use NIS) + */ + getcredres + KEY_GETCRED(netnamestr) = 5; + } = 1; + version KEY_VERS2 { + + /* + * ####### + * Procedures 1-5 are identical to version 1 + * ####### + */ + + /* + * This is my secret key. + * Store it for me. + */ + keystatus + KEY_SET(keybuf) = 1; + + /* + * I want to talk to X. + * Encrypt a conversation key for me. + */ + cryptkeyres + KEY_ENCRYPT(cryptkeyarg) = 2; + + /* + * X just sent me a message. + * Decrypt the conversation key for me. + */ + cryptkeyres + KEY_DECRYPT(cryptkeyarg) = 3; + + /* + * Generate a secure conversation key for me + */ + des_block + KEY_GEN(void) = 4; + + /* + * Get me the uid, gid and group-access-list associated + * with this netname (for kernel which cannot use NIS) + */ + getcredres + KEY_GETCRED(netnamestr) = 5; + + /* + * I want to talk to X. and I know X's public key + * Encrypt a conversation key for me. + */ + cryptkeyres + KEY_ENCRYPT_PK(cryptkeyarg2) = 6; + + /* + * X just sent me a message. and I know X's public key + * Decrypt the conversation key for me. + */ + cryptkeyres + KEY_DECRYPT_PK(cryptkeyarg2) = 7; + + /* + * Store my public key, netname and private key. + */ + keystatus + KEY_NET_PUT(key_netstarg) = 8; + + /* + * Retrieve my public key, netname and private key. + */ + key_netstres + KEY_NET_GET(void) = 9; + + /* + * Return me the conversation key that is constructed + * from my secret key and this publickey. + */ + + cryptkeyres + KEY_GET_CONV(keybuf) = 10; + + + } = 2; +} = 100029; + + diff --git a/include/rpcsvc/klm_prot.x b/include/rpcsvc/klm_prot.x new file mode 100644 index 0000000..389f450 --- /dev/null +++ b/include/rpcsvc/klm_prot.x @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/* + * Kernel/lock manager protocol definition + * Copyright (C) 1986 Sun Microsystems, Inc. + * + * protocol used between the UNIX kernel (the "client") and the + * local lock manager. The local lock manager is a daemon running + * above the kernel. + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)klm_prot.x 1.7 87/07/08 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)klm_prot.x 2.1 88/08/01 4.0 RPCSRC";*/ +%#endif /* not lint */ +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/klm_prot.x 298849 2016-04-30 14:43:42Z pfg $"); +#endif + +const LM_MAXSTRLEN = 1024; + +/* + * lock manager status returns + */ +enum klm_stats { + klm_granted = 0, /* lock is granted */ + klm_denied = 1, /* lock is denied */ + klm_denied_nolocks = 2, /* no lock entry available */ + klm_working = 3 /* lock is being processed */ +}; + +/* + * lock manager lock identifier + */ +struct klm_lock { + string server_name; + netobj fh; /* a counted file handle */ + int pid; /* holder of the lock */ + unsigned l_offset; /* beginning offset of the lock */ + unsigned l_len; /* byte length of the lock; + * zero means through end of file */ +}; + +/* + * lock holder identifier + */ +struct klm_holder { + bool exclusive; /* FALSE if shared lock */ + int svid; /* holder of the lock (pid) */ + unsigned l_offset; /* beginning offset of the lock */ + unsigned l_len; /* byte length of the lock; + * zero means through end of file */ +}; + +/* + * reply to KLM_LOCK / KLM_UNLOCK / KLM_CANCEL + */ +struct klm_stat { + klm_stats stat; +}; + +/* + * reply to a KLM_TEST call + */ +union klm_testrply switch (klm_stats stat) { + case klm_denied: + struct klm_holder holder; + default: /* All other cases return no arguments */ + void; +}; + + +/* + * arguments to KLM_LOCK + */ +struct klm_lockargs { + bool block; + bool exclusive; + struct klm_lock alock; +}; + +/* + * arguments to KLM_TEST + */ +struct klm_testargs { + bool exclusive; + struct klm_lock alock; +}; + +/* + * arguments to KLM_UNLOCK + */ +struct klm_unlockargs { + struct klm_lock alock; +}; + +program KLM_PROG { + version KLM_VERS { + + klm_testrply KLM_TEST (struct klm_testargs) = 1; + + klm_stat KLM_LOCK (struct klm_lockargs) = 2; + + klm_stat KLM_CANCEL (struct klm_lockargs) = 3; + /* klm_granted=> the cancel request fails due to lock is already granted */ + /* klm_denied=> the cancel request successfully aborts +lock request */ + + klm_stat KLM_UNLOCK (struct klm_unlockargs) = 4; + } = 1; +} = 100020; diff --git a/include/rpcsvc/mount.x b/include/rpcsvc/mount.x new file mode 100644 index 0000000..0c8b7fd --- /dev/null +++ b/include/rpcsvc/mount.x @@ -0,0 +1,259 @@ +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/* + * Protocol description for the mount program + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)mount.x 1.2 87/09/18 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)mount.x 2.1 88/08/01 4.0 RPCSRC";*/ +%#endif /* not lint */ +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/mount.x 259117 2013-12-09 04:26:50Z hrs $"); +#endif + +const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */ +const MNTNAMLEN = 255; /* maximum bytes in a name argument */ +const FHSIZE = 32; /* size in bytes of a file handle */ +#ifdef WANT_NFS3 +const FHSIZE3 = 64; /* size in bytes of a file handle (v3) */ +#endif + +/* + * The fhandle is the file handle that the server passes to the client. + * All file operations are done using the file handles to refer to a file + * or a directory. The file handle can contain whatever information the + * server needs to distinguish an individual file. + */ +typedef opaque fhandle[FHSIZE]; +#ifdef WANT_NFS3 +typedef opaque fhandle3; +#endif + +/* + * If a status of zero is returned, the call completed successfully, and + * a file handle for the directory follows. A non-zero status indicates + * some sort of error. The status corresponds with UNIX error numbers. + */ +union fhstatus switch (unsigned fhs_status) { +case 0: + fhandle fhs_fhandle; +default: + void; +}; + +#ifdef WANT_NFS3 +/* + * Status codes returned by the version 3 mount call. + */ +enum mountstat3 { + MNT3_OK = 0, /* no error */ + MNT3ERR_PERM = 1, /* Not owner */ + MNT3ERR_NOENT = 2, /* No such file or directory */ + MNT3ERR_IO = 5, /* I/O error */ + MNT3ERR_ACCES = 13, /* Permission denied */ + MNT3ERR_NOTDIR = 20, /* Not a directory */ + MNT3ERR_INVAL = 22, /* Invalid argument */ + MNT3ERR_NAMETOOLONG = 63, /* Filename too long */ + MNT3ERR_NOTSUPP = 10004, /* Operation not supported */ + MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */ +}; + +struct mountres3_ok { + fhandle3 fhandle; + int auth_flavors<>; +}; + +union mountres3 switch (mountstat3 fhs_status) { +case 0: + mountres3_ok mountinfo; +default: + void; +}; +#endif + +/* + * The type dirpath is the pathname of a directory + */ +typedef string dirpath; + +/* + * The type name is used for arbitrary names (hostnames, groupnames) + */ +typedef string name; + +/* + * A list of who has what mounted + */ +typedef struct mountbody *mountlist; +struct mountbody { + name ml_hostname; + dirpath ml_directory; + mountlist ml_next; +}; + +/* + * A list of netgroups + */ +typedef struct groupnode *groups; +struct groupnode { + name gr_name; + groups gr_next; +}; + +/* + * A list of what is exported and to whom + */ +typedef struct exportnode *exports; +struct exportnode { + dirpath ex_dir; + groups ex_groups; + exports ex_next; +}; + +program MOUNTPROG { + /* + * Version one of the mount protocol communicates with version two + * of the NFS protocol. Version three communicates with + * version three of the NFS protocol. The only connecting + * point is the fhandle structure, which is the same for both + * protocols. + */ + version MOUNTVERS { + /* + * Does no work. It is made available in all RPC services + * to allow server response testing and timing + */ + void + MOUNTPROC_NULL(void) = 0; + + /* + * If fhs_status is 0, then fhs_fhandle contains the + * file handle for the directory. This file handle may + * be used in the NFS protocol. This procedure also adds + * a new entry to the mount list for this client mounting + * the directory. + * Unix authentication required. + */ + fhstatus + MOUNTPROC_MNT(dirpath) = 1; + + /* + * Returns the list of remotely mounted filesystems. The + * mountlist contains one entry for each hostname and + * directory pair. + */ + mountlist + MOUNTPROC_DUMP(void) = 2; + + /* + * Removes the mount list entry for the directory + * Unix authentication required. + */ + void + MOUNTPROC_UMNT(dirpath) = 3; + + /* + * Removes all of the mount list entries for this client + * Unix authentication required. + */ + void + MOUNTPROC_UMNTALL(void) = 4; + + /* + * Returns a list of all the exported filesystems, and which + * machines are allowed to import it. + */ + exports + MOUNTPROC_EXPORT(void) = 5; + + /* + * Identical to MOUNTPROC_EXPORT above + */ + exports + MOUNTPROC_EXPORTALL(void) = 6; + } = 1; +#ifdef WANT_NFS3 + version MOUNTVERS3 { + /* + * Does no work. It is made available in all RPC services + * to allow server response testing and timing + */ + void + MOUNTPROC_NULL(void) = 0; + + /* + * If mountres3.fhs_status is MNT3_OK, then + * mountres3.mountinfo contains the file handle for + * the directory and a list of acceptable + * authentication flavors. This file handle may only + * be used in the NFS version 3 protocol. This + * procedure also results in the server adding a new + * entry to its mount list recording that this client + * has mounted the directory. AUTH_UNIX authentication + * or better is required. + */ + mountres3 + MOUNTPROC_MNT(dirpath) = 1; + + /* + * Returns the list of remotely mounted filesystems. The + * mountlist contains one entry for each hostname and + * directory pair. + */ + mountlist + MOUNTPROC_DUMP(void) = 2; + + /* + * Removes the mount list entry for the directory + * Unix authentication required. + */ + void + MOUNTPROC_UMNT(dirpath) = 3; + + /* + * Removes all of the mount list entries for this client + * Unix authentication required. + */ + void + MOUNTPROC_UMNTALL(void) = 4; + + /* + * Returns a list of all the exported filesystems, and which + * machines are allowed to import it. + */ + exports + MOUNTPROC_EXPORT(void) = 5; + } = 3; +#endif +} = 100005; diff --git a/include/rpcsvc/nfs_prot.x b/include/rpcsvc/nfs_prot.x new file mode 100644 index 0000000..5e27f91 --- /dev/null +++ b/include/rpcsvc/nfs_prot.x @@ -0,0 +1,1268 @@ +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)nfs_prot.x 1.2 87/10/12 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)nfs_prot.x 2.1 88/08/01 4.0 RPCSRC";*/ +%#endif /* not lint */ +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/nfs_prot.x 259117 2013-12-09 04:26:50Z hrs $"); +#endif + +const NFS_PORT = 2049; +const NFS_MAXDATA = 8192; +const NFS_MAXPATHLEN = 1024; +const NFS_MAXNAMLEN = 255; +const NFS_FHSIZE = 32; +const NFS_COOKIESIZE = 4; +const NFS_FIFO_DEV = -1; /* size kludge for named pipes */ + +/* + * File types + */ +const NFSMODE_FMT = 0170000; /* type of file */ +const NFSMODE_DIR = 0040000; /* directory */ +const NFSMODE_CHR = 0020000; /* character special */ +const NFSMODE_BLK = 0060000; /* block special */ +const NFSMODE_REG = 0100000; /* regular */ +const NFSMODE_LNK = 0120000; /* symbolic link */ +const NFSMODE_SOCK = 0140000; /* socket */ +const NFSMODE_FIFO = 0010000; /* fifo */ + +/* + * Error status + */ +enum nfsstat { + NFS_OK= 0, /* no error */ + NFSERR_PERM=1, /* Not owner */ + NFSERR_NOENT=2, /* No such file or directory */ + NFSERR_IO=5, /* I/O error */ + NFSERR_NXIO=6, /* No such device or address */ + NFSERR_ACCES=13, /* Permission denied */ + NFSERR_EXIST=17, /* File exists */ + NFSERR_NODEV=19, /* No such device */ + NFSERR_NOTDIR=20, /* Not a directory*/ + NFSERR_ISDIR=21, /* Is a directory */ + NFSERR_FBIG=27, /* File too large */ + NFSERR_NOSPC=28, /* No space left on device */ + NFSERR_ROFS=30, /* Read-only file system */ + NFSERR_NAMETOOLONG=63, /* File name too long */ + NFSERR_NOTEMPTY=66, /* Directory not empty */ + NFSERR_DQUOT=69, /* Disc quota exceeded */ + NFSERR_STALE=70, /* Stale NFS file handle */ + NFSERR_WFLUSH=99 /* write cache flushed */ +}; + +/* + * File types + */ +enum ftype { + NFNON = 0, /* non-file */ + NFREG = 1, /* regular file */ + NFDIR = 2, /* directory */ + NFBLK = 3, /* block special */ + NFCHR = 4, /* character special */ + NFLNK = 5, /* symbolic link */ + NFSOCK = 6, /* unix domain sockets */ + NFBAD = 7, /* unused */ + NFFIFO = 8 /* named pipe */ +}; + +/* + * File access handle + */ +struct nfs_fh { + opaque data[NFS_FHSIZE]; +}; + +/* + * Timeval + */ +struct nfstime { + unsigned seconds; + unsigned useconds; +}; + + +/* + * File attributes + */ +struct fattr { + ftype type; /* file type */ + unsigned mode; /* protection mode bits */ + unsigned nlink; /* # hard links */ + unsigned uid; /* owner user id */ + unsigned gid; /* owner group id */ + unsigned size; /* file size in bytes */ + unsigned blocksize; /* preferred block size */ + unsigned rdev; /* special device # */ + unsigned blocks; /* Kb of disk used by file */ + unsigned fsid; /* device # */ + unsigned fileid; /* inode # */ + nfstime atime; /* time of last access */ + nfstime mtime; /* time of last modification */ + nfstime ctime; /* time of last change */ +}; + +/* + * File attributes which can be set + */ +struct sattr { + unsigned mode; /* protection mode bits */ + unsigned uid; /* owner user id */ + unsigned gid; /* owner group id */ + unsigned size; /* file size in bytes */ + nfstime atime; /* time of last access */ + nfstime mtime; /* time of last modification */ +}; + + +typedef string filename; +typedef string nfspath; + +/* + * Reply status with file attributes + */ +union attrstat switch (nfsstat status) { +case NFS_OK: + fattr attributes; +default: + void; +}; + +struct sattrargs { + nfs_fh file; + sattr attributes; +}; + +/* + * Arguments for directory operations + */ +struct diropargs { + nfs_fh dir; /* directory file handle */ + filename name; /* name (up to NFS_MAXNAMLEN bytes) */ +}; + +struct diropokres { + nfs_fh file; + fattr attributes; +}; + +/* + * Results from directory operation + */ +union diropres switch (nfsstat status) { +case NFS_OK: + diropokres diropres; +default: + void; +}; + +union readlinkres switch (nfsstat status) { +case NFS_OK: + nfspath data; +default: + void; +}; + +/* + * Arguments to remote read + */ +struct readargs { + nfs_fh file; /* handle for file */ + unsigned offset; /* byte offset in file */ + unsigned count; /* immediate read count */ + unsigned totalcount; /* total read count (from this offset)*/ +}; + +/* + * Status OK portion of remote read reply + */ +struct readokres { + fattr attributes; /* attributes, need for pagin*/ + opaque data; +}; + +union readres switch (nfsstat status) { +case NFS_OK: + readokres reply; +default: + void; +}; + +/* + * Arguments to remote write + */ +struct writeargs { + nfs_fh file; /* handle for file */ + unsigned beginoffset; /* beginning byte offset in file */ + unsigned offset; /* current byte offset in file */ + unsigned totalcount; /* total write count (to this offset)*/ + opaque data; +}; + +struct createargs { + diropargs where; + sattr attributes; +}; + +struct renameargs { + diropargs from; + diropargs to; +}; + +struct linkargs { + nfs_fh from; + diropargs to; +}; + +struct symlinkargs { + diropargs from; + nfspath to; + sattr attributes; +}; + + +typedef opaque nfscookie[NFS_COOKIESIZE]; + +/* + * Arguments to readdir + */ +struct readdirargs { + nfs_fh dir; /* directory handle */ + nfscookie cookie; + unsigned count; /* number of directory bytes to read */ +}; + +struct entry { + unsigned fileid; + filename name; + nfscookie cookie; + entry *nextentry; +}; + +struct dirlist { + entry *entries; + bool eof; +}; + +union readdirres switch (nfsstat status) { +case NFS_OK: + dirlist reply; +default: + void; +}; + +struct statfsokres { + unsigned tsize; /* preferred transfer size in bytes */ + unsigned bsize; /* fundamental file system block size */ + unsigned blocks; /* total blocks in file system */ + unsigned bfree; /* free blocks in fs */ + unsigned bavail; /* free blocks avail to non-superuser */ +}; + +union statfsres switch (nfsstat status) { +case NFS_OK: + statfsokres reply; +default: + void; +}; + +#ifdef WANT_NFS3 + +/* + * NFSv3 constants and types + */ +const NFS3_FHSIZE = 64; /* maximum size in bytes of a file handle */ +const NFS3_COOKIEVERFSIZE = 8; /* size of a cookie verifier for READDIR */ +const NFS3_CREATEVERFSIZE = 8; /* size of the verifier used for CREATE */ +const NFS3_WRITEVERFSIZE = 8; /* size of the verifier used for WRITE */ + +typedef unsigned hyper uint64; +typedef hyper int64; +typedef unsigned long uint32; +typedef long int32; +typedef string filename3<>; +typedef string nfspath3<>; +typedef uint64 fileid3; +typedef uint64 cookie3; +typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE]; +typedef opaque createverf3[NFS3_CREATEVERFSIZE]; +typedef opaque writeverf3[NFS3_WRITEVERFSIZE]; +typedef uint32 uid3; +typedef uint32 gid3; +typedef uint64 size3; +typedef uint64 offset3; +typedef uint32 mode3; +typedef uint32 count3; + +/* + * Error status (v3) + */ +enum nfsstat3 { + NFS3_OK = 0, + NFS3ERR_PERM = 1, + NFS3ERR_NOENT = 2, + NFS3ERR_IO = 5, + NFS3ERR_NXIO = 6, + NFS3ERR_ACCES = 13, + NFS3ERR_EXIST = 17, + NFS3ERR_XDEV = 18, + NFS3ERR_NODEV = 19, + NFS3ERR_NOTDIR = 20, + NFS3ERR_ISDIR = 21, + NFS3ERR_INVAL = 22, + NFS3ERR_FBIG = 27, + NFS3ERR_NOSPC = 28, + NFS3ERR_ROFS = 30, + NFS3ERR_MLINK = 31, + NFS3ERR_NAMETOOLONG = 63, + NFS3ERR_NOTEMPTY = 66, + NFS3ERR_DQUOT = 69, + NFS3ERR_STALE = 70, + NFS3ERR_REMOTE = 71, + NFS3ERR_BADHANDLE = 10001, + NFS3ERR_NOT_SYNC = 10002, + NFS3ERR_BAD_COOKIE = 10003, + NFS3ERR_NOTSUPP = 10004, + NFS3ERR_TOOSMALL = 10005, + NFS3ERR_SERVERFAULT = 10006, + NFS3ERR_BADTYPE = 10007, + NFS3ERR_JUKEBOX = 10008 +}; + +/* + * File types (v3) + */ +enum ftype3 { + NF3REG = 1, /* regular file */ + NF3DIR = 2, /* directory */ + NF3BLK = 3, /* block special */ + NF3CHR = 4, /* character special */ + NF3LNK = 5, /* symbolic link */ + NF3SOCK = 6, /* unix domain sockets */ + NF3FIFO = 7 /* named pipe */ +}; + +struct specdata3 { + uint32 specdata1; + uint32 specdata2; +}; + +/* + * File access handle (v3) + */ +struct nfs_fh3 { + opaque data; +}; + +/* + * Timeval (v3) + */ +struct nfstime3 { + uint32 seconds; + uint32 nseconds; +}; + + +/* + * File attributes (v3) + */ +struct fattr3 { + ftype3 type; /* file type */ + mode3 mode; /* protection mode bits */ + uint32 nlink; /* # hard links */ + uid3 uid; /* owner user id */ + gid3 gid; /* owner group id */ + size3 size; /* file size in bytes */ + size3 used; /* preferred block size */ + specdata3 rdev; /* special device # */ + uint64 fsid; /* device # */ + fileid3 fileid; /* inode # */ + nfstime3 atime; /* time of last access */ + nfstime3 mtime; /* time of last modification */ + nfstime3 ctime; /* time of last change */ +}; + +union post_op_attr switch (bool attributes_follow) { +case TRUE: + fattr3 attributes; +case FALSE: + void; +}; + +struct wcc_attr { + size3 size; + nfstime3 mtime; + nfstime3 ctime; +}; + +union pre_op_attr switch (bool attributes_follow) { +case TRUE: + wcc_attr attributes; +case FALSE: + void; +}; + +struct wcc_data { + pre_op_attr before; + post_op_attr after; +}; + +union post_op_fh3 switch (bool handle_follows) { +case TRUE: + nfs_fh3 handle; +case FALSE: + void; +}; + +/* + * File attributes which can be set (v3) + */ +enum time_how { + DONT_CHANGE = 0, + SET_TO_SERVER_TIME = 1, + SET_TO_CLIENT_TIME = 2 +}; + +union set_mode3 switch (bool set_it) { +case TRUE: + mode3 mode; +default: + void; +}; + +union set_uid3 switch (bool set_it) { +case TRUE: + uid3 uid; +default: + void; +}; + +union set_gid3 switch (bool set_it) { +case TRUE: + gid3 gid; +default: + void; +}; + +union set_size3 switch (bool set_it) { +case TRUE: + size3 size; +default: + void; +}; + +union set_atime switch (time_how set_it) { +case SET_TO_CLIENT_TIME: + nfstime3 atime; +default: + void; +}; + +union set_mtime switch (time_how set_it) { +case SET_TO_CLIENT_TIME: + nfstime3 mtime; +default: + void; +}; + +struct sattr3 { + set_mode3 mode; + set_uid3 uid; + set_gid3 gid; + set_size3 size; + set_atime atime; + set_mtime mtime; +}; + +/* + * Arguments for directory operations (v3) + */ +struct diropargs3 { + nfs_fh3 dir; /* directory file handle */ + filename3 name; /* name (up to NFS_MAXNAMLEN bytes) */ +}; + +/* + * Arguments to getattr (v3). + */ +struct GETATTR3args { + nfs_fh3 object; +}; + +struct GETATTR3resok { + fattr3 obj_attributes; +}; + +union GETATTR3res switch (nfsstat3 status) { +case NFS3_OK: + GETATTR3resok resok; +default: + void; +}; + +/* + * Arguments to setattr (v3). + */ +union sattrguard3 switch (bool check) { +case TRUE: + nfstime3 obj_ctime; +case FALSE: + void; +}; + +struct SETATTR3args { + nfs_fh3 object; + sattr3 new_attributes; + sattrguard3 guard; +}; + +struct SETATTR3resok { + wcc_data obj_wcc; +}; + +struct SETATTR3resfail { + wcc_data obj_wcc; +}; + +union SETATTR3res switch (nfsstat3 status) { +case NFS3_OK: + SETATTR3resok resok; +default: + SETATTR3resfail resfail; +}; + +/* + * Arguments to lookup (v3). + */ +struct LOOKUP3args { + diropargs3 what; +}; + +struct LOOKUP3resok { + nfs_fh3 object; + post_op_attr obj_attributes; + post_op_attr dir_attributes; +}; + +struct LOOKUP3resfail { + post_op_attr dir_attributes; +}; + +union LOOKUP3res switch (nfsstat3 status) { +case NFS3_OK: + LOOKUP3resok resok; +default: + LOOKUP3resfail resfail; +}; + +/* + * Arguments to access (v3). + */ +const ACCESS3_READ = 0x0001; +const ACCESS3_LOOKUP = 0x0002; +const ACCESS3_MODIFY = 0x0004; +const ACCESS3_EXTEND = 0x0008; +const ACCESS3_DELETE = 0x0010; +const ACCESS3_EXECUTE = 0x0020; + +struct ACCESS3args { + nfs_fh3 object; + uint32 access; +}; + +struct ACCESS3resok { + post_op_attr obj_attributes; + uint32 access; +}; + +struct ACCESS3resfail { + post_op_attr obj_attributes; +}; + +union ACCESS3res switch (nfsstat3 status) { +case NFS3_OK: + ACCESS3resok resok; +default: + ACCESS3resfail resfail; +}; + +/* + * Arguments to readlink (v3). + */ +struct READLINK3args { + nfs_fh3 symlink; +}; + +struct READLINK3resok { + post_op_attr symlink_attributes; + nfspath3 data; +}; + +struct READLINK3resfail { + post_op_attr symlink_attributes; +}; + +union READLINK3res switch (nfsstat3 status) { +case NFS3_OK: + READLINK3resok resok; +default: + READLINK3resfail resfail; +}; + +/* + * Arguments to read (v3). + */ +struct READ3args { + nfs_fh3 file; + offset3 offset; + count3 count; +}; + +struct READ3resok { + post_op_attr file_attributes; + count3 count; + bool eof; + opaque data<>; +}; + +struct READ3resfail { + post_op_attr file_attributes; +}; + +/* XXX: solaris 2.6 uses ``nfsstat'' here */ +union READ3res switch (nfsstat3 status) { +case NFS3_OK: + READ3resok resok; +default: + READ3resfail resfail; +}; + +/* + * Arguments to write (v3). + */ +enum stable_how { + UNSTABLE = 0, + DATA_SYNC = 1, + FILE_SYNC = 2 +}; + +struct WRITE3args { + nfs_fh3 file; + offset3 offset; + count3 count; + stable_how stable; + opaque data<>; +}; + +struct WRITE3resok { + wcc_data file_wcc; + count3 count; + stable_how committed; + writeverf3 verf; +}; + +struct WRITE3resfail { + wcc_data file_wcc; +}; + +union WRITE3res switch (nfsstat3 status) { +case NFS3_OK: + WRITE3resok resok; +default: + WRITE3resfail resfail; +}; + +/* + * Arguments to create (v3). + */ +enum createmode3 { + UNCHECKED = 0, + GUARDED = 1, + EXCLUSIVE = 2 +}; + +union createhow3 switch (createmode3 mode) { +case UNCHECKED: +case GUARDED: + sattr3 obj_attributes; +case EXCLUSIVE: + createverf3 verf; +}; + +struct CREATE3args { + diropargs3 where; + createhow3 how; +}; + +struct CREATE3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct CREATE3resfail { + wcc_data dir_wcc; +}; + +union CREATE3res switch (nfsstat3 status) { +case NFS3_OK: + CREATE3resok resok; +default: + CREATE3resfail resfail; +}; + +/* + * Arguments to mkdir (v3). + */ +struct MKDIR3args { + diropargs3 where; + sattr3 attributes; +}; + +struct MKDIR3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct MKDIR3resfail { + wcc_data dir_wcc; +}; + +union MKDIR3res switch (nfsstat3 status) { +case NFS3_OK: + MKDIR3resok resok; +default: + MKDIR3resfail resfail; +}; + +/* + * Arguments to symlink (v3). + */ +struct symlinkdata3 { + sattr3 symlink_attributes; + nfspath3 symlink_data; +}; + +struct SYMLINK3args { + diropargs3 where; + symlinkdata3 symlink; +}; + +struct SYMLINK3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct SYMLINK3resfail { + wcc_data dir_wcc; +}; + +union SYMLINK3res switch (nfsstat3 status) { +case NFS3_OK: + SYMLINK3resok resok; +default: + SYMLINK3resfail resfail; +}; + +/* + * Arguments to mknod (v3). + */ +struct devicedata3 { + sattr3 dev_attributes; + specdata3 spec; +}; + +union mknoddata3 switch (ftype3 type) { +case NF3CHR: +case NF3BLK: + devicedata3 device; +case NF3SOCK: +case NF3FIFO: + sattr3 pipe_attributes; +default: + void; +}; + +struct MKNOD3args { + diropargs3 where; + mknoddata3 what; +}; + +struct MKNOD3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct MKNOD3resfail { + wcc_data dir_wcc; +}; + +union MKNOD3res switch (nfsstat3 status) { +case NFS3_OK: + MKNOD3resok resok; +default: + MKNOD3resfail resfail; +}; + +/* + * Arguments to remove (v3). + */ +struct REMOVE3args { + diropargs3 object; +}; + +struct REMOVE3resok { + wcc_data dir_wcc; +}; + +struct REMOVE3resfail { + wcc_data dir_wcc; +}; + +union REMOVE3res switch (nfsstat3 status) { +case NFS3_OK: + REMOVE3resok resok; +default: + REMOVE3resfail resfail; +}; + +/* + * Arguments to rmdir (v3). + */ +struct RMDIR3args { + diropargs3 object; +}; + +struct RMDIR3resok { + wcc_data dir_wcc; +}; + +struct RMDIR3resfail { + wcc_data dir_wcc; +}; + +union RMDIR3res switch (nfsstat3 status) { +case NFS3_OK: + RMDIR3resok resok; +default: + RMDIR3resfail resfail; +}; + +/* + * Arguments to rename (v3). + */ +struct RENAME3args { + diropargs3 from; + diropargs3 to; +}; + +struct RENAME3resok { + wcc_data fromdir_wcc; + wcc_data todir_wcc; +}; + +struct RENAME3resfail { + wcc_data fromdir_wcc; + wcc_data todir_wcc; +}; + +union RENAME3res switch (nfsstat3 status) { +case NFS3_OK: + RENAME3resok resok; +default: + RENAME3resfail resfail; +}; + +/* + * Arguments to link (v3). + */ +struct LINK3args { + nfs_fh3 file; + diropargs3 link; +}; + +struct LINK3resok { + post_op_attr file_attributes; + wcc_data linkdir_wcc; +}; + +struct LINK3resfail { + post_op_attr file_attributes; + wcc_data linkdir_wcc; +}; + +union LINK3res switch (nfsstat3 status) { +case NFS3_OK: + LINK3resok resok; +default: + LINK3resfail resfail; +}; + +/* + * Arguments to readdir (v3). + */ +struct READDIR3args { + nfs_fh3 dir; + cookie3 cookie; + cookieverf3 cookieverf; + count3 count; +}; + +struct entry3 { + fileid3 fileid; + filename3 name; + cookie3 cookie; + entry3 *nextentry; +}; + +struct dirlist3 { + entry3 *entries; + bool eof; +}; + +struct READDIR3resok { + post_op_attr dir_attributes; + cookieverf3 cookieverf; + dirlist3 reply; +}; + +struct READDIR3resfail { + post_op_attr dir_attributes; +}; + +union READDIR3res switch (nfsstat3 status) { +case NFS3_OK: + READDIR3resok resok; +default: + READDIR3resfail resfail; +}; + +/* + * Arguments to readdirplus (v3). + */ +struct READDIRPLUS3args { + nfs_fh3 dir; + cookie3 cookie; + cookieverf3 cookieverf; + count3 dircount; + count3 maxcount; +}; + +struct entryplus3 { + fileid3 fileid; + filename3 name; + cookie3 cookie; + post_op_attr name_attributes; + post_op_fh3 name_handle; + entryplus3 *nextentry; +}; + +struct dirlistplus3 { + entryplus3 *entries; + bool eof; +}; + +struct READDIRPLUS3resok { + post_op_attr dir_attributes; + cookieverf3 cookieverf; + dirlistplus3 reply; +}; + +struct READDIRPLUS3resfail { + post_op_attr dir_attributes; +}; + +union READDIRPLUS3res switch (nfsstat3 status) { +case NFS3_OK: + READDIRPLUS3resok resok; +default: + READDIRPLUS3resfail resfail; +}; + +/* + * Arguments to fsstat (v3). + */ +struct FSSTAT3args { + nfs_fh3 fsroot; +}; + +struct FSSTAT3resok { + post_op_attr obj_attributes; + size3 tbytes; + size3 fbytes; + size3 abytes; + size3 tfiles; + size3 ffiles; + size3 afiles; + uint32 invarsec; +}; + +struct FSSTAT3resfail { + post_op_attr obj_attributes; +}; + +union FSSTAT3res switch (nfsstat3 status) { +case NFS3_OK: + FSSTAT3resok resok; +default: + FSSTAT3resfail resfail; +}; + +/* + * Arguments to fsinfo (v3). + */ +const FSF3_LINK = 0x0001; +const FSF3_SYMLINK = 0x0002; +const FSF3_HOMOGENEOUS = 0x0008; +const FSF3_CANSETTIME = 0x0010; + +struct FSINFO3args { + nfs_fh3 fsroot; +}; + +struct FSINFO3resok { + post_op_attr obj_attributes; + uint32 rtmax; + uint32 rtpref; + uint32 rtmult; + uint32 wtmax; + uint32 wtpref; + uint32 wtmult; + uint32 dtpref; + size3 maxfilesize; + nfstime3 time_delta; + uint32 properties; +}; + +struct FSINFO3resfail { + post_op_attr obj_attributes; +}; + +union FSINFO3res switch (nfsstat3 status) { +case NFS3_OK: + FSINFO3resok resok; +default: + FSINFO3resfail resfail; +}; + +/* + * Arguments to pathconf (v3). + */ +struct PATHCONF3args { + nfs_fh3 object; +}; + +struct PATHCONF3resok { + post_op_attr obj_attributes; + uint32 linkmax; + uint32 name_max; + bool no_trunc; + bool chown_restricted; + bool case_insensitive; + bool case_preserving; +}; + +struct PATHCONF3resfail { + post_op_attr obj_attributes; +}; + +union PATHCONF3res switch (nfsstat3 status) { +case NFS3_OK: + PATHCONF3resok resok; +default: + PATHCONF3resfail resfail; +}; + +/* + * Arguments to commit (v3). + */ +struct COMMIT3args { + nfs_fh3 file; + offset3 offset; + count3 count; +}; + +struct COMMIT3resok { + wcc_data file_wcc; + writeverf3 verf; +}; + +struct COMMIT3resfail { + wcc_data file_wcc; +}; + +union COMMIT3res switch (nfsstat3 status) { +case NFS3_OK: + COMMIT3resok resok; +default: + COMMIT3resfail resfail; +}; + +#endif /* WANT_NFS3 */ + +/* + * Remote file service routines + */ +program NFS_PROGRAM { + version NFS_VERSION { + void + NFSPROC_NULL(void) = 0; + + attrstat + NFSPROC_GETATTR(nfs_fh) = 1; + + attrstat + NFSPROC_SETATTR(sattrargs) = 2; + + void + NFSPROC_ROOT(void) = 3; + + diropres + NFSPROC_LOOKUP(diropargs) = 4; + + readlinkres + NFSPROC_READLINK(nfs_fh) = 5; + + readres + NFSPROC_READ(readargs) = 6; + + void + NFSPROC_WRITECACHE(void) = 7; + + attrstat + NFSPROC_WRITE(writeargs) = 8; + + diropres + NFSPROC_CREATE(createargs) = 9; + + nfsstat + NFSPROC_REMOVE(diropargs) = 10; + + nfsstat + NFSPROC_RENAME(renameargs) = 11; + + nfsstat + NFSPROC_LINK(linkargs) = 12; + + nfsstat + NFSPROC_SYMLINK(symlinkargs) = 13; + + diropres + NFSPROC_MKDIR(createargs) = 14; + + nfsstat + NFSPROC_RMDIR(diropargs) = 15; + + readdirres + NFSPROC_READDIR(readdirargs) = 16; + + statfsres + NFSPROC_STATFS(nfs_fh) = 17; + } = 2; +} = 100003; +#ifdef WANT_NFS3 +program NFS3_PROGRAM { + version NFS_V3 { + void + NFSPROC3_NULL(void) = 0; + + GETATTR3res + NFSPROC3_GETATTR(GETATTR3args) = 1; + + SETATTR3res + NFSPROC3_SETATTR(SETATTR3args) = 2; + + LOOKUP3res + NFSPROC3_LOOKUP(LOOKUP3args) = 3; + + ACCESS3res + NFSPROC3_ACCESS(ACCESS3args) = 4; + + READLINK3res + NFSPROC3_READLINK(READLINK3args) = 5; + + READ3res + NFSPROC3_READ(READ3args) = 6; + + WRITE3res + NFSPROC3_WRITE(WRITE3args) = 7; + + CREATE3res + NFSPROC3_CREATE(CREATE3args) = 8; + + MKDIR3res + NFSPROC3_MKDIR(MKDIR3args) = 9; + + SYMLINK3res + NFSPROC3_SYMLINK(SYMLINK3args) = 10; + + MKNOD3res + NFSPROC3_MKNOD(MKNOD3args) = 11; + + REMOVE3res + NFSPROC3_REMOVE(REMOVE3args) = 12; + + RMDIR3res + NFSPROC3_RMDIR(RMDIR3args) = 13; + + RENAME3res + NFSPROC3_RENAME(RENAME3args) = 14; + + LINK3res + NFSPROC3_LINK(LINK3args) = 15; + + READDIR3res + NFSPROC3_READDIR(READDIR3args) = 16; + + READDIRPLUS3res + NFSPROC3_READDIRPLUS(READDIRPLUS3args) = 17; + + FSSTAT3res + NFSPROC3_FSSTAT(FSSTAT3args) = 18; + + FSINFO3res + NFSPROC3_FSINFO(FSINFO3args) = 19; + + PATHCONF3res + NFSPROC3_PATHCONF(PATHCONF3args) = 20; + + COMMIT3res + NFSPROC3_COMMIT(COMMIT3args) = 21; + } = 3; +} = 100003; +#endif + diff --git a/include/rpcsvc/nis.x b/include/rpcsvc/nis.x new file mode 100644 index 0000000..3388423 --- /dev/null +++ b/include/rpcsvc/nis.x @@ -0,0 +1,460 @@ +%/*- +% * Copyright (c) 2010, Oracle America, Inc. +% * +% * Redistribution and use in source and binary forms, with or without +% * modification, are permitted provided that the following conditions are +% * met: +% * +% * * Redistributions of source code must retain the above copyright +% * notice, this list of conditions and the following disclaimer. +% * * 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. +% * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 +% * COPYRIGHT HOLDER 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. +% */ + +#ifndef RPC_HDR +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/nis.x 272808 2014-10-09 06:58:33Z bapt $"); +#endif + +/* + * From 4.1 : @(#)nis.x 1.61 Copyright 1989 Sun Microsystems + * + * RPC Language Protocol description file for NIS Plus + * This version : 1.61 + * Last Modified : 3/19/91 + */ +#ifdef RPC_HDR +%/* +% * nis.h +% * +% * This file is the main include file for NIS clients. It contains +% * both the client library function defines and the various data +% * structures used by the NIS service. It includes the file nis_tags.h +% * which defines the tag values. This allows the tags to change without +% * having to change the nis.x file. +% * +% * NOTE : DO NOT EDIT THIS FILE! It is automatically generated when +% * rpcgen is run on the nis.x file. Note that there is a +% * simple sed script to remove some unneeded lines. (See the +% * Makefile target nis.h) +% * +% */ +%#include +#endif + +/* This gets stuffed into the source files. */ +#if RPC_HDR +%#include +#endif +/* + * This is just pointless. + */ +#ifdef SUN_STUPIDITY +#if RPC_SVC +%#include "nis_svc.h" +#endif +#endif + +/* Include the RPC Language description of NIS objects */ +#include "nis_object.x" + +/* Errors that can be returned by the service */ +enum nis_error { + NIS_SUCCESS = 0, /* A-ok, let's rock n roll */ + NIS_S_SUCCESS = 1, /* Name found (maybe) */ + NIS_NOTFOUND = 2, /* Name definitely not found */ + NIS_S_NOTFOUND = 3, /* Name maybe not found */ + NIS_CACHEEXPIRED = 4, /* Name exists but cache out of date */ + NIS_NAMEUNREACHABLE = 5, /* Can't get there from here */ + NIS_UNKNOWNOBJ = 6, /* Object type is bogus */ + NIS_TRYAGAIN = 7, /* I'm busy, call back */ + NIS_SYSTEMERROR = 8, /* Out of band failure */ + NIS_CHAINBROKEN = 9, /* First/Next warning */ + NIS_PERMISSION = 10, /* Not enough permission to access */ + NIS_NOTOWNER = 11, /* You don't own it, sorry */ + NIS_NOT_ME = 12, /* I don't serve this name */ + NIS_NOMEMORY = 13, /* Outta VM! Help! */ + NIS_NAMEEXISTS = 14, /* Can't create over another name */ + NIS_NOTMASTER = 15, /* I'm justa secondaray, don't ask me */ + NIS_INVALIDOBJ = 16, /* Object is broken somehow */ + NIS_BADNAME = 17, /* Unparsable name */ + NIS_NOCALLBACK = 18, /* Couldn't talk to call back proc */ + NIS_CBRESULTS = 19, /* Results being called back to you */ + NIS_NOSUCHNAME = 20, /* Name unknown */ + NIS_NOTUNIQUE = 21, /* Value is not uniques (entry) */ + NIS_IBMODERROR = 22, /* Inf. Base. Modify error. */ + NIS_NOSUCHTABLE = 23, /* Name for table was wrong */ + NIS_TYPEMISMATCH = 24, /* Entry and table type mismatch */ + NIS_LINKNAMEERROR = 25, /* Link points to bogus name */ + NIS_PARTIAL = 26, /* Partial success, found table */ + NIS_TOOMANYATTRS = 27, /* Too many attributes */ + NIS_RPCERROR = 28, /* RPC error encountered */ + NIS_BADATTRIBUTE = 29, /* Bad or invalid attribute */ + NIS_NOTSEARCHABLE = 30, /* Non-searchable object searched */ + NIS_CBERROR = 31, /* Error during callback (svc crash) */ + NIS_FOREIGNNS = 32, /* Foreign Namespace */ + NIS_BADOBJECT = 33, /* Malformed object structure */ + NIS_NOTSAMEOBJ = 34, /* Object swapped during deletion */ + NIS_MODFAIL = 35, /* Failure during a Modify. */ + NIS_BADREQUEST = 36, /* Illegal query for table */ + NIS_NOTEMPTY = 37, /* Attempt to remove a non-empty tbl */ + NIS_COLDSTART_ERR = 38, /* Error accesing the cold start file */ + NIS_RESYNC = 39, /* Transaction log too far out of date */ + NIS_FAIL = 40, /* NIS operation failed. */ + NIS_UNAVAIL = 41, /* NIS+ service is unavailable (client) */ + NIS_RES2BIG = 42, /* NIS+ result too big for datagram */ + NIS_SRVAUTH = 43, /* NIS+ server wasn't authenticated. */ + NIS_CLNTAUTH = 44, /* NIS+ Client wasn't authenticated. */ + NIS_NOFILESPACE = 45, /* NIS+ server ran out of disk space */ + NIS_NOPROC = 46, /* NIS+ server couldn't create new proc */ + NIS_DUMPLATER = 47 /* NIS+ server already has dump child */ +}; + + +/* + * Structure definitions for the parameters and results of the actual + * NIS RPC calls. + * + * This is the standard result (in the protocol) of most of the nis + * requests. + */ + +struct nis_result { + nis_error status; /* Status of the response */ + nis_object objects<>; /* objects found */ + netobj cookie; /* Cookie Data */ + u_long zticks; /* server ticks */ + u_long dticks; /* DBM ticks. */ + u_long aticks; /* Cache (accel) ticks */ + u_long cticks; /* Client ticks */ +}; + +/* + * A Name Service request + * This request is used to access the name space, ns_name is the name + * of the object within the namespace and the object is it's value, for + * add/modify, a copy of the original for remove. + */ + +struct ns_request { + nis_name ns_name; /* Name in the NIS name space */ + nis_object ns_object<1>; /* Optional Object (add/remove) */ +}; + +/* + * An information base request + * This request includes the NIS name of the table we wish to search, the + * search criteria in the form of attribute/value pairs and an optional + * callback program number. If the callback program number is provided + * the server will send back objects one at a time, otherwise it will + * return them all in the response. + */ + +struct ib_request { + nis_name ibr_name; /* The name of the Table */ + nis_attr ibr_srch<>; /* The search critereia */ + u_long ibr_flags; /* Optional flags */ + nis_object ibr_obj<1>; /* optional object (add/modify) */ + nis_server ibr_cbhost<1>; /* Optional callback info */ + u_long ibr_bufsize; /* Optional first/next bufsize */ + netobj ibr_cookie; /* The first/next cookie */ +}; + +/* + * This argument to the PING call notifies the replicas that something in + * a directory has changed and this is it's timestamp. The replica will use + * the timestamp to determine if its resync operation was successful. + */ +struct ping_args { + nis_name dir; /* Directory that had the change */ + u_long stamp; /* timestamp of the transaction */ +}; + +/* + * These are the type of entries that are stored in the transaction log, + * note that modifications will appear as two entries, for names, they have + * an "OLD" entry followed by a "NEW" entry. For entries in tables, there + * is a remove followed by an add. It is done this way so that we can read + * the log backwards to back out transactions and forwards to propagate + * updates. + */ +enum log_entry_t { + LOG_NOP = 0, + ADD_NAME = 1, /* Name Added to name space */ + REM_NAME = 2, /* Name removed from name space */ + MOD_NAME_OLD = 3, /* Name was modified in the name space */ + MOD_NAME_NEW = 4, /* Name was modified in the name space */ + ADD_IBASE = 5, /* Entry added to information base */ + REM_IBASE = 6, /* Entry removed from information base */ + MOD_IBASE = 7, /* Entry was modified in information base */ + UPD_STAMP = 8 /* Update timestamp (used as fenceposts) */ +}; + +/* + * This result is returned from the name service when it is requested to + * dump logged entries from its transaction log. Information base updates + * will have the name of the information base in the le_name field and + * a canonical set of attribute/value pairs to fully specify the entry's + * 'name'. + */ +struct log_entry { + u_long le_time; /* Time in seconds */ + log_entry_t le_type; /* Type of log entry */ + nis_name le_princp; /* Principal making the change */ + nis_name le_name; /* Name of table/dir involved */ + nis_attr le_attrs<>; /* List of AV pairs. */ + nis_object le_object; /* Actual object value */ +}; + +struct log_result { + nis_error lr_status; /* The status itself */ + netobj lr_cookie; /* Used by the dump callback */ + log_entry lr_entries<>; /* zero or more entries */ +}; + +struct cp_result { + nis_error cp_status; /* Status of the checkpoint */ + u_long cp_zticks; /* Service 'ticks' */ + u_long cp_dticks; /* Database 'ticks' */ +}; + +/* + * This structure defines a generic NIS tag list. The taglist contains + * zero or tags, each of which is a type and a value. (u_long). + * These are used to report statistics (see tag definitions below) + * and to set or reset state variables. + */ +struct nis_tag { + u_long tag_type; /* Statistic tag (may vary) */ + string tag_val<1024>; /* Statistic value may also vary */ +}; + +struct nis_taglist { + nis_tag tags<>; /* List of tags */ +}; + +struct dump_args { + nis_name da_dir; /* Directory to dump */ + u_long da_time; /* From this timestamp */ + nis_server da_cbhost<1>; /* Callback to use. */ +}; + +struct fd_args { + nis_name dir_name; /* The directory we're looking for */ + nis_name requester; /* Host principal name for signature */ +}; + +struct fd_result { + nis_error status; /* Status returned by function */ + nis_name source; /* Source of this answer */ + opaque dir_data<>; /* Directory Data (XDR'ed) */ + opaque signature<>; /* Signature of the source */ +}; + + +/* + * What's going on here? Well, it's like this. When the service + * is being compiled it wants to have the service definition specific + * info included, and when the client is being compiled it wants that + * info. This includes the appropriate file which was generated by + * make in the protocols directory (probably /usr/include/rpcsvc). + * + * Uhm... guys? With RPC, you aren't supposed to have separate + * server-specific and client-specific header files. You have one header + * file that's suitable for both. If your code doesn't work using just + * the one header file, I submit to you that it's broken. + * -Bill + */ +#ifdef SUN_STUPIDITY +#ifdef RPC_SVC +%#include "nis_svc.h" +#endif +#ifdef RPC_CLNT +%#include "nis_clnt.h" +#endif +#endif + +program NIS_PROG { + + /* RPC Language description of the NIS+ protocol */ + version NIS_VERSION { + /* The name service functions */ + nis_result NIS_LOOKUP(ns_request) = 1; + nis_result NIS_ADD(ns_request) = 2; + nis_result NIS_MODIFY(ns_request) = 3; + nis_result NIS_REMOVE(ns_request) = 4; + + /* The information base functions */ + nis_result NIS_IBLIST(ib_request) = 5; + nis_result NIS_IBADD(ib_request) = 6; + nis_result NIS_IBMODIFY(ib_request) = 7; + nis_result NIS_IBREMOVE(ib_request) = 8; + nis_result NIS_IBFIRST(ib_request) = 9; + nis_result NIS_IBNEXT(ib_request) = 10; + + /* NIS Administrative functions */ + fd_result NIS_FINDDIRECTORY(fd_args) = 12; + + /* If fetch and optionally reset statistics */ + nis_taglist NIS_STATUS(nis_taglist) = 14; + + /* Dump changes to directory since time in da_time */ + log_result NIS_DUMPLOG(dump_args) = 15; + + /* Dump contents of directory named */ + log_result NIS_DUMP(dump_args) = 16; + + /* Check status of callback thread */ + bool NIS_CALLBACK(netobj) = 17; + + /* Return last update time for named dir */ + u_long NIS_CPTIME(nis_name) = 18; + + /* Checkpoint directory or table named */ + cp_result NIS_CHECKPOINT(nis_name) = 19; + + /* Send 'status changed' ping to replicates */ + void NIS_PING(ping_args) = 20; + + /* Modify server behaviour (such as debugging) */ + nis_taglist NIS_SERVSTATE(nis_taglist) = 21; + + /* Create a Directory */ + nis_error NIS_MKDIR(nis_name) = 22; + + /* Remove a Directory */ + nis_error NIS_RMDIR(nis_name) = 23; + + /* Update public keys of a directory object */ + nis_error NIS_UPDKEYS(nis_name) = 24; + } = 3; +} = 100300; + +/* + * Included below are the defines that become part of nis.h, + * they are technically not part of the protocol, but do define + * key aspects of the implementation and are therefore useful + * in building a conforming server or client. + */ +#if RPC_HDR +%/* +% * Generic "hash" datastructures, used by all types of hashed data. +% */ +%struct nis_hash_data { +% nis_name name; /* NIS name of hashed item */ +% int keychain; /* It's hash key (for pop) */ +% struct nis_hash_data *next; /* Hash collision pointer */ +% struct nis_hash_data *prv_item; /* A serial, doubly linked list */ +% struct nis_hash_data *nxt_item; /* of items in the hash table */ +%}; +%typedef struct nis_hash_data NIS_HASH_ITEM; +% +%struct nis_hash_table { +% NIS_HASH_ITEM *keys[64]; /* A hash table of items */ +% NIS_HASH_ITEM *first; /* The first "item" in serial list */ +%}; +%typedef struct nis_hash_table NIS_HASH_TABLE; +% +%/* Structure for storing dynamically allocated static data */ +%struct nis_sdata { +% void *buf; /* Memory allocation pointer */ +% u_long size; /* Buffer size */ +%}; +% +%/* Generic client creating flags */ +%#define ZMH_VC 1 +%#define ZMH_DG 2 +%#define ZMH_AUTH 4 +% +%/* Testing Access rights for objects */ +% +%#define NIS_READ_ACC 1 +%#define NIS_MODIFY_ACC 2 +%#define NIS_CREATE_ACC 4 +%#define NIS_DESTROY_ACC 8 +%/* Test macros. a == access rights, m == desired rights. */ +%#define WORLD(a, m) (((a) & (m)) != 0) +%#define GROUP(a, m) (((a) & ((m) << 8)) != 0) +%#define OWNER(a, m) (((a) & ((m) << 16)) != 0) +%#define NOBODY(a, m) (((a) & ((m) << 24)) != 0) +% +%#define OATYPE(d, n) (((d)->do_armask.do_armask_val+n)->oa_otype) +%#define OARIGHTS(d, n) (((d)->do_armask.do_armask_val+n)->oa_rights) +%#define WORLD_DEFAULT (NIS_READ_ACC) +%#define GROUP_DEFAULT (NIS_READ_ACC << 8) +%#define OWNER_DEFAULT ((NIS_READ_ACC + NIS_MODIFY_ACC + NIS_CREATE_ACC + NIS_DESTROY_ACC) << 16) +%#define DEFAULT_RIGHTS (WORLD_DEFAULT | GROUP_DEFAULT | OWNER_DEFAULT) +% +%/* Result manipulation defines ... */ +%#define NIS_RES_NUMOBJ(x) ((x)->objects.objects_len) +%#define NIS_RES_OBJECT(x) ((x)->objects.objects_val) +%#define NIS_RES_COOKIE(x) ((x)->cookie) +%#define NIS_RES_STATUS(x) ((x)->status) +% +%/* These defines make getting at the variant part of the object easier. */ +%#define TA_data zo_data.objdata_u.ta_data +%#define EN_data zo_data.objdata_u.en_data +%#define DI_data zo_data.objdata_u.di_data +%#define LI_data zo_data.objdata_u.li_data +%#define GR_data zo_data.objdata_u.gr_data +% +%#define __type_of(o) ((o)->zo_data.zo_type) +% +%/* Declarations for the internal subroutines in nislib.c */ +%enum name_pos {SAME_NAME, HIGHER_NAME, LOWER_NAME, NOT_SEQUENTIAL, BAD_NAME}; +%typedef enum name_pos name_pos; +% +%/* +% * Defines for getting at column data in entry objects. Because RPCGEN +% * generates some rather wordy structures, we create some defines that +% * collapse the needed keystrokes to access a particular value using +% * these definitions they take an nis_object *, and an int and return +% * a u_char * for Value, and an int for length. +% */ +%#define ENTRY_VAL(obj, col) (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val +%#define ENTRY_LEN(obj, col) (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len +% +%#ifdef __cplusplus +%} +%#endif +% +%/* Prototypes, and extern declarations for the NIS library functions. */ +%#include +%#endif /* __NIS_RPCGEN_H */ +%/* EDIT_START */ +% +%/* +% * nis_3.h +% * +% * This file contains definitions that are only of interest to the actual +% * service daemon and client stubs. Normal users of NIS will not include +% * this file. +% * +% * NOTE : This include file is automatically created by a combination +% * of rpcgen and sed. DO NOT EDIT IT, change the nis.x file instead +% * and then remake this file. +% */ +%#ifndef __nis_3_h +%#define __nis_3_h +%#ifdef __cplusplus +%extern "C" { +%#endif +#endif diff --git a/include/rpcsvc/nis_cache.x b/include/rpcsvc/nis_cache.x new file mode 100644 index 0000000..73e61fe --- /dev/null +++ b/include/rpcsvc/nis_cache.x @@ -0,0 +1,85 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user or with the express written consent of +% * Sun Microsystems, Inc. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ + +/* + * nis_cache.x + * + * Copyright (c) 1988-1992 Sun Microsystems Inc + * All Rights Reserved. + */ + +/* From: %#pragma ident "@(#)nis_cache.x 1.11 94/05/03 SMI" */ + +#ifndef RPC_HDR +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/nis_cache.x 114629 2003-05-04 02:51:42Z obrien $"); +#endif + +#ifdef RPC_HDR +%#include +%#include +% +%/* default cache file */ +%#define CACHEFILE "/var/nis/NIS_SHARED_DIRCACHE" +% +%/* clients have to read-lock the cache file, and SVR4 locking requires that */ +%/* the file be writable, but we don't want a world-writable cache file. */ +%/* So... everyone agrees to use a different, world-writable file for the */ +%/* locking operations, but the data is in CACHEFILE. */ +%#define CACHELOCK "/usr/tmp/.NIS_DIR_CACHELOCK" +% +%/* the file containing one trusted XDR'ed directory object. +% * This has to be present for the system to work. +% */ +%#define COLD_START_FILE "/var/nis/NIS_COLD_START" +% +%enum pc_status {HIT, MISS, NEAR_MISS}; +% +%extern int __nis_debuglevel; +% +% +#endif + +#ifdef RPC_CLNT +#ifdef SOLARIS +%#include "../gen/nis_clnt.h" +#else +%#include "nis.h" +#endif +#endif + +program CACHEPROG { + version CACHE_VER_1 { + void NIS_CACHE_ADD_ENTRY(fd_result) = 1; + void NIS_CACHE_REMOVE_ENTRY(directory_obj) = 2; + void NIS_CACHE_READ_COLDSTART(void) = 3; + void NIS_CACHE_REFRESH_ENTRY(string<>) = 4; + } = 1; +} = 100301; diff --git a/include/rpcsvc/nis_callback.x b/include/rpcsvc/nis_callback.x new file mode 100644 index 0000000..af54287 --- /dev/null +++ b/include/rpcsvc/nis_callback.x @@ -0,0 +1,75 @@ +%/*- +% * Copyright (c) 2010, Oracle America, Inc. +% * +% * Redistribution and use in source and binary forms, with or without +% * modification, are permitted provided that the following conditions are +% * met: +% * +% * * Redistributions of source code must retain the above copyright +% * notice, this list of conditions and the following disclaimer. +% * * 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. +% * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 +% * COPYRIGHT HOLDER 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. +% */ + +/* + * nis_callback.x + * + * Copyright (c) 1988-1992 Sun Microsystems Inc + * All Rights Reserved. + */ + +/* From: %#pragma ident "@(#)nis_callback.x 1.7 94/05/03 SMI" */ + +#ifndef RPC_HDR +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/nis_callback.x 259117 2013-12-09 04:26:50Z hrs $"); +#endif + +/* + * "@(#)zns_cback.x 1.2 90/09/10 Copyr 1990 Sun Micro" + * + * RPCL description of the Callback Service. + */ + +#ifdef RPC_HDR +%#include +#endif +#ifdef RPC_XDR +#ifdef SOLARIS +%#include "nis_clnt.h" +#else +%#include "nis.h" +#endif +#endif + +typedef nis_object *obj_p; + +struct cback_data { + obj_p entries<>; /* List of objects */ +}; + +program CB_PROG { + version CB_VERS { + bool CBPROC_RECEIVE(cback_data) = 1; + void CBPROC_FINISH(void) = 2; + void CBPROC_ERROR(nis_error) = 3; + } = 1; +} = 100302; diff --git a/include/rpcsvc/nis_db.h b/include/rpcsvc/nis_db.h new file mode 100644 index 0000000..8d96622 --- /dev/null +++ b/include/rpcsvc/nis_db.h @@ -0,0 +1,135 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * $FreeBSD: releng/11.1/include/rpcsvc/nis_db.h 93032 2002-03-23 17:24:55Z imp $ + */ + +/* + * Copyright (c) 1991, by Sun Microsystems Inc. + */ + +/* + * This header file defines the interface to the NIS database. All + * implementations of the database must export at least these routines. + * They must also follow the conventions set herein. See the implementors + * guide for specific semantics that are required. + */ + +#ifndef _RPCSVC_NIS_DB_H +#define _RPCSVC_NIS_DB_H + + +/* From: #pragma ident "@(#)nis_db.h 1.8 94/05/03 SMI" */ + +/* + * Note: although the version of shipped with Solaris + * 2.5/2.5.x is actually older than this one (according to the ident + * string), it contains changes and a few added functions. Those changes + * have been hand merged into this file to bring it up to date. + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum db_status { + DB_SUCCESS = 0, + DB_NOTFOUND = 1, + DB_NOTUNIQUE = 2, + DB_BADTABLE = 3, + DB_BADQUERY = 4, + DB_BADOBJECT = 5, + DB_MEMORY_LIMIT = 6, + DB_STORAGE_LIMIT = 7, + DB_INTERNAL_ERROR = 8 +}; +typedef enum db_status db_status; + +enum db_action { + DB_LOOKUP = 0, + DB_REMOVE = 1, + DB_ADD = 2, + DB_FIRST = 3, + DB_NEXT = 4, + DB_ALL = 5, + DB_RESET_NEXT = 6 +}; +typedef enum db_action db_action; + +typedef entry_obj *entry_object_p; + +typedef struct { + u_int db_next_desc_len; + char *db_next_desc_val; +} db_next_desc; + +struct db_result { + db_status status; + db_next_desc nextinfo; + struct { + u_int objects_len; + entry_object_p *objects_val; + } objects; + long ticks; +}; +typedef struct db_result db_result; + +/* + * Prototypes for the database functions. + */ + +extern bool_t db_initialize(char *); +#ifdef ORIGINAL_DECLS +extern bool_t db_create_table(char *, table_obj *); +extern bool_t db_destroy_table(char *); +#else +extern db_status db_create_table(char *, table_obj *); +extern db_status db_destroy_table(char *); +#endif +extern db_result *db_first_entry(char *, int, nis_attr *); +extern db_result *db_next_entry(char *, db_next_desc *); +extern db_result *db_reset_next_entry(char *, db_next_desc *); +extern db_result *db_list_entries(char *, int, nis_attr *); +extern db_result *db_add_entry(char *, int, nis_attr *, entry_obj *); +extern db_result *db_remove_entry(char *, int, nis_attr *); +extern db_status db_checkpoint(char *); +extern db_status db_standby(char *); +#ifndef ORIGINAL_DECLS +extern db_status db_table_exists(char *); +extern db_status db_unload_table(char *); +extern void db_free_result(db_result *); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _RPCSVC_NIS_DB_H */ diff --git a/include/rpcsvc/nis_object.x b/include/rpcsvc/nis_object.x new file mode 100644 index 0000000..c1cd031 --- /dev/null +++ b/include/rpcsvc/nis_object.x @@ -0,0 +1,319 @@ +%/*- +% * Copyright (c) 2010, Oracle America, Inc. +% * +% * Redistribution and use in source and binary forms, with or without +% * modification, are permitted provided that the following conditions are +% * met: +% * +% * * Redistributions of source code must retain the above copyright +% * notice, this list of conditions and the following disclaimer. +% * * 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. +% * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 +% * COPYRIGHT HOLDER 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. +% */ + +/* + * nis_object.x + * + * Copyright (c) 1988-1992 Sun Microsystems Inc + * All Rights Reserved. + */ + +/* $FreeBSD: releng/11.1/include/rpcsvc/nis_object.x 259117 2013-12-09 04:26:50Z hrs $ */ +/* From: %#pragma ident "@(#)nis_object.x 1.10 94/05/03 SMI" */ + +#if RPC_HDR +% +%#ifndef __nis_object_h +%#define __nis_object_h +% +#endif +/* + * This file defines the format for a NIS object in RPC language. + * It is included by the main .x file and the database access protocol + * file. It is common because both of them need to deal with the same + * type of object. Generating the actual code though is a bit messy because + * the nis.x file and the nis_dba.x file will generate xdr routines to + * encode/decode objects when only one set is needed. Such is life when + * one is using rpcgen. + * + * Note, the protocol doesn't specify any limits on such things as + * maximum name length, number of attributes, etc. These are enforced + * by the database backend. When you hit them you will no. Also see + * the db_getlimits() function for fetching the limit values. + * + */ + +/* Some manifest constants, chosen to maximize flexibility without + * plugging the wire full of data. + */ +const NIS_MAXSTRINGLEN = 255; +const NIS_MAXNAMELEN = 1024; +const NIS_MAXATTRNAME = 32; +const NIS_MAXATTRVAL = 2048; +const NIS_MAXCOLUMNS = 64; +const NIS_MAXATTR = 16; +const NIS_MAXPATH = 1024; +const NIS_MAXREPLICAS = 128; +const NIS_MAXLINKS = 16; + +const NIS_PK_NONE = 0; /* no public key (unix/sys auth) */ +const NIS_PK_DH = 1; /* Public key is Diffie-Hellman type */ +const NIS_PK_RSA = 2; /* Public key if RSA type */ +const NIS_PK_KERB = 3; /* Use kerberos style authentication */ + +/* + * The fundamental name type of NIS. The name may consist of two parts, + * the first being the fully qualified name, and the second being an + * optional set of attribute/value pairs. + */ +struct nis_attr { + string zattr_ndx<>; /* name of the index */ + opaque zattr_val<>; /* Value for the attribute. */ +}; + +typedef string nis_name<>; /* The NIS name itself. */ + +/* NIS object types are defined by the following enumeration. The numbers + * they use are based on the following scheme : + * 0 - 1023 are reserved for Sun, + * 1024 - 2047 are defined to be private to a particular tree. + * 2048 - 4095 are defined to be user defined. + * 4096 - ... are reserved for future use. + */ + +enum zotypes { + BOGUS_OBJ = 0, /* Uninitialized object structure */ + NO_OBJ = 1, /* NULL object (no data) */ + DIRECTORY_OBJ = 2, /* Directory object describing domain */ + GROUP_OBJ = 3, /* Group object (a list of names) */ + TABLE_OBJ = 4, /* Table object (a database schema) */ + ENTRY_OBJ = 5, /* Entry object (a database record) */ + LINK_OBJ = 6, /* A name link. */ + PRIVATE_OBJ = 7 /* Private object (all opaque data) */ +}; + +/* + * The types of Name services NIS knows about. They are enumerated + * here. The Binder code will use this type to determine if it has + * a set of library routines that will access the indicated name service. + */ +enum nstype { + UNKNOWN = 0, + NIS = 1, /* Nis Plus Service */ + SUNYP = 2, /* Old NIS Service */ + IVY = 3, /* Nis Plus Plus Service */ + DNS = 4, /* Domain Name Service */ + X500 = 5, /* ISO/CCCIT X.500 Service */ + DNANS = 6, /* Digital DECNet Name Service */ + XCHS = 7, /* Xerox ClearingHouse Service */ + CDS= 8 +}; + +/* + * DIRECTORY - The name service object. These objects identify other name + * servers that are serving some portion of the name space. Each has a + * type associated with it. The resolver library will note whether or not + * is has the needed routines to access that type of service. + * The oarmask structure defines an access rights mask on a per object + * type basis for the name spaces. The only bits currently used are + * create and destroy. By enabling or disabling these access rights for + * a specific object type for a one of the accessor entities (owner, + * group, world) the administrator can control what types of objects + * may be freely added to the name space and which require the + * administrator's approval. + */ +struct oar_mask { + u_long oa_rights; /* Access rights mask */ + zotypes oa_otype; /* Object type */ +}; + +struct endpoint { + string uaddr<>; + string family<>; /* Transport family (INET, OSI, etc) */ + string proto<>; /* Protocol (TCP, UDP, CLNP, etc) */ +}; + +/* + * Note: pkey is a netobj which is limited to 1024 bytes which limits the + * keysize to 8192 bits. This is consider to be a reasonable limit for + * the expected lifetime of this service. + */ +struct nis_server { + nis_name name; /* Principal name of the server */ + endpoint ep<>; /* Universal addr(s) for server */ + u_long key_type; /* Public key type */ + netobj pkey; /* server's public key */ +}; + +struct directory_obj { + nis_name do_name; /* Name of the directory being served */ + nstype do_type; /* one of NIS, DNS, IVY, YP, or X.500 */ + nis_server do_servers<>; /* <0> == Primary name server */ + u_long do_ttl; /* Time To Live (for caches) */ + oar_mask do_armask<>; /* Create/Destroy rights by object type */ +}; + +/* + * ENTRY - This is one row of data from an information base. + * The type value is used by the client library to convert the entry to + * it's internal structure representation. The Table name is a back pointer + * to the table where the entry is stored. This allows the client library + * to determine where to send a request if the client wishes to change this + * entry but got to it through a LINK rather than directly. + * If the entry is a "standalone" entry then this field is void. + */ +const EN_BINARY = 1; /* Indicates value is binary data */ +const EN_CRYPT = 2; /* Indicates the value is encrypted */ +const EN_XDR = 4; /* Indicates the value is XDR encoded */ +const EN_MODIFIED = 8; /* Indicates entry is modified. */ +const EN_ASN1 = 64; /* Means contents use ASN.1 encoding */ + +struct entry_col { + u_long ec_flags; /* Flags for this value */ + opaque ec_value<>; /* It's textual value */ +}; + +struct entry_obj { + string en_type<>; /* Type of entry such as "passwd" */ + entry_col en_cols<>; /* Value for the entry */ +}; + +/* + * GROUP - The group object contains a list of NIS principal names. Groups + * are used to authorize principals. Each object has a set of access rights + * for members of its group. Principal names in groups are in the form + * name.directory and recursive groups are expressed as @groupname.directory + */ +struct group_obj { + u_long gr_flags; /* Flags controlling group */ + nis_name gr_members<>; /* List of names in group */ +}; + +/* + * LINK - This is the LINK object. It is quite similar to a symbolic link + * in the UNIX filesystem. The attributes in the main object structure are + * relative to the LINK data and not what it points to (like the file system) + * "modify" privleges here indicate the right to modify what the link points + * at and not to modify that actual object pointed to by the link. + */ +struct link_obj { + zotypes li_rtype; /* Real type of the object */ + nis_attr li_attrs<>; /* Attribute/Values for tables */ + nis_name li_name; /* The object's real NIS name */ +}; + +/* + * TABLE - This is the table object. It implements a simple + * data base that applications and use for configuration or + * administration purposes. The role of the table is to group together + * a set of related entries. Tables are the simple database component + * of NIS. Like many databases, tables are logically divided into columns + * and rows. The columns are labeled with indexes and each ENTRY makes + * up a row. Rows may be addressed within the table by selecting one + * or more indexes, and values for those indexes. Each row which has + * a value for the given index that matches the desired value is returned. + * Within the definition of each column there is a flags variable, this + * variable contains flags which determine whether or not the column is + * searchable, contains binary data, and access rights for the entry objects + * column value. + */ + +const TA_BINARY = 1; /* Means table data is binary */ +const TA_CRYPT = 2; /* Means value should be encrypted */ +const TA_XDR = 4; /* Means value is XDR encoded */ +const TA_SEARCHABLE = 8; /* Means this column is searchable */ +const TA_CASE = 16; /* Means this column is Case Sensitive */ +const TA_MODIFIED = 32; /* Means this columns attrs are modified*/ +const TA_ASN1 = 64; /* Means contents use ASN.1 encoding */ + +struct table_col { + string tc_name<64>; /* Column Name */ + u_long tc_flags; /* control flags */ + u_long tc_rights; /* Access rights mask */ +}; + +struct table_obj { + string ta_type<64>; /* Table type such as "passwd" */ + int ta_maxcol; /* Total number of columns */ + u_char ta_sep; /* Separator character */ + table_col ta_cols<>; /* The number of table indexes */ + string ta_path<>; /* A search path for this table */ +}; + +/* + * This union joins together all of the currently known objects. + */ +union objdata switch (zotypes zo_type) { + case DIRECTORY_OBJ : + struct directory_obj di_data; + case GROUP_OBJ : + struct group_obj gr_data; + case TABLE_OBJ : + struct table_obj ta_data; + case ENTRY_OBJ: + struct entry_obj en_data; + case LINK_OBJ : + struct link_obj li_data; + case PRIVATE_OBJ : + opaque po_data<>; + case NO_OBJ : + void; + case BOGUS_OBJ : + void; + default : + void; +}; + +/* + * This is the basic NIS object data type. It consists of a generic part + * which all objects contain, and a specialized part which varies depending + * on the type of the object. All of the specialized sections have been + * described above. You might have wondered why they all start with an + * integer size, followed by the useful data. The answer is, when the + * server doesn't recognize the type returned it treats it as opaque data. + * And the definition for opaque data is {int size; char *data;}. In this + * way, servers and utility routines that do not understand a given type + * may still pass it around. One has to be careful in setting + * this variable accurately, it must take into account such things as + * XDR padding of structures etc. The best way to set it is to note one's + * position in the XDR encoding stream, encode the structure, look at the + * new position and calculate the size. + */ +struct nis_oid { + u_long ctime; /* Time of objects creation */ + u_long mtime; /* Time of objects modification */ +}; + +struct nis_object { + nis_oid zo_oid; /* object identity verifier. */ + nis_name zo_name; /* The NIS name for this object */ + nis_name zo_owner; /* NIS name of object owner. */ + nis_name zo_group; /* NIS name of access group. */ + nis_name zo_domain; /* The administrator for the object */ + u_long zo_access; /* Access rights (owner, group, world) */ + u_long zo_ttl; /* Object's time to live in seconds. */ + objdata zo_data; /* Data structure for this type */ +}; +#if RPC_HDR +% +%#endif /* if __nis_object_h */ +% +#endif diff --git a/include/rpcsvc/nis_tags.h b/include/rpcsvc/nis_tags.h new file mode 100644 index 0000000..472a56d --- /dev/null +++ b/include/rpcsvc/nis_tags.h @@ -0,0 +1,140 @@ +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/* + * Copyright (c) 1991, Sun Microsystems Inc. + */ + +/* + * nis_tags.h + * + * This file contains the tags and statistics definitions. It is + * automatically included by nis.h + */ + +#ifndef _RPCSVC_NIS_TAGS_H +#define _RPCSVC_NIS_TAGS_H + +/* $FreeBSD: releng/11.1/include/rpcsvc/nis_tags.h 259117 2013-12-09 04:26:50Z hrs $ */ +/* From: #pragma ident "@(#)nis_tags.h 1.10 94/05/03 SMI" */ +/* from file: zns_tags.h 1.7 Copyright (c) 1990 Sun Microsystems */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ORIGINAL_DECLS +#define NIS_DIR "data" +#endif + +/* Lookup and List function flags */ +#define FOLLOW_LINKS (1<<0) /* Follow link objects */ +#define FOLLOW_PATH (1<<1) /* Follow the path in a table */ +#define HARD_LOOKUP (1<<2) /* Block until successful */ +#define ALL_RESULTS (1<<3) /* Retrieve all results */ +#define NO_CACHE (1<<4) /* Do not return 'cached' results */ +#define MASTER_ONLY (1<<5) /* Get value only from master server */ +#define EXPAND_NAME (1<<6) /* Expand partitially qualified names */ + +/* Semantic modification for table operations flags */ +#define RETURN_RESULT (1<<7) /* Return resulting object to client */ +#define ADD_OVERWRITE (1<<8) /* Allow overwrites on ADD */ +#define REM_MULTIPLE (1<<9) /* Allow wildcard deletes */ +#define MOD_SAMEOBJ (1<<10) /* Check modified object before write */ +#define ADD_RESERVED (1<<11) /* Spare ADD semantic */ +#define REM_RESERVED (1<<12) /* Spare REM semantic */ +#ifdef ORIGINAL_DECLS +#define MOD_RESERVED (1<<13) /* Spare MOD semantic */ +#else +#define MOD_EXCLUSIVE (1<<13) /* Modify no overwrite on modified keys */ +#endif + +/* Transport specific modifications to the operation */ +#define USE_DGRAM (1<<16) /* Use a datagram transport */ +#define NO_AUTHINFO (1<<17) /* Don't bother attaching auth info */ + +/* + * Declarations for "standard" NIS+ tags + * State variable tags have values 0 - 2047 + * Statistic tags have values 2048 - 65535 + * User Tags have values >2^16 + */ +#define TAG_DEBUG 1 /* set debug level */ +#define TAG_STATS 2 /* Enable/disable statistics */ +#define TAG_GCACHE 3 /* Flush the Group Cache */ +#ifndef ORIGINAL_DECLS +#define TAG_GCACHE_ALL TAG_GCACHE +#endif +#define TAG_DCACHE 4 /* Flush the directory cache */ +#ifndef ORIGINAL_DECLS +#define TAG_DCACHE_ONE TAG_DCACHE +#endif +#define TAG_OCACHE 5 /* Flush the Object Cache */ +#define TAG_SECURE 6 /* Set the security level */ +#ifndef ORIGINAL_DECLS +#define TAG_TCACHE_ONE 7 /* Flush the table cache */ +#define TAG_DCACHE_ALL 8 /* Flush entire directory cache */ +#define TAG_TCACHE_ALL 9 /* Flush entire table cache */ +#define TAG_GCACHE_ONE 10 /* Flush one group object */ +#define TAG_DCACHE_ONE_REFRESH 11 /* Flush and refresh one DO */ +#endif + +#define TAG_OPSTATS 2048 /* NIS+ operations statistics */ +#define TAG_THREADS 2049 /* Child process/thread status */ +#define TAG_HEAP 2050 /* Heap usage statistics */ +#define TAG_UPDATES 2051 /* Updates to this service */ +#define TAG_VISIBLE 2052 /* First update that isn't replicated */ +#define TAG_S_DCACHE 2053 /* Directory cache statistics */ +#define TAG_S_OCACHE 2054 /* Object cache statistics */ +#define TAG_S_GCACHE 2055 /* Group cache statistics */ +#define TAG_S_STORAGE 2056 /* Group cache statistics */ +#define TAG_UPTIME 2057 /* Time that server has been up */ +#ifndef ORIGINAL_DECLS +#define TAG_DIRLIST 2058 /* Dir served by this server */ +#define TAG_NISCOMPAT 2059 /* Whether supports NIS compat mode */ +#define TAG_DNSFORWARDING 2060 /* Whether DNS forwarding supported*/ +#define TAG_SECURITY_LEVEL 2061 /* Security level of the server */ +#define TAG_ROOTSERVER 2062 /* Whether root server */ +#endif + +/* + * Declarations for the Group object flags. Currently + * there are only 3. + */ +#define IMPMEM_GROUPS 1 /* Implicit Membership allowed */ +#define RECURS_GROUPS 2 /* Recursive Groups allowed */ +#define NEGMEM_GROUPS 4 /* Negative Groups allowed */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RPCSVC_NIS_TAGS_H */ diff --git a/include/rpcsvc/nislib.h b/include/rpcsvc/nislib.h new file mode 100644 index 0000000..ceaad40 --- /dev/null +++ b/include/rpcsvc/nislib.h @@ -0,0 +1,188 @@ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * $FreeBSD: releng/11.1/include/rpcsvc/nislib.h 93032 2002-03-23 17:24:55Z imp $ + */ + +/* + * Copyright (c) 1991, Sun Microsystems Inc. + */ + +/* + * This file contains the interfaces that are visible in the SunOS 5.x + * implementation of NIS Plus. + */ + +#ifndef _RPCSVC_NISLIB_H +#define _RPCSVC_NISLIB_H + +/* From: #pragma ident "@(#)nislib.h 1.16 94/05/03 SMI" */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct signature { + int signature_len; + char *signature_val; +}; + +extern void nis_freeresult(nis_result *); +extern nis_result * nis_lookup(nis_name, u_long); +extern nis_result * nis_list(nis_name, u_long, + int (*)(nis_name, nis_object *, void *), void *); +extern nis_result * nis_add(nis_name, nis_object *); +extern nis_result * nis_remove(nis_name, nis_object *); +extern nis_result * nis_modify(nis_name, nis_object *); + +extern nis_result * nis_add_entry(nis_name, nis_object *, u_long); +extern nis_result * nis_remove_entry(nis_name, nis_object *, u_long); +extern nis_result * nis_modify_entry(nis_name, nis_object *, u_long); +extern nis_result * nis_first_entry(nis_name); +extern nis_result * nis_next_entry(nis_name, netobj *); + +extern nis_error nis_mkdir(nis_name, nis_server *); +extern nis_error nis_rmdir(nis_name, nis_server *); +extern name_pos nis_dir_cmp(nis_name, nis_name); + +extern nis_name * nis_getnames(nis_name); +extern void nis_freenames(nis_name *); +extern nis_name nis_domain_of(nis_name); +extern nis_name nis_leaf_of(nis_name); +extern nis_name nis_leaf_of_r(const nis_name, char *, size_t); +extern nis_name nis_name_of(nis_name); +extern nis_name nis_local_group(void); +extern nis_name nis_local_directory(void); +extern nis_name nis_local_principal(void); +extern nis_name nis_local_host(void); + +extern void nis_destroy_object(nis_object *); +extern nis_object * nis_clone_object(nis_object *, nis_object *); +extern void nis_print_object(nis_object *); + +extern char * nis_sperrno(nis_error); +extern void nis_perror(nis_error, char *); +extern char * nis_sperror(nis_error, char *); +extern void nis_lerror(nis_error, char *); + +extern void nis_print_group_entry(nis_name); +extern bool_t nis_ismember(nis_name, nis_name); +extern nis_error nis_creategroup(nis_name, u_long); +extern nis_error nis_destroygroup(nis_name); +extern nis_error nis_addmember(nis_name, nis_name); +extern nis_error nis_removemember(nis_name, nis_name); +extern nis_error nis_verifygroup(nis_name); + +extern void nis_freeservlist(nis_server **); +extern nis_server ** nis_getservlist(nis_name); +extern nis_error nis_stats(nis_server *, nis_tag *, int, nis_tag **); +extern nis_error nis_servstate(nis_server *, nis_tag *, int, nis_tag **); +extern void nis_freetags(nis_tag *, int); + +extern nis_result * nis_checkpoint(nis_name); +extern void nis_ping(nis_name, u_long, nis_object *); + +/* + * XXX: PLEASE NOTE THAT THE FOLLOWING FUNCTIONS ARE INTERNAL + * TO NIS+ AND SHOULD NOT BE USED BY ANY APPLICATION PROGRAM. + * THEIR SEMANTICS AND/OR SIGNATURE CAN CHANGE WITHOUT NOTICE. + * SO, PLEASE DO NOT USE THEM. YOU ARE WARNED!!!! + */ + +extern char ** __break_name(nis_name, int *); +extern int __name_distance(char **, char **); +extern nis_result * nis_make_error(nis_error, u_long, u_long, u_long, u_long); +extern nis_attr * __cvt2attr(int *, char **); +extern void nis_free_request(ib_request *); +extern nis_error nis_get_request(nis_name, nis_object *, netobj*, ib_request*); +extern nis_object * nis_read_obj(char *); +extern int nis_write_obj(char *, nis_object *); +extern int nis_in_table(nis_name, NIS_HASH_TABLE *, int *); +extern int nis_insert_item(NIS_HASH_ITEM *, NIS_HASH_TABLE *); +extern NIS_HASH_ITEM * nis_find_item(nis_name, NIS_HASH_TABLE *); +extern NIS_HASH_ITEM * nis_remove_item(nis_name, NIS_HASH_TABLE *); +extern void nis_insert_name(nis_name, NIS_HASH_TABLE *); +extern void nis_remove_name(nis_name, NIS_HASH_TABLE *); +extern CLIENT * nis_make_rpchandle(nis_server *, int, u_long, u_long, u_long, + int, int); +extern void * nis_get_static_storage(struct nis_sdata *, u_long, u_long); +extern char * nis_data(char *); +extern void nis_print_rights(u_long); +extern void nis_print_directory(directory_obj *); +extern void nis_print_group(group_obj *); +extern void nis_print_table(table_obj *); +extern void nis_print_link(link_obj *); +extern void nis_print_entry(entry_obj *); +extern nis_object * nis_get_object(char *, char *, char *, u_long, u_long, + zotypes); +extern nis_server * __nis_init_callback(CLIENT *, + int (*)(nis_name, nis_object *, void *), void *); +extern int nis_getdtblsize(void); +extern int __nis_run_callback(netobj *, u_long, struct timeval *, CLIENT *); + +extern log_result *nis_dumplog(nis_server *, nis_name, u_long); +extern log_result *nis_dump(nis_server *, nis_name, + int (*)(nis_name, nis_object *, void *)); + +extern bool_t __do_ismember(nis_name, nis_name, + nis_result *(*)(nis_name, u_long)); +extern nis_name __nis_map_group(nis_name); +extern nis_name __nis_map_group_r(nis_name, char*, size_t); + +extern nis_error __nis_CacheBind(char *, directory_obj *); +extern nis_error __nis_CacheSearch(char *, directory_obj *); +extern bool_t __nis_CacheRemoveEntry(directory_obj *); +extern void __nis_CacheRestart(void); +extern void __nis_CachePrint(void); +extern void __nis_CacheDumpStatistics(void); +extern bool_t writeColdStartFile(directory_obj *); + +extern CLIENT * __get_ti_clnt(char *, CLIENT *, char **, pid_t *); +extern int __strcmp_case_insens(char *, char *); +extern int __strncmp_case_insens(char *, char *); + +extern fd_result * nis_finddirectory(directory_obj *, nis_name); +extern int __start_clock(int); +extern u_long __stop_clock(int); + +/* + * This particular function is part of the FreeBSD NIS+ implementation + * only. Ideally it should be somewhere else, but it is used by both + * rpc.nisd and nis_cachemgr, and there aren't that many headers common + * to both programs. + */ + +extern struct signature *__nis_calculate_encrypted_cksum(unsigned char *, unsigned int, char *, int); + +#define NUL '\0' + +#ifdef __cplusplus +} +#endif + +#endif /* _RPCSVC_NISLIB_H */ diff --git a/include/rpcsvc/nlm_prot.x b/include/rpcsvc/nlm_prot.x new file mode 100644 index 0000000..ce31dd9 --- /dev/null +++ b/include/rpcsvc/nlm_prot.x @@ -0,0 +1,327 @@ +/* + * Network lock manager protocol definition + * Copyright (C) 1986 Sun Microsystems, Inc. + * + * protocol used between local lock manager and remote lock manager + */ + +#ifdef RPC_HDR +%#define LM_MAXSTRLEN 1024 +%#define MAXNAMELEN LM_MAXSTRLEN+1 +#else +%#include +%#ifndef lint +%/*static char sccsid[] = "from: @(#)nlm_prot.x 1.8 87/09/21 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: * @(#)nlm_prot.x 2.1 88/08/01 4.0 RPCSRC";*/ +%__RCSID("$NetBSD: nlm_prot.x,v 1.6 2000/06/07 14:30:15 bouyer Exp $"); +%#endif /* not lint */ +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/nlm_prot.x 114629 2003-05-04 02:51:42Z obrien $"); +#endif + +/* + * status of a call to the lock manager + */ +enum nlm_stats { + nlm_granted = 0, + nlm_denied = 1, + nlm_denied_nolocks = 2, + nlm_blocked = 3, + nlm_denied_grace_period = 4, + nlm_deadlck = 5 +}; + +struct nlm_holder { + bool exclusive; + int svid; + netobj oh; + unsigned l_offset; + unsigned l_len; +}; + +union nlm_testrply switch (nlm_stats stat) { + case nlm_denied: + struct nlm_holder holder; + default: + void; +}; + +struct nlm_stat { + nlm_stats stat; +}; + +struct nlm_res { + netobj cookie; + nlm_stat stat; +}; + +struct nlm_testres { + netobj cookie; + nlm_testrply stat; +}; + +struct nlm_lock { + string caller_name; + netobj fh; /* identify a file */ + netobj oh; /* identify owner of a lock */ + int svid; /* generated from pid for svid */ + unsigned l_offset; + unsigned l_len; +}; + +struct nlm_lockargs { + netobj cookie; + bool block; + bool exclusive; + struct nlm_lock alock; + bool reclaim; /* used for recovering locks */ + int state; /* specify local status monitor state */ +}; + +struct nlm_cancargs { + netobj cookie; + bool block; + bool exclusive; + struct nlm_lock alock; +}; + +struct nlm_testargs { + netobj cookie; + bool exclusive; + struct nlm_lock alock; +}; + +struct nlm_unlockargs { + netobj cookie; + struct nlm_lock alock; +}; + + +#ifdef RPC_HDR +%/* +% * The following enums are actually bit encoded for efficient +% * boolean algebra.... DON'T change them..... +% */ +#endif +enum fsh_mode { + fsm_DN = 0, /* deny none */ + fsm_DR = 1, /* deny read */ + fsm_DW = 2, /* deny write */ + fsm_DRW = 3 /* deny read/write */ +}; + +enum fsh_access { + fsa_NONE = 0, /* for completeness */ + fsa_R = 1, /* read only */ + fsa_W = 2, /* write only */ + fsa_RW = 3 /* read/write */ +}; + +struct nlm_share { + string caller_name; + netobj fh; + netobj oh; + fsh_mode mode; + fsh_access access; +}; + +struct nlm_shareargs { + netobj cookie; + nlm_share share; + bool reclaim; +}; + +struct nlm_shareres { + netobj cookie; + nlm_stats stat; + int sequence; +}; + +struct nlm_notify { + string name; + long state; +}; + +#ifdef RPC_HDR +%/* definitions for NLM version 4 */ +#endif +enum nlm4_stats { + nlm4_granted = 0, + nlm4_denied = 1, + nlm4_denied_nolocks = 2, + nlm4_blocked = 3, + nlm4_denied_grace_period = 4, + nlm4_deadlck = 5, + nlm4_rofs = 6, + nlm4_stale_fh = 7, + nlm4_fbig = 8, + nlm4_failed = 9 +}; + +struct nlm4_stat { + nlm4_stats stat; +}; + +struct nlm4_holder { + bool exclusive; + u_int32_t svid; + netobj oh; + u_int64_t l_offset; + u_int64_t l_len; +}; + +struct nlm4_lock { + string caller_name; + netobj fh; + netobj oh; + u_int32_t svid; + u_int64_t l_offset; + u_int64_t l_len; +}; + +struct nlm4_share { + string caller_name; + netobj fh; + netobj oh; + fsh_mode mode; + fsh_access access; +}; + +union nlm4_testrply switch (nlm4_stats stat) { + case nlm_denied: + struct nlm4_holder holder; + default: + void; +}; + +struct nlm4_testres { + netobj cookie; + nlm4_testrply stat; +}; + +struct nlm4_testargs { + netobj cookie; + bool exclusive; + struct nlm4_lock alock; +}; + +struct nlm4_res { + netobj cookie; + nlm4_stat stat; +}; + +struct nlm4_lockargs { + netobj cookie; + bool block; + bool exclusive; + struct nlm4_lock alock; + bool reclaim; /* used for recovering locks */ + int state; /* specify local status monitor state */ +}; + +struct nlm4_cancargs { + netobj cookie; + bool block; + bool exclusive; + struct nlm4_lock alock; +}; + +struct nlm4_unlockargs { + netobj cookie; + struct nlm4_lock alock; +}; + +struct nlm4_shareargs { + netobj cookie; + nlm4_share share; + bool reclaim; +}; + +struct nlm4_shareres { + netobj cookie; + nlm4_stats stat; + int sequence; +}; + +/* + * argument for the procedure called by rpc.statd when a monitored host + * status change. + * XXX assumes LM_MAXSTRLEN == SM_MAXSTRLEN + */ +struct nlm_sm_status { + string mon_name; /* name of host */ + int state; /* new state */ + opaque priv[16]; /* private data */ +}; + +struct nlm4_notify { + string name; + int32_t state; +}; + +/* + * Over-the-wire protocol used between the network lock managers + */ + +program NLM_PROG { + + version NLM_SM { + void NLM_SM_NOTIFY(struct nlm_sm_status) = 1; + } = 0; + + version NLM_VERS { + + nlm_testres NLM_TEST(struct nlm_testargs) = 1; + + nlm_res NLM_LOCK(struct nlm_lockargs) = 2; + + nlm_res NLM_CANCEL(struct nlm_cancargs) = 3; + nlm_res NLM_UNLOCK(struct nlm_unlockargs) = 4; + + /* + * remote lock manager call-back to grant lock + */ + nlm_res NLM_GRANTED(struct nlm_testargs)= 5; + /* + * message passing style of requesting lock + */ + void NLM_TEST_MSG(struct nlm_testargs) = 6; + void NLM_LOCK_MSG(struct nlm_lockargs) = 7; + void NLM_CANCEL_MSG(struct nlm_cancargs) =8; + void NLM_UNLOCK_MSG(struct nlm_unlockargs) = 9; + void NLM_GRANTED_MSG(struct nlm_testargs) = 10; + void NLM_TEST_RES(nlm_testres) = 11; + void NLM_LOCK_RES(nlm_res) = 12; + void NLM_CANCEL_RES(nlm_res) = 13; + void NLM_UNLOCK_RES(nlm_res) = 14; + void NLM_GRANTED_RES(nlm_res) = 15; + } = 1; + + version NLM_VERSX { + nlm_shareres NLM_SHARE(nlm_shareargs) = 20; + nlm_shareres NLM_UNSHARE(nlm_shareargs) = 21; + nlm_res NLM_NM_LOCK(nlm_lockargs) = 22; + void NLM_FREE_ALL(nlm_notify) = 23; + } = 3; + + version NLM_VERS4 { + nlm4_testres NLM4_TEST(nlm4_testargs) = 1; + nlm4_res NLM4_LOCK(nlm4_lockargs) = 2; + nlm4_res NLM4_CANCEL(nlm4_cancargs) = 3; + nlm4_res NLM4_UNLOCK(nlm4_unlockargs) = 4; + nlm4_res NLM4_GRANTED(nlm4_testargs) = 5; + void NLM4_TEST_MSG(nlm4_testargs) = 6; + void NLM4_LOCK_MSG(nlm4_lockargs) = 7; + void NLM4_CANCEL_MSG(nlm4_cancargs) = 8; + void NLM4_UNLOCK_MSG(nlm4_unlockargs) = 9; + void NLM4_GRANTED_MSG(nlm4_testargs) = 10; + void NLM4_TEST_RES(nlm4_testres) = 11; + void NLM4_LOCK_RES(nlm4_res) = 12; + void NLM4_CANCEL_RES(nlm4_res) = 13; + void NLM4_UNLOCK_RES(nlm4_res) = 14; + void NLM4_GRANTED_RES(nlm4_res) = 15; + nlm4_shareres NLM4_SHARE(nlm4_shareargs) = 20; + nlm4_shareres NLM4_UNSHARE(nlm4_shareargs) = 21; + nlm4_res NLM4_NM_LOCK(nlm4_lockargs) = 22; + void NLM4_FREE_ALL(nlm4_notify) = 23; + } = 4; +} = 100021; diff --git a/include/rpcsvc/pmap_prot.x b/include/rpcsvc/pmap_prot.x new file mode 100644 index 0000000..2c69825 --- /dev/null +++ b/include/rpcsvc/pmap_prot.x @@ -0,0 +1,279 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ +%/* +% * Copyright (c) 1984,1989 by Sun Microsystems, Inc. +% */ + +%/* from pmap_prot.x */ + +#ifdef RPC_HDR +% +%#pragma ident "@(#)pmap_prot.x 1.6 94/04/29 SMI" +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/pmap_prot.x 114629 2003-05-04 02:51:42Z obrien $"); +% +%#ifndef _KERNEL +% +#endif + +/* + * Port Mapper Protocol Specification (in RPC Language) + * derived from RFC 1057 + */ + +%/* +% * Protocol for the local binder service, or pmap. +% * +% * Copyright (C) 1984, Sun Microsystems, Inc. +% * +% * The following procedures are supported by the protocol: +% * +% * PMAPPROC_NULL() returns () +% * takes nothing, returns nothing +% * +% * PMAPPROC_SET(struct pmap) returns (bool_t) +% * TRUE is success, FALSE is failure. Registers the tuple +% * [prog, vers, prot, port]. +% * +% * PMAPPROC_UNSET(struct pmap) returns (bool_t) +% * TRUE is success, FALSE is failure. Un-registers pair +% * [prog, vers]. prot and port are ignored. +% * +% * PMAPPROC_GETPORT(struct pmap) returns (long unsigned). +% * 0 is failure. Otherwise returns the port number where the pair +% * [prog, vers] is registered. It may lie! +% * +% * PMAPPROC_DUMP() RETURNS (struct pmaplist_ptr) +% * +% * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>) +% * RETURNS (port, string<>); +% * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, +% * encapsulatedargs); +% * Calls the procedure on the local machine. If it is not registered, +% * this procedure is quite; ie it does not return error information!!! +% * This procedure only is supported on rpc/udp and calls via +% * rpc/udp. This routine only passes null authentication parameters. +% * This file has no interface to xdr routines for PMAPPROC_CALLIT. +% * +% * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. +% */ +% +const PMAPPORT = 111; /* portmapper port number */ +% +% +%/* +% * A mapping of (program, version, protocol) to port number +% */ + +struct pmap { + unsigned long pm_prog; + unsigned long pm_vers; + unsigned long pm_prot; + unsigned long pm_port; +}; +#ifdef RPC_HDR +% +%typedef pmap PMAP; +% +#endif +% +%/* +% * Supported values for the "prot" field +% */ +% +const PMAP_IPPROTO_TCP = 6; /* protocol number for TCP/IP */ +const PMAP_IPPROTO_UDP = 17; /* protocol number for UDP/IP */ +% +% +%/* +% * A list of mappings +% * +% * Below are two definitions for the pmaplist structure. This is done because +% * xdr_pmaplist() is specified to take a struct pmaplist **, rather than a +% * struct pmaplist * that rpcgen would produce. One version of the pmaplist +% * structure (actually called pm__list) is used with rpcgen, and the other is +% * defined only in the header file for compatibility with the specified +% * interface. +% */ + +struct pm__list { + pmap pml_map; + struct pm__list *pml_next; +}; + +typedef pm__list *pmaplist_ptr; /* results of PMAPPROC_DUMP */ + +#ifdef RPC_HDR +% +%typedef struct pm__list pmaplist; +%typedef struct pm__list PMAPLIST; +% +%#ifndef __cplusplus +%struct pmaplist { +% PMAP pml_map; +% struct pmaplist *pml_next; +%}; +%#endif +% +%#ifdef __cplusplus +%extern "C" { +%#endif +%extern bool_t xdr_pmaplist(XDR *, pmaplist**); +%#ifdef __cplusplus +%} +%#endif +% +#endif + +% +%/* +% * Arguments to callit +% */ + +struct rmtcallargs { + unsigned long prog; + unsigned long vers; + unsigned long proc; + opaque args<>; +}; +#ifdef RPC_HDR +% +%/* +% * Client-side only representation of rmtcallargs structure. +% * +% * The routine that XDRs the rmtcallargs structure must deal with the +% * opaque arguments in the "args" structure. xdr_rmtcall_args() needs to be +% * passed the XDR routine that knows the args' structure. This routine +% * doesn't need to go over-the-wire (and it wouldn't make sense anyway) since +% * the application being called knows the args structure already. So we use a +% * different "XDR" structure on the client side, p_rmtcallargs, which includes +% * the args' XDR routine. +% */ +%struct p_rmtcallargs { +% u_long prog; +% u_long vers; +% u_long proc; +% struct { +% u_int args_len; +% char *args_val; +% } args; +% xdrproc_t xdr_args; /* encodes args */ +%}; +% +#endif /* def RPC_HDR */ +% +% +%/* +% * Results of callit +% */ + +struct rmtcallres { + unsigned long port; + opaque res<>; +}; +#ifdef RPC_HDR +% +%/* +% * Client-side only representation of rmtcallres structure. +% */ +%struct p_rmtcallres { +% u_long port; +% struct { +% u_int res_len; +% char *res_val; +% } res; +% xdrproc_t xdr_res; /* decodes res */ +%}; +% +#endif /* def RPC_HDR */ + +/* + * Port mapper procedures + */ + +program PMAPPROG { + version PMAPVERS { + void + PMAPPROC_NULL(void) = 0; + + bool + PMAPPROC_SET(pmap) = 1; + + bool + PMAPPROC_UNSET(pmap) = 2; + + unsigned long + PMAPPROC_GETPORT(pmap) = 3; + + pmaplist_ptr + PMAPPROC_DUMP(void) = 4; + + rmtcallres + PMAPPROC_CALLIT(rmtcallargs) = 5; + } = 2; +} = 100000; +% +#ifdef RPC_HDR +%#define PMAPVERS_PROTO ((u_long)2) +%#define PMAPVERS_ORIG ((u_long)1) +% +%#else /* ndef _KERNEL */ +% +%#include +% +%#ifdef __cplusplus +%extern "C" { +%#endif +% +%#define PMAPPORT 111 +% +%struct pmap { +% long unsigned pm_prog; +% long unsigned pm_vers; +% long unsigned pm_prot; +% long unsigned pm_port; +%}; +%typedef struct pmap PMAP; +%extern bool_t xdr_pmap (XDR *, struct pmap *); +% +%struct pmaplist { +% struct pmap pml_map; +% struct pmaplist *pml_next; +%}; +%typedef struct pmaplist PMAPLIST; +%typedef struct pmaplist *pmaplist_ptr; +% +% +%#ifdef __cplusplus +%} +%#endif +% +%#endif /* ndef _KERNEL */ +#endif + diff --git a/include/rpcsvc/rex.x b/include/rpcsvc/rex.x new file mode 100644 index 0000000..4b10627 --- /dev/null +++ b/include/rpcsvc/rex.x @@ -0,0 +1,237 @@ +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/* + * Remote execution (rex) protocol specification + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)rex.x 1.3 87/09/18 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)rex.x 2.1 88/08/01 4.0 RPCSRC";*/ +%#endif /* not lint */ +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/rex.x 259117 2013-12-09 04:26:50Z hrs $"); +#endif + +const STRINGSIZE = 1024; +typedef string rexstring<1024>; + +/* + * values to pass to REXPROC_SIGNAL + */ +const SIGINT = 2; /* interrupt */ + +/* + * Values for rst_flags, below + */ +const REX_INTERACTIVE = 1; /* interactive mode */ + +struct rex_start { + rexstring rst_cmd<>; /* list of command and args */ + rexstring rst_host; /* working directory host name */ + rexstring rst_fsname; /* working directory file system name */ + rexstring rst_dirwithin;/* working directory within file system */ + rexstring rst_env<>; /* list of environment */ + unsigned int rst_port0; /* port for stdin */ + unsigned int rst_port1; /* port for stdout */ + unsigned int rst_port2; /* port for stderr */ + unsigned int rst_flags; /* options - see const above */ +}; + +struct rex_result { + int rlt_stat; /* integer status code */ + rexstring rlt_message; /* string message for human consumption */ +}; + + +struct sgttyb { + unsigned four; /* always equals 4 */ + opaque chars[4]; + /* chars[0] == input speed */ + /* chars[1] == output speed */ + /* chars[2] == kill character */ + /* chars[3] == erase character */ + unsigned flags; +}; +/* values for speeds above (baud rates) */ +const B0 = 0; +const B50 = 1; +const B75 = 2; +const B110 = 3; +const B134 = 4; +const B150 = 5; +const B200 = 6; +const B300 = 7; +const B600 = 8; +const B1200 = 9; +const B1800 = 10; +const B2400 = 11; +const B4800 = 12; +const B9600 = 13; +const B19200 = 14; +const B38400 = 15; + +/* values for flags above */ +const TANDEM = 0x00000001; /* send stopc on out q full */ +const CBREAK = 0x00000002; /* half-cooked mode */ +const LCASE = 0x00000004; /* simulate lower case */ +const ECHO = 0x00000008; /* echo input */ +const CRMOD = 0x00000010; /* map \r to \r\n on output */ +const RAW = 0x00000020; /* no i/o processing */ +const ODDP = 0x00000040; /* get/send odd parity */ +const EVENP = 0x00000080; /* get/send even parity */ +const ANYP = 0x000000c0; /* get any parity/send none */ +const NLDELAY = 0x00000300; /* \n delay */ +const NL0 = 0x00000000; +const NL1 = 0x00000100; /* tty 37 */ +const NL2 = 0x00000200; /* vt05 */ +const NL3 = 0x00000300; +const TBDELAY = 0x00000c00; /* horizontal tab delay */ +const TAB0 = 0x00000000; +const TAB1 = 0x00000400; /* tty 37 */ +const TAB2 = 0x00000800; +const XTABS = 0x00000c00; /* expand tabs on output */ +const CRDELAY = 0x00003000; /* \r delay */ +const CR0 = 0x00000000; +const CR1 = 0x00001000; /* tn 300 */ +const CR2 = 0x00002000; /* tty 37 */ +const CR3 = 0x00003000; /* concept 100 */ +const VTDELAY = 0x00004000; /* vertical tab delay */ +const FF0 = 0x00000000; +const FF1 = 0x00004000; /* tty 37 */ +const BSDELAY = 0x00008000; /* \b delay */ +const BS0 = 0x00000000; +const BS1 = 0x00008000; +const CRTBS = 0x00010000; /* do backspacing for crt */ +const PRTERA = 0x00020000; /* \ ... / erase */ +const CRTERA = 0x00040000; /* " \b " to wipe out char */ +const TILDE = 0x00080000; /* hazeltine tilde kludge */ +const MDMBUF = 0x00100000; /* start/stop output on carrier intr */ +const LITOUT = 0x00200000; /* literal output */ +const TOSTOP = 0x00400000; /* SIGTTOU on background output */ +const FLUSHO = 0x00800000; /* flush output to terminal */ +const NOHANG = 0x01000000; /* no SIGHUP on carrier drop */ +const L001000 = 0x02000000; +const CRTKIL = 0x04000000; /* kill line with " \b " */ +const PASS8 = 0x08000000; +const CTLECH = 0x10000000; /* echo control chars as ^X */ +const PENDIN = 0x20000000; /* tp->t_rawq needs reread */ +const DECCTQ = 0x40000000; /* only ^Q starts after ^S */ +const NOFLSH = 0x80000000; /* no output flush on signal */ + +struct tchars { + unsigned six; /* always equals 6 */ + opaque chars[6]; + /* chars[0] == interrupt char */ + /* chars[1] == quit char */ + /* chars[2] == start output char */ + /* chars[3] == stop output char */ + /* chars[4] == end-of-file char */ + /* chars[5] == input delimeter (like nl) */ +}; + +struct ltchars { + unsigned six; /* always equals 6 */ + opaque chars[6]; + /* chars[0] == stop process signal */ + /* chars[1] == delayed stop process signal */ + /* chars[2] == reprint line */ + /* chars[3] == flush output */ + /* chars[4] == word erase */ + /* chars[5] == literal next character */ + unsigned mode; +}; + +struct rex_ttysize { + int ts_lines; + int ts_cols; +}; + +struct rex_ttymode { + sgttyb basic; /* standard unix tty flags */ + tchars more; /* interrupt, kill characters, etc. */ + ltchars yetmore; /* special Berkeley characters */ + unsigned andmore; /* and Berkeley modes */ +}; + +/* values for andmore above */ +const LCRTBS = 0x0001; /* do backspacing for crt */ +const LPRTERA = 0x0002; /* \ ... / erase */ +const LCRTERA = 0x0004; /* " \b " to wipe out char */ +const LTILDE = 0x0008; /* hazeltine tilde kludge */ +const LMDMBUF = 0x0010; /* start/stop output on carrier intr */ +const LLITOUT = 0x0020; /* literal output */ +const LTOSTOP = 0x0040; /* SIGTTOU on background output */ +const LFLUSHO = 0x0080; /* flush output to terminal */ +const LNOHANG = 0x0100; /* no SIGHUP on carrier drop */ +const LL001000 = 0x0200; +const LCRTKIL = 0x0400; /* kill line with " \b " */ +const LPASS8 = 0x0800; +const LCTLECH = 0x1000; /* echo control chars as ^X */ +const LPENDIN = 0x2000; /* needs reread */ +const LDECCTQ = 0x4000; /* only ^Q starts after ^S */ +const LNOFLSH = 0x8000; /* no output flush on signal */ + +program REXPROG { + version REXVERS { + + /* + * Start remote execution + */ + rex_result + REXPROC_START(rex_start) = 1; + + /* + * Wait for remote execution to terminate + */ + rex_result + REXPROC_WAIT(void) = 2; + + /* + * Send tty modes + */ + void + REXPROC_MODES(rex_ttymode) = 3; + + /* + * Send window size change + */ + void + REXPROC_WINCH(rex_ttysize) = 4; + + /* + * Send other signal + */ + void + REXPROC_SIGNAL(int) = 5; + } = 1; +} = 100017; diff --git a/include/rpcsvc/rnusers.x b/include/rpcsvc/rnusers.x new file mode 100644 index 0000000..34d5632 --- /dev/null +++ b/include/rpcsvc/rnusers.x @@ -0,0 +1,125 @@ +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/* + * Find out about remote users + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)rnusers.x 1.2 87/09/20 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)rnusers.x 2.1 88/08/01 4.0 RPCSRC";*/ +%#endif /* not lint */ +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/rnusers.x 259117 2013-12-09 04:26:50Z hrs $"); +#endif + +const MAXUSERS = 100; +const MAXUTLEN = 256; + +struct utmp { + string ut_line; + string ut_name; + string ut_host; + int ut_time; +}; + + +struct utmpidle { + utmp ui_utmp; + unsigned int ui_idle; +}; + +typedef utmp utmparr; + +typedef utmpidle utmpidlearr; + +const RUSERS_MAXUSERLEN = 32; +const RUSERS_MAXLINELEN = 32; +const RUSERS_MAXHOSTLEN = 257; + +struct rusers_utmp { + string ut_user; /* aka ut_name */ + string ut_line; /* device */ + string ut_host; /* host user logged on from */ + int ut_type; /* type of entry */ + int ut_time; /* time entry was made */ + unsigned int ut_idle; /* minutes idle */ +}; + +typedef rusers_utmp utmp_array<>; + +program RUSERSPROG { + /* + * Old version does not include idle information + */ + version RUSERSVERS_ORIG { + int + RUSERSPROC_NUM(void) = 1; + + utmparr + RUSERSPROC_NAMES(void) = 2; + + utmparr + RUSERSPROC_ALLNAMES(void) = 3; + } = 1; + + /* + * Includes idle information + */ + version RUSERSVERS_IDLE { + int + RUSERSPROC_NUM(void) = 1; + + utmpidlearr + RUSERSPROC_NAMES(void) = 2; + + utmpidlearr + RUSERSPROC_ALLNAMES(void) = 3; + } = 2; + + /* + * Version 3 rusers procedures (from Solaris). + * (Thanks a lot Sun.) + */ + version RUSERSVERS_3 { + int + RUSERSPROC_NUM(void) = 1; + + utmp_array + RUSERSPROC_NAMES(void) = 2; + + utmp_array + RUSERSPROC_ALLNAMES(void) = 3; + } = 3; + +} = 100002; + diff --git a/include/rpcsvc/rquota.x b/include/rpcsvc/rquota.x new file mode 100644 index 0000000..6b44ded --- /dev/null +++ b/include/rpcsvc/rquota.x @@ -0,0 +1,67 @@ +/* + * Remote quota protocol + * Requires unix authentication + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)rquota.x 1.2 87/09/20 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)rquota.x 2.1 88/08/01 4.0 RPCSRC";*/ +%#endif /* not lint */ +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/rquota.x 114629 2003-05-04 02:51:42Z obrien $"); +#endif + +const RQ_PATHLEN = 1024; + +struct getquota_args { + string gqa_pathp; /* path to filesystem of interest */ + int gqa_uid; /* inquire about quota for uid */ +}; + +/* + * remote quota structure + */ +struct rquota { + int rq_bsize; /* block size for block counts */ + bool rq_active; /* indicates whether quota is active */ + unsigned int rq_bhardlimit; /* absolute limit on disk blks alloc */ + unsigned int rq_bsoftlimit; /* preferred limit on disk blks */ + unsigned int rq_curblocks; /* current block count */ + unsigned int rq_fhardlimit; /* absolute limit on allocated files */ + unsigned int rq_fsoftlimit; /* preferred file limit */ + unsigned int rq_curfiles; /* current # allocated files */ + unsigned int rq_btimeleft; /* time left for excessive disk use */ + unsigned int rq_ftimeleft; /* time left for excessive files */ +}; + +enum gqr_status { + Q_OK = 1, /* quota returned */ + Q_NOQUOTA = 2, /* noquota for uid */ + Q_EPERM = 3 /* no permission to access quota */ +}; + +union getquota_rslt switch (gqr_status status) { +case Q_OK: + rquota gqr_rquota; /* valid if status == Q_OK */ +case Q_NOQUOTA: + void; +case Q_EPERM: + void; +}; + +program RQUOTAPROG { + version RQUOTAVERS { + /* + * Get all quotas + */ + getquota_rslt + RQUOTAPROC_GETQUOTA(getquota_args) = 1; + + /* + * Get active quotas only + */ + getquota_rslt + RQUOTAPROC_GETACTIVEQUOTA(getquota_args) = 2; + } = 1; +} = 100011; diff --git a/include/rpcsvc/rstat.x b/include/rpcsvc/rstat.x new file mode 100644 index 0000000..504fddc --- /dev/null +++ b/include/rpcsvc/rstat.x @@ -0,0 +1,160 @@ +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/* + * Gather statistics on remote machines + */ + +#ifdef RPC_HDR + +%#ifndef FSCALE +%/* +% * Scale factor for scaled integers used to count load averages. +% */ +%#define FSHIFT 8 /* bits to right of fixed binary point */ +%#define FSCALE (1< +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/rstat.x 259117 2013-12-09 04:26:50Z hrs $"); + +#endif /* def RPC_HDR */ + +const RSTAT_CPUSTATES = 4; +const RSTAT_DK_NDRIVE = 4; + +/* + * GMT since 0:00, January 1, 1970 + */ +struct rstat_timeval { + unsigned int tv_sec; /* seconds */ + unsigned int tv_usec; /* and microseconds */ +}; + +struct statstime { /* RSTATVERS_TIME */ + int cp_time[RSTAT_CPUSTATES]; + int dk_xfer[RSTAT_DK_NDRIVE]; + unsigned int v_pgpgin; /* these are cumulative sum */ + unsigned int v_pgpgout; + unsigned int v_pswpin; + unsigned int v_pswpout; + unsigned int v_intr; + int if_ipackets; + int if_ierrors; + int if_oerrors; + int if_collisions; + unsigned int v_swtch; + int avenrun[3]; /* scaled by FSCALE */ + rstat_timeval boottime; + rstat_timeval curtime; + int if_opackets; +}; + +struct statsswtch { /* RSTATVERS_SWTCH */ + int cp_time[RSTAT_CPUSTATES]; + int dk_xfer[RSTAT_DK_NDRIVE]; + unsigned int v_pgpgin; /* these are cumulative sum */ + unsigned int v_pgpgout; + unsigned int v_pswpin; + unsigned int v_pswpout; + unsigned int v_intr; + int if_ipackets; + int if_ierrors; + int if_oerrors; + int if_collisions; + unsigned int v_swtch; + unsigned int avenrun[3];/* scaled by FSCALE */ + rstat_timeval boottime; + int if_opackets; +}; + +struct stats { /* RSTATVERS_ORIG */ + int cp_time[RSTAT_CPUSTATES]; + int dk_xfer[RSTAT_DK_NDRIVE]; + unsigned int v_pgpgin; /* these are cumulative sum */ + unsigned int v_pgpgout; + unsigned int v_pswpin; + unsigned int v_pswpout; + unsigned int v_intr; + int if_ipackets; + int if_ierrors; + int if_oerrors; + int if_collisions; + int if_opackets; +}; + + +program RSTATPROG { + /* + * Newest version includes current time and context switching info + */ + version RSTATVERS_TIME { + statstime + RSTATPROC_STATS(void) = 1; + + unsigned int + RSTATPROC_HAVEDISK(void) = 2; + } = 3; + /* + * Does not have current time + */ + version RSTATVERS_SWTCH { + statsswtch + RSTATPROC_STATS(void) = 1; + + unsigned int + RSTATPROC_HAVEDISK(void) = 2; + } = 2; + /* + * Old version has no info about current time or context switching + */ + version RSTATVERS_ORIG { + stats + RSTATPROC_STATS(void) = 1; + + unsigned int + RSTATPROC_HAVEDISK(void) = 2; + } = 1; +} = 100001; + +#ifdef RPC_HDR +% +%enum clnt_stat rstat(char *, struct statstime *); +%int havedisk(char *); +% +#endif diff --git a/include/rpcsvc/rwall.x b/include/rpcsvc/rwall.x new file mode 100644 index 0000000..6c26c1f --- /dev/null +++ b/include/rpcsvc/rwall.x @@ -0,0 +1,57 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user or with the express written consent of +% * Sun Microsystems, Inc. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ + +%/* +% * Copyright (c) 1984, 1990 by Sun Microsystems, Inc. +% */ +% +%/* from @(#)rwall.x 1.6 91/03/11 TIRPC 1.0 */ + +#ifdef RPC_HDR +% +%#ifndef _rpcsvc_rwall_h +%#define _rpcsvc_rwall_h +% +%typedef char *wrapstring; +% +#endif + +program WALLPROG { + version WALLVERS { + void + WALLPROC_WALL(wrapstring) = 2; + + } = 1; +} = 100008; + +#ifdef RPC_HDR +% +%#endif /* ! _rpcsvc_rwall_h */ +#endif diff --git a/include/rpcsvc/sm_inter.x b/include/rpcsvc/sm_inter.x new file mode 100644 index 0000000..0bf01e2 --- /dev/null +++ b/include/rpcsvc/sm_inter.x @@ -0,0 +1,127 @@ +/* @(#)sm_inter.x 2.2 88/08/01 4.0 RPCSRC */ +/* @(#)sm_inter.x 1.7 87/06/24 Copyr 1987 Sun Micro */ + +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/* + * Status monitor protocol specification + * Copyright (C) 1986 Sun Microsystems, Inc. + * + */ + +#ifndef RPC_HDR +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/sm_inter.x 259117 2013-12-09 04:26:50Z hrs $"); +#endif + +program SM_PROG { + version SM_VERS { + /* res_stat = stat_succ if status monitor agrees to monitor */ + /* res_stat = stat_fail if status monitor cannot monitor */ + /* if res_stat == stat_succ, state = state number of site sm_name */ + struct sm_stat_res SM_STAT(struct sm_name) = 1; + + /* res_stat = stat_succ if status monitor agrees to monitor */ + /* res_stat = stat_fail if status monitor cannot monitor */ + /* stat consists of state number of local site */ + struct sm_stat_res SM_MON(struct mon) = 2; + + /* stat consists of state number of local site */ + struct sm_stat SM_UNMON(struct mon_id) = 3; + + /* stat consists of state number of local site */ + struct sm_stat SM_UNMON_ALL(struct my_id) = 4; + + void SM_SIMU_CRASH(void) = 5; + void SM_NOTIFY(struct stat_chge) = 6; + + } = 1; +} = 100024; + +const SM_MAXSTRLEN = 1024; + +struct sm_name { + string mon_name; +}; + +struct my_id { + string my_name; /* name of the site iniates the monitoring request*/ + int my_prog; /* rpc program # of the requesting process */ + int my_vers; /* rpc version # of the requesting process */ + int my_proc; /* rpc procedure # of the requesting process */ +}; + +struct mon_id { + string mon_name; /* name of the site to be monitored */ + struct my_id my_id; +}; + + +struct mon{ + struct mon_id mon_id; + opaque priv[16]; /* private information to store at monitor for requesting process */ +}; + +struct stat_chge { + string mon_name; /* name of the site that had the state change */ + int state; +}; + +/* + * state # of status monitor monitonically increases each time + * status of the site changes: + * an even number (>= 0) indicates the site is down and + * an odd number (> 0) indicates the site is up; + */ +struct sm_stat { + int state; /* state # of status monitor */ +}; + +enum sm_res { + stat_succ = 0, /* status monitor agrees to monitor */ + stat_fail = 1 /* status monitor cannot monitor */ +}; + +struct sm_stat_res { + sm_res res_stat; + int state; +}; + +/* + * structure of the status message sent back by the status monitor + * when monitor site status changes + */ +struct sm_status { + string mon_name; + int state; + opaque priv[16]; /* stored private information */ +}; diff --git a/include/rpcsvc/spray.x b/include/rpcsvc/spray.x new file mode 100644 index 0000000..7b763ac --- /dev/null +++ b/include/rpcsvc/spray.x @@ -0,0 +1,92 @@ +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/* + * Spray a server with packets + * Useful for testing flakiness of network interfaces + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)spray.x 1.2 87/09/18 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)spray.x 2.1 88/08/01 4.0 RPCSRC";*/ +%#endif /* not lint */ +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/spray.x 259117 2013-12-09 04:26:50Z hrs $"); +#endif + +const SPRAYMAX = 8845; /* max amount can spray */ + +/* + * GMT since 0:00, 1 January 1970 + */ +struct spraytimeval { + unsigned int sec; + unsigned int usec; +}; + +/* + * spray statistics + */ +struct spraycumul { + unsigned int counter; + spraytimeval clock; +}; + +/* + * spray data + */ +typedef opaque sprayarr; + +program SPRAYPROG { + version SPRAYVERS { + /* + * Just throw away the data and increment the counter + * This call never returns, so the client should always + * time it out. + */ + void + SPRAYPROC_SPRAY(sprayarr) = 1; + + /* + * Get the value of the counter and elapsed time since + * last CLEAR. + */ + spraycumul + SPRAYPROC_GET(void) = 2; + + /* + * Clear the counter and reset the elapsed time + */ + void + SPRAYPROC_CLEAR(void) = 3; + } = 1; +} = 100012; diff --git a/include/rpcsvc/yp.x b/include/rpcsvc/yp.x new file mode 100644 index 0000000..6339edc --- /dev/null +++ b/include/rpcsvc/yp.x @@ -0,0 +1,379 @@ +/* @(#)yp.x 2.1 88/08/01 4.0 RPCSRC */ + +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/* + * Protocol description file for the Yellow Pages Service + */ + +#ifndef RPC_HDR +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/yp.x 259117 2013-12-09 04:26:50Z hrs $"); +#endif + +const YPMAXRECORD = 1024; +const YPMAXDOMAIN = 64; +const YPMAXMAP = 64; +const YPMAXPEER = 64; + + +enum ypstat { + YP_TRUE = 1, + YP_NOMORE = 2, + YP_FALSE = 0, + YP_NOMAP = -1, + YP_NODOM = -2, + YP_NOKEY = -3, + YP_BADOP = -4, + YP_BADDB = -5, + YP_YPERR = -6, + YP_BADARGS = -7, + YP_VERS = -8 +}; + + +enum ypxfrstat { + YPXFR_SUCC = 1, + YPXFR_AGE = 2, + YPXFR_NOMAP = -1, + YPXFR_NODOM = -2, + YPXFR_RSRC = -3, + YPXFR_RPC = -4, + YPXFR_MADDR = -5, + YPXFR_YPERR = -6, + YPXFR_BADARGS = -7, + YPXFR_DBM = -8, + YPXFR_FILE = -9, + YPXFR_SKEW = -10, + YPXFR_CLEAR = -11, + YPXFR_FORCE = -12, + YPXFR_XFRERR = -13, + YPXFR_REFUSED = -14 +}; + + +typedef string domainname; +typedef string mapname; +typedef string peername; +typedef opaque keydat; +typedef opaque valdat; + + +struct ypmap_parms { + domainname domain; + mapname map; + unsigned int ordernum; + peername peer; +}; + +struct ypreq_key { + domainname domain; + mapname map; + keydat key; +}; + +struct ypreq_nokey { + domainname domain; + mapname map; +}; + +struct ypreq_xfr { + ypmap_parms map_parms; + unsigned int transid; + unsigned int prog; + unsigned int port; +}; + + +struct ypresp_val { + ypstat stat; + valdat val; +}; + +struct ypresp_key_val { + ypstat stat; +#ifdef STUPID_SUN_BUG /* These are backwards */ + keydat key; + valdat val; +#else + valdat val; + keydat key; +#endif +}; + + +struct ypresp_master { + ypstat stat; + peername peer; +}; + +struct ypresp_order { + ypstat stat; + unsigned int ordernum; +}; + +union ypresp_all switch (bool more) { +case TRUE: + ypresp_key_val val; +case FALSE: + void; +}; + +struct ypresp_xfr { + unsigned int transid; + ypxfrstat xfrstat; +}; + +struct ypmaplist { + mapname map; + ypmaplist *next; +}; + +struct ypresp_maplist { + ypstat stat; + ypmaplist *maps; +}; + +enum yppush_status { + YPPUSH_SUCC = 1, /* Success */ + YPPUSH_AGE = 2, /* Master's version not newer */ + YPPUSH_NOMAP = -1, /* Can't find server for map */ + YPPUSH_NODOM = -2, /* Domain not supported */ + YPPUSH_RSRC = -3, /* Local resource alloc failure */ + YPPUSH_RPC = -4, /* RPC failure talking to server */ + YPPUSH_MADDR = -5, /* Can't get master address */ + YPPUSH_YPERR = -6, /* YP server/map db error */ + YPPUSH_BADARGS = -7, /* Request arguments bad */ + YPPUSH_DBM = -8, /* Local dbm operation failed */ + YPPUSH_FILE = -9, /* Local file I/O operation failed */ + YPPUSH_SKEW = -10, /* Map version skew during transfer */ + YPPUSH_CLEAR = -11, /* Can't send "Clear" req to local ypserv */ + YPPUSH_FORCE = -12, /* No local order number in map use -f flag. */ + YPPUSH_XFRERR = -13, /* ypxfr error */ + YPPUSH_REFUSED = -14 /* Transfer request refused by ypserv */ +}; + +struct yppushresp_xfr { + unsigned transid; + yppush_status status; +}; + +/* + * Response structure and overall result status codes. Success and failure + * represent two separate response message types. + */ + +enum ypbind_resptype { + YPBIND_SUCC_VAL = 1, + YPBIND_FAIL_VAL = 2 +}; + +struct ypbind_binding { + opaque ypbind_binding_addr[4]; /* In network order */ + opaque ypbind_binding_port[2]; /* In network order */ +}; + +union ypbind_resp switch (ypbind_resptype ypbind_status) { +case YPBIND_FAIL_VAL: + unsigned ypbind_error; +case YPBIND_SUCC_VAL: + ypbind_binding ypbind_bindinfo; +}; + +/* Detailed failure reason codes for response field ypbind_error*/ + +const YPBIND_ERR_ERR = 1; /* Internal error */ +const YPBIND_ERR_NOSERV = 2; /* No bound server for passed domain */ +const YPBIND_ERR_RESC = 3; /* System resource allocation failure */ + + +/* + * Request data structure for ypbind "Set domain" procedure. + */ +struct ypbind_setdom { + domainname ypsetdom_domain; + ypbind_binding ypsetdom_binding; + unsigned ypsetdom_vers; +}; + + +/* + * NIS v1 support for backwards compatibility + */ +enum ypreqtype { + YPREQ_KEY = 1, + YPREQ_NOKEY = 2, + YPREQ_MAP_PARMS = 3 +}; + +enum ypresptype { + YPRESP_VAL = 1, + YPRESP_KEY_VAL = 2, + YPRESP_MAP_PARMS = 3 +}; + +union yprequest switch (ypreqtype yp_reqtype) { +case YPREQ_KEY: + ypreq_key yp_req_keytype; +case YPREQ_NOKEY: + ypreq_nokey yp_req_nokeytype; +case YPREQ_MAP_PARMS: + ypmap_parms yp_req_map_parmstype; +}; + +union ypresponse switch (ypresptype yp_resptype) { +case YPRESP_VAL: + ypresp_val yp_resp_valtype; +case YPRESP_KEY_VAL: + ypresp_key_val yp_resp_key_valtype; +case YPRESP_MAP_PARMS: + ypmap_parms yp_resp_map_parmstype; +}; + +#if !defined(YPBIND_ONLY) && !defined(YPPUSH_ONLY) +/* + * YP access protocol + */ +program YPPROG { +/* + * NIS v1 support for backwards compatibility + */ + version YPOLDVERS { + void + YPOLDPROC_NULL(void) = 0; + + bool + YPOLDPROC_DOMAIN(domainname) = 1; + + bool + YPOLDPROC_DOMAIN_NONACK(domainname) = 2; + + ypresponse + YPOLDPROC_MATCH(yprequest) = 3; + + ypresponse + YPOLDPROC_FIRST(yprequest) = 4; + + ypresponse + YPOLDPROC_NEXT(yprequest) = 5; + + ypresponse + YPOLDPROC_POLL(yprequest) = 6; + + ypresponse + YPOLDPROC_PUSH(yprequest) = 7; + + ypresponse + YPOLDPROC_PULL(yprequest) = 8; + + ypresponse + YPOLDPROC_GET(yprequest) = 9; + } = 1; + + version YPVERS { + void + YPPROC_NULL(void) = 0; + + bool + YPPROC_DOMAIN(domainname) = 1; + + bool + YPPROC_DOMAIN_NONACK(domainname) = 2; + + ypresp_val + YPPROC_MATCH(ypreq_key) = 3; + + ypresp_key_val +#ifdef STUPID_SUN_BUG /* should be ypreq_nokey */ + YPPROC_FIRST(ypreq_key) = 4; +#else + YPPROC_FIRST(ypreq_nokey) = 4; +#endif + ypresp_key_val + YPPROC_NEXT(ypreq_key) = 5; + + ypresp_xfr + YPPROC_XFR(ypreq_xfr) = 6; + + void + YPPROC_CLEAR(void) = 7; + + ypresp_all + YPPROC_ALL(ypreq_nokey) = 8; + + ypresp_master + YPPROC_MASTER(ypreq_nokey) = 9; + + ypresp_order + YPPROC_ORDER(ypreq_nokey) = 10; + + ypresp_maplist + YPPROC_MAPLIST(domainname) = 11; + } = 2; +} = 100004; +#endif +#if !defined(YPSERV_ONLY) && !defined(YPBIND_ONLY) +/* + * YPPUSHPROC_XFRRESP is the callback routine for result of YPPROC_XFR + */ +program YPPUSH_XFRRESPPROG { + version YPPUSH_XFRRESPVERS { + void + YPPUSHPROC_NULL(void) = 0; +#ifdef STUPID_SUN_BUG /* argument and return value are backwards */ + yppushresp_xfr + YPPUSHPROC_XFRRESP(void) = 1; +#else + void + YPPUSHPROC_XFRRESP(yppushresp_xfr) = 1; +#endif + } = 1; +} = 0x40000000; /* transient: could be anything up to 0x5fffffff */ +#endif +#if !defined(YPSERV_ONLY) && !defined(YPPUSH_ONLY) +/* + * YP binding protocol + */ +program YPBINDPROG { + version YPBINDVERS { + void + YPBINDPROC_NULL(void) = 0; + + ypbind_resp + YPBINDPROC_DOMAIN(domainname) = 1; + + void + YPBINDPROC_SETDOM(ypbind_setdom) = 2; + } = 2; +} = 100007; + +#endif diff --git a/include/rpcsvc/yp_prot.h b/include/rpcsvc/yp_prot.h new file mode 100644 index 0000000..591e9ae --- /dev/null +++ b/include/rpcsvc/yp_prot.h @@ -0,0 +1,329 @@ +/* + * Copyright (c) 1992/3 Theo de Raadt + * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/rpcsvc/yp_prot.h 153149 2005-12-06 02:01:06Z peter $ + */ + +#ifndef _RPCSVC_YP_PROT_H_ +#define _RPCSVC_YP_PROT_H_ + +/* + * YPSERV PROTOCOL: + * + * ypserv supports the following procedures: + * + * YPPROC_NULL takes (void), returns (void). + * called to check if server is alive. + * YPPROC_DOMAIN takes (char *), returns (bool_t). + * true if ypserv serves the named domain. + * YPPROC_DOMAIN_NOACK takes (char *), returns (bool_t). + * true if ypserv serves the named domain. + * used for broadcasts, does not ack if ypserv + * doesn't handle named domain. + * YPPROC_MATCH takes (struct ypreq_key), returns (struct ypresp_val) + * does a lookup. + * YPPROC_FIRST takes (struct ypreq_nokey) returns (ypresp_key_val). + * gets the first key/datum from the map. + * YPPROC_NEXT takes (struct ypreq_key) returns (ypresp_key_val). + * gets the next key/datum from the map. + * YPPROC_XFR takes (struct ypreq_xfr), returns (void). + * tells ypserv to check if there is a new version of + * the map. + * YPPROC_CLEAR takes (void), returns (void). + * tells ypserv to flush it's file cache, so that + * newly transferred files will get read. + * YPPROC_ALL takes (struct ypreq_nokey), returns (bool_t and + * struct ypresp_key_val). + * returns an array of data, with the bool_t being + * false on the last datum. read the source, it's + * convoluted. + * YPPROC_MASTER takes (struct ypreq_nokey), returns (ypresp_master). + * YPPROC_ORDER takes (struct ypreq_nokey), returns (ypresp_order). + * YPPROC_MAPLIST takes (char *), returns (struct ypmaplist *). + */ + +#ifndef BOOL_DEFINED +typedef u_int bool; +#define BOOL_DEFINED +#endif + +/* Program and version symbols, magic numbers */ + +#define YPPROG ((u_long)100004) +#define YPVERS ((u_long)2) +#define YPVERS_ORIG ((u_long)1) +#define YPMAXRECORD ((u_long)1024) +#define YPMAXDOMAIN ((u_long)64) +#define YPMAXMAP ((u_long)64) +#define YPMAXPEER ((u_long)256) + +/* + * I don't know if anything of sun's depends on this, or if they + * simply defined it so that their own code wouldn't try to send + * packets over the ethernet MTU. This YP code doesn't use it. + */ +#define YPMSGSZ 1600 + +#ifndef DATUM +typedef struct { + char *dptr; + int dsize; +} datum; +#define DATUM +#endif + +struct ypmap_parms { + char *domain; + char *map; + u_int ordernum; + char *owner; +}; + +struct ypreq_key { + char *domain; + char *map; + datum keydat; +}; + +struct ypreq_nokey { + char *domain; + char *map; +}; + +struct ypreq_xfr { + struct ypmap_parms map_parms; + u_int transid; + u_int proto; + u_int port; +}; +#define ypxfr_domain map_parms.domain +#define ypxfr_map map_parms.map +#define ypxfr_ordernum map_parms.ordernum +#define ypxfr_owner map_parms.owner + +struct ypresp_val { + u_int status; + datum valdat; +}; + +struct ypresp_key_val { + u_int status; + datum keydat; + datum valdat; +}; + +struct ypresp_master { + u_int status; + char *master; +}; + +struct ypresp_order { + u_int status; + u_int ordernum; +}; + +struct ypmaplist { + char *ypml_name; + struct ypmaplist *ypml_next; +}; + +struct ypresp_maplist { + u_int status; + struct ypmaplist *list; +}; + +/* ypserv procedure numbers */ +#define YPPROC_NULL ((u_long)0) +#define YPPROC_DOMAIN ((u_long)1) +#define YPPROC_DOMAIN_NONACK ((u_long)2) +#define YPPROC_MATCH ((u_long)3) +#define YPPROC_FIRST ((u_long)4) +#define YPPROC_NEXT ((u_long)5) +#define YPPROC_XFR ((u_long)6) +#define YPPROC_CLEAR ((u_long)7) +#define YPPROC_ALL ((u_long)8) +#define YPPROC_MASTER ((u_long)9) +#define YPPROC_ORDER ((u_long)10) +#define YPPROC_MAPLIST ((u_long)11) + +/* ypserv procedure return status values */ +#define YP_TRUE ((long)1) /* general purpose success code */ +#define YP_NOMORE ((long)2) /* no more entries in map */ +#define YP_FALSE ((long)0) /* general purpose failure code */ +#define YP_NOMAP ((long)-1) /* no such map in domain */ +#define YP_NODOM ((long)-2) /* domain not supported */ +#define YP_NOKEY ((long)-3) /* no such key in map */ +#define YP_BADOP ((long)-4) /* invalid operation */ +#define YP_BADDB ((long)-5) /* server data base is bad */ +#define YP_YPERR ((long)-6) /* YP server error */ +#define YP_BADARGS ((long)-7) /* request arguments bad */ +#define YP_VERS ((long)-8) /* YP server version mismatch */ + +/* + * Sun's header file says: + * "Domain binding data structure, used by ypclnt package and ypserv modules. + * Users of the ypclnt package (or of this protocol) don't HAVE to know about + * it, but it must be available to users because _yp_dobind is a public + * interface." + * + * This is totally bogus! Nowhere else does Sun state that _yp_dobind() is + * a public interface, and I don't know any reason anyone would want to call + * it. But, just in case anyone does actually expect it to be available.. + * we provide this.. exactly as Sun wants it. + */ +struct dom_binding { + struct dom_binding *dom_pnext; + char dom_domain[YPMAXDOMAIN + 1]; + struct sockaddr_in dom_server_addr; + u_short dom_server_port; + int dom_socket; + CLIENT *dom_client; + u_short dom_local_port; + long dom_vers; +}; + +/* + * YPBIND PROTOCOL: + * + * ypbind supports the following procedures: + * + * YPBINDPROC_NULL takes (void), returns (void). + * to check if ypbind is running. + * YPBINDPROC_DOMAIN takes (char *), returns (struct ypbind_resp). + * requests that ypbind start to serve the + * named domain (if it doesn't already) + * YPBINDPROC_SETDOM takes (struct ypbind_setdom), returns (void). + * used by ypset. + */ + +#define YPBINDPROG ((u_long)100007) +#define YPBINDVERS ((u_long)2) +#define YPBINDVERS_ORIG ((u_long)1) + +/* ypbind procedure numbers */ +#define YPBINDPROC_NULL ((u_long)0) +#define YPBINDPROC_DOMAIN ((u_long)1) +#define YPBINDPROC_SETDOM ((u_long)2) + +/* error code in ypbind_resp.ypbind_status */ +enum ypbind_resptype { + YPBIND_SUCC_VAL = 1, + YPBIND_FAIL_VAL = 2 +}; + +/* network order, of course */ +struct ypbind_binding { + struct in_addr ypbind_binding_addr; + u_short ypbind_binding_port; +}; + +struct ypbind_resp { + enum ypbind_resptype ypbind_status; + union { + u_int ypbind_error; + struct ypbind_binding ypbind_bindinfo; + } ypbind_respbody; +}; + +/* error code in ypbind_resp.ypbind_respbody.ypbind_error */ +#define YPBIND_ERR_ERR 1 /* internal error */ +#define YPBIND_ERR_NOSERV 2 /* no bound server for passed domain */ +#define YPBIND_ERR_RESC 3 /* system resource allocation failure */ + +/* + * Request data structure for ypbind "Set domain" procedure. + */ +struct ypbind_setdom { + char ypsetdom_domain[YPMAXDOMAIN + 1]; + struct ypbind_binding ypsetdom_binding; + u_int ypsetdom_vers; +}; +#define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr +#define ypsetdom_port ypsetdom_binding.ypbind_binding_port + +/* + * YPPUSH PROTOCOL: + * + * Sun says: + * "Protocol between clients (ypxfr, only) and yppush + * yppush speaks a protocol in the transient range, which + * is supplied to ypxfr as a command-line parameter when it + * is activated by ypserv." + * + * This protocol is not implemented, naturally, because this YP + * implementation only does the client side. + */ +#define YPPUSHVERS ((u_long)1) +#define YPPUSHVERS_ORIG ((u_long)1) + +/* yppush procedure numbers */ +#define YPPUSHPROC_NULL ((u_long)0) +#define YPPUSHPROC_XFRRESP ((u_long)1) + +struct yppushresp_xfr { + u_int transid; + u_int status; +}; + +/* yppush status value in yppushresp_xfr.status */ +#define YPPUSH_SUCC ((long)1) /* Success */ +#define YPPUSH_AGE ((long)2) /* Master's version not newer */ +#define YPPUSH_NOMAP ((long)-1) /* Can't find server for map */ +#define YPPUSH_NODOM ((long)-2) /* Domain not supported */ +#define YPPUSH_RSRC ((long)-3) /* Local resource alloc failure */ +#define YPPUSH_RPC ((long)-4) /* RPC failure talking to server */ +#define YPPUSH_MADDR ((long)-5) /* Can't get master address */ +#define YPPUSH_YPERR ((long)-6) /* YP server/map db error */ +#define YPPUSH_BADARGS ((long)-7) /* Request arguments bad */ +#define YPPUSH_DBM ((long)-8) /* Local dbm operation failed */ +#define YPPUSH_FILE ((long)-9) /* Local file I/O operation failed */ +#define YPPUSH_SKEW ((long)-10) /* Map version skew during transfer */ +#define YPPUSH_CLEAR ((long)-11) /* Can't send "Clear" req to local ypserv */ +#define YPPUSH_FORCE ((long)-12) /* No local order number in map - use -f */ +#define YPPUSH_XFRERR ((long)-13) /* ypxfr error */ +#define YPPUSH_REFUSED ((long)-14) /* Transfer request refused by ypserv */ + +struct inaddr; +__BEGIN_DECLS +bool_t xdr_datum(XDR *, datum *); +bool_t xdr_ypreq_key(XDR *, struct ypreq_key *); +bool_t xdr_ypreq_nokey(XDR *, struct ypreq_nokey *); +bool_t xdr_ypreq_xfr(XDR *, struct ypreq_xfr *); +bool_t xdr_ypresp_val(XDR *, struct ypresp_val *); +bool_t xdr_ypresp_key_val(XDR *, struct ypresp_key_val *); +bool_t xdr_ypbind_resp(XDR *, struct ypbind_resp *); +bool_t xdr_ypbind_setdom(XDR *, struct ypbind_setdom *); +bool_t xdr_yp_inaddr(XDR *, struct inaddr *); +bool_t xdr_ypmap_parms(XDR *, struct ypmap_parms *); +bool_t xdr_yppushresp_xfr(XDR *, struct yppushresp_xfr *); +bool_t xdr_ypresp_order(XDR *, struct ypresp_order *); +bool_t xdr_ypresp_master(XDR *, struct ypresp_master *); +bool_t xdr_ypresp_maplist(XDR *, struct ypresp_maplist *); +__END_DECLS + +#endif /* _RPCSVC_YP_PROT_H_ */ diff --git a/include/rpcsvc/ypclnt.h b/include/rpcsvc/ypclnt.h new file mode 100644 index 0000000..343af0e --- /dev/null +++ b/include/rpcsvc/ypclnt.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1992/3 Theo de Raadt + * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/rpcsvc/ypclnt.h 121577 2003-10-26 16:35:11Z peter $ + */ + +#ifndef _RPCSVC_YPCLNT_H_ +#define _RPCSVC_YPCLNT_H_ + +#include + +#define YPERR_BADARGS 1 /* args to function are bad */ +#define YPERR_RPC 2 /* RPC failure */ +#define YPERR_DOMAIN 3 /* can't bind to a server for domain */ +#define YPERR_MAP 4 /* no such map in server's domain */ +#define YPERR_KEY 5 /* no such key in map */ +#define YPERR_YPERR 6 /* some internal YP server or client error */ +#define YPERR_RESRC 7 /* local resource allocation failure */ +#define YPERR_NOMORE 8 /* no more records in map database */ +#define YPERR_PMAP 9 /* can't communicate with portmapper */ +#define YPERR_YPBIND 10 /* can't communicate with ypbind */ +#define YPERR_YPSERV 11 /* can't communicate with ypserv */ +#define YPERR_NODOM 12 /* local domain name not set */ +#define YPERR_BADDB 13 /* YP data base is bad */ +#define YPERR_VERS 14 /* YP version mismatch */ +#define YPERR_ACCESS 15 /* access violation */ +#define YPERR_BUSY 16 /* database is busy */ + +/* + * Types of update operations + */ +#define YPOP_CHANGE 1 /* change, do not add */ +#define YPOP_INSERT 2 /* add, do not change */ +#define YPOP_DELETE 3 /* delete this entry */ +#define YPOP_STORE 4 /* add, or change */ + +struct ypall_callback { + /* return non-0 to stop getting called */ + int (*foreach)(unsigned long, char *, int, char *, int, void *); + char *data; /* opaque pointer for use of callback fn */ +}; + +struct dom_binding; +struct ypmaplist; +struct ypall_callback; + +__BEGIN_DECLS +int yp_bind(char *dom); +int _yp_dobind(char *dom, struct dom_binding **ypdb); +void yp_unbind(char *dom); +int yp_get_default_domain(char **domp); +int yp_match(char *indomain, char *inmap, const char *inkey, int inkeylen, + char **outval, int *outvallen); +int yp_first(char *indomain, char *inmap, char **outkey, int *outkeylen, + char **outval, int *outvallen); +int yp_next(char *indomain, char *inmap, char *inkey, int inkeylen, + char **outkey, int *outkeylen, char **outval, int *outvallen); +int yp_maplist(char *indomain, struct ypmaplist **outmaplist); +int yp_master(char *indomain, char *inmap, char **outname); +int yp_order(char *indomain, char *inmap, int *outorder); +int yp_all(char *indomain, char *inmap, struct ypall_callback *incallback); +const char *yperr_string(int incode); +const char *ypbinderr_string(int incode); +int ypprot_err(unsigned int incode); +__END_DECLS + +#endif /* _RPCSVC_YPCLNT_H_ */ + diff --git a/include/rpcsvc/yppasswd.x b/include/rpcsvc/yppasswd.x new file mode 100644 index 0000000..b70698c --- /dev/null +++ b/include/rpcsvc/yppasswd.x @@ -0,0 +1,77 @@ +/*- + * Copyright (c) 2010, Oracle America, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the "Oracle America, Inc." 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + */ + +/* + * YP password update protocol + * Requires unix authentication + */ + +#ifndef RPC_HDR +%#ifndef lint +%/*static char sccsid[] = "from: @(#)yppasswd.x 1.1 87/04/13 Copyr 1987 Sun Micro";*/ +%/*static char sccsid[] = "from: @(#)yppasswd.x 2.1 88/08/01 4.0 RPCSRC";*/ +%#endif /* not lint */ +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/yppasswd.x 259117 2013-12-09 04:26:50Z hrs $"); +#endif + +program YPPASSWDPROG { + version YPPASSWDVERS { + /* + * Update my passwd entry + */ + int + YPPASSWDPROC_UPDATE(yppasswd) = 1; + } = 1; +} = 100009; + + +struct x_passwd { + string pw_name<>; /* username */ + string pw_passwd<>; /* encrypted password */ + int pw_uid; /* user id */ + int pw_gid; /* group id */ + string pw_gecos<>; /* in real life name */ + string pw_dir<>; /* home directory */ + string pw_shell<>; /* default shell */ +}; + +struct yppasswd { + string oldpass<>; /* unencrypted old password */ + x_passwd newpw; /* new passwd entry */ +}; + + +#ifdef RPC_HDR +%#include +%extern int _yppasswd( char * , struct x_passwd * ); +%#define yppasswd(x,y) _yppasswd(x,y) +#endif diff --git a/include/rpcsvc/ypupdate_prot.x b/include/rpcsvc/ypupdate_prot.x new file mode 100644 index 0000000..6627572 --- /dev/null +++ b/include/rpcsvc/ypupdate_prot.x @@ -0,0 +1,86 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user or with the express written consent of +% * Sun Microsystems, Inc. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ + +%/* +% * Copyright (c) 1986, 1990 by Sun Microsystems, Inc. +% */ +% +%/* from @(#)ypupdate_prot.x 1.3 91/03/11 TIRPC 1.0 */ +#ifndef RPC_HDR +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/ypupdate_prot.x 114629 2003-05-04 02:51:42Z obrien $"); +#endif +% +%/* +% * Compiled from ypupdate_prot.x using rpcgen +% * This is NOT source code! +% * DO NOT EDIT THIS FILE! +% */ + +/* + * YP update service protocol + */ +#ifdef RPC_HDR +% +%#ifndef _rpcsvc_ypupdate_prot_h +%#define _rpcsvc_ypupdate_prot_h +% +#endif + +const MAXMAPNAMELEN = 255; +const MAXYPDATALEN = 1023; +const MAXERRMSGLEN = 255; + +program YPU_PROG { + version YPU_VERS { + u_int YPU_CHANGE(ypupdate_args) = 1; + u_int YPU_INSERT(ypupdate_args) = 2; + u_int YPU_DELETE(ypdelete_args) = 3; + u_int YPU_STORE(ypupdate_args) = 4; + } = 1; +} = 100028; + +typedef opaque yp_buf; + +struct ypupdate_args { + string mapname; + yp_buf key; + yp_buf datum; +}; + +struct ypdelete_args { + string mapname; + yp_buf key; +}; + +#ifdef RPC_HDR +% +%#endif /* !_rpcsvc_ypupdate_prot_h */ +#endif diff --git a/include/rpcsvc/ypxfrd.x b/include/rpcsvc/ypxfrd.x new file mode 100644 index 0000000..160d5ff --- /dev/null +++ b/include/rpcsvc/ypxfrd.x @@ -0,0 +1,169 @@ +/* + * Copyright (c) 1995, 1996 + * Bill Paul . 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 Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul 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. + */ + +/* + * This protocol definition file describes a file transfer + * system used to very quickly move NIS maps from one host to + * another. This is similar to what Sun does with their ypxfrd + * protocol, but it must be stressed that this protocol is _NOT_ + * compatible with Sun's. There are a couple of reasons for this: + * + * 1) Sun's protocol is proprietary. The protocol definition is + * not freely available in any of the SunRPC source distributions, + * even though the NIS v2 protocol is. + * + * 2) The idea here is to transfer entire raw files rather than + * sending just the records. Sun uses ndbm for its NIS map files, + * while FreeBSD uses Berkeley DB. Both are hash databases, but the + * formats are incompatible, making it impossible for them to + * use each others' files. Even if FreeBSD adopted ndbm for its + * database format, FreeBSD/i386 is a little-endian OS and + * SunOS/SPARC is big-endian; ndbm is byte-order sensitive and + * not very smart about it, which means an attempt to read a + * database on a little-endian box that was created on a big-endian + * box (or vice-versa) can cause the ndbm code to eat itself. + * Luckily, Berkeley DB is able to deal with this situation in + * a more graceful manner. + * + * While the protocol is incompatible, the idea is the same: we just open + * up a TCP pipe to the client and transfer the raw map database + * from the master server to the slave. This is many times faster than + * the standard yppush/ypxfr transfer method since it saves us from + * having to recreate the map databases via the DB library each time. + * For example: creating a passwd database with 30,000 entries with yp_mkdb + * can take a couple of minutes, but to just copy the file takes only a few + * seconds. + */ + +#ifndef RPC_HDR +%#include +%__FBSDID("$FreeBSD: releng/11.1/include/rpcsvc/ypxfrd.x 249583 2013-04-17 11:42:40Z gabor $"); +#endif + +/* XXX cribbed from yp.x */ +const _YPMAXRECORD = 1024; +const _YPMAXDOMAIN = 64; +const _YPMAXMAP = 64; +const _YPMAXPEER = 64; + +/* Suggested default -- not necessarily the one used. */ +const YPXFRBLOCK = 32767; + +/* + * Possible return codes from the remote server. + */ +enum xfrstat { + XFR_REQUEST_OK = 1, /* Transfer request granted */ + XFR_DENIED = 2, /* Transfer request denied */ + XFR_NOFILE = 3, /* Requested map file doesn't exist */ + XFR_ACCESS = 4, /* File exists, but I couldn't access it */ + XFR_BADDB = 5, /* File is not a hash database */ + XFR_READ_OK = 6, /* Block read successfully */ + XFR_READ_ERR = 7, /* Read error during transfer */ + XFR_DONE = 8, /* Transfer completed */ + XFR_DB_ENDIAN_MISMATCH = 9, /* Database byte order mismatch */ + XFR_DB_TYPE_MISMATCH = 10 /* Database type mismatch */ +}; + +/* + * Database type specifications. The client can use this to ask + * the server for a particular type of database or just take whatever + * the server has to offer. + */ +enum xfr_db_type { + XFR_DB_ASCII = 1, /* Flat ASCII text */ + XFR_DB_BSD_HASH = 2, /* Berkeley DB, hash method */ + XFR_DB_BSD_BTREE = 3, /* Berkeley DB, btree method */ + XFR_DB_BSD_RECNO = 4, /* Berkeley DB, recno method */ + XFR_DB_BSD_MPOOL = 5, /* Berkeley DB, mpool method */ + XFR_DB_BSD_NDBM = 6, /* Berkeley DB, hash, ndbm compat */ + XFR_DB_GNU_GDBM = 7, /* GNU GDBM */ + XFR_DB_DBM = 8, /* Old, deprecated dbm format */ + XFR_DB_NDBM = 9, /* ndbm format (used by Sun's NISv2) */ + XFR_DB_OPAQUE = 10, /* Mystery format -- just pass along */ + XFR_DB_ANY = 11, /* I'll take any format you've got */ + XFR_DB_UNKNOWN = 12 /* Unknown format */ +}; + +/* + * Machine byte order specification. This allows the client to check + * that it's copying a map database from a machine of similar byte sex. + * This is necessary for handling database libraries that are fatally + * byte order sensitive. + * + * The XFR_ENDIAN_ANY type is for use with the Berkeley DB database + * formats; Berkeley DB is smart enough to make up for byte order + * differences, so byte sex isn't important. + */ +enum xfr_byte_order { + XFR_ENDIAN_BIG = 1, /* We want big endian */ + XFR_ENDIAN_LITTLE = 2, /* We want little endian */ + XFR_ENDIAN_ANY = 3 /* We'll take whatever you got */ +}; + +typedef string xfrdomain<_YPMAXDOMAIN>; +typedef string xfrmap<_YPMAXMAP>; +typedef string xfrmap_filename<_YPMAXMAP>; /* actual name of map file */ + +/* + * Ask the remote ypxfrd for a map using this structure. + * Note: we supply both a map name and a map file name. These are not + * the same thing. In the case of ndbm, maps are stored in two files: + * map.bykey.pag and may.bykey.dir. We may also have to deal with + * file extensions (on the off chance that the remote server is supporting + * multiple DB formats). To handle this, we tell the remote server both + * what map we want and, in the case of ndbm, whether we want the .dir + * or the .pag part. This name should not be a fully qualified path: + * it's up to the remote server to decide which directories to look in. + */ +struct ypxfr_mapname { + xfrmap xfrmap; + xfrdomain xfrdomain; + xfrmap_filename xfrmap_filename; + xfr_db_type xfr_db_type; + xfr_byte_order xfr_byte_order; +}; + +/* Read response using this structure. */ +union xfr switch (bool ok) { +case TRUE: + opaque xfrblock_buf<>; +case FALSE: + xfrstat xfrstat; +}; + +program YPXFRD_FREEBSD_PROG { + version YPXFRD_FREEBSD_VERS { + union xfr + YPXFRD_GETMAP(ypxfr_mapname) = 1; + } = 1; +} = 600100069; /* 100069 + 60000000 -- 100069 is the Sun ypxfrd prog number */ diff --git a/include/search.h b/include/search.h new file mode 100644 index 0000000..2ab9a94 --- /dev/null +++ b/include/search.h @@ -0,0 +1,85 @@ +/*- + * Written by J.T. Conklin + * Public domain. + * + * $NetBSD: search.h,v 1.16 2005/02/03 04:39:32 perry Exp $ + * $FreeBSD: releng/11.1/include/search.h 308090 2016-10-29 14:41:22Z ed $ + */ + +#ifndef _SEARCH_H_ +#define _SEARCH_H_ + +#include +#include + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +typedef struct entry { + char *key; + void *data; +} ENTRY; + +typedef enum { + FIND, ENTER +} ACTION; + +typedef enum { + preorder, + postorder, + endorder, + leaf +} VISIT; + +#ifdef _SEARCH_PRIVATE +typedef struct __posix_tnode { + void *key; + struct __posix_tnode *llink, *rlink; + signed char balance; +} posix_tnode; + +struct que_elem { + struct que_elem *next; + struct que_elem *prev; +}; +#else +typedef void posix_tnode; +#endif + +#if __BSD_VISIBLE +struct hsearch_data { + struct __hsearch *__hsearch; +}; +#endif + +__BEGIN_DECLS +int hcreate(size_t); +void hdestroy(void); +ENTRY *hsearch(ENTRY, ACTION); +void insque(void *, void *); +void *lfind(const void *, const void *, size_t *, size_t, + int (*)(const void *, const void *)); +void *lsearch(const void *, void *, size_t *, size_t, + int (*)(const void *, const void *)); +void remque(void *); +void *tdelete(const void * __restrict, posix_tnode ** __restrict, + int (*)(const void *, const void *)); +posix_tnode * + tfind(const void *, posix_tnode * const *, + int (*)(const void *, const void *)); +posix_tnode * + tsearch(const void *, posix_tnode **, + int (*)(const void *, const void *)); +void twalk(const posix_tnode *, void (*)(const posix_tnode *, VISIT, int)); + +#if __BSD_VISIBLE +int hcreate_r(size_t, struct hsearch_data *); +void hdestroy_r(struct hsearch_data *); +int hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *); +#endif + +__END_DECLS + +#endif /* !_SEARCH_H_ */ diff --git a/include/semaphore.h b/include/semaphore.h new file mode 100644 index 0000000..c14d7cd --- /dev/null +++ b/include/semaphore.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2010 David Xu + * + * 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 unmodified, 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/semaphore.h 315274 2017-03-14 17:52:43Z vangyzen $ + */ + +/* semaphore.h: POSIX 1003.1b semaphores */ + +#ifndef _SEMAPHORE_H_ +#define _SEMAPHORE_H_ + +#include +#include +#include + +#include + +struct _sem { + __uint32_t _magic; + struct _usem2 _kern; + __uint32_t _padding; /* Preserve structure size */ +}; + +typedef struct _sem sem_t; + +#define SEM_FAILED ((sem_t *)0) +#define SEM_VALUE_MAX __INT_MAX + +struct timespec; + +__BEGIN_DECLS +#if __BSD_VISIBLE +int sem_clockwait_np(sem_t * __restrict, __clockid_t, int, + const struct timespec *, struct timespec *); +#endif +int sem_close(sem_t *); +int sem_destroy(sem_t *); +int sem_getvalue(sem_t * __restrict, int * __restrict); +int sem_init(sem_t *, int, unsigned int); +sem_t *sem_open(const char *, int, ...); +int sem_post(sem_t *); +int sem_timedwait(sem_t * __restrict, const struct timespec * __restrict); +int sem_trywait(sem_t *); +int sem_unlink(const char *); +int sem_wait(sem_t *); +__END_DECLS + +#endif /* !_SEMAPHORE_H_ */ diff --git a/include/setjmp.h b/include/setjmp.h new file mode 100644 index 0000000..8bedbe5 --- /dev/null +++ b/include/setjmp.h @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * (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. + * + * 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. + * + * @(#)setjmp.h 8.2 (Berkeley) 1/21/94 + * $FreeBSD: releng/11.1/include/setjmp.h 265878 2014-05-11 13:48:21Z jilles $ + */ + +#ifndef _SETJMP_H_ +#define _SETJMP_H_ + +#include + +/* The size of the jmp_buf is machine dependent: */ +#include + +__BEGIN_DECLS +#if __XSI_VISIBLE >= 600 +void _longjmp(jmp_buf, int) __dead2; +int _setjmp(jmp_buf) __returns_twice; +#endif +void longjmp(jmp_buf, int) __dead2; +#if __BSD_VISIBLE +void longjmperror(void); +#endif +int setjmp(jmp_buf) __returns_twice; +#if __POSIX_VISIBLE || __XSI_VISIBLE +void siglongjmp(sigjmp_buf, int) __dead2; +int sigsetjmp(sigjmp_buf, int) __returns_twice; +#endif +__END_DECLS + +#endif /* !_SETJMP_H_ */ diff --git a/include/signal.h b/include/signal.h new file mode 100644 index 0000000..f1ffdcd --- /dev/null +++ b/include/signal.h @@ -0,0 +1,132 @@ +/*- + * 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. + * + * @(#)signal.h 8.3 (Berkeley) 3/30/94 + * $FreeBSD: releng/11.1/include/signal.h 315282 2017-03-14 20:14:57Z pfg $ + */ + +#ifndef _SIGNAL_H_ +#define _SIGNAL_H_ + +#include +#include +#include +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE +#include +#include +#endif + +__NULLABILITY_PRAGMA_PUSH + +#if __BSD_VISIBLE +/* + * XXX should enlarge these, if only to give empty names instead of bounds + * errors for large signal numbers. + */ +extern const char * const sys_signame[NSIG]; +extern const char * const sys_siglist[NSIG]; +extern const int sys_nsig; +#endif + +#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE +#ifndef _PID_T_DECLARED +typedef __pid_t pid_t; +#define _PID_T_DECLARED +#endif +#endif + +#if __POSIX_VISIBLE || __XSI_VISIBLE +struct pthread; /* XXX */ +typedef struct pthread *__pthread_t; +#if !defined(_PTHREAD_T_DECLARED) && __POSIX_VISIBLE >= 200809 +typedef __pthread_t pthread_t; +#define _PTHREAD_T_DECLARED +#endif +#endif /* __POSIX_VISIBLE || __XSI_VISIBLE */ + +__BEGIN_DECLS +int raise(int); + +#if __POSIX_VISIBLE || __XSI_VISIBLE +int kill(__pid_t, int); +int pthread_kill(__pthread_t, int); +int pthread_sigmask(int, const __sigset_t * __restrict, + __sigset_t * __restrict); +int sigaction(int, const struct sigaction * __restrict, + struct sigaction * __restrict); +int sigaddset(sigset_t *, int); +int sigdelset(sigset_t *, int); +int sigemptyset(sigset_t *); +int sigfillset(sigset_t *); +int sigismember(const sigset_t *, int); +int sigpending(sigset_t * _Nonnull); +int sigprocmask(int, const sigset_t * __restrict, sigset_t * __restrict); +int sigsuspend(const sigset_t * _Nonnull); +int sigwait(const sigset_t * _Nonnull __restrict, + int * _Nonnull __restrict); +#endif + +#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE >= 600 +int sigqueue(__pid_t, int, const union sigval); + +struct timespec; +int sigtimedwait(const sigset_t * __restrict, siginfo_t * __restrict, + const struct timespec * __restrict); +int sigwaitinfo(const sigset_t * __restrict, siginfo_t * __restrict); +#endif + +#if __XSI_VISIBLE +int killpg(__pid_t, int); +int sigaltstack(const stack_t * __restrict, stack_t * __restrict); +int sighold(int); +int sigignore(int); +int sigpause(int); +int sigrelse(int); +void (* _Nullable sigset(int, void (* _Nullable)(int)))(int); +int xsi_sigpause(int); +#endif + +#if __XSI_VISIBLE >= 600 +int siginterrupt(int, int); +#endif + +#if __POSIX_VISIBLE >= 200809 +void psignal(int, const char *); +#endif + +#if __BSD_VISIBLE +int sigblock(int); +int sigreturn(const struct __ucontext *); +int sigsetmask(int); +int sigstack(const struct sigstack *, struct sigstack *); +int sigvec(int, struct sigvec *, struct sigvec *); +#endif +__END_DECLS +__NULLABILITY_PRAGMA_POP + +#endif /* !_SIGNAL_H_ */ diff --git a/include/spawn.h b/include/spawn.h new file mode 100644 index 0000000..52afab9 --- /dev/null +++ b/include/spawn.h @@ -0,0 +1,118 @@ +/*- + * Copyright (c) 2008 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/spawn.h 179873 2008-06-19 07:30:32Z ed $ + */ + +#ifndef _SPAWN_H_ +#define _SPAWN_H_ + +#include +#include +#include + +#ifndef _MODE_T_DECLARED +typedef __mode_t mode_t; +#define _MODE_T_DECLARED +#endif + +#ifndef _PID_T_DECLARED +typedef __pid_t pid_t; +#define _PID_T_DECLARED +#endif + +#ifndef _SIGSET_T_DECLARED +#define _SIGSET_T_DECLARED +typedef __sigset_t sigset_t; +#endif + +struct sched_param; + +typedef struct __posix_spawnattr *posix_spawnattr_t; +typedef struct __posix_spawn_file_actions *posix_spawn_file_actions_t; + +#define POSIX_SPAWN_RESETIDS 0x01 +#define POSIX_SPAWN_SETPGROUP 0x02 +#define POSIX_SPAWN_SETSCHEDPARAM 0x04 +#define POSIX_SPAWN_SETSCHEDULER 0x08 +#define POSIX_SPAWN_SETSIGDEF 0x10 +#define POSIX_SPAWN_SETSIGMASK 0x20 + +__BEGIN_DECLS +/* + * Spawn routines + * + * XXX both arrays should be __restrict, but this does not work when GCC + * is invoked with -std=c99. + */ +int posix_spawn(pid_t * __restrict, const char * __restrict, + const posix_spawn_file_actions_t *, const posix_spawnattr_t * __restrict, + char * const [], char * const []); +int posix_spawnp(pid_t * __restrict, const char * __restrict, + const posix_spawn_file_actions_t *, const posix_spawnattr_t * __restrict, + char * const [], char * const []); + +/* + * File descriptor actions + */ +int posix_spawn_file_actions_init(posix_spawn_file_actions_t *); +int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *); + +int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t * __restrict, + int, const char * __restrict, int, mode_t); +int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *, int, int); +int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *, int); + +/* + * Spawn attributes + */ +int posix_spawnattr_init(posix_spawnattr_t *); +int posix_spawnattr_destroy(posix_spawnattr_t *); + +int posix_spawnattr_getflags(const posix_spawnattr_t * __restrict, + short * __restrict); +int posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict, + pid_t * __restrict); +int posix_spawnattr_getschedparam(const posix_spawnattr_t * __restrict, + struct sched_param * __restrict); +int posix_spawnattr_getschedpolicy(const posix_spawnattr_t * __restrict, + int * __restrict); +int posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict, + sigset_t * __restrict); +int posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict, + sigset_t * __restrict sigmask); + +int posix_spawnattr_setflags(posix_spawnattr_t *, short); +int posix_spawnattr_setpgroup(posix_spawnattr_t *, pid_t); +int posix_spawnattr_setschedparam(posix_spawnattr_t * __restrict, + const struct sched_param * __restrict); +int posix_spawnattr_setschedpolicy(posix_spawnattr_t *, int); +int posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict, + const sigset_t * __restrict); +int posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict, + const sigset_t * __restrict); +__END_DECLS + +#endif /* !_SPAWN_H_ */ diff --git a/include/stab.h b/include/stab.h new file mode 100644 index 0000000..d34c3cd --- /dev/null +++ b/include/stab.h @@ -0,0 +1,70 @@ +/*- + * 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. + * + * @(#)stab.h 8.1 (Berkeley) 6/2/93 + * + * $FreeBSD: releng/11.1/include/stab.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _STAB_H_ +#define _STAB_H_ + +/* + * The following are symbols used by various debuggers and by the Pascal + * compiler. Each of them must have one (or more) of the bits defined by + * the N_STAB mask set. + */ + +#define N_GSYM 0x20 /* global symbol */ +#define N_FNAME 0x22 /* F77 function name */ +#define N_FUN 0x24 /* procedure name */ +#define N_STSYM 0x26 /* data segment variable */ +#define N_LCSYM 0x28 /* bss segment variable */ +#define N_MAIN 0x2a /* main function name */ +#define N_PC 0x30 /* global Pascal symbol */ +#define N_RSYM 0x40 /* register variable */ +#define N_SLINE 0x44 /* text segment line number */ +#define N_DSLINE 0x46 /* data segment line number */ +#define N_BSLINE 0x48 /* bss segment line number */ +#define N_SSYM 0x60 /* structure/union element */ +#define N_SO 0x64 /* main source file name */ +#define N_LSYM 0x80 /* stack variable */ +#define N_BINCL 0x82 /* include file beginning */ +#define N_SOL 0x84 /* included source file name */ +#define N_PSYM 0xa0 /* parameter variable */ +#define N_EINCL 0xa2 /* include file end */ +#define N_ENTRY 0xa4 /* alternate entry point */ +#define N_LBRAC 0xc0 /* left bracket */ +#define N_EXCL 0xc2 /* deleted include file */ +#define N_RBRAC 0xe0 /* right bracket */ +#define N_BCOMM 0xe2 /* begin common */ +#define N_ECOMM 0xe4 /* end common */ +#define N_ECOML 0xe8 /* end common (local name) */ +#define N_LENG 0xfe /* length of preceding entry */ + +#endif diff --git a/include/stdalign.h b/include/stdalign.h new file mode 100644 index 0000000..86016bd --- /dev/null +++ b/include/stdalign.h @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2012 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/stdalign.h 228879 2011-12-25 20:51:40Z ed $ + */ + +#ifndef __alignas_is_defined +#define __alignas_is_defined 1 + +#if !defined(__cplusplus) || __cplusplus < 201103L +#include +#define alignas _Alignas +#endif + +#endif /* !__alignas_is_defined */ + +#ifndef __alignof_is_defined +#define __alignof_is_defined 1 + +#if !defined(__cplusplus) || __cplusplus < 201103L +#include +#define alignof _Alignof +#endif + +#endif /* !__alignof_is_defined */ diff --git a/include/stdbool.h b/include/stdbool.h new file mode 100644 index 0000000..c9ae65b --- /dev/null +++ b/include/stdbool.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2000 Jeroen Ruigrok van der Werven + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/stdbool.h 228878 2011-12-25 20:15:41Z ed $ + */ + +#ifndef __bool_true_false_are_defined +#define __bool_true_false_are_defined 1 + +#ifndef __cplusplus + +#define false 0 +#define true 1 + +#define bool _Bool +#if __STDC_VERSION__ < 199901L && __GNUC__ < 3 && !defined(__INTEL_COMPILER) +typedef int _Bool; +#endif + +#endif /* !__cplusplus */ +#endif /* __bool_true_false_are_defined */ diff --git a/include/stdnoreturn.h b/include/stdnoreturn.h new file mode 100644 index 0000000..abef927 --- /dev/null +++ b/include/stdnoreturn.h @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2012 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/stdnoreturn.h 229437 2012-01-03 23:05:23Z ed $ + */ + +#ifdef __cplusplus +#error " cannot be used in combination with C++11." +#endif + +#ifndef noreturn + +#include +#define noreturn _Noreturn + +#endif /* !noreturn */ diff --git a/include/stringlist.h b/include/stringlist.h new file mode 100644 index 0000000..77fa82a --- /dev/null +++ b/include/stringlist.h @@ -0,0 +1,52 @@ +/* $NetBSD: stringlist.h,v 1.2 1997/01/17 06:11:36 lukem Exp $ */ + +/* + * Copyright (c) 1994 Christos Zoulas + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/stringlist.h 283201 2015-05-21 08:38:25Z bapt $ + */ + +#ifndef _STRINGLIST_H +#define _STRINGLIST_H +#include +#include + +/* + * Simple string list + */ +typedef struct _stringlist { + char **sl_str; + size_t sl_max; + size_t sl_cur; +} StringList; + +__BEGIN_DECLS +StringList *sl_init(void); +int sl_add(StringList *, char *); +void sl_free(StringList *, int); +char *sl_find(StringList *, const char *); +__END_DECLS + +#endif /* _STRINGLIST_H */ diff --git a/include/sysexits.h b/include/sysexits.h new file mode 100644 index 0000000..570302d --- /dev/null +++ b/include/sysexits.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 1987, 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. + * + * @(#)sysexits.h 8.1 (Berkeley) 6/2/93 + * + * $FreeBSD: releng/11.1/include/sysexits.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _SYSEXITS_H_ +#define _SYSEXITS_H_ + +/* + * SYSEXITS.H -- Exit status codes for system programs. + * + * This include file attempts to categorize possible error + * exit statuses for system programs, notably delivermail + * and the Berkeley network. + * + * Error numbers begin at EX__BASE to reduce the possibility of + * clashing with other exit statuses that random programs may + * already return. The meaning of the codes is approximately + * as follows: + * + * EX_USAGE -- The command was used incorrectly, e.g., with + * the wrong number of arguments, a bad flag, a bad + * syntax in a parameter, or whatever. + * EX_DATAERR -- The input data was incorrect in some way. + * This should only be used for user's data & not + * system files. + * EX_NOINPUT -- An input file (not a system file) did not + * exist or was not readable. This could also include + * errors like "No message" to a mailer (if it cared + * to catch it). + * EX_NOUSER -- The user specified did not exist. This might + * be used for mail addresses or remote logins. + * EX_NOHOST -- The host specified did not exist. This is used + * in mail addresses or network requests. + * EX_UNAVAILABLE -- A service is unavailable. This can occur + * if a support program or file does not exist. This + * can also be used as a catchall message when something + * you wanted to do doesn't work, but you don't know + * why. + * EX_SOFTWARE -- An internal software error has been detected. + * This should be limited to non-operating system related + * errors as possible. + * EX_OSERR -- An operating system error has been detected. + * This is intended to be used for such things as "cannot + * fork", "cannot create pipe", or the like. It includes + * things like getuid returning a user that does not + * exist in the passwd file. + * EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp, + * etc.) does not exist, cannot be opened, or has some + * sort of error (e.g., syntax error). + * EX_CANTCREAT -- A (user specified) output file cannot be + * created. + * EX_IOERR -- An error occurred while doing I/O on some file. + * EX_TEMPFAIL -- temporary failure, indicating something that + * is not really an error. In sendmail, this means + * that a mailer (e.g.) could not create a connection, + * and the request should be reattempted later. + * EX_PROTOCOL -- the remote system returned something that + * was "not possible" during a protocol exchange. + * EX_NOPERM -- You did not have sufficient permission to + * perform the operation. This is not intended for + * file system problems, which should use NOINPUT or + * CANTCREAT, but rather for higher level permissions. + */ + +#define EX_OK 0 /* successful termination */ + +#define EX__BASE 64 /* base value for error messages */ + +#define EX_USAGE 64 /* command line usage error */ +#define EX_DATAERR 65 /* data format error */ +#define EX_NOINPUT 66 /* cannot open input */ +#define EX_NOUSER 67 /* addressee unknown */ +#define EX_NOHOST 68 /* host name unknown */ +#define EX_UNAVAILABLE 69 /* service unavailable */ +#define EX_SOFTWARE 70 /* internal software error */ +#define EX_OSERR 71 /* system error (e.g., can't fork) */ +#define EX_OSFILE 72 /* critical OS file missing */ +#define EX_CANTCREAT 73 /* can't create (user) output file */ +#define EX_IOERR 74 /* input/output error */ +#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ +#define EX_PROTOCOL 76 /* remote error in protocol */ +#define EX_NOPERM 77 /* permission denied */ +#define EX_CONFIG 78 /* configuration error */ + +#define EX__MAX 78 /* maximum listed value */ + +#endif /* !_SYSEXITS_H_ */ diff --git a/include/tar.h b/include/tar.h new file mode 100644 index 0000000..a32ad0e --- /dev/null +++ b/include/tar.h @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chuck Karish of Mindcraft, Inc. + * + * 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. + * + * @(#)tar.h 8.2 (Berkeley) 1/4/94 + * + * $FreeBSD: releng/11.1/include/tar.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _TAR_H +#define _TAR_H + +#define TMAGIC "ustar" /* ustar and a null */ +#define TMAGLEN 6 +#define TVERSION "00" /* 00 and no null */ +#define TVERSLEN 2 + +/* Values used in typeflag field */ +#define REGTYPE '0' /* Regular file */ +#define AREGTYPE '\0' /* Regular file */ +#define LNKTYPE '1' /* Link */ +#define SYMTYPE '2' /* Reserved */ +#define CHRTYPE '3' /* Character special */ +#define BLKTYPE '4' /* Block special */ +#define DIRTYPE '5' /* Directory */ +#define FIFOTYPE '6' /* FIFO special */ +#define CONTTYPE '7' /* Reserved */ + +/* Bits used in the mode field - values in octal */ +#define TSUID 04000 /* Set UID on execution */ +#define TSGID 02000 /* Set GID on execution */ +#define TSVTX 01000 /* Reserved */ + /* File permissions */ +#define TUREAD 00400 /* Read by owner */ +#define TUWRITE 00200 /* Write by owner */ +#define TUEXEC 00100 /* Execute/Search by owner */ +#define TGREAD 00040 /* Read by group */ +#define TGWRITE 00020 /* Write by group */ +#define TGEXEC 00010 /* Execute/Search by group */ +#define TOREAD 00004 /* Read by other */ +#define TOWRITE 00002 /* Write by other */ +#define TOEXEC 00001 /* Execute/Search by other */ + +#endif diff --git a/include/termios.h b/include/termios.h new file mode 100644 index 0000000..6ed2c06 --- /dev/null +++ b/include/termios.h @@ -0,0 +1,101 @@ +/*- + * Copyright (c) 1988, 1989, 1993, 1994 + * 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. + * + * @(#)termios.h 8.3 (Berkeley) 3/28/94 + * $FreeBSD: releng/11.1/include/termios.h 319651 2017-06-07 11:39:52Z kib $ + */ + +#ifndef _TERMIOS_H_ +#define _TERMIOS_H_ + +#include +#include +#include + +#ifndef _PID_T_DECLARED +typedef __pid_t pid_t; +#define _PID_T_DECLARED +#endif + +#if __BSD_VISIBLE +#define OXTABS TAB3 +#define MDMBUF CCAR_OFLOW +#endif + +#if __BSD_VISIBLE +#define CCEQ(val, c) ((c) == (val) && (val) != _POSIX_VDISABLE) +#endif + +/* + * Commands passed to tcsetattr() for setting the termios structure. + */ +#define TCSANOW 0 /* make change immediate */ +#define TCSADRAIN 1 /* drain output, then change */ +#define TCSAFLUSH 2 /* drain output, flush input */ +#if __BSD_VISIBLE +#define TCSASOFT 0x10 /* flag - don't alter h.w. state */ +#endif + +#define TCIFLUSH 1 +#define TCOFLUSH 2 +#define TCIOFLUSH 3 +#define TCOOFF 1 +#define TCOON 2 +#define TCIOFF 3 +#define TCION 4 + +__BEGIN_DECLS +speed_t cfgetispeed(const struct termios *); +speed_t cfgetospeed(const struct termios *); +int cfsetispeed(struct termios *, speed_t); +int cfsetospeed(struct termios *, speed_t); +int tcgetattr(int, struct termios *); +int tcsetattr(int, int, const struct termios *); +int tcdrain(int); +int tcflow(int, int); +int tcflush(int, int); +int tcsendbreak(int, int); + +#if __POSIX_VISIBLE >= 200112 +pid_t tcgetsid(int); +#endif +#if __BSD_VISIBLE +int tcsetsid(int, pid_t); + +void cfmakeraw(struct termios *); +void cfmakesane(struct termios *); +int cfsetspeed(struct termios *, speed_t); +#endif +__END_DECLS + +#endif /* !_TERMIOS_H_ */ + +#if __BSD_VISIBLE +#include +#include +#endif diff --git a/include/tgmath.h b/include/tgmath.h new file mode 100644 index 0000000..a4fdd3c --- /dev/null +++ b/include/tgmath.h @@ -0,0 +1,210 @@ +/*- + * Copyright (c) 2004 Stefan Farfeleder. + * All rights reserved. + * + * Copyright (c) 2012 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/tgmath.h 271155 2014-09-05 05:36:32Z ed $ + */ + +#ifndef _TGMATH_H_ +#define _TGMATH_H_ + +#include +#include + +/* + * This implementation of uses the two following macros, + * which are based on the macros described in C11 proposal N1404: + * __tg_impl_simple(x, y, z, fnl, fn, fnf, ...) + * Invokes fnl() if the corresponding real type of x, y or z is long + * double, fn() if it is double or any has an integer type, and fnf() + * otherwise. + * __tg_impl_full(x, y, cfnl, cfn, cfnf, fnl, fn, fnf, ...) + * Invokes [c]fnl() if the corresponding real type of x or y is long + * double, [c]fn() if it is double or any has an integer type, and + * [c]fnf() otherwise. The function with the 'c' prefix is called if + * any of x or y is a complex number. + * Both macros call the chosen function with all additional arguments passed + * to them, as given by __VA_ARGS__. + * + * Note that these macros cannot be implemented with C's ?: operator, + * because the return type of the whole expression would incorrectly be long + * double complex regardless of the argument types. + * + * The structure of the C11 implementation of these macros can in + * principle be reused for non-C11 compilers, but due to an integer + * promotion bug for complex types in GCC 4.2, simply let non-C11 + * compilers use an inefficient yet reliable version. + */ + +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \ + __has_extension(c_generic_selections) +#define __tg_generic(x, cfnl, cfn, cfnf, fnl, fn, fnf) \ + _Generic(x, \ + long double _Complex: cfnl, \ + double _Complex: cfn, \ + float _Complex: cfnf, \ + long double: fnl, \ + default: fn, \ + float: fnf \ + ) +#define __tg_type(x) \ + __tg_generic(x, (long double _Complex)0, (double _Complex)0, \ + (float _Complex)0, (long double)0, (double)0, (float)0) +#define __tg_impl_simple(x, y, z, fnl, fn, fnf, ...) \ + __tg_generic( \ + __tg_type(x) + __tg_type(y) + __tg_type(z), \ + fnl, fn, fnf, fnl, fn, fnf)(__VA_ARGS__) +#define __tg_impl_full(x, y, cfnl, cfn, cfnf, fnl, fn, fnf, ...) \ + __tg_generic( \ + __tg_type(x) + __tg_type(y), \ + cfnl, cfn, cfnf, fnl, fn, fnf)(__VA_ARGS__) +#elif defined(__generic) +#define __tg_generic_simple(x, fnl, fn, fnf) \ + __generic(x, long double _Complex, fnl, \ + __generic(x, double _Complex, fn, \ + __generic(x, float _Complex, fnf, \ + __generic(x, long double, fnl, \ + __generic(x, float, fnf, fn))))) +#define __tg_impl_simple(x, y, z, fnl, fn, fnf, ...) \ + __tg_generic_simple(x, \ + __tg_generic_simple(y, \ + __tg_generic_simple(z, fnl, fnl, fnl), \ + __tg_generic_simple(z, fnl, fnl, fnl), \ + __tg_generic_simple(z, fnl, fnl, fnl)), \ + __tg_generic_simple(y, \ + __tg_generic_simple(z, fnl, fnl, fnl), \ + __tg_generic_simple(z, fnl, fn , fn ), \ + __tg_generic_simple(z, fnl, fn , fn )), \ + __tg_generic_simple(y, \ + __tg_generic_simple(z, fnl, fnl, fnl), \ + __tg_generic_simple(z, fnl, fn , fn ), \ + __tg_generic_simple(z, fnl, fn , fnf)))(__VA_ARGS__) +#define __tg_generic_full(x, cfnl, cfn, cfnf, fnl, fn, fnf) \ + __generic(x, long double _Complex, cfnl, \ + __generic(x, double _Complex, cfn, \ + __generic(x, float _Complex, cfnf, \ + __generic(x, long double, fnl, \ + __generic(x, float, fnf, fn))))) +#define __tg_impl_full(x, y, cfnl, cfn, cfnf, fnl, fn, fnf, ...) \ + __tg_generic_full(x, \ + __tg_generic_full(y, cfnl, cfnl, cfnl, cfnl, cfnl, cfnl), \ + __tg_generic_full(y, cfnl, cfn , cfn , cfnl, cfn , cfn ), \ + __tg_generic_full(y, cfnl, cfn , cfnf, cfnl, cfn , cfnf), \ + __tg_generic_full(y, cfnl, cfnl, cfnl, fnl , fnl , fnl ), \ + __tg_generic_full(y, cfnl, cfn , cfn , fnl , fn , fn ), \ + __tg_generic_full(y, cfnl, cfn , cfnf, fnl , fn , fnf )) \ + (__VA_ARGS__) +#else +#error " not implemented for this compiler" +#endif + +/* Macros to save lots of repetition below */ +#define __tg_simple(x, fn) \ + __tg_impl_simple(x, x, x, fn##l, fn, fn##f, x) +#define __tg_simple2(x, y, fn) \ + __tg_impl_simple(x, x, y, fn##l, fn, fn##f, x, y) +#define __tg_simple3(x, y, z, fn) \ + __tg_impl_simple(x, y, z, fn##l, fn, fn##f, x, y, z) +#define __tg_simplev(x, fn, ...) \ + __tg_impl_simple(x, x, x, fn##l, fn, fn##f, __VA_ARGS__) +#define __tg_full(x, fn) \ + __tg_impl_full(x, x, c##fn##l, c##fn, c##fn##f, fn##l, fn, fn##f, x) +#define __tg_full2(x, y, fn) \ + __tg_impl_full(x, y, c##fn##l, c##fn, c##fn##f, fn##l, fn, fn##f, x, y) + +/* 7.22#4 -- These macros expand to real or complex functions, depending on + * the type of their arguments. */ +#define acos(x) __tg_full(x, acos) +#define asin(x) __tg_full(x, asin) +#define atan(x) __tg_full(x, atan) +#define acosh(x) __tg_full(x, acosh) +#define asinh(x) __tg_full(x, asinh) +#define atanh(x) __tg_full(x, atanh) +#define cos(x) __tg_full(x, cos) +#define sin(x) __tg_full(x, sin) +#define tan(x) __tg_full(x, tan) +#define cosh(x) __tg_full(x, cosh) +#define sinh(x) __tg_full(x, sinh) +#define tanh(x) __tg_full(x, tanh) +#define exp(x) __tg_full(x, exp) +#define log(x) __tg_full(x, log) +#define pow(x, y) __tg_full2(x, y, pow) +#define sqrt(x) __tg_full(x, sqrt) + +/* "The corresponding type-generic macro for fabs and cabs is fabs." */ +#define fabs(x) __tg_impl_full(x, x, cabsl, cabs, cabsf, \ + fabsl, fabs, fabsf, x) + +/* 7.22#5 -- These macros are only defined for arguments with real type. */ +#define atan2(x, y) __tg_simple2(x, y, atan2) +#define cbrt(x) __tg_simple(x, cbrt) +#define ceil(x) __tg_simple(x, ceil) +#define copysign(x, y) __tg_simple2(x, y, copysign) +#define erf(x) __tg_simple(x, erf) +#define erfc(x) __tg_simple(x, erfc) +#define exp2(x) __tg_simple(x, exp2) +#define expm1(x) __tg_simple(x, expm1) +#define fdim(x, y) __tg_simple2(x, y, fdim) +#define floor(x) __tg_simple(x, floor) +#define fma(x, y, z) __tg_simple3(x, y, z, fma) +#define fmax(x, y) __tg_simple2(x, y, fmax) +#define fmin(x, y) __tg_simple2(x, y, fmin) +#define fmod(x, y) __tg_simple2(x, y, fmod) +#define frexp(x, y) __tg_simplev(x, frexp, x, y) +#define hypot(x, y) __tg_simple2(x, y, hypot) +#define ilogb(x) __tg_simple(x, ilogb) +#define ldexp(x, y) __tg_simplev(x, ldexp, x, y) +#define lgamma(x) __tg_simple(x, lgamma) +#define llrint(x) __tg_simple(x, llrint) +#define llround(x) __tg_simple(x, llround) +#define log10(x) __tg_simple(x, log10) +#define log1p(x) __tg_simple(x, log1p) +#define log2(x) __tg_simple(x, log2) +#define logb(x) __tg_simple(x, logb) +#define lrint(x) __tg_simple(x, lrint) +#define lround(x) __tg_simple(x, lround) +#define nearbyint(x) __tg_simple(x, nearbyint) +#define nextafter(x, y) __tg_simple2(x, y, nextafter) +#define nexttoward(x, y) __tg_simplev(x, nexttoward, x, y) +#define remainder(x, y) __tg_simple2(x, y, remainder) +#define remquo(x, y, z) __tg_impl_simple(x, x, y, remquol, remquo, \ + remquof, x, y, z) +#define rint(x) __tg_simple(x, rint) +#define round(x) __tg_simple(x, round) +#define scalbn(x, y) __tg_simplev(x, scalbn, x, y) +#define scalbln(x, y) __tg_simplev(x, scalbln, x, y) +#define tgamma(x) __tg_simple(x, tgamma) +#define trunc(x) __tg_simple(x, trunc) + +/* 7.22#6 -- These macros always expand to complex functions. */ +#define carg(x) __tg_simple(x, carg) +#define cimag(x) __tg_simple(x, cimag) +#define conj(x) __tg_simple(x, conj) +#define cproj(x) __tg_simple(x, cproj) +#define creal(x) __tg_simple(x, creal) + +#endif /* !_TGMATH_H_ */ diff --git a/include/timeconv.h b/include/timeconv.h new file mode 100644 index 0000000..2aed9a9 --- /dev/null +++ b/include/timeconv.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (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. + * + * 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.3 (Berkeley) 1/21/94 + */ + +/* + * $FreeBSD: releng/11.1/include/timeconv.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _TIMECONV_H_ +#define _TIMECONV_H_ + +#include +#include + +#ifndef _TIME_T_DECLARED +typedef __time_t time_t; +#define _TIME_T_DECLARED +#endif + +time_t _time32_to_time(__int32_t t32); +__int32_t _time_to_time32(time_t t); +time_t _time64_to_time(__int64_t t64); +__int64_t _time_to_time64(time_t t); +long _time_to_long(time_t t); +time_t _long_to_time(long tlong); +int _time_to_int(time_t t); +time_t _int_to_time(int tint); + +#endif /* _TIMECONV_H_ */ diff --git a/include/timers.h b/include/timers.h new file mode 100644 index 0000000..c4daa88 --- /dev/null +++ b/include/timers.h @@ -0,0 +1,45 @@ +/* ==== timers.h ============================================================ + * Copyright (c) 1994 by Chris Provenzano, proven@mit.edu + * 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 Chris Provenzano. + * 4. The name of Chris Provenzano may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO ``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 CHRIS PROVENZANO 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. + * + * $FreeBSD: releng/11.1/include/timers.h 50473 1999-08-27 23:45:13Z peter $ + * + * Description : Basic timers header. + * + * 1.00 94/06/13 proven + * -Started coding this file. + */ + +#ifndef _TIMERS_H_ +#define _TIMERS_H_ + +#include + +#endif diff --git a/include/ttyent.h b/include/ttyent.h new file mode 100644 index 0000000..baa4b4c --- /dev/null +++ b/include/ttyent.h @@ -0,0 +1,74 @@ +/* + * 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. + * + * @(#)ttyent.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: releng/11.1/include/ttyent.h 260913 2014-01-20 18:15:06Z nwhitehorn $ + */ + +#ifndef _TTYENT_H_ +#define _TTYENT_H_ + +#define _PATH_TTYS "/etc/ttys" + +#define _TTYS_OFF "off" +#define _TTYS_ON "on" +#define _TTYS_ONIFCONSOLE "onifconsole" +#define _TTYS_SECURE "secure" +#define _TTYS_INSECURE "insecure" +#define _TTYS_WINDOW "window" +#define _TTYS_GROUP "group" +#define _TTYS_NOGROUP "none" +#define _TTYS_DIALUP "dialup" +#define _TTYS_NETWORK "network" + +struct ttyent { + char *ty_name; /* terminal device name */ + char *ty_getty; /* command to execute, usually getty */ + char *ty_type; /* terminal type for termcap */ +#define TTY_ON 0x01 /* enable logins (start ty_getty program) */ +#define TTY_SECURE 0x02 /* allow uid of 0 to login */ +#define TTY_DIALUP 0x04 /* is a dialup tty */ +#define TTY_NETWORK 0x08 /* is a network tty */ + int ty_status; /* status flags */ + char *ty_window; /* command to start up window manager */ + char *ty_comment; /* comment field */ + char *ty_group; /* tty group */ +}; + +#include + +__BEGIN_DECLS +struct ttyent *getttyent(void); +struct ttyent *getttynam(const char *); +int setttyent(void); +int endttyent(void); +int isdialuptty(const char *); +int isnettty(const char *); +__END_DECLS + +#endif /* !_TTYENT_H_ */ diff --git a/include/uchar.h b/include/uchar.h new file mode 100644 index 0000000..d4514ca --- /dev/null +++ b/include/uchar.h @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2013 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/uchar.h 250985 2013-05-25 16:58:12Z ed $ + */ + +#ifndef _UCHAR_H_ +#define _UCHAR_H_ + +#include +#include + +#ifndef _CHAR16_T_DECLARED +typedef __char16_t char16_t; +#define _CHAR16_T_DECLARED +#endif + +#ifndef _CHAR32_T_DECLARED +typedef __char32_t char32_t; +#define _CHAR32_T_DECLARED +#endif + +#ifndef _MBSTATE_T_DECLARED +typedef __mbstate_t mbstate_t; +#define _MBSTATE_T_DECLARED +#endif + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +__BEGIN_DECLS +size_t c16rtomb(char * __restrict, char16_t, mbstate_t * __restrict); +size_t c32rtomb(char * __restrict, char32_t, mbstate_t * __restrict); +size_t mbrtoc16(char16_t * __restrict, const char * __restrict, size_t, + mbstate_t * __restrict); +size_t mbrtoc32(char32_t * __restrict, const char * __restrict, size_t, + mbstate_t * __restrict); +#if __BSD_VISIBLE || defined(_XLOCALE_H_) +#include +#endif +__END_DECLS + +#endif /* !_UCHAR_H_ */ diff --git a/include/ulimit.h b/include/ulimit.h new file mode 100644 index 0000000..c5ea7f9 --- /dev/null +++ b/include/ulimit.h @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2002 Kyle Martin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/ulimit.h 108910 2003-01-08 01:18:13Z tjr $ + */ + +#ifndef _ULIMIT_H_ +#define _ULIMIT_H_ + +#include + +#define UL_GETFSIZE 1 +#define UL_SETFSIZE 2 + +__BEGIN_DECLS +long ulimit(int, ...); +__END_DECLS + +#endif /* !_ULIMIT_H_ */ diff --git a/include/unwind.h b/include/unwind.h new file mode 100644 index 0000000..093d9ec --- /dev/null +++ b/include/unwind.h @@ -0,0 +1,156 @@ +/* $FreeBSD: releng/11.1/include/unwind.h 213290 2010-09-30 03:16:35Z davidxu $ */ + +/* libunwind - a platform-independent unwind library + Copyright (C) 2003 Hewlett-Packard Co + Contributed by David Mosberger-Tang + +This file is part of libunwind. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _UNWIND_H +#define _UNWIND_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Minimal interface as per C++ ABI draft standard: + + http://www.codesourcery.com/cxx-abi/abi-eh.html */ + +typedef enum + { + _URC_NO_REASON = 0, + _URC_FOREIGN_EXCEPTION_CAUGHT = 1, + _URC_FATAL_PHASE2_ERROR = 2, + _URC_FATAL_PHASE1_ERROR = 3, + _URC_NORMAL_STOP = 4, + _URC_END_OF_STACK = 5, + _URC_HANDLER_FOUND = 6, + _URC_INSTALL_CONTEXT = 7, + _URC_CONTINUE_UNWIND = 8 + } +_Unwind_Reason_Code; + +typedef int _Unwind_Action; + +#define _UA_SEARCH_PHASE 1 +#define _UA_CLEANUP_PHASE 2 +#define _UA_HANDLER_FRAME 4 +#define _UA_FORCE_UNWIND 8 + +struct _Unwind_Context; /* opaque data-structure */ +struct _Unwind_Exception; /* forward-declaration */ + +typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code, + struct _Unwind_Exception *); + +typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) (int, _Unwind_Action, + __int64_t, + struct _Unwind_Exception *, + struct _Unwind_Context *, + void *); + +/* The C++ ABI requires exception_class, private_1, and private_2 to + be of type uint64 and the entire structure to be + double-word-aligned, but that seems a bit overly IA-64-specific. + Using "unsigned long" instead should give us the desired effect on + IA-64, while being more general. */ +struct _Unwind_Exception + { + __int64_t exception_class; + _Unwind_Exception_Cleanup_Fn exception_cleanup; + unsigned long private_1; + unsigned long private_2; + }; + +extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *); +extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *, + _Unwind_Stop_Fn, void *); +extern void _Unwind_Resume (struct _Unwind_Exception *); +extern void _Unwind_DeleteException (struct _Unwind_Exception *); +extern unsigned long _Unwind_GetGR (struct _Unwind_Context *, int); +extern void _Unwind_SetGR (struct _Unwind_Context *, int, unsigned long); +extern unsigned long _Unwind_GetIP (struct _Unwind_Context *); +extern unsigned long _Unwind_GetIPInfo (struct _Unwind_Context *, int *); +extern void _Unwind_SetIP (struct _Unwind_Context *, unsigned long); +extern unsigned long _Unwind_GetLanguageSpecificData (struct _Unwind_Context*); +extern unsigned long _Unwind_GetRegionStart (struct _Unwind_Context *); + +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) + +/* Callback for _Unwind_Backtrace(). The backtrace stops immediately + if the callback returns any value other than _URC_NO_REASON. */ +typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (struct _Unwind_Context *, + void *); + +/* See http://gcc.gnu.org/ml/gcc-patches/2001-09/msg00082.html for why + _UA_END_OF_STACK exists. */ +# define _UA_END_OF_STACK 16 + +/* If the unwind was initiated due to a forced unwind, resume that + operation, else re-raise the exception. This is used by + __cxa_rethrow(). */ +extern _Unwind_Reason_Code + _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *); + +/* See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00154.html for why + _Unwind_GetBSP() exists. */ +extern unsigned long _Unwind_GetBSP (struct _Unwind_Context *); + +/* Return the "canonical frame address" for the given context. + This is used by NPTL... */ +extern unsigned long _Unwind_GetCFA (struct _Unwind_Context *); + +/* Return the base-address for data references. */ +extern unsigned long _Unwind_GetDataRelBase (struct _Unwind_Context *); + +/* Return the base-address for text references. */ +extern unsigned long _Unwind_GetTextRelBase (struct _Unwind_Context *); + +/* Call _Unwind_Trace_Fn once for each stack-frame, without doing any + cleanup. The first frame for which the callback is invoked is the + one for the caller of _Unwind_Backtrace(). _Unwind_Backtrace() + returns _URC_END_OF_STACK when the backtrace stopped due to + reaching the end of the call-chain or _URC_FATAL_PHASE1_ERROR if it + stops for any other reason. */ +extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn, void *); + +/* Find the start-address of the procedure containing the specified IP + or NULL if it cannot be found (e.g., because the function has no + unwind info). Note: there is not necessarily a one-to-one + correspondence between source-level functions and procedures: some + functions don't have unwind-info and others are split into multiple + procedures. */ +extern void *_Unwind_FindEnclosingFunction (void *); + +/* See also Linux Standard Base Spec: + http://www.linuxbase.org/spec/refspecs/LSB_1.3.0/gLSB/gLSB/libgcc-s.html */ + +#endif /* _GNU_SOURCE || _BSD_SOURCE */ + +#ifdef __cplusplus +}; +#endif + +#endif /* _UNWIND_H */ diff --git a/include/utime.h b/include/utime.h new file mode 100644 index 0000000..19858b4 --- /dev/null +++ b/include/utime.h @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 1990, 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. + * + * @(#)utime.h 8.1 (Berkeley) 6/2/93 + * $FreeBSD: releng/11.1/include/utime.h 203964 2010-02-16 19:39:50Z imp $ + */ + +#ifndef _UTIME_H_ +#define _UTIME_H_ + +#include +#include + +#ifndef _TIME_T_DECLARED +typedef __time_t time_t; +#define _TIME_T_DECLARED +#endif + +struct utimbuf { + time_t actime; /* Access time */ + time_t modtime; /* Modification time */ +}; + +__BEGIN_DECLS +int utime(const char *, const struct utimbuf *); +__END_DECLS + +#endif /* !_UTIME_H_ */ diff --git a/include/utmpx.h b/include/utmpx.h new file mode 100644 index 0000000..7a98d95 --- /dev/null +++ b/include/utmpx.h @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 2010 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/utmpx.h 202188 2010-01-13 17:29:55Z ed $ + */ + +#ifndef _UTMPX_H_ +#define _UTMPX_H_ + +#include +#include +#include + +#ifndef _PID_T_DECLARED +typedef __pid_t pid_t; +#define _PID_T_DECLARED +#endif + +struct utmpx { + short ut_type; /* Type of entry. */ + struct timeval ut_tv; /* Time entry was made. */ + char ut_id[8]; /* Record identifier. */ + pid_t ut_pid; /* Process ID. */ + char ut_user[32]; /* User login name. */ + char ut_line[16]; /* Device name. */ +#if __BSD_VISIBLE + char ut_host[128]; /* Remote hostname. */ +#else + char __ut_host[128]; +#endif + char __ut_spare[64]; +}; + +#define EMPTY 0 /* No valid user accounting information. */ +#define BOOT_TIME 1 /* Time of system boot. */ +#define OLD_TIME 2 /* Time when system clock changed. */ +#define NEW_TIME 3 /* Time after system clock changed. */ +#define USER_PROCESS 4 /* A process. */ +#define INIT_PROCESS 5 /* A process spawned by the init process. */ +#define LOGIN_PROCESS 6 /* The session leader of a logged-in user. */ +#define DEAD_PROCESS 7 /* A session leader who has exited. */ +#if __BSD_VISIBLE +#define SHUTDOWN_TIME 8 /* Time of system shutdown. */ +#endif + +#if __BSD_VISIBLE +#define UTXDB_ACTIVE 0 /* Active login sessions. */ +#define UTXDB_LASTLOGIN 1 /* Last login sessions. */ +#define UTXDB_LOG 2 /* Log indexed by time. */ +#endif + +__BEGIN_DECLS +void endutxent(void); +struct utmpx *getutxent(void); +struct utmpx *getutxid(const struct utmpx *); +struct utmpx *getutxline(const struct utmpx *); +struct utmpx *pututxline(const struct utmpx *); +void setutxent(void); + +#if __BSD_VISIBLE +struct utmpx *getutxuser(const char *); +int setutxdb(int, const char *); +#endif +__END_DECLS + +#endif /* !_UTMPX_H_ */ diff --git a/include/uuid.h b/include/uuid.h new file mode 100644 index 0000000..365a614 --- /dev/null +++ b/include/uuid.h @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2002,2005 Marcel Moolenaar + * Copyright (c) 2002 Hiten Mahesh Pandya + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/uuid.h 183057 2008-09-15 23:47:19Z emax $ + */ + +#ifndef _UUID_H_ +#define _UUID_H_ + +#include +#include + +/* + * This implementation mostly conforms to the DCE 1.1 specification. + * See Also: + * uuidgen(1), uuidgen(2), uuid(3) + */ + +/* Status codes returned by the functions. */ +#define uuid_s_ok 0 +#define uuid_s_bad_version 1 +#define uuid_s_invalid_string_uuid 2 +#define uuid_s_no_memory 3 + +__BEGIN_DECLS +int32_t uuid_compare(const uuid_t *, const uuid_t *, uint32_t *); +void uuid_create(uuid_t *, uint32_t *); +void uuid_create_nil(uuid_t *, uint32_t *); +int32_t uuid_equal(const uuid_t *, const uuid_t *, uint32_t *); +void uuid_from_string(const char *, uuid_t *, uint32_t *); +uint16_t uuid_hash(const uuid_t *, uint32_t *); +int32_t uuid_is_nil(const uuid_t *, uint32_t *); +void uuid_to_string(const uuid_t *, char **, uint32_t *); +void uuid_enc_le(void *, const uuid_t *); +void uuid_dec_le(const void *, uuid_t *); +void uuid_enc_be(void *, const uuid_t *); +void uuid_dec_be(const void *, uuid_t *); +__END_DECLS + +#endif /* _UUID_H_ */ diff --git a/include/varargs.h b/include/varargs.h new file mode 100644 index 0000000..b1ac706 --- /dev/null +++ b/include/varargs.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2003 Alexander Kabaev + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/varargs.h 119630 2003-09-01 03:28:25Z kan $ + */ + +#ifndef _VARARGS_H_ +#define _VARARGS_H_ + +#if defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ > 2 || __GNUC__ >= 4) + +#error " is obsolete with this version of GCC." +#error "Change your code to use instead." + +#else /* ! __GNUC__ post GCC 3.3 */ + +#include + +#endif /* __GNUC__ post GCC 3.3 */ + +#endif /* !_VARARGS_H_ */ diff --git a/include/wctype.h b/include/wctype.h new file mode 100644 index 0000000..772e0f1 --- /dev/null +++ b/include/wctype.h @@ -0,0 +1,125 @@ +/*- + * Copyright (c)1999 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * citrus Id: wctype.h,v 1.4 2000/12/21 01:50:21 itojun Exp + * $NetBSD: wctype.h,v 1.3 2000/12/22 14:16:16 itojun Exp $ + * $FreeBSD: releng/11.1/include/wctype.h 290494 2015-11-07 12:43:35Z bapt $ + */ + +#ifndef _WCTYPE_H_ +#define _WCTYPE_H_ + +#include +#include + +#include <_ctype.h> + +#ifndef _WCTRANS_T +typedef int wctrans_t; +#define _WCTRANS_T +#endif + +#ifndef _WCTYPE_T +typedef unsigned long wctype_t; +#define _WCTYPE_T +#endif + +#ifndef _WINT_T_DECLARED +typedef __wint_t wint_t; +#define _WINT_T_DECLARED +#endif + +#ifndef WEOF +#define WEOF ((wint_t)-1) +#endif + +__BEGIN_DECLS +int iswalnum(wint_t); +int iswalpha(wint_t); +int iswblank(wint_t); +int iswcntrl(wint_t); +int iswctype(wint_t, wctype_t); +int iswdigit(wint_t); +int iswgraph(wint_t); +int iswlower(wint_t); +int iswprint(wint_t); +int iswpunct(wint_t); +int iswspace(wint_t); +int iswupper(wint_t); +int iswxdigit(wint_t); +wint_t towctrans(wint_t, wctrans_t); +wint_t towlower(wint_t); +wint_t towupper(wint_t); +wctrans_t + wctrans(const char *); +wctype_t + wctype(const char *); + +#if __BSD_VISIBLE +wint_t iswascii(wint_t); +wint_t iswhexnumber(wint_t); +wint_t iswideogram(wint_t); +wint_t iswnumber(wint_t); +wint_t iswphonogram(wint_t); +wint_t iswrune(wint_t); +wint_t iswspecial(wint_t); +wint_t nextwctype(wint_t, wctype_t); +#endif + +#if __POSIX_VISIBLE >= 200809 +#define _XLOCALE_WCTYPES 1 +#include +#endif /* __POSIX_VISIBLE >= 200809 */ +__END_DECLS + +#ifndef __cplusplus +#define iswalnum(wc) __istype((wc), _CTYPE_A|_CTYPE_D|_CTYPE_N) +#define iswalpha(wc) __istype((wc), _CTYPE_A) +#define iswblank(wc) __istype((wc), _CTYPE_B) +#define iswcntrl(wc) __istype((wc), _CTYPE_C) +#define iswctype(wc, charclass) __istype((wc), (charclass)) +#define iswdigit(wc) __istype((wc), _CTYPE_D) +#define iswgraph(wc) __istype((wc), _CTYPE_G) +#define iswlower(wc) __istype((wc), _CTYPE_L) +#define iswprint(wc) __istype((wc), _CTYPE_R) +#define iswpunct(wc) __istype((wc), _CTYPE_P) +#define iswspace(wc) __istype((wc), _CTYPE_S) +#define iswupper(wc) __istype((wc), _CTYPE_U) +#define iswxdigit(wc) __istype((wc), _CTYPE_X) +#define towlower(wc) __tolower(wc) +#define towupper(wc) __toupper(wc) + +#if __BSD_VISIBLE +#define iswascii(wc) (((wc) & ~0x7F) == 0) +#define iswhexnumber(wc) __istype((wc), _CTYPE_X) /* alias of iswxdigit */ +#define iswideogram(wc) __istype((wc), _CTYPE_I) +#define iswnumber(wc) __istype((wc), _CTYPE_D|_CTYPE_N) +#define iswphonogram(wc) __istype((wc), _CTYPE_Q) +#define iswrune(wc) __istype((wc), 0xFFFFFF00L) +#define iswspecial(wc) __istype((wc), _CTYPE_T) +#endif /* __BSD_VISIBLE */ +#endif /* __cplusplus */ + +#endif /* _WCTYPE_H_ */ diff --git a/include/wordexp.h b/include/wordexp.h new file mode 100644 index 0000000..560dba4 --- /dev/null +++ b/include/wordexp.h @@ -0,0 +1,75 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/wordexp.h 131331 2004-06-30 13:55:08Z tjr $ + */ + +#ifndef _WORDEXP_H_ +#define _WORDEXP_H_ + +#include +#include + +#if __XSI_VISIBLE && !defined(_SIZE_T_DECLARED) +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +typedef struct { + __size_t we_wordc; /* count of words matched */ + char **we_wordv; /* pointer to list of words */ + __size_t we_offs; /* slots to reserve in we_wordv */ + char *we_strings; /* storage for wordv strings */ + __size_t we_nbytes; /* size of we_strings */ +} wordexp_t; + +/* + * Flags for wordexp(). + */ +#define WRDE_APPEND 0x1 /* append to previously generated */ +#define WRDE_DOOFFS 0x2 /* we_offs member is valid */ +#define WRDE_NOCMD 0x4 /* disallow command substitution */ +#define WRDE_REUSE 0x8 /* reuse wordexp_t */ +#define WRDE_SHOWERR 0x10 /* don't redirect stderr to /dev/null */ +#define WRDE_UNDEF 0x20 /* disallow undefined shell vars */ + +/* + * Return values from wordexp(). + */ +#define WRDE_BADCHAR 1 /* unquoted special character */ +#define WRDE_BADVAL 2 /* undefined variable */ +#define WRDE_CMDSUB 3 /* command substitution not allowed */ +#define WRDE_NOSPACE 4 /* no memory for result */ +#if __XSI_VISIBLE +#define WRDE_NOSYS 5 /* obsolete, reserved */ +#endif +#define WRDE_SYNTAX 6 /* shell syntax error */ + +__BEGIN_DECLS +int wordexp(const char * __restrict, wordexp_t * __restrict, int); +void wordfree(wordexp_t *); +__END_DECLS + +#endif /* !_WORDEXP_H_ */ diff --git a/include/xlocale.h b/include/xlocale.h new file mode 100644 index 0000000..91b07ed --- /dev/null +++ b/include/xlocale.h @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale.h 232498 2012-03-04 15:31:13Z theraven $ + */ + +#ifndef _XLOCALE_H_ +#define _XLOCALE_H_ + +#include +__BEGIN_DECLS +#include + +#ifdef _STRING_H_ +#include +#endif + +#ifdef _INTTYPES_H_ +#include +#endif + +#ifdef _MONETARY_H_ +#include +#endif + +#ifdef _STDLIB_H_ +#include +#endif + +#ifdef _TIME_H_ +#include +#endif + +#ifdef _LANGINFO_H_ +#include +#endif + +#ifdef _CTYPE_H_ +#include +#endif + +#ifdef _WCTYPE_H_ +#define _XLOCALE_WCTYPES 1 +#include +#endif + +#ifdef _STDIO_H_ +#include +#endif + +#ifdef _WCHAR_H_ +#include +#endif + + + +struct lconv *localeconv_l(locale_t); +__END_DECLS + +#endif diff --git a/include/xlocale/Makefile b/include/xlocale/Makefile new file mode 100644 index 0000000..dc61882 --- /dev/null +++ b/include/xlocale/Makefile @@ -0,0 +1,7 @@ +# $FreeBSD: releng/11.1/include/xlocale/Makefile 284255 2015-06-11 04:22:17Z sjg $ + +INCS= _ctype.h _inttypes.h _langinfo.h _locale.h _monetary.h _stdio.h\ + _stdlib.h _string.h _strings.h _time.h _uchar.h _wchar.h +INCSDIR=${INCLUDEDIR}/xlocale + +.include diff --git a/include/xlocale/Makefile.depend b/include/xlocale/Makefile.depend new file mode 100644 index 0000000..1ab2fc1 --- /dev/null +++ b/include/xlocale/Makefile.depend @@ -0,0 +1,11 @@ +# $FreeBSD: releng/11.1/include/xlocale/Makefile.depend 284345 2015-06-13 19:20:56Z sjg $ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/include/xlocale/_ctype.h b/include/xlocale/_ctype.h new file mode 100644 index 0000000..7faf05d --- /dev/null +++ b/include/xlocale/_ctype.h @@ -0,0 +1,203 @@ +/*- + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale/_ctype.h 290494 2015-11-07 12:43:35Z bapt $ + */ + + +#if (defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_WCTYPE_H)) || \ + (!defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_CTYPE_H)) + +#ifdef _XLOCALE_WCTYPES +#define _XLOCALE_WCTYPE_H +#else +#define _XLOCALE_CTYPE_H +#endif + +#ifndef _LOCALE_T_DEFINED +#define _LOCALE_T_DEFINED +typedef struct _xlocale *locale_t; +#endif + +#ifndef _XLOCALE_RUN_FUNCTIONS_DEFINED +#define _XLOCALE_RUN_FUNCTIONS_DEFINED 1 +unsigned long ___runetype_l(__ct_rune_t, locale_t) __pure; +__ct_rune_t ___tolower_l(__ct_rune_t, locale_t) __pure; +__ct_rune_t ___toupper_l(__ct_rune_t, locale_t) __pure; +_RuneLocale *__runes_for_locale(locale_t, int*); +#endif + +#ifndef _XLOCALE_INLINE +#if defined(__GNUC__) && !defined(__GNUC_STDC_INLINE__) +/* GNU89 inline has nonstandard semantics. */ +#define _XLOCALE_INLINE extern __inline +#else +/* Hack to work around people who define inline away */ +#ifdef inline +#define _XLOCALE_INLINE static __inline +#else +/* Define with C++ / C99 compatible semantics */ +#define _XLOCALE_INLINE inline +#endif +#endif +#endif /* _XLOCALE_INLINE */ + +#ifdef _XLOCALE_WCTYPES +_XLOCALE_INLINE int +__maskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc); +_XLOCALE_INLINE int +__istype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc); + +_XLOCALE_INLINE int +__maskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc) +{ + int __limit; + _RuneLocale *runes = __runes_for_locale(__loc, &__limit); + return ((__c < 0 || __c >= _CACHED_RUNES) ? ___runetype_l(__c, __loc) : + runes->__runetype[__c]) & __f; +} + +_XLOCALE_INLINE int +__istype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc) +{ + return (!!__maskrune_l(__c, __f, __loc)); +} + +#define XLOCALE_ISCTYPE(fname, cat) \ + _XLOCALE_INLINE int isw##fname##_l(int, locale_t);\ + _XLOCALE_INLINE int isw##fname##_l(int __c, locale_t __l)\ + { return __istype_l(__c, cat, __l); } +#else +_XLOCALE_INLINE int +__sbmaskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc); +_XLOCALE_INLINE int +__sbistype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc); + +_XLOCALE_INLINE int +__sbmaskrune_l(__ct_rune_t __c, unsigned long __f, locale_t __loc) +{ + int __limit; + _RuneLocale *runes = __runes_for_locale(__loc, &__limit); + return (__c < 0 || __c >= __limit) ? 0 : + runes->__runetype[__c] & __f; +} + +_XLOCALE_INLINE int +__sbistype_l(__ct_rune_t __c, unsigned long __f, locale_t __loc) +{ + return (!!__sbmaskrune_l(__c, __f, __loc)); +} + +#define XLOCALE_ISCTYPE(__fname, __cat) \ + _XLOCALE_INLINE int is##__fname##_l(int, locale_t); \ + _XLOCALE_INLINE int is##__fname##_l(int __c, locale_t __l)\ + { return __sbistype_l(__c, __cat, __l); } +#endif + +XLOCALE_ISCTYPE(alnum, _CTYPE_A|_CTYPE_D|_CTYPE_N) +XLOCALE_ISCTYPE(alpha, _CTYPE_A) +XLOCALE_ISCTYPE(blank, _CTYPE_B) +XLOCALE_ISCTYPE(cntrl, _CTYPE_C) +XLOCALE_ISCTYPE(digit, _CTYPE_D) +XLOCALE_ISCTYPE(graph, _CTYPE_G) +XLOCALE_ISCTYPE(hexnumber, _CTYPE_X) +XLOCALE_ISCTYPE(ideogram, _CTYPE_I) +XLOCALE_ISCTYPE(lower, _CTYPE_L) +XLOCALE_ISCTYPE(number, _CTYPE_D|_CTYPE_N) +XLOCALE_ISCTYPE(phonogram, _CTYPE_Q) +XLOCALE_ISCTYPE(print, _CTYPE_R) +XLOCALE_ISCTYPE(punct, _CTYPE_P) +XLOCALE_ISCTYPE(rune, 0xFFFFFF00L) +XLOCALE_ISCTYPE(space, _CTYPE_S) +XLOCALE_ISCTYPE(special, _CTYPE_T) +XLOCALE_ISCTYPE(upper, _CTYPE_U) +XLOCALE_ISCTYPE(xdigit, _CTYPE_X) +#undef XLOCALE_ISCTYPE + +#ifdef _XLOCALE_WCTYPES +_XLOCALE_INLINE int towlower_l(int, locale_t); +_XLOCALE_INLINE int __wcwidth_l(__ct_rune_t, locale_t); +_XLOCALE_INLINE int towupper_l(int, locale_t); + +_XLOCALE_INLINE int towlower_l(int __c, locale_t __l) +{ + int __limit; + _RuneLocale *__runes = __runes_for_locale(__l, &__limit); + return (__c < 0 || __c >= _CACHED_RUNES) ? ___tolower_l(__c, __l) : + __runes->__maplower[__c]; +} +_XLOCALE_INLINE int towupper_l(int __c, locale_t __l) +{ + int __limit; + _RuneLocale *__runes = __runes_for_locale(__l, &__limit); + return (__c < 0 || __c >= _CACHED_RUNES) ? ___toupper_l(__c, __l) : + __runes->__mapupper[__c]; +} +_XLOCALE_INLINE int +__wcwidth_l(__ct_rune_t _c, locale_t __l) +{ + unsigned int _x; + + if (_c == 0) + return (0); + _x = (unsigned int)__maskrune_l(_c, _CTYPE_SWM|_CTYPE_R, __l); + if ((_x & _CTYPE_SWM) != 0) + return ((_x & _CTYPE_SWM) >> _CTYPE_SWS); + return ((_x & _CTYPE_R) != 0 ? 1 : -1); +} +int iswctype_l(wint_t __wc, wctype_t __charclass, locale_t __l); +wctype_t wctype_l(const char *property, locale_t __l); +wint_t towctrans_l(wint_t __wc, wctrans_t desc, locale_t __l); +wint_t nextwctype_l(wint_t __wc, wctype_t wct, locale_t __l); +wctrans_t wctrans_l(const char *__charclass, locale_t __l); +#undef _XLOCALE_WCTYPES +#else +_XLOCALE_INLINE int digittoint_l(int, locale_t); +_XLOCALE_INLINE int tolower_l(int, locale_t); +_XLOCALE_INLINE int toupper_l(int, locale_t); + +_XLOCALE_INLINE int digittoint_l(int __c, locale_t __l) +{ return __sbmaskrune_l((__c), 0xFF, __l); } + +_XLOCALE_INLINE int tolower_l(int __c, locale_t __l) +{ + int __limit; + _RuneLocale *__runes = __runes_for_locale(__l, &__limit); + return (__c < 0 || __c >= __limit) ? __c : + __runes->__maplower[__c]; +} +_XLOCALE_INLINE int toupper_l(int __c, locale_t __l) +{ + int __limit; + _RuneLocale *__runes = __runes_for_locale(__l, &__limit); + return (__c < 0 || __c >= __limit) ? __c : + __runes->__mapupper[__c]; +} +#endif +#endif /* (defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_WCTYPE_H)) || \ + (!defined(_XLOCALE_WCTYPES) && !defined(_XLOCALE_CTYPE_H)) */ diff --git a/include/xlocale/_inttypes.h b/include/xlocale/_inttypes.h new file mode 100644 index 0000000..0d3d767 --- /dev/null +++ b/include/xlocale/_inttypes.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale/_inttypes.h 231673 2012-02-14 12:03:23Z theraven $ + */ + + +/* + * Extended locale versions of the locale-aware functions from inttypes.h. + * Include before to expose these. + */ +intmax_t strtoimax_l(const char * __restrict, char ** __restrict, + int, locale_t); +uintmax_t strtoumax_l(const char * __restrict, char ** __restrict, int, + locale_t); +intmax_t wcstoimax_l(const wchar_t * __restrict, wchar_t ** __restrict, + int , locale_t); +uintmax_t wcstoumax_l(const wchar_t * __restrict, wchar_t ** __restrict, + int, locale_t); diff --git a/include/xlocale/_langinfo.h b/include/xlocale/_langinfo.h new file mode 100644 index 0000000..7337b06 --- /dev/null +++ b/include/xlocale/_langinfo.h @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale/_langinfo.h 231673 2012-02-14 12:03:23Z theraven $ + */ + +#ifndef _XLOCALE_LANGINFO_H +#define _XLOCALE_LANGINFO_H + +#ifndef _LOCALE_T_DEFINED +#define _LOCALE_T_DEFINED +typedef struct _xlocale *locale_t; +#endif + +char *nl_langinfo_l(nl_item, locale_t); + +#endif /* _XLOCALE_LANGINFO_H */ diff --git a/include/xlocale/_locale.h b/include/xlocale/_locale.h new file mode 100644 index 0000000..09efd53 --- /dev/null +++ b/include/xlocale/_locale.h @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale/_locale.h 304863 2016-08-26 21:23:38Z ache $ + */ + +#ifndef _XLOCALE_LOCALE_H +#define _XLOCALE_LOCALE_H + +/* Bit shifting order of LC_*_MASK should match XLC_* and LC_* order. */ +#define LC_COLLATE_MASK (1<<0) +#define LC_CTYPE_MASK (1<<1) +#define LC_MONETARY_MASK (1<<2) +#define LC_NUMERIC_MASK (1<<3) +#define LC_TIME_MASK (1<<4) +#define LC_MESSAGES_MASK (1<<5) +#define LC_ALL_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK | \ + LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK) +#define LC_GLOBAL_LOCALE ((locale_t)-1) + +#ifndef _LOCALE_T_DEFINED +#define _LOCALE_T_DEFINED +typedef struct _xlocale *locale_t; +#endif + +locale_t duplocale(locale_t base); +int freelocale(locale_t loc); +locale_t newlocale(int mask, const char *locale, locale_t base); +const char *querylocale(int mask, locale_t loc); +locale_t uselocale(locale_t loc); + +#endif /* _XLOCALE_LOCALE_H */ diff --git a/include/xlocale/_monetary.h b/include/xlocale/_monetary.h new file mode 100644 index 0000000..6694ee1 --- /dev/null +++ b/include/xlocale/_monetary.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale/_monetary.h 231673 2012-02-14 12:03:23Z theraven $ + */ + +#ifndef _LOCALE_T_DEFINED +#define _LOCALE_T_DEFINED +typedef struct _xlocale *locale_t; +#endif + +#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) +#ifndef _XLOCALE_MONETARY_H +#define _XLOCALE_MONETARY_H + +ssize_t strfmon_l(char *, size_t, locale_t, const char *, ...) + __strfmonlike(4, 5); + +#endif /* _XLOCALE_MONETARY_H */ +#endif /* __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) */ diff --git a/include/xlocale/_stdio.h b/include/xlocale/_stdio.h new file mode 100644 index 0000000..6846224 --- /dev/null +++ b/include/xlocale/_stdio.h @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale/_stdio.h 231673 2012-02-14 12:03:23Z theraven $ + */ + +int asprintf_l(char **, locale_t, const char *, ...) __printflike(3, 4); +int dprintf_l(int, locale_t, const char * __restrict, ...) + __printflike(3, 4); +int fprintf_l(FILE * __restrict, locale_t, const char * __restrict, ...) + __printflike(3, 4); +int fscanf_l(FILE * __restrict, locale_t, const char * __restrict, ...) + __scanflike(3, 4); +int printf_l(locale_t, const char * __restrict, ...) __printflike(2, 3); +int scanf_l(locale_t, const char * __restrict, ...) __scanflike(2, 3); +int snprintf_l(char * __restrict, size_t, locale_t, + const char * __restrict, ...) __printflike(4, 5); +int sprintf_l(char * __restrict, locale_t, const char * __restrict, ...) + __printflike(3, 4); +int sscanf_l(const char * __restrict, locale_t, const char * __restrict, + ...) __scanflike(3, 4); +int vfprintf_l(FILE * __restrict, locale_t, const char * __restrict, + __va_list) __printflike(3, 0); +int vprintf_l(locale_t, const char * __restrict, __va_list) + __printflike(2, 0); +int vsprintf_l(char * __restrict, locale_t, const char * __restrict, + __va_list) __printflike(3, 0); +int vfscanf_l(FILE * __restrict, locale_t, const char * __restrict, + __va_list) __scanflike(3, 0); +int vscanf_l(locale_t, const char * __restrict, __va_list) + __scanflike(2, 0); +int vsnprintf_l(char * __restrict, size_t, locale_t, + const char * __restrict, __va_list) __printflike(4, 0); +int vsscanf_l(const char * __restrict, locale_t, const char * __restrict, + __va_list) __scanflike(3, 0); +int vdprintf_l(int, locale_t, const char * __restrict, __va_list) + __printflike(3, 0); +int vasprintf_l(char **, locale_t, const char *, __va_list) + __printflike(3, 0); diff --git a/include/xlocale/_stdlib.h b/include/xlocale/_stdlib.h new file mode 100644 index 0000000..5c2345d --- /dev/null +++ b/include/xlocale/_stdlib.h @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale/_stdlib.h 231673 2012-02-14 12:03:23Z theraven $ + */ + +/* + * Extended locale versions of the locale-aware functions from stdlib.h. + * + * Include before to expose these. + */ +double atof_l(const char *, locale_t); +int atoi_l(const char *, locale_t); +long atol_l(const char *, locale_t); +long long atoll_l(const char *, locale_t); +int mblen_l(const char *, size_t, locale_t); +size_t mbstowcs_l(wchar_t * __restrict, + const char * __restrict, size_t, locale_t); +int mbtowc_l(wchar_t * __restrict, + const char * __restrict, size_t, locale_t); +double strtod_l(const char *, char **, locale_t); +float strtof_l(const char *, char **, locale_t); +long strtol_l(const char *, char **, int, locale_t); +long double strtold_l(const char *, char **, locale_t); +long long strtoll_l(const char *, char **, int, locale_t); +unsigned long strtoul_l(const char *, char **, int, locale_t); +unsigned long long strtoull_l(const char *, char **, int, locale_t); +size_t wcstombs_l(char * __restrict, + const wchar_t * __restrict, size_t, locale_t); +int wctomb_l(char *, wchar_t, locale_t); + +int ___mb_cur_max_l(locale_t); +#define MB_CUR_MAX_L(x) (___mb_cur_max_l(x)) + diff --git a/include/xlocale/_string.h b/include/xlocale/_string.h new file mode 100644 index 0000000..3b578be --- /dev/null +++ b/include/xlocale/_string.h @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale/_string.h 266865 2014-05-30 01:09:07Z pfg $ + */ + +#ifndef _LOCALE_T_DEFINED +#define _LOCALE_T_DEFINED +typedef struct _xlocale *locale_t; +#endif + +/* + * This file is included from both string.h and xlocale.h. We need to expose + * the declarations unconditionally if we are included from xlocale.h, but only + * if we are in POSIX2008 mode if included from string.h. + */ + +#ifndef _XLOCALE_STRING1_H +#define _XLOCALE_STRING1_H + +/* + * POSIX2008 functions + */ +int strcoll_l(const char *, const char *, locale_t); +size_t strxfrm_l(char *, const char *, size_t, locale_t); +#endif /* _XLOCALE_STRING1_H */ + +/* + * xlocale extensions + */ +#ifdef _XLOCALE_H_ +#ifndef _XLOCALE_STRING2_H +#define _XLOCALE_STRING2_H +char *strcasestr_l(const char *, const char *, locale_t); + +#endif /* _XLOCALE_STRING2_H */ +#endif /* _XLOCALE_H_ */ diff --git a/include/xlocale/_strings.h b/include/xlocale/_strings.h new file mode 100644 index 0000000..c02d366 --- /dev/null +++ b/include/xlocale/_strings.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale/_strings.h 266865 2014-05-30 01:09:07Z pfg $ + */ + +#ifndef _LOCALE_T_DEFINED +#define _LOCALE_T_DEFINED +typedef struct _xlocale *locale_t; +#endif + +/* + * This file is included from both strings.h and xlocale.h. We need to expose + * the declarations unconditionally if we are included from xlocale.h, but only + * if we are in POSIX2008 mode if included from string.h. + */ + +#ifndef _XLOCALE_STRINGS1_H +#define _XLOCALE_STRINGS1_H + +/* + * POSIX2008 functions + */ +int strcasecmp_l(const char *, const char *, locale_t); +int strncasecmp_l(const char *, const char *, size_t, locale_t); +#endif /* _XLOCALE_STRINGS1_H */ diff --git a/include/xlocale/_time.h b/include/xlocale/_time.h new file mode 100644 index 0000000..65ac11e --- /dev/null +++ b/include/xlocale/_time.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale/_time.h 231673 2012-02-14 12:03:23Z theraven $ + */ + +#ifndef _LOCALE_T_DEFINED +#define _LOCALE_T_DEFINED +typedef struct _xlocale *locale_t; +#endif + +/* + * This file is included from both locale.h and xlocale.h. We need to expose + * the declarations unconditionally if we are included from xlocale.h, but only + * if we are in POSIX2008 mode if included from locale.h. + */ +#ifndef _XLOCALE_LOCALE1_H +#define _XLOCALE_LOCALE1_H + +size_t strftime_l(char * __restrict, size_t, const char * __restrict, + const struct tm * __restrict, locale_t) __strftimelike(3, 0); + +#endif /* _XLOCALE_LOCALE1_H */ + +#ifdef _XLOCALE_H_ +#ifndef _XLOCALE_LOCALE2_H +#define _XLOCALE_LOCALE2_H + +char *strptime_l(const char * __restrict, const char * __restrict, + struct tm * __restrict, locale_t); + +#endif /* _XLOCALE_LOCALE2_H */ +#endif /* _XLOCALE_H_ */ diff --git a/include/xlocale/_uchar.h b/include/xlocale/_uchar.h new file mode 100644 index 0000000..04b50ee --- /dev/null +++ b/include/xlocale/_uchar.h @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2013 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale/_uchar.h 250883 2013-05-21 19:59:37Z ed $ + */ + +#ifndef _LOCALE_T_DEFINED +#define _LOCALE_T_DEFINED +typedef struct _xlocale *locale_t; +#endif + +#ifndef _XLOCALE_UCHAR_H_ +#define _XLOCALE_UCHAR_H_ + +size_t c16rtomb_l(char * __restrict, char16_t, mbstate_t * __restrict, + locale_t); +size_t c32rtomb_l(char * __restrict, char32_t, mbstate_t * __restrict, + locale_t); +size_t mbrtoc16_l(char16_t * __restrict, const char * __restrict, size_t, + mbstate_t * __restrict, locale_t); +size_t mbrtoc32_l(char32_t * __restrict, const char * __restrict, size_t, + mbstate_t * __restrict, locale_t); + +#endif /* _XLOCALE_UCHAR_H_ */ diff --git a/include/xlocale/_wchar.h b/include/xlocale/_wchar.h new file mode 100644 index 0000000..481f65f --- /dev/null +++ b/include/xlocale/_wchar.h @@ -0,0 +1,133 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/include/xlocale/_wchar.h 231673 2012-02-14 12:03:23Z theraven $ + */ + +#ifndef _LOCALE_T_DEFINED +#define _LOCALE_T_DEFINED +typedef struct _xlocale *locale_t; +#endif + +#ifndef _XLOCALE_WCHAR1_H +#define _XLOCALE_WCHAR1_H +int wcscasecmp_l(const wchar_t *, const wchar_t *, + locale_t); +int wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, + locale_t); +int wcscoll_l(const wchar_t *, const wchar_t *, locale_t); +size_t wcsxfrm_l(wchar_t * __restrict, + const wchar_t * __restrict, size_t, locale_t); + +#endif /* _XLOCALE_WCHAR1_H */ + +/* + * Only declare the non-POSIX functions if we're included from xlocale.h. + */ + +#ifdef _XLOCALE_H_ +#ifndef _XLOCALE_WCHAR2_H +#define _XLOCALE_WCHAR2_H + +wint_t btowc_l(int, locale_t); +wint_t fgetwc_l(FILE *, locale_t); +wchar_t *fgetws_l(wchar_t * __restrict, int, FILE * __restrict, + locale_t); +wint_t fputwc_l(wchar_t, FILE *, locale_t); +int fputws_l(const wchar_t * __restrict, FILE * __restrict, + locale_t); +int fwprintf_l(FILE * __restrict, locale_t, + const wchar_t * __restrict, ...); +int fwscanf_l(FILE * __restrict, locale_t, + const wchar_t * __restrict, ...); +wint_t getwc_l(FILE *, locale_t); +wint_t getwchar_l(locale_t); +size_t mbrlen_l(const char * __restrict, size_t, + mbstate_t * __restrict, locale_t); +size_t mbrtowc_l(wchar_t * __restrict, + const char * __restrict, size_t, + mbstate_t * __restrict, locale_t); +int mbsinit_l(const mbstate_t *, locale_t); +size_t mbsrtowcs_l(wchar_t * __restrict, + const char ** __restrict, size_t, + mbstate_t * __restrict, locale_t); +wint_t putwc_l(wchar_t, FILE *, locale_t); +wint_t putwchar_l(wchar_t, locale_t); +int swprintf_l(wchar_t * __restrict, size_t n, locale_t, + const wchar_t * __restrict, ...); +int swscanf_l(const wchar_t * __restrict, locale_t, + const wchar_t * __restrict, ...); +wint_t ungetwc_l(wint_t, FILE *, locale_t); +int vfwprintf_l(FILE * __restrict, locale_t, + const wchar_t * __restrict, __va_list); +int vswprintf_l(wchar_t * __restrict, size_t n, locale_t, + const wchar_t * __restrict, __va_list); +int vwprintf_l(locale_t, const wchar_t * __restrict, + __va_list); +size_t wcrtomb_l(char * __restrict, wchar_t, + mbstate_t * __restrict, locale_t); +size_t wcsftime_l(wchar_t * __restrict, size_t, + const wchar_t * __restrict, + const struct tm * __restrict, locale_t); +size_t wcsrtombs_l(char * __restrict, + const wchar_t ** __restrict, size_t, + mbstate_t * __restrict, locale_t); +double wcstod_l(const wchar_t * __restrict, + wchar_t ** __restrict, locale_t); +long wcstol_l(const wchar_t * __restrict, + wchar_t ** __restrict, int, locale_t); +unsigned long wcstoul_l(const wchar_t * __restrict, + wchar_t ** __restrict, int, locale_t); +int wcswidth_l(const wchar_t *, size_t, locale_t); +int wctob_l(wint_t, locale_t); +int wcwidth_l(wchar_t, locale_t); +int wprintf_l(locale_t, const wchar_t * __restrict, ...); +int wscanf_l(locale_t, const wchar_t * __restrict, ...); +int vfwscanf_l(FILE * __restrict, locale_t, + const wchar_t * __restrict, __va_list); +int vswscanf_l(const wchar_t * __restrict, locale_t, + const wchar_t *__restrict, __va_list); +int vwscanf_l(locale_t, const wchar_t * __restrict, + __va_list); +float wcstof_l(const wchar_t * __restrict, + wchar_t ** __restrict, locale_t); +long double wcstold_l(const wchar_t * __restrict, + wchar_t ** __restrict, locale_t); +long long wcstoll_l(const wchar_t * __restrict, + wchar_t ** __restrict, int, locale_t); +unsigned long long wcstoull_l(const wchar_t * __restrict, + wchar_t ** __restrict, int, locale_t); +size_t mbsnrtowcs_l(wchar_t * __restrict, + const char ** __restrict, size_t, size_t, + mbstate_t * __restrict, locale_t); +size_t wcsnrtombs_l(char * __restrict, + const wchar_t ** __restrict, size_t, size_t, + mbstate_t * __restrict, locale_t); + +#endif /* _XLOCALE_WCHAR_H */ +#endif /* _XLOCALE_H_ */ diff --git a/lib/Makefile.incl b/lib/Makefile.incl index c2b1de8..686ae00 100644 --- a/lib/Makefile.incl +++ b/lib/Makefile.incl @@ -5,7 +5,7 @@ #CFLAGS = -fpic -DPIC -O2 -fno-strict-aliasing -pipe -D__DBINTERFACE_PRIVATE -DPOSIX_MISTAKE -DBROKEN_DES -DPORTMAP -DDES_BUILTIN -DYP -DHESIOD -Wsystem-headers -Wall -Wno-format-y2k -Wno-uninitialized CFLAGS = -m32 -fno-builtin -Wno-uninitialized -O2 -fno-strict-aliasing -pipe -INCLUDES = -I../include -I../../../include -I../i386 -I../include +INCLUDES = -I../include -I../../../include_old -I../i386 INCLUDES = -I${INCLUDE} CFLAGS = -m32 ${WFLAGS} -Wall -nostdlib -nostdinc -fno-builtin -fno-exceptions -O diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 9a50d34..6e7a3b1 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -172,7 +172,7 @@ SUBDIR+= tests .endif -.include +.include .if !defined(_SKIP_BUILD) # We need libutil.h, get it directly to avoid diff --git a/lib/libc/Makefile.depend b/lib/libc/Makefile.depend new file mode 100644 index 0000000..ed747c4 --- /dev/null +++ b/lib/libc/Makefile.depend @@ -0,0 +1,18 @@ +# $FreeBSD: releng/11.1/lib/libc/Makefile.depend 295989 2016-02-24 17:20:11Z bdrewery $ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + include \ + include/rpc \ + include/rpcsvc \ + lib/${CSU_DIR} \ + lib/libcompiler_rt \ + usr.bin/yacc.host \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/lib/libc/Versions.def b/lib/libc/Versions.def new file mode 100644 index 0000000..cd6df01 --- /dev/null +++ b/lib/libc/Versions.def @@ -0,0 +1,42 @@ +# $FreeBSD: releng/11.1/lib/libc/Versions.def 304523 2016-08-20 11:54:11Z kib $ + +# +# Note: Whenever bumping the FBSD version, always make +# FBSDprivate_1.0 depend on the new FBSD version. +# This will keep it at the end of the dependency chain. +# + +# This is our first version; it depends on no other. +# This version was first added to 7.0-current. +FBSD_1.0 { +}; + +# This version was first added to 8.0-current. +FBSD_1.1 { +} FBSD_1.0; + +# This version was first added to 9.0-current. +FBSD_1.2 { +} FBSD_1.1; + +# This version was first added to 10.0-current. +FBSD_1.3 { +} FBSD_1.2; + +# This version was first added to 11.0-current. +FBSD_1.4 { +} FBSD_1.3; + +# This version was first added to 12.0-current. +FBSD_1.5 { +} FBSD_1.4; + + +# This is our private namespace. Any global interfaces that are +# strictly for use only by other FreeBSD applications and libraries +# are listed here. We use a separate namespace so we can write +# simple ABI-checking tools. +# +# Please do NOT increment the version of this namespace. +FBSDprivate_1.0 { +} FBSD_1.5; diff --git a/lib/libc/aarch64/Makefile.inc b/lib/libc/aarch64/Makefile.inc new file mode 100644 index 0000000..09ba4f8 --- /dev/null +++ b/lib/libc/aarch64/Makefile.inc @@ -0,0 +1,9 @@ +# $FreeBSD: releng/11.1/lib/libc/aarch64/Makefile.inc 315044 2017-03-11 02:51:29Z brooks $ +# +# Machine dependent definitions for the arm 64-bit architecture. +# + +# Long double is quad precision +GDTOASRCS+=strtorQ.c +SRCS+=machdep_ldisQ.c +SYM_MAPS+=${LIBC_SRCTOP}/aarch64/Symbol.map diff --git a/lib/libc/aarch64/SYS.h b/lib/libc/aarch64/SYS.h new file mode 100644 index 0000000..a222f51 --- /dev/null +++ b/lib/libc/aarch64/SYS.h @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2014 Andrew Turner + * Copyright (c) 2015 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/aarch64/SYS.h 281197 2015-04-07 09:52:14Z andrew $ + */ + +#include +#include + +#define _SYSCALL(name) \ + mov x8, SYS_ ## name; \ + svc 0 + +#define SYSCALL(name) \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + ret; \ +END(__sys_##name) + +#define PSEUDO(name) \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + b.cs cerror; \ + ret; \ +END(__sys_##name) + +#define RSYSCALL(name) \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + b.cs cerror; \ + ret; \ +END(__sys_##name) diff --git a/lib/libc/aarch64/Symbol.map b/lib/libc/aarch64/Symbol.map new file mode 100644 index 0000000..fc0095b --- /dev/null +++ b/lib/libc/aarch64/Symbol.map @@ -0,0 +1,38 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/aarch64/Symbol.map 300303 2016-05-20 15:04:48Z andrew $ + */ + +/* + * This only needs to contain symbols that are not listed in + * symbol maps from other parts of libc (i.e., not found in + * stdlib/Symbol.map, string/Symbol.map, sys/Symbol.map, ...). + */ +FBSD_1.0 { + /* PSEUDO syscalls */ + _exit; + + _setjmp; + _longjmp; + fabs; + __flt_rounds; + fpgetmask; + fpsetmask; + __infinity; + __nan; + setjmp; + longjmp; + sigsetjmp; + siglongjmp; + htonl; + htons; + ntohl; + ntohs; + vfork; + makecontext; +}; + +FBSDprivate_1.0 { + _set_tp; + _end; + __makecontext; +}; diff --git a/lib/libc/aarch64/_fpmath.h b/lib/libc/aarch64/_fpmath.h new file mode 100644 index 0000000..95c5a6e --- /dev/null +++ b/lib/libc/aarch64/_fpmath.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * Copyright (2) 2014 The FreeBSD Foundation + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/aarch64/_fpmath.h 281197 2015-04-07 09:52:14Z andrew $ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned long manl :64; + unsigned long manh :48; + unsigned int exp :15; + unsigned int sign :1; + } bits; + /* TODO andrew: Check the packing here */ + struct { + unsigned long manl :64; + unsigned long manh :48; + unsigned int expsign :16; + } xbits; +}; + +#define LDBL_NBIT 0 +#define LDBL_IMPLICIT_NBIT +#define mask_nbit_l(u) ((void)0) + +#define LDBL_MANH_SIZE 48 +#define LDBL_MANL_SIZE 64 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)((u).bits.manl >> 32); \ + (a)[2] = (uint32_t)(u).bits.manh; \ + (a)[3] = (uint32_t)((u).bits.manh >> 32); \ +} while(0) diff --git a/lib/libc/aarch64/arith.h b/lib/libc/aarch64/arith.h new file mode 100644 index 0000000..b84e00d --- /dev/null +++ b/lib/libc/aarch64/arith.h @@ -0,0 +1,19 @@ +/* + * MD header for contrib/gdtoa + * + * $FreeBSD: releng/11.1/lib/libc/aarch64/arith.h 281197 2015-04-07 09:52:14Z andrew $ + */ + +/* + * NOTE: The definitions in this file must be correct or strtod(3) and + * floating point formats in printf(3) will break! The file can be + * generated by running contrib/gdtoa/arithchk.c on the target + * architecture. See contrib/gdtoa/gdtoaimp.h for details. + */ + +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#define Long int +#define Intcast (int)(long) +#define Double_Align +#define X64_bit_pointers diff --git a/lib/libc/aarch64/gd_qnan.h b/lib/libc/aarch64/gd_qnan.h new file mode 100644 index 0000000..b0888d6 --- /dev/null +++ b/lib/libc/aarch64/gd_qnan.h @@ -0,0 +1,21 @@ +/* + * MD header for contrib/gdtoa + * + * This file can be generated by compiling and running contrib/gdtoa/qnan.c + * on the target architecture after arith.h has been generated. + * + * $FreeBSD: releng/11.1/lib/libc/aarch64/gd_qnan.h 281197 2015-04-07 09:52:14Z andrew $ + */ + +#define f_QNAN 0x7fc00000 +#define d_QNAN0 0x0 +#define d_QNAN1 0x7ff80000 +#define ld_QNAN0 0x0 +#define ld_QNAN1 0x0 +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x7fff8000 +#define ldus_QNAN0 0x0 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0x0 +#define ldus_QNAN4 0x0 diff --git a/lib/libc/aarch64/gen/Makefile.inc b/lib/libc/aarch64/gen/Makefile.inc new file mode 100644 index 0000000..7d67490 --- /dev/null +++ b/lib/libc/aarch64/gen/Makefile.inc @@ -0,0 +1,17 @@ +# $FreeBSD: releng/11.1/lib/libc/aarch64/gen/Makefile.inc 297619 2016-04-06 16:09:10Z andrew $ + +CFLAGS+= -DNO_COMPAT7 + +SRCS+= _ctx_start.S \ + fabs.S \ + flt_rounds.c \ + fpgetmask.c \ + fpsetmask.c \ + infinity.c \ + ldexp.c \ + makecontext.c \ + _setjmp.S \ + _set_tp.c \ + setjmp.S \ + sigsetjmp.S \ + trivial-getcontextx.c diff --git a/lib/libc/aarch64/gen/_ctx_start.S b/lib/libc/aarch64/gen/_ctx_start.S new file mode 100644 index 0000000..e1482fe --- /dev/null +++ b/lib/libc/aarch64/gen/_ctx_start.S @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2015 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/gen/_ctx_start.S 285352 2015-07-10 08:36:22Z andrew $"); + +ENTRY(_ctx_start) + blr x19 /* Call func from makecontext */ + mov x0, x20 /* Load ucp saved in makecontext */ + bl _C_LABEL(ctx_done) + bl _C_LABEL(abort) +END(_ctx_start) diff --git a/lib/libc/aarch64/gen/_set_tp.c b/lib/libc/aarch64/gen/_set_tp.c new file mode 100644 index 0000000..e6956d8 --- /dev/null +++ b/lib/libc/aarch64/gen/_set_tp.c @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2014 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/gen/_set_tp.c 288019 2015-09-20 04:59:01Z rodrigc $"); + +#include +#include + +#include + +#include +#include "libc_private.h" + +void +_set_tp(void *tp) +{ + + asm volatile("msr tpidr_el0, %0" : : "r"(tp)); +} diff --git a/lib/libc/aarch64/gen/_setjmp.S b/lib/libc/aarch64/gen/_setjmp.S new file mode 100644 index 0000000..dc816ec --- /dev/null +++ b/lib/libc/aarch64/gen/_setjmp.S @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 2014 Andrew Turner + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Andrew Turner + * under sponsorship from the FreeBSD Foundation + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/gen/_setjmp.S 284768 2015-06-24 16:15:32Z andrew $"); + +#include + +ENTRY(_setjmp) + /* Store the magic value and stack pointer */ + ldr x8, .Lmagic + mov x9, sp + stp x8, x9, [x0], #16 + + /* Store the general purpose registers and lr */ + stp x19, x20, [x0], #16 + stp x21, x22, [x0], #16 + stp x23, x24, [x0], #16 + stp x25, x26, [x0], #16 + stp x27, x28, [x0], #16 + stp x29, lr, [x0], #16 + +#ifndef _STANDALONE + /* Store the vfp registers */ + stp d8, d9, [x0], #16 + stp d10, d11, [x0], #16 + stp d12, d13, [x0], #16 + stp d14, d15, [x0] +#endif + + /* Return value */ + mov x0, #0 + ret + .align 3 +.Lmagic: + .quad _JB_MAGIC__SETJMP +END(_setjmp) + +ENTRY(_longjmp) + /* Check the magic value */ + ldr x8, [x0], #8 + ldr x9, .Lmagic + cmp x8, x9 + b.ne botch + + /* Restore the stack pointer */ + ldr x8, [x0], #8 + mov sp, x8 + + /* Restore the general purpose registers and lr */ + ldp x19, x20, [x0], #16 + ldp x21, x22, [x0], #16 + ldp x23, x24, [x0], #16 + ldp x25, x26, [x0], #16 + ldp x27, x28, [x0], #16 + ldp x29, lr, [x0], #16 + +#ifndef _STANDALONE + /* Restore the vfp registers */ + ldp d8, d9, [x0], #16 + ldp d10, d11, [x0], #16 + ldp d12, d13, [x0], #16 + ldp d14, d15, [x0] +#endif + + /* Load the return value */ + mov x0, x1 + ret + +botch: +#ifdef _STANDALONE + b botch +#else + bl _C_LABEL(longjmperror) + bl _C_LABEL(abort) +#endif +END(_longjmp) diff --git a/lib/libc/aarch64/gen/fabs.S b/lib/libc/aarch64/gen/fabs.S new file mode 100644 index 0000000..ab8d840 --- /dev/null +++ b/lib/libc/aarch64/gen/fabs.S @@ -0,0 +1,33 @@ +/*- + * Copyright (c) 2015 The FreeBSD Foundation + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/gen/fabs.S 282909 2015-05-14 17:12:45Z emaste $"); + +ENTRY(fabs) + fabs d0, d0 + ret +END(fabs) diff --git a/lib/libc/aarch64/gen/flt_rounds.c b/lib/libc/aarch64/gen/flt_rounds.c new file mode 100644 index 0000000..138cdb3 --- /dev/null +++ b/lib/libc/aarch64/gen/flt_rounds.c @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2012 Ian Lepore + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/gen/flt_rounds.c 281197 2015-04-07 09:52:14Z andrew $"); + +#include + +#include +#include + +static int map[] = { + 1, /* round to nearest */ + 2, /* round to positive infinity */ + 3, /* round to negative infinity */ + 0 /* round to zero */ +}; + +int +__flt_rounds(void) +{ + uint64_t fpcr; + + asm volatile("mrs %0, fpcr" : "=r" (fpcr)); + return map[(fpcr >> 22) & 3]; +} diff --git a/lib/libc/aarch64/gen/fpgetmask.c b/lib/libc/aarch64/gen/fpgetmask.c new file mode 100644 index 0000000..2b1be21 --- /dev/null +++ b/lib/libc/aarch64/gen/fpgetmask.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2015 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/gen/fpgetmask.c 284807 2015-06-25 08:22:25Z andrew $"); + +#include +#include + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except_t +fpgetmask(void) +{ + uint64_t mask; + + /* Read the current mask */ + __asm __volatile("mrs %0, fpcr" : "=&r"(mask)); + + return (mask & FP_X_MASK); +} diff --git a/lib/libc/aarch64/gen/fpsetmask.c b/lib/libc/aarch64/gen/fpsetmask.c new file mode 100644 index 0000000..deefea1 --- /dev/null +++ b/lib/libc/aarch64/gen/fpsetmask.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2015 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/gen/fpsetmask.c 284769 2015-06-24 16:18:58Z andrew $"); + +#include +#include + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except_t +fpsetmask(fp_except_t mask) +{ + uint64_t old, new; + + mask &= FP_X_MASK; + + /* Read the current mask */ + __asm __volatile("mrs %0, fpcr" : "=&r"(old)); + new = old & ~FP_X_MASK; + new |= mask; + __asm __volatile("msr fpcr, %0" :: "r"(new)); + + return ((fp_except_t)old); +} diff --git a/lib/libc/aarch64/gen/infinity.c b/lib/libc/aarch64/gen/infinity.c new file mode 100644 index 0000000..09525c1 --- /dev/null +++ b/lib/libc/aarch64/gen/infinity.c @@ -0,0 +1,14 @@ +/* + * infinity.c + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/gen/infinity.c 286959 2015-08-20 13:11:52Z andrew $"); + +#include + +/* bytes for +Infinity on aarch64 */ +const union __infinity_un __infinity = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; + +/* bytes for NaN */ +const union __nan_un __nan = { { 0, 0, 0xc0, 0xff } }; diff --git a/lib/libc/aarch64/gen/makecontext.c b/lib/libc/aarch64/gen/makecontext.c new file mode 100644 index 0000000..889144a --- /dev/null +++ b/lib/libc/aarch64/gen/makecontext.c @@ -0,0 +1,86 @@ +/*- + * Copyright (c) 2015 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/gen/makecontext.c 285352 2015-07-10 08:36:22Z andrew $"); + +#include + +#include + +#include +#include +#include +#include + +void _ctx_start(void); + +void +ctx_done(ucontext_t *ucp) +{ + + if (ucp->uc_link == NULL) { + exit(0); + } else { + setcontext((const ucontext_t *)ucp->uc_link); + abort(); + } +} + +__weak_reference(__makecontext, makecontext); + +void +__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) +{ + struct gpregs *gp; + va_list ap; + int i; + + /* A valid context is required. */ + if (ucp == NULL) + return; + + if ((argc < 0) || (argc > 8)) + return; + + gp = &ucp->uc_mcontext.mc_gpregs; + + va_start(ap, argc); + /* Pass up to eight arguments in x0-7. */ + for (i = 0; i < argc && i < 8; i++) + gp->gp_x[i] = va_arg(ap, uint64_t); + va_end(ap); + + /* Set the stack */ + gp->gp_sp = STACKALIGN(ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + /* Arrange for return via the trampoline code. */ + gp->gp_elr = (__register_t)_ctx_start; + gp->gp_x[19] = (__register_t)func; + gp->gp_x[20] = (__register_t)ucp; +} diff --git a/lib/libc/aarch64/gen/setjmp.S b/lib/libc/aarch64/gen/setjmp.S new file mode 100644 index 0000000..6a9fdf4 --- /dev/null +++ b/lib/libc/aarch64/gen/setjmp.S @@ -0,0 +1,123 @@ +/*- + * Copyright (c) 2014 Andrew Turner + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Andrew Turner + * under sponsorship from the FreeBSD Foundation + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/gen/setjmp.S 284768 2015-06-24 16:15:32Z andrew $"); + +#include + +ENTRY(setjmp) + sub sp, sp, #16 + stp x0, lr, [sp] + + /* Store the signal mask */ + add x2, x0, #(_JB_SIGMASK * 8) /* oset */ + mov x1, #0 /* set */ + mov x0, #1 /* SIG_BLOCK */ + bl sigprocmask + + ldp x0, lr, [sp] + add sp, sp, #16 + + /* Store the magic value and stack pointer */ + ldr x8, .Lmagic + mov x9, sp + stp x8, x9, [x0], #16 + + /* Store the general purpose registers and lr */ + stp x19, x20, [x0], #16 + stp x21, x22, [x0], #16 + stp x23, x24, [x0], #16 + stp x25, x26, [x0], #16 + stp x27, x28, [x0], #16 + stp x29, lr, [x0], #16 + + /* Store the vfp registers */ + stp d8, d9, [x0], #16 + stp d10, d11, [x0], #16 + stp d12, d13, [x0], #16 + stp d14, d15, [x0] + + /* Return value */ + mov x0, #0 + ret + .align 3 +.Lmagic: + .quad _JB_MAGIC_SETJMP +END(setjmp) + +ENTRY(longjmp) + sub sp, sp, #32 + stp x0, lr, [sp] + str x1, [sp, #16] + + /* Restore the signal mask */ + mov x2, #0 /* oset */ + add x1, x0, #(_JB_SIGMASK * 8) /* set */ + mov x0, #3 /* SIG_BLOCK */ + bl sigprocmask + + ldr x1, [sp, #16] + ldp x0, lr, [sp] + add sp, sp, #32 + + /* Check the magic value */ + ldr x8, [x0], #8 + ldr x9, .Lmagic + cmp x8, x9 + b.ne botch + + /* Restore the stack pointer */ + ldr x8, [x0], #8 + mov sp, x8 + + /* Restore the general purpose registers and lr */ + ldp x19, x20, [x0], #16 + ldp x21, x22, [x0], #16 + ldp x23, x24, [x0], #16 + ldp x25, x26, [x0], #16 + ldp x27, x28, [x0], #16 + ldp x29, lr, [x0], #16 + + /* Restore the vfp registers */ + ldp d8, d9, [x0], #16 + ldp d10, d11, [x0], #16 + ldp d12, d13, [x0], #16 + ldp d14, d15, [x0] + + /* Load the return value */ + mov x0, x1 + ret + +botch: + bl _C_LABEL(longjmperror) + bl _C_LABEL(abort) +END(longjmp) diff --git a/lib/libc/aarch64/gen/sigsetjmp.S b/lib/libc/aarch64/gen/sigsetjmp.S new file mode 100644 index 0000000..028b4cd --- /dev/null +++ b/lib/libc/aarch64/gen/sigsetjmp.S @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/gen/sigsetjmp.S 284768 2015-06-24 16:15:32Z andrew $"); + +#include + +ENTRY(sigsetjmp) + cmp x1, #0 + b.eq _C_LABEL(_setjmp) + b _C_LABEL(setjmp) +END(sigsetjmp) + +ENTRY(siglongjmp) + /* Load the _setjmp magic */ + ldr x2, .Lmagic + ldr x3, [x0] + + /* Check the magic */ + cmp x2, x3 + b.eq _C_LABEL(_longjmp) + b _C_LABEL(longjmp) + .align 3 +.Lmagic: + .quad _JB_MAGIC__SETJMP +END(siglongjmp) diff --git a/lib/libc/aarch64/sys/Makefile.inc b/lib/libc/aarch64/sys/Makefile.inc new file mode 100644 index 0000000..ef89a0e --- /dev/null +++ b/lib/libc/aarch64/sys/Makefile.inc @@ -0,0 +1,24 @@ +# $FreeBSD: releng/11.1/lib/libc/aarch64/sys/Makefile.inc 305330 2016-09-03 09:24:33Z kib $ + +MIASM:= ${MIASM:Nfreebsd[467]_*} + +SRCS+= __vdso_gettc.c + +MDASM= cerror.S \ + shmat.S \ + sigreturn.S \ + syscall.S \ + vfork.S + +# Don't generate default code for these syscalls: +NOASM= break.o \ + exit.o \ + getlogin.o \ + openbsd_poll.o \ + sbrk.o \ + sstk.o \ + vfork.o \ + yield.o + +PSEUDO= _exit.o \ + _getlogin.o diff --git a/lib/libc/aarch64/sys/__vdso_gettc.c b/lib/libc/aarch64/sys/__vdso_gettc.c new file mode 100644 index 0000000..852f516 --- /dev/null +++ b/lib/libc/aarch64/sys/__vdso_gettc.c @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2015 The FreeBSD Foundation + * + * This software was developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/sys/__vdso_gettc.c 305866 2016-09-16 10:04:28Z kib $"); + +#include +#include +#include +#include +#include +#include +#include "libc_private.h" + +static inline uint64_t +cp15_cntvct_get(void) +{ + uint64_t reg; + + __asm __volatile("mrs %0, cntvct_el0" : "=r" (reg)); + return (reg); +} + +static inline uint64_t +cp15_cntpct_get(void) +{ + uint64_t reg; + + __asm __volatile("mrs %0, cntpct_el0" : "=r" (reg)); + return (reg); +} + +#pragma weak __vdso_gettc +int +__vdso_gettc(const struct vdso_timehands *th, u_int *tc) +{ + + if (th->th_algo != VDSO_TH_ALGO_ARM_GENTIM) + return (ENOSYS); + __asm __volatile("isb" : : : "memory"); + *tc = th->th_physical == 0 ? cp15_cntvct_get() : cp15_cntpct_get(); + return (0); +} + +#pragma weak __vdso_gettimekeep +int +__vdso_gettimekeep(struct vdso_timekeep **tk) +{ + + return (_elf_aux_info(AT_TIMEKEEP, tk, sizeof(*tk))); +} diff --git a/lib/libc/aarch64/sys/cerror.S b/lib/libc/aarch64/sys/cerror.S new file mode 100644 index 0000000..f8e6209 --- /dev/null +++ b/lib/libc/aarch64/sys/cerror.S @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2014 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/sys/cerror.S 319195 2017-05-30 10:50:15Z andrew $"); + +ENTRY(cerror) + .hidden cerror + sub sp, sp, #16 + stp x0, lr, [sp] + bl _C_LABEL(__error) + ldp x1, lr, [sp] + str w1, [x0] + movn x0, #0 + movn x1, #0 + add sp, sp, #16 + ret +END(cerror) diff --git a/lib/libc/aarch64/sys/shmat.S b/lib/libc/aarch64/sys/shmat.S new file mode 100644 index 0000000..b5368cf --- /dev/null +++ b/lib/libc/aarch64/sys/shmat.S @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/sys/shmat.S 281197 2015-04-07 09:52:14Z andrew $"); + +#include "SYS.h" + +RSYSCALL(shmat) diff --git a/lib/libc/aarch64/sys/sigreturn.S b/lib/libc/aarch64/sys/sigreturn.S new file mode 100644 index 0000000..1851faf --- /dev/null +++ b/lib/libc/aarch64/sys/sigreturn.S @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/sys/sigreturn.S 281197 2015-04-07 09:52:14Z andrew $"); + +#include "SYS.h" + +RSYSCALL(sigreturn) diff --git a/lib/libc/aarch64/sys/syscall.S b/lib/libc/aarch64/sys/syscall.S new file mode 100644 index 0000000..2fefaaf --- /dev/null +++ b/lib/libc/aarch64/sys/syscall.S @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/sys/syscall.S 281197 2015-04-07 09:52:14Z andrew $"); + +#include "SYS.h" + +RSYSCALL(syscall) diff --git a/lib/libc/aarch64/sys/vfork.S b/lib/libc/aarch64/sys/vfork.S new file mode 100644 index 0000000..0a73ad6 --- /dev/null +++ b/lib/libc/aarch64/sys/vfork.S @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2014 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/aarch64/sys/vfork.S 281197 2015-04-07 09:52:14Z andrew $"); +#include "SYS.h" + +ENTRY(__sys_vfork) + WEAK_REFERENCE(__sys_vfork, vfork) + WEAK_REFERENCE(__sys_vfork, _vfork) + mov x2, lr + _SYSCALL(vfork) + b.cs cerror + sub x1, x1, #1 + and x0, x0, x1 + mov lr, x2 + ret +END(__sys_vfork) diff --git a/lib/libc/amd64/Makefile.inc b/lib/libc/amd64/Makefile.inc new file mode 100644 index 0000000..10033d8 --- /dev/null +++ b/lib/libc/amd64/Makefile.inc @@ -0,0 +1,9 @@ +# $FreeBSD: releng/11.1/lib/libc/amd64/Makefile.inc 315044 2017-03-11 02:51:29Z brooks $ +# +# Machine dependent definitions for the amd64 architecture. +# + +# Long double is 80 bits +GDTOASRCS+=strtorx.c +SRCS+=machdep_ldisx.c +SYM_MAPS+=${LIBC_SRCTOP}/amd64/Symbol.map diff --git a/lib/libc/amd64/SYS.h b/lib/libc/amd64/SYS.h new file mode 100644 index 0000000..e93a534 --- /dev/null +++ b/lib/libc/amd64/SYS.h @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 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. + * + * @(#)SYS.h 5.5 (Berkeley) 5/7/91 + * $FreeBSD: releng/11.1/lib/libc/amd64/SYS.h 258447 2013-11-21 21:25:58Z andreast $ + */ + +#include +#include + +#define RSYSCALL(name) ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + mov $SYS_##name,%eax; KERNCALL; \ + jb HIDENAME(cerror); ret; \ + END(__sys_##name) + +#define PSEUDO(name) ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + mov $SYS_##name,%eax; KERNCALL; \ + jb HIDENAME(cerror); ret; \ + END(__sys_##name) + +#define KERNCALL movq %rcx, %r10; syscall diff --git a/lib/libc/amd64/Symbol.map b/lib/libc/amd64/Symbol.map new file mode 100644 index 0000000..7fb88f3 --- /dev/null +++ b/lib/libc/amd64/Symbol.map @@ -0,0 +1,70 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/amd64/Symbol.map 297238 2016-03-24 18:47:19Z emaste $ + */ + +/* + * This only needs to contain symbols that are not listed in + * symbol maps from other parts of libc (i.e., not found in + * stdlib/Symbol.map, string/Symbol.map, sys/Symbol.map, ...). + */ +FBSD_1.0 { + /* PSEUDO syscalls */ + _exit; + + .mcount; + _setjmp; + _longjmp; + fabs; + __flt_rounds; + fpgetmask; + fpgetprec; + fpgetround; + fpgetsticky; + fpsetmask; + fpsetprec; + fpsetround; + __infinity; + __nan; + makecontext; + rfork_thread; + setjmp; + longjmp; + sigsetjmp; + siglongjmp; + htonl; + htons; + ntohl; + ntohs; + amd64_get_fsbase; + amd64_get_gsbase; + amd64_set_fsbase; + amd64_set_gsbase; + brk; + exect; + sbrk; + vfork; +}; + +/* + * + * FreeBSD private ABI + * + */ +FBSDprivate_1.0 { + /* PSEUDO syscalls */ + __sys_getlogin; + _getlogin; + __sys_exit; + + _set_tp; + ___longjmp; + __makecontext; + __longjmp; + __signalcontext; + signalcontext; + __siglongjmp; + _brk; + _end; + __sys_vfork; + _vfork; +}; diff --git a/lib/libc/amd64/_fpmath.h b/lib/libc/amd64/_fpmath.h new file mode 100644 index 0000000..a551b7c --- /dev/null +++ b/lib/libc/amd64/_fpmath.h @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/amd64/_fpmath.h 175402 2008-01-17 16:39:07Z bde $ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned int manl :32; + unsigned int manh :32; + unsigned int exp :15; + unsigned int sign :1; + unsigned int junkl :16; + unsigned int junkh :32; + } bits; + struct { + unsigned long man :64; + unsigned int expsign :16; + unsigned long junk :48; + } xbits; +}; + +#define LDBL_NBIT 0x80000000 +#define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT) + +#define LDBL_MANH_SIZE 32 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while (0) diff --git a/lib/libc/amd64/arith.h b/lib/libc/amd64/arith.h new file mode 100644 index 0000000..88291ea --- /dev/null +++ b/lib/libc/amd64/arith.h @@ -0,0 +1,19 @@ +/* + * MD header for contrib/gdtoa + * + * $FreeBSD: releng/11.1/lib/libc/amd64/arith.h 114839 2003-05-08 13:50:44Z das $ + */ + +/* + * NOTE: The definitions in this file must be correct or strtod(3) and + * floating point formats in printf(3) will break! The file can be + * generated by running contrib/gdtoa/arithchk.c on the target + * architecture. See contrib/gdtoa/gdtoaimp.h for details. + */ + +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#define Long int +#define Intcast (int)(long) +#define Double_Align +#define X64_bit_pointers diff --git a/lib/libc/amd64/gd_qnan.h b/lib/libc/amd64/gd_qnan.h new file mode 100644 index 0000000..9d5ccc4 --- /dev/null +++ b/lib/libc/amd64/gd_qnan.h @@ -0,0 +1,21 @@ +/* + * MD header for contrib/gdtoa + * + * This file can be generated by compiling and running contrib/gdtoa/qnan.c + * on the target architecture after arith.h has been generated. + * + * $FreeBSD: releng/11.1/lib/libc/amd64/gd_qnan.h 174680 2007-12-16 21:15:09Z das $ + */ + +#define f_QNAN 0x7fc00000 +#define d_QNAN0 0x0 +#define d_QNAN1 0x7ff80000 +#define ld_QNAN0 0x0 +#define ld_QNAN1 0xc0000000 +#define ld_QNAN2 0x7fff +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x0 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0xc000 +#define ldus_QNAN4 0x7fff diff --git a/lib/libc/amd64/gen/Makefile.inc b/lib/libc/amd64/gen/Makefile.inc new file mode 100644 index 0000000..5daf460 --- /dev/null +++ b/lib/libc/amd64/gen/Makefile.inc @@ -0,0 +1,8 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/amd64/gen/Makefile.inc 230429 2012-01-21 18:00:28Z kib $ + +SRCS+= _setjmp.S _set_tp.c rfork_thread.S setjmp.S sigsetjmp.S \ + fabs.S getcontextx.c \ + infinity.c ldexp.c makecontext.c signalcontext.c \ + flt_rounds.c fpgetmask.c fpsetmask.c fpgetprec.c fpsetprec.c \ + fpgetround.c fpsetround.c fpgetsticky.c diff --git a/lib/libc/amd64/gen/_set_tp.c b/lib/libc/amd64/gen/_set_tp.c new file mode 100644 index 0000000..ffd89b4 --- /dev/null +++ b/lib/libc/amd64/gen/_set_tp.c @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/amd64/gen/_set_tp.c 288019 2015-09-20 04:59:01Z rodrigc $ + */ + +#include +#include +#include +#include "libc_private.h" + +void +_set_tp(void *tp) +{ + + amd64_set_fsbase(tp); +} diff --git a/lib/libc/amd64/gen/_setjmp.S b/lib/libc/amd64/gen/_setjmp.S new file mode 100644 index 0000000..7e056fb --- /dev/null +++ b/lib/libc/amd64/gen/_setjmp.S @@ -0,0 +1,95 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) + .asciz "@(#)_setjmp.s 5.1 (Berkeley) 4/23/90" +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/gen/_setjmp.S 258447 2013-11-21 21:25:58Z andreast $"); + +/* + * C library -- _setjmp, _longjmp + * + * _longjmp(a,v) + * will generate a "return(v)" from the last call to + * _setjmp(a) + * by restoring registers from the environment 'a'. + * The previous signal state is NOT restored. + */ + +ENTRY(_setjmp) + movq %rdi,%rax + movq 0(%rsp),%rdx /* retval */ + movq %rdx, 0(%rax) /* 0; retval */ + movq %rbx, 8(%rax) /* 1; rbx */ + movq %rsp,16(%rax) /* 2; rsp */ + movq %rbp,24(%rax) /* 3; rbp */ + movq %r12,32(%rax) /* 4; r12 */ + movq %r13,40(%rax) /* 5; r13 */ + movq %r14,48(%rax) /* 6; r14 */ + movq %r15,56(%rax) /* 7; r15 */ + fnstcw 64(%rax) /* 8; fpu cw */ + stmxcsr 68(%rax) /* and mxcsr */ + xorq %rax,%rax + ret +END(_setjmp) + + WEAK_REFERENCE(___longjmp, _longjmp) +ENTRY(___longjmp) + movq %rdi,%rdx + /* Restore the mxcsr, but leave exception flags intact. */ + stmxcsr -4(%rsp) + movl 68(%rdx),%eax + andl $0xffffffc0,%eax + movl -4(%rsp),%edi + andl $0x3f,%edi + xorl %eax,%edi + movl %edi,-4(%rsp) + ldmxcsr -4(%rsp) + movq %rsi,%rax /* retval */ + movq 0(%rdx),%rcx + movq 8(%rdx),%rbx + movq 16(%rdx),%rsp + movq 24(%rdx),%rbp + movq 32(%rdx),%r12 + movq 40(%rdx),%r13 + movq 48(%rdx),%r14 + movq 56(%rdx),%r15 + fldcw 64(%rdx) + testq %rax,%rax + jnz 1f + incq %rax +1: movq %rcx,0(%rsp) + ret +END(___longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/gen/fabs.S b/lib/libc/amd64/gen/fabs.S new file mode 100644 index 0000000..b854525 --- /dev/null +++ b/lib/libc/amd64/gen/fabs.S @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2004 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/gen/fabs.S 217106 2011-01-07 16:08:40Z kib $"); + +/* + * Return floating point absolute value of a double. + */ + + .text +ENTRY(fabs) + movsd %xmm0, %xmm1 + movsd signbit(%rip), %xmm0 + andnpd %xmm1, %xmm0 + ret +END(fabs) + + .data +signbit: + .quad 0x8000000000000000 + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/gen/flt_rounds.c b/lib/libc/amd64/gen/flt_rounds.c new file mode 100644 index 0000000..b41abab --- /dev/null +++ b/lib/libc/amd64/gen/flt_rounds.c @@ -0,0 +1,26 @@ +/* + * Written by J.T. Conklin, Apr 10, 1995 + * Public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/gen/flt_rounds.c 132383 2004-07-19 08:17:25Z das $"); + +#include + +static const int map[] = { + 1, /* round to nearest */ + 3, /* round to zero */ + 2, /* round to negative infinity */ + 0 /* round to positive infinity */ +}; + +int +__flt_rounds(void) +{ + int x; + + /* Assume that the x87 and the SSE unit agree on the rounding mode. */ + __asm("fnstcw %0" : "=m" (x)); + return (map[(x >> 10) & 0x03]); +} diff --git a/lib/libc/amd64/gen/fpgetmask.c b/lib/libc/amd64/gen/fpgetmask.c new file mode 100644 index 0000000..9444ec4 --- /dev/null +++ b/lib/libc/amd64/gen/fpgetmask.c @@ -0,0 +1,8 @@ +/* $FreeBSD: releng/11.1/lib/libc/amd64/gen/fpgetmask.c 117864 2003-07-22 06:46:17Z peter $ */ +#define __IEEEFP_NOINLINES__ 1 +#include + +fp_except_t fpgetmask(void) +{ + return __fpgetmask(); +} diff --git a/lib/libc/amd64/gen/fpgetprec.c b/lib/libc/amd64/gen/fpgetprec.c new file mode 100644 index 0000000..a14f5d7 --- /dev/null +++ b/lib/libc/amd64/gen/fpgetprec.c @@ -0,0 +1,8 @@ +/* $FreeBSD: releng/11.1/lib/libc/amd64/gen/fpgetprec.c 117864 2003-07-22 06:46:17Z peter $ */ +#define __IEEEFP_NOINLINES__ 1 +#include + +fp_prec_t fpgetprec(void) +{ + return __fpgetprec(); +} diff --git a/lib/libc/amd64/gen/fpgetround.c b/lib/libc/amd64/gen/fpgetround.c new file mode 100644 index 0000000..7df6896 --- /dev/null +++ b/lib/libc/amd64/gen/fpgetround.c @@ -0,0 +1,8 @@ +/* $FreeBSD: releng/11.1/lib/libc/amd64/gen/fpgetround.c 117864 2003-07-22 06:46:17Z peter $ */ +#define __IEEEFP_NOINLINES__ 1 +#include + +fp_rnd_t fpgetround(void) +{ + return __fpgetround(); +} diff --git a/lib/libc/amd64/gen/fpgetsticky.c b/lib/libc/amd64/gen/fpgetsticky.c new file mode 100644 index 0000000..be11a78 --- /dev/null +++ b/lib/libc/amd64/gen/fpgetsticky.c @@ -0,0 +1,8 @@ +/* $FreeBSD: releng/11.1/lib/libc/amd64/gen/fpgetsticky.c 117864 2003-07-22 06:46:17Z peter $ */ +#define __IEEEFP_NOINLINES__ 1 +#include + +fp_except_t fpgetsticky(void) +{ + return __fpgetsticky(); +} diff --git a/lib/libc/amd64/gen/fpsetmask.c b/lib/libc/amd64/gen/fpsetmask.c new file mode 100644 index 0000000..772d715 --- /dev/null +++ b/lib/libc/amd64/gen/fpsetmask.c @@ -0,0 +1,8 @@ +/* $FreeBSD: releng/11.1/lib/libc/amd64/gen/fpsetmask.c 117864 2003-07-22 06:46:17Z peter $ */ +#define __IEEEFP_NOINLINES__ 1 +#include + +fp_except_t fpsetmask(fp_except_t m) +{ + return (__fpsetmask(m)); +} diff --git a/lib/libc/amd64/gen/fpsetprec.c b/lib/libc/amd64/gen/fpsetprec.c new file mode 100644 index 0000000..fa00fb1 --- /dev/null +++ b/lib/libc/amd64/gen/fpsetprec.c @@ -0,0 +1,8 @@ +/* $FreeBSD: releng/11.1/lib/libc/amd64/gen/fpsetprec.c 117864 2003-07-22 06:46:17Z peter $ */ +#define __IEEEFP_NOINLINES__ 1 +#include + +fp_prec_t fpsetprec(fp_prec_t m) +{ + return (__fpsetprec(m)); +} diff --git a/lib/libc/amd64/gen/fpsetround.c b/lib/libc/amd64/gen/fpsetround.c new file mode 100644 index 0000000..5abd0ec --- /dev/null +++ b/lib/libc/amd64/gen/fpsetround.c @@ -0,0 +1,8 @@ +/* $FreeBSD: releng/11.1/lib/libc/amd64/gen/fpsetround.c 117864 2003-07-22 06:46:17Z peter $ */ +#define __IEEEFP_NOINLINES__ 1 +#include + +fp_rnd_t fpsetround(fp_rnd_t m) +{ + return (__fpsetround(m)); +} diff --git a/lib/libc/amd64/gen/getcontextx.c b/lib/libc/amd64/gen/getcontextx.c new file mode 100644 index 0000000..1d6693c --- /dev/null +++ b/lib/libc/amd64/gen/getcontextx.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Konstantin Belousov + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/gen/getcontextx.c 251047 2013-05-28 04:54:16Z kib $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int xstate_sz = -1; + +int +__getcontextx_size(void) +{ + u_int p[4]; + + if (xstate_sz == -1) { + do_cpuid(1, p); + if ((p[2] & CPUID2_OSXSAVE) != 0) { + cpuid_count(0xd, 0x0, p); + xstate_sz = p[1] - sizeof(struct savefpu); + } else + xstate_sz = 0; + } + + return (sizeof(ucontext_t) + xstate_sz); +} + +int +__fillcontextx2(char *ctx) +{ + struct amd64_get_xfpustate xfpu; + ucontext_t *ucp; + + ucp = (ucontext_t *)ctx; + if (xstate_sz != 0) { + xfpu.addr = (char *)(ucp + 1); + xfpu.len = xstate_sz; + if (sysarch(AMD64_GET_XFPUSTATE, &xfpu) == -1) + return (-1); + ucp->uc_mcontext.mc_xfpustate = (__register_t)xfpu.addr; + ucp->uc_mcontext.mc_xfpustate_len = xstate_sz; + ucp->uc_mcontext.mc_flags |= _MC_HASFPXSTATE; + } else { + ucp->uc_mcontext.mc_xfpustate = 0; + ucp->uc_mcontext.mc_xfpustate_len = 0; + } + return (0); +} + +int +__fillcontextx(char *ctx) +{ + ucontext_t *ucp; + + ucp = (ucontext_t *)ctx; + if (getcontext(ucp) == -1) + return (-1); + __fillcontextx2(ctx); + return (0); +} + +__weak_reference(__getcontextx, getcontextx); + +ucontext_t * +__getcontextx(void) +{ + char *ctx; + int error; + + ctx = malloc(__getcontextx_size()); + if (ctx == NULL) + return (NULL); + if (__fillcontextx(ctx) == -1) { + error = errno; + free(ctx); + errno = error; + return (NULL); + } + return ((ucontext_t *)ctx); +} diff --git a/lib/libc/amd64/gen/infinity.c b/lib/libc/amd64/gen/infinity.c new file mode 100644 index 0000000..a0e4f16 --- /dev/null +++ b/lib/libc/amd64/gen/infinity.c @@ -0,0 +1,14 @@ +/* + * infinity.c + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/gen/infinity.c 110566 2003-02-08 20:37:55Z mike $"); + +#include + +/* bytes for +Infinity on a 387 */ +const union __infinity_un __infinity = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; + +/* bytes for NaN */ +const union __nan_un __nan = { { 0, 0, 0xc0, 0xff } }; diff --git a/lib/libc/amd64/gen/makecontext.c b/lib/libc/amd64/gen/makecontext.c new file mode 100644 index 0000000..c42820b --- /dev/null +++ b/lib/libc/amd64/gen/makecontext.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/gen/makecontext.c 132912 2004-07-31 01:41:41Z davidxu $"); + +#include +#include +#include +#include + +typedef void (*func_t)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t); + +/* Prototypes */ +static void makectx_wrapper(ucontext_t *ucp, func_t func, uint64_t *args); + +__weak_reference(__makecontext, makecontext); + +void +__makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...) +{ + uint64_t *args; + uint64_t *sp; + va_list ap; + int i; + + /* A valid context is required. */ + if ((ucp == NULL) || (ucp->uc_mcontext.mc_len != sizeof(mcontext_t))) + return; + else if ((argc < 0) || (argc > 6) || (ucp->uc_stack.ss_sp == NULL) || + (ucp->uc_stack.ss_size < MINSIGSTKSZ)) { + /* + * This should really return -1 with errno set to ENOMEM + * or something, but the spec says that makecontext is + * a void function. At least make sure that the context + * isn't valid so it can't be used without an error. + */ + ucp->uc_mcontext.mc_len = 0; + return; + } + + /* Align the stack to 16 bytes. */ + sp = (uint64_t *)(ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + sp = (uint64_t *)((uint64_t)sp & ~15UL); + + /* Allocate space for a maximum of 6 arguments on the stack. */ + args = sp - 6; + + /* + * Account for arguments on stack and do the funky C entry alignment. + * This means that we need an 8-byte-odd alignment since the ABI expects + * the return address to be pushed, thus breaking the 16 byte alignment. + */ + sp -= 7; + + /* Add the arguments: */ + va_start(ap, argc); + for (i = 0; i < argc; i++) + args[i] = va_arg(ap, uint64_t); + va_end(ap); + for (i = argc; i < 6; i++) + args[i] = 0; + + ucp->uc_mcontext.mc_rdi = (register_t)ucp; + ucp->uc_mcontext.mc_rsi = (register_t)start; + ucp->uc_mcontext.mc_rdx = (register_t)args; + ucp->uc_mcontext.mc_rbp = 0; + ucp->uc_mcontext.mc_rbx = (register_t)sp; + ucp->uc_mcontext.mc_rsp = (register_t)sp; + ucp->uc_mcontext.mc_rip = (register_t)makectx_wrapper; +} + +static void +makectx_wrapper(ucontext_t *ucp, func_t func, uint64_t *args) +{ + (*func)(args[0], args[1], args[2], args[3], args[4], args[5]); + if (ucp->uc_link == NULL) + exit(0); + setcontext((const ucontext_t *)ucp->uc_link); + /* should never get here */ + abort(); + /* NOTREACHED */ +} diff --git a/lib/libc/amd64/gen/rfork_thread.S b/lib/libc/amd64/gen/rfork_thread.S new file mode 100644 index 0000000..d8b39a4 --- /dev/null +++ b/lib/libc/amd64/gen/rfork_thread.S @@ -0,0 +1,99 @@ +/*- + * Copyright (c) 2000 Peter Wemm + * Copyright (c) 2003 Alan L. Cox + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/gen/rfork_thread.S 240178 2012-09-06 20:59:49Z jilles $"); + +/* + * With thanks to John Dyson for the original version of this. + */ + +#include + +/* + * %edi %rsi %rdx %rcx + * rfork_thread(flags, stack_addr, start_fnc, start_arg); + * + * flags: Flags to rfork system call. See rfork(2). + * stack_addr: Top of stack for thread. + * start_fnc: Address of thread function to call in child. + * start_arg: Argument to pass to the thread function in child. + */ + +ENTRY(rfork_thread) + pushq %rbx + pushq %r12 + movq %rdx, %rbx + movq %rcx, %r12 + + /* + * Prepare and execute the thread creation syscall + */ + movq $SYS_rfork, %rax + KERNCALL + jb 2f + + /* + * Check to see if we are in the parent or child + */ + cmpl $0, %edx + jnz 1f + popq %r12 + popq %rbx + ret + + /* + * If we are in the child (new thread), then + * set-up the call to the internal subroutine. If it + * returns, then call __exit. + */ +1: + movq %rsi, %rsp + movq %r12, %rdi + call *%rbx + movl %eax, %edi + + /* + * Exit system call + */ +#ifdef SYS_exit + movq $SYS_exit, %rax +#else + movq $SYS_sys_exit, %rax +#endif + KERNCALL + + /* + * Branch here if the thread creation fails: + */ +2: + popq %r12 + popq %rbx + jmp HIDENAME(cerror) +END(rfork_thread) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/gen/setjmp.S b/lib/libc/amd64/gen/setjmp.S new file mode 100644 index 0000000..c103f29 --- /dev/null +++ b/lib/libc/amd64/gen/setjmp.S @@ -0,0 +1,116 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) + .asciz "@(#)setjmp.s 5.1 (Berkeley) 4/23/90" +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/gen/setjmp.S 287292 2015-08-29 14:25:01Z kib $"); + +/* + * C library -- _setjmp, _longjmp + * + * longjmp(a,v) + * will generate a "return(v)" from the last call to + * setjmp(a) + * by restoring registers from the environment 'a'. + * The previous signal state is restored. + */ + +#include "SYS.h" + +ENTRY(setjmp) + pushq %rdi + movq %rdi,%rcx + movq $1,%rdi /* SIG_BLOCK */ + movq $0,%rsi /* (sigset_t*)set */ + leaq 72(%rcx),%rdx /* 9,10; (sigset_t*)oset */ + /* stack is 16-byte aligned */ + call __libc_sigprocmask + popq %rdi + movq %rdi,%rcx + movq 0(%rsp),%rdx /* retval */ + movq %rdx, 0(%rcx) /* 0; retval */ + movq %rbx, 8(%rcx) /* 1; rbx */ + movq %rsp,16(%rcx) /* 2; rsp */ + movq %rbp,24(%rcx) /* 3; rbp */ + movq %r12,32(%rcx) /* 4; r12 */ + movq %r13,40(%rcx) /* 5; r13 */ + movq %r14,48(%rcx) /* 6; r14 */ + movq %r15,56(%rcx) /* 7; r15 */ + fnstcw 64(%rcx) /* 8; fpu cw */ + stmxcsr 68(%rcx) /* and mxcsr */ + xorq %rax,%rax + ret +END(setjmp) + + WEAK_REFERENCE(__longjmp, longjmp) +ENTRY(__longjmp) + pushq %rdi + pushq %rsi + movq %rdi,%rdx + movq $3,%rdi /* SIG_SETMASK */ + leaq 72(%rdx),%rsi /* (sigset_t*)set */ + movq $0,%rdx /* (sigset_t*)oset */ + subq $0x8,%rsp /* make the stack 16-byte aligned */ + call __libc_sigprocmask + addq $0x8,%rsp + popq %rsi + popq %rdi /* jmpbuf */ + movq %rdi,%rdx + /* Restore the mxcsr, but leave exception flags intact. */ + stmxcsr -4(%rsp) + movl 68(%rdx),%eax + andl $0xffffffc0,%eax + movl -4(%rsp),%edi + andl $0x3f,%edi + xorl %eax,%edi + movl %edi,-4(%rsp) + ldmxcsr -4(%rsp) + movq %rsi,%rax /* retval */ + movq 0(%rdx),%rcx + movq 8(%rdx),%rbx + movq 16(%rdx),%rsp + movq 24(%rdx),%rbp + movq 32(%rdx),%r12 + movq 40(%rdx),%r13 + movq 48(%rdx),%r14 + movq 56(%rdx),%r15 + fldcw 64(%rdx) + testq %rax,%rax + jnz 1f + incq %rax +1: movq %rcx,0(%rsp) + ret +END(__longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/gen/signalcontext.c b/lib/libc/amd64/gen/signalcontext.c new file mode 100644 index 0000000..5b0c64c --- /dev/null +++ b/lib/libc/amd64/gen/signalcontext.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2003 Marcel Moolenaar + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/gen/signalcontext.c 132795 2004-07-28 13:08:24Z davidxu $"); + +#include +#include +#include +#include +#include + +typedef void (*handler_t)(uint64_t, uint64_t, uint64_t); + +/* Prototypes */ +static void sigctx_wrapper(ucontext_t *ucp, handler_t func, uint64_t *args); + +__weak_reference(__signalcontext, signalcontext); + +int +__signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func) +{ + uint64_t *args; + siginfo_t *sig_si; + ucontext_t *sig_uc; + uint64_t sp; + + /* Bail out if we don't have a valid ucontext pointer. */ + if (ucp == NULL) + abort(); + + /* + * Build a signal frame and copy the arguments of signal handler + * 'func' onto the stack and do the funky stack alignment. + * This means that we need an 8-byte-odd alignment since the ABI expects + * the return address to be pushed, thus breaking the 16 byte alignment. + */ + sp = (ucp->uc_mcontext.mc_rsp - 128 - sizeof(ucontext_t)) & ~15UL; + sig_uc = (ucontext_t *)sp; + bcopy(ucp, sig_uc, sizeof(*sig_uc)); + sp = (sp - sizeof(siginfo_t)) & ~15UL; + sig_si = (siginfo_t *)sp; + bzero(sig_si, sizeof(*sig_si)); + sig_si->si_signo = sig; + sp -= 3 * sizeof(uint64_t); + args = (uint64_t *)sp; + args[0] = sig; + args[1] = (intptr_t)sig_si; + args[2] = (intptr_t)sig_uc; + sp -= 16; + + /* + * Setup the ucontext of the signal handler. + */ + bzero(&ucp->uc_mcontext, sizeof(ucp->uc_mcontext)); + ucp->uc_mcontext.mc_fpformat = _MC_FPFMT_NODEV; + ucp->uc_mcontext.mc_ownedfp = _MC_FPOWNED_NONE; + ucp->uc_link = sig_uc; + sigdelset(&ucp->uc_sigmask, sig); + + ucp->uc_mcontext.mc_len = sizeof(mcontext_t); + ucp->uc_mcontext.mc_rdi = (register_t)ucp; + ucp->uc_mcontext.mc_rsi = (register_t)func; + ucp->uc_mcontext.mc_rdx = (register_t)args; + ucp->uc_mcontext.mc_rbp = (register_t)sp; + ucp->uc_mcontext.mc_rbx = (register_t)sp; + ucp->uc_mcontext.mc_rsp = (register_t)sp; + ucp->uc_mcontext.mc_rip = (register_t)sigctx_wrapper; + return (0); +} + +static void +sigctx_wrapper(ucontext_t *ucp, handler_t func, uint64_t *args) +{ + + (*func)(args[0], args[1], args[2]); + if (ucp->uc_link == NULL) + exit(0); + setcontext((const ucontext_t *)ucp->uc_link); + /* should never get here */ + abort(); + /* NOTREACHED */ +} diff --git a/lib/libc/amd64/gen/sigsetjmp.S b/lib/libc/amd64/gen/sigsetjmp.S new file mode 100644 index 0000000..d4053a7 --- /dev/null +++ b/lib/libc/amd64/gen/sigsetjmp.S @@ -0,0 +1,116 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 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. + * + * @(#)setjmp.s 5.1 (Berkeley) 4/23/90" + */ + +#if defined(LIBC_SCCS) && !defined(lint) + .text + .asciz "$Id: sigsetjmp.S,v 1.1 1993/12/05 13:01:05 ats Exp $" +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/gen/sigsetjmp.S 287292 2015-08-29 14:25:01Z kib $"); + +#include "SYS.h" + +/*- + * TODO: + * Rename sigsetjmp to __sigsetjmp and siglongjmp to __siglongjmp, + * remove the other *jmp functions and define everything in terms + * of the renamed functions. This requires compiler support for + * the renamed functions (introduced in gcc-2.5.3; previous versions + * only supported *jmp with 0 or 1 leading underscores). + * + * Restore _all_ the registers and the signal mask atomically. Can + * use sigreturn() if sigreturn() works. + */ + +ENTRY(sigsetjmp) + movl %esi,88(%rdi) /* 11; savemask */ + testl %esi,%esi + jz 2f + pushq %rdi + movq %rdi,%rcx + movq $1,%rdi /* SIG_BLOCK */ + movq $0,%rsi /* (sigset_t*)set */ + leaq 72(%rcx),%rdx /* 9,10 (sigset_t*)oset */ + /* stack is 16-byte aligned */ + call __libc_sigprocmask + popq %rdi +2: movq %rdi,%rcx + movq 0(%rsp),%rdx /* retval */ + movq %rdx, 0(%rcx) /* 0; retval */ + movq %rbx, 8(%rcx) /* 1; rbx */ + movq %rsp,16(%rcx) /* 2; rsp */ + movq %rbp,24(%rcx) /* 3; rbp */ + movq %r12,32(%rcx) /* 4; r12 */ + movq %r13,40(%rcx) /* 5; r13 */ + movq %r14,48(%rcx) /* 6; r14 */ + movq %r15,56(%rcx) /* 7; r15 */ + fnstcw 64(%rcx) /* 8; fpu cw */ + xorq %rax,%rax + ret +END(sigsetjmp) + + WEAK_REFERENCE(__siglongjmp, siglongjmp) +ENTRY(__siglongjmp) + cmpl $0,88(%rdi) + jz 2f + movq %rdi,%rdx + pushq %rdi + pushq %rsi + movq $3,%rdi /* SIG_SETMASK */ + leaq 72(%rdx),%rsi /* (sigset_t*)set */ + movq $0,%rdx /* (sigset_t*)oset */ + subq $0x8,%rsp /* make the stack 16-byte aligned */ + call __libc_sigprocmask + addq $0x8,%rsp + popq %rsi + popq %rdi /* jmpbuf */ +2: movq %rdi,%rdx + movq %rsi,%rax /* retval */ + movq 0(%rdx),%rcx + movq 8(%rdx),%rbx + movq 16(%rdx),%rsp + movq 24(%rdx),%rbp + movq 32(%rdx),%r12 + movq 40(%rdx),%r13 + movq 48(%rdx),%r14 + movq 56(%rdx),%r15 + fldcw 64(%rdx) + testq %rax,%rax + jnz 1f + incq %rax +1: movq %rcx,0(%rsp) + ret +END(__siglongjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/stdlib/Makefile.inc b/lib/libc/amd64/stdlib/Makefile.inc new file mode 100644 index 0000000..fcf9e0a --- /dev/null +++ b/lib/libc/amd64/stdlib/Makefile.inc @@ -0,0 +1,4 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/amd64/stdlib/Makefile.inc 168336 2007-04-04 01:19:54Z jkim $ + +MDSRCS+=div.S ldiv.S lldiv.S diff --git a/lib/libc/amd64/stdlib/div.S b/lib/libc/amd64/stdlib/div.S new file mode 100644 index 0000000..b17403c --- /dev/null +++ b/lib/libc/amd64/stdlib/div.S @@ -0,0 +1,20 @@ +/* $NetBSD: div.S,v 1.1 2001/06/19 00:25:04 fvdl Exp $ */ + +/*- + * Written by Frank van der Linden (fvdl@wasabisystems.com) + * Public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/stdlib/div.S 217106 2011-01-07 16:08:40Z kib $"); + +ENTRY(div) + movl %edi,%eax + cltd + idivl %esi + salq $32,%rdx + orq %rdx,%rax + ret +END(div) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/stdlib/ldiv.S b/lib/libc/amd64/stdlib/ldiv.S new file mode 100644 index 0000000..01b7c6c --- /dev/null +++ b/lib/libc/amd64/stdlib/ldiv.S @@ -0,0 +1,18 @@ +/* $NetBSD: ldiv.S,v 1.1 2001/06/19 00:25:04 fvdl Exp $ */ + +/*- + * Written by gcc 3.0. + * Copy/pasted by Frank van der Linden (fvdl@wasabisystems.com) + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/stdlib/ldiv.S 217106 2011-01-07 16:08:40Z kib $"); + +ENTRY(ldiv) + movq %rdi,%rax + cqto + idivq %rsi + ret +END(ldiv) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/stdlib/lldiv.S b/lib/libc/amd64/stdlib/lldiv.S new file mode 100644 index 0000000..feb6312 --- /dev/null +++ b/lib/libc/amd64/stdlib/lldiv.S @@ -0,0 +1,18 @@ +/* $NetBSD: ldiv.S,v 1.1 2001/06/19 00:25:04 fvdl Exp $ */ + +/*- + * Written by gcc 3.0. + * Copy/pasted by Frank van der Linden (fvdl@wasabisystems.com) + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/stdlib/lldiv.S 217106 2011-01-07 16:08:40Z kib $"); + +ENTRY(lldiv) + movq %rdi,%rax + cqto + idivq %rsi + ret +END(lldiv) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/Makefile.inc b/lib/libc/amd64/string/Makefile.inc new file mode 100644 index 0000000..03c81a2 --- /dev/null +++ b/lib/libc/amd64/string/Makefile.inc @@ -0,0 +1,13 @@ +# $FreeBSD: releng/11.1/lib/libc/amd64/string/Makefile.inc 315044 2017-03-11 02:51:29Z brooks $ + +MDSRCS+= \ + bcmp.S \ + bcopy.S \ + bzero.S \ + memcmp.S \ + memcpy.S \ + memmove.S \ + memset.S \ + strcat.S \ + strcmp.S \ + stpcpy.S diff --git a/lib/libc/amd64/string/bcmp.S b/lib/libc/amd64/string/bcmp.S new file mode 100644 index 0000000..fff65ad --- /dev/null +++ b/lib/libc/amd64/string/bcmp.S @@ -0,0 +1,27 @@ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/string/bcmp.S 217106 2011-01-07 16:08:40Z kib $"); + +#if 0 + RCSID("$NetBSD: bcmp.S,v 1.1 2001/06/19 00:25:04 fvdl Exp $") +#endif + +ENTRY(bcmp) + cld /* set compare direction forward */ + + movq %rdx,%rcx /* compare by words */ + shrq $3,%rcx + repe + cmpsq + jne L1 + + movq %rdx,%rcx /* compare remainder by bytes */ + andq $7,%rcx + repe + cmpsb +L1: + setne %al + movsbl %al,%eax + ret +END(bcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/bcopy.S b/lib/libc/amd64/string/bcopy.S new file mode 100644 index 0000000..eef1a0c --- /dev/null +++ b/lib/libc/amd64/string/bcopy.S @@ -0,0 +1,99 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from locore.s. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/string/bcopy.S 217106 2011-01-07 16:08:40Z kib $"); + +#if 0 + RCSID("$NetBSD: bcopy.S,v 1.2 2003/08/07 16:42:36 agc Exp $") +#endif + + /* + * (ov)bcopy (src,dst,cnt) + * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800 + */ + +#ifdef MEMCOPY +ENTRY(memcpy) +#else +#ifdef MEMMOVE +ENTRY(memmove) +#else +ENTRY(bcopy) +#endif +#endif +#if defined(MEMCOPY) || defined(MEMMOVE) + movq %rdi,%rax /* return dst */ +#else + xchgq %rdi,%rsi +#endif + movq %rdx,%rcx + movq %rdi,%r8 + subq %rsi,%r8 + cmpq %rcx,%r8 /* overlapping? */ + jb 1f + cld /* nope, copy forwards. */ + shrq $3,%rcx /* copy by words */ + rep + movsq + movq %rdx,%rcx + andq $7,%rcx /* any bytes left? */ + rep + movsb + ret +1: + addq %rcx,%rdi /* copy backwards. */ + addq %rcx,%rsi + std + andq $7,%rcx /* any fractional bytes? */ + decq %rdi + decq %rsi + rep + movsb + movq %rdx,%rcx /* copy remainder by words */ + shrq $3,%rcx + subq $7,%rsi + subq $7,%rdi + rep + movsq + cld + ret +#ifdef MEMCOPY +END(memcpy) +#else +#ifdef MEMMOVE +END(memmove) +#else +END(bcopy) +#endif +#endif + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/bzero.S b/lib/libc/amd64/string/bzero.S new file mode 100644 index 0000000..2eab181 --- /dev/null +++ b/lib/libc/amd64/string/bzero.S @@ -0,0 +1,46 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * Adapted for NetBSD/x86_64 by Frank van der Linden + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/string/bzero.S 217106 2011-01-07 16:08:40Z kib $"); + +#if 0 + RCSID("$NetBSD: bzero.S,v 1.2 2003/07/26 19:24:38 salo Exp $") +#endif + +ENTRY(bzero) + cld /* set fill direction forward */ + xorq %rax,%rax /* set fill data to 0 */ + + /* + * if the string is too short, it's really not worth the overhead + * of aligning to word boundries, etc. So we jump to a plain + * unaligned set. + */ + cmpq $16,%rsi + jb L1 + + movq %rdi,%rcx /* compute misalignment */ + negq %rcx + andq $7,%rcx + subq %rcx,%rsi + rep /* zero until word aligned */ + stosb + + movq %rsi,%rcx /* zero by words */ + shrq $3,%rcx + andq $7,%rsi + rep + stosq + +L1: movq %rsi,%rcx /* zero remainder by bytes */ + rep + stosb + + ret +END(bzero) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/memcmp.S b/lib/libc/amd64/string/memcmp.S new file mode 100644 index 0000000..51725a8 --- /dev/null +++ b/lib/libc/amd64/string/memcmp.S @@ -0,0 +1,44 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * Adapted for NetBSD/x86_64 by Frank van der Linden + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/string/memcmp.S 217106 2011-01-07 16:08:40Z kib $"); + +#if 0 + RCSID("$NetBSD: memcmp.S,v 1.2 2003/07/26 19:24:39 salo Exp $") +#endif + +ENTRY(memcmp) + cld /* set compare direction forward */ + movq %rdx,%rcx /* compare by longs */ + shrq $3,%rcx + repe + cmpsq + jne L5 /* do we match so far? */ + + movq %rdx,%rcx /* compare remainder by bytes */ + andq $7,%rcx + repe + cmpsb + jne L6 /* do we match? */ + + xorl %eax,%eax /* we match, return zero */ + ret + +L5: movl $8,%ecx /* We know that one of the next */ + subq %rcx,%rdi /* eight pairs of bytes do not */ + subq %rcx,%rsi /* match. */ + repe + cmpsb +L6: xorl %eax,%eax /* Perform unsigned comparison */ + movb -1(%rdi),%al + xorl %edx,%edx + movb -1(%rsi),%dl + subl %edx,%eax + ret +END(memcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/memcpy.S b/lib/libc/amd64/string/memcpy.S new file mode 100644 index 0000000..c86133f --- /dev/null +++ b/lib/libc/amd64/string/memcpy.S @@ -0,0 +1,5 @@ +/* $NetBSD: memcpy.S,v 1.1 2001/06/19 00:25:05 fvdl Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/amd64/string/memcpy.S 144730 2005-04-07 03:56:03Z alc $ */ + +#define MEMCOPY +#include "bcopy.S" diff --git a/lib/libc/amd64/string/memmove.S b/lib/libc/amd64/string/memmove.S new file mode 100644 index 0000000..0c0d92c --- /dev/null +++ b/lib/libc/amd64/string/memmove.S @@ -0,0 +1,5 @@ +/* $NetBSD: memmove.S,v 1.1 2001/06/19 00:25:05 fvdl Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/amd64/string/memmove.S 218303 2011-02-04 21:04:00Z kib $ */ + +#define MEMMOVE +#include "bcopy.S" diff --git a/lib/libc/amd64/string/memset.S b/lib/libc/amd64/string/memset.S new file mode 100644 index 0000000..46f2c88 --- /dev/null +++ b/lib/libc/amd64/string/memset.S @@ -0,0 +1,63 @@ +/* + * Written by J.T. Conklin . + * Public domain. + * Adapted for NetBSD/x86_64 by Frank van der Linden + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/string/memset.S 217106 2011-01-07 16:08:40Z kib $"); + +#if 0 + RCSID("$NetBSD: memset.S,v 1.3 2004/02/26 20:50:06 drochner Exp $") +#endif + +ENTRY(memset) + movq %rsi,%rax + andq $0xff,%rax + movq %rdx,%rcx + movq %rdi,%r11 + + cld /* set fill direction forward */ + + /* + * if the string is too short, it's really not worth the overhead + * of aligning to word boundries, etc. So we jump to a plain + * unaligned set. + */ + cmpq $0x0f,%rcx + jle L1 + + movb %al,%ah /* copy char to all bytes in word */ + movl %eax,%edx + sall $16,%eax + orl %edx,%eax + + movl %eax,%edx + salq $32,%rax + orq %rdx,%rax + + movq %rdi,%rdx /* compute misalignment */ + negq %rdx + andq $7,%rdx + movq %rcx,%r8 + subq %rdx,%r8 + + movq %rdx,%rcx /* set until word aligned */ + rep + stosb + + movq %r8,%rcx + shrq $3,%rcx /* set by words */ + rep + stosq + + movq %r8,%rcx /* set remainder by bytes */ + andq $7,%rcx +L1: rep + stosb + movq %r11,%rax + + ret +END(memset) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/stpcpy.S b/lib/libc/amd64/string/stpcpy.S new file mode 100644 index 0000000..248ebca --- /dev/null +++ b/lib/libc/amd64/string/stpcpy.S @@ -0,0 +1,116 @@ +/* + * Adapted by Guillaume Morin from strcpy.S + * written by J.T. Conklin + * Public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/string/stpcpy.S 224253 2011-07-21 20:06:14Z gnn $"); + +/* + * This stpcpy implementation copies a byte at a time until the + * source pointer is aligned to a word boundary, it then copies by + * words until it finds a word containing a zero byte, and finally + * copies by bytes until the end of the string is reached. + * + * While this may result in unaligned stores if the source and + * destination pointers are unaligned with respect to each other, + * it is still faster than either byte copies or the overhead of + * an implementation suitable for machines with strict alignment + * requirements. + */ + + .globl stpcpy,__stpcpy +ENTRY(stpcpy) +__stpcpy: + movabsq $0x0101010101010101,%r8 + movabsq $0x8080808080808080,%r9 + + /* + * Align source to a word boundary. + * Consider unrolling loop? + */ +.Lalign: + testb $7,%sil + je .Lword_aligned + movb (%rsi),%dl + incq %rsi + movb %dl,(%rdi) + incq %rdi + testb %dl,%dl + jne .Lalign + movq %rdi,%rax + dec %rax + ret + + .p2align 4 +.Lloop: + movq %rdx,(%rdi) + addq $8,%rdi +.Lword_aligned: + movq (%rsi),%rdx + movq %rdx,%rcx + addq $8,%rsi + subq %r8,%rcx + testq %r9,%rcx + je .Lloop + + /* + * In rare cases, the above loop may exit prematurely. We must + * return to the loop if none of the bytes in the word equal 0. + */ + + movb %dl,(%rdi) + testb %dl,%dl /* 1st byte == 0? */ + je .Ldone + incq %rdi + + shrq $8,%rdx + movb %dl,(%rdi) + testb %dl,%dl /* 2nd byte == 0? */ + je .Ldone + incq %rdi + + shrq $8,%rdx + movb %dl,(%rdi) + testb %dl,%dl /* 3rd byte == 0? */ + je .Ldone + incq %rdi + + shrq $8,%rdx + movb %dl,(%rdi) + testb %dl,%dl /* 4th byte == 0? */ + je .Ldone + incq %rdi + + shrq $8,%rdx + movb %dl,(%rdi) + testb %dl,%dl /* 5th byte == 0? */ + je .Ldone + incq %rdi + + shrq $8,%rdx + movb %dl,(%rdi) + testb %dl,%dl /* 6th byte == 0? */ + je .Ldone + incq %rdi + + shrq $8,%rdx + movb %dl,(%rdi) + testb %dl,%dl /* 7th byte == 0? */ + je .Ldone + incq %rdi + + shrq $8,%rdx + movb %dl,(%rdi) + incq %rdi + testb %dl,%dl /* 8th byte == 0? */ + jne .Lword_aligned + decq %rdi + +.Ldone: + movq %rdi,%rax + ret +END(stpcpy) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/strcat.S b/lib/libc/amd64/string/strcat.S new file mode 100644 index 0000000..b6f5e16 --- /dev/null +++ b/lib/libc/amd64/string/strcat.S @@ -0,0 +1,168 @@ +/* + * Written by J.T. Conklin + * Public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/string/strcat.S 217106 2011-01-07 16:08:40Z kib $"); + +#if 0 + RCSID("$NetBSD: strcat.S,v 1.4 2004/07/26 18:51:21 drochner Exp $") +#endif + +ENTRY(strcat) + movq %rdi,%rax + movabsq $0x0101010101010101,%r8 + movabsq $0x8080808080808080,%r9 + + /* + * Align destination to word boundary. + * Consider unrolling loop? + */ +.Lscan: +.Lscan_align: + testb $7,%dil + je .Lscan_aligned + cmpb $0,(%rdi) + je .Lcopy + incq %rdi + jmp .Lscan_align + + .align 4 +.Lscan_aligned: +.Lscan_loop: + movq (%rdi),%rdx + addq $8,%rdi + subq %r8,%rdx + testq %r9,%rdx + je .Lscan_loop + + /* + * In rare cases, the above loop may exit prematurely. We must + * return to the loop if none of the bytes in the word equal 0. + */ + + cmpb $0,-8(%rdi) /* 1st byte == 0? */ + jne 1f + subq $8,%rdi + jmp .Lcopy + +1: cmpb $0,-7(%rdi) /* 2nd byte == 0? */ + jne 1f + subq $7,%rdi + jmp .Lcopy + +1: cmpb $0,-6(%rdi) /* 3rd byte == 0? */ + jne 1f + subq $6,%rdi + jmp .Lcopy + +1: cmpb $0,-5(%rdi) /* 4th byte == 0? */ + jne 1f + subq $5,%rdi + jmp .Lcopy + +1: cmpb $0,-4(%rdi) /* 5th byte == 0? */ + jne 1f + subq $4,%rdi + jmp .Lcopy + +1: cmpb $0,-3(%rdi) /* 6th byte == 0? */ + jne 1f + subq $3,%rdi + jmp .Lcopy + +1: cmpb $0,-2(%rdi) /* 7th byte == 0? */ + jne 1f + subq $2,%rdi + jmp .Lcopy + +1: cmpb $0,-1(%rdi) /* 8th byte == 0? */ + jne .Lscan_loop + subq $1,%rdi + + /* + * Align source to a word boundary. + * Consider unrolling loop? + */ +.Lcopy: +.Lcopy_align: + testb $7,%sil + je .Lcopy_aligned + movb (%rsi),%dl + incq %rsi + movb %dl,(%rdi) + incq %rdi + testb %dl,%dl + jne .Lcopy_align + ret + + .align 4 +.Lcopy_loop: + movq %rdx,(%rdi) + addq $8,%rdi +.Lcopy_aligned: + movq (%rsi),%rdx + movq %rdx,%rcx + addq $8,%rsi + subq %r8,%rcx + testq %r9,%rcx + je .Lcopy_loop + + /* + * In rare cases, the above loop may exit prematurely. We must + * return to the loop if none of the bytes in the word equal 0. + */ + + movb %dl,(%rdi) + incq %rdi + testb %dl,%dl /* 1st byte == 0? */ + je .Ldone + + shrq $8,%rdx + movb %dl,(%rdi) + incq %rdi + testb %dl,%dl /* 2nd byte == 0? */ + je .Ldone + + shrq $8,%rdx + movb %dl,(%rdi) + incq %rdi + testb %dl,%dl /* 3rd byte == 0? */ + je .Ldone + + shrq $8,%rdx + movb %dl,(%rdi) + incq %rdi + testb %dl,%dl /* 4th byte == 0? */ + je .Ldone + + shrq $8,%rdx + movb %dl,(%rdi) + incq %rdi + testb %dl,%dl /* 5th byte == 0? */ + je .Ldone + + shrq $8,%rdx + movb %dl,(%rdi) + incq %rdi + testb %dl,%dl /* 6th byte == 0? */ + je .Ldone + + shrq $8,%rdx + movb %dl,(%rdi) + incq %rdi + testb %dl,%dl /* 7th byte == 0? */ + je .Ldone + + shrq $8,%rdx + movb %dl,(%rdi) + incq %rdi + testb %dl,%dl /* 8th byte == 0? */ + jne .Lcopy_aligned + +.Ldone: + ret +END(strcat) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/strcmp.S b/lib/libc/amd64/string/strcmp.S new file mode 100644 index 0000000..020727b --- /dev/null +++ b/lib/libc/amd64/string/strcmp.S @@ -0,0 +1,76 @@ +/* + * Written by J.T. Conklin + * Public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/string/strcmp.S 298830 2016-04-30 01:24:24Z pfg $"); + +#if 0 + RCSID("$NetBSD: strcmp.S,v 1.3 2004/07/19 20:04:41 drochner Exp $") +#endif + +ENTRY(strcmp) + /* + * Align s1 to word boundary. + * Consider unrolling loop? + */ +.Ls1align: + testb $7,%dil + je .Ls1aligned + movb (%rdi),%al + incq %rdi + movb (%rsi),%dl + incq %rsi + testb %al,%al + je .Ldone + cmpb %al,%dl + je .Ls1align + jmp .Ldone + + /* + * Check whether s2 is aligned to a word boundary. If it is, we + * can compare by words. Otherwise we have to compare by bytes. + */ +.Ls1aligned: + testb $7,%sil + jne .Lbyte_loop + + movabsq $0x0101010101010101,%r8 + subq $8,%rdi + movabsq $0x8080808080808080,%r9 + subq $8,%rsi + + .align 4 +.Lword_loop: + movq 8(%rdi),%rax + addq $8,%rdi + movq 8(%rsi),%rdx + addq $8,%rsi + cmpq %rax,%rdx + jne .Lbyte_loop + subq %r8,%rdx + notq %rax + andq %rax,%rdx + testq %r9,%rdx + je .Lword_loop + + .align 4 +.Lbyte_loop: + movb (%rdi),%al + incq %rdi + movb (%rsi),%dl + incq %rsi + testb %al,%al + je .Ldone + cmpb %al,%dl + je .Lbyte_loop + +.Ldone: + movzbq %al,%rax + movzbq %dl,%rdx + subq %rdx,%rax + ret +END(strcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/strcpy.c b/lib/libc/amd64/string/strcpy.c new file mode 100644 index 0000000..d72af35 --- /dev/null +++ b/lib/libc/amd64/string/strcpy.c @@ -0,0 +1,38 @@ +/* + * Copyright 2011 George V. Neville-Neil. All rights reserved. + * + * The compilation of software known as FreeBSD is distributed under the + * following terms: + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/string/strcpy.c 224246 2011-07-21 16:32:13Z gnn $"); + +char *__stpcpy(char * __restrict, const char * __restrict); + +char * +strcpy(char * __restrict to, const char * __restrict from) +{ + __stpcpy(to, from); + return(to); +} diff --git a/lib/libc/amd64/sys/Makefile.inc b/lib/libc/amd64/sys/Makefile.inc new file mode 100644 index 0000000..fae3ebe --- /dev/null +++ b/lib/libc/amd64/sys/Makefile.inc @@ -0,0 +1,13 @@ +# from: Makefile.inc,v 1.1 1993/09/03 19:04:23 jtc Exp +# $FreeBSD: releng/11.1/lib/libc/amd64/sys/Makefile.inc 305866 2016-09-16 10:04:28Z kib $ + +SRCS+= amd64_get_fsbase.c amd64_get_gsbase.c amd64_set_fsbase.c \ + amd64_set_gsbase.c + +MDASM= vfork.S brk.S cerror.S exect.S getcontext.S \ + sbrk.S setlogin.S sigreturn.S + +# Don't generate default code for these syscalls: +NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o vfork.o yield.o + +PSEUDO= _getlogin.o _exit.o diff --git a/lib/libc/amd64/sys/amd64_get_fsbase.c b/lib/libc/amd64/sys/amd64_get_fsbase.c new file mode 100644 index 0000000..aa87b8d --- /dev/null +++ b/lib/libc/amd64/sys/amd64_get_fsbase.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2003 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/sys/amd64_get_fsbase.c 124296 2004-01-09 16:52:09Z nectar $"); + +#include + +int +amd64_get_fsbase(void **addr) +{ + + return (sysarch(AMD64_GET_FSBASE, addr)); +} diff --git a/lib/libc/amd64/sys/amd64_get_gsbase.c b/lib/libc/amd64/sys/amd64_get_gsbase.c new file mode 100644 index 0000000..c23c30b --- /dev/null +++ b/lib/libc/amd64/sys/amd64_get_gsbase.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2003 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/sys/amd64_get_gsbase.c 124296 2004-01-09 16:52:09Z nectar $"); + +#include + +int +amd64_get_gsbase(void **addr) +{ + + return (sysarch(AMD64_GET_GSBASE, addr)); +} diff --git a/lib/libc/amd64/sys/amd64_set_fsbase.c b/lib/libc/amd64/sys/amd64_set_fsbase.c new file mode 100644 index 0000000..b7f554a --- /dev/null +++ b/lib/libc/amd64/sys/amd64_set_fsbase.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2003 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/sys/amd64_set_fsbase.c 124296 2004-01-09 16:52:09Z nectar $"); + +#include + +int +amd64_set_fsbase(void *addr) +{ + + return (sysarch(AMD64_SET_FSBASE, &addr)); +} diff --git a/lib/libc/amd64/sys/amd64_set_gsbase.c b/lib/libc/amd64/sys/amd64_set_gsbase.c new file mode 100644 index 0000000..92452cf --- /dev/null +++ b/lib/libc/amd64/sys/amd64_set_gsbase.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2003 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/sys/amd64_set_gsbase.c 124296 2004-01-09 16:52:09Z nectar $"); + +#include + +int +amd64_set_gsbase(void *addr) +{ + + return (sysarch(AMD64_SET_GSBASE, &addr)); +} diff --git a/lib/libc/amd64/sys/brk.S b/lib/libc/amd64/sys/brk.S new file mode 100644 index 0000000..1e43b5c --- /dev/null +++ b/lib/libc/amd64/sys/brk.S @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 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. + */ + +#if defined(SYSLIBC_SCCS) && !defined(lint) + .asciz "@(#)brk.s 5.2 (Berkeley) 12/17/90" +#endif /* SYSLIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/sys/brk.S 240178 2012-09-06 20:59:49Z jilles $"); + +#include "SYS.h" + + .globl HIDENAME(curbrk) + .globl HIDENAME(minbrk) +ENTRY(_brk) + pushq %rdi + jmp ok +END(_brk) + +ENTRY(brk) + pushq %rdi + movq %rdi,%rax +#ifdef PIC + movq PIC_GOT(HIDENAME(minbrk)),%rdx + cmpq %rax,(%rdx) +#else + cmpq %rax,HIDENAME(minbrk)(%rip) +#endif + jbe ok +#ifdef PIC + movq (%rdx),%rdi +#else + movq HIDENAME(minbrk)(%rip),%rdi +#endif +ok: + movq $SYS_break,%rax + KERNCALL + jb err + movq 0(%rsp),%rax +#ifdef PIC + movq PIC_GOT(HIDENAME(curbrk)),%rdx + movq %rax,(%rdx) +#else + movq %rax,HIDENAME(curbrk)(%rip) +#endif + movq $0,%rax + popq %rdi + ret +err: + addq $8, %rsp + jmp HIDENAME(cerror) +END(brk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/cerror.S b/lib/libc/amd64/sys/cerror.S new file mode 100644 index 0000000..ef36d7c --- /dev/null +++ b/lib/libc/amd64/sys/cerror.S @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 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. + */ + +#if defined(SYSLIBC_SCCS) && !defined(lint) + .asciz "@(#)cerror.s 5.1 (Berkeley) 4/23/90" +#endif /* SYSLIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/sys/cerror.S 296474 2016-03-08 00:09:34Z emaste $"); + +#include "SYS.h" + + .globl HIDENAME(cerror) + .hidden HIDENAME(cerror) + + /* + * The __error() function is thread aware. For non-threaded + * programs and the initial threaded in threaded programs, + * it returns a pointer to the global errno variable. + */ + .globl CNAME(__error) + .type CNAME(__error),@function +HIDENAME(cerror): + pushq %rax + call PIC_PLT(CNAME(__error)) + popq %rcx + movl %ecx,(%rax) + movq $-1,%rax + movq $-1,%rdx + ret + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/exect.S b/lib/libc/amd64/sys/exect.S new file mode 100644 index 0000000..b6863f6 --- /dev/null +++ b/lib/libc/amd64/sys/exect.S @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 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. + */ + +#if defined(SYSLIBC_SCCS) && !defined(lint) + .asciz "@(#)exect.s 5.1 (Berkeley) 4/23/90" +#endif /* SYSLIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/sys/exect.S 240178 2012-09-06 20:59:49Z jilles $"); + +#include "SYS.h" +#include + +ENTRY(exect) + movq $SYS_execve,%rax + pushfq + popq %r8 + orq $PSL_T,%r8 + pushq %r8 + popfq + KERNCALL + jmp HIDENAME(cerror) +END(exect) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/getcontext.S b/lib/libc/amd64/sys/getcontext.S new file mode 100644 index 0000000..ac50b88 --- /dev/null +++ b/lib/libc/amd64/sys/getcontext.S @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2003 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/sys/getcontext.S 258447 2013-11-21 21:25:58Z andreast $"); + +#include + +/* + * This has to be magic to handle the multiple returns. + * Otherwise, the setcontext() syscall will return here and we'll + * pop off the return address and go to the *setcontext* call. + */ + WEAK_REFERENCE(__sys_getcontext, _getcontext) + WEAK_REFERENCE(__sys_getcontext, getcontext) +ENTRY(__sys_getcontext) + movq (%rsp),%rsi /* save getcontext return address */ + mov $SYS_getcontext,%rax + KERNCALL + jb HIDENAME(cerror) + addq $8,%rsp /* remove stale (setcontext) return address */ + jmp *%rsi /* restore return address */ +END(__sys_getcontext) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/sbrk.S b/lib/libc/amd64/sys/sbrk.S new file mode 100644 index 0000000..0fce9bb --- /dev/null +++ b/lib/libc/amd64/sys/sbrk.S @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 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. + */ + +#if defined(SYSLIBC_SCCS) && !defined(lint) + .asciz "@(#)sbrk.s 5.1 (Berkeley) 4/23/90" +#endif /* SYSLIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/sys/sbrk.S 240178 2012-09-06 20:59:49Z jilles $"); + +#include "SYS.h" + + .globl CNAME(_end) + .globl HIDENAME(minbrk) + .globl HIDENAME(curbrk) + + .data +HIDENAME(minbrk): .quad CNAME(_end) +HIDENAME(curbrk): .quad CNAME(_end) + .text + +ENTRY(sbrk) + pushq %rdi + movq %rdi,%rcx +#ifdef PIC + movq PIC_GOT(HIDENAME(curbrk)),%rdx + movq (%rdx),%rax +#else + movq HIDENAME(curbrk)(%rip),%rax +#endif + testq %rcx,%rcx + jz back + addq %rax,%rdi + mov $SYS_break,%eax + KERNCALL + jb err +#ifdef PIC + movq PIC_GOT(HIDENAME(curbrk)),%rdx + movq (%rdx),%rax +#else + movq HIDENAME(curbrk)(%rip),%rax +#endif + movq 0(%rsp), %rcx +#ifdef PIC + addq %rcx,(%rdx) +#else + addq %rcx,HIDENAME(curbrk)(%rip) +#endif +back: + addq $8, %rsp + ret +err: + addq $8, %rsp + jmp HIDENAME(cerror) +END(sbrk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/setlogin.S b/lib/libc/amd64/sys/setlogin.S new file mode 100644 index 0000000..d46083e --- /dev/null +++ b/lib/libc/amd64/sys/setlogin.S @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 1991 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) + .asciz "@(#)setlogin.s 5.2 (Berkeley) 4/12/91" +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/sys/setlogin.S 258447 2013-11-21 21:25:58Z andreast $"); + +#include "SYS.h" + +.globl CNAME(_logname_valid) /* in _getlogin() */ + + WEAK_REFERENCE(__sys_setlogin, _setlogin) + WEAK_REFERENCE(__sys_setlogin, setlogin) +ENTRY(__sys_setlogin) + mov $SYS_setlogin,%rax + KERNCALL + jb HIDENAME(cerror) + movl $0,CNAME(_logname_valid)(%rip) + ret /* setlogin(name) */ +END(__sys_setlogin) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/sigreturn.S b/lib/libc/amd64/sys/sigreturn.S new file mode 100644 index 0000000..f8bdada --- /dev/null +++ b/lib/libc/amd64/sys/sigreturn.S @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 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. + */ + +#if defined(SYSLIBC_SCCS) && !defined(lint) + .asciz "@(#)sigreturn.s 5.2 (Berkeley) 12/17/90" +#endif /* SYSLIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/sys/sigreturn.S 217106 2011-01-07 16:08:40Z kib $"); + +#include "SYS.h" + +/* + * NOTE: If the profiling ENTRY() code ever changes any registers, they + * must be saved. On FreeBSD, this is not the case. + */ + +RSYSCALL(sigreturn) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/sys/vfork.S b/lib/libc/amd64/sys/vfork.S new file mode 100644 index 0000000..62b1823 --- /dev/null +++ b/lib/libc/amd64/sys/vfork.S @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * 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. + */ + +#if defined(SYSLIBC_SCCS) && !defined(lint) + .asciz "@(#)Ovfork.s 5.1 (Berkeley) 4/23/90" +#endif /* SYSLIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/amd64/sys/vfork.S 258447 2013-11-21 21:25:58Z andreast $"); + +#include "SYS.h" + + WEAK_REFERENCE(__sys_vfork, _vfork) + WEAK_REFERENCE(__sys_vfork, vfork) +ENTRY(__sys_vfork) + popq %rsi /* fetch return address (%rsi preserved) */ + mov $SYS_vfork,%rax + KERNCALL + jb 1f + jmp *%rsi +1: + pushq %rsi + jmp HIDENAME(cerror) +END(__sys_vfork) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/Makefile.inc b/lib/libc/arm/Makefile.inc new file mode 100644 index 0000000..dee1c4e --- /dev/null +++ b/lib/libc/arm/Makefile.inc @@ -0,0 +1,17 @@ +# $FreeBSD: releng/11.1/lib/libc/arm/Makefile.inc 315044 2017-03-11 02:51:29Z brooks $ +# +# Machine dependent definitions for the arm architecture. +# + +SOFTFLOAT_BITS=32 + +# Long double is just double precision. +SRCS+=machdep_ldisd.c +SYM_MAPS+=${LIBC_SRCTOP}/arm/Symbol.map + +.include "${LIBC_SRCTOP}/arm/aeabi/Makefile.inc" + +.if ${MACHINE_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "") +SYM_MAPS+=${LIBC_SRCTOP}/arm/Symbol_vfp.map +.endif + diff --git a/lib/libc/arm/SYS.h b/lib/libc/arm/SYS.h new file mode 100644 index 0000000..dd901cc --- /dev/null +++ b/lib/libc/arm/SYS.h @@ -0,0 +1,80 @@ +/* $NetBSD: SYS.h,v 1.8 2003/08/07 16:42:02 agc Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. + * + * from: @(#)SYS.h 5.5 (Berkeley) 5/7/91 + * $FreeBSD: releng/11.1/lib/libc/arm/SYS.h 283824 2015-05-31 12:53:10Z andrew $ + */ + +#include +#include +#include + +#define SYSTRAP(x) \ + mov ip, r7; \ + ldr r7, =SYS_ ## x; \ + swi 0; \ + mov r7, ip + +#define CERROR _C_LABEL(cerror) +#define CURBRK _C_LABEL(curbrk) + +#define _SYSCALL_NOERROR(x) \ + ENTRY(__CONCAT(__sys_, x)); \ + .weak _C_LABEL(x); \ + .set _C_LABEL(x), _C_LABEL(__CONCAT(__sys_,x)); \ + .weak _C_LABEL(__CONCAT(_,x)); \ + .set _C_LABEL(__CONCAT(_,x)),_C_LABEL(__CONCAT(__sys_,x)); \ + SYSTRAP(x) + +#define _SYSCALL(x) \ + _SYSCALL_NOERROR(x); \ + it cs; \ + bcs PIC_SYM(CERROR, PLT) + +#define SYSCALL(x) \ + _SYSCALL(x) + +#define PSEUDO(x) \ + ENTRY(__CONCAT(__sys_, x)); \ + .weak _C_LABEL(__CONCAT(_,x)); \ + .set _C_LABEL(__CONCAT(_,x)),_C_LABEL(__CONCAT(__sys_,x)); \ + SYSTRAP(x); \ + it cs; \ + bcs PIC_SYM(CERROR, PLT); \ + RET + +#define RSYSCALL(x) \ + _SYSCALL(x); \ + RET + + .globl CERROR diff --git a/lib/libc/arm/Symbol.map b/lib/libc/arm/Symbol.map new file mode 100644 index 0000000..5a23fe1 --- /dev/null +++ b/lib/libc/arm/Symbol.map @@ -0,0 +1,83 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/arm/Symbol.map 297418 2016-03-30 14:42:09Z emaste $ + */ + +/* + * This only needs to contain symbols that are not listed in + * symbol maps from other parts of libc (i.e., not found in + * stdlib/Symbol.map, string/Symbol.map, sys/Symbol.map, ...). + */ +FBSD_1.0 { + /* PSEUDO syscalls */ + _exit; + + __mcount; + _setjmp; + _longjmp; + alloca; + fabs; + __infinity; + __nan; + makecontext; + setjmp; + longjmp; + sigsetjmp; + siglongjmp; + htonl; + htons; + ntohl; + ntohs; + vfork; + brk; + sbrk; +}; + +FBSD_1.3 { + __flt_rounds; +}; + +FBSD_1.4 { + __gnu_Unwind_Find_exidx; + dl_unwind_find_exidx; +}; + +FBSDprivate_1.0 { + /* PSEUDO syscalls */ + __sys_getlogin; + _getlogin; + __sys_exit; + + _set_tp; + __aeabi_read_tp; + ___longjmp; + __makecontext; + __longjmp; + signalcontext; + _signalcontext; + __siglongjmp; + __sys_vfork; + _vfork; + _brk; + _end; + _sbrk; + + /* softfloat */ + __addsf3; + __adddf3; + __subsf3; + __subdf3; + __mulsf3; + __muldf3; + __divsf3; + __divdf3; + __floatsisf; + __floatsidf; + __fixsfsi; + __fixdfsi; + __fixunssfsi; + __fixunsdfsi; + __extendsfdf2; + __truncdfsf2; + + _libc_arm_fpu_present; +}; diff --git a/lib/libc/arm/Symbol_vfp.map b/lib/libc/arm/Symbol_vfp.map new file mode 100644 index 0000000..e96c330 --- /dev/null +++ b/lib/libc/arm/Symbol_vfp.map @@ -0,0 +1,15 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/arm/Symbol_vfp.map 316999 2017-04-16 05:17:48Z mmel $ + */ + +FBSD_1.0 { + fpgetmask; + fpgetround; + fpsetmask; + fpsetround; +}; + +FBSD_1.5 { + fpgetsticky; + fpsetsticky; +}; diff --git a/lib/libc/arm/_fpmath.h b/lib/libc/arm/_fpmath.h new file mode 100644 index 0000000..0d18ef7 --- /dev/null +++ b/lib/libc/arm/_fpmath.h @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/arm/_fpmath.h 255361 2013-09-07 14:04:10Z andrew $ + */ + +#if defined(__VFP_FP__) || defined(__ARM_EABI__) +#define _IEEE_WORD_ORDER _BYTE_ORDER +#else +#define _IEEE_WORD_ORDER _BIG_ENDIAN +#endif + +union IEEEl2bits { + long double e; + struct { +#if _BYTE_ORDER == _LITTLE_ENDIAN +#if _IEEE_WORD_ORDER == _LITTLE_ENDIAN + unsigned int manl :32; +#endif + unsigned int manh :20; + unsigned int exp :11; + unsigned int sign :1; +#if _IEEE_WORD_ORDER == _BIG_ENDIAN + unsigned int manl :32; +#endif +#else /* _BYTE_ORDER == _LITTLE_ENDIAN */ + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; +#endif + } bits; +}; + +#define LDBL_NBIT 0 +#define LDBL_IMPLICIT_NBIT +#define mask_nbit_l(u) ((void)0) + +#define LDBL_MANH_SIZE 20 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/lib/libc/arm/aeabi/Makefile.inc b/lib/libc/arm/aeabi/Makefile.inc new file mode 100644 index 0000000..041ac9d --- /dev/null +++ b/lib/libc/arm/aeabi/Makefile.inc @@ -0,0 +1,33 @@ +# $FreeBSD: releng/11.1/lib/libc/arm/aeabi/Makefile.inc 316998 2017-04-16 05:14:42Z mmel $ + +.PATH: ${LIBC_SRCTOP}/arm/aeabi + +SRCS+= aeabi_atexit.c \ + aeabi_unwind_cpp.c \ + aeabi_unwind_exidx.c +.if (${MACHINE_ARCH:Marmv6*} && defined(CPUTYPE) && ${CPUTYPE:M*soft*} != "") || \ + ${MACHINE_ARCH:Marmv6*} == "" +SRCS+= aeabi_asm_double.S \ + aeabi_asm_float.S \ + aeabi_double.c \ + aeabi_float.c +.endif +.if ${MACHINE_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "") +SRCS+= aeabi_vfp_double.S \ + aeabi_vfp_float.S +.endif + +# Add the aeabi_mem* functions. While they live in compiler-rt they call into +# libc. This causes issues when other parts of libc call these functions. +# We work around this by including these functions in libc but mark them as +# hidden so users of libc will not pick up these versions. +.PATH: ${SRCTOP}/contrib/compiler-rt/lib/builtins/arm + +SRCS+= aeabi_memcmp.S \ + aeabi_memcpy.S \ + aeabi_memmove.S \ + aeabi_memset.S + +SRCS+= aeabi_int_div.S + +SYM_MAPS+=${LIBC_SRCTOP}/arm/aeabi/Symbol.map diff --git a/lib/libc/arm/aeabi/Symbol.map b/lib/libc/arm/aeabi/Symbol.map new file mode 100644 index 0000000..e720fb6 --- /dev/null +++ b/lib/libc/arm/aeabi/Symbol.map @@ -0,0 +1,79 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/arm/aeabi/Symbol.map 316998 2017-04-16 05:14:42Z mmel $ + */ + +/* + * This only needs to contain AEABI symbols that are not listed in + * symbol maps from other parts of libc (i.e., not found in + * stdlib/Symbol.map, string/Symbol.map, sys/Symbol.map, ...). + */ +FBSDprivate_1.0 { + __aeabi_atexit; + + __aeabi_dcmpeq; + __aeabi_dcmplt; + __aeabi_dcmple; + __aeabi_dcmpge; + __aeabi_dcmpgt; + __aeabi_dcmpun; + + __aeabi_cdcmpeq; + __aeabi_cdcmple; + __aeabi_cdrcmple; + + __aeabi_d2iz; + __aeabi_d2f; + + __aeabi_dadd; + __aeabi_ddiv; + __aeabi_dmul; + __aeabi_dsub; + + + __aeabi_fcmpeq; + __aeabi_fcmplt; + __aeabi_fcmple; + __aeabi_fcmpge; + __aeabi_fcmpgt; + __aeabi_fcmpun; + + __aeabi_cfcmpeq; + __aeabi_cfcmple; + __aeabi_cfrcmple; + + __aeabi_f2iz; + __aeabi_f2d; + + __aeabi_fadd; + __aeabi_fdiv; + __aeabi_fmul; + __aeabi_fsub; + + + __aeabi_i2d; + __aeabi_i2f; + + + __aeabi_memclr; + __aeabi_memclr4; + __aeabi_memclr8; + __aeabi_memcmp; + __aeabi_memcmp4; + __aeabi_memcmp8; + __aeabi_memcpy; + __aeabi_memcpy4; + __aeabi_memcpy8; + __aeabi_memmove; + __aeabi_memmove4; + __aeabi_memmove8; + __aeabi_memset; + __aeabi_memset4; + __aeabi_memset8; + + /* + * A workaround for DEFINE_AEABI_FUNCTION_ALIAS() bug. + * - see aeabi_int_div.S + */ + __aeabi_idiv; + __aeabi_uidiv; +}; diff --git a/lib/libc/arm/aeabi/aeabi_asm_double.S b/lib/libc/arm/aeabi/aeabi_asm_double.S new file mode 100644 index 0000000..d00e2d0 --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_asm_double.S @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2014 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/aeabi/aeabi_asm_double.S 288373 2015-09-29 16:09:58Z kib $"); + +#define PCR_Z (1 << 30) +#define PCR_C (1 << 29) + +/* + * These functions return the result in the CPSR register. + * + * For __aeabi_cdcmple: + * Z C + * LT 0 0 + * EQ 1 1 + * else 0 1 + * + * __aeabi_cdrcmple is the same as __aeabi_cdcmple, however the arguments + * have been swapped. + */ +ENTRY(__aeabi_cdcmple) + push {r4, r5, r6, r7, ip, lr} + + /* Backup the input registers */ + mov r4, r0 + mov r5, r1 + mov r6, r2 + mov r7, r3 + /* Is it less than? */ + bl __aeabi_dcmplt + cmp r0, #1 + bne 1f + /* Yes, clear Z and C */ + mov ip, #(0) + b 99f + +1: + /* Restore the input regsters for the next function call */ + mov r0, r4 + mov r1, r5 + mov r2, r6 + mov r3, r7 + /* Is it equal? */ + bl __aeabi_dcmpeq + cmp r0, #1 + bne 2f + /* Yes, set Z and C */ + mov ip, #(PCR_Z | PCR_C) + b 99f + +2: + /* Not less than or equal, set C and clear Z */ + mov ip, #(PCR_C) + +99: + msr cpsr_c, ip + pop {r4, r5, r6, r7, ip, pc} +END(__aeabi_cdcmple) + +ENTRY(__aeabi_cdrcmple) + /* Swap the first half of the arguments */ + mov ip, r0 + mov r0, r2 + mov r2, ip + + /* And the second half */ + mov ip, r1 + mov r1, r3 + mov r3, ip + + b __aeabi_cdcmple +END(__aeabi_cdrcmple) + +/* + * This is just like __aeabi_cdcmple except it will not throw an exception + * in the presence of a quiet NaN. If either argument is a signalling NaN we + * will still signal. + */ +ENTRY(__aeabi_cdcmpeq) + /* Check if we can call __aeabi_cfcmple safely */ + push {r0, r1, r2, r3, r4, lr} + bl __aeabi_cdcmpeq_helper + cmp r0, #1 + pop {r0, r1, r2, r3, r4, lr} + beq 1f + + bl __aeabi_cdcmple + RET + +1: + mov ip, #(PCR_C) + msr cpsr_c, ip + RET +END(__aeabi_cdcmpeq) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/aeabi/aeabi_asm_float.S b/lib/libc/arm/aeabi/aeabi_asm_float.S new file mode 100644 index 0000000..8a3e778 --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_asm_float.S @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2014 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/aeabi/aeabi_asm_float.S 288373 2015-09-29 16:09:58Z kib $"); + +#define PCR_Z (1 << 30) +#define PCR_C (1 << 29) + +/* + * These functions return the result in the CPSR register. + * + * For __aeabi_cfcmple: + * Z C + * LT 0 0 + * EQ 1 1 + * else 0 1 + * + * __aeabi_cfrcmple is the same as __aeabi_cfcmple, however the arguments + * have been swapped. + */ +ENTRY(__aeabi_cfcmple) + push {r4, r5, ip, lr} + + /* Backup the input registers */ + mov r4, r0 + mov r5, r1 + /* Is it less than? */ + bl __aeabi_fcmplt + cmp r0, #1 + bne 1f + /* Yes, clear Z and C */ + mov ip, #(0) + b 99f + +1: + /* Restore the input regsters for the next function call */ + mov r0, r4 + mov r1, r5 + /* Is it equal? */ + bl __aeabi_fcmpeq + cmp r0, #1 + bne 2f + /* Yes, set Z and C */ + mov ip, #(PCR_Z | PCR_C) + b 99f + +2: + /* Not less than or equal, set C and clear Z */ + mov ip, #(PCR_C) + +99: + msr cpsr_c, ip + pop {r4, r5, ip, pc} +END(__aeabi_cfcmple) + +ENTRY(__aeabi_cfrcmple) + /* Swap the arguments */ + mov ip, r0 + mov r0, r1 + mov r1, ip + + b __aeabi_cfcmple +END(__aeabi_cfrcmple) + +/* + * This is just like __aeabi_cfcmple except it will not throw an exception + * in the presence of a quiet NaN. If either argument is a signalling NaN we + * will still signal. + */ +ENTRY(__aeabi_cfcmpeq) + /* Check if we can call __aeabi_cfcmple safely */ + push {r0, r1, r2, lr} + bl __aeabi_cfcmpeq_helper + cmp r0, #1 + pop {r0, r1, r2, lr} + beq 1f + + bl __aeabi_cfcmple + RET + +1: + mov ip, #(PCR_C) + msr cpsr_c, ip + RET +END(__aeabi_cfcmpeq) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/aeabi/aeabi_atexit.c b/lib/libc/arm/aeabi/aeabi_atexit.c new file mode 100644 index 0000000..993618f --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_atexit.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/aeabi/aeabi_atexit.c 245655 2013-01-19 05:33:55Z andrew $"); + +int __cxa_atexit(void (*)(void *), void *, void *); + +int +__aeabi_atexit(void *object, void (*func)(void*), void *dso) +{ + return __cxa_atexit(func, object, dso); +} + diff --git a/lib/libc/arm/aeabi/aeabi_double.c b/lib/libc/arm/aeabi/aeabi_double.c new file mode 100644 index 0000000..0aba4d3 --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_double.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2012 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/aeabi/aeabi_double.c 273088 2014-10-14 14:27:51Z andrew $"); + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include "aeabi_vfp.h" + +extern int _libc_arm_fpu_present; + +flag __unorddf2(float64, float64); + +/* These are written in asm and are only called from this file */ +int __aeabi_dcmpeq_vfp(float64, float64); +int __aeabi_dcmplt_vfp(float64, float64); +int __aeabi_dcmple_vfp(float64, float64); +int __aeabi_dcmpgt_vfp(float64, float64); +int __aeabi_dcmpge_vfp(float64, float64); +int __aeabi_dcmpun_vfp(float64, float64); +int __aeabi_d2iz_vfp(float64); +float32 __aeabi_d2f_vfp(float64); +float64 __aeabi_i2d_vfp(int); +float64 __aeabi_dadd_vfp(float64, float64); +float64 __aeabi_ddiv_vfp(float64, float64); +float64 __aeabi_dmul_vfp(float64, float64); +float64 __aeabi_dsub_vfp(float64, float64); + +/* + * Depending on the target these will: + * On armv6 with a vfp call the above function, or + * Call the softfloat function in the 3rd argument. + */ +int AEABI_FUNC2(dcmpeq, float64, float64_eq) +int AEABI_FUNC2(dcmplt, float64, float64_lt) +int AEABI_FUNC2(dcmple, float64, float64_le) +int AEABI_FUNC2_REV(dcmpge, float64, float64_le) +int AEABI_FUNC2_REV(dcmpgt, float64, float64_lt) +int AEABI_FUNC2(dcmpun, float64, __unorddf2) + +int AEABI_FUNC(d2iz, float64, float64_to_int32_round_to_zero) +float32 AEABI_FUNC(d2f, float64, float64_to_float32) +float64 AEABI_FUNC(i2d, int, int32_to_float64) + +float64 AEABI_FUNC2(dadd, float64, float64_add) +float64 AEABI_FUNC2(ddiv, float64, float64_div) +float64 AEABI_FUNC2(dmul, float64, float64_mul) +float64 AEABI_FUNC2(dsub, float64, float64_sub) + +int +__aeabi_cdcmpeq_helper(float64 a, float64 b) +{ + int quiet = 0; + + /* Check if a is a NaN */ + if ((a << 1) > 0xffe0000000000000ull) { + /* If it's a signalling NaN we will always signal */ + if ((a & 0x0008000000000000ull) == 0) + return (0); + + quiet = 1; + } + + /* Check if b is a NaN */ + if ((b << 1) > 0xffe0000000000000ull) { + /* If it's a signalling NaN we will always signal */ + if ((b & 0x0008000000000000ull) == 0) + return (0); + + quiet = 1; + } + + return (quiet); +} diff --git a/lib/libc/arm/aeabi/aeabi_float.c b/lib/libc/arm/aeabi/aeabi_float.c new file mode 100644 index 0000000..b4bbe3c --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_float.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2012 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/aeabi/aeabi_float.c 273088 2014-10-14 14:27:51Z andrew $"); + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include "aeabi_vfp.h" + +extern int _libc_arm_fpu_present; + +flag __unordsf2(float32, float32); + +/* These are written in asm and are only called from this file */ +int __aeabi_fcmpeq_vfp(float32, float32); +int __aeabi_fcmplt_vfp(float32, float32); +int __aeabi_fcmple_vfp(float32, float32); +int __aeabi_fcmpgt_vfp(float32, float32); +int __aeabi_fcmpge_vfp(float32, float32); +int __aeabi_fcmpun_vfp(float32, float32); +int __aeabi_f2iz_vfp(float32); +float64 __aeabi_f2d_vfp(float32); +float32 __aeabi_i2f_vfp(int); +float32 __aeabi_fadd_vfp(float32, float32); +float32 __aeabi_fdiv_vfp(float32, float32); +float32 __aeabi_fmul_vfp(float32, float32); +float32 __aeabi_fsub_vfp(float32, float32); + +/* + * Depending on the target these will: + * On armv6 with a vfp call the above function, or + * Call the softfloat function in the 3rd argument. + */ +int AEABI_FUNC2(fcmpeq, float32, float32_eq) +int AEABI_FUNC2(fcmplt, float32, float32_lt) +int AEABI_FUNC2(fcmple, float32, float32_le) +int AEABI_FUNC2_REV(fcmpge, float32, float32_le) +int AEABI_FUNC2_REV(fcmpgt, float32, float32_lt) +int AEABI_FUNC2(fcmpun, float32, __unordsf2) + +int AEABI_FUNC(f2iz, float32, float32_to_int32_round_to_zero) +float64 AEABI_FUNC(f2d, float32, float32_to_float64) +float32 AEABI_FUNC(i2f, int, int32_to_float32) + +float32 AEABI_FUNC2(fadd, float32, float32_add) +float32 AEABI_FUNC2(fdiv, float32, float32_div) +float32 AEABI_FUNC2(fmul, float32, float32_mul) +float32 AEABI_FUNC2(fsub, float32, float32_sub) + +int +__aeabi_cfcmpeq_helper(float32 a, float32 b) +{ + int quiet = 0; + + /* Check if a is a NaN */ + if ((a << 1) > 0xff000000u) { + /* If it's a signalling NaN we will always signal */ + if ((a & 0x00400000u) == 0) + return (0); + + quiet = 1; + } + + /* Check if b is a NaN */ + if ((b << 1) > 0xff000000u) { + /* If it's a signalling NaN we will always signal */ + if ((b & 0x00400000u) == 0) + return (0); + + quiet = 1; + } + + return (quiet); +} diff --git a/lib/libc/arm/aeabi/aeabi_int_div.S b/lib/libc/arm/aeabi/aeabi_int_div.S new file mode 100644 index 0000000..5f01b6c --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_int_div.S @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2017 Michal Meloun + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/aeabi/aeabi_int_div.S 316998 2017-04-16 05:14:42Z mmel $"); + +/* + * Due to bug in libcompiler_rt, all symbols declared by + * DEFINE_AEABI_FUNCTION_ALIAS() are not hidden. All these but + * __aeabi_uidiv_compat and/or __aeabi_idiv_compat are explicitly + * exported from libc and don't causes problems. + * + * As workaround, export these from libc as compatible symbols, + * in global namespace + */ + +ENTRY(__aeabi_uidiv_compat) + .symver __aeabi_uidiv_compat, __aeabi_uidiv@ + b __udivsi3 +END(__aeabi_uidiv_compat) + +ENTRY(__aeabi_idiv_compat) + .symver __aeabi_idiv_compat, __aeabi_idiv@ + b __divsi3 +END(__aeabi_idiv_compat) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/aeabi/aeabi_unwind_cpp.c b/lib/libc/arm/aeabi/aeabi_unwind_cpp.c new file mode 100644 index 0000000..2f79b3c --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_unwind_cpp.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2011 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + */ + +/* + * Provide an implementation of __aeabi_unwind_cpp_pr{0,1,2}. These are + * required by libc but are implemented in libgcc_eh.a which we don't link + * against. The libgcc_eh.a version will be called so we call abort to + * check this. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/aeabi/aeabi_unwind_cpp.c 245655 2013-01-19 05:33:55Z andrew $"); + +#include + +void __aeabi_unwind_cpp_pr0(void) __hidden; +void __aeabi_unwind_cpp_pr1(void) __hidden; +void __aeabi_unwind_cpp_pr2(void) __hidden; + +void +__aeabi_unwind_cpp_pr0(void) +{ + abort(); +} + +void +__aeabi_unwind_cpp_pr1(void) +{ + abort(); +} + +void +__aeabi_unwind_cpp_pr2(void) +{ + abort(); +} + diff --git a/lib/libc/arm/aeabi/aeabi_unwind_exidx.c b/lib/libc/arm/aeabi/aeabi_unwind_exidx.c new file mode 100644 index 0000000..0b82026 --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_unwind_exidx.c @@ -0,0 +1,104 @@ +/*- + * Copyright (c) 2014 Ian Lepore + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/aeabi/aeabi_unwind_exidx.c 268893 2014-07-19 22:13:27Z ian $"); + +#include +#include +#include +#include + +/* + * ARM EABI unwind helper. + * + * This finds the exidx section address and size associated with a given code + * address. There are separate implementations for static and dynamic code. + * + * GCC expects this function to exist as __gnu_Unwind_Find_exidx(), clang and + * BSD tools expect it to be dl_unwind_find_exidx(). Both have the same API, so + * we set up an alias for GCC. + */ +__strong_reference(dl_unwind_find_exidx, __gnu_Unwind_Find_exidx); + +/* + * Each entry in the exidx section is a pair of 32-bit words. We don't + * interpret the contents of the entries here; this typedef is just a local + * convenience for using sizeof() and doing pointer math. + */ +typedef struct exidx_entry { + uint32_t data[2]; +} exidx_entry; + +#ifdef __PIC__ + +/* + * Unwind helper for dynamically linked code. + * + * This finds the shared object that contains the given address, and returns the + * address of the exidx section in that shared object along with the number of + * entries in that section, or NULL if it wasn't found. + */ +void * +dl_unwind_find_exidx(const void *pc, int *pcount) +{ + const Elf_Phdr *hdr; + struct dl_phdr_info info; + int i; + + if (_rtld_addr_phdr(pc, &info)) { + hdr = info.dlpi_phdr; + for (i = 0; i < info.dlpi_phnum; i++, hdr++) { + if (hdr->p_type == PT_ARM_EXIDX) { + *pcount = hdr->p_memsz / sizeof(exidx_entry); + return ((void *)(info.dlpi_addr + hdr->p_vaddr)); + } + } + } + return (NULL); +} + +#else /* !__PIC__ */ + +/* + * Unwind helper for statically linked code. + * + * In a statically linked program, the linker populates a pair of symbols with + * the addresses of the start and end of the exidx table, so returning the + * address and count of elements is pretty straighforward. + */ +void * +dl_unwind_find_exidx(const void *pc, int *pcount) +{ + extern struct exidx_entry __exidx_start; + extern struct exidx_entry __exidx_end; + + *pcount = (int)(&__exidx_end - &__exidx_start); + return (&__exidx_start); +} + +#endif /* __PIC__ */ + diff --git a/lib/libc/arm/aeabi/aeabi_vfp.h b/lib/libc/arm/aeabi/aeabi_vfp.h new file mode 100644 index 0000000..95546ff --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_vfp.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2013 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/arm/aeabi/aeabi_vfp.h 297620 2016-04-06 16:50:18Z andrew $ + * + */ + +#ifndef AEABI_VFP_H +#define AEABI_VFP_H + +#include + +/* + * ASM helper macros. These allow the functions to be changed depending on + * the endian-ness we are building for. + */ + +/* Allow the name of the function to be changed depending on the ABI */ +#ifndef __ARM_PCS_VFP +#define AEABI_ENTRY(x) ENTRY(__aeabi_ ## x ## _vfp) +#define AEABI_END(x) END(__aeabi_ ## x ## _vfp) +#else +#define AEABI_ENTRY(x) ENTRY(__aeabi_ ## x) +#define AEABI_END(x) END(__aeabi_ ## x) +#endif + +/* + * These should be used when a function either takes, or returns a floating + * point falue. They will load the data from an ARM to a VFP register(s), + * or from a VFP to an ARM register + */ +#ifdef __ARM_BIG_ENDIAN +#define LOAD_DREG(vreg, reg0, reg1) vmov vreg, reg1, reg0 +#define UNLOAD_DREG(reg0, reg1, vreg) vmov reg1, reg0, vreg +#else +#define LOAD_DREG(vreg, reg0, reg1) vmov vreg, reg0, reg1 +#define UNLOAD_DREG(reg0, reg1, vreg) vmov reg0, reg1, vreg +#endif + +#define LOAD_SREGS(vreg0, vreg1, reg0, reg1) vmov vreg0, vreg1, reg0, reg1 +#define LOAD_SREG(vreg, reg) vmov vreg, reg +#define UNLOAD_SREG(reg, vreg) vmov reg, vreg + +/* + * C Helper macros + */ + +#if __ARM_ARCH >= 6 +/* + * Generate a function that will either call into the VFP implementation, + * or the soft float version for a given __aeabi_* helper. The function + * will take a single argument of the type given by in_type. + */ +#define AEABI_FUNC(name, in_type, soft_func) \ +__aeabi_ ## name(in_type a) \ +{ \ + if (_libc_arm_fpu_present) \ + return __aeabi_ ## name ## _vfp(a); \ + else \ + return soft_func (a); \ +} + +/* As above, but takes two arguments of the same type */ +#define AEABI_FUNC2(name, in_type, soft_func) \ +__aeabi_ ## name(in_type a, in_type b) \ +{ \ + if (_libc_arm_fpu_present) \ + return __aeabi_ ## name ## _vfp(a, b); \ + else \ + return soft_func (a, b); \ +} + +/* As above, but with the soft float arguments reversed */ +#define AEABI_FUNC2_REV(name, in_type, soft_func) \ +__aeabi_ ## name(in_type a, in_type b) \ +{ \ + if (_libc_arm_fpu_present) \ + return __aeabi_ ## name ## _vfp(a, b); \ + else \ + return soft_func (b, a); \ +} +#else +/* + * Helper macros for when we are only able to use the softfloat + * version of these functions, i.e. on arm before armv6. + */ +#define AEABI_FUNC(name, in_type, soft_func) \ +__aeabi_ ## name(in_type a) \ +{ \ + return soft_func (a); \ +} + +/* As above, but takes two arguments of the same type */ +#define AEABI_FUNC2(name, in_type, soft_func) \ +__aeabi_ ## name(in_type a, in_type b) \ +{ \ + return soft_func (a, b); \ +} + +/* As above, but with the soft float arguments reversed */ +#define AEABI_FUNC2_REV(name, in_type, soft_func) \ +__aeabi_ ## name(in_type a, in_type b) \ +{ \ + return soft_func (b, a); \ +} +#endif + +#endif + diff --git a/lib/libc/arm/aeabi/aeabi_vfp_double.S b/lib/libc/arm/aeabi/aeabi_vfp_double.S new file mode 100644 index 0000000..6fb6bdf --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_vfp_double.S @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2013 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/aeabi/aeabi_vfp_double.S 288373 2015-09-29 16:09:58Z kib $"); + +#include "aeabi_vfp.h" + +.fpu vfp +.syntax unified + +/* void __aeabi_cdcmpeq(double, double) */ +AEABI_ENTRY(cdcmpeq) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + RET +AEABI_END(cdcmpeq) + +/* void __aeabi_cdcmple(double, double) */ +AEABI_ENTRY(cdcmple) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmpe.f64 d0, d1 + vmrs APSR_nzcv, fpscr + RET +AEABI_END(cdcmple) + +/* void __aeabi_cdrcmple(double, double) */ +AEABI_ENTRY(cdrcmple) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmpe.f64 d1, d0 + vmrs APSR_nzcv, fpscr + RET +AEABI_END(cdrcmple) + +/* int __aeabi_dcmpeq(double, double) */ +AEABI_ENTRY(dcmpeq) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + ite ne + movne r0, #0 + moveq r0, #1 + RET +AEABI_END(dcmpeq) + +/* int __aeabi_dcmplt(double, double) */ +AEABI_ENTRY(dcmplt) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + ite cs + movcs r0, #0 + movcc r0, #1 + RET +AEABI_END(dcmplt) + +/* int __aeabi_dcmple(double, double) */ +AEABI_ENTRY(dcmple) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + ite hi + movhi r0, #0 + movls r0, #1 + RET +AEABI_END(dcmple) + +/* int __aeabi_dcmpge(double, double) */ +AEABI_ENTRY(dcmpge) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + ite lt + movlt r0, #0 + movge r0, #1 + RET +AEABI_END(dcmpge) + +/* int __aeabi_dcmpgt(double, double) */ +AEABI_ENTRY(dcmpgt) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + ite le + movle r0, #0 + movgt r0, #1 + RET +AEABI_END(dcmpgt) + +/* int __aeabi_dcmpun(double, double) */ +AEABI_ENTRY(dcmpun) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vcmp.f64 d0, d1 + vmrs APSR_nzcv, fpscr + ite vc + movvc r0, #0 + movvs r0, #1 + RET +AEABI_END(dcmpun) + +/* int __aeabi_d2iz(double) */ +AEABI_ENTRY(d2iz) + LOAD_DREG(d0, r0, r1) +#if 0 + /* + * This should be the correct instruction, but binutils incorrectly + * encodes it as the version that used FPSCR to determine the rounding. + * When binutils is fixed we can use this again. + */ + vcvt.s32.f64 s0, d0 +#else + ftosizd s0, d0 +#endif + vmov r0, s0 + RET +AEABI_END(d2iz) + +/* float __aeabi_d2f(double) */ +AEABI_ENTRY(d2f) + LOAD_DREG(d0, r0, r1) + vcvt.f32.f64 s0, d0 + UNLOAD_SREG(r0, s0) + RET +AEABI_END(d2f) + +/* double __aeabi_i2d(int) */ +AEABI_ENTRY(i2d) + vmov s0, r0 + vcvt.f64.s32 d0, s0 + UNLOAD_DREG(r0, r1, d0) + RET +AEABI_END(i2d) + +/* double __aeabi_dadd(double, double) */ +AEABI_ENTRY(dadd) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vadd.f64 d0, d0, d1 + UNLOAD_DREG(r0, r1, d0) + RET +AEABI_END(dadd) + +/* double __aeabi_ddiv(double, double) */ +AEABI_ENTRY(ddiv) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vdiv.f64 d0, d0, d1 + UNLOAD_DREG(r0, r1, d0) + RET +AEABI_END(ddiv) + +/* double __aeabi_dmul(double, double) */ +AEABI_ENTRY(dmul) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vmul.f64 d0, d0, d1 + UNLOAD_DREG(r0, r1, d0) + RET +AEABI_END(dmul) + +/* double __aeabi_dsub(double, double) */ +AEABI_ENTRY(dsub) + LOAD_DREG(d0, r0, r1) + LOAD_DREG(d1, r2, r3) + vsub.f64 d0, d0, d1 + UNLOAD_DREG(r0, r1, d0) + RET +AEABI_END(dsub) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/aeabi/aeabi_vfp_float.S b/lib/libc/arm/aeabi/aeabi_vfp_float.S new file mode 100644 index 0000000..6440731 --- /dev/null +++ b/lib/libc/arm/aeabi/aeabi_vfp_float.S @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2013 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/aeabi/aeabi_vfp_float.S 288373 2015-09-29 16:09:58Z kib $"); + +#include "aeabi_vfp.h" + +.fpu vfp +.syntax unified + +/* void __aeabi_cfcmpeq(float, float) */ +AEABI_ENTRY(cfcmpeq) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + RET +AEABI_END(cfcmpeq) + +/* void __aeabi_cfcmple(float, float) */ +AEABI_ENTRY(cfcmple) + LOAD_SREGS(s0, s1, r0, r1) + vcmpe.f32 s0, s1 + vmrs APSR_nzcv, fpscr + RET +AEABI_END(cfcmple) + +/* void __aeabi_cfrcmple(float, float) */ +AEABI_ENTRY(cfrcmple) + LOAD_SREGS(s0, s1, r0, r1) + vcmpe.f32 s1, s0 + vmrs APSR_nzcv, fpscr + RET +AEABI_END(cfrcmple) + +/* int __aeabi_fcmpeq(float, float) */ +AEABI_ENTRY(fcmpeq) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + ite ne + movne r0, #0 + moveq r0, #1 + RET +AEABI_END(fcmpeq) + +/* int __aeabi_fcmplt(float, float) */ +AEABI_ENTRY(fcmplt) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + ite cs + movcs r0, #0 + movcc r0, #1 + RET +AEABI_END(fcmplt) + +/* int __aeabi_fcmple(float, float) */ +AEABI_ENTRY(fcmple) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + ite hi + movhi r0, #0 + movls r0, #1 + RET +AEABI_END(fcmple) + +/* int __aeabi_fcmpge(float, float) */ +AEABI_ENTRY(fcmpge) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + ite lt + movlt r0, #0 + movge r0, #1 + RET +AEABI_END(fcmpge) + +/* int __aeabi_fcmpgt(float, float) */ +AEABI_ENTRY(fcmpgt) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + ite le + movle r0, #0 + movgt r0, #1 + RET +AEABI_END(fcmpgt) + +/* int __aeabi_fcmpun(float, float) */ +AEABI_ENTRY(fcmpun) + LOAD_SREGS(s0, s1, r0, r1) + vcmp.f32 s0, s1 + vmrs APSR_nzcv, fpscr + ite vc + movvc r0, #0 + movvs r0, #1 + RET +AEABI_END(fcmpun) + +/* int __aeabi_f2iz(float) */ +AEABI_ENTRY(f2iz) + LOAD_SREG(s0, r0) +#if 0 + /* + * This should be the correct instruction, but binutils incorrectly + * encodes it as the version that used FPSCR to determine the rounding. + * When binutils is fixed we can use this again. + */ + vcvt.s32.f32 s0, s0 +#else + ftosizs s0, s0 +#endif + vmov r0, s0 + RET +AEABI_END(f2iz) + +/* double __aeabi_f2d(float) */ +AEABI_ENTRY(f2d) + LOAD_SREG(s0, r0) + vcvt.f64.f32 d0, s0 + UNLOAD_DREG(r0, r1, d0) + RET +AEABI_END(f2d) + +/* float __aeabi_i2f(int) */ +AEABI_ENTRY(i2f) + vmov s0, r0 + vcvt.f32.s32 s0, s0 + UNLOAD_SREG(r0, s0) + RET +AEABI_END(i2f) + +/* float __aeabi_fadd(float, float) */ +AEABI_ENTRY(fadd) + LOAD_SREGS(s0, s1, r0, r1) + vadd.f32 s0, s0, s1 + UNLOAD_SREG(r0, s0) + RET +AEABI_END(fadd) + +/* float __aeabi_fmul(float, float) */ +AEABI_ENTRY(fdiv) + LOAD_SREGS(s0, s1, r0, r1) + vdiv.f32 s0, s0, s1 + UNLOAD_SREG(r0, s0) + RET +AEABI_END(fdiv) + +/* float __aeabi_fmul(float, float) */ +AEABI_ENTRY(fmul) + LOAD_SREGS(s0, s1, r0, r1) + vmul.f32 s0, s0, s1 + UNLOAD_SREG(r0, s0) + RET +AEABI_END(fmul) + +/* float __aeabi_fsub(float, float) */ +AEABI_ENTRY(fsub) + LOAD_SREGS(s0, s1, r0, r1) + vsub.f32 s0, s0, s1 + UNLOAD_SREG(r0, s0) + RET +AEABI_END(fsub) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/arith.h b/lib/libc/arm/arith.h new file mode 100644 index 0000000..b7d7ace --- /dev/null +++ b/lib/libc/arm/arith.h @@ -0,0 +1,21 @@ +/* + * MD header for contrib/gdtoa + * + * $FreeBSD: releng/11.1/lib/libc/arm/arith.h 255361 2013-09-07 14:04:10Z andrew $ + */ + +/* + * NOTE: The definitions in this file must be correct or strtod(3) and + * floating point formats in printf(3) will break! The file can be + * generated by running contrib/gdtoa/arithchk.c on the target + * architecture. See contrib/gdtoa/gdtoaimp.h for details. + */ + +#if !defined(__ARMEB__) && (defined(__VFP_FP__) || defined(__ARM_EABI__)) +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#define Sudden_Underflow +#else +#define IEEE_MC68k +#define Arith_Kind_ASL 2 +#endif diff --git a/lib/libc/arm/gd_qnan.h b/lib/libc/arm/gd_qnan.h new file mode 100644 index 0000000..fd2d444 --- /dev/null +++ b/lib/libc/arm/gd_qnan.h @@ -0,0 +1,23 @@ +/* + * MD header for contrib/gdtoa + * + * This file can be generated by compiling and running contrib/gdtoa/qnan.c + * on the target architecture after arith.h has been generated. + * + * XXX I don't have ARM hardware, so I just guessed. --das + * + * $FreeBSD: releng/11.1/lib/libc/arm/gd_qnan.h 174680 2007-12-16 21:15:09Z das $ + */ + +#define f_QNAN 0x7fc00000 +#define d_QNAN0 0x0 +#define d_QNAN1 0x7ff80000 +#define ld_QNAN0 0x0 +#define ld_QNAN1 0xc0000000 +#define ld_QNAN2 0x7fff +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x0 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0xc000 +#define ldus_QNAN4 0x7fff diff --git a/lib/libc/arm/gen/Makefile.inc b/lib/libc/arm/gen/Makefile.inc new file mode 100644 index 0000000..820d474 --- /dev/null +++ b/lib/libc/arm/gen/Makefile.inc @@ -0,0 +1,13 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/arm/gen/Makefile.inc 300119 2016-05-18 06:01:18Z imp $ + +SRCS+= _ctx_start.S _setjmp.S _set_tp.c alloca.S fabs.c \ + infinity.c ldexp.c makecontext.c \ + __aeabi_read_tp.S setjmp.S signalcontext.c sigsetjmp.S flt_rounds.c \ + arm_initfini.c \ + trivial-getcontextx.c + +.if ${MACHINE_ARCH:Marmv6*} && (!defined(CPUTYPE) || ${CPUTYPE:M*soft*} == "") +SRCS+= fpgetmask_vfp.c fpgetround_vfp.c fpgetsticky_vfp.c fpsetmask_vfp.c \ + fpsetround_vfp.c fpsetsticky_vfp.c +.endif diff --git a/lib/libc/arm/gen/__aeabi_read_tp.S b/lib/libc/arm/gen/__aeabi_read_tp.S new file mode 100644 index 0000000..fdef1e8 --- /dev/null +++ b/lib/libc/arm/gen/__aeabi_read_tp.S @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2012 Oleksandr Tymoshenko + * Copyright (c) 2012 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/__aeabi_read_tp.S 288373 2015-09-29 16:09:58Z kib $"); + +#include + +ENTRY(__aeabi_read_tp) +#ifdef ARM_TP_ADDRESS + ldr r0, .Larm_tp_address + ldr r0, [r0] +#else + mrc p15, 0, r0, c13, c0, 3 +#endif + RET +END(__aeabi_read_tp) + +#ifdef ARM_TP_ADDRESS +.Larm_tp_address: + .word ARM_TP_ADDRESS +#endif + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/_ctx_start.S b/lib/libc/arm/gen/_ctx_start.S new file mode 100644 index 0000000..454e2e6 --- /dev/null +++ b/lib/libc/arm/gen/_ctx_start.S @@ -0,0 +1,12 @@ +#include + +.ident "$FreeBSD: releng/11.1/lib/libc/arm/gen/_ctx_start.S 288373 2015-09-29 16:09:58Z kib $" +ENTRY(_ctx_start) + mov lr, pc + mov pc, r4 + mov r0, r5 + bl _C_LABEL(ctx_done) + bl _C_LABEL(abort) +END(_ctx_start) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/_set_tp.c b/lib/libc/arm/gen/_set_tp.c new file mode 100644 index 0000000..8b6d187 --- /dev/null +++ b/lib/libc/arm/gen/_set_tp.c @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/arm/gen/_set_tp.c 288019 2015-09-20 04:59:01Z rodrigc $ + */ + +#include +#include + +#include +#include "libc_private.h" + +void +_set_tp(void *tp) +{ + +#ifdef ARM_TP_ADDRESS + *((struct tcb **)ARM_TP_ADDRESS) = tp; +#else + sysarch(ARM_SET_TP, tp); +#endif +} diff --git a/lib/libc/arm/gen/_setjmp.S b/lib/libc/arm/gen/_setjmp.S new file mode 100644 index 0000000..0c231a1 --- /dev/null +++ b/lib/libc/arm/gen/_setjmp.S @@ -0,0 +1,161 @@ +/* $NetBSD: _setjmp.S,v 1.12 2013/04/19 13:45:45 matt Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * 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 Mark Brinicombe + * 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 AUTHOR 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 AUTHOR 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. + */ + +#if !defined(__SOFTFP__) && !defined(__VFP_FP__) && !defined(__ARM_PCS) +#error FPA is not supported anymore +#endif + +#if !defined(_STANDALONE) + .fpu vfp +#endif + +#include +#include + +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/_setjmp.S 288373 2015-09-29 16:09:58Z kib $"); + +/* + * C library -- _setjmp, _longjmp + * + * _longjmp(a,v) + * will generate a "return(v)" from the last call to + * _setjmp(a) + * by restoring registers from the stack. + * The previous signal state is NOT restored. + * + * Note: r0 is the return value + * r1-r3,ip are scratch registers in functions + */ + +ENTRY(_setjmp) + ldr r1, .L_setjmp_magic + +#if !defined(_STANDALONE) + ldr r2, .Lfpu_present +#ifdef PIC + GOT_INIT(r3, .L_setjmp_got, .L_setjmp_gotinit) + ldr r2, [r2, r3] +#else + ldr r2, [r2] +#endif + teq r2, #0 /* do we have a FPU? */ + beq 1f /* no, don't save VFP registers */ + + orr r1, r1, #(_JB_MAGIC__SETJMP ^ _JB_MAGIC__SETJMP_VFP) + /* change magic to VFP magic */ + add r2, r0, #(_JB_REG_D8 * 4) + vstmia r2, {d8-d15} + vmrs r2, fpscr + str r2, [r0, #(_JB_REG_FPSCR * 4)] +1: +#endif /* !_STANDALONE */ + + str r1, [r0] + + add r0, r0, #(_JB_REG_R4 * 4) + /* Store integer registers */ +#ifndef __thumb__ + stmia r0, {r4-r14} +#else + stmia r0, {r4-r12} + str r13, [r0, #((_JB_REG_R13 - _JB_REG_R4) * 4)] + str r14, [r0, #((_JB_REG_R14 - _JB_REG_R4) * 4)] +#endif + + mov r0, #0x00000000 + RET +END(_setjmp) + +.L_setjmp_magic: + .word _JB_MAGIC__SETJMP +#if !defined(_STANDALONE) + GOT_INITSYM(.L_setjmp_got, .L_setjmp_gotinit) +.Lfpu_present: + .word PIC_SYM(_libc_arm_fpu_present, GOTOFF) +#endif /* !_STANDALONE */ + +WEAK_ALIAS(___longjmp, _longjmp) +ENTRY(_longjmp) + ldr r2, [r0] /* get magic from jmp_buf */ + bic r3, r2, #(_JB_MAGIC__SETJMP ^ _JB_MAGIC__SETJMP_VFP) + /* ignore VFP-ness of magic */ + ldr ip, .L_setjmp_magic /* load magic */ + teq ip, r3 /* magic correct? */ + bne botch /* no, botch */ + +#if !defined(_STANDALONE) + teq r3, r2 /* did magic change? */ + beq 1f /* no, don't restore VFP */ + add ip, r0, #(_JB_REG_D8 * 4) + vldmia ip, {d8-d15} + ldr ip, [r0, #(_JB_REG_FPSCR * 4)] + vmsr fpscr, ip +1: +#endif /* !_STANDALONE */ + + add r0, r0, #(_JB_REG_R4 * 4) + /* Restore integer registers */ +#ifndef __thumb__ + ldmia r0, {r4-r14} +#else + ldmia r0, {r4-r12} + ldr r13, [r0, #((_JB_REG_R13 - _JB_REG_R4) * 4)] + ldr r14, [r0, #((_JB_REG_R14 - _JB_REG_R4) * 4)] +#endif + + /* Validate sp and r14 */ + teq sp, #0 + it ne + teqne r14, #0 + it eq + beq botch + + /* Set return value */ + movs r0, r1 + it eq + moveq r0, #0x00000001 + RET + + /* validation failed, die die die. */ +botch: +#if !defined(_STANDALONE) + bl PIC_SYM(_C_LABEL(longjmperror), PLT) + bl PIC_SYM(_C_LABEL(abort), PLT) +1: b 1b /* Cannot get here */ +#else + b . +#endif +END(_longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/alloca.S b/lib/libc/arm/gen/alloca.S new file mode 100644 index 0000000..4f7b598 --- /dev/null +++ b/lib/libc/arm/gen/alloca.S @@ -0,0 +1,48 @@ +/* $NetBSD: alloca.S,v 1.3 2003/04/05 23:08:51 bjh21 Exp $ */ + +/* + * Copyright (c) 1995 Mark Brinicombe + * 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 Mark Brinicombe + * 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 AUTHOR 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 AUTHOR 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. + */ + +/* like alloc, but automatic automatic free in return */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/alloca.S 288373 2015-09-29 16:09:58Z kib $"); + +ENTRY(alloca) + add r0, r0, #0x00000007 /* round up to next 8 byte alignment */ + bic r0, r0, #0x00000007 + sub sp, sp, r0 /* Adjust the stack pointer */ + mov r0, sp /* r0 = base of new space */ + RET +END(alloca) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/arm_initfini.c b/lib/libc/arm/gen/arm_initfini.c new file mode 100644 index 0000000..bba5d92 --- /dev/null +++ b/lib/libc/arm/gen/arm_initfini.c @@ -0,0 +1,78 @@ +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * Copyright (c) 2013 Andrew Turner + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas of 3am Software Foundry. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + * + * Bases on NetBSD lib/libc/arch/arm/misc/arm_initfini.c + * $NetBSD: arm_initfini.c,v 1.2 2013/01/31 06:47:55 matt Exp $ + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/arm_initfini.c 251514 2013-06-07 22:01:06Z andrew $"); + +/* + * To properly implement setjmp/longjmp for the ARM AAPCS ABI, it has to be + * aware of whether there is a FPU is present or not. Regardless of whether + * the hard-float ABI is being used, setjmp needs to save D8-D15. But it can + * only do this if those instructions won't cause an exception. + */ + +#include +#include + +#include +#include + +extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen); + +int _libc_arm_fpu_present; +static bool _libc_aapcs_initialized; + +void _libc_aapcs_init(void) __attribute__((__constructor__, __used__)); + +void +_libc_aapcs_init(void) +{ + int mib[2]; + size_t len; + + if (_libc_aapcs_initialized) + return; + + mib[0] = CTL_HW; + mib[1] = HW_FLOATINGPT; + + len = sizeof(_libc_arm_fpu_present); + if (__sysctl(mib, 2, &_libc_arm_fpu_present, &len, NULL, 0) == -1 || + len != sizeof(_libc_arm_fpu_present)) { + /* sysctl failed, assume no vfp */ + _libc_arm_fpu_present = 0; + } + + _libc_aapcs_initialized = true; +} diff --git a/lib/libc/arm/gen/divsi3.S b/lib/libc/arm/gen/divsi3.S new file mode 100644 index 0000000..d57b4ca --- /dev/null +++ b/lib/libc/arm/gen/divsi3.S @@ -0,0 +1,393 @@ +/* $NetBSD: divsi3.S,v 1.4 2003/04/05 23:27:15 bjh21 Exp $ */ + +/* + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/divsi3.S 288373 2015-09-29 16:09:58Z kib $"); + +/* + * stack is aligned as there's a possibility of branching to L_overflow + * which makes a C call + */ + +ENTRY(__umodsi3) + stmfd sp!, {lr} + sub sp, sp, #4 /* align stack */ + bl .L_udivide + add sp, sp, #4 /* unalign stack */ + mov r0, r1 + ldmfd sp!, {pc} +END(__umodsi3) + +ENTRY(__modsi3) + stmfd sp!, {lr} + sub sp, sp, #4 /* align stack */ + bl .L_divide + add sp, sp, #4 /* unalign stack */ + mov r0, r1 + ldmfd sp!, {pc} + +.L_overflow: +#if !defined(_KERNEL) && !defined(_STANDALONE) + mov r0, #8 /* SIGFPE */ + bl PIC_SYM(_C_LABEL(raise), PLT) /* raise it */ + mov r0, #0 +#else + /* XXX should cause a fatal error */ + mvn r0, #0 +#endif + RET +END(__modsi3) + +ENTRY(__udivsi3) +.L_udivide: /* r0 = r0 / r1; r1 = r0 % r1 */ + eor r0, r1, r0 + eor r1, r0, r1 + eor r0, r1, r0 + /* r0 = r1 / r0; r1 = r1 % r0 */ + cmp r0, #1 + bcc .L_overflow + beq .L_divide_l0 + mov ip, #0 + movs r1, r1 + bpl .L_divide_l1 + orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */ + movs r1, r1, lsr #1 + orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */ + b .L_divide_l1 + +.L_divide_l0: /* r0 == 1 */ + mov r0, r1 + mov r1, #0 + RET +END(__udivsi3) + +ENTRY(__divsi3) +.L_divide: /* r0 = r0 / r1; r1 = r0 % r1 */ + eor r0, r1, r0 + eor r1, r0, r1 + eor r0, r1, r0 + /* r0 = r1 / r0; r1 = r1 % r0 */ + cmp r0, #1 + bcc .L_overflow + beq .L_divide_l0 + ands ip, r0, #0x80000000 + rsbmi r0, r0, #0 + ands r2, r1, #0x80000000 + eor ip, ip, r2 + rsbmi r1, r1, #0 + orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */ + /* ip bit 0x80000000 = -ve remainder */ + +.L_divide_l1: + mov r2, #1 + mov r3, #0 + + /* + * If the highest bit of the dividend is set, we have to be + * careful when shifting the divisor. Test this. + */ + movs r1,r1 + bpl .L_old_code + + /* + * At this point, the highest bit of r1 is known to be set. + * We abuse this below in the tst instructions. + */ + tst r1, r0 /*, lsl #0 */ + bmi .L_divide_b1 + tst r1, r0, lsl #1 + bmi .L_divide_b2 + tst r1, r0, lsl #2 + bmi .L_divide_b3 + tst r1, r0, lsl #3 + bmi .L_divide_b4 + tst r1, r0, lsl #4 + bmi .L_divide_b5 + tst r1, r0, lsl #5 + bmi .L_divide_b6 + tst r1, r0, lsl #6 + bmi .L_divide_b7 + tst r1, r0, lsl #7 + bmi .L_divide_b8 + tst r1, r0, lsl #8 + bmi .L_divide_b9 + tst r1, r0, lsl #9 + bmi .L_divide_b10 + tst r1, r0, lsl #10 + bmi .L_divide_b11 + tst r1, r0, lsl #11 + bmi .L_divide_b12 + tst r1, r0, lsl #12 + bmi .L_divide_b13 + tst r1, r0, lsl #13 + bmi .L_divide_b14 + tst r1, r0, lsl #14 + bmi .L_divide_b15 + tst r1, r0, lsl #15 + bmi .L_divide_b16 + tst r1, r0, lsl #16 + bmi .L_divide_b17 + tst r1, r0, lsl #17 + bmi .L_divide_b18 + tst r1, r0, lsl #18 + bmi .L_divide_b19 + tst r1, r0, lsl #19 + bmi .L_divide_b20 + tst r1, r0, lsl #20 + bmi .L_divide_b21 + tst r1, r0, lsl #21 + bmi .L_divide_b22 + tst r1, r0, lsl #22 + bmi .L_divide_b23 + tst r1, r0, lsl #23 + bmi .L_divide_b24 + tst r1, r0, lsl #24 + bmi .L_divide_b25 + tst r1, r0, lsl #25 + bmi .L_divide_b26 + tst r1, r0, lsl #26 + bmi .L_divide_b27 + tst r1, r0, lsl #27 + bmi .L_divide_b28 + tst r1, r0, lsl #28 + bmi .L_divide_b29 + tst r1, r0, lsl #29 + bmi .L_divide_b30 + tst r1, r0, lsl #30 + bmi .L_divide_b31 +/* + * instead of: + * tst r1, r0, lsl #31 + * bmi .L_divide_b32 + */ + b .L_divide_b32 + +.L_old_code: + cmp r1, r0 + bcc .L_divide_b0 + cmp r1, r0, lsl #1 + bcc .L_divide_b1 + cmp r1, r0, lsl #2 + bcc .L_divide_b2 + cmp r1, r0, lsl #3 + bcc .L_divide_b3 + cmp r1, r0, lsl #4 + bcc .L_divide_b4 + cmp r1, r0, lsl #5 + bcc .L_divide_b5 + cmp r1, r0, lsl #6 + bcc .L_divide_b6 + cmp r1, r0, lsl #7 + bcc .L_divide_b7 + cmp r1, r0, lsl #8 + bcc .L_divide_b8 + cmp r1, r0, lsl #9 + bcc .L_divide_b9 + cmp r1, r0, lsl #10 + bcc .L_divide_b10 + cmp r1, r0, lsl #11 + bcc .L_divide_b11 + cmp r1, r0, lsl #12 + bcc .L_divide_b12 + cmp r1, r0, lsl #13 + bcc .L_divide_b13 + cmp r1, r0, lsl #14 + bcc .L_divide_b14 + cmp r1, r0, lsl #15 + bcc .L_divide_b15 + cmp r1, r0, lsl #16 + bcc .L_divide_b16 + cmp r1, r0, lsl #17 + bcc .L_divide_b17 + cmp r1, r0, lsl #18 + bcc .L_divide_b18 + cmp r1, r0, lsl #19 + bcc .L_divide_b19 + cmp r1, r0, lsl #20 + bcc .L_divide_b20 + cmp r1, r0, lsl #21 + bcc .L_divide_b21 + cmp r1, r0, lsl #22 + bcc .L_divide_b22 + cmp r1, r0, lsl #23 + bcc .L_divide_b23 + cmp r1, r0, lsl #24 + bcc .L_divide_b24 + cmp r1, r0, lsl #25 + bcc .L_divide_b25 + cmp r1, r0, lsl #26 + bcc .L_divide_b26 + cmp r1, r0, lsl #27 + bcc .L_divide_b27 + cmp r1, r0, lsl #28 + bcc .L_divide_b28 + cmp r1, r0, lsl #29 + bcc .L_divide_b29 + cmp r1, r0, lsl #30 + bcc .L_divide_b30 +.L_divide_b32: + cmp r1, r0, lsl #31 + subhs r1, r1,r0, lsl #31 + addhs r3, r3,r2, lsl #31 +.L_divide_b31: + cmp r1, r0, lsl #30 + subhs r1, r1,r0, lsl #30 + addhs r3, r3,r2, lsl #30 +.L_divide_b30: + cmp r1, r0, lsl #29 + subhs r1, r1,r0, lsl #29 + addhs r3, r3,r2, lsl #29 +.L_divide_b29: + cmp r1, r0, lsl #28 + subhs r1, r1,r0, lsl #28 + addhs r3, r3,r2, lsl #28 +.L_divide_b28: + cmp r1, r0, lsl #27 + subhs r1, r1,r0, lsl #27 + addhs r3, r3,r2, lsl #27 +.L_divide_b27: + cmp r1, r0, lsl #26 + subhs r1, r1,r0, lsl #26 + addhs r3, r3,r2, lsl #26 +.L_divide_b26: + cmp r1, r0, lsl #25 + subhs r1, r1,r0, lsl #25 + addhs r3, r3,r2, lsl #25 +.L_divide_b25: + cmp r1, r0, lsl #24 + subhs r1, r1,r0, lsl #24 + addhs r3, r3,r2, lsl #24 +.L_divide_b24: + cmp r1, r0, lsl #23 + subhs r1, r1,r0, lsl #23 + addhs r3, r3,r2, lsl #23 +.L_divide_b23: + cmp r1, r0, lsl #22 + subhs r1, r1,r0, lsl #22 + addhs r3, r3,r2, lsl #22 +.L_divide_b22: + cmp r1, r0, lsl #21 + subhs r1, r1,r0, lsl #21 + addhs r3, r3,r2, lsl #21 +.L_divide_b21: + cmp r1, r0, lsl #20 + subhs r1, r1,r0, lsl #20 + addhs r3, r3,r2, lsl #20 +.L_divide_b20: + cmp r1, r0, lsl #19 + subhs r1, r1,r0, lsl #19 + addhs r3, r3,r2, lsl #19 +.L_divide_b19: + cmp r1, r0, lsl #18 + subhs r1, r1,r0, lsl #18 + addhs r3, r3,r2, lsl #18 +.L_divide_b18: + cmp r1, r0, lsl #17 + subhs r1, r1,r0, lsl #17 + addhs r3, r3,r2, lsl #17 +.L_divide_b17: + cmp r1, r0, lsl #16 + subhs r1, r1,r0, lsl #16 + addhs r3, r3,r2, lsl #16 +.L_divide_b16: + cmp r1, r0, lsl #15 + subhs r1, r1,r0, lsl #15 + addhs r3, r3,r2, lsl #15 +.L_divide_b15: + cmp r1, r0, lsl #14 + subhs r1, r1,r0, lsl #14 + addhs r3, r3,r2, lsl #14 +.L_divide_b14: + cmp r1, r0, lsl #13 + subhs r1, r1,r0, lsl #13 + addhs r3, r3,r2, lsl #13 +.L_divide_b13: + cmp r1, r0, lsl #12 + subhs r1, r1,r0, lsl #12 + addhs r3, r3,r2, lsl #12 +.L_divide_b12: + cmp r1, r0, lsl #11 + subhs r1, r1,r0, lsl #11 + addhs r3, r3,r2, lsl #11 +.L_divide_b11: + cmp r1, r0, lsl #10 + subhs r1, r1,r0, lsl #10 + addhs r3, r3,r2, lsl #10 +.L_divide_b10: + cmp r1, r0, lsl #9 + subhs r1, r1,r0, lsl #9 + addhs r3, r3,r2, lsl #9 +.L_divide_b9: + cmp r1, r0, lsl #8 + subhs r1, r1,r0, lsl #8 + addhs r3, r3,r2, lsl #8 +.L_divide_b8: + cmp r1, r0, lsl #7 + subhs r1, r1,r0, lsl #7 + addhs r3, r3,r2, lsl #7 +.L_divide_b7: + cmp r1, r0, lsl #6 + subhs r1, r1,r0, lsl #6 + addhs r3, r3,r2, lsl #6 +.L_divide_b6: + cmp r1, r0, lsl #5 + subhs r1, r1,r0, lsl #5 + addhs r3, r3,r2, lsl #5 +.L_divide_b5: + cmp r1, r0, lsl #4 + subhs r1, r1,r0, lsl #4 + addhs r3, r3,r2, lsl #4 +.L_divide_b4: + cmp r1, r0, lsl #3 + subhs r1, r1,r0, lsl #3 + addhs r3, r3,r2, lsl #3 +.L_divide_b3: + cmp r1, r0, lsl #2 + subhs r1, r1,r0, lsl #2 + addhs r3, r3,r2, lsl #2 +.L_divide_b2: + cmp r1, r0, lsl #1 + subhs r1, r1,r0, lsl #1 + addhs r3, r3,r2, lsl #1 +.L_divide_b1: + cmp r1, r0 + subhs r1, r1, r0 + addhs r3, r3, r2 +.L_divide_b0: + + tst ip, #0x20000000 + bne .L_udivide_l1 + mov r0, r3 + cmp ip, #0 + rsbmi r1, r1, #0 + movs ip, ip, lsl #1 + bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */ + rsbmi r0, r0, #0 + RET + +.L_udivide_l1: + tst ip, #0x10000000 + mov r1, r1, lsl #1 + orrne r1, r1, #1 + mov r3, r3, lsl #1 + cmp r1, r0 + subhs r1, r1, r0 + addhs r3, r3, r2 + mov r0, r3 + RET +END(__divsi3) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/fabs.c b/lib/libc/arm/gen/fabs.c new file mode 100644 index 0000000..c3f4ca3 --- /dev/null +++ b/lib/libc/arm/gen/fabs.c @@ -0,0 +1,46 @@ +/* $NetBSD: fabs.c,v 1.2 2002/05/26 11:48:01 wiz Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe + * + * 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 Mark Brinicombe + * 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 AUTHOR 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 AUTHOR 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. + */ + +/* + * fabs(x) returns the absolute value of x. + */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/fabs.c 129202 2004-05-14 12:04:31Z cognet $"); + +double +fabs(double x) +{ + if (x < 0) + x = -x; + return(x); +} diff --git a/lib/libc/arm/gen/flt_rounds.c b/lib/libc/arm/gen/flt_rounds.c new file mode 100644 index 0000000..6cfe6d8 --- /dev/null +++ b/lib/libc/arm/gen/flt_rounds.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2012 Ian Lepore + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/flt_rounds.c 263631 2014-03-22 12:28:21Z andrew $"); + +#include +#include + +#ifndef __ARM_PCS_VFP +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" +#endif + +int +__flt_rounds(void) +{ + int mode; + +#ifndef __ARM_PCS_VFP + /* + * Translate our rounding modes to the unnamed + * manifest constants required by C99 et. al. + */ + mode = __softfloat_float_rounding_mode; +#else /* __ARM_PCS_VFP */ + /* + * Read the floating-point status and control register + */ + __asm __volatile("vmrs %0, fpscr" : "=&r"(mode)); + mode &= _ROUND_MASK; +#endif /* __ARM_PCS_VFP */ + + switch (mode) { + case FE_TOWARDZERO: + return (0); + case FE_TONEAREST: + return (1); + case FE_UPWARD: + return (2); + case FE_DOWNWARD: + return (3); + } + return (-1); +} diff --git a/lib/libc/arm/gen/fpgetmask_vfp.c b/lib/libc/arm/gen/fpgetmask_vfp.c new file mode 100644 index 0000000..dac665c --- /dev/null +++ b/lib/libc/arm/gen/fpgetmask_vfp.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/fpgetmask_vfp.c 264721 2014-04-21 09:43:22Z andrew $"); + +#include +#include + +#ifdef __weak_alias +__weak_alias(fpgetmask,_fpgetmask) +#endif + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except_t +fpgetmask(void) +{ + fp_except mask; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(mask)); + + return ((mask >> 8) & FP_X_MASK); +} + diff --git a/lib/libc/arm/gen/fpgetround_vfp.c b/lib/libc/arm/gen/fpgetround_vfp.c new file mode 100644 index 0000000..cbc26f8 --- /dev/null +++ b/lib/libc/arm/gen/fpgetround_vfp.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/fpgetround_vfp.c 264721 2014-04-21 09:43:22Z andrew $"); + +#include +#include + +#ifdef __weak_alias +__weak_alias(fpgetround,_fpgetround) +#endif + +fp_rnd_t +fpgetround(void) +{ + uint32_t fpscr; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(fpscr)); + + return ((fpscr >> 22) & 3); +} + diff --git a/lib/libc/arm/gen/fpgetsticky_vfp.c b/lib/libc/arm/gen/fpgetsticky_vfp.c new file mode 100644 index 0000000..c80edd4 --- /dev/null +++ b/lib/libc/arm/gen/fpgetsticky_vfp.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/fpgetsticky_vfp.c 264721 2014-04-21 09:43:22Z andrew $"); + +#include +#include + +#ifdef __weak_alias +__weak_alias(fpgetsticky,_fpgetsticky) +#endif + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except +fpgetsticky(void) +{ + fp_except old; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(old)); + + return (old & FP_X_MASK); +} + diff --git a/lib/libc/arm/gen/fpsetmask_vfp.c b/lib/libc/arm/gen/fpsetmask_vfp.c new file mode 100644 index 0000000..091e53f --- /dev/null +++ b/lib/libc/arm/gen/fpsetmask_vfp.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/fpsetmask_vfp.c 265059 2014-04-28 18:54:12Z andrew $"); + +#include +#include + +#ifdef __weak_alias +__weak_alias(fpsetmask,_fpsetmask) +#endif + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except_t +fpsetmask(fp_except_t mask) +{ + fp_except old, new; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(old)); + mask = (mask & FP_X_MASK) << 8; + new = (old & ~(FP_X_MASK << 8)) | mask; + __asm __volatile("vmsr fpscr, %0" : : "r"(new)); + + return ((old >> 8) & FP_X_MASK); +} + diff --git a/lib/libc/arm/gen/fpsetround_vfp.c b/lib/libc/arm/gen/fpsetround_vfp.c new file mode 100644 index 0000000..089a1ca --- /dev/null +++ b/lib/libc/arm/gen/fpsetround_vfp.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2014 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/fpsetround_vfp.c 264721 2014-04-21 09:43:22Z andrew $"); + +#include +#include + +#ifdef __weak_alias +__weak_alias(fpsetround,_fpsetround) +#endif + +fp_rnd_t +fpsetround(fp_rnd_t rnd_dir) +{ + uint32_t old, new; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(old)); + new = old & ~(3 << 22); + new |= rnd_dir << 22; + __asm __volatile("vmsr fpscr, %0" : : "r"(new)); + + return ((old >> 22) & 3); +} + diff --git a/lib/libc/arm/gen/fpsetsticky_vfp.c b/lib/libc/arm/gen/fpsetsticky_vfp.c new file mode 100644 index 0000000..c92037e --- /dev/null +++ b/lib/libc/arm/gen/fpsetsticky_vfp.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 Andrew Turner + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/fpsetsticky_vfp.c 264721 2014-04-21 09:43:22Z andrew $"); + +#include +#include + +#ifdef __weak_alias +__weak_alias(fpsetsticky,_fpsetsticky) +#endif + +#define FP_X_MASK (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +fp_except +fpsetsticky(fp_except except) +{ + fp_except old, new; + + __asm __volatile("vmrs %0, fpscr" : "=&r"(old)); + new = old & ~(FP_X_MASK); + new &= ~except; + __asm __volatile("vmsr fpscr, %0" : : "r"(new)); + + return (old & except); +} + diff --git a/lib/libc/arm/gen/infinity.c b/lib/libc/arm/gen/infinity.c new file mode 100644 index 0000000..5916c6d --- /dev/null +++ b/lib/libc/arm/gen/infinity.c @@ -0,0 +1,26 @@ +/* + * infinity.c + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/infinity.c 129202 2004-05-14 12:04:31Z cognet $"); + +#include + +/* bytes for +Infinity on a 387 */ +const union __infinity_un __infinity = { +#if BYTE_ORDER == BIG_ENDIAN + { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } +#else + { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } +#endif +}; + +/* bytes for NaN */ +const union __nan_un __nan = { +#if BYTE_ORDER == BIG_ENDIAN + {0xff, 0xc0, 0, 0} +#else + { 0, 0, 0xc0, 0xff } +#endif +}; diff --git a/lib/libc/arm/gen/makecontext.c b/lib/libc/arm/gen/makecontext.c new file mode 100644 index 0000000..8575698 --- /dev/null +++ b/lib/libc/arm/gen/makecontext.c @@ -0,0 +1,89 @@ +/* $NetBSD: makecontext.c,v 1.2 2003/01/18 11:06:24 thorpej Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Klaus Klein. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/makecontext.c 204607 2010-03-02 22:16:40Z joel $"); + +#include +#include +#include +#include + +#include + +extern void _ctx_start(void); + +void +ctx_done(ucontext_t *ucp) +{ + + if (ucp->uc_link == NULL) + exit(0); + else { + setcontext((const ucontext_t *)ucp->uc_link); + abort(); + } +} + +__weak_reference(__makecontext, makecontext); + +void +__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) +{ + __greg_t *gr = ucp->uc_mcontext.__gregs; + int i; + unsigned int *sp; + va_list ap; + + /* Compute and align stack pointer. */ + sp = (unsigned int *) + (((uintptr_t)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size - + sizeof(double)) & ~7); + /* Allocate necessary stack space for arguments exceeding r0-3. */ + if (argc > 4) + sp -= argc - 4; + gr[_REG_SP] = (__greg_t)sp; + /* Wipe out frame pointer. */ + gr[_REG_FP] = 0; + /* Arrange for return via the trampoline code. */ + gr[_REG_PC] = (__greg_t)_ctx_start; + gr[_REG_R4] = (__greg_t)func; + gr[_REG_R5] = (__greg_t)ucp; + + va_start(ap, argc); + /* Pass up to four arguments in r0-3. */ + for (i = 0; i < argc && i < 4; i++) + gr[_REG_R0 + i] = va_arg(ap, int); + /* Pass any additional arguments on the stack. */ + for (argc -= i; argc > 0; argc--) + *sp++ = va_arg(ap, int); + va_end(ap); +} diff --git a/lib/libc/arm/gen/setjmp.S b/lib/libc/arm/gen/setjmp.S new file mode 100644 index 0000000..9e0f475 --- /dev/null +++ b/lib/libc/arm/gen/setjmp.S @@ -0,0 +1,162 @@ +/* $NetBSD: setjmp.S,v 1.14 2013/04/19 13:45:45 matt Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * 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 Mark Brinicombe + * 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 AUTHOR 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 AUTHOR 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. + */ + +#if !defined(__SOFTFP__) && !defined(__VFP_FP__) && !defined(__ARM_PCS) +#error FPA is not supported anymore +#endif + + .fpu vfp + +#include +#include + +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/setjmp.S 288373 2015-09-29 16:09:58Z kib $"); + +/* + * C library -- setjmp, longjmp + * + * longjmp(a,v) + * will generate a "return(v)" from the last call to + * setjmp(a) + * by restoring registers from the stack. + * The previous signal state is restored. + */ + +ENTRY(setjmp) + /* Block all signals and retrieve the old signal mask */ + stmfd sp!, {r0, r14} + add r2, r0, #(_JB_SIGMASK * 4) /* oset */ + mov r1, #0x00000000 /* set */ + mov r0, #0x00000001 /* SIG_BLOCK */ + bl PIC_SYM(_C_LABEL(sigprocmask), PLT) + ldmfd sp!, {r0, r14} + + ldr r1, .Lsetjmp_magic + + ldr r2, .Lfpu_present +#ifdef PIC + GOT_INIT(r3, .Lsetjmp_got, .Lsetjmp_gotinit) + ldr r2, [r2, r3] +#else + ldr r2, [r2] +#endif + teq r2, #0 /* do we have a FPU? */ + beq 1f /* no, don't save VFP registers */ + + orr r1, r1, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP) + /* change magic to VFP magic */ + add r2, r0, #(_JB_REG_D8 * 4) + vstmia r2, {d8-d15} + vmrs r2, fpscr + str r2, [r0, #(_JB_REG_FPSCR * 4)] +1: + + str r1, [r0] /* store magic */ + + /* Store integer registers */ + add r0, r0, #(_JB_REG_R4 * 4) +#ifndef __thumb__ + stmia r0, {r4-r14} +#else + stmia r0, {r4-r12} + str r13, [r0, #((_JB_REG_R13 - _JB_REG_R4) * 4)] + str r14, [r0, #((_JB_REG_R14 - _JB_REG_R4) * 4)] +#endif + mov r0, #0x00000000 + RET + +.Lsetjmp_magic: + .word _JB_MAGIC_SETJMP + GOT_INITSYM(.Lsetjmp_got, .Lsetjmp_gotinit) +.Lfpu_present: + .word PIC_SYM(_libc_arm_fpu_present, GOTOFF) +END(setjmp) + +.weak _C_LABEL(longjmp) +.set _C_LABEL(longjmp), _C_LABEL(__longjmp) +ENTRY(__longjmp) + ldr r2, [r0] + ldr ip, .Lsetjmp_magic + bic r3, r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP) + teq r3, ip + bne .Lbotch + + /* Restore the signal mask. */ + stmfd sp!, {r0-r2, r14} + mov r2, #0x00000000 + add r1, r0, #(_JB_SIGMASK * 4) /* Signal mask */ + mov r0, #3 /* SIG_SETMASK */ + bl PIC_SYM(_C_LABEL(sigprocmask), PLT) + ldmfd sp!, {r0-r2, r14} + + tst r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP) + /* is this a VFP magic? */ + beq 1f /* no, don't restore VFP */ + add ip, r0, #(_JB_REG_D8 * 4) + vldmia ip, {d8-d15} + ldr ip, [r0, #(_JB_REG_FPSCR * 4)] + vmsr fpscr, ip +1: + + add r0, r0, #(_JB_REG_R4 * 4) + /* Restore integer registers */ +#ifndef __thumb__ + ldmia r0, {r4-r14} +#else + ldmia r0, {r4-r12} + ldr r13, [r0, #((_JB_REG_R13 - _JB_REG_R4) * 4)] + ldr r14, [r0, #((_JB_REG_R14 - _JB_REG_R4) * 4)] +#endif + + /* Validate sp and r14 */ + teq sp, #0 + it ne + teqne r14, #0 + it eq + beq .Lbotch + + /* Set return value */ + movs r0, r1 + it eq + moveq r0, #0x00000001 + RET + + /* validation failed, die die die. */ +.Lbotch: + bl PIC_SYM(_C_LABEL(longjmperror), PLT) + bl PIC_SYM(_C_LABEL(abort), PLT) +1: b 1b /* Cannot get here */ +END(__longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/gen/signalcontext.c b/lib/libc/arm/gen/signalcontext.c new file mode 100644 index 0000000..6a598cd --- /dev/null +++ b/lib/libc/arm/gen/signalcontext.c @@ -0,0 +1,78 @@ +/*- + * Copyright (c) 2004 Olivier Houchard + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/signalcontext.c 137286 2004-11-05 23:53:02Z cognet $"); + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +__weak_reference(__signalcontext, signalcontext); + +extern void _ctx_start(void); + +int +__signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func) +{ + struct sigframe *sfp; + __greg_t *gr = ucp->uc_mcontext.__gregs; + unsigned int *sp; + + sp = (unsigned int *)gr[_REG_SP]; + + sfp = (struct sigframe *)sp - 1; + + bzero(sfp, sizeof(*sfp)); + bcopy(ucp, &sfp->sf_uc, sizeof(*ucp)); + sfp->sf_si.si_signo = sig; + + gr[_REG_SP] = (__greg_t)sfp; + /* Wipe out frame pointer. */ + gr[_REG_FP] = 0; + /* Arrange for return via the trampoline code. */ + gr[_REG_PC] = (__greg_t)_ctx_start; + gr[_REG_R4] = (__greg_t)func; + gr[_REG_R5] = (__greg_t)ucp; + gr[_REG_R0] = (__greg_t)sig; + gr[_REG_R1] = (__greg_t)&sfp->sf_si; + gr[_REG_R2] = (__greg_t)&sfp->sf_uc; + + ucp->uc_link = &sfp->sf_uc; + sigdelset(&ucp->uc_sigmask, sig); + + return (0); +} diff --git a/lib/libc/arm/gen/sigsetjmp.S b/lib/libc/arm/gen/sigsetjmp.S new file mode 100644 index 0000000..02eee03 --- /dev/null +++ b/lib/libc/arm/gen/sigsetjmp.S @@ -0,0 +1,70 @@ +/* $NetBSD: sigsetjmp.S,v 1.6 2013/04/19 16:50:22 matt Exp $ */ + +/* + * Copyright (c) 1997 Mark Brinicombe + * 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 Mark Brinicombe + * 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 AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/gen/sigsetjmp.S 288373 2015-09-29 16:09:58Z kib $"); + +#include + +/* + * C library -- sigsetjmp, siglongjmp + * + * longjmp(a,v) + * will generate a "return(v)" from the last call to + * setjmp(a, m) + * by restoring registers from the stack. + * The previous signal state is restored. + */ + +ENTRY(sigsetjmp) + teq r1, #0 + beq PIC_SYM(_C_LABEL(_setjmp), PLT) + b PIC_SYM(_C_LABEL(setjmp), PLT) +END(sigsetjmp) + +.L_setjmp_magic: + .word _JB_MAGIC__SETJMP +WEAK_ALIAS(__siglongjmp, siglongjmp) + +ENTRY(siglongjmp) + ldr r2, .L_setjmp_magic /* load magic */ + ldr r3, [r0] /* get magic from jmp_buf */ + bic r3, r3, #(_JB_MAGIC__SETJMP ^ _JB_MAGIC__SETJMP_VFP) + /* ignore VFP-ness of magic */ + teq r2, r3 /* magic correct? */ + beq PIC_SYM(_C_LABEL(_longjmp), PLT) + b PIC_SYM(_C_LABEL(longjmp), PLT) +END(siglongjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/softfloat/arm-gcc.h b/lib/libc/arm/softfloat/arm-gcc.h new file mode 100644 index 0000000..c165135 --- /dev/null +++ b/lib/libc/arm/softfloat/arm-gcc.h @@ -0,0 +1,101 @@ +/* $NetBSD: arm-gcc.h,v 1.2 2001/02/21 18:09:25 bjh21 Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/arm/softfloat/arm-gcc.h 255361 2013-09-07 14:04:10Z andrew $ */ + +/* +------------------------------------------------------------------------------- +One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined. +------------------------------------------------------------------------------- +*/ +#ifdef __ARMEB__ +#define BIGENDIAN +#else +#define LITTLEENDIAN +#endif + +/* +------------------------------------------------------------------------------- +The macro `BITS64' can be defined to indicate that 64-bit integer types are +supported by the compiler. +------------------------------------------------------------------------------- +*/ +#define BITS64 + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines the most convenient type that holds +integers of at least as many bits as specified. For example, `uint8' should +be the most convenient type that can hold unsigned integers of as many as +8 bits. The `flag' type must be able to hold either a 0 or 1. For most +implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed +to the same as `int'. +------------------------------------------------------------------------------- +*/ +typedef int flag; +typedef int uint8; +typedef int int8; +typedef int uint16; +typedef int int16; +typedef unsigned int uint32; +typedef signed int int32; +#ifdef BITS64 +typedef unsigned long long int uint64; +typedef signed long long int int64; +#endif + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines a type that holds integers +of _exactly_ the number of bits specified. For instance, for most +implementation of C, `bits16' and `sbits16' should be `typedef'ed to +`unsigned short int' and `signed short int' (or `short int'), respectively. +------------------------------------------------------------------------------- +*/ +typedef unsigned char bits8; +typedef signed char sbits8; +typedef unsigned short int bits16; +typedef signed short int sbits16; +typedef unsigned int bits32; +typedef signed int sbits32; +#ifdef BITS64 +typedef unsigned long long int bits64; +typedef signed long long int sbits64; +#endif + +#ifdef BITS64 +/* +------------------------------------------------------------------------------- +The `LIT64' macro takes as its argument a textual integer literal and +if necessary ``marks'' the literal as having a 64-bit integer type. +For example, the GNU C Compiler (`gcc') requires that 64-bit literals be +appended with the letters `LL' standing for `long long', which is `gcc's +name for the 64-bit integer type. Some compilers may allow `LIT64' to be +defined as the identity macro: `#define LIT64( a ) a'. +------------------------------------------------------------------------------- +*/ +#define LIT64( a ) a##LL +#endif + +/* +------------------------------------------------------------------------------- +The macro `INLINE' can be used before functions that should be inlined. If +a compiler does not support explicit inlining, this macro should be defined +to be `static'. +------------------------------------------------------------------------------- +*/ +#define INLINE static __inline + +/* +------------------------------------------------------------------------------- +The ARM FPA is odd in that it stores doubles high-order word first, no matter +what the endianness of the CPU. VFP is sane. +------------------------------------------------------------------------------- +*/ +#if defined(SOFTFLOAT_FOR_GCC) +#if defined (__ARM_EABI__) || defined(__VFP_FP__) || defined(__ARMEB__) +#define FLOAT64_DEMANGLE(a) (a) +#define FLOAT64_MANGLE(a) (a) +#else +#define FLOAT64_DEMANGLE(a) ((((a) & 0xfffffffful) << 32) | ((a) >> 32)) +#define FLOAT64_MANGLE(a) FLOAT64_DEMANGLE(a) +#endif +#endif diff --git a/lib/libc/arm/softfloat/milieu.h b/lib/libc/arm/softfloat/milieu.h new file mode 100644 index 0000000..8349fc8 --- /dev/null +++ b/lib/libc/arm/softfloat/milieu.h @@ -0,0 +1,49 @@ +/* $NetBSD: milieu.h,v 1.1 2000/12/29 20:13:54 bjh21 Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/arm/softfloat/milieu.h 129202 2004-05-14 12:04:31Z cognet $ */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Include common integer types and flags. +------------------------------------------------------------------------------- +*/ +#include "arm-gcc.h" + +/* +------------------------------------------------------------------------------- +Symbolic Boolean literals. +------------------------------------------------------------------------------- +*/ +enum { + FALSE = 0, + TRUE = 1 +}; diff --git a/lib/libc/arm/softfloat/softfloat.h b/lib/libc/arm/softfloat/softfloat.h new file mode 100644 index 0000000..ae80513 --- /dev/null +++ b/lib/libc/arm/softfloat/softfloat.h @@ -0,0 +1,315 @@ +/* $NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/arm/softfloat/softfloat.h 230189 2012-01-16 04:05:53Z das $ */ + +/* This is a derivative work. */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +The macro `FLOATX80' must be defined to enable the extended double-precision +floating-point format `floatx80'. If this macro is not defined, the +`floatx80' type will not be defined, and none of the functions that either +input or output the `floatx80' type will be defined. The same applies to +the `FLOAT128' macro and the quadruple-precision format `float128'. +------------------------------------------------------------------------------- +*/ +/* #define FLOATX80 */ +/* #define FLOAT128 */ + +#include + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point types. +------------------------------------------------------------------------------- +*/ +typedef unsigned int float32; +typedef unsigned long long float64; +#ifdef FLOATX80 +typedef struct { + unsigned short high; + unsigned long long low; +} floatx80; +#endif +#ifdef FLOAT128 +typedef struct { + unsigned long long high, low; +} float128; +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point underflow tininess-detection mode. +------------------------------------------------------------------------------- +*/ +#ifndef SOFTFLOAT_FOR_GCC +extern int float_detect_tininess; +#endif +enum { + float_tininess_after_rounding = 0, + float_tininess_before_rounding = 1 +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point rounding mode. +------------------------------------------------------------------------------- +*/ +extern int float_rounding_mode; +enum { + float_round_nearest_even = FE_TONEAREST, + float_round_to_zero = FE_TOWARDZERO, + float_round_down = FE_DOWNWARD, + float_round_up = FE_UPWARD +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point exception flags. +------------------------------------------------------------------------------- +*/ +extern int float_exception_flags; +extern int float_exception_mask; +enum { + float_flag_inexact = FE_INEXACT, + float_flag_underflow = FE_UNDERFLOW, + float_flag_overflow = FE_OVERFLOW, + float_flag_divbyzero = FE_DIVBYZERO, + float_flag_invalid = FE_INVALID +}; + +/* +------------------------------------------------------------------------------- +Routine to raise any or all of the software IEC/IEEE floating-point +exception flags. +------------------------------------------------------------------------------- +*/ +void float_raise( int ); + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE integer-to-floating-point conversion routines. +------------------------------------------------------------------------------- +*/ +float32 int32_to_float32( int ); +float64 int32_to_float64( int ); +#ifdef FLOATX80 +floatx80 int32_to_floatx80( int ); +#endif +#ifdef FLOAT128 +float128 int32_to_float128( int ); +#endif +#ifndef SOFTFLOAT_FOR_GCC /* __floatdi?f is in libgcc2.c */ +float32 int64_to_float32( long long ); +float64 int64_to_float64( long long ); +#ifdef FLOATX80 +floatx80 int64_to_floatx80( long long ); +#endif +#ifdef FLOAT128 +float128 int64_to_float128( long long ); +#endif +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float32_to_int32( float32 ); +int float32_to_int32_round_to_zero( float32 ); +#if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS) +unsigned int float32_to_uint32_round_to_zero( float32 ); +#endif +#ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */ +long long float32_to_int64( float32 ); +long long float32_to_int64_round_to_zero( float32 ); +#endif +float64 float32_to_float64( float32 ); +#ifdef FLOATX80 +floatx80 float32_to_floatx80( float32 ); +#endif +#ifdef FLOAT128 +float128 float32_to_float128( float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision operations. +------------------------------------------------------------------------------- +*/ +float32 float32_round_to_int( float32 ); +float32 float32_add( float32, float32 ); +float32 float32_sub( float32, float32 ); +float32 float32_mul( float32, float32 ); +float32 float32_div( float32, float32 ); +float32 float32_rem( float32, float32 ); +float32 float32_sqrt( float32 ); +int float32_eq( float32, float32 ); +int float32_le( float32, float32 ); +int float32_lt( float32, float32 ); +int float32_eq_signaling( float32, float32 ); +int float32_le_quiet( float32, float32 ); +int float32_lt_quiet( float32, float32 ); +#ifndef SOFTFLOAT_FOR_GCC +int float32_is_signaling_nan( float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float64_to_int32( float64 ); +int float64_to_int32_round_to_zero( float64 ); +#if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS) +unsigned int float64_to_uint32_round_to_zero( float64 ); +#endif +#ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */ +long long float64_to_int64( float64 ); +long long float64_to_int64_round_to_zero( float64 ); +#endif +float32 float64_to_float32( float64 ); +#ifdef FLOATX80 +floatx80 float64_to_floatx80( float64 ); +#endif +#ifdef FLOAT128 +float128 float64_to_float128( float64 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision operations. +------------------------------------------------------------------------------- +*/ +float64 float64_round_to_int( float64 ); +float64 float64_add( float64, float64 ); +float64 float64_sub( float64, float64 ); +float64 float64_mul( float64, float64 ); +float64 float64_div( float64, float64 ); +float64 float64_rem( float64, float64 ); +float64 float64_sqrt( float64 ); +int float64_eq( float64, float64 ); +int float64_le( float64, float64 ); +int float64_lt( float64, float64 ); +int float64_eq_signaling( float64, float64 ); +int float64_le_quiet( float64, float64 ); +int float64_lt_quiet( float64, float64 ); +#ifndef SOFTFLOAT_FOR_GCC +int float64_is_signaling_nan( float64 ); +#endif + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int floatx80_to_int32( floatx80 ); +int floatx80_to_int32_round_to_zero( floatx80 ); +long long floatx80_to_int64( floatx80 ); +long long floatx80_to_int64_round_to_zero( floatx80 ); +float32 floatx80_to_float32( floatx80 ); +float64 floatx80_to_float64( floatx80 ); +#ifdef FLOAT128 +float128 floatx80_to_float128( floatx80 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision rounding precision. Valid +values are 32, 64, and 80. +------------------------------------------------------------------------------- +*/ +extern int floatx80_rounding_precision; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision operations. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_round_to_int( floatx80 ); +floatx80 floatx80_add( floatx80, floatx80 ); +floatx80 floatx80_sub( floatx80, floatx80 ); +floatx80 floatx80_mul( floatx80, floatx80 ); +floatx80 floatx80_div( floatx80, floatx80 ); +floatx80 floatx80_rem( floatx80, floatx80 ); +floatx80 floatx80_sqrt( floatx80 ); +int floatx80_eq( floatx80, floatx80 ); +int floatx80_le( floatx80, floatx80 ); +int floatx80_lt( floatx80, floatx80 ); +int floatx80_eq_signaling( floatx80, floatx80 ); +int floatx80_le_quiet( floatx80, floatx80 ); +int floatx80_lt_quiet( floatx80, floatx80 ); +int floatx80_is_signaling_nan( floatx80 ); + +#endif + +#ifdef FLOAT128 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE quadruple-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float128_to_int32( float128 ); +int float128_to_int32_round_to_zero( float128 ); +long long float128_to_int64( float128 ); +long long float128_to_int64_round_to_zero( float128 ); +float32 float128_to_float32( float128 ); +float64 float128_to_float64( float128 ); +#ifdef FLOATX80 +floatx80 float128_to_floatx80( float128 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE quadruple-precision operations. +------------------------------------------------------------------------------- +*/ +float128 float128_round_to_int( float128 ); +float128 float128_add( float128, float128 ); +float128 float128_sub( float128, float128 ); +float128 float128_mul( float128, float128 ); +float128 float128_div( float128, float128 ); +float128 float128_rem( float128, float128 ); +float128 float128_sqrt( float128 ); +int float128_eq( float128, float128 ); +int float128_le( float128, float128 ); +int float128_lt( float128, float128 ); +int float128_eq_signaling( float128, float128 ); +int float128_le_quiet( float128, float128 ); +int float128_lt_quiet( float128, float128 ); +int float128_is_signaling_nan( float128 ); + +#endif + diff --git a/lib/libc/arm/string/Makefile.inc b/lib/libc/arm/string/Makefile.inc new file mode 100644 index 0000000..3410ebe --- /dev/null +++ b/lib/libc/arm/string/Makefile.inc @@ -0,0 +1,13 @@ +# $FreeBSD: releng/11.1/lib/libc/arm/string/Makefile.inc 315044 2017-03-11 02:51:29Z brooks $ + +MDSRCS+= \ + bcopy.S \ + bzero.S \ + ffs.S \ + memcmp.S \ + memcpy.S \ + memmove.S \ + memset.S \ + strcmp.S \ + strlen.S \ + strncmp.S diff --git a/lib/libc/arm/string/bcopy.S b/lib/libc/arm/string/bcopy.S new file mode 100644 index 0000000..7196d57 --- /dev/null +++ b/lib/libc/arm/string/bcopy.S @@ -0,0 +1,6 @@ +/* $NetBSD: bcopy.S,v 1.3 2003/10/14 07:51:45 scw Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/string/bcopy.S 129202 2004-05-14 12:04:31Z cognet $"); +#define _BCOPY +#include "memmove.S" diff --git a/lib/libc/arm/string/bzero.S b/lib/libc/arm/string/bzero.S new file mode 100644 index 0000000..e0519fb --- /dev/null +++ b/lib/libc/arm/string/bzero.S @@ -0,0 +1,37 @@ +/* $NetBSD: bzero.S,v 1.3 2003/10/14 07:51:45 scw Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/string/bzero.S 204607 2010-03-02 22:16:40Z joel $"); + +#define _BZERO +#include "memset.S" diff --git a/lib/libc/arm/string/ffs.S b/lib/libc/arm/string/ffs.S new file mode 100644 index 0000000..e5fb8c4 --- /dev/null +++ b/lib/libc/arm/string/ffs.S @@ -0,0 +1,88 @@ +/* $NetBSD: ffs.S,v 1.5 2003/04/05 23:08:52 bjh21 Exp $ */ +/* + * Copyright (c) 2001 Christopher Gilbert + * 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. The name of the company nor the name of the author may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 + +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/string/ffs.S 288373 2015-09-29 16:09:58Z kib $"); + +.syntax unified + +/* + * ffs - find first set bit, this algorithm isolates the first set + * bit, then multiplies the number by 0x0450fbaf which leaves the top + * 6 bits as an index into the table. This algorithm should be a win + * over the checking each bit in turn as per the C compiled version. + * + * under ARMv5 there's an instruction called CLZ (count leading Zero's) that + * could be used + * + * This is the ffs algorithm devised by d.seal and posted to comp.sys.arm on + * 16 Feb 1994. + */ + +ENTRY(ffs) + /* Standard trick to isolate bottom bit in r0 or 0 if r0 = 0 on entry */ + rsb r1, r0, #0 + ands r0, r0, r1 +#ifndef _ARM_ARCH_5 + /* + * now r0 has at most one set bit, call this X + * if X = 0, all further instructions are skipped + */ + adrne r2, .L_ffs_table + orrne r0, r0, r0, lsl #4 /* r0 = X * 0x11 */ + orrne r0, r0, r0, lsl #6 /* r0 = X * 0x451 */ + rsbne r0, r0, r0, lsl #16 /* r0 = X * 0x0450fbaf */ + + /* now lookup in table indexed on top 6 bits of r0 */ + ldrbne r0, [ r2, r0, lsr #26 ] + + RET +.text; +.type .L_ffs_table, _ASM_TYPE_OBJECT; +.L_ffs_table: +/* 0 1 2 3 4 5 6 7 */ + .byte 0, 1, 2, 13, 3, 7, 0, 14 /* 0- 7 */ + .byte 4, 0, 8, 0, 0, 0, 0, 15 /* 8-15 */ + .byte 11, 5, 0, 0, 9, 0, 0, 26 /* 16-23 */ + .byte 0, 0, 0, 0, 0, 22, 28, 16 /* 24-31 */ + .byte 32, 12, 6, 0, 0, 0, 0, 0 /* 32-39 */ + .byte 10, 0, 0, 25, 0, 0, 21, 27 /* 40-47 */ + .byte 31, 0, 0, 0, 0, 24, 0, 20 /* 48-55 */ + .byte 30, 0, 23, 19, 29, 18, 17, 0 /* 56-63 */ +#else + itt ne + clzne r0, r0 + rsbne r0, r0, #32 + RET +#endif +END(ffs) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/memcmp.S b/lib/libc/arm/string/memcmp.S new file mode 100644 index 0000000..62a37ae --- /dev/null +++ b/lib/libc/arm/string/memcmp.S @@ -0,0 +1,185 @@ +/* $NetBSD: memcmp.S,v 1.3 2003/10/14 07:51:45 scw Exp $ */ + +/* + * Copyright 2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Steve C. Woodford for Wasabi Systems, Inc. + * + * 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 for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC + * 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. + */ +/* + * Copyright (c) 2002 ARM Ltd + * 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. The name of the company may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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 + +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/string/memcmp.S 288373 2015-09-29 16:09:58Z kib $"); + +.syntax unified + +ENTRY(memcmp) + mov ip, r0 +#if defined(_KERNEL) && !defined(_STANDALONE) + cmp r2, #0x06 + beq .Lmemcmp_6bytes +#endif + mov r0, #0x00 + + /* Are both addresses aligned the same way? */ + cmp r2, #0x00 + eorsne r3, ip, r1 + RETeq /* len == 0, or same addresses! */ + tst r3, #0x03 + subne r2, r2, #0x01 + bne .Lmemcmp_bytewise2 /* Badly aligned. Do it the slow way */ + + /* Word-align the addresses, if necessary */ + sub r3, r1, #0x05 + ands r3, r3, #0x03 + add r3, r3, r3, lsl #1 + addne pc, pc, r3, lsl #3 + nop + + /* Compare up to 3 bytes */ + ldrb r0, [ip], #0x01 + ldrb r3, [r1], #0x01 + subs r0, r0, r3 + RETne + subs r2, r2, #0x01 + RETeq + + /* Compare up to 2 bytes */ + ldrb r0, [ip], #0x01 + ldrb r3, [r1], #0x01 + subs r0, r0, r3 + RETne + subs r2, r2, #0x01 + RETeq + + /* Compare 1 byte */ + ldrb r0, [ip], #0x01 + ldrb r3, [r1], #0x01 + subs r0, r0, r3 + RETne + subs r2, r2, #0x01 + RETeq + + /* Compare 4 bytes at a time, if possible */ + subs r2, r2, #0x04 + bcc .Lmemcmp_bytewise +.Lmemcmp_word_aligned: + ldr r0, [ip], #0x04 + ldr r3, [r1], #0x04 + subs r2, r2, #0x04 + cmpcs r0, r3 + beq .Lmemcmp_word_aligned + sub r0, r0, r3 + + /* Correct for extra subtraction, and check if done */ + adds r2, r2, #0x04 + cmpeq r0, #0x00 /* If done, did all bytes match? */ + RETeq /* Yup. Just return */ + + /* Re-do the final word byte-wise */ + sub ip, ip, #0x04 + sub r1, r1, #0x04 + +.Lmemcmp_bytewise: + add r2, r2, #0x03 +.Lmemcmp_bytewise2: + ldrb r0, [ip], #0x01 + ldrb r3, [r1], #0x01 + subs r2, r2, #0x01 + cmpcs r0, r3 + beq .Lmemcmp_bytewise2 + sub r0, r0, r3 + RET + +#if defined(_KERNEL) && !defined(_STANDALONE) + /* + * 6 byte compares are very common, thanks to the network stack. + * This code is hand-scheduled to reduce the number of stalls for + * load results. Everything else being equal, this will be ~32% + * faster than a byte-wise memcmp. + */ + .align 5 +.Lmemcmp_6bytes: + ldrb r3, [r1, #0x00] /* r3 = b2#0 */ + ldrb r0, [ip, #0x00] /* r0 = b1#0 */ + ldrb r2, [r1, #0x01] /* r2 = b2#1 */ + subs r0, r0, r3 /* r0 = b1#0 - b2#0 */ + ldreqb r3, [ip, #0x01] /* r3 = b1#1 */ + RETne /* Return if mismatch on #0 */ + subs r0, r3, r2 /* r0 = b1#1 - b2#1 */ + ldreqb r3, [r1, #0x02] /* r3 = b2#2 */ + ldreqb r0, [ip, #0x02] /* r0 = b1#2 */ + RETne /* Return if mismatch on #1 */ + ldrb r2, [r1, #0x03] /* r2 = b2#3 */ + subs r0, r0, r3 /* r0 = b1#2 - b2#2 */ + ldreqb r3, [ip, #0x03] /* r3 = b1#3 */ + RETne /* Return if mismatch on #2 */ + subs r0, r3, r2 /* r0 = b1#3 - b2#3 */ + ldreqb r3, [r1, #0x04] /* r3 = b2#4 */ + ldreqb r0, [ip, #0x04] /* r0 = b1#4 */ + RETne /* Return if mismatch on #3 */ + ldrb r2, [r1, #0x05] /* r2 = b2#5 */ + subs r0, r0, r3 /* r0 = b1#4 - b2#4 */ + ldreqb r3, [ip, #0x05] /* r3 = b1#5 */ + RETne /* Return if mismatch on #4 */ + sub r0, r3, r2 /* r0 = b1#5 - b2#5 */ + RET +#endif +END(memcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/memcpy.S b/lib/libc/arm/string/memcpy.S new file mode 100644 index 0000000..d3a6f0f --- /dev/null +++ b/lib/libc/arm/string/memcpy.S @@ -0,0 +1,9 @@ +/* $NetBSD: memcpy.S,v 1.4 2003/10/14 07:51:45 scw Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/string/memcpy.S 172616 2007-10-13 12:06:31Z cognet $"); +#if !defined(_ARM_ARCH_5E) || defined(_STANDALONE) +#include "memcpy_arm.S" +#else +#include "memcpy_xscale.S" +#endif diff --git a/lib/libc/arm/string/memcpy_arm.S b/lib/libc/arm/string/memcpy_arm.S new file mode 100644 index 0000000..066e486 --- /dev/null +++ b/lib/libc/arm/string/memcpy_arm.S @@ -0,0 +1,338 @@ +/* $NetBSD: memcpy_arm.S,v 1.1 2003/10/14 07:51:45 scw Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/string/memcpy_arm.S 288373 2015-09-29 16:09:58Z kib $"); + +.syntax unified + +/* + * This is one fun bit of code ... + * Some easy listening music is suggested while trying to understand this + * code e.g. Iron Maiden + * + * For anyone attempting to understand it : + * + * The core code is implemented here with simple stubs for memcpy(). + * + * All local labels are prefixed with Lmemcpy_ + * Following the prefix a label starting f is used in the forward copy code + * while a label using b is used in the backwards copy code + * The source and destination addresses determine whether a forward or + * backward copy is performed. + * Separate bits of code are used to deal with the following situations + * for both the forward and backwards copy. + * unaligned source address + * unaligned destination address + * Separate copy routines are used to produce an optimised result for each + * of these cases. + * The copy code will use LDM/STM instructions to copy up to 32 bytes at + * a time where possible. + * + * Note: r12 (aka ip) can be trashed during the function along with + * r0-r3 although r0-r2 have defined uses i.e. src, dest, len through out. + * Additional registers are preserved prior to use i.e. r4, r5 & lr + * + * Apologies for the state of the comments ;-) + */ +/* LINTSTUB: Func: void *memcpy(void *dst, const void *src, size_t len) */ +ENTRY(memcpy) + /* save leaf functions having to store this away */ + stmdb sp!, {r0, lr} /* memcpy() returns dest addr */ + + subs r2, r2, #4 + blt .Lmemcpy_l4 /* less than 4 bytes */ + ands r12, r0, #3 + bne .Lmemcpy_destul /* oh unaligned destination addr */ + ands r12, r1, #3 + bne .Lmemcpy_srcul /* oh unaligned source addr */ + +.Lmemcpy_t8: + /* We have aligned source and destination */ + subs r2, r2, #8 + blt .Lmemcpy_l12 /* less than 12 bytes (4 from above) */ + subs r2, r2, #0x14 + blt .Lmemcpy_l32 /* less than 32 bytes (12 from above) */ + stmdb sp!, {r4} /* borrow r4 */ + + /* blat 32 bytes at a time */ + /* XXX for really big copies perhaps we should use more registers */ +.Lmemcpy_loop32: + ldmia r1!, {r3, r4, r12, lr} + stmia r0!, {r3, r4, r12, lr} + ldmia r1!, {r3, r4, r12, lr} + stmia r0!, {r3, r4, r12, lr} + subs r2, r2, #0x20 + bge .Lmemcpy_loop32 + + cmn r2, #0x10 + ldmiage r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ + stmiage r0!, {r3, r4, r12, lr} + subge r2, r2, #0x10 + ldmia sp!, {r4} /* return r4 */ + +.Lmemcpy_l32: + adds r2, r2, #0x14 + + /* blat 12 bytes at a time */ +.Lmemcpy_loop12: + ldmiage r1!, {r3, r12, lr} + stmiage r0!, {r3, r12, lr} + subsge r2, r2, #0x0c + bge .Lmemcpy_loop12 + +.Lmemcpy_l12: + adds r2, r2, #8 + blt .Lmemcpy_l4 + + subs r2, r2, #4 + ldrlt r3, [r1], #4 + strlt r3, [r0], #4 + ldmiage r1!, {r3, r12} + stmiage r0!, {r3, r12} + subge r2, r2, #4 + +.Lmemcpy_l4: + /* less than 4 bytes to go */ + adds r2, r2, #4 +#ifdef __APCS_26_ + ldmiaeq sp!, {r0, pc}^ /* done */ +#else + ldmiaeq sp!, {r0, pc} /* done */ +#endif + /* copy the crud byte at a time */ + cmp r2, #2 + ldrb r3, [r1], #1 + strb r3, [r0], #1 + ldrbge r3, [r1], #1 + strbge r3, [r0], #1 + ldrbgt r3, [r1], #1 + strbgt r3, [r0], #1 + ldmia sp!, {r0, pc} + + /* erg - unaligned destination */ +.Lmemcpy_destul: + rsb r12, r12, #4 + cmp r12, #2 + + /* align destination with byte copies */ + ldrb r3, [r1], #1 + strb r3, [r0], #1 + ldrbge r3, [r1], #1 + strbge r3, [r0], #1 + ldrbgt r3, [r1], #1 + strbgt r3, [r0], #1 + subs r2, r2, r12 + blt .Lmemcpy_l4 /* less the 4 bytes */ + + ands r12, r1, #3 + beq .Lmemcpy_t8 /* we have an aligned source */ + + /* erg - unaligned source */ + /* This is where it gets nasty ... */ +.Lmemcpy_srcul: + bic r1, r1, #3 + ldr lr, [r1], #4 + cmp r12, #2 + bgt .Lmemcpy_srcul3 + beq .Lmemcpy_srcul2 + cmp r2, #0x0c + blt .Lmemcpy_srcul1loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5} + +.Lmemcpy_srcul1loop16: +#ifdef __ARMEB__ + mov r3, lr, lsl #8 +#else + mov r3, lr, lsr #8 +#endif + ldmia r1!, {r4, r5, r12, lr} +#ifdef __ARMEB__ + orr r3, r3, r4, lsr #24 + mov r4, r4, lsl #8 + orr r4, r4, r5, lsr #24 + mov r5, r5, lsl #8 + orr r5, r5, r12, lsr #24 + mov r12, r12, lsl #8 + orr r12, r12, lr, lsr #24 +#else + orr r3, r3, r4, lsl #24 + mov r4, r4, lsr #8 + orr r4, r4, r5, lsl #24 + mov r5, r5, lsr #8 + orr r5, r5, r12, lsl #24 + mov r12, r12, lsr #8 + orr r12, r12, lr, lsl #24 +#endif + stmia r0!, {r3-r5, r12} + subs r2, r2, #0x10 + bge .Lmemcpy_srcul1loop16 + ldmia sp!, {r4, r5} + adds r2, r2, #0x0c + blt .Lmemcpy_srcul1l4 + +.Lmemcpy_srcul1loop4: +#ifdef __ARMEB__ + mov r12, lr, lsl #8 +#else + mov r12, lr, lsr #8 +#endif + ldr lr, [r1], #4 +#ifdef __ARMEB__ + orr r12, r12, lr, lsr #24 +#else + orr r12, r12, lr, lsl #24 +#endif + str r12, [r0], #4 + subs r2, r2, #4 + bge .Lmemcpy_srcul1loop4 + +.Lmemcpy_srcul1l4: + sub r1, r1, #3 + b .Lmemcpy_l4 + +.Lmemcpy_srcul2: + cmp r2, #0x0c + blt .Lmemcpy_srcul2loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5} + +.Lmemcpy_srcul2loop16: +#ifdef __ARMEB__ + mov r3, lr, lsl #16 +#else + mov r3, lr, lsr #16 +#endif + ldmia r1!, {r4, r5, r12, lr} +#ifdef __ARMEB__ + orr r3, r3, r4, lsr #16 + mov r4, r4, lsl #16 + orr r4, r4, r5, lsr #16 + mov r5, r5, lsl #16 + orr r5, r5, r12, lsr #16 + mov r12, r12, lsl #16 + orr r12, r12, lr, lsr #16 +#else + orr r3, r3, r4, lsl #16 + mov r4, r4, lsr #16 + orr r4, r4, r5, lsl #16 + mov r5, r5, lsr #16 + orr r5, r5, r12, lsl #16 + mov r12, r12, lsr #16 + orr r12, r12, lr, lsl #16 +#endif + stmia r0!, {r3-r5, r12} + subs r2, r2, #0x10 + bge .Lmemcpy_srcul2loop16 + ldmia sp!, {r4, r5} + adds r2, r2, #0x0c + blt .Lmemcpy_srcul2l4 + +.Lmemcpy_srcul2loop4: +#ifdef __ARMEB__ + mov r12, lr, lsl #16 +#else + mov r12, lr, lsr #16 +#endif + ldr lr, [r1], #4 +#ifdef __ARMEB__ + orr r12, r12, lr, lsr #16 +#else + orr r12, r12, lr, lsl #16 +#endif + str r12, [r0], #4 + subs r2, r2, #4 + bge .Lmemcpy_srcul2loop4 + +.Lmemcpy_srcul2l4: + sub r1, r1, #2 + b .Lmemcpy_l4 + +.Lmemcpy_srcul3: + cmp r2, #0x0c + blt .Lmemcpy_srcul3loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5} + +.Lmemcpy_srcul3loop16: +#ifdef __ARMEB__ + mov r3, lr, lsl #24 +#else + mov r3, lr, lsr #24 +#endif + ldmia r1!, {r4, r5, r12, lr} +#ifdef __ARMEB__ + orr r3, r3, r4, lsr #8 + mov r4, r4, lsl #24 + orr r4, r4, r5, lsr #8 + mov r5, r5, lsl #24 + orr r5, r5, r12, lsr #8 + mov r12, r12, lsl #24 + orr r12, r12, lr, lsr #8 +#else + orr r3, r3, r4, lsl #8 + mov r4, r4, lsr #24 + orr r4, r4, r5, lsl #8 + mov r5, r5, lsr #24 + orr r5, r5, r12, lsl #8 + mov r12, r12, lsr #24 + orr r12, r12, lr, lsl #8 +#endif + stmia r0!, {r3-r5, r12} + subs r2, r2, #0x10 + bge .Lmemcpy_srcul3loop16 + ldmia sp!, {r4, r5} + adds r2, r2, #0x0c + blt .Lmemcpy_srcul3l4 + +.Lmemcpy_srcul3loop4: +#ifdef __ARMEB__ + mov r12, lr, lsl #24 +#else + mov r12, lr, lsr #24 +#endif + ldr lr, [r1], #4 +#ifdef __ARMEB__ + orr r12, r12, lr, lsr #8 +#else + orr r12, r12, lr, lsl #8 +#endif + str r12, [r0], #4 + subs r2, r2, #4 + bge .Lmemcpy_srcul3loop4 + +.Lmemcpy_srcul3l4: + sub r1, r1, #1 + b .Lmemcpy_l4 +END(memcpy) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/memcpy_xscale.S b/lib/libc/arm/string/memcpy_xscale.S new file mode 100644 index 0000000..7fd1178 --- /dev/null +++ b/lib/libc/arm/string/memcpy_xscale.S @@ -0,0 +1,1788 @@ +/* $NetBSD: memcpy_xscale.S,v 1.1 2003/10/14 07:51:45 scw Exp $ */ + +/* + * Copyright 2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Steve C. Woodford for Wasabi Systems, Inc. + * + * 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 for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/string/memcpy_xscale.S 288373 2015-09-29 16:09:58Z kib $"); + +.syntax unified + +/* LINTSTUB: Func: void *memcpy(void *dst, const void *src, size_t len) */ +ENTRY(memcpy) + pld [r1] + cmp r2, #0x0c + ble .Lmemcpy_short /* <= 12 bytes */ + mov r3, r0 /* We must not clobber r0 */ + + /* Word-align the destination buffer */ + ands ip, r3, #0x03 /* Already word aligned? */ + beq .Lmemcpy_wordaligned /* Yup */ + cmp ip, #0x02 + ldrb ip, [r1], #0x01 + sub r2, r2, #0x01 + strb ip, [r3], #0x01 + ldrble ip, [r1], #0x01 + suble r2, r2, #0x01 + strble ip, [r3], #0x01 + ldrblt ip, [r1], #0x01 + sublt r2, r2, #0x01 + strblt ip, [r3], #0x01 + + /* Destination buffer is now word aligned */ +.Lmemcpy_wordaligned: + ands ip, r1, #0x03 /* Is src also word-aligned? */ + bne .Lmemcpy_bad_align /* Nope. Things just got bad */ + + /* Quad-align the destination buffer */ + tst r3, #0x07 /* Already quad aligned? */ + ldrne ip, [r1], #0x04 + stmfd sp!, {r4-r9} /* Free up some registers */ + subne r2, r2, #0x04 + strne ip, [r3], #0x04 + + /* Destination buffer quad aligned, source is at least word aligned */ + subs r2, r2, #0x80 + blt .Lmemcpy_w_lessthan128 + + /* Copy 128 bytes at a time */ +.Lmemcpy_w_loop128: + ldr r4, [r1], #0x04 /* LD:00-03 */ + ldr r5, [r1], #0x04 /* LD:04-07 */ + pld [r1, #0x18] /* Prefetch 0x20 */ + ldr r6, [r1], #0x04 /* LD:08-0b */ + ldr r7, [r1], #0x04 /* LD:0c-0f */ + ldr r8, [r1], #0x04 /* LD:10-13 */ + ldr r9, [r1], #0x04 /* LD:14-17 */ + strd r4, [r3], #0x08 /* ST:00-07 */ + ldr r4, [r1], #0x04 /* LD:18-1b */ + ldr r5, [r1], #0x04 /* LD:1c-1f */ + strd r6, [r3], #0x08 /* ST:08-0f */ + ldr r6, [r1], #0x04 /* LD:20-23 */ + ldr r7, [r1], #0x04 /* LD:24-27 */ + pld [r1, #0x18] /* Prefetch 0x40 */ + strd r8, [r3], #0x08 /* ST:10-17 */ + ldr r8, [r1], #0x04 /* LD:28-2b */ + ldr r9, [r1], #0x04 /* LD:2c-2f */ + strd r4, [r3], #0x08 /* ST:18-1f */ + ldr r4, [r1], #0x04 /* LD:30-33 */ + ldr r5, [r1], #0x04 /* LD:34-37 */ + strd r6, [r3], #0x08 /* ST:20-27 */ + ldr r6, [r1], #0x04 /* LD:38-3b */ + ldr r7, [r1], #0x04 /* LD:3c-3f */ + strd r8, [r3], #0x08 /* ST:28-2f */ + ldr r8, [r1], #0x04 /* LD:40-43 */ + ldr r9, [r1], #0x04 /* LD:44-47 */ + pld [r1, #0x18] /* Prefetch 0x60 */ + strd r4, [r3], #0x08 /* ST:30-37 */ + ldr r4, [r1], #0x04 /* LD:48-4b */ + ldr r5, [r1], #0x04 /* LD:4c-4f */ + strd r6, [r3], #0x08 /* ST:38-3f */ + ldr r6, [r1], #0x04 /* LD:50-53 */ + ldr r7, [r1], #0x04 /* LD:54-57 */ + strd r8, [r3], #0x08 /* ST:40-47 */ + ldr r8, [r1], #0x04 /* LD:58-5b */ + ldr r9, [r1], #0x04 /* LD:5c-5f */ + strd r4, [r3], #0x08 /* ST:48-4f */ + ldr r4, [r1], #0x04 /* LD:60-63 */ + ldr r5, [r1], #0x04 /* LD:64-67 */ + pld [r1, #0x18] /* Prefetch 0x80 */ + strd r6, [r3], #0x08 /* ST:50-57 */ + ldr r6, [r1], #0x04 /* LD:68-6b */ + ldr r7, [r1], #0x04 /* LD:6c-6f */ + strd r8, [r3], #0x08 /* ST:58-5f */ + ldr r8, [r1], #0x04 /* LD:70-73 */ + ldr r9, [r1], #0x04 /* LD:74-77 */ + strd r4, [r3], #0x08 /* ST:60-67 */ + ldr r4, [r1], #0x04 /* LD:78-7b */ + ldr r5, [r1], #0x04 /* LD:7c-7f */ + strd r6, [r3], #0x08 /* ST:68-6f */ + strd r8, [r3], #0x08 /* ST:70-77 */ + subs r2, r2, #0x80 + strd r4, [r3], #0x08 /* ST:78-7f */ + bge .Lmemcpy_w_loop128 + +.Lmemcpy_w_lessthan128: + adds r2, r2, #0x80 /* Adjust for extra sub */ + ldmfdeq sp!, {r4-r9} + bxeq lr /* Return now if done */ + subs r2, r2, #0x20 + blt .Lmemcpy_w_lessthan32 + + /* Copy 32 bytes at a time */ +.Lmemcpy_w_loop32: + ldr r4, [r1], #0x04 + ldr r5, [r1], #0x04 + pld [r1, #0x18] + ldr r6, [r1], #0x04 + ldr r7, [r1], #0x04 + ldr r8, [r1], #0x04 + ldr r9, [r1], #0x04 + strd r4, [r3], #0x08 + ldr r4, [r1], #0x04 + ldr r5, [r1], #0x04 + strd r6, [r3], #0x08 + strd r8, [r3], #0x08 + subs r2, r2, #0x20 + strd r4, [r3], #0x08 + bge .Lmemcpy_w_loop32 + +.Lmemcpy_w_lessthan32: + adds r2, r2, #0x20 /* Adjust for extra sub */ + ldmfdeq sp!, {r4-r9} + bxeq lr /* Return now if done */ + + and r4, r2, #0x18 + rsbs r4, r4, #0x18 + addne pc, pc, r4, lsl #1 + nop + + /* At least 24 bytes remaining */ + ldr r4, [r1], #0x04 + ldr r5, [r1], #0x04 + sub r2, r2, #0x08 + strd r4, [r3], #0x08 + + /* At least 16 bytes remaining */ + ldr r4, [r1], #0x04 + ldr r5, [r1], #0x04 + sub r2, r2, #0x08 + strd r4, [r3], #0x08 + + /* At least 8 bytes remaining */ + ldr r4, [r1], #0x04 + ldr r5, [r1], #0x04 + subs r2, r2, #0x08 + strd r4, [r3], #0x08 + + /* Less than 8 bytes remaining */ + ldmfd sp!, {r4-r9} + bxeq lr /* Return now if done */ + subs r2, r2, #0x04 + ldrge ip, [r1], #0x04 + strge ip, [r3], #0x04 + bxeq lr /* Return now if done */ + addlt r2, r2, #0x04 + ldrb ip, [r1], #0x01 + cmp r2, #0x02 + ldrbge r2, [r1], #0x01 + strb ip, [r3], #0x01 + ldrbgt ip, [r1] + strbge r2, [r3], #0x01 + strbgt ip, [r3] + bx lr + + +/* + * At this point, it has not been possible to word align both buffers. + * The destination buffer is word aligned, but the source buffer is not. + */ +.Lmemcpy_bad_align: + stmfd sp!, {r4-r7} + bic r1, r1, #0x03 + cmp ip, #2 + ldr ip, [r1], #0x04 + bgt .Lmemcpy_bad3 + beq .Lmemcpy_bad2 + b .Lmemcpy_bad1 + +.Lmemcpy_bad1_loop16: +#ifdef __ARMEB__ + mov r4, ip, lsl #8 +#else + mov r4, ip, lsr #8 +#endif + ldr r5, [r1], #0x04 + pld [r1, #0x018] + ldr r6, [r1], #0x04 + ldr r7, [r1], #0x04 + ldr ip, [r1], #0x04 +#ifdef __ARMEB__ + orr r4, r4, r5, lsr #24 + mov r5, r5, lsl #8 + orr r5, r5, r6, lsr #24 + mov r6, r6, lsl #8 + orr r6, r6, r7, lsr #24 + mov r7, r7, lsl #8 + orr r7, r7, ip, lsr #24 +#else + orr r4, r4, r5, lsl #24 + mov r5, r5, lsr #8 + orr r5, r5, r6, lsl #24 + mov r6, r6, lsr #8 + orr r6, r6, r7, lsl #24 + mov r7, r7, lsr #8 + orr r7, r7, ip, lsl #24 +#endif + str r4, [r3], #0x04 + str r5, [r3], #0x04 + str r6, [r3], #0x04 + str r7, [r3], #0x04 +.Lmemcpy_bad1: + subs r2, r2, #0x10 + bge .Lmemcpy_bad1_loop16 + + adds r2, r2, #0x10 + ldmfdeq sp!, {r4-r7} + bxeq lr /* Return now if done */ + subs r2, r2, #0x04 + sublt r1, r1, #0x03 + blt .Lmemcpy_bad_done + +.Lmemcpy_bad1_loop4: +#ifdef __ARMEB__ + mov r4, ip, lsl #8 +#else + mov r4, ip, lsr #8 +#endif + ldr ip, [r1], #0x04 + subs r2, r2, #0x04 +#ifdef __ARMEB__ + orr r4, r4, ip, lsr #24 +#else + orr r4, r4, ip, lsl #24 +#endif + str r4, [r3], #0x04 + bge .Lmemcpy_bad1_loop4 + sub r1, r1, #0x03 + b .Lmemcpy_bad_done + +.Lmemcpy_bad2_loop16: +#ifdef __ARMEB__ + mov r4, ip, lsl #16 +#else + mov r4, ip, lsr #16 +#endif + ldr r5, [r1], #0x04 + pld [r1, #0x018] + ldr r6, [r1], #0x04 + ldr r7, [r1], #0x04 + ldr ip, [r1], #0x04 +#ifdef __ARMEB__ + orr r4, r4, r5, lsr #16 + mov r5, r5, lsl #16 + orr r5, r5, r6, lsr #16 + mov r6, r6, lsl #16 + orr r6, r6, r7, lsr #16 + mov r7, r7, lsl #16 + orr r7, r7, ip, lsr #16 +#else + orr r4, r4, r5, lsl #16 + mov r5, r5, lsr #16 + orr r5, r5, r6, lsl #16 + mov r6, r6, lsr #16 + orr r6, r6, r7, lsl #16 + mov r7, r7, lsr #16 + orr r7, r7, ip, lsl #16 +#endif + str r4, [r3], #0x04 + str r5, [r3], #0x04 + str r6, [r3], #0x04 + str r7, [r3], #0x04 +.Lmemcpy_bad2: + subs r2, r2, #0x10 + bge .Lmemcpy_bad2_loop16 + + adds r2, r2, #0x10 + ldmfdeq sp!, {r4-r7} + bxeq lr /* Return now if done */ + subs r2, r2, #0x04 + sublt r1, r1, #0x02 + blt .Lmemcpy_bad_done + +.Lmemcpy_bad2_loop4: +#ifdef __ARMEB__ + mov r4, ip, lsl #16 +#else + mov r4, ip, lsr #16 +#endif + ldr ip, [r1], #0x04 + subs r2, r2, #0x04 +#ifdef __ARMEB__ + orr r4, r4, ip, lsr #16 +#else + orr r4, r4, ip, lsl #16 +#endif + str r4, [r3], #0x04 + bge .Lmemcpy_bad2_loop4 + sub r1, r1, #0x02 + b .Lmemcpy_bad_done + +.Lmemcpy_bad3_loop16: +#ifdef __ARMEB__ + mov r4, ip, lsl #24 +#else + mov r4, ip, lsr #24 +#endif + ldr r5, [r1], #0x04 + pld [r1, #0x018] + ldr r6, [r1], #0x04 + ldr r7, [r1], #0x04 + ldr ip, [r1], #0x04 +#ifdef __ARMEB__ + orr r4, r4, r5, lsr #8 + mov r5, r5, lsl #24 + orr r5, r5, r6, lsr #8 + mov r6, r6, lsl #24 + orr r6, r6, r7, lsr #8 + mov r7, r7, lsl #24 + orr r7, r7, ip, lsr #8 +#else + orr r4, r4, r5, lsl #8 + mov r5, r5, lsr #24 + orr r5, r5, r6, lsl #8 + mov r6, r6, lsr #24 + orr r6, r6, r7, lsl #8 + mov r7, r7, lsr #24 + orr r7, r7, ip, lsl #8 +#endif + str r4, [r3], #0x04 + str r5, [r3], #0x04 + str r6, [r3], #0x04 + str r7, [r3], #0x04 +.Lmemcpy_bad3: + subs r2, r2, #0x10 + bge .Lmemcpy_bad3_loop16 + + adds r2, r2, #0x10 + ldmfdeq sp!, {r4-r7} + bxeq lr /* Return now if done */ + subs r2, r2, #0x04 + sublt r1, r1, #0x01 + blt .Lmemcpy_bad_done + +.Lmemcpy_bad3_loop4: +#ifdef __ARMEB__ + mov r4, ip, lsl #24 +#else + mov r4, ip, lsr #24 +#endif + ldr ip, [r1], #0x04 + subs r2, r2, #0x04 +#ifdef __ARMEB__ + orr r4, r4, ip, lsr #8 +#else + orr r4, r4, ip, lsl #8 +#endif + str r4, [r3], #0x04 + bge .Lmemcpy_bad3_loop4 + sub r1, r1, #0x01 + +.Lmemcpy_bad_done: + ldmfd sp!, {r4-r7} + adds r2, r2, #0x04 + bxeq lr + ldrb ip, [r1], #0x01 + cmp r2, #0x02 + ldrbge r2, [r1], #0x01 + strb ip, [r3], #0x01 + ldrbgt ip, [r1] + strbge r2, [r3], #0x01 + strbgt ip, [r3] + bx lr + + +/* + * Handle short copies (less than 16 bytes), possibly misaligned. + * Some of these are *very* common, thanks to the network stack, + * and so are handled specially. + */ +.Lmemcpy_short: +#ifndef _STANDALONE + add pc, pc, r2, lsl #2 + nop + bx lr /* 0x00 */ + b .Lmemcpy_bytewise /* 0x01 */ + b .Lmemcpy_bytewise /* 0x02 */ + b .Lmemcpy_bytewise /* 0x03 */ + b .Lmemcpy_4 /* 0x04 */ + b .Lmemcpy_bytewise /* 0x05 */ + b .Lmemcpy_6 /* 0x06 */ + b .Lmemcpy_bytewise /* 0x07 */ + b .Lmemcpy_8 /* 0x08 */ + b .Lmemcpy_bytewise /* 0x09 */ + b .Lmemcpy_bytewise /* 0x0a */ + b .Lmemcpy_bytewise /* 0x0b */ + b .Lmemcpy_c /* 0x0c */ +#endif +.Lmemcpy_bytewise: + mov r3, r0 /* We must not clobber r0 */ + ldrb ip, [r1], #0x01 +1: subs r2, r2, #0x01 + strb ip, [r3], #0x01 + ldrbne ip, [r1], #0x01 + bne 1b + bx lr + +#ifndef _STANDALONE +/****************************************************************************** + * Special case for 4 byte copies + */ +#define LMEMCPY_4_LOG2 6 /* 64 bytes */ +#define LMEMCPY_4_PAD .align LMEMCPY_4_LOG2 + LMEMCPY_4_PAD +.Lmemcpy_4: + and r2, r1, #0x03 + orr r2, r2, r0, lsl #2 + ands r2, r2, #0x0f + sub r3, pc, #0x14 + addne pc, r3, r2, lsl #LMEMCPY_4_LOG2 + +/* + * 0000: dst is 32-bit aligned, src is 32-bit aligned + */ + ldr r2, [r1] + str r2, [r0] + bx lr + LMEMCPY_4_PAD + +/* + * 0001: dst is 32-bit aligned, src is 8-bit aligned + */ + ldr r3, [r1, #-1] /* BE:r3 = x012 LE:r3 = 210x */ + ldr r2, [r1, #3] /* BE:r2 = 3xxx LE:r2 = xxx3 */ +#ifdef __ARMEB__ + mov r3, r3, lsl #8 /* r3 = 012. */ + orr r3, r3, r2, lsr #24 /* r3 = 0123 */ +#else + mov r3, r3, lsr #8 /* r3 = .210 */ + orr r3, r3, r2, lsl #24 /* r3 = 3210 */ +#endif + str r3, [r0] + bx lr + LMEMCPY_4_PAD + +/* + * 0010: dst is 32-bit aligned, src is 16-bit aligned + */ +#ifdef __ARMEB__ + ldrh r3, [r1] + ldrh r2, [r1, #0x02] +#else + ldrh r3, [r1, #0x02] + ldrh r2, [r1] +#endif + orr r3, r2, r3, lsl #16 + str r3, [r0] + bx lr + LMEMCPY_4_PAD + +/* + * 0011: dst is 32-bit aligned, src is 8-bit aligned + */ + ldr r3, [r1, #-3] /* BE:r3 = xxx0 LE:r3 = 0xxx */ + ldr r2, [r1, #1] /* BE:r2 = 123x LE:r2 = x321 */ +#ifdef __ARMEB__ + mov r3, r3, lsl #24 /* r3 = 0... */ + orr r3, r3, r2, lsr #8 /* r3 = 0123 */ +#else + mov r3, r3, lsr #24 /* r3 = ...0 */ + orr r3, r3, r2, lsl #8 /* r3 = 3210 */ +#endif + str r3, [r0] + bx lr + LMEMCPY_4_PAD + +/* + * 0100: dst is 8-bit aligned, src is 32-bit aligned + */ + ldr r2, [r1] +#ifdef __ARMEB__ + strb r2, [r0, #0x03] + mov r3, r2, lsr #8 + mov r1, r2, lsr #24 + strb r1, [r0] +#else + strb r2, [r0] + mov r3, r2, lsr #8 + mov r1, r2, lsr #24 + strb r1, [r0, #0x03] +#endif + strh r3, [r0, #0x01] + bx lr + LMEMCPY_4_PAD + +/* + * 0101: dst is 8-bit aligned, src is 8-bit aligned + */ + ldrb r2, [r1] + ldrh r3, [r1, #0x01] + ldrb r1, [r1, #0x03] + strb r2, [r0] + strh r3, [r0, #0x01] + strb r1, [r0, #0x03] + bx lr + LMEMCPY_4_PAD + +/* + * 0110: dst is 8-bit aligned, src is 16-bit aligned + */ + ldrh r2, [r1] /* BE:r2 = ..01 LE:r2 = ..10 */ + ldrh r3, [r1, #0x02] /* LE:r3 = ..23 LE:r3 = ..32 */ +#ifdef __ARMEB__ + mov r1, r2, lsr #8 /* r1 = ...0 */ + strb r1, [r0] + mov r2, r2, lsl #8 /* r2 = .01. */ + orr r2, r2, r3, lsr #8 /* r2 = .012 */ +#else + strb r2, [r0] + mov r2, r2, lsr #8 /* r2 = ...1 */ + orr r2, r2, r3, lsl #8 /* r2 = .321 */ + mov r3, r3, lsr #8 /* r3 = ...3 */ +#endif + strh r2, [r0, #0x01] + strb r3, [r0, #0x03] + bx lr + LMEMCPY_4_PAD + +/* + * 0111: dst is 8-bit aligned, src is 8-bit aligned + */ + ldrb r2, [r1] + ldrh r3, [r1, #0x01] + ldrb r1, [r1, #0x03] + strb r2, [r0] + strh r3, [r0, #0x01] + strb r1, [r0, #0x03] + bx lr + LMEMCPY_4_PAD + +/* + * 1000: dst is 16-bit aligned, src is 32-bit aligned + */ + ldr r2, [r1] +#ifdef __ARMEB__ + strh r2, [r0, #0x02] + mov r3, r2, lsr #16 + strh r3, [r0] +#else + strh r2, [r0] + mov r3, r2, lsr #16 + strh r3, [r0, #0x02] +#endif + bx lr + LMEMCPY_4_PAD + +/* + * 1001: dst is 16-bit aligned, src is 8-bit aligned + */ + ldr r2, [r1, #-1] /* BE:r2 = x012 LE:r2 = 210x */ + ldr r3, [r1, #3] /* BE:r3 = 3xxx LE:r3 = xxx3 */ + mov r1, r2, lsr #8 /* BE:r1 = .x01 LE:r1 = .210 */ + strh r1, [r0] +#ifdef __ARMEB__ + mov r2, r2, lsl #8 /* r2 = 012. */ + orr r2, r2, r3, lsr #24 /* r2 = 0123 */ +#else + mov r2, r2, lsr #24 /* r2 = ...2 */ + orr r2, r2, r3, lsl #8 /* r2 = xx32 */ +#endif + strh r2, [r0, #0x02] + bx lr + LMEMCPY_4_PAD + +/* + * 1010: dst is 16-bit aligned, src is 16-bit aligned + */ + ldrh r2, [r1] + ldrh r3, [r1, #0x02] + strh r2, [r0] + strh r3, [r0, #0x02] + bx lr + LMEMCPY_4_PAD + +/* + * 1011: dst is 16-bit aligned, src is 8-bit aligned + */ + ldr r3, [r1, #1] /* BE:r3 = 123x LE:r3 = x321 */ + ldr r2, [r1, #-3] /* BE:r2 = xxx0 LE:r2 = 0xxx */ + mov r1, r3, lsr #8 /* BE:r1 = .123 LE:r1 = .x32 */ + strh r1, [r0, #0x02] +#ifdef __ARMEB__ + mov r3, r3, lsr #24 /* r3 = ...1 */ + orr r3, r3, r2, lsl #8 /* r3 = xx01 */ +#else + mov r3, r3, lsl #8 /* r3 = 321. */ + orr r3, r3, r2, lsr #24 /* r3 = 3210 */ +#endif + strh r3, [r0] + bx lr + LMEMCPY_4_PAD + +/* + * 1100: dst is 8-bit aligned, src is 32-bit aligned + */ + ldr r2, [r1] /* BE:r2 = 0123 LE:r2 = 3210 */ +#ifdef __ARMEB__ + strb r2, [r0, #0x03] + mov r3, r2, lsr #8 + mov r1, r2, lsr #24 + strh r3, [r0, #0x01] + strb r1, [r0] +#else + strb r2, [r0] + mov r3, r2, lsr #8 + mov r1, r2, lsr #24 + strh r3, [r0, #0x01] + strb r1, [r0, #0x03] +#endif + bx lr + LMEMCPY_4_PAD + +/* + * 1101: dst is 8-bit aligned, src is 8-bit aligned + */ + ldrb r2, [r1] + ldrh r3, [r1, #0x01] + ldrb r1, [r1, #0x03] + strb r2, [r0] + strh r3, [r0, #0x01] + strb r1, [r0, #0x03] + bx lr + LMEMCPY_4_PAD + +/* + * 1110: dst is 8-bit aligned, src is 16-bit aligned + */ +#ifdef __ARMEB__ + ldrh r3, [r1, #0x02] /* BE:r3 = ..23 LE:r3 = ..32 */ + ldrh r2, [r1] /* BE:r2 = ..01 LE:r2 = ..10 */ + strb r3, [r0, #0x03] + mov r3, r3, lsr #8 /* r3 = ...2 */ + orr r3, r3, r2, lsl #8 /* r3 = ..12 */ + strh r3, [r0, #0x01] + mov r2, r2, lsr #8 /* r2 = ...0 */ + strb r2, [r0] +#else + ldrh r2, [r1] /* BE:r2 = ..01 LE:r2 = ..10 */ + ldrh r3, [r1, #0x02] /* BE:r3 = ..23 LE:r3 = ..32 */ + strb r2, [r0] + mov r2, r2, lsr #8 /* r2 = ...1 */ + orr r2, r2, r3, lsl #8 /* r2 = .321 */ + strh r2, [r0, #0x01] + mov r3, r3, lsr #8 /* r3 = ...3 */ + strb r3, [r0, #0x03] +#endif + bx lr + LMEMCPY_4_PAD + +/* + * 1111: dst is 8-bit aligned, src is 8-bit aligned + */ + ldrb r2, [r1] + ldrh r3, [r1, #0x01] + ldrb r1, [r1, #0x03] + strb r2, [r0] + strh r3, [r0, #0x01] + strb r1, [r0, #0x03] + bx lr + LMEMCPY_4_PAD + + +/****************************************************************************** + * Special case for 6 byte copies + */ +#define LMEMCPY_6_LOG2 6 /* 64 bytes */ +#define LMEMCPY_6_PAD .align LMEMCPY_6_LOG2 + LMEMCPY_6_PAD +.Lmemcpy_6: + and r2, r1, #0x03 + orr r2, r2, r0, lsl #2 + ands r2, r2, #0x0f + sub r3, pc, #0x14 + addne pc, r3, r2, lsl #LMEMCPY_6_LOG2 + +/* + * 0000: dst is 32-bit aligned, src is 32-bit aligned + */ + ldr r2, [r1] + ldrh r3, [r1, #0x04] + str r2, [r0] + strh r3, [r0, #0x04] + bx lr + LMEMCPY_6_PAD + +/* + * 0001: dst is 32-bit aligned, src is 8-bit aligned + */ + ldr r2, [r1, #-1] /* BE:r2 = x012 LE:r2 = 210x */ + ldr r3, [r1, #0x03] /* BE:r3 = 345x LE:r3 = x543 */ +#ifdef __ARMEB__ + mov r2, r2, lsl #8 /* r2 = 012. */ + orr r2, r2, r3, lsr #24 /* r2 = 0123 */ +#else + mov r2, r2, lsr #8 /* r2 = .210 */ + orr r2, r2, r3, lsl #24 /* r2 = 3210 */ +#endif + mov r3, r3, lsr #8 /* BE:r3 = .345 LE:r3 = .x54 */ + str r2, [r0] + strh r3, [r0, #0x04] + bx lr + LMEMCPY_6_PAD + +/* + * 0010: dst is 32-bit aligned, src is 16-bit aligned + */ + ldr r3, [r1, #0x02] /* BE:r3 = 2345 LE:r3 = 5432 */ + ldrh r2, [r1] /* BE:r2 = ..01 LE:r2 = ..10 */ +#ifdef __ARMEB__ + mov r1, r3, lsr #16 /* r1 = ..23 */ + orr r1, r1, r2, lsl #16 /* r1 = 0123 */ + str r1, [r0] + strh r3, [r0, #0x04] +#else + mov r1, r3, lsr #16 /* r1 = ..54 */ + orr r2, r2, r3, lsl #16 /* r2 = 3210 */ + str r2, [r0] + strh r1, [r0, #0x04] +#endif + bx lr + LMEMCPY_6_PAD + +/* + * 0011: dst is 32-bit aligned, src is 8-bit aligned + */ + ldr r2, [r1, #-3] /* BE:r2 = xxx0 LE:r2 = 0xxx */ + ldr r3, [r1, #1] /* BE:r3 = 1234 LE:r3 = 4321 */ + ldr r1, [r1, #5] /* BE:r1 = 5xxx LE:r3 = xxx5 */ +#ifdef __ARMEB__ + mov r2, r2, lsl #24 /* r2 = 0... */ + orr r2, r2, r3, lsr #8 /* r2 = 0123 */ + mov r3, r3, lsl #8 /* r3 = 234. */ + orr r1, r3, r1, lsr #24 /* r1 = 2345 */ +#else + mov r2, r2, lsr #24 /* r2 = ...0 */ + orr r2, r2, r3, lsl #8 /* r2 = 3210 */ + mov r1, r1, lsl #8 /* r1 = xx5. */ + orr r1, r1, r3, lsr #24 /* r1 = xx54 */ +#endif + str r2, [r0] + strh r1, [r0, #0x04] + bx lr + LMEMCPY_6_PAD + +/* + * 0100: dst is 8-bit aligned, src is 32-bit aligned + */ + ldr r3, [r1] /* BE:r3 = 0123 LE:r3 = 3210 */ + ldrh r2, [r1, #0x04] /* BE:r2 = ..45 LE:r2 = ..54 */ + mov r1, r3, lsr #8 /* BE:r1 = .012 LE:r1 = .321 */ + strh r1, [r0, #0x01] +#ifdef __ARMEB__ + mov r1, r3, lsr #24 /* r1 = ...0 */ + strb r1, [r0] + mov r3, r3, lsl #8 /* r3 = 123. */ + orr r3, r3, r2, lsr #8 /* r3 = 1234 */ +#else + strb r3, [r0] + mov r3, r3, lsr #24 /* r3 = ...3 */ + orr r3, r3, r2, lsl #8 /* r3 = .543 */ + mov r2, r2, lsr #8 /* r2 = ...5 */ +#endif + strh r3, [r0, #0x03] + strb r2, [r0, #0x05] + bx lr + LMEMCPY_6_PAD + +/* + * 0101: dst is 8-bit aligned, src is 8-bit aligned + */ + ldrb r2, [r1] + ldrh r3, [r1, #0x01] + ldrh ip, [r1, #0x03] + ldrb r1, [r1, #0x05] + strb r2, [r0] + strh r3, [r0, #0x01] + strh ip, [r0, #0x03] + strb r1, [r0, #0x05] + bx lr + LMEMCPY_6_PAD + +/* + * 0110: dst is 8-bit aligned, src is 16-bit aligned + */ + ldrh r2, [r1] /* BE:r2 = ..01 LE:r2 = ..10 */ + ldr r1, [r1, #0x02] /* BE:r1 = 2345 LE:r1 = 5432 */ +#ifdef __ARMEB__ + mov r3, r2, lsr #8 /* r3 = ...0 */ + strb r3, [r0] + strb r1, [r0, #0x05] + mov r3, r1, lsr #8 /* r3 = .234 */ + strh r3, [r0, #0x03] + mov r3, r2, lsl #8 /* r3 = .01. */ + orr r3, r3, r1, lsr #24 /* r3 = .012 */ + strh r3, [r0, #0x01] +#else + strb r2, [r0] + mov r3, r1, lsr #24 + strb r3, [r0, #0x05] + mov r3, r1, lsr #8 /* r3 = .543 */ + strh r3, [r0, #0x03] + mov r3, r2, lsr #8 /* r3 = ...1 */ + orr r3, r3, r1, lsl #8 /* r3 = 4321 */ + strh r3, [r0, #0x01] +#endif + bx lr + LMEMCPY_6_PAD + +/* + * 0111: dst is 8-bit aligned, src is 8-bit aligned + */ + ldrb r2, [r1] + ldrh r3, [r1, #0x01] + ldrh ip, [r1, #0x03] + ldrb r1, [r1, #0x05] + strb r2, [r0] + strh r3, [r0, #0x01] + strh ip, [r0, #0x03] + strb r1, [r0, #0x05] + bx lr + LMEMCPY_6_PAD + +/* + * 1000: dst is 16-bit aligned, src is 32-bit aligned + */ +#ifdef __ARMEB__ + ldr r2, [r1] /* r2 = 0123 */ + ldrh r3, [r1, #0x04] /* r3 = ..45 */ + mov r1, r2, lsr #16 /* r1 = ..01 */ + orr r3, r3, r2, lsl#16 /* r3 = 2345 */ + strh r1, [r0] + str r3, [r0, #0x02] +#else + ldrh r2, [r1, #0x04] /* r2 = ..54 */ + ldr r3, [r1] /* r3 = 3210 */ + mov r2, r2, lsl #16 /* r2 = 54.. */ + orr r2, r2, r3, lsr #16 /* r2 = 5432 */ + strh r3, [r0] + str r2, [r0, #0x02] +#endif + bx lr + LMEMCPY_6_PAD + +/* + * 1001: dst is 16-bit aligned, src is 8-bit aligned + */ + ldr r3, [r1, #-1] /* BE:r3 = x012 LE:r3 = 210x */ + ldr r2, [r1, #3] /* BE:r2 = 345x LE:r2 = x543 */ + mov r1, r3, lsr #8 /* BE:r1 = .x01 LE:r1 = .210 */ +#ifdef __ARMEB__ + mov r2, r2, lsr #8 /* r2 = .345 */ + orr r2, r2, r3, lsl #24 /* r2 = 2345 */ +#else + mov r2, r2, lsl #8 /* r2 = 543. */ + orr r2, r2, r3, lsr #24 /* r2 = 5432 */ +#endif + strh r1, [r0] + str r2, [r0, #0x02] + bx lr + LMEMCPY_6_PAD + +/* + * 1010: dst is 16-bit aligned, src is 16-bit aligned + */ + ldrh r2, [r1] + ldr r3, [r1, #0x02] + strh r2, [r0] + str r3, [r0, #0x02] + bx lr + LMEMCPY_6_PAD + +/* + * 1011: dst is 16-bit aligned, src is 8-bit aligned + */ + ldrb r3, [r1] /* r3 = ...0 */ + ldr r2, [r1, #0x01] /* BE:r2 = 1234 LE:r2 = 4321 */ + ldrb r1, [r1, #0x05] /* r1 = ...5 */ +#ifdef __ARMEB__ + mov r3, r3, lsl #8 /* r3 = ..0. */ + orr r3, r3, r2, lsr #24 /* r3 = ..01 */ + orr r1, r1, r2, lsl #8 /* r1 = 2345 */ +#else + orr r3, r3, r2, lsl #8 /* r3 = 3210 */ + mov r1, r1, lsl #24 /* r1 = 5... */ + orr r1, r1, r2, lsr #8 /* r1 = 5432 */ +#endif + strh r3, [r0] + str r1, [r0, #0x02] + bx lr + LMEMCPY_6_PAD + +/* + * 1100: dst is 8-bit aligned, src is 32-bit aligned + */ + ldr r2, [r1] /* BE:r2 = 0123 LE:r2 = 3210 */ + ldrh r1, [r1, #0x04] /* BE:r1 = ..45 LE:r1 = ..54 */ +#ifdef __ARMEB__ + mov r3, r2, lsr #24 /* r3 = ...0 */ + strb r3, [r0] + mov r2, r2, lsl #8 /* r2 = 123. */ + orr r2, r2, r1, lsr #8 /* r2 = 1234 */ +#else + strb r2, [r0] + mov r2, r2, lsr #8 /* r2 = .321 */ + orr r2, r2, r1, lsl #24 /* r2 = 4321 */ + mov r1, r1, lsr #8 /* r1 = ...5 */ +#endif + str r2, [r0, #0x01] + strb r1, [r0, #0x05] + bx lr + LMEMCPY_6_PAD + +/* + * 1101: dst is 8-bit aligned, src is 8-bit aligned + */ + ldrb r2, [r1] + ldrh r3, [r1, #0x01] + ldrh ip, [r1, #0x03] + ldrb r1, [r1, #0x05] + strb r2, [r0] + strh r3, [r0, #0x01] + strh ip, [r0, #0x03] + strb r1, [r0, #0x05] + bx lr + LMEMCPY_6_PAD + +/* + * 1110: dst is 8-bit aligned, src is 16-bit aligned + */ + ldrh r2, [r1] /* BE:r2 = ..01 LE:r2 = ..10 */ + ldr r1, [r1, #0x02] /* BE:r1 = 2345 LE:r1 = 5432 */ +#ifdef __ARMEB__ + mov r3, r2, lsr #8 /* r3 = ...0 */ + strb r3, [r0] + mov r2, r2, lsl #24 /* r2 = 1... */ + orr r2, r2, r1, lsr #8 /* r2 = 1234 */ +#else + strb r2, [r0] + mov r2, r2, lsr #8 /* r2 = ...1 */ + orr r2, r2, r1, lsl #8 /* r2 = 4321 */ + mov r1, r1, lsr #24 /* r1 = ...5 */ +#endif + str r2, [r0, #0x01] + strb r1, [r0, #0x05] + bx lr + LMEMCPY_6_PAD + +/* + * 1111: dst is 8-bit aligned, src is 8-bit aligned + */ + ldrb r2, [r1] + ldr r3, [r1, #0x01] + ldrb r1, [r1, #0x05] + strb r2, [r0] + str r3, [r0, #0x01] + strb r1, [r0, #0x05] + bx lr + LMEMCPY_6_PAD + + +/****************************************************************************** + * Special case for 8 byte copies + */ +#define LMEMCPY_8_LOG2 6 /* 64 bytes */ +#define LMEMCPY_8_PAD .align LMEMCPY_8_LOG2 + LMEMCPY_8_PAD +.Lmemcpy_8: + and r2, r1, #0x03 + orr r2, r2, r0, lsl #2 + ands r2, r2, #0x0f + sub r3, pc, #0x14 + addne pc, r3, r2, lsl #LMEMCPY_8_LOG2 + +/* + * 0000: dst is 32-bit aligned, src is 32-bit aligned + */ + ldr r2, [r1] + ldr r3, [r1, #0x04] + str r2, [r0] + str r3, [r0, #0x04] + bx lr + LMEMCPY_8_PAD + +/* + * 0001: dst is 32-bit aligned, src is 8-bit aligned + */ + ldr r3, [r1, #-1] /* BE:r3 = x012 LE:r3 = 210x */ + ldr r2, [r1, #0x03] /* BE:r2 = 3456 LE:r2 = 6543 */ + ldrb r1, [r1, #0x07] /* r1 = ...7 */ +#ifdef __ARMEB__ + mov r3, r3, lsl #8 /* r3 = 012. */ + orr r3, r3, r2, lsr #24 /* r3 = 0123 */ + orr r2, r1, r2, lsl #8 /* r2 = 4567 */ +#else + mov r3, r3, lsr #8 /* r3 = .210 */ + orr r3, r3, r2, lsl #24 /* r3 = 3210 */ + mov r1, r1, lsl #24 /* r1 = 7... */ + orr r2, r1, r2, lsr #8 /* r2 = 7654 */ +#endif + str r3, [r0] + str r2, [r0, #0x04] + bx lr + LMEMCPY_8_PAD + +/* + * 0010: dst is 32-bit aligned, src is 16-bit aligned + */ + ldrh r2, [r1] /* BE:r2 = ..01 LE:r2 = ..10 */ + ldr r3, [r1, #0x02] /* BE:r3 = 2345 LE:r3 = 5432 */ + ldrh r1, [r1, #0x06] /* BE:r1 = ..67 LE:r1 = ..76 */ +#ifdef __ARMEB__ + mov r2, r2, lsl #16 /* r2 = 01.. */ + orr r2, r2, r3, lsr #16 /* r2 = 0123 */ + orr r3, r1, r3, lsl #16 /* r3 = 4567 */ +#else + orr r2, r2, r3, lsl #16 /* r2 = 3210 */ + mov r3, r3, lsr #16 /* r3 = ..54 */ + orr r3, r3, r1, lsl #16 /* r3 = 7654 */ +#endif + str r2, [r0] + str r3, [r0, #0x04] + bx lr + LMEMCPY_8_PAD + +/* + * 0011: dst is 32-bit aligned, src is 8-bit aligned + */ + ldrb r3, [r1] /* r3 = ...0 */ + ldr r2, [r1, #0x01] /* BE:r2 = 1234 LE:r2 = 4321 */ + ldr r1, [r1, #0x05] /* BE:r1 = 567x LE:r1 = x765 */ +#ifdef __ARMEB__ + mov r3, r3, lsl #24 /* r3 = 0... */ + orr r3, r3, r2, lsr #8 /* r3 = 0123 */ + mov r2, r2, lsl #24 /* r2 = 4... */ + orr r2, r2, r1, lsr #8 /* r2 = 4567 */ +#else + orr r3, r3, r2, lsl #8 /* r3 = 3210 */ + mov r2, r2, lsr #24 /* r2 = ...4 */ + orr r2, r2, r1, lsl #8 /* r2 = 7654 */ +#endif + str r3, [r0] + str r2, [r0, #0x04] + bx lr + LMEMCPY_8_PAD + +/* + * 0100: dst is 8-bit aligned, src is 32-bit aligned + */ + ldr r3, [r1] /* BE:r3 = 0123 LE:r3 = 3210 */ + ldr r2, [r1, #0x04] /* BE:r2 = 4567 LE:r2 = 7654 */ +#ifdef __ARMEB__ + mov r1, r3, lsr #24 /* r1 = ...0 */ + strb r1, [r0] + mov r1, r3, lsr #8 /* r1 = .012 */ + strb r2, [r0, #0x07] + mov r3, r3, lsl #24 /* r3 = 3... */ + orr r3, r3, r2, lsr #8 /* r3 = 3456 */ +#else + strb r3, [r0] + mov r1, r2, lsr #24 /* r1 = ...7 */ + strb r1, [r0, #0x07] + mov r1, r3, lsr #8 /* r1 = .321 */ + mov r3, r3, lsr #24 /* r3 = ...3 */ + orr r3, r3, r2, lsl #8 /* r3 = 6543 */ +#endif + strh r1, [r0, #0x01] + str r3, [r0, #0x03] + bx lr + LMEMCPY_8_PAD + +/* + * 0101: dst is 8-bit aligned, src is 8-bit aligned + */ + ldrb r2, [r1] + ldrh r3, [r1, #0x01] + ldr ip, [r1, #0x03] + ldrb r1, [r1, #0x07] + strb r2, [r0] + strh r3, [r0, #0x01] + str ip, [r0, #0x03] + strb r1, [r0, #0x07] + bx lr + LMEMCPY_8_PAD + +/* + * 0110: dst is 8-bit aligned, src is 16-bit aligned + */ + ldrh r2, [r1] /* BE:r2 = ..01 LE:r2 = ..10 */ + ldr r3, [r1, #0x02] /* BE:r3 = 2345 LE:r3 = 5432 */ + ldrh r1, [r1, #0x06] /* BE:r1 = ..67 LE:r1 = ..76 */ +#ifdef __ARMEB__ + mov ip, r2, lsr #8 /* ip = ...0 */ + strb ip, [r0] + mov ip, r2, lsl #8 /* ip = .01. */ + orr ip, ip, r3, lsr #24 /* ip = .012 */ + strb r1, [r0, #0x07] + mov r3, r3, lsl #8 /* r3 = 345. */ + orr r3, r3, r1, lsr #8 /* r3 = 3456 */ +#else + strb r2, [r0] /* 0 */ + mov ip, r1, lsr #8 /* ip = ...7 */ + strb ip, [r0, #0x07] /* 7 */ + mov ip, r2, lsr #8 /* ip = ...1 */ + orr ip, ip, r3, lsl #8 /* ip = 4321 */ + mov r3, r3, lsr #8 /* r3 = .543 */ + orr r3, r3, r1, lsl #24 /* r3 = 6543 */ +#endif + strh ip, [r0, #0x01] + str r3, [r0, #0x03] + bx lr + LMEMCPY_8_PAD + +/* + * 0111: dst is 8-bit aligned, src is 8-bit aligned + */ + ldrb r3, [r1] /* r3 = ...0 */ + ldr ip, [r1, #0x01] /* BE:ip = 1234 LE:ip = 4321 */ + ldrh r2, [r1, #0x05] /* BE:r2 = ..56 LE:r2 = ..65 */ + ldrb r1, [r1, #0x07] /* r1 = ...7 */ + strb r3, [r0] + mov r3, ip, lsr #16 /* BE:r3 = ..12 LE:r3 = ..43 */ +#ifdef __ARMEB__ + strh r3, [r0, #0x01] + orr r2, r2, ip, lsl #16 /* r2 = 3456 */ +#else + strh ip, [r0, #0x01] + orr r2, r3, r2, lsl #16 /* r2 = 6543 */ +#endif + str r2, [r0, #0x03] + strb r1, [r0, #0x07] + bx lr + LMEMCPY_8_PAD + +/* + * 1000: dst is 16-bit aligned, src is 32-bit aligned + */ + ldr r2, [r1] /* BE:r2 = 0123 LE:r2 = 3210 */ + ldr r3, [r1, #0x04] /* BE:r3 = 4567 LE:r3 = 7654 */ + mov r1, r2, lsr #16 /* BE:r1 = ..01 LE:r1 = ..32 */ +#ifdef __ARMEB__ + strh r1, [r0] + mov r1, r3, lsr #16 /* r1 = ..45 */ + orr r2, r1 ,r2, lsl #16 /* r2 = 2345 */ +#else + strh r2, [r0] + orr r2, r1, r3, lsl #16 /* r2 = 5432 */ + mov r3, r3, lsr #16 /* r3 = ..76 */ +#endif + str r2, [r0, #0x02] + strh r3, [r0, #0x06] + bx lr + LMEMCPY_8_PAD + +/* + * 1001: dst is 16-bit aligned, src is 8-bit aligned + */ + ldr r2, [r1, #-1] /* BE:r2 = x012 LE:r2 = 210x */ + ldr r3, [r1, #0x03] /* BE:r3 = 3456 LE:r3 = 6543 */ + ldrb ip, [r1, #0x07] /* ip = ...7 */ + mov r1, r2, lsr #8 /* BE:r1 = .x01 LE:r1 = .210 */ + strh r1, [r0] +#ifdef __ARMEB__ + mov r1, r2, lsl #24 /* r1 = 2... */ + orr r1, r1, r3, lsr #8 /* r1 = 2345 */ + orr r3, ip, r3, lsl #8 /* r3 = 4567 */ +#else + mov r1, r2, lsr #24 /* r1 = ...2 */ + orr r1, r1, r3, lsl #8 /* r1 = 5432 */ + mov r3, r3, lsr #24 /* r3 = ...6 */ + orr r3, r3, ip, lsl #8 /* r3 = ..76 */ +#endif + str r1, [r0, #0x02] + strh r3, [r0, #0x06] + bx lr + LMEMCPY_8_PAD + +/* + * 1010: dst is 16-bit aligned, src is 16-bit aligned + */ + ldrh r2, [r1] + ldr ip, [r1, #0x02] + ldrh r3, [r1, #0x06] + strh r2, [r0] + str ip, [r0, #0x02] + strh r3, [r0, #0x06] + bx lr + LMEMCPY_8_PAD + +/* + * 1011: dst is 16-bit aligned, src is 8-bit aligned + */ + ldr r3, [r1, #0x05] /* BE:r3 = 567x LE:r3 = x765 */ + ldr r2, [r1, #0x01] /* BE:r2 = 1234 LE:r2 = 4321 */ + ldrb ip, [r1] /* ip = ...0 */ + mov r1, r3, lsr #8 /* BE:r1 = .567 LE:r1 = .x76 */ + strh r1, [r0, #0x06] +#ifdef __ARMEB__ + mov r3, r3, lsr #24 /* r3 = ...5 */ + orr r3, r3, r2, lsl #8 /* r3 = 2345 */ + mov r2, r2, lsr #24 /* r2 = ...1 */ + orr r2, r2, ip, lsl #8 /* r2 = ..01 */ +#else + mov r3, r3, lsl #24 /* r3 = 5... */ + orr r3, r3, r2, lsr #8 /* r3 = 5432 */ + orr r2, ip, r2, lsl #8 /* r2 = 3210 */ +#endif + str r3, [r0, #0x02] + strh r2, [r0] + bx lr + LMEMCPY_8_PAD + +/* + * 1100: dst is 8-bit aligned, src is 32-bit aligned + */ + ldr r3, [r1, #0x04] /* BE:r3 = 4567 LE:r3 = 7654 */ + ldr r2, [r1] /* BE:r2 = 0123 LE:r2 = 3210 */ + mov r1, r3, lsr #8 /* BE:r1 = .456 LE:r1 = .765 */ + strh r1, [r0, #0x05] +#ifdef __ARMEB__ + strb r3, [r0, #0x07] + mov r1, r2, lsr #24 /* r1 = ...0 */ + strb r1, [r0] + mov r2, r2, lsl #8 /* r2 = 123. */ + orr r2, r2, r3, lsr #24 /* r2 = 1234 */ + str r2, [r0, #0x01] +#else + strb r2, [r0] + mov r1, r3, lsr #24 /* r1 = ...7 */ + strb r1, [r0, #0x07] + mov r2, r2, lsr #8 /* r2 = .321 */ + orr r2, r2, r3, lsl #24 /* r2 = 4321 */ + str r2, [r0, #0x01] +#endif + bx lr + LMEMCPY_8_PAD + +/* + * 1101: dst is 8-bit aligned, src is 8-bit aligned + */ + ldrb r3, [r1] /* r3 = ...0 */ + ldrh r2, [r1, #0x01] /* BE:r2 = ..12 LE:r2 = ..21 */ + ldr ip, [r1, #0x03] /* BE:ip = 3456 LE:ip = 6543 */ + ldrb r1, [r1, #0x07] /* r1 = ...7 */ + strb r3, [r0] + mov r3, ip, lsr #16 /* BE:r3 = ..34 LE:r3 = ..65 */ +#ifdef __ARMEB__ + strh ip, [r0, #0x05] + orr r2, r3, r2, lsl #16 /* r2 = 1234 */ +#else + strh r3, [r0, #0x05] + orr r2, r2, ip, lsl #16 /* r2 = 4321 */ +#endif + str r2, [r0, #0x01] + strb r1, [r0, #0x07] + bx lr + LMEMCPY_8_PAD + +/* + * 1110: dst is 8-bit aligned, src is 16-bit aligned + */ + ldrh r2, [r1] /* BE:r2 = ..01 LE:r2 = ..10 */ + ldr r3, [r1, #0x02] /* BE:r3 = 2345 LE:r3 = 5432 */ + ldrh r1, [r1, #0x06] /* BE:r1 = ..67 LE:r1 = ..76 */ +#ifdef __ARMEB__ + mov ip, r2, lsr #8 /* ip = ...0 */ + strb ip, [r0] + mov ip, r2, lsl #24 /* ip = 1... */ + orr ip, ip, r3, lsr #8 /* ip = 1234 */ + strb r1, [r0, #0x07] + mov r1, r1, lsr #8 /* r1 = ...6 */ + orr r1, r1, r3, lsl #8 /* r1 = 3456 */ +#else + strb r2, [r0] + mov ip, r2, lsr #8 /* ip = ...1 */ + orr ip, ip, r3, lsl #8 /* ip = 4321 */ + mov r2, r1, lsr #8 /* r2 = ...7 */ + strb r2, [r0, #0x07] + mov r1, r1, lsl #8 /* r1 = .76. */ + orr r1, r1, r3, lsr #24 /* r1 = .765 */ +#endif + str ip, [r0, #0x01] + strh r1, [r0, #0x05] + bx lr + LMEMCPY_8_PAD + +/* + * 1111: dst is 8-bit aligned, src is 8-bit aligned + */ + ldrb r2, [r1] + ldr ip, [r1, #0x01] + ldrh r3, [r1, #0x05] + ldrb r1, [r1, #0x07] + strb r2, [r0] + str ip, [r0, #0x01] + strh r3, [r0, #0x05] + strb r1, [r0, #0x07] + bx lr + LMEMCPY_8_PAD + +/****************************************************************************** + * Special case for 12 byte copies + */ +#define LMEMCPY_C_LOG2 7 /* 128 bytes */ +#define LMEMCPY_C_PAD .align LMEMCPY_C_LOG2 + LMEMCPY_C_PAD +.Lmemcpy_c: + and r2, r1, #0x03 + orr r2, r2, r0, lsl #2 + ands r2, r2, #0x0f + sub r3, pc, #0x14 + addne pc, r3, r2, lsl #LMEMCPY_C_LOG2 + +/* + * 0000: dst is 32-bit aligned, src is 32-bit aligned + */ + ldr r2, [r1] + ldr r3, [r1, #0x04] + ldr r1, [r1, #0x08] + str r2, [r0] + str r3, [r0, #0x04] + str r1, [r0, #0x08] + bx lr + LMEMCPY_C_PAD + +/* + * 0001: dst is 32-bit aligned, src is 8-bit aligned + */ + ldrb r2, [r1, #0xb] /* r2 = ...B */ + ldr ip, [r1, #0x07] /* BE:ip = 789A LE:ip = A987 */ + ldr r3, [r1, #0x03] /* BE:r3 = 3456 LE:r3 = 6543 */ + ldr r1, [r1, #-1] /* BE:r1 = x012 LE:r1 = 210x */ +#ifdef __ARMEB__ + orr r2, r2, ip, lsl #8 /* r2 = 89AB */ + str r2, [r0, #0x08] + mov r2, ip, lsr #24 /* r2 = ...7 */ + orr r2, r2, r3, lsl #8 /* r2 = 4567 */ + mov r1, r1, lsl #8 /* r1 = 012. */ + orr r1, r1, r3, lsr #24 /* r1 = 0123 */ +#else + mov r2, r2, lsl #24 /* r2 = B... */ + orr r2, r2, ip, lsr #8 /* r2 = BA98 */ + str r2, [r0, #0x08] + mov r2, ip, lsl #24 /* r2 = 7... */ + orr r2, r2, r3, lsr #8 /* r2 = 7654 */ + mov r1, r1, lsr #8 /* r1 = .210 */ + orr r1, r1, r3, lsl #24 /* r1 = 3210 */ +#endif + str r2, [r0, #0x04] + str r1, [r0] + bx lr + LMEMCPY_C_PAD + +/* + * 0010: dst is 32-bit aligned, src is 16-bit aligned + */ + ldrh r2, [r1] /* BE:r2 = ..01 LE:r2 = ..10 */ + ldr r3, [r1, #0x02] /* BE:r3 = 2345 LE:r3 = 5432 */ + ldr ip, [r1, #0x06] /* BE:ip = 6789 LE:ip = 9876 */ + ldrh r1, [r1, #0x0a] /* BE:r1 = ..AB LE:r1 = ..BA */ +#ifdef __ARMEB__ + mov r2, r2, lsl #16 /* r2 = 01.. */ + orr r2, r2, r3, lsr #16 /* r2 = 0123 */ + str r2, [r0] + mov r3, r3, lsl #16 /* r3 = 45.. */ + orr r3, r3, ip, lsr #16 /* r3 = 4567 */ + orr r1, r1, ip, lsl #16 /* r1 = 89AB */ +#else + orr r2, r2, r3, lsl #16 /* r2 = 3210 */ + str r2, [r0] + mov r3, r3, lsr #16 /* r3 = ..54 */ + orr r3, r3, ip, lsl #16 /* r3 = 7654 */ + mov r1, r1, lsl #16 /* r1 = BA.. */ + orr r1, r1, ip, lsr #16 /* r1 = BA98 */ +#endif + str r3, [r0, #0x04] + str r1, [r0, #0x08] + bx lr + LMEMCPY_C_PAD + +/* + * 0011: dst is 32-bit aligned, src is 8-bit aligned + */ + ldrb r2, [r1] /* r2 = ...0 */ + ldr r3, [r1, #0x01] /* BE:r3 = 1234 LE:r3 = 4321 */ + ldr ip, [r1, #0x05] /* BE:ip = 5678 LE:ip = 8765 */ + ldr r1, [r1, #0x09] /* BE:r1 = 9ABx LE:r1 = xBA9 */ +#ifdef __ARMEB__ + mov r2, r2, lsl #24 /* r2 = 0... */ + orr r2, r2, r3, lsr #8 /* r2 = 0123 */ + str r2, [r0] + mov r3, r3, lsl #24 /* r3 = 4... */ + orr r3, r3, ip, lsr #8 /* r3 = 4567 */ + mov r1, r1, lsr #8 /* r1 = .9AB */ + orr r1, r1, ip, lsl #24 /* r1 = 89AB */ +#else + orr r2, r2, r3, lsl #8 /* r2 = 3210 */ + str r2, [r0] + mov r3, r3, lsr #24 /* r3 = ...4 */ + orr r3, r3, ip, lsl #8 /* r3 = 7654 */ + mov r1, r1, lsl #8 /* r1 = BA9. */ + orr r1, r1, ip, lsr #24 /* r1 = BA98 */ +#endif + str r3, [r0, #0x04] + str r1, [r0, #0x08] + bx lr + LMEMCPY_C_PAD + +/* + * 0100: dst is 8-bit aligned (byte 1), src is 32-bit aligned + */ + ldr r2, [r1] /* BE:r2 = 0123 LE:r2 = 3210 */ + ldr r3, [r1, #0x04] /* BE:r3 = 4567 LE:r3 = 7654 */ + ldr ip, [r1, #0x08] /* BE:ip = 89AB LE:ip = BA98 */ + mov r1, r2, lsr #8 /* BE:r1 = .012 LE:r1 = .321 */ + strh r1, [r0, #0x01] +#ifdef __ARMEB__ + mov r1, r2, lsr #24 /* r1 = ...0 */ + strb r1, [r0] + mov r1, r2, lsl #24 /* r1 = 3... */ + orr r2, r1, r3, lsr #8 /* r1 = 3456 */ + mov r1, r3, lsl #24 /* r1 = 7... */ + orr r1, r1, ip, lsr #8 /* r1 = 789A */ +#else + strb r2, [r0] + mov r1, r2, lsr #24 /* r1 = ...3 */ + orr r2, r1, r3, lsl #8 /* r1 = 6543 */ + mov r1, r3, lsr #24 /* r1 = ...7 */ + orr r1, r1, ip, lsl #8 /* r1 = A987 */ + mov ip, ip, lsr #24 /* ip = ...B */ +#endif + str r2, [r0, #0x03] + str r1, [r0, #0x07] + strb ip, [r0, #0x0b] + bx lr + LMEMCPY_C_PAD + +/* + * 0101: dst is 8-bit aligned (byte 1), src is 8-bit aligned (byte 1) + */ + ldrb r2, [r1] + ldrh r3, [r1, #0x01] + ldr ip, [r1, #0x03] + strb r2, [r0] + ldr r2, [r1, #0x07] + ldrb r1, [r1, #0x0b] + strh r3, [r0, #0x01] + str ip, [r0, #0x03] + str r2, [r0, #0x07] + strb r1, [r0, #0x0b] + bx lr + LMEMCPY_C_PAD + +/* + * 0110: dst is 8-bit aligned (byte 1), src is 16-bit aligned + */ + ldrh r2, [r1] /* BE:r2 = ..01 LE:r2 = ..10 */ + ldr r3, [r1, #0x02] /* BE:r3 = 2345 LE:r3 = 5432 */ + ldr ip, [r1, #0x06] /* BE:ip = 6789 LE:ip = 9876 */ + ldrh r1, [r1, #0x0a] /* BE:r1 = ..AB LE:r1 = ..BA */ +#ifdef __ARMEB__ + mov r2, r2, ror #8 /* r2 = 1..0 */ + strb r2, [r0] + mov r2, r2, lsr #16 /* r2 = ..1. */ + orr r2, r2, r3, lsr #24 /* r2 = ..12 */ + strh r2, [r0, #0x01] + mov r2, r3, lsl #8 /* r2 = 345. */ + orr r3, r2, ip, lsr #24 /* r3 = 3456 */ + mov r2, ip, lsl #8 /* r2 = 789. */ + orr r2, r2, r1, lsr #8 /* r2 = 789A */ +#else + strb r2, [r0] + mov r2, r2, lsr #8 /* r2 = ...1 */ + orr r2, r2, r3, lsl #8 /* r2 = 4321 */ + strh r2, [r0, #0x01] + mov r2, r3, lsr #8 /* r2 = .543 */ + orr r3, r2, ip, lsl #24 /* r3 = 6543 */ + mov r2, ip, lsr #8 /* r2 = .987 */ + orr r2, r2, r1, lsl #24 /* r2 = A987 */ + mov r1, r1, lsr #8 /* r1 = ...B */ +#endif + str r3, [r0, #0x03] + str r2, [r0, #0x07] + strb r1, [r0, #0x0b] + bx lr + LMEMCPY_C_PAD + +/* + * 0111: dst is 8-bit aligned (byte 1), src is 8-bit aligned (byte 3) + */ + ldrb r2, [r1] + ldr r3, [r1, #0x01] /* BE:r3 = 1234 LE:r3 = 4321 */ + ldr ip, [r1, #0x05] /* BE:ip = 5678 LE:ip = 8765 */ + ldr r1, [r1, #0x09] /* BE:r1 = 9ABx LE:r1 = xBA9 */ + strb r2, [r0] +#ifdef __ARMEB__ + mov r2, r3, lsr #16 /* r2 = ..12 */ + strh r2, [r0, #0x01] + mov r3, r3, lsl #16 /* r3 = 34.. */ + orr r3, r3, ip, lsr #16 /* r3 = 3456 */ + mov ip, ip, lsl #16 /* ip = 78.. */ + orr ip, ip, r1, lsr #16 /* ip = 789A */ + mov r1, r1, lsr #8 /* r1 = .9AB */ +#else + strh r3, [r0, #0x01] + mov r3, r3, lsr #16 /* r3 = ..43 */ + orr r3, r3, ip, lsl #16 /* r3 = 6543 */ + mov ip, ip, lsr #16 /* ip = ..87 */ + orr ip, ip, r1, lsl #16 /* ip = A987 */ + mov r1, r1, lsr #16 /* r1 = ..xB */ +#endif + str r3, [r0, #0x03] + str ip, [r0, #0x07] + strb r1, [r0, #0x0b] + bx lr + LMEMCPY_C_PAD + +/* + * 1000: dst is 16-bit aligned, src is 32-bit aligned + */ + ldr ip, [r1] /* BE:ip = 0123 LE:ip = 3210 */ + ldr r3, [r1, #0x04] /* BE:r3 = 4567 LE:r3 = 7654 */ + ldr r2, [r1, #0x08] /* BE:r2 = 89AB LE:r2 = BA98 */ + mov r1, ip, lsr #16 /* BE:r1 = ..01 LE:r1 = ..32 */ +#ifdef __ARMEB__ + strh r1, [r0] + mov r1, ip, lsl #16 /* r1 = 23.. */ + orr r1, r1, r3, lsr #16 /* r1 = 2345 */ + mov r3, r3, lsl #16 /* r3 = 67.. */ + orr r3, r3, r2, lsr #16 /* r3 = 6789 */ +#else + strh ip, [r0] + orr r1, r1, r3, lsl #16 /* r1 = 5432 */ + mov r3, r3, lsr #16 /* r3 = ..76 */ + orr r3, r3, r2, lsl #16 /* r3 = 9876 */ + mov r2, r2, lsr #16 /* r2 = ..BA */ +#endif + str r1, [r0, #0x02] + str r3, [r0, #0x06] + strh r2, [r0, #0x0a] + bx lr + LMEMCPY_C_PAD + +/* + * 1001: dst is 16-bit aligned, src is 8-bit aligned (byte 1) + */ + ldr r2, [r1, #-1] /* BE:r2 = x012 LE:r2 = 210x */ + ldr r3, [r1, #0x03] /* BE:r3 = 3456 LE:r3 = 6543 */ + mov ip, r2, lsr #8 /* BE:ip = .x01 LE:ip = .210 */ + strh ip, [r0] + ldr ip, [r1, #0x07] /* BE:ip = 789A LE:ip = A987 */ + ldrb r1, [r1, #0x0b] /* r1 = ...B */ +#ifdef __ARMEB__ + mov r2, r2, lsl #24 /* r2 = 2... */ + orr r2, r2, r3, lsr #8 /* r2 = 2345 */ + mov r3, r3, lsl #24 /* r3 = 6... */ + orr r3, r3, ip, lsr #8 /* r3 = 6789 */ + orr r1, r1, ip, lsl #8 /* r1 = 89AB */ +#else + mov r2, r2, lsr #24 /* r2 = ...2 */ + orr r2, r2, r3, lsl #8 /* r2 = 5432 */ + mov r3, r3, lsr #24 /* r3 = ...6 */ + orr r3, r3, ip, lsl #8 /* r3 = 9876 */ + mov r1, r1, lsl #8 /* r1 = ..B. */ + orr r1, r1, ip, lsr #24 /* r1 = ..BA */ +#endif + str r2, [r0, #0x02] + str r3, [r0, #0x06] + strh r1, [r0, #0x0a] + bx lr + LMEMCPY_C_PAD + +/* + * 1010: dst is 16-bit aligned, src is 16-bit aligned + */ + ldrh r2, [r1] + ldr r3, [r1, #0x02] + ldr ip, [r1, #0x06] + ldrh r1, [r1, #0x0a] + strh r2, [r0] + str r3, [r0, #0x02] + str ip, [r0, #0x06] + strh r1, [r0, #0x0a] + bx lr + LMEMCPY_C_PAD + +/* + * 1011: dst is 16-bit aligned, src is 8-bit aligned (byte 3) + */ + ldr r2, [r1, #0x09] /* BE:r2 = 9ABx LE:r2 = xBA9 */ + ldr r3, [r1, #0x05] /* BE:r3 = 5678 LE:r3 = 8765 */ + mov ip, r2, lsr #8 /* BE:ip = .9AB LE:ip = .xBA */ + strh ip, [r0, #0x0a] + ldr ip, [r1, #0x01] /* BE:ip = 1234 LE:ip = 4321 */ + ldrb r1, [r1] /* r1 = ...0 */ +#ifdef __ARMEB__ + mov r2, r2, lsr #24 /* r2 = ...9 */ + orr r2, r2, r3, lsl #8 /* r2 = 6789 */ + mov r3, r3, lsr #24 /* r3 = ...5 */ + orr r3, r3, ip, lsl #8 /* r3 = 2345 */ + mov r1, r1, lsl #8 /* r1 = ..0. */ + orr r1, r1, ip, lsr #24 /* r1 = ..01 */ +#else + mov r2, r2, lsl #24 /* r2 = 9... */ + orr r2, r2, r3, lsr #8 /* r2 = 9876 */ + mov r3, r3, lsl #24 /* r3 = 5... */ + orr r3, r3, ip, lsr #8 /* r3 = 5432 */ + orr r1, r1, ip, lsl #8 /* r1 = 3210 */ +#endif + str r2, [r0, #0x06] + str r3, [r0, #0x02] + strh r1, [r0] + bx lr + LMEMCPY_C_PAD + +/* + * 1100: dst is 8-bit aligned (byte 3), src is 32-bit aligned + */ + ldr r2, [r1] /* BE:r2 = 0123 LE:r2 = 3210 */ + ldr ip, [r1, #0x04] /* BE:ip = 4567 LE:ip = 7654 */ + ldr r1, [r1, #0x08] /* BE:r1 = 89AB LE:r1 = BA98 */ +#ifdef __ARMEB__ + mov r3, r2, lsr #24 /* r3 = ...0 */ + strb r3, [r0] + mov r2, r2, lsl #8 /* r2 = 123. */ + orr r2, r2, ip, lsr #24 /* r2 = 1234 */ + str r2, [r0, #0x01] + mov r2, ip, lsl #8 /* r2 = 567. */ + orr r2, r2, r1, lsr #24 /* r2 = 5678 */ + str r2, [r0, #0x05] + mov r2, r1, lsr #8 /* r2 = ..9A */ + strh r2, [r0, #0x09] + strb r1, [r0, #0x0b] +#else + strb r2, [r0] + mov r3, r2, lsr #8 /* r3 = .321 */ + orr r3, r3, ip, lsl #24 /* r3 = 4321 */ + str r3, [r0, #0x01] + mov r3, ip, lsr #8 /* r3 = .765 */ + orr r3, r3, r1, lsl #24 /* r3 = 8765 */ + str r3, [r0, #0x05] + mov r1, r1, lsr #8 /* r1 = .BA9 */ + strh r1, [r0, #0x09] + mov r1, r1, lsr #16 /* r1 = ...B */ + strb r1, [r0, #0x0b] +#endif + bx lr + LMEMCPY_C_PAD + +/* + * 1101: dst is 8-bit aligned (byte 3), src is 8-bit aligned (byte 1) + */ + ldrb r2, [r1, #0x0b] /* r2 = ...B */ + ldr r3, [r1, #0x07] /* BE:r3 = 789A LE:r3 = A987 */ + ldr ip, [r1, #0x03] /* BE:ip = 3456 LE:ip = 6543 */ + ldr r1, [r1, #-1] /* BE:r1 = x012 LE:r1 = 210x */ + strb r2, [r0, #0x0b] +#ifdef __ARMEB__ + strh r3, [r0, #0x09] + mov r3, r3, lsr #16 /* r3 = ..78 */ + orr r3, r3, ip, lsl #16 /* r3 = 5678 */ + mov ip, ip, lsr #16 /* ip = ..34 */ + orr ip, ip, r1, lsl #16 /* ip = 1234 */ + mov r1, r1, lsr #16 /* r1 = ..x0 */ +#else + mov r2, r3, lsr #16 /* r2 = ..A9 */ + strh r2, [r0, #0x09] + mov r3, r3, lsl #16 /* r3 = 87.. */ + orr r3, r3, ip, lsr #16 /* r3 = 8765 */ + mov ip, ip, lsl #16 /* ip = 43.. */ + orr ip, ip, r1, lsr #16 /* ip = 4321 */ + mov r1, r1, lsr #8 /* r1 = .210 */ +#endif + str r3, [r0, #0x05] + str ip, [r0, #0x01] + strb r1, [r0] + bx lr + LMEMCPY_C_PAD + +/* + * 1110: dst is 8-bit aligned (byte 3), src is 16-bit aligned + */ +#ifdef __ARMEB__ + ldrh r2, [r1, #0x0a] /* r2 = ..AB */ + ldr ip, [r1, #0x06] /* ip = 6789 */ + ldr r3, [r1, #0x02] /* r3 = 2345 */ + ldrh r1, [r1] /* r1 = ..01 */ + strb r2, [r0, #0x0b] + mov r2, r2, lsr #8 /* r2 = ...A */ + orr r2, r2, ip, lsl #8 /* r2 = 789A */ + mov ip, ip, lsr #8 /* ip = .678 */ + orr ip, ip, r3, lsl #24 /* ip = 5678 */ + mov r3, r3, lsr #8 /* r3 = .234 */ + orr r3, r3, r1, lsl #24 /* r3 = 1234 */ + mov r1, r1, lsr #8 /* r1 = ...0 */ + strb r1, [r0] + str r3, [r0, #0x01] + str ip, [r0, #0x05] + strh r2, [r0, #0x09] +#else + ldrh r2, [r1] /* r2 = ..10 */ + ldr r3, [r1, #0x02] /* r3 = 5432 */ + ldr ip, [r1, #0x06] /* ip = 9876 */ + ldrh r1, [r1, #0x0a] /* r1 = ..BA */ + strb r2, [r0] + mov r2, r2, lsr #8 /* r2 = ...1 */ + orr r2, r2, r3, lsl #8 /* r2 = 4321 */ + mov r3, r3, lsr #24 /* r3 = ...5 */ + orr r3, r3, ip, lsl #8 /* r3 = 8765 */ + mov ip, ip, lsr #24 /* ip = ...9 */ + orr ip, ip, r1, lsl #8 /* ip = .BA9 */ + mov r1, r1, lsr #8 /* r1 = ...B */ + str r2, [r0, #0x01] + str r3, [r0, #0x05] + strh ip, [r0, #0x09] + strb r1, [r0, #0x0b] +#endif + bx lr + LMEMCPY_C_PAD + +/* + * 1111: dst is 8-bit aligned (byte 3), src is 8-bit aligned (byte 3) + */ + ldrb r2, [r1] + ldr r3, [r1, #0x01] + ldr ip, [r1, #0x05] + strb r2, [r0] + ldrh r2, [r1, #0x09] + ldrb r1, [r1, #0x0b] + str r3, [r0, #0x01] + str ip, [r0, #0x05] + strh r2, [r0, #0x09] + strb r1, [r0, #0x0b] + bx lr +#endif /* !_STANDALONE */ +END(memcpy) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/memmove.S b/lib/libc/arm/string/memmove.S new file mode 100644 index 0000000..118643e --- /dev/null +++ b/lib/libc/arm/string/memmove.S @@ -0,0 +1,613 @@ +/* $NetBSD: memmove.S,v 1.4 2003/10/14 07:51:45 scw Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/string/memmove.S 288373 2015-09-29 16:09:58Z kib $"); + +.syntax unified + +#ifndef _BCOPY +/* LINTSTUB: Func: void *memmove(void *, const void *, size_t) */ +ENTRY(memmove) +#else +/* bcopy = memcpy/memmove with arguments reversed. */ +/* LINTSTUB: Func: void bcopy(void *, void *, size_t) */ +ENTRY(bcopy) + /* switch the source and destination registers */ + eor r0, r1, r0 + eor r1, r0, r1 + eor r0, r1, r0 +#endif + /* Do the buffers overlap? */ + cmp r0, r1 + it eq + RETeq /* Bail now if src/dst are the same */ + ite cc + subcc r3, r0, r1 /* if (dst > src) r3 = dst - src */ + subcs r3, r1, r0 /* if (src > dsr) r3 = src - dst */ + cmp r3, r2 /* if (r3 < len) we have an overlap */ + bcc PIC_SYM(_C_LABEL(memcpy), PLT) + + /* Determine copy direction */ + cmp r1, r0 + it cc + bcc .Lmemmove_backwards + + itt eq + moveq r0, #0 /* Quick abort for len=0 */ + RETeq + + stmdb sp!, {r0, lr} /* memmove() returns dest addr */ + subs r2, r2, #4 + blt .Lmemmove_fl4 /* less than 4 bytes */ + ands r12, r0, #3 + bne .Lmemmove_fdestul /* oh unaligned destination addr */ + ands r12, r1, #3 + bne .Lmemmove_fsrcul /* oh unaligned source addr */ + +.Lmemmove_ft8: + /* We have aligned source and destination */ + subs r2, r2, #8 + blt .Lmemmove_fl12 /* less than 12 bytes (4 from above) */ + subs r2, r2, #0x14 + blt .Lmemmove_fl32 /* less than 32 bytes (12 from above) */ + stmdb sp!, {r4} /* borrow r4 */ + + /* blat 32 bytes at a time */ + /* XXX for really big copies perhaps we should use more registers */ +.Lmemmove_floop32: + ldmia r1!, {r3, r4, r12, lr} + stmia r0!, {r3, r4, r12, lr} + ldmia r1!, {r3, r4, r12, lr} + stmia r0!, {r3, r4, r12, lr} + subs r2, r2, #0x20 + bge .Lmemmove_floop32 + + cmn r2, #0x10 + ittt ge + ldmiage r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ + stmiage r0!, {r3, r4, r12, lr} + subge r2, r2, #0x10 + ldmia sp!, {r4} /* return r4 */ + +.Lmemmove_fl32: + adds r2, r2, #0x14 + + /* blat 12 bytes at a time */ +.Lmemmove_floop12: + ittt ge + ldmiage r1!, {r3, r12, lr} + stmiage r0!, {r3, r12, lr} + subsge r2, r2, #0x0c + bge .Lmemmove_floop12 + +.Lmemmove_fl12: + adds r2, r2, #8 + blt .Lmemmove_fl4 + + subs r2, r2, #4 + itt lt + ldrlt r3, [r1], #4 + strlt r3, [r0], #4 + ittt ge + ldmiage r1!, {r3, r12} + stmiage r0!, {r3, r12} + subge r2, r2, #4 + +.Lmemmove_fl4: + /* less than 4 bytes to go */ + adds r2, r2, #4 + it eq + ldmiaeq sp!, {r0, pc} /* done */ + + /* copy the crud byte at a time */ + cmp r2, #2 + ldrb r3, [r1], #1 + strb r3, [r0], #1 + itt ge + ldrbge r3, [r1], #1 + strbge r3, [r0], #1 + itt gt + ldrbgt r3, [r1], #1 + strbgt r3, [r0], #1 + ldmia sp!, {r0, pc} + + /* erg - unaligned destination */ +.Lmemmove_fdestul: + rsb r12, r12, #4 + cmp r12, #2 + + /* align destination with byte copies */ + ldrb r3, [r1], #1 + strb r3, [r0], #1 + itt ge + ldrbge r3, [r1], #1 + strbge r3, [r0], #1 + itt gt + ldrbgt r3, [r1], #1 + strbgt r3, [r0], #1 + subs r2, r2, r12 + blt .Lmemmove_fl4 /* less the 4 bytes */ + + ands r12, r1, #3 + beq .Lmemmove_ft8 /* we have an aligned source */ + + /* erg - unaligned source */ + /* This is where it gets nasty ... */ +.Lmemmove_fsrcul: + bic r1, r1, #3 + ldr lr, [r1], #4 + cmp r12, #2 + bgt .Lmemmove_fsrcul3 + beq .Lmemmove_fsrcul2 + cmp r2, #0x0c + blt .Lmemmove_fsrcul1loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5} + +.Lmemmove_fsrcul1loop16: +#ifdef __ARMEB__ + mov r3, lr, lsl #8 +#else + mov r3, lr, lsr #8 +#endif + ldmia r1!, {r4, r5, r12, lr} +#ifdef __ARMEB__ + orr r3, r3, r4, lsr #24 + mov r4, r4, lsl #8 + orr r4, r4, r5, lsr #24 + mov r5, r5, lsl #8 + orr r5, r5, r12, lsr #24 + mov r12, r12, lsl #8 + orr r12, r12, lr, lsr #24 +#else + orr r3, r3, r4, lsl #24 + mov r4, r4, lsr #8 + orr r4, r4, r5, lsl #24 + mov r5, r5, lsr #8 + orr r5, r5, r12, lsl #24 + mov r12, r12, lsr #8 + orr r12, r12, lr, lsl #24 +#endif + stmia r0!, {r3-r5, r12} + subs r2, r2, #0x10 + bge .Lmemmove_fsrcul1loop16 + ldmia sp!, {r4, r5} + adds r2, r2, #0x0c + blt .Lmemmove_fsrcul1l4 + +.Lmemmove_fsrcul1loop4: +#ifdef __ARMEB__ + mov r12, lr, lsl #8 +#else + mov r12, lr, lsr #8 +#endif + ldr lr, [r1], #4 +#ifdef __ARMEB__ + orr r12, r12, lr, lsr #24 +#else + orr r12, r12, lr, lsl #24 +#endif + str r12, [r0], #4 + subs r2, r2, #4 + bge .Lmemmove_fsrcul1loop4 + +.Lmemmove_fsrcul1l4: + sub r1, r1, #3 + b .Lmemmove_fl4 + +.Lmemmove_fsrcul2: + cmp r2, #0x0c + blt .Lmemmove_fsrcul2loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5} + +.Lmemmove_fsrcul2loop16: +#ifdef __ARMEB__ + mov r3, lr, lsl #16 +#else + mov r3, lr, lsr #16 +#endif + ldmia r1!, {r4, r5, r12, lr} +#ifdef __ARMEB__ + orr r3, r3, r4, lsr #16 + mov r4, r4, lsl #16 + orr r4, r4, r5, lsr #16 + mov r5, r5, lsl #16 + orr r5, r5, r12, lsr #16 + mov r12, r12, lsl #16 + orr r12, r12, lr, lsr #16 +#else + orr r3, r3, r4, lsl #16 + mov r4, r4, lsr #16 + orr r4, r4, r5, lsl #16 + mov r5, r5, lsr #16 + orr r5, r5, r12, lsl #16 + mov r12, r12, lsr #16 + orr r12, r12, lr, lsl #16 +#endif + stmia r0!, {r3-r5, r12} + subs r2, r2, #0x10 + bge .Lmemmove_fsrcul2loop16 + ldmia sp!, {r4, r5} + adds r2, r2, #0x0c + blt .Lmemmove_fsrcul2l4 + +.Lmemmove_fsrcul2loop4: +#ifdef __ARMEB__ + mov r12, lr, lsl #16 +#else + mov r12, lr, lsr #16 +#endif + ldr lr, [r1], #4 +#ifdef __ARMEB__ + orr r12, r12, lr, lsr #16 +#else + orr r12, r12, lr, lsl #16 +#endif + str r12, [r0], #4 + subs r2, r2, #4 + bge .Lmemmove_fsrcul2loop4 + +.Lmemmove_fsrcul2l4: + sub r1, r1, #2 + b .Lmemmove_fl4 + +.Lmemmove_fsrcul3: + cmp r2, #0x0c + blt .Lmemmove_fsrcul3loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5} + +.Lmemmove_fsrcul3loop16: +#ifdef __ARMEB__ + mov r3, lr, lsl #24 +#else + mov r3, lr, lsr #24 +#endif + ldmia r1!, {r4, r5, r12, lr} +#ifdef __ARMEB__ + orr r3, r3, r4, lsr #8 + mov r4, r4, lsl #24 + orr r4, r4, r5, lsr #8 + mov r5, r5, lsl #24 + orr r5, r5, r12, lsr #8 + mov r12, r12, lsl #24 + orr r12, r12, lr, lsr #8 +#else + orr r3, r3, r4, lsl #8 + mov r4, r4, lsr #24 + orr r4, r4, r5, lsl #8 + mov r5, r5, lsr #24 + orr r5, r5, r12, lsl #8 + mov r12, r12, lsr #24 + orr r12, r12, lr, lsl #8 +#endif + stmia r0!, {r3-r5, r12} + subs r2, r2, #0x10 + bge .Lmemmove_fsrcul3loop16 + ldmia sp!, {r4, r5} + adds r2, r2, #0x0c + blt .Lmemmove_fsrcul3l4 + +.Lmemmove_fsrcul3loop4: +#ifdef __ARMEB__ + mov r12, lr, lsl #24 +#else + mov r12, lr, lsr #24 +#endif + ldr lr, [r1], #4 +#ifdef __ARMEB__ + orr r12, r12, lr, lsr #8 +#else + orr r12, r12, lr, lsl #8 +#endif + str r12, [r0], #4 + subs r2, r2, #4 + bge .Lmemmove_fsrcul3loop4 + +.Lmemmove_fsrcul3l4: + sub r1, r1, #1 + b .Lmemmove_fl4 + +.Lmemmove_backwards: + add r1, r1, r2 + add r0, r0, r2 + subs r2, r2, #4 + blt .Lmemmove_bl4 /* less than 4 bytes */ + ands r12, r0, #3 + bne .Lmemmove_bdestul /* oh unaligned destination addr */ + ands r12, r1, #3 + bne .Lmemmove_bsrcul /* oh unaligned source addr */ + +.Lmemmove_bt8: + /* We have aligned source and destination */ + subs r2, r2, #8 + blt .Lmemmove_bl12 /* less than 12 bytes (4 from above) */ + stmdb sp!, {r4, lr} + subs r2, r2, #0x14 /* less than 32 bytes (12 from above) */ + blt .Lmemmove_bl32 + + /* blat 32 bytes at a time */ + /* XXX for really big copies perhaps we should use more registers */ +.Lmemmove_bloop32: + ldmdb r1!, {r3, r4, r12, lr} + stmdb r0!, {r3, r4, r12, lr} + ldmdb r1!, {r3, r4, r12, lr} + stmdb r0!, {r3, r4, r12, lr} + subs r2, r2, #0x20 + bge .Lmemmove_bloop32 + +.Lmemmove_bl32: + cmn r2, #0x10 + ittt ge + ldmdbge r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ + stmdbge r0!, {r3, r4, r12, lr} + subge r2, r2, #0x10 + adds r2, r2, #0x14 + ittt ge + ldmdbge r1!, {r3, r12, lr} /* blat a remaining 12 bytes */ + stmdbge r0!, {r3, r12, lr} + subge r2, r2, #0x0c + ldmia sp!, {r4, lr} + +.Lmemmove_bl12: + adds r2, r2, #8 + blt .Lmemmove_bl4 + subs r2, r2, #4 + itt lt + ldrlt r3, [r1, #-4]! + strlt r3, [r0, #-4]! + ittt ge + ldmdbge r1!, {r3, r12} + stmdbge r0!, {r3, r12} + subge r2, r2, #4 + +.Lmemmove_bl4: + /* less than 4 bytes to go */ + adds r2, r2, #4 + it eq + RETeq /* done */ + + /* copy the crud byte at a time */ + cmp r2, #2 + ldrb r3, [r1, #-1]! + strb r3, [r0, #-1]! + itt ge + ldrbge r3, [r1, #-1]! + strbge r3, [r0, #-1]! + itt gt + ldrbgt r3, [r1, #-1]! + strbgt r3, [r0, #-1]! + RET + + /* erg - unaligned destination */ +.Lmemmove_bdestul: + cmp r12, #2 + + /* align destination with byte copies */ + ldrb r3, [r1, #-1]! + strb r3, [r0, #-1]! + itt ge + ldrbge r3, [r1, #-1]! + strbge r3, [r0, #-1]! + itt gt + ldrbgt r3, [r1, #-1]! + strbgt r3, [r0, #-1]! + subs r2, r2, r12 + blt .Lmemmove_bl4 /* less than 4 bytes to go */ + ands r12, r1, #3 + beq .Lmemmove_bt8 /* we have an aligned source */ + + /* erg - unaligned source */ + /* This is where it gets nasty ... */ +.Lmemmove_bsrcul: + bic r1, r1, #3 + ldr r3, [r1, #0] + cmp r12, #2 + blt .Lmemmove_bsrcul1 + beq .Lmemmove_bsrcul2 + cmp r2, #0x0c + blt .Lmemmove_bsrcul3loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5, lr} + +.Lmemmove_bsrcul3loop16: +#ifdef __ARMEB__ + mov lr, r3, lsr #8 +#else + mov lr, r3, lsl #8 +#endif + ldmdb r1!, {r3-r5, r12} +#ifdef __ARMEB__ + orr lr, lr, r12, lsl #24 + mov r12, r12, lsr #8 + orr r12, r12, r5, lsl #24 + mov r5, r5, lsr #8 + orr r5, r5, r4, lsl #24 + mov r4, r4, lsr #8 + orr r4, r4, r3, lsl #24 +#else + orr lr, lr, r12, lsr #24 + mov r12, r12, lsl #8 + orr r12, r12, r5, lsr #24 + mov r5, r5, lsl #8 + orr r5, r5, r4, lsr #24 + mov r4, r4, lsl #8 + orr r4, r4, r3, lsr #24 +#endif + stmdb r0!, {r4, r5, r12, lr} + subs r2, r2, #0x10 + bge .Lmemmove_bsrcul3loop16 + ldmia sp!, {r4, r5, lr} + adds r2, r2, #0x0c + blt .Lmemmove_bsrcul3l4 + +.Lmemmove_bsrcul3loop4: +#ifdef __ARMEB__ + mov r12, r3, lsr #8 +#else + mov r12, r3, lsl #8 +#endif + ldr r3, [r1, #-4]! +#ifdef __ARMEB__ + orr r12, r12, r3, lsl #24 +#else + orr r12, r12, r3, lsr #24 +#endif + str r12, [r0, #-4]! + subs r2, r2, #4 + bge .Lmemmove_bsrcul3loop4 + +.Lmemmove_bsrcul3l4: + add r1, r1, #3 + b .Lmemmove_bl4 + +.Lmemmove_bsrcul2: + cmp r2, #0x0c + blt .Lmemmove_bsrcul2loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5, lr} + +.Lmemmove_bsrcul2loop16: +#ifdef __ARMEB__ + mov lr, r3, lsr #16 +#else + mov lr, r3, lsl #16 +#endif + ldmdb r1!, {r3-r5, r12} +#ifdef __ARMEB__ + orr lr, lr, r12, lsl #16 + mov r12, r12, lsr #16 + orr r12, r12, r5, lsl #16 + mov r5, r5, lsr #16 + orr r5, r5, r4, lsl #16 + mov r4, r4, lsr #16 + orr r4, r4, r3, lsl #16 +#else + orr lr, lr, r12, lsr #16 + mov r12, r12, lsl #16 + orr r12, r12, r5, lsr #16 + mov r5, r5, lsl #16 + orr r5, r5, r4, lsr #16 + mov r4, r4, lsl #16 + orr r4, r4, r3, lsr #16 +#endif + stmdb r0!, {r4, r5, r12, lr} + subs r2, r2, #0x10 + bge .Lmemmove_bsrcul2loop16 + ldmia sp!, {r4, r5, lr} + adds r2, r2, #0x0c + blt .Lmemmove_bsrcul2l4 + +.Lmemmove_bsrcul2loop4: +#ifdef __ARMEB__ + mov r12, r3, lsr #16 +#else + mov r12, r3, lsl #16 +#endif + ldr r3, [r1, #-4]! +#ifdef __ARMEB__ + orr r12, r12, r3, lsl #16 +#else + orr r12, r12, r3, lsr #16 +#endif + str r12, [r0, #-4]! + subs r2, r2, #4 + bge .Lmemmove_bsrcul2loop4 + +.Lmemmove_bsrcul2l4: + add r1, r1, #2 + b .Lmemmove_bl4 + +.Lmemmove_bsrcul1: + cmp r2, #0x0c + blt .Lmemmove_bsrcul1loop4 + sub r2, r2, #0x0c + stmdb sp!, {r4, r5, lr} + +.Lmemmove_bsrcul1loop32: +#ifdef __ARMEB__ + mov lr, r3, lsr #24 +#else + mov lr, r3, lsl #24 +#endif + ldmdb r1!, {r3-r5, r12} +#ifdef __ARMEB__ + orr lr, lr, r12, lsl #8 + mov r12, r12, lsr #24 + orr r12, r12, r5, lsl #8 + mov r5, r5, lsr #24 + orr r5, r5, r4, lsl #8 + mov r4, r4, lsr #24 + orr r4, r4, r3, lsl #8 +#else + orr lr, lr, r12, lsr #8 + mov r12, r12, lsl #24 + orr r12, r12, r5, lsr #8 + mov r5, r5, lsl #24 + orr r5, r5, r4, lsr #8 + mov r4, r4, lsl #24 + orr r4, r4, r3, lsr #8 +#endif + stmdb r0!, {r4, r5, r12, lr} + subs r2, r2, #0x10 + bge .Lmemmove_bsrcul1loop32 + ldmia sp!, {r4, r5, lr} + adds r2, r2, #0x0c + blt .Lmemmove_bsrcul1l4 + +.Lmemmove_bsrcul1loop4: +#ifdef __ARMEB__ + mov r12, r3, lsr #24 +#else + mov r12, r3, lsl #24 +#endif + ldr r3, [r1, #-4]! +#ifdef __ARMEB__ + orr r12, r12, r3, lsl #8 +#else + orr r12, r12, r3, lsr #8 +#endif + str r12, [r0, #-4]! + subs r2, r2, #4 + bge .Lmemmove_bsrcul1loop4 + +.Lmemmove_bsrcul1l4: + add r1, r1, #1 + b .Lmemmove_bl4 +#ifndef _BCOPY +END(memmove) +#else +END(bcopy) +#endif + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/memset.S b/lib/libc/arm/string/memset.S new file mode 100644 index 0000000..81b9f7f --- /dev/null +++ b/lib/libc/arm/string/memset.S @@ -0,0 +1,267 @@ +/* $NetBSD: memset.S,v 1.4 2003/10/14 07:51:45 scw Exp $ */ + +/* + * Copyright 2003 Wasabi Systems, Inc. + * All rights reserved. + * + * Written by Steve C. Woodford for Wasabi Systems, Inc. + * + * 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 for the NetBSD Project by + * Wasabi Systems, Inc. + * 4. The name of Wasabi Systems, Inc. may not be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC + * 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. + */ +/* + * Copyright (c) 1995 Mark Brinicombe. + * 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 Mark Brinicombe. + * 4. The name of the company nor the name of the author may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/string/memset.S 288373 2015-09-29 16:09:58Z kib $"); + +.syntax unified + +/* + * memset: Sets a block of memory to the specified value + * + * On entry: + * r0 - dest address + * r1 - byte to write + * r2 - number of bytes to write + * + * On exit: + * r0 - dest address + */ +#ifdef _BZERO +/* LINTSTUB: Func: void bzero(void *, size_t) */ +ENTRY(bzero) + mov r3, #0x00 +#else +/* LINTSTUB: Func: void *memset(void *, int, size_t) */ +ENTRY(memset) + and r3, r1, #0xff /* We deal with bytes */ + mov r1, r2 +#endif + cmp r1, #0x04 /* Do we have less than 4 bytes */ + mov ip, r0 + blt .Lmemset_lessthanfour + + /* Ok first we will word align the address */ + ands r2, ip, #0x03 /* Get the bottom two bits */ + bne .Lmemset_wordunaligned /* The address is not word aligned */ + + /* We are now word aligned */ +.Lmemset_wordaligned: +#ifndef _BZERO + orr r3, r3, r3, lsl #8 /* Extend value to 16-bits */ +#endif +#ifdef _ARM_ARCH_5E + tst ip, #0x04 /* Quad-align for armv5e */ +#else + cmp r1, #0x10 +#endif +#ifndef _BZERO + orr r3, r3, r3, lsl #16 /* Extend value to 32-bits */ +#endif +#ifdef _ARM_ARCH_5E + itt ne + subne r1, r1, #0x04 /* Quad-align if necessary */ + strne r3, [ip], #0x04 + cmp r1, #0x10 +#endif + blt .Lmemset_loop4 /* If less than 16 then use words */ + mov r2, r3 /* Duplicate data */ + cmp r1, #0x80 /* If < 128 then skip the big loop */ + blt .Lmemset_loop32 + + /* Do 128 bytes at a time */ +.Lmemset_loop128: + subs r1, r1, #0x80 +#ifdef _ARM_ARCH_5E + itttt ge + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + itttt ge + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + itttt ge + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + itttt ge + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 +#else + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} +#endif + bgt .Lmemset_loop128 + it eq + RETeq /* Zero length so just exit */ + + add r1, r1, #0x80 /* Adjust for extra sub */ + + /* Do 32 bytes at a time */ +.Lmemset_loop32: + subs r1, r1, #0x20 + itttt ge +#ifdef _ARM_ARCH_5E + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 +#else + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} +#endif + bgt .Lmemset_loop32 + it eq + RETeq /* Zero length so just exit */ + + adds r1, r1, #0x10 /* Partially adjust for extra sub */ + + /* Deal with 16 bytes or more */ + itt ge +#ifdef _ARM_ARCH_5E + strdge r2, [ip], #0x08 + strdge r2, [ip], #0x08 +#else + stmiage ip!, {r2-r3} + stmiage ip!, {r2-r3} +#endif + it eq + RETeq /* Zero length so just exit */ + + it lt + addlt r1, r1, #0x10 /* Possibly adjust for extra sub */ + + /* We have at least 4 bytes so copy as words */ +.Lmemset_loop4: + subs r1, r1, #0x04 + it ge + strge r3, [ip], #0x04 + bgt .Lmemset_loop4 + it eq + RETeq /* Zero length so just exit */ + +#ifdef _ARM_ARCH_5E + /* Compensate for 64-bit alignment check */ + adds r1, r1, #0x04 + it eq + RETeq + cmp r1, #2 +#else + cmp r1, #-2 +#endif + + strb r3, [ip], #0x01 /* Set 1 byte */ + it ge + strbge r3, [ip], #0x01 /* Set another byte */ + it gt + strbgt r3, [ip] /* and a third */ + RET /* Exit */ + +.Lmemset_wordunaligned: + rsb r2, r2, #0x004 + strb r3, [ip], #0x01 /* Set 1 byte */ + cmp r2, #0x02 + it ge + strbge r3, [ip], #0x01 /* Set another byte */ + sub r1, r1, r2 + it gt + strbgt r3, [ip], #0x01 /* and a third */ + cmp r1, #0x04 /* More than 4 bytes left? */ + it ge + bge .Lmemset_wordaligned /* Yup */ + +.Lmemset_lessthanfour: + cmp r1, #0x00 + it eq + RETeq /* Zero length so exit */ + strb r3, [ip], #0x01 /* Set 1 byte */ + cmp r1, #0x02 + it ge + strbge r3, [ip], #0x01 /* Set another byte */ + it gt + strbgt r3, [ip] /* and a third */ + RET /* Exit */ +#ifdef _BZERO +END(bzero) +#else +END(memset) +#endif + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/strcmp.S b/lib/libc/arm/string/strcmp.S new file mode 100644 index 0000000..b7eb5c2 --- /dev/null +++ b/lib/libc/arm/string/strcmp.S @@ -0,0 +1,47 @@ +/* $NetBSD: strcmp.S,v 1.3 2003/04/05 23:08:52 bjh21 Exp $ */ + +/* + * Copyright (c) 2002 ARM Ltd + * 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. The name of the company may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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 + +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/string/strcmp.S 288373 2015-09-29 16:09:58Z kib $"); + +ENTRY(strcmp) +1: + ldrb r2, [r0], #1 + ldrb r3, [r1], #1 + cmp r2, #1 + it cs + cmpcs r2, r3 + beq 1b + sub r0, r2, r3 + RET +END(strcmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/strlen.S b/lib/libc/arm/string/strlen.S new file mode 100644 index 0000000..57acf0b --- /dev/null +++ b/lib/libc/arm/string/strlen.S @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2005 Olivier Houchard + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/string/strlen.S 288373 2015-09-29 16:09:58Z kib $"); + +.syntax unified + +ENTRY(strlen) + mov r1, #0 + /* Check that the pointer is aligned on 32 bits. */ + ands r3, r0, #3 + beq .Loop + sub r0, r0, r3 + ldr r2, [r0] + add r0, r0, #4 + cmp r3, #2 + blt .Ldo_3 + bgt .Ldo_1 + /* So that the N bit is set. */ + cmp r3, #0 + b .Ldo_2 + +.Loop: + ldr r2, [r0] + add r0, r0, #4 +#ifndef __ARMEB__ + ands r3, r2, #0x000000ff +#else + ands r3, r2, #0xff000000 +#endif + it ne + addne r1, r1, #1 +.Ldo_3: + itt ne +#ifndef __ARMEB__ + andsne r3, r2, #0x0000ff00 +#else + andsne r3, r2, #0x00ff0000 +#endif + addne r1, r1, #1 +.Ldo_2: + itt ne +#ifndef __ARMEB__ + andsne r3, r2, #0x00ff0000 +#else + andsne r3, r2, #0x0000ff00 +#endif + addne r1, r1, #1 +.Ldo_1: + ittt ne +#ifndef __ARMEB__ + andsne r3, r2, #0xff000000 +#else + andsne r3, r2, #0x000000ff +#endif + addne r1, r1, #1 + bne .Loop +.Lexit: + mov r0, r1 + RET +END(strlen) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/string/strncmp.S b/lib/libc/arm/string/strncmp.S new file mode 100644 index 0000000..4184fc0 --- /dev/null +++ b/lib/libc/arm/string/strncmp.S @@ -0,0 +1,60 @@ +/* $NetBSD: strncmp.S,v 1.2 2003/04/05 23:08:52 bjh21 Exp $ */ + +/* + * Copyright (c) 2002 ARM Ltd + * 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. The name of the company may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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 + +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/string/strncmp.S 288373 2015-09-29 16:09:58Z kib $"); + +ENTRY(strncmp) +/* if (len == 0) return 0 */ + cmp r2, #0 + itt eq + moveq r0, #0 + moveq pc, lr + +/* ip == last src address to compare */ + adds ip, r0, r2 +/* Use last possible address on overflow. */ + it cs + movcs ip, #0 + sub ip, ip, #1 +1: + ldrb r2, [r0], #1 + ldrb r3, [r1], #1 + cmp ip, r0 + itt cs + cmpcs r2, #1 + cmpcs r2, r3 + beq 1b + sub r0, r2, r3 + RET +END(strncmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/Makefile.inc b/lib/libc/arm/sys/Makefile.inc new file mode 100644 index 0000000..cd0ed17 --- /dev/null +++ b/lib/libc/arm/sys/Makefile.inc @@ -0,0 +1,10 @@ +# $FreeBSD: releng/11.1/lib/libc/arm/sys/Makefile.inc 305329 2016-09-03 09:03:40Z kib $ + +SRCS+= __vdso_gettc.c + +MDASM= Ovfork.S brk.S cerror.S sbrk.S shmat.S sigreturn.S syscall.S + +# Don't generate default code for these syscalls: +NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o vfork.o yield.o + +PSEUDO= _exit.o _getlogin.o diff --git a/lib/libc/arm/sys/Ovfork.S b/lib/libc/arm/sys/Ovfork.S new file mode 100644 index 0000000..3ff739d --- /dev/null +++ b/lib/libc/arm/sys/Ovfork.S @@ -0,0 +1,57 @@ +/* $NetBSD: Ovfork.S,v 1.6 2003/08/07 16:42:03 agc 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. + * + * from: @(#)Ovfork.s 5.1 (Berkeley) 4/23/90 + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/sys/Ovfork.S 288373 2015-09-29 16:09:58Z kib $"); +#include "SYS.h" + +/* + * pid = vfork(); + * + * On return from the SWI: + * r1 == 0 in parent process, r1 == 1 in child process. + * r0 == pid of child in parent, r0 == pid of parent in child. + */ + .text + .align 0 + +ENTRY(vfork) + mov r2, r14 + SYSTRAP(vfork) + bcs PIC_SYM(CERROR, PLT) + sub r1, r1, #1 /* r1 == 0xffffffff if parent, 0 if child */ + and r0, r0, r1 /* r0 == 0 if child, else unchanged */ + mov r15, r2 +END(vfork) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/__vdso_gettc.c b/lib/libc/arm/sys/__vdso_gettc.c new file mode 100644 index 0000000..18b87be --- /dev/null +++ b/lib/libc/arm/sys/__vdso_gettc.c @@ -0,0 +1,89 @@ +/*- + * Copyright (c) 2015 The FreeBSD Foundation + * + * This software was developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/sys/__vdso_gettc.c 305866 2016-09-16 10:04:28Z kib $"); + +#include +#include +#include +#include +#include +#include +#include +#include "libc_private.h" + +#if __ARM_ARCH >= 6 +static inline uint64_t +cp15_cntvct_get(void) +{ + uint64_t reg; + + __asm __volatile("mrrc\tp15, 1, %Q0, %R0, c14" : "=r" (reg)); + return (reg); +} + +static inline uint64_t +cp15_cntpct_get(void) +{ + uint64_t reg; + + __asm __volatile("mrrc\tp15, 0, %Q0, %R0, c14" : "=r" (reg)); + return (reg); +} +#endif + +#pragma weak __vdso_gettc +int +__vdso_gettc(const struct vdso_timehands *th, u_int *tc) +{ + + if (th->th_algo != VDSO_TH_ALGO_ARM_GENTIM) + return (ENOSYS); +#if __ARM_ARCH >= 6 + /* + * Userspace gettimeofday() is only enabled on ARMv7 CPUs, but + * libc is compiled for ARMv6. Due to clang issues, .arch + * armv7-a directive does not work. + */ + __asm __volatile(".word\t0xf57ff06f" : : : "memory"); /* isb */ + *tc = th->th_physical == 0 ? cp15_cntvct_get() : cp15_cntpct_get(); + return (0); +#else + *tc = 0; + return (ENOSYS); +#endif +} + +#pragma weak __vdso_gettimekeep +int +__vdso_gettimekeep(struct vdso_timekeep **tk) +{ + + return (_elf_aux_info(AT_TIMEKEEP, tk, sizeof(*tk))); +} diff --git a/lib/libc/arm/sys/brk.S b/lib/libc/arm/sys/brk.S new file mode 100644 index 0000000..c2a1166 --- /dev/null +++ b/lib/libc/arm/sys/brk.S @@ -0,0 +1,95 @@ +/* $NetBSD: brk.S,v 1.6 2003/08/07 16:42:04 agc 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. + * + * from: @(#)brk.s 5.2 (Berkeley) 12/17/90 + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/sys/brk.S 288373 2015-09-29 16:09:58Z kib $"); +#include "SYS.h" + + .globl _C_LABEL(_end) + .globl CURBRK + +#ifdef WEAK_ALIAS +WEAK_ALIAS(brk, _brk) +#endif + + .data + .align 0 + .globl _C_LABEL(minbrk) + .type _C_LABEL(minbrk),#object +_C_LABEL(minbrk): + .word _C_LABEL(_end) + +/* + * Change the data segment size + */ +ENTRY(_brk) + /* Setup the GOT */ + GOT_INIT(r3, .Lgot, .L1) + GOT_GET(r1, r3, .Lminbrk) + + /* Get the minimum allowable brk address */ + ldr r1, [r1] + + /* + * Valid the address specified and set to the minimum + * if the address is below minbrk. + */ + cmp r0, r1 + it lt + movlt r0, r1 + mov r2, r0 + SYSTRAP(break) + bcs PIC_SYM(CERROR, PLT) + +#ifdef PIC + ldr r1, .Lcurbrk + ldr r1, [r3, r1] +#else + ldr r1, .Lcurbrk +#endif + /* Store the new address in curbrk */ + str r2, [r1] + + /* Return 0 for success */ + mov r0, #0x00000000 + RET + + .align 2 + GOT_INITSYM(.Lgot, .L1) +.Lminbrk: + .word PIC_SYM(_C_LABEL(minbrk), GOT) +.Lcurbrk: + .word PIC_SYM(CURBRK, GOT) +END(_brk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/cerror.S b/lib/libc/arm/sys/cerror.S new file mode 100644 index 0000000..fa3c976 --- /dev/null +++ b/lib/libc/arm/sys/cerror.S @@ -0,0 +1,51 @@ +/* $NetBSD: cerror.S,v 1.5 2003/08/07 16:42:04 agc 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. + * + * from: @(#)cerror.s 5.1 (Berkeley) 4/23/90 + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/sys/cerror.S 288373 2015-09-29 16:09:58Z kib $"); +#include "SYS.h" + +.globl _C_LABEL(__error) +.type _C_LABEL(__error),%function + +ASENTRY(CERROR) + stmfd sp!, {r4, lr} + mov r4, r0 + bl PIC_SYM(_C_LABEL(__error), PLT) + str r4, [r0] + mvn r0, #0x00000000 + mvn r1, #0x00000000 + ldmfd sp!, {r4, pc} +END(CERROR) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/sbrk.S b/lib/libc/arm/sys/sbrk.S new file mode 100644 index 0000000..3121693 --- /dev/null +++ b/lib/libc/arm/sys/sbrk.S @@ -0,0 +1,82 @@ +/* $NetBSD: sbrk.S,v 1.7 2003/08/07 16:42:05 agc 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. + * + * from: @(#)sbrk.s 5.1 (Berkeley) 4/23/90 + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/sys/sbrk.S 288373 2015-09-29 16:09:58Z kib $"); +#include "SYS.h" + + .globl _C_LABEL(_end) + +#ifdef WEAK_ALIAS +WEAK_ALIAS(sbrk, _sbrk) +#endif + + .data + .align 0 + .globl CURBRK + .type CURBRK,#object +CURBRK: + .word _C_LABEL(_end) + +/* + * Change the data segment size + */ +ENTRY(_sbrk) + /* Setup the GOT */ + GOT_INIT(r3, .Lgot, .L1) + GOT_GET(r2, r3, .Lcurbrk) + + /* Get the current brk address */ + ldr r1, [r2] + + /* Calculate new value */ + mov r3, r0 + add r0, r0, r1 + SYSTRAP(break) + bcs PIC_SYM(CERROR, PLT) + + /* Store new curbrk value */ + ldr r0, [r2] + add r1, r0, r3 + str r1, [r2] + + /* Return old curbrk value */ + RET + + .align 0 + GOT_INITSYM(.Lgot, .L1) +.Lcurbrk: + .word PIC_SYM(CURBRK, GOT) +END(_sbrk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/shmat.S b/lib/libc/arm/sys/shmat.S new file mode 100644 index 0000000..e433390 --- /dev/null +++ b/lib/libc/arm/sys/shmat.S @@ -0,0 +1,9 @@ +/* $NetBSD: shmat.S,v 1.1 2000/12/29 20:14:04 bjh21 Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/sys/shmat.S 288373 2015-09-29 16:09:58Z kib $"); +#include "SYS.h" + +RSYSCALL(shmat) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/sigreturn.S b/lib/libc/arm/sys/sigreturn.S new file mode 100644 index 0000000..86b2af9 --- /dev/null +++ b/lib/libc/arm/sys/sigreturn.S @@ -0,0 +1,44 @@ +/* $NetBSD: __sigreturn14.S,v 1.3 2003/08/07 16:42:03 agc 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. + * + * from: @(#)sigreturn.s 5.2 (Berkeley) 12/17/90" + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/sys/sigreturn.S 288373 2015-09-29 16:09:58Z kib $"); +#include "SYS.h" + +/* + * We must preserve the state of the registers as the user has set them up. + */ + +RSYSCALL(sigreturn) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/arm/sys/syscall.S b/lib/libc/arm/sys/syscall.S new file mode 100644 index 0000000..2701512 --- /dev/null +++ b/lib/libc/arm/sys/syscall.S @@ -0,0 +1,40 @@ +/* $NetBSD: syscall.S,v 1.4 2003/08/07 16:42:05 agc 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. + * + * from: @(#)syscall.s 5.1 (Berkeley) 4/23/90 + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/arm/sys/syscall.S 288373 2015-09-29 16:09:58Z kib $"); +#include "SYS.h" + +RSYSCALL(syscall) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/capability/Makefile.inc b/lib/libc/capability/Makefile.inc new file mode 100644 index 0000000..343f60f --- /dev/null +++ b/lib/libc/capability/Makefile.inc @@ -0,0 +1,18 @@ +# $FreeBSD: releng/11.1/lib/libc/capability/Makefile.inc 313240 2017-02-04 17:17:38Z ngie $ + +# capability sources +.PATH: ${SRCTOP}/sys/kern ${LIBC_SRCTOP}/capability + +SRCS+= subr_capability.c + +SYM_MAPS+= ${LIBC_SRCTOP}/capability/Symbol.map + +MAN+= cap_rights_init.3 + +MLINKS+=cap_rights_init.3 cap_rights_set.3 +MLINKS+=cap_rights_init.3 cap_rights_clear.3 +MLINKS+=cap_rights_init.3 cap_rights_is_set.3 +MLINKS+=cap_rights_init.3 cap_rights_is_valid.3 +MLINKS+=cap_rights_init.3 cap_rights_merge.3 +MLINKS+=cap_rights_init.3 cap_rights_remove.3 +MLINKS+=cap_rights_init.3 cap_rights_contains.3 diff --git a/lib/libc/capability/Symbol.map b/lib/libc/capability/Symbol.map new file mode 100644 index 0000000..e6b4385 --- /dev/null +++ b/lib/libc/capability/Symbol.map @@ -0,0 +1,14 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/capability/Symbol.map 255219 2013-09-05 00:09:56Z pjd $ + */ + +FBSD_1.3 { + __cap_rights_clear; + cap_rights_contains; + __cap_rights_init; + __cap_rights_is_set; + cap_rights_is_valid; + cap_rights_merge; + cap_rights_remove; + __cap_rights_set; +}; diff --git a/lib/libc/capability/cap_rights_init.3 b/lib/libc/capability/cap_rights_init.3 new file mode 100644 index 0000000..a1e7167 --- /dev/null +++ b/lib/libc/capability/cap_rights_init.3 @@ -0,0 +1,241 @@ +.\" +.\" Copyright (c) 2013 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by Pawel Jakub Dawidek under sponsorship +.\" from the FreeBSD Foundation. +.\" +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/capability/cap_rights_init.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.Dd March 27, 2014 +.Dt CAP_RIGHTS_INIT 3 +.Os +.Sh NAME +.Nm cap_rights_init , +.Nm cap_rights_set , +.Nm cap_rights_clear , +.Nm cap_rights_is_set , +.Nm cap_rights_is_valid , +.Nm cap_rights_merge , +.Nm cap_rights_remove , +.Nm cap_rights_contains +.Nd manage cap_rights_t structure +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/capsicum.h +.Ft cap_rights_t * +.Fn cap_rights_init "cap_rights_t *rights" "..." +.Ft cap_rights_t * +.Fn cap_rights_set "cap_rights_t *rights" "..." +.Ft cap_rights_t * +.Fn cap_rights_clear "cap_rights_t *rights" "..." +.Ft bool +.Fn cap_rights_is_set "const cap_rights_t *rights" "..." +.Ft bool +.Fn cap_rights_is_valid "const cap_rights_t *rights" +.Ft cap_rights_t * +.Fn cap_rights_merge "cap_rights_t *dst" "const cap_rights_t *src" +.Ft cap_rights_t * +.Fn cap_rights_remove "cap_rights_t *dst" "const cap_rights_t *src" +.Ft bool +.Fn cap_rights_contains "const cap_rights_t *big" "const cap_rights_t *little" +.Sh DESCRIPTION +The functions documented here allow to manage the +.Vt cap_rights_t +structure. +.Pp +Capability rights should be separated with comma when passed to the +.Fn cap_rights_init , +.Fn cap_rights_set , +.Fn cap_rights_clear +and +.Fn cap_rights_is_set +functions. +For example: +.Bd -literal +cap_rights_set(&rights, CAP_READ, CAP_WRITE, CAP_FSTAT, CAP_SEEK); +.Ed +.Pp +The complete list of the capability rights can be found in the +.Xr rights 4 +manual page. +.Pp +The +.Fn cap_rights_init +function initialize provided +.Vt cap_rights_t +structure. +Only properly initialized structure can be passed to the remaining functions. +For convenience the structure can be filled with capability rights instead of +calling the +.Fn cap_rights_set +function later. +For even more convenience pointer to the given structure is returned, so it can +be directly passed to +.Xr cap_rights_limit 2 : +.Bd -literal +cap_rights_t rights; + +if (cap_rights_limit(fd, cap_rights_init(&rights, CAP_READ, CAP_WRITE)) < 0) + err(1, "Unable to limit capability rights"); +.Ed +.Pp +The +.Fn cap_rights_set +function adds the given capability rights to the given +.Vt cap_rights_t +structure. +.Pp +The +.Fn cap_rights_clear +function removes the given capability rights from the given +.Vt cap_rights_t +structure. +.Pp +The +.Fn cap_rights_is_set +function checks if all the given capability rights are set for the given +.Vt cap_rights_t +structure. +.Pp +The +.Fn cap_rights_is_valid +function verifies if the given +.Vt cap_rights_t +structure is valid. +.Pp +The +.Fn cap_rights_merge +function merges all capability rights present in the +.Fa src +structure into the +.Fa dst +structure. +.Pp +The +.Fn cap_rights_remove +function removes all capability rights present in the +.Fa src +structure from the +.Fa dst +structure. +.Pp +The +.Fn cap_rights_contains +function checks if the +.Fa big +structure contains all capability rights present in the +.Fa little +structure. +.Sh RETURN VALUES +The functions never fail. +In case an invalid capability right or an invalid +.Vt cap_rights_t +structure is given as an argument, the program will be aborted. +.Pp +The +.Fn cap_rights_init , +.Fn cap_rights_set +and +.Fn cap_rights_clear +functions return pointer to the +.Vt cap_rights_t +structure given in the +.Fa rights +argument. +.Pp +The +.Fn cap_rights_merge +and +.Fn cap_rights_remove +functions return pointer to the +.Vt cap_rights_t +structure given in the +.Fa dst +argument. +.Pp +The +.Fn cap_rights_is_set +returns +.Va true +if all the given capability rights are set in the +.Fa rights +argument. +.Pp +The +.Fn cap_rights_is_valid +function performs various checks to see if the given +.Vt cap_rights_t +structure is valid and returns +.Va true +if it is. +.Pp +The +.Fn cap_rights_contains +function returns +.Va true +if all capability rights set in the +.Fa little +structure are also present in the +.Fa big +structure. +.Sh EXAMPLES +The following example demonstrates how to prepare a +.Vt cap_rights_t +structure to be passed to the +.Xr cap_rights_limit 2 +system call. +.Bd -literal +cap_rights_t rights; +int fd; + +fd = open("/tmp/foo", O_RDWR); +if (fd < 0) + err(1, "open() failed"); + +cap_rights_init(&rights, CAP_FSTAT, CAP_READ); + +if (allow_write_and_seek) + cap_rights_set(&rights, CAP_WRITE, CAP_SEEK); + +if (dont_allow_seek) + cap_rights_clear(&rights, CAP_SEEK); + +if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) + err(1, "cap_rights_limit() failed"); +.Ed +.Sh SEE ALSO +.Xr cap_rights_limit 2 , +.Xr open 2 , +.Xr capsicum 4 , +.Xr rights 4 +.Sh HISTORY +Support for capabilities and capabilities mode was developed as part of the +.Tn TrustedBSD +Project. +.Sh AUTHORS +This family of functions was created by +.An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net +under sponsorship from the FreeBSD Foundation. diff --git a/lib/libc/capability/subr_capability.c b/lib/libc/capability/subr_capability.c new file mode 100644 index 0000000..522c2ae --- /dev/null +++ b/lib/libc/capability/subr_capability.c @@ -0,0 +1,307 @@ +/*- + * Copyright (c) 2013 FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/sys/kern/subr_capability.c 291553 2015-12-01 02:48:42Z mjg $"); + +/* + * Note that this file is compiled into the kernel and into libc. + */ + +#include +#include + +#ifdef _KERNEL +#include + +#include +#else /* !_KERNEL */ +#include +#include +#include +#include +#include +#endif + +#ifdef _KERNEL +#define assert(exp) KASSERT((exp), ("%s:%u", __func__, __LINE__)) +#endif + +#define CAPARSIZE_MIN (CAP_RIGHTS_VERSION_00 + 2) +#define CAPARSIZE_MAX (CAP_RIGHTS_VERSION + 2) + +static __inline int +right_to_index(uint64_t right) +{ + static const int bit2idx[] = { + -1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, + 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + int idx; + + idx = CAPIDXBIT(right); + assert(idx >= 0 && idx < sizeof(bit2idx) / sizeof(bit2idx[0])); + return (bit2idx[idx]); +} + +static void +cap_rights_vset(cap_rights_t *rights, va_list ap) +{ + uint64_t right; + int i, n; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + n = CAPARSIZE(rights); + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + + for (;;) { + right = (uint64_t)va_arg(ap, unsigned long long); + if (right == 0) + break; + assert(CAPRVER(right) == 0); + i = right_to_index(right); + assert(i >= 0); + assert(i < n); + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + rights->cr_rights[i] |= right; + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + } +} + +static void +cap_rights_vclear(cap_rights_t *rights, va_list ap) +{ + uint64_t right; + int i, n; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + n = CAPARSIZE(rights); + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + + for (;;) { + right = (uint64_t)va_arg(ap, unsigned long long); + if (right == 0) + break; + assert(CAPRVER(right) == 0); + i = right_to_index(right); + assert(i >= 0); + assert(i < n); + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + rights->cr_rights[i] &= ~(right & 0x01FFFFFFFFFFFFFFULL); + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + } +} + +static bool +cap_rights_is_vset(const cap_rights_t *rights, va_list ap) +{ + uint64_t right; + int i, n; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + n = CAPARSIZE(rights); + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + + for (;;) { + right = (uint64_t)va_arg(ap, unsigned long long); + if (right == 0) + break; + assert(CAPRVER(right) == 0); + i = right_to_index(right); + assert(i >= 0); + assert(i < n); + assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right)); + if ((rights->cr_rights[i] & right) != right) + return (false); + } + + return (true); +} + +cap_rights_t * +__cap_rights_init(int version, cap_rights_t *rights, ...) +{ + unsigned int n; + va_list ap; + + assert(version == CAP_RIGHTS_VERSION_00); + + n = version + 2; + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + CAP_NONE(rights); + va_start(ap, rights); + cap_rights_vset(rights, ap); + va_end(ap); + + return (rights); +} + +cap_rights_t * +__cap_rights_set(cap_rights_t *rights, ...) +{ + va_list ap; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + va_start(ap, rights); + cap_rights_vset(rights, ap); + va_end(ap); + + return (rights); +} + +cap_rights_t * +__cap_rights_clear(cap_rights_t *rights, ...) +{ + va_list ap; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + va_start(ap, rights); + cap_rights_vclear(rights, ap); + va_end(ap); + + return (rights); +} + +bool +__cap_rights_is_set(const cap_rights_t *rights, ...) +{ + va_list ap; + bool ret; + + assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00); + + va_start(ap, rights); + ret = cap_rights_is_vset(rights, ap); + va_end(ap); + + return (ret); +} + +bool +cap_rights_is_valid(const cap_rights_t *rights) +{ + cap_rights_t allrights; + int i, j; + + if (CAPVER(rights) != CAP_RIGHTS_VERSION_00) + return (false); + if (CAPARSIZE(rights) < CAPARSIZE_MIN || + CAPARSIZE(rights) > CAPARSIZE_MAX) { + return (false); + } + CAP_ALL(&allrights); + if (!cap_rights_contains(&allrights, rights)) + return (false); + for (i = 0; i < CAPARSIZE(rights); i++) { + j = right_to_index(rights->cr_rights[i]); + if (i != j) + return (false); + if (i > 0) { + if (CAPRVER(rights->cr_rights[i]) != 0) + return (false); + } + } + + return (true); +} + +cap_rights_t * +cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src) +{ + unsigned int i, n; + + assert(CAPVER(dst) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(src) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(dst) == CAPVER(src)); + assert(cap_rights_is_valid(src)); + assert(cap_rights_is_valid(dst)); + + n = CAPARSIZE(dst); + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + + for (i = 0; i < n; i++) + dst->cr_rights[i] |= src->cr_rights[i]; + + assert(cap_rights_is_valid(src)); + assert(cap_rights_is_valid(dst)); + + return (dst); +} + +cap_rights_t * +cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src) +{ + unsigned int i, n; + + assert(CAPVER(dst) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(src) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(dst) == CAPVER(src)); + assert(cap_rights_is_valid(src)); + assert(cap_rights_is_valid(dst)); + + n = CAPARSIZE(dst); + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + + for (i = 0; i < n; i++) { + dst->cr_rights[i] &= + ~(src->cr_rights[i] & 0x01FFFFFFFFFFFFFFULL); + } + + assert(cap_rights_is_valid(src)); + assert(cap_rights_is_valid(dst)); + + return (dst); +} + +bool +cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little) +{ + unsigned int i, n; + + assert(CAPVER(big) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(little) == CAP_RIGHTS_VERSION_00); + assert(CAPVER(big) == CAPVER(little)); + + n = CAPARSIZE(big); + assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX); + + for (i = 0; i < n; i++) { + if ((big->cr_rights[i] & little->cr_rights[i]) != + little->cr_rights[i]) { + return (false); + } + } + + return (true); +} diff --git a/lib/libc/compat-43/Makefile.inc b/lib/libc/compat-43/Makefile.inc new file mode 100644 index 0000000..42c5b19 --- /dev/null +++ b/lib/libc/compat-43/Makefile.inc @@ -0,0 +1,24 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/2/93 +# $FreeBSD: releng/11.1/lib/libc/compat-43/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +# compat-43 sources +.PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/compat-43 ${LIBC_SRCTOP}/compat-43 + +SRCS+= creat.c gethostid.c getwd.c killpg.c sethostid.c setpgrp.c \ + setrgid.c setruid.c sigcompat.c + +SYM_MAPS+=${LIBC_SRCTOP}/compat-43/Symbol.map + +MAN+= creat.2 killpg.2 sigpause.2 sigsetmask.2 sigvec.2 +MAN+= gethostid.3 setruid.3 + +MLINKS+=gethostid.3 sethostid.3 +MLINKS+=sigpause.2 sighold.2 +MLINKS+=sigpause.2 sigignore.2 +MLINKS+=sigpause.2 sigrelse.2 +MLINKS+=sigpause.2 sigset.2 +MLINKS+=sigpause.2 xsi_sigpause.2 +MLINKS+=setruid.3 setrgid.3 + +MLINKS+=sigsetmask.2 sigblock.2 +MLINKS+=sigsetmask.2 sigmask.2 diff --git a/lib/libc/compat-43/Symbol.map b/lib/libc/compat-43/Symbol.map new file mode 100644 index 0000000..211c6cd --- /dev/null +++ b/lib/libc/compat-43/Symbol.map @@ -0,0 +1,31 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/compat-43/Symbol.map 277032 2015-01-11 22:16:31Z kib $ + */ + +FBSD_1.0 { + creat; + gethostid; + getwd; + killpg; + sethostid; + setpgrp; + setrgid; + setruid; + sigblock; + sigpause; + sigsetmask; + sigvec; +}; + +FBSD_1.2 { + sighold; + sigignore; + sigrelse; + sigset; + xsi_sigpause; +}; + +FBSDprivate_1.0 { + __creat; + _creat; +}; diff --git a/lib/libc/compat-43/creat.2 b/lib/libc/compat-43/creat.2 new file mode 100644 index 0000000..2ebf9cd --- /dev/null +++ b/lib/libc/compat-43/creat.2 @@ -0,0 +1,62 @@ +.\" Copyright (c) 1989, 1990, 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. +.\" 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. +.\" +.\" @(#)creat.2 8.1 (Berkeley) 6/2/93 +.\" $FreeBSD: releng/11.1/lib/libc/compat-43/creat.2 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 2, 1993 +.Dt CREAT 2 +.Os +.Sh NAME +.Nm creat +.Nd create a new file +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In fcntl.h +.Ft int +.Fn creat "const char *path" "mode_t mode" +.Sh DESCRIPTION +.Bf -symbolic +This interface is made obsolete by: +.Ef +.Xr open 2 . +.Pp +The +.Fn creat +function +is the same as: +.Bd -literal -offset indent +open(path, O_CREAT | O_TRUNC | O_WRONLY, mode); +.Ed +.Sh SEE ALSO +.Xr open 2 +.Sh HISTORY +The +.Fn creat +function appeared in +.At v6 . diff --git a/lib/libc/compat-43/gethostid.3 b/lib/libc/compat-43/gethostid.3 new file mode 100644 index 0000000..9f5ebdf --- /dev/null +++ b/lib/libc/compat-43/gethostid.3 @@ -0,0 +1,80 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)gethostid.3 8.1 (Berkeley) 6/2/93 +.\" $FreeBSD: releng/11.1/lib/libc/compat-43/gethostid.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 2, 1993 +.Dt GETHOSTID 3 +.Os +.Sh NAME +.Nm gethostid , +.Nm sethostid +.Nd get/set unique identifier of current host +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft long +.Fn gethostid void +.Ft void +.Fn sethostid "long hostid" +.Sh DESCRIPTION +The +.Fn sethostid +function +establishes a 32-bit identifier for the +current processor that is intended to be unique among all +UNIX systems in existence. +This is normally a DARPA Internet +address for the local machine. +This call is allowed only to the +super-user and is normally performed at boot time. +.Pp +The +.Fn gethostid +function +returns the 32-bit identifier for the current processor. +.Pp +This function has been deprecated. +The hostid should be set or retrieved by use of +.Xr sysctl 3 . +.Sh SEE ALSO +.Xr gethostname 3 , +.Xr sysctl 3 , +.Xr sysctl 8 +.Sh HISTORY +The +.Fn gethostid +and +.Fn sethostid +syscalls appeared in +.Bx 4.2 +and were dropped in +.Bx 4.4 . +.Sh BUGS +32 bits for the identifier is too small. diff --git a/lib/libc/compat-43/killpg.2 b/lib/libc/compat-43/killpg.2 new file mode 100644 index 0000000..8359729 --- /dev/null +++ b/lib/libc/compat-43/killpg.2 @@ -0,0 +1,92 @@ +.\" Copyright (c) 1980, 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. +.\" 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. +.\" +.\" @(#)killpg.2 8.1 (Berkeley) 6/2/93 +.\" $FreeBSD: releng/11.1/lib/libc/compat-43/killpg.2 241855 2012-10-22 03:37:00Z eadler $ +.\" +.Dd March 15, 2012 +.Dt KILLPG 2 +.Os +.Sh NAME +.Nm killpg +.Nd send signal to a process group +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In signal.h +.Ft int +.Fn killpg "pid_t pgrp" "int sig" +.Sh DESCRIPTION +The +.Fn killpg +function +sends the signal +.Fa sig +to the process group +.Fa pgrp . +See +.Xr sigaction 2 +for a list of signals. +If +.Fa pgrp +is 0, +.Fn killpg +sends the signal to the sending process's process group. +.Pp +The sending process must be able to +.Fn kill +at least one process in the receiving process group. +.Sh RETURN VALUES +.Rv -std killpg +.Sh ERRORS +The +.Fn killpg +function +will fail and no signal will be sent if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sig +argument +is not a valid signal number. +.It Bq Er ESRCH +No process can be found in the process group specified by +.Fa pgrp . +.It Bq Er EPERM +.Fn kill +returns EPERM for all processes in the process group. +.El +.Sh SEE ALSO +.Xr getpgrp 2 , +.Xr kill 2 , +.Xr sigaction 2 +.Sh HISTORY +The +.Fn killpg +function appeared in +.Bx 4.0 . diff --git a/lib/libc/compat-43/setruid.3 b/lib/libc/compat-43/setruid.3 new file mode 100644 index 0000000..8656a8c --- /dev/null +++ b/lib/libc/compat-43/setruid.3 @@ -0,0 +1,80 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)setruid.3 8.1 (Berkeley) 6/2/93 +.\" $FreeBSD: releng/11.1/lib/libc/compat-43/setruid.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 2, 1993 +.Dt SETRUID 3 +.Os +.Sh NAME +.Nm setruid , +.Nm setrgid +.Nd set user and group ID +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn setruid "uid_t ruid" +.Ft int +.Fn setrgid "gid_t rgid" +.Sh DESCRIPTION +The +.Fn setruid +function +.Pq Fn setrgid +sets the real user ID (group ID) of the +current process. +.Sh RETURN VALUES +.Rv -std +.Sh COMPATIBILITY +The use of these calls is not portable. +Their use is discouraged; they will be removed in the future. +.Sh ERRORS +The functions fail if: +.Bl -tag -width Er +.It Bq Er EPERM +The user is not the super user and the ID +specified is not the real or effective ID. +.El +.Sh SEE ALSO +.Xr getgid 2 , +.Xr getuid 2 , +.Xr setegid 2 , +.Xr seteuid 2 , +.Xr setgid 2 , +.Xr setuid 2 +.Sh HISTORY +The +.Fn setruid +and +.Fn setrgid +syscalls appeared in +.Bx 4.2 +and were dropped in +.Bx 4.4 . diff --git a/lib/libc/compat-43/sigpause.2 b/lib/libc/compat-43/sigpause.2 new file mode 100644 index 0000000..293703a --- /dev/null +++ b/lib/libc/compat-43/sigpause.2 @@ -0,0 +1,243 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)sigpause.2 8.1 (Berkeley) 6/2/93 +.\" $FreeBSD: releng/11.1/lib/libc/compat-43/sigpause.2 235140 2012-05-08 18:56:21Z gjb $ +.\" +.\" Part of the content of the man page was derived from +.\" The Open Group Base Specifications Issue 7 +.\" IEEE Std 1003.1-2008 +.\" +.Dd June 2, 1993 +.Dt SIGPAUSE 2 +.Os +.Sh NAME +.Nm sighold , +.Nm sigignore , +.Nm sigpause , +.Nm sigrelse , +.Nm sigset +.Nd legacy interface for signal management +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In signal.h +.Ft int +.Fn sighold "int sig" +.Ft int +.Fn sigignore "int sig" +.Ft int +.Fn xsi_sigpause "int sigmask" +.Ft int +.Fn sigrelse "int sig" +.Ft void (*)(int) +.Fn sigset "int" "void (*disp)(int)" +.Ft int +.Fn sigpause "int sigmask" +.Sh DESCRIPTION +.Sy This interface is made obsolete by +.Xr sigsuspend 2 +.Sy and +.Xr sigaction 2 . +.Pp +The +.Fn sigset +function modifies signal dispositions. +The +.Fa sig +argument specifies the signal, which may be any signal except +.Dv SIGKILL +and +.Dv SIGSTOP . +The +.Fa disp +argument specifies the signal's disposition, +which may be +.Dv SIG_DFL , +.Dv SIG_IGN , +or the address of a signal handler. +If +.Fn sigset +is used, and +.Fa disp +is the address of a signal handler, the +system adds +.Fa sig +to the signal mask of the calling process before executing the signal +handler; when the signal handler returns, the system restores the +signal mask of the calling process to its state prior to the delivery +of the signal. +In addition, if +.Fn sigset +is used, and +.Fa disp +is equal to +.Dv SIG_HOLD , +.Fa sig +is added to the signal +mask of the calling process and +.Fa sig 's +disposition remains unchanged. +If +.Fn sigset +is used, and +.Fa disp +is not equal to +.Dv SIG_HOLD , +.Fa sig +is removed from the signal mask of the calling process. +.Pp +The +.Fn sighold +function adds +.Fa sig +to the signal mask of the calling process. +.Pp +The +.Fn sigrelse +function removes +.Fa sig +from the signal mask of the calling process. +.Pp +The +.Fn sigignore +function sets the disposition of +.Fa sig +to +.Dv SIG_IGN . +.Pp +The +.Fn xsi_sigpause +function removes +.Fa sig +from the signal mask of the calling process and suspend the calling process +until a signal is received. +The +.Fn xsi_sigpause +function restores the signal mask of the process to its original state before +returning. +.Pp +The +.Fn sigpause +function +assigns +.Fa sigmask +to the set of masked signals +and then waits for a signal to arrive; +on return the set of masked signals is restored. +The +.Fa sigmask +argument +is usually 0 to indicate that no +signals are to be blocked. +.Sh RETURN VALUES +The +.Fn sigpause +and +.Fn xsi_sigpause +functions +always terminate by being interrupted, returning -1 with +.Va errno +set to +.Er EINTR . +.Pp +Upon successful completion, +.Fn sigset +returns +.Dv SIG_HOLD +if the signal had been blocked and the signal's previous disposition if +it had not been blocked. +Otherwise, +.Dv SIG_ERR +is returned and +.Va errno +set to indicate the error. +.Pp +For all other functions, upon successful completion, 0 is returned. +Otherwise, -1 is returned and +.Va errno +is set to indicate the error: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sig +argument +is not a valid signal number. +.It Bq Er EINVAL +For +.Fn sigset +and +.Fn sigignore +functions, an attempt was made to catch or ignore +.Dv SIGKILL +or +.Dv SIGSTOP . +.El +.Sh SEE ALSO +.Xr kill 2 , +.Xr sigaction 2 , +.Xr sigblock 2 , +.Xr sigprocmask 2 , +.Xr sigsuspend 2 , +.Xr sigvec 2 +.Sh STANDARDS +The +.Fn sigpause +function is implemented for compatibility with historic +.Bx 4.3 +applications. +An incompatible interface by the same name, which used a single signal number +rather than a mask, was present in +.At V , +and was copied from there into the +.Sy X/Open System Interfaces +.Pq Tn XSI +option of +.St -p1003.1-2001 . +.Fx +implements it under the name +.Fn xsi_sigpause . +The +.Fn sighold , +.Fn sigignore , +.Fn sigrelse +and +.Fn sigset +functions are implemented for compatibility with +.Sy System V +and +.Sy XSI +interfaces. +.Sh HISTORY +The +.Fn sigpause +function appeared in +.Bx 4.2 +and has been deprecated. +All other functions appeared in +.Fx 8.1 +and were deprecated before being implemented. diff --git a/lib/libc/compat-43/sigsetmask.2 b/lib/libc/compat-43/sigsetmask.2 new file mode 100644 index 0000000..54e9a28 --- /dev/null +++ b/lib/libc/compat-43/sigsetmask.2 @@ -0,0 +1,103 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)sigsetmask.2 8.1 (Berkeley) 6/2/93 +.\" $FreeBSD: releng/11.1/lib/libc/compat-43/sigsetmask.2 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 2, 1993 +.Dt SIGSETMASK 2 +.Os +.Sh NAME +.Nm sigsetmask , +.Nm sigblock +.Nd manipulate current signal mask +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In signal.h +.Ft int +.Fn sigsetmask "int mask" +.Ft int +.Fn sigblock "int mask" +.Ft int +.Fn sigmask "int signum" +.Sh DESCRIPTION +.Bf -symbolic +This interface is made obsolete by: +.Ef +.Xr sigprocmask 2 . +.Pp +The +.Fn sigsetmask +function +sets the current signal mask to the specified +.Fa mask . +Signals are blocked from delivery if the corresponding bit in +.Fa mask +is a 1. +The +.Fn sigblock +function +adds the signals in the specified +.Fa mask +to the current signal mask, +rather than overwriting it as +.Fn sigsetmask +does. +The macro +.Fn sigmask +is provided to construct the mask for a given +.Fa signum . +.Pp +The system +quietly disallows +.Dv SIGKILL +or +.Dv SIGSTOP +to be blocked. +.Sh RETURN VALUES +The +.Fn sigblock +and +.Fn sigsetmask +functions +return the previous set of masked signals. +.Sh SEE ALSO +.Xr kill 2 , +.Xr sigaction 2 , +.Xr sigprocmask 2 , +.Xr sigsuspend 2 , +.Xr sigvec 2 , +.Xr sigsetops 3 +.Sh HISTORY +The +.Fn sigsetmask +and +.Fn sigblock +functions first appeared in +.Bx 4.2 +and have been deprecated. diff --git a/lib/libc/compat-43/sigvec.2 b/lib/libc/compat-43/sigvec.2 new file mode 100644 index 0000000..c3a1fef --- /dev/null +++ b/lib/libc/compat-43/sigvec.2 @@ -0,0 +1,342 @@ +.\" Copyright (c) 1980, 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. +.\" 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. +.\" +.\" @(#)sigvec.2 8.2 (Berkeley) 4/19/94 +.\" $FreeBSD: releng/11.1/lib/libc/compat-43/sigvec.2 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 19, 1994 +.Dt SIGVEC 2 +.Os +.Sh NAME +.Nm sigvec +.Nd software signal facilities +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In signal.h +.Bd -literal +struct sigvec { + void (*sv_handler)(); + int sv_mask; + int sv_flags; +}; +.Ed +.Ft int +.Fn sigvec "int sig" "struct sigvec *vec" "struct sigvec *ovec" +.Sh DESCRIPTION +.Bf -symbolic +This interface is made obsolete by +.Xr sigaction 2 . +.Ef +.Pp +The system defines a set of signals that may be delivered to a process. +Signal delivery resembles the occurrence of a hardware interrupt: +the signal is blocked from further occurrence, the current process +context is saved, and a new one is built. +A process may specify a +.Em handler +to which a signal is delivered, or specify that a signal is to be +.Em blocked +or +.Em ignored . +A process may also specify that a default action is to be taken +by the system when a signal occurs. +Normally, signal handlers execute on the current stack +of the process. +This may be changed, on a per-handler basis, +so that signals are taken on a special +.Em "signal stack" . +.Pp +All signals have the same +.Em priority . +Signal routines execute with the signal that caused their +invocation +.Em blocked , +but other signals may yet occur. +A global +.Em "signal mask" +defines the set of signals currently blocked from delivery +to a process. +The signal mask for a process is initialized +from that of its parent (normally 0). +It +may be changed with a +.Xr sigblock 2 +or +.Xr sigsetmask 2 +call, or when a signal is delivered to the process. +.Pp +When a signal +condition arises for a process, the signal is added to a set of +signals pending for the process. +If the signal is not currently +.Em blocked +by the process then it is delivered to the process. +When a signal +is delivered, the current state of the process is saved, +a new signal mask is calculated (as described below), +and the signal handler is invoked. +The call to the handler +is arranged so that if the signal handling routine returns +normally the process will resume execution in the context +from before the signal's delivery. +If the process wishes to resume in a different context, then it +must arrange to restore the previous context itself. +.Pp +When a signal is delivered to a process a new signal mask is +installed for the duration of the process' signal handler +(or until a +.Xr sigblock 2 +or +.Xr sigsetmask 2 +call is made). +This mask is formed by taking the current signal mask, +adding the signal to be delivered, and +.Em or Ns 'ing +in the signal mask associated with the handler to be invoked. +.Pp +The +.Fn sigvec +function +assigns a handler for a specific signal. +If +.Fa vec +is non-zero, it +specifies a handler routine and mask +to be used when delivering the specified signal. +Further, if the +.Dv SV_ONSTACK +bit is set in +.Fa sv_flags , +the system will deliver the signal to the process on a +.Em "signal stack" , +specified with +.Xr sigaltstack 2 . +If +.Fa ovec +is non-zero, the previous handling information for the signal +is returned to the user. +.Pp +The following is a list of all signals +with names as in the include file +.In signal.h : +.Bl -column SIGVTALARMXX "create core imagexxx" +.It Sy "NAME Default Action Description" +.It Dv SIGHUP No " terminate process" " terminal line hangup" +.It Dv SIGINT No " terminate process" " interrupt program" +.It Dv SIGQUIT No " create core image" " quit program" +.It Dv SIGILL No " create core image" " illegal instruction" +.It Dv SIGTRAP No " create core image" " trace trap" +.It Dv SIGABRT No " create core image" Ta Xr abort 3 +call (formerly +.Dv SIGIOT ) +.It Dv SIGEMT No " create core image" " emulate instruction executed" +.It Dv SIGFPE No " create core image" " floating-point exception" +.It Dv SIGKILL No " terminate process" " kill program" +.It Dv SIGBUS No " create core image" " bus error" +.It Dv SIGSEGV No " create core image" " segmentation violation" +.It Dv SIGSYS No " create core image" " non-existent system call invoked" +.It Dv SIGPIPE No " terminate process" " write on a pipe with no reader" +.It Dv SIGALRM No " terminate process" " real-time timer expired" +.It Dv SIGTERM No " terminate process" " software termination signal" +.It Dv SIGURG No " discard signal" " urgent condition present on socket" +.It Dv SIGSTOP No " stop process" " stop (cannot be caught or ignored)" +.It Dv SIGTSTP No " stop process" " stop signal generated from keyboard" +.It Dv SIGCONT No " discard signal" " continue after stop" +.It Dv SIGCHLD No " discard signal" " child status has changed" +.It Dv SIGTTIN No " stop process" " background read attempted from control terminal" +.It Dv SIGTTOU No " stop process" " background write attempted to control terminal" +.It Dv SIGIO No " discard signal" Tn " I/O" +is possible on a descriptor (see +.Xr fcntl 2 ) +.It Dv SIGXCPU No " terminate process" " cpu time limit exceeded (see" +.Xr setrlimit 2 ) +.It Dv SIGXFSZ No " terminate process" " file size limit exceeded (see" +.Xr setrlimit 2 ) +.It Dv SIGVTALRM No " terminate process" " virtual time alarm (see" +.Xr setitimer 2 ) +.It Dv SIGPROF No " terminate process" " profiling timer alarm (see" +.Xr setitimer 2 ) +.It Dv SIGWINCH No " discard signal" " Window size change" +.It Dv SIGINFO No " discard signal" " status request from keyboard" +.It Dv SIGUSR1 No " terminate process" " User defined signal 1" +.It Dv SIGUSR2 No " terminate process" " User defined signal 2" +.El +.Pp +Once a signal handler is installed, it remains installed +until another +.Fn sigvec +call is made, or an +.Xr execve 2 +is performed. +A signal-specific default action may be reset by +setting +.Fa sv_handler +to +.Dv SIG_DFL . +The defaults are process termination, possibly with core dump; +no action; stopping the process; or continuing the process. +See the above signal list for each signal's default action. +If +.Fa sv_handler +is +.Dv SIG_IGN +current and pending instances +of the signal are ignored and discarded. +.Pp +If a signal is caught during the system calls listed below, +the call is normally restarted. +The call can be forced to terminate prematurely with an +.Er EINTR +error return by setting the +.Dv SV_INTERRUPT +bit in +.Fa sv_flags . +The affected system calls include +.Xr read 2 , +.Xr write 2 , +.Xr sendto 2 , +.Xr recvfrom 2 , +.Xr sendmsg 2 +and +.Xr recvmsg 2 +on a communications channel or a slow device (such as a terminal, +but not a regular file) +and during a +.Xr wait 2 +or +.Xr ioctl 2 . +However, calls that have already committed are not restarted, +but instead return a partial success (for example, a short read count). +.Pp +After a +.Xr fork 2 +or +.Xr vfork 2 +all signals, the signal mask, the signal stack, +and the restart/interrupt flags are inherited by the child. +.Pp +The +.Xr execve 2 +system call reinstates the default +action for all signals which were caught and +resets all signals to be caught on the user stack. +Ignored signals remain ignored; +the signal mask remains the same; +signals that interrupt system calls continue to do so. +.Sh NOTES +The mask specified in +.Fa vec +is not allowed to block +.Dv SIGKILL +or +.Dv SIGSTOP . +This is done silently by the system. +.Pp +The +.Dv SV_INTERRUPT +flag is not available in +.Bx 4.2 , +hence it should not be used if backward compatibility is needed. +.Sh RETURN VALUES +.Rv -std sigvec +.Sh EXAMPLES +On the +.Tn VAX\-11 +The handler routine can be declared: +.Bd -literal -offset indent +void handler(sig, code, scp) +int sig, code; +struct sigcontext *scp; +.Ed +.Pp +Here +.Fa sig +is the signal number, into which the hardware faults and traps are +mapped as defined below. +The +.Fa code +argument +is either a constant +as given below or, for compatibility mode faults, the code provided by +the hardware (Compatibility mode faults are distinguished from the +other +.Dv SIGILL +traps by having +.Dv PSL_CM +set in the psl). +The +.Fa scp +argument +is a pointer to the +.Fa sigcontext +structure (defined in +.In signal.h ) , +used to restore the context from before the signal. +.Sh ERRORS +The +.Fn sigvec +function +will fail and no new signal handler will be installed if one +of the following occurs: +.Bl -tag -width Er +.It Bq Er EFAULT +Either +.Fa vec +or +.Fa ovec +points to memory that is not a valid part of the process +address space. +.It Bq Er EINVAL +The +.Fa sig +argument +is not a valid signal number. +.It Bq Er EINVAL +An attempt is made to ignore or supply a handler for +.Dv SIGKILL +or +.Dv SIGSTOP . +.El +.Sh SEE ALSO +.Xr kill 1 , +.Xr kill 2 , +.Xr ptrace 2 , +.Xr sigaction 2 , +.Xr sigaltstack 2 , +.Xr sigblock 2 , +.Xr sigpause 2 , +.Xr sigprocmask 2 , +.Xr sigsetmask 2 , +.Xr sigsuspend 2 , +.Xr setjmp 3 , +.Xr siginterrupt 3 , +.Xr signal 3 , +.Xr sigsetops 3 , +.Xr tty 4 +.Sh BUGS +This manual page is still confusing. diff --git a/lib/libc/db/Makefile.inc b/lib/libc/db/Makefile.inc new file mode 100644 index 0000000..935acf3 --- /dev/null +++ b/lib/libc/db/Makefile.inc @@ -0,0 +1,13 @@ +# from @(#)Makefile.inc 8.2 (Berkeley) 2/21/94 +# $FreeBSD: releng/11.1/lib/libc/db/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ +# +CFLAGS+=-D__DBINTERFACE_PRIVATE + +.include "${LIBC_SRCTOP}/db/btree/Makefile.inc" +.include "${LIBC_SRCTOP}/db/db/Makefile.inc" +.include "${LIBC_SRCTOP}/db/hash/Makefile.inc" +.include "${LIBC_SRCTOP}/db/man/Makefile.inc" +.include "${LIBC_SRCTOP}/db/mpool/Makefile.inc" +.include "${LIBC_SRCTOP}/db/recno/Makefile.inc" + +SYM_MAPS+=${LIBC_SRCTOP}/db/Symbol.map diff --git a/lib/libc/db/Symbol.map b/lib/libc/db/Symbol.map new file mode 100644 index 0000000..a3d919e --- /dev/null +++ b/lib/libc/db/Symbol.map @@ -0,0 +1,36 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/db/Symbol.map 190498 2009-03-28 07:31:02Z delphij $ + */ + +FBSD_1.0 { + dbopen; + dbm_open; + dbm_close; + dbm_fetch; + dbm_firstkey; + dbm_nextkey; + dbm_delete; + dbm_store; + dbm_error; + dbm_clearerr; + dbm_dirfno; + mpool_open; + mpool_filter; + mpool_get; + mpool_put; + mpool_close; + mpool_sync; + mpool_stat; +}; + +FBSD_1.1 { + mpool_new; + mpool_delete; +}; + +FBSDprivate_1.0 { + __bt_open; + __dbpanic; + __hash_open; + __rec_open; +}; diff --git a/lib/libc/db/btree/Makefile.inc b/lib/libc/db/btree/Makefile.inc new file mode 100644 index 0000000..9f3b4f2 --- /dev/null +++ b/lib/libc/db/btree/Makefile.inc @@ -0,0 +1,8 @@ +# from @(#)Makefile.inc 8.2 (Berkeley) 7/14/94 +# $FreeBSD: releng/11.1/lib/libc/db/btree/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +.PATH: ${LIBC_SRCTOP}/db/btree + +SRCS+= bt_close.c bt_conv.c bt_debug.c bt_delete.c bt_get.c bt_open.c \ + bt_overflow.c bt_page.c bt_put.c bt_search.c bt_seq.c bt_split.c \ + bt_utils.c diff --git a/lib/libc/db/changelog b/lib/libc/db/changelog new file mode 100644 index 0000000..1540ca8 --- /dev/null +++ b/lib/libc/db/changelog @@ -0,0 +1,103 @@ +1.84 -> 1.85 + recno: #ifdef out use of mmap, it's not portable enough. + +1.83 -> 1.84 Thu Aug 18 15:46:07 EDT 1994 + recno: Rework fixed-length records so that closing and reopening + the file now works. Pad short records on input. Never do + signed comparison in recno input reading functions. + +1.82 -> 1.83 Tue Jul 26 15:33:44 EDT 1994 + btree: Rework cursor deletion code yet again; bugs with + deleting empty pages that only contained the cursor + record. + +1.81 -> 1.82 Sat Jul 16 11:01:50 EDT 1994 + btree: Fix bugs introduced by new cursor/deletion code. + Replace return kbuf/dbuf with real DBT's. + +1.80 -> 1.81 + btree: Fix bugs introduced by new cursor/deletion code. + all: Add #defines for Purify. + +1.79 -> 1.80 Wed Jul 13 22:41:54 EDT 1994 + btree Change deletion to coalesce empty pages. This is a major + change, cursors and duplicate pages all had to be reworked. + Return to a fixed stack. + recno: Affected by cursor changes. New cursor structures should + permit multiple cursors in the future. + +1.78 -> 1.79 Mon Jun 20 17:36:47 EDT 1994 + all: Minor cleanups of 1.78 for porting reasons; only + major change was inlining check of NULL pointer + so that __fix_realloc goes away. + +1.77 -> 1.78 Thu Jun 16 19:06:43 EDT 1994 + all: Move "standard" size typedef's into db.h. + +1.76 -> 1.77 Thu Jun 16 16:48:38 EDT 1994 + hash: Delete __init_ routine, has special meaning to OSF 2.0. + +1.74 -> 1.76 + all: Finish up the port to the Alpha. + +1.73 -> 1.74 + recno: Don't put the record if rec_search fails, in rec_rdelete. + Create fixed-length intermediate records past "end" of DB + correctly. + Realloc bug when reading in fixed records. + all: First cut at port to Alpha (64-bit architecture) using + 4.4BSD basic integral types typedef's. + Cast allocation pointers to shut up old compilers. + Rework PORT directory into OS/machine directories. + +1.72 -> 1.73 + btree: If enough duplicate records were inserted and then deleted + that internal pages had references to empty pages of the + duplicate keys, the search function ended up on the wrong + page. + +1.7 -> 1.72 12 Oct 1993 + hash: Support NET/2 hash formats. + +1.7 -> 1.71 16 Sep 1993 + btree/recno: + Fix bug in internal search routines that caused + return of invalid pointers. + +1.6 -> 1.7 07 Sep 1993 + hash: Fixed big key overflow bugs. + test: Portability hacks, rewrite test script, Makefile. + btree/recno: + Stop copying non-overflow key/data pairs. + PORT: Break PORT directory up into per architecture/OS + subdirectories. + +1.5 -> 1.6 06 Jun 1993 + hash: In PAIRFITS, the first comparison should look at (P)[2]. + The hash_realloc function was walking off the end of memory. + The overflow page number was wrong when bumping splitpoint. + +1.4 -> 1.5 23 May 1993 + hash: Set hash default fill factor dynamically. + recno: Fixed bug in sorted page splits. + Add page size parameter support. + Allow recno to specify the name of the underlying btree; + used for vi recovery. + btree/recno: + Support 64K pages. + btree/hash/recno: + Provide access to an underlying file descriptor. + Change sync routines to take a flag argument, recno + uses this to sync out the underlying btree. + +1.3 -> 1.4 10 May 1993 + recno: Delete the R_CURSORLOG flag from the recno interface. + Zero-length record fix for non-mmap reads. + Try and make SIZE_T_MAX test in open portable. + +1.2 -> 1.3 01 May 1993 + btree: Ignore user byte-order setting when reading already + existing database. Fixes to byte-order conversions. + +1.1 -> 1.2 15 Apr 1993 + No bug fixes, only compatibility hacks. diff --git a/lib/libc/db/db/Makefile.inc b/lib/libc/db/db/Makefile.inc new file mode 100644 index 0000000..1fcdd8d --- /dev/null +++ b/lib/libc/db/db/Makefile.inc @@ -0,0 +1,6 @@ +# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/db/db/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +.PATH: ${LIBC_SRCTOP}/db/db + +SRCS+= db.c diff --git a/lib/libc/db/docs/hash.usenix.ps b/lib/libc/db/docs/hash.usenix.ps new file mode 100644 index 0000000..ef53f97 --- /dev/null +++ b/lib/libc/db/docs/hash.usenix.ps @@ -0,0 +1,12209 @@ +%!PS-Adobe-1.0 +%%Creator: utopia:margo (& Seltzer,608-13E,8072,) +%%Title: stdin (ditroff) +%%CreationDate: Tue Dec 11 15:06:45 1990 +%%EndComments +% @(#)psdit.pro 1.3 4/15/88 +% lib/psdit.pro -- prolog for psdit (ditroff) files +% Copyright (c) 1984, 1985 Adobe Systems Incorporated. All Rights Reserved. +% last edit: shore Sat Nov 23 20:28:03 1985 +% RCSID: $FreeBSD: releng/11.1/lib/libc/db/docs/hash.usenix.ps 50488 1999-08-28 05:11:36Z peter $ + +% Changed by Edward Wang (edward@ucbarpa.berkeley.edu) to handle graphics, +% 17 Feb, 87. + +/$DITroff 140 dict def $DITroff begin +/fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def +/xi{0 72 11 mul translate 72 resolution div dup neg scale 0 0 moveto + /fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def F + /pagesave save def}def +/PB{save /psv exch def currentpoint translate + resolution 72 div dup neg scale 0 0 moveto}def +/PE{psv restore}def +/arctoobig 90 def /arctoosmall .05 def +/m1 matrix def /m2 matrix def /m3 matrix def /oldmat matrix def +/tan{dup sin exch cos div}def +/point{resolution 72 div mul}def +/dround {transform round exch round exch itransform}def +/xT{/devname exch def}def +/xr{/mh exch def /my exch def /resolution exch def}def +/xp{}def +/xs{docsave restore end}def +/xt{}def +/xf{/fontname exch def /slotno exch def fontnames slotno get fontname eq not + {fonts slotno fontname findfont put fontnames slotno fontname put}if}def +/xH{/fontheight exch def F}def +/xS{/fontslant exch def F}def +/s{/fontsize exch def /fontheight fontsize def F}def +/f{/fontnum exch def F}def +/F{fontheight 0 le{/fontheight fontsize def}if + fonts fontnum get fontsize point 0 0 fontheight point neg 0 0 m1 astore + fontslant 0 ne{1 0 fontslant tan 1 0 0 m2 astore m3 concatmatrix}if + makefont setfont .04 fontsize point mul 0 dround pop setlinewidth}def +/X{exch currentpoint exch pop moveto show}def +/N{3 1 roll moveto show}def +/Y{exch currentpoint pop exch moveto show}def +/S{show}def +/ditpush{}def/ditpop{}def +/AX{3 -1 roll currentpoint exch pop moveto 0 exch ashow}def +/AN{4 2 roll moveto 0 exch ashow}def +/AY{3 -1 roll currentpoint pop exch moveto 0 exch ashow}def +/AS{0 exch ashow}def +/MX{currentpoint exch pop moveto}def +/MY{currentpoint pop exch moveto}def +/MXY{moveto}def +/cb{pop}def % action on unknown char -- nothing for now +/n{}def/w{}def +/p{pop showpage pagesave restore /pagesave save def}def +/Dt{/Dlinewidth exch def}def 1 Dt +/Ds{/Ddash exch def}def -1 Ds +/Di{/Dstipple exch def}def 1 Di +/Dsetlinewidth{2 Dlinewidth mul setlinewidth}def +/Dsetdash{Ddash 4 eq{[8 12]}{Ddash 16 eq{[32 36]} + {Ddash 20 eq{[32 12 8 12]}{[]}ifelse}ifelse}ifelse 0 setdash}def +/Dstroke{gsave Dsetlinewidth Dsetdash 1 setlinecap stroke grestore + currentpoint newpath moveto}def +/Dl{rlineto Dstroke}def +/arcellipse{/diamv exch def /diamh exch def oldmat currentmatrix pop + currentpoint translate 1 diamv diamh div scale /rad diamh 2 div def + currentpoint exch rad add exch rad -180 180 arc oldmat setmatrix}def +/Dc{dup arcellipse Dstroke}def +/De{arcellipse Dstroke}def +/Da{/endv exch def /endh exch def /centerv exch def /centerh exch def + /cradius centerv centerv mul centerh centerh mul add sqrt def + /eradius endv endv mul endh endh mul add sqrt def + /endang endv endh atan def + /startang centerv neg centerh neg atan def + /sweep startang endang sub dup 0 lt{360 add}if def + sweep arctoobig gt + {/midang startang sweep 2 div sub def /midrad cradius eradius add 2 div def + /midh midang cos midrad mul def /midv midang sin midrad mul def + midh neg midv neg endh endv centerh centerv midh midv Da + Da} + {sweep arctoosmall ge + {/controldelt 1 sweep 2 div cos sub 3 sweep 2 div sin mul div 4 mul def + centerv neg controldelt mul centerh controldelt mul + endv neg controldelt mul centerh add endh add + endh controldelt mul centerv add endv add + centerh endh add centerv endv add rcurveto Dstroke} + {centerh endh add centerv endv add rlineto Dstroke} + ifelse} + ifelse}def +/Dpatterns[ +[%cf[widthbits] +[8<0000000000000010>] +[8<0411040040114000>] +[8<0204081020408001>] +[8<0000103810000000>] +[8<6699996666999966>] +[8<0000800100001008>] +[8<81c36666c3810000>] +[8<0f0e0c0800000000>] +[8<0000000000000010>] +[8<0411040040114000>] +[8<0204081020408001>] +[8<0000001038100000>] +[8<6699996666999966>] +[8<0000800100001008>] +[8<81c36666c3810000>] +[8<0f0e0c0800000000>] +[8<0042660000246600>] +[8<0000990000990000>] +[8<0804020180402010>] +[8<2418814242811824>] +[8<6699996666999966>] +[8<8000000008000000>] +[8<00001c3e363e1c00>] +[8<0000000000000000>] +[32<00000040000000c00000004000000040000000e0000000000000000000000000>] +[32<00000000000060000000900000002000000040000000f0000000000000000000>] +[32<000000000000000000e0000000100000006000000010000000e0000000000000>] +[32<00000000000000002000000060000000a0000000f00000002000000000000000>] +[32<0000000e0000000000000000000000000000000f000000080000000e00000001>] +[32<0000090000000600000000000000000000000000000007000000080000000e00>] +[32<00010000000200000004000000040000000000000000000000000000000f0000>] +[32<0900000006000000090000000600000000000000000000000000000006000000>]] +[%ug +[8<0000020000000000>] +[8<0000020000002000>] +[8<0004020000002000>] +[8<0004020000402000>] +[8<0004060000402000>] +[8<0004060000406000>] +[8<0006060000406000>] +[8<0006060000606000>] +[8<00060e0000606000>] +[8<00060e000060e000>] +[8<00070e000060e000>] +[8<00070e000070e000>] +[8<00070e020070e000>] +[8<00070e020070e020>] +[8<04070e020070e020>] +[8<04070e024070e020>] +[8<04070e064070e020>] +[8<04070e064070e060>] +[8<06070e064070e060>] +[8<06070e066070e060>] +[8<06070f066070e060>] +[8<06070f066070f060>] +[8<060f0f066070f060>] +[8<060f0f0660f0f060>] +[8<060f0f0760f0f060>] +[8<060f0f0760f0f070>] +[8<0e0f0f0760f0f070>] +[8<0e0f0f07e0f0f070>] +[8<0e0f0f0fe0f0f070>] +[8<0e0f0f0fe0f0f0f0>] +[8<0f0f0f0fe0f0f0f0>] +[8<0f0f0f0ff0f0f0f0>] +[8<1f0f0f0ff0f0f0f0>] +[8<1f0f0f0ff1f0f0f0>] +[8<1f0f0f8ff1f0f0f0>] +[8<1f0f0f8ff1f0f0f8>] +[8<9f0f0f8ff1f0f0f8>] +[8<9f0f0f8ff9f0f0f8>] +[8<9f0f0f9ff9f0f0f8>] +[8<9f0f0f9ff9f0f0f9>] +[8<9f8f0f9ff9f0f0f9>] +[8<9f8f0f9ff9f8f0f9>] +[8<9f8f1f9ff9f8f0f9>] +[8<9f8f1f9ff9f8f1f9>] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8]] +[%mg +[8<8000000000000000>] +[8<0822080080228000>] +[8<0204081020408001>] +[8<40e0400000000000>] +[8<66999966>] +[8<8001000010080000>] +[8<81c36666c3810000>] +[8] +[16<07c00f801f003e007c00f800f001e003c007800f001f003e007c00f801f003e0>] +[16<1f000f8007c003e001f000f8007c003e001f800fc007e003f001f8007c003e00>] +[8] +[16<0040008001000200040008001000200040008000000100020004000800100020>] +[16<0040002000100008000400020001800040002000100008000400020001000080>] +[16<1fc03fe07df0f8f8f07de03fc01f800fc01fe03ff07df8f87df03fe01fc00f80>] +[8<80>] +[8<8040201000000000>] +[8<84cc000048cc0000>] +[8<9900009900000000>] +[8<08040201804020100800020180002010>] +[8<2418814242811824>] +[8<66999966>] +[8<8000000008000000>] +[8<70f8d8f870000000>] +[8<0814224180402010>] +[8] +[8<018245aa45820100>] +[8<221c224180808041>] +[8<88000000>] +[8<0855800080550800>] +[8<2844004482440044>] +[8<0810204080412214>] +[8<00>]]]def +/Dfill{ + transform /maxy exch def /maxx exch def + transform /miny exch def /minx exch def + minx maxx gt{/minx maxx /maxx minx def def}if + miny maxy gt{/miny maxy /maxy miny def def}if + Dpatterns Dstipple 1 sub get exch 1 sub get + aload pop /stip exch def /stipw exch def /stiph 128 def + /imatrix[stipw 0 0 stiph 0 0]def + /tmatrix[stipw 0 0 stiph 0 0]def + /minx minx cvi stiph idiv stiph mul def + /miny miny cvi stipw idiv stipw mul def + gsave eoclip 0 setgray + miny stiph maxy{ + tmatrix exch 5 exch put + minx stipw maxx{ + tmatrix exch 4 exch put tmatrix setmatrix + stipw stiph true imatrix {stip} imagemask + }for + }for + grestore +}def +/Dp{Dfill Dstroke}def +/DP{Dfill currentpoint newpath moveto}def +end + +/ditstart{$DITroff begin + /nfonts 60 def % NFONTS makedev/ditroff dependent! + /fonts[nfonts{0}repeat]def + /fontnames[nfonts{()}repeat]def +/docsave save def +}def + +% character outcalls +/oc{ + /pswid exch def /cc exch def /name exch def + /ditwid pswid fontsize mul resolution mul 72000 div def + /ditsiz fontsize resolution mul 72 div def + ocprocs name known{ocprocs name get exec}{name cb}ifelse +}def +/fractm [.65 0 0 .6 0 0] def +/fraction{ + /fden exch def /fnum exch def gsave /cf currentfont def + cf fractm makefont setfont 0 .3 dm 2 copy neg rmoveto + fnum show rmoveto currentfont cf setfont(\244)show setfont fden show + grestore ditwid 0 rmoveto +}def +/oce{grestore ditwid 0 rmoveto}def +/dm{ditsiz mul}def +/ocprocs 50 dict def ocprocs begin +(14){(1)(4)fraction}def +(12){(1)(2)fraction}def +(34){(3)(4)fraction}def +(13){(1)(3)fraction}def +(23){(2)(3)fraction}def +(18){(1)(8)fraction}def +(38){(3)(8)fraction}def +(58){(5)(8)fraction}def +(78){(7)(8)fraction}def +(sr){gsave 0 .06 dm rmoveto(\326)show oce}def +(is){gsave 0 .15 dm rmoveto(\362)show oce}def +(->){gsave 0 .02 dm rmoveto(\256)show oce}def +(<-){gsave 0 .02 dm rmoveto(\254)show oce}def +(==){gsave 0 .05 dm rmoveto(\272)show oce}def +(uc){gsave currentpoint 400 .009 dm mul add translate + 8 -8 scale ucseal oce}def +end + +% an attempt at a PostScript FONT to implement ditroff special chars +% this will enable us to +% cache the little buggers +% generate faster, more compact PS out of psdit +% confuse everyone (including myself)! +50 dict dup begin +/FontType 3 def +/FontName /DIThacks def +/FontMatrix [.001 0 0 .001 0 0] def +/FontBBox [-260 -260 900 900] def% a lie but ... +/Encoding 256 array def +0 1 255{Encoding exch /.notdef put}for +Encoding + dup 8#040/space put %space + dup 8#110/rc put %right ceil + dup 8#111/lt put %left top curl + dup 8#112/bv put %bold vert + dup 8#113/lk put %left mid curl + dup 8#114/lb put %left bot curl + dup 8#115/rt put %right top curl + dup 8#116/rk put %right mid curl + dup 8#117/rb put %right bot curl + dup 8#120/rf put %right floor + dup 8#121/lf put %left floor + dup 8#122/lc put %left ceil + dup 8#140/sq put %square + dup 8#141/bx put %box + dup 8#142/ci put %circle + dup 8#143/br put %box rule + dup 8#144/rn put %root extender + dup 8#145/vr put %vertical rule + dup 8#146/ob put %outline bullet + dup 8#147/bu put %bullet + dup 8#150/ru put %rule + dup 8#151/ul put %underline + pop +/DITfd 100 dict def +/BuildChar{0 begin + /cc exch def /fd exch def + /charname fd /Encoding get cc get def + /charwid fd /Metrics get charname get def + /charproc fd /CharProcs get charname get def + charwid 0 fd /FontBBox get aload pop setcachedevice + 2 setlinejoin 40 setlinewidth + newpath 0 0 moveto gsave charproc grestore + end}def +/BuildChar load 0 DITfd put +/CharProcs 50 dict def +CharProcs begin +/space{}def +/.notdef{}def +/ru{500 0 rls}def +/rn{0 840 moveto 500 0 rls}def +/vr{0 800 moveto 0 -770 rls}def +/bv{0 800 moveto 0 -1000 rls}def +/br{0 840 moveto 0 -1000 rls}def +/ul{0 -140 moveto 500 0 rls}def +/ob{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath stroke}def +/bu{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath fill}def +/sq{80 0 rmoveto currentpoint dround newpath moveto + 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath stroke}def +/bx{80 0 rmoveto currentpoint dround newpath moveto + 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath fill}def +/ci{500 360 rmoveto currentpoint newpath 333 0 360 arc + 50 setlinewidth stroke}def + +/lt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 add exch s4 a4p stroke}def +/lb{0 800 moveto 0 -550 rlineto currx -200 2cx s4 add exch s4 a4p stroke}def +/rt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 sub exch s4 a4p stroke}def +/rb{0 800 moveto 0 -500 rlineto currx -200 2cx s4 sub exch s4 a4p stroke}def +/lk{0 800 moveto 0 300 -300 300 s4 arcto pop pop 1000 sub + 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def +/rk{0 800 moveto 0 300 s2 300 s4 arcto pop pop 1000 sub + 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def +/lf{0 800 moveto 0 -1000 rlineto s4 0 rls}def +/rf{0 800 moveto 0 -1000 rlineto s4 neg 0 rls}def +/lc{0 -200 moveto 0 1000 rlineto s4 0 rls}def +/rc{0 -200 moveto 0 1000 rlineto s4 neg 0 rls}def +end + +/Metrics 50 dict def Metrics begin +/.notdef 0 def +/space 500 def +/ru 500 def +/br 0 def +/lt 416 def +/lb 416 def +/rt 416 def +/rb 416 def +/lk 416 def +/rk 416 def +/rc 416 def +/lc 416 def +/rf 416 def +/lf 416 def +/bv 416 def +/ob 350 def +/bu 350 def +/ci 750 def +/bx 750 def +/sq 750 def +/rn 500 def +/ul 500 def +/vr 0 def +end + +DITfd begin +/s2 500 def /s4 250 def /s3 333 def +/a4p{arcto pop pop pop pop}def +/2cx{2 copy exch}def +/rls{rlineto stroke}def +/currx{currentpoint pop}def +/dround{transform round exch round exch itransform} def +end +end +/DIThacks exch definefont pop +ditstart +(psc)xT +576 1 1 xr +1(Times-Roman)xf 1 f +2(Times-Italic)xf 2 f +3(Times-Bold)xf 3 f +4(Times-BoldItalic)xf 4 f +5(Helvetica)xf 5 f +6(Helvetica-Bold)xf 6 f +7(Courier)xf 7 f +8(Courier-Bold)xf 8 f +9(Symbol)xf 9 f +10(DIThacks)xf 10 f +10 s +1 f +xi +%%EndProlog + +%%Page: 1 1 +10 s 10 xH 0 xS 1 f +3 f +22 s +1249 626(A)N +1420(N)X +1547(ew)X +1796(H)X +1933(ashing)X +2467(P)X +2574(ackage)X +3136(for)X +3405(U)X +3532(N)X +3659(IX)X +2 f +20 s +3855 562(1)N +1 f +12 s +1607 779(Margo)N +1887(Seltzer)X +9 f +2179(-)X +1 f +2256(University)X +2686(of)X +2790(California,)X +3229(Berkeley)X +2015 875(Ozan)N +2242(Yigit)X +9 f +2464(-)X +1 f +2541(York)X +2762(University)X +3 f +2331 1086(ABSTRACT)N +1 f +10 s +1152 1222(UNIX)N +1385(support)X +1657(of)X +1756(disk)X +1921(oriented)X +2216(hashing)X +2497(was)X +2654(originally)X +2997(provided)X +3314(by)X +2 f +3426(dbm)X +1 f +3595([ATT79])X +3916(and)X +1152 1310(subsequently)N +1595(improved)X +1927(upon)X +2112(in)X +2 f +2199(ndbm)X +1 f +2402([BSD86].)X +2735(In)X +2826(AT&T)X +3068(System)X +3327(V,)X +3429(in-memory)X +3809(hashed)X +1152 1398(storage)N +1420(and)X +1572(access)X +1814(support)X +2090(was)X +2251(added)X +2479(in)X +2577(the)X +2 f +2711(hsearch)X +1 f +3000(library)X +3249(routines)X +3542([ATT85].)X +3907(The)X +1152 1486(result)N +1367(is)X +1457(a)X +1530(system)X +1789(with)X +1968(two)X +2125(incompatible)X +2580(hashing)X +2865(schemes,)X +3193(each)X +3377(with)X +3555(its)X +3666(own)X +3840(set)X +3965(of)X +1152 1574(shortcomings.)N +1152 1688(This)N +1316(paper)X +1517(presents)X +1802(the)X +1922(design)X +2152(and)X +2289(performance)X +2717(characteristics)X +3198(of)X +3286(a)X +3343(new)X +3498(hashing)X +3768(package)X +1152 1776(providing)N +1483(a)X +1539(superset)X +1822(of)X +1909(the)X +2027(functionality)X +2456(provided)X +2761(by)X +2 f +2861(dbm)X +1 f +3019(and)X +2 f +3155(hsearch)X +1 f +3409(.)X +3469(The)X +3614(new)X +3768(package)X +1152 1864(uses)N +1322(linear)X +1537(hashing)X +1818(to)X +1912(provide)X +2189(ef\256cient)X +2484(support)X +2755(of)X +2853(both)X +3026(memory)X +3324(based)X +3538(and)X +3685(disk)X +3849(based)X +1152 1952(hash)N +1319(tables)X +1526(with)X +1688(performance)X +2115(superior)X +2398(to)X +2480(both)X +2 f +2642(dbm)X +1 f +2800(and)X +2 f +2936(hsearch)X +1 f +3210(under)X +3413(most)X +3588(conditions.)X +3 f +1380 2128(Introduction)N +1 f +892 2260(Current)N +1196(UNIX)X +1456(systems)X +1768(offer)X +1984(two)X +2163(forms)X +2409(of)X +720 2348(hashed)N +973(data)X +1137(access.)X +2 f +1413(Dbm)X +1 f +1599(and)X +1745(its)X +1850(derivatives)X +2231(provide)X +720 2436(keyed)N +939(access)X +1171(to)X +1259(disk)X +1418(resident)X +1698(data)X +1858(while)X +2 f +2062(hsearch)X +1 f +2342(pro-)X +720 2524(vides)N +929(access)X +1175(for)X +1309(memory)X +1616(resident)X +1910(data.)X +2124(These)X +2356(two)X +720 2612(access)N +979(methods)X +1302(are)X +1453(incompatible)X +1923(in)X +2037(that)X +2209(memory)X +720 2700(resident)N +1011(hash)X +1195(tables)X +1419(may)X +1593(not)X +1731(be)X +1843(stored)X +2075(on)X +2191(disk)X +2360(and)X +720 2788(disk)N +884(resident)X +1169(tables)X +1387(cannot)X +1632(be)X +1739(read)X +1909(into)X +2063(memory)X +2360(and)X +720 2876(accessed)N +1022(using)X +1215(the)X +1333(in-memory)X +1709(routines.)X +2 f +892 2990(Dbm)N +1 f +1091(has)X +1241(several)X +1512(shortcomings.)X +2026(Since)X +2247(data)X +2423(is)X +720 3078(assumed)N +1032(to)X +1130(be)X +1242(disk)X +1411(resident,)X +1721(each)X +1905(access)X +2146(requires)X +2440(a)X +720 3166(system)N +963(call,)X +1120(and)X +1257(almost)X +1491(certainly,)X +1813(a)X +1869(disk)X +2022(operation.)X +2365(For)X +720 3254(extremely)N +1072(large)X +1264(databases,)X +1623(where)X +1851(caching)X +2131(is)X +2214(unlikely)X +720 3342(to)N +810(be)X +914(effective,)X +1244(this)X +1386(is)X +1466(acceptable,)X +1853(however,)X +2177(when)X +2378(the)X +720 3430(database)N +1022(is)X +1100(small)X +1298(\(i.e.)X +1447(the)X +1569(password)X +1896(\256le\),)X +2069(performance)X +720 3518(improvements)N +1204(can)X +1342(be)X +1443(obtained)X +1744(through)X +2018(caching)X +2293(pages)X +720 3606(of)N +818(the)X +947(database)X +1255(in)X +1348(memory.)X +1685(In)X +1782(addition,)X +2 f +2094(dbm)X +1 f +2262(cannot)X +720 3694(store)N +902(data)X +1062(items)X +1261(whose)X +1492(total)X +1660(key)X +1802(and)X +1943(data)X +2102(size)X +2252(exceed)X +720 3782(the)N +850(page)X +1034(size)X +1191(of)X +1290(the)X +1420(hash)X +1599(table.)X +1827(Similarly,)X +2176(if)X +2257(two)X +2409(or)X +720 3870(more)N +907(keys)X +1076(produce)X +1357(the)X +1477(same)X +1664(hash)X +1833(value)X +2029(and)X +2166(their)X +2334(total)X +720 3958(size)N +876(exceeds)X +1162(the)X +1291(page)X +1474(size,)X +1650(the)X +1779(table)X +1966(cannot)X +2210(store)X +2396(all)X +720 4046(the)N +838(colliding)X +1142(keys.)X +892 4160(The)N +1050(in-memory)X +2 f +1439(hsearch)X +1 f +1725(routines)X +2015(have)X +2199(different)X +720 4248(shortcomings.)N +1219(First,)X +1413(the)X +1539(notion)X +1771(of)X +1865(a)X +1928(single)X +2146(hash)X +2320(table)X +720 4336(is)N +807(embedded)X +1171(in)X +1266(the)X +1397(interface,)X +1732(preventing)X +2108(an)X +2217(applica-)X +720 4424(tion)N +902(from)X +1116(accessing)X +1482(multiple)X +1806(tables)X +2050(concurrently.)X +720 4512(Secondly,)N +1063(the)X +1186(routine)X +1438(to)X +1525(create)X +1743(a)X +1804(hash)X +1976(table)X +2157(requires)X +2440(a)X +720 4600(parameter)N +1066(which)X +1286(declares)X +1573(the)X +1694(size)X +1842(of)X +1932(the)X +2053(hash)X +2223(table.)X +2422(If)X +720 4688(this)N +856(size)X +1001(is)X +1074(set)X +1183(too)X +1305(low,)X +1465(performance)X +1892(degradation)X +2291(or)X +2378(the)X +720 4776(inability)N +1008(to)X +1092(add)X +1230(items)X +1425(to)X +1509(the)X +1628(table)X +1805(may)X +1964(result.)X +2223(In)X +2311(addi-)X +720 4864(tion,)N +2 f +910(hsearch)X +1 f +1210(requires)X +1515(that)X +1681(the)X +1825(application)X +2226(allocate)X +720 4952(memory)N +1037(for)X +1181(the)X +1329(key)X +1495(and)X +1661(data)X +1845(items.)X +2108(Lastly,)X +2378(the)X +2 f +720 5040(hsearch)N +1 f +1013(routines)X +1310(provide)X +1594(no)X +1713(interface)X +2034(to)X +2135(store)X +2329(hash)X +720 5128(tables)N +927(on)X +1027(disk.)X +16 s +720 5593 MXY +864 0 Dl +2 f +8 s +760 5648(1)N +1 f +9 s +5673(UNIX)Y +990(is)X +1056(a)X +1106(registered)X +1408(trademark)X +1718(of)X +1796(AT&T.)X +10 s +2878 2128(The)N +3032(goal)X +3199(of)X +3295(our)X +3431(work)X +3625(was)X +3779(to)X +3870(design)X +4108(and)X +4253(imple-)X +2706 2216(ment)N +2900(a)X +2970(new)X +3138(package)X +3436(that)X +3590(provides)X +3899(a)X +3968(superset)X +4264(of)X +4364(the)X +2706 2304(functionality)N +3144(of)X +3240(both)X +2 f +3411(dbm)X +1 f +3578(and)X +2 f +3723(hsearch)X +1 f +3977(.)X +4045(The)X +4198(package)X +2706 2392(had)N +2871(to)X +2982(overcome)X +3348(the)X +3495(interface)X +3826(shortcomings)X +4306(cited)X +2706 2480(above)N +2930(and)X +3078(its)X +3185(implementation)X +3719(had)X +3867(to)X +3961(provide)X +4238(perfor-)X +2706 2568(mance)N +2942(equal)X +3142(or)X +3235(superior)X +3524(to)X +3612(that)X +3758(of)X +3851(the)X +3975(existing)X +4253(imple-)X +2706 2656(mentations.)N +3152(In)X +3274(order)X +3498(to)X +3614(provide)X +3913(a)X +4003(compact)X +4329(disk)X +2706 2744(representation,)N +3224(graceful)X +3531(table)X +3729(growth,)X +4018(and)X +4176(expected)X +2706 2832(constant)N +3033(time)X +3234(performance,)X +3720(we)X +3873(selected)X +4191(Litwin's)X +2706 2920(linear)N +2923(hashing)X +3206(algorithm)X +3551([LAR88,)X +3872(LIT80].)X +4178(We)X +4324(then)X +2706 3008(enhanced)N +3037(the)X +3161(algorithm)X +3498(to)X +3586(handle)X +3826(page)X +4004(over\257ows)X +4346(and)X +2706 3096(large)N +2900(key)X +3049(handling)X +3362(with)X +3537(a)X +3606(single)X +3830(mechanism,)X +4248(named)X +2706 3184(buddy-in-waiting.)N +3 f +2975 3338(Existing)N +3274(UNIX)X +3499(Hashing)X +3802(Techniques)X +1 f +2878 3470(Over)N +3076(the)X +3210(last)X +3357(decade,)X +3637(several)X +3901(dynamic)X +4213(hashing)X +2706 3558(schemes)N +3000(have)X +3174(been)X +3348(developed)X +3700(for)X +3816(the)X +3936(UNIX)X +4159(timeshar-)X +2706 3646(ing)N +2856(system,)X +3146(starting)X +3433(with)X +3622(the)X +3767(inclusion)X +4107(of)X +2 f +4221(dbm)X +1 f +4359(,)X +4426(a)X +2706 3734(minimal)N +3008(database)X +3321(library)X +3571(written)X +3834(by)X +3950(Ken)X +4120(Thompson)X +2706 3822([THOM90],)N +3141(in)X +3248(the)X +3391(Seventh)X +3694(Edition)X +3974(UNIX)X +4220(system.)X +2706 3910(Since)N +2916(then,)X +3106(an)X +3214(extended)X +3536(version)X +3804(of)X +3903(the)X +4032(same)X +4228(library,)X +2 f +2706 3998(ndbm)N +1 f +2884(,)X +2933(and)X +3078(a)X +3142(public-domain)X +3637(clone)X +3839(of)X +3934(the)X +4060(latter,)X +2 f +4273(sdbm)X +1 f +4442(,)X +2706 4086(have)N +2902(been)X +3098(developed.)X +3491(Another)X +3797 0.1645(interface-compatible)AX +2706 4174(library)N +2 f +2950(gdbm)X +1 f +3128(,)X +3178(was)X +3333(recently)X +3622(made)X +3826(available)X +4145(as)X +4241(part)X +4395(of)X +2706 4262(the)N +2829(Free)X +2997(Software)X +3312(Foundation's)X +3759(\(FSF\))X +3970(software)X +4271(distri-)X +2706 4350(bution.)N +2878 4464(All)N +3017(of)X +3121(these)X +3323(implementations)X +3893(are)X +4029(based)X +4248(on)X +4364(the)X +2706 4552(idea)N +2871(of)X +2969(revealing)X +3299(just)X +3445(enough)X +3711(bits)X +3856(of)X +3953(a)X +4019(hash)X +4196(value)X +4400(to)X +2706 4640(locate)N +2920(a)X +2978(page)X +3151(in)X +3234(a)X +3291(single)X +3503(access.)X +3770(While)X +2 f +3987(dbm/ndbm)X +1 f +4346(and)X +2 f +2706 4728(sdbm)N +1 f +2908(map)X +3079(the)X +3210(hash)X +3390(value)X +3597(directly)X +3874(to)X +3968(a)X +4036(disk)X +4201(address,)X +2 f +2706 4816(gdbm)N +1 f +2921(uses)X +3096(the)X +3231(hash)X +3414(value)X +3624(to)X +3722(index)X +3936(into)X +4096(a)X +2 f +4168(directory)X +1 f +2706 4904([ENB88])N +3020(containing)X +3378(disk)X +3531(addresses.)X +2878 5018(The)N +2 f +3033(hsearch)X +1 f +3317(routines)X +3605(in)X +3697(System)X +3962(V)X +4049(are)X +4177(designed)X +2706 5106(to)N +2804(provide)X +3085(memory-resident)X +3669(hash)X +3852(tables.)X +4115(Since)X +4328(data)X +2706 5194(access)N +2948(does)X +3131(not)X +3269(require)X +3533(disk)X +3702(access,)X +3964(simple)X +4213(hashing)X +2706 5282(schemes)N +3010(which)X +3238(may)X +3408(require)X +3667(multiple)X +3964(probes)X +4209(into)X +4364(the)X +2706 5370(table)N +2889(are)X +3015(used.)X +3209(A)X +3294(more)X +3486(interesting)X +3851(version)X +4114(of)X +2 f +4208(hsearch)X +1 f +2706 5458(is)N +2784(a)X +2845(public)X +3070(domain)X +3335(library,)X +2 f +3594(dynahash)X +1 f +3901(,)X +3945(that)X +4089(implements)X +2706 5546(Larson's)N +3036(in-memory)X +3440(adaptation)X +3822([LAR88])X +4164(of)X +4279(linear)X +2706 5634(hashing)N +2975([LIT80].)X +3 f +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +1 f +4424(1)X + +2 p +%%Page: 2 2 +10 s 10 xH 0 xS 1 f +3 f +432 258(A)N +510(New)X +682(Hashing)X +985(Package)X +1290(for)X +1413(UNIX)X +3663(Seltzer)X +3920(&)X +4007(Yigit)X +2 f +1074 538(dbm)N +1 f +1232(and)X +2 f +1368(ndbm)X +1 f +604 670(The)N +2 f +760(dbm)X +1 f +928(and)X +2 f +1074(ndbm)X +1 f +1282(library)X +1526(implementations)X +2089(are)X +432 758(based)N +667(on)X +799(the)X +949(same)X +1166(algorithm)X +1529(by)X +1661(Ken)X +1846(Thompson)X +432 846([THOM90,)N +824(TOR88,)X +1113(WAL84],)X +1452(but)X +1582(differ)X +1789(in)X +1879(their)X +2054(pro-)X +432 934(grammatic)N +801(interfaces.)X +1160(The)X +1311(latter)X +1502(is)X +1581(a)X +1643(modi\256ed)X +1952(version)X +432 1022(of)N +533(the)X +665(former)X +918(which)X +1148(adds)X +1328(support)X +1601(for)X +1728(multiple)X +2027(data-)X +432 1110(bases)N +634(to)X +724(be)X +828(open)X +1011(concurrently.)X +1484(The)X +1636(discussion)X +1996(of)X +2090(the)X +432 1198(algorithm)N +774(that)X +925(follows)X +1196(is)X +1280(applicable)X +1640(to)X +1732(both)X +2 f +1904(dbm)X +1 f +2072(and)X +2 f +432 1286(ndbm)N +1 f +610(.)X +604 1400(The)N +760(basic)X +956(structure)X +1268(of)X +2 f +1366(dbm)X +1 f +1535(calls)X +1712(for)X +1836(\256xed-sized)X +432 1488(disk)N +612(blocks)X +868(\(buckets\))X +1214(and)X +1377(an)X +2 f +1499(access)X +1 f +1755(function)X +2068(that)X +432 1576(maps)N +623(a)X +681(key)X +819(to)X +902(a)X +959(bucket.)X +1234(The)X +1380(interface)X +1683(routines)X +1962(use)X +2090(the)X +2 f +432 1664(access)N +1 f +673(function)X +970(to)X +1062(obtain)X +1292(the)X +1420(appropriate)X +1816(bucket)X +2060(in)X +2152(a)X +432 1752(single)N +643(disk)X +796(access.)X +604 1866(Within)N +869(the)X +2 f +1010(access)X +1 f +1263(function,)X +1593(a)X +1672(bit-randomizing)X +432 1954(hash)N +610(function)X +2 f +8 s +877 1929(2)N +1 f +10 s +940 1954(is)N +1024(used)X +1202(to)X +1294(convert)X +1565(a)X +1631(key)X +1777(into)X +1931(a)X +1997(32-bit)X +432 2042(hash)N +605(value.)X +825(Out)X +971(of)X +1064(these)X +1254(32)X +1359(bits,)X +1519(only)X +1686(as)X +1778(many)X +1981(bits)X +2121(as)X +432 2130(necessary)N +773(are)X +900(used)X +1075(to)X +1165(determine)X +1514(the)X +1639(particular)X +1974(bucket)X +432 2218(on)N +533(which)X +750(a)X +807(key)X +944(resides.)X +1228(An)X +1347(in-memory)X +1724(bitmap)X +1967(is)X +2041(used)X +432 2306(to)N +533(determine)X +893(how)X +1070(many)X +1287(bits)X +1441(are)X +1579(required.)X +1905(Each)X +2104(bit)X +432 2394(indicates)N +746(whether)X +1033(its)X +1136(associated)X +1494(bucket)X +1736(has)X +1871(been)X +2051(split)X +432 2482(yet)N +562(\(a)X +657(0)X +728(indicating)X +1079(that)X +1230(the)X +1359(bucket)X +1604(has)X +1742(not)X +1875(yet)X +2004(split\).)X +432 2570(The)N +590(use)X +730(of)X +830(the)X +961(hash)X +1141(function)X +1441(and)X +1590(the)X +1720(bitmap)X +1974(is)X +2059(best)X +432 2658(described)N +769(by)X +878(stepping)X +1177(through)X +1454(database)X +1759(creation)X +2046(with)X +432 2746(multiple)N +718(invocations)X +1107(of)X +1194(a)X +2 f +1250(store)X +1 f +1430(operation.)X +604 2860(Initially,)N +906(the)X +1033(hash)X +1209(table)X +1394(contains)X +1690(a)X +1755(single)X +1974(bucket)X +432 2948(\(bucket)N +711(0\),)X +836(the)X +972(bit)X +1094(map)X +1270(contains)X +1575(a)X +1649(single)X +1878(bit)X +2000(\(bit)X +2148(0)X +432 3036(corresponding)N +913(to)X +997(bucket)X +1233(0\),)X +1342(and)X +1480(0)X +1542(bits)X +1699(of)X +1788(a)X +1846(hash)X +2014(value)X +432 3124(are)N +560(examined)X +901(to)X +992(determine)X +1342(where)X +1568(a)X +1633(key)X +1778(is)X +1860(placed)X +2099(\(in)X +432 3212(bucket)N +670(0\).)X +801(When)X +1017(bucket)X +1255(0)X +1319(is)X +1396(full,)X +1551(its)X +1650(bit)X +1758(in)X +1844(the)X +1966(bitmap)X +432 3300(\(bit)N +564(0\))X +652(is)X +726(set,)X +856(and)X +993(its)X +1089(contents)X +1377(are)X +1497(split)X +1655(between)X +1943(buckets)X +432 3388(0)N +499(and)X +641(1,)X +727(by)X +833(considering)X +1233(the)X +1357(0)X +2 f +7 s +3356(th)Y +10 s +1 f +1480 3388(bit)N +1590(\(the)X +1741(lowest)X +1976(bit)X +2086(not)X +432 3476(previously)N +800(examined\))X +1169(of)X +1266(the)X +1393(hash)X +1569(value)X +1772(for)X +1895(each)X +2072(key)X +432 3564(within)N +668(the)X +798(bucket.)X +1064(Given)X +1292(a)X +1359(well-designed)X +1840(hash)X +2018(func-)X +432 3652(tion,)N +613(approximately)X +1112(half)X +1273(of)X +1376(the)X +1510(keys)X +1693(will)X +1853(have)X +2041(hash)X +432 3740(values)N +666(with)X +837(the)X +964(0)X +2 f +7 s +3708(th)Y +10 s +1 f +1090 3740(bit)N +1203(set.)X +1341(All)X +1471(such)X +1646(keys)X +1821(and)X +1965(associ-)X +432 3828(ated)N +586(data)X +740(are)X +859(moved)X +1097(to)X +1179(bucket)X +1413(1,)X +1493(and)X +1629(the)X +1747(rest)X +1883(remain)X +2126(in)X +432 3916(bucket)N +666(0.)X +604 4030(After)N +804(this)X +949(split,)X +1135(the)X +1262(\256le)X +1393(now)X +1560(contains)X +1856(two)X +2005(buck-)X +432 4118(ets,)N +562(and)X +699(the)X +818(bitmap)X +1061(contains)X +1349(three)X +1530(bits:)X +1687(the)X +1805(0)X +2 f +7 s +4086(th)Y +10 s +1 f +1922 4118(bit)N +2026(is)X +2099(set)X +432 4206(to)N +525(indicate)X +810(a)X +876(bucket)X +1120(0)X +1190(split)X +1357(when)X +1561(no)X +1671(bits)X +1816(of)X +1913(the)X +2041(hash)X +432 4294(value)N +648(are)X +789(considered,)X +1199(and)X +1357(two)X +1519(more)X +1726(unset)X +1937(bits)X +2094(for)X +432 4382(buckets)N +706(0)X +775(and)X +920(1.)X +1029(The)X +1183(placement)X +1542(of)X +1638(an)X +1742(incoming)X +2072(key)X +432 4470(now)N +604(requires)X +897(examination)X +1327(of)X +1428(the)X +1560(0)X +2 f +7 s +4438(th)Y +10 s +1 f +1691 4470(bit)N +1809(of)X +1910(the)X +2041(hash)X +432 4558(value,)N +667(and)X +824(the)X +963(key)X +1119(is)X +1212(placed)X +1462(either)X +1685(in)X +1787(bucket)X +2041(0)X +2121(or)X +432 4646(bucket)N +674(1.)X +782(If)X +864(either)X +1075(bucket)X +1317(0)X +1385(or)X +1480(bucket)X +1722(1)X +1790(\256lls)X +1937(up,)X +2064(it)X +2135(is)X +432 4734(split)N +598(as)X +693(before,)X +947(its)X +1050(bit)X +1162(is)X +1243(set)X +1360(in)X +1450(the)X +1576(bitmap,)X +1846(and)X +1990(a)X +2054(new)X +432 4822(set)N +541(of)X +628(unset)X +817(bits)X +952(are)X +1071(added)X +1283(to)X +1365(the)X +1483(bitmap.)X +604 4936(Each)N +791(time)X +959(we)X +1079(consider)X +1376(a)X +1437(new)X +1596(bit)X +1705(\(bit)X +1841(n\),)X +1953(we)X +2072(add)X +432 5024(2)N +2 f +7 s +4992(n)Y +9 f +509(+)X +1 f +540(1)X +10 s +595 5024(bits)N +737(to)X +826(the)X +951(bitmap)X +1199(and)X +1341(obtain)X +1567(2)X +2 f +7 s +4992(n)Y +9 f +1644(+)X +1 f +1675(1)X +10 s +1729 5024(more)N +1920(address-)X +432 5112(able)N +595(buckets)X +869(in)X +960(the)X +1087(\256le.)X +1258(As)X +1376(a)X +1441(result,)X +1668(the)X +1795(bitmap)X +2045(con-)X +432 5200(tains)N +618(the)X +751(previous)X +1062(2)X +2 f +7 s +5168(n)Y +9 f +1139(+)X +1 f +1170(1)X +2 f +10 s +9 f +5200(-)Y +1 f +1242(1)X +1317(bits)X +1467(\(1)X +2 f +9 f +1534(+)X +1 f +1578(2)X +2 f +9 f +(+)S +1 f +1662(4)X +2 f +9 f +(+)S +1 f +1746(...)X +2 f +9 f +(+)S +1 f +1850(2)X +2 f +7 s +5168(n)Y +10 s +1 f +1931 5200(\))N +1992(which)X +432 5288(trace)N +649(the)X +807(entire)X +2 f +1050(split)X +1247(history)X +1 f +1529(of)X +1656(the)X +1813(addressable)X +16 s +432 5433 MXY +864 0 Dl +2 f +8 s +472 5488(2)N +1 f +9 s +523 5513(This)N +670(bit-randomizing)X +1153(property)X +1416(is)X +1482(important)X +1780(to)X +1854(obtain)X +2052(radi-)X +432 5593(cally)N +599(different)X +874(hash)X +1033(values)X +1244(for)X +1355(nearly)X +1562(identical)X +1836(keys,)X +2012(which)X +432 5673(in)N +506(turn)X +640(avoids)X +846(clustering)X +1148(of)X +1226(such)X +1376(keys)X +1526(in)X +1600(a)X +1650(single)X +1840(bucket.)X +10 s +2418 538(buckets.)N +2590 652(Given)N +2809(a)X +2868(key)X +3007(and)X +3146(the)X +3267(bitmap)X +3512(created)X +3768(by)X +3871(this)X +4009(algo-)X +2418 740(rithm,)N +2638(we)X +2759(\256rst)X +2910(examine)X +3209(bit)X +3320(0)X +3386(of)X +3479(the)X +3603(bitmap)X +3851(\(the)X +4002(bit)X +4112(to)X +2418 828(consult)N +2673(when)X +2871(0)X +2934(bits)X +3072(of)X +3162(the)X +3283(hash)X +3453(value)X +3650(are)X +3772(being)X +3973(exam-)X +2418 916(ined\).)N +2631(If)X +2713(it)X +2785(is)X +2866(set)X +2982(\(indicating)X +3356(that)X +3503(the)X +3628(bucket)X +3869(split\),)X +4080(we)X +2418 1004(begin)N +2617(considering)X +3012(the)X +3131(bits)X +3267(of)X +3355(the)X +3473(32-bit)X +3684(hash)X +3851(value.)X +4085(As)X +2418 1092(bit)N +2525(n)X +2587(is)X +2662(revealed,)X +2977(a)X +3035(mask)X +3226(equal)X +3422(to)X +3506(2)X +2 f +7 s +1060(n)Y +9 f +3583(+)X +1 f +3614(1)X +2 f +10 s +9 f +1092(-)Y +1 f +3686(1)X +3748(will)X +3894(yield)X +4076(the)X +2418 1180(current)N +2675(bucket)X +2918(address.)X +3228(Adding)X +3496(2)X +2 f +7 s +1148(n)Y +9 f +3573(+)X +1 f +3604(1)X +2 f +10 s +9 f +1180(-)Y +1 f +3676(1)X +3744(to)X +3834(the)X +3960(bucket)X +2418 1268(address)N +2701(identi\256es)X +3035(which)X +3272(bit)X +3397(in)X +3500(the)X +3639(bitmap)X +3902(must)X +4098(be)X +2418 1356(checked.)N +2743(We)X +2876(continue)X +3173(revealing)X +3493(bits)X +3628(of)X +3715(the)X +3833(hash)X +4000(value)X +2418 1444(until)N +2591(all)X +2698(set)X +2814(bits)X +2955(in)X +3043(the)X +3167(bitmap)X +3415(are)X +3540(exhausted.)X +3907(The)X +4058(fol-)X +2418 1532(lowing)N +2682(algorithm,)X +3055(a)X +3133(simpli\256cation)X +3614(of)X +3723(the)X +3863(algorithm)X +2418 1620(due)N +2565(to)X +2658(Ken)X +2823(Thompson)X +3196([THOM90,)X +3590(TOR88],)X +3908(uses)X +4076(the)X +2418 1708(hash)N +2625(value)X +2839(and)X +2995(the)X +3133(bitmap)X +3395(to)X +3497(calculate)X +3823(the)X +3960(bucket)X +2418 1796(address)N +2679(as)X +2766(discussed)X +3093(above.)X +0(Courier)xf 0 f +1 f +0 f +8 s +2418 2095(hash)N +2608(=)X +2684 -0.4038(calchash\(key\);)AX +2418 2183(mask)N +2608(=)X +2684(0;)X +2418 2271(while)N +2646 -0.4018(\(isbitset\(\(hash)AX +3254(&)X +3330(mask\))X +3558(+)X +3634(mask\)\))X +2706 2359(mask)N +2896(=)X +2972(\(mask)X +3200(<<)X +3314(1\))X +3428(+)X +3504(1;)X +2418 2447(bucket)N +2684(=)X +2760(hash)X +2950(&)X +3026(mask;)X +2 f +10 s +3211 2812(sdbm)N +1 f +2590 2944(The)N +2 f +2738(sdbm)X +1 f +2930(library)X +3167(is)X +3243(a)X +3302(public-domain)X +3791(clone)X +3987(of)X +4076(the)X +2 f +2418 3032(ndbm)N +1 f +2638(library,)X +2914(developed)X +3286(by)X +3408(Ozan)X +3620(Yigit)X +3826(to)X +3929(provide)X +2 f +2418 3120(ndbm)N +1 f +2596('s)X +2692(functionality)X +3139(under)X +3359(some)X +3565(versions)X +3869(of)X +3973(UNIX)X +2418 3208(that)N +2559(exclude)X +2830(it)X +2894(for)X +3008(licensing)X +3317(reasons)X +3578([YIG89].)X +3895(The)X +4040(pro-)X +2418 3296(grammer)N +2735(interface,)X +3064(and)X +3207(the)X +3332(basic)X +3524(structure)X +3832(of)X +2 f +3926(sdbm)X +1 f +4121(is)X +2418 3384(identical)N +2733(to)X +2 f +2834(ndbm)X +1 f +3051(but)X +3192(internal)X +3476(details)X +3723(of)X +3828(the)X +2 f +3964(access)X +1 f +2418 3472(function,)N +2726(such)X +2894(as)X +2982(the)X +3101(calculation)X +3474(of)X +3561(the)X +3679(bucket)X +3913(address,)X +2418 3560(and)N +2563(the)X +2690(use)X +2825(of)X +2920(different)X +3225(hash)X +3400(functions)X +3726(make)X +3928(the)X +4054(two)X +2418 3648(incompatible)N +2856(at)X +2934(the)X +3052(database)X +3349(level.)X +2590 3762(The)N +2 f +2740(sdbm)X +1 f +2934(library)X +3173(is)X +3251(based)X +3458(on)X +3562(a)X +3622(simpli\256ed)X +3965(imple-)X +2418 3850(mentation)N +2778(of)X +2885(Larson's)X +3206(1978)X +2 f +3406(dynamic)X +3717(hashing)X +1 f +4009(algo-)X +2418 3938(rithm)N +2616(including)X +2943(the)X +2 f +3066(re\256nements)X +3461(and)X +3605(variations)X +1 f +3953(of)X +4044(sec-)X +2418 4026(tion)N +2562(5)X +2622([LAR78].)X +2956(Larson's)X +3257(original)X +3526(algorithm)X +3857(calls)X +4024(for)X +4138(a)X +2418 4114(forest)N +2635(of)X +2736(binary)X +2975(hash)X +3156(trees)X +3341(that)X +3494(are)X +3626(accessed)X +3941(by)X +4054(two)X +2418 4202(hash)N +2586(functions.)X +2925(The)X +3071(\256rst)X +3216(hash)X +3384(function)X +3672(selects)X +3907(a)X +3964(partic-)X +2418 4290(ular)N +2571(tree)X +2720(within)X +2952(the)X +3078(forest.)X +3309(The)X +3462(second)X +3713(hash)X +3887(function,)X +2418 4378(which)N +2659(is)X +2757(required)X +3070(to)X +3177(be)X +3297(a)X +3377(boolean)X +3675(pseudo-random)X +2418 4466(number)N +2687(generator)X +3015(that)X +3159(is)X +3236(seeded)X +3479(by)X +3583(the)X +3705(key,)X +3865(is)X +3942(used)X +4112(to)X +2418 4554(traverse)N +2733(the)X +2890(tree)X +3070(until)X +3275(internal)X +3579(\(split\))X +3829(nodes)X +4075(are)X +2418 4642(exhausted)N +2763(and)X +2903(an)X +3003(external)X +3286(\(non-split\))X +3648(node)X +3827(is)X +3903(reached.)X +2418 4730(The)N +2571(bucket)X +2813(addresses)X +3149(are)X +3276(stored)X +3500(directly)X +3772(in)X +3861(the)X +3986(exter-)X +2418 4818(nal)N +2536(nodes.)X +2590 4932(Larson's)N +2903(re\256nements)X +3309(are)X +3440(based)X +3655(on)X +3767(the)X +3897(observa-)X +2418 5020(tion)N +2570(that)X +2718(the)X +2844(nodes)X +3059(can)X +3199(be)X +3303(represented)X +3702(by)X +3809(a)X +3872(single)X +4090(bit)X +2418 5108(that)N +2569(is)X +2653(set)X +2773(for)X +2898(internal)X +3174(nodes)X +3392(and)X +3539(not)X +3672(set)X +3791(for)X +3915(external)X +2418 5196(nodes,)N +2652(resulting)X +2959(in)X +3048(a)X +3111(radix)X +3303(search)X +3536(trie.)X +3709(Figure)X +3944(1)X +4010(illus-)X +2418 5284(trates)N +2621(this.)X +2804(Nodes)X +3037(A)X +3123(and)X +3267(B)X +3348(are)X +3475(internal)X +3748(\(split\))X +3967(nodes,)X +2418 5372(thus)N +2573(having)X +2813(no)X +2915(bucket)X +3151(addresses)X +3480(associated)X +3831(with)X +3994(them.)X +2418 5460(Instead,)N +2693(the)X +2814(external)X +3096(nodes)X +3306(\(C,)X +3429(D,)X +3530(and)X +3669(E\))X +3768(each)X +3938(need)X +4112(to)X +2418 5548(refer)N +2594(to)X +2679(a)X +2738(bucket)X +2975(address.)X +3279(These)X +3494(bucket)X +3731(addresses)X +4062(can)X +2418 5636(be)N +2529(stored)X +2760(in)X +2857(the)X +2990(trie)X +3132(itself)X +3327(where)X +3559(the)X +3691(subtries)X +3974(would)X +3 f +432 5960(2)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +3 p +%%Page: 3 3 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +720 258(Seltzer)N +977(&)X +1064(Yigit)X +3278(A)X +3356(New)X +3528(Hashing)X +3831(Package)X +4136(for)X +4259(UNIX)X +1 f +720 538(live)N +862(if)X +933(they)X +1092(existed)X +1340([KNU68].)X +1709(For)X +1841(example,)X +2154(if)X +2224(nodes)X +2432(F)X +720 626(and)N +858(G)X +938(were)X +1117(the)X +1237(children)X +1522(of)X +1610(node)X +1787(C,)X +1881(the)X +2000(bucket)X +2235(address)X +720 714(L00)N +886(could)X +1101(reside)X +1330(in)X +1429(the)X +1563(bits)X +1714(that)X +1870(will)X +2030(eventually)X +2400(be)X +720 802(used)N +887(to)X +969(store)X +1145(nodes)X +1352(F)X +1416(and)X +1552(G)X +1630(and)X +1766(all)X +1866(their)X +2033(children.)X +10 f +720 890 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +1894 2247(L1)N +784 1925(A)N +1431(E)X +1106 2247(D)N +1428 1281(C)N +1109 1603(B)N +1884 1930(L01)N +1879 1286(L00)N +1221 1814(1)N +903 2131(1)N +1221 1402(0)N +903 1714(0)N +1 Dt +1397 1821 MXY +-8 -32 Dl +-5 19 Dl +-20 6 Dl +33 7 Dl +-187 -182 Dl +1397 1322 MXY +-33 7 Dl +20 6 Dl +5 19 Dl +8 -32 Dl +-187 182 Dl +1069 1639 MXY +-32 7 Dl +20 6 Dl +5 19 Dl +7 -32 Dl +-186 182 Dl +1374 1891 MXY +185 Dc +1779 2133 MXY +0 161 Dl +322 0 Dl +0 -161 Dl +-322 0 Dl +1811 MY +0 161 Dl +322 0 Dl +0 -161 Dl +-322 0 Dl +1166 MY +0 161 Dl +322 0 Dl +0 -161 Dl +-322 0 Dl +1052 2213 MXY +185 Dc +1569 MY +185 Dc +720 1881 MXY +185 Dc +1779 2213 MXY +-28 -17 Dl +10 17 Dl +-10 18 Dl +28 -18 Dl +-543 0 Dl +1769 1891 MXY +-28 -18 Dl +10 18 Dl +-10 18 Dl +28 -18 Dl +-201 0 Dl +1364 1247 MXY +185 Dc +1769 MX +-28 -18 Dl +10 18 Dl +-10 18 Dl +28 -18 Dl +-201 0 Dl +1064 2143 MXY +-7 -32 Dl +-5 19 Dl +-20 6 Dl +32 7 Dl +-181 -181 Dl +3 Dt +-1 Ds +8 s +720 2482(Figure)N +925(1:)X +1 f +1002(Radix)X +1179(search)X +1365(trie)X +1474(with)X +1612(internal)X +1831(nodes)X +2004(A)X +2074(and)X +2189(B,)X +2271(external)X +720 2570(nodes)N +891(C,)X +972(D,)X +1056(and)X +1170(E,)X +1247(and)X +1361(bucket)X +1553(addresses)X +1819(stored)X +1997(in)X +2069(the)X +2168(unused)X +2370(por-)X +720 2658(tion)N +836(of)X +905(the)X +999(trie.)X +10 s +10 f +720 2922 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +1 f +892 3124(Further)N +1153(simpli\256cations)X +1647(of)X +1738(the)X +1860(above)X +2076([YIG89])X +2377(are)X +720 3212(possible.)N +1038(Using)X +1265(a)X +1337(single)X +1564(radix)X +1765(trie)X +1908(to)X +2006(avoid)X +2219(the)X +2352(\256rst)X +720 3300(hash)N +904(function,)X +1227(replacing)X +1562(the)X +1696(pseudo-random)X +2231(number)X +720 3388(generator)N +1052(with)X +1222(a)X +1286(well)X +1452(designed,)X +1785(bit-randomizing)X +2329(hash)X +720 3476(function,)N +1053(and)X +1215(using)X +1434(the)X +1578(portion)X +1855(of)X +1967(the)X +2110(hash)X +2302(value)X +720 3564(exposed)N +1021(during)X +1268(the)X +1404(trie)X +1549(traversal)X +1864(as)X +1969(a)X +2042(direct)X +2262(bucket)X +720 3652(address)N +990(results)X +1228(in)X +1319(an)X +2 f +1424(access)X +1 f +1663(function)X +1959(that)X +2108(works)X +2333(very)X +720 3740(similar)N +974(to)X +1068(Thompson's)X +1499(algorithm)X +1841(above.)X +2084(The)X +2240(follow-)X +720 3828(ing)N +847(algorithm)X +1183(uses)X +1346(the)X +1469(hash)X +1641(value)X +1840(to)X +1927(traverse)X +2206(a)X +2266(linear-)X +720 3916(ized)N +874(radix)X +1059(trie)X +2 f +8 s +1166 3891(3)N +1 f +10 s +1218 3916(starting)N +1478(at)X +1556(the)X +1674(0)X +2 f +7 s +3884(th)Y +10 s +1 f +1791 3916(bit.)N +0 f +8 s +720 4215(tbit)N +910(=)X +986(0;)X +1296(/*)X +1410(radix)X +1638(trie)X +1828(index)X +2056(*/)X +720 4303(hbit)N +910(=)X +986(0;)X +1296(/*)X +1410(hash)X +1600(bit)X +1752(index)X +2056(*/)X +720 4391(mask)N +910(=)X +986(0;)X +720 4479(hash)N +910(=)X +986 -0.4038(calchash\(key\);)AX +720 4655(for)N +872(\(mask)X +1100(=)X +1176(0;)X +910 4743 -0.4018(isbitset\(tbit\);)AN +910 4831(mask)N +1100(=)X +1176(\(mask)X +1404(<<)X +1518(1\))X +1632(+)X +1708(1\))X +1008 4919(if)N +1122(\(hash)X +1350(&)X +1426(\(1)X +1540(<<)X +1654 -0.4219(hbit++\)\)\))AX +1160 5007(/*)N +1274(right)X +1502(son)X +1692(*/)X +1160 5095(tbit)N +1350(=)X +1426(2)X +1502(*)X +1578(tbit)X +1768(+)X +1844(2;)X +1008 5183(else)N +1 f +16 s +720 5353 MXY +864 0 Dl +2 f +8 s +760 5408(3)N +1 f +9 s +818 5433(A)N +896(linearized)X +1206(radix)X +1380(trie)X +1502(is)X +1576(merely)X +1802(an)X +1895(array)X +2068(representation)X +720 5513(of)N +800(the)X +908(radix)X +1076(search)X +1280(trie)X +1396(described)X +1692(above.)X +1920(The)X +2052(children)X +2308(of)X +2388(the)X +720 5593(node)N +885(with)X +1038(index)X +1223(i)X +1267(can)X +1391(be)X +1483(found)X +1675(at)X +1751(the)X +1863(nodes)X +2055(indexed)X +2307(2*i+1)X +720 5673(and)N +842(2*i+2.)X +0 f +8 s +3146 538(/*)N +3260(left)X +3450(son)X +3678(*/)X +3146 626(tbit)N +3336(=)X +3412(2)X +3488(*)X +3564(tbit)X +3754(+)X +3830(1;)X +2706 802(bucket)N +2972(=)X +3048(hash)X +3238(&)X +3314(mask;)X +2 f +10 s +3495 1167(gdbm)N +1 f +2878 1299(The)N +3027(gdbm)X +3233(\(GNU)X +3458(data)X +3616(base)X +3783(manager\))X +4111(library)X +4349(is)X +4426(a)X +2706 1387(UNIX)N +2933(database)X +3236(manager)X +3539(written)X +3792(by)X +3897(Philip)X +4112(A.)X +4215(Nelson,)X +2706 1475(and)N +2848(made)X +3048(available)X +3364(as)X +3457(a)X +3518(part)X +3668(of)X +3760(the)X +3883(FSF)X +4040(software)X +4342(dis-)X +2706 1563(tribution.)N +3052(The)X +3207(gdbm)X +3419(library)X +3663(provides)X +3969(the)X +4097(same)X +4292(func-)X +2706 1651(tionality)N +3028(of)X +3151(the)X +2 f +3304(dbm)X +1 f +3442(/)X +2 f +3464(ndbm)X +1 f +3697(libraries)X +4015([NEL90])X +4360(but)X +2706 1739(attempts)N +3018(to)X +3121(avoid)X +3340(some)X +3550(of)X +3658(their)X +3846(shortcomings.)X +4337(The)X +2706 1827(gdbm)N +2918(library)X +3162(allows)X +3401(for)X +3525(arbitrary-length)X +4059(data,)X +4242(and)X +4387(its)X +2706 1915(database)N +3027(is)X +3124(a)X +3203(singular,)X +3524(non-sparse)X +2 f +8 s +3872 1890(4)N +1 f +10 s +3947 1915(\256le.)N +4112(The)X +4280(gdbm)X +2706 2003(library)N +2947(also)X +3103(includes)X +2 f +3396(dbm)X +1 f +3560(and)X +2 f +3702(ndbm)X +1 f +3906(compatible)X +4288(inter-)X +2706 2091(faces.)N +2878 2205(The)N +3025(gdbm)X +3229(library)X +3465(is)X +3540(based)X +3745(on)X +2 f +3847(extensible)X +4189(hashing)X +1 f +4442(,)X +2706 2293(a)N +2766(dynamic)X +3066(hashing)X +3339(algorithm)X +3674(by)X +3778(Fagin)X +3984(et)X +4066(al)X +4148([FAG79].)X +2706 2381(This)N +2881(algorithm)X +3225(differs)X +3467(from)X +3655(the)X +3785(previously)X +4155(discussed)X +2706 2469(algorithms)N +3069(in)X +3152(that)X +3293(it)X +3358(uses)X +3517(a)X +2 f +3574(directory)X +1 f +3889(that)X +4030(is)X +4103(a)X +4159(collapsed)X +2706 2557(representation)N +3192([ENB88])X +3517(of)X +3615(the)X +3744(radix)X +3940(search)X +4177(trie)X +4315(used)X +2706 2645(by)N +2 f +2806(sdbm)X +1 f +2975(.)X +10 f +2706 2733 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +7 s +3572 3761(L1)N +1 Dt +3485 3738 MXY +-20 -13 Dl +7 13 Dl +-7 13 Dl +20 -13 Dl +-400 0 Dl +3180 3027 MXY +136 Dc +2706 3494 MXY +136 Dc +2950 3264 MXY +136 Dc +3738 MY +136 Dc +3485 2968 MXY +0 118 Dl +238 0 Dl +0 -118 Dl +-238 0 Dl +3442 MY +0 119 Dl +238 0 Dl +0 -119 Dl +-238 0 Dl +3679 MY +0 119 Dl +238 0 Dl +0 -119 Dl +-238 0 Dl +3187 3501 MXY +136 Dc +2963 3316 MXY +-24 5 Dl +15 4 Dl +4 15 Dl +5 -24 Dl +-137 134 Dl +3204 3083 MXY +-24 5 Dl +15 4 Dl +3 14 Dl +6 -23 Dl +-137 133 Dl +3204 3450 MXY +-6 -24 Dl +-3 14 Dl +-15 5 Dl +24 5 Dl +-137 -134 Dl +2842 3369(0)N +3075 3139(0)N +2842 3676(1)N +3075 3443(1)N +3562 3054(L00)N +3565 3528(L01)N +4197 2968 MXY +0 118 Dl +237 0 Dl +0 -118 Dl +-237 0 Dl +3205 MY +0 119 Dl +237 0 Dl +0 -119 Dl +-237 0 Dl +3561 MY +0 118 Dl +237 0 Dl +0 -118 Dl +-237 0 Dl +3960 2909 MXY +0 237 Dl +118 0 Dl +0 -237 Dl +-118 0 Dl +3146 MY +0 237 Dl +118 0 Dl +0 -237 Dl +-118 0 Dl +3383 MY +0 237 Dl +118 0 Dl +0 -237 Dl +-118 0 Dl +3620 MY +0 237 Dl +118 0 Dl +0 -237 Dl +-118 0 Dl +4197 3027 MXY +-21 -13 Dl +8 13 Dl +-8 13 Dl +21 -13 Dl +-119 0 Dl +4197 3264 MXY +-21 -13 Dl +8 13 Dl +-8 13 Dl +21 -13 Dl +-119 0 Dl +3501 MY +59 0 Dl +0 89 Dl +4078 3738 MXY +59 0 Dl +0 -88 Dl +4197 3590 MXY +-21 -13 Dl +8 13 Dl +-8 13 Dl +21 -13 Dl +-60 0 Dl +4197 3650 MXY +-21 -13 Dl +8 13 Dl +-8 13 Dl +21 -13 Dl +-60 0 Dl +3991 3050(00)N +3991 3287(01)N +3991 3524(10)N +3991 3761(11)N +4269 3050(L00)N +4269 3287(L01)N +4283 3643(L1)N +3485 3501 MXY +-20 -13 Dl +7 13 Dl +-7 13 Dl +20 -13 Dl +-155 0 Dl +3485 3027 MXY +-20 -13 Dl +7 13 Dl +-7 13 Dl +20 -13 Dl +-163 0 Dl +2967 3687 MXY +-5 -24 Dl +-4 14 Dl +-15 4 Dl +24 6 Dl +-141 -141 Dl +3 Dt +-1 Ds +8 s +2706 4033(Figure)N +2903(2:)X +1 f +2972(A)X +3034(radix)X +3181(search)X +3359(trie)X +3460(and)X +3568(a)X +3612(directory)X +3858(representing)X +4189(the)X +4283(trie.)X +10 s +10 f +2706 4209 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +1 f +2878 4411(In)N +2968(this)X +3106(algorithm,)X +3460(a)X +3519(directory)X +3832(consists)X +4108(of)X +4198(a)X +4256(search)X +2706 4499(trie)N +2847(of)X +2947(depth)X +2 f +3158(n)X +1 f +3211(,)X +3264(containing)X +3635(2)X +2 f +7 s +4467(n)Y +10 s +1 f +3749 4499(bucket)N +3996(addresses)X +4337(\(i.e.)X +2706 4587(each)N +2897(element)X +3194(of)X +3304(the)X +3445(trie)X +3594(is)X +3689(a)X +3767(bucket)X +4023(address\).)X +4373(To)X +2706 4675(access)N +2935(the)X +3056(hash)X +3226(table,)X +3425(a)X +3483(32-bit)X +3696(hash)X +3865(value)X +4061(is)X +4136(calculated)X +2706 4763(and)N +2 f +2861(n)X +1 f +2953(bits)X +3107(of)X +3213(the)X +3350(value)X +3563(are)X +3701(used)X +3886(to)X +3986(index)X +4202(into)X +4364(the)X +2706 4851(directory)N +3018(to)X +3102(obtain)X +3324(a)X +3382(bucket)X +3618(address.)X +3921(It)X +3992(is)X +4067(important)X +4400(to)X +2706 4939(note)N +2866(that)X +3008(multiple)X +3296(entries)X +3532(of)X +3620(this)X +3756(directory)X +4067(may)X +4226(contain)X +2706 5027(the)N +2833(same)X +3026(bucket)X +3268(address)X +3537(as)X +3632(a)X +3696(result)X +3902(of)X +3997(directory)X +4315(dou-)X +2706 5115(bling)N +2903(during)X +3145(bucket)X +3392(splitting.)X +3706(Figure)X +3948(2)X +4021(illustrates)X +4364(the)X +2706 5203(relationship)N +3126(between)X +3436(a)X +3513(typical)X +3772(\(skewed\))X +4108(search)X +4355(trie)X +2706 5291(and)N +2850(its)X +2953(directory)X +3271(representation.)X +3774(The)X +3927(formation)X +4270(of)X +4364(the)X +2706 5379(directory)N +3016(shown)X +3245(in)X +3327(the)X +3445(\256gure)X +3652(is)X +3725(as)X +3812(follows.)X +16 s +2706 5593 MXY +864 0 Dl +2 f +8 s +2746 5648(4)N +1 f +9 s +2796 5673(It)N +2858(does)X +3008(not)X +3118(contain)X +3348(holes.)X +3 f +10 s +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +4424(3)X + +4 p +%%Page: 4 4 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +432 258(A)N +510(New)X +682(Hashing)X +985(Package)X +1290(for)X +1413(UNIX)X +3663(Seltzer)X +3920(&)X +4007(Yigit)X +1 f +604 538(Initially,)N +937(there)X +1158(is)X +1271(one)X +1446(slot)X +1620(in)X +1741(the)X +1898(directory)X +432 626(addressing)N +802(a)X +865(single)X +1083(bucket.)X +1364(The)X +1515(depth)X +1719(of)X +1812(the)X +1936(trie)X +2069(is)X +2148(0)X +432 714(and)N +577(0)X +646(bits)X +790(of)X +886(each)X +1063(hash)X +1239(value)X +1442(are)X +1570(examined)X +1910(to)X +2000(deter-)X +432 802(mine)N +624(in)X +718(which)X +946(bucket)X +1192(to)X +1286(place)X +1488(a)X +1556(key;)X +1726(all)X +1837(keys)X +2015(go)X +2126(in)X +432 890(bucket)N +682(0.)X +797(When)X +1024(this)X +1174(bucket)X +1423(is)X +1511(full,)X +1677(its)X +1787(contents)X +2089(are)X +432 978(divided)N +698(between)X +992(L0)X +1107(and)X +1249(L1)X +1363(as)X +1455(was)X +1605(done)X +1786(in)X +1873(the)X +1996(previ-)X +432 1066(ously)N +664(discussed)X +1030(algorithms.)X +1471(After)X +1700(this)X +1874(split,)X +2090(the)X +432 1154(address)N +710(of)X +814(the)X +948(second)X +1207(bucket)X +1457(must)X +1648(be)X +1760(stored)X +1992(in)X +2090(the)X +432 1242(directory.)N +796(To)X +939(accommodate)X +1438(the)X +1589(new)X +1776(address,)X +2090(the)X +432 1330(directory)N +752(is)X +835(split)X +2 f +8 s +972 1305(5)N +1 f +10 s +1330(,)Y +1054(by)X +1163(doubling)X +1476(it,)X +1569(thus)X +1731(increasing)X +2090(the)X +432 1418(depth)N +630(of)X +717(the)X +835(directory)X +1145(by)X +1245(one.)X +604 1532(After)N +813(this)X +967(split,)X +1163(a)X +1237(single)X +1466(bit)X +1588(of)X +1693(the)X +1829(hash)X +2014(value)X +432 1620(needs)N +663(to)X +773(be)X +896(examined)X +1255(to)X +1364(decide)X +1621(whether)X +1927(the)X +2072(key)X +432 1708(belongs)N +711(to)X +803(L0)X +922(or)X +1019(L1.)X +1158(Once)X +1358(one)X +1504(of)X +1601(these)X +1795(buckets)X +2069(\256lls)X +432 1796(\(L0)N +578(for)X +702(example\),)X +1051(it)X +1125(is)X +1208(split)X +1375(as)X +1472(before,)X +1728(and)X +1873(the)X +2000(direc-)X +432 1884(tory)N +585(is)X +662(split)X +823(again)X +1021(to)X +1107(make)X +1305(room)X +1498(for)X +1615(the)X +1736(address)X +2000(of)X +2090(the)X +432 1972(third)N +618(bucket.)X +927(This)X +1104(splitting)X +1400(causes)X +1645(the)X +1778(addresses)X +2121(of)X +432 2060(the)N +567(non-splitting)X +1012(bucket)X +1263(\(L1\))X +1443(to)X +1541(be)X +1653(duplicated.)X +2063(The)X +432 2148(directory)N +766(now)X +948(has)X +1099(four)X +1277(entries,)X +1555(a)X +1635(depth)X +1857(of)X +1968(2,)X +2072(and)X +432 2236(indexes)N +700(the)X +821(buckets)X +1089(L00,)X +1261(L01)X +1413(and)X +1552(L1,)X +1684(as)X +1774(shown)X +2006(in)X +2090(the)X +432 2324(Figure)N +661(2.)X +604 2438(The)N +756(crucial)X +1002(part)X +1154(of)X +1247(the)X +1371(algorithm)X +1708(is)X +1787(the)X +1911(observa-)X +432 2526(tion)N +580(that)X +724(L1)X +837(is)X +914(addressed)X +1255(twice)X +1453(in)X +1539(the)X +1661(directory.)X +1995(If)X +2073(this)X +432 2614(bucket)N +679(were)X +869(to)X +964(split)X +1134(now,)X +1324(the)X +1454(directory)X +1776(already)X +2045(con-)X +432 2702(tains)N +611(room)X +808(to)X +898(hold)X +1067(the)X +1192(address)X +1460(of)X +1554(the)X +1679(new)X +1840(bucket.)X +2121(In)X +432 2790(general,)N +711(the)X +831(relationship)X +1231(between)X +1521(the)X +1641(directory)X +1953(and)X +2090(the)X +432 2878(number)N +704(of)X +798(bucket)X +1039(addresses)X +1374(contained)X +1713(therein)X +1962(is)X +2041(used)X +432 2966(to)N +517(decide)X +750(when)X +947(to)X +1031(split)X +1190(the)X +1310(directory.)X +1662(Each)X +1845(bucket)X +2081(has)X +432 3054(a)N +505(depth,)X +740(\()X +2 f +767(n)X +7 s +3070(b)Y +10 s +1 f +848 3054(\),)N +932(associated)X +1299(with)X +1478(it)X +1558(and)X +1710(appears)X +1992(in)X +2090(the)X +432 3142(directory)N +744(exactly)X +998(2)X +2 f +7 s +3106(n)Y +9 f +1075(-)X +2 f +1106(n)X +4 s +3110(b)Y +7 s +1 f +10 s +1181 3142(times.)N +1396(When)X +1610(a)X +1668(bucket)X +1904(splits,)X +2113(its)X +432 3230(depth)N +638(increases)X +961(by)X +1069(one.)X +1253(The)X +1406(directory)X +1724(must)X +1907(split)X +2072(any)X +432 3318(time)N +602(a)X +665(bucket's)X +964(depth)X +1169(exceeds)X +1451(the)X +1576(depth)X +1781(of)X +1875(the)X +2000(direc-)X +432 3406(tory.)N +630(The)X +784(following)X +1123(code)X +1303(fragment)X +1621(helps)X +1818(to)X +1908(illustrate)X +432 3494(the)N +554(extendible)X +912(hashing)X +1185(algorithm)X +1520([FAG79])X +1838(for)X +1955(access-)X +432 3582(ing)N +554(individual)X +898(buckets)X +1163(and)X +1299(maintaining)X +1701(the)X +1819(directory.)X +0 f +8 s +432 3881(hash)N +622(=)X +698 -0.4038(calchash\(key\);)AX +432 3969(mask)N +622(=)X +698 -0.4018(maskvec[depth];)AX +432 4145(bucket)N +698(=)X +774 -0.4038(directory[hash)AX +1344(&)X +1420(mask];)X +432 4321(/*)N +546(Key)X +698 -0.4219(Insertion)AX +1078(*/)X +432 4409(if)N +546 -0.4038(\(store\(bucket,)AX +1116(key,)X +1306(data\))X +1534(==)X +1648(FAIL\))X +1876({)X +720 4497(newbl)N +948(=)X +1024 -0.4167(getpage\(\);)AX +720 4585 -0.4000(bucket->depth++;)AN +720 4673 -0.4091(newbl->depth)AN +1214(=)X +1290 -0.4038(bucket->depth;)AX +720 4761(if)N +834 -0.4038(\(bucket->depth)AX +1404(>)X +1480(depth\))X +1746({)X +1008 4849(/*)N +1122(double)X +1388 -0.4219(directory)AX +1768(*/)X +1008 4937(depth++;)N +1 f +16 s +432 5033 MXY +864 0 Dl +2 f +8 s +472 5088(5)N +1 f +9 s +534 5113(This)N +692(decision)X +962(to)X +1048(split)X +1202(the)X +1319(directory)X +1608(is)X +1685(based)X +1878(on)X +1979(a)X +2040(com-)X +432 5193(parison)N +666(of)X +748(the)X +858(depth)X +1040(of)X +1121(the)X +1230(page)X +1387(being)X +1568(split)X +1713(and)X +1838(the)X +1947(depth)X +2128(of)X +432 5273(the)N +543(trie.)X +698(In)X +781(Figure)X +992(2,)X +1069(the)X +1180(depths)X +1390(of)X +1472(both)X +1622(L00)X +1760(and)X +1886(L01)X +2024(are)X +2134(2,)X +432 5353(whereas)N +689(the)X +798(depth)X +979(of)X +1060(L1)X +1161(is)X +1230(1.)X +1323(Therefore,)X +1646(if)X +1710(L1)X +1810(were)X +1970(to)X +2046(split,)X +432 5433(the)N +543(directory)X +826(would)X +1029(not)X +1144(need)X +1303(to)X +1382(split.)X +1565(In)X +1648(reality,)X +1872(a)X +1926(bucket)X +2140(is)X +432 5513(allocated)N +727(for)X +846(the)X +969(directory)X +1264(at)X +1351(the)X +1474(time)X +1637(of)X +1732(\256le)X +1858(creation)X +2124(so)X +432 5593(although)N +707(the)X +818(directory)X +1100(splits)X +1274(logically,)X +1566(physical)X +1828(splits)X +2002(do)X +2096(not)X +432 5673(occur)N +610(until)X +760(the)X +866(\256le)X +976(becomes)X +1246(quite)X +1408(large.)X +0 f +8 s +2994 538 -0.4219(directory)AN +3374(=)X +3450 -0.3971(double\(directory\);)AX +2706 626(})N +2706 714 -0.3958(splitbucket\(bucket,)AN +3466(newbl\))X +2706 802(...)N +2418 890(})N +2 f +10 s +3169 1255(hsearch)N +1 f +2590 1387(Since)N +2 f +2807(hsearch)X +1 f +3100(does)X +3286(not)X +3427(have)X +3617(to)X +3717(translate)X +4027(hash)X +2418 1475(values)N +2659(into)X +2819(disk)X +2988(addresses,)X +3352(it)X +3432(can)X +3579(use)X +3721(much)X +3934(simpler)X +2418 1563(algorithms)N +2808(than)X +2994(those)X +3211(de\256ned)X +3495(above.)X +3775(System)X +4058(V's)X +2 f +2418 1651(hsearch)N +1 f +2708(constructs)X +3069(a)X +3141(\256xed-size)X +3489(hash)X +3671(table)X +3862(\(speci\256ed)X +2418 1739(by)N +2519(the)X +2637(user)X +2791(at)X +2869(table)X +3045(creation\).)X +3391(By)X +3504(default,)X +3767(a)X +3823(multiplica-)X +2418 1827(tive)N +2570(hash)X +2748(function)X +3046(based)X +3260(on)X +3371(that)X +3522(described)X +3861(in)X +3954(Knuth,)X +2418 1915(Volume)N +2710(3,)X +2804(section)X +3065(6.4)X +3199([KNU68])X +3541(is)X +3628(used)X +3809(to)X +3905(obtain)X +4138(a)X +2418 2003(primary)N +2694(bucket)X +2930(address.)X +3233(If)X +3309(this)X +3446(bucket)X +3681(is)X +3755(full,)X +3907(a)X +3964(secon-)X +2418 2091(dary)N +2593(multiplicative)X +3069(hash)X +3248(value)X +3454(is)X +3538(computed)X +3885(to)X +3978(de\256ne)X +2418 2179(the)N +2542(probe)X +2751(interval.)X +3062(The)X +3213(probe)X +3422(interval)X +3693(is)X +3772(added)X +3989(to)X +4076(the)X +2418 2267(original)N +2712(bucket)X +2971(address)X +3257(\(modulo)X +3573(the)X +3716(table)X +3916(size\))X +4112(to)X +2418 2355(obtain)N +2658(a)X +2734(new)X +2908(bucket)X +3162(address.)X +3483(This)X +3665(process)X +3946(repeats)X +2418 2443(until)N +2588(an)X +2688(empty)X +2911(bucket)X +3148(is)X +3224(found.)X +3474(If)X +3551(no)X +3654(bucket)X +3891(is)X +3967(found,)X +2418 2531(an)N +2514(insertion)X +2814(fails)X +2972(with)X +3134(a)X +3190(``table)X +3420(full'')X +3605(condition.)X +2590 2645(The)N +2768(basic)X +2986(algorithm)X +3350(may)X +3541(be)X +3670(modi\256ed)X +4006(by)X +4138(a)X +2418 2733(number)N +2705(of)X +2813(compile)X +3112(time)X +3295(options)X +3571(available)X +3902(to)X +4005(those)X +2418 2821(users)N +2604(with)X +2767(AT&T)X +3006(source)X +3237(code.)X +3450(First,)X +3637(the)X +3756(package)X +4040(pro-)X +2418 2909(vides)N +2638(two)X +2809(options)X +3094(for)X +3238(hash)X +3435(functions.)X +3803(Users)X +4036(may)X +2418 2997(specify)N +2690(their)X +2877(own)X +3055(hash)X +3242(function)X +3549(by)X +3669(compiling)X +4032(with)X +2418 3085(``USCR'')N +2757(de\256ned)X +3016(and)X +3155(declaring)X +3477(and)X +3616(de\256ning)X +3901(the)X +4022(vari-)X +2418 3173(able)N +2 f +2578(hcompar)X +1 f +2863(,)X +2909(a)X +2971(function)X +3263(taking)X +3488(two)X +3633(string)X +3840(arguments)X +2418 3261(and)N +2560(returning)X +2880(an)X +2982(integer.)X +3271(Users)X +3480(may)X +3643(also)X +3797(request)X +4054(that)X +2418 3349(hash)N +2587(values)X +2814(be)X +2912(computed)X +3250(simply)X +3489(by)X +3590(taking)X +3811(the)X +3930(modulo)X +2418 3437(of)N +2521(key)X +2673(\(using)X +2909(division)X +3201(rather)X +3424(than)X +3597(multiplication)X +4080(for)X +2418 3525(hash)N +2589(value)X +2787(calculation\).)X +3230(If)X +3308(this)X +3447(technique)X +3783(is)X +3859(used,)X +4049(col-)X +2418 3613(lisions)N +2651(are)X +2775(resolved)X +3072(by)X +3176(scanning)X +3485(sequentially)X +3896(from)X +4076(the)X +2418 3701(selected)N +2702(bucket)X +2941(\(linear)X +3176(probing\).)X +3517(This)X +3684(option)X +3913(is)X +3991(avail-)X +2418 3789(able)N +2572(by)X +2672(de\256ning)X +2954(the)X +3072(variable)X +3351(``DIV'')X +3622(at)X +3700(compile)X +3978(time.)X +2590 3903(A)N +2720(second)X +3015(option,)X +3311(based)X +3565(on)X +3716(an)X +3863(algorithm)X +2418 3991(discovered)N +2787(by)X +2888(Richard)X +3163(P.)X +3248(Brent,)X +3466(rearranges)X +3822(the)X +3940(table)X +4116(at)X +2418 4079(the)N +2549(time)X +2724(of)X +2824(insertion)X +3137(in)X +3232(order)X +3434(to)X +3528(speed)X +3743(up)X +3855(retrievals.)X +2418 4167(The)N +2571(basic)X +2764(idea)X +2926(is)X +3007(to)X +3097(shorten)X +3361(long)X +3531(probe)X +3741(sequences)X +4094(by)X +2418 4255(lengthening)N +2833(short)X +3030(probe)X +3249(sequences.)X +3651(Once)X +3857(the)X +3991(probe)X +2418 4343(chain)N +2613(has)X +2741(exceeded)X +3062(some)X +3252(threshold)X +3571(\(Brent)X +3796(suggests)X +4087(2\),)X +2418 4431(we)N +2541(attempt)X +2809(to)X +2899(shuf\257e)X +3145(any)X +3289(colliding)X +3601(keys)X +3776(\(keys)X +3978(which)X +2418 4519(appeared)N +2734(in)X +2821(the)X +2944(probe)X +3152(sequence)X +3471(of)X +3562(the)X +3684(new)X +3842(key\).)X +4049(The)X +2418 4607(details)N +2652(of)X +2744(this)X +2884(key)X +3025(shuf\257ing)X +3333(can)X +3469(be)X +3569(found)X +3780(in)X +3866([KNU68])X +2418 4695(and)N +2576([BRE73].)X +2946(This)X +3129(algorithm)X +3481(may)X +3660(be)X +3777(obtained)X +4094(by)X +2418 4783(de\256ning)N +2700(the)X +2818(variable)X +3097(``BRENT'')X +3487(at)X +3565(compile)X +3843(time.)X +2590 4897(A)N +2698(third)X +2899(set)X +3038(of)X +3154(options,)X +3458(obtained)X +3783(by)X +3912(de\256ning)X +2418 4985(``CHAINED'',)N +2943(use)X +3086(linked)X +3321(lists)X +3484(to)X +3581(resolve)X +3848(collisions.)X +2418 5073(Either)N +2647(of)X +2747(the)X +2878(primary)X +3164(hash)X +3343(function)X +3642(described)X +3982(above)X +2418 5161(may)N +2584(be)X +2688(used,)X +2882(but)X +3011(all)X +3118(collisions)X +3451(are)X +3577(resolved)X +3876(by)X +3983(build-)X +2418 5249(ing)N +2554(a)X +2623(linked)X +2856(list)X +2986(of)X +3086(entries)X +3333(from)X +3522(the)X +3653(primary)X +3940(bucket.)X +2418 5337(By)N +2542(default,)X +2816(new)X +2981(entries)X +3226(will)X +3381(be)X +3488(added)X +3711(to)X +3804(a)X +3871(bucket)X +4116(at)X +2418 5425(the)N +2541(beginning)X +2886(of)X +2978(the)X +3101(bucket)X +3339(chain.)X +3577(However,)X +3916(compile)X +2418 5513(options)N +2706(``SORTUP'')X +3173(or)X +3293(``SORTDOWN'')X +3908(may)X +4098(be)X +2418 5601(speci\256ed)N +2723(to)X +2805(order)X +2995(the)X +3113(hash)X +3280(chains)X +3505(within)X +3729(each)X +3897(bucket.)X +3 f +432 5960(4)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +5 p +%%Page: 5 5 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +720 258(Seltzer)N +977(&)X +1064(Yigit)X +3278(A)X +3356(New)X +3528(Hashing)X +3831(Package)X +4136(for)X +4259(UNIX)X +2 f +1444 538(dynahash)N +1 f +892 670(The)N +2 f +1054(dynahash)X +1 f +1398(library,)X +1669(written)X +1932(by)X +2048(Esmond)X +2346(Pitt,)X +720 758(implements)N +1183(Larson's)X +1554(linear)X +1827(hashing)X +2165(algorithm)X +720 846([LAR88])N +1097(with)X +1302(an)X +2 f +1440(hsearch)X +1 f +1756(compatible)X +2174(interface.)X +720 934(Intuitively,)N +1099(a)X +1161(hash)X +1334(table)X +1516(begins)X +1751(as)X +1844(a)X +1905(single)X +2121(bucket)X +2360(and)X +720 1022(grows)N +941(in)X +1028(generations,)X +1443(where)X +1665(a)X +1725(generation)X +2088(corresponds)X +720 1110(to)N +815(a)X +884(doubling)X +1201(in)X +1296(the)X +1427(size)X +1585(of)X +1685(the)X +1815(hash)X +1994(table.)X +2222(The)X +2379(0)X +2 f +7 s +1078(th)Y +10 s +1 f +720 1198(generation)N +1085(occurs)X +1321(as)X +1414(the)X +1538(table)X +1719(grows)X +1940(from)X +2121(one)X +2262(bucket)X +720 1286(to)N +814(two.)X +1006(In)X +1105(the)X +1235(next)X +1405(generation)X +1776(the)X +1906(table)X +2093(grows)X +2320(from)X +720 1374(two)N +862(to)X +946(four.)X +1122(During)X +1371(each)X +1541(generation,)X +1921(every)X +2121(bucket)X +2356(that)X +720 1462(existed)N +967(at)X +1045(the)X +1163(beginning)X +1503(of)X +1590(the)X +1708(generation)X +2067(is)X +2140(split.)X +892 1576(The)N +1041(table)X +1221(starts)X +1414(as)X +1505(a)X +1565(single)X +1780(bucket)X +2018(\(numbered)X +2389(0\),)X +720 1664(the)N +839(current)X +1088(split)X +1245(bucket)X +1479(is)X +1552(set)X +1661(to)X +1743(bucket)X +1977(0,)X +2057(and)X +2193(the)X +2311(max-)X +720 1752(imum)N +933(split)X +1097(point)X +1288(is)X +1368(set)X +1483(to)X +1571(twice)X +1771(the)X +1895(current)X +2149(split)X +2312(point)X +720 1840(\(0\).)N +863(When)X +1084(it)X +1157(is)X +1239(time)X +1410(for)X +1532(a)X +1596(bucket)X +1838(to)X +1928(split,)X +2113(the)X +2239(keys)X +2414(in)X +720 1928(the)N +872(current)X +1154(split)X +1345(bucket)X +1612(are)X +1764(divided)X +2057(between)X +2378(the)X +720 2016(current)N +981(split)X +1151(bucket)X +1397(and)X +1545(a)X +1613(new)X +1779(bucket)X +2025(whose)X +2262(bucket)X +720 2104(number)N +1000(is)X +1088(equal)X +1297(to)X +1394(1)X +1469(+)X +1549(current)X +1812(split)X +1984(bucket)X +2232(+)X +2311(max-)X +720 2192(imum)N +927(split)X +1085(point.)X +1310(We)X +1442(can)X +1574(determine)X +1915(which)X +2131(keys)X +2298(move)X +720 2280(to)N +807(the)X +929(new)X +1087(bucket)X +1325(by)X +1429(examining)X +1791(the)X +2 f +1913(n)X +7 s +1962 2248(th)N +10 s +1 f +2043 2280(bit)N +2151(of)X +2242(a)X +2302(key's)X +720 2368(hash)N +899(value)X +1105(where)X +1334(n)X +1406(is)X +1491(the)X +1620(generation)X +1990(number.)X +2306(After)X +720 2456(the)N +846(bucket)X +1088(at)X +1174(the)X +1300(maximum)X +1651(split)X +1815(point)X +2006(has)X +2140(been)X +2319(split,)X +720 2544(the)N +839(generation)X +1198(number)X +1463(is)X +1536(incremented,)X +1973(the)X +2091(current)X +2339(split)X +720 2632(point)N +908(is)X +985(set)X +1098(back)X +1274(to)X +1360(zero,)X +1543(and)X +1683(the)X +1805(maximum)X +2152(split)X +2312(point)X +720 2720(is)N +815(set)X +946(to)X +1050(the)X +1190(number)X +1477(of)X +1586(the)X +1725(last)X +1877(bucket)X +2132(in)X +2235(the)X +2374(\256le)X +720 2808(\(which)N +971(is)X +1052(equal)X +1253(to)X +1342(twice)X +1543(the)X +1668(old)X +1797(maximum)X +2148(split)X +2312(point)X +720 2896(plus)N +873(1\).)X +892 3010(To)N +1031(facilitate)X +1361(locating)X +1668(keys,)X +1884(we)X +2027(maintain)X +2356(two)X +720 3098(masks.)N +989(The)X +1143(low)X +1291(mask)X +1488(is)X +1569(equal)X +1771(to)X +1861(the)X +1987(maximum)X +2339(split)X +720 3186(bucket)N +967(and)X +1116(the)X +1247(high)X +1422(mask)X +1624(is)X +1710(equal)X +1917(to)X +2011(the)X +2141(next)X +2311(max-)X +720 3274(imum)N +931(split)X +1093(bucket.)X +1372(To)X +1486(locate)X +1703(a)X +1764(speci\256c)X +2033(key,)X +2193(we)X +2311(com-)X +720 3362(pute)N +881(a)X +940(32-bit)X +1154(hash)X +1324(value)X +1520(using)X +1715(a)X +1773(bit-randomizing)X +2311(algo-)X +720 3450(rithm)N +932(such)X +1118(as)X +1224(the)X +1361(one)X +1516(described)X +1862(in)X +1962([LAR88].)X +2334(This)X +720 3538(hash)N +893(value)X +1093(is)X +1172(then)X +1336(masked)X +1607(with)X +1775(the)X +1898(high)X +2065(mask.)X +2299(If)X +2378(the)X +720 3626(resulting)N +1026(number)X +1297(is)X +1376(greater)X +1626(than)X +1790(the)X +1913(maximum)X +2262(bucket)X +720 3714(in)N +823(the)X +962(table)X +1159(\(current)X +1455(split)X +1633(bucket)X +1888(+)X +1974(maximum)X +2339(split)X +720 3802(point\),)N +962(the)X +1091(hash)X +1269(value)X +1474(is)X +1558(masked)X +1834(with)X +2007(the)X +2136(low)X +2287(mask.)X +720 3890(In)N +825(either)X +1046(case,)X +1242(the)X +1377(result)X +1592(of)X +1696(the)X +1831(mask)X +2037(is)X +2127(the)X +2262(bucket)X +720 3978(number)N +989(for)X +1107(the)X +1229(given)X +1431(key.)X +1611(The)X +1759(algorithm)X +2093(below)X +2312(illus-)X +720 4066(trates)N +914(this)X +1049(process.)X +0 f +8 s +720 4365(h)N +796(=)X +872 -0.4038(calchash\(key\);)AX +720 4453(bucket)N +986(=)X +1062(h)X +1138(&)X +1214 -0.4167(high_mask;)AX +720 4541(if)N +834(\()X +910(bucket)X +1176(>)X +1252 -0.4167(max_bucket)AX +1670(\))X +1008 4629(bucket)N +1274(=)X +1350(h)X +1426(&)X +1502 -0.4219(low_mask;)AX +720 4717 -0.4018(return\(bucket\);)AN +1 f +10 s +892 5042(In)N +1013(order)X +1237(to)X +1353(decide)X +1617(when)X +1845(to)X +1961(split)X +2152(a)X +2242(bucket,)X +2 f +720 5130(dynahash)N +1 f +1050(uses)X +2 f +1210(controlled)X +1561(splitting)X +1 f +1822(.)X +1884(A)X +1964(hash)X +2133(table)X +2311(has)X +2440(a)X +720 5218(\256ll)N +837(factor)X +1054(which)X +1279(is)X +1361(expressed)X +1707(in)X +1798(terms)X +2004(of)X +2099(the)X +2225(average)X +720 5306(number)N +990(of)X +1082(keys)X +1253(in)X +1339(each)X +1511(bucket.)X +1789(Each)X +1974(time)X +2140(the)X +2262(table's)X +720 5394(total)N +885(number)X +1153(of)X +1243(keys)X +1413(divided)X +1676(by)X +1778(its)X +1875(number)X +2142(of)X +2231(buckets)X +720 5482(exceeds)N +995(this)X +1130(\256ll)X +1238(factor,)X +1466(a)X +1522(bucket)X +1756(is)X +1829(split.)X +2878 538(Since)N +3079(the)X +2 f +3200(hsearch)X +1 f +3477(create)X +3693(interface)X +3998(\()X +2 f +4025(hcreate)X +1 f +4266(\))X +4315(calls)X +2706 626(for)N +2842(an)X +2960(estimate)X +3269(of)X +3378(the)X +3518(\256nal)X +3702(size)X +3869(of)X +3978(the)X +4118(hash)X +4306(table)X +2706 714(\()N +2 f +2733(nelem)X +1 f +2925(\),)X +2 f +3007(dynahash)X +1 f +3349(uses)X +3522(this)X +3672(information)X +4085(to)X +4182(initialize)X +2706 802(the)N +2848(table.)X +3088(The)X +3257(initial)X +3486(number)X +3774(of)X +3884(buckets)X +4172(is)X +4268(set)X +4400(to)X +2 f +2706 890(nelem)N +1 f +2926(rounded)X +3217(to)X +3306(the)X +3431(next)X +3596(higher)X +3828(power)X +4056(of)X +4150(two.)X +4337(The)X +2706 978(current)N +2958(split)X +3118(point)X +3305(is)X +3381(set)X +3493(to)X +3578(0)X +3641(and)X +3780(the)X +3901(maximum)X +4248(bucket)X +2706 1066(and)N +2842(maximum)X +3186(split)X +3343(point)X +3527(are)X +3646(set)X +3755(to)X +3837(this)X +3972(rounded)X +4255(value.)X +3 f +3148 1220(The)N +3301(New)X +3473(Implementation)X +1 f +2878 1352(Our)N +3042(implementation)X +3583(is)X +3675(also)X +3842(based)X +4063(on)X +4181(Larson's)X +2706 1440(linear)N +2939(hashing)X +3238([LAR88])X +3582(algorithm)X +3943(as)X +4060(well)X +4248(as)X +4364(the)X +2 f +2706 1528(dynahash)N +1 f +3047(implementation.)X +3623(The)X +2 f +3782(dbm)X +1 f +3954(family)X +4197(of)X +4297(algo-)X +2706 1616(rithms)N +2942(decide)X +3184(dynamically)X +3612(which)X +3840(bucket)X +4085(to)X +4178(split)X +4346(and)X +2706 1704(when)N +2914(to)X +3010(split)X +3180(it)X +3257(\(when)X +3491(it)X +3568(over\257ows\))X +3944(while)X +2 f +4155(dynahash)X +1 f +2706 1792(splits)N +2933(in)X +3054(a)X +3149(prede\256ned)X +3547(order)X +3776(\(linearly\))X +4134(and)X +4309(at)X +4426(a)X +2706 1880(prede\256ned)N +3116(time)X +3328(\(when)X +3599(the)X +3767(table)X +3993(\256ll)X +4151(factor)X +4409(is)X +2706 1968(exceeded\).)N +3121(We)X +3280(use)X +3434(a)X +3517(hybrid)X +3773(of)X +3887(these)X +4099(techniques.)X +2706 2056(Splits)N +2913(occur)X +3118(in)X +3206(the)X +3330(prede\256ned)X +3695(order)X +3891(of)X +3984(linear)X +4193(hashing,)X +2706 2144(but)N +2845(the)X +2980(time)X +3159(at)X +3253(which)X +3485(pages)X +3704(are)X +3839(split)X +4012(is)X +4101(determined)X +2706 2232(both)N +2869(by)X +2970(page)X +3143(over\257ows)X +3480(\()X +2 f +3507(uncontrolled)X +3937(splitting)X +1 f +4198(\))X +4246(and)X +4382(by)X +2706 2320(exceeding)N +3052(the)X +3170(\256ll)X +3278(factor)X +3486(\()X +2 f +3513(controlled)X +3862(splitting)X +1 f +4123(\))X +2878 2434(A)N +2962(hash)X +3135(table)X +3317(is)X +3395(parameterized)X +3876(by)X +3981(both)X +4148(its)X +4248(bucket)X +2706 2522(size)N +2904(\()X +2 f +2931(bsize)X +1 f +(\))S +3191(and)X +3380(\256ll)X +3541(factor)X +3801(\()X +2 f +3828(ffactor)X +1 f +4041(\).)X +4180(Whereas)X +2 f +2706 2610(dynahash's)N +1 f +3095(buckets)X +3364(can)X +3500(be)X +3599(represented)X +3993(as)X +4083(a)X +4142(linked)X +4365(list)X +2706 2698(of)N +2798(elements)X +3108(in)X +3195(memory,)X +3507(our)X +3639(package)X +3928(needs)X +4136(to)X +4222(support)X +2706 2786(disk)N +2874(access,)X +3135(and)X +3286(must)X +3476(represent)X +3806(buckets)X +4086(in)X +4183(terms)X +4395(of)X +2706 2874(pages.)N +2955(The)X +2 f +3106(bsize)X +1 f +3291(is)X +3369(the)X +3492(size)X +3642(\(in)X +3756(bytes\))X +3977(of)X +4069(these)X +4259(pages.)X +2706 2962(As)N +2833(in)X +2933(linear)X +3154(hashing,)X +3461(the)X +3597(number)X +3879(of)X +3983(buckets)X +4265(in)X +4364(the)X +2706 3050(table)N +2906(is)X +3003(equal)X +3221(to)X +3327(the)X +3469(number)X +3758(of)X +3869(keys)X +4060(in)X +4165(the)X +4306(table)X +2706 3138(divided)N +2988(by)X +2 f +3110(ffactor)X +1 f +3323(.)X +2 f +8 s +3113(6)Y +1 f +10 s +3417 3138(The)N +3584(controlled)X +3950(splitting)X +4252(occurs)X +2706 3226(each)N +2878(time)X +3044(the)X +3166(number)X +3435(of)X +3526(keys)X +3697(in)X +3783(the)X +3905(table)X +4085(exceeds)X +4364(the)X +2706 3314(\256ll)N +2814(factor)X +3022(multiplied)X +3370(by)X +3470(the)X +3588(number)X +3853(of)X +3940(buckets.)X +2878 3428(Inserting)N +3187(keys)X +3358(and)X +3498(splitting)X +3783(buckets)X +4051(is)X +4127(performed)X +2706 3516(precisely)N +3018(as)X +3107(described)X +3437(previously)X +3796(for)X +2 f +3911(dynahash)X +1 f +4218(.)X +4279(How-)X +2706 3604(ever,)N +2897(since)X +3094(buckets)X +3371(are)X +3502(now)X +3671(comprised)X +4036(of)X +4134(pages,)X +4368(we)X +2706 3692(must)N +2883(be)X +2981(prepared)X +3284(to)X +3367(handle)X +3602(cases)X +3793(where)X +4011(the)X +4130(size)X +4276(of)X +4364(the)X +2706 3780(keys)N +2873(and)X +3009(data)X +3163(in)X +3245(a)X +3301(bucket)X +3535(exceed)X +3779(the)X +3897(bucket)X +4131(size.)X +3 f +3318 3934(Over\257ow)N +3654(Pages)X +1 f +2878 4066(There)N +3095(are)X +3223(two)X +3372(cases)X +3571(where)X +3797(a)X +3862(key)X +4007(may)X +4174(not)X +4305(\256t)X +4400(in)X +2706 4154(its)N +2802(designated)X +3166(bucket.)X +3441(In)X +3529(the)X +3647(\256rst)X +3791(case,)X +3970(the)X +4088(total)X +4250(size)X +4395(of)X +2706 4242(the)N +2833(key)X +2978(and)X +3123(data)X +3286(may)X +3453(exceed)X +3706(the)X +3833(bucket)X +4076(size.)X +4269(In)X +4364(the)X +2706 4330(second,)N +3008(addition)X +3328(of)X +3453(a)X +3547(new)X +3739(key)X +3913(could)X +4149(cause)X +4386(an)X +2706 4418(over\257ow,)N +3068(but)X +3227(the)X +3382(bucket)X +3652(in)X +3770(question)X +4097(is)X +4206(not)X +4364(yet)X +2706 4506(scheduled)N +3049(to)X +3133(be)X +3230(split.)X +3428(In)X +3516(existing)X +3790(implementations,)X +4364(the)X +2706 4594(second)N +2953(case)X +3115(never)X +3317(arises)X +3523(\(since)X +3738(buckets)X +4006(are)X +4128(split)X +4288(when)X +2706 4682(they)N +2871(over\257ow\))X +3210(and)X +3352(the)X +3476(\256rst)X +3626(case)X +3791(is)X +3870(not)X +3998(handled)X +4278(at)X +4362(all.)X +2706 4770(Although)N +3036(large)X +3225(key/data)X +3525(pair)X +3678(handling)X +3986(is)X +4066(dif\256cult)X +4346(and)X +2706 4858(expensive,)N +3083(it)X +3163(is)X +3252(essential.)X +3604(In)X +3706(a)X +3777(linear)X +3995(hashed)X +4253(imple-)X +2706 4946(mentation,)N +3087(over\257ow)X +3413(pages)X +3636(are)X +3775(required)X +4083(for)X +4217(buckets)X +2706 5034(which)N +2935(over\257ow)X +3253(before)X +3492(they)X +3662(are)X +3793(split,)X +3982(so)X +4085(we)X +4211(can)X +4355(use)X +2706 5122(the)N +2833(same)X +3027(mechanism)X +3421(for)X +3544(large)X +3734(key/data)X +4035(pairs)X +4220(that)X +4368(we)X +2706 5210(use)N +2837(for)X +2955(over\257ow)X +3264(pages.)X +3511(Logically,)X +3862(we)X +3980(chain)X +4177(over\257ow)X +16 s +2706 5353 MXY +864 0 Dl +2 f +8 s +2746 5408(6)N +1 f +9 s +2801 5433(This)N +2952(is)X +3023(not)X +3138(strictly)X +3361(true.)X +3532(The)X +3667(\256le)X +3782(does)X +3937(not)X +4052(contract)X +4306(when)X +2706 5513(keys)N +2861(are)X +2972(deleted,)X +3221(so)X +3308(the)X +3419(number)X +3662(of)X +3744(buckets)X +3986(is)X +4056(actually)X +4306(equal)X +2706 5593(to)N +2782(the)X +2890(maximum)X +3202(number)X +3441(of)X +3520(keys)X +3671(ever)X +3814(present)X +4041(in)X +4116(the)X +4223(table)X +4382(di-)X +2706 5673(vided)N +2884(by)X +2974(the)X +3080(\256ll)X +3178(factor.)X +3 f +10 s +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +4424(5)X + +6 p +%%Page: 6 6 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +432 258(A)N +510(New)X +682(Hashing)X +985(Package)X +1290(for)X +1413(UNIX)X +3663(Seltzer)X +3920(&)X +4007(Yigit)X +1 f +432 538(pages)N +639(to)X +725(the)X +847(buckets)X +1116(\(also)X +1296(called)X +1512(primary)X +1789(pages\).)X +2062(In)X +2152(a)X +432 626(memory)N +730(based)X +943(representation,)X +1448(over\257ow)X +1763(pages)X +1976(do)X +2086(not)X +432 714(pose)N +628(any)X +792(special)X +1063(problems)X +1409(because)X +1712(we)X +1854(can)X +2014(chain)X +432 802(over\257ow)N +776(pages)X +1017(to)X +1137(primary)X +1449(pages)X +1690(using)X +1921(memory)X +432 890(pointers.)N +776(However,)X +1137(mapping)X +1463(these)X +1674(over\257ow)X +2005(pages)X +432 978(into)N +584(a)X +648(disk)X +809(\256le)X +939(is)X +1019(more)X +1211(of)X +1305(a)X +1368(challenge,)X +1723(since)X +1915(we)X +2036(need)X +432 1066(to)N +547(be)X +675(able)X +861(to)X +975(address)X +1268(both)X +1462(bucket)X +1728(pages,)X +1983(whose)X +432 1154(numbers)N +729(are)X +849(growing)X +1137(linearly,)X +1422(and)X +1558(some)X +1747(indeterminate)X +432 1242(number)N +715(of)X +820(over\257ow)X +1143(pages)X +1364(without)X +1646(reorganizing)X +2090(the)X +432 1330(\256le.)N +604 1444(One)N +789(simple)X +1053(solution)X +1361(would)X +1612(be)X +1739(to)X +1852(allocate)X +2152(a)X +432 1532(separate)N +737(\256le)X +880(for)X +1015(over\257ow)X +1341(pages.)X +1604(The)X +1769(disadvantage)X +432 1620(with)N +605(such)X +783(a)X +850(technique)X +1193(is)X +1276(that)X +1426(it)X +1500(requires)X +1789(an)X +1895(extra)X +2086(\256le)X +432 1708(descriptor,)N +794(an)X +891(extra)X +1073(system)X +1316(call)X +1453(on)X +1554(open)X +1731(and)X +1867(close,)X +2072(and)X +432 1796(logically)N +739(associating)X +1122(two)X +1269(independent)X +1687(\256les.)X +1886(For)X +2023(these)X +432 1884(reasons,)N +728(we)X +857(wanted)X +1123(to)X +1219(map)X +1391(both)X +1567(primary)X +1855(pages)X +2072(and)X +432 1972(over\257ow)N +737(pages)X +940(into)X +1084(the)X +1202(same)X +1387(\256le)X +1509(space.)X +604 2086(The)N +799(buddy-in-waiting)X +1425(algorithm)X +1806(provides)X +2152(a)X +432 2174(mechanism)N +851(to)X +966(support)X +1259(multiple)X +1578(pages)X +1814(per)X +1970(logical)X +432 2262(bucket)N +685(while)X +902(retaining)X +1226(the)X +1362(simple)X +1613(split)X +1788(sequence)X +2121(of)X +432 2350(linear)N +681(hashing.)X +1015(Over\257ow)X +1383(pages)X +1631(are)X +1795(preallocated)X +432 2438(between)N +781(generations)X +1232(of)X +1379(primary)X +1713(pages.)X +1996(These)X +432 2526(over\257ow)N +759(pages)X +984(are)X +1125(used)X +1314(by)X +1436(any)X +1594(bucket)X +1850(containing)X +432 2614(more)N +646(keys)X +842(than)X +1029(\256t)X +1144(on)X +1273(the)X +1420(primary)X +1723(page)X +1924(and)X +2089(are)X +432 2702(reclaimed,)N +808(if)X +896(possible,)X +1217(when)X +1430(the)X +1567(bucket)X +1819(later)X +2000(splits.)X +432 2790(Figure)N +687(3)X +773(depicts)X +1045(the)X +1188(layout)X +1433(of)X +1545(primary)X +1844(pages)X +2072(and)X +432 2878(over\257ow)N +752(pages)X +970(within)X +1209(the)X +1342(same)X +1542(\256le.)X +1699(Over\257ow)X +2036(page)X +432 2966(use)N +586(information)X +1011(is)X +1111(recorded)X +1440(in)X +1548(bitmaps)X +1847(which)X +2089(are)X +432 3054(themselves)N +819(stored)X +1046(on)X +1157(over\257ow)X +1472(pages.)X +1725(The)X +1880(addresses)X +432 3142(of)N +520(the)X +639(bitmap)X +882(pages)X +1086(and)X +1223(the)X +1342(number)X +1608(of)X +1695(pages)X +1898(allocated)X +432 3230(at)N +515(each)X +688(split)X +850(point)X +1039(are)X +1163(stored)X +1384(in)X +1470(the)X +1592(\256le)X +1718(header.)X +1997(Using)X +432 3318(this)N +577(information,)X +1005(both)X +1177(over\257ow)X +1492(addresses)X +1829(and)X +1974(bucket)X +432 3406(addresses)N +764(can)X +900(be)X +999(mapped)X +1276(to)X +1361(disk)X +1517(addresses)X +1848(by)X +1951(the)X +2072(fol-)X +432 3494(lowing)N +674(calculation:)X +0 f +8 s +432 3793(int)N +736(bucket;)X +1192(/*)X +1306(bucket)X +1572(address)X +1876(*/)X +432 3881(u_short)N +736(oaddr;)X +1192(/*)X +1306(OVERFLOW)X +1648(address)X +1952(*/)X +432 3969(int)N +736 -0.4125(nhdr_pages;)AX +1192(/*)X +1306(npages)X +1572(in)X +1686 -112.4062(\256le)AX +1838(header)X +2104(*/)X +432 4057(int)N +736 -0.4125(spares[32];)AX +1192(/*)X +1306(npages)X +1572(at)X +1686(each)X +1876(split)X +2104(*/)X +432 4145(int)N +736(log2\(\);)X +1198(/*)X +1312(ceil\(log)X +1654(base)X +1844(2\))X +1958(*/)X +432 4321(#DEFINE)N +736 -0.3929(BUCKET_TO_PAGE\(bucket\))AX +1610(\\)X +584 4409(bucket)N +850(+)X +926 -0.4167(nhdr_pages)AX +1344(+)X +1420(\\)X +584 4497 -0.3894(\(bucket?spares[logs2\(bucket)AN +1648(+)X +1724(1\)-1]:0\))X +432 4673(#DEFINE)N +736 -0.3947(OADDR_TO_PAGE\(oaddr\))AX +1534(\\)X +584 4761 -0.3984(BUCKET_TO_PAGE\(\(1)AN +1268(<<)X +1382 -0.4091(\(oaddr>>11\)\))AX +1876(-)X +1952(1\))X +2066(+)X +2142(\\)X +584 4849(oaddr)N +812(&)X +888(0x7ff;)X +1 f +10 s +604 5262(An)N +728(over\257ow)X +1039(page)X +1217(is)X +1295(addressed)X +1637(by)X +1742(its)X +1842(split)X +2004(point,)X +432 5350(identifying)N +858(the)X +1031(generations)X +1476(between)X +1819(which)X +2090(the)X +432 5438(over\257ow)N +740(page)X +915(is)X +991(allocated,)X +1324(and)X +1463(its)X +1561(page)X +1736(number,)X +2023(iden-)X +432 5526(tifying)N +665(the)X +783(particular)X +1111(page)X +1283(within)X +1507(the)X +1625(split)X +1782(point.)X +1986(In)X +2073(this)X +432 5614(implementation,)N +983(offsets)X +1225(within)X +1457(pages)X +1668(are)X +1795(16)X +1903(bits)X +2046(long)X +432 5702(\(limiting)N +732(the)X +851(maximum)X +1196(page)X +1368(size)X +1513(to)X +1595(32K\),)X +1800(so)X +1891(we)X +2005(select)X +2418 538(an)N +2535(over\257ow)X +2860(page)X +3052(addressing)X +3435(algorithm)X +3786(that)X +3946(can)X +4098(be)X +2418 626(expressed)N +2760(in)X +2847(16)X +2952(bits)X +3091(and)X +3231(which)X +3451(allows)X +3684(quick)X +3886(retrieval.)X +2418 714(The)N +2568(top)X +2695(\256ve)X +2840(bits)X +2980(indicate)X +3258(the)X +3380(split)X +3541(point)X +3729(and)X +3869(the)X +3991(lower)X +2418 802(eleven)N +2650(indicate)X +2926(the)X +3046(page)X +3220(number)X +3487(within)X +3713(the)X +3832(split)X +3990(point.)X +2418 890(Since)N +2633(\256ve)X +2789(bits)X +2940(are)X +3075(reserved)X +3384(for)X +3514(the)X +3648(split)X +3821(point,)X +4041(\256les)X +2418 978(may)N +2578(split)X +2737(32)X +2839(times)X +3034(yielding)X +3318(a)X +3376(maximum)X +3721(\256le)X +3844(size)X +3990(of)X +4078(2)X +7 s +946(32)Y +10 s +2418 1066(buckets)N +2698(and)X +2849(32)X +2 f +(*)S +1 f +2982(2)X +7 s +1034(11)Y +10 s +3113 1066(over\257ow)N +3433(pages.)X +3691(The)X +3850(maximum)X +2418 1154(page)N +2597(size)X +2749(is)X +2829(2)X +7 s +1122(15)Y +10 s +1154(,)Y +2971(yielding)X +3259(a)X +3321(maximum)X +3671(\256le)X +3799(size)X +3950(greater)X +2418 1242(than)N +2601(131,000)X +2906(GB)X +3061(\(on)X +3212(\256le)X +3358(systems)X +3655(supporting)X +4041(\256les)X +2418 1330(larger)N +2626(than)X +2784(4GB\).)X +10 f +2418 1418 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +1 Dt +4014 2275 MXY +0 133 Dl +3881 2275 MXY +0 133 Dl +3748 2275 MXY +0 133 Dl +3083 2275 MXY +0 133 Dl +5 s +1 f +3523 2475(2/3)N +3390(2/2)X +3257(2/1)X +2859(1/2)X +2726(1/1)X +5 Dt +3814 1743 MXY +0 133 Dl +3282 1743 MXY +0 133 Dl +3017 1743 MXY +0 133 Dl +2884 1743 MXY +0 133 Dl +1 Dt +3681 1743 MXY +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3548 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3415 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3282 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3150 MX +0 133 Dl +132 0 Dl +0 -133 Dl +-132 0 Dl +3017 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +2884 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3 f +8 s +3017 2601(Over\257ow)N +3285(Addresses)X +3515 2833(Over\257ow)N +3783(Pages)X +2850(Buckets)X +1 Di +3349 2740 MXY + 3349 2740 lineto + 3482 2740 lineto + 3482 2873 lineto + 3349 2873 lineto + 3349 2740 lineto +closepath 3 3349 2740 3482 2873 Dp +2684 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +5 Dt +4146 2275 MXY +0 133 Dl +3216 2275 MXY +0 133 Dl +2684 2275 MXY +0 133 Dl +2551 2275 MXY +0 133 Dl +1 f +3798 1963(3)N +3266 1980(2)N +3001(1)X +2868(0)X +1 Dt +2751 1743 MXY +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3548 2275 MXY +-15 -22 Dl +2 16 Dl +-13 11 Dl +26 -5 Dl +-282 -117 Dl +3432 2275 MXY +-10 -25 Dl +-2 16 Dl +-15 8 Dl +27 1 Dl +-166 -117 Dl +3282 2275 MXY +12 -25 Dl +-14 10 Dl +-15 -6 Dl +17 21 Dl +-16 -117 Dl +2884 2275 MXY +26 7 Dl +-12 -12 Dl +3 -16 Dl +-17 21 Dl +382 -117 Dl +2751 2275 MXY +25 9 Dl +-11 -12 Dl +5 -17 Dl +-19 20 Dl +515 -117 Dl +3 f +3070 2152(Over\257ow)N +3338(Pages)X +3482 2275 MXY + 3482 2275 lineto + 3615 2275 lineto + 3615 2408 lineto + 3482 2408 lineto + 3482 2275 lineto +closepath 3 3482 2275 3615 2408 Dp +3349 MX + 3349 2275 lineto + 3482 2275 lineto + 3482 2408 lineto + 3349 2408 lineto + 3349 2275 lineto +closepath 3 3349 2275 3482 2408 Dp +3216 MX + 3216 2275 lineto + 3349 2275 lineto + 3349 2408 lineto + 3216 2408 lineto + 3216 2275 lineto +closepath 3 3216 2275 3349 2408 Dp +2817 MX + 2817 2275 lineto + 2950 2275 lineto + 2950 2408 lineto + 2817 2408 lineto + 2817 2275 lineto +closepath 3 2817 2275 2950 2408 Dp +2684 MX + 2684 2275 lineto + 2817 2275 lineto + 2817 2408 lineto + 2684 2408 lineto + 2684 2275 lineto +closepath 3 2684 2275 2817 2408 Dp +3615 MX +0 133 Dl +531 0 Dl +0 -133 Dl +-531 0 Dl +2950 MX +0 133 Dl +266 0 Dl +0 -133 Dl +-266 0 Dl +2551 MX +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3798 1726 MXY +-21 -18 Dl +6 16 Dl +-10 13 Dl +25 -11 Dl +-599 -99 Dl +3266 1726 MXY +-1 -27 Dl +-7 15 Dl +-17 1 Dl +25 11 Dl +-67 -99 Dl +3033 1726 MXY +27 1 Dl +-14 -8 Dl +-1 -17 Dl +-12 24 Dl +166 -99 Dl +2900 1726 MXY +27 7 Dl +-13 -11 Dl +3 -17 Dl +-17 21 Dl +299 -99 Dl +3058 1621(Split)N +3203(Points)X +2418 2275 MXY +0 133 Dl +133 0 Dl +0 -133 Dl +-133 0 Dl +3 Dt +-1 Ds +3137(Figure)Y +2619(3:)X +1 f +2691(Split)X +2832(points)X +3008(occur)X +3168(between)X +3399(generations)X +3712(and)X +3823(are)X +3919(numbered)X +2418 3225(from)N +2560(0.)X +2642(In)X +2713(this)X +2824(\256gure)X +2991(there)X +3136(are)X +3231(two)X +3345(over\257ow)X +3590(pages)X +3753(allocated)X +4000(at)X +4063(split)X +2418 3313(point)N +2566(1)X +2614(and)X +2722(three)X +2865(allocated)X +3111(at)X +3173(split)X +3300(point)X +3448(2.)X +10 s +10 f +2418 3489 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +2949 3731(Buffer)N +3192(Management)X +1 f +2590 3863(The)N +2744(hash)X +2920(table)X +3105(is)X +3187(stored)X +3412(in)X +3502(memory)X +3797(as)X +3892(a)X +3956(logical)X +2418 3951(array)N +2633(of)X +2749(bucket)X +3012(pointers.)X +3359(Physically,)X +3761(the)X +3907(array)X +4121(is)X +2418 4039(arranged)N +2728(in)X +2818(segments)X +3144(of)X +3239(256)X +3387(pointers.)X +3713(Initially,)X +4013(there)X +2418 4127(is)N +2530(space)X +2767(to)X +2887(allocate)X +3195(256)X +3373(segments.)X +3769(Reallocation)X +2418 4215(occurs)N +2651(when)X +2847(the)X +2967(number)X +3234(of)X +3323(buckets)X +3590(exceeds)X +3867(32K)X +4027(\(256)X +2418 4303(*)N +2508(256\).)X +2745(Primary)X +3053(pages)X +3286(may)X +3473(be)X +3598(accessed)X +3929(directly)X +2418 4391(through)N +2711(the)X +2853(array)X +3062(by)X +3185(bucket)X +3442(number)X +3730(and)X +3889(over\257ow)X +2418 4479(pages)N +2628(are)X +2754 0.4028(referenced)AX +3122(logically)X +3429(by)X +3536(their)X +3710(over\257ow)X +4022(page)X +2418 4567(address.)N +2726(For)X +2864(small)X +3063(hash)X +3236(tables,)X +3469(it)X +3539(is)X +3618(desirable)X +3934(to)X +4022(keep)X +2418 4655(all)N +2525(pages)X +2735(in)X +2823(main)X +3009(memory)X +3302(while)X +3506(on)X +3612(larger)X +3826(tables,)X +4059(this)X +2418 4743(is)N +2523(probably)X +2860(impossible.)X +3298(To)X +3438(satisfy)X +3698(both)X +3891(of)X +4009(these)X +2418 4831(requirements,)N +2900(the)X +3041(package)X +3348(includes)X +3658(buffer)X +3897(manage-)X +2418 4919(ment)N +2598(with)X +2760(LRU)X +2940(\(least)X +3134(recently)X +3413(used\))X +3607(replacement.)X +2590 5033(By)N +2730(default,)X +3020(the)X +3165(package)X +3475(allocates)X +3802(up)X +3928(to)X +4036(64K)X +2418 5121(bytes)N +2616(of)X +2712(buffered)X +3014(pages.)X +3246(All)X +3377(pages)X +3589(in)X +3680(the)X +3807(buffer)X +4032(pool)X +2418 5209(are)N +2542(linked)X +2766(in)X +2852(LRU)X +3036(order)X +3230(to)X +3316(facilitate)X +3621(fast)X +3761(replacement.)X +2418 5297(Whereas)N +2724(ef\256cient)X +3011(access)X +3241(to)X +3327(primary)X +3605(pages)X +3812(is)X +3889(provided)X +2418 5385(by)N +2521(the)X +2642(bucket)X +2879(array,)X +3087(ef\256cient)X +3372(access)X +3600(to)X +3684(over\257ow)X +3991(pages)X +2418 5473(is)N +2501(provided)X +2816(by)X +2926(linking)X +3182(over\257ow)X +3497(page)X +3679(buffers)X +3936(to)X +4027(their)X +2418 5561(predecessor)N +2827(page)X +3008(\(either)X +3247(the)X +3374(primary)X +3657(page)X +3838(or)X +3933(another)X +2418 5649(over\257ow)N +2742(page\).)X +3000(This)X +3181(means)X +3425(that)X +3584(an)X +3699(over\257ow)X +4022(page)X +3 f +432 5960(6)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +7 p +%%Page: 7 7 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +720 258(Seltzer)N +977(&)X +1064(Yigit)X +3278(A)X +3356(New)X +3528(Hashing)X +3831(Package)X +4136(for)X +4259(UNIX)X +1 f +720 538(cannot)N +955(be)X +1052(present)X +1305(in)X +1388(the)X +1507(buffer)X +1724(pool)X +1886(if)X +1955(its)X +2050(primary)X +2324(page)X +720 626(is)N +804(not)X +937(present.)X +1240(This)X +1413(does)X +1591(not)X +1724(impact)X +1972(performance)X +2409(or)X +720 714(functionality,)N +1209(because)X +1524(an)X +1660(over\257ow)X +2005(page)X +2217(will)X +2400(be)X +720 802(accessed)N +1048(only)X +1236(after)X +1430(its)X +1550(predecessor)X +1975(page)X +2172(has)X +2324(been)X +720 890(accessed.)N +1068(Figure)X +1303(4)X +1369(depicts)X +1622(the)X +1746(data)X +1905(structures)X +2242(used)X +2414(to)X +720 978(manage)N +990(the)X +1108(buffer)X +1325(pool.)X +892 1092(The)N +1040(in-memory)X +1419(bucket)X +1656(array)X +1845(contains)X +2134(pointers)X +2414(to)X +720 1180(buffer)N +975(header)X +1248(structures)X +1617(which)X +1870(represent)X +2222(primary)X +720 1268(pages.)N +968(Buffer)X +1203(headers)X +1474(contain)X +1735(modi\256ed)X +2043(bits,)X +2202(the)X +2324(page)X +720 1356(address)N +995(of)X +1096(the)X +1228(buffer,)X +1479(a)X +1548(pointer)X +1808(to)X +1903(the)X +2034(actual)X +2259(buffer,)X +720 1444(and)N +875(a)X +950(pointer)X +1216(to)X +1317(the)X +1454(buffer)X +1690(header)X +1944(for)X +2077(an)X +2191(over\257ow)X +720 1532(page)N +901(if)X +979(it)X +1052(exists,)X +1283(in)X +1374(addition)X +1665(to)X +1756(the)X +1883(LRU)X +2072(links.)X +2296(If)X +2378(the)X +720 1620(buffer)N +950(corresponding)X +1442(to)X +1537(a)X +1606(particular)X +1947(bucket)X +2194(is)X +2280(not)X +2414(in)X +720 1708(memory,)N +1048(its)X +1164(pointer)X +1432(is)X +1526(NULL.)X +1801(In)X +1909(effect,)X +2154(pages)X +2377(are)X +720 1796(linked)N +950(in)X +1042(three)X +1233(ways.)X +1468(Using)X +1689(the)X +1817(buffer)X +2043(headers,)X +2338(they)X +720 1884(are)N +851(linked)X +1083(physically)X +1444(through)X +1725(the)X +1854(LRU)X +2045(links)X +2231(and)X +2378(the)X +720 1972(over\257ow)N +1036(links.)X +1241(Using)X +1462(the)X +1590(pages)X +1803(themselves,)X +2209(they)X +2377(are)X +720 2060(linked)N +943(logically)X +1246(through)X +1518(the)X +1639(over\257ow)X +1946(addresses)X +2276(on)X +2378(the)X +720 2148(page.)N +948(Since)X +1162(over\257ow)X +1482(pages)X +1700(are)X +1834(accessed)X +2151(only)X +2328(after)X +720 2236(their)N +904(predecessor)X +1321(pages,)X +1560(they)X +1734(are)X +1869(removed)X +2186(from)X +2378(the)X +720 2324(buffer)N +937(pool)X +1099(when)X +1293(their)X +1460(primary)X +1734(is)X +1807(removed.)X +10 f +720 2412 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +1 Dt +2309 3177 MXY +24 15 Dl +-8 -15 Dl +8 -15 Dl +-24 15 Dl +52 0 Dl +789 3160 MXY +-35 0 Dl +0 -156 Dl +1607 0 Dl +0 173 Dl +789 3091 MXY +-24 -15 Dl +9 15 Dl +-9 15 Dl +24 -15 Dl +-69 0 Dl +2309 3125 MXY +104 0 Dl +0 -155 Dl +-1693 0 Dl +0 121 Dl +927 3160 MXY +24 15 Dl +-9 -15 Dl +9 -15 Dl +-24 15 Dl +553 0 Dl +1618 3177 MXY +8 27 Dl +4 -17 Dl +16 -6 Dl +-28 -4 Dl +138 121 Dl +1895 3315 MXY +28 3 Dl +-15 -9 Dl +1 -18 Dl +-14 24 Dl +276 -138 Dl +3108 MY +-28 -3 Dl +15 10 Dl +-1 17 Dl +14 -24 Dl +-276 138 Dl +1756 3229 MXY +-8 -27 Dl +-3 17 Dl +-16 6 Dl +27 4 Dl +-138 -121 Dl +1480 MX +-24 -15 Dl +9 15 Dl +-9 15 Dl +24 -15 Dl +-553 0 Dl +3 f +5 s +1083 3073(LRU)N +1178(chain)X +4 Ds +1402 3851 MXY + 1402 3851 lineto + 1471 3851 lineto + 1471 3920 lineto + 1402 3920 lineto + 1402 3851 lineto +closepath 19 1402 3851 1471 3920 Dp +1445 3747(Over\257ow)N +1613(Address)X +1549 3609 MXY +0 69 Dl +1756 MX +-23 -15 Dl +8 15 Dl +-8 15 Dl +23 -15 Dl +-207 0 Dl +-1 Ds +3 Dt +1756 3419 MXY +-6 -28 Dl +-4 17 Dl +-17 5 Dl +27 6 Dl +-138 -138 Dl +2240 3471 MXY +15 -24 Dl +-15 9 Dl +-15 -9 Dl +15 24 Dl +0 -138 Dl +1826 3609 MXY +15 -24 Dl +-15 9 Dl +-16 -9 Dl +16 24 Dl +0 -138 Dl +1549 MX +15 -24 Dl +-15 9 Dl +-15 -9 Dl +15 24 Dl +0 -138 Dl +858 3471 MXY +15 -24 Dl +-15 9 Dl +-15 -9 Dl +15 24 Dl +0 -138 Dl +2240 3056 MXY +15 -24 Dl +-15 9 Dl +-15 -9 Dl +15 24 Dl +0 -138 Dl +1549 3056 MXY +15 -24 Dl +-15 9 Dl +-15 -9 Dl +15 24 Dl +0 -138 Dl +858 3056 MXY +15 -24 Dl +-15 9 Dl +-15 -9 Dl +15 24 Dl +0 -138 Dl +1 Dt +2171 3471 MXY + 2171 3471 lineto + 2448 3471 lineto + 2448 3609 lineto + 2171 3609 lineto + 2171 3471 lineto +closepath 19 2171 3471 2448 3609 Dp +1756 3609 MXY + 1756 3609 lineto + 2033 3609 lineto + 2033 3747 lineto + 1756 3747 lineto + 1756 3609 lineto +closepath 3 1756 3609 2033 3747 Dp +1480 3471 MXY + 1480 3471 lineto + 1756 3471 lineto + 1756 3609 lineto + 1480 3609 lineto + 1480 3471 lineto +closepath 19 1480 3471 1756 3609 Dp +789 MX + 789 3471 lineto + 1065 3471 lineto + 1065 3609 lineto + 789 3609 lineto + 789 3471 lineto +closepath 19 789 3471 1065 3609 Dp +962 3903(Buffer)N +1083(Header)X +849 3851 MXY + 849 3851 lineto + 918 3851 lineto + 918 3920 lineto + 849 3920 lineto + 849 3851 lineto +closepath 14 849 3851 918 3920 Dp +1756 3194 MXY + 1756 3194 lineto + 1895 3194 lineto + 1895 3471 lineto + 1756 3471 lineto + 1756 3194 lineto +closepath 14 1756 3194 1895 3471 Dp +2171 3056 MXY + 2171 3056 lineto + 2309 3056 lineto + 2309 3333 lineto + 2171 3333 lineto + 2171 3056 lineto +closepath 14 2171 3056 2309 3333 Dp +1480 MX + 1480 3056 lineto + 1618 3056 lineto + 1618 3333 lineto + 1480 3333 lineto + 1480 3056 lineto +closepath 14 1480 3056 1618 3333 Dp +789 MX + 789 3056 lineto + 927 3056 lineto + 927 3333 lineto + 789 3333 lineto + 789 3056 lineto +closepath 14 789 3056 927 3333 Dp +2780 MY +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +927 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +1065 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +1203 MX +0 138 Dl +139 0 Dl +0 -138 Dl +-139 0 Dl +1342 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +1480 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +1618 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +1756 MX +0 138 Dl +139 0 Dl +0 -138 Dl +-139 0 Dl +1895 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +2033 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +2171 MX +0 138 Dl +138 0 Dl +0 -138 Dl +-138 0 Dl +2309 MX +0 138 Dl +139 0 Dl +0 -138 Dl +-139 0 Dl +13 s +1048 2720(In)N +1173(Memory)X +1580(Bucket)X +1918(Array)X +867 3584(B0)N +1558(B5)X +2223(B10)X +1788 3722(O1/1)N +5 s +1515 3903(Primay)N +1651(Buffer)X +4 Ds +1990 3851 MXY + 1990 3851 lineto + 2059 3851 lineto + 2059 3920 lineto + 1990 3920 lineto + 1990 3851 lineto +closepath 3 1990 3851 2059 3920 Dp +2102 3903(Over\257ow)N +2270(Buffer)X +3 Dt +-1 Ds +8 s +720 4184(Figure)N +922(4:)X +1 f +996(Three)X +1164(primary)X +1386(pages)X +1551(\(B0,)X +1683(B5,)X +1794(B10\))X +1942(are)X +2039(accessed)X +2281(directly)X +720 4272(from)N +862(the)X +958(bucket)X +1146(array.)X +1326(The)X +1443(one)X +1553(over\257ow)X +1798(page)X +1935(\(O1/1\))X +2122(is)X +2182(linked)X +2359(phy-)X +720 4360(sically)N +915(from)X +1067(its)X +1155(primary)X +1384(page's)X +1577(buffer)X +1759(header)X +1955(as)X +2035(well)X +2172(as)X +2252(logically)X +720 4448(from)N +860(its)X +937(predecessor)X +1253(page)X +1389(buffer)X +1560(\(B5\).)X +10 s +10 f +720 4624 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +1191 4954(Table)N +1406(Parameterization)X +1 f +892 5086(When)N +1107(a)X +1166(hash)X +1336(table)X +1515(is)X +1590(created,)X +1865(the)X +1985(bucket)X +2221(size,)X +2388(\256ll)X +720 5174(factor,)N +953(initial)X +1164(number)X +1434(of)X +1526(elements,)X +1856(number)X +2125(of)X +2216(bytes)X +2409(of)X +720 5262(main)N +919(memory)X +1225(used)X +1411(for)X +1543(caching,)X +1851(and)X +2005(a)X +2079(user-de\256ned)X +720 5350(hash)N +892(function)X +1184(may)X +1347(be)X +1448(speci\256ed.)X +1797(The)X +1946(bucket)X +2184(size)X +2333(\(and)X +720 5438(page)N +906(size)X +1064(for)X +1191(over\257ow)X +1509(pages\))X +1752(defaults)X +2039(to)X +2134(256)X +2287(bytes.)X +720 5526(For)N +858(tables)X +1072(with)X +1241(large)X +1429(data)X +1590(items,)X +1810(it)X +1881(may)X +2046(be)X +2149(preferable)X +720 5614(to)N +803(increase)X +1088(the)X +1207(page)X +1380(size,)X +1545(and,)X +1701(conversely,)X +2089(applications)X +720 5702(storing)N +1002(small)X +1235(items)X +1467(exclusively)X +1891(in)X +2012(memory)X +2338(may)X +2706 538(bene\256t)N +2966(from)X +3164(a)X +3242(smaller)X +3520(bucket)X +3776(size.)X +3983(A)X +4082(bucket)X +4337(size)X +2706 626(smaller)N +2962(than)X +3120(64)X +3220(bytes)X +3409(is)X +3482(not)X +3604(recommended.)X +2878 740(The)N +3031(\256ll)X +3147(factor)X +3363(indicates)X +3676(a)X +3740(desired)X +4000(density)X +4258(within)X +2706 828(the)N +2833(hash)X +3009(table.)X +3234(It)X +3312(is)X +3394(an)X +3499(approximation)X +3995(of)X +4091(the)X +4217(number)X +2706 916(of)N +2815(keys)X +3004(allowed)X +3300(to)X +3404(accumulate)X +3811(in)X +3914(any)X +4071(one)X +4228(bucket,)X +2706 1004(determining)N +3119(when)X +3319(the)X +3442(hash)X +3614(table)X +3795(grows.)X +4056(Its)X +4161(default)X +4409(is)X +2706 1092(eight.)N +2953(If)X +3054(the)X +3199(user)X +3380(knows)X +3636(the)X +3781(average)X +4079(size)X +4251(of)X +4364(the)X +2706 1180(key/data)N +3008(pairs)X +3194(being)X +3402(stored)X +3627(in)X +3718(the)X +3845(table,)X +4050(near)X +4218(optimal)X +2706 1268(bucket)N +2943(sizes)X +3122(and)X +3261(\256ll)X +3372(factors)X +3614(may)X +3775(be)X +3874(selected)X +4155(by)X +4257(apply-)X +2706 1356(ing)N +2828(the)X +2946(equation:)X +0 f +8 s +2706 1655(\(1\))N +2994 -0.3938(\(\(average_pair_length)AX +3830(+)X +3906(4\))X +4020(*)X +3032 1743(ffactor\))N +3374(>=)X +3488(bsize)X +1 f +10 s +2706 2042(For)N +2859(highly)X +3104(time)X +3287(critical)X +3551(applications,)X +3999(experimenting)X +2706 2130(with)N +2919(different)X +3266(bucket)X +3550(sizes)X +3776(and)X +3962(\256ll)X +4120(factors)X +4409(is)X +2706 2218(encouraged.)N +2878 2332(Figures)N +3144(5a,b,)X +3326(and)X +3468(c)X +3530(illustrate)X +3836(the)X +3960(effects)X +4200(of)X +4292(vary-)X +2706 2420(ing)N +2841(page)X +3026(sizes)X +3215(and)X +3363(\256ll)X +3483(factors)X +3734(for)X +3860(the)X +3990(same)X +4187(data)X +4353(set.)X +2706 2508(The)N +2864(data)X +3031(set)X +3152(consisted)X +3482(of)X +3581(24474)X +3813(keys)X +3992(taken)X +4198(from)X +4386(an)X +2706 2596(online)N +2931(dictionary.)X +3301(The)X +3451(data)X +3609(value)X +3807(for)X +3925(each)X +4097(key)X +4237(was)X +4386(an)X +2706 2684(ASCII)N +2938(string)X +3143(for)X +3260(an)X +3359(integer)X +3605(from)X +3784(1)X +3847(to)X +3931(24474)X +4153(inclusive.)X +2706 2772(The)N +2867(test)X +3013(run)X +3155(consisted)X +3488(of)X +3590(creating)X +3884(a)X +3955(new)X +4124(hash)X +4306(table)X +2706 2860(\(where)N +2966(the)X +3100(ultimate)X +3398(size)X +3559(of)X +3662(the)X +3796(table)X +3987(was)X +4147(known)X +4400(in)X +2706 2948(advance\),)N +3054(entering)X +3354(each)X +3539(key/data)X +3848(pair)X +4010(into)X +4171(the)X +4306(table)X +2706 3036(and)N +2849(then)X +3014(retrieving)X +3353(each)X +3528(key/data)X +3827(pair)X +3979(from)X +4162(the)X +4286(table.)X +2706 3124(Each)N +2898(of)X +2996(the)X +3125(graphs)X +3369(shows)X +3599(the)X +3727(timings)X +3996(resulting)X +4306(from)X +2706 3212(varying)N +2973(the)X +3093(pagesize)X +3392(from)X +3570(128)X +3712(bytes)X +3903(to)X +3986(1M)X +4118(and)X +4255(the)X +4374(\256ll)X +2706 3300(factor)N +2929(from)X +3120(1)X +3195(to)X +3292(128.)X +3486(For)X +3631(each)X +3813(run,)X +3974(the)X +4106(buffer)X +4337(size)X +2706 3388(was)N +2874(set)X +3006(at)X +3106(1M.)X +3299(The)X +3466(tests)X +3650(were)X +3849(all)X +3971(run)X +4120(on)X +4242(an)X +4360(HP)X +2706 3476(9000/370)N +3077(\(33.3)X +3312(Mhz)X +3527(MC68030\),)X +3966(with)X +4176(16M)X +4395(of)X +2706 3564(memory,)N +3042(64K)X +3228(physically)X +3605(addressed)X +3970(cache,)X +4222(and)X +4386(an)X +2706 3652(HP7959S)N +3055(disk)X +3231(drive,)X +3459(running)X +3751(4.3BSD-Reno)X +4244(single-)X +2706 3740(user.)N +2878 3854(Both)N +3066(system)X +3321(time)X +3496(\(Figure)X +3764(5a\))X +3899(and)X +4047(elapsed)X +4320(time)X +2706 3942(\(Figure)N +2966(5b\))X +3097(show)X +3290(that)X +3434(for)X +3552(all)X +3655(bucket)X +3892(sizes,)X +4091(the)X +4212(greatest)X +2706 4030(performance)N +3137(gains)X +3329(are)X +3451(made)X +3648(by)X +3751(increasing)X +4104(the)X +4225(\256ll)X +4336(fac-)X +2706 4118(tor)N +2822(until)X +2995(equation)X +3298(1)X +3365(is)X +3445(satis\256ed.)X +3774(The)X +3925(user)X +4085(time)X +4253(shown)X +2706 4206(in)N +2791(Figure)X +3023(5c)X +3122(gives)X +3314(a)X +3373(more)X +3561(detailed)X +3838(picture)X +4083(of)X +4172(how)X +4332(per-)X +2706 4294(formance)N +3054(varies.)X +3330(The)X +3499(smaller)X +3778(bucket)X +4035(sizes)X +4234(require)X +2706 4382(fewer)N +2921(keys)X +3099(per)X +3233(page)X +3416(to)X +3509(satisfy)X +3749(equation)X +4056(1)X +4127(and)X +4274(there-)X +2706 4470(fore)N +2860(incur)X +3049(fewer)X +3257(collisions.)X +3607(However,)X +3946(when)X +4144(the)X +4265(buffer)X +2706 4558(pool)N +2884(size)X +3045(is)X +3134(\256xed,)X +3349(smaller)X +3620(pages)X +3838(imply)X +4059(more)X +4259(pages.)X +2706 4646(An)N +2830(increased)X +3160(number)X +3430(of)X +3522(pages)X +3730(means)X +3960(more)X +2 f +4150(malloc\(3\))X +1 f +2706 4734(calls)N +2879(and)X +3021(more)X +3212(overhead)X +3533(in)X +3621(the)X +3745(hash)X +3918(package's)X +4265(buffer)X +2706 4822(manager)N +3003(to)X +3085(manage)X +3355(the)X +3473(additional)X +3813(pages.)X +2878 4936(The)N +3028(tradeoff)X +3308(works)X +3529(out)X +3655(most)X +3834(favorably)X +4166(when)X +4364(the)X +2706 5024(page)N +2886(size)X +3039(is)X +3120(256)X +3268(and)X +3412(the)X +3538(\256ll)X +3654(factor)X +3870(is)X +3950(8.)X +4057(Similar)X +4319(con-)X +2706 5112(clusions)N +3009(were)X +3207(obtained)X +3524(if)X +3614(the)X +3753(test)X +3905(was)X +4071(run)X +4218(without)X +2706 5200(knowing)N +3007(the)X +3126(\256nal)X +3289(table)X +3466(size)X +3612(in)X +3695(advance.)X +4020(If)X +4095(the)X +4214(\256le)X +4337(was)X +2706 5288(closed)N +2942(and)X +3088(written)X +3345(to)X +3437(disk,)X +3620(the)X +3748(conclusions)X +4156(were)X +4343(still)X +2706 5376(the)N +2832(same.)X +3065(However,)X +3408(rereading)X +3740(the)X +3865(\256le)X +3994(from)X +4177(disk)X +4337(was)X +2706 5464(slightly)N +2983(faster)X +3199(if)X +3285(a)X +3358(larger)X +3583(bucket)X +3834(size)X +3996(and)X +4149(\256ll)X +4274(factor)X +2706 5552(were)N +2898(used)X +3079(\(1K)X +3238(bucket)X +3486(size)X +3645(and)X +3795(32)X +3909(\256ll)X +4031(factor\).)X +4320(This)X +2706 5640(follows)N +2987(intuitively)X +3356(from)X +3553(the)X +3691(improved)X +4038(ef\256ciency)X +4395(of)X +3 f +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +4424(7)X + +8 p +%%Page: 8 8 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +432 258(A)N +510(New)X +682(Hashing)X +985(Package)X +1290(for)X +1413(UNIX)X +3663(Seltzer)X +3920(&)X +4007(Yigit)X +1 f +432 538(performing)N +830(1K)X +965(reads)X +1172(from)X +1365(the)X +1500(disk)X +1670(rather)X +1894(than)X +2068(256)X +432 626(byte)N +609(reads.)X +857(In)X +962(general,)X +1257(performance)X +1702(for)X +1834(disk)X +2005(based)X +432 714(tables)N +639(is)X +712(best)X +861(when)X +1055(the)X +1173(page)X +1345(size)X +1490(is)X +1563(approximately)X +2046(1K.)X +10 f +432 802 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +619 2380 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +629 2437 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +648 2504 MXY +-12 25 Dl +24 0 Dl +-12 -25 Dl +686 2515 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +762 2516 MXY +-12 24 Dl +25 0 Dl +-13 -24 Dl +916 2515 MXY +-13 24 Dl +25 0 Dl +-12 -24 Dl +1222 2516 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +1834 2515 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +1 Dt +619 2392 MXY +10 57 Dl +19 67 Dl +38 11 Dl +76 1 Dl +154 -1 Dl +306 1 Dl +612 -1 Dl +8 s +1 f +1628 2522(128)N +3 Dt +607 2245 MXY +24 Dc +617 2375 MXY +23 Dc +635 2442 MXY +24 Dc +674 2525 MXY +23 Dc +750 2529 MXY +24 Dc +904 2527 MXY +23 Dc +1210 MX +23 Dc +1822 2528 MXY +23 Dc +20 Ds +1 Dt +619 2245 MXY +10 130 Dl +19 67 Dl +38 83 Dl +76 4 Dl +154 -2 Dl +306 0 Dl +612 1 Dl +678 2482(256)N +-1 Ds +3 Dt +619 2127 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +629 2191 MXY +0 25 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +648 2334 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +686 2409 MXY +0 25 Dl +0 -13 Dl +12 0 Dl +-24 0 Dl +762 2516 MXY +0 25 Dl +0 -12 Dl +13 0 Dl +-25 0 Dl +916 2516 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-25 0 Dl +1222 2515 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +1834 2515 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +5 Dt +619 2139 MXY +10 65 Dl +19 142 Dl +38 75 Dl +76 108 Dl +154 -1 Dl +306 -1 Dl +612 0 Dl +694 2401(512)N +3 Dt +631 2064 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +641 2077 MXY +-24 25 Dl +12 -12 Dl +-12 -13 Dl +24 25 Dl +660 2132 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +698 2292 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +775 2382 MXY +-25 24 Dl +12 -12 Dl +-12 -12 Dl +25 24 Dl +928 2516 MXY +-25 24 Dl +13 -12 Dl +-13 -12 Dl +25 24 Dl +1234 2516 MXY +-24 25 Dl +12 -12 Dl +-12 -13 Dl +24 25 Dl +1846 2516 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +16 Ds +1 Dt +619 2076 MXY +10 14 Dl +19 54 Dl +38 160 Dl +76 90 Dl +154 134 Dl +306 1 Dl +612 -1 Dl +694 2257(1024)N +-1 Ds +3 Dt +619 1877 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +629 1855 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +648 1838 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +686 1860 MXY +12 -25 Dl +-24 0 Dl +12 25 Dl +762 1923 MXY +13 -24 Dl +-25 0 Dl +12 24 Dl +916 2087 MXY +12 -24 Dl +-25 0 Dl +13 24 Dl +1222 2256 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +1834 2541 MXY +12 -25 Dl +-24 0 Dl +12 25 Dl +619 1865 MXY +10 -22 Dl +19 -17 Dl +38 21 Dl +76 64 Dl +154 164 Dl +306 169 Dl +612 285 Dl +1645 2427(4096)N +619 1243 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +629 1196 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +648 1146 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +686 1174 MXY +0 25 Dl +0 -13 Dl +12 0 Dl +-24 0 Dl +762 1249 MXY +0 24 Dl +0 -12 Dl +13 0 Dl +-25 0 Dl +916 1371 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-25 0 Dl +1222 1680 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +1834 1999 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +619 1255 MXY +10 -47 Dl +19 -50 Dl +38 28 Dl +76 75 Dl +154 122 Dl +306 309 Dl +612 319 Dl +1741 1934(8192)N +5 Dt +609 2531 MXY +1225 0 Dl +609 MX +0 -1553 Dl +2531 MY +0 16 Dl +4 Ds +1 Dt +2531 MY +0 -1553 Dl +593 2625(0)N +-1 Ds +5 Dt +916 2531 MXY +0 16 Dl +4 Ds +1 Dt +2531 MY +0 -1553 Dl +884 2625(32)N +-1 Ds +5 Dt +1222 2531 MXY +0 16 Dl +4 Ds +1 Dt +2531 MY +0 -1553 Dl +1190 2625(64)N +-1 Ds +5 Dt +1528 2531 MXY +0 16 Dl +4 Ds +1 Dt +2531 MY +0 -1553 Dl +1496 2625(96)N +-1 Ds +5 Dt +1834 2531 MXY +0 16 Dl +4 Ds +1 Dt +2531 MY +0 -1553 Dl +1786 2625(128)N +-1 Ds +5 Dt +609 2531 MXY +-16 0 Dl +4 Ds +1 Dt +609 MX +1225 0 Dl +545 2558(0)N +-1 Ds +5 Dt +609 2013 MXY +-16 0 Dl +4 Ds +1 Dt +609 MX +1225 0 Dl +481 2040(100)N +-1 Ds +5 Dt +609 1496 MXY +-16 0 Dl +4 Ds +1 Dt +609 MX +1225 0 Dl +481 1523(200)N +-1 Ds +5 Dt +609 978 MXY +-16 0 Dl +4 Ds +1 Dt +609 MX +1225 0 Dl +481 1005(300)N +1088 2724(Fill)N +1194(Factor)X +422 1611(S)N +426 1667(e)N +426 1724(c)N +424 1780(o)N +424 1837(n)N +424 1893(d)N +428 1949(s)N +3 Dt +-1 Ds +3 f +432 2882(Figure)N +636(5a:)X +1 f +744(System)X +956(Time)X +1113(for)X +1209(dictionary)X +1490(data)X +1618(set)X +1711(with)X +1847(1M)X +1958(of)X +2033(buffer)X +432 2970(space)N +594(and)X +707(varying)X +923(bucket)X +1114(sizes)X +1259(and)X +1372(\256ll)X +1465(factors.)X +1675(Each)X +1823(line)X +1940(is)X +2004(labeled)X +432 3058(with)N +562(its)X +639(bucket)X +825(size.)X +10 s +10 f +432 3234 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +8 s +1 f +428 4381(s)N +424 4325(d)N +424 4269(n)N +424 4212(o)N +426 4156(c)N +426 4099(e)N +422 4043(S)N +1116 5156(Fill)N +1222(Factor)X +506 3437(3200)N +4 Ds +1 Dt +666 3410 MXY +1168 0 Dl +-1 Ds +5 Dt +666 MX +-16 0 Dl +506 3825(2400)N +4 Ds +1 Dt +666 3799 MXY +1168 0 Dl +-1 Ds +5 Dt +666 MX +-16 0 Dl +506 4214(1600)N +4 Ds +1 Dt +666 4186 MXY +1168 0 Dl +-1 Ds +5 Dt +666 MX +-16 0 Dl +538 4602(800)N +4 Ds +1 Dt +666 4575 MXY +1168 0 Dl +-1 Ds +5 Dt +666 MX +-16 0 Dl +602 4990(0)N +4 Ds +1 Dt +666 4963 MXY +1168 0 Dl +-1 Ds +5 Dt +666 MX +-16 0 Dl +1786 5057(128)N +4 Ds +1 Dt +1834 4963 MXY +0 -1553 Dl +-1 Ds +5 Dt +4963 MY +0 16 Dl +1510 5057(96)N +4 Ds +1 Dt +1542 4963 MXY +0 -1553 Dl +-1 Ds +5 Dt +4963 MY +0 16 Dl +1218 5057(64)N +4 Ds +1 Dt +1250 4963 MXY +0 -1553 Dl +-1 Ds +5 Dt +4963 MY +0 16 Dl +926 5057(32)N +4 Ds +1 Dt +958 4963 MXY +0 -1553 Dl +-1 Ds +5 Dt +4963 MY +0 16 Dl +650 5057(0)N +4 Ds +1 Dt +666 4963 MXY +0 -1553 Dl +-1 Ds +5 Dt +4963 MY +0 16 Dl +4963 MY +0 -1553 Dl +4963 MY +1168 0 Dl +1741 4752(8192)N +3 Dt +675 3732 MXY +9 -172 Dl +18 -118 Dl +37 128 Dl +73 -121 Dl +146 623 Dl +292 497 Dl +584 245 Dl +4802 MY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +1250 4557 MXY +0 25 Dl +0 -13 Dl +12 0 Dl +-24 0 Dl +958 4060 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +812 3437 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +739 3558 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +702 3430 MXY +0 25 Dl +0 -13 Dl +13 0 Dl +-25 0 Dl +684 3548 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +675 3720 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +1637 4912(4096)N +675 4307 MXY +9 -58 Dl +18 30 Dl +37 89 Dl +73 144 Dl +146 235 Dl +292 122 Dl +584 89 Dl +4970 MY +12 -24 Dl +-24 0 Dl +12 24 Dl +1250 4881 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +958 4759 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +812 4524 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +739 4380 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +702 4291 MXY +13 -24 Dl +-25 0 Dl +12 24 Dl +684 4261 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +675 4319 MXY +12 -24 Dl +-24 0 Dl +12 24 Dl +734 4662(1024)N +16 Ds +1 Dt +675 4352 MXY +9 60 Dl +18 134 Dl +37 266 Dl +73 117 Dl +146 30 Dl +292 0 Dl +584 -1 Dl +-1 Ds +3 Dt +1846 4946 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +1262 4946 MXY +-24 25 Dl +12 -12 Dl +-12 -13 Dl +24 25 Dl +970 4947 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +824 4917 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +751 4800 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +715 4534 MXY +-25 25 Dl +12 -13 Dl +-12 -12 Dl +25 25 Dl +696 4400 MXY +-24 24 Dl +12 -12 Dl +-12 -12 Dl +24 24 Dl +687 4339 MXY +-24 25 Dl +12 -12 Dl +-12 -13 Dl +24 25 Dl +718 4792(512)N +5 Dt +675 4422 MXY +9 137 Dl +18 278 Dl +37 105 Dl +73 18 Dl +146 -1 Dl +292 0 Dl +584 -1 Dl +3 Dt +4946 MY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +1250 4946 MXY +0 25 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +958 4947 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +812 4948 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +739 4930 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +702 4824 MXY +0 25 Dl +0 -12 Dl +13 0 Dl +-25 0 Dl +684 4547 MXY +0 24 Dl +0 -12 Dl +12 0 Dl +-24 0 Dl +675 4410 MXY +0 25 Dl +0 -13 Dl +12 0 Dl +-24 0 Dl +750 4921(256)N +20 Ds +1 Dt +675 4597 MXY +9 246 Dl +18 106 Dl +37 10 Dl +73 0 Dl +146 0 Dl +292 0 Dl +584 -1 Dl +-1 Ds +3 Dt +1822 MX +23 Dc +1238 4959 MXY +23 Dc +946 MX +23 Dc +800 MX +23 Dc +727 MX +23 Dc +691 4949 MXY +23 Dc +672 4843 MXY +24 Dc +663 4597 MXY +24 Dc +1395 4961(128)N +1 Dt +675 4855 MXY +9 93 Dl +18 10 Dl +37 1 Dl +73 0 Dl +146 -1 Dl +292 0 Dl +584 0 Dl +3 Dt +4946 MY +-12 24 Dl +24 0 Dl +-12 -24 Dl +1250 MX +-12 24 Dl +24 0 Dl +-12 -24 Dl +958 MX +-12 24 Dl +24 0 Dl +-12 -24 Dl +812 MX +-12 25 Dl +24 0 Dl +-12 -25 Dl +739 4947 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +702 4946 MXY +-12 24 Dl +25 0 Dl +-13 -24 Dl +684 4936 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +675 4843 MXY +-12 24 Dl +24 0 Dl +-12 -24 Dl +3 Dt +-1 Ds +3 f +432 5314(Figure)N +634(5b:)X +1 f +744(Elapsed)X +967(Time)X +1123(for)X +1218(dictionary)X +1498(data)X +1625(set)X +1717(with)X +1851(1M)X +1960(of)X +2033(buffer)X +432 5402(space)N +593(and)X +705(varying)X +920(bucket)X +1110(sizes)X +1254(and)X +1366(\256ll)X +1457(factors.)X +1681(Each)X +1827(line)X +1942(is)X +2004(labeled)X +432 5490(with)N +562(its)X +639(bucket)X +825(size.)X +10 s +2590 538(If)N +2677(an)X +2785(approximation)X +3284(of)X +3383(the)X +3513(number)X +3790(of)X +3889(elements)X +2418 626(ultimately)N +2773(to)X +2866(be)X +2973(stored)X +3200(in)X +3293(the)X +3422(hash)X +3599(table)X +3785(is)X +3868(known)X +4116(at)X +2418 714(the)N +2564(time)X +2754(of)X +2869(creation,)X +3196(the)X +3342(hash)X +3536(package)X +3847(takes)X +4059(this)X +2418 802(number)N +2688(as)X +2779(a)X +2839(parameter)X +3185(and)X +3325(uses)X +3487(it)X +3555(to)X +3641(hash)X +3812(entries)X +4050(into)X +2418 890(the)N +2541(full)X +2677(sized)X +2867(table)X +3048(rather)X +3261(than)X +3424(growing)X +3716(the)X +3838(table)X +4018(from)X +2418 978(a)N +2477(single)X +2691(bucket.)X +2968(If)X +3044(this)X +3181(number)X +3448(is)X +3523(not)X +3647(known,)X +3907(the)X +4027(hash)X +2418 1066(table)N +2632(starts)X +2859(with)X +3059(a)X +3153(single)X +3402(bucket)X +3674(and)X +3848(gracefully)X +2418 1154(expands)N +2707(as)X +2800(elements)X +3111(are)X +3236(added,)X +3474(although)X +3780(a)X +3842(slight)X +4044(per-)X +2418 1242(formance)N +2747(degradation)X +3151(may)X +3313(be)X +3413(noticed.)X +3713(Figure)X +3946(6)X +4010(illus-)X +2418 1330(trates)N +2625(the)X +2756(difference)X +3116(in)X +3211(performance)X +3651(between)X +3952(storing)X +2418 1418(keys)N +2588(in)X +2673(a)X +2732(\256le)X +2857(when)X +3054(the)X +3174(ultimate)X +3458(size)X +3605(is)X +3680(known)X +3920(\(the)X +4067(left)X +2418 1506(bars)N +2581(in)X +2672(each)X +2849(set\),)X +3014(compared)X +3360(to)X +3450(building)X +3744(the)X +3870(\256le)X +4000(when)X +2418 1594(the)N +2550(ultimate)X +2846(size)X +3005(is)X +3091(unknown)X +3422(\(the)X +3580(right)X +3764(bars)X +3931(in)X +4026(each)X +2418 1682(set\).)N +2609(Once)X +2814(the)X +2947(\256ll)X +3069(factor)X +3291(is)X +3378(suf\256ciently)X +3772(high)X +3948(for)X +4076(the)X +2418 1770(page)N +2596(size)X +2747(\(8\),)X +2887(growing)X +3180(the)X +3304(table)X +3486(dynamically)X +3908(does)X +4081(lit-)X +2418 1858(tle)N +2518(to)X +2600(degrade)X +2875(performance.)X +10 f +2418 1946 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +9 s +1 f +2413 3238(s)N +2409 3173(d)N +2409 3108(n)N +2409 3043(o)N +2411 2979(c)N +2411 2914(e)N +2407 2849(S)N +3143 4129(Fill)N +3261(Factor)X +2448 2152(15)N +4 Ds +1 Dt +2557 2122 MXY +1473 0 Dl +-1 Ds +5 Dt +2557 MX +-19 0 Dl +2448 2747(10)N +4 Ds +1 Dt +2557 2717 MXY +1473 0 Dl +-1 Ds +5 Dt +2557 MX +-19 0 Dl +2484 3343(5)N +4 Ds +1 Dt +2557 3313 MXY +1473 0 Dl +-1 Ds +5 Dt +2557 MX +-19 0 Dl +2484 3938(0)N +4 Ds +1 Dt +2557 3908 MXY +1473 0 Dl +-1 Ds +5 Dt +2557 MX +-19 0 Dl +3976 4015(128)N +4 Ds +1 Dt +4030 3908 MXY +0 -1786 Dl +-1 Ds +5 Dt +3908 MY +0 19 Dl +3626 4015(96)N +4 Ds +1 Dt +3662 3908 MXY +0 -1786 Dl +-1 Ds +5 Dt +3908 MY +0 19 Dl +3258 4015(64)N +4 Ds +1 Dt +3294 3908 MXY +0 -1786 Dl +-1 Ds +5 Dt +3908 MY +0 19 Dl +2889 4015(32)N +4 Ds +1 Dt +2925 3908 MXY +0 -1786 Dl +-1 Ds +5 Dt +3908 MY +0 19 Dl +2539 4015(0)N +4 Ds +1 Dt +2557 3908 MXY +0 -1786 Dl +-1 Ds +5 Dt +3908 MY +0 19 Dl +3908 MY +0 -1786 Dl +3908 MY +1473 0 Dl +4053 2378(8192)N +3 Dt +2569 2277 MXY +11 0 Dl +23 48 Dl +46 -167 Dl +92 35 Dl +184 12 Dl +369 143 Dl +736 0 Dl +2334 MY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +3294 2334 MXY +0 28 Dl +0 -14 Dl +13 0 Dl +-27 0 Dl +2925 2192 MXY +0 27 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2741 2180 MXY +0 27 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2649 2144 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2603 2311 MXY +0 27 Dl +0 -13 Dl +14 0 Dl +-28 0 Dl +2580 2263 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2569 2263 MXY +0 28 Dl +0 -14 Dl +13 0 Dl +-27 0 Dl +4053 2591(4096)N +2569 2348 MXY +11 -11 Dl +23 -96 Dl +46 71 Dl +92 72 Dl +184 226 Dl +369 48 Dl +736 -60 Dl +2612 MY +14 -28 Dl +-28 0 Dl +14 28 Dl +3294 2672 MXY +13 -28 Dl +-27 0 Dl +14 28 Dl +2925 2624 MXY +14 -28 Dl +-28 0 Dl +14 28 Dl +2741 2398 MXY +14 -28 Dl +-28 0 Dl +14 28 Dl +2649 2326 MXY +14 -27 Dl +-28 0 Dl +14 27 Dl +2603 2255 MXY +14 -28 Dl +-28 0 Dl +14 28 Dl +2580 2350 MXY +14 -27 Dl +-28 0 Dl +14 27 Dl +2569 2362 MXY +13 -28 Dl +-27 0 Dl +14 28 Dl +4053 2681(1024)N +16 Ds +1 Dt +2569 2300 MXY +11 48 Dl +23 96 Dl +46 95 Dl +92 274 Dl +184 202 Dl +369 -155 Dl +736 -190 Dl +-1 Ds +3 Dt +4044 2656 MXY +-28 28 Dl +14 -14 Dl +-14 -14 Dl +28 28 Dl +3307 2846 MXY +-27 28 Dl +14 -14 Dl +-14 -14 Dl +27 28 Dl +2939 3001 MXY +-28 28 Dl +14 -14 Dl +-14 -14 Dl +28 28 Dl +2755 2799 MXY +-28 28 Dl +14 -14 Dl +-14 -14 Dl +28 28 Dl +2663 2525 MXY +-28 28 Dl +14 -14 Dl +-14 -14 Dl +28 28 Dl +2617 2430 MXY +-28 28 Dl +14 -14 Dl +-14 -14 Dl +28 28 Dl +2594 2334 MXY +-28 28 Dl +14 -14 Dl +-14 -14 Dl +28 28 Dl +2582 2287 MXY +-27 27 Dl +14 -14 Dl +-14 -13 Dl +27 27 Dl +4053 2851(512)N +5 Dt +2569 2372 MXY +11 -24 Dl +23 405 Dl +46 83 Dl +92 227 Dl +184 -72 Dl +369 -119 Dl +736 -107 Dl +3 Dt +2751 MY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +3294 2858 MXY +0 28 Dl +0 -14 Dl +13 0 Dl +-27 0 Dl +2925 2977 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2741 3049 MXY +0 27 Dl +0 -13 Dl +14 0 Dl +-28 0 Dl +2649 2823 MXY +0 27 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2603 2739 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2580 2334 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2569 2358 MXY +0 28 Dl +0 -14 Dl +13 0 Dl +-27 0 Dl +4053 2795(256)N +20 Ds +1 Dt +2569 2456 MXY +11 285 Dl +23 95 Dl +46 251 Dl +92 -60 Dl +184 -84 Dl +369 -107 Dl +736 -71 Dl +-1 Ds +3 Dt +4016 MX +27 Dc +3280 2836 MXY +27 Dc +2912 2943 MXY +27 Dc +2728 3027 MXY +27 Dc +2635 3087 MXY +28 Dc +2589 2836 MXY +28 Dc +2566 2741 MXY +27 Dc +2554 2456 MXY +28 Dc +4053 2741(128)N +1 Dt +2569 2729 MXY +11 203 Dl +23 131 Dl +46 -60 Dl +92 -119 Dl +184 -60 Dl +369 -83 Dl +736 -12 Dl +3 Dt +2716 MY +-14 27 Dl +28 0 Dl +-14 -27 Dl +3294 2727 MXY +-14 28 Dl +27 0 Dl +-13 -28 Dl +2925 2811 MXY +-14 27 Dl +28 0 Dl +-14 -27 Dl +2741 2870 MXY +-14 28 Dl +28 0 Dl +-14 -28 Dl +2649 2989 MXY +-14 28 Dl +28 0 Dl +-14 -28 Dl +2603 3049 MXY +-14 27 Dl +28 0 Dl +-14 -27 Dl +2580 2918 MXY +-14 28 Dl +28 0 Dl +-14 -28 Dl +2569 2716 MXY +-14 27 Dl +27 0 Dl +-13 -27 Dl +3 Dt +-1 Ds +3 f +8 s +2418 4286(Figure)N +2628(5c:)X +1 f +2738(User)X +2887(Time)X +3051(for)X +3154(dictionary)X +3442(data)X +3577(set)X +3677(with)X +3820(1M)X +3938(of)X +4019(buffer)X +2418 4374(space)N +2579(and)X +2691(varying)X +2906(bucket)X +3096(sizes)X +3240(and)X +3352(\256ll)X +3443(factors.)X +3667(Each)X +3813(line)X +3928(is)X +3990(labeled)X +2418 4462(with)N +2548(its)X +2625(bucket)X +2811(size.)X +10 s +10 f +2418 4638 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +1 f +2590 4840(Since)N +2796(no)X +2904(known)X +3150(hash)X +3325(function)X +3620(performs)X +3938(equally)X +2418 4928(well)N +2589(on)X +2702(all)X +2815(possible)X +3110(data,)X +3297(the)X +3428(user)X +3595(may)X +3766(\256nd)X +3923(that)X +4076(the)X +2418 5016(built-in)N +2678(hash)X +2849(function)X +3140(does)X +3311(poorly)X +3544(on)X +3648(a)X +3708(particular)X +4040(data)X +2418 5104(set.)N +2548(In)X +2636(this)X +2771(case,)X +2950(a)X +3006(hash)X +3173(function,)X +3480(taking)X +3700(two)X +3840(arguments)X +2418 5192(\(a)N +2507(pointer)X +2760(to)X +2848(a)X +2910(byte)X +3074(string)X +3282(and)X +3424(a)X +3486(length\))X +3739(and)X +3880(returning)X +2418 5280(an)N +2517(unsigned)X +2829(long)X +2993(to)X +3077(be)X +3175(used)X +3344(as)X +3433(the)X +3553(hash)X +3722(value,)X +3938(may)X +4098(be)X +2418 5368(speci\256ed)N +2731(at)X +2817(hash)X +2992(table)X +3176(creation)X +3463(time.)X +3673(When)X +3893(an)X +3996(exist-)X +2418 5456(ing)N +2570(hash)X +2767(table)X +2973(is)X +3076(opened)X +3358(and)X +3524(a)X +3609(hash)X +3805(function)X +4121(is)X +2418 5544(speci\256ed,)N +2752(the)X +2879(hash)X +3054(package)X +3346(will)X +3498(try)X +3615(to)X +3705(determine)X +4054(that)X +2418 5632(the)N +2546(hash)X +2723(function)X +3020(supplied)X +3321(is)X +3404(the)X +3532(one)X +3678(with)X +3850(which)X +4076(the)X +2418 5720(table)N +2630(was)X +2811(created.)X +3139(There)X +3382(are)X +3536(a)X +3627(variety)X +3905(of)X +4027(hash)X +3 f +432 5960(8)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +9 p +%%Page: 9 9 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +720 258(Seltzer)N +977(&)X +1064(Yigit)X +3278(A)X +3356(New)X +3528(Hashing)X +3831(Package)X +4136(for)X +4259(UNIX)X +1 f +720 538(functions)N +1065(provided)X +1397(with)X +1586(the)X +1731(package.)X +2082(The)X +2253(default)X +720 626(function)N +1014(for)X +1135(the)X +1260(package)X +1551(is)X +1631(the)X +1755(one)X +1897(which)X +2119(offered)X +2378(the)X +720 714(best)N +875(performance)X +1308(in)X +1396(terms)X +1600(of)X +1693(cycles)X +1920(executed)X +2232(per)X +2360(call)X +720 802(\(it)N +827(did)X +965(not)X +1103(produce)X +1398(the)X +1531(fewest)X +1776(collisions)X +2117(although)X +2432(it)X +720 890(was)N +866(within)X +1091(a)X +1148(small)X +1341(percentage)X +1710(of)X +1797(the)X +1915(function)X +2202(that)X +2342(pro-)X +720 978(duced)N +947(the)X +1080(fewest)X +1324(collisions\).)X +1731(Again,)X +1981(in)X +2077(time)X +2253(critical)X +720 1066(applications,)N +1152(users)X +1342(are)X +1466(encouraged)X +1862(to)X +1949(experiment)X +2334(with)X +720 1154(a)N +783(variety)X +1032(of)X +1125(hash)X +1298(functions)X +1622(to)X +1710(achieve)X +1982(optimal)X +2252(perfor-)X +720 1242(mance.)N +10 f +720 1330 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +7 s +1038 2925(Full)N +1149(size)X +1251(table)X +1384(\(left\))X +1547 2718(Fill)N +1643(Factor)X +2268 2662(64)N +1964(32)X +1674(16)X +1384(8)X +1093(4)X +4 Ds +1 Dt +900 2280 MXY +1548 0 Dl +900 1879 MXY +1548 0 Dl +900 1506 MXY +1548 0 Dl +1563 2902 MXY +111 0 Dl +-1 Ds +900 MX +110 0 Dl +1425 2828(System)N +983(User)X +1895 2778 MXY + 1895 2778 lineto + 1950 2778 lineto + 1950 2833 lineto + 1895 2833 lineto + 1895 2778 lineto +closepath 21 1895 2778 1950 2833 Dp +1342 MX + 1342 2778 lineto + 1397 2778 lineto + 1397 2833 lineto + 1342 2833 lineto + 1342 2778 lineto +closepath 14 1342 2778 1397 2833 Dp +900 MX + 900 2778 lineto + 955 2778 lineto + 955 2833 lineto + 900 2833 lineto + 900 2778 lineto +closepath 3 900 2778 955 2833 Dp +5 Dt +2283 2211 MXY +96 0 Dl +1992 MX +97 0 Dl +1702 MX +97 0 Dl +1411 2252 MXY +97 0 Dl +4 Ds +1 Dt +2283 2211 MXY + 2283 2211 lineto + 2379 2211 lineto + 2379 2252 lineto + 2283 2252 lineto + 2283 2211 lineto +closepath 14 2283 2211 2379 2252 Dp +1992 MX + 1992 2211 lineto + 2089 2211 lineto + 2089 2252 lineto + 1992 2252 lineto + 1992 2211 lineto +closepath 14 1992 2211 2089 2252 Dp +1702 MX + 1702 2211 lineto + 1799 2211 lineto + 1799 2252 lineto + 1702 2252 lineto + 1702 2211 lineto +closepath 14 1702 2211 1799 2252 Dp +1411 2252 MXY + 1411 2252 lineto + 1508 2252 lineto + 1508 2294 lineto + 1411 2294 lineto + 1411 2252 lineto +closepath 14 1411 2252 1508 2294 Dp +2283 MX + 2283 2252 lineto + 2379 2252 lineto + 2379 2612 lineto + 2283 2612 lineto + 2283 2252 lineto +closepath 3 2283 2252 2379 2612 Dp +1992 MX + 1992 2252 lineto + 2089 2252 lineto + 2089 2612 lineto + 1992 2612 lineto + 1992 2252 lineto +closepath 3 1992 2252 2089 2612 Dp +1702 MX + 1702 2252 lineto + 1799 2252 lineto + 1799 2612 lineto + 1702 2612 lineto + 1702 2252 lineto +closepath 3 1702 2252 1799 2612 Dp +1411 2294 MXY + 1411 2294 lineto + 1508 2294 lineto + 1508 2612 lineto + 1411 2612 lineto + 1411 2294 lineto +closepath 3 1411 2294 1508 2612 Dp +-1 Ds +2158 2238 MXY + 2158 2238 lineto + 2255 2238 lineto + 2255 2252 lineto + 2158 2252 lineto + 2158 2238 lineto +closepath 21 2158 2238 2255 2252 Dp +1868 MX + 1868 2238 lineto + 1965 2238 lineto + 1965 2280 lineto + 1868 2280 lineto + 1868 2238 lineto +closepath 21 1868 2238 1965 2280 Dp +1577 MX + 1577 2238 lineto + 1674 2238 lineto + 1674 2308 lineto + 1577 2308 lineto + 1577 2238 lineto +closepath 21 1577 2238 1674 2308 Dp +1287 2308 MXY + 1287 2308 lineto + 1287 2280 lineto + 1384 2280 lineto + 1384 2308 lineto + 1287 2308 lineto +closepath 21 1287 2280 1384 2308 Dp +2158 2280 MXY + 2158 2280 lineto + 2158 2252 lineto + 2255 2252 lineto + 2255 2280 lineto + 2158 2280 lineto +closepath 14 2158 2252 2255 2280 Dp +1868 2308 MXY + 1868 2308 lineto + 1868 2280 lineto + 1965 2280 lineto + 1965 2308 lineto + 1868 2308 lineto +closepath 14 1868 2280 1965 2308 Dp +1577 2335 MXY + 1577 2335 lineto + 1577 2308 lineto + 1674 2308 lineto + 1674 2335 lineto + 1577 2335 lineto +closepath 14 1577 2308 1674 2335 Dp +1287 2363 MXY + 1287 2363 lineto + 1287 2308 lineto + 1384 2308 lineto + 1384 2363 lineto + 1287 2363 lineto +closepath 14 1287 2308 1384 2363 Dp +2158 2280 MXY + 2158 2280 lineto + 2255 2280 lineto + 2255 2612 lineto + 2158 2612 lineto + 2158 2280 lineto +closepath 3 2158 2280 2255 2612 Dp +1868 2308 MXY + 1868 2308 lineto + 1965 2308 lineto + 1965 2612 lineto + 1868 2612 lineto + 1868 2308 lineto +closepath 3 1868 2308 1965 2612 Dp +1577 2335 MXY + 1577 2335 lineto + 1674 2335 lineto + 1674 2612 lineto + 1577 2612 lineto + 1577 2335 lineto +closepath 3 1577 2335 1674 2612 Dp +1287 2363 MXY + 1287 2363 lineto + 1384 2363 lineto + 1384 2612 lineto + 1287 2612 lineto + 1287 2363 lineto +closepath 3 1287 2363 1384 2612 Dp +4 Ds +1121 2066 MXY + 1121 2066 lineto + 1218 2066 lineto + 1224 2080 lineto + 1127 2080 lineto + 1121 2066 lineto +closepath 21 1121 2066 1224 2080 Dp +2080 MY + 1121 2080 lineto + 1218 2080 lineto + 1218 2273 lineto + 1121 2273 lineto + 1121 2080 lineto +closepath 14 1121 2080 1218 2273 Dp +2273 MY + 1121 2273 lineto + 1218 2273 lineto + 1218 2612 lineto + 1121 2612 lineto + 1121 2273 lineto +closepath 3 1121 2273 1218 2612 Dp +-1 Ds +997 1589 MXY + 997 1589 lineto + 1093 1589 lineto + 1093 1644 lineto + 997 1644 lineto + 997 1589 lineto +closepath 21 997 1589 1093 1644 Dp +1644 MY + 997 1644 lineto + 1093 1644 lineto + 1093 2280 lineto + 997 2280 lineto + 997 1644 lineto +closepath 14 997 1644 1093 2280 Dp +2280 MY + 997 2280 lineto + 1093 2280 lineto + 1093 2612 lineto + 997 2612 lineto + 997 2280 lineto +closepath 3 997 2280 1093 2612 Dp +10 s +719 2093(s)N +712 2037(d)N +712 1982(n)N +714 1927(o)N +716 1872(c)N +716 1816(e)N +712 1761(S)N +804 2286(10)N +804 1899(20)N +804 1540(30)N +3 Dt +900 1506 MXY +0 1106 Dl +1548 0 Dl +7 s +1978 2828(Elapsed)N +1701 2925(Dynamically)N +2018(grown)X +2184(table)X +2317(\(right\))X +3 Dt +-1 Ds +8 s +720 3180(Figure)N +934(6:)X +1 f +1020(The)X +1152(total)X +1299(regions)X +1520(indicate)X +1755(the)X +1865(difference)X +2154(between)X +2398(the)X +720 3268(elapsed)N +931(time)X +1065(and)X +1177(the)X +1275(sum)X +1402(of)X +1475(the)X +1573(system)X +1771(and)X +1883(user)X +2008(time.)X +2173(The)X +2291(left)X +2395(bar)X +720 3356(of)N +798(each)X +939(set)X +1035(depicts)X +1241(the)X +1344(timing)X +1537(of)X +1615(the)X +1718(test)X +1831(run)X +1940(when)X +2102(the)X +2204(number)X +2423(of)X +720 3444(entries)N +910(is)X +973(known)X +1167(in)X +1237(advance.)X +1496(The)X +1614(right)X +1754(bars)X +1879(depict)X +2054(the)X +2151(timing)X +2338(when)X +720 3532(the)N +814(\256le)X +912(is)X +971(grown)X +1150(from)X +1290(a)X +1334(single)X +1503(bucket.)X +10 s +10 f +720 3708 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +1 f +892 3910(Since)N +1131(this)X +1307(hashing)X +1617(package)X +1942(provides)X +2279(buffer)X +720 3998(management,)N +1188(the)X +1323(amount)X +1600(of)X +1704(space)X +1920(allocated)X +2247(for)X +2378(the)X +720 4086(buffer)N +948(pool)X +1121(may)X +1290(be)X +1397(speci\256ed)X +1713(by)X +1824(the)X +1953(user.)X +2157(Using)X +2378(the)X +720 4174(same)N +910(data)X +1069(set)X +1183(and)X +1324(test)X +1459(procedure)X +1805(as)X +1896(used)X +2067(to)X +2153(derive)X +2378(the)X +720 4262(graphs)N +962(in)X +1052(Figures)X +1320(5a-c,)X +1507(Figure)X +1744(7)X +1812(shows)X +2039(the)X +2164(impact)X +2409(of)X +720 4350(varying)N +997(the)X +1126(size)X +1282(of)X +1380(the)X +1509(buffer)X +1737(pool.)X +1950(The)X +2106(bucket)X +2351(size)X +720 4438(was)N +873(set)X +989(to)X +1078(256)X +1225(bytes)X +1421(and)X +1564(the)X +1689(\256ll)X +1804(factor)X +2019(was)X +2171(set)X +2287(to)X +2376(16.)X +720 4526(The)N +869(buffer)X +1090(pool)X +1256(size)X +1404(was)X +1552(varied)X +1776(from)X +1955(0)X +2018(\(the)X +2166(minimum)X +720 4614(number)N +986(of)X +1074(pages)X +1277(required)X +1565(to)X +1647(be)X +1743(buffered\))X +2063(to)X +2145(1M.)X +2316(With)X +720 4702(1M)N +854(of)X +944(buffer)X +1164(space,)X +1386(the)X +1507(package)X +1794(performed)X +2151(no)X +2253(I/O)X +2382(for)X +720 4790(this)N +871(data)X +1040(set.)X +1204(As)X +1328(Figure)X +1572(7)X +1647(illustrates,)X +2013(increasing)X +2378(the)X +720 4878(buffer)N +944(pool)X +1113(size)X +1265(can)X +1404(have)X +1583(a)X +1646(dramatic)X +1954(affect)X +2165(on)X +2271(result-)X +720 4966(ing)N +842(performance.)X +2 f +8 s +1269 4941(7)N +1 f +16 s +720 5353 MXY +864 0 Dl +2 f +8 s +760 5408(7)N +1 f +9 s +826 5433(Some)N +1024(allocators)X +1338(are)X +1460(extremely)X +1782(inef\256cient)X +2107(at)X +2192(allocating)X +720 5513(memory.)N +1029(If)X +1110(you)X +1251(\256nd)X +1396(that)X +1536(applications)X +1916(are)X +2036(running)X +2292(out)X +2416(of)X +720 5593(memory)N +1005(before)X +1234(you)X +1386(think)X +1578(they)X +1746(should,)X +2000(try)X +2124(varying)X +2388(the)X +720 5673(pagesize)N +986(to)X +1060(get)X +1166(better)X +1348(utilization)X +1658(from)X +1816(the)X +1922(memory)X +2180(allocator.)X +10 s +2830 1975 MXY +0 -28 Dl +28 0 Dl +0 28 Dl +-28 0 Dl +2853 2004 MXY +0 -27 Dl +28 0 Dl +0 27 Dl +-28 0 Dl +2876 2016 MXY +0 -27 Dl +27 0 Dl +0 27 Dl +-27 0 Dl +2922 1998 MXY +0 -27 Dl +27 0 Dl +0 27 Dl +-27 0 Dl +2967 2025 MXY +0 -28 Dl +28 0 Dl +0 28 Dl +-28 0 Dl +3013 2031 MXY +0 -28 Dl +28 0 Dl +0 28 Dl +-28 0 Dl +3059 MX +0 -28 Dl +27 0 Dl +0 28 Dl +-27 0 Dl +3196 2052 MXY +0 -28 Dl +27 0 Dl +0 28 Dl +-27 0 Dl +3561 2102 MXY +0 -28 Dl +28 0 Dl +0 28 Dl +-28 0 Dl +4292 2105 MXY +0 -28 Dl +27 0 Dl +0 28 Dl +-27 0 Dl +4 Ds +1 Dt +2844 1961 MXY +23 30 Dl +23 12 Dl +45 -18 Dl +46 26 Dl +46 6 Dl +45 0 Dl +137 21 Dl +366 50 Dl +730 3 Dl +9 s +4227 2158(User)N +-1 Ds +3 Dt +2830 1211 MXY +27 Dc +2853 1261 MXY +27 Dc +2876 1267 MXY +27 Dc +2921 1341 MXY +27 Dc +2967 1385 MXY +27 Dc +3013 1450 MXY +27 Dc +3059 1497 MXY +27 Dc +3196 1686 MXY +27 Dc +3561 2109 MXY +27 Dc +4292 2295 MXY +27 Dc +20 Ds +1 Dt +2844 1211 MXY +23 50 Dl +23 6 Dl +45 74 Dl +46 44 Dl +46 65 Dl +45 47 Dl +137 189 Dl +366 423 Dl +730 186 Dl +4181 2270(System)N +-1 Ds +3 Dt +2844 583 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2867 672 MXY +0 27 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +2890 701 MXY +0 28 Dl +0 -14 Dl +13 0 Dl +-27 0 Dl +2935 819 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-27 0 Dl +2981 849 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +3027 908 MXY +0 27 Dl +0 -13 Dl +14 0 Dl +-28 0 Dl +3072 1026 MXY +0 27 Dl +0 -13 Dl +14 0 Dl +-27 0 Dl +3209 1292 MXY +0 27 Dl +0 -14 Dl +14 0 Dl +-27 0 Dl +3575 1823 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-28 0 Dl +4305 2059 MXY +0 28 Dl +0 -14 Dl +14 0 Dl +-27 0 Dl +5 Dt +2844 597 MXY +23 88 Dl +23 30 Dl +45 118 Dl +46 30 Dl +46 59 Dl +45 118 Dl +137 265 Dl +366 532 Dl +730 236 Dl +4328 2103(Total)N +2844 2310 MXY +1461 0 Dl +2844 MX +0 -1772 Dl +2310 MY +0 18 Dl +4 Ds +1 Dt +2310 MY +0 -1772 Dl +2826 2416(0)N +-1 Ds +5 Dt +3209 2310 MXY +0 18 Dl +4 Ds +1 Dt +2310 MY +0 -1772 Dl +3155 2416(256)N +-1 Ds +5 Dt +3575 2310 MXY +0 18 Dl +4 Ds +1 Dt +2310 MY +0 -1772 Dl +3521 2416(512)N +-1 Ds +5 Dt +3940 2310 MXY +0 18 Dl +4 Ds +1 Dt +2310 MY +0 -1772 Dl +3886 2416(768)N +-1 Ds +5 Dt +4305 2310 MXY +0 18 Dl +4 Ds +1 Dt +2310 MY +0 -1772 Dl +4233 2416(1024)N +-1 Ds +5 Dt +2844 2310 MXY +-18 0 Dl +4 Ds +1 Dt +2844 MX +1461 0 Dl +2771 2340(0)N +-1 Ds +5 Dt +2844 2014 MXY +-18 0 Dl +2844 1719 MXY +-18 0 Dl +4 Ds +1 Dt +2844 MX +1461 0 Dl +2735 1749(20)N +-1 Ds +5 Dt +2844 1423 MXY +-18 0 Dl +2844 1128 MXY +-18 0 Dl +4 Ds +1 Dt +2844 MX +1461 0 Dl +2735 1158(40)N +-1 Ds +5 Dt +2844 833 MXY +-18 0 Dl +2844 538 MXY +-18 0 Dl +4 Ds +1 Dt +2844 MX +1461 0 Dl +2735 568(60)N +3239 2529(Buffer)N +3445(Pool)X +3595(Size)X +3737(\(in)X +3835(K\))X +2695 1259(S)N +2699 1324(e)N +2699 1388(c)N +2697 1452(o)N +2697 1517(n)N +2697 1581(d)N +2701 1645(s)N +3 Dt +-1 Ds +3 f +8 s +2706 2773(Figure)N +2908(7:)X +1 f +2982(User)X +3123(time)X +3258(is)X +3322(virtually)X +3560(insensitive)X +3854(to)X +3924(the)X +4022(amount)X +4234(of)X +4307(buffer)X +2706 2861(pool)N +2852(available,)X +3130(however,)X +3396(both)X +3541(system)X +3750(time)X +3895(and)X +4018(elapsed)X +4240(time)X +4385(are)X +2706 2949(inversely)N +2960(proportional)X +3296(to)X +3366(the)X +3464(size)X +3583(of)X +3656(the)X +3753(buffer)X +3927(pool.)X +4092(Even)X +4242(for)X +4335(large)X +2706 3037(data)N +2831(sets)X +2946(where)X +3120(one)X +3230(expects)X +3439(few)X +3552(collisions,)X +3832(specifying)X +4116(a)X +4162(large)X +4307(buffer)X +2706 3125(pool)N +2836(dramatically)X +3171(improves)X +3425(performance.)X +10 s +10 f +2706 3301 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +3175 3543(Enhanced)N +3536(Functionality)X +1 f +2878 3675(This)N +3046(hashing)X +3320(package)X +3609(provides)X +3910(a)X +3971(set)X +4085(of)X +4177(compati-)X +2706 3763(bility)N +2895(routines)X +3174(to)X +3257(implement)X +3620(the)X +2 f +3739(ndbm)X +1 f +3937(interface.)X +4279(How-)X +2706 3851(ever,)N +2893(when)X +3095(the)X +3220(native)X +3443(interface)X +3752(is)X +3832(used,)X +4026(the)X +4151(following)X +2706 3939(additional)N +3046(functionality)X +3475(is)X +3548(provided:)X +10 f +2798 4071(g)N +1 f +2946(Inserts)X +3197(never)X +3413(fail)X +3556(because)X +3847(too)X +3985(many)X +4199(keys)X +2946 4159(hash)N +3113(to)X +3195(the)X +3313(same)X +3498(value.)X +10 f +2798 4247(g)N +1 f +2946(Inserts)X +3187(never)X +3393(fail)X +3527(because)X +3808(key)X +3950(and/or)X +4181(asso-)X +2946 4335(ciated)N +3158(data)X +3312(is)X +3385(too)X +3507(large)X +10 f +2798 4423(g)N +1 f +2946(Hash)X +3131(functions)X +3449(may)X +3607(be)X +3703(user-speci\256ed.)X +10 f +2798 4511(g)N +1 f +2946(Multiple)X +3268(pages)X +3498(may)X +3683(be)X +3806(cached)X +4077(in)X +4186(main)X +2946 4599(memory.)N +2706 4731(It)N +2801(also)X +2976(provides)X +3298(a)X +3380(set)X +3514(of)X +3626(compatibility)X +4097(routines)X +4400(to)X +2706 4819(implement)N +3087(the)X +2 f +3224(hsearch)X +1 f +3516(interface.)X +3876(Again,)X +4130(the)X +4266(native)X +2706 4907(interface)N +3008(offers)X +3216(enhanced)X +3540(functionality:)X +10 f +2798 5039(g)N +1 f +2946(Files)X +3121(may)X +3279(grow)X +3464(beyond)X +2 f +3720(nelem)X +1 f +3932(elements.)X +10 f +2798 5127(g)N +1 f +2946(Multiple)X +3247(hash)X +3420(tables)X +3632(may)X +3795(be)X +3896(accessed)X +4203(con-)X +2946 5215(currently.)N +10 f +2798 5303(g)N +1 f +2946(Hash)X +3134(tables)X +3344(may)X +3505(be)X +3604(stored)X +3823(and)X +3962(accessed)X +4266(on)X +2946 5391(disk.)N +10 f +2798 5479(g)N +1 f +2946(Hash)X +3155(functions)X +3497(may)X +3679(be)X +3799(user-speci\256ed)X +4288(at)X +2946 5567(runtime.)N +3 f +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +4424(9)X + +10 p +%%Page: 10 10 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +432 258(A)N +510(New)X +682(Hashing)X +985(Package)X +1290(for)X +1413(UNIX)X +3663(Seltzer)X +3920(&)X +4007(Yigit)X +459 538(Relative)N +760(Performance)X +1227(of)X +1314(the)X +1441(New)X +1613(Implementation)X +1 f +604 670(The)N +761(performance)X +1200(testing)X +1445(of)X +1544(the)X +1674(new)X +1840(package)X +2135(is)X +432 758(divided)N +711(into)X +874(two)X +1033(test)X +1183(suites.)X +1424(The)X +1588(\256rst)X +1751(suite)X +1941(of)X +2046(tests)X +432 846(requires)N +727(that)X +882(the)X +1015(tables)X +1237(be)X +1348(read)X +1522(from)X +1713(and)X +1864(written)X +2126(to)X +432 934(disk.)N +640(In)X +742(these)X +942(tests,)X +1139(the)X +1272(basis)X +1467(for)X +1595(comparison)X +2003(is)X +2090(the)X +432 1022(4.3BSD-Reno)N +908(version)X +1169(of)X +2 f +1260(ndbm)X +1 f +1438(.)X +1502(Based)X +1722(on)X +1826(the)X +1948(designs)X +432 1110(of)N +2 f +521(sdbm)X +1 f +712(and)X +2 f +850(gdbm)X +1 f +1028(,)X +1070(they)X +1230(are)X +1351(expected)X +1659(to)X +1743(perform)X +2024(simi-)X +432 1198(larly)N +605(to)X +2 f +693(ndbm)X +1 f +871(,)X +917(and)X +1059(we)X +1179(do)X +1285(not)X +1413(show)X +1608(their)X +1781(performance)X +432 1286(numbers.)N +800(The)X +977(second)X +1252(suite)X +1454(contains)X +1772(the)X +1921(memory)X +432 1374(resident)N +712(test)X +849(which)X +1071(does)X +1243(not)X +1370(require)X +1623(that)X +1768(the)X +1891(\256les)X +2049(ever)X +432 1462(be)N +533(written)X +784(to)X +870(disk,)X +1047(only)X +1213(that)X +1357(hash)X +1528(tables)X +1739(may)X +1901(be)X +2001(mani-)X +432 1550(pulated)N +692(in)X +778(main)X +961(memory.)X +1291(In)X +1381(this)X +1519(test,)X +1673(we)X +1790(compare)X +2090(the)X +432 1638(performance)N +859(to)X +941(that)X +1081(of)X +1168(the)X +2 f +1286(hsearch)X +1 f +1560(routines.)X +604 1752(For)N +760(both)X +947(suites,)X +1194(two)X +1358(different)X +1679(databases)X +2031(were)X +432 1840(used.)N +656(The)X +818(\256rst)X +979(is)X +1069(the)X +1204(dictionary)X +1566(database)X +1880(described)X +432 1928(previously.)N +836(The)X +987(second)X +1236(was)X +1386(constructed)X +1781(from)X +1962(a)X +2023(pass-)X +432 2016(word)N +647(\256le)X +799(with)X +990(approximately)X +1502(300)X +1671(accounts.)X +2041(Two)X +432 2104(records)N +700(were)X +887(constructed)X +1287(for)X +1411(each)X +1589(account.)X +1909(The)X +2064(\256rst)X +432 2192(used)N +604(the)X +727(logname)X +1028(as)X +1120(the)X +1243(key)X +1384(and)X +1525(the)X +1648(remainder)X +1999(of)X +2090(the)X +432 2280(password)N +768(entry)X +965(for)X +1091(the)X +1221(data.)X +1427(The)X +1584(second)X +1839(was)X +1996(keyed)X +432 2368(by)N +541(uid)X +672(and)X +817(contained)X +1157(the)X +1283(entire)X +1494(password)X +1825(entry)X +2018(as)X +2113(its)X +432 2456(data)N +589(\256eld.)X +794(The)X +942(tests)X +1107(were)X +1287(all)X +1389(run)X +1518(on)X +1620(the)X +1740(HP)X +1864(9000)X +2046(with)X +432 2544(the)N +574(same)X +783(con\256guration)X +1254(previously)X +1636(described.)X +2027(Each)X +432 2632(test)N +576(was)X +734(run)X +874(\256ve)X +1027(times)X +1232(and)X +1380(the)X +1510(timing)X +1750(results)X +1991(of)X +2090(the)X +432 2720(runs)N +602(were)X +791(averaged.)X +1154(The)X +1311(variance)X +1616(across)X +1849(the)X +1979(5)X +2050(runs)X +432 2808(was)N +591(approximately)X +1088(1%)X +1229(of)X +1330(the)X +1462(average)X +1746(yielding)X +2041(95%)X +432 2896(con\256dence)N +800(intervals)X +1096(of)X +1183(approximately)X +1666(2%.)X +3 f +1021 3050(Disk)N +1196(Based)X +1420(Tests)X +1 f +604 3182(In)N +693(these)X +880(tests,)X +1064(we)X +1180(use)X +1308(a)X +1365(bucket)X +1600(size)X +1746(of)X +1834(1024)X +2015(and)X +2152(a)X +432 3270(\256ll)N +540(factor)X +748(of)X +835(32.)X +3 f +432 3384(create)N +663(test)X +1 f +547 3498(The)N +703(keys)X +881(are)X +1011(entered)X +1279(into)X +1433(the)X +1561(hash)X +1738(table,)X +1944(and)X +2090(the)X +547 3586(\256le)N +669(is)X +742(\257ushed)X +993(to)X +1075(disk.)X +3 f +432 3700(read)N +608(test)X +1 f +547 3814(A)N +640(lookup)X +897(is)X +984(performed)X +1353(for)X +1481(each)X +1663(key)X +1813(in)X +1909(the)X +2041(hash)X +547 3902(table.)N +3 f +432 4016(verify)N +653(test)X +1 f +547 4130(A)N +640(lookup)X +897(is)X +984(performed)X +1353(for)X +1481(each)X +1663(key)X +1813(in)X +1909(the)X +2041(hash)X +547 4218(table,)N +759(and)X +911(the)X +1045(data)X +1215(returned)X +1519(is)X +1608(compared)X +1961(against)X +547 4306(that)N +687(originally)X +1018(stored)X +1234(in)X +1316(the)X +1434(hash)X +1601(table.)X +3 f +432 4420(sequential)N +798(retrieve)X +1 f +547 4534(All)N +674(keys)X +846(are)X +970(retrieved)X +1281(in)X +1367(sequential)X +1716(order)X +1910(from)X +2090(the)X +547 4622(hash)N +724(table.)X +950(The)X +2 f +1105(ndbm)X +1 f +1313(interface)X +1625(allows)X +1863(sequential)X +547 4710(retrieval)N +848(of)X +948(the)X +1079(keys)X +1259(from)X +1448(the)X +1578(database,)X +1907(but)X +2041(does)X +547 4798(not)N +701(return)X +945(the)X +1094(data)X +1279(associated)X +1660(with)X +1853(each)X +2052(key.)X +547 4886(Therefore,)N +929(we)X +1067(compare)X +1388(the)X +1530(performance)X +1980(of)X +2090(the)X +547 4974(new)N +703(package)X +989(to)X +1073(two)X +1215(different)X +1514(runs)X +1674(of)X +2 f +1763(ndbm)X +1 f +1941(.)X +2002(In)X +2090(the)X +547 5062(\256rst)N +697(case,)X +2 f +882(ndbm)X +1 f +1086(returns)X +1335(only)X +1503(the)X +1627(keys)X +1800(while)X +2003(in)X +2090(the)X +547 5150(second,)N +2 f +823(ndbm)X +1 f +1034(returns)X +1290(both)X +1465(the)X +1596(keys)X +1776(and)X +1924(the)X +2054(data)X +547 5238(\(requiring)N +894(a)X +956(second)X +1204(call)X +1345(to)X +1432(the)X +1555(library\).)X +1861(There)X +2074(is)X +2152(a)X +547 5326(single)N +764(run)X +897(for)X +1017(the)X +1141(new)X +1300(library)X +1539(since)X +1729(it)X +1798(returns)X +2046(both)X +547 5414(the)N +665(key)X +801(and)X +937(the)X +1055(data.)X +3 f +3014 538(In-Memory)N +3431(Test)X +1 f +2590 670(This)N +2757(test)X +2892(uses)X +3054(a)X +3114(bucket)X +3352(size)X +3501(of)X +3592(256)X +3736(and)X +3876(a)X +3936(\256ll)X +4048(fac-)X +2418 758(tor)N +2527(of)X +2614(8.)X +3 f +2418 872(create/read)N +2827(test)X +1 f +2533 986(In)N +2627(this)X +2769(test,)X +2927(a)X +2989(hash)X +3162(table)X +3344(is)X +3423(created)X +3682(by)X +3788(inserting)X +4094(all)X +2533 1074(the)N +2660(key/data)X +2961(pairs.)X +3186(Then)X +3380(a)X +3445(keyed)X +3666(retrieval)X +3963(is)X +4044(per-)X +2533 1162(formed)N +2801(for)X +2931(each)X +3115(pair,)X +3295(and)X +3446(the)X +3579(hash)X +3761(table)X +3952(is)X +4040(des-)X +2533 1250(troyed.)N +3 f +2938 1404(Performance)N +3405(Results)X +1 f +2590 1536(Figures)N +2866(8a)X +2978(and)X +3130(8b)X +3246(show)X +3451(the)X +3585(user)X +3755(time,)X +3952(system)X +2418 1624(time,)N +2608(and)X +2752(elapsed)X +3021(time)X +3191(for)X +3312(each)X +3487(test)X +3625(for)X +3746(both)X +3915(the)X +4040(new)X +2418 1712(implementation)N +2951(and)X +3098(the)X +3227(old)X +3360(implementation)X +3893(\()X +2 f +3920(hsearch)X +1 f +2418 1800(or)N +2 f +2528(ndbm)X +1 f +2706(,)X +2769(whichever)X +3147(is)X +3243(appropriate\))X +3678(as)X +3787(well)X +3967(as)X +4076(the)X +2418 1888(improvement.)N +2929(The)X +3098(improvement)X +3569(is)X +3666(expressed)X +4027(as)X +4138(a)X +2418 1976(percentage)N +2787(of)X +2874(the)X +2992(old)X +3114(running)X +3383(time:)X +0 f +8 s +2418 2275(%)N +2494(=)X +2570(100)X +2722(*)X +2798 -0.4219(\(old_time)AX +3178(-)X +3254 -0.4219(new_time\))AX +3634(/)X +3710(old_time)X +1 f +10 s +2590 2600(In)N +2700(nearly)X +2944(all)X +3067(cases,)X +3299(the)X +3439(new)X +3615(routines)X +3915(perform)X +2418 2688(better)N +2628(than)X +2793(the)X +2918(old)X +3047(routines)X +3332(\(both)X +2 f +3527(hsearch)X +1 f +3807(and)X +2 f +3949(ndbm)X +1 f +4127(\).)X +2418 2776(Although)N +2755(the)X +3 f +2888(create)X +1 f +3134(tests)X +3311(exhibit)X +3567(superior)X +3864(user)X +4032(time)X +2418 2864(performance,)N +2869(the)X +2991(test)X +3126(time)X +3292(is)X +3369(dominated)X +3731(by)X +3834(the)X +3955(cost)X +4107(of)X +2418 2952(writing)N +2677(the)X +2803(actual)X +3023(\256le)X +3153(to)X +3243(disk.)X +3444(For)X +3583(the)X +3709(large)X +3897(database)X +2418 3040(\(the)N +2564(dictionary\),)X +2957(this)X +3093(completely)X +3470(overwhelmed)X +3927(the)X +4045(sys-)X +2418 3128(tem)N +2570(time.)X +2783(However,)X +3129(for)X +3254(the)X +3383(small)X +3587(data)X +3752(base,)X +3946(we)X +4071(see)X +2418 3216(that)N +2569(differences)X +2958(in)X +3051(both)X +3224(user)X +3389(and)X +3536(system)X +3788(time)X +3960(contri-)X +2418 3304(bute)N +2576(to)X +2658(the)X +2776(superior)X +3059(performance)X +3486(of)X +3573(the)X +3691(new)X +3845(package.)X +2590 3418(The)N +3 f +2764(read)X +1 f +2920(,)X +3 f +2989(verify)X +1 f +3190(,)X +3259(and)X +3 f +3424(sequential)X +1 f +3818(results)X +4075(are)X +2418 3506(deceptive)N +2758(for)X +2883(the)X +3012(small)X +3216(database)X +3524(since)X +3720(the)X +3849(entire)X +4063(test)X +2418 3594(ran)N +2551(in)X +2643(under)X +2856(a)X +2922(second.)X +3215(However,)X +3560(on)X +3669(the)X +3796(larger)X +4013(data-)X +2418 3682(base)N +2590(the)X +3 f +2716(read)X +1 f +2900(and)X +3 f +3044(verify)X +1 f +3273(tests)X +3443(bene\256t)X +3689(from)X +3873(the)X +3999(cach-)X +2418 3770(ing)N +2546(of)X +2639(buckets)X +2910(in)X +2998(the)X +3122(new)X +3282(package)X +3571(to)X +3658(improve)X +3950(perfor-)X +2418 3858(mance)N +2666(by)X +2784(over)X +2965(80%.)X +3169(Since)X +3384(the)X +3519(\256rst)X +3 f +3680(sequential)X +1 f +4063(test)X +2418 3946(does)N +2598(not)X +2733(require)X +2 f +2994(ndbm)X +1 f +3205(to)X +3299(return)X +3523(the)X +3653(data)X +3819(values,)X +4076(the)X +2418 4034(user)N +2573(time)X +2735(is)X +2808(lower)X +3011(than)X +3169(for)X +3283(the)X +3401(new)X +3555(package.)X +3879(However)X +2418 4122(when)N +2613(we)X +2728(require)X +2977(both)X +3139(packages)X +3454(to)X +3536(return)X +3748(data,)X +3922(the)X +4040(new)X +2418 4210(package)N +2702(excels)X +2923(in)X +3005(all)X +3105(three)X +3286(timings.)X +2590 4324(The)N +2773(small)X +3003(database)X +3337(runs)X +3532(so)X +3660(quickly)X +3957(in)X +4076(the)X +2418 4412(memory-resident)N +3000(case)X +3173(that)X +3326(the)X +3457(results)X +3699(are)X +3831(uninterest-)X +2418 4500(ing.)N +2589(However,)X +2933(for)X +3056(the)X +3183(larger)X +3400(database)X +3706(the)X +3833(new)X +3995(pack-)X +2418 4588(age)N +2567(pays)X +2751(a)X +2824(small)X +3033(penalty)X +3305(in)X +3403(system)X +3661(time)X +3839(because)X +4130(it)X +2418 4676(limits)N +2636(its)X +2748(main)X +2944(memory)X +3247(utilization)X +3607(and)X +3759(swaps)X +3991(pages)X +2418 4764(out)N +2550(to)X +2642(temporary)X +3002(storage)X +3264(in)X +3356(the)X +3484(\256le)X +3616(system)X +3868(while)X +4076(the)X +2 f +2418 4852(hsearch)N +1 f +2698(package)X +2988(requires)X +3273(that)X +3419(the)X +3543(application)X +3924(allocate)X +2418 4940(enough)N +2692(space)X +2909(for)X +3041(all)X +3159(key/data)X +3468(pair.)X +3670(However,)X +4022(even)X +2418 5028(with)N +2600(the)X +2738(system)X +3000(time)X +3182(penalty,)X +3477(the)X +3614(resulting)X +3933(elapsed)X +2418 5116(time)N +2580(improves)X +2898(by)X +2998(over)X +3161(50%.)X +3 f +432 5960(10)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +11 p +%%Page: 11 11 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +720 258(Seltzer)N +977(&)X +1064(Yigit)X +3278(A)X +3356(New)X +3528(Hashing)X +3831(Package)X +4136(for)X +4259(UNIX)X +1 f +10 f +908 454(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2 f +1379 546(hash)N +1652(ndbm)X +1950(%change)X +1 f +10 f +908 550(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +948 642(CREATE)N +10 f +908 646(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +1125 738(user)N +1424(6.4)X +1671(12.2)X +2073(48)X +1157 826(sys)N +1384(32.5)X +1671(34.7)X +2113(6)X +3 f +1006 914(elapsed)N +10 f +1310 922(c)N +890(c)Y +810(c)Y +730(c)Y +3 f +1384 914(90.4)N +10 f +1581 922(c)N +890(c)Y +810(c)Y +730(c)Y +3 f +1671 914(99.6)N +10 f +1883 922(c)N +890(c)Y +810(c)Y +730(c)Y +3 f +2113 914(9)N +1 f +10 f +908 910(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +908 926(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +948 1010(READ)N +10 f +908 1014(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +1125 1106(user)N +1424(3.4)X +1711(6.1)X +2073(44)X +1157 1194(sys)N +1424(1.2)X +1671(15.3)X +2073(92)X +3 f +1006 1282(elapsed)N +10 f +1310 1290(c)N +1258(c)Y +1178(c)Y +1098(c)Y +3 f +1424 1282(4.0)N +10 f +1581 1290(c)N +1258(c)Y +1178(c)Y +1098(c)Y +3 f +1671 1282(21.2)N +10 f +1883 1290(c)N +1258(c)Y +1178(c)Y +1098(c)Y +3 f +2073 1282(81)N +1 f +10 f +908 1278(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +908 1294(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +948 1378(VERIFY)N +10 f +908 1382(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +1125 1474(user)N +1424(3.5)X +1711(6.3)X +2073(44)X +1157 1562(sys)N +1424(1.2)X +1671(15.3)X +2073(92)X +3 f +1006 1650(elapsed)N +10 f +1310 1658(c)N +1626(c)Y +1546(c)Y +1466(c)Y +3 f +1424 1650(4.0)N +10 f +1581 1658(c)N +1626(c)Y +1546(c)Y +1466(c)Y +3 f +1671 1650(21.2)N +10 f +1883 1658(c)N +1626(c)Y +1546(c)Y +1466(c)Y +3 f +2073 1650(81)N +1 f +10 f +908 1646(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +908 1662(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +948 1746(SEQUENTIAL)N +10 f +908 1750(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +1125 1842(user)N +1424(2.7)X +1711(1.9)X +2046(-42)X +1157 1930(sys)N +1424(0.7)X +1711(3.9)X +2073(82)X +3 f +1006 2018(elapsed)N +10 f +1310 2026(c)N +1994(c)Y +1914(c)Y +1834(c)Y +3 f +1424 2018(3.0)N +10 f +1581 2026(c)N +1994(c)Y +1914(c)Y +1834(c)Y +3 f +1711 2018(5.0)N +10 f +1883 2026(c)N +1994(c)Y +1914(c)Y +1834(c)Y +3 f +2073 2018(40)N +1 f +10 f +908 2014(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +908 2030(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +948 2114(SEQUENTIAL)N +1467(\(with)X +1656(data)X +1810(retrieval\))X +10 f +908 2118(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +1125 2210(user)N +1424(2.7)X +1711(8.2)X +2073(67)X +1157 2298(sys)N +1424(0.7)X +1711(4.3)X +2073(84)X +3 f +1006 2386(elapsed)N +1424(3.0)X +1671(12.0)X +2073(75)X +1 f +10 f +908 2390(i)N +927(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +899 2394(c)N +2378(c)Y +2298(c)Y +2218(c)Y +2138(c)Y +2058(c)Y +1978(c)Y +1898(c)Y +1818(c)Y +1738(c)Y +1658(c)Y +1578(c)Y +1498(c)Y +1418(c)Y +1338(c)Y +1258(c)Y +1178(c)Y +1098(c)Y +1018(c)Y +938(c)Y +858(c)Y +778(c)Y +698(c)Y +618(c)Y +538(c)Y +1310 2394(c)N +2362(c)Y +2282(c)Y +2202(c)Y +1581 2394(c)N +2362(c)Y +2282(c)Y +2202(c)Y +1883 2394(c)N +2362(c)Y +2282(c)Y +2202(c)Y +2278 2394(c)N +2378(c)Y +2298(c)Y +2218(c)Y +2138(c)Y +2058(c)Y +1978(c)Y +1898(c)Y +1818(c)Y +1738(c)Y +1658(c)Y +1578(c)Y +1498(c)Y +1418(c)Y +1338(c)Y +1258(c)Y +1178(c)Y +1098(c)Y +1018(c)Y +938(c)Y +858(c)Y +778(c)Y +698(c)Y +618(c)Y +538(c)Y +905 2574(i)N +930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2 f +1318 2666(hash)N +1585(hsearch)X +1953(%change)X +1 f +10 f +905 2670(i)N +930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +945 2762(CREATE/READ)N +10 f +905 2766(i)N +930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +1064 2858(user)N +1343(6.6)X +1642(17.2)X +2096(62)X +1096 2946(sys)N +1343(1.1)X +1682(0.3)X +2029(-266)X +3 f +945 3034(elapsed)N +1343(7.8)X +1642(17.0)X +2096(54)X +1 f +10 f +905 3038(i)N +930(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +896 3050(c)N +2978(c)Y +2898(c)Y +2818(c)Y +2738(c)Y +2658(c)Y +1249 3034(c)N +3010(c)Y +2930(c)Y +2850(c)Y +1520 3034(c)N +3010(c)Y +2930(c)Y +2850(c)Y +1886 3034(c)N +3010(c)Y +2930(c)Y +2850(c)Y +2281 3050(c)N +2978(c)Y +2898(c)Y +2818(c)Y +2738(c)Y +2658(c)Y +3 f +720 3174(Figure)N +967(8a:)X +1 f +1094(Timing)X +1349(results)X +1578(for)X +1692(the)X +1810(dictionary)X +2155(database.)X +10 f +720 3262 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +1407 3504(Conclusion)N +1 f +892 3636(This)N +1063(paper)X +1271(has)X +1407(presented)X +1744(the)X +1871(design,)X +2129(implemen-)X +720 3724(tation)N +928(and)X +1070(performance)X +1503(of)X +1596(a)X +1658(new)X +1818(hashing)X +2093(package)X +2382(for)X +720 3812(UNIX.)N +993(The)X +1150(new)X +1316(package)X +1612(provides)X +1919(a)X +1986(superset)X +2280(of)X +2378(the)X +720 3900(functionality)N +1159(of)X +1255(existing)X +1537(hashing)X +1815(packages)X +2139(and)X +2284(incor-)X +720 3988(porates)N +975(additional)X +1318(features)X +1596(such)X +1766(as)X +1855(large)X +2038(key)X +2176(handling,)X +720 4076(user)N +876(de\256ned)X +1134(hash)X +1302(functions,)X +1641(multiple)X +1928(hash)X +2096(tables,)X +2324(vari-)X +720 4164(able)N +894(sized)X +1099(pages,)X +1342(and)X +1498(linear)X +1721(hashing.)X +2050(In)X +2156(nearly)X +2396(all)X +720 4252(cases,)N +954(the)X +1096(new)X +1274(package)X +1582(provides)X +1902(improved)X +2252(perfor-)X +720 4340(mance)N +974(on)X +1098(the)X +1240(order)X +1454(of)X +1565(50-80%)X +1863(for)X +2001(the)X +2142(workloads)X +720 4428(shown.)N +990(Applications)X +1420(such)X +1588(as)X +1676(the)X +1794(loader,)X +2035(compiler,)X +2360(and)X +720 4516(mail,)N +921(which)X +1156(currently)X +1485(implement)X +1866(their)X +2051(own)X +2227(hashing)X +720 4604(routines,)N +1032(should)X +1279(be)X +1389(modi\256ed)X +1706(to)X +1801(use)X +1941(the)X +2072(generic)X +2342(rou-)X +720 4692(tines.)N +892 4806(This)N +1087(hashing)X +1389(package)X +1705(is)X +1810(one)X +1978(access)X +2236(method)X +720 4894(which)N +953(is)X +1043(part)X +1205(of)X +1309(a)X +1382(generic)X +1656(database)X +1970(access)X +2212(package)X +720 4982(being)N +955(developed)X +1342(at)X +1457(the)X +1612(University)X +2007(of)X +2131(California,)X +720 5070(Berkeley.)N +1089(It)X +1177(will)X +1340(include)X +1614(a)X +1688(btree)X +1887(access)X +2131(method)X +2409(as)X +720 5158(well)N +916(as)X +1041(\256xed)X +1259(and)X +1433(variable)X +1750(length)X +2007(record)X +2270(access)X +720 5246(methods)N +1024(in)X +1119(addition)X +1414(to)X +1509(the)X +1640(hashed)X +1896(support)X +2168(presented)X +720 5334(here.)N +948(All)X +1099(of)X +1215(the)X +1361(access)X +1615(methods)X +1934(are)X +2081(based)X +2312(on)X +2440(a)X +720 5422(key/data)N +1037(pair)X +1207(interface)X +1533(and)X +1693(appear)X +1952(identical)X +2272(to)X +2378(the)X +720 5510(application)N +1121(layer,)X +1347(allowing)X +1671(application)X +2071(implementa-)X +720 5598(tions)N +906(to)X +999(be)X +1106(largely)X +1360(independent)X +1783(of)X +1881(the)X +2010(database)X +2318(type.)X +720 5686(The)N +873(package)X +1165(is)X +1246(expected)X +1560(to)X +1650(be)X +1754(an)X +1858(integral)X +2131(part)X +2284(of)X +2378(the)X +2706 538(4.4BSD)N +3006(system,)X +3293(with)X +3479(various)X +3759(standard)X +4075(applications)X +2706 626(such)N +2879(as)X +2972(more\(1\),)X +3277(sort\(1\))X +3517(and)X +3659(vi\(1\))X +3841(based)X +4050(on)X +4156(it.)X +4266(While)X +2706 714(the)N +2833(current)X +3089(design)X +3326(does)X +3501(not)X +3631(support)X +3899(multi-user)X +4256(access)X +2706 802(or)N +2804(transactions,)X +3238(they)X +3407(could)X +3616(be)X +3723(incorporated)X +4159(relatively)X +2706 890(easily.)N +10 f +2894 938(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2 f +3365 1030(hash)N +3638(ndbm)X +3936(%change)X +1 f +10 f +2894 1034(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2934 1126(CREATE)N +10 f +2894 1130(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +3111 1222(user)N +3390(0.2)X +3677(0.4)X +4079(50)X +3143 1310(sys)N +3390(0.1)X +3677(1.0)X +4079(90)X +3 f +2992 1398(elapsed)N +10 f +3296 1406(c)N +1374(c)Y +1294(c)Y +1214(c)Y +3 f +3390 1398(0)N +10 f +3567 1406(c)N +1374(c)Y +1294(c)Y +1214(c)Y +3 f +3677 1398(3.2)N +10 f +3869 1406(c)N +1374(c)Y +1294(c)Y +1214(c)Y +3 f +4039 1398(100)N +1 f +10 f +2894 1394(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2894 1410(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2934 1494(READ)N +10 f +2894 1498(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +3111 1590(user)N +3390(0.1)X +3677(0.1)X +4119(0)X +3143 1678(sys)N +3390(0.1)X +3677(0.4)X +4079(75)X +3 f +2992 1766(elapsed)N +10 f +3296 1774(c)N +1742(c)Y +1662(c)Y +1582(c)Y +3 f +3390 1766(0.0)N +10 f +3567 1774(c)N +1742(c)Y +1662(c)Y +1582(c)Y +3 f +3677 1766(0.0)N +10 f +3869 1774(c)N +1742(c)Y +1662(c)Y +1582(c)Y +3 f +4119 1766(0)N +1 f +10 f +2894 1762(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2894 1778(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2934 1862(VERIFY)N +10 f +2894 1866(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +3111 1958(user)N +3390(0.1)X +3677(0.2)X +4079(50)X +3143 2046(sys)N +3390(0.1)X +3677(0.3)X +4079(67)X +3 f +2992 2134(elapsed)N +10 f +3296 2142(c)N +2110(c)Y +2030(c)Y +1950(c)Y +3 f +3390 2134(0.0)N +10 f +3567 2142(c)N +2110(c)Y +2030(c)Y +1950(c)Y +3 f +3677 2134(0.0)N +10 f +3869 2142(c)N +2110(c)Y +2030(c)Y +1950(c)Y +3 f +4119 2134(0)N +1 f +10 f +2894 2130(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2894 2146(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2934 2230(SEQUENTIAL)N +10 f +2894 2234(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +3111 2326(user)N +3390(0.1)X +3677(0.0)X +4012(-100)X +3143 2414(sys)N +3390(0.1)X +3677(0.1)X +4119(0)X +3 f +2992 2502(elapsed)N +10 f +3296 2510(c)N +2478(c)Y +2398(c)Y +2318(c)Y +3 f +3390 2502(0.0)N +10 f +3567 2510(c)N +2478(c)Y +2398(c)Y +2318(c)Y +3 f +3677 2502(0.0)N +10 f +3869 2510(c)N +2478(c)Y +2398(c)Y +2318(c)Y +3 f +4119 2502(0)N +1 f +10 f +2894 2498(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2894 2514(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2934 2598(SEQUENTIAL)N +3453(\(with)X +3642(data)X +3796(retrieval\))X +10 f +2894 2602(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +3111 2694(user)N +3390(0.1)X +3677(0.1)X +4119(0)X +3143 2782(sys)N +3390(0.1)X +3677(0.1)X +4119(0)X +3 f +2992 2870(elapsed)N +3390(0.0)X +3677(0.0)X +4119(0)X +1 f +10 f +2894 2874(i)N +2913(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2885 2878(c)N +2862(c)Y +2782(c)Y +2702(c)Y +2622(c)Y +2542(c)Y +2462(c)Y +2382(c)Y +2302(c)Y +2222(c)Y +2142(c)Y +2062(c)Y +1982(c)Y +1902(c)Y +1822(c)Y +1742(c)Y +1662(c)Y +1582(c)Y +1502(c)Y +1422(c)Y +1342(c)Y +1262(c)Y +1182(c)Y +1102(c)Y +1022(c)Y +3296 2878(c)N +2846(c)Y +2766(c)Y +2686(c)Y +3567 2878(c)N +2846(c)Y +2766(c)Y +2686(c)Y +3869 2878(c)N +2846(c)Y +2766(c)Y +2686(c)Y +4264 2878(c)N +2862(c)Y +2782(c)Y +2702(c)Y +2622(c)Y +2542(c)Y +2462(c)Y +2382(c)Y +2302(c)Y +2222(c)Y +2142(c)Y +2062(c)Y +1982(c)Y +1902(c)Y +1822(c)Y +1742(c)Y +1662(c)Y +1582(c)Y +1502(c)Y +1422(c)Y +1342(c)Y +1262(c)Y +1182(c)Y +1102(c)Y +1022(c)Y +2891 3058(i)N +2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2 f +3304 3150(hash)N +3571(hsearch)X +3939(%change)X +1 f +10 f +2891 3154(i)N +2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2931 3246(CREATE/READ)N +10 f +2891 3250(i)N +2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +3050 3342(user)N +3329(0.3)X +3648(0.4)X +4048(25)X +3082 3430(sys)N +3329(0.0)X +3648(0.0)X +4088(0)X +3 f +2931 3518(elapsed)N +3329(0.0)X +3648(0.0)X +4088(0)X +1 f +10 f +2891 3522(i)N +2916(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2882 3534(c)N +3462(c)Y +3382(c)Y +3302(c)Y +3222(c)Y +3142(c)Y +3235 3518(c)N +3494(c)Y +3414(c)Y +3334(c)Y +3506 3518(c)N +3494(c)Y +3414(c)Y +3334(c)Y +3872 3518(c)N +3494(c)Y +3414(c)Y +3334(c)Y +4267 3534(c)N +3462(c)Y +3382(c)Y +3302(c)Y +3222(c)Y +3142(c)Y +3 f +2706 3658(Figure)N +2953(8b:)X +1 f +3084(Timing)X +3339(results)X +3568(for)X +3682(the)X +3800(password)X +4123(database.)X +10 f +2706 3746 -0.0930(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)AN +3 f +3396 3988(References)N +1 f +2706 4120([ATT79])N +3058(AT&T,)X +3358(DBM\(3X\),)X +2 f +3773(Unix)X +3990(Programmer's)X +2878 4208(Manual,)N +3194(Seventh)X +3491(Edition,)X +3793(Volume)X +4085(1)X +1 f +(,)S +4192(January,)X +2878 4296(1979.)N +2706 4472([ATT85])N +3027(AT&T,)X +3296(HSEARCH\(BA_LIB\),)X +2 f +4053(Unix)X +4239(System)X +2878 4560(User's)N +3112(Manual,)X +3401(System)X +3644(V.3)X +1 f +3753(,)X +3793(pp.)X +3913(506-508,)X +4220(1985.)X +2706 4736([BRE73])N +3025(Brent,)X +3253(Richard)X +3537(P.,)X +3651(``Reducing)X +4041(the)X +4168(Retrieval)X +2878 4824(Time)N +3071(of)X +3162(Scatter)X +3409(Storage)X +3678(Techniques'',)X +2 f +4146(Commun-)X +2878 4912(ications)N +3175(of)X +3281(the)X +3422(ACM)X +1 f +3591(,)X +3654(Volume)X +3955(16,)X +4098(No.)X +4259(2,)X +4362(pp.)X +2878 5000(105-109,)N +3185(February,)X +3515(1973.)X +2706 5176([BSD86])N +3055(NDBM\(3\),)X +2 f +3469(4.3BSD)X +3775(Unix)X +3990(Programmer's)X +2878 5264(Manual)N +3155(Reference)X +3505(Guide)X +1 f +3701(,)X +3749(University)X +4114(of)X +4208(Califor-)X +2878 5352(nia,)N +3016(Berkeley,)X +3346(1986.)X +2706 5528([ENB88])N +3025(Enbody,)X +3319(R.)X +3417(J.,)X +3533(Du,)X +3676(H.)X +3779(C.,)X +3897(``Dynamic)X +4270(Hash-)X +2878 5616(ing)N +3034(Schemes'',)X +2 f +3427(ACM)X +3630(Computing)X +4019(Surveys)X +1 f +4269(,)X +4322(Vol.)X +2878 5704(20,)N +2998(No.)X +3136(2,)X +3216(pp.)X +3336(85-113,)X +3603(June)X +3770(1988.)X +3 f +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +4384(11)X + +12 p +%%Page: 12 12 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +432 258(A)N +510(New)X +682(Hashing)X +985(Package)X +1290(for)X +1413(UNIX)X +3663(Seltzer)X +3920(&)X +4007(Yigit)X +1 f +432 538([FAG79])N +776(Ronald)X +1057(Fagin,)X +1308(Jurg)X +1495(Nievergelt,)X +1903(Nicholas)X +604 626(Pippenger,)N +1003(H.)X +1135(Raymond)X +1500(Strong,)X +1787(``Extendible)X +604 714(Hashing)N +901(--)X +985(A)X +1073(Fast)X +1236(Access)X +1493(Method)X +1771(for)X +1894(Dynamic)X +604 802(Files'',)N +2 f +855(ACM)X +1046(Transactions)X +1485(on)X +1586(Database)X +1914(Systems)X +1 f +2168(,)X +604 890(Volume)N +882(4,)X +962(No.)X +1100(3.,)X +1200(September)X +1563(1979,)X +1763(pp)X +1863(315-34)X +432 1066([KNU68],)N +802(Knuth,)X +1064(D.E.,)X +2 f +1273(The)X +1434(Art)X +1577(of)X +1680(Computer)X +2041(Pro-)X +604 1154(gramming)N +971(Vol.)X +1140(3:)X +1245(Sorting)X +1518(and)X +1676(Searching)X +1 f +2001(,)X +2058(sec-)X +604 1242(tions)N +779(6.3-6.4,)X +1046(pp)X +1146(481-550.)X +432 1418([LAR78])N +747(Larson,)X +1011(Per-Ake,)X +1319(``Dynamic)X +1687(Hashing'',)X +2 f +2048(BIT)X +1 f +(,)S +604 1506(Vol.)N +764(18,)X +884(1978,)X +1084(pp.)X +1204(184-201.)X +432 1682([LAR88])N +752(Larson,)X +1021(Per-Ake,)X +1335(``Dynamic)X +1709(Hash)X +1900(Tables'',)X +2 f +604 1770(Communications)N +1183(of)X +1281(the)X +1415(ACM)X +1 f +1584(,)X +1640(Volume)X +1934(31,)X +2070(No.)X +604 1858(4.,)N +704(April)X +893(1988,)X +1093(pp)X +1193(446-457.)X +432 2034([LIT80])N +731(Witold,)X +1013(Litwin,)X +1286(``Linear)X +1590(Hashing:)X +1939(A)X +2036(New)X +604 2122(Tool)N +786(for)X +911(File)X +1065(and)X +1211(Table)X +1424(Addressing'',)X +2 f +1893(Proceed-)X +604 2210(ings)N +761(of)X +847(the)X +969(6th)X +1095(International)X +1540(Conference)X +1933(on)X +2036(Very)X +604 2298(Large)N +815(Databases)X +1 f +1153(,)X +1193(1980.)X +432 2474([NEL90])N +743(Nelson,)X +1011(Philip)X +1222(A.,)X +2 f +1341(Gdbm)X +1558(1.4)X +1679(source)X +1913(distribu-)X +604 2562(tion)N +748(and)X +888(README)X +1 f +1209(,)X +1249(August)X +1500(1990.)X +432 2738([THOM90])N +840(Ken)X +1011(Thompson,)X +1410(private)X +1670(communication,)X +604 2826(Nov.)N +782(1990.)X +432 3002([TOR87])N +790(Torek,)X +1066(C.,)X +1222(``Re:)X +1470(dbm.a)X +1751(and)X +1950(ndbm.a)X +604 3090(archives'',)N +2 f +966(USENET)X +1279(newsgroup)X +1650(comp.unix)X +1 f +2002(1987.)X +432 3266([TOR88])N +760(Torek,)X +1006(C.,)X +1133(``Re:)X +1351(questions)X +1686(regarding)X +2027(data-)X +604 3354(bases)N +826(created)X +1106(with)X +1295(dbm)X +1484(and)X +1647(ndbm)X +1876(routines'')X +2 f +604 3442(USENET)N +937(newsgroup)X +1328(comp.unix.questions)X +1 f +1982(,)X +2041(June)X +604 3530(1988.)N +432 3706([WAL84])N +773(Wales,)X +1018(R.,)X +1135(``Discussion)X +1564(of)X +1655("dbm")X +1887(data)X +2045(base)X +604 3794(system'',)N +2 f +973(USENET)X +1339(newsgroup)X +1762(unix.wizards)X +1 f +2168(,)X +604 3882(January,)N +894(1984.)X +432 4058([YIG89])N +751(Ozan)X +963(S.)X +1069(Yigit,)X +1294(``How)X +1545(to)X +1648(Roll)X +1826(Your)X +2032(Own)X +604 4146(Dbm/Ndbm'',)N +2 f +1087(unpublished)X +1504(manuscript)X +1 f +(,)S +1910(Toronto,)X +604 4234(July,)N +777(1989)X +3 f +432 5960(12)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +13 p +%%Page: 13 13 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +720 258(Seltzer)N +977(&)X +1064(Yigit)X +3278(A)X +3356(New)X +3528(Hashing)X +3831(Package)X +4136(for)X +4259(UNIX)X +1 f +720 538(Margo)N +960(I.)X +1033(Seltzer)X +1282(is)X +1361(a)X +1423(Ph.D.)X +1631(student)X +1887(in)X +1974(the)X +2097(Department)X +720 626(of)N +823(Electrical)X +1167(Engineering)X +1595(and)X +1747(Computer)X +2102(Sciences)X +2418(at)X +720 714(the)N +850(University)X +1220(of)X +1318(California,)X +1694(Berkeley.)X +2055(Her)X +2207(research)X +720 802(interests)N +1017(include)X +1283(\256le)X +1415(systems,)X +1718(databases,)X +2076(and)X +2221(transac-)X +720 890(tion)N +896(processing)X +1291(systems.)X +1636(She)X +1807(spent)X +2027(several)X +2306(years)X +720 978(working)N +1026(at)X +1123(startup)X +1380(companies)X +1762(designing)X +2112(and)X +2267(imple-)X +720 1066(menting)N +1048(\256le)X +1216(systems)X +1535(and)X +1716(transaction)X +2133(processing)X +720 1154(software)N +1026(and)X +1170(designing)X +1509(microprocessors.)X +2103(Ms.)X +2253(Seltzer)X +720 1242(received)N +1057(her)X +1223(AB)X +1397(in)X +1522(Applied)X +1843(Mathematics)X +2320(from)X +720 1330 0.1953(Harvard/Radcliffe)AN +1325(College)X +1594(in)X +1676(1983.)X +720 1444(In)N +810(her)X +936(spare)X +1129(time,)X +1313(Margo)X +1549(can)X +1683(usually)X +1936(be)X +2034(found)X +2243(prepar-)X +720 1532(ing)N +868(massive)X +1171(quantities)X +1527(of)X +1639(food)X +1831(for)X +1970(hungry)X +2242(hoards,)X +720 1620(studying)N +1022(Japanese,)X +1355(or)X +1449(playing)X +1716(soccer)X +1948(with)X +2116(an)X +2218(exciting)X +720 1708(Bay)N +912(Area)X +1132(Women's)X +1507(Soccer)X +1788(team,)X +2026(the)X +2186(Berkeley)X +720 1796(Bruisers.)N +720 1910(Ozan)N +915(\()X +3 f +942(Oz)X +1 f +1040(\))X +1092(Yigit)X +1281(is)X +1358(currently)X +1672(a)X +1732(software)X +2033(engineer)X +2334(with)X +720 1998(the)N +886(Communications)X +1499(Research)X +1861(and)X +2044(Development)X +720 2086(group,)N +948(Computing)X +1328(Services,)X +1641(York)X +1826(University.)X +2224(His)X +2355(for-)X +720 2174(mative)N +967(years)X +1166(were)X +1352(also)X +1510(spent)X +1708(at)X +1795(York,)X +2009(where)X +2234(he)X +2338(held)X +720 2262(system)N +985(programmer)X +1425(and)X +1583(administrator)X +2052(positions)X +2382(for)X +720 2350(various)N +995(mixtures)X +1314(of)X +1420(of)X +1526(UNIX)X +1765(systems)X +2056(starting)X +2334(with)X +720 2438(Berkeley)N +1031(4.1)X +1151(in)X +1233(1982,)X +1433(while)X +1631(at)X +1709(the)X +1827(same)X +2012(time)X +2174(obtaining)X +720 2526(a)N +776(degree)X +1011(in)X +1093(Computer)X +1433(Science.)X +720 2640(In)N +813(his)X +931(copious)X +1205(free)X +1356(time,)X +1543(Oz)X +1662(enjoys)X +1896(working)X +2188(on)X +2293(what-)X +720 2728(ever)N +890(software)X +1197(looks)X +1400(interesting,)X +1788(which)X +2014(often)X +2209(includes)X +720 2816(language)N +1044(interpreters,)X +1464(preprocessors,)X +1960(and)X +2110(lately,)X +2342(pro-)X +720 2904(gram)N +905(generators)X +1260(and)X +1396(expert)X +1617(systems.)X +720 3018(Oz)N +836(has)X +964(authored)X +1266(several)X +1515(public-domain)X +2003(software)X +2301(tools,)X +720 3106(including)N +1069(an)X +1191(nroff-like)X +1545(text)X +1711(formatter)X +2 f +2056(proff)X +1 f +2257(that)X +2423(is)X +720 3194(apparently)N +1083(still)X +1226(used)X +1397(in)X +1483(some)X +1676(basement)X +2002(PCs.)X +2173(His)X +2307(latest)X +720 3282(obsessions)N +1143(include)X +1460(the)X +1639(incredible)X +2040(programming)X +720 3370(language)N +1030(Scheme,)X +1324(and)X +1460(Chinese)X +1738(Brush)X +1949(painting.)X +3 f +720 5960(USENIX)N +9 f +1042(-)X +3 f +1106(Winter)X +1371('91)X +9 f +1498(-)X +3 f +1562(Dallas,)X +1815(TX)X +4384(13)X + +14 p +%%Page: 14 14 +0(Courier)xf 0 f +10 s 10 xH 0 xS 0 f +3 f +432 5960(14)N +2970(USENIX)X +9 f +3292(-)X +3 f +3356(Winter)X +3621('91)X +9 f +3748(-)X +3 f +3812(Dallas,)X +4065(TX)X + +14 p +%%Trailer +xt + +xs diff --git a/lib/libc/db/docs/libtp.usenix.ps b/lib/libc/db/docs/libtp.usenix.ps new file mode 100644 index 0000000..2e9017d --- /dev/null +++ b/lib/libc/db/docs/libtp.usenix.ps @@ -0,0 +1,12340 @@ +%!PS-Adobe-1.0 +%%Creator: utopia:margo (& Seltzer,608-13E,8072,) +%%Title: stdin (ditroff) +%%CreationDate: Thu Dec 12 15:32:11 1991 +%%EndComments +% @(#)psdit.pro 1.3 4/15/88 +% lib/psdit.pro -- prolog for psdit (ditroff) files +% Copyright (c) 1984, 1985 Adobe Systems Incorporated. All Rights Reserved. +% last edit: shore Sat Nov 23 20:28:03 1985 +% RCSID: $FreeBSD: releng/11.1/lib/libc/db/docs/libtp.usenix.ps 50488 1999-08-28 05:11:36Z peter $ + +% Changed by Edward Wang (edward@ucbarpa.berkeley.edu) to handle graphics, +% 17 Feb, 87. + +/$DITroff 140 dict def $DITroff begin +/fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def +/xi{0 72 11 mul translate 72 resolution div dup neg scale 0 0 moveto + /fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def F + /pagesave save def}def +/PB{save /psv exch def currentpoint translate + resolution 72 div dup neg scale 0 0 moveto}def +/PE{psv restore}def +/arctoobig 90 def /arctoosmall .05 def +/m1 matrix def /m2 matrix def /m3 matrix def /oldmat matrix def +/tan{dup sin exch cos div}def +/point{resolution 72 div mul}def +/dround {transform round exch round exch itransform}def +/xT{/devname exch def}def +/xr{/mh exch def /my exch def /resolution exch def}def +/xp{}def +/xs{docsave restore end}def +/xt{}def +/xf{/fontname exch def /slotno exch def fontnames slotno get fontname eq not + {fonts slotno fontname findfont put fontnames slotno fontname put}if}def +/xH{/fontheight exch def F}def +/xS{/fontslant exch def F}def +/s{/fontsize exch def /fontheight fontsize def F}def +/f{/fontnum exch def F}def +/F{fontheight 0 le{/fontheight fontsize def}if + fonts fontnum get fontsize point 0 0 fontheight point neg 0 0 m1 astore + fontslant 0 ne{1 0 fontslant tan 1 0 0 m2 astore m3 concatmatrix}if + makefont setfont .04 fontsize point mul 0 dround pop setlinewidth}def +/X{exch currentpoint exch pop moveto show}def +/N{3 1 roll moveto show}def +/Y{exch currentpoint pop exch moveto show}def +/S{show}def +/ditpush{}def/ditpop{}def +/AX{3 -1 roll currentpoint exch pop moveto 0 exch ashow}def +/AN{4 2 roll moveto 0 exch ashow}def +/AY{3 -1 roll currentpoint pop exch moveto 0 exch ashow}def +/AS{0 exch ashow}def +/MX{currentpoint exch pop moveto}def +/MY{currentpoint pop exch moveto}def +/MXY{moveto}def +/cb{pop}def % action on unknown char -- nothing for now +/n{}def/w{}def +/p{pop showpage pagesave restore /pagesave save def}def +/Dt{/Dlinewidth exch def}def 1 Dt +/Ds{/Ddash exch def}def -1 Ds +/Di{/Dstipple exch def}def 1 Di +/Dsetlinewidth{2 Dlinewidth mul setlinewidth}def +/Dsetdash{Ddash 4 eq{[8 12]}{Ddash 16 eq{[32 36]} + {Ddash 20 eq{[32 12 8 12]}{[]}ifelse}ifelse}ifelse 0 setdash}def +/Dstroke{gsave Dsetlinewidth Dsetdash 1 setlinecap stroke grestore + currentpoint newpath moveto}def +/Dl{rlineto Dstroke}def +/arcellipse{/diamv exch def /diamh exch def oldmat currentmatrix pop + currentpoint translate 1 diamv diamh div scale /rad diamh 2 div def + currentpoint exch rad add exch rad -180 180 arc oldmat setmatrix}def +/Dc{dup arcellipse Dstroke}def +/De{arcellipse Dstroke}def +/Da{/endv exch def /endh exch def /centerv exch def /centerh exch def + /cradius centerv centerv mul centerh centerh mul add sqrt def + /eradius endv endv mul endh endh mul add sqrt def + /endang endv endh atan def + /startang centerv neg centerh neg atan def + /sweep startang endang sub dup 0 lt{360 add}if def + sweep arctoobig gt + {/midang startang sweep 2 div sub def /midrad cradius eradius add 2 div def + /midh midang cos midrad mul def /midv midang sin midrad mul def + midh neg midv neg endh endv centerh centerv midh midv Da + Da} + {sweep arctoosmall ge + {/controldelt 1 sweep 2 div cos sub 3 sweep 2 div sin mul div 4 mul def + centerv neg controldelt mul centerh controldelt mul + endv neg controldelt mul centerh add endh add + endh controldelt mul centerv add endv add + centerh endh add centerv endv add rcurveto Dstroke} + {centerh endh add centerv endv add rlineto Dstroke} + ifelse} + ifelse}def +/Dpatterns[ +[%cf[widthbits] +[8<0000000000000010>] +[8<0411040040114000>] +[8<0204081020408001>] +[8<0000103810000000>] +[8<6699996666999966>] +[8<0000800100001008>] +[8<81c36666c3810000>] +[8<0f0e0c0800000000>] +[8<0000000000000010>] +[8<0411040040114000>] +[8<0204081020408001>] +[8<0000001038100000>] +[8<6699996666999966>] +[8<0000800100001008>] +[8<81c36666c3810000>] +[8<0f0e0c0800000000>] +[8<0042660000246600>] +[8<0000990000990000>] +[8<0804020180402010>] +[8<2418814242811824>] +[8<6699996666999966>] +[8<8000000008000000>] +[8<00001c3e363e1c00>] +[8<0000000000000000>] +[32<00000040000000c00000004000000040000000e0000000000000000000000000>] +[32<00000000000060000000900000002000000040000000f0000000000000000000>] +[32<000000000000000000e0000000100000006000000010000000e0000000000000>] +[32<00000000000000002000000060000000a0000000f00000002000000000000000>] +[32<0000000e0000000000000000000000000000000f000000080000000e00000001>] +[32<0000090000000600000000000000000000000000000007000000080000000e00>] +[32<00010000000200000004000000040000000000000000000000000000000f0000>] +[32<0900000006000000090000000600000000000000000000000000000006000000>]] +[%ug +[8<0000020000000000>] +[8<0000020000002000>] +[8<0004020000002000>] +[8<0004020000402000>] +[8<0004060000402000>] +[8<0004060000406000>] +[8<0006060000406000>] +[8<0006060000606000>] +[8<00060e0000606000>] +[8<00060e000060e000>] +[8<00070e000060e000>] +[8<00070e000070e000>] +[8<00070e020070e000>] +[8<00070e020070e020>] +[8<04070e020070e020>] +[8<04070e024070e020>] +[8<04070e064070e020>] +[8<04070e064070e060>] +[8<06070e064070e060>] +[8<06070e066070e060>] +[8<06070f066070e060>] +[8<06070f066070f060>] +[8<060f0f066070f060>] +[8<060f0f0660f0f060>] +[8<060f0f0760f0f060>] +[8<060f0f0760f0f070>] +[8<0e0f0f0760f0f070>] +[8<0e0f0f07e0f0f070>] +[8<0e0f0f0fe0f0f070>] +[8<0e0f0f0fe0f0f0f0>] +[8<0f0f0f0fe0f0f0f0>] +[8<0f0f0f0ff0f0f0f0>] +[8<1f0f0f0ff0f0f0f0>] +[8<1f0f0f0ff1f0f0f0>] +[8<1f0f0f8ff1f0f0f0>] +[8<1f0f0f8ff1f0f0f8>] +[8<9f0f0f8ff1f0f0f8>] +[8<9f0f0f8ff9f0f0f8>] +[8<9f0f0f9ff9f0f0f8>] +[8<9f0f0f9ff9f0f0f9>] +[8<9f8f0f9ff9f0f0f9>] +[8<9f8f0f9ff9f8f0f9>] +[8<9f8f1f9ff9f8f0f9>] +[8<9f8f1f9ff9f8f1f9>] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8] +[8]] +[%mg +[8<8000000000000000>] +[8<0822080080228000>] +[8<0204081020408001>] +[8<40e0400000000000>] +[8<66999966>] +[8<8001000010080000>] +[8<81c36666c3810000>] +[8] +[16<07c00f801f003e007c00f800f001e003c007800f001f003e007c00f801f003e0>] +[16<1f000f8007c003e001f000f8007c003e001f800fc007e003f001f8007c003e00>] +[8] +[16<0040008001000200040008001000200040008000000100020004000800100020>] +[16<0040002000100008000400020001800040002000100008000400020001000080>] +[16<1fc03fe07df0f8f8f07de03fc01f800fc01fe03ff07df8f87df03fe01fc00f80>] +[8<80>] +[8<8040201000000000>] +[8<84cc000048cc0000>] +[8<9900009900000000>] +[8<08040201804020100800020180002010>] +[8<2418814242811824>] +[8<66999966>] +[8<8000000008000000>] +[8<70f8d8f870000000>] +[8<0814224180402010>] +[8] +[8<018245aa45820100>] +[8<221c224180808041>] +[8<88000000>] +[8<0855800080550800>] +[8<2844004482440044>] +[8<0810204080412214>] +[8<00>]]]def +/Dfill{ + transform /maxy exch def /maxx exch def + transform /miny exch def /minx exch def + minx maxx gt{/minx maxx /maxx minx def def}if + miny maxy gt{/miny maxy /maxy miny def def}if + Dpatterns Dstipple 1 sub get exch 1 sub get + aload pop /stip exch def /stipw exch def /stiph 128 def + /imatrix[stipw 0 0 stiph 0 0]def + /tmatrix[stipw 0 0 stiph 0 0]def + /minx minx cvi stiph idiv stiph mul def + /miny miny cvi stipw idiv stipw mul def + gsave eoclip 0 setgray + miny stiph maxy{ + tmatrix exch 5 exch put + minx stipw maxx{ + tmatrix exch 4 exch put tmatrix setmatrix + stipw stiph true imatrix {stip} imagemask + }for + }for + grestore +}def +/Dp{Dfill Dstroke}def +/DP{Dfill currentpoint newpath moveto}def +end + +/ditstart{$DITroff begin + /nfonts 60 def % NFONTS makedev/ditroff dependent! + /fonts[nfonts{0}repeat]def + /fontnames[nfonts{()}repeat]def +/docsave save def +}def + +% character outcalls +/oc{ + /pswid exch def /cc exch def /name exch def + /ditwid pswid fontsize mul resolution mul 72000 div def + /ditsiz fontsize resolution mul 72 div def + ocprocs name known{ocprocs name get exec}{name cb}ifelse +}def +/fractm [.65 0 0 .6 0 0] def +/fraction{ + /fden exch def /fnum exch def gsave /cf currentfont def + cf fractm makefont setfont 0 .3 dm 2 copy neg rmoveto + fnum show rmoveto currentfont cf setfont(\244)show setfont fden show + grestore ditwid 0 rmoveto +}def +/oce{grestore ditwid 0 rmoveto}def +/dm{ditsiz mul}def +/ocprocs 50 dict def ocprocs begin +(14){(1)(4)fraction}def +(12){(1)(2)fraction}def +(34){(3)(4)fraction}def +(13){(1)(3)fraction}def +(23){(2)(3)fraction}def +(18){(1)(8)fraction}def +(38){(3)(8)fraction}def +(58){(5)(8)fraction}def +(78){(7)(8)fraction}def +(sr){gsave 0 .06 dm rmoveto(\326)show oce}def +(is){gsave 0 .15 dm rmoveto(\362)show oce}def +(->){gsave 0 .02 dm rmoveto(\256)show oce}def +(<-){gsave 0 .02 dm rmoveto(\254)show oce}def +(==){gsave 0 .05 dm rmoveto(\272)show oce}def +(uc){gsave currentpoint 400 .009 dm mul add translate + 8 -8 scale ucseal oce}def +end + +% an attempt at a PostScript FONT to implement ditroff special chars +% this will enable us to +% cache the little buggers +% generate faster, more compact PS out of psdit +% confuse everyone (including myself)! +50 dict dup begin +/FontType 3 def +/FontName /DIThacks def +/FontMatrix [.001 0 0 .001 0 0] def +/FontBBox [-260 -260 900 900] def% a lie but ... +/Encoding 256 array def +0 1 255{Encoding exch /.notdef put}for +Encoding + dup 8#040/space put %space + dup 8#110/rc put %right ceil + dup 8#111/lt put %left top curl + dup 8#112/bv put %bold vert + dup 8#113/lk put %left mid curl + dup 8#114/lb put %left bot curl + dup 8#115/rt put %right top curl + dup 8#116/rk put %right mid curl + dup 8#117/rb put %right bot curl + dup 8#120/rf put %right floor + dup 8#121/lf put %left floor + dup 8#122/lc put %left ceil + dup 8#140/sq put %square + dup 8#141/bx put %box + dup 8#142/ci put %circle + dup 8#143/br put %box rule + dup 8#144/rn put %root extender + dup 8#145/vr put %vertical rule + dup 8#146/ob put %outline bullet + dup 8#147/bu put %bullet + dup 8#150/ru put %rule + dup 8#151/ul put %underline + pop +/DITfd 100 dict def +/BuildChar{0 begin + /cc exch def /fd exch def + /charname fd /Encoding get cc get def + /charwid fd /Metrics get charname get def + /charproc fd /CharProcs get charname get def + charwid 0 fd /FontBBox get aload pop setcachedevice + 2 setlinejoin 40 setlinewidth + newpath 0 0 moveto gsave charproc grestore + end}def +/BuildChar load 0 DITfd put +/CharProcs 50 dict def +CharProcs begin +/space{}def +/.notdef{}def +/ru{500 0 rls}def +/rn{0 840 moveto 500 0 rls}def +/vr{0 800 moveto 0 -770 rls}def +/bv{0 800 moveto 0 -1000 rls}def +/br{0 840 moveto 0 -1000 rls}def +/ul{0 -140 moveto 500 0 rls}def +/ob{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath stroke}def +/bu{200 250 rmoveto currentpoint newpath 200 0 360 arc closepath fill}def +/sq{80 0 rmoveto currentpoint dround newpath moveto + 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath stroke}def +/bx{80 0 rmoveto currentpoint dround newpath moveto + 640 0 rlineto 0 640 rlineto -640 0 rlineto closepath fill}def +/ci{500 360 rmoveto currentpoint newpath 333 0 360 arc + 50 setlinewidth stroke}def + +/lt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 add exch s4 a4p stroke}def +/lb{0 800 moveto 0 -550 rlineto currx -200 2cx s4 add exch s4 a4p stroke}def +/rt{0 -200 moveto 0 550 rlineto currx 800 2cx s4 sub exch s4 a4p stroke}def +/rb{0 800 moveto 0 -500 rlineto currx -200 2cx s4 sub exch s4 a4p stroke}def +/lk{0 800 moveto 0 300 -300 300 s4 arcto pop pop 1000 sub + 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def +/rk{0 800 moveto 0 300 s2 300 s4 arcto pop pop 1000 sub + 0 300 4 2 roll s4 a4p 0 -200 lineto stroke}def +/lf{0 800 moveto 0 -1000 rlineto s4 0 rls}def +/rf{0 800 moveto 0 -1000 rlineto s4 neg 0 rls}def +/lc{0 -200 moveto 0 1000 rlineto s4 0 rls}def +/rc{0 -200 moveto 0 1000 rlineto s4 neg 0 rls}def +end + +/Metrics 50 dict def Metrics begin +/.notdef 0 def +/space 500 def +/ru 500 def +/br 0 def +/lt 416 def +/lb 416 def +/rt 416 def +/rb 416 def +/lk 416 def +/rk 416 def +/rc 416 def +/lc 416 def +/rf 416 def +/lf 416 def +/bv 416 def +/ob 350 def +/bu 350 def +/ci 750 def +/bx 750 def +/sq 750 def +/rn 500 def +/ul 500 def +/vr 0 def +end + +DITfd begin +/s2 500 def /s4 250 def /s3 333 def +/a4p{arcto pop pop pop pop}def +/2cx{2 copy exch}def +/rls{rlineto stroke}def +/currx{currentpoint pop}def +/dround{transform round exch round exch itransform} def +end +end +/DIThacks exch definefont pop +ditstart +(psc)xT +576 1 1 xr +1(Times-Roman)xf 1 f +2(Times-Italic)xf 2 f +3(Times-Bold)xf 3 f +4(Times-BoldItalic)xf 4 f +5(Helvetica)xf 5 f +6(Helvetica-Bold)xf 6 f +7(Courier)xf 7 f +8(Courier-Bold)xf 8 f +9(Symbol)xf 9 f +10(DIThacks)xf 10 f +10 s +1 f +xi +%%EndProlog + +%%Page: 1 1 +10 s 10 xH 0 xS 1 f +3 f +14 s +1205 1206(LIBTP:)N +1633(Portable,)X +2100(M)X +2206(odular)X +2551(Transactions)X +3202(for)X +3374(UNIX)X +1 f +11 s +3661 1162(1)N +2 f +12 s +2182 1398(Margo)N +2467(Seltzer)X +2171 1494(Michael)N +2511(Olson)X +1800 1590(University)N +2225(of)X +2324(California,)X +2773(Berkeley)X +3 f +2277 1878(Abstract)N +1 f +10 s +755 2001(Transactions)N +1198(provide)X +1475(a)X +1543(useful)X +1771(programming)X +2239(paradigm)X +2574(for)X +2700(maintaining)X +3114(logical)X +3364(consistency,)X +3790(arbitrating)X +4156(con-)X +555 2091(current)N +808(access,)X +1059(and)X +1200(managing)X +1540(recovery.)X +1886(In)X +1977(traditional)X +2330(UNIX)X +2555(systems,)X +2852(the)X +2974(only)X +3140(easy)X +3307(way)X +3465(of)X +3556(using)X +3753(transactions)X +4160(is)X +4237(to)X +555 2181(purchase)N +876(a)X +947(database)X +1258(system.)X +1554(Such)X +1748(systems)X +2035(are)X +2168(often)X +2367(slow,)X +2572(costly,)X +2817(and)X +2967(may)X +3139(not)X +3275(provide)X +3554(the)X +3686(exact)X +3890(functionality)X +555 2271(desired.)N +848(This)X +1011(paper)X +1210(presents)X +1493(the)X +1611(design,)X +1860(implementation,)X +2402(and)X +2538(performance)X +2965(of)X +3052(LIBTP,)X +3314(a)X +3370(simple,)X +3623(non-proprietary)X +4147(tran-)X +555 2361(saction)N +809(library)X +1050(using)X +1249(the)X +1373(4.4BSD)X +1654(database)X +1957(access)X +2189(routines)X +2473(\()X +3 f +2500(db)X +1 f +2588(\(3\)\).)X +2775(On)X +2899(a)X +2961(conventional)X +3401(transaction)X +3779(processing)X +4148(style)X +555 2451(benchmark,)N +959(its)X +1061(performance)X +1495(is)X +1575(approximately)X +2065(85%)X +2239(that)X +2386(of)X +2480(the)X +2604(database)X +2907(access)X +3139(routines)X +3423(without)X +3693(transaction)X +4071(protec-)X +555 2541(tion,)N +725(200%)X +938(that)X +1084(of)X +1177(using)X +3 f +1376(fsync)X +1 f +1554(\(2\))X +1674(to)X +1761(commit)X +2030(modi\256cations)X +2490(to)X +2577(disk,)X +2755(and)X +2896(125%)X +3108(that)X +3253(of)X +3345(a)X +3406(commercial)X +3810(relational)X +4138(data-)X +555 2631(base)N +718(system.)X +3 f +555 2817(1.)N +655(Introduction)X +1 f +755 2940(Transactions)N +1186(are)X +1306(used)X +1474(in)X +1557(database)X +1855(systems)X +2129(to)X +2212(enable)X +2443(concurrent)X +2807(users)X +2992(to)X +3074(apply)X +3272(multi-operation)X +3790(updates)X +4055(without)X +555 3030(violating)N +863(the)X +985(integrity)X +1280(of)X +1371(the)X +1493(database.)X +1814(They)X +2003(provide)X +2271(the)X +2392(properties)X +2736(of)X +2826(atomicity,)X +3171(consistency,)X +3588(isolation,)X +3906(and)X +4045(durabil-)X +555 3120(ity.)N +701(By)X +816(atomicity,)X +1160(we)X +1276(mean)X +1472(that)X +1614(the)X +1734(set)X +1845(of)X +1934(updates)X +2200(comprising)X +2581(a)X +2638(transaction)X +3011(must)X +3187(be)X +3284(applied)X +3541(as)X +3629(a)X +3686(single)X +3898(unit;)X +4085(that)X +4226(is,)X +555 3210(they)N +714(must)X +890(either)X +1094(all)X +1195(be)X +1292(applied)X +1549(to)X +1632(the)X +1751(database)X +2049(or)X +2137(all)X +2238(be)X +2335(absent.)X +2601(Consistency)X +3013(requires)X +3293(that)X +3434(a)X +3491(transaction)X +3864(take)X +4019(the)X +4138(data-)X +555 3300(base)N +725(from)X +908(one)X +1051(logically)X +1358(consistent)X +1704(state)X +1877(to)X +1965(another.)X +2272(The)X +2423(property)X +2721(of)X +2814(isolation)X +3115(requires)X +3400(that)X +3546(concurrent)X +3916(transactions)X +555 3390(yield)N +750(results)X +994(which)X +1225(are)X +1358(indistinguishable)X +1938(from)X +2128(the)X +2260(results)X +2503(which)X +2733(would)X +2967(be)X +3077(obtained)X +3387(by)X +3501(running)X +3784(the)X +3916(transactions)X +555 3480(sequentially.)N +1002(Finally,)X +1268(durability)X +1599(requires)X +1878(that)X +2018(once)X +2190(transactions)X +2593(have)X +2765(been)X +2937(committed,)X +3319(their)X +3486(results)X +3715(must)X +3890(be)X +3986(preserved)X +555 3570(across)N +776(system)X +1018(failures)X +1279([TPCB90].)X +755 3693(Although)N +1080(these)X +1268(properties)X +1612(are)X +1734(most)X +1912(frequently)X +2265(discussed)X +2595(in)X +2680(the)X +2801(context)X +3060(of)X +3150(databases,)X +3501(they)X +3661(are)X +3782(useful)X +4000(program-)X +555 3783(ming)N +750(paradigms)X +1114(for)X +1238(more)X +1433(general)X +1700(purpose)X +1984(applications.)X +2441(There)X +2659(are)X +2788(several)X +3046(different)X +3353(situations)X +3689(where)X +3916(transactions)X +555 3873(can)N +687(be)X +783(used)X +950(to)X +1032(replace)X +1285(current)X +1533(ad-hoc)X +1772(mechanisms.)X +755 3996(One)N +910(situation)X +1206(is)X +1280(when)X +1475(multiple)X +1762(\256les)X +1916(or)X +2004(parts)X +2181(of)X +2269(\256les)X +2422(need)X +2594(to)X +2676(be)X +2772(updated)X +3046(in)X +3128(an)X +3224(atomic)X +3462(fashion.)X +3758(For)X +3889(example,)X +4201(the)X +555 4086(traditional)N +907(UNIX)X +1131(\256le)X +1256(system)X +1501(uses)X +1661(ordering)X +1955(constraints)X +2324(to)X +2408(achieve)X +2676(recoverability)X +3144(in)X +3228(the)X +3348(face)X +3505(of)X +3594(crashes.)X +3893(When)X +4107(a)X +4165(new)X +555 4176(\256le)N +678(is)X +752(created,)X +1026(its)X +1122(inode)X +1321(is)X +1395(written)X +1642(to)X +1724(disk)X +1877(before)X +2103(the)X +2221(new)X +2375(\256le)X +2497(is)X +2570(added)X +2782(to)X +2864(the)X +2982(directory)X +3292(structure.)X +3633(This)X +3795(guarantees)X +4159(that,)X +555 4266(if)N +627(the)X +748(system)X +993(crashes)X +1253(between)X +1544(the)X +1665(two)X +1808(I/O's,)X +2016(the)X +2137(directory)X +2450(does)X +2620(not)X +2744(contain)X +3002(a)X +3060 0.4531(reference)AX +3383(to)X +3467(an)X +3565(invalid)X +3809(inode.)X +4049(In)X +4138(actu-)X +555 4356(ality,)N +741(the)X +863(desired)X +1119(effect)X +1326(is)X +1402(that)X +1545(these)X +1733(two)X +1876(updates)X +2144(have)X +2319(the)X +2440(transactional)X +2873(property)X +3168(of)X +3258(atomicity)X +3583(\(either)X +3816(both)X +3981(writes)X +4200(are)X +555 4446(visible)N +790(or)X +879(neither)X +1124(is\).)X +1266(Rather)X +1501(than)X +1660(building)X +1947(special)X +2191(purpose)X +2466(recovery)X +2769(mechanisms)X +3186(into)X +3331(the)X +3450(\256le)X +3573(system)X +3816(or)X +3904(related)X +4144(tools)X +555 4536(\()N +2 f +582(e.g.)X +3 f +726(fsck)X +1 f +864(\(8\)\),)X +1033(one)X +1177(could)X +1383(use)X +1518(general)X +1783(purpose)X +2064(transaction)X +2443(recovery)X +2752(protocols)X +3077(after)X +3252(system)X +3501(failure.)X +3778(Any)X +3943(application)X +555 4626(that)N +705(needs)X +918(to)X +1010(keep)X +1192(multiple,)X +1508(related)X +1757(\256les)X +1920(\(or)X +2044(directories\))X +2440(consistent)X +2790(should)X +3032(do)X +3141(so)X +3241(using)X +3443(transactions.)X +3895(Source)X +4147(code)X +555 4716(control)N +805(systems,)X +1101(such)X +1271(as)X +1361(RCS)X +1534(and)X +1673(SCCS,)X +1910(should)X +2146(use)X +2276(transaction)X +2651(semantics)X +2990(to)X +3075(allow)X +3276(the)X +3397(``checking)X +3764(in'')X +3903(of)X +3992(groups)X +4232(of)X +555 4806(related)N +801(\256les.)X +1001(In)X +1095(this)X +1237(way,)X +1418(if)X +1493(the)X +1617 0.2841(``check-in'')AX +2028(fails,)X +2212(the)X +2336(transaction)X +2714(may)X +2878(be)X +2980(aborted,)X +3267(backing)X +3547(out)X +3675(the)X +3799(partial)X +4030(``check-)X +555 4896(in'')N +691(leaving)X +947(the)X +1065(source)X +1295(repository)X +1640(in)X +1722(a)X +1778(consistent)X +2118(state.)X +755 5019(A)N +842(second)X +1094(situation)X +1398(where)X +1624(transactions)X +2036(can)X +2177(be)X +2282(used)X +2458(to)X +2549(replace)X +2811(current)X +3068(ad-hoc)X +3316(mechanisms)X +3741(is)X +3822(in)X +3912(applications)X +555 5109(where)N +776(concurrent)X +1144(updates)X +1413(to)X +1499(a)X +1559(shared)X +1793(\256le)X +1919(are)X +2042(desired,)X +2318(but)X +2444(there)X +2629(is)X +2706(logical)X +2948(consistency)X +3345(of)X +3435(the)X +3556(data)X +3713(which)X +3932(needs)X +4138(to)X +4223(be)X +555 5199(preserved.)N +928(For)X +1059(example,)X +1371(when)X +1565(the)X +1683(password)X +2006(\256le)X +2128(is)X +2201(updated,)X +2495(\256le)X +2617(locking)X +2877(is)X +2950(used)X +3117(to)X +3199(disallow)X +3490(concurrent)X +3854(access.)X +4120(Tran-)X +555 5289(saction)N +804(semantics)X +1142(on)X +1244(the)X +1364(password)X +1689(\256les)X +1844(would)X +2066(allow)X +2266(concurrent)X +2632(updates,)X +2919(while)X +3119(preserving)X +3479(the)X +3598(logical)X +3837(consistency)X +4232(of)X +555 5379(the)N +681(password)X +1012(database.)X +1357(Similarly,)X +1702(UNIX)X +1930(utilities)X +2196(which)X +2419(rewrite)X +2674(\256les)X +2834(face)X +2996(a)X +3059(potential)X +3366(race)X +3528(condition)X +3857(between)X +4152(their)X +555 5469(rewriting)N +871(a)X +929(\256le)X +1053(and)X +1191(another)X +1453(process)X +1715(reading)X +1977(the)X +2096(\256le.)X +2259(For)X +2391(example,)X +2704(the)X +2823(compiler)X +3129(\(more)X +3342(precisely,)X +3673(the)X +3792(assembler\))X +4161(may)X +8 s +10 f +555 5541(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N +5 s +1 f +727 5619(1)N +8 s +763 5644(To)N +850(appear)X +1035(in)X +1101(the)X +2 f +1195(Proceedings)X +1530(of)X +1596(the)X +1690(1992)X +1834(Winter)X +2024(Usenix)X +1 f +2201(,)X +2233(San)X +2345(Francisco,)X +2625(CA,)X +2746(January)X +2960(1992.)X + +2 p +%%Page: 2 2 +8 s 8 xH 0 xS 1 f +10 s +3 f +1 f +555 630(have)N +737(to)X +829(rewrite)X +1087(a)X +1152(\256le)X +1283(to)X +1374(which)X +1599(it)X +1672(has)X +1808(write)X +2002(permission)X +2382(in)X +2473(a)X +2538(directory)X +2857(to)X +2948(which)X +3173(it)X +3246(does)X +3422(not)X +3553(have)X +3734(write)X +3928(permission.)X +555 720(While)N +779(the)X +904(``.o'')X +1099(\256le)X +1228(is)X +1308(being)X +1513(written,)X +1787(another)X +2055(utility)X +2272(such)X +2446(as)X +3 f +2540(nm)X +1 f +2651(\(1\))X +2772(or)X +3 f +2866(ar)X +1 f +2942(\(1\))X +3063(may)X +3228(read)X +3394(the)X +3519(\256le)X +3648(and)X +3791(produce)X +4077(invalid)X +555 810(results)N +790(since)X +981(the)X +1105(\256le)X +1233(has)X +1366(not)X +1494(been)X +1672(completely)X +2054(written.)X +2347(Currently,)X +2700(some)X +2895(utilities)X +3160(use)X +3293(special)X +3542(purpose)X +3821(code)X +3998(to)X +4085(handle)X +555 900(such)N +722(cases)X +912(while)X +1110(others)X +1326(ignore)X +1551(the)X +1669(problem)X +1956(and)X +2092(force)X +2278(users)X +2463(to)X +2545(live)X +2685(with)X +2847(the)X +2965(consequences.)X +755 1023(In)N +845(this)X +983(paper,)X +1205(we)X +1322(present)X +1577(a)X +1635(simple)X +1870(library)X +2106(which)X +2324(provides)X +2622(transaction)X +2996(semantics)X +3334(\(atomicity,)X +3705(consistency,)X +4121(isola-)X +555 1113(tion,)N +720(and)X +857(durability\).)X +1236(The)X +1382(4.4BSD)X +1658(database)X +1956(access)X +2182(methods)X +2473(have)X +2645(been)X +2817(modi\256ed)X +3121(to)X +3203(use)X +3330(this)X +3465(library,)X +3719(optionally)X +4063(provid-)X +555 1203(ing)N +682(shared)X +917(buffer)X +1139(management)X +1574(between)X +1867(applications,)X +2298(locking,)X +2582(and)X +2722(transaction)X +3098(semantics.)X +3478(Any)X +3640(UNIX)X +3865(program)X +4161(may)X +555 1293(transaction)N +930(protect)X +1176(its)X +1274(data)X +1430(by)X +1532(requesting)X +1888(transaction)X +2262(protection)X +2609(with)X +2773(the)X +3 f +2893(db)X +1 f +2981(\(3\))X +3097(library)X +3333(or)X +3422(by)X +3524(adding)X +3764(appropriate)X +4152(calls)X +555 1383(to)N +646(the)X +773(transaction)X +1154(manager,)X +1480(buffer)X +1706(manager,)X +2032(lock)X +2199(manager,)X +2525(and)X +2670(log)X +2801(manager.)X +3147(The)X +3301(library)X +3543(routines)X +3829(may)X +3995(be)X +4099(linked)X +555 1473(into)N +708(the)X +834(host)X +995(application)X +1379(and)X +1523(called)X +1743(by)X +1851(subroutine)X +2217(interface,)X +2547(or)X +2642(they)X +2808(may)X +2974(reside)X +3194(in)X +3284(a)X +3348(separate)X +3640(server)X +3865(process.)X +4174(The)X +555 1563(server)N +772(architecture)X +1172(provides)X +1468(for)X +1582(network)X +1865(access)X +2091(and)X +2227(better)X +2430(protection)X +2775(mechanisms.)X +3 f +555 1749(2.)N +655(Related)X +938(Work)X +1 f +755 1872(There)N +1000(has)X +1164(been)X +1373(much)X +1608(discussion)X +1998(in)X +2117(recent)X +2371(years)X +2597(about)X +2831(new)X +3021(transaction)X +3429(models)X +3716(and)X +3888(architectures)X +555 1962 0.1172([SPEC88][NODI90][CHEN91][MOHA91].)AN +2009(Much)X +2220(of)X +2310(this)X +2448(work)X +2636(focuses)X +2900(on)X +3003(new)X +3160(ways)X +3348(to)X +3433(model)X +3656(transactions)X +4062(and)X +4201(the)X +555 2052(interactions)N +953(between)X +1245(them,)X +1449(while)X +1651(the)X +1772(work)X +1960(presented)X +2291(here)X +2453(focuses)X +2717(on)X +2820(the)X +2941(implementation)X +3466(and)X +3605(performance)X +4035(of)X +4125(tradi-)X +555 2142(tional)N +757(transaction)X +1129(techniques)X +1492(\(write-ahead)X +1919(logging)X +2183(and)X +2319(two-phase)X +2669(locking\))X +2956(on)X +3056(a)X +3112(standard)X +3404(operating)X +3727(system)X +3969(\(UNIX\).)X +755 2265(Such)N +947(traditional)X +1308(operating)X +1643(systems)X +1928(are)X +2059(often)X +2256(criticized)X +2587(for)X +2713(their)X +2892(inability)X +3190(to)X +3283(perform)X +3573(transaction)X +3956(processing)X +555 2355(adequately.)N +971([STON81])X +1342(cites)X +1517(three)X +1706(main)X +1894(areas)X +2088(of)X +2183(inadequate)X +2559(support:)X +2849(buffer)X +3074(management,)X +3532(the)X +3658(\256le)X +3788(system,)X +4058(and)X +4201(the)X +555 2445(process)N +823(structure.)X +1191(These)X +1410(arguments)X +1771(are)X +1897(summarized)X +2316(in)X +2405(table)X +2587(one.)X +2769(Fortunately,)X +3184(much)X +3388(has)X +3521(changed)X +3815(since)X +4006(1981.)X +4232(In)X +555 2535(the)N +683(area)X +848(of)X +945(buffer)X +1172(management,)X +1632(most)X +1817(UNIX)X +2048(systems)X +2331(provide)X +2606(the)X +2734(ability)X +2968(to)X +3060(memory)X +3357(map)X +3525(\256les,)X +3708(thus)X +3870(obviating)X +4201(the)X +555 2625(need)N +734(for)X +855(a)X +918(copy)X +1101(between)X +1396(kernel)X +1624(and)X +1766(user)X +1926(space.)X +2171(If)X +2251(a)X +2313(database)X +2616(system)X +2864(is)X +2943(going)X +3151(to)X +3239(use)X +3372(the)X +3496(\256le)X +3624(system)X +3872(buffer)X +4095(cache,)X +555 2715(then)N +719(a)X +781(system)X +1029(call)X +1171(is)X +1250(required.)X +1584(However,)X +1924(if)X +1998(buffering)X +2322(is)X +2400(provided)X +2710(at)X +2793(user)X +2952(level)X +3133(using)X +3331(shared)X +3566(memory,)X +3878(as)X +3970(in)X +4057(LIBTP,)X +555 2805(buffer)N +776(management)X +1210(is)X +1287(only)X +1452(as)X +1542(slow)X +1716(as)X +1806(access)X +2035(to)X +2120(shared)X +2353(memory)X +2643(and)X +2782(any)X +2921(replacement)X +3337(algorithm)X +3671(may)X +3832(be)X +3931(used.)X +4121(Since)X +555 2895(multiple)N +849(processes)X +1185(can)X +1325(access)X +1559(the)X +1685(shared)X +1923(data,)X +2105(prefetching)X +2499(may)X +2665(be)X +2769(accomplished)X +3238(by)X +3346(separate)X +3638(processes)X +3973(or)X +4067(threads)X +555 2985(whose)N +782(sole)X +932(purpose)X +1207(is)X +1281(to)X +1364(prefetch)X +1649(pages)X +1853(and)X +1990(wait)X +2149(on)X +2250(them.)X +2471(There)X +2680(is)X +2754(still)X +2894(no)X +2995(way)X +3150(to)X +3233(enforce)X +3496(write)X +3682(ordering)X +3975(other)X +4161(than)X +555 3075(keeping)N +829(pages)X +1032(in)X +1114(user)X +1268(memory)X +1555(and)X +1691(using)X +1884(the)X +3 f +2002(fsync)X +1 f +2180(\(3\))X +2294(system)X +2536(call)X +2672(to)X +2754(perform)X +3033(synchronous)X +3458(writes.)X +755 3198(In)N +845(the)X +966(area)X +1124(of)X +1214(\256le)X +1339(systems,)X +1635(the)X +1756(fast)X +1895(\256le)X +2020(system)X +2265(\(FFS\))X +2474([MCKU84])X +2871(allows)X +3103(allocation)X +3442(in)X +3527(units)X +3704(up)X +3806(to)X +3890(64KBytes)X +4232(as)X +555 3288(opposed)N +846(to)X +932(the)X +1054(4KByte)X +1327(and)X +1466(8KByte)X +1738(\256gures)X +1979(quoted)X +2220(in)X +2305([STON81].)X +2711(The)X +2859(measurements)X +3341(in)X +3426(this)X +3564(paper)X +3766(were)X +3946(taken)X +4143(from)X +555 3378(an)N +655(8KByte)X +928(FFS,)X +1104(but)X +1230(as)X +1320(LIBTP)X +1565(runs)X +1726(exclusively)X +2114(in)X +2199(user)X +2356(space,)X +2578(there)X +2762(is)X +2838(nothing)X +3105(to)X +3190(prevent)X +3454(it)X +3521(from)X +3700(being)X +3901(run)X +4031(on)X +4134(other)X +555 3468(UNIX)N +776(compatible)X +1152(\256le)X +1274(systems)X +1547(\(e.g.)X +1710(log-structured)X +2180([ROSE91],)X +2558(extent-based,)X +3004(or)X +3091(multi-block)X +3484([SELT91]\).)X +755 3591(Finally,)N +1029(with)X +1199(regard)X +1433(to)X +1523(the)X +1648(process)X +1916(structure,)X +2244(neither)X +2494(context)X +2757(switch)X +2993(time)X +3162(nor)X +3296(scheduling)X +3670(around)X +3920(semaphores)X +555 3681(seems)N +785(to)X +881(affect)X +1099(the)X +1231(system)X +1487(performance.)X +1968(However,)X +2317(the)X +2449(implementation)X +2984(of)X +3084(semaphores)X +3496(can)X +3641(impact)X +3892(performance)X +555 3771(tremendously.)N +1051(This)X +1213(is)X +1286(discussed)X +1613(in)X +1695(more)X +1880(detail)X +2078(in)X +2160(section)X +2407(4.3.)X +755 3894(The)N +908(Tuxedo)X +1181(system)X +1431(from)X +1615(AT&T)X +1861(is)X +1941(a)X +2004(transaction)X +2383(manager)X +2687(which)X +2910(coordinates)X +3307(distributed)X +3676(transaction)X +4055(commit)X +555 3984(from)N +738(a)X +801(variety)X +1051(of)X +1145(different)X +1449(local)X +1632(transaction)X +2011(managers.)X +2386(At)X +2493(this)X +2634(time,)X +2822(LIBTP)X +3070(does)X +3243(not)X +3371(have)X +3549(its)X +3650(own)X +3814(mechanism)X +4205(for)X +555 4074(distributed)N +942(commit)X +1231(processing,)X +1639(but)X +1786(could)X +2009(be)X +2130(used)X +2322(as)X +2434(a)X +2515(local)X +2716(transaction)X +3113(agent)X +3331(by)X +3455(systems)X +3752(such)X +3943(as)X +4054(Tuxedo)X +555 4164([ANDR89].)N +10 f +863 4393(i)N +870(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +903 4483(Buffer)N +1133(Management)X +10 f +1672(g)X +1 f +1720(Data)X +1892(must)X +2067(be)X +2163(copied)X +2397(between)X +2685(kernel)X +2906(space)X +3105(and)X +3241(user)X +3395(space.)X +10 f +1672 4573(g)N +1 f +1720(Buffer)X +1950(pool)X +2112(access)X +2338(is)X +2411(too)X +2533(slow.)X +10 f +1672 4663(g)N +1 f +1720(There)X +1928(is)X +2001(no)X +2101(way)X +2255(to)X +2337(request)X +2589(prefetch.)X +10 f +1672 4753(g)N +1 f +1720(Replacement)X +2159(is)X +2232(usually)X +2483(LRU)X +2663(which)X +2879(may)X +3037(be)X +3133(suboptimal)X +3508(for)X +3622(databases.)X +10 f +1672 4843(g)N +1 f +1720(There)X +1928(is)X +2001(no)X +2101(way)X +2255(to)X +2337(guarantee)X +2670(write)X +2855(ordering.)X +10 f +863 4853(i)N +870(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +903 4943(File)N +1047(System)X +10 f +1672(g)X +1 f +1720(Allocation)X +2078(is)X +2151(done)X +2327(in)X +2409(small)X +2602(blocks)X +2831(\(usually)X +3109(4K)X +3227(or)X +3314(8K\).)X +10 f +1672 5033(g)N +1 f +1720(Logical)X +1985(organization)X +2406(of)X +2493(\256les)X +2646(is)X +2719(redundantly)X +3122(expressed.)X +10 f +863 5043(i)N +870(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +903 5133(Process)N +1168(Structure)X +10 f +1672(g)X +1 f +1720(Context)X +1993(switching)X +2324(and)X +2460(message)X +2752(passing)X +3012(are)X +3131(too)X +3253(slow.)X +10 f +1672 5223(g)N +1 f +1720(A)X +1798(process)X +2059(may)X +2217(be)X +2313(descheduled)X +2730(while)X +2928(holding)X +3192(a)X +3248(semaphore.)X +10 f +863 5233(i)N +870(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +863(c)X +5193(c)Y +5113(c)Y +5033(c)Y +4953(c)Y +4873(c)Y +4793(c)Y +4713(c)Y +4633(c)Y +4553(c)Y +4473(c)Y +3990 5233(c)N +5193(c)Y +5113(c)Y +5033(c)Y +4953(c)Y +4873(c)Y +4793(c)Y +4713(c)Y +4633(c)Y +4553(c)Y +4473(c)Y +3 f +1156 5446(Table)N +1371(One:)X +1560(Shortcomings)X +2051(of)X +2138(UNIX)X +2363(transaction)X +2770(support)X +3056(cited)X +3241(in)X +3327([STON81].)X + +3 p +%%Page: 3 3 +10 s 10 xH 0 xS 3 f +1 f +755 630(The)N +901(transaction)X +1274(architecture)X +1675(presented)X +2004(in)X +2087([YOUN91])X +2474(is)X +2548(very)X +2712(similar)X +2955(to)X +3038(that)X +3179(implemented)X +3618(in)X +3701(the)X +3820(LIBTP.)X +4103(While)X +555 720([YOUN91])N +947(presents)X +1236(a)X +1298(model)X +1524(for)X +1644(providing)X +1981(transaction)X +2359(services,)X +2663(this)X +2803(paper)X +3007(focuses)X +3273(on)X +3378(the)X +3501(implementation)X +4028(and)X +4169(per-)X +555 810(formance)N +881(of)X +970(a)X +1028(particular)X +1358(system.)X +1642(In)X +1731(addition,)X +2034(we)X +2149(provide)X +2415(detailed)X +2690(comparisons)X +3116(with)X +3279(alternative)X +3639(solutions:)X +3970(traditional)X +555 900(UNIX)N +776(services)X +1055(and)X +1191(commercial)X +1590(database)X +1887(management)X +2317(systems.)X +3 f +555 1086(3.)N +655(Architecture)X +1 f +755 1209(The)N +906(library)X +1146(is)X +1224(designed)X +1534(to)X +1621(provide)X +1891(well)X +2054(de\256ned)X +2315(interfaces)X +2653(to)X +2740(the)X +2863(services)X +3147(required)X +3440(for)X +3559(transaction)X +3936(processing.)X +555 1299(These)N +777(services)X +1066(are)X +1195(recovery,)X +1527(concurrency)X +1955(control,)X +2232(and)X +2378(the)X +2506(management)X +2946(of)X +3043(shared)X +3283(data.)X +3487(First)X +3663(we)X +3787(will)X +3941(discuss)X +4201(the)X +555 1389(design)N +795(tradeoffs)X +1112(in)X +1205(the)X +1334(selection)X +1650(of)X +1748(recovery,)X +2081(concurrency)X +2510(control,)X +2787(and)X +2933(buffer)X +3160(management)X +3600(implementations,)X +4183(and)X +555 1479(then)N +713(we)X +827(will)X +971(present)X +1223(the)X +1341(overall)X +1584(library)X +1818(architecture)X +2218(and)X +2354(module)X +2614(descriptions.)X +3 f +555 1665(3.1.)N +715(Design)X +966(Tradeoffs)X +1 f +3 f +555 1851(3.1.1.)N +775(Crash)X +1004(Recovery)X +1 f +755 1974(The)N +909(recovery)X +1220(protocol)X +1516(is)X +1598(responsible)X +1992(for)X +2115(providing)X +2455(the)X +2582(transaction)X +2963(semantics)X +3308(discussed)X +3644(earlier.)X +3919(There)X +4136(are)X +4263(a)X +555 2064(wide)N +739(range)X +946(of)X +1041(recovery)X +1351(protocols)X +1677(available)X +1995([HAER83],)X +2395(but)X +2525(we)X +2647(can)X +2786(crudely)X +3054(divide)X +3281(them)X +3468(into)X +3619(two)X +3766(main)X +3953(categories.)X +555 2154(The)N +706(\256rst)X +856(category)X +1159(records)X +1422(all)X +1528(modi\256cations)X +1989(to)X +2077(the)X +2201(database)X +2504(in)X +2592(a)X +2653(separate)X +2942(\256le,)X +3089(and)X +3230(uses)X +3393(this)X +3533(\256le)X +3660(\(log\))X +3841(to)X +3928(back)X +4105(out)X +4232(or)X +555 2244(reapply)N +825(these)X +1019(modi\256cations)X +1483(if)X +1561(a)X +1626(transaction)X +2007(aborts)X +2232(or)X +2328(the)X +2455(system)X +2706(crashes.)X +3012(We)X +3153(call)X +3298(this)X +3442(set)X +3560(the)X +3 f +3687(logging)X +3963(protocols)X +1 f +4279(.)X +555 2334(The)N +703(second)X +949(category)X +1249(avoids)X +1481(the)X +1602(use)X +1732(of)X +1822(a)X +1881(log)X +2006(by)X +2109(carefully)X +2418(controlling)X +2792(when)X +2989(data)X +3146(are)X +3268(written)X +3518(to)X +3603(disk.)X +3799(We)X +3934(call)X +4073(this)X +4210(set)X +555 2424(the)N +3 f +673(non-logging)X +1096(protocols)X +1 f +1412(.)X +755 2547(Non-logging)N +1185(protocols)X +1504(hold)X +1666(dirty)X +1837(buffers)X +2085(in)X +2167(main)X +2347(memory)X +2634(or)X +2721(temporary)X +3071(\256les)X +3224(until)X +3390(commit)X +3654(and)X +3790(then)X +3948(force)X +4134(these)X +555 2637(pages)N +769(to)X +862(disk)X +1026(at)X +1115(transaction)X +1498(commit.)X +1813(While)X +2040(we)X +2165(can)X +2308(use)X +2446(temporary)X +2807(\256les)X +2971(to)X +3064(hold)X +3237(dirty)X +3418(pages)X +3631(that)X +3781(may)X +3949(need)X +4131(to)X +4223(be)X +555 2727(evicted)N +810(from)X +988(memory)X +1277(during)X +1508(a)X +1566(long-running)X +2006(transaction,)X +2400(the)X +2520(only)X +2684(user-level)X +3023(mechanism)X +3410(to)X +3494(force)X +3682(pages)X +3887(to)X +3971(disk)X +4126(is)X +4201(the)X +3 f +555 2817(fsync)N +1 f +733(\(2\))X +850(system)X +1095(call.)X +1274(Unfortunately,)X +3 f +1767(fsync)X +1 f +1945(\(2\))X +2062(is)X +2138(an)X +2237(expensive)X +2581(system)X +2826(call)X +2965(in)X +3050(that)X +3193(it)X +3260(forces)X +3480(all)X +3583(pages)X +3789(of)X +3879(a)X +3938(\256le)X +4062(to)X +4146(disk,)X +555 2907(and)N +691(transactions)X +1094(that)X +1234(manage)X +1504(more)X +1689(than)X +1847(one)X +1983(\256le)X +2105(must)X +2280(issue)X +2460(one)X +2596(call)X +2732(per)X +2855(\256le.)X +755 3030(In)N +853(addition,)X +3 f +1166(fsync)X +1 f +1344(\(2\))X +1469(provides)X +1776(no)X +1887(way)X +2051(to)X +2143(control)X +2400(the)X +2528(order)X +2728(in)X +2820(which)X +3046(dirty)X +3227(pages)X +3440(are)X +3569(written)X +3826(to)X +3918(disk.)X +4121(Since)X +555 3120(non-logging)N +976(protocols)X +1304(must)X +1489(sometimes)X +1861(order)X +2061(writes)X +2287(carefully)X +2603([SULL92],)X +2987(they)X +3155(are)X +3284(dif\256cult)X +3567(to)X +3659(implement)X +4030(on)X +4139(Unix)X +555 3210(systems.)N +868(As)X +977(a)X +1033(result,)X +1251(we)X +1365(have)X +1537(chosen)X +1780(to)X +1862(implement)X +2224(a)X +2280(logging)X +2544(protocol.)X +755 3333(Logging)N +1050(protocols)X +1372(may)X +1534(be)X +1634(categorized)X +2029(based)X +2236(on)X +2340(how)X +2502(information)X +2904(is)X +2981(logged)X +3223(\(physically)X +3602(or)X +3692(logically\))X +4022(and)X +4161(how)X +555 3423(much)N +767(is)X +854(logged)X +1106(\(before)X +1373(images,)X +1654(after)X +1836(images)X +2097(or)X +2198(both\).)X +2441(In)X +3 f +2542(physical)X +2855(logging)X +1 f +3103(,)X +3157(images)X +3417(of)X +3517(complete)X +3844(physical)X +4144(units)X +555 3513(\(pages)N +786(or)X +874(buffers\))X +1150(are)X +1270(recorded,)X +1593(while)X +1792(in)X +3 f +1875(logical)X +2118(logging)X +1 f +2387(a)X +2444(description)X +2820(of)X +2907(the)X +3025(operation)X +3348(is)X +3421(recorded.)X +3763(Therefore,)X +4121(while)X +555 3603(we)N +675(may)X +839(record)X +1071(entire)X +1280(pages)X +1489(in)X +1577(a)X +1639(physical)X +1932(log,)X +2080(we)X +2200(need)X +2378(only)X +2546(record)X +2777(the)X +2900(records)X +3162(being)X +3365(modi\256ed)X +3674(in)X +3761(a)X +3822(logical)X +4065(log.)X +4232(In)X +555 3693(fact,)N +718(physical)X +1006(logging)X +1271(can)X +1404(be)X +1501(thought)X +1766(of)X +1854(as)X +1942(a)X +1999(special)X +2243(case)X +2403(of)X +2491(logical)X +2730(logging,)X +3015(since)X +3201(the)X +3320 0.3125(``records'')AX +3686(that)X +3827(we)X +3942(log)X +4065(in)X +4148(logi-)X +555 3783(cal)N +673(logging)X +941(might)X +1151(be)X +1251(physical)X +1542(pages.)X +1789(Since)X +1991(logical)X +2233(logging)X +2501(is)X +2578(both)X +2743(more)X +2931(space-ef\256cient)X +3423(and)X +3562(more)X +3750(general,)X +4030(we)X +4147(have)X +555 3873(chosen)N +798(it)X +862(for)X +976(our)X +1103(logging)X +1367(protocol.)X +755 3996(In)N +3 f +843(before-image)X +1315(logging)X +1 f +1563(,)X +1604(we)X +1719(log)X +1842(a)X +1899(copy)X +2076(of)X +2164(the)X +2283(data)X +2438(before)X +2665(the)X +2784(update,)X +3039(while)X +3238(in)X +3 f +3321(after-image)X +3739(logging)X +1 f +3987(,)X +4027(we)X +4141(log)X +4263(a)X +555 4086(copy)N +740(of)X +836(the)X +963(data)X +1126(after)X +1303(the)X +1429(update.)X +1711(If)X +1793(we)X +1915(log)X +2045(only)X +2215(before-images,)X +2723(then)X +2889(there)X +3078(is)X +3159(suf\256cient)X +3485(information)X +3891(in)X +3981(the)X +4107(log)X +4237(to)X +555 4176(allow)N +761(us)X +860(to)X +3 f +950(undo)X +1 f +1150(the)X +1276(transaction)X +1656(\(go)X +1791(back)X +1971(to)X +2061(the)X +2187(state)X +2361(represented)X +2759(by)X +2866(the)X +2991(before-image\).)X +3514(However,)X +3876(if)X +3952(the)X +4077(system)X +555 4266(crashes)N +814(and)X +952(a)X +1010(committed)X +1374(transaction's)X +1806(changes)X +2087(have)X +2261(not)X +2385(reached)X +2658(the)X +2778(disk,)X +2953(we)X +3068(have)X +3241(no)X +3342(means)X +3568(to)X +3 f +3651(redo)X +1 f +3828(the)X +3947(transaction)X +555 4356(\(reapply)N +849(the)X +973(updates\).)X +1311(Therefore,)X +1675(logging)X +1945(only)X +2113(before-images)X +2599(necessitates)X +3004(forcing)X +3262(dirty)X +3439(pages)X +3648(at)X +3732(commit)X +4002(time.)X +4210(As)X +555 4446(mentioned)N +913(above,)X +1145(forcing)X +1397(pages)X +1600(at)X +1678(commit)X +1942(is)X +2015(considered)X +2383(too)X +2505(costly.)X +755 4569(If)N +834(we)X +953(log)X +1080(only)X +1247(after-images,)X +1694(then)X +1857(there)X +2043(is)X +2121(suf\256cient)X +2444(information)X +2847(in)X +2934(the)X +3057(log)X +3184(to)X +3271(allow)X +3474(us)X +3570(to)X +3657(redo)X +3825(the)X +3947(transaction)X +555 4659(\(go)N +687(forward)X +967(to)X +1054(the)X +1177(state)X +1348(represented)X +1743(by)X +1847(the)X +1969(after-image\),)X +2411(but)X +2537(we)X +2655(do)X +2759(not)X +2885(have)X +3061(the)X +3183(information)X +3585(required)X +3877(to)X +3963(undo)X +4147(tran-)X +555 4749(sactions)N +845(which)X +1073(aborted)X +1346(after)X +1526(dirty)X +1709(pages)X +1924(were)X +2113(written)X +2372(to)X +2466(disk.)X +2670(Therefore,)X +3039(logging)X +3314(only)X +3487(after-images)X +3920(necessitates)X +555 4839(holding)N +819(all)X +919(dirty)X +1090(buffers)X +1338(in)X +1420(main)X +1600(memory)X +1887(until)X +2053(commit)X +2317(or)X +2404(writing)X +2655(them)X +2835(to)X +2917(a)X +2973(temporary)X +3323(\256le.)X +755 4962(Since)N +956(neither)X +1202(constraint)X +1541(\(forcing)X +1823(pages)X +2029(on)X +2132(commit)X +2399(or)X +2489(buffering)X +2811(pages)X +3016(until)X +3184(commit\))X +3477(was)X +3624(feasible,)X +3916(we)X +4032(chose)X +4237(to)X +555 5052(log)N +683(both)X +851(before)X +1083(and)X +1225(after)X +1399(images.)X +1672(The)X +1823(only)X +1991(remaining)X +2342(consideration)X +2800(is)X +2879(when)X +3079(changes)X +3363(get)X +3486(written)X +3738(to)X +3825(disk.)X +4023(Changes)X +555 5142(affect)N +764(both)X +931(data)X +1090(pages)X +1298(and)X +1438(the)X +1560(log.)X +1726(If)X +1804(the)X +1926(changed)X +2218(data)X +2376(page)X +2552(is)X +2629(written)X +2880(before)X +3110(the)X +3232(log)X +3358(page,)X +3554(and)X +3694(the)X +3816(system)X +4062(crashes)X +555 5232(before)N +787(the)X +911(log)X +1039(page)X +1217(is)X +1296(written,)X +1569(the)X +1693(log)X +1820(will)X +1969(contain)X +2230(insuf\256cient)X +2615(information)X +3018(to)X +3105(undo)X +3290(the)X +3413(change.)X +3706(This)X +3873(violates)X +4147(tran-)X +555 5322(saction)N +803(semantics,)X +1160(since)X +1346(some)X +1536(changed)X +1825(data)X +1980(pages)X +2184(may)X +2343(not)X +2466(have)X +2638(been)X +2810(written,)X +3077(and)X +3213(the)X +3331(database)X +3628(cannot)X +3862(be)X +3958(restored)X +4237(to)X +555 5412(its)N +650(pre-transaction)X +1152(state.)X +755 5535(The)N +914(log)X +1050(record)X +1290(describing)X +1658(an)X +1768(update)X +2016(must)X +2205(be)X +2315(written)X +2576(to)X +2672(stable)X +2893(storage)X +3159(before)X +3398(the)X +3529(modi\256ed)X +3846(page.)X +4071(This)X +4246(is)X +3 f +555 5625(write-ahead)N +992(logging)X +1 f +1240(.)X +1307(If)X +1388(log)X +1517(records)X +1781(are)X +1907(safely)X +2126(written)X +2380(to)X +2469(disk,)X +2649(data)X +2810(pages)X +3020(may)X +3185(be)X +3288(written)X +3542(at)X +3627(any)X +3770(time)X +3939(afterwards.)X +555 5715(This)N +721(means)X +950(that)X +1094(the)X +1216(only)X +1382(\256le)X +1508(that)X +1652(ever)X +1815(needs)X +2022(to)X +2108(be)X +2208(forced)X +2438(to)X +2524(disk)X +2681(is)X +2758(the)X +2880(log.)X +3046(Since)X +3248(the)X +3370(log)X +3495(is)X +3571(append-only,)X +4015(modi\256ed)X + +4 p +%%Page: 4 4 +10 s 10 xH 0 xS 1 f +3 f +1 f +555 630(pages)N +760(always)X +1005(appear)X +1242(at)X +1322(the)X +1442(end)X +1580(and)X +1718(may)X +1878(be)X +1976(written)X +2224(to)X +2307(disk)X +2461(ef\256ciently)X +2807(in)X +2890(any)X +3027(\256le)X +3150(system)X +3393(that)X +3534(favors)X +3756(sequential)X +4102(order-)X +555 720(ing)N +677(\()X +2 f +704(e.g.)X +1 f +820(,)X +860(FFS,)X +1032(log-structured)X +1502(\256le)X +1624(system,)X +1886(or)X +1973(an)X +2069(extent-based)X +2495(system\).)X +3 f +555 906(3.1.2.)N +775(Concurrency)X +1245(Control)X +1 f +755 1029(The)N +918(concurrency)X +1354(control)X +1619(protocol)X +1923(is)X +2013(responsible)X +2415(for)X +2546(maintaining)X +2965(consistency)X +3376(in)X +3475(the)X +3610(presence)X +3929(of)X +4033(multiple)X +555 1119(accesses.)N +897(There)X +1114(are)X +1242(several)X +1499(alternative)X +1867(solutions)X +2183(such)X +2358(as)X +2453(locking,)X +2741(optimistic)X +3088(concurrency)X +3514(control)X +3769([KUNG81],)X +4183(and)X +555 1209(timestamp)N +912(ordering)X +1208([BERN80].)X +1619(Since)X +1821(optimistic)X +2164(methods)X +2459(and)X +2599(timestamp)X +2956(ordering)X +3252(are)X +3374(generally)X +3696(more)X +3884(complex)X +4183(and)X +555 1299(restrict)N +804(concurrency)X +1228(without)X +1498(eliminating)X +1888(starvation)X +2230(or)X +2323(deadlocks,)X +2690(we)X +2810(chose)X +3018(two-phase)X +3373(locking)X +3638(\(2PL\).)X +3890(Strict)X +4088(2PL)X +4246(is)X +555 1389(suboptimal)N +935(for)X +1054(certain)X +1297(data)X +1455(structures)X +1791(such)X +1962(as)X +2053(B-trees)X +2309(because)X +2588(it)X +2656(can)X +2792(limit)X +2966(concurrency,)X +3408(so)X +3503(we)X +3621(use)X +3752(a)X +3812(special)X +4059(locking)X +555 1479(protocol)N +842(based)X +1045(on)X +1145(one)X +1281(described)X +1609(in)X +1691([LEHM81].)X +755 1602(The)N +901(B-tree)X +1123(locking)X +1384(protocol)X +1672(we)X +1787(implemented)X +2226(releases)X +2502(locks)X +2691(at)X +2769(internal)X +3034(nodes)X +3241(in)X +3323(the)X +3441(tree)X +3582(as)X +3669(it)X +3733(descends.)X +4083(A)X +4161(lock)X +555 1692(on)N +658(an)X +757(internal)X +1025(page)X +1200(is)X +1276(always)X +1522(released)X +1808(before)X +2036(a)X +2094(lock)X +2254(on)X +2356(its)X +2453(child)X +2635(is)X +2710(obtained)X +3008(\(that)X +3177(is,)X +3272(locks)X +3463(are)X +3584(not)X +3 f +3708(coupled)X +1 f +3996([BAY77])X +555 1782(during)N +786(descent\).)X +1116(When)X +1330(a)X +1388(leaf)X +1531(\(or)X +1647(internal\))X +1941(page)X +2115(is)X +2190(split,)X +2369(a)X +2427(write)X +2614(lock)X +2774(is)X +2849(acquired)X +3148(on)X +3250(the)X +3370(parent)X +3593(before)X +3821(the)X +3941(lock)X +4100(on)X +4201(the)X +555 1872(just-split)N +855(page)X +1028(is)X +1102(released)X +1387(\(locks)X +1604(are)X +3 f +1724(coupled)X +1 f +2011(during)X +2241(ascent\).)X +2530(Write)X +2734(locks)X +2924(on)X +3025(internal)X +3291(pages)X +3495(are)X +3615(released)X +3899(immediately)X +555 1962(after)N +723(the)X +841(page)X +1013(is)X +1086(updated,)X +1380(but)X +1502(locks)X +1691(on)X +1791(leaf)X +1932(pages)X +2135(are)X +2254(held)X +2412(until)X +2578(the)X +2696(end)X +2832(of)X +2919(the)X +3037(transaction.)X +755 2085(Since)N +964(locks)X +1164(are)X +1294(released)X +1589(during)X +1828(descent,)X +2119(the)X +2247(structure)X +2558(of)X +2655(the)X +2783(tree)X +2934(may)X +3102(change)X +3360(above)X +3582(a)X +3648(node)X +3834(being)X +4042(used)X +4219(by)X +555 2175(some)N +752(process.)X +1061(If)X +1143(that)X +1291(process)X +1560(must)X +1743(later)X +1914(ascend)X +2161(the)X +2287(tree)X +2435(because)X +2717(of)X +2811(a)X +2874(page)X +3053(split,)X +3237(any)X +3380(such)X +3554(change)X +3809(must)X +3991(not)X +4120(cause)X +555 2265(confusion.)N +938(We)X +1077(use)X +1211(the)X +1336(technique)X +1675(described)X +2010(in)X +2099([LEHM81])X +2487(which)X +2710(exploits)X +2989(the)X +3113(ordering)X +3411(of)X +3504(data)X +3664(on)X +3770(a)X +3832(B-tree)X +4059(page)X +4237(to)X +555 2355(guarantee)N +888(that)X +1028(no)X +1128(process)X +1389(ever)X +1548(gets)X +1697(lost)X +1832(as)X +1919(a)X +1975(result)X +2173(of)X +2260(internal)X +2525(page)X +2697(updates)X +2962(made)X +3156(by)X +3256(other)X +3441(processes.)X +755 2478(If)N +836(a)X +899(transaction)X +1278(that)X +1425(updates)X +1697(a)X +1760(B-tree)X +1988(aborts,)X +2231(the)X +2356(user-visible)X +2757(changes)X +3043(to)X +3131(the)X +3255(tree)X +3402(must)X +3583(be)X +3685(rolled)X +3898(back.)X +4116(How-)X +555 2568(ever,)N +735(changes)X +1015(to)X +1097(the)X +1215(internal)X +1480(nodes)X +1687(of)X +1774(the)X +1892(tree)X +2033(need)X +2205(not)X +2327(be)X +2423(rolled)X +2630(back,)X +2822(since)X +3007(these)X +3192(pages)X +3395(contain)X +3651(no)X +3751(user-visible)X +4145(data.)X +555 2658(When)N +771(rolling)X +1008(back)X +1184(a)X +1244(transaction,)X +1640(we)X +1758(roll)X +1893(back)X +2069(all)X +2173(leaf)X +2318(page)X +2494(updates,)X +2783(but)X +2909(no)X +3013(internal)X +3281(insertions)X +3615(or)X +3705(page)X +3880(splits.)X +4111(In)X +4201(the)X +555 2748(worst)N +759(case,)X +944(this)X +1085(will)X +1235(leave)X +1431(a)X +1493(leaf)X +1640(page)X +1818(less)X +1964(than)X +2128(half)X +2279(full.)X +2456(This)X +2624(may)X +2788(cause)X +2993(poor)X +3166(space)X +3371(utilization,)X +3741(but)X +3869(does)X +4042(not)X +4170(lose)X +555 2838(user)N +709(data.)X +755 2961(Holding)N +1038(locks)X +1228(on)X +1329(leaf)X +1471(pages)X +1675(until)X +1842(transaction)X +2215(commit)X +2480(guarantees)X +2845(that)X +2986(no)X +3087(other)X +3273(process)X +3535(can)X +3668(insert)X +3866(or)X +3953(delete)X +4165(data)X +555 3051(that)N +711(has)X +854(been)X +1042(touched)X +1332(by)X +1448(this)X +1598(process.)X +1914(Rolling)X +2188(back)X +2375(insertions)X +2721(and)X +2872(deletions)X +3196(on)X +3311(leaf)X +3467(pages)X +3685(guarantees)X +4064(that)X +4219(no)X +555 3141(aborted)N +819(updates)X +1087(are)X +1209(ever)X +1371(visible)X +1607(to)X +1692(other)X +1880(transactions.)X +2326(Leaving)X +2612(page)X +2787(splits)X +2978(intact)X +3179(permits)X +3442(us)X +3536(to)X +3621(release)X +3867(internal)X +4134(write)X +555 3231(locks)N +744(early.)X +965(Thus)X +1145(transaction)X +1517(semantics)X +1853(are)X +1972(preserved,)X +2325(and)X +2461(locks)X +2650(are)X +2769(held)X +2927(for)X +3041(shorter)X +3284(periods.)X +755 3354(The)N +901(extra)X +1083(complexity)X +1464(introduced)X +1828(by)X +1929(this)X +2065(locking)X +2326(protocol)X +2614(appears)X +2881(substantial,)X +3264(but)X +3387(it)X +3452(is)X +3525(important)X +3856(for)X +3970(multi-user)X +555 3444(execution.)N +950(The)X +1118(bene\256ts)X +1410(of)X +1520(non-two-phase)X +2040(locking)X +2323(on)X +2446(B-trees)X +2721(are)X +2863(well)X +3044(established)X +3443(in)X +3548(the)X +3689(database)X +4009(literature)X +555 3534([BAY77],)N +899([LEHM81].)X +1320(If)X +1394(a)X +1450(process)X +1711(held)X +1869(locks)X +2058(until)X +2224(it)X +2288(committed,)X +2670(then)X +2828(a)X +2884(long-running)X +3322(update)X +3556(could)X +3754(lock)X +3912(out)X +4034(all)X +4134(other)X +555 3624(transactions)N +967(by)X +1076(preventing)X +1448(any)X +1593(other)X +1787(process)X +2057(from)X +2241(locking)X +2509(the)X +2635(root)X +2792(page)X +2972(of)X +3067(the)X +3193(tree.)X +3382(The)X +3535(B-tree)X +3764(locking)X +4032(protocol)X +555 3714(described)N +884(above)X +1096(guarantees)X +1460(that)X +1600(locks)X +1789(on)X +1889(internal)X +2154(pages)X +2357(are)X +2476(held)X +2634(for)X +2748(extremely)X +3089(short)X +3269(periods,)X +3545(thereby)X +3806(increasing)X +4156(con-)X +555 3804(currency.)N +3 f +555 3990(3.1.3.)N +775(Management)X +1245(of)X +1332(Shared)X +1596(Data)X +1 f +755 4113(Database)N +1075(systems)X +1353(permit)X +1587(many)X +1790(users)X +1980(to)X +2067(examine)X +2364(and)X +2505(update)X +2744(the)X +2866(same)X +3055(data)X +3213(concurrently.)X +3683(In)X +3774(order)X +3968(to)X +4054(provide)X +555 4203(this)N +702(concurrent)X +1078(access)X +1316(and)X +1464(enforce)X +1738(the)X +1868(write-ahead)X +2280(logging)X +2556(protocol)X +2855(described)X +3195(in)X +3289(section)X +3548(3.1.1,)X +3759(we)X +3884(use)X +4022(a)X +4089(shared)X +555 4293(memory)N +848(buffer)X +1071(manager.)X +1414(Not)X +1559(only)X +1726(does)X +1898(this)X +2038(provide)X +2308(the)X +2431(guarantees)X +2800(we)X +2919(require,)X +3192(but)X +3319(a)X +3380(user-level)X +3722(buffer)X +3944(manager)X +4246(is)X +555 4383(frequently)N +916(faster)X +1126(than)X +1295(using)X +1498(the)X +1626(\256le)X +1758(system)X +2010(buffer)X +2237(cache.)X +2491(Reads)X +2717(or)X +2814(writes)X +3040(involving)X +3376(the)X +3504(\256le)X +3636(system)X +3888(buffer)X +4115(cache)X +555 4473(often)N +746(require)X +1000(copying)X +1284(data)X +1444(between)X +1738(user)X +1898(and)X +2040(kernel)X +2266(space)X +2470(while)X +2673(a)X +2734(user-level)X +3076(buffer)X +3298(manager)X +3600(can)X +3737(return)X +3954(pointers)X +4237(to)X +555 4563(data)N +709(pages)X +912(directly.)X +1217(Additionally,)X +1661(if)X +1730(more)X +1915(than)X +2073(one)X +2209(process)X +2470(uses)X +2628(the)X +2746(same)X +2931(page,)X +3123(then)X +3281(fewer)X +3485(copies)X +3710(may)X +3868(be)X +3964(required.)X +3 f +555 4749(3.2.)N +715(Module)X +997(Architecture)X +1 f +755 4872(The)N +913(preceding)X +1262(sections)X +1552(described)X +1892(modules)X +2195(for)X +2321(managing)X +2669(the)X +2799(transaction)X +3183(log,)X +3337(locks,)X +3558(and)X +3706(a)X +3774(cache)X +3990(of)X +4089(shared)X +555 4962(buffers.)N +847(In)X +938(addition,)X +1244(we)X +1362(need)X +1538(to)X +1624(provide)X +1893(functionality)X +2326(for)X +2444(transaction)X +2 f +2819(begin)X +1 f +2997(,)X +2 f +3040(commit)X +1 f +3276(,)X +3319(and)X +2 f +3458(abort)X +1 f +3654(processing,)X +4040(necessi-)X +555 5052(tating)N +769(a)X +837(transaction)X +1221(manager.)X +1570(In)X +1669(order)X +1871(to)X +1965(arbitrate)X +2265(concurrent)X +2641(access)X +2879(to)X +2973(locks)X +3173(and)X +3320(buffers,)X +3599(we)X +3724(include)X +3991(a)X +4058(process)X +555 5142(management)N +995(module)X +1264(which)X +1489(manages)X +1799(a)X +1864(collection)X +2209(of)X +2305(semaphores)X +2713(used)X +2889(to)X +2980(block)X +3187(and)X +3332(release)X +3585(processes.)X +3962(Finally,)X +4237(in)X +555 5232(order)N +752(to)X +841(provide)X +1113(a)X +1176(simple,)X +1436(standard)X +1735(interface)X +2044(we)X +2165(have)X +2344(modi\256ed)X +2655(the)X +2780(database)X +3084(access)X +3317(routines)X +3602(\()X +3 f +3629(db)X +1 f +3717(\(3\)\).)X +3904(For)X +4041(the)X +4165(pur-)X +555 5322(poses)N +758(of)X +850(this)X +990(paper)X +1194(we)X +1313(call)X +1453(the)X +1575(modi\256ed)X +1883(package)X +2171(the)X +3 f +2293(Record)X +2567(Manager)X +1 f +2879(.)X +2943(Figure)X +3176(one)X +3316(shows)X +3540(the)X +3662(main)X +3846(interfaces)X +4183(and)X +555 5412(architecture)N +955(of)X +1042(LIBTP.)X + +5 p +%%Page: 5 5 +10 s 10 xH 0 xS 1 f +3 f +1 f +11 s +1851 1520(log_commit)N +2764 2077(buf_unpin)N +2764 1987(buf_get)N +3633 1408(buf_unpin)N +3633 1319(buf_pin)N +3633 1230(buf_get)N +3 f +17 s +1163 960(Txn)N +1430(M)X +1559(anager)X +2582(Record)X +3040(M)X +3169(anager)X +1 Dt +2363 726 MXY +0 355 Dl +1426 0 Dl +0 -355 Dl +-1426 0 Dl +3255 1616 MXY +0 535 Dl +534 0 Dl +0 -535 Dl +-534 0 Dl +2185 MX +0 535 Dl +535 0 Dl +0 -535 Dl +-535 0 Dl +1116 MX +0 535 Dl +534 0 Dl +0 -535 Dl +-534 0 Dl +726 MY +0 355 Dl +891 0 Dl +0 -355 Dl +-891 0 Dl +1 f +11 s +2207 1297(lock)N +2564 1386(log)N +865(unlock_all)X +1851 1609(log_unroll)N +1650 2508 MXY +0 178 Dl +1605 0 Dl +0 -178 Dl +-1605 0 Dl +1294 1616 MXY +19 -30 Dl +-19 11 Dl +-20 -11 Dl +20 30 Dl +0 -535 Dl +2319 2508 MXY +-22 -30 Dl +4 23 Dl +-18 14 Dl +36 -7 Dl +-936 -357 Dl +3277 2455(sleep_on)N +1405 1616 MXY +36 4 Dl +-18 -13 Dl +1 -22 Dl +-19 31 Dl +1070 -535 Dl +2631 2508 MXY +36 6 Dl +-18 -14 Dl +3 -22 Dl +-21 30 Dl +891 -357 Dl +1426 2455(sleep_on)N +3255 1884 MXY +-31 -20 Dl +11 20 Dl +-11 19 Dl +31 -19 Dl +-535 0 Dl +1554 2366(wake)N +3277(wake)X +2185 1884 MXY +-31 -20 Dl +12 20 Dl +-12 19 Dl +31 -19 Dl +-356 0 Dl +0 -803 Dl +3 f +17 s +1236 1851(Lock)N +1118 2030(M)N +1247(anager)X +2339 1851(Log)N +2187 2030(M)N +2316(anager)X +3333 1851(Buffer)N +3257 2030(M)N +3386(anager)X +3522 1616 MXY +20 -30 Dl +-20 11 Dl +-20 -11 Dl +20 30 Dl +0 -535 Dl +1950 2654(Process)N +2424(M)X +2553(anager)X +2542 1616 MXY +19 -30 Dl +-19 11 Dl +-20 -11 Dl +20 30 Dl +0 -535 Dl +1 f +11 s +2207 1364(unlock)N +2452 2508 MXY +20 -31 Dl +-20 11 Dl +-19 -11 Dl +19 31 Dl +0 -357 Dl +2497 2322(sleep_on)N +2497 2233(wake)N +3 Dt +-1 Ds +3 f +10 s +1790 2830(Figure)N +2037(1:)X +2144(Library)X +2435(module)X +2708(interfaces.)X +1 f +10 f +555 3010(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +3 f +555 3286(3.2.1.)N +775(The)X +928(Log)X +1081(Manager)X +1 f +755 3409(The)N +3 f +907(Log)X +1067(Manager)X +1 f +1406(enforces)X +1706(the)X +1831(write-ahead)X +2238(logging)X +2509(protocol.)X +2843(Its)X +2949(primitive)X +3268(operations)X +3628(are)X +2 f +3753(log)X +1 f +3855(,)X +2 f +3901(log_commit)X +1 f +4279(,)X +2 f +555 3499(log_read)N +1 f +844(,)X +2 f +889(log_roll)X +1 f +1171(and)X +2 f +1312(log_unroll)X +1 f +1649(.)X +1714(The)X +2 f +1864(log)X +1 f +1991(call)X +2132(performs)X +2447(a)X +2508(buffered)X +2806(write)X +2996(of)X +3088(the)X +3211(speci\256ed)X +3520(log)X +3646(record)X +3876(and)X +4016(returns)X +4263(a)X +555 3589(unique)N +809(log)X +947(sequence)X +1278(number)X +1559(\(LSN\).)X +1840(This)X +2017(LSN)X +2203(may)X +2376(then)X +2549(be)X +2660(used)X +2842(to)X +2939(retrieve)X +3220(a)X +3291(record)X +3532(from)X +3723(the)X +3856(log)X +3993(using)X +4201(the)X +2 f +555 3679(log_read)N +1 f +865(call.)X +1042(The)X +2 f +1188(log)X +1 f +1311(interface)X +1614(knows)X +1844(very)X +2008(little)X +2175(about)X +2374(the)X +2493(internal)X +2759(format)X +2993(of)X +3080(the)X +3198(log)X +3320(records)X +3577(it)X +3641(receives.)X +3965(Rather,)X +4219(all)X +555 3769(log)N +681(records)X +942(are)X +1065 0.4028(referenced)AX +1430(by)X +1534(a)X +1594(header)X +1833(structure,)X +2158(a)X +2218(log)X +2344(record)X +2574(type,)X +2756(and)X +2896(a)X +2956(character)X +3276(buffer)X +3497(containing)X +3859(the)X +3981(data)X +4138(to)X +4223(be)X +555 3859(logged.)N +834(The)X +980(log)X +1103(record)X +1330(type)X +1489(is)X +1563(used)X +1731(to)X +1814(call)X +1951(the)X +2070(appropriate)X +2457(redo)X +2621(and)X +2758(undo)X +2939(routines)X +3217(during)X +2 f +3446(abort)X +1 f +3639(and)X +2 f +3775(commit)X +1 f +4031(process-)X +555 3949(ing.)N +721(While)X +941(we)X +1059(have)X +1235(used)X +1406(the)X +3 f +1528(Log)X +1684(Manager)X +1 f +2019(to)X +2104(provide)X +2372(before)X +2601(and)X +2740(after)X +2911(image)X +3130(logging,)X +3417(it)X +3484(may)X +3645(also)X +3797(be)X +3896(used)X +4066(for)X +4183(any)X +555 4039(of)N +642(the)X +760(logging)X +1024(algorithms)X +1386(discussed.)X +755 4162(The)N +2 f +905(log_commit)X +1 f +1308(operation)X +1636(behaves)X +1920(exactly)X +2177(like)X +2322(the)X +2 f +2445(log)X +1 f +2572(operation)X +2900(but)X +3026(guarantees)X +3394(that)X +3538(the)X +3660(log)X +3786(has)X +3917(been)X +4093(forced)X +555 4252(to)N +643(disk)X +802(before)X +1034(returning.)X +1394(A)X +1478(discussion)X +1837(of)X +1930(our)X +2063(commit)X +2333(strategy)X +2613(appears)X +2884(in)X +2971(the)X +3094(implementation)X +3621(section)X +3873(\(section)X +4152(4.2\).)X +2 f +555 4342(Log_unroll)N +1 f +935(reads)X +1126(log)X +1249(records)X +1507(from)X +1684(the)X +1803(log,)X +1946(following)X +2278(backward)X +2611(transaction)X +2983(pointers)X +3261(and)X +3397(calling)X +3635(the)X +3753(appropriate)X +4139(undo)X +555 4432(routines)N +839(to)X +927(implement)X +1295(transaction)X +1673(abort.)X +1904(In)X +1997(a)X +2059(similar)X +2307(manner,)X +2 f +2594(log_roll)X +1 f +2877(reads)X +3073(log)X +3201(records)X +3464(sequentially)X +3877(forward,)X +4178(cal-)X +555 4522(ling)N +699(the)X +817(appropriate)X +1203(redo)X +1366(routines)X +1644(to)X +1726(recover)X +1988(committed)X +2350(transactions)X +2753(after)X +2921(a)X +2977(system)X +3219(crash.)X +3 f +555 4708(3.2.2.)N +775(The)X +928(Buffer)X +1171(Manager)X +1 f +755 4831(The)N +3 f +912(Buffer)X +1167(Manager)X +1 f +1511(uses)X +1681(a)X +1749(pool)X +1923(of)X +2022(shared)X +2264(memory)X +2563(to)X +2657(provide)X +2934(a)X +3002(least-recently-used)X +3641(\(LRU\))X +3886(block)X +4095(cache.)X +555 4921(Although)N +886(the)X +1013(current)X +1270(library)X +1513(provides)X +1818(an)X +1923(LRU)X +2112(cache,)X +2345(it)X +2418(would)X +2647(be)X +2752(simple)X +2994(to)X +3085(add)X +3229(alternate)X +3534(replacement)X +3955(policies)X +4232(as)X +555 5011(suggested)N +903(by)X +1015([CHOU85])X +1408(or)X +1507(to)X +1601(provide)X +1878(multiple)X +2176(buffer)X +2405(pools)X +2610(with)X +2784(different)X +3092(policies.)X +3412(Transactions)X +3853(request)X +4116(pages)X +555 5101(from)N +736(the)X +859(buffer)X +1081(manager)X +1383(and)X +1524(keep)X +1701(them)X +3 f +1886(pinned)X +1 f +2145(to)X +2232(ensure)X +2466(that)X +2610(they)X +2772(are)X +2895(not)X +3021(written)X +3272(to)X +3358(disk)X +3515(while)X +3717(they)X +3879(are)X +4002(in)X +4088(a)X +4148(logi-)X +555 5191(cally)N +732(inconsistent)X +1135(state.)X +1343(When)X +1556(page)X +1729(replacement)X +2143(is)X +2217(necessary,)X +2571(the)X +3 f +2689(Buffer)X +2932(Manager)X +1 f +3264(\256nds)X +3439(an)X +3535(unpinned)X +3853(page)X +4025(and)X +4161(then)X +555 5281(checks)N +794(with)X +956(the)X +3 f +1074(Log)X +1227(Manager)X +1 f +1559(to)X +1641(ensure)X +1871(that)X +2011(the)X +2129(write-ahead)X +2529(protocol)X +2816(is)X +2889(enforced.)X +3 f +555 5467(3.2.3.)N +775(The)X +928(Lock)X +1121(Manager)X +1 f +755 5590(The)N +3 f +901(Lock)X +1095(Manager)X +1 f +1428(supports)X +1720(general)X +1978(purpose)X +2253(locking)X +2514(\(single)X +2753(writer,)X +2986(multiple)X +3273(readers\))X +3553(which)X +3769(is)X +3842(currently)X +4152(used)X +555 5680(to)N +638(provide)X +904(two-phase)X +1254(locking)X +1514(and)X +1650(high)X +1812(concurrency)X +2230(B-tree)X +2451(locking.)X +2751(However,)X +3086(the)X +3204(general)X +3461(purpose)X +3735(nature)X +3956(of)X +4043(the)X +4161(lock)X + +6 p +%%Page: 6 6 +10 s 10 xH 0 xS 1 f +3 f +1 f +555 630(manager)N +857(provides)X +1158(the)X +1281(ability)X +1510(to)X +1597(support)X +1862(a)X +1923(variety)X +2171(of)X +2263(locking)X +2528(protocols.)X +2890(Currently,)X +3241(all)X +3345(locks)X +3538(are)X +3661(issued)X +3885(at)X +3967(the)X +4089(granu-)X +555 720(larity)N +747(of)X +837(a)X +896(page)X +1071(\(the)X +1219(size)X +1367(of)X +1457(a)X +1516(buffer)X +1736(in)X +1821(the)X +1942(buffer)X +2161(pool\))X +2352(which)X +2570(is)X +2645(identi\256ed)X +2969(by)X +3071(two)X +3213(4-byte)X +3440(integers)X +3716(\(a)X +3801(\256le)X +3925(id)X +4009(and)X +4147(page)X +555 810(number\).)N +898(This)X +1071(provides)X +1378(the)X +1507(necessary)X +1851(information)X +2259(to)X +2351(extend)X +2595(the)X +3 f +2723(Lock)X +2926(Manager)X +1 f +3268(to)X +3360(perform)X +3649(hierarchical)X +4059(locking)X +555 900([GRAY76].)N +982(The)X +1133(current)X +1387(implementation)X +1915(does)X +2088(not)X +2216(support)X +2482(locks)X +2677(at)X +2760(other)X +2950(granularities)X +3376(and)X +3517(does)X +3689(not)X +3816(promote)X +4108(locks;)X +555 990(these)N +740(are)X +859(obvious)X +1132(future)X +1344(additions)X +1657(to)X +1739(the)X +1857(system.)X +755 1113(If)N +831(an)X +929(incoming)X +1253(lock)X +1413(request)X +1667(cannot)X +1903(be)X +2001(granted,)X +2284(the)X +2404(requesting)X +2760(process)X +3023(is)X +3098(queued)X +3352(for)X +3467(the)X +3586(lock)X +3745(and)X +3882(descheduled.)X +555 1203(When)N +769(a)X +827(lock)X +987(is)X +1062(released,)X +1368(the)X +1488(wait)X +1647(queue)X +1860(is)X +1934(traversed)X +2250(and)X +2387(any)X +2524(newly)X +2741(compatible)X +3118(locks)X +3308(are)X +3428(granted.)X +3730(Locks)X +3947(are)X +4067(located)X +555 1293(via)N +680(a)X +743(\256le)X +872(and)X +1015(page)X +1194(hash)X +1368(table)X +1551(and)X +1694(are)X +1820(chained)X +2097(both)X +2266(by)X +2373(object)X +2595(and)X +2737(by)X +2843(transaction,)X +3241(facilitating)X +3614(rapid)X +3805(traversal)X +4108(of)X +4201(the)X +555 1383(lock)N +713(table)X +889(during)X +1118(transaction)X +1490(commit)X +1754(and)X +1890(abort.)X +755 1506(The)N +907(primary)X +1188(interfaces)X +1528(to)X +1617(the)X +1742(lock)X +1907(manager)X +2211(are)X +2 f +2337(lock)X +1 f +2471(,)X +2 f +2518(unlock)X +1 f +2732(,)X +2779(and)X +2 f +2922(lock_unlock_all)X +1 f +3434(.)X +2 f +3500(Lock)X +1 f +3682(obtains)X +3939(a)X +4001(new)X +4161(lock)X +555 1596(for)N +680(a)X +747(speci\256c)X +1023(object.)X +1290(There)X +1509(are)X +1638(also)X +1797(two)X +1947(variants)X +2231(of)X +2328(the)X +2 f +2456(lock)X +1 f +2620(request,)X +2 f +2902(lock_upgrade)X +1 f +3373(and)X +2 f +3519(lock_downgrade)X +1 f +4053(,)X +4103(which)X +555 1686(allow)N +755(the)X +875(caller)X +1076(to)X +1160(atomically)X +1519(trade)X +1701(a)X +1758(lock)X +1917(of)X +2005(one)X +2142(type)X +2301(for)X +2416(a)X +2473(lock)X +2632(of)X +2720(another.)X +2 f +3022(Unlock)X +1 f +3275(releases)X +3551(a)X +3608(speci\256c)X +3874(mode)X +4073(of)X +4161(lock)X +555 1776(on)N +655(a)X +711(speci\256c)X +976(object.)X +2 f +1232(Lock_unlock_all)X +1 f +1786(releases)X +2061(all)X +2161(the)X +2279(locks)X +2468(associated)X +2818(with)X +2980(a)X +3036(speci\256c)X +3301(transaction.)X +3 f +555 1962(3.2.4.)N +775(The)X +928(Process)X +1207(Manager)X +1 f +755 2085(The)N +3 f +900(Process)X +1179(Manager)X +1 f +1511(acts)X +1656(as)X +1743(a)X +1799(user-level)X +2136(scheduler)X +2464(to)X +2546(make)X +2740(processes)X +3068(wait)X +3226(on)X +3326(unavailable)X +3716(locks)X +3905(and)X +4041(pending)X +555 2175(buffer)N +778(cache)X +988(I/O.)X +1161(For)X +1297(each)X +1470(process,)X +1756(a)X +1817(semaphore)X +2190(is)X +2268(maintained)X +2649(upon)X +2834(which)X +3055(that)X +3200(process)X +3466(waits)X +3660(when)X +3859(it)X +3928(needs)X +4136(to)X +4223(be)X +555 2265(descheduled.)N +1014(When)X +1228(a)X +1286(process)X +1549(needs)X +1754(to)X +1838(be)X +1936(run,)X +2084(its)X +2180(semaphore)X +2549(is)X +2623(cleared,)X +2897(and)X +3034(the)X +3153(operating)X +3477(system)X +3720(reschedules)X +4116(it.)X +4201(No)X +555 2355(sophisticated)N +1002(scheduling)X +1378(algorithm)X +1718(is)X +1799(applied;)X +2085(if)X +2162(the)X +2288(lock)X +2454(for)X +2576(which)X +2800(a)X +2864(process)X +3133(was)X +3286(waiting)X +3554(becomes)X +3863(available,)X +4201(the)X +555 2445(process)N +824(is)X +905(made)X +1107(runnable.)X +1456(It)X +1533(would)X +1761(have)X +1941(been)X +2121(possible)X +2411(to)X +2501(change)X +2757(the)X +2883(kernel's)X +3170(process)X +3439(scheduler)X +3775(to)X +3865(interact)X +4134(more)X +555 2535(ef\256ciently)N +900(with)X +1062(the)X +1180(lock)X +1338(manager,)X +1655(but)X +1777(doing)X +1979(so)X +2070(would)X +2290(have)X +2462(compromised)X +2918(our)X +3045(commitment)X +3469(to)X +3551(a)X +3607(user-level)X +3944(package.)X +3 f +555 2721(3.2.5.)N +775(The)X +928(Transaction)X +1361(Manager)X +1 f +755 2844(The)N +3 f +901(Transaction)X +1335(Manager)X +1 f +1668(provides)X +1965(the)X +2084(standard)X +2377(interface)X +2680(of)X +2 f +2768(txn_begin)X +1 f +3084(,)X +2 f +3125(txn_commit)X +1 f +3499(,)X +3540(and)X +2 f +3676(txn_abort)X +1 f +3987(.)X +4047(It)X +4116(keeps)X +555 2934(track)N +742(of)X +835(all)X +941(active)X +1159(transactions,)X +1588(assigns)X +1845(unique)X +2089(transaction)X +2467(identi\256ers,)X +2833(and)X +2974(directs)X +3213(the)X +3336(abort)X +3526(and)X +3667(commit)X +3936(processing.)X +555 3024(When)N +772(a)X +2 f +833(txn_begin)X +1 f +1174(is)X +1252(issued,)X +1497(the)X +3 f +1620(Transaction)X +2058(Manager)X +1 f +2395(assigns)X +2651(the)X +2773(next)X +2935(available)X +3249(transaction)X +3625(identi\256er,)X +3958(allocates)X +4263(a)X +555 3114(per-process)N +948(transaction)X +1322(structure)X +1625(in)X +1709(shared)X +1941(memory,)X +2249(increments)X +2622(the)X +2741(count)X +2940(of)X +3028(active)X +3241(transactions,)X +3665(and)X +3802(returns)X +4046(the)X +4165(new)X +555 3204(transaction)N +937(identi\256er)X +1256(to)X +1348(the)X +1476(calling)X +1724(process.)X +2034(The)X +2188(in-memory)X +2573(transaction)X +2954(structure)X +3264(contains)X +3560(a)X +3625(pointer)X +3881(into)X +4034(the)X +4161(lock)X +555 3294(table)N +734(for)X +851(locks)X +1043(held)X +1204(by)X +1307(this)X +1445(transaction,)X +1840(the)X +1961(last)X +2095(log)X +2220(sequence)X +2538(number,)X +2826(a)X +2885(transaction)X +3260(state)X +3430(\()X +2 f +3457(idle)X +1 f +(,)S +2 f +3620(running)X +1 f +3873(,)X +2 f +3915(aborting)X +1 f +4190(,)X +4232(or)X +2 f +555 3384(committing\))N +1 f +942(,)X +982(an)X +1078(error)X +1255(code,)X +1447(and)X +1583(a)X +1639(semaphore)X +2007(identi\256er.)X +755 3507(At)N +859(commit,)X +1147(the)X +3 f +1269(Transaction)X +1706(Manager)X +1 f +2042(calls)X +2 f +2213(log_commit)X +1 f +2615(to)X +2700(record)X +2929(the)X +3050(end)X +3189(of)X +3279(transaction)X +3654(and)X +3793(to)X +3878(\257ush)X +4056(the)X +4177(log.)X +555 3597(Then)N +743(it)X +810(directs)X +1047(the)X +3 f +1168(Lock)X +1364(Manager)X +1 f +1699(to)X +1784(release)X +2031(all)X +2134(locks)X +2325(associated)X +2677(with)X +2841(the)X +2961(given)X +3161(transaction.)X +3575(If)X +3651(a)X +3709(transaction)X +4083(aborts,)X +555 3687(the)N +3 f +680(Transaction)X +1120(Manager)X +1 f +1459(calls)X +1633(on)X +2 f +1739(log_unroll)X +1 f +2102(to)X +2190(read)X +2355(the)X +2479(transaction's)X +2915(log)X +3043(records)X +3306(and)X +3448(undo)X +3634(any)X +3776(modi\256cations)X +4237(to)X +555 3777(the)N +673(database.)X +1010(As)X +1119(in)X +1201(the)X +1319(commit)X +1583(case,)X +1762(it)X +1826(then)X +1984(calls)X +2 f +2151(lock_unlock_all)X +1 f +2683(to)X +2765(release)X +3009(the)X +3127(transaction's)X +3557(locks.)X +3 f +555 3963(3.2.6.)N +775(The)X +928(Record)X +1198(Manager)X +1 f +755 4086(The)N +3 f +919(Record)X +1208(Manager)X +1 f +1559(supports)X +1869(the)X +2006(abstraction)X +2397(of)X +2503(reading)X +2783(and)X +2938(writing)X +3208(records)X +3484(to)X +3585(a)X +3660(database.)X +3996(We)X +4147(have)X +555 4176(modi\256ed)N +861(the)X +981(the)X +1101(database)X +1399(access)X +1626(routines)X +3 f +1905(db)X +1 f +1993(\(3\))X +2108([BSD91])X +2418(to)X +2501(call)X +2638(the)X +2757(log,)X +2900(lock,)X +3079(and)X +3216(buffer)X +3434(managers.)X +3803(In)X +3891(order)X +4082(to)X +4165(pro-)X +555 4266(vide)N +718(functionality)X +1152(to)X +1239(perform)X +1523(undo)X +1708(and)X +1849(redo,)X +2037(the)X +3 f +2160(Record)X +2434(Manager)X +1 f +2770(de\256nes)X +3021(a)X +3081(collection)X +3421(of)X +3512(log)X +3638(record)X +3868(types)X +4061(and)X +4201(the)X +555 4356(associated)N +920(undo)X +1115(and)X +1266(redo)X +1444(routines.)X +1777(The)X +3 f +1937(Log)X +2105(Manager)X +1 f +2452(performs)X +2777(a)X +2848(table)X +3039(lookup)X +3296(on)X +3411(the)X +3543(record)X +3783(type)X +3955(to)X +4051(call)X +4201(the)X +555 4446(appropriate)N +951(routines.)X +1299(For)X +1440(example,)X +1762(the)X +1890(B-tree)X +2121(access)X +2356(method)X +2625(requires)X +2913(two)X +3062(log)X +3193(record)X +3428(types:)X +3648(insert)X +3855(and)X +4000(delete.)X +4241(A)X +555 4536(replace)N +808(operation)X +1131(is)X +1204(implemented)X +1642(as)X +1729(a)X +1785(delete)X +1997(followed)X +2302(by)X +2402(an)X +2498(insert)X +2696(and)X +2832(is)X +2905(logged)X +3143(accordingly.)X +3 f +555 4722(3.3.)N +715(Application)X +1134(Architectures)X +1 f +755 4845(The)N +907(structure)X +1215(of)X +1309(LIBTP)X +1558(allows)X +1794(application)X +2177(designers)X +2507(to)X +2596(trade)X +2784(off)X +2905(performance)X +3339(and)X +3481(protection.)X +3872(Since)X +4076(a)X +4138(large)X +555 4935(portion)N +810(of)X +901(LIBTP's)X +1205(functionality)X +1638(is)X +1715(provided)X +2024(by)X +2128(managing)X +2468(structures)X +2804(in)X +2889(shared)X +3122(memory,)X +3432(its)X +3530(structures)X +3865(are)X +3987(subject)X +4237(to)X +555 5025(corruption)N +926(by)X +1043(applications)X +1467(when)X +1678(the)X +1813(library)X +2064(is)X +2154(linked)X +2391(directly)X +2673(with)X +2852(the)X +2987(application.)X +3420(For)X +3568(this)X +3720(reason,)X +3987(LIBTP)X +4246(is)X +555 5115(designed)N +864(to)X +950(allow)X +1152(compilation)X +1558(into)X +1706(a)X +1766(separate)X +2053(server)X +2273(process)X +2537(which)X +2756(may)X +2917(be)X +3016(accessed)X +3321(via)X +3442(a)X +3501(socket)X +3729(interface.)X +4094(In)X +4184(this)X +555 5205(way)N +712(LIBTP's)X +1015(data)X +1172(structures)X +1507(are)X +1629(protected)X +1951(from)X +2130(application)X +2509(code,)X +2704(but)X +2829(communication)X +3349(overhead)X +3666(is)X +3741(increased.)X +4107(When)X +555 5295(applications)N +975(are)X +1107(trusted,)X +1377(LIBTP)X +1631(may)X +1801(be)X +1909(compiled)X +2239(directly)X +2516(into)X +2672(the)X +2802(application)X +3190(providing)X +3533(improved)X +3872(performance.)X +555 5385(Figures)N +815(two)X +955(and)X +1091(three)X +1272(show)X +1461(the)X +1579(two)X +1719(alternate)X +2016(application)X +2392(architectures.)X +755 5508(There)N +964(are)X +1084(potentially)X +1447(two)X +1588(modes)X +1818(in)X +1901(which)X +2118(one)X +2255(might)X +2462(use)X +2590(LIBTP)X +2833(in)X +2916(a)X +2972(server)X +3189(based)X +3392(architecture.)X +3832(In)X +3919(the)X +4037(\256rst,)X +4201(the)X +555 5598(server)N +778(would)X +1004(provide)X +1275(the)X +1399(capability)X +1741(to)X +1829(respond)X +2109(to)X +2197(requests)X +2486(to)X +2574(each)X +2747(of)X +2839(the)X +2962(low)X +3107(level)X +3288(modules)X +3584(\(lock,)X +3794(log,)X +3941(buffer,)X +4183(and)X +555 5688(transaction)N +944(managers\).)X +1356(Unfortunately,)X +1863(the)X +1998(performance)X +2442(of)X +2546(such)X +2730(a)X +2803(system)X +3062(is)X +3152(likely)X +3371(to)X +3470(be)X +3583(blindingly)X +3947(slow)X +4134(since)X + +7 p +%%Page: 7 7 +10 s 10 xH 0 xS 1 f +3 f +1 f +1 Dt +1864 1125 MXY +15 -26 Dl +-15 10 Dl +-14 -10 Dl +14 26 Dl +0 -266 Dl +1315 1125 MXY +15 -26 Dl +-15 10 Dl +-14 -10 Dl +14 26 Dl +0 -266 Dl +3 Dt +1133 1125 MXY +0 798 Dl +931 0 Dl +0 -798 Dl +-931 0 Dl +1 Dt +1266 1257 MXY +0 133 Dl +665 0 Dl +0 -133 Dl +-665 0 Dl +3 f +8 s +1513 1351(driver)N +1502 1617(LIBTP)N +1266 1390 MXY +0 400 Dl +665 0 Dl +0 -400 Dl +-665 0 Dl +3 Dt +1133 726 MXY +0 133 Dl +931 0 Dl +0 -133 Dl +-931 0 Dl +1 f +1029 1098(txn_abort)N +964 1015(txn_commit)N +1018 932(txn_begin)N +1910 1015(db_ops)N +3 f +1308 820(Application)N +1645(Program)X +1398 1218(Server)N +1594(Process)X +1 f +1390 986(socket)N +1569(interface)X +1 Dt +1848 967 MXY +-23 -14 Dl +8 14 Dl +-8 15 Dl +23 -15 Dl +-50 0 Dl +1324 MX +23 15 Dl +-9 -15 Dl +9 -14 Dl +-23 14 Dl +50 0 Dl +3 Dt +2862 859 MXY +0 1064 Dl +932 0 Dl +0 -1064 Dl +-932 0 Dl +1 Dt +3178 1390 MXY +24 -12 Dl +-17 0 Dl +-8 -15 Dl +1 27 Dl +150 -265 Dl +3494 1390 MXY +0 -27 Dl +-8 15 Dl +-16 1 Dl +24 11 Dl +-166 -265 Dl +3 f +3232 1617(LIBTP)N +2995 1390 MXY +0 400 Dl +666 0 Dl +0 -400 Dl +-666 0 Dl +992 MY +0 133 Dl +666 0 Dl +0 -133 Dl +-666 0 Dl +3168 1086(Application)N +1 f +2939 1201(txn_begin)N +2885 1284(txn_commit)N +2950 1368(txn_abort)N +3465 1284(db_ops)N +3 f +3155 766(Single)N +3339(Process)X +3 Dt +-1 Ds +811 2100(Figure)N +1023(2:)X +1107(Server)X +1318(Architecture.)X +1 f +1727(In)X +1811(this)X +1934(con\256guration,)X +811 2190(the)N +916(library)X +1113(is)X +1183(loaded)X +1380(into)X +1507(a)X +1562(server)X +1744(process)X +1962(which)X +2145(is)X +2214(ac-)X +811 2280(cessed)N +993(via)X +1087(a)X +1131(socket)X +1310(interface.)X +3 f +2563 2100(Figure)N +2803(3:)X +2914(Single)X +3140(Process)X +3403(Architecture.)X +1 f +3839(In)X +3950(this)X +2563 2190(con\256guration,)N +2948(the)X +3053(library)X +3250(routines)X +3483(are)X +3587(loaded)X +3784(as)X +3864(part)X +3990(of)X +2563 2280(the)N +2657(application)X +2957(and)X +3065(accessed)X +3303(via)X +3397(a)X +3441(subroutine)X +3727(interface.)X +10 s +10 f +555 2403(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +1 f +555 2679(modifying)N +909(a)X +966(piece)X +1157(of)X +1245(data)X +1400(would)X +1621(require)X +1870(three)X +2051(or)X +2138(possibly)X +2424(four)X +2578(separate)X +2862(communications:)X +3433(one)X +3569(to)X +3651(lock)X +3809(the)X +3927(data,)X +4101(one)X +4237(to)X +555 2769(obtain)N +781(the)X +905(data,)X +1085(one)X +1227(to)X +1315(log)X +1443(the)X +1567(modi\256cation,)X +2017(and)X +2159(possibly)X +2451(one)X +2593(to)X +2681(transmit)X +2969(the)X +3093(modi\256ed)X +3403(data.)X +3583(Figure)X +3817(four)X +3976(shows)X +4201(the)X +555 2859(relative)N +826(performance)X +1263(for)X +1387(retrieving)X +1728(a)X +1793(single)X +2013(record)X +2248(using)X +2450(the)X +2577(record)X +2812(level)X +2997(call)X +3142(versus)X +3376(using)X +3578(the)X +3705(lower)X +3917(level)X +4102(buffer)X +555 2949(management)N +987(and)X +1125(locking)X +1387(calls.)X +1616(The)X +1763(2:1)X +1887(ratio)X +2056(observed)X +2367(in)X +2450(the)X +2569(single)X +2781(process)X +3043(case)X +3203(re\257ects)X +3456(the)X +3575(additional)X +3916(overhead)X +4232(of)X +555 3039(parsing)N +819(eight)X +1006(commands)X +1380(rather)X +1595(than)X +1760(one)X +1903(while)X +2108(the)X +2233(3:1)X +2362(ratio)X +2536(observed)X +2853(in)X +2942(the)X +3067(client/server)X +3491(architecture)X +3898(re\257ects)X +4157(both)X +555 3129(the)N +679(parsing)X +941(and)X +1083(the)X +1207(communication)X +1731(overheard.)X +2118(Although)X +2445(there)X +2631(may)X +2794(be)X +2895(applications)X +3307(which)X +3528(could)X +3731(tolerate)X +3997(such)X +4169(per-)X +555 3219(formance,)N +904(it)X +973(seems)X +1194(far)X +1309(more)X +1499(feasible)X +1774(to)X +1861(support)X +2126(a)X +2187(higher)X +2417(level)X +2597(interface,)X +2923(such)X +3094(as)X +3185(that)X +3329(provided)X +3638(by)X +3742(a)X +3802(query)X +4009(language)X +555 3309(\()N +2 f +582(e.g.)X +1 f +718(SQL)X +889([SQL86]\).)X +755 3432(Although)N +1081(LIBTP)X +1327(does)X +1498(not)X +1624(have)X +1800(an)X +1900(SQL)X +2075(parser,)X +2316(we)X +2433(have)X +2608(built)X +2777(a)X +2836(server)X +3056(application)X +3435(using)X +3631(the)X +3752(toolkit)X +3983(command)X +555 3522(language)N +882(\(TCL\))X +1124([OUST90].)X +1544(The)X +1706(server)X +1940(supports)X +2248(a)X +2321(command)X +2674(line)X +2831(interface)X +3150(similar)X +3409(to)X +3508(the)X +3643(subroutine)X +4017(interface)X +555 3612(de\256ned)N +811(in)X +3 f +893(db)X +1 f +981(\(3\).)X +1135(Since)X +1333(it)X +1397(is)X +1470(based)X +1673(on)X +1773(TCL,)X +1964(it)X +2028(provides)X +2324(control)X +2571(structures)X +2903(as)X +2990(well.)X +3 f +555 3798(4.)N +655(Implementation)X +1 f +3 f +555 3984(4.1.)N +715(Locking)X +1014(and)X +1162(Deadlock)X +1502(Detection)X +1 f +755 4107(LIBTP)N +1007(uses)X +1175(two-phase)X +1535(locking)X +1805(for)X +1929(user)X +2093(data.)X +2297(Strictly)X +2562(speaking,)X +2897(the)X +3024(two)X +3173(phases)X +3416(in)X +3507(two-phase)X +3866(locking)X +4135(are)X +4263(a)X +3 f +555 4197(grow)N +1 f +756(phase,)X +986(during)X +1221(which)X +1443(locks)X +1638(are)X +1763(acquired,)X +2086(and)X +2228(a)X +3 f +2290(shrink)X +1 f +2537(phase,)X +2766(during)X +3001(which)X +3223(locks)X +3418(are)X +3543(released.)X +3873(No)X +3997(lock)X +4161(may)X +555 4287(ever)N +720(be)X +822(acquired)X +1124(during)X +1358(the)X +1481(shrink)X +1706(phase.)X +1954(The)X +2104(grow)X +2294(phase)X +2502(lasts)X +2669(until)X +2840(the)X +2963(\256rst)X +3112(release,)X +3381(which)X +3602(marks)X +3823(the)X +3946(start)X +4109(of)X +4201(the)X +555 4377(shrink)N +780(phase.)X +1028(In)X +1120(practice,)X +1420(the)X +1543(grow)X +1733(phase)X +1941(lasts)X +2108(for)X +2227(the)X +2350(duration)X +2642(of)X +2734(a)X +2795(transaction)X +3172(in)X +3259(LIBTP)X +3506(and)X +3647(in)X +3734(commercial)X +4138(data-)X +555 4467(base)N +721(systems.)X +1037(The)X +1184(shrink)X +1406(phase)X +1611(takes)X +1798(place)X +1990(during)X +2221(transaction)X +2595(commit)X +2861(or)X +2950(abort.)X +3177(This)X +3341(means)X +3568(that)X +3710(locks)X +3901(are)X +4022(acquired)X +555 4557(on)N +655(demand)X +929(during)X +1158(the)X +1276(lifetime)X +1545(of)X +1632(a)X +1688(transaction,)X +2080(and)X +2216(held)X +2374(until)X +2540(commit)X +2804(time,)X +2986(at)X +3064(which)X +3280(point)X +3464(all)X +3564(locks)X +3753(are)X +3872(released.)X +755 4680(If)N +832(multiple)X +1121(transactions)X +1527(are)X +1649(active)X +1864(concurrently,)X +2313(deadlocks)X +2657(can)X +2792(occur)X +2994(and)X +3133(must)X +3311(be)X +3410(detected)X +3701(and)X +3840(resolved.)X +4174(The)X +555 4770(lock)N +715(table)X +893(can)X +1027(be)X +1125(thought)X +1391(of)X +1480(as)X +1569(a)X +1627(representation)X +2104(of)X +2193(a)X +2251(directed)X +2532(graph.)X +2777(The)X +2924(nodes)X +3133(in)X +3216(the)X +3335(graph)X +3539(are)X +3659(transactions.)X +4103(Edges)X +555 4860(represent)N +878(the)X +3 f +1004(waits-for)X +1 f +1340(relation)X +1613(between)X +1909(transactions;)X +2342(if)X +2419(transaction)X +2 f +2799(A)X +1 f +2876(is)X +2957(waiting)X +3225(for)X +3347(a)X +3411(lock)X +3577(held)X +3743(by)X +3851(transaction)X +2 f +4230(B)X +1 f +4279(,)X +555 4950(then)N +716(a)X +775(directed)X +1057(edge)X +1232(exists)X +1437(from)X +2 f +1616(A)X +1 f +1687(to)X +2 f +1771(B)X +1 f +1842(in)X +1926(the)X +2046(graph.)X +2291(A)X +2371(deadlock)X +2683(exists)X +2887(if)X +2958(a)X +3016(cycle)X +3208(appears)X +3476(in)X +3560(the)X +3680(graph.)X +3925(By)X +4040(conven-)X +555 5040(tion,)N +719(no)X +819(transaction)X +1191(ever)X +1350(waits)X +1539(for)X +1653(a)X +1709(lock)X +1867(it)X +1931(already)X +2188(holds,)X +2401(so)X +2492(re\257exive)X +2793(edges)X +2996(are)X +3115(impossible.)X +755 5163(A)N +836(distinguished)X +1285(process)X +1549(monitors)X +1856(the)X +1977(lock)X +2138(table,)X +2337(searching)X +2668(for)X +2785(cycles.)X +3048(The)X +3195(frequency)X +3539(with)X +3703(which)X +3921(this)X +4058(process)X +555 5253(runs)N +716(is)X +792(user-settable;)X +1243(for)X +1360(the)X +1481(multi-user)X +1833(tests)X +1998(discussed)X +2328(in)X +2413(section)X +2663(5.1.2,)X +2866(it)X +2933(has)X +3063(been)X +3238(set)X +3350(to)X +3435(wake)X +3628(up)X +3731(every)X +3932(second,)X +4197(but)X +555 5343(more)N +742(sophisticated)X +1182(schedules)X +1516(are)X +1636(certainly)X +1938(possible.)X +2261(When)X +2474(a)X +2531(cycle)X +2722(is)X +2796(detected,)X +3105(one)X +3242(of)X +3330(the)X +3449(transactions)X +3853(in)X +3936(the)X +4055(cycle)X +4246(is)X +555 5433(nominated)N +917(and)X +1057(aborted.)X +1362(When)X +1578(the)X +1700(transaction)X +2076(aborts,)X +2315(it)X +2382(rolls)X +2547(back)X +2722(its)X +2820(changes)X +3102(and)X +3241(releases)X +3519(its)X +3617(locks,)X +3829(thereby)X +4093(break-)X +555 5523(ing)N +677(the)X +795(cycle)X +985(in)X +1067(the)X +1185(graph.)X + +8 p +%%Page: 8 8 +10 s 10 xH 0 xS 1 f +3 f +1 f +4 Ds +1 Dt +1866 865 MXY +1338 0 Dl +1866 1031 MXY +1338 0 Dl +1866 1199 MXY +1338 0 Dl +1866 1366 MXY +1338 0 Dl +1866 1533 MXY +1338 0 Dl +1866 1701 MXY +1338 0 Dl +-1 Ds +5 Dt +1866 1868 MXY +1338 0 Dl +1 Dt +1 Di +2981 MX + 2981 1868 lineto + 2981 1575 lineto + 3092 1575 lineto + 3092 1868 lineto + 2981 1868 lineto +closepath 21 2981 1575 3092 1868 Dp +2646 MX + 2646 1868 lineto + 2646 949 lineto + 2758 949 lineto + 2758 1868 lineto + 2646 1868 lineto +closepath 14 2646 949 2758 1868 Dp +2312 MX + 2312 1868 lineto + 2312 1701 lineto + 2423 1701 lineto + 2423 1868 lineto + 2312 1868 lineto +closepath 3 2312 1701 2423 1868 Dp +1977 MX + 1977 1868 lineto + 1977 1512 lineto + 2089 1512 lineto + 2089 1868 lineto + 1977 1868 lineto +closepath 19 1977 1512 2089 1868 Dp +3 f +2640 2047(Client/Server)N +1957(Single)X +2185(Process)X +7 s +2957 1957(record)N +2570(component)X +2289(record)X +1890(components)X +1733 1724(.1)N +1733 1556(.2)N +1733 1389(.3)N +1733 1222(.4)N +1733 1055(.5)N +1733 889(.6)N +1590 726(Elapsed)N +1794(Time)X +1613 782(\(in)N +1693(seconds\))X +3 Dt +-1 Ds +8 s +555 2255(Figure)N +756(4:)X +829(Comparison)X +1187(of)X +1260(High)X +1416(and)X +1540(Low)X +1681(Level)X +1850(Interfaces.)X +1 f +2174(Elapsed)X +2395(time)X +2528(in)X +2597(seconds)X +2818(to)X +2887(perform)X +3111(a)X +3158(single)X +3330(record)X +3511(retrieval)X +3742(from)X +3885(a)X +3932(command)X +4203(line)X +555 2345(\(rather)N +751(than)X +888(a)X +943(procedural)X +1241(interface\))X +1510(is)X +1579(shown)X +1772(on)X +1862(the)X +1966(y)X +2024(axis.)X +2185(The)X +2310(``component'')X +2704(numbers)X +2950(re\257ect)X +3135(the)X +3239(timings)X +3458(when)X +3622(the)X +3726(record)X +3914(is)X +3983(retrieved)X +4235(by)X +555 2435(separate)N +785(calls)X +924(to)X +996(the)X +1096(lock)X +1228(manager)X +1469(and)X +1583(buffer)X +1760(manager)X +2001(while)X +2165(the)X +2264(``record'')X +2531(timings)X +2745(were)X +2889(obtained)X +3130(by)X +3215(using)X +3375(a)X +3424(single)X +3598(call)X +3711(to)X +3782(the)X +3881(record)X +4064(manager.)X +555 2525(The)N +674(2:1)X +776(ratio)X +913(observed)X +1163(for)X +1257(the)X +1355(single)X +1528(process)X +1739(case)X +1868(is)X +1930(a)X +1977(re\257ection)X +2237(of)X +2309(the)X +2406(parsing)X +2613(overhead)X +2865(for)X +2958(executing)X +3225(eight)X +3372(separate)X +3599(commands)X +3895(rather)X +4062(than)X +4191(one.)X +555 2615(The)N +673(additional)X +948(factor)X +1115(of)X +1187(one)X +1298(re\257ected)X +1536(in)X +1605(the)X +1702(3:1)X +1803(ratio)X +1939(for)X +2031(the)X +2127(client/server)X +2460(architecture)X +2794(is)X +2855(due)X +2965(to)X +3033(the)X +3129(communication)X +3545(overhead.)X +3828(The)X +3945(true)X +4062(ratios)X +4222(are)X +555 2705(actually)N +775(worse)X +945(since)X +1094(the)X +1190(component)X +1492(timings)X +1703(do)X +1785(not)X +1884(re\257ect)X +2060(the)X +2155(search)X +2334(times)X +2490(within)X +2671(each)X +2804(page)X +2941(or)X +3011(the)X +3106(time)X +3237(required)X +3466(to)X +3533(transmit)X +3760(the)X +3855(page)X +3992(between)X +4221(the)X +555 2795(two)N +667(processes.)X +10 s +10 f +555 2885(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +3 f +555 3161(4.2.)N +715(Group)X +961(Commit)X +1 f +755 3284(Since)N +959(the)X +1083(log)X +1211(must)X +1392(be)X +1494(\257ushed)X +1751(to)X +1839(disk)X +1997(at)X +2080(commit)X +2349(time,)X +2536(disk)X +2694(bandwidth)X +3057(fundamentally)X +3545(limits)X +3751(the)X +3874(rate)X +4020(at)X +4103(which)X +555 3374(transactions)N +959(complete.)X +1314(Since)X +1513(most)X +1688(transactions)X +2091(write)X +2276(only)X +2438(a)X +2494(few)X +2635(small)X +2828(records)X +3085(to)X +3167(the)X +3285(log,)X +3427(the)X +3545(last)X +3676(page)X +3848(of)X +3935(the)X +4053(log)X +4175(will)X +555 3464(be)N +658(\257ushed)X +916(once)X +1095(by)X +1202(every)X +1408(transaction)X +1787(which)X +2010(writes)X +2233(to)X +2322(it.)X +2433(In)X +2527(the)X +2652(naive)X +2853(implementation,)X +3402(these)X +3593(\257ushes)X +3841(would)X +4067(happen)X +555 3554(serially.)N +755 3677(LIBTP)N +1008(uses)X +3 f +1177(group)X +1412(commit)X +1 f +1702([DEWI84])X +2077(in)X +2170(order)X +2371(to)X +2464(amortize)X +2775(the)X +2903(cost)X +3062(of)X +3159(one)X +3305(synchronous)X +3740(disk)X +3903(write)X +4098(across)X +555 3767(multiple)N +851(transactions.)X +1304(Group)X +1539(commit)X +1812(provides)X +2117(a)X +2182(way)X +2345(for)X +2468(a)X +2533(group)X +2749(of)X +2845(transactions)X +3257(to)X +3348(commit)X +3621(simultaneously.)X +4174(The)X +555 3857(\256rst)N +709(several)X +967(transactions)X +1380(to)X +1472(commit)X +1745(write)X +1939(their)X +2115(changes)X +2403(to)X +2494(the)X +2621(in-memory)X +3006(log)X +3137(page,)X +3338(then)X +3505(sleep)X +3699(on)X +3808(a)X +3873(distinguished)X +555 3947(semaphore.)N +966(Later,)X +1179(a)X +1238(committing)X +1629(transaction)X +2004(\257ushes)X +2249(the)X +2370(page)X +2545(to)X +2630(disk,)X +2805(and)X +2943(wakes)X +3166(up)X +3268(all)X +3370(its)X +3467(sleeping)X +3756(peers.)X +3988(The)X +4135(point)X +555 4037(at)N +635(which)X +853(changes)X +1134(are)X +1255(actually)X +1531(written)X +1780(is)X +1855(determined)X +2238(by)X +2340(three)X +2523(thresholds.)X +2914(The)X +3061(\256rst)X +3207(is)X +3281(the)X +2 f +3400(group)X +3612(threshold)X +1 f +3935(and)X +4072(de\256nes)X +555 4127(the)N +674(minimum)X +1005(number)X +1271(of)X +1359(transactions)X +1763(which)X +1979(must)X +2154(be)X +2250(active)X +2462(in)X +2544(the)X +2662(system)X +2904(before)X +3130(transactions)X +3533(are)X +3652(forced)X +3878(to)X +3960(participate)X +555 4217(in)N +646(a)X +711(group)X +927(commit.)X +1240(The)X +1394(second)X +1646(is)X +1728(the)X +2 f +1855(wait)X +2021(threshold)X +1 f +2352(which)X +2577(is)X +2658(expressed)X +3003(as)X +3098(the)X +3224(percentage)X +3601(of)X +3696(active)X +3916(transactions)X +555 4307(waiting)N +826(to)X +919(be)X +1026(committed.)X +1439(The)X +1595(last)X +1737(is)X +1821(the)X +2 f +1950(logdelay)X +2257(threshold)X +1 f +2590(which)X +2816(indicates)X +3131(how)X +3299(much)X +3507(un\257ushed)X +3848(log)X +3980(should)X +4223(be)X +555 4397(allowed)N +829(to)X +911(accumulate)X +1297(before)X +1523(a)X +1579(waiting)X +1839(transaction's)X +2289(commit)X +2553(record)X +2779(is)X +2852(\257ushed.)X +755 4520(Group)N +981(commit)X +1246(can)X +1379(substantially)X +1803(improve)X +2090(performance)X +2517(for)X +2631(high-concurrency)X +3218(environments.)X +3714(If)X +3788(only)X +3950(a)X +4006(few)X +4147(tran-)X +555 4610(sactions)N +836(are)X +957(running,)X +1248(it)X +1314(is)X +1389(unlikely)X +1673(to)X +1757(improve)X +2046(things)X +2263(at)X +2343(all.)X +2485(The)X +2632(crossover)X +2962(point)X +3148(is)X +3223(the)X +3343(point)X +3529(at)X +3609(which)X +3827(the)X +3947(transaction)X +555 4700(commit)N +823(rate)X +968(is)X +1045(limited)X +1295(by)X +1399(the)X +1521(bandwidth)X +1883(of)X +1974(the)X +2096(device)X +2330(on)X +2434(which)X +2654(the)X +2776(log)X +2902(resides.)X +3189(If)X +3267(processes)X +3599(are)X +3722(trying)X +3937(to)X +4023(\257ush)X +4201(the)X +555 4790(log)N +677(faster)X +876(than)X +1034(the)X +1152(log)X +1274(disk)X +1427(can)X +1559(accept)X +1785(data,)X +1959(then)X +2117(group)X +2324(commit)X +2588(will)X +2732(increase)X +3016(the)X +3134(commit)X +3398(rate.)X +3 f +555 4976(4.3.)N +715(Kernel)X +971(Intervention)X +1418(for)X +1541(Synchronization)X +1 f +755 5099(Since)N +954(LIBTP)X +1197(uses)X +1356(data)X +1511(in)X +1594(shared)X +1825(memory)X +2113(\()X +2 f +2140(e.g.)X +1 f +2277(the)X +2395(lock)X +2553(table)X +2729(and)X +2865(buffer)X +3082(pool\))X +3271(it)X +3335(must)X +3510(be)X +3606(possible)X +3888(for)X +4002(a)X +4058(process)X +555 5189(to)N +640(acquire)X +900(exclusive)X +1226(access)X +1454(to)X +1538(shared)X +1770(data)X +1926(in)X +2010(order)X +2202(to)X +2286(prevent)X +2549(corruption.)X +2945(In)X +3034(addition,)X +3338(the)X +3458(process)X +3721(manager)X +4020(must)X +4197(put)X +555 5279(processes)N +886(to)X +971(sleep)X +1159(when)X +1356(the)X +1477(lock)X +1638(or)X +1728(buffer)X +1948(they)X +2109(request)X +2364(is)X +2440(in)X +2525(use)X +2655(by)X +2758(some)X +2950(other)X +3138(process.)X +3441(In)X +3530(the)X +3650(LIBTP)X +3894(implementa-)X +555 5385(tion)N +705(under)X +914(Ultrix)X +1131(4.0)X +7 s +5353(2)Y +10 s +5385(,)Y +1305(we)X +1424(use)X +1556(System)X +1816(V)X +1899(semaphores)X +2303(to)X +2390(provide)X +2660(this)X +2800(synchronization.)X +3377(Semaphores)X +3794(implemented)X +4237(in)X +555 5475(this)N +701(fashion)X +968(turn)X +1128(out)X +1261(to)X +1354(be)X +1461(an)X +1568(expensive)X +1920(choice)X +2161(for)X +2285(synchronization,)X +2847(because)X +3132(each)X +3310(access)X +3546(traps)X +3732(to)X +3824(the)X +3952(kernel)X +4183(and)X +8 s +10 f +555 5547(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N +5 s +1 f +727 5625(2)N +8 s +763 5650(Ultrix)N +932(and)X +1040(DEC)X +1184(are)X +1277(trademarks)X +1576(of)X +1645(Digital)X +1839(Equipment)X +2136(Corporation.)X + +9 p +%%Page: 9 9 +8 s 8 xH 0 xS 1 f +10 s +3 f +1 f +555 630(executes)N +852(atomically)X +1210(there.)X +755 753(On)N +878(architectures)X +1314(that)X +1459(support)X +1724(atomic)X +1967(test-and-set,)X +2382(a)X +2443(much)X +2646(better)X +2854(choice)X +3089(would)X +3314(be)X +3415(to)X +3502(attempt)X +3767(to)X +3854(obtain)X +4079(a)X +4139(spin-)X +555 843(lock)N +714(with)X +877(a)X +934(test-and-set,)X +1345(and)X +1482(issue)X +1663(a)X +1720(system)X +1963(call)X +2100(only)X +2263(if)X +2333(the)X +2452(spinlock)X +2744(is)X +2818(unavailable.)X +3249(Since)X +3447(virtually)X +3738(all)X +3838(semaphores)X +4237(in)X +555 933(LIBTP)N +801(are)X +924(uncontested)X +1330(and)X +1469(are)X +1591(held)X +1752(for)X +1869(very)X +2035(short)X +2218(periods)X +2477(of)X +2567(time,)X +2752(this)X +2890(would)X +3113(improve)X +3403(performance.)X +3873(For)X +4007(example,)X +555 1023(processes)N +885(must)X +1062(acquire)X +1321(exclusive)X +1646(access)X +1874(to)X +1958(buffer)X +2177(pool)X +2341(metadata)X +2653(in)X +2737(order)X +2929(to)X +3013(\256nd)X +3159(and)X +3297(pin)X +3421(a)X +3479(buffer)X +3698(in)X +3781(shared)X +4012(memory.)X +555 1113(This)N +721(semaphore)X +1093(is)X +1170(requested)X +1502(most)X +1681(frequently)X +2034(in)X +2119(LIBTP.)X +2404(However,)X +2742(once)X +2917(it)X +2984(is)X +3060(acquired,)X +3380(only)X +3545(a)X +3604(few)X +3748(instructions)X +4144(must)X +555 1203(be)N +656(executed)X +966(before)X +1196(it)X +1264(is)X +1341(released.)X +1669(On)X +1791(one)X +1931(architecture)X +2335(for)X +2453(which)X +2673(we)X +2791(were)X +2972(able)X +3130(to)X +3216(gather)X +3441(detailed)X +3719(pro\256ling)X +4018(informa-)X +555 1293(tion,)N +729(the)X +857(cost)X +1015(of)X +1111(the)X +1238(semaphore)X +1615(calls)X +1791(accounted)X +2146(for)X +2269(25%)X +2445(of)X +2541(the)X +2668(total)X +2839(time)X +3010(spent)X +3208(updating)X +3517(the)X +3644(metadata.)X +4003(This)X +4174(was)X +555 1383(fairly)N +749(consistent)X +1089(across)X +1310(most)X +1485(of)X +1572(the)X +1690(critical)X +1933(sections.)X +755 1506(In)N +848(an)X +950(attempt)X +1216(to)X +1304(quantify)X +1597(the)X +1720(overhead)X +2040(of)X +2132(kernel)X +2358(synchronization,)X +2915(we)X +3034(ran)X +3162(tests)X +3329(on)X +3434(a)X +3495(version)X +3756(of)X +3848(4.3BSD-Reno)X +555 1596(which)N +786(had)X +937(been)X +1123(modi\256ed)X +1441(to)X +1537(support)X +1811(binary)X +2050(semaphore)X +2432(facilities)X +2742(similar)X +2998(to)X +3094(those)X +3297(described)X +3639(in)X +3735([POSIX91].)X +4174(The)X +555 1686(hardware)N +880(platform)X +1181(consisted)X +1504(of)X +1595(an)X +1695(HP300)X +1941(\(33MHz)X +2237(MC68030\))X +2612(workstation)X +3014(with)X +3180(16MBytes)X +3537(of)X +3628(main)X +3812(memory,)X +4123(and)X +4263(a)X +555 1776(600MByte)N +920(HP7959)X +1205(SCSI)X +1396(disk)X +1552(\(17)X +1682(ms)X +1798(average)X +2072(seek)X +2237(time\).)X +2468(We)X +2602(ran)X +2727(three)X +2910(sets)X +3052(of)X +3141(comparisons)X +3568(which)X +3786(are)X +3907(summarized)X +555 1866(in)N +645(\256gure)X +860(\256ve.)X +1028(In)X +1123(each)X +1299(comparison)X +1701(we)X +1823(ran)X +1954(two)X +2102(tests,)X +2292(one)X +2436(using)X +2637(hardware)X +2965(spinlocks)X +3295(and)X +3438(the)X +3563(other)X +3755(using)X +3955(kernel)X +4183(call)X +555 1956(synchronization.)N +1135(Since)X +1341(the)X +1467(test)X +1606(was)X +1758(run)X +1892(single-user,)X +2291(none)X +2474(of)X +2568(the)X +2693(the)X +2818(locks)X +3014(were)X +3198(contested.)X +3568(In)X +3662(the)X +3787(\256rst)X +3938(two)X +4085(sets)X +4232(of)X +555 2046(tests,)N +743(we)X +863(ran)X +992(the)X +1116(full)X +1253(transaction)X +1631(processing)X +2000(benchmark)X +2383(described)X +2717(in)X +2805(section)X +3058(5.1.)X +3223(In)X +3315(one)X +3456(case)X +3620(we)X +3739(ran)X +3867(with)X +4034(both)X +4201(the)X +555 2136(database)N +854(and)X +992(log)X +1116(on)X +1218(the)X +1338(same)X +1525(disk)X +1680(\(1)X +1769(Disk\))X +1969(and)X +2107(in)X +2191(the)X +2311(second,)X +2576(we)X +2692(ran)X +2817(with)X +2981(the)X +3101(database)X +3400(and)X +3538(log)X +3661(on)X +3762(separate)X +4047(disks)X +4232(\(2)X +555 2226(Disk\).)N +800(In)X +894(the)X +1019(last)X +1157(test,)X +1315(we)X +1436(wanted)X +1695(to)X +1784(create)X +2004(a)X +2067(CPU)X +2249(bound)X +2476(environment,)X +2928(so)X +3026(we)X +3146(used)X +3319(a)X +3381(database)X +3684(small)X +3883(enough)X +4145(to)X +4233(\256t)X +555 2316(completely)N +941(in)X +1033(the)X +1161(cache)X +1375(and)X +1521(issued)X +1751(read-only)X +2089(transactions.)X +2541(The)X +2695(results)X +2933(in)X +3024(\256gure)X +3240(\256ve)X +3389(express)X +3659(the)X +3786(kernel)X +4016(call)X +4161(syn-)X +555 2406(chronization)N +980(performance)X +1411(as)X +1502(a)X +1562(percentage)X +1935(of)X +2026(the)X +2148(spinlock)X +2443(performance.)X +2914(For)X +3049(example,)X +3365(in)X +3451(the)X +3573(1)X +3637(disk)X +3794(case,)X +3977(the)X +4098(kernel)X +555 2496(call)N +697(implementation)X +1225(achieved)X +1537(4.4)X +1662(TPS)X +1824(\(transactions)X +2259(per)X +2387(second\))X +2662(while)X +2865(the)X +2988(semaphore)X +3361(implementation)X +3888(achieved)X +4199(4.6)X +555 2586(TPS,)N +735(and)X +874(the)X +995(relative)X +1259(performance)X +1689(of)X +1779(the)X +1900(kernel)X +2123(synchronization)X +2657(is)X +2732(96%)X +2901(that)X +3043(of)X +3132(the)X +3252(spinlock)X +3545(\(100)X +3714(*)X +3776(4.4)X +3898(/)X +3942(4.6\).)X +4111(There)X +555 2676(are)N +674(two)X +814(striking)X +1078(observations)X +1503(from)X +1679(these)X +1864(results:)X +10 f +635 2799(g)N +1 f +755(even)X +927(when)X +1121(the)X +1239(system)X +1481(is)X +1554(disk)X +1707(bound,)X +1947(the)X +2065(CPU)X +2240(cost)X +2389(of)X +2476(synchronization)X +3008(is)X +3081(noticeable,)X +3451(and)X +10 f +635 2922(g)N +1 f +755(when)X +949(we)X +1063(are)X +1182(CPU)X +1357(bound,)X +1597(the)X +1715(difference)X +2062(is)X +2135(dramatic)X +2436(\(67%\).)X +3 f +555 3108(4.4.)N +715(Transaction)X +1148(Protected)X +1499(Access)X +1747(Methods)X +1 f +755 3231(The)N +903(B-tree)X +1127(and)X +1266(\256xed)X +1449(length)X +1671(recno)X +1872(\(record)X +2127(number\))X +2421(access)X +2649(methods)X +2942(have)X +3116(been)X +3290(modi\256ed)X +3596(to)X +3680(provide)X +3947(transaction)X +555 3321(protection.)N +941(Whereas)X +1244(the)X +1363(previously)X +1722(published)X +2054(interface)X +2357(to)X +2440(the)X +2559(access)X +2786(routines)X +3065(had)X +3202(separate)X +3487(open)X +3664(calls)X +3832(for)X +3946(each)X +4114(of)X +4201(the)X +10 f +555 3507(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +1 Dt +2978 5036 MXY + 2978 5036 lineto + 2978 4662 lineto + 3093 4662 lineto + 3093 5036 lineto + 2978 5036 lineto +closepath 21 2978 4662 3093 5036 Dp +2518 MX + 2518 5036 lineto + 2518 3960 lineto + 2633 3960 lineto + 2633 5036 lineto + 2518 5036 lineto +closepath 3 2518 3960 2633 5036 Dp +2059 MX + 2059 5036 lineto + 2059 3946 lineto + 2174 3946 lineto + 2174 5036 lineto + 2059 5036 lineto +closepath 1 2059 3946 2174 5036 Dp +3 f +7 s +2912 5141(Read-only)N +1426 3767(of)N +1487(Spinlock)X +1710(Throughput)X +1480 3710(Throughput)N +1786(as)X +1850(a)X +1892(%)X +11 s +1670 4843(20)N +1670 4614(40)N +1670 4384(60)N +1670 4155(80)N +1648 3925(100)N +7 s +2041 5141(1)N +2083(Disk)X +2490(2)X +2532(Disks)X +5 Dt +1829 5036 MXY +1494 0 Dl +4 Ds +1 Dt +1829 4806 MXY +1494 0 Dl +1829 4577 MXY +1494 0 Dl +1829 4347 MXY +1494 0 Dl +1829 4118 MXY +1494 0 Dl +1829 3888 MXY +1494 0 Dl +3 Dt +-1 Ds +8 s +555 5360(Figure)N +753(5:)X +823(Kernel)X +1028(Overhead)X +1315(for)X +1413(System)X +1625(Call)X +1756(Synchronization.)X +1 f +2254(The)X +2370(performance)X +2708(of)X +2778(the)X +2873(kernel)X +3049(call)X +3158(synchronization)X +3583(is)X +3643(expressed)X +3911(as)X +3980(a)X +4024(percentage)X +555 5450(of)N +625(the)X +720(spinlock)X +954(synchronization)X +1379(performance.)X +1749(In)X +1819(disk)X +1943(bound)X +2120(cases)X +2271(\(1)X +2341(Disk)X +2479(and)X +2588(2)X +2637(Disks\),)X +2837(we)X +2928(see)X +3026(that)X +3139(4-6%)X +3294(of)X +3364(the)X +3459(performance)X +3797(is)X +3857(lost)X +3966(due)X +4074(to)X +4140(kernel)X +555 5540(calls)N +688(while)X +846(in)X +912(the)X +1006(CPU)X +1147(bound)X +1323(case,)X +1464(we)X +1554(have)X +1690(lost)X +1799(67%)X +1932(of)X +2001(the)X +2095(performance)X +2432(due)X +2540(to)X +2606(kernel)X +2781(calls.)X + +10 p +%%Page: 10 10 +8 s 8 xH 0 xS 1 f +10 s +3 f +1 f +555 630(access)N +781(methods,)X +1092(we)X +1206(now)X +1364(have)X +1536(an)X +1632(integrated)X +1973(open)X +2149(call)X +2285(with)X +2447(the)X +2565(following)X +2896(calling)X +3134(conventions:)X +7 f +715 753(DB)N +859(*dbopen)X +1243(\(const)X +1579(char)X +1819(*file,)X +2155(int)X +2347(flags,)X +2683(int)X +2875(mode,)X +3163(DBTYPE)X +3499(type,)X +1291 843(int)N +1483(dbflags,)X +1915(const)X +2203(void)X +2443(*openinfo\))X +1 f +555 966(where)N +2 f +774(\256le)X +1 f +894(is)X +969(the)X +1089(name)X +1285(of)X +1374(the)X +1494(\256le)X +1618(being)X +1818(opened,)X +2 f +2092(\257ags)X +1 f +2265(and)X +2 f +2402(mode)X +1 f +2597(are)X +2717(the)X +2836(standard)X +3129(arguments)X +3484(to)X +3 f +3567(open)X +1 f +3731(\(2\),)X +2 f +3866(type)X +1 f +4021(is)X +4095(one)X +4232(of)X +555 1056(the)N +680(access)X +913(method)X +1180(types,)X +2 f +1396(db\257ags)X +1 f +1654(indicates)X +1966(the)X +2091(mode)X +2296(of)X +2390(the)X +2515(buffer)X +2739(pool)X +2907(and)X +3049(transaction)X +3427(protection,)X +3798(and)X +2 f +3940(openinfo)X +1 f +4246(is)X +555 1146(the)N +681(access)X +915(method)X +1183(speci\256c)X +1456(information.)X +1902(Currently,)X +2257(the)X +2383(possible)X +2673(values)X +2906(for)X +2 f +3028(db\257ags)X +1 f +3287(are)X +3414(DB_SHARED)X +3912(and)X +4055(DB_TP)X +555 1236(indicating)N +895(that)X +1035(buffers)X +1283(should)X +1516(be)X +1612(kept)X +1770(in)X +1852(a)X +1908(shared)X +2138(buffer)X +2355(pool)X +2517(and)X +2653(that)X +2793(the)X +2911(\256le)X +3033(should)X +3266(be)X +3362(transaction)X +3734(protected.)X +755 1359(The)N +900(modi\256cations)X +1355(required)X +1643(to)X +1725(add)X +1861(transaction)X +2233(protection)X +2578(to)X +2660(an)X +2756(access)X +2982(method)X +3242(are)X +3361(quite)X +3541(simple)X +3774(and)X +3910(localized.)X +715 1482(1.)N +795(Replace)X +1074(\256le)X +2 f +1196(open)X +1 f +1372(with)X +2 f +1534(buf_open)X +1 f +1832(.)X +715 1572(2.)N +795(Replace)X +1074(\256le)X +2 f +1196(read)X +1 f +1363(and)X +2 f +1499(write)X +1 f +1683(calls)X +1850(with)X +2012(buffer)X +2229(manager)X +2526(calls)X +2693(\()X +2 f +2720(buf_get)X +1 f +(,)S +2 f +3000(buf_unpin)X +1 f +3324(\).)X +715 1662(3.)N +795(Precede)X +1070(buffer)X +1287(manager)X +1584(calls)X +1751(with)X +1913(an)X +2009(appropriate)X +2395(\(read)X +2581(or)X +2668(write\))X +2880(lock)X +3038(call.)X +715 1752(4.)N +795(Before)X +1034(updates,)X +1319(issue)X +1499(a)X +1555(logging)X +1819(operation.)X +715 1842(5.)N +795(After)X +985(data)X +1139(have)X +1311(been)X +1483(accessed,)X +1805(release)X +2049(the)X +2167(buffer)X +2384(manager)X +2681(pin.)X +715 1932(6.)N +795(Provide)X +1064(undo/redo)X +1409(code)X +1581(for)X +1695(each)X +1863(type)X +2021(of)X +2108(log)X +2230(record)X +2456(de\256ned.)X +555 2071(The)N +702(following)X +1035(code)X +1209(fragments)X +1552(show)X +1743(how)X +1903(to)X +1987(transaction)X +2361(protect)X +2606(several)X +2856(updates)X +3123(to)X +3206(a)X +3263(B-tree.)X +7 s +3484 2039(3)N +10 s +3533 2071(In)N +3621(the)X +3740(unprotected)X +4140(case,)X +555 2161(an)N +652(open)X +829(call)X +966(is)X +1040(followed)X +1346(by)X +1447(a)X +1504(read)X +1664(call)X +1801(to)X +1884(obtain)X +2105(the)X +2224(meta-data)X +2562(for)X +2677(the)X +2796(B-tree.)X +3058(Instead,)X +3331(we)X +3446(issue)X +3627(an)X +3724(open)X +3901(to)X +3984(the)X +4102(buffer)X +555 2251(manager)N +852(to)X +934(obtain)X +1154(a)X +1210(\256le)X +1332(id)X +1414(and)X +1550(a)X +1606(buffer)X +1823(request)X +2075(to)X +2157(obtain)X +2377(the)X +2495(meta-data)X +2832(as)X +2919(shown)X +3148(below.)X +7 f +715 2374(char)N +955(*path;)X +715 2464(int)N +907(fid,)X +1147(flags,)X +1483(len,)X +1723(mode;)X +715 2644(/*)N +859(Obtain)X +1195(a)X +1291(file)X +1531(id)X +1675(with)X +1915(which)X +2203(to)X +2347(access)X +2683(the)X +2875(buffer)X +3211(pool)X +3451(*/)X +715 2734(fid)N +907(=)X +1003(buf_open\(path,)X +1723(flags,)X +2059(mode\);)X +715 2914(/*)N +859(Read)X +1099(the)X +1291(meta)X +1531(data)X +1771(\(page)X +2059(0\))X +2203(for)X +2395(the)X +2587(B-tree)X +2923(*/)X +715 3004(if)N +859(\(tp_lock\(fid,)X +1531(0,)X +1675(READ_LOCK\)\))X +1003 3094(return)N +1339(error;)X +715 3184(meta_data_ptr)N +1387(=)X +1483(buf_get\(fid,)X +2107(0,)X +2251(BF_PIN,)X +2635(&len\);)X +1 f +555 3307(The)N +714(BF_PIN)X +1014(argument)X +1350(to)X +2 f +1445(buf_get)X +1 f +1718(indicates)X +2036(that)X +2189(we)X +2316(wish)X +2500(to)X +2595(leave)X +2798(this)X +2946(page)X +3131(pinned)X +3382(in)X +3477(memory)X +3777(so)X +3881(that)X +4034(it)X +4111(is)X +4197(not)X +555 3397(swapped)N +862(out)X +990(while)X +1194(we)X +1314(are)X +1439(accessing)X +1772(it.)X +1881(The)X +2031(last)X +2167(argument)X +2495(to)X +2 f +2582(buf_get)X +1 f +2847(returns)X +3095(the)X +3218(number)X +3488(of)X +3580(bytes)X +3774(on)X +3879(the)X +4002(page)X +4179(that)X +555 3487(were)N +732(valid)X +912(so)X +1003(that)X +1143(the)X +1261(access)X +1487(method)X +1747(may)X +1905(initialize)X +2205(the)X +2323(page)X +2495(if)X +2564(necessary.)X +755 3610(Next,)N +955(consider)X +1251(inserting)X +1555(a)X +1615(record)X +1845(on)X +1949(a)X +2009(particular)X +2341(page)X +2517(of)X +2608(a)X +2668(B-tree.)X +2932(In)X +3022(the)X +3143(unprotected)X +3545(case,)X +3727(we)X +3844(read)X +4006(the)X +4127(page,)X +555 3700(call)N +2 f +693(_bt_insertat)X +1 f +1079(,)X +1121(and)X +1258(write)X +1444(the)X +1563(page.)X +1776(Instead,)X +2049(we)X +2164(lock)X +2323(the)X +2442(page,)X +2635(request)X +2888(the)X +3007(buffer,)X +3245(log)X +3368(the)X +3487(change,)X +3756(modify)X +4008(the)X +4127(page,)X +555 3790(and)N +691(release)X +935(the)X +1053(buffer.)X +7 f +715 3913(int)N +907(fid,)X +1147(len,)X +1387(pageno;)X +1867(/*)X +2011(Identifies)X +2539(the)X +2731(buffer)X +3067(*/)X +715 4003(int)N +907(index;)X +1867(/*)X +2011(Location)X +2443(at)X +2587(which)X +2875(to)X +3019(insert)X +3355(the)X +3547(new)X +3739(pair)X +3979(*/)X +715 4093(DBT)N +907(*keyp,)X +1243(*datap;)X +1867(/*)X +2011(Key/Data)X +2443(pair)X +2683(to)X +2827(be)X +2971(inserted)X +3403(*/)X +715 4183(DATUM)N +1003(*d;)X +1867(/*)X +2011(Key/data)X +2443(structure)X +2923(to)X +3067(insert)X +3403(*/)X +715 4363(/*)N +859(Lock)X +1099(and)X +1291(request)X +1675(the)X +1867(buffer)X +2203(*/)X +715 4453(if)N +859(\(tp_lock\(fid,)X +1531(pageno,)X +1915(WRITE_LOCK\)\))X +1003 4543(return)N +1339(error;)X +715 4633(buffer_ptr)N +1243(=)X +1339(buf_get\(fid,)X +1963(pageno,)X +2347(BF_PIN,)X +2731(&len\);)X +715 4813(/*)N +859(Log)X +1051(and)X +1243(perform)X +1627(the)X +1819(update)X +2155(*/)X +715 4903(log_insdel\(BTREE_INSERT,)N +1915(fid,)X +2155(pageno,)X +2539(keyp,)X +2827(datap\);)X +715 4993(_bt_insertat\(buffer_ptr,)N +1915(d,)X +2059(index\);)X +715 5083(buf_unpin\(buffer_ptr\);)N +1 f +555 5206(Succinctly,)N +942(the)X +1068(algorithm)X +1407(for)X +1529(turning)X +1788(unprotected)X +2195(code)X +2375(into)X +2527(protected)X +2854(code)X +3034(is)X +3115(to)X +3205(replace)X +3466(read)X +3633(operations)X +3995(with)X +2 f +4165(lock)X +1 f +555 5296(and)N +2 f +691(buf_get)X +1 f +951(operations)X +1305(and)X +1441(write)X +1626(operations)X +1980(with)X +2 f +2142(log)X +1 f +2264(and)X +2 f +2400(buf_unpin)X +1 f +2744(operations.)X +8 s +10 f +555 5458(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N +5 s +1 f +727 5536(3)N +8 s +766 5561(The)N +884(following)X +1152(code)X +1291(fragments)X +1565(are)X +1661(examples,)X +1937(but)X +2038(do)X +2120(not)X +2220(de\256ne)X +2394(the)X +2490(\256nal)X +2622(interface.)X +2894(The)X +3011(\256nal)X +3143(interface)X +3383(will)X +3501(be)X +3579(determined)X +3884(after)X +4018(LIBTP)X +4214(has)X +555 5633(been)N +691(fully)X +828(integrated)X +1099(with)X +1229(the)X +1323(most)X +1464(recent)X +3 f +1635(db)X +1 f +1707(\(3\))X +1797(release)X +1989(from)X +2129(the)X +2223(Computer)X +2495(Systems)X +2725(Research)X +2974(Group)X +3153(at)X +3215(University)X +3501(of)X +3570(California,)X +3861(Berkeley.)X + +11 p +%%Page: 11 11 +8 s 8 xH 0 xS 1 f +10 s +3 f +555 630(5.)N +655(Performance)X +1 f +755 753(In)N +845(this)X +983(section,)X +1253(we)X +1370(present)X +1625(the)X +1746(results)X +1978(of)X +2067(two)X +2209(very)X +2374(different)X +2673(benchmarks.)X +3103(The)X +3250(\256rst)X +3396(is)X +3471(an)X +3569(online)X +3791(transaction)X +4165(pro-)X +555 843(cessing)N +824(benchmark,)X +1234(similar)X +1489(to)X +1584(the)X +1715(standard)X +2020(TPCB,)X +2272(but)X +2407(has)X +2547(been)X +2732(adapted)X +3015(to)X +3110(run)X +3250(in)X +3345(a)X +3414(desktop)X +3696(environment.)X +4174(The)X +555 933(second)N +798(emulates)X +1103(a)X +1159(computer-aided)X +1683(design)X +1912(environment)X +2337(and)X +2473(provides)X +2769(more)X +2954(complex)X +3250(query)X +3453(processing.)X +3 f +555 1119(5.1.)N +715(Transaction)X +1148(Processing)X +1533(Benchmark)X +1 f +755 1242(For)N +887(this)X +1023(section,)X +1291(all)X +1392(performance)X +1820(numbers)X +2117(shown)X +2346(except)X +2576(for)X +2690(the)X +2808(commercial)X +3207(database)X +3504(system)X +3746(were)X +3923(obtained)X +4219(on)X +555 1332(a)N +614(DECstation)X +1009(5000/200)X +1333(with)X +1497(32MBytes)X +1852(of)X +1941(memory)X +2230(running)X +2501(Ultrix)X +2714(V4.0,)X +2914(accessing)X +3244(a)X +3302(DEC)X +3484(RZ57)X +3688(1GByte)X +3959(disk)X +4114(drive.)X +555 1422(The)N +720(commercial)X +1139(relational)X +1482(database)X +1799(system)X +2061(tests)X +2242(were)X +2438(run)X +2584(on)X +2703(a)X +2778(comparable)X +3192(machine,)X +3523(a)X +3598(Sparcstation)X +4033(1+)X +4157(with)X +555 1512(32MBytes)N +915(memory)X +1209(and)X +1352(a)X +1415(1GByte)X +1691(external)X +1976(disk)X +2135(drive.)X +2366(The)X +2517(database,)X +2840(binaries)X +3120(and)X +3262(log)X +3390(resided)X +3648(on)X +3754(the)X +3878(same)X +4069(device.)X +555 1602(Reported)N +869(times)X +1062(are)X +1181(the)X +1299(means)X +1524(of)X +1611(\256ve)X +1751(tests)X +1913(and)X +2049(have)X +2221(standard)X +2513(deviations)X +2862(within)X +3086(two)X +3226(percent)X +3483(of)X +3570(the)X +3688(mean.)X +755 1725(The)N +905(test)X +1041(database)X +1343(was)X +1493(con\256gured)X +1861(according)X +2203(to)X +2290(the)X +2413(TPCB)X +2637(scaling)X +2889(rules)X +3070(for)X +3189(a)X +3250(10)X +3355(transaction)X +3732(per)X +3860(second)X +4108(\(TPS\))X +555 1815(system)N +817(with)X +999(1,000,000)X +1359(account)X +1649(records,)X +1946(100)X +2106(teller)X +2311(records,)X +2607(and)X +2762(10)X +2881(branch)X +3139(records.)X +3455(Where)X +3709(TPS)X +3885(numbers)X +4200(are)X +555 1905(reported,)N +865(we)X +981(are)X +1102(running)X +1373(a)X +1431(modi\256ed)X +1737(version)X +1995(of)X +2084(the)X +2203(industry)X +2486(standard)X +2779(transaction)X +3152(processing)X +3516(benchmark,)X +3914(TPCB.)X +4174(The)X +555 1995(TPCB)N +780(benchmark)X +1163(simulates)X +1491(a)X +1553(withdrawal)X +1940(performed)X +2301(by)X +2407(a)X +2469(hypothetical)X +2891(teller)X +3082(at)X +3166(a)X +3228(hypothetical)X +3650(bank.)X +3872(The)X +4022(database)X +555 2085(consists)N +831(of)X +921(relations)X +1220(\(\256les\))X +1430(for)X +1547(accounts,)X +1871(branches,)X +2200(tellers,)X +2439(and)X +2578(history.)X +2863(For)X +2997(each)X +3168(transaction,)X +3563(the)X +3684(account,)X +3976(teller,)X +4183(and)X +555 2175(branch)N +795(balances)X +1093(must)X +1269(be)X +1366(updated)X +1641(to)X +1724(re\257ect)X +1946(the)X +2065(withdrawal)X +2447(and)X +2584(a)X +2640(history)X +2882(record)X +3108(is)X +3181(written)X +3428(which)X +3644(contains)X +3931(the)X +4049(account)X +555 2265(id,)N +657(branch)X +896(id,)X +998(teller)X +1183(id,)X +1285(and)X +1421(the)X +1539(amount)X +1799(of)X +1886(the)X +2004(withdrawal)X +2385([TPCB90].)X +755 2388(Our)N +914(implementation)X +1450(of)X +1551(the)X +1683(benchmark)X +2074(differs)X +2317(from)X +2506(the)X +2637(speci\256cation)X +3075(in)X +3170(several)X +3431(aspects.)X +3736(The)X +3894(speci\256cation)X +555 2478(requires)N +840(that)X +985(the)X +1108(database)X +1410(keep)X +1587(redundant)X +1933(logs)X +2091(on)X +2196(different)X +2498(devices,)X +2784(but)X +2911(we)X +3030(use)X +3162(a)X +3223(single)X +3439(log.)X +3606(Furthermore,)X +4052(all)X +4157(tests)X +555 2568(were)N +734(run)X +863(on)X +965(a)X +1023(single,)X +1256(centralized)X +1631(system)X +1875(so)X +1968(there)X +2151(is)X +2226(no)X +2328(notion)X +2553(of)X +2641(remote)X +2885(accesses.)X +3219(Finally,)X +3486(we)X +3601(calculated)X +3948(throughput)X +555 2658(by)N +662(dividing)X +955(the)X +1080(total)X +1249(elapsed)X +1517(time)X +1686(by)X +1793(the)X +1918(number)X +2190(of)X +2284(transactions)X +2694(processed)X +3038(rather)X +3253(than)X +3418(by)X +3525(computing)X +3894(the)X +4018(response)X +555 2748(time)N +717(for)X +831(each)X +999(transaction.)X +755 2871(The)N +912(performance)X +1351(comparisons)X +1788(focus)X +1993(on)X +2104(traditional)X +2464(Unix)X +2655(techniques)X +3029(\(unprotected,)X +3486(using)X +3 f +3690(\257ock)X +1 f +3854(\(2\))X +3979(and)X +4126(using)X +3 f +555 2961(fsync)N +1 f +733(\(2\)\))X +884(and)X +1030(a)X +1096(commercial)X +1504(relational)X +1836(database)X +2142(system.)X +2433(Well-behaved)X +2913(applications)X +3329(using)X +3 f +3531(\257ock)X +1 f +3695(\(2\))X +3818(are)X +3946(guaranteed)X +555 3051(that)N +704(concurrent)X +1077(processes')X +1441(updates)X +1715(do)X +1824(not)X +1955(interact)X +2225(with)X +2396(one)X +2541(another,)X +2831(but)X +2962(no)X +3070(guarantees)X +3442(about)X +3648(atomicity)X +3978(are)X +4105(made.)X +555 3141(That)N +731(is,)X +833(if)X +911(the)X +1038(system)X +1289(crashes)X +1555(in)X +1646(mid-transaction,)X +2198(only)X +2369(parts)X +2554(of)X +2649(that)X +2797(transaction)X +3177(will)X +3329(be)X +3433(re\257ected)X +3738(in)X +3828(the)X +3954 0.3125(after-crash)AX +555 3231(state)N +725(of)X +815(the)X +936(database.)X +1276(The)X +1424(use)X +1554(of)X +3 f +1643(fsync)X +1 f +1821(\(2\))X +1937(at)X +2017(transaction)X +2391(commit)X +2657(time)X +2821(provides)X +3119(guarantees)X +3485(of)X +3574(durability)X +3907(after)X +4077(system)X +555 3321(failure.)N +825(However,)X +1160(there)X +1341(is)X +1414(no)X +1514(mechanism)X +1899(to)X +1981(perform)X +2260(transaction)X +2632(abort.)X +3 f +555 3507(5.1.1.)N +775(Single-User)X +1191(Tests)X +1 f +755 3630(These)N +978(tests)X +1151(compare)X +1459(LIBTP)X +1712(in)X +1804(a)X +1870(variety)X +2123(of)X +2220(con\256gurations)X +2708(to)X +2800(traditional)X +3159(UNIX)X +3390(solutions)X +3708(and)X +3854(a)X +3920(commercial)X +555 3720(relational)N +884(database)X +1187(system)X +1435(\(RDBMS\).)X +1814(To)X +1929(demonstrate)X +2347(the)X +2471(server)X +2694(architecture)X +3100(we)X +3220(built)X +3392(a)X +3454(front)X +3636(end)X +3777(test)X +3913(process)X +4179(that)X +555 3810(uses)N +732(TCL)X +922([OUST90])X +1304(to)X +1405(parse)X +1614(database)X +1930(access)X +2175(commands)X +2561(and)X +2716(call)X +2870(the)X +3006(database)X +3321(access)X +3565(routines.)X +3901(In)X +4006(one)X +4160(case)X +555 3900(\(SERVER\),)N +956(frontend)X +1249(and)X +1386(backend)X +1675(processes)X +2004(were)X +2181(created)X +2434(which)X +2650(communicated)X +3142(via)X +3260(an)X +3356(IP)X +3447(socket.)X +3712(In)X +3799(the)X +3917(second)X +4160(case)X +555 3990(\(TCL\),)N +802(a)X +860(single)X +1073(process)X +1336(read)X +1497(queries)X +1751(from)X +1929(standard)X +2223(input,)X +2429(parsed)X +2660(them,)X +2861(and)X +2998(called)X +3211(the)X +3330(database)X +3628(access)X +3855(routines.)X +4174(The)X +555 4080(performance)N +987(difference)X +1338(between)X +1630(the)X +1752(TCL)X +1927(and)X +2067(SERVER)X +2397(tests)X +2563(quanti\256es)X +2898(the)X +3020(communication)X +3542(overhead)X +3861(of)X +3952(the)X +4074(socket.)X +555 4170(The)N +732(RDBMS)X +1063(implementation)X +1617(used)X +1816(embedded)X +2198(SQL)X +2401(in)X +2515(C)X +2620(with)X +2814(stored)X +3062(database)X +3391(procedures.)X +3835(Therefore,)X +4224(its)X +555 4260(con\256guration)N +1003(is)X +1076(a)X +1132(hybrid)X +1361(of)X +1448(the)X +1566(single)X +1777(process)X +2038(architecture)X +2438(and)X +2574(the)X +2692(server)X +2909(architecture.)X +3349(The)X +3494(graph)X +3697(in)X +3779(\256gure)X +3986(six)X +4099(shows)X +555 4350(a)N +611(comparison)X +1005(of)X +1092(the)X +1210(following)X +1541(six)X +1654(con\256gurations:)X +1126 4506(LIBTP)N +1552(Uses)X +1728(the)X +1846(LIBTP)X +2088(library)X +2322(in)X +2404(a)X +2460(single)X +2671(application.)X +1126 4596(TCL)N +1552(Uses)X +1728(the)X +1846(LIBTP)X +2088(library)X +2322(in)X +2404(a)X +2460(single)X +2671(application,)X +3067(requires)X +3346(query)X +3549(parsing.)X +1126 4686(SERVER)N +1552(Uses)X +1728(the)X +1846(LIBTP)X +2088(library)X +2322(in)X +2404(a)X +2460(server)X +2677(con\256guration,)X +3144(requires)X +3423(query)X +3626(parsing.)X +1126 4776(NOTP)N +1552(Uses)X +1728(no)X +1828(locking,)X +2108(logging,)X +2392(or)X +2479(concurrency)X +2897(control.)X +1126 4866(FLOCK)N +1552(Uses)X +3 f +1728(\257ock)X +1 f +1892(\(2\))X +2006(for)X +2120(concurrency)X +2538(control)X +2785(and)X +2921(nothing)X +3185(for)X +3299(durability.)X +1126 4956(FSYNC)N +1552(Uses)X +3 f +1728(fsync)X +1 f +1906(\(2\))X +2020(for)X +2134(durability)X +2465(and)X +2601(nothing)X +2865(for)X +2979(concurrency)X +3397(control.)X +1126 5046(RDBMS)N +1552(Uses)X +1728(a)X +1784(commercial)X +2183(relational)X +2506(database)X +2803(system.)X +755 5235(The)N +902(results)X +1133(show)X +1324(that)X +1466(LIBTP,)X +1730(both)X +1894(in)X +1978(the)X +2098(procedural)X +2464(and)X +2602(parsed)X +2834(environments,)X +3312(is)X +3387(competitive)X +3787(with)X +3951(a)X +4009(commer-)X +555 5325(cial)N +692(system)X +935(\(comparing)X +1326(LIBTP,)X +1589(TCL,)X +1781(and)X +1917(RDBMS\).)X +2263(Compared)X +2617(to)X +2699(existing)X +2972(UNIX)X +3193(solutions,)X +3521(LIBTP)X +3763(is)X +3836(approximately)X +555 5415(15%)N +738(slower)X +988(than)X +1162(using)X +3 f +1371(\257ock)X +1 f +1535(\(2\))X +1665(or)X +1768(no)X +1884(protection)X +2245(but)X +2383(over)X +2562(80%)X +2745(better)X +2964(than)X +3137(using)X +3 f +3345(fsync)X +1 f +3523(\(2\))X +3652(\(comparing)X +4057(LIBTP,)X +555 5505(FLOCK,)N +857(NOTP,)X +1106(and)X +1242(FSYNC\).)X + +12 p +%%Page: 12 12 +10 s 10 xH 0 xS 1 f +3 f +8 s +3500 2184(RDBMS)N +1 Dt +3553 2085 MXY + 3553 2085 lineto + 3676 2085 lineto + 3676 1351 lineto + 3553 1351 lineto + 3553 2085 lineto +closepath 16 3553 1351 3676 2085 Dp +2018 2184(SERVER)N +1720 1168 MXY +0 917 Dl +122 0 Dl +0 -917 Dl +-122 0 Dl +1715 2184(TCL)N +2087 1534 MXY + 2087 1534 lineto + 2209 1534 lineto + 2209 2085 lineto + 2087 2085 lineto + 2087 1534 lineto +closepath 12 2087 1534 2209 2085 Dp +3187 MX + 3187 1534 lineto + 3309 1534 lineto + 3309 2085 lineto + 3187 2085 lineto + 3187 1534 lineto +closepath 19 3187 1534 3309 2085 Dp +3142 2184(FSYNC)N +2425(NOTP)X +2453 955 MXY + 2453 955 lineto + 2576 955 lineto + 2576 2085 lineto + 2453 2085 lineto + 2453 955 lineto +closepath 21 2453 955 2576 2085 Dp +2820 1000 MXY + 2820 1000 lineto + 2942 1000 lineto + 2942 2085 lineto + 2820 2085 lineto + 2820 1000 lineto +closepath 14 2820 1000 2942 2085 Dp +5 Dt +1231 2085 MXY +2567 0 Dl +4 Ds +1 Dt +1231 1840 MXY +2567 0 Dl +1231 1596 MXY +2567 0 Dl +1231 1351 MXY +2567 0 Dl +1231 1108 MXY +2567 0 Dl +1231 863 MXY +2567 0 Dl +11 s +1087 1877(2)N +1087 1633(4)N +1087 1388(6)N +1087 1145(8)N +1065 900(10)N +1028 763(TPS)N +-1 Ds +1353 2085 MXY + 1353 2085 lineto + 1353 1151 lineto + 1476 1151 lineto + 1476 2085 lineto + 1353 2085 lineto +closepath 3 1353 1151 1476 2085 Dp +8 s +1318 2184(LIBTP)N +2767(FLOCK)X +3 Dt +-1 Ds +10 s +1597 2399(Figure)N +1844(6:)X +1931(Single-User)X +2347(Performance)X +2814(Comparison.)X +1 f +10 f +555 2579(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +3 f +555 2855(5.1.2.)N +775(Multi-User)X +1174(Tests)X +1 f +755 2978(While)N +975(the)X +1097(single-user)X +1473(tests)X +1639(form)X +1819(a)X +1878(basis)X +2061(for)X +2178(comparing)X +2544(LIBTP)X +2789(to)X +2874(other)X +3062(systems,)X +3358(our)X +3488(goal)X +3649(in)X +3734(multi-user)X +4086(testing)X +555 3068(was)N +714(to)X +810(analyze)X +1089(its)X +1197(scalability.)X +1579(To)X +1701(this)X +1849(end,)X +2018(we)X +2145(have)X +2330(run)X +2470(the)X +2601(benchmark)X +2991(in)X +3086(three)X +3280(modes,)X +3542(the)X +3673(normal)X +3933(disk)X +4099(bound)X +555 3158(con\256guration)N +1010(\(\256gure)X +1252(seven\),)X +1510(a)X +1573(CPU)X +1755(bound)X +1982(con\256guration)X +2436(\(\256gure)X +2677(eight,)X +2884(READ-ONLY\),)X +3426(and)X +3569(lock)X +3734(contention)X +4099(bound)X +555 3248(\(\256gure)N +796(eight,)X +1003(NO_FSYNC\).)X +1510(Since)X +1715(the)X +1840(normal)X +2094(con\256guration)X +2548(is)X +2628(completely)X +3011(disk)X +3171(bound)X +3398(\(each)X +3600(transaction)X +3978(requires)X +4263(a)X +555 3354(random)N +823(read,)X +1005(a)X +1064(random)X +1332(write,)X +1540(and)X +1679(a)X +1738(sequential)X +2086(write)X +7 s +2251 3322(4)N +10 s +3354(\))Y +2329(we)X +2446(expect)X +2679(to)X +2764(see)X +2890(little)X +3059(performance)X +3489(improvement)X +3939(as)X +4028(the)X +4148(mul-)X +555 3444(tiprogramming)N +1064(level)X +1249(increases.)X +1613(In)X +1709(fact,)X +1879(\256gure)X +2095(seven)X +2307(reveals)X +2564(that)X +2713(we)X +2836(are)X +2964(able)X +3127(to)X +3218(overlap)X +3487(CPU)X +3670(and)X +3814(disk)X +3975(utilization)X +555 3534(slightly)N +825(producing)X +1181(approximately)X +1674(a)X +1740(10%)X +1917(performance)X +2354(improvement)X +2811(with)X +2983(two)X +3133(processes.)X +3511(After)X +3711(that)X +3861(point,)X +4075(perfor-)X +555 3624(mance)N +785(drops)X +983(off,)X +1117(and)X +1253(at)X +1331(a)X +1387(multi-programming)X +2038(level)X +2214(of)X +2301(4,)X +2381(we)X +2495(are)X +2614(performing)X +2995(worse)X +3207(than)X +3365(in)X +3447(the)X +3565(single)X +3776(process)X +4037(case.)X +755 3747(Similar)N +1021(behavior)X +1333(was)X +1489(reported)X +1787(on)X +1897(the)X +2025(commercial)X +2434(relational)X +2767(database)X +3074(system)X +3326(using)X +3529(the)X +3657(same)X +3852(con\256guration.)X +555 3837(The)N +707(important)X +1045(conclusion)X +1419(to)X +1508(draw)X +1696(from)X +1879(this)X +2021(is)X +2101(that)X +2248(you)X +2395(cannot)X +2636(attain)X +2841(good)X +3028(multi-user)X +3384(scaling)X +3638(on)X +3745(a)X +3808(badly)X +4013(balanced)X +555 3927(system.)N +839(If)X +915(multi-user)X +1266(performance)X +1695(on)X +1797(applications)X +2205(of)X +2293(this)X +2429(sort)X +2570(is)X +2644(important,)X +2996(one)X +3133(must)X +3309(have)X +3482(a)X +3539(separate)X +3824(logging)X +4089(device)X +555 4017(and)N +697(horizontally)X +1110(partition)X +1407(the)X +1531(database)X +1834(to)X +1921(allow)X +2124(a)X +2185(suf\256ciently)X +2570(high)X +2737(degree)X +2977(of)X +3069(multiprogramming)X +3698(that)X +3843(group)X +4055(commit)X +555 4107(can)N +687(amortize)X +988(the)X +1106(cost)X +1255(of)X +1342(log)X +1464(\257ushing.)X +755 4230(By)N +871(using)X +1067(a)X +1126(very)X +1292(small)X +1488(database)X +1788(\(one)X +1954(that)X +2097(can)X +2232(be)X +2331(entirely)X +2599(cached)X +2846(in)X +2930(main)X +3112(memory\))X +3428(and)X +3566(read-only)X +3896(transactions,)X +555 4320(we)N +670(generated)X +1004(a)X +1061(CPU)X +1236(bound)X +1456(environment.)X +1921(By)X +2034(using)X +2227(the)X +2345(same)X +2530(small)X +2723(database,)X +3040(the)X +3158(complete)X +3472(TPCB)X +3691(transaction,)X +4083(and)X +4219(no)X +3 f +555 4410(fsync)N +1 f +733(\(2\))X +862(on)X +977(the)X +1110(log)X +1247(at)X +1340(commit,)X +1639(we)X +1768(created)X +2036(a)X +2107(lock)X +2280(contention)X +2652(bound)X +2886(environment.)X +3365(The)X +3524(small)X +3731(database)X +4042(used)X +4223(an)X +555 4500(account)N +828(\256le)X +953(containing)X +1314(only)X +1479(1000)X +1662(records)X +1922(rather)X +2133(than)X +2294(the)X +2415(full)X +2549(1,000,000)X +2891(records)X +3150(and)X +3288(ran)X +3413(enough)X +3671(transactions)X +4076(to)X +4160(read)X +555 4590(the)N +677(entire)X +883(database)X +1183(into)X +1330(the)X +1451(buffer)X +1671(pool)X +1836(\(2000\))X +2073(before)X +2302(beginning)X +2645(measurements.)X +3147(The)X +3295(read-only)X +3626(transaction)X +4001(consisted)X +555 4680(of)N +646(three)X +831(database)X +1132(reads)X +1326(\(from)X +1533(the)X +1655(1000)X +1839(record)X +2069(account)X +2343(\256le,)X +2489(the)X +2611(100)X +2754(record)X +2983(teller)X +3171(\256le,)X +3316(and)X +3455(the)X +3576(10)X +3679(record)X +3908(branch)X +4150(\256le\).)X +555 4770(Since)N +759(no)X +865(data)X +1025(were)X +1208(modi\256ed)X +1518(and)X +1660(no)X +1766(history)X +2014(records)X +2277(were)X +2460(written,)X +2733(no)X +2839(log)X +2966(records)X +3228(were)X +3410(written.)X +3702(For)X +3838(the)X +3961(contention)X +555 4860(bound)N +780(con\256guration,)X +1252(we)X +1371(used)X +1543(the)X +1666(normal)X +1918(TPCB)X +2142(transaction)X +2519(\(against)X +2798(the)X +2920(small)X +3117(database\))X +3445(and)X +3585(disabled)X +3876(the)X +3998(log)X +4124(\257ush.)X +555 4950(Figure)N +784(eight)X +964(shows)X +1184(both)X +1346(of)X +1433(these)X +1618(results.)X +755 5073(The)N +902(read-only)X +1231(test)X +1363(indicates)X +1669(that)X +1810(we)X +1925(barely)X +2147(scale)X +2329(at)X +2408(all)X +2509(in)X +2592(the)X +2711(CPU)X +2887(bound)X +3108(case.)X +3308(The)X +3454(explanation)X +3849(for)X +3964(that)X +4105(is)X +4179(that)X +555 5163(even)N +735(with)X +905(a)X +969(single)X +1188(process,)X +1477(we)X +1599(are)X +1726(able)X +1888(to)X +1978(drive)X +2171(the)X +2297(CPU)X +2480(utilization)X +2832(to)X +2922(96%.)X +3137(As)X +3254(a)X +3317(result,)X +3542(that)X +3689(gives)X +3885(us)X +3983(very)X +4153(little)X +555 5253(room)N +753(for)X +876(improvement,)X +1352(and)X +1497(it)X +1570(takes)X +1764(a)X +1829(multiprogramming)X +2462(level)X +2647(of)X +2743(four)X +2906(to)X +2997(approach)X +3321(100%)X +3537(CPU)X +3721(saturation.)X +4106(In)X +4201(the)X +555 5343(case)N +718(where)X +939(we)X +1057(do)X +1161(perform)X +1444(writes,)X +1684(we)X +1802(are)X +1925(interested)X +2261(in)X +2347(detecting)X +2665(when)X +2863(lock)X +3025(contention)X +3387(becomes)X +3691(a)X +3750(dominant)X +4075(perfor-)X +555 5433(mance)N +787(factor.)X +1037(Contention)X +1414(will)X +1560(cause)X +1761(two)X +1903(phenomena;)X +2317(we)X +2433(will)X +2579(see)X +2704(transactions)X +3109(queueing)X +3425(behind)X +3665(frequently)X +4017(accessed)X +555 5523(data,)N +731(and)X +869(we)X +985(will)X +1131(see)X +1256(transaction)X +1629(abort)X +1815(rates)X +1988(increasing)X +2339(due)X +2476(to)X +2559(deadlock.)X +2910(Given)X +3127(that)X +3268(the)X +3387(branch)X +3627(\256le)X +3750(contains)X +4038(only)X +4201(ten)X +8 s +10 f +555 5595(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N +5 s +1 f +727 5673(4)N +8 s +763 5698(Although)N +1021(the)X +1115(log)X +1213(is)X +1272(written)X +1469(sequentially,)X +1810(we)X +1900(do)X +1980(not)X +2078(get)X +2172(the)X +2266(bene\256t)X +2456(of)X +2525(sequentiality)X +2868(since)X +3015(the)X +3109(log)X +3207(and)X +3315(database)X +3550(reside)X +3718(on)X +3798(the)X +3892(same)X +4039(disk.)X + +13 p +%%Page: 13 13 +8 s 8 xH 0 xS 1 f +10 s +3 f +1 f +3187 2051 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3286 2028 MXY +0 17 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3384 1926 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3483 1910 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3581 1910 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3680 1832 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3778 1909 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3877 1883 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3975 1679 MXY +0 17 Dl +0 -8 Dl +9 0 Dl +-18 0 Dl +4074 1487 MXY +0 17 Dl +0 -8 Dl +9 0 Dl +-18 0 Dl +5 Dt +3187 2060 MXY +99 -24 Dl +98 -101 Dl +99 -16 Dl +98 0 Dl +99 -78 Dl +98 77 Dl +99 -26 Dl +98 -204 Dl +99 -192 Dl +3 f +6 s +4088 1516(SMALL)N +3 Dt +3187 2051 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3286 2051 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3384 2041 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3483 1990 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3581 1843 MXY +0 17 Dl +0 -8 Dl +9 0 Dl +-18 0 Dl +3680 1578 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3778 1496 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3877 1430 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +3975 1269 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +4074 1070 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1 Dt +3187 2060 MXY +99 0 Dl +98 -10 Dl +99 -51 Dl +98 -147 Dl +99 -265 Dl +98 -82 Dl +99 -66 Dl +98 -161 Dl +99 -199 Dl +4088 1099(LARGE)N +5 Dt +3089 2060 MXY +985 0 Dl +3089 MX +0 -1174 Dl +4 Ds +1 Dt +3581 2060 MXY +0 -1174 Dl +4074 2060 MXY +0 -1174 Dl +3089 1825 MXY +985 0 Dl +9 s +2993 1855(25)N +3089 1591 MXY +985 0 Dl +2993 1621(50)N +3089 1356 MXY +985 0 Dl +2993 1386(75)N +3089 1121 MXY +985 0 Dl +2957 1151(100)N +3089 886 MXY +985 0 Dl +2957 916(125)N +3281 2199(Multiprogramming)N +3071 2152(0)N +3569(5)X +4038(10)X +2859 787(Aborts)N +3089(per)X +3211(500)X +2901 847(transactions)N +-1 Ds +3 Dt +2037 1342 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2125 1358 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2213 1341 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2301 1191 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2388 1124 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-17 0 Dl +2476 1157 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2564 1157 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2652 1161 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2740 1153 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2828 1150 MXY +0 18 Dl +0 -9 Dl +8 0 Dl +-17 0 Dl +5 Dt +2037 1351 MXY +88 16 Dl +88 -17 Dl +88 -150 Dl +87 -67 Dl +88 33 Dl +88 0 Dl +88 4 Dl +88 -8 Dl +88 -3 Dl +6 s +2685 1234(READ-ONLY)N +3 Dt +2037 1464 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2125 1640 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2213 1854 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2301 1872 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2388 1871 MXY +0 17 Dl +0 -9 Dl +9 0 Dl +-17 0 Dl +2476 1933 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2564 1914 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2652 1903 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2740 1980 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +2828 2004 MXY +0 18 Dl +0 -9 Dl +8 0 Dl +-17 0 Dl +1 Dt +2037 1473 MXY +88 176 Dl +88 214 Dl +88 18 Dl +87 -2 Dl +88 63 Dl +88 -19 Dl +88 -11 Dl +88 77 Dl +88 24 Dl +2759 1997(NO-FSYNC)N +5 Dt +1949 2060 MXY +879 0 Dl +1949 MX +0 -1174 Dl +4 Ds +1 Dt +2388 2060 MXY +0 -1174 Dl +2828 2060 MXY +0 -1174 Dl +1949 1825 MXY +879 0 Dl +9 s +1842 1855(40)N +1949 1591 MXY +879 0 Dl +1842 1621(80)N +1949 1356 MXY +879 0 Dl +1806 1386(120)N +1949 1121 MXY +879 0 Dl +1806 1151(160)N +1949 886 MXY +879 0 Dl +1806 916(200)N +2088 2199(Multiprogramming)N +1844 863(in)N +1922(TPS)X +1761 792(Throughput)N +1931 2121(0)N +2370 2133(5)N +2792(10)X +6 s +1679 1833(LIBTP)N +-1 Ds +3 Dt +837 1019 MXY +0 17 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +929 878 MXY +0 17 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1021 939 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1113 1043 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1205 1314 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1297 1567 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1389 1665 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1481 1699 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1573 1828 MXY +0 18 Dl +0 -9 Dl +9 0 Dl +-18 0 Dl +1665 1804 MXY +0 18 Dl +0 -9 Dl +8 0 Dl +-17 0 Dl +5 Dt +837 1027 MXY +92 -141 Dl +92 62 Dl +92 104 Dl +92 271 Dl +92 253 Dl +92 98 Dl +92 34 Dl +92 129 Dl +92 -24 Dl +745 2060 MXY +920 0 Dl +745 MX +0 -1174 Dl +4 Ds +1 Dt +1205 2060 MXY +0 -1174 Dl +1665 2060 MXY +0 -1174 Dl +745 1766 MXY +920 0 Dl +9 s +673 1796(3)N +745 1473 MXY +920 0 Dl +673 1503(5)N +745 1180 MXY +920 0 Dl +673 1210(8)N +745 886 MXY +920 0 Dl +637 916(10)N +905 2199(Multiprogramming)N +622 851(in)N +700(TPS)X +575 792(Throughput)N +733 2152(0)N +1196(5)X +1629(10)X +3 Dt +-1 Ds +8 s +655 2441(Figure)N +872(7:)X +960(Multi-user)X +1286(Performance.)X +1 f +655 2531(Since)N +825(the)X +931(con\256guration)X +1300(is)X +1371(completely)X +655 2621(disk)N +790(bound,)X +994(we)X +1096(see)X +1204(only)X +1345(a)X +1400(small)X +1566(im-)X +655 2711(provement)N +964(by)X +1064(adding)X +1274(a)X +1337(second)X +1549(pro-)X +655 2801(cess.)N +849(Adding)X +1081(any)X +1213(more)X +1383(concurrent)X +655 2891(processes)N +935(causes)X +1137(performance)X +1493(degra-)X +655 2981(dation.)N +3 f +1927 2441(Figure)N +2149(8:)X +2243(Multi-user)X +2574(Performance)X +1927 2531(on)N +2021(a)X +2079(small)X +2251(database.)X +1 f +2551(With)X +2704(one)X +2821(pro-)X +1927 2621(cess,)N +2075(we)X +2174(are)X +2276(driving)X +2486(the)X +2589(CPU)X +2739(at)X +2810(96%)X +1927 2711(utilization)N +2215(leaving)X +2430(little)X +2575(room)X +2737(for)X +2838(im-)X +1927 2801(provement)N +2238(as)X +2328(the)X +2443(multiprogramming)X +1927 2891(level)N +2091(increases.)X +2396(In)X +2489(the)X +2607(NO-FSYNC)X +1927 2981(case,)N +2076(lock)X +2209(contention)X +2502(degrades)X +2751(perfor-)X +1927 3071(mance)N +2117(as)X +2194(soon)X +2339(as)X +2416(a)X +2468(second)X +2669(process)X +2884(is)X +1927 3161(added.)N +3 f +3199 2441(Figure)N +3405(9:)X +3482(Abort)X +3669(rates)X +3827(on)X +3919(the)X +4028(TPCB)X +3199 2531(Benchmark.)N +1 f +3589(The)X +3726(abort)X +3895(rate)X +4028(climbs)X +3199 2621(more)N +3366(quickly)X +3594(for)X +3704(the)X +3818(large)X +3980(database)X +3199 2711(test)N +3324(since)X +3491(processes)X +3771(are)X +3884(descheduled)X +3199 2801(more)N +3409(frequently,)X +3766(allowing)X +4068(more)X +3199 2891(processes)N +3459(to)X +3525(vie)X +3619(for)X +3709(the)X +3803(same)X +3950(locks.)X +10 s +10 f +555 3284(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +1 f +555 3560(records,)N +835(we)X +952(expect)X +1185(contention)X +1546(to)X +1631(become)X +1904(a)X +1963(factor)X +2174(quickly)X +2437(and)X +2576(the)X +2697(NO-FSYNC)X +3120(line)X +3263(in)X +3348(\256gure)X +3557(eight)X +3739(demonstrates)X +4184(this)X +555 3650(dramatically.)N +1022(Each)X +1209(additional)X +1555(process)X +1822(causes)X +2058(both)X +2226(more)X +2417(waiting)X +2682(and)X +2823(more)X +3013(deadlocking.)X +3470(Figure)X +3704(nine)X +3867(shows)X +4092(that)X +4237(in)X +555 3740(the)N +681(small)X +882(database)X +1187(case)X +1353(\(SMALL\),)X +1725(waiting)X +1992(is)X +2072(the)X +2197(dominant)X +2526(cause)X +2732(of)X +2826(declining)X +3151(performance)X +3585(\(the)X +3737(number)X +4009(of)X +4103(aborts)X +555 3830(increases)N +878(less)X +1026(steeply)X +1281(than)X +1447(the)X +1573(performance)X +2008(drops)X +2214(off)X +2336(in)X +2426(\256gure)X +2641(eight\),)X +2876(while)X +3082(in)X +3172(the)X +3298(large)X +3487(database)X +3792(case)X +3958(\(LARGE\),)X +555 3920(deadlocking)N +967(contributes)X +1343(more)X +1528(to)X +1610(the)X +1728(declining)X +2046(performance.)X +755 4043(Deadlocks)N +1116(are)X +1237(more)X +1424(likely)X +1628(to)X +1712(occur)X +1913(in)X +1997(the)X +2116(LARGE)X +2404(test)X +2536(than)X +2695(in)X +2778(the)X +2897(SMALL)X +3189(test)X +3321(because)X +3597(there)X +3779(are)X +3899(more)X +4085(oppor-)X +555 4133(tunities)N +814(to)X +900(wait.)X +1082(In)X +1173(the)X +1295(SMALL)X +1590(case,)X +1773(processes)X +2105(never)X +2307(do)X +2410(I/O)X +2540(and)X +2679(are)X +2801(less)X +2944(likely)X +3149(to)X +3234(be)X +3333(descheduled)X +3753(during)X +3985(a)X +4044(transac-)X +555 4223(tion.)N +740(In)X +828(the)X +947(LARGE)X +1235(case,)X +1415(processes)X +1744(will)X +1889(frequently)X +2240(be)X +2337(descheduled)X +2755(since)X +2941(they)X +3100(have)X +3273(to)X +3356(perform)X +3636(I/O.)X +3804(This)X +3967(provides)X +4263(a)X +555 4313(window)N +837(where)X +1058(a)X +1118(second)X +1365(process)X +1630(can)X +1766(request)X +2022(locks)X +2215(on)X +2318(already)X +2578(locked)X +2815(pages,)X +3041(thus)X +3197(increasing)X +3550(the)X +3671(likelihood)X +4018(of)X +4108(build-)X +555 4403(ing)N +677(up)X +777(long)X +939(chains)X +1164(of)X +1251(waiting)X +1511(processes.)X +1879(Eventually,)X +2266(this)X +2401(leads)X +2586(to)X +2668(deadlock.)X +3 f +555 4589(5.2.)N +715(The)X +868(OO1)X +1052(Benchmark)X +1 f +755 4712(The)N +903(TPCB)X +1125(benchmark)X +1505(described)X +1836(in)X +1921(the)X +2042(previous)X +2341(section)X +2591(measures)X +2913(performance)X +3343(under)X +3549(a)X +3608(conventional)X +4044(transac-)X +555 4802(tion)N +706(processing)X +1076(workload.)X +1446(Other)X +1656(application)X +2039(domains,)X +2357(such)X +2531(as)X +2625(computer-aided)X +3156(design,)X +3412(have)X +3591(substantially)X +4022(different)X +555 4892(access)N +786(patterns.)X +1105(In)X +1197(order)X +1392(to)X +1479(measure)X +1772(the)X +1895(performance)X +2327(of)X +2418(LIBTP)X +2664(under)X +2871(workloads)X +3229(of)X +3320(this)X +3459(type,)X +3641(we)X +3759(implemented)X +4201(the)X +555 4982(OO1)N +731(benchmark)X +1108(described)X +1436(in)X +1518([CATT91].)X +755 5105(The)N +908(database)X +1213(models)X +1472(a)X +1535(set)X +1651(of)X +1745(electronics)X +2120(components)X +2534(with)X +2703(connections)X +3113(among)X +3358(them.)X +3585(One)X +3746(table)X +3929(stores)X +4143(parts)X +555 5195(and)N +696(another)X +962(stores)X +1174(connections.)X +1622(There)X +1835(are)X +1959(three)X +2145(connections)X +2552(originating)X +2927(at)X +3009(any)X +3149(given)X +3351(part.)X +3540(Ninety)X +3782(percent)X +4043(of)X +4134(these)X +555 5285(connections)N +960(are)X +1081(to)X +1165(nearby)X +1406(parts)X +1584(\(those)X +1802(with)X +1966(nearby)X +2 f +2207(ids)X +1 f +2300(\))X +2348(to)X +2431(model)X +2652(the)X +2771(spatial)X +3001(locality)X +3262(often)X +3448(exhibited)X +3767(in)X +3850(CAD)X +4040(applica-)X +555 5375(tions.)N +779(Ten)X +933(percent)X +1198(of)X +1293(the)X +1419(connections)X +1830(are)X +1957(randomly)X +2292(distributed)X +2662(among)X +2908(all)X +3016(other)X +3209(parts)X +3393(in)X +3483(the)X +3609(database.)X +3954(Every)X +4174(part)X +555 5465(appears)N +829(exactly)X +1089(three)X +1278(times)X +1479(in)X +1569(the)X +2 f +1695(from)X +1 f +1874(\256eld)X +2043(of)X +2137(a)X +2200(connection)X +2579(record,)X +2832(and)X +2975(zero)X +3141(or)X +3235(more)X +3427(times)X +3627(in)X +3716(the)X +2 f +3841(to)X +1 f +3930(\256eld.)X +4139(Parts)X +555 5555(have)N +2 f +727(x)X +1 f +783(and)X +2 f +919(y)X +1 f +975(locations)X +1284(set)X +1393(randomly)X +1720(in)X +1802(an)X +1898(appropriate)X +2284(range.)X + +14 p +%%Page: 14 14 +10 s 10 xH 0 xS 1 f +3 f +1 f +755 630(The)N +900(intent)X +1102(of)X +1189(OO1)X +1365(is)X +1438(to)X +1520(measure)X +1808(the)X +1926(overall)X +2169(cost)X +2318(of)X +2405(a)X +2461(query)X +2664(mix)X +2808(characteristic)X +3257(of)X +3344(engineering)X +3743(database)X +4040(applica-)X +555 720(tions.)N +770(There)X +978(are)X +1097(three)X +1278(tests:)X +10 f +635 843(g)N +2 f +755(Lookup)X +1 f +1022(generates)X +1353(1,000)X +1560(random)X +1832(part)X +2 f +1984(ids)X +1 f +2077(,)X +2124(fetches)X +2378(the)X +2502(corresponding)X +2987(parts)X +3169(from)X +3351(the)X +3475(database,)X +3798(and)X +3940(calls)X +4113(a)X +4175(null)X +755 933(procedure)N +1097(in)X +1179(the)X +1297(host)X +1450(programming)X +1906(language)X +2216(with)X +2378(the)X +2496(parts')X +2 f +2699(x)X +1 f +2755(and)X +2 f +2891(y)X +1 f +2947(positions.)X +10 f +635 1056(g)N +2 f +755(Traverse)X +1 f +1067(retrieves)X +1371(a)X +1434(random)X +1706(part)X +1858(from)X +2041(the)X +2166(database)X +2470(and)X +2613(follows)X +2880(connections)X +3290(from)X +3473(it)X +3544(to)X +3632(other)X +3823(parts.)X +4045(Each)X +4232(of)X +755 1146(those)N +947(parts)X +1126(is)X +1202(retrieved,)X +1531(and)X +1670(all)X +1773(connections)X +2179(from)X +2358(it)X +2424(followed.)X +2771(This)X +2935(procedure)X +3279(is)X +3354(repeated)X +3649(depth-\256rst)X +4000(for)X +4116(seven)X +755 1236(hops)N +930(from)X +1110(the)X +1232(original)X +1505(part,)X +1674(for)X +1792(a)X +1852(total)X +2018(of)X +2109(3280)X +2293(parts.)X +2513(Backward)X +2862(traversal)X +3162(also)X +3314(exists,)X +3539(and)X +3678(follows)X +3941(all)X +4044(connec-)X +755 1326(tions)N +930(into)X +1074(a)X +1130(given)X +1328(part)X +1473(to)X +1555(their)X +1722(origin.)X +10 f +635 1449(g)N +2 f +755(Insert)X +1 f +962(adds)X +1129(100)X +1269(new)X +1423(parts)X +1599(and)X +1735(their)X +1902(connections.)X +755 1572(The)N +913(benchmark)X +1303(is)X +1389(single-user,)X +1794(but)X +1929(multi-user)X +2291(access)X +2530(controls)X +2821(\(locking)X +3120(and)X +3268(transaction)X +3652(protection\))X +4036(must)X +4223(be)X +555 1662(enforced.)N +898(It)X +968(is)X +1042(designed)X +1348(to)X +1431(be)X +1528(run)X +1656(on)X +1757(a)X +1814(database)X +2112(with)X +2275(20,000)X +2516(parts,)X +2713(and)X +2850(on)X +2951(one)X +3087(with)X +3249(200,000)X +3529(parts.)X +3745(Because)X +4033(we)X +4147(have)X +555 1752(insuf\256cient)N +935(disk)X +1088(space)X +1287(for)X +1401(the)X +1519(larger)X +1727(database,)X +2044(we)X +2158(report)X +2370(results)X +2599(only)X +2761(for)X +2875(the)X +2993(20,000)X +3233(part)X +3378(database.)X +3 f +555 1938(5.2.1.)N +775(Implementation)X +1 f +755 2061(The)N +920(LIBTP)X +1182(implementation)X +1724(of)X +1831(OO1)X +2027(uses)X +2205(the)X +2342(TCL)X +2532([OUST90])X +2914(interface)X +3235(described)X +3582(earlier.)X +3867(The)X +4031(backend)X +555 2151(accepts)N +813(commands)X +1181(over)X +1345(an)X +1442(IP)X +1534(socket)X +1760(and)X +1897(performs)X +2208(the)X +2327(requested)X +2656(database)X +2954(actions.)X +3242(The)X +3387(frontend)X +3679(opens)X +3886(and)X +4022(executes)X +555 2241(a)N +618(TCL)X +796(script.)X +1041(This)X +1210(script)X +1415(contains)X +1709(database)X +2013(accesses)X +2313(interleaved)X +2697(with)X +2866(ordinary)X +3165(program)X +3463(control)X +3716(statements.)X +4120(Data-)X +555 2331(base)N +718(commands)X +1085(are)X +1204(submitted)X +1539(to)X +1621(the)X +1739(backend)X +2027(and)X +2163(results)X +2392(are)X +2511(bound)X +2731(to)X +2813(program)X +3105(variables.)X +755 2454(The)N +903(parts)X +1082(table)X +1261(was)X +1409(stored)X +1628(as)X +1718(a)X +1776(B-tree)X +1999(indexed)X +2275(by)X +2 f +2377(id)X +1 f +2439(.)X +2501(The)X +2648(connection)X +3022(table)X +3200(was)X +3347(stored)X +3565(as)X +3654(a)X +3712(set)X +3823(of)X +3912(\256xed-length)X +555 2544(records)N +824(using)X +1029(the)X +1159(4.4BSD)X +1446(recno)X +1657(access)X +1895(method.)X +2207(In)X +2306(addition,)X +2620(two)X +2771(B-tree)X +3003(indices)X +3261(were)X +3449(maintained)X +3836(on)X +3947(connection)X +555 2634(table)N +732(entries.)X +1007(One)X +1162(index)X +1360(mapped)X +1634(the)X +2 f +1752(from)X +1 f +1923(\256eld)X +2085(to)X +2167(a)X +2223(connection)X +2595(record)X +2821(number,)X +3106(and)X +3242(the)X +3360(other)X +3545(mapped)X +3819(the)X +2 f +3937(to)X +1 f +4019(\256eld)X +4181(to)X +4263(a)X +555 2724(connection)N +932(record)X +1163(number.)X +1473(These)X +1690(indices)X +1941(support)X +2205(fast)X +2345(lookups)X +2622(on)X +2726(connections)X +3133(in)X +3219(both)X +3385(directions.)X +3765(For)X +3900(the)X +4022(traversal)X +555 2814(tests,)N +743(the)X +867(frontend)X +1165(does)X +1338(an)X +1439(index)X +1642(lookup)X +1889(to)X +1976(discover)X +2273(the)X +2396(connected)X +2747(part's)X +2 f +2955(id)X +1 f +3017(,)X +3062(and)X +3203(then)X +3366(does)X +3538(another)X +3804(lookup)X +4051(to)X +4138(fetch)X +555 2904(the)N +673(part)X +818(itself.)X +3 f +555 3090(5.2.2.)N +775(Performance)X +1242(Measurements)X +1766(for)X +1889(OO1)X +1 f +755 3213(We)N +888(compare)X +1186(LIBTP's)X +1487(OO1)X +1664(performance)X +2092(to)X +2174(that)X +2314(reported)X +2602(in)X +2684([CATT91].)X +3087(Those)X +3303(results)X +3532(were)X +3709(collected)X +4019(on)X +4119(a)X +4175(Sun)X +555 3303(3/280)N +759(\(25)X +888(MHz)X +1075(MC68020\))X +1448(with)X +1612(16)X +1714(MBytes)X +1989(of)X +2078(memory)X +2367(and)X +2505(two)X +2647(Hitachi)X +2904(892MByte)X +3267(disks)X +3452(\(15)X +3580(ms)X +3694(average)X +3966(seek)X +4130(time\))X +555 3393(behind)N +793(an)X +889(SMD-4)X +1149(controller.)X +1521(Frontends)X +1861(ran)X +1984(on)X +2084(an)X +2180(8MByte)X +2462(Sun)X +2606(3/260.)X +755 3516(In)N +844(order)X +1036(to)X +1120(measure)X +1410(performance)X +1839(on)X +1941(a)X +1999(machine)X +2293(of)X +2382(roughly)X +2653(equivalent)X +3009(processor)X +3339(power,)X +3582(we)X +3698(ran)X +3822(one)X +3959(set)X +4069(of)X +4157(tests)X +555 3606(on)N +666(a)X +733(standalone)X +1107(MC68030-based)X +1671(HP300)X +1923(\(33MHz)X +2225(MC68030\).)X +2646(The)X +2801(database)X +3108(was)X +3263(stored)X +3489(on)X +3599(a)X +3665(300MByte)X +4037(HP7959)X +555 3696(SCSI)N +744(disk)X +898(\(17)X +1026(ms)X +1139(average)X +1410(seek)X +1573(time\).)X +1802(Since)X +2000(this)X +2135(machine)X +2427(is)X +2500(not)X +2622(connected)X +2968(to)X +3050(a)X +3106(network,)X +3409(we)X +3523(ran)X +3646(local)X +3822(tests)X +3984(where)X +4201(the)X +555 3786(frontend)N +855(and)X +999(backend)X +1295(run)X +1430(on)X +1538(the)X +1664(same)X +1856(machine.)X +2195(We)X +2334(compare)X +2638(these)X +2830(measurements)X +3316(with)X +3485(Cattell's)X +3783(local)X +3966(Sun)X +4117(3/280)X +555 3876(numbers.)N +755 3999(Because)N +1051(the)X +1177(benchmark)X +1562(requires)X +1849(remote)X +2100(access,)X +2354(we)X +2476(ran)X +2607(another)X +2876(set)X +2993(of)X +3088(tests)X +3258(on)X +3365(a)X +3428(DECstation)X +3828(5000/200)X +4157(with)X +555 4089(32M)N +732(of)X +825(memory)X +1118(running)X +1393(Ultrix)X +1610(V4.0)X +1794(and)X +1936(a)X +1998(DEC)X +2184(1GByte)X +2459(RZ57)X +2666(SCSI)X +2859(disk.)X +3057(We)X +3194(compare)X +3496(the)X +3619(local)X +3800(performance)X +4232(of)X +555 4179(OO1)N +734(on)X +837(the)X +958(DECstation)X +1354(to)X +1439(its)X +1536(remote)X +1781(performance.)X +2250(For)X +2383(the)X +2503(remote)X +2748(case,)X +2929(we)X +3045(ran)X +3170(the)X +3290(frontend)X +3584(on)X +3686(a)X +3744(DECstation)X +4139(3100)X +555 4269(with)N +717(16)X +817(MBytes)X +1090(of)X +1177(main)X +1357(memory.)X +755 4392(The)N +900(databases)X +1228(tested)X +1435(in)X +1517([CATT91])X +1880(are)X +10 f +635 4515(g)N +1 f +755(INDEX,)X +1045(a)X +1101(highly-optimized)X +1672(access)X +1898(method)X +2158(package)X +2442(developed)X +2792(at)X +2870(Sun)X +3014(Microsystems.)X +10 f +635 4638(g)N +1 f +755(OODBMS,)X +1137(a)X +1193(beta)X +1347(release)X +1591(of)X +1678(a)X +1734(commercial)X +2133(object-oriented)X +2639(database)X +2936(management)X +3366(system.)X +10 f +635 4761(g)N +1 f +755(RDBMS,)X +1076(a)X +1133(UNIX-based)X +1565(commercial)X +1965(relational)X +2289(data)X +2444(manager)X +2742(at)X +2821(production)X +3189(release.)X +3474(The)X +3620(OO1)X +3797(implementation)X +755 4851(used)N +922(embedded)X +1272(SQL)X +1443(in)X +1525(C.)X +1638(Stored)X +1867(procedures)X +2240(were)X +2417(de\256ned)X +2673(to)X +2755(reduce)X +2990(client-server)X +3412(traf\256c.)X +755 4974(Table)N +974(two)X +1130(shows)X +1366(the)X +1500(measurements)X +1995(from)X +2187([CATT91])X +2566(and)X +2718(LIBTP)X +2976(for)X +3106(a)X +3178(local)X +3370(test)X +3517(on)X +3632(the)X +3765(MC680x0-based)X +555 5064(hardware.)N +915(All)X +1037(caches)X +1272(are)X +1391(cleared)X +1644(before)X +1870(each)X +2038(test.)X +2209(All)X +2331(times)X +2524(are)X +2643(in)X +2725(seconds.)X +755 5187(Table)N +960(two)X +1102(shows)X +1324(that)X +1466(LIBTP)X +1710(outperforms)X +2123(the)X +2242(commercial)X +2642(relational)X +2966(system,)X +3229(but)X +3352(is)X +3426(slower)X +3661(than)X +3820(OODBMS)X +4183(and)X +555 5277(INDEX.)N +872(Since)X +1077(the)X +1202(caches)X +1444(were)X +1628(cleared)X +1888(at)X +1973(the)X +2098(start)X +2263(of)X +2356(each)X +2530(test,)X +2687(disk)X +2846(throughput)X +3223(is)X +3302(critical)X +3551(in)X +3639(this)X +3780(test.)X +3957(The)X +4108(single)X +555 5367(SCSI)N +749(HP)X +877(drive)X +1068(used)X +1241(by)X +1347(LIBTP)X +1595(is)X +1674(approximately)X +2163(13%)X +2336(slower)X +2576(than)X +2739(the)X +2862(disks)X +3051(used)X +3223(in)X +3310([CATT91])X +3678(which)X +3899(accounts)X +4205(for)X +555 5457(part)N +700(of)X +787(the)X +905(difference.)X +755 5580(OODBMS)N +1118(and)X +1255(INDEX)X +1525(outperform)X +1906(LIBTP)X +2148(most)X +2323(dramatically)X +2744(on)X +2844(traversal.)X +3181(This)X +3343(is)X +3416(because)X +3691(we)X +3805(use)X +3932(index)X +4130(look-)X +555 5670(ups)N +689(to)X +774(\256nd)X +921(connections,)X +1347(whereas)X +1634(the)X +1755(other)X +1942(two)X +2084(systems)X +2359(use)X +2488(a)X +2546(link)X +2692(access)X +2920(method.)X +3222(The)X +3369(index)X +3569(requires)X +3850(us)X +3943(to)X +4027(examine)X + +15 p +%%Page: 15 15 +10 s 10 xH 0 xS 1 f +3 f +1 f +10 f +555 679(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)N +2 f +606 769(Measure)N +1 f +1019(INDEX)X +1389(OODBMS)X +1851(RDBMS)X +2250(LIBTP)X +10 f +555 771(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)N +555 787(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)N +1 f +595 869(Lookup)N +1114(5.4)X +1490(12.9)X +1950(27)X +2291(27.2)X +595 959(Traversal)N +1074(13)X +1530(9.8)X +1950(90)X +2291(47.3)X +595 1049(Insert)N +1114(7.4)X +1530(1.5)X +1950(22)X +2331(9.7)X +10 f +555 1059(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)N +555(c)X +999(c)Y +919(c)Y +839(c)Y +759(c)Y +959 1059(c)N +999(c)Y +919(c)Y +839(c)Y +759(c)Y +1329 1059(c)N +999(c)Y +919(c)Y +839(c)Y +759(c)Y +1791 1059(c)N +999(c)Y +919(c)Y +839(c)Y +759(c)Y +2190 1059(c)N +999(c)Y +919(c)Y +839(c)Y +759(c)Y +2512 1059(c)N +999(c)Y +919(c)Y +839(c)Y +759(c)Y +2618 679(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2 f +2829 769(Measure)N +3401(Cache)X +3726(Local)X +4028(Remote)X +1 f +10 f +2618 771(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2618 787(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2658 869(Lookup)N +3401(cold)X +3747(15.7)X +4078(20.6)X +3401 959(warm)N +3787(7.8)X +4078(12.4)X +10 f +2618 969(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2658 1059(Forward)N +2950(traversal)X +3401(cold)X +3747(28.4)X +4078(52.6)X +3401 1149(warm)N +3747(23.5)X +4078(47.4)X +10 f +2618 1159(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2658 1249(Backward)N +3004(traversal)X +3401(cold)X +3747(24.2)X +4078(47.4)X +3401 1339(warm)N +3747(24.3)X +4078(47.6)X +10 f +2618 1349(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +1 f +2658 1439(Insert)N +3401(cold)X +3787(7.5)X +4078(10.3)X +3401 1529(warm)N +3787(6.7)X +4078(10.9)X +10 f +2618 1539(i)N +2629(iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii)X +2618(c)X +1479(c)Y +1399(c)Y +1319(c)Y +1239(c)Y +1159(c)Y +1079(c)Y +999(c)Y +919(c)Y +839(c)Y +759(c)Y +3341 1539(c)N +1479(c)Y +1399(c)Y +1319(c)Y +1239(c)Y +1159(c)Y +1079(c)Y +999(c)Y +919(c)Y +839(c)Y +759(c)Y +3666 1539(c)N +1479(c)Y +1399(c)Y +1319(c)Y +1239(c)Y +1159(c)Y +1079(c)Y +999(c)Y +919(c)Y +839(c)Y +759(c)Y +3968 1539(c)N +1479(c)Y +1399(c)Y +1319(c)Y +1239(c)Y +1159(c)Y +1079(c)Y +999(c)Y +919(c)Y +839(c)Y +759(c)Y +4309 1539(c)N +1479(c)Y +1399(c)Y +1319(c)Y +1239(c)Y +1159(c)Y +1079(c)Y +999(c)Y +919(c)Y +839(c)Y +759(c)Y +3 f +587 1785(Table)N +823(2:)X +931(Local)X +1163(MC680x0)X +1538(Performance)X +2026(of)X +2133(Several)X +587 1875(Systems)N +883(on)X +987(OO1.)X +2667 1785(Table)N +2909(3:)X +3023(Local)X +3260(vs.)X +3397(Remote)X +3707(Performance)X +4200(of)X +2667 1875(LIBTP)N +2926(on)X +3030(OO1.)X +1 f +10 f +555 1998(h)N +579(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)X +1 f +555 2274(two)N +696(disk)X +850(pages,)X +1074(but)X +1197(the)X +1316(links)X +1492(require)X +1741(only)X +1904(one,)X +2061(regardless)X +2408(of)X +2496(database)X +2794(size.)X +2980(Cattell)X +3214(reports)X +3458(that)X +3599(lookups)X +3873(using)X +4067(B-trees)X +555 2364(instead)N +808(of)X +901(links)X +1082(makes)X +1313(traversal)X +1616(take)X +1776(twice)X +1976(as)X +2069(long)X +2237(in)X +2325(INDEX.)X +2641(Adding)X +2907(a)X +2969(link)X +3119(access)X +3351(method)X +3617(to)X +3 f +3704(db)X +1 f +3792(\(3\))X +3911(or)X +4003(using)X +4201(the)X +555 2454(existing)N +828(hash)X +995(method)X +1255(would)X +1475(apparently)X +1834(be)X +1930(a)X +1986(good)X +2166(idea.)X +755 2577(Both)N +936(OODBMS)X +1304(and)X +1446(INDEX)X +1722(issue)X +1908 0.1944(coarser-granularity)AX +2545(locks)X +2739(than)X +2902(LIBTP.)X +3189(This)X +3356(limits)X +3562(concurrency)X +3985(for)X +4104(multi-)X +555 2667(user)N +711(applications,)X +1140(but)X +1264(helps)X +1455(single-user)X +1829(applications.)X +2278(In)X +2367(addition,)X +2671(the)X +2791(fact)X +2934(that)X +3076(LIBTP)X +3319(releases)X +3595(B-tree)X +3817(locks)X +4007(early)X +4189(is)X +4263(a)X +555 2757(drawback)N +896(in)X +986(OO1.)X +1210(Since)X +1416(there)X +1605(is)X +1686(no)X +1793(concurrency)X +2218(in)X +2307(the)X +2432(benchmark,)X +2836(high-concurrency)X +3430(strategies)X +3760(only)X +3929(show)X +4125(up)X +4232(as)X +555 2847(increased)N +882(locking)X +1145(overhead.)X +1503(Finally,)X +1772(the)X +1892(architecture)X +2294(of)X +2383(the)X +2503(LIBTP)X +2747(implementation)X +3271(was)X +3418(substantially)X +3844(different)X +4143(from)X +555 2937(that)N +702(of)X +796(either)X +1006(OODBMS)X +1375(or)X +1469(INDEX.)X +1786(Both)X +1968(of)X +2062(those)X +2258(systems)X +2538(do)X +2645(the)X +2770(searches)X +3070(in)X +3159(the)X +3284(user's)X +3503(address)X +3771(space,)X +3997(and)X +4139(issue)X +555 3027(requests)N +844(for)X +964(pages)X +1173(to)X +1260(the)X +1383(server)X +1605(process.)X +1911(Pages)X +2123(are)X +2247(cached)X +2496(in)X +2583(the)X +2706(client,)X +2929(and)X +3070(many)X +3273(queries)X +3530(can)X +3667(be)X +3768(satis\256ed)X +4055(without)X +555 3117(contacting)N +910(the)X +1029(server)X +1247(at)X +1326(all.)X +1467(LIBTP)X +1710(submits)X +1979(all)X +2080(the)X +2199(queries)X +2452(to)X +2535(the)X +2653(server)X +2870(process,)X +3151(and)X +3287(receives)X +3571(database)X +3868(records)X +4125(back;)X +555 3207(it)N +619(does)X +786(no)X +886(client)X +1084(caching.)X +755 3330(The)N +911(RDBMS)X +1221(architecture)X +1632(is)X +1716(much)X +1925(closer)X +2148(to)X +2241(that)X +2392(of)X +2490(LIBTP.)X +2783(A)X +2872(server)X +3100(process)X +3372(receives)X +3667(queries)X +3930(and)X +4076(returns)X +555 3420(results)N +786(to)X +870(a)X +928(client.)X +1168(The)X +1315(timing)X +1545(results)X +1776(in)X +1860(table)X +2038(two)X +2180(clearly)X +2421(show)X +2612(that)X +2754(the)X +2874(conventional)X +3309(database)X +3607(client/server)X +4025(model)X +4246(is)X +555 3510(expensive.)N +941(LIBTP)X +1188(outperforms)X +1605(the)X +1728(RDBMS)X +2032(on)X +2136(traversal)X +2437(and)X +2577(insertion.)X +2921(We)X +3057(speculate)X +3380(that)X +3524(this)X +3663(is)X +3740(due)X +3880(in)X +3966(part)X +4115(to)X +4201(the)X +555 3600(overhead)N +870(of)X +957(query)X +1160(parsing,)X +1436(optimization,)X +1880(and)X +2016(repeated)X +2309(interpretation)X +2761(of)X +2848(the)X +2966(plan)X +3124(tree)X +3265(in)X +3347(the)X +3465(RDBMS')X +3791(query)X +3994(executor.)X +755 3723(Table)N +962(three)X +1147(shows)X +1371(the)X +1492(differences)X +1873(between)X +2164(local)X +2343(and)X +2482(remote)X +2728(execution)X +3063(of)X +3153(LIBTP's)X +3456(OO1)X +3635(implementation)X +4160(on)X +4263(a)X +555 3813(DECstation.)N +989(We)X +1122(measured)X +1451(performance)X +1879(with)X +2042(a)X +2099(populated)X +2436(\(warm\))X +2694(cache)X +2899(and)X +3036(an)X +3133(empty)X +3354(\(cold\))X +3567(cache.)X +3812(Reported)X +4126(times)X +555 3903(are)N +681(the)X +806(means)X +1037(of)X +1130(twenty)X +1374(tests,)X +1562(and)X +1704(are)X +1829(in)X +1917(seconds.)X +2237(Standard)X +2548(deviations)X +2903(were)X +3086(within)X +3316(seven)X +3525(percent)X +3788(of)X +3881(the)X +4005(mean)X +4205(for)X +555 3993(remote,)N +818(and)X +954(two)X +1094(percent)X +1351(of)X +1438(the)X +1556(mean)X +1750(for)X +1864(local.)X +755 4116(The)N +914(20ms)X +1121(overhead)X +1450(of)X +1551(TCP/IP)X +1824(on)X +1938(an)X +2048(Ethernet)X +2354(entirely)X +2633(accounts)X +2948(for)X +3076(the)X +3207(difference)X +3567(in)X +3662(speed.)X +3918(The)X +4076(remote)X +555 4206(traversal)N +857(times)X +1055(are)X +1179(nearly)X +1405(double)X +1648(the)X +1771(local)X +1952(times)X +2150(because)X +2430(we)X +2549(do)X +2653(index)X +2855(lookups)X +3132(and)X +3272(part)X +3421(fetches)X +3673(in)X +3759(separate)X +4047(queries.)X +555 4296(It)N +629(would)X +854(make)X +1053(sense)X +1252(to)X +1339(do)X +1444(indexed)X +1723(searches)X +2021(on)X +2126(the)X +2248(server,)X +2489(but)X +2615(we)X +2733(were)X +2914(unwilling)X +3244(to)X +3330(hard-code)X +3676(knowledge)X +4052(of)X +4143(OO1)X +555 4386(indices)N +803(into)X +948(our)X +1075(LIBTP)X +1317(TCL)X +1488(server.)X +1745(Cold)X +1920(and)X +2056(warm)X +2259(insertion)X +2559(times)X +2752(are)X +2871(identical)X +3167(since)X +3352(insertions)X +3683(do)X +3783(not)X +3905(bene\256t)X +4143(from)X +555 4476(caching.)N +755 4599(One)N +915(interesting)X +1279(difference)X +1632(shown)X +1867(by)X +1973(table)X +2155(three)X +2342(is)X +2421(the)X +2545(cost)X +2700(of)X +2793(forward)X +3074(versus)X +3305(backward)X +3644(traversal.)X +3987(When)X +4205(we)X +555 4689(built)N +725(the)X +847(database,)X +1168(we)X +1285(inserted)X +1562(parts)X +1741(in)X +1826(part)X +2 f +1974(id)X +1 f +2059(order.)X +2292(We)X +2427(built)X +2596(the)X +2717(indices)X +2967(at)X +3048(the)X +3169(same)X +3357(time.)X +3562(Therefore,)X +3923(the)X +4044(forward)X +555 4779(index)N +757(had)X +897(keys)X +1068(inserted)X +1346(in)X +1432(order,)X +1646(while)X +1848(the)X +1970(backward)X +2307(index)X +2509(had)X +2649(keys)X +2820(inserted)X +3098(more)X +3286(randomly.)X +3656(In-order)X +3943(insertion)X +4246(is)X +555 4885(pessimal)N +858(for)X +975(B-tree)X +1199(indices,)X +1469(so)X +1563(the)X +1684(forward)X +1962(index)X +2163(is)X +2239(much)X +2440(larger)X +2651(than)X +2812(the)X +2933(backward)X +3269(one)X +7 s +3385 4853(5)N +10 s +4885(.)Y +3476(This)X +3640(larger)X +3850(size)X +3997(shows)X +4219(up)X +555 4975(as)N +642(extra)X +823(disk)X +976(reads)X +1166(in)X +1248(the)X +1366(cold)X +1524(benchmark.)X +3 f +555 5161(6.)N +655(Conclusions)X +1 f +755 5284(LIBTP)N +1006(provides)X +1311(the)X +1438(basic)X +1632(building)X +1927(blocks)X +2165(to)X +2256(support)X +2525(transaction)X +2906(protection.)X +3300(In)X +3396(comparison)X +3799(with)X +3970(traditional)X +555 5374(Unix)N +746(libraries)X +1040(and)X +1187(commercial)X +1597(systems,)X +1900(it)X +1974(offers)X +2192(a)X +2258(variety)X +2511(of)X +2608(tradeoffs.)X +2964(Using)X +3185(complete)X +3509(transaction)X +3891(protection)X +4246(is)X +555 5464(more)N +747(complicated)X +1166(than)X +1331(simply)X +1575(adding)X +3 f +1820(fsync)X +1 f +1998(\(2\))X +2119(and)X +3 f +2262(\257ock)X +1 f +2426(\(2\))X +2547(calls)X +2721(to)X +2810(code,)X +3008(but)X +3136(it)X +3206(is)X +3285(faster)X +3490(in)X +3578(some)X +3773(cases)X +3969(and)X +4111(offers)X +8 s +10 f +555 5536(hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh)N +5 s +1 f +727 5614(5)N +8 s +763 5639(The)N +878(next)X +1004(release)X +1196(of)X +1265(the)X +1359(4.4BSD)X +1580(access)X +1758(method)X +1966(will)X +2082(automatically)X +2446(detect)X +2614(and)X +2722(compensate)X +3039(for)X +3129(in-order)X +3350(insertion,)X +3606(eliminating)X +3914(this)X +4023(problem.)X + +16 p +%%Page: 16 16 +8 s 8 xH 0 xS 1 f +10 s +3 f +1 f +555 630(stricter)N +801(guarantees)X +1168(\(atomicity,)X +1540(consistency,)X +1957(isolation,)X +2275(and)X +2414(durability\).)X +2815(If)X +2892(the)X +3013(data)X +3170(to)X +3255(be)X +3354(protected)X +3676(are)X +3798(already)X +4058(format-)X +555 720(ted)N +675(\()X +2 f +702(i.e.)X +1 f +821(use)X +949(one)X +1086(of)X +1174(the)X +1293(database)X +1591(access)X +1818(methods\),)X +2157(then)X +2316(adding)X +2555(transaction)X +2928(protection)X +3274(requires)X +3554(no)X +3655(additional)X +3996(complex-)X +555 810(ity,)N +679(but)X +801(incurs)X +1017(a)X +1073(performance)X +1500(penalty)X +1756(of)X +1843(approximately)X +2326(15%.)X +755 933(In)N +844(comparison)X +1240(with)X +1404(commercial)X +1805(database)X +2104(systems,)X +2399(the)X +2519(tradeoffs)X +2827(are)X +2948(more)X +3135(complex.)X +3473(LIBTP)X +3717(does)X +3886(not)X +4009(currently)X +555 1023(support)N +825(a)X +891(standard)X +1193(query)X +1406(language.)X +1766(The)X +1921(TCL-based)X +2312(server)X +2539(process)X +2810(allows)X +3049(a)X +3115(certain)X +3364(ease)X +3533(of)X +3630(use)X +3767(which)X +3993(would)X +4223(be)X +555 1113(enhanced)N +882(with)X +1047(a)X +1106(more)X +1294(user-friendly)X +1732(interface)X +2037(\()X +2 f +2064(e.g.)X +1 f +2203(a)X +2261(windows)X +2572(based)X +2777(query-by-form)X +3272(application\),)X +3697(for)X +3813(which)X +4031(we)X +4147(have)X +555 1203(a)N +620(working)X +916(prototype.)X +1292(When)X +1513(accesses)X +1815(do)X +1924(not)X +2055(require)X +2312(sophisticated)X +2758(query)X +2969(processing,)X +3360(the)X +3486(TCL)X +3665(interface)X +3975(is)X +4056(an)X +4160(ade-)X +555 1293(quate)N +756(solution.)X +1080(What)X +1281(LIBTP)X +1529(fails)X +1693(to)X +1781(provide)X +2052(in)X +2140(functionality,)X +2595(it)X +2665(makes)X +2896(up)X +3002(for)X +3122(in)X +3210(performance)X +3643(and)X +3785(\257exibility.)X +4161(Any)X +555 1383(application)N +931(may)X +1089(make)X +1283(use)X +1410(of)X +1497(its)X +1592(record)X +1818(interface)X +2120(or)X +2207(the)X +2325(more)X +2510(primitive)X +2823(log,)X +2965(lock,)X +3143(and)X +3279(buffer)X +3496(calls.)X +755 1506(Future)N +987(work)X +1175(will)X +1322(focus)X +1519(on)X +1621(overcoming)X +2026(some)X +2217(of)X +2306(the)X +2426(areas)X +2614(in)X +2698(which)X +2916(LIBTP)X +3160(is)X +3235(currently)X +3547(de\256cient)X +3845(and)X +3983(extending)X +555 1596(its)N +652(transaction)X +1026(model.)X +1288(The)X +1435(addition)X +1719(of)X +1808(an)X +1905(SQL)X +2077(parser)X +2295(and)X +2432(forms)X +2640(front)X +2817(end)X +2954(will)X +3099(improve)X +3387(the)X +3506(system's)X +3807(ease)X +3967(of)X +4055(use)X +4183(and)X +555 1686(make)N +750(it)X +815(more)X +1001(competitive)X +1400(with)X +1563(commercial)X +1963(systems.)X +2277(In)X +2365(the)X +2484(long)X +2647(term,)X +2835(we)X +2950(would)X +3170(like)X +3310(to)X +3392(add)X +3528(generalized)X +3919(hierarchical)X +555 1776(locking,)N +836(nested)X +1062(transactions,)X +1486(parallel)X +1748(transactions,)X +2171(passing)X +2431(of)X +2518(transactions)X +2921(between)X +3209(processes,)X +3557(and)X +3693(distributed)X +4055(commit)X +555 1866(handling.)N +900(In)X +992(the)X +1115(short)X +1300(term,)X +1492(the)X +1614(next)X +1776(step)X +1929(is)X +2006(to)X +2092(integrate)X +2397(LIBTP)X +2643(with)X +2809(the)X +2931(most)X +3110(recent)X +3331(release)X +3579(of)X +3670(the)X +3792(database)X +4093(access)X +555 1956(routines)N +833(and)X +969(make)X +1163(it)X +1227(freely)X +1435(available)X +1745(via)X +1863(anonymous)X +2252(ftp.)X +3 f +555 2142(7.)N +655(Acknowledgements)X +1 f +755 2265(We)N +888(would)X +1109(like)X +1250(to)X +1332(thank)X +1530(John)X +1701(Wilkes)X +1948(and)X +2084(Carl)X +2242(Staelin)X +2484(of)X +2571(Hewlett-Packard)X +3131(Laboratories)X +3557(and)X +3693(Jon)X +3824(Krueger.)X +4148(John)X +555 2355(and)N +694(Carl)X +855(provided)X +1162(us)X +1255(with)X +1419(an)X +1517(extra)X +1700(disk)X +1855(for)X +1971(the)X +2091(HP)X +2215(testbed)X +2464(less)X +2606(than)X +2766(24)X +2868(hours)X +3068(after)X +3238(we)X +3354(requested)X +3684(it.)X +3770(Jon)X +3903(spent)X +4094(count-)X +555 2445(less)N +699(hours)X +901(helping)X +1164(us)X +1258(understand)X +1633(the)X +1754(intricacies)X +2107(of)X +2197(commercial)X +2599(database)X +2899(products)X +3198(and)X +3337(their)X +3507(behavior)X +3811(under)X +4017(a)X +4076(variety)X +555 2535(of)N +642(system)X +884(con\256gurations.)X +3 f +555 2721(8.)N +655(References)X +1 f +555 2901([ANDR89])N +942(Andrade,)X +1265(J.,)X +1361(Carges,)X +1629(M.,)X +1765(Kovach,)X +2060(K.,)X +2183(``Building)X +2541(an)X +2642(On-Line)X +2939(Transaction)X +3343(Processing)X +3715(System)X +3975(On)X +4098(UNIX)X +727 2991(System)N +982(V'',)X +2 f +1134(CommUNIXations)X +1 f +1725(,)X +1765 0.2188(November/December)AX +2477(1989.)X +555 3171([BAY77])N +878(Bayer,)X +1110(R.,)X +1223(Schkolnick,)X +1623(M.,)X +1754(``Concurrency)X +2243(of)X +2330(Operations)X +2702(on)X +2802(B-Trees'',)X +2 f +3155(Acta)X +3322(Informatica)X +1 f +3700(,)X +3740(1977.)X +555 3351([BERN80])N +936(Bernstein,)X +1297(P.,)X +1415(Goodman,)X +1785(N.,)X +1917(``Timestamp)X +2365(Based)X +2595(Algorithms)X +2992(for)X +3119(Concurrency)X +3567(Control)X +3844(in)X +3939(Distributed)X +727 3441(Database)N +1042(Systems'',)X +2 f +1402(Proceedings)X +1823(6th)X +1945(International)X +2387(Conference)X +2777(on)X +2877(Very)X +3049(Large)X +3260(Data)X +3440(Bases)X +1 f +3627(,)X +3667(October)X +3946(1980.)X +555 3621([BSD91])N +864(DB\(3\),)X +2 f +1109(4.4BSD)X +1376(Unix)X +1552(Programmer's)X +2044(Manual)X +2313(Reference)X +2655(Guide)X +1 f +2851(,)X +2891(University)X +3249(of)X +3336(California,)X +3701(Berkeley,)X +4031(1991.)X +555 3801([CATT91])N +923(Cattell,)X +1181(R.G.G.,)X +1455(``An)X +1632(Engineering)X +2049(Database)X +2369(Benchmark'',)X +2 f +2838(The)X +2983(Benchmark)X +3373(Handbook)X +3731(for)X +3848(Database)X +4179(and)X +727 3891(Transaction)N +1133(Processing)X +1509(Systems)X +1 f +1763(,)X +1803(J.)X +1874(Gray,)X +2075(editor,)X +2302(Morgan)X +2576(Kaufman)X +2895(1991.)X +555 4071([CHEN91])N +929(Cheng,)X +1180(E.,)X +1291(Chang,)X +1542(E.,)X +1653(Klein,)X +1872(J.,)X +1964(Lee,)X +2126(D.,)X +2245(Lu,)X +2375(E.,)X +2485(Lutgardo,)X +2820(A.,)X +2939(Obermarck,)X +3342(R.,)X +3456(``An)X +3629(Open)X +3824(and)X +3961(Extensible)X +727 4161(Event-Based)N +1157(Transaction)X +1556(Manager'',)X +2 f +1936(Proceedings)X +2357(1991)X +2537(Summer)X +2820(Usenix)X +1 f +3043(,)X +3083(Nashville,)X +3430(TN,)X +3577(June)X +3744(1991.)X +555 4341([CHOU85])N +943(Chou,)X +1163(H.,)X +1288(DeWitt,)X +1570(D.,)X +1694(``An)X +1872(Evaluation)X +2245(of)X +2338(Buffer)X +2574(Management)X +3019(Strategies)X +3361(for)X +3481(Relational)X +3836(Database)X +4157(Sys-)X +727 4431(tems'',)N +2 f +972(Proceedings)X +1393(of)X +1475(the)X +1593(11th)X +1755(International)X +2197(Conference)X +2587(on)X +2687(Very)X +2859(Large)X +3070(Databases)X +1 f +3408(,)X +3448(1985.)X +555 4611([DEWI84])N +925(DeWitt,)X +1207(D.,)X +1331(Katz,)X +1529(R.,)X +1648(Olken,)X +1890(F.,)X +2000(Shapiro,)X +2295(L.,)X +2410(Stonebraker,)X +2843(M.,)X +2979(Wood,)X +3220(D.,)X +3343(``Implementation)X +3929(Techniques)X +727 4701(for)N +841(Main)X +1030(Memory)X +1326(Database)X +1641(Systems'',)X +2 f +2001(Proceedings)X +2422(of)X +2504(SIGMOD)X +1 f +2812(,)X +2852(pp.)X +2972(1-8,)X +3119(June)X +3286(1984.)X +555 4881([GRAY76])N +944(Gray,)X +1153(J.,)X +1252(Lorie,)X +1474(R.,)X +1595(Putzolu,)X +1887(F.,)X +1999(and)X +2143(Traiger,)X +2428(I.,)X +2522(``Granularity)X +2973(of)X +3067(locks)X +3263(and)X +3406(degrees)X +3679(of)X +3773(consistency)X +4174(in)X +4263(a)X +727 4971(large)N +909(shared)X +1140(data)X +1295(base'',)X +2 f +1533(Modeling)X +1861(in)X +1944(Data)X +2125(Base)X +2301(Management)X +2740(Systems)X +1 f +2994(,)X +3034(Elsevier)X +3317(North)X +3524(Holland,)X +3822(New)X +3994(York,)X +4199(pp.)X +727 5061(365-394.)N +555 5241([HAER83])N +931(Haerder,)X +1235(T.)X +1348(Reuter,)X +1606(A.)X +1728(``Principles)X +2126(of)X +2217(Transaction-Oriented)X +2928(Database)X +3246(Recovery'',)X +2 f +3651(Computing)X +4029(Surveys)X +1 f +4279(,)X +727 5331(15\(4\);)N +943(237-318,)X +1250(1983.)X +555 5511([KUNG81])N +943(Kung,)X +1162(H.)X +1261(T.,)X +1371(Richardson,)X +1777(J.,)X +1869(``On)X +2042(Optimistic)X +2400(Methods)X +2701(for)X +2816(Concurrency)X +3252(Control'',)X +2 f +3591(ACM)X +3781(Transactions)X +4219(on)X +727 5601(Database)N +1054(Systems)X +1 f +1328(6\(2\);)X +1504(213-226,)X +1811(1981.)X + +17 p +%%Page: 17 17 +10 s 10 xH 0 xS 1 f +3 f +1 f +555 630([LEHM81])N +939(Lehman,)X +1245(P.,)X +1352(Yao,)X +1529(S.,)X +1636(``Ef\256cient)X +1989(Locking)X +2279(for)X +2396(Concurrent)X +2780(Operations)X +3155(on)X +3258(B-trees'',)X +2 f +3587(ACM)X +3779(Transactions)X +4219(on)X +727 720(Database)N +1054(Systems)X +1 f +1308(,)X +1348(6\(4\),)X +1522(December)X +1873(1981.)X +555 900([MOHA91])N +964(Mohan,)X +1241(C.,)X +1364(Pirahesh,)X +1690(H.,)X +1818(``ARIES-RRH:)X +2366(Restricted)X +2721(Repeating)X +3076(of)X +3173(History)X +3442(in)X +3533(the)X +3660(ARIES)X +3920(Transaction)X +727 990(Recovery)N +1055(Method'',)X +2 f +1398(Proceedings)X +1819(7th)X +1941(International)X +2383(Conference)X +2773(on)X +2873(Data)X +3053(Engineering)X +1 f +3449(,)X +3489(Kobe,)X +3703(Japan,)X +3926(April)X +4115(1991.)X +555 1170([NODI90])N +914(Nodine,)X +1194(M.,)X +1328(Zdonik,)X +1602(S.,)X +1709(``Cooperative)X +2178(Transaction)X +2580(Hierarchies:)X +2996(A)X +3077(Transaction)X +3479(Model)X +3711(to)X +3796(Support)X +4072(Design)X +727 1260(Applications'',)N +2 f +1242(Proceedings)X +1675(16th)X +1849(International)X +2303(Conference)X +2704(on)X +2815(Very)X +2998(Large)X +3220(Data)X +3411(Bases)X +1 f +3598(,)X +3649(Brisbane,)X +3985(Australia,)X +727 1350(August)N +978(1990.)X +555 1530([OUST90])N +923(Ousterhout,)X +1324(J.,)X +1420(``Tcl:)X +1648(An)X +1771(Embeddable)X +2197(Command)X +2555(Language'',)X +2 f +2971(Proceedings)X +3396(1990)X +3580(Winter)X +3822(Usenix)X +1 f +4045(,)X +4089(Wash-)X +727 1620(ington,)N +971(D.C.,)X +1162(January)X +1432(1990.)X +555 1800([POSIX91])N +955(``Unapproved)X +1441(Draft)X +1645(for)X +1773(Realtime)X +2096(Extension)X +2450(for)X +2578(Portable)X +2879(Operating)X +3234(Systems'',)X +3608(Draft)X +3812(11,)X +3946(October)X +4239(7,)X +727 1890(1991,)N +927(IEEE)X +1121(Computer)X +1461(Society.)X +555 2070([ROSE91])N +925(Rosenblum,)X +1341(M.,)X +1484(Ousterhout,)X +1892(J.,)X +1995(``The)X +2206(Design)X +2464(and)X +2611(Implementation)X +3149(of)X +3247(a)X +3314(Log-Structured)X +3835(File)X +3990(System'',)X +2 f +727 2160(Proceedings)N +1148(of)X +1230(the)X +1348(13th)X +1510(Symposium)X +1895(on)X +1995(Operating)X +2344(Systems)X +2618(Principles)X +1 f +2947(,)X +2987(1991.)X +555 2340([SELT91])N +904(Seltzer,)X +1171(M.,)X +1306(Stonebraker,)X +1738(M.,)X +1873(``Read)X +2116(Optimized)X +2478(File)X +2626(Systems:)X +2938(A)X +3020(Performance)X +3454(Evaluation'',)X +2 f +3898(Proceedings)X +727 2430(7th)N +849(Annual)X +1100(International)X +1542(Conference)X +1932(on)X +2032(Data)X +2212(Engineering)X +1 f +2608(,)X +2648(Kobe,)X +2862(Japan,)X +3085(April)X +3274(1991.)X +555 2610([SPEC88])N +907(Spector,)X +1200(Rausch,)X +1484(Bruell,)X +1732(``Camelot:)X +2107(A)X +2192(Flexible,)X +2501(Distributed)X +2888(Transaction)X +3294(Processing)X +3668(System'',)X +2 f +4004(Proceed-)X +727 2700(ings)N +880(of)X +962(Spring)X +1195(COMPCON)X +1606(1988)X +1 f +(,)S +1806(February)X +2116(1988.)X +555 2880([SQL86])N +862(American)X +1201(National)X +1499(Standards)X +1836(Institute,)X +2139(``Database)X +2509(Language)X +2847(SQL'',)X +3093(ANSI)X +3301(X3.135-1986)X +3747(\(ISO)X +3924(9075\),)X +4152(May)X +727 2970(1986.)N +555 3150([STON81])N +919(Stonebraker,)X +1348(M.,)X +1480(``Operating)X +1876(System)X +2132(Support)X +2406(for)X +2520(Database)X +2835(Management'',)X +2 f +3348(Communications)X +3910(of)X +3992(the)X +4110(ACM)X +1 f +4279(,)X +727 3240(1981.)N +555 3420([SULL92])N +925(Sullivan,)X +1247(M.,)X +1394(Olson,)X +1641(M.,)X +1788(``An)X +1976(Index)X +2195(Implementation)X +2737(Supporting)X +3127(Fast)X +3295(Recovery)X +3638(for)X +3767(the)X +3900(POSTGRES)X +727 3510(Storage)N +1014(System'',)X +1365(to)X +1469(appear)X +1726(in)X +2 f +1830(Proceedings)X +2272(8th)X +2415(Annual)X +2687(International)X +3150(Conference)X +3561(on)X +3682(Data)X +3883(Engineering)X +1 f +4279(,)X +727 3600(Tempe,)N +990(Arizona,)X +1289(February)X +1599(1992.)X +555 3780([TPCB90])N +914(Transaction)X +1319(Processing)X +1692(Performance)X +2129(Council,)X +2428(``TPC)X +2653(Benchmark)X +3048(B'',)X +3200(Standard)X +3510(Speci\256cation,)X +3973(Waterside)X +727 3870(Associates,)N +1110(Fremont,)X +1421(CA.,)X +1592(1990.)X +555 4050([YOUN91])N +947(Young,)X +1211(M.)X +1328(W.,)X +1470(Thompson,)X +1858(D.)X +1962(S.,)X +2072(Jaffe,)X +2274(E.,)X +2388(``A)X +2525(Modular)X +2826(Architecture)X +3253(for)X +3372(Distributed)X +3757(Transaction)X +4161(Pro-)X +727 4140(cessing'',)N +2 f +1057(Proceedings)X +1478(1991)X +1658(Winter)X +1896(Usenix)X +1 f +2119(,)X +2159(Dallas,)X +2404(TX,)X +2551(January)X +2821(1991.)X +3 f +755 4263(Margo)N +1008(I.)X +1080(Seltzer)X +1 f +1338(is)X +1411(a)X +1467(Ph.D.)X +1669(student)X +1920(in)X +2002(the)X +2120(Department)X +2519(of)X +2606(Electrical)X +2934(Engineering)X +3346(and)X +3482(Computer)X +3822(Sciences)X +4123(at)X +4201(the)X +555 4353(University)N +919(of)X +1012(California,)X +1383(Berkeley.)X +1739(Her)X +1886(research)X +2181(interests)X +2474(include)X +2735(\256le)X +2862(systems,)X +3160(databases,)X +3513(and)X +3654(transaction)X +4031(process-)X +555 4443(ing)N +686(systems.)X +1008(She)X +1157(spent)X +1355(several)X +1612(years)X +1811(working)X +2107(at)X +2194(startup)X +2441(companies)X +2813(designing)X +3153(and)X +3298(implementing)X +3771(\256le)X +3902(systems)X +4183(and)X +555 4533(transaction)N +929(processing)X +1294(software)X +1592(and)X +1729(designing)X +2061(microprocessors.)X +2648(Ms.)X +2791(Seltzer)X +3035(received)X +3329(her)X +3453(AB)X +3585(in)X +3668(Applied)X +3947(Mathemat-)X +555 4623(ics)N +664(from)X +840 0.1953(Harvard/Radcliffe)AX +1445(College)X +1714(in)X +1796(1983.)X +755 4746(In)N +845(her)X +971(spare)X +1163(time,)X +1347(Margo)X +1583(can)X +1717(usually)X +1970(be)X +2068(found)X +2277(preparing)X +2607(massive)X +2887(quantities)X +3220(of)X +3309(food)X +3478(for)X +3594(hungry)X +3843(hordes,)X +4099(study-)X +555 4836(ing)N +677(Japanese,)X +1003(or)X +1090(playing)X +1350(soccer)X +1576(with)X +1738(an)X +1834(exciting)X +2112(Bay)X +2261(Area)X +2438(Women's)X +2770(Soccer)X +3009(team,)X +3205(the)X +3323(Berkeley)X +3633(Bruisers.)X +3 f +755 5049(Michael)N +1056(A.)X +1159(Olson)X +1 f +1383(is)X +1461(a)X +1522(Master's)X +1828(student)X +2084(in)X +2170(the)X +2292(Department)X +2695(of)X +2786(Electrical)X +3118(Engineering)X +3534(and)X +3674(Computer)X +4018(Sciences)X +555 5139(at)N +645(the)X +774(University)X +1143(of)X +1241(California,)X +1617(Berkeley.)X +1978(His)X +2120(primary)X +2405(interests)X +2703(are)X +2833(database)X +3141(systems)X +3425(and)X +3572(mass)X +3763(storage)X +4026(systems.)X +555 5229(Mike)N +759(spent)X +963(two)X +1118(years)X +1323(working)X +1625(for)X +1754(a)X +1825(commercial)X +2239(database)X +2551(system)X +2808(vendor)X +3066(before)X +3307(joining)X +3567(the)X +3699(Postgres)X +4004(Research)X +555 5319(Group)N +780(at)X +858(Berkeley)X +1168(in)X +1250(1988.)X +1470(He)X +1584(received)X +1877(his)X +1990(B.A.)X +2161(in)X +2243(Computer)X +2583(Science)X +2853(from)X +3029(Berkeley)X +3339(in)X +3421(May)X +3588(1991.)X +755 5442(Mike)N +945(only)X +1108(recently)X +1388(transferred)X +1758(into)X +1903(Sin)X +2030(City,)X +2208(but)X +2330(is)X +2403(rapidly)X +2650(adopting)X +2950(local)X +3126(customs)X +3408(and)X +3544(coloration.)X +3929(In)X +4016(his)X +4129(spare)X +555 5532(time,)N +742(he)X +843(organizes)X +1176(informal)X +1477(Friday)X +1711(afternoon)X +2043(study)X +2240(groups)X +2482(to)X +2568(discuss)X +2823(recent)X +3044(technical)X +3358(and)X +3498(economic)X +3834(developments.)X +555 5622(Among)N +815(his)X +928(hobbies)X +1197(are)X +1316(Charles)X +1581(Dickens,)X +1884(Red)X +2033(Rock,)X +2242(and)X +2378(speaking)X +2683(Dutch)X +2899(to)X +2981(anyone)X +3233(who)X +3391(will)X +3535(permit)X +3764(it.)X + +17 p +%%Trailer +xt + +xs + diff --git a/lib/libc/db/hash/Makefile.inc b/lib/libc/db/hash/Makefile.inc new file mode 100644 index 0000000..c5a2a61 --- /dev/null +++ b/lib/libc/db/hash/Makefile.inc @@ -0,0 +1,7 @@ +# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/db/hash/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +.PATH: ${LIBC_SRCTOP}/db/hash + +SRCS+= hash.c hash_bigkey.c hash_buf.c hash_func.c hash_log2.c \ + hash_page.c ndbm.c diff --git a/lib/libc/db/man/Makefile.inc b/lib/libc/db/man/Makefile.inc new file mode 100644 index 0000000..8868991 --- /dev/null +++ b/lib/libc/db/man/Makefile.inc @@ -0,0 +1,18 @@ +# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/db/man/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +.PATH: ${LIBC_SRCTOP}/db/man + +MAN+= btree.3 dbm.3 dbopen.3 hash.3 mpool.3 recno.3 + +MLINKS+= dbm.3 dbm_clearerr.3 +MLINKS+= dbm.3 dbm_close.3 +MLINKS+= dbm.3 dbm_delete.3 +MLINKS+= dbm.3 dbm_dirnfo.3 +MLINKS+= dbm.3 dbm_error.3 +MLINKS+= dbm.3 dbm_fetch.3 +MLINKS+= dbm.3 dbm_firstkey.3 +MLINKS+= dbm.3 dbm_nextkey.3 +MLINKS+= dbm.3 dbm_open.3 +MLINKS+= dbm.3 dbm_store.3 +MLINKS+= dbopen.3 db.3 diff --git a/lib/libc/db/man/btree.3 b/lib/libc/db/man/btree.3 new file mode 100644 index 0000000..590a256 --- /dev/null +++ b/lib/libc/db/man/btree.3 @@ -0,0 +1,271 @@ +.\" Copyright (c) 1990, 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. +.\" 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. +.\" +.\" @(#)btree.3 8.4 (Berkeley) 8/18/94 +.\" $FreeBSD: releng/11.1/lib/libc/db/man/btree.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd August 18, 1994 +.Dt BTREE 3 +.Os +.Sh NAME +.Nm btree +.Nd "btree database access method" +.Sh SYNOPSIS +.In sys/types.h +.In db.h +.Sh DESCRIPTION +The routine +.Fn dbopen +is the library interface to database files. +One of the supported file formats is +.Nm +files. +The general description of the database access methods is in +.Xr dbopen 3 , +this manual page describes only the +.Nm +specific information. +.Pp +The +.Nm +data structure is a sorted, balanced tree structure storing +associated key/data pairs. +.Pp +The +.Nm +access method specific data structure provided to +.Fn dbopen +is defined in the +.In db.h +include file as follows: +.Bd -literal +typedef struct { + u_long flags; + u_int cachesize; + int maxkeypage; + int minkeypage; + u_int psize; + int (*compare)(const DBT *key1, const DBT *key2); + size_t (*prefix)(const DBT *key1, const DBT *key2); + int lorder; +} BTREEINFO; +.Ed +.Pp +The elements of this structure are as follows: +.Bl -tag -width indent +.It Va flags +The flag value is specified by +.Em or Ns 'ing +any of the following values: +.Bl -tag -width indent +.It Dv R_DUP +Permit duplicate keys in the tree, i.e., permit insertion if the key to be +inserted already exists in the tree. +The default behavior, as described in +.Xr dbopen 3 , +is to overwrite a matching key when inserting a new key or to fail if +the +.Dv R_NOOVERWRITE +flag is specified. +The +.Dv R_DUP +flag is overridden by the +.Dv R_NOOVERWRITE +flag, and if the +.Dv R_NOOVERWRITE +flag is specified, attempts to insert duplicate keys into +the tree will fail. +.Pp +If the database contains duplicate keys, the order of retrieval of +key/data pairs is undefined if the +.Va get +routine is used, however, +.Va seq +routine calls with the +.Dv R_CURSOR +flag set will always return the logical +.Dq first +of any group of duplicate keys. +.El +.It Va cachesize +A suggested maximum size (in bytes) of the memory cache. +This value is +.Em only +advisory, and the access method will allocate more memory rather than fail. +Since every search examines the root page of the tree, caching the most +recently used pages substantially improves access time. +In addition, physical writes are delayed as long as possible, so a moderate +cache can reduce the number of I/O operations significantly. +Obviously, using a cache increases (but only increases) the likelihood of +corruption or lost data if the system crashes while a tree is being modified. +If +.Va cachesize +is 0 (no size is specified) a default cache is used. +.It Va maxkeypage +The maximum number of keys which will be stored on any single page. +Not currently implemented. +.\" The maximum number of keys which will be stored on any single page. +.\" Because of the way the +.\" .Nm +.\" data structure works, +.\" .Va maxkeypage +.\" must always be greater than or equal to 2. +.\" If +.\" .Va maxkeypage +.\" is 0 (no maximum number of keys is specified) the page fill factor is +.\" made as large as possible (which is almost invariably what is wanted). +.It Va minkeypage +The minimum number of keys which will be stored on any single page. +This value is used to determine which keys will be stored on overflow +pages, i.e., if a key or data item is longer than the pagesize divided +by the minkeypage value, it will be stored on overflow pages instead +of in the page itself. +If +.Va minkeypage +is 0 (no minimum number of keys is specified) a value of 2 is used. +.It Va psize +Page size is the size (in bytes) of the pages used for nodes in the tree. +The minimum page size is 512 bytes and the maximum page size is 64K. +If +.Va psize +is 0 (no page size is specified) a page size is chosen based on the +underlying file system I/O block size. +.It Va compare +Compare is the key comparison function. +It must return an integer less than, equal to, or greater than zero if the +first key argument is considered to be respectively less than, equal to, +or greater than the second key argument. +The same comparison function must be used on a given tree every time it +is opened. +If +.Va compare +is +.Dv NULL +(no comparison function is specified), the keys are compared +lexically, with shorter keys considered less than longer keys. +.It Va prefix +The +.Va prefix +element +is the prefix comparison function. +If specified, this routine must return the number of bytes of the second key +argument which are necessary to determine that it is greater than the first +key argument. +If the keys are equal, the key length should be returned. +Note, the usefulness of this routine is very data dependent, but, in some +data sets can produce significantly reduced tree sizes and search times. +If +.Va prefix +is +.Dv NULL +(no prefix function is specified), +.Em and +no comparison function is specified, a default lexical comparison routine +is used. +If +.Va prefix +is +.Dv NULL +and a comparison routine is specified, no prefix comparison is +done. +.It Va lorder +The byte order for integers in the stored database metadata. +The number should represent the order as an integer; for example, +big endian order would be the number 4,321. +If +.Va lorder +is 0 (no order is specified) the current host order is used. +.El +.Pp +If the file already exists (and the +.Dv O_TRUNC +flag is not specified), the +values specified for the +.Va flags , lorder +and +.Va psize +arguments +are ignored +in favor of the values used when the tree was created. +.Pp +Forward sequential scans of a tree are from the least key to the greatest. +.Pp +Space freed up by deleting key/data pairs from the tree is never reclaimed, +although it is normally made available for reuse. +This means that the +.Nm +storage structure is grow-only. +The only solutions are to avoid excessive deletions, or to create a fresh +tree periodically from a scan of an existing one. +.Pp +Searches, insertions, and deletions in a +.Nm +will all complete in +O lg base N where base is the average fill factor. +Often, inserting ordered data into +.Nm Ns s +results in a low fill factor. +This implementation has been modified to make ordered insertion the best +case, resulting in a much better than normal page fill factor. +.Sh ERRORS +The +.Nm +access method routines may fail and set +.Va errno +for any of the errors specified for the library routine +.Xr dbopen 3 . +.Sh SEE ALSO +.Xr dbopen 3 , +.Xr hash 3 , +.Xr mpool 3 , +.Xr recno 3 +.Rs +.%T "The Ubiquitous B-tree" +.%A Douglas Comer +.%J "ACM Comput. Surv. 11" +.%N 2 +.%D June 1979 +.%P 121-138 +.Re +.Rs +.%A Bayer +.%A Unterauer +.%T "Prefix B-trees" +.%J "ACM Transactions on Database Systems" +.%N 1 +.%V Vol. 2 +.%D March 1977 +.%P 11-26 +.Re +.Rs +.%B "The Art of Computer Programming Vol. 3: Sorting and Searching" +.%A D. E. Knuth +.%D 1968 +.%P 471-480 +.Re +.Sh BUGS +Only big and little endian byte order is supported. diff --git a/lib/libc/db/man/dbm.3 b/lib/libc/db/man/dbm.3 new file mode 100644 index 0000000..f3e9f1f --- /dev/null +++ b/lib/libc/db/man/dbm.3 @@ -0,0 +1,226 @@ +.\" Copyright (c) 1999 Tim Singletary +.\" No copyright is claimed. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/db/man/dbm.3 301066 2016-05-31 18:32:57Z ed $ +.\" +.Dd May 30, 2016 +.Dt DBM 3 +.Os +.Sh NAME +.Nm dbm_clearerr , +.Nm dbm_close , +.Nm dbm_delete , +.Nm dbm_dirfno , +.Nm dbm_error , +.Nm dbm_fetch , +.Nm dbm_firstkey , +.Nm dbm_nextkey , +.Nm dbm_open , +.Nm dbm_store +.Nd database access functions +.Sh SYNOPSIS +.In fcntl.h +.In ndbm.h +.Ft DBM * +.Fn dbm_open "const char *base" "int flags" "mode_t mode" +.Ft void +.Fn dbm_close "DBM *db" +.Ft int +.Fn dbm_store "DBM *db" "datum key" "datum data" "int flags" +.Ft datum +.Fn dbm_fetch "DBM *db" "datum key" +.Ft int +.Fn dbm_delete "DBM *db" "datum key" +.Ft datum +.Fn dbm_firstkey "DBM *db" +.Ft datum +.Fn dbm_nextkey "DBM *db" +.Ft int +.Fn dbm_error "DBM *db" +.Ft int +.Fn dbm_clearerr "DBM *db" +.Ft int +.Fn dbm_dirfno "DBM *db" +.Sh DESCRIPTION +Database access functions. +These functions are implemented using +.Xr dbopen 3 +with a +.Xr hash 3 +database. +.Pp +.Vt datum +is declared in +.In ndbm.h : +.Bd -literal +typedef struct { + void *dptr; + int dsize; +} datum; +.Ed +.Pp +The +.Fn dbm_open base flags mode +function +opens or creates a database. +The +.Fa base +argument +is the basename of the file containing +the database; the actual database has a +.Pa .db +suffix. +I.e., if +.Fa base +is +.Qq Li /home/me/mystuff +then the actual database is in the file +.Pa /home/me/mystuff.db . +The +.Fa flags +and +.Fa mode +arguments +are passed to +.Xr open 2 . +.Pq Dv O_RDWR | O_CREAT +is a typical value for +.Fa flags ; +.Li 0660 +is a typical value for +.Fa mode . +.Dv O_WRONLY +is not allowed in +.Fa flags . +The pointer returned by +.Fn dbm_open +identifies the database and is the +.Fa db +argument to the other functions. +The +.Fn dbm_open +function +returns +.Dv NULL +and sets +.Va errno +if there were any errors. +.Pp +The +.Fn dbm_close db +function +closes the database. +.Pp +The +.Fn dbm_store db key data flags +function +inserts or replaces an entry in the database. +The +.Fa flags +argument +is either +.Dv DBM_INSERT +or +.Dv DBM_REPLACE . +If +.Fa flags +is +.Dv DBM_INSERT +and the database already contains an entry for +.Fa key , +that entry is not replaced. +Otherwise the entry is replaced or inserted. +The +.Fn dbm_store +function +normally returns zero but returns 1 if the entry could not be +inserted (because +.Fa flags +is +.Dv DBM_INSERT , +and an entry with +.Fa key +already exists) or returns -1 and sets +.Va errno +if there were any errors. +.Pp +The +.Fn dbm_fetch db key +function +returns +.Dv NULL +or the +.Fa data +corresponding to +.Fa key . +.Pp +The +.Fn dbm_delete db key +function +deletes the entry for +.Fa key . +The +.Fn dbm_delete +function +normally returns zero or returns -1 and sets +.Va errno +if there were any errors. +.Pp +The +.Fn dbm_firstkey db +function +returns the first key in the database. +The +.Fn dbm_nextkey db +function +returns subsequent keys. +The +.Fn db_firstkey +function +must be called before +.Fn dbm_nextkey . +The order in which keys are returned is unspecified and may appear +random. +The +.Fn dbm_nextkey +function +returns +.Dv NULL +after all keys have been returned. +.Pp +The +.Fn dbm_error db +function +returns the +.Va errno +value of the most recent error. +The +.Fn dbm_clearerr db +function +resets this value to 0 and returns 0. +.Pp +The +.Fn dbm_dirfno db +function +returns the file descriptor to the database. +.Sh SEE ALSO +.Xr open 2 , +.Xr dbopen 3 , +.Xr hash 3 +.Sh STANDARDS +These functions (except +.Fn dbm_dirfno ) +are included in the +.St -susv2 . diff --git a/lib/libc/db/man/dbopen.3 b/lib/libc/db/man/dbopen.3 new file mode 100644 index 0000000..def2a90 --- /dev/null +++ b/lib/libc/db/man/dbopen.3 @@ -0,0 +1,546 @@ +.\" Copyright (c) 1990, 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. +.\" 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. +.\" +.\" @(#)dbopen.3 8.5 (Berkeley) 1/2/94 +.\" $FreeBSD: releng/11.1/lib/libc/db/man/dbopen.3 212492 2010-09-12 14:04:05Z gjb $ +.\" +.Dd September 10, 2010 +.Dt DBOPEN 3 +.Os +.Sh NAME +.Nm dbopen +.Nd "database access methods" +.Sh SYNOPSIS +.In sys/types.h +.In db.h +.In fcntl.h +.In limits.h +.Ft DB * +.Fn dbopen "const char *file" "int flags" "int mode" "DBTYPE type" "const void *openinfo" +.Sh DESCRIPTION +The +.Fn dbopen +function +is the library interface to database files. +The supported file formats are btree, hashed and UNIX file oriented. +The btree format is a representation of a sorted, balanced tree structure. +The hashed format is an extensible, dynamic hashing scheme. +The flat-file format is a byte stream file with fixed or variable length +records. +The formats and file format specific information are described in detail +in their respective manual pages +.Xr btree 3 , +.Xr hash 3 +and +.Xr recno 3 . +.Pp +The +.Fn dbopen +function +opens +.Fa file +for reading and/or writing. +Files never intended to be preserved on disk may be created by setting +the +.Fa file +argument to +.Dv NULL . +.Pp +The +.Fa flags +and +.Fa mode +arguments +are as specified to the +.Xr open 2 +routine, however, only the +.Dv O_CREAT , O_EXCL , O_EXLOCK , O_NOFOLLOW , O_NONBLOCK , +.Dv O_RDONLY , O_RDWR , O_SHLOCK , O_SYNC +and +.Dv O_TRUNC +flags are meaningful. +(Note, opening a database file +.Dv O_WRONLY +is not possible.) +.\"Three additional options may be specified by +.\".Em or Ns 'ing +.\"them into the +.\".Fa flags +.\"argument. +.\".Bl -tag -width indent +.\".It Dv DB_LOCK +.\"Do the necessary locking in the database to support concurrent access. +.\"If concurrent access is not needed or the database is read-only this +.\"flag should not be set, as it tends to have an associated performance +.\"penalty. +.\".It Dv DB_SHMEM +.\"Place the underlying memory pool used by the database in shared +.\"memory. +.\"Necessary for concurrent access. +.\".It Dv DB_TXN +.\"Support transactions in the database. +.\"The +.\".Dv DB_LOCK +.\"and +.\".Dv DB_SHMEM +.\"flags must be set as well. +.\".El +.Pp +The +.Fa type +argument is of type +.Ft DBTYPE +(as defined in the +.In db.h +include file) and +may be set to +.Dv DB_BTREE , DB_HASH +or +.Dv DB_RECNO . +.Pp +The +.Fa openinfo +argument is a pointer to an access method specific structure described +in the access method's manual page. +If +.Fa openinfo +is +.Dv NULL , +each access method will use defaults appropriate for the system +and the access method. +.Pp +The +.Fn dbopen +function +returns a pointer to a +.Ft DB +structure on success and +.Dv NULL +on error. +The +.Ft DB +structure is defined in the +.In db.h +include file, and contains at +least the following fields: +.Bd -literal +typedef struct { + DBTYPE type; + int (*close)(DB *db); + int (*del)(const DB *db, const DBT *key, u_int flags); + int (*fd)(const DB *db); + int (*get)(const DB *db, const DBT *key, DBT *data, u_int flags); + int (*put)(const DB *db, DBT *key, const DBT *data, + u_int flags); + int (*sync)(const DB *db, u_int flags); + int (*seq)(const DB *db, DBT *key, DBT *data, u_int flags); +} DB; +.Ed +.Pp +These elements describe a database type and a set of functions performing +various actions. +These functions take a pointer to a structure as returned by +.Fn dbopen , +and sometimes one or more pointers to key/data structures and a flag value. +.Bl -tag -width indent +.It Va type +The type of the underlying access method (and file format). +.It Va close +A pointer to a routine to flush any cached information to disk, free any +allocated resources, and close the underlying file(s). +Since key/data pairs may be cached in memory, failing to sync the file +with a +.Va close +or +.Va sync +function may result in inconsistent or lost information. +.Va close +routines return -1 on error (setting +.Va errno ) +and 0 on success. +.It Va del +A pointer to a routine to remove key/data pairs from the database. +.Pp +The +.Fa flags +argument +may be set to the following value: +.Bl -tag -width indent +.It Dv R_CURSOR +Delete the record referenced by the cursor. +The cursor must have previously been initialized. +.El +.Pp +.Va delete +routines return -1 on error (setting +.Va errno ) , +0 on success, and 1 if the specified +.Fa key +was not in the file. +.It Va fd +A pointer to a routine which returns a file descriptor representative +of the underlying database. +A file descriptor referencing the same file will be returned to all +processes which call +.Fn dbopen +with the same +.Fa file +name. +This file descriptor may be safely used as an argument to the +.Xr fcntl 2 +and +.Xr flock 2 +locking functions. +The file descriptor is not necessarily associated with any of the +underlying files used by the access method. +No file descriptor is available for in memory databases. +.Va \&Fd +routines return -1 on error (setting +.Va errno ) , +and the file descriptor on success. +.It Va get +A pointer to a routine which is the interface for keyed retrieval from +the database. +The address and length of the data associated with the specified +.Fa key +are returned in the structure referenced by +.Fa data . +.Va get +routines return -1 on error (setting +.Va errno ) , +0 on success, and 1 if the +.Fa key +was not in the file. +.It Va put +A pointer to a routine to store key/data pairs in the database. +.Pp +The +.Fa flags +argument +may be set to one of the following values: +.Bl -tag -width indent +.It Dv R_CURSOR +Replace the key/data pair referenced by the cursor. +The cursor must have previously been initialized. +.It Dv R_IAFTER +Append the data immediately after the data referenced by +.Fa key , +creating a new key/data pair. +The record number of the appended key/data pair is returned in the +.Fa key +structure. +(Applicable only to the +.Dv DB_RECNO +access method.) +.It Dv R_IBEFORE +Insert the data immediately before the data referenced by +.Fa key , +creating a new key/data pair. +The record number of the inserted key/data pair is returned in the +.Fa key +structure. +(Applicable only to the +.Dv DB_RECNO +access method.) +.It Dv R_NOOVERWRITE +Enter the new key/data pair only if the key does not previously exist. +.It Dv R_SETCURSOR +Store the key/data pair, setting or initializing the position of the +cursor to reference it. +(Applicable only to the +.Dv DB_BTREE +and +.Dv DB_RECNO +access methods.) +.El +.Pp +.Dv R_SETCURSOR +is available only for the +.Dv DB_BTREE +and +.Dv DB_RECNO +access +methods because it implies that the keys have an inherent order +which does not change. +.Pp +.Dv R_IAFTER +and +.Dv R_IBEFORE +are available only for the +.Dv DB_RECNO +access method because they each imply that the access method is able to +create new keys. +This is only true if the keys are ordered and independent, record numbers +for example. +.Pp +The default behavior of the +.Va put +routines is to enter the new key/data pair, replacing any previously +existing key. +.Pp +.Va put +routines return -1 on error (setting +.Va errno ) , +0 on success, and 1 if the +.Dv R_NOOVERWRITE +flag +was set and the key already exists in the file. +.It Va seq +A pointer to a routine which is the interface for sequential +retrieval from the database. +The address and length of the key are returned in the structure +referenced by +.Fa key , +and the address and length of the data are returned in the +structure referenced +by +.Fa data . +.Pp +Sequential key/data pair retrieval may begin at any time, and the +position of the +.Dq cursor +is not affected by calls to the +.Va del , +.Va get , +.Va put , +or +.Va sync +routines. +Modifications to the database during a sequential scan will be reflected +in the scan, i.e., records inserted behind the cursor will not be returned +while records inserted in front of the cursor will be returned. +.Pp +The +.Fa flags +argument +.Em must +be set to one of the following values: +.Bl -tag -width indent +.It Dv R_CURSOR +The data associated with the specified key is returned. +This differs from the +.Va get +routines in that it sets or initializes the cursor to the location of +the key as well. +(Note, for the +.Dv DB_BTREE +access method, the returned key is not necessarily an +exact match for the specified key. +The returned key is the smallest key greater than or equal to the specified +key, permitting partial key matches and range searches.) +.It Dv R_FIRST +The first key/data pair of the database is returned, and the cursor +is set or initialized to reference it. +.It Dv R_LAST +The last key/data pair of the database is returned, and the cursor +is set or initialized to reference it. +(Applicable only to the +.Dv DB_BTREE +and +.Dv DB_RECNO +access methods.) +.It Dv R_NEXT +Retrieve the key/data pair immediately after the cursor. +If the cursor is not yet set, this is the same as the +.Dv R_FIRST +flag. +.It Dv R_PREV +Retrieve the key/data pair immediately before the cursor. +If the cursor is not yet set, this is the same as the +.Dv R_LAST +flag. +(Applicable only to the +.Dv DB_BTREE +and +.Dv DB_RECNO +access methods.) +.El +.Pp +.Dv R_LAST +and +.Dv R_PREV +are available only for the +.Dv DB_BTREE +and +.Dv DB_RECNO +access methods because they each imply that the keys have an inherent +order which does not change. +.Pp +.Va seq +routines return -1 on error (setting +.Va errno ) , +0 on success and 1 if there are no key/data pairs less than or greater +than the specified or current key. +If the +.Dv DB_RECNO +access method is being used, and if the database file +is a character special file and no complete key/data pairs are currently +available, the +.Va seq +routines return 2. +.It Va sync +A pointer to a routine to flush any cached information to disk. +If the database is in memory only, the +.Va sync +routine has no effect and will always succeed. +.Pp +The +.Fa flags +argument may be set to the following value: +.Bl -tag -width indent +.It Dv R_RECNOSYNC +If the +.Dv DB_RECNO +access method is being used, this flag causes +the +.Va sync +routine to apply to the btree file which underlies the +recno file, not the recno file itself. +(See the +.Va bfname +field of the +.Xr recno 3 +manual page for more information.) +.El +.Pp +.Va sync +routines return -1 on error (setting +.Va errno ) +and 0 on success. +.El +.Sh "KEY/DATA PAIRS" +Access to all file types is based on key/data pairs. +Both keys and data are represented by the following data structure: +.Bd -literal +typedef struct { + void *data; + size_t size; +} DBT; +.Ed +.Pp +The elements of the +.Ft DBT +structure are defined as follows: +.Bl -tag -width "data" +.It Va data +A pointer to a byte string. +.It Va size +The length of the byte string. +.El +.Pp +Key and data byte strings may reference strings of essentially unlimited +length although any two of them must fit into available memory at the same +time. +It should be noted that the access methods provide no guarantees about +byte string alignment. +.Sh ERRORS +The +.Fn dbopen +routine may fail and set +.Va errno +for any of the errors specified for the library routines +.Xr open 2 +and +.Xr malloc 3 +or the following: +.Bl -tag -width Er +.It Bq Er EFTYPE +A file is incorrectly formatted. +.It Bq Er EINVAL +An argument has been specified (hash function, pad byte etc.) that is +incompatible with the current file specification or which is not +meaningful for the function (for example, use of the cursor without +prior initialization) or there is a mismatch between the version +number of file and the software. +.El +.Pp +The +.Va close +routines may fail and set +.Va errno +for any of the errors specified for the library routines +.Xr close 2 , +.Xr read 2 , +.Xr write 2 , +.Xr free 3 , +or +.Xr fsync 2 . +.Pp +The +.Va del , +.Va get , +.Va put +and +.Va seq +routines may fail and set +.Va errno +for any of the errors specified for the library routines +.Xr read 2 , +.Xr write 2 , +.Xr free 3 +or +.Xr malloc 3 . +.Pp +The +.Va fd +routines will fail and set +.Va errno +to +.Er ENOENT +for in memory databases. +.Pp +The +.Va sync +routines may fail and set +.Va errno +for any of the errors specified for the library routine +.Xr fsync 2 . +.Sh SEE ALSO +.Xr btree 3 , +.Xr hash 3 , +.Xr mpool 3 , +.Xr recno 3 +.Rs +.%T "LIBTP: Portable, Modular Transactions for UNIX" +.%A Margo Seltzer +.%A Michael Olson +.%R "USENIX proceedings" +.%D Winter 1992 +.Re +.Sh BUGS +The typedef +.Ft DBT +is a mnemonic for +.Dq "data base thang" , +and was used +because noone could think of a reasonable name that was not already used. +.Pp +The file descriptor interface is a kluge and will be deleted in a +future version of the interface. +.Pp +None of the access methods provide any form of concurrent access, +locking, or transactions. diff --git a/lib/libc/db/man/hash.3 b/lib/libc/db/man/hash.3 new file mode 100644 index 0000000..31ba0cf --- /dev/null +++ b/lib/libc/db/man/hash.3 @@ -0,0 +1,196 @@ +.\" Copyright (c) 1990, 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. +.\" 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. +.\" +.\" @(#)hash.3 8.6 (Berkeley) 8/18/94 +.\" $FreeBSD: releng/11.1/lib/libc/db/man/hash.3 231564 2012-02-12 18:29:56Z ed $ +.\" +.Dd August 18, 1994 +.Dt HASH 3 +.Os +.Sh NAME +.Nm hash +.Nd "hash database access method" +.Sh SYNOPSIS +.In sys/types.h +.In db.h +.Sh DESCRIPTION +The routine +.Fn dbopen +is the library interface to database files. +One of the supported file formats is +.Nm +files. +The general description of the database access methods is in +.Xr dbopen 3 , +this manual page describes only the +.Nm +specific information. +.Pp +The +.Nm +data structure is an extensible, dynamic hashing scheme. +.Pp +The access method specific data structure provided to +.Fn dbopen +is defined in the +.In db.h +include file as follows: +.Bd -literal +typedef struct { + u_int bsize; + u_int ffactor; + u_int nelem; + u_int cachesize; + uint32_t (*hash)(const void *, size_t); + int lorder; +} HASHINFO; +.Ed +.Pp +The elements of this structure are as follows: +.Bl -tag -width indent +.It Va bsize +The +.Va bsize +element +defines the +.Nm +table bucket size, and is, by default, 4096 bytes. +It may be preferable to increase the page size for disk-resident tables +and tables with large data items. +.It Va ffactor +The +.Va ffactor +element +indicates a desired density within the +.Nm +table. +It is an approximation of the number of keys allowed to accumulate in any +one bucket, determining when the +.Nm +table grows or shrinks. +The default value is 8. +.It Va nelem +The +.Va nelem +element +is an estimate of the final size of the +.Nm +table. +If not set or set too low, +.Nm +tables will expand gracefully as keys +are entered, although a slight performance degradation may be noticed. +The default value is 1. +.It Va cachesize +A suggested maximum size, in bytes, of the memory cache. +This value is +.Em only +advisory, and the access method will allocate more memory rather +than fail. +.It Va hash +The +.Va hash +element +is a user defined +.Nm +function. +Since no +.Nm +function performs equally well on all possible data, the +user may find that the built-in +.Nm +function does poorly on a particular +data set. +User specified +.Nm +functions must take two arguments (a pointer to a byte +string and a length) and return a 32-bit quantity to be used as the +.Nm +value. +.It Va lorder +The byte order for integers in the stored database metadata. +The number should represent the order as an integer; for example, +big endian order would be the number 4,321. +If +.Va lorder +is 0 (no order is specified) the current host order is used. +If the file already exists, the specified value is ignored and the +value specified when the tree was created is used. +.El +.Pp +If the file already exists (and the +.Dv O_TRUNC +flag is not specified), the +values specified for the +.Va bsize , ffactor , lorder +and +.Va nelem +arguments +are +ignored and the values specified when the tree was created are used. +.Pp +If a +.Nm +function is specified, +.Fn hash_open +will attempt to determine if the +.Nm +function specified is the same as +the one with which the database was created, and will fail if it is not. +.Pp +Backward compatible interfaces to the older +.Em dbm +and +.Em ndbm +routines are provided, however these interfaces are not compatible with +previous file formats. +.Sh ERRORS +The +.Nm +access method routines may fail and set +.Va errno +for any of the errors specified for the library routine +.Xr dbopen 3 . +.Sh SEE ALSO +.Xr btree 3 , +.Xr dbopen 3 , +.Xr mpool 3 , +.Xr recno 3 +.Rs +.%T "Dynamic Hash Tables" +.%A Per-Ake Larson +.%R "Communications of the ACM" +.%D April 1988 +.Re +.Rs +.%T "A New Hash Package for UNIX" +.%A Margo Seltzer +.%R "USENIX Proceedings" +.%D Winter 1991 +.Re +.Sh BUGS +Only big and little endian byte order is supported. diff --git a/lib/libc/db/man/mpool.3 b/lib/libc/db/man/mpool.3 new file mode 100644 index 0000000..fe04ed3 --- /dev/null +++ b/lib/libc/db/man/mpool.3 @@ -0,0 +1,254 @@ +.\" Copyright (c) 1990, 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. +.\" 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. +.\" +.\" @(#)mpool.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/db/man/mpool.3 223214 2011-06-18 00:10:21Z delphij $ +.\" +.Dd June 17, 2011 +.Dt MPOOL 3 +.Os +.Sh NAME +.Nm mpool +.Nd "shared memory buffer pool" +.Sh SYNOPSIS +.In db.h +.In mpool.h +.Ft MPOOL * +.Fn mpool_open "void *key" "int fd" "pgno_t pagesize" "pgno_t maxcache" +.Ft void +.Fo mpool_filter +.Fa "MPOOL *mp" +.Fa "void (*pgin)(void *, pgno_t, void *)" +.Fa "void (*pgout)(void *, pgno_t, void *)" +.Fa "void *pgcookie" +.Fc +.Ft void * +.Fn mpool_new "MPOOL *mp" "pgno_t *pgnoaddr" "u_int flags" +.Ft int +.Fn mpool_delete "MPOOL *mp" "void *page" +.Ft void * +.Fn mpool_get "MPOOL *mp" "pgno_t pgno" "u_int flags" +.Ft int +.Fn mpool_put "MPOOL *mp" "void *pgaddr" "u_int flags" +.Ft int +.Fn mpool_sync "MPOOL *mp" +.Ft int +.Fn mpool_close "MPOOL *mp" +.Sh DESCRIPTION +The +.Nm mpool +library interface is intended to provide page oriented buffer management +of files. +.Pp +The +.Fn mpool_open +function initializes a memory pool. +The +.Fa key +argument is currently ignored. +The +.Fa fd +argument is a file descriptor for the underlying file, which must be seekable. +.Pp +The +.Fa pagesize +argument is the size, in bytes, of the pages into which the file is broken up. +The +.Fa maxcache +argument is the maximum number of pages from the underlying file to cache +at any one time. +This value is not relative to the number of processes which share a file's +buffers, but will be the largest value specified by any of the processes +sharing the file. +.Pp +The +.Fn mpool_filter +function is intended to make transparent input and output processing of the +pages possible. +If the +.Fa pgin +function is specified, it is called each time a buffer is read into the memory +pool from the backing file. +If the +.Fa pgout +function is specified, it is called each time a buffer is written into the +backing file. +Both functions are called with the +.Fa pgcookie +pointer, the page number and a pointer to the page to being read or written. +.Pp +The function +.Fn mpool_new +takes an +.Dv MPOOL +pointer, an address, and a set of flags as arguments. +If a new page can be allocated, a pointer to the page is returned and +the page number is stored into the +.Fa pgnoaddr +address. +Otherwise, +.Dv NULL +is returned and +.Va errno +is set. +The flags value is formed by +.Tn OR Ns 'ing +the following values: +.Bl -tag -width Ds +.It Dv MPOOL_PAGE_REQUEST +Allocate a new page with a specific page number. +.It Dv MPOOL_PAGE_NEXT +Allocate a new page with the next page number. +.El +.Pp +The function +.Fn mpool_delete +deletes the specified page from a pool and frees the page. +It takes an +.Dv MPOOL +pointer and a page as arguments. +The page must have been generated by +.Fn mpool_new . +.Pp +The +.Fn mpool_get +function takes a +.Ft MPOOL +pointer and a page number as arguments. +If the page exists, a pointer to the page is returned. +Otherwise, +.Dv NULL +is returned and +.Va errno +is set. +The +.Fa flags +argument is specified by +.Em or Ns 'ing +any of the following values: +.Bl -tag -width indent +.It Dv MPOOL_IGNOREPIN +The page returned is not pinned; +page will otherwise be pinned on return. +.El +.Pp +The +.Fn mpool_put +function unpins the page referenced by +.Fa pgaddr . +The +.Fa pgaddr +argument +must be an address previously returned by +.Fn mpool_get +or +.Fn mpool_new . +The +.Fa flags +argument is specified by +.Em or Ns 'ing +any of the following values: +.Bl -tag -width indent +.It Dv MPOOL_DIRTY +The page has been modified and needs to be written to the backing file. +.El +.Pp +The +.Fn mpool_put +function +returns 0 on success and -1 if an error occurs. +.Pp +The +.Fn mpool_sync +function writes all modified pages associated with the +.Ft MPOOL +pointer to the +backing file. +The +.Fn mpool_sync +function +returns 0 on success and -1 if an error occurs. +.Pp +The +.Fn mpool_close +function free's up any allocated memory associated with the memory pool +cookie. +Modified pages are +.Em not +written to the backing file. +The +.Fn mpool_close +function +returns 0 on success and -1 if an error occurs. +.Sh ERRORS +The +.Fn mpool_open +function may fail and set +.Va errno +for any of the errors specified for the library routine +.Xr malloc 3 . +.Pp +The +.Fn mpool_get +function may fail and set +.Va errno +for the following: +.Bl -tag -width Er +.It Bq Er EINVAL +The requested record does not exist. +.El +.Pp +The +.Fn mpool_new +and +.Fn mpool_get +functions may fail and set +.Va errno +for any of the errors specified for the library routines +.Xr read 2 , +.Xr write 2 , +and +.Xr malloc 3 . +.Pp +The +.Fn mpool_sync +function may fail and set +.Va errno +for any of the errors specified for the library routine +.Xr write 2 . +.Pp +The +.Fn mpool_close +function may fail and set +.Va errno +for any of the errors specified for the library routine +.Xr free 3 . +.Sh SEE ALSO +.Xr btree 3 , +.Xr dbopen 3 , +.Xr hash 3 , +.Xr recno 3 diff --git a/lib/libc/db/man/recno.3 b/lib/libc/db/man/recno.3 new file mode 100644 index 0000000..92ef449 --- /dev/null +++ b/lib/libc/db/man/recno.3 @@ -0,0 +1,228 @@ +.\" Copyright (c) 1990, 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. +.\" 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. +.\" +.\" @(#)recno.3 8.5 (Berkeley) 8/18/94 +.\" $FreeBSD: releng/11.1/lib/libc/db/man/recno.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd August 18, 1994 +.Dt RECNO 3 +.Os +.Sh NAME +.Nm recno +.Nd "record number database access method" +.Sh SYNOPSIS +.In sys/types.h +.In db.h +.Sh DESCRIPTION +The routine +.Fn dbopen +is the library interface to database files. +One of the supported file formats is record number files. +The general description of the database access methods is in +.Xr dbopen 3 , +this manual page describes only the +.Nm +specific information. +.Pp +The record number data structure is either variable or fixed-length +records stored in a flat-file format, accessed by the logical record +number. +The existence of record number five implies the existence of records +one through four, and the deletion of record number one causes +record number five to be renumbered to record number four, as well +as the cursor, if positioned after record number one, to shift down +one record. +.Pp +The +.Nm +access method specific data structure provided to +.Fn dbopen +is defined in the +.In db.h +include file as follows: +.Bd -literal +typedef struct { + u_long flags; + u_int cachesize; + u_int psize; + int lorder; + size_t reclen; + u_char bval; + char *bfname; +} RECNOINFO; +.Ed +.Pp +The elements of this structure are defined as follows: +.Bl -tag -width indent +.It Va flags +The flag value is specified by +.Em or Ns 'ing +any of the following values: +.Bl -tag -width indent +.It Dv R_FIXEDLEN +The records are fixed-length, not byte delimited. +The structure element +.Va reclen +specifies the length of the record, and the structure element +.Va bval +is used as the pad character. +Any records, inserted into the database, that are less than +.Va reclen +bytes long are automatically padded. +.It Dv R_NOKEY +In the interface specified by +.Fn dbopen , +the sequential record retrieval fills in both the caller's key and +data structures. +If the +.Dv R_NOKEY +flag is specified, the +.Em cursor +routines are not required to fill in the key structure. +This permits applications to retrieve records at the end of files without +reading all of the intervening records. +.It Dv R_SNAPSHOT +This flag requires that a snapshot of the file be taken when +.Fn dbopen +is called, instead of permitting any unmodified records to be read from +the original file. +.El +.It Va cachesize +A suggested maximum size, in bytes, of the memory cache. +This value is +.Em only +advisory, and the access method will allocate more memory rather than fail. +If +.Va cachesize +is 0 (no size is specified) a default cache is used. +.It Va psize +The +.Nm +access method stores the in-memory copies of its records +in a btree. +This value is the size (in bytes) of the pages used for nodes in that tree. +If +.Va psize +is 0 (no page size is specified) a page size is chosen based on the +underlying file system I/O block size. +See +.Xr btree 3 +for more information. +.It Va lorder +The byte order for integers in the stored database metadata. +The number should represent the order as an integer; for example, +big endian order would be the number 4,321. +If +.Va lorder +is 0 (no order is specified) the current host order is used. +.It Va reclen +The length of a fixed-length record. +.It Va bval +The delimiting byte to be used to mark the end of a record for +variable-length records, and the pad character for fixed-length +records. +If no value is specified, newlines +.Pq Dq \en +are used to mark the end +of variable-length records and fixed-length records are padded with +spaces. +.It Va bfname +The +.Nm +access method stores the in-memory copies of its records +in a btree. +If +.Va bfname +is +.No non\- Ns Dv NULL , +it specifies the name of the btree file, +as if specified as the file name for a +.Fn dbopen +of a btree file. +.El +.Pp +The data part of the key/data pair used by the +.Nm +access method +is the same as other access methods. +The key is different. +The +.Va data +field of the key should be a pointer to a memory location of type +.Ft recno_t , +as defined in the +.In db.h +include file. +This type is normally the largest unsigned integral type available to +the implementation. +The +.Va size +field of the key should be the size of that type. +.Pp +Because there can be no meta-data associated with the underlying +.Nm +access method files, any changes made to the default values +(e.g.\& fixed record length or byte separator value) must be explicitly +specified each time the file is opened. +.Pp +In the interface specified by +.Fn dbopen , +using the +.Va put +interface to create a new record will cause the creation of multiple, +empty records if the record number is more than one greater than the +largest record currently in the database. +.Sh ERRORS +The +.Nm +access method routines may fail and set +.Va errno +for any of the errors specified for the library routine +.Xr dbopen 3 +or the following: +.Bl -tag -width Er +.It Bq Er EINVAL +An attempt was made to add a record to a fixed-length database that +was too large to fit. +.El +.Sh SEE ALSO +.Xr btree 3 , +.Xr dbopen 3 , +.Xr hash 3 , +.Xr mpool 3 +.Rs +.%T "Document Processing in a Relational Database System" +.%A Michael Stonebraker +.%A Heidi Stettner +.%A Joseph Kalash +.%A Antonin Guttman +.%A Nadene Lynn +.%R "Memorandum No. UCB/ERL M82/32" +.%D May 1982 +.Re +.Sh BUGS +Only big and little endian byte order is supported. diff --git a/lib/libc/db/mpool/Makefile.inc b/lib/libc/db/mpool/Makefile.inc new file mode 100644 index 0000000..b84099d --- /dev/null +++ b/lib/libc/db/mpool/Makefile.inc @@ -0,0 +1,9 @@ +# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/db/mpool/Makefile.inc 296915 2016-03-15 19:26:32Z emaste $ + +.PATH: ${LIBC_SRCTOP}/db/mpool + +SRCS+= mpool.c +.if ${MK_SYMVER} == yes +SRCS+= mpool-compat.c +.endif diff --git a/lib/libc/db/mpool/mpool-compat.c b/lib/libc/db/mpool/mpool-compat.c new file mode 100644 index 0000000..7888f7c --- /dev/null +++ b/lib/libc/db/mpool/mpool-compat.c @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2009 Xin LI + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/db/mpool/mpool-compat.c 190498 2009-03-28 07:31:02Z delphij $"); + +#include +#include + +void *__mpool_new__44bsd(MPOOL *, pgno_t *); + +void * +__mpool_new__44bsd(MPOOL *mp, pgno_t *pgnoaddr) +{ + + return (mpool_new(mp, pgnoaddr, MPOOL_PAGE_NEXT)); +} + +__sym_compat(mpool_new, __mpool_new_44bsd, FBSD_1.0); diff --git a/lib/libc/db/recno/Makefile.inc b/lib/libc/db/recno/Makefile.inc new file mode 100644 index 0000000..f30892f --- /dev/null +++ b/lib/libc/db/recno/Makefile.inc @@ -0,0 +1,7 @@ +# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/db/recno/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +.PATH: ${LIBC_SRCTOP}/db/recno + +SRCS+= rec_close.c rec_delete.c rec_get.c rec_open.c rec_put.c rec_search.c \ + rec_seq.c rec_utils.c diff --git a/lib/libc/db/test/Makefile b/lib/libc/db/test/Makefile new file mode 100644 index 0000000..e2460e3 --- /dev/null +++ b/lib/libc/db/test/Makefile @@ -0,0 +1,24 @@ +# @(#)Makefile 8.15 (Berkeley) 7/28/94 +# $FreeBSD: releng/11.1/lib/libc/db/test/Makefile 81118 2001-08-03 21:45:54Z bde $ + +PROG= dbtest +OBJS= dbtest.o strerror.o + +# Uncomment the STAT line get hash and btree statistical use info. This +# also forces ld to load the btree debug functions for use by gdb, which +# is useful. The db library has to be compiled with -DSTATISTICS as well. +INC= -I${PORTDIR}/include -I${PORTDIR} +OORG= -g +#STAT= -DSTATISTICS +CFLAGS+=-D__DBINTERFACE_PRIVATE -DDEBUG ${STAT} ${OORG} ${INC} + +dbtest: ${OBJS} ${PORTDIR}/libdb.a + ${CC} -o ${.TARGET} ${OBJS} ${PORTDIR}/libdb.a + +strerror.o: ${PORTDIR}/clib/strerror.c + ${CC} -c ${PORTDIR}/clib/strerror.c + +clean: + rm -f dbtest.core gmon.out ${OBJS} ${PROG} t1 t2 t3 + +${OBJS}: Makefile diff --git a/lib/libc/db/test/README b/lib/libc/db/test/README new file mode 100644 index 0000000..0c0cd13 --- /dev/null +++ b/lib/libc/db/test/README @@ -0,0 +1,74 @@ +# @(#)README 8.8 (Berkeley) 7/31/94 + +To build this portably, try something like: + + make PORTDIR="../PORT/MACH" + +where MACH is the machine, i.e. "sunos.4.1.1". + +To run the tests, enter "sh run.test". If your system dictionary isn't +in /usr/share/dict/words, edit run.test to reflect the correct place. + +Fairly large files (the command files) are built in this directory during +the test runs, and even larger files (the database files) are created in +"/var/tmp". If the latter directory doesn't exist, set the environmental +variable TMPDIR to a directory where the files can be built. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +The script file consists of lines with an initial character which is +the command for that line, or an initial character indicating a key +or data entry for a previous command. + +Legal command characters are as follows: + +c: compare a record + + must be followed by [kK][dD]; the data value in the database + associated with the specified key is compared to the specified + data value. +e: echo a string + + writes out the rest of the line into the output file; if the + last character is not a carriage-return, a newline is appended. +f: set the flags for the next command + + no value zero's the flags +g: do a get command + + must be followed by [kK] + + writes out the retrieved data DBT. +o [r]: dump [reverse] + + dump the database out, if 'r' is set, in reverse order. +p: do a put command + + must be followed by [kK][dD] +r: do a del command + + must be followed by [kK] unless R_CURSOR flag set. +S: sync the database +s: do a seq command + + must be followed by [kK] if R_CURSOR flag set. + + writes out the retrieved data DBT. + +Legal key/data characters are as follows: + +D [file]: data file + + set the current data value to the contents of the file +d [data]: + + set the current key value to the contents of the line. +K [file]: key file + + set the current key value to the contents of the file +k [data]: + + set the current key value to the contents of the line. + +Blank lines, lines with leading white space, and lines with leading +hash marks (#) are ignored. + +Options to dbtest are as follows: + + -d: Set the DB_LOCK flag. + -f: Use the file argument as the database file. + -i: Use the rest of the argument to set elements in the info + structure. If the type is btree, then "-i cachesize=10240" + will set BTREEINFO.cachesize to 10240. + -o: The rest of the argument is the output file instead of + using stdout. + -s: Don't delete the database file before opening it, i.e. + use the database file from a previous run. + +Dbtest requires two arguments, the type of access "hash", "recno" +or "btree", and the script name or "-" to indicate stdin. diff --git a/lib/libc/db/test/btree.tests/main.c b/lib/libc/db/test/btree.tests/main.c new file mode 100644 index 0000000..a621d51 --- /dev/null +++ b/lib/libc/db/test/btree.tests/main.c @@ -0,0 +1,763 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Olson. + * + * 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. + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/db/test/btree.tests/main.c 176380 2008-02-18 03:19:25Z kevlo $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include "btree.h" + +typedef struct cmd_table { + char *cmd; + int nargs; + int rconv; + void (*func)(DB *, char **); + char *usage, *descrip; +} cmd_table; + +int stopstop; +DB *globaldb; + +void append(DB *, char **); +void bstat(DB *, char **); +void cursor(DB *, char **); +void delcur(DB *, char **); +void delete(DB *, char **); +void dump(DB *, char **); +void first(DB *, char **); +void get(DB *, char **); +void help(DB *, char **); +void iafter(DB *, char **); +void ibefore(DB *, char **); +void icursor(DB *, char **); +void insert(DB *, char **); +void keydata(DBT *, DBT *); +void last(DB *, char **); +void list(DB *, char **); +void load(DB *, char **); +void mstat(DB *, char **); +void next(DB *, char **); +int parse(char *, char **, int); +void previous(DB *, char **); +void show(DB *, char **); +void usage(void); +void user(DB *); + +cmd_table commands[] = { + "?", 0, 0, help, "help", NULL, + "a", 2, 1, append, "append key def", "append key with data def", + "b", 0, 0, bstat, "bstat", "stat btree", + "c", 1, 1, cursor, "cursor word", "move cursor to word", + "delc", 0, 0, delcur, "delcur", "delete key the cursor references", + "dele", 1, 1, delete, "delete word", "delete word", + "d", 0, 0, dump, "dump", "dump database", + "f", 0, 0, first, "first", "move cursor to first record", + "g", 1, 1, get, "get key", "locate key", + "h", 0, 0, help, "help", "print command summary", + "ia", 2, 1, iafter, "iafter key data", "insert data after key", + "ib", 2, 1, ibefore, "ibefore key data", "insert data before key", + "ic", 2, 1, icursor, "icursor key data", "replace cursor", + "in", 2, 1, insert, "insert key def", "insert key with data def", + "la", 0, 0, last, "last", "move cursor to last record", + "li", 1, 1, list, "list file", "list to a file", + "loa", 1, 0, load, "load file", NULL, + "loc", 1, 1, get, "get key", NULL, + "m", 0, 0, mstat, "mstat", "stat memory pool", + "n", 0, 0, next, "next", "move cursor forward one record", + "p", 0, 0, previous, "previous", "move cursor back one record", + "q", 0, 0, NULL, "quit", "quit", + "sh", 1, 0, show, "show page", "dump a page", + { NULL }, +}; + +int recno; /* use record numbers */ +char *dict = "words"; /* default dictionary */ +char *progname; + +int +main(argc, argv) + int argc; + char **argv; +{ + int c; + DB *db; + BTREEINFO b; + + progname = *argv; + + b.flags = 0; + b.cachesize = 0; + b.maxkeypage = 0; + b.minkeypage = 0; + b.psize = 0; + b.compare = NULL; + b.prefix = NULL; + b.lorder = 0; + + while ((c = getopt(argc, argv, "bc:di:lp:ru")) != -1) { + switch (c) { + case 'b': + b.lorder = BIG_ENDIAN; + break; + case 'c': + b.cachesize = atoi(optarg); + break; + case 'd': + b.flags |= R_DUP; + break; + case 'i': + dict = optarg; + break; + case 'l': + b.lorder = LITTLE_ENDIAN; + break; + case 'p': + b.psize = atoi(optarg); + break; + case 'r': + recno = 1; + break; + case 'u': + b.flags = 0; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (recno) + db = dbopen(*argv == NULL ? NULL : *argv, O_RDWR, + 0, DB_RECNO, NULL); + else + db = dbopen(*argv == NULL ? NULL : *argv, O_CREAT|O_RDWR, + 0600, DB_BTREE, &b); + + if (db == NULL) { + (void)fprintf(stderr, "dbopen: %s\n", strerror(errno)); + exit(1); + } + globaldb = db; + user(db); + exit(0); + /* NOTREACHED */ +} + +void +user(db) + DB *db; +{ + FILE *ifp; + int argc, i, last; + char *lbuf, *argv[4], buf[512]; + + if ((ifp = fopen("/dev/tty", "r")) == NULL) { + (void)fprintf(stderr, + "/dev/tty: %s\n", strerror(errno)); + exit(1); + } + for (last = 0;;) { + (void)printf("> "); + (void)fflush(stdout); + if ((lbuf = fgets(&buf[0], 512, ifp)) == NULL) + break; + if (lbuf[0] == '\n') { + i = last; + goto uselast; + } + lbuf[strlen(lbuf) - 1] = '\0'; + + if (lbuf[0] == 'q') + break; + + argc = parse(lbuf, &argv[0], 3); + if (argc == 0) + continue; + + for (i = 0; commands[i].cmd != NULL; i++) + if (strncmp(commands[i].cmd, argv[0], + strlen(commands[i].cmd)) == 0) + break; + + if (commands[i].cmd == NULL) { + (void)fprintf(stderr, + "%s: command unknown ('help' for help)\n", lbuf); + continue; + } + + if (commands[i].nargs != argc - 1) { + (void)fprintf(stderr, "usage: %s\n", commands[i].usage); + continue; + } + + if (recno && commands[i].rconv) { + static recno_t nlong; + nlong = atoi(argv[1]); + argv[1] = (char *)&nlong; + } +uselast: last = i; + (*commands[i].func)(db, argv); + } + if ((db->sync)(db) == RET_ERROR) + perror("dbsync"); + else if ((db->close)(db) == RET_ERROR) + perror("dbclose"); +} + +int +parse(lbuf, argv, maxargc) + char *lbuf, **argv; + int maxargc; +{ + int argc = 0; + char *c; + + c = lbuf; + while (isspace(*c)) + c++; + while (*c != '\0' && argc < maxargc) { + *argv++ = c; + argc++; + while (!isspace(*c) && *c != '\0') { + c++; + } + while (isspace(*c)) + *c++ = '\0'; + } + return (argc); +} + +void +append(db, argv) + DB *db; + char **argv; +{ + DBT key, data; + int status; + + if (!recno) { + (void)fprintf(stderr, + "append only available for recno db's.\n"); + return; + } + key.data = argv[1]; + key.size = sizeof(recno_t); + data.data = argv[2]; + data.size = strlen(data.data); + status = (db->put)(db, &key, &data, R_APPEND); + switch (status) { + case RET_ERROR: + perror("append/put"); + break; + case RET_SPECIAL: + (void)printf("%s (duplicate key)\n", argv[1]); + break; + case RET_SUCCESS: + break; + } +} + +void +cursor(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + int status; + + key.data = argv[1]; + if (recno) + key.size = sizeof(recno_t); + else + key.size = strlen(argv[1]) + 1; + status = (*db->seq)(db, &key, &data, R_CURSOR); + switch (status) { + case RET_ERROR: + perror("cursor/seq"); + break; + case RET_SPECIAL: + (void)printf("key not found\n"); + break; + case RET_SUCCESS: + keydata(&key, &data); + break; + } +} + +void +delcur(db, argv) + DB *db; + char **argv; +{ + int status; + + status = (*db->del)(db, NULL, R_CURSOR); + + if (status == RET_ERROR) + perror("delcur/del"); +} + +void +delete(db, argv) + DB *db; + char **argv; +{ + DBT key; + int status; + + key.data = argv[1]; + if (recno) + key.size = sizeof(recno_t); + else + key.size = strlen(argv[1]) + 1; + + status = (*db->del)(db, &key, 0); + switch (status) { + case RET_ERROR: + perror("delete/del"); + break; + case RET_SPECIAL: + (void)printf("key not found\n"); + break; + case RET_SUCCESS: + break; + } +} + +void +dump(db, argv) + DB *db; + char **argv; +{ + __bt_dump(db); +} + +void +first(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + int status; + + status = (*db->seq)(db, &key, &data, R_FIRST); + + switch (status) { + case RET_ERROR: + perror("first/seq"); + break; + case RET_SPECIAL: + (void)printf("no more keys\n"); + break; + case RET_SUCCESS: + keydata(&key, &data); + break; + } +} + +void +get(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + int status; + + key.data = argv[1]; + if (recno) + key.size = sizeof(recno_t); + else + key.size = strlen(argv[1]) + 1; + + status = (*db->get)(db, &key, &data, 0); + + switch (status) { + case RET_ERROR: + perror("get/get"); + break; + case RET_SPECIAL: + (void)printf("key not found\n"); + break; + case RET_SUCCESS: + keydata(&key, &data); + break; + } +} + +void +help(db, argv) + DB *db; + char **argv; +{ + int i; + + for (i = 0; commands[i].cmd; i++) + if (commands[i].descrip) + (void)printf("%s: %s\n", + commands[i].usage, commands[i].descrip); +} + +void +iafter(db, argv) + DB *db; + char **argv; +{ + DBT key, data; + int status; + + if (!recno) { + (void)fprintf(stderr, + "iafter only available for recno db's.\n"); + return; + } + key.data = argv[1]; + key.size = sizeof(recno_t); + data.data = argv[2]; + data.size = strlen(data.data); + status = (db->put)(db, &key, &data, R_IAFTER); + switch (status) { + case RET_ERROR: + perror("iafter/put"); + break; + case RET_SPECIAL: + (void)printf("%s (duplicate key)\n", argv[1]); + break; + case RET_SUCCESS: + break; + } +} + +void +ibefore(db, argv) + DB *db; + char **argv; +{ + DBT key, data; + int status; + + if (!recno) { + (void)fprintf(stderr, + "ibefore only available for recno db's.\n"); + return; + } + key.data = argv[1]; + key.size = sizeof(recno_t); + data.data = argv[2]; + data.size = strlen(data.data); + status = (db->put)(db, &key, &data, R_IBEFORE); + switch (status) { + case RET_ERROR: + perror("ibefore/put"); + break; + case RET_SPECIAL: + (void)printf("%s (duplicate key)\n", argv[1]); + break; + case RET_SUCCESS: + break; + } +} + +void +icursor(db, argv) + DB *db; + char **argv; +{ + int status; + DBT data, key; + + key.data = argv[1]; + if (recno) + key.size = sizeof(recno_t); + else + key.size = strlen(argv[1]) + 1; + data.data = argv[2]; + data.size = strlen(argv[2]) + 1; + + status = (*db->put)(db, &key, &data, R_CURSOR); + switch (status) { + case RET_ERROR: + perror("icursor/put"); + break; + case RET_SPECIAL: + (void)printf("%s (duplicate key)\n", argv[1]); + break; + case RET_SUCCESS: + break; + } +} + +void +insert(db, argv) + DB *db; + char **argv; +{ + int status; + DBT data, key; + + key.data = argv[1]; + if (recno) + key.size = sizeof(recno_t); + else + key.size = strlen(argv[1]) + 1; + data.data = argv[2]; + data.size = strlen(argv[2]) + 1; + + status = (*db->put)(db, &key, &data, R_NOOVERWRITE); + switch (status) { + case RET_ERROR: + perror("insert/put"); + break; + case RET_SPECIAL: + (void)printf("%s (duplicate key)\n", argv[1]); + break; + case RET_SUCCESS: + break; + } +} + +void +last(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + int status; + + status = (*db->seq)(db, &key, &data, R_LAST); + + switch (status) { + case RET_ERROR: + perror("last/seq"); + break; + case RET_SPECIAL: + (void)printf("no more keys\n"); + break; + case RET_SUCCESS: + keydata(&key, &data); + break; + } +} + +void +list(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + FILE *fp; + int status; + + if ((fp = fopen(argv[1], "w")) == NULL) { + (void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno)); + return; + } + status = (*db->seq)(db, &key, &data, R_FIRST); + while (status == RET_SUCCESS) { + (void)fprintf(fp, "%s\n", key.data); + status = (*db->seq)(db, &key, &data, R_NEXT); + } + if (status == RET_ERROR) + perror("list/seq"); +} + +DB *BUGdb; +void +load(db, argv) + DB *db; + char **argv; +{ + char *p, *t; + FILE *fp; + DBT data, key; + recno_t cnt; + size_t len; + int status; + char *lp, buf[16 * 1024]; + + BUGdb = db; + if ((fp = fopen(argv[1], "r")) == NULL) { + (void)fprintf(stderr, "%s: %s\n", argv[1], strerror(errno)); + return; + } + (void)printf("loading %s...\n", argv[1]); + + for (cnt = 1; (lp = fgetline(fp, &len)) != NULL; ++cnt) { + if (recno) { + key.data = &cnt; + key.size = sizeof(recno_t); + data.data = lp; + data.size = len + 1; + } else { + key.data = lp; + key.size = len + 1; + for (p = lp + len - 1, t = buf; p >= lp; *t++ = *p--); + *t = '\0'; + data.data = buf; + data.size = len + 1; + } + + status = (*db->put)(db, &key, &data, R_NOOVERWRITE); + switch (status) { + case RET_ERROR: + perror("load/put"); + exit(1); + case RET_SPECIAL: + if (recno) + (void)fprintf(stderr, + "duplicate: %ld {%s}\n", cnt, data.data); + else + (void)fprintf(stderr, + "duplicate: %ld {%s}\n", cnt, key.data); + exit(1); + case RET_SUCCESS: + break; + } + } + (void)fclose(fp); +} + +void +next(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + int status; + + status = (*db->seq)(db, &key, &data, R_NEXT); + + switch (status) { + case RET_ERROR: + perror("next/seq"); + break; + case RET_SPECIAL: + (void)printf("no more keys\n"); + break; + case RET_SUCCESS: + keydata(&key, &data); + break; + } +} + +void +previous(db, argv) + DB *db; + char **argv; +{ + DBT data, key; + int status; + + status = (*db->seq)(db, &key, &data, R_PREV); + + switch (status) { + case RET_ERROR: + perror("previous/seq"); + break; + case RET_SPECIAL: + (void)printf("no more keys\n"); + break; + case RET_SUCCESS: + keydata(&key, &data); + break; + } +} + +void +show(db, argv) + DB *db; + char **argv; +{ + BTREE *t; + PAGE *h; + pgno_t pg; + + pg = atoi(argv[1]); + t = db->internal; + if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL) { + (void)printf("getpage of %ld failed\n", pg); + return; + } + if (pg == 0) + __bt_dmpage(h); + else + __bt_dpage(h); + mpool_put(t->bt_mp, h, 0); +} + +void +bstat(db, argv) + DB *db; + char **argv; +{ + (void)printf("BTREE\n"); + __bt_stat(db); +} + +void +mstat(db, argv) + DB *db; + char **argv; +{ + (void)printf("MPOOL\n"); + mpool_stat(((BTREE *)db->internal)->bt_mp); +} + +void +keydata(key, data) + DBT *key, *data; +{ + if (!recno && key->size > 0) + (void)printf("%s/", key->data); + if (data->size > 0) + (void)printf("%s", data->data); + (void)printf("\n"); +} + +void +usage() +{ + (void)fprintf(stderr, + "usage: %s [-bdlu] [-c cache] [-i file] [-p page] [file]\n", + progname); + exit (1); +} diff --git a/lib/libc/db/test/dbtest.c b/lib/libc/db/test/dbtest.c new file mode 100644 index 0000000..674d631 --- /dev/null +++ b/lib/libc/db/test/dbtest.c @@ -0,0 +1,738 @@ +/*- + * Copyright (c) 1992, 1993, 1994 + * 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. + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1992, 1993, 1994\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/db/test/dbtest.c 176380 2008-02-18 03:19:25Z kevlo $"); + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA }; + +void compare(DBT *, DBT *); +DBTYPE dbtype(char *); +void dump(DB *, int); +void err(const char *, ...) __printflike(1, 2); +void get(DB *, DBT *); +void getdata(DB *, DBT *, DBT *); +void put(DB *, DBT *, DBT *); +void rem(DB *, DBT *); +char *sflags(int); +void synk(DB *); +void *rfile(char *, size_t *); +void seq(DB *, DBT *); +u_int setflags(char *); +void *setinfo(DBTYPE, char *); +void usage(void); +void *xmalloc(char *, size_t); + +DBTYPE type; /* Database type. */ +void *infop; /* Iflags. */ +u_long lineno; /* Current line in test script. */ +u_int flags; /* Current DB flags. */ +int ofd = STDOUT_FILENO; /* Standard output fd. */ + +DB *XXdbp; /* Global for gdb. */ +int XXlineno; /* Fast breakpoint for gdb. */ + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern int optind; + extern char *optarg; + enum S command, state; + DB *dbp; + DBT data, key, keydata; + size_t len; + int ch, oflags, sflag; + char *fname, *infoarg, *p, *t, buf[8 * 1024]; + + infoarg = NULL; + fname = NULL; + oflags = O_CREAT | O_RDWR; + sflag = 0; + while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1) + switch (ch) { + case 'f': + fname = optarg; + break; + case 'i': + infoarg = optarg; + break; + case 'l': + oflags |= DB_LOCK; + break; + case 'o': + if ((ofd = open(optarg, + O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) + err("%s: %s", optarg, strerror(errno)); + break; + case 's': + sflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc != 2) + usage(); + + /* Set the type. */ + type = dbtype(*argv++); + + /* Open the descriptor file. */ + if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL) + err("%s: %s", *argv, strerror(errno)); + + /* Set up the db structure as necessary. */ + if (infoarg == NULL) + infop = NULL; + else + for (p = strtok(infoarg, ",\t "); p != NULL; + p = strtok(0, ",\t ")) + if (*p != '\0') + infop = setinfo(type, p); + + /* + * Open the DB. Delete any preexisting copy, you almost never + * want it around, and it often screws up tests. + */ + if (fname == NULL) { + p = getenv("TMPDIR"); + if (p == NULL) + p = "/var/tmp"; + (void)snprintf(buf, sizeof(buf), "%s/__dbtest", p); + fname = buf; + (void)unlink(buf); + } else if (!sflag) + (void)unlink(fname); + + if ((dbp = dbopen(fname, + oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL) + err("dbopen: %s", strerror(errno)); + XXdbp = dbp; + + state = COMMAND; + for (lineno = 1; + (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) { + /* Delete the newline, displaying the key/data is easier. */ + if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL) + *t = '\0'; + if ((len = strlen(buf)) == 0 || isspace(*p) || *p == '#') + continue; + + /* Convenient gdb break point. */ + if (XXlineno == lineno) + XXlineno = 1; + switch (*p) { + case 'c': /* compare */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + state = KEY; + command = COMPARE; + break; + case 'e': /* echo */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + /* Don't display the newline, if CR at EOL. */ + if (p[len - 2] == '\r') + --len; + if (write(ofd, p + 1, len - 1) != len - 1 || + write(ofd, "\n", 1) != 1) + err("write: %s", strerror(errno)); + break; + case 'g': /* get */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + state = KEY; + command = GET; + break; + case 'p': /* put */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + state = KEY; + command = PUT; + break; + case 'r': /* remove */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + if (flags == R_CURSOR) { + rem(dbp, &key); + state = COMMAND; + } else { + state = KEY; + command = REMOVE; + } + break; + case 'S': /* sync */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + synk(dbp); + state = COMMAND; + break; + case 's': /* seq */ + if (state != COMMAND) + err("line %lu: not expecting command", lineno); + if (flags == R_CURSOR) { + state = KEY; + command = SEQ; + } else + seq(dbp, &key); + break; + case 'f': + flags = setflags(p + 1); + break; + case 'D': /* data file */ + if (state != DATA) + err("line %lu: not expecting data", lineno); + data.data = rfile(p + 1, &data.size); + goto ldata; + case 'd': /* data */ + if (state != DATA) + err("line %lu: not expecting data", lineno); + data.data = xmalloc(p + 1, len - 1); + data.size = len - 1; +ldata: switch (command) { + case COMPARE: + compare(&keydata, &data); + break; + case PUT: + put(dbp, &key, &data); + break; + default: + err("line %lu: command doesn't take data", + lineno); + } + if (type != DB_RECNO) + free(key.data); + free(data.data); + state = COMMAND; + break; + case 'K': /* key file */ + if (state != KEY) + err("line %lu: not expecting a key", lineno); + if (type == DB_RECNO) + err("line %lu: 'K' not available for recno", + lineno); + key.data = rfile(p + 1, &key.size); + goto lkey; + case 'k': /* key */ + if (state != KEY) + err("line %lu: not expecting a key", lineno); + if (type == DB_RECNO) { + static recno_t recno; + recno = atoi(p + 1); + key.data = &recno; + key.size = sizeof(recno); + } else { + key.data = xmalloc(p + 1, len - 1); + key.size = len - 1; + } +lkey: switch (command) { + case COMPARE: + getdata(dbp, &key, &keydata); + state = DATA; + break; + case GET: + get(dbp, &key); + if (type != DB_RECNO) + free(key.data); + state = COMMAND; + break; + case PUT: + state = DATA; + break; + case REMOVE: + rem(dbp, &key); + if ((type != DB_RECNO) && (flags != R_CURSOR)) + free(key.data); + state = COMMAND; + break; + case SEQ: + seq(dbp, &key); + if ((type != DB_RECNO) && (flags != R_CURSOR)) + free(key.data); + state = COMMAND; + break; + default: + err("line %lu: command doesn't take a key", + lineno); + } + break; + case 'o': + dump(dbp, p[1] == 'r'); + break; + default: + err("line %lu: %s: unknown command character", + lineno, p); + } + } +#ifdef STATISTICS + /* + * -l must be used (DB_LOCK must be set) for this to be + * used, otherwise a page will be locked and it will fail. + */ + if (type == DB_BTREE && oflags & DB_LOCK) + __bt_stat(dbp); +#endif + if (dbp->close(dbp)) + err("db->close: %s", strerror(errno)); + (void)close(ofd); + exit(0); +} + +#define NOOVERWRITE "put failed, would overwrite key\n" + +void +compare(db1, db2) + DBT *db1, *db2; +{ + size_t len; + u_char *p1, *p2; + + if (db1->size != db2->size) + printf("compare failed: key->data len %lu != data len %lu\n", + db1->size, db2->size); + + len = MIN(db1->size, db2->size); + for (p1 = db1->data, p2 = db2->data; len--;) + if (*p1++ != *p2++) { + printf("compare failed at offset %d\n", + p1 - (u_char *)db1->data); + break; + } +} + +void +get(dbp, kp) + DB *dbp; + DBT *kp; +{ + DBT data; + + switch (dbp->get(dbp, kp, &data, flags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case -1: + err("line %lu: get: %s", lineno, strerror(errno)); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "get failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else + (void)fprintf(stderr, "%d: %.*s: %s", + lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); +#undef NOSUCHKEY + break; + } +} + +void +getdata(dbp, kp, dp) + DB *dbp; + DBT *kp, *dp; +{ + switch (dbp->get(dbp, kp, dp, flags)) { + case 0: + return; + case -1: + err("line %lu: getdata: %s", lineno, strerror(errno)); + /* NOTREACHED */ + case 1: + err("line %lu: getdata failed, no such key", lineno); + /* NOTREACHED */ + } +} + +void +put(dbp, kp, dp) + DB *dbp; + DBT *kp, *dp; +{ + switch (dbp->put(dbp, kp, dp, flags)) { + case 0: + break; + case -1: + err("line %lu: put: %s", lineno, strerror(errno)); + /* NOTREACHED */ + case 1: + (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1); + break; + } +} + +void +rem(dbp, kp) + DB *dbp; + DBT *kp; +{ + switch (dbp->del(dbp, kp, flags)) { + case 0: + break; + case -1: + err("line %lu: rem: %s", lineno, strerror(errno)); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "rem failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else if (flags != R_CURSOR) + (void)fprintf(stderr, "%d: %.*s: %s", + lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); + else + (void)fprintf(stderr, + "%d: rem of cursor failed\n", lineno); +#undef NOSUCHKEY + break; + } +} + +void +synk(dbp) + DB *dbp; +{ + switch (dbp->sync(dbp, flags)) { + case 0: + break; + case -1: + err("line %lu: synk: %s", lineno, strerror(errno)); + /* NOTREACHED */ + } +} + +void +seq(dbp, kp) + DB *dbp; + DBT *kp; +{ + DBT data; + + switch (dbp->seq(dbp, kp, &data, flags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case -1: + err("line %lu: seq: %s", lineno, strerror(errno)); + /* NOTREACHED */ + case 1: +#define NOSUCHKEY "seq failed, no such key\n" + if (ofd != STDOUT_FILENO) + (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1); + else if (flags == R_CURSOR) + (void)fprintf(stderr, "%d: %.*s: %s", + lineno, MIN(kp->size, 20), kp->data, NOSUCHKEY); + else + (void)fprintf(stderr, + "%d: seq (%s) failed\n", lineno, sflags(flags)); +#undef NOSUCHKEY + break; + } +} + +void +dump(dbp, rev) + DB *dbp; + int rev; +{ + DBT key, data; + int flags, nflags; + + if (rev) { + flags = R_LAST; + nflags = R_PREV; + } else { + flags = R_FIRST; + nflags = R_NEXT; + } + for (;; flags = nflags) + switch (dbp->seq(dbp, &key, &data, flags)) { + case 0: + (void)write(ofd, data.data, data.size); + if (ofd == STDOUT_FILENO) + (void)write(ofd, "\n", 1); + break; + case 1: + goto done; + case -1: + err("line %lu: (dump) seq: %s", + lineno, strerror(errno)); + /* NOTREACHED */ + } +done: return; +} + +u_int +setflags(s) + char *s; +{ + char *p, *index(); + + for (; isspace(*s); ++s); + if (*s == '\n' || *s == '\0') + return (0); + if ((p = index(s, '\n')) != NULL) + *p = '\0'; + if (!strcmp(s, "R_CURSOR")) return (R_CURSOR); + if (!strcmp(s, "R_FIRST")) return (R_FIRST); + if (!strcmp(s, "R_IAFTER")) return (R_IAFTER); + if (!strcmp(s, "R_IBEFORE")) return (R_IBEFORE); + if (!strcmp(s, "R_LAST")) return (R_LAST); + if (!strcmp(s, "R_NEXT")) return (R_NEXT); + if (!strcmp(s, "R_NOOVERWRITE")) return (R_NOOVERWRITE); + if (!strcmp(s, "R_PREV")) return (R_PREV); + if (!strcmp(s, "R_SETCURSOR")) return (R_SETCURSOR); + + err("line %lu: %s: unknown flag", lineno, s); + /* NOTREACHED */ +} + +char * +sflags(flags) + int flags; +{ + switch (flags) { + case R_CURSOR: return ("R_CURSOR"); + case R_FIRST: return ("R_FIRST"); + case R_IAFTER: return ("R_IAFTER"); + case R_IBEFORE: return ("R_IBEFORE"); + case R_LAST: return ("R_LAST"); + case R_NEXT: return ("R_NEXT"); + case R_NOOVERWRITE: return ("R_NOOVERWRITE"); + case R_PREV: return ("R_PREV"); + case R_SETCURSOR: return ("R_SETCURSOR"); + } + + return ("UNKNOWN!"); +} + +DBTYPE +dbtype(s) + char *s; +{ + if (!strcmp(s, "btree")) + return (DB_BTREE); + if (!strcmp(s, "hash")) + return (DB_HASH); + if (!strcmp(s, "recno")) + return (DB_RECNO); + err("%s: unknown type (use btree, hash or recno)", s); + /* NOTREACHED */ +} + +void * +setinfo(type, s) + DBTYPE type; + char *s; +{ + static BTREEINFO ib; + static HASHINFO ih; + static RECNOINFO rh; + char *eq, *index(); + + if ((eq = index(s, '=')) == NULL) + err("%s: illegal structure set statement", s); + *eq++ = '\0'; + if (!isdigit(*eq)) + err("%s: structure set statement must be a number", s); + + switch (type) { + case DB_BTREE: + if (!strcmp("flags", s)) { + ib.flags = atoi(eq); + return (&ib); + } + if (!strcmp("cachesize", s)) { + ib.cachesize = atoi(eq); + return (&ib); + } + if (!strcmp("maxkeypage", s)) { + ib.maxkeypage = atoi(eq); + return (&ib); + } + if (!strcmp("minkeypage", s)) { + ib.minkeypage = atoi(eq); + return (&ib); + } + if (!strcmp("lorder", s)) { + ib.lorder = atoi(eq); + return (&ib); + } + if (!strcmp("psize", s)) { + ib.psize = atoi(eq); + return (&ib); + } + break; + case DB_HASH: + if (!strcmp("bsize", s)) { + ih.bsize = atoi(eq); + return (&ih); + } + if (!strcmp("ffactor", s)) { + ih.ffactor = atoi(eq); + return (&ih); + } + if (!strcmp("nelem", s)) { + ih.nelem = atoi(eq); + return (&ih); + } + if (!strcmp("cachesize", s)) { + ih.cachesize = atoi(eq); + return (&ih); + } + if (!strcmp("lorder", s)) { + ih.lorder = atoi(eq); + return (&ih); + } + break; + case DB_RECNO: + if (!strcmp("flags", s)) { + rh.flags = atoi(eq); + return (&rh); + } + if (!strcmp("cachesize", s)) { + rh.cachesize = atoi(eq); + return (&rh); + } + if (!strcmp("lorder", s)) { + rh.lorder = atoi(eq); + return (&rh); + } + if (!strcmp("reclen", s)) { + rh.reclen = atoi(eq); + return (&rh); + } + if (!strcmp("bval", s)) { + rh.bval = atoi(eq); + return (&rh); + } + if (!strcmp("psize", s)) { + rh.psize = atoi(eq); + return (&rh); + } + break; + } + err("%s: unknown structure value", s); + /* NOTREACHED */ +} + +void * +rfile(name, lenp) + char *name; + size_t *lenp; +{ + struct stat sb; + void *p; + int fd; + char *np, *index(); + + for (; isspace(*name); ++name); + if ((np = index(name, '\n')) != NULL) + *np = '\0'; + if ((fd = open(name, O_RDONLY, 0)) < 0 || + fstat(fd, &sb)) + err("%s: %s\n", name, strerror(errno)); +#ifdef NOT_PORTABLE + if (sb.st_size > (off_t)SIZE_T_MAX) + err("%s: %s\n", name, strerror(E2BIG)); +#endif + if ((p = (void *)malloc((u_int)sb.st_size)) == NULL) + err("%s", strerror(errno)); + (void)read(fd, p, (int)sb.st_size); + *lenp = sb.st_size; + (void)close(fd); + return (p); +} + +void * +xmalloc(text, len) + char *text; + size_t len; +{ + void *p; + + if ((p = (void *)malloc(len)) == NULL) + err("%s", strerror(errno)); + memmove(p, text, len); + return (p); +} + +void +usage() +{ + (void)fprintf(stderr, + "usage: dbtest [-l] [-f file] [-i info] [-o file] type script\n"); + exit(1); +} + +#include + +void +err(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + (void)fprintf(stderr, "dbtest: "); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + (void)fprintf(stderr, "\n"); + exit(1); + /* NOTREACHED */ +} diff --git a/lib/libc/db/test/hash.tests/driver2.c b/lib/libc/db/test/hash.tests/driver2.c new file mode 100644 index 0000000..28a5bdb --- /dev/null +++ b/lib/libc/db/test/hash.tests/driver2.c @@ -0,0 +1,112 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * 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. + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)driver2.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/db/test/hash.tests/driver2.c 165903 2007-01-09 00:28:16Z imp $"); + +/* + * Test driver, to try to tackle the large ugly-split problem. + */ + +#include +#include +#include "ndbm.h" + +int my_hash(key, len) + char *key; + int len; +{ + return(17); /* So I'm cruel... */ +} + +main(argc, argv) + int argc; +{ + DB *db; + DBT key, content; + char keybuf[2049]; + char contentbuf[2049]; + char buf[256]; + int i; + HASHINFO info; + + info.bsize = 1024; + info.ffactor = 5; + info.nelem = 1; + info.cachesize = NULL; +#ifdef HASH_ID_PROGRAM_SPECIFIED + info.hash_id = HASH_ID_PROGRAM_SPECIFIED; + info.hash_func = my_hash; +#else + info.hash = my_hash; +#endif + info.lorder = 0; + if (!(db = dbopen("bigtest", O_RDWR | O_CREAT, 0644, DB_HASH, &info))) { + sprintf(buf, "dbopen: failed on file bigtest"); + perror(buf); + exit(1); + } + srandom(17); + key.data = keybuf; + content.data = contentbuf; + bzero(keybuf, sizeof(keybuf)); + bzero(contentbuf, sizeof(contentbuf)); + for (i=1; i <= 500; i++) { + key.size = 128 + (random()&1023); + content.size = 128 + (random()&1023); +/* printf("%d: Key size %d, data size %d\n", i, key.size, + content.size); */ + sprintf(keybuf, "Key #%d", i); + sprintf(contentbuf, "Contents #%d", i); + if ((db->put)(db, &key, &content, R_NOOVERWRITE)) { + sprintf(buf, "dbm_store #%d", i); + perror(buf); + } + } + if ((db->close)(db)) { + perror("closing hash file"); + exit(1); + } + exit(0); +} + + + diff --git a/lib/libc/db/test/hash.tests/makedb.sh b/lib/libc/db/test/hash.tests/makedb.sh new file mode 100644 index 0000000..f28e281 --- /dev/null +++ b/lib/libc/db/test/hash.tests/makedb.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# +# @(#)makedb.sh 8.1 (Berkeley) 6/4/93 + +awk '{i++; print $0; print i;}' /usr/share/dict/words > WORDS +ls /bin /usr/bin /usr/ucb /etc | egrep '^(...|....|.....|......)$' | \ +sort | uniq | \ +awk '{ + printf "%s\n", $0 + for (i = 0; i < 1000; i++) + printf "%s+", $0 + printf "\n" +}' > LONG.DATA diff --git a/lib/libc/db/test/hash.tests/tcreat3.c b/lib/libc/db/test/hash.tests/tcreat3.c new file mode 100644 index 0000000..2b27be5 --- /dev/null +++ b/lib/libc/db/test/hash.tests/tcreat3.c @@ -0,0 +1,103 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * 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. + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)tcreat3.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/db/test/hash.tests/tcreat3.c 165903 2007-01-09 00:28:16Z imp $"); + +#include +#include +#include +#include + +#define INITIAL 25000 +#define MAXWORDS 25000 /* # of elements in search table */ + +char wp1[8192]; +char wp2[8192]; +main(argc, argv) +char **argv; +{ + DBT item, key; + DB *dbp; + HASHINFO ctl; + FILE *fp; + int trash; + + int i = 0; + + argv++; + ctl.hash = NULL; + ctl.bsize = atoi(*argv++); + ctl.ffactor = atoi(*argv++); + ctl.nelem = atoi(*argv++); + ctl.lorder = 0; + if (!(dbp = dbopen( "hashtest", + O_CREAT|O_TRUNC|O_RDWR, 0600, DB_HASH, &ctl))){ + /* create table */ + fprintf(stderr, "cannot create: hash table (size %d)\n", + INITIAL); + exit(1); + } + + key.data = wp1; + item.data = wp2; + while ( fgets(wp1, 8192, stdin) && + fgets(wp2, 8192, stdin) && + i++ < MAXWORDS) { +/* +* put info in structure, and structure in the item +*/ + key.size = strlen(wp1); + item.size = strlen(wp2); + +/* + * enter key/data pair into the table + */ + if ((dbp->put)(dbp, &key, &item, R_NOOVERWRITE) != NULL) { + fprintf(stderr, "cannot enter: key %s\n", + item.data); + exit(1); + } + } + + (dbp->close)(dbp); + exit(0); +} diff --git a/lib/libc/db/test/hash.tests/tdel.c b/lib/libc/db/test/hash.tests/tdel.c new file mode 100644 index 0000000..0679670 --- /dev/null +++ b/lib/libc/db/test/hash.tests/tdel.c @@ -0,0 +1,120 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * 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. + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)tdel.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/db/test/hash.tests/tdel.c 165903 2007-01-09 00:28:16Z imp $"); + +#include +#include +#include +#include + +#define INITIAL 25000 +#define MAXWORDS 25000 /* # of elements in search table */ + +/* Usage: thash pagesize fillfactor file */ +char wp1[8192]; +char wp2[8192]; +main(argc, argv) +char **argv; +{ + DBT item, key; + DB *dbp; + HASHINFO ctl; + FILE *fp; + int stat; + + int i = 0; + + argv++; + ctl.nelem = INITIAL; + ctl.hash = NULL; + ctl.bsize = atoi(*argv++); + ctl.ffactor = atoi(*argv++); + ctl.cachesize = 1024 * 1024; /* 1 MEG */ + ctl.lorder = 0; + argc -= 2; + if (!(dbp = dbopen( NULL, O_CREAT|O_RDWR, 0400, DB_HASH, &ctl))) { + /* create table */ + fprintf(stderr, "cannot create: hash table size %d)\n", + INITIAL); + exit(1); + } + + key.data = wp1; + item.data = wp2; + while ( fgets(wp1, 8192, stdin) && + fgets(wp2, 8192, stdin) && + i++ < MAXWORDS) { +/* +* put info in structure, and structure in the item +*/ + key.size = strlen(wp1); + item.size = strlen(wp2); + +/* + * enter key/data pair into the table + */ + if ((dbp->put)(dbp, &key, &item, R_NOOVERWRITE) != NULL) { + fprintf(stderr, "cannot enter: key %s\n", + item.data); + exit(1); + } + } + + if ( --argc ) { + fp = fopen ( argv[0], "r"); + i = 0; + while ( fgets(wp1, 8192, fp) && + fgets(wp2, 8192, fp) && + i++ < MAXWORDS) { + key.size = strlen(wp1); + stat = (dbp->del)(dbp, &key, 0); + if (stat) { + fprintf ( stderr, "Error retrieving %s\n", key.data ); + exit(1); + } + } + fclose(fp); + } + (dbp->close)(dbp); + exit(0); +} diff --git a/lib/libc/db/test/hash.tests/testit b/lib/libc/db/test/hash.tests/testit new file mode 100644 index 0000000..039457a --- /dev/null +++ b/lib/libc/db/test/hash.tests/testit @@ -0,0 +1,147 @@ +#!/bin/csh -f +# +# @(#)testit 8.1 (Berkeley) 6/4/93 +# + +echo "" +echo "PAGE FILL " +set name=WORDS + set i = 256 + foreach j ( 11 14 21 ) + thash4 $i $j 25000 65536 $name < $name + end + set i = 512 + foreach j ( 21 28 43 ) + thash4 $i $j 25000 65536 $name < $name + end + set i = 1024 + foreach j ( 43 57 85 ) + thash4 $i $j 25000 65536 $name < $name + end + set i = 2048 + foreach j ( 85 114 171 ) + thash4 $i $j 25000 65536 $name < $name + end + set i = 4096 + foreach j ( 171 228 341 ) + thash4 $i $j 25000 65536 $name < $name + end + set i = 8192 + foreach j ( 341 455 683 ) + thash4 $i $j 25000 65536 $name < $name + end + echo "PAGE FILL " + set i = 256 + foreach j ( 11 14 21 ) + echo "$i"_"$j" + tcreat3 $i $j 25000 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 512 + foreach j ( 21 28 43 ) + echo "$i"_"$j" + tcreat3 $i $j 25000 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 1024 + foreach j ( 43 57 85 ) + echo "$i"_"$j" + tcreat3 $i $j 25000 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 2048 + foreach j ( 85 114 171 ) + echo "$i"_"$j" + tcreat3 $i $j 25000 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 4096 + foreach j ( 171 228 341 ) + echo "$i"_"$j" + tcreat3 $i $j 25000 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 8192 + foreach j ( 341 455 683 ) + echo "$i"_"$j" + tcreat3 $i $j 25000 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end +set name=LONG.DATA + set i = 1024 + foreach j ( 1 2 4 ) + echo thash4 $i $j 600 65536 $name + thash4 $i $j 600 65536 $name < $name + end + + set i = 2048 + foreach j ( 1 2 4 ) + echo thash4 $i $j 600 65536 $name + thash4 $i $j 600 65536 $name < $name + end + set i = 4096 + foreach j ( 1 2 4 ) + echo thash4 $i $j 600 65536 $name + thash4 $i $j 600 65536 $name < $name + end + set i = 8192 + foreach j ( 2 4 8 ) + echo thash4 $i $j 600 65536 $name + thash4 $i $j 600 65536 $name < $name + end + echo "PAGE FILL " + set i = 1024 + foreach j ( 1 2 4 ) + echo "$i"_"$j" + tcreat3 $i $j 600 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 2048 + foreach j ( 1 2 4 ) + echo "$i"_"$j" + tcreat3 $i $j 600 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 4096 + foreach j ( 1 2 4 ) + echo "$i"_"$j" + tcreat3 $i $j 600 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end + set i = 8192 + foreach j ( 2 4 8 ) + echo "$i"_"$j" + tcreat3 $i $j 600 $name < $name + tread2 65536 < $name + tverify $name < $name + tseq > /dev/null + tdel $i $j $name < $name + end +driver2 diff --git a/lib/libc/db/test/hash.tests/thash4.c b/lib/libc/db/test/hash.tests/thash4.c new file mode 100644 index 0000000..b04129b --- /dev/null +++ b/lib/libc/db/test/hash.tests/thash4.c @@ -0,0 +1,130 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * 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. + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)thash4.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/db/test/hash.tests/thash4.c 165903 2007-01-09 00:28:16Z imp $"); + +#include +#include +#include +#include +#include +#include + +#define INITIAL 25000 +#define MAXWORDS 25000 /* # of elements in search table */ + +/* Usage: thash pagesize fillfactor file */ +char wp1[8192]; +char wp2[8192]; +main(argc, argv) +char **argv; +{ + DBT item, key, res; + DB *dbp; + HASHINFO ctl; + FILE *fp; + int stat; + time_t t; + + int i = 0; + + argv++; + ctl.hash = NULL; + ctl.bsize = atoi(*argv++); + ctl.ffactor = atoi(*argv++); + ctl.nelem = atoi(*argv++); + ctl.cachesize = atoi(*argv++); + ctl.lorder = 0; + if (!(dbp = dbopen( NULL, O_CREAT|O_RDWR, 0400, DB_HASH, &ctl))) { + /* create table */ + fprintf(stderr, "cannot create: hash table size %d)\n", + INITIAL); + fprintf(stderr, "\terrno: %d\n", errno); + exit(1); + } + + key.data = wp1; + item.data = wp2; + while ( fgets(wp1, 8192, stdin) && + fgets(wp2, 8192, stdin) && + i++ < MAXWORDS) { +/* +* put info in structure, and structure in the item +*/ + key.size = strlen(wp1); + item.size = strlen(wp2); + +/* + * enter key/data pair into the table + */ + if ((dbp->put)(dbp, &key, &item, R_NOOVERWRITE) != NULL) { + fprintf(stderr, "cannot enter: key %s\n", + item.data); + fprintf(stderr, "\terrno: %d\n", errno); + exit(1); + } + } + + if ( --argc ) { + fp = fopen ( argv[0], "r"); + i = 0; + while ( fgets(wp1, 256, fp) && + fgets(wp2, 8192, fp) && + i++ < MAXWORDS) { + + key.size = strlen(wp1); + stat = (dbp->get)(dbp, &key, &res, 0); + if (stat < 0 ) { + fprintf ( stderr, "Error retrieving %s\n", key.data ); + fprintf(stderr, "\terrno: %d\n", errno); + exit(1); + } else if ( stat > 0 ) { + fprintf ( stderr, "%s not found\n", key.data ); + fprintf(stderr, "\terrno: %d\n", errno); + exit(1); + } + } + fclose(fp); + } + dbp->close(dbp); + exit(0); +} diff --git a/lib/libc/db/test/hash.tests/tread2.c b/lib/libc/db/test/hash.tests/tread2.c new file mode 100644 index 0000000..1e91978 --- /dev/null +++ b/lib/libc/db/test/hash.tests/tread2.c @@ -0,0 +1,103 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * 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. + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)tread2.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/db/test/hash.tests/tread2.c 165903 2007-01-09 00:28:16Z imp $"); + +#include +#include +#include +#include + +#define INITIAL 25000 +#define MAXWORDS 25000 /* # of elements in search table */ + +typedef struct { /* info to be stored */ + int num, siz; +} info; + +char wp1[8192]; +char wp2[8192]; +main(argc, argv) +char **argv; +{ + DBT item, key, res; + DB *dbp; + HASHINFO ctl; + int stat; + + int i = 0; + + ctl.nelem = INITIAL; + ctl.hash = NULL; + ctl.bsize = 64; + ctl.ffactor = 1; + ctl.cachesize = atoi(*argv++); + ctl.lorder = 0; + if (!(dbp = dbopen( "hashtest", O_RDONLY, 0400, DB_HASH, &ctl))) { + /* create table */ + fprintf(stderr, "cannot open: hash table\n" ); + exit(1); + } + + key.data = wp1; + item.data = wp2; + while ( fgets(wp1, 8192, stdin) && + fgets(wp2, 8192, stdin) && + i++ < MAXWORDS) { +/* +* put info in structure, and structure in the item +*/ + key.size = strlen(wp1); + item.size = strlen(wp2); + + stat = (dbp->get)(dbp, &key, &res,0); + if (stat < 0) { + fprintf ( stderr, "Error retrieving %s\n", key.data ); + exit(1); + } else if ( stat > 0 ) { + fprintf ( stderr, "%s not found\n", key.data ); + exit(1); + } + } + (dbp->close)(dbp); + exit(0); +} diff --git a/lib/libc/db/test/hash.tests/tseq.c b/lib/libc/db/test/hash.tests/tseq.c new file mode 100644 index 0000000..71653d4 --- /dev/null +++ b/lib/libc/db/test/hash.tests/tseq.c @@ -0,0 +1,86 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * 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. + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)tseq.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/db/test/hash.tests/tseq.c 165903 2007-01-09 00:28:16Z imp $"); + +#include +#include +#include +#include + +#define INITIAL 25000 +#define MAXWORDS 25000 /* # of elements in search table */ + + +char wp[8192]; +char cp[8192]; +main(argc, argv) +char **argv; +{ + DBT item, key, res; + DB *dbp; + FILE *fp; + int stat; + + if (!(dbp = dbopen( "hashtest", O_RDONLY, 0400, DB_HASH, NULL))) { + /* create table */ + fprintf(stderr, "cannot open: hash table\n" ); + exit(1); + } + +/* +* put info in structure, and structure in the item +*/ + for ( stat = (dbp->seq) (dbp, &res, &item, 1 ); + stat == 0; + stat = (dbp->seq) (dbp, &res, &item, 0 ) ) { + + bcopy ( res.data, wp, res.size ); + wp[res.size] = 0; + bcopy ( item.data, cp, item.size ); + cp[item.size] = 0; + + printf ( "%s %s\n", wp, cp ); + } + (dbp->close)(dbp); + exit(0); +} diff --git a/lib/libc/db/test/hash.tests/tverify.c b/lib/libc/db/test/hash.tests/tverify.c new file mode 100644 index 0000000..55e42c0 --- /dev/null +++ b/lib/libc/db/test/hash.tests/tverify.c @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Margo Seltzer. + * + * 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. + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)tverify.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/db/test/hash.tests/tverify.c 165903 2007-01-09 00:28:16Z imp $"); + +#include +#include +#include +#include + +#define INITIAL 25000 +#define MAXWORDS 25000 /* # of elements in search table */ + +typedef struct { /* info to be stored */ + int num, siz; +} info; + +char wp1[8192]; +char wp2[8192]; +main(argc, argv) +char **argv; +{ + DBT key, res; + DB *dbp; + HASHINFO ctl; + int trash; + int stat; + + int i = 0; + + ctl.nelem = INITIAL; + ctl.hash = NULL; + ctl.bsize = 64; + ctl.ffactor = 1; + ctl.cachesize = 1024 * 1024; /* 1 MEG */ + ctl.lorder = 0; + if (!(dbp = dbopen( "hashtest", O_RDONLY, 0400, DB_HASH, &ctl))) { + /* create table */ + fprintf(stderr, "cannot open: hash table\n" ); + exit(1); + } + + key.data = wp1; + while ( fgets(wp1, 8192, stdin) && + fgets(wp2, 8192, stdin) && + i++ < MAXWORDS) { +/* +* put info in structure, and structure in the item +*/ + key.size = strlen(wp1); + + stat = (dbp->get)(dbp, &key, &res,0); + if (stat < 0) { + fprintf ( stderr, "Error retrieving %s\n", key.data ); + exit(1); + } else if ( stat > 0 ) { + fprintf ( stderr, "%s not found\n", key.data ); + exit(1); + } + if ( memcmp ( res.data, wp2, res.size ) ) { + fprintf ( stderr, "data for %s is incorrect. Data was %s. Should have been %s\n", key.data, res.data, wp2 ); + } + } + (dbp->close)(dbp); + exit(0); +} diff --git a/lib/libc/db/test/run.test b/lib/libc/db/test/run.test new file mode 100644 index 0000000..52b74c3 --- /dev/null +++ b/lib/libc/db/test/run.test @@ -0,0 +1,705 @@ +#!/bin/sh - +# +# @(#)run.test 8.10 (Berkeley) 7/26/94 +# + +# db regression tests +main() +{ + + PROG=./dbtest + TMP1=t1 + TMP2=t2 + TMP3=t3 + + if [ -f /usr/share/dict/words ]; then + DICT=/usr/share/dict/words + elif [ -f /usr/dict/words ]; then + DICT=/usr/dict/words + else + echo 'run.test: no dictionary' + exit 1 + fi + + if [ $# -eq 0 ]; then + for t in 1 2 3 4 5 6 7 8 9 10 11 12 13 20; do + test$t + done + else + while [ $# -gt 0 ] + do case "$1" in + test*) + $1;; + [0-9]*) + test$1;; + btree) + for t in 1 2 3 7 8 9 10 12 13; do + test$t + done;; + hash) + for t in 1 2 3 8 13 20; do + test$t + done;; + recno) + for t in 1 2 3 4 5 6 7 10 11; do + test$t + done;; + *) + echo "run.test: unknown test $1" + echo "usage: run.test test# | type" + exit 1 + esac + shift + done + fi + rm -f $TMP1 $TMP2 $TMP3 + exit 0 +} + +# Take the first hundred entries in the dictionary, and make them +# be key/data pairs. +test1() +{ + echo "Test 1: btree, hash: small key, small data pairs" + sed 200q $DICT > $TMP1 + for type in btree hash; do + rm -f $TMP2 $TMP3 + for i in `sed 200q $DICT`; do + echo p + echo k$i + echo d$i + echo g + echo k$i + done > $TMP2 + $PROG -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test1: type $type: failed" + exit 1 + fi + done + echo "Test 1: recno: small key, small data pairs" + rm -f $TMP2 $TMP3 + sed 200q $DICT | + awk '{ + ++i; + printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i); + }' > $TMP2 + $PROG -o $TMP3 recno $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test1: type recno: failed" + exit 1 + fi +} + +# Take the first 200 entries in the dictionary, and give them +# each a medium size data entry. +test2() +{ + echo "Test 2: btree, hash: small key, medium data pairs" + mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) print $0 }' > $TMP1 + for type in hash btree; do + rm -f $TMP2 $TMP3 + for i in `sed 200q $DICT`; do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done > $TMP2 + $PROG -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test2: type $type: failed" + exit 1 + fi + done + echo "Test 2: recno: small key, medium data pairs" + rm -f $TMP2 $TMP3 + echo $mdata | + awk '{ for (i = 1; i < 201; ++i) + printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i); + }' > $TMP2 + $PROG -o $TMP3 recno $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test2: type recno: failed" + exit 1 + fi +} + +# Insert the programs in /bin with their paths as their keys. +test3() +{ + echo "Test 3: hash: small key, big data pairs" + rm -f $TMP1 + (find /bin -type f -print | xargs cat) > $TMP1 + for type in hash; do + rm -f $TMP2 $TMP3 + for i in `find /bin -type f -print`; do + echo p + echo k$i + echo D$i + echo g + echo k$i + done > $TMP2 + $PROG -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test3: $type: failed" + exit 1 + fi + done + echo "Test 3: btree: small key, big data pairs" + for psize in 512 16384 65536; do + echo " page size $psize" + for type in btree; do + rm -f $TMP2 $TMP3 + for i in `find /bin -type f -print`; do + echo p + echo k$i + echo D$i + echo g + echo k$i + done > $TMP2 + $PROG -i psize=$psize -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test3: $type: page size $psize: failed" + exit 1 + fi + done + done + echo "Test 3: recno: big data pairs" + rm -f $TMP2 $TMP3 + find /bin -type f -print | + awk '{ + ++i; + printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i); + }' > $TMP2 + for psize in 512 16384 65536; do + echo " page size $psize" + $PROG -i psize=$psize -o $TMP3 recno $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test3: recno: page size $psize: failed" + exit 1 + fi + done +} + +# Do random recno entries. +test4() +{ + echo "Test 4: recno: random entries" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 37; i <= 37 + 88 * 17; i += 17) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 1; i <= 15; ++i) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 19234; i <= 19234 + 61 * 27; i += 27) { + if (i % 41) + s = substr($0, 1, i % 41); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit + }' > $TMP1 + rm -f $TMP2 $TMP3 + cat $TMP1 | + awk 'BEGIN { + i = 37; + incr = 17; + } + { + printf("p\nk%d\nd%s\n", i, $0); + if (i == 19234 + 61 * 27) + exit; + if (i == 37 + 88 * 17) { + i = 1; + incr = 1; + } else if (i == 15) { + i = 19234; + incr = 27; + } else + i += incr; + } + END { + for (i = 37; i <= 37 + 88 * 17; i += 17) + printf("g\nk%d\n", i); + for (i = 1; i <= 15; ++i) + printf("g\nk%d\n", i); + for (i = 19234; i <= 19234 + 61 * 27; i += 27) + printf("g\nk%d\n", i); + }' > $TMP2 + $PROG -o $TMP3 recno $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test4: type recno: failed" + exit 1 + fi +} + +# Do reverse order recno entries. +test5() +{ + echo "Test 5: recno: reverse order entries" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk ' { + for (i = 1500; i; --i) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit; + }' > $TMP1 + rm -f $TMP2 $TMP3 + cat $TMP1 | + awk 'BEGIN { + i = 1500; + } + { + printf("p\nk%d\nd%s\n", i, $0); + --i; + } + END { + for (i = 1500; i; --i) + printf("g\nk%d\n", i); + }' > $TMP2 + $PROG -o $TMP3 recno $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test5: type recno: failed" + exit 1 + fi +} + +# Do alternating order recno entries. +test6() +{ + echo "Test 6: recno: alternating order entries" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk ' { + for (i = 1; i < 1200; i += 2) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + for (i = 2; i < 1200; i += 2) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("input key %d: %s\n", i, s); + } + exit; + }' > $TMP1 + rm -f $TMP2 $TMP3 + cat $TMP1 | + awk 'BEGIN { + i = 1; + even = 0; + } + { + printf("p\nk%d\nd%s\n", i, $0); + i += 2; + if (i >= 1200) { + if (even == 1) + exit; + even = 1; + i = 2; + } + } + END { + for (i = 1; i < 1200; ++i) + printf("g\nk%d\n", i); + }' > $TMP2 + $PROG -o $TMP3 recno $TMP2 + sort -o $TMP1 $TMP1 + sort -o $TMP3 $TMP3 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test6: type recno: failed" + exit 1 + fi +} + +# Delete cursor record +test7() +{ + echo "Test 7: btree, recno: delete cursor record" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 1; i <= 120; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + printf("%05d: input key %d: %s\n", 120, 120, $0); + printf("seq failed, no such key\n"); + printf("%05d: input key %d: %s\n", 1, 1, $0); + printf("%05d: input key %d: %s\n", 2, 2, $0); + exit; + }' > $TMP1 + rm -f $TMP2 $TMP3 + + for type in btree recno; do + cat $TMP1 | + awk '{ + if (i == 120) + exit; + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_NEXT\n"); + for (i = 1; i <= 120; ++i) + printf("s\n"); + printf("fR_CURSOR\ns\nk120\n"); + printf("r\n"); + printf("fR_NEXT\ns\n"); + printf("fR_CURSOR\ns\nk1\n"); + printf("r\n"); + printf("fR_FIRST\ns\n"); + }' > $TMP2 + $PROG -o $TMP3 recno $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test7: type $type: failed" + exit 1 + fi + done +} + +# Make sure that overflow pages are reused. +test8() +{ + echo "Test 8: btree, hash: repeated small key, big data pairs" + rm -f $TMP1 + echo "" | + awk 'BEGIN { + for (i = 1; i <= 10; ++i) { + printf("p\nkkey1\nD/bin/sh\n"); + printf("p\nkkey2\nD/bin/csh\n"); + if (i % 8 == 0) { + printf("c\nkkey2\nD/bin/csh\n"); + printf("c\nkkey1\nD/bin/sh\n"); + printf("e\t%d of 10 (comparison)\n", i); + } else + printf("e\t%d of 10 \n", i); + printf("r\nkkey1\nr\nkkey2\n"); + } + }' > $TMP1 + $PROG btree $TMP1 +# $PROG hash $TMP1 + # No explicit test for success. +} + +# Test btree duplicate keys +test9() +{ + echo "Test 9: btree: duplicate keys" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 1; i <= 543; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' > $TMP1 + rm -f $TMP2 $TMP3 + + for type in btree; do + cat $TMP1 | + awk '{ + if (i++ % 2) + printf("p\nkduplicatekey\nd%s\n", $0); + else + printf("p\nkunique%dkey\nd%s\n", i, $0); + } + END { + printf("o\n"); + }' > $TMP2 + $PROG -iflags=1 -o $TMP3 $type $TMP2 + sort -o $TMP3 $TMP3 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test9: type $type: failed" + exit 1 + fi + done +} + +# Test use of cursor flags without initialization +test10() +{ + echo "Test 10: btree, recno: test cursor flag use" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 1; i <= 20; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' > $TMP1 + rm -f $TMP2 $TMP3 + + # Test that R_CURSOR doesn't succeed before cursor initialized + for type in btree recno; do + cat $TMP1 | + awk '{ + if (i == 10) + exit; + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_CURSOR\nr\n"); + printf("eR_CURSOR SHOULD HAVE FAILED\n"); + }' > $TMP2 + $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1 + if [ -s $TMP3 ] ; then + echo "Test 10: delete: R_CURSOR SHOULD HAVE FAILED" + exit 1 + fi + done + for type in btree recno; do + cat $TMP1 | + awk '{ + if (i == 10) + exit; + printf("p\nk%d\nd%s\n", ++i, $0); + } + END { + printf("fR_CURSOR\np\nk1\ndsome data\n"); + printf("eR_CURSOR SHOULD HAVE FAILED\n"); + }' > $TMP2 + $PROG -o $TMP3 $type $TMP2 > /dev/null 2>&1 + if [ -s $TMP3 ] ; then + echo "Test 10: put: R_CURSOR SHOULD HAVE FAILED" + exit 1 + fi + done +} + +# Test insert in reverse order. +test11() +{ + echo "Test 11: recno: reverse order insert" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 1; i <= 779; ++i) + printf("%05d: input key %d: %s\n", i, i, $0); + exit; + }' > $TMP1 + rm -f $TMP2 $TMP3 + + for type in recno; do + cat $TMP1 | + awk '{ + if (i == 0) { + i = 1; + printf("p\nk1\nd%s\n", $0); + printf("%s\n", "fR_IBEFORE"); + } else + printf("p\nk1\nd%s\n", $0); + } + END { + printf("or\n"); + }' > $TMP2 + $PROG -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test11: type $type: failed" + exit 1 + fi + done +} + +# Take the first 20000 entries in the dictionary, reverse them, and give +# them each a small size data entry. Use a small page size to make sure +# the btree split code gets hammered. +test12() +{ + echo "Test 12: btree: lots of keys, small page size" + mdata=abcdefghijklmnopqrstuvwxy + echo $mdata | + awk '{ for (i = 1; i < 20001; ++i) print $0 }' > $TMP1 + for type in btree; do + rm -f $TMP2 $TMP3 + for i in `sed 20000q $DICT | rev`; do + echo p + echo k$i + echo d$mdata + echo g + echo k$i + done > $TMP2 + $PROG -i psize=512 -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test12: type $type: failed" + exit 1 + fi + done +} + +# Test different byte orders. +test13() +{ + echo "Test 13: btree, hash: differing byte orders" + sed 50q $DICT > $TMP1 + for order in 1234 4321; do + for type in btree hash; do + rm -f byte.file $TMP2 $TMP3 + for i in `sed 50q $DICT`; do + echo p + echo k$i + echo d$i + echo g + echo k$i + done > $TMP2 + $PROG -ilorder=$order -f byte.file -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test13: $type/$order put failed" + exit 1 + fi + for i in `sed 50q $DICT`; do + echo g + echo k$i + done > $TMP2 + $PROG -s \ + -ilorder=$order -f byte.file -o $TMP3 $type $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test13: $type/$order get failed" + exit 1 + fi + done + done + rm -f byte.file +} + +# Try a variety of bucketsizes and fill factors for hashing +test20() +{ + echo\ + "Test 20: hash: bucketsize, fill factor; nelem 25000 cachesize 65536" + echo "abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" | + awk '{ + for (i = 1; i <= 10000; ++i) { + if (i % 34) + s = substr($0, 1, i % 34); + else + s = substr($0, 1); + printf("%s\n", s); + } + exit; + }' > $TMP1 + sed 10000q $DICT | + awk 'BEGIN { + ds="abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg" + } + { + if (++i % 34) + s = substr(ds, 1, i % 34); + else + s = substr(ds, 1); + printf("p\nk%s\nd%s\n", $0, s); + }' > $TMP2 + sed 10000q $DICT | + awk '{ + ++i; + printf("g\nk%s\n", $0); + }' >> $TMP2 + bsize=256 + for ffactor in 11 14 21; do + echo " bucketsize $bsize, fill factor $ffactor" + $PROG -o$TMP3 \ + -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ + hash $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" + exit 1 + fi + done + bsize=512 + for ffactor in 21 28 43; do + echo " bucketsize $bsize, fill factor $ffactor" + $PROG -o$TMP3 \ + -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ + hash $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" + exit 1 + fi + done + bsize=1024 + for ffactor in 43 57 85; do + echo " bucketsize $bsize, fill factor $ffactor" + $PROG -o$TMP3 \ + -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ + hash $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" + exit 1 + fi + done + bsize=2048 + for ffactor in 85 114 171; do + echo " bucketsize $bsize, fill factor $ffactor" + $PROG -o$TMP3 \ + -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ + hash $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" + exit 1 + fi + done + bsize=4096 + for ffactor in 171 228 341; do + echo " bucketsize $bsize, fill factor $ffactor" + $PROG -o$TMP3 \ + -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ + hash $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" + exit 1 + fi + done + bsize=8192 + for ffactor in 341 455 683; do + echo " bucketsize $bsize, fill factor $ffactor" + $PROG -o$TMP3 \ + -ibsize=$bsize,ffactor=$ffactor,nelem=25000,cachesize=65536\ + hash $TMP2 + if (cmp -s $TMP1 $TMP3) ; then : + else + echo "test20: type hash:\ +bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" + exit 1 + fi + done +} + +main $* diff --git a/lib/libc/gdtoa/Makefile.inc b/lib/libc/gdtoa/Makefile.inc new file mode 100644 index 0000000..27073ae --- /dev/null +++ b/lib/libc/gdtoa/Makefile.inc @@ -0,0 +1,21 @@ +# $FreeBSD: releng/11.1/lib/libc/gdtoa/Makefile.inc 316423 2017-04-02 17:24:58Z dim $ + +# netlib gdtoa sources +.PATH: ${LIBC_SRCTOP}/gdtoa + +MISRCS+=_hdtoa.c _hldtoa.c _ldtoa.c glue.c +GDTOASRCS+=dmisc.c dtoa.c gdtoa.c gethex.c gmisc.c \ + hd_init.c hexnan.c misc.c smisc.c \ + strtod.c strtodg.c strtof.c strtord.c sum.c ulp.c + +SYM_MAPS+=${LIBC_SRCTOP}/gdtoa/Symbol.map + +CFLAGS+=-I${SRCTOP}/contrib/gdtoa + +.for src in ${GDTOASRCS} +MISRCS+=gdtoa_${src} +CLEANFILES+=gdtoa_${src} +gdtoa_${src}: ${SRCTOP}/contrib/gdtoa/${src} .NOMETA + ln -sf ${.ALLSRC} ${.TARGET} +CFLAGS.gdtoa_${src}+=-fno-strict-aliasing +.endfor diff --git a/lib/libc/gdtoa/Symbol.map b/lib/libc/gdtoa/Symbol.map new file mode 100644 index 0000000..d8f62e1 --- /dev/null +++ b/lib/libc/gdtoa/Symbol.map @@ -0,0 +1,19 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/gdtoa/Symbol.map 174681 2007-12-16 21:15:57Z das $ + */ + +FBSD_1.0 { + /* + * Standard functions from contrib/gdtoa + */ + strtod; + strtof; + + /* FreeBSD additions */ + strtold; +}; + +FBSDprivate_1.0 { + /* used in libm */ + __hexnan_D2A; +}; diff --git a/lib/libc/gdtoa/_hldtoa.c b/lib/libc/gdtoa/_hldtoa.c new file mode 100644 index 0000000..77796a6 --- /dev/null +++ b/lib/libc/gdtoa/_hldtoa.c @@ -0,0 +1,177 @@ +/*- + * Copyright (c) 2004-2008 David Schultz + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gdtoa/_hldtoa.c 178154 2008-04-12 14:53:52Z das $"); + +#include +#include +#include +#include + +#ifdef __i386__ +#include +#endif + +#include "../stdio/floatio.h" +#include "fpmath.h" +#include "gdtoaimp.h" + +#if (LDBL_MANT_DIG > DBL_MANT_DIG) + +/* Strings values used by dtoa() */ +#define INFSTR "Infinity" +#define NANSTR "NaN" + +#ifdef LDBL_IMPLICIT_NBIT +#define MANH_SIZE LDBL_MANH_SIZE +#else +#define MANH_SIZE (LDBL_MANH_SIZE - 1) +#endif + +#if MANH_SIZE > 32 +typedef uint64_t manh_t; +#else +typedef uint32_t manh_t; +#endif + +#if LDBL_MANL_SIZE > 32 +typedef uint64_t manl_t; +#else +typedef uint32_t manl_t; +#endif + +#define LDBL_ADJ (LDBL_MAX_EXP - 2) +#define SIGFIGS ((LDBL_MANT_DIG + 3) / 4 + 1) + +static const float one[] = { 1.0f, -1.0f }; + +/* + * This is the long double version of __hdtoa(). + */ +char * +__hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign, + char **rve) +{ + union IEEEl2bits u; + char *s, *s0; + manh_t manh; + manl_t manl; + int bufsize; +#ifdef __i386__ + fp_prec_t oldprec; +#endif + + u.e = e; + *sign = u.bits.sign; + + switch (fpclassify(e)) { + case FP_NORMAL: + *decpt = u.bits.exp - LDBL_ADJ; + break; + case FP_ZERO: + *decpt = 1; + return (nrv_alloc("0", rve, 1)); + case FP_SUBNORMAL: +#ifdef __i386__ + oldprec = fpsetprec(FP_PE); +#endif + u.e *= 0x1p514L; + *decpt = u.bits.exp - (514 + LDBL_ADJ); +#ifdef __i386__ + fpsetprec(oldprec); +#endif + break; + case FP_INFINITE: + *decpt = INT_MAX; + return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1)); + default: /* FP_NAN or unrecognized */ + *decpt = INT_MAX; + return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1)); + } + + /* FP_NORMAL or FP_SUBNORMAL */ + + if (ndigits == 0) /* dtoa() compatibility */ + ndigits = 1; + + /* + * If ndigits < 0, we are expected to auto-size, so we allocate + * enough space for all the digits. + */ + bufsize = (ndigits > 0) ? ndigits : SIGFIGS; + s0 = rv_alloc(bufsize); + + /* Round to the desired number of digits. */ + if (SIGFIGS > ndigits && ndigits > 0) { + float redux = one[u.bits.sign]; + int offset = 4 * ndigits + LDBL_MAX_EXP - 4 - LDBL_MANT_DIG; +#ifdef __i386__ + oldprec = fpsetprec(FP_PE); +#endif + u.bits.exp = offset; + u.e += redux; + u.e -= redux; + *decpt += u.bits.exp - offset; +#ifdef __i386__ + fpsetprec(oldprec); +#endif + } + + mask_nbit_l(u); + manh = u.bits.manh; + manl = u.bits.manl; + *s0 = '1'; + for (s = s0 + 1; s < s0 + bufsize; s++) { + *s = xdigs[(manh >> (MANH_SIZE - 4)) & 0xf]; + manh = (manh << 4) | (manl >> (LDBL_MANL_SIZE - 4)); + manl <<= 4; + } + + /* If ndigits < 0, we are expected to auto-size the precision. */ + if (ndigits < 0) { + for (ndigits = SIGFIGS; s0[ndigits - 1] == '0'; ndigits--) + ; + } + + s = s0 + ndigits; + *s = '\0'; + if (rve != NULL) + *rve = s; + return (s0); +} + +#else /* (LDBL_MANT_DIG == DBL_MANT_DIG) */ + +char * +__hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign, + char **rve) +{ + + return (__hdtoa((double)e, xdigs, ndigits, decpt, sign, rve)); +} + +#endif /* (LDBL_MANT_DIG == DBL_MANT_DIG) */ diff --git a/lib/libc/gdtoa/machdep_ldisQ.c b/lib/libc/gdtoa/machdep_ldisQ.c new file mode 100644 index 0000000..dab7354 --- /dev/null +++ b/lib/libc/gdtoa/machdep_ldisQ.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2003 David Schultz + * All rights reserved. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * uses quad precision, such as sparc64. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gdtoa/machdep_ldisQ.c 227753 2011-11-20 14:45:42Z theraven $"); + +#include + +#include "gdtoaimp.h" + +long double +strtold_l(const char * __restrict s, char ** __restrict sp, locale_t locale) +{ + long double result; + + strtorQ_l(s, sp, FLT_ROUNDS, &result, locale); + return result; +} diff --git a/lib/libc/gdtoa/machdep_ldisd.c b/lib/libc/gdtoa/machdep_ldisd.c new file mode 100644 index 0000000..7c6485d --- /dev/null +++ b/lib/libc/gdtoa/machdep_ldisd.c @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2003 David Schultz + * All rights reserved. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * is the same as a double, such as the Alpha. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gdtoa/machdep_ldisd.c 227753 2011-11-20 14:45:42Z theraven $"); + +#include "gdtoaimp.h" +#undef strtold_l + +long double +strtold_l(const char * __restrict s, char ** __restrict sp, locale_t locale) +{ + + return strtod_l(s, sp, locale); +} diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc new file mode 100644 index 0000000..6484466 --- /dev/null +++ b/lib/libc/gen/Makefile.inc @@ -0,0 +1,523 @@ +# @(#)Makefile.inc 8.6 (Berkeley) 5/4/95 +# $FreeBSD: releng/11.1/lib/libc/gen/Makefile.inc 315274 2017-03-14 17:52:43Z vangyzen $ + +# machine-independent gen sources +.PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/gen ${LIBC_SRCTOP}/gen + +SRCS+= __getosreldate.c \ + __pthread_mutex_init_calloc_cb_stub.c \ + __xuname.c \ + _once_stub.c \ + _pthread_stubs.c \ + _rand48.c \ + _spinlock_stub.c \ + _thread_init.c \ + alarm.c \ + arc4random.c \ + assert.c \ + auxv.c \ + basename.c \ + cap_sandboxed.c \ + check_utility_compat.c \ + clock.c \ + clock_getcpuclockid.c \ + closedir.c \ + confstr.c \ + crypt.c \ + ctermid.c \ + daemon.c \ + devname.c \ + dirfd.c \ + dirname.c \ + disklabel.c \ + dlfcn.c \ + drand48.c \ + dup3.c \ + elf_utils.c \ + erand48.c \ + err.c \ + errlst.c \ + errno.c \ + exec.c \ + fdevname.c \ + feature_present.c \ + fmtcheck.c \ + fmtmsg.c \ + fnmatch.c \ + fpclassify.c \ + frexp.c \ + fstab.c \ + ftok.c \ + fts.c \ + ftw.c \ + getbootfile.c \ + getbsize.c \ + getcap.c \ + getcwd.c \ + getdomainname.c \ + getgrent.c \ + getgrouplist.c \ + gethostname.c \ + getloadavg.c \ + getlogin.c \ + getmntinfo.c \ + getnetgrent.c \ + getosreldate.c \ + getpagesize.c \ + getpagesizes.c \ + getpeereid.c \ + getprogname.c \ + getpwent.c \ + getttyent.c \ + getusershell.c \ + getutxent.c \ + getvfsbyname.c \ + glob.c \ + initgroups.c \ + isatty.c \ + isinf.c \ + isnan.c \ + jrand48.c \ + lcong48.c \ + libc_dlopen.c \ + lockf.c \ + lrand48.c \ + mrand48.c \ + nftw.c \ + nice.c \ + nlist.c \ + nrand48.c \ + opendir.c \ + pause.c \ + pmadvise.c \ + popen.c \ + posix_spawn.c \ + psignal.c \ + pututxline.c \ + pw_scan.c \ + raise.c \ + readdir.c \ + readpassphrase.c \ + recvmmsg.c \ + rewinddir.c \ + scandir.c \ + seed48.c \ + seekdir.c \ + semctl.c \ + sendmmsg.c \ + setdomainname.c \ + sethostname.c \ + setjmperr.c \ + setmode.c \ + setproctitle.c \ + setprogname.c \ + siginterrupt.c \ + siglist.c \ + signal.c \ + sigsetops.c \ + sleep.c \ + srand48.c \ + statvfs.c \ + stringlist.c \ + strtofflags.c \ + sysconf.c \ + sysctl.c \ + sysctlbyname.c \ + sysctlnametomib.c \ + syslog.c \ + telldir.c \ + termios.c \ + time.c \ + times.c \ + timezone.c \ + tls.c \ + ttyname.c \ + ttyslot.c \ + ualarm.c \ + ulimit.c \ + uname.c \ + usleep.c \ + utime.c \ + utxdb.c \ + valloc.c \ + wait.c \ + wait3.c \ + waitpid.c \ + waitid.c \ + wordexp.c +.if ${MK_SYMVER} == yes +SRCS+= fts-compat.c \ + unvis-compat.c +.endif + +.PATH: ${SRCTOP}/contrib/libc-pwcache +SRCS+= pwcache.c pwcache.h + +.PATH: ${SRCTOP}/contrib/libc-vis +CFLAGS+= -I${SRCTOP}/contrib/libc-vis +SRCS+= unvis.c vis.c + +MISRCS+=modf.c + +CANCELPOINTS_SRCS=sem.c sem_new.c +.for src in ${CANCELPOINTS_SRCS} +SRCS+=cancelpoints_${src} +CLEANFILES+=cancelpoints_${src} +cancelpoints_${src}: ${LIBC_SRCTOP}/gen/${src} .NOMETA + ln -sf ${.ALLSRC} ${.TARGET} +.endfor + +SYM_MAPS+=${LIBC_SRCTOP}/gen/Symbol.map + +# machine-dependent gen sources +.sinclude "${LIBC_SRCTOP}/${LIBC_ARCH}/gen/Makefile.inc" + +MAN+= alarm.3 \ + arc4random.3 \ + basename.3 \ + cap_rights_get.3 \ + cap_sandboxed.3 \ + check_utility_compat.3 \ + clock.3 \ + clock_getcpuclockid.3 \ + confstr.3 \ + ctermid.3 \ + daemon.3 \ + devname.3 \ + directory.3 \ + dirname.3 \ + dl_iterate_phdr.3 \ + dladdr.3 \ + dlinfo.3 \ + dllockinit.3 \ + dlopen.3 \ + dup3.3 \ + err.3 \ + exec.3 \ + feature_present.3 \ + fmtcheck.3 \ + fmtmsg.3 \ + fnmatch.3 \ + fpclassify.3 \ + frexp.3 \ + ftok.3 \ + fts.3 \ + ftw.3 \ + getbootfile.3 \ + getbsize.3 \ + getcap.3 \ + getcontext.3 \ + getcwd.3 \ + getdiskbyname.3 \ + getdomainname.3 \ + getfsent.3 \ + getgrent.3 \ + getgrouplist.3 \ + gethostname.3 \ + getloadavg.3 \ + getmntinfo.3 \ + getnetgrent.3 \ + getosreldate.3 \ + getpagesize.3 \ + getpagesizes.3 \ + getpass.3 \ + getpeereid.3 \ + getprogname.3 \ + getpwent.3 \ + getttyent.3 \ + getusershell.3 \ + getutxent.3 \ + getvfsbyname.3 \ + glob.3 \ + initgroups.3 \ + isgreater.3 \ + ldexp.3 \ + lockf.3 \ + makecontext.3 \ + modf.3 \ + nice.3 \ + nlist.3 \ + pause.3 \ + popen.3 \ + posix_spawn.3 \ + posix_spawn_file_actions_addopen.3 \ + posix_spawn_file_actions_init.3 \ + posix_spawnattr_getflags.3 \ + posix_spawnattr_getpgroup.3 \ + posix_spawnattr_getschedparam.3 \ + posix_spawnattr_getschedpolicy.3 \ + posix_spawnattr_init.3 \ + posix_spawnattr_getsigdefault.3 \ + posix_spawnattr_getsigmask.3 \ + psignal.3 \ + pwcache.3 \ + raise.3 \ + rand48.3 \ + readpassphrase.3 \ + rfork_thread.3 \ + scandir.3 \ + sem_destroy.3 \ + sem_getvalue.3 \ + sem_init.3 \ + sem_open.3 \ + sem_post.3 \ + sem_timedwait.3 \ + sem_wait.3 \ + setjmp.3 \ + setmode.3 \ + setproctitle.3 \ + siginterrupt.3 \ + signal.3 \ + sigsetops.3 \ + sleep.3 \ + statvfs.3 \ + stringlist.3 \ + strtofflags.3 \ + sysconf.3 \ + sysctl.3 \ + syslog.3 \ + tcgetpgrp.3 \ + tcgetsid.3 \ + tcsendbreak.3 \ + tcsetattr.3 \ + tcsetpgrp.3 \ + tcsetsid.3 \ + time.3 \ + times.3 \ + timezone.3 \ + ttyname.3 \ + tzset.3 \ + ualarm.3 \ + ucontext.3 \ + ulimit.3 \ + uname.3 \ + unvis.3 \ + usleep.3 \ + utime.3 \ + valloc.3 \ + vis.3 \ + wordexp.3 + +MLINKS+=arc4random.3 arc4random_addrandom.3 \ + arc4random.3 arc4random_stir.3 \ + arc4random.3 arc4random_buf.3 \ + arc4random.3 arc4random_uniform.3 +MLINKS+=basename.3 basename_r.3 +MLINKS+=ctermid.3 ctermid_r.3 +MLINKS+=devname.3 devname_r.3 +MLINKS+=devname.3 fdevname.3 +MLINKS+=devname.3 fdevname_r.3 +MLINKS+=directory.3 closedir.3 \ + directory.3 dirfd.3 \ + directory.3 fdclosedir.3 \ + directory.3 fdopendir.3 \ + directory.3 opendir.3 \ + directory.3 readdir.3 \ + directory.3 readdir_r.3 \ + directory.3 rewinddir.3 \ + directory.3 seekdir.3 \ + directory.3 telldir.3 +MLINKS+=dlopen.3 fdlopen.3 \ + dlopen.3 dlclose.3 \ + dlopen.3 dlerror.3 \ + dlopen.3 dlfunc.3 \ + dlopen.3 dlsym.3 +MLINKS+=err.3 err_set_exit.3 \ + err.3 err_set_file.3 \ + err.3 errc.3 \ + err.3 errx.3 \ + err.3 verr.3 \ + err.3 verrc.3 \ + err.3 verrx.3 \ + err.3 vwarn.3 \ + err.3 vwarnc.3 \ + err.3 vwarnx.3 \ + err.3 warnc.3 \ + err.3 warn.3 \ + err.3 warnx.3 +MLINKS+=exec.3 execl.3 \ + exec.3 execle.3 \ + exec.3 execlp.3 \ + exec.3 exect.3 \ + exec.3 execv.3 \ + exec.3 execvP.3 \ + exec.3 execvp.3 +MLINKS+=fpclassify.3 finite.3 \ + fpclassify.3 finitef.3 \ + fpclassify.3 isfinite.3 \ + fpclassify.3 isinf.3 \ + fpclassify.3 isnan.3 \ + fpclassify.3 isnormal.3 +MLINKS+=frexp.3 frexpf.3 \ + frexp.3 frexpl.3 +MLINKS+=fts.3 fts_children.3 \ + fts.3 fts_close.3 \ + fts.3 fts_open.3 \ + fts.3 fts_read.3 \ + fts.3 fts_set.3 \ + fts.3 fts_set_clientptr.3 \ + fts.3 fts_get_clientptr.3 \ + fts.3 fts_get_stream.3 +MLINKS+=ftw.3 nftw.3 +MLINKS+=getcap.3 cgetcap.3 \ + getcap.3 cgetclose.3 \ + getcap.3 cgetent.3 \ + getcap.3 cgetfirst.3 \ + getcap.3 cgetmatch.3 \ + getcap.3 cgetnext.3 \ + getcap.3 cgetnum.3 \ + getcap.3 cgetset.3 \ + getcap.3 cgetstr.3 \ + getcap.3 cgetustr.3 +MLINKS+=getcwd.3 getwd.3 +MLINKS+=getcontext.3 getcontextx.3 +MLINKS+=getcontext.3 setcontext.3 +MLINKS+=getdomainname.3 setdomainname.3 +MLINKS+=getfsent.3 endfsent.3 \ + getfsent.3 getfsfile.3 \ + getfsent.3 getfsspec.3 \ + getfsent.3 getfstype.3 \ + getfsent.3 setfsent.3 \ + getfsent.3 setfstab.3 \ + getfsent.3 getfstab.3 +MLINKS+=getgrent.3 endgrent.3 \ + getgrent.3 getgrgid.3 \ + getgrent.3 getgrnam.3 \ + getgrent.3 setgrent.3 \ + getgrent.3 setgroupent.3 \ + getgrent.3 getgrent_r.3 \ + getgrent.3 getgrnam_r.3 \ + getgrent.3 getgrgid_r.3 +MLINKS+=gethostname.3 sethostname.3 +MLINKS+=getnetgrent.3 endnetgrent.3 \ + getnetgrent.3 getnetgrent_r.3 \ + getnetgrent.3 innetgr.3 \ + getnetgrent.3 setnetgrent.3 +MLINKS+=getprogname.3 setprogname.3 +MLINKS+=getpwent.3 endpwent.3 \ + getpwent.3 getpwnam.3 \ + getpwent.3 getpwuid.3 \ + getpwent.3 setpassent.3 \ + getpwent.3 setpwent.3 \ + getpwent.3 setpwfile.3 \ + getpwent.3 getpwent_r.3 \ + getpwent.3 getpwnam_r.3 \ + getpwent.3 getpwuid_r.3 +MLINKS+=getttyent.3 endttyent.3 \ + getttyent.3 getttynam.3 \ + getttyent.3 isdialuptty.3 \ + getttyent.3 isnettty.3 \ + getttyent.3 setttyent.3 +MLINKS+=getusershell.3 endusershell.3 \ + getusershell.3 setusershell.3 +MLINKS+=getutxent.3 endutxent.3 \ + getutxent.3 getutxid.3 \ + getutxent.3 getutxline.3 \ + getutxent.3 getutxuser.3 \ + getutxent.3 pututxline.3 \ + getutxent.3 setutxdb.3 \ + getutxent.3 setutxent.3 \ + getutxent.3 utmpx.3 +MLINKS+=glob.3 globfree.3 +MLINKS+=isgreater.3 isgreaterequal.3 \ + isgreater.3 isless.3 \ + isgreater.3 islessequal.3 \ + isgreater.3 islessgreater.3 \ + isgreater.3 isunordered.3 +MLINKS+=ldexp.3 ldexpf.3 \ + ldexp.3 ldexpl.3 +MLINKS+=makecontext.3 swapcontext.3 +MLINKS+=modf.3 modff.3 \ + modf.3 modfl.3 +MLINKS+=popen.3 pclose.3 +MLINKS+=posix_spawn.3 posix_spawnp.3 \ + posix_spawn_file_actions_addopen.3 posix_spawn_file_actions_addclose.3 \ + posix_spawn_file_actions_addopen.3 posix_spawn_file_actions_adddup2.3 \ + posix_spawn_file_actions_init.3 posix_spawn_file_actions_destroy.3 \ + posix_spawnattr_getflags.3 posix_spawnattr_setflags.3 \ + posix_spawnattr_getpgroup.3 posix_spawnattr_setpgroup.3 \ + posix_spawnattr_getschedparam.3 posix_spawnattr_setschedparam.3 \ + posix_spawnattr_getschedpolicy.3 posix_spawnattr_setschedpolicy.3 \ + posix_spawnattr_getsigdefault.3 posix_spawnattr_setsigdefault.3 \ + posix_spawnattr_getsigmask.3 posix_spawnattr_setsigmask.3 \ + posix_spawnattr_init.3 posix_spawnattr_destroy.3 +MLINKS+=psignal.3 strsignal.3 \ + psignal.3 sys_siglist.3 \ + psignal.3 sys_signame.3 +MLINKS+=pwcache.3 group_from_gid.3 \ + pwcache.3 user_from_uid.3 +MLINKS+=rand48.3 _rand48.3 \ + rand48.3 drand48.3 \ + rand48.3 erand48.3 \ + rand48.3 jrand48.3 \ + rand48.3 lcong48.3 \ + rand48.3 lrand48.3 \ + rand48.3 mrand48.3 \ + rand48.3 nrand48.3 \ + rand48.3 seed48.3 \ + rand48.3 srand48.3 +MLINKS+=recv.2 recvmmsg.2 +MLINKS+=scandir.3 alphasort.3 +MLINKS+=sem_open.3 sem_close.3 \ + sem_open.3 sem_unlink.3 +MLINKS+=sem_wait.3 sem_trywait.3 +MLINKS+=sem_timedwait.3 sem_clockwait_np.3 +MLINKS+=send.2 sendmmsg.2 +MLINKS+=setjmp.3 _longjmp.3 \ + setjmp.3 _setjmp.3 \ + setjmp.3 longjmp.3 \ + setjmp.3 longjmperr.3 \ + setjmp.3 longjmperror.3 \ + setjmp.3 siglongjmp.3 \ + setjmp.3 sigsetjmp.3 +MLINKS+=setmode.3 getmode.3 +MLINKS+=sigsetops.3 sigaddset.3 \ + sigsetops.3 sigdelset.3 \ + sigsetops.3 sigemptyset.3 \ + sigsetops.3 sigfillset.3 \ + sigsetops.3 sigismember.3 +MLINKS+=statvfs.3 fstatvfs.3 +MLINKS+=stringlist.3 sl_add.3 \ + stringlist.3 sl_find.3 \ + stringlist.3 sl_free.3 \ + stringlist.3 sl_init.3 +MLINKS+=strtofflags.3 fflagstostr.3 +MLINKS+=sysctl.3 sysctlbyname.3 \ + sysctl.3 sysctlnametomib.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 tcflow.3 \ + tcsendbreak.3 tcflush.3 +MLINKS+=tcsetattr.3 cfgetispeed.3 \ + tcsetattr.3 cfgetospeed.3 \ + tcsetattr.3 cfmakeraw.3 \ + tcsetattr.3 cfmakesane.3 \ + tcsetattr.3 cfsetispeed.3 \ + tcsetattr.3 cfsetospeed.3 \ + tcsetattr.3 cfsetspeed.3 \ + tcsetattr.3 tcgetattr.3 +MLINKS+=ttyname.3 isatty.3 \ + ttyname.3 ttyname_r.3 +MLINKS+=tzset.3 tzsetwall.3 +MLINKS+=unvis.3 strunvis.3 \ + unvis.3 strunvisx.3 +MLINKS+=vis.3 nvis.3 \ + vis.3 snvis.3 \ + vis.3 strenvisx.3 \ + vis.3 strnunvis.3 \ + vis.3 strnunvisx.3 \ + vis.3 strnvis.3 \ + vis.3 strnvisx.3 \ + vis.3 strsenvisx.3 \ + vis.3 strsnvis.3 \ + vis.3 strsnvisx.3 \ + vis.3 strsvis.3 \ + vis.3 strsvisx.3 \ + vis.3 strvis.3 \ + vis.3 strvisx.3 \ + vis.3 svis.3 + +MLINKS+=wordexp.3 wordfree.3 diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map new file mode 100644 index 0000000..cd4a40e --- /dev/null +++ b/lib/libc/gen/Symbol.map @@ -0,0 +1,551 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/gen/Symbol.map 319442 2017-06-01 16:03:01Z vangyzen $ + */ + +FBSD_1.0 { + __xuname; + pthread_atfork; + pthread_attr_destroy; + pthread_attr_getdetachstate; + pthread_attr_getguardsize; + pthread_attr_getinheritsched; + pthread_attr_getschedparam; + pthread_attr_getschedpolicy; + pthread_attr_getscope; + pthread_attr_getstackaddr; + pthread_attr_getstacksize; + pthread_attr_init; + pthread_attr_setdetachstate; + pthread_attr_setguardsize; + pthread_attr_setinheritsched; + pthread_attr_setschedparam; + pthread_attr_setschedpolicy; + pthread_attr_setscope; + pthread_attr_setstackaddr; + pthread_attr_setstacksize; + pthread_cancel; + pthread_cleanup_pop; + pthread_cleanup_push; + pthread_cond_broadcast; + pthread_cond_destroy; + pthread_cond_init; + pthread_cond_signal; + pthread_cond_timedwait; + pthread_cond_wait; + pthread_detach; + pthread_equal; + pthread_exit; + pthread_getspecific; + pthread_join; + pthread_key_create; + pthread_key_delete; + pthread_kill; + pthread_main_np; + pthread_mutex_destroy; + pthread_mutex_init; + pthread_mutex_lock; + pthread_mutex_trylock; + pthread_mutex_unlock; + pthread_mutexattr_destroy; + pthread_mutexattr_init; + pthread_mutexattr_settype; + pthread_once; + pthread_rwlock_destroy; + pthread_rwlock_init; + pthread_rwlock_rdlock; + pthread_rwlock_tryrdlock; + pthread_rwlock_trywrlock; + pthread_rwlock_unlock; + pthread_rwlock_wrlock; + pthread_self; + pthread_setcancelstate; + pthread_setcanceltype; + pthread_setspecific; + pthread_sigmask; + pthread_testcancel; + alarm; + arc4random; + arc4random_addrandom; + arc4random_stir; + __assert; + basename; + check_utility_compat; + clock; + closedir; + confstr; + encrypt; + des_setkey; + des_cipher; + setkey; + ctermid; + ctermid_r; + daemon; + devname; + devname_r; + dirname; + getdiskbyname; + dladdr; + dlclose; + dlerror; + dlfunc; + dllockinit; + dlopen; + dlsym; + dlvsym; + dlinfo; + dl_iterate_phdr; + drand48; + erand48; + err_set_file; + err_set_exit; + err; + verr; + errc; + verrc; + errx; + verrx; + warn; + vwarn; + warnc; + vwarnc; + warnx; + vwarnx; + sys_errlist; + sys_nerr; + errno; + execl; + execle; + execlp; + execv; + execvp; + execvP; + fmtcheck; + fmtmsg; + fnmatch; + __fpclassifyf; + __fpclassifyd; + __fpclassifyl; + frexp; + setfstab; + getfstab; + getfsent; + getfsspec; + getfsfile; + setfsent; + endfsent; + ftok; + ftw; + glob; + globfree; + getbootfile; + getbsize; + cgetset; + cgetcap; + cgetent; + cgetmatch; + cgetfirst; + cgetclose; + cgetnext; + cgetstr; + cgetustr; + cgetnum; + getcwd; + getdomainname; + setgrent; + setgroupent; + endgrent; + getgrent_r; + getgrnam_r; + getgrgid_r; + getgrnam; + getgrgid; + getgrent; + /* + * Why are __gr_parse_entry() and __gr_match_entry() not static in + * gen/getgrent.c? + */ + getgrouplist; + gethostname; + getloadavg; + getlogin; + getlogin_r; + getmntinfo; + setnetgrent; + getnetgrent; + endnetgrent; + innetgr; + getosreldate; + getpagesize; + getpeereid; + _getprogname; + getprogname; + setpwent; + setpassent; + endpwent; + getpwent_r; + getpwnam_r; + getpwuid_r; + getpwnam; + getpwuid; + getpwent; + getttynam; + getttyent; + setttyent; + endttyent; + isdialuptty; + isnettty; + getusershell; + endusershell; + setusershell; + getvfsbyname; + __isnan; + isnan; + __isnanf; + isnanf; + __isinf; + isinf; + __isinff; + __isinfl; + isatty; + initgroups; + jrand48; + lcong48; + ldexp; + lockf; + lrand48; + modf; + mrand48; + nftw; + nice; + nlist; + nrand48; + opendir; + pause; + posix_madvise; + popen; + pclose; + psignal; + raise; + readdir; + readdir_r; + readpassphrase; + getpass; + rewinddir; + scandir; + alphasort; + seed48; + seekdir; + user_from_uid; + group_from_gid; + setdomainname; + sethostname; + longjmperror; + getmode; + setmode; + setproctitle; + setprogname; + siginterrupt; + sys_signame; + sys_siglist; + sys_nsig; + signal; + sigaddset; + sigdelset; + sigemptyset; + sigfillset; + sigismember; + sleep; + srand48; + fstatvfs; + statvfs; + sl_init; + sl_add; + sl_free; + sl_find; + fflagstostr; + strtofflags; + sysconf; + sysctl; + sysctlbyname; + sysctlnametomib; + syslog; + vsyslog; + openlog; + closelog; + setlogmask; + ttyname_r; + ttyname; + timezone; + times; + time; + telldir; + tcgetattr; + tcsetattr; + tcsetpgrp; + tcgetpgrp; + cfgetospeed; + cfgetispeed; + cfsetospeed; + cfsetispeed; + cfsetspeed; + cfmakeraw; + tcsendbreak; + _init_tls; + __tls_get_addr; + tcdrain; + tcflush; + tcflow; + ualarm; + ulimit; + uname; + strunvis; + strunvisx; + usleep; + utime; + valloc; + vis; + strvis; + strvisx; + wait; + wait3; + waitpid; + wordexp; + wordfree; +}; + +FBSD_1.1 { + arc4random_buf; + arc4random_uniform; + fdevname; + fdevname_r; + fdopendir; + feature_present; + fts_children; + fts_close; + fts_get_clientptr; + fts_get_stream; + fts_open; + fts_read; + fts_set; + fts_set_clientptr; + posix_spawn; + posix_spawn_file_actions_addclose; + posix_spawn_file_actions_adddup2; + posix_spawn_file_actions_addopen; + posix_spawn_file_actions_destroy; + posix_spawn_file_actions_init; + posix_spawnattr_destroy; + posix_spawnattr_getflags; + posix_spawnattr_getpgroup; + posix_spawnattr_getschedparam; + posix_spawnattr_getschedpolicy; + posix_spawnattr_getsigdefault; + posix_spawnattr_getsigmask; + posix_spawnattr_init; + posix_spawnattr_setflags; + posix_spawnattr_setpgroup; + posix_spawnattr_setschedparam; + posix_spawnattr_setschedpolicy; + posix_spawnattr_setsigdefault; + posix_spawnattr_setsigmask; + posix_spawnp; + semctl; + tcgetsid; + tcsetsid; + __pthread_cleanup_pop_imp; + __pthread_cleanup_push_imp; +}; + +FBSD_1.2 { + basename_r; + cfmakesane; + endutxent; + getpagesizes; + getutxent; + getutxid; + getutxline; + getutxuser; + pututxline; + sem_close; + sem_destroy; + sem_getvalue; + sem_init; + sem_open; + sem_post; + sem_timedwait; + sem_trywait; + sem_unlink; + sem_wait; + setutxdb; + setutxent; +}; + +FBSD_1.3 { + clock_getcpuclockid; + dirfd; + dup3; + fdclosedir; + fdlopen; + __FreeBSD_libc_enter_restricted_mode; + getcontextx; + gid_from_group; + nvis; + pwcache_userdb; + pwcache_groupdb; + snvis; + strenvisx; + strnunvis; + strnunvisx; + strnvis; + strnvisx; + strsenvisx; + strsnvis; + strsnvisx; + strsvis; + strsvisx; + svis; + uid_from_user; + unvis; + waitid; +}; + +FBSD_1.4 { + getnetgrent_r; + pthread_mutex_consistent; + pthread_mutexattr_getrobust; + pthread_mutexattr_setrobust; + scandir_b; + stravis; +}; + +FBSD_1.5 { + sem_clockwait_np; +}; + +FBSDprivate_1.0 { + /* needed by thread libraries */ + __thr_jtable; + + _pthread_atfork; + _pthread_attr_destroy; + _pthread_attr_getdetachstate; + _pthread_attr_getguardsize; + _pthread_attr_getinheritsched; + _pthread_attr_getschedparam; + _pthread_attr_getschedpolicy; + _pthread_attr_getscope; + _pthread_attr_getstackaddr; + _pthread_attr_getstacksize; + _pthread_attr_init; + _pthread_attr_setdetachstate; + _pthread_attr_setguardsize; + _pthread_attr_setinheritsched; + _pthread_attr_setschedparam; + _pthread_attr_setschedpolicy; + _pthread_attr_setscope; + _pthread_attr_setstackaddr; + _pthread_attr_setstacksize; + _pthread_cancel; + _pthread_cancel_enter; + _pthread_cancel_leave; + _pthread_cleanup_pop; + _pthread_cleanup_push; + _pthread_cond_broadcast; + _pthread_cond_destroy; + _pthread_cond_init; + _pthread_cond_signal; + _pthread_cond_timedwait; + _pthread_cond_wait; + _pthread_detach; + _pthread_equal; + _pthread_exit; + _pthread_getspecific; + _pthread_join; + _pthread_key_create; + _pthread_key_delete; + _pthread_kill; + _pthread_main_np; + _pthread_mutex_destroy; + _pthread_mutex_init_calloc_cb; + _pthread_mutex_init; + _pthread_mutex_lock; + _pthread_mutex_trylock; + _pthread_mutex_unlock; + _pthread_mutexattr_destroy; + _pthread_mutexattr_init; + _pthread_mutexattr_settype; + _pthread_once; + _pthread_rwlock_destroy; + _pthread_rwlock_init; + _pthread_rwlock_rdlock; + _pthread_rwlock_tryrdlock; + _pthread_rwlock_trywrlock; + _pthread_rwlock_unlock; + _pthread_rwlock_wrlock; + _pthread_self; + _pthread_setcancelstate; + _pthread_setcanceltype; + _pthread_setspecific; + _pthread_sigmask; + _pthread_testcancel; + _spinlock; + _spinunlock; + _rtld_addr_phdr; + _rtld_atfork_pre; + _rtld_atfork_post; + _rtld_error; /* for private use */ + _rtld_get_stack_prot; + _rtld_is_dlopened; + _rtld_thread_init; /* for private use */ + __elf_phdr_match_addr; + _err; + _warn; + __fmtcheck; + /* __pw_match_entry; */ + /* __pw_parse_entry; */ + __fdnlist; /* used by libkvm */ + /* __aout_fdnlist; */ + /* __elf_is_okay__; */ + /* __elf_fdnlist; */ + __opendir2; + __pause; + _pause; + __pw_scan; /* Used by (at least) libutil */ + __raise; + _raise; + __sleep; + _sleep; + _rtld_allocate_tls; + _rtld_free_tls; +#if defined(i386) + ___libc_tls_get_addr; /* x86 only */ +#endif + __libc_tls_get_addr; + __tcdrain; + _tcdrain; + __usleep; + _usleep; + __wait; + _wait; + __waitpid; + _waitpid; + + _libc_sem_init_compat; + _libc_sem_destroy_compat; + _libc_sem_open_compat; + _libc_sem_close_compat; + _libc_sem_unlink_compat; + _libc_sem_wait_compat; + _libc_sem_trywait_compat; + _libc_sem_timedwait_compat; + _libc_sem_post_compat; + _libc_sem_getvalue_compat; + + __libc_tcdrain; + + __elf_aux_vector; + __pthread_map_stacks_exec; + __fillcontextx; + __fillcontextx2; + __getcontextx_size; +}; diff --git a/lib/libc/gen/__getosreldate.c b/lib/libc/gen/__getosreldate.c new file mode 100644 index 0000000..8d4e243 --- /dev/null +++ b/lib/libc/gen/__getosreldate.c @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2007 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/__getosreldate.c 211416 2010-08-17 09:13:26Z kib $"); + +#include +#include +#include +#include +#include "libc_private.h" + +int __getosreldate(void); + +/* + * This is private to libc. It is intended for wrapping syscall stubs in order + * to avoid having to put SIGSYS signal handlers in place to test for presence + * of new syscalls. This caches the result in order to be as quick as possible. + * + * Use getosreldate(3) for public use as it respects the $OSVERSION environment + * variable. + */ + +int +__getosreldate(void) +{ + static int osreldate; + size_t len; + int oid[2]; + int error, osrel; + + if (osreldate != 0) + return (osreldate); + + error = _elf_aux_info(AT_OSRELDATE, &osreldate, sizeof(osreldate)); + if (error == 0 && osreldate != 0) + return (osreldate); + + oid[0] = CTL_KERN; + oid[1] = KERN_OSRELDATE; + osrel = 0; + len = sizeof(osrel); + error = sysctl(oid, 2, &osrel, &len, NULL, 0); + if (error == 0 && osrel > 0 && len == sizeof(osrel)) + osreldate = osrel; + return (osreldate); +} diff --git a/lib/libc/gen/__pthread_mutex_init_calloc_cb_stub.c b/lib/libc/gen/__pthread_mutex_init_calloc_cb_stub.c new file mode 100644 index 0000000..64e8a92 --- /dev/null +++ b/lib/libc/gen/__pthread_mutex_init_calloc_cb_stub.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014 The FreeBSD Foundation. + * All rights reserved. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + * 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(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/__pthread_mutex_init_calloc_cb_stub.c 276630 2015-01-03 18:38:46Z kib $"); + +#include +#include "libc_private.h" + +int +_pthread_mutex_init_calloc_cb_stub(pthread_mutex_t *mutex, + void *(calloc_cb)(size_t, size_t)) +{ + + return (0); +} diff --git a/lib/libc/gen/_once_stub.c b/lib/libc/gen/_once_stub.c new file mode 100644 index 0000000..87b6cce --- /dev/null +++ b/lib/libc/gen/_once_stub.c @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2009 Hudson River Trading LLC + * Written by: John H. Baldwin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/_once_stub.c 281887 2015-04-23 14:22:20Z jhb $"); + +#include "namespace.h" +#include +#include "un-namespace.h" +#include "libc_private.h" + +/* This implements pthread_once() for the single-threaded case. */ +static int +_libc_once(pthread_once_t *once_control, void (*init_routine)(void)) +{ + + if (once_control->state == PTHREAD_DONE_INIT) + return (0); + init_routine(); + once_control->state = PTHREAD_DONE_INIT; + return (0); +} + +/* + * This is the internal interface provided to libc. It will use + * pthread_once() from the threading library in a multi-threaded + * process and _libc_once() for a single-threaded library. Because + * _libc_once() uses the same ABI for the values in the pthread_once_t + * structure as the threading library, it is safe for a process to + * switch from _libc_once() to pthread_once() when threading is + * enabled. + */ +int +_once(pthread_once_t *once_control, void (*init_routine)(void)) +{ + + if (__isthreaded) + return (_pthread_once(once_control, init_routine)); + return (_libc_once(once_control, init_routine)); +} diff --git a/lib/libc/gen/alarm.3 b/lib/libc/gen/alarm.3 new file mode 100644 index 0000000..e73fde7 --- /dev/null +++ b/lib/libc/gen/alarm.3 @@ -0,0 +1,93 @@ +.\" Copyright (c) 1980, 1991, 1993, 1994 +.\" 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. +.\" 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. +.\" +.\" @(#)alarm.3 8.2 (Berkeley) 4/19/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/alarm.3 207735 2010-05-06 22:49:54Z jilles $ +.\" +.Dd April 19, 1994 +.Dt ALARM 3 +.Os +.Sh NAME +.Nm alarm +.Nd set signal timer alarm +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft unsigned int +.Fn alarm "unsigned int seconds" +.Sh DESCRIPTION +.Bf -symbolic +This interface is made obsolete by +.Xr setitimer 2 . +.Ef +.Pp +The +.Fn alarm +function sets a timer to deliver the signal +.Dv SIGALRM +to the calling process after the specified number of +.Fa seconds . +If an alarm has already been set with +.Fn alarm +but has not been delivered, another call to +.Fn alarm +will supersede the prior call. +The request +.Fn alarm "0" +voids the current +alarm and the signal SIGALRM will not be delivered. +.Pp +Due to +.Xr setitimer 2 +restriction the maximum number of +.Fa seconds +allowed is 100000000. +.Sh RETURN VALUES +The return value of +.Fn alarm +is the amount of time left on the timer from a previous call to +.Fn alarm . +If no alarm is currently set, the return value is 0. +.Sh SEE ALSO +.Xr setitimer 2 , +.Xr sigaction 2 , +.Xr sigsuspend 2 , +.Xr signal 3 , +.Xr sleep 3 , +.Xr ualarm 3 , +.Xr usleep 3 +.\" .Sh STANDARDS +.\" The +.\" .Fn alarm +.\" function conforms to +.\" .St -p1003.1-90 . +.Sh HISTORY +An +.Fn alarm +function appeared in +.At v7 . diff --git a/lib/libc/gen/arc4random.3 b/lib/libc/gen/arc4random.3 new file mode 100644 index 0000000..c689724 --- /dev/null +++ b/lib/libc/gen/arc4random.3 @@ -0,0 +1,127 @@ +.\" $OpenBSD: arc4random.3,v 1.2 1997/04/27 22:40:25 angelos Exp $ +.\" Copyright 1997 Niels Provos +.\" 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 Niels Provos. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +.\" +.\" Manual page, using -mandoc macros +.\" $FreeBSD: releng/11.1/lib/libc/gen/arc4random.3 231564 2012-02-12 18:29:56Z ed $ +.\" +.Dd April 15, 1997 +.Dt ARC4RANDOM 3 +.Os +.Sh NAME +.Nm arc4random , +.Nm arc4random_buf , +.Nm arc4random_uniform , +.Nm arc4random_stir , +.Nm arc4random_addrandom +.Nd arc4 random number generator +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft uint32_t +.Fn arc4random "void" +.Ft void +.Fn arc4random_buf "void *buf" "size_t nbytes" +.Ft uint32_t +.Fn arc4random_uniform "uint32_t upper_bound" +.Ft void +.Fn arc4random_stir "void" +.Ft void +.Fn arc4random_addrandom "unsigned char *dat" "int datlen" +.Sh DESCRIPTION +The +.Fn arc4random +function uses the key stream generator employed by the +arc4 cipher, which uses 8*8 8 bit S-Boxes. +The S-Boxes +can be in about +.if t 2\u\s71700\s10\d +.if n (2**1700) +states. +The +.Fn arc4random +function returns pseudo-random numbers in the range of 0 to +.if t 2\u\s731\s10\d\(mi1, +.if n (2**32)\(mi1, +and therefore has twice the range of +.Xr rand 3 +and +.Xr random 3 . +.Pp +.Fn arc4random_buf +function fills the region +.Fa buf +of length +.Fa nbytes +with ARC4-derived random data. +.Pp +.Fn arc4random_uniform +will return a uniformly distributed random number less than +.Fa upper_bound . +.Fn arc4random_uniform +is recommended over constructions like +.Dq Li arc4random() % upper_bound +as it avoids "modulo bias" when the upper bound is not a power of two. +.Pp +The +.Fn arc4random_stir +function reads data from +.Pa /dev/urandom +and uses it to permute the S-Boxes via +.Fn arc4random_addrandom . +.Pp +There is no need to call +.Fn arc4random_stir +before using +.Fn arc4random +functions family, since +they automatically initialize themselves. +.Sh EXAMPLES +The following produces a drop-in replacement for the traditional +.Fn rand +and +.Fn random +functions using +.Fn arc4random : +.Pp +.Dl "#define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1))" +.Sh SEE ALSO +.Xr rand 3 , +.Xr random 3 , +.Xr srandomdev 3 +.Sh HISTORY +.Pa RC4 +has been designed by RSA Data Security, Inc. +It was posted anonymously +to the USENET and was confirmed to be equivalent by several sources who +had access to the original cipher. +Since +.Pa RC4 +used to be a trade secret, the cipher is now referred to as +.Pa ARC4 . diff --git a/lib/libc/gen/auxv.c b/lib/libc/gen/auxv.c new file mode 100644 index 0000000..e825e98 --- /dev/null +++ b/lib/libc/gen/auxv.c @@ -0,0 +1,186 @@ +/*- + * Copyright 2010, 2012 Konstantin Belousov . + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/auxv.c 239193 2012-08-11 12:07:24Z ed $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" + +extern char **environ; +extern int _DYNAMIC; +#pragma weak _DYNAMIC + +void *__elf_aux_vector; +static pthread_once_t aux_vector_once = PTHREAD_ONCE_INIT; + +static void +init_aux_vector_once(void) +{ + Elf_Addr *sp; + + sp = (Elf_Addr *)environ; + while (*sp++ != 0) + ; + __elf_aux_vector = (Elf_Auxinfo *)sp; +} + +void +__init_elf_aux_vector(void) +{ + + if (&_DYNAMIC != NULL) + return; + _once(&aux_vector_once, init_aux_vector_once); +} + +static pthread_once_t aux_once = PTHREAD_ONCE_INIT; +static int pagesize, osreldate, canary_len, ncpus, pagesizes_len; +static char *canary, *pagesizes; +static void *timekeep; + +static void +init_aux(void) +{ + Elf_Auxinfo *aux; + + for (aux = __elf_aux_vector; aux->a_type != AT_NULL; aux++) { + switch (aux->a_type) { + case AT_CANARY: + canary = (char *)(aux->a_un.a_ptr); + break; + + case AT_CANARYLEN: + canary_len = aux->a_un.a_val; + break; + + case AT_PAGESIZES: + pagesizes = (char *)(aux->a_un.a_ptr); + break; + + case AT_PAGESIZESLEN: + pagesizes_len = aux->a_un.a_val; + break; + + case AT_PAGESZ: + pagesize = aux->a_un.a_val; + break; + + case AT_OSRELDATE: + osreldate = aux->a_un.a_val; + break; + + case AT_NCPUS: + ncpus = aux->a_un.a_val; + break; + + case AT_TIMEKEEP: + timekeep = aux->a_un.a_ptr; + break; + } + } +} + +int +_elf_aux_info(int aux, void *buf, int buflen) +{ + int res; + + __init_elf_aux_vector(); + if (__elf_aux_vector == NULL) + return (ENOSYS); + _once(&aux_once, init_aux); + + switch (aux) { + case AT_CANARY: + if (canary != NULL && canary_len >= buflen) { + memcpy(buf, canary, buflen); + memset(canary, 0, canary_len); + canary = NULL; + res = 0; + } else + res = ENOENT; + break; + case AT_PAGESIZES: + if (pagesizes != NULL && pagesizes_len >= buflen) { + memcpy(buf, pagesizes, buflen); + res = 0; + } else + res = ENOENT; + break; + + case AT_PAGESZ: + if (buflen == sizeof(int)) { + if (pagesize != 0) { + *(int *)buf = pagesize; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; + case AT_OSRELDATE: + if (buflen == sizeof(int)) { + if (osreldate != 0) { + *(int *)buf = osreldate; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; + case AT_NCPUS: + if (buflen == sizeof(int)) { + if (ncpus != 0) { + *(int *)buf = ncpus; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; + case AT_TIMEKEEP: + if (buflen == sizeof(void *)) { + if (timekeep != NULL) { + *(void **)buf = timekeep; + res = 0; + } else + res = ENOENT; + } else + res = EINVAL; + break; + default: + res = ENOENT; + break; + } + return (res); +} diff --git a/lib/libc/gen/basename.3 b/lib/libc/gen/basename.3 new file mode 100644 index 0000000..3c75726 --- /dev/null +++ b/lib/libc/gen/basename.3 @@ -0,0 +1,121 @@ +.\" $OpenBSD: basename.3,v 1.20 2007/05/31 19:19:28 jmc Exp $ +.\" +.\" Copyright (c) 1997 Todd C. Miller +.\" +.\" 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/basename.3 303762 2016-08-05 05:50:27Z ed $ +.\" +.Dd July 29, 2016 +.Dt BASENAME 3 +.Os +.Sh NAME +.Nm basename +.Nd extract the base portion of a pathname +.Sh SYNOPSIS +.In libgen.h +.Ft char * +.Fn basename "const char *path" +.Ft char * +.Fn basename_r "const char *path" "char *bname" +.Sh DESCRIPTION +The +.Fn basename +function returns the last component from the pathname pointed to by +.Fa path , +deleting any trailing +.Sq \&/ +characters. +If +.Fa path +consists entirely of +.Sq \&/ +characters, a pointer to the string +.Qq \&/ +is returned. +If +.Fa path +is a null pointer or the empty string, a pointer to the string +.Qq \&. +is returned. +.Pp +The +.Fn basename_r +variation accepts a buffer of at least +.Dv MAXPATHLEN +bytes in which to store the resulting component. +.Sh IMPLEMENTATION NOTES +The +.Fn basename +function +returns a pointer to internal storage space allocated on the first call +that will be overwritten +by subsequent calls. +.Pp +Other vendor implementations of +.Fn basename +may store their result in the input buffer, +making it safe to use in multithreaded applications. +Future versions of +.Fx +will follow this approach as well. +.Fn basename_r +will then become obsolete. +.Sh RETURN VALUES +On successful completion, +.Fn basename +and +.Fn basename_r +return pointers to the last component of +.Fa path . +.Pp +If they fail, a null pointer is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The following error codes may be set in +.Va errno : +.Bl -tag -width Er +.It Bq Er ENAMETOOLONG +The path component to be returned was larger than +.Dv MAXPATHLEN . +.El +.Sh SEE ALSO +.Xr basename 1 , +.Xr dirname 1 , +.Xr dirname 3 +.Sh STANDARDS +The +.Fn basename +function conforms to +.St -xpg4.2 . +.Sh HISTORY +The +.Fn basename +function first appeared in +.Ox 2.2 +and +.Fx 4.2 . +.Sh AUTHORS +.An Todd C. Miller +.Sh CAVEATS +.Fn basename +returns a pointer to internal static storage space that will be overwritten +by subsequent calls. +.Pp +Other vendor implementations of +.Fn basename +may modify the contents of the string passed to +.Fn basename ; +this should be taken into account when writing code which calls this function +if portability is desired. diff --git a/lib/libc/gen/cap_rights_get.3 b/lib/libc/gen/cap_rights_get.3 new file mode 100644 index 0000000..878f5e2 --- /dev/null +++ b/lib/libc/gen/cap_rights_get.3 @@ -0,0 +1,119 @@ +.\" +.\" Copyright (c) 2013 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by Pawel Jakub Dawidek under sponsorship +.\" from the FreeBSD Foundation. +.\" +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/cap_rights_get.3 276006 2014-12-21 12:36:36Z brueffer $ +.\" +.Dd March 27, 2014 +.Dt CAP_RIGHTS_GET 3 +.Os +.Sh NAME +.Nm cap_rights_get +.Nd obtain capability rights +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/capsicum.h +.Ft int +.Fn cap_rights_get "int fd" "cap_rights_t *rights" +.Sh DESCRIPTION +The +.Nm cap_rights_get +function allows to obtain current capability rights for the given descriptor. +The function will fill the +.Fa rights +argument with all capability rights if they were not limited or capability +rights configured during the last successful call of +.Xr cap_rights_limit 2 +on the given descriptor. +.Pp +The +.Fa rights +argument can be inspected using +.Xr cap_rights_init 3 +family of functions. +.Pp +The complete list of the capability rights can be found in the +.Xr rights 4 +manual page. +.Sh RETURN VALUES +.Rv -std +.Sh EXAMPLES +The following example demonstrates how to limit file descriptor capability +rights and how to obtain them. +.Bd -literal +cap_rights_t setrights, getrights; +int fd; + +memset(&setrights, 0, sizeof(setrights)); +memset(&getrights, 0, sizeof(getrights)); + +fd = open("/tmp/foo", O_RDONLY); +if (fd < 0) + err(1, "open() failed"); + +cap_rights_init(&setrights, CAP_FSTAT, CAP_READ); +if (cap_rights_limit(fd, &setrights) < 0 && errno != ENOSYS) + err(1, "cap_rights_limit() failed"); + +if (cap_rights_get(fd, &getrights) < 0 && errno != ENOSYS) + err(1, "cap_rights_get() failed"); + +assert(memcmp(&setrights, &getrights, sizeof(setrights)) == 0); +.Ed +.Sh ERRORS +.Fn cap_rights_get +succeeds unless: +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa fd +argument is not a valid active descriptor. +.It Bq Er EFAULT +The +.Fa rights +argument points at an invalid address. +.El +.Sh SEE ALSO +.Xr cap_rights_limit 2 , +.Xr errno 2 , +.Xr open 2 , +.Xr assert 3 , +.Xr cap_rights_init 3 , +.Xr err 3 , +.Xr memcmp 3 , +.Xr memset 3 , +.Xr capsicum 4 , +.Xr rights 4 +.Sh HISTORY +Support for capabilities and capabilities mode was developed as part of the +.Tn TrustedBSD +Project. +.Sh AUTHORS +This function was created by +.An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net +under sponsorship of the FreeBSD Foundation. diff --git a/lib/libc/gen/cap_sandboxed.3 b/lib/libc/gen/cap_sandboxed.3 new file mode 100644 index 0000000..0665199 --- /dev/null +++ b/lib/libc/gen/cap_sandboxed.3 @@ -0,0 +1,71 @@ +.\" +.\" Copyright (c) 2012 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by Pawel Jakub Dawidek under sponsorship +.\" from the FreeBSD Foundation. +.\" +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/cap_sandboxed.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.Dd March 27, 2014 +.Dt CAP_SANDBOXED 3 +.Os +.Sh NAME +.Nm cap_sandboxed +.Nd Check if in a capability mode sandbox +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/capsicum.h +.In stdbool.h +.Ft bool +.Fn cap_sandboxed "void" +.Sh DESCRIPTION +.Fn cap_sandboxed +returns +.Va true +if the process is in a capability mode sandbox or +.Va false +if it is not. +This function is a more handy alternative to the +.Xr cap_getmode 2 +system call as it always succeeds, so there is no need for error checking. +If the support for capability mode is not compiled into the kernel, +.Fn cap_sandboxed +will always return +.Va false . +.Sh RETURN VALUES +Function +.Fn cap_sandboxed +is always successful and will return either +.Va true +or +.Va false . +.Sh SEE ALSO +.Xr cap_enter 2 , +.Xr capsicum 4 +.Sh AUTHORS +This function was implemented and manual page was written by +.An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net +under sponsorship of the FreeBSD Foundation. diff --git a/lib/libc/gen/cap_sandboxed.c b/lib/libc/gen/cap_sandboxed.c new file mode 100644 index 0000000..8e72425 --- /dev/null +++ b/lib/libc/gen/cap_sandboxed.c @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 AUTHORS 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/cap_sandboxed.c 263234 2014-03-16 11:04:44Z rwatson $"); + +#include + +#include +#include +#include + +bool +cap_sandboxed(void) +{ + u_int mode; + + if (cap_getmode(&mode) != 0) { + assert(errno == ENOSYS); + return (false); + } + assert(mode == 0 || mode == 1); + return (mode == 1); +} diff --git a/lib/libc/gen/check_utility_compat.3 b/lib/libc/gen/check_utility_compat.3 new file mode 100644 index 0000000..9b577e4 --- /dev/null +++ b/lib/libc/gen/check_utility_compat.3 @@ -0,0 +1,89 @@ +.\" +.\" Copyright 2002 Massachusetts Institute of Technology +.\" +.\" Permission to use, copy, modify, and distribute this software and +.\" its documentation for any purpose and without fee is hereby +.\" granted, provided that both the above copyright notice and this +.\" permission notice appear in all copies, that both the above +.\" copyright notice and this permission notice appear in all +.\" supporting documentation, and that the name of M.I.T. not be used +.\" in advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. M.I.T. makes +.\" no representations about the suitability of this software for any +.\" purpose. It is provided "as is" without express or implied +.\" warranty. +.\" +.\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS +.\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, +.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT +.\" SHALL M.I.T. 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/check_utility_compat.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.Dd October 27, 2002 +.Dt CHECK_UTILITY_COMPAT 3 +.Os +.Sh NAME +.Nm check_utility_compat +.Nd "determine whether a utility should be compatible" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn check_utility_compat "const char *utility" +.Sh DESCRIPTION +The +.Fn check_utility_compat +function checks whether +.Fa utility +should behave in a traditional +.Pq Fx 4.7 Ns -compatible +manner, or in accordance with +.St -p1003.1-2001 . +The configuration is given as a comma-separated list of utility names; +if the list is present but empty, all supported utilities assume their +most compatible mode. +The +.Fn check_utility_compat +function first checks for an environment variable named +.Ev _COMPAT_FreeBSD_4 . +If that environment variable does not exist, then +.Fn check_utility_compat +will attempt to read the contents of a symbolic link named +.Pa /etc/compat-FreeBSD-4-util . +If no configuration is found, compatibility mode is disabled. +.Sh RETURN VALUES +The +.Fn check_utility_compat +function returns zero if +.Fa utility +should implement strict +.St -p1003.1-2001 +behavior, and nonzero otherwise. +.Sh FILES +.Bl -tag -width ".Pa /etc/compat-FreeBSD-4-util" +.It Pa /etc/compat-FreeBSD-4-util +If present, a symbolic link whose expansion gives system-wide default settings +for the +.Fn check_utility_compat +function. +.El +.Sh ERRORS +No errors are detected. +.Sh HISTORY +The +.Fn check_utility_compat +function first appeared in +.Fx 5.0 . +.Sh AUTHORS +This manual page was written by +.An Garrett Wollman Aq Mt wollman@FreeBSD.org . diff --git a/lib/libc/gen/clock.3 b/lib/libc/gen/clock.3 new file mode 100644 index 0000000..61205b2 --- /dev/null +++ b/lib/libc/gen/clock.3 @@ -0,0 +1,76 @@ +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)clock.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/clock.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 4, 1993 +.Dt CLOCK 3 +.Os +.Sh NAME +.Nm clock +.Nd determine processor time used +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In time.h +.Ft clock_t +.Fn clock void +.Sh DESCRIPTION +The +.Fn clock +function +determines the amount of processor time used since the invocation of the +calling process, measured in +.Dv CLOCKS_PER_SEC Ns s +of a second. +.Sh RETURN VALUES +The +.Fn clock +function returns the amount of time used unless an error occurs, in which +case the return value is \-1. +.Sh SEE ALSO +.Xr getrusage 2 , +.Xr clocks 7 +.Sh STANDARDS +The +.Fn clock +function conforms to +.St -isoC . +However, +.St -susv2 +requires +.Dv CLOCKS_PER_SEC +to be defined as one million. +.Fx +does not conform to this requirement; +changing the value would introduce binary incompatibility +and one million is still inadequate on modern processors. diff --git a/lib/libc/gen/clock_getcpuclockid.3 b/lib/libc/gen/clock_getcpuclockid.3 new file mode 100644 index 0000000..90f2014 --- /dev/null +++ b/lib/libc/gen/clock_getcpuclockid.3 @@ -0,0 +1,95 @@ +.\" Copyright (c) 2012 David Xu +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/clock_getcpuclockid.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.Dd August 21, 2012 +.Dt CLOCK_GETCPUCLOCKID 3 +.Os +.Sh NAME +.Nm clock_getcpuclockid +.Nd access a process CPU-time clock +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In time.h +.Ft int +.Fn clock_getcpuclockid "pid_t pid" "clockid_t *clock_id" +.Sh DESCRIPTION +The +.Fn clock_getcpuclockid +returns the clock ID of the CPU-time clock of the process specified by +.Fa pid . +If the process described by +.Fa pid +exists and the calling process has permission, the clock ID of this +clock will be returned in +.Fa clock_id . +.Pp +If +.Fa pid +is zero, the +.Fn clock_getcpuclockid +function returns the clock ID of the CPU-time clock of the process +making the call, in +.Fa clock_id . +.Sh RETURN VALUES +Upon successful completion, +.Fn clock_getcpuclockid +returns zero; otherwise, an error number is returned to indicate the +error. +.Sh ERRORS +The clock_getcpuclockid() function will fail if: +.Bl -tag -width Er +.It Bq Er EPERM +The requesting process does not have permission to access the CPU-time +clock for the process. +.It Bq Er ESRCH +No process can be found corresponding to the process specified by +.Fa pid . +.El +.Sh SEE ALSO +.Xr clock_gettime 2 +.Sh STANDARDS +The +.Fn clock_getcpuclockid +function conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn clock_getcpuclockid +function first appeared in +.Fx 10.0 . +.Sh AUTHORS +.An David Xu Aq Mt davidxu@FreeBSD.org diff --git a/lib/libc/gen/clock_getcpuclockid.c b/lib/libc/gen/clock_getcpuclockid.c new file mode 100644 index 0000000..74192c8 --- /dev/null +++ b/lib/libc/gen/clock_getcpuclockid.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012 David Xu . + * 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. + * + * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/clock_getcpuclockid.c 239485 2012-08-21 09:17:13Z davidxu $"); + +#include +#include +#include +#include + +int +clock_getcpuclockid(pid_t pid, clockid_t *clock_id) +{ + if (clock_getcpuclockid2(pid, CPUCLOCK_WHICH_PID, clock_id)) + return (errno); + return (0); +} diff --git a/lib/libc/gen/confstr.3 b/lib/libc/gen/confstr.3 new file mode 100644 index 0000000..3d86bb1 --- /dev/null +++ b/lib/libc/gen/confstr.3 @@ -0,0 +1,129 @@ +.\" 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 +.\" 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. +.\" 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. +.\" +.\" @(#)confstr.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/confstr.3 213573 2010-10-08 12:40:16Z uqs $ +.\" +.Dd December 3, 2006 +.Dt CONFSTR 3 +.Os +.Sh NAME +.Nm confstr +.Nd get string-valued configurable variables +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft size_t +.Fn confstr "int name" "char *buf" "size_t len" +.Sh DESCRIPTION +This interface is specified by +.St -p1003.1-2001 . +A more flexible (but non-portable) interface is provided by +.Xr sysctl 3 . +.Pp +The +.Fn confstr +function provides a method for applications to get configuration +defined string values. +Shell programmers needing access to these parameters should use the +.Xr getconf 1 +utility. +.Pp +The +.Fa name +argument specifies the system variable to be queried. +Symbolic constants for each name value are found in the include file +.In unistd.h . +The +.Fa len +argument specifies the size of the buffer referenced by the +argument +.Fa buf . +If +.Fa len +is non-zero, +.Fa buf +is a non-null pointer, and +.Fa name +has a value, up to +.Fa len +\- 1 bytes of the value are copied into the buffer +.Fa buf . +The copied value is always null terminated. +.Pp +The available values are as follows: +.Bl -tag -width 6n +.It Li _CS_PATH +Return a value for the +.Ev PATH +environment variable that finds all the standard utilities. +.El +.Sh RETURN VALUES +If the call to +.Fn confstr +is not successful, 0 is returned and +.Va errno +is set appropriately. +Otherwise, if the variable does not have a configuration defined value, +0 is returned and +.Va errno +is not modified. +Otherwise, the buffer size needed to hold the entire configuration-defined +value is returned. +If this size is greater than the argument +.Fa len , +the string in +.Fa buf +was truncated. +.Sh ERRORS +The +.Fn confstr +function may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr malloc 3 +and +.Xr sysctl 3 . +.Pp +In addition, the following errors may be reported: +.Bl -tag -width Er +.It Bq Er EINVAL +The value of the +.Fa name +argument is invalid. +.El +.Sh SEE ALSO +.Xr getconf 1 , +.Xr pathconf 2 , +.Xr sysconf 3 , +.Xr sysctl 3 +.Sh HISTORY +The +.Fn confstr +function first appeared in +.Bx 4.4 . diff --git a/lib/libc/gen/ctermid.3 b/lib/libc/gen/ctermid.3 new file mode 100644 index 0000000..d1d4127 --- /dev/null +++ b/lib/libc/gen/ctermid.3 @@ -0,0 +1,108 @@ +.\" Copyright (c) 1990, 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. +.\" 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. +.\" +.\" @(#)ctermid.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/ctermid.3 225897 2011-10-01 12:19:48Z ed $ +.\" +.Dd October 1, 2011 +.Dt CTERMID 3 +.Os +.Sh NAME +.Nm ctermid +.Nd generate terminal pathname +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft char * +.Fn ctermid "char *buf" +.Ft char * +.Fn ctermid_r "char *buf" +.Sh DESCRIPTION +The +.Fn ctermid +function generates a string, that, when used as a pathname, refers to +the current controlling terminal of the calling process. +.Pp +If +.Fa buf +is the +.Dv NULL +pointer, a pointer to a static area is returned. +Otherwise, the pathname is copied into the memory referenced by +.Fa buf . +The argument +.Fa buf +is assumed to be at least +.Dv L_ctermid +(as defined in the include +file +.In stdio.h ) +bytes long. +.Pp +The +.Fn ctermid_r +function +provides the same functionality as +.Fn ctermid +except that if +.Fa buf +is a +.Dv NULL +pointer, +.Dv NULL +is returned. +.Pp +If no suitable lookup of the controlling terminal name can be performed, +this implementation returns +.Ql /dev/tty . +.Sh RETURN VALUES +Upon successful completion, a +.Pf non- Dv NULL +pointer is returned. +Otherwise, a +.Dv NULL +pointer is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The current implementation detects no error conditions. +.Sh SEE ALSO +.Xr ttyname 3 +.Sh STANDARDS +The +.Fn ctermid +function conforms to +.St -p1003.1-88 . +.Sh BUGS +By default the +.Fn ctermid +function +writes all information to an internal static object. +Subsequent calls to +.Fn ctermid +will modify the same object. diff --git a/lib/libc/gen/daemon.3 b/lib/libc/gen/daemon.3 new file mode 100644 index 0000000..f694a44 --- /dev/null +++ b/lib/libc/gen/daemon.3 @@ -0,0 +1,112 @@ +.\" 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 +.\" 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. +.\" 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. +.\" +.\" @(#)daemon.3 8.1 (Berkeley) 6/9/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/daemon.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 9, 1993 +.Dt DAEMON 3 +.Os +.Sh NAME +.Nm daemon +.Nd run in the background +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fn daemon "int nochdir" "int noclose" +.Sh DESCRIPTION +The +.Fn daemon +function is for programs wishing to detach themselves from the +controlling terminal and run in the background as system daemons. +.Pp +Unless the argument +.Fa nochdir +is non-zero, +.Fn daemon +changes the current working directory to the root +.Pq Pa / . +.Pp +Unless the argument +.Fa noclose +is non-zero, +.Fn daemon +will redirect standard input, standard output, and standard error to +.Pa /dev/null . +.Sh RETURN VALUES +.Rv -std daemon +.Sh ERRORS +The +.Fn daemon +function may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr fork 2 +and +.Xr setsid 2 . +.Sh SEE ALSO +.Xr fork 2 , +.Xr setsid 2 , +.Xr sigaction 2 +.Sh HISTORY +The +.Fn daemon +function first appeared in +.Bx 4.4 . +.Sh CAVEATS +Unless the +.Fa noclose +argument is non-zero, +.Fn daemon +will close the first three file descriptors and redirect them to +.Pa /dev/null . +Normally, these correspond to standard input, standard output, and +standard error. +However, if any of those file descriptors refer to something else, they +will still be closed, resulting in incorrect behavior of the calling program. +This can happen if any of standard input, standard output, or standard +error have been closed before the program was run. +Programs using +.Fn daemon +should therefore either call +.Fn daemon +before opening any files or sockets, or verify that any file +descriptors obtained have values greater than 2. +.Pp +The +.Fn daemon +function temporarily ignores +.Dv SIGHUP +while calling +.Xr setsid 2 +to prevent a parent session group leader's calls to +.Xr fork 2 +and then +.Xr _exit 2 +from prematurely terminating the child process. diff --git a/lib/libc/gen/devname.3 b/lib/libc/gen/devname.3 new file mode 100644 index 0000000..d87ffcb --- /dev/null +++ b/lib/libc/gen/devname.3 @@ -0,0 +1,115 @@ +.\" 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 +.\" 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. +.\" 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. +.\" +.\" @(#)devname.3 8.2 (Berkeley) 4/29/95 +.\" $FreeBSD: releng/11.1/lib/libc/gen/devname.3 188497 2009-02-11 20:24:59Z ed $ +.\" +.Dd February 22, 2005 +.Dt DEVNAME 3 +.Os +.Sh NAME +.Nm devname +.Nd "get device name" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/stat.h +.In stdlib.h +.Ft char * +.Fn devname "dev_t dev" "mode_t type" +.Ft char * +.Fn devname_r "dev_t dev" "mode_t type" "char *buf" "int len" +.Ft char * +.Fn fdevname "int fd" +.Ft char * +.Fn fdevname_r "int fd" "char *buf" "int len" +.Sh DESCRIPTION +The +.Fn devname +function returns a pointer to the name of the block or character +device in +.Pa /dev +with a device number of +.Fa dev , +and a file type matching the one encoded in +.Fa type +which must be one of +.Dv S_IFBLK +or +.Dv S_IFCHR . +To find the right name, +.Fn devname +asks the kernel via the +.Va kern.devname +sysctl. +If it is unable to come up with a suitable name, +it will format the information encapsulated in +.Fa dev +and +.Fa type +in a human-readable format. +.Pp +The +.Fn fdevname +and +.Fn fdevname_r +function obtains the device name directly from a file descriptor +pointing to a character device. +If it is unable to come up with a suitable name, these functions will +return a NULL pointer. +.Pp +.Fn devname +and +.Fn fdevname +return the name stored in a static buffer which will be overwritten +on subsequent calls. +.Fn devname_r +and +.Fn fdevname_r +take a buffer and length as argument to avoid this problem. +.Sh EXAMPLES +.Bd -literal -compact +int fd; +struct stat buf; +char *name; + + fd = open("/dev/tun"); + fstat(fd, &buf); + printf("devname is /dev/%s\en", devname(buf.st_rdev, S_IFCHR)); + printf("fdevname is /dev/%s\en", fdevname(fd)); +.Ed +.Sh SEE ALSO +.Xr stat 2 +.Sh HISTORY +The +.Fn devname +function appeared in +.Bx 4.4 . +The +.Fn fdevname +function appeared in +.Fx 8.0 . diff --git a/lib/libc/gen/directory.3 b/lib/libc/gen/directory.3 new file mode 100644 index 0000000..0268243 --- /dev/null +++ b/lib/libc/gen/directory.3 @@ -0,0 +1,308 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)directory.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/directory.3 305567 2016-09-07 21:03:11Z jilles $ +.\" +.Dd August 31, 2016 +.Dt DIRECTORY 3 +.Os +.Sh NAME +.Nm opendir , +.Nm fdopendir , +.Nm readdir , +.Nm readdir_r , +.Nm telldir , +.Nm seekdir , +.Nm rewinddir , +.Nm closedir , +.Nm fdclosedir , +.Nm dirfd +.Nd directory operations +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In dirent.h +.Ft DIR * +.Fn opendir "const char *filename" +.Ft DIR * +.Fn fdopendir "int fd" +.Ft struct dirent * +.Fn readdir "DIR *dirp" +.Ft int +.Fn readdir_r "DIR *dirp" "struct dirent *entry" "struct dirent **result" +.Ft long +.Fn telldir "DIR *dirp" +.Ft void +.Fn seekdir "DIR *dirp" "long loc" +.Ft void +.Fn rewinddir "DIR *dirp" +.Ft int +.Fn closedir "DIR *dirp" +.Ft int +.Fn fdclosedir "DIR *dirp" +.Ft int +.Fn dirfd "DIR *dirp" +.Sh DESCRIPTION +.Bf -symbolic +The +.Fn readdir_r +interface is deprecated +because it cannot be used correctly unless +.Brq Va NAME_MAX +is a fixed value. +.Ef +.Pp +The +.Fn opendir +function +opens the directory named by +.Fa filename , +associates a +.Em directory stream +with it +and +returns a pointer to be used to identify the +.Em directory stream +in subsequent operations. +The pointer +.Dv NULL +is returned if +.Fa filename +cannot be accessed, or if it cannot +.Xr malloc 3 +enough memory to hold the whole thing. +.Pp +The +.Fn fdopendir +function is equivalent to the +.Fn opendir +function except that the directory is specified by a file descriptor +.Fa fd +rather than by a name. +The file offset associated with the file descriptor at the time of the call +determines which entries are returned. +.Pp +Upon successful return from +.Fn fdopendir , +the file descriptor is under the control of the system, +and if any attempt is made to close the file descriptor, +or to modify the state of the associated description other than by means +of +.Fn closedir , +.Fn readdir , +.Fn readdir_r , +or +.Fn rewinddir , +the behavior is undefined. +Upon calling +.Fn closedir +the file descriptor is closed. +The +.Dv FD_CLOEXEC +flag is set on the file descriptor by a successful call to +.Fn fdopendir . +.Pp +The +.Fn readdir +function +returns a pointer to the next directory entry. +The directory entry remains valid until the next call to +.Fn readdir +or +.Fn closedir +on the same +.Em directory stream . +The function returns +.Dv NULL +upon reaching the end of the directory or on error. +In the event of an error, +.Va errno +may be set to any of the values documented for the +.Xr getdirentries 2 +system call. +.Pp +The +.Fn readdir_r +function +provides the same functionality as +.Fn readdir , +but the caller must provide a directory +.Fa entry +buffer to store the results in. +The buffer must be large enough for a +.Vt struct dirent +with a +.Va d_name +array with +.Brq Va NAME_MAX ++ 1 elements. +If the read succeeds, +.Fa result +is pointed at the +.Fa entry ; +upon reaching the end of the directory +.Fa result +is set to +.Dv NULL . +The +.Fn readdir_r +function +returns 0 on success or an error number to indicate failure. +.Pp +The +.Fn telldir +function +returns a token representing the current location associated with the named +.Em directory stream . +Values returned by +.Fn telldir +are good only for the lifetime of the +.Dv DIR +pointer, +.Fa dirp , +from which they are derived. +If the directory is closed and then +reopened, prior values returned by +.Fn telldir +will no longer be valid. +Values returned by +.Fn telldir +are also invalidated by a call to +.Fn rewinddir . +.Pp +The +.Fn seekdir +function +sets the position of the next +.Fn readdir +operation on the +.Em directory stream . +The new position reverts to the one associated with the +.Em directory stream +when the +.Fn telldir +operation was performed. +.Pp +The +.Fn rewinddir +function +resets the position of the named +.Em directory stream +to the beginning of the directory. +.Pp +The +.Fn closedir +function +closes the named +.Em directory stream +and frees the structure associated with the +.Fa dirp +pointer, +returning 0 on success. +On failure, \-1 is returned and the global variable +.Va errno +is set to indicate the error. +.Pp +The +.Fn fdclosedir +function is equivalent to the +.Fn closedir +function except that this function returns directory file descriptor instead of +closing it. +.Pp +The +.Fn dirfd +function +returns the integer file descriptor associated with the named +.Em directory stream , +see +.Xr open 2 . +.Pp +Sample code which searches a directory for entry ``name'' is: +.Bd -literal -offset indent +dirp = opendir("."); +if (dirp == NULL) + return (ERROR); +len = strlen(name); +while ((dp = readdir(dirp)) != NULL) { + if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) { + (void)closedir(dirp); + return (FOUND); + } +} +(void)closedir(dirp); +return (NOT_FOUND); +.Ed +.Sh SEE ALSO +.Xr close 2 , +.Xr lseek 2 , +.Xr open 2 , +.Xr read 2 , +.Xr dir 5 +.Sh HISTORY +The +.Fn opendir , +.Fn readdir , +.Fn telldir , +.Fn seekdir , +.Fn rewinddir , +.Fn closedir , +and +.Fn dirfd +functions appeared in +.Bx 4.2 . +The +.Fn fdopendir +function appeared in +.Fx 8.0 . +.Fn fdclosedir +function appeared in +.Fx 10.0 . +.Sh BUGS +The behaviour of +.Fn telldir +and +.Fn seekdir +is likely to be wrong if there are parallel unlinks happening +and the directory is larger than one page. +There is code to ensure that a +.Fn seekdir +to the location given by a +.Fn telldir +immediately before the last +.Fn readdir +will always set the correct location to return the same value as that last +.Fn readdir +performed. +This is enough for some applications which want to "push back the last entry read" E.g. Samba. +Seeks back to any other location, +other than the beginning of the directory, +may result in unexpected behaviour if deletes are present. +It is hoped that this situation will be resolved with changes to +.Fn getdirentries +and the VFS. diff --git a/lib/libc/gen/dirfd.c b/lib/libc/gen/dirfd.c new file mode 100644 index 0000000..7ec2f36 --- /dev/null +++ b/lib/libc/gen/dirfd.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2011 Gleb Kurtsou + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/gen/dirfd.c 235649 2012-05-19 14:30:49Z gleb $ + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/dirfd.c 235649 2012-05-19 14:30:49Z gleb $"); + +#include "namespace.h" +#include + +#include +#include "un-namespace.h" + +#include "gen-private.h" + +int +dirfd(DIR *dirp) +{ + + return (_dirfd(dirp)); +} diff --git a/lib/libc/gen/dirname.3 b/lib/libc/gen/dirname.3 new file mode 100644 index 0000000..ae4cc5e --- /dev/null +++ b/lib/libc/gen/dirname.3 @@ -0,0 +1,100 @@ +.\" $OpenBSD: dirname.3,v 1.17 2007/05/31 19:19:28 jmc Exp $ +.\" +.\" Copyright (c) 1997 Todd C. Miller +.\" +.\" 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/dirname.3 303762 2016-08-05 05:50:27Z ed $ +.\" +.Dd July 29, 2016 +.Dt DIRNAME 3 +.Os +.Sh NAME +.Nm dirname +.Nd extract the directory part of a pathname +.Sh SYNOPSIS +.In libgen.h +.Ft char * +.Fn dirname "const char *path" +.Sh DESCRIPTION +The +.Fn dirname +function is the converse of +.Xr basename 3 ; +it returns a pointer to the parent directory of the pathname pointed to by +.Fa path . +Any trailing +.Sq \&/ +characters are not counted as part of the directory +name. +If +.Fa path +is a null pointer, the empty string, or contains no +.Sq \&/ +characters, +.Fn dirname +returns a pointer to the string +.Qq \&. , +signifying the current directory. +.Sh IMPLEMENTATION NOTES +The +.Fn dirname +function +returns a pointer to internal storage space allocated on the first call +that will be overwritten +by subsequent calls. +.Pp +Other vendor implementations of +.Fn dirname +may store their result in the input buffer, +making it safe to use in multithreaded applications. +Future versions of +.Fx +will follow this approach as well. +.Sh RETURN VALUES +On successful completion, +.Fn dirname +returns a pointer to the parent directory of +.Fa path . +.Pp +If +.Fn dirname +fails, a null pointer is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The following error codes may be set in +.Va errno : +.Bl -tag -width Er +.It Bq Er ENAMETOOLONG +The path component to be returned was larger than +.Dv MAXPATHLEN . +.El +.Sh SEE ALSO +.Xr basename 1 , +.Xr dirname 1 , +.Xr basename 3 +.Sh STANDARDS +The +.Fn dirname +function conforms to +.St -xpg4.2 . +.Sh HISTORY +The +.Fn dirname +function first appeared in +.Ox 2.2 +and +.Fx 4.2 . +.Sh AUTHORS +.An "Todd C. Miller" diff --git a/lib/libc/gen/dl_iterate_phdr.3 b/lib/libc/gen/dl_iterate_phdr.3 new file mode 100644 index 0000000..7fe3eca --- /dev/null +++ b/lib/libc/gen/dl_iterate_phdr.3 @@ -0,0 +1,115 @@ +.\" Copyright (c) 2005 Mark Kettenis +.\" Copyright (c) 2012 Konstantin Belousov +.\" +.\" 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. +.\" +.\" $OpenBSD: dl_iterate_phdr.3,v 1.3 2007/05/31 19:19:48 jmc Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/gen/dl_iterate_phdr.3 272848 2014-10-09 22:58:33Z emaste $ +.Dd October 9, 2014 +.Dt DL_ITERATE_PHDR 3 +.Os +.Sh NAME +.Nm dl_iterate_phdr +.Nd iterate over program headers +.Sh LIBRARY +For the dynamically linked binaries, the service is provided by +.Xr ld-elf.so.1 1 +dynamic linker. +Statically linked programs use an implementation of +.Fn dl_iterate_phdr +from libc. +.Sh SYNOPSIS +.In link.h +.Ft int +.Fn dl_iterate_phdr "int (*callback)(struct dl_phdr_info *, size_t, void *)" "void *data" +.Sh DESCRIPTION +The +.Fn dl_iterate_phdr +function iterates over all ELF objects loaded into a process's +address space, calling +.Fa callback +for each object, passing it information about the object's +program headers and the +.Fa data +argument. +The iteration is aborted when all objects are passed, or when the next +.Fa callback +call returns non-zero value. +The information about the program headers is passed in a structure +that is defined as: +.Bd -literal +struct dl_phdr_info { + Elf_Addr dlpi_addr; + const char *dlpi_name; + const Elf_Phdr *dlpi_phdr; + Elf_Half dlpi_phnum; + unsigned long long int dlpi_adds; + unsigned long long int dlpi_subs; + size_t dlpi_tls_modid; + void *dlpi_tls_data; +}; +.Ed +.Pp +The members of +.Li struct dl_phdr_info +have the following meaning: +.Bl -tag -width dlpi_tls_modid +.It Fa dlpi_addr +The base address at which the object is mapped into the address +space of the calling process. +.It Fa dlpi_name +The pathname of the ELF object. +.It Fa dlpi_phdr +A pointer to the object's program headers. +.It Fa dlpi_phnum +The number of program headers in the object. +.It Fa dlpi_adds +The counter of the object loads performed by the dynamic linker. +.It Fa dlpi_subs +The counter of the object unloads performed by the dynamic linker. +.It Fa dlpi_tls_modid +The TLS index of the object. +.It Fa dlpi_tls_data +A pointer to the initialization data for the object TLS segment. +.El +.Pp +Future versions of +.Fx +might add more members to this structure. +To make it possible for programs to check whether any new members have +been added, the size of the structure is passed as an second argument to +.Fa callback . +.Pp +The third argument to callback is the +.Fa data +value passed to the call to +.Fn dl_iterate_phdr , +allowing the +.Fa callback +to have a context. +.Sh RETURN VALUES +The +.Fn dl_iterate_phdr +returns the value returned by the last +.Fa callback +call executed. +.Sh SEE ALSO +.Xr ld 1 , +.Xr ld-elf.so.1 1 , +.Xr dlopen 3 , +.Xr elf 5 +.Sh HISTORY +The +.Nm +function first appeared in +.Fx 7.0 . diff --git a/lib/libc/gen/dladdr.3 b/lib/libc/gen/dladdr.3 new file mode 100644 index 0000000..b1516e1 --- /dev/null +++ b/lib/libc/gen/dladdr.3 @@ -0,0 +1,133 @@ +.\" +.\" Copyright (c) 1998 John D. Polstra +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/dladdr.3 206622 2010-04-14 19:08:06Z uqs $ +.\" +.Dd February 5, 1998 +.Dt DLADDR 3 +.Os +.Sh NAME +.Nm dladdr +.Nd find the shared object containing a given address +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In dlfcn.h +.Ft int +.Fn dladdr "const void *addr" "Dl_info *info" +.Sh DESCRIPTION +The +.Fn dladdr +function +queries the dynamic linker for information about the shared object +containing the address +.Fa addr . +The information is returned in the structure specified by +.Fa info . +The structure contains at least the following members: +.Bl -tag -width "XXXconst char *dli_fname" +.It Li "const char *dli_fname" +The pathname of the shared object containing the address. +.It Li "void *dli_fbase" +The base address at which the shared object is mapped into the +address space of the calling process. +.It Li "const char *dli_sname" +The name of the nearest run-time symbol with a value less than or +equal to +.Fa addr . +When possible, the symbol name is returned as it would appear in C +source code. +.Pp +If no symbol with a suitable value is found, both this field and +.Va dli_saddr +are set to +.Dv NULL . +.It Li "void *dli_saddr" +The value of the symbol returned in +.Li dli_sname . +.El +.Pp +The +.Fn dladdr +function +is available only in dynamically linked programs. +.Sh ERRORS +If a mapped shared object containing +.Fa addr +cannot be found, +.Fn dladdr +returns 0. +In that case, a message detailing the failure can be retrieved by +calling +.Fn dlerror . +.Pp +On success, a non-zero value is returned. +.Sh SEE ALSO +.Xr rtld 1 , +.Xr dlopen 3 +.Sh HISTORY +The +.Fn dladdr +function first appeared in the Solaris operating system. +.Sh BUGS +This implementation is bug-compatible with the Solaris +implementation. +In particular, the following bugs are present: +.Bl -bullet +.It +If +.Fa addr +lies in the main executable rather than in a shared library, the +pathname returned in +.Va dli_fname +may not be correct. +The pathname is taken directly from +.Va argv[0] +of the calling process. +When executing a program specified by its +full pathname, most shells set +.Va argv[0] +to the pathname. +But this is not required of shells or guaranteed +by the operating system. +.It +If +.Fa addr +is of the form +.Va &func , +where +.Va func +is a global function, its value may be an unpleasant surprise. +In +dynamically linked programs, the address of a global function is +considered to point to its program linkage table entry, rather than to +the entry point of the function itself. +This causes most global +functions to appear to be defined within the main executable, rather +than in the shared libraries where the actual code resides. +.It +Returning 0 as an indication of failure goes against long-standing +Unix tradition. +.El diff --git a/lib/libc/gen/dlinfo.3 b/lib/libc/gen/dlinfo.3 new file mode 100644 index 0000000..38fa729 --- /dev/null +++ b/lib/libc/gen/dlinfo.3 @@ -0,0 +1,279 @@ +.\" +.\" Copyright (c) 2003 Alexey Zelkin +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/dlinfo.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.Dd February 14, 2003 +.Dt DLINFO 3 +.Os +.Sh NAME +.Nm dlinfo +.Nd information about dynamically loaded object +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In link.h +.In dlfcn.h +.Ft int +.Fn dlinfo "void * restrict handle" "int request" "void * restrict p" +.Sh DESCRIPTION +The +.Fn dlinfo +function provides information about dynamically loaded object. +The action taken by +.Fn dlinfo +and exact meaning and type of +.Fa p +argument depend on value of the +.Fa request +argument provided by caller. +.Pp +The +.Fa handle +argument is either the value returned from the +.Xr dlopen 3 +function call or special handle +.Dv RTLD_SELF . +If +.Fa handle +is the value returned from +.Xr dlopen 3 , +the information returned by the +.Fn dlinfo +function pertains to the specified object. +If handle is the special handle +.Dv RTLD_SELF , +the information returned pertains to the caller itself. +.Pp +Possible values for the +.Fa request +argument are: +.Bl -tag -width indent +.It Dv RTLD_DI_LINKMAP +Retrieve the +.Vt Link_map +.Pq Vt "struct link_map" +structure pointer for the specified +.Fa handle . +On successful return, the +.Fa p +argument is filled with the pointer to the +.Vt Link_map +structure +.Pq Fa "Link_map **p" +describing a shared object specified by the +.Fa handle +argument. +The +.Vt Link_map +structures are maintained as a doubly linked list by +.Xr ld.so 1 , +in the same order as +.Xr dlopen 3 +and +.Xr dlclose 3 +are called. +See +.Sx EXAMPLES , +example 1. +.Pp +The +.Vt Link_map +structure is defined in +.In link.h +and has the following members: +.Bd -literal -offset indent +caddr_t l_addr; /* Base Address of library */ +const char *l_name; /* Absolute Path to Library */ +const void *l_ld; /* Pointer to .dynamic in memory */ +struct link_map *l_next, /* linked list of mapped libs */ + *l_prev; +.Ed +.Bl -tag -width ".Va l_addr" +.It Va l_addr +The base address of the object loaded into memory. +.It Va l_name +The full name of the loaded shared object. +.It Va l_ld +The address of the dynamic linking information segment +.Pq Dv PT_DYNAMIC +loaded into memory. +.It Va l_next +The next +.Vt Link_map +structure on the link-map list. +.It Va l_prev +The previous +.Vt Link_map +structure on the link-map list. +.El +.It Dv RTLD_DI_SERINFO +Retrieve the library search paths associated with the given +.Fa handle +argument. +The +.Fa p +argument should point to +.Vt Dl_serinfo +structure buffer +.Pq Fa "Dl_serinfo *p" . +The +.Vt Dl_serinfo +structure must be initialized first with the +.Dv RTLD_DI_SERINFOSIZE +request. +.Pp +The returned +.Vt Dl_serinfo +structure contains +.Va dls_cnt +.Vt Dl_serpath +entries. +Each entry's +.Va dlp_name +field points to the search path. +The corresponding +.Va dlp_info +field contains one of more flags indicating the origin of the path (see the +.Dv LA_SER_* +flags defined in the +.In link.h +header file). +See +.Sx EXAMPLES , +example 2, for a usage example. +.It Dv RTLD_DI_SERINFOSIZE +Initialize a +.Vt Dl_serinfo +structure for use in a +.Dv RTLD_DI_SERINFO +request. +Both the +.Va dls_cnt +and +.Va dls_size +fields are returned to indicate the number of search paths applicable +to the handle, and the total size of a +.Vt Dl_serinfo +buffer required to hold +.Va dls_cnt +.Vt Dl_serpath +entries and the associated search path strings. +See +.Sx EXAMPLES , +example 2, for a usage example. +.It Va RTLD_DI_ORIGIN +Retrieve the origin of the dynamic object associated with the handle. +On successful return, +.Fa p +argument is filled with the +.Vt char +pointer +.Pq Fa "char *p" . +.El +.Sh RETURN VALUES +The +.Fn dlinfo +function returns 0 on success, or \-1 if an error occurred. +Whenever an error has been detected, a message detailing it can +be retrieved via a call to +.Xr dlerror 3 . +.Sh EXAMPLES +Example 1: Using +.Fn dlinfo +to retrieve +.Vt Link_map +structure. +.Pp +The following example shows how dynamic library can detect the list +of shared libraries loaded after caller's one. +For simplicity, error checking has been omitted. +.Bd -literal -offset indent +Link_map *map; + +dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &map); + +while (map != NULL) { + printf("%p: %s\\n", map->l_addr, map->l_name); + map = map->l_next; +} +.Ed +.Pp +Example 2: Using +.Fn dlinfo +to retrieve the library search paths. +.Pp +The following example shows how a dynamic object can inspect the library +search paths that would be used to locate a simple filename with +.Xr dlopen 3 . +For simplicity, error checking has been omitted. +.Bd -literal -offset indent +Dl_serinfo _info, *info = &_info; +Dl_serpath *path; +unsigned int cnt; + +/* determine search path count and required buffer size */ +dlinfo(RTLD_SELF, RTLD_DI_SERINFOSIZE, (void *)info); + +/* allocate new buffer and initialize */ +info = malloc(_info.dls_size); +info->dls_size = _info.dls_size; +info->dls_cnt = _info.dls_cnt; + +/* obtain sarch path information */ +dlinfo(RTLD_SELF, RTLD_DI_SERINFO, (void *)info); + +path = &info->dls_serpath[0]; + +for (cnt = 1; cnt <= info->dls_cnt; cnt++, path++) { + (void) printf("%2d: %s\\n", cnt, path->dls_name); +} +.Ed +.Sh SEE ALSO +.Xr rtld 1 , +.Xr dladdr 3 , +.Xr dlopen 3 , +.Xr dlsym 3 +.Sh HISTORY +The +.Fn dlinfo +function first appeared in the Solaris operating system. +In +.Fx , +it first appeared in +.Fx 4.8 . +.Sh AUTHORS +.An -nosplit +The +.Fx +implementation of the +.Fn dlinfo +function was originally written by +.An Alexey Zelkin Aq Mt phantom@FreeBSD.org +and later extended and improved by +.An Alexander Kabaev Aq Mt kan@FreeBSD.org . +.Pp +The manual page for this function was written by +.An Alexey Zelkin Aq Mt phantom@FreeBSD.org . diff --git a/lib/libc/gen/dllockinit.3 b/lib/libc/gen/dllockinit.3 new file mode 100644 index 0000000..601291a --- /dev/null +++ b/lib/libc/gen/dllockinit.3 @@ -0,0 +1,127 @@ +.\" +.\" Copyright (c) 1999, 2000 John D. Polstra +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/dllockinit.3 206622 2010-04-14 19:08:06Z uqs $ +.\" +.Dd July 5, 2000 +.Dt DLLOCKINIT 3 +.Os +.Sh NAME +.Nm dllockinit +.Nd register thread locking methods with the dynamic linker +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In dlfcn.h +.Ft void +.Fn dllockinit "void *context" "void *(*lock_create)(void *context)" "void (*rlock_acquire)(void *lock)" "void (*wlock_acquire)(void *lock)" "void (*lock_release)(void *lock)" "void (*lock_destroy)(void *lock)" "void (*context_destroy)(void *context)" +.Sh DESCRIPTION +.Bf Sy +Due to enhancements in the dynamic linker, this interface is no longer +needed. +It is deprecated and will be removed from future releases. +In current releases it still exists, but only as a stub which does nothing. +.Ef +.Pp +Threads packages can call +.Fn dllockinit +at initialization time to register locking functions for the dynamic +linker to use. +This enables the dynamic linker to prevent multiple +threads from entering its critical sections simultaneously. +.Pp +The +.Fa context +argument specifies an opaque context for creating locks. +The +dynamic linker will pass it to the +.Fa lock_create +function when creating the locks it needs. +When the dynamic linker +is permanently finished using the locking functions (e.g., if the +program makes a subsequent call to +.Fn dllockinit +to register new locking functions) it will call +.Fa context_destroy +to destroy the context. +.Pp +The +.Fa lock_create +argument specifies a function for creating a read/write lock. +It +must return a pointer to the new lock. +.Pp +The +.Fa rlock_acquire +and +.Fa wlock_acquire +arguments specify functions which lock a lock for reading or +writing, respectively. +The +.Fa lock_release +argument specifies a function which unlocks a lock. +Each of these +functions is passed a pointer to the lock. +.Pp +The +.Fa lock_destroy +argument specifies a function to destroy a lock. +It may be +.Dv NULL +if locks do not need to be destroyed. +The +.Fa context_destroy +argument specifies a function to destroy the context. +It may be +.Dv NULL +if the context does not need to be destroyed. +.Pp +Until +.Fn dllockinit +is called, the dynamic linker protects its critical sections using +a default locking mechanism which works by blocking the +.Dv SIGVTALRM , +.Dv SIGPROF , +and +.Dv SIGALRM +signals. +This is sufficient for many application level threads +packages, which typically use one of these signals to implement +preemption. +An application which has registered its own locking +methods with +.Fn dllockinit +can restore the default locking by calling +.Fn dllockinit +with all arguments +.Dv NULL . +.Sh SEE ALSO +.Xr rtld 1 , +.Xr signal 3 +.Sh HISTORY +The +.Fn dllockinit +function first appeared in +.Fx 4.0 . diff --git a/lib/libc/gen/dlopen.3 b/lib/libc/gen/dlopen.3 new file mode 100644 index 0000000..6611697 --- /dev/null +++ b/lib/libc/gen/dlopen.3 @@ -0,0 +1,408 @@ +.\" This source code is a product of Sun Microsystems, Inc. and is provided +.\" for unrestricted use provided that this legend is included on all tape +.\" media and as a part of the software program in whole or part. Users +.\" may copy or modify this source code without charge, but are not authorized +.\" to license or distribute it to anyone else except as part of a product or +.\" program developed by the user. +.\" +.\" THIS PROGRAM CONTAINS SOURCE CODE COPYRIGHTED BY SUN MICROSYSTEMS, INC. +.\" SUN MICROSYSTEMS, INC., MAKES NO REPRESENTATIONS ABOUT THE SUITABLITY +.\" OF SUCH SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT +.\" EXPRESS OR IMPLIED WARRANTY OF ANY KIND. SUN MICROSYSTEMS, INC. DISCLAIMS +.\" ALL WARRANTIES WITH REGARD TO SUCH SOURCE CODE, INCLUDING ALL IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN +.\" NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT, +.\" INCIDENTAL, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING +.\" FROM USE OF SUCH SOURCE CODE, REGARDLESS OF THE THEORY OF LIABILITY. +.\" +.\" This source code is provided with no support and without any obligation on +.\" the part of Sun Microsystems, Inc. to assist in its use, correction, +.\" modification or enhancement. +.\" +.\" SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +.\" INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS +.\" SOURCE CODE OR ANY PART THEREOF. +.\" +.\" Sun Microsystems, Inc. +.\" 2550 Garcia Avenue +.\" Mountain View, California 94043 +.\" +.\" Copyright (c) 1991 Sun Microsystems, Inc. +.\" +.\" @(#) dlopen.3 1.6 90/01/31 SMI +.\" $FreeBSD: releng/11.1/lib/libc/gen/dlopen.3 278758 2015-02-14 15:14:41Z tijl $ +.\" +.Dd February 14, 2015 +.Dt DLOPEN 3 +.Os +.Sh NAME +.Nm dlopen , +.Nm fdlopen , +.Nm dlsym , +.Nm dlfunc , +.Nm dlerror , +.Nm dlclose +.Nd programmatic interface to the dynamic linker +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In dlfcn.h +.Ft void * +.Fn dlopen "const char *path" "int mode" +.Ft void * +.Fn fdlopen "int fd" "int mode" +.Ft void * +.Fn dlsym "void * restrict handle" "const char * restrict symbol" +.Ft dlfunc_t +.Fn dlfunc "void * restrict handle" "const char * restrict symbol" +.Ft char * +.Fn dlerror "void" +.Ft int +.Fn dlclose "void *handle" +.Sh DESCRIPTION +These functions provide a simple programmatic interface to the services of the +dynamic linker. +Operations are provided to add new shared objects to a +program's address space, to obtain the address bindings of symbols +defined by such +objects, and to remove such objects when their use is no longer required. +.Pp +The +.Fn dlopen +function +provides access to the shared object in +.Fa path , +returning a descriptor that can be used for later +references to the object in calls to +.Fn dlsym +and +.Fn dlclose . +If +.Fa path +was not in the address space prior to the call to +.Fn dlopen , +it is placed in the address space. +When an object is first loaded into the address space in this way, its +function +.Fn _init , +if any, is called by the dynamic linker. +If +.Fa path +has already been placed in the address space in a previous call to +.Fn dlopen , +it is not added a second time, although a reference count of +.Fn dlopen +operations on +.Fa path +is maintained. +A null pointer supplied for +.Fa path +is interpreted as a reference to the main +executable of the process. +The +.Fa mode +argument +controls the way in which external function references from the +loaded object are bound to their referents. +It must contain one of the following values, possibly ORed with +additional flags which will be described subsequently: +.Bl -tag -width RTLD_LAZYX +.It Dv RTLD_LAZY +Each external function reference is resolved when the function is first +called. +.It Dv RTLD_NOW +All external function references are bound immediately by +.Fn dlopen . +.El +.Pp +.Dv RTLD_LAZY +is normally preferred, for reasons of efficiency. +However, +.Dv RTLD_NOW +is useful to ensure that any undefined symbols are discovered during the +call to +.Fn dlopen . +.Pp +One of the following flags may be ORed into the +.Fa mode +argument: +.Bl -tag -width RTLD_NODELETE +.It Dv RTLD_GLOBAL +Symbols from this shared object and its directed acyclic graph (DAG) +of needed objects will be available for resolving undefined references +from all other shared objects. +.It Dv RTLD_LOCAL +Symbols in this shared object and its DAG of needed objects will be +available for resolving undefined references only from other objects +in the same DAG. +This is the default, but it may be specified +explicitly with this flag. +.It Dv RTLD_TRACE +When set, causes dynamic linker to exit after loading all objects +needed by this shared object and printing a summary which includes +the absolute pathnames of all objects, to standard output. +With this flag +.Fn dlopen +will return to the caller only in the case of error. +.It Dv RTLD_NODELETE +Prevents unload of the loaded object on +.Fn dlclose . +The same behaviour may be requested by +.Fl "z nodelete" +option of the static linker +.Xr ld 1 . +.It Dv RTLD_NOLOAD +Only return valid handle for the object if it is already loaded in +the process address space, otherwise +.Dv NULL +is returned. +Other mode flags may be specified, which will be applied for promotion +for the found object. +.El +.Pp +If +.Fn dlopen +fails, it returns a null pointer, and sets an error condition which may +be interrogated with +.Fn dlerror . +.Pp +The +.Fn fdlopen +function is similar to +.Fn dlopen , +but it takes the file descriptor argument +.Fa fd , +which is used for the file operations needed to load an object +into the address space. +The file descriptor +.Fa fd +is not closed by the function regardless a result of execution, +but a duplicate of the file descriptor is. +This may be important if a +.Xr lockf 3 +lock is held on the passed descriptor. +The +.Fa fd +argument -1 is interpreted as a reference to the main +executable of the process, similar to +.Va NULL +value for the +.Fa name +argument to +.Fn dlopen . +The +.Fn fdlopen +function can be used by the code that needs to perform +additional checks on the loaded objects, to prevent races with +symlinking or renames. +.Pp +The +.Fn dlsym +function +returns the address binding of the symbol described in the null-terminated +character string +.Fa symbol , +as it occurs in the shared object identified by +.Fa handle . +The symbols exported by objects added to the address space by +.Fn dlopen +can be accessed only through calls to +.Fn dlsym . +Such symbols do not supersede any definition of those symbols already present +in the address space when the object is loaded, nor are they available to +satisfy normal dynamic linking references. +.Pp +If +.Fn dlsym +is called with the special +.Fa handle +.Dv NULL , +it is interpreted as a reference to the executable or shared object +from which the call +is being made. +Thus a shared object can reference its own symbols. +.Pp +If +.Fn dlsym +is called with the special +.Fa handle +.Dv RTLD_DEFAULT , +the search for the symbol follows the algorithm used for resolving +undefined symbols when objects are loaded. +The objects searched are +as follows, in the given order: +.Bl -enum +.It +The referencing object itself (or the object from which the call to +.Fn dlsym +is made), if that object was linked using the +.Fl Bsymbolic +option to +.Xr ld 1 . +.It +All objects loaded at program start-up. +.It +All objects loaded via +.Fn dlopen +with the +.Dv RTLD_GLOBAL +flag set in the +.Fa mode +argument. +.It +All objects loaded via +.Fn dlopen +which are in needed-object DAGs that also contain the referencing object. +.El +.Pp +If +.Fn dlsym +is called with the special +.Fa handle +.Dv RTLD_NEXT , +then the search for the symbol is limited to the shared objects +which were loaded after the one issuing the call to +.Fn dlsym . +Thus, if the function is called from the main program, all +the shared libraries are searched. +If it is called from a shared library, all subsequent shared +libraries are searched. +.Dv RTLD_NEXT +is useful for implementing wrappers around library functions. +For example, a wrapper function +.Fn getpid +could access the +.Dq real +.Fn getpid +with +.Li dlsym(RTLD_NEXT, \&"getpid\&") . +(Actually, the +.Fn dlfunc +interface, below, should be used, since +.Fn getpid +is a function and not a data object.) +.Pp +If +.Fn dlsym +is called with the special +.Fa handle +.Dv RTLD_SELF , +then the search for the symbol is limited to the shared object +issuing the call to +.Fn dlsym +and those shared objects which were loaded after it. +.Pp +The +.Fn dlsym +function +returns a null pointer if the symbol cannot be found, and sets an error +condition which may be queried with +.Fn dlerror . +.Pp +The +.Fn dlfunc +function +implements all of the behavior of +.Fn dlsym , +but has a return type which can be cast to a function pointer without +triggering compiler diagnostics. +(The +.Fn dlsym +function +returns a data pointer; in the C standard, conversions between +data and function pointer types are undefined. +Some compilers and +.Xr lint 1 +utilities warn about such casts.) +The precise return type of +.Fn dlfunc +is unspecified; applications must cast it to an appropriate function pointer +type. +.Pp +The +.Fn dlerror +function +returns a null-terminated character string describing the last error that +occurred during a call to +.Fn dlopen , +.Fn dladdr , +.Fn dlinfo , +.Fn dlsym , +.Fn dlfunc , +or +.Fn dlclose . +If no such error has occurred, +.Fn dlerror +returns a null pointer. +At each call to +.Fn dlerror , +the error indication is reset. +Thus in the case of two calls +to +.Fn dlerror , +where the second call follows the first immediately, the second call +will always return a null pointer. +.Pp +The +.Fn dlclose +function +deletes a reference to the shared object referenced by +.Fa handle . +If the reference count drops to 0, the object is removed from the +address space, and +.Fa handle +is rendered invalid. +Just before removing a shared object in this way, the dynamic linker +calls the object's +.Fn _fini +function, if such a function is defined by the object. +If +.Fn dlclose +is successful, it returns a value of 0. +Otherwise it returns -1, and sets an error condition that can be +interrogated with +.Fn dlerror . +.Pp +The object-intrinsic functions +.Fn _init +and +.Fn _fini +are called with no arguments, and are not expected to return values. +.Sh NOTES +ELF executables need to be linked +using the +.Fl export-dynamic +option to +.Xr ld 1 +for symbols defined in the executable to become visible to +.Fn dlsym . +.Pp +In previous implementations, it was necessary to prepend an underscore +to all external symbols in order to gain symbol +compatibility with object code compiled from the C language. +This is +still the case when using the (obsolete) +.Fl aout +option to the C language compiler. +.Sh ERRORS +The +.Fn dlopen , +.Fn fdlopen , +.Fn dlsym , +and +.Fn dlfunc +functions +return a null pointer in the event of errors. +The +.Fn dlclose +function +returns 0 on success, or -1 if an error occurred. +Whenever an error has been detected, a message detailing it can be +retrieved via a call to +.Fn dlerror . +.Sh SEE ALSO +.Xr ld 1 , +.Xr rtld 1 , +.Xr dladdr 3 , +.Xr dlinfo 3 , +.Xr link 5 diff --git a/lib/libc/gen/dup3.3 b/lib/libc/gen/dup3.3 new file mode 100644 index 0000000..f35204c --- /dev/null +++ b/lib/libc/gen/dup3.3 @@ -0,0 +1,116 @@ +.\" Copyright (c) 2013 Jilles Tjoelker +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/dup3.3 254488 2013-08-18 13:25:18Z jilles $ +.\" +.Dd August 16, 2013 +.Dt DUP3 3 +.Os +.Sh NAME +.Nm dup3 +.Nd duplicate an existing file descriptor +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In fcntl.h +.In unistd.h +.Ft int +.Fn dup3 "int oldd" "int newd" "int flags" +.Sh DESCRIPTION +The +.Fn dup3 +function +duplicates an existing object descriptor +while allowing the value of the new descriptor to be specified. +.Pp +The close-on-exec flag on the new file descriptor is determined by the +.Dv O_CLOEXEC +bit in +.Fa flags . +.Pp +If +.Fa oldd +\*(Ne +.Fa newd +and +.Fa flags +== 0, +the behavior is identical to +.Li dup2(oldd, newd) . +.Pp +If +.Fa oldd +== +.Fa newd , +then +.Fn dup3 +fails, unlike +.Xr dup2 2 . +.Sh RETURN VALUES +The value -1 is returned if an error occurs. +The external variable +.Va errno +indicates the cause of the error. +.Sh ERRORS +The +.Fn dup3 +function fails if: +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa oldd +argument is not a valid active descriptor or the +.Fa newd +argument is negative or exceeds the maximum allowable descriptor number +.It Bq Er EINVAL +The +.Fa oldd +argument is equal to the +.Fa newd +argument. +.It Bq Er EINVAL +The +.Fa flags +argument has bits set other than +.Dv O_CLOEXEC . +.El +.Sh SEE ALSO +.Xr accept 2 , +.Xr close 2 , +.Xr dup2 2 , +.Xr fcntl 2 , +.Xr getdtablesize 2 , +.Xr open 2 , +.Xr pipe 2 , +.Xr socket 2 , +.Xr socketpair 2 +.Sh STANDARDS +The +.Fn dup3 +function does not conform to any standard. +.Sh HISTORY +The +.Fn dup3 +function appeared in +.Fx 10.0 . diff --git a/lib/libc/gen/dup3.c b/lib/libc/gen/dup3.c new file mode 100644 index 0000000..4377b37 --- /dev/null +++ b/lib/libc/gen/dup3.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2012 Jukka A. Ukkonen + * All rights reserved. + * + * This software was developed by Jukka Ukkonen for FreeBSD. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/dup3.c 288028 2015-09-20 20:21:49Z rodrigc $"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" + +int __dup3(int, int, int); + +int +__dup3(int oldfd, int newfd, int flags) +{ + int how; + + if (oldfd == newfd) { + errno = EINVAL; + return (-1); + } + + if (flags & ~O_CLOEXEC) { + errno = EINVAL; + return (-1); + } + + how = (flags & O_CLOEXEC) ? F_DUP2FD_CLOEXEC : F_DUP2FD; + + return (_fcntl(oldfd, how, newfd)); +} + +__weak_reference(__dup3, dup3); +__weak_reference(__dup3, _dup3); diff --git a/lib/libc/gen/elf_utils.c b/lib/libc/gen/elf_utils.c new file mode 100644 index 0000000..8bd9c22 --- /dev/null +++ b/lib/libc/gen/elf_utils.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2010 Konstantin Belousov + * 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. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/gen/elf_utils.c 295407 2016-02-08 19:24:13Z kib $ + */ + +#include +#include +#include +#include +#include +#include +#include "libc_private.h" + +int __elf_phdr_match_addr(struct dl_phdr_info *, void *); +void __pthread_map_stacks_exec(void); + +int +__elf_phdr_match_addr(struct dl_phdr_info *phdr_info, void *addr) +{ + const Elf_Phdr *ph; + int i; + + for (i = 0; i < phdr_info->dlpi_phnum; i++) { + ph = &phdr_info->dlpi_phdr[i]; + if (ph->p_type != PT_LOAD || (ph->p_flags & PF_X) == 0) + continue; + if (phdr_info->dlpi_addr + ph->p_vaddr <= (uintptr_t)addr && + (uintptr_t)addr + sizeof(addr) < phdr_info->dlpi_addr + + ph->p_vaddr + ph->p_memsz) + break; + } + return (i != phdr_info->dlpi_phnum); +} + +void +__libc_map_stacks_exec(void) +{ + int mib[2]; + struct rlimit rlim; + u_long usrstack; + size_t len; + + mib[0] = CTL_KERN; + mib[1] = KERN_USRSTACK; + len = sizeof(usrstack); + if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &usrstack, &len, NULL, 0) + == -1) + return; + if (getrlimit(RLIMIT_STACK, &rlim) == -1) + return; + mprotect((void *)(uintptr_t)(usrstack - rlim.rlim_cur), + rlim.rlim_cur, _rtld_get_stack_prot()); +} + +#pragma weak __pthread_map_stacks_exec +void +__pthread_map_stacks_exec(void) +{ + + ((void (*)(void))__libc_interposing[INTERPOS_map_stacks_exec])(); +} diff --git a/lib/libc/gen/err.3 b/lib/libc/gen/err.3 new file mode 100644 index 0000000..c4ed8fb --- /dev/null +++ b/lib/libc/gen/err.3 @@ -0,0 +1,245 @@ +.\" 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 +.\" 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. +.\" 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. +.\" +.\" From: @(#)err.3 8.1 (Berkeley) 6/9/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/err.3 234714 2012-04-26 19:21:58Z eadler $ +.\" +.Dd March 29, 2012 +.Dt ERR 3 +.Os +.Sh NAME +.Nm err , +.Nm verr , +.Nm errc , +.Nm verrc , +.Nm errx , +.Nm verrx , +.Nm warn , +.Nm vwarn , +.Nm warnc , +.Nm vwarnc , +.Nm warnx , +.Nm vwarnx , +.Nm err_set_exit , +.Nm err_set_file +.Nd formatted error messages +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In err.h +.Ft void +.Fn err "int eval" "const char *fmt" "..." +.Ft void +.Fn err_set_exit "void (*exitf)(int)" +.Ft void +.Fn err_set_file "void *vfp" +.Ft void +.Fn errc "int eval" "int code" "const char *fmt" "..." +.Ft void +.Fn errx "int eval" "const char *fmt" "..." +.Ft void +.Fn warn "const char *fmt" "..." +.Ft void +.Fn warnc "int code" "const char *fmt" "..." +.Ft void +.Fn warnx "const char *fmt" "..." +.In stdarg.h +.Ft void +.Fn verr "int eval" "const char *fmt" "va_list args" +.Ft void +.Fn verrc "int eval" "int code" "const char *fmt" "va_list args" +.Ft void +.Fn verrx "int eval" "const char *fmt" "va_list args" +.Ft void +.Fn vwarn "const char *fmt" "va_list args" +.Ft void +.Fn vwarnc "int code" "const char *fmt" "va_list args" +.Ft void +.Fn vwarnx "const char *fmt" "va_list args" +.Sh DESCRIPTION +The +.Fn err +and +.Fn warn +family of functions display a formatted error message on the standard +error output, or on another file specified using the +.Fn err_set_file +function. +In all cases, the last component of the program name, a colon character, +and a space are output. +If the +.Fa fmt +argument is not NULL, the +.Xr printf 3 Ns +-like formatted error message is output. +The output is terminated by a newline character. +.Pp +The +.Fn err , +.Fn errc , +.Fn verr , +.Fn verrc , +.Fn warn , +.Fn warnc , +.Fn vwarn , +and +.Fn vwarnc +functions append an error message obtained from +.Xr strerror 3 +based on a supplied error code value or the global variable +.Va errno , +preceded by another colon and space unless the +.Fa fmt +argument is +.Dv NULL . +.Pp +In the case of the +.Fn errc , +.Fn verrc , +.Fn warnc , +and +.Fn vwarnc +functions, +the +.Fa code +argument is used to look up the error message. +.Pp +The +.Fn err , +.Fn verr , +.Fn warn , +and +.Fn vwarn +functions use the global variable +.Va errno +to look up the error message. +.Pp +The +.Fn errx +and +.Fn warnx +functions do not append an error message. +.Pp +The +.Fn err , +.Fn verr , +.Fn errc , +.Fn verrc , +.Fn errx , +and +.Fn verrx +functions do not return, but exit with the value of the argument +.Fa eval . +It is recommended that the standard values defined in +.Xr sysexits 3 +be used for the value of +.Fa eval . +The +.Fn err_set_exit +function can be used to specify a function which is called before +.Xr exit 3 +to perform any necessary cleanup; passing a null function pointer for +.Va exitf +resets the hook to do nothing. +The +.Fn err_set_file +function sets the output stream used by the other functions. +Its +.Fa vfp +argument must be either a pointer to an open stream +(possibly already converted to void *) +or a null pointer +(in which case the output stream is set to standard error). +.Sh EXAMPLES +Display the current errno information string and exit: +.Bd -literal -offset indent +if ((p = malloc(size)) == NULL) + err(EX_OSERR, NULL); +if ((fd = open(file_name, O_RDONLY, 0)) == -1) + err(EX_NOINPUT, "%s", file_name); +.Ed +.Pp +Display an error message and exit: +.Bd -literal -offset indent +if (tm.tm_hour < START_TIME) + errx(EX_DATAERR, "too early, wait until %s", + start_time_string); +.Ed +.Pp +Warn of an error: +.Bd -literal -offset indent +if ((fd = open(raw_device, O_RDONLY, 0)) == -1) + warnx("%s: %s: trying the block device", + raw_device, strerror(errno)); +if ((fd = open(block_device, O_RDONLY, 0)) == -1) + err(EX_OSFILE, "%s", block_device); +.Ed +.Pp +Warn of an error without using the global variable +.Va errno : +.Bd -literal -offset indent +error = my_function(); /* returns a value from */ +if (error != 0) + warnc(error, "my_function"); +.Ed +.Sh SEE ALSO +.Xr exit 3 , +.Xr fmtmsg 3 , +.Xr printf 3 , +.Xr strerror 3 , +.Xr sysexits 3 +.Sh STANDARDS +The +.Fn err +and +.Fn warn +families of functions are +.Bx +extensions. +As such they should not be used in truly portable code. +Use +.Fn strerror +or similar functions instead. +.Sh HISTORY +The +.Fn err +and +.Fn warn +functions first appeared in +.Bx 4.4 . +The +.Fn err_set_exit +and +.Fn err_set_file +functions first appeared in +.Fx 2.1 . +The +.Fn errc +and +.Fn warnc +functions first appeared in +.Fx 3.0 . diff --git a/lib/libc/gen/exec.3 b/lib/libc/gen/exec.3 new file mode 100644 index 0000000..00a324a --- /dev/null +++ b/lib/libc/gen/exec.3 @@ -0,0 +1,321 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)exec.3 8.3 (Berkeley) 1/24/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/exec.3 293204 2016-01-05 16:21:20Z jilles $ +.\" +.Dd January 5, 2016 +.Dt EXEC 3 +.Os +.Sh NAME +.Nm execl , +.Nm execlp , +.Nm execle , +.Nm exect , +.Nm execv , +.Nm execvp , +.Nm execvP +.Nd execute a file +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Vt extern char **environ ; +.Ft int +.Fn execl "const char *path" "const char *arg" ... /* "(char *)0" */ +.Ft int +.Fn execlp "const char *file" "const char *arg" ... /* "(char *)0" */ +.Ft int +.Fo execle +.Fa "const char *path" "const char *arg" ... +.Fa /* +.Bk -words +.Fa "(char *)0" "char *const envp[]" */ +.Ek +.Fc +.Ft int +.Fn exect "const char *path" "char *const argv[]" "char *const envp[]" +.Ft int +.Fn execv "const char *path" "char *const argv[]" +.Ft int +.Fn execvp "const char *file" "char *const argv[]" +.Ft int +.Fn execvP "const char *file" "const char *search_path" "char *const argv[]" +.Sh DESCRIPTION +The +.Nm exec +family of functions replaces the current process image with a +new process image. +The functions described in this manual page are front-ends for the function +.Xr execve 2 . +(See the manual page for +.Xr execve 2 +for detailed information about the replacement of the current process.) +.Pp +The initial argument for these functions is the pathname of a file which +is to be executed. +.Pp +The +.Fa "const char *arg" +and subsequent ellipses in the +.Fn execl , +.Fn execlp , +and +.Fn execle +functions can be thought of as +.Em arg0 , +.Em arg1 , +\&..., +.Em argn . +Together they describe a list of one or more pointers to null-terminated +strings that represent the argument list available to the executed program. +The first argument, by convention, should point to the file name associated +with the file being executed. +The list of arguments +.Em must +be terminated by a +.Dv NULL +pointer. +.Pp +The +.Fn exect , +.Fn execv , +.Fn execvp , +and +.Fn execvP +functions provide an array of pointers to null-terminated strings that +represent the argument list available to the new program. +The first argument, by convention, should point to the file name associated +with the file being executed. +The array of pointers +.Sy must +be terminated by a +.Dv NULL +pointer. +.Pp +The +.Fn execle +and +.Fn exect +functions also specify the environment of the executed process by following +the +.Dv NULL +pointer that terminates the list of arguments in the argument list +or the pointer to the argv array with an additional argument. +This additional argument is an array of pointers to null-terminated strings +and +.Em must +be terminated by a +.Dv NULL +pointer. +The other functions take the environment for the new process image from the +external variable +.Va environ +in the current process. +.Pp +Some of these functions have special semantics. +.Pp +The functions +.Fn execlp , +.Fn execvp , +and +.Fn execvP +will duplicate the actions of the shell in searching for an executable file +if the specified file name does not contain a slash +.Dq Li / +character. +For +.Fn execlp +and +.Fn execvp , +search path is the path specified in the environment by +.Dq Ev PATH +variable. +If this variable is not specified, +the default path is set according to the +.Dv _PATH_DEFPATH +definition in +.In paths.h , +which is set to +.Dq Ev /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin . +For +.Fn execvP , +the search path is specified as an argument to the function. +In addition, certain errors are treated specially. +.Pp +If an error is ambiguous (for simplicity, we shall consider all +errors except +.Er ENOEXEC +as being ambiguous here, although only the critical error +.Er EACCES +is really ambiguous), +then these functions will act as if they stat the file to determine +whether the file exists and has suitable execute permissions. +If it does, they will return immediately with the global variable +.Va errno +restored to the value set by +.Fn execve . +Otherwise, the search will be continued. +If the search completes without performing a successful +.Fn execve +or terminating due to an error, +these functions will return with the global variable +.Va errno +set to +.Er EACCES +or +.Er ENOENT +according to whether at least one file with suitable execute permissions +was found. +.Pp +If the header of a file is not recognized (the attempted +.Fn execve +returned +.Er ENOEXEC ) , +these functions will execute the shell with the path of +the file as its first argument. +(If this attempt fails, no further searching is done.) +.Pp +The function +.Fn exect +executes a file with the program tracing facilities enabled (see +.Xr ptrace 2 ) . +.Sh RETURN VALUES +If any of the +.Fn exec +functions returns, an error will have occurred. +The return value is \-1, and the global variable +.Va errno +will be set to indicate the error. +.Sh FILES +.Bl -tag -width /bin/sh -compact +.It Pa /bin/sh +The shell. +.El +.Sh COMPATIBILITY +Historically, the default path for the +.Fn execlp +and +.Fn execvp +functions was +.Dq Pa :/bin:/usr/bin . +This was changed to remove the current directory to enhance system +security. +.Pp +The behavior of +.Fn execlp +and +.Fn execvp +when errors occur while attempting to execute the file is not quite historic +practice, and has not traditionally been documented and is not specified +by the +.Tn POSIX +standard. +.Pp +Traditionally, the functions +.Fn execlp +and +.Fn execvp +ignored all errors except for the ones described above and +.Er ETXTBSY , +upon which they retried after sleeping for several seconds, and +.Er ENOMEM +and +.Er E2BIG , +upon which they returned. +They now return for +.Er ETXTBSY , +and determine existence and executability more carefully. +In particular, +.Er EACCES +for inaccessible directories in the path prefix is no longer +confused with +.Er EACCES +for files with unsuitable execute permissions. +In +.Bx 4.4 , +they returned upon all errors except +.Er EACCES , +.Er ENOENT , +.Er ENOEXEC +and +.Er ETXTBSY . +This was inferior to the traditional error handling, +since it breaks the ignoring of errors for path prefixes +and only improves the handling of the unusual ambiguous error +.Er EFAULT +and the unusual error +.Er EIO . +The behaviour was changed to match the behaviour of +.Xr sh 1 . +.Sh ERRORS +The +.Fn execl , +.Fn execle , +.Fn execlp , +.Fn execvp +and +.Fn execvP +functions +may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr execve 2 +and +.Xr malloc 3 . +.Pp +The +.Fn exect +and +.Fn execv +functions +may fail and set +.Va errno +for any of the errors specified for the library function +.Xr execve 2 . +.Sh SEE ALSO +.Xr sh 1 , +.Xr execve 2 , +.Xr fork 2 , +.Xr ktrace 2 , +.Xr ptrace 2 , +.Xr environ 7 +.Sh STANDARDS +The +.Fn execl , +.Fn execv , +.Fn execle , +.Fn execlp +and +.Fn execvp +functions +conform to +.St -p1003.1-88 . +The +.Fn execvP +function first appeared in +.Fx 5.2 . diff --git a/lib/libc/gen/fdevname.c b/lib/libc/gen/fdevname.c new file mode 100644 index 0000000..42eabe3 --- /dev/null +++ b/lib/libc/gen/fdevname.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2009 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/fdevname.c 200133 2009-12-05 18:51:44Z ed $"); + +#include "namespace.h" +#include +#include +#include +#include "un-namespace.h" + +char * +fdevname_r(int fd, char *buf, int len) +{ + struct fiodgname_arg fgn; + + fgn.buf = buf; + fgn.len = len; + + if (_ioctl(fd, FIODGNAME, &fgn) == -1) + return (NULL); + return (buf); +} + +char * +fdevname(int fd) +{ + static char buf[SPECNAMELEN + 1]; + + return (fdevname_r(fd, buf, sizeof(buf))); +} diff --git a/lib/libc/gen/feature_present.3 b/lib/libc/gen/feature_present.3 new file mode 100644 index 0000000..3a0af04 --- /dev/null +++ b/lib/libc/gen/feature_present.3 @@ -0,0 +1,72 @@ +.\" Copyright (c) 2008 Yahoo!, Inc. +.\" All rights reserved. +.\" Written by: John Baldwin +.\" +.\" 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 author nor the names of any co-contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/feature_present.3 222286 2011-05-25 14:13:53Z ru $ +.\" +.Dd January 8, 2008 +.Dt FEATURE_PRESENT 3 +.Os +.Sh NAME +.Nm feature_present +.Nd query presence of a kernel feature +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn feature_present "const char *feature" +.Sh DESCRIPTION +The +.Fn feature_present +function provides a method for an application to determine if a specific +kernel feature is present in the currently running kernel. +The +.Fa feature +argument specifies the name of the feature to check. +The +.Fn feature_present +function will return 1 if the specified feature is present, +otherwise it will return 0. +If the +.Fn feature_present +function is not able to determine the presence of +.Fa feature +due to an internal error it will return 0. +.Sh RETURN VALUES +If +.Fa feature +is present then 1 is returned; +otherwise 0 is returned. +.Sh SEE ALSO +.Xr sysconf 3 , +.Xr sysctl 3 +.Sh HISTORY +The +.Fn feature_present +function first appeared in +.Fx 8.0 . diff --git a/lib/libc/gen/feature_present.c b/lib/libc/gen/feature_present.c new file mode 100644 index 0000000..fcf3c4f --- /dev/null +++ b/lib/libc/gen/feature_present.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2008 Yahoo!, Inc. + * All rights reserved. + * Written by: John Baldwin + * + * 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 author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/feature_present.c 288007 2015-09-20 03:56:57Z rodrigc $"); + +#include +#include +#include +#include +#include + +/* + * Returns true if the named feature is present in the currently + * running kernel. A feature's presence is indicated by an integer + * sysctl node called kern.feature. that is non-zero. + */ +int +feature_present(const char *feature) +{ + char *mib; + size_t len; + int i; + + if (asprintf(&mib, "kern.features.%s", feature) < 0) + return (0); + len = sizeof(i); + if (sysctlbyname(mib, &i, &len, NULL, 0) < 0) { + free(mib); + return (0); + } + free(mib); + if (len != sizeof(i)) + return (0); + return (i != 0); +} diff --git a/lib/libc/gen/fmtcheck.3 b/lib/libc/gen/fmtcheck.3 new file mode 100644 index 0000000..1eeaf41 --- /dev/null +++ b/lib/libc/gen/fmtcheck.3 @@ -0,0 +1,108 @@ +.\" Copyright (c) 2000 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This file was contributed to The NetBSD Foundation by Allen Briggs. +.\" +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/fmtcheck.3 208027 2010-05-13 12:07:55Z uqs $ +.Dd October 16, 2002 +.Dt FMTCHECK 3 +.Os +.Sh NAME +.Nm fmtcheck +.Nd sanitizes user-supplied +.Xr printf 3 Ns -style +format string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft const char * +.Fn fmtcheck "const char *fmt_suspect" "const char *fmt_default" +.Sh DESCRIPTION +The +.Fn fmtcheck +scans +.Fa fmt_suspect +and +.Fa fmt_default +to determine if +.Fa fmt_suspect +will consume the same argument types as +.Fa fmt_default +and to ensure that +.Fa fmt_suspect +is a valid format string. +.Pp +The +.Xr printf 3 +family of functions cannot verify the types of arguments that they are +passed at run-time. +In some cases, like +.Xr catgets 3 , +it is useful or necessary to use a user-supplied format string with no +guarantee that the format string matches the specified arguments. +.Pp +The +.Fn fmtcheck +was designed to be used in these cases, as in: +.Bd -literal -offset indent +printf(fmtcheck(user_format, standard_format), arg1, arg2); +.Ed +.Pp +In the check, field widths, fillers, precisions, etc.\& are ignored (unless +the field width or precision is an asterisk +.Ql * +instead of a digit string). +Also, any text other than the format specifiers +is completely ignored. +.Sh RETURN VALUES +If +.Fa fmt_suspect +is a valid format and consumes the same argument types as +.Fa fmt_default , +then the +.Fn fmtcheck +will return +.Fa fmt_suspect . +Otherwise, it will return +.Fa fmt_default . +.Sh SEE ALSO +.Xr printf 3 +.Sh BUGS +The +.Fn fmtcheck +function does not recognize positional parameters. +.Sh SECURITY CONSIDERATIONS +Note that the formats may be quite different as long as they accept the +same arguments. +For example, +.Qq Li "%p %o %30s %#llx %-10.*e %n" +is compatible with +.Qq Li "This number %lu %d%% and string %s has %qd numbers and %.*g floats (%n)" . +However, +.Qq Li %o +is not equivalent to +.Qq Li %lx +because +the first requires an integer and the second requires a long. diff --git a/lib/libc/gen/fmtmsg.3 b/lib/libc/gen/fmtmsg.3 new file mode 100644 index 0000000..4c901f8 --- /dev/null +++ b/lib/libc/gen/fmtmsg.3 @@ -0,0 +1,260 @@ +.\" +.\" Copyright (c) 2002 Mike Barcroft +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/fmtmsg.3 107619 2002-12-04 18:57:46Z ru $ +.\" +.Dd August 5, 2002 +.Dt FMTMSG 3 +.Os +.Sh NAME +.Nm fmtmsg +.Nd display a detailed diagnostic message +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In fmtmsg.h +.Ft int +.Fo fmtmsg +.Fa "long classification" "const char *label" "int severity" +.Fa "const char *text" "const char *action" "const char *tag" +.Fc +.Sh DESCRIPTION +The +.Fn fmtmsg +function displays a detailed diagnostic message, based on +the supplied arguments, to +.Dv stderr +and/or the system console. +.Pp +The +.Fa classification +argument is the bitwise inclusive +.Tn OR +of zero or one of the manifest constants from +each of the classification groups below. +The Output classification group is an exception since both +.Dv MM_PRINT +and +.Dv MM_CONSOLE +may be specified. +.Bl -tag -width indent +.It Output +.Bl -tag -width ".Dv MM_CONSOLE" +.It Dv MM_PRINT +Output should take place on +.Dv stderr . +.It Dv MM_CONSOLE +Output should take place on the system console. +.El +.It "Source of Condition (Major)" +.Bl -tag -width ".Dv MM_CONSOLE" +.It Dv MM_HARD +The source of the condition is hardware related. +.It Dv MM_SOFT +The source of the condition is software related. +.It Dv MM_FIRM +The source of the condition is firmware related. +.El +.It "Source of Condition (Minor)" +.Bl -tag -width ".Dv MM_CONSOLE" +.It Dv MM_APPL +The condition was detected at the application level. +.It Dv MM_UTIL +The condition was detected at the utility level. +.It Dv MM_OPSYS +The condition was detected at the operating system level. +.El +.It Status +.Bl -tag -width ".Dv MM_CONSOLE" +.It Dv MM_RECOVER +The application can recover from the condition. +.It Dv MM_NRECOV +The application is unable to recover from the condition. +.El +.El +.Pp +Alternatively, the +.Dv MM_NULLMC +manifest constant may be used to specify no classification. +.Pp +The +.Fa label +argument indicates the source of the message. +It is made up of two fields separated by a colon +.Pq Ql \&: . +The first field can be up to 10 bytes, +and the second field can be up to 14 bytes. +The +.Dv MM_NULLLBL +manifest constant may be used to specify no label. +.Pp +The +.Fa severity +argument identifies the importance of the condition. +One of the following manifest constants should be used for this argument. +.Bl -tag -offset indent -width ".Dv MM_WARNING" +.It Dv MM_HALT +The application has confronted a serious fault and is halting. +.It Dv MM_ERROR +The application has detected a fault. +.It Dv MM_WARNING +The application has detected an unusual condition, +that could be indicative of a problem. +.It Dv MM_INFO +The application is providing information about a non-error condition. +.It Dv MM_NOSEV +No severity level supplied. +.El +.Pp +The +.Fa text +argument details the error condition that caused the message. +There is no limit on the size of this character string. +The +.Dv MM_NULLTXT +manifest constant may be used to specify no text. +.Pp +The +.Fa action +argument details how the error-recovery process should begin. +Upon output, +.Fn fmtmsg +will prefix +.Qq Li "TO FIX:" +to the beginning of the +.Fa action +argument. +The +.Dv MM_NULLACT +manifest constant may be used to specify no action. +.Pp +The +.Fa tag +argument should reference online documentation for the message. +This usually includes the +.Fa label +and a unique identifying number. +An example tag is +.Qq Li BSD:ls:168 . +The +.Dv MM_NULLTAG +manifest constant may be used to specify no tag. +.Sh RETURN VALUES +The +.Fn fmtmsg +function returns +.Dv MM_OK +upon success, +.Dv MM_NOMSG +to indicate output to +.Dv stderr +failed, +.Dv MM_NOCON +to indicate output to the system console failed, or +.Dv MM_NOTOK +to indicate output to +.Dv stderr +and the system console failed. +.Sh ENVIRONMENT +The +.Ev MSGVERB +(message verbosity) +environment variable specifies which arguments to +.Fn fmtmsg +will be output to +.Dv stderr , +and in which order. +.Ev MSGVERB +should be a colon +.Pq Ql \&: +separated list of identifiers. +Valid identifiers include: +.Li label , severity , text , action , +and +.Li tag . +If invalid identifiers are specified or incorrectly separated, +the default message verbosity and ordering will be used. +The default ordering is equivalent to a +.Ev MSGVERB +with a value of +.Qq Li label:severity:text:action:tag . +.Sh EXAMPLES +The code: +.Bd -literal -offset indent +fmtmsg(MM_UTIL | MM_PRINT, "BSD:ls", MM_ERROR, + "illegal option -- z", "refer to manual", "BSD:ls:001"); +.Ed +.Pp +will output: +.Bd -literal -offset indent +BSD:ls: ERROR: illegal option -- z +TO FIX: refer to manual BSD:ls:001 +.Ed +.Pp +to +.Dv stderr . +.Pp +The same code, with +.Ev MSGVERB +set to +.Qq Li "text:severity:action:tag" , +produces: +.Bd -literal -offset indent +illegal option -- z: ERROR +TO FIX: refer to manual BSD:ls:001 +.Ed +.Sh SEE ALSO +.Xr err 3 , +.Xr exit 3 , +.Xr strerror 3 +.Sh STANDARDS +The +.Fn fmtmsg +function conforms to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn fmtmsg +function first appeared in +.Fx 5.0 . +.Sh BUGS +Specifying +.Dv MM_NULLMC +for the +.Fa classification +argument makes little sense, since without an output specified, +.Fn fmtmsg +is unable to do anything useful. +.Pp +In order for +.Fn fmtmsg +to output to the system console, the effective +user must have appropriate permission to write to +.Pa /dev/console . +This means that on most systems +.Fn fmtmsg +will return +.Dv MM_NOCON +unless the effective user is root. diff --git a/lib/libc/gen/fnmatch.3 b/lib/libc/gen/fnmatch.3 new file mode 100644 index 0000000..7aa4b22 --- /dev/null +++ b/lib/libc/gen/fnmatch.3 @@ -0,0 +1,151 @@ +.\" 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. +.\" 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. +.\" 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. +.\" +.\" @(#)fnmatch.3 8.3 (Berkeley) 4/28/95 +.\" $FreeBSD: releng/11.1/lib/libc/gen/fnmatch.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd July 18, 2004 +.Dt FNMATCH 3 +.Os +.Sh NAME +.Nm fnmatch +.Nd test whether a filename or pathname matches a shell-style pattern +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In fnmatch.h +.Ft int +.Fn fnmatch "const char *pattern" "const char *string" "int flags" +.Sh DESCRIPTION +The +.Fn fnmatch +function +matches patterns according to the rules used by the shell. +It checks the string specified by the +.Fa string +argument to see if it matches the pattern specified by the +.Fa pattern +argument. +.Pp +The +.Fa flags +argument modifies the interpretation of +.Fa pattern +and +.Fa string . +The value of +.Fa flags +is the bitwise inclusive +.Tn OR +of any of the following +constants, which are defined in the include file +.In fnmatch.h . +.Bl -tag -width FNM_PATHNAME +.It Dv FNM_NOESCAPE +Normally, every occurrence of a backslash +.Pq Ql \e +followed by a character in +.Fa pattern +is replaced by that character. +This is done to negate any special meaning for the character. +If the +.Dv FNM_NOESCAPE +flag is set, a backslash character is treated as an ordinary character. +.It Dv FNM_PATHNAME +Slash characters in +.Fa string +must be explicitly matched by slashes in +.Fa pattern . +If this flag is not set, then slashes are treated as regular characters. +.It Dv FNM_PERIOD +Leading periods in +.Fa string +must be explicitly matched by periods in +.Fa pattern . +If this flag is not set, then leading periods are treated as regular +characters. +The definition of +.Dq leading +is related to the specification of +.Dv FNM_PATHNAME . +A period is always +.Dq leading +if it is the first character in +.Fa string . +Additionally, if +.Dv FNM_PATHNAME +is set, +a period is +leading +if it immediately follows a slash. +.It Dv FNM_LEADING_DIR +Ignore +.Dq Li /* +rest after successful +.Fa pattern +matching. +.It Dv FNM_CASEFOLD +Ignore case distinctions in both the +.Fa pattern +and the +.Fa string . +.El +.Sh RETURN VALUES +The +.Fn fnmatch +function returns zero if +.Fa string +matches the pattern specified by +.Fa pattern , +otherwise, it returns the value +.Dv FNM_NOMATCH . +.Sh SEE ALSO +.Xr sh 1 , +.Xr glob 3 , +.Xr regex 3 +.Sh STANDARDS +The current implementation of the +.Fn fnmatch +function +.Em does not +conform to +.St -p1003.2 . +Collating symbol expressions, equivalence class expressions and +character class expressions are not supported. +.Sh HISTORY +The +.Fn fnmatch +function first appeared in +.Bx 4.4 . +.Sh BUGS +The pattern +.Ql * +matches the empty string, even if +.Dv FNM_PATHNAME +is specified. diff --git a/lib/libc/gen/fpclassify.3 b/lib/libc/gen/fpclassify.3 new file mode 100644 index 0000000..1de388c --- /dev/null +++ b/lib/libc/gen/fpclassify.3 @@ -0,0 +1,133 @@ +.\" Copyright (c) 2003 Mike Barcroft +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/fpclassify.3 140890 2005-01-27 05:46:17Z das $ +.\" +.Dd January 26, 2005 +.Dt FPCLASSIFY 3 +.Os +.Sh NAME +.Nm fpclassify , isfinite , isinf , isnan , isnormal +.Nd "classify a floating-point number" +.Sh LIBRARY +.Lb libm +.Sh SYNOPSIS +.In math.h +.Ft int +.Fn fpclassify "real-floating x" +.Ft int +.Fn isfinite "real-floating x" +.Ft int +.Fn isinf "real-floating x" +.Ft int +.Fn isnan "real-floating x" +.Ft int +.Fn isnormal "real-floating x" +.Sh DESCRIPTION +The +.Fn fpclassify +macro takes an argument of +.Fa x +and returns one of the following manifest constants. +.Bl -tag -width ".Dv FP_SUBNORMAL" +.It Dv FP_INFINITE +Indicates that +.Fa x +is an infinite number. +.It Dv FP_NAN +Indicates that +.Fa x +is not a number (NaN). +.It Dv FP_NORMAL +Indicates that +.Fa x +is a normalized number. +.It Dv FP_SUBNORMAL +Indicates that +.Fa x +is a denormalized number. +.It Dv FP_ZERO +Indicates that +.Fa x +is zero (0 or \-0). +.El +.Pp +The +.Fn isfinite +macro returns a non-zero value if and only if its argument has +a finite (zero, subnormal, or normal) value. +The +.Fn isinf , +.Fn isnan , +and +.Fn isnormal +macros return non-zero if and only if +.Fa x +is an infinity, NaN, +or a non-zero normalized number, respectively. +.Pp +The symbol +.Fn isnanf +is provided as an alias to +.Fn isnan +for compatibility, and its use is deprecated. +Similarly, +.Fn finite +and +.Fn finitef +are deprecated versions of +.Fn isfinite . +.Sh SEE ALSO +.Xr isgreater 3 , +.Xr math 3 , +.Xr signbit 3 +.Sh STANDARDS +The +.Fn fpclassify , +.Fn isfinite , +.Fn isinf , +.Fn isnan , +and +.Fn isnormal +macros conform to +.St -isoC-99 . +.Sh HISTORY +The +.Fn fpclassify , +.Fn isfinite , +.Fn isinf , +.Fn isnan , +and +.Fn isnormal +macros were added in +.Fx 5.1 . +.Bx 3 +introduced +.Fn isinf +and +.Fn isnan +functions, which accepted +.Vt double +arguments; these have been superseded by the macros +described above. diff --git a/lib/libc/gen/frexp.3 b/lib/libc/gen/frexp.3 new file mode 100644 index 0000000..c9ad31f --- /dev/null +++ b/lib/libc/gen/frexp.3 @@ -0,0 +1,94 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)frexp.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/frexp.3 206616 2010-04-14 18:29:34Z uqs $ +.\" +.Dd March 4, 2005 +.Dt FREXP 3 +.Os +.Sh NAME +.Nm frexp , +.Nm frexpf , +.Nm frexpl +.Nd convert floating-point number to fractional and integral components +.Sh LIBRARY +.Lb libm +.Sh SYNOPSIS +.In math.h +.Ft double +.Fn frexp "double value" "int *exp" +.Ft float +.Fn frexpf "float value" "int *exp" +.Ft long double +.Fn frexpl "long double value" "int *exp" +.Sh DESCRIPTION +The +.Fn frexp , +.Fn frexpf +and +.Fn frexpl +functions break a floating-point number into a normalized +fraction and an integral power of 2. +They store the integer in the +.Vt int +object pointed to by +.Fa exp . +.Sh RETURN VALUES +These functions return the value +.Va x , +such that +.Va x +is a +.Vt double +with magnitude in the interval +.Eo [ 1/2 , 1 Ec ) +or zero, and +.Fa value +equals +.Va x +times 2 raised to the power +.Fa *exp . +If +.Fa value +is zero, both parts of the result are zero. +.Sh SEE ALSO +.Xr ldexp 3 , +.Xr math 3 , +.Xr modf 3 +.Sh STANDARDS +The +.Fn frexp , +.Fn frexpf , +and +.Fn frexpl +functions conform to +.St -isoC-99 . diff --git a/lib/libc/gen/ftok.3 b/lib/libc/gen/ftok.3 new file mode 100644 index 0000000..2836f94 --- /dev/null +++ b/lib/libc/gen/ftok.3 @@ -0,0 +1,83 @@ +.\" Copyright (c) 1994 SigmaSoft, Th. Lockert +.\" 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. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/ftok.3 276006 2014-12-21 12:36:36Z brueffer $ +.Dd July 9, 2009 +.Dt FTOK 3 +.Os +.Sh NAME +.Nm ftok +.Nd create IPC identifier from path name +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/ipc.h +.Ft key_t +.Fn ftok "const char *path" "int id" +.Sh DESCRIPTION +The +.Fn ftok +function attempts to create a unique key suitable for use with the +.Xr msgget 2 , +.Xr semget 2 +and +.Xr shmget 2 +functions given the +.Fa path +of an existing file and a user-selectable +.Fa id . +.Pp +The specified +.Fa path +must specify an existing file that is accessible to the calling process +or the call will fail. +Also, note that links to files will return the +same key, given the same +.Fa id . +.Sh RETURN VALUES +The +.Fn ftok +function will return -1 if +.Fa path +does not exist or if it cannot be accessed by the calling process. +.Sh SEE ALSO +.Xr msgget 2 , +.Xr semget 2 , +.Xr shmget 2 +.Sh HISTORY +The +.Fn ftok +function originates with System V and is typically used by programs +that use the System V IPC routines. +.Sh AUTHORS +.An Thorsten Lockert Aq Mt tholo@sigmasoft.com +.Sh BUGS +The returned key is computed based on the device minor number and inode of the +specified +.Fa path +in combination with the lower 8 bits of the given +.Fa id . +Thus it is quite possible for the routine to return duplicate keys. diff --git a/lib/libc/gen/fts-compat.c b/lib/libc/gen/fts-compat.c new file mode 100644 index 0000000..df62e4e --- /dev/null +++ b/lib/libc/gen/fts-compat.c @@ -0,0 +1,1214 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * 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. + * 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. + * + * $OpenBSD: fts.c,v 1.22 1999/10/03 19:22:22 millert Exp $ + */ + +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94"; +#endif /* LIBC_SCCS and not lint */ +#endif + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/fts-compat.c 300660 2016-05-25 06:55:53Z truckman $"); + +#include "namespace.h" +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "fts-compat.h" +#include "un-namespace.h" + +#include "gen-private.h" + +FTSENT *__fts_children_44bsd(FTS *, int); +int __fts_close_44bsd(FTS *); +void *__fts_get_clientptr_44bsd(FTS *); +FTS *__fts_get_stream_44bsd(FTSENT *); +FTS *__fts_open_44bsd(char * const *, int, + int (*)(const FTSENT * const *, const FTSENT * const *)); +FTSENT *__fts_read_44bsd(FTS *); +int __fts_set_44bsd(FTS *, FTSENT *, int); +void __fts_set_clientptr_44bsd(FTS *, void *); + +static FTSENT *fts_alloc(FTS *, char *, int); +static FTSENT *fts_build(FTS *, int); +static void fts_lfree(FTSENT *); +static void fts_load(FTS *, FTSENT *); +static size_t fts_maxarglen(char * const *); +static void fts_padjust(FTS *, FTSENT *); +static int fts_palloc(FTS *, size_t); +static FTSENT *fts_sort(FTS *, FTSENT *, int); +static u_short fts_stat(FTS *, FTSENT *, int); +static int fts_safe_changedir(FTS *, FTSENT *, int, char *); +static int fts_ufslinks(FTS *, const FTSENT *); + +#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) + +#define CLR(opt) (sp->fts_options &= ~(opt)) +#define ISSET(opt) (sp->fts_options & (opt)) +#define SET(opt) (sp->fts_options |= (opt)) + +#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd)) + +/* fts_build flags */ +#define BCHILD 1 /* fts_children */ +#define BNAMES 2 /* fts_children, names only */ +#define BREAD 3 /* fts_read */ + +/* + * Internal representation of an FTS, including extra implementation + * details. The FTS returned from fts_open points to this structure's + * ftsp_fts member (and can be cast to an _fts_private as required) + */ +struct _fts_private { + FTS ftsp_fts; + struct statfs ftsp_statfs; + dev_t ftsp_dev; + int ftsp_linksreliable; +}; + +/* + * The "FTS_NOSTAT" option can avoid a lot of calls to stat(2) if it + * knows that a directory could not possibly have subdirectories. This + * is decided by looking at the link count: a subdirectory would + * increment its parent's link count by virtue of its own ".." entry. + * This assumption only holds for UFS-like filesystems that implement + * links and directories this way, so we must punt for others. + */ + +static const char *ufslike_filesystems[] = { + "ufs", + "zfs", + "nfs", + "ext2fs", + 0 +}; + +FTS * +__fts_open_44bsd(char * const *argv, int options, + int (*compar)(const FTSENT * const *, const FTSENT * const *)) +{ + struct _fts_private *priv; + FTS *sp; + FTSENT *p, *root; + int nitems; + FTSENT *parent, *tmp; + int len; + + /* Options check. */ + if (options & ~FTS_OPTIONMASK) { + errno = EINVAL; + return (NULL); + } + + /* Allocate/initialize the stream. */ + if ((priv = calloc(1, sizeof(*priv))) == NULL) + return (NULL); + sp = &priv->ftsp_fts; + sp->fts_compar = compar; + sp->fts_options = options; + + /* Shush, GCC. */ + tmp = NULL; + + /* Logical walks turn on NOCHDIR; symbolic links are too hard. */ + if (ISSET(FTS_LOGICAL)) + SET(FTS_NOCHDIR); + + /* + * Start out with 1K of path space, and enough, in any case, + * to hold the user's paths. + */ + if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN))) + goto mem1; + + /* Allocate/initialize root's parent. */ + if ((parent = fts_alloc(sp, "", 0)) == NULL) + goto mem2; + parent->fts_level = FTS_ROOTPARENTLEVEL; + + /* Allocate/initialize root(s). */ + for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) { + /* Don't allow zero-length paths. */ + if ((len = strlen(*argv)) == 0) { + errno = ENOENT; + goto mem3; + } + + p = fts_alloc(sp, *argv, len); + p->fts_level = FTS_ROOTLEVEL; + p->fts_parent = parent; + p->fts_accpath = p->fts_name; + p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW)); + + /* Command-line "." and ".." are real directories. */ + if (p->fts_info == FTS_DOT) + p->fts_info = FTS_D; + + /* + * If comparison routine supplied, traverse in sorted + * order; otherwise traverse in the order specified. + */ + if (compar) { + p->fts_link = root; + root = p; + } else { + p->fts_link = NULL; + if (root == NULL) + tmp = root = p; + else { + tmp->fts_link = p; + tmp = p; + } + } + } + if (compar && nitems > 1) + root = fts_sort(sp, root, nitems); + + /* + * Allocate a dummy pointer and make fts_read think that we've just + * finished the node before the root(s); set p->fts_info to FTS_INIT + * so that everything about the "current" node is ignored. + */ + if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL) + goto mem3; + sp->fts_cur->fts_link = root; + sp->fts_cur->fts_info = FTS_INIT; + + /* + * If using chdir(2), grab a file descriptor pointing to dot to ensure + * that we can get back here; this could be avoided for some paths, + * but almost certainly not worth the effort. Slashes, symbolic links, + * and ".." are all fairly nasty problems. Note, if we can't get the + * descriptor we run anyway, just more slowly. + */ + if (!ISSET(FTS_NOCHDIR) && + (sp->fts_rfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) + SET(FTS_NOCHDIR); + + return (sp); + +mem3: fts_lfree(root); + free(parent); +mem2: free(sp->fts_path); +mem1: free(sp); + return (NULL); +} + +static void +fts_load(FTS *sp, FTSENT *p) +{ + int len; + char *cp; + + /* + * Load the stream structure for the next traversal. Since we don't + * actually enter the directory until after the preorder visit, set + * the fts_accpath field specially so the chdir gets done to the right + * place and the user can access the first node. From fts_open it's + * known that the path will fit. + */ + len = p->fts_pathlen = p->fts_namelen; + memmove(sp->fts_path, p->fts_name, len + 1); + if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) { + len = strlen(++cp); + memmove(p->fts_name, cp, len + 1); + p->fts_namelen = len; + } + p->fts_accpath = p->fts_path = sp->fts_path; + sp->fts_dev = p->fts_dev; +} + +int +__fts_close_44bsd(FTS *sp) +{ + FTSENT *freep, *p; + int saved_errno; + + /* + * This still works if we haven't read anything -- the dummy structure + * points to the root list, so we step through to the end of the root + * list which has a valid parent pointer. + */ + if (sp->fts_cur) { + for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { + freep = p; + p = p->fts_link != NULL ? p->fts_link : p->fts_parent; + free(freep); + } + free(p); + } + + /* Free up child linked list, sort array, path buffer. */ + if (sp->fts_child) + fts_lfree(sp->fts_child); + if (sp->fts_array) + free(sp->fts_array); + free(sp->fts_path); + + /* Return to original directory, save errno if necessary. */ + if (!ISSET(FTS_NOCHDIR)) { + saved_errno = fchdir(sp->fts_rfd) ? errno : 0; + (void)_close(sp->fts_rfd); + + /* Set errno and return. */ + if (saved_errno != 0) { + /* Free up the stream pointer. */ + free(sp); + errno = saved_errno; + return (-1); + } + } + + /* Free up the stream pointer. */ + free(sp); + return (0); +} + +/* + * Special case of "/" at the end of the path so that slashes aren't + * appended which would cause paths to be written as "....//foo". + */ +#define NAPPEND(p) \ + (p->fts_path[p->fts_pathlen - 1] == '/' \ + ? p->fts_pathlen - 1 : p->fts_pathlen) + +FTSENT * +__fts_read_44bsd(FTS *sp) +{ + FTSENT *p, *tmp; + int instr; + char *t; + int saved_errno; + + /* If finished or unrecoverable error, return NULL. */ + if (sp->fts_cur == NULL || ISSET(FTS_STOP)) + return (NULL); + + /* Set current node pointer. */ + p = sp->fts_cur; + + /* Save and zero out user instructions. */ + instr = p->fts_instr; + p->fts_instr = FTS_NOINSTR; + + /* Any type of file may be re-visited; re-stat and re-turn. */ + if (instr == FTS_AGAIN) { + p->fts_info = fts_stat(sp, p, 0); + return (p); + } + + /* + * Following a symlink -- SLNONE test allows application to see + * SLNONE and recover. If indirecting through a symlink, have + * keep a pointer to current location. If unable to get that + * pointer, follow fails. + */ + if (instr == FTS_FOLLOW && + (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { + p->fts_info = fts_stat(sp, p, 1); + if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { + if ((p->fts_symfd = _open(".", O_RDONLY | O_CLOEXEC, + 0)) < 0) { + p->fts_errno = errno; + p->fts_info = FTS_ERR; + } else + p->fts_flags |= FTS_SYMFOLLOW; + } + return (p); + } + + /* Directory in pre-order. */ + if (p->fts_info == FTS_D) { + /* If skipped or crossed mount point, do post-order visit. */ + if (instr == FTS_SKIP || + (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) { + if (p->fts_flags & FTS_SYMFOLLOW) + (void)_close(p->fts_symfd); + if (sp->fts_child) { + fts_lfree(sp->fts_child); + sp->fts_child = NULL; + } + p->fts_info = FTS_DP; + return (p); + } + + /* Rebuild if only read the names and now traversing. */ + if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) { + CLR(FTS_NAMEONLY); + fts_lfree(sp->fts_child); + sp->fts_child = NULL; + } + + /* + * Cd to the subdirectory. + * + * If have already read and now fail to chdir, whack the list + * to make the names come out right, and set the parent errno + * so the application will eventually get an error condition. + * Set the FTS_DONTCHDIR flag so that when we logically change + * directories back to the parent we don't do a chdir. + * + * If haven't read do so. If the read fails, fts_build sets + * FTS_STOP or the fts_info field of the node. + */ + if (sp->fts_child != NULL) { + if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) { + p->fts_errno = errno; + p->fts_flags |= FTS_DONTCHDIR; + for (p = sp->fts_child; p != NULL; + p = p->fts_link) + p->fts_accpath = + p->fts_parent->fts_accpath; + } + } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) { + if (ISSET(FTS_STOP)) + return (NULL); + return (p); + } + p = sp->fts_child; + sp->fts_child = NULL; + goto name; + } + + /* Move to the next node on this level. */ +next: tmp = p; + if ((p = p->fts_link) != NULL) { + free(tmp); + + /* + * If reached the top, return to the original directory (or + * the root of the tree), and load the paths for the next root. + */ + if (p->fts_level == FTS_ROOTLEVEL) { + if (FCHDIR(sp, sp->fts_rfd)) { + SET(FTS_STOP); + return (NULL); + } + fts_load(sp, p); + return (sp->fts_cur = p); + } + + /* + * User may have called fts_set on the node. If skipped, + * ignore. If followed, get a file descriptor so we can + * get back if necessary. + */ + if (p->fts_instr == FTS_SKIP) + goto next; + if (p->fts_instr == FTS_FOLLOW) { + p->fts_info = fts_stat(sp, p, 1); + if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { + if ((p->fts_symfd = + _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) { + p->fts_errno = errno; + p->fts_info = FTS_ERR; + } else + p->fts_flags |= FTS_SYMFOLLOW; + } + p->fts_instr = FTS_NOINSTR; + } + +name: t = sp->fts_path + NAPPEND(p->fts_parent); + *t++ = '/'; + memmove(t, p->fts_name, p->fts_namelen + 1); + return (sp->fts_cur = p); + } + + /* Move up to the parent node. */ + p = tmp->fts_parent; + free(tmp); + + if (p->fts_level == FTS_ROOTPARENTLEVEL) { + /* + * Done; free everything up and set errno to 0 so the user + * can distinguish between error and EOF. + */ + free(p); + errno = 0; + return (sp->fts_cur = NULL); + } + + /* NUL terminate the pathname. */ + sp->fts_path[p->fts_pathlen] = '\0'; + + /* + * Return to the parent directory. If at a root node or came through + * a symlink, go back through the file descriptor. Otherwise, cd up + * one directory. + */ + if (p->fts_level == FTS_ROOTLEVEL) { + if (FCHDIR(sp, sp->fts_rfd)) { + SET(FTS_STOP); + return (NULL); + } + } else if (p->fts_flags & FTS_SYMFOLLOW) { + if (FCHDIR(sp, p->fts_symfd)) { + saved_errno = errno; + (void)_close(p->fts_symfd); + errno = saved_errno; + SET(FTS_STOP); + return (NULL); + } + (void)_close(p->fts_symfd); + } else if (!(p->fts_flags & FTS_DONTCHDIR) && + fts_safe_changedir(sp, p->fts_parent, -1, "..")) { + SET(FTS_STOP); + return (NULL); + } + p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; + return (sp->fts_cur = p); +} + +/* + * Fts_set takes the stream as an argument although it's not used in this + * implementation; it would be necessary if anyone wanted to add global + * semantics to fts using fts_set. An error return is allowed for similar + * reasons. + */ +/* ARGSUSED */ +int +__fts_set_44bsd(FTS *sp, FTSENT *p, int instr) +{ + if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW && + instr != FTS_NOINSTR && instr != FTS_SKIP) { + errno = EINVAL; + return (1); + } + p->fts_instr = instr; + return (0); +} + +FTSENT * +__fts_children_44bsd(FTS *sp, int instr) +{ + FTSENT *p; + int fd; + + if (instr != 0 && instr != FTS_NAMEONLY) { + errno = EINVAL; + return (NULL); + } + + /* Set current node pointer. */ + p = sp->fts_cur; + + /* + * Errno set to 0 so user can distinguish empty directory from + * an error. + */ + errno = 0; + + /* Fatal errors stop here. */ + if (ISSET(FTS_STOP)) + return (NULL); + + /* Return logical hierarchy of user's arguments. */ + if (p->fts_info == FTS_INIT) + return (p->fts_link); + + /* + * If not a directory being visited in pre-order, stop here. Could + * allow FTS_DNR, assuming the user has fixed the problem, but the + * same effect is available with FTS_AGAIN. + */ + if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */) + return (NULL); + + /* Free up any previous child list. */ + if (sp->fts_child != NULL) + fts_lfree(sp->fts_child); + + if (instr == FTS_NAMEONLY) { + SET(FTS_NAMEONLY); + instr = BNAMES; + } else + instr = BCHILD; + + /* + * If using chdir on a relative path and called BEFORE fts_read does + * its chdir to the root of a traversal, we can lose -- we need to + * chdir into the subdirectory, and we don't know where the current + * directory is, so we can't get back so that the upcoming chdir by + * fts_read will work. + */ + if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' || + ISSET(FTS_NOCHDIR)) + return (sp->fts_child = fts_build(sp, instr)); + + if ((fd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) + return (NULL); + sp->fts_child = fts_build(sp, instr); + if (fchdir(fd)) { + (void)_close(fd); + return (NULL); + } + (void)_close(fd); + return (sp->fts_child); +} + +#ifndef fts_get_clientptr +#error "fts_get_clientptr not defined" +#endif + +void * +(__fts_get_clientptr_44bsd)(FTS *sp) +{ + + return (fts_get_clientptr(sp)); +} + +#ifndef fts_get_stream +#error "fts_get_stream not defined" +#endif + +FTS * +(__fts_get_stream_44bsd)(FTSENT *p) +{ + return (fts_get_stream(p)); +} + +void +__fts_set_clientptr_44bsd(FTS *sp, void *clientptr) +{ + + sp->fts_clientptr = clientptr; +} + +/* + * This is the tricky part -- do not casually change *anything* in here. The + * idea is to build the linked list of entries that are used by fts_children + * and fts_read. There are lots of special cases. + * + * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is + * set and it's a physical walk (so that symbolic links can't be directories), + * we can do things quickly. First, if it's a 4.4BSD file system, the type + * of the file is in the directory entry. Otherwise, we assume that the number + * of subdirectories in a node is equal to the number of links to the parent. + * The former skips all stat calls. The latter skips stat calls in any leaf + * directories and for any files after the subdirectories in the directory have + * been found, cutting the stat calls by about 2/3. + */ +static FTSENT * +fts_build(FTS *sp, int type) +{ + struct dirent *dp; + FTSENT *p, *head; + int nitems; + FTSENT *cur, *tail; + DIR *dirp; + void *oldaddr; + size_t dnamlen; + int cderrno, descend, len, level, maxlen, nlinks, oflag, saved_errno, + nostat, doadjust; + char *cp; + + /* Set current node pointer. */ + cur = sp->fts_cur; + + /* + * Open the directory for reading. If this fails, we're done. + * If being called from fts_read, set the fts_info field. + */ +#ifdef FTS_WHITEOUT + if (ISSET(FTS_WHITEOUT)) + oflag = DTF_NODUP | DTF_REWIND; + else + oflag = DTF_HIDEW | DTF_NODUP | DTF_REWIND; +#else +#define __opendir2(path, flag) opendir(path) +#endif + if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) { + if (type == BREAD) { + cur->fts_info = FTS_DNR; + cur->fts_errno = errno; + } + return (NULL); + } + + /* + * Nlinks is the number of possible entries of type directory in the + * directory if we're cheating on stat calls, 0 if we're not doing + * any stat calls at all, -1 if we're doing stats on everything. + */ + if (type == BNAMES) { + nlinks = 0; + /* Be quiet about nostat, GCC. */ + nostat = 0; + } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) { + if (fts_ufslinks(sp, cur)) + nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2); + else + nlinks = -1; + nostat = 1; + } else { + nlinks = -1; + nostat = 0; + } + +#ifdef notdef + (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink); + (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n", + ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT)); +#endif + /* + * If we're going to need to stat anything or we want to descend + * and stay in the directory, chdir. If this fails we keep going, + * but set a flag so we don't chdir after the post-order visit. + * We won't be able to stat anything, but we can still return the + * names themselves. Note, that since fts_read won't be able to + * chdir into the directory, it will have to return different path + * names than before, i.e. "a/b" instead of "b". Since the node + * has already been visited in pre-order, have to wait until the + * post-order visit to return the error. There is a special case + * here, if there was nothing to stat then it's not an error to + * not be able to stat. This is all fairly nasty. If a program + * needed sorted entries or stat information, they had better be + * checking FTS_NS on the returned nodes. + */ + cderrno = 0; + if (nlinks || type == BREAD) { + if (fts_safe_changedir(sp, cur, _dirfd(dirp), NULL)) { + if (nlinks && type == BREAD) + cur->fts_errno = errno; + cur->fts_flags |= FTS_DONTCHDIR; + descend = 0; + cderrno = errno; + } else + descend = 1; + } else + descend = 0; + + /* + * Figure out the max file name length that can be stored in the + * current path -- the inner loop allocates more path as necessary. + * We really wouldn't have to do the maxlen calculations here, we + * could do them in fts_read before returning the path, but it's a + * lot easier here since the length is part of the dirent structure. + * + * If not changing directories set a pointer so that can just append + * each new name into the path. + */ + len = NAPPEND(cur); + if (ISSET(FTS_NOCHDIR)) { + cp = sp->fts_path + len; + *cp++ = '/'; + } else { + /* GCC, you're too verbose. */ + cp = NULL; + } + len++; + maxlen = sp->fts_pathlen - len; + + level = cur->fts_level + 1; + + /* Read the directory, attaching each entry to the `link' pointer. */ + doadjust = 0; + for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) { + dnamlen = dp->d_namlen; + if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) + continue; + + if ((p = fts_alloc(sp, dp->d_name, (int)dnamlen)) == NULL) + goto mem1; + if (dnamlen >= maxlen) { /* include space for NUL */ + oldaddr = sp->fts_path; + if (fts_palloc(sp, dnamlen + len + 1)) { + /* + * No more memory for path or structures. Save + * errno, free up the current structure and the + * structures already allocated. + */ +mem1: saved_errno = errno; + if (p) + free(p); + fts_lfree(head); + (void)closedir(dirp); + cur->fts_info = FTS_ERR; + SET(FTS_STOP); + errno = saved_errno; + return (NULL); + } + /* Did realloc() change the pointer? */ + if (oldaddr != sp->fts_path) { + doadjust = 1; + if (ISSET(FTS_NOCHDIR)) + cp = sp->fts_path + len; + } + maxlen = sp->fts_pathlen - len; + } + + if (len + dnamlen >= USHRT_MAX) { + /* + * In an FTSENT, fts_pathlen is a u_short so it is + * possible to wraparound here. If we do, free up + * the current structure and the structures already + * allocated, then error out with ENAMETOOLONG. + */ + free(p); + fts_lfree(head); + (void)closedir(dirp); + cur->fts_info = FTS_ERR; + SET(FTS_STOP); + errno = ENAMETOOLONG; + return (NULL); + } + p->fts_level = level; + p->fts_parent = sp->fts_cur; + p->fts_pathlen = len + dnamlen; + +#ifdef FTS_WHITEOUT + if (dp->d_type == DT_WHT) + p->fts_flags |= FTS_ISW; +#endif + + if (cderrno) { + if (nlinks) { + p->fts_info = FTS_NS; + p->fts_errno = cderrno; + } else + p->fts_info = FTS_NSOK; + p->fts_accpath = cur->fts_accpath; + } else if (nlinks == 0 +#ifdef DT_DIR + || (nostat && + dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN) +#endif + ) { + p->fts_accpath = + ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name; + p->fts_info = FTS_NSOK; + } else { + /* Build a file name for fts_stat to stat. */ + if (ISSET(FTS_NOCHDIR)) { + p->fts_accpath = p->fts_path; + memmove(cp, p->fts_name, p->fts_namelen + 1); + } else + p->fts_accpath = p->fts_name; + /* Stat it. */ + p->fts_info = fts_stat(sp, p, 0); + + /* Decrement link count if applicable. */ + if (nlinks > 0 && (p->fts_info == FTS_D || + p->fts_info == FTS_DC || p->fts_info == FTS_DOT)) + --nlinks; + } + + /* We walk in directory order so "ls -f" doesn't get upset. */ + p->fts_link = NULL; + if (head == NULL) + head = tail = p; + else { + tail->fts_link = p; + tail = p; + } + ++nitems; + } + if (dirp) + (void)closedir(dirp); + + /* + * If realloc() changed the address of the path, adjust the + * addresses for the rest of the tree and the dir list. + */ + if (doadjust) + fts_padjust(sp, head); + + /* + * If not changing directories, reset the path back to original + * state. + */ + if (ISSET(FTS_NOCHDIR)) { + if (len == sp->fts_pathlen || nitems == 0) + --cp; + *cp = '\0'; + } + + /* + * If descended after called from fts_children or after called from + * fts_read and nothing found, get back. At the root level we use + * the saved fd; if one of fts_open()'s arguments is a relative path + * to an empty directory, we wind up here with no other way back. If + * can't get back, we're done. + */ + if (descend && (type == BCHILD || !nitems) && + (cur->fts_level == FTS_ROOTLEVEL ? + FCHDIR(sp, sp->fts_rfd) : + fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) { + cur->fts_info = FTS_ERR; + SET(FTS_STOP); + return (NULL); + } + + /* If didn't find anything, return NULL. */ + if (!nitems) { + if (type == BREAD) + cur->fts_info = FTS_DP; + return (NULL); + } + + /* Sort the entries. */ + if (sp->fts_compar && nitems > 1) + head = fts_sort(sp, head, nitems); + return (head); +} + +static u_short +fts_stat(FTS *sp, FTSENT *p, int follow) +{ + FTSENT *t; + dev_t dev; + ino_t ino; + struct stat *sbp, sb; + int saved_errno; + + /* If user needs stat info, stat buffer already allocated. */ + sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; + +#ifdef FTS_WHITEOUT + /* Check for whiteout. */ + if (p->fts_flags & FTS_ISW) { + if (sbp != &sb) { + memset(sbp, '\0', sizeof(*sbp)); + sbp->st_mode = S_IFWHT; + } + return (FTS_W); + } +#endif + + /* + * If doing a logical walk, or application requested FTS_FOLLOW, do + * a stat(2). If that fails, check for a non-existent symlink. If + * fail, set the errno from the stat call. + */ + if (ISSET(FTS_LOGICAL) || follow) { + if (stat(p->fts_accpath, sbp)) { + saved_errno = errno; + if (!lstat(p->fts_accpath, sbp)) { + errno = 0; + return (FTS_SLNONE); + } + p->fts_errno = saved_errno; + goto err; + } + } else if (lstat(p->fts_accpath, sbp)) { + p->fts_errno = errno; +err: memset(sbp, 0, sizeof(struct stat)); + return (FTS_NS); + } + + if (S_ISDIR(sbp->st_mode)) { + /* + * Set the device/inode. Used to find cycles and check for + * crossing mount points. Also remember the link count, used + * in fts_build to limit the number of stat calls. It is + * understood that these fields are only referenced if fts_info + * is set to FTS_D. + */ + dev = p->fts_dev = sbp->st_dev; + ino = p->fts_ino = sbp->st_ino; + p->fts_nlink = sbp->st_nlink; + + if (ISDOT(p->fts_name)) + return (FTS_DOT); + + /* + * Cycle detection is done by brute force when the directory + * is first encountered. If the tree gets deep enough or the + * number of symbolic links to directories is high enough, + * something faster might be worthwhile. + */ + for (t = p->fts_parent; + t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent) + if (ino == t->fts_ino && dev == t->fts_dev) { + p->fts_cycle = t; + return (FTS_DC); + } + return (FTS_D); + } + if (S_ISLNK(sbp->st_mode)) + return (FTS_SL); + if (S_ISREG(sbp->st_mode)) + return (FTS_F); + return (FTS_DEFAULT); +} + +/* + * The comparison function takes pointers to pointers to FTSENT structures. + * Qsort wants a comparison function that takes pointers to void. + * (Both with appropriate levels of const-poisoning, of course!) + * Use a trampoline function to deal with the difference. + */ +static int +fts_compar(const void *a, const void *b) +{ + FTS *parent; + + parent = (*(const FTSENT * const *)a)->fts_fts; + return (*parent->fts_compar)(a, b); +} + +static FTSENT * +fts_sort(FTS *sp, FTSENT *head, int nitems) +{ + FTSENT **ap, *p; + + /* + * Construct an array of pointers to the structures and call qsort(3). + * Reassemble the array in the order returned by qsort. If unable to + * sort for memory reasons, return the directory entries in their + * current order. Allocate enough space for the current needs plus + * 40 so don't realloc one entry at a time. + */ + if (nitems > sp->fts_nitems) { + sp->fts_nitems = nitems + 40; + if ((sp->fts_array = reallocf(sp->fts_array, + sp->fts_nitems * sizeof(FTSENT *))) == NULL) { + sp->fts_nitems = 0; + return (head); + } + } + for (ap = sp->fts_array, p = head; p; p = p->fts_link) + *ap++ = p; + qsort(sp->fts_array, nitems, sizeof(FTSENT *), fts_compar); + for (head = *(ap = sp->fts_array); --nitems; ++ap) + ap[0]->fts_link = ap[1]; + ap[0]->fts_link = NULL; + return (head); +} + +static FTSENT * +fts_alloc(FTS *sp, char *name, int namelen) +{ + FTSENT *p; + size_t len; + + struct ftsent_withstat { + FTSENT ent; + struct stat statbuf; + }; + + /* + * The file name is a variable length array and no stat structure is + * necessary if the user has set the nostat bit. Allocate the FTSENT + * structure, the file name and the stat structure in one chunk, but + * be careful that the stat structure is reasonably aligned. + */ + if (ISSET(FTS_NOSTAT)) + len = sizeof(FTSENT) + namelen + 1; + else + len = sizeof(struct ftsent_withstat) + namelen + 1; + + if ((p = malloc(len)) == NULL) + return (NULL); + + if (ISSET(FTS_NOSTAT)) { + p->fts_name = (char *)(p + 1); + p->fts_statp = NULL; + } else { + p->fts_name = (char *)((struct ftsent_withstat *)p + 1); + p->fts_statp = &((struct ftsent_withstat *)p)->statbuf; + } + + /* Copy the name and guarantee NUL termination. */ + memcpy(p->fts_name, name, namelen); + p->fts_name[namelen] = '\0'; + p->fts_namelen = namelen; + p->fts_path = sp->fts_path; + p->fts_errno = 0; + p->fts_flags = 0; + p->fts_instr = FTS_NOINSTR; + p->fts_number = 0; + p->fts_pointer = NULL; + p->fts_fts = sp; + return (p); +} + +static void +fts_lfree(FTSENT *head) +{ + FTSENT *p; + + /* Free a linked list of structures. */ + while ((p = head)) { + head = head->fts_link; + free(p); + } +} + +/* + * Allow essentially unlimited paths; find, rm, ls should all work on any tree. + * Most systems will allow creation of paths much longer than MAXPATHLEN, even + * though the kernel won't resolve them. Add the size (not just what's needed) + * plus 256 bytes so don't realloc the path 2 bytes at a time. + */ +static int +fts_palloc(FTS *sp, size_t more) +{ + + sp->fts_pathlen += more + 256; + /* + * Check for possible wraparound. In an FTS, fts_pathlen is + * a signed int but in an FTSENT it is an unsigned short. + * We limit fts_pathlen to USHRT_MAX to be safe in both cases. + */ + if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) { + if (sp->fts_path) + free(sp->fts_path); + sp->fts_path = NULL; + errno = ENAMETOOLONG; + return (1); + } + sp->fts_path = reallocf(sp->fts_path, sp->fts_pathlen); + return (sp->fts_path == NULL); +} + +/* + * When the path is realloc'd, have to fix all of the pointers in structures + * already returned. + */ +static void +fts_padjust(FTS *sp, FTSENT *head) +{ + FTSENT *p; + char *addr = sp->fts_path; + +#define ADJUST(p) do { \ + if ((p)->fts_accpath != (p)->fts_name) { \ + (p)->fts_accpath = \ + (char *)addr + ((p)->fts_accpath - (p)->fts_path); \ + } \ + (p)->fts_path = addr; \ +} while (0) + /* Adjust the current set of children. */ + for (p = sp->fts_child; p; p = p->fts_link) + ADJUST(p); + + /* Adjust the rest of the tree, including the current level. */ + for (p = head; p->fts_level >= FTS_ROOTLEVEL;) { + ADJUST(p); + p = p->fts_link ? p->fts_link : p->fts_parent; + } +} + +static size_t +fts_maxarglen(char * const *argv) +{ + size_t len, max; + + for (max = 0; *argv; ++argv) + if ((len = strlen(*argv)) > max) + max = len; + return (max + 1); +} + +/* + * Change to dir specified by fd or p->fts_accpath without getting + * tricked by someone changing the world out from underneath us. + * Assumes p->fts_dev and p->fts_ino are filled in. + */ +static int +fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path) +{ + int ret, oerrno, newfd; + struct stat sb; + + newfd = fd; + if (ISSET(FTS_NOCHDIR)) + return (0); + if (fd < 0 && (newfd = _open(path, O_RDONLY | O_CLOEXEC, 0)) < 0) + return (-1); + if (_fstat(newfd, &sb)) { + ret = -1; + goto bail; + } + if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) { + errno = ENOENT; /* disinformation */ + ret = -1; + goto bail; + } + ret = fchdir(newfd); +bail: + oerrno = errno; + if (fd < 0) + (void)_close(newfd); + errno = oerrno; + return (ret); +} + +/* + * Check if the filesystem for "ent" has UFS-style links. + */ +static int +fts_ufslinks(FTS *sp, const FTSENT *ent) +{ + struct _fts_private *priv; + const char **cpp; + + priv = (struct _fts_private *)sp; + /* + * If this node's device is different from the previous, grab + * the filesystem information, and decide on the reliability + * of the link information from this filesystem for stat(2) + * avoidance. + */ + if (priv->ftsp_dev != ent->fts_dev) { + if (statfs(ent->fts_path, &priv->ftsp_statfs) != -1) { + priv->ftsp_dev = ent->fts_dev; + priv->ftsp_linksreliable = 0; + for (cpp = ufslike_filesystems; *cpp; cpp++) { + if (strcmp(priv->ftsp_statfs.f_fstypename, + *cpp) == 0) { + priv->ftsp_linksreliable = 1; + break; + } + } + } else { + priv->ftsp_linksreliable = 0; + } + } + return (priv->ftsp_linksreliable); +} + +__sym_compat(fts_open, __fts_open_44bsd, FBSD_1.0); +__sym_compat(fts_close, __fts_close_44bsd, FBSD_1.0); +__sym_compat(fts_read, __fts_read_44bsd, FBSD_1.0); +__sym_compat(fts_set, __fts_set_44bsd, FBSD_1.0); +__sym_compat(fts_children, __fts_children_44bsd, FBSD_1.0); +__sym_compat(fts_get_clientptr, __fts_get_clientptr_44bsd, FBSD_1.0); +__sym_compat(fts_get_stream, __fts_get_stream_44bsd, FBSD_1.0); +__sym_compat(fts_set_clientptr, __fts_set_clientptr_44bsd, FBSD_1.0); diff --git a/lib/libc/gen/fts-compat.h b/lib/libc/gen/fts-compat.h new file mode 100644 index 0000000..1afa787 --- /dev/null +++ b/lib/libc/gen/fts-compat.h @@ -0,0 +1,128 @@ +/* + * 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. + * + * @(#)fts.h 8.3 (Berkeley) 8/14/94 + * $FreeBSD: releng/11.1/lib/libc/gen/fts-compat.h 251071 2013-05-28 21:05:06Z emaste $ + */ + +#ifndef _FTS_H_ +#define _FTS_H_ + +typedef struct { + struct _ftsent *fts_cur; /* current node */ + struct _ftsent *fts_child; /* linked list of children */ + struct _ftsent **fts_array; /* sort array */ + dev_t fts_dev; /* starting device # */ + char *fts_path; /* path for this descent */ + int fts_rfd; /* fd for root */ + int fts_pathlen; /* sizeof(path) */ + int fts_nitems; /* elements in the sort array */ + int (*fts_compar) /* compare function */ + (const struct _ftsent * const *, const struct _ftsent * const *); + +#define FTS_COMFOLLOW 0x001 /* follow command line symlinks */ +#define FTS_LOGICAL 0x002 /* logical walk */ +#define FTS_NOCHDIR 0x004 /* don't change directories */ +#define FTS_NOSTAT 0x008 /* don't get stat info */ +#define FTS_PHYSICAL 0x010 /* physical walk */ +#define FTS_SEEDOT 0x020 /* return dot and dot-dot */ +#define FTS_XDEV 0x040 /* don't cross devices */ +#define FTS_WHITEOUT 0x080 /* return whiteout information */ +#define FTS_OPTIONMASK 0x0ff /* valid user option mask */ + +#define FTS_NAMEONLY 0x100 /* (private) child names only */ +#define FTS_STOP 0x200 /* (private) unrecoverable error */ + int fts_options; /* fts_open options, global flags */ + void *fts_clientptr; /* thunk for sort function */ +} FTS; + +typedef struct _ftsent { + struct _ftsent *fts_cycle; /* cycle node */ + struct _ftsent *fts_parent; /* parent directory */ + struct _ftsent *fts_link; /* next file in directory */ + union { + struct { + long __fts_number; /* local numeric value */ + void *__fts_pointer; /* local address value */ + } __struct_ftsent; + int64_t __fts_bignum; + } __union_ftsent; +#define fts_number __union_ftsent.__struct_ftsent.__fts_number +#define fts_pointer __union_ftsent.__struct_ftsent.__fts_pointer +#define fts_bignum __union_ftsent.__fts_bignum + char *fts_accpath; /* access path */ + char *fts_path; /* root path */ + int fts_errno; /* errno for this node */ + int fts_symfd; /* fd for symlink */ + u_short fts_pathlen; /* strlen(fts_path) */ + u_short fts_namelen; /* strlen(fts_name) */ + + ino_t fts_ino; /* inode */ + dev_t fts_dev; /* device */ + nlink_t fts_nlink; /* link count */ + +#define FTS_ROOTPARENTLEVEL -1 +#define FTS_ROOTLEVEL 0 + short fts_level; /* depth (-1 to N) */ + +#define FTS_D 1 /* preorder directory */ +#define FTS_DC 2 /* directory that causes cycles */ +#define FTS_DEFAULT 3 /* none of the above */ +#define FTS_DNR 4 /* unreadable directory */ +#define FTS_DOT 5 /* dot or dot-dot */ +#define FTS_DP 6 /* postorder directory */ +#define FTS_ERR 7 /* error; errno is set */ +#define FTS_F 8 /* regular file */ +#define FTS_INIT 9 /* initialized only */ +#define FTS_NS 10 /* stat(2) failed */ +#define FTS_NSOK 11 /* no stat(2) requested */ +#define FTS_SL 12 /* symbolic link */ +#define FTS_SLNONE 13 /* symbolic link without target */ +#define FTS_W 14 /* whiteout object */ + u_short fts_info; /* user flags for FTSENT structure */ + +#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */ +#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */ +#define FTS_ISW 0x04 /* this is a whiteout object */ + u_short fts_flags; /* private flags for FTSENT structure */ + +#define FTS_AGAIN 1 /* read node again */ +#define FTS_FOLLOW 2 /* follow symbolic link */ +#define FTS_NOINSTR 3 /* no instructions */ +#define FTS_SKIP 4 /* discard node */ + u_short fts_instr; /* fts_set() instructions */ + + struct stat *fts_statp; /* stat(2) information */ + char *fts_name; /* file name */ + FTS *fts_fts; /* back pointer to main FTS */ +} FTSENT; + +#define fts_get_clientptr(fts) ((fts)->fts_clientptr) +#define fts_get_stream(ftsent) ((ftsent)->fts_fts) + +#endif /* !_FTS_H_ */ diff --git a/lib/libc/gen/fts.3 b/lib/libc/gen/fts.3 new file mode 100644 index 0000000..4a61f05 --- /dev/null +++ b/lib/libc/gen/fts.3 @@ -0,0 +1,803 @@ +.\" Copyright (c) 1989, 1991, 1993, 1994 +.\" 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. +.\" 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. +.\" +.\" @(#)fts.3 8.5 (Berkeley) 4/16/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/fts.3 260572 2014-01-12 20:47:08Z jilles $ +.\" +.Dd January 12, 2014 +.Dt FTS 3 +.Os +.Sh NAME +.Nm fts +.Nd traverse a file hierarchy +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In fts.h +.Ft FTS * +.Fn fts_open "char * const *path_argv" "int options" "int (*compar)(const FTSENT * const *, const FTSENT * const *)" +.Ft FTSENT * +.Fn fts_read "FTS *ftsp" +.Ft FTSENT * +.Fn fts_children "FTS *ftsp" "int options" +.Ft int +.Fn fts_set "FTS *ftsp" "FTSENT *f" "int options" +.Ft void +.Fn fts_set_clientptr "FTS *ftsp" "void *clientdata" +.Ft void * +.Fn fts_get_clientptr "FTS *ftsp" +.Ft FTS * +.Fn fts_get_stream "FTSENT *f" +.Ft int +.Fn fts_close "FTS *ftsp" +.Sh DESCRIPTION +The +.Nm +functions are provided for traversing +.Ux +file hierarchies. +A simple overview is that the +.Fn fts_open +function returns a +.Dq handle +on a file hierarchy, which is then supplied to +the other +.Nm +functions. +The function +.Fn fts_read +returns a pointer to a structure describing one of the files in the file +hierarchy. +The function +.Fn fts_children +returns a pointer to a linked list of structures, each of which describes +one of the files contained in a directory in the hierarchy. +In general, directories are visited two distinguishable times; in pre-order +(before any of their descendants are visited) and in post-order (after all +of their descendants have been visited). +Files are visited once. +It is possible to walk the hierarchy +.Dq logically +(ignoring symbolic links) +or physically (visiting symbolic links), order the walk of the hierarchy or +prune and/or re-visit portions of the hierarchy. +.Pp +Two structures are defined (and typedef'd) in the include file +.In fts.h . +The first is +.Vt FTS , +the structure that represents the file hierarchy itself. +The second is +.Vt FTSENT , +the structure that represents a file in the file +hierarchy. +Normally, an +.Vt FTSENT +structure is returned for every file in the file +hierarchy. +In this manual page, +.Dq file +and +.Dq Vt FTSENT No structure +are generally +interchangeable. +.Pp +The +.Vt FTS +structure contains space for a single pointer, which may be used to +store application data or per-hierarchy state. +The +.Fn fts_set_clientptr +and +.Fn fts_get_clientptr +functions may be used to set and retrieve this pointer. +This is likely to be useful only when accessed from the sort +comparison function, which can determine the original +.Vt FTS +stream of its arguments using the +.Fn fts_get_stream +function. +The two +.Li get +functions are also available as macros of the same name. +.Pp +The +.Vt FTSENT +structure contains at least the following fields, which are +described in greater detail below: +.Bd -literal +typedef struct _ftsent { + int fts_info; /* status for FTSENT structure */ + char *fts_accpath; /* access path */ + char *fts_path; /* root path */ + size_t fts_pathlen; /* strlen(fts_path) */ + char *fts_name; /* file name */ + size_t fts_namelen; /* strlen(fts_name) */ + long fts_level; /* depth (\-1 to N) */ + int fts_errno; /* file errno */ + long long fts_number; /* local numeric value */ + void *fts_pointer; /* local address value */ + struct ftsent *fts_parent; /* parent directory */ + struct ftsent *fts_link; /* next file structure */ + struct ftsent *fts_cycle; /* cycle structure */ + struct stat *fts_statp; /* stat(2) information */ +} FTSENT; +.Ed +.Pp +These fields are defined as follows: +.Bl -tag -width "fts_namelen" +.It Fa fts_info +One of the following values describing the returned +.Vt FTSENT +structure and +the file it represents. +With the exception of directories without errors +.Pq Dv FTS_D , +all of these +entries are terminal, that is, they will not be revisited, nor will any +of their descendants be visited. +.Bl -tag -width FTS_DEFAULT +.It Dv FTS_D +A directory being visited in pre-order. +.It Dv FTS_DC +A directory that causes a cycle in the tree. +(The +.Fa fts_cycle +field of the +.Vt FTSENT +structure will be filled in as well.) +.It Dv FTS_DEFAULT +Any +.Vt FTSENT +structure that represents a file type not explicitly described +by one of the other +.Fa fts_info +values. +.It Dv FTS_DNR +A directory which cannot be read. +This is an error return, and the +.Fa fts_errno +field will be set to indicate what caused the error. +.It Dv FTS_DOT +A file named +.Ql .\& +or +.Ql ..\& +which was not specified as a file name to +.Fn fts_open +(see +.Dv FTS_SEEDOT ) . +.It Dv FTS_DP +A directory being visited in post-order. +The contents of the +.Vt FTSENT +structure will be unchanged from when +the directory was visited in pre-order, except for the +.Fa fts_info +field. +.It Dv FTS_ERR +This is an error return, and the +.Fa fts_errno +field will be set to indicate what caused the error. +.It Dv FTS_F +A regular file. +.It Dv FTS_NS +A file for which no +.Xr stat 2 +information was available. +The contents of the +.Fa fts_statp +field are undefined. +This is an error return, and the +.Fa fts_errno +field will be set to indicate what caused the error. +.It Dv FTS_NSOK +A file for which no +.Xr stat 2 +information was requested. +The contents of the +.Fa fts_statp +field are undefined. +.It Dv FTS_SL +A symbolic link. +.It Dv FTS_SLNONE +A symbolic link with a non-existent target. +The contents of the +.Fa fts_statp +field reference the file characteristic information for the symbolic link +itself. +.El +.It Fa fts_accpath +A path for accessing the file from the current directory. +.It Fa fts_path +The path for the file relative to the root of the traversal. +This path contains the path specified to +.Fn fts_open +as a prefix. +.It Fa fts_pathlen +The length of the string referenced by +.Fa fts_path . +.It Fa fts_name +The name of the file. +.It Fa fts_namelen +The length of the string referenced by +.Fa fts_name . +.It Fa fts_level +The depth of the traversal, numbered from \-1 to N, where this file +was found. +The +.Vt FTSENT +structure representing the parent of the starting point (or root) +of the traversal is numbered +.Dv FTS_ROOTPARENTLEVEL +(\-1), and the +.Vt FTSENT +structure for the root +itself is numbered +.Dv FTS_ROOTLEVEL +(0). +.It Fa fts_errno +Upon return of a +.Vt FTSENT +structure from the +.Fn fts_children +or +.Fn fts_read +functions, with its +.Fa fts_info +field set to +.Dv FTS_DNR , +.Dv FTS_ERR +or +.Dv FTS_NS , +the +.Fa fts_errno +field contains the value of the external variable +.Va errno +specifying the cause of the error. +Otherwise, the contents of the +.Fa fts_errno +field are undefined. +.It Fa fts_number +This field is provided for the use of the application program and is +not modified by the +.Nm +functions. +It is initialized to 0. +.It Fa fts_pointer +This field is provided for the use of the application program and is +not modified by the +.Nm +functions. +It is initialized to +.Dv NULL . +.It Fa fts_parent +A pointer to the +.Vt FTSENT +structure referencing the file in the hierarchy +immediately above the current file, i.e., the directory of which this +file is a member. +A parent structure for the initial entry point is provided as well, +however, only the +.Fa fts_level , +.Fa fts_number +and +.Fa fts_pointer +fields are guaranteed to be initialized. +.It Fa fts_link +Upon return from the +.Fn fts_children +function, the +.Fa fts_link +field points to the next structure in the NULL-terminated linked list of +directory members. +Otherwise, the contents of the +.Fa fts_link +field are undefined. +.It Fa fts_cycle +If a directory causes a cycle in the hierarchy (see +.Dv FTS_DC ) , +either because +of a hard link between two directories, or a symbolic link pointing to a +directory, the +.Fa fts_cycle +field of the structure will point to the +.Vt FTSENT +structure in the hierarchy that references the same file as the current +.Vt FTSENT +structure. +Otherwise, the contents of the +.Fa fts_cycle +field are undefined. +.It Fa fts_statp +A pointer to +.Xr stat 2 +information for the file. +.El +.Pp +A single buffer is used for all of the paths of all of the files in the +file hierarchy. +Therefore, the +.Fa fts_path +and +.Fa fts_accpath +fields are guaranteed to be +.Dv NUL Ns -terminated +.Em only +for the file most recently returned by +.Fn fts_read . +To use these fields to reference any files represented by other +.Vt FTSENT +structures will require that the path buffer be modified using the +information contained in that +.Vt FTSENT +structure's +.Fa fts_pathlen +field. +Any such modifications should be undone before further calls to +.Fn fts_read +are attempted. +The +.Fa fts_name +field is always +.Dv NUL Ns -terminated . +.Sh FTS_OPEN +The +.Fn fts_open +function takes a pointer to an array of character pointers naming one +or more paths which make up a logical file hierarchy to be traversed. +The array must be terminated by a +.Dv NULL +pointer. +.Pp +There are +a number of options, at least one of which (either +.Dv FTS_LOGICAL +or +.Dv FTS_PHYSICAL ) +must be specified. +The options are selected by +.Em or Ns 'ing +the following values: +.Bl -tag -width "FTS_PHYSICAL" +.It Dv FTS_COMFOLLOW +This option causes any symbolic link specified as a root path to be +followed immediately whether or not +.Dv FTS_LOGICAL +is also specified. +.It Dv FTS_LOGICAL +This option causes the +.Nm +routines to return +.Vt FTSENT +structures for the targets of symbolic links +instead of the symbolic links themselves. +If this option is set, the only symbolic links for which +.Vt FTSENT +structures +are returned to the application are those referencing non-existent files. +Either +.Dv FTS_LOGICAL +or +.Dv FTS_PHYSICAL +.Em must +be provided to the +.Fn fts_open +function. +.It Dv FTS_NOCHDIR +To allow descending to arbitrary depths +(independent of +.Brq Dv PATH_MAX ) +and improve performance, the +.Nm +functions change directories as they walk the file hierarchy. +This has the side-effect that an application cannot rely on being +in any particular directory during the traversal. +The +.Dv FTS_NOCHDIR +option turns off this feature, and the +.Nm +functions will not change the current directory. +Note that applications should not themselves change their current directory +and try to access files unless +.Dv FTS_NOCHDIR +is specified and absolute +pathnames were provided as arguments to +.Fn fts_open . +.It Dv FTS_NOSTAT +By default, returned +.Vt FTSENT +structures reference file characteristic information (the +.Fa statp +field) for each file visited. +This option relaxes that requirement as a performance optimization, +allowing the +.Nm +functions to set the +.Fa fts_info +field to +.Dv FTS_NSOK +and leave the contents of the +.Fa statp +field undefined. +.It Dv FTS_PHYSICAL +This option causes the +.Nm +routines to return +.Vt FTSENT +structures for symbolic links themselves instead +of the target files they point to. +If this option is set, +.Vt FTSENT +structures for all symbolic links in the +hierarchy are returned to the application. +Either +.Dv FTS_LOGICAL +or +.Dv FTS_PHYSICAL +.Em must +be provided to the +.Fn fts_open +function. +.It Dv FTS_SEEDOT +By default, unless they are specified as path arguments to +.Fn fts_open , +any files named +.Ql .\& +or +.Ql ..\& +encountered in the file hierarchy are ignored. +This option causes the +.Nm +routines to return +.Vt FTSENT +structures for them. +.It Dv FTS_XDEV +This option prevents +.Nm +from descending into directories that have a different device number +than the file from which the descent began. +.El +.Pp +The argument +.Fn compar +specifies a user-defined function which may be used to order the traversal +of the hierarchy. +It +takes two pointers to pointers to +.Vt FTSENT +structures as arguments and +should return a negative value, zero, or a positive value to indicate +if the file referenced by its first argument comes before, in any order +with respect to, or after, the file referenced by its second argument. +The +.Fa fts_accpath , +.Fa fts_path +and +.Fa fts_pathlen +fields of the +.Vt FTSENT +structures may +.Em never +be used in this comparison. +If the +.Fa fts_info +field is set to +.Dv FTS_NS +or +.Dv FTS_NSOK , +the +.Fa fts_statp +field may not either. +If the +.Fn compar +argument is +.Dv NULL , +the directory traversal order is in the order listed in +.Fa path_argv +for the root paths, and in the order listed in the directory for +everything else. +.Sh FTS_READ +The +.Fn fts_read +function returns a pointer to an +.Vt FTSENT +structure describing a file in +the hierarchy. +Directories (that are readable and do not cause cycles) are visited at +least twice, once in pre-order and once in post-order. +All other files are visited at least once. +(Hard links between directories that do not cause cycles or symbolic +links to symbolic links may cause files to be visited more than once, +or directories more than twice.) +.Pp +If all the members of the hierarchy have been returned, +.Fn fts_read +returns +.Dv NULL +and sets the external variable +.Va errno +to 0. +If an error unrelated to a file in the hierarchy occurs, +.Fn fts_read +returns +.Dv NULL +and sets +.Va errno +appropriately. +If an error related to a returned file occurs, a pointer to an +.Vt FTSENT +structure is returned, and +.Va errno +may or may not have been set (see +.Fa fts_info ) . +.Pp +The +.Vt FTSENT +structures returned by +.Fn fts_read +may be overwritten after a call to +.Fn fts_close +on the same file hierarchy stream, or, after a call to +.Fn fts_read +on the same file hierarchy stream unless they represent a file of type +directory, in which case they will not be overwritten until after a call to +.Fn fts_read +after the +.Vt FTSENT +structure has been returned by the function +.Fn fts_read +in post-order. +.Sh FTS_CHILDREN +The +.Fn fts_children +function returns a pointer to an +.Vt FTSENT +structure describing the first entry in a NULL-terminated linked list of +the files in the directory represented by the +.Vt FTSENT +structure most recently returned by +.Fn fts_read . +The list is linked through the +.Fa fts_link +field of the +.Vt FTSENT +structure, and is ordered by the user-specified comparison function, if any. +Repeated calls to +.Fn fts_children +will recreate this linked list. +.Pp +As a special case, if +.Fn fts_read +has not yet been called for a hierarchy, +.Fn fts_children +will return a pointer to the files in the logical directory specified to +.Fn fts_open , +i.e., the arguments specified to +.Fn fts_open . +Otherwise, if the +.Vt FTSENT +structure most recently returned by +.Fn fts_read +is not a directory being visited in pre-order, +or the directory does not contain any files, +.Fn fts_children +returns +.Dv NULL +and sets +.Va errno +to zero. +If an error occurs, +.Fn fts_children +returns +.Dv NULL +and sets +.Va errno +appropriately. +.Pp +The +.Vt FTSENT +structures returned by +.Fn fts_children +may be overwritten after a call to +.Fn fts_children , +.Fn fts_close +or +.Fn fts_read +on the same file hierarchy stream. +.Pp +.Em Option +may be set to the following value: +.Bl -tag -width FTS_NAMEONLY +.It Dv FTS_NAMEONLY +Only the names of the files are needed. +The contents of all the fields in the returned linked list of structures +are undefined with the exception of the +.Fa fts_name +and +.Fa fts_namelen +fields. +.El +.Sh FTS_SET +The function +.Fn fts_set +allows the user application to determine further processing for the +file +.Fa f +of the stream +.Fa ftsp . +The +.Fn fts_set +function +returns 0 on success, and \-1 if an error occurs. +.Em Option +must be set to one of the following values: +.Bl -tag -width FTS_PHYSICAL +.It Dv FTS_AGAIN +Re-visit the file; any file type may be re-visited. +The next call to +.Fn fts_read +will return the referenced file. +The +.Fa fts_stat +and +.Fa fts_info +fields of the structure will be reinitialized at that time, +but no other fields will have been changed. +This option is meaningful only for the most recently returned +file from +.Fn fts_read . +Normal use is for post-order directory visits, where it causes the +directory to be re-visited (in both pre and post-order) as well as all +of its descendants. +.It Dv FTS_FOLLOW +The referenced file must be a symbolic link. +If the referenced file is the one most recently returned by +.Fn fts_read , +the next call to +.Fn fts_read +returns the file with the +.Fa fts_info +and +.Fa fts_statp +fields reinitialized to reflect the target of the symbolic link instead +of the symbolic link itself. +If the file is one of those most recently returned by +.Fn fts_children , +the +.Fa fts_info +and +.Fa fts_statp +fields of the structure, when returned by +.Fn fts_read , +will reflect the target of the symbolic link instead of the symbolic link +itself. +In either case, if the target of the symbolic link does not exist the +fields of the returned structure will be unchanged and the +.Fa fts_info +field will be set to +.Dv FTS_SLNONE . +.Pp +If the target of the link is a directory, the pre-order return, followed +by the return of all of its descendants, followed by a post-order return, +is done. +.It Dv FTS_SKIP +No descendants of this file are visited. +The file may be one of those most recently returned by either +.Fn fts_children +or +.Fn fts_read . +.El +.Sh FTS_CLOSE +The +.Fn fts_close +function closes a file hierarchy stream +.Fa ftsp +and restores the current directory to the directory from which +.Fn fts_open +was called to open +.Fa ftsp . +The +.Fn fts_close +function +returns 0 on success, and \-1 if an error occurs. +.Sh ERRORS +The function +.Fn fts_open +may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr open 2 +and +.Xr malloc 3 . +.Pp +The function +.Fn fts_close +may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr chdir 2 +and +.Xr close 2 . +.Pp +The functions +.Fn fts_read +and +.Fn fts_children +may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr chdir 2 , +.Xr malloc 3 , +.Xr opendir 3 , +.Xr readdir 3 +and +.Xr stat 2 . +.Pp +In addition, +.Fn fts_children , +.Fn fts_open +and +.Fn fts_set +may fail and set +.Va errno +as follows: +.Bl -tag -width Er +.It Bq Er EINVAL +The options were invalid, or the list were empty. +.El +.Sh SEE ALSO +.Xr find 1 , +.Xr chdir 2 , +.Xr stat 2 , +.Xr ftw 3 , +.Xr qsort 3 +.Sh HISTORY +The +.Nm +interface was first introduced in +.Bx 4.4 . +The +.Fn fts_get_clientptr , +.Fn fts_get_stream , +and +.Fn fts_set_clientptr +functions were introduced in +.Fx 5.0 , +principally to provide for alternative interfaces to the +.Nm +functionality using different data structures. +.Sh BUGS +The +.Fn fts_open +function will automatically set the +.Dv FTS_NOCHDIR +option if the +.Dv FTS_LOGICAL +option is provided, or if it cannot +.Xr open 2 +the current directory. diff --git a/lib/libc/gen/ftw.3 b/lib/libc/gen/ftw.3 new file mode 100644 index 0000000..0c5ae27 --- /dev/null +++ b/lib/libc/gen/ftw.3 @@ -0,0 +1,218 @@ +.\" $OpenBSD: ftw.3,v 1.5 2004/01/25 14:48:32 jmc Exp $ +.\" +.\" Copyright (c) 2003 Todd C. Miller +.\" +.\" 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. +.\" +.\" Sponsored in part by the Defense Advanced Research Projects +.\" Agency (DARPA) and Air Force Research Laboratory, Air Force +.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/ftw.3 276006 2014-12-21 12:36:36Z brueffer $ +.\" +.Dd July 5, 2004 +.Dt FTW 3 +.Os +.Sh NAME +.Nm ftw , nftw +.Nd traverse (walk) a file tree +.Sh SYNOPSIS +.In ftw.h +.Ft int +.Fo ftw +.Fa "const char *path" +.Fa "int \*[lp]*fn\*[rp]\*[lp]const char *, const struct stat *, int\*[rp]" +.Fa "int maxfds" +.Fc +.Ft int +.Fo nftw +.Fa "const char *path" +.Fa "int \*[lp]*fn\*[rp]\*[lp]const char *, const struct stat *, int, struct FTW *\*[rp]" +.Fa "int maxfds" +.Fa "int flags" +.Fc +.Sh DESCRIPTION +The +.Fn ftw +and +.Fn nftw +functions traverse (walk) the directory hierarchy rooted in +.Fa path . +For each object in the hierarchy, these functions call the function +pointed to by +.Fa fn . +The +.Fn ftw +function passes this function a pointer to a +.Dv NUL Ns +-terminated string containing +the name of the object, a pointer to a +.Vt stat +structure corresponding to the +object, and an integer flag. +The +.Fn nftw +function passes the aforementioned arguments plus a pointer to a +.Vt FTW +structure as defined by +.In ftw.h +(shown below): +.Bd -literal +struct FTW { + int base; /* offset of basename into pathname */ + int level; /* directory depth relative to starting point */ +}; +.Ed +.Pp +Possible values for the flag passed to +.Fa fn +are: +.Bl -tag -width ".Dv FTW_DNR" +.It Dv FTW_F +A regular file. +.It Dv FTW_D +A directory being visited in pre-order. +.It Dv FTW_DNR +A directory which cannot be read. +The directory will not be descended into. +.It Dv FTW_DP +A directory being visited in post-order +.Po Fn nftw +only +.Pc . +.It Dv FTW_NS +A file for which no +.Xr stat 2 +information was available. +The contents of the +.Vt stat +structure are undefined. +.It Dv FTW_SL +A symbolic link. +.It Dv FTW_SLN +A symbolic link with a non-existent target +.Po Fn nftw +only +.Pc . +.El +.Pp +The +.Fn ftw +function traverses the tree in pre-order. +That is, it processes the directory before the directory's contents. +.Pp +The +.Fa maxfds +argument specifies the maximum number of file descriptors +to keep open while traversing the tree. +It has no effect in this implementation. +.Pp +The +.Fn nftw +function has an additional +.Fa flags +argument with the following possible values: +.Bl -tag -width ".Dv FTW_MOUNT" +.It Dv FTW_PHYS +Physical walk, do not follow symbolic links. +.It Dv FTW_MOUNT +The walk will not cross a mount point. +.It FTW_DEPTH +Process directories in post-order. +Contents of a directory are visited before the directory itself. +By default, +.Fn nftw +traverses the tree in pre-order. +.It FTW_CHDIR +Change to a directory before reading it. +By default, +.Fn nftw +will change its starting directory. +The current working directory will be restored to its original value before +.Fn nftw +returns. +.El +.Sh RETURN VALUES +If the tree was traversed successfully, the +.Fn ftw +and +.Fn nftw +functions return 0. +If the function pointed to by +.Fa fn +returns a non-zero value, +.Fn ftw +and +.Fn nftw +will stop processing the tree and return the value from +.Fa fn . +Both functions return \-1 if an error is detected. +.Sh ERRORS +The +.Fn ftw +and +.Fn nftw +functions may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr close 2 , +.Xr open 2 , +.Xr stat 2 , +.Xr malloc 3 , +.Xr opendir 3 +and +.Xr readdir 3 . +If the +.Dv FTW_CHDIR +flag is set, the +.Fn nftw +function may fail and set +.Va errno +for any of the errors specified for +.Xr chdir 2 . +In addition, either function may fail and set +.Va errno +as follows: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa maxfds +argument is less than 1. +.El +.Sh SEE ALSO +.Xr chdir 2 , +.Xr close 2 , +.Xr open 2 , +.Xr stat 2 , +.Xr fts 3 , +.Xr malloc 3 , +.Xr opendir 3 , +.Xr readdir 3 +.Sh STANDARDS +The +.Fn ftw +and +.Fn nftw +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +These functions first appeared in +.At V.3 . +Their first +.Fx +appearance was in +.Fx 5.3 . +.Sh BUGS +The +.Fa maxfds +argument is currently ignored. diff --git a/lib/libc/gen/gen-private.h b/lib/libc/gen/gen-private.h new file mode 100644 index 0000000..64ae1d2 --- /dev/null +++ b/lib/libc/gen/gen-private.h @@ -0,0 +1,58 @@ +/*- + * 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. + * + * $FreeBSD: releng/11.1/lib/libc/gen/gen-private.h 268531 2014-07-11 16:16:26Z jhb $ + */ + +#ifndef _GEN_PRIVATE_H_ +#define _GEN_PRIVATE_H_ + +struct _telldir; /* see telldir.h */ +struct pthread_mutex; + +/* + * Structure describing an open directory. + * + * NOTE. Change structure layout with care, at least dd_fd field has to + * remain unchanged to guarantee backward compatibility. + */ +struct _dirdesc { + int dd_fd; /* file descriptor associated with directory */ + long dd_loc; /* offset in current buffer */ + long dd_size; /* amount of data returned by getdirentries */ + char *dd_buf; /* data buffer */ + int dd_len; /* size of data buffer */ + long dd_seek; /* magic cookie returned by getdirentries */ + int dd_flags; /* flags for readdir */ + struct pthread_mutex *dd_lock; /* lock */ + struct _telldir *dd_td; /* telldir position recording */ +}; + +#define _dirfd(dirp) ((dirp)->dd_fd) + +#endif /* !_GEN_PRIVATE_H_ */ diff --git a/lib/libc/gen/getbootfile.3 b/lib/libc/gen/getbootfile.3 new file mode 100644 index 0000000..74fe596 --- /dev/null +++ b/lib/libc/gen/getbootfile.3 @@ -0,0 +1,69 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" From: @(#)gethostname.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getbootfile.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd September 23, 1994 +.Dt GETBOOTFILE 3 +.Os +.Sh NAME +.Nm getbootfile +.Nd get kernel boot file name +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In paths.h +.Ft const char * +.Fn getbootfile void +.Sh DESCRIPTION +The +.Fn getbootfile +function retrieves the full pathname of the file from which the +current kernel was loaded, and returns a static pointer to the name. +A read/write interface to this information is available via the +.Xr sysctl 3 +MIB variable +.Dq Li kern.bootfile . +.Sh RETURN VALUES +If the call succeeds a string giving the pathname is returned. +If it +fails, a null pointer is returned and an error code is +placed in the global location +.Va errno . +.Sh SEE ALSO +.Xr sysctl 3 +.Sh HISTORY +The +.Fn getbootfile +function appeared in +.Fx 2.0 . +.Sh BUGS +If the boot blocks have not been modified to pass this information into +the kernel at boot time, the static string +.Dq Pa /boot/kernel/kernel +is returned instead of the real boot file. diff --git a/lib/libc/gen/getbsize.3 b/lib/libc/gen/getbsize.3 new file mode 100644 index 0000000..85bed2d --- /dev/null +++ b/lib/libc/gen/getbsize.3 @@ -0,0 +1,94 @@ +.\" 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 +.\" 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. +.\" 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. +.\" +.\" @(#)getbsize.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getbsize.3 243146 2012-11-16 12:03:50Z joel $ +.\" +.Dd November 16, 2012 +.Dt GETBSIZE 3 +.Os +.Sh NAME +.Nm getbsize +.Nd get preferred block size +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft char * +.Fn getbsize "int *headerlenp" "long *blocksizep" +.Sh DESCRIPTION +The +.Fn getbsize +function returns a preferred block size for reporting by system utilities +.Xr df 1 , +.Xr du 1 , +.Xr ls 1 +and +.Xr systat 1 , +based on the value of the +.Ev BLOCKSIZE +environment variable. +.Ev BLOCKSIZE +may be specified directly in bytes, or in multiples of a kilobyte by +specifying a number followed by ``K'' or ``k'', in multiples of a +megabyte by specifying a number followed by ``M'' or ``m'' or in +multiples of a gigabyte by specifying a number followed by ``G'' or +``g''. +Multiples must be integers. +.Pp +Valid values of +.Ev BLOCKSIZE +are 512 bytes to 1 gigabyte. +Sizes less than 512 bytes are rounded up to 512 bytes, and sizes +greater than 1 GB are rounded down to 1 GB. +In each case +.Fn getbsize +produces a warning message. +.Pp +The +.Fn getbsize +function returns a pointer to a null-terminated string describing +the block size, something like +.Dq 1K-blocks . +The memory referenced by +.Fa headerlenp +is filled in with the length of the string (not including the +terminating null). +The memory referenced by +.Fa blocksizep +is filled in with block size, in bytes. +.Sh SEE ALSO +.Xr df 1 , +.Xr du 1 , +.Xr ls 1 , +.Xr systat 1 , +.Xr environ 7 +.Sh HISTORY +The +.Fn getbsize +function first appeared in +.Bx 4.4 . diff --git a/lib/libc/gen/getcap.3 b/lib/libc/gen/getcap.3 new file mode 100644 index 0000000..5ec4b6e --- /dev/null +++ b/lib/libc/gen/getcap.3 @@ -0,0 +1,569 @@ +.\" Copyright (c) 1992, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Casey Leedom of Lawrence Livermore National Laboratory. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)getcap.3 8.4 (Berkeley) 5/13/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getcap.3 276006 2014-12-21 12:36:36Z brueffer $ +.\" +.Dd March 22, 2002 +.Dt GETCAP 3 +.Os +.Sh NAME +.Nm cgetent , +.Nm cgetset , +.Nm cgetmatch , +.Nm cgetcap , +.Nm cgetnum , +.Nm cgetstr , +.Nm cgetustr , +.Nm cgetfirst , +.Nm cgetnext , +.Nm cgetclose +.Nd capability database access routines +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fn cgetent "char **buf" "char **db_array" "const char *name" +.Ft int +.Fn cgetset "const char *ent" +.Ft int +.Fn cgetmatch "const char *buf" "const char *name" +.Ft char * +.Fn cgetcap "char *buf" "const char *cap" "int type" +.Ft int +.Fn cgetnum "char *buf" "const char *cap" "long *num" +.Ft int +.Fn cgetstr "char *buf" "const char *cap" "char **str" +.Ft int +.Fn cgetustr "char *buf" "const char *cap" "char **str" +.Ft int +.Fn cgetfirst "char **buf" "char **db_array" +.Ft int +.Fn cgetnext "char **buf" "char **db_array" +.Ft int +.Fn cgetclose "void" +.Sh DESCRIPTION +The +.Fn cgetent +function extracts the capability +.Fa name +from the database specified by the +.Dv NULL +terminated file array +.Fa db_array +and returns a pointer to a +.Xr malloc 3 Ns \&'d +copy of it in +.Fa buf . +The +.Fn cgetent +function will first look for files ending in +.Pa .db +(see +.Xr cap_mkdb 1 ) +before accessing the ASCII file. +The +.Fa buf +argument +must be retained through all subsequent calls to +.Fn cgetmatch , +.Fn cgetcap , +.Fn cgetnum , +.Fn cgetstr , +and +.Fn cgetustr , +but may then be +.Xr free 3 Ns \&'d . +On success 0 is returned, 1 if the returned +record contains an unresolved +.Ic tc +expansion, +\-1 if the requested record could not be found, +\-2 if a system error was encountered (could not open/read a file, etc.) also +setting +.Va errno , +and \-3 if a potential reference loop is detected (see +.Ic tc= +comments below). +.Pp +The +.Fn cgetset +function enables the addition of a character buffer containing a single capability +record entry +to the capability database. +Conceptually, the entry is added as the first ``file'' in the database, and +is therefore searched first on the call to +.Fn cgetent . +The entry is passed in +.Fa ent . +If +.Fa ent +is +.Dv NULL , +the current entry is removed from the database. +A call to +.Fn cgetset +must precede the database traversal. +It must be called before the +.Fn cgetent +call. +If a sequential access is being performed (see below), it must be called +before the first sequential access call +.Po Fn cgetfirst +or +.Fn cgetnext +.Pc , +or be directly preceded by a +.Fn cgetclose +call. +On success 0 is returned and \-1 on failure. +.Pp +The +.Fn cgetmatch +function will return 0 if +.Fa name +is one of the names of the capability record +.Fa buf , +\-1 if +not. +.Pp +The +.Fn cgetcap +function searches the capability record +.Fa buf +for the capability +.Fa cap +with type +.Fa type . +A +.Fa type +is specified using any single character. +If a colon (`:') is used, an +untyped capability will be searched for (see below for explanation of +types). +A pointer to the value of +.Fa cap +in +.Fa buf +is returned on success, +.Dv NULL +if the requested capability could not be +found. +The end of the capability value is signaled by a `:' or +.Tn ASCII +.Dv NUL +(see below for capability database syntax). +.Pp +The +.Fn cgetnum +function retrieves the value of the numeric capability +.Fa cap +from the capability record pointed to by +.Fa buf . +The numeric value is returned in the +.Ft long +pointed to by +.Fa num . +0 is returned on success, \-1 if the requested numeric capability could not +be found. +.Pp +The +.Fn cgetstr +function retrieves the value of the string capability +.Fa cap +from the capability record pointed to by +.Fa buf . +A pointer to a decoded, +.Dv NUL +terminated, +.Xr malloc 3 Ns \&'d +copy of the string is returned in the +.Ft char * +pointed to by +.Fa str . +The number of characters in the decoded string not including the trailing +.Dv NUL +is returned on success, \-1 if the requested string capability could not +be found, \-2 if a system error was encountered (storage allocation +failure). +.Pp +The +.Fn cgetustr +function is identical to +.Fn cgetstr +except that it does not expand special characters, but rather returns each +character of the capability string literally. +.Pp +The +.Fn cgetfirst +and +.Fn cgetnext +functions comprise a function group that provides for sequential +access of the +.Dv NULL +pointer terminated array of file names, +.Fa db_array . +The +.Fn cgetfirst +function returns the first record in the database and resets the access +to the first record. +The +.Fn cgetnext +function returns the next record in the database with respect to the +record returned by the previous +.Fn cgetfirst +or +.Fn cgetnext +call. +If there is no such previous call, the first record in the database is +returned. +Each record is returned in a +.Xr malloc 3 Ns \&'d +copy pointed to by +.Fa buf . +.Ic Tc +expansion is done (see +.Ic tc= +comments below). +Upon completion of the database 0 is returned, 1 is returned upon successful +return of record with possibly more remaining (we have not reached the end of +the database yet), 2 is returned if the record contains an unresolved +.Ic tc +expansion, \-1 is returned if a system error occurred, and \-2 +is returned if a potential reference loop is detected (see +.Ic tc= +comments below). +Upon completion of database (0 return) the database is closed. +.Pp +The +.Fn cgetclose +function closes the sequential access and frees any memory and file descriptors +being used. +Note that it does not erase the buffer pushed by a call to +.Fn cgetset . +.Sh CAPABILITY DATABASE SYNTAX +Capability databases are normally +.Tn ASCII +and may be edited with standard +text editors. +Blank lines and lines beginning with a `#' are comments +and are ignored. +Lines ending with a `\|\e' indicate that the next line +is a continuation of the current line; the `\|\e' and following newline +are ignored. +Long lines are usually continued onto several physical +lines by ending each line except the last with a `\|\e'. +.Pp +Capability databases consist of a series of records, one per logical +line. +Each record contains a variable number of `:'-separated fields +(capabilities). +Empty fields consisting entirely of white space +characters (spaces and tabs) are ignored. +.Pp +The first capability of each record specifies its names, separated by `|' +characters. +These names are used to reference records in the database. +By convention, the last name is usually a comment and is not intended as +a lookup tag. +For example, the +.Em vt100 +record from the +.Xr termcap 5 +database begins: +.Pp +.Dl "d0\||\|vt100\||\|vt100-am\||\|vt100am\||\|dec vt100:" +.Pp +giving four names that can be used to access the record. +.Pp +The remaining non-empty capabilities describe a set of (name, value) +bindings, consisting of a names optionally followed by a typed value: +.Pp +.Bl -tag -width "nameTvalue" -compact +.It name +typeless [boolean] capability +.Em name No "is present [true]" +.It name Ns Em \&T Ns value +capability +.Pq Em name , \&T +has value +.Em value +.It name@ +no capability +.Em name No exists +.It name Ns Em T Ns \&@ +capability +.Pq Em name , T +does not exist +.El +.Pp +Names consist of one or more characters. +Names may contain any character +except `:', but it is usually best to restrict them to the printable +characters and avoid use of graphics like `#', `=', `%', `@', etc. +Types +are single characters used to separate capability names from their +associated typed values. +Types may be any character except a `:'. +Typically, graphics like `#', `=', `%', etc.\& are used. +Values may be any +number of characters and may contain any character except `:'. +.Sh CAPABILITY DATABASE SEMANTICS +Capability records describe a set of (name, value) bindings. +Names may +have multiple values bound to them. +Different values for a name are +distinguished by their +.Fa types . +The +.Fn cgetcap +function will return a pointer to a value of a name given the capability +name and the type of the value. +.Pp +The types `#' and `=' are conventionally used to denote numeric and +string typed values, but no restriction on those types is enforced. +The +functions +.Fn cgetnum +and +.Fn cgetstr +can be used to implement the traditional syntax and semantics of `#' +and `='. +Typeless capabilities are typically used to denote boolean objects with +presence or absence indicating truth and false values respectively. +This interpretation is conveniently represented by: +.Pp +.Dl "(getcap(buf, name, ':') != NULL)" +.Pp +A special capability, +.Ic tc= name , +is used to indicate that the record specified by +.Fa name +should be substituted for the +.Ic tc +capability. +.Ic Tc +capabilities may interpolate records which also contain +.Ic tc +capabilities and more than one +.Ic tc +capability may be used in a record. +A +.Ic tc +expansion scope (i.e., where the argument is searched for) contains the +file in which the +.Ic tc +is declared and all subsequent files in the file array. +.Pp +When a database is searched for a capability record, the first matching +record in the search is returned. +When a record is scanned for a +capability, the first matching capability is returned; the capability +.Ic :nameT@: +will hide any following definition of a value of type +.Em T +for +.Fa name ; +and the capability +.Ic :name@: +will prevent any following values of +.Fa name +from being seen. +.Pp +These features combined with +.Ic tc +capabilities can be used to generate variations of other databases and +records by either adding new capabilities, overriding definitions with new +definitions, or hiding following definitions via `@' capabilities. +.Sh EXAMPLES +.Bd -unfilled -offset indent +example\||\|an example of binding multiple values to names:\e + :foo%bar:foo^blah:foo@:\e + :abc%xyz:abc^frap:abc$@:\e + :tc=more: +.Ed +.Pp +The capability foo has two values bound to it (bar of type `%' and blah of +type `^') and any other value bindings are hidden. +The capability abc +also has two values bound but only a value of type `$' is prevented from +being defined in the capability record more. +.Bd -unfilled -offset indent +file1: + new\||\|new_record\||\|a modification of "old":\e + :fript=bar:who-cares@:tc=old:blah:tc=extensions: +file2: + old\||\|old_record\||\|an old database record:\e + :fript=foo:who-cares:glork#200: +.Ed +.Pp +The records are extracted by calling +.Fn cgetent +with file1 preceding file2. +In the capability record new in file1, fript=bar overrides the definition +of fript=foo interpolated from the capability record old in file2, +who-cares@ prevents the definition of any who-cares definitions in old +from being seen, glork#200 is inherited from old, and blah and anything +defined by the record extensions is added to those definitions in old. +Note that the position of the fript=bar and who-cares@ definitions before +tc=old is important here. +If they were after, the definitions in old +would take precedence. +.Sh CGETNUM AND CGETSTR SYNTAX AND SEMANTICS +Two types are predefined by +.Fn cgetnum +and +.Fn cgetstr : +.Pp +.Bl -tag -width "nameXnumber" -compact +.It Em name Ns \&# Ns Em number +numeric capability +.Em name +has value +.Em number +.It Em name Ns = Ns Em string +string capability +.Em name +has value +.Em string +.It Em name Ns \&#@ +the numeric capability +.Em name +does not exist +.It Em name Ns \&=@ +the string capability +.Em name +does not exist +.El +.Pp +Numeric capability values may be given in one of three numeric bases. +If the number starts with either +.Ql 0x +or +.Ql 0X +it is interpreted as a hexadecimal number (both upper and lower case a-f +may be used to denote the extended hexadecimal digits). +Otherwise, if the number starts with a +.Ql 0 +it is interpreted as an octal number. +Otherwise the number is interpreted as a decimal number. +.Pp +String capability values may contain any character. +Non-printable +.Dv ASCII +codes, new lines, and colons may be conveniently represented by the use +of escape sequences: +.Bl -column "\e\|X,X\e\|X" "(ASCII octal nnn)" +^X ('X' & 037) control-X +\e\|b, \e\|B (ASCII 010) backspace +\e\|t, \e\|T (ASCII 011) tab +\e\|n, \e\|N (ASCII 012) line feed (newline) +\e\|f, \e\|F (ASCII 014) form feed +\e\|r, \e\|R (ASCII 015) carriage return +\e\|e, \e\|E (ASCII 027) escape +\e\|c, \e\|C (:) colon +\e\|\e (\e\|) back slash +\e\|^ (^) caret +\e\|nnn (ASCII octal nnn) +.El +.Pp +A `\|\e' may be followed by up to three octal digits directly specifies +the numeric code for a character. +The use of +.Tn ASCII +.Dv NUL Ns s , +while easily +encoded, causes all sorts of problems and must be used with care since +.Dv NUL Ns s +are typically used to denote the end of strings; many applications +use `\e\|200' to represent a +.Dv NUL . +.Sh DIAGNOSTICS +The +.Fn cgetent , +.Fn cgetset , +.Fn cgetmatch , +.Fn cgetnum , +.Fn cgetstr , +.Fn cgetustr , +.Fn cgetfirst , +and +.Fn cgetnext +functions +return a value greater than or equal to 0 on success and a value less +than 0 on failure. +The +.Fn cgetcap +function returns a character pointer on success and a +.Dv NULL +on failure. +.Pp +The +.Fn cgetent , +and +.Fn cgetset +functions may fail and set +.Va errno +for any of the errors specified for the library functions: +.Xr fopen 3 , +.Xr fclose 3 , +.Xr open 2 , +and +.Xr close 2 . +.Pp +The +.Fn cgetent , +.Fn cgetset , +.Fn cgetstr , +and +.Fn cgetustr +functions +may fail and set +.Va errno +as follows: +.Bl -tag -width Er +.It Bq Er ENOMEM +No memory to allocate. +.El +.Sh SEE ALSO +.Xr cap_mkdb 1 , +.Xr malloc 3 +.Sh BUGS +Colons (`:') cannot be used in names, types, or values. +.Pp +There are no checks for +.Ic tc Ns = Ns Ic name +loops in +.Fn cgetent . +.Pp +The buffer added to the database by a call to +.Fn cgetset +is not unique to the database but is rather prepended to any database used. diff --git a/lib/libc/gen/getcontext.3 b/lib/libc/gen/getcontext.3 new file mode 100644 index 0000000..14fb070 --- /dev/null +++ b/lib/libc/gen/getcontext.3 @@ -0,0 +1,150 @@ +.\" Copyright (c) 2002 Packet Design, LLC. +.\" All rights reserved. +.\" +.\" Subject to the following obligations and disclaimer of warranty, +.\" use and redistribution of this software, in source or object code +.\" forms, with or without modifications are expressly permitted by +.\" Packet Design; provided, however, that: +.\" +.\" (i) Any and all reproductions of the source or object code +.\" must include the copyright notice above and the following +.\" disclaimer of warranties; and +.\" (ii) No rights are granted, in any manner or form, to use +.\" Packet Design trademarks, including the mark "PACKET DESIGN" +.\" on advertising, endorsements, or otherwise except as such +.\" appears in the above copyright notice or in the software. +.\" +.\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND +.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO +.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING +.\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED +.\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, +.\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE, +.\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS +.\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, +.\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE +.\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE +.\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL +.\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF +.\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 PACKET DESIGN IS ADVISED OF +.\" THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/getcontext.3 248250 2013-03-13 18:18:16Z pluknet $ +.\" +.Dd March 13, 2013 +.Dt GETCONTEXT 3 +.Os +.Sh NAME +.Nm getcontext , getcontextx , setcontext +.Nd get and set user thread context +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ucontext.h +.Ft int +.Fn getcontext "ucontext_t *ucp" +.Ft ucontext_t * +.Fn getcontextx "void" +.Ft int +.Fn setcontext "const ucontext_t *ucp" +.Sh DESCRIPTION +The +.Fn getcontext +function +saves the current thread's execution context in the structure pointed to by +.Fa ucp . +This saved context may then later be restored by calling +.Fn setcontext . +.Pp +The +.Fn getcontextx +function saves the current execution context in the newly allocated structure +.Vt ucontext_t , +which is returned on success. +If architecture defines additional CPU states that can be stored in extended +blocks referenced from the +.Vt ucontext_t , +the memory for them may be allocated and their context also stored. +Memory returned by +.Fn getcontextx +function shall be freed using +.Fn free 3 . +.Pp +The +.Fn setcontext +function +makes a previously saved thread context the current thread context, i.e., +the current context is lost and +.Fn setcontext +does not return. +Instead, execution continues in the context specified by +.Fa ucp , +which must have been previously initialized by a call to +.Fn getcontext , +.Xr makecontext 3 , +or by being passed as an argument to a signal handler (see +.Xr sigaction 2 ) . +.Pp +If +.Fa ucp +was initialized by +.Fn getcontext , +then execution continues as if the original +.Fn getcontext +call had just returned (again). +.Pp +If +.Fa ucp +was initialized by +.Xr makecontext 3 , +execution continues with the invocation of the function specified to +.Xr makecontext 3 . +When that function returns, +.Fa "ucp->uc_link" +determines what happens next: +if +.Fa "ucp->uc_link" +is +.Dv NULL , +the process exits; +otherwise, +.Fn setcontext "ucp->uc_link" +is implicitly invoked. +.Pp +If +.Fa ucp +was initialized by the invocation of a signal handler, execution continues +at the point the thread was interrupted by the signal. +.Sh RETURN VALUES +If successful, +.Fn getcontext +returns zero and +.Fn setcontext +does not return; otherwise \-1 is returned. +The +.Fn getcontextx +returns pointer to the allocated and initialized context on success, and +.Va NULL +on failure. +.Sh ERRORS +No errors are defined for +.Fn getcontext +or +.Fn setcontext . +The +.Fn getcontextx +may return the following errors in +.Va errno : +.Bl -tag -width Er +.It Bq Er ENOMEM +No memory was available to allocate for the context or some extended state. +.El +.Sh SEE ALSO +.Xr sigaction 2 , +.Xr sigaltstack 2 , +.Xr makecontext 3 , +.Xr ucontext 3 diff --git a/lib/libc/gen/getcwd.3 b/lib/libc/gen/getcwd.3 new file mode 100644 index 0000000..ff2ef95 --- /dev/null +++ b/lib/libc/gen/getcwd.3 @@ -0,0 +1,162 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)getcwd.3 8.2 (Berkeley) 12/11/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getcwd.3 206760 2010-04-17 15:52:50Z jilles $ +.\" +.Dd April 17, 2010 +.Dt GETCWD 3 +.Os +.Sh NAME +.Nm getcwd , +.Nm getwd +.Nd get working directory pathname +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft char * +.Fn getcwd "char *buf" "size_t size" +.Ft char * +.Fn getwd "char *buf" +.Sh DESCRIPTION +The +.Fn getcwd +function copies the absolute pathname of the current working directory +into the memory referenced by +.Fa buf +and returns a pointer to +.Fa buf . +The +.Fa size +argument is the size, in bytes, of the array referenced by +.Fa buf . +.Pp +If +.Fa buf +is +.Dv NULL , +space is allocated as necessary to store the pathname. +This space may later be +.Xr free 3 Ns 'd . +.Pp +The function +.Fn getwd +is a compatibility routine which calls +.Fn getcwd +with its +.Fa buf +argument and a size of +.Dv MAXPATHLEN +(as defined in the include +file +.In sys/param.h ) . +Obviously, +.Fa buf +should be at least +.Dv MAXPATHLEN +bytes in length. +.Pp +These routines have traditionally been used by programs to save the +name of a working directory for the purpose of returning to it. +A much faster and less error-prone method of accomplishing this is to +open the current directory +.Pq Ql .\& +and use the +.Xr fchdir 2 +function to return. +.Sh RETURN VALUES +Upon successful completion, a pointer to the pathname is returned. +Otherwise a +.Dv NULL +pointer is returned and the global variable +.Va errno +is set to indicate the error. +In addition, +.Fn getwd +copies the error message associated with +.Va errno +into the memory referenced by +.Fa buf . +.Sh ERRORS +The +.Fn getcwd +function +will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa size +argument is zero. +.It Bq Er ENOENT +A component of the pathname no longer exists. +.It Bq Er ENOMEM +Insufficient memory is available. +.It Bq Er ERANGE +The +.Fa size +argument is greater than zero but smaller than the length of the pathname +plus 1. +.El +.Pp +The +.Fn getcwd +function +may fail if: +.Bl -tag -width Er +.It Bq Er EACCES +Read or search permission was denied for a component of the pathname. +This is only checked in limited cases, depending on implementation details. +.El +.Sh SEE ALSO +.Xr chdir 2 , +.Xr fchdir 2 , +.Xr malloc 3 , +.Xr strerror 3 +.Sh STANDARDS +The +.Fn getcwd +function +conforms to +.St -p1003.1-90 . +The ability to specify a +.Dv NULL +pointer and have +.Fn getcwd +allocate memory as necessary is an extension. +.Sh HISTORY +The +.Fn getwd +function appeared in +.Bx 4.0 . +.Sh BUGS +The +.Fn getwd +function +does not do sufficient error checking and is not able to return very +long, but valid, paths. +It is provided for compatibility. diff --git a/lib/libc/gen/getdiskbyname.3 b/lib/libc/gen/getdiskbyname.3 new file mode 100644 index 0000000..6d8dc86 --- /dev/null +++ b/lib/libc/gen/getdiskbyname.3 @@ -0,0 +1,63 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)getdiskbyname.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getdiskbyname.3 220617 2011-04-14 08:53:04Z pluknet $ +.\" +.Dd June 4, 1993 +.Dt GETDISKBYNAME 3 +.Os +.Sh NAME +.Nm getdiskbyname +.Nd get generic disk description by its name +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/disklabel.h +.Ft struct disklabel * +.Fn getdiskbyname "const char *name" +.Sh DESCRIPTION +The +.Fn getdiskbyname +function +takes a disk name (e.g.\& +.Ql rm03 ) +and returns a prototype disk label +describing its geometry information and the standard +disk partition tables. +All information is obtained from +the +.Xr disktab 5 +file. +.Sh SEE ALSO +.Xr disktab 5 , +.Xr disklabel 8 +.Sh HISTORY +The +.Fn getdiskbyname +function appeared in +.Bx 4.3 . diff --git a/lib/libc/gen/getdomainname.3 b/lib/libc/gen/getdomainname.3 new file mode 100644 index 0000000..41bf9d5 --- /dev/null +++ b/lib/libc/gen/getdomainname.3 @@ -0,0 +1,100 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)gethostname.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getdomainname.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd May 6, 1994 +.Dt GETDOMAINNAME 3 +.Os +.Sh NAME +.Nm getdomainname , +.Nm setdomainname +.Nd get/set the NIS domain name of current host +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn getdomainname "char *name" "int namelen" +.Ft int +.Fn setdomainname "const char *name" "int namelen" +.Sh DESCRIPTION +The +.Fn getdomainname +function +returns the standard NIS domain name for the current host, as +previously set by +.Fn setdomainname . +The +.Fa namelen +argument +specifies the size of the +.Fa name +array. +The returned name is null-terminated unless insufficient +space is provided. +.Pp +The +.Fn setdomainname +function +sets the NIS domain name of the host machine to be +.Fa name , +which has length +.Fa namelen . +This call is restricted to the super-user and +is normally used only when the system is bootstrapped. +.Sh RETURN VALUES +.Rv -std +.Sh ERRORS +The following errors may be returned by these calls: +.Bl -tag -width Er +.It Bq Er EFAULT +The +.Fa name +or +.Fa namelen +argument gave an +invalid address. +.It Bq Er EPERM +The caller tried to set the hostname and was not the super-user. +.El +.Sh SEE ALSO +.Xr gethostid 3 , +.Xr gethostname 3 , +.Xr sysctl 3 +.Sh HISTORY +The +.Fn getdomainname +function appeared in +.Bx 4.2 . +.Sh BUGS +Domain names are limited to +.Dv MAXHOSTNAMELEN +(from +.In sys/param.h ) +characters, currently 256. diff --git a/lib/libc/gen/getfsent.3 b/lib/libc/gen/getfsent.3 new file mode 100644 index 0000000..2691840 --- /dev/null +++ b/lib/libc/gen/getfsent.3 @@ -0,0 +1,185 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)getfsent.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getfsent.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 7, 2003 +.Dt GETFSENT 3 +.Os +.Sh NAME +.Nm getfsent , +.Nm getfsspec , +.Nm getfsfile , +.Nm setfsent , +.Nm endfsent +.Nd get file system descriptor file entry +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In fstab.h +.Ft "struct fstab *" +.Fn getfsent void +.Ft "struct fstab *" +.Fn getfsspec "const char *spec" +.Ft "struct fstab *" +.Fn getfsfile "const char *file" +.Ft int +.Fn setfsent void +.Ft void +.Fn endfsent void +.Ft void +.Fn setfstab "const char *file" +.Ft "const char *" +.Fn getfstab void +.Sh DESCRIPTION +The +.Fn getfsent , +.Fn getfsspec , +and +.Fn getfsfile +functions +each return a pointer to an object with the following structure +containing the broken-out fields of a line in the file system +description file, +.In fstab.h . +.Bd -literal -offset indent +struct fstab { + char *fs_spec; /* block special device name */ + char *fs_file; /* file system path prefix */ + char *fs_vfstype; /* File system type, ufs, nfs */ + char *fs_mntops; /* Mount options ala -o */ + char *fs_type; /* FSTAB_* from fs_mntops */ + int fs_freq; /* dump frequency, in days */ + int fs_passno; /* pass number on parallel fsck */ +}; +.Ed +.Pp +The fields have meanings described in +.Xr fstab 5 . +.Pp +The +.Fn setfsent +function +opens the file (closing any previously opened file) or rewinds it +if it is already open. +.Pp +The +.Fn endfsent +function +closes the file. +.Pp +The +.Fn setfstab +function sets the file to be used by subsequent operations. +The value set by +.Fn setfstab +does not persist across calls to +.Fn endfsent . +.Pp +The +.Fn getfstab +function returns the name of the file that will be used. +.Pp +The +.Fn getfsspec +and +.Fn getfsfile +functions +search the entire file (opening it if necessary) for a matching special +file name or file system file name. +.Pp +For programs wishing to read the entire database, +.Fn getfsent +reads the next entry (opening the file if necessary). +.Pp +All entries in the file with a type field equivalent to +.Dv FSTAB_XX +are ignored. +.Sh RETURN VALUES +The +.Fn getfsent , +.Fn getfsspec , +and +.Fn getfsfile +functions +return a +.Dv NULL +pointer on +.Dv EOF +or error. +The +.Fn setfsent +function +returns 0 on failure, 1 on success. +The +.Fn endfsent +function +returns nothing. +.Sh ENVIRONMENT +.Bl -tag -width ".Ev PATH_FSTAB" +.It Ev PATH_FSTAB +If the environment variable +.Ev PATH_FSTAB +is set, all operations are performed against the specified file. +.Ev PATH_FSTAB +will not be honored if the process environment or memory address space is +considered +.Dq tainted . +(See +.Xr issetugid 2 +for more information.) +.El +.Sh FILES +.Bl -tag -width /etc/fstab -compact +.It Pa /etc/fstab +.El +.Sh SEE ALSO +.Xr fstab 5 +.Sh HISTORY +The +.Fn getfsent +function appeared in +.Bx 4.0 ; +the +.Fn endfsent , +.Fn getfsfile , +.Fn getfsspec , +and +.Fn setfsent +functions appeared in +.Bx 4.3 ; +the +.Fn setfstab +and +.Fn getfstab +functions appeared in +.Fx 5.1 . +.Sh BUGS +These functions use static data storage; +if the data is needed for future use, it should be +copied before any subsequent calls overwrite it. diff --git a/lib/libc/gen/getgrent.3 b/lib/libc/gen/getgrent.3 new file mode 100644 index 0000000..2ff76da --- /dev/null +++ b/lib/libc/gen/getgrent.3 @@ -0,0 +1,287 @@ +.\" Copyright (c) 1989, 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. +.\" 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. +.\" +.\" From: @(#)getgrent.3 8.2 (Berkeley) 4/19/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getgrent.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 16, 2003 +.Dt GETGRENT 3 +.Os +.Sh NAME +.Nm getgrent , +.Nm getgrent_r , +.Nm getgrnam , +.Nm getgrnam_r , +.Nm getgrgid , +.Nm getgrgid_r , +.Nm setgroupent , +.Nm setgrent , +.Nm endgrent +.Nd group database operations +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In grp.h +.Ft struct group * +.Fn getgrent void +.Ft int +.Fn getgrent_r "struct group *grp" "char *buffer" "size_t bufsize" "struct group **result" +.Ft struct group * +.Fn getgrnam "const char *name" +.Ft int +.Fn getgrnam_r "const char *name" "struct group *grp" "char *buffer" "size_t bufsize" "struct group **result" +.Ft struct group * +.Fn getgrgid "gid_t gid" +.Ft int +.Fn getgrgid_r "gid_t gid" "struct group *grp" "char *buffer" "size_t bufsize" "struct group **result" +.Ft int +.Fn setgroupent "int stayopen" +.Ft int +.Fn setgrent void +.Ft void +.Fn endgrent void +.Sh DESCRIPTION +These functions operate on the group database file +.Pa /etc/group +which is described +in +.Xr group 5 . +Each line of the database is defined by the structure +.Vt group +found in the include +file +.In grp.h : +.Bd -literal -offset indent +struct group { + char *gr_name; /* group name */ + char *gr_passwd; /* group password */ + gid_t gr_gid; /* group id */ + char **gr_mem; /* group members */ +}; +.Ed +.Pp +The functions +.Fn getgrnam +and +.Fn getgrgid +search the group database for the given group name pointed to by +.Fa name +or the group id pointed to by +.Fa gid , +respectively, returning the first one encountered. +Identical group +names or group gids may result in undefined behavior. +.Pp +The +.Fn getgrent +function +sequentially reads the group database and is intended for programs +that wish to step through the complete list of groups. +.Pp +The functions +.Fn getgrent_r , +.Fn getgrnam_r , +and +.Fn getgrgid_r +are thread-safe versions of +.Fn getgrent , +.Fn getgrnam , +and +.Fn getgrgid , +respectively. +The caller must provide storage for the results of the search in +the +.Fa grp , +.Fa buffer , +.Fa bufsize , +and +.Fa result +arguments. +When these functions are successful, the +.Fa grp +argument will be filled-in, and a pointer to that argument will be +stored in +.Fa result . +If an entry is not found or an error occurs, +.Fa result +will be set to +.Dv NULL . +.Pp +These functions will open the group file for reading, if necessary. +.Pp +The +.Fn setgroupent +function +opens the file, or rewinds it if it is already open. +If +.Fa stayopen +is non-zero, file descriptors are left open, significantly speeding +functions subsequent calls. +This functionality is unnecessary for +.Fn getgrent +as it does not close its file descriptors by default. +It should also +be noted that it is dangerous for long-running programs to use this +functionality as the group file may be updated. +.Pp +The +.Fn setgrent +function +is identical to +.Fn setgroupent +with an argument of zero. +.Pp +The +.Fn endgrent +function +closes any open files. +.Sh RETURN VALUES +The functions +.Fn getgrent , +.Fn getgrnam , +and +.Fn getgrgid , +return a pointer to a group structure on success or +.Dv NULL +if the entry is not found or if an error occurs. +If an error does occur, +.Va errno +will be set. +Note that programs must explicitly set +.Va errno +to zero before calling any of these functions if they need to +distinguish between a non-existent entry and an error. +The functions +.Fn getgrent_r , +.Fn getgrnam_r , +and +.Fn getgrgid_r +return 0 if no error occurred, or an error number to indicate failure. +It is not an error if a matching entry is not found. +(Thus, if +.Fa result +is set to +.Dv NULL +and the return value is 0, no matching entry exists.) +.Pp +The functions +.Fn setgroupent +and +.Fn setgrent +return the value 1 if successful, otherwise the value +0 is returned. +The functions +.Fn endgrent +and +.Fn setgrfile +have no return value. +.Sh FILES +.Bl -tag -width /etc/group -compact +.It Pa /etc/group +group database file +.El +.Sh COMPATIBILITY +The historic function +.Fn setgrfile , +which allowed the specification of alternate password databases, has +been deprecated and is no longer available. +.Sh SEE ALSO +.Xr getpwent 3 , +.Xr group 5 , +.Xr nsswitch.conf 5 , +.Xr yp 8 +.Sh STANDARDS +The +.Fn getgrent , +.Fn getgrnam , +.Fn getgrnam_r , +.Fn getgrgid , +.Fn getgrgid_r +and +.Fn endgrent +functions conform to +.St -p1003.1-96 . +The +.Fn setgrent +function differs from that standard in that its return type is +.Vt int +rather than +.Vt void . +.Sh HISTORY +The functions +.Fn endgrent , +.Fn getgrent , +.Fn getgrnam , +.Fn getgrgid , +and +.Fn setgrent +appeared in +.At v7 . +The functions +.Fn setgrfile +and +.Fn setgroupent +appeared in +.Bx 4.3 Reno . +The functions +.Fn getgrent_r , +.Fn getgrnam_r , +and +.Fn getgrgid_r +appeared in +.Fx 5.1 . +.Sh BUGS +The functions +.Fn getgrent , +.Fn getgrnam , +.Fn getgrgid , +.Fn setgroupent +and +.Fn setgrent +leave their results in an internal static object and return +a pointer to that object. +Subsequent calls to +the same function +will modify the same object. +.Pp +The functions +.Fn getgrent , +.Fn getgrent_r , +.Fn endgrent , +.Fn setgroupent , +and +.Fn setgrent +are fairly useless in a networked environment and should be +avoided, if possible. +The +.Fn getgrent +and +.Fn getgrent_r +functions +make no attempt to suppress duplicate information if multiple +sources are specified in +.Xr nsswitch.conf 5 . diff --git a/lib/libc/gen/getgrouplist.3 b/lib/libc/gen/getgrouplist.3 new file mode 100644 index 0000000..1686b71 --- /dev/null +++ b/lib/libc/gen/getgrouplist.3 @@ -0,0 +1,82 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)getgrouplist.3 8.1 (Berkeley) 6/9/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getgrouplist.3 273717 2014-10-27 04:09:23Z markj $ +.\" +.Dd October 26, 2014 +.Dt GETGROUPLIST 3 +.Os +.Sh NAME +.Nm getgrouplist +.Nd calculate group access list +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn getgrouplist "const char *name" "gid_t basegid" "gid_t *groups" "int *ngroups" +.Sh DESCRIPTION +The +.Fn getgrouplist +function reads through the group file and calculates +the group access list for the user specified in +.Fa name . +The +.Fa basegid +is automatically included in the groups list. +Typically this value is given as +the group number from the password file. +.Pp +The resulting group list is returned in the array pointed to by +.Fa groups . +The caller specifies the size of the +.Fa groups +array in the integer pointed to by +.Fa ngroups ; +the actual number of groups found is returned in +.Fa ngroups . +.Sh RETURN VALUES +The +.Fn getgrouplist +function +returns 0 on success and \-1 if the size of the group list is too small to +hold all the user's groups. +Here, the group array will be filled with as many groups as will fit. +.Sh FILES +.Bl -tag -width /etc/group -compact +.It Pa /etc/group +group membership list +.El +.Sh SEE ALSO +.Xr setgroups 2 , +.Xr initgroups 3 +.Sh HISTORY +The +.Fn getgrouplist +function first appeared in +.Bx 4.4 . diff --git a/lib/libc/gen/gethostname.3 b/lib/libc/gen/gethostname.3 new file mode 100644 index 0000000..766ff8f --- /dev/null +++ b/lib/libc/gen/gethostname.3 @@ -0,0 +1,131 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)gethostname.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/gethostname.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd August 18, 2003 +.Dt GETHOSTNAME 3 +.Os +.Sh NAME +.Nm gethostname , +.Nm sethostname +.Nd get/set name of current host +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn gethostname "char *name" "size_t namelen" +.Ft int +.Fn sethostname "const char *name" "int namelen" +.Sh DESCRIPTION +The +.Fn gethostname +function +returns the standard host name for the current processor, as +previously set by +.Fn sethostname . +The +.Fa namelen +argument +specifies the size of the +.Fa name +array. +The returned name is null-terminated unless insufficient space is provided. +.Pp +The +.Fn sethostname +function +sets the name of the host machine to be +.Fa name , +which has length +.Fa namelen . +This call is restricted to the super-user and +is normally used only when the system is bootstrapped. +.Pp +Host names are limited to +.Brq Dv HOST_NAME_MAX +characters, not including the trailing null, currently 255. +.Sh RETURN VALUES +.Rv -std +.Sh ERRORS +The following errors may be returned by these calls: +.Bl -tag -width Er +.It Bq Er EFAULT +The +.Fa name +or +.Fa namelen +argument gave an +invalid address. +.It Bq Er ENAMETOOLONG +The current host name is longer than +.Fa namelen . +(For +.Fn gethostname +only.) +.It Bq Er EPERM +The caller tried to set the host name and was not the super-user. +.El +.Sh SEE ALSO +.Xr sysconf 3 , +.Xr sysctl 3 +.Sh STANDARDS +The +.Fn gethostname +function conforms to +.St -p1003.1-2001 . +Callers should be aware that +.Brq Dv HOST_NAME_MAX +may be variable or infinite, but is guaranteed to be no less than +.Brq Dv _POSIX_HOST_NAME_MAX . +On older systems, this limit was defined in the non-standard header +.In sys/param.h +as +.Dv MAXHOSTNAMELEN , +and counted the terminating null. +The +.Fn sethostname +function and the error returns for +.Fn gethostname +are not standardized. +.Sh HISTORY +The +.Fn gethostname +function appeared in +.Bx 4.2 . +The +.Fa namelen +argument to +.Fn gethostname +was changed to +.Vt size_t +in +.Fx 5.2 +for alignment with +.St -p1003.1-2001 . diff --git a/lib/libc/gen/getloadavg.3 b/lib/libc/gen/getloadavg.3 new file mode 100644 index 0000000..966c922 --- /dev/null +++ b/lib/libc/gen/getloadavg.3 @@ -0,0 +1,65 @@ +.\" Copyright (c) 1989, 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. +.\" 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. +.\" +.\" @(#)getloadavg.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getloadavg.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 4, 1993 +.Dt GETLOADAVG 3 +.Os +.Sh NAME +.Nm getloadavg +.Nd get system load averages +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fn getloadavg "double loadavg[]" "int nelem" +.Sh DESCRIPTION +The +.Fn getloadavg +function returns the number of processes in the system run queue +averaged over various periods of time. +Up to +.Fa nelem +samples are retrieved and assigned to successive elements of +.Fa loadavg Ns Bq . +The system imposes a maximum of 3 samples, representing averages +over the last 1, 5, and 15 minutes, respectively. +.Sh DIAGNOSTICS +If the load average was unobtainable, \-1 is returned; otherwise, +the number of samples actually retrieved is returned. +.Sh SEE ALSO +.Xr uptime 1 , +.Xr kvm_getloadavg 3 , +.Xr sysctl 3 +.Sh HISTORY +The +.Fn getloadavg +function appeared in +.Bx 4.3 Reno . diff --git a/lib/libc/gen/getmntinfo.3 b/lib/libc/gen/getmntinfo.3 new file mode 100644 index 0000000..3a5daad --- /dev/null +++ b/lib/libc/gen/getmntinfo.3 @@ -0,0 +1,109 @@ +.\" Copyright (c) 1989, 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. +.\" 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. +.\" +.\" @(#)getmntinfo.3 8.1 (Berkeley) 6/9/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getmntinfo.3 313450 2017-02-08 18:32:35Z jhb $ +.\" +.Dd December 27, 2016 +.Dt GETMNTINFO 3 +.Os +.Sh NAME +.Nm getmntinfo +.Nd get information about mounted file systems +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/param.h +.In sys/ucred.h +.In sys/mount.h +.Ft int +.Fn getmntinfo "struct statfs **mntbufp" "int mode" +.Sh DESCRIPTION +The +.Fn getmntinfo +function +returns an array of +.Fn statfs +structures describing each currently mounted file system (see +.Xr statfs 2 ) . +.Pp +The +.Fn getmntinfo +function +passes its +.Fa mode +argument transparently to +.Xr getfsstat 2 . +.Sh RETURN VALUES +On successful completion, +.Fn getmntinfo +returns a count of the number of elements in the array. +The pointer to the array is stored into +.Fa mntbufp . +.Pp +If an error occurs, zero is returned and the external variable +.Va errno +is set to indicate the error. +Although the pointer +.Fa mntbufp +will be unmodified, any information previously returned by +.Fn getmntinfo +will be lost. +.Sh ERRORS +The +.Fn getmntinfo +function +may fail and set errno for any of the errors specified for the library +routines +.Xr getfsstat 2 +or +.Xr malloc 3 . +.Sh SEE ALSO +.Xr getfsstat 2 , +.Xr mount 2 , +.Xr statfs 2 , +.Xr mount 8 +.Sh HISTORY +The +.Fn getmntinfo +function first appeared in +.Bx 4.4 . +.Sh BUGS +The +.Fn getmntinfo +function writes the array of structures to an internal static object +and returns +a pointer to that object. +Subsequent calls to +.Fn getmntinfo +will modify the same object. +.Pp +The memory allocated by +.Fn getmntinfo +cannot be +.Xr free 3 Ns 'd +by the application. diff --git a/lib/libc/gen/getnetgrent.3 b/lib/libc/gen/getnetgrent.3 new file mode 100644 index 0000000..abac682 --- /dev/null +++ b/lib/libc/gen/getnetgrent.3 @@ -0,0 +1,133 @@ +.\" Copyright (c) 1992, 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. +.\" 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. +.\" +.\" @(#)getnetgrent.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getnetgrent.3 301711 2016-06-09 01:28:44Z markj $ +.\" +.Dd June 5, 2016 +.Dt GETNETGRENT 3 +.Os +.Sh NAME +.Nm getnetgrent , +.Nm innetgr , +.Nm setnetgrent , +.Nm endnetgrent +.Nd netgroup database operations +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In netdb.h +.Ft int +.Fn getnetgrent "char **host" "char **user" "char **domain" +.Ft int +.Fn getnetgrent_r "char **host" "char **user" "char **domain" "char *buf" "size_t bufsize" +.Ft int +.Fn innetgr "const char *netgroup" "const char *host" "const char *user" "const char *domain" +.Ft void +.Fn setnetgrent "const char *netgroup" +.Ft void +.Fn endnetgrent void +.Sh DESCRIPTION +These functions operate on the netgroup database file +.Pa /etc/netgroup +which is described +in +.Xr netgroup 5 . +The database defines a set of netgroups, each made up of one or more triples: +.Bd -literal -offset indent +(host, user, domain) +.Ed +that defines a combination of host, user and domain. +Any of the three fields may be specified as ``wildcards'' that match any +string. +.Pp +The function +.Fn getnetgrent +sets the three pointer arguments to the strings of the next member of the +current netgroup. +If any of the string pointers are +.Dv NULL +that field is considered a wildcard. +.Pp +The functions +.Fn setnetgrent +and +.Fn endnetgrent +set the current netgroup and terminate the current netgroup respectively. +If +.Fn setnetgrent +is called with a different netgroup than the previous call, an implicit +.Fn endnetgrent +is implied. +The +.Fn setnetgrent +function +also sets the offset to the first member of the netgroup. +.Pp +The function +.Fn innetgr +searches for a match of all fields within the specified group. +If any of the +.Sy host , +.Sy user , +or +.Sy domain +arguments are +.Dv NULL +those fields will match any string value in the netgroup member. +.Sh RETURN VALUES +The function +.Fn getnetgrent +returns 0 for ``no more netgroup members'' and 1 otherwise. +The function +.Fn innetgr +returns 1 for a successful match and 0 otherwise. +The functions +.Fn setnetgrent +and +.Fn endnetgrent +have no return value. +.Sh FILES +.Bl -tag -width /etc/netgroup -compact +.It Pa /etc/netgroup +netgroup database file +.El +.Sh COMPATIBILITY +The netgroup members have three string fields to maintain compatibility +with other vendor implementations, however it is not obvious what use the +.Sy domain +string has within +.Bx . +.Sh SEE ALSO +.Xr netgroup 5 +.Sh BUGS +The function +.Fn getnetgrent +returns pointers to dynamically allocated data areas that are freed when +the function +.Fn endnetgrent +is called. diff --git a/lib/libc/gen/getosreldate.3 b/lib/libc/gen/getosreldate.3 new file mode 100644 index 0000000..3c1f58c --- /dev/null +++ b/lib/libc/gen/getosreldate.3 @@ -0,0 +1,86 @@ +.\" Copyright (c) 2002 The FreeBSD Project. +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/getosreldate.3 183495 2008-09-30 11:25:55Z kib $ +.\" +.Dd September 30, 2008 +.Dt GETOSRELDATE 3 +.Os +.Sh NAME +.Nm getosreldate +.Nd get the value of +.Dv __FreeBSD_version +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn getosreldate void +.Sh DESCRIPTION +The +.Fn getosreldate +function returns an integer showing the version of the +currently running +.Fx +kernel. +Definitions of the values can be found in +.%B "The Porter's Handbook" +which is usually installed at +.Pa /usr/share/doc/en_US.ISO8859-1/books/porters-handbook/ . +.Sh RETURN VALUES +Upon successful completion, +.Fn getosreldate +returns the value requested; +otherwise the value \-1 is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ENVIRONMENT +.Bl -tag -width ".Ev OSVERSION" +.It Ev OSVERSION +If the environment variable +.Ev OSVERSION +is set, it will override the +.Fn getosreldate +return value. +.El +.Sh EXAMPLES +An example can be found in +.Pa /usr/share/examples/FreeBSD_version . +.Sh ERRORS +The +.Fn getosreldate +function may fail and set +.Va errno +for any of the errors specified for the library function +.Xr sysctl 3 . +.Sh SEE ALSO +.Rs +.%B "The Porter's Handbook" +.%O /usr/share/doc/en_US.ISO8859-1/books/porters\-handbook/ +.Re +.Sh HISTORY +The +.Fn getosreldate +function appeared in +.Fx 2.0 . diff --git a/lib/libc/gen/getpagesize.3 b/lib/libc/gen/getpagesize.3 new file mode 100644 index 0000000..2f6fb3c --- /dev/null +++ b/lib/libc/gen/getpagesize.3 @@ -0,0 +1,61 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)getpagesize.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getpagesize.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 4, 1993 +.Dt GETPAGESIZE 3 +.Os +.Sh NAME +.Nm getpagesize +.Nd get system page size +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn getpagesize void +.Sh DESCRIPTION +The +.Fn getpagesize +function +returns the number of bytes in a page. +Page granularity is the granularity of many of the memory +management calls. +.Pp +The page size is a system +page size and may not be the same as the underlying +hardware page size. +.Sh SEE ALSO +.Xr pagesize 1 , +.Xr sbrk 2 +.Sh HISTORY +The +.Fn getpagesize +function appeared in +.Bx 4.2 . diff --git a/lib/libc/gen/getpagesizes.3 b/lib/libc/gen/getpagesizes.3 new file mode 100644 index 0000000..4cd6c0a --- /dev/null +++ b/lib/libc/gen/getpagesizes.3 @@ -0,0 +1,99 @@ +.\" Copyright (c) 2009 Alan L. Cox +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/getpagesizes.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.Dd September 21, 2009 +.Dt GETPAGESIZES 3 +.Os +.Sh NAME +.Nm getpagesizes +.Nd "get system page sizes" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/mman.h +.Ft int +.Fn getpagesizes "size_t pagesize[]" "int nelem" +.Sh DESCRIPTION +The +.Fn getpagesizes +function retrieves page size information from the system. +When it is called with +.Fa pagesize +specified as +.Dv NULL +and +.Fa nelem +specified as 0, it returns the number of distinct page sizes that are +supported by the system. +Otherwise, it assigns up to +.Fa nelem +of the system-supported page sizes to consecutive elements of the +array referenced by +.Fa pagesize . +These page sizes are expressed in bytes. +In this case, +.Fn getpagesizes +returns the number of such page sizes that it assigned to the array. +.Sh RETURN VALUES +If successful, the +.Fn getpagesizes +function returns either the number of page sizes that are supported by +the system or the number of supported page sizes that it assigned to +the array referenced by +.Fa pagesize . +Otherwise, it returns the value\~\-1 and sets +.Va errno +to indicate the error. +.Sh ERRORS +The +.Fn getpagesizes +function will succeed unless: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa pagesize +argument is +.Dv NULL +and the +.Fa nelem +argument is non-zero. +.It Bq Er EINVAL +The +.Fa nelem +argument is less than zero. +.El +.Sh SEE ALSO +.Xr getpagesize 3 +.Sh HISTORY +The +.Fn getpagesizes +function first appeared in Solaris 9. +This manual page was written in conjunction with a new but compatible +implementation that was first released in +.Fx 7.3 . +.Sh AUTHORS +This manual page was written by +.An Alan L. Cox Aq Mt alc@cs.rice.edu . diff --git a/lib/libc/gen/getpagesizes.c b/lib/libc/gen/getpagesizes.c new file mode 100644 index 0000000..47ffa99 --- /dev/null +++ b/lib/libc/gen/getpagesizes.c @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2009 Alan L. Cox + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/getpagesizes.c 211416 2010-08-17 09:13:26Z kib $"); + +#include +#include +#include + +#include +#include + +#include "libc_private.h" + +/* + * Retrieves page size information from the system. Specifically, returns the + * number of distinct page sizes that are supported by the system, if + * "pagesize" is NULL and "nelem" is 0. Otherwise, assigns up to "nelem" of + * the system-supported page sizes to consecutive elements of the array + * referenced by "pagesize", and returns the number of such page sizes that it + * assigned to the array. These page sizes are expressed in bytes. + * + * The implementation of this function does not directly or indirectly call + * malloc(3) or any other dynamic memory allocator that may itself call this + * function. + */ +int +getpagesizes(size_t pagesize[], int nelem) +{ + static u_long ps[MAXPAGESIZES]; + static int nops; + size_t size; + int error, i; + + if (nelem < 0 || (nelem > 0 && pagesize == NULL)) { + errno = EINVAL; + return (-1); + } + /* Cache the result of the sysctl(2). */ + if (nops == 0) { + error = _elf_aux_info(AT_PAGESIZES, ps, sizeof(ps)); + size = sizeof(ps); + if (error != 0 || ps[0] == 0) { + if (sysctlbyname("hw.pagesizes", ps, &size, NULL, 0) + == -1) + return (-1); + } + /* Count the number of page sizes that are supported. */ + nops = size / sizeof(ps[0]); + while (nops > 0 && ps[nops - 1] == 0) + nops--; + } + if (pagesize == NULL) + return (nops); + /* Return up to "nelem" page sizes from the cached result. */ + if (nelem > nops) + nelem = nops; + for (i = 0; i < nelem; i++) + pagesize[i] = ps[i]; + return (nelem); +} diff --git a/lib/libc/gen/getpass.3 b/lib/libc/gen/getpass.3 new file mode 100644 index 0000000..4621b47 --- /dev/null +++ b/lib/libc/gen/getpass.3 @@ -0,0 +1,93 @@ +.\" Copyright (c) 1989, 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. +.\" 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. +.\" +.\" @(#)getpass.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getpass.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 4, 1993 +.Dt GETPASS 3 +.Os +.Sh NAME +.Nm getpass +.Nd get a password +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In pwd.h +.In unistd.h +.Ft char * +.Fn getpass "const char *prompt" +.Sh DESCRIPTION +The +.Fn getpass +function displays a prompt to, and reads in a password from, +.Pa /dev/tty . +If this file is not accessible, +.Fn getpass +displays the prompt on the standard error output and reads from the standard +input. +.Pp +The password may be up to _PASSWORD_LEN (currently 128) +characters in length. +Any additional +characters and the terminating newline character are discarded. +.Pp +The +.Fn getpass +function turns off character echoing while reading the password. +.Sh RETURN VALUES +The +.Fn getpass +function returns a pointer to the null terminated password. +.Sh FILES +.Bl -tag -width /dev/tty -compact +.It Pa /dev/tty +.El +.Sh SEE ALSO +.Xr crypt 3 , +.Xr readpassphrase 3 +.Sh HISTORY +A +.Fn getpass +function appeared in +.At v7 . +.Sh BUGS +The +.Fn getpass +function leaves its result in an internal static object and returns +a pointer to that object. +Subsequent calls to +.Fn getpass +will modify the same object. +.Pp +The calling process should zero the password as soon as possible to +avoid leaving the cleartext password visible in the process's address +space. +.Pp +Upon receipt of a SIGTSTP, the input buffer will be flushed, so any +partially typed password must be retyped when the process +continues. diff --git a/lib/libc/gen/getpeereid.3 b/lib/libc/gen/getpeereid.3 new file mode 100644 index 0000000..45cdcf0 --- /dev/null +++ b/lib/libc/gen/getpeereid.3 @@ -0,0 +1,137 @@ +.\" +.\" Copyright (c) 2001 Dima Dorfman. +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/getpeereid.3 108030 2002-12-18 10:13:54Z ru $ +.\" +.Dd July 15, 2001 +.Dt GETPEEREID 3 +.Os +.Sh NAME +.Nm getpeereid +.Nd get the effective credentials of a UNIX-domain peer +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In unistd.h +.Ft int +.Fn getpeereid "int s" "uid_t *euid" "gid_t *egid" +.Sh DESCRIPTION +The +.Fn getpeereid +function returns the effective user and group IDs of the +peer connected to a +.Ux Ns -domain +socket. +The argument +.Fa s +must be a +.Ux Ns -domain +socket +.Pq Xr unix 4 +of type +.Dv SOCK_STREAM +on which either +.Xr connect 2 +or +.Xr listen 2 +have been called. +The effective used ID is placed in +.Fa euid , +and the effective group ID in +.Fa egid . +.Pp +The credentials returned to the +.Xr listen 2 +caller are those of its peer at the time it called +.Xr connect 2 ; +the credentials returned to the +.Xr connect 2 +caller are those of its peer at the time it called +.Xr listen 2 . +This mechanism is reliable; there is no way for either side to influence +the credentials returned to its peer except by calling the appropriate +system call (i.e., either +.Xr connect 2 +or +.Xr listen 2 ) +under different effective credentials. +.Pp +One common use of this routine is for a +.Ux Ns -domain +server +to verify the credentials of its client. +Likewise, the client can verify the credentials of the server. +.Sh IMPLEMENTATION NOTES +On +.Fx , +.Fn getpeereid +is implemented in terms of the +.Dv LOCAL_PEERCRED +.Xr unix 4 +socket option. +.Sh RETURN VALUES +.Rv -std getpeereid +.Sh ERRORS +The +.Fn getpeereid +function +fails if: +.Bl -tag -width Er +.It Bq Er EBADF +The argument +.Fa s +is not a valid descriptor. +.It Bq Er ENOTSOCK +The argument +.Fa s +is a file, not a socket. +.It Bq Er ENOTCONN +The argument +.Fa s +does not refer to a socket on which +.Xr connect 2 +or +.Xr listen 2 +have been called. +.It Bq Er EINVAL +The argument +.Fa s +does not refer to a socket of type +.Dv SOCK_STREAM , +or the kernel returned invalid data. +.El +.Sh SEE ALSO +.Xr connect 2 , +.Xr getpeername 2 , +.Xr getsockname 2 , +.Xr getsockopt 2 , +.Xr listen 2 , +.Xr unix 4 +.Sh HISTORY +The +.Fn getpeereid +function appeared in +.Fx 4.6 . diff --git a/lib/libc/gen/getprogname.3 b/lib/libc/gen/getprogname.3 new file mode 100644 index 0000000..336bff8 --- /dev/null +++ b/lib/libc/gen/getprogname.3 @@ -0,0 +1,94 @@ +.\" +.\" Copyright (c) 2001 Christopher G. Demetriou +.\" 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 for the +.\" NetBSD Project. See http://www.netbsd.org/ for +.\" information about NetBSD. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/getprogname.3 84306 2001-10-01 16:09:29Z ru $ +.\" +.Dd May 1, 2001 +.Dt GETPROGNAME 3 +.Os +.Sh NAME +.Nm getprogname , +.Nm setprogname +.Nd get or set the program name +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft const char * +.Fn getprogname "void" +.Ft void +.Fn setprogname "const char *progname" +.Sh DESCRIPTION +The +.Fn getprogname +and +.Fn setprogname +functions manipulate the name of the current program. +They are used by error-reporting routines to produce +consistent output. +.Pp +The +.Fn getprogname +function returns the name of the program. +If the name has not been set yet, it will return +.Dv NULL . +.Pp +The +.Fn setprogname +function sets the name of the program to be the last component of the +.Fa progname +argument. +Since a pointer to the given string is kept as the program name, +it should not be modified for the rest of the program's lifetime. +.Pp +In +.Fx , +the name of the program is set by the start-up code that is run before +.Fn main ; +thus, +running +.Fn setprogname +is not necessary. +Programs that desire maximum portability should still call it; +on another operating system, +these functions may be implemented in a portability library. +Calling +.Fn setprogname +allows the aforementioned library to learn the program name without +modifications to the start-up code. +.Sh SEE ALSO +.Xr err 3 , +.Xr setproctitle 3 +.Sh HISTORY +These functions first appeared in +.Nx 1.6 , +and made their way into +.Fx 4.4 . diff --git a/lib/libc/gen/getpwent.3 b/lib/libc/gen/getpwent.3 new file mode 100644 index 0000000..a0509bf --- /dev/null +++ b/lib/libc/gen/getpwent.3 @@ -0,0 +1,315 @@ +.\" Copyright (c) 1988, 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. +.\" 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. +.\" +.\" From: @(#)getpwent.3 8.2 (Berkeley) 12/11/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getpwent.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 16, 2003 +.Dt GETPWENT 3 +.Os +.Sh NAME +.Nm getpwent , +.Nm getpwent_r , +.Nm getpwnam , +.Nm getpwnam_r , +.Nm getpwuid , +.Nm getpwuid_r , +.Nm setpassent , +.Nm setpwent , +.Nm endpwent +.Nd password database operations +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In pwd.h +.Ft struct passwd * +.Fn getpwent void +.Ft int +.Fn getpwent_r "struct passwd *pwd" "char *buffer" "size_t bufsize" "struct passwd **result" +.Ft struct passwd * +.Fn getpwnam "const char *login" +.Ft int +.Fn getpwnam_r "const char *name" "struct passwd *pwd" "char *buffer" "size_t bufsize" "struct passwd **result" +.Ft struct passwd * +.Fn getpwuid "uid_t uid" +.Ft int +.Fn getpwuid_r "uid_t uid" "struct passwd *pwd" "char *buffer" "size_t bufsize" "struct passwd **result" +.Ft int +.Fn setpassent "int stayopen" +.Ft void +.Fn setpwent void +.Ft void +.Fn endpwent void +.Sh DESCRIPTION +These functions +operate on the password database file +which is described +in +.Xr passwd 5 . +Each entry in the database is defined by the structure +.Vt passwd +found in the include +file +.In pwd.h : +.Bd -literal -offset indent +struct passwd { + char *pw_name; /* user name */ + char *pw_passwd; /* encrypted password */ + uid_t pw_uid; /* user uid */ + gid_t pw_gid; /* user gid */ + time_t pw_change; /* password change time */ + char *pw_class; /* user access class */ + char *pw_gecos; /* Honeywell login info */ + char *pw_dir; /* home directory */ + char *pw_shell; /* default shell */ + time_t pw_expire; /* account expiration */ + int pw_fields; /* internal: fields filled in */ +}; +.Ed +.Pp +The functions +.Fn getpwnam +and +.Fn getpwuid +search the password database for the given login name or user uid, +respectively, always returning the first one encountered. +.Pp +The +.Fn getpwent +function +sequentially reads the password database and is intended for programs +that wish to process the complete list of users. +.Pp +The functions +.Fn getpwent_r , +.Fn getpwnam_r , +and +.Fn getpwuid_r +are thread-safe versions of +.Fn getpwent , +.Fn getpwnam , +and +.Fn getpwuid , +respectively. +The caller must provide storage for the results of the search in +the +.Fa pwd , +.Fa buffer , +.Fa bufsize , +and +.Fa result +arguments. +When these functions are successful, the +.Fa pwd +argument will be filled-in, and a pointer to that argument will be +stored in +.Fa result . +If an entry is not found or an error occurs, +.Fa result +will be set to +.Dv NULL . +.Pp +The +.Fn setpassent +function +accomplishes two purposes. +First, it causes +.Fn getpwent +to ``rewind'' to the beginning of the database. +Additionally, if +.Fa stayopen +is non-zero, file descriptors are left open, significantly speeding +up subsequent accesses for all of the routines. +(This latter functionality is unnecessary for +.Fn getpwent +as it does not close its file descriptors by default.) +.Pp +It is dangerous for long-running programs to keep the file descriptors +open as the database will become out of date if it is updated while the +program is running. +.Pp +The +.Fn setpwent +function +is identical to +.Fn setpassent +with an argument of zero. +.Pp +The +.Fn endpwent +function +closes any open files. +.Pp +These routines have been written to ``shadow'' the password file, e.g.\& +allow only certain programs to have access to the encrypted password. +If the process which calls them has an effective uid of 0, the encrypted +password will be returned, otherwise, the password field of the returned +structure will point to the string +.Ql * . +.Sh RETURN VALUES +The functions +.Fn getpwent , +.Fn getpwnam , +and +.Fn getpwuid +return a valid pointer to a passwd structure on success +or +.Dv NULL +if the entry is not found or if an error occurs. +If an error does occur, +.Va errno +will be set. +Note that programs must explicitly set +.Va errno +to zero before calling any of these functions if they need to +distinguish between a non-existent entry and an error. +The functions +.Fn getpwent_r , +.Fn getpwnam_r , +and +.Fn getpwuid_r +return 0 if no error occurred, or an error number to indicate failure. +It is not an error if a matching entry is not found. +(Thus, if +.Fa result +is +.Dv NULL +and the return value is 0, no matching entry exists.) +.Pp +The +.Fn setpassent +function returns 0 on failure and 1 on success. +The +.Fn endpwent +and +.Fn setpwent +functions +have no return value. +.Sh FILES +.Bl -tag -width /etc/master.passwd -compact +.It Pa /etc/pwd.db +The insecure password database file +.It Pa /etc/spwd.db +The secure password database file +.It Pa /etc/master.passwd +The current password file +.It Pa /etc/passwd +A Version 7 format password file +.El +.Sh COMPATIBILITY +The historic function +.Xr setpwfile 3 , +which allowed the specification of alternate password databases, +has been deprecated and is no longer available. +.Sh ERRORS +These routines may fail for any of the errors specified in +.Xr open 2 , +.Xr dbopen 3 , +.Xr socket 2 , +and +.Xr connect 2 , +in addition to the following: +.Bl -tag -width Er +.It Bq Er ERANGE +The buffer specified by the +.Fa buffer +and +.Fa bufsize +arguments was insufficiently sized to store the result. +The caller should retry with a larger buffer. +.El +.Sh SEE ALSO +.Xr getlogin 2 , +.Xr getgrent 3 , +.Xr nsswitch.conf 5 , +.Xr passwd 5 , +.Xr pwd_mkdb 8 , +.Xr vipw 8 , +.Xr yp 8 +.Sh STANDARDS +The +.Fn getpwent , +.Fn getpwnam , +.Fn getpwnam_r , +.Fn getpwuid , +.Fn getpwuid_r , +.Fn setpwent , +and +.Fn endpwent +functions conform to +.St -p1003.1-96 . +.Sh HISTORY +The +.Fn getpwent , +.Fn getpwnam , +.Fn getpwuid , +.Fn setpwent , +and +.Fn endpwent +functions appeared in +.At v7 . +The +.Fn setpassent +function appeared in +.Bx 4.3 Reno . +The +.Fn getpwent_r , +.Fn getpwnam_r , +and +.Fn getpwuid_r +functions appeared in +.Fx 5.1 . +.Sh BUGS +The functions +.Fn getpwent , +.Fn getpwnam , +and +.Fn getpwuid , +leave their results in an internal static object and return +a pointer to that object. +Subsequent calls to +the same function +will modify the same object. +.Pp +The functions +.Fn getpwent , +.Fn getpwent_r , +.Fn endpwent , +.Fn setpassent , +and +.Fn setpwent +are fairly useless in a networked environment and should be +avoided, if possible. +The +.Fn getpwent +and +.Fn getpwent_r +functions +make no attempt to suppress duplicate information if multiple +sources are specified in +.Xr nsswitch.conf 5 . diff --git a/lib/libc/gen/getttyent.3 b/lib/libc/gen/getttyent.3 new file mode 100644 index 0000000..56017d1 --- /dev/null +++ b/lib/libc/gen/getttyent.3 @@ -0,0 +1,208 @@ +.\" Copyright (c) 1989, 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. +.\" 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. +.\" +.\" @(#)getttyent.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getttyent.3 202275 2010-01-14 05:37:43Z ed $ +.\" +.Dd November 17, 1996 +.Dt GETTTYENT 3 +.Os +.Sh NAME +.Nm getttyent , +.Nm getttynam , +.Nm setttyent , +.Nm endttyent , +.Nm isdialuptty , +.Nm isnettty +.Nd +.Xr ttys 5 +file routines +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ttyent.h +.Ft struct ttyent * +.Fn getttyent void +.Ft struct ttyent * +.Fn getttynam "const char *name" +.Ft int +.Fn setttyent void +.Ft int +.Fn endttyent void +.Ft int +.Fn isdialuptty "const char *name" +.Ft int +.Fn isnettty "const char *name" +.Sh DESCRIPTION +The +.Fn getttyent , +and +.Fn getttynam +functions +each return a pointer to an object, with the following structure, +containing the broken-out fields of a line from the tty description +file. +.Bd -literal +struct ttyent { + char *ty_name; /* terminal device name */ + char *ty_getty; /* command to execute, usually getty */ + char *ty_type; /* terminal type for termcap */ +#define TTY_ON 0x01 /* enable logins (start ty_getty program) */ +#define TTY_SECURE 0x02 /* allow uid of 0 to login */ +#define TTY_DIALUP 0x04 /* is a dialup tty */ +#define TTY_NETWORK 0x08 /* is a network tty */ + int ty_status; /* status flags */ + char *ty_window; /* command to start up window manager */ + char *ty_comment; /* comment field */ + char *ty_group; /* tty group name */ +}; +.Ed +.Pp +The fields are as follows: +.Bl -tag -width ty_comment +.It Fa ty_name +The name of the character-special file. +.It Fa ty_getty +The name of the command invoked by +.Xr init 8 +to initialize tty line characteristics. +.It Fa ty_type +The name of the default terminal type connected to this tty line. +.It Fa ty_status +A mask of bit fields which indicate various actions allowed on this +tty line. +The possible flags are as follows: +.Bl -tag -width TTY_NETWORK +.It Dv TTY_ON +Enables logins (i.e., +.Xr init 8 +will start the command referenced by +.Fa ty_getty +on this entry). +.It Dv TTY_SECURE +Allow users with a uid of 0 to login on this terminal. +.It Dv TTY_DIALUP +Identifies a tty as a dialin line. +If this flag is set, then +.Fn isdialuptty +will return a non-zero value. +.It Dv TTY_NETWORK +Identifies a tty used for network connections. +If this flag is set, then +.Fn isnettty +will return a non-zero value. +.El +.It Fa ty_window +The command to execute for a window system associated with the line. +.It Fa ty_group +A group name to which the tty belongs. +If no group is specified in the ttys description file, +then the tty is placed in an anonymous group called "none". +.It Fa ty_comment +Any trailing comment field, with any leading hash marks (``#'') or +whitespace removed. +.El +.Pp +If any of the fields pointing to character strings are unspecified, +they are returned as null pointers. +The field +.Fa ty_status +will be zero if no flag values are specified. +.Pp +See +.Xr ttys 5 +for a more complete discussion of the meaning and usage of the +fields. +.Pp +The +.Fn getttyent +function +reads the next line from the ttys file, opening the file if necessary. +The +.Fn setttyent +function +rewinds the file if open, or opens the file if it is unopened. +The +.Fn endttyent +function +closes any open files. +.Pp +The +.Fn getttynam +function +searches from the beginning of the file until a matching +.Fa name +is found +(or until +.Dv EOF +is encountered). +.Sh RETURN VALUES +The routines +.Fn getttyent +and +.Fn getttynam +return a null pointer on +.Dv EOF +or error. +The +.Fn setttyent +function +and +.Fn endttyent +return 0 on failure and 1 on success. +.Pp +The routines +.Fn isdialuptty +and +.Fn isnettty +return non-zero if the dialup or network flag is set for the +tty entry relating to the tty named by the argument, and +zero otherwise. +.Sh FILES +.Bl -tag -width /etc/ttys -compact +.It Pa /etc/ttys +.El +.Sh SEE ALSO +.Xr login 1 , +.Xr gettytab 5 , +.Xr termcap 5 , +.Xr ttys 5 , +.Xr getty 8 , +.Xr init 8 +.Sh HISTORY +The +.Fn getttyent , +.Fn getttynam , +.Fn setttyent , +and +.Fn endttyent +functions appeared in +.Bx 4.3 . +.Sh BUGS +These functions use static data storage; +if the data is needed for future use, it should be +copied before any subsequent calls overwrite it. diff --git a/lib/libc/gen/getusershell.3 b/lib/libc/gen/getusershell.3 new file mode 100644 index 0000000..6695271 --- /dev/null +++ b/lib/libc/gen/getusershell.3 @@ -0,0 +1,99 @@ +.\" $NetBSD: getusershell.3,v 1.6 1999/03/22 19:44:42 garbled Exp $ +.\" +.\" Copyright (c) 1985, 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. +.\" 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. +.\" +.\" @(#)getusershell.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getusershell.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd January 16, 1999 +.Dt GETUSERSHELL 3 +.Os +.Sh NAME +.Nm getusershell , +.Nm setusershell , +.Nm endusershell +.Nd get valid user shells +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft char * +.Fn getusershell void +.Ft void +.Fn setusershell void +.Ft void +.Fn endusershell void +.Sh DESCRIPTION +The +.Fn getusershell +function +returns a pointer to a valid user shell as defined by the +system manager in the shells database as described in +.Xr shells 5 . +If the shells database is not available, +.Fn getusershell +behaves as if +.Pa /bin/sh +and +.Pa /bin/csh +were listed. +.Pp +The +.Fn getusershell +function +reads the next +line (opening the file if necessary); +.Fn setusershell +rewinds the file; +.Fn endusershell +closes it. +.Sh FILES +.Bl -tag -width /etc/shells -compact +.It Pa /etc/shells +.El +.Sh DIAGNOSTICS +The routine +.Fn getusershell +returns a null pointer (0) on +.Dv EOF . +.Sh SEE ALSO +.Xr nsswitch.conf 5 , +.Xr shells 5 +.Sh HISTORY +The +.Fn getusershell +function appeared in +.Bx 4.3 . +.Sh BUGS +The +.Fn getusershell +function leaves its result in an internal static object and returns +a pointer to that object. +Subsequent calls to +.Fn getusershell +will modify the same object. diff --git a/lib/libc/gen/getutxent.3 b/lib/libc/gen/getutxent.3 new file mode 100644 index 0000000..3e6ec7d --- /dev/null +++ b/lib/libc/gen/getutxent.3 @@ -0,0 +1,478 @@ +.\" Copyright (c) 2010 Ed Schouten +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/getutxent.3 282001 2015-04-26 10:29:43Z bapt $ +.\" +.Dd October 27, 2011 +.Dt GETUTXENT 3 +.Os +.Sh NAME +.Nm endutxent , +.Nm getutxent , +.Nm getutxid , +.Nm getutxline , +.Nm getutxuser , +.Nm pututxline , +.Nm setutxdb , +.Nm setutxent +.Nd user accounting database functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In utmpx.h +.Ft void +.Fn endutxent "void" +.Ft struct utmpx * +.Fn getutxent "void" +.Ft struct utmpx * +.Fn getutxid "const struct utmpx *id" +.Ft struct utmpx * +.Fn getutxline "const struct utmpx *line" +.Ft struct utmpx * +.Fn getutxuser "const char *user" +.Ft struct utmpx * +.Fn pututxline "const struct utmpx *utmpx" +.Ft int +.Fn setutxdb "int type" "const char *file" +.Ft void +.Fn setutxent "void" +.Sh DESCRIPTION +These functions operate on the user accounting database which stores +records of various system activities, such as user login and logouts, +but also system startups and shutdowns and modifications to the system's +clock. +The system stores these records in three databases, each having a +different purpose: +.Bl -tag -width indent +.It Pa /var/run/utx.active +Log of currently active user login sessions. +This file is similar to the traditional +.Pa utmp +file. +This file only contains process related entries, such as user login and +logout records. +.It Pa /var/log/utx.lastlogin +Log of last user login entries per user. +This file is similar to the traditional +.Pa lastlog +file. +This file only contains user login records for users who have at least +logged in once. +.It Pa /var/log/utx.log +Log of all entries, sorted by date of addition. +This file is similar to the traditional +.Pa wtmp +file. +This file may contain any type of record described below. +.El +.Pp +Each entry in these databases is defined by the structure +.Vt utmpx +found in the include file +.In utmpx.h : +.Bd -literal -offset indent +struct utmpx { + short ut_type; /* Type of entry. */ + struct timeval ut_tv; /* Time entry was made. */ + char ut_id[]; /* Record identifier. */ + pid_t ut_pid; /* Process ID. */ + char ut_user[]; /* User login name. */ + char ut_line[]; /* Device name. */ + char ut_host[]; /* Remote hostname. */ +}; +.Ed +.Pp +The +.Fa ut_type +field indicates the type of the log entry, which can have one of the +following values: +.Bl -tag -width LOGIN_PROCESS +.It Dv EMPTY +No valid user accounting information. +.It Dv BOOT_TIME +Identifies time of system boot. +.It Dv SHUTDOWN_TIME +Identifies time of system shutdown. +.It Dv OLD_TIME +Identifies time when system clock changed. +.It Dv NEW_TIME +Identifies time after system clock changed. +.It Dv USER_PROCESS +Identifies a process. +.It Dv INIT_PROCESS +Identifies a process spawned by the init process. +.It Dv LOGIN_PROCESS +Identifies the session leader of a logged-in user. +.It Dv DEAD_PROCESS +Identifies a session leader who has exited. +.El +.Pp +Entries of type +.Dv INIT_PROCESS +and +.Dv LOGIN_PROCESS +are not processed by this implementation. +.Pp +Other fields inside the structure are: +.Bl -tag -width ut_user +.It Fa ut_tv +The time the event occurred. +This field is used for all types of entries, except +.Dv EMPTY . +.It Fa ut_id +An identifier that is used to refer to the entry. +This identifier can be used to remove or replace a login entry by +writing a new entry to the database containing the same value for +.Fa ut_id . +This field is only applicable to entries of type +.Dv USER_PROCESS , +.Dv INIT_PROCESS , +.Dv LOGIN_PROCESS +and +.Dv DEAD_PROCESS . +.It Fa ut_pid +The process identifier of the session leader of the login session. +This field is only applicable to entries of type +.Dv USER_PROCESS , +.Dv INIT_PROCESS , +.Dv LOGIN_PROCESS +and +.Dv DEAD_PROCESS . +.It Fa ut_user +The user login name corresponding with the login session. +This field is only applicable to entries of type +.Dv USER_PROCESS +and +.Dv INIT_PROCESS . +For +.Dv INIT_PROCESS +entries this entry typically contains the name of the login process. +.It Fa ut_line +The name of the TTY character device, without the leading +.Pa /dev/ +prefix, corresponding with the device used to facilitate the user login +session. +If no TTY character device is used, this field is left blank. +This field is only applicable to entries of type +.Dv USER_PROCESS +and +.Dv LOGIN_PROCESS . +.It Fa ut_host +The network hostname of the remote system, connecting to perform a user +login. +If the user login session is not performed across a network, this field +is left blank. +This field is only applicable to entries of type +.Dv USER_PROCESS . +.El +.Pp +This implementation guarantees all inapplicable fields are discarded. +The +.Fa ut_user , +.Fa ut_line +and +.Fa ut_host +fields of the structure returned by the library functions are also +guaranteed to be null-terminated in this implementation. +.Pp +The +.Fn getutxent +function can be used to read the next entry from the user accounting +database. +.Pp +The +.Fn getutxid +function searches for the next entry in the database of which the +behaviour is based on the +.Fa ut_type +field of +.Fa id . +If +.Fa ut_type +has a value of +.Dv BOOT_TIME , +.Dv SHUTDOWN_TIME , +.Dv OLD_TIME +or +.Dv NEW_TIME , +it will return the next entry whose +.Fa ut_type +has an equal value. +If +.Fa ut_type +has a value of +.Dv USER_PROCESS , +.Dv INIT_PROCESS , +.Dv LOGIN_PROCESS +or +.Dv DEAD_PROCESS , +it will return the next entry whose +.Fa ut_type +has one of the previously mentioned values and whose +.Fa ut_id +is equal. +.Pp +The +.Fn getutxline +function searches for the next entry in the database whose +.Fa ut_type +has a value of +.Dv USER_PROCESS +or +.Dv LOGIN_PROCESS +and whose +.Fa ut_line +is equal to the same field in +.Fa line . +.Pp +The +.Fn getutxuser +function searches for the next entry in the database whose +.Fa ut_type +has a value of +.Dv USER_PROCESS +and whose +.Fa ut_user +is equal to +.Fa user . +.Pp +The previously mentioned functions will automatically try to open the +user accounting database if not already done so. +The +.Fn setutxdb +and +.Fn setutxent +functions allow the database to be opened manually, causing the offset +within the user accounting database to be rewound. +The +.Fn endutxent +function closes the database. +.Pp +The +.Fn setutxent +database always opens the active sessions database. +The +.Fn setutxdb +function opens the database identified by +.Fa type , +whose value is either +.Dv UTXDB_ACTIVE , +.Dv UTXDB_LASTLOGIN +or +.Dv UTXDB_LOG . +It will open a custom file with filename +.Fa file +instead of the system-default if +.Fa file +is not null. +Care must be taken that when using a custom filename, +.Fa type +still has to match with the actual format, since each database may use +its own file format. +.Pp +The +.Fn pututxline +function writes record +.Fa utmpx +to the system-default user accounting databases. +The value of +.Fa ut_type +determines which databases are modified. +.Pp +Entries of type +.Dv SHUTDOWN_TIME , +.Dv OLD_TIME +and +.Dv NEW_TIME +will only be written to +.Pa /var/log/utx.log . +.Pp +Entries of type +.Dv USER_PROCESS +will also be written to +.Pa /var/run/utx.active +and +.Pa /var/log/utx.lastlogin . +.Pp +Entries of type +.Dv DEAD_PROCESS +will only be written to +.Pa /var/log/utx.log +and +.Pa /var/run/utx.active +if a corresponding +.Dv USER_PROCESS , +.Dv INIT_PROCESS +or +.Dv LOGIN_PROCESS +entry whose +.Fa ut_id +is equal has been found in the latter. +.Pp +In addition, entries of type +.Dv BOOT_TIME +and +.Dv SHUTDOWN_TIME +will cause all existing entries in +.Pa /var/run/utx.active +to be discarded. +.Pp +All entries whose type has not been mentioned previously, are discarded +by this implementation of +.Fn pututxline . +This implementation also ignores the value of +.Fa ut_tv . +.Sh RETURN VALUES +The +.Fn getutxent , +.Fn getutxid , +.Fn getutxline , +and +.Fn getutxuser +functions return a pointer to an +.Vt utmpx +structure that matches the mentioned constraints on success or +.Dv NULL +when reaching the end-of-file or when an error occurs. +.Pp +The +.Fn pututxline +function returns a pointer to an +.Vt utmpx +structure containing a copy of the structure written to disk upon +success. +It returns +.Dv NULL +when the provided +.Vt utmpx +is invalid, or +.Fa ut_type +has a value of +.Dv DEAD_PROCESS +and an entry with an identifier with a value equal to the field +.Fa ut_id +was not found; the global variable +.Va errno +is set to indicate the error. +.Pp +The +.Fn setutxdb +function returns 0 if the user accounting database was opened +successfully. +Otherwise, -1 is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +In addition to the error conditions described in +.Xr open 2 , +.Xr fdopen 3 , +.Xr fopen 3 , +.Xr fseek 3 , +the +.Fn pututxline +function can generate the following errors: +.Bl -tag -width Er +.It Bq Er ESRCH +The value of +.Fa ut_type +is DEAD_PROCESS, and the process entry could not be found. +.It Bq Er EINVAL +The value of +.Fa ut_type +is not supported by this implementation. +.El +In addition to the error conditions described in +.Xr fopen 3 , +the +.Fn setutxdb +function can generate the following errors: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa type +argument contains a value not supported by this implementation. +.It Bq Er EFTYPE +The file format is invalid. +.El +.Sh SEE ALSO +.Xr last 1 , +.Xr write 1 , +.Xr getpid 2 , +.Xr gettimeofday 2 , +.Xr tty 4 , +.Xr ac 8 , +.Xr newsyslog 8 , +.Xr utx 8 +.Sh STANDARDS +The +.Fn endutxent , +.Fn getutxent , +.Fn getutxid , +.Fn getutxline +and +.Fn setutxent +functions are expected to conform to +.St -p1003.1-2008 . +.Pp +The +.Fn pututxline +function deviates from the standard by writing its records to multiple +database files, depending on its +.Fa ut_type . +This prevents the need for special utility functions to update the other +databases, such as the +.Fn updlastlogx +and +.Fn updwtmpx +functions which are available in other implementations. +It also tries to replace +.Dv DEAD_PROCESS +entries in the active sessions database when storing +.Dv USER_PROCESS +entries and no entry with the same value for +.Fa ut_id +has been found. +The standard always requires a new entry to be allocated, which could +cause an unbounded growth of the database. +.Pp +The +.Fn getutxuser +and +.Fn setutxdb +functions, +the +.Fa ut_host +field of the +.Vt utmpx +structure and +.Dv SHUTDOWN_TIME +are extensions. +.Sh HISTORY +These functions appeared in +.Fx 9.0 . +They replaced the +.In utmp.h +interface. +.Sh AUTHORS +.An \&Ed Schouten Aq Mt ed@FreeBSD.org diff --git a/lib/libc/gen/getutxent.c b/lib/libc/gen/getutxent.c new file mode 100644 index 0000000..335112e --- /dev/null +++ b/lib/libc/gen/getutxent.c @@ -0,0 +1,246 @@ +/*- + * Copyright (c) 2010 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/getutxent.c 256537 2013-10-15 13:32:01Z glebius $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include "utxdb.h" +#include "un-namespace.h" + +#ifdef __NO_TLS +static FILE *uf = NULL; +static int udb; +#else +static _Thread_local FILE *uf = NULL; +static _Thread_local int udb; +#endif + +int +setutxdb(int db, const char *file) +{ + struct stat sb; + + switch (db) { + case UTXDB_ACTIVE: + if (file == NULL) + file = _PATH_UTX_ACTIVE; + break; + case UTXDB_LASTLOGIN: + if (file == NULL) + file = _PATH_UTX_LASTLOGIN; + break; + case UTXDB_LOG: + if (file == NULL) + file = _PATH_UTX_LOG; + break; + default: + errno = EINVAL; + return (-1); + } + + if (uf != NULL) + fclose(uf); + uf = fopen(file, "re"); + if (uf == NULL) + return (-1); + + if (db != UTXDB_LOG) { + /* Safety check: never use broken files. */ + if (_fstat(fileno(uf), &sb) != -1 && + sb.st_size % sizeof(struct futx) != 0) { + fclose(uf); + uf = NULL; + errno = EFTYPE; + return (-1); + } + /* Prevent reading of partial records. */ + (void)setvbuf(uf, NULL, _IOFBF, + rounddown(BUFSIZ, sizeof(struct futx))); + } + + udb = db; + return (0); +} + +void +setutxent(void) +{ + + setutxdb(UTXDB_ACTIVE, NULL); +} + +void +endutxent(void) +{ + + if (uf != NULL) { + fclose(uf); + uf = NULL; + } +} + +static int +getfutxent(struct futx *fu) +{ + + if (uf == NULL) + setutxent(); + if (uf == NULL) + return (-1); + + if (udb == UTXDB_LOG) { + uint16_t len; + +retry: + if (fread(&len, sizeof(len), 1, uf) != 1) + return (-1); + len = be16toh(len); + if (len == 0) { + /* + * XXX: Though zero-size records are valid in theory, + * they can never occur in practice. Zero-size records + * indicate file corruption. Seek one byte forward, to + * see if we can find a record there. + */ + ungetc('\0', uf); + goto retry; + } + if (len > sizeof *fu) { + /* Forward compatibility. */ + if (fread(fu, sizeof(*fu), 1, uf) != 1) + return (-1); + fseek(uf, len - sizeof(*fu), SEEK_CUR); + } else { + /* Partial record. */ + memset(fu, 0, sizeof(*fu)); + if (fread(fu, len, 1, uf) != 1) + return (-1); + } + } else { + if (fread(fu, sizeof(*fu), 1, uf) != 1) + return (-1); + } + return (0); +} + +struct utmpx * +getutxent(void) +{ + struct futx fu; + + if (getfutxent(&fu) != 0) + return (NULL); + return (futx_to_utx(&fu)); +} + +struct utmpx * +getutxid(const struct utmpx *id) +{ + struct futx fu; + + for (;;) { + if (getfutxent(&fu) != 0) + return (NULL); + + switch (fu.fu_type) { + case USER_PROCESS: + case INIT_PROCESS: + case LOGIN_PROCESS: + case DEAD_PROCESS: + switch (id->ut_type) { + case USER_PROCESS: + case INIT_PROCESS: + case LOGIN_PROCESS: + case DEAD_PROCESS: + if (memcmp(fu.fu_id, id->ut_id, + MIN(sizeof(fu.fu_id), sizeof(id->ut_id))) == + 0) + goto found; + } + break; + default: + if (fu.fu_type == id->ut_type) + goto found; + break; + } + } + +found: + return (futx_to_utx(&fu)); +} + +struct utmpx * +getutxline(const struct utmpx *line) +{ + struct futx fu; + + for (;;) { + if (getfutxent(&fu) != 0) + return (NULL); + + switch (fu.fu_type) { + case USER_PROCESS: + case LOGIN_PROCESS: + if (strncmp(fu.fu_line, line->ut_line, + MIN(sizeof(fu.fu_line), sizeof(line->ut_line))) == + 0) + goto found; + break; + } + } + +found: + return (futx_to_utx(&fu)); +} + +struct utmpx * +getutxuser(const char *user) +{ + struct futx fu; + + for (;;) { + if (getfutxent(&fu) != 0) + return (NULL); + + switch (fu.fu_type) { + case USER_PROCESS: + if (strncmp(fu.fu_user, user, sizeof(fu.fu_user)) == 0) + goto found; + break; + } + } + +found: + return (futx_to_utx(&fu)); +} diff --git a/lib/libc/gen/getvfsbyname.3 b/lib/libc/gen/getvfsbyname.3 new file mode 100644 index 0000000..05e17c4 --- /dev/null +++ b/lib/libc/gen/getvfsbyname.3 @@ -0,0 +1,117 @@ +.\" Copyright (c) 1995 +.\" 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. +.\" 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. +.\" +.\" @(#)kvm_getvfsbyname.3 8.3 (Berkeley) 5/4/95 +.\" $FreeBSD: releng/11.1/lib/libc/gen/getvfsbyname.3 305566 2016-09-07 21:01:32Z jilles $ +.\" +.Dd August 30, 2016 +.Dt GETVFSBYNAME 3 +.Os +.Sh NAME +.Nm getvfsbyname +.Nd get information about a file system +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/param.h +.In sys/mount.h +.Ft int +.Fn getvfsbyname "const char *name" "struct xvfsconf *vfc" +.Sh DESCRIPTION +The +.Fn getvfsbyname +function provides access to information about a +file system module that is configured in the kernel. +If successful, +the requested file system +.Fa xvfsconf +is returned in the location pointed to by +.Fa vfc . +The fields in a +.Dq Li struct xvfsconf +are defined as follows: +.Pp +.Bl -tag -compact -width vfc_refcount +.It vfc_name +the name of the file system +.It vfc_typenum +the file system type number assigned by the kernel +.It vfc_refcount +the number of active mount points using the file system +.It vfc_flags +flag bits, as described below +.El +.Pp +The flags are defined as follows: +.Pp +.Bl -tag -width VFCF_DELEGADMIN -compact +.It Dv VFCF_STATIC +statically compiled into kernel +.It Dv VFCF_NETWORK +may get data over the network +.It Dv VFCF_READONLY +writes are not implemented +.It Dv VFCF_SYNTHETIC +data does not represent real files +.It Dv VFCF_LOOPBACK +aliases some other mounted FS +.It Dv VFCF_UNICODE +stores file names as Unicode +.It Dv VFCF_JAIL +can be mounted from within a jail if +.Va security.jail.mount_allowed +sysctl is set to +.Dv 1 +.It Dv VFCF_DELEGADMIN +supports delegated administration if +.Va vfs.usermount +sysctl is set to +.Dv 1 +.El +.Sh RETURN VALUES +.Rv -std getvfsbyname +.Sh ERRORS +The following errors may be reported: +.Bl -tag -width Er +.It Bq Er ENOENT +The +.Fa name +argument +specifies a file system that is unknown or not configured in the kernel. +.El +.Sh SEE ALSO +.Xr jail 2 , +.Xr mount 2 , +.Xr sysctl 3 , +.Xr jail 8 , +.Xr mount 8 , +.Xr sysctl 8 +.Sh HISTORY +A variant of the +.Fn getvfsbyname +function first appeared in +.Fx 2.0 . diff --git a/lib/libc/gen/glob.3 b/lib/libc/gen/glob.3 new file mode 100644 index 0000000..835b877 --- /dev/null +++ b/lib/libc/gen/glob.3 @@ -0,0 +1,457 @@ +.\" Copyright (c) 1989, 1991, 1993, 1994 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Guido van Rossum. +.\" 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. +.\" 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. +.\" +.\" @(#)glob.3 8.3 (Berkeley) 4/16/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/glob.3 304284 2016-08-17 09:34:56Z ache $ +.\" +.Dd December 20, 2011 +.Dt GLOB 3 +.Os +.Sh NAME +.Nm glob , +.Nm globfree +.Nd generate pathnames matching a pattern +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In glob.h +.Ft int +.Fn glob "const char * restrict pattern" "int flags" "int (*errfunc)(const char *, int)" "glob_t * restrict pglob" +.Ft void +.Fn globfree "glob_t *pglob" +.Sh DESCRIPTION +The +.Fn glob +function +is a pathname generator that implements the rules for file name pattern +matching used by the shell. +.Pp +The include file +.In glob.h +defines the structure type +.Fa glob_t , +which contains at least the following fields: +.Bd -literal +typedef struct { + size_t gl_pathc; /* count of total paths so far */ + size_t gl_matchc; /* count of paths matching pattern */ + size_t gl_offs; /* reserved at beginning of gl_pathv */ + int gl_flags; /* returned flags */ + char **gl_pathv; /* list of paths matching pattern */ +} glob_t; +.Ed +.Pp +The argument +.Fa pattern +is a pointer to a pathname pattern to be expanded. +The +.Fn glob +argument +matches all accessible pathnames against the pattern and creates +a list of the pathnames that match. +In order to have access to a pathname, +.Fn glob +requires search permission on every component of a path except the last +and read permission on each directory of any filename component of +.Fa pattern +that contains any of the special characters +.Ql * , +.Ql ?\& +or +.Ql \&[ . +.Pp +The +.Fn glob +argument +stores the number of matched pathnames into the +.Fa gl_pathc +field, and a pointer to a list of pointers to pathnames into the +.Fa gl_pathv +field. +The first pointer after the last pathname is +.Dv NULL . +If the pattern does not match any pathnames, the returned number of +matched paths is set to zero. +.Pp +It is the caller's responsibility to create the structure pointed to by +.Fa pglob . +The +.Fn glob +function allocates other space as needed, including the memory pointed +to by +.Fa gl_pathv . +.Pp +The argument +.Fa flags +is used to modify the behavior of +.Fn glob . +The value of +.Fa flags +is the bitwise inclusive +.Tn OR +of any of the following +values defined in +.In glob.h : +.Bl -tag -width GLOB_ALTDIRFUNC +.It Dv GLOB_APPEND +Append pathnames generated to the ones from a previous call (or calls) +to +.Fn glob . +The value of +.Fa gl_pathc +will be the total matches found by this call and the previous call(s). +The pathnames are appended to, not merged with the pathnames returned by +the previous call(s). +Between calls, the caller must not change the setting of the +.Dv GLOB_DOOFFS +flag, nor change the value of +.Fa gl_offs +when +.Dv GLOB_DOOFFS +is set, nor (obviously) call +.Fn globfree +for +.Fa pglob . +.It Dv GLOB_DOOFFS +Make use of the +.Fa gl_offs +field. +If this flag is set, +.Fa gl_offs +is used to specify how many +.Dv NULL +pointers to prepend to the beginning +of the +.Fa gl_pathv +field. +In other words, +.Fa gl_pathv +will point to +.Fa gl_offs +.Dv NULL +pointers, +followed by +.Fa gl_pathc +pathname pointers, followed by a +.Dv NULL +pointer. +.It Dv GLOB_ERR +Causes +.Fn glob +to return when it encounters a directory that it cannot open or read. +Ordinarily, +.Fn glob +continues to find matches. +.It Dv GLOB_MARK +Each pathname that is a directory that matches +.Fa pattern +has a slash +appended. +.It Dv GLOB_NOCHECK +If +.Fa pattern +does not match any pathname, then +.Fn glob +returns a list +consisting of only +.Fa pattern , +with the number of total pathnames set to 1, and the number of matched +pathnames set to 0. +The effect of backslash escaping is present in the pattern returned. +.It Dv GLOB_NOESCAPE +By default, a backslash +.Pq Ql \e +character is used to escape the following character in the pattern, +avoiding any special interpretation of the character. +If +.Dv GLOB_NOESCAPE +is set, backslash escaping is disabled. +.It Dv GLOB_NOSORT +By default, the pathnames are sorted in ascending +.Tn ASCII +order; +this flag prevents that sorting (speeding up +.Fn glob ) . +.El +.Pp +The following values may also be included in +.Fa flags , +however, they are non-standard extensions to +.St -p1003.2 . +.Bl -tag -width GLOB_ALTDIRFUNC +.It Dv GLOB_ALTDIRFUNC +The following additional fields in the pglob structure have been +initialized with alternate functions for glob to use to open, read, +and close directories and to get stat information on names found +in those directories. +.Bd -literal +void *(*gl_opendir)(const char * name); +struct dirent *(*gl_readdir)(void *); +void (*gl_closedir)(void *); +int (*gl_lstat)(const char *name, struct stat *st); +int (*gl_stat)(const char *name, struct stat *st); +.Ed +.Pp +This extension is provided to allow programs such as +.Xr restore 8 +to provide globbing from directories stored on tape. +.It Dv GLOB_BRACE +Pre-process the pattern string to expand +.Ql {pat,pat,...} +strings like +.Xr csh 1 . +The pattern +.Ql {} +is left unexpanded for historical reasons (and +.Xr csh 1 +does the same thing to +ease typing +of +.Xr find 1 +patterns). +.It Dv GLOB_MAGCHAR +Set by the +.Fn glob +function if the pattern included globbing characters. +See the description of the usage of the +.Fa gl_matchc +structure member for more details. +.It Dv GLOB_NOMAGIC +Is the same as +.Dv GLOB_NOCHECK +but it only appends the +.Fa pattern +if it does not contain any of the special characters ``*'', ``?'' or ``[''. +.Dv GLOB_NOMAGIC +is provided to simplify implementing the historic +.Xr csh 1 +globbing behavior and should probably not be used anywhere else. +.It Dv GLOB_TILDE +Expand patterns that start with +.Ql ~ +to user name home directories. +.It Dv GLOB_LIMIT +Limit the total number of returned pathnames to the value provided in +.Fa gl_matchc +(default +.Dv ARG_MAX ) . +This option should be set for programs +that can be coerced into a denial of service attack +via patterns that expand to a very large number of matches, +such as a long string of +.Ql */../*/.. . +.El +.Pp +If, during the search, a directory is encountered that cannot be opened +or read and +.Fa errfunc +is +.Pf non- Dv NULL , +.Fn glob +calls +.Fa \*(lp*errfunc\*(rp Ns ( Fa path , errno ) , +however, the +.Dv GLOB_ERR +flag will cause an immediate +return when this happens. +.Pp +If +.Fa errfunc +returns non-zero, +.Fn glob +stops the scan and returns +.Dv GLOB_ABORTED +after setting +.Fa gl_pathc +and +.Fa gl_pathv +to reflect any paths already matched. +This also happens if an error is encountered and +.Dv GLOB_ERR +is set in +.Fa flags , +regardless of the return value of +.Fa errfunc , +if called. +If +.Dv GLOB_ERR +is not set and either +.Fa errfunc +is +.Dv NULL +or +.Fa errfunc +returns zero, the error is ignored. +.Pp +The +.Fn globfree +function frees any space associated with +.Fa pglob +from a previous call(s) to +.Fn glob . +.Sh RETURN VALUES +On successful completion, +.Fn glob +returns zero. +In addition the fields of +.Fa pglob +contain the values described below: +.Bl -tag -width GLOB_NOCHECK +.It Fa gl_pathc +contains the total number of matched pathnames so far. +This includes other matches from previous invocations of +.Fn glob +if +.Dv GLOB_APPEND +was specified. +.It Fa gl_matchc +contains the number of matched pathnames in the current invocation of +.Fn glob . +.It Fa gl_flags +contains a copy of the +.Fa flags +argument with the bit +.Dv GLOB_MAGCHAR +set if +.Fa pattern +contained any of the special characters ``*'', ``?'' or ``['', cleared +if not. +.It Fa gl_pathv +contains a pointer to a +.Dv NULL Ns -terminated +list of matched pathnames. +However, if +.Fa gl_pathc +is zero, the contents of +.Fa gl_pathv +are undefined. +.El +.Pp +If +.Fn glob +terminates due to an error, it sets errno and returns one of the +following non-zero constants, which are defined in the include +file +.In glob.h : +.Bl -tag -width GLOB_NOCHECK +.It Dv GLOB_NOSPACE +An attempt to allocate memory failed, or if +.Fa errno +was E2BIG, +.Dv GLOB_LIMIT +was specified in the flags and +.Fa pglob\->gl_matchc +or more patterns were matched. +.It Dv GLOB_ABORTED +The scan was stopped because an error was encountered and either +.Dv GLOB_ERR +was set or +.Fa \*(lp*errfunc\*(rp\*(lp\*(rp +returned non-zero. +.It Dv GLOB_NOMATCH +The pattern did not match a pathname and +.Dv GLOB_NOCHECK +was not set. +.El +.Pp +The arguments +.Fa pglob\->gl_pathc +and +.Fa pglob\->gl_pathv +are still set as specified above. +.Sh EXAMPLES +A rough equivalent of +.Ql "ls -l *.c *.h" +can be obtained with the +following code: +.Bd -literal -offset indent +glob_t g; + +g.gl_offs = 2; +glob("*.c", GLOB_DOOFFS, NULL, &g); +glob("*.h", GLOB_DOOFFS | GLOB_APPEND, NULL, &g); +g.gl_pathv[0] = "ls"; +g.gl_pathv[1] = "-l"; +execvp("ls", g.gl_pathv); +.Ed +.Sh SEE ALSO +.Xr sh 1 , +.Xr fnmatch 3 , +.Xr regex 3 +.Sh STANDARDS +The current implementation of the +.Fn glob +function +.Em does not +conform to +.St -p1003.2 . +Collating symbol expressions, equivalence class expressions and +character class expressions are not supported. +.Pp +The flags +.Dv GLOB_ALTDIRFUNC , +.Dv GLOB_BRACE , +.Dv GLOB_LIMIT , +.Dv GLOB_MAGCHAR , +.Dv GLOB_NOMAGIC , +and +.Dv GLOB_TILDE , +and the fields +.Fa gl_matchc +and +.Fa gl_flags +are extensions to the +.Tn POSIX +standard and +should not be used by applications striving for strict +conformance. +.Sh HISTORY +The +.Fn glob +and +.Fn globfree +functions first appeared in +.Bx 4.4 . +.Sh BUGS +Patterns longer than +.Dv MAXPATHLEN +may cause unchecked errors. +.Pp +The +.Fn glob +argument +may fail and set errno for any of the errors specified for the +library routines +.Xr stat 2 , +.Xr closedir 3 , +.Xr opendir 3 , +.Xr readdir 3 , +.Xr malloc 3 , +and +.Xr free 3 . diff --git a/lib/libc/gen/initgroups.3 b/lib/libc/gen/initgroups.3 new file mode 100644 index 0000000..8a97bc0 --- /dev/null +++ b/lib/libc/gen/initgroups.3 @@ -0,0 +1,82 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)initgroups.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/initgroups.3 273717 2014-10-27 04:09:23Z markj $ +.\" +.Dd October 26, 2014 +.Dt INITGROUPS 3 +.Os +.Sh NAME +.Nm initgroups +.Nd initialize group access list +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn initgroups "const char *name" "gid_t basegid" +.Sh DESCRIPTION +The +.Fn initgroups +function +uses the +.Xr getgrouplist 3 +function to calculate the group access list for the user +specified in +.Fa name . +This group list is then setup for the current process using +.Xr setgroups 2 . +The +.Fa basegid +is automatically included in the groups list. +Typically this value is given as +the group number from the password file. +.Sh RETURN VALUES +.Rv -std initgroups +.Sh ERRORS +The +.Fn initgroups +function may fail and set +.Va errno +for any of the errors specified for the library function +.Xr setgroups 2 . +It may also return: +.Bl -tag -width Er +.It Bq Er ENOMEM +The +.Fn initgroups +function was unable to allocate temporary storage. +.El +.Sh SEE ALSO +.Xr setgroups 2 , +.Xr getgrouplist 3 +.Sh HISTORY +The +.Fn initgroups +function appeared in +.Bx 4.2 . diff --git a/lib/libc/gen/isgreater.3 b/lib/libc/gen/isgreater.3 new file mode 100644 index 0000000..f876357 --- /dev/null +++ b/lib/libc/gen/isgreater.3 @@ -0,0 +1,102 @@ +.\" Copyright (c) 2003 David Schultz +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/isgreater.3 208291 2010-05-19 08:57:53Z uqs $ +.\" +.Dd February 12, 2003 +.Dt ISGREATER 3 +.Os +.Sh NAME +.Nm isgreater , isgreaterequal , isless , islessequal , +.Nm islessgreater , isunordered +.Nd "compare two floating-point numbers" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In math.h +.Ft int +.Fn isgreater "real-floating x" "real-floating y" +.Ft int +.Fn isgreaterequal "real-floating x" "real-floating y" +.Ft int +.Fn isless "real-floating x" "real-floating y" +.Ft int +.Fn islessequal "real-floating x" "real-floating y" +.Ft int +.Fn islessgreater "real-floating x" "real-floating y" +.Ft int +.Fn isunordered "real-floating x" "real-floating y" +.Sh DESCRIPTION +Each of the macros +.Fn isgreater , +.Fn isgreaterequal , +.Fn isless , +.Fn islessequal , +and +.Fn islessgreater +take arguments +.Fa x +and +.Fa y +and return a non-zero value if and only if its nominal +relation on +.Fa x +and +.Fa y +is true. +These macros always return zero if either +argument is not a number (NaN), but unlike the corresponding C +operators, they never raise a floating point exception. +.Pp +The +.Fn isunordered +macro takes arguments +.Fa x +and +.Fa y +and returns non-zero if and only if neither +.Fa x +nor +.Fa y +are NaNs. +For any pair of floating-point values, one +of the relationships (less, greater, equal, unordered) holds. +.Sh SEE ALSO +.Xr fpclassify 3 , +.Xr math 3 , +.Xr signbit 3 +.Sh STANDARDS +The +.Fn isgreater , +.Fn isgreaterequal , +.Fn isless , +.Fn islessequal , +.Fn islessgreater , +and +.Fn isunordered +macros conform to +.St -isoC-99 . +.Sh HISTORY +The relational macros described above first appeared in +.Fx 5.1 . diff --git a/lib/libc/gen/ldexp.3 b/lib/libc/gen/ldexp.3 new file mode 100644 index 0000000..21659df --- /dev/null +++ b/lib/libc/gen/ldexp.3 @@ -0,0 +1,77 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)ldexp.3 8.2 (Berkeley) 4/19/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/ldexp.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd March 4, 2005 +.Dt LDEXP 3 +.Os +.Sh NAME +.Nm ldexp , +.Nm ldexpf , +.Nm ldexpl +.Nd multiply floating-point number by integral power of 2 +.Sh LIBRARY +.Lb libm +.Sh SYNOPSIS +.In math.h +.Ft double +.Fn ldexp "double x" "int exp" +.Ft float +.Fn ldexpf "float x" "int exp" +.Ft long double +.Fn ldexpl "long double x" "int exp" +.Sh DESCRIPTION +The +.Fn ldexp , +.Fn ldexpf , +and +.Fn ldexpl +functions multiply a floating-point number by an integral +power of 2. +.Sh RETURN VALUES +These functions return the value of +.Fa x +times 2 raised to the power +.Fa exp . +.Sh SEE ALSO +.Xr frexp 3 , +.Xr math 3 , +.Xr modf 3 +.Sh STANDARDS +The +.Fn ldexp , +.Fn ldexpf , +and +.Fn ldexpl +functions conform to +.St -isoC-99 . diff --git a/lib/libc/gen/libc_dlopen.c b/lib/libc/gen/libc_dlopen.c new file mode 100644 index 0000000..47767bf --- /dev/null +++ b/lib/libc/gen/libc_dlopen.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2011 Xin Li + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/gen/libc_dlopen.c 228843 2011-12-23 15:00:37Z cperciva $ + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/libc_dlopen.c 228843 2011-12-23 15:00:37Z cperciva $"); + +#include +#include +#include + +#include "libc_private.h" + +/* + * Whether we want to restrict dlopen()s. + */ +static int __libc_restricted_mode = 0; + +void * +libc_dlopen(const char *path, int mode) +{ + + if (__libc_restricted_mode) { + _rtld_error("Service unavailable -- libc in restricted mode"); + return (NULL); + } else + return (dlopen(path, mode)); +} + +void +__FreeBSD_libc_enter_restricted_mode(void) +{ + + __libc_restricted_mode = 1; + return; +} + diff --git a/lib/libc/gen/lockf.3 b/lib/libc/gen/lockf.3 new file mode 100644 index 0000000..ed71b8e --- /dev/null +++ b/lib/libc/gen/lockf.3 @@ -0,0 +1,266 @@ +.\" $NetBSD: lockf.3,v 1.10 2008/04/30 13:10:50 martin Exp $ +.\" +.\" Copyright (c) 1997 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Klaus Klein and S.P. Zeidler. +.\" +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/lockf.3 255486 2013-09-12 00:53:38Z bdrewery $ +.\" +.Dd September 11, 2013 +.Dt LOCKF 3 +.Os +.Sh NAME +.Nm lockf +.Nd record locking on files +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn lockf "int fd" "int function" "off_t size" +.Sh DESCRIPTION +The +.Fn lockf +function allows sections of a file to be locked with advisory-mode locks. +Calls to +.Fn lockf +from other processes which attempt to lock the locked file section will +either return an error value or block until the section becomes unlocked. +All the locks for a process are removed when the process terminates. +.Pp +The argument +.Fa fd +is an open file descriptor. +The file descriptor must have been opened either for write-only +.Dv ( O_WRONLY ) +or read/write +.Dv ( O_RDWR ) +operation. +.Pp +The +.Fa function +argument is a control value which specifies the action to be taken. +The permissible values for +.Fa function +are as follows: +.Bl -tag -width F_ULOCKXX -compact -offset indent +.It Sy Function +.Sy Description +.It Dv F_ULOCK +unlock locked sections +.It Dv F_LOCK +lock a section for exclusive use +.It Dv F_TLOCK +test and lock a section for exclusive use +.It Dv F_TEST +test a section for locks by other processes +.El +.Pp +.Dv F_ULOCK +removes locks from a section of the file; +.Dv F_LOCK +and +.Dv F_TLOCK +both lock a section of a file if the section is available; +.Dv F_TEST +detects if a lock by another process is present on the specified section. +.Pp +The +.Fa size +argument is the number of contiguous bytes to be locked or +unlocked. +The section to be locked or unlocked starts at the current +offset in the file and extends forward for a positive size or backward +for a negative size (the preceding bytes up to but not including the +current offset). +However, it is not permitted to lock a section that +starts or extends before the beginning of the file. +If +.Fa size +is 0, the section from the current offset through the largest possible +file offset is locked (that is, from the current offset through the +present or any future end-of-file). +.Pp +The sections locked with +.Dv F_LOCK +or +.Dv F_TLOCK +may, in whole or in part, contain or be contained by a previously +locked section for the same process. +When this occurs, or if adjacent +locked sections would occur, the sections are combined into a single +locked section. +If the request would cause the number of locks to +exceed a system-imposed limit, the request will fail. +.Pp +.Dv F_LOCK +and +.Dv F_TLOCK +requests differ only by the action taken if the section is not +available. +.Dv F_LOCK +blocks the calling process until the section is available. +.Dv F_TLOCK +makes the function fail if the section is already locked by another +process. +.Pp +File locks are released on first close by the locking process of any +file descriptor for the file. +.Pp +.Dv F_ULOCK +requests release (wholly or in part) one or more locked sections +controlled by the process. +Locked sections will be unlocked starting +at the current file offset through +.Fa size +bytes or to the end of file if size is 0. +When all of a locked section +is not released (that is, when the beginning or end of the area to be +unlocked falls within a locked section), the remaining portions of +that section are still locked by the process. +Releasing the center +portion of a locked section will cause the remaining locked beginning +and end portions to become two separate locked sections. +If the +request would cause the number of locks in the system to exceed a +system-imposed limit, the request will fail. +.Pp +An +.Dv F_ULOCK +request in which size is non-zero and the offset of the last byte of +the requested section is the maximum value for an object of type +off_t, when the process has an existing lock in which size is 0 and +which includes the last byte of the requested section, will be treated +as a request to unlock from the start of the requested section with a +size equal to 0. +Otherwise an +.Dv F_ULOCK +request will attempt to unlock only the requested section. +.Pp +A potential for deadlock occurs if a process controlling a locked +region is put to sleep by attempting to lock the locked region of +another process. +This implementation detects that sleeping until a +locked region is unlocked would cause a deadlock and fails with an +.Er EDEADLK +error. +.Pp +The +.Fn lockf , +.Xr fcntl 2 , +and +.Xr flock 2 +locks are compatible. +Processes using different locking interfaces can cooperate +over the same file safely. +However, only one of such interfaces should be used within +the same process. +If a file is locked by a process through +.Xr flock 2 , +any record within the file will be seen as locked +from the viewpoint of another process using +.Xr fcntl 2 +or +.Fn lockf , +and vice versa. +.Pp +Blocking on a section is interrupted by any signal. +.Sh RETURN VALUES +.Rv -std lockf +In the case of a failure, existing locks are not changed. +.Sh ERRORS +The +.Fn lockf +function +will fail if: +.Bl -tag -width Er +.It Bq Er EAGAIN +The argument +.Fa function +is +.Dv F_TLOCK +or +.Dv F_TEST +and the section is already locked by another process. +.It Bq Er EBADF +The argument +.Fa fd +is not a valid open file descriptor. +.Pp +The argument +.Fa function +is +.Dv F_LOCK +or +.Dv F_TLOCK , +and +.Fa fd +is not a valid file descriptor open for writing. +.It Bq Er EDEADLK +The argument +.Fa function +is +.Dv F_LOCK +and a deadlock is detected. +.It Bq Er EINTR +The argument +.Fa function +is F_LOCK +and +.Fn lockf +was interrupted by the delivery of a signal. +.It Bq Er EINVAL +The argument +.Fa function +is not one of +.Dv F_ULOCK , +.Dv F_LOCK , +.Dv F_TLOCK +or +.Dv F_TEST . +.Pp +The argument +.Fa fd +refers to a file that does not support locking. +.It Bq Er ENOLCK +The argument +.Fa function +is +.Dv F_ULOCK , +.Dv F_LOCK +or +.Dv F_TLOCK , +and satisfying the lock or unlock request would result in the number +of locked regions in the system exceeding a system-imposed limit. +.El +.Sh SEE ALSO +.Xr fcntl 2 , +.Xr flock 2 +.Sh STANDARDS +The +.Fn lockf +function conforms to +.St -xpg4.2 . diff --git a/lib/libc/gen/makecontext.3 b/lib/libc/gen/makecontext.3 new file mode 100644 index 0000000..6cddaa1 --- /dev/null +++ b/lib/libc/gen/makecontext.3 @@ -0,0 +1,120 @@ +.\" Copyright (c) 2002 Packet Design, LLC. +.\" All rights reserved. +.\" +.\" Subject to the following obligations and disclaimer of warranty, +.\" use and redistribution of this software, in source or object code +.\" forms, with or without modifications are expressly permitted by +.\" Packet Design; provided, however, that: +.\" +.\" (i) Any and all reproductions of the source or object code +.\" must include the copyright notice above and the following +.\" disclaimer of warranties; and +.\" (ii) No rights are granted, in any manner or form, to use +.\" Packet Design trademarks, including the mark "PACKET DESIGN" +.\" on advertising, endorsements, or otherwise except as such +.\" appears in the above copyright notice or in the software. +.\" +.\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND +.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO +.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING +.\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED +.\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, +.\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE, +.\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS +.\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, +.\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE +.\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE +.\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL +.\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF +.\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 PACKET DESIGN IS ADVISED OF +.\" THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/makecontext.3 108087 2002-12-19 09:40:28Z ru $ +.\" +.Dd September 10, 2002 +.Dt MAKECONTEXT 3 +.Os +.Sh NAME +.Nm makecontext , swapcontext +.Nd modify and exchange user thread contexts +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ucontext.h +.Ft void +.Fo makecontext +.Fa "ucontext_t *ucp" +.Fa "void \*[lp]*func\*[rp]\*[lp]void\*[rp]" +.Fa "int argc" ... +.Fc +.Ft int +.Fn swapcontext "ucontext_t *oucp" "const ucontext_t *ucp" +.Sh DESCRIPTION +The +.Fn makecontext +function +modifies the user thread context pointed to by +.Fa ucp , +which must have previously been initialized by a call to +.Xr getcontext 3 +and had a stack allocated for it. +The context is modified so that it will continue execution by invoking +.Fn func +with the arguments provided. +The +.Fa argc +argument +must be equal to the number of additional arguments provided to +.Fn makecontext +and also equal to the number of arguments to +.Fn func , +or else the behavior is undefined. +.Pp +The +.Fa "ucp->uc_link" +argument +must be initialized before calling +.Fn makecontext +and determines the action to take when +.Fn func +returns: +if equal to +.Dv NULL , +the process exits; +otherwise, +.Fn setcontext "ucp->uc_link" +is implicitly invoked. +.Pp +The +.Fn swapcontext +function +saves the current thread context in +.Fa "*oucp" +and makes +.Fa "*ucp" +the currently active context. +.Sh RETURN VALUES +If successful, +.Fn swapcontext +returns zero; +otherwise \-1 is returned and the global variable +.Va errno +is set appropriately. +.Sh ERRORS +The +.Fn swapcontext +function +will fail if: +.Bl -tag -width Er +.It Bq Er ENOMEM +There is not enough stack space in +.Fa ucp +to complete the operation. +.El +.Sh SEE ALSO +.Xr setcontext 3 , +.Xr ucontext 3 diff --git a/lib/libc/gen/modf.3 b/lib/libc/gen/modf.3 new file mode 100644 index 0000000..f4ca7b2 --- /dev/null +++ b/lib/libc/gen/modf.3 @@ -0,0 +1,81 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)modf.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/modf.3 177710 2008-03-29 16:19:35Z das $ +.\" +.Dd March 29, 2008 +.Dt MODF 3 +.Os +.Sh NAME +.Nm modf , +.Nm modff , +.Nm modfl +.Nd extract signed integral and fractional values from floating-point number +.Sh LIBRARY +.Lb libm +.Sh SYNOPSIS +.In math.h +.Ft double +.Fn modf "double value" "double *iptr" +.Ft float +.Fn modff "float value" "float *iptr" +.Ft long double +.Fn modfl "long double value" "long double *iptr" +.Sh DESCRIPTION +The +.Fn modf , +.Fn modff , +and +.Fn modfl +functions break the argument +.Fa value +into integral and fractional parts, each of which has the +same sign as the argument. +It stores the integral part as a +floating point number +in the object pointed to by +.Fa iptr . +.Sh RETURN VALUES +These functions return the signed fractional part of +.Fa value . +.Sh SEE ALSO +.Xr frexp 3 , +.Xr ldexp 3 , +.Xr math 3 +.Sh STANDARDS +The +.Fn modf , +.Fn modff , +and +.Fn modfl +functions conform to +.St -isoC-99 . diff --git a/lib/libc/gen/modf.c b/lib/libc/gen/modf.c new file mode 100644 index 0000000..8b4ccc1 --- /dev/null +++ b/lib/libc/gen/modf.c @@ -0,0 +1,138 @@ +/* @(#)s_modf.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/modf.c 226606 2011-10-21 06:40:36Z das $"); + +/* + * modf(double x, double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ + +#include +#include +#include + +/* Bit fiddling routines copied from msun/src/math_private.h,v 1.15 */ + +#if BYTE_ORDER == BIG_ENDIAN + +typedef union +{ + double value; + struct + { + u_int32_t msw; + u_int32_t lsw; + } parts; +} ieee_double_shape_type; + +#endif + +#if BYTE_ORDER == LITTLE_ENDIAN + +typedef union +{ + double value; + struct + { + u_int32_t lsw; + u_int32_t msw; + } parts; +} ieee_double_shape_type; + +#endif + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +static const double one = 1.0; + +double +modf(double x, double *iptr) +{ + int32_t i0,i1,j0; + u_int32_t i; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ + if(j0<20) { /* integer part in high x */ + if(j0<0) { /* |x|<1 */ + INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ + return x; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) { /* x is integral */ + u_int32_t high; + *iptr = x; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr,i0&(~i),0); + return x - *iptr; + } + } + } else if (j0>51) { /* no fraction part */ + u_int32_t high; + if (j0 == 0x400) { /* inf/NaN */ + *iptr = x; + return 0.0 / x; + } + *iptr = x*one; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { /* fraction part in low x */ + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) { /* x is integral */ + u_int32_t high; + *iptr = x; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr,i0,i1&(~i)); + return x - *iptr; + } + } +} diff --git a/lib/libc/gen/nice.3 b/lib/libc/gen/nice.3 new file mode 100644 index 0000000..c2f2e75 --- /dev/null +++ b/lib/libc/gen/nice.3 @@ -0,0 +1,97 @@ +.\" Copyright (c) 1980, 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. +.\" 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. +.\" +.\" @(#)nice.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/nice.3 282008 2015-04-26 10:56:06Z bapt $ +.\" +.Dd February 28, 2015 +.Dt NICE 3 +.Os +.Sh NAME +.Nm nice +.Nd set program scheduling priority +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn nice "int incr" +.Sh DESCRIPTION +.Bf -symbolic +This interface is obsoleted by +.Xr setpriority 2 . +.Ef +.Pp +The +.Fn nice +function adds +.Fa incr +to the scheduling priority of the process. +The priority is a value in the range -20 to 20. +The default priority is 0; lower priorities cause more favorable scheduling. +Only the super-user may lower priorities. +.Pp +Children inherit the priority of their parent processes via +.Xr fork 2 . +.Sh RETURN VALUES +Upon successful completion, +.Fn nice +returns 0, and +.Va errno +is unchanged. +Otherwise, \-1 is returned, the process' nice value is not changed, and +.Va errno +is set to indicate the error. +.Sh ERRORS +The +.Fn nice +function will fail if: +.Bl -tag -width Er +.It Bq Er EPERM +The +.Fa incr +argument is negative and the caller does not have appropriate privileges. +.El +.Sh SEE ALSO +.Xr nice 1 , +.Xr fork 2 , +.Xr setpriority 2 , +.Xr renice 8 +.Sh STANDARDS +The +.Fn nice +function conforms to +.St -p1003.1-2008 +except for the return value. +This implementation returns 0 upon successful completion but +the standard requires returning the new nice value, +which could be \-1. +.Sh HISTORY +A +.Fn nice +syscall appeared in +.At v6 . diff --git a/lib/libc/gen/nlist.3 b/lib/libc/gen/nlist.3 new file mode 100644 index 0000000..0b7df86 --- /dev/null +++ b/lib/libc/gen/nlist.3 @@ -0,0 +1,77 @@ +.\" Copyright (c) 1980, 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. +.\" 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. +.\" +.\" @(#)nlist.3 8.3 (Berkeley) 4/19/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/nlist.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 19, 1994 +.Dt NLIST 3 +.Os +.Sh NAME +.Nm nlist +.Nd retrieve symbol table name list from an executable file +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In nlist.h +.Ft int +.Fn nlist "const char *filename" "struct nlist *nl" +.Sh DESCRIPTION +The +.Fn nlist +function +retrieves name list entries from the symbol table of an +executable file (see +.Xr a.out 5 ) . +The argument +.Fa \&nl +is set to reference the +beginning of the list. +The list is preened of binary and invalid data; +if an entry in the +name list is valid, the +.Fa n_type +and +.Fa n_value +for the entry are copied into the list +referenced by +.Fa \&nl . +No other data is copied. +The last entry in the list is always +.Dv NULL . +.Sh RETURN VALUES +The number of invalid entries is returned if successful; otherwise, +if the file +.Fa filename +does not exist or is not executable, the returned value is \-1. +.Sh SEE ALSO +.Xr a.out 5 +.Sh HISTORY +A +.Fn nlist +function appeared in +.At v6 . diff --git a/lib/libc/gen/pause.3 b/lib/libc/gen/pause.3 new file mode 100644 index 0000000..9828530 --- /dev/null +++ b/lib/libc/gen/pause.3 @@ -0,0 +1,82 @@ +.\" Copyright (c) 1980, 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. +.\" 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. +.\" +.\" @(#)pause.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/pause.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 4, 1993 +.Dt PAUSE 3 +.Os +.Sh NAME +.Nm pause +.Nd stop until signal +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn pause void +.Sh DESCRIPTION +.Sy Pause is made obsolete by +.Xr sigsuspend 2 . +.Pp +The +.Fn pause +function +forces a process to pause until +a signal is received from either the +.Xr kill 2 +function +or an interval timer. +(See +.Xr setitimer 2 . ) +Upon termination of a signal handler started during a +.Fn pause , +the +.Fn pause +call will return. +.Sh RETURN VALUES +Always returns \-1. +.Sh ERRORS +The +.Fn pause +function +always returns: +.Bl -tag -width Er +.It Bq Er EINTR +The call was interrupted. +.El +.Sh SEE ALSO +.Xr kill 2 , +.Xr select 2 , +.Xr sigsuspend 2 +.Sh HISTORY +A +.Fn pause +syscall +appeared in +.At v6 . diff --git a/lib/libc/gen/popen.3 b/lib/libc/gen/popen.3 new file mode 100644 index 0000000..bcb6dab --- /dev/null +++ b/lib/libc/gen/popen.3 @@ -0,0 +1,202 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)popen.3 8.2 (Berkeley) 5/3/95 +.\" $FreeBSD: releng/11.1/lib/libc/gen/popen.3 250827 2013-05-20 17:31:18Z jilles $ +.\" +.Dd May 20, 2013 +.Dt POPEN 3 +.Os +.Sh NAME +.Nm popen , +.Nm pclose +.Nd process +.Tn I/O +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdio.h +.Ft FILE * +.Fn popen "const char *command" "const char *type" +.Ft int +.Fn pclose "FILE *stream" +.Sh DESCRIPTION +The +.Fn popen +function +.Dq opens +a process by creating a bidirectional pipe +forking, +and invoking the shell. +Any streams opened by previous +.Fn popen +calls in the parent process are closed in the new child process. +Historically, +.Fn popen +was implemented with a unidirectional pipe; +hence many implementations of +.Fn popen +only allow the +.Fa type +argument to specify reading or writing, not both. +Since +.Fn popen +is now implemented using a bidirectional pipe, the +.Fa type +argument may request a bidirectional data flow. +The +.Fa type +argument is a pointer to a null-terminated string +which must be +.Ql r +for reading, +.Ql w +for writing, or +.Ql r+ +for reading and writing. +.Pp +A letter +.Ql e +may be appended to that to request that the underlying file descriptor +be set close-on-exec. +.Pp +The +.Fa command +argument is a pointer to a null-terminated string +containing a shell command line. +This command is passed to +.Pa /bin/sh +using the +.Fl c +flag; interpretation, if any, is performed by the shell. +.Pp +The return value from +.Fn popen +is a normal standard +.Tn I/O +stream in all respects +save that it must be closed with +.Fn pclose +rather than +.Fn fclose . +Writing to such a stream +writes to the standard input of the command; +the command's standard output is the same as that of the process that called +.Fn popen , +unless this is altered by the command itself. +Conversely, reading from a +.Dq popened +stream reads the command's standard output, and +the command's standard input is the same as that of the process that called +.Fn popen . +.Pp +Note that output +.Fn popen +streams are fully buffered by default. +.Pp +The +.Fn pclose +function waits for the associated process to terminate +and returns the exit status of the command +as returned by +.Xr wait4 2 . +.Sh RETURN VALUES +The +.Fn popen +function returns +.Dv NULL +if the +.Xr fork 2 +or +.Xr pipe 2 +calls fail, +or if it cannot allocate memory. +.Pp +The +.Fn pclose +function +returns \-1 if +.Fa stream +is not associated with a +.Dq popened +command, if +.Fa stream +already +.Dq pclosed , +or if +.Xr wait4 2 +returns an error. +.Sh ERRORS +The +.Fn popen +function does not reliably set +.Va errno . +.Sh SEE ALSO +.Xr sh 1 , +.Xr fork 2 , +.Xr pipe 2 , +.Xr wait4 2 , +.Xr fclose 3 , +.Xr fflush 3 , +.Xr fopen 3 , +.Xr stdio 3 , +.Xr system 3 +.Sh HISTORY +A +.Fn popen +and a +.Fn pclose +function appeared in +.At v7 . +.Pp +Bidirectional functionality was added in +.Fx 2.2.6 . +.Sh BUGS +Since the standard input of a command opened for reading +shares its seek offset with the process that called +.Fn popen , +if the original process has done a buffered read, +the command's input position may not be as expected. +Similarly, the output from a command opened for writing +may become intermingled with that of the original process. +The latter can be avoided by calling +.Xr fflush 3 +before +.Fn popen . +.Pp +Failure to execute the shell +is indistinguishable from the shell's failure to execute command, +or an immediate exit of the command. +The only hint is an exit status of 127. +.Pp +The +.Fn popen +function +always calls +.Xr sh 1 , +never calls +.Xr csh 1 . diff --git a/lib/libc/gen/posix_spawn.3 b/lib/libc/gen/posix_spawn.3 new file mode 100644 index 0000000..316fb1e --- /dev/null +++ b/lib/libc/gen/posix_spawn.3 @@ -0,0 +1,460 @@ +.\" Copyright (c) 2008 Ed Schouten +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/posix_spawn.3 293204 2016-01-05 16:21:20Z jilles $ +.\" +.Dd January 5, 2016 +.Dt POSIX_SPAWN 3 +.Os +.Sh NAME +.Nm posix_spawn , +.Nm posix_spawnp +.Nd "spawn a process" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In spawn.h +.Ft int +.Fn posix_spawn "pid_t *restrict pid" "const char *restrict path" "const posix_spawn_file_actions_t *file_actions" "const posix_spawnattr_t *restrict attrp" "char *const argv[restrict]" "char *const envp[restrict]" +.Ft int +.Fn posix_spawnp "pid_t *restrict pid" "const char *restrict file" "const posix_spawn_file_actions_t *file_actions" "const posix_spawnattr_t *restrict attrp" "char *const argv[restrict]" "char *const envp[restrict]" +.Sh DESCRIPTION +The +.Fn posix_spawn +and +.Fn posix_spawnp +functions create a new process (child process) from the specified +process image. +The new process image is constructed from a regular executable +file called the new process image file. +.Pp +When a C program is executed as the result of this call, it is +entered as a C-language function call as follows: +.Bd -literal -offset indent +int main(int argc, char *argv[]); +.Ed +.Pp +where +.Fa argc +is the argument count and +.Fa argv +is an array of character pointers to the arguments themselves. +In addition, the variable: +.Bd -literal -offset indent +extern char **environ; +.Ed +.Pp +points to an array of character pointers to +the environment strings. +.Pp +The argument +.Fa argv +is an array of character pointers to null-terminated +strings. +The last member of this array is a null pointer and is not counted +in +.Fa argc . +These strings constitute the argument list available to the new process +image. +The value in +.Fa argv Ns [0] +should point to +a filename that is associated with the process image being started by +the +.Fn posix_spawn +or +.Fn posix_spawnp +function. +.Pp +The argument +.Fa envp +is an array of character pointers to null-terminated strings. +These strings constitute the environment for the new process image. +The environment array is terminated by a null pointer. +.Pp +The +.Fa path +argument to +.Fn posix_spawn +is a pathname that identifies the new process image file to execute. +.Pp +The +.Fa file +parameter to +.Fn posix_spawnp +is used to construct a pathname that identifies the new process +image file. +If the file parameter contains a slash character, the file parameter +is used as the pathname for the new process image file. +Otherwise, the path prefix for this file is obtained by a search +of the directories passed as the environment variable +.Dq Ev PATH . +If this variable is not specified, +the default path is set according to the +.Dv _PATH_DEFPATH +definition in +.In paths.h , +which is set to +.Dq Ev /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin . +.Pp +If +.Fa file_actions +is a null pointer, then file descriptors open in the +calling process remain open in the child process, except for those +whose close-on-exec flag +.Dv FD_CLOEXEC +is set (see +.Fn fcntl ) . +For those +file descriptors that remain open, all attributes of the corresponding +open file descriptions, including file locks (see +.Fn fcntl ) , +remain unchanged. +.Pp +If +.Fa file_actions +is not NULL, then the file descriptors open in the child process are +those open in the calling process as modified by the spawn file +actions object pointed to by +.Fa file_actions +and the +.Dv FD_CLOEXEC +flag of each remaining open file descriptor after the spawn file actions +have been processed. +The effective order of processing the spawn file actions are: +.Bl -enum +.It +The set of open file descriptors for the child process initially +are the same set as is open for the calling process. +All attributes of the corresponding open file descriptions, including +file locks (see +.Fn fcntl ) , +remain unchanged. +.It +The signal mask, signal default actions, and the effective user and +group IDs for the child process are changed as specified in the +attributes object referenced by +.Fa attrp . +.It +The file actions specified by the spawn file actions object are +performed in the order in which they were added to the spawn file +actions object. +.It +Any file descriptor that has its +.Dv FD_CLOEXEC +flag set (see +.Fn fcntl ) +is closed. +.El +.Pp +The +.Vt posix_spawnattr_t +spawn attributes object type is defined in +.In spawn.h . +It contains the attributes defined below. +.Pp +If the +.Dv POSIX_SPAWN_SETPGROUP +flag is set in the spawn-flags attribute of the object referenced by +.Fa attrp , +and the spawn-pgroup attribute of the same object is non-zero, then the +child's process group is as specified in the spawn-pgroup +attribute of the object referenced by +.Fa attrp . +.Pp +As a special case, if the +.Dv POSIX_SPAWN_SETPGROUP +flag is set in the spawn-flags attribute of the object referenced by +.Fa attrp , +and the spawn-pgroup attribute of the same object is set to zero, then +the child is in a new process group with a process group ID equal +to its process ID. +.Pp +If the +.Dv POSIX_SPAWN_SETPGROUP +flag is not set in the spawn-flags attribute of the object referenced by +.Fa attrp , +the new child process inherits the parent's process group. +.Pp +If the +.Dv POSIX_SPAWN_SETSCHEDPARAM +flag is set in the spawn-flags attribute of the object referenced by +.Fa attrp , +but +.Dv POSIX_SPAWN_SETSCHEDULER +is not set, the new process image initially has the scheduling +policy of the calling process with the scheduling parameters specified +in the spawn-schedparam attribute of the object referenced by +.Fa attrp . +.Pp +If the +.Dv POSIX_SPAWN_SETSCHEDULER +flag is set in the spawn-flags attribute of the object referenced by +.Fa attrp +(regardless of the setting of the +.Dv POSIX_SPAWN_SETSCHEDPARAM +flag), the new process image initially has the scheduling policy +specified in the spawn-schedpolicy attribute of the object referenced by +.Fa attrp +and the scheduling parameters specified in the spawn-schedparam +attribute of the same object. +.Pp +The +.Dv POSIX_SPAWN_RESETIDS +flag in the spawn-flags attribute of the object referenced by +.Fa attrp +governs the effective user ID of the child process. +If this flag is not set, the child process inherits the parent +process' effective user ID. +If this flag is set, the child process' effective user ID is reset +to the parent's real user ID. +In either case, if the set-user-ID mode bit of the new process image +file is set, the effective user ID of the child process becomes +that file's owner ID before the new process image begins execution. +.Pp +The +.Dv POSIX_SPAWN_RESETIDS +flag in the spawn-flags attribute of the object referenced by +.Fa attrp +also governs the effective group ID of the child process. +If this flag is not set, the child process inherits the parent +process' effective group ID. +If this flag is set, the child process' effective group ID is +reset to the parent's real group ID. +In either case, if the set-group-ID mode bit of the new process image +file is set, the effective group ID of the child process becomes +that file's group ID before the new process image begins execution. +.Pp +If the +.Dv POSIX_SPAWN_SETSIGMASK +flag is set in the spawn-flags attribute of the object referenced by +.Fa attrp , +the child process initially has the signal mask specified in the +spawn-sigmask attribute of the object referenced by +.Fa attrp . +.Pp +If the +.Dv POSIX_SPAWN_SETSIGDEF +flag is set in the spawn-flags attribute of the object referenced by +.Fa attrp , +the signals specified in the spawn-sigdefault attribute of the same +object is set to their default actions in the child process. +Signals set to the default action in the parent process is set to +the default action in the child process. +.Pp +Signals set to be caught by the calling process is set to the +default action in the child process. +.Pp +Signals set to be ignored by the calling process image is set to +be ignored by the child process, unless otherwise specified by the +.Dv POSIX_SPAWN_SETSIGDEF +flag being set in the spawn-flags attribute of the object referenced by +.Fa attrp +and the signals being indicated in the spawn-sigdefault attribute +of the object referenced by +.Fa attrp . +.Pp +If the value of the +.Fa attrp +pointer is NULL, then the default values are used. +.Pp +All process attributes, other than those influenced by the attributes +set in the object referenced by +.Fa attrp +as specified above or by the file descriptor manipulations specified in +.Fa file_actions , +appear in the new process image as though +.Fn vfork +had been called to create a child process and then +.Fn execve +had been called by the child process to execute the new process image. +.Pp +The implementation uses vfork(), thus the fork handlers are not run when +.Fn posix_spawn +or +.Fn posix_spawnp +is called. +.Sh RETURN VALUES +Upon successful completion, +.Fn posix_spawn +and +.Fn posix_spawnp +return the process ID of the child process to the parent process, +in the variable pointed to by a non-NULL +.Fa pid +argument, and return zero as the function return value. +Otherwise, no child process is created, no value is stored into +the variable pointed to by +.Fa pid , +and an error number is returned as the function return value to +indicate the error. +If the +.Fa pid +argument is a null pointer, the process ID of the child is not returned +to the caller. +.Sh ERRORS +.Bl -enum +.It +If +.Fn posix_spawn +and +.Fn posix_spawnp +fail for any of the reasons that would cause +.Fn vfork +or one of the +.Nm exec +to fail, an error value is returned as described by +.Fn vfork +and +.Nm exec , +respectively (or, if the error occurs after the calling process successfully +returns, the child process exits with exit status 127). +.It +If +.Nm POSIX_SPAWN_SETPGROUP +is set in the spawn-flags attribute of the object referenced by attrp, and +.Fn posix_spawn +or +.Fn posix_spawnp +fails while changing the child's process group, an error value is returned as +described by +.Fn setpgid +(or, if the error occurs after the calling process successfully returns, +the child process exits with exit status 127). +.It +If +.Nm POSIX_SPAWN_SETSCHEDPARAM +is set and +.Nm POSIX_SPAWN_SETSCHEDULER +is not set in the spawn-flags attribute of the object referenced by attrp, then +if +.Fn posix_spawn +or +.Fn posix_spawnp +fails for any of the reasons that would cause +.Fn sched_setparam +to fail, an error value is returned as described by +.Fn sched_setparam +(or, if the error occurs after the calling process successfully returns, the +child process exits with exit status 127). +.It +If +.Nm POSIX_SPAWN_SETSCHEDULER +is set in the spawn-flags attribute of the object referenced by attrp, and if +.Fn posix_spawn +or +.Fn posix_spawnp +fails for any of the reasons that would cause +.Fn sched_setscheduler +to fail, an error value is returned as described by +.Fn sched_setscheduler +(or, if the error occurs after the calling process successfully returns, +the child process exits with exit status 127). +.It +If the +.Fa file_actions +argument is not NULL, and specifies any dup2 or open actions to be +performed, and if +.Fn posix_spawn +or +.Fn posix_spawnp +fails for any of the reasons that would cause +.Fn dup2 +or +.Fn open +to fail, an error value is returned as described by +.Fn dup2 +and +.Fn open , +respectively (or, if the error occurs after the calling process successfully +returns, the child process exits with exit status 127). An open file action +may, by itself, result in any of the errors described by +.Fn dup2 , +in addition to those described by +.Fn open . +This implementation ignores any errors from +.Fn close , +including trying to close a descriptor that is not open. +.El +.Sh SEE ALSO +.Xr close 2 , +.Xr dup2 2 , +.Xr execve 2 , +.Xr fcntl 2 , +.Xr open 2 , +.Xr sched_setparam 2 , +.Xr sched_setscheduler 2 , +.Xr setpgid 2 , +.Xr vfork 2 , +.Xr posix_spawn_file_actions_addclose 3 , +.Xr posix_spawn_file_actions_adddup2 3 , +.Xr posix_spawn_file_actions_addopen 3 , +.Xr posix_spawn_file_actions_destroy 3 , +.Xr posix_spawn_file_actions_init 3 , +.Xr posix_spawnattr_destroy 3 , +.Xr posix_spawnattr_getflags 3 , +.Xr posix_spawnattr_getpgroup 3 , +.Xr posix_spawnattr_getschedparam 3 , +.Xr posix_spawnattr_getschedpolicy 3 , +.Xr posix_spawnattr_getsigdefault 3 , +.Xr posix_spawnattr_getsigmask 3 , +.Xr posix_spawnattr_init 3 , +.Xr posix_spawnattr_setflags 3 , +.Xr posix_spawnattr_setpgroup 3 , +.Xr posix_spawnattr_setschedparam 3 , +.Xr posix_spawnattr_setschedpolicy 3 , +.Xr posix_spawnattr_setsigdefault 3 , +.Xr posix_spawnattr_setsigmask 3 +.Sh STANDARDS +The +.Fn posix_spawn +and +.Fn posix_spawnp +functions conform to +.St -p1003.1-2001 , +except that they ignore all errors from +.Fn close . +A future update of the Standard is expected to require that these functions +not fail because a file descriptor to be closed (via +.Fn posix_spawn_file_actions_addclose ) +is not open. +.Sh HISTORY +The +.Fn posix_spawn +and +.Fn posix_spawnp +functions first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An \&Ed Schouten Aq Mt ed@FreeBSD.org diff --git a/lib/libc/gen/posix_spawn.c b/lib/libc/gen/posix_spawn.c new file mode 100644 index 0000000..853eadb --- /dev/null +++ b/lib/libc/gen/posix_spawn.c @@ -0,0 +1,481 @@ +/*- + * Copyright (c) 2008 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/posix_spawn.c 300662 2016-05-25 07:13:53Z truckman $"); + +#include "namespace.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" + +extern char **environ; + +struct __posix_spawnattr { + short sa_flags; + pid_t sa_pgroup; + struct sched_param sa_schedparam; + int sa_schedpolicy; + sigset_t sa_sigdefault; + sigset_t sa_sigmask; +}; + +struct __posix_spawn_file_actions { + STAILQ_HEAD(, __posix_spawn_file_actions_entry) fa_list; +}; + +typedef struct __posix_spawn_file_actions_entry { + STAILQ_ENTRY(__posix_spawn_file_actions_entry) fae_list; + enum { FAE_OPEN, FAE_DUP2, FAE_CLOSE } fae_action; + + int fae_fildes; + union { + struct { + char *path; +#define fae_path fae_data.open.path + int oflag; +#define fae_oflag fae_data.open.oflag + mode_t mode; +#define fae_mode fae_data.open.mode + } open; + struct { + int newfildes; +#define fae_newfildes fae_data.dup2.newfildes + } dup2; + } fae_data; +} posix_spawn_file_actions_entry_t; + +/* + * Spawn routines + */ + +static int +process_spawnattr(const posix_spawnattr_t sa) +{ + struct sigaction sigact = { .sa_flags = 0, .sa_handler = SIG_DFL }; + int i; + + /* + * POSIX doesn't really describe in which order everything + * should be set. We'll just set them in the order in which they + * are mentioned. + */ + + /* Set process group */ + if (sa->sa_flags & POSIX_SPAWN_SETPGROUP) { + if (setpgid(0, sa->sa_pgroup) != 0) + return (errno); + } + + /* Set scheduler policy */ + if (sa->sa_flags & POSIX_SPAWN_SETSCHEDULER) { + if (sched_setscheduler(0, sa->sa_schedpolicy, + &sa->sa_schedparam) != 0) + return (errno); + } else if (sa->sa_flags & POSIX_SPAWN_SETSCHEDPARAM) { + if (sched_setparam(0, &sa->sa_schedparam) != 0) + return (errno); + } + + /* Reset user ID's */ + if (sa->sa_flags & POSIX_SPAWN_RESETIDS) { + if (setegid(getgid()) != 0) + return (errno); + if (seteuid(getuid()) != 0) + return (errno); + } + + /* + * Set signal masks/defaults. + * Use unwrapped syscall, libthr is in undefined state after vfork(). + */ + if (sa->sa_flags & POSIX_SPAWN_SETSIGMASK) { + __sys_sigprocmask(SIG_SETMASK, &sa->sa_sigmask, NULL); + } + + if (sa->sa_flags & POSIX_SPAWN_SETSIGDEF) { + for (i = 1; i <= _SIG_MAXSIG; i++) { + if (sigismember(&sa->sa_sigdefault, i)) + if (__sys_sigaction(i, &sigact, NULL) != 0) + return (errno); + } + } + + return (0); +} + +static int +process_file_actions_entry(posix_spawn_file_actions_entry_t *fae) +{ + int fd, saved_errno; + + switch (fae->fae_action) { + case FAE_OPEN: + /* Perform an open(), make it use the right fd */ + fd = _open(fae->fae_path, fae->fae_oflag, fae->fae_mode); + if (fd < 0) + return (errno); + if (fd != fae->fae_fildes) { + if (_dup2(fd, fae->fae_fildes) == -1) { + saved_errno = errno; + (void)_close(fd); + return (saved_errno); + } + if (_close(fd) != 0) { + if (errno == EBADF) + return (EBADF); + } + } + if (_fcntl(fae->fae_fildes, F_SETFD, 0) == -1) + return (errno); + break; + case FAE_DUP2: + /* Perform a dup2() */ + if (_dup2(fae->fae_fildes, fae->fae_newfildes) == -1) + return (errno); + if (_fcntl(fae->fae_newfildes, F_SETFD, 0) == -1) + return (errno); + break; + case FAE_CLOSE: + /* Perform a close(), do not fail if already closed */ + (void)_close(fae->fae_fildes); + break; + } + return (0); +} + +static int +process_file_actions(const posix_spawn_file_actions_t fa) +{ + posix_spawn_file_actions_entry_t *fae; + int error; + + /* Replay all file descriptor modifications */ + STAILQ_FOREACH(fae, &fa->fa_list, fae_list) { + error = process_file_actions_entry(fae); + if (error) + return (error); + } + return (0); +} + +static int +do_posix_spawn(pid_t *pid, const char *path, + const posix_spawn_file_actions_t *fa, + const posix_spawnattr_t *sa, + char * const argv[], char * const envp[], int use_env_path) +{ + pid_t p; + volatile int error = 0; + + p = vfork(); + switch (p) { + case -1: + return (errno); + case 0: + if (sa != NULL) { + error = process_spawnattr(*sa); + if (error) + _exit(127); + } + if (fa != NULL) { + error = process_file_actions(*fa); + if (error) + _exit(127); + } + if (use_env_path) + _execvpe(path, argv, envp != NULL ? envp : environ); + else + _execve(path, argv, envp != NULL ? envp : environ); + error = errno; + _exit(127); + default: + if (error != 0) + _waitpid(p, NULL, WNOHANG); + else if (pid != NULL) + *pid = p; + return (error); + } +} + +int +posix_spawn(pid_t *pid, const char *path, + const posix_spawn_file_actions_t *fa, + const posix_spawnattr_t *sa, + char * const argv[], char * const envp[]) +{ + return do_posix_spawn(pid, path, fa, sa, argv, envp, 0); +} + +int +posix_spawnp(pid_t *pid, const char *path, + const posix_spawn_file_actions_t *fa, + const posix_spawnattr_t *sa, + char * const argv[], char * const envp[]) +{ + return do_posix_spawn(pid, path, fa, sa, argv, envp, 1); +} + +/* + * File descriptor actions + */ + +int +posix_spawn_file_actions_init(posix_spawn_file_actions_t *ret) +{ + posix_spawn_file_actions_t fa; + + fa = malloc(sizeof(struct __posix_spawn_file_actions)); + if (fa == NULL) + return (-1); + + STAILQ_INIT(&fa->fa_list); + *ret = fa; + return (0); +} + +int +posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *fa) +{ + posix_spawn_file_actions_entry_t *fae; + + while ((fae = STAILQ_FIRST(&(*fa)->fa_list)) != NULL) { + /* Remove file action entry from the queue */ + STAILQ_REMOVE_HEAD(&(*fa)->fa_list, fae_list); + + /* Deallocate file action entry */ + if (fae->fae_action == FAE_OPEN) + free(fae->fae_path); + free(fae); + } + + free(*fa); + return (0); +} + +int +posix_spawn_file_actions_addopen(posix_spawn_file_actions_t * __restrict fa, + int fildes, const char * __restrict path, int oflag, mode_t mode) +{ + posix_spawn_file_actions_entry_t *fae; + int error; + + if (fildes < 0) + return (EBADF); + + /* Allocate object */ + fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); + if (fae == NULL) + return (errno); + + /* Set values and store in queue */ + fae->fae_action = FAE_OPEN; + fae->fae_path = strdup(path); + if (fae->fae_path == NULL) { + error = errno; + free(fae); + return (error); + } + fae->fae_fildes = fildes; + fae->fae_oflag = oflag; + fae->fae_mode = mode; + + STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); + return (0); +} + +int +posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *fa, + int fildes, int newfildes) +{ + posix_spawn_file_actions_entry_t *fae; + + if (fildes < 0 || newfildes < 0) + return (EBADF); + + /* Allocate object */ + fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); + if (fae == NULL) + return (errno); + + /* Set values and store in queue */ + fae->fae_action = FAE_DUP2; + fae->fae_fildes = fildes; + fae->fae_newfildes = newfildes; + + STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); + return (0); +} + +int +posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *fa, + int fildes) +{ + posix_spawn_file_actions_entry_t *fae; + + if (fildes < 0) + return (EBADF); + + /* Allocate object */ + fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); + if (fae == NULL) + return (errno); + + /* Set values and store in queue */ + fae->fae_action = FAE_CLOSE; + fae->fae_fildes = fildes; + + STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); + return (0); +} + +/* + * Spawn attributes + */ + +int +posix_spawnattr_init(posix_spawnattr_t *ret) +{ + posix_spawnattr_t sa; + + sa = calloc(1, sizeof(struct __posix_spawnattr)); + if (sa == NULL) + return (errno); + + /* Set defaults as specified by POSIX, cleared above */ + *ret = sa; + return (0); +} + +int +posix_spawnattr_destroy(posix_spawnattr_t *sa) +{ + free(*sa); + return (0); +} + +int +posix_spawnattr_getflags(const posix_spawnattr_t * __restrict sa, + short * __restrict flags) +{ + *flags = (*sa)->sa_flags; + return (0); +} + +int +posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict sa, + pid_t * __restrict pgroup) +{ + *pgroup = (*sa)->sa_pgroup; + return (0); +} + +int +posix_spawnattr_getschedparam(const posix_spawnattr_t * __restrict sa, + struct sched_param * __restrict schedparam) +{ + *schedparam = (*sa)->sa_schedparam; + return (0); +} + +int +posix_spawnattr_getschedpolicy(const posix_spawnattr_t * __restrict sa, + int * __restrict schedpolicy) +{ + *schedpolicy = (*sa)->sa_schedpolicy; + return (0); +} + +int +posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict sa, + sigset_t * __restrict sigdefault) +{ + *sigdefault = (*sa)->sa_sigdefault; + return (0); +} + +int +posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict sa, + sigset_t * __restrict sigmask) +{ + *sigmask = (*sa)->sa_sigmask; + return (0); +} + +int +posix_spawnattr_setflags(posix_spawnattr_t *sa, short flags) +{ + (*sa)->sa_flags = flags; + return (0); +} + +int +posix_spawnattr_setpgroup(posix_spawnattr_t *sa, pid_t pgroup) +{ + (*sa)->sa_pgroup = pgroup; + return (0); +} + +int +posix_spawnattr_setschedparam(posix_spawnattr_t * __restrict sa, + const struct sched_param * __restrict schedparam) +{ + (*sa)->sa_schedparam = *schedparam; + return (0); +} + +int +posix_spawnattr_setschedpolicy(posix_spawnattr_t *sa, int schedpolicy) +{ + (*sa)->sa_schedpolicy = schedpolicy; + return (0); +} + +int +posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict sa, + const sigset_t * __restrict sigdefault) +{ + (*sa)->sa_sigdefault = *sigdefault; + return (0); +} + +int +posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict sa, + const sigset_t * __restrict sigmask) +{ + (*sa)->sa_sigmask = *sigmask; + return (0); +} diff --git a/lib/libc/gen/posix_spawn_file_actions_addopen.3 b/lib/libc/gen/posix_spawn_file_actions_addopen.3 new file mode 100644 index 0000000..dfad7c3 --- /dev/null +++ b/lib/libc/gen/posix_spawn_file_actions_addopen.3 @@ -0,0 +1,203 @@ +.\" Copyright (c) 2008 Ed Schouten +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/posix_spawn_file_actions_addopen.3 282003 2015-04-26 10:52:37Z bapt $ +.\" +.Dd May 9, 2013 +.Dt POSIX_SPAWN_FILE_ACTIONS_ADDOPEN 3 +.Os +.Sh NAME +.Nm posix_spawn_file_actions_addopen , +.Nm posix_spawn_file_actions_adddup2 , +.Nm posix_spawn_file_actions_addclose +.Nd "add open, dup2 or close action to spawn file actions object" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In spawn.h +.Ft int +.Fn posix_spawn_file_actions_addopen "posix_spawn_file_actions_t * file_actions" "int fildes" "const char *restrict path" "int oflag" "mode_t mode" +.Ft int +.Fn posix_spawn_file_actions_adddup2 "posix_spawn_file_actions_t * file_actions" "int fildes" "int newfildes" +.Ft int +.Fn posix_spawn_file_actions_addclose "posix_spawn_file_actions_t * file_actions" "int fildes" +.Sh DESCRIPTION +These functions add an open, dup2 or close action to a spawn +file actions object. +.Pp +A spawn file actions object is of type +.Vt posix_spawn_file_actions_t +(defined in +.In spawn.h ) +and is used to specify a series of actions to be performed by a +.Fn posix_spawn +or +.Fn posix_spawnp +operation in order to arrive at the set of open file descriptors for the +child process given the set of open file descriptors of the parent. +.Pp +A spawn file actions object, when passed to +.Fn posix_spawn +or +.Fn posix_spawnp , +specify how the set of open file descriptors in the calling +process is transformed into a set of potentially open file descriptors +for the spawned process. +This transformation is as if the specified sequence of actions was +performed exactly once, in the context of the spawned process (prior to +execution of the new process image), in the order in which the actions +were added to the object; additionally, when the new process image is +executed, any file descriptor (from this new set) which has its +.Dv FD_CLOEXEC +flag set is closed (see +.Fn posix_spawn ) . +.Pp +The +.Fn posix_spawn_file_actions_addopen +function adds an open action to the object referenced by +.Fa file_actions +that causes the file named by +.Fa path +to be opened (as if +.Bd -literal -offset indent +open(path, oflag, mode) +.Ed +.Pp +had been called, and the returned file descriptor, if not +.Fa fildes , +had been changed to +.Fa fildes ) +when a new process is spawned using this file actions object. +If +.Fa fildes +was already an open file descriptor, it is closed before the new +file is opened. +.Pp +The string described by +.Fa path +is copied by the +.Fn posix_spawn_file_actions_addopen +function. +.Pp +The +.Fn posix_spawn_file_actions_adddup2 +function adds a dup2 action to the object referenced by +.Fa file_actions +that causes the file descriptor +.Fa fildes +to be duplicated as +.Fa newfildes +(as if +.Bd -literal -offset indent +dup2(fildes, newfildes) +.Ed +.Pp +had been called) when a new process is spawned using this file actions object, +except that the +.Dv FD_CLOEXEC +flag for +.Fa newfildes +is cleared even if +.Fa fildes +is equal to +.Fa newfildes . +The difference from +.Fn dup2 +is useful for passing a particular file descriptor +to a particular child process. +.Pp +The +.Fn posix_spawn_file_actions_addclose +function adds a close action to the object referenced by +.Fa file_actions +that causes the file descriptor +.Fa fildes +to be closed (as if +.Bd -literal -offset indent +close(fildes) +.Ed +.Pp +had been called) when a new process is spawned using this file actions +object. +.Sh RETURN VALUES +Upon successful completion, these functions return zero; +otherwise, an error number is returned to indicate the error. +.Sh ERRORS +These +functions fail if: +.Bl -tag -width Er +.It Bq Er EBADF +The value specified by +.Fa fildes +or +.Fa newfildes +is negative. +.It Bq Er ENOMEM +Insufficient memory exists to add to the spawn file actions object. +.El +.Sh SEE ALSO +.Xr close 2 , +.Xr dup2 2 , +.Xr open 2 , +.Xr posix_spawn 3 , +.Xr posix_spawn_file_actions_destroy 3 , +.Xr posix_spawn_file_actions_init 3 , +.Xr posix_spawnp 3 +.Sh STANDARDS +The +.Fn posix_spawn_file_actions_addopen , +.Fn posix_spawn_file_actions_adddup2 +and +.Fn posix_spawn_file_actions_addclose +functions conform to +.St -p1003.1-2001 , +with the exception of the behavior of +.Fn posix_spawn_file_actions_adddup2 +if +.Fa fildes +is equal to +.Fa newfildes +(clearing +.Dv FD_CLOEXEC ) . +A future update of the Standard is expected to require this behavior. +.Sh HISTORY +The +.Fn posix_spawn_file_actions_addopen , +.Fn posix_spawn_file_actions_adddup2 +and +.Fn posix_spawn_file_actions_addclose +functions first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An \&Ed Schouten Aq Mt ed@FreeBSD.org diff --git a/lib/libc/gen/posix_spawn_file_actions_init.3 b/lib/libc/gen/posix_spawn_file_actions_init.3 new file mode 100644 index 0000000..1a6bcb1 --- /dev/null +++ b/lib/libc/gen/posix_spawn_file_actions_init.3 @@ -0,0 +1,104 @@ +.\" Copyright (c) 2008 Ed Schouten +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/posix_spawn_file_actions_init.3 282003 2015-04-26 10:52:37Z bapt $ +.\" +.Dd March 24, 2008 +.Dt POSIX_SPAWN_FILE_ACTIONS_INIT 3 +.Os +.Sh NAME +.Nm posix_spawn_file_actions_init , +.Nm posix_spawn_file_actions_destroy +.Nd "initialize and destroy spawn file actions object" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In spawn.h +.Ft int +.Fn posix_spawn_file_actions_init "posix_spawn_file_actions_t * file_actions" +.Ft int +.Fn posix_spawn_file_actions_destroy "posix_spawn_file_actions_t * file_actions" +.Sh DESCRIPTION +The +.Fn posix_spawn_file_actions_init +function initialize the object referenced by +.Fn file_actions +to contain no file actions for +.Fn posix_spawn +or +.Fn posix_spawnp . +Initializing an already initialized spawn file actions object may cause +memory to be leaked. +.Pp +The +.Fn posix_spawn_file_actions_destroy +function destroy the object referenced by +.Fa file_actions ; +the object becomes, in effect, uninitialized. +A destroyed spawn file actions object can be reinitialized using +.Fn posix_spawn_file_actions_init . +The object should not be used after it has been destroyed. +.Sh RETURN VALUES +Upon successful completion, these functions return zero; +otherwise, an error number is returned to indicate the error. +.Sh ERRORS +The +.Fn posix_spawn_file_actions_init +function will fail if: +.Bl -tag -width Er +.It Bq Er ENOMEM +Insufficient memory exists to initialize the spawn file actions object. +.El +.Sh SEE ALSO +.Xr posix_spawn 3 , +.Xr posix_spawn_file_actions_addclose 3 , +.Xr posix_spawn_file_actions_adddup2 3 , +.Xr posix_spawn_file_actions_addopen 3 , +.Xr posix_spawnp 3 +.Sh STANDARDS +The +.Fn posix_spawn_file_actions_init +and +.Fn posix_spawn_file_actions_destroy +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn posix_spawn_file_actions_init +and +.Fn posix_spawn_file_actions_destroy +functions first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An \&Ed Schouten Aq Mt ed@FreeBSD.org diff --git a/lib/libc/gen/posix_spawnattr_getflags.3 b/lib/libc/gen/posix_spawnattr_getflags.3 new file mode 100644 index 0000000..3cbd5d2 --- /dev/null +++ b/lib/libc/gen/posix_spawnattr_getflags.3 @@ -0,0 +1,111 @@ +.\" Copyright (c) 2008 Ed Schouten +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/posix_spawnattr_getflags.3 282003 2015-04-26 10:52:37Z bapt $ +.\" +.Dd March 24, 2008 +.Dt POSIX_SPAWNATTR_GETFLAGS 3 +.Os +.Sh NAME +.Nm posix_spawnattr_getflags , +.Nm posix_spawnattr_setflags +.Nd "get and set the spawn-flags attribute of a spawn attributes object" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In spawn.h +.Ft int +.Fn posix_spawnattr_getflags "const posix_spawnattr_t *restrict attr" "short *restrict flags" +.Ft int +.Fn posix_spawnattr_setflags "posix_spawnattr_t *attr" "short flags" +.Sh DESCRIPTION +The +.Fn posix_spawnattr_getflags +function obtains the value of the spawn-flags attribute from the +attributes object referenced by +.Fa attr . +.Pp +The +.Fn posix_spawnattr_setflags +function sets the spawn-flags attribute in an initialized +attributes object referenced by +.Fa attr . +.Pp +The spawn-flags attribute is used to indicate which process attributes +are to be changed in the new process image when invoking +.Fn posix_spawn +or +.Fn posix_spawnp . +It is the bitwise-inclusive OR of zero or more of the following flags +(see +.Fn posix_spawn ) : +.Bl -tag -width "POSIX_SPAWN_SETSCHEDPARAM" -offset indent +.It Dv POSIX_SPAWN_RESETIDS +.It Dv POSIX_SPAWN_SETPGROUP +.It Dv POSIX_SPAWN_SETSIGDEF +.It Dv POSIX_SPAWN_SETSIGMASK +.It Dv POSIX_SPAWN_SETSCHEDPARAM +.It Dv POSIX_SPAWN_SETSCHEDULER +.El +.Pp +These flags are defined in +.In spawn.h . +The default value of this attribute is as if no flags were set. +.Sh RETURN VALUES +The +.Fn posix_spawnattr_getflags +and +.Fn posix_spawnattr_setflags +functions return zero. +.Sh SEE ALSO +.Xr posix_spawn 3 , +.Xr posix_spawnattr_destroy 3 , +.Xr posix_spawnattr_init 3 , +.Xr posix_spawnp 3 +.Sh STANDARDS +The +.Fn posix_spawnattr_getflags +and +.Fn posix_spawnattr_setflags +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn posix_spawnattr_getflags +and +.Fn posix_spawnattr_setflags +functions first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An \&Ed Schouten Aq Mt ed@FreeBSD.org diff --git a/lib/libc/gen/posix_spawnattr_getpgroup.3 b/lib/libc/gen/posix_spawnattr_getpgroup.3 new file mode 100644 index 0000000..b4918a5 --- /dev/null +++ b/lib/libc/gen/posix_spawnattr_getpgroup.3 @@ -0,0 +1,96 @@ +.\" Copyright (c) 2008 Ed Schouten +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/posix_spawnattr_getpgroup.3 282003 2015-04-26 10:52:37Z bapt $ +.\" +.Dd March 24, 2008 +.Dt POSIX_SPAWNATTR_GETPGROUP 3 +.Os +.Sh NAME +.Nm posix_spawnattr_getpgroup , +.Nm posix_spawnattr_setpgroup +.Nd "get and set the spawn-pgroup attribute of a spawn attributes object" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In spawn.h +.Ft int +.Fn posix_spawnattr_getpgroup "const posix_spawnattr_t *restrict attr" "pid_t *restrict pgroup" +.Ft int +.Fn posix_spawnattr_setpgroup "posix_spawnattr_t *attr" "pid_t pgroup" +.Sh DESCRIPTION +The +.Fn posix_spawnattr_getpgroup +function obtains the value of the spawn-pgroup attribute from the +attributes object referenced by +.Fa attr . +.Pp +The +.Fn posix_spawnattr_setpgroup +function sets the spawn-pgroup attribute in an initialized +attributes object referenced by +.Fa attr . +.Pp +The spawn-pgroup attribute represents the process group to be joined by +the new process image in a spawn operation (if +.Dv POSIX_SPAWN_SETPGROUP +is set in the spawn-flags attribute). +The default value of this attribute is zero. +.Sh RETURN VALUES +The +.Fn posix_spawnattr_getpgroup +and +.Fn posix_spawnattr_setpgroup +functions return zero. +.Sh SEE ALSO +.Xr posix_spawn 3 , +.Xr posix_spawnattr_destroy 3 , +.Xr posix_spawnattr_init 3 , +.Xr posix_spawnp 3 +.Sh STANDARDS +The +.Fn posix_spawnattr_getpgroup +and +.Fn posix_spawnattr_setpgroup +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn posix_spawnattr_getpgroup +and +.Fn posix_spawnattr_setpgroup +functions first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An \&Ed Schouten Aq Mt ed@FreeBSD.org diff --git a/lib/libc/gen/posix_spawnattr_getschedparam.3 b/lib/libc/gen/posix_spawnattr_getschedparam.3 new file mode 100644 index 0000000..d8bbd29 --- /dev/null +++ b/lib/libc/gen/posix_spawnattr_getschedparam.3 @@ -0,0 +1,100 @@ +.\" Copyright (c) 2008 Ed Schouten +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/posix_spawnattr_getschedparam.3 282003 2015-04-26 10:52:37Z bapt $ +.\" +.Dd March 24, 2008 +.Dt POSIX_SPAWNATTR_GETSCHEDPARAM 3 +.Os +.Sh NAME +.Nm posix_spawnattr_getschedparam , +.Nm posix_spawnattr_setschedparam +.Nd "get and set the spawn-schedparam attribute of a spawn attributes object" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In spawn.h +.Ft int +.Fn posix_spawnattr_getschedparam "const posix_spawnattr_t *restrict attr" "struct sched_param *restrict schedparam" +.Ft int +.Fn posix_spawnattr_setschedparam "posix_spawnattr_t *attr" "const struct sched_param *restrict schedparam" +.Sh DESCRIPTION +The +.Fn posix_spawnattr_getschedparam +function obtains the value of the spawn-schedparam attribute from the +attributes object referenced by +.Fa attr . +.Pp +The +.Fn posix_spawnattr_setschedparam +function sets the spawn-schedparam attribute in an initialized attributes +object referenced by +.Fa attr . +.Pp +The spawn-schedparam attribute represents the scheduling parameters to +be assigned to the new process image in a spawn operation (if +.Dv POSIX_SPAWN_SETSCHEDULER +or +.Dv POSIX_SPAWN_SETSCHEDPARAM +is set in the spawn-flags attribute). +The default value of this attribute is unspecified. +.Sh RETURN VALUES +The +.Fn posix_spawnattr_getschedparam +and +.Fn posix_spawnattr_setschedparam +functions return zero. +.Sh SEE ALSO +.Xr posix_spawn 3 , +.Xr posix_spawnattr_destroy 3 , +.Xr posix_spawnattr_getschedpolicy 3 , +.Xr posix_spawnattr_init 3 , +.Xr posix_spawnattr_setschedpolicy 3 , +.Xr posix_spawnp 3 +.Sh STANDARDS +The +.Fn posix_spawnattr_getschedparam +and +.Fn posix_spawnattr_setschedparam +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn posix_spawnattr_getschedparam +and +.Fn posix_spawnattr_setschedparam +functions first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An \&Ed Schouten Aq Mt ed@FreeBSD.org diff --git a/lib/libc/gen/posix_spawnattr_getschedpolicy.3 b/lib/libc/gen/posix_spawnattr_getschedpolicy.3 new file mode 100644 index 0000000..c78f0cc --- /dev/null +++ b/lib/libc/gen/posix_spawnattr_getschedpolicy.3 @@ -0,0 +1,98 @@ +.\" Copyright (c) 2008 Ed Schouten +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/posix_spawnattr_getschedpolicy.3 282003 2015-04-26 10:52:37Z bapt $ +.\" +.Dd March 24, 2008 +.Dt POSIX_SPAWNATTR_GETSCHEDPOLICY 3 +.Os +.Sh NAME +.Nm posix_spawnattr_getschedpolicy , +.Nm posix_spawnattr_setschedpolicy +.Nd "get and set the spawn-schedpolicy attribute of a spawn attributes object" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In spawn.h +.Ft int +.Fn posix_spawnattr_getschedpolicy "const posix_spawnattr_t *restrict attr" "int *restrict schedpolicy" +.Ft int +.Fn posix_spawnattr_setschedpolicy "posix_spawnattr_t *attr" "int schedpolicy" +.Sh DESCRIPTION +The +.Fn posix_spawnattr_getschedpolicy +function obtains the value of the spawn-schedpolicy attribute from the +attributes object referenced by +.Fa attr . +.Pp +The +.Fn posix_spawnattr_setschedpolicy +function sets the spawn-schedpolicy attribute in an initialized attributes +object referenced by +.Fa attr . +.Pp +The spawn-schedpolicy attribute represents the scheduling policy to +be assigned to the new process image in a spawn operation (if +.Dv POSIX_SPAWN_SETSCHEDULER +is set in the spawn-flags attribute). +The default value of this attribute is unspecified. +.Sh RETURN VALUES +The +.Fn posix_spawnattr_getschedpolicy +and +.Fn posix_spawnattr_setschedpolicy +functions return zero. +.Sh SEE ALSO +.Xr posix_spawn 3 , +.Xr posix_spawnattr_destroy 3 , +.Xr posix_spawnattr_getschedparam 3 , +.Xr posix_spawnattr_init 3 , +.Xr posix_spawnattr_setschedparam 3 , +.Xr posix_spawnp 3 +.Sh STANDARDS +The +.Fn posix_spawnattr_getschedpolicy +and +.Fn posix_spawnattr_setschedpolicy +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn posix_spawnattr_getschedpolicy +and +.Fn posix_spawnattr_setschedpolicy +functions first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An \&Ed Schouten Aq Mt ed@FreeBSD.org diff --git a/lib/libc/gen/posix_spawnattr_getsigdefault.3 b/lib/libc/gen/posix_spawnattr_getsigdefault.3 new file mode 100644 index 0000000..729d479 --- /dev/null +++ b/lib/libc/gen/posix_spawnattr_getsigdefault.3 @@ -0,0 +1,98 @@ +.\" Copyright (c) 2008 Ed Schouten +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/posix_spawnattr_getsigdefault.3 282003 2015-04-26 10:52:37Z bapt $ +.\" +.Dd March 24, 2008 +.Dt POSIX_SPAWNATTR_GETSIGDEFAULT 3 +.Os +.Sh NAME +.Nm posix_spawnattr_getsigdefault , +.Nm posix_spawnattr_setsigdefault +.Nd "get and set the spawn-sigdefault attribute of a spawn attributes object" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In spawn.h +.Ft int +.Fn posix_spawnattr_getsigdefault "const posix_spawnattr_t *restrict attr" "sigset_t *restrict sigdefault" +.Ft int +.Fn posix_spawnattr_setsigdefault "posix_spawnattr_t *attr" "const sigset_t *restrict sigdefault" +.Sh DESCRIPTION +The +.Fn posix_spawnattr_getsigdefault +function obtains the value of the spawn-sigdefault attribute from the +attributes object referenced by +.Fa attr . +.Pp +The +.Fn posix_spawnattr_setsigdefault +function sets the spawn-sigdefault attribute in an initialized attributes +object referenced by +.Fa attr . +.Pp +The spawn-sigdefault attribute represents the set of signals to be forced to +default signal handling in the new process image (if +.Dv POSIX_SPAWN_SETSIGDEF +is set in the spawn-flags attribute) by a spawn operation. +The default value of this attribute is an empty signal set. +.Sh RETURN VALUES +The +.Fn posix_spawnattr_getsigdefault +and +.Fn posix_spawnattr_setsigdefault +functions return zero. +.Sh SEE ALSO +.Xr posix_spawn 3 , +.Xr posix_spawnattr_destroy 3 , +.Xr posix_spawnattr_getsigmask 3 , +.Xr posix_spawnattr_init 3 , +.Xr posix_spawnattr_setsigmask 3 , +.Xr posix_spawnp 3 +.Sh STANDARDS +The +.Fn posix_spawnattr_getsigdefault +and +.Fn posix_spawnattr_setsigdefault +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn posix_spawnattr_getsigdefault +and +.Fn posix_spawnattr_setsigdefault +functions first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An \&Ed Schouten Aq Mt ed@FreeBSD.org diff --git a/lib/libc/gen/posix_spawnattr_getsigmask.3 b/lib/libc/gen/posix_spawnattr_getsigmask.3 new file mode 100644 index 0000000..99d9b8a --- /dev/null +++ b/lib/libc/gen/posix_spawnattr_getsigmask.3 @@ -0,0 +1,98 @@ +.\" Copyright (c) 2008 Ed Schouten +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/posix_spawnattr_getsigmask.3 282003 2015-04-26 10:52:37Z bapt $ +.\" +.Dd March 24, 2008 +.Dt POSIX_SPAWNATTR_GETSIGMASK 3 +.Os +.Sh NAME +.Nm posix_spawnattr_getsigmask , +.Nm posix_spawnattr_setsigmask +.Nd "get and set the spawn-sigmask attribute of a spawn attributes object" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In spawn.h +.Ft int +.Fn posix_spawnattr_getsigmask "const posix_spawnattr_t *restrict attr" "sigset_t *restrict sigmask" +.Ft int +.Fn posix_spawnattr_setsigmask "posix_spawnattr_t *attr" "const sigset_t *restrict sigmask" +.Sh DESCRIPTION +The +.Fn posix_spawnattr_getsigmask +function obtains the value of the spawn-sigmask attribute from the +attributes object referenced by +.Fa attr . +.Pp +The +.Fn posix_spawnattr_setsigmask +function sets the spawn-sigmask attribute in an initialized attributes +object referenced by +.Fa attr . +.Pp +The spawn-sigmask attribute represents the signal mask in effect in the +new process image of a spawn operation (if +.Dv POSIX_SPAWN_SETSIGMASK +is set in the spawn-flags attribute). +The default value of this attribute is unspecified. +.Sh RETURN VALUES +The +.Fn posix_spawnattr_getsigmask +and +.Fn posix_spawnattr_setsigmask +functions return zero. +.Sh SEE ALSO +.Xr posix_spawn 3 , +.Xr posix_spawnattr_destroy 3 , +.Xr posix_spawnattr_getsigmask 3 , +.Xr posix_spawnattr_init 3 , +.Xr posix_spawnattr_setsigmask 3 , +.Xr posix_spawnp 3 +.Sh STANDARDS +The +.Fn posix_spawnattr_getsigmask +and +.Fn posix_spawnattr_setsigmask +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn posix_spawnattr_getsigmask +and +.Fn posix_spawnattr_setsigmask +functions first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An \&Ed Schouten Aq Mt ed@FreeBSD.org diff --git a/lib/libc/gen/posix_spawnattr_init.3 b/lib/libc/gen/posix_spawnattr_init.3 new file mode 100644 index 0000000..81ee074 --- /dev/null +++ b/lib/libc/gen/posix_spawnattr_init.3 @@ -0,0 +1,123 @@ +.\" Copyright (c) 2008 Ed Schouten +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/posix_spawnattr_init.3 282003 2015-04-26 10:52:37Z bapt $ +.\" +.Dd March 24, 2008 +.Dt POSIX_SPAWNATTR_INIT 3 +.Os +.Sh NAME +.Nm posix_spawnattr_init , +.Nm posix_spawnattr_destroy +.Nd "initialize and destroy spawn attributes object" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In spawn.h +.Ft int +.Fn posix_spawnattr_init "posix_spawnattr_t * attr" +.Ft int +.Fn posix_spawnattr_destroy "posix_spawnattr_t * attr" +.Sh DESCRIPTION +The +.Fn posix_spawnattr_init +function initializes a spawn attributes object +.Fa attr +with the default value for all of the individual attributes used by the +implementation. +Initializing an already initialized spawn attributes object may cause +memory to be leaked. +.Pp +The +.Fn posix_spawnattr_destroy +function destroys a spawn attributes object. +A destroyed +.Fa attr +attributes object can be reinitialized using +.Fn posix_spawnattr_init . +The object should not be used after it has been destroyed. +.Pp +A spawn attributes object is of type +.Vt posix_spawnattr_t +(defined in +.In spawn.h ) +and is used to specify the inheritance of process attributes across a +spawn operation. +.Pp +The resulting spawn attributes object (possibly modified by setting +individual attribute values), is used to modify the behavior of +.Fn posix_spawn +or +.Fn posix_spawnp . +After a spawn attributes object has been used to spawn a process by a +call to a +.Fn posix_spawn +or +.Fn posix_spawnp , +any function affecting the attributes object (including destruction) +will not affect any process that has been spawned in this way. +.Sh RETURN VALUES +Upon successful completion, +.Fn posix_spawnattr_init +and +.Fn posix_spawnattr_destroy +return zero; +otherwise, an error number is returned to indicate the error. +.Sh ERRORS +The +.Fn posix_spawnattr_init +function will fail if: +.Bl -tag -width Er +.It Bq Er ENOMEM +Insufficient memory exists to initialize the spawn attributes object. +.El +.Sh SEE ALSO +.Xr posix_spawn 3 , +.Xr posix_spawnp 3 +.Sh STANDARDS +The +.Fn posix_spawnattr_init +and +.Fn posix_spawnattr_destroy +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn posix_spawnattr_init +and +.Fn posix_spawnattr_destroy +functions first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An \&Ed Schouten Aq Mt ed@FreeBSD.org diff --git a/lib/libc/gen/psignal.3 b/lib/libc/gen/psignal.3 new file mode 100644 index 0000000..b6c993a --- /dev/null +++ b/lib/libc/gen/psignal.3 @@ -0,0 +1,109 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)psignal.3 8.2 (Berkeley) 2/27/95 +.\" $FreeBSD: releng/11.1/lib/libc/gen/psignal.3 300997 2016-05-30 13:51:27Z ed $ +.\" +.Dd May 30, 2016 +.Dt PSIGNAL 3 +.Os +.Sh NAME +.Nm psignal , +.Nm strsignal , +.Nm sys_siglist , +.Nm sys_signame +.Nd system signal messages +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In signal.h +.Ft void +.Fn psignal "int sig" "const char *s" +.Vt extern const char * const sys_siglist[] ; +.Vt extern const char * const sys_signame[] ; +.In string.h +.Ft "char *" +.Fn strsignal "int sig" +.Sh DESCRIPTION +The +.Fn psignal +and +.Fn strsignal +functions locate the descriptive message +string for a signal number. +.Pp +The +.Fn strsignal +function accepts a signal number argument +.Fa sig +and returns a pointer to the corresponding message string. +.Pp +The +.Fn psignal +function accepts a signal number argument +.Fa sig +and writes it to the standard error. +If the argument +.Fa s +is +.Pf non- Dv NULL +and does not point to the null character, +.Fa s +is written to the standard error file descriptor +prior to the message string, +immediately followed by a colon and a space. +If the signal number is not recognized +.Pq Xr sigaction 2 , +the string +.Dq "Unknown signal" +is produced. +.Pp +The message strings can be accessed directly +through the external array +.Va sys_siglist , +indexed by recognized signal numbers. +The external array +.Va sys_signame +is used similarly and +contains short, upper-case abbreviations for signals +which are useful for recognizing signal names +in user input. +The defined variable +.Dv NSIG +contains a count of the strings in +.Va sys_siglist +and +.Va sys_signame . +.Sh SEE ALSO +.Xr sigaction 2 , +.Xr perror 3 , +.Xr strerror 3 +.Sh HISTORY +The +.Fn psignal +function appeared in +.Bx 4.2 . diff --git a/lib/libc/gen/pututxline.c b/lib/libc/gen/pututxline.c new file mode 100644 index 0000000..0ed2146 --- /dev/null +++ b/lib/libc/gen/pututxline.c @@ -0,0 +1,335 @@ +/*- + * Copyright (c) 2010 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/pututxline.c 249593 2013-04-17 21:08:15Z jilles $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "utxdb.h" +#include "un-namespace.h" + +static FILE * +futx_open(const char *file) +{ + FILE *fp; + struct stat sb; + int fd; + + fd = _open(file, O_CREAT|O_RDWR|O_EXLOCK|O_CLOEXEC, 0644); + if (fd < 0) + return (NULL); + + /* Safety check: never use broken files. */ + if (_fstat(fd, &sb) != -1 && sb.st_size % sizeof(struct futx) != 0) { + _close(fd); + errno = EFTYPE; + return (NULL); + } + + fp = fdopen(fd, "r+"); + if (fp == NULL) { + _close(fd); + return (NULL); + } + return (fp); +} + +static int +utx_active_add(const struct futx *fu) +{ + FILE *fp; + struct futx fe; + off_t partial; + int error, ret; + + partial = -1; + ret = 0; + + /* + * Register user login sessions. Overwrite entries of sessions + * that have already been terminated. + */ + fp = futx_open(_PATH_UTX_ACTIVE); + if (fp == NULL) + return (-1); + while (fread(&fe, sizeof(fe), 1, fp) == 1) { + switch (fe.fu_type) { + case BOOT_TIME: + /* Leave these intact. */ + break; + case USER_PROCESS: + case INIT_PROCESS: + case LOGIN_PROCESS: + case DEAD_PROCESS: + /* Overwrite when ut_id matches. */ + if (memcmp(fu->fu_id, fe.fu_id, sizeof(fe.fu_id)) == + 0) { + ret = fseeko(fp, -(off_t)sizeof(fe), SEEK_CUR); + goto exact; + } + if (fe.fu_type != DEAD_PROCESS) + break; + /* FALLTHROUGH */ + default: + /* Allow us to overwrite unused records. */ + if (partial == -1) { + partial = ftello(fp); + /* + * Distinguish errors from valid values so we + * don't overwrite good data by accident. + */ + if (partial != -1) + partial -= (off_t)sizeof(fe); + } + break; + } + } + + /* + * No exact match found. Use the partial match. If no partial + * match was found, just append a new record. + */ + if (partial != -1) + ret = fseeko(fp, partial, SEEK_SET); +exact: + if (ret == -1) + error = errno; + else if (fwrite(fu, sizeof(*fu), 1, fp) < 1) + error = errno; + else + error = 0; + fclose(fp); + if (error != 0) + errno = error; + return (error == 0 ? 0 : 1); +} + +static int +utx_active_remove(struct futx *fu) +{ + FILE *fp; + struct futx fe; + int error, ret; + + /* + * Remove user login sessions, having the same ut_id. + */ + fp = futx_open(_PATH_UTX_ACTIVE); + if (fp == NULL) + return (-1); + error = ESRCH; + ret = -1; + while (fread(&fe, sizeof(fe), 1, fp) == 1 && ret != 0) + switch (fe.fu_type) { + case USER_PROCESS: + case INIT_PROCESS: + case LOGIN_PROCESS: + if (memcmp(fu->fu_id, fe.fu_id, sizeof(fe.fu_id)) != 0) + continue; + + /* Terminate session. */ + if (fseeko(fp, -(off_t)sizeof(fe), SEEK_CUR) == -1) + error = errno; + else if (fwrite(fu, sizeof(*fu), 1, fp) < 1) + error = errno; + else + ret = 0; + + } + + fclose(fp); + if (ret != 0) + errno = error; + return (ret); +} + +static void +utx_active_init(const struct futx *fu) +{ + int fd; + + /* Initialize utx.active with a single BOOT_TIME record. */ + fd = _open(_PATH_UTX_ACTIVE, O_CREAT|O_RDWR|O_TRUNC, 0644); + if (fd < 0) + return; + _write(fd, fu, sizeof(*fu)); + _close(fd); +} + +static void +utx_active_purge(void) +{ + + truncate(_PATH_UTX_ACTIVE, 0); +} + +static int +utx_lastlogin_add(const struct futx *fu) +{ + struct futx fe; + FILE *fp; + int error, ret; + + ret = 0; + + /* + * Write an entry to lastlogin. Overwrite the entry if the + * current user already has an entry. If not, append a new + * entry. + */ + fp = futx_open(_PATH_UTX_LASTLOGIN); + if (fp == NULL) + return (-1); + while (fread(&fe, sizeof fe, 1, fp) == 1) { + if (strncmp(fu->fu_user, fe.fu_user, sizeof fe.fu_user) != 0) + continue; + + /* Found a previous lastlogin entry for this user. */ + ret = fseeko(fp, -(off_t)sizeof fe, SEEK_CUR); + break; + } + if (ret == -1) + error = errno; + else if (fwrite(fu, sizeof *fu, 1, fp) < 1) { + error = errno; + ret = -1; + } + fclose(fp); + if (ret == -1) + errno = error; + return (ret); +} + +static void +utx_lastlogin_upgrade(void) +{ + struct stat sb; + int fd; + + fd = _open(_PATH_UTX_LASTLOGIN, O_RDWR|O_CLOEXEC, 0644); + if (fd < 0) + return; + + /* + * Truncate broken lastlogin files. In the future we should + * check for older versions of the file format here and try to + * upgrade it. + */ + if (_fstat(fd, &sb) != -1 && sb.st_size % sizeof(struct futx) != 0) + ftruncate(fd, 0); + _close(fd); +} + +static int +utx_log_add(const struct futx *fu) +{ + struct iovec vec[2]; + int error, fd; + uint16_t l; + + /* + * Append an entry to the log file. We only need to append + * records to this file, so to conserve space, trim any trailing + * zero-bytes. Prepend a length field, indicating the length of + * the record, excluding the length field itself. + */ + for (l = sizeof(*fu); l > 0 && ((const char *)fu)[l - 1] == '\0'; l--) ; + vec[0].iov_base = &l; + vec[0].iov_len = sizeof(l); + vec[1].iov_base = __DECONST(void *, fu); + vec[1].iov_len = l; + l = htobe16(l); + + fd = _open(_PATH_UTX_LOG, O_CREAT|O_WRONLY|O_APPEND|O_CLOEXEC, 0644); + if (fd < 0) + return (-1); + if (_writev(fd, vec, 2) == -1) + error = errno; + else + error = 0; + _close(fd); + if (error != 0) + errno = error; + return (error == 0 ? 0 : 1); +} + +struct utmpx * +pututxline(const struct utmpx *utmpx) +{ + struct futx fu; + int bad; + + bad = 0; + + utx_to_futx(utmpx, &fu); + + switch (fu.fu_type) { + case BOOT_TIME: + utx_active_init(&fu); + utx_lastlogin_upgrade(); + break; + case SHUTDOWN_TIME: + utx_active_purge(); + break; + case OLD_TIME: + case NEW_TIME: + break; + case USER_PROCESS: + bad |= utx_active_add(&fu); + bad |= utx_lastlogin_add(&fu); + break; +#if 0 /* XXX: Are these records of any use to us? */ + case INIT_PROCESS: + case LOGIN_PROCESS: + bad |= utx_active_add(&fu); + break; +#endif + case DEAD_PROCESS: + /* + * In case writing a logout entry fails, never attempt + * to write it to utx.log. The logout entry's ut_id + * might be invalid. + */ + if (utx_active_remove(&fu) != 0) + return (NULL); + break; + default: + errno = EINVAL; + return (NULL); + } + + bad |= utx_log_add(&fu); + return (bad ? NULL : futx_to_utx(&fu)); +} diff --git a/lib/libc/gen/raise.3 b/lib/libc/gen/raise.3 new file mode 100644 index 0000000..6cf2c05 --- /dev/null +++ b/lib/libc/gen/raise.3 @@ -0,0 +1,73 @@ +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)raise.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/raise.3 207749 2010-05-07 17:20:15Z jilles $ +.\" +.Dd May 7, 2010 +.Dt RAISE 3 +.Os +.Sh NAME +.Nm raise +.Nd send a signal to the current thread +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In signal.h +.Ft int +.Fn raise "int sig" +.Sh DESCRIPTION +The +.Fn raise +function sends the signal +.Fa sig +to the current thread. +.Sh RETURN VALUES +.Rv -std raise +.Sh ERRORS +The +.Fn raise +function +may fail and set +.Va errno +for any of the errors specified for the +library functions +.Xr getpid 2 +and +.Xr kill 2 . +.Sh SEE ALSO +.Xr kill 2 +.Sh STANDARDS +The +.Fn raise +function +conforms to +.St -isoC . diff --git a/lib/libc/gen/rand48.3 b/lib/libc/gen/rand48.3 new file mode 100644 index 0000000..7e8dbe2 --- /dev/null +++ b/lib/libc/gen/rand48.3 @@ -0,0 +1,190 @@ +.\" Copyright (c) 1993 Martin Birgmeier +.\" All rights reserved. +.\" +.\" You may redistribute unmodified or modified versions of this source +.\" code provided that the above copyright notice and this and the +.\" following conditions are retained. +.\" +.\" This software is provided ``as is'', and comes with no warranties +.\" of any kind. I shall in no event be liable for anything that happens +.\" to anyone/anything when using this software. +.\" +.\" @(#)rand48.3 V1.0 MB 8 Oct 1993 +.\" $FreeBSD: releng/11.1/lib/libc/gen/rand48.3 240361 2012-09-11 12:55:15Z des $ +.\" +.Dd September 4, 2012 +.Dt RAND48 3 +.Os +.Sh NAME +.Nm drand48 , +.Nm erand48 , +.Nm lrand48 , +.Nm nrand48 , +.Nm mrand48 , +.Nm jrand48 , +.Nm srand48 , +.Nm seed48 , +.Nm lcong48 +.Nd pseudo random number generators and initialization routines +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft double +.Fn drand48 void +.Ft double +.Fn erand48 "unsigned short xseed[3]" +.Ft long +.Fn lrand48 void +.Ft long +.Fn nrand48 "unsigned short xseed[3]" +.Ft long +.Fn mrand48 void +.Ft long +.Fn jrand48 "unsigned short xseed[3]" +.Ft void +.Fn srand48 "long seed" +.Ft "unsigned short *" +.Fn seed48 "unsigned short xseed[3]" +.Ft void +.Fn lcong48 "unsigned short p[7]" +.Sh DESCRIPTION +.Bf -symbolic +The functions described in this manual page are not cryptographically +secure. +Cryptographic applications should use +.Xr arc4random 3 +instead. +.Ef +.Pp +The +.Fn rand48 +family of functions generates pseudo-random numbers using a linear +congruential algorithm working on integers 48 bits in size. +The +particular formula employed is +r(n+1) = (a * r(n) + c) mod m +where the default values are +for the multiplicand a = 0x5deece66d = 25214903917 and +the addend c = 0xb = 11. +The modulo is always fixed at m = 2 ** 48. +r(n) is called the seed of the random number generator. +.Pp +For all the six generator routines described next, the first +computational step is to perform a single iteration of the algorithm. +.Pp +The +.Fn drand48 +and +.Fn erand48 +functions +return values of type double. +The full 48 bits of r(n+1) are +loaded into the mantissa of the returned value, with the exponent set +such that the values produced lie in the interval [0.0, 1.0). +.Pp +The +.Fn lrand48 +and +.Fn nrand48 +functions +return values of type long in the range +[0, 2**31-1]. +The high-order (31) bits of +r(n+1) are loaded into the lower bits of the returned value, with +the topmost (sign) bit set to zero. +.Pp +The +.Fn mrand48 +and +.Fn jrand48 +functions +return values of type long in the range +[-2**31, 2**31-1]. +The high-order (32) bits of +r(n+1) are loaded into the returned value. +.Pp +The +.Fn drand48 , +.Fn lrand48 , +and +.Fn mrand48 +functions +use an internal buffer to store r(n). +For these functions +the initial value of r(0) = 0x1234abcd330e = 20017429951246. +.Pp +On the other hand, +.Fn erand48 , +.Fn nrand48 , +and +.Fn jrand48 +use a user-supplied buffer to store the seed r(n), +which consists of an array of 3 shorts, where the zeroth member +holds the least significant bits. +.Pp +All functions share the same multiplicand and addend. +.Pp +The +.Fn srand48 +function +is used to initialize the internal buffer r(n) of +.Fn drand48 , +.Fn lrand48 , +and +.Fn mrand48 +such that the 32 bits of the seed value are copied into the upper 32 bits +of r(n), with the lower 16 bits of r(n) arbitrarily being set to 0x330e. +Additionally, the constant multiplicand and addend of the algorithm are +reset to the default values given above. +.Pp +The +.Fn seed48 +function +also initializes the internal buffer r(n) of +.Fn drand48 , +.Fn lrand48 , +and +.Fn mrand48 , +but here all 48 bits of the seed can be specified in an array of 3 shorts, +where the zeroth member specifies the lowest bits. +Again, +the constant multiplicand and addend of the algorithm are +reset to the default values given above. +The +.Fn seed48 +function +returns a pointer to an array of 3 shorts which contains the old seed. +This array is statically allocated, thus its contents are lost after +each new call to +.Fn seed48 . +.Pp +Finally, +.Fn lcong48 +allows full control over the multiplicand and addend used in +.Fn drand48 , +.Fn erand48 , +.Fn lrand48 , +.Fn nrand48 , +.Fn mrand48 , +and +.Fn jrand48 , +and the seed used in +.Fn drand48 , +.Fn lrand48 , +and +.Fn mrand48 . +An array of 7 shorts is passed as argument; the first three shorts are +used to initialize the seed; the second three are used to initialize the +multiplicand; and the last short is used to initialize the addend. +It is thus not possible to use values greater than 0xffff as the addend. +.Pp +Note that all three methods of seeding the random number generator +always also set the multiplicand and addend for any of the six +generator calls. +.Sh SEE ALSO +.Xr arc4random 3 , +.Xr rand 3 , +.Xr random 3 +.Sh AUTHORS +.An Martin Birgmeier diff --git a/lib/libc/gen/readpassphrase.3 b/lib/libc/gen/readpassphrase.3 new file mode 100644 index 0000000..baaeaa1 --- /dev/null +++ b/lib/libc/gen/readpassphrase.3 @@ -0,0 +1,181 @@ +.\" $OpenBSD: readpassphrase.3,v 1.17 2007/05/31 19:19:28 jmc Exp $ +.\" +.\" Copyright (c) 2000, 2002 Todd C. Miller +.\" +.\" 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. +.\" +.\" Sponsored in part by the Defense Advanced Research Projects +.\" Agency (DARPA) and Air Force Research Laboratory, Air Force +.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/readpassphrase.3 215236 2010-11-13 10:38:06Z delphij $ +.\" +.Dd May 31, 2007 +.Dt READPASSPHRASE 3 +.Os +.Sh NAME +.Nm readpassphrase +.Nd get a passphrase from the user +.Sh SYNOPSIS +.In readpassphrase.h +.Ft "char *" +.Fn readpassphrase "const char *prompt" "char *buf" "size_t bufsiz" "int flags" +.Sh DESCRIPTION +The +.Fn readpassphrase +function displays a prompt to, and reads in a passphrase from, +.Pa /dev/tty . +If this file is inaccessible +and the +.Dv RPP_REQUIRE_TTY +flag is not set, +.Fn readpassphrase +displays the prompt on the standard error output and reads from the standard +input. +In this case it is generally not possible to turn off echo. +.Pp +Up to +.Fa bufsiz +\- 1 characters (one is for the +.Dv NUL ) +are read into the provided buffer +.Fa buf . +Any additional +characters and the terminating newline (or return) character are discarded. +.Pp +The +.Fn readpassphrase +function +takes the following optional +.Fa flags : +.Pp +.Bl -tag -width ".Dv RPP_REQUIRE_TTY" -compact +.It Dv RPP_ECHO_OFF +turn off echo (default behavior) +.It Dv RPP_ECHO_ON +leave echo on +.It Dv RPP_REQUIRE_TTY +fail if there is no tty +.It Dv RPP_FORCELOWER +force input to lower case +.It Dv RPP_FORCEUPPER +force input to upper case +.It Dv RPP_SEVENBIT +strip the high bit from input +.It Dv RPP_STDIN +force read of passphrase from stdin +.El +.Pp +The calling process should zero the passphrase as soon as possible to +avoid leaving the cleartext passphrase visible in the process's address +space. +.Sh RETURN VALUES +Upon successful completion, +.Fn readpassphrase +returns a pointer to the NUL-terminated passphrase. +If an error is encountered, the terminal state is restored and +a +.Dv NULL +pointer is returned. +.Sh FILES +.Bl -tag -width ".Pa /dev/tty" -compact +.It Pa /dev/tty +.El +.Sh EXAMPLES +The following code fragment will read a passphrase from +.Pa /dev/tty +into the buffer +.Fa passbuf . +.Bd -literal -offset indent +char passbuf[1024]; + +\&... + +if (readpassphrase("Response: ", passbuf, sizeof(passbuf), + RPP_REQUIRE_TTY) == NULL) + errx(1, "unable to read passphrase"); + +if (compare(transform(passbuf), epass) != 0) + errx(1, "bad passphrase"); + +\&... + +memset(passbuf, 0, sizeof(passbuf)); +.Ed +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EINTR +The +.Fn readpassphrase +function was interrupted by a signal. +.It Bq Er EINVAL +The +.Ar bufsiz +argument was zero. +.It Bq Er EIO +The process is a member of a background process attempting to read +from its controlling terminal, the process is ignoring or blocking +the +.Dv SIGTTIN +signal, or the process group is orphaned. +.It Bq Er EMFILE +The process has already reached its limit for open file descriptors. +.It Bq Er ENFILE +The system file table is full. +.It Bq Er ENOTTY +There is no controlling terminal and the +.Dv RPP_REQUIRE_TTY +flag was specified. +.El +.Sh SIGNALS +The +.Fn readpassphrase +function +will catch the following signals: +.Bd -literal -offset indent +SIGALRM SIGHUP SIGINT +SIGPIPE SIGQUIT SIGTERM +SIGTSTP SIGTTIN SIGTTOU +.Ed +.Pp +When one of the above signals is intercepted, terminal echo will +be restored if it had previously been turned off. +If a signal handler was installed for the signal when +.Fn readpassphrase +was called, that handler is then executed. +If no handler was previously installed for the signal then the +default action is taken as per +.Xr sigaction 2 . +.Pp +The +.Dv SIGTSTP , SIGTTIN +and +.Dv SIGTTOU +signals (stop signals generated from keyboard or due to terminal I/O +from a background process) are treated specially. +When the process is resumed after it has been stopped, +.Fn readpassphrase +will reprint the prompt and the user may then enter a passphrase. +.Sh SEE ALSO +.Xr sigaction 2 , +.Xr getpass 3 +.Sh STANDARDS +The +.Fn readpassphrase +function is an +extension and should not be used if portability is desired. +.Sh HISTORY +The +.Fn readpassphrase +function first appeared in +.Ox 2.9 . diff --git a/lib/libc/gen/recvmmsg.c b/lib/libc/gen/recvmmsg.c new file mode 100644 index 0000000..ac04e60 --- /dev/null +++ b/lib/libc/gen/recvmmsg.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2016 Boris Astardzhiev, Smartcom-Bulgaria AD + * 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(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/recvmmsg.c 307312 2016-10-14 09:34:48Z kib $"); + +#include +#include +#include +#include +#include +#include "libc_private.h" + +ssize_t +recvmmsg(int s, struct mmsghdr *__restrict msgvec, size_t vlen, int flags, + const struct timespec *__restrict timeout) +{ + struct pollfd pfd[1]; + size_t i, rcvd; + ssize_t ret; + int res; + short ev; + + if (timeout != NULL) { + pfd[0].fd = s; + pfd[0].revents = 0; + pfd[0].events = ev = POLLIN | POLLRDNORM | POLLRDBAND | + POLLPRI; + res = ppoll(&pfd[0], 1, timeout, NULL); + if (res == -1 || res == 0) + return (res); + if (pfd[0].revents & POLLNVAL) { + errno = EBADF; + return (-1); + } + if ((pfd[0].revents & ev) == 0) { + errno = ETIMEDOUT; + return (-1); + } + } + + ret = __sys_recvmsg(s, &msgvec[0].msg_hdr, flags); + if (ret == -1) + return (ret); + + msgvec[0].msg_len = ret; + + /* + * Do non-blocking receive for second and later messages if + * WAITFORONE is set. + */ + if (flags & MSG_WAITFORONE) + flags |= MSG_DONTWAIT; + + rcvd = 1; + for (i = rcvd; i < vlen; i++, rcvd++) { + ret = __sys_recvmsg(s, &msgvec[i].msg_hdr, flags); + if (ret == -1) { + /* We have received messages. Let caller know + * about the data received, socket error is + * returned on next invocation. + */ + return (rcvd); + } + + /* Save received bytes. */ + msgvec[i].msg_len = ret; + } + + return (rcvd); +} diff --git a/lib/libc/gen/rfork_thread.3 b/lib/libc/gen/rfork_thread.3 new file mode 100644 index 0000000..2f21179 --- /dev/null +++ b/lib/libc/gen/rfork_thread.3 @@ -0,0 +1,87 @@ +.\" +.\" Copyright (c) 2000 Peter Wemm +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/rfork_thread.3 218385 2011-02-06 23:26:14Z jilles $ +.\" +.Dd February 6, 2011 +.Dt RFORK_THREAD 3 +.Os +.Sh NAME +.Nm rfork_thread +.Nd create a rfork-based process thread +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft pid_t +.Fn rfork_thread "int flags" "void *stack" "int (*func)(void *arg)" "void *arg" +.Sh DESCRIPTION +.Bf -symbolic +The +.Fn rfork_thread +function has been deprecated in favor of +.Xr pthread_create 3 . +.Ef +.Pp +The +.Fn rfork_thread +function +is a helper function for +.Xr rfork 2 . +It arranges for a new process to be created and the child process will +call the specified function with the specified argument, while running on +the supplied stack. +.Pp +Using this function should avoid the need to implement complex stack +swap code. +.Sh RETURN VALUES +Upon successful completion, +.Fn rfork_thread +returns the process ID of the child process to the parent process. +Otherwise, a value of -1 is returned +to the parent process, no child process is created, and the global +variable +.Va errno +is set to indicate the error. +.Pp +The child process context is not aware of a return from the +.Fn rfork_thread +function as it begins executing directly with the supplied function. +.Sh ERRORS +See +.Xr rfork 2 +for error return codes. +.Sh SEE ALSO +.Xr fork 2 , +.Xr intro 2 , +.Xr minherit 2 , +.Xr rfork 2 , +.Xr vfork 2 , +.Xr pthread_create 3 +.Sh HISTORY +The +.Fn rfork_thread +function first appeared in +.Fx 4.3 . diff --git a/lib/libc/gen/scandir.3 b/lib/libc/gen/scandir.3 new file mode 100644 index 0000000..89766e4 --- /dev/null +++ b/lib/libc/gen/scandir.3 @@ -0,0 +1,117 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)scandir.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/scandir.3 276006 2014-12-21 12:36:36Z brueffer $ +.\" +.Dd January 3, 2010 +.Dt SCANDIR 3 +.Os +.Sh NAME +.Nm scandir , +.Nm alphasort +.Nd scan a directory +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In dirent.h +.Ft int +.Fn scandir "const char *dirname" "struct dirent ***namelist" "int \*(lp*select\*(rp\*(lpconst struct dirent *\*(rp" "int \*(lp*compar\*(rp\*(lpconst struct dirent **, const struct dirent **\*(rp" +.Ft int +.Fn scandir_b "const char *dirname" "struct dirent ***namelist" "int \*(lp*select\^(rp\*(lpconst struct dirent *\*(rp" "int \*(lp^compar\*(rp\*(lpconst struct dirent **, const struct dirent **\*(rp" +.Ft int +.Fn alphasort "const struct dirent **d1" "const struct dirent **d2" +.Sh DESCRIPTION +The +.Fn scandir +function +reads the directory +.Fa dirname +and builds an array of pointers to directory +entries using +.Xr malloc 3 . +It returns the number of entries in the array. +A pointer to the array of directory entries is stored in the location +referenced by +.Fa namelist . +.Pp +The +.Fa select +argument is a pointer to a user supplied subroutine which is called by +.Fn scandir +to select which entries are to be included in the array. +The select routine is passed a +pointer to a directory entry and should return a non-zero +value if the directory entry is to be included in the array. +If +.Fa select +is null, then all the directory entries will be included. +.Pp +The +.Fa compar +argument is a pointer to a user supplied subroutine which is passed to +.Xr qsort 3 +to sort the completed array. +If this pointer is null, the array is not sorted. +.Pp +The +.Fn alphasort +function +is a routine which can be used for the +.Fa compar +argument to sort the array alphabetically using +.Xr strcoll 3 . +.Pp +The memory allocated for the array can be deallocated with +.Xr free 3 , +by freeing each pointer in the array and then the array itself. +.Pp +The +.Fn scandir_b +function behaves in the same way as +.Fn scandir , +but takes blocks as arguments instead of function pointers and calls +.Fn qsort_b +rather than +.Fn qsort . +.Sh DIAGNOSTICS +Returns \-1 if the directory cannot be opened for reading or if +.Xr malloc 3 +cannot allocate enough memory to hold all the data structures. +.Sh SEE ALSO +.Xr directory 3 , +.Xr malloc 3 , +.Xr qsort 3 , +.Xr strcoll 3 , +.Xr dir 5 +.Sh HISTORY +The +.Fn scandir +and +.Fn alphasort +functions appeared in +.Bx 4.2 . diff --git a/lib/libc/gen/scandir_b.c b/lib/libc/gen/scandir_b.c new file mode 100644 index 0000000..fb7b337 --- /dev/null +++ b/lib/libc/gen/scandir_b.c @@ -0,0 +1,29 @@ +/*- + * Copyright (c) 2014 David Chisnall + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/gen/scandir_b.c 264042 2014-04-02 16:07:48Z theraven $ + */ +#define I_AM_SCANDIR_B +#include "scandir.c" diff --git a/lib/libc/gen/sem_destroy.3 b/lib/libc/gen/sem_destroy.3 new file mode 100644 index 0000000..898a574 --- /dev/null +++ b/lib/libc/gen/sem_destroy.3 @@ -0,0 +1,87 @@ +.\" Copyright (C) 2000 Jason Evans . +.\" 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(s), this list of conditions and the following disclaimer as +.\" the first lines of this file unmodified other than the possible +.\" addition of one or more copyright notices. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice(s), this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/sem_destroy.3 273601 2014-10-24 19:55:49Z jhb $ +.\" +.Dd February 15, 2000 +.Dt SEM_DESTROY 3 +.Os +.Sh NAME +.Nm sem_destroy +.Nd destroy an unnamed semaphore +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In semaphore.h +.Ft int +.Fn sem_destroy "sem_t *sem" +.Sh DESCRIPTION +The +.Fn sem_destroy +function destroys the unnamed semaphore pointed to by +.Fa sem . +After a successful call to +.Fn sem_destroy , +.Fa sem +is unusable until re-initialized by another call to +.Xr sem_init 3 . +.Sh RETURN VALUES +.Rv -std sem_destroy +.Sh ERRORS +The +.Fn sem_destroy +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sem +argument +points to an invalid semaphore. +.It Bq Er EBUSY +There are currently threads blocked on the semaphore that +.Fa sem +points to. +.El +.Sh SEE ALSO +.Xr sem_init 3 +.Sh STANDARDS +The +.Fn sem_destroy +function conforms to +.St -p1003.1-96 . +.Pp +.Tn POSIX +does not define the behavior of +.Fn sem_destroy +if called while there are threads blocked on +.Fa sem , +but this implementation is guaranteed to return \-1 and set +.Va errno +to +.Er EBUSY +if there are threads blocked on +.Fa sem . diff --git a/lib/libc/gen/sem_getvalue.3 b/lib/libc/gen/sem_getvalue.3 new file mode 100644 index 0000000..0d787ab --- /dev/null +++ b/lib/libc/gen/sem_getvalue.3 @@ -0,0 +1,80 @@ +.\" Copyright (C) 2000 Jason Evans . +.\" 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(s), this list of conditions and the following disclaimer as +.\" the first lines of this file unmodified other than the possible +.\" addition of one or more copyright notices. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice(s), this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/sem_getvalue.3 273601 2014-10-24 19:55:49Z jhb $ +.\" +.Dd February 15, 2000 +.Dt SEM_GETVALUE 3 +.Os +.Sh NAME +.Nm sem_getvalue +.Nd get the value of a semaphore +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In semaphore.h +.Ft int +.Fn sem_getvalue "sem_t * restrict sem" "int * restrict sval" +.Sh DESCRIPTION +The +.Fn sem_getvalue +function sets the variable pointed to by +.Fa sval +to the current value of the semaphore pointed to by +.Fa sem , +as of the time that the call to +.Fn sem_getvalue +is actually run. +.Sh RETURN VALUES +.Rv -std sem_getvalue +.Sh ERRORS +The +.Fn sem_getvalue +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sem +argument +points to an invalid semaphore. +.El +.Sh SEE ALSO +.Xr sem_post 3 , +.Xr sem_trywait 3 , +.Xr sem_wait 3 +.Sh STANDARDS +The +.Fn sem_getvalue +function conforms to +.St -p1003.1-96 . +.Pp +The value of the semaphore is never negative, even if there are threads blocked +on the semaphore. +.Tn POSIX +is somewhat ambiguous in its wording with regard to +what the value of the semaphore should be if there are blocked waiting threads, +but this behavior is conformant, given the wording of the specification. diff --git a/lib/libc/gen/sem_init.3 b/lib/libc/gen/sem_init.3 new file mode 100644 index 0000000..08245b6 --- /dev/null +++ b/lib/libc/gen/sem_init.3 @@ -0,0 +1,101 @@ +.\" Copyright (C) 2000 Jason Evans . +.\" 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(s), this list of conditions and the following disclaimer as +.\" the first lines of this file unmodified other than the possible +.\" addition of one or more copyright notices. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice(s), this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/sem_init.3 273601 2014-10-24 19:55:49Z jhb $ +.\" +.Dd January 9, 2010 +.Dt SEM_INIT 3 +.Os +.Sh NAME +.Nm sem_init +.Nd initialize an unnamed semaphore +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In semaphore.h +.Ft int +.Fn sem_init "sem_t *sem" "int pshared" "unsigned int value" +.Sh DESCRIPTION +The +.Fn sem_init +function initializes the unnamed semaphore pointed to by +.Fa sem +to have the value +.Fa value . +.Pp +A non-zero value for +.Fa pshared +specifies a shared semaphore that can be used by multiple processes, +the semaphore should be located in shared memory region (see +.Xr mmap 2 , +.Xr shm_open 2 , +and +.Xr shmget 2 ) , +any process having read and write access to address +.Fa sem +can perform semaphore operations on +.Fa sem . +.Pp +Following a successful call to +.Fn sem_init , +.Fa sem +can be used as an argument in subsequent calls to +.Xr sem_wait 3 , +.Xr sem_trywait 3 , +.Xr sem_post 3 , +and +.Xr sem_destroy 3 . +The +.Fa sem +argument is no longer valid after a successful call to +.Xr sem_destroy 3 . +.Sh RETURN VALUES +.Rv -std sem_init +.Sh ERRORS +The +.Fn sem_init +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa value +argument exceeds +.Dv SEM_VALUE_MAX . +.It Bq Er ENOSPC +Memory allocation error. +.El +.Sh SEE ALSO +.Xr sem_destroy 3 , +.Xr sem_getvalue 3 , +.Xr sem_post 3 , +.Xr sem_trywait 3 , +.Xr sem_wait 3 +.Sh STANDARDS +The +.Fn sem_init +function conforms to +.St -p1003.1-96 . diff --git a/lib/libc/gen/sem_new.c b/lib/libc/gen/sem_new.c new file mode 100644 index 0000000..b1c6d5e --- /dev/null +++ b/lib/libc/gen/sem_new.c @@ -0,0 +1,470 @@ +/* + * Copyright (C) 2010 David Xu . + * 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(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. + * + * $FreeBSD: releng/11.1/lib/libc/gen/sem_new.c 317897 2017-05-07 07:55:58Z kib $ + */ + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" + +__weak_reference(_sem_close, sem_close); +__weak_reference(_sem_destroy, sem_destroy); +__weak_reference(_sem_getvalue, sem_getvalue); +__weak_reference(_sem_init, sem_init); +__weak_reference(_sem_open, sem_open); +__weak_reference(_sem_post, sem_post); +__weak_reference(_sem_timedwait, sem_timedwait); +__weak_reference(_sem_clockwait_np, sem_clockwait_np); +__weak_reference(_sem_trywait, sem_trywait); +__weak_reference(_sem_unlink, sem_unlink); +__weak_reference(_sem_wait, sem_wait); + +#define SEM_PREFIX "/tmp/SEMD" +#define SEM_MAGIC ((u_int32_t)0x73656d32) + +_Static_assert(SEM_VALUE_MAX <= USEM_MAX_COUNT, "SEM_VALUE_MAX too large"); + +struct sem_nameinfo { + int open_count; + char *name; + dev_t dev; + ino_t ino; + sem_t *sem; + LIST_ENTRY(sem_nameinfo) next; +}; + +static pthread_once_t once = PTHREAD_ONCE_INIT; +static pthread_mutex_t sem_llock; +static LIST_HEAD(, sem_nameinfo) sem_list = LIST_HEAD_INITIALIZER(sem_list); + +static void +sem_prefork(void) +{ + + _pthread_mutex_lock(&sem_llock); +} + +static void +sem_postfork(void) +{ + + _pthread_mutex_unlock(&sem_llock); +} + +static void +sem_child_postfork(void) +{ + + _pthread_mutex_unlock(&sem_llock); +} + +static void +sem_module_init(void) +{ + + _pthread_mutex_init(&sem_llock, NULL); + _pthread_atfork(sem_prefork, sem_postfork, sem_child_postfork); +} + +static inline int +sem_check_validity(sem_t *sem) +{ + + if (sem->_magic == SEM_MAGIC) + return (0); + errno = EINVAL; + return (-1); +} + +int +_sem_init(sem_t *sem, int pshared, unsigned int value) +{ + + if (value > SEM_VALUE_MAX) { + errno = EINVAL; + return (-1); + } + + bzero(sem, sizeof(sem_t)); + sem->_magic = SEM_MAGIC; + sem->_kern._count = (u_int32_t)value; + sem->_kern._flags = pshared ? USYNC_PROCESS_SHARED : 0; + return (0); +} + +sem_t * +_sem_open(const char *name, int flags, ...) +{ + char path[PATH_MAX]; + struct stat sb; + va_list ap; + struct sem_nameinfo *ni; + sem_t *sem, tmp; + int errsave, fd, len, mode, value; + + ni = NULL; + sem = NULL; + fd = -1; + value = 0; + + if (name[0] != '/') { + errno = EINVAL; + return (SEM_FAILED); + } + name++; + strcpy(path, SEM_PREFIX); + if (strlcat(path, name, sizeof(path)) >= sizeof(path)) { + errno = ENAMETOOLONG; + return (SEM_FAILED); + } + if (flags & ~(O_CREAT|O_EXCL)) { + errno = EINVAL; + return (SEM_FAILED); + } + if ((flags & O_CREAT) != 0) { + va_start(ap, flags); + mode = va_arg(ap, int); + value = va_arg(ap, int); + va_end(ap); + } + fd = -1; + _pthread_once(&once, sem_module_init); + + _pthread_mutex_lock(&sem_llock); + LIST_FOREACH(ni, &sem_list, next) { + if (ni->name != NULL && strcmp(name, ni->name) == 0) { + fd = _open(path, flags | O_RDWR | O_CLOEXEC | + O_EXLOCK, mode); + if (fd == -1 || _fstat(fd, &sb) == -1) { + ni = NULL; + goto error; + } + if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | + O_EXCL) || ni->dev != sb.st_dev || + ni->ino != sb.st_ino) { + ni->name = NULL; + ni = NULL; + break; + } + ni->open_count++; + sem = ni->sem; + _pthread_mutex_unlock(&sem_llock); + _close(fd); + return (sem); + } + } + + len = sizeof(*ni) + strlen(name) + 1; + ni = (struct sem_nameinfo *)malloc(len); + if (ni == NULL) { + errno = ENOSPC; + goto error; + } + + ni->name = (char *)(ni+1); + strcpy(ni->name, name); + + if (fd == -1) { + fd = _open(path, flags | O_RDWR | O_CLOEXEC | O_EXLOCK, mode); + if (fd == -1 || _fstat(fd, &sb) == -1) + goto error; + } + if (sb.st_size < sizeof(sem_t)) { + tmp._magic = SEM_MAGIC; + tmp._kern._count = value; + tmp._kern._flags = USYNC_PROCESS_SHARED | SEM_NAMED; + if (_write(fd, &tmp, sizeof(tmp)) != sizeof(tmp)) + goto error; + } + flock(fd, LOCK_UN); + sem = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_NOSYNC, fd, 0); + if (sem == MAP_FAILED) { + sem = NULL; + if (errno == ENOMEM) + errno = ENOSPC; + goto error; + } + if (sem->_magic != SEM_MAGIC) { + errno = EINVAL; + goto error; + } + ni->open_count = 1; + ni->sem = sem; + ni->dev = sb.st_dev; + ni->ino = sb.st_ino; + LIST_INSERT_HEAD(&sem_list, ni, next); + _close(fd); + _pthread_mutex_unlock(&sem_llock); + return (sem); + +error: + errsave = errno; + if (fd != -1) + _close(fd); + if (sem != NULL) + munmap(sem, sizeof(sem_t)); + free(ni); + _pthread_mutex_unlock(&sem_llock); + errno = errsave; + return (SEM_FAILED); +} + +int +_sem_close(sem_t *sem) +{ + struct sem_nameinfo *ni; + bool last; + + if (sem_check_validity(sem) != 0) + return (-1); + + if (!(sem->_kern._flags & SEM_NAMED)) { + errno = EINVAL; + return (-1); + } + + _pthread_once(&once, sem_module_init); + + _pthread_mutex_lock(&sem_llock); + LIST_FOREACH(ni, &sem_list, next) { + if (sem == ni->sem) { + last = --ni->open_count == 0; + if (last) + LIST_REMOVE(ni, next); + _pthread_mutex_unlock(&sem_llock); + if (last) { + munmap(sem, sizeof(*sem)); + free(ni); + } + return (0); + } + } + _pthread_mutex_unlock(&sem_llock); + errno = EINVAL; + return (-1); +} + +int +_sem_unlink(const char *name) +{ + char path[PATH_MAX]; + + if (name[0] != '/') { + errno = ENOENT; + return -1; + } + name++; + strcpy(path, SEM_PREFIX); + if (strlcat(path, name, sizeof(path)) >= sizeof(path)) { + errno = ENAMETOOLONG; + return (-1); + } + + return (unlink(path)); +} + +int +_sem_destroy(sem_t *sem) +{ + + if (sem_check_validity(sem) != 0) + return (-1); + + if (sem->_kern._flags & SEM_NAMED) { + errno = EINVAL; + return (-1); + } + sem->_magic = 0; + return (0); +} + +int +_sem_getvalue(sem_t * __restrict sem, int * __restrict sval) +{ + + if (sem_check_validity(sem) != 0) + return (-1); + + *sval = (int)USEM_COUNT(sem->_kern._count); + return (0); +} + +static __inline int +usem_wake(struct _usem2 *sem) +{ + + return (_umtx_op(sem, UMTX_OP_SEM2_WAKE, 0, NULL, NULL)); +} + +static __inline int +usem_wait(struct _usem2 *sem, clockid_t clock_id, int flags, + const struct timespec *rqtp, struct timespec *rmtp) +{ + struct { + struct _umtx_time timeout; + struct timespec remain; + } tms; + void *tm_p; + size_t tm_size; + int retval; + + if (rqtp == NULL) { + tm_p = NULL; + tm_size = 0; + } else { + tms.timeout._clockid = clock_id; + tms.timeout._flags = (flags & TIMER_ABSTIME) ? UMTX_ABSTIME : 0; + tms.timeout._timeout = *rqtp; + tm_p = &tms; + tm_size = sizeof(tms); + } + retval = _umtx_op(sem, UMTX_OP_SEM2_WAIT, 0, (void *)tm_size, tm_p); + if (retval == -1 && errno == EINTR && (flags & TIMER_ABSTIME) == 0 && + rqtp != NULL && rmtp != NULL) { + *rmtp = tms.remain; + } + + return (retval); +} + +int +_sem_trywait(sem_t *sem) +{ + int val; + + if (sem_check_validity(sem) != 0) + return (-1); + + while (USEM_COUNT(val = sem->_kern._count) > 0) { + if (atomic_cmpset_acq_int(&sem->_kern._count, val, val - 1)) + return (0); + } + errno = EAGAIN; + return (-1); +} + +int +_sem_clockwait_np(sem_t * __restrict sem, clockid_t clock_id, int flags, + const struct timespec *rqtp, struct timespec *rmtp) +{ + int val, retval; + + if (sem_check_validity(sem) != 0) + return (-1); + + retval = 0; + _pthread_testcancel(); + for (;;) { + while (USEM_COUNT(val = sem->_kern._count) > 0) { + if (atomic_cmpset_acq_int(&sem->_kern._count, val, + val - 1)) + return (0); + } + + if (retval) { + _pthread_testcancel(); + break; + } + + /* + * The timeout argument is only supposed to + * be checked if the thread would have blocked. + */ + if (rqtp != NULL) { + if (rqtp->tv_nsec >= 1000000000 || rqtp->tv_nsec < 0) { + errno = EINVAL; + return (-1); + } + } + _pthread_cancel_enter(1); + retval = usem_wait(&sem->_kern, clock_id, flags, rqtp, rmtp); + _pthread_cancel_leave(0); + } + return (retval); +} + +int +_sem_timedwait(sem_t * __restrict sem, + const struct timespec * __restrict abstime) +{ + + return (_sem_clockwait_np(sem, CLOCK_REALTIME, TIMER_ABSTIME, abstime, + NULL)); +}; + +int +_sem_wait(sem_t *sem) +{ + + return (_sem_timedwait(sem, NULL)); +} + +/* + * POSIX: + * The sem_post() interface is reentrant with respect to signals and may be + * invoked from a signal-catching function. + * The implementation does not use lock, so it should be safe. + */ +int +_sem_post(sem_t *sem) +{ + unsigned int count; + + if (sem_check_validity(sem) != 0) + return (-1); + + do { + count = sem->_kern._count; + if (USEM_COUNT(count) + 1 > SEM_VALUE_MAX) { + errno = EOVERFLOW; + return (-1); + } + } while (!atomic_cmpset_rel_int(&sem->_kern._count, count, count + 1)); + if (count & USEM_HAS_WAITERS) + usem_wake(&sem->_kern); + return (0); +} diff --git a/lib/libc/gen/sem_open.3 b/lib/libc/gen/sem_open.3 new file mode 100644 index 0000000..30e5a5f --- /dev/null +++ b/lib/libc/gen/sem_open.3 @@ -0,0 +1,224 @@ +.\" Copyright (C) 2000 Jason Evans . +.\" 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(s), this list of conditions and the following disclaimer as +.\" the first lines of this file unmodified other than the possible +.\" addition of one or more copyright notices. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice(s), this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/sem_open.3 273601 2014-10-24 19:55:49Z jhb $ +.\" +.Dd January 9, 2010 +.Dt SEM_OPEN 3 +.Os +.Sh NAME +.Nm sem_open , +.Nm sem_close , +.Nm sem_unlink +.Nd named semaphore operations +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In semaphore.h +.Ft "sem_t *" +.Fn sem_open "const char *name" "int oflag" ... +.Ft int +.Fn sem_close "sem_t *sem" +.Ft int +.Fn sem_unlink "const char *name" +.Sh DESCRIPTION +The +.Fn sem_open +function creates or opens the named semaphore specified by +.Fa name . +The returned semaphore may be used in subsequent calls to +.Xr sem_getvalue 3 , +.Xr sem_wait 3 , +.Xr sem_trywait 3 , +.Xr sem_post 3 , +and +.Fn sem_close . +.Pp +This implementation places strict requirements on the value of +.Fa name : +it must begin with a slash +.Pq Ql / +and contain no other slash characters. +.Pp +The following bits may be set in the +.Fa oflag +argument: +.Bl -tag -width ".Dv O_CREAT" +.It Dv O_CREAT +Create the semaphore if it does not already exist. +.Pp +The third argument to the call to +.Fn sem_open +must be of type +.Vt mode_t +and specifies the mode for the semaphore. +Only the +.Dv S_IWUSR , S_IWGRP , +and +.Dv S_IWOTH +bits are examined; +it is not possible to grant only +.Dq read +permission on a semaphore. +The mode is modified according to the process's file creation +mask; see +.Xr umask 2 . +.Pp +The fourth argument must be an +.Vt "unsigned int" +and specifies the initial value for the semaphore, +and must be no greater than +.Dv SEM_VALUE_MAX . +.It Dv O_EXCL +Create the semaphore if it does not exist. +If the semaphore already exists, +.Fn sem_open +will fail. +This flag is ignored unless +.Dv O_CREAT +is also specified. +.El +.Pp +The +.Fn sem_close +function closes a named semaphore that was opened by a call to +.Fn sem_open . +.Pp +The +.Fn sem_unlink +function removes the semaphore named +.Fa name . +Resources allocated to the semaphore are only deallocated when all +processes that have the semaphore open close it. +.Sh RETURN VALUES +If successful, +the +.Fn sem_open +function returns the address of the opened semaphore. +If the same +.Fa name +argument is given to multiple calls to +.Fn sem_open +by the same process without an intervening call to +.Fn sem_close , +the same address is returned each time. +If the semaphore cannot be opened, +.Fn sem_open +returns +.Dv SEM_FAILED +and the global variable +.Va errno +is set to indicate the error. +.Pp +.Rv -std sem_close sem_unlink +.Sh ERRORS +The +.Fn sem_open +function will fail if: +.Bl -tag -width Er +.It Bq Er EACCES +The semaphore exists and the permissions specified by +.Fa oflag +at the time it was created deny access to this process. +.It Bq Er EACCES +The semaphore does not exist, but permission to create it is denied. +.It Bq Er EEXIST +.Dv O_CREAT +and +.Dv O_EXCL +are set but the semaphore already exists. +.It Bq Er EINTR +The call was interrupted by a signal. +.It Bq Er EINVAL +The +.Fn sem_open +operation is not supported for the given +.Fa name . +.It Bq Er EINVAL +The +.Fa value +argument is greater than +.Dv SEM_VALUE_MAX . +.\"FreeBSD never returns EMFILE +.\".It Bq Er EMFILE +.\"Too many semaphores are in use by this process. +.It Bq Er ENAMETOOLONG +The +.Fa name +argument is too long. +.It Bq Er ENFILE +The system limit on semaphores has been reached. +.It Bq Er ENOENT +.Dv O_CREAT +is not set but the named semaphore does not exist. +.It Bq Er ENOSPC +There is not enough space to create the semaphore. +.El +.Pp +The +.Fn sem_close +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sem +argument is not a valid semaphore. +.El +.Pp +The +.Fn sem_unlink +function will fail if: +.Bl -tag -width Er +.It Bq Er EACCES +Permission is denied to unlink the semaphore. +.It Bq Er ENAMETOOLONG +The specified +.Fa name +is too long. +.It Bq Er ENOENT +The named semaphore does not exist. +.El +.Sh SEE ALSO +.Xr close 2 , +.Xr open 2 , +.Xr umask 2 , +.Xr unlink 2 , +.Xr sem_getvalue 3 , +.Xr sem_post 3 , +.Xr sem_trywait 3 , +.Xr sem_wait 3 +.Sh STANDARDS +The +.Fn sem_open , +.Fn sem_close , +and +.Fn sem_unlink +functions conform to +.St -p1003.1-96 . +.Sh HISTORY +Support for named semaphores first appeared in +.Fx 5.0 . diff --git a/lib/libc/gen/sem_post.3 b/lib/libc/gen/sem_post.3 new file mode 100644 index 0000000..f6f6655 --- /dev/null +++ b/lib/libc/gen/sem_post.3 @@ -0,0 +1,80 @@ +.\" Copyright (C) 2000 Jason Evans . +.\" 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(s), this list of conditions and the following disclaimer as +.\" the first lines of this file unmodified other than the possible +.\" addition of one or more copyright notices. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice(s), this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/sem_post.3 277862 2015-01-28 22:42:56Z jilles $ +.\" +.Dd January 28, 2015 +.Dt SEM_POST 3 +.Os +.Sh NAME +.Nm sem_post +.Nd increment (unlock) a semaphore +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In semaphore.h +.Ft int +.Fn sem_post "sem_t *sem" +.Sh DESCRIPTION +The +.Fn sem_post +function increments (unlocks) the semaphore pointed to by +.Fa sem . +If there are threads blocked on the semaphore when +.Fn sem_post +is called, then the highest priority thread that has been blocked the longest on +the semaphore will be allowed to return from +.Fn sem_wait . +.Pp +The +.Fn sem_post +function is signal-reentrant and may be called within signal handlers. +.Sh RETURN VALUES +.Rv -std sem_post +.Sh ERRORS +The +.Fn sem_post +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sem +argument +points to an invalid semaphore. +.It Bq Er EOVERFLOW +The semaphore value would exceed +.Dv SEM_VALUE_MAX . +.El +.Sh SEE ALSO +.Xr sem_getvalue 3 , +.Xr sem_trywait 3 , +.Xr sem_wait 3 +.Sh STANDARDS +The +.Fn sem_post +function conforms to +.St -p1003.1-96 . diff --git a/lib/libc/gen/sem_timedwait.3 b/lib/libc/gen/sem_timedwait.3 new file mode 100644 index 0000000..2bf766a --- /dev/null +++ b/lib/libc/gen/sem_timedwait.3 @@ -0,0 +1,163 @@ +.\" Copyright (c) 2008, David Xu +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/sem_timedwait.3 318971 2017-05-27 00:30:51Z gjb $ +.\" +.Dd May 24, 2017 +.Dt SEM_TIMEDWAIT 3 +.Os +.Sh NAME +.Nm sem_timedwait , +.Nm sem_clockwait_np +.Nd "lock a semaphore" +.Sh LIBRARY +.Lb libpthread +.Sh SYNOPSIS +.In semaphore.h +.In time.h +.Ft int +.Fn sem_timedwait "sem_t *sem" "const struct timespec *abs_timeout" +.Ft int +.Fn sem_clockwait_np "sem_t * restrict sem" "clockid_t clock_id" "int flags" "const struct timespec * rqtp" "struct timespec * rmtp" +.Sh DESCRIPTION +The +.Fn sem_timedwait +function locks the semaphore referenced by +.Fa sem , +as in the +.Xr sem_wait 3 +function. +However, if the semaphore cannot be locked without waiting for +another process or thread to unlock the semaphore by performing +a +.Xr sem_post 3 +function, this wait will be terminated when the specified timeout expires. +.Pp +The timeout will expire when the absolute time specified by +.Fa abs_timeout +passes, as measured by the clock on which timeouts are based (that is, +when the value of that clock equals or exceeds +.Fa abs_timeout ) , +or if the +absolute time specified by +.Fa abs_timeout +has already been passed at the time of the call. +.Pp +Note that the timeout is based on the +.Dv CLOCK_REALTIME +clock. +.Pp +The validity of the +.Fa abs_timeout +is not checked if the semaphore can be locked immediately. +.Pp +The +.Fn sem_clockwait_np +function is a more flexible variant of +.Fn sem_timedwait . +The +.Fa clock_id +parameter specifies the reference clock. +If the +.Fa flags +parameter contains +.Dv TIMER_ABSTIME , +then the requested timeout +.Pq Fa rqtp +is an absolute timeout; otherwise, +the timeout is relative. +If this function fails with +.Er EINTR +and the timeout is relative, +a non-NULL +.Fa rmtp +will be updated to contain the amount of time remaining in the interval +.Po +the requested time minus the time actually slept +.Pc . +An absolute timeout has no effect on +.Fa rmtp . +A single structure can be used for both +.Fa rqtp +and +.Fa rmtp . +.Sh RETURN VALUES +These +functions return zero if the calling process successfully performed the +semaphore lock operation on the semaphore designated by +.Fa sem . +If the call was unsuccessful, the state of the semaphore is unchanged, +and the function returns a value of \-1 and sets the global variable +.Va errno +to indicate the error. +.Sh ERRORS +These functions will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sem +argument does not refer to a valid semaphore, or the process or thread would +have blocked, and the +.Fa abs_timeout +parameter specified a nanoseconds field value less than zero or greater than +or equal to 1000 million. +.It Bq Er ETIMEDOUT +The semaphore could not be locked before the specified timeout expired. +.It Bq Er EINTR +A signal interrupted this function. +.El +.Sh SEE ALSO +.Xr sem_post 3 , +.Xr sem_trywait 3 , +.Xr sem_wait 3 +.Sh STANDARDS +The +.Fn sem_timedwait +function conforms to +.St -p1003.1-2004 . +The +.Fn sem_clockwait_np +function is not specified by any standard; +it exists only on +.Fx +at the time of this writing. +.Sh HISTORY +The +.Fn sem_timedwait +function first appeared in +.Fx 5.0 . +The +.Fn sem_clockwait_np +function first appeared in +.Fx 11.1 . diff --git a/lib/libc/gen/sem_wait.3 b/lib/libc/gen/sem_wait.3 new file mode 100644 index 0000000..4f2db1c --- /dev/null +++ b/lib/libc/gen/sem_wait.3 @@ -0,0 +1,102 @@ +.\" Copyright (C) 2000 Jason Evans . +.\" 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(s), this list of conditions and the following disclaimer as +.\" the first lines of this file unmodified other than the possible +.\" addition of one or more copyright notices. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice(s), this list of conditions and the following disclaimer in +.\" the documentation and/or other materials provided with the +.\" distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/sem_wait.3 273601 2014-10-24 19:55:49Z jhb $ +.\" +.Dd April 16, 2013 +.Dt SEM_WAIT 3 +.Os +.Sh NAME +.Nm sem_wait , +.Nm sem_trywait +.Nd decrement (lock) a semaphore +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In semaphore.h +.Ft int +.Fn sem_wait "sem_t *sem" +.Ft int +.Fn sem_trywait "sem_t *sem" +.Sh DESCRIPTION +The +.Fn sem_wait +function decrements (locks) the semaphore pointed to by +.Fa sem , +but blocks if the value of +.Fa sem +is zero, until the value is non-zero and the value can be decremented. +.Pp +The +.Fn sem_trywait +function decrements (locks) the semaphore pointed to by +.Fa sem +only if the value is non-zero. +Otherwise, the semaphore is not decremented and +an error is returned. +.Sh RETURN VALUES +.Rv -std +.Sh ERRORS +The +.Fn sem_wait +and +.Fn sem_trywait +functions will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sem +argument +points to an invalid semaphore. +.El +.Pp +Additionally, +.Fn sem_wait +will fail if: +.Bl -tag -width Er +.It Bq Er EINTR +A signal interrupted this function. +.El +.Pp +Additionally, +.Fn sem_trywait +will fail if: +.Bl -tag -width Er +.It Bq Er EAGAIN +The semaphore value was zero, and thus could not be decremented. +.El +.Sh SEE ALSO +.Xr sem_getvalue 3 , +.Xr sem_post 3 , +.Xr sem_timedwait 3 +.Sh STANDARDS +The +.Fn sem_wait +and +.Fn sem_trywait +functions conform to +.St -p1003.1-96 . diff --git a/lib/libc/gen/sendmmsg.c b/lib/libc/gen/sendmmsg.c new file mode 100644 index 0000000..3f354e6 --- /dev/null +++ b/lib/libc/gen/sendmmsg.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016 Boris Astardzhiev, Smartcom-Bulgaria AD + * 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(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/sendmmsg.c 295039 2016-01-29 14:12:12Z kib $"); + +#include +#include +#include "libc_private.h" + +ssize_t +sendmmsg(int s, struct mmsghdr *__restrict msgvec, size_t vlen, int flags) +{ + size_t i, sent; + ssize_t ret; + + sent = 0; + for (i = 0; i < vlen; i++, sent++) { + ret = __sys_sendmsg(s, &msgvec[i].msg_hdr, flags); + if (ret == -1) { + if (sent != 0) { + /* + * We have sent messages. Let caller + * know about the data sent, socket + * error is returned on next + * invocation. + */ + return (sent); + } + return (ret); + } + + /* Save sent bytes. */ + msgvec[i].msg_len = ret; + } + + return (sent); +} diff --git a/lib/libc/gen/setjmp.3 b/lib/libc/gen/setjmp.3 new file mode 100644 index 0000000..88e6a45 --- /dev/null +++ b/lib/libc/gen/setjmp.3 @@ -0,0 +1,172 @@ +.\" Copyright (c) 1990, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)setjmp.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/setjmp.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 4, 1993 +.Dt SETJMP 3 +.Os +.Sh NAME +.Nm sigsetjmp , +.Nm siglongjmp , +.Nm setjmp , +.Nm longjmp , +.Nm _setjmp , +.Nm _longjmp , +.Nm longjmperror +.Nd non-local jumps +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In setjmp.h +.Ft int +.Fn sigsetjmp "sigjmp_buf env" "int savemask" +.Ft void +.Fn siglongjmp "sigjmp_buf env" "int val" +.Ft int +.Fn setjmp "jmp_buf env" +.Ft void +.Fn longjmp "jmp_buf env" "int val" +.Ft int +.Fn _setjmp "jmp_buf env" +.Ft void +.Fn _longjmp "jmp_buf env" "int val" +.Ft void +.Fn longjmperror void +.Sh DESCRIPTION +The +.Fn sigsetjmp , +.Fn setjmp , +and +.Fn _setjmp +functions save their calling environment in +.Fa env . +Each of these functions returns 0. +.Pp +The corresponding +.Fn longjmp +functions restore the environment saved by their most recent respective +invocations +of the +.Fn setjmp +function. +They then return so that program execution continues as if the corresponding +invocation of the +.Fn setjmp +call had just returned the value specified by +.Fa val , +instead of 0. +.Pp +Pairs of calls may be intermixed, i.e., both +.Fn sigsetjmp +and +.Fn siglongjmp +and +.Fn setjmp +and +.Fn longjmp +combinations may be used in the same program, however, individual +calls may not, e.g.\& the +.Fa env +argument to +.Fn setjmp +may not be passed to +.Fn siglongjmp . +.Pp +The +.Fn longjmp +routines may not be called after the routine which called the +.Fn setjmp +routines returns. +.Pp +All accessible objects have values as of the time +.Fn longjmp +routine was called, except that the values of objects of automatic storage +invocation duration that do not have the +.Vt volatile +type and have been changed between the +.Fn setjmp +invocation and +.Fn longjmp +call are indeterminate. +.Pp +The +.Fn setjmp Ns / Ns Fn longjmp +pairs save and restore the signal mask while +.Fn _setjmp Ns / Ns Fn _longjmp +pairs save and restore only the register set and the stack. +(See +.Fn sigprocmask 2 . ) +.Pp +The +.Fn sigsetjmp Ns / Ns Fn siglongjmp +function +pairs save and restore the signal mask if the argument +.Fa savemask +is non-zero, otherwise only the register set and the stack are saved. +.Sh ERRORS +If the contents of the +.Fa env +are corrupted, or correspond to an environment that has already returned, +the +.Fn longjmp +routine calls the routine +.Fn longjmperror 3 . +If +.Fn longjmperror +returns the program is aborted (see +.Xr abort 3 ) . +The default version of +.Fn longjmperror +prints the message +.Dq Li longjmp botch +to standard error and returns. +User programs wishing to exit more gracefully should write their own +versions of +.Fn longjmperror . +.Sh SEE ALSO +.Xr sigaction 2 , +.Xr sigaltstack 2 , +.Xr signal 3 +.Sh STANDARDS +The +.Fn setjmp +and +.Fn longjmp +functions conform to +.St -isoC . +The +.Fn sigsetjmp +and +.Fn siglongjmp +functions conform to +.St -p1003.1-88 . diff --git a/lib/libc/gen/setmode.3 b/lib/libc/gen/setmode.3 new file mode 100644 index 0000000..387b496 --- /dev/null +++ b/lib/libc/gen/setmode.3 @@ -0,0 +1,127 @@ +.\" Copyright (c) 1989, 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. +.\" 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. +.\" +.\" @(#)setmode.3 8.2 (Berkeley) 4/28/95 +.\" $FreeBSD: releng/11.1/lib/libc/gen/setmode.3 279186 2015-02-22 20:16:44Z pfg $ +.\" +.Dd February 22, 2015 +.Dt SETMODE 3 +.Os +.Sh NAME +.Nm getmode , +.Nm setmode +.Nd modify mode bits +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft mode_t +.Fn getmode "const void *set" "mode_t mode" +.Ft void * +.Fn setmode "const char *mode_str" +.Sh DESCRIPTION +The +.Fn getmode +function +returns a copy of the file permission bits +.Fa mode +as altered by the values pointed to by +.Fa set . +While only the mode bits are altered, other parts of the file mode +may be examined. +.Pp +The +.Fn setmode +function +takes an absolute (octal) or symbolic value, as described in +.Xr chmod 1 , +as an argument +and returns a pointer to mode values to be supplied to +.Fn getmode . +Because some of the symbolic values are relative to the file +creation mask, +.Fn setmode +may call +.Xr umask 2 . +If this occurs, the file creation mask will be restored before +.Fn setmode +returns. +If the calling program changes the value of its file creation mask +after calling +.Fn setmode , +.Fn setmode +must be called again if +.Fn getmode +is to modify future file modes correctly. +.Pp +If the mode passed to +.Fn setmode +is invalid or if memory cannot be allocated for the return value, +.Fn setmode +returns +.Dv NULL . +.Pp +The value returned from +.Fn setmode +is obtained from +.Fn malloc +and should be returned to the system with +.Fn free +when the program is done with it, generally after a call to +.Fn getmode . +.Sh ERRORS +The +.Fn setmode +function +may fail and set errno for any of the errors specified for the library +routine +.Xr malloc 3 +or +.Xr strtol 3 . +In addition, +.Fn setmode +will fail and set +.Va errno +to: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa mode +argument does not represent a valid mode. +.El +.Sh SEE ALSO +.Xr chmod 1 , +.Xr stat 2 , +.Xr umask 2 , +.Xr malloc 3 +.Sh HISTORY +The +.Fn getmode +and +.Fn setmode +functions first appeared in +.Bx 4.4 . diff --git a/lib/libc/gen/setproctitle.3 b/lib/libc/gen/setproctitle.3 new file mode 100644 index 0000000..bfb8da7 --- /dev/null +++ b/lib/libc/gen/setproctitle.3 @@ -0,0 +1,121 @@ +.\" Copyright (c) 1995 Peter Wemm +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, is permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice immediately at the beginning of the file, without modification, +.\" 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. This work was done expressly for inclusion into FreeBSD. Other use +.\" is permitted provided this notation is included. +.\" 4. Absolutely no warranty of function or purpose is made by the author +.\" Peter Wemm. +.\" 5. Modifications may be freely made to this file providing the above +.\" conditions are met. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/setproctitle.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.\" The following requests are required for all man pages. +.Dd December 16, 1995 +.Dt SETPROCTITLE 3 +.Os +.Sh NAME +.Nm setproctitle +.Nd set process title +.Sh SYNOPSIS +.In sys/types.h +.In unistd.h +.Ft void +.Fn setproctitle "const char *fmt" "..." +.Sh DESCRIPTION +The +.Fn setproctitle +library routine sets the process title that appears on the +.Xr ps 1 +command. +.Pp +The title is set from the executable's name, followed by the +result of a +.Xr printf 3 +style expansion of the arguments as specified by the +.Va fmt +argument. +If the +.Va fmt +argument begins with a +.Dq - +character, the executable's name is skipped. +.Pp +If +.Va fmt +is NULL, the process title is restored. +.Sh EXAMPLES +To set the title on a daemon to indicate its activity: +.Bd -literal -offset indent +setproctitle("talking to %s", inet_ntoa(addr)); +.Ed +.Sh SEE ALSO +.Xr ps 1 , +.Xr w 1 , +.Xr kvm 3 , +.Xr kvm_getargv 3 , +.Xr printf 3 +.Sh STANDARDS +The +.Fn setproctitle +function +is implicitly non-standard. +Other methods of causing the +.Xr ps 1 +command line to change, including copying over the argv[0] string are +also implicitly non-portable. +It is preferable to use an operating system +supplied +.Fn setproctitle +if present. +.Pp +Unfortunately, it is possible that there are other calling conventions +to other versions of +.Fn setproctitle , +although none have been found by the author as yet. +This is believed to be +the predominant convention. +.Pp +It is thought that the implementation is compatible with other systems, +including +.Nx +and +.Bsx . +.Sh HISTORY +The +.Fn setproctitle +function +first appeared in +.Fx 2.2 . +Other operating systems have +similar functions. +.Sh AUTHORS +.An -nosplit +.An Peter Wemm Aq Mt peter@FreeBSD.org +stole the idea from the +.Sy "Sendmail 8.7.3" +source code by +.An Eric Allman Aq Mt eric@sendmail.org . +.Sh BUGS +Never pass a string with user-supplied data as a format without using +.Ql %s . +An attacker can put format specifiers in the string to mangle your stack, +leading to a possible security hole. +This holds true even if the string was built using a function like +.Fn snprintf , +as the resulting string may still contain user-supplied conversion specifiers +for later interpolation by +.Fn setproctitle . +.Pp +Always use the proper secure idiom: +.Pp +.Dl setproctitle("%s", string); diff --git a/lib/libc/gen/siginterrupt.3 b/lib/libc/gen/siginterrupt.3 new file mode 100644 index 0000000..baf30bd --- /dev/null +++ b/lib/libc/gen/siginterrupt.3 @@ -0,0 +1,119 @@ +.\" Copyright (c) 1985, 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. +.\" 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. +.\" +.\" @(#)siginterrupt.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/siginterrupt.3 207735 2010-05-06 22:49:54Z jilles $ +.\" +.Dd June 4, 1993 +.Dt SIGINTERRUPT 3 +.Os +.Sh NAME +.Nm siginterrupt +.Nd allow signals to interrupt system calls +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In signal.h +.Ft int +.Fn siginterrupt "int sig" "int flag" +.Sh DESCRIPTION +The +.Fn siginterrupt +function +is used to change the system call restart +behavior when a system call is interrupted by the specified signal. +If the flag is false (0), then system calls will be restarted if +they are interrupted by the specified signal +and no data has been transferred yet. +System call restart has been the default behavior since +.Bx 4.2 , +and is the default behaviour for +.Xr signal 3 +on +.Fx . +.Pp +If the flag is true (1), +then restarting of system calls is disabled. +If a system call is interrupted by the specified signal +and no data has been transferred, +the system call will return \-1 with the global variable +.Va errno +set to +.Er EINTR . +Interrupted system calls that have started transferring +data will return the amount of data actually transferred. +System call interrupt is the signal behavior found on +.Bx 4.1 +and +.At V +systems. +.Pp +Note that the new +.Bx 4.2 +signal handling semantics are not +altered in any other way. +Most notably, signal handlers always remain installed until +explicitly changed by a subsequent +.Xr sigaction 2 +call, and the signal mask operates as documented in +.Xr sigaction 2 . +Programs may switch between restartable and interruptible +system call operation as often as desired in the execution of a program. +.Pp +Issuing a +.Fn siginterrupt 3 +call during the execution of a signal handler will cause +the new action to take place on the next signal to be caught. +.Sh NOTES +This library routine uses an extension of the +.Xr sigaction 2 +system call that is not available in +.Bx 4.2 , +hence it should not be used if backward compatibility is needed. +.Sh RETURN VALUES +.Rv -std siginterrupt +.Sh ERRORS +The +.Fn siginterrupt +call fails if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sig +argument +is not a valid signal number. +.El +.Sh SEE ALSO +.Xr sigaction 2 , +.Xr sigprocmask 2 , +.Xr sigsuspend 2 , +.Xr signal 3 +.Sh HISTORY +The +.Fn siginterrupt +function appeared in +.Bx 4.3 . diff --git a/lib/libc/gen/signal.3 b/lib/libc/gen/signal.3 new file mode 100644 index 0000000..4ce41ee --- /dev/null +++ b/lib/libc/gen/signal.3 @@ -0,0 +1,272 @@ +.\" Copyright (c) 1980, 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. +.\" 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. +.\" +.\" @(#)signal.3 8.3 (Berkeley) 4/19/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/signal.3 255171 2013-09-03 08:19:06Z rwatson $ +.\" +.Dd June 7, 2004 +.Dt SIGNAL 3 +.Os +.Sh NAME +.Nm signal +.Nd simplified software signal facilities +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In signal.h +.\" The following is Quite Ugly, but syntactically correct. +.\" Don't try to fix it. +.Ft void +.Fn \*(lp*signal "int sig" "void \*(lp*func\*(rp\*(lpint\*(rp\*(rp\*(rp\*(lpint" +.Pp +or in +.Fx Ap s +equivalent but easier to read typedef'd version: +.Ft typedef "void \*(lp*sig_t\*(rp \*(lpint\*(rp" ; +.Pp +.Ft sig_t +.Fn signal "int sig" "sig_t func" +.Sh DESCRIPTION +This +.Fn signal +facility +is a simplified interface to the more general +.Xr sigaction 2 +facility. +.Pp +Signals allow the manipulation of a process from outside its +domain as well as allowing the process to manipulate itself or +copies of itself (children). +There are two general types of signals: +those that cause termination of a process and those that do not. +Signals which cause termination of a program might result from +an irrecoverable error or might be the result of a user at a terminal +typing the `interrupt' character. +Signals are used when a process is stopped because it wishes to access +its control terminal while in the background (see +.Xr tty 4 ) . +Signals are optionally generated +when a process resumes after being stopped, +when the status of child processes changes, +or when input is ready at the control terminal. +Most signals result in the termination of the process receiving them +if no action +is taken; some signals instead cause the process receiving them +to be stopped, or are simply discarded if the process has not +requested otherwise. +Except for the +.Dv SIGKILL +and +.Dv SIGSTOP +signals, the +.Fn signal +function allows for a signal to be caught, to be ignored, or to generate +an interrupt. +These signals are defined in the file +.In signal.h : +.Bl -column No ".Dv SIGVTALRM" "create core image" +.It Sy "Num" Ta Sy "Name" Ta Sy "Default Action" Ta Sy "Description" +.It 1 Ta Dv SIGHUP Ta "terminate process" Ta "terminal line hangup" +.It 2 Ta Dv SIGINT Ta "terminate process" Ta "interrupt program" +.It 3 Ta Dv SIGQUIT Ta "create core image" Ta "quit program" +.It 4 Ta Dv SIGILL Ta "create core image" Ta "illegal instruction" +.It 5 Ta Dv SIGTRAP Ta "create core image" Ta "trace trap" +.It 6 Ta Dv SIGABRT Ta "create core image" Ta "abort program" +(formerly +.Dv SIGIOT ) +.It 7 Ta Dv SIGEMT Ta "create core image" Ta "emulate instruction executed" +.It 8 Ta Dv SIGFPE Ta "create core image" Ta "floating-point exception" +.It 9 Ta Dv SIGKILL Ta "terminate process" Ta "kill program" +.It 10 Ta Dv SIGBUS Ta "create core image" Ta "bus error" +.It 11 Ta Dv SIGSEGV Ta "create core image" Ta "segmentation violation" +.It 12 Ta Dv SIGSYS Ta "create core image" Ta "non-existent system call invoked" +.It 13 Ta Dv SIGPIPE Ta "terminate process" Ta "write on a pipe with no reader" +.It 14 Ta Dv SIGALRM Ta "terminate process" Ta "real-time timer expired" +.It 15 Ta Dv SIGTERM Ta "terminate process" Ta "software termination signal" +.It 16 Ta Dv SIGURG Ta "discard signal" Ta "urgent condition present on socket" +.It 17 Ta Dv SIGSTOP Ta "stop process" Ta "stop (cannot be caught or ignored)" +.It 18 Ta Dv SIGTSTP Ta "stop process" Ta "stop signal generated from keyboard" +.It 19 Ta Dv SIGCONT Ta "discard signal" Ta "continue after stop" +.It 20 Ta Dv SIGCHLD Ta "discard signal" Ta "child status has changed" +.It 21 Ta Dv SIGTTIN Ta "stop process" Ta "background read attempted from" +control terminal +.It 22 Ta Dv SIGTTOU Ta "stop process" Ta "background write attempted to" +control terminal +.It 23 Ta Dv SIGIO Ta "discard signal" Ta Tn "I/O" +is possible on a descriptor (see +.Xr fcntl 2 ) +.It 24 Ta Dv SIGXCPU Ta "terminate process" Ta "cpu time limit exceeded (see" +.Xr setrlimit 2 ) +.It 25 Ta Dv SIGXFSZ Ta "terminate process" Ta "file size limit exceeded (see" +.Xr setrlimit 2 ) +.It 26 Ta Dv SIGVTALRM Ta "terminate process" Ta "virtual time alarm (see" +.Xr setitimer 2 ) +.It 27 Ta Dv SIGPROF Ta "terminate process" Ta "profiling timer alarm (see" +.Xr setitimer 2 ) +.It 28 Ta Dv SIGWINCH Ta "discard signal" Ta "Window size change" +.It 29 Ta Dv SIGINFO Ta "discard signal" Ta "status request from keyboard" +.It 30 Ta Dv SIGUSR1 Ta "terminate process" Ta "User defined signal 1" +.It 31 Ta Dv SIGUSR2 Ta "terminate process" Ta "User defined signal 2" +.It 32 Ta Dv SIGTHR Ta "terminate process" Ta "thread interrupt" +.It 33 Ta Dv SIGLIBRT Ta "terminate process" Ta "real-time library interrupt" +.El +.Pp +The +.Fa sig +argument specifies which signal was received. +The +.Fa func +procedure allows a user to choose the action upon receipt of a signal. +To set the default action of the signal to occur as listed above, +.Fa func +should be +.Dv SIG_DFL . +A +.Dv SIG_DFL +resets the default action. +To ignore the signal +.Fa func +should be +.Dv SIG_IGN . +This will cause subsequent instances of the signal to be ignored +and pending instances to be discarded. +If +.Dv SIG_IGN +is not used, +further occurrences of the signal are +automatically blocked and +.Fa func +is called. +.Pp +The handled signal is unblocked when the +function returns and +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. +.Ef +.Pp +For some system calls, if a signal is caught while the call is +executing and the call is prematurely terminated, +the call is automatically restarted. +Any handler installed with +.Xr signal 3 +will have the +.Dv SA_RESTART +flag set, meaning that any restartable system call will not return on +receipt of a signal. +The affected system calls include +.Xr read 2 , +.Xr write 2 , +.Xr sendto 2 , +.Xr recvfrom 2 , +.Xr sendmsg 2 +and +.Xr recvmsg 2 +on a communications channel or a low speed device +and during a +.Xr ioctl 2 +or +.Xr wait 2 . +However, calls that have already committed are not restarted, +but instead return a partial success (for example, a short read count). +These semantics could be changed with +.Xr siginterrupt 3 . +.Pp +When a process which has installed signal handlers forks, +the child process inherits the signals. +All caught signals may be reset to their default action by a call +to the +.Xr execve 2 +function; +ignored signals remain ignored. +.Pp +If a process explicitly specifies +.Dv SIG_IGN +as the action for the signal +.Dv SIGCHLD , +the system will not create zombie processes when children +of the calling process exit. +As a consequence, the system will discard the exit status +from the child processes. +If the calling process subsequently issues a call to +.Xr wait 2 +or equivalent, it will block until all of the calling process's +children terminate, and then return a value of \-1 with +.Va errno +set to +.Er ECHILD . +.Pp +See +.Xr sigaction 2 +for a list of functions +that are considered safe for use in signal handlers. +.Sh RETURN VALUES +The previous action is returned on a successful call. +Otherwise, SIG_ERR is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The +.Fn signal +function +will fail and no action will take place if one of the +following occur: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa sig +argument +is not a valid signal number. +.It Bq Er EINVAL +An attempt is made to ignore or supply a handler for +.Dv SIGKILL +or +.Dv SIGSTOP . +.El +.Sh SEE ALSO +.Xr kill 1 , +.Xr kill 2 , +.Xr ptrace 2 , +.Xr sigaction 2 , +.Xr sigaltstack 2 , +.Xr sigprocmask 2 , +.Xr sigsuspend 2 , +.Xr wait 2 , +.Xr fpsetmask 3 , +.Xr setjmp 3 , +.Xr siginterrupt 3 , +.Xr tty 4 +.Sh HISTORY +The +.Nm +facility appeared in +.Bx 4.0 . +The option to avoid the creation of child zombies through ignoring +.Dv SIGCHLD +appeared in +.Fx 5.0 . diff --git a/lib/libc/gen/sigsetops.3 b/lib/libc/gen/sigsetops.3 new file mode 100644 index 0000000..9f233ae --- /dev/null +++ b/lib/libc/gen/sigsetops.3 @@ -0,0 +1,117 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)sigsetops.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/sigsetops.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd December 16, 2004 +.Dt SIGSETOPS 3 +.Os +.Sh NAME +.Nm sigemptyset , +.Nm sigfillset , +.Nm sigaddset , +.Nm sigdelset , +.Nm sigismember +.Nd manipulate signal sets +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In signal.h +.Ft int +.Fn sigemptyset "sigset_t *set" +.Ft int +.Fn sigfillset "sigset_t *set" +.Ft int +.Fn sigaddset "sigset_t *set" "int signo" +.Ft int +.Fn sigdelset "sigset_t *set" "int signo" +.Ft int +.Fn sigismember "const sigset_t *set" "int signo" +.Sh DESCRIPTION +These functions manipulate signal sets stored in a +.Fa sigset_t . +Either +.Fn sigemptyset +or +.Fn sigfillset +must be called for every object of type +.Fa sigset_t +before any other use of the object. +.Pp +The +.Fn sigemptyset +function initializes a signal set to be empty. +.Pp +The +.Fn sigfillset +function initializes a signal set to contain all signals. +.Pp +The +.Fn sigaddset +function adds the specified signal +.Fa signo +to the signal set. +.Pp +The +.Fn sigdelset +function deletes the specified signal +.Fa signo +from the signal set. +.Pp +The +.Fn sigismember +function returns whether a specified signal +.Fa signo +is contained in the signal set. +.Sh RETURN VALUES +The +.Fn sigismember +function returns 1 +if the signal is a member of the set, +0 otherwise. +The other functions return 0 upon success. +A \-1 return value +indicates an error occurred and the global variable +.Va errno +is set to indicate the reason. +.Sh ERRORS +These functions could fail if one of the following occurs: +.Bl -tag -width Er +.It Bq Er EINVAL +.Fa signo +has an invalid value. +.El +.Sh SEE ALSO +.Xr kill 2 , +.Xr sigaction 2 , +.Xr sigpending 2 , +.Xr sigprocmask 2 , +.Xr sigsuspend 2 +.Sh STANDARDS +These functions are defined by +.St -p1003.1-88 . diff --git a/lib/libc/gen/sleep.3 b/lib/libc/gen/sleep.3 new file mode 100644 index 0000000..6431af0 --- /dev/null +++ b/lib/libc/gen/sleep.3 @@ -0,0 +1,83 @@ +.\" Copyright (c) 1986, 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. +.\" 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. +.\" +.\" @(#)sleep.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/sleep.3 276802 2015-01-08 01:27:43Z rodrigc $ +.\" +.Dd February 13, 1998 +.Dt SLEEP 3 +.Os +.Sh NAME +.Nm sleep +.Nd suspend thread execution for an interval measured in seconds +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft unsigned int +.Fn sleep "unsigned int seconds" +.Sh DESCRIPTION +The +.Fn sleep +function suspends execution of the calling thread until either +.Fa seconds +seconds have elapsed or a signal is delivered to the thread and its +action is to invoke a signal-catching function or to terminate the +thread or process. +System activity may lengthen the sleep by an indeterminate amount. +.Pp +This function is implemented using +.Xr nanosleep 2 +by pausing for +.Fa seconds +seconds or until a signal occurs. +Consequently, in this implementation, +sleeping has no effect on the state of process timers, +and there is no special handling for SIGALRM. +.Sh RETURN VALUES +If the +.Fn sleep +function returns because the requested time has elapsed, the value +returned will be zero. +If the +.Fn sleep +function returns due to the delivery of a signal, the value returned +will be the unslept amount (the requested time minus the time actually +slept) in seconds. +.Sh SEE ALSO +.Xr nanosleep 2 , +.Xr usleep 3 +.Sh STANDARDS +The +.Fn sleep +function conforms to +.St -p1003.1-90 . +.Sh HISTORY +A +.Fn sleep +function appeared in +.At v7 . diff --git a/lib/libc/gen/statvfs.3 b/lib/libc/gen/statvfs.3 new file mode 100644 index 0000000..0d1161f --- /dev/null +++ b/lib/libc/gen/statvfs.3 @@ -0,0 +1,187 @@ +.\" +.\" Copyright 2002 Massachusetts Institute of Technology +.\" +.\" Permission to use, copy, modify, and distribute this software and +.\" its documentation for any purpose and without fee is hereby +.\" granted, provided that both the above copyright notice and this +.\" permission notice appear in all copies, that both the above +.\" copyright notice and this permission notice appear in all +.\" supporting documentation, and that the name of M.I.T. not be used +.\" in advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. M.I.T. makes +.\" no representations about the suitability of this software for any +.\" purpose. It is provided "as is" without express or implied +.\" warranty. +.\" +.\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS +.\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, +.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT +.\" SHALL M.I.T. 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/statvfs.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.Dd July 13, 2002 +.Dt STATVFS 3 +.Os +.Sh NAME +.Nm statvfs , +.Nm fstatvfs +.Nd retrieve file system information +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/statvfs.h +.Ft int +.Fn statvfs "const char * restrict path" "struct statvfs * restrict buf" +.Ft int +.Fn fstatvfs "int fd" "struct statvfs *buf" +.Sh DESCRIPTION +The +.Fn statvfs +and +.Fn fstatvfs +functions fill the structure pointed to by +.Fa buf +with garbage. +This garbage will occasionally bear resemblance to file system +statistics, but portable applications must not depend on this. +Applications must pass a pathname or file descriptor which refers to a +file on the file system in which they are interested. +.Pp +The +.Vt statvfs +structure contains the following members: +.Bl -tag -offset indent -width ".Va f_namemax" +.It Va f_namemax +The maximum length in bytes of a file name on this file system. +Applications should use +.Xr pathconf 2 +instead. +.It Va f_fsid +Not meaningful in this implementation. +.It Va f_frsize +The size in bytes of the minimum unit of allocation on this +file system. +(This corresponds to the +.Va f_bsize +member of +.Vt "struct statfs" . ) +.It Va f_bsize +The preferred length of I/O requests for files on this file system. +(Corresponds to the +.Va f_iosize +member of +.Vt "struct statfs" . ) +.It Va f_flag +Flags describing mount options for this file system; see below. +.El +.Pp +In addition, there are three members of type +.Vt fsfilcnt_t , +which represent counts of file serial numbers +.Em ( i.e. , +inodes); these are named +.Va f_files , f_favail , +and +.Va f_ffree , +and represent the number of file serial numbers which exist in total, +are available to unprivileged processes, and are available to +privileged processes, respectively. +Likewise, the members +.Va f_blocks , f_bavail , +and +.Va f_bfree +(all of type +.Vt fsblkcnt_t ) +represent the respective allocation-block counts. +.Pp +There are two flags defined for the +.Va f_flag +member: +.Bl -tag -offset indent -width ".Dv ST_NOSUID" +.It Dv ST_RDONLY +The file system is mounted read-only. +.It Dv ST_NOSUID +The semantics of the +.Dv S_ISUID +and +.Dv S_ISGID +file mode bits +are not supported by, or are disabled on, this file system. +.El +.Sh IMPLEMENTATION NOTES +The +.Fn statvfs +and +.Fn fstatvfs +functions are implemented as wrappers around the +.Fn statfs +and +.Fn fstatfs +functions, respectively. +Not all the information provided by those functions is made available +through this interface. +.Sh RETURN VALUES +.Rv -std statvfs fstatvfs +.Sh ERRORS +The +.Fn statvfs +and +.Fn fstatvfs +functions may fail for any of the reasons documented for +.Xr statfs 2 +or +.Xr fstatfs 2 +and +.Xr pathconf 2 +or +.Xr fpathconf 2 , +respectively. +In addition, +.Fn statvfs +and +.Fn fstatvfs +functions may also fail for the following reason: +.Bl -tag -width Er +.It Bq Er EOVERFLOW +One or more of the file system statistics has a value which cannot be +represented by the data types used in +.Vt "struct statvfs" . +.El +.Sh SEE ALSO +.Xr pathconf 2 , +.Xr statfs 2 +.Sh STANDARDS +The +.Fn statvfs +and +.Fn fstatvfs +functions conform to +.St -p1003.1-2001 . +As standardized, portable applications cannot depend on these functions +returning any valid information at all. +This implementation attempts to provide as much useful information as +is provided by the underlying file system, subject to the limitations +of the specified data types. +.Sh HISTORY +The +.Fn statvfs +and +.Fn fstatvfs +functions first appeared in +.Fx 5.0 . +.Sh AUTHORS +The +.Fn statvfs +and +.Fn fstatvfs +functions and this manual page were written by +.An Garrett Wollman Aq Mt wollman@FreeBSD.org . diff --git a/lib/libc/gen/stringlist.3 b/lib/libc/gen/stringlist.3 new file mode 100644 index 0000000..7b4b4fc --- /dev/null +++ b/lib/libc/gen/stringlist.3 @@ -0,0 +1,127 @@ +.\" $NetBSD: stringlist.3,v 1.5 1999/03/22 19:44:46 garbled Exp $ +.\" +.\" Copyright (c) 1997, 1999 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This file was contributed to The NetBSD Foundation by Luke Mewburn. +.\" +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/stringlist.3 249802 2013-04-23 13:03:03Z eadler $ +.\" +.Dd November 28, 1999 +.Dt STRINGLIST 3 +.Os +.Sh NAME +.Nm stringlist , +.Nm sl_init , +.Nm sl_add , +.Nm sl_free , +.Nm sl_find +.Nd stringlist manipulation functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stringlist.h +.Ft StringList * +.Fn sl_init +.Ft int +.Fn sl_add "StringList *sl" "char *item" +.Ft void +.Fn sl_free "StringList *sl" "int freeall" +.Ft char * +.Fn sl_find "StringList *sl" "const char *item" +.Sh DESCRIPTION +The +.Nm +functions manipulate stringlists, which are lists of +strings that extend automatically if necessary. +.Pp +The +.Vt StringList +structure has the following definition: +.Bd -literal -offset indent +typedef struct _stringlist { + char **sl_str; + size_t sl_max; + size_t sl_cur; +} StringList; +.Ed +.Bl -tag -width "sl_str" -offset indent +.It Va sl_str +a pointer to the base of the array containing the list. +.It Va sl_max +the size of +.Va sl_str . +.It Va sl_cur +the offset in +.Va sl_str +of the current element. +.El +.Pp +The following stringlist manipulation functions are available: +.Bl -tag -width "sl_init()" +.It Fn sl_init +Create a stringlist. +Returns a pointer to a +.Vt StringList , +or +.Dv NULL +in case of failure. +.It Fn sl_free +Releases memory occupied by +.Fa sl +and the +.Fa sl->sl_str +array. +If +.Fa freeall +is non-zero, then each of the items within +.Fa sl->sl_str +is released as well. +.It Fn sl_add +Add +.Fa item +to +.Fa sl->sl_str +at +.Fa sl->sl_cur , +extending the size of +.Fa sl->sl_str . +Returns zero upon success, \-1 upon failure. +.It Fn sl_find +Find +.Fa item +in +.Fa sl , +returning NULL if it is not found. +.El +.Sh SEE ALSO +.Xr free 3 , +.Xr malloc 3 +.Sh HISTORY +The +.Nm +functions appeared in +.Fx 2.2.6 +and +.Nx 1.3 . diff --git a/lib/libc/gen/strtofflags.3 b/lib/libc/gen/strtofflags.3 new file mode 100644 index 0000000..91a6a23 --- /dev/null +++ b/lib/libc/gen/strtofflags.3 @@ -0,0 +1,95 @@ +.\" Copyright (c) 1989, 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. +.\" 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. +.\" +.\" @(#)setmode.3 8.2 (Berkeley) 4/28/95 +.\" $FreeBSD: releng/11.1/lib/libc/gen/strtofflags.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd January 1, 2000 +.Dt STRTOFFLAGS 3 +.Os +.Sh NAME +.Nm fflagstostr , +.Nm strtofflags +.Nd convert between file flag bits and their string names +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft char * +.Fn fflagstostr "u_long flags" +.Ft int +.Fn strtofflags "char **stringp" "u_long *setp" "u_long *clrp" +.Sh DESCRIPTION +The +.Fn fflagstostr +function returns a comma separated string of the file flags represented by +.Fa flags . +If no flags are set a zero length string is returned. +.Pp +If memory cannot be allocated for the return value, +.Fn fflagstostr +returns +.Dv NULL . +.Pp +The value returned from +.Fn fflagstostr +is obtained from +.Fn malloc +and should be returned to the system with +.Fn free +when the program is done with it. +.Pp +The +.Fn strtofflags +function takes a string of file flags, as described in +.Xr chflags 1 , +parses it, and returns the 'set' flags and 'clear' flags +such as would be given as arguments to +.Xr chflags 2 . +On success +.Fn strtofflags +returns 0, otherwise it returns non-zero and +.Fa stringp +is left pointing to the offending token. +.Sh ERRORS +The +.Fn fflagstostr +function +may fail and set errno for any of the errors specified for the library +routine +.Xr malloc 3 . +.Sh SEE ALSO +.Xr chflags 1 , +.Xr chflags 2 , +.Xr malloc 3 +.Sh HISTORY +The +.Fn fflagstostr +and +.Fn strtofflags +functions first appeared in +.Fx 4.0 . diff --git a/lib/libc/gen/sysconf.3 b/lib/libc/gen/sysconf.3 new file mode 100644 index 0000000..3e8d308 --- /dev/null +++ b/lib/libc/gen/sysconf.3 @@ -0,0 +1,276 @@ +.\" 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 +.\" 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. +.\" 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. +.\" +.\" @(#)sysconf.3 8.3 (Berkeley) 4/19/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/sysconf.3 249956 2013-04-26 21:43:42Z jilles $ +.\" +.Dd April 26, 2013 +.Dt SYSCONF 3 +.Os +.Sh NAME +.Nm sysconf +.Nd get configurable system variables +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft long +.Fn sysconf "int name" +.Sh DESCRIPTION +This interface is defined by +.St -p1003.1-88 . +A far more complete interface is available using +.Xr sysctl 3 . +.Pp +The +.Fn sysconf +function provides a method for applications to determine the current +value of a configurable system limit or option variable. +The +.Fa name +argument specifies the system variable to be queried. +Symbolic constants for each name value are found in the include file +.In unistd.h . +Shell programmers who need access to these parameters should use the +.Xr getconf 1 +utility. +.Pp +The available values are as follows: +.Bl -tag -width 6n +.It Li _SC_ARG_MAX +The maximum bytes of argument to +.Xr execve 2 . +.It Li _SC_CHILD_MAX +The maximum number of simultaneous processes per user id. +.It Li _SC_CLK_TCK +The frequency of the statistics clock in ticks per second. +.It Li _SC_IOV_MAX +The maximum number of elements in the I/O vector used by +.Xr readv 2 , +.Xr writev 2 , +.Xr recvmsg 2 , +and +.Xr sendmsg 2 . +.It Li _SC_NGROUPS_MAX +The maximum number of supplemental groups. +.It Li _SC_NPROCESSORS_CONF +The number of processors configured. +.It Li _SC_NPROCESSORS_ONLN +The number of processors currently online. +.It Li _SC_OPEN_MAX +One more than the maximum value the system may assign to a new file descriptor. +.It Li _SC_PAGESIZE +The size of a system page in bytes. +.It Li _SC_PAGE_SIZE +Equivalent to +.Li _SC_PAGESIZE . +.It Li _SC_STREAM_MAX +The minimum maximum number of streams that a process may have open +at any one time. +.It Li _SC_TZNAME_MAX +The minimum maximum number of types supported for the name of a +timezone. +.It Li _SC_JOB_CONTROL +Return 1 if job control is available on this system, otherwise \-1. +.It Li _SC_SAVED_IDS +Returns 1 if saved set-group and saved set-user ID is available, +otherwise \-1. +.It Li _SC_VERSION +The version of +.St -p1003.1 +with which the system +attempts to comply. +.It Li _SC_BC_BASE_MAX +The maximum ibase/obase values in the +.Xr bc 1 +utility. +.It Li _SC_BC_DIM_MAX +The maximum array size in the +.Xr bc 1 +utility. +.It Li _SC_BC_SCALE_MAX +The maximum scale value in the +.Xr bc 1 +utility. +.It Li _SC_BC_STRING_MAX +The maximum string length in the +.Xr bc 1 +utility. +.It Li _SC_COLL_WEIGHTS_MAX +The maximum number of weights that can be assigned to any entry of +the LC_COLLATE order keyword in the locale definition file. +.It Li _SC_EXPR_NEST_MAX +The maximum number of expressions that can be nested within +parenthesis by the +.Xr expr 1 +utility. +.It Li _SC_LINE_MAX +The maximum length in bytes of a text-processing utility's input +line. +.It Li _SC_RE_DUP_MAX +The maximum number of repeated occurrences of a regular expression +permitted when using interval notation. +.It Li _SC_2_VERSION +The version of +.St -p1003.2 +with which the system attempts to comply. +.It Li _SC_2_C_BIND +Return 1 if the system's C-language development facilities support the +C-Language Bindings Option, otherwise \-1. +.It Li _SC_2_C_DEV +Return 1 if the system supports the C-Language Development Utilities Option, +otherwise \-1. +.It Li _SC_2_CHAR_TERM +Return 1 if the system supports at least one terminal type capable of +all operations described in +.St -p1003.2 , +otherwise \-1. +.It Li _SC_2_FORT_DEV +Return 1 if the system supports the FORTRAN Development Utilities Option, +otherwise \-1. +.It Li _SC_2_FORT_RUN +Return 1 if the system supports the FORTRAN Runtime Utilities Option, +otherwise \-1. +.It Li _SC_2_LOCALEDEF +Return 1 if the system supports the creation of locales, otherwise \-1. +.It Li _SC_2_SW_DEV +Return 1 if the system supports the Software Development Utilities Option, +otherwise \-1. +.It Li _SC_2_UPE +Return 1 if the system supports the User Portability Utilities Option, +otherwise \-1. +.It Li _SC_AIO_LISTIO_MAX +Maximum number of I/O operations in a single list I/O call supported. +.It Li _SC_AIO_MAX +Maximum number of outstanding asynchronous I/O operations supported. +.It Li _SC_AIO_PRIO_DELTA_MAX +The maximum amount by which a process can decrease its asynchronous I/O +priority level from its own scheduling priority. +.It Li _SC_DELAYTIMER_MAX +Maximum number of timer expiration overruns. +.It Li _SC_MQ_OPEN_MAX +The maximum number of open message queue descriptors a process may hold. +.It Li _SC_RTSIG_MAX +Maximum number of realtime signals reserved for application use. +.It Li _SC_SEM_NSEMS_MAX +Maximum number of semaphores that a process may have. +.It Li _SC_SEM_VALUE_MAX +The maximum value a semaphore may have. +.It Li _SC_SIGQUEUE_MAX +Maximum number of queued signals that a process may send and have pending at +the receiver(s) at any time. +.It Li _SC_TIMER_MAX +Maximum number of timers per process supported. +.It Li _SC_GETGR_R_SIZE_MAX +Suggested initial value for the size of the group entry buffer. +.It Li _SC_GETPW_R_SIZE_MAX +Suggested initial value for the size of the password entry buffer. +.It Li _SC_HOST_NAME_MAX +Maximum length of a host name (not including the terminating null) as +returned from the +.Fn gethostname +function. +.It Li _SC_LOGIN_NAME_MAX +Maximum length of a login name. +.It Li _SC_THREAD_STACK_MIN +Minimum size in bytes of thread stack storage. +.It Li _SC_THREAD_THREADS_MAX +Maximum number of threads that can be created per process. +.It Li _SC_TTY_NAME_MAX +Maximum length of terminal device name. +.It Li _SC_SYMLOOP_MAX +Maximum number of symbolic links that can be reliably traversed in the +resolution of a pathname in the absence of a loop. +.It Li _SC_ATEXIT_MAX +Maximum number of functions that may be registered with +.Fn atexit . +.It Li _SC_XOPEN_VERSION +An integer value greater than or equal to 4, +indicating the version of the X/Open Portability Guide to which this +system conforms. +.It Li _SC_XOPEN_XCU_VERSION +An integer value indicating the version of the XCU Specification to which +this system conforms. +.El +.Pp +These values also exist, but may not be standard: +.Bl -tag -width 6n +.It Li _SC_CPUSET_SIZE +Size of the kernel cpuset. +.It Li _SC_PHYS_PAGES +The number of pages of physical memory. +Note that it is possible that the product of this value and the value of +.Li _SC_PAGESIZE +will overflow a +.Vt long +in some configurations on a 32bit machine. +.El +.Sh RETURN VALUES +If the call to +.Fn sysconf +is not successful, \-1 is returned and +.Va errno +is set appropriately. +Otherwise, if the variable is associated with functionality that is not +supported, \-1 is returned and +.Va errno +is not modified. +Otherwise, the current variable value is returned. +.Sh ERRORS +The +.Fn sysconf +function may fail and set +.Va errno +for any of the errors specified for the library function +.Xr sysctl 3 . +In addition, the following error may be reported: +.Bl -tag -width Er +.It Bq Er EINVAL +The value of the +.Fa name +argument is invalid. +.El +.Sh SEE ALSO +.Xr getconf 1 , +.Xr pathconf 2 , +.Xr confstr 3 , +.Xr sysctl 3 +.Sh STANDARDS +Except for the fact that values returned by +.Fn sysconf +may change over the lifetime of the calling process, +this function conforms to +.St -p1003.1-88 . +.Sh HISTORY +The +.Fn sysconf +function first appeared in +.Bx 4.4 . +.Sh BUGS +The value for _SC_STREAM_MAX is a minimum maximum, and required to be +the same as ANSI C's FOPEN_MAX, so the returned value is a ridiculously +small and misleading number. diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3 new file mode 100644 index 0000000..6a467f5 --- /dev/null +++ b/lib/libc/gen/sysctl.3 @@ -0,0 +1,862 @@ +.\" 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 +.\" 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. +.\" 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. +.\" +.\" @(#)sysctl.3 8.4 (Berkeley) 5/9/95 +.\" $FreeBSD: releng/11.1/lib/libc/gen/sysctl.3 309072 2016-11-23 23:53:52Z jhb $ +.\" +.Dd September 10, 2015 +.Dt SYSCTL 3 +.Os +.Sh NAME +.Nm sysctl , +.Nm sysctlbyname , +.Nm sysctlnametomib +.Nd get or set system information +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/sysctl.h +.Ft int +.Fn sysctl "const int *name" "u_int namelen" "void *oldp" "size_t *oldlenp" "const void *newp" "size_t newlen" +.Ft int +.Fn sysctlbyname "const char *name" "void *oldp" "size_t *oldlenp" "const void *newp" "size_t newlen" +.Ft int +.Fn sysctlnametomib "const char *name" "int *mibp" "size_t *sizep" +.Sh DESCRIPTION +The +.Fn sysctl +function retrieves system information and allows processes with +appropriate privileges to set system information. +The information available from +.Fn sysctl +consists of integers, strings, and tables. +Information may be retrieved and set from the command interface +using the +.Xr sysctl 8 +utility. +.Pp +Unless explicitly noted below, +.Fn sysctl +returns a consistent snapshot of the data requested. +Consistency is obtained by locking the destination +buffer into memory so that the data may be copied out without blocking. +Calls to +.Fn sysctl +are serialized to avoid deadlock. +.Pp +The state is described using a ``Management Information Base'' (MIB) +style name, listed in +.Fa name , +which is a +.Fa namelen +length array of integers. +.Pp +The +.Fn sysctlbyname +function accepts an ASCII representation of the name and internally +looks up the integer name vector. +Apart from that, it behaves the same +as the standard +.Fn sysctl +function. +.Pp +The information is copied into the buffer specified by +.Fa oldp . +The size of the buffer is given by the location specified by +.Fa oldlenp +before the call, +and that location gives the amount of data copied after a successful call +and after a call that returns with the error code +.Er ENOMEM . +If the amount of data available is greater +than the size of the buffer supplied, +the call supplies as much data as fits in the buffer provided +and returns with the error code +.Er ENOMEM . +If the old value is not desired, +.Fa oldp +and +.Fa oldlenp +should be set to NULL. +.Pp +The size of the available data can be determined by calling +.Fn sysctl +with the +.Dv NULL +argument for +.Fa oldp . +The size of the available data will be returned in the location pointed to by +.Fa oldlenp . +For some operations, the amount of space may change often. +For these operations, +the system attempts to round up so that the returned size is +large enough for a call to return the data shortly thereafter. +.Pp +To set a new value, +.Fa newp +is set to point to a buffer of length +.Fa newlen +from which the requested value is to be taken. +If a new value is not to be set, +.Fa newp +should be set to NULL and +.Fa newlen +set to 0. +.Pp +The +.Fn sysctlnametomib +function accepts an ASCII representation of the name, +looks up the integer name vector, +and returns the numeric representation in the mib array pointed to by +.Fa mibp . +The number of elements in the mib array is given by the location specified by +.Fa sizep +before the call, +and that location gives the number of entries copied after a successful call. +The resulting +.Fa mib +and +.Fa size +may be used in subsequent +.Fn sysctl +calls to get the data associated with the requested ASCII name. +This interface is intended for use by applications that want to +repeatedly request the same variable (the +.Fn sysctl +function runs in about a third the time as the same request made via the +.Fn sysctlbyname +function). +The +.Fn sysctlnametomib +function is also useful for fetching mib prefixes and then adding +a final component. +For example, to fetch process information +for processes with pid's less than 100: +.Pp +.Bd -literal -offset indent -compact +int i, mib[4]; +size_t len; +struct kinfo_proc kp; + +/* Fill out the first three components of the mib */ +len = 4; +sysctlnametomib("kern.proc.pid", mib, &len); + +/* Fetch and print entries for pid's < 100 */ +for (i = 0; i < 100; i++) { + mib[3] = i; + len = sizeof(kp); + if (sysctl(mib, 4, &kp, &len, NULL, 0) == -1) + perror("sysctl"); + else if (len > 0) + printkproc(&kp); +} +.Ed +.Pp +The top level names are defined with a CTL_ prefix in +.In sys/sysctl.h , +and are as follows. +The next and subsequent levels down are found in the include files +listed here, and described in separate sections below. +.Bl -column CTLXMACHDEPXXX "Next Level NamesXXXXXX" -offset indent +.It Sy Name Ta Sy Next Level Names Ta Sy Description +.It Dv CTL_DEBUG Ta In sys/sysctl.h Ta Debugging +.It Dv CTL_VFS Ta In sys/mount.h Ta File system +.It Dv CTL_HW Ta In sys/sysctl.h Ta Generic CPU, I/O +.It Dv CTL_KERN Ta In sys/sysctl.h Ta High kernel limits +.It Dv CTL_MACHDEP Ta In sys/sysctl.h Ta Machine dependent +.It Dv CTL_NET Ta In sys/socket.h Ta Networking +.It Dv CTL_USER Ta In sys/sysctl.h Ta User-level +.It Dv CTL_VM Ta In vm/vm_param.h Ta Virtual memory +.El +.Pp +For example, the following retrieves the maximum number of processes allowed +in the system: +.Pp +.Bd -literal -offset indent -compact +int mib[2], maxproc; +size_t len; + +mib[0] = CTL_KERN; +mib[1] = KERN_MAXPROC; +len = sizeof(maxproc); +sysctl(mib, 2, &maxproc, &len, NULL, 0); +.Ed +.Pp +To retrieve the standard search path for the system utilities: +.Pp +.Bd -literal -offset indent -compact +int mib[2]; +size_t len; +char *p; + +mib[0] = CTL_USER; +mib[1] = USER_CS_PATH; +sysctl(mib, 2, NULL, &len, NULL, 0); +p = malloc(len); +sysctl(mib, 2, p, &len, NULL, 0); +.Ed +.Ss CTL_DEBUG +The debugging variables vary from system to system. +A debugging variable may be added or deleted without need to recompile +.Fn sysctl +to know about it. +Each time it runs, +.Fn sysctl +gets the list of debugging variables from the kernel and +displays their current values. +The system defines twenty +.Pq Vt "struct ctldebug" +variables named +.Va debug0 +through +.Va debug19 . +They are declared as separate variables so that they can be +individually initialized at the location of their associated variable. +The loader prevents multiple use of the same variable by issuing errors +if a variable is initialized in more than one place. +For example, to export the variable +.Va dospecialcheck +as a debugging variable, the following declaration would be used: +.Pp +.Bd -literal -offset indent -compact +int dospecialcheck = 1; +struct ctldebug debug5 = { "dospecialcheck", &dospecialcheck }; +.Ed +.Ss CTL_VFS +A distinguished second level name, VFS_GENERIC, +is used to get general information about all file systems. +One of its third level identifiers is VFS_MAXTYPENUM +that gives the highest valid file system type number. +Its other third level identifier is VFS_CONF that +returns configuration information about the file system +type given as a fourth level identifier (see +.Xr getvfsbyname 3 +as an example of its use). +The remaining second level identifiers are the +file system type number returned by a +.Xr statfs 2 +call or from VFS_CONF. +The third level identifiers available for each file system +are given in the header file that defines the mount +argument structure for that file system. +.Ss CTL_HW +The string and integer information available for the CTL_HW level +is detailed below. +The changeable column shows whether a process with appropriate +privilege may change the value. +.Bl -column "Second Level Name" integerXXX Changeable -offset indent +.It Sy Second Level Name Ta Sy Type Ta Sy Changeable +.It Dv HW_MACHINE Ta string Ta no +.It Dv HW_MODEL Ta string Ta no +.It Dv HW_NCPU Ta integer Ta no +.It Dv HW_BYTEORDER Ta integer Ta no +.It Dv HW_PHYSMEM Ta integer Ta no +.It Dv HW_USERMEM Ta integer Ta no +.It Dv HW_PAGESIZE Ta integer Ta no +.\".It Dv HW_DISKNAMES Ta integer Ta no +.\".It Dv HW_DISKSTATS Ta integer Ta no +.It Dv HW_FLOATINGPT Ta integer Ta no +.It Dv HW_MACHINE_ARCH Ta string Ta no +.It Dv HW_REALMEM Ta integer Ta no +.El +.Bl -tag -width 6n +.It Li HW_MACHINE +The machine class. +.It Li HW_MODEL +The machine model +.It Li HW_NCPU +The number of cpus. +.It Li HW_BYTEORDER +The byteorder (4321 or 1234). +.It Li HW_PHYSMEM +The bytes of physical memory. +.It Li HW_USERMEM +The bytes of non-kernel memory. +.It Li HW_PAGESIZE +The software page size. +.\".It Fa HW_DISKNAMES +.\".It Fa HW_DISKSTATS +.It Li HW_FLOATINGPT +Nonzero if the floating point support is in hardware. +.It Li HW_MACHINE_ARCH +The machine dependent architecture type. +.It Li HW_REALMEM +The bytes of real memory. +.El +.Ss CTL_KERN +The string and integer information available for the CTL_KERN level +is detailed below. +The changeable column shows whether a process with appropriate +privilege may change the value. +The types of data currently available are process information, +system vnodes, the open file entries, routing table entries, +virtual memory statistics, load average history, and clock rate +information. +.Bl -column "KERNXMAXFILESPERPROCXXX" "struct clockrateXXX" -offset indent +.It Sy Second Level Name Ta Sy Type Ta Sy Changeable +.It Dv KERN_ARGMAX Ta integer Ta no +.It Dv KERN_BOOTFILE Ta string Ta yes +.It Dv KERN_BOOTTIME Ta struct timeval Ta no +.It Dv KERN_CLOCKRATE Ta struct clockinfo Ta no +.It Dv KERN_FILE Ta struct xfile Ta no +.It Dv KERN_HOSTID Ta integer Ta yes +.It Dv KERN_HOSTUUID Ta string Ta yes +.It Dv KERN_HOSTNAME Ta string Ta yes +.It Dv KERN_JOB_CONTROL Ta integer Ta no +.It Dv KERN_MAXFILES Ta integer Ta yes +.It Dv KERN_MAXFILESPERPROC Ta integer Ta yes +.It Dv KERN_MAXPROC Ta integer Ta no +.It Dv KERN_MAXPROCPERUID Ta integer Ta yes +.It Dv KERN_MAXVNODES Ta integer Ta yes +.It Dv KERN_NGROUPS Ta integer Ta no +.It Dv KERN_NISDOMAINNAME Ta string Ta yes +.It Dv KERN_OSRELDATE Ta integer Ta no +.It Dv KERN_OSRELEASE Ta string Ta no +.It Dv KERN_OSREV Ta integer Ta no +.It Dv KERN_OSTYPE Ta string Ta no +.It Dv KERN_POSIX1 Ta integer Ta no +.It Dv KERN_PROC Ta node Ta not applicable +.It Dv KERN_PROF Ta node Ta not applicable +.It Dv KERN_QUANTUM Ta integer Ta yes +.It Dv KERN_SAVED_IDS Ta integer Ta no +.It Dv KERN_SECURELVL Ta integer Ta raise only +.It Dv KERN_UPDATEINTERVAL Ta integer Ta no +.It Dv KERN_VERSION Ta string Ta no +.It Dv KERN_VNODE Ta struct xvnode Ta no +.El +.Bl -tag -width 6n +.It Li KERN_ARGMAX +The maximum bytes of argument to +.Xr execve 2 . +.It Li KERN_BOOTFILE +The full pathname of the file from which the kernel was loaded. +.It Li KERN_BOOTTIME +A +.Va struct timeval +structure is returned. +This structure contains the time that the system was booted. +.It Li KERN_CLOCKRATE +A +.Va struct clockinfo +structure is returned. +This structure contains the clock, statistics clock and profiling clock +frequencies, the number of micro-seconds per hz tick and the skew rate. +.It Li KERN_FILE +Return the entire file table. +The returned data consists of an array of +.Va struct xfile , +whose size depends on the current number of such objects in the system. +.It Li KERN_HOSTID +Get or set the host ID. +.It Li KERN_HOSTUUID +Get or set the host's universally unique identifier (UUID). +.It Li KERN_HOSTNAME +Get or set the hostname. +.It Li KERN_JOB_CONTROL +Return 1 if job control is available on this system, otherwise 0. +.It Li KERN_MAXFILES +The maximum number of files that may be open in the system. +.It Li KERN_MAXFILESPERPROC +The maximum number of files that may be open for a single process. +This limit only applies to processes with an effective uid of nonzero +at the time of the open request. +Files that have already been opened are not affected if the limit +or the effective uid is changed. +.It Li KERN_MAXPROC +The maximum number of concurrent processes the system will allow. +.It Li KERN_MAXPROCPERUID +The maximum number of concurrent processes the system will allow +for a single effective uid. +This limit only applies to processes with an effective uid of nonzero +at the time of a fork request. +Processes that have already been started are not affected if the limit +is changed. +.It Li KERN_MAXVNODES +The maximum number of vnodes available on the system. +.It Li KERN_NGROUPS +The maximum number of supplemental groups. +.It Li KERN_NISDOMAINNAME +The name of the current YP/NIS domain. +.It Li KERN_OSRELDATE +The kernel release version in the format +.Ar M Ns Ar mm Ns Ar R Ns Ar xx , +where +.Ar M +is the major version, +.Ar mm +is the two digit minor version, +.Ar R +is 0 if release branch, otherwise 1, +and +.Ar xx +is updated when the available APIs change. +.Pp +The userland release version is available from +.In osreldate.h ; +parse this file if you need to get the release version of +the currently installed userland. +.It Li KERN_OSRELEASE +The system release string. +.It Li KERN_OSREV +The system revision string. +.It Li KERN_OSTYPE +The system type string. +.It Li KERN_POSIX1 +The version of +.St -p1003.1 +with which the system +attempts to comply. +.It Li KERN_PROC +Return selected information about specific running processes. +.Pp +For the following names, an array of +.Va struct kinfo_proc +structures is returned, +whose size depends on the current number of such objects in the system. +.Bl -column "Third Level NameXXXXXX" "Fourth LevelXXXXXX" -offset indent +.It Sy Third Level Name Ta Sy Fourth Level +.It Dv KERN_PROC_ALL Ta None +.It Dv KERN_PROC_PID Ta A process ID +.It Dv KERN_PROC_PGRP Ta A process group +.It Dv KERN_PROC_TTY Ta A tty device +.It Dv KERN_PROC_UID Ta A user ID +.It Dv KERN_PROC_RUID Ta A real user ID +.El +.Pp +If the third level name is +.Dv KERN_PROC_ARGS +then the command line argument +array is returned in a flattened form, i.e., zero-terminated arguments +follow each other. +The total size of array is returned. +It is also possible for a process to set its own process title this way. +If the third level name is +.Dv KERN_PROC_PATHNAME , +the path of the +process' text file is stored. +For +.Dv KERN_PROC_PATHNAME , +a process ID of +.Li \-1 +implies the current process. +.Bl -column "Third Level NameXXXXXX" "Fourth LevelXXXXXX" -offset indent +.It Sy Third Level Name Ta Sy Fourth Level +.It Dv KERN_PROC_ARGS Ta "A process ID" +.It Dv KERN_PROC_PATHNAME Ta "A process ID" +.El +.It Li KERN_PROF +Return profiling information about the kernel. +If the kernel is not compiled for profiling, +attempts to retrieve any of the KERN_PROF values will +fail with +.Er ENOENT . +The third level names for the string and integer profiling information +is detailed below. +The changeable column shows whether a process with appropriate +privilege may change the value. +.Bl -column "GPROFXGMONPARAMXXX" "struct gmonparamXXX" -offset indent +.It Sy Third Level Name Ta Sy Type Ta Sy Changeable +.It Dv GPROF_STATE Ta integer Ta yes +.It Dv GPROF_COUNT Ta u_short[\|] Ta yes +.It Dv GPROF_FROMS Ta u_short[\|] Ta yes +.It Dv GPROF_TOS Ta struct tostruct Ta yes +.It Dv GPROF_GMONPARAM Ta struct gmonparam Ta no +.El +.Pp +The variables are as follows: +.Bl -tag -width 6n +.It Li GPROF_STATE +Returns GMON_PROF_ON or GMON_PROF_OFF to show that profiling +is running or stopped. +.It Li GPROF_COUNT +Array of statistical program counter counts. +.It Li GPROF_FROMS +Array indexed by program counter of call-from points. +.It Li GPROF_TOS +Array of +.Va struct tostruct +describing destination of calls and their counts. +.It Li GPROF_GMONPARAM +Structure giving the sizes of the above arrays. +.El +.It Li KERN_QUANTUM +The maximum period of time, in microseconds, for which a process is allowed +to run without being preempted if other processes are in the run queue. +.It Li KERN_SAVED_IDS +Returns 1 if saved set-group and saved set-user ID is available. +.It Li KERN_SECURELVL +The system security level. +This level may be raised by processes with appropriate privilege. +It may not be lowered. +.It Li KERN_VERSION +The system version string. +.It Li KERN_VNODE +Return the entire vnode table. +Note, the vnode table is not necessarily a consistent snapshot of +the system. +The returned data consists of an array whose size depends on the +current number of such objects in the system. +Each element of the array consists of a +.Va struct xvnode . +.El +.Ss CTL_NET +The string and integer information available for the CTL_NET level +is detailed below. +The changeable column shows whether a process with appropriate +privilege may change the value. +.Bl -column "Second Level NameXXXXXX" "routing messagesXXX" -offset indent +.It Sy Second Level Name Ta Sy Type Ta Sy Changeable +.It Dv PF_ROUTE Ta routing messages Ta no +.It Dv PF_INET Ta IPv4 values Ta yes +.It Dv PF_INET6 Ta IPv6 values Ta yes +.El +.Bl -tag -width 6n +.It Li PF_ROUTE +Return the entire routing table or a subset of it. +The data is returned as a sequence of routing messages (see +.Xr route 4 +for the header file, format and meaning). +The length of each message is contained in the message header. +.Pp +The third level name is a protocol number, which is currently always 0. +The fourth level name is an address family, which may be set to 0 to +select all address families. +The fifth, sixth, and seventh level names are as follows: +.Bl -column -offset indent "Fifth Level" "Sixth Level" "Seventh Level" +.It Sy Fifth level Ta Sy Sixth Level Ta Sy Seventh Level +.It Dv NET_RT_FLAGS Ta rtflags Ta None +.It Dv NET_RT_DUMP Ta None Ta None or fib number +.It Dv NET_RT_IFLIST Ta 0 or if_index Ta None +.It Dv NET_RT_IFMALIST Ta 0 or if_index Ta None +.It Dv NET_RT_IFLISTL Ta 0 or if_index Ta None +.El +.Pp +The +.Dv NET_RT_IFMALIST +name returns information about multicast group memberships on all interfaces +if 0 is specified, or for the interface specified by +.Va if_index . +.Pp +The +.Dv NET_RT_IFLISTL +is like +.Dv NET_RT_IFLIST , +just returning message header structs with additional fields allowing the +interface to be extended without breaking binary compatibility. +The +.Dv NET_RT_IFLISTL +uses 'l' versions of the message header structures: +.Va struct if_msghdrl +and +.Va struct ifa_msghdrl . +.It Li PF_INET +Get or set various global information about the IPv4 +(Internet Protocol version 4). +The third level name is the protocol. +The fourth level name is the variable name. +The currently defined protocols and names are: +.Bl -column ProtocolXX VariableXX TypeXX ChangeableXX +.It Sy Protocol Ta Sy Variable Ta Sy Type Ta Sy Changeable +.It icmp Ta bmcastecho Ta integer Ta yes +.It icmp Ta maskrepl Ta integer Ta yes +.It ip Ta forwarding Ta integer Ta yes +.It ip Ta redirect Ta integer Ta yes +.It ip Ta ttl Ta integer Ta yes +.It udp Ta checksum Ta integer Ta yes +.El +.Pp +The variables are as follows: +.Bl -tag -width 6n +.It Li icmp.bmcastecho +Returns 1 if an ICMP echo request to a broadcast or multicast address is +to be answered. +.It Li icmp.maskrepl +Returns 1 if ICMP network mask requests are to be answered. +.It Li ip.forwarding +Returns 1 when IP forwarding is enabled for the host, +meaning that the host is acting as a router. +.It Li ip.redirect +Returns 1 when ICMP redirects may be sent by the host. +This option is ignored unless the host is routing IP packets, +and should normally be enabled on all systems. +.It Li ip.ttl +The maximum time-to-live (hop count) value for an IP packet sourced by +the system. +This value applies to normal transport protocols, not to ICMP. +.It Li udp.checksum +Returns 1 when UDP checksums are being computed and checked. +Disabling UDP checksums is strongly discouraged. +.Pp +For variables net.inet.*.ipsec, please refer to +.Xr ipsec 4 . +.El +.It Li PF_INET6 +Get or set various global information about the IPv6 +(Internet Protocol version 6). +The third level name is the protocol. +The fourth level name is the variable name. +.Pp +For variables net.inet6.* please refer to +.Xr inet6 4 . +For variables net.inet6.*.ipsec6, please refer to +.Xr ipsec 4 . +.El +.Ss CTL_USER +The string and integer information available for the CTL_USER level +is detailed below. +The changeable column shows whether a process with appropriate +privilege may change the value. +.Bl -column "USER_COLL_WEIGHTS_MAXXXX" "integerXXX" -offset indent +.It Sy Second Level Name Ta Sy Type Ta Sy Changeable +.It Dv USER_BC_BASE_MAX Ta integer Ta no +.It Dv USER_BC_DIM_MAX Ta integer Ta no +.It Dv USER_BC_SCALE_MAX Ta integer Ta no +.It Dv USER_BC_STRING_MAX Ta integer Ta no +.It Dv USER_COLL_WEIGHTS_MAX Ta integer Ta no +.It Dv USER_CS_PATH Ta string Ta no +.It Dv USER_EXPR_NEST_MAX Ta integer Ta no +.It Dv USER_LINE_MAX Ta integer Ta no +.It Dv USER_POSIX2_CHAR_TERM Ta integer Ta no +.It Dv USER_POSIX2_C_BIND Ta integer Ta no +.It Dv USER_POSIX2_C_DEV Ta integer Ta no +.It Dv USER_POSIX2_FORT_DEV Ta integer Ta no +.It Dv USER_POSIX2_FORT_RUN Ta integer Ta no +.It Dv USER_POSIX2_LOCALEDEF Ta integer Ta no +.It Dv USER_POSIX2_SW_DEV Ta integer Ta no +.It Dv USER_POSIX2_UPE Ta integer Ta no +.It Dv USER_POSIX2_VERSION Ta integer Ta no +.It Dv USER_RE_DUP_MAX Ta integer Ta no +.It Dv USER_STREAM_MAX Ta integer Ta no +.It Dv USER_TZNAME_MAX Ta integer Ta no +.El +.Bl -tag -width 6n +.It Li USER_BC_BASE_MAX +The maximum ibase/obase values in the +.Xr bc 1 +utility. +.It Li USER_BC_DIM_MAX +The maximum array size in the +.Xr bc 1 +utility. +.It Li USER_BC_SCALE_MAX +The maximum scale value in the +.Xr bc 1 +utility. +.It Li USER_BC_STRING_MAX +The maximum string length in the +.Xr bc 1 +utility. +.It Li USER_COLL_WEIGHTS_MAX +The maximum number of weights that can be assigned to any entry of +the LC_COLLATE order keyword in the locale definition file. +.It Li USER_CS_PATH +Return a value for the +.Ev PATH +environment variable that finds all the standard utilities. +.It Li USER_EXPR_NEST_MAX +The maximum number of expressions that can be nested within +parenthesis by the +.Xr expr 1 +utility. +.It Li USER_LINE_MAX +The maximum length in bytes of a text-processing utility's input +line. +.It Li USER_POSIX2_CHAR_TERM +Return 1 if the system supports at least one terminal type capable of +all operations described in +.St -p1003.2 , +otherwise 0. +.It Li USER_POSIX2_C_BIND +Return 1 if the system's C-language development facilities support the +C-Language Bindings Option, otherwise 0. +.It Li USER_POSIX2_C_DEV +Return 1 if the system supports the C-Language Development Utilities Option, +otherwise 0. +.It Li USER_POSIX2_FORT_DEV +Return 1 if the system supports the FORTRAN Development Utilities Option, +otherwise 0. +.It Li USER_POSIX2_FORT_RUN +Return 1 if the system supports the FORTRAN Runtime Utilities Option, +otherwise 0. +.It Li USER_POSIX2_LOCALEDEF +Return 1 if the system supports the creation of locales, otherwise 0. +.It Li USER_POSIX2_SW_DEV +Return 1 if the system supports the Software Development Utilities Option, +otherwise 0. +.It Li USER_POSIX2_UPE +Return 1 if the system supports the User Portability Utilities Option, +otherwise 0. +.It Li USER_POSIX2_VERSION +The version of +.St -p1003.2 +with which the system attempts to comply. +.It Li USER_RE_DUP_MAX +The maximum number of repeated occurrences of a regular expression +permitted when using interval notation. +.It Li USER_STREAM_MAX +The minimum maximum number of streams that a process may have open +at any one time. +.It Li USER_TZNAME_MAX +The minimum maximum number of types supported for the name of a +timezone. +.El +.Ss CTL_VM +The string and integer information available for the CTL_VM level +is detailed below. +The changeable column shows whether a process with appropriate +privilege may change the value. +.Bl -column "Second Level NameXXXXXX" "struct loadavgXXX" -offset indent +.It Sy Second Level Name Ta Sy Type Ta Sy Changeable +.It Dv VM_LOADAVG Ta struct loadavg Ta no +.It Dv VM_TOTAL Ta struct vmtotal Ta no +.It Dv VM_SWAPPING_ENABLED Ta integer Ta maybe +.It Dv VM_V_FREE_MIN Ta integer Ta yes +.It Dv VM_V_FREE_RESERVED Ta integer Ta yes +.It Dv VM_V_FREE_TARGET Ta integer Ta yes +.It Dv VM_V_INACTIVE_TARGET Ta integer Ta yes +.It Dv VM_V_PAGEOUT_FREE_MIN Ta integer Ta yes +.El +.Bl -tag -width 6n +.It Li VM_LOADAVG +Return the load average history. +The returned data consists of a +.Va struct loadavg . +.It Li VM_TOTAL +Return the system wide virtual memory statistics. +The returned data consists of a +.Va struct vmtotal . +.It Li VM_SWAPPING_ENABLED +1 if process swapping is enabled or 0 if disabled. +This variable is +permanently set to 0 if the kernel was built with swapping disabled. +.It Li VM_V_FREE_MIN +Minimum amount of memory (cache memory plus free memory) +required to be available before a process waiting on memory will be +awakened. +.It Li VM_V_FREE_RESERVED +Processes will awaken the pageout daemon and wait for memory if the +number of free and cached pages drops below this value. +.It Li VM_V_FREE_TARGET +The total amount of free memory (including cache memory) that the +pageout daemon tries to maintain. +.It Li VM_V_INACTIVE_TARGET +The desired number of inactive pages that the pageout daemon should +achieve when it runs. +Inactive pages can be quickly inserted into +process address space when needed. +.It Li VM_V_PAGEOUT_FREE_MIN +If the amount of free and cache memory falls below this value, the +pageout daemon will enter "memory conserving mode" to avoid deadlock. +.El +.Sh RETURN VALUES +.Rv -std +.Sh FILES +.Bl -tag -width -compact +.It In sys/sysctl.h +definitions for top level identifiers, second level kernel and hardware +identifiers, and user level identifiers +.It In sys/socket.h +definitions for second level network identifiers +.It In sys/gmon.h +definitions for third level profiling identifiers +.It In vm/vm_param.h +definitions for second level virtual memory identifiers +.It In netinet/in.h +definitions for third level IPv4/IPv6 identifiers and +fourth level IPv4/v6 identifiers +.It In netinet/icmp_var.h +definitions for fourth level ICMP identifiers +.It In netinet/icmp6.h +definitions for fourth level ICMPv6 identifiers +.It In netinet/udp_var.h +definitions for fourth level UDP identifiers +.El +.Sh ERRORS +The following errors may be reported: +.Bl -tag -width Er +.It Bq Er EFAULT +The buffer +.Fa name , +.Fa oldp , +.Fa newp , +or length pointer +.Fa oldlenp +contains an invalid address. +.It Bq Er EINVAL +The +.Fa name +array is less than two or greater than CTL_MAXNAME. +.It Bq Er EINVAL +A non-null +.Fa newp +is given and its specified length in +.Fa newlen +is too large or too small. +.It Bq Er ENOMEM +The length pointed to by +.Fa oldlenp +is too short to hold the requested value. +.It Bq Er ENOMEM +The smaller of either the length pointed to by +.Fa oldlenp +or the estimated size of the returned data exceeds the +system limit on locked memory. +.It Bq Er ENOMEM +Locking the buffer +.Fa oldp , +or a portion of the buffer if the estimated size of the data +to be returned is smaller, +would cause the process to exceed its per-process locked memory limit. +.It Bq Er ENOTDIR +The +.Fa name +array specifies an intermediate rather than terminal name. +.It Bq Er EISDIR +The +.Fa name +array specifies a terminal name, but the actual name is not terminal. +.It Bq Er ENOENT +The +.Fa name +array specifies a value that is unknown. +.It Bq Er EPERM +An attempt is made to set a read-only value. +.It Bq Er EPERM +A process without appropriate privilege attempts to set a value. +.El +.Sh SEE ALSO +.Xr confstr 3 , +.Xr kvm 3 , +.Xr sysconf 3 , +.Xr sysctl 8 +.Sh HISTORY +The +.Fn sysctl +function first appeared in +.Bx 4.4 . diff --git a/lib/libc/gen/syslog.3 b/lib/libc/gen/syslog.3 new file mode 100644 index 0000000..6c580f7 --- /dev/null +++ b/lib/libc/gen/syslog.3 @@ -0,0 +1,295 @@ +.\" Copyright (c) 1985, 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. +.\" 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. +.\" +.\" @(#)syslog.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/syslog.3 285739 2015-07-21 09:44:45Z pluknet $ +.\" +.Dd July 21, 2015 +.Dt SYSLOG 3 +.Os +.Sh NAME +.Nm syslog , +.Nm vsyslog , +.Nm openlog , +.Nm closelog , +.Nm setlogmask +.Nd control system log +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In syslog.h +.In stdarg.h +.Ft void +.Fn syslog "int priority" "const char *message" "..." +.Ft void +.Fn vsyslog "int priority" "const char *message" "va_list args" +.Ft void +.Fn openlog "const char *ident" "int logopt" "int facility" +.Ft void +.Fn closelog void +.Ft int +.Fn setlogmask "int maskpri" +.Sh DESCRIPTION +The +.Fn syslog +function +writes +.Fa message +to the system message logger. +The message is then written to the system console, log files, +logged-in users, or forwarded to other machines as appropriate. +(See +.Xr syslogd 8 . ) +.Pp +The message is identical to a +.Xr printf 3 +format string, except that +.Ql %m +is replaced by the current error +message. +(As denoted by the global variable +.Va errno ; +see +.Xr strerror 3 . ) +A trailing newline is added if none is present. +.Pp +The +.Fn vsyslog +function +is an alternate form in which the arguments have already been captured +using the variable-length argument facilities of +.Xr stdarg 3 . +.Pp +The message is tagged with +.Fa priority . +Priorities are encoded as a +.Fa facility +and a +.Em level . +The facility describes the part of the system +generating the message. +The level is selected from the following +.Em ordered +(high to low) list: +.Bl -tag -width LOG_AUTHPRIV +.It Dv LOG_EMERG +A panic condition. +This is normally broadcast to all users. +.It Dv LOG_ALERT +A condition that should be corrected immediately, such as a corrupted +system database. +.It Dv LOG_CRIT +Critical conditions, e.g., hard device errors. +.It Dv LOG_ERR +Errors. +.It Dv LOG_WARNING +Warning messages. +.It Dv LOG_NOTICE +Conditions that are not error conditions, +but should possibly be handled specially. +.It Dv LOG_INFO +Informational messages. +.It Dv LOG_DEBUG +Messages that contain information +normally of use only when debugging a program. +.El +.Pp +The +.Fn openlog +function +provides for more specialized processing of the messages sent +by +.Fn syslog +and +.Fn vsyslog . +The +.Fa ident +argument +is a string that will be prepended to every message. +The +.Fa logopt +argument +is a bit field specifying logging options, which is formed by +.Tn OR Ns 'ing +one or more of the following values: +.Bl -tag -width LOG_AUTHPRIV +.It Dv LOG_CONS +If +.Fn syslog +cannot pass the message to +.Xr syslogd 8 +it will attempt to write the message to the console +.Pq Dq Pa /dev/console . +.It Dv LOG_NDELAY +Open the connection to +.Xr syslogd 8 +immediately. +Normally the open is delayed until the first message is logged. +Useful for programs that need to manage the order in which file +descriptors are allocated. +.It Dv LOG_PERROR +Write the message to standard error output as well to the system log. +.It Dv LOG_PID +Log the process id with each message: useful for identifying +instantiations of daemons. +.El +.Pp +The +.Fa facility +argument encodes a default facility to be assigned to all messages +that do not have an explicit facility encoded: +.Bl -tag -width LOG_AUTHPRIV +.It Dv LOG_AUTH +The authorization system: +.Xr login 1 , +.Xr su 1 , +.Xr getty 8 , +etc. +.It Dv LOG_AUTHPRIV +The same as +.Dv LOG_AUTH , +but logged to a file readable only by +selected individuals. +.It Dv LOG_CONSOLE +Messages written to +.Pa /dev/console +by the kernel console output driver. +.It Dv LOG_CRON +The cron daemon: +.Xr cron 8 . +.It Dv LOG_DAEMON +System daemons, such as +.Xr routed 8 , +that are not provided for explicitly by other facilities. +.It Dv LOG_FTP +The file transfer protocol daemons: +.Xr ftpd 8 , +.Xr tftpd 8 . +.It Dv LOG_KERN +Messages generated by the kernel. +These cannot be generated by any user processes. +.It Dv LOG_LPR +The line printer spooling system: +.Xr lpr 1 , +.Xr lpc 8 , +.Xr lpd 8 , +etc. +.It Dv LOG_MAIL +The mail system. +.It Dv LOG_NEWS +The network news system. +.It Dv LOG_NTP +The network time protocol system. +.It Dv LOG_SECURITY +Security subsystems, such as +.Xr ipfw 4 . +.It Dv LOG_SYSLOG +Messages generated internally by +.Xr syslogd 8 . +.It Dv LOG_USER +Messages generated by random user processes. +This is the default facility identifier if none is specified. +.It Dv LOG_UUCP +The uucp system. +.It Dv LOG_LOCAL0 +Reserved for local use. +Similarly for +.Dv LOG_LOCAL1 +through +.Dv LOG_LOCAL7 . +.El +.Pp +The +.Fn closelog +function +can be used to close the log file. +.Pp +The +.Fn setlogmask +function +sets the log priority mask to +.Fa maskpri +and returns the previous mask. +Calls to +.Fn syslog +with a priority not set in +.Fa maskpri +are rejected. +The mask for an individual priority +.Fa pri +is calculated by the macro +.Fn LOG_MASK pri ; +the mask for all priorities up to and including +.Fa toppri +is given by the macro +.Fn LOG_UPTO toppri ; . +The default allows all priorities to be logged. +.Sh RETURN VALUES +The routines +.Fn closelog , +.Fn openlog , +.Fn syslog +and +.Fn vsyslog +return no value. +.Pp +The routine +.Fn setlogmask +always returns the previous log mask level. +.Sh EXAMPLES +.Bd -literal -offset indent -compact +syslog(LOG_ALERT, "who: internal error 23"); + +openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP); + +setlogmask(LOG_UPTO(LOG_ERR)); + +syslog(LOG_INFO, "Connection from host %d", CallingHost); + +syslog(LOG_INFO|LOG_LOCAL2, "foobar error: %m"); +.Ed +.Sh SEE ALSO +.Xr logger 1 , +.Xr syslogd 8 +.Sh HISTORY +These +functions appeared in +.Bx 4.2 . +.Sh BUGS +Never pass a string with user-supplied data as a format without using +.Ql %s . +An attacker can put format specifiers in the string to mangle your stack, +leading to a possible security hole. +This holds true even if the string was built using a function like +.Fn snprintf , +as the resulting string may still contain user-supplied conversion specifiers +for later interpolation by +.Fn syslog . +.Pp +Always use the proper secure idiom: +.Pp +.Dl syslog(priority, "%s", string); diff --git a/lib/libc/gen/tcgetpgrp.3 b/lib/libc/gen/tcgetpgrp.3 new file mode 100644 index 0000000..2dd58c7 --- /dev/null +++ b/lib/libc/gen/tcgetpgrp.3 @@ -0,0 +1,78 @@ +.\" 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. +.\" 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 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/tcgetpgrp.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 4, 1993 +.Dt TCGETPGRP 3 +.Os +.Sh NAME +.Nm tcgetpgrp +.Nd get foreground process group ID +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In unistd.h +.Ft pid_t +.Fn tcgetpgrp "int fd" +.Sh DESCRIPTION +The +.Fn 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, +.Fn tcgetpgrp +returns an invalid process ID. +.Sh ERRORS +If an error occurs, +.Fn 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 2 , +.Xr setsid 2 , +.Xr tcsetpgrp 3 +.Sh STANDARDS +The +.Fn tcgetpgrp +function is expected to be compliant with the +.St -p1003.1-88 +specification. diff --git a/lib/libc/gen/tcgetsid.3 b/lib/libc/gen/tcgetsid.3 new file mode 100644 index 0000000..e422892 --- /dev/null +++ b/lib/libc/gen/tcgetsid.3 @@ -0,0 +1,72 @@ +.\" Copyright (c) 2008 David Xu +.\" 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. +.\" +.\" 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/tcgetsid.3 208291 2010-05-19 08:57:53Z uqs $ +.\" +.Dd April 15, 2008 +.Dt TCGETSID 3 +.Os +.Sh NAME +.Nm tcgetsid +.Nd get session ID associated with a controlling terminal +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In termios.h +.Ft pid_t +.Fn tcgetsid "int fd" +.Sh DESCRIPTION +The +.Fn tcgetsid +function returns the process group ID of the session leader for a +controlling terminal specified by +.Fa fd . +.Sh ERRORS +If an error occurs, +.Fn tcgetsid +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 getsid 2 , +.Xr setsid 2 , +.Xr tcgetpgrp 3 , +.Xr tcsetsid 3 +.Sh STANDARDS +The +.Fn tcgetsid +function conforms to +.St -xpg4.2 . diff --git a/lib/libc/gen/tcsendbreak.3 b/lib/libc/gen/tcsendbreak.3 new file mode 100644 index 0000000..37e89e4 --- /dev/null +++ b/lib/libc/gen/tcsendbreak.3 @@ -0,0 +1,180 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)tcsendbreak.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/tcsendbreak.3 314538 2017-03-02 04:23:53Z ian $ +.\" +.Dd January 11, 2017 +.Dt TCSENDBREAK 3 +.Os +.Sh NAME +.Nm tcsendbreak , +.Nm tcdrain , +.Nm tcflush , +.Nm tcflow +.Nd line control functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In termios.h +.Ft int +.Fn tcdrain "int fd" +.Ft int +.Fn tcflow "int fd" "int action" +.Ft int +.Fn tcflush "int fd" "int action" +.Ft int +.Fn tcsendbreak "int fd" "int len" +.Sh DESCRIPTION +The +.Fn tcdrain +function waits until all output written to the terminal referenced by +.Fa fd +has been transmitted to the terminal. +.Pp +The +.Fn tcflow +function suspends transmission of data to or the reception of data from +the terminal referenced by +.Fa fd +depending on the value of +.Fa action . +The value of +.Fa action +must be one of the following: +.Bl -tag -width "TCIOFF" +.It Fa TCOOFF +Suspend output. +.It Fa TCOON +Restart suspended output. +.It Fa TCIOFF +Transmit a STOP character, which is intended to cause the terminal to stop +transmitting data to the system. +(See the description of IXOFF in the +.Ql Input Modes +section of +.Xr termios 4 ) . +.It Fa TCION +Transmit a START character, which is intended to cause the terminal to start +transmitting data to the system. +(See the description of IXOFF in the +.Ql Input Modes +section of +.Xr termios 4 ) . +.El +.Pp +The +.Fn tcflush +function discards any data written to the terminal referenced by +.Fa fd +which has not been transmitted to the terminal, or any data received +from the terminal but not yet read, depending on the value of +.Fa action . +The value of +.Fa action +must be one of the following: +.Bl -tag -width "TCIOFLUSH" +.It Fa TCIFLUSH +Flush data received but not read. +.It Fa TCOFLUSH +Flush data written but not transmitted. +.It Fa TCIOFLUSH +Flush both data received but not read and data written but not transmitted. +.El +.Pp +The +.Fn tcsendbreak +function transmits a continuous stream of zero-valued bits for four-tenths +of a second to the terminal referenced by +.Fa fd . +The +.Fa len +argument is ignored in this implementation. +.Sh RETURN VALUES +Upon successful completion, all of these functions return a value of zero. +.Sh ERRORS +If any error occurs, a value of -1 is returned 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 +The +.Fa action +argument is not a proper value. +.It Bq Er ENOTTY +The file associated with +.Fa fd +is not a terminal. +.It Bq Er EINTR +A signal interrupted the +.Fn tcdrain +function. +.It Bq Er EWOULDBLOCK +The configured timeout expired before the +.Fn tcdrain +function could write all buffered output. +.El +.Sh SEE ALSO +.Xr tcsetattr 3 , +.Xr termios 4 , +.Xr tty 4 , +.Xr comcontrol 8 +.Sh STANDARDS +The +.Fn tcsendbreak , +.Fn tcflush +and +.Fn tcflow +functions are expected to be compliant with the +.St -p1003.1-88 +specification. +.Pp +The +.Fn tcdrain +function is expected to be compliant with +.St -p1003.1-88 +when the drain wait value is set to zero with +.Xr comcontrol 8 , +or with +.Xr ioctl 2 +.Va TIOCSDRAINWAIT , +or with +.Xr sysctl 8 +.Va kern.tty_drainwait . +A non-zero drain wait value can result in +.Fn tcdrain +returning +.Va EWOULDBLOCK +without writing all output. +The default value for +.Va kern.tty_drainwait +is 300 seconds. + diff --git a/lib/libc/gen/tcsetattr.3 b/lib/libc/gen/tcsetattr.3 new file mode 100644 index 0000000..86a2699 --- /dev/null +++ b/lib/libc/gen/tcsetattr.3 @@ -0,0 +1,340 @@ +.\" 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. +.\" 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 8.3 (Berkeley) 1/2/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/tcsetattr.3 214680 2010-11-02 17:00:56Z ed $ +.\" +.Dd January 2, 1994 +.Dt TCSETATTR 3 +.Os +.Sh NAME +.Nm cfgetispeed , +.Nm cfsetispeed , +.Nm cfgetospeed , +.Nm cfsetospeed , +.Nm cfsetspeed , +.Nm cfmakeraw , +.Nm cfmakesane , +.Nm tcgetattr , +.Nm tcsetattr +.Nd manipulating the termios structure +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In termios.h +.Ft speed_t +.Fn cfgetispeed "const struct termios *t" +.Ft int +.Fn cfsetispeed "struct termios *t" "speed_t speed" +.Ft speed_t +.Fn cfgetospeed "const struct termios *t" +.Ft int +.Fn cfsetospeed "struct termios *t" "speed_t speed" +.Ft int +.Fn cfsetspeed "struct termios *t" "speed_t speed" +.Ft void +.Fn cfmakeraw "struct termios *t" +.Ft void +.Fn cfmakesane "struct termios *t" +.Ft int +.Fn tcgetattr "int fd" "struct termios *t" +.Ft int +.Fn tcsetattr "int fd" "int action" "const struct termios *t" +.Sh DESCRIPTION +The +.Fn cfmakeraw , +.Fn cfmakesane , +.Fn tcgetattr +and +.Fn tcsetattr +functions are provided for getting and setting the termios structure. +.Pp +The +.Fn cfgetispeed , +.Fn cfsetispeed , +.Fn cfgetospeed , +.Fn cfsetospeed +and +.Fn 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 +.Fn tcsetattr +function is called. +Certain values for baud rates set in the termios structure and passed to +.Fn tcsetattr +have special meanings. +These are discussed in the portion of the manual page that describes the +.Fn 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 typedef'd in the include file +.In 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 +.Fn cfgetispeed +function returns the input baud rate in the termios structure referenced by +.Fa tp . +.Pp +The +.Fn cfsetispeed +function sets the input baud rate in the termios structure referenced by +.Fa tp +to +.Fa speed . +.Pp +The +.Fn cfgetospeed +function returns the output baud rate in the termios structure referenced by +.Fa tp . +.Pp +The +.Fn cfsetospeed +function sets the output baud rate in the termios structure referenced by +.Fa tp +to +.Fa speed . +.Pp +The +.Fn 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 +.Fn cfsetispeed , +.Fn cfsetospeed , +and +.Fn 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 +.Fn 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 , +while the +.Fn cfmakesane +function sets them to a state similar to those of a newly created +terminal device. +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 +.Fn tcgetattr , +setting raw or sane mode with +.Fn cfmakeraw +or +.Fn cfmakesane +and the subsequent +.Fn tcsetattr , +and then using another +.Fn tcsetattr +with the saved state to revert to the previous terminal state. +.Pp +The +.Fn 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 +.Fn tcsetattr +function sets the parameters associated with the terminal from the +termios structure referenced by +.Fa tp . +The +.Fa action +argument is created by +.Em or Ns 'ing +the following values, as specified in the include file +.In 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 +.Va c_cflag , +.Va c_ispeed , +and +.Va 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 +.Fn 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 +.Fn tcsetattr , +the input baud rate will be set to the same value as that specified by +the output baud rate. +.Pp +If +.Fn tcsetattr +is unable 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 +.Fn tcgetattr +and +.Fn 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 +.Fn tcgetattr +or +.Fn tcsetattr +was not a valid file descriptor. +.It Bq Er EINTR +The +.Fn tcsetattr +function was interrupted by a signal. +.It Bq Er EINVAL +The +.Fa action +argument to the +.Fn 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 +.Fn tcgetattr +or +.Fn tcsetattr +is not a terminal. +.El +.Sh SEE ALSO +.Xr tcsendbreak 3 , +.Xr termios 4 +.Sh STANDARDS +The +.Fn cfgetispeed , +.Fn cfsetispeed , +.Fn cfgetospeed , +.Fn cfsetospeed , +.Fn tcgetattr +and +.Fn tcsetattr +functions are expected to be compliant with the +.St -p1003.1-88 +specification. +The +.Fn cfmakeraw , +.Fn cfmakesane +and +.Fn cfsetspeed +functions, +as well as the +.Li TCSASOFT +option to the +.Fn 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 0000000..5f6ff4d --- /dev/null +++ b/lib/libc/gen/tcsetpgrp.3 @@ -0,0 +1,95 @@ +.\" 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. +.\" 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 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/tcsetpgrp.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd June 4, 1993 +.Dt TCSETPGRP 3 +.Os +.Sh NAME +.Nm tcsetpgrp +.Nd set foreground process group ID +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In unistd.h +.Ft int +.Fn tcsetpgrp "int fd" "pid_t pgrp_id" +.Sh DESCRIPTION +If the process has a controlling terminal, the +.Fn 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. +.Sh RETURN VALUES +.Rv -std tcsetpgrp +.Sh ERRORS +The +.Fn tcsetpgrp +function will fail if: +.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 2 , +.Xr setsid 2 , +.Xr tcgetpgrp 3 +.Sh STANDARDS +The +.Fn tcsetpgrp +function is expected to be compliant with the +.St -p1003.1-88 +specification. diff --git a/lib/libc/gen/tcsetsid.3 b/lib/libc/gen/tcsetsid.3 new file mode 100644 index 0000000..14a9f26 --- /dev/null +++ b/lib/libc/gen/tcsetsid.3 @@ -0,0 +1,92 @@ +.\" Copyright (c) 2009 Ed Schouten +.\" 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. +.\" +.\" 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/tcsetsid.3 191882 2009-05-07 13:49:48Z ed $ +.\" +.Dd May 4, 2009 +.Dt TCSETSID 3 +.Os +.Sh NAME +.Nm tcsetsid +.Nd set session ID associated with a controlling terminal +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In termios.h +.Ft int +.Fn tcsetsid "int fd" "pid_t pid" +.Sh DESCRIPTION +The +.Fn tcsetsid +function sets associates a session identified by +.Fa pid +with a controlling terminal specified by +.Fa fd . +.Pp +This implementation only allows the controlling terminal to be changed +by the session leader itself. +This implies that +.Fa pid +always has to be equal to the process ID. +.Pp +It is unsupported to associate with a terminal that already has an +associated session. +Conversely, it is also unsupported to associate to a terminal when +the session is already associated with a different terminal. +.Sh ERRORS +If an error occurs, +.Fn tcsetsid +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 file descriptor represented by +.Fa fd +is not a terminal. +.It Bq Er EINVAL +The +.Fa pid +argument is not equal to the session ID of the calling process. +.It Bq Er EPERM +The calling process is not a session leader. +.It Bq Er EPERM +The session already has an associated terminal or the terminal already +has an associated session. +.El +.Sh SEE ALSO +.Xr getsid 2 , +.Xr setsid 2 , +.Xr tcgetpgrp 3 , +.Xr tcgetsid 3 +.Sh HISTORY +A +.Fn tcsetsid +function first appeared in QNX. +It does not comply to any standard. diff --git a/lib/libc/gen/time.3 b/lib/libc/gen/time.3 new file mode 100644 index 0000000..f494079 --- /dev/null +++ b/lib/libc/gen/time.3 @@ -0,0 +1,101 @@ +.\" 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 +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)time.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/time.3 201201 2009-12-29 14:29:08Z kib $ +.\" +.Dd July 18, 2003 +.Dt TIME 3 +.Os +.Sh NAME +.Nm time +.Nd get time of day +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In time.h +.Ft time_t +.Fn time "time_t *tloc" +.Sh DESCRIPTION +The +.Fn time +function +returns the value of time in seconds since 0 hours, 0 minutes, +0 seconds, January 1, 1970, Coordinated Universal Time. +If an error occurs, +.Fn time +returns the value +.Po Vt time_t Pc Ns \-1 . +.Pp +The return value is also stored in +.No \&* Ns Va tloc , +provided that +.Va tloc +is non-null. +.Sh ERRORS +The +.Fn time +function may fail for any of the reasons described in +.Xr gettimeofday 2 . +.Sh SEE ALSO +.Xr clock_gettime 2 , +.Xr gettimeofday 2 , +.Xr ctime 3 +.Sh STANDARDS +The +.Nm +function conforms to +.St -p1003.1-2001 . +.Sh HISTORY +A +.Fn time +function appeared in +.At v6 . +.Sh BUGS +Neither +.St -isoC-99 +nor +.St -p1003.1-2001 +requires +.Fn time +to set +.Va errno +on failure; thus, it is impossible for an application to distinguish +the valid time value \-1 (representing the last UTC second of 1969) +from the error return value. +.Pp +Systems conforming to earlier versions of the C and +.Tn POSIX +standards (including older versions of +.Fx ) +did not set +.No \&* Ns Va tloc +in the error case. diff --git a/lib/libc/gen/times.3 b/lib/libc/gen/times.3 new file mode 100644 index 0000000..9230f8e --- /dev/null +++ b/lib/libc/gen/times.3 @@ -0,0 +1,145 @@ +.\" Copyright (c) 1990, 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. +.\" 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. +.\" +.\" @(#)times.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/times.3 185519 2008-12-01 15:27:00Z keramida $ +.\" +.Dd December 1, 2008 +.Dt TIMES 3 +.Os +.Sh NAME +.Nm times +.Nd process times +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/times.h +.Ft clock_t +.Fn times "struct tms *tp" +.Sh DESCRIPTION +.Bf -symbolic +This interface is obsoleted by +.Xr getrusage 2 +and +.Xr gettimeofday 2 . +.Ef +.Pp +The +.Fn times +function returns the value of time in +.Dv CLK_TCK Ns 's +of a second since the system startup time. +The current value of +.Dv CLK_TCK , +the frequency of the statistics clock in ticks per second, may be +obtained through the +.Xr sysconf 3 +interface. +.Pp +It also fills in the structure pointed to by +.Fa tp +with time-accounting information. +.Pp +The +.Vt tms +structure is defined as follows: +.Bd -literal -offset indent +struct tms { + clock_t tms_utime; + clock_t tms_stime; + clock_t tms_cutime; + clock_t tms_cstime; +}; +.Ed +.Pp +The elements of this structure are defined as follows: +.Bl -tag -width ".Va tms_cutime" +.It Va tms_utime +The +.Tn CPU +time charged for the execution of user instructions. +.It Va tms_stime +The +.Tn CPU +time charged for execution by the system on behalf of +the process. +.It Va tms_cutime +The sum of the +.Va tms_utime Ns s +and +.Va tms_cutime Ns s +of the child processes. +.It Va tms_cstime +The sum of the +.Fa tms_stime Ns s +and +.Fa tms_cstime Ns s +of the child processes. +.El +.Pp +All times are in +.Dv CLK_TCK Ns 's +of a second. +.Pp +The times of a terminated child process are included in the +.Va tms_cutime +and +.Va tms_cstime +elements of the parent when one of the +.Xr wait 2 +functions returns the process ID of the terminated child to the parent. +If an error occurs, +.Fn times +returns the value +.Pq Po Vt clock_t Pc Ns \-1 , +and sets +.Va errno +to indicate the error. +.Sh ERRORS +The +.Fn times +function +may fail and set the global variable +.Va errno +for any of the errors specified for the library +routines +.Xr getrusage 2 +and +.Xr gettimeofday 2 . +.Sh SEE ALSO +.Xr time 1 , +.Xr getrusage 2 , +.Xr gettimeofday 2 , +.Xr wait 2 , +.Xr sysconf 3 , +.Xr clocks 7 +.Sh STANDARDS +The +.Fn times +function +conforms to +.St -p1003.1-88 . diff --git a/lib/libc/gen/timezone.3 b/lib/libc/gen/timezone.3 new file mode 100644 index 0000000..5324b67 --- /dev/null +++ b/lib/libc/gen/timezone.3 @@ -0,0 +1,69 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)timezone.3 8.2 (Berkeley) 4/19/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/timezone.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 19, 1994 +.Dt TIMEZONE 3 +.Os +.Sh NAME +.Nm timezone +.Nd return the timezone abbreviation +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.Ft char * +.Fn timezone "int zone" "int dst" +.Sh DESCRIPTION +.Bf Sy +This interface is for compatibility only; it is impossible to reliably +map timezone's arguments to a time zone abbreviation. +See +.Xr ctime 3 . +.Ef +.Pp +The +.Fn timezone +function returns a pointer to a time zone abbreviation for the specified +.Fa zone +and +.Fa dst +values. +The +.Fa zone +argument +is the number of minutes west of GMT and +.Fa dst +is non-zero if daylight savings time is in effect. +.Sh SEE ALSO +.Xr ctime 3 +.Sh HISTORY +A +.Fn timezone +function appeared in +.At v7 . diff --git a/lib/libc/gen/trivial-getcontextx.c b/lib/libc/gen/trivial-getcontextx.c new file mode 100644 index 0000000..982fc7c --- /dev/null +++ b/lib/libc/gen/trivial-getcontextx.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2011 Konstantin Belousov + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/trivial-getcontextx.c 277078 2015-01-12 18:13:38Z emaste $"); + +#include +#include +#include +#include + +int +__getcontextx_size(void) +{ + + return (sizeof(ucontext_t)); +} + +int +__fillcontextx2(char *ctx) +{ + + return (0); +} + +int +__fillcontextx(char *ctx) +{ + ucontext_t *ucp; + + ucp = (ucontext_t *)ctx; + return (getcontext(ucp)); +} + +__weak_reference(__getcontextx, getcontextx); + +ucontext_t * +__getcontextx(void) +{ + char *ctx; + int error; + + ctx = malloc(__getcontextx_size()); + if (ctx == NULL) + return (NULL); + if (__fillcontextx(ctx) == -1) { + error = errno; + free(ctx); + errno = error; + return (NULL); + } + return ((ucontext_t *)ctx); +} diff --git a/lib/libc/gen/ttyname.3 b/lib/libc/gen/ttyname.3 new file mode 100644 index 0000000..08f45e4 --- /dev/null +++ b/lib/libc/gen/ttyname.3 @@ -0,0 +1,140 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)ttyname.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/ttyname.3 268857 2014-07-18 21:29:59Z jilles $ +.\" +.Dd July 18, 2014 +.Dt TTYNAME 3 +.Os +.Sh NAME +.Nm ttyname , +.Nm ttyname_r , +.Nm isatty +.Nd get name of associated terminal (tty) from file descriptor +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft char * +.Fn ttyname "int fd" +.Ft int +.Fn ttyname_r "int fd" "char *buf" "size_t len" +.Ft int +.Fn isatty "int fd" +.Sh DESCRIPTION +These functions operate on file descriptors for terminal type devices. +.Pp +The +.Fn isatty +function +determines if the file descriptor +.Fa fd +refers to a valid +terminal type device. +.Pp +The +.Fn ttyname +function +gets the related device name of +a file descriptor for which +.Fn isatty +is true. +.Pp +The +.Fn ttyname +function +returns the name stored in a static buffer which will be overwritten +on subsequent calls. +The +.Fn ttyname_r +function +takes a buffer and length as arguments to avoid this problem. +.Sh RETURN VALUES +The +.Fn isatty +function returns 1 if +.Fa fd +refers to a terminal type device; +otherwise, it returns 0 and may set +.Va errno +to indicate the error. +The +.Fn ttyname +function +returns the null terminated name if the device is found and +.Fn isatty +is true; otherwise +a +.Dv NULL +pointer is returned. +The +.Fn ttyname_r +function returns 0 if successful. +Otherwise an error number is returned. +.Sh ERRORS +These functions may fail if: +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa fd +argument +is not a valid file descriptor. +.It Bq Er ENOTTY +The file associated with +.Fa fd +is not a terminal. +.El +.Pp +Additionally, +.Fn ttyname_r +may fail if: +.Bl -tag -width Er +.It Bq Er ERANGE +The +.Fa bufsize +argument +is smaller than the length of the string to be returned. +.El +.Sh SEE ALSO +.Xr fdevname 3 , +.Xr ptsname 3 , +.Xr tcgetattr 3 , +.Xr tty 4 +.Sh HISTORY +The +.Fn isatty +and +.Fn ttyname +functions +appeared in +.At v7 . +The +.Fn ttyname_r +function +appeared in +.Fx 6.0 . diff --git a/lib/libc/gen/tzset.3 b/lib/libc/gen/tzset.3 new file mode 100644 index 0000000..ff54dd8 --- /dev/null +++ b/lib/libc/gen/tzset.3 @@ -0,0 +1,338 @@ +.\" 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 +.\" Arthur Olson. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)tzset.3 8.2 (Berkeley) 11/17/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/tzset.3 199405 2009-11-17 16:29:39Z obrien $ +.\" +.Dd November 17, 1993 +.Dt TZSET 3 +.Os +.Sh NAME +.Nm tzset , +.Nm tzsetwall +.Nd initialize time conversion information +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In time.h +.Ft void +.Fn tzset void +.Ft void +.Fn tzsetwall void +.Sh DESCRIPTION +The +.Fn tzset +function +initializes time conversion information used by the library routine +.Xr localtime 3 . +The environment variable +.Ev TZ +specifies how this is done. +.Pp +If +.Ev TZ +does not appear in the environment, the best available approximation to +local wall clock time, as specified by the +.Xr tzfile 5 Ns -format +file +.Pa /etc/localtime +is used. +.Pp +If +.Ev TZ +appears in the environment but its value is a null string, Coordinated +Universal Time +.Pq Tn UTC +is used (without leap second correction). +.Pp +If +.Ev TZ +appears in the environment and its value begins with a colon +.Pq Ql \&: , +the rest of its value is used as a pathname of a +.Xr tzfile 5 Ns -format +file from which to read the time conversion information. +If the first character of the pathname is a slash +.Pq Ql / +it is used as +an absolute pathname; otherwise, it is used as a pathname relative to +the system time conversion information directory. +.Pp +If its value does not begin with a colon, it is first used as the pathname +of a file (as described above) from which to read the time conversion +information. +If that file cannot be read, the value is then interpreted as a direct +specification (the format is described below) of the time conversion +information. +.Pp +If the +.Ev TZ +environment variable does not specify a +.Xr tzfile 5 Ns -format +file and cannot be interpreted as a direct specification, +.Tn UTC +is used. +.Pp +The +.Fn tzsetwall +function +sets things up so that +.Xr localtime 3 +returns the best available approximation of local wall clock time. +.Sh SPECIFICATION FORMAT +When +.Ev TZ +is used directly as a specification of the time conversion information, +it must have the following syntax (spaces inserted for clarity): +.Bd -ragged -offset indent +.Em std offset +.Bo +.Em dst +.Bq Em offset +.Bq , Em rule +.Bc +.Ed +.Pp +Where: +.Bl -tag -width std_and_dst -offset indent +.It Em std No and Em dst +Three or more bytes that are the designation for the standard +.Pq Em std +or summer +.Pq Em dst +time zone. +Only +.Em std +is required; if +.Em dst +is missing, then summer time does not apply in this locale. +Upper and lowercase letters are explicitly allowed. +Any characters +except a leading colon +.Pq Ql \&: , +digits, comma +.Pq Ql \&, , +minus +.Pq Ql \- , +plus +.Pq Ql + , +and +.Tn ASCII +.Dv NUL +are allowed. +.It Em offset +Indicates the value one must add to the local time to arrive at +Coordinated Universal Time. +The +.Em offset +has the form: +.Bd -ragged -offset indent +.Sm off +.Em hh Bo +.Em : mm +.Bq Em : ss +.Bc +.Sm on +.Ed +.Pp +The minutes +.Pq Em mm +and seconds +.Pq Em ss +are optional. +The hour +.Pq Em hh +is required and may be a single digit. +The +.Em offset +following +.Em std +is required. +If no +.Em offset +follows +.Em dst , +summer time is assumed to be one hour ahead of standard time. +One or +more digits may be used; the value is always interpreted as a decimal +number. +The hour must be between zero and 24, and the minutes (and +seconds) \(em if present \(em between zero and 59. +If preceded by a +.Pq Ql \- +the time zone shall be east of the Prime Meridian; otherwise it shall be +west (which may be indicated by an optional preceding +.Pq Ql + ) . +.It Em rule +Indicates when to change to and back from summer time. +The +.Em rule +has the form: +.Bd -ragged -offset indent +.Em date/time,date/time +.Ed +.Pp +where the first +.Em date +describes when the change from standard to summer time occurs and the +second +.Em date +describes when the change back happens. +Each +.Em time +field describes when, in current local time, the change to the other +time is made. +.Pp +The format of +.Em date +is one of the following: +.Bl -tag -width "M.m.n.d" +.It Sy J Em n +The Julian day +.Em n +(1 \*(Le +.Em n +\*(Le 365). +Leap days are not counted; that is, in all years \(em including leap +years \(em February 28 is day 59 and March 1 is day 60. +It is +impossible to explicitly refer to the occasional February 29. +.It Em n +The zero-based Julian day +(0 \*(Le +.Em n +\*(Le 365 ) . +Leap days are counted, and it is possible to refer to February 29. +.It Sy M Em m.n.d +The +.Em d Ns 'th +day (0 \*(Le +.Em d +\*(Le 6) +of week +.Em n +of month +.Em m +of the year +(1 \*(Le +.Em n +\*(Le 5), +(1 \*(Le +.Em m +\*(Le 12), +where week 5 means +.Do +the last +.Em d +day in month +.Em m +.Dc +which may occur in either the fourth or the fifth week). +Week 1 is the +first week in which the +.Em d Ns 'th +day occurs. +Day zero is Sunday. +.Pp +The +.Em time +has the same format as +.Em offset +except that no leading sign +.Pq Ql \- +or +.Pq Ql + +is allowed. +The default, if +.Em time +is not given, is +.Sy 02:00:00 . +.El +.Pp +If no +.Em rule +is present in the +.Ev TZ +specification, the rules specified +by the +.Xr tzfile 5 Ns -format +file +.Em posixrules +in the system time conversion information directory are used, with the +standard and summer time offsets from +.Tn UTC +replaced by those specified by +the +.Em offset +values in +.Ev TZ . +.El +.Pp +For compatibility with System V Release 3.1, a semicolon +.Pq Ql \&; +may be used to separate the +.Em rule +from the rest of the specification. +.Sh FILES +.Bl -tag -width /usr/share/zoneinfo/posixrules -compact +.It Pa /etc/localtime +local time zone file +.It Pa /usr/share/zoneinfo +time zone directory +.It Pa /usr/share/zoneinfo/posixrules +rules for +.Tn POSIX Ns -style +.Tn TZ Ns 's +.It Pa /usr/share/zoneinfo/Etc/GMT +for +.Tn UTC +leap seconds +.El +.Pp +If the file +.Pa /usr/share/zoneinfo/UTC +does not exist, +.Tn UTC +leap seconds are loaded from +.Pa /usr/share/zoneinfo/posixrules . +.Sh SEE ALSO +.Xr date 1 , +.Xr gettimeofday 2 , +.Xr ctime 3 , +.Xr getenv 3 , +.Xr time 3 , +.Xr tzfile 5 +.Sh HISTORY +The +.Fn tzset +and +.Fn tzsetwall +functions first appeared in +.Bx 4.4 . diff --git a/lib/libc/gen/ualarm.3 b/lib/libc/gen/ualarm.3 new file mode 100644 index 0000000..819cd48 --- /dev/null +++ b/lib/libc/gen/ualarm.3 @@ -0,0 +1,97 @@ +.\" Copyright (c) 1986, 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. +.\" 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. +.\" +.\" From: @(#)ualarm.3 8.2 (Berkeley) 4/19/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/ualarm.3 207735 2010-05-06 22:49:54Z jilles $ +.\" +.Dd April 19, 1994 +.Dt UALARM 3 +.Os +.Sh NAME +.Nm ualarm +.Nd schedule signal after specified time +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft useconds_t +.Fn ualarm "useconds_t microseconds" "useconds_t interval" +.Sh DESCRIPTION +.Bf -symbolic +This is a simplified interface to +.Xr setitimer 2 . +.Ef +.Pp +The +.Fn ualarm +function +waits a count of +.Fa microseconds +before asserting the terminating signal +.Dv SIGALRM . +System activity or time used in processing the call may cause a slight +delay. +.Pp +If the +.Fa interval +argument is non-zero, the +.Dv SIGALRM +signal will be sent +to the process every +.Fa interval +microseconds after the timer expires (e.g.\& after +.Fa microseconds +number of microseconds have passed). +.Pp +Due to +.Xr setitimer 2 +restriction the maximum number of +.Fa microseconds +and +.Fa interval +is limited to 100000000000000 +(in case this value fits in the unsigned integer). +.Sh RETURN VALUES +When the signal has successfully been caught, +.Fn ualarm +returns the amount of time left on the clock. +.Sh NOTES +A microsecond is 0.000001 seconds. +.Sh SEE ALSO +.Xr getitimer 2 , +.Xr setitimer 2 , +.Xr sigaction 2 , +.Xr sigsuspend 2 , +.Xr alarm 3 , +.Xr signal 3 , +.Xr sleep 3 , +.Xr usleep 3 +.Sh HISTORY +The +.Fn ualarm +function appeared in +.Bx 4.3 . diff --git a/lib/libc/gen/ucontext.3 b/lib/libc/gen/ucontext.3 new file mode 100644 index 0000000..8fde73f --- /dev/null +++ b/lib/libc/gen/ucontext.3 @@ -0,0 +1,111 @@ +.\" Copyright (c) 2002 Packet Design, LLC. +.\" All rights reserved. +.\" +.\" Subject to the following obligations and disclaimer of warranty, +.\" use and redistribution of this software, in source or object code +.\" forms, with or without modifications are expressly permitted by +.\" Packet Design; provided, however, that: +.\" +.\" (i) Any and all reproductions of the source or object code +.\" must include the copyright notice above and the following +.\" disclaimer of warranties; and +.\" (ii) No rights are granted, in any manner or form, to use +.\" Packet Design trademarks, including the mark "PACKET DESIGN" +.\" on advertising, endorsements, or otherwise except as such +.\" appears in the above copyright notice or in the software. +.\" +.\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND +.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO +.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING +.\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED +.\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, +.\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE, +.\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS +.\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, +.\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE +.\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE +.\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL +.\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF +.\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 PACKET DESIGN IS ADVISED OF +.\" THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/ucontext.3 230429 2012-01-21 18:00:28Z kib $ +.\" +.Dd September 10, 2002 +.Dt UCONTEXT 3 +.Os +.Sh NAME +.Nm ucontext +.Nd user thread context +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ucontext.h +.Sh DESCRIPTION +The +.Vt ucontext_t +type is a structure type suitable for holding the context for a user +thread of execution. +A thread's context includes its stack, saved registers, and list of +blocked signals. +.Pp +The +.Vt ucontext_t +structure contains at least these fields: +.Pp +.Bl -tag -width ".Va mcontext_t\ \ uc_mcontext" -offset 3n -compact +.It Va "ucontext_t *uc_link" +context to assume when this one returns +.It Va "sigset_t uc_sigmask" +signals being blocked +.It Va "stack_t uc_stack" +stack area +.It Va "mcontext_t uc_mcontext" +saved registers +.El +.Pp +The +.Va uc_link +field points to the context to resume when this context's entry point +function returns. +If +.Va uc_link +is equal to +.Dv NULL , +then the process exits when this context returns. +.Pp +The +.Va uc_mcontext +field is machine-dependent and should be treated as opaque by +portable applications. +.Pp +The following functions are defined to manipulate +.Vt ucontext_t +structures: +.Pp +.Bl -item -offset 3n -compact +.It +.Ft int +.Fn getcontext "ucontext_t *" ; +.It +.Ft "ucontext_t *" +.Fn getcontextx "void" ; +.It +.Ft int +.Fn setcontext "const ucontext_t *" ; +.It +.Ft void +.Fn makecontext "ucontext_t *" "void \*[lp]*\*[rp]\*[lp]void\*[rp]" int ... ; +.It +.Ft int +.Fn swapcontext "ucontext_t *" "const ucontext_t *" ; +.El +.Sh SEE ALSO +.Xr sigaltstack 2 , +.Xr getcontext 3 , +.Xr getcontextx 3 , +.Xr makecontext 3 diff --git a/lib/libc/gen/ulimit.3 b/lib/libc/gen/ulimit.3 new file mode 100644 index 0000000..888d6c8 --- /dev/null +++ b/lib/libc/gen/ulimit.3 @@ -0,0 +1,98 @@ +.\" Copyright (c) 2002 Kyle Martin. 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/ulimit.3 108637 2003-01-04 01:11:49Z tjr $ +.\" +.Dd January 4, 2003 +.Dt ULIMIT 3 +.Os +.Sh NAME +.Nm ulimit +.Nd get and set process limits +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ulimit.h +.Ft long +.Fn ulimit "int cmd" "..." +.Sh DESCRIPTION +The +.Fn ulimit +function will get and set process limits. +Currently this is limited to the maximum file size. +The +.Fa cmd +argument is one of the following: +.Bl -tag -width ".Dv UL_GETFSIZE" +.It Dv UL_GETFSIZE +will return the maximum file size in units of 512 blocks of +the current process. +.It Dv UL_SETFSIZE +will attempt to set the maximum file size of the current +process and its children with the second argument expressed as a long. +.El +.Sh RETURN VALUES +Upon successful completion, +.Fn ulimit +returns the value requested; +otherwise the value \-1 is returned and the global variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The +.Fn ulimit +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The command specified was invalid. +.It Bq Er EPERM +The limit specified to +.Fn ulimit +would have raised the maximum limit value, +and the caller is not the super-user. +.El +.Sh SEE ALSO +.Xr getrlimit 2 +.Sh STANDARDS +The +.Fn ulimit +function conforms to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn ulimit +function first appeared in +.Fx 5.0 . +.Sh BUGS +The +.Fn ulimit +function provides limited precision for +setting and retrieving process limits. +If there is a need for greater precision than the +type +.Vt long +provides, the +.Xr getrlimit 2 +and +.Xr setrlimit 2 +functions should be considered. diff --git a/lib/libc/gen/uname.3 b/lib/libc/gen/uname.3 new file mode 100644 index 0000000..1781da0 --- /dev/null +++ b/lib/libc/gen/uname.3 @@ -0,0 +1,117 @@ +.\" Copyright (c) 1994 +.\" 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. +.\" 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. +.\" +.\" @(#)uname.3 8.1 (Berkeley) 1/4/94 +.\" $FreeBSD: releng/11.1/lib/libc/gen/uname.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd December 2, 2005 +.Dt UNAME 3 +.Os +.Sh NAME +.Nm uname +.Nd get system identification +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/utsname.h +.Ft int +.Fn uname "struct utsname *name" +.Sh DESCRIPTION +The +.Fn uname +function stores +.Dv NUL Ns -terminated +strings of information identifying +the current system into the structure referenced by +.Fa name . +.Pp +The +.Vt utsname +structure is defined in the +.In sys/utsname.h +header file, and contains the following members: +.Bl -tag -width nodenameXXXX -offset indent +.It sysname +Name of the operating system implementation. +.It nodename +Network name of this machine. +.It release +Release level of the operating system. +.It version +Version level of the operating system. +.It machine +Machine hardware platform. +.El +.Sh RETURN VALUES +.Rv -std uname +.Sh ENVIRONMENT +.Bl -tag -width ".Ev UNAME_s" +.It Ev UNAME_s +If the environment variable +.Ev UNAME_s +is set, it will override the +.Va sysname +member. +.It Ev UNAME_r +If the environment variable +.Ev UNAME_r +is set, it will override the +.Va release +member. +.It Ev UNAME_v +If the environment variable +.Ev UNAME_v +is set, it will override the +.Va version +member. +.It Ev UNAME_m +If the environment variable +.Ev UNAME_m +is set, it will override the +.Va machine +member. +.El +.Sh ERRORS +The +.Fn uname +function may fail and set +.Va errno +for any of the errors specified for the library functions +.Xr sysctl 3 . +.Sh SEE ALSO +.Xr uname 1 , +.Xr sysctl 3 +.Sh STANDARDS +The +.Fn uname +function conforms to +.St -p1003.1-88 . +.Sh HISTORY +The +.Fn uname +function first appeared in +.Bx 4.4 . diff --git a/lib/libc/gen/unvis-compat.c b/lib/libc/gen/unvis-compat.c new file mode 100644 index 0000000..20f9ce7 --- /dev/null +++ b/lib/libc/gen/unvis-compat.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2012 SRI International + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/gen/unvis-compat.c 288029 2015-09-20 20:23:16Z rodrigc $ + */ + +#include + +#define _UNVIS_END 1 + +int __unvis_44bsd(char *, int, int *, int); + +int +__unvis_44bsd(char *cp, int c, int *astate, int flag) +{ + + if (flag & _UNVIS_END) + flag = (flag & ~_UNVIS_END) ^ UNVIS_END; + return unvis(cp, c, astate, flag); +} + +__sym_compat(unvis, __vis_44bsd, FBSD_1.0); diff --git a/lib/libc/gen/usleep.3 b/lib/libc/gen/usleep.3 new file mode 100644 index 0000000..93419e5 --- /dev/null +++ b/lib/libc/gen/usleep.3 @@ -0,0 +1,80 @@ +.\" Copyright (c) 1986, 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. +.\" 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. +.\" +.\" @(#)usleep.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/usleep.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd February 13, 1998 +.Dt USLEEP 3 +.Os +.Sh NAME +.Nm usleep +.Nd suspend process execution for an interval measured in microseconds +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn usleep "useconds_t microseconds" +.Sh DESCRIPTION +The +.Fn usleep +function suspends execution of the calling process until either +.Fa microseconds +microseconds have elapsed or a signal is delivered to the process and its +action is to invoke a signal-catching function or to terminate the +process. +System activity may lengthen the sleep by an indeterminate amount. +.Pp +This function is implemented using +.Xr nanosleep 2 +by pausing for +.Fa microseconds +microseconds or until a signal occurs. +Consequently, in this implementation, +sleeping has no effect on the state of process timers, +and there is no special handling for SIGALRM. +.Sh RETURN VALUES +.Rv -std usleep +.Sh ERRORS +The +.Fn usleep +function +will fail if: +.Bl -tag -width Er +.It Bq Er EINTR +A signal was delivered to the process and its +action was to invoke a signal-catching function. +.El +.Sh SEE ALSO +.Xr nanosleep 2 , +.Xr sleep 3 +.Sh HISTORY +The +.Fn usleep +function appeared in +.Bx 4.3 . diff --git a/lib/libc/gen/utime.3 b/lib/libc/gen/utime.3 new file mode 100644 index 0000000..6bec735 --- /dev/null +++ b/lib/libc/gen/utime.3 @@ -0,0 +1,94 @@ +.\" Copyright (c) 1980, 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. +.\" 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. +.\" +.\" @(#)utime.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/utime.3 301768 2016-06-09 22:14:58Z jilles $ +.\" +.Dd June 9, 2016 +.Dt UTIME 3 +.Os +.Sh NAME +.Nm utime +.Nd set file times +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In utime.h +.Ft int +.Fn utime "const char *file" "const struct utimbuf *timep" +.Sh DESCRIPTION +.Bf -symbolic +This interface is obsoleted by +.Xr utimensat 2 +because it is not accurate to fractions of a second. +.Ef +.Pp +The +.Fn utime +function sets the access and modification times of the named file from +the +.Va actime +and +.Va modtime +fields of the +.Vt "struct utimbuf" +pointed at by +.Fa timep . +.Pp +If the times are specified (the +.Fa timep +argument is +.Pf non- Dv NULL ) +the caller must be the owner of the file or be the super-user. +.Pp +If the times are not specified (the +.Fa timep +argument is +.Dv NULL ) +the caller must be the owner of the file, have permission to write +the file, or be the super-user. +.Sh ERRORS +The +.Fn utime +function may fail and set +.Va errno +for any of the errors specified for the library function +.Xr utimes 2 . +.Sh SEE ALSO +.Xr stat 2 , +.Xr utimensat 2 , +.Xr utimes 2 +.Sh STANDARDS +The +.Fn utime +function conforms to +.St -p1003.1-88 . +.Sh HISTORY +A +.Fn utime +function appeared in +.At v7 . diff --git a/lib/libc/gen/utxdb.c b/lib/libc/gen/utxdb.c new file mode 100644 index 0000000..fcb58d7 --- /dev/null +++ b/lib/libc/gen/utxdb.c @@ -0,0 +1,179 @@ +/*- + * Copyright (c) 2010 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/utxdb.c 233345 2012-03-23 08:26:31Z ed $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include "utxdb.h" +#include "un-namespace.h" + +#define UTOF_STRING(ut, fu, field) do { \ + strncpy((fu)->fu_ ## field, (ut)->ut_ ## field, \ + MIN(sizeof (fu)->fu_ ## field, sizeof (ut)->ut_ ## field)); \ +} while (0) +#define UTOF_ID(ut, fu) do { \ + memcpy((fu)->fu_id, (ut)->ut_id, \ + MIN(sizeof (fu)->fu_id, sizeof (ut)->ut_id)); \ +} while (0) +#define UTOF_PID(ut, fu) do { \ + (fu)->fu_pid = htobe32((ut)->ut_pid); \ +} while (0) +#define UTOF_TYPE(ut, fu) do { \ + (fu)->fu_type = (ut)->ut_type; \ +} while (0) +#define UTOF_TV(fu) do { \ + struct timeval tv; \ + gettimeofday(&tv, NULL); \ + (fu)->fu_tv = htobe64((uint64_t)tv.tv_sec * 1000000 + \ + (uint64_t)tv.tv_usec); \ +} while (0) + +void +utx_to_futx(const struct utmpx *ut, struct futx *fu) +{ + + memset(fu, 0, sizeof *fu); + + switch (ut->ut_type) { + case BOOT_TIME: + case OLD_TIME: + case NEW_TIME: + /* Extension: shutdown time. */ + case SHUTDOWN_TIME: + break; + case USER_PROCESS: + UTOF_ID(ut, fu); + UTOF_STRING(ut, fu, user); + UTOF_STRING(ut, fu, line); + /* Extension: host name. */ + UTOF_STRING(ut, fu, host); + UTOF_PID(ut, fu); + break; + case INIT_PROCESS: + UTOF_ID(ut, fu); + UTOF_PID(ut, fu); + break; + case LOGIN_PROCESS: + UTOF_ID(ut, fu); + UTOF_STRING(ut, fu, user); + UTOF_STRING(ut, fu, line); + UTOF_PID(ut, fu); + break; + case DEAD_PROCESS: + UTOF_ID(ut, fu); + UTOF_PID(ut, fu); + break; + default: + fu->fu_type = EMPTY; + return; + } + + UTOF_TYPE(ut, fu); + UTOF_TV(fu); +} + +#define FTOU_STRING(fu, ut, field) do { \ + strncpy((ut)->ut_ ## field, (fu)->fu_ ## field, \ + MIN(sizeof (ut)->ut_ ## field - 1, sizeof (fu)->fu_ ## field)); \ +} while (0) +#define FTOU_ID(fu, ut) do { \ + memcpy((ut)->ut_id, (fu)->fu_id, \ + MIN(sizeof (ut)->ut_id, sizeof (fu)->fu_id)); \ +} while (0) +#define FTOU_PID(fu, ut) do { \ + (ut)->ut_pid = be32toh((fu)->fu_pid); \ +} while (0) +#define FTOU_TYPE(fu, ut) do { \ + (ut)->ut_type = (fu)->fu_type; \ +} while (0) +#define FTOU_TV(fu, ut) do { \ + uint64_t t; \ + t = be64toh((fu)->fu_tv); \ + (ut)->ut_tv.tv_sec = t / 1000000; \ + (ut)->ut_tv.tv_usec = t % 1000000; \ +} while (0) + +struct utmpx * +futx_to_utx(const struct futx *fu) +{ +#ifdef __NO_TLS + static struct utmpx *ut; +#else + static _Thread_local struct utmpx *ut; +#endif + + if (ut == NULL) { + ut = calloc(1, sizeof *ut); + if (ut == NULL) + return (NULL); + } else + memset(ut, 0, sizeof *ut); + + switch (fu->fu_type) { + case BOOT_TIME: + case OLD_TIME: + case NEW_TIME: + /* Extension: shutdown time. */ + case SHUTDOWN_TIME: + break; + case USER_PROCESS: + FTOU_ID(fu, ut); + FTOU_STRING(fu, ut, user); + FTOU_STRING(fu, ut, line); + /* Extension: host name. */ + FTOU_STRING(fu, ut, host); + FTOU_PID(fu, ut); + break; + case INIT_PROCESS: + FTOU_ID(fu, ut); + FTOU_PID(fu, ut); + break; + case LOGIN_PROCESS: + FTOU_ID(fu, ut); + FTOU_STRING(fu, ut, user); + FTOU_STRING(fu, ut, line); + FTOU_PID(fu, ut); + break; + case DEAD_PROCESS: + FTOU_ID(fu, ut); + FTOU_PID(fu, ut); + break; + default: + ut->ut_type = EMPTY; + return (ut); + } + + FTOU_TYPE(fu, ut); + FTOU_TV(fu, ut); + return (ut); +} diff --git a/lib/libc/gen/utxdb.h b/lib/libc/gen/utxdb.h new file mode 100644 index 0000000..99b06d8 --- /dev/null +++ b/lib/libc/gen/utxdb.h @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2010 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/gen/utxdb.h 202530 2010-01-17 21:40:05Z ed $ + */ + +#ifndef _UTXDB_H_ +#define _UTXDB_H_ + +#include + +#define _PATH_UTX_ACTIVE "/var/run/utx.active" +#define _PATH_UTX_LASTLOGIN "/var/log/utx.lastlogin" +#define _PATH_UTX_LOG "/var/log/utx.log" + +/* + * Entries in struct futx are ordered by how often they are used. In + * utx.log only entries will be written until the last non-zero byte, + * which means we want to put the hostname at the end. Most primitive + * records only store a ut_type and ut_tv, which means we want to store + * those at the front. + */ + +struct utmpx; + +struct futx { + uint8_t fu_type; + uint64_t fu_tv; + char fu_id[8]; + uint32_t fu_pid; + char fu_user[32]; + char fu_line[16]; + char fu_host[128]; +} __packed; + +void utx_to_futx(const struct utmpx *, struct futx *); +struct utmpx *futx_to_utx(const struct futx *); + +#endif /* !_UTXDB_H_ */ diff --git a/lib/libc/gen/valloc.3 b/lib/libc/gen/valloc.3 new file mode 100644 index 0000000..6c62f2b --- /dev/null +++ b/lib/libc/gen/valloc.3 @@ -0,0 +1,75 @@ +.\" Copyright (c) 1980, 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. +.\" 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. +.\" +.\" @(#)valloc.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gen/valloc.3 173182 2007-10-30 15:26:20Z keramida $ +.\" +.Dd October 30, 2007 +.Dt VALLOC 3 +.Os +.Sh NAME +.Nm valloc +.Nd aligned memory allocation function +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft void * +.Fn valloc "size_t size" +.Sh DESCRIPTION +The +.Fn valloc +function is obsoleted by +.Xr posix_memalign 3 , +which can be used to request page-aligned allocations. +.Pp +The +.Fn valloc +function +allocates +.Fa size +bytes aligned on a page boundary. +.Sh RETURN VALUES +The +.Fn valloc +function returns +a pointer to the allocated space if successful; otherwise +a null pointer is returned. +.Sh SEE ALSO +.Xr posix_memalign 3 +.Sh HISTORY +The +.Fn valloc +function appeared in +.Bx 3.0 . +.Pp +The +.Fn valloc +function correctly allocated memory that could be deallocated via +.Fn free +starting in +.Fx 7.0 . diff --git a/lib/libc/gen/waitid.c b/lib/libc/gen/waitid.c new file mode 100644 index 0000000..3075587 --- /dev/null +++ b/lib/libc/gen/waitid.c @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2012 Jukka A. Ukkonen + * All rights reserved. + * + * This software was developed by Jukka Ukkonen for FreeBSD. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/gen/waitid.c 288028 2015-09-20 20:21:49Z rodrigc $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "libc_private.h" + +int __waitid(idtype_t, id_t, siginfo_t *, int); + +int +__waitid(idtype_t idtype, id_t id, siginfo_t *info, int flags) +{ + int status; + pid_t ret; + + ret = ((pid_t (*)(idtype_t, id_t, int *, int, struct __wrusage *, + siginfo_t *))__libc_interposing[INTERPOS_wait6])(idtype, id, + &status, flags, NULL, info); + + /* + * According to SUSv4, waitid() shall not return a PID when a + * process is found, but only 0. If a process was actually + * found, siginfo_t fields si_signo and si_pid will be + * non-zero. In case WNOHANG was set in the flags and no + * process was found those fields are set to zero using + * memset() below. + */ + if (ret == 0 && info != NULL) + memset(info, 0, sizeof(*info)); + else if (ret > 0) + ret = 0; + return (ret); +} + +__weak_reference(__waitid, waitid); +__weak_reference(__waitid, _waitid); diff --git a/lib/libc/gen/wordexp.3 b/lib/libc/gen/wordexp.3 new file mode 100644 index 0000000..cd41883 --- /dev/null +++ b/lib/libc/gen/wordexp.3 @@ -0,0 +1,210 @@ +.\" +.\" Copyright (c) 2002 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/gen/wordexp.3 288430 2015-09-30 21:32:29Z jilles $ +.\" +.Dd September 30, 2015 +.Dt WORDEXP 3 +.Os +.Sh NAME +.Nm wordexp +.Nd "perform shell-style word expansions" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wordexp.h +.Ft int +.Fn wordexp "const char * restrict words" "wordexp_t * restrict we" "int flags" +.Ft void +.Fn wordfree "wordexp_t *we" +.Sh DESCRIPTION +The +.Fn wordexp +function performs shell-style word expansion on +.Fa words +and places the list of words into the +.Va we_wordv +member of +.Fa we , +and the number of words into +.Va we_wordc . +.Pp +The +.Fa flags +argument is the bitwise inclusive OR of any of the following constants: +.Bl -tag -width ".Dv WRDE_SHOWERR" +.It Dv WRDE_APPEND +Append the words to those generated by a previous call to +.Fn wordexp . +.It Dv WRDE_DOOFFS +As many +.Dv NULL +pointers as are specified by the +.Va we_offs +member of +.Fa we +are added to the front of +.Va we_wordv . +.It Dv WRDE_NOCMD +Disallow command substitution in +.Fa words . +See the note in +.Sx BUGS +before using this. +.It Dv WRDE_REUSE +The +.Fa we +argument was passed to a previous successful call to +.Fn wordexp +but has not been passed to +.Fn wordfree . +The implementation may reuse the space allocated to it. +.It Dv WRDE_SHOWERR +Do not redirect shell error messages to +.Pa /dev/null . +.It Dv WRDE_UNDEF +Report error on an attempt to expand an undefined shell variable. +.El +.Pp +The +.Vt wordexp_t +structure is defined in +.In wordexp.h +as: +.Bd -literal -offset indent +typedef struct { + size_t we_wordc; /* count of words matched */ + char **we_wordv; /* pointer to list of words */ + size_t we_offs; /* slots to reserve in we_wordv */ +} wordexp_t; +.Ed +.Pp +The +.Fn wordfree +function frees the memory allocated by +.Fn wordexp . +.Sh IMPLEMENTATION NOTES +The +.Fn wordexp +function is implemented using the undocumented +.Ic freebsd_wordexp +shell built-in command. +.Sh RETURN VALUES +The +.Fn wordexp +function returns zero if successful, otherwise it returns one of the following +error codes: +.Bl -tag -width ".Dv WRDE_NOSPACE" +.It Dv WRDE_BADCHAR +The +.Fa words +argument contains one of the following unquoted characters: +.Aq newline , +.Ql | , +.Ql & , +.Ql \&; , +.Ql < , +.Ql > , +.Ql \&( , +.Ql \&) , +.Ql { , +.Ql } . +.It Dv WRDE_BADVAL +An error after successful parsing, +such as an attempt to expand an undefined shell variable with +.Dv WRDE_UNDEF +set in +.Fa flags . +.It Dv WRDE_CMDSUB +An attempt was made to use command substitution and +.Dv WRDE_NOCMD +is set in +.Fa flags . +.It Dv WRDE_NOSPACE +Not enough memory to store the result or +an error during +.Xr fork 2 . +.It Dv WRDE_SYNTAX +Shell syntax error in +.Fa words . +.El +.Pp +The +.Fn wordfree +function returns no value. +.Sh ENVIRONMENT +.Bl -tag -width ".Ev IFS" +.It Ev IFS +Field separator. +.El +.Sh EXAMPLES +Invoke the editor on all +.Pa .c +files in the current directory +and +.Pa /etc/motd +(error checking omitted): +.Bd -literal -offset indent +wordexp_t we; + +wordexp("${EDITOR:-vi} *.c /etc/motd", &we, 0); +execvp(we.we_wordv[0], we.we_wordv); +.Ed +.Sh DIAGNOSTICS +Diagnostic messages from the shell are written to the standard error output +if +.Dv WRDE_SHOWERR +is set in +.Fa flags . +.Sh SEE ALSO +.Xr sh 1 , +.Xr fnmatch 3 , +.Xr glob 3 , +.Xr popen 3 , +.Xr system 3 +.Sh STANDARDS +The +.Fn wordexp +and +.Fn wordfree +functions conform to +.St -p1003.1-2001 . +.Sh BUGS +The current +.Fn wordexp +implementation does not recognize multibyte characters other than UTF-8, since +the shell (which it invokes to perform expansions) does not. +.Sh SECURITY CONSIDERATIONS +Pathname generation may create output that is exponentially larger than the +input size. +.Pp +Although this implementation detects command substitution reliably for +.Dv WRDE_NOCMD , +the attack surface remains fairly large. +Also, some other implementations +(such as older versions of this one) +may execute command substitutions even if +.Dv WRDE_NOCMD +is set. diff --git a/lib/libc/gmon/Makefile.inc b/lib/libc/gmon/Makefile.inc new file mode 100644 index 0000000..deb8a84 --- /dev/null +++ b/lib/libc/gmon/Makefile.inc @@ -0,0 +1,17 @@ +# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/gmon/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +# gmon sources +.PATH: ${LIBC_SRCTOP}/gmon + +SRCS+= gmon.c mcount.c + +SYM_MAPS+=${LIBC_SRCTOP}/gmon/Symbol.map + +MAN+= moncontrol.3 + +MLINKS+=moncontrol.3 monstartup.3 + +# mcount cannot be compiled with profiling +mcount.po: mcount.o + cp mcount.o mcount.po diff --git a/lib/libc/gmon/Symbol.map b/lib/libc/gmon/Symbol.map new file mode 100644 index 0000000..2ae56ee --- /dev/null +++ b/lib/libc/gmon/Symbol.map @@ -0,0 +1,14 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/gmon/Symbol.map 169525 2007-05-13 14:16:55Z deischen $ + */ + +FBSD_1.0 { + _mcleanup; + monstartup; + moncontrol; + mexitcount; +}; + +FBSDprivate_1.0 { + _gmonparam; +}; diff --git a/lib/libc/gmon/moncontrol.3 b/lib/libc/gmon/moncontrol.3 new file mode 100644 index 0000000..4b3c961 --- /dev/null +++ b/lib/libc/gmon/moncontrol.3 @@ -0,0 +1,117 @@ +.\" Copyright (c) 1980, 1991, 1992, 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. +.\" 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. +.\" +.\" @(#)moncontrol.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/gmon/moncontrol.3 235327 2012-05-12 07:52:45Z joel $ +.\" +.Dd June 14, 2004 +.Dt MONCONTROL 3 +.Os +.Sh NAME +.Nm moncontrol , +.Nm monstartup +.Nd control execution profile +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/gmon.h +.Ft void +.Fn moncontrol "int mode" +.Ft void +.Fn monstartup "u_long lowpc" "u_long highpc" +.Sh DESCRIPTION +An executable program compiled using the +.Fl pg +option to +.Xr cc 1 +automatically includes calls to collect statistics for the +.Xr gprof 1 +call-graph execution profiler. +In typical operation, profiling begins at program startup +and ends when the program calls exit. +When the program exits, the profiling data are written to the file +.Ar progname Ns Pa .gmon , +where progname is the name of the program, then +.Xr gprof 1 +can be used to examine the results. +.Pp +The +.Fn moncontrol +function +selectively controls profiling within a program. +When the program starts, profiling begins. +To stop the collection of histogram ticks and call counts use +.Fn moncontrol 0 ; +to resume the collection of histogram ticks and call counts use +.Fn moncontrol 1 . +This feature allows the cost of particular operations to be measured. +Note that an output file will be produced on program exit +regardless of the state of +.Fn moncontrol . +.Pp +Programs that are not loaded with +.Fl pg +may selectively collect profiling statistics by calling +.Fn monstartup +with the range of addresses to be profiled. +The +.Fa lowpc +and +.Fa highpc +arguments +specify the address range that is to be sampled; +the lowest address sampled is that of +.Fa lowpc +and the highest is just below +.Fa highpc . +Only functions in that range that have been compiled with the +.Fl pg +option to +.Xr cc 1 +will appear in the call graph part of the output; +however, all functions in that address range will +have their execution time measured. +Profiling begins on return from +.Fn monstartup . +.Sh ENVIRONMENT +The following environment variables affect the execution of +.Nm : +.Bl -tag -width ".Ev PROFIL_USE_PID" +.It PROFIL_USE_PID +If set, the pid of the process is inserted into the filename. +.El +.Sh FILES +.Bl -tag -width progname.gmon -compact +.It Pa progname.gmon +execution data file +.El +.Sh SEE ALSO +.Xr cc 1 , +.Xr gprof 1 , +.Xr profil 2 , +.Xr clocks 7 diff --git a/lib/libc/i386/Makefile.inc b/lib/libc/i386/Makefile.inc new file mode 100644 index 0000000..f1580ee --- /dev/null +++ b/lib/libc/i386/Makefile.inc @@ -0,0 +1,6 @@ +# $FreeBSD: releng/11.1/lib/libc/i386/Makefile.inc 315044 2017-03-11 02:51:29Z brooks $ + +# Long double is 80 bits +GDTOASRCS+=strtorx.c +SRCS+=machdep_ldisx.c +SYM_MAPS+=${LIBC_SRCTOP}/i386/Symbol.map diff --git a/lib/libc/i386/Symbol.map b/lib/libc/i386/Symbol.map new file mode 100644 index 0000000..40c2f4f --- /dev/null +++ b/lib/libc/i386/Symbol.map @@ -0,0 +1,67 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/i386/Symbol.map 297238 2016-03-24 18:47:19Z emaste $ + */ + +/* + * This only needs to contain symbols that are not listed in + * symbol maps from other parts of libc (i.e., not found in + * stdlib/Symbol.map, string/Symbol.map, sys/Symbol.map, ...). + */ +FBSD_1.0 { + /* PSEUDO syscalls */ + _exit; + + .mcount; + _setjmp; + _longjmp; + alloca; + fabs; + __flt_rounds; + __nan; + __infinity; + makecontext; + rfork_thread; + setjmp; + longjmp; + sigsetjmp; + siglongjmp; + htonl; + htons; + ntohl; + ntohs; + vfork; + brk; + exect; + i386_clr_watch; + i386_get_fsbase; + i386_get_gsbase; + i386_get_ioperm; + i386_get_ldt; + i386_set_fsbase; + i386_set_gsbase; + i386_set_ioperm; + i386_set_ldt; + i386_set_watch; + i386_vm86; + sbrk; + ___tls_get_addr; +}; + +FBSDprivate_1.0 { + /* PSEUDO syscalls */ + __sys_getlogin; + _getlogin; + __sys_exit; + + _set_tp; + ___longjmp; + __makecontext; + __longjmp; + __signalcontext; + signalcontext; + __siglongjmp; + __sys_vfork; + _vfork; + _end; + _brk; +}; diff --git a/lib/libc/i386/gd_qnan.h b/lib/libc/i386/gd_qnan.h new file mode 100644 index 0000000..f5f1209 --- /dev/null +++ b/lib/libc/i386/gd_qnan.h @@ -0,0 +1,21 @@ +/* + * MD header for contrib/gdtoa + * + * This file can be generated by compiling and running contrib/gdtoa/qnan.c + * on the target architecture after arith.h has been generated. + * + * $FreeBSD: releng/11.1/lib/libc/i386/gd_qnan.h 174680 2007-12-16 21:15:09Z das $ + */ + +#define f_QNAN 0x7fc00000 +#define d_QNAN0 0x0 +#define d_QNAN1 0x7ff80000 +#define ld_QNAN0 0x0 +#define ld_QNAN1 0xc0000000 +#define ld_QNAN2 0x7fff +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x0 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0xc000 +#define ldus_QNAN4 0x7fff diff --git a/lib/libc/i386/gen/Makefile.inc b/lib/libc/i386/gen/Makefile.inc new file mode 100644 index 0000000..e6b89e0 --- /dev/null +++ b/lib/libc/i386/gen/Makefile.inc @@ -0,0 +1,6 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/i386/gen/Makefile.inc 230429 2012-01-21 18:00:28Z kib $ + +SRCS+= _ctx_start.S _setjmp.S _set_tp.c fabs.S \ + flt_rounds.c getcontextx.c infinity.c ldexp.c makecontext.c \ + rfork_thread.S setjmp.S signalcontext.c sigsetjmp.S diff --git a/lib/libc/i386/gen/getcontextx.c b/lib/libc/i386/gen/getcontextx.c new file mode 100644 index 0000000..148191a --- /dev/null +++ b/lib/libc/i386/gen/getcontextx.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2011 Konstantin Belousov + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/i386/gen/getcontextx.c 251047 2013-05-28 04:54:16Z kib $"); + +#include +#include +#include +#include +#include +#include +#include +#include + +static int xstate_sz = -1; + +int +__getcontextx_size(void) +{ + u_int p[4]; + int cpuid_supported; + + if (xstate_sz == -1) { + __asm __volatile( + " pushfl\n" + " popl %%eax\n" + " movl %%eax,%%ecx\n" + " xorl $0x200000,%%eax\n" + " pushl %%eax\n" + " popfl\n" + " pushfl\n" + " popl %%eax\n" + " xorl %%eax,%%ecx\n" + " je 1f\n" + " movl $1,%0\n" + " jmp 2f\n" + "1: movl $0,%0\n" + "2:\n" + : "=r" (cpuid_supported) : : "eax", "ecx"); + if (cpuid_supported) { + __asm __volatile( + " pushl %%ebx\n" + " cpuid\n" + " movl %%ebx,%1\n" + " popl %%ebx\n" + : "=a" (p[0]), "=r" (p[1]), "=c" (p[2]), "=d" (p[3]) + : "0" (0x1)); + if ((p[2] & CPUID2_OSXSAVE) != 0) { + __asm __volatile( + " pushl %%ebx\n" + " cpuid\n" + " movl %%ebx,%1\n" + " popl %%ebx\n" + : "=a" (p[0]), "=r" (p[1]), "=c" (p[2]), + "=d" (p[3]) + : "0" (0xd), "2" (0x0)); + xstate_sz = p[1] - sizeof(struct savexmm); + } else + xstate_sz = 0; + } else + xstate_sz = 0; + } + + return (sizeof(ucontext_t) + xstate_sz); +} + +int +__fillcontextx2(char *ctx) +{ + struct i386_get_xfpustate xfpu; + ucontext_t *ucp; + + ucp = (ucontext_t *)ctx; + if (xstate_sz != 0) { + xfpu.addr = (char *)(ucp + 1); + xfpu.len = xstate_sz; + if (sysarch(I386_GET_XFPUSTATE, &xfpu) == -1) + return (-1); + ucp->uc_mcontext.mc_xfpustate = (__register_t)xfpu.addr; + ucp->uc_mcontext.mc_xfpustate_len = xstate_sz; + ucp->uc_mcontext.mc_flags |= _MC_HASFPXSTATE; + } else { + ucp->uc_mcontext.mc_xfpustate = 0; + ucp->uc_mcontext.mc_xfpustate_len = 0; + } + return (0); +} + +int +__fillcontextx(char *ctx) +{ + ucontext_t *ucp; + + ucp = (ucontext_t *)ctx; + if (getcontext(ucp) == -1) + return (-1); + __fillcontextx2(ctx); + return (0); +} + +__weak_reference(__getcontextx, getcontextx); + +ucontext_t * +__getcontextx(void) +{ + char *ctx; + int error; + + ctx = malloc(__getcontextx_size()); + if (ctx == NULL) + return (NULL); + if (__fillcontextx(ctx) == -1) { + error = errno; + free(ctx); + errno = error; + return (NULL); + } + return ((ucontext_t *)ctx); +} diff --git a/lib/libc/i386/stdlib/Makefile.inc b/lib/libc/i386/stdlib/Makefile.inc new file mode 100644 index 0000000..6bcf055 --- /dev/null +++ b/lib/libc/i386/stdlib/Makefile.inc @@ -0,0 +1,4 @@ +# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/i386/stdlib/Makefile.inc 194688 2009-06-23 09:04:59Z ed $ + +MDSRCS+=div.S ldiv.S diff --git a/lib/libc/i386/string/Makefile.inc b/lib/libc/i386/string/Makefile.inc new file mode 100644 index 0000000..978ddd9 --- /dev/null +++ b/lib/libc/i386/string/Makefile.inc @@ -0,0 +1,23 @@ +# $FreeBSD: releng/11.1/lib/libc/i386/string/Makefile.inc 315044 2017-03-11 02:51:29Z brooks $ + +MDSRCS+= \ + bcmp.S \ + bcopy.S \ + bzero.S \ + ffs.S \ + memchr.S \ + memcmp.S \ + memcpy.S \ + memmove.S \ + memset.S \ + strcat.S \ + strchr.S \ + strcmp.S \ + strcpy.S \ + strncmp.S \ + strrchr.S \ + swab.S \ + wcschr.S \ + wcscmp.S \ + wcslen.S \ + wmemchr.S diff --git a/lib/libc/i386/sys/Makefile.inc b/lib/libc/i386/sys/Makefile.inc new file mode 100644 index 0000000..8310921 --- /dev/null +++ b/lib/libc/i386/sys/Makefile.inc @@ -0,0 +1,23 @@ +# from: Makefile.inc,v 1.1 1993/09/03 19:04:23 jtc Exp +# $FreeBSD: releng/11.1/lib/libc/i386/sys/Makefile.inc 305866 2016-09-16 10:04:28Z kib $ + +.if !defined(COMPAT_32BIT) +SRCS+= i386_clr_watch.c i386_set_watch.c i386_vm86.c +.endif +SRCS+= i386_get_fsbase.c i386_get_gsbase.c i386_get_ioperm.c i386_get_ldt.c \ + i386_set_fsbase.c i386_set_gsbase.c i386_set_ioperm.c i386_set_ldt.c + +MDASM= Ovfork.S brk.S cerror.S exect.S getcontext.S \ + sbrk.S setlogin.S sigreturn.S syscall.S + +# Don't generate default code for these syscalls: +NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o vfork.o yield.o + +PSEUDO= _getlogin.o _exit.o + +MAN+= i386_get_ioperm.2 i386_get_ldt.2 i386_vm86.2 +MAN+= i386_set_watch.3 + +MLINKS+=i386_get_ioperm.2 i386_set_ioperm.2 +MLINKS+=i386_get_ldt.2 i386_set_ldt.2 +MLINKS+=i386_set_watch.3 i386_clr_watch.3 diff --git a/lib/libc/i386/sys/i386_get_ioperm.2 b/lib/libc/i386/sys/i386_get_ioperm.2 new file mode 100644 index 0000000..287d9ae --- /dev/null +++ b/lib/libc/i386/sys/i386_get_ioperm.2 @@ -0,0 +1,87 @@ +.\" Copyright (c) 1998 Jonathan Lemon +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/i386/sys/i386_get_ioperm.2 233520 2012-03-26 19:23:57Z joel $ +.\" +.Dd July 27, 1998 +.Dt I386_GET_IOPERM 2 +.Os +.Sh NAME +.Nm i386_get_ioperm , +.Nm i386_set_ioperm +.Nd manage per-process access to the i386 I/O port space +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In machine/sysarch.h +.Ft int +.Fn i386_get_ioperm "unsigned int start" "unsigned int *length" "int *enable" +.Ft int +.Fn i386_set_ioperm "unsigned int start" "unsigned int length" "int enable" +.Sh DESCRIPTION +The +.Fn i386_get_ioperm +system call +will return the permission for the process' I/O port space in the +.Fa *enable +argument. +The port range starts at +.Fa start +and the number of contiguous entries will be returned in +.Fa *length . +.Pp +The +.Fn i386_set_ioperm +system call +will set access to a range of I/O ports described by the +.Fa start +and +.Fa length +arguments to the state specified by the +.Fa enable +argument. +.Sh RETURN VALUES +.Rv -std +.Sh ERRORS +The +.Fn i386_get_ioperm +and +.Fn i386_set_ioperm +system calls +will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +An invalid range was specified by the +.Fa start +or +.Fa length +arguments. +.It Bq Er EPERM +The caller of i386_set_ioperm was not the superuser. +.El +.Sh SEE ALSO +.Xr io 4 +.Sh AUTHORS +This man page was written by +.An Jonathan Lemon . diff --git a/lib/libc/i386/sys/i386_get_ldt.2 b/lib/libc/i386/sys/i386_get_ldt.2 new file mode 100644 index 0000000..e022b90 --- /dev/null +++ b/lib/libc/i386/sys/i386_get_ldt.2 @@ -0,0 +1,139 @@ +.\" Copyright (c) 1980, 1991 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. +.\" 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. +.\" +.\" from: @(#)fork.2 6.5 (Berkeley) 3/10/91 +.\" $FreeBSD: releng/11.1/lib/libc/i386/sys/i386_get_ldt.2 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd October 14, 2006 +.Dt I386_GET_LDT 2 +.Os +.Sh NAME +.Nm i386_get_ldt , +.Nm i386_set_ldt +.Nd manage i386 per-process Local Descriptor Table entries +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In machine/segments.h +.In machine/sysarch.h +.Ft int +.Fn i386_get_ldt "int start_sel" "union descriptor *descs" "int num_sels" +.Ft int +.Fn i386_set_ldt "int start_sel" "union descriptor *descs" "int num_sels" +.Sh DESCRIPTION +The +.Fn i386_get_ldt +system call +returns a list of the i386 descriptors in the current process' +LDT. +The +.Fn i386_set_ldt +system call +sets a list of i386 descriptors in the current process' +LDT. +For both routines, +.Fa start_sel +specifies the index of the selector in the LDT at which to begin and +.Fa descs +points to an array of +.Fa num_sels +descriptors to be set or returned. +.Pp +Each entry in the +.Fa descs +array can be either a segment_descriptor or gate_descriptor and are defined in +.In i386/segments.h . +These structures are defined by the architecture +as disjoint bit-fields, so care must be taken in constructing them. +.Pp +If +.Fa start_sel +is +.Em LDT_AUTO_ALLOC , +.Fa num_sels +is 1 and the descriptor pointed to by +.Fa descs +is legal, then +.Fn i386_set_ldt +will allocate a descriptor and return its +selector number. +.Pp +If +.Fa num_descs +is 1, +.Fa start_sels +is valid, and +.Fa descs +is NULL, then +.Fn i386_set_ldt +will free that descriptor +(making it available to be reallocated again later). +.Pp +If +.Fa num_descs +is 0, +.Fa start_sels +is 0 and +.Fa descs +is NULL then, as a special case, +.Fn i386_set_ldt +will free all descriptors. +.Sh RETURN VALUES +Upon successful completion, +.Fn i386_get_ldt +returns the number of descriptors currently in the LDT. +The +.Fn i386_set_ldt +system call +returns the first selector set on success. +If the kernel allocated a descriptor in the LDT, +the allocated index is returned. +Otherwise, a value of -1 is returned and the global +variable +.Va errno +is set to indicate the error. +.Sh ERRORS +The +.Fn i386_get_ldt +and +.Fn i386_set_ldt +system calls +will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +An inappropriate value was used for +.Fa start_sel +or +.Fa num_sels . +.It Bq Er EACCES +The caller attempted to use a descriptor that would +circumvent protection or cause a failure. +.El +.Sh SEE ALSO +i386 Microprocessor Programmer's Reference Manual, Intel +.Sh WARNING +You can really hose your process using this. diff --git a/lib/libc/i386/sys/i386_set_watch.3 b/lib/libc/i386/sys/i386_set_watch.3 new file mode 100644 index 0000000..be40c0f --- /dev/null +++ b/lib/libc/i386/sys/i386_set_watch.3 @@ -0,0 +1,118 @@ +.\" Copyright (c) 2000 Brian S. Dean +.\" All rights reserved. +.\" +.\" This man-page is based on a similar man-page by Jonathan Lemon +.\" which is copyrighted under the following conditions: +.\" +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/i386/sys/i386_set_watch.3 233520 2012-03-26 19:23:57Z joel $ +.\" +.Dd August 24, 2000 +.Dt I386_SET_WATCH 3 +.Os +.Sh NAME +.Nm i386_clr_watch , +.Nm i386_set_watch +.Nd manage i386 debug register values +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In machine/reg.h +.In machine/sysarch.h +.Ft int +.Fn i386_clr_watch "int watchnum" "struct dbreg *d" +.Ft int +.Fn i386_set_watch "int watchnum" "unsigned int watchaddr" "int size" "int access" "struct dbreg *d" +.Sh DESCRIPTION +The +.Fn i386_clr_watch +function +will disable the indicated watch point within the specified debug +register set. +.Pp +The +.Fn i386_set_watch +function +will set up the specified debug registers as indicated by the +arguments. +The +.Fa watchnum +argument specifies which watch register is used, 0, 1, 2, 3, or \-1. +If +.Fa watchnum +is \-1, a free watch register is found and used. +If there are no free +watch registers, an error code of \-1 is returned. +The +.Fa watchaddr +argument +specifies the watch address, +.Fa size +specifies the size in bytes of the area to be watched (1, 2, or 4 bytes), +and +.Fa access +specifies the type of watch point: +.Pp +.Bd -literal -offset indent -compact +DBREG_DR7_EXEC An execution breakpoint. +DBREG_DR7_WRONLY Break only when the watch area is written to. +DBREG_DR7_RDWR Break when the watch area is read from or written + to. +.Ed +.Pp +Note that these functions do not actually set or clear breakpoints; +they manipulate the indicated debug register set. +You must use +.Xr ptrace 2 +to retrieve and install the debug register values for a process. +.Sh RETURN VALUES +On success, the +.Fn i386_clr_watch +function returns 0. +On error, \-1 returned which indicates that +.Fa watchnum +is invalid (not in the range of 0-3). +If the specified watchnum was already disabled, no error is returned. +.Pp +On success, the +.Fn i386_set_watch +function returns the +.Fa watchnum +argument, or the watchnum actually used in the case where the specified +.Fa watchnum +was \-1. +On error, the +.Fn i386_set_watch +function returns \-1 indicating that the watchpoint could not established +because either no more watchpoints are available, or +.Fa watchnum , +.Fa size , +or +.Fa access +is invalid. +.Sh SEE ALSO +.Xr ptrace 2 , +.Xr procfs 5 +.Sh AUTHORS +This man page was written by +.An Brian S. Dean . diff --git a/lib/libc/i386/sys/i386_vm86.2 b/lib/libc/i386/sys/i386_vm86.2 new file mode 100644 index 0000000..c421a51 --- /dev/null +++ b/lib/libc/i386/sys/i386_vm86.2 @@ -0,0 +1,141 @@ +.\" Copyright (c) 1998 Jonathan Lemon +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/i386/sys/i386_vm86.2 233520 2012-03-26 19:23:57Z joel $ +.\" +.Dd July 27, 1998 +.Dt I386_VM86 2 +.Os +.Sh NAME +.Nm i386_vm86 +.Nd control vm86-related functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In machine/sysarch.h +.In machine/vm86.h +.Ft int +.Fn i386_vm86 "int function" "void *data" +.Sh DESCRIPTION +The +.Fn i386_vm86 +system call +is used to call various vm86 related functions. +The +.Fa function +argument +can be one of the following values: +.Bl -tag -offset indent -width VM86_SET_VME +.It Dv VM86_INIT +This will initialize the kernel's vm86 parameter area for the +process, and permit the process to make vm86 calls. +The +.Fa data +argument +points to the following structure: +.Bd -literal +struct vm86_init_args { + int debug; + int cpu_type; + u_char int_map[32]; +}; +.Ed +.Pp +The +.Fa debug +argument +is used to turn on debugging code. +The +.Fa cpu_type +argument +controls the type of CPU being emulated, and is currently unimplemented. +The +.Fa int_map +argument +is a bitmap which determines whether vm86 interrupts should be handled +in vm86 mode, or reflected back to the process. +If the +.Em Nth +bit is set, the interrupt will be reflected to the process, otherwise +it will be dispatched by the vm86 interrupt table. +.It Dv VM86_INTCALL +This allows calls to be made to vm86 interrupt handlers by the process. +It effectively simulates an INT instruction. +.Fa data +should point to the following structure: +.Bd -literal +struct vm86_intcall_args { + int intnum; + struct vm86frame vmf; +}; +.Ed +.Pp +.Fa intnum +specifies the operand of INT for the simulated call. +A value of 0x10, for example, would often be used to call into the VGA BIOS. +.Fa vmf +is used to initialize CPU registers according to the calling convention for +the interrupt handler. +.It Dv VM86_GET_VME +This is used to retrieve the current state of the Pentium(r) processor's +VME (Virtual-8086 Mode Extensions) flag, which is bit 0 of CR4. +.Fa data +should be initialized to point to the following: +.Bd -literal +struct vm86_vme_args { + int state; /* status */ +}; +.Ed +.Pp +.Fa state +will contain the state of the VME flag on return. +.\" .It Dv VM86_SET_VME +.El +.Pp +vm86 mode is entered by calling +.Xr sigreturn 2 +with the correct machine context for vm86, and with the +.Dv PSL_VM +bit set. +Control returns to the process upon delivery of a signal. +.Sh RETURN VALUES +.Rv -std i386_vm86 +.Sh ERRORS +The +.Fn i386_vm86 +system call +will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The kernel does not have vm86 support, or an invalid function was specified. +.It Bq Er ENOMEM +There is not enough memory to initialize the kernel data structures. +.El +.Sh AUTHORS +.An -nosplit +This man page was written by +.An Jonathan Lemon , +and updated by +.An Bruce M Simpson . diff --git a/lib/libc/iconv/Makefile.inc b/lib/libc/iconv/Makefile.inc new file mode 100644 index 0000000..0b4ca74 --- /dev/null +++ b/lib/libc/iconv/Makefile.inc @@ -0,0 +1,26 @@ +# $FreeBSD: releng/11.1/lib/libc/iconv/Makefile.inc 313240 2017-02-04 17:17:38Z ngie $ + +# iconv sources +.PATH: ${LIBC_SRCTOP}/iconv + +MAN+= iconv.3 iconvctl.3 iconv_canonicalize.3 iconvlist.3 __iconv_get_list.3 +MLINKS+= iconv.3 iconv_open.3 \ + iconv.3 iconv_open_into.3 \ + iconv.3 iconv_close.3 \ + iconv.3 __iconv.3 \ + __iconv_get_list.3 __iconv_free_list.3 +SRCS+= citrus_bcs.c citrus_bcs_strtol.c citrus_bcs_strtoul.c \ + citrus_csmapper.c citrus_db.c citrus_db_factory.c citrus_db_hash.c \ + citrus_esdb.c citrus_hash.c citrus_iconv.c citrus_lookup.c \ + citrus_lookup_factory.c citrus_mapper.c citrus_memstream.c \ + citrus_mmap.c citrus_module.c citrus_none.c citrus_pivot_factory.c \ + citrus_prop.c citrus_stdenc.c bsd_iconv.c +.if ${MK_SYMVER} == yes +SRCS+= iconv_compat.c +.endif + +SYM_MAPS+= ${LIBC_SRCTOP}/iconv/Symbol.map + +.if ${MK_ICONV} == yes +.include "${SRCTOP}/lib/libc_nonshared/Makefile.iconv" +.endif diff --git a/lib/libc/iconv/Symbol.map b/lib/libc/iconv/Symbol.map new file mode 100644 index 0000000..e0a76d5 --- /dev/null +++ b/lib/libc/iconv/Symbol.map @@ -0,0 +1,104 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/iconv/Symbol.map 258283 2013-11-17 22:52:17Z peter $ + */ + +FBSD_1.3 { + __bsd___iconv; + __bsd___iconv_free_list; + __bsd___iconv_get_list; + __bsd_iconv; + __bsd_iconv_canonicalize; + __bsd_iconv_close; + __bsd_iconv_open; + __bsd_iconv_open_into; + __bsd_iconv_set_relocation_prefix; + __bsd_iconvctl; + __bsd_iconvlist; +}; + +FBSDprivate_1.0 { + _citrus_bcs_convert_to_lower; + _citrus_bcs_convert_to_upper; + _citrus_bcs_isalnum; + _citrus_bcs_isalpha; + _citrus_bcs_isblank; + _citrus_bcs_isdigit; + _citrus_bcs_iseol; + _citrus_bcs_islower; + _citrus_bcs_isspace; + _citrus_bcs_isupper; + _citrus_bcs_isxdigit; + _citrus_bcs_skip_nonws; + _citrus_bcs_skip_nonws_len; + _citrus_bcs_skip_ws; + _citrus_bcs_skip_ws_len; + _citrus_bcs_strcasecmp; + _citrus_bcs_strncasecmp; + _citrus_bcs_strtol; + _citrus_bcs_strtoul; + _citrus_bcs_tolower; + _citrus_bcs_toupper; + _citrus_bcs_trunc_rws_len; + _citrus_bcs_trunc_ws_len; + _citrus_csmapper_open; + _citrus_csmapper_close; + _citrus_db_factory_add_by_string; + _citrus_db_factory_add_string_by_string; + _citrus_db_factory_add32_by_string; + _citrus_db_factory_calc_size; + _citrus_db_factory_create; + _citrus_db_factory_serialize; + _citrus_db_hash_std; + _citrus_db_close; + _citrus_db_get_entry; + _citrus_db_get_number_of_entries; + _citrus_db_lookup; + _citrus_db_lookup_by_string; + _citrus_db_lookup8_by_string; + _citrus_db_lookup16_by_string; + _citrus_db_lookup_string_by_string; + _citrus_db_open; + _citrus_esdb_close; + _citrus_esdb_open; + _citrus_lookup_factory_convert; + _citrus_map_file; + _citrus_mapper_close; + _citrus_mapper_convert; + _citrus_mapper_create_area; + _citrus_mapper_get_dst_max; + _citrus_mapper_get_src_max; + _citrus_mapper_get_state_size; + _citrus_mapper_init_state; + _citrus_mapper_open; + _citrus_mapper_open_direct; + _citrus_mapper_set_persistent; + _citrus_memory_stream_bind; + _citrus_memory_stream_chr; + _citrus_memory_stream_getc; + _citrus_memory_stream_getln; + _citrus_memory_stream_getln_region; + _citrus_memory_stream_getregion; + _citrus_memory_stream_iseof; + _citrus_memory_stream_matchline; + _citrus_memory_stream_peek; + _citrus_memory_stream_remainder; + _citrus_memory_stream_rewind; + _citrus_memory_stream_seek; + _citrus_memory_stream_skip_ws; + _citrus_memory_stream_tell; + _citrus_memory_stream_ungetc; + _citrus_pivot_factory_convert; + _citrus_prop_object_init; + _citrus_prop_object_uninit; + _citrus_prop_parse_variable; + _citrus_prop_read_bool; + _citrus_prop_read_character; + _citrus_prop_read_character_common; + _citrus_prop_read_element; + _citrus_prop_read_num; + _citrus_prop_read_str; + _citrus_prop_read_symbol; + _citrus_stdenc_close; + _citrus_stdenc_open; + _citrus_unmap_file; +}; diff --git a/lib/libc/iconv/__iconv.c b/lib/libc/iconv/__iconv.c new file mode 100644 index 0000000..0157178 --- /dev/null +++ b/lib/libc/iconv/__iconv.c @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/__iconv.c 281550 2015-04-15 09:09:20Z tijl $ + */ + +#include +#include +#include "iconv-internal.h" + +size_t +__iconv(iconv_t a, char **b, size_t *c, char **d, + size_t *e, __uint32_t f, size_t *g) +{ + return __bsd___iconv(a, b, c, d, e, f, g); +} diff --git a/lib/libc/iconv/__iconv_free_list.c b/lib/libc/iconv/__iconv_free_list.c new file mode 100644 index 0000000..efb1f87 --- /dev/null +++ b/lib/libc/iconv/__iconv_free_list.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/__iconv_free_list.c 258587 2013-11-25 20:17:55Z peter $ + */ + +#include +#include +#include "iconv-internal.h" + +void +__iconv_free_list(char **a, size_t b) +{ + __bsd___iconv_free_list(a, b); +} diff --git a/lib/libc/iconv/__iconv_get_list.3 b/lib/libc/iconv/__iconv_get_list.3 new file mode 100644 index 0000000..1d6b4b4 --- /dev/null +++ b/lib/libc/iconv/__iconv_get_list.3 @@ -0,0 +1,95 @@ +.\" Copyright (c) 2009 Gabor Kovesdan +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/iconv/__iconv_get_list.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.Dd October 20, 2009 +.Dt __ICONV_GET_LIST 3 +.Os +.Sh NAME +.Nm __iconv_get_list +.Nm __iconv_free_list +.Nd retrieving a list of character encodings supported by +.Xr iconv 3 +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In iconv.h +.Ft int +.Fn __iconv_get_list "char ***names" "size_t count" "bool paired" +.Ft void +.Fn __iconv_free_list "char **names" "size_t count" +.Sh DESCRIPTION +The +.Fn __iconv_get_list +function obtains a list of character encodings that are supported by the +.Xr iconv 3 +call. +The list of the encoding names will be stored in +.Fa names +and the number of the entries is stored in +.Fa count . +If the +.Fa paired +variable is true, the list will be arranged into +canonical/alias name pairs. +.Pp +The +.Fn __iconv_free_list +function is to free the allocated memory during the call of +.Fn __iconv_get_list . +.Sh RETURN VALUES +Upon successful completion +.Fn __iconv_get_list +returns 0 and set the +.Fa names +and +.Fa count +arguments. +Otherwise, \-1 is returned and errno is set to indicate the error. +.Sh SEE ALSO +.Xr iconv 3 , +.Xr iconvlist 3 +.Sh STANDARDS +The +.Nm __iconv_get_list +and +.Nm __iconv_free_list +functions are non-standard interfaces, which appeared in +the implementation of the Citrus Project. +The iconv implementation of the Citrus Project was adopted in +.Fx 9.0 . +.Sh AUTHORS +This manual page was written by +.An Gabor Kovesdan Aq Mt gabor@FreeBSD.org . diff --git a/lib/libc/iconv/__iconv_get_list.c b/lib/libc/iconv/__iconv_get_list.c new file mode 100644 index 0000000..2656f72 --- /dev/null +++ b/lib/libc/iconv/__iconv_get_list.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/__iconv_get_list.c 258587 2013-11-25 20:17:55Z peter $ + */ + +#include +#include +#include "iconv-internal.h" + +int +__iconv_get_list(char ***a, size_t *b, __iconv_bool c) +{ + return __bsd___iconv_get_list(a, b, c); +} diff --git a/lib/libc/iconv/_strtol.h b/lib/libc/iconv/_strtol.h new file mode 100644 index 0000000..6cb961c --- /dev/null +++ b/lib/libc/iconv/_strtol.h @@ -0,0 +1,167 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/_strtol.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: _strtol.h,v 1.2 2009/05/20 22:03:29 christos Exp $ */ + +/*- + * Copyright (c) 1990, 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. + * + * Original version ID: + * NetBSD: src/lib/libc/locale/_wcstol.h,v 1.2 2003/08/07 16:43:03 agc Exp + */ + +/* + * function template for strtol, strtoll and strtoimax. + * + * parameters: + * _FUNCNAME : function name + * __INT : return type + * __INT_MIN : lower limit of the return type + * __INT_MAX : upper limit of the return type + */ + +__INT +_FUNCNAME(const char *nptr, char **endptr, int base) +{ + const char *s; + __INT acc, cutoff; + unsigned char c; + int any, cutlim, i, neg; + + /* check base value */ + if (base && (base < 2 || base > 36)) { +#if !defined(_KERNEL) && !defined(_STANDALONE) + errno = EINVAL; + if (endptr != NULL) + /* LINTED interface specification */ + *endptr = __DECONST(void *, nptr); + return (0); +#else + panic("%s: invalid base %d", __func__, base); +#endif + } + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = (c == '0' ? 8 : 10); + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for longs is + * [-2147483648..2147483647] and the input base is 10, + * cutoff will be set to 214748364 and cutlim to either + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + * a value > 214748364, or equal but the next digit is > 7 (or 8), + * the number is too big, and we will return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + cutoff = (neg ? __INT_MIN : __INT_MAX); + cutlim = (int)(cutoff % base); + cutoff /= base; + if (neg) { + if (cutlim > 0) { + cutlim -= base; + cutoff += 1; + } + cutlim = -cutlim; + } + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) + i = c - '0'; + else if (isalpha(c)) + i = c - (isupper(c) ? 'A' - 10 : 'a' - 10); + else + break; + if (i >= base) + break; + if (any < 0) + continue; + if (neg) { + if (acc < cutoff || (acc == cutoff && i > cutlim)) { + acc = __INT_MIN; +#if !defined(_KERNEL) && !defined(_STANDALONE) + any = -1; + errno = ERANGE; +#else + any = 0; + break; +#endif + } else { + any = 1; + acc *= base; + acc -= i; + } + } else { + if (acc > cutoff || (acc == cutoff && i > cutlim)) { + acc = __INT_MAX; +#if !defined(_KERNEL) && !defined(_STANDALONE) + any = -1; + errno = ERANGE; +#else + any = 0; + break; +#endif + } else { + any = 1; + acc *= base; + acc += i; + } + } + } + if (endptr != NULL) + /* LINTED interface specification */ + *endptr = __DECONST(void *, any ? s - 1 : nptr); + return(acc); +} diff --git a/lib/libc/iconv/_strtoul.h b/lib/libc/iconv/_strtoul.h new file mode 100644 index 0000000..5121334 --- /dev/null +++ b/lib/libc/iconv/_strtoul.h @@ -0,0 +1,126 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/_strtoul.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: _strtoul.h,v 1.1 2008/08/20 12:42:26 joerg Exp $ */ + +/*- + * Copyright (c) 1990, 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. + * + * Original version ID: + * NetBSD: src/lib/libc/locale/_wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp + */ + +/* + * function template for strtoul, strtoull and strtoumax. + * + * parameters: + * _FUNCNAME : function name + * __UINT : return type + * __UINT_MAX : upper limit of the return type + */ + +__UINT +_FUNCNAME(const char *nptr, char **endptr, int base) +{ + const char *s; + __UINT acc, cutoff; + unsigned char c; + int any, cutlim, i, neg; + + /* check base value */ + if (base && (base < 2 || base > 36)) { +#if !defined(_KERNEL) && !defined(_STANDALONE) + errno = EINVAL; + return (0); +#else + panic("%s: invalid base %d", __func__, base); +#endif + } + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = (c == '0' ? 8 : 10); + + /* + * See strtol for comments as to the logic used. + */ + cutoff = __UINT_MAX / (__UINT)base; + cutlim = (int)(__UINT_MAX % (__UINT)base); + for (acc = 0, any = 0;; c = *s++) { + if (isdigit(c)) + i = c - '0'; + else if (isalpha(c)) + i = c - (isupper(c) ? 'A' - 10 : 'a' - 10); + else + break; + if (i >= base) + break; + if (any < 0) + continue; + if (acc > cutoff || (acc == cutoff && i > cutlim)) { + acc = __UINT_MAX; +#if !defined(_KERNEL) && !defined(_STANDALONE) + any = -1; + errno = ERANGE; +#else + any = 0; + break; +#endif + } else { + any = 1; + acc *= (__UINT)base; + acc += i; + } + } + if (neg && any > 0) + acc = -acc; + if (endptr != NULL) + /* LINTED interface specification */ + *endptr = __DECONST(void *, any ? s - 1 : nptr); + return (acc); +} diff --git a/lib/libc/iconv/bsd_iconv.c b/lib/libc/iconv/bsd_iconv.c new file mode 100644 index 0000000..d2c9717 --- /dev/null +++ b/lib/libc/iconv/bsd_iconv.c @@ -0,0 +1,325 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/bsd_iconv.c 299704 2016-05-14 00:35:35Z vangyzen $ */ +/* $NetBSD: iconv.c,v 1.11 2009/03/03 16:22:33 explorer Exp $ */ + +/*- + * Copyright (c) 2003 Citrus Project, + * Copyright (c) 2009, 2010 Gabor Kovesdan , + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "citrus_types.h" +#include "citrus_module.h" +#include "citrus_esdb.h" +#include "citrus_hash.h" +#include "citrus_iconv.h" + +#include "iconv-internal.h" + +#define ISBADF(_h_) (!(_h_) || (_h_) == (iconv_t)-1) + +static iconv_t +__bsd___iconv_open(const char *out, const char *in, struct _citrus_iconv *handle) +{ + const char *out_slashes; + char *out_noslashes; + int ret; + + /* + * Remove anything following a //, as these are options (like + * //ignore, //translate, etc) and we just don't handle them. + * This is for compatibility with software that uses these + * blindly. + */ + out_slashes = strstr(out, "//"); + if (out_slashes != NULL) { + out_noslashes = strndup(out, out_slashes - out); + if (out_noslashes == NULL) { + errno = ENOMEM; + return ((iconv_t)-1); + } + ret = _citrus_iconv_open(&handle, in, out_noslashes); + free(out_noslashes); + } else { + ret = _citrus_iconv_open(&handle, in, out); + } + + if (ret) { + errno = ret == ENOENT ? EINVAL : ret; + return ((iconv_t)-1); + } + + handle->cv_shared->ci_discard_ilseq = strcasestr(out, "//IGNORE"); + handle->cv_shared->ci_ilseq_invalid = false; + handle->cv_shared->ci_hooks = NULL; + + return ((iconv_t)(void *)handle); +} + +iconv_t +__bsd_iconv_open(const char *out, const char *in) +{ + + return (__bsd___iconv_open(out, in, NULL)); +} + +int +__bsd_iconv_open_into(const char *out, const char *in, iconv_allocation_t *ptr) +{ + struct _citrus_iconv *handle; + + handle = (struct _citrus_iconv *)ptr; + return ((__bsd___iconv_open(out, in, handle) == (iconv_t)-1) ? -1 : 0); +} + +int +__bsd_iconv_close(iconv_t handle) +{ + + if (ISBADF(handle)) { + errno = EBADF; + return (-1); + } + + _citrus_iconv_close((struct _citrus_iconv *)(void *)handle); + + return (0); +} + +size_t +__bsd_iconv(iconv_t handle, char **in, size_t *szin, char **out, size_t *szout) +{ + size_t ret; + int err; + + if (ISBADF(handle)) { + errno = EBADF; + return ((size_t)-1); + } + + err = _citrus_iconv_convert((struct _citrus_iconv *)(void *)handle, + in, szin, out, szout, 0, &ret); + if (err) { + errno = err; + ret = (size_t)-1; + } + + return (ret); +} + +size_t +__bsd___iconv(iconv_t handle, char **in, size_t *szin, char **out, + size_t *szout, uint32_t flags, size_t *invalids) +{ + size_t ret; + int err; + + if (ISBADF(handle)) { + errno = EBADF; + return ((size_t)-1); + } + + err = _citrus_iconv_convert((struct _citrus_iconv *)(void *)handle, + in, szin, out, szout, flags, &ret); + if (invalids) + *invalids = ret; + if (err) { + errno = err; + ret = (size_t)-1; + } + + return (ret); +} + +int +__bsd___iconv_get_list(char ***rlist, size_t *rsz, bool sorted) +{ + int ret; + + ret = _citrus_esdb_get_list(rlist, rsz, sorted); + if (ret) { + errno = ret; + return (-1); + } + + return (0); +} + +void +__bsd___iconv_free_list(char **list, size_t sz) +{ + + _citrus_esdb_free_list(list, sz); +} + +/* + * GNU-compatibile non-standard interfaces. + */ +static int +qsort_helper(const void *first, const void *second) +{ + const char * const *s1; + const char * const *s2; + + s1 = first; + s2 = second; + return (strcmp(*s1, *s2)); +} + +void +__bsd_iconvlist(int (*do_one) (unsigned int, const char * const *, + void *), void *data) +{ + char **list, **names; + const char * const *np; + char *curitem, *curkey, *slashpos; + size_t sz; + unsigned int i, j, n; + + i = 0; + names = NULL; + + if (__bsd___iconv_get_list(&list, &sz, true)) { + list = NULL; + goto out; + } + qsort((void *)list, sz, sizeof(char *), qsort_helper); + while (i < sz) { + j = 0; + slashpos = strchr(list[i], '/'); + names = malloc(sz * sizeof(char *)); + if (names == NULL) + goto out; + curkey = strndup(list[i], slashpos - list[i]); + if (curkey == NULL) + goto out; + names[j++] = curkey; + for (; (i < sz) && (memcmp(curkey, list[i], strlen(curkey)) == 0); i++) { + slashpos = strchr(list[i], '/'); + if (strcmp(curkey, &slashpos[1]) == 0) + continue; + curitem = strdup(&slashpos[1]); + if (curitem == NULL) + goto out; + names[j++] = curitem; + } + np = (const char * const *)names; + do_one(j, np, data); + for (n = 0; n < j; n++) + free(names[n]); + free(names); + names = NULL; + } + +out: + if (names != NULL) { + for (n = 0; n < j; n++) + free(names[n]); + free(names); + } + if (list != NULL) + __bsd___iconv_free_list(list, sz); +} + +__inline const char * +__bsd_iconv_canonicalize(const char *name) +{ + + return (_citrus_iconv_canonicalize(name)); +} + +int +__bsd_iconvctl(iconv_t cd, int request, void *argument) +{ + struct _citrus_iconv *cv; + struct iconv_hooks *hooks; + const char *convname; + char *dst; + int *i; + size_t srclen; + + cv = (struct _citrus_iconv *)(void *)cd; + hooks = (struct iconv_hooks *)argument; + i = (int *)argument; + + if (ISBADF(cd)) { + errno = EBADF; + return (-1); + } + + switch (request) { + case ICONV_TRIVIALP: + convname = cv->cv_shared->ci_convname; + dst = strchr(convname, '/'); + srclen = dst - convname; + dst++; + *i = (srclen == strlen(dst)) && !memcmp(convname, dst, srclen); + return (0); + case ICONV_GET_TRANSLITERATE: + *i = 1; + return (0); + case ICONV_SET_TRANSLITERATE: + return ((*i == 1) ? 0 : -1); + case ICONV_GET_DISCARD_ILSEQ: + *i = cv->cv_shared->ci_discard_ilseq ? 1 : 0; + return (0); + case ICONV_SET_DISCARD_ILSEQ: + cv->cv_shared->ci_discard_ilseq = *i; + return (0); + case ICONV_SET_HOOKS: + cv->cv_shared->ci_hooks = hooks; + return (0); + case ICONV_SET_FALLBACKS: + errno = EOPNOTSUPP; + return (-1); + case ICONV_GET_ILSEQ_INVALID: + *i = cv->cv_shared->ci_ilseq_invalid ? 1 : 0; + return (0); + case ICONV_SET_ILSEQ_INVALID: + cv->cv_shared->ci_ilseq_invalid = *i; + return (0); + default: + errno = EINVAL; + return (-1); + } +} + +void +__bsd_iconv_set_relocation_prefix(const char *orig_prefix __unused, + const char *curr_prefix __unused) +{ + +} diff --git a/lib/libc/iconv/citrus_aliasname_local.h b/lib/libc/iconv/citrus_aliasname_local.h new file mode 100644 index 0000000..4314d18 --- /dev/null +++ b/lib/libc/iconv/citrus_aliasname_local.h @@ -0,0 +1,49 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_aliasname_local.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_aliasname_local.h,v 1.2 2009/01/11 02:46:24 christos Exp $ */ + +/*- + * Copyright (c)2008 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_ALIASNAME_LOCAL_H_ +#define _CITRUS_ALIASNAME_LOCAL_H_ + +static __inline const char * +__unaliasname(const char *dbname, const char *alias, + void *buf, size_t bufsize) +{ + + return (_lookup_simple(dbname, alias, + buf, bufsize, _LOOKUP_CASE_SENSITIVE)); +} + +static __inline int +__isforcemapping(const char *name) +{ + + return (_bcs_strcasecmp("/force", name)); +} + +#endif /*_CITRUS_ALIASNAME_LOCAL_H_*/ diff --git a/lib/libc/iconv/citrus_bcs.c b/lib/libc/iconv/citrus_bcs.c new file mode 100644 index 0000000..65d6e6e --- /dev/null +++ b/lib/libc/iconv/citrus_bcs.c @@ -0,0 +1,168 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_bcs.c 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_bcs.c,v 1.5 2005/05/14 17:55:42 tshiozak Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + +#include +#include + +#include "citrus_namespace.h" +#include "citrus_bcs.h" + +/* + * case insensitive comparison between two C strings. + */ +int +_citrus_bcs_strcasecmp(const char * __restrict str1, + const char * __restrict str2) +{ + int c1, c2; + + c1 = c2 = 1; + + while (c1 && c2 && c1 == c2) { + c1 = _bcs_toupper(*str1++); + c2 = _bcs_toupper(*str2++); + } + + return ((c1 == c2) ? 0 : ((c1 > c2) ? 1 : -1)); +} + +/* + * case insensitive comparison between two C strings with limitation of length. + */ +int +_citrus_bcs_strncasecmp(const char * __restrict str1, + const char * __restrict str2, size_t sz) +{ + int c1, c2; + + c1 = c2 = 1; + + while (c1 && c2 && c1 == c2 && sz != 0) { + c1 = _bcs_toupper(*str1++); + c2 = _bcs_toupper(*str2++); + sz--; + } + + return ((c1 == c2) ? 0 : ((c1 > c2) ? 1 : -1)); +} + +/* + * skip white space characters. + */ +const char * +_citrus_bcs_skip_ws(const char *p) +{ + + while (*p && _bcs_isspace(*p)) + p++; + + return (p); +} + +/* + * skip non white space characters. + */ +const char * +_citrus_bcs_skip_nonws(const char *p) +{ + + while (*p && !_bcs_isspace(*p)) + p++; + + return (p); +} + +/* + * skip white space characters with limitation of length. + */ +const char * +_citrus_bcs_skip_ws_len(const char * __restrict p, size_t * __restrict len) +{ + + while (*p && *len > 0 && _bcs_isspace(*p)) { + p++; + (*len)--; + } + + return (p); +} + +/* + * skip non white space characters with limitation of length. + */ +const char * +_citrus_bcs_skip_nonws_len(const char * __restrict p, size_t * __restrict len) +{ + + while (*p && *len > 0 && !_bcs_isspace(*p)) { + p++; + (*len)--; + } + + return (p); +} + +/* + * truncate trailing white space characters. + */ +void +_citrus_bcs_trunc_rws_len(const char * __restrict p, size_t * __restrict len) +{ + + while (*len > 0 && _bcs_isspace(p[*len - 1])) + (*len)--; +} + +/* + * destructive transliterate to lowercase. + */ +void +_citrus_bcs_convert_to_lower(char *s) +{ + + while (*s) { + *s = _bcs_tolower(*s); + s++; + } +} + +/* + * destructive transliterate to uppercase. + */ +void +_citrus_bcs_convert_to_upper(char *s) +{ + + while (*s) { + *s = _bcs_toupper(*s); + s++; + } +} diff --git a/lib/libc/iconv/citrus_bcs.h b/lib/libc/iconv/citrus_bcs.h new file mode 100644 index 0000000..c05704d --- /dev/null +++ b/lib/libc/iconv/citrus_bcs.h @@ -0,0 +1,102 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_bcs.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_bcs.h,v 1.6 2009/01/11 02:46:24 christos Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + +#ifndef _CITRUS_BCS_H_ +#define _CITRUS_BCS_H_ + +/* + * predicate/conversion for basic character set. + * + * `Basic character set' is a term defined in the ISO C standard. + * Citrus bcs is, if anything, close to `portable character set' + * defined in the POSIX. + */ + +#define _CITRUS_BCS_PRED(_name_, _cond_) \ +static __inline int _citrus_bcs_##_name_(uint8_t c) { return (_cond_); } + +/* + * predicates. + * Unlike predicates defined in ctype.h, these do not accept EOF. + */ +_CITRUS_BCS_PRED(isblank, c == ' ' || c == '\t') +_CITRUS_BCS_PRED(iseol, c == '\n' || c == '\r') +_CITRUS_BCS_PRED(isspace, _citrus_bcs_isblank(c) || _citrus_bcs_iseol(c) || + c == '\f' || c == '\v') +_CITRUS_BCS_PRED(isdigit, c >= '0' && c <= '9') +_CITRUS_BCS_PRED(isupper, c >= 'A' && c <= 'Z') +_CITRUS_BCS_PRED(islower, c >= 'a' && c <= 'z') +_CITRUS_BCS_PRED(isalpha, _citrus_bcs_isupper(c) || _citrus_bcs_islower(c)) +_CITRUS_BCS_PRED(isalnum, _citrus_bcs_isdigit(c) || _citrus_bcs_isalpha(c)) +_CITRUS_BCS_PRED(isxdigit, _citrus_bcs_isdigit(c) || + (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) + +/* + * transliterate between uppercase and lowercase. + * Unlike transliterator defined in ctype.h, these do not accept EOF. + */ +static __inline uint8_t +_citrus_bcs_toupper(uint8_t c) +{ + + return (_citrus_bcs_islower(c) ? (c - 'a' + 'A') : c); +} + +static __inline uint8_t +_citrus_bcs_tolower(uint8_t c) +{ + + return (_citrus_bcs_isupper(c) ? (c - 'A' + 'a') : c); +} + +__BEGIN_DECLS +int _citrus_bcs_strcasecmp(const char * __restrict, + const char * __restrict); +int _citrus_bcs_strncasecmp(const char * __restrict, + const char * __restrict, size_t); +const char *_citrus_bcs_skip_ws(const char * __restrict); +const char *_citrus_bcs_skip_nonws(const char * __restrict); +const char *_citrus_bcs_skip_ws_len(const char * __restrict, + size_t * __restrict); +const char *_citrus_bcs_skip_nonws_len(const char * __restrict, + size_t * __restrict); +void _citrus_bcs_trunc_rws_len(const char * __restrict, + size_t * __restrict); +void _citrus_bcs_convert_to_lower(char *); +void _citrus_bcs_convert_to_upper(char *); + +long int _citrus_bcs_strtol(const char * __restrict, + char ** __restrict, int); +unsigned long _citrus_bcs_strtoul(const char * __restrict, + char ** __restrict, int); +__END_DECLS + +#endif diff --git a/lib/libc/iconv/citrus_bcs_strtol.c b/lib/libc/iconv/citrus_bcs_strtol.c new file mode 100644 index 0000000..4bd8513 --- /dev/null +++ b/lib/libc/iconv/citrus_bcs_strtol.c @@ -0,0 +1,57 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_bcs_strtol.c 263986 2014-04-01 10:36:11Z tijl $ */ +/* $NetBSD: citrus_bcs_strtol.c,v 1.4 2013/04/26 21:20:47 joerg Exp $ */ + +/*- + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * Copyright (c) 2003, 2008 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_bcs.h" + +#define _FUNCNAME _bcs_strtol +#define __INT long int + +#undef isspace +#define isspace(c) _bcs_isspace(c) + +#undef isdigit +#define isdigit(c) _bcs_isdigit(c) + +#undef isalpha +#define isalpha(c) _bcs_isalpha(c) + +#undef isupper +#define isupper(c) _bcs_isupper(c) + +#include "_strtol.h" diff --git a/lib/libc/iconv/citrus_bcs_strtoul.c b/lib/libc/iconv/citrus_bcs_strtoul.c new file mode 100644 index 0000000..acf5dfe --- /dev/null +++ b/lib/libc/iconv/citrus_bcs_strtoul.c @@ -0,0 +1,57 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_bcs_strtoul.c 263986 2014-04-01 10:36:11Z tijl $ */ +/* $NetBSD: citrus_bcs_strtoul.c,v 1.5 2013/04/26 21:20:48 joerg Exp $ */ + +/*- + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * Copyright (c) 2003, 2008 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_bcs.h" + +#define _FUNCNAME _bcs_strtoul +#define __UINT unsigned long int + +#undef isspace +#define isspace(c) _bcs_isspace(c) + +#undef isdigit +#define isdigit(c) _bcs_isdigit(c) + +#undef isalpha +#define isalpha(c) _bcs_isalpha(c) + +#undef isupper +#define isupper(c) _bcs_isupper(c) + +#include "_strtoul.h" diff --git a/lib/libc/iconv/citrus_csmapper.c b/lib/libc/iconv/citrus_csmapper.c new file mode 100644 index 0000000..b64264c --- /dev/null +++ b/lib/libc/iconv/citrus_csmapper.c @@ -0,0 +1,386 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_csmapper.c 263986 2014-04-01 10:36:11Z tijl $ */ +/* $NetBSD: citrus_csmapper.c,v 1.11 2011/11/20 07:43:52 tnozaki Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_types.h" +#include "citrus_bcs.h" +#include "citrus_region.h" +#include "citrus_lock.h" +#include "citrus_memstream.h" +#include "citrus_mmap.h" +#include "citrus_module.h" +#include "citrus_hash.h" +#include "citrus_mapper.h" +#include "citrus_csmapper.h" +#include "citrus_pivot_file.h" +#include "citrus_db.h" +#include "citrus_db_hash.h" +#include "citrus_lookup.h" + +static struct _citrus_mapper_area *maparea = NULL; + +static pthread_rwlock_t ma_lock = PTHREAD_RWLOCK_INITIALIZER; + +#define CS_ALIAS _PATH_CSMAPPER "/charset.alias" +#define CS_PIVOT _PATH_CSMAPPER "/charset.pivot" + + +/* ---------------------------------------------------------------------- */ + +static int +get32(struct _region *r, uint32_t *rval) +{ + + if (_region_size(r) != 4) + return (EFTYPE); + + memcpy(rval, _region_head(r), (size_t)4); + *rval = be32toh(*rval); + + return (0); +} + +static int +open_subdb(struct _citrus_db **subdb, struct _citrus_db *db, const char *src) +{ + struct _region r; + int ret; + + ret = _db_lookup_by_s(db, src, &r, NULL); + if (ret) + return (ret); + ret = _db_open(subdb, &r, _CITRUS_PIVOT_SUB_MAGIC, _db_hash_std, NULL); + if (ret) + return (ret); + + return (0); +} + + +#define NO_SUCH_FILE EOPNOTSUPP +static int +find_best_pivot_pvdb(const char *src, const char *dst, char *pivot, + size_t pvlen, unsigned long *rnorm) +{ + struct _citrus_db *db1, *db2, *db3; + struct _region fr, r1, r2; + char buf[LINE_MAX]; + uint32_t val32; + unsigned long norm; + int i, num, ret; + + ret = _map_file(&fr, CS_PIVOT ".pvdb"); + if (ret) { + if (ret == ENOENT) + ret = NO_SUCH_FILE; + return (ret); + } + ret = _db_open(&db1, &fr, _CITRUS_PIVOT_MAGIC, _db_hash_std, NULL); + if (ret) + goto quit1; + ret = open_subdb(&db2, db1, src); + if (ret) + goto quit2; + + num = _db_get_num_entries(db2); + *rnorm = ULONG_MAX; + for (i = 0; i < num; i++) { + /* iterate each pivot */ + ret = _db_get_entry(db2, i, &r1, &r2); + if (ret) + goto quit3; + /* r1:pivot name, r2:norm among src and pivot */ + ret = get32(&r2, &val32); + if (ret) + goto quit3; + norm = val32; + snprintf(buf, sizeof(buf), "%.*s", + (int)_region_size(&r1), (char *)_region_head(&r1)); + /* buf: pivot name */ + ret = open_subdb(&db3, db1, buf); + if (ret) + goto quit3; + if (_db_lookup_by_s(db3, dst, &r2, NULL) != 0) + /* don't break the loop, test all src/dst pairs. */ + goto quit4; + /* r2: norm among pivot and dst */ + ret = get32(&r2, &val32); + if (ret) + goto quit4; + norm += val32; + /* judge minimum norm */ + if (norm < *rnorm) { + *rnorm = norm; + strlcpy(pivot, buf, pvlen); + } +quit4: + _db_close(db3); + if (ret) + goto quit3; + } +quit3: + _db_close(db2); +quit2: + _db_close(db1); +quit1: + _unmap_file(&fr); + if (ret) + return (ret); + + if (*rnorm == ULONG_MAX) + return (ENOENT); + + return (0); +} + +/* ---------------------------------------------------------------------- */ + +struct zone { + const char *begin, *end; +}; + +struct parse_arg { + char dst[PATH_MAX]; + unsigned long norm; +}; + +static int +parse_line(struct parse_arg *pa, struct _region *r) +{ + struct zone z1, z2; + char buf[20]; + size_t len; + + len = _region_size(r); + z1.begin = _bcs_skip_ws_len(_region_head(r), &len); + if (len == 0) + return (EFTYPE); + z1.end = _bcs_skip_nonws_len(z1.begin, &len); + if (len == 0) + return (EFTYPE); + z2.begin = _bcs_skip_ws_len(z1.end, &len); + if (len == 0) + return (EFTYPE); + z2.end = _bcs_skip_nonws_len(z2.begin, &len); + + /* z1 : dst name, z2 : norm */ + snprintf(pa->dst, sizeof(pa->dst), + "%.*s", (int)(z1.end-z1.begin), z1.begin); + snprintf(buf, sizeof(buf), + "%.*s", (int)(z2.end-z2.begin), z2.begin); + pa->norm = _bcs_strtoul(buf, NULL, 0); + + return (0); +} + +static int +find_dst(struct parse_arg *pasrc, const char *dst) +{ + struct _lookup *cl; + struct parse_arg padst; + struct _region data; + int ret; + + ret = _lookup_seq_open(&cl, CS_PIVOT, _LOOKUP_CASE_IGNORE); + if (ret) + return (ret); + + ret = _lookup_seq_lookup(cl, pasrc->dst, &data); + while (ret == 0) { + ret = parse_line(&padst, &data); + if (ret) + break; + if (strcmp(dst, padst.dst) == 0) { + pasrc->norm += padst.norm; + break; + } + ret = _lookup_seq_next(cl, NULL, &data); + } + _lookup_seq_close(cl); + + return (ret); +} + +static int +find_best_pivot_lookup(const char *src, const char *dst, char *pivot, + size_t pvlen, unsigned long *rnorm) +{ + struct _lookup *cl; + struct _region data; + struct parse_arg pa; + char pivot_min[PATH_MAX]; + unsigned long norm_min; + int ret; + + ret = _lookup_seq_open(&cl, CS_PIVOT, _LOOKUP_CASE_IGNORE); + if (ret) + return (ret); + + norm_min = ULONG_MAX; + + /* find pivot code */ + ret = _lookup_seq_lookup(cl, src, &data); + while (ret == 0) { + ret = parse_line(&pa, &data); + if (ret) + break; + ret = find_dst(&pa, dst); + if (ret) + break; + if (pa.norm < norm_min) { + norm_min = pa.norm; + strlcpy(pivot_min, pa.dst, sizeof(pivot_min)); + } + ret = _lookup_seq_next(cl, NULL, &data); + } + _lookup_seq_close(cl); + + if (ret != ENOENT) + return (ret); + if (norm_min == ULONG_MAX) + return (ENOENT); + strlcpy(pivot, pivot_min, pvlen); + if (rnorm) + *rnorm = norm_min; + + return (0); +} + +static int +find_best_pivot(const char *src, const char *dst, char *pivot, size_t pvlen, + unsigned long *rnorm) +{ + int ret; + + ret = find_best_pivot_pvdb(src, dst, pivot, pvlen, rnorm); + if (ret == NO_SUCH_FILE) + ret = find_best_pivot_lookup(src, dst, pivot, pvlen, rnorm); + + return (ret); +} + +static __inline int +open_serial_mapper(struct _citrus_mapper_area *__restrict ma, + struct _citrus_mapper * __restrict * __restrict rcm, + const char *src, const char *pivot, const char *dst) +{ + char buf[PATH_MAX]; + + snprintf(buf, sizeof(buf), "%s/%s,%s/%s", src, pivot, pivot, dst); + + return (_mapper_open_direct(ma, rcm, "mapper_serial", buf)); +} + +static struct _citrus_csmapper *csm_none = NULL; +static int +get_none(struct _citrus_mapper_area *__restrict ma, + struct _citrus_csmapper *__restrict *__restrict rcsm) +{ + int ret; + + WLOCK(&ma_lock); + if (csm_none) { + *rcsm = csm_none; + ret = 0; + goto quit; + } + + ret = _mapper_open_direct(ma, &csm_none, "mapper_none", ""); + if (ret) + goto quit; + _mapper_set_persistent(csm_none); + + *rcsm = csm_none; + ret = 0; +quit: + UNLOCK(&ma_lock); + return (ret); +} + +int +_citrus_csmapper_open(struct _citrus_csmapper * __restrict * __restrict rcsm, + const char * __restrict src, const char * __restrict dst, uint32_t flags, + unsigned long *rnorm) +{ + const char *realsrc, *realdst; + char buf1[PATH_MAX], buf2[PATH_MAX], key[PATH_MAX], pivot[PATH_MAX]; + unsigned long norm; + int ret; + + norm = 0; + + ret = _citrus_mapper_create_area(&maparea, _PATH_CSMAPPER); + if (ret) + return (ret); + + realsrc = _lookup_alias(CS_ALIAS, src, buf1, sizeof(buf1), + _LOOKUP_CASE_IGNORE); + realdst = _lookup_alias(CS_ALIAS, dst, buf2, sizeof(buf2), + _LOOKUP_CASE_IGNORE); + if (!strcmp(realsrc, realdst)) { + ret = get_none(maparea, rcsm); + if (ret == 0 && rnorm != NULL) + *rnorm = 0; + return (ret); + } + + snprintf(key, sizeof(key), "%s/%s", realsrc, realdst); + + ret = _mapper_open(maparea, rcsm, key); + if (ret == 0) { + if (rnorm != NULL) + *rnorm = 0; + return (0); + } + if (ret != ENOENT || (flags & _CSMAPPER_F_PREVENT_PIVOT)!=0) + return (ret); + + ret = find_best_pivot(realsrc, realdst, pivot, sizeof(pivot), &norm); + if (ret) + return (ret); + + ret = open_serial_mapper(maparea, rcsm, realsrc, pivot, realdst); + if (ret == 0 && rnorm != NULL) + *rnorm = norm; + + return (ret); +} diff --git a/lib/libc/iconv/citrus_csmapper.h b/lib/libc/iconv/citrus_csmapper.h new file mode 100644 index 0000000..4afc46c --- /dev/null +++ b/lib/libc/iconv/citrus_csmapper.h @@ -0,0 +1,48 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_csmapper.h 263986 2014-04-01 10:36:11Z tijl $ */ +/* $NetBSD: citrus_csmapper.h,v 1.3 2013/06/24 17:28:35 joerg Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_CSMAPPER_H_ +#define _CITRUS_CSMAPPER_H_ + +#define _citrus_csmapper _citrus_mapper +#define _citrus_csmapper_close _citrus_mapper_close +#define _citrus_csmapper_convert _citrus_mapper_convert +#define _citrus_csmapper_init_state _citrus_mapper_init_state +#define _citrus_csmapper_get_state_size _citrus_mapper_get_state_size +#define _citrus_csmapper_get_src_max _citrus_mapper_get_src_max +#define _citrus_csmapper_get_dst_max _citrus_mapper_get_dst_max + +#define _CITRUS_CSMAPPER_F_PREVENT_PIVOT 0x00000001 +__BEGIN_DECLS +int _citrus_csmapper_open(struct _citrus_csmapper *__restrict *__restrict, + const char *__restrict, const char *__restrict, uint32_t, + unsigned long *); +__END_DECLS + +#endif diff --git a/lib/libc/iconv/citrus_db.c b/lib/libc/iconv/citrus_db.c new file mode 100644 index 0000000..5149d25 --- /dev/null +++ b/lib/libc/iconv/citrus_db.c @@ -0,0 +1,331 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_db.c 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_db.c,v 1.5 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_bcs.h" +#include "citrus_region.h" +#include "citrus_memstream.h" +#include "citrus_mmap.h" +#include "citrus_db.h" +#include "citrus_db_factory.h" +#include "citrus_db_file.h" + +struct _citrus_db { + struct _region db_region; + _citrus_db_hash_func_t db_hashfunc; + void *db_hashfunc_closure; +}; + +int +_citrus_db_open(struct _citrus_db **rdb, struct _region *r, const char *magic, + _citrus_db_hash_func_t hashfunc, void *hashfunc_closure) +{ + struct _citrus_db *db; + struct _citrus_db_header_x *dhx; + struct _memstream ms; + + _memstream_bind(&ms, r); + + /* sanity check */ + dhx = _memstream_getregion(&ms, NULL, sizeof(*dhx)); + if (dhx == NULL) + return (EFTYPE); + if (strncmp(dhx->dhx_magic, magic, _CITRUS_DB_MAGIC_SIZE) != 0) + return (EFTYPE); + if (_memstream_seek(&ms, be32toh(dhx->dhx_entry_offset), SEEK_SET)) + return (EFTYPE); + + if (be32toh(dhx->dhx_num_entries)*_CITRUS_DB_ENTRY_SIZE > + _memstream_remainder(&ms)) + return (EFTYPE); + + db = malloc(sizeof(*db)); + if (db == NULL) + return (errno); + db->db_region = *r; + db->db_hashfunc = hashfunc; + db->db_hashfunc_closure = hashfunc_closure; + *rdb = db; + + return (0); +} + +void +_citrus_db_close(struct _citrus_db *db) +{ + + free(db); +} + +int +_citrus_db_lookup(struct _citrus_db *db, struct _citrus_region *key, + struct _citrus_region *data, struct _citrus_db_locator *dl) +{ + struct _citrus_db_entry_x *dex; + struct _citrus_db_header_x *dhx; + struct _citrus_region r; + struct _memstream ms; + uint32_t hashval, num_entries; + size_t offset; + + _memstream_bind(&ms, &db->db_region); + + dhx = _memstream_getregion(&ms, NULL, sizeof(*dhx)); + num_entries = be32toh(dhx->dhx_num_entries); + if (num_entries == 0) + return (ENOENT); + + if (dl != NULL && dl->dl_offset>0) { + hashval = dl->dl_hashval; + offset = dl->dl_offset; + if (offset >= _region_size(&db->db_region)) + return (ENOENT); + } else { + hashval = db->db_hashfunc(key)%num_entries; + offset = be32toh(dhx->dhx_entry_offset) + + hashval * _CITRUS_DB_ENTRY_SIZE; + if (dl) + dl->dl_hashval = hashval; + } + do { + /* seek to the next entry */ + if (_citrus_memory_stream_seek(&ms, offset, SEEK_SET)) + return (EFTYPE); + /* get the entry record */ + dex = _memstream_getregion(&ms, NULL, _CITRUS_DB_ENTRY_SIZE); + if (dex == NULL) + return (EFTYPE); + + /* jump to next entry having the same hash value. */ + offset = be32toh(dex->dex_next_offset); + + /* save the current position */ + if (dl) { + dl->dl_offset = offset; + if (offset == 0) + dl->dl_offset = _region_size(&db->db_region); + } + + /* compare hash value. */ + if (be32toh(dex->dex_hash_value) != hashval) + /* not found */ + break; + /* compare key length */ + if (be32toh(dex->dex_key_size) == _region_size(key)) { + /* seek to the head of the key. */ + if (_memstream_seek(&ms, be32toh(dex->dex_key_offset), + SEEK_SET)) + return (EFTYPE); + /* get the region of the key */ + if (_memstream_getregion(&ms, &r, + _region_size(key)) == NULL) + return (EFTYPE); + /* compare key byte stream */ + if (memcmp(_region_head(&r), _region_head(key), + _region_size(key)) == 0) { + /* match */ + if (_memstream_seek( + &ms, be32toh(dex->dex_data_offset), + SEEK_SET)) + return (EFTYPE); + if (_memstream_getregion( + &ms, data, + be32toh(dex->dex_data_size)) == NULL) + return (EFTYPE); + return (0); + } + } + } while (offset != 0); + + return (ENOENT); +} + +int +_citrus_db_lookup_by_string(struct _citrus_db *db, const char *key, + struct _citrus_region *data, struct _citrus_db_locator *dl) +{ + struct _region r; + + _region_init(&r, __DECONST(void *, key), strlen(key)); + + return (_citrus_db_lookup(db, &r, data, dl)); +} + +int +_citrus_db_lookup8_by_string(struct _citrus_db *db, const char *key, + uint8_t *rval, struct _citrus_db_locator *dl) +{ + struct _region r; + int ret; + + ret = _citrus_db_lookup_by_string(db, key, &r, dl); + if (ret) + return (ret); + + if (_region_size(&r) != 1) + return (EFTYPE); + + if (rval) + memcpy(rval, _region_head(&r), 1); + + return (0); +} + +int +_citrus_db_lookup16_by_string(struct _citrus_db *db, const char *key, + uint16_t *rval, struct _citrus_db_locator *dl) +{ + struct _region r; + int ret; + uint16_t val; + + ret = _citrus_db_lookup_by_string(db, key, &r, dl); + if (ret) + return (ret); + + if (_region_size(&r) != 2) + return (EFTYPE); + + if (rval) { + memcpy(&val, _region_head(&r), 2); + *rval = be16toh(val); + } + + return (0); +} + +int +_citrus_db_lookup32_by_string(struct _citrus_db *db, const char *key, + uint32_t *rval, struct _citrus_db_locator *dl) +{ + struct _region r; + uint32_t val; + int ret; + + ret = _citrus_db_lookup_by_string(db, key, &r, dl); + if (ret) + return (ret); + + if (_region_size(&r) != 4) + return (EFTYPE); + + if (rval) { + memcpy(&val, _region_head(&r), 4); + *rval = be32toh(val); + } + + return (0); +} + +int +_citrus_db_lookup_string_by_string(struct _citrus_db *db, const char *key, + const char **rdata, struct _citrus_db_locator *dl) +{ + struct _region r; + int ret; + + ret = _citrus_db_lookup_by_string(db, key, &r, dl); + if (ret) + return (ret); + + /* check whether the string is null terminated */ + if (_region_size(&r) == 0) + return (EFTYPE); + if (*((const char*)_region_head(&r)+_region_size(&r)-1) != '\0') + return (EFTYPE); + + if (rdata) + *rdata = _region_head(&r); + + return (0); +} + +int +_citrus_db_get_number_of_entries(struct _citrus_db *db) +{ + struct _citrus_db_header_x *dhx; + struct _memstream ms; + + _memstream_bind(&ms, &db->db_region); + + dhx = _memstream_getregion(&ms, NULL, sizeof(*dhx)); + return ((int)be32toh(dhx->dhx_num_entries)); +} + +int +_citrus_db_get_entry(struct _citrus_db *db, int idx, struct _region *key, + struct _region *data) +{ + struct _citrus_db_entry_x *dex; + struct _citrus_db_header_x *dhx; + struct _memstream ms; + uint32_t num_entries; + size_t offset; + + _memstream_bind(&ms, &db->db_region); + + dhx = _memstream_getregion(&ms, NULL, sizeof(*dhx)); + num_entries = be32toh(dhx->dhx_num_entries); + if (idx < 0 || (uint32_t)idx >= num_entries) + return (EINVAL); + + /* seek to the next entry */ + offset = be32toh(dhx->dhx_entry_offset) + idx * _CITRUS_DB_ENTRY_SIZE; + if (_citrus_memory_stream_seek(&ms, offset, SEEK_SET)) + return (EFTYPE); + /* get the entry record */ + dex = _memstream_getregion(&ms, NULL, _CITRUS_DB_ENTRY_SIZE); + if (dex == NULL) + return (EFTYPE); + /* seek to the head of the key. */ + if (_memstream_seek(&ms, be32toh(dex->dex_key_offset), SEEK_SET)) + return (EFTYPE); + /* get the region of the key. */ + if (_memstream_getregion(&ms, key, be32toh(dex->dex_key_size))==NULL) + return (EFTYPE); + /* seek to the head of the data. */ + if (_memstream_seek(&ms, be32toh(dex->dex_data_offset), SEEK_SET)) + return (EFTYPE); + /* get the region of the data. */ + if (_memstream_getregion(&ms, data, be32toh(dex->dex_data_size))==NULL) + return (EFTYPE); + + return (0); +} diff --git a/lib/libc/iconv/citrus_db.h b/lib/libc/iconv/citrus_db.h new file mode 100644 index 0000000..36db2f2 --- /dev/null +++ b/lib/libc/iconv/citrus_db.h @@ -0,0 +1,70 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_db.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_db.h,v 1.2 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_DB_H_ +#define _CITRUS_DB_H_ + +#include "citrus_db_factory.h" + +struct _citrus_db; +struct _citrus_db_locator { + uint32_t dl_hashval; + size_t dl_offset; +}; + +__BEGIN_DECLS +int _citrus_db_open(struct _citrus_db **, struct _citrus_region *, + const char *, _citrus_db_hash_func_t, void *); +void _citrus_db_close(struct _citrus_db *); +int _citrus_db_lookup(struct _citrus_db *, struct _citrus_region *, + struct _citrus_region *, struct _citrus_db_locator *); +int _citrus_db_lookup_by_string(struct _citrus_db *, const char *, + struct _citrus_region *, struct _citrus_db_locator *); +int _citrus_db_lookup8_by_string(struct _citrus_db *, const char *, + uint8_t *, struct _citrus_db_locator *); +int _citrus_db_lookup16_by_string(struct _citrus_db *, const char *, + uint16_t *, struct _citrus_db_locator *); +int _citrus_db_lookup32_by_string(struct _citrus_db *, const char *, + uint32_t *, struct _citrus_db_locator *); +int _citrus_db_lookup_string_by_string(struct _citrus_db *, const char *, + const char **, struct _citrus_db_locator *); +int _citrus_db_get_number_of_entries(struct _citrus_db *); +int _citrus_db_get_entry(struct _citrus_db *, int, + struct _citrus_region *, struct _citrus_region *); +__END_DECLS + +static __inline void +_citrus_db_locator_init(struct _citrus_db_locator *dl) +{ + + dl->dl_hashval = 0; + dl->dl_offset = 0; +} + +#endif diff --git a/lib/libc/iconv/citrus_db_factory.c b/lib/libc/iconv/citrus_db_factory.c new file mode 100644 index 0000000..358a3f2 --- /dev/null +++ b/lib/libc/iconv/citrus_db_factory.c @@ -0,0 +1,337 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_db_factory.c 267437 2014-06-13 08:28:51Z tijl $ */ +/* $NetBSD: citrus_db_factory.c,v 1.10 2013/09/14 13:05:51 joerg Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_region.h" +#include "citrus_db_file.h" +#include "citrus_db_factory.h" + +struct _citrus_db_factory_entry { + STAILQ_ENTRY(_citrus_db_factory_entry) de_entry; + struct _citrus_db_factory_entry *de_next; + uint32_t de_hashvalue; + struct _region de_key; + int de_key_free; + struct _region de_data; + int de_data_free; + int de_idx; +}; + +struct _citrus_db_factory { + size_t df_num_entries; + STAILQ_HEAD(, _citrus_db_factory_entry) df_entries; + size_t df_total_key_size; + size_t df_total_data_size; + uint32_t (*df_hashfunc)(struct _citrus_region *); + void *df_hashfunc_closure; +}; + +#define DB_ALIGN 16 + +int +_citrus_db_factory_create(struct _citrus_db_factory **rdf, + _citrus_db_hash_func_t hashfunc, void *hashfunc_closure) +{ + struct _citrus_db_factory *df; + + df = malloc(sizeof(*df)); + if (df == NULL) + return (errno); + df->df_num_entries = 0; + df->df_total_key_size = df->df_total_data_size = 0; + STAILQ_INIT(&df->df_entries); + df->df_hashfunc = hashfunc; + df->df_hashfunc_closure = hashfunc_closure; + + *rdf = df; + + return (0); +} + +void +_citrus_db_factory_free(struct _citrus_db_factory *df) +{ + struct _citrus_db_factory_entry *de; + + while ((de = STAILQ_FIRST(&df->df_entries)) != NULL) { + STAILQ_REMOVE_HEAD(&df->df_entries, de_entry); + if (de->de_key_free) + free(_region_head(&de->de_key)); + if (de->de_data_free) + free(_region_head(&de->de_data)); + free(de); + } + free(df); +} + +static __inline size_t +ceilto(size_t sz) +{ + return ((sz + DB_ALIGN - 1) & ~(DB_ALIGN - 1)); +} + +int +_citrus_db_factory_add(struct _citrus_db_factory *df, struct _region *key, + int keyfree, struct _region *data, int datafree) +{ + struct _citrus_db_factory_entry *de; + + de = malloc(sizeof(*de)); + if (de == NULL) + return (-1); + + de->de_hashvalue = df->df_hashfunc(key); + de->de_key = *key; + de->de_key_free = keyfree; + de->de_data = *data; + de->de_data_free = datafree; + de->de_idx = -1; + + STAILQ_INSERT_TAIL(&df->df_entries, de, de_entry); + df->df_total_key_size += _region_size(key); + df->df_total_data_size += ceilto(_region_size(data)); + df->df_num_entries++; + + return (0); + +} + +int +_citrus_db_factory_add_by_string(struct _citrus_db_factory *df, + const char *key, struct _citrus_region *data, int datafree) +{ + struct _region r; + char *tmp; + + tmp = strdup(key); + if (tmp == NULL) + return (errno); + _region_init(&r, tmp, strlen(key)); + return _citrus_db_factory_add(df, &r, 1, data, datafree); +} + +int +_citrus_db_factory_add8_by_string(struct _citrus_db_factory *df, + const char *key, uint8_t val) +{ + struct _region r; + uint8_t *p; + + p = malloc(sizeof(*p)); + if (p == NULL) + return (errno); + *p = val; + _region_init(&r, p, 1); + return (_citrus_db_factory_add_by_string(df, key, &r, 1)); +} + +int +_citrus_db_factory_add16_by_string(struct _citrus_db_factory *df, + const char *key, uint16_t val) +{ + struct _region r; + uint16_t *p; + + p = malloc(sizeof(*p)); + if (p == NULL) + return (errno); + *p = htons(val); + _region_init(&r, p, 2); + return (_citrus_db_factory_add_by_string(df, key, &r, 1)); +} + +int +_citrus_db_factory_add32_by_string(struct _citrus_db_factory *df, + const char *key, uint32_t val) +{ + struct _region r; + uint32_t *p; + + p = malloc(sizeof(*p)); + if (p == NULL) + return (errno); + *p = htonl(val); + _region_init(&r, p, 4); + return (_citrus_db_factory_add_by_string(df, key, &r, 1)); +} + +int +_citrus_db_factory_add_string_by_string(struct _citrus_db_factory *df, + const char *key, const char *data) +{ + char *p; + struct _region r; + + p = strdup(data); + if (p == NULL) + return (errno); + _region_init(&r, p, strlen(p) + 1); + return (_citrus_db_factory_add_by_string(df, key, &r, 1)); +} + +size_t +_citrus_db_factory_calc_size(struct _citrus_db_factory *df) +{ + size_t sz; + + sz = ceilto(_CITRUS_DB_HEADER_SIZE); + sz += ceilto(_CITRUS_DB_ENTRY_SIZE * df->df_num_entries); + sz += ceilto(df->df_total_key_size); + sz += df->df_total_data_size; + + return (sz); +} + +static __inline void +put8(struct _region *r, size_t *rofs, uint8_t val) +{ + + *(uint8_t *)_region_offset(r, *rofs) = val; + *rofs += 1; +} + +static __inline void +put32(struct _region *r, size_t *rofs, uint32_t val) +{ + + val = htonl(val); + memcpy(_region_offset(r, *rofs), &val, 4); + *rofs += 4; +} + +static __inline void +putpad(struct _region *r, size_t *rofs) +{ + size_t i; + + for (i = ceilto(*rofs) - *rofs; i > 0; i--) + put8(r, rofs, 0); +} + +static __inline void +dump_header(struct _region *r, const char *magic, size_t *rofs, + size_t num_entries) +{ + + while (*rofs<_CITRUS_DB_MAGIC_SIZE) + put8(r, rofs, *magic++); + put32(r, rofs, num_entries); + put32(r, rofs, _CITRUS_DB_HEADER_SIZE); +} + +int +_citrus_db_factory_serialize(struct _citrus_db_factory *df, const char *magic, + struct _region *r) +{ + struct _citrus_db_factory_entry *de, **depp, *det; + size_t dataofs, i, keyofs, nextofs, ofs; + + ofs = 0; + /* check whether more than 0 entries exist */ + if (df->df_num_entries == 0) { + dump_header(r, magic, &ofs, 0); + return (0); + } + /* allocate hash table */ + depp = calloc(df->df_num_entries, sizeof(*depp)); + if (depp == NULL) + return (-1); + + /* step1: store the entries which are not conflicting */ + STAILQ_FOREACH(de, &df->df_entries, de_entry) { + de->de_hashvalue %= df->df_num_entries; + de->de_idx = -1; + de->de_next = NULL; + if (depp[de->de_hashvalue] == NULL) { + depp[de->de_hashvalue] = de; + de->de_idx = (int)de->de_hashvalue; + } + } + + /* step2: resolve conflicts */ + i = 0; + STAILQ_FOREACH(de, &df->df_entries, de_entry) { + if (de->de_idx == -1) { + det = depp[de->de_hashvalue]; + while (det->de_next != NULL) + det = det->de_next; + det->de_next = de; + while (depp[i] != NULL) + i++; + depp[i] = de; + de->de_idx = (int)i; + } + } + + keyofs = _CITRUS_DB_HEADER_SIZE + + ceilto(df->df_num_entries*_CITRUS_DB_ENTRY_SIZE); + dataofs = keyofs + ceilto(df->df_total_key_size); + + /* dump header */ + dump_header(r, magic, &ofs, df->df_num_entries); + + /* dump entries */ + for (i = 0; i < df->df_num_entries; i++) { + de = depp[i]; + nextofs = 0; + if (de->de_next) { + nextofs = _CITRUS_DB_HEADER_SIZE + + de->de_next->de_idx * _CITRUS_DB_ENTRY_SIZE; + } + put32(r, &ofs, de->de_hashvalue); + put32(r, &ofs, nextofs); + put32(r, &ofs, keyofs); + put32(r, &ofs, _region_size(&de->de_key)); + put32(r, &ofs, dataofs); + put32(r, &ofs, _region_size(&de->de_data)); + memcpy(_region_offset(r, keyofs), + _region_head(&de->de_key), _region_size(&de->de_key)); + keyofs += _region_size(&de->de_key); + memcpy(_region_offset(r, dataofs), + _region_head(&de->de_data), _region_size(&de->de_data)); + dataofs += _region_size(&de->de_data); + putpad(r, &dataofs); + } + putpad(r, &ofs); + putpad(r, &keyofs); + free(depp); + + return (0); +} diff --git a/lib/libc/iconv/citrus_db_factory.h b/lib/libc/iconv/citrus_db_factory.h new file mode 100644 index 0000000..9212e6e --- /dev/null +++ b/lib/libc/iconv/citrus_db_factory.h @@ -0,0 +1,57 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_db_factory.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_db_factory.h,v 1.3 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_DB_FACTORY_H_ +#define _CITRUS_DB_FACTORY_H_ + +struct _citrus_db_factory; +typedef uint32_t (*_citrus_db_hash_func_t)(struct _citrus_region *); + +__BEGIN_DECLS +int _citrus_db_factory_create(struct _citrus_db_factory **, + _citrus_db_hash_func_t, void *); +void _citrus_db_factory_free(struct _citrus_db_factory *); +int _citrus_db_factory_add(struct _citrus_db_factory *, + struct _citrus_region *, int, struct _citrus_region *, int); +int _citrus_db_factory_add_by_string(struct _citrus_db_factory *, + const char *, struct _citrus_region *, int); +int _citrus_db_factory_add8_by_string(struct _citrus_db_factory *, + const char *, uint8_t); +int _citrus_db_factory_add16_by_string(struct _citrus_db_factory *, + const char *, uint16_t); +int _citrus_db_factory_add32_by_string(struct _citrus_db_factory *, + const char *, uint32_t); +int _citrus_db_factory_add_string_by_string(struct _citrus_db_factory *, + const char *, const char *); +size_t _citrus_db_factory_calc_size(struct _citrus_db_factory *); +int _citrus_db_factory_serialize(struct _citrus_db_factory *, + const char *, struct _citrus_region *); +__END_DECLS + +#endif diff --git a/lib/libc/iconv/citrus_db_file.h b/lib/libc/iconv/citrus_db_file.h new file mode 100644 index 0000000..9ab4a1b --- /dev/null +++ b/lib/libc/iconv/citrus_db_file.h @@ -0,0 +1,85 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_db_file.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_db_file.h,v 1.4 2008/02/10 05:58:22 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_DB_FILE_H_ +#define _CITRUS_DB_FILE_H_ + +/* + * db format: + * +--- + * | header + * | - magic + * | - num entries + * +--- + * | entry directory + * | +------------ + * | | entry0 + * | | - hash value + * | | - next entry + * | | - key offset + * | | - key len + * | | - data offset + * | | - data size + * | |--- + * | | entry1 + * | | .. + * | | entryN + * | +--- + * +--- + * | key table + * | - key0 + * | ... + * | - keyN + * +--- + * | data table + * | - data0 + * | ... + * | - dataN + * +--- + */ + +#define _CITRUS_DB_MAGIC_SIZE 8 +#define _CITRUS_DB_HEADER_SIZE 16 +struct _citrus_db_header_x { + char dhx_magic[_CITRUS_DB_MAGIC_SIZE]; + uint32_t dhx_num_entries; + uint32_t dhx_entry_offset; +} __packed; + +struct _citrus_db_entry_x { + uint32_t dex_hash_value; + uint32_t dex_next_offset; + uint32_t dex_key_offset; + uint32_t dex_key_size; + uint32_t dex_data_offset; + uint32_t dex_data_size; +} __packed; +#define _CITRUS_DB_ENTRY_SIZE 24 + +#endif diff --git a/lib/libc/iconv/citrus_db_hash.c b/lib/libc/iconv/citrus_db_hash.c new file mode 100644 index 0000000..1283d16 --- /dev/null +++ b/lib/libc/iconv/citrus_db_hash.c @@ -0,0 +1,64 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_db_hash.c 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_db_hash.c,v 1.5 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +#include + +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_types.h" +#include "citrus_bcs.h" +#include "citrus_region.h" +#include "citrus_db_hash.h" + +uint32_t +_citrus_db_hash_std(struct _region *r) +{ + const uint8_t *p; + uint32_t hash, tmp; + size_t i; + + hash = 0; + p = _region_head(r); + + for (i = _region_size(r); i > 0; i--) { + hash <<= 4; + hash += _bcs_tolower(*p); + tmp = hash & 0xF0000000; + if (tmp != 0) { + hash ^= tmp; + hash ^= tmp >> 24; + } + p++; + } + return (hash); +} diff --git a/lib/libc/iconv/citrus_db_hash.h b/lib/libc/iconv/citrus_db_hash.h new file mode 100644 index 0000000..f758d87 --- /dev/null +++ b/lib/libc/iconv/citrus_db_hash.h @@ -0,0 +1,37 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_db_hash.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_db_hash.h,v 1.2 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_DB_HASH_H_ +#define _CITRUS_DB_HASH_H_ + +__BEGIN_DECLS +uint32_t _citrus_db_hash_std(struct _citrus_region *); +__END_DECLS + +#endif diff --git a/lib/libc/iconv/citrus_esdb.c b/lib/libc/iconv/citrus_esdb.c new file mode 100644 index 0000000..c1d698a --- /dev/null +++ b/lib/libc/iconv/citrus_esdb.c @@ -0,0 +1,366 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_esdb.c 316613 2017-04-07 16:08:04Z pfg $ */ +/* $NetBSD: citrus_esdb.c,v 1.5 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_types.h" +#include "citrus_bcs.h" +#include "citrus_region.h" +#include "citrus_memstream.h" +#include "citrus_mmap.h" +#include "citrus_lookup.h" +#include "citrus_db.h" +#include "citrus_db_hash.h" +#include "citrus_esdb.h" +#include "citrus_esdb_file.h" + +#define ESDB_DIR "esdb.dir" +#define ESDB_ALIAS "esdb.alias" + +/* + * _citrus_esdb_alias: + * resolve encoding scheme name aliases. + */ +const char * +_citrus_esdb_alias(const char *esname, char *buf, size_t bufsize) +{ + + return (_lookup_alias(_PATH_ESDB "/" ESDB_ALIAS, esname, buf, bufsize, + _LOOKUP_CASE_IGNORE)); +} + + +/* + * conv_esdb: + * external representation -> local structure. + */ +static int +conv_esdb(struct _citrus_esdb *esdb, struct _region *fr) +{ + struct _citrus_db *db; + const char *str; + char buf[100]; + uint32_t csid, i, num_charsets, tmp, version; + int ret; + + /* open db */ + ret = _db_open(&db, fr, _CITRUS_ESDB_MAGIC, &_db_hash_std, NULL); + if (ret) + goto err0; + + /* check version */ + ret = _db_lookup32_by_s(db, _CITRUS_ESDB_SYM_VERSION, &version, NULL); + if (ret) + goto err1; + switch (version) { + case 0x00000001: + /* current version */ + /* initial version */ + break; + default: + ret = EFTYPE; + goto err1; + } + + /* get encoding/variable */ + ret = _db_lookupstr_by_s(db, _CITRUS_ESDB_SYM_ENCODING, &str, NULL); + if (ret) + goto err1; + esdb->db_encname = strdup(str); + if (esdb->db_encname == NULL) { + ret = errno; + goto err1; + } + + esdb->db_len_variable = 0; + esdb->db_variable = NULL; + ret = _db_lookupstr_by_s(db, _CITRUS_ESDB_SYM_VARIABLE, &str, NULL); + if (ret == 0) { + esdb->db_len_variable = strlen(str) + 1; + esdb->db_variable = strdup(str); + if (esdb->db_variable == NULL) { + ret = errno; + goto err2; + } + } else if (ret != ENOENT) + goto err2; + + /* get number of charsets */ + ret = _db_lookup32_by_s(db, _CITRUS_ESDB_SYM_NUM_CHARSETS, + &num_charsets, NULL); + if (ret) + goto err3; + esdb->db_num_charsets = num_charsets; + + /* get invalid character */ + ret = _db_lookup32_by_s(db, _CITRUS_ESDB_SYM_INVALID, &tmp, NULL); + if (ret == 0) { + esdb->db_use_invalid = 1; + esdb->db_invalid = tmp; + } else if (ret == ENOENT) + esdb->db_use_invalid = 0; + else + goto err3; + + /* get charsets */ + esdb->db_charsets = malloc(num_charsets * sizeof(*esdb->db_charsets)); + if (esdb->db_charsets == NULL) { + ret = errno; + goto err3; + } + for (i = 0; i < num_charsets; i++) { + snprintf(buf, sizeof(buf), + _CITRUS_ESDB_SYM_CSID_PREFIX "%d", i); + ret = _db_lookup32_by_s(db, buf, &csid, NULL); + if (ret) + goto err4; + esdb->db_charsets[i].ec_csid = csid; + + snprintf(buf, sizeof(buf), + _CITRUS_ESDB_SYM_CSNAME_PREFIX "%d", i); + ret = _db_lookupstr_by_s(db, buf, &str, NULL); + if (ret) + goto err4; + esdb->db_charsets[i].ec_csname = strdup(str); + if (esdb->db_charsets[i].ec_csname == NULL) { + ret = errno; + goto err4; + } + } + + _db_close(db); + return (0); + +err4: + for (; i > 0; i--) + free(esdb->db_charsets[i - 1].ec_csname); + free(esdb->db_charsets); +err3: + free(esdb->db_variable); +err2: + free(esdb->db_encname); +err1: + _db_close(db); + if (ret == ENOENT) + ret = EFTYPE; +err0: + return (ret); +} + +/* + * _citrus_esdb_open: + * open an ESDB file. + */ +int +_citrus_esdb_open(struct _citrus_esdb *db, const char *esname) +{ + struct _region fr; + const char *realname, *encfile; + char buf1[PATH_MAX], buf2[PATH_MAX], path[PATH_MAX]; + int ret; + + snprintf(path, sizeof(path), "%s/%s", _PATH_ESDB, ESDB_ALIAS); + realname = _lookup_alias(path, esname, buf1, sizeof(buf1), + _LOOKUP_CASE_IGNORE); + + snprintf(path, sizeof(path), "%s/%s", _PATH_ESDB, ESDB_DIR); + encfile = _lookup_simple(path, realname, buf2, sizeof(buf2), + _LOOKUP_CASE_IGNORE); + if (encfile == NULL) + return (ENOENT); + + /* open file */ + snprintf(path, sizeof(path), "%s/%s", _PATH_ESDB, encfile); + ret = _map_file(&fr, path); + if (ret) + return (ret); + + ret = conv_esdb(db, &fr); + + _unmap_file(&fr); + + return (ret); +} + +/* + * _citrus_esdb_close: + * free an ESDB. + */ +void +_citrus_esdb_close(struct _citrus_esdb *db) +{ + + for (int i = 0; i < db->db_num_charsets; i++) + free(db->db_charsets[i].ec_csname); + db->db_num_charsets = 0; + free(db->db_charsets); db->db_charsets = NULL; + free(db->db_encname); db->db_encname = NULL; + db->db_len_variable = 0; + free(db->db_variable); db->db_variable = NULL; +} + +/* + * _citrus_esdb_free_list: + * free the list. + */ +void +_citrus_esdb_free_list(char **list, size_t num) +{ + + for (size_t i = 0; i < num; i++) + free(list[i]); + free(list); +} + +/* + * _citrus_esdb_get_list: + * get esdb entries. + */ +int +_citrus_esdb_get_list(char ***rlist, size_t *rnum, bool sorted) +{ + struct _citrus_lookup *cla, *cld; + struct _region key, data; + char **list, **q; + char buf[PATH_MAX]; + size_t num; + int ret; + + ret = _lookup_seq_open(&cla, _PATH_ESDB "/" ESDB_ALIAS, + _LOOKUP_CASE_IGNORE); + if (ret) + goto quit0; + + ret = _lookup_seq_open(&cld, _PATH_ESDB "/" ESDB_DIR, + _LOOKUP_CASE_IGNORE); + if (ret) + goto quit1; + + /* count number of entries */ + num = _lookup_get_num_entries(cla) + _lookup_get_num_entries(cld); + + _lookup_seq_rewind(cla); + _lookup_seq_rewind(cld); + + /* allocate list pointer space */ + list = malloc(num * sizeof(char *)); + num = 0; + if (list == NULL) { + ret = errno; + goto quit3; + } + + /* get alias entries */ + while ((ret = _lookup_seq_next(cla, &key, &data)) == 0) { + /* XXX: sorted? */ + snprintf(buf, sizeof(buf), "%.*s/%.*s", + (int)_region_size(&data), + (const char *)_region_head(&data), + (int)_region_size(&key), + (const char *)_region_head(&key)); + _bcs_convert_to_upper(buf); + list[num] = strdup(buf); + if (list[num] == NULL) { + ret = errno; + goto quit3; + } + num++; + } + if (ret != ENOENT) + goto quit3; + /* get dir entries */ + while ((ret = _lookup_seq_next(cld, &key, &data)) == 0) { + if (!sorted) + snprintf(buf, sizeof(buf), "%.*s", + (int)_region_size(&key), + (const char *)_region_head(&key)); + else { + /* check duplicated entry */ + char *p; + char buf1[PATH_MAX]; + + snprintf(buf1, sizeof(buf1), "%.*s", + (int)_region_size(&data), + (const char *)_region_head(&data)); + if ((p = strchr(buf1, '/')) != NULL) + memmove(buf1, p + 1, strlen(p) - 1); + if ((p = strstr(buf1, ".esdb")) != NULL) + *p = '\0'; + snprintf(buf, sizeof(buf), "%s/%.*s", buf1, + (int)_region_size(&key), + (const char *)_region_head(&key)); + } + _bcs_convert_to_upper(buf); + ret = _lookup_seq_lookup(cla, buf, NULL); + if (ret) { + if (ret != ENOENT) + goto quit3; + /* not duplicated */ + list[num] = strdup(buf); + if (list[num] == NULL) { + ret = errno; + goto quit3; + } + num++; + } + } + if (ret != ENOENT) + goto quit3; + + ret = 0; + /* XXX: why reallocing the list space posteriorly? + shouldn't be done earlier? */ + q = reallocarray(list, num, sizeof(char *)); + if (!q) { + ret = ENOMEM; + goto quit3; + } + list = q; + *rlist = list; + *rnum = num; +quit3: + if (ret) + _citrus_esdb_free_list(list, num); + _lookup_seq_close(cld); +quit1: + _lookup_seq_close(cla); +quit0: + return (ret); +} diff --git a/lib/libc/iconv/citrus_esdb.h b/lib/libc/iconv/citrus_esdb.h new file mode 100644 index 0000000..5c6b637 --- /dev/null +++ b/lib/libc/iconv/citrus_esdb.h @@ -0,0 +1,58 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_esdb.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_esdb.h,v 1.1 2003/06/25 09:51:32 tshiozak Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_ESDB_H_ +#define _CITRUS_ESDB_H_ + +#include "citrus_types.h" + +struct _citrus_esdb_charset { + _citrus_csid_t ec_csid; + char *ec_csname; +}; + +struct _citrus_esdb { + char *db_encname; + void *db_variable; + size_t db_len_variable; + int db_num_charsets; + struct _citrus_esdb_charset *db_charsets; + int db_use_invalid; + _citrus_wc_t db_invalid; +}; + +__BEGIN_DECLS +const char *_citrus_esdb_alias(const char *, char *, size_t); +int _citrus_esdb_open(struct _citrus_esdb *, const char *); +void _citrus_esdb_close(struct _citrus_esdb *); +void _citrus_esdb_free_list(char **, size_t); +int _citrus_esdb_get_list(char ***, size_t *, bool); +__END_DECLS + +#endif diff --git a/lib/libc/iconv/citrus_esdb_file.h b/lib/libc/iconv/citrus_esdb_file.h new file mode 100644 index 0000000..d977164 --- /dev/null +++ b/lib/libc/iconv/citrus_esdb_file.h @@ -0,0 +1,45 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_esdb_file.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_esdb_file.h,v 1.1 2003/06/25 09:51:32 tshiozak Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_ESDB_FILE_H_ +#define _CITRUS_ESDB_FILE_H_ + +#define _CITRUS_ESDB_MAGIC "ESDB\0\0\0\0" + +#define _CITRUS_ESDB_SYM_VERSION "version" +#define _CITRUS_ESDB_SYM_ENCODING "encoding" +#define _CITRUS_ESDB_SYM_VARIABLE "variable" +#define _CITRUS_ESDB_SYM_NUM_CHARSETS "num_charsets" +#define _CITRUS_ESDB_SYM_INVALID "invalid" +#define _CITRUS_ESDB_SYM_CSNAME_PREFIX "csname_" +#define _CITRUS_ESDB_SYM_CSID_PREFIX "csid_" + +#define _CITRUS_ESDB_VERSION 0x00000001 + +#endif diff --git a/lib/libc/iconv/citrus_fix_grouping.h b/lib/libc/iconv/citrus_fix_grouping.h new file mode 100644 index 0000000..f328b0d --- /dev/null +++ b/lib/libc/iconv/citrus_fix_grouping.h @@ -0,0 +1,53 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_fix_grouping.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_fix_grouping.h,v 1.2 2009/01/11 02:46:24 christos Exp $ */ + +/*- + * Copyright (c)2008 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_FIX_GROUPING_H_ +#define _CITRUS_FIX_GROUPING_H_ + +#define _CITRUS_LC_GROUPING_VALUE_MIN 0 +#define _CITRUS_LC_GROUPING_VALUE_MAX 126 +#define _CITRUS_LC_GROUPING_VALUE_NO_FUTHER 127 + +#if CHAR_MAX != _CITRUS_LC_GROUPING_VALUE_NO_FUTHER +static __inline void +_citrus_fixup_char_max_md(char *grouping) +{ + char *p; + + for (p = grouping; *p != '\0'; ++p) + if (*p == _CITRUS_LC_GROUPING_VALUE_NO_FUTHER) + *p = (char)CHAR_MAX; +} +#define _CITRUS_FIXUP_CHAR_MAX_MD(grouping) \ + _citrus_fixup_char_max_md(__DECONST(void *, grouping)) +#else +#define _CITRUS_FIXUP_CHAR_MAX_MD(grouping) /* nothing to do */ +#endif + +#endif /*_CITRUS_FIX_GROUPING_H_*/ diff --git a/lib/libc/iconv/citrus_hash.c b/lib/libc/iconv/citrus_hash.c new file mode 100644 index 0000000..9bdbf09 --- /dev/null +++ b/lib/libc/iconv/citrus_hash.c @@ -0,0 +1,51 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_hash.c 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_hash.c,v 1.3 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +#include + +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_types.h" +#include "citrus_region.h" +#include "citrus_hash.h" +#include "citrus_db_hash.h" + +int +_citrus_string_hash_func(const char *key, int hashsize) +{ + struct _region r; + + _region_init(&r, __DECONST(void *, key), strlen(key)); + + return ((int)(_db_hash_std(&r) % (uint32_t)hashsize)); +} diff --git a/lib/libc/iconv/citrus_hash.h b/lib/libc/iconv/citrus_hash.h new file mode 100644 index 0000000..b27cbd3 --- /dev/null +++ b/lib/libc/iconv/citrus_hash.h @@ -0,0 +1,59 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_hash.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_hash.h,v 1.3 2004/01/02 21:49:35 itojun Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_HASH_H_ +#define _CITRUS_HASH_H_ + +#define _CITRUS_HASH_ENTRY(type) LIST_ENTRY(type) +#define _CITRUS_HASH_HEAD(headname, type, hashsize) \ +struct headname { \ + LIST_HEAD(, type) chh_table[hashsize]; \ +} +#define _CITRUS_HASH_INIT(head, hashsize) \ +do { \ + int _ch_loop; \ + \ + for (_ch_loop = 0; _ch_loop < hashsize; _ch_loop++) \ + LIST_INIT(&(head)->chh_table[_ch_loop]); \ +} while (0) +#define _CITRUS_HASH_REMOVE(elm, field) LIST_REMOVE(elm, field) +#define _CITRUS_HASH_INSERT(head, elm, field, hashval) \ + LIST_INSERT_HEAD(&(head)->chh_table[hashval], elm, field) +#define _CITRUS_HASH_SEARCH(head, elm, field, matchfunc, key, hashval) \ +do { \ + LIST_FOREACH((elm), &(head)->chh_table[hashval], field) \ + if (matchfunc((elm), key) == 0) \ + break; \ +} while (0) + +__BEGIN_DECLS +int _citrus_string_hash_func(const char *, int); +__END_DECLS + +#endif diff --git a/lib/libc/iconv/citrus_iconv.c b/lib/libc/iconv/citrus_iconv.c new file mode 100644 index 0000000..07815e4 --- /dev/null +++ b/lib/libc/iconv/citrus_iconv.c @@ -0,0 +1,359 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_iconv.c 279404 2015-02-28 20:30:25Z kan $ */ +/* $NetBSD: citrus_iconv.c,v 1.10 2011/11/19 18:34:21 tnozaki Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_bcs.h" +#include "citrus_esdb.h" +#include "citrus_region.h" +#include "citrus_memstream.h" +#include "citrus_mmap.h" +#include "citrus_module.h" +#include "citrus_lock.h" +#include "citrus_lookup.h" +#include "citrus_hash.h" +#include "citrus_iconv.h" + +#define _CITRUS_ICONV_DIR "iconv.dir" +#define _CITRUS_ICONV_ALIAS "iconv.alias" + +#define CI_HASH_SIZE 101 +#define CI_INITIAL_MAX_REUSE 5 +#define CI_ENV_MAX_REUSE "ICONV_MAX_REUSE" + +static bool isinit = false; +static int shared_max_reuse, shared_num_unused; +static _CITRUS_HASH_HEAD(, _citrus_iconv_shared, CI_HASH_SIZE) shared_pool; +static TAILQ_HEAD(, _citrus_iconv_shared) shared_unused; + +static pthread_rwlock_t ci_lock = PTHREAD_RWLOCK_INITIALIZER; + +static __inline void +init_cache(void) +{ + + WLOCK(&ci_lock); + if (!isinit) { + _CITRUS_HASH_INIT(&shared_pool, CI_HASH_SIZE); + TAILQ_INIT(&shared_unused); + shared_max_reuse = -1; + if (!issetugid() && getenv(CI_ENV_MAX_REUSE)) + shared_max_reuse = atoi(getenv(CI_ENV_MAX_REUSE)); + if (shared_max_reuse < 0) + shared_max_reuse = CI_INITIAL_MAX_REUSE; + isinit = true; + } + UNLOCK(&ci_lock); +} + +static __inline void +close_shared(struct _citrus_iconv_shared *ci) +{ + + if (ci) { + if (ci->ci_module) { + if (ci->ci_ops) { + if (ci->ci_closure) + (*ci->ci_ops->io_uninit_shared)(ci); + free(ci->ci_ops); + } + _citrus_unload_module(ci->ci_module); + } + free(ci); + } +} + +static __inline int +open_shared(struct _citrus_iconv_shared * __restrict * __restrict rci, + const char * __restrict convname, const char * __restrict src, + const char * __restrict dst) +{ + struct _citrus_iconv_shared *ci; + _citrus_iconv_getops_t getops; + const char *module; + size_t len_convname; + int ret; + +#ifdef INCOMPATIBLE_WITH_GNU_ICONV + /* + * Sadly, the gnu tools expect iconv to actually parse the + * byte stream and don't allow for a pass-through when + * the (src,dest) encodings are the same. + * See gettext-0.18.3+ NEWS: + * msgfmt now checks PO file headers more strictly with less + * false-positives. + * NetBSD don't do this either. + */ + module = (strcmp(src, dst) != 0) ? "iconv_std" : "iconv_none"; +#else + module = "iconv_std"; +#endif + + /* initialize iconv handle */ + len_convname = strlen(convname); + ci = malloc(sizeof(*ci) + len_convname + 1); + if (!ci) { + ret = errno; + goto err; + } + ci->ci_module = NULL; + ci->ci_ops = NULL; + ci->ci_closure = NULL; + ci->ci_convname = (void *)&ci[1]; + memcpy(ci->ci_convname, convname, len_convname + 1); + + /* load module */ + ret = _citrus_load_module(&ci->ci_module, module); + if (ret) + goto err; + + /* get operators */ + getops = (_citrus_iconv_getops_t)_citrus_find_getops(ci->ci_module, + module, "iconv"); + if (!getops) { + ret = EOPNOTSUPP; + goto err; + } + ci->ci_ops = malloc(sizeof(*ci->ci_ops)); + if (!ci->ci_ops) { + ret = errno; + goto err; + } + ret = (*getops)(ci->ci_ops); + if (ret) + goto err; + + if (ci->ci_ops->io_init_shared == NULL || + ci->ci_ops->io_uninit_shared == NULL || + ci->ci_ops->io_init_context == NULL || + ci->ci_ops->io_uninit_context == NULL || + ci->ci_ops->io_convert == NULL) { + ret = EINVAL; + goto err; + } + + /* initialize the converter */ + ret = (*ci->ci_ops->io_init_shared)(ci, src, dst); + if (ret) + goto err; + + *rci = ci; + + return (0); +err: + close_shared(ci); + return (ret); +} + +static __inline int +hash_func(const char *key) +{ + + return (_string_hash_func(key, CI_HASH_SIZE)); +} + +static __inline int +match_func(struct _citrus_iconv_shared * __restrict ci, + const char * __restrict key) +{ + + return (strcmp(ci->ci_convname, key)); +} + +static int +get_shared(struct _citrus_iconv_shared * __restrict * __restrict rci, + const char *src, const char *dst) +{ + struct _citrus_iconv_shared * ci; + char convname[PATH_MAX]; + int hashval, ret = 0; + + snprintf(convname, sizeof(convname), "%s/%s", src, dst); + + WLOCK(&ci_lock); + + /* lookup alread existing entry */ + hashval = hash_func(convname); + _CITRUS_HASH_SEARCH(&shared_pool, ci, ci_hash_entry, match_func, + convname, hashval); + if (ci != NULL) { + /* found */ + if (ci->ci_used_count == 0) { + TAILQ_REMOVE(&shared_unused, ci, ci_tailq_entry); + shared_num_unused--; + } + ci->ci_used_count++; + *rci = ci; + goto quit; + } + + /* create new entry */ + ret = open_shared(&ci, convname, src, dst); + if (ret) + goto quit; + + _CITRUS_HASH_INSERT(&shared_pool, ci, ci_hash_entry, hashval); + ci->ci_used_count = 1; + *rci = ci; + +quit: + UNLOCK(&ci_lock); + + return (ret); +} + +static void +release_shared(struct _citrus_iconv_shared * __restrict ci) +{ + + WLOCK(&ci_lock); + ci->ci_used_count--; + if (ci->ci_used_count == 0) { + /* put it into unused list */ + shared_num_unused++; + TAILQ_INSERT_TAIL(&shared_unused, ci, ci_tailq_entry); + /* flood out */ + while (shared_num_unused > shared_max_reuse) { + ci = TAILQ_FIRST(&shared_unused); + TAILQ_REMOVE(&shared_unused, ci, ci_tailq_entry); + _CITRUS_HASH_REMOVE(ci, ci_hash_entry); + shared_num_unused--; + close_shared(ci); + } + } + + UNLOCK(&ci_lock); +} + +/* + * _citrus_iconv_open: + * open a converter for the specified in/out codes. + */ +int +_citrus_iconv_open(struct _citrus_iconv * __restrict * __restrict rcv, + const char * __restrict src, const char * __restrict dst) +{ + struct _citrus_iconv *cv = NULL; + struct _citrus_iconv_shared *ci = NULL; + char realdst[PATH_MAX], realsrc[PATH_MAX]; +#ifdef _PATH_ICONV + char buf[PATH_MAX], path[PATH_MAX]; +#endif + int ret; + + init_cache(); + + /* GNU behaviour, using locale encoding if "" or "char" is specified */ + if ((strcmp(src, "") == 0) || (strcmp(src, "char") == 0)) + src = nl_langinfo(CODESET); + if ((strcmp(dst, "") == 0) || (strcmp(dst, "char") == 0)) + dst = nl_langinfo(CODESET); + + /* resolve codeset name aliases */ +#ifdef _PATH_ICONV + snprintf(path, sizeof(path), "%s/%s", _PATH_ICONV, _CITRUS_ICONV_ALIAS); + strlcpy(realsrc, _lookup_alias(path, src, buf, (size_t)PATH_MAX, + _LOOKUP_CASE_IGNORE), (size_t)PATH_MAX); + strlcpy(realdst, _lookup_alias(path, dst, buf, (size_t)PATH_MAX, + _LOOKUP_CASE_IGNORE), (size_t)PATH_MAX); +#else + strlcpy(realsrc, src, (size_t)PATH_MAX); + strlcpy(realdst, dst, (size_t)PATH_MAX); +#endif + + /* sanity check */ + if (strchr(realsrc, '/') != NULL || strchr(realdst, '/')) + return (EINVAL); + + /* get shared record */ + ret = get_shared(&ci, realsrc, realdst); + if (ret) + return (ret); + + /* create/init context */ + if (*rcv == NULL) { + cv = malloc(sizeof(*cv)); + if (cv == NULL) { + ret = errno; + release_shared(ci); + return (ret); + } + *rcv = cv; + } + (*rcv)->cv_shared = ci; + ret = (*ci->ci_ops->io_init_context)(*rcv); + if (ret) { + release_shared(ci); + free(cv); + return (ret); + } + return (0); +} + +/* + * _citrus_iconv_close: + * close the specified converter. + */ +void +_citrus_iconv_close(struct _citrus_iconv *cv) +{ + + if (cv) { + (*cv->cv_shared->ci_ops->io_uninit_context)(cv); + release_shared(cv->cv_shared); + free(cv); + } +} + +const char +*_citrus_iconv_canonicalize(const char *name) +{ + char *buf; + + if ((buf = calloc((size_t)PATH_MAX, sizeof(*buf))) == NULL) + return (NULL); + _citrus_esdb_alias(name, buf, (size_t)PATH_MAX); + return (buf); +} diff --git a/lib/libc/iconv/citrus_iconv.h b/lib/libc/iconv/citrus_iconv.h new file mode 100644 index 0000000..967b9c9 --- /dev/null +++ b/lib/libc/iconv/citrus_iconv.h @@ -0,0 +1,64 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_iconv.h 281550 2015-04-15 09:09:20Z tijl $ */ +/* $NetBSD: citrus_iconv.h,v 1.5 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_ICONV_H_ +#define _CITRUS_ICONV_H_ + +struct _citrus_iconv_shared; +struct _citrus_iconv_ops; +struct _citrus_iconv; + +__BEGIN_DECLS +int _citrus_iconv_open(struct _citrus_iconv * __restrict * __restrict, + const char * __restrict, const char * __restrict); +void _citrus_iconv_close(struct _citrus_iconv *); +const char *_citrus_iconv_canonicalize(const char *); +__END_DECLS + + +#include "citrus_iconv_local.h" + +#define _CITRUS_ICONV_F_HIDE_INVALID 0x0001 + +/* + * _citrus_iconv_convert: + * convert a string. + */ +static __inline int +_citrus_iconv_convert(struct _citrus_iconv * __restrict cv, + char * __restrict * __restrict in, size_t * __restrict inbytes, + char * __restrict * __restrict out, size_t * __restrict outbytes, + uint32_t flags, size_t * __restrict nresults) +{ + + return (*cv->cv_shared->ci_ops->io_convert)(cv, in, inbytes, out, + outbytes, flags, nresults); +} + +#endif diff --git a/lib/libc/iconv/citrus_iconv_local.h b/lib/libc/iconv/citrus_iconv_local.h new file mode 100644 index 0000000..4d3dced --- /dev/null +++ b/lib/libc/iconv/citrus_iconv_local.h @@ -0,0 +1,110 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_iconv_local.h 281550 2015-04-15 09:09:20Z tijl $ */ +/* $NetBSD: citrus_iconv_local.h,v 1.3 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_ICONV_LOCAL_H_ +#define _CITRUS_ICONV_LOCAL_H_ + +#include +#include + +#define _CITRUS_ICONV_GETOPS_FUNC_BASE(_n_) \ + int _n_(struct _citrus_iconv_ops *) +#define _CITRUS_ICONV_GETOPS_FUNC(_n_) \ + _CITRUS_ICONV_GETOPS_FUNC_BASE(_citrus_##_n_##_iconv_getops) + +#define _CITRUS_ICONV_DECLS(_m_) \ +static int _citrus_##_m_##_iconv_init_shared \ + (struct _citrus_iconv_shared * __restrict, \ + const char * __restrict, const char * __restrict); \ +static void _citrus_##_m_##_iconv_uninit_shared \ + (struct _citrus_iconv_shared *); \ +static int _citrus_##_m_##_iconv_convert \ + (struct _citrus_iconv * __restrict, \ + char * __restrict * __restrict, \ + size_t * __restrict, \ + char * __restrict * __restrict, \ + size_t * __restrict outbytes, \ + uint32_t, size_t * __restrict); \ +static int _citrus_##_m_##_iconv_init_context \ + (struct _citrus_iconv *); \ +static void _citrus_##_m_##_iconv_uninit_context \ + (struct _citrus_iconv *) + + +#define _CITRUS_ICONV_DEF_OPS(_m_) \ +extern struct _citrus_iconv_ops _citrus_##_m_##_iconv_ops; \ +struct _citrus_iconv_ops _citrus_##_m_##_iconv_ops = { \ + /* io_init_shared */ &_citrus_##_m_##_iconv_init_shared, \ + /* io_uninit_shared */ &_citrus_##_m_##_iconv_uninit_shared, \ + /* io_init_context */ &_citrus_##_m_##_iconv_init_context, \ + /* io_uninit_context */ &_citrus_##_m_##_iconv_uninit_context, \ + /* io_convert */ &_citrus_##_m_##_iconv_convert \ +} + +typedef _CITRUS_ICONV_GETOPS_FUNC_BASE((*_citrus_iconv_getops_t)); +typedef int (*_citrus_iconv_init_shared_t) + (struct _citrus_iconv_shared * __restrict, + const char * __restrict, const char * __restrict); +typedef void (*_citrus_iconv_uninit_shared_t) + (struct _citrus_iconv_shared *); +typedef int (*_citrus_iconv_convert_t) + (struct _citrus_iconv * __restrict, + char *__restrict* __restrict, size_t * __restrict, + char * __restrict * __restrict, size_t * __restrict, uint32_t, + size_t * __restrict); +typedef int (*_citrus_iconv_init_context_t)(struct _citrus_iconv *); +typedef void (*_citrus_iconv_uninit_context_t)(struct _citrus_iconv *); + +struct _citrus_iconv_ops { + _citrus_iconv_init_shared_t io_init_shared; + _citrus_iconv_uninit_shared_t io_uninit_shared; + _citrus_iconv_init_context_t io_init_context; + _citrus_iconv_uninit_context_t io_uninit_context; + _citrus_iconv_convert_t io_convert; +}; + +struct _citrus_iconv_shared { + struct _citrus_iconv_ops *ci_ops; + void *ci_closure; + _CITRUS_HASH_ENTRY(_citrus_iconv_shared) ci_hash_entry; + TAILQ_ENTRY(_citrus_iconv_shared) ci_tailq_entry; + _citrus_module_t ci_module; + unsigned int ci_used_count; + char *ci_convname; + bool ci_discard_ilseq; + struct iconv_hooks *ci_hooks; + bool ci_ilseq_invalid; +}; + +struct _citrus_iconv { + struct _citrus_iconv_shared *cv_shared; + void *cv_closure; +}; + +#endif diff --git a/lib/libc/iconv/citrus_lock.h b/lib/libc/iconv/citrus_lock.h new file mode 100644 index 0000000..5107bb3 --- /dev/null +++ b/lib/libc/iconv/citrus_lock.h @@ -0,0 +1,33 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_lock.h 252584 2013-07-03 18:35:21Z peter $ */ +/*- + * Copyright (C) 2010 Gabor Kovesdan + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + +#define WLOCK(lock) if (__isthreaded) \ + pthread_rwlock_wrlock(lock); +#define UNLOCK(lock) if (__isthreaded) \ + pthread_rwlock_unlock(lock); diff --git a/lib/libc/iconv/citrus_lookup.c b/lib/libc/iconv/citrus_lookup.c new file mode 100644 index 0000000..980d8d9 --- /dev/null +++ b/lib/libc/iconv/citrus_lookup.c @@ -0,0 +1,362 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_lookup.c 263986 2014-04-01 10:36:11Z tijl $ */ +/* $NetBSD: citrus_lookup.c,v 1.7 2012/05/04 16:45:05 joerg Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_bcs.h" +#include "citrus_region.h" +#include "citrus_memstream.h" +#include "citrus_mmap.h" +#include "citrus_db.h" +#include "citrus_db_hash.h" +#include "citrus_lookup.h" +#include "citrus_lookup_file.h" + +struct _citrus_lookup { + union { + struct { + struct _citrus_db *db; + struct _citrus_region file; + int num, idx; + struct _db_locator locator; + } db; + struct { + struct _region r; + struct _memstream ms; + } plain; + } u; +#define cl_db u.db.db +#define cl_dbidx u.db.idx +#define cl_dbfile u.db.file +#define cl_dbnum u.db.num +#define cl_dblocator u.db.locator +#define cl_plainr u.plain.r +#define cl_plainms u.plain.ms + int cl_ignore_case; + int cl_rewind; + char *cl_key; + size_t cl_keylen; + int (*cl_next)(struct _citrus_lookup *, struct _region *, + struct _region *); + int (*cl_lookup)(struct _citrus_lookup *, const char *, + struct _region *); + int (*cl_num_entries)(struct _citrus_lookup *); + void (*cl_close)(struct _citrus_lookup *); +}; + +static int +seq_get_num_entries_db(struct _citrus_lookup *cl) +{ + + return (cl->cl_dbnum); +} + +static int +seq_next_db(struct _citrus_lookup *cl, struct _region *key, + struct _region *data) +{ + + if (cl->cl_key) { + if (key) + _region_init(key, cl->cl_key, cl->cl_keylen); + return (_db_lookup_by_s(cl->cl_db, cl->cl_key, data, + &cl->cl_dblocator)); + } + + if (cl->cl_rewind) { + cl->cl_dbidx = 0; + } + cl->cl_rewind = 0; + if (cl->cl_dbidx >= cl->cl_dbnum) + return (ENOENT); + + return (_db_get_entry(cl->cl_db, cl->cl_dbidx++, key, data)); +} + +static int +seq_lookup_db(struct _citrus_lookup *cl, const char *key, struct _region *data) +{ + + cl->cl_rewind = 0; + free(cl->cl_key); + cl->cl_key = strdup(key); + if (cl->cl_ignore_case) + _bcs_convert_to_lower(cl->cl_key); + cl->cl_keylen = strlen(cl->cl_key); + _db_locator_init(&cl->cl_dblocator); + return (_db_lookup_by_s(cl->cl_db, cl->cl_key, data, + &cl->cl_dblocator)); +} + +static void +seq_close_db(struct _citrus_lookup *cl) +{ + + _db_close(cl->cl_db); + _unmap_file(&cl->cl_dbfile); +} + +static int +seq_open_db(struct _citrus_lookup *cl, const char *name) +{ + struct _region r; + char path[PATH_MAX]; + int ret; + + snprintf(path, sizeof(path), "%s.db", name); + ret = _map_file(&r, path); + if (ret) + return (ret); + + ret = _db_open(&cl->cl_db, &r, _CITRUS_LOOKUP_MAGIC, + _db_hash_std, NULL); + if (ret) { + _unmap_file(&r); + return (ret); + } + + cl->cl_dbfile = r; + cl->cl_dbnum = _db_get_num_entries(cl->cl_db); + cl->cl_dbidx = 0; + cl->cl_rewind = 1; + cl->cl_lookup = &seq_lookup_db; + cl->cl_next = &seq_next_db; + cl->cl_num_entries = &seq_get_num_entries_db; + cl->cl_close = &seq_close_db; + + return (0); +} + +#define T_COMM '#' +static int +seq_next_plain(struct _citrus_lookup *cl, struct _region *key, + struct _region *data) +{ + const char *p, *q; + size_t len; + + if (cl->cl_rewind) + _memstream_bind(&cl->cl_plainms, &cl->cl_plainr); + cl->cl_rewind = 0; + +retry: + p = _memstream_getln(&cl->cl_plainms, &len); + if (p == NULL) + return (ENOENT); + /* ignore comment */ + q = memchr(p, T_COMM, len); + if (q) { + len = q - p; + } + /* ignore trailing spaces */ + _bcs_trunc_rws_len(p, &len); + p = _bcs_skip_ws_len(p, &len); + q = _bcs_skip_nonws_len(p, &len); + if (p == q) + goto retry; + if (cl->cl_key && ((size_t)(q - p) != cl->cl_keylen || + memcmp(p, cl->cl_key, (size_t)(q - p)) != 0)) + goto retry; + + /* found a entry */ + if (key) + _region_init(key, __DECONST(void *, p), (size_t)(q - p)); + p = _bcs_skip_ws_len(q, &len); + if (data) + _region_init(data, len ? __DECONST(void *, p) : NULL, len); + + return (0); +} + +static int +seq_get_num_entries_plain(struct _citrus_lookup *cl) +{ + int num; + + num = 0; + while (seq_next_plain(cl, NULL, NULL) == 0) + num++; + + return (num); +} + +static int +seq_lookup_plain(struct _citrus_lookup *cl, const char *key, + struct _region *data) +{ + size_t len; + const char *p; + + cl->cl_rewind = 0; + free(cl->cl_key); + cl->cl_key = strdup(key); + if (cl->cl_ignore_case) + _bcs_convert_to_lower(cl->cl_key); + cl->cl_keylen = strlen(cl->cl_key); + _memstream_bind(&cl->cl_plainms, &cl->cl_plainr); + p = _memstream_matchline(&cl->cl_plainms, cl->cl_key, &len, 0); + if (p == NULL) + return (ENOENT); + if (data) + _region_init(data, __DECONST(void *, p), len); + + return (0); +} + +static void +seq_close_plain(struct _citrus_lookup *cl) +{ + + _unmap_file(&cl->cl_plainr); +} + +static int +seq_open_plain(struct _citrus_lookup *cl, const char *name) +{ + int ret; + + /* open read stream */ + ret = _map_file(&cl->cl_plainr, name); + if (ret) + return (ret); + + cl->cl_rewind = 1; + cl->cl_next = &seq_next_plain; + cl->cl_lookup = &seq_lookup_plain; + cl->cl_num_entries = &seq_get_num_entries_plain; + cl->cl_close = &seq_close_plain; + + return (0); +} + +int +_citrus_lookup_seq_open(struct _citrus_lookup **rcl, const char *name, + int ignore_case) +{ + int ret; + struct _citrus_lookup *cl; + + cl = malloc(sizeof(*cl)); + if (cl == NULL) + return (errno); + + cl->cl_key = NULL; + cl->cl_keylen = 0; + cl->cl_ignore_case = ignore_case; + ret = seq_open_db(cl, name); + if (ret == ENOENT) + ret = seq_open_plain(cl, name); + if (!ret) + *rcl = cl; + else + free(cl); + + return (ret); +} + +void +_citrus_lookup_seq_rewind(struct _citrus_lookup *cl) +{ + + cl->cl_rewind = 1; + free(cl->cl_key); + cl->cl_key = NULL; + cl->cl_keylen = 0; +} + +int +_citrus_lookup_seq_next(struct _citrus_lookup *cl, + struct _region *key, struct _region *data) +{ + + return ((*cl->cl_next)(cl, key, data)); +} + +int +_citrus_lookup_seq_lookup(struct _citrus_lookup *cl, const char *key, + struct _region *data) +{ + + return ((*cl->cl_lookup)(cl, key, data)); +} + +int +_citrus_lookup_get_number_of_entries(struct _citrus_lookup *cl) +{ + + return ((*cl->cl_num_entries)(cl)); +} + +void +_citrus_lookup_seq_close(struct _citrus_lookup *cl) +{ + + free(cl->cl_key); + (*cl->cl_close)(cl); + free(cl); +} + +char * +_citrus_lookup_simple(const char *name, const char *key, + char *linebuf, size_t linebufsize, int ignore_case) +{ + struct _citrus_lookup *cl; + struct _region data; + int ret; + + ret = _citrus_lookup_seq_open(&cl, name, ignore_case); + if (ret) + return (NULL); + + ret = _citrus_lookup_seq_lookup(cl, key, &data); + if (ret) { + _citrus_lookup_seq_close(cl); + return (NULL); + } + + snprintf(linebuf, linebufsize, "%.*s", (int)_region_size(&data), + (const char *)_region_head(&data)); + + _citrus_lookup_seq_close(cl); + + return (linebuf); +} diff --git a/lib/libc/iconv/citrus_lookup.h b/lib/libc/iconv/citrus_lookup.h new file mode 100644 index 0000000..0976be2 --- /dev/null +++ b/lib/libc/iconv/citrus_lookup.h @@ -0,0 +1,64 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_lookup.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_lookup.h,v 1.2 2004/07/21 14:16:34 tshiozak Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_LOOKUP_H_ +#define _CITRUS_LOOKUP_H_ + +#define _CITRUS_LOOKUP_CASE_SENSITIVE 0 +#define _CITRUS_LOOKUP_CASE_IGNORE 1 + +struct _citrus_lookup; +__BEGIN_DECLS +char *_citrus_lookup_simple(const char *, const char *, char *, + size_t, int); +int _citrus_lookup_seq_open(struct _citrus_lookup **, + const char *, int); +void _citrus_lookup_seq_rewind(struct _citrus_lookup *); +int _citrus_lookup_seq_next(struct _citrus_lookup *, + struct _region *, struct _region *); +int _citrus_lookup_seq_lookup(struct _citrus_lookup *, + const char *, struct _region *); +int _citrus_lookup_get_number_of_entries(struct _citrus_lookup *); +void _citrus_lookup_seq_close(struct _citrus_lookup *); +__END_DECLS + +static __inline const char * +_citrus_lookup_alias(const char *path, const char *key, char *buf, size_t n, + int ignore_case) +{ + const char *ret; + + ret = _citrus_lookup_simple(path, key, buf, n, ignore_case); + if (ret == NULL) + ret = key; + + return (ret); +} + +#endif diff --git a/lib/libc/iconv/citrus_lookup_factory.c b/lib/libc/iconv/citrus_lookup_factory.c new file mode 100644 index 0000000..df9d257 --- /dev/null +++ b/lib/libc/iconv/citrus_lookup_factory.c @@ -0,0 +1,121 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_lookup_factory.c 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_lookup_factory.c,v 1.4 2003/10/27 00:12:42 lukem Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + +#include +#include +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_region.h" +#include "citrus_bcs.h" +#include "citrus_db_factory.h" +#include "citrus_db_hash.h" +#include "citrus_lookup_factory.h" +#include "citrus_lookup_file.h" + +#define T_COMM '#' +static int +convert_line(struct _citrus_db_factory *df, const char *line, size_t len) +{ + const char *p; + char data[LINE_MAX], key[LINE_MAX]; + + /* cut off trailing comment */ + p = memchr(line, T_COMM, len); + if (p) + len = p - line; + + /* key */ + line = _bcs_skip_ws_len(line, &len); + if (len == 0) + return (0); + p = _bcs_skip_nonws_len(line, &len); + if (p == line) + return (0); + snprintf(key, sizeof(key), "%.*s", (int)(p-line), line); + _bcs_convert_to_lower(key); + + /* data */ + line = _bcs_skip_ws_len(p, &len); + _bcs_trunc_rws_len(line, &len); + snprintf(data, sizeof(data), "%.*s", (int)len, line); + + return (_db_factory_addstr_by_s(df, key, data)); +} + +static int +dump_db(struct _citrus_db_factory *df, struct _region *r) +{ + void *ptr; + size_t size; + + size = _db_factory_calc_size(df); + ptr = malloc(size); + if (ptr == NULL) + return (errno); + _region_init(r, ptr, size); + + return (_db_factory_serialize(df, _CITRUS_LOOKUP_MAGIC, r)); +} + +int +_citrus_lookup_factory_convert(FILE *out, FILE *in) +{ + struct _citrus_db_factory *df; + struct _region r; + char *line; + size_t size; + int ret; + + ret = _db_factory_create(&df, &_db_hash_std, NULL); + if (ret) + return (ret); + + while ((line = fgetln(in, &size)) != NULL) + if ((ret = convert_line(df, line, size))) { + _db_factory_free(df); + return (ret); + } + + ret = dump_db(df, &r); + _db_factory_free(df); + if (ret) + return (ret); + + if (fwrite(_region_head(&r), _region_size(&r), 1, out) != 1) + return (errno); + + return (0); +} diff --git a/lib/libc/iconv/citrus_lookup_factory.h b/lib/libc/iconv/citrus_lookup_factory.h new file mode 100644 index 0000000..aae745b --- /dev/null +++ b/lib/libc/iconv/citrus_lookup_factory.h @@ -0,0 +1,37 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_lookup_factory.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_lookup_factory.h,v 1.1 2003/06/25 09:51:35 tshiozak Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_LOOKUP_FACTORY_H_ +#define _CITRUS_LOOKUP_FACTORY_H_ + +__BEGIN_DECLS +int _citrus_lookup_factory_convert(FILE *, FILE *); +__END_DECLS + +#endif diff --git a/lib/libc/iconv/citrus_lookup_file.h b/lib/libc/iconv/citrus_lookup_file.h new file mode 100644 index 0000000..7fac006 --- /dev/null +++ b/lib/libc/iconv/citrus_lookup_file.h @@ -0,0 +1,35 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_lookup_file.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_lookup_file.h,v 1.1 2003/06/25 09:51:36 tshiozak Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_LOOKUP_FILE_H_ +#define _CITRUS_LOOKUP_FILE_H_ + +#define _CITRUS_LOOKUP_MAGIC "LOOKUP\0\0" + +#endif diff --git a/lib/libc/iconv/citrus_mapper.c b/lib/libc/iconv/citrus_mapper.c new file mode 100644 index 0000000..dc604db --- /dev/null +++ b/lib/libc/iconv/citrus_mapper.c @@ -0,0 +1,405 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_mapper.c 263986 2014-04-01 10:36:11Z tijl $ */ +/* $NetBSD: citrus_mapper.c,v 1.10 2012/06/08 07:49:42 martin Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_types.h" +#include "citrus_region.h" +#include "citrus_lock.h" +#include "citrus_memstream.h" +#include "citrus_bcs.h" +#include "citrus_mmap.h" +#include "citrus_module.h" +#include "citrus_hash.h" +#include "citrus_mapper.h" + +#define _CITRUS_MAPPER_DIR "mapper.dir" + +#define CM_HASH_SIZE 101 +#define REFCOUNT_PERSISTENT -1 + +static pthread_rwlock_t cm_lock = PTHREAD_RWLOCK_INITIALIZER; + +struct _citrus_mapper_area { + _CITRUS_HASH_HEAD(, _citrus_mapper, CM_HASH_SIZE) ma_cache; + char *ma_dir; +}; + +/* + * _citrus_mapper_create_area: + * create mapper area + */ + +int +_citrus_mapper_create_area( + struct _citrus_mapper_area *__restrict *__restrict rma, + const char *__restrict area) +{ + struct _citrus_mapper_area *ma; + struct stat st; + char path[PATH_MAX]; + int ret; + + WLOCK(&cm_lock); + + if (*rma != NULL) { + ret = 0; + goto quit; + } + + snprintf(path, (size_t)PATH_MAX, "%s/%s", area, _CITRUS_MAPPER_DIR); + + ret = stat(path, &st); + if (ret) + goto quit; + + ma = malloc(sizeof(*ma)); + if (ma == NULL) { + ret = errno; + goto quit; + } + ma->ma_dir = strdup(area); + if (ma->ma_dir == NULL) { + ret = errno; + free(ma); + goto quit; + } + _CITRUS_HASH_INIT(&ma->ma_cache, CM_HASH_SIZE); + + *rma = ma; + ret = 0; +quit: + UNLOCK(&cm_lock); + + return (ret); +} + + +/* + * lookup_mapper_entry: + * lookup mapper.dir entry in the specified directory. + * + * line format of iconv.dir file: + * mapper module arg + * mapper : mapper name. + * module : mapper module name. + * arg : argument for the module (generally, description file name) + */ + +static int +lookup_mapper_entry(const char *dir, const char *mapname, void *linebuf, + size_t linebufsize, const char **module, const char **variable) +{ + struct _region r; + struct _memstream ms; + const char *cp, *cq; + char *p; + char path[PATH_MAX]; + size_t len; + int ret; + + /* create mapper.dir path */ + snprintf(path, (size_t)PATH_MAX, "%s/%s", dir, _CITRUS_MAPPER_DIR); + + /* open read stream */ + ret = _map_file(&r, path); + if (ret) + return (ret); + + _memstream_bind(&ms, &r); + + /* search the line matching to the map name */ + cp = _memstream_matchline(&ms, mapname, &len, 0); + if (!cp) { + ret = ENOENT; + goto quit; + } + if (!len || len > linebufsize - 1) { + ret = EINVAL; + goto quit; + } + + p = linebuf; + /* get module name */ + *module = p; + cq = _bcs_skip_nonws_len(cp, &len); + strlcpy(p, cp, (size_t)(cq - cp + 1)); + p += cq - cp + 1; + + /* get variable */ + *variable = p; + cp = _bcs_skip_ws_len(cq, &len); + strlcpy(p, cp, len + 1); + + ret = 0; + +quit: + _unmap_file(&r); + return (ret); +} + +/* + * mapper_close: + * simply close a mapper. (without handling hash) + */ +static void +mapper_close(struct _citrus_mapper *cm) +{ + if (cm->cm_module) { + if (cm->cm_ops) { + if (cm->cm_closure) + (*cm->cm_ops->mo_uninit)(cm); + free(cm->cm_ops); + } + _citrus_unload_module(cm->cm_module); + } + free(cm->cm_traits); + free(cm); +} + +/* + * mapper_open: + * simply open a mapper. (without handling hash) + */ +static int +mapper_open(struct _citrus_mapper_area *__restrict ma, + struct _citrus_mapper * __restrict * __restrict rcm, + const char * __restrict module, + const char * __restrict variable) +{ + struct _citrus_mapper *cm; + _citrus_mapper_getops_t getops; + int ret; + + /* initialize mapper handle */ + cm = malloc(sizeof(*cm)); + if (!cm) + return (errno); + + cm->cm_module = NULL; + cm->cm_ops = NULL; + cm->cm_closure = NULL; + cm->cm_traits = NULL; + cm->cm_refcount = 0; + cm->cm_key = NULL; + + /* load module */ + ret = _citrus_load_module(&cm->cm_module, module); + if (ret) + goto err; + + /* get operators */ + getops = (_citrus_mapper_getops_t) + _citrus_find_getops(cm->cm_module, module, "mapper"); + if (!getops) { + ret = EOPNOTSUPP; + goto err; + } + cm->cm_ops = malloc(sizeof(*cm->cm_ops)); + if (!cm->cm_ops) { + ret = errno; + goto err; + } + ret = (*getops)(cm->cm_ops); + if (ret) + goto err; + + if (!cm->cm_ops->mo_init || + !cm->cm_ops->mo_uninit || + !cm->cm_ops->mo_convert || + !cm->cm_ops->mo_init_state) { + ret = EINVAL; + goto err; + } + + /* allocate traits structure */ + cm->cm_traits = malloc(sizeof(*cm->cm_traits)); + if (cm->cm_traits == NULL) { + ret = errno; + goto err; + } + /* initialize the mapper */ + ret = (*cm->cm_ops->mo_init)(ma, cm, ma->ma_dir, + (const void *)variable, strlen(variable) + 1, + cm->cm_traits, sizeof(*cm->cm_traits)); + if (ret) + goto err; + + *rcm = cm; + + return (0); + +err: + mapper_close(cm); + return (ret); +} + +/* + * _citrus_mapper_open_direct: + * open a mapper. + */ +int +_citrus_mapper_open_direct(struct _citrus_mapper_area *__restrict ma, + struct _citrus_mapper * __restrict * __restrict rcm, + const char * __restrict module, const char * __restrict variable) +{ + + return (mapper_open(ma, rcm, module, variable)); +} + +/* + * hash_func + */ +static __inline int +hash_func(const char *key) +{ + + return (_string_hash_func(key, CM_HASH_SIZE)); +} + +/* + * match_func + */ +static __inline int +match_func(struct _citrus_mapper *cm, const char *key) +{ + + return (strcmp(cm->cm_key, key)); +} + +/* + * _citrus_mapper_open: + * open a mapper with looking up "mapper.dir". + */ +int +_citrus_mapper_open(struct _citrus_mapper_area *__restrict ma, + struct _citrus_mapper * __restrict * __restrict rcm, + const char * __restrict mapname) +{ + struct _citrus_mapper *cm; + char linebuf[PATH_MAX]; + const char *module, *variable; + int hashval, ret; + + variable = NULL; + + WLOCK(&cm_lock); + + /* search in the cache */ + hashval = hash_func(mapname); + _CITRUS_HASH_SEARCH(&ma->ma_cache, cm, cm_entry, match_func, mapname, + hashval); + if (cm) { + /* found */ + cm->cm_refcount++; + *rcm = cm; + ret = 0; + goto quit; + } + + /* search mapper entry */ + ret = lookup_mapper_entry(ma->ma_dir, mapname, linebuf, + (size_t)PATH_MAX, &module, &variable); + if (ret) + goto quit; + + /* open mapper */ + UNLOCK(&cm_lock); + ret = mapper_open(ma, &cm, module, variable); + WLOCK(&cm_lock); + if (ret) + goto quit; + cm->cm_key = strdup(mapname); + if (cm->cm_key == NULL) { + ret = errno; + _mapper_close(cm); + goto quit; + } + + /* insert to the cache */ + cm->cm_refcount = 1; + _CITRUS_HASH_INSERT(&ma->ma_cache, cm, cm_entry, hashval); + + *rcm = cm; + ret = 0; +quit: + UNLOCK(&cm_lock); + + return (ret); +} + +/* + * _citrus_mapper_close: + * close the specified mapper. + */ +void +_citrus_mapper_close(struct _citrus_mapper *cm) +{ + + if (cm) { + WLOCK(&cm_lock); + if (cm->cm_refcount == REFCOUNT_PERSISTENT) + goto quit; + if (cm->cm_refcount > 0) { + if (--cm->cm_refcount > 0) + goto quit; + _CITRUS_HASH_REMOVE(cm, cm_entry); + free(cm->cm_key); + } + UNLOCK(&cm_lock); + mapper_close(cm); + return; +quit: + UNLOCK(&cm_lock); + } +} + +/* + * _citrus_mapper_set_persistent: + * set persistent count. + */ +void +_citrus_mapper_set_persistent(struct _citrus_mapper * __restrict cm) +{ + + WLOCK(&cm_lock); + cm->cm_refcount = REFCOUNT_PERSISTENT; + UNLOCK(&cm_lock); +} diff --git a/lib/libc/iconv/citrus_mapper.h b/lib/libc/iconv/citrus_mapper.h new file mode 100644 index 0000000..aa2ad30 --- /dev/null +++ b/lib/libc/iconv/citrus_mapper.h @@ -0,0 +1,131 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_mapper.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_mapper.h,v 1.3 2003/07/12 15:39:19 tshiozak Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_MAPPER_H_ +#define _CITRUS_MAPPER_H_ + +struct _citrus_mapper_area; +struct _citrus_mapper; +struct _citrus_mapper_ops; +struct _citrus_mapper_traits; + +__BEGIN_DECLS +int _citrus_mapper_create_area( + struct _citrus_mapper_area *__restrict *__restrict, + const char *__restrict); +int _citrus_mapper_open(struct _citrus_mapper_area *__restrict, + struct _citrus_mapper *__restrict *__restrict, + const char *__restrict); +int _citrus_mapper_open_direct( + struct _citrus_mapper_area *__restrict, + struct _citrus_mapper *__restrict *__restrict, + const char *__restrict, const char *__restrict); +void _citrus_mapper_close(struct _citrus_mapper *); +void _citrus_mapper_set_persistent(struct _citrus_mapper * __restrict); +__END_DECLS + +#include "citrus_mapper_local.h" + +/* return values of _citrus_mapper_convert */ +#define _CITRUS_MAPPER_CONVERT_SUCCESS (0) +#define _CITRUS_MAPPER_CONVERT_NONIDENTICAL (1) +#define _CITRUS_MAPPER_CONVERT_SRC_MORE (2) +#define _CITRUS_MAPPER_CONVERT_DST_MORE (3) +#define _CITRUS_MAPPER_CONVERT_ILSEQ (4) +#define _CITRUS_MAPPER_CONVERT_FATAL (5) + +/* + * _citrus_mapper_convert: + * convert an index. + * - if the converter supports M:1 converter, the function may return + * _CITRUS_MAPPER_CONVERT_SRC_MORE and the storage pointed by dst + * may be unchanged in this case, although the internal status of + * the mapper is affected. + * - if the converter supports 1:N converter, the function may return + * _CITRUS_MAPPER_CONVERT_DST_MORE. In this case, the contiguous + * call of this function ignores src and changes the storage pointed + * by dst. + * - if the converter supports M:N converter, the function may behave + * the combination of the above. + * + */ +static __inline int +_citrus_mapper_convert(struct _citrus_mapper * __restrict cm, + _citrus_index_t * __restrict dst, _citrus_index_t src, + void * __restrict ps) +{ + + return ((*cm->cm_ops->mo_convert)(cm, dst, src, ps)); +} + +/* + * _citrus_mapper_init_state: + * initialize the state. + */ +static __inline void +_citrus_mapper_init_state(struct _citrus_mapper * __restrict cm) +{ + + (*cm->cm_ops->mo_init_state)(); +} + +/* + * _citrus_mapper_get_state_size: + * get the size of state storage. + */ +static __inline size_t +_citrus_mapper_get_state_size(struct _citrus_mapper * __restrict cm) +{ + + return (cm->cm_traits->mt_state_size); +} + +/* + * _citrus_mapper_get_src_max: + * get the maximum number of suspended sources. + */ +static __inline size_t +_citrus_mapper_get_src_max(struct _citrus_mapper * __restrict cm) +{ + + return (cm->cm_traits->mt_src_max); +} + +/* + * _citrus_mapper_get_dst_max: + * get the maximum number of suspended destinations. + */ +static __inline size_t +_citrus_mapper_get_dst_max(struct _citrus_mapper * __restrict cm) +{ + + return (cm->cm_traits->mt_dst_max); +} + +#endif diff --git a/lib/libc/iconv/citrus_mapper_local.h b/lib/libc/iconv/citrus_mapper_local.h new file mode 100644 index 0000000..d4eb2d0 --- /dev/null +++ b/lib/libc/iconv/citrus_mapper_local.h @@ -0,0 +1,97 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_mapper_local.h 250938 2013-05-23 18:07:01Z ed $ */ +/* $NetBSD: citrus_mapper_local.h,v 1.2 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_MAPPER_LOCAL_H_ +#define _CITRUS_MAPPER_LOCAL_H_ + +#define _CITRUS_MAPPER_GETOPS_FUNC_BASE(_n_) \ +int _n_(struct _citrus_mapper_ops *) +#define _CITRUS_MAPPER_GETOPS_FUNC(_n_) \ +_CITRUS_MAPPER_GETOPS_FUNC_BASE(_citrus_##_n_##_mapper_getops) + +#define _CITRUS_MAPPER_DECLS(_m_) \ +static int _citrus_##_m_##_mapper_init \ + (struct _citrus_mapper_area *__restrict, \ + struct _citrus_mapper * __restrict, \ + const char * __restrict, const void * __restrict, \ + size_t, struct _citrus_mapper_traits * __restrict, \ + size_t); \ +static void _citrus_##_m_##_mapper_uninit( \ + struct _citrus_mapper *); \ +static int _citrus_##_m_##_mapper_convert \ + (struct _citrus_mapper * __restrict, \ + _citrus_index_t * __restrict, _citrus_index_t, \ + void * __restrict); \ +static void _citrus_##_m_##_mapper_init_state \ + (void); + +#define _CITRUS_MAPPER_DEF_OPS(_m_) \ +extern struct _citrus_mapper_ops _citrus_##_m_##_mapper_ops; \ +struct _citrus_mapper_ops _citrus_##_m_##_mapper_ops = { \ + /* mo_init */ &_citrus_##_m_##_mapper_init, \ + /* mo_uninit */ &_citrus_##_m_##_mapper_uninit, \ + /* mo_convert */ &_citrus_##_m_##_mapper_convert, \ + /* mo_init_state */ &_citrus_##_m_##_mapper_init_state \ +} + +typedef _CITRUS_MAPPER_GETOPS_FUNC_BASE((*_citrus_mapper_getops_t)); +typedef int (*_citrus_mapper_init_t)( + struct _citrus_mapper_area *__restrict, + struct _citrus_mapper *__restrict, const char *__restrict, + const void *__restrict, size_t, + struct _citrus_mapper_traits * __restrict, size_t); +typedef void (*_citrus_mapper_uninit_t)(struct _citrus_mapper *); +typedef int (*_citrus_mapper_convert_t)(struct _citrus_mapper * __restrict, + _citrus_index_t * __restrict, _citrus_index_t, void * __restrict); +typedef void (*_citrus_mapper_init_state_t)(void); + +struct _citrus_mapper_ops { + _citrus_mapper_init_t mo_init; + _citrus_mapper_uninit_t mo_uninit; + _citrus_mapper_convert_t mo_convert; + _citrus_mapper_init_state_t mo_init_state; +}; + +struct _citrus_mapper_traits { + /* version 0x00000001 */ + size_t mt_state_size; + size_t mt_src_max; + size_t mt_dst_max; +}; + +struct _citrus_mapper { + struct _citrus_mapper_ops *cm_ops; + void *cm_closure; + _citrus_module_t cm_module; + struct _citrus_mapper_traits *cm_traits; + _CITRUS_HASH_ENTRY(_citrus_mapper) cm_entry; + int cm_refcount; + char *cm_key; +}; +#endif diff --git a/lib/libc/iconv/citrus_memstream.c b/lib/libc/iconv/citrus_memstream.c new file mode 100644 index 0000000..3484878 --- /dev/null +++ b/lib/libc/iconv/citrus_memstream.c @@ -0,0 +1,147 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_memstream.c 263986 2014-04-01 10:36:11Z tijl $ */ +/* $NetBSD: citrus_memstream.c,v 1.5 2012/03/13 21:13:31 christos Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_region.h" +#include "citrus_memstream.h" +#include "citrus_bcs.h" + +const char * +_citrus_memory_stream_getln(struct _citrus_memory_stream * __restrict ms, + size_t * __restrict rlen) +{ + const uint8_t *h, *p; + size_t i, ret; + + if (ms->ms_pos>=_region_size(&ms->ms_region)) + return (NULL); + + h = p = (uint8_t *)_region_offset(&ms->ms_region, ms->ms_pos); + ret = 0; + for (i = _region_size(&ms->ms_region) - ms->ms_pos; i > 0; i--) { + ret++; + if (_bcs_iseol(*p)) + break; + p++; + } + + ms->ms_pos += ret; + *rlen = ret; + return ((const char *)h); +} + +#define T_COMM '#' + +const char * +_citrus_memory_stream_matchline(struct _citrus_memory_stream * __restrict ms, + const char * __restrict key, size_t * __restrict rlen, int iscasesensitive) +{ + const char *p, *q; + size_t keylen, len; + + keylen = strlen(key); + for(;;) { + p = _citrus_memory_stream_getln(ms, &len); + if (p == NULL) + return (NULL); + + /* ignore comment */ + q = memchr(p, T_COMM, len); + if (q) { + len = q - p; + } + /* ignore trailing white space and newline */ + _bcs_trunc_rws_len(p, &len); + if (len == 0) + continue; /* ignore null line */ + + /* skip white spaces at the head of the line */ + p = _bcs_skip_ws_len(p, &len); + q = _bcs_skip_nonws_len(p, &len); + + if ((size_t)(q - p) == keylen) { + if (iscasesensitive) { + if (memcmp(key, p, keylen) == 0) + break; /* match */ + } else { + if (_bcs_strncasecmp(key, p, keylen) == 0) + break; /* match */ + } + } + } + + p = _bcs_skip_ws_len(q, &len); + *rlen = len; + + return (p); +} + +void * +_citrus_memory_stream_chr(struct _citrus_memory_stream *ms, + struct _citrus_region *r, char ch) +{ + void *chr, *head; + size_t sz; + + if (ms->ms_pos >= _region_size(&ms->ms_region)) + return (NULL); + + head = _region_offset(&ms->ms_region, ms->ms_pos); + chr = memchr(head, ch, _memstream_remainder(ms)); + if (chr == NULL) { + _region_init(r, head, _memstream_remainder(ms)); + ms->ms_pos = _region_size(&ms->ms_region); + return (NULL); + } + sz = (char *)chr - (char *)head; + + _region_init(r, head, sz); + ms->ms_pos += sz + 1; + + return (chr); +} + +void +_citrus_memory_stream_skip_ws(struct _citrus_memory_stream *ms) +{ + int ch; + + while ((ch = _memstream_peek(ms)) != EOF) { + if (!_bcs_isspace(ch)) + break; + _memstream_getc(ms); + } +} diff --git a/lib/libc/iconv/citrus_memstream.h b/lib/libc/iconv/citrus_memstream.h new file mode 100644 index 0000000..64ee7f1 --- /dev/null +++ b/lib/libc/iconv/citrus_memstream.h @@ -0,0 +1,226 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_memstream.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_memstream.h,v 1.3 2005/05/14 17:55:42 tshiozak Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + */ + +#ifndef _CITRUS_MEMSTREAM_H_ +#define _CITRUS_MEMSTREAM_H_ + +struct _citrus_memory_stream { + struct _citrus_region ms_region; + size_t ms_pos; +}; + +__BEGIN_DECLS +const char *_citrus_memory_stream_getln( + struct _citrus_memory_stream * __restrict, + size_t * __restrict); +const char *_citrus_memory_stream_matchline( + struct _citrus_memory_stream * __restrict, + const char * __restrict, size_t * __restrict, int); +void *_citrus_memory_stream_chr(struct _citrus_memory_stream *, + struct _citrus_region *, char); +void _citrus_memory_stream_skip_ws(struct _citrus_memory_stream *); +__END_DECLS + +static __inline int +_citrus_memory_stream_iseof(struct _citrus_memory_stream *ms) +{ + + return (ms->ms_pos >= _citrus_region_size(&ms->ms_region)); +} + +static __inline void +_citrus_memory_stream_bind(struct _citrus_memory_stream * __restrict ms, + const struct _citrus_region * __restrict r) +{ + + ms->ms_region = *r; + ms->ms_pos = 0; +} + +static __inline void +_citrus_memory_stream_bind_ptr(struct _citrus_memory_stream * __restrict ms, + void *ptr, size_t sz) +{ + struct _citrus_region r; + + _citrus_region_init(&r, ptr, sz); + _citrus_memory_stream_bind(ms, &r); +} + +static __inline void +_citrus_memory_stream_rewind(struct _citrus_memory_stream *ms) +{ + + ms->ms_pos = 0; +} + +static __inline size_t +_citrus_memory_stream_tell(struct _citrus_memory_stream *ms) +{ + + return (ms->ms_pos); +} + +static __inline size_t +_citrus_memory_stream_remainder(struct _citrus_memory_stream *ms) +{ + size_t sz; + + sz = _citrus_region_size(&ms->ms_region); + if (ms->ms_pos>sz) + return (0); + return (sz-ms->ms_pos); +} + +static __inline int +_citrus_memory_stream_seek(struct _citrus_memory_stream *ms, size_t pos, int w) +{ + size_t sz; + + sz = _citrus_region_size(&ms->ms_region); + + switch (w) { + case SEEK_SET: + if (pos >= sz) + return (-1); + ms->ms_pos = pos; + break; + case SEEK_CUR: + pos += (ssize_t)ms->ms_pos; + if (pos >= sz) + return (-1); + ms->ms_pos = pos; + break; + case SEEK_END: + if (sz < pos) + return (-1); + ms->ms_pos = sz - pos; + break; + } + return (0); +} + +static __inline int +_citrus_memory_stream_getc(struct _citrus_memory_stream *ms) +{ + + if (_citrus_memory_stream_iseof(ms)) + return (EOF); + return (_citrus_region_peek8(&ms->ms_region, ms->ms_pos++)); +} + +static __inline void +_citrus_memory_stream_ungetc(struct _citrus_memory_stream *ms, int ch) +{ + + if (ch != EOF && ms->ms_pos > 0) + ms->ms_pos--; +} + +static __inline int +_citrus_memory_stream_peek(struct _citrus_memory_stream *ms) +{ + + if (_citrus_memory_stream_iseof(ms)) + return (EOF); + return (_citrus_region_peek8(&ms->ms_region, ms->ms_pos)); +} + +static __inline void * +_citrus_memory_stream_getregion(struct _citrus_memory_stream *ms, + struct _citrus_region *r, size_t sz) +{ + void *ret; + + if (ms->ms_pos + sz > _citrus_region_size(&ms->ms_region)) + return (NULL); + + ret = _citrus_region_offset(&ms->ms_region, ms->ms_pos); + ms->ms_pos += sz; + if (r) + _citrus_region_init(r, ret, sz); + + return (ret); +} + +static __inline int +_citrus_memory_stream_get8(struct _citrus_memory_stream *ms, uint8_t *rval) +{ + + if (ms->ms_pos + 1 > _citrus_region_size(&ms->ms_region)) + return (-1); + + *rval = _citrus_region_peek8(&ms->ms_region, ms->ms_pos); + ms->ms_pos += 2; + + return (0); +} + +static __inline int +_citrus_memory_stream_get16(struct _citrus_memory_stream *ms, uint16_t *rval) +{ + + if (ms->ms_pos + 2 > _citrus_region_size(&ms->ms_region)) + return (-1); + + *rval = _citrus_region_peek16(&ms->ms_region, ms->ms_pos); + ms->ms_pos += 2; + + return (0); +} + +static __inline int +_citrus_memory_stream_get32(struct _citrus_memory_stream *ms, uint32_t *rval) +{ + + if (ms->ms_pos + 4 > _citrus_region_size(&ms->ms_region)) + return (-1); + + *rval = _citrus_region_peek32(&ms->ms_region, ms->ms_pos); + ms->ms_pos += 4; + + return (0); +} + +static __inline int +_citrus_memory_stream_getln_region(struct _citrus_memory_stream *ms, + struct _citrus_region *r) +{ + const char *ptr; + size_t sz; + + ptr = _citrus_memory_stream_getln(ms, &sz); + if (ptr) + _citrus_region_init(r, __DECONST(void *, ptr), sz); + + return (ptr == NULL); +} + +#endif diff --git a/lib/libc/iconv/citrus_mmap.c b/lib/libc/iconv/citrus_mmap.c new file mode 100644 index 0000000..8200503 --- /dev/null +++ b/lib/libc/iconv/citrus_mmap.c @@ -0,0 +1,95 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_mmap.c 292521 2015-12-20 23:05:20Z jilles $ */ +/* $NetBSD: citrus_mmap.c,v 1.4 2011/10/15 23:00:01 christos Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 "namespace.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "citrus_namespace.h" +#include "citrus_region.h" +#include "citrus_mmap.h" + +int +_citrus_map_file(struct _citrus_region * __restrict r, + const char * __restrict path) +{ + struct stat st; + void *head; + int fd, ret; + + ret = 0; + + _region_init(r, NULL, 0); + + if ((fd = _open(path, O_RDONLY | O_CLOEXEC)) == -1) + return (errno); + + if (_fstat(fd, &st) == -1) { + ret = errno; + goto error; + } + if (!S_ISREG(st.st_mode)) { + ret = EOPNOTSUPP; + goto error; + } + + head = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_FILE|MAP_PRIVATE, + fd, (off_t)0); + if (head == MAP_FAILED) { + ret = errno; + goto error; + } + _region_init(r, head, (size_t)st.st_size); + +error: + (void)_close(fd); + return (ret); +} + +void +_citrus_unmap_file(struct _citrus_region *r) +{ + + if (_region_head(r) != NULL) { + (void)munmap(_region_head(r), _region_size(r)); + _region_init(r, NULL, 0); + } +} diff --git a/lib/libc/iconv/citrus_mmap.h b/lib/libc/iconv/citrus_mmap.h new file mode 100644 index 0000000..c2952e7 --- /dev/null +++ b/lib/libc/iconv/citrus_mmap.h @@ -0,0 +1,40 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_mmap.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_mmap.h,v 1.1 2003/06/25 09:51:38 tshiozak Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + */ + +#ifndef _CITRUS_MMAP_H_ +#define _CITRUS_MMAP_H_ + +__BEGIN_DECLS +int _citrus_map_file(struct _citrus_region * __restrict, + const char * __restrict); +void _citrus_unmap_file(struct _citrus_region *); +__END_DECLS + +#endif diff --git a/lib/libc/iconv/citrus_module.c b/lib/libc/iconv/citrus_module.c new file mode 100644 index 0000000..3ed4f31 --- /dev/null +++ b/lib/libc/iconv/citrus_module.c @@ -0,0 +1,315 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_module.c 228843 2011-12-23 15:00:37Z cperciva $ */ +/* $NetBSD: citrus_module.c,v 1.9 2009/01/11 02:46:24 christos Exp $ */ + +/*- + * Copyright (c)1999, 2000, 2001, 2002 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Paul Kranenburg. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define I18NMODULE_MAJOR 4 + +#include "citrus_namespace.h" +#include "citrus_bcs.h" +#include "citrus_module.h" +#include "libc_private.h" + +static int _getdewey(int[], char *); +static int _cmpndewey(int[], int, int[], int); +static const char *_findshlib(char *, int *, int *); + +static const char *_pathI18nModule = NULL; + +/* from libexec/ld.aout_so/shlib.c */ +#undef major +#undef minor +#define MAXDEWEY 3 /*ELF*/ + +static int +_getdewey(int dewey[], char *cp) +{ + int i, n; + + for (n = 0, i = 0; i < MAXDEWEY; i++) { + if (*cp == '\0') + break; + + if (*cp == '.') cp++; + if (*cp < '0' || '9' < *cp) + return (0); + + dewey[n++] = (int)_bcs_strtol(cp, &cp, 10); + } + + return (n); +} + +/* + * Compare two dewey arrays. + * Return -1 if `d1' represents a smaller value than `d2'. + * Return 1 if `d1' represents a greater value than `d2'. + * Return 0 if equal. + */ +static int +_cmpndewey(int d1[], int n1, int d2[], int n2) +{ + int i; + + for (i = 0; i < n1 && i < n2; i++) { + if (d1[i] < d2[i]) + return (-1); + if (d1[i] > d2[i]) + return (1); + } + + if (n1 == n2) + return (0); + + if (i == n1) + return (-1); + + if (i == n2) + return (1); + + /* cannot happen */ + return (0); +} + +static const char * +_findshlib(char *name, int *majorp, int *minorp) +{ + char *lname; + const char *search_dirs[1]; + static char path[PATH_MAX]; + int dewey[MAXDEWEY], tmp[MAXDEWEY]; + int i, len, major, minor, ndewey, n_search_dirs; + + n_search_dirs = 1; + major = *majorp; + minor = *minorp; + path[0] = '\0'; + search_dirs[0] = _pathI18nModule; + len = strlen(name); + lname = name; + + ndewey = 0; + + for (i = 0; i < n_search_dirs; i++) { + struct dirent *dp; + DIR *dd = opendir(search_dirs[i]); + int found_dot_a = 0, found_dot_so = 0; + + if (dd == NULL) + break; + + while ((dp = readdir(dd)) != NULL) { + int n; + + if (dp->d_namlen < len + 4) + continue; + if (strncmp(dp->d_name, lname, (size_t)len) != 0) + continue; + if (strncmp(dp->d_name+len, ".so.", 4) != 0) + continue; + + if ((n = _getdewey(tmp, dp->d_name+len+4)) == 0) + continue; + + if (major != -1 && found_dot_a) + found_dot_a = 0; + + /* XXX should verify the library is a.out/ELF? */ + + if (major == -1 && minor == -1) + goto compare_version; + else if (major != -1 && minor == -1) { + if (tmp[0] == major) + goto compare_version; + } else if (major != -1 && minor != -1) { + if (tmp[0] == major) { + if (n == 1 || tmp[1] >= minor) + goto compare_version; + } + } + + /* else, this file does not qualify */ + continue; + + compare_version: + if (_cmpndewey(tmp, n, dewey, ndewey) <= 0) + continue; + + /* We have a better version */ + found_dot_so = 1; + snprintf(path, sizeof(path), "%s/%s", search_dirs[i], + dp->d_name); + found_dot_a = 0; + bcopy(tmp, dewey, sizeof(dewey)); + ndewey = n; + *majorp = dewey[0]; + *minorp = dewey[1]; + } + closedir(dd); + + if (found_dot_a || found_dot_so) + /* + * There's a lib in this dir; take it. + */ + return (path[0] ? path : NULL); + } + + return (path[0] ? path : NULL); +} + +void * +_citrus_find_getops(_citrus_module_t handle, const char *modname, + const char *ifname) +{ + char name[PATH_MAX]; + void *p; + + snprintf(name, sizeof(name), "_citrus_%s_%s_getops", + modname, ifname); + p = dlsym((void *)handle, name); + return (p); +} + +int +_citrus_load_module(_citrus_module_t *rhandle, const char *encname) +{ + const char *p; + char path[PATH_MAX]; + void *handle; + int maj, min; + + if (_pathI18nModule == NULL) { + p = getenv("PATH_I18NMODULE"); + if (p != NULL && !issetugid()) { + _pathI18nModule = strdup(p); + if (_pathI18nModule == NULL) + return (ENOMEM); + } else + _pathI18nModule = _PATH_I18NMODULE; + } + + (void)snprintf(path, sizeof(path), "lib%s", encname); + maj = I18NMODULE_MAJOR; + min = -1; + p = _findshlib(path, &maj, &min); + if (!p) + return (EINVAL); + handle = libc_dlopen(p, RTLD_LAZY); + if (!handle) { + printf("%s", dlerror()); + return (EINVAL); + } + + *rhandle = (_citrus_module_t)handle; + + return (0); +} + +void +_citrus_unload_module(_citrus_module_t handle) +{ + + if (handle) + dlclose((void *)handle); +} diff --git a/lib/libc/iconv/citrus_module.h b/lib/libc/iconv/citrus_module.h new file mode 100644 index 0000000..981fff5 --- /dev/null +++ b/lib/libc/iconv/citrus_module.h @@ -0,0 +1,54 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_module.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_module.h,v 1.1 2002/03/17 22:14:20 tshiozak Exp $ */ + +/*- + * Copyright (c)2002 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + */ + +#ifndef _CITRUS_MODULE_H_ +#define _CITRUS_MODULE_H_ + +#define MATCH(x, act) \ +do { \ + if (lenvar >= (sizeof(#x)-1) && \ + _bcs_strncasecmp(p, #x, sizeof(#x)-1) == 0) { \ + act; \ + lenvar -= sizeof(#x)-1; \ + p += sizeof(#x)-1; \ + } \ +} while (0) + +typedef struct _citrus_module_rec *_citrus_module_t; + +__BEGIN_DECLS +void *_citrus_find_getops(_citrus_module_t __restrict, + const char * __restrict, const char * __restrict); +int _citrus_load_module(_citrus_module_t * __restrict, + const char * __restrict); +void _citrus_unload_module(_citrus_module_t); +__END_DECLS + +#endif diff --git a/lib/libc/iconv/citrus_namespace.h b/lib/libc/iconv/citrus_namespace.h new file mode 100644 index 0000000..19e0a5e --- /dev/null +++ b/lib/libc/iconv/citrus_namespace.h @@ -0,0 +1,241 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_namespace.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_namespace.h,v 1.8 2009/01/11 02:46:24 christos Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 "citrus_bcs.h" + +#ifndef _CITRUS_NAMESPACE_H_ +#define _CITRUS_NAMESPACE_H_ + +/* citrus_alias */ +#ifndef _CITRUS_ALIAS_NO_NAMESPACE +#define _alias_lookup _citrus_alias_lookup +#endif /* _CITRUS_ALIAS_NO_NAMESPACE */ + +/* citrus_bcs */ +#ifndef _CITRUS_BCS_NO_NAMESPACE +#define _bcs_isalnum _citrus_bcs_isalnum +#define _bcs_isalpha _citrus_bcs_isalpha +#define _bcs_isblank _citrus_bcs_isblank +#define _bcs_isdigit _citrus_bcs_isdigit +#define _bcs_islower _citrus_bcs_islower +#define _bcs_iseol _citrus_bcs_iseol +#define _bcs_isspace _citrus_bcs_isspace +#define _bcs_isupper _citrus_bcs_isupper +#define _bcs_isxdigit _citrus_bcs_isxdigit +#define _bcs_skip_nonws _citrus_bcs_skip_nonws +#define _bcs_skip_nonws_len _citrus_bcs_skip_nonws_len +#define _bcs_skip_ws _citrus_bcs_skip_ws +#define _bcs_skip_ws_len _citrus_bcs_skip_ws_len +#define _bcs_strcasecmp _citrus_bcs_strcasecmp +#define _bcs_strncasecmp _citrus_bcs_strncasecmp +#define _bcs_tolower _citrus_bcs_tolower +#define _bcs_toupper _citrus_bcs_toupper +#define _bcs_trunc_rws_len _citrus_bcs_trunc_rws_len +#define _bcs_convert_to_lower _citrus_bcs_convert_to_lower +#define _bcs_convert_to_upper _citrus_bcs_convert_to_upper +#define _bcs_strtol _citrus_bcs_strtol +#define _bcs_strtoul _citrus_bcs_strtoul +#endif /* _CITRUS_BCS_NO_NAMESPACE */ + +/* citrus_csmapper */ +#ifndef _CITRUS_CSMAPPER_NO_NAMESPACE +#define _csmapper _citrus_csmapper +#define _csmapper_open _citrus_csmapper_open +#define _csmapper_close _citrus_csmapper_close +#define _csmapper_convert _citrus_csmapper_convert +#define _csmapper_init_state _citrus_csmapper_init_state +#define _csmapper_get_state_size _citrus_csmapper_get_state_size +#define _csmapper_get_src_max _citrus_csmapper_get_src_max +#define _csmapper_get_dst_max _citrus_csmapper_get_dst_max +#define _CSMAPPER_F_PREVENT_PIVOT _CITRUS_CSMAPPER_F_PREVENT_PIVOT +#endif /* _CITRUS_CSMAPPER_NO_NAMESPACE */ + +/* citrus_db */ +#ifndef _CITRUS_DB_NO_NAMESPACE +#define _db_open _citrus_db_open +#define _db_close _citrus_db_close +#define _db_lookup _citrus_db_lookup +#define _db_lookup_by_s _citrus_db_lookup_by_string +#define _db_lookup8_by_s _citrus_db_lookup8_by_string +#define _db_lookup16_by_s _citrus_db_lookup16_by_string +#define _db_lookup32_by_s _citrus_db_lookup32_by_string +#define _db_lookupstr_by_s _citrus_db_lookup_string_by_string +#define _db_hash_std _citrus_db_hash_std +#define _db_get_num_entries _citrus_db_get_number_of_entries +#define _db_get_entry _citrus_db_get_entry +#define _db_locator _citrus_db_locator +#define _db_locator_init _citrus_db_locator_init +#endif /* _CITRUS_DB_NO_NAMESPACE */ + +/* citrus_db_factory */ +#ifndef _CITRUS_DB_FACTORY_NO_NAMESPACE +#define _db_factory _citrus_db_factory +#define _db_factory_create _citrus_db_factory_create +#define _db_factory_free _citrus_db_factory_free +#define _db_factory_add _citrus_db_factory_add +#define _db_factory_add_by_s _citrus_db_factory_add_by_string +#define _db_factory_add8_by_s _citrus_db_factory_add8_by_string +#define _db_factory_add16_by_s _citrus_db_factory_add16_by_string +#define _db_factory_add32_by_s _citrus_db_factory_add32_by_string +#define _db_factory_addstr_by_s _citrus_db_factory_add_string_by_string +#define _db_factory_calc_size _citrus_db_factory_calc_size +#define _db_factory_serialize _citrus_db_factory_serialize +#endif /* _CITRUS_DB_FACTORY_NO_NAMESPACE */ + +/* citrus_lookup */ +#ifndef _CITRUS_DB_NO_NAMESPACE +#define _LOOKUP_CASE_SENSITIVE _CITRUS_LOOKUP_CASE_SENSITIVE +#define _LOOKUP_CASE_IGNORE _CITRUS_LOOKUP_CASE_IGNORE +#define _lookup _citrus_lookup +#define _lookup_simple _citrus_lookup_simple +#define _lookup_alias _citrus_lookup_alias +#define _lookup_seq_open _citrus_lookup_seq_open +#define _lookup_seq_rewind _citrus_lookup_seq_rewind +#define _lookup_seq_next _citrus_lookup_seq_next +#define _lookup_seq_lookup _citrus_lookup_seq_lookup +#define _lookup_get_num_entries _citrus_lookup_get_number_of_entries +#define _lookup_seq_close _citrus_lookup_seq_close +#define _lookup_factory_convert _citrus_lookup_factory_convert +#endif /* _CITRUS_DB_NO_NAMESPACE */ + +/* citrus_esdb */ +#ifndef _CITRUS_ESDB_NO_NAMESPACE +#define _esdb _citrus_esdb +#define _esdb_charset _citrus_esdb_charset +#define _esdb_open _citrus_esdb_open +#define _esdb_close _citrus_esdb_close +#define _esdb_get_list _citrus_esdb_get_list +#define _esdb_free_list _citrus_esdb_free_list +#endif /* _CITRUS_ESDB_NO_NAMESPACE */ + +/* citrus_hash */ +#ifndef _CITRUS_HASH_NO_NAMESPACE +#define _citrus_string_hash_func _string_hash_func +#endif /* _CITRUS_HASH_NO_NAMESPACE */ + +/* citrus_mapper */ +#ifndef _CITRUS_MAPPER_NO_NAMESPACE +#define _mapper _citrus_mapper +#define _mapper_ops _citrus_mapper_ops +#define _mapper_traits _citrus_mapper_traits +#define _mapper_open _citrus_mapper_open +#define _mapper_open_direct _citrus_mapper_open_direct +#define _mapper_close _citrus_mapper_close +#define _MAPPER_CONVERT_SUCCESS _CITRUS_MAPPER_CONVERT_SUCCESS +#define _MAPPER_CONVERT_NONIDENTICAL _CITRUS_MAPPER_CONVERT_NONIDENTICAL +#define _MAPPER_CONVERT_SRC_MORE _CITRUS_MAPPER_CONVERT_SRC_MORE +#define _MAPPER_CONVERT_DST_MORE _CITRUS_MAPPER_CONVERT_DST_MORE +#define _MAPPER_CONVERT_ILSEQ _CITRUS_MAPPER_CONVERT_ILSEQ +#define _MAPPER_CONVERT_FATAL _CITRUS_MAPPER_CONVERT_FATAL +#define _mapper_convert _citrus_mapper_convert +#define _mapper_init_state _citrus_mapper_init_state +#define _mapper_get_state_size _citrus_mapper_get_state_size +#define _mapper_get_src_max _citrus_mapper_get_src_max +#define _mapper_get_dst_max _citrus_mapper_get_dst_max +#define _mapper_set_persistent _citrus_mapper_set_persistent +#endif /* _CITRUS_MAPPER_NO_NAMESPACE */ + +/* citrus_memstream */ +#ifndef _CITRUS_MEMSTREAM_NO_NAMESPACE +#define _memstream _citrus_memory_stream +#define _memstream_getln _citrus_memory_stream_getln +#define _memstream_matchline _citrus_memory_stream_matchline +#define _memstream_chr _citrus_memory_stream_chr +#define _memstream_skip_ws _citrus_memory_stream_skip_ws +#define _memstream_iseof _citrus_memory_stream_iseof +#define _memstream_bind _citrus_memory_stream_bind +#define _memstream_bind_ptr _citrus_memory_stream_bind_ptr +#define _memstream_seek _citrus_memory_stream_seek +#define _memstream_rewind _citrus_memory_stream_rewind +#define _memstream_tell _citrus_memory_stream_tell +#define _memstream_remainder _citrus_memory_stream_remainder +#define _memstream_getc _citrus_memory_stream_getc +#define _memstream_ungetc _citrus_memory_stream_ungetc +#define _memstream_peek _citrus_memory_stream_peek +#define _memstream_getregion _citrus_memory_stream_getregion +#define _memstream_getln_region _citrus_memory_stream_getln_region +#endif /* _CITRUS_MEMSTREAM_NO_NAMESPACE */ + +/* citrus_mmap */ +#ifndef _CITRUS_MMAP_NO_NAMESPACE +#define _map_file _citrus_map_file +#define _unmap_file _citrus_unmap_file +#endif /* _CITRUS_MMAP_NO_NAMESPACE */ + +#ifndef _CITRUS_PIVOT_NO_NAMESPACE +#define _pivot_factory_convert _citrus_pivot_factory_convert +#endif /* _CITRUS_PIVOT_NO_NAMESPACE */ + +/* citrus_region.h */ +#ifndef _CITRUS_REGION_NO_NAMESPACE +#define _region _citrus_region +#define _region_init _citrus_region_init +#define _region_head _citrus_region_head +#define _region_size _citrus_region_size +#define _region_check _citrus_region_check +#define _region_offset _citrus_region_offset +#define _region_peek8 _citrus_region_peek8 +#define _region_peek16 _citrus_region_peek16 +#define _region_peek32 _citrus_region_peek32 +#define _region_get_subregion _citrus_region_get_subregion +#endif /* _CITRUS_REGION_NO_NAMESPACE */ + +/* citrus_stdenc.h */ +#ifndef _CITRUS_STDENC_NO_NAMESPACE +#define _stdenc _citrus_stdenc +#define _stdenc_ops _citrus_stdenc_ops +#define _stdenc_traits _citrus_stdenc_traits +#define _stdenc_state_desc _citrus_stdenc_state_desc +#define _stdenc_open _citrus_stdenc_open +#define _stdenc_close _citrus_stdenc_close +#define _stdenc_init_state _citrus_stdenc_init_state +#define _stdenc_mbtocs _citrus_stdenc_mbtocs +#define _stdenc_cstomb _citrus_stdenc_cstomb +#define _stdenc_mbtowc _citrus_stdenc_mbtowc +#define _stdenc_wctomb _citrus_stdenc_wctomb +#define _stdenc_put_state_reset _citrus_stdenc_put_state_reset +#define _stdenc_get_state_size _citrus_stdenc_get_state_size +#define _stdenc_get_mb_cur_max _citrus_stdenc_get_mb_cur_max +#define _stdenc_get_state_desc _citrus_stdenc_get_state_desc +#define _STDENC_SDID_GENERIC _CITRUS_STDENC_SDID_GENERIC +#define _STDENC_SDGEN_UNKNOWN _CITRUS_STDENC_SDGEN_UNKNOWN +#define _STDENC_SDGEN_INITIAL _CITRUS_STDENC_SDGEN_INITIAL +#define _STDENC_SDGEN_STABLE _CITRUS_STDENC_SDGEN_STABLE +#define _STDENC_SDGEN_INCOMPLETE_CHAR _CITRUS_STDENC_SDGEN_INCOMPLETE_CHAR +#define _STDENC_SDGEN_INCOMPLETE_SHIFT _CITRUS_STDENC_SDGEN_INCOMPLETE_SHIFT +#endif /* _CITRUS_STDENC_NO_NAMESPACE */ + +/* citrus_types.h */ +#ifndef _CITRUS_TYPES_NO_NAMESPACE +#define _index_t _citrus_index_t +#define _csid_t _citrus_csid_t +#define _wc_t _citrus_wc_t +#endif /* _CITRUS_TYPES_NO_NAMESPACE */ + +#endif diff --git a/lib/libc/iconv/citrus_none.c b/lib/libc/iconv/citrus_none.c new file mode 100644 index 0000000..029e888 --- /dev/null +++ b/lib/libc/iconv/citrus_none.c @@ -0,0 +1,237 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_none.c 281550 2015-04-15 09:09:20Z tijl $ */ +/* $NetBSD: citrus_none.c,v 1.18 2008/06/14 16:01:07 tnozaki Exp $ */ + +/*- + * Copyright (c) 2002 Citrus Project, + * Copyright (c) 2010 Gabor Kovesdan , + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_types.h" +#include "citrus_module.h" +#include "citrus_none.h" +#include "citrus_stdenc.h" + +_CITRUS_STDENC_DECLS(NONE); +_CITRUS_STDENC_DEF_OPS(NONE); +struct _citrus_stdenc_traits _citrus_NONE_stdenc_traits = { + 0, /* et_state_size */ + 1, /* mb_cur_max */ +}; + +static int +_citrus_NONE_stdenc_init(struct _citrus_stdenc * __restrict ce, + const void *var __unused, size_t lenvar __unused, + struct _citrus_stdenc_traits * __restrict et) +{ + + et->et_state_size = 0; + et->et_mb_cur_max = 1; + + ce->ce_closure = NULL; + + return (0); +} + +static void +_citrus_NONE_stdenc_uninit(struct _citrus_stdenc *ce __unused) +{ + +} + +static int +_citrus_NONE_stdenc_init_state(struct _citrus_stdenc * __restrict ce __unused, + void * __restrict ps __unused) +{ + + return (0); +} + +static int +_citrus_NONE_stdenc_mbtocs(struct _citrus_stdenc * __restrict ce __unused, + _csid_t *csid, _index_t *idx, char **s, size_t n, + void *ps __unused, size_t *nresult, struct iconv_hooks *hooks) +{ + + if (n < 1) { + *nresult = (size_t)-2; + return (0); + } + + *csid = 0; + *idx = (_index_t)(unsigned char)*(*s)++; + *nresult = *idx == 0 ? 0 : 1; + + if ((hooks != NULL) && (hooks->uc_hook != NULL)) + hooks->uc_hook((unsigned int)*idx, hooks->data); + + return (0); +} + +static int +_citrus_NONE_stdenc_cstomb(struct _citrus_stdenc * __restrict ce __unused, + char *s, size_t n, _csid_t csid, _index_t idx, void *ps __unused, + size_t *nresult, struct iconv_hooks *hooks __unused) +{ + + if (csid == _CITRUS_CSID_INVALID) { + *nresult = 0; + return (0); + } + if (csid != 0) + return (EILSEQ); + + if ((idx & 0x000000FF) == idx) { + if (n < 1) { + *nresult = (size_t)-1; + return (E2BIG); + } + *s = (char)idx; + *nresult = 1; + } else if ((idx & 0x0000FFFF) == idx) { + if (n < 2) { + *nresult = (size_t)-1; + return (E2BIG); + } + s[0] = (char)idx; + /* XXX: might be endian dependent */ + s[1] = (char)(idx >> 8); + *nresult = 2; + } else if ((idx & 0x00FFFFFF) == idx) { + if (n < 3) { + *nresult = (size_t)-1; + return (E2BIG); + } + s[0] = (char)idx; + /* XXX: might be endian dependent */ + s[1] = (char)(idx >> 8); + s[2] = (char)(idx >> 16); + *nresult = 3; + } else { + if (n < 3) { + *nresult = (size_t)-1; + return (E2BIG); + } + s[0] = (char)idx; + /* XXX: might be endian dependent */ + s[1] = (char)(idx >> 8); + s[2] = (char)(idx >> 16); + s[3] = (char)(idx >> 24); + *nresult = 4; + } + + return (0); +} + +static int +_citrus_NONE_stdenc_mbtowc(struct _citrus_stdenc * __restrict ce __unused, + _wc_t * __restrict pwc, char ** __restrict s, size_t n, + void * __restrict pspriv __unused, size_t * __restrict nresult, + struct iconv_hooks *hooks) +{ + + if (s == NULL) { + *nresult = 0; + return (0); + } + if (n == 0) { + *nresult = (size_t)-2; + return (0); + } + + if (pwc != NULL) + *pwc = (_wc_t)(unsigned char) **s; + + *nresult = *s == '\0' ? 0 : 1; + + if ((hooks != NULL) && (hooks->wc_hook != NULL)) + hooks->wc_hook(*pwc, hooks->data); + + return (0); +} + +static int +_citrus_NONE_stdenc_wctomb(struct _citrus_stdenc * __restrict ce __unused, + char * __restrict s, size_t n, _wc_t wc, + void * __restrict pspriv __unused, size_t * __restrict nresult, + struct iconv_hooks *hooks __unused) +{ + + if ((wc & ~0xFFU) != 0) { + *nresult = (size_t)-1; + return (EILSEQ); + } + if (n == 0) { + *nresult = (size_t)-1; + return (E2BIG); + } + + *nresult = 1; + if (s != NULL && n > 0) + *s = (char)wc; + + return (0); +} + +static int +_citrus_NONE_stdenc_put_state_reset(struct _citrus_stdenc * __restrict ce __unused, + char * __restrict s __unused, size_t n __unused, + void * __restrict pspriv __unused, size_t * __restrict nresult) +{ + + *nresult = 0; + + return (0); +} + +static int +_citrus_NONE_stdenc_get_state_desc(struct _stdenc * __restrict ce __unused, + void * __restrict ps __unused, int id, + struct _stdenc_state_desc * __restrict d) +{ + int ret = 0; + + switch (id) { + case _STDENC_SDID_GENERIC: + d->u.generic.state = _STDENC_SDGEN_INITIAL; + break; + default: + ret = EOPNOTSUPP; + } + + return (ret); +} diff --git a/lib/libc/iconv/citrus_none.h b/lib/libc/iconv/citrus_none.h new file mode 100644 index 0000000..a61adc0 --- /dev/null +++ b/lib/libc/iconv/citrus_none.h @@ -0,0 +1,36 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_none.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_none.h,v 1.3 2003/06/25 09:51:38 tshiozak Exp $ */ + +/*- + * Copyright (c)2002 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_NONE_H_ +#define _CITRUS_NONE_H_ + +extern struct _citrus_stdenc_ops _citrus_NONE_stdenc_ops; +extern struct _citrus_stdenc_traits _citrus_NONE_stdenc_traits; + +#endif diff --git a/lib/libc/iconv/citrus_pivot_factory.c b/lib/libc/iconv/citrus_pivot_factory.c new file mode 100644 index 0000000..76f2881 --- /dev/null +++ b/lib/libc/iconv/citrus_pivot_factory.c @@ -0,0 +1,225 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_pivot_factory.c 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_pivot_factory.c,v 1.7 2009/04/12 14:20:19 lukem Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_region.h" +#include "citrus_bcs.h" +#include "citrus_db_factory.h" +#include "citrus_db_hash.h" +#include "citrus_pivot_file.h" +#include "citrus_pivot_factory.h" + +struct src_entry { + char *se_name; + struct _citrus_db_factory *se_df; + STAILQ_ENTRY(src_entry) se_entry; +}; +STAILQ_HEAD(src_head, src_entry); + +static int +find_src(struct src_head *sh, struct src_entry **rse, const char *name) +{ + int ret; + struct src_entry *se; + + STAILQ_FOREACH(se, sh, se_entry) { + if (_bcs_strcasecmp(se->se_name, name) == 0) { + *rse = se; + return (0); + } + } + se = malloc(sizeof(*se)); + if (se == NULL) + return (errno); + se->se_name = strdup(name); + if (se->se_name == NULL) { + ret = errno; + free(se); + return (ret); + } + ret = _db_factory_create(&se->se_df, &_db_hash_std, NULL); + if (ret) { + free(se->se_name); + free(se); + return (ret); + } + STAILQ_INSERT_TAIL(sh, se, se_entry); + *rse = se; + + return (0); +} + +static void +free_src(struct src_head *sh) +{ + struct src_entry *se; + + while ((se = STAILQ_FIRST(sh)) != NULL) { + STAILQ_REMOVE_HEAD(sh, se_entry); + _db_factory_free(se->se_df); + free(se->se_name); + free(se); + } +} + + +#define T_COMM '#' +static int +convert_line(struct src_head *sh, const char *line, size_t len) +{ + struct src_entry *se; + const char *p; + char key1[LINE_MAX], key2[LINE_MAX], data[LINE_MAX]; + char *ep; + uint32_t val; + int ret; + + se = NULL; + + /* cut off trailing comment */ + p = memchr(line, T_COMM, len); + if (p) + len = p - line; + + /* key1 */ + line = _bcs_skip_ws_len(line, &len); + if (len == 0) + return (0); + p = _bcs_skip_nonws_len(line, &len); + if (p == line) + return (0); + snprintf(key1, sizeof(key1), "%.*s", (int)(p - line), line); + + /* key2 */ + line = _bcs_skip_ws_len(p, &len); + if (len == 0) + return (0); + p = _bcs_skip_nonws_len(line, &len); + if (p == line) + return (0); + snprintf(key2, sizeof(key2), "%.*s", (int)(p - line), line); + + /* data */ + line = _bcs_skip_ws_len(p, &len); + _bcs_trunc_rws_len(line, &len); + snprintf(data, sizeof(data), "%.*s", (int)len, line); + val = strtoul(data, &ep, 0); + if (*ep != '\0') + return (EFTYPE); + + /* insert to DB */ + ret = find_src(sh, &se, key1); + if (ret) + return (ret); + + return (_db_factory_add32_by_s(se->se_df, key2, val)); +} + +static int +dump_db(struct src_head *sh, struct _region *r) +{ + struct _db_factory *df; + struct src_entry *se; + struct _region subr; + void *ptr; + size_t size; + int ret; + + ret = _db_factory_create(&df, &_db_hash_std, NULL); + if (ret) + return (ret); + + STAILQ_FOREACH(se, sh, se_entry) { + size = _db_factory_calc_size(se->se_df); + ptr = malloc(size); + if (ptr == NULL) + goto quit; + _region_init(&subr, ptr, size); + ret = _db_factory_serialize(se->se_df, _CITRUS_PIVOT_SUB_MAGIC, + &subr); + if (ret) + goto quit; + ret = _db_factory_add_by_s(df, se->se_name, &subr, 1); + if (ret) + goto quit; + } + + size = _db_factory_calc_size(df); + ptr = malloc(size); + if (ptr == NULL) + goto quit; + _region_init(r, ptr, size); + + ret = _db_factory_serialize(df, _CITRUS_PIVOT_MAGIC, r); + ptr = NULL; + +quit: + free(ptr); + _db_factory_free(df); + return (ret); +} + +int +_citrus_pivot_factory_convert(FILE *out, FILE *in) +{ + struct src_head sh; + struct _region r; + char *line; + size_t size; + int ret; + + STAILQ_INIT(&sh); + + while ((line = fgetln(in, &size)) != NULL) + if ((ret = convert_line(&sh, line, size))) { + free_src(&sh); + return (ret); + } + + ret = dump_db(&sh, &r); + free_src(&sh); + if (ret) + return (ret); + + if (fwrite(_region_head(&r), _region_size(&r), 1, out) != 1) + return (errno); + + return (0); +} diff --git a/lib/libc/iconv/citrus_pivot_factory.h b/lib/libc/iconv/citrus_pivot_factory.h new file mode 100644 index 0000000..78d2d7f --- /dev/null +++ b/lib/libc/iconv/citrus_pivot_factory.h @@ -0,0 +1,37 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_pivot_factory.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_pivot_factory.h,v 1.1 2003/06/25 09:51:39 tshiozak Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_PIVOT_FACTORY_H_ +#define _CITRUS_PIVOT_FACTORY_H_ + +__BEGIN_DECLS +int _citrus_pivot_factory_convert(FILE *, FILE *); +__END_DECLS + +#endif diff --git a/lib/libc/iconv/citrus_pivot_file.h b/lib/libc/iconv/citrus_pivot_file.h new file mode 100644 index 0000000..8d14e20 --- /dev/null +++ b/lib/libc/iconv/citrus_pivot_file.h @@ -0,0 +1,36 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_pivot_file.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_pivot_file.h,v 1.1 2003/06/25 09:51:39 tshiozak Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#ifndef _CITRUS_PIVOT_FILE_H_ +#define _CITRUS_PIVOT_FILE_H_ + +#define _CITRUS_PIVOT_MAGIC "CSPIVOT\0" +#define _CITRUS_PIVOT_SUB_MAGIC "CSPIVSUB" + +#endif diff --git a/lib/libc/iconv/citrus_prop.c b/lib/libc/iconv/citrus_prop.c new file mode 100644 index 0000000..5d5eb2e --- /dev/null +++ b/lib/libc/iconv/citrus_prop.c @@ -0,0 +1,445 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_prop.c 281798 2015-04-20 22:09:50Z pfg $ */ +/* $NetBSD: citrus_prop.c,v 1.4 2011/03/30 08:22:01 jruoho Exp $ */ + +/*- + * Copyright (c)2006 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_bcs.h" +#include "citrus_region.h" +#include "citrus_memstream.h" +#include "citrus_prop.h" + +typedef struct { + _citrus_prop_type_t type; + union { + const char *str; + int chr; + bool boolean; + uint64_t num; + } u; +} _citrus_prop_object_t; + +static __inline void +_citrus_prop_object_init(_citrus_prop_object_t *obj, _citrus_prop_type_t type) +{ + + obj->type = type; + memset(&obj->u, 0, sizeof(obj->u)); +} + +static __inline void +_citrus_prop_object_uninit(_citrus_prop_object_t *obj) +{ + + if (obj->type == _CITRUS_PROP_STR) + free(__DECONST(void *, obj->u.str)); +} + +static const char *xdigit = "0123456789ABCDEF"; + +#define _CITRUS_PROP_READ_UINT_COMMON(_func_, _type_, _max_) \ +static int \ +_citrus_prop_read_##_func_##_common(struct _memstream * __restrict ms, \ + _type_ * __restrict result, int base) \ +{ \ + _type_ acc, cutoff; \ + int ch, cutlim, n; \ + char *p; \ + \ + acc = (_type_)0; \ + cutoff = _max_ / base; \ + cutlim = _max_ % base; \ + for (;;) { \ + ch = _memstream_getc(ms); \ + p = strchr(xdigit, _bcs_toupper(ch)); \ + if (p == NULL || (n = (p - xdigit)) >= base) \ + break; \ + if (acc > cutoff || (acc == cutoff && n > cutlim)) \ + break; \ + acc *= base; \ + acc += n; \ + } \ + _memstream_ungetc(ms, ch); \ + *result = acc; \ + return (0); \ +} +_CITRUS_PROP_READ_UINT_COMMON(chr, int, UCHAR_MAX) +_CITRUS_PROP_READ_UINT_COMMON(num, uint64_t, UINT64_MAX) +#undef _CITRUS_PROP_READ_UINT_COMMON + +#define _CITRUS_PROP_READ_INT(_func_, _type_) \ +static int \ +_citrus_prop_read_##_func_(struct _memstream * __restrict ms, \ + _citrus_prop_object_t * __restrict obj) \ +{ \ + int base, ch, neg; \ + \ + _memstream_skip_ws(ms); \ + ch = _memstream_getc(ms); \ + neg = 0; \ + switch (ch) { \ + case '-': \ + neg = 1; \ + case '+': \ + ch = _memstream_getc(ms); \ + } \ + base = 10; \ + if (ch == '0') { \ + base -= 2; \ + ch = _memstream_getc(ms); \ + if (ch == 'x' || ch == 'X') { \ + ch = _memstream_getc(ms); \ + if (_bcs_isxdigit(ch) == 0) { \ + _memstream_ungetc(ms, ch); \ + obj->u._func_ = 0; \ + return (0); \ + } \ + base += 8; \ + } \ + } else if (_bcs_isdigit(ch) == 0) \ + return (EINVAL); \ + _memstream_ungetc(ms, ch); \ + return (_citrus_prop_read_##_func_##_common \ + (ms, &obj->u._func_, base)); \ +} +_CITRUS_PROP_READ_INT(chr, int) +_CITRUS_PROP_READ_INT(num, uint64_t) +#undef _CITRUS_PROP_READ_INT + +static int +_citrus_prop_read_character_common(struct _memstream * __restrict ms, + int * __restrict result) +{ + int base, ch; + + ch = _memstream_getc(ms); + if (ch != '\\') + *result = ch; + else { + ch = _memstream_getc(ms); + base = 16; + switch (ch) { + case 'a': + *result = '\a'; + break; + case 'b': + *result = '\b'; + break; + case 'f': + *result = '\f'; + break; + case 'n': + *result = '\n'; + break; + case 'r': + *result = '\r'; + break; + case 't': + *result = '\t'; + break; + case 'v': + *result = '\v'; + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + _memstream_ungetc(ms, ch); + base -= 8; + /*FALLTHROUGH*/ + case 'x': + return (_citrus_prop_read_chr_common(ms, result, base)); + /*NOTREACHED*/ + default: + /* unknown escape */ + *result = ch; + } + } + return (0); +} + +static int +_citrus_prop_read_character(struct _memstream * __restrict ms, + _citrus_prop_object_t * __restrict obj) +{ + int ch, errnum; + + _memstream_skip_ws(ms); + ch = _memstream_getc(ms); + if (ch != '\'') { + _memstream_ungetc(ms, ch); + return (_citrus_prop_read_chr(ms, obj)); + } + errnum = _citrus_prop_read_character_common(ms, &ch); + if (errnum != 0) + return (errnum); + obj->u.chr = ch; + ch = _memstream_getc(ms); + if (ch != '\'') + return (EINVAL); + return (0); +} + +static int +_citrus_prop_read_bool(struct _memstream * __restrict ms, + _citrus_prop_object_t * __restrict obj) +{ + + _memstream_skip_ws(ms); + switch (_bcs_tolower(_memstream_getc(ms))) { + case 't': + if (_bcs_tolower(_memstream_getc(ms)) == 'r' && + _bcs_tolower(_memstream_getc(ms)) == 'u' && + _bcs_tolower(_memstream_getc(ms)) == 'e') { + obj->u.boolean = true; + return (0); + } + break; + case 'f': + if (_bcs_tolower(_memstream_getc(ms)) == 'a' && + _bcs_tolower(_memstream_getc(ms)) == 'l' && + _bcs_tolower(_memstream_getc(ms)) == 's' && + _bcs_tolower(_memstream_getc(ms)) == 'e') { + obj->u.boolean = false; + return (0); + } + } + return (EINVAL); +} + +static int +_citrus_prop_read_str(struct _memstream * __restrict ms, + _citrus_prop_object_t * __restrict obj) +{ + int ch, errnum, quot; + char *s, *t; +#define _CITRUS_PROP_STR_BUFSIZ 512 + size_t m, n; + + m = _CITRUS_PROP_STR_BUFSIZ; + s = malloc(m); + if (s == NULL) + return (ENOMEM); + n = 0; + _memstream_skip_ws(ms); + quot = _memstream_getc(ms); + switch (quot) { + case EOF: + goto done; + /*NOTREACHED*/ + case '\\': + _memstream_ungetc(ms, quot); + quot = EOF; + /*FALLTHROUGH*/ + case '\"': case '\'': + break; + default: + s[n] = quot; + ++n, --m; + quot = EOF; + } + for (;;) { + if (m < 1) { + m = _CITRUS_PROP_STR_BUFSIZ; + t = realloc(s, n + m); + if (t == NULL) { + free(s); + return (ENOMEM); + } + s = t; + } + ch = _memstream_getc(ms); + if (quot == ch || (quot == EOF && + (ch == ';' || _bcs_isspace(ch)))) { +done: + s[n] = '\0'; + obj->u.str = (const char *)s; + return (0); + } + _memstream_ungetc(ms, ch); + errnum = _citrus_prop_read_character_common(ms, &ch); + if (errnum != 0) { + free(s); + return (errnum); + } + s[n] = ch; + ++n, --m; + } + free(s); + return (EINVAL); +#undef _CITRUS_PROP_STR_BUFSIZ +} + +typedef int (*_citrus_prop_read_type_t)(struct _memstream * __restrict, + _citrus_prop_object_t * __restrict); + +static const _citrus_prop_read_type_t readers[] = { + _citrus_prop_read_bool, + _citrus_prop_read_str, + _citrus_prop_read_character, + _citrus_prop_read_num, +}; + +static __inline int +_citrus_prop_read_symbol(struct _memstream * __restrict ms, + char * __restrict s, size_t n) +{ + int ch; + size_t m; + + for (m = 0; m < n; ++m) { + ch = _memstream_getc(ms); + if (ch != '_' && _bcs_isalnum(ch) == 0) + goto name_found; + s[m] = ch; + } + ch = _memstream_getc(ms); + if (ch == '_' || _bcs_isalnum(ch) != 0) + return (EINVAL); + +name_found: + _memstream_ungetc(ms, ch); + s[m] = '\0'; + + return (0); +} + +static int +_citrus_prop_parse_element(struct _memstream * __restrict ms, + const _citrus_prop_hint_t * __restrict hints, void * __restrict context) +{ + int ch, errnum; +#define _CITRUS_PROP_HINT_NAME_LEN_MAX 255 + char name[_CITRUS_PROP_HINT_NAME_LEN_MAX + 1]; + const _citrus_prop_hint_t *hint; + _citrus_prop_object_t ostart, oend; + + errnum = _citrus_prop_read_symbol(ms, name, sizeof(name)); + if (errnum != 0) + return (errnum); + for (hint = hints; hint->name != NULL; ++hint) + if (_citrus_bcs_strcasecmp(name, hint->name) == 0) + goto hint_found; + return (EINVAL); + +hint_found: + _memstream_skip_ws(ms); + ch = _memstream_getc(ms); + if (ch != '=' && ch != ':') + _memstream_ungetc(ms, ch); + do { + _citrus_prop_object_init(&ostart, hint->type); + _citrus_prop_object_init(&oend, hint->type); + errnum = (*readers[hint->type])(ms, &ostart); + if (errnum != 0) + return (errnum); + _memstream_skip_ws(ms); + ch = _memstream_getc(ms); + switch (hint->type) { + case _CITRUS_PROP_BOOL: + /*FALLTHROUGH*/ + case _CITRUS_PROP_STR: + break; + default: + if (ch != '-') + break; + errnum = (*readers[hint->type])(ms, &oend); + if (errnum != 0) + return (errnum); + _memstream_skip_ws(ms); + ch = _memstream_getc(ms); + } +#define CALL0(_func_) \ +do { \ + errnum = (*hint->cb._func_.func)(context, \ + hint->name, ostart.u._func_); \ +} while (0) +#define CALL1(_func_) \ +do { \ + errnum = (*hint->cb._func_.func)(context, \ + hint->name, ostart.u._func_, oend.u._func_);\ +} while (0) + switch (hint->type) { + case _CITRUS_PROP_BOOL: + CALL0(boolean); + break; + case _CITRUS_PROP_STR: + CALL0(str); + break; + case _CITRUS_PROP_CHR: + CALL1(chr); + break; + case _CITRUS_PROP_NUM: + CALL1(num); + break; + default: + abort(); + /*NOTREACHED*/ + } +#undef CALL0 +#undef CALL1 + _citrus_prop_object_uninit(&ostart); + _citrus_prop_object_uninit(&oend); + if (errnum != 0) + return (errnum); + } while (ch == ','); + if (ch != ';') + _memstream_ungetc(ms, ch); + return (0); +} + +int +_citrus_prop_parse_variable(const _citrus_prop_hint_t * __restrict hints, + void * __restrict context, const void *var, size_t lenvar) +{ + struct _memstream ms; + int ch, errnum; + + _memstream_bind_ptr(&ms, __DECONST(void *, var), lenvar); + for (;;) { + _memstream_skip_ws(&ms); + ch = _memstream_getc(&ms); + if (ch == EOF || ch == '\0') + break; + _memstream_ungetc(&ms, ch); + errnum = _citrus_prop_parse_element(&ms, hints, context); + if (errnum != 0) + return (errnum); + } + return (0); +} diff --git a/lib/libc/iconv/citrus_prop.h b/lib/libc/iconv/citrus_prop.h new file mode 100644 index 0000000..77c44dc --- /dev/null +++ b/lib/libc/iconv/citrus_prop.h @@ -0,0 +1,92 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_prop.h 263986 2014-04-01 10:36:11Z tijl $ */ +/* $NetBSD: citrus_prop.h,v 1.5 2011/05/23 14:52:32 joerg Exp $ */ + +/*- + * Copyright (c)2006 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + */ + +#ifndef _CITRUS_PROP_H_ +#define _CITRUS_PROP_H_ + +typedef enum { + _CITRUS_PROP_BOOL = 0, + _CITRUS_PROP_STR = 1, + _CITRUS_PROP_CHR = 2, + _CITRUS_PROP_NUM = 3, +} _citrus_prop_type_t; + +typedef struct _citrus_prop_hint_t _citrus_prop_hint_t; + +#define _CITRUS_PROP_CB0_T(_func_, _type_) \ +typedef int (*_citrus_prop_##_func_##_cb_func_t) \ + (void * __restrict, const char *, _type_); \ +typedef struct { \ + _citrus_prop_##_func_##_cb_func_t func; \ +} _citrus_prop_##_func_##_cb_t; +_CITRUS_PROP_CB0_T(boolean, int) +_CITRUS_PROP_CB0_T(str, const char *) +#undef _CITRUS_PROP_CB0_T + +#define _CITRUS_PROP_CB1_T(_func_, _type_) \ +typedef int (*_citrus_prop_##_func_##_cb_func_t) \ + (void * __restrict, const char *, _type_, _type_); \ +typedef struct { \ + _citrus_prop_##_func_##_cb_func_t func; \ +} _citrus_prop_##_func_##_cb_t; +_CITRUS_PROP_CB1_T(chr, int) +_CITRUS_PROP_CB1_T(num, uint64_t) +#undef _CITRUS_PROP_CB1_T + +struct _citrus_prop_hint_t { + const char *name; + _citrus_prop_type_t type; +#define _CITRUS_PROP_CB_T_OPS(_name_) \ + _citrus_prop_##_name_##_cb_t _name_ + union { + _CITRUS_PROP_CB_T_OPS(boolean); + _CITRUS_PROP_CB_T_OPS(str); + _CITRUS_PROP_CB_T_OPS(chr); + _CITRUS_PROP_CB_T_OPS(num); + } cb; +}; + +#define _CITRUS_PROP_HINT_BOOL(name, cb) \ + { name, _CITRUS_PROP_BOOL, { .boolean = { cb } } } +#define _CITRUS_PROP_HINT_STR(name, cb) \ + { name, _CITRUS_PROP_STR, { .str = { cb } } } +#define _CITRUS_PROP_HINT_CHR(name, cb) \ + { name, _CITRUS_PROP_CHR, { .chr = { cb } } } +#define _CITRUS_PROP_HINT_NUM(name, cb) \ + { name, _CITRUS_PROP_NUM, { .num = { cb } } } +#define _CITRUS_PROP_HINT_END \ + { .name = NULL } + +__BEGIN_DECLS +int _citrus_prop_parse_variable(const _citrus_prop_hint_t * __restrict, + void * __restrict, const void *, size_t); +__END_DECLS + +#endif /* !_CITRUS_PROP_H_ */ diff --git a/lib/libc/iconv/citrus_region.h b/lib/libc/iconv/citrus_region.h new file mode 100644 index 0000000..7c4e9cf --- /dev/null +++ b/lib/libc/iconv/citrus_region.h @@ -0,0 +1,113 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_region.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_region.h,v 1.7 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + */ + +#ifndef _CITRUS_REGION_H_ +#define _CITRUS_REGION_H_ + +#include + +struct _citrus_region { + void *r_head; + size_t r_size; +}; + +static __inline void +_citrus_region_init(struct _citrus_region *r, void *h, size_t sz) +{ + + r->r_head = h; + r->r_size = sz; +} + +static __inline void * +_citrus_region_head(const struct _citrus_region *r) +{ + + return (r->r_head); +} + +static __inline size_t +_citrus_region_size(const struct _citrus_region *r) +{ + + return (r->r_size); +} + +static __inline int +_citrus_region_check(const struct _citrus_region *r, size_t ofs, size_t sz) +{ + + return (r->r_size >= ofs + sz ? 0 : -1); +} + +static __inline void * +_citrus_region_offset(const struct _citrus_region *r, size_t pos) +{ + + return ((void *)((uint8_t *)r->r_head + pos)); +} + +static __inline uint8_t +_citrus_region_peek8(const struct _citrus_region *r, size_t pos) +{ + + return (*(uint8_t *)_citrus_region_offset(r, pos)); +} + +static __inline uint16_t +_citrus_region_peek16(const struct _citrus_region *r, size_t pos) +{ + uint16_t val; + + memcpy(&val, _citrus_region_offset(r, pos), (size_t)2); + return (val); +} + +static __inline uint32_t +_citrus_region_peek32(const struct _citrus_region *r, size_t pos) +{ + uint32_t val; + + memcpy(&val, _citrus_region_offset(r, pos), (size_t)4); + return (val); +} + +static __inline int +_citrus_region_get_subregion(struct _citrus_region *subr, + const struct _citrus_region *r, size_t ofs, size_t sz) +{ + + if (_citrus_region_check(r, ofs, sz)) + return (-1); + _citrus_region_init(subr, _citrus_region_offset(r, ofs), sz); + return (0); +} + +#endif diff --git a/lib/libc/iconv/citrus_stdenc.c b/lib/libc/iconv/citrus_stdenc.c new file mode 100644 index 0000000..e0e5279 --- /dev/null +++ b/lib/libc/iconv/citrus_stdenc.c @@ -0,0 +1,147 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_stdenc.c 263986 2014-04-01 10:36:11Z tijl $ */ +/* $NetBSD: citrus_stdenc.c,v 1.4 2011/11/19 18:39:58 tnozaki Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + +#include +#include +#include +#include + +#include "citrus_namespace.h" +#include "citrus_types.h" +#include "citrus_module.h" +#include "citrus_none.h" +#include "citrus_stdenc.h" + +struct _citrus_stdenc _citrus_stdenc_default = { + &_citrus_NONE_stdenc_ops, /* ce_ops */ + NULL, /* ce_closure */ + NULL, /* ce_module */ + &_citrus_NONE_stdenc_traits, /* ce_traits */ +}; + +int +_citrus_stdenc_open(struct _citrus_stdenc * __restrict * __restrict rce, + char const * __restrict encname, const void * __restrict variable, + size_t lenvar) +{ + struct _citrus_stdenc *ce; + _citrus_module_t handle; + _citrus_stdenc_getops_t getops; + int ret; + + if (!strcmp(encname, _CITRUS_DEFAULT_STDENC_NAME)) { + *rce = &_citrus_stdenc_default; + return (0); + } + ce = malloc(sizeof(*ce)); + if (ce == NULL) { + ret = errno; + goto bad; + } + ce->ce_ops = NULL; + ce->ce_closure = NULL; + ce->ce_module = NULL; + ce->ce_traits = NULL; + + ret = _citrus_load_module(&handle, encname); + if (ret) + goto bad; + + ce->ce_module = handle; + + getops = (_citrus_stdenc_getops_t)_citrus_find_getops(ce->ce_module, + encname, "stdenc"); + if (getops == NULL) { + ret = EINVAL; + goto bad; + } + + ce->ce_ops = (struct _citrus_stdenc_ops *)malloc(sizeof(*ce->ce_ops)); + if (ce->ce_ops == NULL) { + ret = errno; + goto bad; + } + + ret = (*getops)(ce->ce_ops, sizeof(*ce->ce_ops)); + if (ret) + goto bad; + + /* validation check */ + if (ce->ce_ops->eo_init == NULL || + ce->ce_ops->eo_uninit == NULL || + ce->ce_ops->eo_init_state == NULL || + ce->ce_ops->eo_mbtocs == NULL || + ce->ce_ops->eo_cstomb == NULL || + ce->ce_ops->eo_mbtowc == NULL || + ce->ce_ops->eo_wctomb == NULL || + ce->ce_ops->eo_get_state_desc == NULL) { + ret = EINVAL; + goto bad; + } + + /* allocate traits */ + ce->ce_traits = malloc(sizeof(*ce->ce_traits)); + if (ce->ce_traits == NULL) { + ret = errno; + goto bad; + } + /* init and get closure */ + ret = (*ce->ce_ops->eo_init)(ce, variable, lenvar, ce->ce_traits); + if (ret) + goto bad; + + *rce = ce; + + return (0); + +bad: + _citrus_stdenc_close(ce); + return (ret); +} + +void +_citrus_stdenc_close(struct _citrus_stdenc *ce) +{ + + if (ce == &_citrus_stdenc_default) + return; + + if (ce->ce_module) { + if (ce->ce_ops) { + if (ce->ce_closure && ce->ce_ops->eo_uninit) + (*ce->ce_ops->eo_uninit)(ce); + free(ce->ce_ops); + } + free(ce->ce_traits); + _citrus_unload_module(ce->ce_module); + } + free(ce); +} diff --git a/lib/libc/iconv/citrus_stdenc.h b/lib/libc/iconv/citrus_stdenc.h new file mode 100644 index 0000000..9797648 --- /dev/null +++ b/lib/libc/iconv/citrus_stdenc.h @@ -0,0 +1,124 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_stdenc.h 281550 2015-04-15 09:09:20Z tijl $ */ +/* $NetBSD: citrus_stdenc.h,v 1.4 2005/10/29 18:02:04 tshiozak Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + */ + +#ifndef _CITRUS_STDENC_H_ +#define _CITRUS_STDENC_H_ + +struct _citrus_stdenc; +struct _citrus_stdenc_ops; +struct _citrus_stdenc_traits; + +#define _CITRUS_STDENC_SDID_GENERIC 0 +struct _citrus_stdenc_state_desc +{ + union { + struct { + int state; +#define _CITRUS_STDENC_SDGEN_UNKNOWN 0 +#define _CITRUS_STDENC_SDGEN_INITIAL 1 +#define _CITRUS_STDENC_SDGEN_STABLE 2 +#define _CITRUS_STDENC_SDGEN_INCOMPLETE_CHAR 3 +#define _CITRUS_STDENC_SDGEN_INCOMPLETE_SHIFT 4 + } generic; + } u; +}; + +#include "citrus_stdenc_local.h" + +__BEGIN_DECLS +int _citrus_stdenc_open(struct _citrus_stdenc * __restrict * __restrict, + char const * __restrict, const void * __restrict, size_t); +void _citrus_stdenc_close(struct _citrus_stdenc *); +__END_DECLS + +static __inline int +_citrus_stdenc_init_state(struct _citrus_stdenc * __restrict ce, + void * __restrict ps) +{ + + return ((*ce->ce_ops->eo_init_state)(ce, ps)); +} + +static __inline int +_citrus_stdenc_mbtocs(struct _citrus_stdenc * __restrict ce, + _citrus_csid_t * __restrict csid, _citrus_index_t * __restrict idx, + char ** __restrict s, size_t n, void * __restrict ps, + size_t * __restrict nresult, struct iconv_hooks *hooks) +{ + + return ((*ce->ce_ops->eo_mbtocs)(ce, csid, idx, s, n, ps, nresult, + hooks)); +} + +static __inline int +_citrus_stdenc_cstomb(struct _citrus_stdenc * __restrict ce, + char * __restrict s, size_t n, _citrus_csid_t csid, _citrus_index_t idx, + void * __restrict ps, size_t * __restrict nresult, + struct iconv_hooks *hooks) +{ + + return ((*ce->ce_ops->eo_cstomb)(ce, s, n, csid, idx, ps, nresult, + hooks)); +} + +static __inline int +_citrus_stdenc_wctomb(struct _citrus_stdenc * __restrict ce, + char * __restrict s, size_t n, _citrus_wc_t wc, void * __restrict ps, + size_t * __restrict nresult, struct iconv_hooks *hooks) +{ + + return ((*ce->ce_ops->eo_wctomb)(ce, s, n, wc, ps, nresult, hooks)); +} + +static __inline int +_citrus_stdenc_put_state_reset(struct _citrus_stdenc * __restrict ce, + char * __restrict s, size_t n, void * __restrict ps, + size_t * __restrict nresult) +{ + + return ((*ce->ce_ops->eo_put_state_reset)(ce, s, n, ps, nresult)); +} + +static __inline size_t +_citrus_stdenc_get_state_size(struct _citrus_stdenc *ce) +{ + + return (ce->ce_traits->et_state_size); +} + +static __inline int +_citrus_stdenc_get_state_desc(struct _citrus_stdenc * __restrict ce, + void * __restrict ps, int id, + struct _citrus_stdenc_state_desc * __restrict d) +{ + + return ((*ce->ce_ops->eo_get_state_desc)(ce, ps, id, d)); +} +#endif diff --git a/lib/libc/iconv/citrus_stdenc_local.h b/lib/libc/iconv/citrus_stdenc_local.h new file mode 100644 index 0000000..ac00095 --- /dev/null +++ b/lib/libc/iconv/citrus_stdenc_local.h @@ -0,0 +1,162 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_stdenc_local.h 281550 2015-04-15 09:09:20Z tijl $ */ +/* $NetBSD: citrus_stdenc_local.h,v 1.4 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + */ + +#ifndef _CITRUS_STDENC_LOCAL_H_ +#define _CITRUS_STDENC_LOCAL_H_ + +#include + +#include "citrus_module.h" + +#define _CITRUS_STDENC_GETOPS_FUNC_BASE(n) \ + int n(struct _citrus_stdenc_ops *, size_t) +#define _CITRUS_STDENC_GETOPS_FUNC(_e_) \ + _CITRUS_STDENC_GETOPS_FUNC_BASE(_citrus_##_e_##_stdenc_getops) +typedef _CITRUS_STDENC_GETOPS_FUNC_BASE((*_citrus_stdenc_getops_t)); + + +#define _CITRUS_STDENC_DECLS(_e_) \ +static int _citrus_##_e_##_stdenc_init \ + (struct _citrus_stdenc * __restrict, \ + const void * __restrict, size_t, \ + struct _citrus_stdenc_traits * __restrict); \ +static void _citrus_##_e_##_stdenc_uninit(struct _citrus_stdenc *);\ +static int _citrus_##_e_##_stdenc_init_state \ + (struct _citrus_stdenc * __restrict, \ + void * __restrict); \ +static int _citrus_##_e_##_stdenc_mbtocs \ + (struct _citrus_stdenc * __restrict, \ + _citrus_csid_t * __restrict, \ + _citrus_index_t * __restrict, \ + char ** __restrict, size_t, \ + void * __restrict, size_t * __restrict, \ + struct iconv_hooks *); \ +static int _citrus_##_e_##_stdenc_cstomb \ + (struct _citrus_stdenc * __restrict, \ + char * __restrict, size_t, _citrus_csid_t, \ + _citrus_index_t, void * __restrict, \ + size_t * __restrict, struct iconv_hooks *); \ +static int _citrus_##_e_##_stdenc_mbtowc \ + (struct _citrus_stdenc * __restrict, \ + _citrus_wc_t * __restrict, \ + char ** __restrict, size_t, \ + void * __restrict, size_t * __restrict, \ + struct iconv_hooks *); \ +static int _citrus_##_e_##_stdenc_wctomb \ + (struct _citrus_stdenc * __restrict, \ + char * __restrict, size_t, _citrus_wc_t, \ + void * __restrict, size_t * __restrict, \ + struct iconv_hooks *); \ +static int _citrus_##_e_##_stdenc_put_state_reset \ + (struct _citrus_stdenc * __restrict, \ + char * __restrict, size_t, void * __restrict, \ + size_t * __restrict); \ +static int _citrus_##_e_##_stdenc_get_state_desc \ + (struct _citrus_stdenc * __restrict, \ + void * __restrict, int, \ + struct _citrus_stdenc_state_desc * __restrict) + +#define _CITRUS_STDENC_DEF_OPS(_e_) \ +extern struct _citrus_stdenc_ops _citrus_##_e_##_stdenc_ops; \ +struct _citrus_stdenc_ops _citrus_##_e_##_stdenc_ops = { \ + /* eo_init */ &_citrus_##_e_##_stdenc_init, \ + /* eo_uninit */ &_citrus_##_e_##_stdenc_uninit, \ + /* eo_init_state */ &_citrus_##_e_##_stdenc_init_state, \ + /* eo_mbtocs */ &_citrus_##_e_##_stdenc_mbtocs, \ + /* eo_cstomb */ &_citrus_##_e_##_stdenc_cstomb, \ + /* eo_mbtowc */ &_citrus_##_e_##_stdenc_mbtowc, \ + /* eo_wctomb */ &_citrus_##_e_##_stdenc_wctomb, \ + /* eo_put_state_reset */&_citrus_##_e_##_stdenc_put_state_reset,\ + /* eo_get_state_desc */ &_citrus_##_e_##_stdenc_get_state_desc \ +} + +typedef int (*_citrus_stdenc_init_t) + (struct _citrus_stdenc * __reatrict, const void * __restrict , size_t, + struct _citrus_stdenc_traits * __restrict); +typedef void (*_citrus_stdenc_uninit_t)(struct _citrus_stdenc * __restrict); +typedef int (*_citrus_stdenc_init_state_t) + (struct _citrus_stdenc * __restrict, void * __restrict); +typedef int (*_citrus_stdenc_mbtocs_t) + (struct _citrus_stdenc * __restrict, + _citrus_csid_t * __restrict, _citrus_index_t * __restrict, + char ** __restrict, size_t, + void * __restrict, size_t * __restrict, + struct iconv_hooks *); +typedef int (*_citrus_stdenc_cstomb_t) + (struct _citrus_stdenc *__restrict, char * __restrict, size_t, + _citrus_csid_t, _citrus_index_t, void * __restrict, + size_t * __restrict, struct iconv_hooks *); +typedef int (*_citrus_stdenc_mbtowc_t) + (struct _citrus_stdenc * __restrict, + _citrus_wc_t * __restrict, + char ** __restrict, size_t, + void * __restrict, size_t * __restrict, + struct iconv_hooks *); +typedef int (*_citrus_stdenc_wctomb_t) + (struct _citrus_stdenc *__restrict, char * __restrict, size_t, + _citrus_wc_t, void * __restrict, size_t * __restrict, + struct iconv_hooks *); +typedef int (*_citrus_stdenc_put_state_reset_t) + (struct _citrus_stdenc *__restrict, char * __restrict, size_t, + void * __restrict, size_t * __restrict); +typedef int (*_citrus_stdenc_get_state_desc_t) + (struct _citrus_stdenc * __restrict, void * __restrict, int, + struct _citrus_stdenc_state_desc * __restrict); + +struct _citrus_stdenc_ops { + _citrus_stdenc_init_t eo_init; + _citrus_stdenc_uninit_t eo_uninit; + _citrus_stdenc_init_state_t eo_init_state; + _citrus_stdenc_mbtocs_t eo_mbtocs; + _citrus_stdenc_cstomb_t eo_cstomb; + _citrus_stdenc_mbtowc_t eo_mbtowc; + _citrus_stdenc_wctomb_t eo_wctomb; + _citrus_stdenc_put_state_reset_t eo_put_state_reset; + /* version 0x00000002 */ + _citrus_stdenc_get_state_desc_t eo_get_state_desc; +}; + +struct _citrus_stdenc_traits { + /* version 0x00000001 */ + size_t et_state_size; + size_t et_mb_cur_max; +}; + +struct _citrus_stdenc { + /* version 0x00000001 */ + struct _citrus_stdenc_ops *ce_ops; + void *ce_closure; + _citrus_module_t ce_module; + struct _citrus_stdenc_traits *ce_traits; +}; + +#define _CITRUS_DEFAULT_STDENC_NAME "NONE" + +#endif diff --git a/lib/libc/iconv/citrus_stdenc_template.h b/lib/libc/iconv/citrus_stdenc_template.h new file mode 100644 index 0000000..cd6a267 --- /dev/null +++ b/lib/libc/iconv/citrus_stdenc_template.h @@ -0,0 +1,211 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_stdenc_template.h 281550 2015-04-15 09:09:20Z tijl $ */ +/* $NetBSD: citrus_stdenc_template.h,v 1.4 2008/02/09 14:56:20 junyoung Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + +/* + * CAUTION: THIS IS NOT STANDALONE FILE + * + * function templates of iconv standard encoding handler for each encodings. + * + */ + +/* + * macros + */ + +#undef _TO_EI +#undef _CE_TO_EI +#undef _TO_STATE +#define _TO_EI(_cl_) ((_ENCODING_INFO*)(_cl_)) +#define _CE_TO_EI(_ce_) (_TO_EI((_ce_)->ce_closure)) +#define _TO_STATE(_ps_) ((_ENCODING_STATE*)(_ps_)) + +/* ---------------------------------------------------------------------- + * templates for public functions + */ + +int +_FUNCNAME(stdenc_getops)(struct _citrus_stdenc_ops *ops, + size_t lenops __unused) +{ + + memcpy(ops, &_FUNCNAME(stdenc_ops), sizeof(_FUNCNAME(stdenc_ops))); + + return (0); +} + +static int +_FUNCNAME(stdenc_init)(struct _citrus_stdenc * __restrict ce, + const void * __restrict var, size_t lenvar, + struct _citrus_stdenc_traits * __restrict et) +{ + _ENCODING_INFO *ei; + int ret; + + ei = NULL; + if (sizeof(_ENCODING_INFO) > 0) { + ei = calloc(1, sizeof(_ENCODING_INFO)); + if (ei == NULL) + return (errno); + } + + ret = _FUNCNAME(encoding_module_init)(ei, var, lenvar); + if (ret) { + free((void *)ei); + return (ret); + } + + ce->ce_closure = ei; + et->et_state_size = sizeof(_ENCODING_STATE); + et->et_mb_cur_max = _ENCODING_MB_CUR_MAX(_CE_TO_EI(ce)); + + return (0); +} + +static void +_FUNCNAME(stdenc_uninit)(struct _citrus_stdenc * __restrict ce) +{ + + if (ce) { + _FUNCNAME(encoding_module_uninit)(_CE_TO_EI(ce)); + free(ce->ce_closure); + } +} + +static int +_FUNCNAME(stdenc_init_state)(struct _citrus_stdenc * __restrict ce, + void * __restrict ps) +{ + + _FUNCNAME(init_state)(_CE_TO_EI(ce), _TO_STATE(ps)); + + return (0); +} + +static int +_FUNCNAME(stdenc_mbtocs)(struct _citrus_stdenc * __restrict ce, + _citrus_csid_t * __restrict csid, _citrus_index_t * __restrict idx, + char ** __restrict s, size_t n, void * __restrict ps, + size_t * __restrict nresult, struct iconv_hooks *hooks) +{ + wchar_t wc; + int ret; + + ret = _FUNCNAME(mbrtowc_priv)(_CE_TO_EI(ce), &wc, s, n, + _TO_STATE(ps), nresult); + + if ((ret == 0) && *nresult != (size_t)-2) + ret = _FUNCNAME(stdenc_wctocs)(_CE_TO_EI(ce), csid, idx, wc); + + if ((ret == 0) && (hooks != NULL) && (hooks->uc_hook != NULL)) + hooks->uc_hook((unsigned int)*idx, hooks->data); + return (ret); +} + +static int +_FUNCNAME(stdenc_cstomb)(struct _citrus_stdenc * __restrict ce, + char * __restrict s, size_t n, _citrus_csid_t csid, _citrus_index_t idx, + void * __restrict ps, size_t * __restrict nresult, + struct iconv_hooks *hooks __unused) +{ + wchar_t wc; + int ret; + + wc = ret = 0; + + if (csid != _CITRUS_CSID_INVALID) + ret = _FUNCNAME(stdenc_cstowc)(_CE_TO_EI(ce), &wc, csid, idx); + + if (ret == 0) + ret = _FUNCNAME(wcrtomb_priv)(_CE_TO_EI(ce), s, n, wc, + _TO_STATE(ps), nresult); + return (ret); +} + +static int +_FUNCNAME(stdenc_mbtowc)(struct _citrus_stdenc * __restrict ce, + _citrus_wc_t * __restrict wc, char ** __restrict s, size_t n, + void * __restrict ps, size_t * __restrict nresult, + struct iconv_hooks *hooks) +{ + int ret; + + ret = _FUNCNAME(mbrtowc_priv)(_CE_TO_EI(ce), wc, s, n, + _TO_STATE(ps), nresult); + if ((ret == 0) && (hooks != NULL) && (hooks->wc_hook != NULL)) + hooks->wc_hook(*wc, hooks->data); + return (ret); +} + +static int +_FUNCNAME(stdenc_wctomb)(struct _citrus_stdenc * __restrict ce, + char * __restrict s, size_t n, _citrus_wc_t wc, void * __restrict ps, + size_t * __restrict nresult, struct iconv_hooks *hooks __unused) +{ + int ret; + + ret = _FUNCNAME(wcrtomb_priv)(_CE_TO_EI(ce), s, n, wc, _TO_STATE(ps), + nresult); + return (ret); +} + +static int +_FUNCNAME(stdenc_put_state_reset)(struct _citrus_stdenc * __restrict ce __unused, + char * __restrict s __unused, size_t n __unused, + void * __restrict ps __unused, size_t * __restrict nresult) +{ + +#if _ENCODING_IS_STATE_DEPENDENT + return ((_FUNCNAME(put_state_reset)(_CE_TO_EI(ce), s, n, _TO_STATE(ps), + nresult))); +#else + *nresult = 0; + return (0); +#endif +} + +static int +_FUNCNAME(stdenc_get_state_desc)(struct _citrus_stdenc * __restrict ce, + void * __restrict ps, int id, + struct _citrus_stdenc_state_desc * __restrict d) +{ + int ret; + + switch (id) { + case _STDENC_SDID_GENERIC: + ret = _FUNCNAME(stdenc_get_state_desc_generic)( + _CE_TO_EI(ce), _TO_STATE(ps), &d->u.generic.state); + break; + default: + ret = EOPNOTSUPP; + } + + return (ret); +} diff --git a/lib/libc/iconv/citrus_types.h b/lib/libc/iconv/citrus_types.h new file mode 100644 index 0000000..cb33f87 --- /dev/null +++ b/lib/libc/iconv/citrus_types.h @@ -0,0 +1,40 @@ +/* $FreeBSD: releng/11.1/lib/libc/iconv/citrus_types.h 219019 2011-02-25 00:04:39Z gabor $ */ +/* $NetBSD: citrus_types.h,v 1.3 2003/10/27 00:12:42 lukem Exp $ */ + +/*- + * Copyright (c)2003 Citrus Project, + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + +#ifndef _CITRUS_TYPES_H_ +#define _CITRUS_TYPES_H_ + +typedef uint32_t _citrus_wc_t; +typedef uint32_t _citrus_index_t; +typedef uint32_t _citrus_csid_t; +#define _CITRUS_CSID_INVALID ((_citrus_csid_t)-1) + +#endif diff --git a/lib/libc/iconv/iconv-internal.h b/lib/libc/iconv/iconv-internal.h new file mode 100644 index 0000000..e0e45ef --- /dev/null +++ b/lib/libc/iconv/iconv-internal.h @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/iconv-internal.h 298830 2016-04-30 01:24:24Z pfg $ + */ + +/* + * Internal prototypes for our back-end functions. + */ +size_t __bsd___iconv(iconv_t, char **, size_t *, char **, + size_t *, __uint32_t, size_t *); +void __bsd___iconv_free_list(char **, size_t); +int __bsd___iconv_get_list(char ***, size_t *, __iconv_bool); +size_t __bsd_iconv(iconv_t, char ** __restrict, + size_t * __restrict, char ** __restrict, + size_t * __restrict); +const char *__bsd_iconv_canonicalize(const char *); +int __bsd_iconv_close(iconv_t); +iconv_t __bsd_iconv_open(const char *, const char *); +int __bsd_iconv_open_into(const char *, const char *, iconv_allocation_t *); +void __bsd_iconv_set_relocation_prefix(const char *, const char *); +int __bsd_iconvctl(iconv_t, int, void *); +void __bsd_iconvlist(int (*) (unsigned int, const char * const *, void *), void *); diff --git a/lib/libc/iconv/iconv.3 b/lib/libc/iconv/iconv.3 new file mode 100644 index 0000000..fe565b2 --- /dev/null +++ b/lib/libc/iconv/iconv.3 @@ -0,0 +1,309 @@ +.\" $FreeBSD: releng/11.1/lib/libc/iconv/iconv.3 281550 2015-04-15 09:09:20Z tijl $ +.\" $NetBSD: iconv.3,v 1.12 2004/08/02 13:38:21 tshiozak Exp $ +.\" +.\" Copyright (c) 2003 Citrus Project, +.\" Copyright (c) 2009, 2010 Gabor Kovesdan , +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.Dd August 4, 2014 +.Dt ICONV 3 +.Os +.Sh NAME +.Nm iconv_open , +.Nm iconv_open_into , +.Nm iconv_close , +.Nm iconv +.Nd codeset conversion functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In iconv.h +.Ft iconv_t +.Fn iconv_open "const char *dstname" "const char *srcname" +.Ft int +.Fn iconv_open_into "const char *dstname" "const char *srcname" "iconv_allocation_t *ptr" +.Ft int +.Fn iconv_close "iconv_t cd" +.Ft size_t +.Fn iconv "iconv_t cd" "char ** restrict src" "size_t * restrict srcleft" "char ** restrict dst" "size_t * restrict dstleft" +.Ft size_t +.Fn __iconv "iconv_t cd" "char ** restrict src" "size_t * restrict srcleft" "char ** restrict dst" "size_t * restrict dstleft" "uint32_t flags" "size_t * invalids" +.Sh DESCRIPTION +The +.Fn iconv_open +function opens a converter from the codeset +.Fa srcname +to the codeset +.Fa dstname +and returns its descriptor. +The arguments +.Fa srcname +and +.Fa dstname +accept "" and "char", which refer to the current locale encoding. +.Pp +The +.Fn iconv_open_into +creates a conversion descriptor on a preallocated space. +The +.Ft iconv_allocation_t +is used as a spaceholder type when allocating such space. +The +.Fa dstname +and +.Fa srcname +arguments are the same as in the case of +.Fn iconv_open . +The +.Fa ptr +argument is a pointer of +.Ft iconv_allocation_t +to the preallocated space. +.Pp +The +.Fn iconv_close +function closes the specified converter +.Fa cd . +.Pp +The +.Fn iconv +function converts the string in the buffer +.Fa *src +of length +.Fa *srcleft +bytes and stores the converted string in the buffer +.Fa *dst +of size +.Fa *dstleft +bytes. +After calling +.Fn iconv , +the values pointed to by +.Fa src , +.Fa srcleft , +.Fa dst , +and +.Fa dstleft +are updated as follows: +.Bl -tag -width 01234567 +.It *src +Pointer to the byte just after the last character fetched. +.It *srcleft +Number of remaining bytes in the source buffer. +.It *dst +Pointer to the byte just after the last character stored. +.It *dstleft +Number of remainder bytes in the destination buffer. +.El +.Pp +If the string pointed to by +.Fa *src +contains a byte sequence which is not a valid character in the source +codeset, the conversion stops just after the last successful conversion. +If the output buffer is too small to store the converted +character, the conversion also stops in the same way. +In these cases, the values pointed to by +.Fa src , +.Fa srcleft , +.Fa dst , +and +.Fa dstleft +are updated to the state just after the last successful conversion. +.Pp +If the string pointed to by +.Fa *src +contains a character which is valid under the source codeset but +can not be converted to the destination codeset, +the character is replaced by an +.Dq invalid character +which depends on the destination codeset, e.g., +.Sq \&? , +and the conversion is continued. +.Fn iconv +returns the number of such +.Dq invalid conversions . +.Pp +There are two special cases of +.Fn iconv : +.Bl -tag -width 0123 +.It "src == NULL || *src == NULL" +If the source and/or destination codesets are stateful, +.Fn iconv +places these into their initial state. +.Pp +If both +.Fa dst +and +.Fa *dst +are +.No non- Ns Dv NULL , +.Fn iconv +stores the shift sequence for the destination switching to the initial state +in the buffer pointed to by +.Fa *dst . +The buffer size is specified by the value pointed to by +.Fa dstleft +as above. +.Fn iconv +will fail if the buffer is too small to store the shift sequence. +.Pp +On the other hand, +.Fa dst +or +.Fa *dst +may be +.Dv NULL . +In this case, the shift sequence for the destination switching +to the initial state is discarded. +.El +.Pp +The +.Fn __iconv +function works just like +.Fn iconv +but if +.Fn iconv +fails, the invalid character count is lost there. +This is a not bug rather a limitation of +.St -p1003.1-2008 , +so +.Fn __iconv +is provided as an alternative but non-standard interface. +It also has a flags argument, where currently the following +flags can be passed: +.Bl -tag -width 0123 +.It __ICONV_F_HIDE_INVALID +Skip invalid characters, instead of returning with an error. +.El +.Sh RETURN VALUES +Upon successful completion of +.Fn iconv_open , +it returns a conversion descriptor. +Otherwise, +.Fn iconv_open +returns (iconv_t)\-1 and sets errno to indicate the error. +.Pp +Upon successful completion of +.Fn iconv_open_into , +it returns 0. +Otherwise, +.Fn iconv_open_into +returns \-1, and sets errno to indicate the error. +.Pp +Upon successful completion of +.Fn iconv_close , +it returns 0. +Otherwise, +.Fn iconv_close +returns \-1 and sets errno to indicate the error. +.Pp +Upon successful completion of +.Fn iconv , +it returns the number of +.Dq invalid +conversions. +Otherwise, +.Fn iconv +returns (size_t)\-1 and sets errno to indicate the error. +.Sh ERRORS +The +.Fn iconv_open +function may cause an error in the following cases: +.Bl -tag -width Er +.It Bq Er ENOMEM +Memory is exhausted. +.It Bq Er EINVAL +There is no converter specified by +.Fa srcname +and +.Fa dstname . +.El +The +.Fn iconv_open_into +function may cause an error in the following cases: +.Bl -tag -width Er +.It Bq Er EINVAL +There is no converter specified by +.Fa srcname +and +.Fa dstname . +.El +.Pp +The +.Fn iconv_close +function may cause an error in the following case: +.Bl -tag -width Er +.It Bq Er EBADF +The conversion descriptor specified by +.Fa cd +is invalid. +.El +.Pp +The +.Fn iconv +function may cause an error in the following cases: +.Bl -tag -width Er +.It Bq Er EBADF +The conversion descriptor specified by +.Fa cd +is invalid. +.It Bq Er EILSEQ +The string pointed to by +.Fa *src +contains a byte sequence which does not describe a valid character of +the source codeset. +.It Bq Er E2BIG +The output buffer pointed to by +.Fa *dst +is too small to store the result string. +.It Bq Er EINVAL +The string pointed to by +.Fa *src +terminates with an incomplete character or shift sequence. +.El +.Sh SEE ALSO +.Xr iconv 1 , +.Xr mkcsmapper 1 , +.Xr mkesdb 1 , +.Xr __iconv_get_list 3 , +.Xr iconv_canonicalize 3 , +.Xr iconvctl 3 , +.Xr iconvlist 3 +.Sh STANDARDS +The +.Fn iconv_open , +.Fn iconv_close , +and +.Fn iconv +functions conform to +.St -p1003.1-2008 . +.Pp +The +.Fn iconv_open_into +function is a GNU-specific extension and it is not part of any standard, +thus its use may break portability. +The +.Fn __iconv +function is an own extension and it is not part of any standard, +thus its use may break portability. diff --git a/lib/libc/iconv/iconv.c b/lib/libc/iconv/iconv.c new file mode 100644 index 0000000..88cb34d --- /dev/null +++ b/lib/libc/iconv/iconv.c @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/iconv.c 281550 2015-04-15 09:09:20Z tijl $ + */ + +#include +#include +#include "iconv-internal.h" + +size_t +iconv(iconv_t a, char ** __restrict b, + size_t * __restrict c, char ** __restrict d, + size_t * __restrict e) +{ + return __bsd_iconv(a, b, c, d, e); +} diff --git a/lib/libc/iconv/iconv_canonicalize.3 b/lib/libc/iconv/iconv_canonicalize.3 new file mode 100644 index 0000000..9284f50 --- /dev/null +++ b/lib/libc/iconv/iconv_canonicalize.3 @@ -0,0 +1,74 @@ +.\" Copyright (c) 2009 Gabor Kovesdan +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/iconv/iconv_canonicalize.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.Dd October 20, 2009 +.Dt ICONV_CANONICALIZE 3 +.Os +.Sh NAME +.Nm iconv_canonicalize +.Nd resolving character encoding names to canonical form +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In iconv.h +.Ft const char * +.Fn iconv_canonicalize "const char *name" +.Sh DESCRIPTION +The +.Fn iconv_canonicalize +function resolves the character encoding name specified by the +.Fa name +argument to its canonical form. +.Sh RETURN VALUES +Upon successful completion +.Fn iconv_canonicalize , +returns the canonical name of the given encoding. +If the specified name is already a canonical name, the same +value is returned. +If the specified name is not an existing character encoding +name, NULL is returned. +.Sh SEE ALSO +.Xr iconv 3 +.Sh STANDARDS +The +.Nm +function is a non-standard extension, which appeared in +the GNU implementation and was adopted in +.Fx 9.0 +for compatibility's sake. +.Sh AUTHORS +This manual page was written by +.An Gabor Kovesdan Aq Mt gabor@FreeBSD.org . diff --git a/lib/libc/iconv/iconv_canonicalize.c b/lib/libc/iconv/iconv_canonicalize.c new file mode 100644 index 0000000..a418691 --- /dev/null +++ b/lib/libc/iconv/iconv_canonicalize.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/iconv_canonicalize.c 258587 2013-11-25 20:17:55Z peter $ + */ + +#include +#include +#include "iconv-internal.h" + +const char * +iconv_canonicalize(const char *a) +{ + return __bsd_iconv_canonicalize(a); +} diff --git a/lib/libc/iconv/iconv_close.c b/lib/libc/iconv/iconv_close.c new file mode 100644 index 0000000..5707cdd --- /dev/null +++ b/lib/libc/iconv/iconv_close.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/iconv_close.c 258587 2013-11-25 20:17:55Z peter $ + */ + +#include +#include +#include "iconv-internal.h" + +int +iconv_close(iconv_t a) +{ + return __bsd_iconv_close(a); +} diff --git a/lib/libc/iconv/iconv_compat.c b/lib/libc/iconv/iconv_compat.c new file mode 100644 index 0000000..aeddd6e --- /dev/null +++ b/lib/libc/iconv/iconv_compat.c @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/iconv_compat.c 281550 2015-04-15 09:09:20Z tijl $ + */ + +/* + * These are ABI implementations for when the raw iconv_* symbol + * space was exposed via libc.so.7 in its early life. This is + * a transition aide, these wrappers will not normally ever be + * executed except via __sym_compat() references. + */ +#include +#include +#include "iconv-internal.h" + +size_t +__iconv_compat(iconv_t a, char ** b, size_t * c, char ** d, + size_t * e, __uint32_t f, size_t *g) +{ + return __bsd___iconv(a, b, c, d, e, f, g); +} + +void +__iconv_free_list_compat(char ** a, size_t b) +{ + __bsd___iconv_free_list(a, b); +} + +int +__iconv_get_list_compat(char ***a, size_t *b, __iconv_bool c) +{ + return __bsd___iconv_get_list(a, b, c); +} + +size_t +iconv_compat(iconv_t a, char ** __restrict b, + size_t * __restrict c, char ** __restrict d, + size_t * __restrict e) +{ + return __bsd_iconv(a, b, c, d, e); +} + +const char * +iconv_canonicalize_compat(const char *a) +{ + return __bsd_iconv_canonicalize(a); +} + +int +iconv_close_compat(iconv_t a) +{ + return __bsd_iconv_close(a); +} + +iconv_t +iconv_open_compat(const char *a, const char *b) +{ + return __bsd_iconv_open(a, b); +} + +int +iconv_open_into_compat(const char *a, const char *b, iconv_allocation_t *c) +{ + return __bsd_iconv_open_into(a, b, c); +} + +void +iconv_set_relocation_prefix_compat(const char *a, const char *b) +{ + return __bsd_iconv_set_relocation_prefix(a, b); +} + +int +iconvctl_compat(iconv_t a, int b, void *c) +{ + return __bsd_iconvctl(a, b, c); +} + +void +iconvlist_compat(int (*a) (unsigned int, const char * const *, void *), void *b) +{ + return __bsd_iconvlist(a, b); +} + +int _iconv_version_compat = 0x0108; /* Magic - not used */ + +__sym_compat(__iconv, __iconv_compat, FBSD_1.2); +__sym_compat(__iconv_free_list, __iconv_free_list_compat, FBSD_1.2); +__sym_compat(__iconv_get_list, __iconv_get_list_compat, FBSD_1.2); +__sym_compat(_iconv_version, _iconv_version_compat, FBSD_1.3); +__sym_compat(iconv, iconv_compat, FBSD_1.3); +__sym_compat(iconv_canonicalize, iconv_canonicalize_compat, FBSD_1.2); +__sym_compat(iconv_close, iconv_close_compat, FBSD_1.3); +__sym_compat(iconv_open, iconv_open_compat, FBSD_1.3); +__sym_compat(iconv_open_into, iconv_open_into_compat, FBSD_1.3); +__sym_compat(iconv_set_relocation_prefix, iconv_set_relocation_prefix_compat, FBSD_1.3); +__sym_compat(iconvctl, iconvctl_compat, FBSD_1.3); +__sym_compat(iconvlist, iconvlist_compat, FBSD_1.3); diff --git a/lib/libc/iconv/iconv_open.c b/lib/libc/iconv/iconv_open.c new file mode 100644 index 0000000..8da8c90 --- /dev/null +++ b/lib/libc/iconv/iconv_open.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/iconv_open.c 258587 2013-11-25 20:17:55Z peter $ + */ + +#include +#include +#include "iconv-internal.h" + +iconv_t +iconv_open(const char *a, const char *b) +{ + return __bsd_iconv_open(a, b); +} diff --git a/lib/libc/iconv/iconv_open_into.c b/lib/libc/iconv/iconv_open_into.c new file mode 100644 index 0000000..92dbbb0 --- /dev/null +++ b/lib/libc/iconv/iconv_open_into.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/iconv_open_into.c 258587 2013-11-25 20:17:55Z peter $ + */ + +#include +#include +#include "iconv-internal.h" + +int +iconv_open_into(const char *a, const char *b, iconv_allocation_t *c) +{ + return __bsd_iconv_open_into(a, b, c); +} diff --git a/lib/libc/iconv/iconv_set_relocation_prefix.c b/lib/libc/iconv/iconv_set_relocation_prefix.c new file mode 100644 index 0000000..bfd389e --- /dev/null +++ b/lib/libc/iconv/iconv_set_relocation_prefix.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/iconv_set_relocation_prefix.c 258587 2013-11-25 20:17:55Z peter $ + */ + +#include +#include +#include "iconv-internal.h" + +void +iconv_set_relocation_prefix(const char *a, const char *b) +{ + return __bsd_iconv_set_relocation_prefix(a, b); +} diff --git a/lib/libc/iconv/iconvctl.3 b/lib/libc/iconv/iconvctl.3 new file mode 100644 index 0000000..d54dd03 --- /dev/null +++ b/lib/libc/iconv/iconvctl.3 @@ -0,0 +1,189 @@ +.\" Copyright (c) 2009 Gabor Kovesdan +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/iconv/iconvctl.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.Dd November 25, 2009 +.Dt ICONVCTL 3 +.Os +.Sh NAME +.Nm iconvctl +.Nd controlling and diagnostical facility for +.Xr iconv 3 +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In iconv.h +.Ft int +.Fn iconvctl "iconv_t cd" "int request" "void *argument" +.Sh DESCRIPTION +The +.Fn iconvctl +function can retrieve or set specific conversion +setting from the +.Fa cd +conversion descriptor. +The +.Fa request +parameter specifies the operation to accomplish and +.Fa argument +is an operation-specific argument. +.Pp +The possible operations are the following: +.Bl -tag -width indent +.It ICONV_TRIVIALP +In this case +.Fa argument +is an +.Ft int * +variable, which is set to 1 if the encoding is trivial one, i.e. +the input and output encodings are the same. +Otherwise, the variable will be 0. +.It ICONV_GET_TRANSLITERATE +Determines if transliteration is enabled. +The answer is stored in +.Fa argument , +which is of +.Ft int * . +It will be set to 1 if this feature is enabled or set to 0 otherwise. +.It ICONV_SET_TRANSLITERATE +Enables transliteration if +.Fa argument , +which is of +.Ft int * +set to 1 or disables it if +.Fa argument +is set to 0. +.It ICONV_GET_DISCARD_ILSEQ +Determines if illegal sequences are discarded or not. +The answer is stored in +.Fa argument , +which is of +.Ft int * . +It will be set to 1 if this feature is enabled or set to 0 otherwise. +.It ICONV_SET_DISCARD_ILSEQ +Sets whether illegal sequences are discarded or not. +.Fa argument , +which is of +.Ft int * +set to 1 or disables it if +.Fa argument +is set to 0. +.It ICONV_SET_HOOKS +Sets callback functions, which will be called back after successful +conversions. +The callback functions are stored in a +.Ft struct iconv_hooks +variable, which is passed to +.Nm +via +.Fa argument +by its address. +.It ICONV_GET_ILSEQ_INVALID +Determines if a character in the input buffer that is valid, +but for which an identical character does not exist in the target +codeset returns +.Er EILSEQ +or not. +The answer is stored in +.Fa argument , +which is of +.Ft int * . +It will be set to 1 if this feature is enabled or set to 0 otherwise. +.It ICONV_SET_ILSEQ_INVALID +Sets whether a character in the input buffer that is valid, +but for which an identical character does not exist in the target +codeset returns +.Er EILSEQ +or not. +If +.Fa argument , +which is of +.Ft int * +is set to 1 it will be enabled, +and if +.Fa argument +is set to 0 it will be disabled. +.El +.\" XXX: fallbacks are unimplemented and trying to set them will always +.\" return EOPNOTSUPP but definitions are provided for source-level +.\" compatibility. +.\".It ICONV_SET_FALLBACKS +.\"Sets callback functions, which will be called back after failed +.\"conversions. +.\"The callback functions are stored in a +.\".Ft struct iconv_fallbacks +.\"variable, which is passed to +.\".Nm +.\"via +.\".Fa argument +.\"by its address. +.Sh RETURN VALUES +Upon successful completion +.Fn iconvctl , +returns 0. +Otherwise, \-1 is returned and errno is set to +specify the kind of error. +.Sh ERRORS +The +.Fn iconvctl +function may cause an error in the following cases: +.Bl -tag -width Er +.It Bq Er EINVAL +Unknown or unimplemented operation. +.It Bq Er EBADF +The conversion descriptor specified by +.Fa cd +is invalid. +.El +.Sh SEE ALSO +.Xr iconv 1 , +.Xr iconv 3 +.Sh STANDARDS +The +.Nm +facility is a non-standard extension, which appeared in +the GNU implementation and was adopted in +.Fx 9.0 +for compatibility's sake. +.Sh AUTHORS +This manual page was written by +.An Gabor Kovesdan Aq Mt gabor@FreeBSD.org . +.Sh BUGS +Transliteration is enabled in this implementation by default, so it +is impossible by design to turn it off. +Accordingly, trying to turn it off will always fail and \-1 will be +returned. +Getting the transliteration state will always succeed and indicate +that it is turned on, though. diff --git a/lib/libc/iconv/iconvctl.c b/lib/libc/iconv/iconvctl.c new file mode 100644 index 0000000..2021616 --- /dev/null +++ b/lib/libc/iconv/iconvctl.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/iconvctl.c 258587 2013-11-25 20:17:55Z peter $ + */ + +#include +#include +#include "iconv-internal.h" + +int +iconvctl(iconv_t a, int b, void *c) +{ + return __bsd_iconvctl(a, b, c); +} diff --git a/lib/libc/iconv/iconvlist.3 b/lib/libc/iconv/iconvlist.3 new file mode 100644 index 0000000..1f234c0 --- /dev/null +++ b/lib/libc/iconv/iconvlist.3 @@ -0,0 +1,93 @@ +.\" Copyright (c) 2009 Gabor Kovesdan +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" Portions of this text are reprinted and reproduced in electronic form +.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- +.\" Portable Operating System Interface (POSIX), The Open Group Base +.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of +.\" Electrical and Electronics Engineers, Inc and The Open Group. In the +.\" event of any discrepancy between this version and the original IEEE and +.\" The Open Group Standard, the original IEEE and The Open Group Standard is +.\" the referee document. The original Standard can be obtained online at +.\" http://www.opengroup.org/unix/online.html. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/iconv/iconvlist.3 276294 2014-12-27 08:31:52Z joel $ +.\" +.Dd October 20, 2009 +.Dt ICONVLIST 3 +.Os +.Sh NAME +.Nm iconvlist +.Nd retrieving a list of character encodings supported by +.Xr iconv 3 +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In iconv.h +.Ft void +.Fo iconvlist +.Fa "int \*[lp]*do_one\*[rp]\*[lp]unsigned int *count, const char * const *names, void *arg\*[rp]" +.Fa "void *arg" +.Fc +.Sh DESCRIPTION +The +.Fn iconvlist +function obtains a list of character encodings that are supported by the +.Xr iconv 3 +call. +The +.Fn do_one +callback function will be called, where the +.Fa count +argument will be set to the number of the encoding names found, the +.Fa names +argument will be the list of the supported encoding names and the +.Fa arg +argument will be the \"outer\" +.Fa arg +argument of the +.Fn iconvlist +function. +This argument can be used to interchange custom data between the caller of +.Fn iconvlist +and the callback function. +.Pp +If an error occurs, +.Fa names +will be NULL when calling +.Fn do_one . +.Sh SEE ALSO +.Xr __iconv_free_list 3 , +.Xr __iconv_get_list 3 , +.Xr iconv 3 +.Sh STANDARDS +The +.Nm +function is a non-standard extension, which appeared in +the GNU implementation and was adopted in +.Fx 9.0 +for compatibility's sake. +.Sh AUTHORS +This manual page was written by +.An Gabor Kovesdan Aq Mt gabor@FreeBSD.org . diff --git a/lib/libc/iconv/iconvlist.c b/lib/libc/iconv/iconvlist.c new file mode 100644 index 0000000..a294770 --- /dev/null +++ b/lib/libc/iconv/iconvlist.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2013 Peter Wemm + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/iconv/iconvlist.c 258587 2013-11-25 20:17:55Z peter $ + */ + +#include +#include +#include "iconv-internal.h" + +void +iconvlist(int (*a) (unsigned int, const char * const *, void *), void *b) +{ + return __bsd_iconvlist(a, b); +} diff --git a/lib/libc/include/block_abi.h b/lib/libc/include/block_abi.h new file mode 100644 index 0000000..f9694ac --- /dev/null +++ b/lib/libc/include/block_abi.h @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2014 David T Chisnall + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/include/block_abi.h 264069 2014-04-03 08:08:36Z theraven $ + */ + +#ifdef __BLOCKS__ +/** + * Declares a block variable. This macro is defined in the trivial way for + * compilers that support blocks and exposing the ABI in the source for other + * compilers. + */ +#define DECLARE_BLOCK(retTy, name, argTys, ...)\ + retTy(^name)(argTys, ## __VA_ARGS__) +/** + * Calls a block variable. This macro is defined in the trivial way for + * compilers that support blocks and exposing the ABI in the source for other + * compilers. + */ +#define CALL_BLOCK(name, ...) name(__VA_ARGS__) +#else // !__BLOCKS__ +#define DECLARE_BLOCK(retTy, name, argTys, ...)\ + struct {\ + void *isa;\ + int flags;\ + int reserved;\ + retTy (*invoke)(void *, ...);\ + } *name +#define CALL_BLOCK(name, ...) (name)->invoke(name, __VA_ARGS__) +#endif // __BLOCKS__ +/** + * Returns the pointer to the block-invoke function. This is used for passing + * blocks to functions that want a function pointer and a data pointer. + */ +#define GET_BLOCK_FUNCTION(x) \ + (((struct {\ + void *isa;\ + int flags;\ + int reserved;\ + void (*invoke)(void *, ...);\ + }*)(void*)x)->invoke) diff --git a/lib/libc/include/compat.h b/lib/libc/include/compat.h new file mode 100644 index 0000000..bc7e20c --- /dev/null +++ b/lib/libc/include/compat.h @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2009 Hudson River Trading LLC + * Written by: John H. Baldwin + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/include/compat.h 298830 2016-04-30 01:24:24Z pfg $ + */ + +/* + * This file defines compatibility symbol versions for old system calls. It + * is included in all generated system call files. + */ + +#ifndef __LIBC_COMPAT_H__ +#define __LIBC_COMPAT_H__ + +#define __sym_compat(sym,impl,verid) \ + .symver impl, sym@verid + +#ifndef NO_COMPAT7 +__sym_compat(__semctl, freebsd7___semctl, FBSD_1.0); +__sym_compat(msgctl, freebsd7_msgctl, FBSD_1.0); +__sym_compat(shmctl, freebsd7_shmctl, FBSD_1.0); +#endif + +#undef __sym_compat + +#define __weak_reference(sym,alias) \ + .weak alias;.equ alias,sym + +__weak_reference(__sys_fcntl,__fcntl_compat) + +#undef __weak_reference + +#endif /* __LIBC_COMPAT_H__ */ + diff --git a/lib/libc/include/errlst.h b/lib/libc/include/errlst.h new file mode 100644 index 0000000..bf373e4 --- /dev/null +++ b/lib/libc/include/errlst.h @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2013 Jilles Tjoelker + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/include/errlst.h 275004 2014-11-25 03:50:31Z emaste $ + */ + +#ifndef __ERRLST_H__ +#define __ERRLST_H__ + +#include + +#ifdef PIC +/* If the main executable imports these, do not use its copy from libc.so. */ +extern const char *const __hidden_sys_errlist[] __hidden; +extern const int __hidden_sys_nerr __hidden; +#else +#define __hidden_sys_errlist sys_errlist +#define __hidden_sys_nerr sys_nerr +#endif + +#endif /* __ERRLST_H__ */ diff --git a/lib/libc/include/isc/list.h b/lib/libc/include/isc/list.h new file mode 100644 index 0000000..87f7675 --- /dev/null +++ b/lib/libc/include/isc/list.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1997,1999 by Internet Software Consortium. + * + * 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 ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. + */ + +/* $FreeBSD: releng/11.1/lib/libc/include/isc/list.h 269867 2014-08-12 12:36:06Z ume $ */ + +#ifndef LIST_H +#define LIST_H 1 +#ifdef _LIBC +#include +#define INSIST(cond) assert(cond) +#else +#include +#endif + +#define LIST(type) struct { type *head, *tail; } +#define INIT_LIST(list) \ + do { (list).head = NULL; (list).tail = NULL; } while (0) + +#define LINK(type) struct { type *prev, *next; } +#define INIT_LINK_TYPE(elt, link, type) \ + do { \ + (elt)->link.prev = (type *)(-1); \ + (elt)->link.next = (type *)(-1); \ + } while (0) +#define INIT_LINK(elt, link) \ + INIT_LINK_TYPE(elt, link, void) +#define LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1) && \ + (void *)((elt)->link.next) != (void *)(-1)) + +#define HEAD(list) ((list).head) +#define TAIL(list) ((list).tail) +#define EMPTY(list) ((list).head == NULL) + +#define PREPEND(list, elt, link) \ + do { \ + INSIST(!LINKED(elt, link));\ + if ((list).head != NULL) \ + (list).head->link.prev = (elt); \ + else \ + (list).tail = (elt); \ + (elt)->link.prev = NULL; \ + (elt)->link.next = (list).head; \ + (list).head = (elt); \ + } while (0) + +#define APPEND(list, elt, link) \ + do { \ + INSIST(!LINKED(elt, link));\ + if ((list).tail != NULL) \ + (list).tail->link.next = (elt); \ + else \ + (list).head = (elt); \ + (elt)->link.prev = (list).tail; \ + (elt)->link.next = NULL; \ + (list).tail = (elt); \ + } while (0) + +#define UNLINK_TYPE(list, elt, link, type) \ + do { \ + INSIST(LINKED(elt, link));\ + if ((elt)->link.next != NULL) \ + (elt)->link.next->link.prev = (elt)->link.prev; \ + else { \ + INSIST((list).tail == (elt)); \ + (list).tail = (elt)->link.prev; \ + } \ + if ((elt)->link.prev != NULL) \ + (elt)->link.prev->link.next = (elt)->link.next; \ + else { \ + INSIST((list).head == (elt)); \ + (list).head = (elt)->link.next; \ + } \ + INIT_LINK_TYPE(elt, link, type); \ + } while (0) +#define UNLINK(list, elt, link) \ + UNLINK_TYPE(list, elt, link, void) + +#define PREV(elt, link) ((elt)->link.prev) +#define NEXT(elt, link) ((elt)->link.next) + +#define INSERT_BEFORE(list, before, elt, link) \ + do { \ + INSIST(!LINKED(elt, link));\ + if ((before)->link.prev == NULL) \ + PREPEND(list, elt, link); \ + else { \ + (elt)->link.prev = (before)->link.prev; \ + (before)->link.prev = (elt); \ + (elt)->link.prev->link.next = (elt); \ + (elt)->link.next = (before); \ + } \ + } while (0) + +#define INSERT_AFTER(list, after, elt, link) \ + do { \ + INSIST(!LINKED(elt, link));\ + if ((after)->link.next == NULL) \ + APPEND(list, elt, link); \ + else { \ + (elt)->link.next = (after)->link.next; \ + (after)->link.next = (elt); \ + (elt)->link.next->link.prev = (elt); \ + (elt)->link.prev = (after); \ + } \ + } while (0) + +#define ENQUEUE(list, elt, link) APPEND(list, elt, link) +#define DEQUEUE(list, elt, link) UNLINK(list, elt, link) + +#endif /* LIST_H */ +/*! \file */ diff --git a/lib/libc/include/isc/platform.h b/lib/libc/include/isc/platform.h new file mode 100644 index 0000000..d1dfff4 --- /dev/null +++ b/lib/libc/include/isc/platform.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC 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. + */ + +/* $Id: platform.h.in,v 1.2.6.2 2008/01/23 02:15:02 tbox Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/include/isc/platform.h 186090 2008-12-14 19:39:53Z ume $ */ + +/*! \file */ + +#ifndef ISC_PLATFORM_H +#define ISC_PLATFORM_H + +/* + * Define if the OS does not define struct timespec. + */ +#undef ISC_PLATFORM_NEEDTIMESPEC +#ifdef ISC_PLATFORM_NEEDTIMESPEC +#include /* For time_t */ +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; +#endif + +#endif diff --git a/lib/libc/include/nscache.h b/lib/libc/include/nscache.h new file mode 100644 index 0000000..a2cc2d3 --- /dev/null +++ b/lib/libc/include/nscache.h @@ -0,0 +1,197 @@ +/*- + * Copyright (c) 2005 Michael Bushkov + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/include/nscache.h 158115 2006-04-28 12:03:38Z ume $ + */ + +#ifndef __NS_CACHE_H__ +#define __NS_CACHE_H__ + +#include "nscachedcli.h" + +typedef int (*nss_cache_id_func_t)(char *, size_t *, va_list, void *); +typedef int (*nss_cache_marshal_func_t)(char *, size_t *, void *, va_list, + void *); +typedef int (*nss_cache_unmarshal_func_t)(char *, size_t, void *, va_list, + void *); + +typedef void (*nss_set_mp_ws_func_t)(cached_mp_write_session); +typedef cached_mp_write_session (*nss_get_mp_ws_func_t)(void); + +typedef void (*nss_set_mp_rs_func_t)(cached_mp_read_session); +typedef cached_mp_read_session (*nss_get_mp_rs_func_t)(void); + +typedef struct _nss_cache_info { + char *entry_name; + void *mdata; + + /* + * These 3 functions should be implemented specifically for each + * nsswitch database. + */ + nss_cache_id_func_t id_func; /* marshals the request parameters */ + nss_cache_marshal_func_t marshal_func; /* marshals response */ + nss_cache_unmarshal_func_t unmarshal_func; /* unmarshals response */ + + /* + * These 4 functions should be generated with NSS_MP_CACHE_HANDLING + * macro. + */ + nss_set_mp_ws_func_t set_mp_ws_func; /* sets current write session */ + nss_get_mp_ws_func_t get_mp_ws_func; /* gets current write session */ + + nss_set_mp_rs_func_t set_mp_rs_func; /* sets current read session */ + nss_get_mp_rs_func_t get_mp_rs_func; /* gets current read session */ +} nss_cache_info; + +/* + * NSS_MP_CACHE_HANDLING implements the set_mp_ws, get_mp_ws, set_mp_rs, + * get_mp_rs functions, that are used in _nss_cache_info. It uses + * NSS_TLS_HANDLING macro to organize thread local storage. + */ +#define NSS_MP_CACHE_HANDLING(name) \ +struct name##_mp_state { \ + cached_mp_write_session mp_write_session; \ + cached_mp_read_session mp_read_session; \ +}; \ + \ +static void \ +name##_mp_endstate(void *s) { \ + struct name##_mp_state *mp_state; \ + \ + mp_state = (struct name##_mp_state *)s; \ + if (mp_state->mp_write_session != INVALID_CACHED_MP_WRITE_SESSION)\ + __abandon_cached_mp_write_session(mp_state->mp_write_session);\ + \ + if (mp_state->mp_read_session != INVALID_CACHED_MP_READ_SESSION)\ + __close_cached_mp_read_session(mp_state->mp_read_session);\ +} \ +NSS_TLS_HANDLING(name##_mp); \ + \ +static void \ +name##_set_mp_ws(cached_mp_write_session ws) \ +{ \ + struct name##_mp_state *mp_state; \ + int res; \ + \ + res = name##_mp_getstate(&mp_state); \ + if (res != 0) \ + return; \ + \ + mp_state->mp_write_session = ws; \ +} \ + \ +static cached_mp_write_session \ +name##_get_mp_ws(void) \ +{ \ + struct name##_mp_state *mp_state; \ + int res; \ + \ + res = name##_mp_getstate(&mp_state); \ + if (res != 0) \ + return (INVALID_CACHED_MP_WRITE_SESSION); \ + \ + return (mp_state->mp_write_session); \ +} \ + \ +static void \ +name##_set_mp_rs(cached_mp_read_session rs) \ +{ \ + struct name##_mp_state *mp_state; \ + int res; \ + \ + res = name##_mp_getstate(&mp_state); \ + if (res != 0) \ + return; \ + \ + mp_state->mp_read_session = rs; \ +} \ + \ +static cached_mp_read_session \ +name##_get_mp_rs(void) \ +{ \ + struct name##_mp_state *mp_state; \ + int res; \ + \ + res = name##_mp_getstate(&mp_state); \ + if (res != 0) \ + return (INVALID_CACHED_MP_READ_SESSION); \ + \ + return (mp_state->mp_read_session); \ +} + +/* + * These macros should be used to initialize _nss_cache_info structure. For + * multipart queries in setXXXent and getXXXent functions mf and uf + * (marshal function and unmarshal function) should be both NULL. + */ +#define NS_COMMON_CACHE_INFO_INITIALIZER(name, mdata, if, mf, uf) \ + {#name, mdata, if, mf, uf, NULL, NULL, NULL, NULL} +#define NS_MP_CACHE_INFO_INITIALIZER(name, mdata, mf, uf) \ + {#name, mdata, NULL, mf, uf, name##_set_mp_ws, name##_get_mp_ws,\ + name##_set_mp_rs, name##_get_mp_rs } + +/* + * Analog of other XXX_CB macros. Has the pointer to _nss_cache_info + * structure as the only argument. + */ +#define NS_CACHE_CB(cinfo) {NSSRC_CACHE, __nss_cache_handler, (void *)(cinfo) }, + +/* args are: current pointer, current buffer, initial buffer, pointer type */ +#define NS_APPLY_OFFSET(cp, cb, ib, p_type) \ + if ((cp) != NULL) \ + (cp) = (p_type)((char *)(cb) + (size_t)(cp) - (size_t)(ib)) +/* + * Gets new pointer from the marshalled buffer by uisng initial address + * and initial buffer address + */ +#define NS_GET_NEWP(cp, cb, ib) \ + ((char *)(cb) + (size_t)(cp) - (size_t)(ib)) + +typedef struct _nss_cache_data { + char *key; + size_t key_size; + + nss_cache_info const *info; +} nss_cache_data; + +__BEGIN_DECLS +/* dummy function, which is needed to make nss_method_lookup happy */ +extern int __nss_cache_handler(void *, void *, va_list); + +#ifdef _NS_PRIVATE +extern int __nss_common_cache_read(void *, void *, va_list); +extern int __nss_common_cache_write(void *, void *, va_list); +extern int __nss_common_cache_write_negative(void *); + +extern int __nss_mp_cache_read(void *, void *, va_list); +extern int __nss_mp_cache_write(void *, void *, va_list); +extern int __nss_mp_cache_write_submit(void *, void *, va_list); +extern int __nss_mp_cache_end(void *, void *, va_list); +#endif /* _NS_PRIVATE */ + +__END_DECLS + +#endif diff --git a/lib/libc/include/nscachedcli.h b/lib/libc/include/nscachedcli.h new file mode 100644 index 0000000..e5f704f --- /dev/null +++ b/lib/libc/include/nscachedcli.h @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 2004 Michael Bushkov + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/include/nscachedcli.h 158115 2006-04-28 12:03:38Z ume $ + */ + +#ifndef __NS_CACHED_CLI_H__ +#define __NS_CACHED_CLI_H__ + +/* + * This file contains API for working with caching daemon + */ + +enum comm_element_t { + CET_UNDEFINED = 0, + CET_WRITE_REQUEST = 1, + CET_WRITE_RESPONSE = 2, + CET_READ_REQUEST = 3, + CET_READ_RESPONSE = 4, + CET_TRANSFORM_REQUEST = 5, + CET_TRANSFORM_RESPONSE = 6, + CET_MP_WRITE_SESSION_REQUEST = 7, + CET_MP_WRITE_SESSION_RESPONSE = 8, + CET_MP_WRITE_SESSION_WRITE_REQUEST = 9, + CET_MP_WRITE_SESSION_WRITE_RESPONSE = 10, + CET_MP_WRITE_SESSION_CLOSE_NOTIFICATION = 11, + CET_MP_WRITE_SESSION_ABANDON_NOTIFICATION = 12, + CET_MP_READ_SESSION_REQUEST = 13, + CET_MP_READ_SESSION_RESPONSE = 14, + CET_MP_READ_SESSION_READ_REQUEST = 15, + CET_MP_READ_SESSION_READ_RESPONSE = 16, + CET_MP_READ_SESSION_CLOSE_NOTIFICATION = 17 +}; + +struct cached_connection_params { + char *socket_path; + struct timeval timeout; +}; + +struct cached_connection_ { + int sockfd; + int read_queue; + int write_queue; + + int mp_flag; /* shows if the connection is used for + * multipart operations */ +}; + +/* simple abstractions for not to write "struct" every time */ +typedef struct cached_connection_ *cached_connection; +typedef struct cached_connection_ *cached_mp_write_session; +typedef struct cached_connection_ *cached_mp_read_session; + +#define INVALID_CACHED_CONNECTION (NULL) +#define INVALID_CACHED_MP_WRITE_SESSION (NULL) +#define INVALID_CACHED_MP_READ_SESSION (NULL) + +__BEGIN_DECLS + +/* initialization/destruction routines */ +extern cached_connection __open_cached_connection( + struct cached_connection_params const *); +extern void __close_cached_connection(cached_connection); + +/* simple read/write operations */ +extern int __cached_write(cached_connection, const char *, const char *, + size_t, const char *, size_t); +extern int __cached_read(cached_connection, const char *, const char *, + size_t, char *, size_t *); + +/* multipart read/write operations */ +extern cached_mp_write_session __open_cached_mp_write_session( + struct cached_connection_params const *, const char *); +extern int __cached_mp_write(cached_mp_write_session, const char *, size_t); +extern int __abandon_cached_mp_write_session(cached_mp_write_session); +extern int __close_cached_mp_write_session(cached_mp_write_session); + +extern cached_mp_read_session __open_cached_mp_read_session( + struct cached_connection_params const *, const char *); +extern int __cached_mp_read(cached_mp_read_session, char *, size_t *); +extern int __close_cached_mp_read_session(cached_mp_read_session); + +__END_DECLS + +#endif diff --git a/lib/libc/inet/Makefile.inc b/lib/libc/inet/Makefile.inc new file mode 100644 index 0000000..cd81776 --- /dev/null +++ b/lib/libc/inet/Makefile.inc @@ -0,0 +1,11 @@ +# $FreeBSD: releng/11.1/lib/libc/inet/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +# inet sources +.PATH: ${LIBC_SRCTOP}/inet + +SRCS+= inet_addr.c inet_cidr_ntop.c inet_cidr_pton.c inet_lnaof.c \ + inet_makeaddr.c inet_net_ntop.c inet_net_pton.c inet_neta.c \ + inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \ + inet_pton.c nsap_addr.c + +SYM_MAPS+= ${LIBC_SRCTOP}/inet/Symbol.map diff --git a/lib/libc/inet/Symbol.map b/lib/libc/inet/Symbol.map new file mode 100644 index 0000000..d1bc3d3 --- /dev/null +++ b/lib/libc/inet/Symbol.map @@ -0,0 +1,38 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/inet/Symbol.map 170548 2007-06-11 07:21:21Z delphij $ + */ + +FBSD_1.0 { + __inet_addr; + __inet_aton; + inet_addr; + inet_aton; + __inet_cidr_ntop; + __inet_cidr_pton; + __inet_lnaof; + inet_lnaof; + __inet_makeaddr; + inet_makeaddr; + __inet_net_ntop; + inet_net_ntop; + __inet_net_pton; + inet_net_pton; + __inet_neta; + inet_neta; + __inet_netof; + inet_netof; + __inet_network; + inet_network; + __inet_ntoa; + inet_ntoa; + __inet_ntoa_r; + inet_ntoa_r; + __inet_ntop; + inet_ntop; + __inet_pton; + inet_pton; + __inet_nsap_addr; + __inet_nsap_ntoa; + inet_nsap_addr; + inet_nsap_ntoa; +}; diff --git a/lib/libc/isc/Makefile.inc b/lib/libc/isc/Makefile.inc new file mode 100644 index 0000000..6e8a71d --- /dev/null +++ b/lib/libc/isc/Makefile.inc @@ -0,0 +1,6 @@ +# $FreeBSD: releng/11.1/lib/libc/isc/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +# isc sources +.PATH: ${LIBC_SRCTOP}/isc + +SRCS+= ev_streams.c ev_timers.c diff --git a/lib/libc/libc.ldscript b/lib/libc/libc.ldscript new file mode 100644 index 0000000..42a2c5c --- /dev/null +++ b/lib/libc/libc.ldscript @@ -0,0 +1,2 @@ +/* $FreeBSD: releng/11.1/lib/libc/libc.ldscript 258283 2013-11-17 22:52:17Z peter $ */ +GROUP ( @@SHLIB@@ @@LIBDIR@@/libc_nonshared.a @@LIBDIR@@/libssp_nonshared.a ) diff --git a/lib/libc/locale/DESIGN.xlocale b/lib/libc/locale/DESIGN.xlocale new file mode 100644 index 0000000..3dca58b --- /dev/null +++ b/lib/libc/locale/DESIGN.xlocale @@ -0,0 +1,159 @@ +$FreeBSD: releng/11.1/lib/libc/locale/DESIGN.xlocale 227753 2011-11-20 14:45:42Z theraven $ + +Design of xlocale +================= + +The xlocale APIs come from Darwin, although a subset is now part of POSIX 2008. +They fall into two broad categories: + +- Manipulation of per-thread locales (POSIX) +- Locale-aware functions taking an explicit locale argument (Darwin) + +This document describes the implementation of these APIs for FreeBSD. + +Goals +----- + +The overall goal of this implementation is to be compatible with the Darwin +version. Additionally, it should include minimal changes to the existing +locale code. A lot of the existing locale code originates with 4BSD or earlier +and has had over a decade of testing. Replacing this code, unless absolutely +necessary, gives us the potential for more bugs without much benefit. + +With this in mind, various libc-private functions have been modified to take a +locale_t parameter. This causes a compiler error if they are accidentally +called without a locale. This approach was taken, rather than adding _l +variants of these functions, to make it harder for accidental uses of the +global-locale versions to slip in. + +Locale Objects +-------------- + +A locale is encapsulated in a `locale_t`, which is an opaque type: a pointer to +a `struct _xlocale`. The name `_xlocale` is unfortunate, as it does not fit +well with existing conventions, but is used because this is the name the Darwin +implementation gives to this structure and so may be used by existing (bad) code. + +This structure should include all of the information corresponding to a locale. +A locale_t is almost immutable after creation. There are no functions that modify it, +and it can therefore be used without locking. It is the responsibility of the +caller to ensure that a locale is not deallocated during a call that uses it. + +Each locale contains a number of components, one for each of the categories +supported by `setlocale()`. These are likewise immutable after creation. This +differs from the Darwin implementation, which includes a deprecated +`setinvalidrune()` function that can modify the rune locale. + +The exception to these mutability rules is a set of `mbstate_t` flags stored +with each locale. These are used by various functions that previously had a +static local `mbstate_t` variable. + +The components are reference counted, and so can be aliased between locale +objects. This makes copying locales very cheap. + +The Global Locale +----------------- + +All locales and locale components are reference counted. The global locale, +however, is special. It, and all of its components, are static and so no +malloc() memory is required when using a single locale. + +This means that threads using the global locale are subject to the same +constraints as with the pre-xlocale libc. Calls to any locale-aware functions +in threads using the global locale, while modifying the global locale, have +undefined behaviour. + +Because of this, we have to ensure that we always copy the components of the +global locale, rather than alias them. + +It would be cleaner to simply remove the special treatment of the global locale +and have a locale_t lazily allocated for the global context. This would cost a +little more `malloc()` memory, so is not done in the initial version. + +Caching +------- + +The existing locale implementation included several ad-hoc caching layers. +None of these were thread safe. Caching is only really of use for supporting +the pattern where the locale is briefly changed to something and then changed +back. + +The current xlocale implementation removes the caching entirely. This pattern +is not one that should be encouraged. If you need to make some calls with a +modified locale, then you should use the _l suffix versions of the calls, +rather than switch the global locale. If you do need to temporarily switch the +locale and then switch it back, `uselocale()` provides a way of doing this very +easily: It returns the old locale, which can then be passed to a subsequent +call to `uselocale()` to restore it, without the need to load any locale data +from the disk. + +If, in the future, it is determined that caching is beneficial, it can be added +quite easily in xlocale.c. Given, however, that any locale-aware call is going +to be a preparation for presenting data to the user, and so is invariably going +to be part of an I/O operation, this seems like a case of premature +optimisation. + +localeconv +---------- + +The `localeconv()` function is an exception to the immutable-after-creation +rule. In the classic implementation, this function returns a pointer to some +global storage, which is initialised with the data from the current locale. +This is not possible in a multithreaded environment, with multiple locales. + +Instead, each locale contains a `struct lconv` that is lazily initialised on +calls to `localeconv()`. This is not protected by any locking, however this is +still safe on any machine where word-sized stores are atomic: two concurrent +calls will write the same data into the structure. + +Explicit Locale Calls +--------------------- + +A large number of functions have been modified to take an explicit `locale_t` +parameter. The old APIs are then reimplemented with a call to `__get_locale()` +to supply the `locale_t` parameter. This is in line with the Darwin public +APIs, but also simplifies the modifications to these functions. The +`__get_locale()` function is now the only way to access the current locale +within libc. All of the old globals have gone, so there is now a linker error +if any functions attempt to use them. + +The ctype.h functions are a little different. These are not implemented in +terms of their locale-aware versions, for performance reasons. Each of these +is implemented as a short inline function. + +Differences to Darwin APIs +-------------------------- + +`strtoq_l()` and `strtouq_l() `are not provided. These are extensions to +deprecated functions - we should not be encouraging people to use deprecated +interfaces. + +Locale Placeholders +------------------- + +The pointer values 0 and -1 have special meanings as `locale_t` values. Any +public function that accepts a `locale_t` parameter must use the `FIX_LOCALE()` +macro on it before using it. For efficiency, this can be emitted in functions +which *only* use their locale parameter as an argument to another public +function, as the callee will do the `FIX_LOCALE()` itself. + +Potential Improvements +---------------------- + +Currently, the current rune set is accessed via a function call. This makes it +fairly expensive to use any of the ctype.h functions. We could improve this +quite a lot by storing the rune locale data in a __thread-qualified variable. + +Several of the existing FreeBSD locale-aware functions appear to be wrong. For +example, most of the `strto*()` family should probably use `digittoint_l()`, +but instead they assume ASCII. These will break if using a character encoding +that does not put numbers and the letters A-F in the same location as ASCII. +Some functions, like `strcoll()` only work on single-byte encodings. No +attempt has been made to fix existing limitations in the libc functions other +than to add support for xlocale. + +Intuitively, setting a thread-local locale should ensure that all locale-aware +functions can be used safely from that thread. In fact, this is not the case +in either this implementation or the Darwin one. You must call `duplocale()` +or `newlocale()` before calling `uselocale()`. This is a bit ugly, and it +would be better if libc ensure that every thread had its own locale object. diff --git a/lib/libc/locale/Makefile.inc b/lib/libc/locale/Makefile.inc new file mode 100644 index 0000000..d522624 --- /dev/null +++ b/lib/libc/locale/Makefile.inc @@ -0,0 +1,90 @@ +# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/locale/Makefile.inc 291296 2015-11-25 09:12:30Z ngie $ + +# locale sources +.PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/locale ${LIBC_SRCTOP}/locale + +SRCS+= ascii.c big5.c btowc.c collate.c collcmp.c euc.c fix_grouping.c \ + gb18030.c gb2312.c gbk.c ctype.c isctype.c iswctype.c \ + ldpart.c lmessages.c lmonetary.c lnumeric.c localeconv.c mblen.c \ + mbrlen.c \ + mbrtowc.c mbsinit.c mbsnrtowcs.c \ + mbsrtowcs.c mbtowc.c mbstowcs.c \ + mskanji.c nextwctype.c nl_langinfo.c nomacros.c none.c rpmatch.c \ + rune.c \ + runetype.c setlocale.c setrunelocale.c \ + table.c \ + tolower.c toupper.c utf8.c wcrtomb.c wcsnrtombs.c \ + wcsrtombs.c wcsftime.c \ + wcstof.c wcstod.c \ + wcstoimax.c wcstol.c wcstold.c wcstoll.c \ + wcstombs.c \ + wcstoul.c wcstoull.c wcstoumax.c wctob.c wctomb.c wctrans.c wctype.c \ + wcwidth.c\ + xlocale.c + +.if ${MK_ICONV} != "no" +SRCS+= c16rtomb_iconv.c c32rtomb_iconv.c mbrtoc16_iconv.c mbrtoc32_iconv.c +.else +SRCS+= c16rtomb.c c32rtomb.c mbrtoc16.c mbrtoc32.c +.endif + +SYM_MAPS+=${LIBC_SRCTOP}/locale/Symbol.map + +MAN+= btowc.3 \ + ctype_l.3 \ + ctype.3 digittoint.3 isalnum.3 isalpha.3 isascii.3 isblank.3 iscntrl.3 \ + isdigit.3 isgraph.3 isideogram.3 islower.3 isphonogram.3 isprint.3 \ + ispunct.3 isrune.3 isspace.3 isspecial.3 \ + isupper.3 iswalnum.3 iswalnum_l.3 isxdigit.3 \ + localeconv.3 mblen.3 mbrlen.3 \ + mbrtowc.3 \ + mbsinit.3 \ + mbsrtowcs.3 mbstowcs.3 mbtowc.3 multibyte.3 \ + nextwctype.3 nl_langinfo.3 rpmatch.3 \ + setlocale.3 toascii.3 tolower.3 toupper.3 towlower.3 towupper.3 \ + wcsftime.3 \ + wcrtomb.3 \ + wcsrtombs.3 wcstod.3 wcstol.3 wcstombs.3 wctomb.3 \ + wctrans.3 wctype.3 wcwidth.3 \ + duplocale.3 freelocale.3 newlocale.3 querylocale.3 uselocale.3 xlocale.3 + +MAN+= big5.5 euc.5 gb18030.5 gb2312.5 gbk.5 mskanji.5 utf8.5 + +MLINKS+=btowc.3 wctob.3 +MLINKS+=isdigit.3 isnumber.3 +MLINKS+=isgraph.3 isgraph_l.3 +MLINKS+=islower.3 islower_l.3 +MLINKS+=ispunct.3 ispunct_l.3 +MLINKS+=isspace.3 isspace_l.3 +MLINKS+=nl_langinfo.3 nl_langinfo_l.3 +MLINKS+=iswalnum.3 iswalpha.3 iswalnum.3 iswascii.3 iswalnum.3 iswblank.3 \ + iswalnum.3 iswcntrl.3 iswalnum.3 iswdigit.3 iswalnum.3 iswgraph.3 \ + iswalnum.3 iswhexnumber.3 \ + iswalnum.3 iswideogram.3 iswalnum.3 iswlower.3 iswalnum.3 iswnumber.3 \ + iswalnum.3 iswphonogram.3 iswalnum.3 iswprint.3 iswalnum.3 iswpunct.3 \ + iswalnum.3 iswrune.3 iswalnum.3 iswspace.3 iswalnum.3 iswspecial.3 \ + iswalnum.3 iswupper.3 iswalnum.3 iswxdigit.3 +MLINKS+=iswalnum_l.3 iswalpha_l.3 iswalnum_l.3 iswcntrl_l.3 \ + iswalnum_l.3 iswctype_l.3 iswalnum_l.3 iswdigit_l.3 \ + iswalnum_l.3 iswgraph_l.3 iswalnum_l.3 iswlower_l.3 \ + iswalnum_l.3 iswprint_l.3 iswalnum_l.3 iswpunct_l.3 \ + iswalnum_l.3 iswspace_l.3 iswalnum_l.3 iswupper_l.3 \ + iswalnum_l.3 iswxdigit_l.3 iswalnum_l.3 towlower_l.3 \ + iswalnum_l.3 towupper_l.3 iswalnum_l.3 wctype_l.3 \ + iswalnum_l.3 iswblank_l.3 iswalnum_l.3 iswhexnumber_l.3 \ + iswalnum_l.3 iswideogram_l.3 iswalnum_l.3 iswnumber_l.3 \ + iswalnum_l.3 iswphonogram_l.3 iswalnum_l.3 iswrune_l.3 \ + iswalnum_l.3 iswspecial_l.3 iswalnum_l.3 nextwctype_l.3 \ + iswalnum_l.3 towctrans_l.3 iswalnum_l.3 wctrans_l.3 +MLINKS+=isxdigit.3 ishexnumber.3 +MLINKS+=localeconv.3 localeconv_l.3 +MLINKS+=mbrtowc.3 mbrtoc16.3 mbrtowc.3 mbrtoc32.3 +MLINKS+=mbsrtowcs.3 mbsnrtowcs.3 +MLINKS+=wcrtomb.3 c16rtomb.3 wcrtomb.3 c32rtomb.3 +MLINKS+=wcsrtombs.3 wcsnrtombs.3 +MLINKS+=wcstod.3 wcstof.3 wcstod.3 wcstold.3 +MLINKS+=wcstol.3 wcstoul.3 wcstol.3 wcstoll.3 wcstol.3 wcstoull.3 \ + wcstol.3 wcstoimax.3 wcstol.3 wcstoumax.3 +MLINKS+=wctrans.3 towctrans.3 +MLINKS+=wctype.3 iswctype.3 diff --git a/lib/libc/locale/Symbol.map b/lib/libc/locale/Symbol.map new file mode 100644 index 0000000..1079f18 --- /dev/null +++ b/lib/libc/locale/Symbol.map @@ -0,0 +1,217 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/locale/Symbol.map 250883 2013-05-21 19:59:37Z ed $ + */ + +FBSD_1.0 { + btowc; + digittoint; + isalnum; + isalpha; + isascii; + isblank; + iscntrl; + isdigit; + isgraph; + ishexnumber; + isideogram; + islower; + isnumber; + isphonogram; + isprint; + ispunct; + isrune; + isspace; + isspecial; + isupper; + isxdigit; + toascii; + tolower; + toupper; + iswalnum; + iswalpha; + iswascii; + iswblank; + iswcntrl; + iswdigit; + iswgraph; + iswhexnumber; + iswideogram; + iswlower; + iswnumber; + iswphonogram; + iswprint; + iswpunct; + iswrune; + iswspace; + iswspecial; + iswupper; + iswxdigit; + towlower; + towupper; + localeconv; + mblen; + mbrlen; + mbrtowc; + mbsinit; + mbsnrtowcs; + mbsrtowcs; + mbstowcs; + mbtowc; + nextwctype; + nl_langinfo; + __maskrune; + __sbmaskrune; + __istype; + __sbistype; + __isctype; + __toupper; + __sbtoupper; + __tolower; + __sbtolower; + __wcwidth; + __mb_cur_max; + __mb_sb_limit; + rpmatch; + ___runetype; + setlocale; + _DefaultRuneLocale; + _CurrentRuneLocale; + ___tolower; + ___toupper; + wcrtomb; + wcsftime; + wcsnrtombs; + wcsrtombs; + wcstod; + wcstof; + wcstoimax; + wcstol; + wcstold; + wcstoll; + wcstombs; + wcstoul; + wcstoull; + wcstoumax; + wctob; + wctomb; + towctrans; + wctrans; + iswctype; + wctype; + wcwidth; +}; + +FBSD_1.3 { + newlocale; + duplocale; + freelocale; + querylocale; + uselocale; + __getCurrentRuneLocale; + btowc_l; + localeconv_l; + mblen_l; + mbrlen_l; + mbrtowc_l; + mbsinit_l; + mbsnrtowcs_l; + mbsrtowcs_l; + mbstowcs_l; + mbtowc_l; + nl_langinfo_l; + strcoll_l; + strfmon_l; + strftime_l; + strptime_l; + strxfrm_l; + wcrtomb_l; + wcscoll_l; + wcsnrtombs_l; + wcsrtombs_l; + wcstombs_l; + wcsxfrm_l; + wctob_l; + wctomb_l; + ___tolower_l; + ___toupper_l; + ___runetype_l; + digittoint_l; + isalnum_l; + isalpha_l; + isblank_l; + iscntrl_l; + isdigit_l; + isgraph_l; + ishexnumber_l; + isideogram_l; + islower_l; + isnumber_l; + isphonogram_l; + isprint_l; + ispunct_l; + isrune_l; + isspace_l; + isspecial_l; + isupper_l; + isxdigit_l; + tolower_l; + toupper_l; + iswalnum_l; + iswalpha_l; + iswblank_l; + iswcntrl_l; + iswdigit_l; + iswgraph_l; + iswhexnumber_l; + iswideogram_l; + iswlower_l; + iswnumber_l; + iswphonogram_l; + iswprint_l; + iswpunct_l; + iswrune_l; + iswspace_l; + iswspecial_l; + iswupper_l; + iswxdigit_l; + towlower_l; + towupper_l; + iswctype_l; + wctype_l; + nextwctype_l; + ___mb_cur_max; + ___mb_cur_max_l; + towctrans_l; + wctrans_l; + wcsftime_l; + wcstod_l; + wcstof_l; + wcstoimax_l; + wcstol_l; + wcstold_l; + wcstoll_l; + wcstoul_l; + wcstoull_l; + wcstoumax_l; + __sbistype_l; + __maskrune_l; + __sbmaskrune_l; + __istype_l; + __runes_for_locale; + _ThreadRuneLocale; + c16rtomb; + c16rtomb_l; + c32rtomb; + c32rtomb_l; + mbrtoc16; + mbrtoc16_l; + mbrtoc32; + mbrtoc32_l; +}; + +FBSDprivate_1.0 { + _PathLocale; + __detect_path_locale; + __collate_load_error; + __collate_range_cmp; +}; diff --git a/lib/libc/locale/ascii.c b/lib/libc/locale/ascii.c new file mode 100644 index 0000000..97f437a --- /dev/null +++ b/lib/libc/locale/ascii.c @@ -0,0 +1,194 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * 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. + * 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. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/locale/ascii.c 302408 2016-07-08 00:04:57Z gjb $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mblocal.h" + +static size_t _ascii_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _ascii_mbsinit(const mbstate_t *); +static size_t _ascii_mbsnrtowcs(wchar_t * __restrict dst, + const char ** __restrict src, size_t nms, size_t len, + mbstate_t * __restrict ps __unused); +static size_t _ascii_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); +static size_t _ascii_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict); + +int +_ascii_init(struct xlocale_ctype *l,_RuneLocale *rl) +{ + + l->__mbrtowc = _ascii_mbrtowc; + l->__mbsinit = _ascii_mbsinit; + l->__mbsnrtowcs = _ascii_mbsnrtowcs; + l->__wcrtomb = _ascii_wcrtomb; + l->__wcsnrtombs = _ascii_wcsnrtombs; + l->runes = rl; + l->__mb_cur_max = 1; + l->__mb_sb_limit = 128; + return(0); +} + +static int +_ascii_mbsinit(const mbstate_t *ps __unused) +{ + + /* + * Encoding is not state dependent - we are always in the + * initial state. + */ + return (1); +} + +static size_t +_ascii_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps __unused) +{ + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (0); + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + if (*s & 0x80) { + errno = EILSEQ; + return ((size_t)-1); + } + if (pwc != NULL) + *pwc = (unsigned char)*s; + return (*s == '\0' ? 0 : 1); +} + +static size_t +_ascii_wcrtomb(char * __restrict s, wchar_t wc, + mbstate_t * __restrict ps __unused) +{ + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if (wc < 0 || wc > 127) { + errno = EILSEQ; + return ((size_t)-1); + } + *s = (unsigned char)wc; + return (1); +} + +static size_t +_ascii_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, + size_t nms, size_t len, mbstate_t * __restrict ps __unused) +{ + const char *s; + size_t nchr; + + if (dst == NULL) { + for (s = *src; nms > 0 && *s != '\0'; s++, nms--) { + if (*s & 0x80) { + errno = EILSEQ; + return ((size_t)-1); + } + } + return (s - *src); + } + + s = *src; + nchr = 0; + while (len-- > 0 && nms-- > 0) { + if (*s & 0x80) { + *src = s; + errno = EILSEQ; + return ((size_t)-1); + } + if ((*dst++ = (unsigned char)*s++) == L'\0') { + *src = NULL; + return (nchr); + } + nchr++; + } + *src = s; + return (nchr); +} + +static size_t +_ascii_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, + size_t nwc, size_t len, mbstate_t * __restrict ps __unused) +{ + const wchar_t *s; + size_t nchr; + + if (dst == NULL) { + for (s = *src; nwc > 0 && *s != L'\0'; s++, nwc--) { + if (*s < 0 || *s > 127) { + errno = EILSEQ; + return ((size_t)-1); + } + } + return (s - *src); + } + + s = *src; + nchr = 0; + while (len-- > 0 && nwc-- > 0) { + if (*s < 0 || *s > 127) { + *src = s; + errno = EILSEQ; + return ((size_t)-1); + } + if ((*dst++ = *s++) == '\0') { + *src = NULL; + return (nchr); + } + nchr++; + } + *src = s; + return (nchr); +} + diff --git a/lib/libc/locale/big5.5 b/lib/libc/locale/big5.5 new file mode 100644 index 0000000..7bfdaa7 --- /dev/null +++ b/lib/libc/locale/big5.5 @@ -0,0 +1,51 @@ +.\" Copyright (c) 2002, 2003 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/big5.5 131608 2004-07-05 06:39:03Z ru $ +.\" +.Dd August 7, 2003 +.Dt BIG5 5 +.Os +.Sh NAME +.Nm big5 +.Nd +.Dq "Big Five" +encoding for Traditional Chinese text +.Sh SYNOPSIS +.Nm ENCODING +.Qq BIG5 +.Sh DESCRIPTION +.Dq Big Five +is the de facto standard for encoding Traditional Chinese text. +Each character is represented by either one or two bytes. +Characters from the +.Tn ASCII +character set are represented as single bytes in the range 0x00 - 0x7F. +Traditional Chinese characters are represented by two bytes: +the first in the range 0xA1 - 0xFE, the second in the range +0x40 - 0xFE. +.Sh SEE ALSO +.Xr euc 5 , +.Xr gb18030 5 , +.Xr utf8 5 diff --git a/lib/libc/locale/btowc.3 b/lib/libc/locale/btowc.3 new file mode 100644 index 0000000..9486eef --- /dev/null +++ b/lib/libc/locale/btowc.3 @@ -0,0 +1,88 @@ +.\" Copyright (c) 2002 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/btowc.3 248803 2013-03-27 21:31:40Z jilles $ +.\" +.Dd February 13, 2012 +.Dt BTOWC 3 +.Os +.Sh NAME +.Nm btowc , +.Nm wctob +.Nd "convert between wide and single-byte characters" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft wint_t +.Fn btowc "int c" +.Ft int +.Fn wctob "wint_t c" +.In wchar.h +.In xlocale.h +.Ft wint_t +.Fn btowc_l "int c" "locale_t loc" +.Ft int +.Fn wctob_l "wint_t c" "locale_t loc" +.Sh DESCRIPTION +The +.Fn btowc +function converts a single-byte character into a corresponding wide character. +If the character is +.Dv EOF +or not valid in the initial shift state, +.Fn btowc +returns +.Dv WEOF . +.Pp +The +.Fn wctob +function converts a wide character into a corresponding single-byte character. +If the wide character is +.Dv WEOF +or not able to be represented as a single byte in the initial shift state, +.Fn wctob +returns +.Dv EOF . +.Pp +The _l-suffixed versions take an explicit locale argument, while the +non-suffixed versions use the current global or per-thread locale. +.Sh SEE ALSO +.Xr mbrtowc 3 , +.Xr multibyte 3 , +.Xr wcrtomb 3 +.Sh STANDARDS +The +.Fn btowc +and +.Fn wctob +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn btowc +and +.Fn wctob +functions first appeared in +.Fx 5.0 . diff --git a/lib/libc/locale/c16rtomb.c b/lib/libc/locale/c16rtomb.c new file mode 100644 index 0000000..035700e --- /dev/null +++ b/lib/libc/locale/c16rtomb.c @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 2013 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/locale/c16rtomb.c 250883 2013-05-21 19:59:37Z ed $"); + +#include +#include +#include "xlocale_private.h" + +typedef struct { + char16_t lead_surrogate; + mbstate_t c32_mbstate; +} _Char16State; + +size_t +c16rtomb_l(char * __restrict s, char16_t c16, mbstate_t * __restrict ps, + locale_t locale) +{ + _Char16State *cs; + char32_t c32; + + FIX_LOCALE(locale); + if (ps == NULL) + ps = &locale->c16rtomb; + cs = (_Char16State *)ps; + + /* If s is a null pointer, the value of parameter c16 is ignored. */ + if (s == NULL) { + c32 = 0; + } else if (cs->lead_surrogate >= 0xd800 && + cs->lead_surrogate <= 0xdbff) { + /* We should see a trail surrogate now. */ + if (c16 < 0xdc00 || c16 > 0xdfff) { + errno = EILSEQ; + return ((size_t)-1); + } + c32 = 0x10000 + ((cs->lead_surrogate & 0x3ff) << 10 | + (c16 & 0x3ff)); + } else if (c16 >= 0xd800 && c16 <= 0xdbff) { + /* Store lead surrogate for next invocation. */ + cs->lead_surrogate = c16; + return (0); + } else { + /* Regular character. */ + c32 = c16; + } + cs->lead_surrogate = 0; + + return (c32rtomb_l(s, c32, &cs->c32_mbstate, locale)); +} + +size_t +c16rtomb(char * __restrict s, char16_t c16, mbstate_t * __restrict ps) +{ + + return (c16rtomb_l(s, c16, ps, __get_locale())); +} diff --git a/lib/libc/locale/c16rtomb_iconv.c b/lib/libc/locale/c16rtomb_iconv.c new file mode 100644 index 0000000..d0e017f --- /dev/null +++ b/lib/libc/locale/c16rtomb_iconv.c @@ -0,0 +1,8 @@ +/* $FreeBSD: releng/11.1/lib/libc/locale/c16rtomb_iconv.c 251314 2013-06-03 17:17:56Z ed $ */ +#define charXX_t char16_t +#define cXXrtomb c16rtomb +#define cXXrtomb_l c16rtomb_l +#define SRCBUF_LEN 2 +#define UTF_XX_INTERNAL "UTF-16-INTERNAL" + +#include "cXXrtomb_iconv.h" diff --git a/lib/libc/locale/c32rtomb.c b/lib/libc/locale/c32rtomb.c new file mode 100644 index 0000000..324838b --- /dev/null +++ b/lib/libc/locale/c32rtomb.c @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2013 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/locale/c32rtomb.c 250883 2013-05-21 19:59:37Z ed $"); + +#include +#include +#include +#include "xlocale_private.h" + +size_t +c32rtomb_l(char * __restrict s, char32_t c32, mbstate_t * __restrict ps, + locale_t locale) +{ + + /* Unicode Standard 5.0, D90: ill-formed characters. */ + if ((c32 >= 0xd800 && c32 <= 0xdfff) || c32 > 0x10ffff) { + errno = EILSEQ; + return ((size_t)-1); + } + + FIX_LOCALE(locale); + if (ps == NULL) + ps = &locale->c32rtomb; + + /* Assume wchar_t uses UTF-32. */ + return (wcrtomb_l(s, c32, ps, locale)); +} + +size_t +c32rtomb(char * __restrict s, char32_t c32, mbstate_t * __restrict ps) +{ + + return (c32rtomb_l(s, c32, ps, __get_locale())); +} diff --git a/lib/libc/locale/c32rtomb_iconv.c b/lib/libc/locale/c32rtomb_iconv.c new file mode 100644 index 0000000..c489fe2 --- /dev/null +++ b/lib/libc/locale/c32rtomb_iconv.c @@ -0,0 +1,8 @@ +/* $FreeBSD: releng/11.1/lib/libc/locale/c32rtomb_iconv.c 251314 2013-06-03 17:17:56Z ed $ */ +#define charXX_t char32_t +#define cXXrtomb c32rtomb +#define cXXrtomb_l c32rtomb_l +#define SRCBUF_LEN 1 +#define UTF_XX_INTERNAL "UTF-32-INTERNAL" + +#include "cXXrtomb_iconv.h" diff --git a/lib/libc/locale/cXXrtomb_iconv.h b/lib/libc/locale/cXXrtomb_iconv.h new file mode 100644 index 0000000..eb5ce8d --- /dev/null +++ b/lib/libc/locale/cXXrtomb_iconv.h @@ -0,0 +1,115 @@ +/*- + * Copyright (c) 2013 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/locale/cXXrtomb_iconv.h 281550 2015-04-15 09:09:20Z tijl $"); + +#include + +#include +#include +#include +#include + +#include "../iconv/citrus_hash.h" +#include "../iconv/citrus_module.h" +#include "../iconv/citrus_iconv.h" +#include "xlocale_private.h" + +typedef struct { + bool initialized; + struct _citrus_iconv iconv; + union { + charXX_t widechar[SRCBUF_LEN]; + char bytes[sizeof(charXX_t) * SRCBUF_LEN]; + } srcbuf; + size_t srcbuf_len; +} _ConversionState; +_Static_assert(sizeof(_ConversionState) <= sizeof(mbstate_t), + "Size of _ConversionState must not exceed mbstate_t's size."); + +size_t +cXXrtomb_l(char * __restrict s, charXX_t c, mbstate_t * __restrict ps, + locale_t locale) +{ + _ConversionState *cs; + struct _citrus_iconv *handle; + char *src, *dst; + size_t srcleft, dstleft, invlen; + int err; + + FIX_LOCALE(locale); + if (ps == NULL) + ps = &locale->cXXrtomb; + cs = (_ConversionState *)ps; + handle = &cs->iconv; + + /* Reinitialize mbstate_t. */ + if (s == NULL || !cs->initialized) { + if (_citrus_iconv_open(&handle, UTF_XX_INTERNAL, + nl_langinfo_l(CODESET, locale)) != 0) { + cs->initialized = false; + errno = EINVAL; + return (-1); + } + handle->cv_shared->ci_discard_ilseq = true; + handle->cv_shared->ci_hooks = NULL; + cs->srcbuf_len = 0; + cs->initialized = true; + if (s == NULL) + return (1); + } + + assert(cs->srcbuf_len < sizeof(cs->srcbuf.widechar) / sizeof(charXX_t)); + cs->srcbuf.widechar[cs->srcbuf_len++] = c; + + /* Perform conversion. */ + src = cs->srcbuf.bytes; + srcleft = cs->srcbuf_len * sizeof(charXX_t); + dst = s; + dstleft = MB_CUR_MAX_L(locale); + err = _citrus_iconv_convert(handle, &src, &srcleft, &dst, &dstleft, + 0, &invlen); + + /* Character is part of a surrogate pair. We need more input. */ + if (err == EINVAL) + return (0); + cs->srcbuf_len = 0; + + /* Illegal sequence. */ + if (dst == s) { + errno = EILSEQ; + return ((size_t)-1); + } + return (dst - s); +} + +size_t +cXXrtomb(char * __restrict s, charXX_t c, mbstate_t * __restrict ps) +{ + + return (cXXrtomb_l(s, c, ps, __get_locale())); +} diff --git a/lib/libc/locale/ctype.3 b/lib/libc/locale/ctype.3 new file mode 100644 index 0000000..d1df382 --- /dev/null +++ b/lib/libc/locale/ctype.3 @@ -0,0 +1,151 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)ctype.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/ctype.3 233648 2012-03-29 05:02:12Z eadler $ +.\" +.Dd March 30, 2004 +.Dt CTYPE 3 +.Os +.Sh NAME +.Nm digittoint , +.Nm isalnum , +.Nm isalpha , +.Nm isascii , +.Nm isblank , +.Nm iscntrl , +.Nm isdigit , +.Nm isgraph , +.Nm ishexnumber , +.Nm isideogram , +.Nm islower , +.Nm isnumber , +.Nm isphonogram , +.Nm isprint , +.Nm ispunct , +.Nm isrune , +.Nm isspace , +.Nm isspecial , +.Nm isupper , +.Nm isxdigit , +.Nm toascii , +.Nm tolower , +.Nm toupper +.Nd character classification functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn digittoint "int c" +.Ft int +.Fn isalnum "int c" +.Ft int +.Fn isalpha "int c" +.Ft int +.Fn isascii "int c" +.Ft int +.Fn iscntrl "int c" +.Ft int +.Fn isdigit "int c" +.Ft int +.Fn isgraph "int c" +.Ft int +.Fn ishexnumber "int c" +.Ft int +.Fn isideogram "int c" +.Ft int +.Fn islower "int c" +.Ft int +.Fn isnumber "int c" +.Ft int +.Fn isphonogram "int c" +.Ft int +.Fn isspecial "int c" +.Ft int +.Fn isprint "int c" +.Ft int +.Fn ispunct "int c" +.Ft int +.Fn isrune "int c" +.Ft int +.Fn isspace "int c" +.Ft int +.Fn isupper "int c" +.Ft int +.Fn isxdigit "int c" +.Ft int +.Fn toascii "int c" +.Ft int +.Fn tolower "int c" +.Ft int +.Fn toupper "int c" +.Sh DESCRIPTION +The above functions perform character tests and conversions on the integer +.Fa c . +They are available as macros, defined in the include file +.In ctype.h , +or as true functions in the C library. +See the specific manual pages for more information. +.Sh SEE ALSO +.Xr digittoint 3 , +.Xr isalnum 3 , +.Xr isalpha 3 , +.Xr isascii 3 , +.Xr isblank 3 , +.Xr iscntrl 3 , +.Xr isdigit 3 , +.Xr isgraph 3 , +.Xr isideogram 3 , +.Xr islower 3 , +.Xr isphonogram 3 , +.Xr isprint 3 , +.Xr ispunct 3 , +.Xr isrune 3 , +.Xr isspace 3 , +.Xr isspecial 3 , +.Xr isupper 3 , +.Xr isxdigit 3 , +.Xr toascii 3 , +.Xr tolower 3 , +.Xr toupper 3 , +.Xr wctype 3 , +.Xr ascii 7 +.Sh STANDARDS +These functions, except for +.Fn digittoint , +.Fn isascii , +.Fn ishexnumber , +.Fn isideogram , +.Fn isnumber , +.Fn isphonogram , +.Fn isrune , +.Fn isspecial +and +.Fn toascii , +conform to +.St -isoC . diff --git a/lib/libc/locale/ctype.c b/lib/libc/locale/ctype.c new file mode 100644 index 0000000..6ac09d7 --- /dev/null +++ b/lib/libc/locale/ctype.c @@ -0,0 +1,33 @@ +/*- + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/locale/ctype.c 227753 2011-11-20 14:45:42Z theraven $ + */ +#define _XLOCALE_INLINE +#include +#include +#include diff --git a/lib/libc/locale/ctype_l.3 b/lib/libc/locale/ctype_l.3 new file mode 100644 index 0000000..d58ddc1 --- /dev/null +++ b/lib/libc/locale/ctype_l.3 @@ -0,0 +1,151 @@ +.\" Copyright (c) 2011 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by David Chisnall under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" 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. +.\" +.\" 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/ctype_l.3 237939 2012-07-01 22:18:20Z jilles $ +.\" +.Dd March 6, 2012 +.Dt CTYPE_L 3 +.Os +.Sh NAME +.Nm digittoint_l , +.Nm isalnum_l , +.Nm isalpha_l , +.Nm isascii_l , +.Nm isblank_l , +.Nm iscntrl_l , +.Nm isdigit_l , +.Nm isgraph_l , +.Nm ishexnumber_l , +.Nm isideogram_l , +.Nm islower_l , +.Nm isnumber_l , +.Nm isphonogram_l , +.Nm isprint_l , +.Nm ispunct_l , +.Nm isrune_l , +.Nm isspace_l , +.Nm isspecial_l , +.Nm isupper_l , +.Nm isxdigit_l , +.Nm tolower_l , +.Nm toupper_l +.Nd character classification functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn digittoint_l "int c" "locale_t loc" +.Ft int +.Fn isalnum_l "int c" "locale_t loc" +.Ft int +.Fn isalpha_l "int c" "locale_t loc" +.Ft int +.Fn isascii_l "int c" "locale_t loc" +.Ft int +.Fn iscntrl_l "int c" "locale_t loc" +.Ft int +.Fn isdigit_l "int c" "locale_t loc" +.Ft int +.Fn isgraph_l "int c" "locale_t loc" +.Ft int +.Fn ishexnumber_l "int c" "locale_t loc" +.Ft int +.Fn isideogram_l "int c" "locale_t loc" +.Ft int +.Fn islower_l "int c" "locale_t loc" +.Ft int +.Fn isnumber_l "int c" "locale_t loc" +.Ft int +.Fn isphonogram_l "int c" "locale_t loc" +.Ft int +.Fn isspecial_l "int c" "locale_t loc" +.Ft int +.Fn isprint_l "int c" "locale_t loc" +.Ft int +.Fn ispunct_l "int c" "locale_t loc" +.Ft int +.Fn isrune_l "int c" "locale_t loc" +.Ft int +.Fn isspace_l "int c" "locale_t loc" +.Ft int +.Fn isupper_l "int c" "locale_t loc" +.Ft int +.Fn isxdigit_l "int c" "locale_t loc" +.Ft int +.Fn tolower_l "int c" "locale_t loc" +.Ft int +.Fn toupper_l "int c" "locale_t loc" +.Sh DESCRIPTION +The above functions perform character tests and conversions on the integer +.Fa c +in the locale +.Fa loc . +They behave in the same way as the versions without the _l suffix, but use the +specified locale rather than the global or per-thread locale. +.In ctype.h , +or as true functions in the C library. +See the specific manual pages for more information. +.Sh SEE ALSO +.Xr digittoint 3 , +.Xr isalnum 3 , +.Xr isalpha 3 , +.Xr isascii 3 , +.Xr isblank 3 , +.Xr iscntrl 3 , +.Xr isdigit 3 , +.Xr isgraph 3 , +.Xr isideogram 3 , +.Xr islower 3 , +.Xr isphonogram 3 , +.Xr isprint 3 , +.Xr ispunct 3 , +.Xr isrune 3 , +.Xr isspace 3 , +.Xr isspecial 3 , +.Xr isupper 3 , +.Xr isxdigit 3 , +.Xr tolower 3 , +.Xr toupper 3 , +.Xr wctype 3 , +.Xr xlocale 3 +.Sh STANDARDS +These functions conform to +.St -p1003.1-2008 , +except for +.Fn digittoint_l , +.Fn isascii_l , +.Fn ishexnumber_l , +.Fn isideogram_l , +.Fn isnumber_l , +.Fn isphonogram_l , +.Fn isrune_l +and +.Fn isspecial_l +which are +.Fx +extensions. diff --git a/lib/libc/locale/digittoint.3 b/lib/libc/locale/digittoint.3 new file mode 100644 index 0000000..c5722fc --- /dev/null +++ b/lib/libc/locale/digittoint.3 @@ -0,0 +1,68 @@ +.\" 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 +.\" 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. +.\" 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. +.\" +.\" @(#)digittoint.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/digittoint.3 276294 2014-12-27 08:31:52Z joel $ +.\" +.Dd April 6, 2001 +.Dt DIGITTOINT 3 +.Os +.Sh NAME +.Nm digittoint +.Nd convert a numeric character to its integer value +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn digittoint "int c" +.Ft int +.Fn digittoint_l "int c" "locale_t loc" +.Sh DESCRIPTION +The +.Fn digittoint +function converts a numeric character to its corresponding integer value. +The character can be any decimal digit or hexadecimal digit. +With hexadecimal characters, the case of the values does not matter. +.Pp +The +.Fn digittoint_l +function takes an explicit locale argument, whereas the +.Fn digittoint +function use the current global or per-thread locale. +.Sh RETURN VALUES +The +.Fn digittoint +function always returns an integer from the range of 0 to 15. +If the given character was not a digit as defined by +.Xr isxdigit 3 , +the function will return 0. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isdigit 3 , +.Xr isxdigit 3 , +.Xr xlocale 3 diff --git a/lib/libc/locale/duplocale.3 b/lib/libc/locale/duplocale.3 new file mode 100644 index 0000000..5706dc3 --- /dev/null +++ b/lib/libc/locale/duplocale.3 @@ -0,0 +1,79 @@ +.\" Copyright (c) 2011 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by David Chisnall under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" 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. +.\" +.\" 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/duplocale.3 281925 2015-04-24 10:17:55Z theraven $ +.\" +.Dd September 17, 2011 +.Dt DUPLOCALE 3 +.Os +.Sh NAME +.Nm duplocale +.Nd duplicate an locale +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In locale.h +.Ft locale_t +.Fn duplocale "locale_t locale" +.Sh DESCRIPTION +Duplicates an existing +.Fa locale_t +returning a new +.Fa locale_t +that refers to the same locale values but has an independent internal state. +Various functions, such as +.Xr mblen 3 +require a persistent state. +These functions formerly used static variables and calls to them from multiple +threads had undefined behavior. +They now use fields in the +.Fa locale_t +associated with the current thread by +.Xr uselocale 3 . +These calls are therefore only thread safe on threads with a unique per-thread +locale. +The locale returned by this call must be freed with +.Xr freelocale 3 . +.Sh SEE ALSO +.Xr freelocale 3 , +.Xr localeconv 3 , +.Xr newlocale 3 , +.Xr querylocale 3 , +.Xr uselocale 3 , +.Xr xlocale 3 +.Sh STANDARDS +This function conforms to +.St -p1003.1-2008 . +.Sh BUGS +Ideally, +.Xr uselocale 3 +should make a copy of the +.Fa locale_t +implicitly to ensure thread safety, +and a copy of the global locale should be installed lazily on each thread. +The FreeBSD implementation does not do this, +for compatibility with Darwin. diff --git a/lib/libc/locale/euc.5 b/lib/libc/locale/euc.5 new file mode 100644 index 0000000..86b053d --- /dev/null +++ b/lib/libc/locale/euc.5 @@ -0,0 +1,134 @@ +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Paul Borman at Krystal Technologies. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)euc.4 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/euc.5 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd November 8, 2003 +.Dt EUC 5 +.Os +.Sh NAME +.Nm euc +.Nd EUC encoding of wide characters +.Sh SYNOPSIS +.Nm ENCODING +.Qq EUC +.Pp +.Nm VARIABLE +.Ar len1 +.Ar mask1 +.Ar len2 +.Ar mask2 +.Ar len3 +.Ar mask3 +.Ar len4 +.Ar mask4 +.Ar mask +.Sh DESCRIPTION +.\"The +.\".Nm EUC +.\"encoding is provided for compatibility with +.\".Ux +.\"based systems. +.\"See +.\".Xr mklocale 1 +.\"for a complete description of the +.\".Ev LC_CTYPE +.\"source file format. +.\".Pp +.Nm EUC +implements a system of 4 multibyte codesets. +A multibyte character in the first codeset consists of +.Ar len1 +bytes starting with a byte in the range of 0x00 to 0x7f. +To allow use of +.Tn ASCII , +.Ar len1 +is always 1. +A multibyte character in the second codeset consists of +.Ar len2 +bytes starting with a byte in the range of 0x80-0xff excluding 0x8e and 0x8f. +A multibyte character in the third codeset consists of +.Ar len3 +bytes starting with the byte 0x8e. +A multibyte character in the fourth codeset consists of +.Ar len4 +bytes starting with the byte 0x8f. +.Pp +The +.Vt wchar_t +encoding of +.Nm EUC +multibyte characters is dependent on the +.Ar len +and +.Ar mask +arguments. +First, the bytes are moved into a +.Vt wchar_t +as follows: +.Bd -literal +byte0 << ((\fIlen\fPN-1) * 8) | byte1 << ((\fIlen\fPN-2) * 8) | ... | byte\fIlen\fPN-1 +.Ed +.Pp +The result is then ANDed with +.Ar ~mask +and ORed with +.Ar maskN . +Codesets 2 and 3 are special in that the leading byte (0x8e or 0x8f) is +first removed and the +.Ar lenN +argument is reduced by 1. +.Pp +For example, the +.Li ja_JP.eucJP +locale has the following +.Va VARIABLE +line: +.Bd -literal +VARIABLE 1 0x0000 2 0x8080 2 0x0080 3 0x8000 0x8080 +.Ed +.Pp +Codeset 1 consists of the values 0x0000 - 0x007f. +.Pp +Codeset 2 consists of the values who have the bits 0x8080 set. +.Pp +Codeset 3 consists of the values 0x0080 - 0x00ff. +.Pp +Codeset 4 consists of the values 0x8000 - 0xff7f excluding the values +which have the 0x0080 bit set. +.Pp +Notice that the global +.Ar mask +is set to 0x8080, this implies that from those 2 bits the codeset can +be determined. +.Sh SEE ALSO +.Xr mklocale 1 , +.Xr setlocale 3 diff --git a/lib/libc/locale/freelocale.3 b/lib/libc/locale/freelocale.3 new file mode 100644 index 0000000..96dc4a2 --- /dev/null +++ b/lib/libc/locale/freelocale.3 @@ -0,0 +1,68 @@ +.\" Copyright (c) 2011 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by David Chisnall under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" 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. +.\" +.\" 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/freelocale.3 281925 2015-04-24 10:17:55Z theraven $ +.Dd September 17, 2011 +.Dt FREELOCALE 3 +.Os +.Sh NAME +.Nm freelocale +.Nd Frees a locale created with +.Xr duplocale 3 +or +.Xr newlocale 3 +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In locale.h +.Ft int +.Fn freelocale "locale_t locale" +.Sh DESCRIPTION +Frees a +.Fa locale_t . +This relinquishes any resources held exclusively by this locale. +Note that locales share reference-counted components, +so a call to this function is not guaranteed to free all of the components. +.Sh RETURN VALUES +Returns 0 on success or -1 on error. +.Sh SEE ALSO +.Xr duplocale 3 , +.Xr localeconv 3 , +.Xr newlocale 3 , +.Xr querylocale 3 , +.Xr uselocale 3 , +.Xr xlocale 3 +.Sh STANDARDS +The +.Fn freelocale +function +differs from +.St -p1003.1-2008 +in that its return type is +.Vt int +rather than +.Vt void . diff --git a/lib/libc/locale/gb18030.5 b/lib/libc/locale/gb18030.5 new file mode 100644 index 0000000..27b350c --- /dev/null +++ b/lib/libc/locale/gb18030.5 @@ -0,0 +1,78 @@ +.\" Copyright (c) 2002, 2003 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/gb18030.5 131608 2004-07-05 06:39:03Z ru $ +.\" +.Dd August 10, 2003 +.Dt GB18030 5 +.Os +.Sh NAME +.Nm gb18030 +.Nd "GB 18030 encoding method for Chinese text" +.Sh SYNOPSIS +.Nm ENCODING +.Qq GB18030 +.Sh DESCRIPTION +The +.Nm GB18030 +encoding implements GB 18030-2000, a PRC national standard for the encoding of +Chinese characters. +It is a superset of the older GB\ 2312-1980 and GBK encodings, +and incorporates Unicode's Unihan Extension A completely. +It also provides code space for all Unicode 3.0 code points. +.Pp +Multibyte characters in the +.Nm GB18030 +encoding can be one byte, two bytes, or +four bytes long. +There are a total of over 1.5 million code positions. +.Pp +.No GB\ 11383-1981 Pq Tn ASCII +characters are represented by single bytes in the range 0x00 to 0x7F. +.Pp +Chinese characters are represented as either two bytes or four bytes. +Characters that are represented by two bytes begin with a byte in the range +0x81-0xFE and end with a byte either in the range 0x40-0x7E or 0x80-0xFE. +.Pp +Characters that are represented by four bytes begin with a byte in the range +0x81-0xFE, have a second byte in the range 0x30-0x39, a third byte in the range +0x81-0xFE and a fourth byte in the range 0x30-0x39. +.Sh SEE ALSO +.Xr euc 5 , +.Xr gb2312 5 , +.Xr gbk 5 , +.Xr utf8 5 +.Rs +.%T "Chinese National Standard GB 18030-2000: Information Technology -- Chinese ideograms coded character set for information interchange -- Extension for the basic set" +.%D "March 2000" +.Re +.Rs +.%Q "The Unicode Consortium" +.%T "The Unicode Standard, Version 3.0" +.%D "2000" +.Re +.Sh STANDARDS +The +.Nm GB18030 +encoding is believed to be compatible with GB 18030-2000. diff --git a/lib/libc/locale/gb2312.5 b/lib/libc/locale/gb2312.5 new file mode 100644 index 0000000..fbe83c7 --- /dev/null +++ b/lib/libc/locale/gb2312.5 @@ -0,0 +1,57 @@ +.\" Copyright (c) 2003 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/gb2312.5 131608 2004-07-05 06:39:03Z ru $ +.\" +.Dd November 7, 2003 +.Dt GB2312 5 +.Os +.Sh NAME +.Nm gb2312 +.Nd "GB2312 encoding method for Chinese text" +.Sh SYNOPSIS +.Nm ENCODING +.Qq GB2312 +.Sh DESCRIPTION +The +.Nm GB2312 +encoding implements GB\ 2312-1980, a PRC national standard +for the encoding of simplified Chinese characters. +.Pp +Multibyte characters in the GB2312 +encoding can be one byte or two bytes long. +.No GB\ 11383-1981 Pq Tn ASCII +characters are represented by single bytes in the range 0x00 to 0x7F. +Simplified Chinese characters are represented by two bytes, both in +the range 0xA1-0xFE. +.Sh SEE ALSO +.Xr euc 5 , +.Xr gb18030 5 , +.Xr gbk 5 +.Sh STANDARDS +The +.Nm GB2312 +encoding is believed to be compatible with GB\ 2312-1980. +This standard has been superseded by GB\ 18030-2000, but is still +in wide use. diff --git a/lib/libc/locale/gbk.5 b/lib/libc/locale/gbk.5 new file mode 100644 index 0000000..34ec55d --- /dev/null +++ b/lib/libc/locale/gbk.5 @@ -0,0 +1,63 @@ +.\" Copyright (c) 2003 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/gbk.5 131608 2004-07-05 06:39:03Z ru $ +.\" +.Dd August 10, 2003 +.Dt GBK 5 +.Os +.Sh NAME +.Nm gbk +.Nd "Guojia biaozhun kuozhan (GBK) encoding method for Chinese text" +.Sh SYNOPSIS +.Nm ENCODING +.Qq GBK +.Sh DESCRIPTION +GBK is a backwards-compatible extension of the GB\ 2312-1980 encoding +method for Chinese text, which adds the characters defined in the +Unified Han portion of the Unicode 2.1 standard. +.Pp +Multibyte characters in the GBK +encoding can be one byte or two bytes long. +.No GB\ 11383-1981 Pq Tn ASCII +characters are represented by single bytes in the range 0x00 to 0x7F. +Chinese characters are represented by two bytes, beginning with a byte in +the range 0x80-0xFE and ending with a byte in the range 0x40-0xFE. +.Sh SEE ALSO +.Xr euc 5 , +.Xr gb18030 5 , +.Xr gb2312 5 , +.Xr utf8 5 +.Rs +.%Q "The Unicode Consortium" +.%T "The Unicode Standard, Version 2.1" +.%D "1999" +.Re +.Rs +.%T "Chinese National Standard GB 18030-2000: Information Technology -- Chinese ideograms coded character set for information interchange -- Extension for the basic set" +.%D "March 2000" +.Re +.Sh STANDARDS +GBK is not a standard, but has been superseded by +GB\ 18030-2000. diff --git a/lib/libc/locale/isalnum.3 b/lib/libc/locale/isalnum.3 new file mode 100644 index 0000000..6a2ed86 --- /dev/null +++ b/lib/libc/locale/isalnum.3 @@ -0,0 +1,115 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)isalnum.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/isalnum.3 233992 2012-04-07 09:05:30Z joel $ +.\" +.Dd July 17, 2005 +.Dt ISALNUM 3 +.Os +.Sh NAME +.Nm isalnum +.Nd alphanumeric character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isalnum "int c" +.Ft int +.Fn isalnum_l "int c" "locale_t loc" +.Sh DESCRIPTION +The +.Fn isalnum +function tests for any character for which +.Xr isalpha 3 +or +.Xr isdigit 3 +is true. +The value of the argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Pp +In the ASCII character set, this includes the following characters +(with their numeric values shown in octal): +.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ +.It "\&060\ ``0''" Ta "061\ ``1''" Ta "062\ ``2''" Ta "063\ ``3''" Ta "064\ ``4''" +.It "\&065\ ``5''" Ta "066\ ``6''" Ta "067\ ``7''" Ta "070\ ``8''" Ta "071\ ``9''" +.It "\&101\ ``A''" Ta "102\ ``B''" Ta "103\ ``C''" Ta "104\ ``D''" Ta "105\ ``E''" +.It "\&106\ ``F''" Ta "107\ ``G''" Ta "110\ ``H''" Ta "111\ ``I''" Ta "112\ ``J''" +.It "\&113\ ``K''" Ta "114\ ``L''" Ta "115\ ``M''" Ta "116\ ``N''" Ta "117\ ``O''" +.It "\&120\ ``P''" Ta "121\ ``Q''" Ta "122\ ``R''" Ta "123\ ``S''" Ta "124\ ``T''" +.It "\&125\ ``U''" Ta "126\ ``V''" Ta "127\ ``W''" Ta "130\ ``X''" Ta "131\ ``Y''" +.It "\&132\ ``Z''" Ta "141\ ``a''" Ta "142\ ``b''" Ta "143\ ``c''" Ta "144\ ``d''" +.It "\&145\ ``e''" Ta "146\ ``f''" Ta "147\ ``g''" Ta "150\ ``h''" Ta "151\ ``i''" +.It "\&152\ ``j''" Ta "153\ ``k''" Ta "154\ ``l''" Ta "155\ ``m''" Ta "156\ ``n''" +.It "\&157\ ``o''" Ta "160\ ``p''" Ta "161\ ``q''" Ta "162\ ``r''" Ta "163\ ``s''" +.It "\&164\ ``t''" Ta "165\ ``u''" Ta "166\ ``v''" Ta "167\ ``w''" Ta "170\ ``x''" +.It "\&171\ ``y''" Ta "172\ ``z''" Ta \& Ta \& Ta \& +.El +.Pp +The +.Fn isalnum_l +function takes an explicit locale argument, whereas the +.Fn isalnum +function uses the current global or per-thread locale. +.Sh RETURN VALUES +The +.Fn isalnum +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswalnum +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isalpha 3 , +.Xr isdigit 3 , +.Xr iswalnum 3 , +.Xr xlocale 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isalnum +function conforms to +.St -isoC . +The +.Fn isalnum_l +function conforms to +.St -p1003.1-2008 . diff --git a/lib/libc/locale/isalpha.3 b/lib/libc/locale/isalpha.3 new file mode 100644 index 0000000..e9cc4c6 --- /dev/null +++ b/lib/libc/locale/isalpha.3 @@ -0,0 +1,113 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)isalpha.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/isalpha.3 233992 2012-04-07 09:05:30Z joel $ +.\" +.Dd July 17, 2005 +.Dt ISALPHA 3 +.Os +.Sh NAME +.Nm isalpha +.Nd alphabetic character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isalpha "int c" +.Ft int +.Fn isalpha_l "int c" "locale_t loc" +.Sh DESCRIPTION +The +.Fn isalpha +function tests for any character for which +.Xr isupper 3 +or +.Xr islower 3 +is true. +The value of the argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Pp +In the ASCII character set, this includes the following characters +(with their numeric values shown in octal): +.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ +.It "\&101\ ``A''" Ta "102\ ``B''" Ta "103\ ``C''" Ta "104\ ``D''" Ta "105\ ``E''" +.It "\&106\ ``F''" Ta "107\ ``G''" Ta "110\ ``H''" Ta "111\ ``I''" Ta "112\ ``J''" +.It "\&113\ ``K''" Ta "114\ ``L''" Ta "115\ ``M''" Ta "116\ ``N''" Ta "117\ ``O''" +.It "\&120\ ``P''" Ta "121\ ``Q''" Ta "122\ ``R''" Ta "123\ ``S''" Ta "124\ ``T''" +.It "\&125\ ``U''" Ta "126\ ``V''" Ta "127\ ``W''" Ta "130\ ``X''" Ta "131\ ``Y''" +.It "\&132\ ``Z''" Ta "141\ ``a''" Ta "142\ ``b''" Ta "143\ ``c''" Ta "144\ ``d''" +.It "\&145\ ``e''" Ta "146\ ``f''" Ta "147\ ``g''" Ta "150\ ``h''" Ta "151\ ``i''" +.It "\&152\ ``j''" Ta "153\ ``k''" Ta "154\ ``l''" Ta "155\ ``m''" Ta "156\ ``n''" +.It "\&157\ ``o''" Ta "160\ ``p''" Ta "161\ ``q''" Ta "162\ ``r''" Ta "163\ ``s''" +.It "\&164\ ``t''" Ta "165\ ``u''" Ta "166\ ``v''" Ta "167\ ``w''" Ta "170\ ``x''" +.It "\&171\ ``y''" Ta "172\ ``z''" Ta \& Ta \& Ta \& +.El +.Pp +The +.Fn isalpha_l +function takes an explicit locale argument, whereas the +.Fn isalpha +function uses the current global or per-thread locale. +.Sh RETURN VALUES +The +.Fn isalpha +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswalpha +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr islower 3 , +.Xr isupper 3 , +.Xr iswalpha 3 , +.Xr xlocale 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isalpha +function conforms to +.St -isoC . +The +.Fn isalpha_l +function conforms to +.St -p1003.1-2008 . diff --git a/lib/libc/locale/isascii.3 b/lib/libc/locale/isascii.3 new file mode 100644 index 0000000..ebd01a5 --- /dev/null +++ b/lib/libc/locale/isascii.3 @@ -0,0 +1,53 @@ +.\" Copyright (c) 1989, 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. +.\" 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. +.\" +.\" @(#)isascii.3 8.2 (Berkeley) 12/11/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/isascii.3 196820 2009-09-04 07:44:58Z des $ +.\" +.Dd October 6, 2002 +.Dt ISASCII 3 +.Os +.Sh NAME +.Nm isascii +.Nd test for ASCII character +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isascii "int c" +.Sh DESCRIPTION +The +.Fn isascii +function tests for an +.Tn ASCII +character, which is any character +between 0 and octal 0177 inclusive. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswascii 3 , +.Xr ascii 7 diff --git a/lib/libc/locale/isblank.3 b/lib/libc/locale/isblank.3 new file mode 100644 index 0000000..2b27cef --- /dev/null +++ b/lib/libc/locale/isblank.3 @@ -0,0 +1,96 @@ +.\" 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. +.\" 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. +.\" +.\" @(#)isblank.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/isblank.3 248803 2013-03-27 21:31:40Z jilles $ +.\" +.Dd July 17, 2005 +.Dt ISBLANK 3 +.Os +.Sh NAME +.Nm isblank +.Nd space or tab character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isblank "int c" +.Ft int +.Fn isblank_l "int c" "locale_t loc" +.Sh DESCRIPTION +The +.Fn isblank +function tests for a space or tab character. +For any locale, this includes the following standard characters: +.Bl -column XXXX +.It Do \et Dc Ta Dq " " +.El +.Pp +In the "C" locale, a successful +.Fn isblank +test is limited to these characters only. +The value of the argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Pp +The +.Fn isblank_l +function takes an explicit locale argument, whereas the +.Fn isblank +function uses the current global or per-thread locale. +.Sh RETURN VALUES +The +.Fn isblank +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswblank +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswblank 3 , +.Xr xlocale 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isblank +function +conforms to +.St -isoC-99 . +The +.Fn isblank_l +function conforms to +.St -p1003.1-2008 . diff --git a/lib/libc/locale/iscntrl.3 b/lib/libc/locale/iscntrl.3 new file mode 100644 index 0000000..bd4cc14 --- /dev/null +++ b/lib/libc/locale/iscntrl.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)iscntrl.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/iscntrl.3 233992 2012-04-07 09:05:30Z joel $ +.\" +.Dd July 17, 2005 +.Dt ISCNTRL 3 +.Os +.Sh NAME +.Nm iscntrl +.Nd control character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn iscntrl "int c" +.Ft int +.Fn iscntrl_l "int c" "locale_t loc" +.Sh DESCRIPTION +The +.Fn iscntrl +function tests for any control character. +The value of the argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Pp +In the ASCII character set, this includes the following characters +(with their numeric values shown in octal): +.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ +.It "\&000\ NUL" Ta "001\ SOH" Ta "002\ STX" Ta "003\ ETX" Ta "004\ EOT" +.It "\&005\ ENQ" Ta "006\ ACK" Ta "007\ BEL" Ta "010\ BS" Ta "011\ HT" +.It "\&012\ NL" Ta "013\ VT" Ta "014\ NP" Ta "015\ CR" Ta "016\ SO" +.It "\&017\ SI" Ta "020\ DLE" Ta "021\ DC1" Ta "022\ DC2" Ta "023\ DC3" +.It "\&024\ DC4" Ta "025\ NAK" Ta "026\ SYN" Ta "027\ ETB" Ta "030\ CAN" +.It "\&031\ EM" Ta "032\ SUB" Ta "033\ ESC" Ta "034\ FS" Ta "035\ GS" +.It "\&036\ RS" Ta "037\ US" Ta "177\ DEL" Ta \& Ta \& +.El +.Pp +The +.Fn iscntrl_l +function takes an explicit locale argument, whereas the +.Fn iscntrl +function uses the current global or per-thread locale. +.Sh RETURN VALUES +The +.Fn iscntrl +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswcntrl +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswcntrl 3 , +.Xr xlocale 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn iscntrl +function conforms to +.St -isoC . +The +.Fn iscntrl_l +function conforms to +.St -p1003.1-2008 . diff --git a/lib/libc/locale/isdigit.3 b/lib/libc/locale/isdigit.3 new file mode 100644 index 0000000..27c3b6e --- /dev/null +++ b/lib/libc/locale/isdigit.3 @@ -0,0 +1,113 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)isdigit.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/isdigit.3 233992 2012-04-07 09:05:30Z joel $ +.\" +.Dd May 4, 2007 +.Dt ISDIGIT 3 +.Os +.Sh NAME +.Nm isdigit, isnumber +.Nd decimal-digit character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isdigit "int c" +.Ft int +.Fn isnumber "int c" +.Ft int +.Fn isdigit_l "int c" "locale_t loc" +.Ft int +.Fn isnumber_l "int c" "locale_t loc" +.Sh DESCRIPTION +The +.Fn isdigit +function tests for a decimal digit character. +Regardless of locale, this includes the following characters only: +.Bl -column \&``0''______ \&``0''______ \&``0''______ \&``0''______ \&``0''______ +.It "\&``0''" Ta "``1''" Ta "``2''" Ta "``3''" Ta "``4''" +.It "\&``5''" Ta "``6''" Ta "``7''" Ta "``8''" Ta "``9''" +.El +.Pp +The +.Fn isnumber +function behaves similarly to +.Fn isdigit , +but may recognize additional characters, depending on the current locale +setting. +.Pp +The value of the argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Pp +The _l-suffixed versions take an explicit locale argument, whereas the +non-suffixed versions use the current global or per-thread locale. +.Sh RETURN VALUES +The +.Fn isdigit +and +.Fn isnumber +functions return zero if the character tests false and +return non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswdigit +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswdigit 3 , +.Xr multibyte 3 , +.Xr xlocale 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isdigit +function conforms to +.St -isoC . +The +.Fn isdigit_l +function conforms to +.St -p1003.1-2008 . +.Sh HISTORY +The +.Fn isnumber +function appeared in +.Bx 4.4 . diff --git a/lib/libc/locale/isgraph.3 b/lib/libc/locale/isgraph.3 new file mode 100644 index 0000000..a387aec --- /dev/null +++ b/lib/libc/locale/isgraph.3 @@ -0,0 +1,119 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)isgraph.3 8.2 (Berkeley) 12/11/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/isgraph.3 238919 2012-07-30 20:56:19Z issyl0 $ +.\" +.Dd July 30, 2012 +.Dt ISGRAPH 3 +.Os +.Sh NAME +.Nm isgraph +.Nd printing character test (space character exclusive) +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isgraph "int c" +.Ft int +.Fn isgraph_l "int c" "locale_t loc" +.Sh DESCRIPTION +The +.Fn isgraph +function tests for any printing character except space +.Pq Ql "\~" +and other +locale-specific space-like characters. +The value of the argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Pp +In the ASCII character set, this includes the following characters +(with their numeric values shown in octal): +.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ +.It "\&041\ ``!''" Ta "042\ ``""''" Ta "043\ ``#''" Ta "044\ ``$''" Ta "045\ ``%''" +.It "\&046\ ``&''" Ta "047\ ``'''" Ta "050\ ``(''" Ta "051\ ``)''" Ta "052\ ``*''" +.It "\&053\ ``+''" Ta "054\ ``,''" Ta "055\ ``-''" Ta "056\ ``.''" Ta "057\ ``/''" +.It "\&060\ ``0''" Ta "061\ ``1''" Ta "062\ ``2''" Ta "063\ ``3''" Ta "064\ ``4''" +.It "\&065\ ``5''" Ta "066\ ``6''" Ta "067\ ``7''" Ta "070\ ``8''" Ta "071\ ``9''" +.It "\&072\ ``:''" Ta "073\ ``;''" Ta "074\ ``<''" Ta "075\ ``=''" Ta "076\ ``>''" +.It "\&077\ ``?''" Ta "100\ ``@''" Ta "101\ ``A''" Ta "102\ ``B''" Ta "103\ ``C''" +.It "\&104\ ``D''" Ta "105\ ``E''" Ta "106\ ``F''" Ta "107\ ``G''" Ta "110\ ``H''" +.It "\&111\ ``I''" Ta "112\ ``J''" Ta "113\ ``K''" Ta "114\ ``L''" Ta "115\ ``M''" +.It "\&116\ ``N''" Ta "117\ ``O''" Ta "120\ ``P''" Ta "121\ ``Q''" Ta "122\ ``R''" +.It "\&123\ ``S''" Ta "124\ ``T''" Ta "125\ ``U''" Ta "126\ ``V''" Ta "127\ ``W''" +.It "\&130\ ``X''" Ta "131\ ``Y''" Ta "132\ ``Z''" Ta "133\ ``[''" Ta "134\ ``\e\|''" +.It "\&135\ ``]''" Ta "136\ ``^''" Ta "137\ ``_''" Ta "140\ ```''" Ta "141\ ``a''" +.It "\&142\ ``b''" Ta "143\ ``c''" Ta "144\ ``d''" Ta "145\ ``e''" Ta "146\ ``f''" +.It "\&147\ ``g''" Ta "150\ ``h''" Ta "151\ ``i''" Ta "152\ ``j''" Ta "153\ ``k''" +.It "\&154\ ``l''" Ta "155\ ``m''" Ta "156\ ``n''" Ta "157\ ``o''" Ta "160\ ``p''" +.It "\&161\ ``q''" Ta "162\ ``r''" Ta "163\ ``s''" Ta "164\ ``t''" Ta "165\ ``u''" +.It "\&166\ ``v''" Ta "167\ ``w''" Ta "170\ ``x''" Ta "171\ ``y''" Ta "172\ ``z''" +.It "\&173\ ``{''" Ta "174\ ``|''" Ta "175\ ``}''" Ta "176\ ``~''" Ta \& +.El +.Pp +The +.Fn isgraph_l +function takes an explicit locale argument, whereas the +.Fn isgraph +function uses the current global or per-thread locale. +.Sh RETURN VALUES +The +.Fn isgraph +and +.Fn isgraph_l +functions return zero if the character tests false and +return non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswgraph +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswgraph 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isgraph +function conforms to +.St -isoC . +The +.Fn isgraph_l +function conforms to +.St -p1003.1-2008 . diff --git a/lib/libc/locale/isideogram.3 b/lib/libc/locale/isideogram.3 new file mode 100644 index 0000000..811a631 --- /dev/null +++ b/lib/libc/locale/isideogram.3 @@ -0,0 +1,57 @@ +.\" +.\" Copyright (c) 2004 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/isideogram.3 196820 2009-09-04 07:44:58Z des $ +.\" +.Dd March 30, 2004 +.Dt ISIDEOGRAM 3 +.Os +.Sh NAME +.Nm isideogram +.Nd ideographic character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isideogram "int c" +.Sh DESCRIPTION +The +.Fn isideogram +function tests for an ideographic character. +.Sh RETURN VALUES +The +.Fn isideogram +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isphonogram 3 , +.Xr iswideogram 3 +.Sh HISTORY +The +.Fn isideogram +function appeared in +.Bx 4.4 . diff --git a/lib/libc/locale/islower.3 b/lib/libc/locale/islower.3 new file mode 100644 index 0000000..c3a5e24 --- /dev/null +++ b/lib/libc/locale/islower.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)islower.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/islower.3 238920 2012-07-30 21:02:44Z joel $ +.\" +.Dd July 30, 2012 +.Dt ISLOWER 3 +.Os +.Sh NAME +.Nm islower +.Nd lower-case character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn islower "int c" +.Ft int +.Fn islower_l "int c" "locale_t loc" +.Sh DESCRIPTION +The +.Fn islower +function tests for any lower-case letters. +The value of the argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Pp +In the ASCII character set, this includes the following characters +(with their numeric values shown in octal): +.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ +.It "\&141\ ``a''" Ta "142\ ``b''" Ta "143\ ``c''" Ta "144\ ``d''" Ta "145\ ``e''" +.It "\&146\ ``f''" Ta "147\ ``g''" Ta "150\ ``h''" Ta "151\ ``i''" Ta "152\ ``j''" +.It "\&153\ ``k''" Ta "154\ ``l''" Ta "155\ ``m''" Ta "156\ ``n''" Ta "157\ ``o''" +.It "\&160\ ``p''" Ta "161\ ``q''" Ta "162\ ``r''" Ta "163\ ``s''" Ta "164\ ``t''" +.It "\&165\ ``u''" Ta "166\ ``v''" Ta "167\ ``w''" Ta "170\ ``x''" Ta "171\ ``y''" +.It "\&172\ ``z''" Ta \& Ta \& Ta \& Ta \& +.El +The +.Fn islower_l +function takes an explicit locale argument, whereas the +.Fn islower +function uses the current global or per-thread locale. +.Sh RETURN VALUES +The +.Fn islower +and +.Fn islower_l +functions return zero if the character tests false and +return non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswlower +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswlower 3 , +.Xr tolower 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn islower +function conforms to +.St -isoC . +The +.Fn islower_l +function conforms to +.St -p1003.1-2008 . diff --git a/lib/libc/locale/isphonogram.3 b/lib/libc/locale/isphonogram.3 new file mode 100644 index 0000000..85df1d2 --- /dev/null +++ b/lib/libc/locale/isphonogram.3 @@ -0,0 +1,57 @@ +.\" +.\" Copyright (c) 2004 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/isphonogram.3 196820 2009-09-04 07:44:58Z des $ +.\" +.Dd March 30, 2004 +.Dt ISPHONOGRAM 3 +.Os +.Sh NAME +.Nm isphonogram +.Nd phonographic character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isphonogram "int c" +.Sh DESCRIPTION +The +.Fn isphonogram +function tests for a phonographic character. +.Sh RETURN VALUES +The +.Fn isphonogram +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isideogram 3 , +.Xr iswphonogram 3 +.Sh HISTORY +The +.Fn isphonogram +function appeared in +.Bx 4.4 . diff --git a/lib/libc/locale/isprint.3 b/lib/libc/locale/isprint.3 new file mode 100644 index 0000000..0ccb129 --- /dev/null +++ b/lib/libc/locale/isprint.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)isprint.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/isprint.3 233992 2012-04-07 09:05:30Z joel $ +.\" +.Dd July 17, 2005 +.Dt ISPRINT 3 +.Os +.Sh NAME +.Nm isprint +.Nd printing character test (space character inclusive) +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isprint "int c" +.Sh DESCRIPTION +The +.Fn isprint +function tests for any printing character, including space +.Pq Ql "\ " . +The value of the argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Pp +In the ASCII character set, this includes the following characters +(with their numeric values shown in octal): +.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ +.It "\&040\ sp" Ta "041\ ``!''" Ta "042\ ``""''" Ta "043\ ``#''" Ta "044\ ``$''" +.It "\&045\ ``%''" Ta "046\ ``&''" Ta "047\ ``'''" Ta "050\ ``(''" Ta "051\ ``)''" +.It "\&052\ ``*''" Ta "053\ ``+''" Ta "054\ ``,''" Ta "055\ ``-''" Ta "056\ ``.''" +.It "\&057\ ``/''" Ta "060\ ``0''" Ta "061\ ``1''" Ta "062\ ``2''" Ta "063\ ``3''" +.It "\&064\ ``4''" Ta "065\ ``5''" Ta "066\ ``6''" Ta "067\ ``7''" Ta "070\ ``8''" +.It "\&071\ ``9''" Ta "072\ ``:''" Ta "073\ ``;''" Ta "074\ ``<''" Ta "075\ ``=''" +.It "\&076\ ``>''" Ta "077\ ``?''" Ta "100\ ``@''" Ta "101\ ``A''" Ta "102\ ``B''" +.It "\&103\ ``C''" Ta "104\ ``D''" Ta "105\ ``E''" Ta "106\ ``F''" Ta "107\ ``G''" +.It "\&110\ ``H''" Ta "111\ ``I''" Ta "112\ ``J''" Ta "113\ ``K''" Ta "114\ ``L''" +.It "\&115\ ``M''" Ta "116\ ``N''" Ta "117\ ``O''" Ta "120\ ``P''" Ta "121\ ``Q''" +.It "\&122\ ``R''" Ta "123\ ``S''" Ta "124\ ``T''" Ta "125\ ``U''" Ta "126\ ``V''" +.It "\&127\ ``W''" Ta "130\ ``X''" Ta "131\ ``Y''" Ta "132\ ``Z''" Ta "133\ ``[''" +.It "\&134\ ``\e\|''" Ta "135\ ``]''" Ta "136\ ``^''" Ta "137\ ``_''" Ta "140\ ```''" +.It "\&141\ ``a''" Ta "142\ ``b''" Ta "143\ ``c''" Ta "144\ ``d''" Ta "145\ ``e''" +.It "\&146\ ``f''" Ta "147\ ``g''" Ta "150\ ``h''" Ta "151\ ``i''" Ta "152\ ``j''" +.It "\&153\ ``k''" Ta "154\ ``l''" Ta "155\ ``m''" Ta "156\ ``n''" Ta "157\ ``o''" +.It "\&160\ ``p''" Ta "161\ ``q''" Ta "162\ ``r''" Ta "163\ ``s''" Ta "164\ ``t''" +.It "\&165\ ``u''" Ta "166\ ``v''" Ta "167\ ``w''" Ta "170\ ``x''" Ta "171\ ``y''" +.It "\&172\ ``z''" Ta "173\ ``{''" Ta "174\ ``|''" Ta "175\ ``}''" Ta "176\ ``~''" +.El +.Sh RETURN VALUES +The +.Fn isprint +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswprint +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswprint 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isprint +function conforms to +.St -isoC . diff --git a/lib/libc/locale/ispunct.3 b/lib/libc/locale/ispunct.3 new file mode 100644 index 0000000..571c594 --- /dev/null +++ b/lib/libc/locale/ispunct.3 @@ -0,0 +1,109 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)ispunct.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/ispunct.3 238919 2012-07-30 20:56:19Z issyl0 $ +.\" +.Dd July 30, 2012 +.Dt ISPUNCT 3 +.Os +.Sh NAME +.Nm ispunct +.Nd punctuation character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn ispunct "int c" +.Ft int +.Fn ispunct_l "int c" "locale_t loc" +.Sh DESCRIPTION +The +.Fn ispunct +function tests for any printing character except for space +.Pq Ql "\ " +or a +character for which +.Xr isalnum 3 +is true. +The value of the argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Pp +In the ASCII character set, this includes the following characters +(with their numeric values shown in octal): +.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ +.It "\&041\ ``!''" Ta "042\ ``""''" Ta "043\ ``#''" Ta "044\ ``$''" Ta "045\ ``%''" +.It "\&046\ ``&''" Ta "047\ ``'''" Ta "050\ ``(''" Ta "051\ ``)''" Ta "052\ ``*''" +.It "\&053\ ``+''" Ta "054\ ``,''" Ta "055\ ``-''" Ta "056\ ``.''" Ta "057\ ``/''" +.It "\&072\ ``:''" Ta "073\ ``;''" Ta "074\ ``<''" Ta "075\ ``=''" Ta "076\ ``>''" +.It "\&077\ ``?''" Ta "100\ ``@''" Ta "133\ ``[''" Ta "134\ ``\e\|''" Ta "135\ ``]''" +.It "\&136\ ``^''" Ta "137\ ``_''" Ta "140\ ```''" Ta "173\ ``{''" Ta "174\ ``|''" +.It "\&175\ ``}''" Ta "176\ ``~''" Ta \& Ta \& Ta \& +.El +.Pp +The +.Fn ispunct_l +function takes an explicit locale argument, whereas the +.Fn ispunct +function uses the current global or per-thread locale. +.Sh RETURN VALUES +The +.Fn ispunct +and +.Fn ispunct_l +functions return zero if the character tests false and +return non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswpunct +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswpunct 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn ispunct +function conforms to +.St -isoC . +The +.Fn ispunct_l +function conforms to +.St -p1003.1-2008 . diff --git a/lib/libc/locale/isrune.3 b/lib/libc/locale/isrune.3 new file mode 100644 index 0000000..5d00a09 --- /dev/null +++ b/lib/libc/locale/isrune.3 @@ -0,0 +1,63 @@ +.\" +.\" Copyright (c) 2004 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/isrune.3 196820 2009-09-04 07:44:58Z des $ +.\" +.Dd March 30, 2004 +.Dt ISRUNE 3 +.Os +.Sh NAME +.Nm isrune +.Nd valid character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isrune "int c" +.Sh DESCRIPTION +The +.Fn isrune +function tests for any character that is valid in the current +character set. +In the +.Tn ASCII +character set, this is equivalent to +.Fn isascii . +.Sh RETURN VALUES +The +.Fn isrune +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isascii 3 , +.Xr iswrune 3 , +.Xr ascii 7 +.Sh HISTORY +The +.Fn isrune +function appeared in +.Bx 4.4 . diff --git a/lib/libc/locale/isspace.3 b/lib/libc/locale/isspace.3 new file mode 100644 index 0000000..69a5be1 --- /dev/null +++ b/lib/libc/locale/isspace.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)isspace.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/isspace.3 238919 2012-07-30 20:56:19Z issyl0 $ +.\" +.Dd July 30, 2012 +.Dt ISSPACE 3 +.Os +.Sh NAME +.Nm isspace +.Nd white-space character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isspace "int c" +.Ft int +.Fn isspace_l "int c" "locale_t loc" +.Sh DESCRIPTION +The +.Fn isspace +function tests for white-space characters. +For any locale, this includes the following standard characters: +.Bl -column \&`\et''___ \&``\et''___ \&``\et''___ \&``\et''___ \&``\et''___ \&``\et''___ +.It "\&``\et''" Ta "``\en''" Ta "``\ev''" Ta "``\ef''" Ta "``\er''" Ta "`` ''" +.El +.Pp +In the "C" locale, +.Fn isspace +returns non-zero for these characters only. +The value of the argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Pp +The +.Fn isspace_l +function takes an explicit locale argument, whereas the +.Fn isspace +function uses the current global or per-thread locale. +.Sh RETURN VALUES +The +.Fn isspace +and +.Fn isspace_l +functions return zero if the character tests false and +return non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswspace +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswspace 3 , +.Xr multibyte 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isspace +function conforms to +.St -isoC . +The +.Fn isspace_l +function conforms to +.St -p1003.1-2008 . diff --git a/lib/libc/locale/isspecial.3 b/lib/libc/locale/isspecial.3 new file mode 100644 index 0000000..d4436dc --- /dev/null +++ b/lib/libc/locale/isspecial.3 @@ -0,0 +1,56 @@ +.\" +.\" Copyright (c) 2004 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/isspecial.3 196820 2009-09-04 07:44:58Z des $ +.\" +.Dd March 30, 2004 +.Dt ISSPECIAL 3 +.Os +.Sh NAME +.Nm isspecial +.Nd special character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isspecial "int c" +.Sh DESCRIPTION +The +.Fn isspecial +function tests for a special character. +.Sh RETURN VALUES +The +.Fn isspecial +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswspecial 3 +.Sh HISTORY +The +.Fn isspecial +function appeared in +.Bx 4.4 . diff --git a/lib/libc/locale/isupper.3 b/lib/libc/locale/isupper.3 new file mode 100644 index 0000000..d54a93a --- /dev/null +++ b/lib/libc/locale/isupper.3 @@ -0,0 +1,90 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)isupper.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/isupper.3 233992 2012-04-07 09:05:30Z joel $ +.\" +.Dd July 17, 2005 +.Dt ISUPPER 3 +.Os +.Sh NAME +.Nm isupper +.Nd upper-case character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isupper "int c" +.Sh DESCRIPTION +The +.Fn isupper +function tests for any upper-case letter. +The value of the argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Pp +In the ASCII character set, this includes the following characters +(with their numeric values shown in octal): +.Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ +.It "\&101\ ``A''" Ta "102\ ``B''" Ta "103\ ``C''" Ta "104\ ``D''" Ta "105\ ``E''" +.It "\&106\ ``F''" Ta "107\ ``G''" Ta "110\ ``H''" Ta "111\ ``I''" Ta "112\ ``J''" +.It "\&113\ ``K''" Ta "114\ ``L''" Ta "115\ ``M''" Ta "116\ ``N''" Ta "117\ ``O''" +.It "\&120\ ``P''" Ta "121\ ``Q''" Ta "122\ ``R''" Ta "123\ ``S''" Ta "124\ ``T''" +.It "\&125\ ``U''" Ta "126\ ``V''" Ta "127\ ``W''" Ta "130\ ``X''" Ta "131\ ``Y''" +.It "\&132\ ``Z''" Ta \& Ta \& Ta \& Ta \& +.El +.Sh RETURN VALUES +The +.Fn isupper +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswupper +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswupper 3 , +.Xr toupper 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isupper +function conforms to +.St -isoC . diff --git a/lib/libc/locale/iswalnum.3 b/lib/libc/locale/iswalnum.3 new file mode 100644 index 0000000..b8d8343 --- /dev/null +++ b/lib/libc/locale/iswalnum.3 @@ -0,0 +1,158 @@ +.\" $NetBSD: iswalnum.3,v 1.5 2002/07/10 14:46:10 yamt Exp $ +.\" +.\" Copyright (c) 1991 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)isalnum.3 5.2 (Berkeley) 6/29/91 +.\" $FreeBSD: releng/11.1/lib/libc/locale/iswalnum.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd October 3, 2002 +.Dt ISWALNUM 3 +.Os +.Sh NAME +.Nm iswalnum , +.Nm iswalpha , +.Nm iswascii , +.Nm iswblank , +.Nm iswcntrl , +.Nm iswdigit , +.Nm iswgraph , +.Nm iswhexnumber , +.Nm iswideogram , +.Nm iswlower , +.Nm iswnumber , +.Nm iswphonogram , +.Nm iswprint , +.Nm iswpunct , +.Nm iswrune , +.Nm iswspace , +.Nm iswspecial , +.Nm iswupper , +.Nm iswxdigit +.Nd wide character classification utilities +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft int +.Fn iswalnum "wint_t wc" +.Ft int +.Fn iswalpha "wint_t wc" +.Ft int +.Fn iswascii "wint_t wc" +.Ft int +.Fn iswblank "wint_t wc" +.Ft int +.Fn iswcntrl "wint_t wc" +.Ft int +.Fn iswdigit "wint_t wc" +.Ft int +.Fn iswgraph "wint_t wc" +.Ft int +.Fn iswhexnumber "wint_t wc" +.Ft int +.Fn iswideogram "wint_t wc" +.Ft int +.Fn iswlower "wint_t wc" +.Ft int +.Fn iswnumber "wint_t wc" +.Ft int +.Fn iswphonogram "wint_t wc" +.Ft int +.Fn iswprint "wint_t wc" +.Ft int +.Fn iswpunct "wint_t wc" +.Ft int +.Fn iswrune "wint_t wc" +.Ft int +.Fn iswspace "wint_t wc" +.Ft int +.Fn iswspecial "wint_t wc" +.Ft int +.Fn iswupper "wint_t wc" +.Ft int +.Fn iswxdigit "wint_t wc" +.Sh DESCRIPTION +The above functions are character classification utility functions, +for use with wide characters +.Vt ( wchar_t +or +.Vt wint_t ) . +See the description for the similarly-named single byte classification +functions (like +.Xr isalnum 3 ) , +for details. +.Sh RETURN VALUES +The functions return zero if the character tests false and +return non-zero if the character tests true. +.Sh SEE ALSO +.Xr isalnum 3 , +.Xr isalpha 3 , +.Xr isascii 3 , +.Xr isblank 3 , +.Xr iscntrl 3 , +.Xr isdigit 3 , +.Xr isgraph 3 , +.Xr ishexnumber 3 , +.Xr isideogram 3 , +.Xr islower 3 , +.Xr isnumber 3 , +.Xr isphonogram 3 , +.Xr isprint 3 , +.Xr ispunct 3 , +.Xr isrune 3 , +.Xr isspace 3 , +.Xr isspecial 3 , +.Xr isupper 3 , +.Xr isxdigit 3 , +.Xr wctype 3 +.Sh STANDARDS +These functions conform to +.St -p1003.1-2001 , +except +.Fn iswascii , +.Fn iswhexnumber , +.Fn iswideogram , +.Fn iswnumber , +.Fn iswphonogram , +.Fn iswrune +and +.Fn iswspecial , +which are +.Fx +extensions. +.Sh CAVEATS +The result of these functions is undefined unless +the argument is +.Dv WEOF +or a valid +.Vt wchar_t +value for the current locale. diff --git a/lib/libc/locale/iswalnum_l.3 b/lib/libc/locale/iswalnum_l.3 new file mode 100644 index 0000000..980ba3e --- /dev/null +++ b/lib/libc/locale/iswalnum_l.3 @@ -0,0 +1,168 @@ +.\" Copyright (c) 2012 Isabell Long +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/iswalnum_l.3 238808 2012-07-26 14:46:19Z joel $ +.\" +.Dd July 25, 2012 +.Dt ISWALNUM_L 3 +.Os +.Sh NAME +.Nm iswalnum_l , +.Nm iswalpha_l , +.Nm iswcntrl_l , +.Nm iswctype_l , +.Nm iswdigit_l , +.Nm iswgraph_l , +.Nm iswlower_l , +.Nm iswprint_l , +.Nm iswpunct_l , +.Nm iswspace_l , +.Nm iswupper_l , +.Nm iswxdigit_l , +.Nm towlower_l , +.Nm towupper_l , +.Nm wctype_l , +.Nm iswblank_l , +.Nm iswhexnumber_l , +.Nm iswideogram_l , +.Nm iswnumber_l , +.Nm iswphonogram_l , +.Nm iswrune_l , +.Nm iswspecial_l , +.Nm nextwctype_l , +.Nm towctrans_l , +.Nm wctrans_l +.Nd wide character classification utilities +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft int +.Fn iswalnum_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswalpha_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswcntrl_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswctype_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswdigit_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswgraph_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswlower_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswprint_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswpunct_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswspace_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswupper_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswxdigit_l "wint_t wc" "locale_t loc" +.Ft wint_t +.Fn towlower_l "wint_t wc" "locale_t loc" +.Ft wint_t +.Fn towupper_l "wint_t wc" "locale_t loc" +.Ft wctype_t +.Fn wctype_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswblank_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswhexnumber_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswideogram_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswnumber_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswphonogram_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswrune_l "wint_t wc" "locale_t loc" +.Ft int +.Fn iswspecial_l "wint_t wc" "locale_t loc" +.Ft wint_t +.Fn nextwctype_l "wint_t wc" "locale_t loc" +.Ft wint_t +.Fn towctrans_l "wint_t wc" "wctrans_t" "locale_t loc" +.Ft wctrans_t +.Fn wctrans_l "const char *" "locale_t loc" +.Sh DESCRIPTION +The above functions are character classification utility functions, +for use with wide characters +.Vt ( wchar_t +or +.Vt wint_t ) +in the locale +.Fa loc . +They behave in the same way as the versions without the _l suffix, but use +the specified locale rather than the global or per-thread locale. +These functions may be implemented as inline functions in +.In wctype.h +and as functions in the C library. +See the specific manual pages for more information. +.Sh RETURN VALUES +These functions return the same things as their non-locale versions. +If the locale is invalid, their behaviors are undefined. +.Sh SEE ALSO +.Xr iswalnum 3 , +.Xr iswalpha 3 , +.Xr iswblank 3 , +.Xr iswcntrl 3 , +.Xr iswctype 3 , +.Xr iswdigit 3 , +.Xr iswgraph 3 , +.Xr iswhexnumber 3 , +.Xr iswideogram 3 , +.Xr iswlower 3 , +.Xr iswnumber 3 , +.Xr iswphonogram 3 , +.Xr iswprint 3 , +.Xr iswpunct 3 , +.Xr iswrune 3 , +.Xr iswspace 3 , +.Xr iswspecial 3 , +.Xr iswupper 3 , +.Xr iswxdigit 3 , +.Xr nextwctype 3 , +.Xr towctrans 3 , +.Xr towlower 3 , +.Xr towupper 3 , +.Xr wctrans 3 , +.Xr wctype 3 +.Sh STANDARDS +These functions conform to +.St -p1003.1-2008 , +except for +.Fn iswascii_l , +.Fn iswhexnumber_l , +.Fn iswideogram_l , +.Fn iswphonogram_l , +.Fn iswrune_l , +.Fn iswspecial_l +and +.Fn nextwctype_l +which are +.Fx +extensions. diff --git a/lib/libc/locale/isxdigit.3 b/lib/libc/locale/isxdigit.3 new file mode 100644 index 0000000..9a6d034 --- /dev/null +++ b/lib/libc/locale/isxdigit.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)isxdigit.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/isxdigit.3 233992 2012-04-07 09:05:30Z joel $ +.\" +.Dd July 17, 2005 +.Dt ISXDIGIT 3 +.Os +.Sh NAME +.Nm isxdigit, ishexnumber +.Nd hexadecimal-digit character test +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn isxdigit "int c" +.Ft int +.Fn ishexnumber "int c" +.Sh DESCRIPTION +The +.Fn isxdigit +function tests for any hexadecimal-digit character. +Regardless of locale, this includes the following characters only: +.Bl -column \&``0''______ \&``0''______ \&``0''______ \&``0''______ \&``0''______ +.It "\&``0''" Ta "``1''" Ta "``2''" Ta "``3''" Ta "``4''" +.It "\&``5''" Ta "``6''" Ta "``7''" Ta "``8''" Ta "``9''" +.It "\&``A''" Ta "``B''" Ta "``C''" Ta "``D''" Ta "``E''" +.It "\&``F''" Ta "``a''" Ta "``b''" Ta "``c''" Ta "``d''" +.It "\&``e''" Ta "``f''" Ta \& Ta \& Ta \& +.El +.Pp +The +.Fn ishexnumber +function behaves similarly to +.Fn isxdigit , +but may recognize additional characters, +depending on the current locale setting. +.Pp +The value of the argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Sh RETURN VALUES +The +.Fn isxdigit +function returns zero if the character tests false and +returns non-zero if the character tests true. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn iswxdigit +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr iswxdigit 3 , +.Xr ascii 7 +.Sh STANDARDS +The +.Fn isxdigit +function conforms to +.St -isoC . +.Sh HISTORY +The +.Fn ishexnumber +function appeared in +.Bx 4.4 . diff --git a/lib/libc/locale/localeconv.3 b/lib/libc/locale/localeconv.3 new file mode 100644 index 0000000..db5d49f --- /dev/null +++ b/lib/libc/locale/localeconv.3 @@ -0,0 +1,237 @@ +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Donn Seeley at BSDI. +.\" +.\" 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. +.\" 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. +.\" +.\" From @(#)setlocale.3 8.1 (Berkeley) 6/9/93 +.\" From FreeBSD: src/lib/libc/locale/setlocale.3,v 1.28 2003/11/15 02:26:04 tjr Exp +.\" $FreeBSD: releng/11.1/lib/libc/locale/localeconv.3 228199 2011-12-02 11:55:09Z obrien $ +.\" +.Dd November 21, 2003 +.Dt LOCALECONV 3 +.Os +.Sh NAME +.Nm localeconv +.Nd natural language formatting for C +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In locale.h +.Ft struct lconv * +.Fn localeconv "void" +.In xlocale.h +.Ft struct lconv * +.Fn localeconv_l "locale_t locale" +.Sh DESCRIPTION +The +.Fn localeconv +function returns a pointer to a structure +which provides parameters for formatting numbers, +especially currency values: +.Bd -literal -offset indent +struct lconv { + char *decimal_point; + char *thousands_sep; + char *grouping; + char *int_curr_symbol; + char *currency_symbol; + char *mon_decimal_point; + char *mon_thousands_sep; + char *mon_grouping; + char *positive_sign; + char *negative_sign; + char int_frac_digits; + char frac_digits; + char p_cs_precedes; + char p_sep_by_space; + char n_cs_precedes; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +}; +.Ed +.Pp +The individual fields have the following meanings: +.Bl -tag -width mon_decimal_point +.It Va decimal_point +The decimal point character, except for currency values, +cannot be an empty string. +.It Va thousands_sep +The separator between groups of digits +before the decimal point, except for currency values. +.It Va grouping +The sizes of the groups of digits, except for currency values. +This is a pointer to a vector of integers, each of size +.Vt char , +representing group size from low order digit groups +to high order (right to left). +The list may be terminated with 0 or +.Dv CHAR_MAX . +If the list is terminated with 0, +the last group size before the 0 is repeated to account for all the digits. +If the list is terminated with +.Dv CHAR_MAX , +no more grouping is performed. +.It Va int_curr_symbol +The standardized international currency symbol. +.It Va currency_symbol +The local currency symbol. +.It Va mon_decimal_point +The decimal point character for currency values. +.It Va mon_thousands_sep +The separator for digit groups in currency values. +.It Va mon_grouping +Like +.Va grouping +but for currency values. +.It Va positive_sign +The character used to denote nonnegative currency values, +usually the empty string. +.It Va negative_sign +The character used to denote negative currency values, +usually a minus sign. +.It Va int_frac_digits +The number of digits after the decimal point +in an international-style currency value. +.It Va frac_digits +The number of digits after the decimal point +in the local style for currency values. +.It Va p_cs_precedes +1 if the currency symbol precedes the currency value +for nonnegative values, 0 if it follows. +.It Va p_sep_by_space +1 if a space is inserted between the currency symbol +and the currency value for nonnegative values, 0 otherwise. +.It Va n_cs_precedes +Like +.Va p_cs_precedes +but for negative values. +.It Va n_sep_by_space +Like +.Va p_sep_by_space +but for negative values. +.It Va p_sign_posn +The location of the +.Va positive_sign +with respect to a nonnegative quantity and the +.Va currency_symbol , +coded as follows: +.Pp +.Bl -tag -width 3n -compact +.It Li 0 +Parentheses around the entire string. +.It Li 1 +Before the string. +.It Li 2 +After the string. +.It Li 3 +Just before +.Va currency_symbol . +.It Li 4 +Just after +.Va currency_symbol . +.El +.It Va n_sign_posn +Like +.Va p_sign_posn +but for negative currency values. +.It Va int_p_cs_precedes +Same as +.Va p_cs_precedes , +but for internationally formatted monetary quantities. +.It Va int_n_cs_precedes +Same as +.Va n_cs_precedes , +but for internationally formatted monetary quantities. +.It Va int_p_sep_by_space +Same as +.Va p_sep_by_space , +but for internationally formatted monetary quantities. +.It Va int_n_sep_by_space +Same as +.Va n_sep_by_space , +but for internationally formatted monetary quantities. +.It Va int_p_sign_posn +Same as +.Va p_sign_posn , +but for internationally formatted monetary quantities. +.It Va int_n_sign_posn +Same as +.Va n_sign_posn , +but for internationally formatted monetary quantities. +.El +.Pp +Unless mentioned above, +an empty string as a value for a field +indicates a zero length result or +a value that is not in the current locale. +A +.Dv CHAR_MAX +result similarly denotes an unavailable value. +.Pp +The +.Fn localeconv_l +function takes an explicit locale parameter. For more information, see +.Xr xlocale 3 . +.Sh RETURN VALUES +The +.Fn localeconv +function returns a pointer to a static object +which may be altered by later calls to +.Xr setlocale 3 +or +.Fn localeconv . +The return value for +.Fn localeconv_l +is stored with the locale. +It will remain valid until a subsequent call to +.Xr freelocale 3 . +If a thread-local locale is in effect then the return value from +.Fn localeconv +will remain valid until the locale is destroyed. +.Sh ERRORS +No errors are defined. +.Sh SEE ALSO +.Xr setlocale 3 , +.Xr strfmon 3 +.Sh STANDARDS +The +.Fn localeconv +function conforms to +.St -isoC-99 . +.Sh HISTORY +The +.Fn localeconv +function first appeared in +.Bx 4.4 . diff --git a/lib/libc/locale/mblen.3 b/lib/libc/locale/mblen.3 new file mode 100644 index 0000000..76fb3e5 --- /dev/null +++ b/lib/libc/locale/mblen.3 @@ -0,0 +1,106 @@ +.\" Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Donn Seeley of BSDI. +.\" +.\" 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. +.\" 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. +.\" +.\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 +.\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp +.\" $FreeBSD: releng/11.1/lib/libc/locale/mblen.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 11, 2004 +.Dt MBLEN 3 +.Os +.Sh NAME +.Nm mblen +.Nd get number of bytes in a character +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fn mblen "const char *mbchar" "size_t nbytes" +.Sh DESCRIPTION +The +.Fn mblen +function computes the length in bytes +of a multibyte character +.Fa mbchar +according to the current conversion state. +Up to +.Fa nbytes +bytes are examined. +.Pp +A call with a null +.Fa mbchar +pointer returns nonzero if the current locale requires shift states, +zero otherwise; +if shift states are required, the shift state is reset to the initial state. +.Sh RETURN VALUES +If +.Fa mbchar +is +.Dv NULL , +the +.Fn mblen +function returns nonzero if shift states are supported, +zero otherwise. +.Pp +Otherwise, if +.Fa mbchar +is not a null pointer, +.Fn mblen +either returns 0 if +.Fa mbchar +represents the null wide character, or returns +the number of bytes processed in +.Fa mbchar , +or returns \-1 if no multibyte character +could be recognized or converted. +In this case, +.Fn mblen Ns 's +internal conversion state is undefined. +.Sh ERRORS +The +.Fn mblen +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.It Bq Er EINVAL +The internal conversion state is not valid. +.El +.Sh SEE ALSO +.Xr mbrlen 3 , +.Xr mbtowc 3 , +.Xr multibyte 3 +.Sh STANDARDS +The +.Fn mblen +function conforms to +.St -isoC-99 . diff --git a/lib/libc/locale/mbrlen.3 b/lib/libc/locale/mbrlen.3 new file mode 100644 index 0000000..37277f4 --- /dev/null +++ b/lib/libc/locale/mbrlen.3 @@ -0,0 +1,145 @@ +.\" Copyright (c) 2002-2004 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/mbrlen.3 131360 2004-06-30 19:32:41Z ru $ +.\" +.Dd April 7, 2004 +.Dt MBRLEN 3 +.Os +.Sh NAME +.Nm mbrlen +.Nd "get number of bytes in a character (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fn mbrlen "const char * restrict s" "size_t n" "mbstate_t * restrict ps" +.Sh DESCRIPTION +The +.Fn mbrlen +function inspects at most +.Fa n +bytes pointed to by +.Fa s +to determine the number of bytes needed to complete the next +multibyte character. +.Pp +The +.Vt mbstate_t +argument, +.Fa ps , +is used to keep track of the shift state. +If it is +.Dv NULL , +.Fn mbrlen +uses an internal, static +.Vt mbstate_t +object, which is initialized to the initial conversion state +at program startup. +.Pp +It is equivalent to: +.Pp +.Dl "mbrtowc(NULL, s, n, ps);" +.Pp +Except that when +.Fa ps +is a +.Dv NULL +pointer, +.Fn mbrlen +uses its own static, internal +.Vt mbstate_t +object to keep track of the shift state. +.Sh RETURN VALUES +The +.Fn mbrlen +functions returns: +.Bl -tag -width indent +.It 0 +The next +.Fa n +or fewer bytes +represent the null wide character +.Pq Li "L'\e0'" . +.It >0 +The next +.Fa n +or fewer bytes +represent a valid character, +.Fn mbrlen +returns the number of bytes used to complete the multibyte character. +.It Po Vt size_t Pc Ns \-2 +The next +.Fa n +contribute to, but do not complete, a valid multibyte character sequence, +and all +.Fa n +bytes have been processed. +.It Po Vt size_t Pc Ns \-1 +An encoding error has occurred. +The next +.Fa n +or fewer bytes do not contribute to a valid multibyte character. +.El +.Sh EXAMPLES +A function that calculates the number of characters in a multibyte +character string: +.Bd -literal -offset indent +size_t +nchars(const char *s) +{ + size_t charlen, chars; + mbstate_t mbs; + + chars = 0; + memset(&mbs, 0, sizeof(mbs)); + while ((charlen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0 && + charlen != (size_t)-1 && charlen != (size_t)-2) { + s += charlen; + chars++; + } + + return (chars); +} +.Ed +.Sh ERRORS +The +.Fn mbrlen +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mblen 3 , +.Xr mbrtowc 3 , +.Xr multibyte 3 +.Sh STANDARDS +The +.Fn mbrlen +function conforms to +.St -isoC-99 . diff --git a/lib/libc/locale/mbrtoc16.c b/lib/libc/locale/mbrtoc16.c new file mode 100644 index 0000000..52dddf5 --- /dev/null +++ b/lib/libc/locale/mbrtoc16.c @@ -0,0 +1,89 @@ +/*- + * Copyright (c) 2013 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/locale/mbrtoc16.c 250883 2013-05-21 19:59:37Z ed $"); + +#include +#include "xlocale_private.h" + +typedef struct { + char16_t trail_surrogate; + mbstate_t c32_mbstate; +} _Char16State; + +size_t +mbrtoc16_l(char16_t * __restrict pc16, const char * __restrict s, size_t n, + mbstate_t * __restrict ps, locale_t locale) +{ + _Char16State *cs; + char32_t c32; + ssize_t len; + + FIX_LOCALE(locale); + if (ps == NULL) + ps = &locale->mbrtoc16; + cs = (_Char16State *)ps; + + /* + * Call straight into mbrtoc32_l() if we don't need to return a + * character value. According to the spec, if s is a null + * pointer, the value of parameter pc16 is also ignored. + */ + if (pc16 == NULL || s == NULL) { + cs->trail_surrogate = 0; + return (mbrtoc32_l(NULL, s, n, &cs->c32_mbstate, locale)); + } + + /* Return the trail surrogate from the previous invocation. */ + if (cs->trail_surrogate >= 0xdc00 && cs->trail_surrogate <= 0xdfff) { + *pc16 = cs->trail_surrogate; + cs->trail_surrogate = 0; + return ((size_t)-3); + } + + len = mbrtoc32_l(&c32, s, n, &cs->c32_mbstate, locale); + if (len >= 0) { + if (c32 < 0x10000) { + /* Fits in one UTF-16 character. */ + *pc16 = c32; + } else { + /* Split up in a surrogate pair. */ + c32 -= 0x10000; + *pc16 = 0xd800 | (c32 >> 10); + cs->trail_surrogate = 0xdc00 | (c32 & 0x3ff); + } + } + return (len); +} + +size_t +mbrtoc16(char16_t * __restrict pc16, const char * __restrict s, size_t n, + mbstate_t * __restrict ps) +{ + + return (mbrtoc16_l(pc16, s, n, ps, __get_locale())); +} diff --git a/lib/libc/locale/mbrtoc16_iconv.c b/lib/libc/locale/mbrtoc16_iconv.c new file mode 100644 index 0000000..08b3d29 --- /dev/null +++ b/lib/libc/locale/mbrtoc16_iconv.c @@ -0,0 +1,8 @@ +/* $FreeBSD: releng/11.1/lib/libc/locale/mbrtoc16_iconv.c 251314 2013-06-03 17:17:56Z ed $ */ +#define charXX_t char16_t +#define mbrtocXX mbrtoc16 +#define mbrtocXX_l mbrtoc16_l +#define DSTBUF_LEN 2 +#define UTF_XX_INTERNAL "UTF-16-INTERNAL" + +#include "mbrtocXX_iconv.h" diff --git a/lib/libc/locale/mbrtoc32.c b/lib/libc/locale/mbrtoc32.c new file mode 100644 index 0000000..8313790 --- /dev/null +++ b/lib/libc/locale/mbrtoc32.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2013 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/locale/mbrtoc32.c 250883 2013-05-21 19:59:37Z ed $"); + +#include +#include +#include "xlocale_private.h" + +size_t +mbrtoc32_l(char32_t * __restrict pc32, const char * __restrict s, size_t n, + mbstate_t * __restrict ps, locale_t locale) +{ + + FIX_LOCALE(locale); + if (ps == NULL) + ps = &locale->mbrtoc32; + + /* Assume wchar_t uses UTF-32. */ + return (mbrtowc_l(pc32, s, n, ps, locale)); +} + +size_t +mbrtoc32(char32_t * __restrict pc32, const char * __restrict s, size_t n, + mbstate_t * __restrict ps) +{ + + return (mbrtoc32_l(pc32, s, n, ps, __get_locale())); +} diff --git a/lib/libc/locale/mbrtoc32_iconv.c b/lib/libc/locale/mbrtoc32_iconv.c new file mode 100644 index 0000000..ce17b6c --- /dev/null +++ b/lib/libc/locale/mbrtoc32_iconv.c @@ -0,0 +1,8 @@ +/* $FreeBSD: releng/11.1/lib/libc/locale/mbrtoc32_iconv.c 251314 2013-06-03 17:17:56Z ed $ */ +#define charXX_t char32_t +#define mbrtocXX mbrtoc32 +#define mbrtocXX_l mbrtoc32_l +#define DSTBUF_LEN 1 +#define UTF_XX_INTERNAL "UTF-32-INTERNAL" + +#include "mbrtocXX_iconv.h" diff --git a/lib/libc/locale/mbrtocXX_iconv.h b/lib/libc/locale/mbrtocXX_iconv.h new file mode 100644 index 0000000..ceb8113 --- /dev/null +++ b/lib/libc/locale/mbrtocXX_iconv.h @@ -0,0 +1,158 @@ +/*- + * Copyright (c) 2013 Ed Schouten + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/locale/mbrtocXX_iconv.h 281550 2015-04-15 09:09:20Z tijl $"); + +#include + +#include +#include +#include +#include +#include +#include + +#include "../iconv/citrus_hash.h" +#include "../iconv/citrus_module.h" +#include "../iconv/citrus_iconv.h" +#include "xlocale_private.h" + +typedef struct { + bool initialized; + struct _citrus_iconv iconv; + char srcbuf[MB_LEN_MAX]; + size_t srcbuf_len; + union { + charXX_t widechar[DSTBUF_LEN]; + char bytes[sizeof(charXX_t) * DSTBUF_LEN]; + } dstbuf; + size_t dstbuf_len; +} _ConversionState; +_Static_assert(sizeof(_ConversionState) <= sizeof(mbstate_t), + "Size of _ConversionState must not exceed mbstate_t's size."); + +size_t +mbrtocXX_l(charXX_t * __restrict pc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps, locale_t locale) +{ + _ConversionState *cs; + struct _citrus_iconv *handle; + size_t i, retval; + charXX_t retchar; + + FIX_LOCALE(locale); + if (ps == NULL) + ps = &locale->mbrtocXX; + cs = (_ConversionState *)ps; + handle = &cs->iconv; + + /* Reinitialize mbstate_t. */ + if (s == NULL || !cs->initialized) { + if (_citrus_iconv_open(&handle, + nl_langinfo_l(CODESET, locale), UTF_XX_INTERNAL) != 0) { + cs->initialized = false; + errno = EINVAL; + return (-1); + } + handle->cv_shared->ci_discard_ilseq = true; + handle->cv_shared->ci_hooks = NULL; + cs->srcbuf_len = cs->dstbuf_len = 0; + cs->initialized = true; + if (s == NULL) + return (0); + } + + /* See if we still have characters left from the previous invocation. */ + if (cs->dstbuf_len > 0) { + retval = (size_t)-3; + goto return_char; + } + + /* Fill up the read buffer as far as possible. */ + if (n > sizeof(cs->srcbuf) - cs->srcbuf_len) + n = sizeof(cs->srcbuf) - cs->srcbuf_len; + memcpy(cs->srcbuf + cs->srcbuf_len, s, n); + + /* Convert as few characters to the dst buffer as possible. */ + for (i = 0; ; i++) { + char *src, *dst; + size_t srcleft, dstleft, invlen; + int err; + + src = cs->srcbuf; + srcleft = cs->srcbuf_len + n; + dst = cs->dstbuf.bytes; + dstleft = i * sizeof(charXX_t); + assert(srcleft <= sizeof(cs->srcbuf) && + dstleft <= sizeof(cs->dstbuf.bytes)); + err = _citrus_iconv_convert(handle, &src, &srcleft, + &dst, &dstleft, 0, &invlen); + cs->dstbuf_len = (dst - cs->dstbuf.bytes) / sizeof(charXX_t); + + /* Got new character(s). Return the first. */ + if (cs->dstbuf_len > 0) { + assert(src - cs->srcbuf > cs->srcbuf_len); + retval = src - cs->srcbuf - cs->srcbuf_len; + cs->srcbuf_len = 0; + goto return_char; + } + + /* Increase dst buffer size, to obtain the surrogate pair. */ + if (err == E2BIG) + continue; + + /* Illegal sequence. */ + if (invlen > 0) { + cs->srcbuf_len = 0; + errno = EILSEQ; + return ((size_t)-1); + } + + /* Save unprocessed remainder for the next invocation. */ + memmove(cs->srcbuf, src, srcleft); + cs->srcbuf_len = srcleft; + return ((size_t)-2); + } + +return_char: + retchar = cs->dstbuf.widechar[0]; + memmove(&cs->dstbuf.widechar[0], &cs->dstbuf.widechar[1], + --cs->dstbuf_len * sizeof(charXX_t)); + if (pc != NULL) + *pc = retchar; + if (retchar == 0) + return (0); + return (retval); +} + +size_t +mbrtocXX(charXX_t * __restrict pc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps) +{ + + return (mbrtocXX_l(pc, s, n, ps, __get_locale())); +} diff --git a/lib/libc/locale/mbrtowc.3 b/lib/libc/locale/mbrtowc.3 new file mode 100644 index 0000000..1cbf4cb --- /dev/null +++ b/lib/libc/locale/mbrtowc.3 @@ -0,0 +1,179 @@ +.\" Copyright (c) 2002-2004 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/mbrtowc.3 250883 2013-05-21 19:59:37Z ed $ +.\" +.Dd May 21, 2013 +.Dt MBRTOWC 3 +.Os +.Sh NAME +.Nm mbrtowc , +.Nm mbrtoc16 , +.Nm mbrtoc32 +.Nd "convert a character to a wide-character code (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo mbrtowc +.Fa "wchar_t * restrict pc" "const char * restrict s" "size_t n" +.Fa "mbstate_t * restrict ps" +.Fc +.In uchar.h +.Ft size_t +.Fo mbrtoc16 +.Fa "char16_t * restrict pc" "const char * restrict s" "size_t n" +.Fa "mbstate_t * restrict ps" +.Fc +.Ft size_t +.Fo mbrtoc32 +.Fa "char32_t * restrict pc" "const char * restrict s" "size_t n" +.Fa "mbstate_t * restrict ps" +.Fc +.Sh DESCRIPTION +The +.Fn mbrtowc , +.Fn mbrtoc16 +and +.Fn mbrtoc32 +functions inspect at most +.Fa n +bytes pointed to by +.Fa s +to determine the number of bytes needed to complete the next multibyte +character. +If a character can be completed, and +.Fa pc +is not +.Dv NULL , +the wide character which is represented by +.Fa s +is stored in the +.Vt wchar_t , +.Vt char16_t +or +.Vt char32_t +it points to. +.Pp +If +.Fa s +is +.Dv NULL , +these functions behave as if +.Fa pc +was +.Dv NULL , +.Fa s +was an empty string +.Pq Qq +and +.Fa n +was 1. +.Pp +The +.Vt mbstate_t +argument, +.Fa ps , +is used to keep track of the shift state. +If it is +.Dv NULL , +these functions use an internal, static +.Vt mbstate_t +object, which is initialized to the initial conversion state +at program startup. +.Pp +As a single +.Vt char16_t +is not large enough to represent certain multibyte characters, the +.Fn mbrtoc16 +function may need to be invoked multiple times to convert a single +multibyte character sequence. +.Sh RETURN VALUES +The +.Fn mbrtowc , +.Fn mbrtoc16 +and +.Fn mbrtoc32 +functions return: +.Bl -tag -width indent +.It 0 +The next +.Fa n +or fewer bytes +represent the null wide character +.Pq Li "L'\e0'" . +.It >0 +The next +.Fa n +or fewer bytes represent a valid character, these functions +return the number of bytes used to complete the multibyte character. +.It Po Vt size_t Pc Ns \-1 +An encoding error has occurred. +The next +.Fa n +or fewer bytes do not contribute to a valid multibyte character. +.It Po Vt size_t Pc Ns \-2 +The next +.Fa n +contribute to, but do not complete, a valid multibyte character sequence, +and all +.Fa n +bytes have been processed. +.El +.Pp +The +.Fn mbrtoc16 +function also returns: +.Bl -tag -width indent +.It Po Vt size_t Pc Ns \-3 +The next character resulting from a previous call has been stored. +No bytes from the input have been consumed. +.El +.Sh ERRORS +The +.Fn mbrtowc , +.Fn mbrtoc16 +and +.Fn mbrtoc32 +functions will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbtowc 3 , +.Xr multibyte 3 , +.Xr setlocale 3 , +.Xr wcrtomb 3 +.Sh STANDARDS +The +.Fn mbrtowc , +.Fn mbrtoc16 +and +.Fn mbrtoc32 +functions conform to +.St -isoC-2011 . diff --git a/lib/libc/locale/mbsinit.3 b/lib/libc/locale/mbsinit.3 new file mode 100644 index 0000000..9f0cd50 --- /dev/null +++ b/lib/libc/locale/mbsinit.3 @@ -0,0 +1,67 @@ +.\" Copyright (c) 2002-2004 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/mbsinit.3 128032 2004-04-08 09:59:02Z tjr $ +.\" +.Dd April 8, 2004 +.Dt MBSINIT 3 +.Os +.Sh NAME +.Nm mbsinit +.Nd "determine conversion object status" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft int +.Fn mbsinit "const mbstate_t *ps" +.Sh DESCRIPTION +The +.Fn mbsinit +function determines whether the +.Vt mbstate_t +object pointed to by +.Fa ps +describes an initial conversion state. +.Sh RETURN VALUES +The +.Fn mbsinit +function returns non-zero if +.Fa ps +is +.Dv NULL +or describes an initial conversion state, +otherwise it returns zero. +.Sh SEE ALSO +.Xr mbrlen 3 , +.Xr mbrtowc 3 , +.Xr mbsrtowcs 3 , +.Xr multibyte 3 , +.Xr wcrtomb 3 , +.Xr wcsrtombs 3 +.Sh STANDARDS +The +.Fn mbsinit +function conforms to +.St -isoC-99 . diff --git a/lib/libc/locale/mbsrtowcs.3 b/lib/libc/locale/mbsrtowcs.3 new file mode 100644 index 0000000..fed5763 --- /dev/null +++ b/lib/libc/locale/mbsrtowcs.3 @@ -0,0 +1,135 @@ +.\" Copyright (c) 2002-2004 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/mbsrtowcs.3 140081 2005-01-11 20:50:51Z ru $ +.Dd July 21, 2004 +.Dt MBSRTOWCS 3 +.Os +.Sh NAME +.Nm mbsrtowcs , +.Nm mbsnrtowcs +.Nd "convert a character string to a wide-character string (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo mbsrtowcs +.Fa "wchar_t * restrict dst" "const char ** restrict src" "size_t len" +.Fa "mbstate_t * restrict ps" +.Fc +.Ft size_t +.Fo mbsnrtowcs +.Fa "wchar_t * restrict dst" "const char ** restrict src" "size_t nms" +.Fa "size_t len" "mbstate_t * restrict ps" +.Fc +.Sh DESCRIPTION +The +.Fn mbsrtowcs +function converts a sequence of multibyte characters pointed to indirectly by +.Fa src +into a sequence of corresponding wide characters and stores at most +.Fa len +of them in the +.Vt wchar_t +array pointed to by +.Fa dst , +until it encounters a terminating null character +.Pq Li '\e0' . +.Pp +If +.Fa dst +is +.Dv NULL , +no characters are stored. +.Pp +If +.Fa dst +is not +.Dv NULL , +the pointer pointed to by +.Fa src +is updated to point to the character after the one that conversion stopped at. +If conversion stops because a null character is encountered, +.Fa *src +is set to +.Dv NULL . +.Pp +The +.Vt mbstate_t +argument, +.Fa ps , +is used to keep track of the shift state. +If it is +.Dv NULL , +.Fn mbsrtowcs +uses an internal, static +.Vt mbstate_t +object, which is initialized to the initial conversion state +at program startup. +.Pp +The +.Fn mbsnrtowcs +function behaves identically to +.Fn mbsrtowcs , +except that conversion stops after reading at most +.Fa nms +bytes from the buffer pointed to by +.Fa src . +.Sh RETURN VALUES +The +.Fn mbsrtowcs +and +.Fn mbsnrtowcs +functions return the number of wide characters stored in +the array pointed to by +.Fa dst +if successful, otherwise it returns +.Po Vt size_t Pc Ns \-1 . +.Sh ERRORS +The +.Fn mbsrtowcs +and +.Fn mbsnrtowcs +functions will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte character sequence was encountered. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbrtowc 3 , +.Xr mbstowcs 3 , +.Xr multibyte 3 , +.Xr wcsrtombs 3 +.Sh STANDARDS +The +.Fn mbsrtowcs +function conforms to +.St -isoC-99 . +.Pp +The +.Fn mbsnrtowcs +function is an extension to the standard. diff --git a/lib/libc/locale/mbstowcs.3 b/lib/libc/locale/mbstowcs.3 new file mode 100644 index 0000000..3909aa4 --- /dev/null +++ b/lib/libc/locale/mbstowcs.3 @@ -0,0 +1,87 @@ +.\" Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Donn Seeley of BSDI. +.\" +.\" 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. +.\" 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. +.\" +.\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 +.\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp +.\" $FreeBSD: releng/11.1/lib/libc/locale/mbstowcs.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 8, 2004 +.Dt MBSTOWCS 3 +.Os +.Sh NAME +.Nm mbstowcs +.Nd convert a character string to a wide-character string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft size_t +.Fo mbstowcs +.Fa "wchar_t * restrict wcstring" "const char * restrict mbstring" +.Fa "size_t nwchars" +.Fc +.Sh DESCRIPTION +The +.Fn mbstowcs +function converts a multibyte character string +.Fa mbstring +beginning in the initial conversion state +into a wide character string +.Fa wcstring . +No more than +.Fa nwchars +wide characters are stored. +A terminating null wide character is appended if there is room. +.Sh RETURN VALUES +The +.Fn mbstowcs +function returns the number of wide characters converted, +not counting any terminating null wide character, or \-1 +if an invalid multibyte character was encountered. +.Sh ERRORS +The +.Fn mbstowcs +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbsrtowcs 3 , +.Xr mbtowc 3 , +.Xr multibyte 3 +.Sh STANDARDS +The +.Fn mbstowcs +function conforms to +.St -isoC-99 . diff --git a/lib/libc/locale/mbtowc.3 b/lib/libc/locale/mbtowc.3 new file mode 100644 index 0000000..befb5d2 --- /dev/null +++ b/lib/libc/locale/mbtowc.3 @@ -0,0 +1,114 @@ +.\" Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Donn Seeley of BSDI. +.\" +.\" 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. +.\" 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. +.\" +.\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 +.\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp +.\" $FreeBSD: releng/11.1/lib/libc/locale/mbtowc.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 11, 2004 +.Dt MBTOWC 3 +.Os +.Sh NAME +.Nm mbtowc +.Nd convert a character to a wide-character code +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fo mbtowc +.Fa "wchar_t * restrict wcharp" "const char * restrict mbchar" +.Fa "size_t nbytes" +.Fc +.Sh DESCRIPTION +The +.Fn mbtowc +function converts a multibyte character +.Fa mbchar +into a wide character according to the current conversion state, +and stores the result +in the object pointed to by +.Fa wcharp . +Up to +.Fa nbytes +bytes are examined. +.Pp +A call with a null +.Fa mbchar +pointer returns nonzero if the current encoding requires shift states, +zero otherwise; +if shift states are required, the shift state is reset to the initial state. +.Sh RETURN VALUES +If +.Fa mbchar +is +.Dv NULL , +the +.Fn mbtowc +function returns nonzero if shift states are supported, +zero otherwise. +.Pp +Otherwise, if +.Fa mbchar +is not a null pointer, +.Fn mbtowc +either returns 0 if +.Fa mbchar +represents the null wide character, or returns +the number of bytes processed in +.Fa mbchar , +or returns \-1 if no multibyte character +could be recognized or converted. +In this case, +.Fn mbtowc Ns 's +internal conversion state is undefined. +.Sh ERRORS +The +.Fn mbtowc +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.It Bq Er EINVAL +The internal conversion state is invalid. +.El +.Sh SEE ALSO +.Xr btowc 3 , +.Xr mblen 3 , +.Xr mbrtowc 3 , +.Xr mbstowcs 3 , +.Xr multibyte 3 , +.Xr wctomb 3 +.Sh STANDARDS +The +.Fn mbtowc +function conforms to +.St -isoC-99 . diff --git a/lib/libc/locale/mskanji.5 b/lib/libc/locale/mskanji.5 new file mode 100644 index 0000000..1ebd801 --- /dev/null +++ b/lib/libc/locale/mskanji.5 @@ -0,0 +1,70 @@ +.\" Copyright (c) 2002, 2003 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/mskanji.5 131608 2004-07-05 06:39:03Z ru $ +.\" +.Dd August 7, 2003 +.Dt MSKANJI 5 +.Os +.Sh NAME +.Nm mskanji +.Nd "Shift-JIS (MS Kanji) encoding for Japanese text" +.Sh SYNOPSIS +.Nm ENCODING +.Qq MSKanji +.Sh DESCRIPTION +Shift-JIS, also known as MS Kanji or SJIS, is an encoding system for +Japanese characters, developed by Microsoft Corporation. +It encodes the characters from the +.Tn JIS +X 0201 (ASCII/JIS-Roman) and +.Tn JIS +X 0208 (Japanese) character sets as sequences of either one or two bytes. +.Pp +Characters from the +.Tn ASCII Ns +/JIS-Roman character set are encoded as single bytes between 0x00 and 0x7F +(ASCII) or 0xA1 and 0xDF (Half-width katakana). +.Pp +Characters from the +.Tn JIS +X 0208 character set are encoded as two bytes. +The first ranges from +0x81 - 0x9F, 0xE0 - 0xEA, 0xED - 0xEE (not +.Tn JIS : +.Tn NEC Ns - Ns +selected +.Tn IBM +extended characters), +0xF0 - 0xF9 (not +.Tn JIS : +user defined), +or 0xFA - 0xFC (not +.Tn JIS : +.Tn IBM +extended characters). +The second byte ranges from 0x40 - 0xFC, excluding 0x7F (delete). +.Sh SEE ALSO +.Xr euc 5 , +.Xr utf8 5 diff --git a/lib/libc/locale/multibyte.3 b/lib/libc/locale/multibyte.3 new file mode 100644 index 0000000..5b85c02 --- /dev/null +++ b/lib/libc/locale/multibyte.3 @@ -0,0 +1,142 @@ +.\" Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Donn Seeley of BSDI. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)multibyte.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/multibyte.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 8, 2004 +.Dt MULTIBYTE 3 +.Os +.Sh NAME +.Nm multibyte +.Nd multibyte and wide character manipulation functions +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In limits.h +.In stdlib.h +.In wchar.h +.Sh DESCRIPTION +The basic elements of some written natural languages, such as Chinese, +cannot be represented uniquely with single C +.Vt char Ns s . +The C standard supports two different ways of dealing with +extended natural language encodings: +wide characters and +multibyte characters. +Wide characters are an internal representation +which allows each basic element to map +to a single object of type +.Vt wchar_t . +Multibyte characters are used for input and output +and code each basic element as a sequence of C +.Vt char Ns s . +Individual basic elements may map into one or more +(up to +.Dv MB_LEN_MAX ) +bytes in a multibyte character. +.Pp +The current locale +.Pq Xr setlocale 3 +governs the interpretation of wide and multibyte characters. +The locale category +.Dv LC_CTYPE +specifically controls this interpretation. +The +.Vt wchar_t +type is wide enough to hold the largest value +in the wide character representations for all locales. +.Pp +Multibyte strings may contain +.Sq shift +indicators to switch to and from +particular modes within the given representation. +If explicit bytes are used to signal shifting, +these are not recognized as separate characters +but are lumped with a neighboring character. +There is always a distinguished +.Sq initial +shift state. +Some functions (e.g., +.Xr mblen 3 , +.Xr mbtowc 3 +and +.Xr wctomb 3 ) +maintain static shift state internally, whereas +others store it in an +.Vt mbstate_t +object passed by the caller. +Shift states are undefined after a call to +.Xr setlocale 3 +with the +.Dv LC_CTYPE +or +.Dv LC_ALL +categories. +.Pp +For convenience in processing, +the wide character with value 0 +(the null wide character) +is recognized as the wide character string terminator, +and the character with value 0 +(the null byte) +is recognized as the multibyte character string terminator. +Null bytes are not permitted within multibyte characters. +.Pp +The C library provides the following functions for dealing with +multibyte characters: +.Bl -column "Description" +.It Sy "Function Description" +.It Xr mblen 3 Ta "get number of bytes in a character" +.It Xr mbrlen 3 Ta "get number of bytes in a character (restartable)" +.It Xr mbrtowc 3 Ta "convert a character to a wide-character code (restartable)" +.It Xr mbsrtowcs 3 Ta "convert a character string to a wide-character string (restartable)" +.It Xr mbstowcs 3 Ta "convert a character string to a wide-character string" +.It Xr mbtowc 3 Ta "convert a character to a wide-character code" +.It Xr wcrtomb 3 Ta "convert a wide-character code to a character (restartable)" +.It Xr wcstombs 3 Ta "convert a wide-character string to a character string" +.It Xr wcsrtombs 3 Ta "convert a wide-character string to a character string (restartable)" +.It Xr wctomb 3 Ta "convert a wide-character code to a character" +.El +.Sh SEE ALSO +.Xr mklocale 1 , +.Xr setlocale 3 , +.Xr stdio 3 , +.Xr big5 5 , +.Xr euc 5 , +.Xr gb18030 5 , +.Xr gb2312 5 , +.Xr gbk 5 , +.Xr mskanji 5 , +.Xr utf8 5 +.Sh STANDARDS +These functions conform to +.St -isoC-99 . diff --git a/lib/libc/locale/newlocale.3 b/lib/libc/locale/newlocale.3 new file mode 100644 index 0000000..49b3a12 --- /dev/null +++ b/lib/libc/locale/newlocale.3 @@ -0,0 +1,112 @@ +.\" Copyright (c) 2011 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by David Chisnall under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" 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. +.\" +.\" 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/newlocale.3 281925 2015-04-24 10:17:55Z theraven $ +.Dd September 17, 2011 +.Dt NEWLOCALE 3 +.Os +.Sh NAME +.Nm newlocale +.Nd Creates a new locale +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In locale.h +.Ft locale_t +.Fn newlocale "int mask" "const char * locale" "locale_t base" +.Sh DESCRIPTION +Creates a new locale, inheriting some properties from an existing locale. +The +.Fa mask +defines the components that the new locale will have set to the locale with the +name specified in the +.Fa locale +parameter. +Any other components will be inherited from +.Fa base . +The +.Fa mask +is either +.Fa LC_ALL_MASK , +indicating all possible locale components, +or the logical OR of some combination of the following: +.Bl -tag -width "LC_MESSAGES_MASK" -offset indent +.It LC_COLLATE_MASK +The locale for string collation routines. +This controls alphabetic ordering in +.Xr strcoll 3 +and +.Xr strxfrm 3 . +.It LC_CTYPE_MASK +The locale for the +.Xr ctype 3 +and +.Xr multibyte 3 +functions. +This controls recognition of upper and lower case, alphabetic or +non-alphabetic characters, and so on. +.It LC_MESSAGES_MASK +Set a locale for message catalogs, see +.Xr catopen 3 +function. +.It LC_MONETARY_MASK +Set a locale for formatting monetary values; this affects +the +.Xr localeconv 3 +function. +.It LC_NUMERIC_MASK +Set a locale for formatting numbers. +This controls the formatting of decimal points in input and output of floating +point numbers in functions such as +.Xr printf 3 +and +.Xr scanf 3 , +as well as values returned by +.Xr localeconv 3 . +.It LC_TIME_MASK +Set a locale for formatting dates and times using the +.Xr strftime 3 +function. +.El +This function uses the same rules for loading locale components as +.Xr setlocale 3 . +.Sh RETURN VALUES +Returns a new, valid, +.Fa locale_t +or NULL if an error occurs. +You must free the returned locale with +.Xr freelocale 3 . +.Sh SEE ALSO +.Xr duplocale 3 , +.Xr freelocale 3 , +.Xr localeconv 3 , +.Xr querylocale 3 , +.Xr uselocale 3 , +.Xr xlocale 3 +.Sh STANDARDS +This function conforms to +.St -p1003.1-2008 . diff --git a/lib/libc/locale/nextwctype.3 b/lib/libc/locale/nextwctype.3 new file mode 100644 index 0000000..1230a20 --- /dev/null +++ b/lib/libc/locale/nextwctype.3 @@ -0,0 +1,67 @@ +.\" +.\" Copyright (c) 2004 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/nextwctype.3 148232 2005-07-21 10:27:45Z tjr $ +.\" +.Dd July 21, 2005 +.Dt NEXTWCTYPE 3 +.Os +.Sh NAME +.Nm nextwctype +.Nd "iterate through character classes" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft wint_t +.Fn nextwctype "wint_t ch" "wctype_t wct" +.Sh DESCRIPTION +The +.Fn nextwctype +function determines the next character after +.Fa ch +that is a member of character class +.Fa wct . +If +.Fa ch +is \-1, the search begins at the first member of +.Fa wct . +.Sh RETURN VALUES +The +.Fn nextwctype +function returns the next character, or \-1 if there are no more. +.Sh COMPATIBILITY +This function is a non-standard +.Fx +extension and should not be used where the standard +.Fn iswctype +function would suffice. +.Sh SEE ALSO +.Xr wctype 3 +.Sh HISTORY +The +.Fn nextwctype +function appeared in +.Fx 5.4 . diff --git a/lib/libc/locale/nl_langinfo.3 b/lib/libc/locale/nl_langinfo.3 new file mode 100644 index 0000000..cd520dc --- /dev/null +++ b/lib/libc/locale/nl_langinfo.3 @@ -0,0 +1,102 @@ +.\" Copyright (c) 2001 Alexey Zelkin +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/nl_langinfo.3 238919 2012-07-30 20:56:19Z issyl0 $ +.\" +.Dd July 30, 2012 +.Dt NL_LANGINFO 3 +.Os +.Sh NAME +.Nm nl_langinfo +.Nd language information +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In langinfo.h +.Ft char * +.Fn nl_langinfo "nl_item item" +.Ft char * +.Fn nl_langinfo_l "nl_item item" "locale_t loc" +.Sh DESCRIPTION +The +.Fn nl_langinfo +function returns a pointer to a string containing information relevant to +the particular language or cultural area defined in the program or thread's +locale, or in the case of +.Fn nl_langinfo_l , +the locale passed as the second argument. +The manifest constant names and values of +.Fa item +are defined in +.In langinfo.h . +.Pp +Calls to +.Fn setlocale +with a category corresponding to the category of +.Fa item , +or to the +category +.Dv LC_ALL , +may overwrite the buffer pointed to by the return value. +.Sh RETURN VALUES +In a locale where langinfo data is not defined, +.Fn nl_langinfo +returns a pointer to the corresponding string in the +.Tn POSIX +locale. +.Fn nl_langinfo_l +returns the same values as +.Fn nl_langinfo . +In all locales, +.Fn nl_langinfo +returns a pointer to an empty string if +.Fa item +contains an invalid setting. +.Sh EXAMPLES +For example: +.Pp +.Dl nl_langinfo(ABDAY_1) +.Pp +would return a pointer to the string +.Qq Li Dom +if the identified language was +Portuguese, and +.Qq Li Sun +if the identified language was English. +.Sh SEE ALSO +.Xr setlocale 3 +.Sh STANDARDS +The +.Fn nl_langinfo +function conforms to +.St -susv2 . +The +.Fn nl_langinfo_l +function conforms to +.St -p1003.1-2008 . +.Sh HISTORY +The +.Fn nl_langinfo +function first appeared in +.Fx 4.6 . diff --git a/lib/libc/locale/querylocale.3 b/lib/libc/locale/querylocale.3 new file mode 100644 index 0000000..d4d50dc --- /dev/null +++ b/lib/libc/locale/querylocale.3 @@ -0,0 +1,54 @@ +.\" Copyright (c) 2011 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by David Chisnall under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" 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. +.\" +.\" 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/querylocale.3 281925 2015-04-24 10:17:55Z theraven $ +.\" +.Dd May 3, 2013 +.Dt QUERYLOCALE 3 +.Os +.Sh NAME +.Nm querylocale +.Nd Look up the locale name for a specified category +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In locale.h +.Ft const char * +.Fn querylocale "int mask" "locale_t locale" +.Sh DESCRIPTION +Returns the name of the locale for the category specified by +.Fa mask . +This possible values for the mask are the same as those in +.Xr newlocale 3 . +If more than one bit in the mask is set, the returned value is undefined. +.Sh SEE ALSO +.Xr duplocale 3 , +.Xr freelocale 3 , +.Xr localeconv 3 , +.Xr newlocale 3 , +.Xr uselocale 3 , +.Xr xlocale 3 diff --git a/lib/libc/locale/rpmatch.3 b/lib/libc/locale/rpmatch.3 new file mode 100644 index 0000000..7e0fb2b --- /dev/null +++ b/lib/libc/locale/rpmatch.3 @@ -0,0 +1,66 @@ +.\" +.\" Copyright (c) 2005 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/rpmatch.3 148234 2005-07-21 10:53:27Z tjr $ +.\" +.Dd July 21, 2005 +.Dt RPMATCH 3 +.Os +.Sh NAME +.Nm rpmatch +.Nd "determine whether the response to a question is affirmative or negative" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fn rpmatch "const char *response" +.Sh DESCRIPTION +The +.Fn rpmatch +function determines whether the +.Fa response +argument is an affirmative or negative response to a question +according to the current locale. +.Sh RETURN VALUES +The +.Fn rpmatch +functions returns: +.Bl -tag -width indent +.It 1 +The response is affirmative. +.It 0 +The response is negative. +.It \&-1 +The response is not recognized. +.El +.Sh SEE ALSO +.Xr nl_langinfo 3 , +.Xr setlocale 3 +.Sh HISTORY +The +.Fn rpmatch +function appeared in +.Fx 6.0 . diff --git a/lib/libc/locale/setlocale.3 b/lib/libc/locale/setlocale.3 new file mode 100644 index 0000000..1e516d4 --- /dev/null +++ b/lib/libc/locale/setlocale.3 @@ -0,0 +1,173 @@ +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Donn Seeley at BSDI. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)setlocale.3 8.1 (Berkeley) 6/9/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/setlocale.3 213573 2010-10-08 12:40:16Z uqs $ +.\" +.Dd November 21, 2003 +.Dt SETLOCALE 3 +.Os +.Sh NAME +.Nm setlocale +.Nd natural language formatting for C +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In locale.h +.Ft char * +.Fn setlocale "int category" "const char *locale" +.Sh DESCRIPTION +The +.Fn setlocale +function sets the C library's notion +of natural language formatting style +for particular sets of routines. +Each such style is called a +.Sq locale +and is invoked using an appropriate name passed as a C string. +.Pp +The +.Fn setlocale +function recognizes several categories of routines. +These are the categories and the sets of routines they select: +.Bl -tag -width LC_MONETARY +.It Dv LC_ALL +Set the entire locale generically. +.It Dv LC_COLLATE +Set a locale for string collation routines. +This controls alphabetic ordering in +.Fn strcoll +and +.Fn strxfrm . +.It Dv LC_CTYPE +Set a locale for the +.Xr ctype 3 +and +.Xr multibyte 3 +functions. +This controls recognition of upper and lower case, +alphabetic or non-alphabetic characters, +and so on. +.It Dv LC_MESSAGES +Set a locale for message catalogs, see +.Xr catopen 3 +function. +.It Dv LC_MONETARY +Set a locale for formatting monetary values; +this affects the +.Fn localeconv +function. +.It Dv LC_NUMERIC +Set a locale for formatting numbers. +This controls the formatting of decimal points +in input and output of floating point numbers +in functions such as +.Fn printf +and +.Fn scanf , +as well as values returned by +.Fn localeconv . +.It Dv LC_TIME +Set a locale for formatting dates and times using the +.Fn strftime +function. +.El +.Pp +Only three locales are defined by default, +the empty string +.Li \&"\|" +which denotes the native environment, and the +.Li \&"C" +and +.Li \&"POSIX" +locales, which denote the C language environment. +A +.Fa locale +argument of +.Dv NULL +causes +.Fn setlocale +to return the current locale. +By default, C programs start in the +.Li \&"C" +locale. +The only function in the library that sets the locale is +.Fn setlocale ; +the locale is never changed as a side effect of some other routine. +.Sh RETURN VALUES +Upon successful completion, +.Fn setlocale +returns the string associated with the specified +.Fa category +for the requested +.Fa locale . +The +.Fn setlocale +function returns +.Dv NULL +and fails to change the locale +if the given combination of +.Fa category +and +.Fa locale +makes no sense. +.Sh FILES +.Bl -tag -width /usr/share/locale/locale/category -compact +.It Pa $PATH_LOCALE/ Ns Em locale/category +.It Pa /usr/share/locale/ Ns Em locale/category +locale file for the locale +.Em locale +and the category +.Em category . +.El +.Sh ERRORS +No errors are defined. +.Sh SEE ALSO +.Xr colldef 1 , +.Xr mklocale 1 , +.Xr catopen 3 , +.Xr ctype 3 , +.Xr localeconv 3 , +.Xr multibyte 3 , +.Xr strcoll 3 , +.Xr strxfrm 3 , +.Xr euc 5 , +.Xr utf8 5 , +.Xr environ 7 +.Sh STANDARDS +The +.Fn setlocale +function conforms to +.St -isoC-99 . +.Sh HISTORY +The +.Fn setlocale +function first appeared in +.Bx 4.4 . diff --git a/lib/libc/locale/toascii.3 b/lib/libc/locale/toascii.3 new file mode 100644 index 0000000..d38883e --- /dev/null +++ b/lib/libc/locale/toascii.3 @@ -0,0 +1,69 @@ +.\" 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 +.\" 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. +.\" 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. +.\" +.\" @(#)toascii.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/toascii.3 196820 2009-09-04 07:44:58Z des $ +.\" +.Dd June 4, 1993 +.Dt TOASCII 3 +.Os +.Sh NAME +.Nm toascii +.Nd convert a byte to 7-bit ASCII +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn toascii "int c" +.Sh DESCRIPTION +The +.Fn toascii +function strips all but the low 7 bits from a letter, +including parity or other marker bits. +.Sh RETURN VALUES +The +.Fn toascii +function always returns a valid ASCII character. +.Sh SEE ALSO +.Xr digittoint 3 , +.Xr isalnum 3 , +.Xr isalpha 3 , +.Xr isascii 3 , +.Xr iscntrl 3 , +.Xr isdigit 3 , +.Xr isgraph 3 , +.Xr islower 3 , +.Xr isprint 3 , +.Xr ispunct 3 , +.Xr isspace 3 , +.Xr isupper 3 , +.Xr isxdigit 3 , +.Xr stdio 3 , +.Xr tolower 3 , +.Xr toupper 3 , +.Xr ascii 7 diff --git a/lib/libc/locale/tolower.3 b/lib/libc/locale/tolower.3 new file mode 100644 index 0000000..89244c5 --- /dev/null +++ b/lib/libc/locale/tolower.3 @@ -0,0 +1,79 @@ +.\" 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 +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)tolower.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/tolower.3 210468 2010-07-25 13:32:19Z bcr $ +.\" +.Dd July 25, 2010 +.Dt TOLOWER 3 +.Os +.Sh NAME +.Nm tolower +.Nd upper case to lower case letter conversion +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn tolower "int c" +.Sh DESCRIPTION +The +.Fn tolower +function converts an upper-case letter to the corresponding lower-case +letter. +The argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Sh RETURN VALUES +If the argument is an upper-case letter, the +.Fn tolower +function returns the corresponding lower-case letter if there is +one; otherwise, the argument is returned unchanged. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn towlower +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr islower 3 , +.Xr towlower 3 +.Sh STANDARDS +The +.Fn tolower +function conforms to +.St -isoC . diff --git a/lib/libc/locale/toupper.3 b/lib/libc/locale/toupper.3 new file mode 100644 index 0000000..c2f8111 --- /dev/null +++ b/lib/libc/locale/toupper.3 @@ -0,0 +1,79 @@ +.\" 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 +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)toupper.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/toupper.3 210468 2010-07-25 13:32:19Z bcr $ +.\" +.Dd July 25, 2010 +.Dt TOUPPER 3 +.Os +.Sh NAME +.Nm toupper +.Nd lower case to upper case letter conversion +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In ctype.h +.Ft int +.Fn toupper "int c" +.Sh DESCRIPTION +The +.Fn toupper +function converts a lower-case letter to the corresponding +upper-case letter. +The argument must be representable as an +.Vt "unsigned char" +or the value of +.Dv EOF . +.Sh RETURN VALUES +If the argument is a lower-case letter, the +.Fn toupper +function returns the corresponding upper-case letter if there is +one; otherwise, the argument is returned unchanged. +.Sh COMPATIBILITY +The +.Bx 4.4 +extension of accepting arguments outside of the range of the +.Vt "unsigned char" +type in locales with large character sets is considered obsolete +and may not be supported in future releases. +The +.Fn towupper +function should be used instead. +.Sh SEE ALSO +.Xr ctype 3 , +.Xr isupper 3 , +.Xr towupper 3 +.Sh STANDARDS +The +.Fn toupper +function conforms to +.St -isoC . diff --git a/lib/libc/locale/towlower.3 b/lib/libc/locale/towlower.3 new file mode 100644 index 0000000..9751fe6 --- /dev/null +++ b/lib/libc/locale/towlower.3 @@ -0,0 +1,66 @@ +.\" 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 +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)tolower.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/towlower.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd October 3, 2002 +.Dt TOWLOWER 3 +.Os +.Sh NAME +.Nm towlower +.Nd "upper case to lower case letter conversion (wide character version)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft wint_t +.Fn towlower "wint_t wc" +.Sh DESCRIPTION +The +.Fn towlower +function converts an upper-case letter to the corresponding lower-case +letter. +.Sh RETURN VALUES +If the argument is an upper-case letter, the +.Fn towlower +function returns the corresponding lower-case letter if there is +one; otherwise the argument is returned unchanged. +.Sh SEE ALSO +.Xr iswlower 3 , +.Xr tolower 3 , +.Xr towupper 3 , +.Xr wctrans 3 +.Sh STANDARDS +The +.Fn towlower +function conforms to +.St -isoC-99 . diff --git a/lib/libc/locale/towupper.3 b/lib/libc/locale/towupper.3 new file mode 100644 index 0000000..d02d7fa --- /dev/null +++ b/lib/libc/locale/towupper.3 @@ -0,0 +1,66 @@ +.\" 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 +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)toupper.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/towupper.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd October 3, 2002 +.Dt TOWUPPER 3 +.Os +.Sh NAME +.Nm towupper +.Nd "lower case to upper case letter conversion (wide character version)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft wint_t +.Fn towupper "wint_t wc" +.Sh DESCRIPTION +The +.Fn towupper +function converts a lower-case letter to the corresponding +upper-case letter. +.Sh RETURN VALUES +If the argument is a lower-case letter, the +.Fn towupper +function returns the corresponding upper-case letter if there is +one; otherwise the argument is returned unchanged. +.Sh SEE ALSO +.Xr iswupper 3 , +.Xr toupper 3 , +.Xr towlower 3 , +.Xr wctrans 3 +.Sh STANDARDS +The +.Fn towupper +function conforms to +.St -isoC-99 . diff --git a/lib/libc/locale/uselocale.3 b/lib/libc/locale/uselocale.3 new file mode 100644 index 0000000..3317cf4 --- /dev/null +++ b/lib/libc/locale/uselocale.3 @@ -0,0 +1,60 @@ +.\" Copyright (c) 2011 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by David Chisnall under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" 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. +.\" +.\" 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/uselocale.3 281925 2015-04-24 10:17:55Z theraven $ +.\" +.Dd September 17, 2011 +.Dt USELOCALE 3 +.Os +.Sh NAME +.Nm uselocale +.Nd Sets a thread-local locale +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In locale.h +.Ft locale_t +.Fn uselocale "locale_t locale" +.Sh DESCRIPTION +Specifies the locale for this thread to use. +Specifying +.Fa LC_GLOBAL_LOCALE +disables the per-thread locale, +while NULL returns the current locale without setting a new one. +.Sh RETURN VALUES +Returns the previous locale, +or LC_GLOBAL_LOCALE if this thread has no locale associated with it. +.Sh SEE ALSO +.Xr duplocale 3 , +.Xr freelocale 3 , +.Xr localeconv 3 , +.Xr newlocale 3 , +.Xr querylocale 3 , +.Xr xlocale 3 +.Sh STANDARDS +This function conforms to +.St -p1003.1-2008 . diff --git a/lib/libc/locale/utf8.5 b/lib/libc/locale/utf8.5 new file mode 100644 index 0000000..5a51d6d --- /dev/null +++ b/lib/libc/locale/utf8.5 @@ -0,0 +1,102 @@ +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Paul Borman at Krystal Technologies. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)utf2.4 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/locale/utf8.5 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 7, 2004 +.Dt UTF8 5 +.Os +.Sh NAME +.Nm utf8 +.Nd "UTF-8, a transformation format of ISO 10646" +.Sh SYNOPSIS +.Nm ENCODING +.Qq UTF-8 +.Sh DESCRIPTION +The +.Nm UTF-8 +encoding represents UCS-4 characters as a sequence of octets, using +between 1 and 6 for each character. +It is backwards compatible with +.Tn ASCII , +so 0x00-0x7f refer to the +.Tn ASCII +character set. +The multibyte encoding of +.No non- Ns Tn ASCII +characters +consist entirely of bytes whose high order bit is set. +The actual +encoding is represented by the following table: +.Bd -literal +[0x00000000 - 0x0000007f] [00000000.0bbbbbbb] -> 0bbbbbbb +[0x00000080 - 0x000007ff] [00000bbb.bbbbbbbb] -> 110bbbbb, 10bbbbbb +[0x00000800 - 0x0000ffff] [bbbbbbbb.bbbbbbbb] -> + 1110bbbb, 10bbbbbb, 10bbbbbb +[0x00010000 - 0x001fffff] [00000000.000bbbbb.bbbbbbbb.bbbbbbbb] -> + 11110bbb, 10bbbbbb, 10bbbbbb, 10bbbbbb +[0x00200000 - 0x03ffffff] [000000bb.bbbbbbbb.bbbbbbbb.bbbbbbbb] -> + 111110bb, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb +[0x04000000 - 0x7fffffff] [0bbbbbbb.bbbbbbbb.bbbbbbbb.bbbbbbbb] -> + 1111110b, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb, 10bbbbbb +.Ed +.Pp +If more than a single representation of a value exists (for example, +0x00; 0xC0 0x80; 0xE0 0x80 0x80) the shortest representation is always +used. +Longer ones are detected as an error as they pose a potential +security risk, and destroy the 1:1 character:octet sequence mapping. +.Sh SEE ALSO +.Xr euc 5 +.Rs +.%A "Rob Pike" +.%A "Ken Thompson" +.%T "Hello World" +.%J "Proceedings of the Winter 1993 USENIX Technical Conference" +.%Q "USENIX Association" +.%D "January 1993" +.Re +.Rs +.%A "F. Yergeau" +.%T "UTF-8, a transformation format of ISO 10646" +.%O "RFC 2279" +.%D "January 1998" +.Re +.Rs +.%Q "The Unicode Consortium" +.%T "The Unicode Standard, Version 3.0" +.%D "2000" +.%O "as amended by the Unicode Standard Annex #27: Unicode 3.1 and by the Unicode Standard Annex #28: Unicode 3.2" +.Re +.Sh STANDARDS +The +.Nm +encoding is compatible with RFC 2279 and Unicode 3.2. diff --git a/lib/libc/locale/wcrtomb.3 b/lib/libc/locale/wcrtomb.3 new file mode 100644 index 0000000..779189c --- /dev/null +++ b/lib/libc/locale/wcrtomb.3 @@ -0,0 +1,123 @@ +.\" Copyright (c) 2002-2004 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/wcrtomb.3 250883 2013-05-21 19:59:37Z ed $ +.\" +.Dd May 21, 2013 +.Dt WCRTOMB 3 +.Os +.Sh NAME +.Nm wcrtomb , +.Nm c16rtomb , +.Nm c32rtomb +.Nd "convert a wide-character code to a character (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fn wcrtomb "char * restrict s" "wchar_t c" "mbstate_t * restrict ps" +.In uchar.h +.Ft size_t +.Fn c16rtomb "char * restrict s" "char16_t c" "mbstate_t * restrict ps" +.Ft size_t +.Fn c32rtomb "char * restrict s" "char32_t c" "mbstate_t * restrict ps" +.Sh DESCRIPTION +The +.Fn wcrtomb , +.Fn c16rtomb +and +.Fn c32rtomb +functions store a multibyte sequence representing the +wide character +.Fa c , +including any necessary shift sequences, to the +character array +.Fa s , +storing a maximum of +.Dv MB_CUR_MAX +bytes. +.Pp +If +.Fa s +is +.Dv NULL , +these functions behave as if +.Fa s +pointed to an internal buffer and +.Fa c +was a null wide character (L'\e0'). +.Pp +The +.Ft mbstate_t +argument, +.Fa ps , +is used to keep track of the shift state. +If it is +.Dv NULL , +these functions use an internal, static +.Vt mbstate_t +object, which is initialized to the initial conversion state +at program startup. +.Pp +As certain multibyte characters may only be represented by a series of +16-bit characters, the +.Fn c16rtomb +may need to invoked multiple times before a multibyte sequence is +returned. +.Sh RETURN VALUES +These functions return the length (in bytes) of the multibyte sequence +needed to represent +.Fa c , +or +.Po Vt size_t Pc Ns \-1 +if +.Fa c +is not a valid wide character code. +.Sh ERRORS +The +.Fn wcrtomb , +.Fn c16rtomb +and +.Fn c32rtomb +functions will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid wide character code was specified. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbrtowc 3 , +.Xr multibyte 3 , +.Xr setlocale 3 , +.Xr wctomb 3 +.Sh STANDARDS +The +.Fn wcrtomb , +.Fn c16rtomb +and +.Fn c32rtomb +functions conform to +.St -isoC-2011 . diff --git a/lib/libc/locale/wcsftime.3 b/lib/libc/locale/wcsftime.3 new file mode 100644 index 0000000..2bf7156 --- /dev/null +++ b/lib/libc/locale/wcsftime.3 @@ -0,0 +1,66 @@ +.\" Copyright (c) 2002 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/wcsftime.3 107392 2002-11-29 17:35:09Z ru $ +.\" +.Dd September 8, 2002 +.Dt WCSFTIME 3 +.Os +.Sh NAME +.Nm wcsftime +.Nd "convert date and time to a wide-character string" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo wcsftime +.Fa "wchar_t * restrict wcs" "size_t maxsize" +.Fa "const wchar_t * restrict format" "const struct tm * restrict timeptr" +.Fc +.Sh DESCRIPTION +The +.Fn wcsftime +function is equivalent to the +.Fn strftime +function except for the types of its arguments. +Refer to +.Xr strftime 3 +for a detailed description. +.Sh COMPATIBILITY +Some early implementations of +.Fn wcsftime +had a +.Fa format +argument with type +.Vt "const char *" +instead of +.Vt "const wchar_t *" . +.Sh SEE ALSO +.Xr strftime 3 +.Sh STANDARDS +The +.Fn wcsftime +function conforms to +.St -isoC-99 . diff --git a/lib/libc/locale/wcsrtombs.3 b/lib/libc/locale/wcsrtombs.3 new file mode 100644 index 0000000..519fc83 --- /dev/null +++ b/lib/libc/locale/wcsrtombs.3 @@ -0,0 +1,134 @@ +.\" Copyright (c) 2002-2004 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/wcsrtombs.3 132497 2004-07-21 10:54:57Z tjr $ +.\" +.Dd July 21, 2004 +.Dt WCSRTOMBS 3 +.Os +.Sh NAME +.Nm wcsrtombs , +.Nm wcsnrtombs +.Nd "convert a wide-character string to a character string (restartable)" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft size_t +.Fo wcsrtombs +.Fa "char * restrict dst" "const wchar_t ** restrict src" +.Fa "size_t len" "mbstate_t * restrict ps" +.Fc +.Ft size_t +.Fo wcsnrtombs +.Fa "char * restrict dst" "const wchar_t ** restrict src" "size_t nwc" +.Fa "size_t len" "mbstate_t * restrict ps" +.Fc +.Sh DESCRIPTION +The +.Fn wcsrtombs +function converts a string of wide characters indirectly pointed to by +.Fa src +to a corresponding multibyte character string stored in the array +pointed to by +.Fa dst . +No more than +.Fa len +bytes are written to +.Fa dst . +.Pp +If +.Fa dst +is +.Dv NULL , +no characters are stored. +.Pp +If +.Fa dst +is not +.Dv NULL , +the pointer pointed to by +.Fa src +is updated to point to the character after the one that conversion stopped at. +If conversion stops because a null character is encountered, +.Fa *src +is set to +.Dv NULL . +.Pp +The +.Vt mbstate_t +argument, +.Fa ps , +is used to keep track of the shift state. +If it is +.Dv NULL , +.Fn wcsrtombs +uses an internal, static +.Vt mbstate_t +object, which is initialized to the initial conversion state +at program startup. +.Pp +The +.Fn wcsnrtombs +function behaves identically to +.Fn wcsrtombs , +except that conversion stops after reading at most +.Fa nwc +characters from the buffer pointed to by +.Fa src . +.Sh RETURN VALUES +The +.Fn wcsrtombs +and +.Fn wcsnrtombs +functions return the number of bytes stored in +the array pointed to by +.Fa dst +(not including any terminating null), if successful, otherwise it returns +.Po Vt size_t Pc Ns \-1 . +.Sh ERRORS +The +.Fn wcsrtombs +and +.Fn wcsnrtombs +functions will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid wide character was encountered. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbsrtowcs 3 , +.Xr wcrtomb 3 , +.Xr wcstombs 3 +.Sh STANDARDS +The +.Fn wcsrtombs +function conforms to +.St -isoC-99 . +.Pp +The +.Fn wcsnrtombs +function is an extension to the standard. diff --git a/lib/libc/locale/wcstod.3 b/lib/libc/locale/wcstod.3 new file mode 100644 index 0000000..1be2df7 --- /dev/null +++ b/lib/libc/locale/wcstod.3 @@ -0,0 +1,73 @@ +.\" Copyright (c) 2002, 2003 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/wcstod.3 115225 2003-05-22 13:02:28Z ru $ +.\" +.Dd February 22, 2003 +.Dt WCSTOD 3 +.Os +.Sh NAME +.Nm wcstof , +.Nm wcstod , +.Nm wcstold +.Nd convert string to +.Vt float , double +or +.Vt "long double" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft float +.Fn wcstof "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" +.Ft "long double" +.Fn wcstold "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" +.Ft double +.Fn wcstod "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" +.Sh DESCRIPTION +The +.Fn wcstof , +.Fn wcstod +and +.Fn wcstold +functions are the wide-character versions of the +.Fn strtof , +.Fn strtod +and +.Fn strtold +functions. +Refer to +.Xr strtod 3 +for details. +.Sh SEE ALSO +.Xr strtod 3 , +.Xr wcstol 3 +.Sh STANDARDS +The +.Fn wcstof , +.Fn wcstod +and +.Fn wcstold +functions conform to +.St -isoC-99 . diff --git a/lib/libc/locale/wcstol.3 b/lib/libc/locale/wcstol.3 new file mode 100644 index 0000000..c866130 --- /dev/null +++ b/lib/libc/locale/wcstol.3 @@ -0,0 +1,94 @@ +.\" Copyright (c) 2002 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/wcstol.3 107392 2002-11-29 17:35:09Z ru $ +.\" +.Dd September 7, 2002 +.Dt WCSTOL 3 +.Os +.Sh NAME +.Nm wcstol , wcstoul , +.Nm wcstoll , wcstoull , +.Nm wcstoimax , wcstoumax +.Nd "convert a wide character string value to a" +.Vt long , +.Vt "unsigned long" , +.Vt "long long" , +.Vt "unsigned long long" , +.Vt intmax_t +or +.Vt uintmax_t +integer +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft long +.Fn wcstol "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" +.Ft "unsigned long" +.Fn wcstoul "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" +.Ft "long long" +.Fn wcstoll "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" +.Ft "unsigned long long" +.Fn wcstoull "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" +.In inttypes.h +.Ft intmax_t +.Fn wcstoimax "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" +.Ft uintmax_t +.Fn wcstoumax "const wchar_t * restrict nptr" "wchar_t ** restrict endptr" "int base" +.Sh DESCRIPTION +The +.Fn wcstol , +.Fn wcstoul , +.Fn wcstoll , +.Fn wcstoull , +.Fn wcstoimax +and +.Fn wcstoumax +functions are wide-character versions of the +.Fn strtol , +.Fn strtoul , +.Fn strtoll , +.Fn strtoull , +.Fn strtoimax +and +.Fn strtoumax +functions, respectively. +Refer to their manual pages (for example +.Xr strtol 3 ) +for details. +.Sh SEE ALSO +.Xr strtol 3 , +.Xr strtoul 3 +.Sh STANDARDS +The +.Fn wcstol , +.Fn wcstoul , +.Fn wcstoll , +.Fn wcstoull , +.Fn wcstoimax +and +.Fn wcstoumax +functions conform to +.St -isoC-99 . diff --git a/lib/libc/locale/wcstombs.3 b/lib/libc/locale/wcstombs.3 new file mode 100644 index 0000000..b7fa421 --- /dev/null +++ b/lib/libc/locale/wcstombs.3 @@ -0,0 +1,90 @@ +.\" Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Donn Seeley of BSDI. +.\" +.\" 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. +.\" 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. +.\" +.\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 +.\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp +.\" $FreeBSD: releng/11.1/lib/libc/locale/wcstombs.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 8, 2004 +.Dt WCSTOMBS 3 +.Os +.Sh NAME +.Nm wcstombs +.Nd convert a wide-character string to a character string +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft size_t +.Fo wcstombs +.Fa "char * restrict mbstring" "const wchar_t * restrict wcstring" +.Fa "size_t nbytes" +.Fc +.Sh DESCRIPTION +The +.Fn wcstombs +function converts a wide character string +.Fa wcstring +into a multibyte character string, +.Fa mbstring , +beginning in the initial conversion state. +Up to +.Fa nbytes +bytes are stored in +.Fa mbstring . +Partial multibyte characters at the end of the string are not stored. +The multibyte character string is null terminated if there is room. +.Sh RETURN VALUES +The +.Fn wcstombs +function returns the number of bytes converted +(not including any terminating null), if successful, otherwise it returns +.Po Vt size_t Pc Ns \-1 . +.Sh ERRORS +The +.Fn wcstombs +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid wide character was encountered. +.It Bq Er EINVAL +The conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbstowcs 3 , +.Xr multibyte 3 , +.Xr wcsrtombs 3 , +.Xr wctomb 3 +.Sh STANDARDS +The +.Fn wcstombs +function conforms to +.St -isoC-99 . diff --git a/lib/libc/locale/wctomb.3 b/lib/libc/locale/wctomb.3 new file mode 100644 index 0000000..eeedd27 --- /dev/null +++ b/lib/libc/locale/wctomb.3 @@ -0,0 +1,108 @@ +.\" Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Donn Seeley of BSDI. +.\" +.\" 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. +.\" 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. +.\" +.\" From @(#)multibyte.3 8.1 (Berkeley) 6/4/93 +.\" From FreeBSD: src/lib/libc/locale/multibyte.3,v 1.22 2003/11/08 03:23:11 tjr Exp +.\" $FreeBSD: releng/11.1/lib/libc/locale/wctomb.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd April 8, 2004 +.Dt WCTOMB 3 +.Os +.Sh NAME +.Nm wctomb +.Nd convert a wide-character code to a character +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft int +.Fn wctomb "char *mbchar" "wchar_t wchar" +.Sh DESCRIPTION +The +.Fn wctomb +function converts a wide character +.Fa wchar +into a multibyte character and stores +the result in +.Fa mbchar . +The object pointed to by +.Fa mbchar +must be large enough to accommodate the multibyte character, which +may be up to +.Dv MB_LEN_MAX +bytes. +.Pp +A call with a null +.Fa mbchar +pointer returns nonzero if the current locale requires shift states, +zero otherwise; +if shift states are required, the shift state is reset to the initial state. +.Sh RETURN VALUES +If +.Fa mbchar +is +.Dv NULL , +the +.Fn wctomb +function returns nonzero if shift states are supported, +zero otherwise. +If +.Fa mbchar +is valid, +.Fn wctomb +returns +the number of bytes processed in +.Fa mbchar , +or \-1 if no multibyte character +could be recognized or converted. +In this case, +.Fn wctomb Ns 's +internal conversion state is undefined. +.Sh ERRORS +The +.Fn wctomb +function will fail if: +.Bl -tag -width Er +.It Bq Er EILSEQ +An invalid multibyte sequence was detected. +.It Bq Er EINVAL +The internal conversion state is invalid. +.El +.Sh SEE ALSO +.Xr mbtowc 3 , +.Xr wcrtomb 3 , +.Xr wcstombs 3 , +.Xr wctob 3 +.Sh STANDARDS +The +.Fn wctomb +function conforms to +.St -isoC-99 . diff --git a/lib/libc/locale/wctrans.3 b/lib/libc/locale/wctrans.3 new file mode 100644 index 0000000..7e43e2d --- /dev/null +++ b/lib/libc/locale/wctrans.3 @@ -0,0 +1,122 @@ +.\" Copyright (c) 2002 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/wctrans.3 107392 2002-11-29 17:35:09Z ru $ +.\" +.Dd October 3, 2002 +.Dt WCTRANS 3 +.Os +.Sh NAME +.Nm towctrans , wctrans +.Nd "wide character mapping functions" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft wint_t +.Fn towctrans "wint_t wc" "wctrans_t desc" +.Ft wctrans_t +.Fn wctrans "const char *charclass" +.Sh DESCRIPTION +The +.Fn wctrans +function returns a value of type +.Vt wctrans_t +which represents the requested wide character mapping operation and +may be used as the second argument for calls to +.Fn towctrans . +.Pp +The following character mapping names are recognised: +.Bl -column -offset indent ".Li tolower" ".Li toupper" +.It Li "tolower toupper" +.El +.Pp +The +.Fn towctrans +function transliterates the wide character +.Fa wc +according to the mapping described by +.Fa desc . +.Sh RETURN VALUES +The +.Fn towctrans +function returns the transliterated character if successful, otherwise +it returns the character unchanged and sets +.Va errno . +.Pp +The +.Fn wctrans +function returns non-zero if successful, otherwise it returns zero +and sets +.Va errno . +.Sh EXAMPLES +Reimplement +.Fn towupper +in terms of +.Fn towctrans +and +.Fn wctrans : +.Bd -literal -offset indent +wint_t +mytowupper(wint_t wc) +{ + return (towctrans(wc, wctrans("toupper"))); +} +.Ed +.Sh ERRORS +The +.Fn towctrans +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The supplied +.Fa desc +argument is invalid. +.El +.Pp +The +.Fn wctrans +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The requested mapping name is invalid. +.El +.Sh SEE ALSO +.Xr tolower 3 , +.Xr toupper 3 , +.Xr wctype 3 +.Sh STANDARDS +The +.Fn towctrans +and +.Fn wctrans +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Fn towctrans +and +.Fn wctrans +functions first appeared in +.Fx 5.0 . diff --git a/lib/libc/locale/wctype.3 b/lib/libc/locale/wctype.3 new file mode 100644 index 0000000..ce2bacc --- /dev/null +++ b/lib/libc/locale/wctype.3 @@ -0,0 +1,119 @@ +.\" Copyright (c) 2002 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/wctype.3 163314 2006-10-13 16:11:12Z ru $ +.\" +.Dd March 27, 2004 +.Dt WCTYPE 3 +.Os +.Sh NAME +.Nm iswctype , wctype +.Nd "wide character class functions" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wctype.h +.Ft int +.Fn iswctype "wint_t wc" "wctype_t charclass" +.Ft wctype_t +.Fn wctype "const char *property" +.Sh DESCRIPTION +The +.Fn wctype +function returns a value of type +.Vt wctype_t +which represents the requested wide character class and +may be used as the second argument for calls to +.Fn iswctype . +.Pp +The following character class names are recognised: +.Bl -column -offset indent ".Li alnum" ".Li cntrl" ".Li ideogram" ".Li print" ".Li space" +.It Li "alnum cntrl ideogram print space xdigit" +.It Li "alpha digit lower punct special" +.It Li "blank graph phonogram rune upper" +.El +.Pp +The +.Fn iswctype +function checks whether the wide character +.Fa wc +is in the character class +.Fa charclass . +.Sh RETURN VALUES +The +.Fn iswctype +function returns non-zero if and only if +.Fa wc +has the property described by +.Fa charclass , +or +.Fa charclass +is zero. +.Pp +The +.Fn wctype +function returns 0 if +.Fa property +is invalid, otherwise it returns a value of type +.Vt wctype_t +that can be used in subsequent calls to +.Fn iswctype . +.Sh EXAMPLES +Reimplement +.Xr iswalpha 3 +in terms of +.Fn iswctype +and +.Fn wctype : +.Bd -literal -offset indent +int +myiswalpha(wint_t wc) +{ + return (iswctype(wc, wctype("alpha"))); +} +.Ed +.Sh SEE ALSO +.Xr ctype 3 , +.Xr nextwctype 3 +.Sh STANDARDS +The +.Fn iswctype +and +.Fn wctype +functions conform to +.St -p1003.1-2001 . +The +.Dq Li ideogram , +.Dq Li phonogram , +.Dq Li special , +and +.Dq Li rune +character classes are extensions. +.Sh HISTORY +The +.Fn iswctype +and +.Fn wctype +functions first appeared in +.Fx 5.0 . diff --git a/lib/libc/locale/wcwidth.3 b/lib/libc/locale/wcwidth.3 new file mode 100644 index 0000000..4f91307 --- /dev/null +++ b/lib/libc/locale/wcwidth.3 @@ -0,0 +1,87 @@ +.\" Copyright (c) 2002 Tim J. Robbins +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/wcwidth.3 133915 2004-08-17 04:56:03Z trhodes $ +.\" +.Dd August 17, 2004 +.Dt WCWIDTH 3 +.Os +.Sh NAME +.Nm wcwidth +.Nd "number of column positions of a wide-character code" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In wchar.h +.Ft int +.Fn wcwidth "wchar_t wc" +.Sh DESCRIPTION +The +.Fn wcwidth +function determines the number of column positions required to +display the wide character +.Fa wc . +.Sh RETURN VALUES +The +.Fn wcwidth +function returns 0 if the +.Fa wc +argument is a null wide character (L'\e0'), +\-1 if +.Fa wc +is not printable, +otherwise it returns the number of column positions the +character occupies. +.Sh EXAMPLES +This code fragment reads text from standard input and +breaks lines that are more than 20 column positions wide, +similar to the +.Xr fold 1 +utility: +.Bd -literal -offset indent +wint_t ch; +int column, w; + +column = 0; +while ((ch = getwchar()) != WEOF) { + w = wcwidth(ch); + if (w > 0 && column + w >= 20) { + putwchar(L'\en'); + column = 0; + } + putwchar(ch); + if (ch == L'\en') + column = 0; + else if (w > 0) + column += w; +} +.Ed +.Sh SEE ALSO +.Xr iswprint 3 , +.Xr wcswidth 3 +.Sh STANDARDS +The +.Fn wcwidth +function conforms to +.St -p1003.1-2001 . diff --git a/lib/libc/locale/xlocale.3 b/lib/libc/locale/xlocale.3 new file mode 100644 index 0000000..947dcf2 --- /dev/null +++ b/lib/libc/locale/xlocale.3 @@ -0,0 +1,280 @@ +.\" Copyright (c) 2011 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by David Chisnall under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" 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. +.\" +.\" 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/locale/xlocale.3 276294 2014-12-27 08:31:52Z joel $ +.\" +.Dd September 17, 2011 +.Dt XLOCALE 3 +.Os +.Sh NAME +.Nm xlocale +.Nd Thread-safe extended locale support +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In xlocale.h +.Sh DESCRIPTION +The extended locale support includes a set of functions for setting +thread-local locales, +as well convenience functions for performing locale-aware +calls with a specified locale. +.Pp +The core of the xlocale API is the +.Fa locale_t +type. +This is an opaque type encapsulating a locale. +Instances of this can be either set as the locale for a specific thread or +passed directly to the +.Fa _l +suffixed variants of various standard C functions. +Two special +.Fa locale_t +values are available: +.Bl -bullet -offset indent +.It +NULL refers to the current locale for the thread, +or to the global locale if no locale has been set for this thread. +.It +LC_GLOBAL_LOCALE refers to the global locale. +.El +.Pp +The global locale is the locale set with the +.Xr setlocale 3 +function. +.Sh SEE ALSO +.Xr duplocale 3 , +.Xr freelocale 3 , +.Xr localeconv 3 , +.Xr newlocale 3 , +.Xr querylocale 3 , +.Xr uselocale 3 +.Sh CONVENIENCE FUNCTIONS +The xlocale API includes a number of +.Fa _l +suffixed convenience functions. +These are variants of standard C functions +that have been modified to take an explicit +.Fa locale_t +parameter as the final argument or, in the case of variadic functions, +as an additional argument directly before the format string. +Each of these functions accepts either NULL or LC_GLOBAL_LOCALE. +In these functions, NULL refers to the C locale, +rather than the thread's current locale. +If you wish to use the thread's current locale, +then use the unsuffixed version of the function. +.Pp +These functions are exposed by including +.In xlocale.h +.Em after +including the relevant headers for the standard variant. +For example, the +.Xr strtol_l 3 +function is exposed by including +.In xlocale.h +after +.In stdlib.h , +which defines +.Xr strtol 3 . +.Pp +For reference, +a complete list of the locale-aware functions that are available in this form, +along with the headers that expose them, is provided here: +.Bl -tag -width " " +.It In wctype.h +.Xr iswalnum_l 3 , +.Xr iswalpha_l 3 , +.Xr iswcntrl_l 3 , +.Xr iswctype_l 3 , +.Xr iswdigit_l 3 , +.Xr iswgraph_l 3 , +.Xr iswlower_l 3 , +.Xr iswprint_l 3 , +.Xr iswpunct_l 3 , +.Xr iswspace_l 3 , +.Xr iswupper_l 3 , +.Xr iswxdigit_l 3 , +.Xr towlower_l 3 , +.Xr towupper_l 3 , +.Xr wctype_l 3 , +.It In ctype.h +.Xr digittoint_l 3 , +.Xr isalnum_l 3 , +.Xr isalpha_l 3 , +.Xr isblank_l 3 , +.Xr iscntrl_l 3 , +.Xr isdigit_l 3 , +.Xr isgraph_l 3 , +.Xr ishexnumber_l 3 , +.Xr isideogram_l 3 , +.Xr islower_l 3 , +.Xr isnumber_l 3 , +.Xr isphonogram_l 3 , +.Xr isprint_l 3 , +.Xr ispunct_l 3 , +.Xr isrune_l 3 , +.Xr isspace_l 3 , +.Xr isspecial_l 3 , +.Xr isupper_l 3 , +.Xr isxdigit_l 3 , +.Xr tolower_l 3 , +.Xr toupper_l 3 +.It In inttypes.h +.Xr strtoimax_l 3 , +.Xr strtoumax_l 3 , +.Xr wcstoimax_l 3 , +.Xr wcstoumax_l 3 +.It In langinfo.h +.Xr nl_langinfo_l 3 +.It In monetary.h +.Xr strfmon_l 3 +.It In stdio.h +.Xr asprintf_l 3 , +.Xr fprintf_l 3 , +.Xr fscanf_l 3 , +.Xr printf_l 3 , +.Xr scanf_l 3 , +.Xr snprintf_l 3 , +.Xr sprintf_l 3 , +.Xr sscanf_l 3 , +.Xr vasprintf_l 3 , +.Xr vfprintf_l 3 , +.Xr vfscanf_l 3 , +.Xr vprintf_l 3 , +.Xr vscanf_l 3 , +.Xr vsnprintf_l 3 , +.Xr vsprintf_l 3 , +.Xr vsscanf_l 3 +.It In stdlib.h +.Xr atof_l 3 , +.Xr atoi_l 3 , +.Xr atol_l 3 , +.Xr atoll_l 3 , +.Xr mblen_l 3 , +.Xr mbstowcs_l 3 , +.Xr mbtowc_l 3 , +.Xr strtod_l 3 , +.Xr strtof_l 3 , +.Xr strtol_l 3 , +.Xr strtold_l 3 , +.Xr strtoll_l 3 , +.Xr strtoq_l 3 , +.Xr strtoul_l 3 , +.Xr strtoull_l 3 , +.Xr strtouq_l 3 , +.Xr wcstombs_l 3 , +.Xr wctomb_l 3 +.It In string.h +.Xr strcoll_l 3 , +.Xr strxfrm_l 3 , +.Xr strcasecmp_l 3 , +.Xr strcasestr_l 3 , +.Xr strncasecmp_l 3 +.It In time.h +.Xr strftime_l 3 +.Xr strptime_l 3 +.It In wchar.h +.Xr btowc_l 3 , +.Xr fgetwc_l 3 , +.Xr fgetws_l 3 , +.Xr fputwc_l 3 , +.Xr fputws_l 3 , +.Xr fwprintf_l 3 , +.Xr fwscanf_l 3 , +.Xr getwc_l 3 , +.Xr getwchar_l 3 , +.Xr mbrlen_l 3 , +.Xr mbrtowc_l 3 , +.Xr mbsinit_l 3 , +.Xr mbsnrtowcs_l 3 , +.Xr mbsrtowcs_l 3 , +.Xr putwc_l 3 , +.Xr putwchar_l 3 , +.Xr swprintf_l 3 , +.Xr swscanf_l 3 , +.Xr ungetwc_l 3 , +.Xr vfwprintf_l 3 , +.Xr vfwscanf_l 3 , +.Xr vswprintf_l 3 , +.Xr vswscanf_l 3 , +.Xr vwprintf_l 3 , +.Xr vwscanf_l 3 , +.Xr wcrtomb_l 3 , +.Xr wcscoll_l 3 , +.Xr wcsftime_l 3 , +.Xr wcsnrtombs_l 3 , +.Xr wcsrtombs_l 3 , +.Xr wcstod_l 3 , +.Xr wcstof_l 3 , +.Xr wcstol_l 3 , +.Xr wcstold_l 3 , +.Xr wcstoll_l 3 , +.Xr wcstoul_l 3 , +.Xr wcstoull_l 3 , +.Xr wcswidth_l 3 , +.Xr wcsxfrm_l 3 , +.Xr wctob_l 3 , +.Xr wcwidth_l 3 , +.Xr wprintf_l 3 , +.Xr wscanf_l 3 +.It In wctype.h +.Xr iswblank_l 3 , +.Xr iswhexnumber_l 3 , +.Xr iswideogram_l 3 , +.Xr iswnumber_l 3 , +.Xr iswphonogram_l 3 , +.Xr iswrune_l 3 , +.Xr iswspecial_l 3 , +.Xr nextwctype_l 3 , +.Xr towctrans_l 3 , +.Xr wctrans_l 3 +.It In xlocale.h +.Xr localeconv_l 3 +.El +.Sh STANDARDS +The functions +conform to +.St -p1003.1-2008 . +.Sh HISTORY +The xlocale APIs first appeared in Darwin 8.0. +This implementation was written by David Chisnall, +under sponsorship from the FreeBSD Foundation and first appeared in +.Fx 9.1 . +.Sh CAVEATS +The +.Xr setlocale 3 +function, and others in the family, refer to the global locale. +Other functions that depend on the locale, however, +will take the thread-local locale if one has been set. +This means that the idiom of setting the locale using +.Xr setlocale 3 , +calling a locale-dependent function, +and then restoring the locale will not +have the expected behavior if the current thread has had a locale set using +.Xr uselocale 3 . +You should avoid this idiom and prefer to use the +.Fa _l +suffixed versions instead. diff --git a/lib/libc/locale/xlocale.c b/lib/libc/locale/xlocale.c new file mode 100644 index 0000000..40124db --- /dev/null +++ b/lib/libc/locale/xlocale.c @@ -0,0 +1,369 @@ +/*- + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/locale/xlocale.c 264038 2014-04-02 11:10:46Z theraven $ + */ + +#include +#include +#include +#include +#include "libc_private.h" +#include "xlocale_private.h" + +/** + * Each locale loader declares a global component. This is used by setlocale() + * and also by xlocale with LC_GLOBAL_LOCALE.. + */ +extern struct xlocale_component __xlocale_global_collate; +extern struct xlocale_component __xlocale_global_ctype; +extern struct xlocale_component __xlocale_global_monetary; +extern struct xlocale_component __xlocale_global_numeric; +extern struct xlocale_component __xlocale_global_time; +extern struct xlocale_component __xlocale_global_messages; +/* + * And another version for the statically-allocated C locale. We only have + * components for the parts that are expected to be sensible. + */ +extern struct xlocale_component __xlocale_C_collate; +extern struct xlocale_component __xlocale_C_ctype; + +#ifndef __NO_TLS +/* + * The locale for this thread. + */ +_Thread_local locale_t __thread_locale; +#endif +/* + * Flag indicating that one or more per-thread locales exist. + */ +int __has_thread_locale; +/* + * Private functions in setlocale.c. + */ +const char * +__get_locale_env(int category); +int +__detect_path_locale(void); + +struct _xlocale __xlocale_global_locale = { + {0}, + { + &__xlocale_global_collate, + &__xlocale_global_ctype, + &__xlocale_global_monetary, + &__xlocale_global_numeric, + &__xlocale_global_time, + &__xlocale_global_messages + }, + 1, + 0, + 1, + 0 +}; + +struct _xlocale __xlocale_C_locale = { + {0}, + { + &__xlocale_C_collate, + &__xlocale_C_ctype, + 0, 0, 0, 0 + }, + 1, + 0, + 1, + 0 +}; + +static void*(*constructors[])(const char*, locale_t) = +{ + __collate_load, + __ctype_load, + __monetary_load, + __numeric_load, + __time_load, + __messages_load +}; + +static pthread_key_t locale_info_key; +static int fake_tls; +static locale_t thread_local_locale; + +static void init_key(void) +{ + + pthread_key_create(&locale_info_key, xlocale_release); + pthread_setspecific(locale_info_key, (void*)42); + if (pthread_getspecific(locale_info_key) == (void*)42) { + pthread_setspecific(locale_info_key, 0); + } else { + fake_tls = 1; + } + /* At least one per-thread locale has now been set. */ + __has_thread_locale = 1; + __detect_path_locale(); +} + +static pthread_once_t once_control = PTHREAD_ONCE_INIT; + +static locale_t +get_thread_locale(void) +{ + + _once(&once_control, init_key); + + return (fake_tls ? thread_local_locale : + pthread_getspecific(locale_info_key)); +} + +#ifdef __NO_TLS +locale_t +__get_locale(void) +{ + locale_t l = get_thread_locale(); + return (l ? l : &__xlocale_global_locale); + +} +#endif + +static void +set_thread_locale(locale_t loc) +{ + locale_t l = (loc == LC_GLOBAL_LOCALE) ? 0 : loc; + + _once(&once_control, init_key); + + if (NULL != l) { + xlocale_retain((struct xlocale_refcounted*)l); + } + locale_t old = pthread_getspecific(locale_info_key); + if ((NULL != old) && (l != old)) { + xlocale_release((struct xlocale_refcounted*)old); + } + if (fake_tls) { + thread_local_locale = l; + } else { + pthread_setspecific(locale_info_key, l); + } +#ifndef __NO_TLS + __thread_locale = l; + __set_thread_rune_locale(loc); +#endif +} + +/** + * Clean up a locale, once its reference count reaches zero. This function is + * called by xlocale_release(), it should not be called directly. + */ +static void +destruct_locale(void *l) +{ + locale_t loc = l; + + for (int type=0 ; typecomponents[type]) { + xlocale_release(loc->components[type]); + } + } + if (loc->csym) { + free(loc->csym); + } + free(l); +} + +/** + * Allocates a new, uninitialised, locale. + */ +static locale_t +alloc_locale(void) +{ + locale_t new = calloc(sizeof(struct _xlocale), 1); + + new->header.destructor = destruct_locale; + new->monetary_locale_changed = 1; + new->numeric_locale_changed = 1; + return (new); +} +static void +copyflags(locale_t new, locale_t old) +{ + new->using_monetary_locale = old->using_monetary_locale; + new->using_numeric_locale = old->using_numeric_locale; + new->using_time_locale = old->using_time_locale; + new->using_messages_locale = old->using_messages_locale; +} + +static int dupcomponent(int type, locale_t base, locale_t new) +{ + /* Always copy from the global locale, since it has mutable components. + */ + struct xlocale_component *src = base->components[type]; + + if (&__xlocale_global_locale == base) { + new->components[type] = constructors[type](src->locale, new); + if (new->components[type]) { + strncpy(new->components[type]->locale, src->locale, + ENCODING_LEN); + } + } else if (base->components[type]) { + new->components[type] = xlocale_retain(base->components[type]); + } else { + /* If the component was NULL, return success - if base is a + * valid locale then the flag indicating that this isn't + * present should be set. If it isn't a valid locale, then + * we're stuck anyway. */ + return 1; + } + return (0 != new->components[type]); +} + +/* + * Public interfaces. These are the five public functions described by the + * xlocale interface. + */ + +locale_t newlocale(int mask, const char *locale, locale_t base) +{ + int type; + const char *realLocale = locale; + int useenv = 0; + int success = 1; + + _once(&once_control, init_key); + + locale_t new = alloc_locale(); + if (NULL == new) { + return (NULL); + } + + FIX_LOCALE(base); + copyflags(new, base); + + if (NULL == locale) { + realLocale = "C"; + } else if ('\0' == locale[0]) { + useenv = 1; + } + + for (type=0 ; typecomponents[type] = + constructors[type](realLocale, new); + if (new->components[type]) { + strncpy(new->components[type]->locale, + realLocale, ENCODING_LEN); + } else { + success = 0; + break; + } + } else { + if (!dupcomponent(type, base, new)) { + success = 0; + break; + } + } + mask >>= 1; + } + if (0 == success) { + xlocale_release(new); + new = NULL; + } + + return (new); +} + +locale_t duplocale(locale_t base) +{ + locale_t new = alloc_locale(); + int type; + + _once(&once_control, init_key); + + if (NULL == new) { + return (NULL); + } + + FIX_LOCALE(base); + copyflags(new, base); + + for (type=0 ; type= XLC_LAST) + return (NULL); + if (loc->components[type]) + return (loc->components[type]->locale); + return ("C"); +} + +/* + * Installs the specified locale_t as this thread's locale. + */ +locale_t uselocale(locale_t loc) +{ + locale_t old = get_thread_locale(); + if (NULL != loc) { + set_thread_locale(loc); + } + return (old ? old : LC_GLOBAL_LOCALE); +} + diff --git a/lib/libc/locale/xlocale_private.h b/lib/libc/locale/xlocale_private.h new file mode 100644 index 0000000..dba03b5 --- /dev/null +++ b/lib/libc/locale/xlocale_private.h @@ -0,0 +1,231 @@ +/*- + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/locale/xlocale_private.h 297790 2016-04-10 19:33:58Z pfg $ + */ + +#ifndef _XLOCALE_PRIVATE__H_ +#define _XLOCALE_PRIVATE__H_ + +#include +#include +#include +#include +#include +#include +#include "setlocale.h" + +enum { + XLC_COLLATE = 0, + XLC_CTYPE, + XLC_MONETARY, + XLC_NUMERIC, + XLC_TIME, + XLC_MESSAGES, + XLC_LAST +}; + + +/** + * Header used for objects that are reference counted. Objects may optionally + * have a destructor associated, which is responsible for destroying the + * structure. Global / static versions of the structure should have no + * destructor set - they can then have their reference counts manipulated as + * normal, but will not do anything with them. + * + * The header stores a retain count - objects are assumed to have a reference + * count of 1 when they are created, but the retain count is 0. When the + * retain count is less than 0, they are freed. + */ +struct xlocale_refcounted { + /** Number of references to this component. */ + long retain_count; + /** Function used to destroy this component, if one is required*/ + void(*destructor)(void*); +}; +/** + * Header for a locale component. All locale components must begin with this + * header. + */ +struct xlocale_component { + struct xlocale_refcounted header; + /** Name of the locale used for this component. */ + char locale[ENCODING_LEN+1]; +}; + +/** + * xlocale structure, stores per-thread locale information. + */ +struct _xlocale { + struct xlocale_refcounted header; + /** Components for the locale. */ + struct xlocale_component *components[XLC_LAST]; + /** Flag indicating if components[XLC_MONETARY] has changed since the + * last call to localeconv_l() with this locale. */ + int monetary_locale_changed; + /** Flag indicating whether this locale is actually using a locale for + * LC_MONETARY (1), or if it should use the C default instead (0). */ + int using_monetary_locale; + /** Flag indicating if components[XLC_NUMERIC] has changed since the + * last call to localeconv_l() with this locale. */ + int numeric_locale_changed; + /** Flag indicating whether this locale is actually using a locale for + * LC_NUMERIC (1), or if it should use the C default instead (0). */ + int using_numeric_locale; + /** Flag indicating whether this locale is actually using a locale for + * LC_TIME (1), or if it should use the C default instead (0). */ + int using_time_locale; + /** Flag indicating whether this locale is actually using a locale for + * LC_MESSAGES (1), or if it should use the C default instead (0). */ + int using_messages_locale; + /** The structure to be returned from localeconv_l() for this locale. */ + struct lconv lconv; + /** Persistent state used by mblen() calls. */ + __mbstate_t mblen; + /** Persistent state used by mbrlen() calls. */ + __mbstate_t mbrlen; + /** Persistent state used by mbrtoc16() calls. */ + __mbstate_t mbrtoc16; + /** Persistent state used by mbrtoc32() calls. */ + __mbstate_t mbrtoc32; + /** Persistent state used by mbrtowc() calls. */ + __mbstate_t mbrtowc; + /** Persistent state used by mbsnrtowcs() calls. */ + __mbstate_t mbsnrtowcs; + /** Persistent state used by mbsrtowcs() calls. */ + __mbstate_t mbsrtowcs; + /** Persistent state used by mbtowc() calls. */ + __mbstate_t mbtowc; + /** Persistent state used by c16rtomb() calls. */ + __mbstate_t c16rtomb; + /** Persistent state used by c32rtomb() calls. */ + __mbstate_t c32rtomb; + /** Persistent state used by wcrtomb() calls. */ + __mbstate_t wcrtomb; + /** Persistent state used by wcsnrtombs() calls. */ + __mbstate_t wcsnrtombs; + /** Persistent state used by wcsrtombs() calls. */ + __mbstate_t wcsrtombs; + /** Persistent state used by wctomb() calls. */ + __mbstate_t wctomb; + /** Buffer used by nl_langinfo_l() */ + char *csym; +}; + +/** + * Increments the reference count of a reference-counted structure. + */ +__attribute__((unused)) static void* +xlocale_retain(void *val) +{ + struct xlocale_refcounted *obj = val; + atomic_add_long(&(obj->retain_count), 1); + return (val); +} +/** + * Decrements the reference count of a reference-counted structure, freeing it + * if this is the last reference, calling its destructor if it has one. + */ +__attribute__((unused)) static void +xlocale_release(void *val) +{ + struct xlocale_refcounted *obj = val; + long count; + + count = atomic_fetchadd_long(&(obj->retain_count), -1) - 1; + if (count < 0 && obj->destructor != NULL) + obj->destructor(obj); +} + +/** + * Load functions. Each takes the name of a locale and a pointer to the data + * to be initialised as arguments. Two special values are allowed for the + */ +extern void* __collate_load(const char*, locale_t); +extern void* __ctype_load(const char*, locale_t); +extern void* __messages_load(const char*, locale_t); +extern void* __monetary_load(const char*, locale_t); +extern void* __numeric_load(const char*, locale_t); +extern void* __time_load(const char*, locale_t); + +extern struct _xlocale __xlocale_global_locale; +extern struct _xlocale __xlocale_C_locale; + +/** + * Caches the rune table in TLS for fast access. + */ +void __set_thread_rune_locale(locale_t loc); +/** + * Flag indicating whether a per-thread locale has been set. If no per-thread + * locale has ever been set, then we always use the global locale. + */ +extern int __has_thread_locale; +#ifndef __NO_TLS +/** + * The per-thread locale. Avoids the need to use pthread lookup functions when + * getting the per-thread locale. + */ +extern _Thread_local locale_t __thread_locale; + +/** + * Returns the current locale for this thread, or the global locale if none is + * set. The caller does not have to free the locale. The return value from + * this call is not guaranteed to remain valid after the locale changes. As + * such, this should only be called within libc functions. + */ +static inline locale_t __get_locale(void) +{ + + if (!__has_thread_locale) { + return (&__xlocale_global_locale); + } + return (__thread_locale ? __thread_locale : &__xlocale_global_locale); +} +#else +locale_t __get_locale(void); +#endif + +/** + * Two magic values are allowed for locale_t objects. NULL and -1. This + * function maps those to the real locales that they represent. + */ +static inline locale_t get_real_locale(locale_t locale) +{ + switch ((intptr_t)locale) { + case 0: return (&__xlocale_C_locale); + case -1: return (&__xlocale_global_locale); + default: return (locale); + } +} + +/** + * Replace a placeholder locale with the real global or thread-local locale_t. + */ +#define FIX_LOCALE(l) (l = get_real_locale(l)) + +#endif diff --git a/lib/libc/md/Makefile.inc b/lib/libc/md/Makefile.inc new file mode 100644 index 0000000..36f80ad --- /dev/null +++ b/lib/libc/md/Makefile.inc @@ -0,0 +1,5 @@ +# $FreeBSD: releng/11.1/lib/libc/md/Makefile.inc 313240 2017-02-04 17:17:38Z ngie $ + +.PATH: ${SRCTOP}/lib/libmd + +SRCS+= md5c.c diff --git a/lib/libc/mips/Makefile.inc b/lib/libc/mips/Makefile.inc new file mode 100644 index 0000000..17fd53c --- /dev/null +++ b/lib/libc/mips/Makefile.inc @@ -0,0 +1,7 @@ +# $NetBSD: Makefile.inc,v 1.7 2005/09/17 11:49:39 tsutsui Exp $ +# $FreeBSD: releng/11.1/lib/libc/mips/Makefile.inc 315044 2017-03-11 02:51:29Z brooks $ + +CFLAGS+=-DSOFTFLOAT + +SRCS+= machdep_ldisd.c +SYM_MAPS+= ${LIBC_SRCTOP}/mips/Symbol.map diff --git a/lib/libc/mips/SYS.h b/lib/libc/mips/SYS.h new file mode 100644 index 0000000..8c3b1d3 --- /dev/null +++ b/lib/libc/mips/SYS.h @@ -0,0 +1,151 @@ +/* $NetBSD: SYS.h,v 1.19 2009/12/14 01:07:41 matt Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/mips/SYS.h 294515 2016-01-21 17:29:01Z brooks $ */ + +/*- + * Copyright (c) 1996 Jonathan Stone + * 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 Jonathan Stone for + * the NetBSD Project. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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. + * + * from: @(#)SYS.h 8.1 (Berkeley) 6/4/93 + */ + +#include + +#include + +/* + * If compiling for shared libs, Emit sysV ABI PIC segment pseudo-ops. + * + * i) Emit .abicalls before .LEAF entrypoint, and .cpload/.cprestore after. + * ii) Do interprocedure jumps indirectly via t9, with the side-effect of + * preserving the callee's entry address in t9. + */ +#ifdef __ABICALLS__ + .abicalls +# if defined(__mips_o32) || defined(__mips_o64) +# define PIC_PROLOGUE(x) SETUP_GP +# define PIC_TAILCALL(l) PTR_LA t9, _C_LABEL(l); jr t9 +# define PIC_RETURN() j ra +# else +# define PIC_PROLOGUE(x) SETUP_GP64(t3, x) +# define PIC_TAILCALL(l) PTR_LA t9, _C_LABEL(l); RESTORE_GP64; jr t9 +# define PIC_RETURN() RESTORE_GP64; j ra +# endif +#else +# define PIC_PROLOGUE(x) +# define PIC_TAILCALL(l) j _C_LABEL(l) +# define PIC_RETURN() j ra +#endif /* __ABICALLS__ */ + +# define SYSTRAP(x) li v0,SYS_ ## x; syscall; + +/* + * Do a syscall that cannot fail (sync, get{p,u,g,eu,eg)id) + */ +#define RSYSCALL_NOERROR(x) \ +LEAF(__sys_ ## x); \ + .weak _C_LABEL(x); \ + _C_LABEL(x) = _C_LABEL(__CONCAT(__sys_,x)); \ + .weak _C_LABEL(__CONCAT(_,x)); \ + _C_LABEL(__CONCAT(_,x)) = _C_LABEL(__CONCAT(__sys_,x)); \ + SYSTRAP(x); \ + j ra; \ +END(__sys_ ## x) + +/* + * Do a normal syscall. + */ +#define RSYSCALL(x) \ +LEAF(__sys_ ## x); \ + .weak _C_LABEL(x); \ + _C_LABEL(x) = _C_LABEL(__CONCAT(__sys_,x)); \ + .weak _C_LABEL(__CONCAT(_,x)); \ + _C_LABEL(__CONCAT(_,x)) = _C_LABEL(__CONCAT(__sys_,x)); \ + PIC_PROLOGUE(__sys_ ## x); \ + SYSTRAP(x); \ + bne a3,zero,err; \ + PIC_RETURN(); \ +err: \ + PIC_TAILCALL(__cerror); \ +END(__sys_ ## x) + +/* + * Do a renamed or pseudo syscall (e.g., _exit()), where the entrypoint + * and syscall name are not the same. + */ +#define PSEUDO_NOERROR(x) \ +LEAF(__sys_ ## x); \ + .weak _C_LABEL(__CONCAT(_,x)); \ + _C_LABEL(__CONCAT(_,x)) = _C_LABEL(__CONCAT(__sys_,x)); \ + SYSTRAP(x); \ + j ra; \ +END(__sys_ ## x) + +#define PSEUDO(x) \ +LEAF(__sys_ ## x); \ + .weak _C_LABEL(__CONCAT(_,x)); \ + _C_LABEL(__CONCAT(_,x)) = _C_LABEL(__CONCAT(__sys_,x)); \ + PIC_PROLOGUE(__sys_ ## x); \ + SYSTRAP(x); \ + bne a3,zero,err; \ + PIC_RETURN(); \ +err: \ + PIC_TAILCALL(__cerror); \ +END(__sys_ ## x) diff --git a/lib/libc/mips/Symbol.map b/lib/libc/mips/Symbol.map new file mode 100644 index 0000000..46dda47 --- /dev/null +++ b/lib/libc/mips/Symbol.map @@ -0,0 +1,74 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/mips/Symbol.map 297418 2016-03-30 14:42:09Z emaste $ + */ + +/* + * This only needs to contain symbols that are not listed in + * symbol maps from other parts of libc (i.e., not found in + * stdlib/Symbol.map, string/Symbol.map, sys/Symbol.map, ...). + */ +FBSD_1.0 { + /* PSEUDO syscalls */ + _exit; + + _setjmp; + _longjmp; + alloca; + fabs; + __infinity; + __nan; + makecontext; + setjmp; + longjmp; + sigsetjmp; + siglongjmp; + htonl; + htons; + ntohl; + ntohs; + vfork; + brk; + sbrk; +}; + +FBSDprivate_1.0 { + /* PSEUDO syscalls */ + __sys_getlogin; + _getlogin; + __sys_exit; + + _set_tp; + ___longjmp; + __umodsi3; + __modsi3; + __udivsi3; + __divsi3; + __makecontext; + __longjmp; + signalcontext; + _signalcontext; + __siglongjmp; + __sys_vfork; + _vfork; + _end; + _brk; + _sbrk; + + /* softfloat */ + __addsf3; + __adddf3; + __subsf3; + __subdf3; + __mulsf3; + __muldf3; + __divsf3; + __divdf3; + __floatsisf; + __floatsidf; + __fixsfsi; + __fixdfsi; + __fixunssfsi; + __fixunsdfsi; + __extendsfdf2; + __truncdfsf2; +}; diff --git a/lib/libc/mips/_fpmath.h b/lib/libc/mips/_fpmath.h new file mode 100644 index 0000000..54ec6e9 --- /dev/null +++ b/lib/libc/mips/_fpmath.h @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/mips/_fpmath.h 178580 2008-04-26 12:08:02Z imp $ + */ + +union IEEEl2bits { + long double e; + struct { +#ifndef __MIPSEB__ + unsigned int manl :32; + unsigned int manh :20; + unsigned int exp :11; + unsigned int sign :1; +#else + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; +#endif + } bits; +}; + +#define LDBL_NBIT 0 +#define mask_nbit_l(u) ((void)0) +#define LDBL_IMPLICIT_NBIT + +#define LDBL_MANH_SIZE 20 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/lib/libc/mips/arith.h b/lib/libc/mips/arith.h new file mode 100644 index 0000000..6dd36cf --- /dev/null +++ b/lib/libc/mips/arith.h @@ -0,0 +1,26 @@ +/* + * MD header for contrib/gdtoa + * + * $FreeBSD: releng/11.1/lib/libc/mips/arith.h 268351 2014-07-07 00:27:09Z marcel $ + */ + +/* + * NOTE: The definitions in this file must be correct or strtod(3) and + * floating point formats in printf(3) will break! The file can be + * generated by running contrib/gdtoa/arithchk.c on the target + * architecture. See contrib/gdtoa/gdtoaimp.h for details. + */ +#include + +#if BYTE_ORDER == BIG_ENDIAN +#define IEEE_MC68k +#define Arith_Kind_ASL 2 +#define Double_Align +#else +/* TODO: Generate these values on a LE machine */ +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#define Long int +#define Intcast (int)(long) +#define Double_Align +#endif diff --git a/lib/libc/mips/gd_qnan.h b/lib/libc/mips/gd_qnan.h new file mode 100644 index 0000000..86e65ee --- /dev/null +++ b/lib/libc/mips/gd_qnan.h @@ -0,0 +1,48 @@ +/* + * MD header for contrib/gdtoa + * + * This file can be generated by compiling and running contrib/gdtoa/qnan.c + * on the target architecture after arith.h has been generated. + * + * $FreeBSD: releng/11.1/lib/libc/mips/gd_qnan.h 178580 2008-04-26 12:08:02Z imp $ + */ + + +#include + +#if BYTE_ORDER == BIG_ENDIAN +/* These values were gained on a running + * Octeon in Big Endian order. They were gotten + * by running ./qnan after arithchk was ran and + * got us the proper values for arith.h. + */ +#define f_QNAN 0x7f900000 +#define d_QNAN0 0x7ff80000 +#define d_QNAN1 0x0 +#define ld_QNAN0 0x7ff80000 +#define ld_QNAN1 0x0 +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x7ff8 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0x0 +#define ldus_QNAN4 0x0 +#else +/* FIX FIX, need to run this on a Little Endian + * machine and get the proper values, these here + * were stolen fromn i386/gd_qnan.h + */ +#define f_QNAN 0x7fc00000 +#define d_QNAN0 0x0 +#define d_QNAN1 0x7ff80000 +#define ld_QNAN0 0x0 +#define ld_QNAN1 0xc0000000 +#define ld_QNAN2 0x7fff +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x0 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0xc000 +#define ldus_QNAN4 0x7fff +#endif diff --git a/lib/libc/mips/gen/Makefile.inc b/lib/libc/mips/gen/Makefile.inc new file mode 100644 index 0000000..cbd7cee --- /dev/null +++ b/lib/libc/mips/gen/Makefile.inc @@ -0,0 +1,11 @@ +# $NetBSD: Makefile.inc,v 1.27 2005/10/07 17:16:40 tsutsui Exp $ +# $FreeBSD: releng/11.1/lib/libc/mips/gen/Makefile.inc 277078 2015-01-12 18:13:38Z emaste $ + +SRCS+= infinity.c fabs.c ldexp.c + +# SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ +# fpsetround.c fpsetsticky.c + +SRCS+= _ctx_start.S _set_tp.c _setjmp.S makecontext.c \ + setjmp.S signalcontext.c sigsetjmp.S \ + trivial-getcontextx.c diff --git a/lib/libc/mips/gen/_ctx_start.S b/lib/libc/mips/gen/_ctx_start.S new file mode 100644 index 0000000..bc9987e --- /dev/null +++ b/lib/libc/mips/gen/_ctx_start.S @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2010 Juli Mallett. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/_ctx_start.S 209233 2010-06-16 14:13:36Z jchandra $"); + +/* + * XXX gp? + */ +ENTRY(_ctx_start) + jalr t9 + + move a0, s0 + PTR_LA t9, _ctx_done + jalr t9 + + break 0 +END(_ctx_start) diff --git a/lib/libc/mips/gen/_set_tp.c b/lib/libc/mips/gen/_set_tp.c new file mode 100644 index 0000000..1b7e2e5 --- /dev/null +++ b/lib/libc/mips/gen/_set_tp.c @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/mips/gen/_set_tp.c 288019 2015-09-20 04:59:01Z rodrigc $ + */ + +#include +#include + +#include +#include "libc_private.h" + +void +_set_tp(void *tp) +{ + + sysarch(MIPS_SET_TLS, tp); +} diff --git a/lib/libc/mips/gen/_setjmp.S b/lib/libc/mips/gen/_setjmp.S new file mode 100644 index 0000000..dee366d --- /dev/null +++ b/lib/libc/mips/gen/_setjmp.S @@ -0,0 +1,201 @@ +/* $NetBSD: _setjmp.S,v 1.20.34.5 2010/02/03 23:46:47 matt Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/_setjmp.S 274816 2014-11-21 20:02:06Z brooks $"); +#include + +#include "SYS.h" + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 + RCSID("from: @(#)_setjmp.s 8.1 (Berkeley) 6/4/93") +#else + RCSID("$NetBSD: _setjmp.S,v 1.20.34.5 2010/02/03 23:46:47 matt Exp $") +#endif +#endif /* LIBC_SCCS and not lint */ + +/* + * C library -- _setjmp, _longjmp + * + * _longjmp(a,v) + * will generate a "return(v)" from + * the last call to + * _setjmp(a) + * by restoring registers from the stack, + * The previous signal state is NOT restored. + */ + + .set noreorder + +LEAF(_setjmp) + REG_PROLOGUE + REG_LI v0, _JB_MAGIC__SETJMP # sigcontext magic number + REG_S v0, (_JB_MAGIC * SZREG)(a0) + REG_S ra, (_JB_REG_RA * SZREG)(a0) + /* + * From "MIPSpro N32 ABI Handbook", Table 2-1: + * Registers s0..s7 are callee-saved. + * The sp register is callee-saved. + * The fp (or s8) register is callee-saved. + * The gp register is callee-saved (for n32/n64). + */ + REG_S s0, (_JB_REG_S0 * SZREG)(a0) + REG_S s1, (_JB_REG_S1 * SZREG)(a0) + REG_S s2, (_JB_REG_S2 * SZREG)(a0) + REG_S s3, (_JB_REG_S3 * SZREG)(a0) + REG_S s4, (_JB_REG_S4 * SZREG)(a0) + REG_S s5, (_JB_REG_S5 * SZREG)(a0) + REG_S s6, (_JB_REG_S6 * SZREG)(a0) + REG_S s7, (_JB_REG_S7 * SZREG)(a0) + REG_S sp, (_JB_REG_SP * SZREG)(a0) + REG_S s8, (_JB_REG_S8 * SZREG)(a0) +#if defined(__mips_n32) || defined(__mips_n64) + REG_S gp, (_JB_REG_GP * SZREG)(a0) # newabi gp is callee-saved +#endif + /* + * From "MIPSpro N32 ABI Handbook", Table 2-1: + * In N32, FP registers F20, F22, F24, F26, F28, F30 are callee-saved. + * In N64, FP registers F24 .. F31 are callee-saved. + * In O32, FP registers F20 .. F23 are callee-saved. + */ +#ifndef SOFTFLOAT + cfc1 v0, $31 # too bad can't check if FP used +#if defined(__mips_n64) || defined(__mips_n32) + FP_S $f30, (_JB_FPREG_F30 * SZREG)(a0) + FP_S $f28, (_JB_FPREG_F28 * SZREG)(a0) + FP_S $f26, (_JB_FPREG_F26 * SZREG)(a0) + FP_S $f24, (_JB_FPREG_F24 * SZREG)(a0) +#endif +#if defined(__mips_n32) || defined(__mips_o32) || defined(__mips_o64) + FP_S $f22, (_JB_FPREG_F22 * SZREG)(a0) + FP_S $f20, (_JB_FPREG_F20 * SZREG)(a0) +#endif +#if defined(__mips_o32) || defined(__mips_o64) + FP_S $f21, (_JB_FPREG_F21 * SZREG)(a0) + FP_S $f23, (_JB_FPREG_F23 * SZREG)(a0) +#endif +#if defined(__mips_n64) + FP_S $f25, (_JB_FPREG_F25 * SZREG)(a0) + FP_S $f27, (_JB_FPREG_F27 * SZREG)(a0) + FP_S $f29, (_JB_FPREG_F29 * SZREG)(a0) + FP_S $f31, (_JB_FPREG_F31 * SZREG)(a0) +#endif + INT_S v0, (_JB_FPREG_FCSR * SZREG)(a0) +#endif /* ! SOFTFLOAT */ + REG_EPILOGUE + + j ra + move v0, zero +END(_setjmp) + +LEAF(_longjmp) + PIC_PROLOGUE(_longjmp) + PTR_SUBU sp, sp, CALLFRAME_SIZ + SAVE_GP(CALLFRAME_GP) + + REG_PROLOGUE + REG_L v0, (_JB_MAGIC * SZREG)(a0) # get magic number + REG_L ra, (_JB_REG_RA * SZREG)(a0) + REG_LI t0, _JB_MAGIC__SETJMP + bne v0, t0, botch # jump if error + PTR_ADDU sp, sp, CALLFRAME_SIZ # does not matter, sanity + /* + * From "MIPSpro N32 ABI Handbook", Table 2-1: + * Registers s0..s7 are callee-saved. + * The sp register is callee-saved. + * The fp (or s8) register is callee-saved. + * The gp register is callee-saved (for n32/n64). + */ + REG_L s0, (_JB_REG_S0 * SZREG)(a0) + REG_L s1, (_JB_REG_S1 * SZREG)(a0) + REG_L s2, (_JB_REG_S2 * SZREG)(a0) + REG_L s3, (_JB_REG_S3 * SZREG)(a0) + REG_L s4, (_JB_REG_S4 * SZREG)(a0) + REG_L s5, (_JB_REG_S5 * SZREG)(a0) + REG_L s6, (_JB_REG_S6 * SZREG)(a0) + REG_L s7, (_JB_REG_S7 * SZREG)(a0) + REG_L sp, (_JB_REG_SP * SZREG)(a0) + REG_L s8, (_JB_REG_S8 * SZREG)(a0) +#if defined(__mips_n32) || defined(__mips_n64) + REG_L gp, (_JB_REG_GP * SZREG)(a0) +#endif +#ifndef SOFTFLOAT + # get fpu status + INT_L v0, (_JB_FPREG_FCSR * SZREG)(a0) + ctc1 v0, $31 + /* + * From "MIPSpro N32 ABI Handbook", Table 2-1: + * In N32, FP registers F20, F22, F24, F26, F28, F30 are callee-saved. + * In N64, FP registers F24 .. F31 are callee-saved. + * In O32, FP registers F20 .. F23 are callee-saved. + */ +#if defined(__mips_n64) || defined(__mips_n32) + FP_L $f30, (_JB_FPREG_F30 * SZREG)(a0) + FP_L $f28, (_JB_FPREG_F28 * SZREG)(a0) + FP_L $f26, (_JB_FPREG_F26 * SZREG)(a0) + FP_L $f24, (_JB_FPREG_F24 * SZREG)(a0) +#endif +#if defined(__mips_n32) || defined(__mips_o32) || defined(__mips_o64) + FP_L $f22, (_JB_FPREG_F22 * SZREG)(a0) + FP_L $f20, (_JB_FPREG_F20 * SZREG)(a0) +#endif +#if defined(__mips_o32) || defined(__mips_o64) + FP_L $f21, (_JB_FPREG_F21 * SZREG)(a0) + FP_L $f23, (_JB_FPREG_F23 * SZREG)(a0) +#endif +#if defined(__mips_n64) + FP_L $f25, (_JB_FPREG_F25 * SZREG)(a0) + FP_L $f27, (_JB_FPREG_F27 * SZREG)(a0) + FP_L $f29, (_JB_FPREG_F29 * SZREG)(a0) + FP_L $f31, (_JB_FPREG_F31 * SZREG)(a0) +#endif +#endif /* ! SOFTFLOAT */ + + REG_EPILOGUE + move v0, a1 # get return value in 1st arg + j ra + nop + +botch: + /* + * We know we aren't returning so we don't care about restoring + * our caller's GP. + */ + PTR_LA t9, _C_LABEL(longjmperror) + jalr t9 + nop + + PIC_TAILCALL(abort) +END(_longjmp) diff --git a/lib/libc/mips/gen/fabs.S b/lib/libc/mips/gen/fabs.S new file mode 100644 index 0000000..685d350 --- /dev/null +++ b/lib/libc/mips/gen/fabs.S @@ -0,0 +1,58 @@ +/* $NetBSD: fabs.S,v 1.7 2003/08/07 16:42:15 agc Exp $ */ + +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/fabs.S 178580 2008-04-26 12:08:02Z imp $"); + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)fabs.s 8.1 (Berkeley) 2/16/94") + ASMSTR("$NetBSD: fabs.S,v 1.7 2003/08/07 16:42:15 agc Exp $") +#endif /* LIBC_SCCS and not lint */ + + +#ifdef __ABICALLS__ + .abicalls +#endif + .set noreorder + +/* + * fabs(x) + * double x; + * + * Return absolute value of x. + */ +LEAF(fabs) + j ra + abs.d $f0, $f12 # compute absolute value of x +END(fabs) diff --git a/lib/libc/mips/gen/fabs.c b/lib/libc/mips/gen/fabs.c new file mode 100644 index 0000000..2e0a2ee --- /dev/null +++ b/lib/libc/mips/gen/fabs.c @@ -0,0 +1,46 @@ +/* $NetBSD: fabs.c,v 1.2 2002/05/26 11:48:01 wiz Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe + * + * 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 Mark Brinicombe + * 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 AUTHOR 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 AUTHOR 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. + */ + +/* + * fabs(x) returns the absolute value of x. + */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/fabs.c 178580 2008-04-26 12:08:02Z imp $"); + +double +fabs(double x) +{ + if (x < 0) + x = -x; + return(x); +} diff --git a/lib/libc/mips/gen/flt_rounds.c b/lib/libc/mips/gen/flt_rounds.c new file mode 100644 index 0000000..21566b7 --- /dev/null +++ b/lib/libc/mips/gen/flt_rounds.c @@ -0,0 +1,30 @@ +/* $NetBSD: flt_rounds.c,v 1.5 2005/12/24 23:10:08 perry Exp $ */ + +/* + * Written by J.T. Conklin, Apr 11, 1995 + * Public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/flt_rounds.c 178580 2008-04-26 12:08:02Z imp $"); +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: flt_rounds.c,v 1.5 2005/12/24 23:10:08 perry Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include + +static const int map[] = { + 1, /* round to nearest */ + 0, /* round to zero */ + 2, /* round to positive infinity */ + 3 /* round to negative infinity */ +}; + +int +__flt_rounds() +{ + int x; + + __asm("cfc1 %0,$31" : "=r" (x)); + return map[x & 0x03]; +} diff --git a/lib/libc/mips/gen/hardfloat/fpgetmask.c b/lib/libc/mips/gen/hardfloat/fpgetmask.c new file mode 100644 index 0000000..8350237 --- /dev/null +++ b/lib/libc/mips/gen/hardfloat/fpgetmask.c @@ -0,0 +1,29 @@ +/* $NetBSD: fpgetmask.c,v 1.5 2005/12/24 23:10:08 perry Exp $ */ + +/* + * Written by J.T. Conklin, Apr 11, 1995 + * Public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/hardfloat/fpgetmask.c 201856 2010-01-08 23:50:39Z imp $"); +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: fpgetmask.c,v 1.5 2005/12/24 23:10:08 perry Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include + +#ifdef __weak_alias +__weak_alias(fpgetmask,_fpgetmask) +#endif + +fp_except_t +fpgetmask() +{ + int x; + + __asm("cfc1 %0,$31" : "=r" (x)); + return (x >> 7) & 0x1f; +} diff --git a/lib/libc/mips/gen/hardfloat/fpgetround.c b/lib/libc/mips/gen/hardfloat/fpgetround.c new file mode 100644 index 0000000..61d8285 --- /dev/null +++ b/lib/libc/mips/gen/hardfloat/fpgetround.c @@ -0,0 +1,29 @@ +/* $NetBSD: fpgetround.c,v 1.5 2005/12/24 23:10:08 perry Exp $ */ + +/* + * Written by J.T. Conklin, Apr 11, 1995 + * Public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/hardfloat/fpgetround.c 201856 2010-01-08 23:50:39Z imp $"); +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: fpgetround.c,v 1.5 2005/12/24 23:10:08 perry Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include + +#ifdef __weak_alias +__weak_alias(fpgetround,_fpgetround) +#endif + +fp_rnd_t +fpgetround() +{ + int x; + + __asm("cfc1 %0,$31" : "=r" (x)); + return x & 0x03; +} diff --git a/lib/libc/mips/gen/hardfloat/fpgetsticky.c b/lib/libc/mips/gen/hardfloat/fpgetsticky.c new file mode 100644 index 0000000..dec8046 --- /dev/null +++ b/lib/libc/mips/gen/hardfloat/fpgetsticky.c @@ -0,0 +1,29 @@ +/* $NetBSD: fpgetsticky.c,v 1.5 2005/12/24 23:10:08 perry Exp $ */ + +/* + * Written by J.T. Conklin, Apr 11, 1995 + * Public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/hardfloat/fpgetsticky.c 201856 2010-01-08 23:50:39Z imp $"); +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: fpgetsticky.c,v 1.5 2005/12/24 23:10:08 perry Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include + +#ifdef __weak_alias +__weak_alias(fpgetsticky,_fpgetsticky) +#endif + +fp_except_t +fpgetsticky() +{ + int x; + + __asm("cfc1 %0,$31" : "=r" (x)); + return (x >> 2) & 0x1f; +} diff --git a/lib/libc/mips/gen/hardfloat/fpsetmask.c b/lib/libc/mips/gen/hardfloat/fpsetmask.c new file mode 100644 index 0000000..c25dfa6 --- /dev/null +++ b/lib/libc/mips/gen/hardfloat/fpsetmask.c @@ -0,0 +1,38 @@ +/* $NetBSD: fpsetmask.c,v 1.5 2005/12/24 23:10:08 perry Exp $ */ + +/* + * Written by J.T. Conklin, Apr 11, 1995 + * Public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/hardfloat/fpsetmask.c 201856 2010-01-08 23:50:39Z imp $"); +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: fpsetmask.c,v 1.5 2005/12/24 23:10:08 perry Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include + +#ifdef __weak_alias +__weak_alias(fpsetmask,_fpsetmask) +#endif + +fp_except_t +fpsetmask(mask) + fp_except_t mask; +{ + fp_except_t old; + fp_except_t new; + + __asm("cfc1 %0,$31" : "=r" (old)); + + new = old; + new &= ~(0x1f << 7); + new |= ((mask & 0x1f) << 7); + + __asm("ctc1 %0,$31" : : "r" (new)); + + return (old >> 7) & 0x1f; +} diff --git a/lib/libc/mips/gen/hardfloat/fpsetround.c b/lib/libc/mips/gen/hardfloat/fpsetround.c new file mode 100644 index 0000000..496d184 --- /dev/null +++ b/lib/libc/mips/gen/hardfloat/fpsetround.c @@ -0,0 +1,37 @@ +/* $NetBSD: fpsetround.c,v 1.5 2005/12/24 23:10:08 perry Exp $ */ + +/* + * Written by J.T. Conklin, Apr 11, 1995 + * Public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/hardfloat/fpsetround.c 201856 2010-01-08 23:50:39Z imp $"); +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: fpsetround.c,v 1.5 2005/12/24 23:10:08 perry Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include + +#ifdef __weak_alias +__weak_alias(fpsetround,_fpsetround) +#endif + +fp_rnd_t +fpsetround(fp_rnd_t rnd_dir) +{ + fp_rnd_t old; + fp_rnd_t new; + + __asm("cfc1 %0,$31" : "=r" (old)); + + new = old; + new &= ~0x03; + new |= (rnd_dir & 0x03); + + __asm("ctc1 %0,$31" : : "r" (new)); + + return old & 0x03; +} diff --git a/lib/libc/mips/gen/hardfloat/fpsetsticky.c b/lib/libc/mips/gen/hardfloat/fpsetsticky.c new file mode 100644 index 0000000..2b8b665 --- /dev/null +++ b/lib/libc/mips/gen/hardfloat/fpsetsticky.c @@ -0,0 +1,38 @@ +/* $NetBSD: fpsetsticky.c,v 1.5 2005/12/24 23:10:08 perry Exp $ */ + +/* + * Written by J.T. Conklin, Apr 11, 1995 + * Public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/hardfloat/fpsetsticky.c 201856 2010-01-08 23:50:39Z imp $"); +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: fpsetsticky.c,v 1.5 2005/12/24 23:10:08 perry Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include "namespace.h" + +#include + +#ifdef __weak_alias +__weak_alias(fpsetsticky,_fpsetsticky) +#endif + +fp_except +fpsetsticky(sticky) + fp_except sticky; +{ + fp_except old; + fp_except new; + + __asm("cfc1 %0,$31" : "=r" (old)); + + new = old; + new &= ~(0x1f << 2); + new |= ((sticky & 0x1f) << 2); + + __asm("ctc1 %0,$31" : : "r" (new)); + + return (old >> 2) & 0x1f; +} diff --git a/lib/libc/mips/gen/infinity.c b/lib/libc/mips/gen/infinity.c new file mode 100644 index 0000000..aff7796 --- /dev/null +++ b/lib/libc/mips/gen/infinity.c @@ -0,0 +1,26 @@ +/* + * infinity.c + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/infinity.c 178580 2008-04-26 12:08:02Z imp $"); + +#include + +/* bytes for +Infinity on a 387 */ +const union __infinity_un __infinity = { +#if BYTE_ORDER == BIG_ENDIAN + { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } +#else + { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } +#endif +}; + +/* bytes for NaN */ +const union __nan_un __nan = { +#if BYTE_ORDER == BIG_ENDIAN + {0x7f, 0xa0, 0, 0} +#else + { 0, 0, 0xa0, 0x7f } +#endif +}; diff --git a/lib/libc/mips/gen/ldexp.S b/lib/libc/mips/gen/ldexp.S new file mode 100644 index 0000000..a7bf26e --- /dev/null +++ b/lib/libc/mips/gen/ldexp.S @@ -0,0 +1,219 @@ +/* $NetBSD: ldexp.S,v 1.8 2003/08/07 16:42:15 agc Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/ldexp.S 178580 2008-04-26 12:08:02Z imp $"); + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)ldexp.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: ldexp.S,v 1.8 2003/08/07 16:42:15 agc Exp $") +#endif /* LIBC_SCCS and not lint */ + +#ifdef __ABICALLS__ + .abicalls +#endif + +#define DEXP_INF 0x7ff +#define DEXP_BIAS 1023 +#define DEXP_MIN -1022 +#define DEXP_MAX 1023 +#define DFRAC_BITS 52 +#define DIMPL_ONE 0x00100000 +#define DLEAD_ZEROS 31 - 20 +#define STICKYBIT 1 +#define GUARDBIT 0x80000000 +#define DSIGNAL_NAN 0x00040000 +#define DQUIET_NAN0 0x0007ffff +#define DQUIET_NAN1 0xffffffff + +/* + * double ldexp(x, N) + * double x; int N; + * + * Return x * (2**N), for integer values N. + */ +LEAF(ldexp) + mfc1 v1, $f13 # get MSW of x + mfc1 t3, $f12 # get LSW of x + sll t1, v1, 1 # get x exponent + srl t1, t1, 32 - 11 + beq t1, DEXP_INF, 9f # is it a NAN or infinity? + beq t1, zero, 1f # zero or denormalized number? + addu t1, t1, a2 # scale exponent + sll v0, a2, 20 # position N for addition + bge t1, DEXP_INF, 8f # overflow? + addu v0, v0, v1 # multiply by (2**N) + ble t1, zero, 4f # underflow? + mtc1 v0, $f1 # save MSW of result + mtc1 t3, $f0 # save LSW of result + j ra +1: + sll t2, v1, 32 - 20 # get x fraction + srl t2, t2, 32 - 20 + srl t0, v1, 31 # get x sign + bne t2, zero, 1f + beq t3, zero, 9f # result is zero +1: +/* + * Find out how many leading zero bits are in t2,t3 and put in t9. + */ + move v0, t2 + move t9, zero + bne t2, zero, 1f + move v0, t3 + addu t9, 32 +1: + srl ta0, v0, 16 + bne ta0, zero, 1f + addu t9, 16 + sll v0, 16 +1: + srl ta0, v0, 24 + bne ta0, zero, 1f + addu t9, 8 + sll v0, 8 +1: + srl ta0, v0, 28 + bne ta0, zero, 1f + addu t9, 4 + sll v0, 4 +1: + srl ta0, v0, 30 + bne ta0, zero, 1f + addu t9, 2 + sll v0, 2 +1: + srl ta0, v0, 31 + bne ta0, zero, 1f + addu t9, 1 +/* + * Now shift t2,t3 the correct number of bits. + */ +1: + subu t9, t9, DLEAD_ZEROS # dont count normal leading zeros + li t1, DEXP_MIN + DEXP_BIAS + subu t1, t1, t9 # adjust exponent + addu t1, t1, a2 # scale exponent + li v0, 32 + blt t9, v0, 1f + subu t9, t9, v0 # shift fraction left >= 32 bits + sll t2, t3, t9 + move t3, zero + b 2f +1: + subu v0, v0, t9 # shift fraction left < 32 bits + sll t2, t2, t9 + srl ta0, t3, v0 + or t2, t2, ta0 + sll t3, t3, t9 +2: + bge t1, DEXP_INF, 8f # overflow? + ble t1, zero, 4f # underflow? + sll t2, t2, 32 - 20 # clear implied one bit + srl t2, t2, 32 - 20 +3: + sll t1, t1, 31 - 11 # reposition exponent + sll t0, t0, 31 # reposition sign + or t0, t0, t1 # put result back together + or t0, t0, t2 + mtc1 t0, $f1 # save MSW of result + mtc1 t3, $f0 # save LSW of result + j ra +4: + li v0, 0x80000000 + ble t1, -52, 7f # is result too small for denorm? + sll t2, v1, 31 - 20 # clear exponent, extract fraction + or t2, t2, v0 # set implied one bit + blt t1, -30, 2f # will all bits in t3 be shifted out? + srl t2, t2, 31 - 20 # shift fraction back to normal position + subu t1, t1, 1 + sll ta0, t2, t1 # shift right t2,t3 based on exponent + srl t8, t3, t1 # save bits shifted out + negu t1 + srl t3, t3, t1 + or t3, t3, ta0 + srl t2, t2, t1 + bge t8, zero, 1f # does result need to be rounded? + addu t3, t3, 1 # round result + sltu ta0, t3, 1 + sll t8, t8, 1 + addu t2, t2, ta0 + bne t8, zero, 1f # round result to nearest + and t3, t3, ~1 +1: + mtc1 t3, $f0 # save denormalized result (LSW) + mtc1 t2, $f1 # save denormalized result (MSW) + bge v1, zero, 1f # should result be negative? + neg.d $f0, $f0 # negate result +1: + j ra +2: + mtc1 zero, $f1 # exponent and upper fraction + addu t1, t1, 20 # compute amount to shift right by + sll t8, t2, t1 # save bits shifted out + negu t1 + srl t3, t2, t1 + bge t8, zero, 1f # does result need to be rounded? + addu t3, t3, 1 # round result + sltu ta0, t3, 1 + sll t8, t8, 1 + mtc1 ta0, $f1 # exponent and upper fraction + bne t8, zero, 1f # round result to nearest + and t3, t3, ~1 +1: + mtc1 t3, $f0 + bge v1, zero, 1f # is result negative? + neg.d $f0, $f0 # negate result +1: + j ra +7: + mtc1 zero, $f0 # result is zero + mtc1 zero, $f1 + beq t0, zero, 1f # is result positive? + neg.d $f0, $f0 # negate result +1: + j ra +8: + li t1, 0x7ff00000 # result is infinity (MSW) + mtc1 t1, $f1 + mtc1 zero, $f0 # result is infinity (LSW) + bge v1, zero, 1f # should result be negative infinity? + neg.d $f0, $f0 # result is negative infinity +1: + add.d $f0, $f0 # cause overflow faults if enabled + j ra +9: + mov.d $f0, $f12 # yes, result is just x + j ra +END(ldexp) diff --git a/lib/libc/mips/gen/longjmp.c b/lib/libc/mips/gen/longjmp.c new file mode 100644 index 0000000..43da088 --- /dev/null +++ b/lib/libc/mips/gen/longjmp.c @@ -0,0 +1,103 @@ +/* $NetBSD: longjmp.c,v 1.1 2005/09/17 11:49:39 tsutsui Exp $ */ + +/*- + * Copyright (c) 2003 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christian Limpach and Matt Thomas. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/longjmp.c 251091 2013-05-29 01:54:10Z emaste $"); +#include "namespace.h" +#include +#include +#include +#include +#include + +#include + +void +__longjmp14(jmp_buf env, int val) +{ + struct sigcontext *sc = (void *)env; + ucontext_t uc; + + /* Ensure non-zero SP and sigcontext magic number is present */ + if (sc->sc_regs[_R_SP] == 0 || sc->sc_regs[_R_ZERO] != 0xACEDBADE) + goto err; + + /* Ensure non-zero return value */ + if (val == 0) + val = 1; + + /* + * Set _UC_{SET,CLR}STACK according to SS_ONSTACK. + * + * Restore the signal mask with sigprocmask() instead of _UC_SIGMASK, + * since libpthread may want to interpose on signal handling. + */ + uc.uc_flags = _UC_CPU | (sc->sc_onstack ? _UC_SETSTACK : _UC_CLRSTACK); + + sigprocmask(SIG_SETMASK, &sc->sc_mask, NULL); + + /* Clear uc_link */ + uc.uc_link = 0; + + /* Save return value in context */ + uc.uc_mcontext.__gregs[_R_V0] = val; + + /* Copy saved registers */ + uc.uc_mcontext.__gregs[_REG_S0] = sc->sc_regs[_R_S0]; + uc.uc_mcontext.__gregs[_REG_S1] = sc->sc_regs[_R_S1]; + uc.uc_mcontext.__gregs[_REG_S2] = sc->sc_regs[_R_S2]; + uc.uc_mcontext.__gregs[_REG_S3] = sc->sc_regs[_R_S3]; + uc.uc_mcontext.__gregs[_REG_S4] = sc->sc_regs[_R_S4]; + uc.uc_mcontext.__gregs[_REG_S5] = sc->sc_regs[_R_S5]; + uc.uc_mcontext.__gregs[_REG_S6] = sc->sc_regs[_R_S6]; + uc.uc_mcontext.__gregs[_REG_S7] = sc->sc_regs[_R_S7]; + uc.uc_mcontext.__gregs[_REG_S8] = sc->sc_regs[_R_S8]; + uc.uc_mcontext.__gregs[_REG_SP] = sc->sc_regs[_R_SP]; + uc.uc_mcontext.__gregs[_REG_RA] = sc->sc_regs[_R_RA]; + uc.uc_mcontext.__gregs[_REG_EPC] = sc->sc_pc; + + /* Copy FP state */ + if (sc->sc_fpused) { + /* FP saved regs are $f20 .. $f31 */ + memcpy(&uc.uc_mcontext.__fpregs.__fp_r.__fp_regs[20], + &sc->sc_fpregs[20], 32 - 20); + uc.uc_mcontext.__fpregs.__fp_csr = + sc->sc_fpregs[_R_FSR - _FPBASE]; + /* XXX sc_fp_control */ + uc.uc_flags |= _UC_FPU; + } + + setcontext(&uc); + err: + longjmperror(); + abort(); + /* NOTREACHED */ +} diff --git a/lib/libc/mips/gen/makecontext.c b/lib/libc/mips/gen/makecontext.c new file mode 100644 index 0000000..32ef991 --- /dev/null +++ b/lib/libc/mips/gen/makecontext.c @@ -0,0 +1,123 @@ +/* $NetBSD: makecontext.c,v 1.5 2009/12/14 01:07:42 matt Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Klaus Klein. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/makecontext.c 209233 2010-06-16 14:13:36Z jchandra $"); +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: makecontext.c,v 1.5 2009/12/14 01:07:42 matt Exp $"); +#endif + +#include +#include + +#include +#include +#include +#include +#include + +__weak_reference(__makecontext, makecontext); + +void _ctx_done(ucontext_t *); +void _ctx_start(void); + +void +__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) +{ + mcontext_t *mc; + register_t *sp; + int i; + va_list ap; + + /* + * XXX/juli + * We need an mc_len or mc_flags like other architectures + * so that we can mark a context as invalid. Store it in + * mc->mc_regs[ZERO] perhaps? + */ + if (argc < 0 || argc > 6 || ucp == NULL || + ucp->uc_stack.ss_sp == NULL || + ucp->uc_stack.ss_size < MINSIGSTKSZ) + return; + mc = &ucp->uc_mcontext; + + sp = (register_t *) + ((uintptr_t)ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); +#if defined(__mips_o32) || defined(__mips_o64) + sp -= (argc >= 4 ? argc : 4); /* Make room for >=4 arguments. */ + sp = (register_t *) + ((uintptr_t)sp & ~0x7); /* Align on double-word boundary. */ +#elif defined(__mips_n32) || defined(__mips_n64) + sp -= (argc > 8 ? argc - 8 : 0); /* Make room for > 8 arguments. */ + sp = (register_t *) + ((uintptr_t)sp & ~0xf); /* Align on quad-word boundary. */ +#endif + + mc->mc_regs[SP] = (intptr_t)sp; + mc->mc_regs[S0] = (intptr_t)ucp; + mc->mc_regs[T9] = (intptr_t)func; + mc->mc_pc = (intptr_t)_ctx_start; + + /* Construct argument list. */ + va_start(ap, argc); +#if defined(__mips_o32) || defined(__mips_o64) + /* Up to the first four arguments are passed in $a0-3. */ + for (i = 0; i < argc && i < 4; i++) + /* LINTED register_t is safe */ + mc->mc_regs[A0 + i] = va_arg(ap, register_t); + /* Pass remaining arguments on the stack above the $a0-3 gap. */ + sp += i; +#endif +#if defined(__mips_n32) || defined(__mips_n64) + /* Up to the first 8 arguments are passed in $a0-7. */ + for (i = 0; i < argc && i < 8; i++) + /* LINTED register_t is safe */ + mc->mc_regs[A0 + i] = va_arg(ap, register_t); + /* Pass remaining arguments on the stack above the $a0-3 gap. */ +#endif + /* Pass remaining arguments on the stack above the $a0-3 gap. */ + for (; i < argc; i++) + /* LINTED uintptr_t is safe */ + *sp++ = va_arg(ap, register_t); + va_end(ap); +} + +void +_ctx_done(ucontext_t *ucp) +{ + + if (ucp->uc_link == NULL) + exit(0); + else { + setcontext((const ucontext_t *)ucp->uc_link); + abort(); + } +} diff --git a/lib/libc/mips/gen/setjmp.S b/lib/libc/mips/gen/setjmp.S new file mode 100644 index 0000000..1c35fc0 --- /dev/null +++ b/lib/libc/mips/gen/setjmp.S @@ -0,0 +1,238 @@ +/* $NetBSD: setjmp.S,v 1.17 2005/09/17 11:49:39 tsutsui Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/setjmp.S 274816 2014-11-21 20:02:06Z brooks $"); +#include + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)setjmp.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: setjmp.S,v 1.17 2005/09/17 11:49:39 tsutsui Exp $") +#endif /* LIBC_SCCS and not lint */ + +#include "SYS.h" + +#ifdef __ABICALLS__ + .abicalls +#endif + +/* + * C library -- setjmp, longjmp + * + * longjmp(a,v) + * will generate a "return(v)" from + * the last call to + * setjmp(a) + * by restoring registers from the stack, + * and a struct sigcontext, see + */ + +#define SETJMP_FRAME_SIZE (CALLFRAME_SIZ + (SZREG * 2)) + + +NESTED(setjmp, SETJMP_FRAME_SIZE, ra) + .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) + SETUP_GP + PTR_SUBU sp, sp, SETJMP_FRAME_SIZE # allocate stack frame + SAVE_GP(CALLFRAME_GP) + SETUP_GP64(CALLFRAME_GP, setjmp) + + REG_S ra, CALLFRAME_RA(sp) # save RA + REG_S a0, CALLFRAME_SIZ(sp) # store env + + /* Get the signal mask. */ + PTR_ADDU a2, a0, _JB_SIGMASK * SZREG # &oenv + li a0, 1 # SIG_SETBLOCK + move a1, zero # &env == 0 + PTR_LA t9, _C_LABEL(sigprocmask) # get current signal mask + jalr t9 + + RESTORE_GP64 + REG_L a0, CALLFRAME_SIZ(sp) # restore env pointer + REG_L ra, CALLFRAME_RA(sp) # restore RA + PTR_ADDU sp, sp, SETJMP_FRAME_SIZE # pop stack frame + + REG_LI v0, _JB_MAGIC_SETJMP + REG_S v0, (_JB_MAGIC * SZREG)(a0) + REG_S ra, (_JB_REG_RA * SZREG)(a0) + /* + * From "MIPSpro N32 ABI Handbook", Table 2-1: + * Registers s0..s7 are callee-saved. + * The sp register is callee-saved. + * The fp (or s8) register is callee-saved. + * The gp register is callee-saved (for n32/n64). + */ + REG_S s0, (_JB_REG_S0 * SZREG)(a0) + REG_S s1, (_JB_REG_S1 * SZREG)(a0) + REG_S s2, (_JB_REG_S2 * SZREG)(a0) + REG_S s3, (_JB_REG_S3 * SZREG)(a0) + REG_S s4, (_JB_REG_S4 * SZREG)(a0) + REG_S s5, (_JB_REG_S5 * SZREG)(a0) + REG_S s6, (_JB_REG_S6 * SZREG)(a0) + REG_S s7, (_JB_REG_S7 * SZREG)(a0) + REG_S sp, (_JB_REG_SP * SZREG)(a0) + REG_S s8, (_JB_REG_S8 * SZREG)(a0) +#if defined(__mips_n32) || defined(__mips_n64) + REG_S gp, (_JB_REG_GP * SZREG)(a0) +#endif +#ifndef SOFTFLOAT + /* + * From "MIPSpro N32 ABI Handbook", Table 2-1: + * In N32, FP registers F20, F22, F24, F26, F28, F30 are callee-saved. + * In N64, FP registers F24 .. F31 are callee-saved. + * In O32, FP registers F20 .. F23 are callee-saved. + */ + cfc1 v0, $31 + INT_S v0, (_JB_FPREG_FCSR * SZREG)(a0) +#if defined(__mips_o32) || defined(__mips_o64) || defined(__mips_n32) + FP_S $f20, (_JB_FPREG_F20 * SZREG)(a0) + FP_S $f22, (_JB_FPREG_F22 * SZREG)(a0) +#endif +#if defined(__mips_o32) || defined(__mips_o64) + FP_S $f21, (_JB_FPREG_F21 * SZREG)(a0) + FP_S $f23, (_JB_FPREG_F23 * SZREG)(a0) +#endif +#if defined(__mips_n32) || defined(__mips_n64) + FP_S $f24, (_JB_FPREG_F24 * SZREG)(a0) + FP_S $f26, (_JB_FPREG_F26 * SZREG)(a0) + FP_S $f28, (_JB_FPREG_F28 * SZREG)(a0) + FP_S $f30, (_JB_FPREG_F30 * SZREG)(a0) +#endif +#if defined(__mips_n64) + FP_S $f25, (_JB_FPREG_F25 * SZREG)(a0) + FP_S $f27, (_JB_FPREG_F27 * SZREG)(a0) + FP_S $f29, (_JB_FPREG_F29 * SZREG)(a0) + FP_S $f31, (_JB_FPREG_F31 * SZREG)(a0) +#endif +#endif /* ! SOFTFLOAT */ + + move v0, zero + jr ra +END(setjmp) + +#define LONGJMP_FRAME_SIZE (CALLFRAME_SIZ + (SZREG * 2)) + +NESTED(longjmp, LONGJMP_FRAME_SIZE, ra) + .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) + PIC_PROLOGUE(longjmp) + PTR_SUBU sp, sp, LONGJMP_FRAME_SIZE # allocate stack frame + SAVE_GP(CALLFRAME_GP) + + REG_S ra, CALLFRAME_RA(sp) # save RA + REG_L v0, (_JB_MAGIC * SZREG)(a0) + REG_LI t0, _JB_MAGIC_SETJMP + bne v0, t0, botch # jump if error + nop + + REG_S a0, CALLFRAME_SIZ(sp) # save env + REG_S a1, (CALLFRAME_SIZ + SZREG)(sp) # save return value + + # set sigmask + PTR_ADDU a1, a0, _JB_SIGMASK * SZREG # &set + move a2, zero # &oset == NULL + li a0, 3 # SIG_SETMASK + PTR_LA t9,_C_LABEL(sigprocmask) # set current signal mask + jal t9 + nop + + REG_L a0, CALLFRAME_SIZ(sp) # restore env + REG_L a1, (CALLFRAME_SIZ + SZREG)(sp) # restore return value + + REG_L ra, (_JB_REG_RA * SZREG)(a0) + /* + * From "MIPSpro N32 ABI Handbook", Table 2-1: + * Registers s0..s7 are callee-saved. + * The sp register is callee-saved. + * The fp (or s8) register is callee-saved. + * The gp register is callee-saved (for n32/n64). + */ + REG_L s0, (_JB_REG_S0 * SZREG)(a0) + REG_L s1, (_JB_REG_S1 * SZREG)(a0) + REG_L s2, (_JB_REG_S2 * SZREG)(a0) + REG_L s3, (_JB_REG_S3 * SZREG)(a0) + REG_L s4, (_JB_REG_S4 * SZREG)(a0) + REG_L s5, (_JB_REG_S5 * SZREG)(a0) + REG_L s6, (_JB_REG_S6 * SZREG)(a0) + REG_L s7, (_JB_REG_S7 * SZREG)(a0) + REG_L sp, (_JB_REG_SP * SZREG)(a0) + REG_L s8, (_JB_REG_S8 * SZREG)(a0) +#if defined(__mips_n32) || defined(__mips_n64) + REG_L gp, (_JB_REG_GP * SZREG)(a0) +#endif +#ifndef SOFTFLOAT + /* + * From "MIPSpro N32 ABI Handbook", Table 2-1: + * In N32, FP registers F20, F22, F24, F26, F28, F30 are callee-saved. + * In N64, FP registers F23 .. F31 are callee-saved. + * In O32, FP registers F20 .. F23 are callee-saved. + */ + INT_L v0, (_JB_FPREG_FCSR * SZREG)(a0) + ctc1 v0, $31 +#if defined(__mips_n64) || defined(__mips_n32) + FP_L $f30, (_JB_FPREG_F30 * SZREG)(a0) + FP_L $f28, (_JB_FPREG_F28 * SZREG)(a0) + FP_L $f26, (_JB_FPREG_F26 * SZREG)(a0) + FP_L $f24, (_JB_FPREG_F24 * SZREG)(a0) +#endif +#if defined(__mips_n32) || defined(__mips_o32) || defined(__mips_o64) + FP_L $f22, (_JB_FPREG_F22 * SZREG)(a0) + FP_L $f20, (_JB_FPREG_F20 * SZREG)(a0) +#endif +#if defined(__mips_o32) || defined(__mips_o64) + FP_L $f21, (_JB_FPREG_F21 * SZREG)(a0) + FP_L $f23, (_JB_FPREG_F23 * SZREG)(a0) +#endif +#if defined(__mips_n64) + FP_L $f25, (_JB_FPREG_F25 * SZREG)(a0) + FP_L $f27, (_JB_FPREG_F27 * SZREG)(a0) + FP_L $f29, (_JB_FPREG_F29 * SZREG)(a0) + FP_L $f31, (_JB_FPREG_F31 * SZREG)(a0) +#endif +#endif /* ! SOFTFLOAT */ + + move v0, a1 + j ra + nop + +botch: + /* + * We know we aren't returning so we don't care about restoring + * our caller's GP. + */ + PTR_LA t9, _C_LABEL(longjmperror) + jalr t9 + nop + + PIC_TAILCALL(abort) +END(longjmp) diff --git a/lib/libc/mips/gen/signalcontext.c b/lib/libc/mips/gen/signalcontext.c new file mode 100644 index 0000000..4599aed --- /dev/null +++ b/lib/libc/mips/gen/signalcontext.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2004 Olivier Houchard + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/signalcontext.c 178580 2008-04-26 12:08:02Z imp $"); + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +__weak_reference(__signalcontext, signalcontext); + +extern void _ctx_start(void); + +int +__signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func) +{ + /* XXXMIPS: Implement me */ + return (0); +} diff --git a/lib/libc/mips/gen/sigsetjmp.S b/lib/libc/mips/gen/sigsetjmp.S new file mode 100644 index 0000000..9a010a2 --- /dev/null +++ b/lib/libc/mips/gen/sigsetjmp.S @@ -0,0 +1,77 @@ +/* $NetBSD: sigsetjmp.S,v 1.8 2005/09/17 11:49:39 tsutsui Exp $ */ + +/*- + * Copyright (c) 1991, 1993, 1995, + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Havard Eidnes. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/gen/sigsetjmp.S 277877 2015-01-29 15:30:04Z emaste $"); +#include +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)setjmp.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: sigsetjmp.S,v 1.8 2005/09/17 11:49:39 tsutsui Exp $") +#endif /* LIBC_SCCS and not lint */ + +#include "SYS.h" + +#ifdef __ABICALLS__ + .abicalls +#endif + +/* + * C library -- sigsetjmp, siglongjmp + * + * siglongjmp(a,v) + * will generate a "return(v)" from + * the last call to + * sigsetjmp(a, savemask) + * by restoring registers from the stack, + * and dependent on savemask restores the + * signal mask. + */ + +LEAF(sigsetjmp) + PIC_PROLOGUE(sigsetjmp) + + bne a1, zero, 1f # do saving of signal mask? + PIC_TAILCALL(_setjmp) + +1: PIC_TAILCALL(setjmp) +END(sigsetjmp) + +LEAF(siglongjmp) + PIC_PROLOGUE(siglongjmp) + REG_L t0, (_JB_MAGIC * SZREG)(a0) + REG_LI t1, _JB_MAGIC__SETJMP + bne t0, t1, 1f # setjmp or _setjmp magic? + PIC_TAILCALL(_longjmp) +1: PIC_TAILCALL(longjmp) +END(siglongjmp) diff --git a/lib/libc/mips/net/Makefile.inc b/lib/libc/mips/net/Makefile.inc new file mode 100644 index 0000000..f61e6d9 --- /dev/null +++ b/lib/libc/mips/net/Makefile.inc @@ -0,0 +1,4 @@ +# $NetBSD: Makefile.inc,v 1.3 2003/08/01 17:03:51 lukem Exp $ +# $FreeBSD: releng/11.1/lib/libc/mips/net/Makefile.inc 178580 2008-04-26 12:08:02Z imp $ + +SRCS+= htonl.S ntohl.S htons.S ntohs.S diff --git a/lib/libc/mips/net/htonl.S b/lib/libc/mips/net/htonl.S new file mode 100644 index 0000000..705696d --- /dev/null +++ b/lib/libc/mips/net/htonl.S @@ -0,0 +1,51 @@ +/* $NetBSD: byte_swap_4.S,v 1.2 2006/02/08 21:52:36 simonb Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/net/htonl.S 251091 2013-05-29 01:54:10Z emaste $"); + +LEAF(htonl) # a0 = 0x11223344, return 0x44332211 +#ifdef __MIPSEB__ + move v0, a0 +#else + srl v1, a0, 24 # v1 = 0x00000011 + sll v0, a0, 24 # v0 = 0x44000000 + or v0, v0, v1 + and v1, a0, 0xff00 + sll v1, v1, 8 # v1 = 0x00330000 + or v0, v0, v1 + srl v1, a0, 8 + and v1, v1, 0xff00 # v1 = 0x00002200 + or v0, v0, v1 +#endif + j ra +END(htonl) diff --git a/lib/libc/mips/net/htons.S b/lib/libc/mips/net/htons.S new file mode 100644 index 0000000..8382868 --- /dev/null +++ b/lib/libc/mips/net/htons.S @@ -0,0 +1,47 @@ +/* $NetBSD: byte_swap_2.S,v 1.2 2006/02/08 21:52:36 simonb Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/net/htons.S 251091 2013-05-29 01:54:10Z emaste $"); + +LEAF(htons) +#ifdef __MIPSEB__ + move v0, a0 +#else + srl v0, a0, 8 + and v0, v0, 0xff + sll v1, a0, 8 + and v1, v1, 0xff00 + or v0, v0, v1 +#endif + j ra +END(htons) diff --git a/lib/libc/mips/net/ntohl.S b/lib/libc/mips/net/ntohl.S new file mode 100644 index 0000000..afd4ef4 --- /dev/null +++ b/lib/libc/mips/net/ntohl.S @@ -0,0 +1,51 @@ +/* $NetBSD: byte_swap_4.S,v 1.2 2006/02/08 21:52:36 simonb Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/net/ntohl.S 251091 2013-05-29 01:54:10Z emaste $"); + +LEAF(ntohl) # a0 = 0x11223344, return 0x44332211 +#ifdef __MIPSEB__ + move v0, a0 +#else + srl v1, a0, 24 # v1 = 0x00000011 + sll v0, a0, 24 # v0 = 0x44000000 + or v0, v0, v1 + and v1, a0, 0xff00 + sll v1, v1, 8 # v1 = 0x00330000 + or v0, v0, v1 + srl v1, a0, 8 + and v1, v1, 0xff00 # v1 = 0x00002200 + or v0, v0, v1 +#endif + j ra +END(ntohl) diff --git a/lib/libc/mips/net/ntohs.S b/lib/libc/mips/net/ntohs.S new file mode 100644 index 0000000..c9df09d --- /dev/null +++ b/lib/libc/mips/net/ntohs.S @@ -0,0 +1,46 @@ +/* $NetBSD: byte_swap_2.S,v 1.2 2006/02/08 21:52:36 simonb Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/net/ntohs.S 251091 2013-05-29 01:54:10Z emaste $"); + +LEAF(ntohs) +#ifdef __MIPSEB__ + move v0, a0 +#else + srl v0, a0, 8 + and v0, v0, 0xff + sll v1, a0, 8 + and v1, v1, 0xff00 + or v0, v0, v1 +#endif + j ra +END(ntohs) diff --git a/lib/libc/mips/softfloat/milieu.h b/lib/libc/mips/softfloat/milieu.h new file mode 100644 index 0000000..d8c53c6 --- /dev/null +++ b/lib/libc/mips/softfloat/milieu.h @@ -0,0 +1,48 @@ +/* $FreeBSD: releng/11.1/lib/libc/mips/softfloat/milieu.h 178580 2008-04-26 12:08:02Z imp $ */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Include common integer types and flags. +------------------------------------------------------------------------------- +*/ +#include "mips-gcc.h" + +/* +------------------------------------------------------------------------------- +Symbolic Boolean literals. +------------------------------------------------------------------------------- +*/ +enum { + FALSE = 0, + TRUE = 1 +}; diff --git a/lib/libc/mips/softfloat/mips-gcc.h b/lib/libc/mips/softfloat/mips-gcc.h new file mode 100644 index 0000000..ca6a47c --- /dev/null +++ b/lib/libc/mips/softfloat/mips-gcc.h @@ -0,0 +1,91 @@ +/* $NetBSD: arm-gcc.h,v 1.2 2001/02/21 18:09:25 bjh21 Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/mips/softfloat/mips-gcc.h 178580 2008-04-26 12:08:02Z imp $ */ + +/* +------------------------------------------------------------------------------- +One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined. +------------------------------------------------------------------------------- +*/ +#ifdef __MIPSEB__ +#define BIGENDIAN +#else +#define LITTLEENDIAN +#endif + +/* +------------------------------------------------------------------------------- +The macro `BITS64' can be defined to indicate that 64-bit integer types are +supported by the compiler. +------------------------------------------------------------------------------- +*/ +#define BITS64 + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines the most convenient type that holds +integers of at least as many bits as specified. For example, `uint8' should +be the most convenient type that can hold unsigned integers of as many as +8 bits. The `flag' type must be able to hold either a 0 or 1. For most +implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed +to the same as `int'. +------------------------------------------------------------------------------- +*/ +typedef int flag; +typedef int uint8; +typedef int int8; +typedef int uint16; +typedef int int16; +typedef unsigned int uint32; +typedef signed int int32; +#ifdef BITS64 +typedef unsigned long long int uint64; +typedef signed long long int int64; +#endif + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines a type that holds integers +of _exactly_ the number of bits specified. For instance, for most +implementation of C, `bits16' and `sbits16' should be `typedef'ed to +`unsigned short int' and `signed short int' (or `short int'), respectively. +------------------------------------------------------------------------------- +*/ +typedef unsigned char bits8; +typedef signed char sbits8; +typedef unsigned short int bits16; +typedef signed short int sbits16; +typedef unsigned int bits32; +typedef signed int sbits32; +#ifdef BITS64 +typedef unsigned long long int bits64; +typedef signed long long int sbits64; +#endif + +#ifdef BITS64 +/* +------------------------------------------------------------------------------- +The `LIT64' macro takes as its argument a textual integer literal and +if necessary ``marks'' the literal as having a 64-bit integer type. +For example, the GNU C Compiler (`gcc') requires that 64-bit literals be +appended with the letters `LL' standing for `long long', which is `gcc's +name for the 64-bit integer type. Some compilers may allow `LIT64' to be +defined as the identity macro: `#define LIT64( a ) a'. +------------------------------------------------------------------------------- +*/ +#define LIT64( a ) a##LL +#endif + +/* +------------------------------------------------------------------------------- +The macro `INLINE' can be used before functions that should be inlined. If +a compiler does not support explicit inlining, this macro should be defined +to be `static'. +------------------------------------------------------------------------------- +*/ +#define INLINE static __inline + +#if defined(SOFTFLOAT_FOR_GCC) +/* XXXMIPS: check this one */ +#define FLOAT64_DEMANGLE(a) (a) +#define FLOAT64_MANGLE(a) (a) +#endif diff --git a/lib/libc/mips/softfloat/softfloat.h b/lib/libc/mips/softfloat/softfloat.h new file mode 100644 index 0000000..01ce6e5 --- /dev/null +++ b/lib/libc/mips/softfloat/softfloat.h @@ -0,0 +1,315 @@ +/* $NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/mips/softfloat/softfloat.h 230189 2012-01-16 04:05:53Z das $ */ + +/* This is a derivative work. */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +The macro `FLOATX80' must be defined to enable the extended double-precision +floating-point format `floatx80'. If this macro is not defined, the +`floatx80' type will not be defined, and none of the functions that either +input or output the `floatx80' type will be defined. The same applies to +the `FLOAT128' macro and the quadruple-precision format `float128'. +------------------------------------------------------------------------------- +*/ +/* #define FLOATX80 */ +/* #define FLOAT128 */ + +#include + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point types. +------------------------------------------------------------------------------- +*/ +typedef unsigned int float32; +typedef unsigned long long float64; +#ifdef FLOATX80 +typedef struct { + unsigned short high; + unsigned long long low; +} floatx80; +#endif +#ifdef FLOAT128 +typedef struct { + unsigned long long high, low; +} float128; +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point underflow tininess-detection mode. +------------------------------------------------------------------------------- +*/ +#ifndef SOFTFLOAT_FOR_GCC +extern int float_detect_tininess; +#endif +enum { + float_tininess_after_rounding = 0, + float_tininess_before_rounding = 1 +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point rounding mode. +------------------------------------------------------------------------------- +*/ +extern int float_rounding_mode; +enum { + float_round_nearest_even = FE_TONEAREST, + float_round_to_zero = FE_TOWARDZERO, + float_round_down = FE_DOWNWARD, + float_round_up = FE_UPWARD +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point exception flags. +------------------------------------------------------------------------------- +*/ +extern int float_exception_flags; +extern int float_exception_mask; +enum { + float_flag_inexact = FE_INEXACT, + float_flag_underflow = FE_UNDERFLOW, + float_flag_overflow = FE_OVERFLOW, + float_flag_divbyzero = FE_DIVBYZERO, + float_flag_invalid = FE_INVALID +}; + +/* +------------------------------------------------------------------------------- +Routine to raise any or all of the software IEC/IEEE floating-point +exception flags. +------------------------------------------------------------------------------- +*/ +void float_raise( int ); + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE integer-to-floating-point conversion routines. +------------------------------------------------------------------------------- +*/ +float32 int32_to_float32( int ); +float64 int32_to_float64( int ); +#ifdef FLOATX80 +floatx80 int32_to_floatx80( int ); +#endif +#ifdef FLOAT128 +float128 int32_to_float128( int ); +#endif +#ifndef SOFTFLOAT_FOR_GCC /* __floatdi?f is in libgcc2.c */ +float32 int64_to_float32( long long ); +float64 int64_to_float64( long long ); +#ifdef FLOATX80 +floatx80 int64_to_floatx80( long long ); +#endif +#ifdef FLOAT128 +float128 int64_to_float128( long long ); +#endif +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float32_to_int32( float32 ); +int float32_to_int32_round_to_zero( float32 ); +#if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS) +unsigned int float32_to_uint32_round_to_zero( float32 ); +#endif +#ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */ +long long float32_to_int64( float32 ); +long long float32_to_int64_round_to_zero( float32 ); +#endif +float64 float32_to_float64( float32 ); +#ifdef FLOATX80 +floatx80 float32_to_floatx80( float32 ); +#endif +#ifdef FLOAT128 +float128 float32_to_float128( float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision operations. +------------------------------------------------------------------------------- +*/ +float32 float32_round_to_int( float32 ); +float32 float32_add( float32, float32 ); +float32 float32_sub( float32, float32 ); +float32 float32_mul( float32, float32 ); +float32 float32_div( float32, float32 ); +float32 float32_rem( float32, float32 ); +float32 float32_sqrt( float32 ); +int float32_eq( float32, float32 ); +int float32_le( float32, float32 ); +int float32_lt( float32, float32 ); +int float32_eq_signaling( float32, float32 ); +int float32_le_quiet( float32, float32 ); +int float32_lt_quiet( float32, float32 ); +#ifndef SOFTFLOAT_FOR_GCC +int float32_is_signaling_nan( float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float64_to_int32( float64 ); +int float64_to_int32_round_to_zero( float64 ); +#if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS) +unsigned int float64_to_uint32_round_to_zero( float64 ); +#endif +#ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */ +long long float64_to_int64( float64 ); +long long float64_to_int64_round_to_zero( float64 ); +#endif +float32 float64_to_float32( float64 ); +#ifdef FLOATX80 +floatx80 float64_to_floatx80( float64 ); +#endif +#ifdef FLOAT128 +float128 float64_to_float128( float64 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision operations. +------------------------------------------------------------------------------- +*/ +float64 float64_round_to_int( float64 ); +float64 float64_add( float64, float64 ); +float64 float64_sub( float64, float64 ); +float64 float64_mul( float64, float64 ); +float64 float64_div( float64, float64 ); +float64 float64_rem( float64, float64 ); +float64 float64_sqrt( float64 ); +int float64_eq( float64, float64 ); +int float64_le( float64, float64 ); +int float64_lt( float64, float64 ); +int float64_eq_signaling( float64, float64 ); +int float64_le_quiet( float64, float64 ); +int float64_lt_quiet( float64, float64 ); +#ifndef SOFTFLOAT_FOR_GCC +int float64_is_signaling_nan( float64 ); +#endif + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int floatx80_to_int32( floatx80 ); +int floatx80_to_int32_round_to_zero( floatx80 ); +long long floatx80_to_int64( floatx80 ); +long long floatx80_to_int64_round_to_zero( floatx80 ); +float32 floatx80_to_float32( floatx80 ); +float64 floatx80_to_float64( floatx80 ); +#ifdef FLOAT128 +float128 floatx80_to_float128( floatx80 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision rounding precision. Valid +values are 32, 64, and 80. +------------------------------------------------------------------------------- +*/ +extern int floatx80_rounding_precision; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision operations. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_round_to_int( floatx80 ); +floatx80 floatx80_add( floatx80, floatx80 ); +floatx80 floatx80_sub( floatx80, floatx80 ); +floatx80 floatx80_mul( floatx80, floatx80 ); +floatx80 floatx80_div( floatx80, floatx80 ); +floatx80 floatx80_rem( floatx80, floatx80 ); +floatx80 floatx80_sqrt( floatx80 ); +int floatx80_eq( floatx80, floatx80 ); +int floatx80_le( floatx80, floatx80 ); +int floatx80_lt( floatx80, floatx80 ); +int floatx80_eq_signaling( floatx80, floatx80 ); +int floatx80_le_quiet( floatx80, floatx80 ); +int floatx80_lt_quiet( floatx80, floatx80 ); +int floatx80_is_signaling_nan( floatx80 ); + +#endif + +#ifdef FLOAT128 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE quadruple-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float128_to_int32( float128 ); +int float128_to_int32_round_to_zero( float128 ); +long long float128_to_int64( float128 ); +long long float128_to_int64_round_to_zero( float128 ); +float32 float128_to_float32( float128 ); +float64 float128_to_float64( float128 ); +#ifdef FLOATX80 +floatx80 float128_to_floatx80( float128 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE quadruple-precision operations. +------------------------------------------------------------------------------- +*/ +float128 float128_round_to_int( float128 ); +float128 float128_add( float128, float128 ); +float128 float128_sub( float128, float128 ); +float128 float128_mul( float128, float128 ); +float128 float128_div( float128, float128 ); +float128 float128_rem( float128, float128 ); +float128 float128_sqrt( float128 ); +int float128_eq( float128, float128 ); +int float128_le( float128, float128 ); +int float128_lt( float128, float128 ); +int float128_eq_signaling( float128, float128 ); +int float128_le_quiet( float128, float128 ); +int float128_lt_quiet( float128, float128 ); +int float128_is_signaling_nan( float128 ); + +#endif + diff --git a/lib/libc/mips/string/Makefile.inc b/lib/libc/mips/string/Makefile.inc new file mode 100644 index 0000000..7c8c88e --- /dev/null +++ b/lib/libc/mips/string/Makefile.inc @@ -0,0 +1,13 @@ +# $FreeBSD: releng/11.1/lib/libc/mips/string/Makefile.inc 315044 2017-03-11 02:51:29Z brooks $ + +MDSRCS+= \ + bcmp.S \ + bcopy.S \ + bzero.S \ + ffs.S \ + memcpy.S \ + memmove.S \ + strchr.S \ + strcmp.S \ + strlen.S \ + strrchr.S diff --git a/lib/libc/mips/string/bcmp.S b/lib/libc/mips/string/bcmp.S new file mode 100644 index 0000000..42b5546 --- /dev/null +++ b/lib/libc/mips/string/bcmp.S @@ -0,0 +1,130 @@ +/* $NetBSD: bcmp.S,v 1.9 2009/12/14 01:07:42 matt Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/string/bcmp.S 209231 2010-06-16 12:55:14Z jchandra $"); + +#define _LOCORE /* XXX not really, just assembly-code source */ +#include /* LWLO/LWHI, SWLO/SWHI */ + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 + ASMSTR("from: @(#)bcmp.s 8.1 (Berkeley) 6/4/93") +#else + ASMSTR("$NetBSD: bcmp.S,v 1.9 2009/12/14 01:07:42 matt Exp $") +#endif +#endif /* LIBC_SCCS and not lint */ + +#ifdef __ABICALLS__ + .abicalls +#endif + +/* bcmp(s1, s2, n) */ + + +LEAF(bcmp) + .set noreorder + blt a2, 16, small # is it worth any trouble? + xor v0, a0, a1 # compare low two bits of addresses + and v0, v0, 3 + PTR_SUBU a3, zero, a1 # compute # bytes to word align address + bne v0, zero, unaligned # not possible to align addresses + and a3, a3, 3 + + beq a3, zero, 1f + PTR_SUBU a2, a2, a3 # subtract from remaining count + move v0, v1 # init v0,v1 so unmodified bytes match + LWHI v0, 0(a0) # read 1, 2, or 3 bytes + LWHI v1, 0(a1) + PTR_ADDU a1, a1, a3 + bne v0, v1, nomatch + PTR_ADDU a0, a0, a3 +1: + and a3, a2, ~3 # compute number of whole words left + PTR_SUBU a2, a2, a3 # which has to be >= (16-3) & ~3 + PTR_ADDU a3, a3, a0 # compute ending address +2: + lw v0, 0(a0) # compare words + lw v1, 0(a1) + PTR_ADDU a0, a0, 4 + bne v0, v1, nomatch + PTR_ADDU a1, a1, 4 + bne a0, a3, 2b + nop + b small # finish remainder + nop +unaligned: + beq a3, zero, 2f + PTR_SUBU a2, a2, a3 # subtract from remaining count + PTR_ADDU a3, a3, a0 # compute ending address +1: + lbu v0, 0(a0) # compare bytes until a1 word aligned + lbu v1, 0(a1) + PTR_ADDU a0, a0, 1 + bne v0, v1, nomatch + PTR_ADDU a1, a1, 1 + bne a0, a3, 1b + nop +2: + and a3, a2, ~3 # compute number of whole words left + PTR_SUBU a2, a2, a3 # which has to be >= (16-3) & ~3 + PTR_ADDU a3, a3, a0 # compute ending address +3: + LWHI v0, 0(a0) # compare words a0 unaligned, a1 aligned + LWLO v0, 3(a0) + lw v1, 0(a1) + PTR_ADDU a0, a0, 4 + bne v0, v1, nomatch + PTR_ADDU a1, a1, 4 + bne a0, a3, 3b + nop +small: + ble a2, zero, match + PTR_ADDU a3, a2, a0 # compute ending address +1: + lbu v0, 0(a0) + lbu v1, 0(a1) + PTR_ADDU a0, a0, 1 + bne v0, v1, nomatch + PTR_ADDU a1, a1, 1 + bne a0, a3, 1b + nop +match: + j ra + move v0, zero +nomatch: + j ra + li v0, 1 + .set reorder +END(bcmp) diff --git a/lib/libc/mips/string/bcopy.S b/lib/libc/mips/string/bcopy.S new file mode 100644 index 0000000..4c3890c --- /dev/null +++ b/lib/libc/mips/string/bcopy.S @@ -0,0 +1,297 @@ +/* $NetBSD: bcopy.S,v 1.3 2009/12/14 00:39:00 matt Exp $ */ + +/* + * Mach Operating System + * Copyright (c) 1993 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + * File: mips_bcopy.s + * Author: Chris Maeda + * Date: June 1993 + * + * Fast copy routine. Derived from aligned_block_copy. + */ + + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/string/bcopy.S 209231 2010-06-16 12:55:14Z jchandra $"); + +#define _LOCORE /* XXX not really, just assembly-code source */ +#include + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 + ASMSTR("from: @(#)mips_bcopy.s 2.2 CMU 18/06/93") +#else + ASMSTR("$NetBSD: bcopy.S,v 1.3 2009/12/14 00:39:00 matt Exp $") +#endif +#endif /* LIBC_SCCS and not lint */ + +#ifdef __ABICALLS__ + .abicalls +#endif + +/* + * bcopy(caddr_t src, caddr_t dst, unsigned int len) + * + * a0 src address + * a1 dst address + * a2 length + */ + +#if defined(MEMCOPY) || defined(MEMMOVE) +#ifdef MEMCOPY +#define FUNCTION memcpy +#else +#define FUNCTION memmove +#endif +#define SRCREG a1 +#define DSTREG a0 +#else +#define FUNCTION bcopy +#define SRCREG a0 +#define DSTREG a1 +#endif + +#define SIZEREG a2 + +LEAF(FUNCTION) + .set noat + .set noreorder + +#if defined(MEMCOPY) || defined(MEMMOVE) + /* set up return value, while we still can */ + move v0,DSTREG +#endif + /* + * Make sure we can copy forwards. + */ + sltu t0,SRCREG,DSTREG # t0 == SRCREG < DSTREG + bne t0,zero,6f # copy backwards + + /* + * There are four alignment cases (with frequency) + * (Based on measurements taken with a DECstation 5000/200 + * inside a Mach kernel.) + * + * aligned -> aligned (mostly) + * unaligned -> aligned (sometimes) + * aligned,unaligned -> unaligned (almost never) + * + * Note that we could add another case that checks if + * the destination and source are unaligned but the + * copy is alignable. eg if src and dest are both + * on a halfword boundary. + */ + andi t1,DSTREG,(SZREG-1) # get last bits of dest + bne t1,zero,3f # dest unaligned + andi t0,SRCREG,(SZREG-1) # get last bits of src + bne t0,zero,5f + + /* + * Forward aligned->aligned copy, 8 words at a time. + */ +98: + li AT,-(SZREG*8) + and t0,SIZEREG,AT # count truncated to multiples + PTR_ADDU a3,SRCREG,t0 # run fast loop up to this addr + sltu AT,SRCREG,a3 # any work to do? + beq AT,zero,2f + PTR_SUBU SIZEREG,t0 + + /* + * loop body + */ +1: # cp + REG_L t3,(0*SZREG)(SRCREG) + REG_L v1,(1*SZREG)(SRCREG) + REG_L t0,(2*SZREG)(SRCREG) + REG_L t1,(3*SZREG)(SRCREG) + PTR_ADDU SRCREG,SZREG*8 + REG_S t3,(0*SZREG)(DSTREG) + REG_S v1,(1*SZREG)(DSTREG) + REG_S t0,(2*SZREG)(DSTREG) + REG_S t1,(3*SZREG)(DSTREG) + REG_L t1,(-1*SZREG)(SRCREG) + REG_L t0,(-2*SZREG)(SRCREG) + REG_L v1,(-3*SZREG)(SRCREG) + REG_L t3,(-4*SZREG)(SRCREG) + PTR_ADDU DSTREG,SZREG*8 + REG_S t1,(-1*SZREG)(DSTREG) + REG_S t0,(-2*SZREG)(DSTREG) + REG_S v1,(-3*SZREG)(DSTREG) + bne SRCREG,a3,1b + REG_S t3,(-4*SZREG)(DSTREG) + + /* + * Copy a word at a time, no loop unrolling. + */ +2: # wordcopy + andi t2,SIZEREG,(SZREG-1) # get byte count / SZREG + PTR_SUBU t2,SIZEREG,t2 # t2 = words to copy * SZREG + beq t2,zero,3f + PTR_ADDU t0,SRCREG,t2 # stop at t0 + PTR_SUBU SIZEREG,SIZEREG,t2 +1: + REG_L t3,0(SRCREG) + PTR_ADDU SRCREG,SZREG + REG_S t3,0(DSTREG) + bne SRCREG,t0,1b + PTR_ADDU DSTREG,SZREG + +3: # bytecopy + beq SIZEREG,zero,4f # nothing left to do? + nop +1: + lb t3,0(SRCREG) + PTR_ADDU SRCREG,1 + sb t3,0(DSTREG) + PTR_SUBU SIZEREG,1 + bgtz SIZEREG,1b + PTR_ADDU DSTREG,1 + +4: # copydone + j ra + nop + + /* + * Copy from unaligned source to aligned dest. + */ +5: # destaligned + andi t0,SIZEREG,(SZREG-1) # t0 = bytecount mod SZREG + PTR_SUBU a3,SIZEREG,t0 # number of words to transfer + beq a3,zero,3b + nop + move SIZEREG,t0 # this many to do after we are done + PTR_ADDU a3,SRCREG,a3 # stop point + +1: + REG_LHI t3,0(SRCREG) + REG_LLO t3,SZREG-1(SRCREG) + PTR_ADDI SRCREG,SZREG + REG_S t3,0(DSTREG) + bne SRCREG,a3,1b + PTR_ADDI DSTREG,SZREG + + b 3b + nop + +6: # backcopy -- based on above + PTR_ADDU SRCREG,SIZEREG + PTR_ADDU DSTREG,SIZEREG + andi t1,DSTREG,SZREG-1 # get last 3 bits of dest + bne t1,zero,3f + andi t0,SRCREG,SZREG-1 # get last 3 bits of src + bne t0,zero,5f + + /* + * Forward aligned->aligned copy, 8*4 bytes at a time. + */ + li AT,(-8*SZREG) + and t0,SIZEREG,AT # count truncated to multiple of 32 + beq t0,zero,2f # any work to do? + PTR_SUBU SIZEREG,t0 + PTR_SUBU a3,SRCREG,t0 + + /* + * loop body + */ +1: # cp + REG_L t3,(-4*SZREG)(SRCREG) + REG_L v1,(-3*SZREG)(SRCREG) + REG_L t0,(-2*SZREG)(SRCREG) + REG_L t1,(-1*SZREG)(SRCREG) + PTR_SUBU SRCREG,8*SZREG + REG_S t3,(-4*SZREG)(DSTREG) + REG_S v1,(-3*SZREG)(DSTREG) + REG_S t0,(-2*SZREG)(DSTREG) + REG_S t1,(-1*SZREG)(DSTREG) + REG_L t1,(3*SZREG)(SRCREG) + REG_L t0,(2*SZREG)(SRCREG) + REG_L v1,(1*SZREG)(SRCREG) + REG_L t3,(0*SZREG)(SRCREG) + PTR_SUBU DSTREG,8*SZREG + REG_S t1,(3*SZREG)(DSTREG) + REG_S t0,(2*SZREG)(DSTREG) + REG_S v1,(1*SZREG)(DSTREG) + bne SRCREG,a3,1b + REG_S t3,(0*SZREG)(DSTREG) + + /* + * Copy a word at a time, no loop unrolling. + */ +2: # wordcopy + andi t2,SIZEREG,SZREG-1 # get byte count / 4 + PTR_SUBU t2,SIZEREG,t2 # t2 = number of words to copy + beq t2,zero,3f + PTR_SUBU t0,SRCREG,t2 # stop at t0 + PTR_SUBU SIZEREG,SIZEREG,t2 +1: + REG_L t3,-SZREG(SRCREG) + PTR_SUBU SRCREG,SZREG + REG_S t3,-SZREG(DSTREG) + bne SRCREG,t0,1b + PTR_SUBU DSTREG,SZREG + +3: # bytecopy + beq SIZEREG,zero,4f # nothing left to do? + nop +1: + lb t3,-1(SRCREG) + PTR_SUBU SRCREG,1 + sb t3,-1(DSTREG) + PTR_SUBU SIZEREG,1 + bgtz SIZEREG,1b + PTR_SUBU DSTREG,1 + +4: # copydone + j ra + nop + + /* + * Copy from unaligned source to aligned dest. + */ +5: # destaligned + andi t0,SIZEREG,SZREG-1 # t0 = bytecount mod 4 + PTR_SUBU a3,SIZEREG,t0 # number of words to transfer + beq a3,zero,3b + nop + move SIZEREG,t0 # this many to do after we are done + PTR_SUBU a3,SRCREG,a3 # stop point + +1: + REG_LHI t3,-SZREG(SRCREG) + REG_LLO t3,-1(SRCREG) + PTR_SUBU SRCREG,SZREG + REG_S t3,-SZREG(DSTREG) + bne SRCREG,a3,1b + PTR_SUBU DSTREG,SZREG + + b 3b + nop + + .set reorder + .set at + END(FUNCTION) diff --git a/lib/libc/mips/string/bzero.S b/lib/libc/mips/string/bzero.S new file mode 100644 index 0000000..dfc4b4d --- /dev/null +++ b/lib/libc/mips/string/bzero.S @@ -0,0 +1,83 @@ +/* $NetBSD: bzero.S,v 1.10 2009/12/14 02:53:52 matt Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/string/bzero.S 218939 2011-02-22 07:49:51Z jchandra $"); + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 + ASMSTR("from: @(#)bzero.s 8.1 (Berkeley) 6/4/93") +#else + ASMSTR("$NetBSD: bzero.S,v 1.10 2009/12/14 02:53:52 matt Exp $") +#endif +#endif /* LIBC_SCCS and not lint */ + +#define _LOCORE /* XXX not really, just assembly-code source */ +#include + +#ifdef __ABICALLS__ + .abicalls +#endif + +/* bzero(s1, n) */ + +LEAF(bzero) + .set noreorder + blt a1, 3*SZREG, smallclr # small amount to clear? + PTR_SUBU a3, zero, a0 # compute # bytes to word align address + and a3, a3, SZREG-1 + beq a3, zero, 1f # skip if word aligned + PTR_SUBU a1, a1, a3 # subtract from remaining count + REG_SHI zero, 0(a0) # clear 1, 2, or 3 bytes to align + PTR_ADDU a0, a0, a3 +1: + and v0, a1, SZREG-1 # compute number of words left + PTR_SUBU a3, a1, v0 + move a1, v0 + PTR_ADDU a3, a3, a0 # compute ending address +2: + PTR_ADDU a0, a0, SZREG # clear words + bne a0, a3, 2b # unrolling loop doesnt help + REG_S zero, -SZREG(a0) # since we are limited by memory speed +smallclr: + ble a1, zero, 2f + PTR_ADDU a3, a1, a0 # compute ending address +1: + PTR_ADDU a0, a0, 1 # clear bytes + bne a0, a3, 1b + sb zero, -1(a0) +2: + j ra + nop +END(bzero) diff --git a/lib/libc/mips/string/ffs.S b/lib/libc/mips/string/ffs.S new file mode 100644 index 0000000..a5ac398 --- /dev/null +++ b/lib/libc/mips/string/ffs.S @@ -0,0 +1,59 @@ +/* $NetBSD: ffs.S,v 1.2 2009/12/14 00:39:00 matt Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/string/ffs.S 209231 2010-06-16 12:55:14Z jchandra $"); + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)ffs.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: ffs.S,v 1.2 2009/12/14 00:39:00 matt Exp $") +#endif /* LIBC_SCCS and not lint */ + +#ifdef __ABICALLS__ + .abicalls +#endif + +/* bit = ffs(value) */ + +LEAF(ffs) + move v0, zero + beq a0, zero, done +1: + and v1, a0, 1 # bit set? + addu v0, v0, 1 + srl a0, a0, 1 + beq v1, zero, 1b # no, continue +done: + j ra +END(ffs) diff --git a/lib/libc/mips/string/memcpy.S b/lib/libc/mips/string/memcpy.S new file mode 100644 index 0000000..a230023 --- /dev/null +++ b/lib/libc/mips/string/memcpy.S @@ -0,0 +1,7 @@ +/* $NetBSD: memcpy.S,v 1.1 2005/12/20 19:28:50 christos Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/string/memcpy.S 178580 2008-04-26 12:08:02Z imp $"); + +#define MEMCOPY +#include "bcopy.S" diff --git a/lib/libc/mips/string/memmove.S b/lib/libc/mips/string/memmove.S new file mode 100644 index 0000000..13eafba --- /dev/null +++ b/lib/libc/mips/string/memmove.S @@ -0,0 +1,7 @@ +/* $NetBSD: memmove.S,v 1.1 2005/12/20 19:28:50 christos Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/string/memmove.S 178580 2008-04-26 12:08:02Z imp $"); + +#define MEMMOVE +#include "bcopy.S" diff --git a/lib/libc/mips/string/strchr.S b/lib/libc/mips/string/strchr.S new file mode 100644 index 0000000..e13545b --- /dev/null +++ b/lib/libc/mips/string/strchr.S @@ -0,0 +1,61 @@ +/* $NetBSD: index.S,v 1.8 2005/04/22 06:59:00 simonb Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/string/strchr.S 229571 2012-01-05 10:32:53Z ed $"); + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)index.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: index.S,v 1.8 2005/04/22 06:59:00 simonb Exp $") +#endif /* LIBC_SCCS and not lint */ + +#ifdef __ABICALLS__ + .abicalls +#endif + +LEAF(strchr) +1: + lbu a2, 0(a0) # get a byte + PTR_ADDU a0, a0, 1 + beq a2, a1, fnd + bne a2, zero, 1b +notfnd: + move v0, zero + j ra +fnd: + PTR_SUBU v0, a0, 1 + j ra +END(strchr) + +WEAK_ALIAS(index, strchr) diff --git a/lib/libc/mips/string/strcmp.S b/lib/libc/mips/string/strcmp.S new file mode 100644 index 0000000..c38d999 --- /dev/null +++ b/lib/libc/mips/string/strcmp.S @@ -0,0 +1,68 @@ +/* $NetBSD: strcmp.S,v 1.2 2009/12/14 00:39:00 matt Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/string/strcmp.S 209231 2010-06-16 12:55:14Z jchandra $"); + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)strcmp.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: strcmp.S,v 1.2 2009/12/14 00:39:00 matt Exp $") +#endif /* LIBC_SCCS and not lint */ + +#ifdef __ABICALLS__ + .abicalls +#endif + +/* + * NOTE: this version assumes unsigned chars in order to be "8 bit clean". + */ +LEAF(strcmp) +1: + lbu t0, 0(a0) # get two bytes and compare them + lbu t1, 0(a1) + beq t0, zero, LessOrEq # end of first string? + bne t0, t1, NotEq + lbu t0, 1(a0) # unroll loop + lbu t1, 1(a1) + PTR_ADD a0, a0, 2 + beq t0, zero, LessOrEq # end of first string? + PTR_ADD a1, a1, 2 + beq t0, t1, 1b +NotEq: + subu v0, t0, t1 + j ra +LessOrEq: + subu v0, zero, t1 + j ra +END(strcmp) diff --git a/lib/libc/mips/string/strlen.S b/lib/libc/mips/string/strlen.S new file mode 100644 index 0000000..e3f684c --- /dev/null +++ b/lib/libc/mips/string/strlen.S @@ -0,0 +1,55 @@ +/* $NetBSD: strlen.S,v 1.2 2009/12/14 00:39:00 matt Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/string/strlen.S 209231 2010-06-16 12:55:14Z jchandra $"); + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)strlen.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: strlen.S,v 1.2 2009/12/14 00:39:00 matt Exp $") +#endif /* LIBC_SCCS and not lint */ + +#ifdef __ABICALLS__ + .abicalls +#endif + +LEAF(strlen) + PTR_ADDU v1, a0, 1 +1: + lb v0, 0(a0) # get byte from string + PTR_ADDU a0, a0, 1 # increment pointer + bne v0, zero, 1b # continue if not end + PTR_SUBU v0, a0, v1 # compute length - 1 for '\0' char + j ra +END(strlen) diff --git a/lib/libc/mips/string/strrchr.S b/lib/libc/mips/string/strrchr.S new file mode 100644 index 0000000..ed1ef69 --- /dev/null +++ b/lib/libc/mips/string/strrchr.S @@ -0,0 +1,59 @@ +/* $NetBSD: rindex.S,v 1.7 2003/08/07 16:42:16 agc Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/string/strrchr.S 229571 2012-01-05 10:32:53Z ed $"); + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)rindex.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: rindex.S,v 1.7 2003/08/07 16:42:16 agc Exp $") +#endif /* LIBC_SCCS and not lint */ + +#ifdef __ABICALLS__ + .abicalls +#endif + +LEAF(strrchr) + move v0, zero # default if not found +1: + lbu a3, 0(a0) # get a byte + PTR_ADDU a0, a0, 1 + bne a3, a1, 2f + PTR_SUBU v0, a0, 1 # save address of last match +2: + bne a3, zero, 1b # continue if not end + j ra +END(strrchr) + +WEAK_ALIAS(rindex, strrchr) diff --git a/lib/libc/mips/sys/Makefile.inc b/lib/libc/mips/sys/Makefile.inc new file mode 100644 index 0000000..ffe2d99 --- /dev/null +++ b/lib/libc/mips/sys/Makefile.inc @@ -0,0 +1,11 @@ +# $FreeBSD: releng/11.1/lib/libc/mips/sys/Makefile.inc 305329 2016-09-03 09:03:40Z kib $ + +SRCS+= trivial-vdso_tc.c + +MDASM= Ovfork.S brk.S cerror.S exect.S \ + sbrk.S syscall.S + +# Don't generate default code for these syscalls: +NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o vfork.o yield.o + +PSEUDO= _exit.o _getlogin.o diff --git a/lib/libc/mips/sys/Ovfork.S b/lib/libc/mips/sys/Ovfork.S new file mode 100644 index 0000000..aa5a1c2 --- /dev/null +++ b/lib/libc/mips/sys/Ovfork.S @@ -0,0 +1,64 @@ +/* $NetBSD: compat_Ovfork.S,v 1.1 2005/09/17 11:49:39 tsutsui Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/sys/Ovfork.S 209231 2010-06-16 12:55:14Z jchandra $"); +#include "SYS.h" + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)Ovfork.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: compat_Ovfork.S,v 1.1 2005/09/17 11:49:39 tsutsui Exp $") +#endif /* LIBC_SCCS and not lint */ + +/* + * pid = vfork(); + * + * v1 == 0 in parent process, v1 == 1 in child process. + * v0 == pid of child in parent, v0 == pid of parent in child. + */ + +LEAF(__sys_vfork) + WEAK_ALIAS(vfork, __sys_vfork) + WEAK_ALIAS(_vfork, __sys_vfork) + PIC_PROLOGUE(__sys_vfork) + li v0, SYS_vfork # system call number for vfork + syscall + beq a3, zero, 1f # jump if no errors + PIC_TAILCALL(__cerror) +1: + beq v1, zero, 2f # parent process ? + move v0, zero # return zero in child +2: + PIC_RETURN() +END(__sys_vfork) diff --git a/lib/libc/mips/sys/brk.S b/lib/libc/mips/sys/brk.S new file mode 100644 index 0000000..d97a21d --- /dev/null +++ b/lib/libc/mips/sys/brk.S @@ -0,0 +1,71 @@ +/* $NetBSD: brk.S,v 1.16 2003/08/07 16:42:17 agc Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/sys/brk.S 209521 2010-06-25 05:36:36Z jchandra $"); +#include "SYS.h" + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)brk.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: brk.S,v 1.16 2003/08/07 16:42:17 agc Exp $") +#endif /* LIBC_SCCS and not lint */ + + .globl _C_LABEL(minbrk) + .globl _C_LABEL(__curbrk) + .globl _C_LABEL(_end) + + .data +_C_LABEL(minbrk): + PTR_WORD _C_LABEL(_end) + + .text +LEAF(__sys_brk) + WEAK_ALIAS(brk, __sys_brk) + WEAK_ALIAS(_brk, __sys_brk) + PIC_PROLOGUE(__sys_brk) + PTR_LA v0, _C_LABEL(minbrk) + PTR_L v0, 0(v0) + bgeu a0, v0, 1f + move a0, v0 # dont allow break < minbrk +1: + li v0, SYS_break + syscall + bne a3, zero, 2f + PTR_LA t0, _C_LABEL(__curbrk) + PTR_S a0, 0(t0) + move v0, zero + PIC_RETURN() +2: + PIC_TAILCALL(__cerror) +END(__sys_brk) diff --git a/lib/libc/mips/sys/cerror.S b/lib/libc/mips/sys/cerror.S new file mode 100644 index 0000000..a30e60a --- /dev/null +++ b/lib/libc/mips/sys/cerror.S @@ -0,0 +1,72 @@ +/* $NetBSD: cerror.S,v 1.14 2009/12/14 01:07:42 matt Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/sys/cerror.S 209231 2010-06-16 12:55:14Z jchandra $"); +#include "SYS.h" + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 + RCSID("from: @(#)cerror.s 8.1 (Berkeley) 6/16/93") +#else + RCSID("$NetBSD: cerror.S,v 1.14 2009/12/14 01:07:42 matt Exp $") +#endif +#endif /* LIBC_SCCS and not lint */ + + .globl _C_LABEL(__error) +NESTED_NOPROFILE(__cerror, CALLFRAME_SIZ, ra) + .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) + SETUP_GP + PTR_SUBU sp, sp, CALLFRAME_SIZ + SETUP_GP64(CALLFRAME_GP, __cerror) + SAVE_GP(CALLFRAME_GP) + + PTR_S ra, CALLFRAME_RA(sp) + REG_S v0, CALLFRAME_S0(sp) # save errno value + + PTR_LA t9, _C_LABEL(__error) # locate address of errno + jalr t9 + + REG_L t0, CALLFRAME_S0(sp) + PTR_L ra, CALLFRAME_RA(sp) + INT_S t0, 0(v0) # update errno value + + RESTORE_GP64 + PTR_ADDU sp, sp, CALLFRAME_SIZ + + li v0, -1 + li v1, -1 + + j ra +END(__cerror) diff --git a/lib/libc/mips/sys/exect.S b/lib/libc/mips/sys/exect.S new file mode 100644 index 0000000..a9aec43 --- /dev/null +++ b/lib/libc/mips/sys/exect.S @@ -0,0 +1,51 @@ +/* $NetBSD: exect.S,v 1.9 2003/08/07 16:42:17 agc Exp $ */ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/sys/exect.S 209231 2010-06-16 12:55:14Z jchandra $"); +#include "SYS.h" + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)exect.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: exect.S,v 1.9 2003/08/07 16:42:17 agc Exp $") +#endif /* LIBC_SCCS and not lint */ + +LEAF(exect) + PIC_PROLOGUE(exect) + li v0, SYS_execve + syscall + bne a3, zero, 1f + PIC_RETURN() +1: + PIC_TAILCALL(__cerror) +END(exect) diff --git a/lib/libc/mips/sys/sbrk.S b/lib/libc/mips/sys/sbrk.S new file mode 100644 index 0000000..9116417 --- /dev/null +++ b/lib/libc/mips/sys/sbrk.S @@ -0,0 +1,73 @@ +/* $NetBSD: sbrk.S,v 1.16 2005/04/22 06:58:01 simonb Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/sys/sbrk.S 209521 2010-06-25 05:36:36Z jchandra $"); +#include "SYS.h" + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)sbrk.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: sbrk.S,v 1.16 2005/04/22 06:58:01 simonb Exp $") +#endif /* LIBC_SCCS and not lint */ + + .globl _C_LABEL(__curbrk) + .globl _C_LABEL(_end) + + .data +_C_LABEL(__curbrk): + PTR_WORD _C_LABEL(_end) + .text + +LEAF(__sys_sbrk) + WEAK_ALIAS(sbrk, __sys_sbrk) + WEAK_ALIAS(_sbrk, __sys_sbrk) + PIC_PROLOGUE(__sys_sbrk) + PTR_LA t0, _C_LABEL(__curbrk) + PTR_L t0, 0(t0) + PTR_ADDU a0, a0, t0 + + li v0, SYS_break + syscall + + bne a3, zero, 1f + nop + move v0, t0 # return old val of curbrk from above + PTR_LA t0, _C_LABEL(__curbrk) + PTR_S a0, 0(t0) # save current val of curbrk from above + PIC_RETURN() + j ra + +1: + PIC_TAILCALL(__cerror) +END(__sys_sbrk) diff --git a/lib/libc/mips/sys/shmat.S b/lib/libc/mips/sys/shmat.S new file mode 100644 index 0000000..02b23a8 --- /dev/null +++ b/lib/libc/mips/sys/shmat.S @@ -0,0 +1,7 @@ +/* $NetBSD: shmat.S,v 1.1 2000/07/07 08:20:52 itohy Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/sys/shmat.S 178580 2008-04-26 12:08:02Z imp $"); +#include "SYS.h" + +RSYSCALL(shmat) diff --git a/lib/libc/mips/sys/syscall.S b/lib/libc/mips/sys/syscall.S new file mode 100644 index 0000000..deec0a6 --- /dev/null +++ b/lib/libc/mips/sys/syscall.S @@ -0,0 +1,44 @@ +/* $NetBSD: syscall.S,v 1.5 2003/08/07 16:42:18 agc Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell. + * + * 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/mips/sys/syscall.S 178580 2008-04-26 12:08:02Z imp $"); +#include "SYS.h" + +#if defined(LIBC_SCCS) && !defined(lint) + ASMSTR("from: @(#)syscall.s 8.1 (Berkeley) 6/4/93") + ASMSTR("$NetBSD: syscall.S,v 1.5 2003/08/07 16:42:18 agc Exp $") +#endif /* LIBC_SCCS and not lint */ + +RSYSCALL(syscall) diff --git a/lib/libc/nameser/Makefile.inc b/lib/libc/nameser/Makefile.inc new file mode 100644 index 0000000..900bf15 --- /dev/null +++ b/lib/libc/nameser/Makefile.inc @@ -0,0 +1,8 @@ +# $FreeBSD: releng/11.1/lib/libc/nameser/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +# nameser sources +.PATH: ${LIBC_SRCTOP}/nameser + +SRCS+= ns_name.c ns_netint.c ns_parse.c ns_print.c ns_samedomain.c ns_ttl.c + +SYM_MAPS+= ${LIBC_SRCTOP}/nameser/Symbol.map diff --git a/lib/libc/nameser/Symbol.map b/lib/libc/nameser/Symbol.map new file mode 100644 index 0000000..49b8ace --- /dev/null +++ b/lib/libc/nameser/Symbol.map @@ -0,0 +1,52 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/nameser/Symbol.map 269867 2014-08-12 12:36:06Z ume $ + */ + +FBSD_1.0 { + __ns_makecanon; + __ns_msg_getflag; + __ns_name_ntol; + __ns_name_ntop; + __ns_name_pton; + __ns_name_unpack; + __ns_name_pack; + __ns_name_uncompress; + __ns_name_compress; + __ns_name_rollback; + __ns_name_skip; + __ns_get16; + __ns_get32; + __ns_put16; + __ns_put32; + __ns_initparse; + __ns_parserr; + _ns_flagdata; + __ns_samedomain; + __ns_samename; + __ns_skiprr; + __ns_sprintrr; + __ns_sprintrrf; + __ns_format_ttl; + __ns_parse_ttl; +}; + +FBSD_1.4 { + __ns_parserr2; + __ns_name_pton2; + __ns_name_unpack2; + __ns_name_length; + __ns_name_eq; + __ns_name_owned; + __ns_name_map; + __ns_name_labels; + __ns_newmsg_init; + __ns_newmsg_copy; + __ns_newmsg_id; + __ns_newmsg_flag; + __ns_newmsg_q; + __ns_newmsg_rr; + __ns_newmsg_done; + __ns_rdata_unpack; + __ns_rdata_equal; + __ns_rdata_refers; +}; diff --git a/lib/libc/net/Makefile.inc b/lib/libc/net/Makefile.inc new file mode 100644 index 0000000..bb75acb --- /dev/null +++ b/lib/libc/net/Makefile.inc @@ -0,0 +1,125 @@ +# from @(#)Makefile.inc 8.2 (Berkeley) 9/5/93 +# $FreeBSD: releng/11.1/lib/libc/net/Makefile.inc 297283 2016-03-26 03:46:12Z bdrewery $ + +# machine-independent net sources +.PATH: ${LIBC_SRCTOP}/net + +SRCS+= base64.c ether_addr.c eui64.c \ + gai_strerror.c getaddrinfo.c \ + gethostbydns.c gethostbyht.c gethostbynis.c gethostnamadr.c \ + getifaddrs.c getifmaddrs.c getnameinfo.c \ + getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \ + getproto.c getprotoent.c getprotoname.c getservent.c \ + if_indextoname.c if_nameindex.c if_nametoindex.c \ + ip6opt.c linkaddr.c map_v4v6.c name6.c ntoh.c \ + nsdispatch.c nslexer.l nsparser.y nss_compat.c \ + rcmd.c rcmdsh.c recv.c rthdr.c sctp_sys_calls.c send.c \ + sockatmark.c sourcefilter.c vars.c + +.if ${MK_NS_CACHING} != "no" +SRCS+= nscache.c nscachedcli.c +.endif + +SYM_MAPS+=${LIBC_SRCTOP}/net/Symbol.map + +.if ${MK_INET6_SUPPORT} != "no" +CFLAGS+=-DINET6 +.endif + +CFLAGS+=-I${.OBJDIR} + +# name6.c refers res_private.h +CFLAGS+=-I${LIBC_SRCTOP}/resolv + +YFLAGS+=-p_nsyy +LFLAGS+=-P_nsyy + +CFLAGS.nslexer.c= -DYY_BUF_SIZE=1024 + +MAN+= byteorder.3 ethers.3 eui64.3 \ + getaddrinfo.3 gai_strerror.3 gethostbyname.3 \ + getifaddrs.3 getifmaddrs.3 getipnodebyname.3 \ + getnameinfo.3 getnetent.3 getprotoent.3 getservent.3 \ + if_indextoname.3 \ + inet.3 inet_net.3 \ + inet6_opt_init.3 inet6_option_space.3 inet6_rth_space.3 \ + inet6_rthdr_space.3 linkaddr.3 \ + nsdispatch.3 rcmd.3 rcmdsh.3 resolver.3 sockatmark.3 \ + sourcefilter.3 \ + sctp_bindx.3 sctp_connectx.3 sctp_freepaddrs.3 \ + sctp_getaddrlen.3 sctp_getassocid.3 sctp_getpaddrs.3 \ + sctp_opt_info.3 sctp_recvmsg.3 sctp_send.3 sctp_sendmsg.3 \ + +MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \ + byteorder.3 ntohs.3 +MLINKS+=ethers.3 ether_aton.3 ethers.3 ether_hostton.3 ethers.3 ether_line.3 \ + ethers.3 ether_ntoa.3 ethers.3 ether_ntohost.3 +MLINKS+=eui64.3 eui64_aton.3 eui64.3 eui64_hostton.3 \ + eui64.3 eui64_ntoa.3 eui64.3 eui64_ntohost.3 +MLINKS+=getaddrinfo.3 freeaddrinfo.3 +MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ + gethostbyname.3 gethostbyname2.3 gethostbyname.3 gethostent.3 \ + gethostbyname.3 herror.3 gethostbyname.3 hstrerror.3 \ + gethostbyname.3 sethostent.3 +MLINKS+=getifaddrs.3 freeifaddrs.3 +MLINKS+=getifmaddrs.3 freeifmaddrs.3 +MLINKS+=getipnodebyname.3 getipnodebyaddr.3 getipnodebyname.3 freehostent.3 +MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ + getnetent.3 getnetbyname.3 getnetent.3 setnetent.3 +MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \ + getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3 +MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \ + getservent.3 getservbyport.3 getservent.3 setservent.3 +MLINKS+=if_indextoname.3 if_nametoindex.3 if_indextoname.3 if_nameindex.3 \ + if_indextoname.3 if_freenameindex.3 +MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_aton.3 \ + inet.3 inet_lnaof.3 inet.3 inet_makeaddr.3 inet.3 inet_netof.3 \ + inet.3 inet_network.3 inet.3 inet_ntoa.3 inet.3 inet_ntoa_r.3\ + inet.3 inet_ntop.3 inet.3 inet_pton.3 \ + inet.3 network.3 inet.3 ntoa.3 +MLINKS+= sctp_send.3 sctp_sendx.3 +MLINKS+= sctp_sendmsg.3 sctp_sendmsgx.3 +MLINKS+= sctp_freepaddrs.3 sctp_freeladdrs.3 +MLINKS+= sctp_getpaddrs.3 sctp_getladdrs.3 +MLINKS+=inet_net.3 inet_net_ntop.3 inet_net.3 inet_net_pton.3 +MLINKS+=inet6_opt_init.3 inet6_opt_append.3 \ + inet6_opt_init.3 inet6_opt_find.3 \ + inet6_opt_init.3 inet6_opt_finish.3 \ + inet6_opt_init.3 inet6_opt_get_val.3 \ + inet6_opt_init.3 inet6_opt_next.3 \ + inet6_opt_init.3 inet6_opt_set_val.3 \ + inet6_option_space.3 inet6_option_alloc.3 \ + inet6_option_space.3 inet6_option_append.3 \ + inet6_option_space.3 inet6_option_find.3 \ + inet6_option_space.3 inet6_option_init.3 \ + inet6_option_space.3 inet6_option_next.3 \ + inet6_rth_space.3 inet6_rth_add.3 \ + inet6_rth_space.3 inet6_rth_getaddr.3 \ + inet6_rth_space.3 inet6_rth_init.3 \ + inet6_rth_space.3 inet6_rth_reverse.3 \ + inet6_rth_space.3 inet6_rth_segments.3 \ + inet6_rthdr_space.3 inet6_rthdr_add.3 \ + inet6_rthdr_space.3 inet6_rthdr_getaddr.3 \ + inet6_rthdr_space.3 inet6_rthdr_getflags.3 \ + inet6_rthdr_space.3 inet6_rthdr_init.3 \ + inet6_rthdr_space.3 inet6_rthdr_lasthop.3 \ + inet6_rthdr_space.3 inet6_rthdr_reverse.3 \ + inet6_rthdr_space.3 inet6_rthdr_segments.3 +MLINKS+=linkaddr.3 link_addr.3 linkaddr.3 link_ntoa.3 +MLINKS+=rcmd.3 iruserok.3 rcmd.3 iruserok_sa.3 \ + rcmd.3 rcmd_af.3 \ + rcmd.3 rresvport.3 rcmd.3 rresvport_af.3 \ + rcmd.3 ruserok.3 +MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \ + resolver.3 res_mkquery.3 resolver.3 res_query.3 \ + resolver.3 res_search.3 resolver.3 res_send.3 resolver.3 dn_skipname.3 \ + resolver.3 ns_get16.3 resolver.3 ns_get32.3 \ + resolver.3 ns_put16.3 resolver.3 ns_put32.3 +MLINKS+=sourcefilter.3 setipv4sourcefilter.3 sourcefilter.3 getipv4sourcefilter.3 \ + sourcefilter.3 setsourcefilter.3 sourcefilter.3 getsourcefilter.3 + +.if ${MK_HESIOD} != "no" +SRCS+= hesiod.c +MAN+= hesiod.3 +.endif + diff --git a/lib/libc/net/Symbol.map b/lib/libc/net/Symbol.map new file mode 100644 index 0000000..3d23c47 --- /dev/null +++ b/lib/libc/net/Symbol.map @@ -0,0 +1,174 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/net/Symbol.map 280782 2015-03-28 09:08:57Z tuexen $ + */ + +FBSD_1.0 { + __b64_ntop; + __b64_pton; + ether_line; + ether_aton; + ether_aton_r; + ether_ntoa; + ether_ntoa_r; + ether_ntohost; + ether_hostton; + eui64_aton; + eui64_ntoa; + eui64_ntohost; + eui64_hostton; + gai_strerror; + freeaddrinfo; + getaddrinfo; + gethostent; + gethostent_r; + gethostbyname; + gethostbyname_r; + gethostbyname2; + gethostbyname2_r; + gethostbyaddr; + gethostbyaddr_r; + sethostent; + endhostent; + getifaddrs; + freeifaddrs; + getifmaddrs; + freeifmaddrs; + getnameinfo; + getnetent; + getnetent_r; + getnetbyname; + getnetbyname_r; + getnetbyaddr; + getnetbyaddr_r; + setnetent; + endnetent; + getprotobynumber; + getprotobynumber_r; + setprotoent; + endprotoent; + getprotoent; + getprotoent_r; + getprotobyname; + getprotobyname_r; + getservbyname; + getservbyname_r; + getservbyport; + getservbyport_r; + setservent; + endservent; + getservent; + getservent_r; + hesiod_init; + hesiod_end; + hesiod_to_bind; + hesiod_resolve; + hesiod_free_list; + hes_init; + hes_to_bind; + hes_resolve; + hes_error; + hes_free; + if_indextoname; + if_nameindex; + if_freenameindex; + if_nametoindex; + inet6_option_space; + inet6_option_init; + inet6_option_append; + inet6_option_alloc; + inet6_option_next; + inet6_option_find; + inet6_opt_init; + inet6_opt_append; + inet6_opt_finish; + inet6_opt_set_val; + inet6_opt_next; + inet6_opt_find; + inet6_opt_get_val; + link_addr; + link_ntoa; + getipnodebyname; + getipnodebyaddr; + freehostent; + __nsdefaultsrc; + _nsdbtaddsrc; + _nsdbtdump; + _nsdbtput; + nsdispatch; + rcmd; + rcmd_af; + rresvport; + rresvport_af; + ruserok; + iruserok; + iruserok_sa; + rcmdsh; + recv; + inet6_rthdr_space; + inet6_rthdr_init; + inet6_rthdr_add; + inet6_rthdr_lasthop; + inet6_rthdr_segments; + inet6_rthdr_getaddr; + inet6_rthdr_getflags; + inet6_rth_space; + inet6_rth_init; + inet6_rth_add; + inet6_rth_reverse; + inet6_rth_segments; + inet6_rth_getaddr; + send; + sockatmark; + in6addr_any; + in6addr_loopback; + in6addr_nodelocal_allnodes; + in6addr_linklocal_allnodes; + sctp_getaddrlen; + sctp_getassocid; + sctp_bindx; + sctp_connectx; + sctp_peeloff; + sctp_opt_info; + sctp_getpaddrs; + sctp_freepaddrs; + sctp_getladdrs; + sctp_freeladdrs; + sctp_sendmsg; + sctp_sendmsgx; + sctp_send; + sctp_sendx; + sctp_recvmsg; + setipv4sourcefilter; + getipv4sourcefilter; + getsourcefilter; + setsourcefilter; +}; + +FBSD_1.3 { + sctp_recvv; + sctp_sendv; +}; + +FBSDprivate_1.0 { + _nsdispatch; + _nsyyerror; /* generated from nslexer.l */ + _nsyylex; /* generated from nslexer.l */ + _nsyyparse; /* generated from nsparser.y */ + _nsyylineno; /* generated from nsparser.y */ + __dns_getanswer; + __ivaliduser; + __ivaliduser_af; + __ivaliduser_sa; + __check_rhosts_file; + __rcmd_errstr; + __nss_compat_getgrnam_r; + __nss_compat_getgrgid_r; + __nss_compat_getgrent_r; + __nss_compat_setgrent; + __nss_compat_endgrent; + __nss_compat_getpwnam_r; + __nss_compat_getpwuid_r; + __nss_compat_getpwent_r; + __nss_compat_setpwent; + __nss_compat_endpwent; +}; diff --git a/lib/libc/net/byteorder.3 b/lib/libc/net/byteorder.3 new file mode 100644 index 0000000..fa174bc --- /dev/null +++ b/lib/libc/net/byteorder.3 @@ -0,0 +1,86 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)byteorder.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/net/byteorder.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd March 20, 2005 +.Dt BYTEORDER 3 +.Os +.Sh NAME +.Nm htonl , +.Nm htons , +.Nm ntohl , +.Nm ntohs +.Nd convert values between host and network byte order +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In arpa/inet.h +.Pp +or +.Pp +.In netinet/in.h +.Ft uint32_t +.Fn htonl "uint32_t hostlong" +.Ft uint16_t +.Fn htons "uint16_t hostshort" +.Ft uint32_t +.Fn ntohl "uint32_t netlong" +.Ft uint16_t +.Fn ntohs "uint16_t netshort" +.Sh DESCRIPTION +These routines convert 16 and 32 bit quantities between network +byte order and host byte order. +On machines which have a byte order which is the same as the network +order, routines are defined as null macros. +.Pp +These routines are most often used in conjunction with Internet +addresses and ports as returned by +.Xr gethostbyname 3 +and +.Xr getservent 3 . +.Sh SEE ALSO +.Xr gethostbyname 3 , +.Xr getservent 3 , +.Xr byteorder 9 +.Sh STANDARDS +The +.Nm byteorder +functions conform to +.St -p1003.1-2001 . +.Sh HISTORY +The +.Nm byteorder +functions appeared in +.Bx 4.2 . +.Sh BUGS +On the +.Tn VAX +bytes are handled backwards from most everyone else in +the world. +This is not expected to be fixed in the near future. diff --git a/lib/libc/net/ethers.3 b/lib/libc/net/ethers.3 new file mode 100644 index 0000000..8687a92 --- /dev/null +++ b/lib/libc/net/ethers.3 @@ -0,0 +1,233 @@ +.\" Copyright (c) 1995 Bill Paul . +.\" Copyright (c) 2007 Robert N. M. Watson +.\" 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 Bill Paul. +.\" 4. Neither the name of the author nor the names of any co-contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY Bill Paul 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/ethers.3 224701 2011-08-08 03:09:03Z hrs $ +.\" +.Dd October 30, 2007 +.Dt ETHERS 3 +.Os +.Sh NAME +.Nm ethers , +.Nm ether_line , +.Nm ether_aton , +.Nm ether_aton_r , +.Nm ether_ntoa , +.Nm ether_ntoa_r , +.Nm ether_ntohost , +.Nm ether_hostton +.Nd Ethernet address conversion and lookup routines +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In net/ethernet.h +.Ft int +.Fn ether_line "const char *l" "struct ether_addr *e" "char *hostname" +.Ft struct ether_addr * +.Fn ether_aton "const char *a" +.Ft struct ether_addr * +.Fn ether_aton_r "const char *a" "struct ether_addr *e" +.Ft char * +.Fn ether_ntoa "const struct ether_addr *n" +.Ft char * +.Fn ether_ntoa_r "const struct ether_addr *n" "char *buf" +.Ft int +.Fn ether_ntohost "char *hostname" "const struct ether_addr *e" +.Ft int +.Fn ether_hostton "const char *hostname" "struct ether_addr *e" +.Sh DESCRIPTION +These functions operate on ethernet addresses using an +.Vt ether_addr +structure, which is defined in the header file +.In net/ethernet.h : +.Bd -literal -offset indent +/* + * The number of bytes in an ethernet (MAC) address. + */ +#define ETHER_ADDR_LEN 6 + +/* + * Structure of a 48-bit Ethernet address. + */ +struct ether_addr { + u_char octet[ETHER_ADDR_LEN]; +}; +.Ed +.Pp +The function +.Fn ether_line +scans +.Fa l , +an +.Tn ASCII +string in +.Xr ethers 5 +format and sets +.Fa e +to the ethernet address specified in the string and +.Fa h +to the hostname. +This function is used to parse lines from +.Pa /etc/ethers +into their component parts. +.Pp +The +.Fn ether_aton +and +.Fn ether_aton_r +functions convert +.Tn ASCII +representation of ethernet addresses into +.Vt ether_addr +structures. +Likewise, the +.Fn ether_ntoa +and +.Fn ether_ntoa_r +functions +convert ethernet addresses specified as +.Vt ether_addr +structures into +.Tn ASCII +strings. +.Pp +The +.Fn ether_ntohost +and +.Fn ether_hostton +functions map ethernet addresses to their corresponding hostnames +as specified in the +.Pa /etc/ethers +database. +The +.Fn ether_ntohost +function +converts from ethernet address to hostname, and +.Fn ether_hostton +converts from hostname to ethernet address. +.Sh RETURN VALUES +The +.Fn ether_line +function +returns zero on success and non-zero if it was unable to parse +any part of the supplied line +.Fa l . +It returns the extracted ethernet address in the supplied +.Vt ether_addr +structure +.Fa e +and the hostname in the supplied string +.Fa h . +.Pp +On success, +.Fn ether_ntoa +and +.Fn ether_ntoa_r +functions return a pointer to a string containing an +.Tn ASCII +representation of an ethernet address. +If it is unable to convert +the supplied +.Vt ether_addr +structure, it returns a +.Dv NULL +pointer. +.Fn ether_ntoa +stores the result in a static buffer; +.Fn ether_ntoa_r +stores the result in a user-passed buffer. +.Pp +Likewise, +.Fn ether_aton +and +.Fn ether_aton_r +return a pointer to an +.Vt ether_addr +structure on success and a +.Dv NULL +pointer on failure. +.Fn ether_aton +stores the result in a static buffer; +.Fn ether_aton_r +stores the result in a user-passed buffer. +.Pp +The +.Fn ether_ntohost +and +.Fn ether_hostton +functions both return zero on success or non-zero if they were +unable to find a match in the +.Pa /etc/ethers +database. +.Sh NOTES +The user must ensure that the hostname strings passed to the +.Fn ether_line , +.Fn ether_ntohost +and +.Fn ether_hostton +functions are large enough to contain the returned hostnames. +.Sh NIS INTERACTION +If the +.Pa /etc/ethers +contains a line with a single + in it, the +.Fn ether_ntohost +and +.Fn ether_hostton +functions will attempt to consult the NIS +.Pa ethers.byname +and +.Pa ethers.byaddr +maps in addition to the data in the +.Pa /etc/ethers +file. +.Sh SEE ALSO +.Xr ethers 5 , +.Xr yp 8 +.Sh HISTORY +This particular implementation of the +.Nm +library functions were written for and first appeared in +.Fx 2.1 . +Thread-safe function variants first appeared in +.Fx 7.0 . +.Sh BUGS +The +.Fn ether_aton +and +.Fn ether_ntoa +functions returns values that are stored in static memory areas +which may be overwritten the next time they are called. +.Pp +.Fn ether_ntoa_r +accepts a character buffer pointer, but not a buffer length. +The caller must ensure adequate space is available in the buffer in order to +avoid a buffer overflow. diff --git a/lib/libc/net/eui64.3 b/lib/libc/net/eui64.3 new file mode 100644 index 0000000..1a24ab7 --- /dev/null +++ b/lib/libc/net/eui64.3 @@ -0,0 +1,223 @@ +.\" Copyright 2004 The Aerospace Corporation. 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. The name of The Aerospace Corporation may not be used to endorse or +.\" promote products derived from this software. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "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 AEROSPACE CORPORATION 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. +.\" +.\" Copyright (c) 1995 +.\" Bill Paul . 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 Bill Paul. +.\" 4. Neither the name of the author nor the names of any co-contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY Bill Paul 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/eui64.3 231196 2012-02-08 11:30:13Z brooks $ +.\" +.Dd March 4, 2004 +.Dt EUI64 3 +.Os +.Sh NAME +.Nm eui64 , +.\" .Nm eui64_line , +.Nm eui64_aton , +.Nm eui64_ntoa , +.Nm eui64_ntohost , +.Nm eui64_hostton +.Nd IEEE EUI-64 conversion and lookup routines +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/eui64.h +.\" .Ft int +.\" .Fn eui64_line "const char *l" "struct eui64 *e" "char *hostname" "size_t len" +.Ft int +.Fn eui64_aton "const char *a" "struct eui64 *e" +.Ft int +.Fn eui64_ntoa "const struct eui64 *id" "char *a" "size_t len" +.Ft int +.Fn eui64_ntohost "char *hostname" "size_t len" "const struct eui64 *id" +.Ft int +.Fn eui64_hostton "const char *hostname" "struct eui64 *id" +.Sh DESCRIPTION +These functions operate on IEEE EUI-64s using an +.Vt eui64 +structure, which is defined in the header file +.In sys/eui64.h : +.Bd -literal -offset indent +/* + * The number of bytes in an EUI-64. + */ +#define EUI64_LEN 8 + +/* + * Structure of an IEEE EUI-64. + */ +struct eui64 { + u_char octet[EUI64_LEN]; +}; +.Ed +.\" .Pp +.\" The function +.\" .Fn eui64_line +.\" scans +.\" .Fa l , +.\" an +.\" .Tn ASCII +.\" string in +.\" .Xr eui64 5 +.\" format and sets +.\" .Fa e +.\" to the EUI-64 specified in the string and +.\" .Fa h +.\" to the hostname. +.\" This function is used to parse lines from +.\" .Pa /etc/eui64 +.\" into their component parts. +.Pp +The +.Fn eui64_aton +function converts an +.Tn ASCII +representation of an EUI-64 into an +.Vt eui64 +structure. +Likewise, +.Fn eui64_ntoa +converts an EUI-64 specified as an +.Vt eui64 +structure into an +.Tn ASCII +string. +.Pp +The +.Fn eui64_ntohost +and +.Fn eui64_hostton +functions map EUI-64s to their corresponding hostnames +as specified in the +.Pa /etc/eui64 +database. +The +.Fn eui64_ntohost +function +converts from EUI-64 to hostname, and +.Fn eui64_hostton +converts from hostname to EUI-64. +.Sh RETURN VALUES +.\" The +.\" .Fn eui64_line +.\" function +.\" returns zero on success and non-zero if it was unable to parse +.\" any part of the supplied line +.\" .Fa l . +.\" It returns the extracted EUI-64 in the supplied +.\" .Vt eui64 +.\" structure +.\" .Fa e +.\" and the hostname in the supplied string +.\" .Fa h . +.\" .Pp +On success, +.Fn eui64_ntoa +returns a pointer to a string containing an +.Tn ASCII +representation of an EUI-64. +If it is unable to convert +the supplied +.Vt eui64 +structure, it returns a +.Dv NULL +pointer. +Likewise, +.Fn eui64_aton +returns a pointer to an +.Vt eui64 +structure on success and a +.Dv NULL +pointer on failure. +.Pp +The +.Fn eui64_ntohost +and +.Fn eui64_hostton +functions both return zero on success or non-zero if they were +unable to find a match in the +.Pa /etc/eui64 +database. +.Sh NOTES +The user must ensure that the hostname strings passed to the +.\" .Fn eui64_line , +.Fn eui64_ntohost +and +.Fn eui64_hostton +functions are large enough to contain the returned hostnames. +.Sh NIS INTERACTION +If the +.Pa /etc/eui64 +contains a line with a single +.Ql + +in it, the +.Fn eui64_ntohost +and +.Fn eui64_hostton +functions will attempt to consult the NIS +.Pa eui64.byname +and +.Pa eui64.byid +maps in addition to the data in the +.Pa /etc/eui64 +file. +.Sh SEE ALSO +.Xr firewire 4 , +.Xr eui64 5 , +.Xr yp 8 +.Sh HISTORY +These functions first appears in +.Fx 5.3 . +They are derived from the +.Xr ethers 3 +family of functions. diff --git a/lib/libc/net/gai_strerror.3 b/lib/libc/net/gai_strerror.3 new file mode 100644 index 0000000..00c1f25 --- /dev/null +++ b/lib/libc/net/gai_strerror.3 @@ -0,0 +1,92 @@ +.\" $KAME: gai_strerror.3,v 1.1 2005/01/05 03:04:47 itojun Exp $ +.\" $OpenBSD: gai_strerror.3,v 1.4 2004/12/20 23:04:53 millert Exp $ +.\" +.\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000, 2001 Internet Software Consortium. +.\" +.\" 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 ISC DISCLAIMS ALL WARRANTIES WITH +.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +.\" AND FITNESS. IN NO EVENT SHALL ISC 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/gai_strerror.3 162385 2006-09-17 21:27:35Z ru $ +.\" +.Dd May 21, 2006 +.Dt GAI_STRERROR 3 +.Os +.Sh NAME +.Nm gai_strerror +.Nd get error message string from EAI_xxx error code +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netdb.h +.Ft "const char *" +.Fn gai_strerror "int ecode" +.Sh DESCRIPTION +The +.Fn gai_strerror +function returns an error message string corresponding to the error code +returned by +.Xr getaddrinfo 3 +or +.Xr getnameinfo 3 . +.Pp +The following error codes and their meaning are defined in +.In netdb.h : +.Pp +.Bl -tag -width ".Dv EAI_BADFLAGS" -offset indent -compact +.It Dv EAI_AGAIN +temporary failure in name resolution +.It Dv EAI_BADFLAGS +invalid value for +.Fa ai_flags +.It Dv EAI_BADHINTS +invalid value for +.Fa hints +.It Dv EAI_FAIL +non-recoverable failure in name resolution +.It Dv EAI_FAMILY +.Fa ai_family +not supported +.It Dv EAI_MEMORY +memory allocation failure +.It Dv EAI_NONAME +.Fa hostname +or +.Fa servname +not provided, or not known +.It Dv EAI_OVERFLOW +argument buffer overflow +.It Dv EAI_PROTOCOL +resolved protocol is unknown +.It Dv EAI_SERVICE +.Fa servname +not supported for +.Fa ai_socktype +.It Dv EAI_SOCKTYPE +.Fa ai_socktype +not supported +.It Dv EAI_SYSTEM +system error returned in +.Va errno +.El +.Sh RETURN VALUES +The +.Fn gai_strerror +function +returns a pointer to the error message string corresponding to +.Fa ecode . +If +.Fa ecode +is out of range, an implementation-specific error message string is returned. +.Sh SEE ALSO +.Xr getaddrinfo 3 , +.Xr getnameinfo 3 diff --git a/lib/libc/net/getaddrinfo.3 b/lib/libc/net/getaddrinfo.3 new file mode 100644 index 0000000..c938a3f --- /dev/null +++ b/lib/libc/net/getaddrinfo.3 @@ -0,0 +1,509 @@ +.\" $KAME: getaddrinfo.3,v 1.36 2005/01/05 03:23:05 itojun Exp $ +.\" $OpenBSD: getaddrinfo.3,v 1.35 2004/12/21 03:40:31 jaredy Exp $ +.\" +.\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000, 2001 Internet Software Consortium. +.\" +.\" 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 ISC DISCLAIMS ALL WARRANTIES WITH +.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +.\" AND FITNESS. IN NO EVENT SHALL ISC 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/getaddrinfo.3 292514 2015-12-20 15:18:50Z ume $ +.\" +.Dd December 21, 2015 +.Dt GETADDRINFO 3 +.Os +.Sh NAME +.Nm getaddrinfo , +.Nm freeaddrinfo +.Nd socket address structure to host and service name +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netdb.h +.Ft int +.Fo getaddrinfo +.Fa "const char *hostname" "const char *servname" +.Fa "const struct addrinfo *hints" "struct addrinfo **res" +.Fc +.Ft void +.Fn freeaddrinfo "struct addrinfo *ai" +.Sh DESCRIPTION +The +.Fn getaddrinfo +function is used to get a list of +addresses and port numbers for host +.Fa hostname +and service +.Fa servname . +It is a replacement for and provides more flexibility than the +.Xr gethostbyname 3 +and +.Xr getservbyname 3 +functions. +.Pp +The +.Fa hostname +and +.Fa servname +arguments are either pointers to NUL-terminated strings or the null pointer. +An acceptable value for +.Fa hostname +is either a valid host name or a numeric host address string consisting +of a dotted decimal IPv4 address, +an IPv6 address, +or a UNIX-domain address. +The +.Fa servname +is either a decimal port number or a service name listed in +.Xr services 5 . +At least one of +.Fa hostname +and +.Fa servname +must be non-null. +.Pp +.Fa hints +is an optional pointer to a +.Li struct addrinfo , +as defined by +.Aq Pa netdb.h : +.Bd -literal +struct addrinfo { + int ai_flags; /* input flags */ + int ai_family; /* address family for socket */ + int ai_socktype; /* socket type */ + int ai_protocol; /* protocol for socket */ + socklen_t ai_addrlen; /* length of socket-address */ + struct sockaddr *ai_addr; /* socket-address for socket */ + char *ai_canonname; /* canonical name for service location */ + struct addrinfo *ai_next; /* pointer to next in list */ +}; +.Ed +.Pp +This structure can be used to provide hints concerning the type of socket +that the caller supports or wishes to use. +The caller can supply the following structure elements in +.Fa hints : +.Bl -tag -width "ai_socktypeXX" +.It Fa ai_family +The address family that should be used. +When +.Fa ai_family +is set to +.Dv AF_UNSPEC , +it means the caller will accept any address family supported by the +operating system. +.It Fa ai_socktype +Denotes the type of socket that is wanted: +.Dv SOCK_STREAM , +.Dv SOCK_DGRAM , +.Dv SOCK_SEQPACKET , +or +.Dv SOCK_RAW . +When +.Fa ai_socktype +is zero the caller will accept any socket type. +.It Fa ai_protocol +Indicates which transport protocol is desired, +.Dv IPPROTO_UDP , +.Dv IPPROTO_TCP , +.Dv IPPROTO_SCTP , +or +.Dv IPPROTO_UDPLITE . +If +.Fa ai_protocol +is zero the caller will accept any protocol. +.It Fa ai_flags +The +.Fa ai_flags +field to which the +.Fa hints +parameter points shall be set to zero +or be the bitwise-inclusive OR of one or more of the values +.Dv AI_ADDRCONFIG , +.Dv AI_ALL , +.Dv AI_CANONNAME , +.Dv AI_NUMERICHOST , +.Dv AI_NUMERICSERV , +.Dv AI_PASSIVE +and +.Dv AI_V4MAPPED . +For a UNIX-domain address, +.Fa ai_flags +is ignored. +.Bl -tag -width "AI_CANONNAMEXX" +.It Dv AI_ADDRCONFIG +If the +.Dv AI_ADDRCONFIG +bit is set, IPv4 addresses shall be returned only if +an IPv4 address is configured on the local system, +and IPv6 addresses shall be returned only if +an IPv6 address is configured on the local system. +.It Dv AI_ALL +If the +.Dv AI_ALL +flag is used with the +.Dv AI_V4MAPPED +flag, then +.Fn getaddrinfo +shall return all matching IPv6 and IPv4 addresses. +.Pp +For example, when using the DNS, queries are made for both AAAA records and A records, and +.Fn getaddrinfo +returns the combined results of both queries. +Any IPv4 addresses found are returned as IPv4-mapped IPv6 addresses. +.Pp +The +.Dv AI_ALL +flag without the +.Dv AI_V4MAPPED +flag is ignored. +.It Dv AI_CANONNAME +If the +.Dv AI_CANONNAME +bit is set, a successful call to +.Fn getaddrinfo +will return a NUL-terminated string containing the canonical name +of the specified hostname in the +.Fa ai_canonname +element of the first +.Li addrinfo +structure returned. +.It Dv AI_NUMERICHOST +If the +.Dv AI_NUMERICHOST +bit is set, it indicates that +.Fa hostname +should be treated as a numeric string defining an IPv4 or IPv6 address +and no name resolution should be attempted. +.It Dv AI_NUMERICSERV +If the +.Dv AI_NUMERICSERV +bit is set, +then a non-null +.Fa servname +string supplied shall be a numeric port string. +Otherwise, an +.Dv EAI_NONAME +error shall be returned. +This bit shall prevent any type of name resolution service +(for example, NIS+) from being invoked. +.It Dv AI_PASSIVE +If the +.Dv AI_PASSIVE +bit is set it indicates that the returned socket address structure +is intended for use in a call to +.Xr bind 2 . +In this case, if the +.Fa hostname +argument is the null pointer, then the IP address portion of the +socket address structure will be set to +.Dv INADDR_ANY +for an IPv4 address or +.Dv IN6ADDR_ANY_INIT +for an IPv6 address. +.Pp +If the +.Dv AI_PASSIVE +bit is not set, the returned socket address structure will be ready +for use in a call to +.Xr connect 2 +for a connection-oriented protocol or +.Xr connect 2 , +.Xr sendto 2 , +or +.Xr sendmsg 2 +if a connectionless protocol was chosen. +The +.Tn IP +address portion of the socket address structure will be set to the +loopback address if +.Fa hostname +is the null pointer and +.Dv AI_PASSIVE +is not set. +.It Dv AI_V4MAPPED +If the +.Dv AI_V4MAPPED +flag is specified along with an ai_family of +.Dv AF_INET6 , +then +.Fn getaddrinfo +shall return IPv4-mapped IPv6 addresses on finding no matching IPv6 addresses ( +.Fa ai_addrlen +shall be 16). +.Pp +For example, when using the DNS, if no AAAA records are found then a query is made for A records and any found are returned as IPv4-mapped IPv6 addresses. +.Pp +The +.Dv AI_V4MAPPED +flag shall be ignored unless +.Fa ai_family +equals +.Dv AF_INET6 . +.El +.El +.Pp +All other elements of the +.Li addrinfo +structure passed via +.Fa hints +must be zero or the null pointer. +.Pp +If +.Fa hints +is the null pointer, +.Fn getaddrinfo +behaves as if the caller provided a +.Li struct addrinfo +with +.Fa ai_family +set to +.Dv AF_UNSPEC +and all other elements set to zero or +.Dv NULL . +.Pp +After a successful call to +.Fn getaddrinfo , +.Fa *res +is a pointer to a linked list of one or more +.Li addrinfo +structures. +The list can be traversed by following the +.Fa ai_next +pointer in each +.Li addrinfo +structure until a null pointer is encountered. +Each returned +.Li addrinfo +structure contains three members that are suitable for a call to +.Xr socket 2 : +.Fa ai_family , +.Fa ai_socktype , +and +.Fa ai_protocol . +For each +.Li addrinfo +structure in the list, the +.Fa ai_addr +member points to a filled-in socket address structure of length +.Fa ai_addrlen . +.Pp +This implementation of +.Fn getaddrinfo +allows numeric IPv6 address notation with scope identifier, +as documented in chapter 11 of RFC 4007. +By appending the percent character and scope identifier to addresses, +one can fill the +.Li sin6_scope_id +field for addresses. +This would make management of scoped addresses easier +and allows cut-and-paste input of scoped addresses. +.Pp +At this moment the code supports only link-local addresses with the format. +The scope identifier is hardcoded to the name of the hardware interface +associated +with the link +.Po +such as +.Li ne0 +.Pc . +An example is +.Dq Li fe80::1%ne0 , +which means +.Do +.Li fe80::1 +on the link associated with the +.Li ne0 +interface +.Dc . +.Pp +The current implementation assumes a one-to-one relationship between +the interface and link, which is not necessarily true from the specification. +.Pp +All of the information returned by +.Fn getaddrinfo +is dynamically allocated: the +.Li addrinfo +structures themselves as well as the socket address structures and +the canonical host name strings included in the +.Li addrinfo +structures. +.Pp +Memory allocated for the dynamically allocated structures created by +a successful call to +.Fn getaddrinfo +is released by the +.Fn freeaddrinfo +function. +The +.Fa ai +pointer should be a +.Li addrinfo +structure created by a call to +.Fn getaddrinfo . +.Sh RETURN VALUES +.Fn getaddrinfo +returns zero on success or one of the error codes listed in +.Xr gai_strerror 3 +if an error occurs. +.Sh EXAMPLES +The following code tries to connect to +.Dq Li www.kame.net +service +.Dq Li http +via a stream socket. +It loops through all the addresses available, regardless of address family. +If the destination resolves to an IPv4 address, it will use an +.Dv AF_INET +socket. +Similarly, if it resolves to IPv6, an +.Dv AF_INET6 +socket is used. +Observe that there is no hardcoded reference to a particular address family. +The code works even if +.Fn getaddrinfo +returns addresses that are not IPv4/v6. +.Bd -literal -offset indent +struct addrinfo hints, *res, *res0; +int error; +int s; +const char *cause = NULL; + +memset(&hints, 0, sizeof(hints)); +hints.ai_family = AF_UNSPEC; +hints.ai_socktype = SOCK_STREAM; +error = getaddrinfo("www.kame.net", "http", &hints, &res0); +if (error) { + errx(1, "%s", gai_strerror(error)); + /* NOTREACHED */ +} +s = -1; +for (res = res0; res; res = res->ai_next) { + s = socket(res->ai_family, res->ai_socktype, + res->ai_protocol); + if (s < 0) { + cause = "socket"; + continue; + } + + if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { + cause = "connect"; + close(s); + s = -1; + continue; + } + + break; /* okay we got one */ +} +if (s < 0) { + err(1, "%s", cause); + /* NOTREACHED */ +} +freeaddrinfo(res0); +.Ed +.Pp +The following example tries to open a wildcard listening socket onto service +.Dq Li http , +for all the address families available. +.Bd -literal -offset indent +struct addrinfo hints, *res, *res0; +int error; +int s[MAXSOCK]; +int nsock; +const char *cause = NULL; + +memset(&hints, 0, sizeof(hints)); +hints.ai_family = AF_UNSPEC; +hints.ai_socktype = SOCK_STREAM; +hints.ai_flags = AI_PASSIVE; +error = getaddrinfo(NULL, "http", &hints, &res0); +if (error) { + errx(1, "%s", gai_strerror(error)); + /* NOTREACHED */ +} +nsock = 0; +for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) { + s[nsock] = socket(res->ai_family, res->ai_socktype, + res->ai_protocol); + if (s[nsock] < 0) { + cause = "socket"; + continue; + } + + if (bind(s[nsock], res->ai_addr, res->ai_addrlen) < 0) { + cause = "bind"; + close(s[nsock]); + continue; + } + (void) listen(s[nsock], 5); + + nsock++; +} +if (nsock == 0) { + err(1, "%s", cause); + /* NOTREACHED */ +} +freeaddrinfo(res0); +.Ed +.Sh SEE ALSO +.Xr bind 2 , +.Xr connect 2 , +.Xr send 2 , +.Xr socket 2 , +.Xr gai_strerror 3 , +.Xr gethostbyname 3 , +.Xr getnameinfo 3 , +.Xr getservbyname 3 , +.Xr resolver 3 , +.Xr inet 4 , +.Xr inet6 4 , +.Xr unix 4 , +.Xr hosts 5 , +.Xr resolv.conf 5 , +.Xr services 5 , +.Xr hostname 7 , +.Xr named 8 +.Rs +.%A R. Gilligan +.%A S. Thomson +.%A J. Bound +.%A J. McCann +.%A W. Stevens +.%T Basic Socket Interface Extensions for IPv6 +.%R RFC 3493 +.%D February 2003 +.Re +.Rs +.%A S. Deering +.%A B. Haberman +.%A T. Jinmei +.%A E. Nordmark +.%A B. Zill +.%T "IPv6 Scoped Address Architecture" +.%R RFC 4007 +.%D March 2005 +.Re +.Rs +.%A Craig Metz +.%T Protocol Independence Using the Sockets API +.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference" +.%D June 2000 +.Re +.Sh STANDARDS +The +.Fn getaddrinfo +function is defined by the +.St -p1003.1-2004 +specification and documented in +.Dv "RFC 3493" , +.Dq Basic Socket Interface Extensions for IPv6 . diff --git a/lib/libc/net/gethostbyname.3 b/lib/libc/net/gethostbyname.3 new file mode 100644 index 0000000..16007a0 --- /dev/null +++ b/lib/libc/net/gethostbyname.3 @@ -0,0 +1,375 @@ +.\" Copyright (c) 1983, 1987, 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. +.\" 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. +.\" +.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95 +.\" $FreeBSD: releng/11.1/lib/libc/net/gethostbyname.3 254484 2013-08-18 10:38:59Z pjd $ +.\" +.Dd May 12, 2006 +.Dt GETHOSTBYNAME 3 +.Os +.Sh NAME +.Nm gethostbyname , +.Nm gethostbyname2 , +.Nm gethostbyaddr , +.Nm gethostent , +.Nm sethostent , +.Nm endhostent , +.Nm herror , +.Nm hstrerror +.Nd get network host entry +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In netdb.h +.Vt int h_errno ; +.Ft struct hostent * +.Fn gethostbyname "const char *name" +.Ft struct hostent * +.Fn gethostbyname2 "const char *name" "int af" +.Ft struct hostent * +.Fn gethostbyaddr "const void *addr" "socklen_t len" "int af" +.Ft struct hostent * +.Fn gethostent void +.Ft void +.Fn sethostent "int stayopen" +.Ft void +.Fn endhostent void +.Ft void +.Fn herror "const char *string" +.Ft const char * +.Fn hstrerror "int err" +.Sh DESCRIPTION +.Bf -symbolic +The +.Xr getaddrinfo 3 +and +.Xr getnameinfo 3 +functions are preferred over the +.Fn gethostbyname , +.Fn gethostbyname2 , +and +.Fn gethostbyaddr +functions. +.Ef +.Pp +The +.Fn gethostbyname , +.Fn gethostbyname2 +and +.Fn gethostbyaddr +functions +each return a pointer to an object with the +following structure describing an internet host +referenced by name or by address, respectively. +.Pp +The +.Fa name +argument passed to +.Fn gethostbyname +or +.Fn gethostbyname2 +should point to a +.Dv NUL Ns -terminated +hostname. +The +.Fa addr +argument passed to +.Fn gethostbyaddr +should point to an address which is +.Fa len +bytes long, +in binary form +(i.e., not an IP address in human readable +.Tn ASCII +form). +The +.Fa af +argument specifies the address family +(e.g.\& +.Dv AF_INET , AF_INET6 , +etc.) of this address. +.Pp +The structure returned contains either the information obtained from the name +server, +.Xr named 8 , +broken-out fields from a line in +.Pa /etc/hosts , +or database entries supplied by the +.Xr yp 8 +system. +The order of the lookups is controlled by the +.Sq hosts +entry in +.Xr nsswitch.conf 5 . +.Bd -literal +struct hostent { + char *h_name; /* official name of host */ + char **h_aliases; /* alias list */ + int h_addrtype; /* host address type */ + int h_length; /* length of address */ + char **h_addr_list; /* list of addresses from name server */ +}; +#define h_addr h_addr_list[0] /* address, for backward compatibility */ +.Ed +.Pp +The members of this structure are: +.Bl -tag -width h_addr_list +.It Va h_name +Official name of the host. +.It Va h_aliases +A +.Dv NULL Ns -terminated +array of alternate names for the host. +.It Va h_addrtype +The type of address being returned; usually +.Dv AF_INET . +.It Va h_length +The length, in bytes, of the address. +.It Va h_addr_list +A +.Dv NULL Ns -terminated +array of network addresses for the host. +Host addresses are returned in network byte order. +.It Va h_addr +The first address in +.Va h_addr_list ; +this is for backward compatibility. +.El +.Pp +When using the nameserver, +.Fn gethostbyname +and +.Fn gethostbyname2 +will search for the named host in the current domain and its parents +unless the name ends in a dot. +If the name contains no dot, and if the environment variable +.Dq Ev HOSTALIASES +contains the name of an alias file, the alias file will first be searched +for an alias matching the input name. +See +.Xr hostname 7 +for the domain search procedure and the alias file format. +.Pp +The +.Fn gethostbyname2 +function is an evolution of +.Fn gethostbyname +which is intended to allow lookups in address families other than +.Dv AF_INET , +for example +.Dv AF_INET6 . +.Pp +The +.Fn sethostent +function +may be used to request the use of a connected +.Tn TCP +socket for queries. +If the +.Fa stayopen +flag is non-zero, +this sets the option to send all queries to the name server using +.Tn TCP +and to retain the connection after each call to +.Fn gethostbyname , +.Fn gethostbyname2 +or +.Fn gethostbyaddr . +Otherwise, queries are performed using +.Tn UDP +datagrams. +.Pp +The +.Fn endhostent +function +closes the +.Tn TCP +connection. +.Pp +The +.Fn herror +function writes a message to the diagnostic output consisting of the +string argument +.Fa string , +the constant string +.Qq Li ":\ " , +and a message corresponding to the value of +.Va h_errno . +.Pp +The +.Fn hstrerror +function returns a string which is the message text corresponding to the +value of the +.Fa err +argument. +.Sh FILES +.Bl -tag -width /etc/nsswitch.conf -compact +.It Pa /etc/hosts +.It Pa /etc/nsswitch.conf +.It Pa /etc/resolv.conf +.El +.Sh EXAMPLES +Print out the hostname associated with a specific IP address: +.Bd -literal -offset indent +const char *ipstr = "127.0.0.1"; +struct in_addr ip; +struct hostent *hp; + +if (!inet_aton(ipstr, &ip)) + errx(1, "can't parse IP address %s", ipstr); + +if ((hp = gethostbyaddr((const void *)&ip, + sizeof ip, AF_INET)) == NULL) + errx(1, "no name associated with %s", ipstr); + +printf("name associated with %s is %s\en", ipstr, hp->h_name); +.Ed +.Sh DIAGNOSTICS +Error return status from +.Fn gethostbyname , +.Fn gethostbyname2 +and +.Fn gethostbyaddr +is indicated by return of a +.Dv NULL +pointer. +The integer +.Va h_errno +may then be checked to see whether this is a temporary failure +or an invalid or unknown host. +The routine +.Fn herror +can be used to print an error message describing the failure. +If its argument +.Fa string +is +.Pf non- Dv NULL , +it is printed, followed by a colon and a space. +The error message is printed with a trailing newline. +.Pp +The variable +.Va h_errno +can have the following values: +.Bl -tag -width HOST_NOT_FOUND +.It Dv HOST_NOT_FOUND +No such host is known. +.It Dv TRY_AGAIN +This is usually a temporary error +and means that the local server did not receive +a response from an authoritative server. +A retry at some later time may succeed. +.It Dv NO_RECOVERY +Some unexpected server failure was encountered. +This is a non-recoverable error. +.It Dv NO_DATA +The requested name is valid but does not have an IP address; +this is not a temporary error. +This means that the name is known to the name server but there is no address +associated with this name. +Another type of request to the name server using this domain name +will result in an answer; +for example, a mail-forwarder may be registered for this domain. +.El +.Sh SEE ALSO +.Xr getaddrinfo 3 , +.Xr getnameinfo 3 , +.Xr inet_aton 3 , +.Xr resolver 3 , +.Xr hosts 5 , +.Xr hostname 7 , +.Xr named 8 +.Sh CAVEAT +The +.Fn gethostent +function +is defined, and +.Fn sethostent +and +.Fn endhostent +are redefined, +when +.Lb libc +is built to use only the routines to lookup in +.Pa /etc/hosts +and not the name server. +.Pp +The +.Fn gethostent +function +reads the next line of +.Pa /etc/hosts , +opening the file if necessary. +.Pp +The +.Fn sethostent +function +opens and/or rewinds the file +.Pa /etc/hosts . +If the +.Fa stayopen +argument is non-zero, +the file will not be closed after each call to +.Fn gethostbyname , +.Fn gethostbyname2 +or +.Fn gethostbyaddr . +.Pp +The +.Fn endhostent +function +closes the file. +.Sh HISTORY +The +.Fn herror +function appeared in +.Bx 4.3 . +The +.Fn endhostent , +.Fn gethostbyaddr , +.Fn gethostbyname , +.Fn gethostent , +and +.Fn sethostent +functions appeared in +.Bx 4.2 . +The +.Fn gethostbyname2 +function first appeared in +.Tn BIND +version 4.9.4. +.Sh BUGS +These functions use a thread-specific data storage; +if the data is needed for future use, it should be +copied before any subsequent calls overwrite it. +.Pp +Though these functions are thread-safe, +still it is recommended to use the +.Xr getaddrinfo 3 +family of functions, instead. +.Pp +Only the Internet +address format is currently understood. diff --git a/lib/libc/net/getifaddrs.3 b/lib/libc/net/getifaddrs.3 new file mode 100644 index 0000000..a4f9859 --- /dev/null +++ b/lib/libc/net/getifaddrs.3 @@ -0,0 +1,163 @@ +.\" $KAME: getifaddrs.3,v 1.4 2000/05/17 14:13:14 itojun Exp $ +.\" BSDI getifaddrs.3,v 2.5 2000/02/23 14:51:59 dab Exp +.\" +.\" Copyright (c) 1995, 1999 +.\" Berkeley Software Design, Inc. 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``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 Berkeley Software Design, Inc. 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/getifaddrs.3 275044 2014-11-25 15:09:34Z pluknet $ +.\" +.Dd November 25, 2014 +.Dt GETIFADDRS 3 +.Os +.Sh NAME +.Nm getifaddrs +.Nd get interface addresses +.Sh SYNOPSIS +.In ifaddrs.h +.Ft int +.Fn getifaddrs "struct ifaddrs **ifap" +.Ft void +.Fn freeifaddrs "struct ifaddrs *ifp" +.Sh DESCRIPTION +The +.Fn getifaddrs +function stores a reference to a linked list of the network interfaces +on the local machine in the memory referenced by +.Fa ifap . +The list consists of +.Nm ifaddrs +structures, as defined in the include file +.In ifaddrs.h . +The +.Nm ifaddrs +structure contains at least the following entries: +.Bd -literal + struct ifaddrs *ifa_next; /* Pointer to next struct */ + char *ifa_name; /* Interface name */ + u_int ifa_flags; /* Interface flags */ + struct sockaddr *ifa_addr; /* Interface address */ + struct sockaddr *ifa_netmask; /* Interface netmask */ + struct sockaddr *ifa_broadaddr; /* Interface broadcast address */ + struct sockaddr *ifa_dstaddr; /* P2P interface destination */ + void *ifa_data; /* Address specific data */ +.Ed +.Pp +The +.Li ifa_next +field contains a pointer to the next structure on the list. +This field is +.Dv NULL +in last structure on the list. +.Pp +The +.Li ifa_name +field contains the interface name. +.Pp +The +.Li ifa_flags +field contains the interface flags, as set by +.Xr ifconfig 8 +utility. +.Pp +The +.Li ifa_addr +field references either the address of the interface or the link level +address of the interface, if one exists, otherwise it is NULL. +(The +.Li sa_family +field of the +.Li ifa_addr +field should be consulted to determine the format of the +.Li ifa_addr +address.) +.Pp +The +.Li ifa_netmask +field references the netmask associated with +.Li ifa_addr , +if one is set, otherwise it is NULL. +.Pp +The +.Li ifa_broadaddr +field, +which should only be referenced for non-P2P interfaces, +references the broadcast address associated with +.Li ifa_addr , +if one exists, otherwise it is NULL. +.Pp +The +.Li ifa_dstaddr +field references the destination address on a P2P interface, +if one exists, otherwise it is NULL. +.Pp +The +.Li ifa_data +field references address family specific data +in a pointer to the +.Fa struct if_data +(as defined in include file +.In net/if.h ) . +For +.Dv AF_LINK +addresses, +it contains various interface attributes and statistics. +For all other address families, +it contains per-address interface statistics. +.Pp +The data returned by +.Fn getifaddrs +is dynamically allocated and should be freed using +.Fn freeifaddrs +when no longer needed. +.Sh RETURN VALUES +.Rv -std getifaddrs +.Sh ERRORS +The +.Fn getifaddrs +may fail and set +.Va errno +for any of the errors specified for the library routines +.Xr ioctl 2 , +.Xr socket 2 , +.Xr malloc 3 +or +.Xr sysctl 3 . +.Sh SEE ALSO +.Xr ioctl 2 , +.Xr socket 2 , +.Xr sysctl 3 , +.Xr networking 4 , +.Xr ifconfig 8 +.Sh HISTORY +The +.Nm +implementation first appeared in BSDi +.Bsx . +.Sh BUGS +If both +.In net/if.h +and +.In ifaddrs.h +are being included, +.In net/if.h +.Em must +be included before +.In ifaddrs.h . diff --git a/lib/libc/net/getifmaddrs.3 b/lib/libc/net/getifmaddrs.3 new file mode 100644 index 0000000..66fd9d4 --- /dev/null +++ b/lib/libc/net/getifmaddrs.3 @@ -0,0 +1,114 @@ +.\" Copyright (c) 2003 Bruce M. Simpson. 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson ``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 Bruce M. Simpson 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/getifmaddrs.3 250888 2013-05-21 21:39:18Z ed $ +.\" +.Dd May 21, 2013 +.Dt GETIFMADDRS 3 +.Os +.Sh NAME +.Nm getifmaddrs +.Nd get multicast group memberships +.Sh SYNOPSIS +.In ifaddrs.h +.Ft int +.Fn getifmaddrs "struct ifmaddrs **ifmap" +.Ft void +.Fn freeifmaddrs "struct ifmaddrs *ifmp" +.Sh DESCRIPTION +The +.Fn getifmaddrs +function stores a reference to a linked list of the multicast memberships +on the local machine in the memory referenced by +.Fa ifmap . +The list consists of +.Vt ifmaddrs +structures, as defined in the include file +.In ifaddrs.h . +The +.Vt ifmaddrs +structure contains at least the following entries: +.Bd -literal + struct ifmaddrs *ifma_next; /* Pointer to next struct */ + struct sockaddr *ifma_name; /* Interface name (AF_LINK) */ + struct sockaddr *ifma_addr; /* Multicast address */ + struct sockaddr *ifma_lladdr; /* Link-layer translation, if any */ +.Ed +.Pp +The +.Va ifma_next +field contains a pointer to the next structure on the list. +This field is +.Dv NULL +in last structure on the list. +.Pp +The +.Va ifma_name +field references an +.Dv AF_LINK +address structure, containing the name of the +interface where the membership exists. +.Pp +The +.Va ifma_addr +references the address that this membership is for. +.Pp +The +.Va ifma_lladdr +field references a link-layer translation for the protocol-level address in +.Va ifma_addr , +if one is set, otherwise it is +.Dv NULL . +.Pp +The data returned by +.Fn getifmaddrs +is dynamically allocated and should be freed using +.Fn freeifmaddrs +when no longer needed. +.Sh RETURN VALUES +.Rv -std getifmaddrs +.Sh ERRORS +The +.Fn getifmaddrs +may fail and set +.Va errno +for any of the errors specified for the library routines +.Xr malloc 3 +or +.Xr sysctl 3 . +.Sh SEE ALSO +.Xr sysctl 3 , +.Xr networking 4 , +.Xr ifconfig 8 +.Sh HISTORY +The +.Fn getifmaddrs +function first appeared in +.Fx 5.2 . +.Sh BUGS +If both +.In net/if.h +and +.In ifaddrs.h +are being included, +.In net/if.h +.Em must +be included before +.In ifaddrs.h . diff --git a/lib/libc/net/getipnodebyname.3 b/lib/libc/net/getipnodebyname.3 new file mode 100644 index 0000000..d41467f --- /dev/null +++ b/lib/libc/net/getipnodebyname.3 @@ -0,0 +1,474 @@ +.\" $KAME: getipnodebyname.3,v 1.6 2000/08/09 21:16:17 itojun Exp $ +.\" +.\" Copyright (c) 1983, 1987, 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. +.\" 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. +.\" +.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95 +.\" $FreeBSD: releng/11.1/lib/libc/net/getipnodebyname.3 233522 2012-03-26 21:22:53Z joel $ +.\" +.Dd August 6, 2004 +.Dt GETIPNODEBYNAME 3 +.Os +.\" +.Sh NAME +.Nm getipnodebyname , +.Nm getipnodebyaddr , +.Nm freehostent +.Nd nodename-to-address and address-to-nodename translation +.\" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netdb.h +.Ft "struct hostent *" +.Fn getipnodebyname "const char *name" "int af" "int flags" "int *error_num" +.Ft "struct hostent *" +.Fn getipnodebyaddr "const void *src" "size_t len" "int af" "int *error_num" +.Ft void +.Fn freehostent "struct hostent *ptr" +.\" +.Sh DESCRIPTION +The +.Fn getipnodebyname +and +.Fn getipnodebyaddr +functions are very similar to +.Xr gethostbyname 3 , +.Xr gethostbyname2 3 +and +.Xr gethostbyaddr 3 . +The functions cover all the functionalities provided by the older ones, +and provide better interface to programmers. +The functions require additional arguments, +.Fa af , +and +.Fa flags , +for specifying address family and operation mode. +The additional arguments allow programmer to get address for a nodename, +for specific address family +(such as +.Dv AF_INET +or +.Dv AF_INET6 ) . +The functions also require an additional pointer argument, +.Fa error_num +to return the appropriate error code, +to support thread safe error code returns. +.Pp +The type and usage of the return value, +.Li "struct hostent" +is described in +.Xr gethostbyname 3 . +.Pp +For +.Fn getipnodebyname , +the +.Fa name +argument can be either a node name or a numeric address +string +(i.e., a dotted-decimal IPv4 address or an IPv6 hex address). +The +.Fa af +argument specifies the address family, either +.Dv AF_INET +or +.Dv AF_INET6 . +The +.Fa flags +argument specifies the types of addresses that are searched for, +and the types of addresses that are returned. +We note that a special flags value of +.Dv AI_DEFAULT +(defined below) +should handle most applications. +That is, porting simple applications to use IPv6 replaces the call +.Bd -literal -offset indent +hptr = gethostbyname(name); +.Ed +.Pp +with +.Bd -literal -offset indent +hptr = getipnodebyname(name, AF_INET6, AI_DEFAULT, &error_num); +.Ed +.Pp +Applications desiring finer control over the types of addresses +searched for and returned, can specify other combinations of the +.Fa flags +argument. +.Pp +A +.Fa flags +of +.Li 0 +implies a strict interpretation of the +.Fa af +argument: +.Bl -bullet +.It +If +.Fa flags +is 0 and +.Fa af +is +.Dv AF_INET , +then the caller wants only IPv4 addresses. +A query is made for +.Li A +records. +If successful, the IPv4 addresses are returned and the +.Li h_length +member of the +.Li hostent +structure will be 4, else the function returns a +.Dv NULL +pointer. +.It +If +.Fa flags +is 0 and if +.Fa af +is +.Li AF_INET6 , +then the caller wants only IPv6 addresses. +A query is made for +.Li AAAA +records. +If successful, the IPv6 addresses are returned and the +.Li h_length +member of the +.Li hostent +structure will be 16, else the function returns a +.Dv NULL +pointer. +.El +.Pp +Other constants can be logically-ORed into the +.Fa flags +argument, to modify the behavior of the function. +.Bl -bullet +.It +If the +.Dv AI_V4MAPPED +flag is specified along with an +.Fa af +of +.Dv AF_INET6 , +then the caller will accept IPv4-mapped IPv6 addresses. +That is, if no +.Li AAAA +records are found then a query is made for +.Li A +records and any found are returned as IPv4-mapped IPv6 addresses +.Li ( h_length +will be 16). +The +.Dv AI_V4MAPPED +flag is ignored unless +.Fa af +equals +.Dv AF_INET6 . +.It +The +.Dv AI_V4MAPPED_CFG +flag is exact same as the +.Dv AI_V4MAPPED +flag only if the kernel supports IPv4-mapped IPv6 address. +.It +If the +.Dv AI_ALL +flag is used in conjunction with the +.Dv AI_V4MAPPED +flag, and only used with the IPv6 address family. +When +.Dv AI_ALL +is logically or'd with +.Dv AI_V4MAPPED +flag then the caller wants all addresses: IPv6 and IPv4-mapped IPv6. +A query is first made for +.Li AAAA +records and if successful, the +IPv6 addresses are returned. +Another query is then made for +.Li A +records and any found are returned as IPv4-mapped IPv6 addresses. +.Li h_length +will be 16. +Only if both queries fail does the function +return a +.Dv NULL +pointer. +This flag is ignored unless af equals +AF_INET6. +If both +.Dv AI_ALL +and +.Dv AI_V4MAPPED +are specified, +.Dv AI_ALL +takes precedence. +.It +The +.Dv AI_ADDRCONFIG +flag specifies that a query for +.Li AAAA +records +should occur only if the node has at least one IPv6 source +address configured and a query for +.Li A +records should occur only if the node has at least one IPv4 source address +configured. +.Pp +For example, if the node has no IPv6 source addresses configured, +and +.Fa af +equals AF_INET6, and the node name being looked up has both +.Li AAAA +and +.Li A +records, then: +(a) if only +.Dv AI_ADDRCONFIG +is +specified, the function returns a +.Dv NULL +pointer; +(b) if +.Dv AI_ADDRCONFIG +| +.Dv AI_V4MAPPED +is specified, the +.Li A +records are returned as IPv4-mapped IPv6 addresses; +.El +.Pp +The special flags value of +.Dv AI_DEFAULT +is defined as +.Bd -literal -offset indent +#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) +.Ed +.Pp +We noted that the +.Fn getipnodebyname +function must allow the +.Fa name +argument to be either a node name or a literal address string +(i.e., a dotted-decimal IPv4 address or an IPv6 hex address). +This saves applications from having to call +.Xr inet_pton 3 +to handle literal address strings. +When the +.Fa name +argument is a literal address string, +the +.Fa flags +argument is always ignored. +.Pp +There are four scenarios based on the type of literal address string +and the value of the +.Fa af +argument. +The two simple cases are when +.Fa name +is a dotted-decimal IPv4 address and +.Fa af +equals +.Dv AF_INET , +or when +.Fa name +is an IPv6 hex address and +.Fa af +equals +.Dv AF_INET6 . +The members of the +returned hostent structure are: +.Li h_name +points to a copy of the +.Fa name +argument, +.Li h_aliases +is a +.Dv NULL +pointer, +.Li h_addrtype +is a copy of the +.Fa af +argument, +.Li h_length +is either 4 +(for +.Dv AF_INET ) +or 16 +(for +.Dv AF_INET6 ) , +.Li h_addr_list[0] +is a pointer to the 4-byte or 16-byte binary address, +and +.Li h_addr_list[1] +is a +.Dv NULL +pointer. +.Pp +When +.Fa name +is a dotted-decimal IPv4 address and +.Fa af +equals +.Dv AF_INET6 , +and +.Dv AI_V4MAPPED +is specified, +an IPv4-mapped IPv6 address is returned: +.Li h_name +points to an IPv6 hex address containing the IPv4-mapped IPv6 address, +.Li h_aliases +is a +.Dv NULL +pointer, +.Li h_addrtype +is +.Dv AF_INET6 , +.Li h_length +is 16, +.Li h_addr_list[0] +is a pointer to the 16-byte binary address, and +.Li h_addr_list[1] +is a +.Dv NULL +pointer. +.Pp +It is an error when +.Fa name +is an IPv6 hex address and +.Fa af +equals +.Dv AF_INET . +The function's return value is a +.Dv NULL +pointer and the value pointed to by +.Fa error_num +equals +.Dv HOST_NOT_FOUND . +.Pp +The +.Fn getipnodebyaddr +function +takes almost the same argument as +.Xr gethostbyaddr 3 , +but adds a pointer to return an error number. +Additionally it takes care of IPv4-mapped IPv6 addresses, +and IPv4-compatible IPv6 addresses. +.Pp +The +.Fn getipnodebyname +and +.Fn getipnodebyaddr +functions +dynamically allocate the structure to be returned to the caller. +The +.Fn freehostent +function +reclaims memory region allocated and returned by +.Fn getipnodebyname +or +.Fn getipnodebyaddr . +.\" +.Sh FILES +.Bl -tag -width /etc/nsswitch.conf -compact +.It Pa /etc/hosts +.It Pa /etc/nsswitch.conf +.It Pa /etc/resolv.conf +.El +.\" +.Sh DIAGNOSTICS +The +.Fn getipnodebyname +and +.Fn getipnodebyaddr +functions +returns +.Dv NULL +on errors. +The integer values pointed to by +.Fa error_num +may then be checked to see whether this is a temporary failure +or an invalid or unknown host. +The meanings of each error code are described in +.Xr gethostbyname 3 . +.\" +.Sh SEE ALSO +.Xr getaddrinfo 3 , +.Xr gethostbyaddr 3 , +.Xr gethostbyname 3 , +.Xr getnameinfo 3 , +.Xr hosts 5 , +.Xr nsswitch.conf 5 , +.Xr services 5 , +.Xr hostname 7 , +.Xr named 8 +.Pp +.Rs +.%A R. Gilligan +.%A S. Thomson +.%A J. Bound +.%A W. Stevens +.%T Basic Socket Interface Extensions for IPv6 +.%R RFC2553 +.%D March 1999 +.Re +.\" +.Sh STANDARDS +The +.Fn getipnodebyname +and +.Fn getipnodebyaddr +functions +are documented in +.Dq Basic Socket Interface Extensions for IPv6 +(RFC2553). +.\" +.Sh HISTORY +The implementation first appeared in KAME advanced networking kit. +.\" +.Sh BUGS +The +.Fn getipnodebyname +and +.Fn getipnodebyaddr +functions +do not handle scoped IPv6 address properly. +If you use these functions, +your program will not be able to handle scoped IPv6 addresses. +For IPv6 address manipulation, +.Fn getaddrinfo 3 +and +.Fn getnameinfo 3 +are recommended. +.Pp +The text was shamelessly copied from RFC2553. diff --git a/lib/libc/net/getnameinfo.3 b/lib/libc/net/getnameinfo.3 new file mode 100644 index 0000000..26f96e4 --- /dev/null +++ b/lib/libc/net/getnameinfo.3 @@ -0,0 +1,296 @@ +.\" $KAME: getnameinfo.3,v 1.37 2005/01/05 03:23:05 itojun Exp $ +.\" $OpenBSD: getnameinfo.3,v 1.36 2004/12/21 09:48:20 jmc Exp $ +.\" +.\" Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2000, 2001 Internet Software Consortium. +.\" +.\" 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 ISC DISCLAIMS ALL WARRANTIES WITH +.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +.\" AND FITNESS. IN NO EVENT SHALL ISC 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/getnameinfo.3 287999 2015-09-20 01:09:23Z hrs $ +.\" +.Dd September 20, 2015 +.Dt GETNAMEINFO 3 +.Os +.Sh NAME +.Nm getnameinfo +.Nd socket address structure to hostname and service name +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netdb.h +.Ft int +.Fo getnameinfo +.Fa "const struct sockaddr *sa" "socklen_t salen" "char *host" +.Fa "size_t hostlen" "char *serv" "size_t servlen" "int flags" +.Fc +.Sh DESCRIPTION +The +.Fn getnameinfo +function is used to convert a +.Li sockaddr +structure to a pair of host name and service strings. +It is a replacement for and provides more flexibility than the +.Xr gethostbyaddr 3 +and +.Xr getservbyport 3 +functions and is the converse of the +.Xr getaddrinfo 3 +function. +.Pp +If a link-layer address or UNIX-domain address is passed to +.Fn getnameinfo , +its ASCII representation will be stored in +.Fa host . +The string pointed to by +.Fa serv +will be set to the empty string if non-NULL; +.Fa flags +will always be ignored. +For a link-layer address, +this can be used as a replacement of the legacy +.Xr link_ntoa 3 +function. +.Pp +The +.Li sockaddr +structure +.Fa sa +should point to either a +.Li sockaddr_in , +.Li sockaddr_in6 , +.Li sockaddr_dl , +or +.Li sockaddr_un +structure +.Po for IPv4 , +IPv6, +link-layer, +or UNIX-domain respectively +.Pc +that is +.Fa salen +bytes long. +.Pp +The host and service names associated with +.Fa sa +are stored in +.Fa host +and +.Fa serv +which have length parameters +.Fa hostlen +and +.Fa servlen . +The maximum value for +.Fa hostlen +is +.Dv NI_MAXHOST +and +the maximum value for +.Fa servlen +is +.Dv NI_MAXSERV , +as defined by +.Aq Pa netdb.h . +If a length parameter is zero, no string will be stored. +Otherwise, enough space must be provided to store the +host name or service string plus a byte for the NUL terminator. +.Pp +The +.Fa flags +argument is formed by +.Tn OR Ns 'ing +the following values: +.Bl -tag -width "NI_NUMERICHOSTXX" +.It Dv NI_NOFQDN +A fully qualified domain name is not required for local hosts. +The local part of the fully qualified domain name is returned instead. +.It Dv NI_NUMERICHOST +Return the address in numeric form, as if calling +.Xr inet_ntop 3 , +instead of a host name. +.It Dv NI_NAMEREQD +A name is required. +If the host name cannot be found in DNS and this flag is set, +a non-zero error code is returned. +If the host name is not found and the flag is not set, the +address is returned in numeric form. +.It NI_NUMERICSERV +The service name is returned as a digit string representing the port number. +.It NI_DGRAM +Specifies that the service being looked up is a datagram +service, and causes +.Xr getservbyport 3 +to be called with a second argument of +.Dq udp +instead of its default of +.Dq tcp . +This is required for the few ports (512\-514) that have different services +for +.Tn UDP +and +.Tn TCP . +.El +.Pp +This implementation allows numeric IPv6 address notation with scope identifier, +as documented in chapter 11 of RFC 4007. +IPv6 link-local address will appear as a string like +.Dq Li fe80::1%ne0 . +Refer to +.Xr getaddrinfo 3 +for more information. +.Sh RETURN VALUES +.Fn getnameinfo +returns zero on success or one of the error codes listed in +.Xr gai_strerror 3 +if an error occurs. +.Sh EXAMPLES +The following code tries to get a numeric host name, and service name, +for a given socket address. +Observe that there is no hardcoded reference to a particular address family. +.Bd -literal -offset indent +struct sockaddr *sa; /* input */ +char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; + +if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf, + sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { + errx(1, "could not get numeric hostname"); + /* NOTREACHED */ +} +printf("host=%s, serv=%s\en", hbuf, sbuf); +.Ed +.Pp +The following version checks if the socket address has a reverse address mapping: +.Bd -literal -offset indent +struct sockaddr *sa; /* input */ +char hbuf[NI_MAXHOST]; + +if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0, + NI_NAMEREQD)) { + errx(1, "could not resolve hostname"); + /* NOTREACHED */ +} +printf("host=%s\en", hbuf); +.Ed +.Sh SEE ALSO +.Xr gai_strerror 3 , +.Xr getaddrinfo 3 , +.Xr gethostbyaddr 3 , +.Xr getservbyport 3 , +.Xr inet_ntop 3 , +.Xr link_ntoa 3 , +.Xr resolver 3 , +.Xr inet 4 , +.Xr inet6 4 , +.Xr unix 4 , +.Xr hosts 5 , +.Xr resolv.conf 5 , +.Xr services 5 , +.Xr hostname 7 , +.Xr named 8 +.Rs +.%A R. Gilligan +.%A S. Thomson +.%A J. Bound +.%A J. McCann +.%A W. Stevens +.%T Basic Socket Interface Extensions for IPv6 +.%R RFC 3493 +.%D February 2003 +.Re +.Rs +.%A S. Deering +.%A B. Haberman +.%A T. Jinmei +.%A E. Nordmark +.%A B. Zill +.%T "IPv6 Scoped Address Architecture" +.%R RFC 4007 +.%D March 2005 +.Re +.Rs +.%A Craig Metz +.%T Protocol Independence Using the Sockets API +.%B "Proceedings of the freenix track: 2000 USENIX annual technical conference" +.%D June 2000 +.Re +.Sh STANDARDS +The +.Fn getnameinfo +function is defined by the +.St -p1003.1-2004 +specification and documented in +.Tn "RFC 3493" , +.Dq Basic Socket Interface Extensions for IPv6 . +.Sh CAVEATS +.Fn getnameinfo +can return both numeric and FQDN forms of the address specified in +.Fa sa . +There is no return value that indicates whether the string returned in +.Fa host +is a result of binary to numeric-text translation (like +.Xr inet_ntop 3 ) , +or is the result of a DNS reverse lookup. +Because of this, malicious parties could set up a PTR record as follows: +.Bd -literal -offset indent +1.0.0.127.in-addr.arpa. IN PTR 10.1.1.1 +.Ed +.Pp +and trick the caller of +.Fn getnameinfo +into believing that +.Fa sa +is +.Li 10.1.1.1 +when it is actually +.Li 127.0.0.1 . +.Pp +To prevent such attacks, the use of +.Dv NI_NAMEREQD +is recommended when the result of +.Fn getnameinfo +is used +for access control purposes: +.Bd -literal -offset indent +struct sockaddr *sa; +socklen_t salen; +char addr[NI_MAXHOST]; +struct addrinfo hints, *res; +int error; + +error = getnameinfo(sa, salen, addr, sizeof(addr), + NULL, 0, NI_NAMEREQD); +if (error == 0) { + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(addr, "0", &hints, &res) == 0) { + /* malicious PTR record */ + freeaddrinfo(res); + printf("bogus PTR record\en"); + return -1; + } + /* addr is FQDN as a result of PTR lookup */ +} else { + /* addr is numeric string */ + error = getnameinfo(sa, salen, addr, sizeof(addr), + NULL, 0, NI_NUMERICHOST); +} +.Ed +.\".Pp +.\".Ox +.\"intentionally uses a different +.\".Dv NI_MAXHOST +.\"value from what +.\".Tn "RFC 2553" +.\"suggests, to avoid buffer length handling mistakes. diff --git a/lib/libc/net/getnetent.3 b/lib/libc/net/getnetent.3 new file mode 100644 index 0000000..c5ef03a --- /dev/null +++ b/lib/libc/net/getnetent.3 @@ -0,0 +1,170 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)getnetent.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/net/getnetent.3 243156 2012-11-16 15:02:35Z kevlo $ +.\" +.Dd June 4, 1993 +.Dt GETNETENT 3 +.Os +.Sh NAME +.Nm getnetent , +.Nm getnetbyaddr , +.Nm getnetbyname , +.Nm setnetent , +.Nm endnetent +.Nd get network entry +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In netdb.h +.Ft struct netent * +.Fn getnetent void +.Ft struct netent * +.Fn getnetbyname "const char *name" +.Ft struct netent * +.Fn getnetbyaddr "uint32_t net" "int type" +.Ft void +.Fn setnetent "int stayopen" +.Ft void +.Fn endnetent void +.Sh DESCRIPTION +The +.Fn getnetent , +.Fn getnetbyname , +and +.Fn getnetbyaddr +functions +each return a pointer to an object with the +following structure describing an internet network. +This structure contains either the information obtained +from the nameserver, +.Xr named 8 , +broken-out fields of a line in the network data base +.Pa /etc/networks , +or entries supplied by the +.Xr yp 8 +system. +The order of the lookups is controlled by the +`networks' entry in +.Xr nsswitch.conf 5 . +.Bd -literal -offset indent +struct netent { + char *n_name; /* official name of net */ + char **n_aliases; /* alias list */ + int n_addrtype; /* net number type */ + uint32_t n_net; /* net number */ +}; +.Ed +.Pp +The members of this structure are: +.Bl -tag -width n_addrtype +.It Fa n_name +The official name of the network. +.It Fa n_aliases +A zero terminated list of alternate names for the network. +.It Fa n_addrtype +The type of the network number returned; currently only AF_INET. +.It Fa n_net +The network number. +Network numbers are returned in machine byte +order. +.El +.Pp +The +.Fn getnetent +function +reads the next line of the file, opening the file if necessary. +.Pp +The +.Fn setnetent +function +opens and rewinds the file. +If the +.Fa stayopen +flag is non-zero, +the net data base will not be closed after each call to +.Fn getnetbyname +or +.Fn getnetbyaddr . +.Pp +The +.Fn endnetent +function +closes the file. +.Pp +The +.Fn getnetbyname +function +and +.Fn getnetbyaddr +sequentially search from the beginning +of the file until a matching +net name or +net address and type is found, +or until +.Dv EOF +is encountered. +The +.Fa type +argument +must be +.Dv AF_INET . +Network numbers are supplied in host order. +.Sh FILES +.Bl -tag -width /etc/nsswitch.conf -compact +.It Pa /etc/networks +.It Pa /etc/nsswitch.conf +.It Pa /etc/resolv.conf +.El +.Sh DIAGNOSTICS +Null pointer returned on +.Dv EOF +or error. +.Sh SEE ALSO +.Xr networks 5 +.Pp +.%T RFC 1101 +.Sh HISTORY +The +.Fn getnetent , +.Fn getnetbyaddr , +.Fn getnetbyname , +.Fn setnetent , +and +.Fn endnetent +functions appeared in +.Bx 4.2 . +.Sh BUGS +The data space used by +these functions is thread-specific; if future use requires the data, it should be +copied before any subsequent calls to these functions overwrite it. +Only Internet network +numbers are currently understood. +Expecting network numbers to fit +in no more than 32 bits is probably +naive. diff --git a/lib/libc/net/getprotoent.3 b/lib/libc/net/getprotoent.3 new file mode 100644 index 0000000..4d17a90 --- /dev/null +++ b/lib/libc/net/getprotoent.3 @@ -0,0 +1,144 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" @(#)getprotoent.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/net/getprotoent.3 243156 2012-11-16 15:02:35Z kevlo $ +.\" +.Dd June 4, 1993 +.Dt GETPROTOENT 3 +.Os +.Sh NAME +.Nm getprotoent , +.Nm getprotobynumber , +.Nm getprotobyname , +.Nm setprotoent , +.Nm endprotoent +.Nd get protocol entry +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In netdb.h +.Ft struct protoent * +.Fn getprotoent void +.Ft struct protoent * +.Fn getprotobyname "const char *name" +.Ft struct protoent * +.Fn getprotobynumber "int proto" +.Ft void +.Fn setprotoent "int stayopen" +.Ft void +.Fn endprotoent void +.Sh DESCRIPTION +The +.Fn getprotoent , +.Fn getprotobyname , +and +.Fn getprotobynumber +functions +each return a pointer to an object with the +following structure +containing the broken-out +fields of a line in the network protocol data base, +.Pa /etc/protocols . +.Bd -literal -offset indent +struct protoent { + char *p_name; /* official name of protocol */ + char **p_aliases; /* alias list */ + int p_proto; /* protocol number */ +}; +.Ed +.Pp +The members of this structure are: +.Bl -tag -width p_aliases +.It Fa p_name +The official name of the protocol. +.It Fa p_aliases +A zero terminated list of alternate names for the protocol. +.It Fa p_proto +The protocol number. +.El +.Pp +The +.Fn getprotoent +function +reads the next line of the file, opening the file if necessary. +.Pp +The +.Fn setprotoent +function +opens and rewinds the file. +If the +.Fa stayopen +flag is non-zero, +the net data base will not be closed after each call to +.Fn getprotobyname +or +.Fn getprotobynumber . +.Pp +The +.Fn endprotoent +function +closes the file. +.Pp +The +.Fn getprotobyname +function +and +.Fn getprotobynumber +sequentially search from the beginning +of the file until a matching +protocol name or +protocol number is found, +or until +.Dv EOF +is encountered. +.Sh RETURN VALUES +Null pointer returned on +.Dv EOF +or error. +.Sh FILES +.Bl -tag -width /etc/protocols -compact +.It Pa /etc/protocols +.El +.Sh SEE ALSO +.Xr protocols 5 +.Sh HISTORY +The +.Fn getprotoent , +.Fn getprotobynumber , +.Fn getprotobyname , +.Fn setprotoent , +and +.Fn endprotoent +functions appeared in +.Bx 4.2 . +.Sh BUGS +These functions use a thread-specific data space; +if the data is needed for future use, it should be +copied before any subsequent calls overwrite it. +Only the Internet +protocols are currently understood. diff --git a/lib/libc/net/getservent.3 b/lib/libc/net/getservent.3 new file mode 100644 index 0000000..68bd7a6 --- /dev/null +++ b/lib/libc/net/getservent.3 @@ -0,0 +1,154 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" From: @(#)getservent.3 8.3 (Berkeley) 1/12/94 +.\" $FreeBSD: releng/11.1/lib/libc/net/getservent.3 243156 2012-11-16 15:02:35Z kevlo $ +.\" +.Dd July 9, 1995 +.Dt GETSERVENT 3 +.Os +.Sh NAME +.Nm getservent , +.Nm getservbyport , +.Nm getservbyname , +.Nm setservent , +.Nm endservent +.Nd get service entry +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In netdb.h +.Ft struct servent * +.Fn getservent +.Ft struct servent * +.Fn getservbyname "const char *name" "const char *proto" +.Ft struct servent * +.Fn getservbyport "int port" "const char *proto" +.Ft void +.Fn setservent "int stayopen" +.Ft void +.Fn endservent void +.Sh DESCRIPTION +The +.Fn getservent , +.Fn getservbyname , +and +.Fn getservbyport +functions +each return a pointer to an object with the +following structure +containing the broken-out +fields of a line in the network services data base, +.Pa /etc/services . +.Bd -literal -offset indent +struct servent { + char *s_name; /* official name of service */ + char **s_aliases; /* alias list */ + int s_port; /* port service resides at */ + char *s_proto; /* protocol to use */ +}; +.Ed +.Pp +The members of this structure are: +.Bl -tag -width s_aliases +.It Fa s_name +The official name of the service. +.It Fa s_aliases +A zero terminated list of alternate names for the service. +.It Fa s_port +The port number at which the service resides. +Port numbers are returned in network byte order. +.It Fa s_proto +The name of the protocol to use when contacting the +service. +.El +.Pp +The +.Fn getservent +function +reads the next line of the file, opening the file if necessary. +.Pp +The +.Fn setservent +function +opens and rewinds the file. +If the +.Fa stayopen +flag is non-zero, +the net data base will not be closed after each call to +.Fn getservbyname +or +.Fn getservbyport . +.Pp +The +.Fn endservent +function +closes the file. +.Pp +The +.Fn getservbyname +and +.Fn getservbyport +functions +sequentially search from the beginning +of the file until a matching +protocol name or +port number (which must be specified in +network byte order) is found, +or until +.Dv EOF +is encountered. +If a protocol name is also supplied (non- +.Dv NULL ) , +searches must also match the protocol. +.Sh FILES +.Bl -tag -width /etc/services -compact +.It Pa /etc/services +.El +.Sh DIAGNOSTICS +Null pointer returned on +.Dv EOF +or error. +.Sh SEE ALSO +.Xr getprotoent 3 , +.Xr services 5 +.Sh HISTORY +The +.Fn getservent , +.Fn getservbyport , +.Fn getservbyname , +.Fn setservent , +and +.Fn endservent +functions appeared in +.Bx 4.2 . +.Sh BUGS +These functions use a thread-specific data storage; +if the data is needed for future use, it should be +copied before any subsequent calls overwrite it. +Expecting port numbers to fit in a 32 bit +quantity is probably naive. diff --git a/lib/libc/net/hesiod.3 b/lib/libc/net/hesiod.3 new file mode 100644 index 0000000..468dae0 --- /dev/null +++ b/lib/libc/net/hesiod.3 @@ -0,0 +1,176 @@ +.\" $NetBSD: hesiod.3,v 1.1 1999/01/25 03:43:04 lukem Exp $ +.\" +.\" from: #Id: hesiod.3,v 1.9.2.1 1997/01/03 21:02:23 ghudson Exp # +.\" +.\" Copyright 1988, 1996 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/hesiod.3 140505 2005-01-20 09:17:07Z ru $ +.\" +.Dd November 30, 1996 +.Dt HESIOD 3 +.Os +.Sh NAME +.Nm hesiod , +.Nm hesiod_init , +.Nm hesiod_resolve , +.Nm hesiod_free_list , +.Nm hesiod_to_bind , +.Nm hesiod_end +.Nd Hesiod name server interface library +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In hesiod.h +.Ft int +.Fn hesiod_init "void **context" +.Ft char ** +.Fn hesiod_resolve "void *context" "const char *name" "const char *type" +.Ft void +.Fn hesiod_free_list "void *context" "char **list" +.Ft char * +.Fn hesiod_to_bind "void *context" "const char *name" "const char *type" +.Ft void +.Fn hesiod_end "void *context" +.Sh DESCRIPTION +This family of functions allows you to perform lookups of Hesiod +information, which is stored as text records in the Domain Name +Service. +To perform lookups, you must first initialize a +.Fa context , +an opaque object which stores information used internally by the +library between calls. +The +.Fn hesiod_init +function +initializes a context, storing a pointer to the context in the +location pointed to by the +.Fa context +argument. +The +.Fn hesiod_end +function +frees the resources used by a context. +.Pp +The +.Fn hesiod_resolve +function +is the primary interface to the library. +If successful, it returns a +list of one or more strings giving the records matching +.Fa name +and +.Fa type . +The last element of the list is followed by a +.Dv NULL +pointer. +It is the +caller's responsibility to call +.Fn hesiod_free_list +to free the resources used by the returned list. +.Pp +The +.Fn hesiod_to_bind +function +converts +.Fa name +and +.Fa type +into the DNS name used by +.Fn hesiod_resolve . +It is the caller's responsibility to free the returned string using +.Fn free . +.Sh RETURN VALUES +.Rv -std hesiod_init +On failure, +.Fn hesiod_resolve +and +.Fn hesiod_to_bind +return +.Dv NULL +and set the global variable +.Va errno +to indicate the error. +.Sh ENVIRONMENT +.Bl -tag -width HESIOD_CONFIG +.It Ev HES_DOMAIN +If the environment variable +.Ev HES_DOMAIN +is set, it will override the domain in the Hesiod configuration file. +.It Ev HESIOD_CONFIG +If the environment variable +.Ev HESIOD_CONFIG +is set, it specifies the location of the Hesiod configuration file. +.El +.Sh ERRORS +Hesiod calls may fail because of: +.Bl -tag -width Er +.It Bq Er ENOMEM +Insufficient memory was available to carry out the requested +operation. +.It Bq Er ENOEXEC +The +.Fn hesiod_init +function +failed because the Hesiod configuration file was invalid. +.It Bq Er ECONNREFUSED +The +.Fn hesiod_resolve +function +failed because no name server could be contacted to answer the query. +.It Bq Er EMSGSIZE +The +.Fn hesiod_resolve +or +.Fn hesiod_to_bind +function +failed because the query or response was too big to fit into the +packet buffers. +.It Bq Er ENOENT +The +.Fn hesiod_resolve +function +failed because the name server had no text records matching +.Fa name +and +.Fa type , +or +.Fn hesiod_to_bind +failed because the +.Fa name +argument had a domain extension which could not be resolved with type +.Dq rhs\-extension +in the local Hesiod domain. +.El +.Sh SEE ALSO +.Xr hesiod.conf 5 , +.Xr named 8 +.Rs +.%T "Hesiod - Project Athena Technical Plan -- Name Service" +.Re +.Sh AUTHORS +.An Steve Dyer , +IBM/Project Athena +.An Greg Hudson , +MIT Team Athena +.Pp +Copyright 1987, 1988, 1995, 1996 by the Massachusetts Institute of Technology. +.Sh BUGS +The strings corresponding to the +.Va errno +values set by the Hesiod functions are not particularly indicative of +what went wrong, especially for +.Er ENOEXEC +and +.Er ENOENT . diff --git a/lib/libc/net/if_indextoname.3 b/lib/libc/net/if_indextoname.3 new file mode 100644 index 0000000..ebc60ad --- /dev/null +++ b/lib/libc/net/if_indextoname.3 @@ -0,0 +1,152 @@ +.\" $KAME: if_indextoname.3,v 1.10 2000/11/24 08:13:51 itojun Exp $ +.\" BSDI Id: if_indextoname.3,v 2.2 2000/04/17 22:38:05 dab Exp +.\" +.\" Copyright (c) 1997, 2000 +.\" Berkeley Software Design, Inc. 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``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 Berkeley Software Design, Inc. 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/if_indextoname.3 152712 2005-11-23 10:49:07Z ru $ +.\" +.Dd November 23, 2005 +.Dt IF_NAMETOINDEX 3 +.Os +.Sh NAME +.Nm if_nametoindex , +.Nm if_indextoname , +.Nm if_nameindex , +.Nm if_freenameindex +.Nd provide mappings between interface names and indexes +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In net/if.h +.Ft "unsigned int" +.Fn if_nametoindex "const char *ifname" +.Ft "char *" +.Fn if_indextoname "unsigned int ifindex" "char *ifname" +.Ft "struct if_nameindex *" +.Fn if_nameindex "void" +.Ft void +.Fn if_freenameindex "struct if_nameindex *ptr" +.Sh DESCRIPTION +The +.Fn if_nametoindex +function maps the interface name specified in +.Fa ifname +to its corresponding index. +If the specified interface does not exist, it returns 0. +.Pp +The +.Fn if_indextoname +function maps the interface index specified in +.Fa ifindex +to it corresponding name, which is copied into the +buffer pointed to by +.Fa ifname , +which must be of at least +.Dv IFNAMSIZ +bytes. +This pointer is also the return value of the function. +If there is no interface corresponding to the specified +index, +.Dv NULL +is returned. +.Pp +The +.Fn if_nameindex +function returns an array of +.Vt if_nameindex +structures, one structure per interface, as +defined in the include file +.In net/if.h . +The +.Vt if_nameindex +structure contains at least the following entries: +.Bd -literal + unsigned int if_index; /* 1, 2, ... */ + char *if_name; /* null terminated name: "le0", ... */ +.Ed +.Pp +The end of the array of structures is indicated by a structure with an +.Va if_index +of 0 and an +.Va if_name +of +.Dv NULL . +A +.Dv NULL +pointer is returned upon an error. +.Pp +The +.Fn if_freenameindex +function frees the dynamic memory that was +allocated by +.Fn if_nameindex . +.Sh RETURN VALUES +Upon successful completion, +.Fn if_nametoindex +returns the index number of the interface. +If the interface is not found, a value of 0 is returned and +.Va errno +is set to +.Er ENXIO . +A value of 0 is also returned if an error +occurs while retrieving the list of interfaces via +.Xr getifaddrs 3 . +.Pp +Upon successful completion, +.Fn if_indextoname +returns +.Fa ifname . +If the interface is not found, a +.Dv NULL +pointer is returned and +.Va errno +is set to +.Er ENXIO . +A +.Dv NULL +pointer is also returned if an error +occurs while retrieving the list of interfaces via +.Xr getifaddrs 3 . +.Pp +The +.Fn if_nameindex +returns a +.Dv NULL +pointer if an error +occurs while retrieving the list of interfaces via +.Xr getifaddrs 3 , +or if sufficient memory cannot be allocated. +.Sh SEE ALSO +.Xr getifaddrs 3 , +.Xr networking 4 +.Sh STANDARDS +The +.Fn if_nametoindex , +.Fn if_indextoname , +.Fn if_nameindex , +and +.Fn if_freenameindex +functions conform to +.%T "RFC 2553" . +.Sh HISTORY +The implementation first appeared in BSDi +.Bsx . diff --git a/lib/libc/net/inet.3 b/lib/libc/net/inet.3 new file mode 100644 index 0000000..e316ce9 --- /dev/null +++ b/lib/libc/net/inet.3 @@ -0,0 +1,305 @@ +.\" Copyright (c) 1983, 1990, 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. +.\" 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. +.\" +.\" From: @(#)inet.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/net/inet.3 170715 2007-06-14 07:13:28Z delphij $ +.\" +.Dd June 14, 2007 +.Dt INET 3 +.Os +.Sh NAME +.Nm inet_aton , +.Nm inet_addr , +.Nm inet_network , +.Nm inet_ntoa , +.Nm inet_ntoa_r , +.Nm inet_ntop , +.Nm inet_pton , +.Nm inet_makeaddr , +.Nm inet_lnaof , +.Nm inet_netof +.Nd Internet address manipulation routines +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netinet/in.h +.In arpa/inet.h +.Ft int +.Fn inet_aton "const char *cp" "struct in_addr *pin" +.Ft in_addr_t +.Fn inet_addr "const char *cp" +.Ft in_addr_t +.Fn inet_network "const char *cp" +.Ft char * +.Fn inet_ntoa "struct in_addr in" +.Ft char * +.Fo inet_ntoa_r +.Fa "struct in_addr in" +.Fa "char *buf" +.Fa "socklen_t size" +.Fc +.Ft const char * +.Fo inet_ntop +.Fa "int af" +.Fa "const void * restrict src" +.Fa "char * restrict dst" +.Fa "socklen_t size" +.Fc +.Ft int +.Fn inet_pton "int af" "const char * restrict src" "void * restrict dst" +.Ft struct in_addr +.Fn inet_makeaddr "in_addr_t net" "in_addr_t lna" +.Ft in_addr_t +.Fn inet_lnaof "struct in_addr in" +.Ft in_addr_t +.Fn inet_netof "struct in_addr in" +.Sh DESCRIPTION +The routines +.Fn inet_aton , +.Fn inet_addr +and +.Fn inet_network +interpret character strings representing +numbers expressed in the Internet standard +.Ql .\& +notation. +.Pp +The +.Fn inet_pton +function converts a presentation format address (that is, printable form +as held in a character string) to network format (usually a +.Ft struct in_addr +or some other internal binary representation, in network byte order). +It returns 1 if the address was valid for the specified address family, or +0 if the address was not parseable in the specified address family, or -1 +if some system error occurred (in which case +.Va errno +will have been set). +This function is presently valid for +.Dv AF_INET +and +.Dv AF_INET6 . +.Pp +The +.Fn inet_aton +routine interprets the specified character string as an Internet address, +placing the address into the structure provided. +It returns 1 if the string was successfully interpreted, +or 0 if the string is invalid. +The +.Fn inet_addr +and +.Fn inet_network +functions return numbers suitable for use +as Internet addresses and Internet network +numbers, respectively. +.Pp +The function +.Fn inet_ntop +converts an address +.Fa *src +from network format +(usually a +.Ft struct in_addr +or some other binary form, in network byte order) to presentation format +(suitable for external display purposes). +The +.Fa size +argument specifies the size, in bytes, of the buffer +.Fa *dst . +.Dv INET_ADDRSTRLEN +and +.Dv INET6_ADDRSTRLEN +define the maximum size required to convert an address of the respective +type. +It returns NULL if a system error occurs (in which case, +.Va errno +will have been set), or it returns a pointer to the destination string. +This function is presently valid for +.Dv AF_INET +and +.Dv AF_INET6 . +.Pp +The routine +.Fn inet_ntoa +takes an Internet address and returns an +.Tn ASCII +string representing the address in +.Ql .\& +notation. +The routine +.Fn inet_ntoa_r +is the reentrant version of +.Fn inet_ntoa . +The routine +.Fn inet_makeaddr +takes an Internet network number and a local +network address and constructs an Internet address +from it. +The routines +.Fn inet_netof +and +.Fn inet_lnaof +break apart Internet host addresses, returning +the network number and local network address part, +respectively. +.Pp +All Internet addresses are returned in network +order (bytes ordered from left to right). +All network numbers and local address parts are +returned as machine byte order integer values. +.Sh INTERNET ADDRESSES +Values specified using the +.Ql .\& +notation take one +of the following forms: +.Bd -literal -offset indent +a.b.c.d +a.b.c +a.b +a +.Ed +.Pp +When four parts are specified, each is interpreted +as a byte of data and assigned, from left to right, +to the four bytes of an Internet address. +Note +that when an Internet address is viewed as a 32-bit +integer quantity on the +.Tn VAX +the bytes referred to +above appear as +.Dq Li d.c.b.a . +That is, +.Tn VAX +bytes are +ordered from right to left. +.Pp +When a three part address is specified, the last +part is interpreted as a 16-bit quantity and placed +in the right-most two bytes of the network address. +This makes the three part address format convenient +for specifying Class B network addresses as +.Dq Li 128.net.host . +.Pp +When a two part address is supplied, the last part +is interpreted as a 24-bit quantity and placed in +the right most three bytes of the network address. +This makes the two part address format convenient +for specifying Class A network addresses as +.Dq Li net.host . +.Pp +When only one part is given, the value is stored +directly in the network address without any byte +rearrangement. +.Pp +All numbers supplied as +.Dq parts +in a +.Ql .\& +notation +may be decimal, octal, or hexadecimal, as specified +in the C language (i.e., a leading 0x or 0X implies +hexadecimal; otherwise, a leading 0 implies octal; +otherwise, the number is interpreted as decimal). +.Sh DIAGNOSTICS +The constant +.Dv INADDR_NONE +is returned by +.Fn inet_addr +and +.Fn inet_network +for malformed requests. +.Sh ERRORS +The +.Fn inet_ntop +call fails if: +.Bl -tag -width Er +.It Bq Er ENOSPC +.Fa size +was not large enough to store the presentation form of the address. +.It Bq Er EAFNOSUPPORT +.Fa *src +was not an +.Dv AF_INET +or +.Dv AF_INET6 +family address. +.El +.Sh SEE ALSO +.Xr byteorder 3 , +.Xr getaddrinfo 3 , +.Xr gethostbyname 3 , +.Xr getnameinfo 3 , +.Xr getnetent 3 , +.Xr inet_net 3 , +.Xr hosts 5 , +.Xr networks 5 +.Rs +.%R RFC +.%N 2373 +.%D July 1998 +.%T "IP Version 6 Addressing Architecture" +.Re +.Sh STANDARDS +The +.Fn inet_ntop +and +.Fn inet_pton +functions conform to +.St -xns5.2 . +Note that +.Fn inet_pton +does not accept 1-, 2-, or 3-part dotted addresses; all four parts +must be specified and are interpreted only as decimal values. +This is a narrower input set than that accepted by +.Fn inet_aton . +.Sh HISTORY +These +functions appeared in +.Bx 4.2 . +.Sh BUGS +The value +.Dv INADDR_NONE +(0xffffffff) is a valid broadcast address, but +.Fn inet_addr +cannot return that value without indicating failure. +The newer +.Fn inet_aton +function does not share this problem. +The problem of host byte ordering versus network byte ordering is +confusing. +The string returned by +.Fn inet_ntoa +resides in a static memory area. +.Pp +The +.Fn inet_addr +function should return a +.Fa struct in_addr . diff --git a/lib/libc/net/inet6_opt_init.3 b/lib/libc/net/inet6_opt_init.3 new file mode 100644 index 0000000..2e7ff1d --- /dev/null +++ b/lib/libc/net/inet6_opt_init.3 @@ -0,0 +1,337 @@ +.\" $KAME: inet6_opt_init.3,v 1.7 2004/12/27 05:08:23 itojun Exp $ +.\" +.\" Copyright (C) 2004 WIDE Project. +.\" 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 project 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 PROJECT 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 PROJECT 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/inet6_opt_init.3 152717 2005-11-23 16:07:54Z ru $ +.\" +.Dd December 23, 2004 +.Dt INET6_OPT_INIT 3 +.Os +.\" +.Sh NAME +.Nm inet6_opt_init , +.Nm inet6_opt_append , +.Nm inet6_opt_finish , +.Nm inet6_opt_set_val , +.Nm inet6_opt_next , +.Nm inet6_opt_find , +.Nm inet6_opt_get_val +.Nd IPv6 Hop-by-Hop and Destination Options manipulation +.\" +.Sh SYNOPSIS +.In netinet/in.h +.Ft "int" +.Fn inet6_opt_init "void *extbuf" "socklen_t extlen" +.Ft "int" +.Fn inet6_opt_append "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t type" "socklen_t len" "u_int8_t align" "void **databufp" +.Ft "int" +.Fn inet6_opt_finish "void *extbuf" "socklen_t extlen" "int offset" +.Ft "int" +.Fn inet6_opt_set_val "void *databuf" "int offset" "void *val" "socklen_t vallen" +.Ft "int" +.Fn inet6_opt_next "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t *typep" "socklen_t *lenp" "void **databufp" +.Ft "int" +.Fn inet6_opt_find "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t type" "socklen_t *lenp" "void **databufp" +.Ft "int" +.Fn inet6_opt_get_val "void *databuf" "int offset" "void *val" "socklen_t vallen" +.\" +.Sh DESCRIPTION +Building and parsing the Hop-by-Hop and Destination options is +complicated. +The advanced sockets API defines a set of functions to +help applications create and manipulate Hop-by-Hop and Destination +options. +This man page describes the functions specified in +IETF Draft RFC3542. +These functions use the +formatting rules specified in Appendix B in RFC2460, i.e., that the +largest field is placed last in the option. +The function prototypes +for these functions are all contained in the +.In netinet/in.h +header file. +.\" +.Ss inet6_opt_init +The +.Fn inet6_opt_init +function +returns the number of bytes needed for an empty +extension header, one without any options. +If the +.Fa extbuf +argument points to a valid section of memory +then the +.Fn inet6_opt_init +function also initializes the extension header's length field. +When attempting to initialize an extension buffer passed in the +.Fa extbuf +argument, +.Fa extlen +must be a positive multiple of 8 or else the function fails and +returns \-1 to the caller. +.\" +.Ss inet6_opt_append +The +.Fn inet6_opt_append +function can perform two different jobs. +When a valid +.Fa extbuf +argument is supplied it appends an option to the extension buffer and +returns the updated total length as well as a pointer to the newly +created option in +.Fa databufp . +If the value +of +.Fa extbuf +is +.Dv NULL +then the +.Fn inet6_opt_append +function only reports what the total length would +be if the option were actually appended. +The +.Fa len +and +.Fa align +arguments specify the length of the option and the required data +alignment which must be used when appending the option. +The +.Fa offset +argument should be the length returned by the +.Fn inet6_opt_init +function or a previous call to +.Fn inet6_opt_append . +.Pp +The +.Fa type +argument is the 8-bit option type. +.Pp +After +.Fn inet6_opt_append +has been called, the application can use the buffer pointed to by +.Fa databufp +directly, or use +.Fn inet6_opt_set_val +to specify the data to be contained in the option. +.Pp +Option types of +.Li 0 +and +.Li 1 +are reserved for the +.Li Pad1 +and +.Li PadN +options. +All other values from 2 through 255 may be used by applications. +.Pp +The length of the option data is contained in an 8-bit value and so +may contain any value from 0 through 255. +.Pp +The +.Fa align +parameter must have a value of 1, 2, 4, or 8 and cannot exceed the +value of +.Fa len . +The alignment values represent no alignment, 16 bit, 32 bit and 64 bit +alignments, respectively. +.\" +.Ss inet6_opt_finish +The +.Fn inet6_opt_finish +function +calculates the final padding necessary to make the extension header a +multiple of 8 bytes, as required by the IPv6 extension header +specification, and returns the extension header's updated total +length. +The +.Fa offset +argument should be the length returned by +.Fn inet6_opt_init +or +.Fn inet6_opt_append . +When +.Fa extbuf +is not +.Dv NULL +the function also sets up the appropriate padding bytes by inserting a +Pad1 or PadN option of the proper length. +.Pp +If the extension header is too small to contain the proper padding +then an error of \-1 is returned to the caller. +.\" +.Ss inet6_opt_set_val +The +.Fn inet6_opt_set_val +function inserts data items of various sizes into the data portion of +the option. +The +.Fa databuf +argument is a pointer to memory that was returned by the +.Fn inet6_opt_append +call and the +.Fa offset +argument specifies where the option should be placed in the +data buffer. +The +.Fa val +argument points to an area of memory containing the data to be +inserted into the extension header, and the +.Fa vallen +argument indicates how much data to copy. +.Pp +The caller should ensure that each field is aligned on its natural +boundaries as described in Appendix B of RFC2460. +.Pp +The function returns the offset for the next field which is calculated as +.Fa offset ++ +.Fa vallen +and is used when composing options with multiple fields. +.\" +.Ss inet6_opt_next +The +.Fn inet6_opt_next +function parses received extension headers. +The +.Fa extbuf +and +.Fa extlen +arguments specify the location and length of the extension header +being parsed. +The +.Fa offset +argument should either be zero, for the first option, or the length value +returned by a previous call to +.Fn inet6_opt_next +or +.Fn inet6_opt_find . +The return value specifies the position where to continue scanning the +extension buffer. +The option is returned in the arguments +.Fa typep , lenp , +and +.Fa databufp , +which +point to the 8-bit option type, the 8-bit option length and the option +data, respectively. +This function does not return any PAD1 or PADN options. +When an error occurs or there are no more options, the return +value is \-1. +.\" +.Ss inet6_opt_find +The +.Fn inet6_opt_find +function searches the extension buffer for a particular option type, +passed in through the +.Fa type +argument. +If the option is found then the +.Fa lenp +and +.Fa databufp +arguments are updated to point to the option's length and data, +respectively. +The +.Fa extbuf +and +.Fa extlen +arguments +must point to a valid extension buffer and give its length. +The +.Fa offset +argument can be used to search from a location anywhere in the +extension header. +.Ss inet6_opt_get_val +The +.Fn inet6_opt_get_val +function extracts data items of various sizes in the data portion of +the option. +The +.Fa databuf +is a pointer returned by the +.Fn inet6_opt_next +or +.Fn inet6_opt_find +functions. +The +.Fa val +argument points where the data will be extracted. +The +.Fa offset +argument specifies from where in the data portion of the option the +value should be extracted; the first byte of option data is specified +by an offset of zero. +.Pp +It is expected that each field is aligned on its natural boundaries as +described in Appendix B of RFC2460. +.Pp +The function returns the offset for the next field +by calculating +.Fa offset ++ +.Fa vallen +which can be used when extracting option content with multiple fields. +Robust receivers must verify alignment before calling this function. +.\" +.Sh RETURN VALUES +All the functions return +\-1 +on an error. +.\" +.Sh EXAMPLES +RFC3542 gives comprehensive examples in Section 23. +.Pp +KAME also provides examples in the +.Pa advapitest +directory of its kit. +.\" +.Sh SEE ALSO +.Rs +.%A W. Stevens +.%A M. Thomas +.%A E. Nordmark +.%A T. Jinmei +.%T "Advanced Sockets API for IPv6" +.%N RFC3542 +.%D October 2002 +.Re +.Rs +.%A S. Deering +.%A R. Hinden +.%T "Internet Protocol, Version 6 (IPv6) Specification" +.%N RFC2460 +.%D December 1998 +.Re +.Sh STANDARDS +The functions are documented in +.Dq Advanced Sockets API for IPv6 +.Pq RFC3542 . +.\" +.Sh HISTORY +The implementation first appeared in KAME advanced networking kit. diff --git a/lib/libc/net/inet6_option_space.3 b/lib/libc/net/inet6_option_space.3 new file mode 100644 index 0000000..12a96e8 --- /dev/null +++ b/lib/libc/net/inet6_option_space.3 @@ -0,0 +1,54 @@ +.\" $KAME: inet6_option_space.3,v 1.11 2005/01/05 03:00:44 itojun Exp $ +.\" +.\" Copyright (C) 2004 WIDE Project. +.\" 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 project 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 PROJECT 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 PROJECT 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/inet6_option_space.3 140750 2005-01-24 18:14:18Z ru $ +.\" +.Dd January 24, 2005 +.Dt INET6_OPTION_SPACE 3 +.Os +.\" +.Sh NAME +.Nm inet6_option_space , +.Nm inet6_option_init , +.Nm inet6_option_append , +.Nm inet6_option_alloc , +.Nm inet6_option_next , +.Nm inet6_option_find +.Nd IPv6 Hop-by-Hop and Destination Option Manipulation +.\" +.Sh DESCRIPTION +The functions that were documented in this manual page are now +deprecated in favor of those described in +.Xr inet6_opt_init 3 . +Please refer to that manual page for information on how to manipulate +IPv6 Hop-by-Hop and Destination options. +.Sh SEE ALSO +.Xr inet6_opt_init 3 +.\" +.\" diff --git a/lib/libc/net/inet6_rth_space.3 b/lib/libc/net/inet6_rth_space.3 new file mode 100644 index 0000000..ea4a9d4 --- /dev/null +++ b/lib/libc/net/inet6_rth_space.3 @@ -0,0 +1,225 @@ +.\" $KAME: inet6_rth_space.3,v 1.7 2005/01/05 03:00:44 itojun Exp $ +.\" +.\" Copyright (C) 2004 WIDE Project. +.\" 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 project 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 PROJECT 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 PROJECT 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/inet6_rth_space.3 211397 2010-08-16 15:18:30Z joel $ +.\" +.Dd December 24, 2004 +.Dt INET6_RTH_SPACE 3 +.Os +.\" +.Sh NAME +.Nm inet6_rth_space , +.Nm inet6_rth_init , +.Nm inet6_rth_add , +.Nm inet6_rth_reverse , +.Nm inet6_rth_segments , +.Nm inet6_rth_getaddr +.Nd IPv6 Routing Header Options manipulation +.\" +.Sh SYNOPSIS +.In netinet/in.h +.Ft socklen_t +.Fn inet6_rth_space "int" "int" +.Ft "void *" +.Fn inet6_rth_init "void *" "socklen_t" "int" "int" +.Ft int +.Fn inet6_rth_add "void *" "const struct in6_addr *" +.Ft int +.Fn inet6_rth_reverse "const void *" "void *" +.Ft int +.Fn inet6_rth_segments "const void *" +.Ft "struct in6_addr *" +.Fn inet6_rth_getaddr "const void *" "int" +.\" +.Sh DESCRIPTION +The IPv6 Advanced API, RFC 3542, defines the functions that an +application calls to build and examine IPv6 Routing headers. +Routing headers are used to perform source routing in IPv6 networks. +The RFC uses the word +.Dq segments +to describe addresses and that is the term used here as well. +All of the functions are defined in the +.In netinet/in.h +header file. +The functions described in this manual page all operate +on routing header structures which are defined in +.In netinet/ip6.h +but which should not need to be modified outside the use of this API. +The size and shape of the route header structures may change, so using +the APIs is a more portable, long term, solution. +.Pp +The functions in the API are split into two groups, those that build a +routing header and those that parse a received routing header. +We will describe the builder functions followed by the parser functions. +.Ss inet6_rth_space +The +.Fn inet6_rth_space +function returns the number of bytes required to hold a Routing Header +of the type, specified in the +.Fa type +argument and containing the number of addresses specified in the +.Fa segments +argument. +When the type is +.Dv IPV6_RTHDR_TYPE_0 +the number of segments must be from 0 through 127. +Routing headers of type +.Dv IPV6_RTHDR_TYPE_2 +contain only one segment, and are only used with Mobile IPv6. +The return value from this function is the number of bytes required to +store the routing header. +If the value 0 is returned then either the +route header type was not recognized or another error occurred. +.Ss inet6_rth_init +The +.Fn inet6_rth_init +function initializes the pre-allocated buffer pointed to by +.Fa bp +to contain a routing header of the specified type. +The +.Fa bp_len +argument is used to verify that the buffer is large enough. +The caller must allocate the buffer pointed to by bp. +The necessary buffer size should be determined by calling +.Fn inet6_rth_space +described in the previous sections. +.Pp +The +.Fn inet6_rth_init +function returns a pointer to +.Fa bp +on success and +.Dv NULL +when there is an error. +.Ss inet6_rth_add +The +.Fn inet6_rth_add +function adds the IPv6 address pointed to by +.Fa addr +to the end of the routing header being constructed. +.Pp +A successful addition results in the function returning 0, otherwise +\-1 is returned. +.Ss inet6_rth_reverse +The +.Fn inet6_rth_reverse +function takes a routing header, pointed to by the +argument +.Fa in , +and writes a new routing header into the argument pointed to by +.Fa out . +The routing header at that sends datagrams along the reverse of that +route. +Both arguments are allowed to point to the same buffer meaning +that the reversal can occur in place. +.Pp +The return value of the function is 0 on success, or \-1 when +there is an error. +.\" +.Pp +The next set of functions operate on a routing header that the +application wants to parse. +In the usual case such a routing header +is received from the network, although these functions can also be +used with routing headers that the application itself created. +.Ss inet6_rth_segments +The +.Fn inet6_rth_segments +function returns the number of segments contained in the +routing header pointed to by +.Fa bp . +The return value is the number of segments contained in the routing +header, or \-1 if an error occurred. +It is not an error for 0 to be +returned as a routing header may contain 0 segments. +.\" +.Ss inet6_rth_getaddr +The +.Fn inet6_rth_getaddr +function is used to retrieve a single address from a routing header. +The +.Fa index +is the location in the routing header from which the application wants +to retrieve an address. +The +.Fa index +parameter must have a value between 0 and one less than the number of +segments present in the routing header. +The +.Fn inet6_rth_segments +function, described in the last section, should be used to determine +the total number of segments in the routing header. +The +.Fn inet6_rth_getaddr +function returns a pointer to an IPv6 address on success or +.Dv NULL +when an error has occurred. +.\" +.Sh EXAMPLES +RFC 3542 gives extensive examples in Section 21, Appendix B. +.Pp +KAME also provides examples in the advapitest directory of its kit. +.\" +.Sh DIAGNOSTICS +The +.Fn inet6_rth_space +and +.Fn inet6_rth_getaddr +functions return 0 on errors. +.Pp +The +.Fn inet6_rthdr_init +function returns +.Dv NULL +on error. +The +.Fn inet6_rth_add +and +.Fn inet6_rth_reverse +functions return 0 on success, or \-1 upon an error. +.\" +.Sh SEE ALSO +.Rs +.%A W. Stevens +.%A M. Thomas +.%A E. Nordmark +.%A T. Jinmei +.%T "Advanced Sockets API for IPv6" +.%N RFC 3542 +.%D May 2003 +.Re +.Rs +.%A S. Deering +.%A R. Hinden +.%T "Internet Protocol, Version 6 (IPv6) Specification" +.%N RFC2460 +.%D December 1998 +.Re +.Sh HISTORY +The implementation first appeared in KAME advanced networking kit. diff --git a/lib/libc/net/inet6_rthdr_space.3 b/lib/libc/net/inet6_rthdr_space.3 new file mode 100644 index 0000000..c3a2ba9 --- /dev/null +++ b/lib/libc/net/inet6_rthdr_space.3 @@ -0,0 +1,57 @@ +.\" $KAME: inet6_rthdr_space.3,v 1.11 2005/01/05 03:00:44 itojun Exp $ +.\" +.\" Copyright (C) 2004 WIDE Project. +.\" 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 project 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 PROJECT 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 PROJECT 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/inet6_rthdr_space.3 140750 2005-01-24 18:14:18Z ru $ +.\" +.Dd January 24, 2005 +.Dt INET6_RTHDR_SPACE 3 +.Os +.\" +.Sh NAME +.Nm inet6_rthdr_space , +.Nm inet6_rthdr_init , +.Nm inet6_rthdr_add , +.Nm inet6_rthdr_lasthop , +.Nm inet6_rthdr_reverse , +.Nm inet6_rthdr_segments , +.Nm inet6_rthdr_getaddr , +.Nm inet6_rthdr_getflags +.Nd IPv6 Routing Header Options Manipulation +.\" +.Sh DESCRIPTION +The RFC 2292 IPv6 Advanced API has been deprecated in favor of the +newer, RFC 3542 APIs documented in +.Xr inet6_rth_space 3 . +On platforms that support it, currently only +.Fx , +please use the newer API to manipulate routing header +options. +.\" +.Sh SEE ALSO +.Xr inet6_rth_space 3 diff --git a/lib/libc/net/inet_net.3 b/lib/libc/net/inet_net.3 new file mode 100644 index 0000000..b7f1cde --- /dev/null +++ b/lib/libc/net/inet_net.3 @@ -0,0 +1,162 @@ +.\" $NetBSD: inet_net.3,v 1.4 1999/03/22 19:44:52 garbled Exp $ +.\" +.\" Copyright (c) 1997 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Luke Mewburn. +.\" +.\" 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. +.\" 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/inet_net.3 233462 2012-03-25 12:13:24Z joel $ +.\" +.Dd February 26, 2006 +.Dt INET_NET 3 +.Os +.Sh NAME +.Nm inet_net_ntop , +.Nm inet_net_pton +.Nd Internet network number manipulation routines +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netinet/in.h +.In arpa/inet.h +.Ft char * +.Fn inet_net_ntop "int af" "const void *src" "int bits" "char *dst" "size_t size" +.Ft int +.Fn inet_net_pton "int af" "const char *src" "void *dst" "size_t size" +.Sh DESCRIPTION +The +.Fn inet_net_ntop +function converts an Internet network number from network format (usually a +.Vt "struct in_addr" +or some other binary form, in network byte order) to CIDR presentation format +(suitable for external display purposes). +The +.Fa bits +argument +is the number of bits in +.Fa src +that are the network number. +It returns +.Dv NULL +if a system error occurs (in which case, +.Va errno +will have been set), or it returns a pointer to the destination string. +.Pp +The +.Fn inet_net_pton +function converts a presentation format Internet network number (that is, +printable form as held in a character string) to network format (usually a +.Vt "struct in_addr" +or some other internal binary representation, in network byte order). +It returns the number of bits (either computed based on the class, or +specified with /CIDR), or \-1 if a failure occurred +(in which case +.Va errno +will have been set. +It will be set to +.Er ENOENT +if the Internet network number was not valid). +.Pp +The currently supported values for +.Fa af +are +.Dv AF_INET +and +.Dv AF_INET6 . +The +.Fa size +argument +is the size of the result buffer +.Fa dst . +.Sh NETWORK NUMBERS (IP VERSION 4) +Internet network numbers may be specified in one of the following forms: +.Bd -literal -offset indent +a.b.c.d/bits +a.b.c.d +a.b.c +a.b +a +.Ed +.Pp +When four parts are specified, each is interpreted +as a byte of data and assigned, from left to right, +to the four bytes of an Internet network number. +Note +that when an Internet network number is viewed as a 32-bit +integer quantity on a system that uses little-endian +byte order (such as the +.Tn Intel 386 , 486 , +and +.Tn Pentium +processors) the bytes referred to above appear as +.Dq Li d.c.b.a . +That is, little-endian bytes are ordered from right to left. +.Pp +When a three part number is specified, the last +part is interpreted as a 16-bit quantity and placed +in the rightmost two bytes of the Internet network number. +This makes the three part number format convenient +for specifying Class B network numbers as +.Dq Li 128.net.host . +.Pp +When a two part number is supplied, the last part +is interpreted as a 24-bit quantity and placed in +the rightmost three bytes of the Internet network number. +This makes the two part number format convenient +for specifying Class A network numbers as +.Dq Li net.host . +.Pp +When only one part is given, the value is stored +directly in the Internet network number without any byte +rearrangement. +.Pp +All numbers supplied as +.Dq parts +in a +.Ql \&. +notation +may be decimal, octal, or hexadecimal, as specified +in the C language (i.e., a leading 0x or 0X implies +hexadecimal; otherwise, a leading 0 implies octal; +otherwise, the number is interpreted as decimal). +.\" +.\" .Sh NETWORK NUMBERS (IP VERSION 6) +.\" XXX - document this! +.\" +.Sh SEE ALSO +.Xr byteorder 3 , +.Xr inet 3 , +.Xr networks 5 +.Sh HISTORY +The +.Fn inet_net_ntop +and +.Fn inet_net_pton +functions appeared in BIND 4.9.4. diff --git a/lib/libc/net/linkaddr.3 b/lib/libc/net/linkaddr.3 new file mode 100644 index 0000000..f3e81ce --- /dev/null +++ b/lib/libc/net/linkaddr.3 @@ -0,0 +1,134 @@ +.\" Copyright (c) 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Donn Seeley at BSDI. +.\" +.\" 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. +.\" 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. +.\" +.\" From: @(#)linkaddr.3 8.1 (Berkeley) 7/28/93 +.\" $FreeBSD: releng/11.1/lib/libc/net/linkaddr.3 167121 2007-02-28 21:18:38Z bms $ +.\" +.Dd February 28, 2007 +.Dt LINK_ADDR 3 +.Os +.Sh NAME +.Nm link_addr , +.Nm link_ntoa +.Nd elementary address specification routines for link level access +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In net/if_dl.h +.Ft void +.Fn link_addr "const char *addr" "struct sockaddr_dl *sdl" +.Ft char * +.Fn link_ntoa "const struct sockaddr_dl *sdl" +.Sh DESCRIPTION +The routine +.Fn link_addr +interprets character strings representing +link-level addresses, returning binary information suitable +for use in system calls. +The routine +.Fn link_ntoa +takes +a link-level +address and returns an +.Tn ASCII +string representing some of the information present, +including the link level address itself, and the interface name +or number, if present. +This facility is experimental and is +still subject to change. +.Pp +For +.Fn link_addr , +the string +.Fa addr +may contain +an optional network interface identifier of the form +.Dq "name unit-number" , +suitable for the first argument to +.Xr ifconfig 8 , +followed in all cases by a colon and +an interface address in the form of +groups of hexadecimal digits +separated by periods. +Each group represents a byte of address; +address bytes are filled left to right from +low order bytes through high order bytes. +.Pp +.\" A regular expression may make this format clearer: +.\" .Bd -literal -offset indent +.\" ([a-z]+[0-9]+:)?[0-9a-f]+(\e.[0-9a-f]+)* +.\" .Ed +.\" .Pp +Thus +.Li le0:8.0.9.13.d.30 +represents an ethernet address +to be transmitted on the first Lance ethernet interface. +.Sh RETURN VALUES +The +.Fn link_ntoa +function +always returns a null terminated string. +The +.Fn link_addr +function +has no return value. +(See +.Sx BUGS . ) +.Sh SEE ALSO +.Xr getnameinfo 3 +.Sh HISTORY +The +.Fn link_addr +and +.Fn link_ntoa +functions appeared in +.Bx 4.3 Reno . +.Sh BUGS +The returned values for link_ntoa +reside in a static memory area. +.Pp +The function +.Fn link_addr +should diagnose improperly formed input, and there should be an unambiguous +way to recognize this. +.Pp +If the +.Va sdl_len +field of the link socket address +.Fa sdl +is 0, +.Fn link_ntoa +will not insert a colon before the interface address bytes. +If this translated address is given to +.Fn link_addr +without inserting an initial colon, +the latter will not interpret it correctly. diff --git a/lib/libc/net/nscache.c b/lib/libc/net/nscache.c new file mode 100644 index 0000000..8dab981 --- /dev/null +++ b/lib/libc/net/nscache.c @@ -0,0 +1,439 @@ +/*- + * Copyright (c) 2005 Michael Bushkov + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/net/nscache.c 288013 2015-09-20 04:17:03Z rodrigc $"); + +#include "namespace.h" +#define _NS_PRIVATE +#include +#include +#include +#include "un-namespace.h" +#include "nscachedcli.h" +#include "nscache.h" + +#define NSS_CACHE_KEY_INITIAL_SIZE (256) +#define NSS_CACHE_KEY_SIZE_LIMIT (NSS_CACHE_KEY_INITIAL_SIZE << 4) + +#define NSS_CACHE_BUFFER_INITIAL_SIZE (1024) +#define NSS_CACHE_BUFFER_SIZE_LIMIT (NSS_CACHE_BUFFER_INITIAL_SIZE << 8) + +#define CACHED_SOCKET_PATH "/var/run/nscd" + +int +__nss_cache_handler(void *retval, void *mdata, va_list ap) +{ + return (NS_UNAVAIL); +} + +int +__nss_common_cache_read(void *retval, void *mdata, va_list ap) +{ + struct cached_connection_params params; + cached_connection connection; + + char *buffer; + size_t buffer_size, size; + + nss_cache_info const *cache_info; + nss_cache_data *cache_data; + va_list ap_new; + int res; + + cache_data = (nss_cache_data *)mdata; + cache_info = cache_data->info; + + memset(¶ms, 0, sizeof(struct cached_connection_params)); + params.socket_path = CACHED_SOCKET_PATH; + + cache_data->key = (char *)malloc(NSS_CACHE_KEY_INITIAL_SIZE); + memset(cache_data->key, 0, NSS_CACHE_KEY_INITIAL_SIZE); + cache_data->key_size = NSS_CACHE_KEY_INITIAL_SIZE; + va_copy(ap_new, ap); + + do { + size = cache_data->key_size; + res = cache_info->id_func(cache_data->key, &size, ap_new, + cache_info->mdata); + va_end(ap_new); + if (res == NS_RETURN) { + if (cache_data->key_size > NSS_CACHE_KEY_SIZE_LIMIT) + break; + + cache_data->key_size <<= 1; + cache_data->key = realloc(cache_data->key, + cache_data->key_size); + memset(cache_data->key, 0, cache_data->key_size); + va_copy(ap_new, ap); + } + } while (res == NS_RETURN); + + if (res != NS_SUCCESS) { + free(cache_data->key); + cache_data->key = NULL; + cache_data->key_size = 0; + return (res); + } else + cache_data->key_size = size; + + buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE; + buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE); + memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE); + + do { + connection = __open_cached_connection(¶ms); + if (connection == NULL) { + res = -1; + break; + } + res = __cached_read(connection, cache_info->entry_name, + cache_data->key, cache_data->key_size, buffer, + &buffer_size); + __close_cached_connection(connection); + if (res == -2 && buffer_size < NSS_CACHE_BUFFER_SIZE_LIMIT) { + buffer = (char *)realloc(buffer, buffer_size); + memset(buffer, 0, buffer_size); + } + } while (res == -2); + + if (res == 0) { + if (buffer_size == 0) { + free(buffer); + free(cache_data->key); + cache_data->key = NULL; + cache_data->key_size = 0; + return (NS_RETURN); + } + + va_copy(ap_new, ap); + res = cache_info->unmarshal_func(buffer, buffer_size, retval, + ap_new, cache_info->mdata); + va_end(ap_new); + + if (res != NS_SUCCESS) { + free(buffer); + free(cache_data->key); + cache_data->key = NULL; + cache_data->key_size = 0; + return (res); + } else + res = 0; + } + + if (res == 0) { + free(cache_data->key); + cache_data->key = NULL; + cache_data->key_size = 0; + } + + free(buffer); + return (res == 0 ? NS_SUCCESS : NS_NOTFOUND); +} + +int +__nss_common_cache_write(void *retval, void *mdata, va_list ap) +{ + struct cached_connection_params params; + cached_connection connection; + + char *buffer; + size_t buffer_size; + + nss_cache_info const *cache_info; + nss_cache_data *cache_data; + va_list ap_new; + int res; + + cache_data = (nss_cache_data *)mdata; + cache_info = cache_data->info; + + if (cache_data->key == NULL) + return (NS_UNAVAIL); + + memset(¶ms, 0, sizeof(struct cached_connection_params)); + params.socket_path = CACHED_SOCKET_PATH; + + connection = __open_cached_connection(¶ms); + if (connection == NULL) { + free(cache_data->key); + return (NS_UNAVAIL); + } + + buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE; + buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE); + memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE); + + do { + size_t size; + + size = buffer_size; + va_copy(ap_new, ap); + res = cache_info->marshal_func(buffer, &size, retval, ap_new, + cache_info->mdata); + va_end(ap_new); + + if (res == NS_RETURN) { + if (buffer_size > NSS_CACHE_BUFFER_SIZE_LIMIT) + break; + + buffer_size <<= 1; + buffer = (char *)realloc(buffer, buffer_size); + memset(buffer, 0, buffer_size); + } + } while (res == NS_RETURN); + + if (res != NS_SUCCESS) { + __close_cached_connection(connection); + free(cache_data->key); + free(buffer); + return (res); + } + + res = __cached_write(connection, cache_info->entry_name, + cache_data->key, cache_data->key_size, buffer, buffer_size); + __close_cached_connection(connection); + + free(cache_data->key); + free(buffer); + + return (res == 0 ? NS_SUCCESS : NS_UNAVAIL); +} + +int +__nss_common_cache_write_negative(void *mdata) +{ + struct cached_connection_params params; + cached_connection connection; + int res; + + nss_cache_info const *cache_info; + nss_cache_data *cache_data; + + cache_data = (nss_cache_data *)mdata; + cache_info = cache_data->info; + + if (cache_data->key == NULL) + return (NS_UNAVAIL); + + memset(¶ms, 0, sizeof(struct cached_connection_params)); + params.socket_path = CACHED_SOCKET_PATH; + + connection = __open_cached_connection(¶ms); + if (connection == NULL) { + free(cache_data->key); + return (NS_UNAVAIL); + } + + res = __cached_write(connection, cache_info->entry_name, + cache_data->key, cache_data->key_size, NULL, 0); + __close_cached_connection(connection); + + free(cache_data->key); + return (res == 0 ? NS_SUCCESS : NS_UNAVAIL); +} + +int +__nss_mp_cache_read(void *retval, void *mdata, va_list ap) +{ + struct cached_connection_params params; + cached_mp_read_session rs; + + char *buffer; + size_t buffer_size; + + nss_cache_info const *cache_info; + nss_cache_data *cache_data; + va_list ap_new; + int res; + + cache_data = (nss_cache_data *)mdata; + cache_info = cache_data->info; + + if (cache_info->get_mp_ws_func() != INVALID_CACHED_MP_WRITE_SESSION) + return (NS_UNAVAIL); + + rs = cache_info->get_mp_rs_func(); + if (rs == INVALID_CACHED_MP_READ_SESSION) { + memset(¶ms, 0, sizeof(struct cached_connection_params)); + params.socket_path = CACHED_SOCKET_PATH; + + rs = __open_cached_mp_read_session(¶ms, + cache_info->entry_name); + if (rs == INVALID_CACHED_MP_READ_SESSION) + return (NS_UNAVAIL); + + cache_info->set_mp_rs_func(rs); + } + + buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE; + buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE); + memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE); + + do { + res = __cached_mp_read(rs, buffer, &buffer_size); + if (res == -2 && buffer_size < NSS_CACHE_BUFFER_SIZE_LIMIT) { + buffer = (char *)realloc(buffer, buffer_size); + memset(buffer, 0, buffer_size); + } + } while (res == -2); + + if (res == 0) { + va_copy(ap_new, ap); + res = cache_info->unmarshal_func(buffer, buffer_size, retval, + ap_new, cache_info->mdata); + va_end(ap_new); + + if (res != NS_SUCCESS) { + free(buffer); + return (res); + } else + res = 0; + } else { + free(buffer); + __close_cached_mp_read_session(rs); + rs = INVALID_CACHED_MP_READ_SESSION; + cache_info->set_mp_rs_func(rs); + return (res == -1 ? NS_RETURN : NS_UNAVAIL); + } + + free(buffer); + return (res == 0 ? NS_SUCCESS : NS_NOTFOUND); +} + +int +__nss_mp_cache_write(void *retval, void *mdata, va_list ap) +{ + struct cached_connection_params params; + cached_mp_write_session ws; + + char *buffer; + size_t buffer_size; + + nss_cache_info const *cache_info; + nss_cache_data *cache_data; + va_list ap_new; + int res; + + cache_data = (nss_cache_data *)mdata; + cache_info = cache_data->info; + + ws = cache_info->get_mp_ws_func(); + if (ws == INVALID_CACHED_MP_WRITE_SESSION) { + memset(¶ms, 0, sizeof(struct cached_connection_params)); + params.socket_path = CACHED_SOCKET_PATH; + + ws = __open_cached_mp_write_session(¶ms, + cache_info->entry_name); + if (ws == INVALID_CACHED_MP_WRITE_SESSION) + return (NS_UNAVAIL); + + cache_info->set_mp_ws_func(ws); + } + + buffer_size = NSS_CACHE_BUFFER_INITIAL_SIZE; + buffer = (char *)malloc(NSS_CACHE_BUFFER_INITIAL_SIZE); + memset(buffer, 0, NSS_CACHE_BUFFER_INITIAL_SIZE); + + do { + size_t size; + + size = buffer_size; + va_copy(ap_new, ap); + res = cache_info->marshal_func(buffer, &size, retval, ap_new, + cache_info->mdata); + va_end(ap_new); + + if (res == NS_RETURN) { + if (buffer_size > NSS_CACHE_BUFFER_SIZE_LIMIT) + break; + + buffer_size <<= 1; + buffer = (char *)realloc(buffer, buffer_size); + memset(buffer, 0, buffer_size); + } + } while (res == NS_RETURN); + + if (res != NS_SUCCESS) { + free(buffer); + return (res); + } + + res = __cached_mp_write(ws, buffer, buffer_size); + + free(buffer); + return (res == 0 ? NS_SUCCESS : NS_UNAVAIL); +} + +int +__nss_mp_cache_write_submit(void *retval, void *mdata, va_list ap) +{ + cached_mp_write_session ws; + + nss_cache_info const *cache_info; + nss_cache_data *cache_data; + + cache_data = (nss_cache_data *)mdata; + cache_info = cache_data->info; + + ws = cache_info->get_mp_ws_func(); + if (ws != INVALID_CACHED_MP_WRITE_SESSION) { + __close_cached_mp_write_session(ws); + ws = INVALID_CACHED_MP_WRITE_SESSION; + cache_info->set_mp_ws_func(ws); + } + return (NS_UNAVAIL); +} + +int +__nss_mp_cache_end(void *retval, void *mdata, va_list ap) +{ + cached_mp_write_session ws; + cached_mp_read_session rs; + + nss_cache_info const *cache_info; + nss_cache_data *cache_data; + + cache_data = (nss_cache_data *)mdata; + cache_info = cache_data->info; + + ws = cache_info->get_mp_ws_func(); + if (ws != INVALID_CACHED_MP_WRITE_SESSION) { + __abandon_cached_mp_write_session(ws); + ws = INVALID_CACHED_MP_WRITE_SESSION; + cache_info->set_mp_ws_func(ws); + } + + rs = cache_info->get_mp_rs_func(); + if (rs != INVALID_CACHED_MP_READ_SESSION) { + __close_cached_mp_read_session(rs); + rs = INVALID_CACHED_MP_READ_SESSION; + cache_info->set_mp_rs_func(rs); + } + + return (NS_UNAVAIL); +} diff --git a/lib/libc/net/nscachedcli.c b/lib/libc/net/nscachedcli.c new file mode 100644 index 0000000..8b1778f --- /dev/null +++ b/lib/libc/net/nscachedcli.c @@ -0,0 +1,577 @@ +/*- + * Copyright (c) 2005 Michael Bushkov + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/net/nscachedcli.c 298830 2016-04-30 01:24:24Z pfg $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" +#include "nscachedcli.h" + +#define NS_DEFAULT_CACHED_IO_TIMEOUT 4 + +static int safe_write(struct cached_connection_ *, const void *, size_t); +static int safe_read(struct cached_connection_ *, void *, size_t); +static int send_credentials(struct cached_connection_ *, int); + +/* + * safe_write writes data to the specified connection and tries to do it in + * the very safe manner. We ensure, that we can write to the socket with + * kevent. If the data_size can't be sent in one piece, then it would be + * splitted. + */ +static int +safe_write(struct cached_connection_ *connection, const void *data, + size_t data_size) +{ + struct kevent eventlist; + int nevents; + size_t result; + ssize_t s_result; + struct timespec timeout; + + if (data_size == 0) + return (0); + + timeout.tv_sec = NS_DEFAULT_CACHED_IO_TIMEOUT; + timeout.tv_nsec = 0; + result = 0; + do { + nevents = _kevent(connection->write_queue, NULL, 0, &eventlist, + 1, &timeout); + if ((nevents == 1) && (eventlist.filter == EVFILT_WRITE)) { + s_result = _sendto(connection->sockfd, data + result, + eventlist.data < data_size - result ? + eventlist.data : data_size - result, MSG_NOSIGNAL, + NULL, 0); + if (s_result == -1) + return (-1); + else + result += s_result; + + if (eventlist.flags & EV_EOF) + return (result < data_size ? -1 : 0); + } else + return (-1); + } while (result < data_size); + + return (0); +} + +/* + * safe_read reads data from connection and tries to do it in the very safe + * and stable way. It uses kevent to ensure, that the data are available for + * reading. If the amount of data to be read is too large, then they would + * be splitted. + */ +static int +safe_read(struct cached_connection_ *connection, void *data, size_t data_size) +{ + struct kevent eventlist; + size_t result; + ssize_t s_result; + struct timespec timeout; + int nevents; + + if (data_size == 0) + return (0); + + timeout.tv_sec = NS_DEFAULT_CACHED_IO_TIMEOUT; + timeout.tv_nsec = 0; + result = 0; + do { + nevents = _kevent(connection->read_queue, NULL, 0, &eventlist, + 1, &timeout); + if (nevents == 1 && eventlist.filter == EVFILT_READ) { + s_result = _read(connection->sockfd, data + result, + eventlist.data <= data_size - result ? + eventlist.data : data_size - result); + if (s_result == -1) + return (-1); + else + result += s_result; + + if (eventlist.flags & EV_EOF) + return (result < data_size ? -1 : 0); + } else + return (-1); + } while (result < data_size); + + return (0); +} + +/* + * Sends the credentials information to the connection along with the + * communication element type. + */ +static int +send_credentials(struct cached_connection_ *connection, int type) +{ + struct kevent eventlist; + int nevents; + ssize_t result; + int res; + + struct msghdr cred_hdr; + struct iovec iov; + + struct { + struct cmsghdr hdr; + char cred[CMSG_SPACE(sizeof(struct cmsgcred))]; + } cmsg; + + memset(&cmsg, 0, sizeof(cmsg)); + cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(struct cmsgcred)); + cmsg.hdr.cmsg_level = SOL_SOCKET; + cmsg.hdr.cmsg_type = SCM_CREDS; + + memset(&cred_hdr, 0, sizeof(struct msghdr)); + cred_hdr.msg_iov = &iov; + cred_hdr.msg_iovlen = 1; + cred_hdr.msg_control = (caddr_t)&cmsg; + cred_hdr.msg_controllen = CMSG_SPACE(sizeof(struct cmsgcred)); + + iov.iov_base = &type; + iov.iov_len = sizeof(int); + + EV_SET(&eventlist, connection->sockfd, EVFILT_WRITE, EV_ADD, + NOTE_LOWAT, sizeof(int), NULL); + res = _kevent(connection->write_queue, &eventlist, 1, NULL, 0, NULL); + + nevents = _kevent(connection->write_queue, NULL, 0, &eventlist, 1, + NULL); + if (nevents == 1 && eventlist.filter == EVFILT_WRITE) { + result = (_sendmsg(connection->sockfd, &cred_hdr, + MSG_NOSIGNAL) == -1) ? -1 : 0; + EV_SET(&eventlist, connection->sockfd, EVFILT_WRITE, EV_ADD, + 0, 0, NULL); + _kevent(connection->write_queue, &eventlist, 1, NULL, 0, NULL); + return (result); + } else + return (-1); +} + +/* + * Opens the connection with the specified params. Initializes all kqueues. + */ +struct cached_connection_ * +__open_cached_connection(struct cached_connection_params const *params) +{ + struct cached_connection_ *retval; + struct kevent eventlist; + struct sockaddr_un client_address; + int client_address_len, client_socket; + int res; + + assert(params != NULL); + + client_socket = _socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0); + client_address.sun_family = PF_LOCAL; + strncpy(client_address.sun_path, params->socket_path, + sizeof(client_address.sun_path)); + client_address_len = sizeof(client_address.sun_family) + + strlen(client_address.sun_path) + 1; + + res = _connect(client_socket, (struct sockaddr *)&client_address, + client_address_len); + if (res == -1) { + _close(client_socket); + return (NULL); + } + _fcntl(client_socket, F_SETFL, O_NONBLOCK); + + retval = malloc(sizeof(struct cached_connection_)); + assert(retval != NULL); + memset(retval, 0, sizeof(struct cached_connection_)); + + retval->sockfd = client_socket; + + retval->write_queue = kqueue(); + assert(retval->write_queue != -1); + + EV_SET(&eventlist, retval->sockfd, EVFILT_WRITE, EV_ADD, 0, 0, NULL); + res = _kevent(retval->write_queue, &eventlist, 1, NULL, 0, NULL); + + retval->read_queue = kqueue(); + assert(retval->read_queue != -1); + + EV_SET(&eventlist, retval->sockfd, EVFILT_READ, EV_ADD, 0, 0, NULL); + res = _kevent(retval->read_queue, &eventlist, 1, NULL, 0, NULL); + + return (retval); +} + +void +__close_cached_connection(struct cached_connection_ *connection) +{ + assert(connection != NULL); + + _close(connection->sockfd); + _close(connection->read_queue); + _close(connection->write_queue); + free(connection); +} + +/* + * This function is very close to the cache_write function of the caching + * library, which is used in the caching daemon. It caches the data with the + * specified key in the cache entry with entry_name. + */ +int +__cached_write(struct cached_connection_ *connection, const char *entry_name, + const char *key, size_t key_size, const char *data, size_t data_size) +{ + size_t name_size; + int error_code; + int result; + + error_code = -1; + result = 0; + result = send_credentials(connection, CET_WRITE_REQUEST); + if (result != 0) + goto fin; + + name_size = strlen(entry_name); + result = safe_write(connection, &name_size, sizeof(size_t)); + if (result != 0) + goto fin; + + result = safe_write(connection, &key_size, sizeof(size_t)); + if (result != 0) + goto fin; + + result = safe_write(connection, &data_size, sizeof(size_t)); + if (result != 0) + goto fin; + + result = safe_write(connection, entry_name, name_size); + if (result != 0) + goto fin; + + result = safe_write(connection, key, key_size); + if (result != 0) + goto fin; + + result = safe_write(connection, data, data_size); + if (result != 0) + goto fin; + + result = safe_read(connection, &error_code, sizeof(int)); + if (result != 0) + error_code = -1; + +fin: + return (error_code); +} + +/* + * This function is very close to the cache_read function of the caching + * library, which is used in the caching daemon. It reads cached data with the + * specified key from the cache entry with entry_name. + */ +int +__cached_read(struct cached_connection_ *connection, const char *entry_name, + const char *key, size_t key_size, char *data, size_t *data_size) +{ + size_t name_size, result_size; + int error_code, rec_error_code; + int result; + + assert(connection != NULL); + result = 0; + error_code = -1; + + result = send_credentials(connection, CET_READ_REQUEST); + if (result != 0) + goto fin; + + name_size = strlen(entry_name); + result = safe_write(connection, &name_size, sizeof(size_t)); + if (result != 0) + goto fin; + + result = safe_write(connection, &key_size, sizeof(size_t)); + if (result != 0) + goto fin; + + result = safe_write(connection, entry_name, name_size); + if (result != 0) + goto fin; + + result = safe_write(connection, key, key_size); + if (result != 0) + goto fin; + + result = safe_read(connection, &rec_error_code, sizeof(int)); + if (result != 0) + goto fin; + + if (rec_error_code != 0) { + error_code = rec_error_code; + goto fin; + } + + result = safe_read(connection, &result_size, sizeof(size_t)); + if (result != 0) + goto fin; + + if (result_size > *data_size) { + *data_size = result_size; + error_code = -2; + goto fin; + } + + result = safe_read(connection, data, result_size); + if (result != 0) + goto fin; + + *data_size = result_size; + error_code = 0; + +fin: + return (error_code); +} + +/* + * Initializes the mp_write_session. For such a session the new connection + * would be opened. The data should be written to the session with + * __cached_mp_write function. The __close_cached_mp_write_session function + * should be used to submit session and __abandon_cached_mp_write_session - to + * abandon it. When the session is submitted, the whole se + */ +struct cached_connection_ * +__open_cached_mp_write_session(struct cached_connection_params const *params, + const char *entry_name) +{ + struct cached_connection_ *connection, *retval; + size_t name_size; + int error_code; + int result; + + retval = NULL; + connection = __open_cached_connection(params); + if (connection == NULL) + return (NULL); + connection->mp_flag = 1; + + result = send_credentials(connection, CET_MP_WRITE_SESSION_REQUEST); + if (result != 0) + goto fin; + + name_size = strlen(entry_name); + result = safe_write(connection, &name_size, sizeof(size_t)); + if (result != 0) + goto fin; + + result = safe_write(connection, entry_name, name_size); + if (result != 0) + goto fin; + + result = safe_read(connection, &error_code, sizeof(int)); + if (result != 0) + goto fin; + + if (error_code != 0) + result = error_code; + +fin: + if (result != 0) + __close_cached_connection(connection); + else + retval = connection; + return (retval); +} + +/* + * Adds new portion of data to the opened write session + */ +int +__cached_mp_write(struct cached_connection_ *ws, const char *data, + size_t data_size) +{ + int request, result; + int error_code; + + error_code = -1; + + request = CET_MP_WRITE_SESSION_WRITE_REQUEST; + result = safe_write(ws, &request, sizeof(int)); + if (result != 0) + goto fin; + + result = safe_write(ws, &data_size, sizeof(size_t)); + if (result != 0) + goto fin; + + result = safe_write(ws, data, data_size); + if (result != 0) + goto fin; + + result = safe_read(ws, &error_code, sizeof(int)); + if (result != 0) + error_code = -1; + +fin: + return (error_code); +} + +/* + * Abandons all operations with the write session. All data, that were written + * to the session before, are discarded. + */ +int +__abandon_cached_mp_write_session(struct cached_connection_ *ws) +{ + int notification; + int result; + + notification = CET_MP_WRITE_SESSION_ABANDON_NOTIFICATION; + result = safe_write(ws, ¬ification, sizeof(int)); + __close_cached_connection(ws); + return (result); +} + +/* + * Gracefully closes the write session. The data, that were previously written + * to the session, are committed. + */ +int +__close_cached_mp_write_session(struct cached_connection_ *ws) +{ + int notification; + int result; + + notification = CET_MP_WRITE_SESSION_CLOSE_NOTIFICATION; + result = safe_write(ws, ¬ification, sizeof(int)); + __close_cached_connection(ws); + return (0); +} + +struct cached_connection_ * +__open_cached_mp_read_session(struct cached_connection_params const *params, + const char *entry_name) +{ + struct cached_connection_ *connection, *retval; + size_t name_size; + int error_code; + int result; + + retval = NULL; + connection = __open_cached_connection(params); + if (connection == NULL) + return (NULL); + connection->mp_flag = 1; + + result = send_credentials(connection, CET_MP_READ_SESSION_REQUEST); + if (result != 0) + goto fin; + + name_size = strlen(entry_name); + result = safe_write(connection, &name_size, sizeof(size_t)); + if (result != 0) + goto fin; + + result = safe_write(connection, entry_name, name_size); + if (result != 0) + goto fin; + + result = safe_read(connection, &error_code, sizeof(int)); + if (result != 0) + goto fin; + + if (error_code != 0) + result = error_code; + +fin: + if (result != 0) + __close_cached_connection(connection); + else + retval = connection; + return (retval); +} + +int +__cached_mp_read(struct cached_connection_ *rs, char *data, size_t *data_size) +{ + size_t result_size; + int error_code, rec_error_code; + int request, result; + + error_code = -1; + request = CET_MP_READ_SESSION_READ_REQUEST; + result = safe_write(rs, &request, sizeof(int)); + if (result != 0) + goto fin; + + result = safe_read(rs, &rec_error_code, sizeof(int)); + if (result != 0) + goto fin; + + if (rec_error_code != 0) { + error_code = rec_error_code; + goto fin; + } + + result = safe_read(rs, &result_size, sizeof(size_t)); + if (result != 0) + goto fin; + + if (result_size > *data_size) { + *data_size = result_size; + error_code = -2; + goto fin; + } + + result = safe_read(rs, data, result_size); + if (result != 0) + goto fin; + + *data_size = result_size; + error_code = 0; + +fin: + return (error_code); +} + +int +__close_cached_mp_read_session(struct cached_connection_ *rs) +{ + + __close_cached_connection(rs); + return (0); +} diff --git a/lib/libc/net/nsdispatch.3 b/lib/libc/net/nsdispatch.3 new file mode 100644 index 0000000..aa3dd30 --- /dev/null +++ b/lib/libc/net/nsdispatch.3 @@ -0,0 +1,257 @@ +.\" $NetBSD: nsdispatch.3,v 1.8 1999/03/22 19:44:53 garbled Exp $ +.\" +.\" Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Luke Mewburn. +.\" +.\" 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. +.\" 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/nsdispatch.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.Dd April 4, 2010 +.Dt NSDISPATCH 3 +.Os +.Sh NAME +.Nm nsdispatch +.Nd name-service switch dispatcher routine +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In stdarg.h +.In nsswitch.h +.Ft int +.Fo nsdispatch +.Fa "void *retval" +.Fa "const ns_dtab dtab[]" +.Fa "const char *database" +.Fa "const char *method_name" +.Fa "const ns_src defaults[]" +.Fa "..." +.Fc +.Sh DESCRIPTION +The +.Fn nsdispatch +function invokes the methods specified in +.Va dtab +in the order given by +.Xr nsswitch.conf 5 +for the database +.Va database +until a successful entry is found. +.Pp +.Va retval +is passed to each method to modify as necessary, to pass back results to +the caller of +.Fn nsdispatch . +.Pp +Each method has the function signature described by the typedef: +.Pp +.Ft typedef int +.Fn \*(lp*nss_method\*(rp "void *retval" "void *mdata" "va_list *ap" ; +.Pp +.Va dtab +is an array of +.Va ns_dtab +structures, which have the following format: +.Bd -literal -offset indent +typedef struct _ns_dtab { + const char *src; + nss_method method; + void *mdata; +} ns_dtab; +.Ed +.Pp +The +.Fa dtab +array should consist of one entry for each source type that is +implemented, with +.Va src +as the name of the source, +.Va method +as a function which handles that source, and +.Va mdata +as a handle on arbitrary data to be passed to the method. +The last entry in +.Va dtab +should contain +.Dv NULL +values for +.Va src , +.Va method , +and +.Va mdata . +.Pp +Additionally, methods may be implemented in NSS modules, in +which case they are selected using the +.Fa database +and +.Fa method_name +arguments along with the configured source. +(The methods supplied via +.Fa dtab +take priority over those implemented in NSS modules in the event +of a conflict.) +.Pp +.Va defaults +contains a list of default sources to try if +.Xr nsswitch.conf 5 +is missing or corrupted, or if there is no relevant entry for +.Va database . +It is an array of +.Va ns_src +structures, which have the following format: +.Bd -literal -offset indent +typedef struct _ns_src { + const char *src; + uint32_t flags; +} ns_src; +.Ed +.Pp +The +.Fa defaults +array should consist of one entry for each source to be configured by +default indicated by +.Va src , +and +.Va flags +set to the criterion desired +(usually +.Dv NS_SUCCESS ; +refer to +.Sx Method return values +for more information). +The last entry in +.Va defaults +should have +.Va src +set to +.Dv NULL +and +.Va flags +set to 0. +.Pp +For convenience, a global variable defined as: +.Pp +.Dl extern const ns_src __nsdefaultsrc[]; +.Pp +exists which contains a single default entry for the source +.Sq files +that may be used by callers which do not require complicated default +rules. +.Pp +.Sq Va ... +are optional extra arguments, which are passed to the appropriate method +as a variable argument list of the type +.Vt va_list . +.Ss Valid source types +While there is support for arbitrary sources, the following +#defines for commonly implemented sources are available: +.Bl -column NSSRC_COMPAT compat -offset indent +.It Sy "#define value" +.It Dv NSSRC_FILES Ta \&"files\&" +.It Dv NSSRC_DB Ta \&"db\&" +.It Dv NSSRC_DNS Ta \&"dns\&" +.It Dv NSSRC_NIS Ta \&"nis\&" +.It Dv NSSRC_COMPAT Ta \&"compat\&" +.El +.Pp +Refer to +.Xr nsswitch.conf 5 +for a complete description of what each source type is. +.Ss Method return values +The +.Vt nss_method +functions must return one of the following values depending upon status +of the lookup: +.Bl -column "Return value" "Status code" +.It Sy "Return value Status code" +.It Dv NS_SUCCESS Ta success +.It Dv NS_NOTFOUND Ta notfound +.It Dv NS_UNAVAIL Ta unavail +.It Dv NS_TRYAGAIN Ta tryagain +.It Dv NS_RETURN Ta -none- +.El +.Pp +Refer to +.Xr nsswitch.conf 5 +for a complete description of each status code. +.Pp +The +.Fn nsdispatch +function returns the value of the method that caused the dispatcher to +terminate, or +.Dv NS_NOTFOUND +otherwise. +.Sh NOTES +.Fx Ns 's +.Lb libc +provides stubs for compatibility with NSS modules +written for the +.Tn GNU +C Library +.Nm nsswitch +interface. +However, these stubs only support the use of the +.Dq Li passwd +and +.Dq Li group +databases. +.Sh SEE ALSO +.Xr hesiod 3 , +.Xr stdarg 3 , +.Xr nsswitch.conf 5 , +.Xr yp 8 +.Sh HISTORY +The +.Fn nsdispatch +function first appeared in +.Fx 5.0 . +It was imported from the +.Nx +Project, +where it appeared first in +.Nx 1.4 . +Support for NSS modules first appeared in +.Fx 5.1 . +.Sh AUTHORS +.An Luke Mewburn Aq Mt lukem@netbsd.org +wrote this freely-distributable name-service switch implementation, +using ideas from the +.Tn ULTRIX +svc.conf(5) +and +.Tn Solaris +nsswitch.conf(4) +manual pages. +The +.Fx +Project +added the support for threads and NSS modules, and normalized the uses +of +.Fn nsdispatch +within the standard C library. diff --git a/lib/libc/net/ntoh.c b/lib/libc/net/ntoh.c new file mode 100644 index 0000000..1e92778 --- /dev/null +++ b/lib/libc/net/ntoh.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 2006 Olivier Houchard + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/net/ntoh.c 288012 2015-09-20 04:15:37Z rodrigc $"); + +#include +#define _BYTEORDER_FUNC_DEFINED +#include + +uint32_t +htonl(uint32_t hl) +{ + + return (__htonl(hl)); +} + +uint16_t +htons(uint16_t hs) +{ + + return (__htons(hs)); +} + +uint32_t +ntohl(uint32_t nl) +{ + + return (__ntohl(nl)); +} + +uint16_t +ntohs(uint16_t ns) +{ + + return (__ntohs(ns)); +} diff --git a/lib/libc/net/rcmd.3 b/lib/libc/net/rcmd.3 new file mode 100644 index 0000000..a5b2bbf --- /dev/null +++ b/lib/libc/net/rcmd.3 @@ -0,0 +1,306 @@ +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" From: @(#)rcmd.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/net/rcmd.3 189208 2009-03-01 05:47:14Z delphij $ +.\" +.Dd March 3, 2000 +.Dt RCMD 3 +.Os +.Sh NAME +.Nm rcmd , +.Nm rresvport , +.Nm iruserok , +.Nm ruserok , +.Nm rcmd_af , +.Nm rresvport_af , +.Nm iruserok_sa +.Nd routines for returning a stream to a remote command +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" +.Ft int +.Fn rresvport "int *port" +.Ft int +.Fn iruserok "u_long raddr" "int superuser" "const char *ruser" "const char *luser" +.Ft int +.Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser" +.Ft int +.Fn rcmd_af "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p" "int af" +.Ft int +.Fn rresvport_af "int *port" "int af" +.Ft int +.Fn iruserok_sa "const void *addr" "int addrlen" "int superuser" "const char *ruser" "const char *luser" +.Sh DESCRIPTION +The +.Fn rcmd +function +is used by the super-user to execute a command on +a remote machine using an authentication scheme based +on reserved port numbers. +The +.Fn rresvport +function +returns a descriptor to a socket +with an address in the privileged port space. +The +.Fn ruserok +function +is used by servers +to authenticate clients requesting service with +.Fn rcmd . +All three functions are present in the same file and are used +by the +.Xr rshd 8 +server (among others). +.Pp +The +.Fn rcmd +function +looks up the host +.Fa *ahost +using +.Xr gethostbyname 3 , +returning -1 if the host does not exist. +Otherwise +.Fa *ahost +is set to the standard name of the host +and a connection is established to a server +residing at the well-known Internet port +.Fa inport . +.Pp +If the connection succeeds, +a socket in the Internet domain of type +.Dv SOCK_STREAM +is returned to the caller, and given to the remote +command as +.Dv stdin +and +.Dv stdout . +If +.Fa fd2p +is non-zero, then an auxiliary channel to a control +process will be set up, and a descriptor for it will be placed +in +.Fa *fd2p . +The control process will return diagnostic +output from the command (unit 2) on this channel, and will also +accept bytes on this channel as being +.Ux +signal numbers, to be +forwarded to the process group of the command. +If +.Fa fd2p +is 0, then the +.Dv stderr +(unit 2 of the remote +command) will be made the same as the +.Dv stdout +and no +provision is made for sending arbitrary signals to the remote process, +although you may be able to get its attention by using out-of-band data. +.Pp +The protocol is described in detail in +.Xr rshd 8 . +.Pp +The +.Fn rresvport +function is used to obtain a socket to which an address with a Privileged +Internet port is bound. +This socket is suitable for use by +.Fn rcmd +and several other functions. +Privileged Internet ports are those in the range 0 to 1023. +Only the super-user is allowed to bind an address of this sort +to a socket. +.Pp +The +.Fn iruserok +and +.Fn ruserok +functions take a remote host's IP address or name, as returned by the +.Xr gethostbyname 3 +routines, two user names and a flag indicating whether the local user's +name is that of the super-user. +Then, if the user is +.Em NOT +the super-user, it checks the +.Pa /etc/hosts.equiv +file. +If that lookup is not done, or is unsuccessful, the +.Pa .rhosts +in the local user's home directory is checked to see if the request for +service is allowed. +.Pp +If this file does not exist, is not a regular file, is owned by anyone +other than the user or the super-user, or is writable by anyone other +than the owner, the check automatically fails. +Zero is returned if the machine name is listed in the +.Dq Pa hosts.equiv +file, or the host and remote user name are found in the +.Dq Pa .rhosts +file; otherwise +.Fn iruserok +and +.Fn ruserok +return -1. +If the local domain (as obtained from +.Xr gethostname 3 ) +is the same as the remote domain, only the machine name need be specified. +.Pp +The +.Fn iruserok +function is strongly preferred for security reasons. +It requires trusting the local DNS at most, while the +.Fn ruserok +function requires trusting the entire DNS, which can be spoofed. +.Pp +The functions with an +.Dq Li _af +or +.Dq Li _sa +suffix, i.e., +.Fn rcmd_af , +.Fn rresvport_af +and +.Fn iruserok_sa , +work the same as the corresponding functions without a +suffix, except that they are capable of handling both IPv6 and IPv4 ports. +.Pp +The +.Dq Li _af +suffix means that the function has an additional +.Fa af +argument which is used to specify the address family, +(see below). +The +.Fa af +argument extension is implemented for functions +that have no binary address argument. +Instead, the +.Fa af +argument specifies which address family is desired. +.Pp +The +.Dq Li _sa +suffix means that the function has general socket address and +length arguments. +As the socket address is a protocol independent data structure, +IPv4 and IPv6 socket address can be passed as desired. +The +.Fa sa +argument extension is implemented for functions +that pass a protocol dependent binary address argument. +The argument needs to be replaced with a more general address structure +to support multiple address families in a general way. +.Pp +The functions with neither an +.Dq Li _af +suffix nor an +.Dq Li _sa +suffix work for IPv4 only, except for +.Fn ruserok +which can handle both IPv6 and IPv4. +To switch the address family, the +.Fa af +argument must be filled with +.Dv AF_INET , +or +.Dv AF_INET6 . +For +.Fn rcmd_af , +.Dv PF_UNSPEC +is also allowed. +.Sh ENVIRONMENT +.Bl -tag -width RSH +.It Ev RSH +When using the +.Fn rcmd +function, this variable is used as the program to run instead of +.Xr rsh 1 . +.El +.Sh DIAGNOSTICS +The +.Fn rcmd +function +returns a valid socket descriptor on success. +It returns -1 on error and prints a diagnostic message +on the standard error. +.Pp +The +.Fn rresvport +function +returns a valid, bound socket descriptor on success. +It returns -1 on error with the global value +.Va errno +set according to the reason for failure. +The error code +.Er EAGAIN +is overloaded to mean ``All network ports in use.'' +.Sh SEE ALSO +.Xr rlogin 1 , +.Xr rsh 1 , +.Xr intro 2 , +.Xr rlogind 8 , +.Xr rshd 8 +.Pp +.Rs +.%A W. Stevens +.%A M. Thomas +.%T "Advanced Socket API for IPv6" +.%O RFC2292 +.Re +.Rs +.%A W. Stevens +.%A M. Thomas +.%A E. Nordmark +.%T "Advanced Socket API for IPv6" +.%O RFC3542 +.Re +.Sh HISTORY +Most of these +functions appeared in +.Bx 4.2 . +The +.Fn rresvport_af +function +appeared in RFC2292, and was implemented by the WIDE project +for the Hydrangea IPv6 protocol stack kit. +The +.Fn rcmd_af +function +appeared in draft-ietf-ipngwg-rfc2292bis-01.txt, +and was implemented in the WIDE/KAME IPv6 protocol stack kit. +The +.Fn iruserok_sa +function +appeared in discussion on the IETF ipngwg mailing list, +and was implemented in +.Fx 4.0 . diff --git a/lib/libc/net/rcmdsh.3 b/lib/libc/net/rcmdsh.3 new file mode 100644 index 0000000..8d3da9a --- /dev/null +++ b/lib/libc/net/rcmdsh.3 @@ -0,0 +1,116 @@ +.\" $OpenBSD: rcmdsh.3,v 1.6 1999/07/05 04:41:00 aaron Exp $ +.\" +.\" Copyright (c) 1983, 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. +.\" 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/rcmdsh.3 165903 2007-01-09 00:28:16Z imp $ +.\" +.Dd September 1, 1996 +.Dt RCMDSH 3 +.Os +.Sh NAME +.Nm rcmdsh +.Nd return a stream to a remote command without superuser +.Sh SYNOPSIS +.In unistd.h +.Ft int +.Fo rcmdsh +.Fa "char **ahost" +.Fa "int inport" +.Fa "const char *locuser" +.Fa "const char *remuser" +.Fa "const char *cmd" +.Fa "const char *rshprog" +.Fc +.Sh DESCRIPTION +The +.Fn rcmdsh +function +is used by normal users to execute a command on +a remote machine using an authentication scheme based +on reserved port numbers using +.Xr rshd 8 +or the value of +.Fa rshprog +(if +.No non- Ns Dv NULL ) . +.Pp +The +.Fn rcmdsh +function +looks up the host +.Fa *ahost +using +.Xr gethostbyname 3 , +returning \-1 if the host does not exist. +Otherwise +.Fa *ahost +is set to the standard name of the host +and a connection is established to a server +residing at the well-known Internet port +.Dq Li shell/tcp +(or whatever port is used by +.Fa rshprog ) . +The +.Fa inport +argument +is ignored; it is only included to provide an interface similar to +.Xr rcmd 3 . +.Pp +If the connection succeeds, +a socket in the +.Ux +domain of type +.Dv SOCK_STREAM +is returned to the caller, and given to the remote +command as +.Dv stdin , stdout , +and +.Dv stderr . +.Sh RETURN VALUES +The +.Fn rcmdsh +function +returns a valid socket descriptor on success. +Otherwise, \-1 is returned +and a diagnostic message is printed on the standard error. +.Sh SEE ALSO +.Xr rsh 1 , +.Xr socketpair 2 , +.Xr rcmd 3 , +.Xr rshd 8 +.Sh HISTORY +The +.Fn rcmdsh +function first appeared in +.Ox 2.0 , +and made its way into +.Fx 4.6 . +.Sh BUGS +If +.Xr rsh 1 +encounters an error, a file descriptor is still returned instead of \-1. diff --git a/lib/libc/net/resolver.3 b/lib/libc/net/resolver.3 new file mode 100644 index 0000000..fb9cc4c --- /dev/null +++ b/lib/libc/net/resolver.3 @@ -0,0 +1,461 @@ +.\" Copyright (c) 1985, 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. +.\" 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. +.\" +.\" @(#)resolver.3 8.1 (Berkeley) 6/4/93 +.\" $FreeBSD: releng/11.1/lib/libc/net/resolver.3 193024 2009-05-29 07:55:44Z delphij $ +.\" +.Dd May 29, 2009 +.Dt RESOLVER 3 +.Os +.Sh NAME +.Nm res_query , +.Nm res_search , +.Nm res_mkquery , +.Nm res_send , +.Nm res_init , +.Nm dn_comp , +.Nm dn_expand , +.Nm dn_skipname , +.Nm ns_get16 , +.Nm ns_get32 , +.Nm ns_put16 , +.Nm ns_put32 +.Nd resolver routines +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In netinet/in.h +.In arpa/nameser.h +.In resolv.h +.Ft int +.Fo res_query +.Fa "const char *dname" +.Fa "int class" +.Fa "int type" +.Fa "u_char *answer" +.Fa "int anslen" +.Fc +.Ft int +.Fo res_search +.Fa "const char *dname" +.Fa "int class" +.Fa "int type" +.Fa "u_char *answer" +.Fa "int anslen" +.Fc +.Ft int +.Fo res_mkquery +.Fa "int op" +.Fa "const char *dname" +.Fa "int class" +.Fa "int type" +.Fa "const u_char *data" +.Fa "int datalen" +.Fa "const u_char *newrr_in" +.Fa "u_char *buf" +.Fa "int buflen" +.Fc +.Ft int +.Fo res_send +.Fa "const u_char *msg" +.Fa "int msglen" +.Fa "u_char *answer" +.Fa "int anslen" +.Fc +.Ft int +.Fn res_init void +.Ft int +.Fo dn_comp +.Fa "const char *exp_dn" +.Fa "u_char *comp_dn" +.Fa "int length" +.Fa "u_char **dnptrs" +.Fa "u_char **lastdnptr" +.Fc +.Ft int +.Fo dn_expand +.Fa "const u_char *msg" +.Fa "const u_char *eomorig" +.Fa "const u_char *comp_dn" +.Fa "char *exp_dn" +.Fa "int length" +.Fc +.Ft int +.Fn dn_skipname "const u_char *comp_dn" "const u_char *eom" +.Ft u_int +.Fn ns_get16 "const u_char *src" +.Ft u_long +.Fn ns_get32 "const u_char *src" +.Ft void +.Fn ns_put16 "u_int src" "u_char *dst" +.Ft void +.Fn ns_put32 "u_long src" "u_char *dst" +.Sh DESCRIPTION +These routines are used for making, sending and interpreting +query and reply messages with Internet domain name servers. +.Pp +Global configuration and state information that is used by the +resolver routines is kept in the structure +.Va _res . +Most of the values have reasonable defaults and can be ignored. +Options +stored in +.Va _res.options +are defined in +.In resolv.h +and are as follows. +Options are stored as a simple bit mask containing the bitwise ``or'' +of the options enabled. +.Bl -tag -width RES_USE_INET6 +.It Dv RES_INIT +True if the initial name server address and default domain name are +initialized (i.e., +.Fn res_init +has been called). +.It Dv RES_DEBUG +Print debugging messages. +.It Dv RES_AAONLY +Accept authoritative answers only. +With this option, +.Fn res_send +should continue until it finds an authoritative answer or finds an error. +Currently this is not implemented. +.It Dv RES_USEVC +Use +.Tn TCP +connections for queries instead of +.Tn UDP +datagrams. +.It Dv RES_STAYOPEN +Used with +.Dv RES_USEVC +to keep the +.Tn TCP +connection open between +queries. +This is useful only in programs that regularly do many queries. +.Tn UDP +should be the normal mode used. +.It Dv RES_IGNTC +Unused currently (ignore truncation errors, i.e., do not retry with +.Tn TCP ) . +.It Dv RES_RECURSE +Set the recursion-desired bit in queries. +This is the default. +.Pf ( Fn res_send +does not do iterative queries and expects the name server +to handle recursion.) +.It Dv RES_DEFNAMES +If set, +.Fn res_search +will append the default domain name to single-component names +(those that do not contain a dot). +This option is enabled by default. +.It Dv RES_DNSRCH +If this option is set, +.Fn res_search +will search for host names in the current domain and in parent domains; see +.Xr hostname 7 . +This is used by the standard host lookup routine +.Xr gethostbyname 3 . +This option is enabled by default. +.It Dv RES_NOALIASES +This option turns off the user level aliasing feature controlled by the +.Dq Ev HOSTALIASES +environment variable. +Network daemons should set this option. +.It Dv RES_USE_INET6 +Enables support for IPv6-only applications. +This causes IPv4 addresses to be returned as an IPv4 mapped address. +For example, +.Li 10.1.1.1 +will be returned as +.Li ::ffff:10.1.1.1 . +The option is meaningful with certain kernel configuration only. +.It Dv RES_USE_EDNS0 +Enables support for OPT pseudo-RR for EDNS0 extension. +With the option, resolver code will attach OPT pseudo-RR into DNS queries, +to inform of our receive buffer size. +The option will allow DNS servers to take advantage of non-default receive +buffer size, and to send larger replies. +DNS query packets with EDNS0 extension is not compatible with +non-EDNS0 DNS servers. +.El +.Pp +The +.Fn res_init +routine +reads the configuration file (if any; see +.Xr resolver 5 ) +to get the default domain name, +search list and +the Internet address of the local name server(s). +If no server is configured, the host running +the resolver is tried. +The current domain name is defined by the hostname +if not specified in the configuration file; +it can be overridden by the environment variable +.Ev LOCALDOMAIN . +This environment variable may contain several blank-separated +tokens if you wish to override the +.Em "search list" +on a per-process basis. +This is similar to the +.Ic search +command in the configuration file. +Another environment variable +.Dq Ev RES_OPTIONS +can be set to +override certain internal resolver options which are otherwise +set by changing fields in the +.Va _res +structure or are inherited from the configuration file's +.Ic options +command. +The syntax of the +.Dq Ev RES_OPTIONS +environment variable is explained in +.Xr resolver 5 . +Initialization normally occurs on the first call +to one of the following routines. +.Pp +The +.Fn res_query +function provides an interface to the server query mechanism. +It constructs a query, sends it to the local server, +awaits a response, and makes preliminary checks on the reply. +The query requests information of the specified +.Fa type +and +.Fa class +for the specified fully-qualified domain name +.Fa dname . +The reply message is left in the +.Fa answer +buffer with length +.Fa anslen +supplied by the caller. +.Pp +The +.Fn res_search +routine makes a query and awaits a response like +.Fn res_query , +but in addition, it implements the default and search rules +controlled by the +.Dv RES_DEFNAMES +and +.Dv RES_DNSRCH +options. +It returns the first successful reply. +.Pp +The remaining routines are lower-level routines used by +.Fn res_query . +The +.Fn res_mkquery +function +constructs a standard query message and places it in +.Fa buf . +It returns the size of the query, or \-1 if the query is +larger than +.Fa buflen . +The query type +.Fa op +is usually +.Dv QUERY , +but can be any of the query types defined in +.In arpa/nameser.h . +The domain name for the query is given by +.Fa dname . +The +.Fa newrr_in +argument +is currently unused but is intended for making update messages. +.Pp +The +.Fn res_send +routine +sends a pre-formatted query and returns an answer. +It will call +.Fn res_init +if +.Dv RES_INIT +is not set, send the query to the local name server, and +handle timeouts and retries. +The length of the reply message is returned, or +\-1 if there were errors. +.Pp +The +.Fn dn_comp +function +compresses the domain name +.Fa exp_dn +and stores it in +.Fa comp_dn . +The size of the compressed name is returned or \-1 if there were errors. +The size of the array pointed to by +.Fa comp_dn +is given by +.Fa length . +The compression uses +an array of pointers +.Fa dnptrs +to previously-compressed names in the current message. +The first pointer points to +the beginning of the message and the list ends with +.Dv NULL . +The limit to the array is specified by +.Fa lastdnptr . +A side effect of +.Fn dn_comp +is to update the list of pointers for +labels inserted into the message +as the name is compressed. +If +.Fa dnptr +is +.Dv NULL , +names are not compressed. +If +.Fa lastdnptr +is +.Dv NULL , +the list of labels is not updated. +.Pp +The +.Fn dn_expand +entry +expands the compressed domain name +.Fa comp_dn +to a full domain name +The compressed name is contained in a query or reply message; +.Fa msg +is a pointer to the beginning of the message. +The uncompressed name is placed in the buffer indicated by +.Fa exp_dn +which is of size +.Fa length . +The size of compressed name is returned or \-1 if there was an error. +.Pp +The +.Fn dn_skipname +function skips over a compressed domain name, which starts at a location +pointed to by +.Fa comp_dn . +The compressed name is contained in a query or reply message; +.Fa eom +is a pointer to the end of the message. +The size of compressed name is returned or \-1 if there was +an error. +.Pp +The +.Fn ns_get16 +function gets a 16-bit quantity from a buffer pointed to by +.Fa src . +.Pp +The +.Fn ns_get32 +function gets a 32-bit quantity from a buffer pointed to by +.Fa src . +.Pp +The +.Fn ns_put16 +function puts a 16-bit quantity +.Fa src +to a buffer pointed to by +.Fa dst . +.Pp +The +.Fn ns_put32 +function puts a 32-bit quantity +.Fa src +to a buffer pointed to by +.Fa dst . +.Sh IMPLEMENTATION NOTES +This implementation of the resolver is thread-safe, but it will not +function properly if the programmer attempts to declare his or her own +.Va _res +structure in an attempt to replace the per-thread version referred to +by that macro. +.Pp +The following compile-time option can be specified to change the default +behavior of resolver routines when necessary. +.Bl -tag -width RES_ENFORCE_RFC1034 +.It Dv RES_ENFORCE_RFC1034 +If this symbol is defined during compile-time, +.Fn res_search +will enforce RFC 1034 check, namely, disallow using of underscore character +within host names. +This is used by the standard host lookup routines like +.Xr gethostbyname 3 . +For compatibility reasons this option is not enabled by default. +.El +.Sh RETURN VALUES +The +.Fn res_init +function will return 0 on success, or \-1 in a threaded program if +per-thread storage could not be allocated. +.Pp +The +.Fn res_mkquery , +.Fn res_search , +and +.Fn res_query +functions return the size of the response on success, or \-1 if an +error occurs. +The integer +.Vt h_errno +may be checked to determine the reason for error. +See +.Xr gethostbyname 3 +for more information. +.Sh FILES +.Bl -tag -width /etc/resolv.conf +.It Pa /etc/resolv.conf +The configuration file, +see +.Xr resolver 5 . +.El +.Sh SEE ALSO +.Xr gethostbyname 3 , +.Xr resolver 5 , +.Xr hostname 7 , +.Xr named 8 +.Pp +.%T RFC1032 , +.%T RFC1033 , +.%T RFC1034 , +.%T RFC1035 , +.%T RFC974 +.Rs +.%T "Name Server Operations Guide for BIND" +.Re +.Sh HISTORY +The +.Nm +function appeared in +.Bx 4.3 . diff --git a/lib/libc/net/sctp_bindx.3 b/lib/libc/net/sctp_bindx.3 new file mode 100644 index 0000000..1089f61 --- /dev/null +++ b/lib/libc/net/sctp_bindx.3 @@ -0,0 +1,110 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94 +.\" $FreeBSD: releng/11.1/lib/libc/net/sctp_bindx.3 319618 2017-06-06 09:23:12Z trasz $ +.\" +.Dd June 14, 2015 +.Dt SCTP_BINDX 3 +.Os +.Sh NAME +.Nm sctp_bindx +.Nd bind or unbind an SCTP socket to a list of addresses +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netinet/sctp.h +.Ft int +.Fn sctp_bindx "int s" "struct sockaddr *addrs" "int num" "int type" +.Sh DESCRIPTION +The +.Fn sctp_bindx +call binds or unbinds a address or a list of addresses to an +SCTP endpoint. +This allows a user to bind a subset of +addresses. +The +.Fn sctp_bindx +call operates similarly to +.Fn bind +but allows a list of addresses and also allows a bind or an +unbind. +The argument +.Fa s +must be a valid SCTP socket descriptor. +The argument +.Fa addrs +is a list of addresses (where the list may be only 1 in +length) that the user wishes to bind or unbind to the +socket. +The argument +.Fa type +must be one of the following values. +.Pp +.Dv SCTP_BINDX_ADD_ADDR +This value indicates that the listed address(es) need to +be added to the endpoint. +.Pp +.Dv SCTP_BINDX_REM_ADDR +This value indicates that the listed address(es) need to +be removed from the endpoint. +.Pp +Note that when a user adds or deletes an address to an +association if the dynamic address flag +.Va net.inet.sctp.auto_asconf +is enabled any associations in the endpoint will attempt to +have the address(es) added dynamically to the existing +association. +.Sh RETURN VALUES +The call returns 0 on success and -1 upon failure. +.Sh ERRORS +The +.Fn sctp_bindx +function can return the following errors: +.Bl -tag -width Er +.It Bq Er EINVAL +This value is returned if the +.Fa type +field is not one of the allowed values (see above). +.It Bq Er ENOMEM +This value is returned if the number of addresses +being added causes a memory allocation failure in +the call. +.It Bq Er EBADF +The argument +.Fa s +is not a valid descriptor. +.It Bq Er ENOTSOCK +The argument +.Fa s +is not a socket. +.El +.Sh SEE ALSO +.Xr bind 2 , +.Xr sctp 4 diff --git a/lib/libc/net/sctp_connectx.3 b/lib/libc/net/sctp_connectx.3 new file mode 100644 index 0000000..84496e4 --- /dev/null +++ b/lib/libc/net/sctp_connectx.3 @@ -0,0 +1,102 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/sctp_connectx.3 251067 2013-05-28 20:37:48Z emaste $ +.\" +.Dd June 19, 2007 +.Dt SCTP_CONNECTX 3 +.Os +.Sh NAME +.Nm sctp_connectx +.Nd connect an SCTP socket with multiple destination addresses +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netinet/sctp.h +.Ft int +.Fn sctp_connectx "int sd" "struct sockaddr *addrs" "int addrcnt" "sctp_assoc_t *id" +.Sh DESCRIPTION +The +.Fn sctp_connectx +call attempts to initiate an association to a peer SCTP +endpoint. +The call operates similarly to +.Fn connect +but it also provides the ability to specify multiple destination +addresses for the peer. +This allows a fault tolerant method +of initiating an association. +When one of the peers addresses +is unreachable, the subsequent listed addresses will also be used +to set up the association with the peer. +.Pp +The user also needs to consider that any address listed in an +.Fn sctp_connectx +call is also considered "confirmed". +A confirmed address is one in +which the SCTP transport will trust is a part of the association +and it will not send a confirmation heartbeat to it with +a random nonce. +.Pp +If the peer SCTP stack does not list one or more of +the provided addresses in its response message then +the extra addresses sent in the +.Fn sctp_connectx +call will be silently discarded from the association. +On +successful completion the provided +.Fa id +will be +filled in with the association identification of the newly +forming association. +.Sh RETURN VALUES +The call returns 0 on success and -1 upon failure. +.Sh ERRORS +The +.Fn sctp_connectx +function can return the following errors: +.Bl -tag -width Er +.It Bq Er EINVAL +An address listed has an invalid family or no +addresses were provided. +.It Bq Er E2BIG +The size of the address list exceeds the amount of +data provided. +.It Bq Er EBADF +The argument +.Fa s +is not a valid descriptor. +.It Bq Er ENOTSOCK +The argument +.Fa s +is not a socket. +.El +.Sh SEE ALSO +.Xr connect 2 , +.Xr sctp 4 diff --git a/lib/libc/net/sctp_freepaddrs.3 b/lib/libc/net/sctp_freepaddrs.3 new file mode 100644 index 0000000..eb748a2 --- /dev/null +++ b/lib/libc/net/sctp_freepaddrs.3 @@ -0,0 +1,64 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94 +.\" $FreeBSD: releng/11.1/lib/libc/net/sctp_freepaddrs.3 251067 2013-05-28 20:37:48Z emaste $ +.\" +.Dd December 15, 2006 +.Dt SCTP_FREEPADDRS 3 +.Os +.Sh NAME +.Nm sctp_freepaddrs , +.Nm sctp_freeladdrs +.Nd release the memory returned from a previous call +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netinet/sctp.h +.Ft void +.Fn sctp_freepaddrs "struct sockaddr *" +.Ft void +.Fn sctp_freeladdrs "struct sockaddr *" +.Sh DESCRIPTION +The +.Fn sctp_freepaddrs +and +.Fn sctp_freeladdrs +functions are used to release the memory allocated by previous +calls to +.Fn sctp_getpaddrs +or +.Fn sctp_getladdrs +respectively. +.Sh RETURN VALUES +none. +.Sh SEE ALSO +.Xr sctp_getladdrs 3 , +.Xr sctp_getpaddrs 3 , +.Xr sctp 4 diff --git a/lib/libc/net/sctp_getaddrlen.3 b/lib/libc/net/sctp_getaddrlen.3 new file mode 100644 index 0000000..9b22049 --- /dev/null +++ b/lib/libc/net/sctp_getaddrlen.3 @@ -0,0 +1,83 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94 +.\" $FreeBSD: releng/11.1/lib/libc/net/sctp_getaddrlen.3 251067 2013-05-28 20:37:48Z emaste $ +.\" +.Dd December 15, 2006 +.Dt SCTP_GETADDRLEN 3 +.Os +.Sh NAME +.Nm sctp_getaddrlen +.Nd return the address length of an address family +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netinet/sctp.h +.Ft int +.Fn sctp_getaddrlen "sa_family_t family" +.Sh DESCRIPTION +The +.Fn sctp_getaddrlen +function returns the size of a specific address family. +This function +is provided for application binary compatibility since it +provides the application with the size the operating system +thinks the specific address family is. +Note that the function +will actually create an SCTP socket and then gather the +information via a +.Fn getsockopt +system calls. +If for some reason a SCTP socket cannot +be created or the +.Fn getsockopt +call fails, an error will be returned +with +.Va errno +set as specified in the +.Fn socket +or +.Fn getsockopt +system call. +.Sh RETURN VALUES +The call returns the number of bytes that the operating +system expects for the specific address family or -1. +.Sh ERRORS +The +.Fn sctp_getaddrlen +function can return the following errors: +.Bl -tag -width Er +.It Bq Er EINVAL +The address family specified does NOT exist. +.El +.Sh SEE ALSO +.Xr getsockopt 2 , +.Xr socket 2 , +.Xr sctp 4 diff --git a/lib/libc/net/sctp_getassocid.3 b/lib/libc/net/sctp_getassocid.3 new file mode 100644 index 0000000..29bdd0f --- /dev/null +++ b/lib/libc/net/sctp_getassocid.3 @@ -0,0 +1,70 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/sctp_getassocid.3 319618 2017-06-06 09:23:12Z trasz $ +.\" +.Dd December 15, 2006 +.Dt SCTP_GETASSOCID 3 +.Os +.Sh NAME +.Nm sctp_getassocid +.Nd return an association id for a specified socket address +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netinet/sctp.h +.Ft sctp_assoc_t +.Fn sctp_getassocid "int s" "struct sockaddr *addr" +.Sh DESCRIPTION +The +.Fn sctp_getassocid +call attempts to look up the specified socket address +.Fa addr +and find the respective association identification. +.Sh RETURN VALUES +The call returns the association id upon success and +0 is returned upon failure. +.Sh ERRORS +The +.Fn sctp_getassocid +function can return the following errors: +.Bl -tag -width Er +.It Bq Er ENOENT +The address does not have an association setup to it. +.It Bq Er EBADF +The argument +.Fa s +is not a valid descriptor. +.It Bq Er ENOTSOCK +The argument +.Fa s +is not a socket. +.El +.Sh SEE ALSO +.Xr sctp 4 diff --git a/lib/libc/net/sctp_getpaddrs.3 b/lib/libc/net/sctp_getpaddrs.3 new file mode 100644 index 0000000..9e58256 --- /dev/null +++ b/lib/libc/net/sctp_getpaddrs.3 @@ -0,0 +1,96 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94 +.\" $FreeBSD: releng/11.1/lib/libc/net/sctp_getpaddrs.3 251067 2013-05-28 20:37:48Z emaste $ +.\" +.Dd December 15, 2006 +.Dt SCTP_GETPADDRS 3 +.Os +.Sh NAME +.Nm sctp_getpaddrs , +.Nm sctp_getladdrs +.Nd return a list of addresses to the caller +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netinet/sctp.h +.Ft int +.Fn sctp_getpaddrs "int s" "sctp_assoc_t asocid" "struct sockaddr **addrs" +.Ft int +.Fn sctp_getladdrs "int s" "sctp_assoc_t asocid" "struct sockaddr **addrs" +.Sh DESCRIPTION +The +.Fn sctp_getpaddrs +function is used to get the list of the peers addresses. +The +.Fn sctp_getladdrs +function is used to get the list of the local addresses. +The association of interest is identified by the +.Fa asocid +argument. +The addresses are returned in a newly allocated +array of socket addresses returned in the argument +.Fa addrs +upon success. +.Pp +After the caller is finished, the function +.Fn sctp_freepaddrs +or +.Fn sctp_freeladdrs +should be used to release the memory allocated by these +calls. +.Sh RETURN VALUES +The call returns -1 upon failure and a count of +the number of addresses returned in +.Fa addrs +upon success. +.Sh ERRORS +The functions can return the following errors: +.Bl -tag -width Er +.It Bq Er EINVAL +An address listed has an invalid family or no +addresses were provided. +.It Bq Er ENOMEM +The call cannot allocate memory to hold the +socket addresses. +.It Bq Er EBADF +The argument +.Fa s +is not a valid descriptor. +.It Bq Er ENOTSOCK +The argument +.Fa s +is not a socket. +.El +.Sh SEE ALSO +.Xr getsockopt 2 , +.Xr sctp_freeladdrs 3 , +.Xr sctp_freepaddrs 3 , +.Xr sctp 4 diff --git a/lib/libc/net/sctp_opt_info.3 b/lib/libc/net/sctp_opt_info.3 new file mode 100644 index 0000000..39ebe6d --- /dev/null +++ b/lib/libc/net/sctp_opt_info.3 @@ -0,0 +1,140 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94 +.\" $FreeBSD: releng/11.1/lib/libc/net/sctp_opt_info.3 251067 2013-05-28 20:37:48Z emaste $ +.\" +.Dd June 18, 2011 +.Dt SCTP_OPT_INFO 3 +.Os +.Sh NAME +.Nm sctp_opt_info +.Nd get SCTP socket information +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netinet/sctp.h +.Ft int +.Fn sctp_opt_info "int sd" "sctp_assoc_t id" "int opt" "void *arg" "socklen_t *size" +.Sh DESCRIPTION +The +.Fn sctp_opt_info +call provides a multi-os compatible method for getting +specific +.Fn getsockopt +data where an association identification needs to be passed +into the operating system. +For +.Fx +a direct +.Fn getsockopt +may be used, since +.Fx +has the ability to pass information +into the operating system on a +.Fn getsockopt +call. +Other operating systems may not have this ability. +For those +who wish to write portable code amongst multiple operating systems +this call should be used for the following SCTP +socket options. +.Pp +.Dv SCTP_RTOINFO +.Pp +.Dv SCTP_ASSOCINFO +.Pp +.Dv SCTP_PRIMARY_ADDR +.Pp +.Dv SCTP_PEER_ADDR_PARAMS +.Pp +.Dv SCTP_DEFAULT_SEND_PARAM +.Pp +.Dv SCTP_MAX_SEG +.Pp +.Dv SCTP_AUTH_ACTIVE_KEY +.Pp +.Dv SCTP_DELAYED_SACK +.Pp +.Dv SCTP_MAX_BURST +.Pp +.Dv SCTP_CONTEXT +.Pp +.Dv SCTP_EVENT +.Pp +.Dv SCTP_DEFAULT_SNDINFO +.Pp +.Dv SCTP_DEFAULT_PRINFO +.Pp +.Dv SCTP_STATUS +.Pp +.Dv SCTP_GET_PEER_ADDR_INFO +.Pp +.Dv SCTP_PEER_AUTH_CHUNKS +.Pp +.Dv SCTP_LOCAL_AUTH_CHUNKS +.Sh RETURN VALUES +The call returns 0 on success and -1 upon error. +.Sh ERRORS +The +.Fn sctp_opt_info +function can return the following errors: +.Bl -tag -width Er +.It Bq Er EINVAL +The argument +.Fa arg +value was invalid. +.It Bq Er EOPNOTSUPP +The argument +.Fa opt +was not one of the above listed SCTP socket +options. +.It Bq Er EBADF +The argument +.Fa s +is not a valid descriptor. +.It Bq Er ENOTSOCK +The argument +.Fa s +is not a socket. +.El +.Sh SEE ALSO +.Xr getsockopt 2 , +.Xr sctp 4 +.Sh BUGS +Because the structure used for +.Fa arg +of the +.Dv SCTP_MAX_BURST +socket option has changed in FreeBSD 9.0 and higher, +using +.Dv SCTP_MAX_BURST +as +.Fa opt +is only supported in FreeBSD 9.0 and higher. diff --git a/lib/libc/net/sctp_recvmsg.3 b/lib/libc/net/sctp_recvmsg.3 new file mode 100644 index 0000000..d5bedd3 --- /dev/null +++ b/lib/libc/net/sctp_recvmsg.3 @@ -0,0 +1,294 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/sctp_recvmsg.3 296200 2016-02-29 17:19:15Z trasz $ +.\" +.Dd April 23, 2015 +.Dt SCTP_RECVMSG 3 +.Os +.Sh NAME +.Nm sctp_recvmsg +.Nd receive a message from an SCTP socket +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netinet/sctp.h +.Ft ssize_t +.Fo sctp_recvmsg +.Fa "int s" "void *msg" "size_t len" "struct sockaddr * restrict from" +.Fa "socklen_t * restrict fromlen" "struct sctp_sndrcvinfo *sinfo" "int *flags" +.Fc +.Sh DESCRIPTION +The +.Fn sctp_recvmsg +system call +is used to receive a message from another SCTP endpoint. +The +.Fn sctp_recvmsg +call is used by one-to-one (SOCK_STREAM) type sockets after a +successful +.Fn connect +call or after the application has performed a +.Fn listen +followed by a successful +.Fn accept . +For a one-to-many (SOCK_SEQPACKET) type socket, an endpoint may call +.Fn sctp_recvmsg +after having implicitly started an association via one +of the send calls including +.Fn sctp_sendmsg , +.Fn sendto +and +.Fn sendmsg . +Or, an application may also receive a message after having +called +.Fn listen +with a positive backlog to enable the reception of new associations. +.Pp +The address of the sender is held in the +.Fa from +argument with +.Fa fromlen +specifying its size. +At the completion of a successful +.Fn sctp_recvmsg +call +.Fa from +will hold the address of the peer and +.Fa fromlen +will hold the length of that address. +Note that +the address is bounded by the initial value of +.Fa fromlen +which is used as an in/out variable. +.Pp +The length of the message +.Fa msg +to be received is bounded by +.Fa len . +If the message is too long to fit in the users +receive buffer, then the +.Fa flags +argument will +.Em not +have the +.Dv MSG_EOR +flag applied. +If the message is a complete message then +the +.Fa flags +argument will have +.Dv MSG_EOR +set. +Locally detected errors are +indicated by a return value of -1 with +.Va errno +set accordingly. +The +.Fa flags +argument may also hold the value +.Dv MSG_NOTIFICATION . +When this +occurs it indicates that the message received is +.Em not +from +the peer endpoint, but instead is a notification from the +SCTP stack (see +.Xr sctp 4 +for more details). +Note that no notifications are ever +given unless the user subscribes to such notifications using +the +.Dv SCTP_EVENTS +socket option. +.Pp +If no messages are available at the socket then +.Fn sctp_recvmsg +normally blocks on the reception of a message or NOTIFICATION, unless the +socket has been placed in non-blocking I/O mode. +The +.Xr select 2 +system call may be used to determine when it is possible to +receive a message. +.Pp +The +.Fa sinfo +argument is defined as follows. +.Bd -literal +struct sctp_sndrcvinfo { + uint16_t sinfo_stream; /* Stream arriving on */ + uint16_t sinfo_ssn; /* Stream Sequence Number */ + uint16_t sinfo_flags; /* Flags on the incoming message */ + uint32_t sinfo_ppid; /* The ppid field */ + uint32_t sinfo_context; /* context field */ + uint32_t sinfo_timetolive; /* not used by sctp_recvmsg */ + uint32_t sinfo_tsn; /* The transport sequence number */ + uint32_t sinfo_cumtsn; /* The cumulative acknowledgment point */ + sctp_assoc_t sinfo_assoc_id; /* The association id of the peer */ +}; +.Ed +.Pp +The +.Fa sinfo->sinfo_ppid +field is an opaque 32 bit value that is passed transparently +through the stack from the peer endpoint. +Note that the stack passes this value without regard to byte +order. +.Pp +The +.Fa sinfo->sinfo_flags +field may include the following: +.Bd -literal +#define SCTP_UNORDERED 0x0400 /* Message is un-ordered */ +.Ed +.Pp +The +.Dv SCTP_UNORDERED +flag is used to specify that the message arrived with no +specific order and was delivered to the peer application +as soon as possible. +When this flag is absent the message +was delivered in order within the stream it was received. +.Pp +The +.Fa sinfo->sinfo_stream +field is the SCTP stream that the message was received on. +Streams in SCTP are reliable (or partially reliable) flows of ordered +messages. +.Pp +The +.Fa sinfo->sinfo_context +field is used only if the local application set an association level +context with the +.Dv SCTP_CONTEXT +socket option. +Optionally a user process can use this value to index some application +specific data structure for all data coming from a specific +association. +.Pp +The +.Fa sinfo->sinfo_ssn +field will hold the stream sequence number assigned +by the peer endpoint if the message is +.Em not +unordered. +For unordered messages this field holds an undefined value. +.Pp +The +.Fa sinfo->sinfo_tsn +field holds a transport sequence number (TSN) that was assigned +to this message by the peer endpoint. +For messages that fit in or less +than the path MTU this will be the only TSN assigned. +Note that for messages that span multiple TSNs this +value will be one of the TSNs that was used on the +message. +.Pp +The +.Fa sinfo->sinfo_cumtsn +field holds the current cumulative acknowledgment point of +the transport association. +Note that this may be larger +or smaller than the TSN assigned to the message itself. +.Pp +The +.Fa sinfo->sinfo_assoc_id +is the unique association identification that was assigned +to the association. +For one-to-many (SOCK_SEQPACKET) type +sockets this value can be used to send data to the peer without +the use of an address field. +It is also quite useful in +setting various socket options on the specific association +(see +.Xr sctp 4 ) . +.Pp +The +.Fa sinfo->info_timetolive +field is not used by +.Fn sctp_recvmsg . +.Sh RETURN VALUES +The call returns the number of bytes received, or -1 +if an error occurred. +.Sh ERRORS +The +.Fn sctp_recvmsg +system call +fails if: +.Bl -tag -width Er +.It Bq Er EBADF +An invalid descriptor was specified. +.It Bq Er ENOTSOCK +The argument +.Fa s +is not a socket. +.It Bq Er EFAULT +An invalid user space address was specified for an argument. +.It Bq Er EMSGSIZE +The socket requires that message be sent atomically, +and the size of the message to be sent made this impossible. +.It Bq Er EAGAIN +The socket is marked non-blocking and the requested operation +would block. +.It Bq Er ENOBUFS +The system was unable to allocate an internal buffer. +The operation may succeed when buffers become available. +.It Bq Er ENOBUFS +The output queue for a network interface was full. +This generally indicates that the interface has stopped sending, +but may be caused by transient congestion. +.It Bq Er EHOSTUNREACH +The remote host was unreachable. +.It Bq Er ENOTCONN +On a one-to-one style socket no association exists. +.It Bq Er ECONNRESET +An abort was received by the stack while the user was +attempting to send data to the peer. +.It Bq Er ENOENT +On a one to many style socket no address is specified +so that the association cannot be located or the +SCTP_ABORT flag was specified on a non-existing association. +.It Bq Er EPIPE +The socket is unable to send anymore data +.Dv ( SBS_CANTSENDMORE +has been set on the socket). +This typically means that the socket +is not connected and is a one-to-one style socket. +.El +.Sh SEE ALSO +.Xr getsockopt 2 , +.Xr recv 2 , +.Xr select 2 , +.Xr sendmsg 2 , +.Xr setsockopt 2 , +.Xr socket 2 , +.Xr write 2 , +.Xr sctp_send 3 , +.Xr sctp_sendmsg 3 , +.Xr sctp 4 diff --git a/lib/libc/net/sctp_send.3 b/lib/libc/net/sctp_send.3 new file mode 100644 index 0000000..ddfd39c --- /dev/null +++ b/lib/libc/net/sctp_send.3 @@ -0,0 +1,350 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/sctp_send.3 276006 2014-12-21 12:36:36Z brueffer $ +.\" +.Dd December 15, 2006 +.Dt SCTP_SEND 3 +.Os +.Sh NAME +.Nm sctp_send , +.Nm sctp_sendx +.Nd send a message from an SCTP socket +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netinet/sctp.h +.Ft ssize_t +.Fo sctp_send +.Fa "int sd" "const void *msg" "size_t len" +.Fa "const struct sctp_sndrcvinfo *sinfo" "int flags" +.Fc +.Ft ssize_t +.Fo sctp_sendx +.Fa "int sd" "const void *msg" "size_t len" "struct sockaddr *addrs" +.Fa "int addrcnt" "const struct sctp_sndrcvinfo *sinfo" "int flags" +.Fc +.Sh DESCRIPTION +The +.Fn sctp_send +system call +is used to transmit a message to another SCTP endpoint. +.Fn sctp_send +may be used to send data to an existing association for both +one-to-many (SOCK_SEQPACKET) and one-to-one (SOCK_STREAM) socket types. +The length of the message +.Fa msg +is given by +.Fa len . +If the message is too long to pass atomically through the +underlying protocol, +.Va errno +is set to +.Er EMSGSIZE , +-1 is returned, and +the message is not transmitted. +.Pp +No indication of failure to deliver is implicit in a +.Fn sctp_send . +Locally detected errors are indicated by a return value of -1. +.Pp +If no space is available at the socket to hold +the message to be transmitted, then +.Fn sctp_send +normally blocks, unless the socket has been placed in +non-blocking I/O mode. +The +.Xr select 2 +system call may be used to determine when it is possible to +send more data on one-to-one type (SOCK_STREAM) sockets. +.Pp +The +.Fa sinfo +structure is used to control various SCTP features +and has the following format: +.Bd -literal +struct sctp_sndrcvinfo { + uint16_t sinfo_stream; /* Stream sending to */ + uint16_t sinfo_ssn; /* valid for recv only */ + uint16_t sinfo_flags; /* flags to control sending */ + uint32_t sinfo_ppid; /* ppid field */ + uint32_t sinfo_context; /* context field */ + uint32_t sinfo_timetolive; /* timetolive for PR-SCTP */ + uint32_t sinfo_tsn; /* valid for recv only */ + uint32_t sinfo_cumtsn; /* valid for recv only */ + sctp_assoc_t sinfo_assoc_id; /* The association id */ +}; +.Ed +.Pp +The +.Fa sinfo->sinfo_ppid +argument is an opaque 32 bit value that is passed transparently +through the stack to the peer endpoint. It will be available on +reception of a message (see +.Xr sctp_recvmsg 3 ) . +Note that the stack passes this value without regard to byte +order. +.Pp +The +.Fa sinfo->sinfo_flags +argument may include one or more of the following: +.Bd -literal +#define SCTP_EOF 0x0100 /* Start a shutdown procedures */ +#define SCTP_ABORT 0x0200 /* Send an ABORT to peer */ +#define SCTP_UNORDERED 0x0400 /* Message is un-ordered */ +#define SCTP_ADDR_OVER 0x0800 /* Override the primary-address */ +#define SCTP_SENDALL 0x1000 /* Send this on all associations */ + /* for the endpoint */ +/* The lower byte is an enumeration of PR-SCTP policies */ +#define SCTP_PR_SCTP_TTL 0x0001 /* Time based PR-SCTP */ +#define SCTP_PR_SCTP_BUF 0x0002 /* Buffer based PR-SCTP */ +#define SCTP_PR_SCTP_RTX 0x0003 /* Number of retransmissions based PR-SCTP */ +.Ed +.Pp +The flag +.Dv SCTP_EOF +is used to instruct the SCTP stack to queue this message +and then start a graceful shutdown of the association. +All +remaining data in queue will be sent after which the association +will be shut down. +.Pp +.Dv SCTP_ABORT +is used to immediately terminate an association. +An abort +is sent to the peer and the local TCB is destroyed. +.Pp +.Dv SCTP_UNORDERED +is used to specify that the message being sent has no +specific order and should be delivered to the peer application +as soon as possible. +When this flag is absent messages +are delivered in order within the stream they are sent, but without +respect to order to peer streams. +.Pp +The flag +.Dv SCTP_ADDR_OVER +is used to specify that a specific address should be used. +Normally +SCTP will use only one of a multi-homed peers addresses as the primary +address to send to. +By default, no matter what the +.Fa to +argument is, this primary address is used to send data. +By specifying +this flag, the user is asking the stack to ignore the primary address +and instead use the specified address not only as a lookup mechanism +to find the association but also as the actual address to send to. +.Pp +For a one-to-many type (SOCK_SEQPACKET) socket the flag +.Dv SCTP_SENDALL +can be used as a convenient way to make one send call and have +all associations that are under the socket get a copy of the message. +Note that this mechanism is quite efficient and makes only one actual +copy of the data which is shared by all the associations for sending. +.Pp +The remaining flags are used for the partial reliability extension (RFC3758) +and will only be effective if the peer endpoint supports this extension. +This option specifies what local policy the local endpoint should use +in skipping data. +If none of these options are set, then data is +never skipped over. +.Pp +.Dv SCTP_PR_SCTP_TTL +is used to indicate that a time based lifetime is being applied +to the data. +The +.Fa sinfo->sinfo_timetolive +argument is then a number of milliseconds for which the data is +attempted to be transmitted. +If that many milliseconds elapse +and the peer has not acknowledged the data, the data will be +skipped and no longer transmitted. +Note that this policy does +not even assure that the data will ever be sent. +In times of a congestion +with large amounts of data being queued, the +.Fa sinfo->sinfo_timetolive +may expire before the first transmission is ever made. +.Pp +The +.Dv SCTP_PR_SCTP_BUF +based policy transforms the +.Fa sinfo->sinfo_timetolive +field into a total number of bytes allowed on the outbound +send queue. +If that number or more bytes are in queue, then +other buffer-based sends are looked to be removed and +skipped. +Note that this policy may also result in the data +never being sent if no buffer based sends are in queue and +the maximum specified by +.Fa timetolive +bytes is in queue. +.Pp +The +.Dv SCTP_PR_SCTP_RTX +policy transforms the +.Fa sinfo->sinfo_timetolive +into a number of retransmissions to allow. +This policy +always assures that at a minimum one send attempt is +made of the data. +After which no more than +.Fa sinfo->sinfo_timetolive +retransmissions will be made before the data is skipped. +.Pp +.Fa sinfo->sinfo_stream +is the SCTP stream that you wish to send the +message on. +Streams in SCTP are reliable (or partially reliable) flows of ordered +messages. +.Pp +The +.Fa sinfo->sinfo_assoc_id +field is used to +select the association to send to on a one-to-many socket. +For a one-to-one socket, this field is ignored. +.Pp +The +.Fa sinfo->sinfo_context +field is used only in the event the message cannot be sent. +This is an opaque +value that the stack retains and will give to the user when a failed send +is given if that notification is enabled (see +.Xr sctp 4 ) . +Normally a user process can use this value to index some application +specific data structure when a send cannot be fulfilled. +.Pp +The +.Fa flags +argument holds the same meaning and values as those found in +.Xr sendmsg 2 +but is generally ignored by SCTP. +.Pp +The fields +.Fa sinfo->sinfo_ssn , +.Fa sinfo->sinfo_tsn , +and +.Fa sinfo->sinfo_cumtsn +are used only when receiving messages and are thus ignored by +.Fn sctp_send . +The function +.Fn sctp_sendx +has the same properties as +.Fn sctp_send +with the additional arguments of an array of sockaddr structures +passed in. +With the +.Fa addrs +argument being given as an array of addresses to be sent to and +the +.Fa addrcnt +argument indicating how many socket addresses are in the passed +in array. +Note that all of the addresses will only be used +when an implicit association is being set up. +This allows the +user the equivalent behavior as doing a +.Fn sctp_connectx +followed by a +.Fn sctp_send +to the association. +Note that if the +.Fa sinfo->sinfo_assoc_id +field is 0, then the first address will be used to look up +the association in place of the association id. +If both +an address and an association id are specified, the association +id has priority. +.Sh RETURN VALUES +The call returns the number of characters sent, or -1 +if an error occurred. +.Sh ERRORS +The +.Fn sctp_send +system call +fails if: +.Bl -tag -width Er +.It Bq Er EBADF +An invalid descriptor was specified. +.It Bq Er ENOTSOCK +The argument +.Fa s +is not a socket. +.It Bq Er EFAULT +An invalid user space address was specified for an argument. +.It Bq Er EMSGSIZE +The socket requires that message be sent atomically, +and the size of the message to be sent made this impossible. +.It Bq Er EAGAIN +The socket is marked non-blocking and the requested operation +would block. +.It Bq Er ENOBUFS +The system was unable to allocate an internal buffer. +The operation may succeed when buffers become available. +.It Bq Er ENOBUFS +The output queue for a network interface was full. +This generally indicates that the interface has stopped sending, +but may be caused by transient congestion. +.It Bq Er EHOSTUNREACH +The remote host was unreachable. +.It Bq Er ENOTCONN +On a one-to-one style socket no association exists. +.It Bq Er ECONNRESET +An abort was received by the stack while the user was +attempting to send data to the peer. +.It Bq Er ENOENT +On a one-to-many style socket no address is specified +so that the association cannot be located or the +SCTP_ABORT flag was specified on a non-existing association. +.It Bq Er EPIPE +The socket is unable to send anymore data +.Dv ( SBS_CANTSENDMORE +has been set on the socket). +This typically means that the socket +is not connected and is a one-to-one style socket. +.El +.Sh SEE ALSO +.Xr getsockopt 2 , +.Xr recv 2 , +.Xr select 2 , +.Xr sendmsg 2 , +.Xr socket 2 , +.Xr write 2 , +.Xr sctp_connectx 3 , +.Xr sctp_recvmsg 3 , +.Xr sctp_sendmsg 3 , +.Xr sctp 4 +.Sh BUGS +Because +.Fn sctp_send +may have multiple associations under one endpoint, a +select on write will only work for a one-to-one style +socket. diff --git a/lib/libc/net/sctp_sendmsg.3 b/lib/libc/net/sctp_sendmsg.3 new file mode 100644 index 0000000..15a95ed --- /dev/null +++ b/lib/libc/net/sctp_sendmsg.3 @@ -0,0 +1,329 @@ +.\" Copyright (c) 1983, 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. +.\" +.\" From: @(#)send.2 8.2 (Berkeley) 2/21/94 +.\" $FreeBSD: releng/11.1/lib/libc/net/sctp_sendmsg.3 296200 2016-02-29 17:19:15Z trasz $ +.\" +.Dd December 15, 2006 +.Dt SCTP_SENDMSG 3 +.Os +.Sh NAME +.Nm sctp_sendmsg , +.Nm sctp_sendmsgx +.Nd send a message from an SCTP socket +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/socket.h +.In netinet/sctp.h +.Ft ssize_t +.Fo sctp_sendmsg +.Fa "int s" "const void *msg" "size_t len" "const struct sockaddr *to" +.Fa "socklen_t tolen" "uint32_t ppid" "uint32_t flags" "uint16_t stream_no" +.Fa "uint32_t timetolive" "uint32_t context" +.Fc +.Ft ssize_t +.Fo sctp_sendmsgx +.Fa "int s" "const void *msg" "size_t len" "const struct sockaddr *to" +.Fa "int addrcnt" "uint32_t ppid" "uint32_t flags" "uint16_t stream_no" +.Fa "uint32_t timetolive" "uint32_t context" +.Fc +.Sh DESCRIPTION +The +.Fn sctp_sendmsg +system call +is used to transmit a message to another SCTP endpoint. +The +.Fn sctp_sendmsg +may be used at any time. +If the socket is a one-to-many type (SOCK_SEQPACKET) +socket then an attempt to send to an address that no association exists to will +implicitly create a new association. +Data sent in such an instance will result in +the data being sent on the third leg of the SCTP four-way handshake. +Note that if +the socket is a one-to-one type (SOCK_STREAM) socket then an association must +be in existence (by use of the +.Xr connect 2 +system call). +Calling +.Fn sctp_sendmsg +or +.Fn sctp_sendmsgx +on a non-connected one-to-one socket will result in +.Va errno +being set to +.Er ENOTCONN , +-1 being returned, and the message not being transmitted. +.Pp +The address of the target is given by +.Fa to +with +.Fa tolen +specifying its size. +The length of the message +.Fa msg +is given by +.Fa len . +If the message is too long to pass atomically through the +underlying protocol, +.Va errno +is set to +.Er EMSGSIZE , +-1 is returned, and +the message is not transmitted. +.Pp +No indication of failure to deliver is implicit in a +.Xr sctp_sendmsg 3 +call. +Locally detected errors are indicated by a return value of -1. +.Pp +If no space is available at the socket to hold +the message to be transmitted, then +.Xr sctp_sendmsg 3 +normally blocks, unless the socket has been placed in +non-blocking I/O mode. +The +.Xr select 2 +system call may be used to determine when it is possible to +send more data on one-to-one type (SOCK_STREAM) sockets. +.Pp +The +.Fa ppid +argument is an opaque 32 bit value that is passed transparently +through the stack to the peer endpoint. +It will be available on +reception of a message (see +.Xr sctp_recvmsg 3 ) . +Note that the stack passes this value without regard to byte +order. +.Pp +The +.Fa flags +argument may include one or more of the following: +.Bd -literal +#define SCTP_EOF 0x0100 /* Start a shutdown procedures */ +#define SCTP_ABORT 0x0200 /* Send an ABORT to peer */ +#define SCTP_UNORDERED 0x0400 /* Message is un-ordered */ +#define SCTP_ADDR_OVER 0x0800 /* Override the primary-address */ +#define SCTP_SENDALL 0x1000 /* Send this on all associations */ + /* for the endpoint */ +/* The lower byte is an enumeration of PR-SCTP policies */ +#define SCTP_PR_SCTP_TTL 0x0001 /* Time based PR-SCTP */ +#define SCTP_PR_SCTP_BUF 0x0002 /* Buffer based PR-SCTP */ +#define SCTP_PR_SCTP_RTX 0x0003 /* Number of retransmissions based PR-SCTP */ +.Ed +.Pp +The flag +.Dv SCTP_EOF +is used to instruct the SCTP stack to queue this message +and then start a graceful shutdown of the association. +All +remaining data in queue will be sent after which the association +will be shut down. +.Pp +.Dv SCTP_ABORT +is used to immediately terminate an association. +An abort +is sent to the peer and the local TCB is destroyed. +.Pp +.Dv SCTP_UNORDERED +is used to specify that the message being sent has no +specific order and should be delivered to the peer application +as soon as possible. +When this flag is absent messages +are delivered in order within the stream they are sent, but without +respect to order to peer streams. +.Pp +The flag +.Dv SCTP_ADDR_OVER +is used to specify that an specific address should be used. +Normally +SCTP will use only one of a multi-homed peers addresses as the primary +address to send to. +By default, no matter what the +.Fa to +argument is, this primary address is used to send data. +By specifying +this flag, the user is asking the stack to ignore the primary address +and instead use the specified address not only as a lookup mechanism +to find the association but also as the actual address to send to. +.Pp +For a one-to-many type (SOCK_SEQPACKET) socket the flag +.Dv SCTP_SENDALL +can be used as a convenient way to make one send call and have +all associations that are under the socket get a copy of the message. +Note that this mechanism is quite efficient and makes only one actual +copy of the data which is shared by all the associations for sending. +.Pp +The remaining flags are used for the partial reliability extension (RFC3758) +and will only be effective if the peer endpoint supports this extension. +This option specifies what local policy the local endpoint should use +in skipping data. +If none of these options are set, then data is +never skipped over. +.Pp +.Dv SCTP_PR_SCTP_TTL +is used to indicate that a time based lifetime is being applied +to the data. +The +.Fa timetolive +argument is then a number of milliseconds for which the data is +attempted to be transmitted. +If that many milliseconds elapse +and the peer has not acknowledged the data, the data will be +skipped and no longer transmitted. +Note that this policy does +not even assure that the data will ever be sent. +In times of a congestion +with large amounts of data being queued, the +.Fa timetolive +may expire before the first transmission is ever made. +.Pp +The +.Dv SCTP_PR_SCTP_BUF +based policy transforms the +.Fa timetolive +field into a total number of bytes allowed on the outbound +send queue. +If that number or more bytes are in queue, then +other buffer based sends are looked to be removed and +skipped. +Note that this policy may also result in the data +never being sent if no buffer based sends are in queue and +the maximum specified by +.Fa timetolive +bytes is in queue. +.Pp +The +.Dv SCTP_PR_SCTP_RTX +policy transforms the +.Fa timetolive +into a number of retransmissions to allow. +This policy +always assures that at a minimum one send attempt is +made of the data. +After which no more than +.Fa timetolive +retransmissions will be made before the data is skipped. +.Pp +.Fa stream_no +is the SCTP stream that you wish to send the +message on. +Streams in SCTP are reliable (or partially reliable) flows of ordered +messages. +The +.Fa context +field is used only in the event the message cannot be sent. +This is an opaque +value that the stack retains and will give to the user when a failed send +is given if that notification is enabled (see +.Xr sctp 4 ) . +Normally a user process can use this value to index some application +specific data structure when a send cannot be fulfilled. +.Fn sctp_sendmsgx +is identical to +.Fn sctp_sendmsg +with the exception that it takes an array of sockaddr structures in the +argument +.Fa to +and adds the additional argument +.Fa addrcnt +which specifies how many addresses are in the array. +This allows a +caller to implicitly set up an association passing multiple addresses +as if +.Fn sctp_connectx +had been called to set up the association. +.Sh RETURN VALUES +The call returns the number of characters sent, or -1 +if an error occurred. +.Sh ERRORS +The +.Fn sctp_sendmsg +system call +fails if: +.Bl -tag -width Er +.It Bq Er EBADF +An invalid descriptor was specified. +.It Bq Er ENOTSOCK +The argument +.Fa s +is not a socket. +.It Bq Er EFAULT +An invalid user space address was specified for an argument. +.It Bq Er EMSGSIZE +The socket requires that message be sent atomically, +and the size of the message to be sent made this impossible. +.It Bq Er EAGAIN +The socket is marked non-blocking and the requested operation +would block. +.It Bq Er ENOBUFS +The system was unable to allocate an internal buffer. +The operation may succeed when buffers become available. +.It Bq Er ENOBUFS +The output queue for a network interface was full. +This generally indicates that the interface has stopped sending, +but may be caused by transient congestion. +.It Bq Er EHOSTUNREACH +The remote host was unreachable. +.It Bq Er ENOTCONN +On a one-to-one style socket no association exists. +.It Bq Er ECONNRESET +An abort was received by the stack while the user was +attempting to send data to the peer. +.It Bq Er ENOENT +On a one-to-many style socket no address is specified +so that the association cannot be located or the +.Dv SCTP_ABORT +flag was specified on a non-existing association. +.It Bq Er EPIPE +The socket is unable to send anymore data +.Dv ( SBS_CANTSENDMORE +has been set on the socket). +This typically means that the socket +is not connected and is a one-to-one style socket. +.El +.Sh SEE ALSO +.Xr connect 2 , +.Xr getsockopt 2 , +.Xr recv 2 , +.Xr select 2 , +.Xr sendmsg 2 , +.Xr socket 2 , +.Xr write 2 , +.Xr sctp_connectx 3 , +.Xr sctp 4 +.Sh BUGS +Because in the one-to-many style socket +.Fn sctp_sendmsg +or +.Fn sctp_sendmsgx +may have multiple associations under one endpoint, a +select on write will only work for a one-to-one style +socket. diff --git a/lib/libc/net/sctp_sys_calls.c b/lib/libc/net/sctp_sys_calls.c new file mode 100644 index 0000000..5fd5517 --- /dev/null +++ b/lib/libc/net/sctp_sys_calls.c @@ -0,0 +1,1203 @@ +/*- + * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. + * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. + * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * a) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * b) 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. + * + * c) Neither the name of Cisco Systems, Inc. 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/net/sctp_sys_calls.c 310220 2016-12-18 13:05:42Z tuexen $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef IN6_IS_ADDR_V4MAPPED +#define IN6_IS_ADDR_V4MAPPED(a) \ + ((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \ + (*(const uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \ + (*(const uint32_t *)(const void *)(&(a)->s6_addr[8]) == ntohl(0x0000ffff))) +#endif + +#define SCTP_CONTROL_VEC_SIZE_RCV 16384 + + +static void +in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6) +{ + bzero(sin, sizeof(*sin)); + sin->sin_len = sizeof(struct sockaddr_in); + sin->sin_family = AF_INET; + sin->sin_port = sin6->sin6_port; + sin->sin_addr.s_addr = sin6->sin6_addr.__u6_addr.__u6_addr32[3]; +} + +int +sctp_getaddrlen(sa_family_t family) +{ + int ret, sd; + socklen_t siz; + struct sctp_assoc_value av; + + av.assoc_value = family; + siz = sizeof(av); +#if defined(AF_INET) + sd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP); +#elif defined(AF_INET6) + sd = socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP); +#else + sd = -1; +#endif + if (sd == -1) { + return (-1); + } + ret = getsockopt(sd, IPPROTO_SCTP, SCTP_GET_ADDR_LEN, &av, &siz); + close(sd); + if (ret == 0) { + return ((int)av.assoc_value); + } else { + return (-1); + } +} + +int +sctp_connectx(int sd, const struct sockaddr *addrs, int addrcnt, + sctp_assoc_t * id) +{ + char *buf; + int i, ret, *aa; + char *cpto; + const struct sockaddr *at; + size_t len; + + /* validate the address count and list */ + if ((addrs == NULL) || (addrcnt <= 0)) { + errno = EINVAL; + return (-1); + } + if ((buf = malloc(sizeof(int) + (size_t)addrcnt * sizeof(struct sockaddr_in6))) == NULL) { + errno = E2BIG; + return (-1); + } + len = sizeof(int); + at = addrs; + cpto = buf + sizeof(int); + /* validate all the addresses and get the size */ + for (i = 0; i < addrcnt; i++) { + switch (at->sa_family) { + case AF_INET: + if (at->sa_len != sizeof(struct sockaddr_in)) { + free(buf); + errno = EINVAL; + return (-1); + } + memcpy(cpto, at, sizeof(struct sockaddr_in)); + cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in)); + len += sizeof(struct sockaddr_in); + break; + case AF_INET6: + if (at->sa_len != sizeof(struct sockaddr_in6)) { + free(buf); + errno = EINVAL; + return (-1); + } + if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)at)->sin6_addr)) { + in6_sin6_2_sin((struct sockaddr_in *)cpto, (struct sockaddr_in6 *)at); + cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in)); + len += sizeof(struct sockaddr_in); + } else { + memcpy(cpto, at, sizeof(struct sockaddr_in6)); + cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in6)); + len += sizeof(struct sockaddr_in6); + } + break; + default: + free(buf); + errno = EINVAL; + return (-1); + } + at = (struct sockaddr *)((caddr_t)at + at->sa_len); + } + aa = (int *)buf; + *aa = addrcnt; + ret = setsockopt(sd, IPPROTO_SCTP, SCTP_CONNECT_X, (void *)buf, + (socklen_t) len); + if ((ret == 0) && (id != NULL)) { + *id = *(sctp_assoc_t *) buf; + } + free(buf); + return (ret); +} + +int +sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags) +{ + struct sctp_getaddresses *gaddrs; + struct sockaddr *sa; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + int i; + size_t argsz; + uint16_t sport = 0; + + /* validate the flags */ + if ((flags != SCTP_BINDX_ADD_ADDR) && + (flags != SCTP_BINDX_REM_ADDR)) { + errno = EFAULT; + return (-1); + } + /* validate the address count and list */ + if ((addrcnt <= 0) || (addrs == NULL)) { + errno = EINVAL; + return (-1); + } + /* First pre-screen the addresses */ + sa = addrs; + for (i = 0; i < addrcnt; i++) { + switch (sa->sa_family) { + case AF_INET: + if (sa->sa_len != sizeof(struct sockaddr_in)) { + errno = EINVAL; + return (-1); + } + sin = (struct sockaddr_in *)sa; + if (sin->sin_port) { + /* non-zero port, check or save */ + if (sport) { + /* Check against our port */ + if (sport != sin->sin_port) { + errno = EINVAL; + return (-1); + } + } else { + /* save off the port */ + sport = sin->sin_port; + } + } + break; + case AF_INET6: + if (sa->sa_len != sizeof(struct sockaddr_in6)) { + errno = EINVAL; + return (-1); + } + sin6 = (struct sockaddr_in6 *)sa; + if (sin6->sin6_port) { + /* non-zero port, check or save */ + if (sport) { + /* Check against our port */ + if (sport != sin6->sin6_port) { + errno = EINVAL; + return (-1); + } + } else { + /* save off the port */ + sport = sin6->sin6_port; + } + } + break; + default: + /* Invalid address family specified. */ + errno = EAFNOSUPPORT; + return (-1); + } + sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len); + } + argsz = sizeof(struct sctp_getaddresses) + + sizeof(struct sockaddr_storage); + if ((gaddrs = (struct sctp_getaddresses *)malloc(argsz)) == NULL) { + errno = ENOMEM; + return (-1); + } + sa = addrs; + for (i = 0; i < addrcnt; i++) { + memset(gaddrs, 0, argsz); + gaddrs->sget_assoc_id = 0; + memcpy(gaddrs->addr, sa, sa->sa_len); + /* + * Now, if there was a port mentioned, assure that the first + * address has that port to make sure it fails or succeeds + * correctly. + */ + if ((i == 0) && (sport != 0)) { + switch (gaddrs->addr->sa_family) { + case AF_INET: + sin = (struct sockaddr_in *)gaddrs->addr; + sin->sin_port = sport; + break; + case AF_INET6: + sin6 = (struct sockaddr_in6 *)gaddrs->addr; + sin6->sin6_port = sport; + break; + } + } + if (setsockopt(sd, IPPROTO_SCTP, flags, gaddrs, + (socklen_t) argsz) != 0) { + free(gaddrs); + return (-1); + } + sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len); + } + free(gaddrs); + return (0); +} + +int +sctp_opt_info(int sd, sctp_assoc_t id, int opt, void *arg, socklen_t * size) +{ + if (arg == NULL) { + errno = EINVAL; + return (-1); + } + if ((id == SCTP_CURRENT_ASSOC) || + (id == SCTP_ALL_ASSOC)) { + errno = EINVAL; + return (-1); + } + switch (opt) { + case SCTP_RTOINFO: + ((struct sctp_rtoinfo *)arg)->srto_assoc_id = id; + break; + case SCTP_ASSOCINFO: + ((struct sctp_assocparams *)arg)->sasoc_assoc_id = id; + break; + case SCTP_DEFAULT_SEND_PARAM: + ((struct sctp_assocparams *)arg)->sasoc_assoc_id = id; + break; + case SCTP_PRIMARY_ADDR: + ((struct sctp_setprim *)arg)->ssp_assoc_id = id; + break; + case SCTP_PEER_ADDR_PARAMS: + ((struct sctp_paddrparams *)arg)->spp_assoc_id = id; + break; + case SCTP_MAXSEG: + ((struct sctp_assoc_value *)arg)->assoc_id = id; + break; + case SCTP_AUTH_KEY: + ((struct sctp_authkey *)arg)->sca_assoc_id = id; + break; + case SCTP_AUTH_ACTIVE_KEY: + ((struct sctp_authkeyid *)arg)->scact_assoc_id = id; + break; + case SCTP_DELAYED_SACK: + ((struct sctp_sack_info *)arg)->sack_assoc_id = id; + break; + case SCTP_CONTEXT: + ((struct sctp_assoc_value *)arg)->assoc_id = id; + break; + case SCTP_STATUS: + ((struct sctp_status *)arg)->sstat_assoc_id = id; + break; + case SCTP_GET_PEER_ADDR_INFO: + ((struct sctp_paddrinfo *)arg)->spinfo_assoc_id = id; + break; + case SCTP_PEER_AUTH_CHUNKS: + ((struct sctp_authchunks *)arg)->gauth_assoc_id = id; + break; + case SCTP_LOCAL_AUTH_CHUNKS: + ((struct sctp_authchunks *)arg)->gauth_assoc_id = id; + break; + case SCTP_TIMEOUTS: + ((struct sctp_timeouts *)arg)->stimo_assoc_id = id; + break; + case SCTP_EVENT: + ((struct sctp_event *)arg)->se_assoc_id = id; + break; + case SCTP_DEFAULT_SNDINFO: + ((struct sctp_sndinfo *)arg)->snd_assoc_id = id; + break; + case SCTP_DEFAULT_PRINFO: + ((struct sctp_default_prinfo *)arg)->pr_assoc_id = id; + break; + case SCTP_PEER_ADDR_THLDS: + ((struct sctp_paddrthlds *)arg)->spt_assoc_id = id; + break; + case SCTP_REMOTE_UDP_ENCAPS_PORT: + ((struct sctp_udpencaps *)arg)->sue_assoc_id = id; + break; + case SCTP_ECN_SUPPORTED: + ((struct sctp_assoc_value *)arg)->assoc_id = id; + break; + case SCTP_PR_SUPPORTED: + ((struct sctp_assoc_value *)arg)->assoc_id = id; + break; + case SCTP_AUTH_SUPPORTED: + ((struct sctp_assoc_value *)arg)->assoc_id = id; + break; + case SCTP_ASCONF_SUPPORTED: + ((struct sctp_assoc_value *)arg)->assoc_id = id; + break; + case SCTP_RECONFIG_SUPPORTED: + ((struct sctp_assoc_value *)arg)->assoc_id = id; + break; + case SCTP_NRSACK_SUPPORTED: + ((struct sctp_assoc_value *)arg)->assoc_id = id; + break; + case SCTP_PKTDROP_SUPPORTED: + ((struct sctp_assoc_value *)arg)->assoc_id = id; + break; + case SCTP_MAX_BURST: + ((struct sctp_assoc_value *)arg)->assoc_id = id; + break; + case SCTP_ENABLE_STREAM_RESET: + ((struct sctp_assoc_value *)arg)->assoc_id = id; + break; + case SCTP_PR_STREAM_STATUS: + ((struct sctp_prstatus *)arg)->sprstat_assoc_id = id; + break; + case SCTP_PR_ASSOC_STATUS: + ((struct sctp_prstatus *)arg)->sprstat_assoc_id = id; + break; + case SCTP_MAX_CWND: + ((struct sctp_assoc_value *)arg)->assoc_id = id; + break; + default: + break; + } + return (getsockopt(sd, IPPROTO_SCTP, opt, arg, size)); +} + +int +sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **raddrs) +{ + struct sctp_getaddresses *addrs; + struct sockaddr *sa; + sctp_assoc_t asoc; + caddr_t lim; + socklen_t opt_len; + int cnt; + + if (raddrs == NULL) { + errno = EFAULT; + return (-1); + } + asoc = id; + opt_len = (socklen_t) sizeof(sctp_assoc_t); + if (getsockopt(sd, IPPROTO_SCTP, SCTP_GET_REMOTE_ADDR_SIZE, + &asoc, &opt_len) != 0) { + return (-1); + } + /* size required is returned in 'asoc' */ + opt_len = (socklen_t) ((size_t)asoc + sizeof(struct sctp_getaddresses)); + addrs = calloc(1, (size_t)opt_len); + if (addrs == NULL) { + errno = ENOMEM; + return (-1); + } + addrs->sget_assoc_id = id; + /* Now lets get the array of addresses */ + if (getsockopt(sd, IPPROTO_SCTP, SCTP_GET_PEER_ADDRESSES, + addrs, &opt_len) != 0) { + free(addrs); + return (-1); + } + *raddrs = (struct sockaddr *)&addrs->addr[0]; + cnt = 0; + sa = (struct sockaddr *)&addrs->addr[0]; + lim = (caddr_t)addrs + opt_len; + while (((caddr_t)sa < lim) && (sa->sa_len > 0)) { + sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len); + cnt++; + } + return (cnt); +} + +void +sctp_freepaddrs(struct sockaddr *addrs) +{ + void *fr_addr; + + /* Take away the hidden association id */ + fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t)); + /* Now free it */ + free(fr_addr); +} + +int +sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr **raddrs) +{ + struct sctp_getaddresses *addrs; + caddr_t lim; + struct sockaddr *sa; + size_t size_of_addresses; + socklen_t opt_len; + int cnt; + + if (raddrs == NULL) { + errno = EFAULT; + return (-1); + } + size_of_addresses = 0; + opt_len = (socklen_t) sizeof(int); + if (getsockopt(sd, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDR_SIZE, + &size_of_addresses, &opt_len) != 0) { + errno = ENOMEM; + return (-1); + } + if (size_of_addresses == 0) { + errno = ENOTCONN; + return (-1); + } + opt_len = (socklen_t) (size_of_addresses + + sizeof(struct sockaddr_storage) + + sizeof(struct sctp_getaddresses)); + addrs = calloc(1, (size_t)opt_len); + if (addrs == NULL) { + errno = ENOMEM; + return (-1); + } + addrs->sget_assoc_id = id; + /* Now lets get the array of addresses */ + if (getsockopt(sd, IPPROTO_SCTP, SCTP_GET_LOCAL_ADDRESSES, addrs, + &opt_len) != 0) { + free(addrs); + errno = ENOMEM; + return (-1); + } + *raddrs = (struct sockaddr *)&addrs->addr[0]; + cnt = 0; + sa = (struct sockaddr *)&addrs->addr[0]; + lim = (caddr_t)addrs + opt_len; + while (((caddr_t)sa < lim) && (sa->sa_len > 0)) { + sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len); + cnt++; + } + return (cnt); +} + +void +sctp_freeladdrs(struct sockaddr *addrs) +{ + void *fr_addr; + + /* Take away the hidden association id */ + fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t)); + /* Now free it */ + free(fr_addr); +} + +ssize_t +sctp_sendmsg(int s, + const void *data, + size_t len, + const struct sockaddr *to, + socklen_t tolen, + uint32_t ppid, + uint32_t flags, + uint16_t stream_no, + uint32_t timetolive, + uint32_t context) +{ +#ifdef SYS_sctp_generic_sendmsg + struct sctp_sndrcvinfo sinfo; + + memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); + sinfo.sinfo_ppid = ppid; + sinfo.sinfo_flags = flags; + sinfo.sinfo_stream = stream_no; + sinfo.sinfo_timetolive = timetolive; + sinfo.sinfo_context = context; + sinfo.sinfo_assoc_id = 0; + return (syscall(SYS_sctp_generic_sendmsg, s, + data, len, to, tolen, &sinfo, 0)); +#else + struct msghdr msg; + struct sctp_sndrcvinfo *sinfo; + struct iovec iov; + char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + struct sockaddr *who = NULL; + union { + struct sockaddr_in in; + struct sockaddr_in6 in6; + } addr; + + if ((tolen > 0) && + ((to == NULL) || (tolen < sizeof(struct sockaddr)))) { + errno = EINVAL; + return (-1); + } + if ((to != NULL) && (tolen > 0)) { + switch (to->sa_family) { + case AF_INET: + if (tolen != sizeof(struct sockaddr_in)) { + errno = EINVAL; + return (-1); + } + if ((to->sa_len > 0) && + (to->sa_len != sizeof(struct sockaddr_in))) { + errno = EINVAL; + return (-1); + } + memcpy(&addr, to, sizeof(struct sockaddr_in)); + addr.in.sin_len = sizeof(struct sockaddr_in); + break; + case AF_INET6: + if (tolen != sizeof(struct sockaddr_in6)) { + errno = EINVAL; + return (-1); + } + if ((to->sa_len > 0) && + (to->sa_len != sizeof(struct sockaddr_in6))) { + errno = EINVAL; + return (-1); + } + memcpy(&addr, to, sizeof(struct sockaddr_in6)); + addr.in6.sin6_len = sizeof(struct sockaddr_in6); + break; + default: + errno = EAFNOSUPPORT; + return (-1); + } + who = (struct sockaddr *)&addr; + } + iov.iov_base = (char *)data; + iov.iov_len = len; + + if (who) { + msg.msg_name = (caddr_t)who; + msg.msg_namelen = who->sa_len; + } else { + msg.msg_name = (caddr_t)NULL; + msg.msg_namelen = 0; + } + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsgbuf; + msg.msg_controllen = CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)); + msg.msg_flags = 0; + cmsg = (struct cmsghdr *)cmsgbuf; + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo)); + sinfo->sinfo_stream = stream_no; + sinfo->sinfo_ssn = 0; + sinfo->sinfo_flags = flags; + sinfo->sinfo_ppid = ppid; + sinfo->sinfo_context = context; + sinfo->sinfo_assoc_id = 0; + sinfo->sinfo_timetolive = timetolive; + return (sendmsg(s, &msg, 0)); +#endif +} + + +sctp_assoc_t +sctp_getassocid(int sd, struct sockaddr *sa) +{ + struct sctp_paddrinfo sp; + socklen_t siz; + + /* First get the assoc id */ + siz = sizeof(sp); + memset(&sp, 0, sizeof(sp)); + memcpy((caddr_t)&sp.spinfo_address, sa, sa->sa_len); + if (getsockopt(sd, IPPROTO_SCTP, + SCTP_GET_PEER_ADDR_INFO, &sp, &siz) != 0) { + /* We depend on the fact that 0 can never be returned */ + return ((sctp_assoc_t) 0); + } + return (sp.spinfo_assoc_id); +} + +ssize_t +sctp_send(int sd, const void *data, size_t len, + const struct sctp_sndrcvinfo *sinfo, + int flags) +{ + +#ifdef SYS_sctp_generic_sendmsg + struct sockaddr *to = NULL; + + return (syscall(SYS_sctp_generic_sendmsg, sd, + data, len, to, 0, sinfo, flags)); +#else + struct msghdr msg; + struct iovec iov; + char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct cmsghdr *cmsg; + + if (sinfo == NULL) { + errno = EINVAL; + return (-1); + } + iov.iov_base = (char *)data; + iov.iov_len = len; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsgbuf; + msg.msg_controllen = CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)); + msg.msg_flags = 0; + cmsg = (struct cmsghdr *)cmsgbuf; + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + memcpy(CMSG_DATA(cmsg), sinfo, sizeof(struct sctp_sndrcvinfo)); + return (sendmsg(sd, &msg, flags)); +#endif +} + + + +ssize_t +sctp_sendx(int sd, const void *msg, size_t msg_len, + struct sockaddr *addrs, int addrcnt, + struct sctp_sndrcvinfo *sinfo, + int flags) +{ + struct sctp_sndrcvinfo __sinfo; + ssize_t ret; + int i, cnt, *aa, saved_errno; + char *buf; + int no_end_cx = 0; + size_t len, add_len; + struct sockaddr *at; + + if (addrs == NULL) { + errno = EINVAL; + return (-1); + } +#ifdef SYS_sctp_generic_sendmsg + if (addrcnt == 1) { + socklen_t l; + ssize_t ret; + + /* + * Quick way, we don't need to do a connectx so lets use the + * syscall directly. + */ + l = addrs->sa_len; + ret = syscall(SYS_sctp_generic_sendmsg, sd, + msg, msg_len, addrs, l, sinfo, flags); + if ((ret >= 0) && (sinfo != NULL)) { + sinfo->sinfo_assoc_id = sctp_getassocid(sd, addrs); + } + return (ret); + } +#endif + + len = sizeof(int); + at = addrs; + cnt = 0; + /* validate all the addresses and get the size */ + for (i = 0; i < addrcnt; i++) { + if (at->sa_family == AF_INET) { + add_len = sizeof(struct sockaddr_in); + } else if (at->sa_family == AF_INET6) { + add_len = sizeof(struct sockaddr_in6); + } else { + errno = EINVAL; + return (-1); + } + len += add_len; + at = (struct sockaddr *)((caddr_t)at + add_len); + cnt++; + } + /* do we have any? */ + if (cnt == 0) { + errno = EINVAL; + return (-1); + } + buf = malloc(len); + if (buf == NULL) { + errno = ENOMEM; + return (-1); + } + aa = (int *)buf; + *aa = cnt; + aa++; + memcpy((caddr_t)aa, addrs, (size_t)(len - sizeof(int))); + ret = setsockopt(sd, IPPROTO_SCTP, SCTP_CONNECT_X_DELAYED, (void *)buf, + (socklen_t) len); + + free(buf); + if (ret != 0) { + if (errno == EALREADY) { + no_end_cx = 1; + goto continue_send; + } + return (ret); + } +continue_send: + if (sinfo == NULL) { + sinfo = &__sinfo; + memset(&__sinfo, 0, sizeof(__sinfo)); + } + sinfo->sinfo_assoc_id = sctp_getassocid(sd, addrs); + if (sinfo->sinfo_assoc_id == 0) { + (void)setsockopt(sd, IPPROTO_SCTP, SCTP_CONNECT_X_COMPLETE, (void *)addrs, + (socklen_t) addrs->sa_len); + errno = ENOENT; + return (-1); + } + ret = sctp_send(sd, msg, msg_len, sinfo, flags); + saved_errno = errno; + if (no_end_cx == 0) + (void)setsockopt(sd, IPPROTO_SCTP, SCTP_CONNECT_X_COMPLETE, (void *)addrs, + (socklen_t) addrs->sa_len); + + errno = saved_errno; + return (ret); +} + +ssize_t +sctp_sendmsgx(int sd, + const void *msg, + size_t len, + struct sockaddr *addrs, + int addrcnt, + uint32_t ppid, + uint32_t flags, + uint16_t stream_no, + uint32_t timetolive, + uint32_t context) +{ + struct sctp_sndrcvinfo sinfo; + + memset((void *)&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); + sinfo.sinfo_ppid = ppid; + sinfo.sinfo_flags = flags; + sinfo.sinfo_stream = stream_no; + sinfo.sinfo_timetolive = timetolive; + sinfo.sinfo_context = context; + return (sctp_sendx(sd, msg, len, addrs, addrcnt, &sinfo, 0)); +} + +ssize_t +sctp_recvmsg(int s, + void *dbuf, + size_t len, + struct sockaddr *from, + socklen_t * fromlen, + struct sctp_sndrcvinfo *sinfo, + int *msg_flags) +{ +#ifdef SYS_sctp_generic_recvmsg + struct iovec iov; + + iov.iov_base = dbuf; + iov.iov_len = len; + return (syscall(SYS_sctp_generic_recvmsg, s, + &iov, 1, from, fromlen, sinfo, msg_flags)); +#else + ssize_t sz; + struct msghdr msg; + struct iovec iov; + char cmsgbuf[SCTP_CONTROL_VEC_SIZE_RCV]; + struct cmsghdr *cmsg; + + if (msg_flags == NULL) { + errno = EINVAL; + return (-1); + } + iov.iov_base = dbuf; + iov.iov_len = len; + msg.msg_name = (caddr_t)from; + if (fromlen == NULL) + msg.msg_namelen = 0; + else + msg.msg_namelen = *fromlen; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); + msg.msg_flags = 0; + sz = recvmsg(s, &msg, *msg_flags); + *msg_flags = msg.msg_flags; + if (sz <= 0) { + return (sz); + } + if (sinfo) { + sinfo->sinfo_assoc_id = 0; + } + if ((msg.msg_controllen > 0) && (sinfo != NULL)) { + /* + * parse through and see if we find the sctp_sndrcvinfo (if + * the user wants it). + */ + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level != IPPROTO_SCTP) { + continue; + } + if (cmsg->cmsg_type == SCTP_SNDRCV) { + memcpy(sinfo, CMSG_DATA(cmsg), sizeof(struct sctp_sndrcvinfo)); + break; + } + if (cmsg->cmsg_type == SCTP_EXTRCV) { + /* + * Let's hope that the user provided enough + * enough memory. At least he asked for more + * information. + */ + memcpy(sinfo, CMSG_DATA(cmsg), sizeof(struct sctp_extrcvinfo)); + break; + } + } + } + return (sz); +#endif +} + +ssize_t +sctp_recvv(int sd, + const struct iovec *iov, + int iovlen, + struct sockaddr *from, + socklen_t * fromlen, + void *info, + socklen_t * infolen, + unsigned int *infotype, + int *flags) +{ + char cmsgbuf[SCTP_CONTROL_VEC_SIZE_RCV]; + struct msghdr msg; + struct cmsghdr *cmsg; + ssize_t ret; + struct sctp_rcvinfo *rcvinfo; + struct sctp_nxtinfo *nxtinfo; + + if (((info != NULL) && (infolen == NULL)) || + ((info == NULL) && (infolen != NULL) && (*infolen != 0)) || + ((info != NULL) && (infotype == NULL))) { + errno = EINVAL; + return (-1); + } + if (infotype) { + *infotype = SCTP_RECVV_NOINFO; + } + msg.msg_name = from; + if (fromlen == NULL) { + msg.msg_namelen = 0; + } else { + msg.msg_namelen = *fromlen; + } + msg.msg_iov = (struct iovec *)iov; + msg.msg_iovlen = iovlen; + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); + msg.msg_flags = 0; + ret = recvmsg(sd, &msg, *flags); + *flags = msg.msg_flags; + if ((ret > 0) && + (msg.msg_controllen > 0) && + (infotype != NULL) && + (infolen != NULL) && + (*infolen > 0)) { + rcvinfo = NULL; + nxtinfo = NULL; + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level != IPPROTO_SCTP) { + continue; + } + if (cmsg->cmsg_type == SCTP_RCVINFO) { + rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg); + if (nxtinfo != NULL) { + break; + } else { + continue; + } + } + if (cmsg->cmsg_type == SCTP_NXTINFO) { + nxtinfo = (struct sctp_nxtinfo *)CMSG_DATA(cmsg); + if (rcvinfo != NULL) { + break; + } else { + continue; + } + } + } + if (rcvinfo != NULL) { + if ((nxtinfo != NULL) && (*infolen >= sizeof(struct sctp_recvv_rn))) { + struct sctp_recvv_rn *rn_info; + + rn_info = (struct sctp_recvv_rn *)info; + rn_info->recvv_rcvinfo = *rcvinfo; + rn_info->recvv_nxtinfo = *nxtinfo; + *infolen = (socklen_t) sizeof(struct sctp_recvv_rn); + *infotype = SCTP_RECVV_RN; + } else if (*infolen >= sizeof(struct sctp_rcvinfo)) { + memcpy(info, rcvinfo, sizeof(struct sctp_rcvinfo)); + *infolen = (socklen_t) sizeof(struct sctp_rcvinfo); + *infotype = SCTP_RECVV_RCVINFO; + } + } else if (nxtinfo != NULL) { + if (*infolen >= sizeof(struct sctp_nxtinfo)) { + memcpy(info, nxtinfo, sizeof(struct sctp_nxtinfo)); + *infolen = (socklen_t) sizeof(struct sctp_nxtinfo); + *infotype = SCTP_RECVV_NXTINFO; + } + } + } + return (ret); +} + +ssize_t +sctp_sendv(int sd, + const struct iovec *iov, int iovcnt, + struct sockaddr *addrs, int addrcnt, + void *info, socklen_t infolen, unsigned int infotype, + int flags) +{ + ssize_t ret; + int i; + socklen_t addr_len; + struct msghdr msg; + in_port_t port; + struct sctp_sendv_spa *spa_info; + struct cmsghdr *cmsg; + char *cmsgbuf; + struct sockaddr *addr; + struct sockaddr_in *addr_in; + struct sockaddr_in6 *addr_in6; + sctp_assoc_t *assoc_id; + + if ((addrcnt < 0) || + (iovcnt < 0) || + ((addrs == NULL) && (addrcnt > 0)) || + ((addrs != NULL) && (addrcnt == 0)) || + ((iov == NULL) && (iovcnt > 0)) || + ((iov != NULL) && (iovcnt == 0))) { + errno = EINVAL; + return (-1); + } + cmsgbuf = malloc(CMSG_SPACE(sizeof(struct sctp_sndinfo)) + + CMSG_SPACE(sizeof(struct sctp_prinfo)) + + CMSG_SPACE(sizeof(struct sctp_authinfo)) + + (size_t)addrcnt * CMSG_SPACE(sizeof(struct in6_addr))); + if (cmsgbuf == NULL) { + errno = ENOMEM; + return (-1); + } + assoc_id = NULL; + msg.msg_control = cmsgbuf; + msg.msg_controllen = 0; + cmsg = (struct cmsghdr *)cmsgbuf; + switch (infotype) { + case SCTP_SENDV_NOINFO: + if ((infolen != 0) || (info != NULL)) { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + break; + case SCTP_SENDV_SNDINFO: + if ((info == NULL) || (infolen < sizeof(struct sctp_sndinfo))) { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo)); + memcpy(CMSG_DATA(cmsg), info, sizeof(struct sctp_sndinfo)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_sndinfo))); + assoc_id = &(((struct sctp_sndinfo *)info)->snd_assoc_id); + break; + case SCTP_SENDV_PRINFO: + if ((info == NULL) || (infolen < sizeof(struct sctp_prinfo))) { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_PRINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo)); + memcpy(CMSG_DATA(cmsg), info, sizeof(struct sctp_prinfo)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_prinfo))); + break; + case SCTP_SENDV_AUTHINFO: + if ((info == NULL) || (infolen < sizeof(struct sctp_authinfo))) { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_AUTHINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_authinfo)); + memcpy(CMSG_DATA(cmsg), info, sizeof(struct sctp_authinfo)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_authinfo)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_authinfo))); + break; + case SCTP_SENDV_SPA: + if ((info == NULL) || (infolen < sizeof(struct sctp_sendv_spa))) { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + spa_info = (struct sctp_sendv_spa *)info; + if (spa_info->sendv_flags & SCTP_SEND_SNDINFO_VALID) { + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo)); + memcpy(CMSG_DATA(cmsg), &spa_info->sendv_sndinfo, sizeof(struct sctp_sndinfo)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_sndinfo))); + assoc_id = &(spa_info->sendv_sndinfo.snd_assoc_id); + } + if (spa_info->sendv_flags & SCTP_SEND_PRINFO_VALID) { + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_PRINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo)); + memcpy(CMSG_DATA(cmsg), &spa_info->sendv_prinfo, sizeof(struct sctp_prinfo)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_prinfo))); + } + if (spa_info->sendv_flags & SCTP_SEND_AUTHINFO_VALID) { + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_AUTHINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_authinfo)); + memcpy(CMSG_DATA(cmsg), &spa_info->sendv_authinfo, sizeof(struct sctp_authinfo)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_authinfo)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_authinfo))); + } + break; + default: + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + addr = addrs; + msg.msg_name = NULL; + msg.msg_namelen = 0; + + for (i = 0; i < addrcnt; i++) { + switch (addr->sa_family) { + case AF_INET: + addr_len = (socklen_t) sizeof(struct sockaddr_in); + addr_in = (struct sockaddr_in *)addr; + if (addr_in->sin_len != addr_len) { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + if (i == 0) { + port = addr_in->sin_port; + } else { + if (port == addr_in->sin_port) { + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_DSTADDRV4; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); + memcpy(CMSG_DATA(cmsg), &addr_in->sin_addr, sizeof(struct in_addr)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct in_addr)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct in_addr))); + } else { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + } + break; + case AF_INET6: + addr_len = (socklen_t) sizeof(struct sockaddr_in6); + addr_in6 = (struct sockaddr_in6 *)addr; + if (addr_in6->sin6_len != addr_len) { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + if (i == 0) { + port = addr_in6->sin6_port; + } else { + if (port == addr_in6->sin6_port) { + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_DSTADDRV6; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_addr)); + memcpy(CMSG_DATA(cmsg), &addr_in6->sin6_addr, sizeof(struct in6_addr)); + msg.msg_controllen += CMSG_SPACE(sizeof(struct in6_addr)); + cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct in6_addr))); + } else { + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + } + break; + default: + free(cmsgbuf); + errno = EINVAL; + return (-1); + } + if (i == 0) { + msg.msg_name = addr; + msg.msg_namelen = addr_len; + } + addr = (struct sockaddr *)((caddr_t)addr + addr_len); + } + if (msg.msg_controllen == 0) { + msg.msg_control = NULL; + } + msg.msg_iov = (struct iovec *)iov; + msg.msg_iovlen = iovcnt; + msg.msg_flags = 0; + ret = sendmsg(sd, &msg, flags); + free(cmsgbuf); + if ((ret >= 0) && (addrs != NULL) && (assoc_id != NULL)) { + *assoc_id = sctp_getassocid(sd, addrs); + } + return (ret); +} + + +#if !defined(SYS_sctp_peeloff) && !defined(HAVE_SCTP_PEELOFF_SOCKOPT) + +int +sctp_peeloff(int sd, sctp_assoc_t assoc_id) +{ + /* NOT supported, return invalid sd */ + errno = ENOTSUP; + return (-1); +} + +#endif +#if defined(SYS_sctp_peeloff) && !defined(HAVE_SCTP_PEELOFF_SOCKOPT) +int +sctp_peeloff(int sd, sctp_assoc_t assoc_id) +{ + return (syscall(SYS_sctp_peeloff, sd, assoc_id)); +} + +#endif + +#undef SCTP_CONTROL_VEC_SIZE_RCV diff --git a/lib/libc/net/sockatmark.3 b/lib/libc/net/sockatmark.3 new file mode 100644 index 0000000..c847819 --- /dev/null +++ b/lib/libc/net/sockatmark.3 @@ -0,0 +1,123 @@ +.\" Copyright (c) 2002 William C. Fenner. 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/sockatmark.3 108087 2002-12-19 09:40:28Z ru $ +.\" +.Dd October 13, 2002 +.Dt SOCKATMARK 3 +.Os +.Sh NAME +.Nm sockatmark +.Nd determine whether the read pointer is at the OOB mark +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/socket.h +.Ft int +.Fn sockatmark "int s" +.Sh DESCRIPTION +To find out if the read pointer is currently pointing at +the mark in the data stream, the +.Fn sockatmark +function is provided. +If +.Fn sockatmark +returns 1, the next read will return data +after the mark. +Otherwise (assuming out of band data has arrived), +the next read will provide data sent by the client prior +to transmission of the out of band signal. +The routine used +in the remote login process to flush output on receipt of an +interrupt or quit signal is shown below. +It reads the normal data up to the mark (to discard it), +then reads the out-of-band byte. +.Bd -literal -offset indent +#include +\&... +oob() +{ + int out = FWRITE, mark; + char waste[BUFSIZ]; + + /* flush local terminal output */ + ioctl(1, TIOCFLUSH, (char *)&out); + for (;;) { + if ((mark = sockatmark(rem)) < 0) { + perror("sockatmark"); + break; + } + if (mark) + break; + (void) read(rem, waste, sizeof (waste)); + } + if (recv(rem, &mark, 1, MSG_OOB) < 0) { + perror("recv"); + ... + } + ... +} +.Ed +.Sh RETURN VALUES +Upon successful completion, the +.Fn sockatmark +function returns the value 1 if the read pointer is pointing at +the OOB mark, 0 if it is not. +Otherwise the value \-1 is returned +and the global variable +.Va errno +is set to +indicate the error. +.Sh ERRORS +The +.Fn sockatmark +call fails if: +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa s +argument +is not a valid descriptor. +.It Bq Er ENOTTY +The +.Fa s +argument +is a descriptor for a file, not a socket. +.El +.Sh SEE ALSO +.Xr recv 2 , +.Xr send 2 +.Sh HISTORY +The +.Fn sockatmark +function was introduced by +.St -p1003.1-2001 , +to standardize the historical +.Dv SIOCATMARK +.Xr ioctl 2 . +The +.Er ENOTTY +error instead of the usual +.Er ENOTSOCK +is to match the historical behavior of +.Dv SIOCATMARK . diff --git a/lib/libc/net/sourcefilter.3 b/lib/libc/net/sourcefilter.3 new file mode 100644 index 0000000..3c09b9f --- /dev/null +++ b/lib/libc/net/sourcefilter.3 @@ -0,0 +1,239 @@ +.\" Copyright (c) 2007-2009 Bruce Simpson. +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/net/sourcefilter.3 267774 2014-06-23 08:25:03Z bapt $ +.\" +.Dd February 13, 2009 +.Dt SOURCEFILTER 3 +.Os +.Sh NAME +.Nm sourcefilter +.Nd advanced multicast group membership API +.Sh SYNOPSIS +.In sys/socket.h +.In netinet/in.h +.Ft int +.Fo getipv4sourcefilter +.Fa "int s" +.Fa "struct in_addr interface" +.Fa "struct in_addr group" +.Fa "uint32_t *fmode" +.Fa "uint32_t *numsrc" +.Fa "struct in_addr *slist" +.Fc +.Ft int +.Fo getsourcefilter +.Fa "int s" +.Fa "uint32_t interface" +.Fa "struct sockaddr *group" +.Fa "socklen_t grouplen" +.Fa "uint32_t *fmode" +.Fa "uint32_t *numsrc" +.Fa "struct sockaddr_storage *slist" +.Fc +.Ft int +.Fo setipv4sourcefilter +.Fa "int s" +.Fa "struct in_addr interface" +.Fa "struct in_addr group" +.Fa "uint32_t fmode" +.Fa "uint32_t numsrc" +.Fa "struct in_addr *slist" +.Fc +.Ft int +.Fo setsourcefilter +.Fa "int s" +.Fa "uint32_t interface" +.Fa "struct sockaddr *group" +.Fa "socklen_t grouplen" +.Fa "uint32_t fmode" +.Fa "uint32_t numsrc" +.Fa "struct sockaddr_storage *slist" +.Fc +.Sh DESCRIPTION +The +.Nm +functions implement the advanced, full-state multicast API +defined in RFC 3678. +An application may use these functions to atomically set and +retrieve the multicast source address filters associated with a socket +.Fa s +and a multicast +.Fa group . +.Pp +The functions +.Fn getipv4sourcefilter +and +.Fn getsourcefilter +allow an application to discover the filter mode, and +source filter entries, +for an existing group membership. +.Pp +The kernel will always return the number of source filter +entries on the socket for that group in +.Fa *numsrc . +If the +.Fa *numsrc +argument is non-zero, the kernel will attempt to return up to +.Fa *numsrc +filter entries in the array pointed to by +.Fa slist . +The +.Fa *numsrc +argument may be set to 0, in which case the +.Fa slist +argument will be ignored. +.Pp +For the +.Fn setipv4sourcefilter +and +.Fn setsourcefilter +functions, +the +.Fa fmode +argument may be used to place the socket into inclusive or exclusive +group membership modes, by using the +.Dv MCAST_INCLUDE +or +.Dv MCAST_EXCLUDE +constants respectively. +The +.Fa numsrc +argument specifies the number of source entries in the +.Fa slist +array. +If the +.Fa numsrc +argument has a value of 0, +all source filters will be removed from the socket. +Removing all source filters from a membership which is in the +.Dv MCAST_INCLUDE +filter mode will cause the group to be left on that socket. +.Pp +The protocol-independent function +.Fn setsourcefilter +allows an application to join a multicast group on an interface +which may not have an assigned protocol address, +by passing its index for the +.Fa interface +argument. +.Pp +Any changes made by these functions +will be communicated to IGMPv3 and/or MLDv2 routers +on the local network as appropriate. +If no IGMPv3 or MLDv2 routers are present, changes in the source filter +lists made by these functions will not cause +state changes to be transmitted, with the exception of any +change which causes a group to be joined or left. +The kernel will continue to maintain the source filter state +regardless of the IGMP or MLD version in use on the link. +.Sh IMPLEMENTATION NOTES +The IPv4 specific versions of these functions are implemented in terms +of the protocol-independent functions. +Application writers are encouraged to use the protocol-independent functions +for efficiency, and forwards compatibility with IPv6 networks. +.Pp +For the protocol-independent functions +.Fn getsourcefilter +and +.Fn setsourcefilter , +the +.Fa grouplen +argument specifies the size of the structure pointed to by +.Fa group . +This is required in order to differentiate between different +address families. +.Pp +Currently +.Fx +does not support source address selection for the IPv4 +protocol family, therefore the use of multicast APIs with +an unnumbered IPv4 interface is +.Em not recommended. +In all cases, the first assigned IPv4 address on the interface +will be used as the source address of IGMP control traffic. +If this address is removed or changed, the results are undefined. +.Sh RETURN VALUES +.Rv -std getsourcefilter getipv4sourcefilter setsourcefilter setipv4sourcefilter +.Sh ERRORS +The +.Nm +functions may fail because of: +.Bl -tag -width Er +.It Bq Er EADDRNOTAVAIL +The network interface which the +.Dv interface +argument refers to was not configured in the system, +or the system is not a member of the +.Dv group . +.It Bq Er EAFNOSUPPORT +The +.Dv group +and/or one or more of the +.Dv slist +arguments were of an address family unsupported by the system, +or the address family of the +.Dv group +and +.Dv slist +arguments were not identical. +.It Bq Er EINVAL +The +.Dv group +argument does not contain a multicast address. +The +.Dv fmode +argument is invalid; it must be set to either +.Dv MCAST_INCLUDE +or +.Dv MCAST_EXCLUDE . +The +.Dv numsrc +or +.Dv slist +arguments do not specify a source list. +.It Bq Er ENOMEM +Insufficient memory was available to carry out the requested +operation. +.El +.Sh SEE ALSO +.Xr ip 4 , +.Xr ip6 4 , +.Xr multicast 4 , +.Xr ifmcstat 8 +.Rs +.%A D. Thaler +.%A B. Fenner +.%A B. Quinn +.%T "Socket Interface Extensions for Multicast Source Filters" +.%N RFC 3678 +.%D Jan 2004 +.Re +.Sh HISTORY +The +.Nm +functions first appeared in +.Fx 7.0 . +.Sh AUTHORS +.An Bruce M. Simpson Aq Mt bms@FreeBSD.org diff --git a/lib/libc/net/sourcefilter.c b/lib/libc/net/sourcefilter.c new file mode 100644 index 0000000..87b9471 --- /dev/null +++ b/lib/libc/net/sourcefilter.c @@ -0,0 +1,402 @@ +/*- + * Copyright (c) 2007-2009 Bruce Simpson. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/net/sourcefilter.c 298226 2016-04-18 21:05:15Z avos $"); + +#include "namespace.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "un-namespace.h" + +/* + * Advanced (Full-state) multicast group membership APIs [RFC3678] + * Currently this module assumes IPv4 support (INET) in the base system. + */ +#ifndef INET +#define INET +#endif + +union sockunion { + struct sockaddr_storage ss; + struct sockaddr sa; + struct sockaddr_dl sdl; +#ifdef INET + struct sockaddr_in sin; +#endif +#ifdef INET6 + struct sockaddr_in6 sin6; +#endif +}; +typedef union sockunion sockunion_t; + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +/* + * Internal: Map an IPv4 unicast address to an interface index. + * This is quite inefficient so it is recommended applications use + * the newer, more portable, protocol independent API. + */ +static uint32_t +__inaddr_to_index(in_addr_t ifaddr) +{ + struct ifaddrs *ifa; + struct ifaddrs *ifaddrs; + char *ifname; + int ifindex; + sockunion_t *psu; + + if (getifaddrs(&ifaddrs) < 0) + return (0); + + ifindex = 0; + ifname = NULL; + + /* + * Pass #1: Find the ifaddr entry corresponding to the + * supplied IPv4 address. We should really use the ifindex + * consistently for matches, however it is not available to + * us on this pass. + */ + for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { + psu = (sockunion_t *)ifa->ifa_addr; + if (psu && psu->ss.ss_family == AF_INET && + psu->sin.sin_addr.s_addr == ifaddr) { + ifname = ifa->ifa_name; + break; + } + } + if (ifname == NULL) + goto out; + + /* + * Pass #2: Find the index of the interface matching the name + * we obtained from looking up the IPv4 ifaddr in pass #1. + * There must be a better way of doing this. + */ + for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { + psu = (sockunion_t *)ifa->ifa_addr; + if (psu && psu->ss.ss_family == AF_LINK && + strcmp(ifa->ifa_name, ifname) == 0) { + ifindex = LLINDEX(&psu->sdl); + break; + } + } + assert(ifindex != 0); + +out: + freeifaddrs(ifaddrs); + return (ifindex); +} + +/* + * Set IPv4 source filter list in use on socket. + * + * Stubbed to setsourcefilter(). Performs conversion of structures which + * may be inefficient; applications are encouraged to use the + * protocol-independent API. + */ +int +setipv4sourcefilter(int s, struct in_addr interface, struct in_addr group, + uint32_t fmode, uint32_t numsrc, struct in_addr *slist) +{ +#ifdef INET + sockunion_t tmpgroup; + struct in_addr *pina; + sockunion_t *psu, *tmpslist; + int err; + size_t i; + uint32_t ifindex; + + assert(s != -1); + + tmpslist = NULL; + + if (!IN_MULTICAST(ntohl(group.s_addr)) || + (fmode != MCAST_INCLUDE && fmode != MCAST_EXCLUDE)) { + errno = EINVAL; + return (-1); + } + + ifindex = __inaddr_to_index(interface.s_addr); + if (ifindex == 0) { + errno = EADDRNOTAVAIL; + return (-1); + } + + memset(&tmpgroup, 0, sizeof(sockunion_t)); + tmpgroup.sin.sin_family = AF_INET; + tmpgroup.sin.sin_len = sizeof(struct sockaddr_in); + tmpgroup.sin.sin_addr = group; + + if (numsrc != 0 || slist != NULL) { + tmpslist = calloc(numsrc, sizeof(sockunion_t)); + if (tmpslist == NULL) { + errno = ENOMEM; + return (-1); + } + + pina = slist; + psu = tmpslist; + for (i = 0; i < numsrc; i++, pina++, psu++) { + psu->sin.sin_family = AF_INET; + psu->sin.sin_len = sizeof(struct sockaddr_in); + psu->sin.sin_addr = *pina; + } + } + + err = setsourcefilter(s, ifindex, (struct sockaddr *)&tmpgroup, + sizeof(struct sockaddr_in), fmode, numsrc, + (struct sockaddr_storage *)tmpslist); + + if (tmpslist != NULL) + free(tmpslist); + + return (err); +#else /* !INET */ + return (EAFNOSUPPORT); +#endif /* INET */ +} + +/* + * Get IPv4 source filter list in use on socket. + * + * Stubbed to getsourcefilter(). Performs conversion of structures which + * may be inefficient; applications are encouraged to use the + * protocol-independent API. + * An slist of NULL may be used for guessing the required buffer size. + */ +int +getipv4sourcefilter(int s, struct in_addr interface, struct in_addr group, + uint32_t *fmode, uint32_t *numsrc, struct in_addr *slist) +{ + sockunion_t *psu, *tmpslist; + sockunion_t tmpgroup; + struct in_addr *pina; + int err; + size_t i; + uint32_t ifindex, onumsrc; + + assert(s != -1); + assert(fmode != NULL); + assert(numsrc != NULL); + + onumsrc = *numsrc; + *numsrc = 0; + tmpslist = NULL; + + if (!IN_MULTICAST(ntohl(group.s_addr)) || + (onumsrc != 0 && slist == NULL)) { + errno = EINVAL; + return (-1); + } + + ifindex = __inaddr_to_index(interface.s_addr); + if (ifindex == 0) { + errno = EADDRNOTAVAIL; + return (-1); + } + + memset(&tmpgroup, 0, sizeof(sockunion_t)); + tmpgroup.sin.sin_family = AF_INET; + tmpgroup.sin.sin_len = sizeof(struct sockaddr_in); + tmpgroup.sin.sin_addr = group; + + if (onumsrc != 0 || slist != NULL) { + tmpslist = calloc(onumsrc, sizeof(sockunion_t)); + if (tmpslist == NULL) { + errno = ENOMEM; + return (-1); + } + } + + err = getsourcefilter(s, ifindex, (struct sockaddr *)&tmpgroup, + sizeof(struct sockaddr_in), fmode, numsrc, + (struct sockaddr_storage *)tmpslist); + + if (tmpslist != NULL && *numsrc != 0) { + pina = slist; + psu = tmpslist; + for (i = 0; i < MIN(onumsrc, *numsrc); i++, psu++) { + if (psu->ss.ss_family != AF_INET) + continue; + *pina++ = psu->sin.sin_addr; + } + free(tmpslist); + } + + return (err); +} + +/* + * Set protocol-independent source filter list in use on socket. + */ +int +setsourcefilter(int s, uint32_t interface, struct sockaddr *group, + socklen_t grouplen, uint32_t fmode, uint32_t numsrc, + struct sockaddr_storage *slist) +{ + struct __msfilterreq msfr; + sockunion_t *psu; + int level, optname; + + if (fmode != MCAST_INCLUDE && fmode != MCAST_EXCLUDE) { + errno = EINVAL; + return (-1); + } + + psu = (sockunion_t *)group; + switch (psu->ss.ss_family) { +#ifdef INET + case AF_INET: + if ((grouplen != sizeof(struct sockaddr_in) || + !IN_MULTICAST(ntohl(psu->sin.sin_addr.s_addr)))) { + errno = EINVAL; + return (-1); + } + level = IPPROTO_IP; + optname = IP_MSFILTER; + break; +#endif +#ifdef INET6 + case AF_INET6: + if (grouplen != sizeof(struct sockaddr_in6) || + !IN6_IS_ADDR_MULTICAST(&psu->sin6.sin6_addr)) { + errno = EINVAL; + return (-1); + } + level = IPPROTO_IPV6; + optname = IPV6_MSFILTER; + break; +#endif + default: + errno = EAFNOSUPPORT; + return (-1); + } + + memset(&msfr, 0, sizeof(msfr)); + msfr.msfr_ifindex = interface; + msfr.msfr_fmode = fmode; + msfr.msfr_nsrcs = numsrc; + memcpy(&msfr.msfr_group, &psu->ss, psu->ss.ss_len); + msfr.msfr_srcs = slist; /* pointer */ + + return (_setsockopt(s, level, optname, &msfr, sizeof(msfr))); +} + +/* + * Get protocol-independent source filter list in use on socket. + * An slist of NULL may be used for guessing the required buffer size. + */ +int +getsourcefilter(int s, uint32_t interface, struct sockaddr *group, + socklen_t grouplen, uint32_t *fmode, uint32_t *numsrc, + struct sockaddr_storage *slist) +{ + struct __msfilterreq msfr; + sockunion_t *psu; + socklen_t optlen; + int err, level, nsrcs, optname; + + if (interface == 0 || group == NULL || numsrc == NULL || + fmode == NULL) { + errno = EINVAL; + return (-1); + } + + nsrcs = *numsrc; + *numsrc = 0; + *fmode = 0; + + psu = (sockunion_t *)group; + switch (psu->ss.ss_family) { +#ifdef INET + case AF_INET: + if ((grouplen != sizeof(struct sockaddr_in) || + !IN_MULTICAST(ntohl(psu->sin.sin_addr.s_addr)))) { + errno = EINVAL; + return (-1); + } + level = IPPROTO_IP; + optname = IP_MSFILTER; + break; +#endif +#ifdef INET6 + case AF_INET6: + if (grouplen != sizeof(struct sockaddr_in6) || + !IN6_IS_ADDR_MULTICAST(&psu->sin6.sin6_addr)) { + errno = EINVAL; + return (-1); + } + level = IPPROTO_IPV6; + optname = IPV6_MSFILTER; + break; +#endif + default: + errno = EAFNOSUPPORT; + return (-1); + break; + } + + optlen = sizeof(struct __msfilterreq); + memset(&msfr, 0, optlen); + msfr.msfr_ifindex = interface; + msfr.msfr_fmode = 0; + msfr.msfr_nsrcs = nsrcs; + memcpy(&msfr.msfr_group, &psu->ss, psu->ss.ss_len); + + /* + * msfr_srcs is a pointer to a vector of sockaddr_storage. It + * may be NULL. The kernel will always return the total number + * of filter entries for the group in msfr.msfr_nsrcs. + */ + msfr.msfr_srcs = slist; + err = _getsockopt(s, level, optname, &msfr, &optlen); + if (err == 0) { + *numsrc = msfr.msfr_nsrcs; + *fmode = msfr.msfr_fmode; + } + + return (err); +} diff --git a/lib/libc/nls/Makefile.inc b/lib/libc/nls/Makefile.inc new file mode 100644 index 0000000..9f101c7 --- /dev/null +++ b/lib/libc/nls/Makefile.inc @@ -0,0 +1,41 @@ +# from $NetBSD: Makefile.inc,v 1.7 1995/02/27 13:06:20 cgd Exp $ +# $FreeBSD: releng/11.1/lib/libc/nls/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +.PATH: ${LIBC_SRCTOP}/nls + +SRCS+= msgcat.c + +SYM_MAPS+=${LIBC_SRCTOP}/nls/Symbol.map + +MAN+= catclose.3 catgets.3 catopen.3 + +# NOTE: C.msg should not be processed here, it's used as a template +# for translators. + +NLSNAME= libc +NLS+= be_BY.UTF-8 +NLS+= ca_ES.ISO8859-1 +NLS+= de_DE.ISO8859-1 +NLS+= el_GR.ISO8859-7 +NLS+= es_ES.ISO8859-1 +NLS+= fi_FI.ISO8859-1 +NLS+= fr_FR.ISO8859-1 +NLS+= gl_ES.ISO8859-1 +NLS+= hu_HU.ISO8859-2 +NLS+= it_IT.ISO8859-15 +NLS+= ja_JP.UTF-8 +NLS+= ja_JP.eucJP +NLS+= ko_KR.UTF-8 +NLS+= ko_KR.eucKR +NLS+= mn_MN.UTF-8 +NLS+= nl_NL.ISO8859-1 +NLS+= no_NO.ISO8859-1 +NLS+= pl_PL.ISO8859-2 +NLS+= pt_BR.ISO8859-1 +NLS+= ru_RU.KOI8-R +NLS+= sk_SK.ISO8859-2 +NLS+= sv_SE.ISO8859-1 +NLS+= uk_UA.UTF-8 +NLS+= zh_CN.GB18030 +NLS+= zh_CN.GB2312 +NLS+= zh_CN.UTF-8 diff --git a/lib/libc/nls/Symbol.map b/lib/libc/nls/Symbol.map new file mode 100644 index 0000000..ea5daea --- /dev/null +++ b/lib/libc/nls/Symbol.map @@ -0,0 +1,9 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/nls/Symbol.map 169092 2007-04-29 14:05:22Z deischen $ + */ + +FBSD_1.0 { + catopen; + catgets; + catclose; +}; diff --git a/lib/libc/nls/be_BY.UTF-8.msg b/lib/libc/nls/be_BY.UTF-8.msg new file mode 100644 index 0000000..e5adac3 --- /dev/null +++ b/lib/libc/nls/be_BY.UTF-8.msg @@ -0,0 +1,249 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/be_BY.UTF-8.msg 192653 2009-05-23 17:13:35Z des $ +$ +$ Message catalog for be_BY.UTF-8 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Аперацыя не дазволена +$ ENOENT +2 Няма такога файлу ці каталогу +$ ESRCH +3 Няма такога працэсу +$ EINTR +4 Перарваны сістэмны выклік +$ EIO +5 Памылка ўводу/вываду +$ ENXIO +6 Прыстасаванне не сканфігуравана +$ E2BIG +7 Надта доўгі спіс аргументаў +$ ENOEXEC +8 Памылка фармату файлу, які выконваецца +$ EBADF +9 Некарэктны дэскрыптар файлу +$ ECHILD +10 Няма дачэрніх працэсаў +$ EDEADLK +11 Прадухілена ўзаемная блакіроўка падчас доступу да рэсурсу +$ ENOMEM +12 Не дастае памяці +$ EACCES +13 Не дастае прывілеяў +$ EFAULT +14 Некарэктны адрас +$ ENOTBLK +15 Неабходна блочнае прыстасаванне +$ EBUSY +16 Прыстасаванне занятае +$ EEXIST +17 Файл існуе +$ EXDEV +18 Спасылка на іншае прыстасаванне +$ ENODEV +19 Аперацыя не падтрымліваецца прыстасаваннем +$ ENOTDIR +20 Пазначаны файл не з'яўляецца каталогам +$ EISDIR +21 Пазначаны файл з'яўляецца каталогам +$ EINVAL +22 Недапушчальны аргумент +$ ENFILE +23 Надта шмат адчыненых файлаў у сістэме +$ EMFILE +24 Надта шмат адчыненых файлаў +$ ENOTTY +25 Выклік ioctl не падтрымліваецца прыстасаваннем +$ ETXTBSY +26 Текставы файл заняты +$ EFBIG +27 Надта вялікі файл +$ ENOSPC +28 На прыстасаванні не засталося месца +$ ESPIPE +29 Недапушчальнае пазіцыянаванне +$ EROFS +30 Файлавая сістэма толькі для чытання +$ EMLINK +31 Надта шмат спасылак +$ EPIPE +32 Канал пашкоджаны +$ EDOM +33 Недапушчальнае значэнне лічбавага аргументу +$ ERANGE +34 Надта вялікі рэзультат +$ EAGAIN, EWOULDBLOCK +35 Рэсурс часова недаступны +$ EINPROGRESS +36 Аперацыя ў працэсе выканання +$ EALREADY +37 Аперацыя ўжо выконваецца +$ ENOTSOCK +38 Аперацыя з сокетам прыменена не да сокету +$ EDESTADDRREQ +39 Патрабуецца адрас прызначэння +$ EMSGSIZE +40 Надта доўгае паведамленне +$ EPROTOTYPE +41 Няправільны тып пратаколу для сокету +$ ENOPROTOOPT +42 Пратакол недаступны +$ EPROTONOSUPPORT +43 Пратакол не падтрымліваецца +$ ESOCKTNOSUPPORT +44 Тып сокету не падтрымліваецца +$ EOPNOTSUPP +45 Аперацыя не падтрымліваецца +$ EPFNOSUPPORT +46 Сямейства пратаколаў не падтрымліваецца +$ EAFNOSUPPORT +47 Сямейства адрасоў не падтрымліваецца сямействам пратаколаў +$ EADDRINUSE +48 Адрас ўжо выкарыстоўваецца +$ EADDRNOTAVAIL +49 Не магчыма прызначыць дадзены адрас +$ ENETDOWN +50 Сетка не працуе +$ ENETUNREACH +51 Сетка недасяжна +$ ENETRESET +52 Злучэнне прыпынена сеткай +$ ECONNABORTED +53 Праграма выклікала аварыйнае завяршэнне злучэння +$ ECONNRESET +54 Злучэнне завяршана супрацьлеглым бокам +$ ENOBUFS +55 Не засталося месца пад буфер +$ EISCONN +56 Сокет ужо падлучаны +$ ENOTCONN +57 Сокет не падлучаны +$ ESHUTDOWN +58 Не магчыма дасылаць пасля закрыцця сокету +$ ETOOMANYREFS +59 Надта шмат спасылак: не магчыма злучыць +$ ETIMEDOUT +60 Аперацыя перавысіла часавы ліміт +$ ECONNREFUSED +61 У злучэнні адмоўлена +$ ELOOP +62 Надта шмат узроўняў сімвальных спасылак +$ ENAMETOOLONG +63 Надта доўгае імя файлу +$ EHOSTDOWN +64 Хост не працуе +$ EHOSTUNREACH +65 Няма маршруту да хосту +$ ENOTEMPTY +66 Каталог не пусты +$ EPROCLIM +67 Надта шмат працэсаў +$ EUSERS +68 Надта шмат карыстальнікаў +$ EDQUOT +69 Перавышана дыскавая квота +$ ESTALE +70 Састарэлы дэскрыптар файлу NFS +$ EREMOTE +71 Надта шмат дыстанцыйных пераходаў на шляху +$ EBADRPC +72 Некарэктная структура RPC +$ ERPCMISMATCH +73 Няправільная версія RPC +$ EPROGUNAVAIL +74 Праграма RPC недасяжная +$ EPROGMISMATCH +75 Няправільная версія праграмы +$ EPROCUNAVAIL +76 Некарэктная працэдура для праграмы +$ ENOLCK +77 Блакіроўкі недаступны +$ ENOSYS +78 Функцыя не рэалізавана +$ EFTYPE +79 Непадыходзячы тып ці фармат файлу +$ EAUTH +80 Памылка аўтэнтыфікацыі +$ ENEEDAUTH +81 Неабходна аўтэнтыфікацыя +$ EIDRM +82 Ідэнтыфікатар выдалены +$ ENOMSG +83 Няма паведамлення патрэбнага тыпу +$ EOVERFLOW +84 Надта вялікае значэнне для захоўвання ў пазначаным тыпе дадзеных +$ ECANCELED +85 Аперацыя адменена +$ EILSEQ +86 Недазволеная паслядоўнасць байтаў +$ ENOATTR +87 Атрыбут не знойдзены +$ EDOOFUS +88 Памылка праграмавання +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Разрыў сувязі +$ SIGINT +2 Перарванне па сігналу +$ SIGQUIT +3 Выхад +$ SIGILL +4 Недапушчальная інструкцыя +$ SIGTRAP +5 Пастка трасіроўкі/кропкі спынення +$ SIGABRT +6 Пастка аварыйнага завяршэння +$ SIGEMT +7 Пастка EMT +$ SIGFPE +8 Памылка падчас працы з рэчыўным лікам +$ SIGKILL +9 Прымусова спынены +$ SIGBUS +10 Памылка шыны +$ SIGSEGV +11 Памылка сегментацыі +$ SIGSYS +12 Недапушчальны сістэмны выклік +$ SIGPIPE +13 Канал пашкоджаны +$ SIGALRM +14 Спрацаваў таймер +$ SIGTERM +15 Завершаны +$ SIGURG +16 Неабходны тэрміновы ўвод-вывад +$ SIGSTOP +17 Прыпыненне (сігнал) +$ SIGTSTP +18 Прыпыненне +$ SIGCONT +19 Працяг працы +$ SIGCHLD +20 Завершана праца дачэрняга працэсу +$ SIGTTIN +21 Спынены (увод з тэрміналу) +$ SIGTTOU +22 Спынены (увод на тэрмінал) +$ SIGIO +23 Увод-вывад магчымы +$ SIGXCPU +24 Перавышана абмежаванне працэсарнага часу +$ SIGXFSZ +25 Перавышаны максімальны памер файлу +$ SIGVTALRM +26 Вычарпаны віртуальны таймер +$ SIGPROF +27 Вычарпаны таймер прафілявання +$ SIGWINCH +28 Змена памеру вакна +$ SIGINFO +29 Запыт інфармацыі +$ SIGUSR1 +30 Сігнал карыстальніка 1 +$ SIGUSR2 +31 Сігнал карыстальніка 2 diff --git a/lib/libc/nls/ca_ES.ISO8859-1.msg b/lib/libc/nls/ca_ES.ISO8859-1.msg new file mode 100644 index 0000000..a323927 --- /dev/null +++ b/lib/libc/nls/ca_ES.ISO8859-1.msg @@ -0,0 +1,267 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/ca_ES.ISO8859-1.msg 189765 2009-03-13 10:40:38Z gabor $ +$ +$ Message catalog for ca_ES.ISO8859-1 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Operaci� no permesa +$ ENOENT +2 Arxiu o directori inexistent +$ ESRCH +3 Proc�s inexistent +$ EINTR +4 Crida del sistema interrompuda +$ EIO +5 Error d'entrada/sortida +$ ENXIO +6 Dispositiu no configurat +$ E2BIG +7 Llista de par�metres massa llarga +$ ENOEXEC +8 Error en el format de l'executable +$ EBADF +9 Descriptor d'arxiu incorrecte +$ ECHILD +10 No hi ha processos fills +$ EDEADLK +11 S'ha evitat el bloqueig del recurs +$ ENOMEM +12 No es pot assignar la mem�ria demanada +$ EACCES +13 Perm�s denegat +$ EFAULT +14 Adre�a incorrecta +$ ENOTBLK +15 Es necessita un dispositiu de blocs +$ EBUSY +16 Dispositiu ocupat +$ EEXIST +17 L'arxiu ja existeix +$ EXDEV +18 Enlla� entre dispositius +$ ENODEV +19 Operaci� no suportada pel dispositiu +$ ENOTDIR +20 No �s un directori +$ EISDIR +21 �s un directori +$ EINVAL +22 Par�metre incorrecte +$ ENFILE +23 Hi ha massa arxius oberts al sistema +$ EMFILE +24 Hi ha massa arxius oberts +$ ENOTTY +25 L'ioctl no �s adecuat per al dispositiu +$ ETXTBSY +26 Arxiu de text ocupat +$ EFBIG +27 Arxiu massa gran +$ ENOSPC +28 No queda espai lliure en el dispositiu +$ ESPIPE +29 Cerca il�legal +$ EROFS +30 Sistema d'arxius de nom�s lectura +$ EMLINK +31 Massa enlla�os +$ EPIPE +32 Canal (pipe) trencat +$ EDOM +33 El resultat surt fora de rang +$ ERANGE +34 Resultat massa gran +$ EAGAIN, EWOULDBLOCK +35 El recurs no est� disponible temporalment +$ EINPROGRESS +36 L'operaci� es troba en progr�s actualment +$ EALREADY +37 L'operaci� ja es troba en progr�s +$ ENOTSOCK +38 Operaci� de tipus socket en quelcom que no ho �s +$ EDESTADDRREQ +39 Es requereix l'adre�a de dest� +$ EMSGSIZE +40 Missatge massa llarg +$ EPROTOTYPE +41 Tipus de protocol incorrecte per al socket +$ ENOPROTOOPT +42 Protocol no disponible +$ EPROTONOSUPPORT +43 Protocol no suportat +$ ESOCKTNOSUPPORT +44 Tipus de socket no suportat +$ EOPNOTSUPP +45 Operaci� no suportada +$ EPFNOSUPPORT +46 Fam�lia de protocols no suportada +$ EAFNOSUPPORT +47 Fam�lia d'adreces no suportada per la fam�lia de protocols +$ EADDRINUSE +48 L'adre�a ja es troba en �s +$ EADDRNOTAVAIL +49 No es pot assignar l'adre�a demanada +$ ENETDOWN +50 La xarxa no es troba disponible +$ ENETUNREACH +51 No es pot accedir a la xarxa +$ ENETRESET +52 La connexi� a la xarxa s'ha perdut durant la reinicialitzaci� +$ ECONNABORTED +53 El programari ha causat l'avort de la connexi� +$ ECONNRESET +54 L'interlocutor ha reinicialitzat la comunicaci� +$ ENOBUFS +55 No hi ha prou espai per a la memoria interm�dia (buffer) +$ EISCONN +56 El socket ja es troba connectat +$ ENOTCONN +57 El socket no es troba connectat +$ ESHUTDOWN +58 No es pot enviar despr�s de la desconnexi� del socket +$ ETOOMANYREFS +59 Hi ha massa refer�ncies: no es poden unir +$ ETIMEDOUT +60 El temps de connexi� s'ha esgotat +$ ECONNREFUSED +61 Connexi� rebutjada +$ ELOOP +62 Hi ha massa nivells d'enlla�os simb�lics +$ ENAMETOOLONG +63 Nom d'arxiu massa llarg +$ EHOSTDOWN +64 La m�quina no es troba disponible +$ EHOSTUNREACH +65 No hi ha cap cam� fins a la m�quina +$ ENOTEMPTY +66 El directori no est� buit +$ EPROCLIM +67 Hi ha massa processos +$ EUSERS +68 Hi ha massa usuaris +$ EDQUOT +69 Quota de disc sobrepassada +$ ESTALE +70 Descriptor d'arxiu NFS incorrecte +$ EREMOTE +71 Massa nivells en el cam� de dest� +$ EBADRPC +72 L'estructura RPC es incorrecta +$ ERPCMISMATCH +73 La versi� del RPC es incorrecta +$ EPROGUNAVAIL +74 El programa RPC no es troba disponible +$ EPROGMISMATCH +75 Versi� incorrecta del programa +$ EPROCUNAVAIL +76 Procediment erroni per al programa +$ ENOLCK +77 No hi ha bloquejos disponibles +$ ENOSYS +78 Funci� no implementada +$ EFTYPE +79 Tipus d'arxiu o de format inadequat +$ EAUTH +80 Error d'autenticaci� +$ ENEEDAUTH +81 Es necessita un autenticador +$ EIDRM +82 Identificador eliminat +$ ENOMSG +83 No hi ha missatges del tipus desitjat +$ EOVERFLOW +84 Valor massa gran per a �sser emmagatzemat en el tipus de dades +$ EILSEQ +85 Seq��ncia de bytes il�legal +$ ENOTSUP +86 No suportat +$ ECANCELED +87 Operaci� cancel�lada +$ EBADMSG +88 Missatje incorrecte o corrupte +$ ENODATA +89 No hi ha missatges disponibles +$ ENOSR +90 No hi ha recursos de tipus STREAM +$ ENOSTR +91 No �s un STREAM +$ ETIME +92 Temps d'espera esgotat en el ioctl STREAM +$ ENOATTR +93 Atribut inexistent +$ EMULTIHOP +94 S'ha intentat un multisalt +$ ENOLINK +95 L'enlla� s'ha servit +$ EPROTO +96 Error de protocol +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 F� de l�nia (hangup) +$ SIGINT +2 Interrupci� +$ SIGQUIT +3 Finalitzaci� +$ SIGILL +4 Instrucci� il�legal +$ SIGTRAP +5 Depuraci� (Trace/BPT) +$ SIGABRT +6 Crida d'avort +$ SIGEMT +7 Captura d'EMT +$ SIGFPE +8 Excepci� de coma flotant +$ SIGKILL +9 Matat +$ SIGBUS +10 Error del bus +$ SIGSEGV +11 Error de segmentaci� +$ SIGSYS +12 Crida al sistema incorrecta +$ SIGPIPE +13 Canal (pipe) trencat +$ SIGALRM +14 Alarma de rellotge +$ SIGTERM +15 Finalitzat +$ SIGURG +16 Condici� urgent d'E/S +$ SIGSTOP +17 Parat (per senyal) +$ SIGTSTP +18 Parat +$ SIGCONT +19 Continuant +$ SIGCHLD +20 El fill ha acabat +$ SIGTTIN +21 Parat (entrada de tty) +$ SIGTTOU +22 Parat (sortida de tty) +$ SIGIO +23 I/O permesa +$ SIGXCPU +24 S'ha sobrepassat el l�mit de temps de la CPU +$ SIGXFSZ +25 S'ha sobrepassat el l�mit de la longitud de l'arxiu +$ SIGVTALRM +26 El temporitzador virtual ha expirat +$ SIGPROF +27 El temporitzador del perfilador ha expirat +$ SIGWINCH +28 Canvis en la mida de la finestra +$ SIGINFO +29 Demanda d'informaci� +$ SIGUSR1 +30 Senyal 1 definida per l'usuari +$ SIGUSR2 +31 Senyal 2 definida per l'usuari +$ SIGPWR +32 Fallada/reinicialitzaci� de l'alimentaci� diff --git a/lib/libc/nls/catclose.3 b/lib/libc/nls/catclose.3 new file mode 100644 index 0000000..8b23f3e --- /dev/null +++ b/lib/libc/nls/catclose.3 @@ -0,0 +1,64 @@ +.\" Copyright (c) 1994 Winning Strategies, Inc. +.\" 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 Winning Strategies, Inc. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/nls/catclose.3 142665 2005-02-27 16:30:16Z phantom $ +.Dd February 12, 2005 +.Dt CATCLOSE 3 +.Os +.Sh NAME +.Nm catclose +.Nd close message catalog +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In nl_types.h +.Ft int +.Fn catclose "nl_catd catd" +.Sh DESCRIPTION +The +.Fn catclose +function closes the message catalog specified by the argument +.Fa catd . +.Sh RETURN VALUES +.Rv -std catclose +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EBADF +An invalid message catalog descriptor was passed by the +.Fa catd +argument. +.El +.Sh SEE ALSO +.Xr gencat 1 , +.Xr catgets 3 , +.Xr catopen 3 +.Sh STANDARDS +The +.Fn catclose +function conforms to +.St -p1003.1-2001 . diff --git a/lib/libc/nls/catgets.3 b/lib/libc/nls/catgets.3 new file mode 100644 index 0000000..a0ddd69 --- /dev/null +++ b/lib/libc/nls/catgets.3 @@ -0,0 +1,82 @@ +.\" Copyright (c) 1994 Winning Strategies, Inc. +.\" 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 Winning Strategies, Inc. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/nls/catgets.3 147402 2005-06-15 19:04:04Z ru $ +.Dd February 12, 2005 +.Dt CATGETS 3 +.Os +.Sh NAME +.Nm catgets +.Nd retrieve string from message catalog +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In nl_types.h +.Ft char * +.Fn catgets "nl_catd catd" "int set_id" "int msg_id" "const char *s" +.Sh DESCRIPTION +The +.Fn catgets +function attempts to retrieve message +.Fa msg_id +of set +.Fa set_id +from the message catalog referenced by the descriptor +.Fa catd . +The argument +.Fa s +points to a default message which is returned if the function +is unable to retrieve the specified message. +.Sh RETURN VALUES +If the specified message was retrieved successfully, +.Fn catgets +returns a pointer to an internal buffer containing the message string; +otherwise it returns +.Fa s . +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa catd +argument is not a valid message catalog descriptor. +.It Bq Er EBADMSG +The message identified by +.Fa set_id +and +.Fa msg_id +is not in the message catalog. +.El +.Sh SEE ALSO +.Xr gencat 1 , +.Xr catclose 3 , +.Xr catopen 3 +.Sh STANDARDS +The +.Fn catgets +function conforms to +.St -p1003.1-2001 . diff --git a/lib/libc/nls/catopen.3 b/lib/libc/nls/catopen.3 new file mode 100644 index 0000000..d6132cf --- /dev/null +++ b/lib/libc/nls/catopen.3 @@ -0,0 +1,157 @@ +.\" Copyright (c) 1994 Winning Strategies, Inc. +.\" 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 Winning Strategies, Inc. +.\" 4. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +.\" +.\" $FreeBSD: releng/11.1/lib/libc/nls/catopen.3 282006 2015-04-26 10:54:52Z bapt $ +.Dd February 12, 2005 +.Dt CATOPEN 3 +.Os +.Sh NAME +.Nm catopen +.Nd open message catalog +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In nl_types.h +.Ft nl_catd +.Fn catopen "const char *name" "int oflag" +.Sh DESCRIPTION +The +.Fn catopen +function opens the message catalog specified by +.Fa name +and returns a message catalog descriptor. +If +.Fa name +contains a +.Sq / +then +.Fa name +specifies the full pathname for the message catalog, otherwise the value +of the environment variable +.Ev NLSPATH +is used with +the following substitutions: +.Bl -tag -width XXX +.It \&%N +The value of the +.Fa name +argument. +.It \&%L +The value of the +.Ev LANG +environment variable or the +.Dv LC_MESSAGES +category (see below). +.It \&%l +The language element from the +.Ev LANG +environment variable or from the +.Dv LC_MESSAGES +category. +.It \&%t +The territory element from the +.Ev LANG +environment variable or from the +.Dv LC_MESSAGES +category. +.It \&%c +The codeset element from the +.Ev LANG +environment variable or from the +.Dv LC_MESSAGES +category. +.It \&%% +A single % character. +.El +.Pp +An empty string is substituted for undefined values. +.Pp +Path names templates defined in +.Ev NLSPATH +are separated by colons +.Pq Sq \&: . +A leading or two adjacent colons +is equivalent to specifying %N. +.Pp +If the +.Fa oflag +argument is set to the +.Dv NL_CAT_LOCALE +constant, +.Dv LC_MESSAGES +locale category used to open the message catalog; using +.Dv NL_CAT_LOCALE +conforms to the +.St -xpg4 +standard. +You can specify 0 for compatibility with +.St -xpg3 ; +when +.Fa oflag +is set to 0, the +.Ev LANG +environment variable +determines the message catalog locale. +.Pp +A message catalog descriptor +remains valid in a process until that process closes it, or +until a successful call to one of the +.Xr exec 3 +function. +.Sh RETURN VALUES +Upon successful completion, +.Fn catopen +returns a message catalog descriptor. +Otherwise, (nl_catd) -1 is returned and +.Va errno +is set to indicate the error. +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EINVAL +Argument +.Fa name +does not point to a valid message catalog, or catalog is corrupt. +.It Bq Er ENAMETOOLONG +An entire path to the message catalog exceeded 1024 characters. +.It Bq Er ENOENT +The named message catalog does not exists, or the +.Fa name +argument points to an empty string. +.It Bq Er ENOMEM +Insufficient memory is available. +.El +.Sh SEE ALSO +.Xr gencat 1 , +.Xr catclose 3 , +.Xr catgets 3 , +.Xr setlocale 3 +.Sh STANDARDS +The +.Fn catopen +function conforms to +.St -p1003.1-2001 . diff --git a/lib/libc/nls/de_DE.ISO8859-1.msg b/lib/libc/nls/de_DE.ISO8859-1.msg new file mode 100644 index 0000000..d6471ca --- /dev/null +++ b/lib/libc/nls/de_DE.ISO8859-1.msg @@ -0,0 +1,249 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/de_DE.ISO8859-1.msg 190410 2009-03-25 12:36:37Z netchild $ +$ +$ Message catalog for de_DE.ISO8859-1 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Operation nicht erlaubt +$ ENOENT +2 Datei oder Verzeichnis nicht gefunden +$ ESRCH +3 Prozess nicht gefunden +$ EINTR +4 Interrupt innerhalb eines Systemaufrufs +$ EIO +5 Ein-/Ausgabefehler +$ ENXIO +6 Ger�t ist nicht konfiguriert +$ E2BIG +7 Argumentliste ist zu lang +$ ENOEXEC +8 Die Datei hat kein bekanntes ausf�hrbares Format +$ EBADF +9 Ung�ltiger Dateideskriptor +$ ECHILD +10 Keine Kindprozesse +$ EDEADLK +11 Ein Deadlock wurde vermieden +$ ENOMEM +12 Kann nicht genug Speicher belegen +$ EACCES +13 Zugriff verweigert +$ EFAULT +14 Ung�ltige Adresse +$ ENOTBLK +15 Es wird ein Blockger�t ben�tigt +$ EBUSY +16 Das Ger�t ist belegt +$ EEXIST +17 Datei existiert bereits +$ EXDEV +18 Link zwischen verschiedenen Ger�ten +$ ENODEV +19 Die Operation wird von diesem Ger�t nicht unterst�tzt +$ ENOTDIR +20 Kein Verzeichnis +$ EISDIR +21 Ist ein Verzeichnis +$ EINVAL +22 Ung�ltiges Argument +$ ENFILE +23 Zu viele offene Dateien im System +$ EMFILE +24 Zu viele offene Dateien +$ ENOTTY +25 Ung�ltiger IOCTL f�r dieses Ger�t +$ ETXTBSY +26 Datei wird benutzt +$ EFBIG +27 Datei zu gro� +$ ENOSPC +28 Kein Platz mehr auf dem Ger�t +$ ESPIPE +29 Ung�ltige Positionierung +$ EROFS +30 Dateisystem ist schreibgesch�tzt +$ EMLINK +31 Zu viele Links +$ EPIPE +32 Unterbrochene Pipe +$ EDOM +33 Numerisches Argument au�erhalb des Wertebereichs +$ ERANGE +34 Ergebnis au�erhalb des Wertebereichs +$ EAGAIN, EWOULDBLOCK +35 Ressource vor�bergehend nicht verf�gbar +$ EINPROGRESS +36 Operation wird gerade ausgef�hrt +$ EALREADY +37 Operation wird bereits ausgef�hrt +$ ENOTSOCK +38 Deskriptor ist kein Socket +$ EDESTADDRREQ +39 Zieladresse ben�tigt +$ EMSGSIZE +40 Nachricht zu lang +$ EPROTOTYPE +41 Ung�ltiger Protokolltyp f�r diesen Socket +$ ENOPROTOOPT +42 Protokoll nicht verf�gbar +$ EPROTONOSUPPORT +43 Protokoll nicht unterst�tzt +$ ESOCKTNOSUPPORT +44 Sockettyp nicht unterst�tzt +$ EOPNOTSUPP +45 Operation nicht unterst�tzt +$ EPFNOSUPPORT +46 Protokollfamilie nicht unterst�tzt +$ EAFNOSUPPORT +47 Adressfamilie wird von der Protokollfamilie nicht unterst�tzt +$ EADDRINUSE +48 Adresse wird bereits benutzt +$ EADDRNOTAVAIL +49 Kann angeforderte Adresse nicht belegen +$ ENETDOWN +50 Netzwerk nicht verf�gbar +$ ENETUNREACH +51 Netzwerk nicht erreichbar +$ ENETRESET +52 Netzwerk hat Verbindung mit Reset abgebrochen +$ ECONNABORTED +53 Software verursachte einen Verbindungsabbruch +$ ECONNRESET +54 Verbindung wurde von der Gegenstelle geschlossen +$ ENOBUFS +55 Keine Buffer verf�gbar +$ EISCONN +56 Socket ist schon verbunden +$ ENOTCONN +57 Socket ist nicht verbunden +$ ESHUTDOWN +58 Kann nach einem Socket-Shutdown nicht mehr senden +$ ETOOMANYREFS +59 Zu viele Referenzen, kann nicht verbinden +$ ETIMEDOUT +60 Verbindungsabbruch durch Zeit�berschreitung +$ ECONNREFUSED +61 Verbindung wurde abgelehnt +$ ELOOP +62 Zu viele symbolische Links (zirkul�r?) +$ ENAMETOOLONG +63 Dateiname zu lang +$ EHOSTDOWN +64 Host nicht verf�gbar +$ EHOSTUNREACH +65 Keine Route zum Host +$ ENOTEMPTY +66 Verzeichnis ist nicht leer +$ EPROCLIM +67 Zu viele Prozesse +$ EUSERS +68 Zu viele Benutzer +$ EDQUOT +69 Platzlimit �berschritten +$ ESTALE +70 Verwaister NFS-Dateideskriptor +$ EREMOTE +71 Zu viele Fernverweise in diesem Zugriff +$ EBADRPC +72 RPC-Struktur ist ung�ltig +$ ERPCMISMATCH +73 RPC-Version ist falsch +$ EPROGUNAVAIL +74 RPC-Programm nicht verf�gbar +$ EPROGMISMATCH +75 Falsche Programmversion +$ EPROCUNAVAIL +76 Falsche Prozedur f�r dieses Programm +$ ENOLCK +77 Keine Dateisperren verf�gbar +$ ENOSYS +78 Funktion nicht implementiert +$ EFTYPE +79 Ung�ltiger Dateityp oder Dateiformat +$ EAUTH +80 Authentifizierungsfehler +$ ENEEDAUTH +81 Authentikator ben�tigt +$ EIDRM +82 Identifizierung entfernt +$ ENOMSG +83 Keine Nachricht vom gew�nschten Typ +$ EOVERFLOW +84 Wert zu gro�, um in Datentyp zu speichern +$ ECANCELED +85 Operation abgebrochen +$ EILSEQ +86 Ung�ltige Byte-Sequenz +$ ENOATTR +87 Attribut nicht gefunden +$ EDOOFUS +88 Programmierfehler +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Verbindungsende +$ SIGINT +2 Unterbrechung +$ SIGQUIT +3 Programmende +$ SIGILL +4 Ung�ltiger Maschinenbefehl +$ SIGTRAP +5 Trace/BPT trap +$ SIGABRT +6 Abort trap +$ SIGEMT +7 EMT trap +$ SIGFPE +8 Flie�kommafehler +$ SIGKILL +9 Unbedingter Programmabbruch +$ SIGBUS +10 Bus-Zugriffsfehler +$ SIGSEGV +11 Illegaler Speicherzugriff +$ SIGSYS +12 Ung�ltiger Systemaufruf +$ SIGPIPE +13 Unterbrochene Pipe +$ SIGALRM +14 Wecker +$ SIGTERM +15 Beendet +$ SIGURG +16 Dringende Ein/Ausgabeanforderung +$ SIGSTOP +17 Gestoppt (Signal) +$ SIGTSTP +18 Gestoppt +$ SIGCONT +19 Fortgesetzt +$ SIGCHLD +20 Kindprozess beendet +$ SIGTTIN +21 Gestoppt (Eingabe) +$ SIGTTOU +22 Gestoppt (Ausgabe) +$ SIGIO +23 Ein/Ausgabe m�glich +$ SIGXCPU +24 CPU-Zeitlimit �berschritten +$ SIGXFSZ +25 Dateigr��enlimit �berschritten +$ SIGVTALRM +26 Virtueller Wecker abgelaufen +$ SIGPROF +27 Profil-Wecker abgelaufen +$ SIGWINCH +28 Fenstergr��e hat sich ver�ndert +$ SIGINFO +29 Informationsanforderung +$ SIGUSR1 +30 Benutzerdefiniertes Signal 1 +$ SIGUSR2 +31 Benutzerdefiniertes Signal 2 diff --git a/lib/libc/nls/el_GR.ISO8859-7.msg b/lib/libc/nls/el_GR.ISO8859-7.msg new file mode 100644 index 0000000..2690ed9 --- /dev/null +++ b/lib/libc/nls/el_GR.ISO8859-7.msg @@ -0,0 +1,249 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/el_GR.ISO8859-7.msg 192653 2009-05-23 17:13:35Z des $ +$ +$ Message catalog for C locale (template) +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 �� ��������� �������� +$ ENOENT +2 ��� ������� ������ ������ � ��������� +$ ESRCH +3 � ��������� ���� ��� ������� +$ EINTR +4 � ����� ���������� ��������� +$ EIO +5 ������ �������/������ +$ ENXIO +6 � ������� ��� ���� ��������� +$ E2BIG +7 � ����� ��� ���������� ����� ���� ������ +$ ENOEXEC +8 ���������� ����� ����������� +$ EBADF +9 ������������� ����������� ������� +$ ECHILD +10 ��� �������� ����������� ���������� +$ EDEADLK +11 ����������� �������� ����� +$ ENOMEM +12 �������� ��������� ������ +$ EACCES +13 ������ ��������� +$ EFAULT +14 ����� ��������� +$ ENOTBLK +15 ���������� ������� ����� block +$ EBUSY +16 ������� ������������ +$ EEXIST +17 �� ������ ������� +$ EXDEV +18 ��������� ������ �������� +$ ENODEV +19 � ���������� ��� ������������� ��� �� ������� +$ ENOTDIR +20 ��� ����� ��������� +$ EISDIR +21 ����� ��������� +$ EINVAL +22 �� ������ ���������� +$ ENFILE +23 ���������� ����� ������� ������ ��� ������� +$ EMFILE +24 ���������� ����� ������� ������ +$ ENOTTY +25 ���������� ioctl ��� �� ������� +$ ETXTBSY +26 �� ������ �������� ����� ������������ +$ EFBIG +27 ���� ������ ������ +$ ENOSPC +28 ��� ���� ������ ��������� ����� ��� ������� +$ ESPIPE +29 ���������� ��������� +$ EROFS +30 �� ������� ������� ����� ���� ��� �������� +$ EMLINK +31 ���� ������ ��������� +$ EPIPE +32 ���������� �������� +$ EDOM +33 �� ���������� ������ ����� ����� ����� +$ ERANGE +34 ���� ������ ���������� +$ EAGAIN, EWOULDBLOCK +35 � ����� ��� ����� ���������� ��������� +$ EINPROGRESS +36 � ���������� ��������� �� ������� ���� +$ EALREADY +37 � ���������� ����� ��� �� ������� +$ ENOTSOCK +38 ���������� �������� �� ��-������� +$ EDESTADDRREQ +39 ���������� ��������� ���������� +$ EMSGSIZE +40 ���� ������ ������ +$ EPROTOTYPE +41 ����� ����� ���������� ��� ������� +$ ENOPROTOOPT +42 �� ���������� ��� ����� ��������� +$ EPROTONOSUPPORT +43 �� ���������� ��� ������������� +$ ESOCKTNOSUPPORT +44 � ����� ��� �������� ��� ������������ +$ EOPNOTSUPP +45 � ���������� ��� ������������� +$ EPFNOSUPPORT +46 ��� ������������� � ���������� ����������� +$ EAFNOSUPPORT +47 � ���������� ����������� ��� ������������� ��� ��� ���������� ����������� +$ EADDRINUSE +48 � ��������� ��������������� ��� +$ EADDRNOTAVAIL +49 ��� ������ �� ����� ������� ��� ���������� ���������� +$ ENETDOWN +50 �� ������ ��� ���������� +$ ENETUNREACH +51 ��� ������� �������� ���� �� ������ +$ ENETRESET +52 �� ������ ������� �� ������� ���� ��� ��������� +$ ECONNABORTED +53 �� ��������� ��������� ���������� ��� �������� +$ ECONNRESET +54 � ������� ������������ ��� ��� ���� ����� +$ ENOBUFS +55 ��� ������� ���������� ���������� ����� +$ EISCONN +56 � ������� ���� ��� �������� +$ ENOTCONN +57 � ������� ��� ���� �������� +$ ESHUTDOWN +58 ��� ����� ������ � �������� ���� ��� ���������� ��� �������� +$ ETOOMANYREFS +59 ���� ������ ��������: ��� ������ �� ����� �������� +$ ETIMEDOUT +60 ����� ������ ����������� +$ ECONNREFUSED +61 ������ �������� +$ ELOOP +62 ���� ����� ������� ���������� ��������� +$ ENAMETOOLONG +63 ���� ������ ����� ������� +$ EHOSTDOWN +64 �� ������� ��� ����� �� ���������� +$ EHOSTUNREACH +65 ��� ������� �������� ���� �� ������� +$ ENOTEMPTY +66 � ��������� ��� ����� ������ +$ EPROCLIM +67 ���������� ������ ���������� +$ EUSERS +68 ���������� ������ ������� +$ EDQUOT +69 �������� ����� ������ ������ +$ ESTALE +70 ����� handle ������� ��� NFS +$ EREMOTE +71 ���� ����� ������������� ������� ��� �������� +$ EBADRPC +72 � ���� RPC ����� ������������ +$ ERPCMISMATCH +73 ���������� ������ RPC +$ EPROGUNAVAIL +74 �� ��������� RPC ��� ����� ��������� +$ EPROGMISMATCH +75 ���������� ������ ������������ +$ EPROCUNAVAIL +76 ������������ ���������� ��� �� ��������� +$ ENOLCK +77 ��� �������� ��������� ���������� +$ ENOSYS +78 � ���������� ��� ���� ���������� +$ EFTYPE +79 ����������� ����� � ����� ������� +$ EAUTH +80 ������ ���� ��� ����������� �������������� +$ ENEEDAUTH +81 ���������� ������������ �������������� +$ EIDRM +82 �� ������������� ���� ��������� +$ ENOMSG +83 ��� ������� ������ ��� ������������ ����� +$ EOVERFLOW +84 � ���� ����� ���� ������ ��� �� ����������� ���� ���� ��������� +$ ECANCELED +85 � ���������� ��������� +$ EILSEQ +86 ��-������ ��������� bytes +$ ENOATTR +87 �� �������������� ��� ������� +$ EDOOFUS +88 ������ ��������������� +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 �������� +$ SIGINT +2 ������� +$ SIGQUIT +3 ����������� +$ SIGILL +4 ��-������ ������ +$ SIGTRAP +5 ������ Trace/BPT +$ SIGABRT +6 ������ �������� +$ SIGEMT +7 ������ EMT +$ SIGFPE +8 �������� ������� ������������ +$ SIGKILL +9 ������������ +$ SIGBUS +10 ������ ������� +$ SIGSEGV +11 ������ Segmentation +$ SIGSYS +12 ���� ����� ���������� +$ SIGPIPE +13 ������� pipe +$ SIGALRM +14 ����� ����������� +$ SIGTERM +15 ������������ +$ SIGURG +16 ������� ��������� �/� +$ SIGSTOP +17 �� ������� (����) +$ SIGTSTP +18 �� ������� +$ SIGCONT +19 ����������� +$ SIGCHLD +20 ����� ����������� ���������� +$ SIGTTIN +21 ������� (������� tty) +$ SIGTTOU +22 ������� (������ tty) +$ SIGIO +23 ���������� I/O +$ SIGXCPU +24 ����������� �� ���� ������ ��� CPU +$ SIGXFSZ +25 ����������� �� ������� ������� ������� +$ SIGVTALRM +26 ����������� � ��������� ������������� +$ SIGPROF +27 ����������� � ������������� profiling +$ SIGWINCH +28 �� ������� ��� ��������� ������� +$ SIGINFO +29 ������ ��� ���������� +$ SIGUSR1 +30 ���� 1 ����������� ��� �� ������ +$ SIGUSR2 +31 ���� 2 ����������� ��� �� ������ diff --git a/lib/libc/nls/es_ES.ISO8859-1.msg b/lib/libc/nls/es_ES.ISO8859-1.msg new file mode 100644 index 0000000..a90f46b --- /dev/null +++ b/lib/libc/nls/es_ES.ISO8859-1.msg @@ -0,0 +1,295 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/es_ES.ISO8859-1.msg 200077 2009-12-03 19:27:12Z gabor $ +$ +$ Message catalog for es_ES.ISO8859-1 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Operaci�n no permitida +$ ENOENT +2 Fichero o directorio inexistente +$ ESRCH +3 Proceso inexistente +$ EINTR +4 Llamada del sistema interrumpida +$ EIO +5 Error de Entrada/Salida +$ ENXIO +6 Dispositivo no configurado +$ E2BIG +7 La lista de argumentos es demasiado larga +$ ENOEXEC +8 Error en el formato del ejecutable +$ EBADF +9 Descriptor incorrecto de fichero +$ ECHILD +10 No hay procesos hijo +$ EDEADLK +11 Se ha evitado el bloqueo del recurso +$ ENOMEM +12 No se pudo asignar memoria +$ EACCES +13 Permiso denegado +$ EFAULT +14 Direcci�n incorrecta +$ ENOTBLK +15 Se necesita un dispositivo de bloques +$ EBUSY +16 Dispositivo ocupado +$ EEXIST +17 El fichero ya existe +$ EXDEV +18 Enlace entre dispositivos +$ ENODEV +19 Operaci�n inadecuada para este dispositivo +$ ENOTDIR +20 No es un directorio +$ EISDIR +21 Es un directorio +$ EINVAL +22 Argumento inadecuado +$ ENFILE +23 Hay demasiados ficheros abiertos en el sistema +$ EMFILE +24 Hay demasiados ficheros abiertos +$ ENOTTY +25 ioctl inapropiado para el dispositivo +$ ETXTBSY +26 Fichero de texto ocupado +$ EFBIG +27 Fichero demasiado grande +$ ENOSPC +28 No queda espacio libre en el dispositivo +$ ESPIPE +29 B�squeda ilegal +$ EROFS +30 Sistema de ficheros de solo lectura +$ EMLINK +31 Demasiados enlaces +$ EPIPE +32 Canal (pipe) roto +$ EDOM +33 Argumento num�rico fuera de rango +$ ERANGE +34 El resultado es demasiado grande +$ EAGAIN, EWOULDBLOCK +35 el recurso no est� disponible temporalmente +$ EINPROGRESS +36 Operaci�n en proceso +$ EALREADY +37 La operaci�n ya se est� ejecutando +$ ENOTSOCK +38 Operaci�n de socket inaceptable para el dispositivo +$ EDESTADDRREQ +39 Se necesita una direcci�n de destino +$ EMSGSIZE +40 Mensaje demasiado largo +$ EPROTOTYPE +41 Tipo err�neo de protocolo para el socket +$ ENOPROTOOPT +42 Protocolo no disponible +$ EPROTONOSUPPORT +43 Protocolo no contemplado +$ ESOCKTNOSUPPORT +44 Tipo de socket no contemplado +$ EOPNOTSUPP +45 Operaci�n no contemplada +$ EPFNOSUPPORT +46 Familia de protocolos no contemplada +$ EAFNOSUPPORT +47 Familia de direcciones no contemplada por la familia de protocolos +$ EADDRINUSE +48 La direcci�n ya est� siendo usada +$ EADDRNOTAVAIL +49 No se pudo asignar la direcci�n requerida +$ ENETDOWN +50 La red no funciona +$ ENETUNREACH +51 No se ha podido acceder a la red +$ ENETRESET +52 La conexi�n de red se ha interrumpido al reinicializar +$ ECONNABORTED +53 Conexi�n perdida por problemas en el software +$ ECONNRESET +54 El interlocutor ha reinicializado la conexi�n +$ ENOBUFS +55 No queda espacio en el b�fer +$ EISCONN +56 El socket ya estaba conectado +$ ENOTCONN +57 El socket no est� conectado +$ ESHUTDOWN +58 No se puede enviar tras la desconexi�n del socket +$ ETOOMANYREFS +59 Demasiadas referencias: no se pueden unir +$ ETIMEDOUT +60 El tiempo de conexi�n ha expirado +$ ECONNREFUSED +61 Conexi�n rehusada +$ ELOOP +62 Demasiados niveles de enlaces simb�licos +$ ENAMETOOLONG +63 Nombre de fichero demasiado largo +$ EHOSTDOWN +64 La m�quina est� fuera de servicio +$ EHOSTUNREACH +65 No hay ruta hasta la m�quina +$ ENOTEMPTY +66 Directorio no vac�o +$ EPROCLIM +67 Demasiados procesos +$ EUSERS +68 Demasiados usuarios +$ EDQUOT +69 Cuota de disco sobrepasada +$ ESTALE +70 Descriptor de fichero NFS inv�lido +$ EREMOTE +71 Ruta con demasiados niveles +$ EBADRPC +72 La estructura de la RPC es err�nea +$ ERPCMISMATCH +73 La vers�n de la RPC es err�nea +$ EPROGUNAVAIL +74 La RPC no est� accesible +$ EPROGMISMATCH +75 Versi�n err�nea del programa +$ EPROCUNAVAIL +76 Procedimiento err�neo para el programa +$ ENOLCK +77 No hay bloqueos disponibles +$ ENOSYS +78 Funci�n no realizada +$ EFTYPE +79 Tipo de fichero o formato inapropiado +$ EAUTH +80 Error de autentificaci�n +$ ENEEDAUTH +81 Se necesita un autenticador +$ EIDRM +82 Identificador eliminado +$ ENOMSG +83 No hay mensajes del tipo deseado +$ EOVERFLOW +84 Valor demasiado grande para almacenarse en el tipo deseado +$ ECANCELED +85 Operaci�n cancelada +$ EILSEQ +86 Secuencia de bytes ilegal +$ ENOATTR +87 Atributo no encontrado +$ EDOOFUS +88 Error de programaci�n +$ EBADMSG +89 Mensaje inv�lido +$ EMULTIHOP +90 Intento de hop multiple +$ ENOLINK +91 El enlace se ha roto +$ EPROTO +92 Fallo de protocolo +$ ENOTCAPABLE +93 Habilidades insuficientes +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Fin de l�nea (Hangup) +$ SIGINT +2 Interrumpido +$ SIGQUIT +3 Terminado +$ SIGILL +4 Instrucci�n ilegal +$ SIGTRAP +5 Trace/BPT trap +$ SIGABRT +6 Abort trap +$ SIGEMT +7 EMT trap +$ SIGFPE +8 Excepci�n de coma flotante +$ SIGKILL +9 Matado +$ SIGBUS +10 Error en el bus +$ SIGSEGV +11 Fallo de segmentaci�n +$ SIGSYS +12 Llamada al sistema err�nea +$ SIGPIPE +13 Canal (pipe) roto +$ SIGALRM +14 Alarma del reloj +$ SIGTERM +15 Terminado +$ SIGURG +16 Condici�n urgente de E/S +$ SIGSTOP +17 Detenido (se�al) +$ SIGTSTP +18 Detenido +$ SIGCONT +19 Continuando +$ SIGCHLD +20 Proceso hijo terminado +$ SIGTTIN +21 Detenido (entrada tty) +$ SIGTTOU +22 Detenido (salida tty) +$ SIGIO +23 E/S posible +$ SIGXCPU +24 Se ha sobrepasado el tiempo l�mite de la CPU +$ SIGXFSZ +25 Se ha sobrepasado el l�mite de tama�o de fichero +$ SIGVTALRM +26 Temporizador virtual expirado +$ SIGPROF +27 Temporizador de perfilaci�n expirado +$ SIGWINCH +28 Cambios en el tama�o de ventana +$ SIGINFO +29 Petici�n de informaci�n +$ SIGUSR1 +30 Se�al definida por el usuario n1 +$ SIGUSR2 +31 Se�al definida por el usuario n2 +$ +$ gai_strerror() support catalog +$ +$set 3 +$ 1 (obsoleto) +1 Tipo de direcci�n no contemplado +$ EAI_AGAIN +2 Error transitorio en la resoluci�n de nombres +$ EAI_BADFLAGS +3 Valor inv�lido de ai_flags +$ EAI_FAIL +4 Error no recuperable en la resoluci�n de nombres +$ EAI_FAMILY +5 ai_family no contemplado +$ EAI_MEMORY +6 Error en la asignaci�n de memoria +$ 7 (obsoleto) +7 No hay direcci�n asociada con el nombre de m�quina +$ EAI_NONAME +8 No se dispone nombre de m�quina, ni nombre de servicio +$ EAI_SERVICE +9 Nombre de servicio no contemplado en ai_socktype +$ EAI_SOCKTYPE +10 ai_socktype no contemplado +$ EAI_SYSTEM +11 Error de sistema devuelto en errno +$ EAI_BADHINTS +12 Valor inv�lido de hints +$ EAI_PROTOCOL +13 Protocolo resuelto desconocido +$ EAI_OVERFLOW +14 B�fer de argumentos sobrepasado +$ 0 +32766 �xito +$ NL_MSGMAX +32767 Error desconocido diff --git a/lib/libc/nls/fi_FI.ISO8859-1.msg b/lib/libc/nls/fi_FI.ISO8859-1.msg new file mode 100644 index 0000000..3c86183 --- /dev/null +++ b/lib/libc/nls/fi_FI.ISO8859-1.msg @@ -0,0 +1,233 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/fi_FI.ISO8859-1.msg 189765 2009-03-13 10:40:38Z gabor $ +$ +$ Message catalog for fi_FI.ISO8859-1 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Toimintoa ei sallita +$ ENOENT +2 Tiedostoa tai hakemistoa ei l�ydy +$ ESRCH +3 Prosessia ei l�ydy +$ EINTR +4 Systeemikutsu keskeytyi +$ EIO +5 Sy�tt�/tulostusvirhe +$ ENXIO +6 Laitetta ei m��ritelty +$ E2BIG +7 Liikaa argumentteja +$ ENOEXEC +8 Tuntematon ohjelmatyyppi +$ EBADF +9 Virheellinen tiedosto-osoitin +$ ECHILD +10 Ei lapsiprosesseja +$ EDEADLK +11 Resurssin ristiinlukitus v�ltetty +$ ENOMEM +12 Muistinvaraus ep�onnistui +$ EACCES +13 Lupa kielletty +$ EFAULT +14 Virheellinen osoite +$ ENOTBLK +15 Tarvitaan lohko-osoitettava laite +$ EBUSY +16 Laite k�yt�ss� +$ EEXIST +17 Tiedosto on jo olemassa +$ EXDEV +18 Laitteiden v�linen linkki +$ ENODEV +19 Laite ei tue toimintoa +$ ENOTDIR +20 Kohde ei ole hakemisto +$ EISDIR +21 Kohde on hakemisto +$ EINVAL +22 Virheellinen argumentti +$ ENFILE +23 J�rjestelm�ss� on liian monta avointa tiedostoa +$ EMFILE +24 Liian monta avointa tiedostoa +$ ENOTTY +25 Virheellinen ohjaustoiminto laitteelle +$ ETXTBSY +26 Tiedosto on k�yt�ss� +$ EFBIG +27 Tiedosto liian suuri +$ ENOSPC +28 Laitteella ei ole tilaa +$ ESPIPE +29 Virheellinen haku +$ EROFS +30 Vain luettava tiedostoj�rjestelm� +$ EMLINK +31 Liian monta linkki� +$ EPIPE +32 Katkennut putki +$ EDOM +33 Numeerinen sy�te virheellinen +$ ERANGE +34 Tulos liian suuri +$ EAGAIN, EWOULDBLOCK +35 Resurssi ei ole tilap�isesti saatavilla +$ EINPROGRESS +36 Toiminta on k�ynniss� +$ EALREADY +37 Toiminta oli jo k�ynniss� +$ ENOTSOCK +38 Socket-operaatio muulla kuin socketilla +$ EDESTADDRREQ +39 Tarvitaan kohdeosoite +$ EMSGSIZE +40 Sanoma liian pitk� +$ EPROTOTYPE +41 V��r� protokolla socketille +$ ENOPROTOOPT +42 Protokolla ei ole k�ytett�viss� +$ EPROTONOSUPPORT +43 Protokollaa ei tueta +$ ESOCKTNOSUPPORT +44 Socket-tyyppi� ei tueta +$ EOPNOTSUPP +45 Toimintoa ei tueta +$ EPFNOSUPPORT +46 Protokollaperhett� ei tueta +$ EAFNOSUPPORT +47 Protokollaperhe ei tue osoiteperhett� +$ EADDRINUSE +48 Osoite on jo k�yt�ss� +$ EADDRNOTAVAIL +49 Ei pysty antamaan pyydetty� osoitetta +$ ENETDOWN +50 Verkko ei ole k�ytett�viss� +$ ENETUNREACH +51 Verkkoon ei ole yhteytt� +$ ENETRESET +52 Verkko sulki yhteyden +$ ECONNABORTED +53 Ohjelmiston aiheuttama yhteyden keskeytyminen +$ ECONNRESET +54 Is�nt� nollasi yhteyden +$ ENOBUFS +55 Puskuritila on lopussa +$ EISCONN +56 Yhteys on jo olemassa +$ ENOTCONN +57 Yhteytt� ei ole olemassa +$ ESHUTDOWN +58 L�hett�minen ei ole mahdollista yhteyden katkaisun j�lkeen +$ ETOOMANYREFS +59 Liikaa viittauksia: ei voi yhdist�� +$ ETIMEDOUT +60 Yhteyden aikavalvontakatkaisu +$ ECONNREFUSED +61 Yhteys hyl�tty +$ ELOOP +62 Liian monta per�kk�ist� symbolista linkki� +$ ENAMETOOLONG +63 Tiedoston nimi on liian pitk� +$ EHOSTDOWN +64 Is�nt� ei vastaa +$ EHOSTUNREACH +65 Ei reitti� is�nt��n +$ ENOTEMPTY +66 Hakemisto ei ole tyhj� +$ EPROCLIM +67 Liian monta prosessia +$ EUSERS +68 Liian monta k�ytt�j�� +$ EDQUOT +69 Levytilarajoitus ylittyi +$ ESTALE +70 Vanhentunut NFS-yhteys +$ EREMOTE +71 Liian monta verkkolevy� polussa +$ EBADRPC +72 Virheellinen RPC-pyynt� +$ ERPCMISMATCH +73 V��r� RPC-versio +$ EPROGUNAVAIL +74 RPC ei k�ytett�viss� +$ EPROGMISMATCH +75 V��r� ohjelmaversio +$ EPROCUNAVAIL +76 V��r� RPC-pyynt� ohjelmalle +$ ENOLCK +77 Lukitus ei k�ytett�viss� +$ ENOSYS +78 Toimintoa ei ole +$ EFTYPE +79 V��r� tiedostotyyppi tai -formaatti +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Katkaisu +$ SIGINT +2 Keskeytys +$ SIGQUIT +3 Lopetus +$ SIGILL +4 Laiton k�sky +$ SIGTRAP +5 J�ljitys/BPT ansa +$ SIGABRT +6 Poistumisansa +$ SIGEMT +7 EMT-ansa +$ SIGFPE +8 Liukulukuvirhe +$ SIGKILL +9 Tapettu +$ SIGBUS +10 V�yl�virhe +$ SIGSEGV +11 Suojausvirhe +$ SIGSYS +12 Virheellinen systeemikutsu +$ SIGPIPE +13 Katkennut putki +$ SIGALRM +14 H�lytyskello +$ SIGTERM +15 Lopetettu +$ SIGURG +16 Kiireellinen sy�tt�/tulostus +$ SIGSTOP +17 Pys�ytetty (signaali) +$ SIGTSTP +18 Pys�ytetty +$ SIGCONT +19 Jatkettu +$ SIGCHLD +20 Lapsiprosessi p��ttynyt +$ SIGTTIN +21 Pys�ytetty (tty-sy�te) +$ SIGTTOU +22 Pys�ytetty (tty-tuloste) +$ SIGIO +23 Sy�tt� ja tulostus mahdollisia +$ SIGXCPU +24 Keskusyksikk�aikarajoitus ylitetty +$ SIGXFSZ +25 Tiedoston kokorajoitus ylitetty +$ SIGVTALRM +26 Virtuaali-ajastin laukesi +$ SIGPROF +27 Profilointiajastin laukesi +$ SIGWINCH +28 Ikkunan koko muuttuu +$ SIGINFO +29 Informaatiopyynt� +$ SIGUSR1 +30 K�ytt�j�n m��ritelt�v� signaali 1 +$ SIGUSR2 +31 K�ytt�j�n m��ritelt�v� signaali 2 +$ SIGPWR +32 Virransaannin tilassa muutos diff --git a/lib/libc/nls/fr_FR.ISO8859-1.msg b/lib/libc/nls/fr_FR.ISO8859-1.msg new file mode 100644 index 0000000..08c2667 --- /dev/null +++ b/lib/libc/nls/fr_FR.ISO8859-1.msg @@ -0,0 +1,249 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/fr_FR.ISO8859-1.msg 249471 2013-04-14 11:44:47Z jilles $ +$ +$ Message catalog for fr_FR.ISO8859-1 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Op�ration non autoris�e +$ ENOENT +2 Fichier ou r�pertoire inexistant +$ ESRCH +3 Processus inconnu +$ EINTR +4 Appel syst�me interrompu +$ EIO +5 Erreur d'entr�e/sortie +$ ENXIO +6 Dispositif non configur� +$ E2BIG +7 Liste d'arguments trop longue +$ ENOEXEC +8 Format d'ex�cutable invalide +$ EBADF +9 Mauvais descripteur de fichier +$ ECHILD +10 Pas de processus fils +$ EDEADLK +11 �treinte mortelle d�tect�e +$ ENOMEM +12 Impossible d'allouer de la m�moire +$ EACCES +13 Permission refus�e +$ EFAULT +14 Mauvaise adresse +$ ENOTBLK +15 Dispositif en mode bloc requis +$ EBUSY +16 Dispositif occup� +$ EEXIST +17 Le fichier existe +$ EXDEV +18 Lien inter-unit�s +$ ENODEV +19 Op�ration non support�e par le dispositif +$ ENOTDIR +20 Pas un r�pertoire +$ EISDIR +21 Est un r�pertoire +$ EINVAL +22 Argument invalide +$ ENFILE +23 Trop de fichiers ouverts sur le syst�me +$ EMFILE +24 Trop de fichiers ouverts +$ ENOTTY +25 Fonction inadapt�e au dispositif +$ ETXTBSY +26 Fichier en cours d'utilisation +$ EFBIG +27 Fichier trop grand +$ ENOSPC +28 Plus d'espace disponible +$ ESPIPE +29 Recherche ill�gale +$ EROFS +30 Syst�me de fichier en lecture seulement +$ EMLINK +31 Trop de liens +$ EPIPE +32 Tube d�connect� +$ EDOM +33 Argument num�rique hors d�finition +$ ERANGE +34 R�sultat trop grand +$ EAGAIN, EWOULDBLOCK +35 Ressource indisponible temporairement +$ EINPROGRESS +36 Op�ration en cours +$ EALREADY +37 Op�ration d�j� en cours +$ ENOTSOCK +38 Op�ration de type socket sur un descripteur de fichier +$ EDESTADDRREQ +39 Adresse de destination obligatoire +$ EMSGSIZE +40 Message trop long +$ EPROTOTYPE +41 Mauvais type de protocole pour la socket +$ ENOPROTOOPT +42 Protocole non disponible +$ EPROTONOSUPPORT +43 Protocole non support� +$ ESOCKTNOSUPPORT +44 Type de socket non support� +$ EOPNOTSUPP +45 Op�ration non support�e +$ EPFNOSUPPORT +46 Famille de protocole non support�e +$ EAFNOSUPPORT +47 Famille d'adresse non support�e par la famille de protocole +$ EADDRINUSE +48 Adresse en cours d'utilisation +$ EADDRNOTAVAIL +49 Impossible d'assigner l'adresse demand�e +$ ENETDOWN +50 Plus de r�seau +$ ENETUNREACH +51 R�seau inaccessible +$ ENETRESET +52 Connexion coup�e par le r�seau +$ ECONNABORTED +53 Connexion interrompue +$ ECONNRESET +54 Connexion interrompue par l'h�te distant +$ ENOBUFS +55 Tampon satur� +$ EISCONN +56 La socket est d�j� connect�e +$ ENOTCONN +57 La socket n'est pas connect�e +$ ESHUTDOWN +58 Impossible d'envoyer apr�s la coupure +$ ETOOMANYREFS +59 Trop de r�f�rences�: lien impossible +$ ETIMEDOUT +60 D�passement du d�lai d'attente +$ ECONNREFUSED +61 Connexion refus�e +$ ELOOP +62 Trop de niveaux de liens symboliques +$ ENAMETOOLONG +63 Nom de fichier trop long +$ EHOSTDOWN +64 H�te distant arr�t� +$ EHOSTUNREACH +65 Pas de route vers l'h�te distant +$ ENOTEMPTY +66 R�pertoire non vide +$ EPROCLIM +67 Trop de processus +$ EUSERS +68 Trop d'utilisateurs +$ EDQUOT +69 Quota de disque d�pass� +$ ESTALE +70 Identificateur de fichier NFS p�rim� +$ EREMOTE +71 Trop de niveaux ext�rieurs dans le path +$ EBADRPC +72 Mauvaise structure RPC +$ ERPCMISMATCH +73 Mauvaise version RPC +$ EPROGUNAVAIL +74 Prog. RPC indisponible +$ EPROGMISMATCH +75 Mauvaise version de programme +$ EPROCUNAVAIL +76 Mauvaise proc�dure pour le programme +$ ENOLCK +77 Plus de verrous disponibles +$ ENOSYS +78 Fonction non impl�ment�e +$ EFTYPE +79 Type de fichier ou format inappropri� +$ EAUTH +80 Erreur d'authentification +$ ENEEDAUTH +81 Authentification requise +$ EIDRM +82 Identifiant retir� +$ ENOMSG +83 Aucun message du type souhait� +$ EOVERFLOW +84 Valeur trop grande pour le type de donn�e +$ ECANCELED +85 Op�ration annul�e +$ EILSEQ +86 S�quence d'octets ill�gale +$ ENOATTR +87 Attribut non trouv� +$ EDOOFUS +88 Erreur de programmation +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Fin de connexion +$ SIGINT +2 Interruption +$ SIGQUIT +3 Quitter +$ SIGILL +4 Instruction ill�gale +$ SIGTRAP +5 Trace/BPT trap +$ SIGABRT +6 Abort trap +$ SIGEMT +7 EMT trap +$ SIGFPE +8 Exception sur virgule flottante +$ SIGKILL +9 Tu� +$ SIGBUS +10 Bus error +$ SIGSEGV +11 Segmentation fault +$ SIGSYS +12 Bad system call +$ SIGPIPE +13 Broken pipe +$ SIGALRM +14 Alarm clock +$ SIGTERM +15 Termin� +$ SIGURG +16 Urgent I/O condition +$ SIGSTOP +17 Suspended (signal) +$ SIGTSTP +18 Suspended +$ SIGCONT +19 Continued +$ SIGCHLD +20 Child exited +$ SIGTTIN +21 Stopped (tty input) +$ SIGTTOU +22 Stopped (tty output) +$ SIGIO +23 I/O possible +$ SIGXCPU +24 Cputime limit exceeded +$ SIGXFSZ +25 Filesize limit exceeded +$ SIGVTALRM +26 Virtual timer expired +$ SIGPROF +27 Profiling timer expired +$ SIGWINCH +28 Window size changes +$ SIGINFO +29 Information request +$ SIGUSR1 +30 User defined signal 1 +$ SIGUSR2 +31 User defined signal 2 diff --git a/lib/libc/nls/gl_ES.ISO8859-1.msg b/lib/libc/nls/gl_ES.ISO8859-1.msg new file mode 100644 index 0000000..008cf33 --- /dev/null +++ b/lib/libc/nls/gl_ES.ISO8859-1.msg @@ -0,0 +1,295 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/gl_ES.ISO8859-1.msg 202743 2010-01-21 11:36:40Z gabor $ +$ +$ Message catalog for gl_ES.ISO8859-1 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Operaci�n non permitida +$ ENOENT +2 Ficheiro ou directorio inexistente +$ ESRCH +3 Proceso inexistente +$ EINTR +4 Chamada do sistema interrompida +$ EIO +5 Erro de Entrada/Sa�da +$ ENXIO +6 Dispositivo non configurado +$ E2BIG +7 A lista de argumentos � demasiado larga +$ ENOEXEC +8 Erro no formato do executable +$ EBADF +9 Descriptor incorrecto de ficheiro +$ ECHILD +10 Non hai procesos fillos +$ EDEADLK +11 Evitouse o bloqueo do recurso +$ ENOMEM +12 Non se puido asignar memoria +$ EACCES +13 Permiso denegado +$ EFAULT +14 Direcci�n incorrecta +$ ENOTBLK +15 Prec�sase un dispositivo de bloques +$ EBUSY +16 Dispositivo ocupado +$ EEXIST +17 O ficheiro xa existe +$ EXDEV +18 Enlace entre dispositivos +$ ENODEV +19 Operaci�n inadecuada para este dispositivo +$ ENOTDIR +20 Non � un directorio +$ EISDIR +21 � un directorio +$ EINVAL +22 Argumento inadecuado +$ ENFILE +23 Hai demasiados ficheiros abertos no sistema +$ EMFILE +24 Hai demasiados ficheiros abertos +$ ENOTTY +25 ioctl inapropiado para o dispositivo +$ ETXTBSY +26 Ficheiro de texto ocupado +$ EFBIG +27 Ficheiro demasiado grande +$ ENOSPC +28 Non queda espacio libre no dispositivo +$ ESPIPE +29 seek inv�lido +$ EROFS +30 Sistema de ficheiros de s� lectura +$ EMLINK +31 Demasiados enlaces +$ EPIPE +32 Canal (pipe) roto +$ EDOM +33 Argumento num�rico f�ra de rango +$ ERANGE +34 O resultado � demasiado grande +$ EAGAIN, EWOULDBLOCK +35 O recurso non est� dispo�ible temporalmente +$ EINPROGRESS +36 Operaci�n en proceso +$ EALREADY +37 A operaci�n xa estase executando +$ ENOTSOCK +38 Operaci�n de socket inaceptable para o dispositivo +$ EDESTADDRREQ +39 Prec�sase unha direcci�n de destino +$ EMSGSIZE +40 Mensaxe demasiado largo +$ EPROTOTYPE +41 Tipo malo de protocolo para o socket +$ ENOPROTOOPT +42 Protocolo non dispo�ible +$ EPROTONOSUPPORT +43 Protocolo non contemplado +$ ESOCKTNOSUPPORT +44 Tipo de socket non contemplado +$ EOPNOTSUPP +45 Operaci�n non contemplada +$ EPFNOSUPPORT +46 Familia de protocolos non contemplada +$ EAFNOSUPPORT +47 Familia de direcciones non contemplada pola familia de protocolos +$ EADDRINUSE +48 A direcci�n xa est� en uso +$ EADDRNOTAVAIL +49 Non se puido asignar a direcci�n requerida +$ ENETDOWN +50 A rede non funciona +$ ENETUNREACH +51 Non se puido acceder � rede +$ ENETRESET +52 A conexi�n de rede interrompiuse ao reinicializar +$ ECONNABORTED +53 Conexi�n perdida por problemas no software +$ ECONNRESET +54 O interlocutor reinicializou a conexi�n +$ ENOBUFS +55 Non queda espacio no b�fer +$ EISCONN +56 O socket xa estaba conectado +$ ENOTCONN +57 O socket non est� conectado +$ ESHUTDOWN +58 Non se pode enviar tras a desconexi�n do socket +$ ETOOMANYREFS +59 Demasiadas referencias: non poden unirse +$ ETIMEDOUT +60 O tempo de conexi�n expirou +$ ECONNREFUSED +61 Conexi�n rexeitada +$ ELOOP +62 Demasiados niveles de enlaces simb�licos +$ ENAMETOOLONG +63 Nome de ficheiro demasiado largo +$ EHOSTDOWN +64 A m�quina est� f�ra de servicio +$ EHOSTUNREACH +65 Non hai ruta ata a m�quina +$ ENOTEMPTY +66 Directorio non baleiro +$ EPROCLIM +67 Demasiados procesos +$ EUSERS +68 Demasiados usuarios +$ EDQUOT +69 Cuota de disco sobrepasada +$ ESTALE +70 Descriptor de ficheiro NFS inv�lido +$ EREMOTE +71 Ruta con demasiados niveles +$ EBADRPC +72 A estructura da RPC � mala +$ ERPCMISMATCH +73 A versi�n da RPC � mala +$ EPROGUNAVAIL +74 A RPC non est� accesible +$ EPROGMISMATCH +75 Versi�n mala do programa +$ EPROCUNAVAIL +76 Procedemento malo para o programa +$ ENOLCK +77 Non hai bloqueos dispo�ibles +$ ENOSYS +78 Funci�n non realizada +$ EFTYPE +79 Tipo de ficheiro ou formato inapropiado +$ EAUTH +80 Erro de autenticaci�n +$ ENEEDAUTH +81 Prec�sase un autenticador +$ EIDRM +82 Identificador eliminado +$ ENOMSG +83 Non hai mensaxes do tipo desexado +$ EOVERFLOW +84 Valor demasiado grande para se almacenar no tipo desexado +$ ECANCELED +85 Operaci�n cancelada +$ EILSEQ +86 Secuencia inv�lida de byte +$ ENOATTR +87 Atributo non encontrado +$ EDOOFUS +88 Erro de programaci�n +$ EBADMSG +89 Mensaxe inv�lido +$ EMULTIHOP +90 Intento de Multihop +$ ENOLINK +91 Enlace fortaleceuse +$ EPROTO +92 Erro de protocolo +$ ENOTCAPABLE +93 Habilidades non suficientes +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Fin de li�a (Hangup) +$ SIGINT +2 Interrompido +$ SIGQUIT +3 Terminado +$ SIGILL +4 Instrucci�n inv�lida +$ SIGTRAP +5 Trace/BPT trap +$ SIGABRT +6 Abort trap +$ SIGEMT +7 EMT trap +$ SIGFPE +8 Excepci�n de coma flotante +$ SIGKILL +9 Matado +$ SIGBUS +10 Erro no bus +$ SIGSEGV +11 Fallo de segmentaci�n +$ SIGSYS +12 Chamada ao sistema mala +$ SIGPIPE +13 Canal (pipe) roto +$ SIGALRM +14 Alarma do reloxo +$ SIGTERM +15 Terminado +$ SIGURG +16 Condici�n urxente de E/S +$ SIGSTOP +17 Detido (sinal) +$ SIGTSTP +18 Detido +$ SIGCONT +19 Continuando +$ SIGCHLD +20 Proceso fillo terminado +$ SIGTTIN +21 Detido (entrada tty) +$ SIGTTOU +22 Detido (s�da tty) +$ SIGIO +23 E/S posible +$ SIGXCPU +24 Sobrepasouse o tempo l�mite da CPU +$ SIGXFSZ +25 Sobrepasouse o l�mite de tama�o de ficheiro +$ SIGVTALRM +26 Temporizador virtual caducado +$ SIGPROF +27 Temporizador de perfilaci�n caducado +$ SIGWINCH +28 Cambios no tama�o de xanela +$ SIGINFO +29 Petici�n de informaci�n +$ SIGUSR1 +30 Sinal definida polo usuario no. 1 +$ SIGUSR2 +31 Sinal definida polo usuario no. 2 +$ +$ gai_strerror() support catalog +$ +$set 3 +$ 1 (obsoleto) +1 Tipo de direcci�n non soportado +$ EAI_AGAIN +2 Erro temporal na resoluci�n de nomes +$ EAI_BADFLAGS +3 Valor inv�lido de ai_flags +$ EAI_FAIL +4 Erro non recuperable na resoluci�n de nomes +$ EAI_FAMILY +5 ai_family non soportado +$ EAI_MEMORY +6 Erro na asignaci�n de memoria +$ 7 (obsoleto) +7 Non hai direcci�n asociada co nome de m�quina +$ EAI_NONAME +8 Non se disp�n nome de m�quina, nin nome de servizo +$ EAI_SERVICE +9 Nome de servizo non soportado en ai_socktype +$ EAI_SOCKTYPE +10 ai_socktype non soportado +$ EAI_SYSTEM +11 Erro de sistema devolto en errno +$ EAI_BADHINTS +12 Valor inv�lido de hints +$ EAI_PROTOCOL +13 Protocolo resolto desco�ecido +$ EAI_OVERFLOW +14 B�fer de argumentos excedido +$ 0 +32766 �xito +$ NL_MSGMAX +32767 Erro desco�ecido diff --git a/lib/libc/nls/hu_HU.ISO8859-2.msg b/lib/libc/nls/hu_HU.ISO8859-2.msg new file mode 100644 index 0000000..55d22df --- /dev/null +++ b/lib/libc/nls/hu_HU.ISO8859-2.msg @@ -0,0 +1,295 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/hu_HU.ISO8859-2.msg 199417 2009-11-17 18:57:44Z gabor $ +$ +$ Message catalog for hu_HU.ISO8859-2 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Nem enged�lyezett m�velet +$ ENOENT +2 F�jl vagy k�nyvt�r nem tal�lhat� +$ ESRCH +3 Processz nem tal�lhat� +$ EINTR +4 Megszak�tott rendszerh�v�s +$ EIO +5 B/K hiba +$ ENXIO +6 Konfigur�latlan eszk�z +$ E2BIG +7 T�l hossz� argumentumlista +$ ENOEXEC +8 Hib�s v�grehajthat� form�tum +$ EBADF +9 Rossz f�jlle�r� +$ ECHILD +10 Nem l�tez� gyermek processz +$ EDEADLK +11 Resource deadlock avoided +$ ENOMEM +12 Mem�ria nem foglalhat� le +$ EACCES +13 Hozz�f�r�s megtagadva +$ EFAULT +14 Rossz c�m +$ ENOTBLK +15 Blokkos eszk�z sz�ks�ges +$ EBUSY +16 Eszk�z foglalt +$ EEXIST +17 F�jl l�tezik +$ EXDEV +18 Kereszthivatkoz�s eszk�z�k�n +$ ENODEV +19 A m�velet nem t�mogatott az eszk�z �ltal +$ ENOTDIR +20 Nem k�nyvt�r +$ EISDIR +21 K�nyvt�r +$ EINVAL +22 �rv�nytelen argumentum +$ ENFILE +23 T�l sok megnyitott f�jl a rendszerben +$ EMFILE +24 T�l sok megnyitott f�jl +$ ENOTTY +25 Nem megfelel� ioctl az eszk�zh�z +$ ETXTBSY +26 Sz�veges f�jl foglalt +$ EFBIG +27 F�jl t�l nagy +$ ENOSPC +28 Nincs hely az eszk�z�n +$ ESPIPE +29 �rv�nytelen seek +$ EROFS +30 Csak olvashat� f�jlrendszer +$ EMLINK +31 T�l sok link +$ EPIPE +32 Hib�s cs�vezet�k +$ EDOM +33 Numerikus argumentum nem esik a tartom�nyba +$ ERANGE +34 Az eserm�ny t�l nagy +$ EAGAIN, EWOULDBLOCK +35 Az er�forr�s ideiglenesen nem �rhet� el +$ EINPROGRESS +36 A m�velet folyamatban van +$ EALREADY +37 A m�velet m�r folyamatban van +$ ENOTSOCK +38 Socket m�velet nem socketen +$ EDESTADDRREQ +39 C�l c�m sz�ks�ges +$ EMSGSIZE +40 T�l hossz� �zenet +$ EPROTOTYPE +41 Rossz protokollt�pus a sockethez +$ ENOPROTOOPT +42 Protokoll nem �rhet� el +$ EPROTONOSUPPORT +43 Protokoll nem t�mogatott +$ ESOCKTNOSUPPORT +44 Sockett�pus nem t�mogatott +$ EOPNOTSUPP +45 M�velet nem t�mogatott +$ EPFNOSUPPORT +46 Protokollcsal�d nem t�mogatott +$ EAFNOSUPPORT +47 A c�mcsal�d nem t�mogatott a protokollcsal�d �ltal +$ EADDRINUSE +48 A c�m m�r haszn�latban van +$ EADDRNOTAVAIL +49 A k�rt c�m nem oszthat� ki +$ ENETDOWN +50 A h�l�zat nem m�k�dik +$ ENETUNREACH +51 A h�l�zat nem �rhet� el +$ ENETRESET +52 A h�l�zat megszak�totta a kapcsolatot +$ ECONNABORTED +53 A szoftver megszak�totta a kapcsolatot +$ ECONNRESET +54 A kapcsolatot megszak�totta a peer +$ ENOBUFS +55 Nincs rendelkez�sre �ll� pufferter�let +$ EISCONN +56 A socket m�r kapcsol�dva van +$ ENOTCONN +57 A socket nincs kapcsol�dva +$ ESHUTDOWN +58 Nem k�ldhet� el a socket lebont�sa ut�n +$ ETOOMANYREFS +59 T�l sok hivatkoz�s: nem illeszthet� �ssze +$ ETIMEDOUT +60 A m�velet t�ll�pte a rendelkez�sre �ll� id�t +$ ECONNREFUSED +61 Kapcsolat elutas�tva +$ ELOOP +62 T�l sok szint a szimbolikus linkekben +$ ENAMETOOLONG +63 T�l hossz� f�jln�v +$ EHOSTDOWN +64 A kiszolg�l� nem �rhet� el +$ EHOSTUNREACH +65 Nincs �tvonal a kiszolg�l�hoz +$ ENOTEMPTY +66 K�nyvt�r nem �res +$ EPROCLIM +67 T�l sok processz +$ EUSERS +68 T�l sok felhaszn�l� +$ EDQUOT +69 A lemezkv�ta t�ll�pve +$ ESTALE +70 Elavult NFS f�jlkezel� +$ EREMOTE +71 T�l sok szint a t�voli �tvonalban +$ EBADRPC +72 Rossz RPC strukt�ra +$ ERPCMISMATCH +73 Rossz RPC verzi� +$ EPROGUNAVAIL +74 RPC program nem �rhet� el +$ EPROGMISMATCH +75 Rossz programverzi� +$ EPROCUNAVAIL +76 Rossz elj�r�s a programhoz +$ ENOLCK +77 Nincs el�rhet� z�rol�s +$ ENOSYS +78 Nem implement�lt funkci� +$ EFTYPE +79 Nem megfelel� f�jlt�pus vagy form�tum +$ EAUTH +80 Azonos�t�si hiba +$ ENEEDAUTH +81 Azonos�t�s sz�ks�ges +$ EIDRM +82 Azonos�t� elt�vol�tva +$ ENOMSG +83 Nincs �zenet a k�v�nt t�pusb�l +$ EOVERFLOW +84 Az �rt�k t�l nagy az adott adatt�pusban val� t�rol�shoz +$ ECANCELED +85 M�velet t�r�lva +$ EILSEQ +86 �rv�nytelen b�jtsorrend +$ ENOATTR +87 Attrib�tum nem tal�lhat� +$ EDOOFUS +88 Programoz�si hiba +$ EBADMSG +89 Helytelen �zenet +$ EMULTIHOP +90 Multihop k�s�rlet +$ ENOLINK +91 A kapcsolat szigor�tva lett +$ EPROTO +92 Protokol hiba +$ ENOTCAPABLE +93 El�gtelen k�pess�gek +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Hangup +$ SIGINT +2 Megszak�t�s +$ SIGQUIT +3 Kil�p�s +$ SIGILL +4 �rv�nytelen m�velet +$ SIGTRAP +5 Trace/BPT csapda +$ SIGABRT +6 Abort csapda +$ SIGEMT +7 EMT csapda +$ SIGFPE +8 Lebeg�pontos kiv�tel +$ SIGKILL +9 Meg�lve +$ SIGBUS +10 Busz hiba +$ SIGSEGV +11 Szegment�ci�s hiba +$ SIGSYS +12 Rossz rendszerh�v�s +$ SIGPIPE +13 Hib�s cs�vezet�k +$ SIGALRM +14 Id�z�t�si riaszt�s +$ SIGTERM +15 Befejezve +$ SIGURG +16 S�rg�s B/K felt�tel +$ SIGSTOP +17 Elaltatva (szign�l) +$ SIGTSTP +18 Elaltatva +$ SIGCONT +19 Folytatva +$ SIGCHLD +20 Gyermek befejez�d�tt +$ SIGTTIN +21 Le�ll�tva (tty bevitel) +$ SIGTTOU +22 Le�ll�tva (tty kivitel) +$ SIGIO +23 B/K lehets�ges +$ SIGXCPU +24 Processzorid�-korl�toz�s t�ll�pve +$ SIGXFSZ +25 �jlm�ret-korl�toz�s t�ll�pve +$ SIGVTALRM +26 Virtu�lis id�z�t� lej�rt +$ SIGPROF +27 Profilid�z�t� lej�rt +$ SIGWINCH +28 Ablakm�ret-v�ltoz�sok +$ SIGINFO +29 Inform�ci�k�r�s +$ SIGUSR1 +30 Felhaszn�l�i szign�l 1 +$ SIGUSR2 +31 Felhaszn�l�i szign�l 2 +$ +$ gai_strerror() support catalog +$ +$set 3 +$ 1 (elavult) +1 A hosztn�vhez tartoz� c�mcsal�d nem t�mogatott +$ EAI_AGAIN +2 Ideiglenes hiba a n�vfelold�skor +$ EAI_BADFLAGS +3 �rv�nytelen ai_flags �rt�k +$ EAI_FAIL +4 Nem helyre�ll�that� hiba a n�vfelold�sban +$ EAI_FAMILY +5 ai_family nem t�mogatott +$ EAI_MEMORY +6 Mem�riafoglal�si hiba +$ 7 (elavult) +7 Nem tartozik c�m � hosztn�vhez +$ EAI_NONAME +8 Se hosztn�v, se szolg�ltat�sn�v nem �ll rendelkez�sre +$ EAI_SERVICE +9 Nem t�mogatott ai_socktype szolg�ltat�sn�v +$ EAI_SOCKTYPE +10 ai_socktype nem t�mogatott +$ EAI_SYSTEM +11 Rendszerhiba j�tt vissza az errno v�ltoz�ban +$ EAI_BADHINTS +12 �rv�nytelen hint �rt�k +$ EAI_PROTOCOL +13 A feloldott protokol ismeretlen +$ EAI_OVERFLOW +14 Az argumentumok puffere t�lcsordult +$ 0 +32766 Siker +$ NL_MSGMAX +32767 Ismeretlen hiba diff --git a/lib/libc/nls/it_IT.ISO8859-15.msg b/lib/libc/nls/it_IT.ISO8859-15.msg new file mode 100644 index 0000000..d833e3f --- /dev/null +++ b/lib/libc/nls/it_IT.ISO8859-15.msg @@ -0,0 +1,231 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/it_IT.ISO8859-15.msg 189765 2009-03-13 10:40:38Z gabor $ +$ +$ Message catalog for it_IT.ISO8859-15 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Operazione non permessa +$ ENOENT +2 File o directory inesistente +$ ESRCH +3 Processo inesistente +$ EINTR +4 Chiamata di sistema interrotta +$ EIO +5 Errore di input/output +$ ENXIO +6 Periferica non configurata +$ E2BIG +7 Lista degli argomenti troppo lunga +$ ENOEXEC +8 Errore nel formato eseguibile +$ EBADF +9 Descrittore di file non valido +$ ECHILD +10 Nessun processo figlio +$ EDEADLK +11 Situazione di deadlock evitata +$ ENOMEM +12 Impossibile allocare memoria +$ EACCES +13 Permesso negato +$ EFAULT +14 Indirizzo non valido +$ ENOTBLK +15 Periferica a blocchi necessaria +$ EBUSY +16 Periferica occupata +$ EEXIST +17 Il file esiste +$ EXDEV +18 Link improprio +$ ENODEV +19 Operazione non supportata dalla periferica +$ ENOTDIR +20 Non è una directory +$ EISDIR +21 E' una directory +$ EINVAL +22 Argomento non valido +$ ENFILE +23 Troppi file aperti nel sistema +$ EMFILE +24 Troppi file aperti +$ ENOTTY +25 Ioctl inappropriata per la periferica +$ ETXTBSY +26 File di testo occupato +$ EFBIG +27 File troppo grande +$ ENOSPC +28 Spazio sulla periferica esaurito +$ ESPIPE +29 Ricerca non valida +$ EROFS +30 Filesystem di sola lettura +$ EMLINK +31 Troppi link +$ EPIPE +32 Pipe rotta +$ EDOM +33 Argomento numerico fuori dal dominio +$ ERANGE +34 Risultato troppo grande +$ EAGAIN, EWOULDBLOCK +35 Risorsa temporaneamente non disponibile +$ EINPROGRESS +36 Operazione in esecuzione +$ EALREADY +37 Operazione già in esecuzione +$ ENOTSOCK +38 Operazione sui socket eseguita su un non-socket +$ EDESTADDRREQ +39 Indirizzo destinazione necessario +$ EMSGSIZE +40 Messaggio troppo lungo +$ EPROTOTYPE +41 Tipo di protocollo non valido per il socket +$ ENOPROTOOPT +42 Protocollo non disponibile +$ EPROTONOSUPPORT +43 Protocollo non supportato +$ ESOCKTNOSUPPORT +44 Tipo di socket non supportato +$ EOPNOTSUPP +45 Operazione non supportata +$ EPFNOSUPPORT +46 Famiglia di protocolli non supportata +$ EAFNOSUPPORT +47 Famiglia di indirizzi non supportata dalla famiglia di protocolli +$ EADDRINUSE +48 Indirizzo già in uso +$ EADDRNOTAVAIL +49 Impossibile assegnare l'indirizzo richiesto +$ ENETDOWN +50 Network fuori uso +$ ENETUNREACH +51 Network non raggiungibile +$ ENETRESET +52 Network dropped connection on reset +$ ECONNABORTED +53 Interruzione della connessione causata dal software +$ ECONNRESET +54 Connessione azzerata dal corrispondente +$ ENOBUFS +55 Spazio del buffer esaurito +$ EISCONN +56 Socket già connesso +$ ENOTCONN +57 Socket non connesso +$ ESHUTDOWN +58 Impossibile inviare dopo la chiusura del socket +$ ETOOMANYREFS +59 Troppe referenze: impossibile raccordare +$ ETIMEDOUT +60 Connessione scaduta +$ ECONNREFUSED +61 Connection rifiutata +$ ELOOP +62 Troppi livelli di link simbolici +$ ENAMETOOLONG +63 Nome di file troppo lungo +$ EHOSTDOWN +64 Host fuori uso +$ EHOSTUNREACH +65 Host irraggiungibile +$ ENOTEMPTY +66 Directory non vuota +$ EPROCLIM +67 Troppi processi +$ EUSERS +68 Troppi utenti +$ EDQUOT +69 Quota disco superata +$ ESTALE +70 Manipolatore di file NFS scaduto +$ EREMOTE +71 Troppi livelli remoti nel path +$ EBADRPC +72 Struttura RPC non valida +$ ERPCMISMATCH +73 Versione RPC non corrispondente +$ EPROGUNAVAIL +74 Programma RPC non disponibile +$ EPROGMISMATCH +75 Versione del programma non corrispodente +$ EPROCUNAVAIL +76 Procedura non disponibile +$ ENOLCK +77 Nessun lock disponibile +$ ENOSYS +78 Funzione non implementata +$ EFTYPE +79 Tipo di file o formato inappropriato +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Hangup +$ SIGINT +2 Interruzione +$ SIGQUIT +3 Chiusura +$ SIGILL +4 Istruzione illegale +$ SIGTRAP +5 Trappola Trace/breakpoint +$ SIGABRT +6 Trappola abort() +$ SIGEMT +7 Trappola EMT +$ SIGFPE +8 Errore di virgola mobile +$ SIGKILL +9 Ucciso +$ SIGBUS +10 Errore di bus +$ SIGSEGV +11 Errore di segmentazione +$ SIGSYS +12 Chiamata di sistema non valida +$ SIGPIPE +13 Pipe rotta +$ SIGALRM +14 Sveglia +$ SIGTERM +15 Terminato +$ SIGURG +16 I/O urgente +$ SIGSTOP +17 Processo fermato +$ SIGTSTP +18 Stop da terminale +$ SIGCONT +19 Continuato +$ SIGCHLD +20 Processo figlio uscito +$ SIGTTIN +21 Input da terminale per processo in background +$ SIGTTOU +22 Output a terminale per processo in background +$ SIGIO +23 I/O possibile +$ SIGXCPU +24 Limite del tempo di CPU superato +$ SIGXFSZ +25 Limite della dimensione del file superato +$ SIGVTALRM +26 Timer virtuale scaduto +$ SIGPROF +27 Timer di profilo expired +$ SIGWINCH +28 Cambio di dimensione della finestra +$ SIGINFO +29 Richiesta di informazioni +$ SIGUSR1 +30 Segnale definito dall'utente 1 +$ SIGUSR2 +31 Segnale definito dall'utente 2 diff --git a/lib/libc/nls/ja_JP.UTF-8.msg b/lib/libc/nls/ja_JP.UTF-8.msg new file mode 100644 index 0000000..f6b87b7 --- /dev/null +++ b/lib/libc/nls/ja_JP.UTF-8.msg @@ -0,0 +1,295 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/ja_JP.UTF-8.msg 199128 2009-11-10 03:56:51Z ume $ +$ +$ Message catalog for ja_JP.UTF-8 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 許可されていない操作です +$ ENOENT +2 そのようなファイルまたはディレクトリはありません +$ ESRCH +3 そのようなプロセスはありません +$ EINTR +4 システムコールが中断されました +$ EIO +5 入出力エラーです +$ ENXIO +6 デバイスが準備されていません +$ E2BIG +7 引数のリストが長すぎます +$ ENOEXEC +8 無効な実行形式です +$ EBADF +9 無効なファイル記述子です +$ ECHILD +10 子プロセスがありません +$ EDEADLK +11 リソースデッドロックを回避しました +$ ENOMEM +12 メモリの割り当てができません +$ EACCES +13 パーミッションが拒絶されました +$ EFAULT +14 無効なアドレスです +$ ENOTBLK +15 ブロックデバイスが要求されています +$ EBUSY +16 デバイスがビジー状態です +$ EEXIST +17 ファイルが存在します +$ EXDEV +18 デバイスをまたぐリンクです +$ ENODEV +19 デバイスが対応してない操作です +$ ENOTDIR +20 ディレクトリではありません +$ EISDIR +21 ディレクトリです +$ EINVAL +22 無効な引数です +$ ENFILE +23 システム内でオープンされているファイルが多すぎます +$ EMFILE +24 オープンしているファイルが多すぎます +$ ENOTTY +25 デバイスが対応していない ioctl です +$ ETXTBSY +26 テキストファイルがビジー状態です +$ EFBIG +27 ファイルが大きすぎます +$ ENOSPC +28 デバイスの空き領域不足です +$ ESPIPE +29 無効なシークです +$ EROFS +30 読み込み専用ファイルシステムです +$ EMLINK +31 リンク数が多すぎます +$ EPIPE +32 パイプが破壊されてました +$ EDOM +33 数値引数が範囲外です +$ ERANGE +34 結果が大き過ぎます +$ EAGAIN, EWOULDBLOCK +35 リソースが一時的に利用できません +$ EINPROGRESS +36 操作が現在進行中です +$ EALREADY +37 操作は既に進行中です +$ ENOTSOCK +38 ソケットでないものについてソケット操作を行いました +$ EDESTADDRREQ +39 宛先アドレスが要求されています +$ EMSGSIZE +40 メッセージが長すぎます +$ EPROTOTYPE +41 ソケットが対応していないプロトコルタイプです +$ ENOPROTOOPT +42 利用できないプロトコルです +$ EPROTONOSUPPORT +43 対応していないプロトコルです +$ ESOCKTNOSUPPORT +44 対応していないソケットタイプです +$ EOPNOTSUPP +45 対応していない操作です +$ EPFNOSUPPORT +46 対応していないプロトコルファミリです +$ EAFNOSUPPORT +47 プロトコルファミリが対応していないアドレスファミリが指定されました +$ EADDRINUSE +48 アドレスが既に使用中です +$ EADDRNOTAVAIL +49 要求されたアドレスを割り当てできません +$ ENETDOWN +50 ネットワークがダウンしています +$ ENETUNREACH +51 ネットワークに到達できません +$ ENETRESET +52 リセットによりネットワークの接続が失われました +$ ECONNABORTED +53 ソフトウェアによって接続が切断されました +$ ECONNRESET +54 接続が通信相手によってリセットされました +$ ENOBUFS +55 バッファの容量不足です +$ EISCONN +56 ソケットは既に接続されています +$ ENOTCONN +57 ソケットは接続されていません +$ ESHUTDOWN +58 ソケットのシャットダウンの後で送信ができません +$ ETOOMANYREFS +59 処理限界を超える多重参照です +$ ETIMEDOUT +60 操作がタイムアウトしました +$ ECONNREFUSED +61 接続が拒絶されました +$ ELOOP +62 処理限界を超えるシンボリックリンクレベルです +$ ENAMETOOLONG +63 ファイル名が長すぎます +$ EHOSTDOWN +64 ホストがダウンしています +$ EHOSTUNREACH +65 ホストへの経路がありません +$ ENOTEMPTY +66 ディレクトリが空ではありません +$ EPROCLIM +67 プロセスが多すぎます +$ EUSERS +68 ユーザが多すぎます +$ EDQUOT +69 ディスククォータが超過しました +$ ESTALE +70 失効した NFS ファイルハンドルです +$ EREMOTE +71 パス中のリモートのレベルが多すぎます +$ EBADRPC +72 無効な RPC 構造体です +$ ERPCMISMATCH +73 RPC バージョンが間違っています +$ EPROGUNAVAIL +74 RPC プログラムが利用できません +$ EPROGMISMATCH +75 プログラムのバージョンが合っていません +$ EPROCUNAVAIL +76 プログラムでは利用できない procedure です +$ ENOLCK +77 ロックが利用できません +$ ENOSYS +78 関数が実装されていません +$ EFTYPE +79 ファイルの型または形式が不適切です +$ EAUTH +80 認証エラーです +$ ENEEDAUTH +81 認証物が必要です +$ EIDRM +82 識別子は削除されました +$ ENOMSG +83 要求された型のメッセージがありません +$ EOVERFLOW +84 データ型に格納するには大きすぎる値です +$ ECANCELED +85 処理がキャンセルされました +$ EILSEQ +86 不正なバイト列です +$ ENOATTR +87 そのような属性はありません +$ EDOOFUS +88 プログラミングエラーです +$ EBADMSG +89 無効なメッセージです +$ EMULTIHOP +90 マルチホップが試みられました +$ ENOLINK +91 リンクが切断されています +$ EPROTO +92 プロトコルエラーです +$ ENOTCAPABLE +93 ケーパビリティが不足です +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 ハングアップ +$ SIGINT +2 割り込み +$ SIGQUIT +3 中断 +$ SIGILL +4 不正命令 +$ SIGTRAP +5 トレース/BPT トラップ +$ SIGABRT +6 アボートトラップ +$ SIGEMT +7 EMT トラップ +$ SIGFPE +8 浮動小数点例外 +$ SIGKILL +9 Kill された +$ SIGBUS +10 バスエラー +$ SIGSEGV +11 セグメンテーション違反 +$ SIGSYS +12 存在しないシステムコール +$ SIGPIPE +13 パイプ破壊 +$ SIGALRM +14 アラームクロック +$ SIGTERM +15 終了 +$ SIGURG +16 緊急入出力状況 +$ SIGSTOP +17 一時停止 (シグナル) +$ SIGTSTP +18 一時停止 +$ SIGCONT +19 継続 +$ SIGCHLD +20 子プロセスの終了 +$ SIGTTIN +21 一時停止 (tty 入力) +$ SIGTTOU +22 一時停止 (tty 出力) +$ SIGIO +23 入出力可能 +$ SIGXCPU +24 CPU 時間の制限超過 +$ SIGXFSZ +25 ファイルサイズの制限超過 +$ SIGVTALRM +26 仮想タイマの期限超過 +$ SIGPROF +27 プロファイルタイマの期限超過 +$ SIGWINCH +28 ウィンドウサイズの変化 +$ SIGINFO +29 情報要求 +$ SIGUSR1 +30 ユーザ定義シグナル 1 +$ SIGUSR2 +31 ユーザ定義シグナル 2 +$ +$ gai_strerror() support catalog +$ +$set 3 +$ 1 (obsolete) +1 ホスト名のアドレスファミリーはサポートされません +$ EAI_AGAIN +2 名前解決での一時的な失敗 +$ EAI_BADFLAGS +3 ai_flags の値が無効 +$ EAI_FAIL +4 名前解決での回復不能な失敗 +$ EAI_FAMILY +5 ai_family はサポートされません +$ EAI_MEMORY +6 メモリ割り当て失敗 +$ 7 (obsolete) +7 ホスト名に対応するアドレスはありません +$ EAI_NONAME +8 ホスト名かサービス名が指定されない、または不明 +$ EAI_SERVICE +9 サービス名は ai_socktype に対してサポートされません +$ EAI_SOCKTYPE +10 ai_socktype はサポートされません +$ EAI_SYSTEM +11 システムエラー、errno 参照 +$ EAI_BADHINTS +12 hints の値が無効 +$ EAI_PROTOCOL +13 解決されたプロトコルは不明です +$ EAI_OVERFLOW +14 引数バッファオーバフロー +$ 0 +32766 成功 +$ NL_MSGMAX +32767 不明なエラー diff --git a/lib/libc/nls/ja_JP.eucJP.msg b/lib/libc/nls/ja_JP.eucJP.msg new file mode 100644 index 0000000..9db1bb5 --- /dev/null +++ b/lib/libc/nls/ja_JP.eucJP.msg @@ -0,0 +1,295 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/ja_JP.eucJP.msg 199128 2009-11-10 03:56:51Z ume $ +$ +$ Message catalog for ja_JP.eucJP locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 ���Ĥ���Ƥ��ʤ����Ǥ� +$ ENOENT +2 ���Τ褦�ʥե�����ޤ��ϥǥ��쥯�ȥ�Ϥ���ޤ��� +$ ESRCH +3 ���Τ褦�ʥץ����Ϥ���ޤ��� +$ EINTR +4 �����ƥॳ���뤬���Ǥ���ޤ��� +$ EIO +5 �����ϥ��顼�Ǥ� +$ ENXIO +6 �ǥХ�������������Ƥ��ޤ��� +$ E2BIG +7 �����Υꥹ�Ȥ�Ĺ�����ޤ� +$ ENOEXEC +8 ̵���ʼ¹Է����Ǥ� +$ EBADF +9 ̵���ʥե����뵭�һҤǤ� +$ ECHILD +10 �ҥץ���������ޤ��� +$ EDEADLK +11 �꥽�����ǥåɥ�å�����򤷤ޤ��� +$ ENOMEM +12 ����γ�����Ƥ��Ǥ��ޤ��� +$ EACCES +13 �ѡ��ߥå���󤬵��䤵��ޤ��� +$ EFAULT +14 ̵���ʥ��ɥ쥹�Ǥ� +$ ENOTBLK +15 �֥�å��ǥХ������׵ᤵ��Ƥ��ޤ� +$ EBUSY +16 �ǥХ������ӥ������֤Ǥ� +$ EEXIST +17 �ե����뤬¸�ߤ��ޤ� +$ EXDEV +18 �ǥХ�����ޤ�����󥯤Ǥ� +$ ENODEV +19 �ǥХ������б����Ƥʤ����Ǥ� +$ ENOTDIR +20 �ǥ��쥯�ȥ�ǤϤ���ޤ��� +$ EISDIR +21 �ǥ��쥯�ȥ�Ǥ� +$ EINVAL +22 ̵���ʰ����Ǥ� +$ ENFILE +23 �����ƥ���ǥ����ץ󤵤�Ƥ���ե����뤬¿�����ޤ� +$ EMFILE +24 �����ץ󤷤Ƥ���ե����뤬¿�����ޤ� +$ ENOTTY +25 �ǥХ������б����Ƥ��ʤ� ioctl �Ǥ� +$ ETXTBSY +26 �ƥ����ȥե����뤬�ӥ������֤Ǥ� +$ EFBIG +27 �ե����뤬�礭�����ޤ� +$ ENOSPC +28 �ǥХ����ζ����ΰ���­�Ǥ� +$ ESPIPE +29 ̵���ʥ������Ǥ� +$ EROFS +30 �ɤ߹������ѥե����륷���ƥ�Ǥ� +$ EMLINK +31 ��󥯿���¿�����ޤ� +$ EPIPE +32 �ѥ��פ��˲�����Ƥޤ��� +$ EDOM +33 ���Ͱ������ϰϳ��Ǥ� +$ ERANGE +34 ��̤��礭�᤮�ޤ� +$ EAGAIN, EWOULDBLOCK +35 �꥽���������Ū�����ѤǤ��ޤ��� +$ EINPROGRESS +36 �����߿ʹ���Ǥ� +$ EALREADY +37 ���ϴ��˿ʹ���Ǥ� +$ ENOTSOCK +38 �����åȤǤʤ���ΤˤĤ��ƥ����å�����Ԥ��ޤ��� +$ EDESTADDRREQ +39 ���襢�ɥ쥹���׵ᤵ��Ƥ��ޤ� +$ EMSGSIZE +40 ��å�������Ĺ�����ޤ� +$ EPROTOTYPE +41 �����åȤ��б����Ƥ��ʤ��ץ�ȥ��륿���פǤ� +$ ENOPROTOOPT +42 ���ѤǤ��ʤ��ץ�ȥ���Ǥ� +$ EPROTONOSUPPORT +43 �б����Ƥ��ʤ��ץ�ȥ���Ǥ� +$ ESOCKTNOSUPPORT +44 �б����Ƥ��ʤ������åȥ����פǤ� +$ EOPNOTSUPP +45 �б����Ƥ��ʤ����Ǥ� +$ EPFNOSUPPORT +46 �б����Ƥ��ʤ��ץ�ȥ���ե��ߥ�Ǥ� +$ EAFNOSUPPORT +47 �ץ�ȥ���ե��ߥ꤬�б����Ƥ��ʤ����ɥ쥹�ե��ߥ꤬���ꤵ��ޤ��� +$ EADDRINUSE +48 ���ɥ쥹�����˻�����Ǥ� +$ EADDRNOTAVAIL +49 �׵ᤵ�줿���ɥ쥹�������ƤǤ��ޤ��� +$ ENETDOWN +50 �ͥåȥ���������󤷤Ƥ��ޤ� +$ ENETUNREACH +51 �ͥåȥ������ã�Ǥ��ޤ��� +$ ENETRESET +52 �ꥻ�åȤˤ��ͥåȥ������³�������ޤ��� +$ ECONNABORTED +53 ���եȥ������ˤ�ä���³�����Ǥ���ޤ��� +$ ECONNRESET +54 ��³���̿����ˤ�äƥꥻ�åȤ���ޤ��� +$ ENOBUFS +55 �Хåե���������­�Ǥ� +$ EISCONN +56 �����åȤϴ�����³����Ƥ��ޤ� +$ ENOTCONN +57 �����åȤ���³����Ƥ��ޤ��� +$ ESHUTDOWN +58 �����åȤΥ���åȥ�����θ���������Ǥ��ޤ��� +$ ETOOMANYREFS +59 �����³���Ķ����¿�Ż��ȤǤ� +$ ETIMEDOUT +60 �������ॢ���Ȥ��ޤ��� +$ ECONNREFUSED +61 ��³�����䤵��ޤ��� +$ ELOOP +62 �����³���Ķ���륷��ܥ�å���󥯥�٥�Ǥ� +$ ENAMETOOLONG +63 �ե�����̾��Ĺ�����ޤ� +$ EHOSTDOWN +64 �ۥ��Ȥ������󤷤Ƥ��ޤ� +$ EHOSTUNREACH +65 �ۥ��Ȥؤη�ϩ������ޤ��� +$ ENOTEMPTY +66 �ǥ��쥯�ȥ꤬���ǤϤ���ޤ��� +$ EPROCLIM +67 �ץ�����¿�����ޤ� +$ EUSERS +68 �桼����¿�����ޤ� +$ EDQUOT +69 �ǥ���������������Ķ�ᤷ�ޤ��� +$ ESTALE +70 �������� NFS �ե�����ϥ�ɥ�Ǥ� +$ EREMOTE +71 �ѥ���Υ�⡼�ȤΥ�٥뤬¿�����ޤ� +$ EBADRPC +72 ̵���� RPC ��¤�ΤǤ� +$ ERPCMISMATCH +73 RPC �С�����󤬴ְ�äƤ��ޤ� +$ EPROGUNAVAIL +74 RPC �ץ���ब���ѤǤ��ޤ��� +$ EPROGMISMATCH +75 �ץ����ΥС�����󤬹�äƤ��ޤ��� +$ EPROCUNAVAIL +76 �ץ����Ǥ����ѤǤ��ʤ� procedure �Ǥ� +$ ENOLCK +77 ��å������ѤǤ��ޤ��� +$ ENOSYS +78 �ؿ�����������Ƥ��ޤ��� +$ EFTYPE +79 �ե�����η��ޤ��Ϸ�������Ŭ�ڤǤ� +$ EAUTH +80 ǧ�ڥ��顼�Ǥ� +$ ENEEDAUTH +81 ǧ��ʪ��ɬ�פǤ� +$ EIDRM +82 ���̻ҤϺ������ޤ��� +$ ENOMSG +83 �׵ᤵ�줿���Υ�å�����������ޤ��� +$ EOVERFLOW +84 �ǡ������˳�Ǽ����ˤ��礭�������ͤǤ� +$ ECANCELED +85 ����������󥻥뤵��ޤ��� +$ EILSEQ +86 �����ʥХ�����Ǥ� +$ ENOATTR +87 ���Τ褦��°���Ϥ���ޤ��� +$ EDOOFUS +88 �ץ���ߥ󥰥��顼�Ǥ� +$ EBADMSG +89 ̵���ʥ�å������Ǥ� +$ EMULTIHOP +90 �ޥ���ۥåפ���ߤ��ޤ��� +$ ENOLINK +91 ��󥯤����Ǥ���Ƥ��ޤ� +$ EPROTO +92 �ץ�ȥ��륨�顼�Ǥ� +$ ENOTCAPABLE +93 �����ѥӥ�ƥ�����­�Ǥ� +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 �ϥ󥰥��å� +$ SIGINT +2 ������ +$ SIGQUIT +3 ���� +$ SIGILL +4 ����̿�� +$ SIGTRAP +5 �ȥ졼��/BPT �ȥ�å� +$ SIGABRT +6 ���ܡ��ȥȥ�å� +$ SIGEMT +7 EMT �ȥ�å� +$ SIGFPE +8 ��ư�������㳰 +$ SIGKILL +9 Kill ���줿 +$ SIGBUS +10 �Х����顼 +$ SIGSEGV +11 �������ơ�������ȿ +$ SIGSYS +12 ¸�ߤ��ʤ������ƥॳ���� +$ SIGPIPE +13 �ѥ����˲� +$ SIGALRM +14 ���顼�९��å� +$ SIGTERM +15 ��λ +$ SIGURG +16 �۵������Ͼ��� +$ SIGSTOP +17 ������ (�����ʥ�) +$ SIGTSTP +18 ������ +$ SIGCONT +19 ��³ +$ SIGCHLD +20 �ҥץ����ν�λ +$ SIGTTIN +21 ������ (tty ����) +$ SIGTTOU +22 ������ (tty ����) +$ SIGIO +23 �����ϲ�ǽ +$ SIGXCPU +24 CPU ���֤�����Ķ�� +$ SIGXFSZ +25 �ե����륵����������Ķ�� +$ SIGVTALRM +26 ���ۥ����ޤδ���Ķ�� +$ SIGPROF +27 �ץ�ե����륿���ޤδ���Ķ�� +$ SIGWINCH +28 ������ɥ����������Ѳ� +$ SIGINFO +29 �����׵� +$ SIGUSR1 +30 �桼����������ʥ� 1 +$ SIGUSR2 +31 �桼����������ʥ� 2 +$ +$ gai_strerror() support catalog +$ +$set 3 +$ 1 (obsolete) +1 �ۥ���̾�Υ��ɥ쥹�ե��ߥ꡼�ϥ��ݡ��Ȥ���ޤ��� +$ EAI_AGAIN +2 ̾�����Ǥΰ��Ū�ʼ��� +$ EAI_BADFLAGS +3 ai_flags ���ͤ�̵�� +$ EAI_FAIL +4 ̾�����Ǥβ�����ǽ�ʼ��� +$ EAI_FAMILY +5 ai_family �ϥ��ݡ��Ȥ���ޤ��� +$ EAI_MEMORY +6 ���������Ƽ��� +$ 7 (obsolete) +7 �ۥ���̾���б����륢�ɥ쥹�Ϥ���ޤ��� +$ EAI_NONAME +8 �ۥ���̾�������ӥ�̾�����ꤵ��ʤ����ޤ������� +$ EAI_SERVICE +9 �����ӥ�̾�� ai_socktype ���Ф��ƥ��ݡ��Ȥ���ޤ��� +$ EAI_SOCKTYPE +10 ai_socktype �ϥ��ݡ��Ȥ���ޤ��� +$ EAI_SYSTEM +11 �����ƥ२�顼��errno ���� +$ EAI_BADHINTS +12 hints ���ͤ�̵�� +$ EAI_PROTOCOL +13 ��褵�줿�ץ�ȥ���������Ǥ� +$ EAI_OVERFLOW +14 �����Хåե������Хե� +$ 0 +32766 ���� +$ NL_MSGMAX +32767 �����ʥ��顼 diff --git a/lib/libc/nls/mn_MN.UTF-8.msg b/lib/libc/nls/mn_MN.UTF-8.msg new file mode 100644 index 0000000..4ce5ef0 --- /dev/null +++ b/lib/libc/nls/mn_MN.UTF-8.msg @@ -0,0 +1,249 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/mn_MN.UTF-8.msg 192653 2009-05-23 17:13:35Z des $ +$ +$ Message catalog for mn_MN.UTF-8 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Үйлдэл зөвшөөрөгдөхгүй +$ ENOENT +2 Тийм файл эсвэл сан алга +$ ESRCH +3 Тийм процесс байхгүй +$ EINTR +4 Системийн тасалдсан дуудлага +$ EIO +5 Оролт/гаралтын алдаа +$ ENXIO +6 Төхөөрөмж тохируулагдаагүй +$ E2BIG +7 Дагавар өгөгдлийн жагсаалт хэтэрхий урт +$ ENOEXEC +8 Exec хэлбэршилтийн алдаа +$ EBADF +9 Файлын буруу тодорхойлогч +$ ECHILD +10 Хүүхэд процесс алга +$ EDEADLK +11 Эх үүсвэрийн гацаанаас зайлсхийсэн +$ ENOMEM +12 Санах ойд зай байрлуулж чадахгүй байна +$ EACCES +13 Зөвшөөрөхөөс татгалзсан +$ EFAULT +14 Буруу хаяг +$ ENOTBLK +15 Блок төхөөрөмж шаардагдсан +$ EBUSY +16 Төхөөрөмж завгүй +$ EEXIST +17 Файл байна +$ EXDEV +18 Төхөөрөмж хоорондын холбоос +$ ENODEV +19 Үйлдлийг төхөөрөмж дэмжээгүй +$ ENOTDIR +20 Сан биш +$ EISDIR +21 Сан мөн +$ EINVAL +22 Дагавар өгөгдөл буруу +$ ENFILE +23 Системд хэтэрхий олон нээлттэй файл байна +$ EMFILE +24 Хэтэрхий олон нээлттэй файл байна +$ ENOTTY +25 Төхөөрөмжтэй тохирохгүй ioctl үйлдэл +$ ETXTBSY +26 Текст файл завгүй +$ EFBIG +27 Файл хэтэрхий том +$ ENOSPC +28 Төхөөрөмж дээр зай үлдсэнгүй +$ ESPIPE +29 Хайлт буруу +$ EROFS +30 Зөвхөн-уншигдах файлын систем +$ EMLINK +31 Хэтэрхий олон холбоос байна +$ EPIPE +32 Эвдэрхий хоолой +$ EDOM +33 Тоон дагавар өгөгдөл талбараас гадна байна +$ ERANGE +34 Үр дүн хэтэрхий том +$ EAGAIN, EWOULDBLOCK +35 Эх үүсвэр түр зуур боломжгүй байна +$ EINPROGRESS +36 Үйлдэл одоо хийгдэж байна +$ EALREADY +37 Үйлдэл аль хэдийн хийгдэж байна +$ ENOTSOCK +38 Сокет бус зүйл дээр сокет үйлдэл +$ EDESTADDRREQ +39 Очих хаяг шаардагдсан +$ EMSGSIZE +40 Зурвас мэдээ хэтэрхий урт +$ EPROTOTYPE +41 Сокетийн хувьд протокол буруу төрлийнх байна +$ ENOPROTOOPT +42 Протокол байхгүй +$ EPROTONOSUPPORT +43 Протокол дэмжигдээгүй +$ ESOCKTNOSUPPORT +44 Сокетийн төрөл дэмжигдээгүй +$ EOPNOTSUPP +45 Үйлдэл дэмжигдээгүй +$ EPFNOSUPPORT +46 Протоколын гэр бүл дэмжигдээгүй +$ EAFNOSUPPORT +47 Хаягийн гэр бүлийг протоколын гэр бүл дэмжээгүй +$ EADDRINUSE +48 Хаяг ашиглагдаж байна +$ EADDRNOTAVAIL +49 Хүссэн хаягийг өгч чадахгүй +$ ENETDOWN +50 Сүлжээ унасан байна +$ ENETUNREACH +51 Сүлжээнд хүрэх боломжгүй +$ ENETRESET +52 Салгалт хийгдэхэд сүлжээ холболтыг унагалаа +$ ECONNABORTED +53 Програм хангамжаас болж холболт зогслоо +$ ECONNRESET +54 Холболтыг харилцагч салгалаа +$ ENOBUFS +55 Буфферийн зай байхгүй +$ EISCONN +56 Сокет аль хэдийн холбогдсон +$ ENOTCONN +57 Сокет холбогдоогүй +$ ESHUTDOWN +58 Сокет унтарсны дараа илгээж чадахгүй +$ ETOOMANYREFS +59 Хэтэрхий их хамаарлууд байна: залгаж чадахгүй +$ ETIMEDOUT +60 Үйлдлийн хугацаа дууссан +$ ECONNREFUSED +61 Холболт тогтоохоос татгалзлаа +$ ELOOP +62 Тэмдэгт холбоосуудын түвшин хэтэрхий олон байна +$ ENAMETOOLONG +63 Файлын нэр хэтэрхий урт +$ EHOSTDOWN +64 Төв компьютер зогссон байна +$ EHOSTUNREACH +65 Төв компьютер рүү чиглүүлэлт байхгүй +$ ENOTEMPTY +66 Сан хоосон биш +$ EPROCLIM +67 Хэтэрхий олон үйлдэл байна +$ EUSERS +68 Хэтэрхий олон хэрэглэгч байна +$ EDQUOT +69 Дискийн хязгаар хэмжээ хэтэрсэн +$ ESTALE +70 Хуучирсан NFS файлын жолоо +$ EREMOTE +71 Зам хэтэрхий алслагдсан түвшинтэй байна +$ EBADRPC +2 RPC бүтэц буруу +$ ERPCMISMATCH +73 RPC-ийн хувилбар буруу +$ EPROGUNAVAIL +74 RPC програм байхгүй +$ EPROGMISMATCH +75 Програмын хувилбар буруу +$ EPROCUNAVAIL +76 Програмын хувьд процедур буруу +$ ENOLCK +77 Түгжээ байхгүй +$ ENOSYS +78 Функц гүйцэтгэгдээгүй +$ EFTYPE +79 Файлын төрөл эсвэл хэлбэршилт тохироогүй +$ EAUTH +80 Нэвтрүүлэх алдаа +$ ENEEDAUTH +81 Нэвтррүүлэгч хэрэгтэй +$ EIDRM +82 Танигч устгагдсан +$ ENOMSG +83 Хүссэн төрлийн зурвас мэдээ байхгүй +$ EOVERFLOW +84 Утга нь өгөгдлийн төрөлд хадгалагдаж болохооргүй хэтэрхий том байна +$ ECANCELED +85 Үйлдэл зогсоогдсон +$ EILSEQ +86 Байтын дараалал буруу +$ ENOATTR +87 Атрибут олдсонгүй +$ EDOOFUS +88 Програмчлалын алдаа +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Зогсоох (Hangup) +$ SIGINT +2 Тасалдал +$ SIGQUIT +3 Гарах +$ SIGILL +4 Буруу заавар +$ SIGTRAP +5 Мөр/BPT занга +$ SIGABRT +6 Таслан зогсоох занга +$ SIGEMT +7 EMT занга +$ SIGFPE +8 Хөвөгч цэгийн онцгой алдаа +$ SIGKILL +9 Хөнөөсөн +$ SIGBUS +10 Шугамын алдаа +$ SIGSEGV +11 Сегментийн гэмтэл +$ SIGSYS +12 Системийн буруу дуудлага +$ SIGPIPE +13 Эвдэрхий хоолой +$ SIGALRM +14 Сэрүүлэгт цаг +$ SIGTERM +15 Төгссөн +$ SIGURG +16 Яаралтай I/O нөхцөл +$ SIGSTOP +17 Түр зогссон (дохио) +$ SIGTSTP +18 Түр зогссон +$ SIGCONT +19 Үргэлжилсэн +$ SIGCHLD +20 Хүүхэд процесс гарсан +$ SIGTTIN +21 Зогссон (tty оролт) +$ SIGTTOU +22 Зогссон (tty гаралт) +$ SIGIO +23 I/O боломжтой +$ SIGXCPU +24 CPU-ийн хугацааны хязгаар хэтэрсэн +$ SIGXFSZ +25 Файлын хэмжээний хязгаар хэтэрсэн +$ SIGVTALRM +26 Виртуал цаг хэмжигчийн хугацаа дууссан +$ SIGPROF +27 Профил хийх цаг хэмжигчийн хугацаа дууссан +$ SIGWINCH +28 Цонхны хэмжээний өөрчлөлт +$ SIGINFO +29 Мэдээллийн хүсэлт +$ SIGUSR1 +30 Хэрэглэгчийн тодорхойлсон дохио 1 +$ SIGUSR2 +31 Хэрэглэгчийн тодорхойлсон дохио 2 diff --git a/lib/libc/nls/nl_NL.ISO8859-1.msg b/lib/libc/nls/nl_NL.ISO8859-1.msg new file mode 100644 index 0000000..205c2a1 --- /dev/null +++ b/lib/libc/nls/nl_NL.ISO8859-1.msg @@ -0,0 +1,294 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/nl_NL.ISO8859-1.msg 199190 2009-11-11 18:28:12Z rene $ +$ +$ Message catalog for nl_NL.ISO8859-1 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Bewerking niet toegestaan +$ ENOENT +2 Bestand of map niet gevonden +$ ESRCH +3 Taak bestaat niet +$ EINTR +4 Onderbroken systeemaanroep +$ EIO +5 Invoer/uitvoer fout +$ ENXIO +6 Apparaat niet geconfigureerd +$ E2BIG +7 Argumentenlijst is te lang +$ ENOEXEC +8 Programma kan niet worden uitgevoerd +$ EBADF +9 Ongeldige bestandsverwijzing +$ ECHILD +10 Geen kindprocessen +$ EDEADLK +11 Een deadlock op een bron is vermeden +$ ENOMEM +12 Kan geen geheugen meer verkrijgen +$ EACCES +13 Toegang geweigerd +$ EFAULT +14 Ongeldig adres +$ ENOTBLK +15 Een per blok adresseerbaar apparaat is vereist +$ EBUSY +16 Apparaat is bezig +$ EEXIST +17 Bestand bestaat reeds +$ EXDEV +18 Verwijzing tussen verschillende apparaten +$ ENODEV +19 Bewerking wordt niet ondersteund door dit apparaat +$ ENOTDIR +20 Dit is geen map +$ EISDIR +21 Dit is een map +$ EINVAL +22 Ongeldig argument +$ ENFILE +23 Te veel open bestanden in het systeem +$ EMFILE +24 Te veel open bestanden +$ ENOTTY +25 ioctl niet van toepassing op dit apparaat +$ ETXTBSY +26 Programmabestand is bezig +$ EFBIG +27 Bestand is te groot +$ ENOSPC +28 Geen ruimte meer op dit apparaat +$ ESPIPE +29 Ongeldige zoekopdracht +$ EROFS +30 Van dit bestandssysteem kan alleen worden gelezen +$ EMLINK +31 Te veel bestandsverwijzingen +$ EPIPE +32 Gebroken pijp +$ EDOM +33 Numeriek argument valt buiten domein +$ ERANGE +34 Resultaat te groot of te klein +$ EAGAIN, EWOULDBLOCK +35 Middel tijdelijk onbeschikbaar +$ EINPROGRESS +36 Bewerking in gang gezet +$ EALREADY +37 Bewerking is al in gang gezet +$ ENOTSOCK +38 Voor deze bewerking is een contactpunt vereist +$ EDESTADDRREQ +39 Een bestemmingsadres is vereist +$ EMSGSIZE +40 Te groot bericht +$ EPROTOTYPE +41 Protocol past niet bij dit contactpunt +$ ENOPROTOOPT +42 Protocol is niet beschikbaar +$ EPROTONOSUPPORT +43 Protocol is niet ondersteund +$ ESOCKTNOSUPPORT +44 Dit soort contactpunt is niet ondersteund +$ EOPNOTSUPP +45 Bewerking niet ondersteund +$ EPFNOSUPPORT +46 Protocolfamilie niet ondersteund +$ EAFNOSUPPORT +47 Adressenfamilie niet ondersteund door protocolfamilie +$ EADDRINUSE +48 Adres is al in gebruik +$ EADDRNOTAVAIL +49 Het gevraagde adres kan niet worden toegekend +$ ENETDOWN +50 Netwerk is plat +$ ENETUNREACH +51 Netwerk is onbereikbaar +$ ENETRESET +52 Netwerk onderbrak verbinding tijdens herstart +$ ECONNABORTED +53 Verbroken verbinding veroorzaakt door software +$ ECONNRESET +54 Verbinding werd aan de andere kant verbroken +$ ENOBUFS +55 Geen bufferruimte meer beschikbaar +$ EISCONN +56 Contactpunt is al verbonden +$ ENOTCONN +57 Contactpunt is niet verbonden +$ ESHUTDOWN +58 Een afgesloten contactpunt kan geen gegevens meer verzenden +$ ETOOMANYREFS +59 Te veel verwijzingen: splitsen niet mogelijk +$ ETIMEDOUT +60 Verbinding te lang niet mogelijk +$ ECONNREFUSED +61 Verbinding geweigerd +$ ELOOP +62 Te veel niveaus van symbolische verwijzingen +$ ENAMETOOLONG +63 Bestandsnaam te lang +$ EHOSTDOWN +64 Bestemming niet actief +$ EHOSTUNREACH +65 Bestemming niet bereikbaar +$ ENOTEMPTY +66 Map is niet leeg +$ EPROCLIM +67 Te veel processen +$ EUSERS +68 Te veel gebruikers +$ EDQUOT +69 Schijfquota overschreden +$ ESTALE +70 Verlopen NFS-bestandsverwijzing +$ EREMOTE +71 Te veel verwijzingen op afstand in dit pad +$ EBADRPC +72 RPC-argumentstructuur is incorrect +$ ERPCMISMATCH +73 RPC-versie is verkeerd +$ EPROGUNAVAIL +74 RPC-programma niet beschikbaar +$ EPROGMISMATCH +75 Programmaversie is verkeerd +$ EPROCUNAVAIL +76 Taak kan niet door dit programma worden uitgevoerd +$ ENOLCK +77 Geen sloten beschikbaar +$ ENOSYS +78 Systeemfunctie is niet geimplementeerd +$ EFTYPE +79 Bestandsformaat niet van toepassing +$ EAUTH +80 Aanmeldingsfout +$ ENEEDAUTH +81 Aanmeldingsprocedure benodigd +$ EIDRM +82 De aanwijzer is verwijderd +$ ENOMSG +83 Geen bericht van het gewenste type +$ EOVERFLOW +84 Waarde te groot om te bewaren in gegevenstype +$ ECANCELED +85 Bewerking geannuleerd +$ EILSEQ +86 Ongeldige bytereeks +$ ENOATTR +87 Attribuut niet gevonden +$ EDOOFUS +88 Programmeerfout +$ EBADMSG +89 Verkeerd of defect bericht +$ EMULTIHOP +90 Multihopverzoek +$ ENOLINK +91 Verbinding werd verstoord +$ EPROTO +92 Protocolfout +$ ENOTCAPABLE +93 Onvoldoende mogelijkheden +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Opgehangen +$ SIGINT +2 Onderbroken +$ SIGQUIT +3 Opgegeven +$ SIGILL +4 Verboden instructie +$ SIGTRAP +5 Spoor/BPT-val +$ SIGABRT +6 Abort-val +$ SIGEMT +7 EMT-val +$ SIGFPE +8 Drijvende kommafout +$ SIGKILL +9 Gedood +$ SIGBUS +10 Busfout +$ SIGSEGV +11 Segmentatiefout +$ SIGSYS +12 Verkeerde systeemaanroep +$ SIGPIPE +13 Gebroken pijp +$ SIGALRM +14 Wekker +$ SIGTERM +15 Beeindigd +$ SIGURG +16 Dringende I/O opgemerkt +$ SIGSTOP +17 Gestopt (signaal) +$ SIGTSTP +18 Gestopt +$ SIGCONT +19 Voortgezet +$ SIGCHLD +20 Kindproces beeindigd +$ SIGTTIN +21 Gestopt (TTY-invoer) +$ SIGTTOU +22 Gestopt (TTY-uitvoer) +$ SIGIO +23 I/O mogelijk +$ SIGXCPU +24 Te veel CPU-tijd verbruikt +$ SIGXFSZ +25 Maximale bestandsgrootte overschreden +$ SIGVTALRM +26 Virtuele wekker +$ SIGPROF +27 Profiling-wekker +$ SIGWINCH +28 Venstergrootte veranderd +$ SIGINFO +29 Informatieverzoek +$ SIGUSR1 +30 Gebruikersignaal 1 +$ SIGUSR2 +31 Gebruikersignaal 2 +$ +$ gai_strerror() support catalog +$set 3 +$ 1 (obsolete) +1 Adresfamilie voor hostnaam niet ondersteund +$ EAI_AGAIN +2 Tijdelijke fout in naamresolutie +$ EAI_BADFLAGS +3 Ongeldige waarde voor ai_flags +$ EAI_FAIL +4 Onherstelbare fout in naamresolutie +$ EAI_FAMILY +5 ai_familie niet ondersteund +$ EAI_MEMORY +6 Geheugenallocatiefout +$ 7 (obsolete) +7 Geen adres met hostnaam geassocieerd +$ EAI_NONAME +8 hostname noch servname gegeven, of onbekend +$ EAI_SERVICE +9 servname niet ondersteund voor ai_socktype +$ EAI_SOCKTYPE +10 ai_socktype niet ondersteund +$ EAI_SYSTEM +11 Systeemfout geretourneerd in errno +$ EAI_BADHINTS +12 Ongeldige waarde voor hints +$ EAI_PROTOCOL +13 Opgelost protocol is onbekend +$ EAI_OVERFLOW +14 Argumentbuffer overstroomd +$ 0 +32766 Succes +$ NL_MSGMAX +32767 Onbekende fout diff --git a/lib/libc/nls/no_NO.ISO8859-1.msg b/lib/libc/nls/no_NO.ISO8859-1.msg new file mode 100644 index 0000000..3d2da21 --- /dev/null +++ b/lib/libc/nls/no_NO.ISO8859-1.msg @@ -0,0 +1,231 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/no_NO.ISO8859-1.msg 189765 2009-03-13 10:40:38Z gabor $ +$ +$ Message catalog for no_NO.ISO8859-1 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Operasjonen er ikke tillatt +$ ENOENT +2 Filen eller katalogen finnes ikke +$ ESRCH +3 Prosessen finnes ikke +$ EINTR +4 Avbrudt systemkall +$ EIO +5 I/O feil +$ ENXIO +6 Enheten er ikke konfigurert +$ E2BIG +7 Argumentlisten er for lang +$ ENOEXEC +8 Ukjent kj�rbart format +$ EBADF +9 Ugyldig fildeskriptor +$ ECHILD +10 Ingen barneprosess +$ EDEADLK +11 Vrangl�s unng�tt +$ ENOMEM +12 Kan ikke allokere nok minne +$ EACCES +13 Ingen adgang +$ EFAULT +14 Ugyldig adresse +$ ENOTBLK +15 Blokk-enhet p�krevd +$ EBUSY +16 Enheten er opptatt +$ EEXIST +17 Filen finnes +$ EXDEV +18 Link mellom forskjellige enheter +$ ENODEV +19 Operasjonen er ikke st�ttet av enheten +$ ENOTDIR +20 Ikke en katalog +$ EISDIR +21 Er en katalog +$ EINVAL +22 Ugyldig argument +$ ENFILE +23 For mange �pne filer i systemet +$ EMFILE +24 For mange �pne filer +$ ENOTTY +25 Ugyldig ioctl for enheten +$ ETXTBSY +26 Kj�rbar fil i bruk +$ EFBIG +27 Filen er for stor +$ ENOSPC +28 Ingen ledig plass p� enheten +$ ESPIPE +29 Ugyldig seek operasjon +$ EROFS +30 Filsystemet er skrivebeskyttet +$ EMLINK +31 For mange linker +$ EPIPE +32 Brudt pipe +$ EDOM +33 Numerisk argument utenfor arbeidsomr�det +$ ERANGE +34 Resultatet er for stort +$ EAGAIN, EWOULDBLOCK +35 Ressurs midlertidig utilgjengelig +$ EINPROGRESS +36 Operasjonen er n� i gang +$ EALREADY +37 Operasjonen er allerede i gang +$ ENOTSOCK +38 Deskriptoren er ikke en socket +$ EDESTADDRREQ +39 Mottakeradresse er p�krevd +$ EMSGSIZE +40 Meldingen er for lang +$ EPROTOTYPE +41 Ugyldig protokolltype for denne socketen +$ ENOPROTOOPT +42 Protokollen er ikke tilgjengelig +$ EPROTONOSUPPORT +43 Protokollen er ikke st�ttet +$ ESOCKTNOSUPPORT +44 Socket-typen er ikke st�ttet +$ EOPNOTSUPP +45 Operasjonen er ikke st�ttet +$ EPFNOSUPPORT +46 Protokollfamilien er ikke st�ttet +$ EAFNOSUPPORT +47 Adressetypen er ikke st�ttet av protokollfamilien +$ EADDRINUSE +48 Adressen er allerede i bruk +$ EADDRNOTAVAIL +49 Kan ikke bruke den �nskede adressen +$ ENETDOWN +50 Nettverket er nede +$ ENETUNREACH +51 Nettverket er utilgjengelig +$ ENETRESET +52 Nettverket kuttet forbindelsen ved reset +$ ECONNABORTED +53 Programvaren for�rsaket brudd av forbindelsen +$ ECONNRESET +54 Forbindelsen avbrudt av korrespondenten +$ ENOBUFS +55 Buffer-plass ikke tilgjengelig +$ EISCONN +56 Socketen er allerede forbundet +$ ENOTCONN +57 Socketen er ikke forbundet +$ ESHUTDOWN +58 Kan ikke sende etter at socketen er tatt ned +$ ETOOMANYREFS +59 For mange referanser: kan ikke sl� dem sammen +$ ETIMEDOUT +60 Tiden til forbindelsen utl�p +$ ECONNREFUSED +61 Forbindelse nektet +$ ELOOP +62 For mange niv�er med symbolske linker +$ ENAMETOOLONG +63 Filnavnet er for langt +$ EHOSTDOWN +64 Maskinen er nede +$ EHOSTUNREACH +65 Ingen rute til maskinen +$ ENOTEMPTY +66 Katalogen er ikke tom +$ EPROCLIM +67 For mange prosesser +$ EUSERS +68 For mange brukere +$ EDQUOT +69 Diskkvote overskredet +$ ESTALE +70 Fastl�st NFS fildeskriptor +$ EREMOTE +71 For mange niv�er med remote i stien +$ EBADRPC +72 Ugyldig RPC struktur +$ ERPCMISMATCH +73 Feil RPC versjon +$ EPROGUNAVAIL +74 RPC program ikke tilgjengelig +$ EPROGMISMATCH +75 Feil programversjon +$ EPROCUNAVAIL +76 Prosedyren finnes ikke i programmet +$ ENOLCK +77 Ingen l�sing tilgjengelig +$ ENOSYS +78 Funksjonen er ikke implementert +$ EFTYPE +79 Ugyldig filtype eller format +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Hangup +$ SIGINT +2 Avbrudd +$ SIGQUIT +3 Avslutt +$ SIGILL +4 Ugyldig instruksjon +$ SIGTRAP +5 Trace/BPT trap +$ SIGABRT +6 Abort trap +$ SIGEMT +7 EMT trap +$ SIGFPE +8 Flyttallsfeil +$ SIGKILL +9 Drept +$ SIGBUS +10 Buss feil +$ SIGSEGV +11 Segmenteringsfeil +$ SIGSYS +12 Ugyldig systemkall +$ SIGPIPE +13 Brudt pipe +$ SIGALRM +14 Alarmklokke +$ SIGTERM +15 Terminert +$ SIGURG +16 Urgent I/O condition +$ SIGSTOP +17 Stoppet (signal) +$ SIGTSTP +18 Stoppet +$ SIGCONT +19 Fortsetter +$ SIGCHLD +20 Barn avsluttet +$ SIGTTIN +21 Stoppet (tty input) +$ SIGTTOU +22 Stoppet (tty output) +$ SIGIO +23 I/O mulig +$ SIGXCPU +24 CPU-tid overskredet +$ SIGXFSZ +25 Maksimal filst�rrelse overskredet +$ SIGVTALRM +26 Virtuell timer utl�pt +$ SIGPROF +27 Profileringstimer utl�pt +$ SIGWINCH +28 Vindust�rrelse endres +$ SIGINFO +29 Informasjonsforesp�rsel +$ SIGUSR1 +30 Brukerdefinert signal 1 +$ SIGUSR2 +31 Brukerdefinert signal 2 diff --git a/lib/libc/nls/pt_BR.ISO8859-1.msg b/lib/libc/nls/pt_BR.ISO8859-1.msg new file mode 100644 index 0000000..4b81841 --- /dev/null +++ b/lib/libc/nls/pt_BR.ISO8859-1.msg @@ -0,0 +1,249 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/pt_BR.ISO8859-1.msg 189963 2009-03-18 14:33:10Z gabor $ +$ +$ Message catalog for pt_BR.ISO8859-1 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Opera��o n�o permitida +$ ENOENT +2 Nenhum arquivo ou diret�rio encontrado +$ ESRCH +3 Nenhum processo encontrado +$ EINTR +4 Chamada de sistema interrompida +$ EIO +5 Erro de entrada/sa�da +$ ENXIO +6 Dispositivo n�o configurado +$ E2BIG +7 Lista de argumentos muito grande +$ ENOEXEC +8 Erro no formato de execu��o +$ EBADF +9 Erro no descritor de arquivo +$ ECHILD +10 Nenhum processo filho +$ EDEADLK +11 Bloqueio de recurso evitado +$ ENOMEM +12 Imposs�vel alocar mem�ria +$ EACCES +13 Permiss�o negada +$ EFAULT +14 Endere�o errado +$ ENOTBLK +15 Dispositivo de bloco requerido +$ EBUSY +16 Dispositivo ocupado +$ EEXIST +17 Arquivo existe +$ EXDEV +18 Liga��o entre dispositivos +$ ENODEV +19 Opera��o n�o suportada pelo dispositivo +$ ENOTDIR +20 N�o � um diret�rio +$ EISDIR +21 � um diret�rio +$ EINVAL +22 Argumento inv�lido +$ ENFILE +23 Muitos arquivos abertos no sistema +$ EMFILE +24 Muitos arquivos abertos no sistema +$ ENOTTY +25 ioctl inapropriado para o dispositivo +$ ETXTBSY +26 Arquivo texto sendo utilizado +$ EFBIG +27 Arquivo muito grande +$ ENOSPC +28 Sem espa�o no dispositivo +$ ESPIPE +29 seek ilegal +$ EROFS +30 Sistema de arquivos apenas para leitura +$ EMLINK +31 Muitos links +$ EPIPE +32 pipe quebrado +$ EDOM +33 Argumento num�rico fora do dom�nio +$ ERANGE +34 Resultado muito grande +$ EAGAIN, EWOULDBLOCK +35 Recurso temporariamente indispon�vel +$ EINPROGRESS +36 Opera��o em progresso agora +$ EALREADY +37 Opera��o em progresso pronta +$ ENOTSOCK +38 Opera��o de socket em um n�o-socket +$ EDESTADDRREQ +39 Endere�o de destino requerido +$ EMSGSIZE +40 Mensagem muito grande +$ EPROTOTYPE +41 Tipo de protocolo errado para socket +$ ENOPROTOOPT +42 Protocolo n�o dispon�vel +$ EPROTONOSUPPORT +43 Protocolo n�o suportado +$ ESOCKTNOSUPPORT +44 Tipo de socket n�o suportado +$ EOPNOTSUPP +45 Opera��o n�o permitida +$ EPFNOSUPPORT +46 Fam�lia de protocolo n�o suportada +$ EAFNOSUPPORT +47 Fam�lia de endere�os n�o suportada pela fam�lia de protocolos +$ EADDRINUSE +48 Endere�o j� est� em uso +$ EADDRNOTAVAIL +49 Imposs�vel obter endere�o solicitado +$ ENETDOWN +50 Rede est� parada +$ ENETUNREACH +51 Rede est� inalcan��vel +$ ENETRESET +52 Conex�o de rede perdida durante reset +$ ECONNABORTED +53 Conex�o abortada por software +$ ECONNRESET +54 Conex�o reiniciada pelo outro ponto +$ ENOBUFS +55 Sem espa�o de buffer dispon�vel +$ EISCONN +56 Socket j� est� conectado +$ ENOTCONN +57 Socket n�o est� conectado +$ ESHUTDOWN +58 Imposs�vel enviar depois que o socket foi finalizado +$ ETOOMANYREFS +59 Muitas refer�ncias: imposs�vel ligar +$ ETIMEDOUT +60 Tempo de opera��o expirou +$ ECONNREFUSED +61 Conex�o recusada +$ ELOOP +62 Muitos n�veis de links simb�licos +$ ENAMETOOLONG +63 Nome de arquivo muito grande +$ EHOSTDOWN +64 Host est� desligado +$ EHOSTUNREACH +65 Sem rota para o host +$ ENOTEMPTY +66 Diret�rio n�o est� vazio +$ EPROCLIM +67 Muitos processos +$ EUSERS +68 Muitos usu�rios +$ EDQUOT +69 Quota de disco excedida +$ ESTALE +70 Manipulador de arquivo NFS velho +$ EREMOTE +71 Muitos n�veis no caminho remoto +$ EBADRPC +72 Estrutura RPC incorreta +$ ERPCMISMATCH +73 Vers�o RPC incorreta +$ EPROGUNAVAIL +74 Programa RPC indispon�vel +$ EPROGMISMATCH +75 Vers�o do programa incorreta +$ EPROCUNAVAIL +76 Procedimento incorreto para o programa +$ ENOLCK +77 Nenhum lock dispon�vel +$ ENOSYS +78 Fun��o n�o implementada +$ EFTYPE +79 Tipo de arquivo ou formato inapropriados +$ EAUTH +80 Erro de autentica��o +$ ENEEDAUTH +81 Necessidade de autenticador +$ EIDRM +82 Identificador removido +$ ENOMSG +83 Nenhuma mensagem do tipo desejado +$ EOVERFLOW +84 Valor muito grande para ser armazenado neste tipo de dado +$ ECANCELED +85 Opera��o cancelada +$ EILSEQ +86 Sequ�ncia de bytes ilegal +$ ENOATTR +87 Atributo n�o encontrado +$ EDOOFUS +88 Erro de programa��o +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Fim da linha (Hangup) +$ SIGINT +2 Interrup��o +$ SIGQUIT +3 Sa�da +$ SIGILL +4 Instru��o ilegal +$ SIGTRAP +5 Trap de Trace/BPT +$ SIGABRT +6 Abortar trap +$ SIGEMT +7 EMT trap +$ SIGFPE +8 Exce��o de ponto flutuante +$ SIGKILL +9 Morreu +$ SIGBUS +10 Erro de barramento +$ SIGSEGV +11 Falha de segmenta��o +$ SIGSYS +12 Chamada de sistema incorreta +$ SIGPIPE +13 Pipe incorreto +$ SIGALRM +14 Alarme do rel�gio +$ SIGTERM +15 Terminado +$ SIGURG +16 Condi��o urgente de E/S +$ SIGSTOP +17 Suspendido (sinal) +$ SIGTSTP +18 Suspendido +$ SIGCONT +19 Continuado +$ SIGCHLD +20 Filho saiu +$ SIGTTIN +21 Parado (entrada de tty) +$ SIGTTOU +22 Parado (sa�da de tty) +$ SIGIO +23 E/S poss�vel +$ SIGXCPU +24 Limite de tempo de CPU excedido +$ SIGXFSZ +25 Tamanho de arquivo excedido +$ SIGVTALRM +26 Temporizador virtual expirou +$ SIGPROF +27 Temporizador de profiling expirou +$ SIGWINCH +28 Mudan�a no tamanho de janela +$ SIGINFO +29 Requisi��o de informa��o +$ SIGUSR1 +30 Sinal 1 definido pelo usu�rio +$ SIGUSR2 +31 Sinal 2 definido pelo usu�rio diff --git a/lib/libc/nls/sk_SK.ISO8859-2.msg b/lib/libc/nls/sk_SK.ISO8859-2.msg new file mode 100644 index 0000000..bcec96a --- /dev/null +++ b/lib/libc/nls/sk_SK.ISO8859-2.msg @@ -0,0 +1,267 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/sk_SK.ISO8859-2.msg 189765 2009-03-13 10:40:38Z gabor $ +$ +$ Message catalog for sk_SK.ISO8859-2 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Oper�cia nie je povolen� +$ ENOENT +2 Neexistuj�ci s�bor alebo adres�r +$ ESRCH +3 Proces neexistuje +$ EINTR +4 Syst�mov� volanie preru�en� +$ EIO +5 Chyba vstupu/v�stupu +$ ENXIO +6 Zariadenie nie je nakonfigurovan� +$ E2BIG +7 Pr�li� dlh� zoznam argumentov +$ ENOEXEC +8 Chybn� form�t spusten�ho s�boru +$ EBADF +9 Chybn� deskriptor s�boru +$ ECHILD +10 Neexistuje �iaden potomok procesu +$ EDEADLK +11 Bolo zabr�nen� zablokovaniu prostriedku +$ ENOMEM +12 Nie je mo�n� prideli� pam� +$ EACCES +13 Pr�stup odmietnut� +$ EFAULT +14 Chybn� adresa +$ ENOTBLK +15 Vy�adovan� blokov� zariadenie +$ EBUSY +16 Zariadenie je pou��van� +$ EEXIST +17 S�bor existuje +$ EXDEV +18 Odkaz medzi zariadeniami +$ ENODEV +19 Oper�cia nie je zariaden�m podporovan� +$ ENOTDIR +20 Nie je adres�r +$ EISDIR +21 Je adres�r +$ EINVAL +22 Chybn� argument +$ ENFILE +23 Prive�a otvoren�ch s�borov v syst�me +$ EMFILE +24 Prive�a otvoren�ch s�borov +$ ENOTTY +25 Nevhodn� ioctl pre dan� zariadenie +$ ETXTBSY +26 Textov� s�bor je pou��van� +$ EFBIG +27 S�bor je pr�li� ve�k� +$ ENOSPC +28 Na zariaden� nie je vo�n� miesto +$ ESPIPE +29 Nepr�pustn� nastavenie poz�cie +$ EROFS +30 S�borov� syst�m je len na ��tanie +$ EMLINK +31 Prive�a odkazov +$ EPIPE +32 Preru�en� r�ra +$ EDOM +33 ��seln� argument mimo defini�n� obor +$ ERANGE +34 V�sledok pr�li� ve�k� alebo pr�li� mal� +$ EAGAIN, EWOULDBLOCK +35 Zdroj je do�asne nedostupn� +$ EINPROGRESS +36 Oper�cia pr�ve prebieha +$ EALREADY +37 Oper�cia u� prebieha +$ ENOTSOCK +38 Socketov� oper�cia na objekte, ktor� nie je socket +$ EDESTADDRREQ +39 Vy�adovan� cie�ov� adresa +$ EMSGSIZE +40 Pr�li� dlh� spr�va +$ EPROTOTYPE +41 Protokol nie je socketom podporovan� +$ ENOPROTOOPT +42 Protokol nie je k dispoz�cii +$ EPROTONOSUPPORT +43 Protokol nie je podporovan� +$ ESOCKTNOSUPPORT +44 Typ socketu nie je podporovan� +$ EOPNOTSUPP +45 Oper�cia nie je podporovan� +$ EPFNOSUPPORT +46 Rodina protokolov nie je podporovan� +$ EAFNOSUPPORT +47 Rodina adries nie je podporovan� rodinou protokolov +$ EADDRINUSE +48 Adresa je u� pou��van� +$ EADDRNOTAVAIL +49 Nie je mo�n� prideli� po�adovan� adresu +$ ENETDOWN +50 Sie� je nefunk�n� +$ ENETUNREACH +51 Sie� je nedostupn� +$ ENETRESET +52 Sie� zru�ila spojenie po resete +$ ECONNABORTED +53 Program sp�sobil ukon�enie spojenia +$ ECONNRESET +54 Spojenie zru�en� druhou stranou +$ ENOBUFS +55 Vyrovn�vacia pam� nie je k dispoz�cii +$ EISCONN +56 Socket je u� pripojen� +$ ENOTCONN +57 Socket nie je pripojen� +$ ESHUTDOWN +58 Nie je mo�n� posiela� po uzavret� socketu +$ ETOOMANYREFS +59 Pr�li� mnoho odkazov: nie je mo�n� spoji� +$ ETIMEDOUT +60 �asov� limit pre spojenie vypr�al +$ ECONNREFUSED +61 Spojenie odmietnut� +$ ELOOP +62 Prive�a �rovn� symbolick�ch odkazov +$ ENAMETOOLONG +63 Meno s�boru pr�li� dlh� +$ EHOSTDOWN +64 Vzdialen� uzol je odpojen� +$ EHOSTUNREACH +65 Neexistuje cesta k vzdialen�mu uzlu +$ ENOTEMPTY +66 Adres�r nie je pr�zdny +$ EPROCLIM +67 Prive�a procesov +$ EUSERS +68 Prive�a pou��vate�ov +$ EDQUOT +69 Diskov� kv�ta prekro�en� +$ ESTALE +70 Zastaral� NFS s�borov� ukazate� +$ EREMOTE +71 Prive�a �rovn� vzdialen�ho v ceste +$ EBADRPC +72 RPC �trukt�ra je chybn� +$ ERPCMISMATCH +73 Chybn� verzia RPC +$ EPROGUNAVAIL +74 RPC program nie je k dispoz�cii +$ EPROGMISMATCH +75 Chybn� verzia RPC programu +$ EPROCUNAVAIL +76 Chybn� RPC proced�ra pre program +$ ENOLCK +77 Z�mky nie s� k dispoz�cii +$ ENOSYS +78 Funkcia nie je implementovan� +$ EFTYPE +79 Nevhodn� typ alebo form�t s�boru +$ EAUTH +80 Overenie pr�v ne�spe�n� +$ ENEEDAUTH +81 Vy�adovan� overovac� objekt +$ EIDRM +82 Identifik�tor odstr�nen� +$ ENOMSG +83 Neexistuje spr�va �elan�ho typu +$ EOVERFLOW +84 Hodnota je pre dan� d�tov� typ prive�k� +$ EILSEQ +85 Nepr�pustn� postupnos� bajtov +$ ENOTSUP +86 Nie je podporovan� +$ ECANCELED +87 Oper�cia zru�en� +$ EBADMSG +88 Chybn� alebo poru�en� spr�va +$ ENODATA +89 �iadna spr�va nie je k dispoz�cii +$ ENOSR +90 �iadne STREAM zdroje +$ ENOSTR +91 Nie je STREAM +$ ETIME +92 �asov� limit pre STREAM ioctl vypr�al +$ ENOATTR +93 Atrib�t nen�jden� +$ EMULTIHOP +94 Pokus o spojenie cez viacero uzlov +$ ENOLINK +95 Odkaz bol pretrhnut� +$ EPROTO +96 Chyba protokolu +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Termin�l odpojen� +$ SIGINT +2 Preru�enie +$ SIGQUIT +3 Koniec +$ SIGILL +4 Chybn� in�trukcia +$ SIGTRAP +5 Trasovacia/ladiaca in�trukcia +$ SIGABRT +6 N�siln� ukon�enie +$ SIGEMT +7 Emulovan� in�trukcia +$ SIGFPE +8 V�nimka pohyblivej r�dovej �iarky +$ SIGKILL +9 Zabit� +$ SIGBUS +10 Chyba na zbernici +$ SIGSEGV +11 Chyba segment�cie +$ SIGSYS +12 Chybn� syst�mov� volanie +$ SIGPIPE +13 Preru�en� r�ra +$ SIGALRM +14 Bud�k +$ SIGTERM +15 Ukon�en� +$ SIGURG +16 Naliehav� vstupn�/v�stupn� stav +$ SIGSTOP +17 Pozastaven� (sign�l) +$ SIGTSTP +18 Pozastaven� +$ SIGCONT +19 Pokra�ovanie +$ SIGCHLD +20 Potomok procesu ukon�en� +$ SIGTTIN +21 Pozastaven� (termin�lov� vstup) +$ SIGTTOU +22 Pozastaven� (termin�lov� v�stup) +$ SIGIO +23 Vstup/v�stup mo�n� +$ SIGXCPU +24 Prekro�en� �asov� limit pre procesor +$ SIGXFSZ +25 Prekro�en� limit ve�kosti s�boru +$ SIGVTALRM +26 Vypr�al virtu�lny �asova� +$ SIGPROF +27 Vypr�al profilovac� �asova� +$ SIGWINCH +28 Ve�kos� okna zmenen� +$ SIGINFO +29 �iados� o inform�ciu +$ SIGUSR1 +30 Pou��vate�om definovan� sign�l 1 +$ SIGUSR2 +31 Pou��vate�om definovan� sign�l 2 +$ SIGPWR +32 Zlyhanie/opakovan� spustenie nap�jania diff --git a/lib/libc/nls/sv_SE.ISO8859-1.msg b/lib/libc/nls/sv_SE.ISO8859-1.msg new file mode 100644 index 0000000..92c8ec2 --- /dev/null +++ b/lib/libc/nls/sv_SE.ISO8859-1.msg @@ -0,0 +1,233 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/sv_SE.ISO8859-1.msg 189765 2009-03-13 10:40:38Z gabor $ +$ +$ Message catalog for sv_SE.ISO8859-1 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Otill�ten operation +$ ENOENT +2 Filen eller katalogen finns ej +$ ESRCH +3 Denna process finns ej +$ EINTR +4 Avbrutet systemanrop +$ EIO +5 In-/utmatningsfel +$ ENXIO +6 Enheten �r ej konfigurerad +$ E2BIG +7 Argumentlistan �r f�r l�ng +$ ENOEXEC +8 Ej k�rbar fil +$ EBADF +9 Felaktigt filhandtag +$ ECHILD +10 Inga barnprocesser +$ EDEADLK +11 Undvek resursd�dl�ge +$ ENOMEM +12 Kan ej erh�lla minne +$ EACCES +13 Tillst�nd nekas +$ EFAULT +14 Felaktig adress +$ ENOTBLK +15 Blockenhet kr�vs +$ EBUSY +16 Enheten �r upptagen +$ EEXIST +17 Filen finns redan +$ EXDEV +18 L�nken korsar enheter +$ ENODEV +19 Enheten st�der ej operationen +$ ENOTDIR +20 �r ej en katalog +$ EISDIR +21 �r en katalog +$ EINVAL +22 Ogiltigt argument +$ ENFILE +23 F�r m�nga �ppna filer i systemet +$ EMFILE +24 F�r m�nga �ppna filer +$ ENOTTY +25 Ol�mplig ioctl f�r enheten +$ ETXTBSY +26 Programfilen �r upptagen +$ EFBIG +27 Filen �r f�r stor +$ ENOSPC +28 Inget utrymme kvar p� enheten +$ ESPIPE +29 Otill�ten s�kning +$ EROFS +30 Skrivskyddat filsystem +$ EMLINK +31 F�r m�nga l�nkar +$ EPIPE +32 Avbruten kommunikationskanal +$ EDOM +33 Numeriskt argument utanf�r dom�nen +$ ERANGE +34 Resultatet �r f�r stort +$ EAGAIN, EWOULDBLOCK +35 Resursen �r tillf�lligt otillg�nglig +$ EINPROGRESS +36 Operationen �r ig�ng +$ EALREADY +37 Operationen �r redan ig�ng +$ ENOTSOCK +38 Sockeloperation p� icke-sockel +$ EDESTADDRREQ +39 Destinationsadress erfordras +$ EMSGSIZE +40 F�r l�ngt meddelande +$ EPROTOTYPE +41 Fel protokolltyp f�r sockeln +$ ENOPROTOOPT +42 Protokollet otillg�ngligt +$ EPROTONOSUPPORT +43 Protokollet �r ej underst�tt +$ ESOCKTNOSUPPORT +44 Sockeltypen �r ej underst�dd +$ EOPNOTSUPP +45 Operationen �r ej underst�dd +$ EPFNOSUPPORT +46 Protokollfamiljen �r ej underst�dd +$ EAFNOSUPPORT +47 Adressfamiljen �r ej underst�dd av protokollfamiljen +$ EADDRINUSE +48 Adressen �r upptagen +$ EADDRNOTAVAIL +49 Kan ej tilldela den beg�rda adressen +$ ENETDOWN +50 N�tverket fungerar inte +$ ENETUNREACH +51 N�tverket �r ej kontaktbart +$ ENETRESET +52 N�tverket tappade kontakten vid �terst�llningen +$ ECONNABORTED +53 Mjukvara orsakade nedkoppling +$ ECONNRESET +54 Motparten avbr�t uppkopplingen +$ ENOBUFS +55 Inget buffertutrymme tillg�ngligt +$ EISCONN +56 Sockeln �r redan uppkopplad +$ ENOTCONN +57 Sockeln �r ej uppkopplad +$ ESHUTDOWN +58 Kan ej s�nda efter att sockeln nedkopplats +$ ETOOMANYREFS +59 F�r m�nga referenser: kan inte delas +$ ETIMEDOUT +60 Uppkopplingstiden tog slut +$ ECONNREFUSED +61 Uppkopplingen nekad +$ ELOOP +62 F�r m�nga niv�er av symboliska l�nkar +$ ENAMETOOLONG +63 Alldeles f�r l�ngt filnamn +$ EHOSTDOWN +64 V�rddatorn �r nere +$ EHOSTUNREACH +65 V�g till v�rddatorn saknas +$ ENOTEMPTY +66 Katalogen ej tom +$ EPROCLIM +67 F�r m�nga processer +$ EUSERS +68 F�r m�nga anv�ndare +$ EDQUOT +69 Diskkvot �verskriden +$ ESTALE +70 Inaktuellt NFS-filhandtag +$ EREMOTE +71 F�r m�nga fj�rrniv�er i s�kv�gen +$ EBADRPC +72 Felaktig RPC-struktur +$ ERPCMISMATCH +73 Felaktig RPC-version +$ EPROGUNAVAIL +74 RPC-programmet otillg�ngligt +$ EPROGMISMATCH +75 Fel programversion +$ EPROCUNAVAIL +76 Felaktig procedur f�r programmet +$ ENOLCK +77 Inga l�s tillg�ngliga +$ ENOSYS +78 Funktionen �r ej implementerad +$ EFTYPE +79 Ol�mplig filtyp eller format +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 L�gg p� +$ SIGINT +2 Avbryt +$ SIGQUIT +3 Avsluta +$ SIGILL +4 Olaglig instruktion +$ SIGTRAP +5 Sp�r- eller brytpunktsf�lla +$ SIGABRT +6 Avslutsf�lla +$ SIGEMT +7 Emuleringsf�lla +$ SIGFPE +8 Flyttalsavbrott +$ SIGKILL +9 Dr�pt +$ SIGBUS +10 Bussfel +$ SIGSEGV +11 Segmentfel +$ SIGSYS +12 Felaktigt systemanrop +$ SIGPIPE +13 Avbruten kommunikationskanal +$ SIGALRM +14 �ggklocka +$ SIGTERM +15 Terminerad +$ SIGURG +16 Br�dskande In/Ut-tillst�nd +$ SIGSTOP +17 Stoppad (signal) +$ SIGTSTP +18 Stoppad +$ SIGCONT +19 Forts�tter +$ SIGCHLD +20 Barn avslutat +$ SIGTTIN +21 Stoppad (terminalinmatning) +$ SIGTTOU +22 Stoppad (terminalutmatning) +$ SIGIO +23 In- och utmatning m�jlig +$ SIGXCPU +24 Cputidsgr�nsen �verskriden +$ SIGXFSZ +25 Filstorleksgr�nsen �verskriden +$ SIGVTALRM +26 Virtuella �ggklockan ringde +$ SIGPROF +27 Profilerings�ggklockan ringde +$ SIGWINCH +28 F�nsterstorleken �ndras +$ SIGINFO +29 Informationsf�rfr�gan +$ SIGUSR1 +30 Anv�ndardefinierad signal 1 +$ SIGUSR2 +31 Anv�ndardefinierad signal 2 +$ SIGPWR +32 Kraftbortfall/omstart diff --git a/lib/libc/nls/uk_UA.UTF-8.msg b/lib/libc/nls/uk_UA.UTF-8.msg new file mode 100644 index 0000000..f0180a1 --- /dev/null +++ b/lib/libc/nls/uk_UA.UTF-8.msg @@ -0,0 +1,259 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/uk_UA.UTF-8.msg 199044 2009-11-08 11:55:03Z gabor $ +$ +$ Message catalog for uk_UA.UTF-8 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 Операція не дозволена +$ ENOENT +2 Немає такого файлу або каталогу +$ ESRCH +3 Немає такого процесу +$ EINTR +4 Перервано виклик функції +$ EIO +5 Помилка вводу-виводу +$ ENXIO +6 Немає такого пристрою або адреси +$ E2BIG +7 Перелік аргументів надто довгий +$ ENOEXEC +8 Помилка формату виконуваного файлу +$ EBADF +9 Невірний дескриптор файлу +$ ECHILD +10 Немає дочірнього процесу +$ EDEADLK +11 Уникнуто взаємне блокування ресурсів +$ ENOMEM +12 Не достатньо пам'яті +$ EACCES +13 Відмова у доступі +$ EFAULT +14 Невірна адреса +$ ENOTBLK +15 Потрібен блочний пристрій +$ EBUSY +16 Ресурс зайнятий +$ EEXIST +17 Файл вже існує +$ EXDEV +18 Посилання за межі пристрою +$ ENODEV +19 Немає такого пристрою +$ ENOTDIR +20 Це не каталог +$ EISDIR +21 Це каталог +$ EINVAL +22 Недозволений аргумент +$ ENFILE +23 Забагато відкритих файлів у системі +$ EMFILE +24 Забагато відкритих файлів +$ ENOTTY +25 Це не термінал +$ ETXTBSY +26 Текстовий файл зайнятий +$ EFBIG +27 Файл надто великий +$ ENOSPC +28 Не залишилось місця на пристрої +$ ESPIPE +29 Недозволене позиціонування +$ EROFS +30 Файлова система лише для читання +$ EMLINK +31 Забагато посилань +$ EPIPE +32 Канал зруйновано +$ EDOM +33 Помилка області визначення +$ ERANGE +34 Результат надто великий +$ EAGAIN, EWOULDBLOCK +35 Ресурс тимчасово не доступний +$ EINPROGRESS +36 Операція у процесі виконання +$ EALREADY +37 Операція вже виконується +$ ENOTSOCK +38 Це не сокет +$ EDESTADDRREQ +39 Необхідна адреса призначення +$ EMSGSIZE +40 Повідомлення надто довге +$ EPROTOTYPE +41 Помилковий тип протоколу для сокету +$ ENOPROTOOPT +42 Немає такого протоколу +$ EPROTONOSUPPORT +43 Протокол не підтримується +$ ESOCKTNOSUPPORT +44 Цей тип сокету не підтримується +$ EOPNOTSUPP +45 Операція не підтримується +$ EPFNOSUPPORT +46 Родина протоколів не підтримується +$ EAFNOSUPPORT +47 Родина адрес не підтримується протоколом +$ EADDRINUSE +48 Адреса вже використовується +$ EADDRNOTAVAIL +49 Адреса недосяжна +$ ENETDOWN +50 Мережа не працює +$ ENETUNREACH +51 Мережа недосяжна +$ ENETRESET +52 З'єднання припинено мережею +$ ECONNABORTED +53 З'єднання припинено +$ ECONNRESET +54 З'єднання припинено протилежною стороною +$ ENOBUFS +55 Немає вільних буферів +$ EISCONN +56 Сокет вже під'єднано +$ ENOTCONN +57 Сокет не під'єднано +$ ESHUTDOWN +58 Не можу відіслати після закриття сокету протилежною стороною +$ ETOOMANYREFS +59 Забагато посилань: не можу з'єднати +$ ETIMEDOUT +60 Вийшов ліміт часу для з'єднання +$ ECONNREFUSED +61 Відмова у з'єднанні +$ ELOOP +62 Забагато рівнів символічних посилань +$ ENAMETOOLONG +63 Ім'я файлу надто довге +$ EHOSTDOWN +64 Хост не працює +$ EHOSTUNREACH +65 Хост недосяжний +$ ENOTEMPTY +66 Каталог не порожній +$ EPROCLIM +67 Забагато процесів +$ EUSERS +68 Забагато користувачів +$ EDQUOT +69 Перевищена дискова квота +$ ESTALE +70 Застарілий дескриптор файлу NFS +$ EREMOTE +71 Віддалений об'єкт +$ EBADRPC +72 Погана структура RPC +$ ERPCMISMATCH +73 Невірна версія RPC +$ EPROGUNAVAIL +74 Програма RPC недосяжна +$ EPROGMISMATCH +75 Невірна версія програми +$ EPROCUNAVAIL +76 Погана процедура для програми +$ ENOLCK +77 Блокування не доступне +$ ENOSYS +78 Функцію не реалізовано +$ EFTYPE +79 Непридатний тип чи формат файлу +$ EAUTH +80 Помилка аутентифікації +$ ENEEDAUTH +81 Потрібна аутентифікація +$ EIDRM +82 Ідентифікатор вилучено +$ ENOMSG +83 Немає повідомлення бажаного типу +$ EOVERFLOW +84 Завелике значення для цього типу даних +$ ECANCELED +85 Операцію скасовано +$ EILSEQ +86 Недозволена послідовність байтів +$ ENOATTR +87 Атрибут не знайдено +$ EDOOFUS +88 Помилка програмування +$ EBADMSG +89 Поганий формат повідомлення +$ EMULTIHOP XXX +90 Спроба мултіхопу +$ ENOLINK +91 Мережовий канал розірвано +$ EPROTO +92 Помилка протоколу +$ ENOTCAPABLE +93 Можливості недостатні +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 Відключення +$ SIGINT +2 Переривання +$ SIGQUIT +3 Вихід +$ SIGILL +4 Неприпустима інструкція +$ SIGTRAP +5 Пастка трасування +$ SIGABRT +6 Аварійне завершення +$ SIGEMT +7 Перехоплення емульованої інструкції +$ SIGFPE +8 Помилка роботи з плаваючою крапкою +$ SIGKILL +9 Вбито +$ SIGBUS +10 Помилка шини +$ SIGSEGV +11 Порушення сегментації +$ SIGSYS +12 Поганий системний виклик +$ SIGPIPE +13 Канал зруйновано +$ SIGALRM +14 Таймер вичерпано +$ SIGTERM +15 Завершення +$ SIGURG +16 Невідкладний стан на сокеті +$ SIGSTOP +17 Призупинено (сигнал) +$ SIGTSTP +18 Призупинено +$ SIGCONT +19 Продовження роботи +$ SIGCHLD +20 Зміна статусу дочірнього процесу +$ SIGTTIN +21 Зупинено (ввід з терміналу) +$ SIGTTOU +22 Зупинено (вивід на термінал) +$ SIGIO +23 Ввід-вивід можливий +$ SIGXCPU +24 Перевищено ліміт процесорного часу +$ SIGXFSZ +25 Перевищено ліміт максимального розміру файла +$ SIGVTALRM +26 Віртуальний таймер вичерпано +$ SIGPROF +27 Таймер профілювання вичерпано +$ SIGWINCH +28 Розмір вікна змінено +$ SIGINFO +29 Запит інформації +$ SIGUSR1 +30 Сигнал користувача 1 +$ SIGUSR2 +31 Сигнал користувача 2 diff --git a/lib/libc/nls/zh_CN.GB18030.msg b/lib/libc/nls/zh_CN.GB18030.msg new file mode 100644 index 0000000..2b3beb0 --- /dev/null +++ b/lib/libc/nls/zh_CN.GB18030.msg @@ -0,0 +1,297 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/zh_CN.GB18030.msg 244757 2012-12-28 01:23:12Z delphij $ +$ +$ Message catalog for zh_CN.GB18030 locale +$ +$ Derived from FreeBSD: head/lib/libc/nls/zh_CN.UTF-8.msg 244756 2012-12-28 01:09:30Z delphij +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 ������IJ��� +$ ENOENT +2 �ļ���Ŀ¼������ +$ ESRCH +3 ���̲����� +$ EINTR +4 ϵͳ������ֹ +$ EIO +5 ����/������� +$ ENXIO +6 δ���õ��豸 +$ E2BIG +7 ��������� +$ ENOEXEC +8 ��ִ���ļ���ʽ���� +$ EBADF +9 �ļ���������Ч +$ ECHILD +10 ָ���ӽ��̲����� +$ EDEADLK +11 �˲����ᵼ������ +$ ENOMEM +12 �޷������ڴ� +$ EACCES +13 �ܾ����� +$ EFAULT +14 ��Ч��ַ +$ ENOTBLK +15 �ò�����Ҫ���豸 +$ EBUSY +16 �豸ʹ���� +$ EEXIST +17 �ļ��Ѵ��� +$ EXDEV +18 ���ӿ��豸 +$ ENODEV +19 �豸��֧�ִ˲��� +$ ENOTDIR +20 �����Ŀ¼ +$ EISDIR +21 ����ΪĿ¼ +$ EINVAL +22 ������Ч +$ ENFILE +23 ϵͳ���ļ����� +$ EMFILE +24 ���̴��ļ����� +$ ENOTTY +25 ��Ч�豸 ioctl +$ ETXTBSY +26 ��ִ���ļ�æ +$ EFBIG +27 �ļ����� +$ ENOSPC +28 �豸�޿��ÿռ� +$ ESPIPE +29 ������ִ�� seek ���� +$ EROFS +30 �ļ�ϵͳֻ�� +$ EMLINK +31 �ļ����ӹ��� +$ EPIPE +32 �ܵ�����ֹ +$ EDOM +33 ��ֵ����Խ�� +$ ERANGE +34 ������� +$ EAGAIN, EWOULDBLOCK +35 ��Դ��ʱ������ +$ EINPROGRESS +36 ���������� +$ EALREADY +37 �����ѿ�ʼ +$ ENOTSOCK +38 �����ڷ� socket ��ִ�� socket ���� +$ EDESTADDRREQ +39 ��ҪĿ�ĵ�ַ +$ EMSGSIZE +40 ��Ϣ���� +$ EPROTOTYPE +41 socketЭ�����ʹ��� +$ ENOPROTOOPT +42 Э�鲻���� +$ EPROTONOSUPPORT +43 ��֧�ֵ�Э�� +$ ESOCKTNOSUPPORT +44 ��֧�ֵ� socket ���� +$ EOPNOTSUPP +45 ��֧�ֵIJ��� +$ EPFNOSUPPORT +46 ��֧�ֵ�Э���� +$ EAFNOSUPPORT +47 Э���岻֧�ֵĵ�ַ�� +$ EADDRINUSE +48 ��ַ�ѱ�ռ�� +$ EADDRNOTAVAIL +49 �޷�ָ������ĵ�ַ +$ ENETDOWN +50 �����ѹر� +$ ENETUNREACH +51 ���粻�ɴ� +$ ENETRESET +52 ��λ�����������Ӷ�ʧ +$ ECONNABORTED +53 ������µ�������ֹ +$ ECONNRESET +54 �Է���λ������ +$ ENOBUFS +55 �������ռ䲻�� +$ EISCONN +56 socket ������ +$ ENOTCONN +57 socket δ���� +$ ESHUTDOWN +58 socket shutdown ֮���޷��������� +$ ETOOMANYREFS +59 ���������ࣺ�޷�ƴ�� +$ ETIMEDOUT +60 ������ʱ +$ ECONNREFUSED +61 �ܾ����� +$ ELOOP +62 �������Ӳ������� +$ ENAMETOOLONG +63 �ļ������� +$ EHOSTDOWN +64 �����ѹر� +$ EHOSTUNREACH +65 û�е�������·�� +$ ENOTEMPTY +66 Ŀ¼�ǿ� +$ EPROCLIM +67 ���������� +$ EUSERS +68 �û������� +$ EDQUOT +69 ���̿ռ����� +$ ESTALE +70 NFS �ļ������ʧЧ +$ EREMOTE +71 Զ��Ŀ¼�������� +$ EBADRPC +72 RPC �ṹ��Ч +$ ERPCMISMATCH +73 RPC �汾���� +$ EPROGUNAVAIL +74 RPC ���򲻿��� +$ EPROGMISMATCH +75 ����汾���� +$ EPROCUNAVAIL +76 δ�ṩ��Զ�̺��� +$ ENOLCK +77 ��֧���� +$ ENOSYS +78 ����δʵ�� +$ EFTYPE +79 �ļ����ͻ��ʽ��Ч +$ EAUTH +80 �����Ч +$ ENEEDAUTH +81 ������ƾ�� +$ EIDRM +82 �ޱ�ʶ�� +$ ENOMSG +83 ����Ϣ���� +$ EOVERFLOW +84 ��ֵ��� +$ ECANCELED +85 ������ȡ�� +$ EILSEQ +86 ��Ч�ַ����� +$ ENOATTR +87 ����չ���� +$ EDOOFUS +88 ������ƴ��� +$ EBADMSG +89 ��Ч��Ϣ +$ EMULTIHOP +90 Multihop attempted +$ ENOLINK +91 Link has been severed +$ EPROTO +92 Э����� +$ ENOTCAPABLE +93 Ȩ�ܲ��� +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 �ն���·�Ҷ� +$ SIGINT +2 �ж� +$ SIGQUIT +3 �˳� +$ SIGILL +4 ��Чָ�� +$ SIGTRAP +5 ����/BPT ���� +$ SIGABRT +6 ��ֹ���� +$ SIGEMT +7 EMT ���� +$ SIGFPE +8 �����쳣 +$ SIGKILL +9 ǿ����ֹ���� +$ SIGBUS +10 ϵͳ�ڴ����Խ�� +$ SIGSEGV +11 �ڴ����Խ�� +$ SIGSYS +12 ��Чϵͳ���� +$ SIGPIPE +13 д�ܵ�ʱ��ȡ�߲����� +$ SIGALRM +14 ʵʱ����ʱ���� +$ SIGTERM +15 ��ֹ +$ SIGURG +16 ����������� I/O ����״�� +$ SIGSTOP +17 ���� (�ź�) +$ SIGTSTP +18 ���� +$ SIGCONT +19 �������� +$ SIGCHLD +20 �ӽ�����ֹ +$ SIGTTIN +21 TTY �������� +$ SIGTTOU +22 TTY ������� +$ SIGIO +23 I/O ���� +$ SIGXCPU +24 CPU ʹ��ʱ����� +$ SIGXFSZ +25 �ļ��ߴ���� +$ SIGVTALRM +26 ���⵹��ʱ���� +$ SIGPROF +27 ��������ʱ���� +$ SIGWINCH +28 ���ڳߴ�仯 +$ SIGINFO +29 ������Ϣ +$ SIGUSR1 +30 �û��Զ����ź� 1 +$ SIGUSR2 +31 �û��Զ����ź� 2 +$ +$ gai_strerror() support catalog +$ +$set 3 +$ 1 (obsolete) +1 ������ʹ���˲�֧�ֵĵ�ַ���� +$ EAI_AGAIN +2 ��ʱ�޷��������� +$ EAI_BADFLAGS +3 ��Ч�� ai_flags ֵ +$ EAI_FAIL +4 ��������ʱ�����޷��ָ��Ĵ��� +$ EAI_FAMILY +5 ��֧�ֵĵ�ַ��Ϣ���� +$ EAI_MEMORY +6 �ڴ����ʧ�� +$ 7 (obsolete) +7 ��������������ĵ�ַ +$ EAI_NONAME +8 δ֪��������������� +$ EAI_SERVICE +9 �׽������Ͳ�֧�ִ˷����� +$ EAI_SOCKTYPE +10 ��֧�ֵ��׽������� +$ EAI_SYSTEM +11 ϵͳ���÷����� errno ���� +$ EAI_BADHINTS +12 ��Ч��ʾ���� +$ EAI_PROTOCOL +13 δ֪Э�� +$ EAI_OVERFLOW +14 ����������� +$ 0 +32766 �ɹ� +$ NL_MSGMAX +32767 δ֪���� diff --git a/lib/libc/nls/zh_CN.GB2312.msg b/lib/libc/nls/zh_CN.GB2312.msg new file mode 100644 index 0000000..2a7d62c --- /dev/null +++ b/lib/libc/nls/zh_CN.GB2312.msg @@ -0,0 +1,297 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/zh_CN.GB2312.msg 244757 2012-12-28 01:23:12Z delphij $ +$ +$ Message catalog for zh_CN.GB2312 locale +$ +$ Derived from FreeBSD: head/lib/libc/nls/zh_CN.UTF-8.msg 244756 2012-12-28 01:09:30Z delphij +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 ������IJ��� +$ ENOENT +2 �ļ���Ŀ¼������ +$ ESRCH +3 ���̲����� +$ EINTR +4 ϵͳ������ֹ +$ EIO +5 ����/������� +$ ENXIO +6 δ���õ��豸 +$ E2BIG +7 ��������� +$ ENOEXEC +8 ��ִ���ļ���ʽ���� +$ EBADF +9 �ļ���������Ч +$ ECHILD +10 ָ���ӽ��̲����� +$ EDEADLK +11 �˲����ᵼ������ +$ ENOMEM +12 �޷������ڴ� +$ EACCES +13 �ܾ����� +$ EFAULT +14 ��Ч��ַ +$ ENOTBLK +15 �ò�����Ҫ���豸 +$ EBUSY +16 �豸ʹ���� +$ EEXIST +17 �ļ��Ѵ��� +$ EXDEV +18 ���ӿ��豸 +$ ENODEV +19 �豸��֧�ִ˲��� +$ ENOTDIR +20 �����Ŀ¼ +$ EISDIR +21 ����ΪĿ¼ +$ EINVAL +22 ������Ч +$ ENFILE +23 ϵͳ���ļ����� +$ EMFILE +24 ���̴��ļ����� +$ ENOTTY +25 ��Ч�豸 ioctl +$ ETXTBSY +26 ��ִ���ļ�æ +$ EFBIG +27 �ļ����� +$ ENOSPC +28 �豸�޿��ÿռ� +$ ESPIPE +29 ������ִ�� seek ���� +$ EROFS +30 �ļ�ϵͳֻ�� +$ EMLINK +31 �ļ����ӹ��� +$ EPIPE +32 �ܵ�����ֹ +$ EDOM +33 ��ֵ����Խ�� +$ ERANGE +34 ������� +$ EAGAIN, EWOULDBLOCK +35 ��Դ��ʱ������ +$ EINPROGRESS +36 ���������� +$ EALREADY +37 �����ѿ�ʼ +$ ENOTSOCK +38 �����ڷ� socket ��ִ�� socket ���� +$ EDESTADDRREQ +39 ��ҪĿ�ĵ�ַ +$ EMSGSIZE +40 ��Ϣ���� +$ EPROTOTYPE +41 socketЭ�����ʹ��� +$ ENOPROTOOPT +42 Э�鲻���� +$ EPROTONOSUPPORT +43 ��֧�ֵ�Э�� +$ ESOCKTNOSUPPORT +44 ��֧�ֵ� socket ���� +$ EOPNOTSUPP +45 ��֧�ֵIJ��� +$ EPFNOSUPPORT +46 ��֧�ֵ�Э���� +$ EAFNOSUPPORT +47 Э���岻֧�ֵĵ�ַ�� +$ EADDRINUSE +48 ��ַ�ѱ�ռ�� +$ EADDRNOTAVAIL +49 �޷�ָ������ĵ�ַ +$ ENETDOWN +50 �����ѹر� +$ ENETUNREACH +51 ���粻�ɴ� +$ ENETRESET +52 ��λ�����������Ӷ�ʧ +$ ECONNABORTED +53 ������µ�������ֹ +$ ECONNRESET +54 �Է���λ������ +$ ENOBUFS +55 �������ռ䲻�� +$ EISCONN +56 socket ������ +$ ENOTCONN +57 socket δ���� +$ ESHUTDOWN +58 socket shutdown ֮���޷��������� +$ ETOOMANYREFS +59 ���������ࣺ�޷�ƴ�� +$ ETIMEDOUT +60 ������ʱ +$ ECONNREFUSED +61 �ܾ����� +$ ELOOP +62 �������Ӳ������� +$ ENAMETOOLONG +63 �ļ������� +$ EHOSTDOWN +64 �����ѹر� +$ EHOSTUNREACH +65 û�е�������·�� +$ ENOTEMPTY +66 Ŀ¼�ǿ� +$ EPROCLIM +67 ���������� +$ EUSERS +68 �û������� +$ EDQUOT +69 ���̿ռ����� +$ ESTALE +70 NFS �ļ������ʧЧ +$ EREMOTE +71 Զ��Ŀ¼�������� +$ EBADRPC +72 RPC �ṹ��Ч +$ ERPCMISMATCH +73 RPC �汾���� +$ EPROGUNAVAIL +74 RPC ���򲻿��� +$ EPROGMISMATCH +75 ����汾���� +$ EPROCUNAVAIL +76 δ�ṩ��Զ�̺��� +$ ENOLCK +77 ��֧���� +$ ENOSYS +78 ����δʵ�� +$ EFTYPE +79 �ļ����ͻ��ʽ��Ч +$ EAUTH +80 �����Ч +$ ENEEDAUTH +81 ������ƾ�� +$ EIDRM +82 �ޱ�ʶ�� +$ ENOMSG +83 ����Ϣ���� +$ EOVERFLOW +84 ��ֵ��� +$ ECANCELED +85 ������ȡ�� +$ EILSEQ +86 ��Ч�ַ����� +$ ENOATTR +87 ����չ���� +$ EDOOFUS +88 ������ƴ��� +$ EBADMSG +89 ��Ч��Ϣ +$ EMULTIHOP +90 Multihop attempted +$ ENOLINK +91 Link has been severed +$ EPROTO +92 Э����� +$ ENOTCAPABLE +93 Ȩ�ܲ��� +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 �ն���·�Ҷ� +$ SIGINT +2 �ж� +$ SIGQUIT +3 �˳� +$ SIGILL +4 ��Чָ�� +$ SIGTRAP +5 ����/BPT ���� +$ SIGABRT +6 ��ֹ���� +$ SIGEMT +7 EMT ���� +$ SIGFPE +8 �����쳣 +$ SIGKILL +9 ǿ����ֹ���� +$ SIGBUS +10 ϵͳ�ڴ����Խ�� +$ SIGSEGV +11 �ڴ����Խ�� +$ SIGSYS +12 ��Чϵͳ���� +$ SIGPIPE +13 д�ܵ�ʱ��ȡ�߲����� +$ SIGALRM +14 ʵʱ����ʱ���� +$ SIGTERM +15 ��ֹ +$ SIGURG +16 ����������� I/O ����״�� +$ SIGSTOP +17 ���� (�ź�) +$ SIGTSTP +18 ���� +$ SIGCONT +19 �������� +$ SIGCHLD +20 �ӽ�����ֹ +$ SIGTTIN +21 TTY �������� +$ SIGTTOU +22 TTY ������� +$ SIGIO +23 I/O ���� +$ SIGXCPU +24 CPU ʹ��ʱ����� +$ SIGXFSZ +25 �ļ��ߴ���� +$ SIGVTALRM +26 ���⵹��ʱ���� +$ SIGPROF +27 ��������ʱ���� +$ SIGWINCH +28 ���ڳߴ�仯 +$ SIGINFO +29 ������Ϣ +$ SIGUSR1 +30 �û��Զ����ź� 1 +$ SIGUSR2 +31 �û��Զ����ź� 2 +$ +$ gai_strerror() support catalog +$ +$set 3 +$ 1 (obsolete) +1 ������ʹ���˲�֧�ֵĵ�ַ���� +$ EAI_AGAIN +2 ��ʱ�޷��������� +$ EAI_BADFLAGS +3 ��Ч�� ai_flags ֵ +$ EAI_FAIL +4 ��������ʱ�����޷��ָ��Ĵ��� +$ EAI_FAMILY +5 ��֧�ֵĵ�ַ��Ϣ���� +$ EAI_MEMORY +6 �ڴ����ʧ�� +$ 7 (obsolete) +7 ��������������ĵ�ַ +$ EAI_NONAME +8 δ֪��������������� +$ EAI_SERVICE +9 �׽������Ͳ�֧�ִ˷����� +$ EAI_SOCKTYPE +10 ��֧�ֵ��׽������� +$ EAI_SYSTEM +11 ϵͳ���÷����� errno ���� +$ EAI_BADHINTS +12 ��Ч��ʾ���� +$ EAI_PROTOCOL +13 δ֪Э�� +$ EAI_OVERFLOW +14 ����������� +$ 0 +32766 �ɹ� +$ NL_MSGMAX +32767 δ֪���� diff --git a/lib/libc/nls/zh_CN.UTF-8.msg b/lib/libc/nls/zh_CN.UTF-8.msg new file mode 100644 index 0000000..4c52f4a --- /dev/null +++ b/lib/libc/nls/zh_CN.UTF-8.msg @@ -0,0 +1,295 @@ +$ $FreeBSD: releng/11.1/lib/libc/nls/zh_CN.UTF-8.msg 244756 2012-12-28 01:09:30Z delphij $ +$ +$ Message catalog for zh_CN.UTF-8 locale +$ +$ strerror() support catalog +$ +$set 1 +$ EPERM +1 不允许的操作 +$ ENOENT +2 文件或目录不存在 +$ ESRCH +3 进程不存在 +$ EINTR +4 系统调用中止 +$ EIO +5 输入/输出错误 +$ ENXIO +6 未配置的设备 +$ E2BIG +7 参数表过长 +$ ENOEXEC +8 可执行文件格式错误 +$ EBADF +9 文件描述符无效 +$ ECHILD +10 指定子进程不存在 +$ EDEADLK +11 此操作会导致死锁 +$ ENOMEM +12 无法分配内存 +$ EACCES +13 拒绝访问 +$ EFAULT +14 无效地址 +$ ENOTBLK +15 该操作需要块设备 +$ EBUSY +16 设备使用中 +$ EEXIST +17 文件已存在 +$ EXDEV +18 链接跨设备 +$ ENODEV +19 设备不支持此操作 +$ ENOTDIR +20 对象非目录 +$ EISDIR +21 对象为目录 +$ EINVAL +22 参数无效 +$ ENFILE +23 系统打开文件过多 +$ EMFILE +24 进程打开文件过多 +$ ENOTTY +25 无效设备 ioctl +$ ETXTBSY +26 可执行文件忙 +$ EFBIG +27 文件过大 +$ ENOSPC +28 设备无可用空间 +$ ESPIPE +29 不允许执行 seek 操作 +$ EROFS +30 文件系统只读 +$ EMLINK +31 文件链接过多 +$ EPIPE +32 管道已中止 +$ EDOM +33 数值参数越界 +$ ERANGE +34 结果过大 +$ EAGAIN, EWOULDBLOCK +35 资源暂时不可用 +$ EINPROGRESS +36 操作进行中 +$ EALREADY +37 操作已开始 +$ ENOTSOCK +38 尝试在非 socket 上执行 socket 操作 +$ EDESTADDRREQ +39 需要目的地址 +$ EMSGSIZE +40 消息过长 +$ EPROTOTYPE +41 socket协议类型错误 +$ ENOPROTOOPT +42 协议不可用 +$ EPROTONOSUPPORT +43 不支持的协议 +$ ESOCKTNOSUPPORT +44 不支持的 socket 类型 +$ EOPNOTSUPP +45 不支持的操作 +$ EPFNOSUPPORT +46 不支持的协议族 +$ EAFNOSUPPORT +47 协议族不支持的地址族 +$ EADDRINUSE +48 地址已被占用 +$ EADDRNOTAVAIL +49 无法指定请求的地址 +$ ENETDOWN +50 网络已关闭 +$ ENETUNREACH +51 网络不可达 +$ ENETRESET +52 复位导致网络连接丢失 +$ ECONNABORTED +53 软件导致的连接中止 +$ ECONNRESET +54 对方复位了连接 +$ ENOBUFS +55 缓冲区空间不足 +$ EISCONN +56 socket 已连接 +$ ENOTCONN +57 socket 未连接 +$ ESHUTDOWN +58 socket shutdown 之后无法发送数据 +$ ETOOMANYREFS +59 引用数过多:无法拼接 +$ ETIMEDOUT +60 操作超时 +$ ECONNREFUSED +61 拒绝连接 +$ ELOOP +62 符号链接层数过多 +$ ENAMETOOLONG +63 文件名过长 +$ EHOSTDOWN +64 主机已关闭 +$ EHOSTUNREACH +65 没有到主机的路由 +$ ENOTEMPTY +66 目录非空 +$ EPROCLIM +67 进程数超限 +$ EUSERS +68 用户数超限 +$ EDQUOT +69 磁盘空间配额超限 +$ ESTALE +70 NFS 文件句柄已失效 +$ EREMOTE +71 远程目录层数过多 +$ EBADRPC +72 RPC 结构无效 +$ ERPCMISMATCH +73 RPC 版本错误 +$ EPROGUNAVAIL +74 RPC 程序不可用 +$ EPROGMISMATCH +75 程序版本错误 +$ EPROCUNAVAIL +76 未提供的远程函数 +$ ENOLCK +77 不支持锁 +$ ENOSYS +78 功能未实现 +$ EFTYPE +79 文件类型或格式无效 +$ EAUTH +80 身份无效 +$ ENEEDAUTH +81 无信任凭据 +$ EIDRM +82 无标识符 +$ ENOMSG +83 无消息类型 +$ EOVERFLOW +84 数值溢出 +$ ECANCELED +85 操作已取消 +$ EILSEQ +86 无效字符序列 +$ ENOATTR +87 无扩展属性 +$ EDOOFUS +88 程序设计错误 +$ EBADMSG +89 无效消息 +$ EMULTIHOP +90 Multihop attempted +$ ENOLINK +91 Link has been severed +$ EPROTO +92 协议错误 +$ ENOTCAPABLE +93 权能不足 +$ +$ strsignal() support catalog +$ +$set 2 +$ SIGHUP +1 终端线路挂断 +$ SIGINT +2 中断 +$ SIGQUIT +3 退出 +$ SIGILL +4 无效指令 +$ SIGTRAP +5 跟踪/BPT 陷阱 +$ SIGABRT +6 终止陷阱 +$ SIGEMT +7 EMT 陷阱 +$ SIGFPE +8 浮点异常 +$ SIGKILL +9 强制终止进程 +$ SIGBUS +10 系统内存访问越界 +$ SIGSEGV +11 内存访问越界 +$ SIGSYS +12 无效系统调用 +$ SIGPIPE +13 写管道时读取者不存在 +$ SIGALRM +14 实时倒计时到期 +$ SIGTERM +15 终止 +$ SIGURG +16 需立即处理的 I/O 紧急状况 +$ SIGSTOP +17 挂起 (信号) +$ SIGTSTP +18 挂起 +$ SIGCONT +19 继续运行 +$ SIGCHLD +20 子进程终止 +$ SIGTTIN +21 TTY 输入阻塞 +$ SIGTTOU +22 TTY 输出阻塞 +$ SIGIO +23 I/O 就绪 +$ SIGXCPU +24 CPU 使用时间过长 +$ SIGXFSZ +25 文件尺寸过大 +$ SIGVTALRM +26 虚拟倒计时到期 +$ SIGPROF +27 剖析倒计时到期 +$ SIGWINCH +28 窗口尺寸变化 +$ SIGINFO +29 请求信息 +$ SIGUSR1 +30 用户自定义信号 1 +$ SIGUSR2 +31 用户自定义信号 2 +$ +$ gai_strerror() support catalog +$ +$set 3 +$ 1 (obsolete) +1 主机名使用了不支持的地址类型 +$ EAI_AGAIN +2 暂时无法解析名称 +$ EAI_BADFLAGS +3 无效的 ai_flags 值 +$ EAI_FAIL +4 解析名称时出现无法恢复的错误 +$ EAI_FAMILY +5 不支持的地址信息类型 +$ EAI_MEMORY +6 内存分配失败 +$ 7 (obsolete) +7 主机名无相关联的地址 +$ EAI_NONAME +8 未知的主机名或服务名 +$ EAI_SERVICE +9 套接字类型不支持此服务名 +$ EAI_SOCKTYPE +10 不支持的套接字类型 +$ EAI_SYSTEM +11 系统调用返回了 errno 错误 +$ EAI_BADHINTS +12 无效提示参数 +$ EAI_PROTOCOL +13 未知协议 +$ EAI_OVERFLOW +14 参数缓冲溢出 +$ 0 +32766 成功 +$ NL_MSGMAX +32767 未知错误 diff --git a/lib/libc/posix1e/Makefile.inc b/lib/libc/posix1e/Makefile.inc new file mode 100644 index 0000000..1ac94a7 --- /dev/null +++ b/lib/libc/posix1e/Makefile.inc @@ -0,0 +1,126 @@ +# $FreeBSD: releng/11.1/lib/libc/posix1e/Makefile.inc 313240 2017-02-04 17:17:38Z ngie $ + +.PATH: ${LIBC_SRCTOP}/posix1e + +CFLAGS+=-D_ACL_PRIVATE + +# Copy kern/subr_acl_nfs4.c to the libc object directory. +subr_acl_nfs4.c: ${SRCTOP}/sys/kern/subr_acl_nfs4.c + cat ${.ALLSRC} > ${.TARGET} + +SRCS+= acl_branding.c \ + acl_calc_mask.c \ + acl_copy.c \ + acl_delete.c \ + acl_delete_entry.c \ + acl_entry.c \ + acl_flag.c \ + acl_free.c \ + acl_from_text.c \ + acl_from_text_nfs4.c \ + acl_get.c \ + acl_id_to_name.c \ + acl_init.c \ + acl_perm.c \ + acl_set.c \ + acl_strip.c \ + acl_support.c \ + acl_support_nfs4.c \ + acl_to_text.c \ + acl_to_text_nfs4.c \ + acl_valid.c \ + extattr.c \ + mac.c \ + mac_exec.c \ + mac_get.c \ + mac_set.c \ + subr_acl_nfs4.c +.if ${MK_SYMVER} == yes +SRCS+= acl_compat.c +.endif + +SYM_MAPS+=${LIBC_SRCTOP}/posix1e/Symbol.map + +MAN+= acl.3 \ + acl_add_flag_np.3 \ + acl_add_perm.3 \ + acl_calc_mask.3 \ + acl_clear_flags_np.3 \ + acl_clear_perms.3 \ + acl_copy_entry.3 \ + acl_create_entry.3 \ + acl_delete.3 \ + acl_delete_entry.3 \ + acl_delete_flag_np.3 \ + acl_delete_perm.3 \ + acl_dup.3 \ + acl_free.3 \ + acl_from_text.3 \ + acl_get.3 \ + acl_get_brand_np.3 \ + acl_get_entry.3 \ + acl_get_entry_type_np.3 \ + acl_get_flagset_np.3 \ + acl_get_flag_np.3 \ + acl_get_permset.3 \ + acl_get_perm_np.3 \ + acl_get_qualifier.3 \ + acl_get_tag_type.3 \ + acl_init.3 \ + acl_is_trivial_np.3 \ + acl_set.3 \ + acl_set_entry_type_np.3 \ + acl_set_flagset_np.3 \ + acl_set_permset.3 \ + acl_set_qualifier.3 \ + acl_set_tag_type.3 \ + acl_strip_np.3 \ + acl_to_text.3 \ + acl_valid.3 \ + extattr.3 \ + mac.3 \ + mac.conf.5 \ + mac_free.3 \ + mac_is_present.3 \ + mac_get.3 \ + mac_prepare.3 \ + mac_set.3 \ + mac_text.3 \ + posix1e.3 + +MLINKS+=acl_create_entry.3 acl_create_entry_np.3\ + acl_delete.3 acl_delete_def_file.3 \ + acl_delete.3 acl_delete_file_np.3 \ + acl_delete.3 acl_delete_fd_np.3 \ + acl_delete_entry.3 acl_delete_entry_np.3\ + acl_get.3 acl_get_file.3 \ + acl_get.3 acl_get_fd.3 \ + acl_get.3 acl_get_fd_np.3 \ + acl_get.3 acl_get_link_np.3 \ + acl_set.3 acl_set_file.3 \ + acl_set.3 acl_set_fd.3 \ + acl_set.3 acl_set_fd_np.3 \ + acl_set.3 acl_set_link_np.3 \ + acl_to_text.3 acl_to_text_np.3 \ + acl_valid.3 acl_valid_file_np.3 \ + acl_valid.3 acl_valid_fd_np.3 \ + extattr.3 extattr_namespace_to_string.3 \ + extattr.3 extattr_string_to_namespace.3 \ + mac_get.3 mac_get_fd.3 \ + mac_get.3 mac_get_file.3 \ + mac_get.3 mac_get_link.3 \ + mac_get.3 mac_get_peer.3 \ + mac_get.3 mac_get_pid.3 \ + mac_get.3 mac_get_proc.3 \ + mac_prepare.3 mac_prepare_file_label.3 \ + mac_prepare.3 mac_prepare_ifnet_label.3 \ + mac_prepare.3 mac_prepare_process_label.3 \ + mac_prepare.3 mac_prepare_type.3 \ + mac_set.3 mac_set_fd.3 \ + mac_set.3 mac_set_file.3 \ + mac_set.3 mac_set_link.3 \ + mac_set.3 mac_set_proc.3 \ + mac_text.3 mac_from_text.3 \ + mac_text.3 mac_to_text.3 + +CLEANFILES+= subr_acl_nfs4.c diff --git a/lib/libc/posix1e/subr_acl_nfs4.c b/lib/libc/posix1e/subr_acl_nfs4.c new file mode 100644 index 0000000..e43025e --- /dev/null +++ b/lib/libc/posix1e/subr_acl_nfs4.c @@ -0,0 +1,1418 @@ +/*- + * Copyright (c) 2008-2010 Edward Tomasz Napierała + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +/* + * ACL support routines specific to NFSv4 access control lists. These are + * utility routines for code common across file systems implementing NFSv4 + * ACLs. + */ + +#ifdef _KERNEL +#include +__FBSDID("$FreeBSD: releng/11.1/sys/kern/subr_acl_nfs4.c 287445 2015-09-04 00:14:20Z delphij $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#define KASSERT(a, b) assert(a) +#define CTASSERT(a) + +#endif /* !_KERNEL */ + +#ifdef _KERNEL + +static void acl_nfs4_trivial_from_mode(struct acl *aclp, mode_t mode); + +static int acl_nfs4_old_semantics = 0; + +SYSCTL_INT(_vfs, OID_AUTO, acl_nfs4_old_semantics, CTLFLAG_RW, + &acl_nfs4_old_semantics, 0, "Use pre-PSARC/2010/029 NFSv4 ACL semantics"); + +static struct { + accmode_t accmode; + int mask; +} accmode2mask[] = {{VREAD, ACL_READ_DATA}, + {VWRITE, ACL_WRITE_DATA}, + {VAPPEND, ACL_APPEND_DATA}, + {VEXEC, ACL_EXECUTE}, + {VREAD_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, + {VWRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, + {VDELETE_CHILD, ACL_DELETE_CHILD}, + {VREAD_ATTRIBUTES, ACL_READ_ATTRIBUTES}, + {VWRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, + {VDELETE, ACL_DELETE}, + {VREAD_ACL, ACL_READ_ACL}, + {VWRITE_ACL, ACL_WRITE_ACL}, + {VWRITE_OWNER, ACL_WRITE_OWNER}, + {VSYNCHRONIZE, ACL_SYNCHRONIZE}, + {0, 0}}; + +static int +_access_mask_from_accmode(accmode_t accmode) +{ + int access_mask = 0, i; + + for (i = 0; accmode2mask[i].accmode != 0; i++) { + if (accmode & accmode2mask[i].accmode) + access_mask |= accmode2mask[i].mask; + } + + /* + * VAPPEND is just a modifier for VWRITE; if the caller asked + * for 'VAPPEND | VWRITE', we want to check for ACL_APPEND_DATA only. + */ + if (access_mask & ACL_APPEND_DATA) + access_mask &= ~ACL_WRITE_DATA; + + return (access_mask); +} + +/* + * Return 0, iff access is allowed, 1 otherwise. + */ +static int +_acl_denies(const struct acl *aclp, int access_mask, struct ucred *cred, + int file_uid, int file_gid, int *denied_explicitly) +{ + int i; + const struct acl_entry *entry; + + if (denied_explicitly != NULL) + *denied_explicitly = 0; + + KASSERT(aclp->acl_cnt <= ACL_MAX_ENTRIES, + ("aclp->acl_cnt <= ACL_MAX_ENTRIES")); + + for (i = 0; i < aclp->acl_cnt; i++) { + entry = &(aclp->acl_entry[i]); + + if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW && + entry->ae_entry_type != ACL_ENTRY_TYPE_DENY) + continue; + if (entry->ae_flags & ACL_ENTRY_INHERIT_ONLY) + continue; + switch (entry->ae_tag) { + case ACL_USER_OBJ: + if (file_uid != cred->cr_uid) + continue; + break; + case ACL_USER: + if (entry->ae_id != cred->cr_uid) + continue; + break; + case ACL_GROUP_OBJ: + if (!groupmember(file_gid, cred)) + continue; + break; + case ACL_GROUP: + if (!groupmember(entry->ae_id, cred)) + continue; + break; + default: + KASSERT(entry->ae_tag == ACL_EVERYONE, + ("entry->ae_tag == ACL_EVERYONE")); + } + + if (entry->ae_entry_type == ACL_ENTRY_TYPE_DENY) { + if (entry->ae_perm & access_mask) { + if (denied_explicitly != NULL) + *denied_explicitly = 1; + return (1); + } + } + + access_mask &= ~(entry->ae_perm); + if (access_mask == 0) + return (0); + } + + if (access_mask == 0) + return (0); + + return (1); +} + +int +vaccess_acl_nfs4(enum vtype type, uid_t file_uid, gid_t file_gid, + struct acl *aclp, accmode_t accmode, struct ucred *cred, int *privused) +{ + accmode_t priv_granted = 0; + int denied, explicitly_denied, access_mask, is_directory, + must_be_owner = 0; + mode_t file_mode = 0; + + KASSERT((accmode & ~(VEXEC | VWRITE | VREAD | VADMIN | VAPPEND | + VEXPLICIT_DENY | VREAD_NAMED_ATTRS | VWRITE_NAMED_ATTRS | + VDELETE_CHILD | VREAD_ATTRIBUTES | VWRITE_ATTRIBUTES | VDELETE | + VREAD_ACL | VWRITE_ACL | VWRITE_OWNER | VSYNCHRONIZE)) == 0, + ("invalid bit in accmode")); + KASSERT((accmode & VAPPEND) == 0 || (accmode & VWRITE), + ("VAPPEND without VWRITE")); + + if (privused != NULL) + *privused = 0; + + if (accmode & VADMIN) + must_be_owner = 1; + + /* + * Ignore VSYNCHRONIZE permission. + */ + accmode &= ~VSYNCHRONIZE; + + access_mask = _access_mask_from_accmode(accmode); + + if (type == VDIR) + is_directory = 1; + else + is_directory = 0; + + /* + * File owner is always allowed to read and write the ACL + * and basic attributes. This is to prevent a situation + * where user would change ACL in a way that prevents him + * from undoing the change. + */ + if (file_uid == cred->cr_uid) + access_mask &= ~(ACL_READ_ACL | ACL_WRITE_ACL | + ACL_READ_ATTRIBUTES | ACL_WRITE_ATTRIBUTES); + + /* + * Ignore append permission for regular files; use write + * permission instead. + */ + if (!is_directory && (access_mask & ACL_APPEND_DATA)) { + access_mask &= ~ACL_APPEND_DATA; + access_mask |= ACL_WRITE_DATA; + } + + denied = _acl_denies(aclp, access_mask, cred, file_uid, file_gid, + &explicitly_denied); + + if (must_be_owner) { + if (file_uid != cred->cr_uid) + denied = EPERM; + } + + /* + * For VEXEC, ensure that at least one execute bit is set for + * non-directories. We have to check the mode here to stay + * consistent with execve(2). See the test in + * exec_check_permissions(). + */ + acl_nfs4_sync_mode_from_acl(&file_mode, aclp); + if (!denied && !is_directory && (accmode & VEXEC) && + (file_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0) + denied = EACCES; + + if (!denied) + return (0); + + /* + * Access failed. Iff it was not denied explicitly and + * VEXPLICIT_DENY flag was specified, allow access. + */ + if ((accmode & VEXPLICIT_DENY) && explicitly_denied == 0) + return (0); + + accmode &= ~VEXPLICIT_DENY; + + /* + * No match. Try to use privileges, if there are any. + */ + if (is_directory) { + if ((accmode & VEXEC) && !priv_check_cred(cred, + PRIV_VFS_LOOKUP, 0)) + priv_granted |= VEXEC; + } else { + /* + * Ensure that at least one execute bit is on. Otherwise, + * a privileged user will always succeed, and we don't want + * this to happen unless the file really is executable. + */ + if ((accmode & VEXEC) && (file_mode & + (S_IXUSR | S_IXGRP | S_IXOTH)) != 0 && + !priv_check_cred(cred, PRIV_VFS_EXEC, 0)) + priv_granted |= VEXEC; + } + + if ((accmode & VREAD) && !priv_check_cred(cred, PRIV_VFS_READ, 0)) + priv_granted |= VREAD; + + if ((accmode & (VWRITE | VAPPEND | VDELETE_CHILD)) && + !priv_check_cred(cred, PRIV_VFS_WRITE, 0)) + priv_granted |= (VWRITE | VAPPEND | VDELETE_CHILD); + + if ((accmode & VADMIN_PERMS) && + !priv_check_cred(cred, PRIV_VFS_ADMIN, 0)) + priv_granted |= VADMIN_PERMS; + + if ((accmode & VSTAT_PERMS) && + !priv_check_cred(cred, PRIV_VFS_STAT, 0)) + priv_granted |= VSTAT_PERMS; + + if ((accmode & priv_granted) == accmode) { + if (privused != NULL) + *privused = 1; + + return (0); + } + + if (accmode & (VADMIN_PERMS | VDELETE_CHILD | VDELETE)) + denied = EPERM; + else + denied = EACCES; + + return (denied); +} +#endif /* _KERNEL */ + +static int +_acl_entry_matches(struct acl_entry *entry, acl_tag_t tag, acl_perm_t perm, + acl_entry_type_t entry_type) +{ + if (entry->ae_tag != tag) + return (0); + + if (entry->ae_id != ACL_UNDEFINED_ID) + return (0); + + if (entry->ae_perm != perm) + return (0); + + if (entry->ae_entry_type != entry_type) + return (0); + + if (entry->ae_flags != 0) + return (0); + + return (1); +} + +static struct acl_entry * +_acl_append(struct acl *aclp, acl_tag_t tag, acl_perm_t perm, + acl_entry_type_t entry_type) +{ + struct acl_entry *entry; + + KASSERT(aclp->acl_cnt + 1 <= ACL_MAX_ENTRIES, + ("aclp->acl_cnt + 1 <= ACL_MAX_ENTRIES")); + + entry = &(aclp->acl_entry[aclp->acl_cnt]); + aclp->acl_cnt++; + + entry->ae_tag = tag; + entry->ae_id = ACL_UNDEFINED_ID; + entry->ae_perm = perm; + entry->ae_entry_type = entry_type; + entry->ae_flags = 0; + + return (entry); +} + +static struct acl_entry * +_acl_duplicate_entry(struct acl *aclp, int entry_index) +{ + int i; + + KASSERT(aclp->acl_cnt + 1 <= ACL_MAX_ENTRIES, + ("aclp->acl_cnt + 1 <= ACL_MAX_ENTRIES")); + + for (i = aclp->acl_cnt; i > entry_index; i--) + aclp->acl_entry[i] = aclp->acl_entry[i - 1]; + + aclp->acl_cnt++; + + return (&(aclp->acl_entry[entry_index + 1])); +} + +static void +acl_nfs4_sync_acl_from_mode_draft(struct acl *aclp, mode_t mode, + int file_owner_id) +{ + int i, meets, must_append; + struct acl_entry *entry, *copy, *previous, + *a1, *a2, *a3, *a4, *a5, *a6; + mode_t amode; + const int READ = 04; + const int WRITE = 02; + const int EXEC = 01; + + KASSERT(aclp->acl_cnt <= ACL_MAX_ENTRIES, + ("aclp->acl_cnt <= ACL_MAX_ENTRIES")); + + /* + * NFSv4 Minor Version 1, draft-ietf-nfsv4-minorversion1-03.txt + * + * 3.16.6.3. Applying a Mode to an Existing ACL + */ + + /* + * 1. For each ACE: + */ + for (i = 0; i < aclp->acl_cnt; i++) { + entry = &(aclp->acl_entry[i]); + + /* + * 1.1. If the type is neither ALLOW or DENY - skip. + */ + if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW && + entry->ae_entry_type != ACL_ENTRY_TYPE_DENY) + continue; + + /* + * 1.2. If ACL_ENTRY_INHERIT_ONLY is set - skip. + */ + if (entry->ae_flags & ACL_ENTRY_INHERIT_ONLY) + continue; + + /* + * 1.3. If ACL_ENTRY_FILE_INHERIT or ACL_ENTRY_DIRECTORY_INHERIT + * are set: + */ + if (entry->ae_flags & + (ACL_ENTRY_FILE_INHERIT | ACL_ENTRY_DIRECTORY_INHERIT)) { + /* + * 1.3.1. A copy of the current ACE is made, and placed + * in the ACL immediately following the current + * ACE. + */ + copy = _acl_duplicate_entry(aclp, i); + + /* + * 1.3.2. In the first ACE, the flag + * ACL_ENTRY_INHERIT_ONLY is set. + */ + entry->ae_flags |= ACL_ENTRY_INHERIT_ONLY; + + /* + * 1.3.3. In the second ACE, the following flags + * are cleared: + * ACL_ENTRY_FILE_INHERIT, + * ACL_ENTRY_DIRECTORY_INHERIT, + * ACL_ENTRY_NO_PROPAGATE_INHERIT. + */ + copy->ae_flags &= ~(ACL_ENTRY_FILE_INHERIT | + ACL_ENTRY_DIRECTORY_INHERIT | + ACL_ENTRY_NO_PROPAGATE_INHERIT); + + /* + * The algorithm continues on with the second ACE. + */ + i++; + entry = copy; + } + + /* + * 1.4. If it's owner@, group@ or everyone@ entry, clear + * ACL_READ_DATA, ACL_WRITE_DATA, ACL_APPEND_DATA + * and ACL_EXECUTE. Continue to the next entry. + */ + if (entry->ae_tag == ACL_USER_OBJ || + entry->ae_tag == ACL_GROUP_OBJ || + entry->ae_tag == ACL_EVERYONE) { + entry->ae_perm &= ~(ACL_READ_DATA | ACL_WRITE_DATA | + ACL_APPEND_DATA | ACL_EXECUTE); + continue; + } + + /* + * 1.5. Otherwise, if the "who" field did not match one + * of OWNER@, GROUP@, EVERYONE@: + * + * 1.5.1. If the type is ALLOW, check the preceding ACE. + * If it does not meet all of the following criteria: + */ + if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW) + continue; + + meets = 0; + if (i > 0) { + meets = 1; + previous = &(aclp->acl_entry[i - 1]); + + /* + * 1.5.1.1. The type field is DENY, + */ + if (previous->ae_entry_type != ACL_ENTRY_TYPE_DENY) + meets = 0; + + /* + * 1.5.1.2. The "who" field is the same as the current + * ACE, + * + * 1.5.1.3. The flag bit ACE4_IDENTIFIER_GROUP + * is the same as it is in the current ACE, + * and no other flag bits are set, + */ + if (previous->ae_id != entry->ae_id || + previous->ae_tag != entry->ae_tag) + meets = 0; + + if (previous->ae_flags) + meets = 0; + + /* + * 1.5.1.4. The mask bits are a subset of the mask bits + * of the current ACE, and are also subset of + * the following: ACL_READ_DATA, + * ACL_WRITE_DATA, ACL_APPEND_DATA, ACL_EXECUTE + */ + if (previous->ae_perm & ~(entry->ae_perm)) + meets = 0; + + if (previous->ae_perm & ~(ACL_READ_DATA | + ACL_WRITE_DATA | ACL_APPEND_DATA | ACL_EXECUTE)) + meets = 0; + } + + if (!meets) { + /* + * Then the ACE of type DENY, with a who equal + * to the current ACE, flag bits equal to + * ( & ) + * and no mask bits, is prepended. + */ + previous = entry; + entry = _acl_duplicate_entry(aclp, i); + + /* Adjust counter, as we've just added an entry. */ + i++; + + previous->ae_tag = entry->ae_tag; + previous->ae_id = entry->ae_id; + previous->ae_flags = entry->ae_flags; + previous->ae_perm = 0; + previous->ae_entry_type = ACL_ENTRY_TYPE_DENY; + } + + /* + * 1.5.2. The following modifications are made to the prepended + * ACE. The intent is to mask the following ACE + * to disallow ACL_READ_DATA, ACL_WRITE_DATA, + * ACL_APPEND_DATA, or ACL_EXECUTE, based upon the group + * permissions of the new mode. As a special case, + * if the ACE matches the current owner of the file, + * the owner bits are used, rather than the group bits. + * This is reflected in the algorithm below. + */ + amode = mode >> 3; + + /* + * If ACE4_IDENTIFIER_GROUP is not set, and the "who" field + * in ACE matches the owner of the file, we shift amode three + * more bits, in order to have the owner permission bits + * placed in the three low order bits of amode. + */ + if (entry->ae_tag == ACL_USER && entry->ae_id == file_owner_id) + amode = amode >> 3; + + if (entry->ae_perm & ACL_READ_DATA) { + if (amode & READ) + previous->ae_perm &= ~ACL_READ_DATA; + else + previous->ae_perm |= ACL_READ_DATA; + } + + if (entry->ae_perm & ACL_WRITE_DATA) { + if (amode & WRITE) + previous->ae_perm &= ~ACL_WRITE_DATA; + else + previous->ae_perm |= ACL_WRITE_DATA; + } + + if (entry->ae_perm & ACL_APPEND_DATA) { + if (amode & WRITE) + previous->ae_perm &= ~ACL_APPEND_DATA; + else + previous->ae_perm |= ACL_APPEND_DATA; + } + + if (entry->ae_perm & ACL_EXECUTE) { + if (amode & EXEC) + previous->ae_perm &= ~ACL_EXECUTE; + else + previous->ae_perm |= ACL_EXECUTE; + } + + /* + * 1.5.3. If ACE4_IDENTIFIER_GROUP is set in the flags + * of the ALLOW ace: + * + * XXX: This point is not there in the Falkner's draft. + */ + if (entry->ae_tag == ACL_GROUP && + entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) { + mode_t extramode, ownermode; + extramode = (mode >> 3) & 07; + ownermode = mode >> 6; + extramode &= ~ownermode; + + if (extramode) { + if (extramode & READ) { + entry->ae_perm &= ~ACL_READ_DATA; + previous->ae_perm &= ~ACL_READ_DATA; + } + + if (extramode & WRITE) { + entry->ae_perm &= + ~(ACL_WRITE_DATA | ACL_APPEND_DATA); + previous->ae_perm &= + ~(ACL_WRITE_DATA | ACL_APPEND_DATA); + } + + if (extramode & EXEC) { + entry->ae_perm &= ~ACL_EXECUTE; + previous->ae_perm &= ~ACL_EXECUTE; + } + } + } + } + + /* + * 2. If there at least six ACEs, the final six ACEs are examined. + * If they are not equal to what we want, append six ACEs. + */ + must_append = 0; + if (aclp->acl_cnt < 6) { + must_append = 1; + } else { + a6 = &(aclp->acl_entry[aclp->acl_cnt - 1]); + a5 = &(aclp->acl_entry[aclp->acl_cnt - 2]); + a4 = &(aclp->acl_entry[aclp->acl_cnt - 3]); + a3 = &(aclp->acl_entry[aclp->acl_cnt - 4]); + a2 = &(aclp->acl_entry[aclp->acl_cnt - 5]); + a1 = &(aclp->acl_entry[aclp->acl_cnt - 6]); + + if (!_acl_entry_matches(a1, ACL_USER_OBJ, 0, + ACL_ENTRY_TYPE_DENY)) + must_append = 1; + if (!_acl_entry_matches(a2, ACL_USER_OBJ, ACL_WRITE_ACL | + ACL_WRITE_OWNER | ACL_WRITE_ATTRIBUTES | + ACL_WRITE_NAMED_ATTRS, ACL_ENTRY_TYPE_ALLOW)) + must_append = 1; + if (!_acl_entry_matches(a3, ACL_GROUP_OBJ, 0, + ACL_ENTRY_TYPE_DENY)) + must_append = 1; + if (!_acl_entry_matches(a4, ACL_GROUP_OBJ, 0, + ACL_ENTRY_TYPE_ALLOW)) + must_append = 1; + if (!_acl_entry_matches(a5, ACL_EVERYONE, ACL_WRITE_ACL | + ACL_WRITE_OWNER | ACL_WRITE_ATTRIBUTES | + ACL_WRITE_NAMED_ATTRS, ACL_ENTRY_TYPE_DENY)) + must_append = 1; + if (!_acl_entry_matches(a6, ACL_EVERYONE, ACL_READ_ACL | + ACL_READ_ATTRIBUTES | ACL_READ_NAMED_ATTRS | + ACL_SYNCHRONIZE, ACL_ENTRY_TYPE_ALLOW)) + must_append = 1; + } + + if (must_append) { + KASSERT(aclp->acl_cnt + 6 <= ACL_MAX_ENTRIES, + ("aclp->acl_cnt <= ACL_MAX_ENTRIES")); + + a1 = _acl_append(aclp, ACL_USER_OBJ, 0, ACL_ENTRY_TYPE_DENY); + a2 = _acl_append(aclp, ACL_USER_OBJ, ACL_WRITE_ACL | + ACL_WRITE_OWNER | ACL_WRITE_ATTRIBUTES | + ACL_WRITE_NAMED_ATTRS, ACL_ENTRY_TYPE_ALLOW); + a3 = _acl_append(aclp, ACL_GROUP_OBJ, 0, ACL_ENTRY_TYPE_DENY); + a4 = _acl_append(aclp, ACL_GROUP_OBJ, 0, ACL_ENTRY_TYPE_ALLOW); + a5 = _acl_append(aclp, ACL_EVERYONE, ACL_WRITE_ACL | + ACL_WRITE_OWNER | ACL_WRITE_ATTRIBUTES | + ACL_WRITE_NAMED_ATTRS, ACL_ENTRY_TYPE_DENY); + a6 = _acl_append(aclp, ACL_EVERYONE, ACL_READ_ACL | + ACL_READ_ATTRIBUTES | ACL_READ_NAMED_ATTRS | + ACL_SYNCHRONIZE, ACL_ENTRY_TYPE_ALLOW); + + KASSERT(a1 != NULL && a2 != NULL && a3 != NULL && a4 != NULL && + a5 != NULL && a6 != NULL, ("couldn't append to ACL.")); + } + + /* + * 3. The final six ACEs are adjusted according to the incoming mode. + */ + if (mode & S_IRUSR) + a2->ae_perm |= ACL_READ_DATA; + else + a1->ae_perm |= ACL_READ_DATA; + if (mode & S_IWUSR) + a2->ae_perm |= (ACL_WRITE_DATA | ACL_APPEND_DATA); + else + a1->ae_perm |= (ACL_WRITE_DATA | ACL_APPEND_DATA); + if (mode & S_IXUSR) + a2->ae_perm |= ACL_EXECUTE; + else + a1->ae_perm |= ACL_EXECUTE; + + if (mode & S_IRGRP) + a4->ae_perm |= ACL_READ_DATA; + else + a3->ae_perm |= ACL_READ_DATA; + if (mode & S_IWGRP) + a4->ae_perm |= (ACL_WRITE_DATA | ACL_APPEND_DATA); + else + a3->ae_perm |= (ACL_WRITE_DATA | ACL_APPEND_DATA); + if (mode & S_IXGRP) + a4->ae_perm |= ACL_EXECUTE; + else + a3->ae_perm |= ACL_EXECUTE; + + if (mode & S_IROTH) + a6->ae_perm |= ACL_READ_DATA; + else + a5->ae_perm |= ACL_READ_DATA; + if (mode & S_IWOTH) + a6->ae_perm |= (ACL_WRITE_DATA | ACL_APPEND_DATA); + else + a5->ae_perm |= (ACL_WRITE_DATA | ACL_APPEND_DATA); + if (mode & S_IXOTH) + a6->ae_perm |= ACL_EXECUTE; + else + a5->ae_perm |= ACL_EXECUTE; +} + +#ifdef _KERNEL +void +acl_nfs4_sync_acl_from_mode(struct acl *aclp, mode_t mode, + int file_owner_id) +{ + + if (acl_nfs4_old_semantics) + acl_nfs4_sync_acl_from_mode_draft(aclp, mode, file_owner_id); + else + acl_nfs4_trivial_from_mode(aclp, mode); +} +#endif /* _KERNEL */ + +void +acl_nfs4_sync_mode_from_acl(mode_t *_mode, const struct acl *aclp) +{ + int i; + mode_t old_mode = *_mode, mode = 0, seen = 0; + const struct acl_entry *entry; + + KASSERT(aclp->acl_cnt <= ACL_MAX_ENTRIES, + ("aclp->acl_cnt <= ACL_MAX_ENTRIES")); + + /* + * NFSv4 Minor Version 1, draft-ietf-nfsv4-minorversion1-03.txt + * + * 3.16.6.1. Recomputing mode upon SETATTR of ACL + */ + + for (i = 0; i < aclp->acl_cnt; i++) { + entry = &(aclp->acl_entry[i]); + + if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW && + entry->ae_entry_type != ACL_ENTRY_TYPE_DENY) + continue; + + if (entry->ae_flags & ACL_ENTRY_INHERIT_ONLY) + continue; + + if (entry->ae_tag == ACL_USER_OBJ) { + if ((entry->ae_perm & ACL_READ_DATA) && + ((seen & S_IRUSR) == 0)) { + seen |= S_IRUSR; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IRUSR; + } + if ((entry->ae_perm & ACL_WRITE_DATA) && + ((seen & S_IWUSR) == 0)) { + seen |= S_IWUSR; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IWUSR; + } + if ((entry->ae_perm & ACL_EXECUTE) && + ((seen & S_IXUSR) == 0)) { + seen |= S_IXUSR; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IXUSR; + } + } else if (entry->ae_tag == ACL_GROUP_OBJ) { + if ((entry->ae_perm & ACL_READ_DATA) && + ((seen & S_IRGRP) == 0)) { + seen |= S_IRGRP; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IRGRP; + } + if ((entry->ae_perm & ACL_WRITE_DATA) && + ((seen & S_IWGRP) == 0)) { + seen |= S_IWGRP; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IWGRP; + } + if ((entry->ae_perm & ACL_EXECUTE) && + ((seen & S_IXGRP) == 0)) { + seen |= S_IXGRP; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IXGRP; + } + } else if (entry->ae_tag == ACL_EVERYONE) { + if (entry->ae_perm & ACL_READ_DATA) { + if ((seen & S_IRUSR) == 0) { + seen |= S_IRUSR; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IRUSR; + } + if ((seen & S_IRGRP) == 0) { + seen |= S_IRGRP; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IRGRP; + } + if ((seen & S_IROTH) == 0) { + seen |= S_IROTH; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IROTH; + } + } + if (entry->ae_perm & ACL_WRITE_DATA) { + if ((seen & S_IWUSR) == 0) { + seen |= S_IWUSR; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IWUSR; + } + if ((seen & S_IWGRP) == 0) { + seen |= S_IWGRP; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IWGRP; + } + if ((seen & S_IWOTH) == 0) { + seen |= S_IWOTH; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IWOTH; + } + } + if (entry->ae_perm & ACL_EXECUTE) { + if ((seen & S_IXUSR) == 0) { + seen |= S_IXUSR; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IXUSR; + } + if ((seen & S_IXGRP) == 0) { + seen |= S_IXGRP; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IXGRP; + } + if ((seen & S_IXOTH) == 0) { + seen |= S_IXOTH; + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + mode |= S_IXOTH; + } + } + } + } + + *_mode = mode | (old_mode & ACL_PRESERVE_MASK); +} + +#ifdef _KERNEL +/* + * Calculate inherited ACL in a manner compatible with NFSv4 Minor Version 1, + * draft-ietf-nfsv4-minorversion1-03.txt. + */ +static void +acl_nfs4_compute_inherited_acl_draft(const struct acl *parent_aclp, + struct acl *child_aclp, mode_t mode, int file_owner_id, + int is_directory) +{ + int i, flags; + const struct acl_entry *parent_entry; + struct acl_entry *entry, *copy; + + KASSERT(child_aclp->acl_cnt == 0, ("child_aclp->acl_cnt == 0")); + KASSERT(parent_aclp->acl_cnt <= ACL_MAX_ENTRIES, + ("parent_aclp->acl_cnt <= ACL_MAX_ENTRIES")); + + /* + * NFSv4 Minor Version 1, draft-ietf-nfsv4-minorversion1-03.txt + * + * 3.16.6.2. Applying the mode given to CREATE or OPEN + * to an inherited ACL + */ + + /* + * 1. Form an ACL that is the concatenation of all inheritable ACEs. + */ + for (i = 0; i < parent_aclp->acl_cnt; i++) { + parent_entry = &(parent_aclp->acl_entry[i]); + flags = parent_entry->ae_flags; + + /* + * Entry is not inheritable at all. + */ + if ((flags & (ACL_ENTRY_DIRECTORY_INHERIT | + ACL_ENTRY_FILE_INHERIT)) == 0) + continue; + + /* + * We're creating a file, but entry is not inheritable + * by files. + */ + if (!is_directory && (flags & ACL_ENTRY_FILE_INHERIT) == 0) + continue; + + /* + * Entry is inheritable only by files, but has NO_PROPAGATE + * flag set, and we're creating a directory, so it wouldn't + * propagate to any file in that directory anyway. + */ + if (is_directory && + (flags & ACL_ENTRY_DIRECTORY_INHERIT) == 0 && + (flags & ACL_ENTRY_NO_PROPAGATE_INHERIT)) + continue; + + KASSERT(child_aclp->acl_cnt + 1 <= ACL_MAX_ENTRIES, + ("child_aclp->acl_cnt + 1 <= ACL_MAX_ENTRIES")); + child_aclp->acl_entry[child_aclp->acl_cnt] = *parent_entry; + child_aclp->acl_cnt++; + } + + /* + * 2. For each entry in the new ACL, adjust its flags, possibly + * creating two entries in place of one. + */ + for (i = 0; i < child_aclp->acl_cnt; i++) { + entry = &(child_aclp->acl_entry[i]); + + /* + * This is not in the specification, but SunOS + * apparently does that. + */ + if (((entry->ae_flags & ACL_ENTRY_NO_PROPAGATE_INHERIT) || + !is_directory) && + entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + entry->ae_perm &= ~(ACL_WRITE_ACL | ACL_WRITE_OWNER); + + /* + * 2.A. If the ACL_ENTRY_NO_PROPAGATE_INHERIT is set, or if the object + * being created is not a directory, then clear the + * following flags: ACL_ENTRY_NO_PROPAGATE_INHERIT, + * ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT, + * ACL_ENTRY_INHERIT_ONLY. + */ + if (entry->ae_flags & ACL_ENTRY_NO_PROPAGATE_INHERIT || + !is_directory) { + entry->ae_flags &= ~(ACL_ENTRY_NO_PROPAGATE_INHERIT | + ACL_ENTRY_FILE_INHERIT | ACL_ENTRY_DIRECTORY_INHERIT | + ACL_ENTRY_INHERIT_ONLY); + + /* + * Continue on to the next ACE. + */ + continue; + } + + /* + * 2.B. If the object is a directory and ACL_ENTRY_FILE_INHERIT + * is set, but ACL_ENTRY_NO_PROPAGATE_INHERIT is not set, ensure + * that ACL_ENTRY_INHERIT_ONLY is set. Continue to the + * next ACE. Otherwise... + */ + /* + * XXX: Read it again and make sure what does the "otherwise" + * apply to. + */ + if (is_directory && + (entry->ae_flags & ACL_ENTRY_FILE_INHERIT) && + ((entry->ae_flags & ACL_ENTRY_DIRECTORY_INHERIT) == 0)) { + entry->ae_flags |= ACL_ENTRY_INHERIT_ONLY; + continue; + } + + /* + * 2.C. If the type of the ACE is neither ALLOW nor deny, + * then continue. + */ + if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW && + entry->ae_entry_type != ACL_ENTRY_TYPE_DENY) + continue; + + /* + * 2.D. Copy the original ACE into a second, adjacent ACE. + */ + copy = _acl_duplicate_entry(child_aclp, i); + + /* + * 2.E. On the first ACE, ensure that ACL_ENTRY_INHERIT_ONLY + * is set. + */ + entry->ae_flags |= ACL_ENTRY_INHERIT_ONLY; + + /* + * 2.F. On the second ACE, clear the following flags: + * ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_FILE_INHERIT, + * ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_INHERIT_ONLY. + */ + copy->ae_flags &= ~(ACL_ENTRY_NO_PROPAGATE_INHERIT | + ACL_ENTRY_FILE_INHERIT | ACL_ENTRY_DIRECTORY_INHERIT | + ACL_ENTRY_INHERIT_ONLY); + + /* + * 2.G. On the second ACE, if the type is ALLOW, + * an implementation MAY clear the following + * mask bits: ACL_WRITE_ACL, ACL_WRITE_OWNER. + */ + if (copy->ae_entry_type == ACL_ENTRY_TYPE_ALLOW) + copy->ae_perm &= ~(ACL_WRITE_ACL | ACL_WRITE_OWNER); + + /* + * Increment the counter to skip the copied entry. + */ + i++; + } + + /* + * 3. To ensure that the mode is honored, apply the algorithm describe + * in Section 2.16.6.3, using the mode that is to be used for file + * creation. + */ + acl_nfs4_sync_acl_from_mode(child_aclp, mode, file_owner_id); +} +#endif /* _KERNEL */ + +/* + * Populate the ACL with entries inherited from parent_aclp. + */ +static void +acl_nfs4_inherit_entries(const struct acl *parent_aclp, + struct acl *child_aclp, mode_t mode, int file_owner_id, + int is_directory) +{ + int i, flags, tag; + const struct acl_entry *parent_entry; + struct acl_entry *entry; + + KASSERT(parent_aclp->acl_cnt <= ACL_MAX_ENTRIES, + ("parent_aclp->acl_cnt <= ACL_MAX_ENTRIES")); + + for (i = 0; i < parent_aclp->acl_cnt; i++) { + parent_entry = &(parent_aclp->acl_entry[i]); + flags = parent_entry->ae_flags; + tag = parent_entry->ae_tag; + + /* + * Don't inherit owner@, group@, or everyone@ entries. + */ + if (tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || + tag == ACL_EVERYONE) + continue; + + /* + * Entry is not inheritable at all. + */ + if ((flags & (ACL_ENTRY_DIRECTORY_INHERIT | + ACL_ENTRY_FILE_INHERIT)) == 0) + continue; + + /* + * We're creating a file, but entry is not inheritable + * by files. + */ + if (!is_directory && (flags & ACL_ENTRY_FILE_INHERIT) == 0) + continue; + + /* + * Entry is inheritable only by files, but has NO_PROPAGATE + * flag set, and we're creating a directory, so it wouldn't + * propagate to any file in that directory anyway. + */ + if (is_directory && + (flags & ACL_ENTRY_DIRECTORY_INHERIT) == 0 && + (flags & ACL_ENTRY_NO_PROPAGATE_INHERIT)) + continue; + + /* + * Entry qualifies for being inherited. + */ + KASSERT(child_aclp->acl_cnt + 1 <= ACL_MAX_ENTRIES, + ("child_aclp->acl_cnt + 1 <= ACL_MAX_ENTRIES")); + entry = &(child_aclp->acl_entry[child_aclp->acl_cnt]); + *entry = *parent_entry; + child_aclp->acl_cnt++; + + entry->ae_flags &= ~ACL_ENTRY_INHERIT_ONLY; + entry->ae_flags |= ACL_ENTRY_INHERITED; + + /* + * If the type of the ACE is neither ALLOW nor DENY, + * then leave it as it is and proceed to the next one. + */ + if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW && + entry->ae_entry_type != ACL_ENTRY_TYPE_DENY) + continue; + + /* + * If the ACL_ENTRY_NO_PROPAGATE_INHERIT is set, or if + * the object being created is not a directory, then clear + * the following flags: ACL_ENTRY_NO_PROPAGATE_INHERIT, + * ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT, + * ACL_ENTRY_INHERIT_ONLY. + */ + if (entry->ae_flags & ACL_ENTRY_NO_PROPAGATE_INHERIT || + !is_directory) { + entry->ae_flags &= ~(ACL_ENTRY_NO_PROPAGATE_INHERIT | + ACL_ENTRY_FILE_INHERIT | ACL_ENTRY_DIRECTORY_INHERIT | + ACL_ENTRY_INHERIT_ONLY); + } + + /* + * If the object is a directory and ACL_ENTRY_FILE_INHERIT + * is set, but ACL_ENTRY_DIRECTORY_INHERIT is not set, ensure + * that ACL_ENTRY_INHERIT_ONLY is set. + */ + if (is_directory && + (entry->ae_flags & ACL_ENTRY_FILE_INHERIT) && + ((entry->ae_flags & ACL_ENTRY_DIRECTORY_INHERIT) == 0)) { + entry->ae_flags |= ACL_ENTRY_INHERIT_ONLY; + } + + if (entry->ae_entry_type == ACL_ENTRY_TYPE_ALLOW && + (entry->ae_flags & ACL_ENTRY_INHERIT_ONLY) == 0) { + /* + * Some permissions must never be inherited. + */ + entry->ae_perm &= ~(ACL_WRITE_ACL | ACL_WRITE_OWNER | + ACL_WRITE_NAMED_ATTRS | ACL_WRITE_ATTRIBUTES); + + /* + * Others must be masked according to the file mode. + */ + if ((mode & S_IRGRP) == 0) + entry->ae_perm &= ~ACL_READ_DATA; + if ((mode & S_IWGRP) == 0) + entry->ae_perm &= + ~(ACL_WRITE_DATA | ACL_APPEND_DATA); + if ((mode & S_IXGRP) == 0) + entry->ae_perm &= ~ACL_EXECUTE; + } + } +} + +/* + * Calculate inherited ACL in a manner compatible with PSARC/2010/029. + * It's also being used to calculate a trivial ACL, by inheriting from + * a NULL ACL. + */ +static void +acl_nfs4_compute_inherited_acl_psarc(const struct acl *parent_aclp, + struct acl *aclp, mode_t mode, int file_owner_id, int is_directory) +{ + acl_perm_t user_allow_first = 0, user_deny = 0, group_deny = 0; + acl_perm_t user_allow, group_allow, everyone_allow; + + KASSERT(aclp->acl_cnt == 0, ("aclp->acl_cnt == 0")); + + user_allow = group_allow = everyone_allow = ACL_READ_ACL | + ACL_READ_ATTRIBUTES | ACL_READ_NAMED_ATTRS | ACL_SYNCHRONIZE; + user_allow |= ACL_WRITE_ACL | ACL_WRITE_OWNER | ACL_WRITE_ATTRIBUTES | + ACL_WRITE_NAMED_ATTRS; + + if (mode & S_IRUSR) + user_allow |= ACL_READ_DATA; + if (mode & S_IWUSR) + user_allow |= (ACL_WRITE_DATA | ACL_APPEND_DATA); + if (mode & S_IXUSR) + user_allow |= ACL_EXECUTE; + + if (mode & S_IRGRP) + group_allow |= ACL_READ_DATA; + if (mode & S_IWGRP) + group_allow |= (ACL_WRITE_DATA | ACL_APPEND_DATA); + if (mode & S_IXGRP) + group_allow |= ACL_EXECUTE; + + if (mode & S_IROTH) + everyone_allow |= ACL_READ_DATA; + if (mode & S_IWOTH) + everyone_allow |= (ACL_WRITE_DATA | ACL_APPEND_DATA); + if (mode & S_IXOTH) + everyone_allow |= ACL_EXECUTE; + + user_deny = ((group_allow | everyone_allow) & ~user_allow); + group_deny = everyone_allow & ~group_allow; + user_allow_first = group_deny & ~user_deny; + + if (user_allow_first != 0) + _acl_append(aclp, ACL_USER_OBJ, user_allow_first, + ACL_ENTRY_TYPE_ALLOW); + if (user_deny != 0) + _acl_append(aclp, ACL_USER_OBJ, user_deny, + ACL_ENTRY_TYPE_DENY); + if (group_deny != 0) + _acl_append(aclp, ACL_GROUP_OBJ, group_deny, + ACL_ENTRY_TYPE_DENY); + + if (parent_aclp != NULL) + acl_nfs4_inherit_entries(parent_aclp, aclp, mode, + file_owner_id, is_directory); + + _acl_append(aclp, ACL_USER_OBJ, user_allow, ACL_ENTRY_TYPE_ALLOW); + _acl_append(aclp, ACL_GROUP_OBJ, group_allow, ACL_ENTRY_TYPE_ALLOW); + _acl_append(aclp, ACL_EVERYONE, everyone_allow, ACL_ENTRY_TYPE_ALLOW); +} + +#ifdef _KERNEL +void +acl_nfs4_compute_inherited_acl(const struct acl *parent_aclp, + struct acl *child_aclp, mode_t mode, int file_owner_id, + int is_directory) +{ + + if (acl_nfs4_old_semantics) + acl_nfs4_compute_inherited_acl_draft(parent_aclp, child_aclp, + mode, file_owner_id, is_directory); + else + acl_nfs4_compute_inherited_acl_psarc(parent_aclp, child_aclp, + mode, file_owner_id, is_directory); +} +#endif /* _KERNEL */ + +/* + * Calculate trivial ACL in a manner compatible with PSARC/2010/029. + * Note that this results in an ACL different from (but semantically + * equal to) the "canonical six" trivial ACL computed using algorithm + * described in draft-ietf-nfsv4-minorversion1-03.txt, 3.16.6.2. + */ +static void +acl_nfs4_trivial_from_mode(struct acl *aclp, mode_t mode) +{ + + aclp->acl_cnt = 0; + acl_nfs4_compute_inherited_acl_psarc(NULL, aclp, mode, -1, -1); +} + +#ifndef _KERNEL +/* + * This routine is used by libc to implement acl_strip_np(3) + * and acl_is_trivial_np(3). + */ +void +acl_nfs4_trivial_from_mode_libc(struct acl *aclp, int mode, int canonical_six) +{ + + aclp->acl_cnt = 0; + if (canonical_six) + acl_nfs4_sync_acl_from_mode_draft(aclp, mode, -1); + else + acl_nfs4_trivial_from_mode(aclp, mode); +} +#endif /* !_KERNEL */ + +#ifdef _KERNEL +static int +_acls_are_equal(const struct acl *a, const struct acl *b) +{ + int i; + const struct acl_entry *entrya, *entryb; + + if (a->acl_cnt != b->acl_cnt) + return (0); + + for (i = 0; i < b->acl_cnt; i++) { + entrya = &(a->acl_entry[i]); + entryb = &(b->acl_entry[i]); + + if (entrya->ae_tag != entryb->ae_tag || + entrya->ae_id != entryb->ae_id || + entrya->ae_perm != entryb->ae_perm || + entrya->ae_entry_type != entryb->ae_entry_type || + entrya->ae_flags != entryb->ae_flags) + return (0); + } + + return (1); +} + +/* + * This routine is used to determine whether to remove extended attribute + * that stores ACL contents. + */ +int +acl_nfs4_is_trivial(const struct acl *aclp, int file_owner_id) +{ + int trivial; + mode_t tmpmode = 0; + struct acl *tmpaclp; + + if (aclp->acl_cnt > 6) + return (0); + + /* + * Compute the mode from the ACL, then compute new ACL from that mode. + * If the ACLs are identical, then the ACL is trivial. + * + * XXX: I guess there is a faster way to do this. However, even + * this slow implementation significantly speeds things up + * for files that don't have non-trivial ACLs - it's critical + * for performance to not use EA when they are not needed. + * + * First try the PSARC/2010/029 semantics. + */ + tmpaclp = acl_alloc(M_WAITOK | M_ZERO); + acl_nfs4_sync_mode_from_acl(&tmpmode, aclp); + acl_nfs4_trivial_from_mode(tmpaclp, tmpmode); + trivial = _acls_are_equal(aclp, tmpaclp); + if (trivial) { + acl_free(tmpaclp); + return (trivial); + } + + /* + * Check if it's a draft-ietf-nfsv4-minorversion1-03.txt trivial ACL. + */ + tmpaclp->acl_cnt = 0; + acl_nfs4_sync_acl_from_mode_draft(tmpaclp, tmpmode, file_owner_id); + trivial = _acls_are_equal(aclp, tmpaclp); + acl_free(tmpaclp); + + return (trivial); +} +#endif /* _KERNEL */ + +int +acl_nfs4_check(const struct acl *aclp, int is_directory) +{ + int i; + const struct acl_entry *entry; + + /* + * The spec doesn't seem to say anything about ACL validity. + * It seems there is not much to do here. There is even no need + * to count "owner@" or "everyone@" (ACL_USER_OBJ and ACL_EVERYONE) + * entries, as there can be several of them and that's perfectly + * valid. There can be none of them too. Really. + */ + + if (aclp->acl_cnt > ACL_MAX_ENTRIES || aclp->acl_cnt <= 0) + return (EINVAL); + + for (i = 0; i < aclp->acl_cnt; i++) { + entry = &(aclp->acl_entry[i]); + + switch (entry->ae_tag) { + case ACL_USER_OBJ: + case ACL_GROUP_OBJ: + case ACL_EVERYONE: + if (entry->ae_id != ACL_UNDEFINED_ID) + return (EINVAL); + break; + + case ACL_USER: + case ACL_GROUP: + if (entry->ae_id == ACL_UNDEFINED_ID) + return (EINVAL); + break; + + default: + return (EINVAL); + } + + if ((entry->ae_perm | ACL_NFS4_PERM_BITS) != ACL_NFS4_PERM_BITS) + return (EINVAL); + + /* + * Disallow ACL_ENTRY_TYPE_AUDIT and ACL_ENTRY_TYPE_ALARM for now. + */ + if (entry->ae_entry_type != ACL_ENTRY_TYPE_ALLOW && + entry->ae_entry_type != ACL_ENTRY_TYPE_DENY) + return (EINVAL); + + if ((entry->ae_flags | ACL_FLAGS_BITS) != ACL_FLAGS_BITS) + return (EINVAL); + + /* Disallow unimplemented flags. */ + if (entry->ae_flags & (ACL_ENTRY_SUCCESSFUL_ACCESS | + ACL_ENTRY_FAILED_ACCESS)) + return (EINVAL); + + /* Disallow flags not allowed for ordinary files. */ + if (!is_directory) { + if (entry->ae_flags & (ACL_ENTRY_FILE_INHERIT | + ACL_ENTRY_DIRECTORY_INHERIT | + ACL_ENTRY_NO_PROPAGATE_INHERIT | ACL_ENTRY_INHERIT_ONLY)) + return (EINVAL); + } + } + + return (0); +} + +#ifdef _KERNEL +static int +acl_nfs4_modload(module_t module, int what, void *arg) +{ + int ret; + + ret = 0; + + switch (what) { + case MOD_LOAD: + case MOD_SHUTDOWN: + break; + + case MOD_QUIESCE: + /* XXX TODO */ + ret = 0; + break; + + case MOD_UNLOAD: + /* XXX TODO */ + ret = 0; + break; + default: + ret = EINVAL; + break; + } + + return (ret); +} + +static moduledata_t acl_nfs4_mod = { + "acl_nfs4", + acl_nfs4_modload, + NULL +}; + +/* + * XXX TODO: which subsystem, order? + */ +DECLARE_MODULE(acl_nfs4, acl_nfs4_mod, SI_SUB_VFS, SI_ORDER_FIRST); +MODULE_VERSION(acl_nfs4, 1); +#endif /* _KERNEL */ diff --git a/lib/libc/powerpc/Makefile.inc b/lib/libc/powerpc/Makefile.inc new file mode 100644 index 0000000..2043c0a --- /dev/null +++ b/lib/libc/powerpc/Makefile.inc @@ -0,0 +1,7 @@ +# $FreeBSD: releng/11.1/lib/libc/powerpc/Makefile.inc 315044 2017-03-11 02:51:29Z brooks $ + +SRCS+= trivial-vdso_tc.c + +# Long double is 64-bits +SRCS+=machdep_ldisd.c +SYM_MAPS+=${LIBC_SRCTOP}/powerpc/Symbol.map diff --git a/lib/libc/powerpc/SYS.h b/lib/libc/powerpc/SYS.h new file mode 100644 index 0000000..a7b5b0a --- /dev/null +++ b/lib/libc/powerpc/SYS.h @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2002 Benno Rice. All rights reserved. + * Copyright (c) 2002 David E. O'Brien. 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 author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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. + * + * $NetBSD: SYS.h,v 1.8 2002/01/14 00:55:56 thorpej Exp $ + * $FreeBSD: releng/11.1/lib/libc/powerpc/SYS.h 258502 2013-11-23 18:50:43Z andreast $ + */ + +#include +#include + +#define _SYSCALL(name) \ + .text; \ + .align 2; \ + li 0,(SYS_##name); \ + sc + +#define SYSCALL(name) \ + .text; \ + .align 2; \ +2: b PIC_PLT(CNAME(HIDENAME(cerror))); \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + bso 2b + +#define PSEUDO(name) \ + .text; \ + .align 2; \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + bnslr; \ + b PIC_PLT(CNAME(HIDENAME(cerror))) + +#define RSYSCALL(name) \ + .text; \ + .align 2; \ +2: b PIC_PLT(CNAME(HIDENAME(cerror))); \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + bnslr; \ + b PIC_PLT(CNAME(HIDENAME(cerror))) diff --git a/lib/libc/powerpc/Symbol.map b/lib/libc/powerpc/Symbol.map new file mode 100644 index 0000000..53c40cc --- /dev/null +++ b/lib/libc/powerpc/Symbol.map @@ -0,0 +1,59 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/powerpc/Symbol.map 297418 2016-03-30 14:42:09Z emaste $ + */ + +/* + * This only needs to contain symbols that are not listed in + * symbol maps from other parts of libc (i.e., not found in + * stdlib/Symbol.map, string/Symbol.map, sys/Symbol.map, ...). + */ +FBSD_1.0 { + /* PSEUDO syscalls */ + _exit; + + _mcount; + _setjmp; + _longjmp; + fabs; + __flt_rounds; + fpgetmask; + fpgetround; + fpgetsticky; + fpsetmask; + fpsetround; + __infinity; + __nan; + makecontext; + setjmp; + longjmp; + sigsetjmp; + siglongjmp; + htonl; + htons; + ntohl; + ntohs; + brk; + exect; + sbrk; + vfork; +}; + +FBSD_1.3 { + __eabi; +}; + +FBSDprivate_1.0 { + /* PSEUDO syscalls */ + __sys_getlogin; + _getlogin; + __sys_exit; + + _set_tp; + _fpgetsticky; + __makecontext; + __longjmp; + signalcontext; + __signalcontext; + __syncicache; + _end; +}; diff --git a/lib/libc/powerpc/_fpmath.h b/lib/libc/powerpc/_fpmath.h new file mode 100644 index 0000000..4617118 --- /dev/null +++ b/lib/libc/powerpc/_fpmath.h @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2003 David Schultz + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/powerpc/_fpmath.h 296113 2016-02-26 20:38:23Z nwhitehorn $ + */ + +union IEEEl2bits { + long double e; + struct { +#if _BYTE_ORDER == _LITTLE_ENDIAN + unsigned int manl :32; + unsigned int manh :20; + unsigned int exp :11; + unsigned int sign :1; +#else /* _BYTE_ORDER == _LITTLE_ENDIAN */ + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; +#endif + } bits; +}; + +#define mask_nbit_l(u) ((void)0) +#define LDBL_IMPLICIT_NBIT +#define LDBL_NBIT 0 + +#define LDBL_MANH_SIZE 20 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/lib/libc/powerpc/arith.h b/lib/libc/powerpc/arith.h new file mode 100644 index 0000000..ac7e7d1 --- /dev/null +++ b/lib/libc/powerpc/arith.h @@ -0,0 +1,16 @@ +/* + * MD header for contrib/gdtoa + * + * $FreeBSD: releng/11.1/lib/libc/powerpc/arith.h 114839 2003-05-08 13:50:44Z das $ + */ + +/* + * NOTE: The definitions in this file must be correct or strtod(3) and + * floating point formats in printf(3) will break! The file can be + * generated by running contrib/gdtoa/arithchk.c on the target + * architecture. See contrib/gdtoa/gdtoaimp.h for details. + */ + +#define IEEE_MC68k +#define Arith_Kind_ASL 2 +#define Double_Align diff --git a/lib/libc/powerpc/gd_qnan.h b/lib/libc/powerpc/gd_qnan.h new file mode 100644 index 0000000..538d957 --- /dev/null +++ b/lib/libc/powerpc/gd_qnan.h @@ -0,0 +1,21 @@ +/* + * MD header for contrib/gdtoa + * + * This file can be generated by compiling and running contrib/gdtoa/qnan.c + * on the target architecture after arith.h has been generated. + * + * $FreeBSD: releng/11.1/lib/libc/powerpc/gd_qnan.h 165747 2007-01-03 05:00:03Z das $ + */ + +#define f_QNAN 0x7fc00000 +#define d_QNAN0 0x7ff80000 +#define d_QNAN1 0x0 +#define ld_QNAN0 0x7ff80000 +#define ld_QNAN1 0x0 +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x7ff8 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0x0 +#define ldus_QNAN4 0x0 diff --git a/lib/libc/powerpc/gen/Makefile.inc b/lib/libc/powerpc/gen/Makefile.inc new file mode 100644 index 0000000..f71be60 --- /dev/null +++ b/lib/libc/powerpc/gen/Makefile.inc @@ -0,0 +1,11 @@ +# $FreeBSD: releng/11.1/lib/libc/powerpc/gen/Makefile.inc 277078 2015-01-12 18:13:38Z emaste $ + +SRCS += _ctx_start.S eabi.S fabs.S flt_rounds.c fpgetmask.c fpgetround.c \ + fpgetsticky.c fpsetmask.c fpsetround.c \ + infinity.c ldexp.c makecontext.c _setjmp.S \ + setjmp.S sigsetjmp.S signalcontext.c syncicache.c \ + _set_tp.c \ + trivial-getcontextx.c + + + diff --git a/lib/libc/powerpc/gen/_ctx_start.S b/lib/libc/powerpc/gen/_ctx_start.S new file mode 100644 index 0000000..97996ec --- /dev/null +++ b/lib/libc/powerpc/gen/_ctx_start.S @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2004 Suleiman Souhlal + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + + __FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/_ctx_start.S 272362 2014-10-01 15:00:21Z bapt $"); + + .globl CNAME(_ctx_done) + .globl CNAME(abort) + + ENTRY(_ctx_start) + mtlr %r14 + blrl /* branch to start function */ + mr %r3,%r15 /* pass pointer to ucontext as argument */ + bl PIC_PLT(CNAME(_ctx_done)) /* branch to ctxt completion func */ + /* + * we should never return from the + * above branch. + */ + bl PIC_PLT(CNAME(abort)) /* abort */ + END(_cts_start) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc/gen/_set_tp.c b/lib/libc/powerpc/gen/_set_tp.c new file mode 100644 index 0000000..2c7945c --- /dev/null +++ b/lib/libc/powerpc/gen/_set_tp.c @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/powerpc/gen/_set_tp.c 288019 2015-09-20 04:59:01Z rodrigc $ + */ +#include "libc_private.h" + +void +_set_tp(void *tpval) +{ + + __asm __volatile("mr 2,%0" :: "r"((char*)tpval + 0x7008)); +} diff --git a/lib/libc/powerpc/gen/_setjmp.S b/lib/libc/powerpc/gen/_setjmp.S new file mode 100644 index 0000000..3f546c1 --- /dev/null +++ b/lib/libc/powerpc/gen/_setjmp.S @@ -0,0 +1,116 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: _setjmp.S,v 1.1 1997/03/29 20:55:53 thorpej Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/_setjmp.S 281243 2015-04-08 00:32:39Z jhibbits $"); + +/* + * C library -- _setjmp, _longjmp + * + * _longjmp(a,v) + * will generate a "return(v?v:1)" from the last call to + * _setjmp(a) + * by restoring registers from the stack. + * The previous signal state is NOT restored. + * + * jmpbuf layout: + * +------------+ + * | unused | + * +------------+ + * | unused | + * | | + * | (4 words) | + * | | + * +------------+ + * | saved regs | + * | ... | + */ + +ENTRY(_setjmp) + mflr %r11 + mfcr %r12 + mr %r10,%r1 + mr %r9,%r2 + stmw %r9,20(%r3) + + /* FPRs */ + stfd %f14,112+0*8(%r3) + stfd %f15,112+1*8(%r3) + stfd %f16,112+2*8(%r3) + stfd %f17,112+3*8(%r3) + stfd %f18,112+4*8(%r3) + stfd %f19,112+5*8(%r3) + stfd %f20,112+6*8(%r3) + stfd %f21,112+7*8(%r3) + stfd %f22,112+8*8(%r3) + stfd %f23,112+9*8(%r3) + stfd %f24,112+10*8(%r3) + stfd %f25,112+11*8(%r3) + stfd %f26,112+12*8(%r3) + stfd %f27,112+13*8(%r3) + stfd %f28,112+14*8(%r3) + stfd %f29,112+15*8(%r3) + stfd %f30,112+16*8(%r3) + stfd %f31,112+17*8(%r3) + + li %r3,0 + blr +END(_setjmp) + +ENTRY(_longjmp) + lmw %r9,20(%r3) + + /* FPRs */ + lfd %f14,112+0*8(%r3) + lfd %f15,112+1*8(%r3) + lfd %f16,112+2*8(%r3) + lfd %f17,112+3*8(%r3) + lfd %f18,112+4*8(%r3) + lfd %f19,112+5*8(%r3) + lfd %f20,112+6*8(%r3) + lfd %f21,112+7*8(%r3) + lfd %f22,112+8*8(%r3) + lfd %f23,112+9*8(%r3) + lfd %f24,112+10*8(%r3) + lfd %f25,112+11*8(%r3) + lfd %f26,112+12*8(%r3) + lfd %f27,112+13*8(%r3) + lfd %f28,112+14*8(%r3) + lfd %f29,112+15*8(%r3) + lfd %f30,112+16*8(%r3) + lfd %f31,112+17*8(%r3) + + mtlr %r11 + mtcr %r12 + mr %r1,%r10 + or. %r3,%r4,%r4 + bnelr + li %r3,1 + blr +END(_longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc/gen/eabi.S b/lib/libc/powerpc/gen/eabi.S new file mode 100644 index 0000000..330b7a8 --- /dev/null +++ b/lib/libc/powerpc/gen/eabi.S @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Marcel Moolenaar + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/eabi.S 272362 2014-10-01 15:00:21Z bapt $"); + +ENTRY(__eabi) + blr +END(__eabi) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc/gen/fabs.S b/lib/libc/powerpc/gen/fabs.S new file mode 100644 index 0000000..a7675e5 --- /dev/null +++ b/lib/libc/powerpc/gen/fabs.S @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2004 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/fabs.S 272362 2014-10-01 15:00:21Z bapt $"); + +/* + * double fabs(double) + */ +ENTRY(fabs) + fabs %f1,%f1 + blr +END(fabs) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc/gen/flt_rounds.c b/lib/libc/powerpc/gen/flt_rounds.c new file mode 100644 index 0000000..82b9a65 --- /dev/null +++ b/lib/libc/powerpc/gen/flt_rounds.c @@ -0,0 +1,56 @@ +/* $NetBSD: flt_rounds.c,v 1.4.10.3 2002/03/22 20:41:53 nathanw Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe + * 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 Mark Brinicombe + * for the NetBSD Project. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/flt_rounds.c 176530 2008-02-24 19:22:53Z raj $"); + +#include +#include + +#ifndef _SOFT_FLOAT +static const int map[] = { + 1, /* round to nearest */ + 0, /* round to zero */ + 2, /* round to positive infinity */ + 3 /* round to negative infinity */ +}; + +int +__flt_rounds() +{ + uint64_t fpscr; + + __asm__ __volatile("mffs %0" : "=f"(fpscr)); + return map[(fpscr & 0x03)]; +} +#endif diff --git a/lib/libc/powerpc/gen/fpgetmask.c b/lib/libc/powerpc/gen/fpgetmask.c new file mode 100644 index 0000000..010606d --- /dev/null +++ b/lib/libc/powerpc/gen/fpgetmask.c @@ -0,0 +1,48 @@ +/* $NetBSD: fpgetmask.c,v 1.3 2002/01/13 21:45:47 thorpej Exp $ */ + +/* + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/fpgetmask.c 204606 2010-03-02 22:11:14Z joel $"); + +#include +#include + +#ifndef _SOFT_FLOAT +fp_except_t +fpgetmask() +{ + u_int64_t fpscr; + + __asm__("mffs %0" : "=f"(fpscr)); + return ((fp_except_t)((fpscr >> 3) & 0x1f)); +} +#endif diff --git a/lib/libc/powerpc/gen/fpgetround.c b/lib/libc/powerpc/gen/fpgetround.c new file mode 100644 index 0000000..020404b --- /dev/null +++ b/lib/libc/powerpc/gen/fpgetround.c @@ -0,0 +1,48 @@ +/* $NetBSD: fpgetround.c,v 1.3 2002/01/13 21:45:47 thorpej Exp $ */ + +/* + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/fpgetround.c 204606 2010-03-02 22:11:14Z joel $"); + +#include +#include + +#ifndef _SOFT_FLOAT +fp_rnd_t +fpgetround() +{ + u_int64_t fpscr; + + __asm__("mffs %0" : "=f"(fpscr)); + return ((fp_rnd_t)(fpscr & 0x3)); +} +#endif diff --git a/lib/libc/powerpc/gen/fpgetsticky.c b/lib/libc/powerpc/gen/fpgetsticky.c new file mode 100644 index 0000000..27dafb6 --- /dev/null +++ b/lib/libc/powerpc/gen/fpgetsticky.c @@ -0,0 +1,54 @@ +/* $NetBSD: fpgetsticky.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */ + +/* + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + * + * $FreeBSD: releng/11.1/lib/libc/powerpc/gen/fpgetsticky.c 204606 2010-03-02 22:11:14Z joel $ + */ + +#include + +#include "namespace.h" + +#include +#include + +#ifndef _SOFT_FLOAT +#ifdef __weak_alias +__weak_alias(fpgetsticky,_fpgetsticky) +#endif + +fp_except_t +fpgetsticky() +{ + u_int64_t fpscr; + + __asm__ __volatile("mffs %0" : "=f"(fpscr)); + return ((fp_except_t)((fpscr >> 25) & 0x1f)); +} +#endif diff --git a/lib/libc/powerpc/gen/fpsetmask.c b/lib/libc/powerpc/gen/fpsetmask.c new file mode 100644 index 0000000..33469dd --- /dev/null +++ b/lib/libc/powerpc/gen/fpsetmask.c @@ -0,0 +1,52 @@ +/* $NetBSD: fpsetmask.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */ + +/* + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/fpsetmask.c 204606 2010-03-02 22:11:14Z joel $"); + +#include +#include + +#ifndef _SOFT_FLOAT +fp_except_t +fpsetmask(fp_except_t mask) +{ + u_int64_t fpscr; + fp_rnd_t old; + + __asm__("mffs %0" : "=f"(fpscr)); + old = (fp_rnd_t)((fpscr >> 3) & 0x1f); + fpscr = (fpscr & 0xffffff07) | (mask << 3); + __asm__ __volatile("mtfsf 0xff,%0" :: "f"(fpscr)); + return (old); +} +#endif diff --git a/lib/libc/powerpc/gen/fpsetround.c b/lib/libc/powerpc/gen/fpsetround.c new file mode 100644 index 0000000..fdcaa55 --- /dev/null +++ b/lib/libc/powerpc/gen/fpsetround.c @@ -0,0 +1,52 @@ +/* $NetBSD: fpsetround.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */ + +/* + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/fpsetround.c 204606 2010-03-02 22:11:14Z joel $"); + +#include +#include + +#ifndef _SOFT_FLOAT +fp_rnd_t +fpsetround(fp_rnd_t rnd_dir) +{ + u_int64_t fpscr; + fp_rnd_t old; + + __asm__ __volatile("mffs %0" : "=f"(fpscr)); + old = (fp_rnd_t)(fpscr & 0x3); + fpscr = (fpscr & 0xfffffffc) | rnd_dir; + __asm__ __volatile("mtfsf 0xff,%0" :: "f"(fpscr)); + return (old); +} +#endif diff --git a/lib/libc/powerpc/gen/infinity.c b/lib/libc/powerpc/gen/infinity.c new file mode 100644 index 0000000..9976424 --- /dev/null +++ b/lib/libc/powerpc/gen/infinity.c @@ -0,0 +1,30 @@ +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: infinity.c,v 1.2 1998/11/14 19:31:02 christos Exp $"); +#endif /* LIBC_SCCS and not lint */ +#endif +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/infinity.c 296113 2016-02-26 20:38:23Z nwhitehorn $"); + +/* infinity.c */ + +#include + +/* bytes for +Infinity on powerpc */ +const union __infinity_un __infinity = { +#if BYTE_ORDER == BIG_ENDIAN + { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } +#else + { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } +#endif +}; + +/* bytes for NaN */ +const union __nan_un __nan = { +#if BYTE_ORDER == BIG_ENDIAN + {0xff, 0xc0, 0, 0} +#else + { 0, 0, 0xc0, 0xff } +#endif +}; + diff --git a/lib/libc/powerpc/gen/makecontext.c b/lib/libc/powerpc/gen/makecontext.c new file mode 100644 index 0000000..bf013d1 --- /dev/null +++ b/lib/libc/powerpc/gen/makecontext.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2004 Suleiman Souhlal + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/makecontext.c 132398 2004-07-19 12:05:07Z grehan $"); + +#include + +#include +#include +#include +#include +#include + +__weak_reference(__makecontext, makecontext); + +void _ctx_done(ucontext_t *ucp); +void _ctx_start(void); + +void +_ctx_done(ucontext_t *ucp) +{ + if (ucp->uc_link == NULL) + exit(0); + else { + /* invalidate context */ + ucp->uc_mcontext.mc_len = 0; + + setcontext((const ucontext_t *)ucp->uc_link); + + abort(); /* should never return from above call */ + } +} + +void +__makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...) +{ + mcontext_t *mc; + char *sp; + va_list ap; + int i, regargs, stackargs; + + /* Sanity checks */ + if ((ucp == NULL) || (argc < 0) || (argc > NCARGS) + || (ucp->uc_stack.ss_sp == NULL) + || (ucp->uc_stack.ss_size < MINSIGSTKSZ)) { + /* invalidate context */ + ucp->uc_mcontext.mc_len = 0; + return; + } + + /* + * The stack must have space for the frame pointer, saved + * link register, overflow arguments, and be 16-byte + * aligned. + */ + stackargs = (argc > 8) ? argc - 8 : 0; + sp = (char *) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size + - sizeof(uint32_t)*(stackargs + 2); + sp = (char *)((uint32_t)sp & ~0x1f); + + mc = &ucp->uc_mcontext; + + /* + * Up to 8 register args. Assumes all args are 32-bit and + * integer only. Not sure how to cater for floating point, + * although 64-bit args will work if aligned correctly + * in the arg list. + */ + regargs = (argc > 8) ? 8 : argc; + va_start(ap, argc); + for (i = 0; i < regargs; i++) + mc->mc_gpr[3 + i] = va_arg(ap, uint32_t); + + /* + * Overflow args go onto the stack + */ + if (argc > 8) { + uint32_t *argp; + + /* Skip past frame pointer and saved LR */ + argp = (uint32_t *)sp + 2; + + for (i = 0; i < stackargs; i++) + *argp++ = va_arg(ap, uint32_t); + } + va_end(ap); + + /* + * Use caller-saved regs 14/15 to hold params that _ctx_start + * will use to invoke the user-supplied func + */ + mc->mc_srr0 = (uint32_t) _ctx_start; + mc->mc_gpr[1] = (uint32_t) sp; /* new stack pointer */ + mc->mc_gpr[14] = (uint32_t) start; /* r14 <- start */ + mc->mc_gpr[15] = (uint32_t) ucp; /* r15 <- ucp */ +} diff --git a/lib/libc/powerpc/gen/setjmp.S b/lib/libc/powerpc/gen/setjmp.S new file mode 100644 index 0000000..3aacecc --- /dev/null +++ b/lib/libc/powerpc/gen/setjmp.S @@ -0,0 +1,134 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: setjmp.S,v 1.3 1998/10/03 12:30:38 tsubai Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/setjmp.S 281243 2015-04-08 00:32:39Z jhibbits $"); + +#include + +/* + * C library -- setjmp, longjmp + * + * longjmp(a,v) + * will generate a "return(v?v:1)" from the last call to + * setjmp(a) + * by restoring registers from the stack. + * The previous signal state is restored. + * + * jmpbuf layout: + * +------------+ + * | unused | + * +------------+ + * | sig state | + * | | + * | (4 words) | + * | | + * +------------+ + * | saved regs | + * | ... | + */ + +ENTRY(setjmp) + mr %r6,%r3 + li %r3,1 /* SIG_BLOCK, but doesn't matter */ + /* since set == NULL */ + li %r4,0 /* set = NULL */ + mr %r5,%r6 /* &oset */ + addi %r5,%r5,4 + li %r0, SYS_sigprocmask /*sigprocmask(SIG_BLOCK, NULL, &oset)*/ + sc /*assume no error XXX */ + mflr %r11 /* r11 <- link reg */ + mfcr %r12 /* r12 <- condition reg */ + mr %r10,%r1 /* r10 <- stackptr */ + mr %r9,%r2 /* r9 <- global ptr */ + stmw %r9,20(%r6) + + /* FPRs */ + stfd %f14,112+0*8(%r6) + stfd %f15,112+1*8(%r6) + stfd %f16,112+2*8(%r6) + stfd %f17,112+3*8(%r6) + stfd %f18,112+4*8(%r6) + stfd %f19,112+5*8(%r6) + stfd %f20,112+6*8(%r6) + stfd %f21,112+7*8(%r6) + stfd %f22,112+8*8(%r6) + stfd %f23,112+9*8(%r6) + stfd %f24,112+10*8(%r6) + stfd %f25,112+11*8(%r6) + stfd %f26,112+12*8(%r6) + stfd %f27,112+13*8(%r6) + stfd %f28,112+14*8(%r6) + stfd %f29,112+15*8(%r6) + stfd %f30,112+16*8(%r6) + stfd %f31,112+17*8(%r6) + + li %r3,0 /* return (0) */ + blr +END(setjmp) + + WEAK_REFERENCE(CNAME(__longjmp), longjmp) +ENTRY(__longjmp) + lmw %r9,20(%r3) /* restore regs */ + + /* FPRs */ + lfd %f14,112+0*8(%r3) + lfd %f15,112+1*8(%r3) + lfd %f16,112+2*8(%r3) + lfd %f17,112+3*8(%r3) + lfd %f18,112+4*8(%r3) + lfd %f19,112+5*8(%r3) + lfd %f20,112+6*8(%r3) + lfd %f21,112+7*8(%r3) + lfd %f22,112+8*8(%r3) + lfd %f23,112+9*8(%r3) + lfd %f24,112+10*8(%r3) + lfd %f25,112+11*8(%r3) + lfd %f26,112+12*8(%r3) + lfd %f27,112+13*8(%r3) + lfd %f28,112+14*8(%r3) + lfd %f29,112+15*8(%r3) + lfd %f30,112+16*8(%r3) + lfd %f31,112+17*8(%r3) + + mr %r6,%r4 /* save val param */ + mtlr %r11 /* r11 -> link reg */ + mtcr %r12 /* r12 -> condition reg */ + mr %r1,%r10 /* r10 -> stackptr */ + mr %r4,%r3 + li %r3,3 /* SIG_SETMASK */ + addi %r4,%r4,4 /* &set */ + li %r5,0 /* oset = NULL */ + li %r0,SYS_sigprocmask /* sigprocmask(SIG_SET, &set, NULL) */ + sc /* assume no error XXX */ + or. %r3,%r6,%r6 + bnelr + li %r3,1 + blr +END(__longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc/gen/signalcontext.c b/lib/libc/powerpc/gen/signalcontext.c new file mode 100644 index 0000000..db00f48 --- /dev/null +++ b/lib/libc/powerpc/gen/signalcontext.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2004 Marcel Moolenaar, Peter Grehan + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/signalcontext.c 132399 2004-07-19 12:08:03Z grehan $"); + +#include +#include +#include +#include +#include + +typedef void (*handler_t)(uint32_t, uint32_t, uint32_t); + +/* Prototypes */ +static void ctx_wrapper(ucontext_t *ucp, handler_t func, uint32_t sig, + uint32_t sig_si, uint32_t sig_uc); + +__weak_reference(__signalcontext, signalcontext); + +int +__signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func) +{ + siginfo_t *sig_si; + ucontext_t *sig_uc; + uint32_t sp; + + /* Bail out if we don't have a valid ucontext pointer. */ + if (ucp == NULL) + abort(); + + /* + * Build a 16-byte-aligned signal frame + */ + sp = (ucp->uc_mcontext.mc_gpr[1] - sizeof(ucontext_t)) & ~15UL; + sig_uc = (ucontext_t *)sp; + bcopy(ucp, sig_uc, sizeof(*sig_uc)); + sp = (sp - sizeof(siginfo_t)) & ~15UL; + sig_si = (siginfo_t *)sp; + bzero(sig_si, sizeof(*sig_si)); + sig_si->si_signo = sig; + + /* + * Subtract 8 bytes from stack to allow for frameptr + */ + sp -= 2*sizeof(uint32_t); + sp &= ~15UL; + + /* + * Setup the ucontext of the signal handler. + */ + bzero(&ucp->uc_mcontext, sizeof(ucp->uc_mcontext)); + ucp->uc_link = sig_uc; + sigdelset(&ucp->uc_sigmask, sig); + + ucp->uc_mcontext.mc_vers = _MC_VERSION; + ucp->uc_mcontext.mc_len = sizeof(struct __mcontext); + ucp->uc_mcontext.mc_srr0 = (uint32_t) ctx_wrapper; + ucp->uc_mcontext.mc_gpr[1] = (uint32_t) sp; + ucp->uc_mcontext.mc_gpr[3] = (uint32_t) func; + ucp->uc_mcontext.mc_gpr[4] = (uint32_t) sig; + ucp->uc_mcontext.mc_gpr[5] = (uint32_t) sig_si; + ucp->uc_mcontext.mc_gpr[6] = (uint32_t) sig_uc; + + return (0); +} + +static void +ctx_wrapper(ucontext_t *ucp, handler_t func, uint32_t sig, uint32_t sig_si, + uint32_t sig_uc) +{ + + (*func)(sig, sig_si, sig_uc); + if (ucp->uc_link == NULL) + exit(0); + setcontext((const ucontext_t *)ucp->uc_link); + /* should never get here */ + abort(); + /* NOTREACHED */ +} diff --git a/lib/libc/powerpc/gen/sigsetjmp.S b/lib/libc/powerpc/gen/sigsetjmp.S new file mode 100644 index 0000000..a2d94b2 --- /dev/null +++ b/lib/libc/powerpc/gen/sigsetjmp.S @@ -0,0 +1,142 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: sigsetjmp.S,v 1.4 1998/10/03 12:30:38 tsubai Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/gen/sigsetjmp.S 281243 2015-04-08 00:32:39Z jhibbits $"); + +/* + * C library -- sigsetjmp, siglongjmp + * + * siglongjmp(a,v) + * will generate a "return(v?v:1)" from the last call to + * sigsetjmp(a, savemask) + * by restoring registers from the stack. + * The previous signal state is restored if savemask is non-zero + * + * jmpbuf layout: + * +------------+ + * | savemask | + * +------------+ + * | sig state | + * | | + * | (4 words) | + * | | + * +------------+ + * | saved regs | + * | ... | + */ + + +#include + +ENTRY(sigsetjmp) + mr %r6,%r3 + stw %r4,0(%r3) + or. %r7,%r4,%r4 + beq 1f + li %r3,1 /* SIG_BLOCK, but doesn't matter */ + /* since set == NULL */ + li %r4,0 /* set = NULL */ + mr %r5,%r6 /* &oset */ + addi %r5,%r5,4 + li %r0, SYS_sigprocmask /* sigprocmask(SIG_BLOCK, NULL, &oset)*/ + sc /* assume no error XXX */ +1: + mflr %r11 + mfcr %r12 + mr %r10,%r1 + mr %r9,%r2 + stmw %r9,20(%r6) + + /* FPRs */ + stfd %f14,112+0*8(%r6) + stfd %f15,112+1*8(%r6) + stfd %f16,112+2*8(%r6) + stfd %f17,112+3*8(%r6) + stfd %f18,112+4*8(%r6) + stfd %f19,112+5*8(%r6) + stfd %f20,112+6*8(%r6) + stfd %f21,112+7*8(%r6) + stfd %f22,112+8*8(%r6) + stfd %f23,112+9*8(%r6) + stfd %f24,112+10*8(%r6) + stfd %f25,112+11*8(%r6) + stfd %f26,112+12*8(%r6) + stfd %f27,112+13*8(%r6) + stfd %f28,112+14*8(%r6) + stfd %f29,112+15*8(%r6) + stfd %f30,112+16*8(%r6) + stfd %f31,112+17*8(%r6) + + li %r3,0 + blr +END(sigsetjmp) + +ENTRY(siglongjmp) + lmw %r9,20(%r3) + + /* FPRs */ + lfd %f14,112+0*8(%r3) + lfd %f15,112+1*8(%r3) + lfd %f16,112+2*8(%r3) + lfd %f17,112+3*8(%r3) + lfd %f18,112+4*8(%r3) + lfd %f19,112+5*8(%r3) + lfd %f20,112+6*8(%r3) + lfd %f21,112+7*8(%r3) + lfd %f22,112+8*8(%r3) + lfd %f23,112+9*8(%r3) + lfd %f24,112+10*8(%r3) + lfd %f25,112+11*8(%r3) + lfd %f26,112+12*8(%r3) + lfd %f27,112+13*8(%r3) + lfd %f28,112+14*8(%r3) + lfd %f29,112+15*8(%r3) + lfd %f30,112+16*8(%r3) + lfd %f31,112+17*8(%r3) + + lwz %r7,0(%r3) + mr %r6,%r4 + mtlr %r11 + mtcr %r12 + mr %r1,%r10 + or. %r7,%r7,%r7 + beq 1f + mr %r4,%r3 + li %r3,3 /* SIG_SETMASK */ + addi %r4,%r4,4 /* &set */ + li %r5,0 /* oset = NULL */ + li %r0,SYS_sigprocmask /* sigprocmask(SIG_SET, &set, NULL) */ + sc /* assume no error XXX */ +1: + or. %r3,%r6,%r6 + bnelr + li %r3,1 + blr +END(siglongjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc/gen/syncicache.c b/lib/libc/powerpc/gen/syncicache.c new file mode 100644 index 0000000..4f97e33 --- /dev/null +++ b/lib/libc/powerpc/gen/syncicache.c @@ -0,0 +1,103 @@ +/*- + * Copyright (C) 1995-1997, 1999 Wolfgang Solfrank. + * Copyright (C) 1995-1997, 1999 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. + * + * $NetBSD: syncicache.c,v 1.2 1999/05/05 12:36:40 tsubai Exp $ + */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD: releng/11.1/lib/libc/powerpc/gen/syncicache.c 298120 2016-04-16 17:52:00Z pfg $"; +#endif /* not lint */ + +#include +#if defined(_KERNEL) || defined(_STANDALONE) +#include +#include +#include +#endif +#include + +#include +#include + +#ifdef _STANDALONE +int cacheline_size = 32; +#endif + +#if !defined(_KERNEL) && !defined(_STANDALONE) +#include + +int cacheline_size = 0; + +static void getcachelinesize(void); + +static void +getcachelinesize() +{ + static int cachemib[] = { CTL_MACHDEP, CPU_CACHELINE }; + int clen; + + clen = sizeof(cacheline_size); + + if (sysctl(cachemib, nitems(cachemib), &cacheline_size, &clen, + NULL, 0) < 0 || !cacheline_size) { + abort(); + } +} +#endif + +void +__syncicache(void *from, int len) +{ + int l, off; + char *p; + +#if !defined(_KERNEL) && !defined(_STANDALONE) + if (!cacheline_size) + getcachelinesize(); +#endif + + off = (u_int)from & (cacheline_size - 1); + l = len += off; + p = (char *)from - off; + + do { + __asm __volatile ("dcbst 0,%0" :: "r"(p)); + p += cacheline_size; + } while ((l -= cacheline_size) > 0); + __asm __volatile ("sync"); + p = (char *)from - off; + do { + __asm __volatile ("icbi 0,%0" :: "r"(p)); + p += cacheline_size; + } while ((len -= cacheline_size) > 0); + __asm __volatile ("sync; isync"); +} + diff --git a/lib/libc/powerpc/softfloat/milieu.h b/lib/libc/powerpc/softfloat/milieu.h new file mode 100644 index 0000000..05ed8fa --- /dev/null +++ b/lib/libc/powerpc/softfloat/milieu.h @@ -0,0 +1,49 @@ +/* $NetBSD: milieu.h,v 1.1 2000/12/29 20:13:54 bjh21 Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/powerpc/softfloat/milieu.h 178620 2008-04-27 18:34:34Z marcel $ */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Include common integer types and flags. +------------------------------------------------------------------------------- +*/ +#include "powerpc-gcc.h" + +/* +------------------------------------------------------------------------------- +Symbolic Boolean literals. +------------------------------------------------------------------------------- +*/ +enum { + FALSE = 0, + TRUE = 1 +}; diff --git a/lib/libc/powerpc/softfloat/powerpc-gcc.h b/lib/libc/powerpc/softfloat/powerpc-gcc.h new file mode 100644 index 0000000..2ed5074 --- /dev/null +++ b/lib/libc/powerpc/softfloat/powerpc-gcc.h @@ -0,0 +1,92 @@ +/* $NetBSD: arm-gcc.h,v 1.2 2001/02/21 18:09:25 bjh21 Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/powerpc/softfloat/powerpc-gcc.h 178620 2008-04-27 18:34:34Z marcel $ */ + +/* +------------------------------------------------------------------------------- +One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined. +------------------------------------------------------------------------------- +*/ +#define BIGENDIAN + +/* +------------------------------------------------------------------------------- +The macro `BITS64' can be defined to indicate that 64-bit integer types are +supported by the compiler. +------------------------------------------------------------------------------- +*/ +#define BITS64 + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines the most convenient type that holds +integers of at least as many bits as specified. For example, `uint8' should +be the most convenient type that can hold unsigned integers of as many as +8 bits. The `flag' type must be able to hold either a 0 or 1. For most +implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed +to the same as `int'. +------------------------------------------------------------------------------- +*/ +typedef int flag; +typedef unsigned int uint8; +typedef int int8; +typedef unsigned int uint16; +typedef int int16; +typedef unsigned int uint32; +typedef signed int int32; +#ifdef BITS64 +typedef unsigned long long int uint64; +typedef signed long long int int64; +#endif + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines a type that holds integers +of _exactly_ the number of bits specified. For instance, for most +implementation of C, `bits16' and `sbits16' should be `typedef'ed to +`unsigned short int' and `signed short int' (or `short int'), respectively. +------------------------------------------------------------------------------- +*/ +typedef unsigned char bits8; +typedef signed char sbits8; +typedef unsigned short int bits16; +typedef signed short int sbits16; +typedef unsigned int bits32; +typedef signed int sbits32; +#ifdef BITS64 +typedef unsigned long long int bits64; +typedef signed long long int sbits64; +#endif + +#ifdef BITS64 +/* +------------------------------------------------------------------------------- +The `LIT64' macro takes as its argument a textual integer literal and +if necessary ``marks'' the literal as having a 64-bit integer type. +For example, the GNU C Compiler (`gcc') requires that 64-bit literals be +appended with the letters `LL' standing for `long long', which is `gcc's +name for the 64-bit integer type. Some compilers may allow `LIT64' to be +defined as the identity macro: `#define LIT64( a ) a'. +------------------------------------------------------------------------------- +*/ +#define LIT64( a ) a##LL +#endif + +/* +------------------------------------------------------------------------------- +The macro `INLINE' can be used before functions that should be inlined. If +a compiler does not support explicit inlining, this macro should be defined +to be `static'. +------------------------------------------------------------------------------- +*/ +#define INLINE static __inline + +/* +------------------------------------------------------------------------------- +The ARM FPA is odd in that it stores doubles high-order word first, no matter +what the endianness of the CPU. VFP is sane. +------------------------------------------------------------------------------- +*/ +#if defined(SOFTFLOAT_FOR_GCC) +#define FLOAT64_DEMANGLE(a) (a) +#define FLOAT64_MANGLE(a) (a) +#endif diff --git a/lib/libc/powerpc/softfloat/softfloat.h b/lib/libc/powerpc/softfloat/softfloat.h new file mode 100644 index 0000000..daa625a --- /dev/null +++ b/lib/libc/powerpc/softfloat/softfloat.h @@ -0,0 +1,307 @@ +/* $NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/powerpc/softfloat/softfloat.h 178620 2008-04-27 18:34:34Z marcel $ */ + +/* This is a derivative work. */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +The macro `FLOATX80' must be defined to enable the extended double-precision +floating-point format `floatx80'. If this macro is not defined, the +`floatx80' type will not be defined, and none of the functions that either +input or output the `floatx80' type will be defined. The same applies to +the `FLOAT128' macro and the quadruple-precision format `float128'. +------------------------------------------------------------------------------- +*/ +/* #define FLOATX80 */ +/* #define FLOAT128 */ + +#include + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point types. +------------------------------------------------------------------------------- +*/ +typedef unsigned int float32; +typedef unsigned long long float64; +#ifdef FLOATX80 +typedef struct { + unsigned short high; + unsigned long long low; +} floatx80; +#endif +#ifdef FLOAT128 +typedef struct { + unsigned long long high, low; +} float128; +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point underflow tininess-detection mode. +------------------------------------------------------------------------------- +*/ +#ifndef SOFTFLOAT_FOR_GCC +extern int8 float_detect_tininess; +#endif +enum { + float_tininess_after_rounding = 0, + float_tininess_before_rounding = 1 +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point rounding mode. +------------------------------------------------------------------------------- +*/ +extern fp_rnd_t float_rounding_mode; +enum { + float_round_nearest_even = FP_RN, + float_round_to_zero = FP_RZ, + float_round_down = FP_RM, + float_round_up = FP_RP +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point exception flags. +------------------------------------------------------------------------------- +*/ +typedef fp_except_t fp_except; + +extern fp_except float_exception_flags; +extern fp_except float_exception_mask; +enum { + float_flag_inexact = FP_X_IMP, + float_flag_underflow = FP_X_UFL, + float_flag_overflow = FP_X_OFL, + float_flag_divbyzero = FP_X_DZ, + float_flag_invalid = FP_X_INV +}; + +/* +------------------------------------------------------------------------------- +Routine to raise any or all of the software IEC/IEEE floating-point +exception flags. +------------------------------------------------------------------------------- +*/ +void float_raise( fp_except ); + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE integer-to-floating-point conversion routines. +------------------------------------------------------------------------------- +*/ +float32 int32_to_float32( int ); +float64 int32_to_float64( int ); +#ifdef FLOATX80 +floatx80 int32_to_floatx80( int ); +#endif +#ifdef FLOAT128 +float128 int32_to_float128( int ); +#endif +float32 int64_to_float32( long long ); +float64 int64_to_float64( long long ); +#ifdef FLOATX80 +floatx80 int64_to_floatx80( long long ); +#endif +#ifdef FLOAT128 +float128 int64_to_float128( long long ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float32_to_int32( float32 ); +int float32_to_int32_round_to_zero( float32 ); +unsigned int float32_to_uint32_round_to_zero( float32 ); +long long float32_to_int64( float32 ); +long long float32_to_int64_round_to_zero( float32 ); +float64 float32_to_float64( float32 ); +#ifdef FLOATX80 +floatx80 float32_to_floatx80( float32 ); +#endif +#ifdef FLOAT128 +float128 float32_to_float128( float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision operations. +------------------------------------------------------------------------------- +*/ +float32 float32_round_to_int( float32 ); +float32 float32_add( float32, float32 ); +float32 float32_sub( float32, float32 ); +float32 float32_mul( float32, float32 ); +float32 float32_div( float32, float32 ); +float32 float32_rem( float32, float32 ); +float32 float32_sqrt( float32 ); +int float32_eq( float32, float32 ); +int float32_le( float32, float32 ); +int float32_lt( float32, float32 ); +int float32_eq_signaling( float32, float32 ); +int float32_le_quiet( float32, float32 ); +int float32_lt_quiet( float32, float32 ); +#ifndef SOFTFLOAT_FOR_GCC +int float32_is_signaling_nan( float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float64_to_int32( float64 ); +int float64_to_int32_round_to_zero( float64 ); +unsigned int float64_to_uint32_round_to_zero( float64 ); +long long float64_to_int64( float64 ); +long long float64_to_int64_round_to_zero( float64 ); +float32 float64_to_float32( float64 ); +#ifdef FLOATX80 +floatx80 float64_to_floatx80( float64 ); +#endif +#ifdef FLOAT128 +float128 float64_to_float128( float64 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision operations. +------------------------------------------------------------------------------- +*/ +float64 float64_round_to_int( float64 ); +float64 float64_add( float64, float64 ); +float64 float64_sub( float64, float64 ); +float64 float64_mul( float64, float64 ); +float64 float64_div( float64, float64 ); +float64 float64_rem( float64, float64 ); +float64 float64_sqrt( float64 ); +int float64_eq( float64, float64 ); +int float64_le( float64, float64 ); +int float64_lt( float64, float64 ); +int float64_eq_signaling( float64, float64 ); +int float64_le_quiet( float64, float64 ); +int float64_lt_quiet( float64, float64 ); +#ifndef SOFTFLOAT_FOR_GCC +int float64_is_signaling_nan( float64 ); +#endif + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int floatx80_to_int32( floatx80 ); +int floatx80_to_int32_round_to_zero( floatx80 ); +long long floatx80_to_int64( floatx80 ); +long long floatx80_to_int64_round_to_zero( floatx80 ); +float32 floatx80_to_float32( floatx80 ); +float64 floatx80_to_float64( floatx80 ); +#ifdef FLOAT128 +float128 floatx80_to_float128( floatx80 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision rounding precision. Valid +values are 32, 64, and 80. +------------------------------------------------------------------------------- +*/ +extern int floatx80_rounding_precision; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision operations. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_round_to_int( floatx80 ); +floatx80 floatx80_add( floatx80, floatx80 ); +floatx80 floatx80_sub( floatx80, floatx80 ); +floatx80 floatx80_mul( floatx80, floatx80 ); +floatx80 floatx80_div( floatx80, floatx80 ); +floatx80 floatx80_rem( floatx80, floatx80 ); +floatx80 floatx80_sqrt( floatx80 ); +int floatx80_eq( floatx80, floatx80 ); +int floatx80_le( floatx80, floatx80 ); +int floatx80_lt( floatx80, floatx80 ); +int floatx80_eq_signaling( floatx80, floatx80 ); +int floatx80_le_quiet( floatx80, floatx80 ); +int floatx80_lt_quiet( floatx80, floatx80 ); +int floatx80_is_signaling_nan( floatx80 ); + +#endif + +#ifdef FLOAT128 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE quadruple-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float128_to_int32( float128 ); +int float128_to_int32_round_to_zero( float128 ); +long long float128_to_int64( float128 ); +long long float128_to_int64_round_to_zero( float128 ); +float32 float128_to_float32( float128 ); +float64 float128_to_float64( float128 ); +#ifdef FLOATX80 +floatx80 float128_to_floatx80( float128 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE quadruple-precision operations. +------------------------------------------------------------------------------- +*/ +float128 float128_round_to_int( float128 ); +float128 float128_add( float128, float128 ); +float128 float128_sub( float128, float128 ); +float128 float128_mul( float128, float128 ); +float128 float128_div( float128, float128 ); +float128 float128_rem( float128, float128 ); +float128 float128_sqrt( float128 ); +int float128_eq( float128, float128 ); +int float128_le( float128, float128 ); +int float128_lt( float128, float128 ); +int float128_eq_signaling( float128, float128 ); +int float128_le_quiet( float128, float128 ); +int float128_lt_quiet( float128, float128 ); +int float128_is_signaling_nan( float128 ); + +#endif + diff --git a/lib/libc/powerpc/sys/Makefile.inc b/lib/libc/powerpc/sys/Makefile.inc new file mode 100644 index 0000000..6471f35 --- /dev/null +++ b/lib/libc/powerpc/sys/Makefile.inc @@ -0,0 +1,8 @@ +# $FreeBSD: releng/11.1/lib/libc/powerpc/sys/Makefile.inc 305329 2016-09-03 09:03:40Z kib $ + +MDASM+= brk.S cerror.S exect.S sbrk.S setlogin.S + +# Don't generate default code for these syscalls: +NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o yield.o + +PSEUDO= _getlogin.o _exit.o diff --git a/lib/libc/powerpc/sys/brk.S b/lib/libc/powerpc/sys/brk.S new file mode 100644 index 0000000..a362af5 --- /dev/null +++ b/lib/libc/powerpc/sys/brk.S @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: brk.S,v 1.9 2000/06/26 06:25:43 kleink Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/sys/brk.S 272362 2014-10-01 15:00:21Z bapt $"); + +#include "SYS.h" + + .globl HIDENAME(curbrk) + .globl HIDENAME(minbrk) + .globl CNAME(_end) + + .data +HIDENAME(minbrk): + .long CNAME(_end) + + .text + +ENTRY(brk) +#ifdef PIC + mflr %r10 + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr %r9 + mtlr %r10 + lwz %r5,HIDENAME(minbrk)@got(%r9) + lwz %r6,0(%r5) +#else + lis %r5,HIDENAME(minbrk)@ha + lwz %r6,HIDENAME(minbrk)@l(%r5) +#endif + cmplw %r6,%r3 /* if (minbrk <= r3) */ + bgt 0f + mr %r6,%r3 /* r6 = r3 */ +0: + mr %r3,%r6 /* new break value */ + li %r0,SYS_break + sc /* assume, that r5 is kept */ + bso 1f +#ifdef PIC + lwz %r7,HIDENAME(curbrk)@got(%r9) + stw %r6,0(%r7) +#else + lis %r7,HIDENAME(curbrk)@ha /* record new break */ + stw %r6,HIDENAME(curbrk)@l(%r7) +#endif + blr /* return 0 */ + +1: + b PIC_PLT(HIDENAME(cerror)) +END(brk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc/sys/cerror.S b/lib/libc/powerpc/sys/cerror.S new file mode 100644 index 0000000..caa879a --- /dev/null +++ b/lib/libc/powerpc/sys/cerror.S @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: cerror.S,v 1.5 2000/01/27 14:58:48 kleink Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/sys/cerror.S 217398 2011-01-14 11:33:40Z kib $"); + +#include "SYS.h" + + .globl HIDENAME(cerror) + .globl CNAME(__error) + + /* + * The __error() function is thread aware. For non-threaded + * programs and the initial threaded in threaded programs, + * it returns a pointer to the global errno variable. + */ +HIDENAME(cerror): + mflr %r0 + stwu %r1,-16(%r1) /* allocate new stack frame */ + stw %r0,20(%r1) /* and save lr, r31 */ + stw %r31,8(%r1) + mr %r31,%r3 /* stash errval in callee-saved register */ + bl PIC_PLT(CNAME(__error)) + stw %r31,0(%r3) /* store errval into &errno */ + lwz %r0,20(%r1) + lwz %r31,8(%r1) + mtlr %r0 + la %r1,16(%r1) + li %r3,-1 + li %r4,-1 + blr /* return to callers caller */ + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc/sys/exect.S b/lib/libc/powerpc/sys/exect.S new file mode 100644 index 0000000..3183d9e --- /dev/null +++ b/lib/libc/powerpc/sys/exect.S @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: exect.S,v 1.3 1998/05/25 15:28:03 ws Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/sys/exect.S 272362 2014-10-01 15:00:21Z bapt $"); + +#include "SYS.h" + +ENTRY(exect) + li %r0,SYS_execve + sc + bso 1f + blr +1: + b PIC_PLT(HIDENAME(cerror)) +END(exect) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc/sys/sbrk.S b/lib/libc/powerpc/sys/sbrk.S new file mode 100644 index 0000000..f6d58b3 --- /dev/null +++ b/lib/libc/powerpc/sys/sbrk.S @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: sbrk.S,v 1.8 2000/06/26 06:25:44 kleink Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/sys/sbrk.S 272362 2014-10-01 15:00:21Z bapt $"); + +#include "SYS.h" + + .globl HIDENAME(curbrk) + .globl CNAME(_end) + + .data +HIDENAME(curbrk): + .long CNAME(_end) + + .text +ENTRY(sbrk) + +#ifdef PIC + mflr %r10 + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr %r5 + mtlr %r10 + lwz %r5,HIDENAME(curbrk)@got(%r5) + lwz %r6,0(%r5) +#else + lis %r5,HIDENAME(curbrk)@ha + lwz %r6,HIDENAME(curbrk)@l(%r5) /* r6 = old break */ +#endif + cmpwi %r3,0 /* sbrk(0) - return curbrk */ + beq 1f + add %r3,%r3,%r6 + mr %r7,%r3 /* r7 = new break */ + li %r0,SYS_break + sc /* break(new_break) */ + bso 2f +#ifdef PIC + stw %r7,0(%r5) +#else + stw %r7,HIDENAME(curbrk)@l(%r5) /* record new break */ +#endif +1: + mr %r3,%r6 /* set return value */ + blr +2: + b PIC_PLT(HIDENAME(cerror)) +END(sbrk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc/sys/setlogin.S b/lib/libc/powerpc/sys/setlogin.S new file mode 100644 index 0000000..e385f9c --- /dev/null +++ b/lib/libc/powerpc/sys/setlogin.S @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: setlogin.S,v 1.3 1998/11/24 11:14:57 tsubai Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc/sys/setlogin.S 217398 2011-01-14 11:33:40Z kib $"); + +#include "SYS.h" + + .globl CNAME(_logname_valid) /* in _getlogin() */ + +SYSCALL(setlogin) +#ifdef PIC + mflr %r10 + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr %r4 + lwz %r4,CNAME(_logname_valid)@got(%r4) + li %r5,%r0 + stw %r5,0(%r4) + mtlr %r10 +#else + lis %r4,CNAME(_logname_valid)@ha + li %r5,0 + stw %r5,CNAME(_logname_valid)@l(%r4) +#endif + blr + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc64/Makefile.inc b/lib/libc/powerpc64/Makefile.inc new file mode 100644 index 0000000..ff9b4b8 --- /dev/null +++ b/lib/libc/powerpc64/Makefile.inc @@ -0,0 +1,7 @@ +# $FreeBSD: releng/11.1/lib/libc/powerpc64/Makefile.inc 315044 2017-03-11 02:51:29Z brooks $ + +SRCS+= trivial-vdso_tc.c + +# Long double is 64-bits +SRCS+=machdep_ldisd.c +SYM_MAPS+=${LIBC_SRCTOP}/powerpc64/Symbol.map diff --git a/lib/libc/powerpc64/SYS.h b/lib/libc/powerpc64/SYS.h new file mode 100644 index 0000000..f291f04 --- /dev/null +++ b/lib/libc/powerpc64/SYS.h @@ -0,0 +1,94 @@ +/*- + * Copyright (c) 2002 Benno Rice. All rights reserved. + * Copyright (c) 2002 David E. O'Brien. 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 author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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. + * + * $NetBSD: SYS.h,v 1.8 2002/01/14 00:55:56 thorpej Exp $ + * $FreeBSD: releng/11.1/lib/libc/powerpc64/SYS.h 258502 2013-11-23 18:50:43Z andreast $ + */ + +#include +#include + +#define _SYSCALL(name) \ + .text; \ + .align 2; \ + li 0,(SYS_##name); \ + sc + +#define SYSCALL(name) \ + .text; \ + .align 2; \ +2: mflr %r0; \ + std %r0,16(%r1); \ + stdu %r1,-48(%r1); \ + bl CNAME(HIDENAME(cerror)); \ + nop; \ + addi %r1,%r1,48; \ + ld %r0,16(%r1); \ + mtlr %r0; \ + blr; \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + bso 2b + +#define PSEUDO(name) \ + .text; \ + .align 2; \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + bnslr; \ + mflr %r0; \ + std %r0,16(%r1); \ + stdu %r1,-48(%r1); \ + bl CNAME(HIDENAME(cerror)); \ + nop; \ + addi %r1,%r1,48; \ + ld %r0,16(%r1); \ + mtlr %r0; \ + blr; + +#define RSYSCALL(name) \ + .text; \ + .align 2; \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + bnslr; \ + \ + mflr %r0; \ + std %r0,16(%r1); \ + stdu %r1,-48(%r1); \ + bl CNAME(HIDENAME(cerror)); \ + nop; \ + addi %r1,%r1,48; \ + ld %r0,16(%r1); \ + mtlr %r0; \ + blr; diff --git a/lib/libc/powerpc64/Symbol.map b/lib/libc/powerpc64/Symbol.map new file mode 100644 index 0000000..c453c6e --- /dev/null +++ b/lib/libc/powerpc64/Symbol.map @@ -0,0 +1,55 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/powerpc64/Symbol.map 297418 2016-03-30 14:42:09Z emaste $ + */ + +/* + * This only needs to contain symbols that are not listed in + * symbol maps from other parts of libc (i.e., not found in + * stdlib/Symbol.map, string/Symbol.map, sys/Symbol.map, ...). + */ +FBSD_1.0 { + /* PSEUDO syscalls */ + _exit; + + _mcount; + _setjmp; + _longjmp; + fabs; + __flt_rounds; + fpgetmask; + fpgetround; + fpgetsticky; + fpsetmask; + fpsetround; + __infinity; + __nan; + makecontext; + setjmp; + longjmp; + sigsetjmp; + siglongjmp; + htonl; + htons; + ntohl; + ntohs; + brk; + exect; + sbrk; + vfork; +}; + +FBSDprivate_1.0 { + /* PSEUDO syscalls */ + __sys_getlogin; + _getlogin; + __sys_exit; + + _set_tp; + _fpgetsticky; + __makecontext; + __longjmp; + signalcontext; + __signalcontext; + __syncicache; + _end; +}; diff --git a/lib/libc/powerpc64/_fpmath.h b/lib/libc/powerpc64/_fpmath.h new file mode 100644 index 0000000..7b265ff --- /dev/null +++ b/lib/libc/powerpc64/_fpmath.h @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2003 David Schultz + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/powerpc64/_fpmath.h 296113 2016-02-26 20:38:23Z nwhitehorn $ + */ + +union IEEEl2bits { + long double e; + struct { +#if _BYTE_ORDER == _LITTLE_ENDIAN + unsigned int manl :32; + unsigned int manh :20; + unsigned int exp :11; + unsigned int sign :1; +#else /* _BYTE_ORDER == _LITTLE_ENDIAN */ + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; +#endif + } bits; +}; + +#define mask_nbit_l(u) ((void)0) +#define LDBL_IMPLICIT_NBIT +#define LDBL_NBIT 0 + +#define LDBL_MANH_SIZE 20 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/lib/libc/powerpc64/arith.h b/lib/libc/powerpc64/arith.h new file mode 100644 index 0000000..9e8ad4a --- /dev/null +++ b/lib/libc/powerpc64/arith.h @@ -0,0 +1,16 @@ +/* + * MD header for contrib/gdtoa + * + * $FreeBSD: releng/11.1/lib/libc/powerpc64/arith.h 209878 2010-07-10 14:45:03Z nwhitehorn $ + */ + +/* + * NOTE: The definitions in this file must be correct or strtod(3) and + * floating point formats in printf(3) will break! The file can be + * generated by running contrib/gdtoa/arithchk.c on the target + * architecture. See contrib/gdtoa/gdtoaimp.h for details. + */ + +#define IEEE_MC68k +#define Arith_Kind_ASL 2 +#define Double_Align diff --git a/lib/libc/powerpc64/gd_qnan.h b/lib/libc/powerpc64/gd_qnan.h new file mode 100644 index 0000000..2a89989 --- /dev/null +++ b/lib/libc/powerpc64/gd_qnan.h @@ -0,0 +1,21 @@ +/* + * MD header for contrib/gdtoa + * + * This file can be generated by compiling and running contrib/gdtoa/qnan.c + * on the target architecture after arith.h has been generated. + * + * $FreeBSD: releng/11.1/lib/libc/powerpc64/gd_qnan.h 209878 2010-07-10 14:45:03Z nwhitehorn $ + */ + +#define f_QNAN 0x7fc00000 +#define d_QNAN0 0x7ff80000 +#define d_QNAN1 0x0 +#define ld_QNAN0 0x7ff80000 +#define ld_QNAN1 0x0 +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x7ff8 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0x0 +#define ldus_QNAN4 0x0 diff --git a/lib/libc/powerpc64/gen/Makefile.inc b/lib/libc/powerpc64/gen/Makefile.inc new file mode 100644 index 0000000..128dc82 --- /dev/null +++ b/lib/libc/powerpc64/gen/Makefile.inc @@ -0,0 +1,10 @@ +# $FreeBSD: releng/11.1/lib/libc/powerpc64/gen/Makefile.inc 277078 2015-01-12 18:13:38Z emaste $ + +SRCS += _ctx_start.S fabs.S flt_rounds.c fpgetmask.c fpgetround.c \ + fpgetsticky.c fpsetmask.c fpsetround.c \ + infinity.c ldexp.c makecontext.c _setjmp.S \ + setjmp.S sigsetjmp.S signalcontext.c syncicache.c \ + _set_tp.c \ + trivial-getcontextx.c + + diff --git a/lib/libc/powerpc64/gen/_ctx_start.S b/lib/libc/powerpc64/gen/_ctx_start.S new file mode 100644 index 0000000..aeac46b --- /dev/null +++ b/lib/libc/powerpc64/gen/_ctx_start.S @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2004 Suleiman Souhlal + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + + __FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/_ctx_start.S 272362 2014-10-01 15:00:21Z bapt $"); + + .globl CNAME(_ctx_done) + .globl CNAME(abort) + + ENTRY(_ctx_start) + ld %r2,8(%r14) + ld %r14,0(%r14) + mtlr %r14 + blrl /* branch to start function */ + mr %r3,%r15 /* pass pointer to ucontext as argument */ + nop + bl CNAME(_ctx_done) /* branch to ctxt completion func */ + /* + * we should never return from the + * above branch. + */ + nop + bl CNAME(abort) /* abort */ + nop + END(_ctx_start) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc64/gen/_set_tp.c b/lib/libc/powerpc64/gen/_set_tp.c new file mode 100644 index 0000000..19ae7de --- /dev/null +++ b/lib/libc/powerpc64/gen/_set_tp.c @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/powerpc64/gen/_set_tp.c 288019 2015-09-20 04:59:01Z rodrigc $ + */ +#include "libc_private.h" + +void +_set_tp(void *tpval) +{ + + __asm __volatile("mr 13,%0" :: "r"((char*)tpval + 0x7010)); +} diff --git a/lib/libc/powerpc64/gen/_setjmp.S b/lib/libc/powerpc64/gen/_setjmp.S new file mode 100644 index 0000000..599f1da --- /dev/null +++ b/lib/libc/powerpc64/gen/_setjmp.S @@ -0,0 +1,155 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: _setjmp.S,v 1.1 1997/03/29 20:55:53 thorpej Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/_setjmp.S 279784 2015-03-08 19:37:08Z nwhitehorn $"); + +/* + * C library -- _setjmp, _longjmp + * + * _longjmp(a,v) + * will generate a "return(v?v:1)" from the last call to + * _setjmp(a) + * by restoring registers from the stack. + * The previous signal state is NOT restored. + * + * jmpbuf layout: + * +------------+ + * | unused | + * +------------+ + * | unused | + * | | + * | (4 words) | + * | | + * +------------+ + * | saved regs | + * | ... | + */ + +ENTRY(_setjmp) + mflr %r11 + mfcr %r12 + mr %r10,%r1 + mr %r9,%r2 + std %r9,40 + 0*8(%r3) + stfd %f14,40 + 23*8(%r3) + std %r10,40 + 1*8(%r3) + stfd %f15,40 + 24*8(%r3) + std %r11,40 + 2*8(%r3) + stfd %f16,40 + 25*8(%r3) + std %r12,40 + 3*8(%r3) + stfd %f17,40 + 26*8(%r3) + std %r13,40 + 4*8(%r3) + stfd %f18,40 + 27*8(%r3) + std %r14,40 + 5*8(%r3) + stfd %f19,40 + 28*8(%r3) + std %r15,40 + 6*8(%r3) + stfd %f20,40 + 29*8(%r3) + std %r16,40 + 7*8(%r3) + stfd %f21,40 + 30*8(%r3) + std %r17,40 + 8*8(%r3) + stfd %f22,40 + 31*8(%r3) + std %r18,40 + 9*8(%r3) + stfd %f23,40 + 32*8(%r3) + std %r19,40 + 10*8(%r3) + stfd %f24,40 + 33*8(%r3) + std %r20,40 + 11*8(%r3) + stfd %f25,40 + 34*8(%r3) + std %r21,40 + 12*8(%r3) + stfd %f26,40 + 35*8(%r3) + std %r22,40 + 13*8(%r3) + stfd %f27,40 + 36*8(%r3) + std %r23,40 + 14*8(%r3) + stfd %f28,40 + 37*8(%r3) + std %r24,40 + 15*8(%r3) + stfd %f29,40 + 38*8(%r3) + std %r25,40 + 16*8(%r3) + stfd %f30,40 + 39*8(%r3) + std %r26,40 + 17*8(%r3) + stfd %f31,40 + 40*8(%r3) + std %r27,40 + 18*8(%r3) + std %r28,40 + 19*8(%r3) + std %r29,40 + 20*8(%r3) + std %r30,40 + 21*8(%r3) + std %r31,40 + 22*8(%r3) + li %r3,0 + blr +END(_setjmp) + +ENTRY(_longjmp) + ld %r9,40 + 0*8(%r3) + lfd %f14,40 + 23*8(%r3) + ld %r10,40 + 1*8(%r3) + lfd %f15,40 + 24*8(%r3) + ld %r11,40 + 2*8(%r3) + lfd %f16,40 + 25*8(%r3) + ld %r12,40 + 3*8(%r3) + lfd %f17,40 + 26*8(%r3) + ld %r14,40 + 5*8(%r3) + lfd %f18,40 + 27*8(%r3) + ld %r15,40 + 6*8(%r3) + lfd %f19,40 + 28*8(%r3) + ld %r16,40 + 7*8(%r3) + lfd %f20,40 + 29*8(%r3) + ld %r17,40 + 8*8(%r3) + lfd %f21,40 + 30*8(%r3) + ld %r18,40 + 9*8(%r3) + lfd %f22,40 + 31*8(%r3) + ld %r19,40 + 10*8(%r3) + lfd %f23,40 + 32*8(%r3) + ld %r20,40 + 11*8(%r3) + lfd %f24,40 + 33*8(%r3) + ld %r21,40 + 12*8(%r3) + lfd %f25,40 + 34*8(%r3) + ld %r22,40 + 13*8(%r3) + lfd %f26,40 + 35*8(%r3) + ld %r23,40 + 14*8(%r3) + lfd %f27,40 + 36*8(%r3) + ld %r24,40 + 15*8(%r3) + lfd %f28,40 + 37*8(%r3) + ld %r25,40 + 16*8(%r3) + lfd %f29,40 + 38*8(%r3) + ld %r26,40 + 17*8(%r3) + lfd %f30,40 + 39*8(%r3) + ld %r27,40 + 18*8(%r3) + lfd %f31,40 + 40*8(%r3) + ld %r28,40 + 19*8(%r3) + ld %r29,40 + 20*8(%r3) + ld %r30,40 + 21*8(%r3) + ld %r31,40 + 22*8(%r3) + + mtlr %r11 + mtcr %r12 + mr %r2,%r9 + mr %r1,%r10 + or. %r3,%r4,%r4 + bnelr + li %r3,1 + blr +END(_longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc64/gen/fabs.S b/lib/libc/powerpc64/gen/fabs.S new file mode 100644 index 0000000..97b9779 --- /dev/null +++ b/lib/libc/powerpc64/gen/fabs.S @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2004 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/fabs.S 272362 2014-10-01 15:00:21Z bapt $"); + +/* + * double fabs(double) + */ +ENTRY(fabs) + fabs %f1,%f1 + blr +END(fabs) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc64/gen/flt_rounds.c b/lib/libc/powerpc64/gen/flt_rounds.c new file mode 100644 index 0000000..d6e9412 --- /dev/null +++ b/lib/libc/powerpc64/gen/flt_rounds.c @@ -0,0 +1,56 @@ +/* $NetBSD: flt_rounds.c,v 1.4.10.3 2002/03/22 20:41:53 nathanw Exp $ */ + +/* + * Copyright (c) 1996 Mark Brinicombe + * 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 Mark Brinicombe + * for the NetBSD Project. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/flt_rounds.c 209878 2010-07-10 14:45:03Z nwhitehorn $"); + +#include +#include + +#ifndef _SOFT_FLOAT +static const int map[] = { + 1, /* round to nearest */ + 0, /* round to zero */ + 2, /* round to positive infinity */ + 3 /* round to negative infinity */ +}; + +int +__flt_rounds() +{ + uint64_t fpscr; + + __asm__ __volatile("mffs %0" : "=f"(fpscr)); + return map[(fpscr & 0x03)]; +} +#endif diff --git a/lib/libc/powerpc64/gen/fpgetmask.c b/lib/libc/powerpc64/gen/fpgetmask.c new file mode 100644 index 0000000..9ef3600 --- /dev/null +++ b/lib/libc/powerpc64/gen/fpgetmask.c @@ -0,0 +1,48 @@ +/* $NetBSD: fpgetmask.c,v 1.3 2002/01/13 21:45:47 thorpej Exp $ */ + +/* + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/fpgetmask.c 251091 2013-05-29 01:54:10Z emaste $"); + +#include +#include + +#ifndef _SOFT_FLOAT +fp_except_t +fpgetmask() +{ + u_int64_t fpscr; + + __asm__("mffs %0" : "=f"(fpscr)); + return ((fp_except_t)((fpscr >> 3) & 0x1f)); +} +#endif diff --git a/lib/libc/powerpc64/gen/fpgetround.c b/lib/libc/powerpc64/gen/fpgetround.c new file mode 100644 index 0000000..4ae077a --- /dev/null +++ b/lib/libc/powerpc64/gen/fpgetround.c @@ -0,0 +1,48 @@ +/* $NetBSD: fpgetround.c,v 1.3 2002/01/13 21:45:47 thorpej Exp $ */ + +/* + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/fpgetround.c 251091 2013-05-29 01:54:10Z emaste $"); + +#include +#include + +#ifndef _SOFT_FLOAT +fp_rnd_t +fpgetround() +{ + u_int64_t fpscr; + + __asm__("mffs %0" : "=f"(fpscr)); + return ((fp_rnd_t)(fpscr & 0x3)); +} +#endif diff --git a/lib/libc/powerpc64/gen/fpgetsticky.c b/lib/libc/powerpc64/gen/fpgetsticky.c new file mode 100644 index 0000000..0062133 --- /dev/null +++ b/lib/libc/powerpc64/gen/fpgetsticky.c @@ -0,0 +1,54 @@ +/* $NetBSD: fpgetsticky.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */ + +/* + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + * + * $FreeBSD: releng/11.1/lib/libc/powerpc64/gen/fpgetsticky.c 251091 2013-05-29 01:54:10Z emaste $ + */ + +#include + +#include "namespace.h" + +#include +#include + +#ifndef _SOFT_FLOAT +#ifdef __weak_alias +__weak_alias(fpgetsticky,_fpgetsticky) +#endif + +fp_except_t +fpgetsticky() +{ + u_int64_t fpscr; + + __asm__ __volatile("mffs %0" : "=f"(fpscr)); + return ((fp_except_t)((fpscr >> 25) & 0x1f)); +} +#endif diff --git a/lib/libc/powerpc64/gen/fpsetmask.c b/lib/libc/powerpc64/gen/fpsetmask.c new file mode 100644 index 0000000..98d837b --- /dev/null +++ b/lib/libc/powerpc64/gen/fpsetmask.c @@ -0,0 +1,52 @@ +/* $NetBSD: fpsetmask.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */ + +/* + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/fpsetmask.c 251091 2013-05-29 01:54:10Z emaste $"); + +#include +#include + +#ifndef _SOFT_FLOAT +fp_except_t +fpsetmask(fp_except_t mask) +{ + u_int64_t fpscr; + fp_rnd_t old; + + __asm__("mffs %0" : "=f"(fpscr)); + old = (fp_rnd_t)((fpscr >> 3) & 0x1f); + fpscr = (fpscr & 0xffffff07) | (mask << 3); + __asm__ __volatile("mtfsf 0xff,%0" :: "f"(fpscr)); + return (old); +} +#endif diff --git a/lib/libc/powerpc64/gen/fpsetround.c b/lib/libc/powerpc64/gen/fpsetround.c new file mode 100644 index 0000000..fe3454c --- /dev/null +++ b/lib/libc/powerpc64/gen/fpsetround.c @@ -0,0 +1,52 @@ +/* $NetBSD: fpsetround.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */ + +/* + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/fpsetround.c 251091 2013-05-29 01:54:10Z emaste $"); + +#include +#include + +#ifndef _SOFT_FLOAT +fp_rnd_t +fpsetround(fp_rnd_t rnd_dir) +{ + u_int64_t fpscr; + fp_rnd_t old; + + __asm__ __volatile("mffs %0" : "=f"(fpscr)); + old = (fp_rnd_t)(fpscr & 0x3); + fpscr = (fpscr & 0xfffffffc) | rnd_dir; + __asm__ __volatile("mtfsf 0xff,%0" :: "f"(fpscr)); + return (old); +} +#endif diff --git a/lib/libc/powerpc64/gen/infinity.c b/lib/libc/powerpc64/gen/infinity.c new file mode 100644 index 0000000..ca990ff --- /dev/null +++ b/lib/libc/powerpc64/gen/infinity.c @@ -0,0 +1,30 @@ +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: infinity.c,v 1.2 1998/11/14 19:31:02 christos Exp $"); +#endif /* LIBC_SCCS and not lint */ +#endif +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/infinity.c 296113 2016-02-26 20:38:23Z nwhitehorn $"); + +/* infinity.c */ + +#include + +/* bytes for +Infinity on powerpc */ +const union __infinity_un __infinity = { +#if BYTE_ORDER == BIG_ENDIAN + { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } +#else + { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } +#endif +}; + +/* bytes for NaN */ +const union __nan_un __nan = { +#if BYTE_ORDER == BIG_ENDIAN + {0xff, 0xc0, 0, 0} +#else + { 0, 0, 0xc0, 0xff } +#endif +}; + diff --git a/lib/libc/powerpc64/gen/makecontext.c b/lib/libc/powerpc64/gen/makecontext.c new file mode 100644 index 0000000..8decb21 --- /dev/null +++ b/lib/libc/powerpc64/gen/makecontext.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2004 Suleiman Souhlal + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/makecontext.c 234003 2012-04-07 22:28:50Z nwhitehorn $"); + +#include + +#include +#include +#include +#include +#include + +__weak_reference(__makecontext, makecontext); + +void _ctx_done(ucontext_t *ucp); +void _ctx_start(void); + +void +_ctx_done(ucontext_t *ucp) +{ + if (ucp->uc_link == NULL) + exit(0); + else { + /* invalidate context */ + ucp->uc_mcontext.mc_len = 0; + + setcontext((const ucontext_t *)ucp->uc_link); + + abort(); /* should never return from above call */ + } +} + +void +__makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...) +{ + mcontext_t *mc; + char *sp; + va_list ap; + int i, regargs, stackargs; + + /* Sanity checks */ + if ((ucp == NULL) || (argc < 0) || (argc > NCARGS) + || (ucp->uc_stack.ss_sp == NULL) + || (ucp->uc_stack.ss_size < MINSIGSTKSZ)) { + /* invalidate context */ + ucp->uc_mcontext.mc_len = 0; + return; + } + + /* + * The stack must have space for the frame pointer, saved + * link register, overflow arguments, and be 16-byte + * aligned. + */ + stackargs = (argc > 8) ? argc - 8 : 0; + sp = (char *) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size + - sizeof(uintptr_t)*(stackargs + 2); + sp = (char *)((uintptr_t)sp & ~0x1f); + + mc = &ucp->uc_mcontext; + + /* + * Up to 8 register args. Assumes all args are 64-bit and + * integer only. Not sure how to cater for floating point. + */ + regargs = (argc > 8) ? 8 : argc; + va_start(ap, argc); + for (i = 0; i < regargs; i++) + mc->mc_gpr[3 + i] = va_arg(ap, uint64_t); + + /* + * Overflow args go onto the stack + */ + if (argc > 8) { + uint64_t *argp; + + /* Skip past frame pointer and saved LR */ + argp = (uint64_t *)sp + 6; + + for (i = 0; i < stackargs; i++) + *argp++ = va_arg(ap, uint64_t); + } + va_end(ap); + + /* + * Use caller-saved regs 14/15 to hold params that _ctx_start + * will use to invoke the user-supplied func + */ + mc->mc_srr0 = *(uintptr_t *)_ctx_start; + mc->mc_gpr[1] = (uintptr_t) sp; /* new stack pointer */ + mc->mc_gpr[14] = (uintptr_t) start; /* r14 <- start */ + mc->mc_gpr[15] = (uintptr_t) ucp; /* r15 <- ucp */ +} diff --git a/lib/libc/powerpc64/gen/setjmp.S b/lib/libc/powerpc64/gen/setjmp.S new file mode 100644 index 0000000..a2ac515 --- /dev/null +++ b/lib/libc/powerpc64/gen/setjmp.S @@ -0,0 +1,176 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: setjmp.S,v 1.3 1998/10/03 12:30:38 tsubai Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/setjmp.S 279784 2015-03-08 19:37:08Z nwhitehorn $"); + +#include + +/* + * C library -- setjmp, longjmp + * + * longjmp(a,v) + * will generate a "return(v?v:1)" from the last call to + * setjmp(a) + * by restoring registers from the stack. + * The previous signal state is restored. + * + * jmpbuf layout: + * +------------+ + * | unused | + * +------------+ + * | sig state | + * | | + * | (4 words) | + * | | + * +------------+ + * | saved regs | + * | ... | + */ + +ENTRY(setjmp) + mr %r6,%r3 + li %r3,1 /* SIG_BLOCK, but doesn't matter */ + /* since set == NULL */ + li %r4,0 /* set = NULL */ + mr %r5,%r6 /* &oset */ + addi %r5,%r5,4 + li %r0, SYS_sigprocmask /*sigprocmask(SIG_BLOCK, NULL, &oset)*/ + sc /*assume no error XXX */ + mflr %r11 /* r11 <- link reg */ + mfcr %r12 /* r12 <- condition reg */ + mr %r10,%r1 /* r10 <- stackptr */ + mr %r9,%r2 /* r9 <- global ptr */ + + std %r9,40 + 0*8(%r6) + stfd %f14,40 + 23*8(%r6) + std %r10,40 + 1*8(%r6) + stfd %f15,40 + 24*8(%r6) + std %r11,40 + 2*8(%r6) + stfd %f16,40 + 25*8(%r6) + std %r12,40 + 3*8(%r6) + stfd %f17,40 + 26*8(%r6) + std %r13,40 + 4*8(%r6) + stfd %f18,40 + 27*8(%r6) + std %r14,40 + 5*8(%r6) + stfd %f19,40 + 28*8(%r6) + std %r15,40 + 6*8(%r6) + stfd %f20,40 + 29*8(%r6) + std %r16,40 + 7*8(%r6) + stfd %f21,40 + 30*8(%r6) + std %r17,40 + 8*8(%r6) + stfd %f22,40 + 31*8(%r6) + std %r18,40 + 9*8(%r6) + stfd %f23,40 + 32*8(%r6) + std %r19,40 + 10*8(%r6) + stfd %f24,40 + 33*8(%r6) + std %r20,40 + 11*8(%r6) + stfd %f25,40 + 34*8(%r6) + std %r21,40 + 12*8(%r6) + stfd %f26,40 + 35*8(%r6) + std %r22,40 + 13*8(%r6) + stfd %f27,40 + 36*8(%r6) + std %r23,40 + 14*8(%r6) + stfd %f28,40 + 37*8(%r6) + std %r24,40 + 15*8(%r6) + stfd %f29,40 + 38*8(%r6) + std %r25,40 + 16*8(%r6) + stfd %f30,40 + 39*8(%r6) + std %r26,40 + 17*8(%r6) + stfd %f31,40 + 40*8(%r6) + std %r27,40 + 18*8(%r6) + std %r28,40 + 19*8(%r6) + std %r29,40 + 20*8(%r6) + std %r30,40 + 21*8(%r6) + std %r31,40 + 22*8(%r6) + + /* XXX Altivec regs */ + + li %r3,0 /* return (0) */ + blr +END(setjmp) + + WEAK_REFERENCE(__longjmp, longjmp) +ENTRY(__longjmp) + ld %r9,40 + 0*8(%r3) + lfd %f14,40 + 23*8(%r3) + ld %r10,40 + 1*8(%r3) + lfd %f15,40 + 24*8(%r3) + ld %r11,40 + 2*8(%r3) + lfd %f16,40 + 25*8(%r3) + ld %r12,40 + 3*8(%r3) + lfd %f17,40 + 26*8(%r3) + ld %r14,40 + 5*8(%r3) + lfd %f18,40 + 27*8(%r3) + ld %r15,40 + 6*8(%r3) + lfd %f19,40 + 28*8(%r3) + ld %r16,40 + 7*8(%r3) + lfd %f20,40 + 29*8(%r3) + ld %r17,40 + 8*8(%r3) + lfd %f21,40 + 30*8(%r3) + ld %r18,40 + 9*8(%r3) + lfd %f22,40 + 31*8(%r3) + ld %r19,40 + 10*8(%r3) + lfd %f23,40 + 32*8(%r3) + ld %r20,40 + 11*8(%r3) + lfd %f24,40 + 33*8(%r3) + ld %r21,40 + 12*8(%r3) + lfd %f25,40 + 34*8(%r3) + ld %r22,40 + 13*8(%r3) + lfd %f26,40 + 35*8(%r3) + ld %r23,40 + 14*8(%r3) + lfd %f27,40 + 36*8(%r3) + ld %r24,40 + 15*8(%r3) + lfd %f28,40 + 37*8(%r3) + ld %r25,40 + 16*8(%r3) + lfd %f29,40 + 38*8(%r3) + ld %r26,40 + 17*8(%r3) + lfd %f30,40 + 39*8(%r3) + ld %r27,40 + 18*8(%r3) + lfd %f31,40 + 40*8(%r3) + ld %r28,40 + 19*8(%r3) + ld %r29,40 + 20*8(%r3) + ld %r30,40 + 21*8(%r3) + ld %r31,40 + 22*8(%r3) + mr %r6,%r4 /* save val param */ + mtlr %r11 /* r11 -> link reg */ + mtcr %r12 /* r12 -> condition reg */ + mr %r2,%r9 /* r9 -> global ptr */ + mr %r1,%r10 /* r10 -> stackptr */ + mr %r4,%r3 + li %r3,3 /* SIG_SETMASK */ + addi %r4,%r4,4 /* &set */ + li %r5,0 /* oset = NULL */ + li %r0,SYS_sigprocmask /* sigprocmask(SIG_SET, &set, NULL) */ + sc /* assume no error XXX */ + or. %r3,%r6,%r6 + bnelr + li %r3,1 + blr +END(__longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc64/gen/signalcontext.c b/lib/libc/powerpc64/gen/signalcontext.c new file mode 100644 index 0000000..e17338b --- /dev/null +++ b/lib/libc/powerpc64/gen/signalcontext.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2004 Marcel Moolenaar, Peter Grehan + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/signalcontext.c 209878 2010-07-10 14:45:03Z nwhitehorn $"); + +#include +#include +#include +#include +#include + +typedef void (*handler_t)(uint32_t, uint32_t, uint32_t); + +/* Prototypes */ +static void ctx_wrapper(ucontext_t *ucp, handler_t func, uint32_t sig, + uint32_t sig_si, uint32_t sig_uc); + +__weak_reference(__signalcontext, signalcontext); + +int +__signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func) +{ + siginfo_t *sig_si; + ucontext_t *sig_uc; + uintptr_t sp; + + /* Bail out if we don't have a valid ucontext pointer. */ + if (ucp == NULL) + abort(); + + /* + * Build a 16-byte-aligned signal frame + */ + sp = (ucp->uc_mcontext.mc_gpr[1] - sizeof(ucontext_t)) & ~15UL; + sig_uc = (ucontext_t *)sp; + bcopy(ucp, sig_uc, sizeof(*sig_uc)); + sp = (sp - sizeof(siginfo_t)) & ~15UL; + sig_si = (siginfo_t *)sp; + bzero(sig_si, sizeof(*sig_si)); + sig_si->si_signo = sig; + + /* + * Subtract 48 bytes from stack to allow for frameptr + */ + sp -= 6*sizeof(uint64_t); + sp &= ~15UL; + + /* + * Setup the ucontext of the signal handler. + */ + bzero(&ucp->uc_mcontext, sizeof(ucp->uc_mcontext)); + ucp->uc_link = sig_uc; + sigdelset(&ucp->uc_sigmask, sig); + + ucp->uc_mcontext.mc_vers = _MC_VERSION; + ucp->uc_mcontext.mc_len = sizeof(struct __mcontext); + ucp->uc_mcontext.mc_srr0 = (uint64_t) ctx_wrapper; + ucp->uc_mcontext.mc_gpr[1] = (uint64_t) sp; + ucp->uc_mcontext.mc_gpr[3] = (uint64_t) func; + ucp->uc_mcontext.mc_gpr[4] = (uint64_t) sig; + ucp->uc_mcontext.mc_gpr[5] = (uint64_t) sig_si; + ucp->uc_mcontext.mc_gpr[6] = (uint64_t) sig_uc; + + return (0); +} + +static void +ctx_wrapper(ucontext_t *ucp, handler_t func, uint32_t sig, uint32_t sig_si, + uint32_t sig_uc) +{ + + (*func)(sig, sig_si, sig_uc); + if (ucp->uc_link == NULL) + exit(0); + setcontext((const ucontext_t *)ucp->uc_link); + /* should never get here */ + abort(); + /* NOTREACHED */ +} diff --git a/lib/libc/powerpc64/gen/sigsetjmp.S b/lib/libc/powerpc64/gen/sigsetjmp.S new file mode 100644 index 0000000..6b94a23 --- /dev/null +++ b/lib/libc/powerpc64/gen/sigsetjmp.S @@ -0,0 +1,183 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: sigsetjmp.S,v 1.4 1998/10/03 12:30:38 tsubai Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/sigsetjmp.S 279784 2015-03-08 19:37:08Z nwhitehorn $"); + +/* + * C library -- sigsetjmp, siglongjmp + * + * siglongjmp(a,v) + * will generate a "return(v?v:1)" from the last call to + * sigsetjmp(a, savemask) + * by restoring registers from the stack. + * The previous signal state is restored if savemask is non-zero + * + * jmpbuf layout: + * +------------+ + * | savemask | + * +------------+ + * | sig state | + * | | + * | (4 words) | + * | | + * +------------+ + * | saved regs | + * | ... | + */ + + +#include + +ENTRY(sigsetjmp) + mr %r6,%r3 + stw %r4,0(%r3) + or. %r7,%r4,%r4 + beq 1f + li %r3,1 /* SIG_BLOCK, but doesn't matter */ + /* since set == NULL */ + li %r4,0 /* set = NULL */ + mr %r5,%r6 /* &oset */ + addi %r5,%r5,4 + li %r0, SYS_sigprocmask /* sigprocmask(SIG_BLOCK, NULL, &oset)*/ + sc /* assume no error XXX */ +1: + mflr %r11 + mfcr %r12 + mr %r10,%r1 + mr %r9,%r2 + + std %r9,40 + 0*8(%r6) + stfd %f14,40 + 23*8(%r6) + std %r10,40 + 1*8(%r6) + stfd %f15,40 + 24*8(%r6) + std %r11,40 + 2*8(%r6) + stfd %f16,40 + 25*8(%r6) + std %r12,40 + 3*8(%r6) + stfd %f17,40 + 26*8(%r6) + std %r13,40 + 4*8(%r6) + stfd %f18,40 + 27*8(%r6) + std %r14,40 + 5*8(%r6) + stfd %f19,40 + 28*8(%r6) + std %r15,40 + 6*8(%r6) + stfd %f20,40 + 29*8(%r6) + std %r16,40 + 7*8(%r6) + stfd %f21,40 + 30*8(%r6) + std %r17,40 + 8*8(%r6) + stfd %f22,40 + 31*8(%r6) + std %r18,40 + 9*8(%r6) + stfd %f23,40 + 32*8(%r6) + std %r19,40 + 10*8(%r6) + stfd %f24,40 + 33*8(%r6) + std %r20,40 + 11*8(%r6) + stfd %f25,40 + 34*8(%r6) + std %r21,40 + 12*8(%r6) + stfd %f26,40 + 35*8(%r6) + std %r22,40 + 13*8(%r6) + stfd %f27,40 + 36*8(%r6) + std %r23,40 + 14*8(%r6) + stfd %f28,40 + 37*8(%r6) + std %r24,40 + 15*8(%r6) + stfd %f29,40 + 38*8(%r6) + std %r25,40 + 16*8(%r6) + stfd %f30,40 + 39*8(%r6) + std %r26,40 + 17*8(%r6) + stfd %f31,40 + 40*8(%r6) + std %r27,40 + 18*8(%r6) + std %r28,40 + 19*8(%r6) + std %r29,40 + 20*8(%r6) + std %r30,40 + 21*8(%r6) + std %r31,40 + 22*8(%r6) + + li %r3,0 + blr +END(sigsetjmp) + +ENTRY(siglongjmp) + ld %r9,40 + 0*8(%r3) + lfd %f14,40 + 23*8(%r3) + ld %r10,40 + 1*8(%r3) + lfd %f15,40 + 24*8(%r3) + ld %r11,40 + 2*8(%r3) + lfd %f16,40 + 25*8(%r3) + ld %r12,40 + 3*8(%r3) + lfd %f17,40 + 26*8(%r3) + ld %r14,40 + 5*8(%r3) + lfd %f18,40 + 27*8(%r3) + ld %r15,40 + 6*8(%r3) + lfd %f19,40 + 28*8(%r3) + ld %r16,40 + 7*8(%r3) + lfd %f20,40 + 29*8(%r3) + ld %r17,40 + 8*8(%r3) + lfd %f21,40 + 30*8(%r3) + ld %r18,40 + 9*8(%r3) + lfd %f22,40 + 31*8(%r3) + ld %r19,40 + 10*8(%r3) + lfd %f23,40 + 32*8(%r3) + ld %r20,40 + 11*8(%r3) + lfd %f24,40 + 33*8(%r3) + ld %r21,40 + 12*8(%r3) + lfd %f25,40 + 34*8(%r3) + ld %r22,40 + 13*8(%r3) + lfd %f26,40 + 35*8(%r3) + ld %r23,40 + 14*8(%r3) + lfd %f27,40 + 36*8(%r3) + ld %r24,40 + 15*8(%r3) + lfd %f28,40 + 37*8(%r3) + ld %r25,40 + 16*8(%r3) + lfd %f29,40 + 38*8(%r3) + ld %r26,40 + 17*8(%r3) + lfd %f30,40 + 39*8(%r3) + ld %r27,40 + 18*8(%r3) + lfd %f31,40 + 40*8(%r3) + ld %r28,40 + 19*8(%r3) + ld %r29,40 + 20*8(%r3) + ld %r30,40 + 21*8(%r3) + ld %r31,40 + 22*8(%r3) + + lwz %r7,0(%r3) + mr %r6,%r4 + mtlr %r11 + mtcr %r12 + mr %r2,%r9 + mr %r1,%r10 + or. %r7,%r7,%r7 + beq 1f + mr %r4,%r3 + li %r3,3 /* SIG_SETMASK */ + addi %r4,%r4,4 /* &set */ + li %r5,0 /* oset = NULL */ + li %r0,SYS_sigprocmask /* sigprocmask(SIG_SET, &set, NULL) */ + sc /* assume no error XXX */ +1: + or. %r3,%r6,%r6 + bnelr + li %r3,1 + blr +END(siglongjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc64/gen/syncicache.c b/lib/libc/powerpc64/gen/syncicache.c new file mode 100644 index 0000000..6a4eb2e --- /dev/null +++ b/lib/libc/powerpc64/gen/syncicache.c @@ -0,0 +1,103 @@ +/*- + * Copyright (C) 1995-1997, 1999 Wolfgang Solfrank. + * Copyright (C) 1995-1997, 1999 TooLs GmbH. + * 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 TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. + * + * $NetBSD: syncicache.c,v 1.2 1999/05/05 12:36:40 tsubai Exp $ + */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD: releng/11.1/lib/libc/powerpc64/gen/syncicache.c 298120 2016-04-16 17:52:00Z pfg $"; +#endif /* not lint */ + +#include +#if defined(_KERNEL) || defined(_STANDALONE) +#include +#include +#include +#endif +#include + +#include +#include + +#ifdef _STANDALONE +int cacheline_size = 32; +#endif + +#if !defined(_KERNEL) && !defined(_STANDALONE) +#include + +int cacheline_size = 0; + +static void getcachelinesize(void); + +static void +getcachelinesize() +{ + static int cachemib[] = { CTL_MACHDEP, CPU_CACHELINE }; + long clen; + + clen = sizeof(cacheline_size); + + if (sysctl(cachemib, nitems(cachemib), &cacheline_size, &clen, + NULL, 0) < 0 || !cacheline_size) { + abort(); + } +} +#endif + +void +__syncicache(void *from, int len) +{ + off_t l, off; + char *p; + +#if !defined(_KERNEL) && !defined(_STANDALONE) + if (!cacheline_size) + getcachelinesize(); +#endif + + off = (uintptr_t)from & (cacheline_size - 1); + l = len += off; + p = (char *)from - off; + + do { + __asm __volatile ("dcbst 0,%0" :: "r"(p)); + p += cacheline_size; + } while ((l -= cacheline_size) > 0); + __asm __volatile ("sync"); + p = (char *)from - off; + do { + __asm __volatile ("icbi 0,%0" :: "r"(p)); + p += cacheline_size; + } while ((len -= cacheline_size) > 0); + __asm __volatile ("sync; isync"); +} + diff --git a/lib/libc/powerpc64/softfloat/milieu.h b/lib/libc/powerpc64/softfloat/milieu.h new file mode 100644 index 0000000..94e5150 --- /dev/null +++ b/lib/libc/powerpc64/softfloat/milieu.h @@ -0,0 +1,49 @@ +/* $NetBSD: milieu.h,v 1.1 2000/12/29 20:13:54 bjh21 Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/powerpc64/softfloat/milieu.h 209878 2010-07-10 14:45:03Z nwhitehorn $ */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Include common integer types and flags. +------------------------------------------------------------------------------- +*/ +#include "powerpc-gcc.h" + +/* +------------------------------------------------------------------------------- +Symbolic Boolean literals. +------------------------------------------------------------------------------- +*/ +enum { + FALSE = 0, + TRUE = 1 +}; diff --git a/lib/libc/powerpc64/softfloat/powerpc-gcc.h b/lib/libc/powerpc64/softfloat/powerpc-gcc.h new file mode 100644 index 0000000..534652d --- /dev/null +++ b/lib/libc/powerpc64/softfloat/powerpc-gcc.h @@ -0,0 +1,92 @@ +/* $NetBSD: arm-gcc.h,v 1.2 2001/02/21 18:09:25 bjh21 Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/powerpc64/softfloat/powerpc-gcc.h 209878 2010-07-10 14:45:03Z nwhitehorn $ */ + +/* +------------------------------------------------------------------------------- +One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined. +------------------------------------------------------------------------------- +*/ +#define BIGENDIAN + +/* +------------------------------------------------------------------------------- +The macro `BITS64' can be defined to indicate that 64-bit integer types are +supported by the compiler. +------------------------------------------------------------------------------- +*/ +#define BITS64 + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines the most convenient type that holds +integers of at least as many bits as specified. For example, `uint8' should +be the most convenient type that can hold unsigned integers of as many as +8 bits. The `flag' type must be able to hold either a 0 or 1. For most +implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed +to the same as `int'. +------------------------------------------------------------------------------- +*/ +typedef int flag; +typedef unsigned int uint8; +typedef int int8; +typedef unsigned int uint16; +typedef int int16; +typedef unsigned int uint32; +typedef signed int int32; +#ifdef BITS64 +typedef unsigned long long int uint64; +typedef signed long long int int64; +#endif + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines a type that holds integers +of _exactly_ the number of bits specified. For instance, for most +implementation of C, `bits16' and `sbits16' should be `typedef'ed to +`unsigned short int' and `signed short int' (or `short int'), respectively. +------------------------------------------------------------------------------- +*/ +typedef unsigned char bits8; +typedef signed char sbits8; +typedef unsigned short int bits16; +typedef signed short int sbits16; +typedef unsigned int bits32; +typedef signed int sbits32; +#ifdef BITS64 +typedef unsigned long long int bits64; +typedef signed long long int sbits64; +#endif + +#ifdef BITS64 +/* +------------------------------------------------------------------------------- +The `LIT64' macro takes as its argument a textual integer literal and +if necessary ``marks'' the literal as having a 64-bit integer type. +For example, the GNU C Compiler (`gcc') requires that 64-bit literals be +appended with the letters `LL' standing for `long long', which is `gcc's +name for the 64-bit integer type. Some compilers may allow `LIT64' to be +defined as the identity macro: `#define LIT64( a ) a'. +------------------------------------------------------------------------------- +*/ +#define LIT64( a ) a##LL +#endif + +/* +------------------------------------------------------------------------------- +The macro `INLINE' can be used before functions that should be inlined. If +a compiler does not support explicit inlining, this macro should be defined +to be `static'. +------------------------------------------------------------------------------- +*/ +#define INLINE static __inline + +/* +------------------------------------------------------------------------------- +The ARM FPA is odd in that it stores doubles high-order word first, no matter +what the endianness of the CPU. VFP is sane. +------------------------------------------------------------------------------- +*/ +#if defined(SOFTFLOAT_FOR_GCC) +#define FLOAT64_DEMANGLE(a) (a) +#define FLOAT64_MANGLE(a) (a) +#endif diff --git a/lib/libc/powerpc64/softfloat/softfloat.h b/lib/libc/powerpc64/softfloat/softfloat.h new file mode 100644 index 0000000..5662cfe --- /dev/null +++ b/lib/libc/powerpc64/softfloat/softfloat.h @@ -0,0 +1,307 @@ +/* $NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/powerpc64/softfloat/softfloat.h 209878 2010-07-10 14:45:03Z nwhitehorn $ */ + +/* This is a derivative work. */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +The macro `FLOATX80' must be defined to enable the extended double-precision +floating-point format `floatx80'. If this macro is not defined, the +`floatx80' type will not be defined, and none of the functions that either +input or output the `floatx80' type will be defined. The same applies to +the `FLOAT128' macro and the quadruple-precision format `float128'. +------------------------------------------------------------------------------- +*/ +/* #define FLOATX80 */ +/* #define FLOAT128 */ + +#include + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point types. +------------------------------------------------------------------------------- +*/ +typedef unsigned int float32; +typedef unsigned long long float64; +#ifdef FLOATX80 +typedef struct { + unsigned short high; + unsigned long long low; +} floatx80; +#endif +#ifdef FLOAT128 +typedef struct { + unsigned long long high, low; +} float128; +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point underflow tininess-detection mode. +------------------------------------------------------------------------------- +*/ +#ifndef SOFTFLOAT_FOR_GCC +extern int8 float_detect_tininess; +#endif +enum { + float_tininess_after_rounding = 0, + float_tininess_before_rounding = 1 +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point rounding mode. +------------------------------------------------------------------------------- +*/ +extern fp_rnd_t float_rounding_mode; +enum { + float_round_nearest_even = FP_RN, + float_round_to_zero = FP_RZ, + float_round_down = FP_RM, + float_round_up = FP_RP +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point exception flags. +------------------------------------------------------------------------------- +*/ +typedef fp_except_t fp_except; + +extern fp_except float_exception_flags; +extern fp_except float_exception_mask; +enum { + float_flag_inexact = FP_X_IMP, + float_flag_underflow = FP_X_UFL, + float_flag_overflow = FP_X_OFL, + float_flag_divbyzero = FP_X_DZ, + float_flag_invalid = FP_X_INV +}; + +/* +------------------------------------------------------------------------------- +Routine to raise any or all of the software IEC/IEEE floating-point +exception flags. +------------------------------------------------------------------------------- +*/ +void float_raise( fp_except ); + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE integer-to-floating-point conversion routines. +------------------------------------------------------------------------------- +*/ +float32 int32_to_float32( int ); +float64 int32_to_float64( int ); +#ifdef FLOATX80 +floatx80 int32_to_floatx80( int ); +#endif +#ifdef FLOAT128 +float128 int32_to_float128( int ); +#endif +float32 int64_to_float32( long long ); +float64 int64_to_float64( long long ); +#ifdef FLOATX80 +floatx80 int64_to_floatx80( long long ); +#endif +#ifdef FLOAT128 +float128 int64_to_float128( long long ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float32_to_int32( float32 ); +int float32_to_int32_round_to_zero( float32 ); +unsigned int float32_to_uint32_round_to_zero( float32 ); +long long float32_to_int64( float32 ); +long long float32_to_int64_round_to_zero( float32 ); +float64 float32_to_float64( float32 ); +#ifdef FLOATX80 +floatx80 float32_to_floatx80( float32 ); +#endif +#ifdef FLOAT128 +float128 float32_to_float128( float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision operations. +------------------------------------------------------------------------------- +*/ +float32 float32_round_to_int( float32 ); +float32 float32_add( float32, float32 ); +float32 float32_sub( float32, float32 ); +float32 float32_mul( float32, float32 ); +float32 float32_div( float32, float32 ); +float32 float32_rem( float32, float32 ); +float32 float32_sqrt( float32 ); +int float32_eq( float32, float32 ); +int float32_le( float32, float32 ); +int float32_lt( float32, float32 ); +int float32_eq_signaling( float32, float32 ); +int float32_le_quiet( float32, float32 ); +int float32_lt_quiet( float32, float32 ); +#ifndef SOFTFLOAT_FOR_GCC +int float32_is_signaling_nan( float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float64_to_int32( float64 ); +int float64_to_int32_round_to_zero( float64 ); +unsigned int float64_to_uint32_round_to_zero( float64 ); +long long float64_to_int64( float64 ); +long long float64_to_int64_round_to_zero( float64 ); +float32 float64_to_float32( float64 ); +#ifdef FLOATX80 +floatx80 float64_to_floatx80( float64 ); +#endif +#ifdef FLOAT128 +float128 float64_to_float128( float64 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision operations. +------------------------------------------------------------------------------- +*/ +float64 float64_round_to_int( float64 ); +float64 float64_add( float64, float64 ); +float64 float64_sub( float64, float64 ); +float64 float64_mul( float64, float64 ); +float64 float64_div( float64, float64 ); +float64 float64_rem( float64, float64 ); +float64 float64_sqrt( float64 ); +int float64_eq( float64, float64 ); +int float64_le( float64, float64 ); +int float64_lt( float64, float64 ); +int float64_eq_signaling( float64, float64 ); +int float64_le_quiet( float64, float64 ); +int float64_lt_quiet( float64, float64 ); +#ifndef SOFTFLOAT_FOR_GCC +int float64_is_signaling_nan( float64 ); +#endif + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int floatx80_to_int32( floatx80 ); +int floatx80_to_int32_round_to_zero( floatx80 ); +long long floatx80_to_int64( floatx80 ); +long long floatx80_to_int64_round_to_zero( floatx80 ); +float32 floatx80_to_float32( floatx80 ); +float64 floatx80_to_float64( floatx80 ); +#ifdef FLOAT128 +float128 floatx80_to_float128( floatx80 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision rounding precision. Valid +values are 32, 64, and 80. +------------------------------------------------------------------------------- +*/ +extern int floatx80_rounding_precision; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision operations. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_round_to_int( floatx80 ); +floatx80 floatx80_add( floatx80, floatx80 ); +floatx80 floatx80_sub( floatx80, floatx80 ); +floatx80 floatx80_mul( floatx80, floatx80 ); +floatx80 floatx80_div( floatx80, floatx80 ); +floatx80 floatx80_rem( floatx80, floatx80 ); +floatx80 floatx80_sqrt( floatx80 ); +int floatx80_eq( floatx80, floatx80 ); +int floatx80_le( floatx80, floatx80 ); +int floatx80_lt( floatx80, floatx80 ); +int floatx80_eq_signaling( floatx80, floatx80 ); +int floatx80_le_quiet( floatx80, floatx80 ); +int floatx80_lt_quiet( floatx80, floatx80 ); +int floatx80_is_signaling_nan( floatx80 ); + +#endif + +#ifdef FLOAT128 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE quadruple-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float128_to_int32( float128 ); +int float128_to_int32_round_to_zero( float128 ); +long long float128_to_int64( float128 ); +long long float128_to_int64_round_to_zero( float128 ); +float32 float128_to_float32( float128 ); +float64 float128_to_float64( float128 ); +#ifdef FLOATX80 +floatx80 float128_to_floatx80( float128 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE quadruple-precision operations. +------------------------------------------------------------------------------- +*/ +float128 float128_round_to_int( float128 ); +float128 float128_add( float128, float128 ); +float128 float128_sub( float128, float128 ); +float128 float128_mul( float128, float128 ); +float128 float128_div( float128, float128 ); +float128 float128_rem( float128, float128 ); +float128 float128_sqrt( float128 ); +int float128_eq( float128, float128 ); +int float128_le( float128, float128 ); +int float128_lt( float128, float128 ); +int float128_eq_signaling( float128, float128 ); +int float128_le_quiet( float128, float128 ); +int float128_lt_quiet( float128, float128 ); +int float128_is_signaling_nan( float128 ); + +#endif + diff --git a/lib/libc/powerpc64/sys/Makefile.inc b/lib/libc/powerpc64/sys/Makefile.inc new file mode 100644 index 0000000..b1412e1 --- /dev/null +++ b/lib/libc/powerpc64/sys/Makefile.inc @@ -0,0 +1,8 @@ +# $FreeBSD: releng/11.1/lib/libc/powerpc64/sys/Makefile.inc 305329 2016-09-03 09:03:40Z kib $ + +MDASM+= brk.S cerror.S exect.S sbrk.S setlogin.S + +# Don't generate default code for these syscalls: +NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o yield.o + +PSEUDO= _getlogin.o _exit.o diff --git a/lib/libc/powerpc64/sys/brk.S b/lib/libc/powerpc64/sys/brk.S new file mode 100644 index 0000000..b555f92 --- /dev/null +++ b/lib/libc/powerpc64/sys/brk.S @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: brk.S,v 1.9 2000/06/26 06:25:43 kleink Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/sys/brk.S 272362 2014-10-01 15:00:21Z bapt $"); + +#include "SYS.h" + + .globl HIDENAME(curbrk) + .globl HIDENAME(minbrk) + .globl CNAME(_end) + + .data + .align 3 +HIDENAME(minbrk): + .llong CNAME(_end) + + .text + +ENTRY(brk) + addis %r6,%r2,HIDENAME(minbrk)@toc@ha + ld %r6,HIDENAME(minbrk)@toc@l(%r6) + cmpld %r6,%r3 /* if (minbrk <= r3) */ + bgt 0f + mr %r6,%r3 /* r6 = r3 */ +0: + mr %r3,%r6 /* new break value */ + li %r0,SYS_break + sc /* assume, that r5 is kept */ + bso 1f + + /* record new break */ + addis %r7,%r2,HIDENAME(curbrk)@toc@ha + std %r6,HIDENAME(curbrk)@toc@l(%r7) + + blr /* return 0 */ + +1: + mflr %r0 + std %r0,16(%r1) + stdu %r1,-48(%r1) + bl HIDENAME(cerror) + nop + ld %r1,0(%r1) + ld %r0,16(%r1) + mtlr %r0 + blr +END(brk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc64/sys/cerror.S b/lib/libc/powerpc64/sys/cerror.S new file mode 100644 index 0000000..dd22622 --- /dev/null +++ b/lib/libc/powerpc64/sys/cerror.S @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: cerror.S,v 1.5 2000/01/27 14:58:48 kleink Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/sys/cerror.S 230400 2012-01-20 22:34:19Z andreast $"); + +#include "SYS.h" + + .globl HIDENAME(cerror) + .globl CNAME(__error) + + /* + * The __error() function is thread aware. For non-threaded + * programs and the initial threaded in threaded programs, + * it returns a pointer to the global errno variable. + */ +ENTRY_NOPROF(HIDENAME(cerror)) + mflr %r0 + std %r0,16(%r1) /* save lr */ + stdu %r1,-64(%r1) /* allocate new stack frame */ + std %r31,48(%r1) + + mr %r31,%r3 /* stash errval in callee-saved register */ + bl CNAME(__error) + nop + stw %r31,0(%r3) /* store errval into &errno */ + + ld %r31,48(%r1) + ld %r1,0(%r1) + ld %r0,16(%r1) + mtlr %r0 + li %r3,-1 + li %r4,-1 + blr + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc64/sys/exect.S b/lib/libc/powerpc64/sys/exect.S new file mode 100644 index 0000000..ea47ac3 --- /dev/null +++ b/lib/libc/powerpc64/sys/exect.S @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: exect.S,v 1.3 1998/05/25 15:28:03 ws Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/sys/exect.S 272362 2014-10-01 15:00:21Z bapt $"); + +#include "SYS.h" + +ENTRY(exect) + li %r0,SYS_execve + sc + bso 1f + blr +1: + mflr %r0 + std %r0,16(%r1) + stdu %r1,-48(%r1) + bl HIDENAME(cerror) + nop + ld %r1,0(%r1) + ld %r0,16(%r1) + mtlr %r0 + blr +END(exect) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc64/sys/sbrk.S b/lib/libc/powerpc64/sys/sbrk.S new file mode 100644 index 0000000..8bd274e --- /dev/null +++ b/lib/libc/powerpc64/sys/sbrk.S @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: sbrk.S,v 1.8 2000/06/26 06:25:44 kleink Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/sys/sbrk.S 272362 2014-10-01 15:00:21Z bapt $"); + +#include "SYS.h" + + .globl HIDENAME(curbrk) + .globl CNAME(_end) + + .data + .align 3 +HIDENAME(curbrk): + .llong CNAME(_end) + + .text +ENTRY(sbrk) + addis %r5,%r2,HIDENAME(curbrk)@toc@ha + addi %r5,%r5,HIDENAME(curbrk)@toc@l + ld %r6,0(%r5) /* r6 = old break */ + cmpdi %r3,0 /* sbrk(0) - return curbrk */ + beq 1f + add %r3,%r3,%r6 + mr %r7,%r3 /* r7 = new break */ + li %r0,SYS_break + sc /* break(new_break) */ + bso 2f + std %r7,0(%r5) +1: + mr %r3,%r6 /* set return value */ + blr +2: + mflr %r0 + std %r0,16(%r1) + stdu %r1,-48(%r1) + bl HIDENAME(cerror) + nop + ld %r1,0(%r1) + ld %r0,16(%r1) + mtlr %r0 + blr +END(sbrk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc64/sys/setlogin.S b/lib/libc/powerpc64/sys/setlogin.S new file mode 100644 index 0000000..880c997 --- /dev/null +++ b/lib/libc/powerpc64/sys/setlogin.S @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ +/* $NetBSD: setlogin.S,v 1.3 1998/11/24 11:14:57 tsubai Exp $ */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/powerpc64/sys/setlogin.S 217398 2011-01-14 11:33:40Z kib $"); + +#include "SYS.h" + + .globl CNAME(_logname_valid) /* in _getlogin() */ + +SYSCALL(setlogin) + addis %r4,%r2,CNAME(_logname_valid)@toc@ha + li %r5,0 + stw %r5,CNAME(_logname_valid)@toc@l(%r4) + blr + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/quad/Makefile.inc b/lib/libc/quad/Makefile.inc new file mode 100644 index 0000000..921940a --- /dev/null +++ b/lib/libc/quad/Makefile.inc @@ -0,0 +1,25 @@ +# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/quad/Makefile.inc 272350 2014-10-01 08:26:51Z andrew $ + +# Quad support, if needed +.PATH: ${LIBC_SRCTOP}/${LIBC_ARCH}/quad ${LIBC_SRCTOP}/quad + +.if ${LIBC_ARCH} == "i386" + +SRCS+= cmpdi2.c divdi3.c moddi3.c qdivrem.c ucmpdi2.c udivdi3.c umoddi3.c + +.elif ${LIBC_ARCH} == "arm" + +SRCS+= adddi3.c anddi3.c floatunsdidf.c iordi3.c lshldi3.c notdi2.c \ + qdivrem.c subdi3.c xordi3.c +.else + +SRCS+= adddi3.c anddi3.c ashldi3.c ashrdi3.c cmpdi2.c divdi3.c fixdfdi.c \ + fixsfdi.c fixunsdfdi.c fixunssfdi.c floatdidf.c floatdisf.c \ + floatunsdidf.c iordi3.c lshldi3.c lshrdi3.c moddi3.c muldi3.c \ + negdi2.c notdi2.c qdivrem.c subdi3.c ucmpdi2.c udivdi3.c umoddi3.c \ + xordi3.c + +.endif + +SYM_MAPS+=${LIBC_SRCTOP}/quad/Symbol.map diff --git a/lib/libc/quad/Symbol.map b/lib/libc/quad/Symbol.map new file mode 100644 index 0000000..b81df25 --- /dev/null +++ b/lib/libc/quad/Symbol.map @@ -0,0 +1,38 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/quad/Symbol.map 170155 2007-05-31 13:07:37Z deischen $ + */ + +FBSD_1.0 { + /* + * These symbols really shouldn't be exported since they should + * be pulled from libgcc, but the build of some applications is + * broken and they expect to see them in libc. glibc exports + * them, but they do not appear to be exported in Solaris. + */ + __adddi3; + __anddi3; + __ashldi3; + __ashrdi3; + __cmpdi2; + __divdi3; + __fixdfdi; + __fixsfdi; + __fixunsdfdi; + __fixunssfdi; + __floatdidf; + __floatdisf; + __floatunsdidf; + __iordi3; + __lshldi3; + __lshrdi3; + __moddi3; + __muldi3; + __negdi2; + __one_cmpldi2; + __qdivrem; + __subdi3; + __ucmpdi2; + __udivdi3; + __umoddi3; + __xordi3; +}; diff --git a/lib/libc/quad/TESTS/Makefile b/lib/libc/quad/TESTS/Makefile new file mode 100644 index 0000000..5834f21 --- /dev/null +++ b/lib/libc/quad/TESTS/Makefile @@ -0,0 +1,11 @@ +# @(#)Makefile 8.1 (Berkeley) 6/4/93 + +all: mul divrem + +MUL= mul.c ../muldi3.c +mul: ${MUL} + gcc -g -DSPARC_XXX ${MUL} -o ${.TARGET} + +DIVREM= divrem.c ../qdivrem.c +divrem: ${DIVREM} + gcc -g -DSPARC_XXX ${DIVREM} -o ${.TARGET} diff --git a/lib/libc/quad/TESTS/divrem.c b/lib/libc/quad/TESTS/divrem.c new file mode 100644 index 0000000..a2f9781 --- /dev/null +++ b/lib/libc/quad/TESTS/divrem.c @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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. + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1992, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)divrem.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/quad/TESTS/divrem.c 165903 2007-01-09 00:28:16Z imp $"); + +#include + +main() +{ + union { long long q; unsigned long v[2]; } a, b, q, r; + char buf[300]; + extern long long __qdivrem(unsigned long long, unsigned long long, + unsigned long long *); + + for (;;) { + printf("> "); + if (fgets(buf, sizeof buf, stdin) == NULL) + break; + if (sscanf(buf, "%lu:%lu %lu:%lu", + &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4 && + sscanf(buf, "0x%lx:%lx 0x%lx:%lx", + &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4) { + printf("eh?\n"); + continue; + } + q.q = __qdivrem(a.q, b.q, &r.q); + printf("%lx:%lx /%% %lx:%lx => q=%lx:%lx r=%lx:%lx\n", + a.v[0], a.v[1], b.v[0], b.v[1], + q.v[0], q.v[1], r.v[0], r.v[1]); + printf(" = %lX%08lX / %lX%08lX => %lX%08lX\n\ + = %lX%08lX %% %lX%08lX => %lX%08lX\n", + a.v[0], a.v[1], b.v[0], b.v[1], q.v[0], q.v[1], + a.v[0], a.v[1], b.v[0], b.v[1], r.v[0], r.v[1]); + } + exit(0); +} diff --git a/lib/libc/quad/TESTS/mul.c b/lib/libc/quad/TESTS/mul.c new file mode 100644 index 0000000..cb6ec42 --- /dev/null +++ b/lib/libc/quad/TESTS/mul.c @@ -0,0 +1,72 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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. + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1992, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)mul.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/quad/TESTS/mul.c 165903 2007-01-09 00:28:16Z imp $"); + +#include + +main() +{ + union { long long q; unsigned long v[2]; } a, b, m; + char buf[300]; + extern long long __muldi3(long long, long long); + + for (;;) { + printf("> "); + if (fgets(buf, sizeof buf, stdin) == NULL) + break; + if (sscanf(buf, "%lu:%lu %lu:%lu", + &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4 && + sscanf(buf, "0x%lx:%lx 0x%lx:%lx", + &a.v[0], &a.v[1], &b.v[0], &b.v[1]) != 4) { + printf("eh?\n"); + continue; + } + m.q = __muldi3(a.q, b.q); + printf("%lx:%lx * %lx:%lx => %lx:%lx\n", + a.v[0], a.v[1], b.v[0], b.v[1], m.v[0], m.v[1]); + printf(" = %lX%08lX * %lX%08lX => %lX%08lX\n", + a.v[0], a.v[1], b.v[0], b.v[1], m.v[0], m.v[1]); + } + exit(0); +} diff --git a/lib/libc/regex/Makefile.inc b/lib/libc/regex/Makefile.inc new file mode 100644 index 0000000..11a9665 --- /dev/null +++ b/lib/libc/regex/Makefile.inc @@ -0,0 +1,17 @@ +# from @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 +# $FreeBSD: releng/11.1/lib/libc/regex/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +# regex sources +.PATH: ${LIBC_SRCTOP}/regex + +CFLAGS+=-DPOSIX_MISTAKE + +SRCS+= regcomp.c regerror.c regexec.c regfree.c + +SYM_MAPS+=${LIBC_SRCTOP}/regex/Symbol.map + +MAN+= regex.3 +MAN+= re_format.7 + +MLINKS+=regex.3 regcomp.3 regex.3 regexec.3 regex.3 regerror.3 +MLINKS+=regexec.3 regfree.3 diff --git a/lib/libc/regex/Symbol.map b/lib/libc/regex/Symbol.map new file mode 100644 index 0000000..b244e65 --- /dev/null +++ b/lib/libc/regex/Symbol.map @@ -0,0 +1,10 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/regex/Symbol.map 169092 2007-04-29 14:05:22Z deischen $ + */ + +FBSD_1.0 { + regcomp; + regerror; + regexec; + regfree; +}; diff --git a/lib/libc/regex/WHATSNEW b/lib/libc/regex/WHATSNEW new file mode 100644 index 0000000..f4301d3 --- /dev/null +++ b/lib/libc/regex/WHATSNEW @@ -0,0 +1,94 @@ +# @(#)WHATSNEW 8.3 (Berkeley) 3/18/94 + +New in alpha3.4: The complex bug alluded to below has been fixed (in a +slightly kludgey temporary way that may hurt efficiency a bit; this is +another "get it out the door for 4.4" release). The tests at the end of +the tests file have accordingly been uncommented. The primary sign of +the bug was that something like a?b matching ab matched b rather than ab. +(The bug was essentially specific to this exact situation, else it would +have shown up earlier.) + +New in alpha3.3: The definition of word boundaries has been altered +slightly, to more closely match the usual programming notion that "_" +is an alphabetic. Stuff used for pre-ANSI systems is now in a subdir, +and the makefile no longer alludes to it in mysterious ways. The +makefile has generally been cleaned up some. Fixes have been made +(again!) so that the regression test will run without -DREDEBUG, at +the cost of weaker checking. A workaround for a bug in some folks' + has been added. And some more things have been added to +tests, including a couple right at the end which are commented out +because the code currently flunks them (complex bug; fix coming). +Plus the usual minor cleanup. + +New in alpha3.2: Assorted bits of cleanup and portability improvement +(the development base is now a BSDI system using GCC instead of an ancient +Sun system, and the newer compiler exposed some glitches). Fix for a +serious bug that affected REs using many [] (including REG_ICASE REs +because of the way they are implemented), *sometimes*, depending on +memory-allocation patterns. The header-file prototypes no longer name +the parameters, avoiding possible name conflicts. The possibility that +some clot has defined CHAR_MIN as (say) `-128' instead of `(-128)' is +now handled gracefully. "uchar" is no longer used as an internal type +name (too many people have the same idea). Still the same old lousy +performance, alas. + +New in alpha3.1: Basically nothing, this release is just a bookkeeping +convenience. Stay tuned. + +New in alpha3.0: Performance is no better, alas, but some fixes have been +made and some functionality has been added. (This is basically the "get +it out the door in time for 4.4" release.) One bug fix: regfree() didn't +free the main internal structure (how embarrassing). It is now possible +to put NULs in either the RE or the target string, using (resp.) a new +REG_PEND flag and the old REG_STARTEND flag. The REG_NOSPEC flag to +regcomp() makes all characters ordinary, so you can match a literal +string easily (this will become more useful when performance improves!). +There are now primitives to match beginnings and ends of words, although +the syntax is disgusting and so is the implementation. The REG_ATOI +debugging interface has changed a bit. And there has been considerable +internal cleanup of various kinds. + +New in alpha2.3: Split change list out of README, and moved flags notes +into Makefile. Macro-ized the name of regex(7) in regex(3), since it has +to change for 4.4BSD. Cleanup work in engine.c, and some new regression +tests to catch tricky cases thereof. + +New in alpha2.2: Out-of-date manpages updated. Regerror() acquires two +small extensions -- REG_ITOA and REG_ATOI -- which avoid debugging kludges +in my own test program and might be useful to others for similar purposes. +The regression test will now compile (and run) without REDEBUG. The +BRE \$ bug is fixed. Most uses of "uchar" are gone; it's all chars now. +Char/uchar parameters are now written int/unsigned, to avoid possible +portability problems with unpromoted parameters. Some unsigned casts have +been introduced to minimize portability problems with shifting into sign +bits. + +New in alpha2.1: Lots of little stuff, cleanup and fixes. The one big +thing is that regex.h is now generated, using mkh, rather than being +supplied in the distribution; due to circularities in dependencies, +you have to build regex.h explicitly by "make h". The two known bugs +have been fixed (and the regression test now checks for them), as has a +problem with assertions not being suppressed in the absence of REDEBUG. +No performance work yet. + +New in alpha2: Backslash-anything is an ordinary character, not an +error (except, of course, for the handful of backslashed metacharacters +in BREs), which should reduce script breakage. The regression test +checks *where* null strings are supposed to match, and has generally +been tightened up somewhat. Small bug fixes in parameter passing (not +harmful, but technically errors) and some other areas. Debugging +invoked by defining REDEBUG rather than not defining NDEBUG. + +New in alpha+3: full prototyping for internal routines, using a little +helper program, mkh, which extracts prototypes given in stylized comments. +More minor cleanup. Buglet fix: it's CHAR_BIT, not CHAR_BITS. Simple +pre-screening of input when a literal string is known to be part of the +RE; this does wonders for performance. + +New in alpha+2: minor bits of cleanup. Notably, the number "32" for the +word width isn't hardwired into regexec.c any more, the public header +file prototypes the functions if __STDC__ is defined, and some small typos +in the manpages have been fixed. + +New in alpha+1: improvements to the manual pages, and an important +extension, the REG_STARTEND option to regexec(). diff --git a/lib/libc/regex/grot/Makefile b/lib/libc/regex/grot/Makefile new file mode 100644 index 0000000..1f6b013 --- /dev/null +++ b/lib/libc/regex/grot/Makefile @@ -0,0 +1,99 @@ +# $FreeBSD: releng/11.1/lib/libc/regex/grot/Makefile 313240 2017-02-04 17:17:38Z ngie $ +# You probably want to take -DREDEBUG out of CFLAGS, and put something like +# -O in, *after* testing (-DREDEBUG strengthens testing by enabling a lot of +# internal assertion checking). Take -Dconst= out for an ANSI compiler. +# Do not take -DPOSIX_MISTAKE out. REGCFLAGS isn't important to you (it's +# for my use in some special contexts). + +PATHS= ${LIBC_SRCTOP}/regex ${LIBC_SRCTOP}/locale ${SRCTOP}/include +.PATH: ${PATHS} + +CFLAGS+= -static -DPOSIX_MISTAKE -DREDEBUG $(REGCFLAGS) +.for incpath in ${PATHS} +CFLAGS+= -I${incpath} +.endfor + +# If you have an ANSI compiler, take -o out of MKHFLAGS. If you want +# the Berkeley __P macro, put -b in. +MKHFLAGS = + +LDFLAGS = + +# If you have an ANSI environment, take limits.h and stdlib.h out of +# HMISSING and take memmove out of SRCMISSING and OBJMISSING. +HMISSING = +SRCMISSING = split.c +OBJMISSING = split.o +H = cname.h regex2.h utils.h $(HMISSING) +REGSRC = regcomp.c regerror.c regexec.c regfree.c engine.c +SRC = $(REGSRC) debug.c main.c $(SRCMISSING) + +# Internal stuff, should not need changing. +OBJPRODN = regcomp.o regexec.o regerror.o regfree.o +OBJS = $(OBJPRODN) debug.o main.o $(OBJMISSING) + +# Stuff that matters only if you're trying to lint the package. +LINTFLAGS = -I. -Dstatic= -Dconst= -DREDEBUG +LINTC = regcomp.c regexec.c regerror.c regfree.c debug.c main.c $(SRCMISSING) +JUNKLINT =possible pointer alignment|null effect + +.SUFFIXES: .ih .h +.c.ih: + sh mkh $(MKHFLAGS) -p $< >$@ + +default: r + +re: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $@ + +o: $(OBJPRODN) + +REGEXHSRC = ../regex2.h ../reg*.c +h: $(REGEXHSRC) + sh mkh $(MKHFLAGS) -i _REGEX_H_ $(REGEXHSRC) >regex.tmp + cmp -s regex.tmp regex.h 2>/dev/null || cp regex.tmp regex.h + rm -f regex.tmp + +regex.h: h + +regcomp.o regexec.o regfree.o debug.o: utils.h regex.h regex2.h +regcomp.o: cname.h regcomp.ih +regexec.o: engine.c engine.ih +regerror.o: regerror.ih +regerror.o: utils.h +debug.o: debug.ih +main.o: debug.ih main.ih split.ih +split.o: split.ih + +r: re tests + ./re &1 | egrep -v '$(JUNKLINT)' | tee lint + +clean: tidy + rm -f *.o *.s *.ih re + +tidy: + rm -f junk* core regex.tmp lint + +spotless: clean + rm -f regex.h diff --git a/lib/libc/regex/grot/debug.c b/lib/libc/regex/grot/debug.c new file mode 100644 index 0000000..076048b --- /dev/null +++ b/lib/libc/regex/grot/debug.c @@ -0,0 +1,212 @@ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/regex/grot/debug.c 291832 2015-12-05 01:12:58Z ngie $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "regex2.h" +#include "debug.ih" + +/* + - regprint - print a regexp for debugging + == void regprint(regex_t *r, FILE *d); + */ +void +regprint(r, d) +regex_t *r; +FILE *d; +{ + struct re_guts *g = r->re_g; + int i; + int c; + int last; + + fprintf(d, "%ld states", (long)g->nstates); + fprintf(d, ", first %ld last %ld", (long)g->firststate, + (long)g->laststate); + if (g->iflags&USEBOL) + fprintf(d, ", USEBOL"); + if (g->iflags&USEEOL) + fprintf(d, ", USEEOL"); + if (g->iflags&BAD) + fprintf(d, ", BAD"); + if (g->nsub > 0) + fprintf(d, ", nsub=%ld", (long)g->nsub); + if (g->must != NULL) + fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen, + g->must); + if (g->backrefs) + fprintf(d, ", backrefs"); + if (g->nplus > 0) + fprintf(d, ", nplus %ld", (long)g->nplus); + fprintf(d, "\n"); + s_print(g, d); +} + +/* + - s_print - print the strip for debugging + == static void s_print(struct re_guts *g, FILE *d); + */ +static void +s_print(g, d) +struct re_guts *g; +FILE *d; +{ + sop *s; + cset *cs; + int i; + int done = 0; + sop opnd; + int col = 0; + int last; + sopno offset = 2; +# define GAP() { if (offset % 5 == 0) { \ + if (col > 40) { \ + fprintf(d, "\n\t"); \ + col = 0; \ + } else { \ + fprintf(d, " "); \ + col++; \ + } \ + } else \ + col++; \ + offset++; \ + } + + if (OP(g->strip[0]) != OEND) + fprintf(d, "missing initial OEND!\n"); + for (s = &g->strip[1]; !done; s++) { + opnd = OPND(*s); + switch (OP(*s)) { + case OEND: + fprintf(d, "\n"); + done = 1; + break; + case OCHAR: + if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL) + fprintf(d, "\\%c", (char)opnd); + else + fprintf(d, "%s", regchar((char)opnd)); + break; + case OBOL: + fprintf(d, "^"); + break; + case OEOL: + fprintf(d, "$"); + break; + case OBOW: + fprintf(d, "\\{"); + break; + case OEOW: + fprintf(d, "\\}"); + break; + case OANY: + fprintf(d, "."); + break; + case OANYOF: + fprintf(d, "[(%ld)", (long)opnd); +#if 0 + cs = &g->sets[opnd]; + last = -1; + for (i = 0; i < g->csetsize+1; i++) /* +1 flushes */ + if (CHIN(cs, i) && i < g->csetsize) { + if (last < 0) { + fprintf(d, "%s", regchar(i)); + last = i; + } + } else { + if (last >= 0) { + if (last != i-1) + fprintf(d, "-%s", + regchar(i-1)); + last = -1; + } + } +#endif + fprintf(d, "]"); + break; + case OBACK_: + fprintf(d, "(\\<%ld>", (long)opnd); + break; + case O_BACK: + fprintf(d, "<%ld>\\)", (long)opnd); + break; + case OPLUS_: + fprintf(d, "(+"); + if (OP(*(s+opnd)) != O_PLUS) + fprintf(d, "<%ld>", (long)opnd); + break; + case O_PLUS: + if (OP(*(s-opnd)) != OPLUS_) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, "+)"); + break; + case OQUEST_: + fprintf(d, "(?"); + if (OP(*(s+opnd)) != O_QUEST) + fprintf(d, "<%ld>", (long)opnd); + break; + case O_QUEST: + if (OP(*(s-opnd)) != OQUEST_) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, "?)"); + break; + case OLPAREN: + fprintf(d, "((<%ld>", (long)opnd); + break; + case ORPAREN: + fprintf(d, "<%ld>))", (long)opnd); + break; + case OCH_: + fprintf(d, "<"); + if (OP(*(s+opnd)) != OOR2) + fprintf(d, "<%ld>", (long)opnd); + break; + case OOR1: + if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, "|"); + break; + case OOR2: + fprintf(d, "|"); + if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH) + fprintf(d, "<%ld>", (long)opnd); + break; + case O_CH: + if (OP(*(s-opnd)) != OOR1) + fprintf(d, "<%ld>", (long)opnd); + fprintf(d, ">"); + break; + default: + fprintf(d, "!%ld(%ld)!", OP(*s), (long)opnd); + break; + } + if (!done) + GAP(); + } +} + +/* + - regchar - make a character printable + == static char *regchar(int ch); + */ +static char * /* -> representation */ +regchar(ch) +int ch; +{ + static char buf[10]; + + if (isprint(ch) || ch == ' ') + sprintf(buf, "%c", ch); + else + sprintf(buf, "\\%o", ch); + return(buf); +} diff --git a/lib/libc/regex/grot/main.c b/lib/libc/regex/grot/main.c new file mode 100644 index 0000000..d19c34c --- /dev/null +++ b/lib/libc/regex/grot/main.c @@ -0,0 +1,494 @@ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/regex/grot/main.c 291838 2015-12-05 02:25:20Z ngie $"); + +#include +#include +#include +#include +#include +#include +#include + +#include "debug.ih" +#include "main.ih" +#include "split.ih" + +char *progname; +int debug = 0; +int line = 0; +int status = 0; + +int copts = REG_EXTENDED; +int eopts = 0; +regoff_t startoff = 0; +regoff_t endoff = 0; + + +/* + - main - do the simple case, hand off to regress() for regression + */ +int +main(int argc, char **argv) +{ + regex_t re; +# define NS 10 + regmatch_t subs[NS]; + char erbuf[100]; + int err; + size_t len; + int c; + int errflg = 0; + int i; + extern int optind; + extern char *optarg; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "c:e:S:E:x")) != -1) + switch (c) { + case 'c': /* compile options */ + copts = options('c', optarg); + break; + case 'e': /* execute options */ + eopts = options('e', optarg); + break; + case 'S': /* start offset */ + startoff = (regoff_t)atoi(optarg); + break; + case 'E': /* end offset */ + endoff = (regoff_t)atoi(optarg); + break; + case 'x': /* Debugging. */ + debug++; + break; + case '?': + default: + errflg++; + break; + } + if (errflg) { + fprintf(stderr, "usage: %s ", progname); + fprintf(stderr, "[-c copt][-C][-d] [re]\n"); + exit(2); + } + + if (optind >= argc) { + regress(stdin); + exit(status); + } + + err = regcomp(&re, argv[optind++], copts); + if (err) { + len = regerror(err, &re, erbuf, sizeof(erbuf)); + fprintf(stderr, "error %s, %zu/%zu `%s'\n", + eprint(err), len, sizeof(erbuf), erbuf); + exit(status); + } + regprint(&re, stdout); + + if (optind >= argc) { + regfree(&re); + exit(status); + } + + if ((eopts & REG_STARTEND) != 0) { + subs[0].rm_so = startoff; + subs[0].rm_eo = strlen(argv[optind]) - endoff; + } + err = regexec(&re, argv[optind], (size_t)NS, subs, eopts); + if (err) { + len = regerror(err, &re, erbuf, sizeof(erbuf)); + fprintf(stderr, "error %s, %zu/%zu `%s'\n", + eprint(err), len, sizeof(erbuf), erbuf); + exit(status); + } + if ((copts & REG_NOSUB) == 0) { + len = (int)(subs[0].rm_eo - subs[0].rm_so); + if (subs[0].rm_so != -1) { + if (len != 0) + printf("match `%.*s'\n", (int)len, + argv[optind] + subs[0].rm_so); + else + printf("match `'@%.1s\n", + argv[optind] + subs[0].rm_so); + } + for (i = 1; i < NS; i++) + if (subs[i].rm_so != -1) + printf("(%d) `%.*s'\n", i, + (int)(subs[i].rm_eo - subs[i].rm_so), + argv[optind] + subs[i].rm_so); + } + exit(status); +} + +/* + - regress - main loop of regression test + == void regress(FILE *in); + */ +void +regress(FILE *in) +{ + char inbuf[1000]; +# define MAXF 10 + char *f[MAXF]; + int nf; + int i; + char erbuf[100]; + size_t ne; + char *badpat = "invalid regular expression"; +# define SHORT 10 + char *bpname = "REG_BADPAT"; + regex_t re; + + while (fgets(inbuf, sizeof(inbuf), in) != NULL) { + line++; + if (inbuf[0] == '#' || inbuf[0] == '\n') + continue; /* NOTE CONTINUE */ + inbuf[strlen(inbuf)-1] = '\0'; /* get rid of stupid \n */ + if (debug) + fprintf(stdout, "%d:\n", line); + nf = split(inbuf, f, MAXF, "\t\t"); + if (nf < 3) { + fprintf(stderr, "bad input, line %d\n", line); + exit(1); + } + for (i = 0; i < nf; i++) + if (strcmp(f[i], "\"\"") == 0) + f[i] = ""; + if (nf <= 3) + f[3] = NULL; + if (nf <= 4) + f[4] = NULL; + try(f[0], f[1], f[2], f[3], f[4], options('c', f[1])); + if (opt('&', f[1])) /* try with either type of RE */ + try(f[0], f[1], f[2], f[3], f[4], + options('c', f[1]) &~ REG_EXTENDED); + } + + ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf)); + if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) { + fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n", + erbuf, badpat); + status = 1; + } + ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, (size_t)SHORT); + if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' || + ne != strlen(badpat)+1) { + fprintf(stderr, "end: regerror() short test gave `%s' not `%.*s'\n", + erbuf, SHORT-1, badpat); + status = 1; + } + ne = regerror(REG_ITOA|REG_BADPAT, (regex_t *)NULL, erbuf, sizeof(erbuf)); + if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname) + 1) { + fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n", + erbuf, bpname); + status = 1; + } + re.re_endp = bpname; + ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf)); + if (atoi(erbuf) != (int)REG_BADPAT) { + fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n", + erbuf, (long)REG_BADPAT); + status = 1; + } else if (ne != strlen(erbuf) + 1) { + fprintf(stderr, "end: regerror() ATOI test len(`%s') = %ld\n", + erbuf, (long)REG_BADPAT); + status = 1; + } +} + +/* + - try - try it, and report on problems + == void try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts); + - opts: may not match f1 + */ +void +try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts) +{ + regex_t re; +# define NSUBS 10 + regmatch_t subs[NSUBS]; +# define NSHOULD 15 + char *should[NSHOULD]; + char erbuf[100]; + size_t len; + int err, i, nshould; + char *grump; + char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE"; + char f0copy[1000]; + char f2copy[1000]; + + strcpy(f0copy, f0); + re.re_endp = (opts®_PEND) ? f0copy + strlen(f0copy) : NULL; + fixstr(f0copy); + err = regcomp(&re, f0copy, opts); + if (err != 0 && (!opt('C', f1) || err != efind(f2))) { + /* unexpected error or wrong error */ + len = regerror(err, &re, erbuf, sizeof(erbuf)); + fprintf(stderr, "%d: %s error %s, %zu/%zu `%s'\n", + line, type, eprint(err), len, sizeof(erbuf), erbuf); + status = 1; + } else if (err == 0 && opt('C', f1)) { + /* unexpected success */ + fprintf(stderr, "%d: %s should have given REG_%s\n", + line, type, f2); + status = 1; + err = 1; /* so we won't try regexec */ + } + + if (err != 0) { + regfree(&re); + return; + } + + strcpy(f2copy, f2); + fixstr(f2copy); + + if (options('e', f1)®_STARTEND) { + if (strchr(f2, '(') == NULL || strchr(f2, ')') == NULL) + fprintf(stderr, "%d: bad STARTEND syntax\n", line); + subs[0].rm_so = strchr(f2, '(') - f2 + 1; + subs[0].rm_eo = strchr(f2, ')') - f2; + } + err = regexec(&re, f2copy, NSUBS, subs, options('e', f1)); + + if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) { + /* unexpected error or wrong error */ + len = regerror(err, &re, erbuf, sizeof(erbuf)); + fprintf(stderr, "%d: %s exec error %s, %zu/%zu `%s'\n", + line, type, eprint(err), len, sizeof(erbuf), erbuf); + status = 1; + } else if (err != 0) { + /* nothing more to check */ + } else if (f3 == NULL) { + /* unexpected success */ + fprintf(stderr, "%d: %s exec should have failed\n", + line, type); + status = 1; + err = 1; /* just on principle */ + } else if (opts®_NOSUB) { + /* nothing more to check */ + } else if ((grump = check(f2, subs[0], f3)) != NULL) { + fprintf(stderr, "%d: %s %s\n", line, type, grump); + status = 1; + err = 1; + } + + if (err != 0 || f4 == NULL) { + regfree(&re); + return; + } + + for (i = 1; i < NSHOULD; i++) + should[i] = NULL; + nshould = split(f4, should+1, NSHOULD-1, ","); + if (nshould == 0) { + nshould = 1; + should[1] = ""; + } + for (i = 1; i < NSUBS; i++) { + grump = check(f2, subs[i], should[i]); + if (grump != NULL) { + fprintf(stderr, "%d: %s $%d %s\n", line, + type, i, grump); + status = 1; + err = 1; + } + } + + regfree(&re); +} + +/* + - options - pick options out of a regression-test string + - type: 'c' - compile, 'e' - exec + == int options(int type, char *s); + */ +int +options(int type, char *s) +{ + char *p; + int o = (type == 'c') ? copts : eopts; + char *legal = (type == 'c') ? "bisnmp" : "^$#tl"; + + for (p = s; *p != '\0'; p++) + if (strchr(legal, *p) != NULL) + switch (*p) { + case 'b': + o &= ~REG_EXTENDED; + break; + case 'i': + o |= REG_ICASE; + break; + case 's': + o |= REG_NOSUB; + break; + case 'n': + o |= REG_NEWLINE; + break; + case 'm': + o &= ~REG_EXTENDED; + o |= REG_NOSPEC; + break; + case 'p': + o |= REG_PEND; + break; + case '^': + o |= REG_NOTBOL; + break; + case '$': + o |= REG_NOTEOL; + break; + case '#': + o |= REG_STARTEND; + break; + case 't': /* trace */ + o |= REG_TRACE; + break; + case 'l': /* force long representation */ + o |= REG_LARGE; + break; + case 'r': /* force backref use */ + o |= REG_BACKR; + break; + } + return(o); +} + +/* + - opt - is a particular option in a regression string? + == int opt(int c, char *s); + */ +int /* predicate */ +opt(int c, char *s) +{ + return(strchr(s, c) != NULL); +} + +/* + - fixstr - transform magic characters in strings + == void fixstr(char *p); + */ +void +fixstr(char *p) +{ + if (p == NULL) + return; + + for (; *p != '\0'; p++) + if (*p == 'N') + *p = '\n'; + else if (*p == 'T') + *p = '\t'; + else if (*p == 'S') + *p = ' '; + else if (*p == 'Z') + *p = '\0'; +} + +/* + - check - check a substring match + == char *check(char *str, regmatch_t sub, char *should); + */ +char * /* NULL or complaint */ +check(char *str, regmatch_t sub, char *should) +{ + int len; + int shlen; + char *p; + static char grump[500]; + char *at = NULL; + + if (should != NULL && strcmp(should, "-") == 0) + should = NULL; + if (should != NULL && should[0] == '@') { + at = should + 1; + should = ""; + } + + /* check rm_so and rm_eo for consistency */ + if (sub.rm_so > sub.rm_eo || (sub.rm_so == -1 && sub.rm_eo != -1) || + (sub.rm_so != -1 && sub.rm_eo == -1) || + (sub.rm_so != -1 && sub.rm_so < 0) || + (sub.rm_eo != -1 && sub.rm_eo < 0) ) { + sprintf(grump, "start %ld end %ld", (long)sub.rm_so, + (long)sub.rm_eo); + return(grump); + } + + /* check for no match */ + if (sub.rm_so == -1 && should == NULL) + return(NULL); + if (sub.rm_so == -1) + return("did not match"); + + /* check for in range */ + if (sub.rm_eo > strlen(str)) { + sprintf(grump, "start %ld end %ld, past end of string", + (long)sub.rm_so, (long)sub.rm_eo); + return(grump); + } + + len = (int)(sub.rm_eo - sub.rm_so); + shlen = (int)strlen(should); + p = str + sub.rm_so; + + /* check for not supposed to match */ + if (should == NULL) { + sprintf(grump, "matched `%.*s'", len, p); + return(grump); + } + + /* check for wrong match */ + if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) { + sprintf(grump, "matched `%.*s' instead", len, p); + return(grump); + } + if (shlen > 0) + return(NULL); + + /* check null match in right place */ + if (at == NULL) + return(NULL); + shlen = strlen(at); + if (shlen == 0) + shlen = 1; /* force check for end-of-string */ + if (strncmp(p, at, shlen) != 0) { + sprintf(grump, "matched null at `%.20s'", p); + return(grump); + } + return(NULL); +} + +/* + - eprint - convert error number to name + == static char *eprint(int err); + */ +static char * +eprint(int err) +{ + static char epbuf[100]; + size_t len; + + len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf)); + assert(len <= sizeof(epbuf)); + return(epbuf); +} + +/* + - efind - convert error name to number + == static int efind(char *name); + */ +static int +efind(char *name) +{ + static char efbuf[100]; + size_t n; + regex_t re; + + sprintf(efbuf, "REG_%s", name); + assert(strlen(efbuf) < sizeof(efbuf)); + re.re_endp = efbuf; + (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf)); + return(atoi(efbuf)); +} diff --git a/lib/libc/regex/grot/mkh b/lib/libc/regex/grot/mkh new file mode 100755 index 0000000..1a05101 --- /dev/null +++ b/lib/libc/regex/grot/mkh @@ -0,0 +1,77 @@ +#! /bin/sh +# mkh - pull headers out of C source +# $FreeBSD: releng/11.1/lib/libc/regex/grot/mkh 92971 2002-03-22 19:45:43Z obrien $ +PATH=/bin:/usr/bin ; export PATH + +# egrep pattern to pick out marked lines +egrep='^ =([ ]|$)' + +# Sed program to process marked lines into lines for the header file. +# The markers have already been removed. Two things are done here: removal +# of backslashed newlines, and some fudging of comments. The first is done +# because -o needs to have prototypes on one line to strip them down. +# Getting comments into the output is tricky; we turn C++-style // comments +# into /* */ comments, after altering any existing */'s to avoid trouble. +peel=' /\\$/N + /\\\n[ ]*/s///g + /\/\//s;\*/;* /;g + /\/\//s;//\(.*\);/*\1 */;' + +for a +do + case "$a" in + -o) # old (pre-function-prototype) compiler + # add code to comment out argument lists + peel="$peel + "'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1(/*\2*/);' + shift + ;; + -b) # funny Berkeley __P macro + peel="$peel + "'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1 __P((\2));' + shift + ;; + -s) # compiler doesn't like `static foo();' + # add code to get rid of the `static' + peel="$peel + "'/^static[ ][^\/]*[a-zA-Z0-9_)](.*)/s;static.;;' + shift + ;; + -p) # private declarations + egrep='^ ==([ ]|$)' + shift + ;; + -i) # wrap in #ifndef, argument is name + ifndef="$2" + shift ; shift + ;; + *) break + ;; + esac +done + +if test " $ifndef" != " " +then + echo "#ifndef $ifndef" + echo "#define $ifndef /* never again */" +fi +echo "/* ========= begin header generated by $0 ========= */" +echo '#ifdef __cplusplus' +echo 'extern "C" {' +echo '#endif' +for f +do + echo + echo "/* === $f === */" + egrep "$egrep" $f | sed 's/^ ==*[ ]//;s/^ ==*$//' | sed "$peel" + echo +done +echo '#ifdef __cplusplus' +echo '}' +echo '#endif' +echo "/* ========= end header generated by $0 ========= */" +if test " $ifndef" != " " +then + echo "#endif" +fi +exit 0 diff --git a/lib/libc/regex/grot/split.c b/lib/libc/regex/grot/split.c new file mode 100644 index 0000000..df20f4a --- /dev/null +++ b/lib/libc/regex/grot/split.c @@ -0,0 +1,316 @@ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/regex/grot/split.c 291837 2015-12-05 02:23:44Z ngie $"); + +#include +#include + +#include "split.ih" + +/* + - split - divide a string into fields, like awk split() + == int split(char *string, char *fields[], int nfields, char *sep); + - fields: list is not NULL-terminated + - nfields: number of entries available in fields[] + - sep: "" white, "c" single char, "ab" [ab]+ + */ +int /* number of fields, including overflow */ +split(char *string, char *fields[], int nfields, char *sep) +{ + char *p = string; + char c; /* latest character */ + char sepc = sep[0]; + char sepc2; + int fn; + char **fp = fields; + char *sepp; + int trimtrail; + + /* white space */ + if (sepc == '\0') { + while ((c = *p++) == ' ' || c == '\t') + continue; + p--; + trimtrail = 1; + sep = " \t"; /* note, code below knows this is 2 long */ + sepc = ' '; + } else + trimtrail = 0; + sepc2 = sep[1]; /* now we can safely pick this up */ + + /* catch empties */ + if (*p == '\0') + return(0); + + /* single separator */ + if (sepc2 == '\0') { + fn = nfields; + for (;;) { + *fp++ = p; + fn--; + if (fn == 0) + break; + while ((c = *p++) != sepc) + if (c == '\0') + return(nfields - fn); + *(p-1) = '\0'; + } + /* we have overflowed the fields vector -- just count them */ + fn = nfields; + for (;;) { + while ((c = *p++) != sepc) + if (c == '\0') + return(fn); + fn++; + } + /* not reached */ + } + + /* two separators */ + if (sep[2] == '\0') { + fn = nfields; + for (;;) { + *fp++ = p; + fn--; + while ((c = *p++) != sepc && c != sepc2) + if (c == '\0') { + if (trimtrail && **(fp-1) == '\0') + fn++; + return(nfields - fn); + } + if (fn == 0) + break; + *(p-1) = '\0'; + while ((c = *p++) == sepc || c == sepc2) + continue; + p--; + } + /* we have overflowed the fields vector -- just count them */ + fn = nfields; + while (c != '\0') { + while ((c = *p++) == sepc || c == sepc2) + continue; + p--; + fn++; + while ((c = *p++) != '\0' && c != sepc && c != sepc2) + continue; + } + /* might have to trim trailing white space */ + if (trimtrail) { + p--; + while ((c = *--p) == sepc || c == sepc2) + continue; + p++; + if (*p != '\0') { + if (fn == nfields+1) + *p = '\0'; + fn--; + } + } + return(fn); + } + + /* n separators */ + fn = 0; + for (;;) { + if (fn < nfields) + *fp++ = p; + fn++; + for (;;) { + c = *p++; + if (c == '\0') + return(fn); + sepp = sep; + while ((sepc = *sepp++) != '\0' && sepc != c) + continue; + if (sepc != '\0') /* it was a separator */ + break; + } + if (fn < nfields) + *(p-1) = '\0'; + for (;;) { + c = *p++; + sepp = sep; + while ((sepc = *sepp++) != '\0' && sepc != c) + continue; + if (sepc == '\0') /* it wasn't a separator */ + break; + } + p--; + } + + /* not reached */ +} + +#ifdef TEST_SPLIT + + +/* + * test program + * pgm runs regression + * pgm sep splits stdin lines by sep + * pgm str sep splits str by sep + * pgm str sep n splits str by sep n times + */ +int +main(int argc, char *argv[]) +{ + char buf[512]; + int n; +# define MNF 10 + char *fields[MNF]; + + if (argc > 4) + for (n = atoi(argv[3]); n > 0; n--) { + (void) strcpy(buf, argv[1]); + } + else if (argc > 3) + for (n = atoi(argv[3]); n > 0; n--) { + (void) strcpy(buf, argv[1]); + (void) split(buf, fields, MNF, argv[2]); + } + else if (argc > 2) + dosplit(argv[1], argv[2]); + else if (argc > 1) + while (fgets(buf, sizeof(buf), stdin) != NULL) { + buf[strlen(buf)-1] = '\0'; /* stomp newline */ + dosplit(buf, argv[1]); + } + else + regress(); + + exit(0); +} + +void +dosplit(char *string, char *seps) +{ +# define NF 5 + char *fields[NF]; + int nf; + + nf = split(string, fields, NF, seps); + print(nf, NF, fields); +} + +void +print(int nf, int nfp, char *fields[]) +{ + int fn; + int bound; + + bound = (nf > nfp) ? nfp : nf; + printf("%d:\t", nf); + for (fn = 0; fn < bound; fn++) + printf("\"%s\"%s", fields[fn], (fn+1 < nf) ? ", " : "\n"); +} + +#define RNF 5 /* some table entries know this */ +struct { + char *str; + char *seps; + int nf; + char *fi[RNF]; +} tests[] = { + "", " ", 0, { "" }, + " ", " ", 2, { "", "" }, + "x", " ", 1, { "x" }, + "xy", " ", 1, { "xy" }, + "x y", " ", 2, { "x", "y" }, + "abc def g ", " ", 5, { "abc", "def", "", "g", "" }, + " a bcd", " ", 4, { "", "", "a", "bcd" }, + "a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" }, + " a b c d ", " ", 6, { "", "a", "b", "c", "d " }, + + "", " _", 0, { "" }, + " ", " _", 2, { "", "" }, + "x", " _", 1, { "x" }, + "x y", " _", 2, { "x", "y" }, + "ab _ cd", " _", 2, { "ab", "cd" }, + " a_b c ", " _", 5, { "", "a", "b", "c", "" }, + "a b c_d e f", " _", 6, { "a", "b", "c", "d", "e f" }, + " a b c d ", " _", 6, { "", "a", "b", "c", "d " }, + + "", " _~", 0, { "" }, + " ", " _~", 2, { "", "" }, + "x", " _~", 1, { "x" }, + "x y", " _~", 2, { "x", "y" }, + "ab _~ cd", " _~", 2, { "ab", "cd" }, + " a_b c~", " _~", 5, { "", "a", "b", "c", "" }, + "a b_c d~e f", " _~", 6, { "a", "b", "c", "d", "e f" }, + "~a b c d ", " _~", 6, { "", "a", "b", "c", "d " }, + + "", " _~-", 0, { "" }, + " ", " _~-", 2, { "", "" }, + "x", " _~-", 1, { "x" }, + "x y", " _~-", 2, { "x", "y" }, + "ab _~- cd", " _~-", 2, { "ab", "cd" }, + " a_b c~", " _~-", 5, { "", "a", "b", "c", "" }, + "a b_c-d~e f", " _~-", 6, { "a", "b", "c", "d", "e f" }, + "~a-b c d ", " _~-", 6, { "", "a", "b", "c", "d " }, + + "", " ", 0, { "" }, + " ", " ", 2, { "", "" }, + "x", " ", 1, { "x" }, + "xy", " ", 1, { "xy" }, + "x y", " ", 2, { "x", "y" }, + "abc def g ", " ", 4, { "abc", "def", "g", "" }, + " a bcd", " ", 3, { "", "a", "bcd" }, + "a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" }, + " a b c d ", " ", 6, { "", "a", "b", "c", "d " }, + + "", "", 0, { "" }, + " ", "", 0, { "" }, + "x", "", 1, { "x" }, + "xy", "", 1, { "xy" }, + "x y", "", 2, { "x", "y" }, + "abc def g ", "", 3, { "abc", "def", "g" }, + "\t a bcd", "", 2, { "a", "bcd" }, + " a \tb\t c ", "", 3, { "a", "b", "c" }, + "a b c d e ", "", 5, { "a", "b", "c", "d", "e" }, + "a b\tc d e f", "", 6, { "a", "b", "c", "d", "e f" }, + " a b c d e f ", "", 6, { "a", "b", "c", "d", "e f " }, + + NULL, NULL, 0, { NULL }, +}; + +void +regress(void) +{ + char buf[512]; + int n; + char *fields[RNF+1]; + int nf; + int i; + int printit; + char *f; + + for (n = 0; tests[n].str != NULL; n++) { + (void) strcpy(buf, tests[n].str); + fields[RNF] = NULL; + nf = split(buf, fields, RNF, tests[n].seps); + printit = 0; + if (nf != tests[n].nf) { + printf("split `%s' by `%s' gave %d fields, not %d\n", + tests[n].str, tests[n].seps, nf, tests[n].nf); + printit = 1; + } else if (fields[RNF] != NULL) { + printf("split() went beyond array end\n"); + printit = 1; + } else { + for (i = 0; i < nf && i < RNF; i++) { + f = fields[i]; + if (f == NULL) + f = "(NULL)"; + if (strcmp(f, tests[n].fi[i]) != 0) { + printf("split `%s' by `%s' field %d is `%s', not `%s'\n", + tests[n].str, tests[n].seps, + i, fields[i], tests[n].fi[i]); + printit = 1; + } + } + } + if (printit) + print(nf, RNF, fields); + } +} +#endif diff --git a/lib/libc/regex/grot/tests b/lib/libc/regex/grot/tests new file mode 100644 index 0000000..d0ad36a --- /dev/null +++ b/lib/libc/regex/grot/tests @@ -0,0 +1,477 @@ +# regular expression test set +# $FreeBSD: releng/11.1/lib/libc/regex/grot/tests 197234 2009-09-15 21:15:29Z dds $ +# Lines are at least three fields, separated by one or more tabs. "" stands +# for an empty field. First field is an RE. Second field is flags. If +# C flag given, regcomp() is expected to fail, and the third field is the +# error name (minus the leading REG_). +# +# Otherwise it is expected to succeed, and the third field is the string to +# try matching it against. If there is no fourth field, the match is +# expected to fail. If there is a fourth field, it is the substring that +# the RE is expected to match. If there is a fifth field, it is a comma- +# separated list of what the subexpressions should match, with - indicating +# no match for that one. In both the fourth and fifth fields, a (sub)field +# starting with @ indicates that the (sub)expression is expected to match +# a null string followed by the stuff after the @; this provides a way to +# test where null strings match. The character `N' in REs and strings +# is newline, `S' is space, `T' is tab, `Z' is NUL. +# +# The full list of flags: +# - placeholder, does nothing +# b RE is a BRE, not an ERE +# & try it as both an ERE and a BRE +# C regcomp() error expected, third field is error name +# i REG_ICASE +# m ("mundane") REG_NOSPEC +# s REG_NOSUB (not really testable) +# n REG_NEWLINE +# ^ REG_NOTBOL +# $ REG_NOTEOL +# # REG_STARTEND (see below) +# p REG_PEND +# +# For REG_STARTEND, the start/end offsets are those of the substring +# enclosed in (). + +# basics +a & a a +abc & abc abc +abc|de - abc abc +a|b|c - abc a + +# parentheses and perversions thereof +a(b)c - abc abc +a\(b\)c b abc abc +a( C EPAREN +a( b a( a( +a\( - a( a( +a\( bC EPAREN +a\(b bC EPAREN +a(b C EPAREN +a(b b a(b a(b +# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly) +a) - a) a) +) - ) ) +# end gagging (in a just world, those *should* give EPAREN) +a) b a) a) +a\) bC EPAREN +\) bC EPAREN +a()b - ab ab +a\(\)b b ab ab + +# anchoring and REG_NEWLINE +^abc$ & abc abc +a^b - a^b +a^b b a^b a^b +a$b - a$b +a$b b a$b a$b +^ & abc @abc +$ & abc @ +^$ & "" @ +$^ - "" @ +\($\)\(^\) b "" @ +# stop retching, those are legitimate (although disgusting) +^^ - "" @ +$$ - "" @ +b$ & abNc +b$ &n abNc b +^b$ & aNbNc +^b$ &n aNbNc b +^$ &n aNNb @Nb +^$ n abc +^$ n abcN @ +$^ n aNNb @Nb +\($\)\(^\) bn aNNb @Nb +^^ n^ aNNb @Nb +$$ n aNNb @NN +^a ^ a +a$ $ a +^a ^n aNb +^b ^n aNb b +a$ $n bNa +b$ $n bNa b +a*(^b$)c* - b b +a*\(^b$\)c* b b b + +# certain syntax errors and non-errors +| C EMPTY +| b | | +* C BADRPT +* b * * ++ C BADRPT +? C BADRPT +"" &C EMPTY +() - abc @abc +\(\) b abc @abc +a||b C EMPTY +|ab C EMPTY +ab| C EMPTY +(|a)b C EMPTY +(a|)b C EMPTY +(*a) C BADRPT +(+a) C BADRPT +(?a) C BADRPT +({1}a) C BADRPT +\(\{1\}a\) bC BADRPT +(a|*b) C BADRPT +(a|+b) C BADRPT +(a|?b) C BADRPT +(a|{1}b) C BADRPT +^* C BADRPT +^* b * * +^+ C BADRPT +^? C BADRPT +^{1} C BADRPT +^\{1\} bC BADRPT + +# metacharacters, backslashes +a.c & abc abc +a[bc]d & abd abd +a\*c & a*c a*c +a\\b & a\b a\b +a\\\*b & a\*b a\*b +a\bc & abc abc +a\ &C EESCAPE +a\\bc & a\bc a\bc +\{ bC BADRPT +# trailing $ is a peculiar special case for the BRE code +a$ & a a +a$ & a$ +a\$ & a +a\$ & a$ a$ +a\\$ & a +a\\$ & a$ +a\\$ & a\$ +a\\$ & a\ a\ + +# back references, ugh +a\(b\)\2c bC ESUBREG +a\(b\1\)c bC ESUBREG +a\(b*\)c\1d b abbcbbd abbcbbd bb +a\(b*\)c\1d b abbcbd +a\(b*\)c\1d b abbcbbbd +^\(.\)\1 b abc +a\([bc]\)\1d b abcdabbd abbd b +a\(\([bc]\)\2\)*d b abbccd abbccd +a\(\([bc]\)\2\)*d b abbcbd +# actually, this next one probably ought to fail, but the spec is unclear +a\(\(b\)*\2\)*d b abbbd abbbd +# here is a case that no NFA implementation does right +\(ab*\)[ab]*\1 b ababaaa ababaaa a +# check out normal matching in the presence of back refs +\(a\)\1bcd b aabcd aabcd +\(a\)\1bc*d b aabcd aabcd +\(a\)\1bc*d b aabd aabd +\(a\)\1bc*d b aabcccd aabcccd +\(a\)\1bc*[ce]d b aabcccd aabcccd +^\(a\)\1b\(c\)*cd$ b aabcccd aabcccd +\(b*\)\(a*\1\)* b ab a +\([^_]*\)\(_*\1\)* b foo_foo_bar_bar_bar_baz foo_foo foo,_foo +\([^_]*\)\(_*\1\)* b bar_bar_bar_baz bar_bar_bar bar,_bar +\([^_]*\)\(_*\1\)* b foo_bar_baz foo foo +\(.*\)\1 b "" "" +\(.*\)\1 b a "" +\(.*\)\1 b aa aa +\(.*\)\1 b aaa aa +\(.*\)\1 b aaaa aaaa +\([^_]*\)\1 b "" "" +\([^_]*\)\1 b a "" +\([^_]*\)\1 b aa aa +\([^_]*\)\1 b aaa aa +\([^_]*\)\1 b aaaa aaaa +foo\(.*\)bar\1 b foolbarl foolbarl l +foo\(.*\)bar\1 b foobar foobar "" +\(\(.\)b\)*\1 b aba +\(\(.\)b\)*\1 b abba +\(\(.\)b\)*\1 b abbba +\(\(.\)b\)*\1 b abbbba bbbb bb,b +\(\(.\)b\)*\1 b abbbbba abbbbb bb,b +\(\(.\)b\)*\1 b abbbbbba abbbbb bb,b +\(\(.\)b\)*\1 b abbbbbbbbbbbbbba abbbbbbbbbbbbb bb,b +\(\(.\)b\)*\1 b abbbbbbbbbbbbbbba abbbbbbbbbbbbbbb bb,b + +# ordinary repetitions +ab*c & abc abc +ab+c - abc abc +ab?c - abc abc +a\(*\)b b a*b a*b +a\(**\)b b ab ab +a\(***\)b bC BADRPT +*a b *a *a +**a b a a +***a bC BADRPT + +# the dreaded bounded repetitions +{ & { { +{abc & {abc {abc +{1 C BADRPT +{1} C BADRPT +a{b & a{b a{b +a{1}b - ab ab +a\{1\}b b ab ab +a{1,}b - ab ab +a\{1,\}b b ab ab +a{1,2}b - aab aab +a\{1,2\}b b aab aab +a{1 C EBRACE +a\{1 bC EBRACE +a{1a C EBRACE +a\{1a bC EBRACE +a{1a} C BADBR +a\{1a\} bC BADBR +a{,2} - a{,2} a{,2} +a\{,2\} bC BADBR +a{,} - a{,} a{,} +a\{,\} bC BADBR +a{1,x} C BADBR +a\{1,x\} bC BADBR +a{1,x C EBRACE +a\{1,x bC EBRACE +a{300} C BADBR +a\{300\} bC BADBR +a{1,0} C BADBR +a\{1,0\} bC BADBR +ab{0,0}c - abcac ac +ab\{0,0\}c b abcac ac +ab{0,1}c - abcac abc +ab\{0,1\}c b abcac abc +ab{0,3}c - abbcac abbc +ab\{0,3\}c b abbcac abbc +ab{1,1}c - acabc abc +ab\{1,1\}c b acabc abc +ab{1,3}c - acabc abc +ab\{1,3\}c b acabc abc +ab{2,2}c - abcabbc abbc +ab\{2,2\}c b abcabbc abbc +ab{2,4}c - abcabbc abbc +ab\{2,4\}c b abcabbc abbc +((a{1,10}){1,10}){1,10} - a a a,a +((a{1,10}){1,10}){1,10}bb - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb aaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb + +# multiple repetitions +a** &C BADRPT +a++ C BADRPT +a?? C BADRPT +a*+ C BADRPT +a*? C BADRPT +a+* C BADRPT +a+? C BADRPT +a?* C BADRPT +a?+ C BADRPT +a{1}{1} C BADRPT +a*{1} C BADRPT +a+{1} C BADRPT +a?{1} C BADRPT +a{1}* C BADRPT +a{1}+ C BADRPT +a{1}? C BADRPT +a*{b} - a{b} a{b} +a\{1\}\{1\} bC BADRPT +a*\{1\} bC BADRPT +a\{1\}* bC BADRPT + +# brackets, and numerous perversions thereof +a[b]c & abc abc +a[ab]c & abc abc +a[^ab]c & adc adc +a[]b]c & a]c a]c +a[[b]c & a[c a[c +a[-b]c & a-c a-c +a[^]b]c & adc adc +a[^-b]c & adc adc +a[b-]c & a-c a-c +a[b &C EBRACK +a[] &C EBRACK +a[1-3]c & a2c a2c +a[3-1]c &C ERANGE +a[1-3-5]c &C ERANGE +a[[.-.]--]c & a-c a-c +a[1- &C ERANGE +a[[. &C EBRACK +a[[.x &C EBRACK +a[[.x. &C EBRACK +a[[.x.] &C EBRACK +a[[.x.]] & ax ax +a[[.x,.]] &C ECOLLATE +a[[.one.]]b & a1b a1b +a[[.notdef.]]b &C ECOLLATE +a[[.].]]b & a]b a]b +a[[:alpha:]]c & abc abc +a[[:notdef:]]c &C ECTYPE +a[[: &C EBRACK +a[[:alpha &C EBRACK +a[[:alpha:] &C EBRACK +a[[:alpha,:] &C ECTYPE +a[[:]:]]b &C ECTYPE +a[[:-:]]b &C ECTYPE +a[[:alph:]] &C ECTYPE +a[[:alphabet:]] &C ECTYPE +[[:alnum:]]+ - -%@a0X- a0X +[[:alpha:]]+ - -%@aX0- aX +[[:blank:]]+ - aSSTb SST +[[:cntrl:]]+ - aNTb NT +[[:digit:]]+ - a019b 019 +[[:graph:]]+ - Sa%bS a%b +[[:lower:]]+ - AabC ab +[[:print:]]+ - NaSbN aSb +[[:punct:]]+ - S%-&T %-& +[[:space:]]+ - aSNTb SNT +[[:upper:]]+ - aBCd BC +[[:xdigit:]]+ - p0f3Cq 0f3C +a[[=b=]]c & abc abc +a[[= &C EBRACK +a[[=b &C EBRACK +a[[=b= &C EBRACK +a[[=b=] &C EBRACK +a[[=b,=]] &C ECOLLATE +a[[=one=]]b & a1b a1b + +# complexities +a(((b)))c - abc abc +a(b|(c))d - abd abd +a(b*|c)d - abbd abbd +# just gotta have one DFA-buster, of course +a[ab]{20} - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab +# and an inline expansion in case somebody gets tricky +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab +# and in case somebody just slips in an NFA... +a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) - aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights +# fish for anomalies as the number of states passes 32 +12345678901234567890123456789 - a12345678901234567890123456789b 12345678901234567890123456789 +123456789012345678901234567890 - a123456789012345678901234567890b 123456789012345678901234567890 +1234567890123456789012345678901 - a1234567890123456789012345678901b 1234567890123456789012345678901 +12345678901234567890123456789012 - a12345678901234567890123456789012b 12345678901234567890123456789012 +123456789012345678901234567890123 - a123456789012345678901234567890123b 123456789012345678901234567890123 +# and one really big one, beyond any plausible word width +1234567890123456789012345678901234567890123456789012345678901234567890 - a1234567890123456789012345678901234567890123456789012345678901234567890b 1234567890123456789012345678901234567890123456789012345678901234567890 +# fish for problems as brackets go past 8 +[ab][cd][ef][gh][ij][kl][mn] - xacegikmoq acegikm +[ab][cd][ef][gh][ij][kl][mn][op] - xacegikmoq acegikmo +[ab][cd][ef][gh][ij][kl][mn][op][qr] - xacegikmoqy acegikmoq +[ab][cd][ef][gh][ij][kl][mn][op][q] - xacegikmoqy acegikmoq + +# subtleties of matching +abc & xabcy abc +a\(b\)?c\1d b acd +aBc i Abc Abc +a[Bc]*d i abBCcd abBCcd +0[[:upper:]]1 &i 0a1 0a1 +0[[:lower:]]1 &i 0A1 0A1 +a[^b]c &i abc +a[^b]c &i aBc +a[^b]c &i adc adc +[a]b[c] - abc abc +[a]b[a] - aba aba +[abc]b[abc] - abc abc +[abc]b[abd] - abd abd +a(b?c)+d - accd accd +(wee|week)(knights|night) - weeknights weeknights +(we|wee|week|frob)(knights|night|day) - weeknights weeknights +a[bc]d - xyzaaabcaababdacd abd +a[ab]c - aaabc abc +abc s abc abc + +# subexpressions +a(b)(c)d - abcd abcd b,c +a(((b)))c - abc abc b,b,b +a(b|(c))d - abd abd b,- +a(b*|c|e)d - abbd abbd bb +a(b*|c|e)d - acd acd c +a(b*|c|e)d - ad ad @d +a(b?)c - abc abc b +a(b?)c - ac ac @c +a(b+)c - abc abc b +a(b+)c - abbbc abbbc bbb +a(b*)c - ac ac @c +(a|ab)(bc([de]+)f|cde) - abcdef abcdef a,bcdef,de +# the regression tester only asks for 9 subexpressions +a(b)(c)(d)(e)(f)(g)(h)(i)(j)k - abcdefghijk abcdefghijk b,c,d,e,f,g,h,i,j +a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l - abcdefghijkl abcdefghijkl b,c,d,e,f,g,h,i,j,k +a([bc]?)c - abc abc b +a([bc]?)c - ac ac @c +a([bc]+)c - abc abc b +a([bc]+)c - abcc abcc bc +a([bc]+)bc - abcbc abcbc bc +a(bb+|b)b - abb abb b +a(bbb+|bb+|b)b - abb abb b +a(bbb+|bb+|b)b - abbb abbb bb +a(bbb+|bb+|b)bb - abbb abbb b +(.*).* - abcdef abcdef abcdef +(a*)* - bc @b @b + +# do we get the right subexpression when it is used more than once? +a(b|c)*d - ad ad - +a(b|c)*d - abcd abcd c +a(b|c)+d - abd abd b +a(b|c)+d - abcd abcd c +a(b|c?)+d - ad ad @d +a(b|c?)+d - abcd abcd @d +a(b|c){0,0}d - ad ad - +a(b|c){0,1}d - ad ad - +a(b|c){0,1}d - abd abd b +a(b|c){0,2}d - ad ad - +a(b|c){0,2}d - abcd abcd c +a(b|c){0,}d - ad ad - +a(b|c){0,}d - abcd abcd c +a(b|c){1,1}d - abd abd b +a(b|c){1,1}d - acd acd c +a(b|c){1,2}d - abd abd b +a(b|c){1,2}d - abcd abcd c +a(b|c){1,}d - abd abd b +a(b|c){1,}d - abcd abcd c +a(b|c){2,2}d - acbd acbd b +a(b|c){2,2}d - abcd abcd c +a(b|c){2,4}d - abcd abcd c +a(b|c){2,4}d - abcbd abcbd b +a(b|c){2,4}d - abcbcd abcbcd c +a(b|c){2,}d - abcd abcd c +a(b|c){2,}d - abcbd abcbd b +a(b+|((c)*))+d - abd abd @d,@d,- +a(b+|((c)*))+d - abcd abcd @d,@d,- + +# check out the STARTEND option +[abc] &# a(b)c b +[abc] &# a(d)c +[abc] &# a(bc)d b +[abc] &# a(dc)d c +. &# a()c +b.*c &# b(bc)c bc +b.* &# b(bc)c bc +.*c &# b(bc)c bc + +# plain strings, with the NOSPEC flag +abc m abc abc +abc m xabcy abc +abc m xyz +a*b m aba*b a*b +a*b m ab +"" mC EMPTY + +# cases involving NULs +aZb & a a +aZb &p a +aZb &p# (aZb) aZb +aZ*b &p# (ab) ab +a.b &# (aZb) aZb +a.* &# (aZb)c aZb + +# word boundaries (ick) +[[:<:]]a & a a +[[:<:]]a & ba +[[:<:]]a & -a a +a[[:>:]] & a a +a[[:>:]] & ab +a[[:>:]] & a- a +[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc abc +[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc-q abc +[[:<:]]a.c[[:>:]] & axc-dayc-dazce-abc axc + +# past problems +(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A]) - A1 A1 +abcdefghijklmnop i abcdefghijklmnop abcdefghijklmnop +abcdefghijklmnopqrstuv i abcdefghijklmnopqrstuv abcdefghijklmnopqrstuv +(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN]) - CC11 CC11 +CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a - CC11 CC11 +# PR 130504 +(.|())(b) - ab ab +(()|.)(b) - ab ab diff --git a/lib/libc/regex/re_format.7 b/lib/libc/regex/re_format.7 new file mode 100644 index 0000000..2422a43 --- /dev/null +++ b/lib/libc/regex/re_format.7 @@ -0,0 +1,492 @@ +.\" Copyright (c) 1992, 1993, 1994 Henry Spencer. +.\" Copyright (c) 1992, 1993, 1994 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Henry Spencer. +.\" +.\" 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. +.\" +.\" @(#)re_format.7 8.3 (Berkeley) 3/20/94 +.\" $FreeBSD: releng/11.1/lib/libc/regex/re_format.7 282007 2015-04-26 10:55:39Z bapt $ +.\" +.Dd June 30, 2014 +.Dt RE_FORMAT 7 +.Os +.Sh NAME +.Nm re_format +.Nd POSIX 1003.2 regular expressions +.Sh DESCRIPTION +Regular expressions +.Pq Dq RE Ns s , +as defined in +.St -p1003.2 , +come in two forms: +modern REs (roughly those of +.Xr egrep 1 ; +1003.2 calls these +.Dq extended +REs) +and obsolete REs (roughly those of +.Xr ed 1 ; +1003.2 +.Dq basic +REs). +Obsolete REs mostly exist for backward compatibility in some old programs; +they will be discussed at the end. +.St -p1003.2 +leaves some aspects of RE syntax and semantics open; +`\(dd' marks decisions on these aspects that +may not be fully portable to other +.St -p1003.2 +implementations. +.Pp +A (modern) RE is one\(dd or more non-empty\(dd +.Em branches , +separated by +.Ql \&| . +It matches anything that matches one of the branches. +.Pp +A branch is one\(dd 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 a single\(dd +.Ql \&* , +.Ql \&+ , +.Ql \&? , +or +.Em bound . +An atom followed by +.Ql \&* +matches a sequence of 0 or more matches of the atom. +An atom followed by +.Ql \&+ +matches a sequence of 1 or more matches of the atom. +An atom followed by +.Ql ?\& +matches a sequence of 0 or 1 matches of the atom. +.Pp +A +.Em bound +is +.Ql \&{ +followed by an unsigned decimal integer, +possibly followed by +.Ql \&, +possibly followed by another unsigned decimal integer, +always followed by +.Ql \&} . +The integers must lie between 0 and +.Dv RE_DUP_MAX +(255\(dd) inclusive, +and if there are two of them, the first may not exceed the second. +An atom followed by a bound containing one integer +.Em i +and no comma matches +a sequence of exactly +.Em i +matches of the atom. +An atom followed by a bound +containing one integer +.Em i +and a comma matches +a sequence of +.Em i +or more matches of the atom. +An atom followed by a bound +containing two integers +.Em i +and +.Em j +matches +a sequence of +.Em i +through +.Em j +(inclusive) matches of the atom. +.Pp +An atom is a regular expression enclosed in +.Ql () +(matching a match for the +regular expression), +an empty set of +.Ql () +(matching the null string)\(dd, +a +.Em bracket expression +(see below), +.Ql .\& +(matching any single character), +.Ql \&^ +(matching the null string at the beginning of a line), +.Ql \&$ +(matching the null string at the end of a line), a +.Ql \e +followed by one of the characters +.Ql ^.[$()|*+?{\e +(matching that character taken as an ordinary character), +a +.Ql \e +followed by any other character\(dd +(matching that character taken as an ordinary character, +as if the +.Ql \e +had not been present\(dd), +or a single character with no other significance (matching that character). +A +.Ql \&{ +followed by a character other than a digit is an ordinary +character, not the beginning of a bound\(dd. +It is illegal to end an RE with +.Ql \e . +.Pp +A +.Em bracket expression +is a list of characters enclosed in +.Ql [] . +It normally matches any single character from the list (but see below). +If the list begins with +.Ql \&^ , +it matches any single character +(but see below) +.Em not +from the rest of the list. +If two characters in the list are separated by +.Ql \&- , +this is shorthand +for the full +.Em range +of characters between those two (inclusive) in the +collating sequence, +.No e.g. Ql [0-9] +in ASCII matches any decimal digit. +It is illegal\(dd for two ranges to share an +endpoint, +.No e.g. Ql a-c-e . +Ranges are very collating-sequence-dependent, +and portable programs should avoid relying on them. +.Pp +To include a literal +.Ql \&] +in the list, make it the first character +(following a possible +.Ql \&^ ) . +To include a literal +.Ql \&- , +make it the first or last character, +or the second endpoint of a range. +To use a literal +.Ql \&- +as the first endpoint of a range, +enclose it in +.Ql [.\& +and +.Ql .]\& +to make it a collating element (see below). +With the exception of these and some combinations using +.Ql \&[ +(see next paragraphs), all other special characters, including +.Ql \e , +lose their special significance within a bracket expression. +.Pp +Within a bracket expression, a collating element (a character, +a multi-character sequence that collates as if it were a single character, +or a collating-sequence name for either) +enclosed in +.Ql [.\& +and +.Ql .]\& +stands for the +sequence of characters of that collating element. +The sequence is a single element of the bracket expression's list. +A bracket expression containing a multi-character collating element +can thus match more than one character, +e.g.\& if the collating sequence includes a +.Ql ch +collating element, +then the RE +.Ql [[.ch.]]*c +matches the first five characters +of +.Ql chchcc . +.Pp +Within a bracket expression, a collating element enclosed in +.Ql [= +and +.Ql =] +is an equivalence class, standing for the sequences of characters +of all collating elements equivalent to that one, including itself. +(If there are no other equivalent collating elements, +the treatment is as if the enclosing delimiters were +.Ql [.\& +and +.Ql .] . ) +For example, if +.Ql x +and +.Ql y +are the members of an equivalence class, +then +.Ql [[=x=]] , +.Ql [[=y=]] , +and +.Ql [xy] +are all synonymous. +An equivalence class may not\(dd be an endpoint +of a range. +.Pp +Within a bracket expression, the name of a +.Em character class +enclosed in +.Ql [: +and +.Ql :] +stands for the list of all characters belonging to that +class. +Standard character class names are: +.Bl -column "alnum" "digit" "xdigit" -offset indent +.It Em "alnum digit punct" +.It Em "alpha graph space" +.It Em "blank lower upper" +.It Em "cntrl print xdigit" +.El +.Pp +These stand for the character classes defined in +.Xr ctype 3 . +A locale may provide others. +A character class may not be used as an endpoint of a range. +.Pp +A bracketed expression like +.Ql [[:class:]] +can be used to match a single character that belongs to a character +class. +The reverse, matching any character that does not belong to a specific +class, the negation operator of bracket expressions may be used: +.Ql [^[:class:]] . +.Pp +There are two special cases\(dd of bracket expressions: +the bracket expressions +.Ql [[:<:]] +and +.Ql [[:>:]] +match the null string at the beginning and end of a word respectively. +A word is defined as a sequence of word characters +which is neither preceded nor followed by +word characters. +A word character is an +.Em alnum +character (as defined by +.Xr ctype 3 ) +or an underscore. +This is an extension, +compatible with but not specified by +.St -p1003.2 , +and should be used with +caution in software intended to be portable to other systems. +The additional word delimiters +.Ql \e< +and +.Ql \e> +are provided to ease compatibility with traditional +.Xr svr4 4 +systems but are not portable and should be avoided. +.Pp +In the event that an RE could match more than one substring of a given +string, +the RE matches the one starting earliest in the string. +If the RE could match more than one substring starting at that point, +it matches the longest. +Subexpressions also match the longest possible substrings, subject to +the constraint that the whole match be as long as possible, +with subexpressions starting earlier in the RE taking priority over +ones starting later. +Note that higher-level subexpressions thus take priority over +their lower-level component subexpressions. +.Pp +Match lengths are measured in characters, not collating elements. +A null string is considered longer than no match at all. +For example, +.Ql bb* +matches the three middle characters of +.Ql abbbc , +.Ql (wee|week)(knights|nights) +matches all ten characters of +.Ql weeknights , +when +.Ql (.*).*\& +is matched against +.Ql abc +the parenthesized subexpression +matches all three characters, and +when +.Ql (a*)* +is matched against +.Ql bc +both the whole RE and the parenthesized +subexpression match the null string. +.Pp +If case-independent matching is specified, +the effect is much as if all case distinctions had vanished from the +alphabet. +When an alphabetic that exists in multiple cases appears as an +ordinary character outside a bracket expression, it is effectively +transformed into a bracket expression containing both cases, +.No e.g. Ql x +becomes +.Ql [xX] . +When it appears inside a bracket expression, all case counterparts +of it are added to the bracket expression, so that (e.g.) +.Ql [x] +becomes +.Ql [xX] +and +.Ql [^x] +becomes +.Ql [^xX] . +.Pp +No particular limit is imposed on the length of REs\(dd. +Programs intended to be portable should not employ REs longer +than 256 bytes, +as an implementation can refuse to accept such REs and remain +POSIX-compliant. +.Pp +Obsolete +.Pq Dq basic +regular expressions differ in several respects. +.Ql \&| +is an ordinary character and there is no equivalent +for its functionality. +.Ql \&+ +and +.Ql ?\& +are ordinary characters, and their functionality +can be expressed using bounds +.Po +.Ql {1,} +or +.Ql {0,1} +respectively +.Pc . +Also note that +.Ql x+ +in modern REs is equivalent to +.Ql xx* . +The delimiters for bounds are +.Ql \e{ +and +.Ql \e} , +with +.Ql \&{ +and +.Ql \&} +by themselves ordinary characters. +The parentheses for nested subexpressions are +.Ql \e( +and +.Ql \e) , +with +.Ql \&( +and +.Ql \&) +by themselves ordinary characters. +.Ql \&^ +is an ordinary character except at the beginning of the +RE or\(dd the beginning of a parenthesized subexpression, +.Ql \&$ +is an ordinary character except at the end of the +RE or\(dd the end of a parenthesized subexpression, +and +.Ql \&* +is an ordinary character if it appears at the beginning of the +RE or the beginning of a parenthesized subexpression +(after a possible leading +.Ql \&^ ) . +Finally, there is one new type of atom, a +.Em back reference : +.Ql \e +followed by a non-zero decimal digit +.Em d +matches the same sequence of characters +matched by the +.Em d Ns th +parenthesized subexpression +(numbering subexpressions by the positions of their opening parentheses, +left to right), +so that (e.g.) +.Ql \e([bc]\e)\e1 +matches +.Ql bb +or +.Ql cc +but not +.Ql bc . +.Sh SEE ALSO +.Xr regex 3 +.Rs +.%T Regular Expression Notation +.%R IEEE Std +.%N 1003.2 +.%P section 2.8 +.Re +.Sh BUGS +Having two kinds of REs is a botch. +.Pp +The current +.St -p1003.2 +spec says that +.Ql \&) +is an ordinary character in +the absence of an unmatched +.Ql \&( ; +this was an unintentional result of a wording error, +and change is likely. +Avoid relying on it. +.Pp +Back references are a dreadful botch, +posing major problems for efficient implementations. +They are also somewhat vaguely defined +(does +.Ql a\e(\e(b\e)*\e2\e)*d +match +.Ql abbbd ? ) . +Avoid using them. +.Pp +.St -p1003.2 +specification of case-independent matching is vague. +The +.Dq one case implies all cases +definition given above +is current consensus among implementors as to the right interpretation. +.Pp +The syntax for word boundaries is incredibly ugly. diff --git a/lib/libc/regex/regex.3 b/lib/libc/regex/regex.3 new file mode 100644 index 0000000..3aafc64 --- /dev/null +++ b/lib/libc/regex/regex.3 @@ -0,0 +1,755 @@ +.\" Copyright (c) 1992, 1993, 1994 Henry Spencer. +.\" Copyright (c) 1992, 1993, 1994 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" Henry Spencer. +.\" +.\" 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. +.\" 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. +.\" +.\" @(#)regex.3 8.4 (Berkeley) 3/20/94 +.\" $FreeBSD: releng/11.1/lib/libc/regex/regex.3 300683 2016-05-25 15:35:23Z pfg $ +.\" +.Dd May 25, 2016 +.Dt REGEX 3 +.Os +.Sh NAME +.Nm regcomp , +.Nm regexec , +.Nm regerror , +.Nm regfree +.Nd regular-expression library +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In regex.h +.Ft int +.Fo regcomp +.Fa "regex_t * restrict preg" "const char * restrict pattern" "int cflags" +.Fc +.Ft int +.Fo regexec +.Fa "const regex_t * restrict preg" "const char * restrict string" +.Fa "size_t nmatch" "regmatch_t pmatch[restrict]" "int eflags" +.Fc +.Ft size_t +.Fo regerror +.Fa "int errcode" "const regex_t * restrict preg" +.Fa "char * restrict errbuf" "size_t errbuf_size" +.Fc +.Ft void +.Fn regfree "regex_t *preg" +.Sh DESCRIPTION +These routines implement +.St -p1003.2 +regular expressions +.Pq Do RE Dc Ns s ; +see +.Xr re_format 7 . +The +.Fn regcomp +function +compiles an RE written as a string into an internal form, +.Fn regexec +matches that internal form against a string and reports results, +.Fn regerror +transforms error codes from either into human-readable messages, +and +.Fn regfree +frees any dynamically-allocated storage used by the internal form +of an RE. +.Pp +The header +.In regex.h +declares two structure types, +.Ft regex_t +and +.Ft regmatch_t , +the former for compiled internal forms and the latter for match reporting. +It also declares the four functions, +a type +.Ft regoff_t , +and a number of constants with names starting with +.Dq Dv REG_ . +.Pp +The +.Fn regcomp +function +compiles the regular expression contained in the +.Fa pattern +string, +subject to the flags in +.Fa cflags , +and places the results in the +.Ft regex_t +structure pointed to by +.Fa preg . +The +.Fa cflags +argument +is the bitwise OR of zero or more of the following flags: +.Bl -tag -width REG_EXTENDED +.It Dv REG_EXTENDED +Compile modern +.Pq Dq extended +REs, +rather than the obsolete +.Pq Dq basic +REs that +are the default. +.It Dv REG_BASIC +This is a synonym for 0, +provided as a counterpart to +.Dv REG_EXTENDED +to improve readability. +.It Dv REG_NOSPEC +Compile with recognition of all special characters turned off. +All characters are thus considered ordinary, +so the +.Dq RE +is a literal string. +This is an extension, +compatible with but not specified by +.St -p1003.2 , +and should be used with +caution in software intended to be portable to other systems. +.Dv REG_EXTENDED +and +.Dv REG_NOSPEC +may not be used +in the same call to +.Fn regcomp . +.It Dv REG_ICASE +Compile for matching that ignores upper/lower case distinctions. +See +.Xr re_format 7 . +.It Dv REG_NOSUB +Compile for matching that need only report success or failure, +not what was matched. +.It Dv REG_NEWLINE +Compile for newline-sensitive matching. +By default, newline is a completely ordinary character with no special +meaning in either REs or strings. +With this flag, +.Ql [^ +bracket expressions and +.Ql .\& +never match newline, +a +.Ql ^\& +anchor matches the null string after any newline in the string +in addition to its normal function, +and the +.Ql $\& +anchor matches the null string before any newline in the +string in addition to its normal function. +.It Dv REG_PEND +The regular expression ends, +not at the first NUL, +but just before the character pointed to by the +.Va re_endp +member of the structure pointed to by +.Fa preg . +The +.Va re_endp +member is of type +.Ft "const char *" . +This flag permits inclusion of NULs in the RE; +they are considered ordinary characters. +This is an extension, +compatible with but not specified by +.St -p1003.2 , +and should be used with +caution in software intended to be portable to other systems. +.El +.Pp +When successful, +.Fn regcomp +returns 0 and fills in the structure pointed to by +.Fa preg . +One member of that structure +(other than +.Va re_endp ) +is publicized: +.Va re_nsub , +of type +.Ft size_t , +contains the number of parenthesized subexpressions within the RE +(except that the value of this member is undefined if the +.Dv REG_NOSUB +flag was used). +If +.Fn regcomp +fails, it returns a non-zero error code; +see +.Sx DIAGNOSTICS . +.Pp +The +.Fn regexec +function +matches the compiled RE pointed to by +.Fa preg +against the +.Fa string , +subject to the flags in +.Fa eflags , +and reports results using +.Fa nmatch , +.Fa pmatch , +and the returned value. +The RE must have been compiled by a previous invocation of +.Fn regcomp . +The compiled form is not altered during execution of +.Fn regexec , +so a single compiled RE can be used simultaneously by multiple threads. +.Pp +By default, +the NUL-terminated string pointed to by +.Fa string +is considered to be the text of an entire line, minus any terminating +newline. +The +.Fa eflags +argument is the bitwise OR of zero or more of the following flags: +.Bl -tag -width REG_STARTEND +.It Dv REG_NOTBOL +The first character of the string is treated as the continuation +of a line. +This means that the anchors +.Ql ^\& , +.Ql [[:<:]] , +and +.Ql \e< +do not match before it; but see +.Dv REG_STARTEND +below. +This does not affect the behavior of newlines under +.Dv REG_NEWLINE . +.It Dv REG_NOTEOL +The NUL terminating +the string +does not end a line, so the +.Ql $\& +anchor does not match before it. +This does not affect the behavior of newlines under +.Dv REG_NEWLINE . +.It Dv REG_STARTEND +The string is considered to start at +.Fa string No + +.Fa pmatch Ns [0]. Ns Fa rm_so +and to end before the byte located at +.Fa string No + +.Fa pmatch Ns [0]. Ns Fa rm_eo , +regardless of the value of +.Fa nmatch . +See below for the definition of +.Fa pmatch +and +.Fa nmatch . +This is an extension, +compatible with but not specified by +.St -p1003.2 , +and should be used with +caution in software intended to be portable to other systems. +.Pp +Without +.Dv REG_NOTBOL , +the position +.Fa rm_so +is considered the beginning of a line, such that +.Ql ^ +matches before it, and the beginning of a word if there is a word +character at this position, such that +.Ql [[:<:]] +and +.Ql \e< +match before it. +.Pp +With +.Dv REG_NOTBOL , +the character at position +.Fa rm_so +is treated as the continuation of a line, and if +.Fa rm_so +is greater than 0, the preceding character is taken into consideration. +If the preceding character is a newline and the regular expression was compiled +with +.Dv REG_NEWLINE , +.Ql ^ +matches before the string; if the preceding character is not a word character +but the string starts with a word character, +.Ql [[:<:]] +and +.Ql \e< +match before the string. +.El +.Pp +See +.Xr re_format 7 +for a discussion of what is matched in situations where an RE or a +portion thereof could match any of several substrings of +.Fa string . +.Pp +Normally, +.Fn regexec +returns 0 for success and the non-zero code +.Dv REG_NOMATCH +for failure. +Other non-zero error codes may be returned in exceptional situations; +see +.Sx DIAGNOSTICS . +.Pp +If +.Dv REG_NOSUB +was specified in the compilation of the RE, +or if +.Fa nmatch +is 0, +.Fn regexec +ignores the +.Fa pmatch +argument (but see below for the case where +.Dv REG_STARTEND +is specified). +Otherwise, +.Fa pmatch +points to an array of +.Fa nmatch +structures of type +.Ft regmatch_t . +Such a structure has at least the members +.Va rm_so +and +.Va rm_eo , +both of type +.Ft regoff_t +(a signed arithmetic type at least as large as an +.Ft off_t +and a +.Ft ssize_t ) , +containing respectively the offset of the first character of a substring +and the offset of the first character after the end of the substring. +Offsets are measured from the beginning of the +.Fa string +argument given to +.Fn regexec . +An empty substring is denoted by equal offsets, +both indicating the character following the empty substring. +.Pp +The 0th member of the +.Fa pmatch +array is filled in to indicate what substring of +.Fa string +was matched by the entire RE. +Remaining members report what substring was matched by parenthesized +subexpressions within the RE; +member +.Va i +reports subexpression +.Va i , +with subexpressions counted (starting at 1) by the order of their opening +parentheses in the RE, left to right. +Unused entries in the array (corresponding either to subexpressions that +did not participate in the match at all, or to subexpressions that do not +exist in the RE (that is, +.Va i +> +.Fa preg Ns -> Ns Va re_nsub ) ) +have both +.Va rm_so +and +.Va rm_eo +set to -1. +If a subexpression participated in the match several times, +the reported substring is the last one it matched. +(Note, as an example in particular, that when the RE +.Ql "(b*)+" +matches +.Ql bbb , +the parenthesized subexpression matches each of the three +.So Li b Sc Ns s +and then +an infinite number of empty strings following the last +.Ql b , +so the reported substring is one of the empties.) +.Pp +If +.Dv REG_STARTEND +is specified, +.Fa pmatch +must point to at least one +.Ft regmatch_t +(even if +.Fa nmatch +is 0 or +.Dv REG_NOSUB +was specified), +to hold the input offsets for +.Dv REG_STARTEND . +Use for output is still entirely controlled by +.Fa nmatch ; +if +.Fa nmatch +is 0 or +.Dv REG_NOSUB +was specified, +the value of +.Fa pmatch Ns [0] +will not be changed by a successful +.Fn regexec . +.Pp +The +.Fn regerror +function +maps a non-zero +.Fa errcode +from either +.Fn regcomp +or +.Fn regexec +to a human-readable, printable message. +If +.Fa preg +is +.No non\- Ns Dv NULL , +the error code should have arisen from use of +the +.Ft regex_t +pointed to by +.Fa preg , +and if the error code came from +.Fn regcomp , +it should have been the result from the most recent +.Fn regcomp +using that +.Ft regex_t . +The +.Po +.Fn regerror +may be able to supply a more detailed message using information +from the +.Ft regex_t . +.Pc +The +.Fn regerror +function +places the NUL-terminated message into the buffer pointed to by +.Fa errbuf , +limiting the length (including the NUL) to at most +.Fa errbuf_size +bytes. +If the whole message will not fit, +as much of it as will fit before the terminating NUL is supplied. +In any case, +the returned value is the size of buffer needed to hold the whole +message (including terminating NUL). +If +.Fa errbuf_size +is 0, +.Fa errbuf +is ignored but the return value is still correct. +.Pp +If the +.Fa errcode +given to +.Fn regerror +is first ORed with +.Dv REG_ITOA , +the +.Dq message +that results is the printable name of the error code, +e.g.\& +.Dq Dv REG_NOMATCH , +rather than an explanation thereof. +If +.Fa errcode +is +.Dv REG_ATOI , +then +.Fa preg +shall be +.No non\- Ns Dv NULL +and the +.Va re_endp +member of the structure it points to +must point to the printable name of an error code; +in this case, the result in +.Fa errbuf +is the decimal digits of +the numeric value of the error code +(0 if the name is not recognized). +.Dv REG_ITOA +and +.Dv REG_ATOI +are intended primarily as debugging facilities; +they are extensions, +compatible with but not specified by +.St -p1003.2 , +and should be used with +caution in software intended to be portable to other systems. +Be warned also that they are considered experimental and changes are possible. +.Pp +The +.Fn regfree +function +frees any dynamically-allocated storage associated with the compiled RE +pointed to by +.Fa preg . +The remaining +.Ft regex_t +is no longer a valid compiled RE +and the effect of supplying it to +.Fn regexec +or +.Fn regerror +is undefined. +.Pp +None of these functions references global variables except for tables +of constants; +all are safe for use from multiple threads if the arguments are safe. +.Sh IMPLEMENTATION CHOICES +There are a number of decisions that +.St -p1003.2 +leaves up to the implementor, +either by explicitly saying +.Dq undefined +or by virtue of them being +forbidden by the RE grammar. +This implementation treats them as follows. +.Pp +See +.Xr re_format 7 +for a discussion of the definition of case-independent matching. +.Pp +There is no particular limit on the length of REs, +except insofar as memory is limited. +Memory usage is approximately linear in RE size, and largely insensitive +to RE complexity, except for bounded repetitions. +See +.Sx BUGS +for one short RE using them +that will run almost any system out of memory. +.Pp +A backslashed character other than one specifically given a magic meaning +by +.St -p1003.2 +(such magic meanings occur only in obsolete +.Bq Dq basic +REs) +is taken as an ordinary character. +.Pp +Any unmatched +.Ql [\& +is a +.Dv REG_EBRACK +error. +.Pp +Equivalence classes cannot begin or end bracket-expression ranges. +The endpoint of one range cannot begin another. +.Pp +.Dv RE_DUP_MAX , +the limit on repetition counts in bounded repetitions, is 255. +.Pp +A repetition operator +.Ql ( ?\& , +.Ql *\& , +.Ql +\& , +or bounds) +cannot follow another +repetition operator. +A repetition operator cannot begin an expression or subexpression +or follow +.Ql ^\& +or +.Ql |\& . +.Pp +.Ql |\& +cannot appear first or last in a (sub)expression or after another +.Ql |\& , +i.e., an operand of +.Ql |\& +cannot be an empty subexpression. +An empty parenthesized subexpression, +.Ql "()" , +is legal and matches an +empty (sub)string. +An empty string is not a legal RE. +.Pp +A +.Ql {\& +followed by a digit is considered the beginning of bounds for a +bounded repetition, which must then follow the syntax for bounds. +A +.Ql {\& +.Em not +followed by a digit is considered an ordinary character. +.Pp +.Ql ^\& +and +.Ql $\& +beginning and ending subexpressions in obsolete +.Pq Dq basic +REs are anchors, not ordinary characters. +.Sh DIAGNOSTICS +Non-zero error codes from +.Fn regcomp +and +.Fn regexec +include the following: +.Pp +.Bl -tag -width REG_ECOLLATE -compact +.It Dv REG_NOMATCH +The +.Fn regexec +function +failed to match +.It Dv REG_BADPAT +invalid regular expression +.It Dv REG_ECOLLATE +invalid collating element +.It Dv REG_ECTYPE +invalid character class +.It Dv REG_EESCAPE +.Ql \e +applied to unescapable character +.It Dv REG_ESUBREG +invalid backreference number +.It Dv REG_EBRACK +brackets +.Ql "[ ]" +not balanced +.It Dv REG_EPAREN +parentheses +.Ql "( )" +not balanced +.It Dv REG_EBRACE +braces +.Ql "{ }" +not balanced +.It Dv REG_BADBR +invalid repetition count(s) in +.Ql "{ }" +.It Dv REG_ERANGE +invalid character range in +.Ql "[ ]" +.It Dv REG_ESPACE +ran out of memory +.It Dv REG_BADRPT +.Ql ?\& , +.Ql *\& , +or +.Ql +\& +operand invalid +.It Dv REG_EMPTY +empty (sub)expression +.It Dv REG_ASSERT +cannot happen - you found a bug +.It Dv REG_INVARG +invalid argument, e.g.\& negative-length string +.It Dv REG_ILLSEQ +illegal byte sequence (bad multibyte character) +.El +.Sh SEE ALSO +.Xr grep 1 , +.Xr re_format 7 +.Pp +.St -p1003.2 , +sections 2.8 (Regular Expression Notation) +and +B.5 (C Binding for Regular Expression Matching). +.Sh HISTORY +Originally written by +.An Henry Spencer . +Altered for inclusion in the +.Bx 4.4 +distribution. +.Sh BUGS +This is an alpha release with known defects. +Please report problems. +.Pp +The back-reference code is subtle and doubts linger about its correctness +in complex cases. +.Pp +The +.Fn regexec +function +performance is poor. +This will improve with later releases. +The +.Fa nmatch +argument +exceeding 0 is expensive; +.Fa nmatch +exceeding 1 is worse. +The +.Fn regexec +function +is largely insensitive to RE complexity +.Em except +that back +references are massively expensive. +RE length does matter; in particular, there is a strong speed bonus +for keeping RE length under about 30 characters, +with most special characters counting roughly double. +.Pp +The +.Fn regcomp +function +implements bounded repetitions by macro expansion, +which is costly in time and space if counts are large +or bounded repetitions are nested. +An RE like, say, +.Ql "((((a{1,100}){1,100}){1,100}){1,100}){1,100}" +will (eventually) run almost any existing machine out of swap space. +.Pp +There are suspected problems with response to obscure error conditions. +Notably, +certain kinds of internal overflow, +produced only by truly enormous REs or by multiply nested bounded repetitions, +are probably not handled well. +.Pp +Due to a mistake in +.St -p1003.2 , +things like +.Ql "a)b" +are legal REs because +.Ql )\& +is +a special character only in the presence of a previous unmatched +.Ql (\& . +This cannot be fixed until the spec is fixed. +.Pp +The standard's definition of back references is vague. +For example, does +.Ql "a\e(\e(b\e)*\e2\e)*d" +match +.Ql "abbbd" ? +Until the standard is clarified, +behavior in such cases should not be relied on. +.Pp +The implementation of word-boundary matching is a bit of a kludge, +and bugs may lurk in combinations of word-boundary matching and anchoring. +.Pp +Word-boundary matching does not work properly in multibyte locales. diff --git a/lib/libc/resolv/Makefile.inc b/lib/libc/resolv/Makefile.inc new file mode 100644 index 0000000..a0e5495 --- /dev/null +++ b/lib/libc/resolv/Makefile.inc @@ -0,0 +1,12 @@ +# $FreeBSD: releng/11.1/lib/libc/resolv/Makefile.inc 313240 2017-02-04 17:17:38Z ngie $ + +# resolv sources +.PATH: ${LIBC_SRCTOP}/resolv + +SRCS+= herror.c h_errno.c mtctxres.c res_comp.c res_data.c res_debug.c \ + res_findzonecut.c res_init.c res_mkquery.c res_mkupdate.c \ + res_query.c res_send.c res_state.c res_update.c + +SYM_MAPS+= ${LIBC_SRCTOP}/resolv/Symbol.map + +CFLAGS+=-I${SRCTOP}/lib/libmd diff --git a/lib/libc/resolv/Symbol.map b/lib/libc/resolv/Symbol.map new file mode 100644 index 0000000..d88bf9b --- /dev/null +++ b/lib/libc/resolv/Symbol.map @@ -0,0 +1,112 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/resolv/Symbol.map 269867 2014-08-12 12:36:06Z ume $ + */ + +FBSD_1.0 { + /* h_nerr; */ /* Why is this not staticized in net/herror.c? */ + h_errlist; + herror; + hstrerror; + __dn_expand; + __dn_comp; + __dn_skipname; + __res_hnok; + __res_ownok; + __res_mailok; + __res_dnok; + __putlong; + __putshort; + _getlong; + _getshort; + dn_comp; + dn_expand; + __fp_resstat; + __p_query; + __fp_query; + __fp_nquery; + __p_cdnname; + __p_cdname; + __p_fqnname; + __p_fqname; + __p_cert_syms; + __p_class_syms; + __p_key_syms; + __p_rcode_syms; + __p_type_syms; + __sym_ston; + __sym_ntos; + __sym_ntop; + __p_rcode; + __p_sockun; + __p_type; + __p_section; + __p_class; + __p_option; + __p_time; + __loc_aton; + __loc_ntoa; + __dn_count_labels; + __p_secstodate; + fp_resstat; + p_query; + p_fqnname; + sym_ston; + sym_ntos; + sym_ntop; + dn_count_labels; + p_secstodate; + __res_init; + __res_randomid; + __h_errno; + __h_errno_set; + h_errno; + res_init; + __res_findzonecut2; + __res_freeupdrec; + __res_mkquery; + res_mkquery; + __res_mkupdrec; + __res_mkupdate; + __res_opt; + __res_getservers; + __res_hostalias; + __res_nametoclass; + __res_nametotype; + __res_nclose; + __res_ndestroy; + __res_ninit; + __res_nmkquery; + __res_nmkupdate; + __res_nopt; + __res_nquery; + __res_nquerydomain; + __res_nsearch; + __res_nsend; + __res_nupdate; + __res_ourserver_p; + __res_pquery; + __res_query; + __res_search; + __res_querydomain; + __res_setservers; + _res; + __res_state; + __res_vinit; + __hostalias; + res_query; + res_search; + res_querydomain; + __res_isourserver; + __res_nameinquery; + __res_queriesmatch; + __res_send; + __res_close; + _res_close; + res_send; + __res_update; +}; + +FBSD_1.4 { + __res_rndinit; + __res_nrandomid; +}; diff --git a/lib/libc/resolv/res_findzonecut.c b/lib/libc/resolv/res_findzonecut.c new file mode 100644 index 0000000..f11e541 --- /dev/null +++ b/lib/libc/resolv/res_findzonecut.c @@ -0,0 +1,727 @@ +#if !defined(lint) && !defined(SABER) +static const char rcsid[] = "$Id: res_findzonecut.c,v 1.10 2005/10/11 00:10:16 marka Exp $"; +#endif /* not lint */ + +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1999 by Internet Software Consortium. + * + * 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 ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/resolv/res_findzonecut.c 298830 2016-04-30 01:24:24Z pfg $"); + +/* Import. */ + +#include "port_before.h" + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "port_after.h" + +#include + +/* Data structures. */ + +typedef struct rr_a { + LINK(struct rr_a) link; + union res_sockaddr_union addr; +} rr_a; +typedef LIST(rr_a) rrset_a; + +typedef struct rr_ns { + LINK(struct rr_ns) link; + const char * name; + unsigned int flags; + rrset_a addrs; +} rr_ns; +typedef LIST(rr_ns) rrset_ns; + +#define RR_NS_HAVE_V4 0x01 +#define RR_NS_HAVE_V6 0x02 + +/* Forward. */ + +static int satisfy(res_state, const char *, rrset_ns *, + union res_sockaddr_union *, int); +static int add_addrs(res_state, rr_ns *, + union res_sockaddr_union *, int); +static int get_soa(res_state, const char *, ns_class, int, + char *, size_t, char *, size_t, + rrset_ns *); +static int get_ns(res_state, const char *, ns_class, int, rrset_ns *); +static int get_glue(res_state, ns_class, int, rrset_ns *); +static int save_ns(res_state, ns_msg *, ns_sect, + const char *, ns_class, int, rrset_ns *); +static int save_a(res_state, ns_msg *, ns_sect, + const char *, ns_class, int, rr_ns *); +static void free_nsrrset(rrset_ns *); +static void free_nsrr(rrset_ns *, rr_ns *); +static rr_ns * find_ns(rrset_ns *, const char *); +static int do_query(res_state, const char *, ns_class, ns_type, + u_char *, ns_msg *); +static void res_dprintf(const char *, ...) ISC_FORMAT_PRINTF(1, 2); + +/* Macros. */ + +#define DPRINTF(x) do {\ + int save_errno = errno; \ + if ((statp->options & RES_DEBUG) != 0U) res_dprintf x; \ + errno = save_errno; \ + } while (0) + +/* Public. */ + +/*% + * find enclosing zone for a , and some server addresses + * + * parameters: + *\li res - resolver context to work within (is modified) + *\li dname - domain name whose enclosing zone is desired + *\li class - class of dname (and its enclosing zone) + *\li zname - found zone name + *\li zsize - allocated size of zname + *\li addrs - found server addresses + *\li naddrs - max number of addrs + * + * return values: + *\li < 0 - an error occurred (check errno) + *\li = 0 - zname is now valid, but addrs[] wasn't changed + *\li > 0 - zname is now valid, and return value is number of addrs[] found + * + * notes: + *\li this function calls res_nsend() which means it depends on correctly + * functioning recursive nameservers (usually defined in /etc/resolv.conf + * or its local equivalent). + * + *\li we start by asking for an SOA. if we get one as an + * answer, that just means is a zone top, which is fine. + * more than likely we'll be told to go pound sand, in the form of a + * negative answer. + * + *\li note that we are not prepared to deal with referrals since that would + * only come from authority servers and our correctly functioning local + * recursive server would have followed the referral and got us something + * more definite. + * + *\li if the authority section contains an SOA, this SOA should also be the + * closest enclosing zone, since any intermediary zone cuts would've been + * returned as referrals and dealt with by our correctly functioning local + * recursive name server. but an SOA in the authority section should NOT + * match our dname (since that would have been returned in the answer + * section). an authority section SOA has to be "above" our dname. + * + *\li however, since authority section SOA's were once optional, it's + * possible that we'll have to go hunting for the enclosing SOA by + * ripping labels off the front of our dname -- this is known as "doing + * it the hard way." + * + *\li ultimately we want some server addresses, which are ideally the ones + * pertaining to the SOA.MNAME, but only if there is a matching NS RR. + * so the second phase (after we find an SOA) is to go looking for the + * NS RRset for that SOA's zone. + * + *\li no answer section processed by this code is allowed to contain CNAME + * or DNAME RR's. for the SOA query this means we strip a label and + * keep going. for the NS and A queries this means we just give up. + */ + +#ifndef _LIBC +int +res_findzonecut(res_state statp, const char *dname, ns_class class, int opts, + char *zname, size_t zsize, struct in_addr *addrs, int naddrs) +{ + int result, i; + union res_sockaddr_union *u; + + + opts |= RES_IPV4ONLY; + opts &= ~RES_IPV6ONLY; + + u = calloc(naddrs, sizeof(*u)); + if (u == NULL) + return(-1); + + result = res_findzonecut2(statp, dname, class, opts, zname, zsize, + u, naddrs); + + for (i = 0; i < result; i++) { + addrs[i] = u[i].sin.sin_addr; + } + free(u); + return (result); +} +#endif + +int +res_findzonecut2(res_state statp, const char *dname, ns_class class, int opts, + char *zname, size_t zsize, union res_sockaddr_union *addrs, + int naddrs) +{ + char mname[NS_MAXDNAME]; + u_long save_pfcode; + rrset_ns nsrrs; + int n; + + DPRINTF(("START dname='%s' class=%s, zsize=%ld, naddrs=%d", + dname, p_class(class), (long)zsize, naddrs)); + save_pfcode = statp->pfcode; + statp->pfcode |= RES_PRF_HEAD2 | RES_PRF_HEAD1 | RES_PRF_HEADX | + RES_PRF_QUES | RES_PRF_ANS | + RES_PRF_AUTH | RES_PRF_ADD; + INIT_LIST(nsrrs); + + DPRINTF(("get the soa, and see if it has enough glue")); + if ((n = get_soa(statp, dname, class, opts, zname, zsize, + mname, sizeof mname, &nsrrs)) < 0 || + ((opts & RES_EXHAUSTIVE) == 0 && + (n = satisfy(statp, mname, &nsrrs, addrs, naddrs)) > 0)) + goto done; + + DPRINTF(("get the ns rrset and see if it has enough glue")); + if ((n = get_ns(statp, zname, class, opts, &nsrrs)) < 0 || + ((opts & RES_EXHAUSTIVE) == 0 && + (n = satisfy(statp, mname, &nsrrs, addrs, naddrs)) > 0)) + goto done; + + DPRINTF(("get the missing glue and see if it's finally enough")); + if ((n = get_glue(statp, class, opts, &nsrrs)) >= 0) + n = satisfy(statp, mname, &nsrrs, addrs, naddrs); + + done: + DPRINTF(("FINISH n=%d (%s)", n, (n < 0) ? strerror(errno) : "OK")); + free_nsrrset(&nsrrs); + statp->pfcode = save_pfcode; + return (n); +} + +/* Private. */ + +static int +satisfy(res_state statp, const char *mname, rrset_ns *nsrrsp, + union res_sockaddr_union *addrs, int naddrs) +{ + rr_ns *nsrr; + int n, x; + + n = 0; + nsrr = find_ns(nsrrsp, mname); + if (nsrr != NULL) { + x = add_addrs(statp, nsrr, addrs, naddrs); + addrs += x; + naddrs -= x; + n += x; + } + for (nsrr = HEAD(*nsrrsp); + nsrr != NULL && naddrs > 0; + nsrr = NEXT(nsrr, link)) + if (ns_samename(nsrr->name, mname) != 1) { + x = add_addrs(statp, nsrr, addrs, naddrs); + addrs += x; + naddrs -= x; + n += x; + } + DPRINTF(("satisfy(%s): %d", mname, n)); + return (n); +} + +static int +add_addrs(res_state statp, rr_ns *nsrr, + union res_sockaddr_union *addrs, int naddrs) +{ + rr_a *arr; + int n = 0; + + for (arr = HEAD(nsrr->addrs); arr != NULL; arr = NEXT(arr, link)) { + if (naddrs <= 0) + return (0); + *addrs++ = arr->addr; + naddrs--; + n++; + } + DPRINTF(("add_addrs: %d", n)); + return (n); +} + +static int +get_soa(res_state statp, const char *dname, ns_class class, int opts, + char *zname, size_t zsize, char *mname, size_t msize, + rrset_ns *nsrrsp) +{ + char tname[NS_MAXDNAME]; + u_char *resp = NULL; + int n, i, ancount, nscount; + ns_sect sect; + ns_msg msg; + u_int rcode; + + /* + * Find closest enclosing SOA, even if it's for the root zone. + */ + + /* First canonicalize dname (exactly one unescaped trailing "."). */ + if (ns_makecanon(dname, tname, sizeof tname) < 0) + goto cleanup; + dname = tname; + + resp = malloc(NS_MAXMSG); + if (resp == NULL) + goto cleanup; + + /* Now grovel the subdomains, hunting for an SOA answer or auth. */ + for (;;) { + /* Leading or inter-label '.' are skipped here. */ + while (*dname == '.') + dname++; + + /* Is there an SOA? */ + n = do_query(statp, dname, class, ns_t_soa, resp, &msg); + if (n < 0) { + DPRINTF(("get_soa: do_query('%s', %s) failed (%d)", + dname, p_class(class), n)); + goto cleanup; + } + if (n > 0) { + DPRINTF(("get_soa: CNAME or DNAME found")); + sect = ns_s_max, n = 0; + } else { + rcode = ns_msg_getflag(msg, ns_f_rcode); + ancount = ns_msg_count(msg, ns_s_an); + nscount = ns_msg_count(msg, ns_s_ns); + if (ancount > 0 && rcode == ns_r_noerror) + sect = ns_s_an, n = ancount; + else if (nscount > 0) + sect = ns_s_ns, n = nscount; + else + sect = ns_s_max, n = 0; + } + for (i = 0; i < n; i++) { + const char *t; + const u_char *rdata; + ns_rr rr; + + if (ns_parserr(&msg, sect, i, &rr) < 0) { + DPRINTF(("get_soa: ns_parserr(%s, %d) failed", + p_section(sect, ns_o_query), i)); + goto cleanup; + } + if (ns_rr_type(rr) == ns_t_cname || + ns_rr_type(rr) == ns_t_dname) + break; + if (ns_rr_type(rr) != ns_t_soa || + ns_rr_class(rr) != class) + continue; + t = ns_rr_name(rr); + switch (sect) { + case ns_s_an: + if (ns_samedomain(dname, t) == 0) { + DPRINTF( + ("get_soa: ns_samedomain('%s', '%s') == 0", + dname, t) + ); + errno = EPROTOTYPE; + goto cleanup; + } + break; + case ns_s_ns: + if (ns_samename(dname, t) == 1 || + ns_samedomain(dname, t) == 0) { + DPRINTF( + ("get_soa: ns_samename() || !ns_samedomain('%s', '%s')", + dname, t) + ); + errno = EPROTOTYPE; + goto cleanup; + } + break; + default: + abort(); + } + if (strlen(t) + 1 > zsize) { + DPRINTF(("get_soa: zname(%lu) too small (%lu)", + (unsigned long)zsize, + (unsigned long)strlen(t) + 1)); + errno = EMSGSIZE; + goto cleanup; + } + strcpy(zname, t); + rdata = ns_rr_rdata(rr); + if (ns_name_uncompress(resp, ns_msg_end(msg), rdata, + mname, msize) < 0) { + DPRINTF(("get_soa: ns_name_uncompress failed") + ); + goto cleanup; + } + if (save_ns(statp, &msg, ns_s_ns, + zname, class, opts, nsrrsp) < 0) { + DPRINTF(("get_soa: save_ns failed")); + goto cleanup; + } + free(resp); + return (0); + } + + /* If we're out of labels, then not even "." has an SOA! */ + if (*dname == '\0') + break; + + /* Find label-terminating "."; top of loop will skip it. */ + while (*dname != '.') { + if (*dname == '\\') + if (*++dname == '\0') { + errno = EMSGSIZE; + goto cleanup; + } + dname++; + } + } + DPRINTF(("get_soa: out of labels")); + errno = EDESTADDRREQ; + cleanup: + if (resp != NULL) + free(resp); + return (-1); +} + +static int +get_ns(res_state statp, const char *zname, ns_class class, int opts, + rrset_ns *nsrrsp) +{ + u_char *resp; + ns_msg msg; + int n; + + resp = malloc(NS_MAXMSG); + if (resp == NULL) + return (-1); + + /* Go and get the NS RRs for this zone. */ + n = do_query(statp, zname, class, ns_t_ns, resp, &msg); + if (n != 0) { + DPRINTF(("get_ns: do_query('%s', %s) failed (%d)", + zname, p_class(class), n)); + free(resp); + return (-1); + } + + /* Remember the NS RRs and associated A RRs that came back. */ + if (save_ns(statp, &msg, ns_s_an, zname, class, opts, nsrrsp) < 0) { + DPRINTF(("get_ns save_ns('%s', %s) failed", + zname, p_class(class))); + free(resp); + return (-1); + } + + free(resp); + return (0); +} + +static int +get_glue(res_state statp, ns_class class, int opts, rrset_ns *nsrrsp) { + rr_ns *nsrr, *nsrr_n; + u_char *resp; + + resp = malloc(NS_MAXMSG); + if (resp == NULL) + return(-1); + + /* Go and get the A RRs for each empty NS RR on our list. */ + for (nsrr = HEAD(*nsrrsp); nsrr != NULL; nsrr = nsrr_n) { + ns_msg msg; + int n; + + nsrr_n = NEXT(nsrr, link); + + if ((nsrr->flags & RR_NS_HAVE_V4) == 0) { + n = do_query(statp, nsrr->name, class, ns_t_a, + resp, &msg); + if (n < 0) { + DPRINTF( + ("get_glue: do_query('%s', %s') failed", + nsrr->name, p_class(class))); + goto cleanup; + } + if (n > 0) { + DPRINTF(( + "get_glue: do_query('%s', %s') CNAME or DNAME found", + nsrr->name, p_class(class))); + } + if (save_a(statp, &msg, ns_s_an, nsrr->name, class, + opts, nsrr) < 0) { + DPRINTF(("get_glue: save_r('%s', %s) failed", + nsrr->name, p_class(class))); + goto cleanup; + } + } + + if ((nsrr->flags & RR_NS_HAVE_V6) == 0) { + n = do_query(statp, nsrr->name, class, ns_t_aaaa, + resp, &msg); + if (n < 0) { + DPRINTF( + ("get_glue: do_query('%s', %s') failed", + nsrr->name, p_class(class))); + goto cleanup; + } + if (n > 0) { + DPRINTF(( + "get_glue: do_query('%s', %s') CNAME or DNAME found", + nsrr->name, p_class(class))); + } + if (save_a(statp, &msg, ns_s_an, nsrr->name, class, + opts, nsrr) < 0) { + DPRINTF(("get_glue: save_r('%s', %s) failed", + nsrr->name, p_class(class))); + goto cleanup; + } + } + + /* If it's still empty, it's just chaff. */ + if (EMPTY(nsrr->addrs)) { + DPRINTF(("get_glue: removing empty '%s' NS", + nsrr->name)); + free_nsrr(nsrrsp, nsrr); + } + } + free(resp); + return (0); + + cleanup: + free(resp); + return (-1); +} + +static int +save_ns(res_state statp, ns_msg *msg, ns_sect sect, + const char *owner, ns_class class, int opts, + rrset_ns *nsrrsp) +{ + int i; + + for (i = 0; i < ns_msg_count(*msg, sect); i++) { + char tname[MAXDNAME]; + const u_char *rdata; + rr_ns *nsrr; + ns_rr rr; + + if (ns_parserr(msg, sect, i, &rr) < 0) { + DPRINTF(("save_ns: ns_parserr(%s, %d) failed", + p_section(sect, ns_o_query), i)); + return (-1); + } + if (ns_rr_type(rr) != ns_t_ns || + ns_rr_class(rr) != class || + ns_samename(ns_rr_name(rr), owner) != 1) + continue; + nsrr = find_ns(nsrrsp, ns_rr_name(rr)); + if (nsrr == NULL) { + nsrr = malloc(sizeof *nsrr); + if (nsrr == NULL) { + DPRINTF(("save_ns: malloc failed")); + return (-1); + } + rdata = ns_rr_rdata(rr); + if (ns_name_uncompress(ns_msg_base(*msg), + ns_msg_end(*msg), rdata, + tname, sizeof tname) < 0) { + DPRINTF(("save_ns: ns_name_uncompress failed") + ); + free(nsrr); + return (-1); + } + nsrr->name = strdup(tname); + if (nsrr->name == NULL) { + DPRINTF(("save_ns: strdup failed")); + free(nsrr); + return (-1); + } + INIT_LINK(nsrr, link); + INIT_LIST(nsrr->addrs); + nsrr->flags = 0; + APPEND(*nsrrsp, nsrr, link); + } + if (save_a(statp, msg, ns_s_ar, + nsrr->name, class, opts, nsrr) < 0) { + DPRINTF(("save_ns: save_r('%s', %s) failed", + nsrr->name, p_class(class))); + return (-1); + } + } + return (0); +} + +static int +save_a(res_state statp, ns_msg *msg, ns_sect sect, + const char *owner, ns_class class, int opts, + rr_ns *nsrr) +{ + int i; + + for (i = 0; i < ns_msg_count(*msg, sect); i++) { + ns_rr rr; + rr_a *arr; + + if (ns_parserr(msg, sect, i, &rr) < 0) { + DPRINTF(("save_a: ns_parserr(%s, %d) failed", + p_section(sect, ns_o_query), i)); + return (-1); + } + if ((ns_rr_type(rr) != ns_t_a && + ns_rr_type(rr) != ns_t_aaaa) || + ns_rr_class(rr) != class || + ns_samename(ns_rr_name(rr), owner) != 1 || + ns_rr_rdlen(rr) != NS_INADDRSZ) + continue; + if ((opts & RES_IPV6ONLY) != 0 && ns_rr_type(rr) != ns_t_aaaa) + continue; + if ((opts & RES_IPV4ONLY) != 0 && ns_rr_type(rr) != ns_t_a) + continue; + arr = malloc(sizeof *arr); + if (arr == NULL) { + DPRINTF(("save_a: malloc failed")); + return (-1); + } + INIT_LINK(arr, link); + memset(&arr->addr, 0, sizeof(arr->addr)); + switch (ns_rr_type(rr)) { + case ns_t_a: + arr->addr.sin.sin_family = AF_INET; +#ifdef HAVE_SA_LEN + arr->addr.sin.sin_len = sizeof(arr->addr.sin); +#endif + memcpy(&arr->addr.sin.sin_addr, ns_rr_rdata(rr), + NS_INADDRSZ); + arr->addr.sin.sin_port = htons(NAMESERVER_PORT); + nsrr->flags |= RR_NS_HAVE_V4; + break; + case ns_t_aaaa: + arr->addr.sin6.sin6_family = AF_INET6; +#ifdef HAVE_SA_LEN + arr->addr.sin6.sin6_len = sizeof(arr->addr.sin6); +#endif + memcpy(&arr->addr.sin6.sin6_addr, ns_rr_rdata(rr), 16); + arr->addr.sin.sin_port = htons(NAMESERVER_PORT); + nsrr->flags |= RR_NS_HAVE_V6; + break; + default: + abort(); + } + APPEND(nsrr->addrs, arr, link); + } + return (0); +} + +static void +free_nsrrset(rrset_ns *nsrrsp) { + rr_ns *nsrr; + + while ((nsrr = HEAD(*nsrrsp)) != NULL) + free_nsrr(nsrrsp, nsrr); +} + +static void +free_nsrr(rrset_ns *nsrrsp, rr_ns *nsrr) { + rr_a *arr; + char *tmp; + + while ((arr = HEAD(nsrr->addrs)) != NULL) { + UNLINK(nsrr->addrs, arr, link); + free(arr); + } + DE_CONST(nsrr->name, tmp); + free(tmp); + UNLINK(*nsrrsp, nsrr, link); + free(nsrr); +} + +static rr_ns * +find_ns(rrset_ns *nsrrsp, const char *dname) { + rr_ns *nsrr; + + for (nsrr = HEAD(*nsrrsp); nsrr != NULL; nsrr = NEXT(nsrr, link)) + if (ns_samename(nsrr->name, dname) == 1) + return (nsrr); + return (NULL); +} + +static int +do_query(res_state statp, const char *dname, ns_class class, ns_type qtype, + u_char *resp, ns_msg *msg) +{ + u_char req[NS_PACKETSZ]; + int i, n; + + n = res_nmkquery(statp, ns_o_query, dname, class, qtype, + NULL, 0, NULL, req, NS_PACKETSZ); + if (n < 0) { + DPRINTF(("do_query: res_nmkquery failed")); + return (-1); + } + n = res_nsend(statp, req, n, resp, NS_MAXMSG); + if (n < 0) { + DPRINTF(("do_query: res_nsend failed")); + return (-1); + } + if (n == 0) { + DPRINTF(("do_query: res_nsend returned 0")); + errno = EMSGSIZE; + return (-1); + } + if (ns_initparse(resp, n, msg) < 0) { + DPRINTF(("do_query: ns_initparse failed")); + return (-1); + } + n = 0; + for (i = 0; i < ns_msg_count(*msg, ns_s_an); i++) { + ns_rr rr; + + if (ns_parserr(msg, ns_s_an, i, &rr) < 0) { + DPRINTF(("do_query: ns_parserr failed")); + return (-1); + } + n += (ns_rr_class(rr) == class && + (ns_rr_type(rr) == ns_t_cname || + ns_rr_type(rr) == ns_t_dname)); + } + return (n); +} + +static void +res_dprintf(const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + fputs(";; res_findzonecut: ", stderr); + vfprintf(stderr, fmt, ap); + fputc('\n', stderr); + va_end(ap); +} + +/*! \file */ diff --git a/lib/libc/resolv/res_mkupdate.c b/lib/libc/resolv/res_mkupdate.c new file mode 100644 index 0000000..3cfaf06 --- /dev/null +++ b/lib/libc/resolv/res_mkupdate.c @@ -0,0 +1,1198 @@ +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996-1999 by Internet Software Consortium. + * + * 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 ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. + */ + +/*! \file + * \brief + * Based on the Dynamic DNS reference implementation by Viraj Bais + * <viraj_bais@ccm.fm.intel.com> + */ + +#if !defined(lint) && !defined(SABER) +static const char rcsid[] = "$Id: res_mkupdate.c,v 1.10 2008/12/11 09:59:00 marka Exp $"; +#endif /* not lint */ +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/resolv/res_mkupdate.c 298226 2016-04-18 21:05:15Z avos $"); + +#include "port_before.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _LIBC +#include +#endif + +#include "port_after.h" + +/* Options. Leave them on. */ +#ifndef DEBUG +#define DEBUG +#endif +#define MAXPORT 1024 + +static int getnum_str(u_char **, u_char *); +static int gethexnum_str(u_char **, u_char *); +static int getword_str(char *, int, u_char **, u_char *); +static int getstr_str(char *, int, u_char **, u_char *); + +#define ShrinkBuffer(x) if ((buflen -= x) < 0) return (-2); + +/* Forward. */ + +#ifdef _LIBC +static +#endif +int res_protocolnumber(const char *); +#ifdef _LIBC +static +#endif +int res_servicenumber(const char *); + +/*% + * Form update packets. + * Returns the size of the resulting packet if no error + * + * On error, + * returns + *\li -1 if error in reading a word/number in rdata + * portion for update packets + *\li -2 if length of buffer passed is insufficient + *\li -3 if zone section is not the first section in + * the linked list, or section order has a problem + *\li -4 on a number overflow + *\li -5 unknown operation or no records + */ +int +res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) { + ns_updrec *rrecp_start = rrecp_in; + HEADER *hp; + u_char *cp, *sp2, *startp, *endp; + int n, i, soanum, multiline; + ns_updrec *rrecp; + struct in_addr ina; + struct in6_addr in6a; + char buf2[MAXDNAME]; + u_char buf3[MAXDNAME]; + int section, numrrs = 0, counts[ns_s_max]; + u_int16_t rtype, rclass; + u_int32_t n1, rttl; + u_char *dnptrs[20], **dpp, **lastdnptr; +#ifndef _LIBC + int siglen; +#endif + int keylen, certlen; + + /* + * Initialize header fields. + */ + if ((buf == NULL) || (buflen < HFIXEDSZ)) + return (-1); + memset(buf, 0, HFIXEDSZ); + hp = (HEADER *) buf; + statp->id = res_nrandomid(statp); + hp->id = htons(statp->id); + hp->opcode = ns_o_update; + hp->rcode = NOERROR; + cp = buf + HFIXEDSZ; + buflen -= HFIXEDSZ; + dpp = dnptrs; + *dpp++ = buf; + *dpp++ = NULL; + lastdnptr = dnptrs + nitems(dnptrs); + + if (rrecp_start == NULL) + return (-5); + else if (rrecp_start->r_section != S_ZONE) + return (-3); + + memset(counts, 0, sizeof counts); + for (rrecp = rrecp_start; rrecp; rrecp = NEXT(rrecp, r_glink)) { + numrrs++; + section = rrecp->r_section; + if (section < 0 || section >= ns_s_max) + return (-1); + counts[section]++; + for (i = section + 1; i < ns_s_max; i++) + if (counts[i]) + return (-3); + rtype = rrecp->r_type; + rclass = rrecp->r_class; + rttl = rrecp->r_ttl; + /* overload class and type */ + if (section == S_PREREQ) { + rttl = 0; + switch (rrecp->r_opcode) { + case YXDOMAIN: + rclass = C_ANY; + rtype = T_ANY; + rrecp->r_size = 0; + break; + case NXDOMAIN: + rclass = C_NONE; + rtype = T_ANY; + rrecp->r_size = 0; + break; + case NXRRSET: + rclass = C_NONE; + rrecp->r_size = 0; + break; + case YXRRSET: + if (rrecp->r_size == 0) + rclass = C_ANY; + break; + default: + fprintf(stderr, + "res_mkupdate: incorrect opcode: %d\n", + rrecp->r_opcode); + fflush(stderr); + return (-1); + } + } else if (section == S_UPDATE) { + switch (rrecp->r_opcode) { + case DELETE: + rclass = rrecp->r_size == 0 ? C_ANY : C_NONE; + break; + case ADD: + break; + default: + fprintf(stderr, + "res_mkupdate: incorrect opcode: %d\n", + rrecp->r_opcode); + fflush(stderr); + return (-1); + } + } + + /* + * XXX appending default domain to owner name is omitted, + * fqdn must be provided + */ + if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs, + lastdnptr)) < 0) + return (-1); + cp += n; + ShrinkBuffer(n + 2*INT16SZ); + PUTSHORT(rtype, cp); + PUTSHORT(rclass, cp); + if (section == S_ZONE) { + if (numrrs != 1 || rrecp->r_type != T_SOA) + return (-3); + continue; + } + ShrinkBuffer(INT32SZ + INT16SZ); + PUTLONG(rttl, cp); + sp2 = cp; /*%< save pointer to length byte */ + cp += INT16SZ; + if (rrecp->r_size == 0) { + if (section == S_UPDATE && rclass != C_ANY) + return (-1); + else { + PUTSHORT(0, sp2); + continue; + } + } + startp = rrecp->r_data; + endp = startp + rrecp->r_size - 1; + /* XXX this should be done centrally. */ + switch (rrecp->r_type) { + case T_A: + if (!getword_str(buf2, sizeof buf2, &startp, endp)) + return (-1); + if (!inet_aton(buf2, &ina)) + return (-1); + n1 = ntohl(ina.s_addr); + ShrinkBuffer(INT32SZ); + PUTLONG(n1, cp); + break; + case T_CNAME: + case T_MB: + case T_MG: + case T_MR: + case T_NS: + case T_PTR: + case ns_t_dname: + if (!getword_str(buf2, sizeof buf2, &startp, endp)) + return (-1); + n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); + if (n < 0) + return (-1); + cp += n; + ShrinkBuffer(n); + break; + case T_MINFO: + case T_SOA: + case T_RP: + for (i = 0; i < 2; i++) { + if (!getword_str(buf2, sizeof buf2, &startp, + endp)) + return (-1); + n = dn_comp(buf2, cp, buflen, + dnptrs, lastdnptr); + if (n < 0) + return (-1); + cp += n; + ShrinkBuffer(n); + } + if (rrecp->r_type == T_SOA) { + ShrinkBuffer(5 * INT32SZ); + while (isspace(*startp) || !*startp) + startp++; + if (*startp == '(') { + multiline = 1; + startp++; + } else + multiline = 0; + /* serial, refresh, retry, expire, minimum */ + for (i = 0; i < 5; i++) { + soanum = getnum_str(&startp, endp); + if (soanum < 0) + return (-1); + PUTLONG(soanum, cp); + } + if (multiline) { + while (isspace(*startp) || !*startp) + startp++; + if (*startp != ')') + return (-1); + } + } + break; + case T_MX: + case T_AFSDB: + case T_RT: + n = getnum_str(&startp, endp); + if (n < 0) + return (-1); + ShrinkBuffer(INT16SZ); + PUTSHORT(n, cp); + if (!getword_str(buf2, sizeof buf2, &startp, endp)) + return (-1); + n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); + if (n < 0) + return (-1); + cp += n; + ShrinkBuffer(n); + break; + case T_SRV: + n = getnum_str(&startp, endp); + if (n < 0) + return (-1); + ShrinkBuffer(INT16SZ); + PUTSHORT(n, cp); + + n = getnum_str(&startp, endp); + if (n < 0) + return (-1); + ShrinkBuffer(INT16SZ); + PUTSHORT(n, cp); + + n = getnum_str(&startp, endp); + if (n < 0) + return (-1); + ShrinkBuffer(INT16SZ); + PUTSHORT(n, cp); + + if (!getword_str(buf2, sizeof buf2, &startp, endp)) + return (-1); + n = dn_comp(buf2, cp, buflen, NULL, NULL); + if (n < 0) + return (-1); + cp += n; + ShrinkBuffer(n); + break; + case T_PX: + n = getnum_str(&startp, endp); + if (n < 0) + return (-1); + PUTSHORT(n, cp); + ShrinkBuffer(INT16SZ); + for (i = 0; i < 2; i++) { + if (!getword_str(buf2, sizeof buf2, &startp, + endp)) + return (-1); + n = dn_comp(buf2, cp, buflen, dnptrs, + lastdnptr); + if (n < 0) + return (-1); + cp += n; + ShrinkBuffer(n); + } + break; + case T_WKS: { + char bm[MAXPORT/8]; + unsigned int maxbm = 0; + + if (!getword_str(buf2, sizeof buf2, &startp, endp)) + return (-1); + if (!inet_aton(buf2, &ina)) + return (-1); + n1 = ntohl(ina.s_addr); + ShrinkBuffer(INT32SZ); + PUTLONG(n1, cp); + + if (!getword_str(buf2, sizeof buf2, &startp, endp)) + return (-1); + if ((i = res_protocolnumber(buf2)) < 0) + return (-1); + ShrinkBuffer(1); + *cp++ = i & 0xff; + + for (i = 0; i < MAXPORT/8 ; i++) + bm[i] = 0; + + while (getword_str(buf2, sizeof buf2, &startp, endp)) { + if ((n = res_servicenumber(buf2)) <= 0) + return (-1); + + if (n < MAXPORT) { + bm[n/8] |= (0x80>>(n%8)); + if ((unsigned)n > maxbm) + maxbm = n; + } else + return (-1); + } + maxbm = maxbm/8 + 1; + ShrinkBuffer(maxbm); + memcpy(cp, bm, maxbm); + cp += maxbm; + break; + } + case T_HINFO: + for (i = 0; i < 2; i++) { + if ((n = getstr_str(buf2, sizeof buf2, + &startp, endp)) < 0) + return (-1); + if (n > 255) + return (-1); + ShrinkBuffer(n+1); + *cp++ = n; + memcpy(cp, buf2, n); + cp += n; + } + break; + case T_TXT: + for (;;) { + if ((n = getstr_str(buf2, sizeof buf2, + &startp, endp)) < 0) { + if (cp != (sp2 + INT16SZ)) + break; + return (-1); + } + if (n > 255) + return (-1); + ShrinkBuffer(n+1); + *cp++ = n; + memcpy(cp, buf2, n); + cp += n; + } + break; + case T_X25: + /* RFC1183 */ + if ((n = getstr_str(buf2, sizeof buf2, &startp, + endp)) < 0) + return (-1); + if (n > 255) + return (-1); + ShrinkBuffer(n+1); + *cp++ = n; + memcpy(cp, buf2, n); + cp += n; + break; + case T_ISDN: + /* RFC1183 */ + if ((n = getstr_str(buf2, sizeof buf2, &startp, + endp)) < 0) + return (-1); + if ((n > 255) || (n == 0)) + return (-1); + ShrinkBuffer(n+1); + *cp++ = n; + memcpy(cp, buf2, n); + cp += n; + if ((n = getstr_str(buf2, sizeof buf2, &startp, + endp)) < 0) + n = 0; + if (n > 255) + return (-1); + ShrinkBuffer(n+1); + *cp++ = n; + memcpy(cp, buf2, n); + cp += n; + break; + case T_NSAP: + if ((n = inet_nsap_addr((char *)startp, (u_char *)buf2, sizeof(buf2))) != 0) { + ShrinkBuffer(n); + memcpy(cp, buf2, n); + cp += n; + } else { + return (-1); + } + break; + case T_LOC: + if ((n = loc_aton((char *)startp, (u_char *)buf2)) != 0) { + ShrinkBuffer(n); + memcpy(cp, buf2, n); + cp += n; + } else + return (-1); + break; + case ns_t_sig: +#ifdef _LIBC + return (-1); +#else + { + int sig_type, success, dateerror; + u_int32_t exptime, timesigned; + + /* type */ + if ((n = getword_str(buf2, sizeof buf2, + &startp, endp)) < 0) + return (-1); + sig_type = sym_ston(__p_type_syms, buf2, &success); + if (!success || sig_type == ns_t_any) + return (-1); + ShrinkBuffer(INT16SZ); + PUTSHORT(sig_type, cp); + /* alg */ + n = getnum_str(&startp, endp); + if (n < 0) + return (-1); + ShrinkBuffer(1); + *cp++ = n; + /* labels */ + n = getnum_str(&startp, endp); + if (n <= 0 || n > 255) + return (-1); + ShrinkBuffer(1); + *cp++ = n; + /* ottl & expire */ + if (!getword_str(buf2, sizeof buf2, &startp, endp)) + return (-1); + exptime = ns_datetosecs(buf2, &dateerror); + if (!dateerror) { + ShrinkBuffer(INT32SZ); + PUTLONG(rttl, cp); + } + else { + char *ulendp; + u_int32_t ottl; + + errno = 0; + ottl = strtoul(buf2, &ulendp, 10); + if (errno != 0 || + (ulendp != NULL && *ulendp != '\0')) + return (-1); + ShrinkBuffer(INT32SZ); + PUTLONG(ottl, cp); + if (!getword_str(buf2, sizeof buf2, &startp, + endp)) + return (-1); + exptime = ns_datetosecs(buf2, &dateerror); + if (dateerror) + return (-1); + } + /* expire */ + ShrinkBuffer(INT32SZ); + PUTLONG(exptime, cp); + /* timesigned */ + if (!getword_str(buf2, sizeof buf2, &startp, endp)) + return (-1); + timesigned = ns_datetosecs(buf2, &dateerror); + if (!dateerror) { + ShrinkBuffer(INT32SZ); + PUTLONG(timesigned, cp); + } + else + return (-1); + /* footprint */ + n = getnum_str(&startp, endp); + if (n < 0) + return (-1); + ShrinkBuffer(INT16SZ); + PUTSHORT(n, cp); + /* signer name */ + if (!getword_str(buf2, sizeof buf2, &startp, endp)) + return (-1); + n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr); + if (n < 0) + return (-1); + cp += n; + ShrinkBuffer(n); + /* sig */ + if ((n = getword_str(buf2, sizeof buf2, + &startp, endp)) < 0) + return (-1); + siglen = b64_pton(buf2, buf3, sizeof(buf3)); + if (siglen < 0) + return (-1); + ShrinkBuffer(siglen); + memcpy(cp, buf3, siglen); + cp += siglen; + break; + } +#endif + case ns_t_key: + /* flags */ + n = gethexnum_str(&startp, endp); + if (n < 0) + return (-1); + ShrinkBuffer(INT16SZ); + PUTSHORT(n, cp); + /* proto */ + n = getnum_str(&startp, endp); + if (n < 0) + return (-1); + ShrinkBuffer(1); + *cp++ = n; + /* alg */ + n = getnum_str(&startp, endp); + if (n < 0) + return (-1); + ShrinkBuffer(1); + *cp++ = n; + /* key */ + if ((n = getword_str(buf2, sizeof buf2, + &startp, endp)) < 0) + return (-1); + keylen = b64_pton(buf2, buf3, sizeof(buf3)); + if (keylen < 0) + return (-1); + ShrinkBuffer(keylen); + memcpy(cp, buf3, keylen); + cp += keylen; + break; + case ns_t_nxt: + { + int success, nxt_type; + u_char data[32]; + int maxtype; + + /* next name */ + if (!getword_str(buf2, sizeof buf2, &startp, endp)) + return (-1); + n = dn_comp(buf2, cp, buflen, NULL, NULL); + if (n < 0) + return (-1); + cp += n; + ShrinkBuffer(n); + maxtype = 0; + memset(data, 0, sizeof data); + for (;;) { + if (!getword_str(buf2, sizeof buf2, &startp, + endp)) + break; + nxt_type = sym_ston(__p_type_syms, buf2, + &success); + if (!success || !ns_t_rr_p(nxt_type)) + return (-1); + NS_NXT_BIT_SET(nxt_type, data); + if (nxt_type > maxtype) + maxtype = nxt_type; + } + n = maxtype/NS_NXT_BITS+1; + ShrinkBuffer(n); + memcpy(cp, data, n); + cp += n; + break; + } + case ns_t_cert: + /* type */ + n = getnum_str(&startp, endp); + if (n < 0) + return (-1); + ShrinkBuffer(INT16SZ); + PUTSHORT(n, cp); + /* key tag */ + n = getnum_str(&startp, endp); + if (n < 0) + return (-1); + ShrinkBuffer(INT16SZ); + PUTSHORT(n, cp); + /* alg */ + n = getnum_str(&startp, endp); + if (n < 0) + return (-1); + ShrinkBuffer(1); + *cp++ = n; + /* cert */ + if ((n = getword_str(buf2, sizeof buf2, + &startp, endp)) < 0) + return (-1); + certlen = b64_pton(buf2, buf3, sizeof(buf3)); + if (certlen < 0) + return (-1); + ShrinkBuffer(certlen); + memcpy(cp, buf3, certlen); + cp += certlen; + break; + case ns_t_aaaa: + if (!getword_str(buf2, sizeof buf2, &startp, endp)) + return (-1); + if (inet_pton(AF_INET6, buf2, &in6a) <= 0) + return (-1); + ShrinkBuffer(NS_IN6ADDRSZ); + memcpy(cp, &in6a, NS_IN6ADDRSZ); + cp += NS_IN6ADDRSZ; + break; + case ns_t_naptr: + /* Order Preference Flags Service Replacement Regexp */ + /* Order */ + n = getnum_str(&startp, endp); + if (n < 0 || n > 65535) + return (-1); + ShrinkBuffer(INT16SZ); + PUTSHORT(n, cp); + /* Preference */ + n = getnum_str(&startp, endp); + if (n < 0 || n > 65535) + return (-1); + ShrinkBuffer(INT16SZ); + PUTSHORT(n, cp); + /* Flags */ + if ((n = getstr_str(buf2, sizeof buf2, + &startp, endp)) < 0) { + return (-1); + } + if (n > 255) + return (-1); + ShrinkBuffer(n+1); + *cp++ = n; + memcpy(cp, buf2, n); + cp += n; + /* Service Classes */ + if ((n = getstr_str(buf2, sizeof buf2, + &startp, endp)) < 0) { + return (-1); + } + if (n > 255) + return (-1); + ShrinkBuffer(n+1); + *cp++ = n; + memcpy(cp, buf2, n); + cp += n; + /* Pattern */ + if ((n = getstr_str(buf2, sizeof buf2, + &startp, endp)) < 0) { + return (-1); + } + if (n > 255) + return (-1); + ShrinkBuffer(n+1); + *cp++ = n; + memcpy(cp, buf2, n); + cp += n; + /* Replacement */ + if (!getword_str(buf2, sizeof buf2, &startp, endp)) + return (-1); + n = dn_comp(buf2, cp, buflen, NULL, NULL); + if (n < 0) + return (-1); + cp += n; + ShrinkBuffer(n); + break; + default: + return (-1); + } /*switch*/ + n = (u_int16_t)((cp - sp2) - INT16SZ); + PUTSHORT(n, sp2); + } /*for*/ + + hp->qdcount = htons(counts[0]); + hp->ancount = htons(counts[1]); + hp->nscount = htons(counts[2]); + hp->arcount = htons(counts[3]); + return (cp - buf); +} + +/*% + * Get a whitespace delimited word from a string (not file) + * into buf. modify the start pointer to point after the + * word in the string. + */ +static int +getword_str(char *buf, int size, u_char **startpp, u_char *endp) { + char *cp; + int c; + + for (cp = buf; *startpp <= endp; ) { + c = **startpp; + if (isspace(c) || c == '\0') { + if (cp != buf) /*%< trailing whitespace */ + break; + else { /*%< leading whitespace */ + (*startpp)++; + continue; + } + } + (*startpp)++; + if (cp >= buf+size-1) + break; + *cp++ = (u_char)c; + } + *cp = '\0'; + return (cp != buf); +} + +/*% + * get a white spae delimited string from memory. Process quoted strings + * and \\DDD escapes. Return length or -1 on error. Returned string may + * contain nulls. + */ +static char digits[] = "0123456789"; +static int +getstr_str(char *buf, int size, u_char **startpp, u_char *endp) { + char *cp; + int c, c1 = 0; + int inquote = 0; + int seen_quote = 0; + int escape = 0; + int dig = 0; + + for (cp = buf; *startpp <= endp; ) { + if ((c = **startpp) == '\0') + break; + /* leading white space */ + if ((cp == buf) && !seen_quote && isspace(c)) { + (*startpp)++; + continue; + } + + switch (c) { + case '\\': + if (!escape) { + escape = 1; + dig = 0; + c1 = 0; + (*startpp)++; + continue; + } + goto do_escape; + case '"': + if (!escape) { + inquote = !inquote; + seen_quote = 1; + (*startpp)++; + continue; + } + /* fall through */ + default: + do_escape: + if (escape) { + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + c1 = c1 * 10 + + (strchr(digits, c) - digits); + + if (++dig == 3) { + c = c1 &0xff; + break; + } + (*startpp)++; + continue; + } + escape = 0; + } else if (!inquote && isspace(c)) + goto done; + if (cp >= buf+size-1) + goto done; + *cp++ = (u_char)c; + (*startpp)++; + } + } + done: + *cp = '\0'; + return ((cp == buf)? (seen_quote? 0: -1): (cp - buf)); +} + +/*% + * Get a whitespace delimited base 16 number from a string (not file) into buf + * update the start pointer to point after the number in the string. + */ +static int +gethexnum_str(u_char **startpp, u_char *endp) { + int c, n; + int seendigit = 0; + int m = 0; + + if (*startpp + 2 >= endp || strncasecmp((char *)*startpp, "0x", 2) != 0) + return getnum_str(startpp, endp); + (*startpp)+=2; + for (n = 0; *startpp <= endp; ) { + c = **startpp; + if (isspace(c) || c == '\0') { + if (seendigit) /*%< trailing whitespace */ + break; + else { /*%< leading whitespace */ + (*startpp)++; + continue; + } + } + if (c == ';') { + while ((*startpp <= endp) && + ((c = **startpp) != '\n')) + (*startpp)++; + if (seendigit) + break; + continue; + } + if (!isxdigit(c)) { + if (c == ')' && seendigit) { + (*startpp)--; + break; + } + return (-1); + } + (*startpp)++; + if (isdigit(c)) + n = n * 16 + (c - '0'); + else + n = n * 16 + (tolower(c) - 'a' + 10); + seendigit = 1; + } + return (n + m); +} + +/*% + * Get a whitespace delimited base 10 number from a string (not file) into buf + * update the start pointer to point after the number in the string. + */ +static int +getnum_str(u_char **startpp, u_char *endp) { + int c, n; + int seendigit = 0; + int m = 0; + + for (n = 0; *startpp <= endp; ) { + c = **startpp; + if (isspace(c) || c == '\0') { + if (seendigit) /*%< trailing whitespace */ + break; + else { /*%< leading whitespace */ + (*startpp)++; + continue; + } + } + if (c == ';') { + while ((*startpp <= endp) && + ((c = **startpp) != '\n')) + (*startpp)++; + if (seendigit) + break; + continue; + } + if (!isdigit(c)) { + if (c == ')' && seendigit) { + (*startpp)--; + break; + } + return (-1); + } + (*startpp)++; + n = n * 10 + (c - '0'); + seendigit = 1; + } + return (n + m); +} + +/*% + * Allocate a resource record buffer & save rr info. + */ +ns_updrec * +res_mkupdrec(int section, const char *dname, + u_int class, u_int type, u_long ttl) { + ns_updrec *rrecp = (ns_updrec *)calloc(1, sizeof(ns_updrec)); + + if (!rrecp || !(rrecp->r_dname = strdup(dname))) { + if (rrecp) + free((char *)rrecp); + return (NULL); + } + INIT_LINK(rrecp, r_link); + INIT_LINK(rrecp, r_glink); + rrecp->r_class = (ns_class)class; + rrecp->r_type = (ns_type)type; + rrecp->r_ttl = ttl; + rrecp->r_section = (ns_sect)section; + return (rrecp); +} + +/*% + * Free a resource record buffer created by res_mkupdrec. + */ +void +res_freeupdrec(ns_updrec *rrecp) { + /* Note: freeing r_dp is the caller's responsibility. */ + if (rrecp->r_dname != NULL) + free(rrecp->r_dname); + free(rrecp); +} + +struct valuelist { + struct valuelist * next; + struct valuelist * prev; + char * name; + char * proto; + int port; +}; +static struct valuelist *servicelist, *protolist; + +static void +res_buildservicelist(void) { + struct servent *sp; + struct valuelist *slp; + +#ifdef MAYBE_HESIOD + setservent(0); +#else + setservent(1); +#endif + while ((sp = getservent()) != NULL) { + slp = (struct valuelist *)malloc(sizeof(struct valuelist)); + if (!slp) + break; + slp->name = strdup(sp->s_name); + slp->proto = strdup(sp->s_proto); + if ((slp->name == NULL) || (slp->proto == NULL)) { + if (slp->name) free(slp->name); + if (slp->proto) free(slp->proto); + free(slp); + break; + } + slp->port = ntohs((u_int16_t)sp->s_port); /*%< host byt order */ + slp->next = servicelist; + slp->prev = NULL; + if (servicelist) + servicelist->prev = slp; + servicelist = slp; + } + endservent(); +} + +#ifndef _LIBC +void +res_destroyservicelist() { + struct valuelist *slp, *slp_next; + + for (slp = servicelist; slp != NULL; slp = slp_next) { + slp_next = slp->next; + free(slp->name); + free(slp->proto); + free(slp); + } + servicelist = (struct valuelist *)0; +} +#endif + +#ifdef _LIBC +static +#endif +void +res_buildprotolist(void) { + struct protoent *pp; + struct valuelist *slp; + +#ifdef MAYBE_HESIOD + setprotoent(0); +#else + setprotoent(1); +#endif + while ((pp = getprotoent()) != NULL) { + slp = (struct valuelist *)malloc(sizeof(struct valuelist)); + if (!slp) + break; + slp->name = strdup(pp->p_name); + if (slp->name == NULL) { + free(slp); + break; + } + slp->port = pp->p_proto; /*%< host byte order */ + slp->next = protolist; + slp->prev = NULL; + if (protolist) + protolist->prev = slp; + protolist = slp; + } + endprotoent(); +} + +#ifndef _LIBC +void +res_destroyprotolist(void) { + struct valuelist *plp, *plp_next; + + for (plp = protolist; plp != NULL; plp = plp_next) { + plp_next = plp->next; + free(plp->name); + free(plp); + } + protolist = (struct valuelist *)0; +} +#endif + +static int +findservice(const char *s, struct valuelist **list) { + struct valuelist *lp = *list; + int n; + + for (; lp != NULL; lp = lp->next) + if (strcasecmp(lp->name, s) == 0) { + if (lp != *list) { + lp->prev->next = lp->next; + if (lp->next) + lp->next->prev = lp->prev; + (*list)->prev = lp; + lp->next = *list; + *list = lp; + } + return (lp->port); /*%< host byte order */ + } + if (sscanf(s, "%d", &n) != 1 || n <= 0) + n = -1; + return (n); +} + +/*% + * Convert service name or (ascii) number to int. + */ +#ifdef _LIBC +static +#endif +int +res_servicenumber(const char *p) { + if (servicelist == (struct valuelist *)0) + res_buildservicelist(); + return (findservice(p, &servicelist)); +} + +/*% + * Convert protocol name or (ascii) number to int. + */ +#ifdef _LIBC +static +#endif +int +res_protocolnumber(const char *p) { + if (protolist == (struct valuelist *)0) + res_buildprotolist(); + return (findservice(p, &protolist)); +} + +#ifndef _LIBC +static struct servent * +cgetservbyport(u_int16_t port, const char *proto) { /*%< Host byte order. */ + struct valuelist **list = &servicelist; + struct valuelist *lp = *list; + static struct servent serv; + + port = ntohs(port); + for (; lp != NULL; lp = lp->next) { + if (port != (u_int16_t)lp->port) /*%< Host byte order. */ + continue; + if (strcasecmp(lp->proto, proto) == 0) { + if (lp != *list) { + lp->prev->next = lp->next; + if (lp->next) + lp->next->prev = lp->prev; + (*list)->prev = lp; + lp->next = *list; + *list = lp; + } + serv.s_name = lp->name; + serv.s_port = htons((u_int16_t)lp->port); + serv.s_proto = lp->proto; + return (&serv); + } + } + return (0); +} + +static struct protoent * +cgetprotobynumber(int proto) { /*%< Host byte order. */ + struct valuelist **list = &protolist; + struct valuelist *lp = *list; + static struct protoent prot; + + for (; lp != NULL; lp = lp->next) + if (lp->port == proto) { /*%< Host byte order. */ + if (lp != *list) { + lp->prev->next = lp->next; + if (lp->next) + lp->next->prev = lp->prev; + (*list)->prev = lp; + lp->next = *list; + *list = lp; + } + prot.p_name = lp->name; + prot.p_proto = lp->port; /*%< Host byte order. */ + return (&prot); + } + return (0); +} + +const char * +res_protocolname(int num) { + static char number[8]; + struct protoent *pp; + + if (protolist == (struct valuelist *)0) + res_buildprotolist(); + pp = cgetprotobynumber(num); + if (pp == NULL) { + (void) sprintf(number, "%d", num); + return (number); + } + return (pp->p_name); +} + +const char * +res_servicename(u_int16_t port, const char *proto) { /*%< Host byte order. */ + static char number[8]; + struct servent *ss; + + if (servicelist == (struct valuelist *)0) + res_buildservicelist(); + ss = cgetservbyport(htons(port), proto); + if (ss == NULL) { + (void) sprintf(number, "%d", port); + return (number); + } + return (ss->s_name); +} +#endif diff --git a/lib/libc/resolv/res_update.c b/lib/libc/resolv/res_update.c new file mode 100644 index 0000000..54792c4 --- /dev/null +++ b/lib/libc/resolv/res_update.c @@ -0,0 +1,222 @@ +#if !defined(lint) && !defined(SABER) +static const char rcsid[] = "$Id: res_update.c,v 1.13 2005/04/27 04:56:43 sra Exp $"; +#endif /* not lint */ + +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996-1999 by Internet Software Consortium. + * + * 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 ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. + */ + +/*! \file + * \brief + * Based on the Dynamic DNS reference implementation by Viraj Bais + * <viraj_bais@ccm.fm.intel.com> + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/resolv/res_update.c 269867 2014-08-12 12:36:06Z ume $"); + +#include "port_before.h" + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "port_after.h" +#include "res_private.h" + +/*% + * Separate a linked list of records into groups so that all records + * in a group will belong to a single zone on the nameserver. + * Create a dynamic update packet for each zone and send it to the + * nameservers for that zone, and await answer. + * Abort if error occurs in updating any zone. + * Return the number of zones updated on success, < 0 on error. + * + * On error, caller must deal with the unsynchronized zones + * eg. an A record might have been successfully added to the forward + * zone but the corresponding PTR record would be missing if error + * was encountered while updating the reverse zone. + */ + +struct zonegrp { + char z_origin[MAXDNAME]; + ns_class z_class; + union res_sockaddr_union z_nsaddrs[MAXNS]; + int z_nscount; + int z_flags; + LIST(ns_updrec) z_rrlist; + LINK(struct zonegrp) z_link; +}; + +#define ZG_F_ZONESECTADDED 0x0001 + +/* Forward. */ + +static void res_dprintf(const char *, ...) ISC_FORMAT_PRINTF(1, 2); + +/* Macros. */ + +#define DPRINTF(x) do {\ + int save_errno = errno; \ + if ((statp->options & RES_DEBUG) != 0U) res_dprintf x; \ + errno = save_errno; \ + } while (0) + +/* Public. */ + +int +res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { + ns_updrec *rrecp; + u_char answer[PACKETSZ]; + u_char *packet; + struct zonegrp *zptr, tgrp; + LIST(struct zonegrp) zgrps; + int nzones = 0, nscount = 0, n; + union res_sockaddr_union nsaddrs[MAXNS]; + + packet = malloc(NS_MAXMSG); + if (packet == NULL) { + DPRINTF(("malloc failed")); + return (0); + } + /* Thread all of the updates onto a list of groups. */ + INIT_LIST(zgrps); + memset(&tgrp, 0, sizeof (tgrp)); + for (rrecp = rrecp_in; rrecp; + rrecp = LINKED(rrecp, r_link) ? NEXT(rrecp, r_link) : NULL) { + int nscnt; + /* Find the origin for it if there is one. */ + tgrp.z_class = rrecp->r_class; + nscnt = res_findzonecut2(statp, rrecp->r_dname, tgrp.z_class, + RES_EXHAUSTIVE, tgrp.z_origin, + sizeof tgrp.z_origin, + tgrp.z_nsaddrs, MAXNS); + if (nscnt <= 0) { + DPRINTF(("res_findzonecut failed (%d)", nscnt)); + goto done; + } + tgrp.z_nscount = nscnt; + /* Find the group for it if there is one. */ + for (zptr = HEAD(zgrps); zptr != NULL; zptr = NEXT(zptr, z_link)) + if (ns_samename(tgrp.z_origin, zptr->z_origin) == 1 && + tgrp.z_class == zptr->z_class) + break; + /* Make a group for it if there isn't one. */ + if (zptr == NULL) { + zptr = malloc(sizeof *zptr); + if (zptr == NULL) { + DPRINTF(("malloc failed")); + goto done; + } + *zptr = tgrp; + zptr->z_flags = 0; + INIT_LINK(zptr, z_link); + INIT_LIST(zptr->z_rrlist); + APPEND(zgrps, zptr, z_link); + } + /* Thread this rrecp onto the right group. */ + APPEND(zptr->z_rrlist, rrecp, r_glink); + } + + for (zptr = HEAD(zgrps); zptr != NULL; zptr = NEXT(zptr, z_link)) { + /* Construct zone section and prepend it. */ + rrecp = res_mkupdrec(ns_s_zn, zptr->z_origin, + zptr->z_class, ns_t_soa, 0); + if (rrecp == NULL) { + DPRINTF(("res_mkupdrec failed")); + goto done; + } + PREPEND(zptr->z_rrlist, rrecp, r_glink); + zptr->z_flags |= ZG_F_ZONESECTADDED; + + /* Marshall the update message. */ + n = res_nmkupdate(statp, HEAD(zptr->z_rrlist), + packet, NS_MAXMSG); + DPRINTF(("res_mkupdate -> %d", n)); + if (n < 0) + goto done; + + /* Temporarily replace the resolver's nameserver set. */ + nscount = res_getservers(statp, nsaddrs, MAXNS); + res_setservers(statp, zptr->z_nsaddrs, zptr->z_nscount); + + /* Send the update and remember the result. */ + if (key != NULL) { +#ifdef _LIBC + DPRINTF(("TSIG is not supported\n")); + RES_SET_H_ERRNO(statp, NO_RECOVERY); + goto done; +#else + n = res_nsendsigned(statp, packet, n, key, + answer, sizeof answer); +#endif + } else + n = res_nsend(statp, packet, n, answer, sizeof answer); + if (n < 0) { + DPRINTF(("res_nsend: send error, n=%d (%s)\n", + n, strerror(errno))); + goto done; + } + if (((HEADER *)answer)->rcode == NOERROR) + nzones++; + + /* Restore resolver's nameserver set. */ + res_setservers(statp, nsaddrs, nscount); + nscount = 0; + } + done: + while (!EMPTY(zgrps)) { + zptr = HEAD(zgrps); + if ((zptr->z_flags & ZG_F_ZONESECTADDED) != 0) + res_freeupdrec(HEAD(zptr->z_rrlist)); + UNLINK(zgrps, zptr, z_link); + free(zptr); + } + if (nscount != 0) + res_setservers(statp, nsaddrs, nscount); + + free(packet); + return (nzones); +} + +/* Private. */ + +static void +res_dprintf(const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + fputs(";; res_nupdate: ", stderr); + vfprintf(stderr, fmt, ap); + fputc('\n', stderr); + va_end(ap); +} diff --git a/lib/libc/riscv/Makefile.inc b/lib/libc/riscv/Makefile.inc new file mode 100644 index 0000000..4384c02 --- /dev/null +++ b/lib/libc/riscv/Makefile.inc @@ -0,0 +1,9 @@ +# $FreeBSD: releng/11.1/lib/libc/riscv/Makefile.inc 315044 2017-03-11 02:51:29Z brooks $ +# +# Machine dependent definitions for the RISC-V architecture. +# + +# Long double is quad precision +GDTOASRCS+=strtorQ.c +SRCS+=machdep_ldisQ.c +SYM_MAPS+=${LIBC_SRCTOP}/riscv/Symbol.map diff --git a/lib/libc/riscv/SYS.h b/lib/libc/riscv/SYS.h new file mode 100644 index 0000000..00bc1c6 --- /dev/null +++ b/lib/libc/riscv/SYS.h @@ -0,0 +1,68 @@ +/*- + * Copyright (c) 2014 Andrew Turner + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/riscv/SYS.h 294227 2016-01-17 15:21:23Z br $ + */ + +#include +#include + +#define _SYSCALL(name) \ + li t0, SYS_ ## name; \ + ecall + +#define SYSCALL(name) \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + ret; \ +END(__sys_##name) + +#define PSEUDO(name) \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + bnez t0, cerror; \ + ret; \ +END(__sys_##name) + +#define RSYSCALL(name) \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + bnez t0, cerror; \ + ret; \ +END(__sys_##name) diff --git a/lib/libc/riscv/Symbol.map b/lib/libc/riscv/Symbol.map new file mode 100644 index 0000000..72aa784 --- /dev/null +++ b/lib/libc/riscv/Symbol.map @@ -0,0 +1,38 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/riscv/Symbol.map 300680 2016-05-25 14:08:21Z br $ + */ + +/* + * This only needs to contain symbols that are not listed in + * symbol maps from other parts of libc (i.e., not found in + * stdlib/Symbol.map, string/Symbol.map, sys/Symbol.map, ...). + */ +FBSD_1.0 { + /* PSEUDO syscalls */ + _exit; + + _setjmp; + _longjmp; + fabs; + __flt_rounds; + fpgetmask; + fpsetmask; + __infinity; + __nan; + setjmp; + longjmp; + sigsetjmp; + siglongjmp; + htonl; + htons; + ntohl; + ntohs; + vfork; + makecontext; +}; + +FBSDprivate_1.0 { + _set_tp; + _end; + __makecontext; +}; diff --git a/lib/libc/riscv/_fpmath.h b/lib/libc/riscv/_fpmath.h new file mode 100644 index 0000000..a1d4753 --- /dev/null +++ b/lib/libc/riscv/_fpmath.h @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * Copyright (c) 2014 The FreeBSD Foundation + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/riscv/_fpmath.h 294227 2016-01-17 15:21:23Z br $ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned long manl :64; + unsigned long manh :48; + unsigned int exp :15; + unsigned int sign :1; + } bits; + struct { + unsigned long manl :64; + unsigned long manh :48; + unsigned int expsign :16; + } xbits; +}; + +#define LDBL_NBIT 0 +#define LDBL_IMPLICIT_NBIT +#define mask_nbit_l(u) ((void)0) + +#define LDBL_MANH_SIZE 20 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) + +/* + * TODO: Due to compiler problem we are temporary using + * LDBL_PREC == 53. Use code below for LDBL_PREC == 113 + */ +#if 0 +#define LDBL_MANH_SIZE 48 +#define LDBL_MANL_SIZE 64 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)((u).bits.manl >> 32); \ + (a)[2] = (uint32_t)(u).bits.manh; \ + (a)[3] = (uint32_t)((u).bits.manh >> 32); \ +} while(0) +#endif diff --git a/lib/libc/riscv/arith.h b/lib/libc/riscv/arith.h new file mode 100644 index 0000000..9ea9fc2 --- /dev/null +++ b/lib/libc/riscv/arith.h @@ -0,0 +1,19 @@ +/* + * MD header for contrib/gdtoa + * + * $FreeBSD: releng/11.1/lib/libc/riscv/arith.h 294227 2016-01-17 15:21:23Z br $ + */ + +/* + * NOTE: The definitions in this file must be correct or strtod(3) and + * floating point formats in printf(3) will break! The file can be + * generated by running contrib/gdtoa/arithchk.c on the target + * architecture. See contrib/gdtoa/gdtoaimp.h for details. + */ + +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#define Long int +#define Intcast (int)(long) +#define Double_Align +#define X64_bit_pointers diff --git a/lib/libc/riscv/gd_qnan.h b/lib/libc/riscv/gd_qnan.h new file mode 100644 index 0000000..346c1cc --- /dev/null +++ b/lib/libc/riscv/gd_qnan.h @@ -0,0 +1,21 @@ +/* + * MD header for contrib/gdtoa + * + * This file can be generated by compiling and running contrib/gdtoa/qnan.c + * on the target architecture after arith.h has been generated. + * + * $FreeBSD: releng/11.1/lib/libc/riscv/gd_qnan.h 294227 2016-01-17 15:21:23Z br $ + */ + +#define f_QNAN 0x7fc00000 +#define d_QNAN0 0x0 +#define d_QNAN1 0x7ff80000 +#define ld_QNAN0 0x0 +#define ld_QNAN1 0x7ff80000 +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x0 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0x7ff8 +#define ldus_QNAN4 0x0 diff --git a/lib/libc/riscv/gen/Makefile.inc b/lib/libc/riscv/gen/Makefile.inc new file mode 100644 index 0000000..e08e46c --- /dev/null +++ b/lib/libc/riscv/gen/Makefile.inc @@ -0,0 +1,13 @@ +# $FreeBSD: releng/11.1/lib/libc/riscv/gen/Makefile.inc 294227 2016-01-17 15:21:23Z br $ + +SRCS+= _ctx_start.S \ + fabs.S \ + flt_rounds.c \ + infinity.c \ + ldexp.c \ + makecontext.c \ + _setjmp.S \ + _set_tp.c \ + setjmp.S \ + sigsetjmp.S \ + trivial-getcontextx.c diff --git a/lib/libc/riscv/gen/_ctx_start.S b/lib/libc/riscv/gen/_ctx_start.S new file mode 100644 index 0000000..6225cc0 --- /dev/null +++ b/lib/libc/riscv/gen/_ctx_start.S @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/gen/_ctx_start.S 294227 2016-01-17 15:21:23Z br $"); + +ENTRY(_ctx_start) + jalr s0 /* Call func from makecontext */ + mv a0, s1 /* Load ucp saved in makecontext */ + call _C_LABEL(ctx_done) + call _C_LABEL(abort) +END(_ctx_start) diff --git a/lib/libc/riscv/gen/_set_tp.c b/lib/libc/riscv/gen/_set_tp.c new file mode 100644 index 0000000..934f09e --- /dev/null +++ b/lib/libc/riscv/gen/_set_tp.c @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/gen/_set_tp.c 294227 2016-01-17 15:21:23Z br $"); + +#include +#include + +#include + +#include + +void +_set_tp(void *tp) +{ + + __asm __volatile("mv tp, %0" :: "r"((char*)tp + 0x10)); +} diff --git a/lib/libc/riscv/gen/_setjmp.S b/lib/libc/riscv/gen/_setjmp.S new file mode 100644 index 0000000..2b2b07f --- /dev/null +++ b/lib/libc/riscv/gen/_setjmp.S @@ -0,0 +1,151 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/gen/_setjmp.S 294227 2016-01-17 15:21:23Z br $"); + +#include + +ENTRY(_setjmp) + /* Store the magic value and stack pointer */ + la t0, .Lmagic + ld t0, 0(t0) + sd t0, (0 * 8)(a0) + sd sp, (1 * 8)(a0) + addi a0, a0, (2 * 8) + + /* Store the general purpose registers and ra */ + sd s0, (0 * 8)(a0) + sd s1, (1 * 8)(a0) + sd s2, (2 * 8)(a0) + sd s3, (3 * 8)(a0) + sd s4, (4 * 8)(a0) + sd s5, (5 * 8)(a0) + sd s6, (6 * 8)(a0) + sd s7, (7 * 8)(a0) + sd s8, (8 * 8)(a0) + sd s9, (9 * 8)(a0) + sd s10, (10 * 8)(a0) + sd s11, (11 * 8)(a0) + sd ra, (12 * 8)(a0) + addi a0, a0, (13 * 8) + +#ifndef _STANDALONE +#if 0 + /* RISCVTODO */ + /* Store the vfp registers */ + fsq fs0, (0 * 16)(a0) + fsq fs1, (1 * 16)(a0) + fsq fs2, (2 * 16)(a0) + fsq fs3, (3 * 16)(a0) + fsq fs4, (4 * 16)(a0) + fsq fs5, (5 * 16)(a0) + fsq fs6, (6 * 16)(a0) + fsq fs7, (7 * 16)(a0) + fsq fs8, (8 * 16)(a0) + fsq fs9, (9 * 16)(a0) + fsq fs10, (10 * 16)(a0) + fsq fs11, (11 * 16)(a0) + addi a0, a0, (12 * 16) +#endif +#endif + + /* Return value */ + li a0, 0 + ret + .align 3 +.Lmagic: + .quad _JB_MAGIC__SETJMP +END(_setjmp) + +ENTRY(_longjmp) + /* Check the magic value */ + ld t0, 0(a0) + la t1, .Lmagic + ld t1, 0(t1) + bne t0, t1, botch + + /* Restore the stack pointer */ + ld t0, 8(a0) + mv sp, t0 + addi a0, a0, (2 * 8) + + /* Restore the general purpose registers and ra */ + ld s0, (0 * 8)(a0) + ld s1, (1 * 8)(a0) + ld s2, (2 * 8)(a0) + ld s3, (3 * 8)(a0) + ld s4, (4 * 8)(a0) + ld s5, (5 * 8)(a0) + ld s6, (6 * 8)(a0) + ld s7, (7 * 8)(a0) + ld s8, (8 * 8)(a0) + ld s9, (9 * 8)(a0) + ld s10, (10 * 8)(a0) + ld s11, (11 * 8)(a0) + ld ra, (12 * 8)(a0) + addi a0, a0, (13 * 8) + +#ifndef _STANDALONE +#if 0 + /* RISCVTODO */ + /* Restore the vfp registers */ + flq fs0, (0 * 16)(a0) + flq fs1, (1 * 16)(a0) + flq fs2, (2 * 16)(a0) + flq fs3, (3 * 16)(a0) + flq fs4, (4 * 16)(a0) + flq fs5, (5 * 16)(a0) + flq fs6, (6 * 16)(a0) + flq fs7, (7 * 16)(a0) + flq fs8, (8 * 16)(a0) + flq fs9, (9 * 16)(a0) + flq fs10, (10 * 16)(a0) + flq fs11, (11 * 16)(a0) + addi a0, a0, (12 * 16) +#endif +#endif + + /* Load the return value */ + mv a0, a1 + ret + +botch: +#ifdef _STANDALONE + j botch +#else + call _C_LABEL(longjmperror) + call _C_LABEL(abort) +#endif +END(_longjmp) diff --git a/lib/libc/riscv/gen/fabs.S b/lib/libc/riscv/gen/fabs.S new file mode 100644 index 0000000..4a5d77c --- /dev/null +++ b/lib/libc/riscv/gen/fabs.S @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/gen/fabs.S 294227 2016-01-17 15:21:23Z br $"); + +ENTRY(fabs) + fabs.d fa0, fa0 + ret +END(fabs) diff --git a/lib/libc/riscv/gen/flt_rounds.c b/lib/libc/riscv/gen/flt_rounds.c new file mode 100644 index 0000000..7e4fb50 --- /dev/null +++ b/lib/libc/riscv/gen/flt_rounds.c @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/gen/flt_rounds.c 294227 2016-01-17 15:21:23Z br $"); + +#include + +#include +#include + +int +__flt_rounds(void) +{ +#if 0 + uint64_t fcsr; +#endif + int mode; + +#if 0 + __asm __volatile("csrr %0, fcsr" : "=r" (fcsr)); + mode = (fcsr & _ROUND_MASK); +#endif + + /* RISCVTODO */ + mode = FE_TOWARDZERO; /* softfloat rounding mode */ + + switch (mode) { + case FE_TOWARDZERO: + return (0); + case FE_TONEAREST: + return (1); + case FE_UPWARD: + return (2); + case FE_DOWNWARD: + return (3); + } + + return (-1); +} diff --git a/lib/libc/riscv/gen/infinity.c b/lib/libc/riscv/gen/infinity.c new file mode 100644 index 0000000..709d5eb --- /dev/null +++ b/lib/libc/riscv/gen/infinity.c @@ -0,0 +1,14 @@ +/* + * infinity.c + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/gen/infinity.c 294227 2016-01-17 15:21:23Z br $"); + +#include + +/* bytes for +Infinity on riscv */ +const union __infinity_un __infinity = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; + +/* bytes for NaN */ +const union __nan_un __nan = { { 0, 0, 0xc0, 0xff } }; diff --git a/lib/libc/riscv/gen/makecontext.c b/lib/libc/riscv/gen/makecontext.c new file mode 100644 index 0000000..df7b5e8 --- /dev/null +++ b/lib/libc/riscv/gen/makecontext.c @@ -0,0 +1,91 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/gen/makecontext.c 294227 2016-01-17 15:21:23Z br $"); + +#include + +#include + +#include +#include +#include +#include + +void _ctx_start(void); + +void +ctx_done(ucontext_t *ucp) +{ + + if (ucp->uc_link == NULL) { + exit(0); + } else { + setcontext((const ucontext_t *)ucp->uc_link); + abort(); + } +} + +__weak_reference(__makecontext, makecontext); + +void +__makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...) +{ + struct gpregs *gp; + va_list ap; + int i; + + /* A valid context is required. */ + if (ucp == NULL) + return; + + if ((argc < 0) || (argc > 8)) + return; + + gp = &ucp->uc_mcontext.mc_gpregs; + + va_start(ap, argc); + /* Pass up to eight arguments in a0-7. */ + for (i = 0; i < argc && i < 8; i++) + gp->gp_a[i] = va_arg(ap, uint64_t); + va_end(ap); + + /* Set the stack */ + gp->gp_sp = STACKALIGN(ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + /* Arrange for return via the trampoline code. */ + gp->gp_sepc = (__register_t)_ctx_start; + gp->gp_s[0] = (__register_t)func; + gp->gp_s[1] = (__register_t)ucp; +} diff --git a/lib/libc/riscv/gen/setjmp.S b/lib/libc/riscv/gen/setjmp.S new file mode 100644 index 0000000..b2250ba --- /dev/null +++ b/lib/libc/riscv/gen/setjmp.S @@ -0,0 +1,173 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/gen/setjmp.S 294227 2016-01-17 15:21:23Z br $"); + +#include + +ENTRY(setjmp) + addi sp, sp, -(2 * 8) + sd a0, 0(sp) + sd ra, 8(sp) + + /* Store the signal mask */ + addi a2, a0, (_JB_SIGMASK * 8) /* oset */ + li a1, 0 /* set */ + li a0, 1 /* SIG_BLOCK */ + jal sigprocmask + + ld a0, 0(sp) + ld ra, 8(sp) + addi sp, sp, (2 * 8) + + /* Store the magic value and stack pointer */ + la t0, .Lmagic + ld t0, 0(t0) + sd t0, (0 * 8)(a0) + sd sp, (1 * 8)(a0) + addi a0, a0, (2 * 8) + + /* Store the general purpose registers and ra */ + sd s0, (0 * 8)(a0) + sd s1, (1 * 8)(a0) + sd s2, (2 * 8)(a0) + sd s3, (3 * 8)(a0) + sd s4, (4 * 8)(a0) + sd s5, (5 * 8)(a0) + sd s6, (6 * 8)(a0) + sd s7, (7 * 8)(a0) + sd s8, (8 * 8)(a0) + sd s9, (9 * 8)(a0) + sd s10, (10 * 8)(a0) + sd s11, (11 * 8)(a0) + sd ra, (12 * 8)(a0) + addi a0, a0, (13 * 8) + +#if 0 + /* RISCVTODO */ + /* Store the vfp registers */ + fsq fs0, (0 * 16)(a0) + fsq fs1, (1 * 16)(a0) + fsq fs2, (2 * 16)(a0) + fsq fs3, (3 * 16)(a0) + fsq fs4, (4 * 16)(a0) + fsq fs5, (5 * 16)(a0) + fsq fs6, (6 * 16)(a0) + fsq fs7, (7 * 16)(a0) + fsq fs8, (8 * 16)(a0) + fsq fs9, (9 * 16)(a0) + fsq fs10, (10 * 16)(a0) + fsq fs11, (11 * 16)(a0) + addi a0, a0, (12 * 16) +#endif + + /* Return value */ + li a0, 0 + ret + .align 3 +.Lmagic: + .quad _JB_MAGIC_SETJMP +END(setjmp) + +ENTRY(longjmp) + addi sp, sp, -(4 * 8) + sd a0, (0 * 8)(sp) + sd ra, (1 * 8)(sp) + sd a1, (2 * 8)(sp) + + /* Restore the signal mask */ + li a2, 0 /* oset */ + addi a1, a0, (_JB_SIGMASK * 8) /* set */ + li a0, 3 /* SIG_BLOCK */ + jal sigprocmask + + ld a1, (2 * 8)(sp) + ld ra, (1 * 8)(sp) + ld a0, (0 * 8)(sp) + addi sp, sp, (4 * 8) + + /* Check the magic value */ + ld t0, 0(a0) + la t1, .Lmagic + ld t1, 0(t1) + bne t0, t1, botch + + /* Restore the stack pointer */ + ld t0, 8(a0) + mv sp, t0 + addi a0, a0, (2 * 8) + + /* Restore the general purpose registers and ra */ + ld s0, (0 * 8)(a0) + ld s1, (1 * 8)(a0) + ld s2, (2 * 8)(a0) + ld s3, (3 * 8)(a0) + ld s4, (4 * 8)(a0) + ld s5, (5 * 8)(a0) + ld s6, (6 * 8)(a0) + ld s7, (7 * 8)(a0) + ld s8, (8 * 8)(a0) + ld s9, (9 * 8)(a0) + ld s10, (10 * 8)(a0) + ld s11, (11 * 8)(a0) + ld ra, (12 * 8)(a0) + addi a0, a0, (13 * 8) + +#if 0 + /* RISCVTODO */ + /* Restore the vfp registers */ + flq fs0, (0 * 16)(a0) + flq fs1, (1 * 16)(a0) + flq fs2, (2 * 16)(a0) + flq fs3, (3 * 16)(a0) + flq fs4, (4 * 16)(a0) + flq fs5, (5 * 16)(a0) + flq fs6, (6 * 16)(a0) + flq fs7, (7 * 16)(a0) + flq fs8, (8 * 16)(a0) + flq fs9, (9 * 16)(a0) + flq fs10, (10 * 16)(a0) + flq fs11, (11 * 16)(a0) + addi a0, a0, (12 * 16) +#endif + + /* Load the return value */ + mv a0, a1 + ret + +botch: + call _C_LABEL(longjmperror) + call _C_LABEL(abort) +END(longjmp) diff --git a/lib/libc/riscv/gen/sigsetjmp.S b/lib/libc/riscv/gen/sigsetjmp.S new file mode 100644 index 0000000..8142862 --- /dev/null +++ b/lib/libc/riscv/gen/sigsetjmp.S @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/gen/sigsetjmp.S 294227 2016-01-17 15:21:23Z br $"); + +#include + +ENTRY(sigsetjmp) + beqz a1, _C_LABEL(_setjmp) + j _C_LABEL(setjmp) +END(sigsetjmp) + +ENTRY(siglongjmp) + /* Load the _setjmp magic */ + ld a2, .Lmagic + ld a3, 0(a0) + + /* Check the magic */ + beq a2, a3, _C_LABEL(_longjmp) + j _C_LABEL(longjmp) + + .align 3 +.Lmagic: + .quad _JB_MAGIC__SETJMP +END(siglongjmp) diff --git a/lib/libc/riscv/sys/Makefile.inc b/lib/libc/riscv/sys/Makefile.inc new file mode 100644 index 0000000..1494308 --- /dev/null +++ b/lib/libc/riscv/sys/Makefile.inc @@ -0,0 +1,23 @@ +# $FreeBSD: releng/11.1/lib/libc/riscv/sys/Makefile.inc 302092 2016-06-22 21:11:27Z brooks $ + +SRCS+= trivial-vdso_tc.c + +#MDASM= ptrace.S +MDASM= cerror.S \ + shmat.S \ + sigreturn.S \ + syscall.S \ + vfork.S + +# Don't generate default code for these syscalls: +NOASM= break.o \ + exit.o \ + getlogin.o \ + openbsd_poll.o \ + sbrk.o \ + sstk.o \ + vfork.o \ + yield.o + +PSEUDO= _exit.o \ + _getlogin.o diff --git a/lib/libc/riscv/sys/cerror.S b/lib/libc/riscv/sys/cerror.S new file mode 100644 index 0000000..8dac9e9 --- /dev/null +++ b/lib/libc/riscv/sys/cerror.S @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/sys/cerror.S 294227 2016-01-17 15:21:23Z br $"); + +ENTRY(cerror) + addi sp, sp, -16 + sd a0, 0(sp) + sd ra, 8(sp) + call _C_LABEL(__error) + ld a1, 0(sp) + ld ra, 8(sp) + sw a1, 0(a0) + li a0, -1 + li a1, -1 + addi sp, sp, 16 + ret +END(cerror) diff --git a/lib/libc/riscv/sys/shmat.S b/lib/libc/riscv/sys/shmat.S new file mode 100644 index 0000000..6d4610c --- /dev/null +++ b/lib/libc/riscv/sys/shmat.S @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/sys/shmat.S 294227 2016-01-17 15:21:23Z br $"); + +#include "SYS.h" + +RSYSCALL(shmat) diff --git a/lib/libc/riscv/sys/sigreturn.S b/lib/libc/riscv/sys/sigreturn.S new file mode 100644 index 0000000..fbca3d5 --- /dev/null +++ b/lib/libc/riscv/sys/sigreturn.S @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/sys/sigreturn.S 294227 2016-01-17 15:21:23Z br $"); + +#include "SYS.h" + +RSYSCALL(sigreturn) diff --git a/lib/libc/riscv/sys/syscall.S b/lib/libc/riscv/sys/syscall.S new file mode 100644 index 0000000..10fb4cf --- /dev/null +++ b/lib/libc/riscv/sys/syscall.S @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/sys/syscall.S 294227 2016-01-17 15:21:23Z br $"); + +#include "SYS.h" + +RSYSCALL(syscall) diff --git a/lib/libc/riscv/sys/vfork.S b/lib/libc/riscv/sys/vfork.S new file mode 100644 index 0000000..97cb3d0 --- /dev/null +++ b/lib/libc/riscv/sys/vfork.S @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2015 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/riscv/sys/vfork.S 294227 2016-01-17 15:21:23Z br $"); +#include "SYS.h" + +ENTRY(__sys_vfork) + WEAK_REFERENCE(__sys_vfork, vfork) + WEAK_REFERENCE(__sys_vfork, _vfork) + mv a2, ra + + _SYSCALL(vfork) + bnez t0, cerror + addi a1, a1, -1 + and a0, a0, a1 + mv ra, a2 + + ret +END(__sys_vfork) diff --git a/lib/libc/rpc/Makefile.inc b/lib/libc/rpc/Makefile.inc new file mode 100644 index 0000000..dfc9844 --- /dev/null +++ b/lib/libc/rpc/Makefile.inc @@ -0,0 +1,179 @@ +# @(#)Makefile 5.11 (Berkeley) 9/6/90 +# $FreeBSD: releng/11.1/lib/libc/rpc/Makefile.inc 302255 2016-06-28 19:53:16Z bdrewery $ + +.PATH: ${LIBC_SRCTOP}/rpc ${LIBC_SRCTOP}/. +SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \ + clnt_dg.c clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c \ + clnt_vc.c rpc_dtablesize.c getnetconfig.c getnetpath.c getrpcent.c \ + getrpcport.c mt_misc.c pmap_clnt.c pmap_getmaps.c pmap_getport.c \ + pmap_prot.c pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c \ + rpc_callmsg.c rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c \ + rpcb_st_xdr.c rpcsec_gss_stub.c svc.c svc_auth.c svc_dg.c \ + svc_auth_unix.c svc_generic.c svc_raw.c svc_run.c svc_simple.c \ + svc_vc.c + +# Secure-RPC +SRCS+= auth_time.c auth_des.c authdes_prot.c des_crypt.c des_soft.c \ + crypt_client.c key_call.c key_prot_xdr.c getpublickey.c \ + svc_auth_des.c + +# Resolver stuff +SRCS+= netname.c netnamer.c rpcdname.c + +# Misc Source +SRCS+= rtime.c + +# generated sources +SRCS+= crypt_clnt.c crypt_xdr.c crypt.h + +SYM_MAPS+=${LIBC_SRCTOP}/rpc/Symbol.map + +CFLAGS+= -DBROKEN_DES -DPORTMAP -DDES_BUILTIN +CFLAGS+= -I${LIBC_SRCTOP}/rpc + +CLEANFILES+= crypt_clnt.c crypt_xdr.c crypt.h + +RPCDIR= ${SRCTOP}/include/rpcsvc +RPCGEN= RPCGEN_CPP=${CPP:Q} rpcgen -C + +crypt_clnt.c: ${RPCDIR}/crypt.x crypt.h + ${RPCGEN} -l -o ${.TARGET} ${RPCDIR}/crypt.x + +crypt_xdr.c: ${RPCDIR}/crypt.x crypt.h + ${RPCGEN} -c -o ${.TARGET} ${RPCDIR}/crypt.x + +crypt.h: ${RPCDIR}/crypt.x + ${RPCGEN} -h -o ${.TARGET} ${RPCDIR}/crypt.x +MAN+= bindresvport.3 des_crypt.3 getnetconfig.3 getnetpath.3 getrpcent.3 \ + getrpcport.3 rpc.3 rpc_soc.3 rpc_clnt_auth.3 rpc_clnt_calls.3 \ + rpc_clnt_create.3 rpc_svc_calls.3 rpc_svc_create.3 rpc_svc_err.3 \ + rpc_svc_reg.3 rpc_xdr.3 rpcbind.3 publickey.3 rpc_secure.3 \ + rtime.3 +MAN+= publickey.5 rpc.5 netconfig.5 +MLINKS+= bindresvport.3 bindresvport_sa.3 \ + des_crypt.3 ecb_crypt.3 \ + des_crypt.3 cbc_crypt.3 \ + des_crypt.3 des_setparity.3 \ + getnetconfig.3 setnetconfig.3 \ + getnetconfig.3 getnetconfigent.3 \ + getnetconfig.3 freenetconfigent.3 \ + getnetconfig.3 endnetconfig.3 \ + getnetconfig.3 nc_perror.3 \ + getnetconfig.3 nc_sperror.3 \ + getnetpath.3 setnetpath.3 \ + getnetpath.3 endnetpath.3 \ + getrpcent.3 getrpcbyname.3 \ + getrpcent.3 getrpcbynumber.3 \ + getrpcent.3 endrpcent.3 \ + getrpcent.3 setrpcent.3 \ + publickey.3 getpublickey.3 \ + publickey.3 getsecretkey.3 \ + rpc_clnt_auth.3 auth_destroy.3 \ + rpc_clnt_auth.3 authnone_create.3 \ + rpc_clnt_auth.3 authsys_create.3 \ + rpc_clnt_auth.3 authsys_create_default.3 \ + rpc_clnt_calls.3 clnt_call.3 \ + rpc_clnt_calls.3 clnt_perrno.3 \ + rpc_clnt_calls.3 clnt_perror.3 \ + rpc_clnt_calls.3 clnt_sperrno.3 \ + rpc_clnt_calls.3 clnt_sperror.3 \ + rpc_clnt_calls.3 rpc_call.3 \ + rpc_clnt_calls.3 rpc_broadcast.3 \ + rpc_clnt_calls.3 rpc_broadcast_exp.3 \ + rpc_clnt_calls.3 clnt_freeres.3 \ + rpc_clnt_calls.3 clnt_geterr.3 \ + rpc_clnt_create.3 clnt_control.3 \ + rpc_clnt_create.3 clnt_create.3 \ + rpc_clnt_create.3 clnt_create_timed.3 \ + rpc_clnt_create.3 clnt_create_vers.3 \ + rpc_clnt_create.3 clnt_create_vers_timed.3 \ + rpc_clnt_create.3 clnt_destroy.3 \ + rpc_clnt_create.3 clnt_pcreateerror.3 \ + rpc_clnt_create.3 clnt_spcreateerror.3 \ + rpc_clnt_create.3 clnt_dg_create.3 \ + rpc_clnt_create.3 clnt_raw_create.3 \ + rpc_clnt_create.3 clnt_tli_create.3 \ + rpc_clnt_create.3 clnt_tp_create.3 \ + rpc_clnt_create.3 clnt_tp_create_timed.3 \ + rpc_clnt_create.3 clnt_vc_create.3 \ + rpc_secure.3 authdes_create.3 \ + rpc_secure.3 authdes_getucred.3 \ + rpc_secure.3 getnetname.3 \ + rpc_secure.3 host2netname.3 \ + rpc_secure.3 key_decryptsession.3 \ + rpc_secure.3 key_encryptsession.3 \ + rpc_secure.3 key_gendes.3 \ + rpc_secure.3 key_setsecret.3 \ + rpc_secure.3 netname2host.3 \ + rpc_secure.3 netname2user.3 \ + rpc_secure.3 user2netname.3 \ + rpc_svc_calls.3 svc_dg_enablecache.3 \ + rpc_svc_calls.3 svc_exit.3 \ + rpc_svc_calls.3 svc_freeargs.3 \ + rpc_svc_calls.3 svc_getargs.3 \ + rpc_svc_calls.3 svc_getreq_common.3 \ + rpc_svc_calls.3 svc_getreq_poll.3 \ + rpc_svc_calls.3 svc_getreqset.3 \ + rpc_svc_calls.3 svc_getrpccaller.3 \ + rpc_svc_calls.3 __svc_getcallercreds.3 \ + rpc_svc_calls.3 svc_pollset.3 \ + rpc_svc_calls.3 svc_run.3 \ + rpc_svc_calls.3 svc_sendreply.3 \ + rpc_svc_create.3 svc_control.3 \ + rpc_svc_create.3 svc_create.3 \ + rpc_svc_create.3 svc_dg_create.3 \ + rpc_svc_create.3 svc_destroy.3 \ + rpc_svc_create.3 svc_fd_create.3 \ + rpc_svc_create.3 svc_raw_create.3 \ + rpc_svc_create.3 svc_tli_create.3 \ + rpc_svc_create.3 svc_tp_create.3 \ + rpc_svc_create.3 svc_vc_create.3 \ + rpc_svc_err.3 svcerr_auth.3 \ + rpc_svc_err.3 svcerr_decode.3 \ + rpc_svc_err.3 svcerr_noproc.3 \ + rpc_svc_err.3 svcerr_noprog.3 \ + rpc_svc_err.3 svcerr_progvers.3 \ + rpc_svc_err.3 svcerr_systemerr.3 \ + rpc_svc_err.3 svcerr_weakauth.3 \ + rpc_svc_reg.3 rpc_reg.3 \ + rpc_svc_reg.3 svc_reg.3 \ + rpc_svc_reg.3 svc_unreg.3 \ + rpc_svc_reg.3 svc_auth_reg.3 \ + rpc_svc_reg.3 xprt_register.3 \ + rpc_svc_reg.3 xprt_unregister.3 \ + rpcbind.3 rpcb_getmaps.3 \ + rpcbind.3 rpcb_getaddr.3 \ + rpcbind.3 rpcb_gettime.3 \ + rpcbind.3 rpcb_rmtcall.3 \ + rpcbind.3 rpcb_set.3 \ + rpcbind.3 rpcb_unset.3 \ + rpc_soc.3 authunix_create.3 \ + rpc_soc.3 authunix_create_default.3 \ + rpc_soc.3 callrpc.3 \ + rpc_soc.3 clnt_broadcast.3 \ + rpc_soc.3 clntraw_create.3 \ + rpc_soc.3 clnttcp_create.3 \ + rpc_soc.3 clntunix_create.3 \ + rpc_soc.3 clntudp_bufcreate.3 \ + rpc_soc.3 clntudp_create.3 \ + rpc_soc.3 get_myaddress.3 \ + rpc_soc.3 pmap_getmaps.3 \ + rpc_soc.3 pmap_getport.3 \ + rpc_soc.3 pmap_rmtcall.3 \ + rpc_soc.3 pmap_set.3 \ + rpc_soc.3 pmap_unset.3 \ + rpc_soc.3 registerrpc.3 \ + rpc_soc.3 rpc_createerr.3 \ + rpc_soc.3 svc_fds.3 \ + rpc_soc.3 svc_fdset.3 \ + rpc_soc.3 svc_getcaller.3 \ + rpc_soc.3 svc_register.3 \ + rpc_soc.3 svc_unregister.3 \ + rpc_soc.3 svcfd_create.3 \ + rpc_soc.3 svcunixfd_create.3 \ + rpc_soc.3 svcraw_create.3 \ + rpc_soc.3 svctcp_create.3 \ + rpc_soc.3 svcudp_bufcreate.3 \ + rpc_soc.3 svcunix_create.3 \ + rpc_soc.3 xdr_pmap.3 \ + rpc_soc.3 xdr_pmaplist.3 diff --git a/lib/libc/rpc/Symbol.map b/lib/libc/rpc/Symbol.map new file mode 100644 index 0000000..ed2643a --- /dev/null +++ b/lib/libc/rpc/Symbol.map @@ -0,0 +1,247 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/rpc/Symbol.map 204950 2010-03-10 13:23:25Z jhb $ + */ + +FBSD_1.0 { + /* From crypt_clnt.c (generated by rpcgen - include/rpcsvc/crypt.x) */ + des_crypt_1; + + /* From crypt_xdr.c (generated by rpcgen - include/rpcsvc/crypt.x) */ + xdr_des_dir; + xdr_des_mode; + xdr_desargs; + xdr_desresp; + + /* From yp_xdr.c (generated by rpcgen - include/rpcsvc/yp.x) */ + xdr_domainname; + xdr_keydat; + xdr_mapname; + xdr_peername; + xdr_valdat; + xdr_ypbind_binding; + xdr_ypbind_resp; + xdr_ypbind_resptype; + xdr_ypbind_setdom; + xdr_ypmap_parms; + xdr_ypmaplist; + xdr_yppush_status; + xdr_yppushresp_xfr; + xdr_ypreq_key; + xdr_ypreq_nokey; + xdr_ypreq_xfr; + xdr_ypreqtype; + xdr_yprequest; + xdr_ypresp_all; + xdr_ypresp_key_val; + xdr_ypresp_maplist; + xdr_ypresp_master; + xdr_ypresp_order; + xdr_ypresp_val; + xdr_ypresp_xfr; + xdr_ypresponse; + xdr_ypresptype; + xdr_ypstat; + xdr_ypxfrstat; + + authdes_seccreate; + authdes_pk_seccreate; + authnone_create; + authunix_create; + authunix_create_default; + xdr_authdes_cred; + xdr_authdes_verf; + xdr_authunix_parms; + bindresvport; + bindresvport_sa; + rpc_broadcast_exp; + rpc_broadcast; + clnt_dg_create; + clnt_create_vers; + clnt_create_vers_timed; + clnt_create; + clnt_create_timed; + clnt_tp_create; + clnt_tp_create_timed; + clnt_tli_create; + clnt_sperror; + clnt_perror; + clnt_sperrno; + clnt_perrno; + clnt_spcreateerror; + clnt_pcreateerror; + clnt_raw_create; + rpc_call; + clnt_vc_create; + cbc_crypt; + ecb_crypt; + des_setparity; + setnetconfig; + getnetconfig; + endnetconfig; + getnetconfigent; + freenetconfigent; + nc_sperror; + nc_perror; + setnetpath; + getnetpath; + endnetpath; + getpublicandprivatekey; + getpublickey; + getrpcbynumber; + getrpcbyname; + setrpcent; + endrpcent; + getrpcent; + getrpcport; + key_setsecret; + key_secretkey_is_set; + key_encryptsession_pk; + key_decryptsession_pk; + key_encryptsession; + key_decryptsession; + key_gendes; + key_setnet; + key_get_conv; + xdr_keystatus; + xdr_keybuf; + xdr_netnamestr; + xdr_cryptkeyarg; + xdr_cryptkeyarg2; + xdr_cryptkeyres; + xdr_unixcred; + xdr_getcredres; + xdr_key_netstarg; + xdr_key_netstres; + rpc_createerr; + __rpc_createerr; + getnetname; + user2netname; + host2netname; + netname2user; + netname2host; + pmap_set; + pmap_unset; + pmap_getmaps; + pmap_getport; + xdr_pmap; + xdr_pmaplist; + xdr_pmaplist_ptr; + pmap_rmtcall; + xdr_rmtcall_args; + xdr_rmtcallres; + xdr_callmsg; + _null_auth; + svc_fdset; + svc_maxfd; + _rpc_dtablesize; + __rpc_get_t_size; + __rpc_getconfip; + __rpc_setconf; + __rpc_getconf; + __rpc_endconf; + rpc_nullproc; + __rpc_fd2sockinfo; + __rpc_nconf2sockinfo; + __rpc_nconf2fd; + taddr2uaddr; + uaddr2taddr; + xdr_opaque_auth; + xdr_des_block; + xdr_accepted_reply; + xdr_rejected_reply; + xdr_replymsg; + xdr_callhdr; + _seterr_reply; + clntudp_bufcreate; + clntudp_create; + clnttcp_create; + clntraw_create; + svctcp_create; + svcudp_bufcreate; + svcfd_create; + svcudp_create; + svcraw_create; + get_myaddress; + callrpc; + registerrpc; + clnt_broadcast; + authdes_create; + clntunix_create; + svcunix_create; + svcunixfd_create; + rpcb_set; + rpcb_unset; + rpcb_getaddr; + rpcb_getmaps; + rpcb_rmtcall; + rpcb_gettime; + rpcb_taddr2uaddr; + rpcb_uaddr2taddr; + xdr_rpcb; + xdr_rpcblist_ptr; + xdr_rpcblist; + xdr_rpcb_entry; + xdr_rpcb_entry_list_ptr; + xdr_rpcb_rmtcallargs; + xdr_rpcb_rmtcallres; + xdr_netbuf; + xdr_rpcbs_addrlist; + xdr_rpcbs_rmtcalllist; + xdr_rpcbs_proc; + xdr_rpcbs_addrlist_ptr; + xdr_rpcbs_rmtcalllist_ptr; + xdr_rpcb_stat; + xdr_rpcb_stat_byvers; + rtime; + xprt_register; + xprt_unregister; + svc_reg; + svc_unreg; + svc_register; + svc_unregister; + svc_sendreply; + svcerr_noproc; + svcerr_decode; + svcerr_systemerr; + svcerr_auth; + svcerr_weakauth; + svcerr_noprog; + svcerr_progvers; + svc_getreq; + svc_getreqset; + svc_getreq_common; + svc_getreq_poll; + rpc_control; + _authenticate; + _svcauth_null; + svc_auth_reg; + _svcauth_des; + authdes_getucred; + _svcauth_unix; + _svcauth_short; + svc_dg_create; + svc_dg_enablecache; + svc_create; + svc_tp_create; + svc_tli_create; + __rpc_rawcombuf; + svc_raw_create; + svc_run; + svc_exit; + rpc_reg; + svc_vc_create; + svc_fd_create; + __rpc_get_local_uid; +}; + +FBSDprivate_1.0 { + __des_crypt_LOCAL; + __key_encryptsession_pk_LOCAL; + __key_decryptsession_pk_LOCAL; + __key_gendes_LOCAL; + __svc_clean_idle; + __rpc_gss_unwrap; + __rpc_gss_unwrap_stub; + __rpc_gss_wrap; + __rpc_gss_wrap_stub; +}; diff --git a/lib/libc/rpc/bindresvport.3 b/lib/libc/rpc/bindresvport.3 new file mode 100644 index 0000000..afc79ae --- /dev/null +++ b/lib/libc/rpc/bindresvport.3 @@ -0,0 +1,103 @@ +.\" @(#)bindresvport.3n 2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI +.\" $NetBSD: bindresvport.3,v 1.8 2000/07/05 15:45:33 msaitoh Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/bindresvport.3 108037 2002-12-18 12:45:11Z ru $ +.\" +.Dd November 22, 1987 +.Dt BINDRESVPORT 3 +.Os +.Sh NAME +.Nm bindresvport , +.Nm bindresvport_sa +.Nd bind a socket to a privileged IP port +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In rpc/rpc.h +.Ft int +.Fn bindresvport "int sd" "struct sockaddr_in *sin" +.Ft int +.Fn bindresvport_sa "int sd" "struct sockaddr *sa" +.Sh DESCRIPTION +The +.Fn bindresvport +and +.Fn bindresvport_sa +functions +are used to bind a socket descriptor to a privileged +.Tn IP +port, that is, a +port number in the range 0-1023. +.Pp +If +.Fa sin +is a pointer to a +.Ft "struct sockaddr_in" +then the appropriate fields in the structure should be defined. +Note that +.Fa sin->sin_family +must be initialized to the address family of the socket, passed by +.Fa sd . +If +.Fa sin->sin_port +is +.Sq 0 +then an anonymous port (in the range 600-1023) will be +chosen, and if +.Xr bind 2 +is successful, the +.Fa sin->sin_port +will be updated to contain the allocated port. +.Pp +If +.Fa sin +is the +.Dv NULL +pointer, +an anonymous port will be allocated (as above). +However, there is no way for +.Fn bindresvport +to return the allocated port in this case. +.Pp +Only root can bind to a privileged port; this call will fail for any +other users. +.Pp +Function prototype of +.Fn bindresvport +is biased to +.Dv AF_INET +socket. +The +.Fn bindresvport_sa +function +acts exactly the same, with more neutral function prototype. +Note that both functions behave exactly the same, and +both support +.Dv AF_INET6 +sockets as well as +.Dv AF_INET +sockets. +.Sh RETURN VALUES +.Rv -std bindresvport +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er EPFNOSUPPORT +If second argument was supplied, +and address family did not match between arguments. +.El +.Pp +The +.Fn bindresvport +function +may also fail and set +.Va errno +for any of the errors specified for the calls +.Xr bind 2 , +.Xr getsockopt 2 , +or +.Xr setsockopt 2 . +.Sh SEE ALSO +.Xr bind 2 , +.Xr getsockopt 2 , +.Xr setsockopt 2 , +.Xr ip 4 diff --git a/lib/libc/rpc/des_crypt.3 b/lib/libc/rpc/des_crypt.3 new file mode 100644 index 0000000..b8522f5 --- /dev/null +++ b/lib/libc/rpc/des_crypt.3 @@ -0,0 +1,130 @@ +.\" @(#)des_crypt.3 2.1 88/08/11 4.0 RPCSRC; from 1.16 88/03/02 SMI; +.\" $FreeBSD: releng/11.1/lib/libc/rpc/des_crypt.3 108087 2002-12-19 09:40:28Z ru $ +.\" +.Dd October 6, 1987 +.Dt DES_CRYPT 3 +.Os +.Sh NAME +.Nm des_crypt , ecb_crypt , cbc_crypt , des_setparity +.Nd "fast DES encryption" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/des_crypt.h +.Ft int +.Fn ecb_crypt "char *key" "char *data" "unsigned datalen" "unsigned mode" +.Ft int +.Fn cbc_crypt "char *key" "char *data" "unsigned datalen" "unsigned mode" "char *ivec" +.Ft void +.Fn des_setparity "char *key" +.Sh DESCRIPTION +The +.Fn ecb_crypt +and +.Fn cbc_crypt +functions +implement the +.Tn NBS +.Tn DES +(Data Encryption Standard). +These routines are faster and more general purpose than +.Xr crypt 3 . +They also are able to utilize +.Tn DES +hardware if it is available. +The +.Fn ecb_crypt +function +encrypts in +.Tn ECB +(Electronic Code Book) +mode, which encrypts blocks of data independently. +The +.Fn cbc_crypt +function +encrypts in +.Tn CBC +(Cipher Block Chaining) +mode, which chains together +successive blocks. +.Tn CBC +mode protects against insertions, deletions and +substitutions of blocks. +Also, regularities in the clear text will +not appear in the cipher text. +.Pp +Here is how to use these routines. +The first argument, +.Fa key , +is the 8-byte encryption key with parity. +To set the key's parity, which for +.Tn DES +is in the low bit of each byte, use +.Fn des_setparity . +The second argument, +.Fa data , +contains the data to be encrypted or decrypted. +The +third argument, +.Fa datalen , +is the length in bytes of +.Fa data , +which must be a multiple of 8. +The fourth argument, +.Fa mode , +is formed by +.Em OR Ns 'ing +together some things. +For the encryption direction +.Em OR +in either +.Dv DES_ENCRYPT +or +.Dv DES_DECRYPT . +For software versus hardware +encryption, +.Em OR +in either +.Dv DES_HW +or +.Dv DES_SW . +If +.Dv DES_HW +is specified, and there is no hardware, then the encryption is performed +in software and the routine returns +.Er DESERR_NOHWDEVICE . +For +.Fn cbc_crypt , +the +.Fa ivec +argument +is the 8-byte initialization +vector for the chaining. +It is updated to the next initialization +vector upon return. +.Sh ERRORS +.Bl -tag -width [DESERR_NOHWDEVICE] -compact +.It Bq Er DESERR_NONE +No error. +.It Bq Er DESERR_NOHWDEVICE +Encryption succeeded, but done in software instead of the requested hardware. +.It Bq Er DESERR_HWERR +An error occurred in the hardware or driver. +.It Bq Er DESERR_BADPARAM +Bad argument to routine. +.El +.Pp +Given a result status +.Va stat , +the macro +.Fn DES_FAILED stat +is false only for the first two statuses. +.Sh SEE ALSO +.\" .Xr des 1 , +.Xr crypt 3 +.Sh RESTRICTIONS +These routines are not available in RPCSRC 4.0. +This information is provided to describe the +.Tn DES +interface expected by +Secure RPC. diff --git a/lib/libc/rpc/getnetconfig.3 b/lib/libc/rpc/getnetconfig.3 new file mode 100644 index 0000000..a88b367 --- /dev/null +++ b/lib/libc/rpc/getnetconfig.3 @@ -0,0 +1,222 @@ +.\" @(#)getnetconfig.3n 1.28 93/06/02 SMI; from SVr4 +.\" $NetBSD: getnetconfig.3,v 1.1 2000/06/02 23:11:11 fvdl Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/getnetconfig.3 108087 2002-12-19 09:40:28Z ru $ +.\" Copyright 1989 AT&T +.Dd April 22, 2000 +.Dt GETNETCONFIG 3 +.Os +.Sh NAME +.Nm getnetconfig , +.Nm setnetconfig , +.Nm endnetconfig , +.Nm getnetconfigent , +.Nm freenetconfigent , +.Nm nc_perror , +.Nm nc_sperror +.Nd get network configuration database entry +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In netconfig.h +.Ft "struct netconfig *" +.Fn getnetconfig "void *handlep" +.Ft "void *" +.Fn setnetconfig "void" +.Ft int +.Fn endnetconfig "void *handlep" +.Ft "struct netconfig *" +.Fn getnetconfigent "const char *netid" +.Ft void +.Fn freenetconfigent "struct netconfig *netconfigp" +.Ft void +.Fn nc_perror "const char *msg" +.Ft "char *" +.Fn nc_sperror "void" +.Sh DESCRIPTION +The library routines described on this page +provide the application access to +the system network configuration database, +.Pa /etc/netconfig . +The +.Fn getnetconfig +function +returns a pointer to the +current entry in the +netconfig +database, formatted as a +.Ft "struct netconfig" . +Successive calls will return successive netconfig +entries in the netconfig database. +The +.Fn getnetconfig +function +can be used to search the entire netconfig +file. +The +.Fn getnetconfig +function +returns +.Dv NULL +at the end of the file. +The +.Fa handlep +argument +is the handle obtained through +.Fn setnetconfig . +.Pp +A call to +.Fn setnetconfig +has the effect of +.Dq binding +to or +.Dq rewinding +the netconfig database. +The +.Fn setnetconfig +function +must be called before the first call to +.Fn getnetconfig +and may be called at any other time. +The +.Fn setnetconfig +function +need not be called before a call to +.Fn getnetconfigent . +The +.Fn setnetconfig +function +returns a unique handle to be used by +.Fn getnetconfig . +.Pp +The +.Fn endnetconfig +function +should be called when processing is complete to release resources for reuse. +The +.Fa handlep +argument +is the handle obtained through +.Fn setnetconfig . +Programmers should be aware, however, that the last call to +.Fn endnetconfig +frees all memory allocated by +.Fn getnetconfig +for the +.Ft "struct netconfig" +data structure. +The +.Fn endnetconfig +function +may not be called before +.Fn setnetconfig . +.Pp +The +.Fn getnetconfigent +function +returns a pointer +to the netconfig structure corresponding +to +.Fa netid . +It returns +.Dv NULL +if +.Fa netid +is invalid +(that is, does not name an entry in the netconfig database). +.Pp +The +.Fn freenetconfigent +function +frees the netconfig structure pointed to by +.Fa netconfigp +(previously returned by +.Fn getnetconfigent ) . +.Pp +The +.Fn nc_perror +function +prints a message to the standard error indicating why any of the +above routines failed. +The message is prepended with the string +.Fa msg +and a colon. +A newline character is appended at the end of the message. +.Pp +The +.Fn nc_sperror +function +is similar to +.Fn nc_perror +but instead of sending the message +to the standard error, will return a pointer to a string that +contains the error message. +.Pp +The +.Fn nc_perror +and +.Fn nc_sperror +functions +can also be used with the +.Ev NETPATH +access routines defined in +.Xr getnetpath 3 . +.Sh RETURN VALUES +The +.Fn setnetconfig +function +returns a unique handle to be used by +.Fn getnetconfig . +In the case of an error, +.Fn setnetconfig +returns +.Dv NULL +and +.Fn nc_perror +or +.Fn nc_sperror +can be used to print the reason for failure. +.Pp +The +.Fn getnetconfig +function +returns a pointer to the current entry in the netconfig +database, formatted as a +.Ft "struct netconfig" . +The +.Fn getnetconfig +function +returns +.Dv NULL +at the end of the file, or upon failure. +.Pp +The +.Fn endnetconfig +function +returns 0 on success and \-1 on failure +(for example, if +.Fn setnetconfig +was not called previously). +.Pp +On success, +.Fn getnetconfigent +returns a pointer to the +.Ft "struct netconfig" +structure corresponding to +.Fa netid ; +otherwise it returns +.Dv NULL . +.Pp +The +.Fn nc_sperror +function +returns a pointer to a buffer which contains the error message string. +This buffer is overwritten on each call. +In multithreaded applications, this buffer is +implemented as thread-specific data. +.Sh FILES +.Bl -tag -width /etc/netconfig -compact +.It Pa /etc/netconfig +.El +.Sh SEE ALSO +.Xr getnetpath 3 , +.Xr netconfig 5 diff --git a/lib/libc/rpc/getnetpath.3 b/lib/libc/rpc/getnetpath.3 new file mode 100644 index 0000000..434103c --- /dev/null +++ b/lib/libc/rpc/getnetpath.3 @@ -0,0 +1,170 @@ +.\" @(#)getnetpath.3n 1.26 93/05/07 SMI; from SVr4 +.\" $NetBSD: getnetpath.3,v 1.1 2000/06/02 23:11:11 fvdl Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/getnetpath.3 108037 2002-12-18 12:45:11Z ru $ +.\" Copyright 1989 AT&T +.Dd April 22, 2000 +.Dt GETNETPATH 3 +.Os +.Sh NAME +.Nm getnetpath , +.Nm setnetpath , +.Nm endnetpath +.Nd get +.Pa /etc/netconfig +entry corresponding to +.Ev NETPATH +component +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In netconfig.h +.Ft "struct netconfig *" +.Fn getnetpath "void *handlep" +.Ft "void *" +.Fn setnetpath "void" +.Ft int +.Fn endnetpath "void *handlep" +.Sh DESCRIPTION +The routines described in this page provide the application access to the system +network configuration database, +.Pa /etc/netconfig , +as it is +.Dq filtered +by the +.Ev NETPATH +environment variable (see +.Xr environ 7 ) . +See +.Xr getnetconfig 3 +for other routines that also access the +network configuration database directly. +The +.Ev NETPATH +variable is a list of colon-separated network identifiers. +.Pp +The +.Fn getnetpath +function +returns a pointer to the +netconfig database entry corresponding to the first valid +.Ev NETPATH +component. +The netconfig entry is formatted as a +.Ft "struct netconfig" . +On each subsequent call, +.Fn getnetpath +returns a pointer to the netconfig entry that corresponds to the next +valid +.Ev NETPATH +component. +The +.Fn getnetpath +function +can thus be used to search the netconfig database for all networks +included in the +.Ev NETPATH +variable. +When +.Ev NETPATH +has been exhausted, +.Fn getnetpath +returns +.Dv NULL . +.Pp +A call to +.Fn setnetpath +.Dq binds +to or +.Dq rewinds +.Ev NETPATH . +The +.Fn setnetpath +function +must be called before the first call to +.Fn getnetpath +and may be called at any other time. +It returns a handle that is used by +.Fn getnetpath . +.Pp +The +.Fn getnetpath +function +silently ignores invalid +.Ev NETPATH +components. +A +.Ev NETPATH +component is invalid if there is no corresponding +entry in the netconfig database. +.Pp +If the +.Ev NETPATH +variable is unset, +.Fn getnetpath +behaves as if +.Ev NETPATH +were set to the sequence of +.Dq default +or +.Dq visible +networks in the netconfig database, in the +order in which they are listed. +.\"This proviso holds also for this +.\"whole manpage. +.Pp +The +.Fn endnetpath +function +may be called to +.Dq unbind +from +.Ev NETPATH +when processing is complete, releasing resources for reuse. +Programmers should be aware, however, that +.Fn endnetpath +frees all memory allocated by +.Fn getnetpath +for the struct netconfig data structure. +.Sh RETURN VALUES +The +.Fn setnetpath +function +returns a handle that is used by +.Fn getnetpath . +In case of an error, +.Fn setnetpath +returns +.Dv NULL . +.Pp +The +.Fn endnetpath +function +returns 0 on success and \-1 on failure +(for example, if +.Fn setnetpath +was not called previously). +The +.Fn nc_perror +or +.Fn nc_sperror +function +can be used to print out the reason for failure. +See +.Xr getnetconfig 3 . +.Pp +When first called, +.Fn getnetpath +returns a pointer to the netconfig database entry corresponding to the first +valid +.Ev NETPATH +component. +When +.Ev NETPATH +has been exhausted, +.Fn getnetpath +returns +.Dv NULL . +.Sh SEE ALSO +.Xr getnetconfig 3 , +.Xr netconfig 5 , +.Xr environ 7 diff --git a/lib/libc/rpc/getrpcent.3 b/lib/libc/rpc/getrpcent.3 new file mode 100644 index 0000000..80107dd --- /dev/null +++ b/lib/libc/rpc/getrpcent.3 @@ -0,0 +1,109 @@ +.\" @(#)getrpcent.3n 2.2 88/08/02 4.0 RPCSRC; from 1.11 88/03/14 SMI +.\" $NetBSD: getrpcent.3,v 1.6 1998/02/05 18:49:06 perry Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/getrpcent.3 296133 2016-02-26 23:25:21Z pfg $ +.\" +.Dd February 26, 2016 +.Dt GETRPCENT 3 +.Os +.Sh NAME +.Nm getrpcent , +.Nm getrpcbyname , +.Nm getrpcbynumber , +.Nm endrpcent , +.Nm setrpcent +.Nd get RPC entry +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/rpc.h +.Ft struct rpcent * +.Fn getrpcent void +.Ft struct rpcent * +.Fn getrpcbyname "const char *name" +.Ft struct rpcent * +.Fn getrpcbynumber "int number" +.Ft void +.Fn setrpcent "int stayopen" +.Ft void +.Fn endrpcent void +.Sh DESCRIPTION +The +.Fn getrpcent , +.Fn getrpcbyname , +and +.Fn getrpcbynumber +functions +each return a pointer to an object with the +following structure +containing the broken-out +fields of a line in the rpc program number data base, +.Pa /etc/rpc : +.Bd -literal +struct rpcent { + char *r_name; /* name of server for this rpc program */ + char **r_aliases; /* alias list */ + long r_number; /* rpc program number */ +}; +.Ed +.Pp +The members of this structure are: +.Bl -tag -width r_aliases -offset indent +.It Va r_name +The name of the server for this rpc program. +.It Va r_aliases +A zero terminated list of alternate names for the rpc program. +.It Va r_number +The rpc program number for this service. +.El +.Pp +The +.Fn getrpcent +function +reads the next line of the file, opening the file if necessary. +.Pp +The +.Fn setrpcent +function +opens and rewinds the file. +If the +.Fa stayopen +flag is non-zero, +the net data base will not be closed after each call to +.Fn getrpcent +(either directly, or indirectly through one of +the other +.Dq getrpc +calls). +.Pp +The +.Fn endrpcent +function +closes the file. +.Pp +The +.Fn getrpcbyname +and +.Fn getrpcbynumber +functions +sequentially search from the beginning +of the file until a matching rpc program name or +program number is found, or until end-of-file is encountered. +.Sh FILES +.Bl -tag -width /etc/rpc -compact +.It Pa /etc/rpc +.El +.Sh DIAGNOSTICS +A +.Dv NULL +pointer is returned on +.Dv EOF +or error. +.Sh SEE ALSO +.Xr rpc 5 , +.Xr rpcinfo 8 , +.Xr ypserv 8 +.Sh BUGS +All information +is contained in a static area +so it must be copied if it is +to be saved. diff --git a/lib/libc/rpc/getrpcport.3 b/lib/libc/rpc/getrpcport.3 new file mode 100644 index 0000000..a1666ae --- /dev/null +++ b/lib/libc/rpc/getrpcport.3 @@ -0,0 +1,36 @@ +.\" @(#)getrpcport.3r 2.2 88/08/02 4.0 RPCSRC; from 1.12 88/02/26 SMI +.\" $FreeBSD: releng/11.1/lib/libc/rpc/getrpcport.3 131504 2004-07-02 23:52:20Z ru $ +.\" +.Dd October 6, 1987 +.Dt GETRPCPORT 3 +.Os +.Sh NAME +.Nm getrpcport +.Nd get RPC port number +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.Ft int +.Fn getrpcport "char *host" "int prognum" "int versnum" "int proto" +.Sh DESCRIPTION +The +.Fn getrpcport +function +returns the port number for version +.Fa versnum +of the RPC program +.Fa prognum +running on +.Fa host +and using protocol +.Fa proto . +It returns 0 if it cannot contact the portmapper, or if +.Fa prognum +is not registered. +If +.Fa prognum +is registered but not with version +.Fa versnum , +it will still return a port number (for some version of the program) +indicating that the program is indeed registered. +The version mismatch will be detected upon the first call to the service. diff --git a/lib/libc/rpc/mt_misc.h b/lib/libc/rpc/mt_misc.h new file mode 100644 index 0000000..978371b --- /dev/null +++ b/lib/libc/rpc/mt_misc.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2006 The FreeBSD Project. 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. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/rpc/mt_misc.h 204950 2010-03-10 13:23:25Z jhb $ + */ +#ifndef _MT_MISC_H +#define _MT_MISC_H + +/* Take these locks out of the application namespace. */ +#define svc_lock __svc_lock +#define svc_fd_lock __svc_fd_lock +#define rpcbaddr_cache_lock __rpcbaddr_cache_lock +#define authdes_ops_lock __authdes_ops_lock +#define authnone_lock __authnone_lock +#define authsvc_lock __authsvc_lock +#define clnt_fd_lock __clnt_fd_lock +#define clntraw_lock __clntraw_lock +#define dupreq_lock __dupreq_lock +#define loopnconf_lock __loopnconf_lock +#define ops_lock __ops_lock +#define proglst_lock __proglst_lock +#define rpcsoc_lock __rpcsoc_lock +#define svcraw_lock __svcraw_lock +#define xprtlist_lock __xprtlist_lock + +extern pthread_rwlock_t svc_lock; +extern pthread_rwlock_t svc_fd_lock; +extern pthread_rwlock_t rpcbaddr_cache_lock; +extern pthread_mutex_t authdes_ops_lock; +extern pthread_mutex_t svcauthdesstats_lock; +extern pthread_mutex_t authnone_lock; +extern pthread_mutex_t authsvc_lock; +extern pthread_mutex_t clnt_fd_lock; +extern pthread_mutex_t clntraw_lock; +extern pthread_mutex_t dupreq_lock; +extern pthread_mutex_t loopnconf_lock; +extern pthread_mutex_t ops_lock; +extern pthread_mutex_t proglst_lock; +extern pthread_mutex_t rpcsoc_lock; +extern pthread_mutex_t svcraw_lock; +extern pthread_mutex_t tsd_lock; +extern pthread_mutex_t xprtlist_lock; + +#endif diff --git a/lib/libc/rpc/netconfig.5 b/lib/libc/rpc/netconfig.5 new file mode 100644 index 0000000..36cebaf --- /dev/null +++ b/lib/libc/rpc/netconfig.5 @@ -0,0 +1,132 @@ +.\" $NetBSD: netconfig.5,v 1.2 2000/11/08 13:18:28 lukem Exp $ +.\" $NetBSD: netconfig.5,v 1.2 2000/11/08 13:18:28 lukem Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/netconfig.5 154224 2006-01-11 13:57:15Z ceri $ +.Dd November 17, 2000 +.Dt NETCONFIG 5 +.Os +.Sh NAME +.Nm netconfig +.Nd network configuration data base +.Sh SYNOPSIS +.Pa /etc/netconfig +.Sh DESCRIPTION +The +.Nm +file defines a list of +.Dq transport names , +describing their semantics and protocol. +In +.Fx , +this file is only used by the RPC library code. +.Pp +Entries have the following format: +.Pp +.Ar network_id semantics flags family protoname device libraries +.Pp +Entries consist of the following fields: +.Bl -tag -width network_id +.It Ar network_id +The name of the transport described. +.It Ar semantics +Describes the semantics of the transport. +This can be one of: +.Bl -tag -width tpi_cots_ord -offset indent +.It Sy tpi_clts +Connectionless transport. +.It Sy tpi_cots +Connection-oriented transport +.It Sy tpi_cots_ord +Connection-oriented, ordered transport. +.It Sy tpi_raw +A raw connection. +.El +.It Ar flags +This field is either blank (specified by +.Dq Li - ) , +or contains one or more of the following characters: +.Bl -tag -width b -offset indent +.It Sy b +The network represented by this entry is broadcast capable. +This flag is meaningless in +.Fx . +.It Sy v +The entry may be returned by the +.Xr getnetpath 3 +function. +.El +.It Ar family +The protocol family of the transport. +This is currently one of: +.Bl -tag -width loopback -offset indent +.It Sy inet6 +The IPv6 +.Pq Dv PF_INET6 +family of protocols. +.It Sy inet +The IPv4 +.Pq Dv PF_INET +family of protocols. +.It Sy loopback +The +.Dv PF_LOCAL +protocol family. +.El +.It Ar protoname +The name of the protocol used for this transport. +Can currently be either +.Sy udp , +.Sy tcp +or empty. +.It Ar device +This field is always empty in +.Fx . +.It Ar libraries +This field is always empty in +.Fx . +.El +.Pp +The order of entries in this file will determine which transport will +be preferred by the RPC library code, given a match on a specified +network type. +For example, if a sample network config file would look like this: +.Bd -literal -offset indent +udp6 tpi_clts v inet6 udp - - +tcp6 tpi_cots_ord v inet6 tcp - - +udp tpi_clts v inet udp - - +tcp tpi_cots_ord v inet tcp - - +rawip tpi_raw - inet - - - +local tpi_cots_ord - loopback - - - +.Ed +.Pp +then using the network type +.Sy udp +in calls to the RPC library function (see +.Xr rpc 3 ) +will make the code first try +.Sy udp6 , +and then +.Sy udp . +.Pp +.Xr getnetconfig 3 +and associated functions will parse this file and return structures of +the following format: +.Bd -literal +struct netconfig { + char *nc_netid; /* Network ID */ + unsigned long nc_semantics; /* Semantics */ + unsigned long nc_flag; /* Flags */ + char *nc_protofmly; /* Protocol family */ + char *nc_proto; /* Protocol name */ + char *nc_device; /* Network device pathname (unused) */ + unsigned long nc_nlookups; /* Number of lookup libs (unused) */ + char **nc_lookups; /* Names of the libraries (unused) */ + unsigned long nc_unused[9]; /* reserved */ +}; +.Ed +.Sh FILES +.Bl -tag -width /etc/netconfig -compact +.It Pa /etc/netconfig +.El +.Sh SEE ALSO +.Xr getnetconfig 3 , +.Xr getnetpath 3 diff --git a/lib/libc/rpc/publickey.3 b/lib/libc/rpc/publickey.3 new file mode 100644 index 0000000..86a83f9 --- /dev/null +++ b/lib/libc/rpc/publickey.3 @@ -0,0 +1,53 @@ +.\" @(#)publickey.3r 2.1 88/08/07 4.0 RPCSRC +.\" $FreeBSD: releng/11.1/lib/libc/rpc/publickey.3 235286 2012-05-11 20:06:46Z gjb $ +.\" +.Dd October 6, 1987 +.Dt PUBLICKEY 3 +.Os +.Sh NAME +.Nm publickey , getpublickey , getsecretkey +.Nd "get public or secret key" +.Sh LIBRARY +.Lb librpcsvc +.Sh SYNOPSIS +.In rpc/rpc.h +.In rpc/key_prot.h +.Ft int +.Fo getpublickey +.Fa "const char netname[MAXNETNAMELEN+1]" +.Fa "char publickey[HEXKEYBYTES+1]" +.Fc +.Ft int +.Fo getsecretkey +.Fa "char netname[MAXNETNAMELEN+1]" +.Fa "char secretkey[HEXKEYBYTES+1]" +.Fa "char *passwd" +.Fc +.Sh DESCRIPTION +These routines are used to get public and secret keys from the +.Tn YP +database. +The +.Fn getsecretkey +function +has an extra argument, +.Fa passwd , +which is used to decrypt the encrypted secret key stored in the database. +Both routines return 1 if they are successful in finding the key, 0 otherwise. +The keys are returned as +.Dv NUL Ns \-terminated , +hexadecimal strings. +If the password supplied to +.Fn getsecretkey +fails to decrypt the secret key, the routine will return 1 but the +.Fa secretkey +argument will be a +.Dv NUL +string +.Pq Dq . +.Sh SEE ALSO +.Xr publickey 5 +.Pp +.%T "RPC Programmer's Manual" +in +.Pa /usr/share/doc/psd/23.rpc . diff --git a/lib/libc/rpc/publickey.5 b/lib/libc/rpc/publickey.5 new file mode 100644 index 0000000..37dff23 --- /dev/null +++ b/lib/libc/rpc/publickey.5 @@ -0,0 +1,42 @@ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/publickey.5 119492 2003-08-26 15:52:47Z eivind $ +.\" @(#)publickey.5 2.1 88/08/07 4.0 RPCSRC; from 1.6 88/02/29 SMI; +.Dd October 19, 1987 +.Dt PUBLICKEY 5 +.Os +.Sh NAME +.Nm publickey +.Nd "public key database" +.Sh SYNOPSIS +.Pa /etc/publickey +.Sh DESCRIPTION +.Pa /etc/publickey +is the public key database used for secure +RPC (Remote Procedure Calls). +Each entry in +the database consists of a network user +name (which may either refer to +a user or a hostname), followed by the user's +public key (in hex +notation), a colon, and then the user's +secret key encrypted with +its login password (also in hex notation). +.Pp +This file is altered either by the user through the +.Xr chkey 1 +command or by the system administrator through the +.Xr newkey 8 +command. +The file +.Pa /etc/publickey +should only contain data on the +.Tn NIS +master machine, where it +is converted into the +.Tn NIS +database +.Pa publickey.byname . +.Sh SEE ALSO +.Xr chkey 1 , +.Xr publickey 3 , +.Xr newkey 8 , +.Xr ypupdated 8 diff --git a/lib/libc/rpc/rpc.3 b/lib/libc/rpc/rpc.3 new file mode 100644 index 0000000..b3997f7 --- /dev/null +++ b/lib/libc/rpc/rpc.3 @@ -0,0 +1,517 @@ +.\" @(#)rpc.3n 1.31 93/08/31 SMI; from SVr4 +.\" Copyright 1989 AT&T +.\" $NetBSD: rpc.3,v 1.10 2000/06/02 23:11:12 fvdl Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpc.3 276294 2014-12-27 08:31:52Z joel $ +.Dd May 7, 1993 +.Dt RPC 3 +.Os +.Sh NAME +.Nm rpc +.Nd library routines for remote procedure calls +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/rpc.h +.In netconfig.h +.Sh DESCRIPTION +These +routines allow C language programs to make procedure +calls on other machines across a network. +First, the client sends a request to the server. +On receipt of the request, the server calls a dispatch routine +to perform the requested service, and then sends back a reply. +.Pp +All +RPC routines require the header +.In rpc/rpc.h . +Routines that take a +.Vt "struct netconfig" +also require that +.In netconfig.h +be included. +.Sh Nettype +Some of the high-level +RPC interface routines take a +.Fa nettype +string as one of the arguments +(for example, +.Fn clnt_create , +.Fn svc_create , +.Fn rpc_reg , +.Fn rpc_call ) . +This string defines a class of transports which can be used +for a particular application. +.Pp +The +.Fa nettype +argument +can be one of the following: +.Bl -tag -width datagram_v +.It netpath +Choose from the transports which have been +indicated by their token names in the +.Ev NETPATH +environment variable. +.Ev NETPATH +is unset or +.Dv NULL , +it defaults to +.Qq visible . +.Qq netpath +is the default +.Fa nettype . +.It visible +Choose the transports which have the visible flag (v) +set in the +.Pa /etc/netconfig +file. +.It circuit_v +This is same as +.Qq visible +except that it chooses only the connection oriented transports +(semantics +.Qq tpi_cots +or +.Qq tpi_cots_ord ) +from the entries in the +.Pa /etc/netconfig +file. +.It datagram_v +This is same as +.Qq visible +except that it chooses only the connectionless datagram transports +(semantics +.Qq tpi_clts ) +from the entries in the +.Pa /etc/netconfig +file. +.It circuit_n +This is same as +.Qq netpath +except that it chooses only the connection oriented datagram transports +(semantics +.Qq tpi_cots +or +.Qq tpi_cots_ord ) . +.It datagram_n +This is same as +.Qq netpath +except that it chooses only the connectionless datagram transports +(semantics +.Qq tpi_clts ) . +.It udp +This refers to Internet UDP, both version 4 and 6. +.It tcp +This refers to Internet TCP, both version 4 and 6. +.El +.Pp +If +.Fa nettype +is +.Dv NULL , +it defaults to +.Qq netpath . +The transports are tried in left to right order in the +.Ev NETPATH +variable or in top to down order in the +.Pa /etc/netconfig +file. +.Sh Derived Types +The derived types used in the RPC interfaces are defined as follows: +.Bd -literal + typedef uint32_t rpcprog_t; + typedef uint32_t rpcvers_t; + typedef uint32_t rpcproc_t; + typedef uint32_t rpcprot_t; + typedef uint32_t rpcport_t; + typedef int32_t rpc_inline_t; +.Ed +.Sh "Data Structures" +Some of the data structures used by the +RPC package are shown below. +.Sh "The AUTH Structure" +.Bd -literal +/* + * Authentication info. Opaque to client. + */ +struct opaque_auth { + enum_t oa_flavor; /* flavor of auth */ + caddr_t oa_base; /* address of more auth stuff */ + u_int oa_length; /* not to exceed MAX_AUTH_BYTES */ +}; + +/* + * Auth handle, interface to client side authenticators. + */ +typedef struct { + struct opaque_auth ah_cred; + struct opaque_auth ah_verf; + struct auth_ops { + void (*ah_nextverf)(\|); + int (*ah_marshal)(\|); /* nextverf & serialize */ + int (*ah_validate)(\|); /* validate verifier */ + int (*ah_refresh)(\|); /* refresh credentials */ + void (*ah_destroy)(\|); /* destroy this structure */ + } *ah_ops; + caddr_t ah_private; +} AUTH; +.Ed +.Sh "The CLIENT Structure" +.Bd -literal +/* + * Client rpc handle. + * Created by individual implementations. + * Client is responsible for initializing auth. + */ + +typedef struct { + AUTH *cl_auth; /* authenticator */ + struct clnt_ops { + enum clnt_stat (*cl_call)(); /* call remote procedure */ + void (*cl_abort)(); /* abort a call */ + void (*cl_geterr)(); /* get specific error code */ + bool_t (*cl_freeres)(); /* frees results */ + void (*cl_destroy)(); /* destroy this structure */ + bool_t (*cl_control)(); /* the ioctl() of rpc */ + } *cl_ops; + caddr_t cl_private; /* private stuff */ + char *cl_netid; /* network identifier */ + char *cl_tp; /* device name */ +} CLIENT; +.Ed +.Sh "The SVCXPRT structure" +.Bd -literal +enum xprt_stat { + XPRT_DIED, + XPRT_MOREREQS, + XPRT_IDLE +}; + +/* + * Server side transport handle + */ +typedef struct { + int xp_fd; /* file descriptor for the server handle */ + u_short xp_port; /* obsolete */ + const struct xp_ops { + bool_t (*xp_recv)(); /* receive incoming requests */ + enum xprt_stat (*xp_stat)(); /* get transport status */ + bool_t (*xp_getargs)(); /* get arguments */ + bool_t (*xp_reply)(); /* send reply */ + bool_t (*xp_freeargs)(); /* free mem allocated for args */ + void (*xp_destroy)(); /* destroy this struct */ + } *xp_ops; + int xp_addrlen; /* length of remote addr. Obsolete */ + struct sockaddr_in xp_raddr; /* Obsolete */ + const struct xp_ops2 { + bool_t (*xp_control)(); /* catch-all function */ + } *xp_ops2; + char *xp_tp; /* transport provider device name */ + char *xp_netid; /* network identifier */ + struct netbuf xp_ltaddr; /* local transport address */ + struct netbuf xp_rtaddr; /* remote transport address */ + struct opaque_auth xp_verf; /* raw response verifier */ + caddr_t xp_p1; /* private: for use by svc ops */ + caddr_t xp_p2; /* private: for use by svc ops */ + caddr_t xp_p3; /* private: for use by svc lib */ + int xp_type /* transport type */ +} SVCXPRT; +.Ed +.Sh "The svc_reg structure" +.Bd -literal +struct svc_req { + rpcprog_t rq_prog; /* service program number */ + rpcvers_t rq_vers; /* service protocol version */ + rpcproc_t rq_proc; /* the desired procedure */ + struct opaque_auth rq_cred; /* raw creds from the wire */ + caddr_t rq_clntcred; /* read only cooked cred */ + SVCXPRT *rq_xprt; /* associated transport */ +}; +.Ed +.Sh "The XDR structure" +.Bd -literal +/* + * XDR operations. + * XDR_ENCODE causes the type to be encoded into the stream. + * XDR_DECODE causes the type to be extracted from the stream. + * XDR_FREE can be used to release the space allocated by an XDR_DECODE + * request. + */ +enum xdr_op { + XDR_ENCODE=0, + XDR_DECODE=1, + XDR_FREE=2 +}; +/* + * This is the number of bytes per unit of external data. + */ +#define BYTES_PER_XDR_UNIT (4) +#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / + BYTES_PER_XDR_UNIT) \e * BYTES_PER_XDR_UNIT) + +/* + * A xdrproc_t exists for each data type which is to be encoded or + * decoded. The second argument to the xdrproc_t is a pointer to + * an opaque pointer. The opaque pointer generally points to a + * structure of the data type to be decoded. If this points to 0, + * then the type routines should allocate dynamic storage of the + * appropriate size and return it. + * bool_t (*xdrproc_t)(XDR *, caddr_t *); + */ +typedef bool_t (*xdrproc_t)(); + +/* + * The XDR handle. + * Contains operation which is being applied to the stream, + * an operations vector for the particular implementation + */ +typedef struct { + enum xdr_op x_op; /* operation; fast additional param */ + struct xdr_ops { + bool_t (*x_getlong)(); /* get a long from underlying stream */ + bool_t (*x_putlong)(); /* put a long to underlying stream */ + bool_t (*x_getbytes)(); /* get bytes from underlying stream */ + bool_t (*x_putbytes)(); /* put bytes to underlying stream */ + u_int (*x_getpostn)(); /* returns bytes off from beginning */ + bool_t (*x_setpostn)(); /* lets you reposition the stream */ + long * (*x_inline)(); /* buf quick ptr to buffered data */ + void (*x_destroy)(); /* free privates of this xdr_stream */ + } *x_ops; + caddr_t x_public; /* users' data */ + caddr_t x_private; /* pointer to private data */ + caddr_t x_base; /* private used for position info */ + u_int x_handy; /* extra private word */ +} XDR; + +/* + * The netbuf structure. This structure is defined in on SysV + * systems, but NetBSD / FreeBSD do not use XTI. + * + * Usually, buf will point to a struct sockaddr, and len and maxlen + * will contain the length and maximum length of that socket address, + * respectively. + */ +struct netbuf { + unsigned int maxlen; + unsigned int len; + void *buf; +}; + +/* + * The format of the address and options arguments of the XTI t_bind call. + * Only provided for compatibility, it should not be used other than + * as an argument to svc_tli_create(). + */ + +struct t_bind { + struct netbuf addr; + unsigned int qlen; +}; +.Ed +.Sh "Index to Routines" +The following table lists RPC routines and the manual reference +pages on which they are described: +.Pp +.Bl -tag -width "authunix_create_default()" -compact +.It Em "RPC Routine" +.Em "Manual Reference Page" +.Pp +.It Fn auth_destroy +.Xr rpc_clnt_auth 3 +.It Fn authdes_create +.Xr rpc_soc 3 +.It Fn authnone_create +.Xr rpc_clnt_auth 3 +.It Fn authsys_create +.Xr rpc_clnt_auth 3 +.It Fn authsys_create_default +.Xr rpc_clnt_auth 3 +.It Fn authunix_create +.Xr rpc_soc 3 +.It Fn authunix_create_default +.Xr rpc_soc 3 +.It Fn callrpc +.Xr rpc_soc 3 +.It Fn clnt_broadcast +.Xr rpc_soc 3 +.It Fn clnt_call +.Xr rpc_clnt_calls 3 +.It Fn clnt_control +.Xr rpc_clnt_create 3 +.It Fn clnt_create +.Xr rpc_clnt_create 3 +.It Fn clnt_create_timed +.Xr rpc_clnt_create 3 +.It Fn clnt_create_vers +.Xr rpc_clnt_create 3 +.It Fn clnt_create_vers_timed +.Xr rpc_clnt_create 3 +.It Fn clnt_destroy +.Xr rpc_clnt_create 3 +.It Fn clnt_dg_create +.Xr rpc_clnt_create 3 +.It Fn clnt_freeres +.Xr rpc_clnt_calls 3 +.It Fn clnt_geterr +.Xr rpc_clnt_calls 3 +.It Fn clnt_pcreateerror +.Xr rpc_clnt_create 3 +.It Fn clnt_perrno +.Xr rpc_clnt_calls 3 +.It Fn clnt_perror +.Xr rpc_clnt_calls 3 +.It Fn clnt_raw_create +.Xr rpc_clnt_create 3 +.It Fn clnt_spcreateerror +.Xr rpc_clnt_create 3 +.It Fn clnt_sperrno +.Xr rpc_clnt_calls 3 +.It Fn clnt_sperror +.Xr rpc_clnt_calls 3 +.It Fn clnt_tli_create +.Xr rpc_clnt_create 3 +.It Fn clnt_tp_create +.Xr rpc_clnt_create 3 +.It Fn clnt_tp_create_timed +.Xr rpc_clnt_create 3 +.It Fn clnt_udpcreate +.Xr rpc_soc 3 +.It Fn clnt_vc_create +.Xr rpc_clnt_create 3 +.It Fn clntraw_create +.Xr rpc_soc 3 +.It Fn clnttcp_create +.Xr rpc_soc 3 +.It Fn clntudp_bufcreate +.Xr rpc_soc 3 +.It Fn get_myaddress +.Xr rpc_soc 3 +.It Fn pmap_getmaps +.Xr rpc_soc 3 +.It Fn pmap_getport +.Xr rpc_soc 3 +.It Fn pmap_rmtcall +.Xr rpc_soc 3 +.It Fn pmap_set +.Xr rpc_soc 3 +.It Fn pmap_unset +.Xr rpc_soc 3 +.It Fn registerrpc +.Xr rpc_soc 3 +.It Fn rpc_broadcast +.Xr rpc_clnt_calls 3 +.It Fn rpc_broadcast_exp +.Xr rpc_clnt_calls 3 +.It Fn rpc_call +.Xr rpc_clnt_calls 3 +.It Fn rpc_reg +.Xr rpc_svc_calls 3 +.It Fn svc_create +.Xr rpc_svc_create 3 +.It Fn svc_destroy +.Xr rpc_svc_create 3 +.It Fn svc_dg_create +.Xr rpc_svc_create 3 +.It Fn svc_dg_enablecache +.Xr rpc_svc_calls 3 +.It Fn svc_fd_create +.Xr rpc_svc_create 3 +.It Fn svc_fds +.Xr rpc_soc 3 +.It Fn svc_freeargs +.Xr rpc_svc_reg 3 +.It Fn svc_getargs +.Xr rpc_svc_reg 3 +.It Fn svc_getcaller +.Xr rpc_soc 3 +.It Fn svc_getreq +.Xr rpc_soc 3 +.It Fn svc_getreqset +.Xr rpc_svc_calls 3 +.It Fn svc_getrpccaller +.Xr rpc_svc_calls 3 +.It Fn svc_kerb_reg +.Xr kerberos_rpc 3 +.It Fn svc_raw_create +.Xr rpc_svc_create 3 +.It Fn svc_reg +.Xr rpc_svc_calls 3 +.It Fn svc_register +.Xr rpc_soc 3 +.It Fn svc_run +.Xr rpc_svc_reg 3 +.It Fn svc_sendreply +.Xr rpc_svc_reg 3 +.It Fn svc_tli_create +.Xr rpc_svc_create 3 +.It Fn svc_tp_create +.Xr rpc_svc_create 3 +.It Fn svc_unreg +.Xr rpc_svc_calls 3 +.It Fn svc_unregister +.Xr rpc_soc 3 +.It Fn svc_vc_create +.Xr rpc_svc_create 3 +.It Fn svcerr_auth +.Xr rpc_svc_err 3 +.It Fn svcerr_decode +.Xr rpc_svc_err 3 +.It Fn svcerr_noproc +.Xr rpc_svc_err 3 +.It Fn svcerr_noprog +.Xr rpc_svc_err 3 +.It Fn svcerr_progvers +.Xr rpc_svc_err 3 +.It Fn svcerr_systemerr +.Xr rpc_svc_err 3 +.It Fn svcerr_weakauth +.Xr rpc_svc_err 3 +.It Fn svcfd_create +.Xr rpc_soc 3 +.It Fn svcraw_create +.Xr rpc_soc 3 +.It Fn svctcp_create +.Xr rpc_soc 3 +.It Fn svcudp_bufcreate +.Xr rpc_soc 3 +.It Fn svcudp_create +.Xr rpc_soc 3 +.It Fn xdr_accepted_reply +.Xr rpc_xdr 3 +.It Fn xdr_authsys_parms +.Xr rpc_xdr 3 +.It Fn xdr_authunix_parms +.Xr rpc_soc 3 +.It Fn xdr_callhdr +.Xr rpc_xdr 3 +.It Fn xdr_callmsg +.Xr rpc_xdr 3 +.It Fn xdr_opaque_auth +.Xr rpc_xdr 3 +.It Fn xdr_rejected_reply +.Xr rpc_xdr 3 +.It Fn xdr_replymsg +.Xr rpc_xdr 3 +.It Fn xprt_register +.Xr rpc_svc_calls 3 +.It Fn xprt_unregister +.Xr rpc_svc_calls 3 +.El +.Sh FILES +.Bl -tag -width /etc/netconfig +.It Pa /etc/netconfig +.El +.Sh SEE ALSO +.Xr getnetconfig 3 , +.Xr getnetpath 3 , +.Xr rpc_clnt_auth 3 , +.Xr rpc_clnt_calls 3 , +.Xr rpc_clnt_create 3 , +.Xr rpc_svc_calls 3 , +.Xr rpc_svc_create 3 , +.Xr rpc_svc_err 3 , +.Xr rpc_svc_reg 3 , +.Xr rpc_xdr 3 , +.Xr rpcbind 3 , +.Xr xdr 3 , +.Xr netconfig 5 diff --git a/lib/libc/rpc/rpc.5 b/lib/libc/rpc/rpc.5 new file mode 100644 index 0000000..0bfd2e7 --- /dev/null +++ b/lib/libc/rpc/rpc.5 @@ -0,0 +1,59 @@ +.\" $NetBSD: rpc.5,v 1.3 2000/06/15 20:05:54 fvdl Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpc.5 140505 2005-01-20 09:17:07Z ru $ +.\" @(#)rpc.4 1.17 93/08/30 SMI; from SVr4 +.\" Copyright 1989 AT&T +.Dd December 10, 1991 +.Dt RPC 5 +.Os +.Sh NAME +.Nm rpc +.Nd rpc program number data base +.Sh SYNOPSIS +.Pa /etc/rpc +.Sh DESCRIPTION +The +.Nm +file contains user readable names that +can be used in place of RPC program numbers. +For each RPC program a single line should be present +with the following information: +.Pp +.Bl -enum -compact +.It +name of the RPC program +.It +RPC program number +.It +aliases +.El +.Pp +Items are separated by any number of blanks and/or +tab characters. +A hash +.Pq Dq Li # +indicates the beginning of a comment; characters up to the end of +the line are not interpreted by routines which search the file. +.Sh FILES +.Bl -tag -width /etc/nsswitch.conf -compact +.It Pa /etc/nsswitch.conf +.El +.Sh EXAMPLES +Below is an example of an RPC database: +.Bd -literal +# +# rpc +# +rpcbind 100000 portmap sunrpc portmapper +rusersd 100002 rusers +nfs 100003 nfsprog +mountd 100005 mount showmount +walld 100008 rwall shutdown +sprayd 100012 spray +llockmgr 100020 +nlockmgr 100021 +status 100024 +bootparam 100026 +keyserv 100029 keyserver +.Ed +.Sh SEE ALSO +.Xr getrpcent 3 diff --git a/lib/libc/rpc/rpc_clnt_auth.3 b/lib/libc/rpc/rpc_clnt_auth.3 new file mode 100644 index 0000000..a55d124 --- /dev/null +++ b/lib/libc/rpc/rpc_clnt_auth.3 @@ -0,0 +1,96 @@ +.\" @(#)rpc_clnt_auth.3n 1.21 93/05/07 SMI; from SVr4 +.\" Copyright 1989 AT&T +.\" @(#)rpc_clnt_auth 1.4 89/07/20 SMI; +.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. +.\" $NetBSD: rpc_clnt_auth.3,v 1.1 2000/06/03 09:29:50 fvdl Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpc_clnt_auth.3 141580 2005-02-09 18:07:17Z ru $ +.Dd May 7, 1993 +.Dt RPC_CLNT_AUTH 3 +.Os +.Sh NAME +.Nm auth_destroy , +.Nm authnone_create , +.Nm authsys_create , +.Nm authsys_create_default +.Nd library routines for client side remote procedure call authentication +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/rpc.h +.Ft "void" +.Fn auth_destroy "AUTH *auth" +.Ft "AUTH *" +.Fn authnone_create "void" +.Ft "AUTH *" +.Fn authsys_create "const char *host" "const uid_t uid" "const gid_t gid" "const int len" "const gid_t *aup_gids" +.Ft "AUTH *" +.Fn authsys_create_default "void" +.Sh DESCRIPTION +These routines are part of the +RPC library that allows C language programs to make procedure +calls on other machines across the network, +with desired authentication. +.Pp +These routines are normally called after creating the +.Vt CLIENT +handle. +The +.Va cl_auth +field of the +.Vt CLIENT +structure should be initialized by the +.Vt AUTH +structure returned by some of the following routines. +The client's authentication information +is passed to the server when the +RPC +call is made. +.Pp +Only the +.Dv NULL +and the +.Dv SYS +style of authentication is discussed here. +.Sh Routines +.Bl -tag -width authsys_create_default() +.It Fn auth_destroy +A function macro that destroys the authentication +information associated with +.Fa auth . +Destruction usually involves deallocation +of private data structures. +The use of +.Fa auth +is undefined after calling +.Fn auth_destroy . +.It Fn authnone_create +Create and return an RPC +authentication handle that passes nonusable +authentication information with each remote procedure call. +This is the default authentication used by RPC. +.It Fn authsys_create +Create and return an RPC authentication handle that contains +.Dv AUTH_SYS +authentication information. +The +.Fa host +argument +is the name of the machine on which the information was +created; +.Fa uid +is the user's user ID; +.Fa gid +is the user's current group ID; +.Fa len +and +.Fa aup_gids +refer to a counted array of groups to which the user belongs. +.It Fn authsys_create_default +Call +.Fn authsys_create +with the appropriate arguments. +.El +.Sh SEE ALSO +.Xr rpc 3 , +.Xr rpc_clnt_calls 3 , +.Xr rpc_clnt_create 3 diff --git a/lib/libc/rpc/rpc_clnt_calls.3 b/lib/libc/rpc/rpc_clnt_calls.3 new file mode 100644 index 0000000..daf71e8 --- /dev/null +++ b/lib/libc/rpc/rpc_clnt_calls.3 @@ -0,0 +1,316 @@ +.\" @(#)rpc_clnt_calls.3n 1.30 93/08/31 SMI; from SVr4 +.\" Copyright 1989 AT&T +.\" @(#)rpc_clnt_calls 1.4 89/07/20 SMI; +.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpc_clnt_calls.3 141580 2005-02-09 18:07:17Z ru $ +.Dd May 7, 1993 +.Dt RPC_CLNT_CALLS 3 +.Os +.Sh NAME +.Nm rpc_clnt_calls , +.Nm clnt_call , +.Nm clnt_freeres , +.Nm clnt_geterr , +.Nm clnt_perrno , +.Nm clnt_perror , +.Nm clnt_sperrno , +.Nm clnt_sperror , +.Nm rpc_broadcast , +.Nm rpc_broadcast_exp , +.Nm rpc_call +.Nd library routines for client side calls +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/rpc.h +.Ft "enum clnt_stat" +.Fn clnt_call "CLIENT *clnt" "const rpcproc_t procnum" "const xdrproc_t inproc" "const caddr_t in" "const xdrproc_t outproc" "caddr_t out" "const struct timeval tout" +.Ft bool_t +.Fn clnt_freeres "CLIENT *clnt" "const xdrproc_t outproc" "caddr_t out" +.Ft void +.Fn clnt_geterr "const CLIENT * clnt" "struct rpc_err * errp" +.Ft void +.Fn clnt_perrno "const enum clnt_stat stat" +.Ft void +.Fn clnt_perror "CLIENT *clnt" "const char *s" +.Ft "char *" +.Fn clnt_sperrno "const enum clnt_stat stat" +.Ft "char *" +.Fn clnt_sperror "CLIENT *clnt" "const char * s" +.Ft "enum clnt_stat" +.Fo rpc_broadcast +.Fa "const rpcprog_t prognum" "const rpcvers_t versnum" +.Fa "const rpcproc_t procnum" "const xdrproc_t inproc" +.Fa "const caddr_t in" "const xdrproc_t outproc" "caddr_t out" +.Fa "const resultproc_t eachresult" "const char *nettype" +.Fc +.Ft "enum clnt_stat" +.Fo rpc_broadcast_exp +.Fa "const rpcprog_t prognum" "const rpcvers_t versnum" +.Fa "const rpcproc_t procnum" "const xdrproc_t xargs" +.Fa "caddr_t argsp" "const xdrproc_t xresults" +.Fa "caddr_t resultsp" "const resultproc_t eachresult" +.Fa "const int inittime" "const int waittime" +.Fa "const char * nettype" +.Fc +.Ft "enum clnt_stat" +.Fo rpc_call +.Fa "const char *host" "const rpcprog_t prognum" +.Fa "const rpcvers_t versnum" "const rpcproc_t procnum" +.Fa "const xdrproc_t inproc" "const char *in" +.Fa "const xdrproc_t outproc" "char *out" "const char *nettype" +.Fc +.Sh DESCRIPTION +RPC library routines allow C language programs to make procedure +calls on other machines across the network. +First, the client calls a procedure to send a request to the server. +Upon receipt of the request, the server calls a dispatch routine +to perform the requested service, and then sends back a reply. +.Pp +The +.Fn clnt_call , +.Fn rpc_call , +and +.Fn rpc_broadcast +routines handle the client side of the procedure call. +The remaining routines deal with error handling in the case of errors. +.Pp +Some of the routines take a +.Vt CLIENT +handle as one of the arguments. +A +.Vt CLIENT +handle can be created by an RPC creation routine such as +.Fn clnt_create +(see +.Xr rpc_clnt_create 3 ) . +.Pp +These routines are safe for use in multithreaded applications. +.Vt CLIENT +handles can be shared between threads, however in this implementation +requests by different threads are serialized (that is, the first request will +receive its results before the second request is sent). +.Sh Routines +See +.Xr rpc 3 +for the definition of the +.Vt CLIENT +data structure. +.Bl -tag -width XXXXX +.It Fn clnt_call +A function macro that calls the remote procedure +.Fa procnum +associated with the client handle, +.Fa clnt , +which is obtained with an RPC +client creation routine such as +.Fn clnt_create +(see +.Xr rpc_clnt_create 3 ) . +The +.Fa inproc +argument +is the XDR function used to encode the procedure's arguments, and +.Fa outproc +is the XDR function used to decode the procedure's results; +.Fa in +is the address of the procedure's argument(s), and +.Fa out +is the address of where to place the result(s). +The +.Fa tout +argument +is the time allowed for results to be returned, which is overridden by +a time-out set explicitly through +.Fn clnt_control , +see +.Xr rpc_clnt_create 3 . +If the remote call succeeds, the status returned is +.Dv RPC_SUCCESS , +otherwise an appropriate status is returned. +.It Fn clnt_freeres +A function macro that frees any data allocated by the +RPC/XDR system when it decoded the results of an RPC call. +The +.Fa out +argument +is the address of the results, and +.Fa outproc +is the XDR routine describing the results. +This routine returns 1 if the results were successfully freed, +and 0 otherwise. +.It Fn clnt_geterr +A function macro that copies the error structure out of the client +handle to the structure at address +.Fa errp . +.It Fn clnt_perrno +Print a message to standard error corresponding +to the condition indicated by +.Fa stat . +A newline is appended. +Normally used after a procedure call fails for a routine +for which a client handle is not needed, for instance +.Fn rpc_call . +.It Fn clnt_perror +Print a message to the standard error indicating why an +RPC call failed; +.Fa clnt +is the handle used to do the call. +The message is prepended with string +.Fa s +and a colon. +A newline is appended. +Normally used after a remote procedure call fails +for a routine which requires a client handle, +for instance +.Fn clnt_call . +.It Fn clnt_sperrno +Take the same arguments as +.Fn clnt_perrno , +but instead of sending a message to the standard error +indicating why an RPC +call failed, return a pointer to a string which contains the message. +The +.Fn clnt_sperrno +function +is normally used instead of +.Fn clnt_perrno +when the program does not have a standard error (as a program +running as a server quite likely does not), or if the programmer +does not want the message to be output with +.Fn printf +(see +.Xr printf 3 ) , +or if a message format different than that supported by +.Fn clnt_perrno +is to be used. +Note: +unlike +.Fn clnt_sperror +and +.Fn clnt_spcreateerror +(see +.Xr rpc_clnt_create 3 ) , +.Fn clnt_sperrno +does not return pointer to static data so the +result will not get overwritten on each call. +.It Fn clnt_sperror +Like +.Fn clnt_perror , +except that (like +.Fn clnt_sperrno ) +it returns a string instead of printing to standard error. +However, +.Fn clnt_sperror +does not append a newline at the end of the message. +Warning: +returns pointer to a buffer that is overwritten +on each call. +.It Fn rpc_broadcast +Like +.Fn rpc_call , +except the call message is broadcast to +all the connectionless transports specified by +.Fa nettype . +If +.Fa nettype +is +.Dv NULL , +it defaults to +.Qq netpath . +Each time it receives a response, +this routine calls +.Fn eachresult , +whose form is: +.Ft bool_t +.Fn eachresult "caddr_t out" "const struct netbuf * addr" "const struct netconfig * netconf" +where +.Fa out +is the same as +.Fa out +passed to +.Fn rpc_broadcast , +except that the remote procedure's output is decoded there; +.Fa addr +points to the address of the machine that sent the results, and +.Fa netconf +is the netconfig structure of the transport on which the remote +server responded. +If +.Fn eachresult +returns 0, +.Fn rpc_broadcast +waits for more replies; +otherwise it returns with appropriate status. +Warning: +broadcast file descriptors are limited in size to the +maximum transfer size of that transport. +For Ethernet, this value is 1500 bytes. +The +.Fn rpc_broadcast +function +uses +.Dv AUTH_SYS +credentials by default (see +.Xr rpc_clnt_auth 3 ) . +.It Fn rpc_broadcast_exp +Like +.Fn rpc_broadcast , +except that the initial timeout, +.Fa inittime +and the maximum timeout, +.Fa waittime +are specified in milliseconds. +The +.Fa inittime +argument +is the initial time that +.Fn rpc_broadcast_exp +waits before resending the request. +After the first resend, the re-transmission interval +increases exponentially until it exceeds +.Fa waittime . +.It Fn rpc_call +Call the remote procedure associated with +.Fa prognum , +.Fa versnum , +and +.Fa procnum +on the machine, +.Fa host . +The +.Fa inproc +argument +is used to encode the procedure's arguments, and +.Fa outproc +is used to decode the procedure's results; +.Fa in +is the address of the procedure's argument(s), and +.Fa out +is the address of where to place the result(s). +The +.Fa nettype +argument +can be any of the values listed on +.Xr rpc 3 . +This routine returns +.Dv RPC_SUCCESS +if it succeeds, +or an appropriate status is returned. +Use the +.Fn clnt_perrno +routine to translate failure status into error messages. +Warning: +.Fn rpc_call +uses the first available transport belonging +to the class +.Fa nettype , +on which it can create a connection. +You do not have control of timeouts or authentication +using this routine. +.El +.Sh SEE ALSO +.Xr printf 3 , +.Xr rpc 3 , +.Xr rpc_clnt_auth 3 , +.Xr rpc_clnt_create 3 diff --git a/lib/libc/rpc/rpc_clnt_create.3 b/lib/libc/rpc/rpc_clnt_create.3 new file mode 100644 index 0000000..56bf7aa --- /dev/null +++ b/lib/libc/rpc/rpc_clnt_create.3 @@ -0,0 +1,514 @@ +.\" @(#)rpc_clnt_create.3n 1.36 93/08/31 SMI; from SVr4 +.\" Copyright 1989 AT&T +.\" @(#)rpc_clnt_create 1.5 89/07/24 SMI; +.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. +.\" $NetBSD: rpc_clnt_create.3,v 1.2 2000/06/20 00:53:08 fvdl Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpc_clnt_create.3 231564 2012-02-12 18:29:56Z ed $ +.Dd May 7, 1993 +.Dt RPC_CLNT_CREATE 3 +.Os +.Sh NAME +.Nm rpc_clnt_create , +.Nm clnt_control , +.Nm clnt_create , +.Nm clnt_create_timed , +.Nm clnt_create_vers , +.Nm clnt_create_vers_timed , +.Nm clnt_destroy , +.Nm clnt_dg_create , +.Nm clnt_pcreateerror , +.Nm clnt_raw_create , +.Nm clnt_spcreateerror , +.Nm clnt_tli_create , +.Nm clnt_tp_create , +.Nm clnt_tp_create_timed , +.Nm clnt_vc_create , +.Nm rpc_createerr +.Nd "library routines for dealing with creation and manipulation of" +.Vt CLIENT +handles +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/rpc.h +.Ft bool_t +.Fn clnt_control "CLIENT *clnt" "const u_int req" "char *info" +.Ft "CLIENT *" +.Fn clnt_create "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const char *nettype" +.Ft "CLIENT *" +.Fn clnt_create_timed "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const char *nettype" "const struct timeval *timeout" +.Ft "CLIENT *" +.Fn clnt_create_vers "const char * host" "const rpcprog_t prognum" "rpcvers_t *vers_outp" "const rpcvers_t vers_low" "const rpcvers_t vers_high" "const char *nettype" +.Ft "CLIENT *" +.Fn clnt_create_vers_timed "const char * host" "const rpcprog_t prognum" "rpcvers_t *vers_outp" "const rpcvers_t vers_low" "const rpcvers_t vers_high" "const char *nettype" "const struct timeval *timeout" +.Ft void +.Fn clnt_destroy "CLIENT *clnt" +.Ft "CLIENT *" +.Fn clnt_dg_create "const int fildes" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "const u_int sendsz" "const u_int recvsz" +.Ft void +.Fn clnt_pcreateerror "const char *s" +.Ft "char *" +.Fn clnt_spcreateerror "const char *s" +.Ft "CLIENT *" +.Fn clnt_raw_create "const rpcprog_t prognum" "const rpcvers_t versnum" +.Ft "CLIENT *" +.Fn clnt_tli_create "const int fildes" "const struct netconfig *netconf" "struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "const u_int sendsz" "const u_int recvsz" +.Ft "CLIENT *" +.Fn clnt_tp_create "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" +.Ft "CLIENT *" +.Fn clnt_tp_create_timed "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" "const struct timeval *timeout" +.Ft "CLIENT *" +.Fn clnt_vc_create "const int fildes" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "u_int sendsz" "u_int recvsz" +.Sh DESCRIPTION +RPC library routines allow C language programs to make procedure +calls on other machines across the network. +First a +.Vt CLIENT +handle is created and then the client calls a procedure to send a +request to the server. +On receipt of the request, the server calls a dispatch routine +to perform the requested service, and then sends a reply. +.Sh Routines +.Bl -tag -width YYYYYYY +.It Fn clnt_control +A function macro to change or retrieve various information +about a client object. +The +.Fa req +argument +indicates the type of operation, and +.Fa info +is a pointer to the information. +For both connectionless and connection-oriented transports, +the supported values of +.Fa req +and their argument types and what they do are: +.Bl -column "CLSET_FD_NCLOSE" "struct timeval *" "set total timeout" +.It Dv CLSET_TIMEOUT Ta "struct timeval *" Ta "set total timeout" +.It Dv CLGET_TIMEOUT Ta "struct timeval *" Ta "get total timeout" +.El +.Pp +Note: +if you set the timeout using +.Fn clnt_control , +the timeout argument passed by +.Fn clnt_call +is ignored in all subsequent calls. +.Pp +Note: +If you set the timeout value to 0, +.Fn clnt_control +immediately returns an error +.Pq Dv RPC_TIMEDOUT . +Set the timeout argument to 0 for batching calls. +.Bl -column CLSET_FD_NCLOSE "struct timeval *" +.It Dv CLGET_SVC_ADDR Ta "struct netbuf *" Ta "get servers address" +.It Dv CLGET_FD Ta "int *" Ta "get fd from handle" +.It Dv CLSET_FD_CLOSE Ta "void" Ta "close fd on destroy" +.It Dv CLSET_FD_NCLOSE Ta void Ta "do not close fd on destroy" +.It Dv CLGET_VERS Ta "uint32_t *" Ta "get RPC program version" +.It Dv CLSET_VERS Ta "uint32_t *" Ta "set RPC program version" +.It Dv CLGET_XID Ta "uint32_t *" Ta "get XID of previous call" +.It Dv CLSET_XID Ta "uint32_t *" Ta "set XID of next call" +.El +.Pp +The following operations are valid for connectionless transports only: +.Bl -column CLSET_RETRY_TIMEOUT "struct timeval *" "set total timeout" +.It Dv CLSET_RETRY_TIMEOUT Ta "struct timeval *" Ta "set the retry timeout" +.It Dv CLGET_RETRY_TIMEOUT Ta "struct timeval *" Ta "get the retry timeout" +.It Dv CLSET_CONNECT Ta Vt "int *" Ta use Xr connect 2 +.El +.Pp +The retry timeout is the time that RPC +waits for the server to reply before retransmitting the request. +The +.Fn clnt_control +function +returns +.Dv TRUE +on success and +.Dv FALSE +on failure. +.It Fn clnt_create +Generic client creation routine for program +.Fa prognum +and version +.Fa versnum . +The +.Fa host +argument +identifies the name of the remote host where the server +is located. +The +.Fa nettype +argument +indicates the class of transport protocol to use. +The transports are tried in left to right order in +.Ev NETPATH +environment variable or in top to bottom order in +the netconfig database. +The +.Fn clnt_create +function +tries all the transports of the +.Fa nettype +class available from the +.Ev NETPATH +environment variable and the netconfig database, +and chooses the first successful one. +A default timeout is set and can be modified using +.Fn clnt_control . +This routine returns +.Dv NULL +if it fails. +The +.Fn clnt_pcreateerror +routine can be used to print the reason for failure. +.Pp +Note: +.Fn clnt_create +returns a valid client handle even +if the particular version number supplied to +.Fn clnt_create +is not registered with the +.Xr rpcbind 8 +service. +This mismatch will be discovered by a +.Fn clnt_call +later (see +.Xr rpc_clnt_calls 3 ) . +.It Fn clnt_create_timed +Generic client creation routine which is similar to +.Fn clnt_create +but which also has the additional argument +.Fa timeout +that specifies the maximum amount of time allowed for +each transport class tried. +In all other respects, the +.Fn clnt_create_timed +call behaves exactly like the +.Fn clnt_create +call. +.It Fn clnt_create_vers +Generic client creation routine which is similar to +.Fn clnt_create +but which also checks for the +version availability. +The +.Fa host +argument +identifies the name of the remote host where the server +is located. +The +.Fa nettype +argument +indicates the class transport protocols to be used. +If the routine is successful it returns a client handle created for +the highest version between +.Fa vers_low +and +.Fa vers_high +that is supported by the server. +The +.Fa vers_outp +argument +is set to this value. +That is, after a successful return +.Fa vers_low +<= +.Fa *vers_outp +<= +.Fa vers_high . +If no version between +.Fa vers_low +and +.Fa vers_high +is supported by the server then the routine fails and returns +.Dv NULL . +A default timeout is set and can be modified using +.Fn clnt_control . +This routine returns +.Dv NULL +if it fails. +The +.Fn clnt_pcreateerror +routine can be used to print the reason for failure. +Note: +.Fn clnt_create +returns a valid client handle even +if the particular version number supplied to +.Fn clnt_create +is not registered with the +.Xr rpcbind 8 +service. +This mismatch will be discovered by a +.Fn clnt_call +later (see +.Xr rpc_clnt_calls 3 ) . +However, +.Fn clnt_create_vers +does this for you and returns a valid handle +only if a version within +the range supplied is supported by the server. +.It Fn clnt_create_vers_timed +Generic client creation routine which is similar to +.Fn clnt_create_vers +but which also has the additional argument +.Fa timeout +that specifies the maximum amount of time allowed for +each transport class tried. +In all other respects, the +.Fn clnt_create_vers_timed +call behaves exactly like the +.Fn clnt_create_vers +call. +.It Fn clnt_destroy +A function macro that destroys the client's RPC handle. +Destruction usually involves deallocation +of private data structures, including +.Fa clnt +itself. +Use of +.Fa clnt +is undefined after calling +.Fn clnt_destroy . +If the RPC library opened the associated file descriptor, or +.Dv CLSET_FD_CLOSE +was set using +.Fn clnt_control , +the file descriptor will be closed. +The caller should call +.Fn auth_destroy "clnt->cl_auth" +(before calling +.Fn clnt_destroy ) +to destroy the associated +.Vt AUTH +structure (see +.Xr rpc_clnt_auth 3 ) . +.It Fn clnt_dg_create +This routine creates an RPC client for the remote program +.Fa prognum +and version +.Fa versnum ; +the client uses a connectionless transport. +The remote program is located at address +.Fa svcaddr . +The +.Fa fildes +argument +is an open and bound file descriptor. +This routine will resend the call message in intervals of +15 seconds until a response is received or until the +call times out. +The total time for the call to time out is specified by +.Fn clnt_call +(see +.Fn clnt_call +in +.Xr rpc_clnt_calls 3 ) . +The retry time out and the total time out periods can +be changed using +.Fn clnt_control . +The user may set the size of the send and receive +buffers with the +.Fa sendsz +and +.Fa recvsz +arguments; +values of 0 choose suitable defaults. +This routine returns +.Dv NULL +if it fails. +.It Fn clnt_pcreateerror +Print a message to standard error indicating +why a client RPC handle could not be created. +The message is prepended with the string +.Fa s +and a colon, and appended with a newline. +.It Fn clnt_spcreateerror +Like +.Fn clnt_pcreateerror , +except that it returns a string +instead of printing to the standard error. +A newline is not appended to the message in this case. +Warning: +returns a pointer to a buffer that is overwritten +on each call. +.It Fn clnt_raw_create +This routine creates an RPC +client handle for the remote program +.Fa prognum +and version +.Fa versnum . +The transport used to pass messages to the service is +a buffer within the process's address space, +so the corresponding RPC +server should live in the same address space; +(see +.Fn svc_raw_create +in +.Xr rpc_svc_create 3 ) . +This allows simulation of RPC and measurement of +RPC overheads, such as round trip times, +without any kernel or networking interference. +This routine returns +.Dv NULL +if it fails. +The +.Fn clnt_raw_create +function +should be called after +.Fn svc_raw_create . +.It Fn clnt_tli_create +This routine creates an RPC +client handle for the remote program +.Fa prognum +and version +.Fa versnum . +The remote program is located at address +.Fa svcaddr . +If +.Fa svcaddr +is +.Dv NULL +and it is connection-oriented, it is assumed that the file descriptor +is connected. +For connectionless transports, if +.Fa svcaddr +is +.Dv NULL , +.Dv RPC_UNKNOWNADDR +error is set. +The +.Fa fildes +argument +is a file descriptor which may be open, bound and connected. +If it is +.Dv RPC_ANYFD , +it opens a file descriptor on the transport specified by +.Fa netconf . +If +.Fa fildes +is +.Dv RPC_ANYFD +and +.Fa netconf +is +.Dv NULL , +a +.Dv RPC_UNKNOWNPROTO +error is set. +If +.Fa fildes +is unbound, then it will attempt to bind the descriptor. +The user may specify the size of the buffers with the +.Fa sendsz +and +.Fa recvsz +arguments; +values of 0 choose suitable defaults. +Depending upon the type of the transport (connection-oriented +or connectionless), +.Fn clnt_tli_create +calls appropriate client creation routines. +This routine returns +.Dv NULL +if it fails. +The +.Fn clnt_pcreateerror +routine can be used to print the reason for failure. +The remote rpcbind +service (see +.Xr rpcbind 8 ) +is not consulted for the address of the remote +service. +.It Fn clnt_tp_create +Like +.Fn clnt_create +except +.Fn clnt_tp_create +tries only one transport specified through +.Fa netconf . +The +.Fn clnt_tp_create +function +creates a client handle for the program +.Fa prognum , +the version +.Fa versnum , +and for the transport specified by +.Fa netconf . +Default options are set, +which can be changed using +.Fn clnt_control +calls. +The remote rpcbind service on the host +.Fa host +is consulted for the address of the remote service. +This routine returns +.Dv NULL +if it fails. +The +.Fn clnt_pcreateerror +routine can be used to print the reason for failure. +.It Fn clnt_tp_create_timed +Like +.Fn clnt_tp_create +except +.Fn clnt_tp_create_timed +has the extra argument +.Fa timeout +which specifies the maximum time allowed for +the creation attempt to succeed. +In all other respects, the +.Fn clnt_tp_create_timed +call behaves exactly like the +.Fn clnt_tp_create +call. +.It Fn clnt_vc_create +This routine creates an RPC +client for the remote program +.Fa prognum +and version +.Fa versnum ; +the client uses a connection-oriented transport. +The remote program is located at address +.Fa svcaddr . +The +.Fa fildes +argument +is an open and bound file descriptor. +The user may specify the size of the send and receive buffers +with the +.Fa sendsz +and +.Fa recvsz +arguments; +values of 0 choose suitable defaults. +This routine returns +.Dv NULL +if it fails. +The address +.Fa svcaddr +should not be +.Dv NULL +and should point to the actual address of the remote program. +The +.Fn clnt_vc_create +function +does not consult the remote rpcbind service for this information. +.It Xo +.Vt "struct rpc_createerr" Va rpc_createerr ; +.Xc +A global variable whose value is set by any RPC +client handle creation routine +that fails. +It is used by the routine +.Fn clnt_pcreateerror +to print the reason for the failure. +.El +.Sh SEE ALSO +.Xr rpc 3 , +.Xr rpc_clnt_auth 3 , +.Xr rpc_clnt_calls 3 , +.Xr rpcbind 8 diff --git a/lib/libc/rpc/rpc_secure.3 b/lib/libc/rpc/rpc_secure.3 new file mode 100644 index 0000000..828ce87 --- /dev/null +++ b/lib/libc/rpc/rpc_secure.3 @@ -0,0 +1,287 @@ +.\" @(#)rpc_secure.3n 2.1 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpc_secure.3 131504 2004-07-02 23:52:20Z ru $ +.\" +.Dd February 16, 1988 +.Dt RPC 3 +.Os +.Sh NAME +.Nm rpc_secure +.Nd library routines for secure remote procedure calls +.Sh SYNOPSIS +.In rpc/rpc.h +.Ft AUTH * +.Fo authdes_create +.Fa "char *name" +.Fa "unsigned window" +.Fa "struct sockaddr *addr" +.Fa "des_block *ckey" +.Fc +.Ft int +.Fn authdes_getucred "struct authdes_cred *adc" "uid_t *uid" "gid_t *gid" "int *grouplen" "gid_t *groups" +.Ft int +.Fn getnetname "char *name" +.Ft int +.Fn host2netname "char *name" "const char *host" "const char *domain" +.Ft int +.Fn key_decryptsession "const char *remotename" "des_block *deskey" +.Ft int +.Fn key_encryptsession "const char *remotename" "des_block *deskey" +.Ft int +.Fn key_gendes "des_block *deskey" +.Ft int +.Fn key_setsecret "const char *key" +.Ft int +.Fn netname2host "char *name" "char *host" "int hostlen" +.Ft int +.Fn netname2user "char *name" "uid_t *uidp" "gid_t *gidp" "int *gidlenp" "gid_t *gidlist" +.Ft int +.Fn user2netname "char *name" "const uid_t uid" "const char *domain" +.Sh DESCRIPTION +These routines are part of the +.Tn RPC +library. +They implement +.Tn DES +Authentication. +See +.Xr rpc 3 +for further details about +.Tn RPC . +.Pp +The +.Fn authdes_create +is the first of two routines which interface to the +.Tn RPC +secure authentication system, known as +.Tn DES +authentication. +The second is +.Fn authdes_getucred , +below. +.Pp +Note: the keyserver daemon +.Xr keyserv 8 +must be running for the +.Tn DES +authentication system to work. +.Pp +The +.Fn authdes_create +function, +used on the client side, returns an authentication handle that +will enable the use of the secure authentication system. +The first argument +.Fa name +is the network name, or +.Fa netname , +of the owner of the server process. +This field usually +represents a +.Fa hostname +derived from the utility routine +.Fn host2netname , +but could also represent a user name using +.Fn user2netname . +The second field is window on the validity of +the client credential, given in seconds. +A small +window is more secure than a large one, but choosing +too small of a window will increase the frequency of +resynchronizations because of clock drift. +The third +argument +.Fa addr +is optional. +If it is +.Dv NULL , +then the authentication system will assume +that the local clock is always in sync with the server's +clock, and will not attempt resynchronizations. +If an address +is supplied, however, then the system will use the address +for consulting the remote time service whenever +resynchronization +is required. +This argument is usually the +address of the +.Tn RPC +server itself. +The final argument +.Fa ckey +is also optional. +If it is +.Dv NULL , +then the authentication system will +generate a random +.Tn DES +key to be used for the encryption of credentials. +If it is supplied, however, then it will be used instead. +.Pp +The +.Fn authdes_getucred +function, +the second of the two +.Tn DES +authentication routines, +is used on the server side for converting a +.Tn DES +credential, which is +operating system independent, into a +.Ux +credential. +This routine differs from utility routine +.Fn netname2user +in that +.Fn authdes_getucred +pulls its information from a cache, and does not have to do a +Yellow Pages lookup every time it is called to get its information. +.Pp +The +.Fn getnetname +function +installs the unique, operating-system independent netname of +the +caller in the fixed-length array +.Fa name . +Returns +.Dv TRUE +if it succeeds and +.Dv FALSE +if it fails. +.Pp +The +.Fn host2netname +function +converts from a domain-specific hostname to an +operating-system independent netname. +Returns +.Dv TRUE +if it succeeds and +.Dv FALSE +if it fails. +Inverse of +.Fn netname2host . +.Pp +The +.Fn key_decryptsession +function +is an interface to the keyserver daemon, which is associated +with +.Tn RPC Ns 's +secure authentication system +.Tn ( DES +authentication). +User programs rarely need to call it, or its associated routines +.Fn key_encryptsession , +.Fn key_gendes +and +.Fn key_setsecret . +System commands such as +.Xr login 1 +and the +.Tn RPC +library are the main clients of these four routines. +.Pp +The +.Fn key_decryptsession +function +takes a server netname and a +.Tn DES +key, and decrypts the key by +using the public key of the server and the secret key +associated with the effective uid of the calling process. +It +is the inverse of +.Fn key_encryptsession . +.Pp +The +.Fn key_encryptsession +function +is a keyserver interface routine. +It +takes a server netname and a des key, and encrypts +it using the public key of the server and the secret key +associated with the effective uid of the calling process. +It +is the inverse of +.Fn key_decryptsession . +.Pp +The +.Fn key_gendes +function +is a keyserver interface routine. +It +is used to ask the keyserver for a secure conversation key. +Choosing one +.Qq random +is usually not good enough, +because +the common ways of choosing random numbers, such as using the +current time, are very easy to guess. +.Pp +The +.Fn key_setsecret +function +is a keyserver interface routine. +It is used to set the key for +the effective +.Fa uid +of the calling process. +.Pp +The +.Fn netname2host +function +converts from an operating-system independent netname to a +domain-specific hostname. +Returns +.Dv TRUE +if it succeeds and +.Dv FALSE +if it fails. +Inverse of +.Fn host2netname . +.Pp +The +.Fn netname2user +function +converts from an operating-system independent netname to a +domain-specific user ID. +Returns +.Dv TRUE +if it succeeds and +.Dv FALSE +if it fails. +Inverse of +.Fn user2netname . +.Pp +The +.Fn user2netname +function +converts from a domain-specific username to an operating-system +independent netname. +Returns +.Dv TRUE +if it succeeds and +.Dv FALSE +if it fails. +Inverse of +.Fn netname2user . +.Sh SEE ALSO +.Xr rpc 3 , +.Xr xdr 3 , +.Xr keyserv 8 +.Pp +The following manuals: +.Rs +.%B Remote Procedure Calls: Protocol Specification +.Re +.Rs +.%B Remote Procedure Call Programming Guide +.Re +.Rs +.%B Rpcgen Programming Guide +.Re +.Rs +.%B RPC: Remote Procedure Call Protocol Specification +.%O RFC1050, Sun Microsystems Inc., USC-ISI +.Re diff --git a/lib/libc/rpc/rpc_soc.3 b/lib/libc/rpc/rpc_soc.3 new file mode 100644 index 0000000..13df29a --- /dev/null +++ b/lib/libc/rpc/rpc_soc.3 @@ -0,0 +1,1721 @@ +.\" @(#)rpc.3n 2.4 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI +.\" $NetBSD: rpc_soc.3,v 1.2 2000/06/07 13:39:43 simonb Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpc_soc.3 241181 2012-10-04 04:15:18Z pfg $ +.\" +.Dd February 16, 1988 +.Dt RPC_SOC 3 +.Os +.Sh NAME +.Nm rpc_soc , +.Nm auth_destroy , +.Nm authnone_create , +.Nm authunix_create , +.Nm authunix_create_default , +.Nm callrpc , +.Nm clnt_broadcast , +.Nm clnt_call , +.Nm clnt_control , +.Nm clnt_create , +.Nm clnt_destroy , +.Nm clnt_freeres , +.Nm clnt_geterr , +.Nm clnt_pcreateerror , +.Nm clnt_perrno , +.Nm clnt_perror , +.Nm clnt_spcreateerror , +.Nm clnt_sperrno , +.Nm clnt_sperror , +.Nm clntraw_create , +.Nm clnttcp_create , +.Nm clntudp_bufcreate , +.Nm clntudp_create , +.Nm clntunix_create , +.Nm get_myaddress , +.Nm pmap_getmaps , +.Nm pmap_getport , +.Nm pmap_rmtcall , +.Nm pmap_set , +.Nm pmap_unset , +.Nm registerrpc , +.Nm rpc_createerr , +.Nm svc_destroy , +.Nm svc_fds , +.Nm svc_fdset , +.Nm svc_getargs , +.Nm svc_getcaller , +.Nm svc_getreq , +.Nm svc_getreqset , +.Nm svc_register , +.Nm svc_run , +.Nm svc_sendreply , +.Nm svc_unregister , +.Nm svcerr_auth , +.Nm svcerr_decode , +.Nm svcerr_noproc , +.Nm svcerr_noprog , +.Nm svcerr_progvers , +.Nm svcerr_systemerr , +.Nm svcerr_weakauth , +.Nm svcfd_create , +.Nm svcunixfd_create , +.Nm svcraw_create , +.Nm svcunix_create , +.Nm xdr_accepted_reply , +.Nm xdr_authunix_parms , +.Nm xdr_callhdr , +.Nm xdr_callmsg , +.Nm xdr_opaque_auth , +.Nm xdr_pmap , +.Nm xdr_pmaplist , +.Nm xdr_rejected_reply , +.Nm xdr_replymsg , +.Nm xprt_register , +.Nm xprt_unregister +.Nd "library routines for remote procedure calls" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/rpc.h +.Pp +See +.Sx DESCRIPTION +for function declarations. +.Sh DESCRIPTION +.Bf -symbolic +The +.Fn svc_* +and +.Fn clnt_* +functions described in this page are the old, TS-RPC +interface to the XDR and RPC library, and exist for backward compatibility. +The new interface is described in the pages +referenced from +.Xr rpc 3 . +.Ef +.Pp +These routines allow C programs to make procedure +calls on other machines across the network. +First, the client calls a procedure to send a +data packet to the server. +Upon receipt of the packet, the server calls a dispatch routine +to perform the requested service, and then sends back a +reply. +Finally, the procedure call returns to the client. +.Pp +Routines that are used for Secure +.Tn RPC ( DES +authentication) are described in +.Xr rpc_secure 3 . +Secure +.Tn RPC +can be used only if +.Tn DES +encryption is available. +.Pp +.Bl -tag -width indent -compact +.It Xo +.Ft void +.Xc +.It Xo +.Fn auth_destroy "AUTH *auth" +.Xc +.Pp +A macro that destroys the authentication information associated with +.Fa auth . +Destruction usually involves deallocation of private data +structures. +The use of +.Fa auth +is undefined after calling +.Fn auth_destroy . +.Pp +.It Xo +.Ft "AUTH *" +.Xc +.It Xo +.Fn authnone_create +.Xc +.Pp +Create and return an +.Tn RPC +authentication handle that passes nonusable authentication +information with each remote procedure call. +This is the +default authentication used by +.Tn RPC . +.Pp +.It Xo +.Ft "AUTH *" +.Xc +.It Xo +.Fn authunix_create "char *host" "u_int uid" "u_int gid" "int len" "u_int *aup_gids" +.Xc +.Pp +Create and return an +.Tn RPC +authentication handle that contains +.Ux +authentication information. +The +.Fa host +argument +is the name of the machine on which the information was +created; +.Fa uid +is the user's user ID; +.Fa gid +is the user's current group ID; +.Fa len +and +.Fa aup_gids +refer to a counted array of groups to which the user belongs. +It is easy to impersonate a user. +.Pp +.It Xo +.Ft "AUTH *" +.Xc +.It Xo +.Fn authunix_create_default +.Xc +.Pp +Calls +.Fn authunix_create +with the appropriate arguments. +.Pp +.It Xo +.Ft int +.Fo callrpc +.Fa "char *host" +.Fa "u_long prognum" +.Fa "u_long versnum" +.Fa "u_long procnum" +.Fa "xdrproc_t inproc" +.Fa "void *in" +.Fa "xdrproc_t outproc" +.Fa "void *out" +.Fc +.Xc +.Pp +Call the remote procedure associated with +.Fa prognum , +.Fa versnum , +and +.Fa procnum +on the machine +.Fa host . +The +.Fa in +argument +is the address of the procedure's argument(s), and +.Fa out +is the address of where to place the result(s); +.Fa inproc +is used to encode the procedure's arguments, and +.Fa outproc +is used to decode the procedure's results. +This routine returns zero if it succeeds, or the value of +.Vt "enum clnt_stat" +cast to an integer if it fails. +The routine +.Fn clnt_perrno +is handy for translating failure statuses into messages. +.Pp +Warning: calling remote procedures with this routine +uses +.Tn UDP/IP +as a transport; see +.Fn clntudp_create +for restrictions. +You do not have control of timeouts or authentication using +this routine. +.Pp +.It Xo +.Ft "enum clnt_stat" +.Xc +.It Xo +.Fo clnt_broadcast +.Fa "u_long prognum" +.Fa "u_long versnum" +.Fa "u_long procnum" +.Fa "xdrproc_t inproc" +.Fa "char *in" +.Fa "xdrproc_t outproc" +.Fa "char *out" +.Fa "bool_t (*eachresult)(caddr_t, struct sockaddr_in *)" +.Fc +.Xc +.Pp +Like +.Fn callrpc , +except the call message is broadcast to all locally +connected broadcast nets. +Each time it receives a +response, this routine calls +.Fn eachresult , +whose form is: +.Bd -ragged -offset indent +.Ft bool_t +.Fn eachresult "caddr_t out" "struct sockaddr_in *addr" +.Ed +.Pp +where +.Fa out +is the same as +.Fa out +passed to +.Fn clnt_broadcast , +except that the remote procedure's output is decoded there; +.Fa addr +points to the address of the machine that sent the results. +If +.Fn eachresult +returns zero, +.Fn clnt_broadcast +waits for more replies; otherwise it returns with appropriate +status. +.Pp +Warning: broadcast sockets are limited in size to the +maximum transfer unit of the data link. +For ethernet, +this value is 1500 bytes. +.Pp +.It Xo +.Ft "enum clnt_stat" +.Xc +.It Xo +.Fo clnt_call +.Fa "CLIENT *clnt" +.Fa "u_long procnum" +.Fa "xdrproc_t inproc" +.Fa "char *in" +.Fa "xdrproc_t outproc" +.Fa "char *out" +.Fa "struct timeval tout" +.Fc +.Xc +.Pp +A macro that calls the remote procedure +.Fa procnum +associated with the client handle, +.Fa clnt , +which is obtained with an +.Tn RPC +client creation routine such as +.Fn clnt_create . +The +.Fa in +argument +is the address of the procedure's argument(s), and +.Fa out +is the address of where to place the result(s); +.Fa inproc +is used to encode the procedure's arguments, and +.Fa outproc +is used to decode the procedure's results; +.Fa tout +is the time allowed for results to come back. +.Pp +.It Xo +.Ft void +.Fn clnt_destroy "CLIENT *clnt" +.Xc +.Pp +A macro that destroys the client's +.Tn RPC +handle. +Destruction usually involves deallocation +of private data structures, including +.Fa clnt +itself. +Use of +.Fa clnt +is undefined after calling +.Fn clnt_destroy . +If the +.Tn RPC +library opened the associated socket, it will close it also. +Otherwise, the socket remains open. +.Pp +.It Xo +.Ft CLIENT * +.Xc +.It Xo +.Fn clnt_create "char *host" "u_long prog" "u_long vers" "char *proto" +.Xc +.Pp +Generic client creation routine. +The +.Fa host +argument +identifies the name of the remote host where the server +is located. +The +.Fa proto +argument +indicates which kind of transport protocol to use. +The +currently supported values for this field are +.Qq Li udp +and +.Qq Li tcp . +Default timeouts are set, but can be modified using +.Fn clnt_control . +.Pp +Warning: Using +.Tn UDP +has its shortcomings. +Since +.Tn UDP Ns \-based +.Tn RPC +messages can only hold up to 8 Kbytes of encoded data, +this transport cannot be used for procedures that take +large arguments or return huge results. +.Pp +.It Xo +.Ft bool_t +.Xc +.It Xo +.Fn clnt_control "CLIENT *cl" "u_int req" "char *info" +.Xc +.Pp +A macro used to change or retrieve various information +about a client object. +The +.Fa req +argument +indicates the type of operation, and +.Fa info +is a pointer to the information. +For both +.Tn UDP +and +.Tn TCP , +the supported values of +.Fa req +and their argument types and what they do are: +.Bl -column "CLSET_RETRY_TIMEOUT" "struct sockaddr_in" +.It Dv CLSET_TIMEOUT Ta +.Vt "struct timeval" Ta "set total timeout" +.It Dv CLGET_TIMEOUT Ta +.Vt "struct timeval" Ta "get total timeout" +.El +.Pp +Note: if you set the timeout using +.Fn clnt_control , +the timeout argument passed to +.Fn clnt_call +will be ignored in all future calls. +.Bl -column "CLSET_RETRY_TIMEOUT" "struct sockaddr_in" +.It Dv CLGET_SERVER_ADDR Ta +.Vt "struct sockaddr_in" Ta "get server's address" +.El +.Pp +The following operations are valid for +.Tn UDP +only: +.Bl -column "CLSET_RETRY_TIMEOUT" "struct sockaddr_in" +.It Dv CLSET_RETRY_TIMEOUT Ta +.Vt "struct timeval" Ta "set the retry timeout" +.It Dv CLGET_RETRY_TIMEOUT Ta +.Vt "struct timeval" Ta "get the retry timeout" +.El +.Pp +The retry timeout is the time that +.Tn "UDP RPC" +waits for the server to reply before +retransmitting the request. +.Pp +.It Xo +.Ft bool_t +.Fn clnt_freeres "CLIENT *clnt" "xdrproc_t outproc" "char *out" +.Xc +.Pp +A macro that frees any data allocated by the +.Tn RPC/XDR +system when it decoded the results of an +.Tn RPC +call. +The +.Fa out +argument +is the address of the results, and +.Fa outproc +is the +.Tn XDR +routine describing the results. +This routine returns one if the results were successfully +freed, +and zero otherwise. +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn clnt_geterr "CLIENT *clnt" "struct rpc_err *errp" +.Xc +.Pp +A macro that copies the error structure out of the client +handle +to the structure at address +.Fa errp . +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn clnt_pcreateerror "char *s" +.Xc +.Pp +prints a message to standard error indicating +why a client +.Tn RPC +handle could not be created. +The message is prepended with string +.Fa s +and a colon. +A newline is appended at the end of the message. +Used when a +.Fn clnt_create , +.Fn clntraw_create , +.Fn clnttcp_create , +or +.Fn clntudp_create +call fails. +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn clnt_perrno "enum clnt_stat stat" +.Xc +.Pp +Print a message to standard error corresponding +to the condition indicated by +.Fa stat . +A newline is appended at the end of the message. +Used after +.Fn callrpc . +.Pp +.It Xo +.Ft void +.Fn clnt_perror "CLIENT *clnt" "char *s" +.Xc +.Pp +Print a message to standard error indicating why an +.Tn RPC +call failed; +.Fa clnt +is the handle used to do the call. +The message is prepended with string +.Fa s +and a colon. +A newline is appended at the end of the message. +Used after +.Fn clnt_call . +.Pp +.It Xo +.Ft "char *" +.Xc +.It Xo +.Fn clnt_spcreateerror "char *s" +.Xc +.Pp +Like +.Fn clnt_pcreateerror , +except that it returns a string +instead of printing to the standard error. +.Pp +Bugs: returns pointer to static data that is overwritten +on each call. +.Pp +.It Xo +.Ft "char *" +.Xc +.It Xo +.Fn clnt_sperrno "enum clnt_stat stat" +.Xc +.Pp +Take the same arguments as +.Fn clnt_perrno , +but instead of sending a message to the standard error +indicating why an +.Tn RPC +call failed, return a pointer to a string which contains +the message. +.Pp +The +.Fn clnt_sperrno +function +is used instead of +.Fn clnt_perrno +if the program does not have a standard error (as a program +running as a server quite likely does not), or if the +programmer +does not want the message to be output with +.Fn printf , +or if a message format different from that supported by +.Fn clnt_perrno +is to be used. +.Pp +Note: unlike +.Fn clnt_sperror +and +.Fn clnt_spcreateerror , +.Fn clnt_sperrno +returns pointer to static data, but the +result will not get overwritten on each call. +.Pp +.It Xo +.Ft "char *" +.Xc +.It Xo +.Fn clnt_sperror "CLIENT *rpch" "char *s" +.Xc +.Pp +Like +.Fn clnt_perror , +except that (like +.Fn clnt_sperrno ) +it returns a string instead of printing to standard error. +.Pp +Bugs: returns pointer to static data that is overwritten +on each call. +.Pp +.It Xo +.Ft "CLIENT *" +.Xc +.It Xo +.Fn clntraw_create "u_long prognum" "u_long versnum" +.Xc +.Pp +This routine creates a toy +.Tn RPC +client for the remote program +.Fa prognum , +version +.Fa versnum . +The transport used to pass messages to the service is +actually a buffer within the process's address space, so the +corresponding +.Tn RPC +server should live in the same address space; see +.Fn svcraw_create . +This allows simulation of +.Tn RPC +and acquisition of +.Tn RPC +overheads, such as round trip times, without any +kernel interference. +This routine returns +.Dv NULL +if it fails. +.Pp +.It Xo +.Ft "CLIENT *" +.Xc +.It Xo +.Fo clnttcp_create +.Fa "struct sockaddr_in *addr" +.Fa "u_long prognum" +.Fa "u_long versnum" +.Fa "int *sockp" +.Fa "u_int sendsz" +.Fa "u_int recvsz" +.Fc +.Xc +.Pp +This routine creates an +.Tn RPC +client for the remote program +.Fa prognum , +version +.Fa versnum ; +the client uses +.Tn TCP/IP +as a transport. +The remote program is located at Internet +address +.Fa addr . +If +.Fa addr\->sin_port +is zero, then it is set to the actual port that the remote +program is listening on (the remote +.Xr rpcbind 8 +service is consulted for this information). +The +.Fa sockp +argument +is a socket; if it is +.Dv RPC_ANYSOCK , +then this routine opens a new one and sets +.Fa sockp . +Since +.Tn TCP Ns \-based +.Tn RPC +uses buffered +.Tn I/O , +the user may specify the size of the send and receive buffers +with the +.Fa sendsz +and +.Fa recvsz +arguments; +values of zero choose suitable defaults. +This routine returns +.Dv NULL +if it fails. +.Pp +.It Xo +.Ft "CLIENT *" +.Xc +.It Xo +.Fo clntudp_create +.Fa "struct sockaddr_in *addr" +.Fa "u_long prognum" +.Fa "u_long versnum" +.Fa "struct timeval wait" +.Fa "int *sockp" +.Fc +.Xc +.Pp +This routine creates an +.Tn RPC +client for the remote program +.Fa prognum , +version +.Fa versnum ; +the client uses +.Tn UDP/IP +as a transport. +The remote program is located at Internet +address +.Fa addr . +If +.Fa addr\->sin_port +is zero, then it is set to actual port that the remote +program is listening on (the remote +.Xr rpcbind 8 +service is consulted for this information). +The +.Fa sockp +argument +is a socket; if it is +.Dv RPC_ANYSOCK , +then this routine opens a new one and sets +.Fa sockp . +The +.Tn UDP +transport resends the call message in intervals of +.Fa wait +time until a response is received or until the call times +out. +The total time for the call to time out is specified by +.Fn clnt_call . +.Pp +Warning: since +.Tn UDP Ns \-based +.Tn RPC +messages can only hold up to 8 Kbytes +of encoded data, this transport cannot be used for procedures +that take large arguments or return huge results. +.Pp +.It Xo +.Ft "CLIENT *" +.Xc +.It Xo +.Fo clntudp_bufcreate +.Fa "struct sockaddr_in *addr" +.Fa "u_long prognum" +.Fa "u_long versnum" +.Fa "struct timeval wait" +.Fa "int *sockp" +.Fa "unsigned int sendsize" +.Fa "unsigned int recosize" +.Fc +.Xc +.Pp +This routine creates an +.Tn RPC +client for the remote program +.Fa prognum , +on +.Fa versnum ; +the client uses +.Tn UDP/IP +as a transport. +The remote program is located at Internet +address +.Fa addr . +If +.Fa addr\->sin_port +is zero, then it is set to actual port that the remote +program is listening on (the remote +.Xr rpcbind 8 +service is consulted for this information). +The +.Fa sockp +argument +is a socket; if it is +.Dv RPC_ANYSOCK , +then this routine opens a new one and sets +.Fa sockp . +The +.Tn UDP +transport resends the call message in intervals of +.Fa wait +time until a response is received or until the call times +out. +The total time for the call to time out is specified by +.Fn clnt_call . +.Pp +This allows the user to specify the maximum packet size +for sending and receiving +.Tn UDP Ns \-based +.Tn RPC +messages. +.Pp +.It Xo +.Ft "CLIENT *" +.Xc +.It Xo +.Fo clntunix_create +.Fa "struct sockaddr_un *raddr" +.Fa "u_long prognum" +.Fa "u_long versnum" +.Fa "int *sockp" +.Fa "u_int sendsz" +.Fa "u_int recvsz" +.Fc +.Xc +.Pp +This routine creates an +.Tn RPC +client for the local +program +.Fa prognum , +version +.Fa versnum ; +the client uses +.Ux Ns -domain +sockets as a transport. +The local program is located at the +.Fa *raddr . +The +.Fa sockp +argument +is a socket; if it is +.Dv RPC_ANYSOCK , +then this routine opens a new one and sets +.Fa sockp . +Since +.Ux Ns -based +.Tn RPC +uses buffered +.Tn I/O , +the user may specify the size of the send and receive buffers +with the +.Fa sendsz +and +.Fa recvsz +arguments; +values of zero choose suitable defaults. +This routine returns +.Dv NULL +if it fails. +.Pp +.It Xo +.Ft int +.Xc +.It Xo +.Fn get_myaddress "struct sockaddr_in *addr" +.Xc +.Pp +Stuff the machine's +.Tn IP +address into +.Fa addr , +without consulting the library routines that deal with +.Pa /etc/hosts . +The port number is always set to +.Fn htons PMAPPORT . +Returns zero on success, non-zero on failure. +.Pp +.It Xo +.Ft "struct pmaplist *" +.Xc +.It Xo +.Fn pmap_getmaps "struct sockaddr_in *addr" +.Xc +.Pp +A user interface to the +.Xr rpcbind 8 +service, which returns a list of the current +.Tn RPC +program\-to\-port mappings +on the host located at +.Tn IP +address +.Fa addr . +This routine can return +.Dv NULL . +The command +.Dq Nm rpcinfo Fl p +uses this routine. +.Pp +.It Xo +.Ft u_short +.Xc +.It Xo +.Fo pmap_getport +.Fa "struct sockaddr_in *addr" +.Fa "u_long prognum" +.Fa "u_long versnum" +.Fa "u_long protocol" +.Fc +.Xc +.Pp +A user interface to the +.Xr rpcbind 8 +service, which returns the port number +on which waits a service that supports program number +.Fa prognum , +version +.Fa versnum , +and speaks the transport protocol associated with +.Fa protocol . +The value of +.Fa protocol +is most likely +.Dv IPPROTO_UDP +or +.Dv IPPROTO_TCP . +A return value of zero means that the mapping does not exist +or that +the +.Tn RPC +system failed to contact the remote +.Xr rpcbind 8 +service. +In the latter case, the global variable +.Va rpc_createerr +contains the +.Tn RPC +status. +.Pp +.It Xo +.Ft "enum clnt_stat" +.Xc +.It Xo +.Fo pmap_rmtcall +.Fa "struct sockaddr_in *addr" +.Fa "u_long prognum" +.Fa "u_long versnum" +.Fa "u_long procnum" +.Fa "xdrproc_t inproc" +.Fa "char *in" +.Fa "xdrproc_t outproc" +.Fa "char *out" +.Fa "struct timeval tout" +.Fa "u_long *portp" +.Fc +.Xc +.Pp +A user interface to the +.Xr rpcbind 8 +service, which instructs +.Xr rpcbind 8 +on the host at +.Tn IP +address +.Fa addr +to make an +.Tn RPC +call on your behalf to a procedure on that host. +The +.Fa portp +argument +will be modified to the program's port number if the +procedure +succeeds. +The definitions of other arguments are discussed +in +.Fn callrpc +and +.Fn clnt_call . +This procedure should be used for a +.Dq ping +and nothing +else. +See also +.Fn clnt_broadcast . +.Pp +.It Xo +.Ft bool_t +.Fn pmap_set "u_long prognum" "u_long versnum" "u_long protocol" "u_short port" +.Xc +.Pp +A user interface to the +.Xr rpcbind 8 +service, which establishes a mapping between the triple +.Pq Fa prognum , versnum , protocol +and +.Fa port +on the machine's +.Xr rpcbind 8 +service. +The value of +.Fa protocol +is most likely +.Dv IPPROTO_UDP +or +.Dv IPPROTO_TCP . +This routine returns one if it succeeds, zero otherwise. +Automatically done by +.Fn svc_register . +.Pp +.It Xo +.Ft bool_t +.Fn pmap_unset "u_long prognum" "u_long versnum" +.Xc +.Pp +A user interface to the +.Xr rpcbind 8 +service, which destroys all mapping between the triple +.Pq Fa prognum , versnum , * +and +.Fa ports +on the machine's +.Xr rpcbind 8 +service. +This routine returns one if it succeeds, zero +otherwise. +.Pp +.It Xo +.Ft bool_t +.Fo registerrpc +.Fa "u_long prognum" +.Fa "u_long versnum" +.Fa "u_long procnum" +.Fa "char *(*procname)(void)" +.Fa "xdrproc_t inproc" +.Fa "xdrproc_t outproc" +.Fc +.Xc +.Pp +Register procedure +.Fa procname +with the +.Tn RPC +service package. +If a request arrives for program +.Fa prognum , +version +.Fa versnum , +and procedure +.Fa procnum , +.Fa procname +is called with a pointer to its argument(s); +.Fa progname +should return a pointer to its static result(s); +.Fa inproc +is used to decode the arguments while +.Fa outproc +is used to encode the results. +This routine returns zero if the registration succeeded, \-1 +otherwise. +.Pp +Warning: remote procedures registered in this form +are accessed using the +.Tn UDP/IP +transport; see +.Fn svcudp_create +for restrictions. +.Pp +.It Xo +.Vt "struct rpc_createerr" rpc_createerr ; +.Xc +.Pp +A global variable whose value is set by any +.Tn RPC +client creation routine +that does not succeed. +Use the routine +.Fn clnt_pcreateerror +to print the reason why. +.Pp +.It Xo +.Ft bool_t +.Fn svc_destroy "SVCXPRT * xprt" +.Xc +.Pp +A macro that destroys the +.Tn RPC +service transport handle, +.Fa xprt . +Destruction usually involves deallocation +of private data structures, including +.Fa xprt +itself. +Use of +.Fa xprt +is undefined after calling this routine. +.Pp +.It Xo +.Vt fd_set svc_fdset ; +.Xc +.Pp +A global variable reflecting the +.Tn RPC +service side's +read file descriptor bit mask; it is suitable as a template argument +to the +.Xr select 2 +system call. +This is only of interest +if a service implementor does not call +.Fn svc_run , +but rather does his own asynchronous event processing. +This variable is read\-only (do not pass its address to +.Xr select 2 ! ) , +yet it may change after calls to +.Fn svc_getreqset +or any creation routines. +As well, note that if the process has descriptor limits +which are extended beyond +.Dv FD_SETSIZE , +this variable will only be usable for the first +.Dv FD_SETSIZE +descriptors. +.Pp +.It Xo +.Vt int svc_fds ; +.Xc +.Pp +Similar to +.Va svc_fdset , +but limited to 32 descriptors. +This +interface is obsoleted by +.Va svc_fdset . +.Pp +.It Xo +.Ft bool_t +.Fn svc_freeargs "SVCXPRT *xprt" "xdrproc_t inproc" "char *in" +.Xc +.Pp +A macro that frees any data allocated by the +.Tn RPC/XDR +system when it decoded the arguments to a service procedure +using +.Fn svc_getargs . +This routine returns 1 if the results were successfully +freed, +and zero otherwise. +.Pp +.It Xo +.Ft bool_t +.Fn svc_getargs "SVCXPRT *xprt" "xdrproc_t inproc" "char *in" +.Xc +.Pp +A macro that decodes the arguments of an +.Tn RPC +request +associated with the +.Tn RPC +service transport handle, +.Fa xprt . +The +.Fa in +argument +is the address where the arguments will be placed; +.Fa inproc +is the +.Tn XDR +routine used to decode the arguments. +This routine returns one if decoding succeeds, and zero +otherwise. +.Pp +.It Xo +.Ft "struct sockaddr_in *" +.Xc +.It Xo +.Fn svc_getcaller "SVCXPRT *xprt" +.Xc +.Pp +The approved way of getting the network address of the caller +of a procedure associated with the +.Tn RPC +service transport handle, +.Fa xprt . +.Pp +.It Xo +.Ft void +.Fn svc_getreqset "fd_set *rdfds" +.Xc +.Pp +This routine is only of interest if a service implementor +does not call +.Fn svc_run , +but instead implements custom asynchronous event processing. +It is called when the +.Xr select 2 +system call has determined that an +.Tn RPC +request has arrived on some +.Tn RPC +socket(s); +.Fa rdfds +is the resultant read file descriptor bit mask. +The routine returns when all sockets associated with the +value of +.Fa rdfds +have been serviced. +.Pp +.It Xo +.Ft void +.Fn svc_getreq "int rdfds" +.Xc +.Pp +Similar to +.Fn svc_getreqset , +but limited to 32 descriptors. +This interface is obsoleted by +.Fn svc_getreqset . +.Pp +.It Xo +.Ft bool_t +.Fo svc_register +.Fa "SVCXPRT *xprt" +.Fa "u_long prognum" +.Fa "u_long versnum" +.Fa "void (*dispatch)(struct svc_req *, SVCXPRT *)" +.Fa "int protocol" +.Fc +.Xc +.Pp +Associates +.Fa prognum +and +.Fa versnum +with the service dispatch procedure, +.Fn dispatch . +If +.Fa protocol +is zero, the service is not registered with the +.Xr rpcbind 8 +service. +If +.Fa protocol +is non-zero, then a mapping of the triple +.Pq Fa prognum , versnum , protocol +to +.Fa xprt\->xp_port +is established with the local +.Xr rpcbind 8 +service (generally +.Fa protocol +is zero, +.Dv IPPROTO_UDP +or +.Dv IPPROTO_TCP ) . +The procedure +.Fn dispatch +has the following form: +.Bd -ragged -offset indent +.Ft bool_t +.Fn dispatch "struct svc_req *request" "SVCXPRT *xprt" +.Ed +.Pp +The +.Fn svc_register +routine returns one if it succeeds, and zero otherwise. +.Pp +.It Xo +.Fn svc_run +.Xc +.Pp +This routine never returns. +It waits for +.Tn RPC +requests to arrive, and calls the appropriate service +procedure using +.Fn svc_getreq +when one arrives. +This procedure is usually waiting for a +.Xr select 2 +system call to return. +.Pp +.It Xo +.Ft bool_t +.Fn svc_sendreply "SVCXPRT *xprt" "xdrproc_t outproc" "char *out" +.Xc +.Pp +Called by an +.Tn RPC +service's dispatch routine to send the results of a +remote procedure call. +The +.Fa xprt +argument +is the request's associated transport handle; +.Fa outproc +is the +.Tn XDR +routine which is used to encode the results; and +.Fa out +is the address of the results. +This routine returns one if it succeeds, zero otherwise. +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn svc_unregister "u_long prognum" "u_long versnum" +.Xc +.Pp +Remove all mapping of the double +.Pq Fa prognum , versnum +to dispatch routines, and of the triple +.Pq Fa prognum , versnum , * +to port number. +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn svcerr_auth "SVCXPRT *xprt" "enum auth_stat why" +.Xc +.Pp +Called by a service dispatch routine that refuses to perform +a remote procedure call due to an authentication error. +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn svcerr_decode "SVCXPRT *xprt" +.Xc +.Pp +Called by a service dispatch routine that cannot successfully +decode its arguments. +See also +.Fn svc_getargs . +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn svcerr_noproc "SVCXPRT *xprt" +.Xc +.Pp +Called by a service dispatch routine that does not implement +the procedure number that the caller requests. +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn svcerr_noprog "SVCXPRT *xprt" +.Xc +.Pp +Called when the desired program is not registered with the +.Tn RPC +package. +Service implementors usually do not need this routine. +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn svcerr_progvers "SVCXPRT *xprt" "u_long low_vers" "u_long high_vers" +.Xc +.Pp +Called when the desired version of a program is not registered +with the +.Tn RPC +package. +Service implementors usually do not need this routine. +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn svcerr_systemerr "SVCXPRT *xprt" +.Xc +.Pp +Called by a service dispatch routine when it detects a system +error +not covered by any particular protocol. +For example, if a service can no longer allocate storage, +it may call this routine. +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn svcerr_weakauth "SVCXPRT *xprt" +.Xc +.Pp +Called by a service dispatch routine that refuses to perform +a remote procedure call due to insufficient +authentication arguments. +The routine calls +.Fn svcerr_auth xprt AUTH_TOOWEAK . +.Pp +.It Xo +.Ft "SVCXPRT *" +.Xc +.It Xo +.Fn svcraw_create void +.Xc +.Pp +This routine creates a toy +.Tn RPC +service transport, to which it returns a pointer. +The transport +is really a buffer within the process's address space, +so the corresponding +.Tn RPC +client should live in the same +address space; +see +.Fn clntraw_create . +This routine allows simulation of +.Tn RPC +and acquisition of +.Tn RPC +overheads (such as round trip times), without any kernel +interference. +This routine returns +.Dv NULL +if it fails. +.Pp +.It Xo +.Ft "SVCXPRT *" +.Xc +.It Xo +.Fn svctcp_create "int sock" "u_int send_buf_size" "u_int recv_buf_size" +.Xc +.Pp +This routine creates a +.Tn TCP/IP Ns \-based +.Tn RPC +service transport, to which it returns a pointer. +The transport is associated with the socket +.Fa sock , +which may be +.Dv RPC_ANYSOCK , +in which case a new socket is created. +If the socket is not bound to a local +.Tn TCP +port, then this routine binds it to an arbitrary port. +Upon completion, +.Fa xprt\->xp_fd +is the transport's socket descriptor, and +.Fa xprt\->xp_port +is the transport's port number. +This routine returns +.Dv NULL +if it fails. +Since +.Tn TCP Ns \-based +.Tn RPC +uses buffered +.Tn I/O , +users may specify the size of buffers; values of zero +choose suitable defaults. +.Pp +.It Xo +.Ft "SVCXPRT *" +.Xc +.It Xo +.Fn svcunix_create "int sock" "u_int send_buf_size" "u_int recv_buf_size" "char *path" +.Xc +.Pp +This routine creates a +.Ux Ns -based +.Tn RPC +service transport, to which it returns a pointer. +The transport is associated with the socket +.Fa sock , +which may be +.Dv RPC_ANYSOCK , +in which case a new socket is created. +The +.Fa *path +argument +is a variable-length file system pathname of +at most 104 characters. +This file is +.Em not +removed when the socket is closed. +The +.Xr unlink 2 +system call must be used to remove the file. +Upon completion, +.Fa xprt\->xp_fd +is the transport's socket descriptor. +This routine returns +.Dv NULL +if it fails. +Since +.Ux Ns -based +.Tn RPC +uses buffered +.Tn I/O , +users may specify the size of buffers; values of zero +choose suitable defaults. +.Pp +.It Xo +.Ft "SVCXPRT *" +.Xc +.It Xo +.Fn svcunixfd_create "int fd" "u_int sendsize" "u_int recvsize" +.Xc +.Pp +Create a service on top of any open descriptor. +The +.Fa sendsize +and +.Fa recvsize +arguments +indicate sizes for the send and receive buffers. +If they are +zero, a reasonable default is chosen. +.Pp +.It Xo +.Ft "SVCXPRT *" +.Xc +.It Xo +.Fn svcfd_create "int fd" "u_int sendsize" "u_int recvsize" +.Xc +.Pp +Create a service on top of any open descriptor. +Typically, +this +descriptor is a connected socket for a stream protocol such +as +.Tn TCP . +The +.Fa sendsize +and +.Fa recvsize +arguments +indicate sizes for the send and receive buffers. +If they are +zero, a reasonable default is chosen. +.Pp +.It Xo +.Ft "SVCXPRT *" +.Xc +.It Xo +.Fn svcudp_bufcreate "int sock" "u_int sendsize" "u_int recvsize" +.Xc +.Pp +This routine creates a +.Tn UDP/IP Ns \-based +.Tn RPC +service transport, to which it returns a pointer. +The transport is associated with the socket +.Fa sock , +which may be +.Dv RPC_ANYSOCK , +in which case a new socket is created. +If the socket is not bound to a local +.Tn UDP +port, then this routine binds it to an arbitrary port. +Upon +completion, +.Fa xprt\->xp_fd +is the transport's socket descriptor, and +.Fa xprt\->xp_port +is the transport's port number. +This routine returns +.Dv NULL +if it fails. +.Pp +This allows the user to specify the maximum packet size for sending and +receiving +.Tn UDP Ns \-based +.Tn RPC +messages. +.Pp +.It Xo +.Ft bool_t +.Fn xdr_accepted_reply "XDR *xdrs" "struct accepted_reply *ar" +.Xc +.Pp +Used for encoding +.Tn RPC +reply messages. +This routine is useful for users who +wish to generate +.Tn RPC Ns \-style +messages without using the +.Tn RPC +package. +.Pp +.It Xo +.Ft bool_t +.Fn xdr_authunix_parms "XDR *xdrs" "struct authunix_parms *aupp" +.Xc +.Pp +Used for describing +.Ux +credentials. +This routine is useful for users +who wish to generate these credentials without using the +.Tn RPC +authentication package. +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Ft bool_t +.Fn xdr_callhdr "XDR *xdrs" "struct rpc_msg *chdr" +.Xc +.Pp +Used for describing +.Tn RPC +call header messages. +This routine is useful for users who wish to generate +.Tn RPC Ns \-style +messages without using the +.Tn RPC +package. +.Pp +.It Xo +.Ft bool_t +.Fn xdr_callmsg "XDR *xdrs" "struct rpc_msg *cmsg" +.Xc +.Pp +Used for describing +.Tn RPC +call messages. +This routine is useful for users who wish to generate +.Tn RPC Ns \-style +messages without using the +.Tn RPC +package. +.Pp +.It Xo +.Ft bool_t +.Fn xdr_opaque_auth "XDR *xdrs" "struct opaque_auth *ap" +.Xc +.Pp +Used for describing +.Tn RPC +authentication information messages. +This routine is useful for users who wish to generate +.Tn RPC Ns \-style +messages without using the +.Tn RPC +package. +.Pp +.It Xo +.Vt struct pmap ; +.Xc +.It Xo +.Ft bool_t +.Fn xdr_pmap "XDR *xdrs" "struct pmap *regs" +.Xc +.Pp +Used for describing arguments to various +.Xr rpcbind 8 +procedures, externally. +This routine is useful for users who wish to generate +these arguments without using the +.Fn pmap_* +interface. +.Pp +.It Xo +.Ft bool_t +.Fn xdr_pmaplist "XDR *xdrs" "struct pmaplist **rp" +.Xc +.Pp +Used for describing a list of port mappings, externally. +This routine is useful for users who wish to generate +these arguments without using the +.Fn pmap_* +interface. +.Pp +.It Xo +.Ft bool_t +.Fn xdr_rejected_reply "XDR *xdrs" "struct rejected_reply *rr" +.Xc +.Pp +Used for describing +.Tn RPC +reply messages. +This routine is useful for users who wish to generate +.Tn RPC Ns \-style +messages without using the +.Tn RPC +package. +.Pp +.It Xo +.Ft bool_t +.Fn xdr_replymsg "XDR *xdrs" "struct rpc_msg *rmsg" +.Xc +.Pp +Used for describing +.Tn RPC +reply messages. +This routine is useful for users who wish to generate +.Tn RPC +style messages without using the +.Tn RPC +package. +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn xprt_register "SVCXPRT *xprt" +.Xc +.Pp +After +.Tn RPC +service transport handles are created, +they should register themselves with the +.Tn RPC +service package. +This routine modifies the global variable +.Va svc_fds . +Service implementors usually do not need this routine. +.Pp +.It Xo +.Ft void +.Xc +.It Xo +.Fn xprt_unregister "SVCXPRT *xprt" +.Xc +.Pp +Before an +.Tn RPC +service transport handle is destroyed, +it should unregister itself with the +.Tn RPC +service package. +This routine modifies the global variable +.Va svc_fds . +Service implementors usually do not need this routine. +.El +.Sh SEE ALSO +.Xr rpc_secure 3 , +.Xr xdr 3 +.Rs +.%T "Remote Procedure Calls: Protocol Specification" +.Re +.Rs +.%T "Remote Procedure Call Programming Guide" +.Re +.Rs +.%T "rpcgen Programming Guide" +.Re +.Rs +.%T "RPC: Remote Procedure Call Protocol Specification" +.%O RFC1050 +.%Q "Sun Microsystems, Inc., USC-ISI" +.Re diff --git a/lib/libc/rpc/rpc_svc_calls.3 b/lib/libc/rpc/rpc_svc_calls.3 new file mode 100644 index 0000000..625245c --- /dev/null +++ b/lib/libc/rpc/rpc_svc_calls.3 @@ -0,0 +1,267 @@ +.\" @(#)rpc_svc_calls.3n 1.28 93/05/10 SMI; from SVr4 +.\" Copyright 1989 AT&T +.\" @(#)rpc_svc_calls 1.5 89/07/25 SMI; +.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. +.\" $NetBSD: rpc_svc_calls.3,v 1.1 2000/06/02 23:11:13 fvdl Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpc_svc_calls.3 152720 2005-11-23 16:44:23Z ru $ +.Dd May 3, 1993 +.Dt RPC_SVC_CALLS 3 +.Os +.Sh NAME +.Nm svc_dg_enablecache , +.Nm svc_exit , +.Nm svc_fdset , +.Nm svc_freeargs , +.Nm svc_getargs , +.Nm svc_getreq_common , +.Nm svc_getreq_poll , +.Nm svc_getreqset , +.Nm svc_getrpccaller , +.Nm svc_pollset , +.Nm svc_run , +.Nm svc_sendreply +.Nd library routines for RPC servers +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/rpc.h +.Ft int +.Fn svc_dg_enablecache "SVCXPRT *xprt" "const unsigned cache_size" +.Ft void +.Fn svc_exit "void" +.Ft bool_t +.Fn svc_freeargs "const SVCXPRT *xprt" "const xdrproc_t inproc" "caddr_t in" +.Ft bool_t +.Fn svc_getargs "const SVCXPRT *xprt" "const xdrproc_t inproc" "caddr_t in" +.Ft void +.Fn svc_getreq_common "const int fd" +.Ft void +.Fn svc_getreq_poll "struct pollfd *pfdp" "const int pollretval" +.Ft void +.Fn svc_getreqset "fd_set * rdfds" +.Ft "struct netbuf *" +.Fn svc_getrpccaller "const SVCXPRT *xprt" +.Ft "struct cmsgcred *" +.Fn __svc_getcallercreds "const SVCXPRT *xprt" +.Vt struct pollfd svc_pollset[FD_SETSIZE]; +.Ft void +.Fn svc_run "void" +.Ft bool_t +.Fn svc_sendreply "SVCXPRT *xprt" "xdrproc_t outproc" "void *out" +.Sh DESCRIPTION +These routines are part of the +RPC +library which allows C language programs to make procedure +calls on other machines across the network. +.Pp +These routines are associated with the server side of the +RPC mechanism. +Some of them are called by the server side dispatch function, +while others +(such as +.Fn svc_run ) +are called when the server is initiated. +.\" .Pp +.\" In the current implementation, the service transport handle, +.\" .Dv SVCXPRT , +.\" contains a single data area for decoding arguments and encoding results. +.\" Therefore, this structure cannot be freely shared between threads that call +.\" functions that do this. +.\" Routines on this page that are affected by this +.\" restriction are marked as unsafe for MT applications. +.Sh Routines +See +.Xr rpc 3 +for the definition of the +.Vt SVCXPRT +data structure. +.Bl -tag -width __svc_getcallercreds() +.It Fn svc_dg_enablecache +This function allocates a duplicate request cache for the +service endpoint +.Fa xprt , +large enough to hold +.Fa cache_size +entries. +Once enabled, there is no way to disable caching. +This routine returns 0 if space necessary for a cache of the given size +was successfully allocated, and 1 otherwise. +.It Fn svc_exit +This function, when called by any of the RPC server procedure or +otherwise, causes +.Fn svc_run +to return. +.Pp +As currently implemented, +.Fn svc_exit +zeroes the +.Va svc_fdset +global variable. +If RPC server activity is to be resumed, +services must be reregistered with the RPC library +either through one of the +.Xr rpc_svc_create 3 +functions, or using +.Fn xprt_register . +The +.Fn svc_exit +function +has global scope and ends all RPC server activity. +.It Xo +.Vt fd_set Va svc_fdset +.Xc +A global variable reflecting the +RPC server's read file descriptor bit mask; it is suitable as an argument +to the +.Xr select 2 +system call. +This is only of interest +if service implementors do not call +.Fn svc_run , +but rather do their own asynchronous event processing. +This variable is read-only (do not pass its address to +.Xr select 2 ! ) , +yet it may change after calls to +.Fn svc_getreqset +or any creation routines. +.It Fn svc_freeargs +A function macro that frees any data allocated by the +RPC/XDR system when it decoded the arguments to a service procedure +using +.Fn svc_getargs . +This routine returns +.Dv TRUE +if the results were successfully +freed, and +.Dv FALSE +otherwise. +.It Fn svc_getargs +A function macro that decodes the arguments of an +RPC request associated with the RPC +service transport handle +.Fa xprt . +The +.Fa in +argument +is the address where the arguments will be placed; +.Fa inproc +is the XDR +routine used to decode the arguments. +This routine returns +.Dv TRUE +if decoding succeeds, and +.Dv FALSE +otherwise. +.It Fn svc_getreq_common +This routine is called to handle a request on the given +file descriptor. +.It Fn svc_getreq_poll +This routine is only of interest if a service implementor +does not call +.Fn svc_run , +but instead implements custom asynchronous event processing. +It is called when +.Xr poll 2 +has determined that an RPC request has arrived on some RPC +file descriptors; +.Fa pollretval +is the return value from +.Xr poll 2 +and +.Fa pfdp +is the array of +.Vt pollfd +structures on which the +.Xr poll 2 +was done. +It is assumed to be an array large enough to +contain the maximal number of descriptors allowed. +.It Fn svc_getreqset +This routine is only of interest if a service implementor +does not call +.Fn svc_run , +but instead implements custom asynchronous event processing. +It is called when +.Xr poll 2 +has determined that an RPC +request has arrived on some RPC file descriptors; +.Fa rdfds +is the resultant read file descriptor bit mask. +The routine returns when all file descriptors +associated with the value of +.Fa rdfds +have been serviced. +.It Fn svc_getrpccaller +The approved way of getting the network address of the caller +of a procedure associated with the +RPC service transport handle +.Fa xprt . +.It Fn __svc_getcallercreds +.Em Warning : +this macro is specific to +.Fx +and thus not portable. +This macro returns a pointer to a +.Vt cmsgcred +structure, defined in +.In sys/socket.h , +identifying the calling client. +This only works if the client is +calling the server over an +.Dv AF_LOCAL +socket. +.It Xo +.Vt struct pollfd Va svc_pollset[FD_SETSIZE] ; +.Xc +.Va svc_pollset +is an array of +.Vt pollfd +structures derived from +.Va svc_fdset[] . +It is suitable as an argument to the +.Xr poll 2 +system call. +The derivation of +.Va svc_pollset +from +.Va svc_fdset +is made in the current implementation in +.Fn svc_run . +Service implementors who do not call +.Fn svc_run +and who wish to use this array must perform this derivation themselves. +.It Fn svc_run +This routine never returns. +It waits for RPC +requests to arrive, and calls the appropriate service +procedure using +.Fn svc_getreq_poll +when one arrives. +This procedure is usually waiting for the +.Xr poll 2 +system call to return. +.It Fn svc_sendreply +Called by an RPC service's dispatch routine to send the results of a +remote procedure call. +The +.Fa xprt +argument +is the request's associated transport handle; +.Fa outproc +is the XDR +routine which is used to encode the results; and +.Fa out +is the address of the results. +This routine returns +.Dv TRUE +if it succeeds, +.Dv FALSE +otherwise. +.El +.Sh SEE ALSO +.Xr poll 2 , +.Xr select 2 , +.Xr rpc 3 , +.Xr rpc_svc_create 3 , +.Xr rpc_svc_err 3 , +.Xr rpc_svc_reg 3 diff --git a/lib/libc/rpc/rpc_svc_create.3 b/lib/libc/rpc/rpc_svc_create.3 new file mode 100644 index 0000000..9327e82 --- /dev/null +++ b/lib/libc/rpc/rpc_svc_create.3 @@ -0,0 +1,337 @@ +.\" @(#)rpc_svc_create.3n 1.26 93/08/26 SMI; from SVr4 +.\" Copyright 1989 AT&T +.\" @(#)rpc_svc_create 1.3 89/06/28 SMI; +.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpc_svc_create.3 119893 2003-09-08 19:57:22Z ru $ +.Dd May 3, 1993 +.Dt RPC_SVC_CREATE 3 +.Os +.Sh NAME +.Nm rpc_svc_create , +.Nm svc_control , +.Nm svc_create , +.Nm svc_destroy , +.Nm svc_dg_create , +.Nm svc_fd_create , +.Nm svc_raw_create , +.Nm svc_tli_create , +.Nm svc_tp_create , +.Nm svc_vc_create +.Nd library routines for the creation of server handles +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/rpc.h +.Ft bool_t +.Fn svc_control "SVCXPRT *svc" "const u_int req" "void *info" +.Ft int +.Fn svc_create "void (*dispatch)(struct svc_req *, SVCXPRT *)" "const rpcprog_t prognum" "const rpcvers_t versnum" "const char *nettype" +.Ft SVCXPRT * +.Fn svc_dg_create "const int fildes" "const u_int sendsz" "const u_int recvsz" +.Ft void +.Fn svc_destroy "SVCXPRT *xprt" +.Ft "SVCXPRT *" +.Fn svc_fd_create "const int fildes" "const u_int sendsz" "const u_int recvsz" +.Ft "SVCXPRT *" +.Fn svc_raw_create "void" +.Ft "SVCXPRT *" +.Fn svc_tli_create "const int fildes" "const struct netconfig *netconf" "const struct t_bind *bindaddr" "const u_int sendsz" "const u_int recvsz" +.Ft "SVCXPRT *" +.Fn svc_tp_create "void (*dispatch)(struct svc_req *, SVCXPRT *)" "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" +.Ft "SVCXPRT *" +.Fn svc_vc_create "const int fildes" "const u_int sendsz" "const u_int recvsz" +.Sh DESCRIPTION +These routines are part of the RPC +library which allows C language programs to make procedure +calls on servers across the network. +These routines deal with the creation of service handles. +Once the handle is created, the server can be invoked by calling +.Fn svc_run . +.Sh Routines +See +.Xr rpc 3 +for the definition of the +.Vt SVCXPRT +data structure. +.Bl -tag -width XXXXX +.It Fn svc_control +A function to change or retrieve various information +about a service object. +The +.Fa req +argument +indicates the type of operation and +.Fa info +is a pointer to the information. +The supported values of +.Fa req , +their argument types, and what they do are: +.Bl -tag -width SVCGET_XID +.It Dv SVCGET_VERSQUIET +If a request is received for a program number +served by this server but the version number +is outside the range registered with the server, +an +.Dv RPC_PROGVERSMISMATCH +error will normally +be returned. +The +.Fa info +argument +should be a pointer to an +integer. +Upon successful completion of the +.Dv SVCGET_VERSQUIET +request, +.Fa *info +contains an +integer which describes the server's current +behavior: 0 indicates normal server behavior +(that is, an +.Dv RPC_PROGVERSMISMATCH +error +will be returned); 1 indicates that the out of +range request will be silently ignored. +.It Dv SVCSET_VERSQUIET +If a request is received for a program number +served by this server but the version number +is outside the range registered with the server, +an +.Dv RPC_PROGVERSMISMATCH +error will normally +be returned. +It is sometimes desirable to +change this behavior. +The +.Fa info +argument +should be a +pointer to an integer which is either 0 +(indicating normal server behavior - an +.Dv RPC_PROGVERSMISMATCH +error will be returned), +or 1 (indicating that the out of range request +should be silently ignored). +.El +.It Fn svc_create +The +.Fn svc_create +function +creates server handles for all the transports +belonging to the class +.Fa nettype . +The +.Fa nettype +argument +defines a class of transports which can be used +for a particular application. +The transports are tried in left to right order in +.Ev NETPATH +variable or in top to bottom order in the netconfig database. +If +.Fa nettype +is +.Dv NULL , +it defaults to +.Qq netpath . +.Pp +The +.Fn svc_create +function +registers itself with the rpcbind +service (see +.Xr rpcbind 8 ) . +The +.Fa dispatch +function +is called when there is a remote procedure call for the given +.Fa prognum +and +.Fa versnum ; +this requires calling +.Fn svc_run +(see +.Fn svc_run +in +.Xr rpc_svc_reg 3 ) . +If +.Fn svc_create +succeeds, it returns the number of server +handles it created, +otherwise it returns 0 and an error message is logged. +.It Fn svc_destroy +A function macro that destroys the RPC +service handle +.Fa xprt . +Destruction usually involves deallocation +of private data structures, +including +.Fa xprt +itself. +Use of +.Fa xprt +is undefined after calling this routine. +.It Fn svc_dg_create +This routine creates a connectionless RPC +service handle, and returns a pointer to it. +This routine returns +.Dv NULL +if it fails, and an error message is logged. +The +.Fa sendsz +and +.Fa recvsz +arguments +are arguments used to specify the size of the buffers. +If they are 0, suitable defaults are chosen. +The file descriptor +.Fa fildes +should be open and bound. +The server is not registered with +.Xr rpcbind 8 . +.Pp +Warning: +since connectionless-based RPC +messages can only hold limited amount of encoded data, +this transport cannot be used for procedures +that take large arguments or return huge results. +.It Fn svc_fd_create +This routine creates a service on top of an open and bound file descriptor, +and returns the handle to it. +Typically, this descriptor is a connected file descriptor for a +connection-oriented transport. +The +.Fa sendsz +and +.Fa recvsz +arguments +indicate sizes for the send and receive buffers. +If they are 0, reasonable defaults are chosen. +This routine returns +.Dv NULL +if it fails, and an error message is logged. +.It Fn svc_raw_create +This routine creates an RPC +service handle and returns a pointer to it. +The transport is really a buffer within the process's +address space, so the corresponding RPC +client should live in the same address space; +(see +.Fn clnt_raw_create +in +.Xr rpc_clnt_create 3 ) . +This routine allows simulation of RPC and acquisition of +RPC overheads (such as round trip times), +without any kernel and networking interference. +This routine returns +.Dv NULL +if it fails, and an error message is logged. +.Pp +Note: +.Fn svc_run +should not be called when the raw interface is being used. +.It Fn svc_tli_create +This routine creates an RPC +server handle, and returns a pointer to it. +The +.Fa fildes +argument +is the file descriptor on which the service is listening. +If +.Fa fildes +is +.Dv RPC_ANYFD , +it opens a file descriptor on the transport specified by +.Fa netconf . +If the file descriptor is unbound and +.Fa bindaddr +is not +.Dv NULL , +.Fa fildes +is bound to the address specified by +.Fa bindaddr , +otherwise +.Fa fildes +is bound to a default address chosen by the transport. +.Pp +Note: the +.Vt t_bind +structure comes from the TLI/XTI SysV interface, which +.Nx +does not use. +The structure is defined in +.In rpc/types.h +for compatibility as: +.Bd -literal +struct t_bind { + struct netbuf addr; /* network address, see rpc(3) */ + unsigned int qlen; /* queue length (for listen(2)) */ +}; +.Ed +.Pp +In the case where the default address is chosen, +the number of outstanding connect requests is set to 8 +for connection-oriented transports. +The user may specify the size of the send and receive buffers +with the arguments +.Fa sendsz +and +.Fa recvsz ; +values of 0 choose suitable defaults. +This routine returns +.Dv NULL +if it fails, +and an error message is logged. +The server is not registered with the +.Xr rpcbind 8 +service. +.It Fn svc_tp_create +The +.Fn svc_tp_create +function +creates a server handle for the network +specified by +.Fa netconf , +and registers itself with the rpcbind service. +The +.Fa dispatch +function +is called when there is a remote procedure call +for the given +.Fa prognum +and +.Fa versnum ; +this requires calling +.Fn svc_run . +The +.Fn svc_tp_create +function +returns the service handle if it succeeds, +otherwise a +.Dv NULL +is returned and an error message is logged. +.It Fn svc_vc_create +This routine creates a connection-oriented RPC +service and returns a pointer to it. +This routine returns +.Dv NULL +if it fails, and an error message is logged. +The users may specify the size of the send and receive buffers +with the arguments +.Fa sendsz +and +.Fa recvsz ; +values of 0 choose suitable defaults. +The file descriptor +.Fa fildes +should be open and bound. +The server is not registered with the +.Xr rpcbind 8 +service. +.El +.Sh SEE ALSO +.Xr rpc 3 , +.Xr rpc_svc_calls 3 , +.Xr rpc_svc_err 3 , +.Xr rpc_svc_reg 3 , +.Xr rpcbind 8 diff --git a/lib/libc/rpc/rpc_svc_err.3 b/lib/libc/rpc/rpc_svc_err.3 new file mode 100644 index 0000000..e60b3e1 --- /dev/null +++ b/lib/libc/rpc/rpc_svc_err.3 @@ -0,0 +1,97 @@ +.\" @(#)rpc_svc_err.3n 1.23 93/08/31 SMI; from SVr4 +.\" Copyright 1989 AT&T +.\" @(#)rpc_svc_err 1.4 89/06/28 SMI; +.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. +.\" $NetBSD: rpc_svc_err.3,v 1.1 2000/06/02 23:11:14 fvdl Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpc_svc_err.3 141580 2005-02-09 18:07:17Z ru $ +.Dd May 3, 1993 +.Dt RPC_SVC_ERR 3 +.Os +.Sh NAME +.Nm rpc_svc_err , +.Nm svcerr_auth , +.Nm svcerr_decode , +.Nm svcerr_noproc , +.Nm svcerr_noprog , +.Nm svcerr_progvers , +.Nm svcerr_systemerr , +.Nm svcerr_weakauth +.Nd library routines for server side remote procedure call errors +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/rpc.h +.Ft void +.Fn svcerr_auth "SVCXPRT *xprt" "enum auth_stat why" +.Ft void +.Fn svcerr_decode "SVCXPRT *xprt" +.Ft void +.Fn svcerr_noproc "SVCXPRT *xprt" +.Ft void +.Fn svcerr_noprog "SVCXPRT *xprt" +.Ft void +.Fn svcerr_progvers "SVCXPRT *xprt" "rpcvers_t low_vers" "rpcvers_t high_vers" +.Ft void +.Fn svcerr_systemerr "SVCXPRT *xprt" +.Ft void +.Fn svcerr_weakauth "SVCXPRT *xprt" +.Sh DESCRIPTION +These routines are part of the RPC +library which allows C language programs to make procedure +calls on other machines across the network. +.Pp +These routines can be called by the server side +dispatch function if there is any error in the +transaction with the client. +.Sh Routines +See +.Xr rpc 3 +for the definition of the +.Vt SVCXPRT +data structure. +.Bl -tag -width XXXXX +.It Fn svcerr_auth +Called by a service dispatch routine that refuses to perform +a remote procedure call due to an authentication error. +.It Fn svcerr_decode +Called by a service dispatch routine that cannot successfully +decode the remote arguments +(see +.Fn svc_getargs +in +.Xr rpc_svc_reg 3 ) . +.It Fn svcerr_noproc +Called by a service dispatch routine that does not implement +the procedure number that the caller requests. +.It Fn svcerr_noprog +Called when the desired program is not registered with the +RPC package. +Service implementors usually do not need this routine. +.It Fn svcerr_progvers +Called when the desired version of a program is not registered with the +RPC package. +The +.Fa low_vers +argument +is the lowest version number, +and +.Fa high_vers +is the highest version number. +Service implementors usually do not need this routine. +.It Fn svcerr_systemerr +Called by a service dispatch routine when it detects a system +error not covered by any particular protocol. +For example, if a service can no longer allocate storage, +it may call this routine. +.It Fn svcerr_weakauth +Called by a service dispatch routine that refuses to perform +a remote procedure call due to insufficient (but correct) +authentication arguments. +The routine calls +.Fn svcerr_auth "xprt" "AUTH_TOOWEAK" . +.El +.Sh SEE ALSO +.Xr rpc 3 , +.Xr rpc_svc_calls 3 , +.Xr rpc_svc_create 3 , +.Xr rpc_svc_reg 3 diff --git a/lib/libc/rpc/rpc_svc_reg.3 b/lib/libc/rpc/rpc_svc_reg.3 new file mode 100644 index 0000000..ec1981f --- /dev/null +++ b/lib/libc/rpc/rpc_svc_reg.3 @@ -0,0 +1,183 @@ +.\" @(#)rpc_svc_reg.3n 1.32 93/08/31 SMI; from SVr4 +.\" Copyright 1989 AT&T +.\" @(#)rpc_svc_call 1.6 89/07/20 SMI; +.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. +.\" $NetBSD: rpc_svc_reg.3,v 1.1 2000/06/02 23:11:14 fvdl Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpc_svc_reg.3 276294 2014-12-27 08:31:52Z joel $ +.Dd May 3, 1993 +.Dt RPC_SVC_REG 3 +.Os +.Sh NAME +.Nm rpc_svc_reg , +.Nm rpc_reg , +.Nm svc_reg , +.Nm svc_unreg , +.Nm svc_auth_reg , +.Nm xprt_register , +.Nm xprt_unregister +.Nd library routines for registering servers +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/rpc.h +.Ft int +.Fn rpc_reg "rpcprog_t prognum" "rpcvers_t versnum" "rpcproc_t procnum" "char *(*procname)()" "xdrproc_t inproc" "xdrproc_t outproc" "char *nettype" +.Ft bool_t +.Fn svc_reg "SVCXPRT *xprt" "const rpcprog_t prognum" "const rpcvers_t versnum" "void (*dispatch)(struct svc_req *, SVCXPRT *)" "const struct netconfig *netconf" +.Ft void +.Fn svc_unreg "const rpcprog_t prognum" "const rpcvers_t versnum" +.Ft int +.Fn svc_auth_reg "int cred_flavor" "enum auth_stat (*handler)(struct svc_req *, struct rpc_msg *)" +.Ft void +.Fn xprt_register "SVCXPRT *xprt" +.Ft void +.Fn xprt_unregister "SVCXPRT *xprt" +.Sh DESCRIPTION +These routines are a part of the RPC +library which allows the RPC +servers to register themselves with rpcbind +(see +.Xr rpcbind 8 ) , +and associate the given program and version +number with the dispatch function. +When the RPC server receives a RPC request, the library invokes the +dispatch routine with the appropriate arguments. +.Sh Routines +See +.Xr rpc 3 +for the definition of the +.Vt SVCXPRT +data structure. +.Bl -tag -width XXXXX +.It Fn rpc_reg +Register program +.Fa prognum , +procedure +.Fa procname , +and version +.Fa versnum +with the RPC +service package. +If a request arrives for program +.Fa prognum , +version +.Fa versnum , +and procedure +.Fa procnum , +.Fa procname +is called with a pointer to its argument(s); +.Fa procname +should return a pointer to its static result(s); +.Fa inproc +is the XDR function used to decode the arguments while +.Fa outproc +is the XDR function used to encode the results. +Procedures are registered on all available transports of the class +.Fa nettype . +See +.Xr rpc 3 . +This routine returns 0 if the registration succeeded, +\-1 otherwise. +.It Fn svc_reg +Associates +.Fa prognum +and +.Fa versnum +with the service dispatch procedure, +.Fa dispatch . +If +.Fa netconf +is +.Dv NULL , +the service is not registered with the +.Xr rpcbind 8 +service. +If +.Fa netconf +is non-zero, +then a mapping of the triple +.Bq Fa prognum , versnum , netconf->nc_netid +to +.Fa xprt->xp_ltaddr +is established with the local rpcbind +service. +.Pp +The +.Fn svc_reg +routine returns 1 if it succeeds, +and 0 otherwise. +.It Fn svc_unreg +Remove from the rpcbind +service, all mappings of the triple +.Bq Fa prognum , versnum , No all-transports +to network address +and all mappings within the RPC service package +of the double +.Bq Fa prognum , versnum +to dispatch routines. +.It Fn svc_auth_reg +Registers the service authentication routine +.Fa handler +with the dispatch mechanism so that it can be +invoked to authenticate RPC requests received +with authentication type +.Fa cred_flavor . +This interface allows developers to add new authentication +types to their RPC applications without needing to modify +the libraries. +Service implementors usually do not need this routine. +.Pp +Typical service application would call +.Fn svc_auth_reg +after registering the service and prior to calling +.Fn svc_run . +When needed to process an RPC credential of type +.Fa cred_flavor , +the +.Fa handler +procedure will be called with two arguments, +.Fa "struct svc_req *rqst" +and +.Fa "struct rpc_msg *msg" , +and is expected to return a valid +.Vt "enum auth_stat" +value. +There is no provision to change or delete an authentication handler +once registered. +.Pp +The +.Fn svc_auth_reg +routine returns 0 if the registration is successful, +1 if +.Fa cred_flavor +already has an authentication handler registered for it, +and \-1 otherwise. +.It Fn xprt_register +After RPC service transport handle +.Fa xprt +is created, it is registered with the RPC +service package. +This routine modifies the global variable +.Va svc_fdset +(see +.Xr rpc_svc_calls 3 ) . +Service implementors usually do not need this routine. +.It Fn xprt_unregister +Before an RPC service transport handle +.Fa xprt +is destroyed, it unregisters itself with the +RPC service package. +This routine modifies the global variable +.Va svc_fdset +(see +.Xr rpc_svc_calls 3 ) . +Service implementors usually do not need this routine. +.El +.Sh SEE ALSO +.Xr select 2 , +.Xr rpc 3 , +.Xr rpc_svc_calls 3 , +.Xr rpc_svc_create 3 , +.Xr rpc_svc_err 3 , +.Xr rpcbind 3 , +.Xr rpcbind 8 diff --git a/lib/libc/rpc/rpc_xdr.3 b/lib/libc/rpc/rpc_xdr.3 new file mode 100644 index 0000000..5c1cb5e --- /dev/null +++ b/lib/libc/rpc/rpc_xdr.3 @@ -0,0 +1,101 @@ +.\" @(#)rpc_xdr.3n 1.24 93/08/31 SMI; from SVr4 +.\" Copyright 1989 AT&T +.\" @(#)rpc_xdr.new 1.1 89/04/06 SMI; +.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved. +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpc_xdr.3 141580 2005-02-09 18:07:17Z ru $ +.Dd May 3, 1993 +.Dt RPC_XDR 3 +.Os +.Sh NAME +.Nm xdr_accepted_reply , +.Nm xdr_authsys_parms , +.Nm xdr_callhdr , +.Nm xdr_callmsg , +.Nm xdr_opaque_auth , +.Nm xdr_rejected_reply , +.Nm xdr_replymsg +.Nd XDR library routines for remote procedure calls +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/rpc.h +.Ft bool_t +.Fn xdr_accepted_reply "XDR *xdrs" "struct accepted_reply *ar" +.Ft bool_t +.Fn xdr_authsys_parms "XDR *xdrs" "struct authsys_parms *aupp" +.Ft bool_t +.Fn xdr_callhdr "XDR *xdrs" "struct rpc_msg *chdr" +.Ft bool_t +.Fn xdr_callmsg "XDR *xdrs" "struct rpc_msg *cmsg" +.Ft bool_t +.Fn xdr_opaque_auth "XDR *xdrs" "struct opaque_auth *ap" +.Ft bool_t +.Fn xdr_rejected_reply "XDR *xdrs" "struct rejected_reply *rr" +.Ft bool_t +.Fn xdr_replymsg "XDR *xdrs" "struct rpc_msg *rmsg" +.Sh DESCRIPTION +These routines are used for describing the +RPC messages in XDR language. +They should normally be used by those who do not +want to use the RPC +package directly. +These routines return +.Dv TRUE +if they succeed, +.Dv FALSE +otherwise. +.Sh Routines +See +.Xr rpc 3 +for the definition of the +.Vt XDR +data structure. +.Bl -tag -width XXXXX +.It Fn xdr_accepted_reply +Used to translate between RPC +reply messages and their external representation. +It includes the status of the RPC +call in the XDR language format. +In the case of success, it also includes the call results. +.It Fn xdr_authsys_parms +Used for describing +.Ux +operating system credentials. +It includes machine-name, uid, gid list, etc. +.It Fn xdr_callhdr +Used for describing +RPC +call header messages. +It encodes the static part of the call message header in the +XDR language format. +It includes information such as transaction +ID, RPC version number, program and version number. +.It Fn xdr_callmsg +Used for describing +RPC call messages. +This includes all the RPC +call information such as transaction +ID, RPC version number, program number, version number, +authentication information, etc. +This is normally used by servers to determine information about the client +RPC call. +.It Fn xdr_opaque_auth +Used for describing RPC +opaque authentication information messages. +.It Fn xdr_rejected_reply +Used for describing RPC reply messages. +It encodes the rejected RPC message in the XDR language format. +The message could be rejected either because of version +number mis-match or because of authentication errors. +.It Fn xdr_replymsg +Used for describing RPC +reply messages. +It translates between the +RPC reply message and its external representation. +This reply could be either an acceptance, +rejection or +.Dv NULL . +.El +.Sh SEE ALSO +.Xr rpc 3 , +.Xr xdr 3 diff --git a/lib/libc/rpc/rpcbind.3 b/lib/libc/rpc/rpcbind.3 new file mode 100644 index 0000000..61ab633 --- /dev/null +++ b/lib/libc/rpc/rpcbind.3 @@ -0,0 +1,194 @@ +.\" @(#)rpcbind.3n 1.25 93/05/07 SMI; from SVr4 +.\" Copyright 1989 AT&T +.\" Copyright (c) 1988 Sun Microsystem's, Inc. - All Right's Reserved. +.\" $NetBSD: rpcbind.3,v 1.2 2000/06/03 18:47:28 fvdl Exp $ +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rpcbind.3 282005 2015-04-26 10:53:50Z bapt $ +.Dd May 7, 1993 +.Dt RPCBIND 3 +.Os +.Sh NAME +.Nm rpcb_getmaps , +.Nm rpcb_getaddr , +.Nm rpcb_gettime , +.Nm rpcb_rmtcall , +.Nm rpcb_set , +.Nm rpcb_unset +.Nd library routines for RPC bind service +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In rpc/rpc.h +.Ft "rpcblist *" +.Fn rpcb_getmaps "const struct netconfig *netconf" "const char *host" +.Ft bool_t +.Fn rpcb_getaddr "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" "struct netbuf *svcaddr" "const char *host" +.Ft bool_t +.Fn rpcb_gettime "const char *host" "time_t * timep" +.Ft "enum clnt_stat" +.Fn rpcb_rmtcall "const struct netconfig *netconf" "const char *host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const rpcproc_t procnum" "const xdrproc_t inproc" "const caddr_t in" "const xdrproc_t outproc" "const caddr_t out" "const struct timeval tout" "const struct netbuf *svcaddr" +.Ft bool_t +.Fn rpcb_set "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" "const struct netbuf *svcaddr" +.Ft bool_t +.Fn rpcb_unset "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf" +.Sh DESCRIPTION +These routines allow client C programs to make procedure +calls to the RPC binder service. +(see +.Xr rpcbind 8 ) +maintains a list of mappings between programs +and their universal addresses. +.Sh Routines +.Bl -tag -width XXXXX +.It Fn rpcb_getmaps +An interface to the rpcbind service, +which returns a list of the current +RPC program-to-address mappings on +.Fa host . +It uses the transport specified through +.Fa netconf +to contact the remote rpcbind +service on +.Fa host . +This routine will return +.Dv NULL , +if the remote rpcbind could not be contacted. +.It Fn rpcb_getaddr +An interface to the rpcbind +service, which finds the address of the service on +.Fa host +that is registered with program number +.Fa prognum , +version +.Fa versnum , +and speaks the transport protocol associated with +.Fa netconf . +The address found is returned in +.Fa svcaddr . +The +.Fa svcaddr +argument +should be preallocated. +This routine returns +.Dv TRUE +if it succeeds. +A return value of +.Dv FALSE +means that the mapping does not exist +or that the RPC +system failed to contact the remote +rpcbind service. +In the latter case, the global variable +.Va rpc_createerr +(see +.Xr rpc_clnt_create 3 ) +contains the +RPC status. +.It Fn rpcb_gettime +This routine returns the time on +.Fa host +in +.Fa timep . +If +.Fa host +is +.Dv NULL , +.Fn rpcb_gettime +returns the time on its own machine. +This routine returns +.Dv TRUE +if it succeeds, +.Dv FALSE +if it fails. +The +.Fn rpcb_gettime +function +can be used to synchronize the time between the +client and the remote server. +.It Fn rpcb_rmtcall +An interface to the rpcbind service, which instructs +rpcbind on +.Fa host +to make an RPC +call on your behalf to a procedure on that host. +The +.Fn netconfig +structure should correspond to a connectionless transport. +The +.Fa svcaddr +argument +will be modified to the server's address if the procedure succeeds +(see +.Fn rpc_call +and +.Fn clnt_call +in +.Xr rpc_clnt_calls 3 +for the definitions of other arguments). +.Pp +This procedure should normally be used for a +.Dq ping +and nothing else. +This routine allows programs to do lookup and call, all in one step. +.Pp +Note: Even if the server is not running +.Fn rpcb_rmtcall +does not return any error messages to the caller. +In such a case, the caller times out. +.Pp +Note: +.Fn rpcb_rmtcall +is only available for connectionless transports. +.It Fn rpcb_set +An interface to the rpcbind +service, which establishes a mapping between the triple +.Bq Fa prognum , versnum , netconf->nc_netid +and +.Fa svcaddr +on the machine's rpcbind +service. +The value of +.Fa nc_netid +must correspond to a network identifier that is defined by the +netconfig database. +This routine returns +.Dv TRUE +if it succeeds, +.Dv FALSE +otherwise. +(See also +.Fn svc_reg +in +.Xr rpc_svc_calls 3 . ) +If there already exists such an entry with rpcbind, +.Fn rpcb_set +will fail. +.It Fn rpcb_unset +An interface to the rpcbind +service, which destroys the mapping between the triple +.Bq Fa prognum , versnum , netconf->nc_netid +and the address on the machine's rpcbind +service. +If +.Fa netconf +is +.Dv NULL , +.Fn rpcb_unset +destroys all mapping between the triple +.Bq Fa prognum , versnum , No all-transports +and the addresses on the machine's rpcbind service. +This routine returns +.Dv TRUE +if it succeeds, +.Dv FALSE +otherwise. +Only the owner of the service or the super-user can destroy the mapping. +(See also +.Fn svc_unreg +in +.Xr rpc_svc_calls 3 . ) +.El +.Sh SEE ALSO +.Xr rpc_clnt_calls 3 , +.Xr rpc_svc_calls 3 , +.Xr rpcbind 8 , +.Xr rpcinfo 8 diff --git a/lib/libc/rpc/rpcsec_gss_stub.c b/lib/libc/rpc/rpcsec_gss_stub.c new file mode 100644 index 0000000..e76e5c2 --- /dev/null +++ b/lib/libc/rpc/rpcsec_gss_stub.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2006 Doug Rabson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: releng/11.1/lib/libc/rpc/rpcsec_gss_stub.c 181344 2008-08-06 14:02:05Z dfr $ + */ + +#include +#include + +bool_t +__rpc_gss_wrap_stub(AUTH *auth, void *header, size_t headerlen, XDR* xdrs, + xdrproc_t xdr_args, void *args_ptr) +{ + + return (FALSE); +} + +bool_t +__rpc_gss_unwrap_stub(AUTH *auth, XDR* xdrs, xdrproc_t xdr_args, void *args_ptr) +{ + + return (FALSE); +} + +__weak_reference(__rpc_gss_wrap_stub, __rpc_gss_wrap); +__weak_reference(__rpc_gss_unwrap_stub, __rpc_gss_unwrap); diff --git a/lib/libc/rpc/rtime.3 b/lib/libc/rpc/rtime.3 new file mode 100644 index 0000000..1c75e61 --- /dev/null +++ b/lib/libc/rpc/rtime.3 @@ -0,0 +1,50 @@ +.\" @(#)rtime.3n 2.1 88/08/08 4.0 RPCSRC; from 1.5 88/02/08 SMI +.\" $FreeBSD: releng/11.1/lib/libc/rpc/rtime.3 108087 2002-12-19 09:40:28Z ru $ +.\" +.Dd November 22, 1987 +.Dt RTIME 3 +.Os +.Sh NAME +.Nm rtime +.Nd "get remote time" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In sys/time.h +.In netinet/in.h +.Ft int +.Fo rtime +.Fa "struct sockaddr_in *addrp" +.Fa "struct timeval *timep" +.Fa "struct timeval *timeout" +.Fc +.Sh DESCRIPTION +The +.Fn rtime +function +consults the Internet Time Server at the address pointed to by +.Fa addrp +and returns the remote time in the +.Vt timeval +struct pointed to by +.Fa timep . +Normally, the +.Tn UDP +protocol is used when consulting the Time Server. +The +.Fa timeout +argument specifies how long the +routine should wait before giving +up when waiting for a reply. +If +.Fa timeout +is specified as +.Dv NULL , +however, the routine will instead use +.Tn TCP +and block until a reply is received from the time server. +.Sh RETURN VALUES +.Rv -std rtime +.Sh SEE ALSO +.Xr timed 8 diff --git a/lib/libc/secure/Makefile.inc b/lib/libc/secure/Makefile.inc new file mode 100644 index 0000000..25d7fba --- /dev/null +++ b/lib/libc/secure/Makefile.inc @@ -0,0 +1,13 @@ +# $FreeBSD: releng/11.1/lib/libc/secure/Makefile.inc 296915 2016-03-15 19:26:32Z emaste $ +# +# libc sources related to security + +.PATH: ${LIBC_SRCTOP}/secure + +# Sources common to both syscall interfaces: +SRCS+= stack_protector.c +.if ${MK_SYMVER} == yes +SRCS+= stack_protector_compat.c +.endif + +SYM_MAPS+= ${LIBC_SRCTOP}/secure/Symbol.map diff --git a/lib/libc/secure/Symbol.map b/lib/libc/secure/Symbol.map new file mode 100644 index 0000000..7b4e53b --- /dev/null +++ b/lib/libc/secure/Symbol.map @@ -0,0 +1,9 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/secure/Symbol.map 286782 2015-08-14 14:58:04Z pfg $ + */ + +FBSD_1.0 { + __chk_fail; + __stack_chk_fail; + __stack_chk_guard; +}; diff --git a/lib/libc/secure/stack_protector.c b/lib/libc/secure/stack_protector.c new file mode 100644 index 0000000..f925c1e --- /dev/null +++ b/lib/libc/secure/stack_protector.c @@ -0,0 +1,116 @@ +/* $NetBSD: stack_protector.c,v 1.4 2006/11/22 17:23:25 christos Exp $ */ +/* $OpenBSD: stack_protector.c,v 1.10 2006/03/31 05:34:44 deraadt Exp $ */ +/* + * Copyright (c) 2002 Hiroaki Etoh, Federico G. Schwindt, and Miodrag Vallat. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/secure/stack_protector.c 298226 2016-04-18 21:05:15Z avos $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include "libc_private.h" + +extern int __sysctl(const int *name, u_int namelen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen); + +long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static void __guard_setup(void) __attribute__((__constructor__, __used__)); +static void __fail(const char *); +void __stack_chk_fail(void); +void __chk_fail(void); + +/*LINTED used*/ +static void +__guard_setup(void) +{ + static const int mib[2] = { CTL_KERN, KERN_ARND }; + size_t len; + int error; + + if (__stack_chk_guard[0] != 0) + return; + error = _elf_aux_info(AT_CANARY, __stack_chk_guard, + sizeof(__stack_chk_guard)); + if (error == 0 && __stack_chk_guard[0] != 0) + return; + + len = sizeof(__stack_chk_guard); + if (__sysctl(mib, nitems(mib), __stack_chk_guard, &len, NULL, 0) == + -1 || len != sizeof(__stack_chk_guard)) { + /* If sysctl was unsuccessful, use the "terminator canary". */ + ((unsigned char *)(void *)__stack_chk_guard)[0] = 0; + ((unsigned char *)(void *)__stack_chk_guard)[1] = 0; + ((unsigned char *)(void *)__stack_chk_guard)[2] = '\n'; + ((unsigned char *)(void *)__stack_chk_guard)[3] = 255; + } +} + +/*ARGSUSED*/ +static void +__fail(const char *msg) +{ + struct sigaction sa; + sigset_t mask; + + /* Immediately block all signal handlers from running code */ + (void)sigfillset(&mask); + (void)sigdelset(&mask, SIGABRT); + (void)sigprocmask(SIG_BLOCK, &mask, NULL); + + /* This may fail on a chroot jail... */ + syslog(LOG_CRIT, "%s", msg); + + (void)memset(&sa, 0, sizeof(sa)); + (void)sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + (void)sigaction(SIGABRT, &sa, NULL); + (void)kill(getpid(), SIGABRT); + _exit(127); +} + +void +__stack_chk_fail(void) +{ + __fail("stack overflow detected; terminated"); +} + +void +__chk_fail(void) +{ + __fail("buffer overflow detected; terminated"); +} + +#ifndef PIC +__weak_reference(__stack_chk_fail, __stack_chk_fail_local); +#endif diff --git a/lib/libc/secure/stack_protector_compat.c b/lib/libc/secure/stack_protector_compat.c new file mode 100644 index 0000000..c0f5dd3 --- /dev/null +++ b/lib/libc/secure/stack_protector_compat.c @@ -0,0 +1,20 @@ +/* + * Written by Alexander Kabaev + * The file is in public domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/secure/stack_protector_compat.c 286760 2015-08-14 03:03:13Z pfg $"); + +void __stack_chk_fail(void); + +#ifdef PIC +void +__stack_chk_fail_local_hidden(void) +{ + + __stack_chk_fail(); +} + +__sym_compat(__stack_chk_fail_local, __stack_chk_fail_local_hidden, FBSD_1.0); +#endif diff --git a/lib/libc/softfloat/Makefile.inc b/lib/libc/softfloat/Makefile.inc new file mode 100644 index 0000000..2631d78 --- /dev/null +++ b/lib/libc/softfloat/Makefile.inc @@ -0,0 +1,32 @@ +# $NetBSD: Makefile.inc,v 1.10 2011/07/04 02:53:15 mrg Exp $ +# $FreeBSD: releng/11.1/lib/libc/softfloat/Makefile.inc 262722 2014-03-04 02:19:39Z marcel $ + +SOFTFLOAT_BITS?=64 +.PATH: ${LIBC_ARCH}/softfloat \ + ${LIBC_SRCTOP}/softfloat/bits${SOFTFLOAT_BITS} \ + ${LIBC_SRCTOP}/softfloat + +CFLAGS+= -I${LIBC_SRCTOP}/${LIBC_ARCH}/softfloat \ + -I${LIBC_SRCTOP}/softfloat +CFLAGS+= -DSOFTFLOAT_FOR_GCC + +SRCS+= softfloat.c + +SRCS+= fpgetround.c fpsetround.c fpgetmask.c fpsetmask.c \ + fpgetsticky.c + +SRCS+= eqsf2.c nesf2.c gtsf2.c gesf2.c ltsf2.c lesf2.c negsf2.c \ + eqdf2.c nedf2.c gtdf2.c gedf2.c ltdf2.c ledf2.c negdf2.c \ + unordsf2.c unorddf2.c + +.if defined(SOFTFLOAT_128) +CFLAGS+= -DFLOAT128 +SRCS+= eqtf2.c netf2.c gttf2.c getf2.c lttf2.c letf2.c negtf2.c +.endif + +.if defined(SOFTFLOAT_X80) +CFLAGS+= -DFLOATX80 +SRCS+= nexf2.c gtxf2.c gexf2.c negxf2.c +.endif + +SYM_MAPS+= ${LIBC_SRCTOP}/softfloat/Symbol.map diff --git a/lib/libc/softfloat/README.NetBSD b/lib/libc/softfloat/README.NetBSD new file mode 100644 index 0000000..302dc94 --- /dev/null +++ b/lib/libc/softfloat/README.NetBSD @@ -0,0 +1,9 @@ +$NetBSD: README.NetBSD,v 1.2 2002/05/21 23:51:05 bjh21 Exp $ +$FreeBSD: releng/11.1/lib/libc/softfloat/README.NetBSD 129203 2004-05-14 12:13:06Z cognet $ + +This is a modified version of part of John Hauser's SoftFloat 2a package. +This version has been heavily modified to support its use with GCC to +implement built-in floating-point operations, but compiling +softfloat.c without SOFTFLOAT_FOR_GCC defined should get you the same +results as from the original. + diff --git a/lib/libc/softfloat/README.txt b/lib/libc/softfloat/README.txt new file mode 100644 index 0000000..c8e9ca3 --- /dev/null +++ b/lib/libc/softfloat/README.txt @@ -0,0 +1,40 @@ +$NetBSD: README.txt,v 1.1 2000/06/06 08:15:02 bjh21 Exp $ +$FreeBSD: releng/11.1/lib/libc/softfloat/README.txt 129203 2004-05-14 12:13:06Z cognet $ + +Package Overview for SoftFloat Release 2a + +John R. Hauser +1998 December 13 + + +SoftFloat is a software implementation of floating-point that conforms to +the IEC/IEEE Standard for Binary Floating-Point Arithmetic. SoftFloat is +distributed in the form of C source code. Compiling the SoftFloat sources +generates two things: + +-- A SoftFloat object file (typically `softfloat.o') containing the complete + set of IEC/IEEE floating-point routines. + +-- A `timesoftfloat' program for evaluating the speed of the SoftFloat + routines. (The SoftFloat module is linked into this program.) + +The SoftFloat package is documented in four text files: + + softfloat.txt Documentation for using the SoftFloat functions. + softfloat-source.txt Documentation for compiling SoftFloat. + softfloat-history.txt History of major changes to SoftFloat. + timesoftfloat.txt Documentation for using `timesoftfloat'. + +Other files in the package comprise the source code for SoftFloat. + +Please be aware that some work is involved in porting this software to other +targets. It is not just a matter of getting `make' to complete without +error messages. I would have written the code that way if I could, but +there are fundamental differences between systems that I can't make go away. +You should not attempt to compile SoftFloat without first reading both +`softfloat.txt' and `softfloat-source.txt'. + +At the time of this writing, the most up-to-date information about +SoftFloat and the latest release can be found at the Web page `http:// +HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html'. + diff --git a/lib/libc/softfloat/Symbol.map b/lib/libc/softfloat/Symbol.map new file mode 100644 index 0000000..cd49cca --- /dev/null +++ b/lib/libc/softfloat/Symbol.map @@ -0,0 +1,41 @@ +/* + * $FreeBSD: releng/11.1/lib/libc/softfloat/Symbol.map 230190 2012-01-16 04:06:56Z das $ + */ + +FBSD_1.0 { + _fpgetmask; + fpgetmask; + _fpgetround; + fpgetround; + _fpgetsticky; + fpgetsticky; + _fpsetmask; + fpsetmask; + _fpsetround; + fpsetround; + _fpsetsticky; + fpsetsticky; +}; + +FBSDprivate_1.0 { + __softfloat_float_exception_flags; + __softfloat_float_exception_mask; + __softfloat_float_rounding_mode; + __softfloat_float_raise; + __eqdf2; + __eqsf2; + __gedf2; + __gesf2; + __gtdf2; + __gtsf2; + __ledf2; + __lesf2; + __ltdf2; + __ltsf2; + __nedf2; + __negdf2; + __negsf2; + __nesf2; + __unorddf2; + __unordsf2; +}; diff --git a/lib/libc/softfloat/bits32/softfloat-macros b/lib/libc/softfloat/bits32/softfloat-macros new file mode 100644 index 0000000..1e562c9 --- /dev/null +++ b/lib/libc/softfloat/bits32/softfloat-macros @@ -0,0 +1,649 @@ +/* $FreeBSD: releng/11.1/lib/libc/softfloat/bits32/softfloat-macros 230363 2012-01-20 06:16:14Z das $ */ + +/* +=============================================================================== + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Shifts `a' right by the number of bits given in `count'. If any nonzero +bits are shifted off, they are ``jammed'' into the least significant bit of +the result by setting the least significant bit to 1. The value of `count' +can be arbitrarily large; in particular, if `count' is greater than 32, the +result will be either 0 or 1, depending on whether `a' is zero or nonzero. +The result is stored in the location pointed to by `zPtr'. +------------------------------------------------------------------------------- +*/ +INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr ) +{ + bits32 z; + + if ( count == 0 ) { + z = a; + } + else if ( count < 32 ) { + z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 ); + } + else { + z = ( a != 0 ); + } + *zPtr = z; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 64-bit value formed by concatenating `a0' and `a1' right by the +number of bits given in `count'. Any bits shifted off are lost. The value +of `count' can be arbitrarily large; in particular, if `count' is greater +than 64, the result will be 0. The result is broken into two 32-bit pieces +which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shift64Right( + bits32 a0, bits32 a1, int16 count, bits32 *z0Ptr, bits32 *z1Ptr ) +{ + bits32 z0, z1; + int8 negCount = ( - count ) & 31; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 32 ) { + z1 = ( a0<>count ); + z0 = a0>>count; + } + else { + z1 = ( count < 64 ) ? ( a0>>( count & 31 ) ) : 0; + z0 = 0; + } + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 64-bit value formed by concatenating `a0' and `a1' right by the +number of bits given in `count'. If any nonzero bits are shifted off, they +are ``jammed'' into the least significant bit of the result by setting the +least significant bit to 1. The value of `count' can be arbitrarily large; +in particular, if `count' is greater than 64, the result will be either 0 +or 1, depending on whether the concatenation of `a0' and `a1' is zero or +nonzero. The result is broken into two 32-bit pieces which are stored at +the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shift64RightJamming( + bits32 a0, bits32 a1, int16 count, bits32 *z0Ptr, bits32 *z1Ptr ) +{ + bits32 z0, z1; + int8 negCount = ( - count ) & 31; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 32 ) { + z1 = ( a0<>count ) | ( ( a1<>count; + } + else { + if ( count == 32 ) { + z1 = a0 | ( a1 != 0 ); + } + else if ( count < 64 ) { + z1 = ( a0>>( count & 31 ) ) | ( ( ( a0<>count ); + z0 = a0>>count; + } + else { + if ( count == 32 ) { + z2 = a1; + z1 = a0; + } + else { + a2 |= a1; + if ( count < 64 ) { + z2 = a0<>( count & 31 ); + } + else { + z2 = ( count == 64 ) ? a0 : ( a0 != 0 ); + z1 = 0; + } + } + z0 = 0; + } + z2 |= ( a2 != 0 ); + } + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 64-bit value formed by concatenating `a0' and `a1' left by the +number of bits given in `count'. Any bits shifted off are lost. The value +of `count' must be less than 32. The result is broken into two 32-bit +pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shortShift64Left( + bits32 a0, bits32 a1, int16 count, bits32 *z0Ptr, bits32 *z1Ptr ) +{ + + *z1Ptr = a1<>( ( - count ) & 31 ) ); + +} + +/* +------------------------------------------------------------------------------- +Shifts the 96-bit value formed by concatenating `a0', `a1', and `a2' left +by the number of bits given in `count'. Any bits shifted off are lost. +The value of `count' must be less than 32. The result is broken into three +32-bit pieces which are stored at the locations pointed to by `z0Ptr', +`z1Ptr', and `z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shortShift96Left( + bits32 a0, + bits32 a1, + bits32 a2, + int16 count, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ) +{ + bits32 z0, z1, z2; + int8 negCount; + + z2 = a2<>negCount; + z0 |= a1>>negCount; + } + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Adds the 64-bit value formed by concatenating `a0' and `a1' to the 64-bit +value formed by concatenating `b0' and `b1'. Addition is modulo 2^64, so +any carry out is lost. The result is broken into two 32-bit pieces which +are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + add64( + bits32 a0, bits32 a1, bits32 b0, bits32 b1, bits32 *z0Ptr, bits32 *z1Ptr ) +{ + bits32 z1; + + z1 = a1 + b1; + *z1Ptr = z1; + *z0Ptr = a0 + b0 + ( z1 < a1 ); + +} + +/* +------------------------------------------------------------------------------- +Adds the 96-bit value formed by concatenating `a0', `a1', and `a2' to the +96-bit value formed by concatenating `b0', `b1', and `b2'. Addition is +modulo 2^96, so any carry out is lost. The result is broken into three +32-bit pieces which are stored at the locations pointed to by `z0Ptr', +`z1Ptr', and `z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + add96( + bits32 a0, + bits32 a1, + bits32 a2, + bits32 b0, + bits32 b1, + bits32 b2, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ) +{ + bits32 z0, z1, z2; + int8 carry0, carry1; + + z2 = a2 + b2; + carry1 = ( z2 < a2 ); + z1 = a1 + b1; + carry0 = ( z1 < a1 ); + z0 = a0 + b0; + z1 += carry1; + z0 += ( z1 < (bits32)carry1 ); + z0 += carry0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Subtracts the 64-bit value formed by concatenating `b0' and `b1' from the +64-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo +2^64, so any borrow out (carry out) is lost. The result is broken into two +32-bit pieces which are stored at the locations pointed to by `z0Ptr' and +`z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + sub64( + bits32 a0, bits32 a1, bits32 b0, bits32 b1, bits32 *z0Ptr, bits32 *z1Ptr ) +{ + + *z1Ptr = a1 - b1; + *z0Ptr = a0 - b0 - ( a1 < b1 ); + +} + +/* +------------------------------------------------------------------------------- +Subtracts the 96-bit value formed by concatenating `b0', `b1', and `b2' from +the 96-bit value formed by concatenating `a0', `a1', and `a2'. Subtraction +is modulo 2^96, so any borrow out (carry out) is lost. The result is broken +into three 32-bit pieces which are stored at the locations pointed to by +`z0Ptr', `z1Ptr', and `z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + sub96( + bits32 a0, + bits32 a1, + bits32 a2, + bits32 b0, + bits32 b1, + bits32 b2, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ) +{ + bits32 z0, z1, z2; + int8 borrow0, borrow1; + + z2 = a2 - b2; + borrow1 = ( a2 < b2 ); + z1 = a1 - b1; + borrow0 = ( a1 < b1 ); + z0 = a0 - b0; + z0 -= ( z1 < (bits32)borrow1 ); + z1 -= borrow1; + z0 -= borrow0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Multiplies `a' by `b' to obtain a 64-bit product. The product is broken +into two 32-bit pieces which are stored at the locations pointed to by +`z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void mul32To64( bits32 a, bits32 b, bits32 *z0Ptr, bits32 *z1Ptr ) +{ + bits16 aHigh, aLow, bHigh, bLow; + bits32 z0, zMiddleA, zMiddleB, z1; + + aLow = a; + aHigh = a>>16; + bLow = b; + bHigh = b>>16; + z1 = ( (bits32) aLow ) * bLow; + zMiddleA = ( (bits32) aLow ) * bHigh; + zMiddleB = ( (bits32) aHigh ) * bLow; + z0 = ( (bits32) aHigh ) * bHigh; + zMiddleA += zMiddleB; + z0 += ( ( (bits32) ( zMiddleA < zMiddleB ) )<<16 ) + ( zMiddleA>>16 ); + zMiddleA <<= 16; + z1 += zMiddleA; + z0 += ( z1 < zMiddleA ); + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Multiplies the 64-bit value formed by concatenating `a0' and `a1' by `b' +to obtain a 96-bit product. The product is broken into three 32-bit pieces +which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and +`z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + mul64By32To96( + bits32 a0, + bits32 a1, + bits32 b, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr + ) +{ + bits32 z0, z1, z2, more1; + + mul32To64( a1, b, &z1, &z2 ); + mul32To64( a0, b, &z0, &more1 ); + add64( z0, more1, 0, z1, &z0, &z1 ); + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Multiplies the 64-bit value formed by concatenating `a0' and `a1' to the +64-bit value formed by concatenating `b0' and `b1' to obtain a 128-bit +product. The product is broken into four 32-bit pieces which are stored at +the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + mul64To128( + bits32 a0, + bits32 a1, + bits32 b0, + bits32 b1, + bits32 *z0Ptr, + bits32 *z1Ptr, + bits32 *z2Ptr, + bits32 *z3Ptr + ) +{ + bits32 z0, z1, z2, z3; + bits32 more1, more2; + + mul32To64( a1, b1, &z2, &z3 ); + mul32To64( a1, b0, &z1, &more2 ); + add64( z1, more2, 0, z2, &z1, &z2 ); + mul32To64( a0, b0, &z0, &more1 ); + add64( z0, more1, 0, z1, &z0, &z1 ); + mul32To64( a0, b1, &more1, &more2 ); + add64( more1, more2, 0, z2, &more1, &z2 ); + add64( z0, z1, 0, more1, &z0, &z1 ); + *z3Ptr = z3; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Returns an approximation to the 32-bit integer quotient obtained by dividing +`b' into the 64-bit value formed by concatenating `a0' and `a1'. The +divisor `b' must be at least 2^31. If q is the exact quotient truncated +toward zero, the approximation returned lies between q and q + 2 inclusive. +If the exact quotient q is larger than 32 bits, the maximum positive 32-bit +unsigned integer is returned. +------------------------------------------------------------------------------- +*/ +static bits32 estimateDiv64To32( bits32 a0, bits32 a1, bits32 b ) +{ + bits32 b0, b1; + bits32 rem0, rem1, term0, term1; + bits32 z; + + if ( b <= a0 ) return 0xFFFFFFFF; + b0 = b>>16; + z = ( b0<<16 <= a0 ) ? 0xFFFF0000 : ( a0 / b0 )<<16; + mul32To64( b, z, &term0, &term1 ); + sub64( a0, a1, term0, term1, &rem0, &rem1 ); + while ( ( (sbits32) rem0 ) < 0 ) { + z -= 0x10000; + b1 = b<<16; + add64( rem0, rem1, b0, b1, &rem0, &rem1 ); + } + rem0 = ( rem0<<16 ) | ( rem1>>16 ); + z |= ( b0<<16 <= rem0 ) ? 0xFFFF : rem0 / b0; + return z; + +} + +#ifndef SOFTFLOAT_FOR_GCC +/* +------------------------------------------------------------------------------- +Returns an approximation to the square root of the 32-bit significand given +by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of +`aExp' (the least significant bit) is 1, the integer returned approximates +2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp' +is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either +case, the approximation returned lies strictly within +/-2 of the exact +value. +------------------------------------------------------------------------------- +*/ +static bits32 estimateSqrt32( int16 aExp, bits32 a ) +{ + static const bits16 sqrtOddAdjustments[] = { + 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, + 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 + }; + static const bits16 sqrtEvenAdjustments[] = { + 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, + 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 + }; + int8 index; + bits32 z; + + index = ( a>>27 ) & 15; + if ( aExp & 1 ) { + z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ]; + z = ( ( a / z )<<14 ) + ( z<<15 ); + a >>= 1; + } + else { + z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ]; + z = a / z + z; + z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); + if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 ); + } + return ( ( estimateDiv64To32( a, 0, z ) )>>1 ) + ( z>>1 ); + +} +#endif + +/* +------------------------------------------------------------------------------- +Returns the number of leading 0 bits before the most-significant 1 bit of +`a'. If `a' is zero, 32 is returned. +------------------------------------------------------------------------------- +*/ +static int8 countLeadingZeros32( bits32 a ) +{ + static const int8 countLeadingZerosHigh[] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + int8 shiftCount; + + shiftCount = 0; + if ( a < 0x10000 ) { + shiftCount += 16; + a <<= 16; + } + if ( a < 0x1000000 ) { + shiftCount += 8; + a <<= 8; + } + shiftCount += countLeadingZerosHigh[ a>>24 ]; + return shiftCount; + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is +equal to the 64-bit value formed by concatenating `b0' and `b1'. Otherwise, +returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag eq64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ) +{ + + return ( a0 == b0 ) && ( a1 == b1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is less +than or equal to the 64-bit value formed by concatenating `b0' and `b1'. +Otherwise, returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag le64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ) +{ + + return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is less +than the 64-bit value formed by concatenating `b0' and `b1'. Otherwise, +returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag lt64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ) +{ + + return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 64-bit value formed by concatenating `a0' and `a1' is not +equal to the 64-bit value formed by concatenating `b0' and `b1'. Otherwise, +returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag ne64( bits32 a0, bits32 a1, bits32 b0, bits32 b1 ) +{ + + return ( a0 != b0 ) || ( a1 != b1 ); + +} + diff --git a/lib/libc/softfloat/bits32/softfloat.c b/lib/libc/softfloat/bits32/softfloat.c new file mode 100644 index 0000000..85039b7 --- /dev/null +++ b/lib/libc/softfloat/bits32/softfloat.c @@ -0,0 +1,2347 @@ +/* $NetBSD: softfloat.c,v 1.1 2002/05/21 23:51:07 bjh21 Exp $ */ + +/* + * This version hacked for use with gcc -msoft-float by bjh21. + * (Mostly a case of #ifdefing out things GCC doesn't need or provides + * itself). + */ + +/* + * Things you may want to define: + * + * SOFTFLOAT_FOR_GCC - build only those functions necessary for GCC (with + * -msoft-float) to work. Include "softfloat-for-gcc.h" to get them + * properly renamed. + */ + +/* + * This differs from the standard bits32/softfloat.c in that float64 + * is defined to be a 64-bit integer rather than a structure. The + * structure is float64s, with translation between the two going via + * float64u. + */ + +/* +=============================================================================== + +This C source file is part of the SoftFloat IEC/IEEE Floating-Point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/bits32/softfloat.c 230189 2012-01-16 04:05:53Z das $"); + +#ifdef SOFTFLOAT_FOR_GCC +#include "softfloat-for-gcc.h" +#endif + +#include "milieu.h" +#include "softfloat.h" + +/* + * Conversions between floats as stored in memory and floats as + * SoftFloat uses them + */ +#ifndef FLOAT64_DEMANGLE +#define FLOAT64_DEMANGLE(a) (a) +#endif +#ifndef FLOAT64_MANGLE +#define FLOAT64_MANGLE(a) (a) +#endif + +/* +------------------------------------------------------------------------------- +Floating-point rounding mode and exception flags. +------------------------------------------------------------------------------- +*/ +int float_rounding_mode = float_round_nearest_even; +int float_exception_flags = 0; + +/* +------------------------------------------------------------------------------- +Primitive arithmetic functions, including multi-word arithmetic, and +division and square root approximations. (Can be specialized to target if +desired.) +------------------------------------------------------------------------------- +*/ +#include "softfloat-macros" + +/* +------------------------------------------------------------------------------- +Functions and definitions to determine: (1) whether tininess for underflow +is detected before or after rounding by default, (2) what (if anything) +happens when exceptions are raised, (3) how signaling NaNs are distinguished +from quiet NaNs, (4) the default generated quiet NaNs, and (4) how NaNs +are propagated from function inputs to output. These details are target- +specific. +------------------------------------------------------------------------------- +*/ +#include "softfloat-specialize" + +/* +------------------------------------------------------------------------------- +Returns the fraction bits of the single-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE bits32 extractFloat32Frac( float32 a ) +{ + + return a & 0x007FFFFF; + +} + +/* +------------------------------------------------------------------------------- +Returns the exponent bits of the single-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE int16 extractFloat32Exp( float32 a ) +{ + + return ( a>>23 ) & 0xFF; + +} + +/* +------------------------------------------------------------------------------- +Returns the sign bit of the single-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE flag extractFloat32Sign( float32 a ) +{ + + return a>>31; + +} + +/* +------------------------------------------------------------------------------- +Normalizes the subnormal single-precision floating-point value represented +by the denormalized significand `aSig'. The normalized exponent and +significand are stored at the locations pointed to by `zExpPtr' and +`zSigPtr', respectively. +------------------------------------------------------------------------------- +*/ +static void + normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros32( aSig ) - 8; + *zSigPtr = aSig<>7; + zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); + if ( zSig == 0 ) zExp = 0; + return packFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent `zExp', +and significand `zSig', and returns the proper single-precision floating- +point value corresponding to the abstract input. This routine is just like +`roundAndPackFloat32' except that `zSig' does not have to be normalized. +Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' +floating-point exponent. +------------------------------------------------------------------------------- +*/ +static float32 + normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros32( zSig ) - 1; + return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<>32 ) & 0x000FFFFF; + +} + +/* +------------------------------------------------------------------------------- +Returns the exponent bits of the double-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE int16 extractFloat64Exp( float64 a ) +{ + + return ( FLOAT64_DEMANGLE(a)>>52 ) & 0x7FF; + +} + +/* +------------------------------------------------------------------------------- +Returns the sign bit of the double-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE flag extractFloat64Sign( float64 a ) +{ + + return FLOAT64_DEMANGLE(a)>>63; + +} + +/* +------------------------------------------------------------------------------- +Normalizes the subnormal double-precision floating-point value represented +by the denormalized significand formed by the concatenation of `aSig0' and +`aSig1'. The normalized exponent is stored at the location pointed to by +`zExpPtr'. The most significant 21 bits of the normalized significand are +stored at the location pointed to by `zSig0Ptr', and the least significant +32 bits of the normalized significand are stored at the location pointed to +by `zSig1Ptr'. +------------------------------------------------------------------------------- +*/ +static void + normalizeFloat64Subnormal( + bits32 aSig0, + bits32 aSig1, + int16 *zExpPtr, + bits32 *zSig0Ptr, + bits32 *zSig1Ptr + ) +{ + int8 shiftCount; + + if ( aSig0 == 0 ) { + shiftCount = countLeadingZeros32( aSig1 ) - 11; + if ( shiftCount < 0 ) { + *zSig0Ptr = aSig1>>( - shiftCount ); + *zSig1Ptr = aSig1<<( shiftCount & 31 ); + } + else { + *zSig0Ptr = aSig1<>( - shiftCount ); + } + if ( aSigExtra ) float_exception_flags |= float_flag_inexact; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + if ( (sbits32) aSigExtra < 0 ) { + ++z; + if ( (bits32) ( aSigExtra<<1 ) == 0 ) z &= ~1; + } + if ( aSign ) z = - z; + } + else { + aSigExtra = ( aSigExtra != 0 ); + if ( aSign ) { + z += ( roundingMode == float_round_down ) & aSigExtra; + z = - z; + } + else { + z += ( roundingMode == float_round_up ) & aSigExtra; + } + } + } + return z; + +} +#endif + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic, except that the conversion is always rounded toward zero. +If `a' is a NaN, the largest positive integer is returned. Otherwise, if +the conversion overflows, the largest integer with the same sign as `a' is +returned. +------------------------------------------------------------------------------- +*/ +int32 float32_to_int32_round_to_zero( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + int32 z; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = aExp - 0x9E; + if ( 0 <= shiftCount ) { + if ( a != 0xCF000000 ) { + float_raise( float_flag_invalid ); + if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF; + } + return (sbits32) 0x80000000; + } + else if ( aExp <= 0x7E ) { + if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig = ( aSig | 0x00800000 )<<8; + z = aSig>>( - shiftCount ); + if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the double-precision floating-point format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float32_to_float64( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig, zSig0, zSig1; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) ); + return packFloat64( aSign, 0x7FF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( aSign, 0, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + shift64Right( aSig, 0, 3, &zSig0, &zSig1 ); + return packFloat64( aSign, aExp + 0x380, zSig0, zSig1 ); + +} + +#ifndef SOFTFLOAT_FOR_GCC +/* +------------------------------------------------------------------------------- +Rounds the single-precision floating-point value `a' to an integer, +and returns the result as a single-precision floating-point value. The +operation is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_round_to_int( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 lastBitMask, roundBitsMask; + int8 roundingMode; + float32 z; + + aExp = extractFloat32Exp( a ); + if ( 0x96 <= aExp ) { + if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { + return propagateFloat32NaN( a, a ); + } + return a; + } + if ( aExp <= 0x7E ) { + if ( (bits32) ( a<<1 ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat32Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { + return packFloat32( aSign, 0x7F, 0 ); + } + break; + case float_round_to_zero: + break; + case float_round_down: + return aSign ? 0xBF800000 : 0; + case float_round_up: + return aSign ? 0x80000000 : 0x3F800000; + } + return packFloat32( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x96 - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z += lastBitMask>>1; + if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z += roundBitsMask; + } + } + z &= ~ roundBitsMask; + if ( z != a ) float_exception_flags |= float_flag_inexact; + return z; + +} +#endif + +/* +------------------------------------------------------------------------------- +Returns the result of adding the absolute values of the single-precision +floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +before being returned. `zSign' is ignored if the result is a NaN. +The addition is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 6; + bSig <<= 6; + if ( 0 < expDiff ) { + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x20000000; + } + shift32RightJamming( bSig, expDiff, &bSig ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x20000000; + } + shift32RightJamming( aSig, - expDiff, &aSig ); + zExp = bExp; + } + else { + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); + zSig = 0x40000000 + aSig + bSig; + zExp = aExp; + goto roundAndPack; + } + aSig |= 0x20000000; + zSig = ( aSig + bSig )<<1; + --zExp; + if ( (sbits32) zSig < 0 ) { + zSig = aSig + bSig; + ++zExp; + } + roundAndPack: + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the absolute values of the single- +precision floating-point values `a' and `b'. If `zSign' is 1, the +difference is negated before being returned. `zSign' is ignored if the +result is a NaN. The subtraction is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 7; + bSig <<= 7; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign ^ 1, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x40000000; + } + shift32RightJamming( aSig, - expDiff, &aSig ); + bSig |= 0x40000000; + bBigger: + zSig = bSig - aSig; + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x40000000; + } + shift32RightJamming( bSig, expDiff, &bSig ); + aSig |= 0x40000000; + aBigger: + zSig = aSig - bSig; + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the single-precision floating-point values `a' +and `b'. The operation is performed according to the IEC/IEEE Standard for +Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_add( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return addFloat32Sigs( a, b, aSign ); + } + else { + return subFloat32Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the single-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_sub( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return subFloat32Sigs( a, b, aSign ); + } + else { + return addFloat32Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of multiplying the single-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_mul( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig0, zSig1; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x7F; + aSig = ( aSig | 0x00800000 )<<7; + bSig = ( bSig | 0x00800000 )<<8; + mul32To64( aSig, bSig, &zSig0, &zSig1 ); + zSig0 |= ( zSig1 != 0 ); + if ( 0 <= (sbits32) ( zSig0<<1 ) ) { + zSig0 <<= 1; + --zExp; + } + return roundAndPackFloat32( zSign, zExp, zSig0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of dividing the single-precision floating-point value `a' +by the corresponding value `b'. The operation is performed according to the +IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_div( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig, rem0, rem1, term0, term1; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat32( zSign, 0xFF, 0 ); + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x7D; + aSig = ( aSig | 0x00800000 )<<7; + bSig = ( bSig | 0x00800000 )<<8; + if ( bSig <= ( aSig + aSig ) ) { + aSig >>= 1; + ++zExp; + } + zSig = estimateDiv64To32( aSig, 0, bSig ); + if ( ( zSig & 0x3F ) <= 2 ) { + mul32To64( bSig, zSig, &term0, &term1 ); + sub64( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( (sbits32) rem0 < 0 ) { + --zSig; + add64( rem0, rem1, 0, bSig, &rem0, &rem1 ); + } + zSig |= ( rem1 != 0 ); + } + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +#ifndef SOFTFLOAT_FOR_GCC +/* +------------------------------------------------------------------------------- +Returns the remainder of the single-precision floating-point value `a' +with respect to the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_rem( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, expDiff; + bits32 aSig, bSig, q, allZero, alternateASig; + sbits32 sigMean; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return a; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + expDiff = aExp - bExp; + aSig = ( aSig | 0x00800000 )<<8; + bSig = ( bSig | 0x00800000 )<<8; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + aSig >>= 1; + } + q = ( bSig <= aSig ); + if ( q ) aSig -= bSig; + expDiff -= 32; + while ( 0 < expDiff ) { + q = estimateDiv64To32( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + aSig = - ( ( bSig>>2 ) * q ); + expDiff -= 30; + } + expDiff += 32; + if ( 0 < expDiff ) { + q = estimateDiv64To32( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + q >>= 32 - expDiff; + bSig >>= 2; + aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; + } + else { + aSig >>= 2; + bSig >>= 2; + } + do { + alternateASig = aSig; + ++q; + aSig -= bSig; + } while ( 0 <= (sbits32) aSig ); + sigMean = aSig + alternateASig; + if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { + aSig = alternateASig; + } + zSign = ( (sbits32) aSig < 0 ); + if ( zSign ) aSig = - aSig; + return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig ); + +} +#endif + +#ifndef SOFTFLOAT_FOR_GCC +/* +------------------------------------------------------------------------------- +Returns the square root of the single-precision floating-point value `a'. +The operation is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_sqrt( float32 a ) +{ + flag aSign; + int16 aExp, zExp; + bits32 aSig, zSig, rem0, rem1, term0, term1; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, 0 ); + if ( ! aSign ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aSign ) { + if ( ( aExp | aSig ) == 0 ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return 0; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; + aSig = ( aSig | 0x00800000 )<<8; + zSig = estimateSqrt32( aExp, aSig ) + 2; + if ( ( zSig & 0x7F ) <= 5 ) { + if ( zSig < 2 ) { + zSig = 0x7FFFFFFF; + goto roundAndPack; + } + else { + aSig >>= aExp & 1; + mul32To64( zSig, zSig, &term0, &term1 ); + sub64( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( (sbits32) rem0 < 0 ) { + --zSig; + shortShift64Left( 0, zSig, 1, &term0, &term1 ); + term1 |= 1; + add64( rem0, rem1, term0, term1, &rem0, &rem1 ); + } + zSig |= ( ( rem0 | rem1 ) != 0 ); + } + } + shift32RightJamming( zSig, 1, &zSig ); + roundAndPack: + return roundAndPackFloat32( 0, zExp, zSig ); + +} +#endif + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is equal to +the corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_eq( float32 a, float32 b ) +{ + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is less than +or equal to the corresponding value `b', and 0 otherwise. The comparison +is performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_le( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_lt( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +#ifndef SOFTFLOAT_FOR_GCC /* Not needed */ +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is equal to +the corresponding value `b', and 0 otherwise. The invalid exception is +raised if either operand is a NaN. Otherwise, the comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_eq_signaling( float32 a, float32 b ) +{ + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is less than or +equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +cause an exception. Otherwise, the comparison is performed according to the +IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_le_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; + int16 aExp, bExp; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +exception. Otherwise, the comparison is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_lt_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} +#endif /* !SOFTFLOAT_FOR_GCC */ + +#ifndef SOFTFLOAT_FOR_GCC /* Not needed */ +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic---which means in particular that the conversion is rounded +according to the current rounding mode. If `a' is a NaN, the largest +positive integer is returned. Otherwise, if the conversion overflows, the +largest integer with the same sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +int32 float64_to_int32( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig0, aSig1, absZ, aSigExtra; + int32 z; + int8 roundingMode; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + shiftCount = aExp - 0x413; + if ( 0 <= shiftCount ) { + if ( 0x41E < aExp ) { + if ( ( aExp == 0x7FF ) && ( aSig0 | aSig1 ) ) aSign = 0; + goto invalid; + } + shortShift64Left( + aSig0 | 0x00100000, aSig1, shiftCount, &absZ, &aSigExtra ); + if ( 0x80000000 < absZ ) goto invalid; + } + else { + aSig1 = ( aSig1 != 0 ); + if ( aExp < 0x3FE ) { + aSigExtra = aExp | aSig0 | aSig1; + absZ = 0; + } + else { + aSig0 |= 0x00100000; + aSigExtra = ( aSig0<<( shiftCount & 31 ) ) | aSig1; + absZ = aSig0>>( - shiftCount ); + } + } + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + if ( (sbits32) aSigExtra < 0 ) { + ++absZ; + if ( (bits32) ( aSigExtra<<1 ) == 0 ) absZ &= ~1; + } + z = aSign ? - absZ : absZ; + } + else { + aSigExtra = ( aSigExtra != 0 ); + if ( aSign ) { + z = - ( absZ + + ( ( roundingMode == float_round_down ) & aSigExtra ) ); + } + else { + z = absZ + ( ( roundingMode == float_round_up ) & aSigExtra ); + } + } + if ( ( aSign ^ ( z < 0 ) ) && z ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( aSigExtra ) float_exception_flags |= float_flag_inexact; + return z; + +} +#endif /* !SOFTFLOAT_FOR_GCC */ + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic, except that the conversion is always rounded toward zero. +If `a' is a NaN, the largest positive integer is returned. Otherwise, if +the conversion overflows, the largest integer with the same sign as `a' is +returned. +------------------------------------------------------------------------------- +*/ +int32 float64_to_int32_round_to_zero( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig0, aSig1, absZ, aSigExtra; + int32 z; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + shiftCount = aExp - 0x413; + if ( 0 <= shiftCount ) { + if ( 0x41E < aExp ) { + if ( ( aExp == 0x7FF ) && ( aSig0 | aSig1 ) ) aSign = 0; + goto invalid; + } + shortShift64Left( + aSig0 | 0x00100000, aSig1, shiftCount, &absZ, &aSigExtra ); + } + else { + if ( aExp < 0x3FF ) { + if ( aExp | aSig0 | aSig1 ) { + float_exception_flags |= float_flag_inexact; + } + return 0; + } + aSig0 |= 0x00100000; + aSigExtra = ( aSig0<<( shiftCount & 31 ) ) | aSig1; + absZ = aSig0>>( - shiftCount ); + } + z = aSign ? - absZ : absZ; + if ( ( aSign ^ ( z < 0 ) ) && z ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( aSigExtra ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the single-precision floating-point format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float64_to_float32( float64 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig0, aSig1, zSig; + bits32 allZero; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloat32( float64ToCommonNaN( a ) ); + } + return packFloat32( aSign, 0xFF, 0 ); + } + shift64RightJamming( aSig0, aSig1, 22, &allZero, &zSig ); + if ( aExp ) zSig |= 0x40000000; + return roundAndPackFloat32( aSign, aExp - 0x381, zSig ); + +} + +#ifndef SOFTFLOAT_FOR_GCC +/* +------------------------------------------------------------------------------- +Rounds the double-precision floating-point value `a' to an integer, +and returns the result as a double-precision floating-point value. The +operation is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_round_to_int( float64 a ) +{ + flag aSign; + int16 aExp; + bits32 lastBitMask, roundBitsMask; + int8 roundingMode; + float64 z; + + aExp = extractFloat64Exp( a ); + if ( 0x413 <= aExp ) { + if ( 0x433 <= aExp ) { + if ( ( aExp == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) { + return propagateFloat64NaN( a, a ); + } + return a; + } + lastBitMask = 1; + lastBitMask = ( lastBitMask<<( 0x432 - aExp ) )<<1; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + if ( lastBitMask ) { + add64( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low ); + if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; + } + else { + if ( (sbits32) z.low < 0 ) { + ++z.high; + if ( (bits32) ( z.low<<1 ) == 0 ) z.high &= ~1; + } + } + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat64Sign( z ) + ^ ( roundingMode == float_round_up ) ) { + add64( z.high, z.low, 0, roundBitsMask, &z.high, &z.low ); + } + } + z.low &= ~ roundBitsMask; + } + else { + if ( aExp <= 0x3FE ) { + if ( ( ( (bits32) ( a.high<<1 ) ) | a.low ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat64Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FE ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) + ) { + return packFloat64( aSign, 0x3FF, 0, 0 ); + } + break; + case float_round_down: + return + aSign ? packFloat64( 1, 0x3FF, 0, 0 ) + : packFloat64( 0, 0, 0, 0 ); + case float_round_up: + return + aSign ? packFloat64( 1, 0, 0, 0 ) + : packFloat64( 0, 0x3FF, 0, 0 ); + } + return packFloat64( aSign, 0, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x413 - aExp; + roundBitsMask = lastBitMask - 1; + z.low = 0; + z.high = a.high; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z.high += lastBitMask>>1; + if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) { + z.high &= ~ lastBitMask; + } + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat64Sign( z ) + ^ ( roundingMode == float_round_up ) ) { + z.high |= ( a.low != 0 ); + z.high += roundBitsMask; + } + } + z.high &= ~ roundBitsMask; + } + if ( ( z.low != a.low ) || ( z.high != a.high ) ) { + float_exception_flags |= float_flag_inexact; + } + return z; + +} +#endif + +/* +------------------------------------------------------------------------------- +Returns the result of adding the absolute values of the double-precision +floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +before being returned. `zSign' is ignored if the result is a NaN. +The addition is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + int16 expDiff; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + bSig1 = extractFloat64Frac1( b ); + bSig0 = extractFloat64Frac0( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) { + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig0 |= 0x00100000; + } + shift64ExtraRightJamming( + bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FF ) { + if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0x7FF, 0, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig0 |= 0x00100000; + } + shift64ExtraRightJamming( + aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 ); + zExp = bExp; + } + else { + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 | bSig0 | bSig1 ) { + return propagateFloat64NaN( a, b ); + } + return a; + } + add64( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + if ( aExp == 0 ) return packFloat64( zSign, 0, zSig0, zSig1 ); + zSig2 = 0; + zSig0 |= 0x00200000; + zExp = aExp; + goto shiftRight1; + } + aSig0 |= 0x00100000; + add64( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + --zExp; + if ( zSig0 < 0x00200000 ) goto roundAndPack; + ++zExp; + shiftRight1: + shift64ExtraRightJamming( zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); + roundAndPack: + return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the absolute values of the double- +precision floating-point values `a' and `b'. If `zSign' is 1, the +difference is negated before being returned. `zSign' is ignored if the +result is a NaN. The subtraction is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; + int16 expDiff; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + bSig1 = extractFloat64Frac1( b ); + bSig0 = extractFloat64Frac0( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + shortShift64Left( aSig0, aSig1, 10, &aSig0, &aSig1 ); + shortShift64Left( bSig0, bSig1, 10, &bSig0, &bSig1 ); + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 | bSig0 | bSig1 ) { + return propagateFloat64NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig0 < aSig0 ) goto aBigger; + if ( aSig0 < bSig0 ) goto bBigger; + if ( bSig1 < aSig1 ) goto aBigger; + if ( aSig1 < bSig1 ) goto bBigger; + return packFloat64( float_rounding_mode == float_round_down, 0, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FF ) { + if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign ^ 1, 0x7FF, 0, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig0 |= 0x40000000; + } + shift64RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); + bSig0 |= 0x40000000; + bBigger: + sub64( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 ); + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig0 |= 0x40000000; + } + shift64RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 ); + aSig0 |= 0x40000000; + aBigger: + sub64( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat64( zSign, zExp - 10, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the double-precision floating-point values `a' +and `b'. The operation is performed according to the IEC/IEEE Standard for +Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_add( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return addFloat64Sigs( a, b, aSign ); + } + else { + return subFloat64Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the double-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_sub( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return subFloat64Sigs( a, b, aSign ); + } + else { + return addFloat64Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of multiplying the double-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_mul( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig1 = extractFloat64Frac1( b ); + bSig0 = extractFloat64Frac0( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( ( aSig0 | aSig1 ) + || ( ( bExp == 0x7FF ) && ( bSig0 | bSig1 ) ) ) { + return propagateFloat64NaN( a, b ); + } + if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid; + return packFloat64( zSign, 0x7FF, 0, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b ); + if ( ( aExp | aSig0 | aSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat64( zSign, 0, 0, 0 ); + normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) return packFloat64( zSign, 0, 0, 0 ); + normalizeFloat64Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + zExp = aExp + bExp - 0x400; + aSig0 |= 0x00100000; + shortShift64Left( bSig0, bSig1, 12, &bSig0, &bSig1 ); + mul64To128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 ); + add64( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 ); + zSig2 |= ( zSig3 != 0 ); + if ( 0x00200000 <= zSig0 ) { + shift64ExtraRightJamming( + zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); + ++zExp; + } + return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of dividing the double-precision floating-point value `a' +by the corresponding value `b'. The operation is performed according to the +IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_div( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + bits32 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig1 = extractFloat64Frac1( b ); + bSig0 = extractFloat64Frac0( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, b ); + if ( bExp == 0x7FF ) { + if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b ); + goto invalid; + } + return packFloat64( zSign, 0x7FF, 0, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0, 0, 0 ); + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) { + if ( ( aExp | aSig0 | aSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + return float64_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat64( zSign, 0x7FF, 0, 0 ); + } + normalizeFloat64Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat64( zSign, 0, 0, 0 ); + normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + zExp = aExp - bExp + 0x3FD; + shortShift64Left( aSig0 | 0x00100000, aSig1, 11, &aSig0, &aSig1 ); + shortShift64Left( bSig0 | 0x00100000, bSig1, 11, &bSig0, &bSig1 ); + if ( le64( bSig0, bSig1, aSig0, aSig1 ) ) { + shift64Right( aSig0, aSig1, 1, &aSig0, &aSig1 ); + ++zExp; + } + zSig0 = estimateDiv64To32( aSig0, aSig1, bSig0 ); + mul64By32To96( bSig0, bSig1, zSig0, &term0, &term1, &term2 ); + sub96( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 ); + while ( (sbits32) rem0 < 0 ) { + --zSig0; + add96( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 ); + } + zSig1 = estimateDiv64To32( rem1, rem2, bSig0 ); + if ( ( zSig1 & 0x3FF ) <= 4 ) { + mul64By32To96( bSig0, bSig1, zSig1, &term1, &term2, &term3 ); + sub96( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits32) rem1 < 0 ) { + --zSig1; + add96( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shift64ExtraRightJamming( zSig0, zSig1, 0, 11, &zSig0, &zSig1, &zSig2 ); + return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +#ifndef SOFTFLOAT_FOR_GCC +/* +------------------------------------------------------------------------------- +Returns the remainder of the double-precision floating-point value `a' +with respect to the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_rem( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, expDiff; + bits32 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2; + bits32 allZero, alternateASig0, alternateASig1, sigMean1; + sbits32 sigMean0; + float64 z; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig1 = extractFloat64Frac1( b ); + bSig0 = extractFloat64Frac0( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + if ( aExp == 0x7FF ) { + if ( ( aSig0 | aSig1 ) + || ( ( bExp == 0x7FF ) && ( bSig0 | bSig1 ) ) ) { + return propagateFloat64NaN( a, b ); + } + goto invalid; + } + if ( bExp == 0x7FF ) { + if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + return float64_default_nan; + } + normalizeFloat64Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return a; + normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + expDiff = aExp - bExp; + if ( expDiff < -1 ) return a; + shortShift64Left( + aSig0 | 0x00100000, aSig1, 11 - ( expDiff < 0 ), &aSig0, &aSig1 ); + shortShift64Left( bSig0 | 0x00100000, bSig1, 11, &bSig0, &bSig1 ); + q = le64( bSig0, bSig1, aSig0, aSig1 ); + if ( q ) sub64( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); + expDiff -= 32; + while ( 0 < expDiff ) { + q = estimateDiv64To32( aSig0, aSig1, bSig0 ); + q = ( 4 < q ) ? q - 4 : 0; + mul64By32To96( bSig0, bSig1, q, &term0, &term1, &term2 ); + shortShift96Left( term0, term1, term2, 29, &term1, &term2, &allZero ); + shortShift64Left( aSig0, aSig1, 29, &aSig0, &allZero ); + sub64( aSig0, 0, term1, term2, &aSig0, &aSig1 ); + expDiff -= 29; + } + if ( -32 < expDiff ) { + q = estimateDiv64To32( aSig0, aSig1, bSig0 ); + q = ( 4 < q ) ? q - 4 : 0; + q >>= - expDiff; + shift64Right( bSig0, bSig1, 8, &bSig0, &bSig1 ); + expDiff += 24; + if ( expDiff < 0 ) { + shift64Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); + } + else { + shortShift64Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 ); + } + mul64By32To96( bSig0, bSig1, q, &term0, &term1, &term2 ); + sub64( aSig0, aSig1, term1, term2, &aSig0, &aSig1 ); + } + else { + shift64Right( aSig0, aSig1, 8, &aSig0, &aSig1 ); + shift64Right( bSig0, bSig1, 8, &bSig0, &bSig1 ); + } + do { + alternateASig0 = aSig0; + alternateASig1 = aSig1; + ++q; + sub64( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); + } while ( 0 <= (sbits32) aSig0 ); + add64( + aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 ); + if ( ( sigMean0 < 0 ) + || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { + aSig0 = alternateASig0; + aSig1 = alternateASig1; + } + zSign = ( (sbits32) aSig0 < 0 ); + if ( zSign ) sub64( 0, 0, aSig0, aSig1, &aSig0, &aSig1 ); + return + normalizeRoundAndPackFloat64( aSign ^ zSign, bExp - 4, aSig0, aSig1 ); + +} +#endif + +#ifndef SOFTFLOAT_FOR_GCC +/* +------------------------------------------------------------------------------- +Returns the square root of the double-precision floating-point value `a'. +The operation is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_sqrt( float64 a ) +{ + flag aSign; + int16 aExp, zExp; + bits32 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0; + bits32 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + float64 z; + + aSig1 = extractFloat64Frac1( a ); + aSig0 = extractFloat64Frac0( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, a ); + if ( ! aSign ) return a; + goto invalid; + } + if ( aSign ) { + if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a; + invalid: + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat64( 0, 0, 0, 0 ); + normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; + aSig0 |= 0x00100000; + shortShift64Left( aSig0, aSig1, 11, &term0, &term1 ); + zSig0 = ( estimateSqrt32( aExp, term0 )>>1 ) + 1; + if ( zSig0 == 0 ) zSig0 = 0x7FFFFFFF; + doubleZSig0 = zSig0 + zSig0; + shortShift64Left( aSig0, aSig1, 9 - ( aExp & 1 ), &aSig0, &aSig1 ); + mul32To64( zSig0, zSig0, &term0, &term1 ); + sub64( aSig0, aSig1, term0, term1, &rem0, &rem1 ); + while ( (sbits32) rem0 < 0 ) { + --zSig0; + doubleZSig0 -= 2; + add64( rem0, rem1, 0, doubleZSig0 | 1, &rem0, &rem1 ); + } + zSig1 = estimateDiv64To32( rem1, 0, doubleZSig0 ); + if ( ( zSig1 & 0x1FF ) <= 5 ) { + if ( zSig1 == 0 ) zSig1 = 1; + mul32To64( doubleZSig0, zSig1, &term1, &term2 ); + sub64( rem1, 0, term1, term2, &rem1, &rem2 ); + mul32To64( zSig1, zSig1, &term2, &term3 ); + sub96( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits32) rem1 < 0 ) { + --zSig1; + shortShift64Left( 0, zSig1, 1, &term2, &term3 ); + term3 |= 1; + term2 |= doubleZSig0; + add96( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shift64ExtraRightJamming( zSig0, zSig1, 0, 10, &zSig0, &zSig1, &zSig2 ); + return roundAndPackFloat64( 0, zExp, zSig0, zSig1, zSig2 ); + +} +#endif + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is equal to +the corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_eq( float64 a, float64 b ) +{ + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) + && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || + ( (bits64) ( ( FLOAT64_DEMANGLE(a) | FLOAT64_DEMANGLE(b) )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is less than +or equal to the corresponding value `b', and 0 otherwise. The comparison +is performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_le( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) + && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) + return aSign || + ( (bits64) ( ( FLOAT64_DEMANGLE(a) | FLOAT64_DEMANGLE(b) )<<1 ) == + 0 ); + return ( a == b ) || + ( aSign ^ ( FLOAT64_DEMANGLE(a) < FLOAT64_DEMANGLE(b) ) ); +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_lt( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) + && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) + return aSign && + ( (bits64) ( ( FLOAT64_DEMANGLE(a) | FLOAT64_DEMANGLE(b) )<<1 ) != + 0 ); + return ( a != b ) && + ( aSign ^ ( FLOAT64_DEMANGLE(a) < FLOAT64_DEMANGLE(b) ) ); + +} + +#ifndef SOFTFLOAT_FOR_GCC +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is equal to +the corresponding value `b', and 0 otherwise. The invalid exception is +raised if either operand is a NaN. Otherwise, the comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_eq_signaling( float64 a, float64 b ) +{ + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) + && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is less than or +equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +cause an exception. Otherwise, the comparison is performed according to the +IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_le_quiet( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) + && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +exception. Otherwise, the comparison is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_lt_quiet( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) + && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) + && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +#endif diff --git a/lib/libc/softfloat/bits64/softfloat-macros b/lib/libc/softfloat/bits64/softfloat-macros new file mode 100644 index 0000000..c0b2cc7 --- /dev/null +++ b/lib/libc/softfloat/bits64/softfloat-macros @@ -0,0 +1,746 @@ +/* $NetBSD: softfloat-macros,v 1.2 2009/02/16 10:23:35 tron Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/softfloat/bits64/softfloat-macros 230363 2012-01-20 06:16:14Z das $ */ + +/* +=============================================================================== + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Shifts `a' right by the number of bits given in `count'. If any nonzero +bits are shifted off, they are ``jammed'' into the least significant bit of +the result by setting the least significant bit to 1. The value of `count' +can be arbitrarily large; in particular, if `count' is greater than 32, the +result will be either 0 or 1, depending on whether `a' is zero or nonzero. +The result is stored in the location pointed to by `zPtr'. +------------------------------------------------------------------------------- +*/ +INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr ) +{ + bits32 z; + + if ( count == 0 ) { + z = a; + } + else if ( count < 32 ) { + z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 ); + } + else { + z = ( a != 0 ); + } + *zPtr = z; + +} + +/* +------------------------------------------------------------------------------- +Shifts `a' right by the number of bits given in `count'. If any nonzero +bits are shifted off, they are ``jammed'' into the least significant bit of +the result by setting the least significant bit to 1. The value of `count' +can be arbitrarily large; in particular, if `count' is greater than 64, the +result will be either 0 or 1, depending on whether `a' is zero or nonzero. +The result is stored in the location pointed to by `zPtr'. +------------------------------------------------------------------------------- +*/ +INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr ) +{ + bits64 z; + + if ( count == 0 ) { + z = a; + } + else if ( count < 64 ) { + z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 ); + } + else { + z = ( a != 0 ); + } + *zPtr = z; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64 +_plus_ the number of bits given in `count'. The shifted result is at most +64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The +bits shifted off form a second 64-bit result as follows: The _last_ bit +shifted off is the most-significant bit of the extra result, and the other +63 bits of the extra result are all zero if and only if _all_but_the_last_ +bits shifted off were all zero. This extra result is stored in the location +pointed to by `z1Ptr'. The value of `count' can be arbitrarily large. + (This routine makes more sense if `a0' and `a1' are considered to form a +fixed-point value with binary point between `a0' and `a1'. This fixed-point +value is shifted right by the number of bits given in `count', and the +integer part of the result is returned at the location pointed to by +`z0Ptr'. The fractional part of the result may be slightly corrupted as +described above, and is returned at the location pointed to by `z1Ptr'.) +------------------------------------------------------------------------------- +*/ +INLINE void + shift64ExtraRightJamming( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z0, z1; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 64 ) { + z1 = ( a0<>count; + } + else { + if ( count == 64 ) { + z1 = a0 | ( a1 != 0 ); + } + else { + z1 = ( ( a0 | a1 ) != 0 ); + } + z0 = 0; + } + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the +number of bits given in `count'. Any bits shifted off are lost. The value +of `count' can be arbitrarily large; in particular, if `count' is greater +than 128, the result will be 0. The result is broken into two 64-bit pieces +which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shift128Right( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z0, z1; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 64 ) { + z1 = ( a0<>count ); + z0 = a0>>count; + } + else { + z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0; + z0 = 0; + } + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the +number of bits given in `count'. If any nonzero bits are shifted off, they +are ``jammed'' into the least significant bit of the result by setting the +least significant bit to 1. The value of `count' can be arbitrarily large; +in particular, if `count' is greater than 128, the result will be either +0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or +nonzero. The result is broken into two 64-bit pieces which are stored at +the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shift128RightJamming( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z0, z1; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 64 ) { + z1 = ( a0<>count ) | ( ( a1<>count; + } + else { + if ( count == 64 ) { + z1 = a0 | ( a1 != 0 ); + } + else if ( count < 128 ) { + z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<>count ); + z0 = a0>>count; + } + else { + if ( count == 64 ) { + z2 = a1; + z1 = a0; + } + else { + a2 |= a1; + if ( count < 128 ) { + z2 = a0<>( count & 63 ); + } + else { + z2 = ( count == 128 ) ? a0 : ( a0 != 0 ); + z1 = 0; + } + } + z0 = 0; + } + z2 |= ( a2 != 0 ); + } + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the +number of bits given in `count'. Any bits shifted off are lost. The value +of `count' must be less than 64. The result is broken into two 64-bit +pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shortShift128Left( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + + *z1Ptr = a1<>( ( - count ) & 63 ) ); + +} + +/* +------------------------------------------------------------------------------- +Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left +by the number of bits given in `count'. Any bits shifted off are lost. +The value of `count' must be less than 64. The result is broken into three +64-bit pieces which are stored at the locations pointed to by `z0Ptr', +`z1Ptr', and `z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + shortShift192Left( + bits64 a0, + bits64 a1, + bits64 a2, + int16 count, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + int8 negCount; + + z2 = a2<>negCount; + z0 |= a1>>negCount; + } + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit +value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so +any carry out is lost. The result is broken into two 64-bit pieces which +are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + add128( + bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z1; + + z1 = a1 + b1; + *z1Ptr = z1; + *z0Ptr = a0 + b0 + ( z1 < a1 ); + +} + +/* +------------------------------------------------------------------------------- +Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the +192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is +modulo 2^192, so any carry out is lost. The result is broken into three +64-bit pieces which are stored at the locations pointed to by `z0Ptr', +`z1Ptr', and `z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + add192( + bits64 a0, + bits64 a1, + bits64 a2, + bits64 b0, + bits64 b1, + bits64 b2, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + int8 carry0, carry1; + + z2 = a2 + b2; + carry1 = ( z2 < a2 ); + z1 = a1 + b1; + carry0 = ( z1 < a1 ); + z0 = a0 + b0; + z1 += carry1; + z0 += ( z1 < (bits64)carry1 ); + z0 += carry0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the +128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo +2^128, so any borrow out (carry out) is lost. The result is broken into two +64-bit pieces which are stored at the locations pointed to by `z0Ptr' and +`z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + sub128( + bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + + *z1Ptr = a1 - b1; + *z0Ptr = a0 - b0 - ( a1 < b1 ); + +} + +/* +------------------------------------------------------------------------------- +Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2' +from the 192-bit value formed by concatenating `a0', `a1', and `a2'. +Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The +result is broken into three 64-bit pieces which are stored at the locations +pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + sub192( + bits64 a0, + bits64 a1, + bits64 a2, + bits64 b0, + bits64 b1, + bits64 b2, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + int8 borrow0, borrow1; + + z2 = a2 - b2; + borrow1 = ( a2 < b2 ); + z1 = a1 - b1; + borrow0 = ( a1 < b1 ); + z0 = a0 - b0; + z0 -= ( z1 < (bits64)borrow1 ); + z1 -= borrow1; + z0 -= borrow0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Multiplies `a' by `b' to obtain a 128-bit product. The product is broken +into two 64-bit pieces which are stored at the locations pointed to by +`z0Ptr' and `z1Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits32 aHigh, aLow, bHigh, bLow; + bits64 z0, zMiddleA, zMiddleB, z1; + + aLow = a; + aHigh = a>>32; + bLow = b; + bHigh = b>>32; + z1 = ( (bits64) aLow ) * bLow; + zMiddleA = ( (bits64) aLow ) * bHigh; + zMiddleB = ( (bits64) aHigh ) * bLow; + z0 = ( (bits64) aHigh ) * bHigh; + zMiddleA += zMiddleB; + z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 ); + zMiddleA <<= 32; + z1 += zMiddleA; + z0 += ( z1 < zMiddleA ); + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Multiplies the 128-bit value formed by concatenating `a0' and `a1' by +`b' to obtain a 192-bit product. The product is broken into three 64-bit +pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and +`z2Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + mul128By64To192( + bits64 a0, + bits64 a1, + bits64 b, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2, more1; + + mul64To128( a1, b, &z1, &z2 ); + mul64To128( a0, b, &z0, &more1 ); + add128( z0, more1, 0, z1, &z0, &z1 ); + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the +128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit +product. The product is broken into four 64-bit pieces which are stored at +the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'. +------------------------------------------------------------------------------- +*/ +INLINE void + mul128To256( + bits64 a0, + bits64 a1, + bits64 b0, + bits64 b1, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr, + bits64 *z3Ptr + ) +{ + bits64 z0, z1, z2, z3; + bits64 more1, more2; + + mul64To128( a1, b1, &z2, &z3 ); + mul64To128( a1, b0, &z1, &more2 ); + add128( z1, more2, 0, z2, &z1, &z2 ); + mul64To128( a0, b0, &z0, &more1 ); + add128( z0, more1, 0, z1, &z0, &z1 ); + mul64To128( a0, b1, &more1, &more2 ); + add128( more1, more2, 0, z2, &more1, &z2 ); + add128( z0, z1, 0, more1, &z0, &z1 ); + *z3Ptr = z3; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/* +------------------------------------------------------------------------------- +Returns an approximation to the 64-bit integer quotient obtained by dividing +`b' into the 128-bit value formed by concatenating `a0' and `a1'. The +divisor `b' must be at least 2^63. If q is the exact quotient truncated +toward zero, the approximation returned lies between q and q + 2 inclusive. +If the exact quotient q is larger than 64 bits, the maximum positive 64-bit +unsigned integer is returned. +------------------------------------------------------------------------------- +*/ +static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b ) +{ + bits64 b0, b1; + bits64 rem0, rem1, term0, term1; + bits64 z; + + if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF ); + b0 = b>>32; + z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32; + mul64To128( b, z, &term0, &term1 ); + sub128( a0, a1, term0, term1, &rem0, &rem1 ); + while ( ( (sbits64) rem0 ) < 0 ) { + z -= LIT64( 0x100000000 ); + b1 = b<<32; + add128( rem0, rem1, b0, b1, &rem0, &rem1 ); + } + rem0 = ( rem0<<32 ) | ( rem1>>32 ); + z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0; + return z; + +} + +#if !defined(SOFTFLOAT_FOR_GCC) || defined(FLOATX80) || defined(FLOAT128) +/* +------------------------------------------------------------------------------- +Returns an approximation to the square root of the 32-bit significand given +by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of +`aExp' (the least significant bit) is 1, the integer returned approximates +2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp' +is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either +case, the approximation returned lies strictly within +/-2 of the exact +value. +------------------------------------------------------------------------------- +*/ +static bits32 estimateSqrt32( int16 aExp, bits32 a ) +{ + static const bits16 sqrtOddAdjustments[] = { + 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, + 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 + }; + static const bits16 sqrtEvenAdjustments[] = { + 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, + 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 + }; + int8 idx; + bits32 z; + + idx = ( a>>27 ) & 15; + if ( aExp & 1 ) { + z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ idx ]; + z = ( ( a / z )<<14 ) + ( z<<15 ); + a >>= 1; + } + else { + z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ idx ]; + z = a / z + z; + z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); + if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 ); + } + return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 ); + +} +#endif + +/* +------------------------------------------------------------------------------- +Returns the number of leading 0 bits before the most-significant 1 bit of +`a'. If `a' is zero, 32 is returned. +------------------------------------------------------------------------------- +*/ +static int8 countLeadingZeros32( bits32 a ) +{ + static const int8 countLeadingZerosHigh[] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + int8 shiftCount; + + shiftCount = 0; + if ( a < 0x10000 ) { + shiftCount += 16; + a <<= 16; + } + if ( a < 0x1000000 ) { + shiftCount += 8; + a <<= 8; + } + shiftCount += countLeadingZerosHigh[ a>>24 ]; + return shiftCount; + +} + +/* +------------------------------------------------------------------------------- +Returns the number of leading 0 bits before the most-significant 1 bit of +`a'. If `a' is zero, 64 is returned. +------------------------------------------------------------------------------- +*/ +static int8 countLeadingZeros64( bits64 a ) +{ + int8 shiftCount; + + shiftCount = 0; + if ( a < ( (bits64) 1 )<<32 ) { + shiftCount += 32; + } + else { + a >>= 32; + } + shiftCount += countLeadingZeros32( a ); + return shiftCount; + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' +is equal to the 128-bit value formed by concatenating `b0' and `b1'. +Otherwise, returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 == b0 ) && ( a1 == b1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less +than or equal to the 128-bit value formed by concatenating `b0' and `b1'. +Otherwise, returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less +than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise, +returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is +not equal to the 128-bit value formed by concatenating `b0' and `b1'. +Otherwise, returns 0. +------------------------------------------------------------------------------- +*/ +INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 != b0 ) || ( a1 != b1 ); + +} + diff --git a/lib/libc/softfloat/bits64/softfloat.c b/lib/libc/softfloat/bits64/softfloat.c new file mode 100644 index 0000000..76b8f5f --- /dev/null +++ b/lib/libc/softfloat/bits64/softfloat.c @@ -0,0 +1,5599 @@ +/* $NetBSD: softfloat.c,v 1.8 2011/07/10 04:52:23 matt Exp $ */ + +/* + * This version hacked for use with gcc -msoft-float by bjh21. + * (Mostly a case of #ifdefing out things GCC doesn't need or provides + * itself). + */ + +/* + * Things you may want to define: + * + * SOFTFLOAT_FOR_GCC - build only those functions necessary for GCC (with + * -msoft-float) to work. Include "softfloat-for-gcc.h" to get them + * properly renamed. + */ + +/* +=============================================================================== + +This C source file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/bits64/softfloat.c 230380 2012-01-20 14:44:21Z das $"); + +#ifdef SOFTFLOAT_FOR_GCC +#include "softfloat-for-gcc.h" +#endif + +#include "milieu.h" +#include "softfloat.h" + +/* + * Conversions between floats as stored in memory and floats as + * SoftFloat uses them + */ +#ifndef FLOAT64_DEMANGLE +#define FLOAT64_DEMANGLE(a) (a) +#endif +#ifndef FLOAT64_MANGLE +#define FLOAT64_MANGLE(a) (a) +#endif + +/* +------------------------------------------------------------------------------- +Floating-point rounding mode, extended double-precision rounding precision, +and exception flags. +------------------------------------------------------------------------------- +*/ +int float_rounding_mode = float_round_nearest_even; +int float_exception_flags = 0; +#ifdef FLOATX80 +int8 floatx80_rounding_precision = 80; +#endif + +/* +------------------------------------------------------------------------------- +Primitive arithmetic functions, including multi-word arithmetic, and +division and square root approximations. (Can be specialized to target if +desired.) +------------------------------------------------------------------------------- +*/ +#include "softfloat-macros" + +/* +------------------------------------------------------------------------------- +Functions and definitions to determine: (1) whether tininess for underflow +is detected before or after rounding by default, (2) what (if anything) +happens when exceptions are raised, (3) how signaling NaNs are distinguished +from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs +are propagated from function inputs to output. These details are target- +specific. +------------------------------------------------------------------------------- +*/ +#include "softfloat-specialize" + +#if !defined(SOFTFLOAT_FOR_GCC) || defined(FLOATX80) || defined(FLOAT128) +/* +------------------------------------------------------------------------------- +Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 +and 7, and returns the properly rounded 32-bit integer corresponding to the +input. If `zSign' is 1, the input is negated before being converted to an +integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input +is simply rounded to an integer, with the inexact exception raised if the +input cannot be represented exactly as an integer. However, if the fixed- +point input is too large, the invalid exception is raised and the largest +positive or negative integer is returned. +------------------------------------------------------------------------------- +*/ +static int32 roundAndPackInt32( flag zSign, bits64 absZ ) +{ + int8 roundingMode; + flag roundNearestEven; + int8 roundIncrement, roundBits; + int32 z; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + roundIncrement = 0x40; + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + roundIncrement = 0; + } + else { + roundIncrement = 0x7F; + if ( zSign ) { + if ( roundingMode == float_round_up ) roundIncrement = 0; + } + else { + if ( roundingMode == float_round_down ) roundIncrement = 0; + } + } + } + roundBits = absZ & 0x7F; + absZ = ( absZ + roundIncrement )>>7; + absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); + z = absZ; + if ( zSign ) z = - z; + if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { + float_raise( float_flag_invalid ); + return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( roundBits ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/* +------------------------------------------------------------------------------- +Takes the 128-bit fixed-point value formed by concatenating `absZ0' and +`absZ1', with binary point between bits 63 and 64 (between the input words), +and returns the properly rounded 64-bit integer corresponding to the input. +If `zSign' is 1, the input is negated before being converted to an integer. +Ordinarily, the fixed-point input is simply rounded to an integer, with +the inexact exception raised if the input cannot be represented exactly as +an integer. However, if the fixed-point input is too large, the invalid +exception is raised and the largest positive or negative integer is +returned. +------------------------------------------------------------------------------- +*/ +static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 ) +{ + int8 roundingMode; + flag roundNearestEven, increment; + int64 z; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + increment = ( (sbits64) absZ1 < 0 ); + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + increment = 0; + } + else { + if ( zSign ) { + increment = ( roundingMode == float_round_down ) && absZ1; + } + else { + increment = ( roundingMode == float_round_up ) && absZ1; + } + } + } + if ( increment ) { + ++absZ0; + if ( absZ0 == 0 ) goto overflow; + absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven ); + } + z = absZ0; + if ( zSign ) z = - z; + if ( z && ( ( z < 0 ) ^ zSign ) ) { + overflow: + float_raise( float_flag_invalid ); + return + zSign ? (sbits64) LIT64( 0x8000000000000000 ) + : LIT64( 0x7FFFFFFFFFFFFFFF ); + } + if ( absZ1 ) float_exception_flags |= float_flag_inexact; + return z; + +} +#endif + +/* +------------------------------------------------------------------------------- +Returns the fraction bits of the single-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE bits32 extractFloat32Frac( float32 a ) +{ + + return a & 0x007FFFFF; + +} + +/* +------------------------------------------------------------------------------- +Returns the exponent bits of the single-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE int16 extractFloat32Exp( float32 a ) +{ + + return ( a>>23 ) & 0xFF; + +} + +/* +------------------------------------------------------------------------------- +Returns the sign bit of the single-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE flag extractFloat32Sign( float32 a ) +{ + + return a>>31; + +} + +/* +------------------------------------------------------------------------------- +Normalizes the subnormal single-precision floating-point value represented +by the denormalized significand `aSig'. The normalized exponent and +significand are stored at the locations pointed to by `zExpPtr' and +`zSigPtr', respectively. +------------------------------------------------------------------------------- +*/ +static void + normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros32( aSig ) - 8; + *zSigPtr = aSig<>7; + zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); + if ( zSig == 0 ) zExp = 0; + return packFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent `zExp', +and significand `zSig', and returns the proper single-precision floating- +point value corresponding to the abstract input. This routine is just like +`roundAndPackFloat32' except that `zSig' does not have to be normalized. +Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' +floating-point exponent. +------------------------------------------------------------------------------- +*/ +static float32 + normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros32( zSig ) - 1; + return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<>52 ) & 0x7FF; + +} + +/* +------------------------------------------------------------------------------- +Returns the sign bit of the double-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE flag extractFloat64Sign( float64 a ) +{ + + return FLOAT64_DEMANGLE(a)>>63; + +} + +/* +------------------------------------------------------------------------------- +Normalizes the subnormal double-precision floating-point value represented +by the denormalized significand `aSig'. The normalized exponent and +significand are stored at the locations pointed to by `zExpPtr' and +`zSigPtr', respectively. +------------------------------------------------------------------------------- +*/ +static void + normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( aSig ) - 11; + *zSigPtr = aSig<>10; + zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven ); + if ( zSig == 0 ) zExp = 0; + return packFloat64( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Takes an abstract floating-point value having sign `zSign', exponent `zExp', +and significand `zSig', and returns the proper double-precision floating- +point value corresponding to the abstract input. This routine is just like +`roundAndPackFloat64' except that `zSig' does not have to be normalized. +Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' +floating-point exponent. +------------------------------------------------------------------------------- +*/ +static float64 + normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( zSig ) - 1; + return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<>15; + +} + +/* +------------------------------------------------------------------------------- +Normalizes the subnormal extended double-precision floating-point value +represented by the denormalized significand `aSig'. The normalized exponent +and significand are stored at the locations pointed to by `zExpPtr' and +`zSigPtr', respectively. +------------------------------------------------------------------------------- +*/ +static void + normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( aSig ); + *zSigPtr = aSig<>48 ) & 0x7FFF; + +} + +/* +------------------------------------------------------------------------------- +Returns the sign bit of the quadruple-precision floating-point value `a'. +------------------------------------------------------------------------------- +*/ +INLINE flag extractFloat128Sign( float128 a ) +{ + + return a.high>>63; + +} + +/* +------------------------------------------------------------------------------- +Normalizes the subnormal quadruple-precision floating-point value +represented by the denormalized significand formed by the concatenation of +`aSig0' and `aSig1'. The normalized exponent is stored at the location +pointed to by `zExpPtr'. The most significant 49 bits of the normalized +significand are stored at the location pointed to by `zSig0Ptr', and the +least significant 64 bits of the normalized significand are stored at the +location pointed to by `zSig1Ptr'. +------------------------------------------------------------------------------- +*/ +static void + normalizeFloat128Subnormal( + bits64 aSig0, + bits64 aSig1, + int32 *zExpPtr, + bits64 *zSig0Ptr, + bits64 *zSig1Ptr + ) +{ + int8 shiftCount; + + if ( aSig0 == 0 ) { + shiftCount = countLeadingZeros64( aSig1 ) - 15; + if ( shiftCount < 0 ) { + *zSig0Ptr = aSig1>>( - shiftCount ); + *zSig1Ptr = aSig1<<( shiftCount & 63 ); + } + else { + *zSig0Ptr = aSig1<> 1 ); + return normalizeRoundAndPackFloat32( 0, 0x9C, a ); +} +#endif + + +/* +------------------------------------------------------------------------------- +Returns the result of converting the 32-bit two's complement integer `a' +to the double-precision floating-point format. The conversion is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 int32_to_float64( int32 a ) +{ + flag zSign; + uint32 absA; + int8 shiftCount; + bits64 zSig; + + if ( a == 0 ) return 0; + zSign = ( a < 0 ); + absA = zSign ? - a : a; + shiftCount = countLeadingZeros32( absA ) + 21; + zSig = absA; + return packFloat64( zSign, 0x432 - shiftCount, zSig<>( - shiftCount ); + if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +#ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */ +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the 64-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic---which means in particular that the conversion is rounded +according to the current rounding mode. If `a' is a NaN, the largest +positive integer is returned. Otherwise, if the conversion overflows, the +largest integer with the same sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +int64 float32_to_int64( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + bits64 aSig64, aSigExtra; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = 0xBE - aExp; + if ( shiftCount < 0 ) { + float_raise( float_flag_invalid ); + if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { + return LIT64( 0x7FFFFFFFFFFFFFFF ); + } + return (sbits64) LIT64( 0x8000000000000000 ); + } + if ( aExp ) aSig |= 0x00800000; + aSig64 = aSig; + aSig64 <<= 40; + shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra ); + return roundAndPackInt64( aSign, aSig64, aSigExtra ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the 64-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic, except that the conversion is always rounded toward zero. If +`a' is a NaN, the largest positive integer is returned. Otherwise, if the +conversion overflows, the largest integer with the same sign as `a' is +returned. +------------------------------------------------------------------------------- +*/ +int64 float32_to_int64_round_to_zero( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + bits64 aSig64; + int64 z; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = aExp - 0xBE; + if ( 0 <= shiftCount ) { + if ( a != 0xDF000000 ) { + float_raise( float_flag_invalid ); + if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { + return LIT64( 0x7FFFFFFFFFFFFFFF ); + } + } + return (sbits64) LIT64( 0x8000000000000000 ); + } + else if ( aExp <= 0x7E ) { + if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig64 = aSig | 0x00800000; + aSig64 <<= 40; + z = aSig64>>( - shiftCount ); + if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} +#endif /* !SOFTFLOAT_FOR_GCC */ + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the double-precision floating-point format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float32_to_float64( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) ); + return packFloat64( aSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( aSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 ); + +} + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the extended double-precision floating-point format. The conversion +is performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 float32_to_floatx80( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) ); + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + aSig |= 0x00800000; + return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 ); + +} + +#endif + +#ifdef FLOAT128 + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point value +`a' to the double-precision floating-point format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +float128 float32_to_float128( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a ) ); + return packFloat128( aSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 ); + +} + +#endif + +#ifndef SOFTFLOAT_FOR_GCC /* Not needed */ +/* +------------------------------------------------------------------------------- +Rounds the single-precision floating-point value `a' to an integer, and +returns the result as a single-precision floating-point value. The +operation is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_round_to_int( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 lastBitMask, roundBitsMask; + int8 roundingMode; + float32 z; + + aExp = extractFloat32Exp( a ); + if ( 0x96 <= aExp ) { + if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { + return propagateFloat32NaN( a, a ); + } + return a; + } + if ( aExp <= 0x7E ) { + if ( (bits32) ( a<<1 ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat32Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { + return packFloat32( aSign, 0x7F, 0 ); + } + break; + case float_round_to_zero: + break; + case float_round_down: + return aSign ? 0xBF800000 : 0; + case float_round_up: + return aSign ? 0x80000000 : 0x3F800000; + } + return packFloat32( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x96 - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z += lastBitMask>>1; + if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z += roundBitsMask; + } + } + z &= ~ roundBitsMask; + if ( z != a ) float_exception_flags |= float_flag_inexact; + return z; + +} +#endif /* !SOFTFLOAT_FOR_GCC */ + +/* +------------------------------------------------------------------------------- +Returns the result of adding the absolute values of the single-precision +floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +before being returned. `zSign' is ignored if the result is a NaN. +The addition is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 6; + bSig <<= 6; + if ( 0 < expDiff ) { + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x20000000; + } + shift32RightJamming( bSig, expDiff, &bSig ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x20000000; + } + shift32RightJamming( aSig, - expDiff, &aSig ); + zExp = bExp; + } + else { + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); + zSig = 0x40000000 + aSig + bSig; + zExp = aExp; + goto roundAndPack; + } + aSig |= 0x20000000; + zSig = ( aSig + bSig )<<1; + --zExp; + if ( (sbits32) zSig < 0 ) { + zSig = aSig + bSig; + ++zExp; + } + roundAndPack: + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the absolute values of the single- +precision floating-point values `a' and `b'. If `zSign' is 1, the +difference is negated before being returned. `zSign' is ignored if the +result is a NaN. The subtraction is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 7; + bSig <<= 7; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign ^ 1, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x40000000; + } + shift32RightJamming( aSig, - expDiff, &aSig ); + bSig |= 0x40000000; + bBigger: + zSig = bSig - aSig; + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x40000000; + } + shift32RightJamming( bSig, expDiff, &bSig ); + aSig |= 0x40000000; + aBigger: + zSig = aSig - bSig; + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the single-precision floating-point values `a' +and `b'. The operation is performed according to the IEC/IEEE Standard for +Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_add( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return addFloat32Sigs( a, b, aSign ); + } + else { + return subFloat32Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the single-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_sub( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return subFloat32Sigs( a, b, aSign ); + } + else { + return addFloat32Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of multiplying the single-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_mul( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig; + bits64 zSig64; + bits32 zSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x7F; + aSig = ( aSig | 0x00800000 )<<7; + bSig = ( bSig | 0x00800000 )<<8; + shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 ); + zSig = zSig64; + if ( 0 <= (sbits32) ( zSig<<1 ) ) { + zSig <<= 1; + --zExp; + } + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of dividing the single-precision floating-point value `a' +by the corresponding value `b'. The operation is performed according to the +IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_div( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat32( zSign, 0xFF, 0 ); + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x7D; + aSig = ( aSig | 0x00800000 )<<7; + bSig = ( bSig | 0x00800000 )<<8; + if ( bSig <= ( aSig + aSig ) ) { + aSig >>= 1; + ++zExp; + } + zSig = ( ( (bits64) aSig )<<32 ) / bSig; + if ( ( zSig & 0x3F ) == 0 ) { + zSig |= ( (bits64) bSig * zSig != ( (bits64) aSig )<<32 ); + } + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +#ifndef SOFTFLOAT_FOR_GCC /* Not needed */ +/* +------------------------------------------------------------------------------- +Returns the remainder of the single-precision floating-point value `a' +with respect to the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_rem( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, expDiff; + bits32 aSig, bSig; + bits32 q; + bits64 aSig64, bSig64, q64; + bits32 alternateASig; + sbits32 sigMean; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return a; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + expDiff = aExp - bExp; + aSig |= 0x00800000; + bSig |= 0x00800000; + if ( expDiff < 32 ) { + aSig <<= 8; + bSig <<= 8; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + aSig >>= 1; + } + q = ( bSig <= aSig ); + if ( q ) aSig -= bSig; + if ( 0 < expDiff ) { + q = ( ( (bits64) aSig )<<32 ) / bSig; + q >>= 32 - expDiff; + bSig >>= 2; + aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; + } + else { + aSig >>= 2; + bSig >>= 2; + } + } + else { + if ( bSig <= aSig ) aSig -= bSig; + aSig64 = ( (bits64) aSig )<<40; + bSig64 = ( (bits64) bSig )<<40; + expDiff -= 64; + while ( 0 < expDiff ) { + q64 = estimateDiv128To64( aSig64, 0, bSig64 ); + q64 = ( 2 < q64 ) ? q64 - 2 : 0; + aSig64 = - ( ( bSig * q64 )<<38 ); + expDiff -= 62; + } + expDiff += 64; + q64 = estimateDiv128To64( aSig64, 0, bSig64 ); + q64 = ( 2 < q64 ) ? q64 - 2 : 0; + q = q64>>( 64 - expDiff ); + bSig <<= 6; + aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q; + } + do { + alternateASig = aSig; + ++q; + aSig -= bSig; + } while ( 0 <= (sbits32) aSig ); + sigMean = aSig + alternateASig; + if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { + aSig = alternateASig; + } + zSign = ( (sbits32) aSig < 0 ); + if ( zSign ) aSig = - aSig; + return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig ); + +} +#endif /* !SOFTFLOAT_FOR_GCC */ + +#ifndef SOFTFLOAT_FOR_GCC /* Not needed */ +/* +------------------------------------------------------------------------------- +Returns the square root of the single-precision floating-point value `a'. +The operation is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float32_sqrt( float32 a ) +{ + flag aSign; + int16 aExp, zExp; + bits32 aSig, zSig; + bits64 rem, term; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, 0 ); + if ( ! aSign ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aSign ) { + if ( ( aExp | aSig ) == 0 ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return 0; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; + aSig = ( aSig | 0x00800000 )<<8; + zSig = estimateSqrt32( aExp, aSig ) + 2; + if ( ( zSig & 0x7F ) <= 5 ) { + if ( zSig < 2 ) { + zSig = 0x7FFFFFFF; + goto roundAndPack; + } + aSig >>= aExp & 1; + term = ( (bits64) zSig ) * zSig; + rem = ( ( (bits64) aSig )<<32 ) - term; + while ( (sbits64) rem < 0 ) { + --zSig; + rem += ( ( (bits64) zSig )<<1 ) | 1; + } + zSig |= ( rem != 0 ); + } + shift32RightJamming( zSig, 1, &zSig ); + roundAndPack: + return roundAndPackFloat32( 0, zExp, zSig ); + +} +#endif /* !SOFTFLOAT_FOR_GCC */ + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is equal to +the corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_eq( float32 a, float32 b ) +{ + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is less than +or equal to the corresponding value `b', and 0 otherwise. The comparison +is performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_le( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_lt( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +#ifndef SOFTFLOAT_FOR_GCC /* Not needed */ +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is equal to +the corresponding value `b', and 0 otherwise. The invalid exception is +raised if either operand is a NaN. Otherwise, the comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_eq_signaling( float32 a, float32 b ) +{ + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is less than or +equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +cause an exception. Otherwise, the comparison is performed according to the +IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_le_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +exception. Otherwise, the comparison is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float32_lt_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} +#endif /* !SOFTFLOAT_FOR_GCC */ + +#ifndef SOFTFLOAT_FOR_GCC /* Not needed */ +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic---which means in particular that the conversion is rounded +according to the current rounding mode. If `a' is a NaN, the largest +positive integer is returned. Otherwise, if the conversion overflows, the +largest integer with the same sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +int32 float64_to_int32( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); + shiftCount = 0x42C - aExp; + if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); + return roundAndPackInt32( aSign, aSig ); + +} +#endif /* !SOFTFLOAT_FOR_GCC */ + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the 32-bit two's complement integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic, except that the conversion is always rounded toward zero. +If `a' is a NaN, the largest positive integer is returned. Otherwise, if +the conversion overflows, the largest integer with the same sign as `a' is +returned. +------------------------------------------------------------------------------- +*/ +int32 float64_to_int32_round_to_zero( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig, savedASig; + int32 z; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( 0x41E < aExp ) { + if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + goto invalid; + } + else if ( aExp < 0x3FF ) { + if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig |= LIT64( 0x0010000000000000 ); + shiftCount = 0x433 - aExp; + savedASig = aSig; + aSig >>= shiftCount; + z = aSig; + if ( aSign ) z = - z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig<>( - shiftCount ); + if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + } + if ( aSign ) z = - z; + return z; + +} +#endif /* !SOFTFLOAT_FOR_GCC */ + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the single-precision floating-point format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float64_to_float32( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig; + bits32 zSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) ); + return packFloat32( aSign, 0xFF, 0 ); + } + shift64RightJamming( aSig, 22, &aSig ); + zSig = aSig; + if ( aExp || zSig ) { + zSig |= 0x40000000; + aExp -= 0x381; + } + return roundAndPackFloat32( aSign, aExp, zSig ); + +} + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the extended double-precision floating-point format. The conversion +is performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 float64_to_floatx80( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) ); + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + return + packFloatx80( + aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 ); + +} + +#endif + +#ifdef FLOAT128 + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the quadruple-precision floating-point format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +float128 float64_to_float128( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig, zSig0, zSig1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a ) ); + return packFloat128( aSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + shift128Right( aSig, 0, 4, &zSig0, &zSig1 ); + return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 ); + +} + +#endif + +#ifndef SOFTFLOAT_FOR_GCC +/* +------------------------------------------------------------------------------- +Rounds the double-precision floating-point value `a' to an integer, and +returns the result as a double-precision floating-point value. The +operation is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_round_to_int( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + float64 z; + + aExp = extractFloat64Exp( a ); + if ( 0x433 <= aExp ) { + if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) { + return propagateFloat64NaN( a, a ); + } + return a; + } + if ( aExp < 0x3FF ) { + if ( (bits64) ( a<<1 ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat64Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { + return packFloat64( aSign, 0x3FF, 0 ); + } + break; + case float_round_to_zero: + break; + case float_round_down: + return aSign ? LIT64( 0xBFF0000000000000 ) : 0; + case float_round_up: + return + aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ); + } + return packFloat64( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x433 - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z += lastBitMask>>1; + if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z += roundBitsMask; + } + } + z &= ~ roundBitsMask; + if ( z != a ) float_exception_flags |= float_flag_inexact; + return z; + +} +#endif + +/* +------------------------------------------------------------------------------- +Returns the result of adding the absolute values of the double-precision +floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +before being returned. `zSign' is ignored if the result is a NaN. +The addition is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + aSig <<= 9; + bSig <<= 9; + if ( 0 < expDiff ) { + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= LIT64( 0x2000000000000000 ); + } + shift64RightJamming( bSig, expDiff, &bSig ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= LIT64( 0x2000000000000000 ); + } + shift64RightJamming( aSig, - expDiff, &aSig ); + zExp = bExp; + } + else { + if ( aExp == 0x7FF ) { + if ( aSig | bSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); + zSig = LIT64( 0x4000000000000000 ) + aSig + bSig; + zExp = aExp; + goto roundAndPack; + } + aSig |= LIT64( 0x2000000000000000 ); + zSig = ( aSig + bSig )<<1; + --zExp; + if ( (sbits64) zSig < 0 ) { + zSig = aSig + bSig; + ++zExp; + } + roundAndPack: + return roundAndPackFloat64( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the absolute values of the double- +precision floating-point values `a' and `b'. If `zSign' is 1, the +difference is negated before being returned. `zSign' is ignored if the +result is a NaN. The subtraction is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + aSig <<= 10; + bSig <<= 10; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FF ) { + if ( aSig | bSig ) return propagateFloat64NaN( a, b ); + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloat64( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign ^ 1, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= LIT64( 0x4000000000000000 ); + } + shift64RightJamming( aSig, - expDiff, &aSig ); + bSig |= LIT64( 0x4000000000000000 ); + bBigger: + zSig = bSig - aSig; + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= LIT64( 0x4000000000000000 ); + } + shift64RightJamming( bSig, expDiff, &bSig ); + aSig |= LIT64( 0x4000000000000000 ); + aBigger: + zSig = aSig - bSig; + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat64( zSign, zExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the double-precision floating-point values `a' +and `b'. The operation is performed according to the IEC/IEEE Standard for +Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_add( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return addFloat64Sigs( a, b, aSign ); + } + else { + return subFloat64Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the double-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_sub( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return subFloat64Sigs( a, b, aSign ); + } + else { + return addFloat64Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of multiplying the double-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_mul( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { + return propagateFloat64NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x3FF; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + mul64To128( aSig, bSig, &zSig0, &zSig1 ); + zSig0 |= ( zSig1 != 0 ); + if ( 0 <= (sbits64) ( zSig0<<1 ) ) { + zSig0 <<= 1; + --zExp; + } + return roundAndPackFloat64( zSign, zExp, zSig0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of dividing the double-precision floating-point value `a' +by the corresponding value `b'. The operation is performed according to +the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_div( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + bits64 rem0, rem1; + bits64 term0, term1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat64( zSign, 0x7FF, 0 ); + } + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x3FD; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + if ( bSig <= ( aSig + aSig ) ) { + aSig >>= 1; + ++zExp; + } + zSig = estimateDiv128To64( aSig, 0, bSig ); + if ( ( zSig & 0x1FF ) <= 2 ) { + mul64To128( bSig, zSig, &term0, &term1 ); + sub128( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig; + add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); + } + zSig |= ( rem1 != 0 ); + } + return roundAndPackFloat64( zSign, zExp, zSig ); + +} + +#ifndef SOFTFLOAT_FOR_GCC +/* +------------------------------------------------------------------------------- +Returns the remainder of the double-precision floating-point value `a' +with respect to the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_rem( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, expDiff; + bits64 aSig, bSig; + bits64 q, alternateASig; + sbits64 sigMean; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + if ( aExp == 0x7FF ) { + if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { + return propagateFloat64NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return a; + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + expDiff = aExp - bExp; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + aSig >>= 1; + } + q = ( bSig <= aSig ); + if ( q ) aSig -= bSig; + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + aSig = - ( ( bSig>>2 ) * q ); + expDiff -= 62; + } + expDiff += 64; + if ( 0 < expDiff ) { + q = estimateDiv128To64( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + q >>= 64 - expDiff; + bSig >>= 2; + aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; + } + else { + aSig >>= 2; + bSig >>= 2; + } + do { + alternateASig = aSig; + ++q; + aSig -= bSig; + } while ( 0 <= (sbits64) aSig ); + sigMean = aSig + alternateASig; + if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { + aSig = alternateASig; + } + zSign = ( (sbits64) aSig < 0 ); + if ( zSign ) aSig = - aSig; + return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the square root of the double-precision floating-point value `a'. +The operation is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float64_sqrt( float64 a ) +{ + flag aSign; + int16 aExp, zExp; + bits64 aSig, zSig, doubleZSig; + bits64 rem0, rem1, term0, term1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, a ); + if ( ! aSign ) return a; + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aSign ) { + if ( ( aExp | aSig ) == 0 ) return a; + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return 0; + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; + aSig |= LIT64( 0x0010000000000000 ); + zSig = estimateSqrt32( aExp, aSig>>21 ); + aSig <<= 9 - ( aExp & 1 ); + zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 ); + if ( ( zSig & 0x1FF ) <= 5 ) { + doubleZSig = zSig<<1; + mul64To128( zSig, zSig, &term0, &term1 ); + sub128( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig; + doubleZSig -= 2; + add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 ); + } + zSig |= ( ( rem0 | rem1 ) != 0 ); + } + return roundAndPackFloat64( 0, zExp, zSig ); + +} +#endif + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is equal to the +corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_eq( float64 a, float64 b ) +{ + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || + ( (bits64) ( ( FLOAT64_DEMANGLE(a) | FLOAT64_DEMANGLE(b) )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is less than or +equal to the corresponding value `b', and 0 otherwise. The comparison is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_le( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) + return aSign || + ( (bits64) ( ( FLOAT64_DEMANGLE(a) | FLOAT64_DEMANGLE(b) )<<1 ) == + 0 ); + return ( a == b ) || + ( aSign ^ ( FLOAT64_DEMANGLE(a) < FLOAT64_DEMANGLE(b) ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_lt( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) + return aSign && + ( (bits64) ( ( FLOAT64_DEMANGLE(a) | FLOAT64_DEMANGLE(b) )<<1 ) != + 0 ); + return ( a != b ) && + ( aSign ^ ( FLOAT64_DEMANGLE(a) < FLOAT64_DEMANGLE(b) ) ); + +} + +#ifndef SOFTFLOAT_FOR_GCC +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is equal to the +corresponding value `b', and 0 otherwise. The invalid exception is raised +if either operand is a NaN. Otherwise, the comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_eq_signaling( float64 a, float64 b ) +{ + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is less than or +equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +cause an exception. Otherwise, the comparison is performed according to the +IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_le_quiet( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +exception. Otherwise, the comparison is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float64_lt_quiet( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} +#endif + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Returns the result of converting the extended double-precision floating- +point value `a' to the 32-bit two's complement integer format. The +conversion is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic---which means in particular that the conversion +is rounded according to the current rounding mode. If `a' is a NaN, the +largest positive integer is returned. Otherwise, if the conversion +overflows, the largest integer with the same sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +int32 floatx80_to_int32( floatx80 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; + shiftCount = 0x4037 - aExp; + if ( shiftCount <= 0 ) shiftCount = 1; + shift64RightJamming( aSig, shiftCount, &aSig ); + return roundAndPackInt32( aSign, aSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the extended double-precision floating- +point value `a' to the 32-bit two's complement integer format. The +conversion is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic, except that the conversion is always rounded +toward zero. If `a' is a NaN, the largest positive integer is returned. +Otherwise, if the conversion overflows, the largest integer with the same +sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +int32 floatx80_to_int32_round_to_zero( floatx80 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig, savedASig; + int32 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( 0x401E < aExp ) { + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; + goto invalid; + } + else if ( aExp < 0x3FFF ) { + if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + shiftCount = 0x403E - aExp; + savedASig = aSig; + aSig >>= shiftCount; + z = aSig; + if ( aSign ) z = - z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig<>( - shiftCount ); + if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the extended double-precision floating- +point value `a' to the single-precision floating-point format. The +conversion is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 floatx80_to_float32( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat32( floatx80ToCommonNaN( a ) ); + } + return packFloat32( aSign, 0xFF, 0 ); + } + shift64RightJamming( aSig, 33, &aSig ); + if ( aExp || aSig ) aExp -= 0x3F81; + return roundAndPackFloat32( aSign, aExp, aSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the extended double-precision floating- +point value `a' to the double-precision floating-point format. The +conversion is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 floatx80_to_float64( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig, zSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat64( floatx80ToCommonNaN( a ) ); + } + return packFloat64( aSign, 0x7FF, 0 ); + } + shift64RightJamming( aSig, 1, &zSig ); + if ( aExp || aSig ) aExp -= 0x3C01; + return roundAndPackFloat64( aSign, aExp, zSig ); + +} + +#ifdef FLOAT128 + +/* +------------------------------------------------------------------------------- +Returns the result of converting the extended double-precision floating- +point value `a' to the quadruple-precision floating-point format. The +conversion is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float128 floatx80_to_float128( floatx80 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig, zSig0, zSig1; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat128( floatx80ToCommonNaN( a ) ); + } + shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 ); + return packFloat128( aSign, aExp, zSig0, zSig1 ); + +} + +#endif + +/* +------------------------------------------------------------------------------- +Rounds the extended double-precision floating-point value `a' to an integer, +and returns the result as an extended quadruple-precision floating-point +value. The operation is performed according to the IEC/IEEE Standard for +Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_round_to_int( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + floatx80 z; + + aExp = extractFloatx80Exp( a ); + if ( 0x403E <= aExp ) { + if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) { + return propagateFloatx80NaN( a, a ); + } + return a; + } + if ( aExp < 0x3FFF ) { + if ( ( aExp == 0 ) + && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { + return a; + } + float_exception_flags |= float_flag_inexact; + aSign = extractFloatx80Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 ) + ) { + return + packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) ); + } + break; + case float_round_to_zero: + break; + case float_round_down: + return + aSign ? + packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) ) + : packFloatx80( 0, 0, 0 ); + case float_round_up: + return + aSign ? packFloatx80( 1, 0, 0 ) + : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) ); + } + return packFloatx80( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x403E - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z.low += lastBitMask>>1; + if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z.low += roundBitsMask; + } + } + z.low &= ~ roundBitsMask; + if ( z.low == 0 ) { + ++z.high; + z.low = LIT64( 0x8000000000000000 ); + } + if ( z.low != a.low ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the absolute values of the extended double- +precision floating-point values `a' and `b'. If `zSign' is 1, the sum is +negated before being returned. `zSign' is ignored if the result is a NaN. +The addition is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + int32 expDiff; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) { + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) --expDiff; + shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) ++expDiff; + shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); + zExp = bExp; + } + else { + if ( aExp == 0x7FFF ) { + if ( (bits64) ( ( aSig | bSig )<<1 ) ) { + return propagateFloatx80NaN( a, b ); + } + return a; + } + zSig1 = 0; + zSig0 = aSig + bSig; + if ( aExp == 0 ) { + normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 ); + goto roundAndPack; + } + zExp = aExp; + goto shiftRight1; + } + zSig0 = aSig + bSig; + if ( (sbits64) zSig0 < 0 ) goto roundAndPack; + shiftRight1: + shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 ); + zSig0 |= LIT64( 0x8000000000000000 ); + ++zExp; + roundAndPack: + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the absolute values of the extended +double-precision floating-point values `a' and `b'. If `zSign' is 1, the +difference is negated before being returned. `zSign' is ignored if the +result is a NaN. The subtraction is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + int32 expDiff; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( ( aSig | bSig )<<1 ) ) { + return propagateFloatx80NaN( a, b ); + } + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + zSig1 = 0; + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloatx80( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) ++expDiff; + shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); + bBigger: + sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 ); + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) --expDiff; + shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); + aBigger: + sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 ); + zExp = aExp; + normalizeRoundAndPack: + return + normalizeRoundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the extended double-precision floating-point +values `a' and `b'. The operation is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_add( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign == bSign ) { + return addFloatx80Sigs( a, b, aSign ); + } + else { + return subFloatx80Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the extended double-precision floating- +point values `a' and `b'. The operation is performed according to the +IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_sub( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign == bSign ) { + return subFloatx80Sigs( a, b, aSign ); + } + else { + return addFloatx80Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of multiplying the extended double-precision floating- +point values `a' and `b'. The operation is performed according to the +IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_mul( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) + || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { + return propagateFloatx80NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) goto invalid; + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x3FFE; + mul64To128( aSig, bSig, &zSig0, &zSig1 ); + if ( 0 < (sbits64) zSig0 ) { + shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 ); + --zExp; + } + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of dividing the extended double-precision floating-point +value `a' by the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_div( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + bits64 rem0, rem1, rem2, term0, term1, term2; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + goto invalid; + } + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + float_raise( float_flag_divbyzero ); + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x3FFE; + rem1 = 0; + if ( bSig <= aSig ) { + shift128Right( aSig, 0, 1, &aSig, &rem1 ); + ++zExp; + } + zSig0 = estimateDiv128To64( aSig, rem1, bSig ); + mul64To128( bSig, zSig0, &term0, &term1 ); + sub128( aSig, rem1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, bSig ); + if ( (bits64) ( zSig1<<1 ) <= 8 ) { + mul64To128( bSig, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + add128( rem1, rem2, 0, bSig, &rem1, &rem2 ); + } + zSig1 |= ( ( rem1 | rem2 ) != 0 ); + } + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the remainder of the extended double-precision floating-point value +`a' with respect to the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_rem( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, expDiff; + bits64 aSig0, aSig1, bSig; + bits64 q, term0, term1, alternateASig0, alternateASig1; + floatx80 z; + + aSig0 = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig0<<1 ) + || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { + return propagateFloatx80NaN( a, b ); + } + goto invalid; + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( (bits64) ( aSig0<<1 ) == 0 ) return a; + normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); + } + bSig |= LIT64( 0x8000000000000000 ); + zSign = aSign; + expDiff = aExp - bExp; + aSig1 = 0; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + shift128Right( aSig0, 0, 1, &aSig0, &aSig1 ); + expDiff = 0; + } + q = ( bSig <= aSig0 ); + if ( q ) aSig0 -= bSig; + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + mul64To128( bSig, q, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 ); + expDiff -= 62; + } + expDiff += 64; + if ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + q >>= 64 - expDiff; + mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 ); + while ( le128( term0, term1, aSig0, aSig1 ) ) { + ++q; + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + } + } + else { + term1 = 0; + term0 = bSig; + } + sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 ); + if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 ) + || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 ) + && ( q & 1 ) ) + ) { + aSig0 = alternateASig0; + aSig1 = alternateASig1; + zSign = ! zSign; + } + return + normalizeRoundAndPackFloatx80( + 80, zSign, bExp + expDiff, aSig0, aSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the square root of the extended double-precision floating-point +value `a'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_sqrt( floatx80 a ) +{ + flag aSign; + int32 aExp, zExp; + bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + floatx80 z; + + aSig0 = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a ); + if ( ! aSign ) return a; + goto invalid; + } + if ( aSign ) { + if ( ( aExp | aSig0 ) == 0 ) return a; + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + if ( aExp == 0 ) { + if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 ); + normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); + } + zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF; + zSig0 = estimateSqrt32( aExp, aSig0>>32 ); + shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 ); + zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); + doubleZSig0 = zSig0<<1; + mul64To128( zSig0, zSig0, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + doubleZSig0 -= 2; + add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); + if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) { + if ( zSig1 == 0 ) zSig1 = 1; + mul64To128( doubleZSig0, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + mul64To128( zSig1, zSig1, &term2, &term3 ); + sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + shortShift128Left( 0, zSig1, 1, &term2, &term3 ); + term3 |= 1; + term2 |= doubleZSig0; + add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 ); + zSig0 |= doubleZSig0; + return + roundAndPackFloatx80( + floatx80_rounding_precision, 0, zExp, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is +equal to the corresponding value `b', and 0 otherwise. The comparison is +performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag floatx80_eq( floatx80 a, floatx80 b ) +{ + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is +less than or equal to the corresponding value `b', and 0 otherwise. The +comparison is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag floatx80_le( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is +less than the corresponding value `b', and 0 otherwise. The comparison +is performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag floatx80_lt( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is equal +to the corresponding value `b', and 0 otherwise. The invalid exception is +raised if either operand is a NaN. Otherwise, the comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag floatx80_eq_signaling( floatx80 a, floatx80 b ) +{ + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is less +than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs +do not cause an exception. Otherwise, the comparison is performed according +to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag floatx80_le_quiet( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is less +than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause +an exception. Otherwise, the comparison is performed according to the +IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag floatx80_lt_quiet( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +#endif + +#ifdef FLOAT128 + +/* +------------------------------------------------------------------------------- +Returns the result of converting the quadruple-precision floating-point +value `a' to the 32-bit two's complement integer format. The conversion +is performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic---which means in particular that the conversion is rounded +according to the current rounding mode. If `a' is a NaN, the largest +positive integer is returned. Otherwise, if the conversion overflows, the +largest integer with the same sign as `a' is returned. +------------------------------------------------------------------------------- +*/ +int32 float128_to_int32( float128 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0; + if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 ); + aSig0 |= ( aSig1 != 0 ); + shiftCount = 0x4028 - aExp; + if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 ); + return roundAndPackInt32( aSign, aSig0 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the quadruple-precision floating-point +value `a' to the 32-bit two's complement integer format. The conversion +is performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic, except that the conversion is always rounded toward zero. If +`a' is a NaN, the largest positive integer is returned. Otherwise, if the +conversion overflows, the largest integer with the same sign as `a' is +returned. +------------------------------------------------------------------------------- +*/ +int32 float128_to_int32_round_to_zero( float128 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig0, aSig1, savedASig; + int32 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + aSig0 |= ( aSig1 != 0 ); + if ( 0x401E < aExp ) { + if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0; + goto invalid; + } + else if ( aExp < 0x3FFF ) { + if ( aExp || aSig0 ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig0 |= LIT64( 0x0001000000000000 ); + shiftCount = 0x402F - aExp; + savedASig = aSig0; + aSig0 >>= shiftCount; + z = aSig0; + if ( aSign ) z = - z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig0<>( ( - shiftCount ) & 63 ) ); + if ( (bits64) ( aSig1<>( - shiftCount ); + if ( aSig1 + || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) { + float_exception_flags |= float_flag_inexact; + } + } + if ( aSign ) z = - z; + return z; + +} + +#if (defined(SOFTFLOATSPARC64_FOR_GCC) || defined(SOFTFLOAT_FOR_GCC)) \ + && defined(SOFTFLOAT_NEED_FIXUNS) +/* + * just like above - but do not care for overflow of signed results + */ +uint64 float128_to_uint64_round_to_zero( float128 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig0, aSig1; + uint64 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 ); + shiftCount = aExp - 0x402F; + if ( 0 < shiftCount ) { + if ( 0x403F <= aExp ) { + aSig0 &= LIT64( 0x0000FFFFFFFFFFFF ); + if ( ( a.high == LIT64( 0xC03E000000000000 ) ) + && ( aSig1 < LIT64( 0x0002000000000000 ) ) ) { + if ( aSig1 ) float_exception_flags |= float_flag_inexact; + } + else { + float_raise( float_flag_invalid ); + } + return LIT64( 0xFFFFFFFFFFFFFFFF ); + } + z = ( aSig0<>( ( - shiftCount ) & 63 ) ); + if ( (bits64) ( aSig1<>( - shiftCount ); + if (aSig1 || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) { + float_exception_flags |= float_flag_inexact; + } + } + if ( aSign ) z = - z; + return z; + +} +#endif /* (SOFTFLOATSPARC64_FOR_GCC || SOFTFLOAT_FOR_GCC) && SOFTFLOAT_NEED_FIXUNS */ + +/* +------------------------------------------------------------------------------- +Returns the result of converting the quadruple-precision floating-point +value `a' to the single-precision floating-point format. The conversion +is performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +float32 float128_to_float32( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + bits32 zSig; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloat32( float128ToCommonNaN( a ) ); + } + return packFloat32( aSign, 0xFF, 0 ); + } + aSig0 |= ( aSig1 != 0 ); + shift64RightJamming( aSig0, 18, &aSig0 ); + zSig = aSig0; + if ( aExp || zSig ) { + zSig |= 0x40000000; + aExp -= 0x3F81; + } + return roundAndPackFloat32( aSign, aExp, zSig ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the quadruple-precision floating-point +value `a' to the double-precision floating-point format. The conversion +is performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +float64 float128_to_float64( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloat64( float128ToCommonNaN( a ) ); + } + return packFloat64( aSign, 0x7FF, 0 ); + } + shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); + aSig0 |= ( aSig1 != 0 ); + if ( aExp || aSig0 ) { + aSig0 |= LIT64( 0x4000000000000000 ); + aExp -= 0x3C01; + } + return roundAndPackFloat64( aSign, aExp, aSig0 ); + +} + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Returns the result of converting the quadruple-precision floating-point +value `a' to the extended double-precision floating-point format. The +conversion is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +floatx80 float128_to_floatx80( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloatx80( float128ToCommonNaN( a ) ); + } + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + else { + aSig0 |= LIT64( 0x0001000000000000 ); + } + shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 ); + return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 ); + +} + +#endif + +/* +------------------------------------------------------------------------------- +Rounds the quadruple-precision floating-point value `a' to an integer, and +returns the result as a quadruple-precision floating-point value. The +operation is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float128 float128_round_to_int( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + float128 z; + + aExp = extractFloat128Exp( a ); + if ( 0x402F <= aExp ) { + if ( 0x406F <= aExp ) { + if ( ( aExp == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) + ) { + return propagateFloat128NaN( a, a ); + } + return a; + } + lastBitMask = 1; + lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + if ( lastBitMask ) { + add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low ); + if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; + } + else { + if ( (sbits64) z.low < 0 ) { + ++z.high; + if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1; + } + } + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat128Sign( z ) + ^ ( roundingMode == float_round_up ) ) { + add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low ); + } + } + z.low &= ~ roundBitsMask; + } + else { + if ( aExp < 0x3FFF ) { + if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat128Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FFE ) + && ( extractFloat128Frac0( a ) + | extractFloat128Frac1( a ) ) + ) { + return packFloat128( aSign, 0x3FFF, 0, 0 ); + } + break; + case float_round_to_zero: + break; + case float_round_down: + return + aSign ? packFloat128( 1, 0x3FFF, 0, 0 ) + : packFloat128( 0, 0, 0, 0 ); + case float_round_up: + return + aSign ? packFloat128( 1, 0, 0, 0 ) + : packFloat128( 0, 0x3FFF, 0, 0 ); + } + return packFloat128( aSign, 0, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x402F - aExp; + roundBitsMask = lastBitMask - 1; + z.low = 0; + z.high = a.high; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z.high += lastBitMask>>1; + if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) { + z.high &= ~ lastBitMask; + } + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat128Sign( z ) + ^ ( roundingMode == float_round_up ) ) { + z.high |= ( a.low != 0 ); + z.high += roundBitsMask; + } + } + z.high &= ~ roundBitsMask; + } + if ( ( z.low != a.low ) || ( z.high != a.high ) ) { + float_exception_flags |= float_flag_inexact; + } + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the absolute values of the quadruple-precision +floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +before being returned. `zSign' is ignored if the result is a NaN. +The addition is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float128 addFloat128Sigs( float128 a, float128 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + int32 expDiff; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) { + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig0 |= LIT64( 0x0001000000000000 ); + } + shift128ExtraRightJamming( + bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig0 |= LIT64( 0x0001000000000000 ); + } + shift128ExtraRightJamming( + aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 ); + zExp = bExp; + } + else { + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 | bSig0 | bSig1 ) { + return propagateFloat128NaN( a, b ); + } + return a; + } + add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 ); + zSig2 = 0; + zSig0 |= LIT64( 0x0002000000000000 ); + zExp = aExp; + goto shiftRight1; + } + aSig0 |= LIT64( 0x0001000000000000 ); + add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + --zExp; + if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack; + ++zExp; + shiftRight1: + shift128ExtraRightJamming( + zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); + roundAndPack: + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the absolute values of the quadruple- +precision floating-point values `a' and `b'. If `zSign' is 1, the +difference is negated before being returned. `zSign' is ignored if the +result is a NaN. The subtraction is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +static float128 subFloat128Sigs( float128 a, float128 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; + int32 expDiff; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + expDiff = aExp - bExp; + shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); + shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 ); + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 | bSig0 | bSig1 ) { + return propagateFloat128NaN( a, b ); + } + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig0 < aSig0 ) goto aBigger; + if ( aSig0 < bSig0 ) goto bBigger; + if ( bSig1 < aSig1 ) goto aBigger; + if ( aSig1 < bSig1 ) goto bBigger; + return packFloat128( float_rounding_mode == float_round_down, 0, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig0 |= LIT64( 0x4000000000000000 ); + } + shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); + bSig0 |= LIT64( 0x4000000000000000 ); + bBigger: + sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 ); + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig0 |= LIT64( 0x4000000000000000 ); + } + shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 ); + aSig0 |= LIT64( 0x4000000000000000 ); + aBigger: + sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of adding the quadruple-precision floating-point values +`a' and `b'. The operation is performed according to the IEC/IEEE Standard +for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float128 float128_add( float128 a, float128 b ) +{ + flag aSign, bSign; + + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign == bSign ) { + return addFloat128Sigs( a, b, aSign ); + } + else { + return subFloat128Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of subtracting the quadruple-precision floating-point +values `a' and `b'. The operation is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float128 float128_sub( float128 a, float128 b ) +{ + flag aSign, bSign; + + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign == bSign ) { + return subFloat128Sigs( a, b, aSign ); + } + else { + return addFloat128Sigs( a, b, aSign ); + } + +} + +/* +------------------------------------------------------------------------------- +Returns the result of multiplying the quadruple-precision floating-point +values `a' and `b'. The operation is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float128 float128_mul( float128 a, float128 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + bSign = extractFloat128Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( ( aSig0 | aSig1 ) + || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { + return propagateFloat128NaN( a, b ); + } + if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid; + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + if ( ( aExp | aSig0 | aSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); + normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + zExp = aExp + bExp - 0x4000; + aSig0 |= LIT64( 0x0001000000000000 ); + shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 ); + mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 ); + add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 ); + zSig2 |= ( zSig3 != 0 ); + if ( LIT64( 0x0002000000000000 ) <= zSig0 ) { + shift128ExtraRightJamming( + zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); + ++zExp; + } + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of dividing the quadruple-precision floating-point value +`a' by the corresponding value `b'. The operation is performed according to +the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float128 float128_div( float128 a, float128 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + bSign = extractFloat128Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + goto invalid; + } + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return packFloat128( zSign, 0, 0, 0 ); + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) { + if ( ( aExp | aSig0 | aSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + float_raise( float_flag_divbyzero ); + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + zExp = aExp - bExp + 0x3FFD; + shortShift128Left( + aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 ); + shortShift128Left( + bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); + if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) { + shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 ); + ++zExp; + } + zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 ); + mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 ); + sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 ); + } + zSig1 = estimateDiv128To64( rem1, rem2, bSig0 ); + if ( ( zSig1 & 0x3FFF ) <= 4 ) { + mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 ); + sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 ); + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the remainder of the quadruple-precision floating-point value `a' +with respect to the corresponding value `b'. The operation is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float128 float128_rem( float128 a, float128 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, expDiff; + bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2; + bits64 allZero, alternateASig0, alternateASig1, sigMean1; + sbits64 sigMean0; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + bSign = extractFloat128Sign( b ); + if ( aExp == 0x7FFF ) { + if ( ( aSig0 | aSig1 ) + || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { + return propagateFloat128NaN( a, b ); + } + goto invalid; + } + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return a; + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + expDiff = aExp - bExp; + if ( expDiff < -1 ) return a; + shortShift128Left( + aSig0 | LIT64( 0x0001000000000000 ), + aSig1, + 15 - ( expDiff < 0 ), + &aSig0, + &aSig1 + ); + shortShift128Left( + bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); + q = le128( bSig0, bSig1, aSig0, aSig1 ); + if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig0 ); + q = ( 4 < q ) ? q - 4 : 0; + mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); + shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero ); + shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero ); + sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 ); + expDiff -= 61; + } + if ( -64 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig0 ); + q = ( 4 < q ) ? q - 4 : 0; + q >>= - expDiff; + shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); + expDiff += 52; + if ( expDiff < 0 ) { + shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); + } + else { + shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 ); + } + mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); + sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 ); + } + else { + shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 ); + shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); + } + do { + alternateASig0 = aSig0; + alternateASig1 = aSig1; + ++q; + sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); + } while ( 0 <= (sbits64) aSig0 ); + add128( + aSig0, aSig1, alternateASig0, alternateASig1, (bits64 *)&sigMean0, &sigMean1 ); + if ( ( sigMean0 < 0 ) + || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { + aSig0 = alternateASig0; + aSig1 = alternateASig1; + } + zSign = ( (sbits64) aSig0 < 0 ); + if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 ); + return + normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns the square root of the quadruple-precision floating-point value `a'. +The operation is performed according to the IEC/IEEE Standard for Binary +Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +float128 float128_sqrt( float128 a ) +{ + flag aSign; + int32 aExp, zExp; + bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a ); + if ( ! aSign ) return a; + goto invalid; + } + if ( aSign ) { + if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a; + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE; + aSig0 |= LIT64( 0x0001000000000000 ); + zSig0 = estimateSqrt32( aExp, aSig0>>17 ); + shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 ); + zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); + doubleZSig0 = zSig0<<1; + mul64To128( zSig0, zSig0, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + doubleZSig0 -= 2; + add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); + if ( ( zSig1 & 0x1FFF ) <= 5 ) { + if ( zSig1 == 0 ) zSig1 = 1; + mul64To128( doubleZSig0, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + mul64To128( zSig1, zSig1, &term2, &term3 ); + sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + shortShift128Left( 0, zSig1, 1, &term2, &term3 ); + term3 |= 1; + term2 |= doubleZSig0; + add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 ); + return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the quadruple-precision floating-point value `a' is equal to +the corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float128_eq( float128 a, float128 b ) +{ + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the quadruple-precision floating-point value `a' is less than +or equal to the corresponding value `b', and 0 otherwise. The comparison +is performed according to the IEC/IEEE Standard for Binary Floating-Point +Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float128_le( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the quadruple-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. The comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float128_lt( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the quadruple-precision floating-point value `a' is equal to +the corresponding value `b', and 0 otherwise. The invalid exception is +raised if either operand is a NaN. Otherwise, the comparison is performed +according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float128_eq_signaling( float128 a, float128 b ) +{ + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the quadruple-precision floating-point value `a' is less than +or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +cause an exception. Otherwise, the comparison is performed according to the +IEC/IEEE Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float128_le_quiet( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the quadruple-precision floating-point value `a' is less than +the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +exception. Otherwise, the comparison is performed according to the IEC/IEEE +Standard for Binary Floating-Point Arithmetic. +------------------------------------------------------------------------------- +*/ +flag float128_lt_quiet( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +#endif + + +#if defined(SOFTFLOAT_FOR_GCC) && defined(SOFTFLOAT_NEED_FIXUNS) + +/* + * These two routines are not part of the original softfloat distribution. + * + * They are based on the corresponding conversions to integer but return + * unsigned numbers instead since these functions are required by GCC. + * + * Added by Mark Brinicombe 27/09/97 + * + * float64 version overhauled for SoftFloat 2a [bjh21 2000-07-15] + */ + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point value +`a' to the 32-bit unsigned integer format. The conversion is +performed according to the IEC/IEEE Standard for Binary Floating-point +Arithmetic, except that the conversion is always rounded toward zero. If +`a' is a NaN, the largest positive integer is returned. If the conversion +overflows, the largest integer positive is returned. +------------------------------------------------------------------------------- +*/ +uint32 float64_to_uint32_round_to_zero( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig, savedASig; + uint32 z; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + + if (aSign) { + float_raise( float_flag_invalid ); + return(0); + } + + if ( 0x41E < aExp ) { + float_raise( float_flag_invalid ); + return 0xffffffff; + } + else if ( aExp < 0x3FF ) { + if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig |= LIT64( 0x0010000000000000 ); + shiftCount = 0x433 - aExp; + savedASig = aSig; + aSig >>= shiftCount; + z = aSig; + if ( ( aSig<>( - shiftCount ); + if ( aSig<<( shiftCount & 31 ) ) { + float_exception_flags |= float_flag_inexact; + } + return z; + +} + +#endif diff --git a/lib/libc/softfloat/eqdf2.c b/lib/libc/softfloat/eqdf2.c new file mode 100644 index 0000000..c5af96c --- /dev/null +++ b/lib/libc/softfloat/eqdf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: eqdf2.c,v 1.1 2000/06/06 08:15:02 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/eqdf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +flag __eqdf2(float64, float64); + +flag +__eqdf2(float64 a, float64 b) +{ + + /* libgcc1.c says !(a == b) */ + return !float64_eq(a, b); +} diff --git a/lib/libc/softfloat/eqsf2.c b/lib/libc/softfloat/eqsf2.c new file mode 100644 index 0000000..f4194c2 --- /dev/null +++ b/lib/libc/softfloat/eqsf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: eqsf2.c,v 1.1 2000/06/06 08:15:03 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/eqsf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +flag __eqsf2(float32, float32); + +flag +__eqsf2(float32 a, float32 b) +{ + + /* libgcc1.c says !(a == b) */ + return !float32_eq(a, b); +} diff --git a/lib/libc/softfloat/eqtf2.c b/lib/libc/softfloat/eqtf2.c new file mode 100644 index 0000000..5394c26 --- /dev/null +++ b/lib/libc/softfloat/eqtf2.c @@ -0,0 +1,24 @@ +/* $NetBSD: eqtf2.c,v 1.1 2011/01/17 10:08:35 matt Exp $ */ + +/* + * Written by Matt Thomas, 2011. This file is in the Public Domain. + */ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/eqtf2.c 230363 2012-01-20 06:16:14Z das $"); + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#ifdef FLOAT128 +flag __eqtf2(float128, float128); + +flag +__eqtf2(float128 a, float128 b) +{ + + /* libgcc1.c says !(a == b) */ + return !float128_eq(a, b); +} +#endif /* FLOAT128 */ diff --git a/lib/libc/softfloat/fpgetmask.c b/lib/libc/softfloat/fpgetmask.c new file mode 100644 index 0000000..6cb7b02 --- /dev/null +++ b/lib/libc/softfloat/fpgetmask.c @@ -0,0 +1,53 @@ +/* $NetBSD: fpgetmask.c,v 1.4 2008/04/28 20:23:00 martin Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/fpgetmask.c 189647 2009-03-10 21:13:26Z delphij $"); + +#include "namespace.h" + +#include +#ifdef SOFTFLOAT_FOR_GCC +#include "softfloat-for-gcc.h" +#endif +#include "milieu.h" +#include "softfloat.h" + +#ifdef __weak_alias +__weak_alias(fpgetmask,_fpgetmask) +#endif + +fp_except +fpgetmask(void) +{ + + return float_exception_mask; +} diff --git a/lib/libc/softfloat/fpgetround.c b/lib/libc/softfloat/fpgetround.c new file mode 100644 index 0000000..f87ca62 --- /dev/null +++ b/lib/libc/softfloat/fpgetround.c @@ -0,0 +1,53 @@ +/* $NetBSD: fpgetround.c,v 1.3 2008/04/28 20:23:00 martin Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/fpgetround.c 189647 2009-03-10 21:13:26Z delphij $"); + +#include "namespace.h" + +#include +#ifdef SOFTFLOAT_FOR_GCC +#include "softfloat-for-gcc.h" +#endif +#include "milieu.h" +#include "softfloat.h" + +#ifdef __weak_alias +__weak_alias(fpgetround,_fpgetround) +#endif + +fp_rnd_t +fpgetround(void) +{ + + return float_rounding_mode; +} diff --git a/lib/libc/softfloat/fpgetsticky.c b/lib/libc/softfloat/fpgetsticky.c new file mode 100644 index 0000000..292a466 --- /dev/null +++ b/lib/libc/softfloat/fpgetsticky.c @@ -0,0 +1,53 @@ +/* $NetBSD: fpgetsticky.c,v 1.3 2008/04/28 20:23:00 martin Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/fpgetsticky.c 189647 2009-03-10 21:13:26Z delphij $"); + +#include "namespace.h" + +#include +#ifdef SOFTFLOAT_FOR_GCC +#include "softfloat-for-gcc.h" +#endif +#include "milieu.h" +#include "softfloat.h" + +#ifdef __weak_alias +__weak_alias(fpgetsticky,_fpgetsticky) +#endif + +fp_except +fpgetsticky(void) +{ + + return float_exception_flags; +} diff --git a/lib/libc/softfloat/fpsetmask.c b/lib/libc/softfloat/fpsetmask.c new file mode 100644 index 0000000..7b9df0f --- /dev/null +++ b/lib/libc/softfloat/fpsetmask.c @@ -0,0 +1,56 @@ +/* $NetBSD: fpsetmask.c,v 1.4 2008/04/28 20:23:00 martin Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/fpsetmask.c 189647 2009-03-10 21:13:26Z delphij $"); + +#include "namespace.h" + +#include +#ifdef SOFTFLOAT_FOR_GCC +#include "softfloat-for-gcc.h" +#endif +#include "milieu.h" +#include "softfloat.h" + +#ifdef __weak_alias +__weak_alias(fpsetmask,_fpsetmask) +#endif + +fp_except +fpsetmask(fp_except mask) +{ + fp_except old; + + old = float_exception_mask; + float_exception_mask = mask; + return old; +} diff --git a/lib/libc/softfloat/fpsetround.c b/lib/libc/softfloat/fpsetround.c new file mode 100644 index 0000000..4c8187f --- /dev/null +++ b/lib/libc/softfloat/fpsetround.c @@ -0,0 +1,56 @@ +/* $NetBSD: fpsetround.c,v 1.3 2008/04/28 20:23:00 martin Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/fpsetround.c 189647 2009-03-10 21:13:26Z delphij $"); + +#include "namespace.h" + +#include +#ifdef SOFTFLOAT_FOR_GCC +#include "softfloat-for-gcc.h" +#endif +#include "milieu.h" +#include "softfloat.h" + +#ifdef __weak_alias +__weak_alias(fpsetround,_fpsetround) +#endif + +fp_rnd_t +fpsetround(fp_rnd_t rnd_dir) +{ + fp_rnd_t old; + + old = float_rounding_mode; + float_rounding_mode = rnd_dir; + return old; +} diff --git a/lib/libc/softfloat/fpsetsticky.c b/lib/libc/softfloat/fpsetsticky.c new file mode 100644 index 0000000..66a4135 --- /dev/null +++ b/lib/libc/softfloat/fpsetsticky.c @@ -0,0 +1,56 @@ +/* $NetBSD: fpsetsticky.c,v 1.3 2008/04/28 20:23:00 martin Exp $ */ + +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Neil A. Carson and Mark Brinicombe + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/fpsetsticky.c 189647 2009-03-10 21:13:26Z delphij $"); + +#include "namespace.h" + +#include +#ifdef SOFTFLOAT_FOR_GCC +#include "softfloat-for-gcc.h" +#endif +#include "milieu.h" +#include "softfloat.h" + +#ifdef __weak_alias +__weak_alias(fpsetsticky,_fpsetsticky) +#endif + +fp_except +fpsetsticky(fp_except except) +{ + fp_except old; + + old = float_exception_flags; + float_exception_flags = except; + return old; +} diff --git a/lib/libc/softfloat/gedf2.c b/lib/libc/softfloat/gedf2.c new file mode 100644 index 0000000..08782a2 --- /dev/null +++ b/lib/libc/softfloat/gedf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: gedf2.c,v 1.1 2000/06/06 08:15:05 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/gedf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +flag __gedf2(float64, float64); + +flag +__gedf2(float64 a, float64 b) +{ + + /* libgcc1.c says (a >= b) - 1 */ + return float64_le(b, a) - 1; +} diff --git a/lib/libc/softfloat/gesf2.c b/lib/libc/softfloat/gesf2.c new file mode 100644 index 0000000..601234c --- /dev/null +++ b/lib/libc/softfloat/gesf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: gesf2.c,v 1.1 2000/06/06 08:15:05 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/gesf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +flag __gesf2(float32, float32); + +flag +__gesf2(float32 a, float32 b) +{ + + /* libgcc1.c says (a >= b) - 1 */ + return float32_le(b, a) - 1; +} diff --git a/lib/libc/softfloat/getf2.c b/lib/libc/softfloat/getf2.c new file mode 100644 index 0000000..4799370 --- /dev/null +++ b/lib/libc/softfloat/getf2.c @@ -0,0 +1,26 @@ +/* $NetBSD: getf2.c,v 1.1 2011/01/17 10:08:35 matt Exp $ */ + +/* + * Written by Matt Thomas, 2011. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/getf2.c 230363 2012-01-20 06:16:14Z das $"); + +#ifdef FLOAT128 + +flag __getf2(float128, float128); + +flag +__getf2(float128 a, float128 b) +{ + + /* libgcc1.c says (a >= b) - 1 */ + return float128_le(b, a) - 1; +} + +#endif /* FLOAT128 */ diff --git a/lib/libc/softfloat/gexf2.c b/lib/libc/softfloat/gexf2.c new file mode 100644 index 0000000..188b0ec --- /dev/null +++ b/lib/libc/softfloat/gexf2.c @@ -0,0 +1,25 @@ +/* $NetBSD: gexf2.c,v 1.2 2004/09/27 10:16:24 he Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/gexf2.c 230363 2012-01-20 06:16:14Z das $"); + +#ifdef FLOATX80 + +flag __gexf2(floatx80, floatx80); + +flag +__gexf2(floatx80 a, floatx80 b) +{ + + /* libgcc1.c says (a >= b) - 1 */ + return floatx80_le(b, a) - 1; +} +#endif /* FLOATX80 */ diff --git a/lib/libc/softfloat/gtdf2.c b/lib/libc/softfloat/gtdf2.c new file mode 100644 index 0000000..f0dfa03 --- /dev/null +++ b/lib/libc/softfloat/gtdf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: gtdf2.c,v 1.1 2000/06/06 08:15:05 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/gtdf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +flag __gtdf2(float64, float64); + +flag +__gtdf2(float64 a, float64 b) +{ + + /* libgcc1.c says a > b */ + return float64_lt(b, a); +} diff --git a/lib/libc/softfloat/gtsf2.c b/lib/libc/softfloat/gtsf2.c new file mode 100644 index 0000000..093a016 --- /dev/null +++ b/lib/libc/softfloat/gtsf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: gtsf2.c,v 1.1 2000/06/06 08:15:06 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/gtsf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +flag __gtsf2(float32, float32); + +flag +__gtsf2(float32 a, float32 b) +{ + + /* libgcc1.c says a > b */ + return float32_lt(b, a); +} diff --git a/lib/libc/softfloat/gttf2.c b/lib/libc/softfloat/gttf2.c new file mode 100644 index 0000000..d441477 --- /dev/null +++ b/lib/libc/softfloat/gttf2.c @@ -0,0 +1,26 @@ +/* $NetBSD: gttf2.c,v 1.1 2011/01/17 10:08:35 matt Exp $ */ + +/* + * Written by Matt Thomas, 2011. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/gttf2.c 230363 2012-01-20 06:16:14Z das $"); + +#ifdef FLOAT128 + +flag __gttf2(float128, float128); + +flag +__gttf2(float128 a, float128 b) +{ + + /* libgcc1.c says a > b */ + return float128_lt(b, a); +} + +#endif /* FLOAT128 */ diff --git a/lib/libc/softfloat/gtxf2.c b/lib/libc/softfloat/gtxf2.c new file mode 100644 index 0000000..d1e08a2 --- /dev/null +++ b/lib/libc/softfloat/gtxf2.c @@ -0,0 +1,25 @@ +/* $NetBSD: gtxf2.c,v 1.2 2004/09/27 10:16:24 he Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/gtxf2.c 230363 2012-01-20 06:16:14Z das $"); + +#ifdef FLOATX80 + +flag __gtxf2(floatx80, floatx80); + +flag +__gtxf2(floatx80 a, floatx80 b) +{ + + /* libgcc1.c says a > b */ + return floatx80_lt(b, a); +} +#endif /* FLOATX80 */ diff --git a/lib/libc/softfloat/ledf2.c b/lib/libc/softfloat/ledf2.c new file mode 100644 index 0000000..7d8f9c9 --- /dev/null +++ b/lib/libc/softfloat/ledf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: ledf2.c,v 1.1 2000/06/06 08:15:06 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/ledf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +flag __ledf2(float64, float64); + +flag +__ledf2(float64 a, float64 b) +{ + + /* libgcc1.c says 1 - (a <= b) */ + return 1 - float64_le(a, b); +} diff --git a/lib/libc/softfloat/lesf2.c b/lib/libc/softfloat/lesf2.c new file mode 100644 index 0000000..13105b2 --- /dev/null +++ b/lib/libc/softfloat/lesf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: lesf2.c,v 1.1 2000/06/06 08:15:06 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/lesf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +flag __lesf2(float32, float32); + +flag +__lesf2(float32 a, float32 b) +{ + + /* libgcc1.c says 1 - (a <= b) */ + return 1 - float32_le(a, b); +} diff --git a/lib/libc/softfloat/letf2.c b/lib/libc/softfloat/letf2.c new file mode 100644 index 0000000..3661912 --- /dev/null +++ b/lib/libc/softfloat/letf2.c @@ -0,0 +1,26 @@ +/* $NetBSD: letf2.c,v 1.1 2011/01/17 10:08:35 matt Exp $ */ + +/* + * Written by Matt Thomas, 2011. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/letf2.c 230363 2012-01-20 06:16:14Z das $"); + +#ifdef FLOAT128 + +flag __letf2(float128, float128); + +flag +__letf2(float128 a, float128 b) +{ + + /* libgcc1.c says 1 - (a <= b) */ + return 1 - float128_le(a, b); +} + +#endif /* FLOAT128 */ diff --git a/lib/libc/softfloat/ltdf2.c b/lib/libc/softfloat/ltdf2.c new file mode 100644 index 0000000..73fe67a --- /dev/null +++ b/lib/libc/softfloat/ltdf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: ltdf2.c,v 1.1 2000/06/06 08:15:06 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/ltdf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +flag __ltdf2(float64, float64); + +flag +__ltdf2(float64 a, float64 b) +{ + + /* libgcc1.c says -(a < b) */ + return -float64_lt(a, b); +} diff --git a/lib/libc/softfloat/ltsf2.c b/lib/libc/softfloat/ltsf2.c new file mode 100644 index 0000000..33204cb --- /dev/null +++ b/lib/libc/softfloat/ltsf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: ltsf2.c,v 1.1 2000/06/06 08:15:06 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/ltsf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +flag __ltsf2(float32, float32); + +flag +__ltsf2(float32 a, float32 b) +{ + + /* libgcc1.c says -(a < b) */ + return -float32_lt(a, b); +} diff --git a/lib/libc/softfloat/lttf2.c b/lib/libc/softfloat/lttf2.c new file mode 100644 index 0000000..1da9e4a --- /dev/null +++ b/lib/libc/softfloat/lttf2.c @@ -0,0 +1,26 @@ +/* $NetBSD: lttf2.c,v 1.1 2011/01/17 10:08:35 matt Exp $ */ + +/* + * Written by Matt Thomas, 2011. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/lttf2.c 230363 2012-01-20 06:16:14Z das $"); + +#ifdef FLOAT128 + +flag __lttf2(float128, float128); + +flag +__lttf2(float128 a, float128 b) +{ + + /* libgcc1.c says -(a < b) */ + return -float128_lt(a, b); +} + +#endif /* FLOAT128 */ diff --git a/lib/libc/softfloat/nedf2.c b/lib/libc/softfloat/nedf2.c new file mode 100644 index 0000000..0398573 --- /dev/null +++ b/lib/libc/softfloat/nedf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: nedf2.c,v 1.1 2000/06/06 08:15:07 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/nedf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +flag __nedf2(float64, float64); + +flag +__nedf2(float64 a, float64 b) +{ + + /* libgcc1.c says a != b */ + return !float64_eq(a, b); +} diff --git a/lib/libc/softfloat/negdf2.c b/lib/libc/softfloat/negdf2.c new file mode 100644 index 0000000..1677061 --- /dev/null +++ b/lib/libc/softfloat/negdf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: negdf2.c,v 1.1 2000/06/06 08:15:07 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/negdf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +float64 __negdf2(float64); + +float64 +__negdf2(float64 a) +{ + + /* libgcc1.c says -a */ + return a ^ FLOAT64_MANGLE(0x8000000000000000ULL); +} diff --git a/lib/libc/softfloat/negsf2.c b/lib/libc/softfloat/negsf2.c new file mode 100644 index 0000000..09682d9 --- /dev/null +++ b/lib/libc/softfloat/negsf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: negsf2.c,v 1.1 2000/06/06 08:15:07 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/negsf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +float32 __negsf2(float32); + +float32 +__negsf2(float32 a) +{ + + /* libgcc1.c says INTIFY(-a) */ + return a ^ 0x80000000; +} diff --git a/lib/libc/softfloat/negtf2.c b/lib/libc/softfloat/negtf2.c new file mode 100644 index 0000000..5f3724d --- /dev/null +++ b/lib/libc/softfloat/negtf2.c @@ -0,0 +1,27 @@ +/* $NetBSD: negtf2.c,v 1.1 2011/01/17 10:08:35 matt Exp $ */ + +/* + * Written by Matt Thomas, 2011. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/negtf2.c 230363 2012-01-20 06:16:14Z das $"); + +#ifdef FLOAT128 + +float128 __negtf2(float128); + +float128 +__negtf2(float128 a) +{ + + /* libgcc1.c says -a */ + a.high ^= FLOAT64_MANGLE(0x8000000000000000ULL); + return a; +} + +#endif /* FLOAT128 */ diff --git a/lib/libc/softfloat/negxf2.c b/lib/libc/softfloat/negxf2.c new file mode 100644 index 0000000..73a065e --- /dev/null +++ b/lib/libc/softfloat/negxf2.c @@ -0,0 +1,25 @@ +/* $NetBSD: negxf2.c,v 1.2 2004/09/27 10:16:24 he Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/negxf2.c 230363 2012-01-20 06:16:14Z das $"); + +#ifdef FLOATX80 + +floatx80 __negxf2(floatx80); + +floatx80 +__negxf2(floatx80 a) +{ + + /* libgcc1.c says -a */ + return __mulxf3(a,__floatsixf(-1)); +} +#endif /* FLOATX80 */ diff --git a/lib/libc/softfloat/nesf2.c b/lib/libc/softfloat/nesf2.c new file mode 100644 index 0000000..84f74c6 --- /dev/null +++ b/lib/libc/softfloat/nesf2.c @@ -0,0 +1,22 @@ +/* $NetBSD: nesf2.c,v 1.1 2000/06/06 08:15:07 bjh21 Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/nesf2.c 129203 2004-05-14 12:13:06Z cognet $"); + +flag __nesf2(float32, float32); + +flag +__nesf2(float32 a, float32 b) +{ + + /* libgcc1.c says a != b */ + return !float32_eq(a, b); +} diff --git a/lib/libc/softfloat/netf2.c b/lib/libc/softfloat/netf2.c new file mode 100644 index 0000000..fe28cc0 --- /dev/null +++ b/lib/libc/softfloat/netf2.c @@ -0,0 +1,26 @@ +/* $NetBSD: netf2.c,v 1.1 2011/01/17 10:08:35 matt Exp $ */ + +/* + * Written by Matt Thomas, 2011. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/netf2.c 230363 2012-01-20 06:16:14Z das $"); + +#ifdef FLOAT128 + +flag __netf2(float128, float128); + +flag +__netf2(float128 a, float128 b) +{ + + /* libgcc1.c says a != b */ + return !float128_eq(a, b); +} + +#endif /* FLOAT128 */ diff --git a/lib/libc/softfloat/nexf2.c b/lib/libc/softfloat/nexf2.c new file mode 100644 index 0000000..19c5bee --- /dev/null +++ b/lib/libc/softfloat/nexf2.c @@ -0,0 +1,25 @@ +/* $NetBSD: nexf2.c,v 1.2 2004/09/27 10:16:24 he Exp $ */ + +/* + * Written by Ben Harris, 2000. This file is in the Public Domain. + */ + +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/nexf2.c 230363 2012-01-20 06:16:14Z das $"); + +#ifdef FLOATX80 + +flag __nexf2(floatx80, floatx80); + +flag +__nexf2(floatx80 a, floatx80 b) +{ + + /* libgcc1.c says a != b */ + return !floatx80_eq(a, b); +} +#endif /* FLOATX80 */ diff --git a/lib/libc/softfloat/softfloat-for-gcc.h b/lib/libc/softfloat/softfloat-for-gcc.h new file mode 100644 index 0000000..7c5f765 --- /dev/null +++ b/lib/libc/softfloat/softfloat-for-gcc.h @@ -0,0 +1,169 @@ +/* $NetBSD: softfloat-for-gcc.h,v 1.8 2009/12/14 01:07:42 matt Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/softfloat/softfloat-for-gcc.h 230363 2012-01-20 06:16:14Z das $ */ + +/* + * Move private identifiers with external linkage into implementation + * namespace. -- Klaus Klein , May 5, 1999 + */ +#define float_exception_flags __softfloat_float_exception_flags +#define float_exception_mask __softfloat_float_exception_mask +#define float_rounding_mode __softfloat_float_rounding_mode +#define float_raise __softfloat_float_raise +/* The following batch are called by GCC through wrappers */ +#define float32_eq __softfloat_float32_eq +#define float32_le __softfloat_float32_le +#define float32_lt __softfloat_float32_lt +#define float64_eq __softfloat_float64_eq +#define float64_le __softfloat_float64_le +#define float64_lt __softfloat_float64_lt +#define float128_eq __softfloat_float128_eq +#define float128_le __softfloat_float128_le +#define float128_lt __softfloat_float128_lt + +/* + * Macros to define functions with the GCC expected names + */ + +#define float32_add __addsf3 +#define float64_add __adddf3 +#define floatx80_add __addxf3 +#define float128_add __addtf3 + +#define float32_sub __subsf3 +#define float64_sub __subdf3 +#define floatx80_sub __subxf3 +#define float128_sub __subtf3 + +#define float32_mul __mulsf3 +#define float64_mul __muldf3 +#define floatx80_mul __mulxf3 +#define float128_mul __multf3 + +#define float32_div __divsf3 +#define float64_div __divdf3 +#define floatx80_div __divxf3 +#define float128_div __divtf3 + +#if 0 +#define float32_neg __negsf2 +#define float64_neg __negdf2 +#define floatx80_neg __negxf2 +#define float128_neg __negtf2 +#endif + +#define int32_to_float32 __floatsisf +#define int32_to_float64 __floatsidf +#define int32_to_floatx80 __floatsixf +#define int32_to_float128 __floatsitf + +#define int64_to_float32 __floatdisf +#define int64_to_float64 __floatdidf +#define int64_to_floatx80 __floatdixf +#define int64_to_float128 __floatditf + +#define int128_to_float32 __floattisf +#define int128_to_float64 __floattidf +#define int128_to_floatx80 __floattixf +#define int128_to_float128 __floattitf + +#define uint32_to_float32 __floatunsisf +#define uint32_to_float64 __floatunsidf +#define uint32_to_floatx80 __floatunsixf +#define uint32_to_float128 __floatunsitf + +#define uint64_to_float32 __floatundisf +#define uint64_to_float64 __floatundidf +#define uint64_to_floatx80 __floatundixf +#define uint64_to_float128 __floatunditf + +#define uint128_to_float32 __floatuntisf +#define uint128_to_float64 __floatuntidf +#define uint128_to_floatx80 __floatuntixf +#define uint128_to_float128 __floatuntitf + +#define float32_to_int32_round_to_zero __fixsfsi +#define float64_to_int32_round_to_zero __fixdfsi +#define floatx80_to_int32_round_to_zero __fixxfsi +#define float128_to_int32_round_to_zero __fixtfsi + +#define float32_to_int64_round_to_zero __fixsfdi +#define float64_to_int64_round_to_zero __fixdfdi +#define floatx80_to_int64_round_to_zero __fixxfdi +#define float128_to_int64_round_to_zero __fixtfdi + +#define float32_to_int128_round_to_zero __fixsfti +#define float64_to_int128_round_to_zero __fixdfti +#define floatx80_to_int128_round_to_zero __fixxfti +#define float128_to_int128_round_to_zero __fixtfti + +#define float32_to_uint32_round_to_zero __fixunssfsi +#define float64_to_uint32_round_to_zero __fixunsdfsi +#define floatx80_to_uint32_round_to_zero __fixunsxfsi +#define float128_to_uint32_round_to_zero __fixunstfsi + +#define float32_to_uint64_round_to_zero __fixunssfdi +#define float64_to_uint64_round_to_zero __fixunsdfdi +#define floatx80_to_uint64_round_to_zero __fixunsxfdi +#define float128_to_uint64_round_to_zero __fixunstfdi + +#define float32_to_uint128_round_to_zero __fixunssfti +#define float64_to_uint128_round_to_zero __fixunsdfti +#define floatx80_to_uint128_round_to_zero __fixunsxfti +#define float128_to_uint128_round_to_zero __fixunstfti + +#define float32_to_float64 __extendsfdf2 +#define float32_to_floatx80 __extendsfxf2 +#define float32_to_float128 __extendsftf2 +#define float64_to_floatx80 __extenddfxf2 +#define float64_to_float128 __extenddftf2 + +#define float128_to_float64 __trunctfdf2 +#define floatx80_to_float64 __truncxfdf2 +#define float128_to_float32 __trunctfsf2 +#define floatx80_to_float32 __truncxfsf2 +#define float64_to_float32 __truncdfsf2 + +#if 0 +#define float32_cmp __cmpsf2 +#define float32_unord __unordsf2 +#define float32_eq __eqsf2 +#define float32_ne __nesf2 +#define float32_ge __gesf2 +#define float32_lt __ltsf2 +#define float32_le __lesf2 +#define float32_gt __gtsf2 +#endif + +#if 0 +#define float64_cmp __cmpdf2 +#define float64_unord __unorddf2 +#define float64_eq __eqdf2 +#define float64_ne __nedf2 +#define float64_ge __gedf2 +#define float64_lt __ltdf2 +#define float64_le __ledf2 +#define float64_gt __gtdf2 +#endif + +/* XXX not in libgcc */ +#if 1 +#define floatx80_cmp __cmpxf2 +#define floatx80_unord __unordxf2 +#define floatx80_eq __eqxf2 +#define floatx80_ne __nexf2 +#define floatx80_ge __gexf2 +#define floatx80_lt __ltxf2 +#define floatx80_le __lexf2 +#define floatx80_gt __gtxf2 +#endif + +#if 0 +#define float128_cmp __cmptf2 +#define float128_unord __unordtf2 +#define float128_eq __eqtf2 +#define float128_ne __netf2 +#define float128_ge __getf2 +#define float128_lt __lttf2 +#define float128_le __letf2 +#define float128_gt __gttf2 +#endif diff --git a/lib/libc/softfloat/softfloat-history.txt b/lib/libc/softfloat/softfloat-history.txt new file mode 100644 index 0000000..67b7687 --- /dev/null +++ b/lib/libc/softfloat/softfloat-history.txt @@ -0,0 +1,53 @@ +$NetBSD: softfloat-history.txt,v 1.1 2000/06/06 08:15:08 bjh21 Exp $ +$FreeBSD: releng/11.1/lib/libc/softfloat/softfloat-history.txt 129203 2004-05-14 12:13:06Z cognet $ + +History of Major Changes to SoftFloat, up to Release 2a + +John R. Hauser +1998 December 16 + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Release 2a (1998 December) + +-- Added functions to convert between 64-bit integers (int64) and all + supported floating-point formats. + +-- Fixed a bug in all 64-bit-version square root functions except + `float32_sqrt' that caused the result sometimes to be off by 1 unit in + the last place (1 ulp) from what it should be. (Bug discovered by Paul + Donahue.) + +-- Improved the makefiles. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Release 2 (1997 June) + +-- Created the 64-bit (bits64) version, adding the floatx80 and float128 + formats. + +-- Changed the source directory structure, splitting the sources into a + `bits32' and a `bits64' version. Renamed `environment.h' to `milieu.h' + (to avoid confusion with environment variables). + +-- Fixed a small error that caused `float64_round_to_int' often to round the + wrong way in nearest/even mode when the operand was between 2^20 and 2^21 + and halfway between two integers. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Release 1a (1996 July) + +-- Corrected a mistake that caused borderline underflow cases not to raise + the underflow flag when they should have. (Problem reported by Doug + Priest.) + +-- Added the `float_detect_tininess' variable to control whether tininess is + detected before or after rounding. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Release 1 (1996 July) + +-- Original release. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/lib/libc/softfloat/softfloat-source.txt b/lib/libc/softfloat/softfloat-source.txt new file mode 100644 index 0000000..3f7680d --- /dev/null +++ b/lib/libc/softfloat/softfloat-source.txt @@ -0,0 +1,384 @@ +$NetBSD: softfloat-source.txt,v 1.2 2006/11/24 19:46:58 christos Exp $ +$FreeBSD: releng/11.1/lib/libc/softfloat/softfloat-source.txt 230363 2012-01-20 06:16:14Z das $ + +SoftFloat Release 2a Source Documentation + +John R. Hauser +1998 December 14 + + +------------------------------------------------------------------------------- +Introduction + +SoftFloat is a software implementation of floating-point that conforms to +the IEC/IEEE Standard for Binary Floating-Point Arithmetic. SoftFloat can +support four floating-point formats: single precision, double precision, +extended double precision, and quadruple precision. All operations required +by the IEEE Standard are implemented, except for conversions to and from +decimal. SoftFloat is distributed in the form of C source code, so a +C compiler is needed to compile the code. Support for the extended double- +precision and quadruple-precision formats is dependent on the C compiler +implementing a 64-bit integer type. + +This document gives information needed for compiling and/or porting +SoftFloat. + +The source code for SoftFloat is intended to be relatively machine- +independent and should be compilable using any ISO/ANSI C compiler. At the +time of this writing, SoftFloat has been successfully compiled with the GNU +C Compiler (`gcc') for several platforms. + + +------------------------------------------------------------------------------- +Limitations + +SoftFloat as written requires an ISO/ANSI-style C compiler. No attempt has +been made to accommodate compilers that are not ISO-conformant. Older ``K&R- +style'' compilers are not adequate for compiling SoftFloat. All testing I +have done so far has been with the GNU C Compiler. Compilation with other +compilers should be possible but has not been tested. + +The SoftFloat sources assume that source code file names can be longer than +8 characters. In order to compile under an MS-DOS-type system, many of the +source files will need to be renamed, and the source and makefiles edited +appropriately. Once compiled, the SoftFloat binary does not depend on the +existence of long file names. + +The underlying machine is assumed to be binary with a word size that is a +power of 2. Bytes are 8 bits. Support for the extended double-precision +and quadruple-precision formats depends on the C compiler implementing +a 64-bit integer type. If the largest integer type supported by the +C compiler is 32 bits, SoftFloat is limited to the single- and double- +precision formats. + + +------------------------------------------------------------------------------- +Contents + + Introduction + Limitations + Contents + Legal Notice + SoftFloat Source Directory Structure + SoftFloat Source Files + processors/*.h + softfloat/bits*/*/softfloat.h + softfloat/bits*/*/milieu.h + softfloat/bits*/*/softfloat-specialize + softfloat/bits*/softfloat-macros + softfloat/bits*/softfloat.c + Steps to Creating a `softfloat.o' + Making `softfloat.o' a Library + Testing SoftFloat + Timing SoftFloat + Compiler Options and Efficiency + Processor-Specific Optimization of `softfloat.c' Using `softfloat-macros' + Contact Information + + + +------------------------------------------------------------------------------- +Legal Notice + +SoftFloat was written by John R. Hauser. This work was made possible in +part by the International Computer Science Institute, located at Suite 600, +1947 Center Street, Berkeley, California 94704. Funding was partially +provided by the National Science Foundation under grant MIP-9311980. The +original version of this code was written as part of a project to build +a fixed-point vector processor in collaboration with the University of +California at Berkeley, overseen by Profs. Nelson Morgan and John Wawrzynek. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + + +------------------------------------------------------------------------------- +SoftFloat Source Directory Structure + +Because SoftFloat is targeted to multiple platforms, its source code +is slightly scattered between target-specific and target-independent +directories and files. The directory structure is as follows: + + processors + softfloat + bits64 + templates + 386-Win32-gcc + SPARC-Solaris-gcc + bits32 + templates + 386-Win32-gcc + SPARC-Solaris-gcc + +The two topmost directories and their contents are: + + softfloat - Most of the source code needed for SoftFloat. + processors - Target-specific header files that are not specific to + SoftFloat. + +The `softfloat' directory is further split into two parts: + + bits64 - SoftFloat implementation using 64-bit integers. + bits32 - SoftFloat implementation using only 32-bit integers. + +Within these directories are subdirectories for each of the targeted +platforms. The SoftFloat source code is distributed with targets +`386-Win32-gcc' and `SPARC-Solaris-gcc' (and perhaps others) already +prepared for both the 32-bit and 64-bit implementations. Source files that +are not within these target-specific subdirectories are intended to be +target-independent. + +The naming convention used for the target-specific directories is +`--'. The names of the supplied +target directories should be interpreted as follows: + + : + 386 - Intel 386-compatible processor. + SPARC - SPARC processor (as used by Sun machines). + : + Win32 - Microsoft Win32 executable. + Solaris - Sun Solaris executable. + : + gcc - GNU C Compiler. + +You do not need to maintain this convention if you do not want to. + +Alongside the supplied target-specific directories is a `templates' +directory containing a set of ``generic'' target-specific source files. A +new target directory can be created by copying the `templates' directory and +editing the files inside. (Complete instructions for porting SoftFloat to a +new target are in the section _Steps_to_Creating_a_`softfloat.o'_.) Note +that the `templates' directory will not work as a target directory without +some editing. To avoid confusion, it would be wise to refrain from editing +the files inside `templates' directly. + + +------------------------------------------------------------------------------- +SoftFloat Source Files + +The purpose of each source file is described below. In the following, +the `*' symbol is used in place of the name of a specific target, such as +`386-Win32-gcc' or `SPARC-Solaris-gcc', or in place of some other text, as +in `bits*' for either `bits32' or `bits64'. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +processors/*.h + +The target-specific `processors' header file defines integer types +of various sizes, and also defines certain C preprocessor macros that +characterize the target. The two examples supplied are `386-gcc.h' and +`SPARC-gcc.h'. The naming convention used for processor header files is +`-.h'. + +If 64-bit integers are supported by the compiler, the macro name `BITS64' +should be defined here along with the corresponding 64-bit integer +types. In addition, the function-like macro `LIT64' must be defined for +constructing 64-bit integer literals (constants). The `LIT64' macro is used +consistently in the SoftFloat code to annotate 64-bit literals. + +If `BITS64' is not defined, only the 32-bit version of SoftFloat can be +compiled. If `BITS64' _is_ defined, either can be compiled. + +If an inlining attribute (such as an `inline' keyword) is provided by the +compiler, the macro `INLINE' should be defined to the appropriate keyword. +If not, `INLINE' can be set to the keyword `static'. The `INLINE' macro +appears in the SoftFloat source code before every function that should +be inlined by the compiler. SoftFloat depends on inlining to obtain +good speed. Even if inlining cannot be forced with a language keyword, +the compiler may still be able to perform inlining on its own as an +optimization. If a command-line option is needed to convince the compiler +to perform this optimization, this should be assured in the makefile. (See +the section _Compiler_Options_and_Efficiency_ below.) + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +softfloat/bits*/*/softfloat.h + +The target-specific `softfloat.h' header file defines the SoftFloat +interface as seen by clients. + +Unlike the actual function definitions in `softfloat.c', the declarations +in `softfloat.h' do not use any of the types defined by the `processors' +header file. This is done so that clients will not have to include the +`processors' header file in order to use SoftFloat. Nevertheless, the +target-specific declarations in `softfloat.h' must match what `softfloat.c' +expects. For example, if `int32' is defined as `int' in the `processors' +header file, then in `softfloat.h' the output of `float32_to_int32' should +be stated as `int', although in `softfloat.c' it is given in target- +independent form as `int32'. + +For the `bits64' implementation of SoftFloat, the macro names `FLOATX80' and +`FLOAT128' must be defined in order for the extended double-precision and +quadruple-precision formats to be enabled in the code. Conversely, either +or both of the extended formats can be disabled by simply removing the +`#define' of the respective macro. When an extended format is not enabled, +none of the functions that either input or output the format are defined, +and no space is taken up in `softfloat.o' by such functions. There is no +provision for disabling the usual single- and double-precision formats. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +softfloat/bits*/*/milieu.h + +The target-specific `milieu.h' header file provides declarations that are +needed to compile SoftFloat. In addition, deviations from ISO/ANSI C by +the compiler (such as names not properly declared in system header files) +are corrected in this header if possible. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +softfloat/bits*/*/softfloat-specialize + +This target-specific C source fragment defines: + +-- whether tininess for underflow is detected before or after rounding by + default; +-- what (if anything) special happens when exceptions are raised; +-- how signaling NaNs are distinguished from quiet NaNs; +-- the default generated quiet NaNs; and +-- how NaNs are propagated from function inputs to output. + +These details are not decided by the IEC/IEEE Standard. This fragment is +included verbatim within `softfloat.c' when SoftFloat is compiled. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +softfloat/bits*/softfloat-macros + +This target-independent C source fragment defines a number of arithmetic +functions used as primitives within the `softfloat.c' source. Most of the +functions defined here are intended to be inlined for efficiency. This +fragment is included verbatim within `softfloat.c' when SoftFloat is +compiled. + +Target-specific variations on this file are possible. See the section +_Processor-Specific_Optimization_of_`softfloat.c'_Using_`softfloat-macros'_ +below. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +softfloat/bits*/softfloat.c + +The target-independent `softfloat.c' source file contains the body of the +SoftFloat implementation. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +The inclusion of the files above within each other (using `#include') can be +shown graphically as follows: + + softfloat/bits*/softfloat.c + softfloat/bits*/*/milieu.h + processors/*.h + softfloat/bits*/*/softfloat.h + softfloat/bits*/*/softfloat-specialize + softfloat/bits*/softfloat-macros + +Note in particular that `softfloat.c' does not include the `processors' +header file directly. Rather, `softfloat.c' includes the target-specific +`milieu.h' header file, which in turn includes the processor header file. + + +------------------------------------------------------------------------------- +Steps to Creating a `softfloat.o' + +Porting and/or compiling SoftFloat involves the following steps: + +1. If one does not already exist, create an appropriate `.h' file in the + `processors' directory. + +2. If `BITS64' is defined in the `processors' header file, choose whether + to compile the 32-bit or 64-bit implementation of SoftFloat. If + `BITS64' is not defined, your only choice is the 32-bit implementation. + The remaining steps occur within either the `bits32' or `bits64' + subdirectories. + +3. If one does not already exist, create an appropriate target-specific + subdirectory by copying the given `templates' directory. + +4. In the target-specific subdirectory, edit the files `softfloat-specialize' + and `softfloat.h' to define the desired exception handling functions + and mode control values. In the `softfloat.h' header file, ensure also + that all declarations give the proper target-specific type (such as + `int' or `long') corresponding to the target-independent type used in + `softfloat.c' (such as `int32'). None of the type names declared in the + `processors' header file should appear in `softfloat.h'. + +5. In the target-specific subdirectory, edit the files `milieu.h' and + `Makefile' to reflect the current environment. + +6. In the target-specific subdirectory, execute `make'. + +For the targets that are supplied, if the expected compiler is available +(usually `gcc'), it should only be necessary to execute `make' in the +target-specific subdirectory. + + +------------------------------------------------------------------------------- +Making `softfloat.o' a Library + +SoftFloat is not made into a software library by the supplied makefile. +If desired, `softfloat.o' can easily be put into its own library (in Unix, +`softfloat.a') using the usual system tool (in Unix, `ar'). + + +------------------------------------------------------------------------------- +Testing SoftFloat + +SoftFloat can be tested using the `testsoftfloat' program by the same +author. The `testsoftfloat' program is part of the TestFloat package +available at the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/ +TestFloat.html'. + + +------------------------------------------------------------------------------- +Timing SoftFloat + +A program called `timesoftfloat' for timing the SoftFloat functions is +included with the SoftFloat source code. Compiling `timesoftfloat' should +pose no difficulties once `softfloat.o' exists. The supplied makefile +will create a `timesoftfloat' executable by default after generating +`softfloat.o'. See `timesoftfloat.txt' for documentation about using +`timesoftfloat'. + + +------------------------------------------------------------------------------- +Compiler Options and Efficiency + +In order to get good speed with SoftFloat, it is important that the compiler +inline the routines that have been marked `INLINE' in the code. Even if +inlining cannot be forced by an appropriate definition of the `INLINE' +macro, the compiler may still be able to perform inlining on its own as +an optimization. In that case, the makefile should be edited to give the +compiler whatever option is required to cause it to inline small functions. + +The ability of the processor to do fast shifts has been assumed. Efficiency +will not be as good on processors for which this is not the case (such as +the original Motorola 68000 or Intel 8086 processors). + + +------------------------------------------------------------------------------- +Processor-Specific Optimization of `softfloat.c' Using `softfloat-macros' + +The `softfloat-macros' source fragment defines arithmetic functions used +as primitives by `softfloat.c'. This file has been written in a target- +independent form. For a given target, it may be possible to improve on +these functions using target-specific and/or non-ISO-C features (such +as `asm' statements). For example, one of the ``macro'' functions takes +two word-size integers and returns their full product in two words. +This operation can be done directly in hardware on many processors; but +because it is not available through standard C, the function defined in +`softfloat-macros' uses four multiplies to achieve the same result. + +To address these shortcomings, a customized version of `softfloat-macros' +can be created in any of the target-specific subdirectories. A simple +modification to the target's makefile should be sufficient to ensure that +the custom version is used instead of the generic one. + + +------------------------------------------------------------------------------- +Contact Information + +At the time of this writing, the most up-to-date information about +SoftFloat and the latest release can be found at the Web page `http:// +HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html'. + + diff --git a/lib/libc/softfloat/softfloat-specialize b/lib/libc/softfloat/softfloat-specialize new file mode 100644 index 0000000..106f778 --- /dev/null +++ b/lib/libc/softfloat/softfloat-specialize @@ -0,0 +1,521 @@ +/* $NetBSD: softfloat-specialize,v 1.6 2011/03/06 10:27:37 martin Exp $ */ +/* $FreeBSD: releng/11.1/lib/libc/softfloat/softfloat-specialize 230363 2012-01-20 06:16:14Z das $ */ + +/* This is a derivative work. */ + +/* +=============================================================================== + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +#include +#include +#include + +/* +------------------------------------------------------------------------------- +Underflow tininess-detection mode, statically initialized to default value. +(The declaration in `softfloat.h' must match the `int8' type here.) +------------------------------------------------------------------------------- +*/ +#ifdef SOFTFLOAT_FOR_GCC +static +#endif +#ifdef __sparc64__ +int8 float_detect_tininess = float_tininess_before_rounding; +#else +int8 float_detect_tininess = float_tininess_after_rounding; +#endif + +/* +------------------------------------------------------------------------------- +Raises the exceptions specified by `flags'. Floating-point traps can be +defined here if desired. It is currently not possible for such a trap to +substitute a result value. If traps are not implemented, this routine +should be simply `float_exception_flags |= flags;'. +------------------------------------------------------------------------------- +*/ +#ifdef SOFTFLOAT_FOR_GCC +#define float_exception_mask __softfloat_float_exception_mask +#endif +int float_exception_mask = 0; +void float_raise( int flags ) +{ + + float_exception_flags |= flags; + + if ( flags & float_exception_mask ) { +#if 0 + siginfo_t info; + memset(&info, 0, sizeof info); + info.si_signo = SIGFPE; + info.si_pid = getpid(); + info.si_uid = geteuid(); + if (flags & float_flag_underflow) + info.si_code = FPE_FLTUND; + else if (flags & float_flag_overflow) + info.si_code = FPE_FLTOVF; + else if (flags & float_flag_divbyzero) + info.si_code = FPE_FLTDIV; + else if (flags & float_flag_invalid) + info.si_code = FPE_FLTINV; + else if (flags & float_flag_inexact) + info.si_code = FPE_FLTRES; + sigqueueinfo(getpid(), &info); +#else + raise( SIGFPE ); +#endif + } +} +#undef float_exception_mask + +/* +------------------------------------------------------------------------------- +Internal canonical NaN format. +------------------------------------------------------------------------------- +*/ +typedef struct { + flag sign; + bits64 high, low; +} commonNaNT; + +/* +------------------------------------------------------------------------------- +The pattern for a default generated single-precision NaN. +------------------------------------------------------------------------------- +*/ +#define float32_default_nan 0xFFFFFFFF + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is a NaN; +otherwise returns 0. +------------------------------------------------------------------------------- +*/ +#ifdef SOFTFLOAT_FOR_GCC +static +#endif +flag float32_is_nan( float32 a ) +{ + + return ( 0xFF000000 < (bits32) ( a<<1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is a signaling +NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +#if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \ + !defined(SOFTFLOAT_M68K_FOR_GCC) +static +#endif +flag float32_is_signaling_nan( float32 a ) +{ + + return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point NaN +`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +exception is raised. +------------------------------------------------------------------------------- +*/ +static commonNaNT float32ToCommonNaN( float32 a ) +{ + commonNaNT z; + + if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a>>31; + z.low = 0; + z.high = ( (bits64) a )<<41; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the canonical NaN `a' to the single- +precision floating-point format. +------------------------------------------------------------------------------- +*/ +static float32 commonNaNToFloat32( commonNaNT a ) +{ + + return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); + +} + +/* +------------------------------------------------------------------------------- +Takes two single-precision floating-point values `a' and `b', one of which +is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static float32 propagateFloat32NaN( float32 a, float32 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float32_is_nan( a ); + aIsSignalingNaN = float32_is_signaling_nan( a ); + bIsNaN = float32_is_nan( b ); + bIsSignalingNaN = float32_is_signaling_nan( b ); + a |= 0x00400000; + b |= 0x00400000; + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +/* +------------------------------------------------------------------------------- +The pattern for a default generated double-precision NaN. +------------------------------------------------------------------------------- +*/ +#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is a NaN; +otherwise returns 0. +------------------------------------------------------------------------------- +*/ +#ifdef SOFTFLOAT_FOR_GCC +static +#endif +flag float64_is_nan( float64 a ) +{ + + return ( LIT64( 0xFFE0000000000000 ) < + (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is a signaling +NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +#if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \ + !defined(SOFTFLOATM68K_FOR_GCC) +static +#endif +flag float64_is_signaling_nan( float64 a ) +{ + + return + ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE ) + && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point NaN +`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +exception is raised. +------------------------------------------------------------------------------- +*/ +static commonNaNT float64ToCommonNaN( float64 a ) +{ + commonNaNT z; + + if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = FLOAT64_DEMANGLE(a)>>63; + z.low = 0; + z.high = FLOAT64_DEMANGLE(a)<<12; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the canonical NaN `a' to the double- +precision floating-point format. +------------------------------------------------------------------------------- +*/ +static float64 commonNaNToFloat64( commonNaNT a ) +{ + + return FLOAT64_MANGLE( + ( ( (bits64) a.sign )<<63 ) + | LIT64( 0x7FF8000000000000 ) + | ( a.high>>12 ) ); + +} + +/* +------------------------------------------------------------------------------- +Takes two double-precision floating-point values `a' and `b', one of which +is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static float64 propagateFloat64NaN( float64 a, float64 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float64_is_nan( a ); + aIsSignalingNaN = float64_is_signaling_nan( a ); + bIsNaN = float64_is_nan( b ); + bIsSignalingNaN = float64_is_signaling_nan( b ); + a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 )); + b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 )); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +The pattern for a default generated extended double-precision NaN. The +`high' and `low' values hold the most- and least-significant bits, +respectively. +------------------------------------------------------------------------------- +*/ +#define floatx80_default_nan_high 0xFFFF +#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is a +NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag floatx80_is_nan( floatx80 a ) +{ + + return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is a +signaling NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag floatx80_is_signaling_nan( floatx80 a ) +{ + bits64 aLow; + + aLow = a.low & ~ LIT64( 0x4000000000000000 ); + return + ( ( a.high & 0x7FFF ) == 0x7FFF ) + && (bits64) ( aLow<<1 ) + && ( a.low == aLow ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the extended double-precision floating- +point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the +invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static commonNaNT floatx80ToCommonNaN( floatx80 a ) +{ + commonNaNT z; + + if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a.high>>15; + z.low = 0; + z.high = a.low<<1; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the canonical NaN `a' to the extended +double-precision floating-point format. +------------------------------------------------------------------------------- +*/ +static floatx80 commonNaNToFloatx80( commonNaNT a ) +{ + floatx80 z; + + z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); + z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; + return z; + +} + +/* +------------------------------------------------------------------------------- +Takes two extended double-precision floating-point values `a' and `b', one +of which is a NaN, and returns the appropriate NaN result. If either `a' or +`b' is a signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = floatx80_is_nan( a ); + aIsSignalingNaN = floatx80_is_signaling_nan( a ); + bIsNaN = floatx80_is_nan( b ); + bIsSignalingNaN = floatx80_is_signaling_nan( b ); + a.low |= LIT64( 0xC000000000000000 ); + b.low |= LIT64( 0xC000000000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +#endif + +#ifdef FLOAT128 + +/* +------------------------------------------------------------------------------- +The pattern for a default generated quadruple-precision NaN. The `high' and +`low' values hold the most- and least-significant bits, respectively. +------------------------------------------------------------------------------- +*/ +#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF ) +#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) + +/* +------------------------------------------------------------------------------- +Returns 1 if the quadruple-precision floating-point value `a' is a NaN; +otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag float128_is_nan( float128 a ) +{ + + return + ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) + && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the quadruple-precision floating-point value `a' is a +signaling NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag float128_is_signaling_nan( float128 a ) +{ + + return + ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) + && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the quadruple-precision floating-point NaN +`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +exception is raised. +------------------------------------------------------------------------------- +*/ +static commonNaNT float128ToCommonNaN( float128 a ) +{ + commonNaNT z; + + if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a.high>>63; + shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the canonical NaN `a' to the quadruple- +precision floating-point format. +------------------------------------------------------------------------------- +*/ +static float128 commonNaNToFloat128( commonNaNT a ) +{ + float128 z; + + shift128Right( a.high, a.low, 16, &z.high, &z.low ); + z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); + return z; + +} + +/* +------------------------------------------------------------------------------- +Takes two quadruple-precision floating-point values `a' and `b', one of +which is a NaN, and returns the appropriate NaN result. If either `a' or +`b' is a signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static float128 propagateFloat128NaN( float128 a, float128 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float128_is_nan( a ); + aIsSignalingNaN = float128_is_signaling_nan( a ); + bIsNaN = float128_is_nan( b ); + bIsSignalingNaN = float128_is_signaling_nan( b ); + a.high |= LIT64( 0x0000800000000000 ); + b.high |= LIT64( 0x0000800000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +#endif + diff --git a/lib/libc/softfloat/softfloat.txt b/lib/libc/softfloat/softfloat.txt new file mode 100644 index 0000000..f6c7c21 --- /dev/null +++ b/lib/libc/softfloat/softfloat.txt @@ -0,0 +1,373 @@ +$NetBSD: softfloat.txt,v 1.2 2006/11/24 19:46:58 christos Exp $ +$FreeBSD: releng/11.1/lib/libc/softfloat/softfloat.txt 230363 2012-01-20 06:16:14Z das $ + +SoftFloat Release 2a General Documentation + +John R. Hauser +1998 December 13 + + +------------------------------------------------------------------------------- +Introduction + +SoftFloat is a software implementation of floating-point that conforms to +the IEC/IEEE Standard for Binary Floating-Point Arithmetic. As many as four +formats are supported: single precision, double precision, extended double +precision, and quadruple precision. All operations required by the standard +are implemented, except for conversions to and from decimal. + +This document gives information about the types defined and the routines +implemented by SoftFloat. It does not attempt to define or explain the +IEC/IEEE Floating-Point Standard. Details about the standard are available +elsewhere. + + +------------------------------------------------------------------------------- +Limitations + +SoftFloat is written in C and is designed to work with other C code. The +SoftFloat header files assume an ISO/ANSI-style C compiler. No attempt +has been made to accommodate compilers that are not ISO-conformant. In +particular, the distributed header files will not be acceptable to any +compiler that does not recognize function prototypes. + +Support for the extended double-precision and quadruple-precision formats +depends on a C compiler that implements 64-bit integer arithmetic. If the +largest integer format supported by the C compiler is 32 bits, SoftFloat is +limited to only single and double precisions. When that is the case, all +references in this document to the extended double precision, quadruple +precision, and 64-bit integers should be ignored. + + +------------------------------------------------------------------------------- +Contents + + Introduction + Limitations + Contents + Legal Notice + Types and Functions + Rounding Modes + Extended Double-Precision Rounding Precision + Exceptions and Exception Flags + Function Details + Conversion Functions + Standard Arithmetic Functions + Remainder Functions + Round-to-Integer Functions + Comparison Functions + Signaling NaN Test Functions + Raise-Exception Function + Contact Information + + + +------------------------------------------------------------------------------- +Legal Notice + +SoftFloat was written by John R. Hauser. This work was made possible in +part by the International Computer Science Institute, located at Suite 600, +1947 Center Street, Berkeley, California 94704. Funding was partially +provided by the National Science Foundation under grant MIP-9311980. The +original version of this code was written as part of a project to build +a fixed-point vector processor in collaboration with the University of +California at Berkeley, overseen by Profs. Nelson Morgan and John Wawrzynek. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + + +------------------------------------------------------------------------------- +Types and Functions + +When 64-bit integers are supported by the compiler, the `softfloat.h' header +file defines four types: `float32' (single precision), `float64' (double +precision), `floatx80' (extended double precision), and `float128' +(quadruple precision). The `float32' and `float64' types are defined in +terms of 32-bit and 64-bit integer types, respectively, while the `float128' +type is defined as a structure of two 64-bit integers, taking into account +the byte order of the particular machine being used. The `floatx80' type +is defined as a structure containing one 16-bit and one 64-bit integer, with +the machine's byte order again determining the order of the `high' and `low' +fields. + +When 64-bit integers are _not_ supported by the compiler, the `softfloat.h' +header file defines only two types: `float32' and `float64'. Because +ISO/ANSI C guarantees at least one built-in integer type of 32 bits, +the `float32' type is identified with an appropriate integer type. The +`float64' type is defined as a structure of two 32-bit integers, with the +machine's byte order determining the order of the fields. + +In either case, the types in `softfloat.h' are defined such that if a system +implements the usual C `float' and `double' types according to the IEC/IEEE +Standard, then the `float32' and `float64' types should be indistinguishable +in memory from the native `float' and `double' types. (On the other hand, +when `float32' or `float64' values are placed in processor registers by +the compiler, the type of registers used may differ from those used for the +native `float' and `double' types.) + +SoftFloat implements the following arithmetic operations: + +-- Conversions among all the floating-point formats, and also between + integers (32-bit and 64-bit) and any of the floating-point formats. + +-- The usual add, subtract, multiply, divide, and square root operations + for all floating-point formats. + +-- For each format, the floating-point remainder operation defined by the + IEC/IEEE Standard. + +-- For each floating-point format, a ``round to integer'' operation that + rounds to the nearest integer value in the same format. (The floating- + point formats can hold integer values, of course.) + +-- Comparisons between two values in the same floating-point format. + +The only functions required by the IEC/IEEE Standard that are not provided +are conversions to and from decimal. + + +------------------------------------------------------------------------------- +Rounding Modes + +All four rounding modes prescribed by the IEC/IEEE Standard are implemented +for all operations that require rounding. The rounding mode is selected +by the global variable `float_rounding_mode'. This variable may be set +to one of the values `float_round_nearest_even', `float_round_to_zero', +`float_round_down', or `float_round_up'. The rounding mode is initialized +to nearest/even. + + +------------------------------------------------------------------------------- +Extended Double-Precision Rounding Precision + +For extended double precision (`floatx80') only, the rounding precision +of the standard arithmetic operations is controlled by the global variable +`floatx80_rounding_precision'. The operations affected are: + + floatx80_add floatx80_sub floatx80_mul floatx80_div floatx80_sqrt + +When `floatx80_rounding_precision' is set to its default value of 80, these +operations are rounded (as usual) to the full precision of the extended +double-precision format. Setting `floatx80_rounding_precision' to 32 +or to 64 causes the operations listed to be rounded to reduced precision +equivalent to single precision (`float32') or to double precision +(`float64'), respectively. When rounding to reduced precision, additional +bits in the result significand beyond the rounding point are set to zero. +The consequences of setting `floatx80_rounding_precision' to a value other +than 32, 64, or 80 is not specified. Operations other than the ones listed +above are not affected by `floatx80_rounding_precision'. + + +------------------------------------------------------------------------------- +Exceptions and Exception Flags + +All five exception flags required by the IEC/IEEE Standard are +implemented. Each flag is stored as a unique bit in the global variable +`float_exception_flags'. The positions of the exception flag bits within +this variable are determined by the bit masks `float_flag_inexact', +`float_flag_underflow', `float_flag_overflow', `float_flag_divbyzero', and +`float_flag_invalid'. The exception flags variable is initialized to all 0, +meaning no exceptions. + +An individual exception flag can be cleared with the statement + + float_exception_flags &= ~ float_flag_; + +where `' is the appropriate name. To raise a floating-point +exception, the SoftFloat function `float_raise' should be used (see below). + +In the terminology of the IEC/IEEE Standard, SoftFloat can detect tininess +for underflow either before or after rounding. The choice is made by +the global variable `float_detect_tininess', which can be set to either +`float_tininess_before_rounding' or `float_tininess_after_rounding'. +Detecting tininess after rounding is better because it results in fewer +spurious underflow signals. The other option is provided for compatibility +with some systems. Like most systems, SoftFloat always detects loss of +accuracy for underflow as an inexact result. + + +------------------------------------------------------------------------------- +Function Details + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Conversion Functions + +All conversions among the floating-point formats are supported, as are all +conversions between a floating-point format and 32-bit and 64-bit signed +integers. The complete set of conversion functions is: + + int32_to_float32 int64_to_float32 + int32_to_float64 int64_to_float32 + int32_to_floatx80 int64_to_floatx80 + int32_to_float128 int64_to_float128 + + float32_to_int32 float32_to_int64 + float32_to_int32 float64_to_int64 + floatx80_to_int32 floatx80_to_int64 + float128_to_int32 float128_to_int64 + + float32_to_float64 float32_to_floatx80 float32_to_float128 + float64_to_float32 float64_to_floatx80 float64_to_float128 + floatx80_to_float32 floatx80_to_float64 floatx80_to_float128 + float128_to_float32 float128_to_float64 float128_to_floatx80 + +Each conversion function takes one operand of the appropriate type and +returns one result. Conversions from a smaller to a larger floating-point +format are always exact and so require no rounding. Conversions from 32-bit +integers to double precision and larger formats are also exact, and likewise +for conversions from 64-bit integers to extended double and quadruple +precisions. + +Conversions from floating-point to integer raise the invalid exception if +the source value cannot be rounded to a representable integer of the desired +size (32 or 64 bits). If the floating-point operand is a NaN, the largest +positive integer is returned. Otherwise, if the conversion overflows, the +largest integer with the same sign as the operand is returned. + +On conversions to integer, if the floating-point operand is not already an +integer value, the operand is rounded according to the current rounding +mode as specified by `float_rounding_mode'. Because C (and perhaps other +languages) require that conversions to integers be rounded toward zero, the +following functions are provided for improved speed and convenience: + + float32_to_int32_round_to_zero float32_to_int64_round_to_zero + float64_to_int32_round_to_zero float64_to_int64_round_to_zero + floatx80_to_int32_round_to_zero floatx80_to_int64_round_to_zero + float128_to_int32_round_to_zero float128_to_int64_round_to_zero + +These variant functions ignore `float_rounding_mode' and always round toward +zero. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Standard Arithmetic Functions + +The following standard arithmetic functions are provided: + + float32_add float32_sub float32_mul float32_div float32_sqrt + float64_add float64_sub float64_mul float64_div float64_sqrt + floatx80_add floatx80_sub floatx80_mul floatx80_div floatx80_sqrt + float128_add float128_sub float128_mul float128_div float128_sqrt + +Each function takes two operands, except for `sqrt' which takes only one. +The operands and result are all of the same type. + +Rounding of the extended double-precision (`floatx80') functions is affected +by the `floatx80_rounding_precision' variable, as explained above in the +section _Extended_Double-Precision_Rounding_Precision_. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Remainder Functions + +For each format, SoftFloat implements the remainder function according to +the IEC/IEEE Standard. The remainder functions are: + + float32_rem + float64_rem + floatx80_rem + float128_rem + +Each remainder function takes two operands. The operands and result are all +of the same type. Given operands x and y, the remainder functions return +the value x - n*y, where n is the integer closest to x/y. If x/y is exactly +halfway between two integers, n is the even integer closest to x/y. The +remainder functions are always exact and so require no rounding. + +Depending on the relative magnitudes of the operands, the remainder +functions can take considerably longer to execute than the other SoftFloat +functions. This is inherent in the remainder operation itself and is not a +flaw in the SoftFloat implementation. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Round-to-Integer Functions + +For each format, SoftFloat implements the round-to-integer function +specified by the IEC/IEEE Standard. The functions are: + + float32_round_to_int + float64_round_to_int + floatx80_round_to_int + float128_round_to_int + +Each function takes a single floating-point operand and returns a result of +the same type. (Note that the result is not an integer type.) The operand +is rounded to an exact integer according to the current rounding mode, and +the resulting integer value is returned in the same floating-point format. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Comparison Functions + +The following floating-point comparison functions are provided: + + float32_eq float32_le float32_lt + float64_eq float64_le float64_lt + floatx80_eq floatx80_le floatx80_lt + float128_eq float128_le float128_lt + +Each function takes two operands of the same type and returns a 1 or 0 +representing either _true_ or _false_. The abbreviation `eq' stands for +``equal'' (=); `le' stands for ``less than or equal'' (<=); and `lt' stands +for ``less than'' (<). + +The standard greater-than (>), greater-than-or-equal (>=), and not-equal +(!=) functions are easily obtained using the functions provided. The +not-equal function is just the logical complement of the equal function. +The greater-than-or-equal function is identical to the less-than-or-equal +function with the operands reversed; and the greater-than function can be +obtained from the less-than function in the same way. + +The IEC/IEEE Standard specifies that the less-than-or-equal and less-than +functions raise the invalid exception if either input is any kind of NaN. +The equal functions, on the other hand, are defined not to raise the invalid +exception on quiet NaNs. For completeness, SoftFloat provides the following +additional functions: + + float32_eq_signaling float32_le_quiet float32_lt_quiet + float64_eq_signaling float64_le_quiet float64_lt_quiet + floatx80_eq_signaling floatx80_le_quiet floatx80_lt_quiet + float128_eq_signaling float128_le_quiet float128_lt_quiet + +The `signaling' equal functions are identical to the standard functions +except that the invalid exception is raised for any NaN input. Likewise, +the `quiet' comparison functions are identical to their counterparts except +that the invalid exception is not raised for quiet NaNs. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Signaling NaN Test Functions + +The following functions test whether a floating-point value is a signaling +NaN: + + float32_is_signaling_nan + float64_is_signaling_nan + floatx80_is_signaling_nan + float128_is_signaling_nan + +The functions take one operand and return 1 if the operand is a signaling +NaN and 0 otherwise. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Raise-Exception Function + +SoftFloat provides a function for raising floating-point exceptions: + + float_raise + +The function takes a mask indicating the set of exceptions to raise. No +result is returned. In addition to setting the specified exception flags, +this function may cause a trap or abort appropriate for the current system. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +------------------------------------------------------------------------------- +Contact Information + +At the time of this writing, the most up-to-date information about +SoftFloat and the latest release can be found at the Web page `http:// +HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html'. + + diff --git a/lib/libc/softfloat/templates/milieu.h b/lib/libc/softfloat/templates/milieu.h new file mode 100644 index 0000000..b20343b --- /dev/null +++ b/lib/libc/softfloat/templates/milieu.h @@ -0,0 +1,49 @@ +/* $FreeBSD: releng/11.1/lib/libc/softfloat/templates/milieu.h 129203 2004-05-14 12:13:06Z cognet $ */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Include common integer types and flags. +------------------------------------------------------------------------------- +*/ +#include "../../../processors/!!!processor.h" + +/* +------------------------------------------------------------------------------- +Symbolic Boolean literals. +------------------------------------------------------------------------------- +*/ +enum { + FALSE = 0, + TRUE = 1 +}; + diff --git a/lib/libc/softfloat/templates/softfloat-specialize b/lib/libc/softfloat/templates/softfloat-specialize new file mode 100644 index 0000000..ab9a85f --- /dev/null +++ b/lib/libc/softfloat/templates/softfloat-specialize @@ -0,0 +1,465 @@ +/* $FreeBSD: releng/11.1/lib/libc/softfloat/templates/softfloat-specialize 129203 2004-05-14 12:13:06Z cognet $ */ + +/* +=============================================================================== + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Underflow tininess-detection mode, statically initialized to default value. +(The declaration in `softfloat.h' must match the `int8' type here.) +------------------------------------------------------------------------------- +*/ +int8 float_detect_tininess = float_tininess_after_rounding; + +/* +------------------------------------------------------------------------------- +Raises the exceptions specified by `flags'. Floating-point traps can be +defined here if desired. It is currently not possible for such a trap to +substitute a result value. If traps are not implemented, this routine +should be simply `float_exception_flags |= flags;'. +------------------------------------------------------------------------------- +*/ +void float_raise( int8 flags ) +{ + + float_exception_flags |= flags; + +} + +/* +------------------------------------------------------------------------------- +Internal canonical NaN format. +------------------------------------------------------------------------------- +*/ +typedef struct { + flag sign; + bits64 high, low; +} commonNaNT; + +/* +------------------------------------------------------------------------------- +The pattern for a default generated single-precision NaN. +------------------------------------------------------------------------------- +*/ +#define float32_default_nan 0xFFFFFFFF + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is a NaN; +otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag float32_is_nan( float32 a ) +{ + + return ( 0xFF000000 < (bits32) ( a<<1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the single-precision floating-point value `a' is a signaling +NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag float32_is_signaling_nan( float32 a ) +{ + + return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the single-precision floating-point NaN +`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +exception is raised. +------------------------------------------------------------------------------- +*/ +static commonNaNT float32ToCommonNaN( float32 a ) +{ + commonNaNT z; + + if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a>>31; + z.low = 0; + z.high = ( (bits64) a )<<41; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the canonical NaN `a' to the single- +precision floating-point format. +------------------------------------------------------------------------------- +*/ +static float32 commonNaNToFloat32( commonNaNT a ) +{ + + return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); + +} + +/* +------------------------------------------------------------------------------- +Takes two single-precision floating-point values `a' and `b', one of which +is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static float32 propagateFloat32NaN( float32 a, float32 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float32_is_nan( a ); + aIsSignalingNaN = float32_is_signaling_nan( a ); + bIsNaN = float32_is_nan( b ); + bIsSignalingNaN = float32_is_signaling_nan( b ); + a |= 0x00400000; + b |= 0x00400000; + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +/* +------------------------------------------------------------------------------- +The pattern for a default generated double-precision NaN. +------------------------------------------------------------------------------- +*/ +#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is a NaN; +otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag float64_is_nan( float64 a ) +{ + + return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the double-precision floating-point value `a' is a signaling +NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag float64_is_signaling_nan( float64 a ) +{ + + return + ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) + && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the double-precision floating-point NaN +`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +exception is raised. +------------------------------------------------------------------------------- +*/ +static commonNaNT float64ToCommonNaN( float64 a ) +{ + commonNaNT z; + + if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a>>63; + z.low = 0; + z.high = a<<12; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the canonical NaN `a' to the double- +precision floating-point format. +------------------------------------------------------------------------------- +*/ +static float64 commonNaNToFloat64( commonNaNT a ) +{ + + return + ( ( (bits64) a.sign )<<63 ) + | LIT64( 0x7FF8000000000000 ) + | ( a.high>>12 ); + +} + +/* +------------------------------------------------------------------------------- +Takes two double-precision floating-point values `a' and `b', one of which +is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static float64 propagateFloat64NaN( float64 a, float64 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float64_is_nan( a ); + aIsSignalingNaN = float64_is_signaling_nan( a ); + bIsNaN = float64_is_nan( b ); + bIsSignalingNaN = float64_is_signaling_nan( b ); + a |= LIT64( 0x0008000000000000 ); + b |= LIT64( 0x0008000000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +The pattern for a default generated extended double-precision NaN. The +`high' and `low' values hold the most- and least-significant bits, +respectively. +------------------------------------------------------------------------------- +*/ +#define floatx80_default_nan_high 0xFFFF +#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is a +NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag floatx80_is_nan( floatx80 a ) +{ + + return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the extended double-precision floating-point value `a' is a +signaling NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag floatx80_is_signaling_nan( floatx80 a ) +{ + bits64 aLow; + + aLow = a.low & ~ LIT64( 0x4000000000000000 ); + return + ( ( a.high & 0x7FFF ) == 0x7FFF ) + && (bits64) ( aLow<<1 ) + && ( a.low == aLow ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the extended double-precision floating- +point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the +invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static commonNaNT floatx80ToCommonNaN( floatx80 a ) +{ + commonNaNT z; + + if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a.high>>15; + z.low = 0; + z.high = a.low<<1; + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the canonical NaN `a' to the extended +double-precision floating-point format. +------------------------------------------------------------------------------- +*/ +static floatx80 commonNaNToFloatx80( commonNaNT a ) +{ + floatx80 z; + + z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); + z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; + return z; + +} + +/* +------------------------------------------------------------------------------- +Takes two extended double-precision floating-point values `a' and `b', one +of which is a NaN, and returns the appropriate NaN result. If either `a' or +`b' is a signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = floatx80_is_nan( a ); + aIsSignalingNaN = floatx80_is_signaling_nan( a ); + bIsNaN = floatx80_is_nan( b ); + bIsSignalingNaN = floatx80_is_signaling_nan( b ); + a.low |= LIT64( 0xC000000000000000 ); + b.low |= LIT64( 0xC000000000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +#endif + +#ifdef FLOAT128 + +/* +------------------------------------------------------------------------------- +The pattern for a default generated quadruple-precision NaN. The `high' and +`low' values hold the most- and least-significant bits, respectively. +------------------------------------------------------------------------------- +*/ +#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF ) +#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) + +/* +------------------------------------------------------------------------------- +Returns 1 if the quadruple-precision floating-point value `a' is a NaN; +otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag float128_is_nan( float128 a ) +{ + + return + ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) + && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns 1 if the quadruple-precision floating-point value `a' is a +signaling NaN; otherwise returns 0. +------------------------------------------------------------------------------- +*/ +flag float128_is_signaling_nan( float128 a ) +{ + + return + ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) + && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the quadruple-precision floating-point NaN +`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +exception is raised. +------------------------------------------------------------------------------- +*/ +static commonNaNT float128ToCommonNaN( float128 a ) +{ + commonNaNT z; + + if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a.high>>63; + shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); + return z; + +} + +/* +------------------------------------------------------------------------------- +Returns the result of converting the canonical NaN `a' to the quadruple- +precision floating-point format. +------------------------------------------------------------------------------- +*/ +static float128 commonNaNToFloat128( commonNaNT a ) +{ + float128 z; + + shift128Right( a.high, a.low, 16, &z.high, &z.low ); + z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); + return z; + +} + +/* +------------------------------------------------------------------------------- +Takes two quadruple-precision floating-point values `a' and `b', one of +which is a NaN, and returns the appropriate NaN result. If either `a' or +`b' is a signaling NaN, the invalid exception is raised. +------------------------------------------------------------------------------- +*/ +static float128 propagateFloat128NaN( float128 a, float128 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float128_is_nan( a ); + aIsSignalingNaN = float128_is_signaling_nan( a ); + bIsNaN = float128_is_nan( b ); + bIsSignalingNaN = float128_is_signaling_nan( b ); + a.high |= LIT64( 0x0000800000000000 ); + b.high |= LIT64( 0x0000800000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsNaN ) { + return ( aIsSignalingNaN & bIsNaN ) ? b : a; + } + else { + return b; + } + +} + +#endif + diff --git a/lib/libc/softfloat/templates/softfloat.h b/lib/libc/softfloat/templates/softfloat.h new file mode 100644 index 0000000..bfd9117 --- /dev/null +++ b/lib/libc/softfloat/templates/softfloat.h @@ -0,0 +1,291 @@ +/* $FreeBSD: releng/11.1/lib/libc/softfloat/templates/softfloat.h 129203 2004-05-14 12:13:06Z cognet $ */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +The macro `FLOATX80' must be defined to enable the extended double-precision +floating-point format `floatx80'. If this macro is not defined, the +`floatx80' type will not be defined, and none of the functions that either +input or output the `floatx80' type will be defined. The same applies to +the `FLOAT128' macro and the quadruple-precision format `float128'. +------------------------------------------------------------------------------- +*/ +#define FLOATX80 +#define FLOAT128 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point types. +------------------------------------------------------------------------------- +*/ +typedef !!!bits32 float32; +typedef !!!bits64 float64; +#ifdef FLOATX80 +typedef struct { + !!!bits16 high; + !!!bits64 low; +} floatx80; +#endif +#ifdef FLOAT128 +typedef struct { + !!!bits64 high, low; +} float128; +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point underflow tininess-detection mode. +------------------------------------------------------------------------------- +*/ +extern !!!int8 float_detect_tininess; +enum { + float_tininess_after_rounding = 0, + float_tininess_before_rounding = 1 +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point rounding mode. +------------------------------------------------------------------------------- +*/ +extern !!!int8 float_rounding_mode; +enum { + float_round_nearest_even = 0, + float_round_to_zero = 1, + float_round_down = 2, + float_round_up = 3 +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point exception flags. +------------------------------------------------------------------------------- +*/ +extern !!!int8 float_exception_flags; +enum { + float_flag_inexact = 1, + float_flag_underflow = 2, + float_flag_overflow = 4, + float_flag_divbyzero = 8, + float_flag_invalid = 16 +}; + +/* +------------------------------------------------------------------------------- +Routine to raise any or all of the software IEC/IEEE floating-point +exception flags. +------------------------------------------------------------------------------- +*/ +void float_raise( !!!int8 ); + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE integer-to-floating-point conversion routines. +------------------------------------------------------------------------------- +*/ +float32 int32_to_float32( !!!int32 ); +float64 int32_to_float64( !!!int32 ); +#ifdef FLOATX80 +floatx80 int32_to_floatx80( !!!int32 ); +#endif +#ifdef FLOAT128 +float128 int32_to_float128( !!!int32 ); +#endif +float32 int64_to_float32( !!!int64 ); +float64 int64_to_float64( !!!int64 ); +#ifdef FLOATX80 +floatx80 int64_to_floatx80( !!!int64 ); +#endif +#ifdef FLOAT128 +float128 int64_to_float128( !!!int64 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision conversion routines. +------------------------------------------------------------------------------- +*/ +!!!int32 float32_to_int32( float32 ); +!!!int32 float32_to_int32_round_to_zero( float32 ); +!!!int64 float32_to_int64( float32 ); +!!!int64 float32_to_int64_round_to_zero( float32 ); +float64 float32_to_float64( float32 ); +#ifdef FLOATX80 +floatx80 float32_to_floatx80( float32 ); +#endif +#ifdef FLOAT128 +float128 float32_to_float128( float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision operations. +------------------------------------------------------------------------------- +*/ +float32 float32_round_to_int( float32 ); +float32 float32_add( float32, float32 ); +float32 float32_sub( float32, float32 ); +float32 float32_mul( float32, float32 ); +float32 float32_div( float32, float32 ); +float32 float32_rem( float32, float32 ); +float32 float32_sqrt( float32 ); +!!!flag float32_eq( float32, float32 ); +!!!flag float32_le( float32, float32 ); +!!!flag float32_lt( float32, float32 ); +!!!flag float32_eq_signaling( float32, float32 ); +!!!flag float32_le_quiet( float32, float32 ); +!!!flag float32_lt_quiet( float32, float32 ); +!!!flag float32_is_signaling_nan( float32 ); + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +!!!int32 float64_to_int32( float64 ); +!!!int32 float64_to_int32_round_to_zero( float64 ); +!!!int64 float64_to_int64( float64 ); +!!!int64 float64_to_int64_round_to_zero( float64 ); +float32 float64_to_float32( float64 ); +#ifdef FLOATX80 +floatx80 float64_to_floatx80( float64 ); +#endif +#ifdef FLOAT128 +float128 float64_to_float128( float64 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision operations. +------------------------------------------------------------------------------- +*/ +float64 float64_round_to_int( float64 ); +float64 float64_add( float64, float64 ); +float64 float64_sub( float64, float64 ); +float64 float64_mul( float64, float64 ); +float64 float64_div( float64, float64 ); +float64 float64_rem( float64, float64 ); +float64 float64_sqrt( float64 ); +!!!flag float64_eq( float64, float64 ); +!!!flag float64_le( float64, float64 ); +!!!flag float64_lt( float64, float64 ); +!!!flag float64_eq_signaling( float64, float64 ); +!!!flag float64_le_quiet( float64, float64 ); +!!!flag float64_lt_quiet( float64, float64 ); +!!!flag float64_is_signaling_nan( float64 ); + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +!!!int32 floatx80_to_int32( floatx80 ); +!!!int32 floatx80_to_int32_round_to_zero( floatx80 ); +!!!int64 floatx80_to_int64( floatx80 ); +!!!int64 floatx80_to_int64_round_to_zero( floatx80 ); +float32 floatx80_to_float32( floatx80 ); +float64 floatx80_to_float64( floatx80 ); +#ifdef FLOAT128 +float128 floatx80_to_float128( floatx80 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision rounding precision. Valid +values are 32, 64, and 80. +------------------------------------------------------------------------------- +*/ +extern !!!int8 floatx80_rounding_precision; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision operations. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_round_to_int( floatx80 ); +floatx80 floatx80_add( floatx80, floatx80 ); +floatx80 floatx80_sub( floatx80, floatx80 ); +floatx80 floatx80_mul( floatx80, floatx80 ); +floatx80 floatx80_div( floatx80, floatx80 ); +floatx80 floatx80_rem( floatx80, floatx80 ); +floatx80 floatx80_sqrt( floatx80 ); +!!!flag floatx80_eq( floatx80, floatx80 ); +!!!flag floatx80_le( floatx80, floatx80 ); +!!!flag floatx80_lt( floatx80, floatx80 ); +!!!flag floatx80_eq_signaling( floatx80, floatx80 ); +!!!flag floatx80_le_quiet( floatx80, floatx80 ); +!!!flag floatx80_lt_quiet( floatx80, floatx80 ); +!!!flag floatx80_is_signaling_nan( floatx80 ); + +#endif + +#ifdef FLOAT128 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE quadruple-precision conversion routines. +------------------------------------------------------------------------------- +*/ +!!!int32 float128_to_int32( float128 ); +!!!int32 float128_to_int32_round_to_zero( float128 ); +!!!int64 float128_to_int64( float128 ); +!!!int64 float128_to_int64_round_to_zero( float128 ); +float32 float128_to_float32( float128 ); +float64 float128_to_float64( float128 ); +#ifdef FLOATX80 +floatx80 float128_to_floatx80( float128 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE quadruple-precision operations. +------------------------------------------------------------------------------- +*/ +float128 float128_round_to_int( float128 ); +float128 float128_add( float128, float128 ); +float128 float128_sub( float128, float128 ); +float128 float128_mul( float128, float128 ); +float128 float128_div( float128, float128 ); +float128 float128_rem( float128, float128 ); +float128 float128_sqrt( float128 ); +!!!flag float128_eq( float128, float128 ); +!!!flag float128_le( float128, float128 ); +!!!flag float128_lt( float128, float128 ); +!!!flag float128_eq_signaling( float128, float128 ); +!!!flag float128_le_quiet( float128, float128 ); +!!!flag float128_lt_quiet( float128, float128 ); +!!!flag float128_is_signaling_nan( float128 ); + +#endif + diff --git a/lib/libc/softfloat/timesoftfloat.c b/lib/libc/softfloat/timesoftfloat.c new file mode 100644 index 0000000..cfd436f --- /dev/null +++ b/lib/libc/softfloat/timesoftfloat.c @@ -0,0 +1,2639 @@ +/* $NetBSD: timesoftfloat.c,v 1.1 2000/06/06 08:15:11 bjh21 Exp $ */ + +/* +=============================================================================== + +This C source file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +#include +__FBSDID("$FreeBSD: releng/11.1/lib/libc/softfloat/timesoftfloat.c 297790 2016-04-10 19:33:58Z pfg $"); + +#include +#include +#include +#include +#include +#include "milieu.h" +#include "softfloat.h" + +enum { + minIterations = 1000 +}; + +static void fail( const char *message, ... ) +{ + va_list varArgs; + + fputs( "timesoftfloat: ", stderr ); + va_start( varArgs, message ); + vfprintf( stderr, message, varArgs ); + va_end( varArgs ); + fputs( ".\n", stderr ); + exit( EXIT_FAILURE ); + +} + +static char *functionName; +static char *roundingPrecisionName, *roundingModeName, *tininessModeName; + +static void reportTime( int32 count, long clocks ) +{ + + printf( + "%8.1f kops/s: %s", + ( count / ( ( (float) clocks ) / CLOCKS_PER_SEC ) ) / 1000, + functionName + ); + if ( roundingModeName ) { + if ( roundingPrecisionName ) { + fputs( ", precision ", stdout ); + fputs( roundingPrecisionName, stdout ); + } + fputs( ", rounding ", stdout ); + fputs( roundingModeName, stdout ); + if ( tininessModeName ) { + fputs( ", tininess ", stdout ); + fputs( tininessModeName, stdout ); + fputs( " rounding", stdout ); + } + } + fputc( '\n', stdout ); + +} + +enum { + numInputs_int32 = 32 +}; + +static const int32 inputs_int32[ numInputs_int32 ] = { + 0xFFFFBB79, 0x405CF80F, 0x00000000, 0xFFFFFD04, + 0xFFF20002, 0x0C8EF795, 0xF00011FF, 0x000006CA, + 0x00009BFE, 0xFF4862E3, 0x9FFFEFFE, 0xFFFFFFB7, + 0x0BFF7FFF, 0x0000F37A, 0x0011DFFE, 0x00000006, + 0xFFF02006, 0xFFFFF7D1, 0x10200003, 0xDE8DF765, + 0x00003E02, 0x000019E8, 0x0008FFFE, 0xFFFFFB5C, + 0xFFDF7FFE, 0x07C42FBF, 0x0FFFE3FF, 0x040B9F13, + 0xBFFFFFF8, 0x0001BF56, 0x000017F6, 0x000A908A +}; + +static void time_a_int32_z_float32( float32 function( int32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_int32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_int32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_a_int32_z_float64( float64 function( int32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_int32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_int32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#ifdef FLOATX80 + +static void time_a_int32_z_floatx80( floatx80 function( int32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_int32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_int32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#endif + +#ifdef FLOAT128 + +static void time_a_int32_z_float128( float128 function( int32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_int32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_int32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#endif + +enum { + numInputs_int64 = 32 +}; + +static const int64 inputs_int64[ numInputs_int64 ] = { + LIT64( 0xFBFFC3FFFFFFFFFF ), + LIT64( 0x0000000003C589BC ), + LIT64( 0x00000000400013FE ), + LIT64( 0x0000000000186171 ), + LIT64( 0xFFFFFFFFFFFEFBFA ), + LIT64( 0xFFFFFD79E6DFFC73 ), + LIT64( 0x0000000010001DFF ), + LIT64( 0xDD1A0F0C78513710 ), + LIT64( 0xFFFF83FFFFFEFFFE ), + LIT64( 0x00756EBD1AD0C1C7 ), + LIT64( 0x0003FDFFFFFFFFBE ), + LIT64( 0x0007D0FB2C2CA951 ), + LIT64( 0x0007FC0007FFFFFE ), + LIT64( 0x0000001F942B18BB ), + LIT64( 0x0000080101FFFFFE ), + LIT64( 0xFFFFFFFFFFFF0978 ), + LIT64( 0x000000000008BFFF ), + LIT64( 0x0000000006F5AF08 ), + LIT64( 0xFFDEFF7FFFFFFFFE ), + LIT64( 0x0000000000000003 ), + LIT64( 0x3FFFFFFFFF80007D ), + LIT64( 0x0000000000000078 ), + LIT64( 0xFFF80000007FDFFD ), + LIT64( 0x1BBC775B78016AB0 ), + LIT64( 0xFFF9001FFFFFFFFE ), + LIT64( 0xFFFD4767AB98E43F ), + LIT64( 0xFFFFFEFFFE00001E ), + LIT64( 0xFFFFFFFFFFF04EFD ), + LIT64( 0x07FFFFFFFFFFF7FF ), + LIT64( 0xFFFC9EAA38F89050 ), + LIT64( 0x00000020FBFFFFFE ), + LIT64( 0x0000099AE6455357 ) +}; + +static void time_a_int64_z_float32( float32 function( int64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_int64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_int64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_a_int64_z_float64( float64 function( int64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_int64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_int64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#ifdef FLOATX80 + +static void time_a_int64_z_floatx80( floatx80 function( int64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_int64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_int64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#endif + +#ifdef FLOAT128 + +static void time_a_int64_z_float128( float128 function( int64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_int64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_int64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_int64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#endif + +enum { + numInputs_float32 = 32 +}; + +static const float32 inputs_float32[ numInputs_float32 ] = { + 0x4EFA0000, 0xC1D0B328, 0x80000000, 0x3E69A31E, + 0xAF803EFF, 0x3F800000, 0x17BF8000, 0xE74A301A, + 0x4E010003, 0x7EE3C75D, 0xBD803FE0, 0xBFFEFF00, + 0x7981F800, 0x431FFFFC, 0xC100C000, 0x3D87EFFF, + 0x4103FEFE, 0xBC000007, 0xBF01F7FF, 0x4E6C6B5C, + 0xC187FFFE, 0xC58B9F13, 0x4F88007F, 0xDF004007, + 0xB7FFD7FE, 0x7E8001FB, 0x46EFFBFF, 0x31C10000, + 0xDB428661, 0x33F89B1F, 0xA3BFEFFF, 0x537BFFBE +}; + +static void time_a_float32_z_int32( int32 function( float32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_a_float32_z_int64( int64 function( float32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_a_float32_z_float64( float64 function( float32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#ifdef FLOATX80 + +static void time_a_float32_z_floatx80( floatx80 function( float32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#endif + +#ifdef FLOAT128 + +static void time_a_float32_z_float128( float128 function( float32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#endif + +static void time_az_float32( float32 function( float32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float32[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_ab_float32_z_flag( flag function( float32, float32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNumA, inputNumB; + + count = 0; + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( + inputs_float32[ inputNumA ], inputs_float32[ inputNumB ] ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_float32 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_float32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( + inputs_float32[ inputNumA ], inputs_float32[ inputNumB ] ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_float32 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_float32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_abz_float32( float32 function( float32, float32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNumA, inputNumB; + + count = 0; + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( + inputs_float32[ inputNumA ], inputs_float32[ inputNumB ] ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_float32 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_float32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( + inputs_float32[ inputNumA ], inputs_float32[ inputNumB ] ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_float32 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_float32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static const float32 inputs_float32_pos[ numInputs_float32 ] = { + 0x4EFA0000, 0x41D0B328, 0x00000000, 0x3E69A31E, + 0x2F803EFF, 0x3F800000, 0x17BF8000, 0x674A301A, + 0x4E010003, 0x7EE3C75D, 0x3D803FE0, 0x3FFEFF00, + 0x7981F800, 0x431FFFFC, 0x4100C000, 0x3D87EFFF, + 0x4103FEFE, 0x3C000007, 0x3F01F7FF, 0x4E6C6B5C, + 0x4187FFFE, 0x458B9F13, 0x4F88007F, 0x5F004007, + 0x37FFD7FE, 0x7E8001FB, 0x46EFFBFF, 0x31C10000, + 0x5B428661, 0x33F89B1F, 0x23BFEFFF, 0x537BFFBE +}; + +static void time_az_float32_pos( float32 function( float32 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float32_pos[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float32_pos[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float32 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +enum { + numInputs_float64 = 32 +}; + +static const float64 inputs_float64[ numInputs_float64 ] = { + LIT64( 0x422FFFC008000000 ), + LIT64( 0xB7E0000480000000 ), + LIT64( 0xF3FD2546120B7935 ), + LIT64( 0x3FF0000000000000 ), + LIT64( 0xCE07F766F09588D6 ), + LIT64( 0x8000000000000000 ), + LIT64( 0x3FCE000400000000 ), + LIT64( 0x8313B60F0032BED8 ), + LIT64( 0xC1EFFFFFC0002000 ), + LIT64( 0x3FB3C75D224F2B0F ), + LIT64( 0x7FD00000004000FF ), + LIT64( 0xA12FFF8000001FFF ), + LIT64( 0x3EE0000000FE0000 ), + LIT64( 0x0010000080000004 ), + LIT64( 0x41CFFFFE00000020 ), + LIT64( 0x40303FFFFFFFFFFD ), + LIT64( 0x3FD000003FEFFFFF ), + LIT64( 0xBFD0000010000000 ), + LIT64( 0xB7FC6B5C16CA55CF ), + LIT64( 0x413EEB940B9D1301 ), + LIT64( 0xC7E00200001FFFFF ), + LIT64( 0x47F00021FFFFFFFE ), + LIT64( 0xBFFFFFFFF80000FF ), + LIT64( 0xC07FFFFFE00FFFFF ), + LIT64( 0x001497A63740C5E8 ), + LIT64( 0xC4BFFFE0001FFFFF ), + LIT64( 0x96FFDFFEFFFFFFFF ), + LIT64( 0x403FC000000001FE ), + LIT64( 0xFFD00000000001F6 ), + LIT64( 0x0640400002000000 ), + LIT64( 0x479CEE1E4F789FE0 ), + LIT64( 0xC237FFFFFFFFFDFE ) +}; + +static void time_a_float64_z_int32( int32 function( float64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_a_float64_z_int64( int64 function( float64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_a_float64_z_float32( float32 function( float64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#ifdef FLOATX80 + +static void time_a_float64_z_floatx80( floatx80 function( float64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#endif + +#ifdef FLOAT128 + +static void time_a_float64_z_float128( float128 function( float64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#endif + +static void time_az_float64( float64 function( float64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float64[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_ab_float64_z_flag( flag function( float64, float64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNumA, inputNumB; + + count = 0; + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( + inputs_float64[ inputNumA ], inputs_float64[ inputNumB ] ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_float64 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_float64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( + inputs_float64[ inputNumA ], inputs_float64[ inputNumB ] ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_float64 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_float64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_abz_float64( float64 function( float64, float64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNumA, inputNumB; + + count = 0; + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( + inputs_float64[ inputNumA ], inputs_float64[ inputNumB ] ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_float64 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_float64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( + inputs_float64[ inputNumA ], inputs_float64[ inputNumB ] ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_float64 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_float64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static const float64 inputs_float64_pos[ numInputs_float64 ] = { + LIT64( 0x422FFFC008000000 ), + LIT64( 0x37E0000480000000 ), + LIT64( 0x73FD2546120B7935 ), + LIT64( 0x3FF0000000000000 ), + LIT64( 0x4E07F766F09588D6 ), + LIT64( 0x0000000000000000 ), + LIT64( 0x3FCE000400000000 ), + LIT64( 0x0313B60F0032BED8 ), + LIT64( 0x41EFFFFFC0002000 ), + LIT64( 0x3FB3C75D224F2B0F ), + LIT64( 0x7FD00000004000FF ), + LIT64( 0x212FFF8000001FFF ), + LIT64( 0x3EE0000000FE0000 ), + LIT64( 0x0010000080000004 ), + LIT64( 0x41CFFFFE00000020 ), + LIT64( 0x40303FFFFFFFFFFD ), + LIT64( 0x3FD000003FEFFFFF ), + LIT64( 0x3FD0000010000000 ), + LIT64( 0x37FC6B5C16CA55CF ), + LIT64( 0x413EEB940B9D1301 ), + LIT64( 0x47E00200001FFFFF ), + LIT64( 0x47F00021FFFFFFFE ), + LIT64( 0x3FFFFFFFF80000FF ), + LIT64( 0x407FFFFFE00FFFFF ), + LIT64( 0x001497A63740C5E8 ), + LIT64( 0x44BFFFE0001FFFFF ), + LIT64( 0x16FFDFFEFFFFFFFF ), + LIT64( 0x403FC000000001FE ), + LIT64( 0x7FD00000000001F6 ), + LIT64( 0x0640400002000000 ), + LIT64( 0x479CEE1E4F789FE0 ), + LIT64( 0x4237FFFFFFFFFDFE ) +}; + +static void time_az_float64_pos( float64 function( float64 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + function( inputs_float64_pos[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + function( inputs_float64_pos[ inputNum ] ); + inputNum = ( inputNum + 1 ) & ( numInputs_float64 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#ifdef FLOATX80 + +enum { + numInputs_floatx80 = 32 +}; + +static const struct { + bits16 high; + bits64 low; +} inputs_floatx80[ numInputs_floatx80 ] = { + { 0xC03F, LIT64( 0xA9BE15A19C1E8B62 ) }, + { 0x8000, LIT64( 0x0000000000000000 ) }, + { 0x75A8, LIT64( 0xE59591E4788957A5 ) }, + { 0xBFFF, LIT64( 0xFFF0000000000040 ) }, + { 0x0CD8, LIT64( 0xFC000000000007FE ) }, + { 0x43BA, LIT64( 0x99A4000000000000 ) }, + { 0x3FFF, LIT64( 0x8000000000000000 ) }, + { 0x4081, LIT64( 0x94FBF1BCEB5545F0 ) }, + { 0x403E, LIT64( 0xFFF0000000002000 ) }, + { 0x3FFE, LIT64( 0xC860E3C75D224F28 ) }, + { 0x407E, LIT64( 0xFC00000FFFFFFFFE ) }, + { 0x737A, LIT64( 0x800000007FFDFFFE ) }, + { 0x4044, LIT64( 0xFFFFFF80000FFFFF ) }, + { 0xBBFE, LIT64( 0x8000040000001FFE ) }, + { 0xC002, LIT64( 0xFF80000000000020 ) }, + { 0xDE8D, LIT64( 0xFFFFFFFFFFE00004 ) }, + { 0xC004, LIT64( 0x8000000000003FFB ) }, + { 0x407F, LIT64( 0x800000000003FFFE ) }, + { 0xC000, LIT64( 0xA459EE6A5C16CA55 ) }, + { 0x8003, LIT64( 0xC42CBF7399AEEB94 ) }, + { 0xBF7F, LIT64( 0xF800000000000006 ) }, + { 0xC07F, LIT64( 0xBF56BE8871F28FEA ) }, + { 0xC07E, LIT64( 0xFFFF77FFFFFFFFFE ) }, + { 0xADC9, LIT64( 0x8000000FFFFFFFDE ) }, + { 0xC001, LIT64( 0xEFF7FFFFFFFFFFFF ) }, + { 0x4001, LIT64( 0xBE84F30125C497A6 ) }, + { 0xC06B, LIT64( 0xEFFFFFFFFFFFFFFF ) }, + { 0x4080, LIT64( 0xFFFFFFFFBFFFFFFF ) }, + { 0x87E9, LIT64( 0x81FFFFFFFFFFFBFF ) }, + { 0xA63F, LIT64( 0x801FFFFFFEFFFFFE ) }, + { 0x403C, LIT64( 0x801FFFFFFFF7FFFF ) }, + { 0x4018, LIT64( 0x8000000000080003 ) } +}; + +static void time_a_floatx80_z_int32( int32 function( floatx80 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + floatx80 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_floatx80[ inputNum ].low; + a.high = inputs_floatx80[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_floatx80[ inputNum ].low; + a.high = inputs_floatx80[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_a_floatx80_z_int64( int64 function( floatx80 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + floatx80 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_floatx80[ inputNum ].low; + a.high = inputs_floatx80[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_floatx80[ inputNum ].low; + a.high = inputs_floatx80[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_a_floatx80_z_float32( float32 function( floatx80 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + floatx80 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_floatx80[ inputNum ].low; + a.high = inputs_floatx80[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_floatx80[ inputNum ].low; + a.high = inputs_floatx80[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_a_floatx80_z_float64( float64 function( floatx80 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + floatx80 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_floatx80[ inputNum ].low; + a.high = inputs_floatx80[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_floatx80[ inputNum ].low; + a.high = inputs_floatx80[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#ifdef FLOAT128 + +static void time_a_floatx80_z_float128( float128 function( floatx80 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + floatx80 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_floatx80[ inputNum ].low; + a.high = inputs_floatx80[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_floatx80[ inputNum ].low; + a.high = inputs_floatx80[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#endif + +static void time_az_floatx80( floatx80 function( floatx80 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + floatx80 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_floatx80[ inputNum ].low; + a.high = inputs_floatx80[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_floatx80[ inputNum ].low; + a.high = inputs_floatx80[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_ab_floatx80_z_flag( flag function( floatx80, floatx80 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNumA, inputNumB; + floatx80 a, b; + + count = 0; + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_floatx80[ inputNumA ].low; + a.high = inputs_floatx80[ inputNumA ].high; + b.low = inputs_floatx80[ inputNumB ].low; + b.high = inputs_floatx80[ inputNumB ].high; + function( a, b ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_floatx80 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_floatx80 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_floatx80[ inputNumA ].low; + a.high = inputs_floatx80[ inputNumA ].high; + b.low = inputs_floatx80[ inputNumB ].low; + b.high = inputs_floatx80[ inputNumB ].high; + function( a, b ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_floatx80 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_floatx80 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_abz_floatx80( floatx80 function( floatx80, floatx80 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNumA, inputNumB; + floatx80 a, b; + + count = 0; + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_floatx80[ inputNumA ].low; + a.high = inputs_floatx80[ inputNumA ].high; + b.low = inputs_floatx80[ inputNumB ].low; + b.high = inputs_floatx80[ inputNumB ].high; + function( a, b ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_floatx80 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_floatx80 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_floatx80[ inputNumA ].low; + a.high = inputs_floatx80[ inputNumA ].high; + b.low = inputs_floatx80[ inputNumB ].low; + b.high = inputs_floatx80[ inputNumB ].high; + function( a, b ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_floatx80 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_floatx80 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static const struct { + bits16 high; + bits64 low; +} inputs_floatx80_pos[ numInputs_floatx80 ] = { + { 0x403F, LIT64( 0xA9BE15A19C1E8B62 ) }, + { 0x0000, LIT64( 0x0000000000000000 ) }, + { 0x75A8, LIT64( 0xE59591E4788957A5 ) }, + { 0x3FFF, LIT64( 0xFFF0000000000040 ) }, + { 0x0CD8, LIT64( 0xFC000000000007FE ) }, + { 0x43BA, LIT64( 0x99A4000000000000 ) }, + { 0x3FFF, LIT64( 0x8000000000000000 ) }, + { 0x4081, LIT64( 0x94FBF1BCEB5545F0 ) }, + { 0x403E, LIT64( 0xFFF0000000002000 ) }, + { 0x3FFE, LIT64( 0xC860E3C75D224F28 ) }, + { 0x407E, LIT64( 0xFC00000FFFFFFFFE ) }, + { 0x737A, LIT64( 0x800000007FFDFFFE ) }, + { 0x4044, LIT64( 0xFFFFFF80000FFFFF ) }, + { 0x3BFE, LIT64( 0x8000040000001FFE ) }, + { 0x4002, LIT64( 0xFF80000000000020 ) }, + { 0x5E8D, LIT64( 0xFFFFFFFFFFE00004 ) }, + { 0x4004, LIT64( 0x8000000000003FFB ) }, + { 0x407F, LIT64( 0x800000000003FFFE ) }, + { 0x4000, LIT64( 0xA459EE6A5C16CA55 ) }, + { 0x0003, LIT64( 0xC42CBF7399AEEB94 ) }, + { 0x3F7F, LIT64( 0xF800000000000006 ) }, + { 0x407F, LIT64( 0xBF56BE8871F28FEA ) }, + { 0x407E, LIT64( 0xFFFF77FFFFFFFFFE ) }, + { 0x2DC9, LIT64( 0x8000000FFFFFFFDE ) }, + { 0x4001, LIT64( 0xEFF7FFFFFFFFFFFF ) }, + { 0x4001, LIT64( 0xBE84F30125C497A6 ) }, + { 0x406B, LIT64( 0xEFFFFFFFFFFFFFFF ) }, + { 0x4080, LIT64( 0xFFFFFFFFBFFFFFFF ) }, + { 0x07E9, LIT64( 0x81FFFFFFFFFFFBFF ) }, + { 0x263F, LIT64( 0x801FFFFFFEFFFFFE ) }, + { 0x403C, LIT64( 0x801FFFFFFFF7FFFF ) }, + { 0x4018, LIT64( 0x8000000000080003 ) } +}; + +static void time_az_floatx80_pos( floatx80 function( floatx80 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + floatx80 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_floatx80_pos[ inputNum ].low; + a.high = inputs_floatx80_pos[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_floatx80_pos[ inputNum ].low; + a.high = inputs_floatx80_pos[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_floatx80 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#endif + +#ifdef FLOAT128 + +enum { + numInputs_float128 = 32 +}; + +static const struct { + bits64 high, low; +} inputs_float128[ numInputs_float128 ] = { + { LIT64( 0x3FDA200000100000 ), LIT64( 0x0000000000000000 ) }, + { LIT64( 0x3FFF000000000000 ), LIT64( 0x0000000000000000 ) }, + { LIT64( 0x85F14776190C8306 ), LIT64( 0xD8715F4E3D54BB92 ) }, + { LIT64( 0xF2B00000007FFFFF ), LIT64( 0xFFFFFFFFFFF7FFFF ) }, + { LIT64( 0x8000000000000000 ), LIT64( 0x0000000000000000 ) }, + { LIT64( 0xBFFFFFFFFFE00000 ), LIT64( 0x0000008000000000 ) }, + { LIT64( 0x407F1719CE722F3E ), LIT64( 0xDA6B3FE5FF29425B ) }, + { LIT64( 0x43FFFF8000000000 ), LIT64( 0x0000000000400000 ) }, + { LIT64( 0x401E000000000100 ), LIT64( 0x0000000000002000 ) }, + { LIT64( 0x3FFED71DACDA8E47 ), LIT64( 0x4860E3C75D224F28 ) }, + { LIT64( 0xBF7ECFC1E90647D1 ), LIT64( 0x7A124FE55623EE44 ) }, + { LIT64( 0x0DF7007FFFFFFFFF ), LIT64( 0xFFFFFFFFEFFFFFFF ) }, + { LIT64( 0x3FE5FFEFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFEFFF ) }, + { LIT64( 0x403FFFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFBFE ) }, + { LIT64( 0xBFFB2FBF7399AFEB ), LIT64( 0xA459EE6A5C16CA55 ) }, + { LIT64( 0xBDB8FFFFFFFFFFFC ), LIT64( 0x0000000000000400 ) }, + { LIT64( 0x3FC8FFDFFFFFFFFF ), LIT64( 0xFFFFFFFFF0000000 ) }, + { LIT64( 0x3FFBFFFFFFDFFFFF ), LIT64( 0xFFF8000000000000 ) }, + { LIT64( 0x407043C11737BE84 ), LIT64( 0xDDD58212ADC937F4 ) }, + { LIT64( 0x8001000000000000 ), LIT64( 0x0000001000000001 ) }, + { LIT64( 0xC036FFFFFFFFFFFF ), LIT64( 0xFE40000000000000 ) }, + { LIT64( 0x4002FFFFFE000002 ), LIT64( 0x0000000000000000 ) }, + { LIT64( 0x4000C3FEDE897773 ), LIT64( 0x326AC4FD8EFBE6DC ) }, + { LIT64( 0xBFFF0000000FFFFF ), LIT64( 0xFFFFFE0000000000 ) }, + { LIT64( 0x62C3E502146E426D ), LIT64( 0x43F3CAA0DC7DF1A0 ) }, + { LIT64( 0xB5CBD32E52BB570E ), LIT64( 0xBCC477CB11C6236C ) }, + { LIT64( 0xE228FFFFFFC00000 ), LIT64( 0x0000000000000000 ) }, + { LIT64( 0x3F80000000000000 ), LIT64( 0x0000000080000008 ) }, + { LIT64( 0xC1AFFFDFFFFFFFFF ), LIT64( 0xFFFC000000000000 ) }, + { LIT64( 0xC96F000000000000 ), LIT64( 0x00000001FFFBFFFF ) }, + { LIT64( 0x3DE09BFE7923A338 ), LIT64( 0xBCC8FBBD7CEC1F4F ) }, + { LIT64( 0x401CFFFFFFFFFFFF ), LIT64( 0xFFFFFFFEFFFFFF80 ) } +}; + +static void time_a_float128_z_int32( int32 function( float128 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + float128 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_float128[ inputNum ].low; + a.high = inputs_float128[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_float128[ inputNum ].low; + a.high = inputs_float128[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_a_float128_z_int64( int64 function( float128 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + float128 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_float128[ inputNum ].low; + a.high = inputs_float128[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_float128[ inputNum ].low; + a.high = inputs_float128[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_a_float128_z_float32( float32 function( float128 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + float128 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_float128[ inputNum ].low; + a.high = inputs_float128[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_float128[ inputNum ].low; + a.high = inputs_float128[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_a_float128_z_float64( float64 function( float128 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + float128 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_float128[ inputNum ].low; + a.high = inputs_float128[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_float128[ inputNum ].low; + a.high = inputs_float128[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#ifdef FLOATX80 + +static void time_a_float128_z_floatx80( floatx80 function( float128 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + float128 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_float128[ inputNum ].low; + a.high = inputs_float128[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_float128[ inputNum ].low; + a.high = inputs_float128[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#endif + +static void time_az_float128( float128 function( float128 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + float128 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_float128[ inputNum ].low; + a.high = inputs_float128[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_float128[ inputNum ].low; + a.high = inputs_float128[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_ab_float128_z_flag( flag function( float128, float128 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNumA, inputNumB; + float128 a, b; + + count = 0; + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_float128[ inputNumA ].low; + a.high = inputs_float128[ inputNumA ].high; + b.low = inputs_float128[ inputNumB ].low; + b.high = inputs_float128[ inputNumB ].high; + function( a, b ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_float128 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_float128 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_float128[ inputNumA ].low; + a.high = inputs_float128[ inputNumA ].high; + b.low = inputs_float128[ inputNumB ].low; + b.high = inputs_float128[ inputNumB ].high; + function( a, b ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_float128 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_float128 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static void time_abz_float128( float128 function( float128, float128 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNumA, inputNumB; + float128 a, b; + + count = 0; + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_float128[ inputNumA ].low; + a.high = inputs_float128[ inputNumA ].high; + b.low = inputs_float128[ inputNumB ].low; + b.high = inputs_float128[ inputNumB ].high; + function( a, b ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_float128 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_float128 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNumA = 0; + inputNumB = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_float128[ inputNumA ].low; + a.high = inputs_float128[ inputNumA ].high; + b.low = inputs_float128[ inputNumB ].low; + b.high = inputs_float128[ inputNumB ].high; + function( a, b ); + inputNumA = ( inputNumA + 1 ) & ( numInputs_float128 - 1 ); + if ( inputNumA == 0 ) ++inputNumB; + inputNumB = ( inputNumB + 1 ) & ( numInputs_float128 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +static const struct { + bits64 high, low; +} inputs_float128_pos[ numInputs_float128 ] = { + { LIT64( 0x3FDA200000100000 ), LIT64( 0x0000000000000000 ) }, + { LIT64( 0x3FFF000000000000 ), LIT64( 0x0000000000000000 ) }, + { LIT64( 0x05F14776190C8306 ), LIT64( 0xD8715F4E3D54BB92 ) }, + { LIT64( 0x72B00000007FFFFF ), LIT64( 0xFFFFFFFFFFF7FFFF ) }, + { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000000 ) }, + { LIT64( 0x3FFFFFFFFFE00000 ), LIT64( 0x0000008000000000 ) }, + { LIT64( 0x407F1719CE722F3E ), LIT64( 0xDA6B3FE5FF29425B ) }, + { LIT64( 0x43FFFF8000000000 ), LIT64( 0x0000000000400000 ) }, + { LIT64( 0x401E000000000100 ), LIT64( 0x0000000000002000 ) }, + { LIT64( 0x3FFED71DACDA8E47 ), LIT64( 0x4860E3C75D224F28 ) }, + { LIT64( 0x3F7ECFC1E90647D1 ), LIT64( 0x7A124FE55623EE44 ) }, + { LIT64( 0x0DF7007FFFFFFFFF ), LIT64( 0xFFFFFFFFEFFFFFFF ) }, + { LIT64( 0x3FE5FFEFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFEFFF ) }, + { LIT64( 0x403FFFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFBFE ) }, + { LIT64( 0x3FFB2FBF7399AFEB ), LIT64( 0xA459EE6A5C16CA55 ) }, + { LIT64( 0x3DB8FFFFFFFFFFFC ), LIT64( 0x0000000000000400 ) }, + { LIT64( 0x3FC8FFDFFFFFFFFF ), LIT64( 0xFFFFFFFFF0000000 ) }, + { LIT64( 0x3FFBFFFFFFDFFFFF ), LIT64( 0xFFF8000000000000 ) }, + { LIT64( 0x407043C11737BE84 ), LIT64( 0xDDD58212ADC937F4 ) }, + { LIT64( 0x0001000000000000 ), LIT64( 0x0000001000000001 ) }, + { LIT64( 0x4036FFFFFFFFFFFF ), LIT64( 0xFE40000000000000 ) }, + { LIT64( 0x4002FFFFFE000002 ), LIT64( 0x0000000000000000 ) }, + { LIT64( 0x4000C3FEDE897773 ), LIT64( 0x326AC4FD8EFBE6DC ) }, + { LIT64( 0x3FFF0000000FFFFF ), LIT64( 0xFFFFFE0000000000 ) }, + { LIT64( 0x62C3E502146E426D ), LIT64( 0x43F3CAA0DC7DF1A0 ) }, + { LIT64( 0x35CBD32E52BB570E ), LIT64( 0xBCC477CB11C6236C ) }, + { LIT64( 0x6228FFFFFFC00000 ), LIT64( 0x0000000000000000 ) }, + { LIT64( 0x3F80000000000000 ), LIT64( 0x0000000080000008 ) }, + { LIT64( 0x41AFFFDFFFFFFFFF ), LIT64( 0xFFFC000000000000 ) }, + { LIT64( 0x496F000000000000 ), LIT64( 0x00000001FFFBFFFF ) }, + { LIT64( 0x3DE09BFE7923A338 ), LIT64( 0xBCC8FBBD7CEC1F4F ) }, + { LIT64( 0x401CFFFFFFFFFFFF ), LIT64( 0xFFFFFFFEFFFFFF80 ) } +}; + +static void time_az_float128_pos( float128 function( float128 ) ) +{ + clock_t startClock, endClock; + int32 count, i; + int8 inputNum; + float128 a; + + count = 0; + inputNum = 0; + startClock = clock(); + do { + for ( i = minIterations; i; --i ) { + a.low = inputs_float128_pos[ inputNum ].low; + a.high = inputs_float128_pos[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + count += minIterations; + } while ( clock() - startClock < CLOCKS_PER_SEC ); + inputNum = 0; + startClock = clock(); + for ( i = count; i; --i ) { + a.low = inputs_float128_pos[ inputNum ].low; + a.high = inputs_float128_pos[ inputNum ].high; + function( a ); + inputNum = ( inputNum + 1 ) & ( numInputs_float128 - 1 ); + } + endClock = clock(); + reportTime( count, endClock - startClock ); + +} + +#endif + +enum { + INT32_TO_FLOAT32 = 1, + INT32_TO_FLOAT64, +#ifdef FLOATX80 + INT32_TO_FLOATX80, +#endif +#ifdef FLOAT128 + INT32_TO_FLOAT128, +#endif + INT64_TO_FLOAT32, + INT64_TO_FLOAT64, +#ifdef FLOATX80 + INT64_TO_FLOATX80, +#endif +#ifdef FLOAT128 + INT64_TO_FLOAT128, +#endif + FLOAT32_TO_INT32, + FLOAT32_TO_INT32_ROUND_TO_ZERO, + FLOAT32_TO_INT64, + FLOAT32_TO_INT64_ROUND_TO_ZERO, + FLOAT32_TO_FLOAT64, +#ifdef FLOATX80 + FLOAT32_TO_FLOATX80, +#endif +#ifdef FLOAT128 + FLOAT32_TO_FLOAT128, +#endif + FLOAT32_ROUND_TO_INT, + FLOAT32_ADD, + FLOAT32_SUB, + FLOAT32_MUL, + FLOAT32_DIV, + FLOAT32_REM, + FLOAT32_SQRT, + FLOAT32_EQ, + FLOAT32_LE, + FLOAT32_LT, + FLOAT32_EQ_SIGNALING, + FLOAT32_LE_QUIET, + FLOAT32_LT_QUIET, + FLOAT64_TO_INT32, + FLOAT64_TO_INT32_ROUND_TO_ZERO, + FLOAT64_TO_INT64, + FLOAT64_TO_INT64_ROUND_TO_ZERO, + FLOAT64_TO_FLOAT32, +#ifdef FLOATX80 + FLOAT64_TO_FLOATX80, +#endif +#ifdef FLOAT128 + FLOAT64_TO_FLOAT128, +#endif + FLOAT64_ROUND_TO_INT, + FLOAT64_ADD, + FLOAT64_SUB, + FLOAT64_MUL, + FLOAT64_DIV, + FLOAT64_REM, + FLOAT64_SQRT, + FLOAT64_EQ, + FLOAT64_LE, + FLOAT64_LT, + FLOAT64_EQ_SIGNALING, + FLOAT64_LE_QUIET, + FLOAT64_LT_QUIET, +#ifdef FLOATX80 + FLOATX80_TO_INT32, + FLOATX80_TO_INT32_ROUND_TO_ZERO, + FLOATX80_TO_INT64, + FLOATX80_TO_INT64_ROUND_TO_ZERO, + FLOATX80_TO_FLOAT32, + FLOATX80_TO_FLOAT64, +#ifdef FLOAT128 + FLOATX80_TO_FLOAT128, +#endif + FLOATX80_ROUND_TO_INT, + FLOATX80_ADD, + FLOATX80_SUB, + FLOATX80_MUL, + FLOATX80_DIV, + FLOATX80_REM, + FLOATX80_SQRT, + FLOATX80_EQ, + FLOATX80_LE, + FLOATX80_LT, + FLOATX80_EQ_SIGNALING, + FLOATX80_LE_QUIET, + FLOATX80_LT_QUIET, +#endif +#ifdef FLOAT128 + FLOAT128_TO_INT32, + FLOAT128_TO_INT32_ROUND_TO_ZERO, + FLOAT128_TO_INT64, + FLOAT128_TO_INT64_ROUND_TO_ZERO, + FLOAT128_TO_FLOAT32, + FLOAT128_TO_FLOAT64, +#ifdef FLOATX80 + FLOAT128_TO_FLOATX80, +#endif + FLOAT128_ROUND_TO_INT, + FLOAT128_ADD, + FLOAT128_SUB, + FLOAT128_MUL, + FLOAT128_DIV, + FLOAT128_REM, + FLOAT128_SQRT, + FLOAT128_EQ, + FLOAT128_LE, + FLOAT128_LT, + FLOAT128_EQ_SIGNALING, + FLOAT128_LE_QUIET, + FLOAT128_LT_QUIET, +#endif + NUM_FUNCTIONS +}; + +static struct { + char *name; + int8 numInputs; + flag roundingPrecision, roundingMode; + flag tininessMode, tininessModeAtReducedPrecision; +} functions[ NUM_FUNCTIONS ] = { + { 0, 0, 0, 0, 0, 0 }, + { "int32_to_float32", 1, FALSE, TRUE, FALSE, FALSE }, + { "int32_to_float64", 1, FALSE, FALSE, FALSE, FALSE }, +#ifdef FLOATX80 + { "int32_to_floatx80", 1, FALSE, FALSE, FALSE, FALSE }, +#endif +#ifdef FLOAT128 + { "int32_to_float128", 1, FALSE, FALSE, FALSE, FALSE }, +#endif + { "int64_to_float32", 1, FALSE, TRUE, FALSE, FALSE }, + { "int64_to_float64", 1, FALSE, TRUE, FALSE, FALSE }, +#ifdef FLOATX80 + { "int64_to_floatx80", 1, FALSE, FALSE, FALSE, FALSE }, +#endif +#ifdef FLOAT128 + { "int64_to_float128", 1, FALSE, FALSE, FALSE, FALSE }, +#endif + { "float32_to_int32", 1, FALSE, TRUE, FALSE, FALSE }, + { "float32_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE }, + { "float32_to_int64", 1, FALSE, TRUE, FALSE, FALSE }, + { "float32_to_int64_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE }, + { "float32_to_float64", 1, FALSE, FALSE, FALSE, FALSE }, +#ifdef FLOATX80 + { "float32_to_floatx80", 1, FALSE, FALSE, FALSE, FALSE }, +#endif +#ifdef FLOAT128 + { "float32_to_float128", 1, FALSE, FALSE, FALSE, FALSE }, +#endif + { "float32_round_to_int", 1, FALSE, TRUE, FALSE, FALSE }, + { "float32_add", 2, FALSE, TRUE, FALSE, FALSE }, + { "float32_sub", 2, FALSE, TRUE, FALSE, FALSE }, + { "float32_mul", 2, FALSE, TRUE, TRUE, FALSE }, + { "float32_div", 2, FALSE, TRUE, FALSE, FALSE }, + { "float32_rem", 2, FALSE, FALSE, FALSE, FALSE }, + { "float32_sqrt", 1, FALSE, TRUE, FALSE, FALSE }, + { "float32_eq", 2, FALSE, FALSE, FALSE, FALSE }, + { "float32_le", 2, FALSE, FALSE, FALSE, FALSE }, + { "float32_lt", 2, FALSE, FALSE, FALSE, FALSE }, + { "float32_eq_signaling", 2, FALSE, FALSE, FALSE, FALSE }, + { "float32_le_quiet", 2, FALSE, FALSE, FALSE, FALSE }, + { "float32_lt_quiet", 2, FALSE, FALSE, FALSE, FALSE }, + { "float64_to_int32", 1, FALSE, TRUE, FALSE, FALSE }, + { "float64_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE }, + { "float64_to_int64", 1, FALSE, TRUE, FALSE, FALSE }, + { "float64_to_int64_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE }, + { "float64_to_float32", 1, FALSE, TRUE, TRUE, FALSE }, +#ifdef FLOATX80 + { "float64_to_floatx80", 1, FALSE, FALSE, FALSE, FALSE }, +#endif +#ifdef FLOAT128 + { "float64_to_float128", 1, FALSE, FALSE, FALSE, FALSE }, +#endif + { "float64_round_to_int", 1, FALSE, TRUE, FALSE, FALSE }, + { "float64_add", 2, FALSE, TRUE, FALSE, FALSE }, + { "float64_sub", 2, FALSE, TRUE, FALSE, FALSE }, + { "float64_mul", 2, FALSE, TRUE, TRUE, FALSE }, + { "float64_div", 2, FALSE, TRUE, FALSE, FALSE }, + { "float64_rem", 2, FALSE, FALSE, FALSE, FALSE }, + { "float64_sqrt", 1, FALSE, TRUE, FALSE, FALSE }, + { "float64_eq", 2, FALSE, FALSE, FALSE, FALSE }, + { "float64_le", 2, FALSE, FALSE, FALSE, FALSE }, + { "float64_lt", 2, FALSE, FALSE, FALSE, FALSE }, + { "float64_eq_signaling", 2, FALSE, FALSE, FALSE, FALSE }, + { "float64_le_quiet", 2, FALSE, FALSE, FALSE, FALSE }, + { "float64_lt_quiet", 2, FALSE, FALSE, FALSE, FALSE }, +#ifdef FLOATX80 + { "floatx80_to_int32", 1, FALSE, TRUE, FALSE, FALSE }, + { "floatx80_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE }, + { "floatx80_to_int64", 1, FALSE, TRUE, FALSE, FALSE }, + { "floatx80_to_int64_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE }, + { "floatx80_to_float32", 1, FALSE, TRUE, TRUE, FALSE }, + { "floatx80_to_float64", 1, FALSE, TRUE, TRUE, FALSE }, +#ifdef FLOAT128 + { "floatx80_to_float128", 1, FALSE, FALSE, FALSE, FALSE }, +#endif + { "floatx80_round_to_int", 1, FALSE, TRUE, FALSE, FALSE }, + { "floatx80_add", 2, TRUE, TRUE, FALSE, TRUE }, + { "floatx80_sub", 2, TRUE, TRUE, FALSE, TRUE }, + { "floatx80_mul", 2, TRUE, TRUE, TRUE, TRUE }, + { "floatx80_div", 2, TRUE, TRUE, FALSE, TRUE }, + { "floatx80_rem", 2, FALSE, FALSE, FALSE, FALSE }, + { "floatx80_sqrt", 1, TRUE, TRUE, FALSE, FALSE }, + { "floatx80_eq", 2, FALSE, FALSE, FALSE, FALSE }, + { "floatx80_le", 2, FALSE, FALSE, FALSE, FALSE }, + { "floatx80_lt", 2, FALSE, FALSE, FALSE, FALSE }, + { "floatx80_eq_signaling", 2, FALSE, FALSE, FALSE, FALSE }, + { "floatx80_le_quiet", 2, FALSE, FALSE, FALSE, FALSE }, + { "floatx80_lt_quiet", 2, FALSE, FALSE, FALSE, FALSE }, +#endif +#ifdef FLOAT128 + { "float128_to_int32", 1, FALSE, TRUE, FALSE, FALSE }, + { "float128_to_int32_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE }, + { "float128_to_int64", 1, FALSE, TRUE, FALSE, FALSE }, + { "float128_to_int64_round_to_zero", 1, FALSE, FALSE, FALSE, FALSE }, + { "float128_to_float32", 1, FALSE, TRUE, TRUE, FALSE }, + { "float128_to_float64", 1, FALSE, TRUE, TRUE, FALSE }, +#ifdef FLOATX80 + { "float128_to_floatx80", 1, FALSE, TRUE, TRUE, FALSE }, +#endif + { "float128_round_to_int", 1, FALSE, TRUE, FALSE, FALSE }, + { "float128_add", 2, FALSE, TRUE, FALSE, FALSE }, + { "float128_sub", 2, FALSE, TRUE, FALSE, FALSE }, + { "float128_mul", 2, FALSE, TRUE, TRUE, FALSE }, + { "float128_div", 2, FALSE, TRUE, FALSE, FALSE }, + { "float128_rem", 2, FALSE, FALSE, FALSE, FALSE }, + { "float128_sqrt", 1, FALSE, TRUE, FALSE, FALSE }, + { "float128_eq", 2, FALSE, FALSE, FALSE, FALSE }, + { "float128_le", 2, FALSE, FALSE, FALSE, FALSE }, + { "float128_lt", 2, FALSE, FALSE, FALSE, FALSE }, + { "float128_eq_signaling", 2, FALSE, FALSE, FALSE, FALSE }, + { "float128_le_quiet", 2, FALSE, FALSE, FALSE, FALSE }, + { "float128_lt_quiet", 2, FALSE, FALSE, FALSE, FALSE }, +#endif +}; + +enum { + ROUND_NEAREST_EVEN = 1, + ROUND_TO_ZERO, + ROUND_DOWN, + ROUND_UP, + NUM_ROUNDINGMODES +}; +enum { + TININESS_BEFORE_ROUNDING = 1, + TININESS_AFTER_ROUNDING, + NUM_TININESSMODES +}; + +static void + timeFunctionVariety( + uint8 functionCode, + int8 roundingPrecision, + int8 roundingMode, + int8 tininessMode + ) +{ + uint8 roundingCode; + int8 tininessCode; + + functionName = functions[ functionCode ].name; + if ( roundingPrecision == 32 ) { + roundingPrecisionName = "32"; + } + else if ( roundingPrecision == 64 ) { + roundingPrecisionName = "64"; + } + else if ( roundingPrecision == 80 ) { + roundingPrecisionName = "80"; + } + else { + roundingPrecisionName = NULL; + } +#ifdef FLOATX80 + floatx80_rounding_precision = roundingPrecision; +#endif + switch ( roundingMode ) { + case 0: + roundingModeName = NULL; + roundingCode = float_round_nearest_even; + break; + case ROUND_NEAREST_EVEN: + roundingModeName = "nearest_even"; + roundingCode = float_round_nearest_even; + break; + case ROUND_TO_ZERO: + roundingModeName = "to_zero"; + roundingCode = float_round_to_zero; + break; + case ROUND_DOWN: + roundingModeName = "down"; + roundingCode = float_round_down; + break; + case ROUND_UP: + roundingModeName = "up"; + roundingCode = float_round_up; + break; + } + float_rounding_mode = roundingCode; + switch ( tininessMode ) { + case 0: + tininessModeName = NULL; + tininessCode = float_tininess_after_rounding; + break; + case TININESS_BEFORE_ROUNDING: + tininessModeName = "before"; + tininessCode = float_tininess_before_rounding; + break; + case TININESS_AFTER_ROUNDING: + tininessModeName = "after"; + tininessCode = float_tininess_after_rounding; + break; + } + float_detect_tininess = tininessCode; + switch ( functionCode ) { + case INT32_TO_FLOAT32: + time_a_int32_z_float32( int32_to_float32 ); + break; + case INT32_TO_FLOAT64: + time_a_int32_z_float64( int32_to_float64 ); + break; +#ifdef FLOATX80 + case INT32_TO_FLOATX80: + time_a_int32_z_floatx80( int32_to_floatx80 ); + break; +#endif +#ifdef FLOAT128 + case INT32_TO_FLOAT128: + time_a_int32_z_float128( int32_to_float128 ); + break; +#endif + case INT64_TO_FLOAT32: + time_a_int64_z_float32( int64_to_float32 ); + break; + case INT64_TO_FLOAT64: + time_a_int64_z_float64( int64_to_float64 ); + break; +#ifdef FLOATX80 + case INT64_TO_FLOATX80: + time_a_int64_z_floatx80( int64_to_floatx80 ); + break; +#endif +#ifdef FLOAT128 + case INT64_TO_FLOAT128: + time_a_int64_z_float128( int64_to_float128 ); + break; +#endif + case FLOAT32_TO_INT32: + time_a_float32_z_int32( float32_to_int32 ); + break; + case FLOAT32_TO_INT32_ROUND_TO_ZERO: + time_a_float32_z_int32( float32_to_int32_round_to_zero ); + break; + case FLOAT32_TO_INT64: + time_a_float32_z_int64( float32_to_int64 ); + break; + case FLOAT32_TO_INT64_ROUND_TO_ZERO: + time_a_float32_z_int64( float32_to_int64_round_to_zero ); + break; + case FLOAT32_TO_FLOAT64: + time_a_float32_z_float64( float32_to_float64 ); + break; +#ifdef FLOATX80 + case FLOAT32_TO_FLOATX80: + time_a_float32_z_floatx80( float32_to_floatx80 ); + break; +#endif +#ifdef FLOAT128 + case FLOAT32_TO_FLOAT128: + time_a_float32_z_float128( float32_to_float128 ); + break; +#endif + case FLOAT32_ROUND_TO_INT: + time_az_float32( float32_round_to_int ); + break; + case FLOAT32_ADD: + time_abz_float32( float32_add ); + break; + case FLOAT32_SUB: + time_abz_float32( float32_sub ); + break; + case FLOAT32_MUL: + time_abz_float32( float32_mul ); + break; + case FLOAT32_DIV: + time_abz_float32( float32_div ); + break; + case FLOAT32_REM: + time_abz_float32( float32_rem ); + break; + case FLOAT32_SQRT: + time_az_float32_pos( float32_sqrt ); + break; + case FLOAT32_EQ: + time_ab_float32_z_flag( float32_eq ); + break; + case FLOAT32_LE: + time_ab_float32_z_flag( float32_le ); + break; + case FLOAT32_LT: + time_ab_float32_z_flag( float32_lt ); + break; + case FLOAT32_EQ_SIGNALING: + time_ab_float32_z_flag( float32_eq_signaling ); + break; + case FLOAT32_LE_QUIET: + time_ab_float32_z_flag( float32_le_quiet ); + break; + case FLOAT32_LT_QUIET: + time_ab_float32_z_flag( float32_lt_quiet ); + break; + case FLOAT64_TO_INT32: + time_a_float64_z_int32( float64_to_int32 ); + break; + case FLOAT64_TO_INT32_ROUND_TO_ZERO: + time_a_float64_z_int32( float64_to_int32_round_to_zero ); + break; + case FLOAT64_TO_INT64: + time_a_float64_z_int64( float64_to_int64 ); + break; + case FLOAT64_TO_INT64_ROUND_TO_ZERO: + time_a_float64_z_int64( float64_to_int64_round_to_zero ); + break; + case FLOAT64_TO_FLOAT32: + time_a_float64_z_float32( float64_to_float32 ); + break; +#ifdef FLOATX80 + case FLOAT64_TO_FLOATX80: + time_a_float64_z_floatx80( float64_to_floatx80 ); + break; +#endif +#ifdef FLOAT128 + case FLOAT64_TO_FLOAT128: + time_a_float64_z_float128( float64_to_float128 ); + break; +#endif + case FLOAT64_ROUND_TO_INT: + time_az_float64( float64_round_to_int ); + break; + case FLOAT64_ADD: + time_abz_float64( float64_add ); + break; + case FLOAT64_SUB: + time_abz_float64( float64_sub ); + break; + case FLOAT64_MUL: + time_abz_float64( float64_mul ); + break; + case FLOAT64_DIV: + time_abz_float64( float64_div ); + break; + case FLOAT64_REM: + time_abz_float64( float64_rem ); + break; + case FLOAT64_SQRT: + time_az_float64_pos( float64_sqrt ); + break; + case FLOAT64_EQ: + time_ab_float64_z_flag( float64_eq ); + break; + case FLOAT64_LE: + time_ab_float64_z_flag( float64_le ); + break; + case FLOAT64_LT: + time_ab_float64_z_flag( float64_lt ); + break; + case FLOAT64_EQ_SIGNALING: + time_ab_float64_z_flag( float64_eq_signaling ); + break; + case FLOAT64_LE_QUIET: + time_ab_float64_z_flag( float64_le_quiet ); + break; + case FLOAT64_LT_QUIET: + time_ab_float64_z_flag( float64_lt_quiet ); + break; +#ifdef FLOATX80 + case FLOATX80_TO_INT32: + time_a_floatx80_z_int32( floatx80_to_int32 ); + break; + case FLOATX80_TO_INT32_ROUND_TO_ZERO: + time_a_floatx80_z_int32( floatx80_to_int32_round_to_zero ); + break; + case FLOATX80_TO_INT64: + time_a_floatx80_z_int64( floatx80_to_int64 ); + break; + case FLOATX80_TO_INT64_ROUND_TO_ZERO: + time_a_floatx80_z_int64( floatx80_to_int64_round_to_zero ); + break; + case FLOATX80_TO_FLOAT32: + time_a_floatx80_z_float32( floatx80_to_float32 ); + break; + case FLOATX80_TO_FLOAT64: + time_a_floatx80_z_float64( floatx80_to_float64 ); + break; +#ifdef FLOAT128 + case FLOATX80_TO_FLOAT128: + time_a_floatx80_z_float128( floatx80_to_float128 ); + break; +#endif + case FLOATX80_ROUND_TO_INT: + time_az_floatx80( floatx80_round_to_int ); + break; + case FLOATX80_ADD: + time_abz_floatx80( floatx80_add ); + break; + case FLOATX80_SUB: + time_abz_floatx80( floatx80_sub ); + break; + case FLOATX80_MUL: + time_abz_floatx80( floatx80_mul ); + break; + case FLOATX80_DIV: + time_abz_floatx80( floatx80_div ); + break; + case FLOATX80_REM: + time_abz_floatx80( floatx80_rem ); + break; + case FLOATX80_SQRT: + time_az_floatx80_pos( floatx80_sqrt ); + break; + case FLOATX80_EQ: + time_ab_floatx80_z_flag( floatx80_eq ); + break; + case FLOATX80_LE: + time_ab_floatx80_z_flag( floatx80_le ); + break; + case FLOATX80_LT: + time_ab_floatx80_z_flag( floatx80_lt ); + break; + case FLOATX80_EQ_SIGNALING: + time_ab_floatx80_z_flag( floatx80_eq_signaling ); + break; + case FLOATX80_LE_QUIET: + time_ab_floatx80_z_flag( floatx80_le_quiet ); + break; + case FLOATX80_LT_QUIET: + time_ab_floatx80_z_flag( floatx80_lt_quiet ); + break; +#endif +#ifdef FLOAT128 + case FLOAT128_TO_INT32: + time_a_float128_z_int32( float128_to_int32 ); + break; + case FLOAT128_TO_INT32_ROUND_TO_ZERO: + time_a_float128_z_int32( float128_to_int32_round_to_zero ); + break; + case FLOAT128_TO_INT64: + time_a_float128_z_int64( float128_to_int64 ); + break; + case FLOAT128_TO_INT64_ROUND_TO_ZERO: + time_a_float128_z_int64( float128_to_int64_round_to_zero ); + break; + case FLOAT128_TO_FLOAT32: + time_a_float128_z_float32( float128_to_float32 ); + break; + case FLOAT128_TO_FLOAT64: + time_a_float128_z_float64( float128_to_float64 ); + break; +#ifdef FLOATX80 + case FLOAT128_TO_FLOATX80: + time_a_float128_z_floatx80( float128_to_floatx80 ); + break; +#endif + case FLOAT128_ROUND_TO_INT: + time_az_float128( float128_round_to_int ); + break; + case FLOAT128_ADD: + time_abz_float128( float128_add ); + break; + case FLOAT128_SUB: + time_abz_float128( float128_sub ); + break; + case FLOAT128_MUL: + time_abz_float128( float128_mul ); + break; + case FLOAT128_DIV: + time_abz_float128( float128_div ); + break; + case FLOAT128_REM: + time_abz_float128( float128_rem ); + break; + case FLOAT128_SQRT: + time_az_float128_pos( float128_sqrt ); + break; + case FLOAT128_EQ: + time_ab_float128_z_flag( float128_eq ); + break; + case FLOAT128_LE: + time_ab_float128_z_flag( float128_le ); + break; + case FLOAT128_LT: + time_ab_float128_z_flag( float128_lt ); + break; + case FLOAT128_EQ_SIGNALING: + time_ab_float128_z_flag( float128_eq_signaling ); + break; + case FLOAT128_LE_QUIET: + time_ab_float128_z_flag( float128_le_quiet ); + break; + case FLOAT128_LT_QUIET: + time_ab_float128_z_flag( float128_lt_quiet ); + break; +#endif + } + +} + +static void + timeFunction( + uint8 functionCode, + int8 roundingPrecisionIn, + int8 roundingModeIn, + int8 tininessModeIn + ) +{ + int8 roundingPrecision, roundingMode, tininessMode; + + roundingPrecision = 32; + for (;;) { + if ( ! functions[ functionCode ].roundingPrecision ) { + roundingPrecision = 0; + } + else if ( roundingPrecisionIn ) { + roundingPrecision = roundingPrecisionIn; + } + for ( roundingMode = 1; + roundingMode < NUM_ROUNDINGMODES; + ++roundingMode + ) { + if ( ! functions[ functionCode ].roundingMode ) { + roundingMode = 0; + } + else if ( roundingModeIn ) { + roundingMode = roundingModeIn; + } + for ( tininessMode = 1; + tininessMode < NUM_TININESSMODES; + ++tininessMode + ) { + if ( ( roundingPrecision == 32 ) + || ( roundingPrecision == 64 ) ) { + if ( ! functions[ functionCode ] + .tininessModeAtReducedPrecision + ) { + tininessMode = 0; + } + else if ( tininessModeIn ) { + tininessMode = tininessModeIn; + } + } + else { + if ( ! functions[ functionCode ].tininessMode ) { + tininessMode = 0; + } + else if ( tininessModeIn ) { + tininessMode = tininessModeIn; + } + } + timeFunctionVariety( + functionCode, roundingPrecision, roundingMode, tininessMode + ); + if ( tininessModeIn || ! tininessMode ) break; + } + if ( roundingModeIn || ! roundingMode ) break; + } + if ( roundingPrecisionIn || ! roundingPrecision ) break; + if ( roundingPrecision == 80 ) { + break; + } + else if ( roundingPrecision == 64 ) { + roundingPrecision = 80; + } + else if ( roundingPrecision == 32 ) { + roundingPrecision = 64; + } + } + +} + +main( int argc, char **argv ) +{ + char *argPtr; + flag functionArgument; + uint8 functionCode; + int8 operands, roundingPrecision, roundingMode, tininessMode; + + if ( argc <= 1 ) goto writeHelpMessage; + functionArgument = FALSE; + functionCode = 0; + operands = 0; + roundingPrecision = 0; + roundingMode = 0; + tininessMode = 0; + --argc; + ++argv; + while ( argc && ( argPtr = argv[ 0 ] ) ) { + if ( argPtr[ 0 ] == '-' ) ++argPtr; + if ( strcmp( argPtr, "help" ) == 0 ) { + writeHelpMessage: + fputs( +"timesoftfloat [